diff --git a/CMakeLists.txt b/CMakeLists.txt index 051ba92..e2e208e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,14 @@ project(portal64) # Tools # TODO: find automatically # TODO: test on Windows +set(FFMPEG "ffmpeg") set(IMAGEMAGICK_CONVERT "convert") -set(VTF2PNG "vtf2png") set(PYTHON3 "python") set(VPK "vpk") +set(VTF2PNG "vtf2png") + set(CONVERT_ASSET "${PROJECT_SOURCE_DIR}/tools/convert_asset.py") +set(SKELETOOL64 "${PROJECT_SOURCE_DIR}/skelatool64/skeletool64") # Directories set(ASSETS_DIR "${PROJECT_SOURCE_DIR}/assets") diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index 939c719..a28de6e 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -1,331 +1 @@ -######################## -## Texture conversion ## -######################## - -# All textures used from the original game -set(TEXTURES - materials/concrete/concrete_modular_ceiling001a - materials/concrete/concrete_modular_floor001a - materials/concrete/concrete_modular_wall001b - materials/concrete/concrete_modular_wall001d - materials/concrete/observationwall_001a - materials/decals/orange_spot - materials/effects/brightglow_y - materials/effects/fleck_ash2 - materials/effects/light_rail_beam1 - materials/effects/portal_1_particle - materials/effects/portal_2_particle - materials/effects/portal_cleanser - materials/gamepadui/portal_logo - materials/glass/glasswindow_frosted_002 - materials/glass/refract01_dx8 - materials/metal/metalgrate018 - materials/metal/metal_modular_floor001 - materials/metal/metalwall048b - materials/metal/metalwall_bts_006a - materials/models/player/chell_body - materials/models/player/chell_face - materials/models/props/autoportal_frame/autoportal_frame - materials/models/props/ball_catcher_sheet - materials/models/props/bed01 - materials/models/props/button - materials/models/props/combine_ball_launcher - materials/models/props/door_01 - materials/models/props/door_02 - materials/models/props/elevatorshaft_wall/elevatorshaft_wall - materials/models/props/elevator_caps/elevator_caps - materials/models/props/lab_monitor/lab_monitor_screen_text - materials/models/props/light_rail_endcap - materials/models/props/metal_box - materials/models/props/portal_cleanser - materials/models/props/radio - materials/models/props/round_elevator_sheet_1 - materials/models/props/round_elevator_sheet_2 - materials/models/props/round_elevator_sheet_3 - materials/models/props/security_camera - materials/models/props/toilet - materials/models/props_animsigns/awe_total - materials/models/props_animsigns/newsignage_back02 - materials/models/props_c17/door01a_skin6 - materials/models/weapons/v_models/v_portalgun/v_portalgun - materials/nature/hazard_liquid - materials/plastic/plasticwall003a - materials/plastic/plasticwall004a - materials/signage/clock/clock_dots - materials/signage/clock/countdown - materials/signage/hazard_orange_03b - materials/signage/indicator_lights/indicator_lights_corner_floor - materials/signage/indicator_lights/indicator_lights_floor - materials/signage/overlay_aperture_logo_worn - materials/signage/signage_doorstate - materials/signage/signage_exit - materials/signage/signage_overlay_arrow - materials/signage/signage_overlay_boxdispenser - materials/signage/signage_overlay_boxhurt - materials/signage/signage_overlay_catcher - materials/signage/signage_overlay_dots1 - materials/signage/signage_overlay_dots2 - materials/signage/signage_overlay_dots3 - materials/signage/signage_overlay_dots4 - materials/signage/signage_overlay_energyball - materials/signage/signage_overlay_fling1 - materials/signage/signage_overlay_fling2 - materials/signage/signage_overlay_fountain - materials/signage/signage_overlay_midair1 - materials/signage/signage_overlay_midair2 - materials/signage/signage_overlay_toxic - materials/sprites/grav_flare - materials/sprites/hud/portal_crosshairs - materials/tile/observation_tilefloor001a - materials/vgui/chapters/chapter1 - materials/vgui/chapters/chapter2 - materials/vgui/chapters/chapter3 - materials/vgui/chapters/chapter4 - materials/vgui/chapters/chapter5 - materials/vgui/chapters/chapter6 - materials/vgui/chapters/chapter7 - materials/vgui/chapters/chapter8 - materials/vgui/chapters/chapter9 - materials/vgui/chapters/chapter10 - materials/vgui/chapters/chapter11 -) - -function(_add_texture_convert_command INPUT_FILE OUTPUT_FILE) - set(INPUT_FILE "${PAK_DIR}/${INPUT_FILE}.vtf") - set(OUTPUT_FILE "${PAK_DIR}/${OUTPUT_FILE}.png") - set(ARGS "${ARGN}") - - if(NOT ARGS) - get_source_file_property(FILE_ARGS ${INPUT_FILE} ARGS) - if (FILE_ARGS) - set(ARGS "${FILE_ARGS}") - endif() - endif() - - cmake_path( - RELATIVE_PATH INPUT_FILE - BASE_DIRECTORY "${PROJECT_SOURCE_DIR}" - OUTPUT_VARIABLE RELATIVE_INPUT_FILE - ) - - add_custom_command( - DEPENDS - extract_vpks - OUTPUT - ${OUTPUT_FILE} - COMMAND - ${VTF2PNG} ${ARGS} ${INPUT_FILE} ${OUTPUT_FILE} - COMMENT - "Converting ${RELATIVE_INPUT_FILE}" - VERBATIM - ) -endfunction() - -# Add commands for converting VTF textures to PNG -# There are some special cases for VTFs with multiple frames - -set_property(SOURCE ${PAK_DIR}/materials/signage/clock/countdown.vtf - PROPERTY ARGS - -f 60 -) - -foreach(i RANGE 1 9) - math(EXPR FRAME "60 - ${i}") - - _add_texture_convert_command( - materials/signage/clock/countdown - materials/signage/clock/countdown_${i} - -f ${FRAME} - ) -endforeach() - -_add_texture_convert_command( - materials/signage/signage_doorstate - materials/signage/signage_doorstate_on - -f 2 -) -_add_texture_convert_command( - materials/signage/indicator_lights/indicator_lights_corner_floor - materials/signage/indicator_lights/indicator_lights_corner_floor_on - -f 2 -) -_add_texture_convert_command( - materials/signage/indicator_lights/indicator_lights_floor - materials/signage/indicator_lights/indicator_lights_floor_on - -f 2 -) - -foreach(TEXTURE ${TEXTURES}) - _add_texture_convert_command(${TEXTURE} ${TEXTURE}) -endforeach() - -############################ -## Texture transformation ## -############################ - -# Adding a new .ims implies a new texture, which necessitates updating the -# TEXTURES list above, which will retrigger CMake on build and so the typical -# glob pitfalls do not apply here. -file(GLOB_RECURSE TEXTURE_SCRIPTS "materials/*.ims") - -function(_get_texture_script_file_list TEXTURE_SCRIPT PROPERTY_NAME PARENT_DIR OUTPUT) - get_source_file_property(FILE_LIST ${TEXTURE_SCRIPT} ${PROPERTY_NAME}) - - if (FILE_LIST) - list(TRANSFORM FILE_LIST PREPEND "${PARENT_DIR}/" OUTPUT_VARIABLE FILE_LIST) - list(TRANSFORM FILE_LIST APPEND ".png" OUTPUT_VARIABLE FILE_LIST) - list(APPEND ${OUTPUT} "${FILE_LIST}") - endif() - - return(PROPAGATE ${OUTPUT}) -endfunction() - -function(_add_texture_transform_command TEXTURE_SCRIPT OUTPUT_LIST) - cmake_path( - RELATIVE_PATH TEXTURE_SCRIPT - BASE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - OUTPUT_VARIABLE TEXTURE_NAME - ) - cmake_path( - REMOVE_EXTENSION TEXTURE_NAME - OUTPUT_VARIABLE TEXTURE_NAME - ) - - set(INPUT_FILE "${PAK_DIR}/${TEXTURE_NAME}.png") - set(OUTPUT_FILE "${PAK_MODIFIED_DIR}/${TEXTURE_NAME}.png") - - set(DEPENDENCY_FILES ${INPUT_FILE} ${TEXTURE_SCRIPT}) - _get_texture_script_file_list(${TEXTURE_SCRIPT} ADDITIONAL_DEPS ${PAK_DIR} DEPENDENCY_FILES) - - set(OUTPUT_FILES ${OUTPUT_FILE}) - _get_texture_script_file_list(${TEXTURE_SCRIPT} ADDITIONAL_OUTPUTS ${PAK_MODIFIED_DIR} OUTPUT_FILES) - - cmake_path( - RELATIVE_PATH INPUT_FILE - BASE_DIRECTORY "${PROJECT_SOURCE_DIR}" - OUTPUT_VARIABLE RELATIVE_INPUT_FILE - ) - - add_custom_command( - DEPENDS - ${CONVERT_ASSET} ${DEPENDENCY_FILES} - OUTPUT - ${OUTPUT_FILES} - COMMAND - ${PYTHON3} ${CONVERT_ASSET} ${IMAGEMAGICK_CONVERT} ${INPUT_FILE} ${TEXTURE_SCRIPT} ${OUTPUT_FILE} - WORKING_DIRECTORY - # TODO: Change this to PAK_MODIFIED_DIR and update .ims files with relative path - ${PROJECT_SOURCE_DIR} - COMMENT - "Transforming ${RELATIVE_INPUT_FILE}" - VERBATIM - ) - - list(APPEND ${OUTPUT_LIST} "${OUTPUT_FILES}") - return(PROPAGATE ${OUTPUT_LIST}) -endfunction() - -# Add commands for transforming converted PNG textures (crop, scale, etc.). -# There are some special cases due to some conversion scripts reading textures -# other than those they are named after (combining multiple textures), or -# producing more than one output (texture splitting). - -set_property(SOURCE materials/effects/portal_cleanser.ims - PROPERTY ADDITIONAL_OUTPUTS - materials/effects/spark -) -set_property(SOURCE materials/models/player/chell_body.ims - PROPERTY ADDITIONAL_OUTPUTS - materials/models/player/chell_back_logo - materials/models/player/chell_pants -) -set_property(SOURCE materials/models/player/chell_face.ims - PROPERTY ADDITIONAL_OUTPUTS - materials/models/player/chell_head -) -set_property(SOURCE materials/models/props_animsigns/awe_total.ims - PROPERTY ADDITIONAL_OUTPUTS - materials/models/props_animsigns/awe_total_copy_0 - materials/models/props_animsigns/awe_total_copy_1 - materials/models/props_animsigns/awe_total_copy_2 -) -set_property(SOURCE materials/models/props/ball_catcher_sheet.ims - PROPERTY ADDITIONAL_OUTPUTS - materials/models/props/ball_catcher_back -) -set_property(SOURCE materials/models/props/bed01.ims - PROPERTY ADDITIONAL_OUTPUTS - materials/models/props/bed01_screen -) -set_property(SOURCE materials/models/props/button.ims - PROPERTY ADDITIONAL_OUTPUTS - materials/models/props/button_base -) -set_property(SOURCE materials/models/props/round_elevator_sheet_1.ims - PROPERTY ADDITIONAL_DEPS - materials/models/props/round_elevator_sheet_3 -) -set_property(SOURCE materials/models/props/round_elevator_sheet_1.ims - PROPERTY ADDITIONAL_OUTPUTS - materials/models/props/round_elevator_floor -) -set_property(SOURCE materials/models/props/round_elevator_sheet_3.ims - PROPERTY ADDITIONAL_OUTPUTS - materials/models/props/elevator_sign -) -set_property(SOURCE materials/signage/clock/countdown.ims - PROPERTY ADDITIONAL_DEPS - materials/signage/clock/countdown_1 - materials/signage/clock/countdown_2 - materials/signage/clock/countdown_3 - materials/signage/clock/countdown_4 - materials/signage/clock/countdown_5 - materials/signage/clock/countdown_6 - materials/signage/clock/countdown_7 - materials/signage/clock/countdown_8 - materials/signage/clock/countdown_9 - materials/signage/clock/clock_dots -) -set_property(SOURCE materials/signage/indicator_lights/indicator_lights_floor.ims - PROPERTY ADDITIONAL_DEPS - materials/signage/indicator_lights/indicator_lights_corner_floor -) -set_property(SOURCE materials/signage/indicator_lights/indicator_lights_floor_on.ims - PROPERTY ADDITIONAL_DEPS - materials/signage/indicator_lights/indicator_lights_corner_floor_on -) -set_property(SOURCE materials/signage/signage_exit.ims - PROPERTY ADDITIONAL_DEPS - materials/signage/signage_overlay_arrow - materials/signage/signage_overlay_boxdispenser - materials/signage/signage_overlay_boxhurt - materials/signage/signage_overlay_energyball - materials/signage/signage_overlay_catcher - materials/signage/signage_overlay_toxic - materials/signage/signage_overlay_fountain -) -set_property(SOURCE materials/signage/signage_overlay_fling1.ims - PROPERTY ADDITIONAL_DEPS - materials/signage/signage_overlay_fling2 - materials/signage/signage_overlay_dots1 - materials/signage/signage_overlay_dots2 - materials/signage/signage_overlay_dots3 - materials/signage/signage_overlay_dots4 - materials/signage/signage_overlay_toxic - materials/signage/signage_overlay_fountain -) -set_property(SOURCE materials/signage/signage_overlay_midair1.ims - PROPERTY ADDITIONAL_DEPS - materials/signage/signage_overlay_midair2 -) - -set(TEXTURES_TRANSFORMED "") - -foreach(TEXTURE_SCRIPT ${TEXTURE_SCRIPTS}) - _add_texture_transform_command(${TEXTURE_SCRIPT} TEXTURES_TRANSFORMED) -endforeach() - -add_custom_target( - all_textures - DEPENDS ${TEXTURES_TRANSFORMED} -) +add_subdirectory(materials) diff --git a/assets/materials/CMakeLists.txt b/assets/materials/CMakeLists.txt new file mode 100644 index 0000000..c5d7b8e --- /dev/null +++ b/assets/materials/CMakeLists.txt @@ -0,0 +1,492 @@ +set(PAK_MATERIALS_DIR "${PAK_DIR}/materials") +set(PAK_MODIFIED_MATERIALS_DIR "${PAK_MODIFIED_DIR}/materials") + +######################## +## Texture conversion ## +######################## + +# All textures used from the original game +set(TEXTURES + concrete/concrete_modular_ceiling001a + concrete/concrete_modular_floor001a + concrete/concrete_modular_wall001b + concrete/concrete_modular_wall001d + concrete/observationwall_001a + decals/orange_spot + effects/brightglow_y + effects/fleck_ash2 + effects/light_rail_beam1 + effects/portal_1_particle + effects/portal_2_particle + effects/portal_cleanser + gamepadui/portal_logo + glass/glasswindow_frosted_002 + glass/refract01_dx8 + metal/metalgrate018 + metal/metal_modular_floor001 + metal/metalwall048b + metal/metalwall_bts_006a + models/player/chell_body + models/player/chell_face + models/props/autoportal_frame/autoportal_frame + models/props/ball_catcher_sheet + models/props/bed01 + models/props/button + models/props/combine_ball_launcher + models/props/door_01 + models/props/door_02 + models/props/elevatorshaft_wall/elevatorshaft_wall + models/props/elevator_caps/elevator_caps + models/props/lab_monitor/lab_monitor_screen_text + models/props/light_rail_endcap + models/props/metal_box + models/props/portal_cleanser + models/props/radio + models/props/round_elevator_sheet_1 + models/props/round_elevator_sheet_2 + models/props/round_elevator_sheet_3 + models/props/security_camera + models/props/toilet + models/props_animsigns/awe_total + models/props_animsigns/newsignage_back02 + models/props_c17/door01a_skin6 + models/weapons/v_models/v_portalgun/v_portalgun + nature/hazard_liquid + plastic/plasticwall003a + plastic/plasticwall004a + signage/clock/clock_dots + signage/clock/countdown + signage/hazard_orange_03b + signage/indicator_lights/indicator_lights_corner_floor + signage/indicator_lights/indicator_lights_floor + signage/overlay_aperture_logo_worn + signage/signage_doorstate + signage/signage_exit + signage/signage_overlay_arrow + signage/signage_overlay_boxdispenser + signage/signage_overlay_boxhurt + signage/signage_overlay_catcher + signage/signage_overlay_dots1 + signage/signage_overlay_dots2 + signage/signage_overlay_dots3 + signage/signage_overlay_dots4 + signage/signage_overlay_energyball + signage/signage_overlay_fling1 + signage/signage_overlay_fling2 + signage/signage_overlay_fountain + signage/signage_overlay_midair1 + signage/signage_overlay_midair2 + signage/signage_overlay_toxic + sprites/grav_flare + sprites/hud/portal_crosshairs + tile/observation_tilefloor001a + vgui/chapters/chapter1 + vgui/chapters/chapter2 + vgui/chapters/chapter3 + vgui/chapters/chapter4 + vgui/chapters/chapter5 + vgui/chapters/chapter6 + vgui/chapters/chapter7 + vgui/chapters/chapter8 + vgui/chapters/chapter9 + vgui/chapters/chapter10 + vgui/chapters/chapter11 +) + +function(_add_texture_convert_command INPUT_FILE OUTPUT_FILE) + set(INPUT_FILE "${PAK_MATERIALS_DIR}/${INPUT_FILE}.vtf") + set(OUTPUT_FILE "${PAK_MATERIALS_DIR}/${OUTPUT_FILE}.png") + set(ARGS "${ARGN}") + + if(NOT ARGS) + get_source_file_property(FILE_ARGS ${INPUT_FILE} ARGS) + if (FILE_ARGS) + set(ARGS "${FILE_ARGS}") + endif() + endif() + + cmake_path( + RELATIVE_PATH INPUT_FILE + BASE_DIRECTORY "${PROJECT_SOURCE_DIR}" + OUTPUT_VARIABLE RELATIVE_INPUT_FILE + ) + + add_custom_command( + DEPENDS + extract_vpks ${INPUT_FILE} + OUTPUT + ${OUTPUT_FILE} + COMMAND + ${VTF2PNG} ${ARGS} ${INPUT_FILE} ${OUTPUT_FILE} + COMMENT + "Converting ${RELATIVE_INPUT_FILE}" + VERBATIM + ) +endfunction() + +# Add commands for converting VTF textures to PNG +# There are some special cases for VTFs with multiple frames + +set_property(SOURCE ${PAK_MATERIALS_DIR}/signage/clock/countdown.vtf + PROPERTY ARGS + -f 60 +) + +foreach(i RANGE 1 9) + math(EXPR FRAME "60 - ${i}") + + _add_texture_convert_command( + signage/clock/countdown + signage/clock/countdown_${i} + -f ${FRAME} + ) +endforeach() + +_add_texture_convert_command( + signage/signage_doorstate + signage/signage_doorstate_on + -f 2 +) +_add_texture_convert_command( + signage/indicator_lights/indicator_lights_corner_floor + signage/indicator_lights/indicator_lights_corner_floor_on + -f 2 +) +_add_texture_convert_command( + signage/indicator_lights/indicator_lights_floor + signage/indicator_lights/indicator_lights_floor_on + -f 2 +) + +foreach(TEXTURE ${TEXTURES}) + _add_texture_convert_command(${TEXTURE} ${TEXTURE}) +endforeach() + +################ +## Valve logo ## +################ + +set(VALVE_INTRO_VIDEO "${VPK_DIR}/Portal/hl2/media/valve.bik") + +if(NOT EXISTS ${VALVE_INTRO_VIDEO}) + # The Mac release of Portal uses a .mov instead of a .bik + string(REPLACE ".mov" ".bik" VALVE_INTRO_VIDEO_MAC "${VALVE_INTRO_VIDEO}") + + # The Valve video doesn't exist in a VPK so we can check its type at + # configuration time and avoid complicating the conversion command. + # + # Users may forget to copy their game files before running CMake. + # Only use the .mov if it exists at configuration time, so the build + # system supports the common case by default. + if (EXISTS ${VALVE_INTRO_VIDEO_MAC}) + set(VALVE_INTRO_VIDEO ${VALVE_INTRO_VIDEO_MAC}) + endif() +endif() + +function(_add_extract_frame_command INPUT_FILE OUTPUT_FILE SECONDS) + cmake_path( + GET OUTPUT_FILE PARENT_PATH + OUTPUT_DIR + ) + cmake_path( + RELATIVE_PATH INPUT_FILE + BASE_DIRECTORY "${PROJECT_SOURCE_DIR}" + OUTPUT_VARIABLE RELATIVE_INPUT_FILE + ) + + add_custom_command( + DEPENDS + ${INPUT_FILE} + OUTPUT + ${OUTPUT_FILE} + COMMAND + ${CMAKE_COMMAND} -E make_directory ${OUTPUT_DIR} + COMMAND + ${FFMPEG} -ss 00:00:${SECONDS} -i ${VALVE_INTRO_VIDEO} -frames:v 1 -update true -q:v 2 -y ${OUTPUT_FILE} + COMMAND + ${IMAGEMAGICK_CONVERT} ${OUTPUT_FILE} -crop 491x369+265+202 -resize 160x120 ${OUTPUT_FILE} + COMMENT + "Converting ${RELATIVE_INPUT_FILE}" + VERBATIM + ) +endfunction() + +_add_extract_frame_command( + ${VALVE_INTRO_VIDEO} + ${CMAKE_BINARY_DIR}/assets/images/valve.png + 4 +) + +_add_extract_frame_command( + ${VALVE_INTRO_VIDEO} + ${CMAKE_BINARY_DIR}/assets/images/valve-no-logo.png + 1 +) + +############################ +## Texture transformation ## +############################ + +# Adding a new .ims implies a new texture, which necessitates updating the +# TEXTURES list above, which will retrigger CMake on build and so the typical +# glob pitfalls do not apply here. +file(GLOB_RECURSE TEXTURE_SCRIPTS "*.ims") + +function(_get_texture_script_file_list TEXTURE_SCRIPT PROPERTY_NAME PARENT_DIR OUTPUT) + get_source_file_property(FILE_LIST ${TEXTURE_SCRIPT} ${PROPERTY_NAME}) + + if (FILE_LIST) + list(TRANSFORM FILE_LIST PREPEND "${PARENT_DIR}/" OUTPUT_VARIABLE FILE_LIST) + list(TRANSFORM FILE_LIST APPEND ".png" OUTPUT_VARIABLE FILE_LIST) + list(APPEND ${OUTPUT} ${FILE_LIST}) + endif() + + return(PROPAGATE ${OUTPUT}) +endfunction() + +function(_add_texture_transform_command TEXTURE_SCRIPT OUTPUT_LIST) + cmake_path( + RELATIVE_PATH TEXTURE_SCRIPT + BASE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + OUTPUT_VARIABLE TEXTURE_NAME + ) + cmake_path( + REMOVE_EXTENSION TEXTURE_NAME + OUTPUT_VARIABLE TEXTURE_NAME + ) + + set(INPUT_FILE "${PAK_MATERIALS_DIR}/${TEXTURE_NAME}.png") + set(OUTPUT_FILE "${PAK_MODIFIED_MATERIALS_DIR}/${TEXTURE_NAME}.png") + + set(DEPENDENCY_FILES ${INPUT_FILE} ${TEXTURE_SCRIPT}) + _get_texture_script_file_list(${TEXTURE_SCRIPT} ADDITIONAL_DEPS ${PAK_MATERIALS_DIR} DEPENDENCY_FILES) + + set(OUTPUT_FILES ${OUTPUT_FILE}) + _get_texture_script_file_list(${TEXTURE_SCRIPT} ADDITIONAL_OUTPUTS ${PAK_MODIFIED_MATERIALS_DIR} OUTPUT_FILES) + + cmake_path( + RELATIVE_PATH INPUT_FILE + BASE_DIRECTORY "${PROJECT_SOURCE_DIR}" + OUTPUT_VARIABLE RELATIVE_INPUT_FILE + ) + + add_custom_command( + DEPENDS + ${CONVERT_ASSET} ${DEPENDENCY_FILES} + OUTPUT + ${OUTPUT_FILES} + COMMAND + ${PYTHON3} ${CONVERT_ASSET} ${IMAGEMAGICK_CONVERT} ${INPUT_FILE} ${TEXTURE_SCRIPT} ${OUTPUT_FILE} + WORKING_DIRECTORY + # TODO: Change this to PAK_MODIFIED_DIR and update .ims files with relative path + ${PROJECT_SOURCE_DIR} + COMMENT + "Transforming ${RELATIVE_INPUT_FILE}" + VERBATIM + ) + + list(APPEND ${OUTPUT_LIST} ${OUTPUT_FILES}) + return(PROPAGATE ${OUTPUT_LIST}) +endfunction() + +# Add commands for transforming converted PNG textures (crop, scale, etc.). +# There are some special cases due to some conversion scripts reading textures +# other than those they are named after (combining multiple textures), or +# producing more than one output (texture splitting). + +set_property(SOURCE effects/portal_cleanser.ims + PROPERTY ADDITIONAL_OUTPUTS + effects/spark +) +set_property(SOURCE models/player/chell_body.ims + PROPERTY ADDITIONAL_OUTPUTS + models/player/chell_back_logo + models/player/chell_pants +) +set_property(SOURCE models/player/chell_face.ims + PROPERTY ADDITIONAL_OUTPUTS + models/player/chell_head +) +set_property(SOURCE models/props_animsigns/awe_total.ims + PROPERTY ADDITIONAL_OUTPUTS + models/props_animsigns/awe_total_copy_0 + models/props_animsigns/awe_total_copy_1 + models/props_animsigns/awe_total_copy_2 +) +set_property(SOURCE models/props/ball_catcher_sheet.ims + PROPERTY ADDITIONAL_OUTPUTS + models/props/ball_catcher_back +) +set_property(SOURCE models/props/bed01.ims + PROPERTY ADDITIONAL_OUTPUTS + models/props/bed01_screen +) +set_property(SOURCE models/props/button.ims + PROPERTY ADDITIONAL_OUTPUTS + models/props/button_base +) +set_property(SOURCE models/props/round_elevator_sheet_1.ims + PROPERTY ADDITIONAL_DEPS + models/props/round_elevator_sheet_3 +) +set_property(SOURCE models/props/round_elevator_sheet_1.ims + PROPERTY ADDITIONAL_OUTPUTS + models/props/round_elevator_floor +) +set_property(SOURCE models/props/round_elevator_sheet_3.ims + PROPERTY ADDITIONAL_OUTPUTS + models/props/elevator_sign +) +set_property(SOURCE signage/clock/countdown.ims + PROPERTY ADDITIONAL_DEPS + signage/clock/countdown_1 + signage/clock/countdown_2 + signage/clock/countdown_3 + signage/clock/countdown_4 + signage/clock/countdown_5 + signage/clock/countdown_6 + signage/clock/countdown_7 + signage/clock/countdown_8 + signage/clock/countdown_9 + signage/clock/clock_dots +) +set_property(SOURCE signage/indicator_lights/indicator_lights_floor.ims + PROPERTY ADDITIONAL_DEPS + signage/indicator_lights/indicator_lights_corner_floor +) +set_property(SOURCE signage/indicator_lights/indicator_lights_floor_on.ims + PROPERTY ADDITIONAL_DEPS + signage/indicator_lights/indicator_lights_corner_floor_on +) +set_property(SOURCE signage/signage_exit.ims + PROPERTY ADDITIONAL_DEPS + signage/signage_overlay_arrow + signage/signage_overlay_boxdispenser + signage/signage_overlay_boxhurt + signage/signage_overlay_energyball + signage/signage_overlay_catcher + signage/signage_overlay_toxic + signage/signage_overlay_fountain +) +set_property(SOURCE signage/signage_overlay_fling1.ims + PROPERTY ADDITIONAL_DEPS + signage/signage_overlay_fling2 + signage/signage_overlay_dots1 + signage/signage_overlay_dots2 + signage/signage_overlay_dots3 + signage/signage_overlay_dots4 + signage/signage_overlay_toxic + signage/signage_overlay_fountain +) +set_property(SOURCE signage/signage_overlay_midair1.ims + PROPERTY ADDITIONAL_DEPS + signage/signage_overlay_midair2 +) + +set(TEXTURES_TRANSFORMED "") + +foreach(TEXTURE_SCRIPT ${TEXTURE_SCRIPTS}) + _add_texture_transform_command(${TEXTURE_SCRIPT} TEXTURES_TRANSFORMED) +endforeach() + +add_custom_target( + all_textures + DEPENDS ${TEXTURES_TRANSFORMED} +) + +######################### +## Material generation ## +######################### + +set(MATERIALS + hud.skm.yaml + images.skm.yaml + static.skm.yaml + ui.skm.yaml +) + +function(_add_material_generate_command INPUT_FILE OUTPUT_LIST) + cmake_path( + GET INPUT_FILE STEM + MATERIAL_NAME + ) + cmake_path( + RELATIVE_PATH CMAKE_CURRENT_SOURCE_DIR + BASE_DIRECTORY "${PROJECT_SOURCE_DIR}" + OUTPUT_VARIABLE RELATIVE_DIR + ) + + set(INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_FILE}") + set(OUTPUT_FILE_H "${CMAKE_BINARY_DIR}/${RELATIVE_DIR}/${MATERIAL_NAME}.h") + set(OUTPUT_FILE_C "${CMAKE_BINARY_DIR}/${RELATIVE_DIR}/${MATERIAL_NAME}_mat.c") + + # Depend on all textures for simplicity. Materials are cheap to rebuild. + set(DEPENDENCY_FILES ${INPUT_FILE} ${TEXTURES_TRANSFORMED}) + + get_source_file_property(DEP_FILE_LIST ${INPUT_FILE} ADDITIONAL_DEPS) + if (DEP_FILE_LIST) + list(APPEND DEPENDENCY_FILES ${DEP_FILE_LIST}) + endif() + + cmake_path( + RELATIVE_PATH INPUT_FILE + BASE_DIRECTORY "${PROJECT_SOURCE_DIR}" + OUTPUT_VARIABLE RELATIVE_INPUT_FILE + ) + + # TODO: add dependency on skeletool once it is built with CMake + add_custom_command( + DEPENDS + all_textures ${DEPENDENCY_FILES} + OUTPUT + ${OUTPUT_FILE_H} ${OUTPUT_FILE_C} + COMMAND + ${SKELETOOL64} --name ${MATERIAL_NAME} -m ${INPUT_FILE} --material-output -o ${OUTPUT_FILE_H} + WORKING_DIRECTORY + ${PROJECT_SOURCE_DIR} + COMMENT + "Generating materials for ${RELATIVE_INPUT_FILE}" + VERBATIM + ) + + list(APPEND ${OUTPUT_LIST} ${OUTPUT_FILE_H} ${OUTPUT_FILE_C}) + return(PROPAGATE ${OUTPUT_LIST}) +endfunction() + +# Add commands for generating materials +# There are some special cases for materials which use non-VPK textures + +set_property(SOURCE hud.skm.yaml + PROPERTY ADDITIONAL_DEPS + ${PROJECT_SOURCE_DIR}/assets/images/center_reticle.png +) + +set_property(SOURCE images.skm.yaml + PROPERTY ADDITIONAL_DEPS + ${CMAKE_BINARY_DIR}/assets/images/valve.png +) + +set_property(SOURCE ui.skm.yaml + PROPERTY ADDITIONAL_DEPS + ${PROJECT_SOURCE_DIR}/assets/fonts/dejavu_sans_0.png + ${PROJECT_SOURCE_DIR}/assets/fonts/dejavu_sans_1.png + ${PROJECT_SOURCE_DIR}/assets/fonts/dejavu_sans_2.png + ${PROJECT_SOURCE_DIR}/assets/fonts/dejavu_sans_3.png + ${PROJECT_SOURCE_DIR}/assets/fonts/dejavu_sans_4.png + ${PROJECT_SOURCE_DIR}/assets/fonts/liberation_mono_0.png + ${PROJECT_SOURCE_DIR}/assets/images/button_icons.png + ${PROJECT_SOURCE_DIR}/assets/images/credits_icons.png + ${PROJECT_SOURCE_DIR}/assets/images/github_qr.png + ${PROJECT_SOURCE_DIR}/assets/images/rounded_corners.png +) + +set(GENERATED_MATERIALS "") + +foreach(MATERIAL ${MATERIALS}) + _add_material_generate_command(${MATERIAL} GENERATED_MATERIALS) +endforeach() + +add_custom_target( + all_materials + DEPENDS ${GENERATED_MATERIALS} +) diff --git a/assets/models/valve_animation.blend b/assets/models/valve_animation.blend index 902729a..0a169c3 100644 Binary files a/assets/models/valve_animation.blend and b/assets/models/valve_animation.blend differ diff --git a/vpk/CMakeLists.txt b/vpk/CMakeLists.txt index 20037cb..da49eb1 100644 --- a/vpk/CMakeLists.txt +++ b/vpk/CMakeLists.txt @@ -1,3 +1,7 @@ +#################### +## VPK extraction ## +#################### + # TODO: multiple languages set(VPKS_PORTAL Portal/portal/portal_pak_dir.vpk @@ -24,19 +28,14 @@ set(VPKS_HL2_SOUND_MISC Portal/hl2/hl2_sound_misc_002.vpk ) -set(VPK_LISTS - VPKS_PORTAL - VPKS_HL2_MISC - VPKS_HL2_SOUND_MISC -) - -set(VPK_STAMP_FILES "") - -foreach(VPK_LIST ${VPK_LISTS}) +function(_add_vpk_extract_command VPK_LIST OUTPUT_LIST) # First VPK is the one to extract list(GET ${VPK_LIST} 0 MAIN_VPK) - cmake_path(GET MAIN_VPK STEM MAIN_VPK_NAME) + cmake_path( + GET MAIN_VPK STEM + MAIN_VPK_NAME + ) set(MAIN_VPK_STAMP "${PAK_DIR}/${MAIN_VPK_NAME}.stamp") list(APPEND VPK_STAMP_FILES ${MAIN_VPK_STAMP}) @@ -55,7 +54,16 @@ foreach(VPK_LIST ${VPK_LISTS}) "Extracting ${MAIN_VPK}" VERBATIM ) -endforeach() + + list(APPEND ${OUTPUT_LIST} ${MAIN_VPK_STAMP}) + return(PROPAGATE ${OUTPUT_LIST}) +endfunction() + +set(VPK_STAMP_FILES "") + +_add_vpk_extract_command(VPKS_PORTAL VPK_STAMP_FILES) +_add_vpk_extract_command(VPKS_HL2_MISC VPK_STAMP_FILES) +_add_vpk_extract_command(VPKS_HL2_SOUND_MISC VPK_STAMP_FILES) add_custom_target( extract_vpks