cmake_minimum_required(VERSION 3.20)
project(Tomba2Recomp C CXX)
include(CTest)

set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 17)

# Both direct runtime targets use the same release version as the packagers.
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/packaging/release/VERSION"
    _tomba2_release_version LIMIT_COUNT 1)
set(PSX_GAME_VERSION "${_tomba2_release_version}" CACHE STRING
    "Tomba 2 build version")

set(PSXRECOMP_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/psxrecomp-v4" CACHE PATH
    "Path to psxrecomp")

include("${PSXRECOMP_ROOT}/runtime/runtime.cmake")

# Split-TU build: the recompiler writes the recompiled game as N
# SCUS_944.54_full_NN.c shards (plus a shared SCUS_944.54_decls.h) instead of
# one monolithic SCUS_944.54_full.c, so every shard compiles as its own
# translation unit in parallel. CONFIGURE_DEPENDS re-globs on every build so
# a shard-count change (regen) is picked up without a manual re-configure.
file(GLOB GAME_GENERATED_FULL CONFIGURE_DEPENDS
    "${CMAKE_CURRENT_SOURCE_DIR}/generated/SCUS_944.54_full_*.c")
set(GAME_GENERATED_DISPATCH
    "${CMAKE_CURRENT_SOURCE_DIR}/generated/SCUS_944.54_dispatch.c")

file(GLOB TOMBA2_MOD_PLUGIN_SOURCES CONFIGURE_DEPENDS
    "${CMAKE_CURRENT_SOURCE_DIR}/src/mods/*.c"
    "${CMAKE_CURRENT_SOURCE_DIR}/src/mods/*.cpp")

# The resident implementation is a build choice. Leave the original generated
# loader available in REFERENCE without linking/preparing the resident service.
list(REMOVE_ITEM TOMBA2_MOD_PLUGIN_SOURCES
    "${CMAKE_CURRENT_SOURCE_DIR}/src/mods/tomba2_seamless.c"
    "${CMAKE_CURRENT_SOURCE_DIR}/src/mods/tomba2_seamless_prepare.cpp"
    "${CMAKE_CURRENT_SOURCE_DIR}/src/mods/tomba2_seamless_reference.c"
    "${CMAKE_CURRENT_SOURCE_DIR}/src/mods/tomba2_terrain_execution_hle.c"
    "${CMAKE_CURRENT_SOURCE_DIR}/src/mods/tomba2_terrain_execution_lle.c")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/tomba2_execution.cmake")

# Isolated-worktree process-identity overrides. A sibling investigation may
# build this same game repo from a DIFFERENT worktree at the same time; without
# a distinct exe name / debug port the two builds' runtimes collide on process
# name (taskkill / Task Manager confusion) and on the TCP debug port. Empty by
# default so an ordinary configure uses OUTPUT_NAME "Tomba2Recomp", DEBUG_PORT
# 4515.
set(PSXRECOMP_GAME_EXE_NAME_OVERRIDE "" CACHE STRING
    "Override this game's runtime OUTPUT_NAME (default: Tomba2Recomp)")
set(PSXRECOMP_GAME_DEBUG_PORT_OVERRIDE "" CACHE STRING
    "Override this game's default TCP debug port (default: 4515)")

set(_tomba2_exe_name "Tomba2Recomp")
if(PSXRECOMP_GAME_EXE_NAME_OVERRIDE)
    set(_tomba2_exe_name "${PSXRECOMP_GAME_EXE_NAME_OVERRIDE}")
endif()
set(_tomba2_debug_port 4515)
if(PSXRECOMP_GAME_DEBUG_PORT_OVERRIDE)
    set(_tomba2_debug_port "${PSXRECOMP_GAME_DEBUG_PORT_OVERRIDE}")
endif()

# Tomba 2's trusted, game-owned mod catalogs. The authentic 4:3/non-interpolated
# presentation and stock guest code remain the disabled baseline. The Italian
# runtime ships a SEPARATE localized catalog: Italian psx.* manifests that
# override the framework's English ones at the same id and version, the three
# tombi2.* packages, and deliberately NO tomba2.debug.debug-menu (its payload is
# US-layout-specific).
#
# The FRAMEWORK stages both, one per runtime target, via PRELOADED_MODS_DIR
# below. Each target's POST_BUILD wipes <exe-dir>/mods/bundled and re-stages
# exactly the framework's builtin packages plus that target's own catalog, so
# the US and Italian runtimes -- which share one output directory -- can no
# longer contaminate each other and the old hand-written
#
#     COMMAND ${CMAKE_COMMAND} -E rm -rf .../mods/packages/tombi2.*
#
# exclusion lists are gone. Those lists existed only because the previous
# hand-rolled copy MERGED into a directory the other target had already
# written; they were also the sharpest edge of the mods/packages ->
# mods/bundled rename in framework 4cc04be3, since a find-and-replace of the
# copy destination alone would have left them pointing at a directory nothing
# writes any more and the Italian build would have silently shipped Debug Menu.
# Bead beads-eio.3.101.
set(TOMBA2_PRELOADED_MODS "${CMAKE_CURRENT_SOURCE_DIR}/mods/preloaded")
set(TOMBA2_PRELOADED_MODS_ITA "${CMAKE_CURRENT_SOURCE_DIR}/mods/preloaded_ita")

# USA Seamless Loading replaces the generic CD-speed and host-turbo mods.
# Restore the caller's selection afterward: Italian has no resident adapter.
set(_tomba2_previous_builtin_allowlist "${PSX_BUILTIN_MOD_ALLOWLIST}")
set(PSX_BUILTIN_MOD_ALLOWLIST
    psx.enhancement.pgxp
    psx.presentation.bezel)
psxrecomp_add_runtime_target(psx-runtime
    PGXP
    GAME_GENERATED_FULL_C "${GAME_GENERATED_FULL}"
    GAME_GENERATED_DISPATCH_C "${GAME_GENERATED_DISPATCH}"
    EXTRAS_SOURCES ${TOMBA2_MOD_PLUGIN_SOURCES}
    PRELOADED_MODS_DIR "${TOMBA2_PRELOADED_MODS}"
    # (OUTPUT_NAME set below: the exe ships as Tomba2Recomp.exe so process
    # management — taskkill, port collisions, task manager — never confuses
    # this title with other psxrecomp games' psx-runtime.exe instances.
    # PSXRECOMP_GAME_EXE_NAME_OVERRIDE swaps this for an isolated build.)
    # 4515: Tomba2's OWN debug port. 4500 collides with the SNES mmx_cosim
    # processes (they bind 127.0.0.1:4500 too and eat connections); other
    # taken ports: 4370/4380 psxrecomp-v4, 4470 Tomba1, 4510 Tsumu, 4520 MMX5.
    # PSXRECOMP_GAME_DEBUG_PORT_OVERRIDE swaps this for an isolated build.
    DEBUG_PORT ${_tomba2_debug_port}
    WINDOW_TITLE "Tomba! 2 Recompiled"
    # No DEFAULT_BIOS_PATH: an absolute value would bake a build-machine path
    # into the binary (the framework refuses those and falls back to relative
    # "bios/SCPH1001.BIN"). Dev trees resolve it via the exe-dir upward search
    # (psxrecomp-v4/bios); user installs use bios.cfg / the picker.
    DEFAULT_GAME_CONFIG_PATH "game.toml"
    LAUNCHER_BOXART "${CMAKE_SOURCE_DIR}/recomp/launcher/boxart.tga"
)
set(PSX_BUILTIN_MOD_ALLOWLIST "${_tomba2_previous_builtin_allowlist}")
unset(_tomba2_previous_builtin_allowlist)

# Distinct process name (see comment above).
set_target_properties(psx-runtime PROPERTIES OUTPUT_NAME "${_tomba2_exe_name}")
tomba2_add_loading_implementation(psx-runtime)
tomba2_add_terrain_implementation(psx-runtime)

if(BUILD_TESTING)
    add_executable(tomba2_seamless_prepare_test
        tests/test_seamless_prepare.cpp
        src/mods/tomba2_seamless_prepare.cpp
        "${PSXRECOMP_ROOT}/runtime/src/psx_sha256.c")
    target_include_directories(tomba2_seamless_prepare_test PRIVATE
        "${PSXRECOMP_ROOT}/runtime/include")
    add_executable(tomba2_preloaded_mods_test
        tests/test_preloaded_mods.cpp
        "${PSXRECOMP_ROOT}/runtime/src/mod_packages.cpp"
        "${PSXRECOMP_ROOT}/runtime/src/crc32.c"
        "${PSXRECOMP_ROOT}/runtime/src/psx_sha256.c"
    )
    target_include_directories(tomba2_preloaded_mods_test PRIVATE
        "${PSXRECOMP_ROOT}/runtime/include"
        "${PSXRECOMP_ROOT}/recompiler/lib/toml11"
    )
    add_test(
        NAME tomba2_preloaded_mods_test
        COMMAND "$<TARGET_FILE:tomba2_preloaded_mods_test>"
                "${TOMBA2_PRELOADED_MODS}"
                "${TOMBA2_PRELOADED_MODS_ITA}"
    )
endif()

# ---------------------------------------------------------------------------
# Italian PAL release (Tombi! 2 - The Evil Swine Return, SCES-02686).
# Same runtime, same mod plugins; only the game image differs. The recompiler
# writes generated_ita/SCES_026.86_* shards from game_ita.toml.
file(GLOB GAME_ITA_GENERATED_FULL CONFIGURE_DEPENDS
    "${CMAKE_CURRENT_SOURCE_DIR}/generated_ita/SCES_026.86_full_*.c")
set(GAME_ITA_GENERATED_DISPATCH
    "${CMAKE_CURRENT_SOURCE_DIR}/generated_ita/SCES_026.86_dispatch.c")

set(PSXRECOMP_GAME_ITA_EXE_NAME_OVERRIDE "" CACHE STRING
    "Override the Italian runtime OUTPUT_NAME (default: Tombi2Recomp-ita)")
set(PSXRECOMP_GAME_ITA_DEBUG_PORT_OVERRIDE "" CACHE STRING
    "Override the Italian runtime TCP debug port (default: 4516)")

set(_tomba2_ita_exe_name "Tombi2Recomp-ita")
if(PSXRECOMP_GAME_ITA_EXE_NAME_OVERRIDE)
    set(_tomba2_ita_exe_name "${PSXRECOMP_GAME_ITA_EXE_NAME_OVERRIDE}")
endif()
set(_tomba2_ita_debug_port 4516)
if(PSXRECOMP_GAME_ITA_DEBUG_PORT_OVERRIDE)
    set(_tomba2_ita_debug_port "${PSXRECOMP_GAME_ITA_DEBUG_PORT_OVERRIDE}")
endif()

psxrecomp_add_runtime_target(psx-runtime-ita
    GAME_GENERATED_FULL_C "${GAME_ITA_GENERATED_FULL}"
    GAME_GENERATED_DISPATCH_C "${GAME_ITA_GENERATED_DISPATCH}"
    EXTRAS_SOURCES ${TOMBA2_MOD_PLUGIN_SOURCES}
    PRELOADED_MODS_DIR "${TOMBA2_PRELOADED_MODS_ITA}"
    DEBUG_PORT ${_tomba2_ita_debug_port}
    WINDOW_TITLE "Tombi! 2 (Italian) Recompiled"
    DEFAULT_GAME_CONFIG_PATH "game_ita.toml"
    LAUNCHER_BOXART "${CMAKE_SOURCE_DIR}/recomp/launcher/boxart.tga"
)

set_target_properties(psx-runtime-ita PROPERTIES OUTPUT_NAME
    "${_tomba2_ita_exe_name}")
tomba2_add_loading_implementation(psx-runtime-ita)
tomba2_add_terrain_implementation(psx-runtime-ita)

recomp_target_launcher_language(psx-runtime-ita it)

# (No mod-catalog POST_BUILD here: PRELOADED_MODS_DIR above hands
# mods/preloaded_ita to the framework, which wipes mods/bundled and stages
# exactly the Italian catalog for this target. The US packages that the old
# hand-written rm -rf list stripped can no longer be present at all.)
