cmake_minimum_required(VERSION 3.15)
project(Hydralis LANGUAGES C CXX ASM)

if(NOT DEFINED FXSDK_PLATFORM OR NOT FXSDK_PLATFORM STREQUAL "cg")
    message(FATAL_ERROR "targets only Graph 90+E/fx-CG50")
endif()

include(GenerateG3A)
include(Fxconv)
find_package(Gint 2.11 REQUIRED)
find_package(Azur 0.1 REQUIRED)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

add_compile_options(-fno-freestanding)

set(ENGINE_SOURCES
    Engine/src/Components/BillboardAnimator.cpp
    Engine/src/Components/BillboardCharacterRenderer.cpp
    Engine/src/Components/BillboardObjectRenderer.cpp
    Engine/src/Components/BillboardRaster.S
    Engine/src/Components/BillboardRenderSystem.cpp
    Engine/src/Components/Camera.cpp
    Engine/src/Components/SpriteRenderer.cpp
    Engine/src/Components/Tilemap.cpp
    Engine/src/Internal/OvalShader.cpp
    Engine/src/Internal/WorldRenderSystem.cpp
    Engine/src/Component.cpp
    Engine/src/Runtime.cpp
    Engine/src/GameObject.cpp
    Engine/src/Math.cpp
    Engine/src/Scene.cpp
    Engine/src/SceneManager.cpp
    Engine/src/Sprite.cpp
    Engine/src/Time.cpp
    Engine/src/Transform.cpp
    Engine/src/UI.cpp
)

set(GAME_SOURCES
    Game/src/Components/BoxCollider.cpp
    Game/src/Components/DepthProjector.cpp
    Game/src/Components/DemoHud.cpp
    Game/src/Components/Door.cpp
    Game/src/Components/Interact.cpp
    Game/src/Components/IntroSequence.cpp
    Game/src/Components/PlayerCamera.cpp
    Game/src/Components/PlayerController.cpp
    Game/src/Components/MainMenu.cpp
    Game/src/Components/Rigidbody.cpp
    Game/src/Components/Shadow.cpp
    Game/src/Components/TilemapCameraController.cpp
    Game/src/Components/TilemapCollider.cpp
    Game/src/Components/TilemapHud.cpp
    Game/src/Components/WaterLevel.cpp
    Game/src/Components/WaterToggleTrigger.cpp
    Game/src/Components/WorldSwitch.cpp
    Game/src/Components/ZeldaController.cpp
    Game/src/Dialogue.cpp
    Game/src/Prefabs.cpp
    Game/src/Scenes.cpp
    Game/src/State.cpp
    Game/src/main.cpp
)

file(GLOB TILEMAP_ASSETS CONFIGURE_DEPENDS
    assets-cg/tilemap/*.tm.json
    assets-cg/tilemap/*.sprites
    assets-cg/tilemap/*.png
)

file(GLOB COLLISION_ASSETS CONFIGURE_DEPENDS
    assets-cg/collision/*.collider
)

file(GLOB UI_ASSETS CONFIGURE_DEPENDS
    assets-cg/UI/*.sprites
    assets-cg/UI/*.canvas
    assets-cg/UI/ui_*.png
)

file(GLOB GAME_SPRITE_ASSETS CONFIGURE_DEPENDS
    assets-cg/sprites/*.sprites
    assets-cg/sprites/*.png
)

set(ASSETS_CG
    assets-cg/billboard/bb_Dimartino_atlas.png
    assets-cg/billboard/bb_Dimartino.bb.json
    ${TILEMAP_ASSETS}
    ${COLLISION_ASSETS}
    ${UI_ASSETS}
    ${GAME_SPRITE_ASSETS}
)

fxconv_declare_converters(Engine/tools/asset_converter.py)
fxconv_declare_assets(${ASSETS_CG} WITH_METADATA)

set_property(
    SOURCE assets-cg/billboard/bb_Dimartino.bb.json
    APPEND PROPERTY OBJECT_DEPENDS
    "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/asset_converter.py"
    "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/billboard_converter.py"
)

foreach(TILEMAP_ASSET IN LISTS TILEMAP_ASSETS)
    if(TILEMAP_ASSET MATCHES "\\.tm\\.json$")
        set_property(
            SOURCE "${TILEMAP_ASSET}"
            APPEND PROPERTY OBJECT_DEPENDS
            "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/asset_converter.py"
            "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/tilemap_converter.py"
        )
    elseif(TILEMAP_ASSET MATCHES "\\.sprites$")
        set_property(
            SOURCE "${TILEMAP_ASSET}"
            APPEND PROPERTY OBJECT_DEPENDS
            "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/asset_converter.py"
            "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/sprite_converter.py"
        )
    endif()
endforeach()

foreach(COLLISION_ASSET IN LISTS COLLISION_ASSETS)
    set_property(
        SOURCE "${COLLISION_ASSET}"
        APPEND PROPERTY OBJECT_DEPENDS
        "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/asset_converter.py"
        "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/tilemap_collider_converter.py"
    )
endforeach()

foreach(UI_ASSET IN LISTS UI_ASSETS GAME_SPRITE_ASSETS)
    if(UI_ASSET MATCHES "\\.sprites$")
        set_property(
            SOURCE "${UI_ASSET}"
            APPEND PROPERTY OBJECT_DEPENDS
            "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/asset_converter.py"
            "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/sprite_converter.py"
        )
    elseif(UI_ASSET MATCHES "\\.canvas$")
        set_property(
            SOURCE "${UI_ASSET}"
            APPEND PROPERTY OBJECT_DEPENDS
            "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/asset_converter.py"
            "${CMAKE_CURRENT_SOURCE_DIR}/Engine/tools/canvas_converter.py"
        )
    endif()
endforeach()

add_executable(Hydralis
    ${ENGINE_SOURCES}
    ${GAME_SOURCES}
    ${ASSETS_CG}
)

target_include_directories(Hydralis PRIVATE
    "${CMAKE_CURRENT_SOURCE_DIR}/Engine/include"
    "${CMAKE_CURRENT_SOURCE_DIR}/Game/include"
)

target_compile_options(Hydralis PRIVATE
    -Wall
    -Wextra
    -Wshadow
    -Wconversion
    -O3
    -flto=auto
    -fno-exceptions
    -fno-rtti
    -fno-threadsafe-statics
    -ffunction-sections
    -fdata-sections
)

target_link_options(Hydralis PRIVATE
    -flto=auto
    -Wl,--gc-sections
)

target_link_libraries(Hydralis PRIVATE
    Azur::Azur
    Gint::Gint
    -lstdc++
)

generate_g3a(
    TARGET Hydralis
    OUTPUT "Hydralis.g3a"
    NAME "HYDRALIS"
    ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png
)
