cmake_minimum_required(VERSION 3.16)
project(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 C CXX)

include(CheckIPOSupported)

# Set C standard
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Migrate stale generated-project cache entries when the default profile changes.
set(GBRECOMP_PROFILE_CACHE_VERSION "2")
set(GBRECOMP_APPLIED_PROFILE_CACHE_VERSION "0" CACHE STRING "Internal generated-project profile version")
if(NOT GBRECOMP_APPLIED_PROFILE_CACHE_VERSION STREQUAL GBRECOMP_PROFILE_CACHE_VERSION)
    set(GBRECOMP_ENABLE_IPO OFF CACHE BOOL "Enable interprocedural optimization/LTO for non-Debug builds" FORCE)
    set(GBRECOMP_ENABLE_STRIP ON CACHE BOOL "Strip symbols from generated executables in non-Debug builds" FORCE)
    set(GBRECOMP_GENERATED_OPT_LEVEL "1" CACHE STRING "Optimization level for the generated ROM source files" FORCE)
    set(GBRECOMP_APPLIED_PROFILE_CACHE_VERSION "${GBRECOMP_PROFILE_CACHE_VERSION}" CACHE STRING "Internal generated-project profile version" FORCE)
endif()

# Default to a smaller, iteration-friendly profile for generated projects.
# Benchmark and release builds can still opt into Release/-O3/IPO explicitly.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
    set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Build type" FORCE)
endif()
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
        add_compile_options(-O0 -g)
    elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
        add_compile_options(-O2 -g)
    elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
        add_compile_options(-Os)
    else()
        add_compile_options(-O3)
    endif()
    add_compile_options(-ffunction-sections -fdata-sections)
endif()
# Very large ROMs (e.g. Pokemon 1MB) blow past the default COFF
# relocation limit on Windows; -Wa,-mbig-obj uses the extended header.
if(WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang"))
    add_compile_options(-Wa,-mbig-obj)
endif()

# Runtime library path (relative to this output directory)
set(GBRT_DIR "/home/claude/gbrecompiled/runtime")

set(GBRECOMP_HOST_COMPILER "/home/claude/gbrecompiled/./build/bin/gbrecomp" CACHE FILEPATH "Host gbrecomp for native BIOS compilation")
# Locate the recomp-ui launcher checkout (sibling of the gbcrecomp tree).
# The depth of this generated project varies per game, and some link the
# runtime through a symlink (which defeats lexical ../ walking), so probe a
# few candidate layouts with REALPATH (resolves symlinks) and keep the first
# that actually contains recomp_ui.cmake. Override with -DRECOMP_UI_ROOT=...
# to force one. Set BEFORE add_subdirectory(GBRT_DIR) so the runtime build
# inherits the same root (cache set is idempotent -> game value wins).
if(NOT RECOMP_UI_ROOT)
    foreach(_gb_rui_cand
            "${GBRT_DIR}/../../../recomp-ui"
            "${GBRT_DIR}/../../recomp-ui"
            "${CMAKE_CURRENT_SOURCE_DIR}/../../../recomp-ui"
            "${CMAKE_CURRENT_SOURCE_DIR}/../../recomp-ui")
        get_filename_component(_gb_rui_abs "${_gb_rui_cand}" REALPATH)
        if(EXISTS "${_gb_rui_abs}/recomp_ui.cmake")
            set(RECOMP_UI_ROOT "${_gb_rui_abs}" CACHE PATH "Root of the recomp-ui launcher checkout")
            break()
        endif()
    endforeach()
endif()

# Find SDL2
if(NOT TARGET SDL2::SDL2)
    find_package(SDL2 REQUIRED)
endif()

# Build the runtime library via its own CMakeLists -- the single
# source of truth for runtime sources, include dirs, and link libs.
# Never duplicate the source list here (it drifts from the runtime).
add_subdirectory(${GBRT_DIR} ${CMAKE_CURRENT_BINARY_DIR}/gbrt_build)

# Main executable
set(GBRECOMP_GAME_SOURCES
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_main.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_dispatch_chunk_0.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_dispatch_chunk_1.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_dispatch_chunk_2.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_dispatch_chunk_3.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_0.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_1.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_2.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_3.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_4.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_5.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_6.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_7.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_8.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_9.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_10.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_11.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_12.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_rom.c
)

if(ANDROID)
    add_library(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 SHARED ${GBRECOMP_GAME_SOURCES})
    set_target_properties(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 PROPERTIES OUTPUT_NAME main)
else()
    add_executable(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 ${GBRECOMP_GAME_SOURCES})
endif()

# Pick up an optional extras.c from the project root (one level up).
# Game projects (e.g. Tetris, Pokemon Red/Blue) provide ROM-identity hooks
# (game_get_expected_crc32, game_get_valid_crcs) in this file.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../extras.c")
    target_sources(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../extras.c")
    message(STATUS "Blue_s_Clues___Blue_s_Alphabet_Book__USA__1: linking extras.c from project root")
endif()

# Optional per-game build extension. A game project can drop a
# 'game_build.cmake' in its root (one level up) to add extra sources
# (e.g. a C++ overlay TU, mock modules), include dirs, or link libs.
# GBRECOMP_GAME_TARGET names the executable target to attach them to.
set(GBRECOMP_GAME_TARGET Blue_s_Clues___Blue_s_Alphabet_Book__USA__1)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../game_build.cmake")
    include("${CMAKE_CURRENT_SOURCE_DIR}/../game_build.cmake")
    message(STATUS "Blue_s_Clues___Blue_s_Alphabet_Book__USA__1: applied game_build.cmake extension")
endif()

# Generated ROM code defaults to a smaller manual-testing profile.
# Raise the optimization level or enable IPO/LTO explicitly for benchmark/release builds.
set(GBRECOMP_GENERATED_OPT_LEVEL "1" CACHE STRING "Optimization level for the generated ROM source files")
set_property(CACHE GBRECOMP_GENERATED_OPT_LEVEL PROPERTY STRINGS 0 1 2 3)
option(GBRECOMP_ENABLE_IPO "Enable interprocedural optimization/LTO for non-Debug builds" OFF)
option(GBRECOMP_ENABLE_STRIP "Strip symbols from generated executables in non-Debug builds" ON)
set(GBRECOMP_GENERATED_SOURCES
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_dispatch_chunk_0.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_dispatch_chunk_1.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_dispatch_chunk_2.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_dispatch_chunk_3.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_0.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_1.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_2.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_3.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_4.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_5.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_6.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_7.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_8.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_9.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_10.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_11.c
    Blue_s_Clues___Blue_s_Alphabet_Book__USA__1_funcs_12.c
)
set_source_files_properties(${GBRECOMP_GENERATED_SOURCES} PROPERTIES COMPILE_OPTIONS "-O${GBRECOMP_GENERATED_OPT_LEVEL}")

if(NOT MSVC AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
    if(APPLE)
        target_link_options(gbrt PRIVATE -Wl,-dead_strip)
        target_link_options(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 PRIVATE -Wl,-dead_strip)
    else()
        target_link_options(gbrt PRIVATE -Wl,--gc-sections)
        target_link_options(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 PRIVATE -Wl,--gc-sections)
    endif()
endif()

if(GBRECOMP_ENABLE_IPO AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
    check_ipo_supported(RESULT GBRECOMP_IPO_SUPPORTED OUTPUT GBRECOMP_IPO_ERROR)
    if(GBRECOMP_IPO_SUPPORTED)
        set_property(TARGET gbrt PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
        set_property(TARGET Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
    else()
        message(STATUS "GB Recompiled: IPO/LTO not enabled (${GBRECOMP_IPO_ERROR})")
    endif()
endif()

target_link_libraries(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 gbrt)

# [launcher] Stage the recomp-ui launcher assets (fonts, console art) and
# this game's box art next to the exe. No-op when recomp-ui is absent (the
# runtime then falls back to the legacy file-picker boot). Box art lives at
# <project>/recomp/launcher/boxart.tga (one level up from this output dir).
if(EXISTS "${RECOMP_UI_ROOT}/recomp_ui.cmake")
    include(${RECOMP_UI_ROOT}/recomp_ui.cmake)
    set(_gb_boxart "${CMAKE_CURRENT_SOURCE_DIR}/../recomp/launcher/boxart.tga")
    if(EXISTS "${_gb_boxart}")
        recomp_stage_launcher_assets(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 CONSOLE ${GBRECOMP_LAUNCHER_CONSOLE} BOXART "${_gb_boxart}")
    else()
        recomp_stage_launcher_assets(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 CONSOLE ${GBRECOMP_LAUNCHER_CONSOLE})
    endif()
endif()

if(WIN32 AND TARGET SDL2::SDL2main)
    # SDL2 redefines main to SDL_main via SDL.h; SDL2main provides WinMain.
    target_link_libraries(Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 SDL2::SDL2main)
endif()
option(GBRECOMP_STAGE_RUNTIME_DLLS "Copy the mingw-w64 runtime DLLs next to the executable (Windows/GNU)" ON)
if(WIN32 AND GBRECOMP_STAGE_RUNTIME_DLLS AND CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
    get_filename_component(_gb_toolchain_bin "${CMAKE_C_COMPILER}" DIRECTORY)
    foreach(_gb_dll SDL2.dll libEGL.dll libGLESv2.dll zlib1.dll libgcc_s_seh-1.dll libstdc++-6.dll libwinpthread-1.dll)
        if(EXISTS "${_gb_toolchain_bin}/${_gb_dll}")
            add_custom_command(TARGET Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_gb_toolchain_bin}/${_gb_dll}" $<TARGET_FILE_DIR:Blue_s_Clues___Blue_s_Alphabet_Book__USA__1>
                VERBATIM)
        else()
            message(WARNING "Blue_s_Clues___Blue_s_Alphabet_Book__USA__1: runtime DLL ${_gb_dll} not found in ${_gb_toolchain_bin}; the packaged tree will need it")
        endif()
    endforeach()
endif()
if(GBRECOMP_ENABLE_STRIP AND NOT MSVC AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
    if(APPLE)
        add_custom_command(TARGET Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 POST_BUILD
            COMMAND ${CMAKE_STRIP} -Sx $<TARGET_FILE:Blue_s_Clues___Blue_s_Alphabet_Book__USA__1>
            VERBATIM)
    elseif(CMAKE_STRIP)
        add_custom_command(TARGET Blue_s_Clues___Blue_s_Alphabet_Book__USA__1 POST_BUILD
            COMMAND ${CMAKE_STRIP} --strip-debug $<TARGET_FILE:Blue_s_Clues___Blue_s_Alphabet_Book__USA__1>
            VERBATIM)
    endif()
endif()
