# Tuxanci 2 - A first person shooter
# Copyright (C) 2007-2011 Tuxánci Development Team
# Copyright (C) 2025-2026 Connor Thomson
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
cmake_minimum_required(VERSION 3.12)
project(tuxanci2 VERSION 0.29.0 LANGUAGES C)
option(UNIX_LIKE "Enable features exclusive to UNIX-like systems" ${CMAKE_HOST_UNIX})
option(ENABLE_AUDIO "Enable audio" ON)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
include(CompileShaders)
configure_file(${CMAKE_SOURCE_DIR}/include/version.h.in
${CMAKE_BINARY_DIR}/include/version.h
@ONLY)
file(GLOB_RECURSE C_SRC_FILES CONFIGURE_DEPENDS "src/*.c")
file(GLOB_RECURSE SLANG_SRC_FILES CONFIGURE_DEPENDS "shaders/*.slang")
set(DATA_FILES
"${CMAKE_SOURCE_DIR}/data/fonts/DejaVuSans.ttf"
"${CMAKE_SOURCE_DIR}/data/music/theme.it"
"${CMAKE_SOURCE_DIR}/data/models/teapot.obj"
)
foreach(DATA_FILE ${DATA_FILES})
if(NOT EXISTS "${DATA_FILE}")
message(FATAL_ERROR "Required data file not found: ${DATA_FILE}")
endif()
endforeach()
add_executable(${PROJECT_NAME} ${C_SRC_FILES})
target_include_directories(${PROJECT_NAME} PRIVATE
include
${CMAKE_BINARY_DIR}/include
)
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -pedantic)
target_compile_options(${PROJECT_NAME} PRIVATE
-g
$<$:-fdebug-prefix-map=${CMAKE_SOURCE_DIR}/src=>
)
if(EMSCRIPTEN)
set(UNIX_LIKE OFF)
set(ENABLE_AUDIO OFF)
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html")
target_compile_options(${PROJECT_NAME} PRIVATE -sUSE_SDL=3 -sUSE_SDL_TTF=3)
target_link_options(${PROJECT_NAME} PRIVATE
-sUSE_SDL=3
-sUSE_SDL_TTF=3
-sENVIRONMENT=web
-sWASM=1
)
set_target_properties(${PROJECT_NAME} PROPERTIES
LINK_FLAGS "--shell-file ${CMAKE_SOURCE_DIR}/em/${PROJECT_NAME}.html"
)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/em/${PROJECT_NAME}.css
${CMAKE_BINARY_DIR}/${PROJECT_NAME}.css
)
else()
if(UNIX_LIKE)
message(STATUS "UNIX_LIKE: ON")
target_compile_definitions(${PROJECT_NAME} PRIVATE UNIX_LIKE)
find_package(Threads REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(UNWIND REQUIRED libunwind)
target_link_libraries(${PROJECT_NAME} PRIVATE Threads::Threads ${UNWIND_LIBRARIES})
target_include_directories(${PROJECT_NAME} PRIVATE ${UNWIND_INCLUDE_DIRS})
target_compile_options(${PROJECT_NAME} PRIVATE ${UNWIND_CFLAGS_OTHER})
pkg_check_modules(DW REQUIRED libdw)
target_link_libraries(${PROJECT_NAME} PRIVATE ${DW_LIBRARIES})
target_include_directories(${PROJECT_NAME} PRIVATE ${DW_INCLUDE_DIRS})
target_compile_options(${PROJECT_NAME} PRIVATE ${DW_CFLAGS_OTHER})
else()
message(STATUS "UNIX_LIKE: OFF")
endif()
if(WIN32)
set(ENABLE_AUDIO OFF)
find_package(SDL3 CONFIG REQUIRED)
find_package(SDL3_ttf CONFIG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE
SDL3::SDL3
SDL3_ttf::SDL3_ttf
)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"$"
"$"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"$"
"$"
)
else()
pkg_check_modules(SDL REQUIRED sdl3)
target_link_libraries(${PROJECT_NAME} PRIVATE ${SDL_LIBRARIES} m)
target_include_directories(${PROJECT_NAME} PRIVATE ${SDL_INCLUDE_DIRS})
target_compile_options(${PROJECT_NAME} PRIVATE ${SDL_CFLAGS_OTHER})
pkg_check_modules(SDL_TTF REQUIRED sdl3-ttf)
target_link_libraries(${PROJECT_NAME} PRIVATE ${SDL_TTF_LIBRARIES})
target_include_directories(${PROJECT_NAME} PRIVATE ${SDL_TTF_INCLUDE_DIRS})
target_compile_options(${PROJECT_NAME} PRIVATE ${SDL_TTF_CFLAGS_OTHER})
endif()
if(ENABLE_AUDIO)
message(STATUS "ENABLE_AUDIO: ON")
target_compile_definitions(${PROJECT_NAME} PRIVATE ENABLE_AUDIO)
pkg_check_modules(OPENAL REQUIRED openal)
target_link_libraries(${PROJECT_NAME} PRIVATE ${OPENAL_LIBRARIES})
target_include_directories(${PROJECT_NAME} PRIVATE ${OPENAL_INCLUDE_DIRS})
target_compile_options(${PROJECT_NAME} PRIVATE ${OPENAL_CFLAGS_OTHER})
pkg_check_modules(OPENMPT REQUIRED libopenmpt)
target_link_libraries(${PROJECT_NAME} PRIVATE ${OPENMPT_LIBRARIES})
target_include_directories(${PROJECT_NAME} PRIVATE ${OPENMPT_INCLUDE_DIRS})
target_compile_options(${PROJECT_NAME} PRIVATE ${OPENMPT_CFLAGS_OTHER})
else()
message(STATUS "ENABLE_AUDIO: OFF")
endif()
endif()
target_compile_shaders(${PROJECT_NAME} SHADERS ${SLANG_SRC_FILES})
target_embed_files(${PROJECT_NAME} FILES ${DATA_FILES})