# mp3-win - the PS4 port's build of Max Payne 3 on Windows x64, to debug the renderer on the PC (the user, 2026-11-06:
# "we need to run this recomp on pc, see what is wrong, try to solve it then think about ps4").
#
# The same generated code as the PS4 build (tools/codegen.sh with BARRIERS=0 PS4=1: x86-64, unfused FMA, the PS4
# PCH from tools/make_ps4_pch.py) and the same SDK branch, built with clang-cl into a desktop ReXApp (SDL window), with
# the SDK's Xenos GPU plugin (Vulkan, and D3D12 where the SDK builds it). Not for release.
#
#   cmake -S mp3/win -B <build> -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER=clang-cl
#     -DCMAKE_CXX_COMPILER=clang-cl -DREXSDK_DIR=<sdk> -DMP3_CODEGEN_DIR=<codegen output>

cmake_minimum_required(VERSION 3.25)
project(mp3win LANGUAGES C CXX RC)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

get_filename_component(MP3_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE)

set(MP3_CODEGEN_DIR "" CACHE PATH "tools/codegen.sh output folder (holds generated/default/)")
# The PC builder's own tools (mp3-extract), built before any game code exists: no codegen output needed.
option(MP3_TOOLS_ONLY "Only the PC builder's tools (mp3-extract)" OFF)
set(MP3_GENERATED "${MP3_CODEGEN_DIR}/generated/default")
if(NOT MP3_TOOLS_ONLY AND NOT EXISTS "${MP3_GENERATED}/sources.cmake")
    message(FATAL_ERROR "MP3_CODEGEN_DIR must point at tools/codegen.sh's output ('${MP3_CODEGEN_DIR}')")
endif()

set(REXSDK_DIR "" CACHE PATH "Path to the rexglue-sdk(-nx) source tree")
add_subdirectory("${REXSDK_DIR}" rexglue-sdk)

# mp3-extract: the player's disc image, Title Update 6 and Games on Demand packages to plain files (tools/mp3_extract.cpp).
add_executable(mp3-extract tools/mp3_extract.cpp)
target_link_libraries(mp3-extract PRIVATE rex::runtime)
rexglue_apply_target_settings(mp3-extract)
if(MP3_TOOLS_ONLY)
    return()
endif()

# The generated tree with the PS4 PCH: copied (Windows needs privileges for symlinks), only the PCH replaced.
find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter)
set(MP3_TREE "${CMAKE_BINARY_DIR}/generated_win")
execute_process(
    COMMAND "${Python3_EXECUTABLE}" -I "${CMAKE_CURRENT_SOURCE_DIR}/prepare_tree_win.py"
            "${MP3_GENERATED}" "${MP3_TREE}" "${MP3_DIR}/tools/make_ps4_pch.py"
    RESULT_VARIABLE _mp3_tree_rc)
if(NOT _mp3_tree_rc EQUAL 0)
    message(FATAL_ERROR "mp3: prepare_tree_win.py failed (${_mp3_tree_rc})")
endif()
include("${MP3_TREE}/sources.cmake")
set(MP3_GUEST_SOURCES ${GENERATED_SOURCES})
set_source_files_properties("${MP3_TREE}/mp3_register.cpp" PROPERTIES COMPILE_OPTIONS "/O1" SKIP_PRECOMPILE_HEADERS ON)

add_executable(mp3
    main_win.cpp
    mp3_pc_menu.cpp
    mp3_pc.cpp
    mp3_pc_fps.cpp
    mp3_pc_game_menu.cpp
    ${MP3_DIR}/ps4/mp3_ps4_fps.cpp
    ${MP3_DIR}/ps4/mp3_ps4_live.cpp
    ${MP3_DIR}/ps4/mp3_ps4_icons.cpp
    ${MP3_DIR}/ps4/mp3_offline_menus.cpp
    ${MP3_DIR}/src/mp3_god.cpp
    ${MP3_DIR}/src/mp3_cpu.cpp
    ${MP3_DIR}/src/mp3_guards.cpp
    ${MP3_DIR}/src/mp3_perf_hooks.cpp
    ${MP3_DIR}/src/mp3_detail.cpp
)
add_library(mp3_recomp OBJECT ${MP3_GUEST_SOURCES})
target_include_directories(mp3_recomp PRIVATE "${MP3_TREE}" "${MP3_DIR}/src")
target_link_libraries(mp3_recomp PRIVATE rex::runtime)
rexglue_apply_target_settings(mp3_recomp)
target_precompile_headers(mp3_recomp PRIVATE "${MP3_TREE}/mp3_pch.h")
# As the PS4 build: no debug info for the generated units, the guest's floating point unfused, no strict aliasing.
target_compile_options(mp3_recomp PRIVATE /clang:-g0 /clang:-ffp-contract=off /clang:-fno-strict-aliasing
                       /clang:-march=btver2 /clang:-mno-sse4a)  # the PS4's Jaguar, less AMD-only SSE4A (Intel)
target_link_libraries(mp3 PRIVATE mp3_recomp rex::runtime ws2_32)  # ws2_32: the live console's socket

# The PC version's version and name (the user, 2026-11-06: "call the process MAX PAYNE 3 [VER]": the window's title and
# the file description Task Manager shows), and the game's own icon when the codegen made one from the player's copy
# (tools/title_icon.py: the title image of their default.xex; none is shipped).
set(MP3_PC_VERSION_MAJOR 1)
set(MP3_PC_VERSION_MINOR 0)
set(MP3_PC_VERSION "v1.00")
set(MP3_PC_TITLE "MAX PAYNE 3 [${MP3_PC_VERSION}]")
target_compile_definitions(mp3 PRIVATE "MP3_PC_TITLE=\"${MP3_PC_TITLE}\"")
if(EXISTS "${MP3_CODEGEN_DIR}/mp3.ico")
    set(MP3_RC_ICON "1 ICON \"${MP3_CODEGEN_DIR}/mp3.ico\"")
else()
    set(MP3_RC_ICON "")
endif()
configure_file(mp3.rc.in "${CMAKE_CURRENT_BINARY_DIR}/mp3.rc" @ONLY)
target_sources(mp3 PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/mp3.rc")
target_include_directories(mp3 PRIVATE "${MP3_TREE}" "${MP3_DIR}/src" "${MP3_DIR}/ps4")
target_compile_options(mp3 PRIVATE /clang:-ffp-contract=off /clang:-fno-strict-aliasing)

# The names the generated code was made with (the PS4 port's, for the 0.0.6.6 executable): in the codegen output.
set(MP3_NAMES_TOML "${MP3_CODEGEN_DIR}/names.toml" CACHE FILEPATH "The names.toml the codegen used" FORCE)
# A new name there turns on a new hook: CMake configures again when the file changes.
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${MP3_NAMES_TOML}")
file(STRINGS "${MP3_NAMES_TOML}" MP3_NOMBRES REGEX "^name = \"mp3_[A-Za-z0-9_]+\"")
set(MP3_OWN_SOURCES ${MP3_DIR}/src/mp3_perf_hooks.cpp ${MP3_DIR}/src/mp3_detail.cpp ${MP3_DIR}/ps4/mp3_ps4_fps.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/mp3_pc_fps.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mp3_pc_game_menu.cpp
    ${MP3_DIR}/ps4/mp3_offline_menus.cpp)
foreach(linea IN LISTS MP3_NOMBRES)
    string(REGEX REPLACE "^name = \"(mp3_[A-Za-z0-9_]+)\".*" "\\1" nombre "${linea}")
    set_property(SOURCE ${MP3_OWN_SOURCES} APPEND PROPERTY COMPILE_DEFINITIONS MP3_TIENE_${nombre}=1)
endforeach()
set_property(SOURCE ${MP3_DIR}/src/mp3_cpu.cpp APPEND PROPERTY COMPILE_DEFINITIONS MP3_VERSION="win" MP3_COMMIT="win")

rexglue_configure_target(mp3 GPU_PLUGINS xenos)
# The SDK's SDL entry point is wWinMain on Windows.
set_target_properties(mp3 PROPERTIES WIN32_EXECUTABLE TRUE)
