cmake_minimum_required(VERSION 3.24)
project(MarioParty2Recompiled VERSION 0.2.2 LANGUAGES C CXX)
set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(SDL2 REQUIRED)
find_package(Threads REQUIRED)
add_executable(renderer_patch_test tests/renderer_patch_test.cpp)
target_include_directories(renderer_patch_test PRIVATE src)
option(MP2_NETPLAY_ONLY "Build networking integration tests without the game/renderer" OFF)
include(cmake/Netplay.cmake)
if(MP2_NETPLAY_ONLY)
    return()
endif()

find_package(CURL 7.71 REQUIRED)
add_library(mp2_public_ip STATIC src/public_ip.cpp)
target_include_directories(mp2_public_ip PUBLIC src)
target_link_libraries(mp2_public_ip PUBLIC CURL::libcurl)
add_executable(public_ip_test tests/public_ip_test.cpp)
target_link_libraries(public_ip_test PRIVATE mp2_public_ip)
if(WIN32)
    find_package(SDL2_ttf CONFIG REQUIRED)
else()
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(SDL2_TTF REQUIRED IMPORTED_TARGET SDL2_ttf)
    pkg_check_modules(RUNTIME_DATA REQUIRED IMPORTED_TARGET gtk+-3.0 fontconfig xkbcommon)
endif()
option(MP2_PORTABILITY_CHECK "Build with synthetic link fixtures, without a ROM" OFF)
if(WIN32)
    add_compile_definitions(NOMINMAX WIN32_LEAN_AND_MEAN)
endif()
set(RT64_STATIC ON CACHE BOOL "" FORCE)
set(RT64_SDL_WINDOW_VULKAN ON CACHE BOOL "" FORCE)
add_subdirectory(rt64)
add_subdirectory(runtime)
if(MINGW)
    target_compile_options(plume PUBLIC "$<$<COMPILE_LANGUAGE:CXX>:-fms-extensions>"
        "$<$<COMPILE_LANGUAGE:CXX>:SHELL:-include \"${CMAKE_SOURCE_DIR}/src/mingw_compat.hpp\">")
    target_link_libraries(rt64 dwmapi d3dcompiler)
    target_compile_options(rabbitizer PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-include;cstdlib>")
    include(cmake/MinGWCompat.cmake)
    target_include_directories(plume BEFORE PUBLIC
        ${CMAKE_SOURCE_DIR}/rt64/src/contrib/dxc/inc
        ${CMAKE_SOURCE_DIR}/directx-headers/include
        ${CMAKE_SOURCE_DIR}/directx-headers/include/directx
        ${CMAKE_SOURCE_DIR}/directx-headers/include/dxguids)
    target_compile_definitions(plume PUBLIC D3D12MA_USING_DIRECTX_HEADERS)
    target_sources(plume PRIVATE ${CMAKE_SOURCE_DIR}/directx-headers/src/dxguids.cpp)
    get_target_property(RT64_LINKS rt64 LINK_LIBRARIES)
    list(TRANSFORM RT64_LINKS REPLACE "^delayimp.lib$" "delayimp")
    set_property(TARGET rt64 PROPERTY LINK_LIBRARIES "${RT64_LINKS}")
endif()
set_property(SOURCE runtime/librecomp/src/ultra_translation.cpp TARGET_DIRECTORY librecomp PROPERTY COMPILE_DEFINITIONS
    "osGetTime_recomp=mp2_original_osGetTime_recomp;osGetCount_recomp=mp2_original_osGetCount_recomp")
set_property(SOURCE runtime/librecomp/src/pi.cpp TARGET_DIRECTORY librecomp PROPERTY COMPILE_DEFINITIONS "osEPiStartDma_recomp=mp2_original_osEPiStartDma_recomp")
if(MP2_PORTABILITY_CHECK)
    file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/fixtures)
    configure_file(tests/fixture_funcs.h ${CMAKE_BINARY_DIR}/fixtures/funcs.h COPYONLY)
    configure_file(tests/fixture_overlays.inl ${CMAKE_BINARY_DIR}/fixtures/recomp_overlays.inl COPYONLY)
    set(RECOMP_SOURCES tests/portability_stubs.cpp)
    set(RECOMP_HEADERS ${CMAKE_BINARY_DIR}/fixtures)
    set(RSP_SOURCE "")
else()
    file(GLOB RECOMP_SOURCES CONFIGURE_DEPENDS RecompiledFuncs/funcs_*.c)
    set(RECOMP_HEADERS ${CMAKE_SOURCE_DIR}/RecompiledFuncs)
    set(RSP_SOURCE src/aspMain.cpp)
endif()
add_library(mp2_code STATIC ${RECOMP_SOURCES})
target_include_directories(mp2_code PUBLIC N64Recomp/include ${RECOMP_HEADERS} runtime/librecomp/include runtime/ultramodern/include runtime/thirdparty/concurrentqueue)
target_compile_options(mp2_code PRIVATE -fno-strict-aliasing -ffp-contract=off -Wno-implicit-function-declaration)
add_executable(mp2recomp src/debug_state.cpp src/debug.cpp src/debug_renderer.cpp src/main.cpp src/settings.cpp src/renderer.cpp src/process.cpp src/overlays.cpp src/platform.cpp src/self_test.cpp src/netplay_game.cpp src/netplay_lobby.cpp ${RSP_SOURCE})
mp2_copy_steam_runtime(mp2recomp)
target_include_directories(mp2recomp PRIVATE
    N64Recomp/include ${RECOMP_HEADERS}
    rt64/src rt64/src/contrib rt64/src/contrib/plume rt64/src/contrib/hlslpp/include
    rt64/src/contrib/mupen64plus-core/src/api rt64/src/contrib/imgui
    rt64/src/contrib/plume/contrib/VulkanMemoryAllocator/include)
target_compile_definitions(mp2recomp PRIVATE HLSL_CPU SDL_MAIN_HANDLED RT64_SDL_WINDOW_VULKAN PLUME_SDL_VULKAN_ENABLED)
target_link_libraries(mp2recomp PRIVATE mp2_public_ip mp2_netplay mp2_code librecomp ultramodern rt64 SDL2::SDL2 Threads::Threads ${CMAKE_DL_LIBS})
target_compile_options(mp2recomp PRIVATE -fno-strict-aliasing)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
    target_compile_options(mp2recomp PRIVATE -msse4.1)
endif()
if(WIN32)
    target_link_libraries(mp2recomp PRIVATE SDL2_ttf::SDL2_ttf Winmm Shcore)
else()
    target_link_libraries(mp2recomp PRIVATE PkgConfig::SDL2_TTF PkgConfig::RUNTIME_DATA)
    target_link_options(mp2recomp PRIVATE -rdynamic)
endif()

if(WIN32)
    foreach(DLL dxcompiler.dll dxil.dll)
        add_custom_command(TARGET mp2recomp POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different
            "${CMAKE_SOURCE_DIR}/rt64/src/contrib/dxc/bin/x64/${DLL}" "$<TARGET_FILE_DIR:mp2recomp>/${DLL}")
    endforeach()
endif()

include(cmake/PrebuiltRuntime.cmake)
