cmake_minimum_required(VERSION 3.13)

option(PS1_BUILD "Build for the original Sony Playstation" OFF)
option(HOST_BUILD "Build for host platform using SDL-1.2" OFF)
option(WIN9X_BUILD "Build for Win9x using SDL-1.2" OFF)

if(NOT PS1_BUILD AND NOT HOST_BUILD AND NOT WIN9X_BUILD)
    message(FATAL_ERROR "Please define target platform. Available options:
        PS1_BUILD
        HOST_BUILD
        WIN9X_BUILD
        Run CMake again using one of the available platforms e.g.: cmake .. -DPS1_BUILD=1")
endif()

if(PS1_BUILD)
    if("$ENV{PSXSDK_PATH}" STREQUAL "")
        message(FATAL_ERROR "Please set PSXSDK_PATH env variable first")
    endif()

    set(CMAKE_C_COMPILER psx-gcc)
    set(CMAKE_AR mipsel-unknown-elf-ar)
elseif(WIN9X_BUILD)
    set(CMAKE_C_COMPILER i386-mingw32-gcc)
endif()

project(rts)

add_executable(${PROJECT_NAME} "src/main.c")
set(cdroot ${CMAKE_BINARY_DIR}/cdimg)

if(PS1_BUILD)
    file(MAKE_DIRECTORY ${cdroot})
    target_link_directories(${PROJECT_NAME} PUBLIC $ENV{PSXSDK_PATH}/lib)
    target_link_libraries(${PROJECT_NAME} PUBLIC -lpsx -lfixmath)
    target_compile_definitions(${PROJECT_NAME} PUBLIC FIXMATH_FAST_SIN PSXSDK_DEBUG)
    target_include_directories(${PROJECT_NAME} PRIVATE . $ENV{PSXSDK_PATH}/include)
    add_custom_target(exe ALL elf2exe ${PROJECT_NAME}
        ${cdroot}/${PROJECT_NAME}.exe -mark="A homebrew game created with PSXSDK"
        DEPENDS ${PROJECT_NAME})
    add_custom_target(iso ALL mkisofs -o ${PROJECT_NAME}.iso -V ${PROJECT_NAME}
        -sysid PLAYSTATION ${cdroot} DEPENDS exe)
    set(license $ENV{PSXSDK_PATH}/share/licenses/infoeur.dat)
    add_custom_target(bin_cue ALL mkpsxiso ${PROJECT_NAME}.iso ${PROJECT_NAME}.bin
        ${license} -s DEPENDS iso)
    # add_custom_target(libpsx ALL DEPENDS $ENV{PSXSDK_PATH}/lib/libpsx.a)
    # add_dependencies(${PROJECT_NAME} libpsx)

    if(NOT EXISTS "${cdroot}/system.cnf")
        file(WRITE "${cdroot}/system.cnf"
            "BOOT = cdrom:\\${PROJECT_NAME}.exe;1\n"
            "TCB = 4\n"
            "EVENT = 8\n"
            "STACK = 801FF800\n")
    endif()
elseif(WIN9X_BUILD)
    file(MAKE_DIRECTORY ${cdroot})
    if("$ENV{SDL_PATH}" STREQUAL "")
        message(FATAL_ERROR "please define env variable SDL_PATH")
    elseif("$ENV{SDL_TTF_PATH}" STREQUAL "")
        message(FATAL_ERROR "please define env variable SDL_TTF_PATH")
    elseif("$ENV{FREETYPE_PATH}" STREQUAL "")
        message(FATAL_ERROR "please define env variable FREETYPE_PATH")
    elseif("$ENV{SDL_MIXER_PATH}" STREQUAL "")
        message(FATAL_ERROR "please define env variable SDL_MIXER_PATH")
    endif()

    add_custom_command(OUTPUT ${cdroot}/${PROJECT_NAME}
            COMMAND i386-mingw32-strip ${PROJECT_NAME} -o ${cdroot}/${PROJECT_NAME}
            WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
            DEPENDS ${PROJECT_NAME}
            VERBATIM)
    add_custom_target(stripped-exe ALL DEPENDS ${cdroot}/${PROJECT_NAME})

    target_link_directories(${PROJECT_NAME} PRIVATE $ENV{SDL_PATH}/lib
        $ENV{SDL_TTF_PATH}/lib $ENV{FREETYPE_PATH}/lib
        $ENV{SDL_MIXER_PATH}/lib)
    include_directories($ENV{SDL_PATH}/include
        $ENV{SDL_PATH}/include/SDL $ENV{SDL_TTF_PATH}/include
        $ENV{FREETYPE_PATH}/include
        $ENV{SDL_MIXER_PATH}/include)
    add_compile_options(-march=i386)
    link_libraries(gdi32 user32 winmm dxguid freetype)
    set(SDL1_2_BUILD 1)
elseif(HOST_BUILD)
    file(MAKE_DIRECTORY ${cdroot})
    find_package(SDL 1.2 REQUIRED)
    find_package(SDL_mixer 1.2 REQUIRED)
    set(SDL1_2_BUILD 1)
    #find_package(SDL_ttf 2.0 REQUIRED)
endif()

# libfixmath is already bundled with PSXSDK.
if(NOT PS1_BUILD)
    if("$ENV{FIXMATH_PATH}" STREQUAL "")
        message(FATAL_ERROR "please define env variable FIXMATH_PATH")
    endif()

    add_subdirectory($ENV{FIXMATH_PATH} ${CMAKE_BINARY_DIR}/libfixmath)
endif()

add_subdirectory("res")

set(components
    building
    camera
    container
    font
    game
    gfx
    gui
    instance
    pad
    player
    resource
    sfx
    system
    terrain
    unit
    util
)

set(interfaces
    tech
)

# Avoid C11 since it is not supported by the i386-mingw32 toolchain.
set(cflags -Wall -g3 -ffunction-sections -fdata-sections -pedantic -std=c99)

if(WIN9X_BUILD)
    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
        # i386-mingw32-gcc 3.4.5 does not support -Og.
        set(cflags ${cflags} -O0)
    else()
        set(cflags ${cflags} -O2)
    endif()
elseif(PS1_BUILD)
    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
        set(cflags ${cflags} -Og)
    else()
        set(cflags ${cflags} -Os)
    endif()

    set(cflags ${cflags} -fshort-enums)
else()
    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
        set(cflags ${cflags} -Og)
    else()
        set(cflags ${cflags} -O3)
    endif()
endif()

target_compile_options(${PROJECT_NAME} PUBLIC ${cflags})

foreach(c ${components})
    add_subdirectory("src/${c}")
    target_compile_options(${c} PUBLIC ${cflags})
    target_link_libraries(${PROJECT_NAME} PRIVATE ${c})
endforeach()

foreach(i ${interfaces})
    add_subdirectory("src/${i}")
    target_compile_options(${i} INTERFACE ${cflags})
    target_link_libraries(${PROJECT_NAME} PRIVATE ${c})
endforeach()

target_link_options(${PROJECT_NAME} PRIVATE -Wl,--gc-sections)
