cmake_minimum_required(VERSION 3.24)
project(Llamatron VERSION 1.2.0 LANGUAGES C CXX RC)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_BUILD_TYPE Release)
endif()
# The C/C++ runtime linked statically: the portable folder is just the exe.
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
# Release builds keep a PDB (crash dumps, profiles).
if(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  string(APPEND CMAKE_C_FLAGS_RELEASE " -gcodeview -gline-tables-only")
  string(APPEND CMAKE_CXX_FLAGS_RELEASE " -gcodeview -gline-tables-only")
  string(APPEND CMAKE_EXE_LINKER_FLAGS_RELEASE " -Wl,-debug -Wl,-opt:ref -Wl,-opt:icf")
endif()

# SDL3, static.
set(SDL_SHARED OFF CACHE BOOL "" FORCE)
set(SDL_STATIC ON CACHE BOOL "" FORCE)
set(SDL_TEST_LIBRARY OFF CACHE BOOL "" FORCE)
set(SDL_EXAMPLES OFF CACHE BOOL "" FORCE)
add_subdirectory(third_party/SDL EXCLUDE_FROM_ALL)

# Musashi 68000 core: its sources are copied to the build dir with our m68kconf.h over theirs, and the opcode
# tables are generated by its m68kmake tool.
set(MUSASHI_SRC ${CMAKE_SOURCE_DIR}/third_party/musashi)
set(MUSASHI_GEN ${CMAKE_BINARY_DIR}/musashi)
file(MAKE_DIRECTORY ${MUSASHI_GEN})
foreach(f m68k.h m68kcpu.h m68kcpu.c m68kdasm.c m68kfpu.c m68kmmu.h m68k_in.c m68kmake.c)
  configure_file(${MUSASHI_SRC}/${f} ${MUSASHI_GEN}/${f} COPYONLY)
endforeach()
file(COPY ${MUSASHI_SRC}/softfloat DESTINATION ${MUSASHI_GEN})
configure_file(${CMAKE_SOURCE_DIR}/src/musashi/m68kconf.h ${MUSASHI_GEN}/m68kconf.h COPYONLY)

add_executable(m68kmake ${MUSASHI_GEN}/m68kmake.c)
target_compile_definitions(m68kmake PRIVATE _CRT_SECURE_NO_WARNINGS)
add_custom_command(
  OUTPUT ${MUSASHI_GEN}/m68kops.c ${MUSASHI_GEN}/m68kops.h
  COMMAND m68kmake ${MUSASHI_GEN} ${MUSASHI_GEN}/m68k_in.c
  DEPENDS m68kmake ${MUSASHI_GEN}/m68k_in.c
  WORKING_DIRECTORY ${MUSASHI_GEN})

add_library(musashi STATIC
  ${MUSASHI_GEN}/m68kcpu.c ${MUSASHI_GEN}/m68kdasm.c ${MUSASHI_GEN}/m68kops.c
  ${MUSASHI_GEN}/softfloat/softfloat.c)
target_include_directories(musashi PUBLIC ${MUSASHI_GEN})
target_compile_definitions(musashi PRIVATE _CRT_SECURE_NO_WARNINGS)
if(CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
  target_compile_options(musashi PRIVATE -w)
endif()

configure_file(res/llamatron.rc.in ${CMAKE_BINARY_DIR}/llamatron.rc @ONLY)
add_executable(llamatron WIN32
  ${CMAKE_BINARY_DIR}/llamatron.rc
  src/main.cpp
  src/machine.cpp
  src/cpu_musashi.cpp
  src/ym2149.cpp
  src/disk.cpp
  src/input.cpp
  src/game.cpp
  src/gridrunner.cpp
  src/launcher.cpp
  src/crt.cpp
  src/settings.cpp
  src/log.cpp
  src/crash.cpp)
target_link_libraries(llamatron PRIVATE SDL3::SDL3-static musashi)
target_compile_definitions(llamatron PRIVATE _CRT_SECURE_NO_WARNINGS)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
  target_compile_options(llamatron PRIVATE -Wall -Wextra -Wno-unused-parameter)
endif()
