1:1 source port of the engine and game code; Windows build and system layer; docs. No game files or SDK headers.

This commit is contained in:
CRTkafa 2026-10-22 16:30:40 +08:00
parent c3b032a45a
commit 0ecb47e9cb
3871 changed files with 91080 additions and 1640063 deletions

138
port/CMakeLists.txt Normal file
View file

@ -0,0 +1,138 @@
# Windows system layer (task 9), not 1:1: CMake + Ninja build of choc3port.exe for Windows (32-bit, llvm-mingw).
# The Mac build is port/Makefile (unchanged). Configure and build with port/winbuild.sh (sets up the toolchain paths):
# bash port/winbuild.sh # configure + build everything (-j4)
# Nothing here runs the game.
cmake_minimum_required(VERSION 3.20)
project(choc3port C CXX)
if(NOT WIN32)
message(FATAL_ERROR "port/CMakeLists.txt is the Windows build; use port/Makefile on macOS")
endif()
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 4)
message(FATAL_ERROR "The port is built 32-bit (ILP32) like the shipped game binary: use cmake/llvm-mingw-i686.cmake")
endif()
get_filename_component(ROOT "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE)
set(TP "${ROOT}/parity-out/thirdparty") # third-party sources (tools/port/build_thirdparty.sh fetches/patches)
set(Z "${TP}/src/zlib-1.2.1")
set(PNG "${TP}/src/libpng-1.2.5")
set(JPG "${TP}/build/jpeg-6b") # patched (tools/port/thirdparty/jpeg-6b-playground.patch)
set(JAS "${TP}/build/jasper-1.900.1/src/libjasper")
set(LUA "${TP}/build/lua-5.0.2") # patched (tools/port/thirdparty/lua-5.0.2-luaplus.patch)
set(OGG "${TP}/src/libogg-1.0")
set(VORBIS "${TP}/src/libvorbis-1.0")
set(OPENAL_SRC "${TP}/src/openal-soft") # OpenAL Soft 1.24.x (headers; the DLL is built by winbuild.sh)
set(OPENAL_BUILD "${TP}/win32/openal-build")
# ---- one flag set for everything -------------------------------------------------------------------------------------
# SSE2 scalar math like the shipped game (FP_CONTRACT off is also pragma'd in the sources).
set(PF_ARCH_FLAGS -msse2 -mfpmath=sse -ffp-contract=off -mstackrealign)
# ---- third-party libraries (same sources, flags and file lists as tools/port/build_thirdparty.sh) ---------------------
function(tp_lib name)
cmake_parse_arguments(A "" "" "SOURCES;INCLUDES;DEFS;OPTS" ${ARGN})
add_library(${name} STATIC ${A_SOURCES})
target_include_directories(${name} PRIVATE ${A_INCLUDES} "${CMAKE_CURRENT_SOURCE_DIR}/src/win/include")
target_compile_definitions(${name} PRIVATE ${A_DEFS})
target_compile_options(${name} PRIVATE -O2 -w -std=gnu89 ${PF_ARCH_FLAGS} ${A_OPTS})
set_target_properties(${name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
endfunction()
function(prefix_list out prefix)
set(l)
foreach(n ${ARGN})
list(APPEND l "${prefix}/${n}.c")
endforeach()
set(${out} ${l} PARENT_SCOPE)
endfunction()
prefix_list(Z_SRC "${Z}" adler32 compress crc32 deflate gzio infback inffast inflate inftrees trees uncompr zutil)
tp_lib(tp_z SOURCES ${Z_SRC})
prefix_list(PNG_SRC "${PNG}" png pngerror pngget pngmem pngpread pngread pngrio pngrtran pngrutil pngset pngtrans
pngwio pngwrite pngwtran pngwutil)
# pngconf.h takes <fp.h> for MACOS unless <math.h> is already in: pre-include it (no source change)
tp_lib(tp_png SOURCES ${PNG_SRC} INCLUDES ${Z} OPTS -include math.h)
prefix_list(JPG_SRC "${JPG}" jcapimin jcapistd jccoefct jccolor jcdctmgr jchuff jcinit jcmainct jcmarker jcmaster
jcomapi jcparam jcphuff jcprepct jcsample jctrans jdapimin jdapistd jdatadst jdatasrc jdcoefct jdcolor
jddctmgr jdhuff jdinput jdmainct jdmarker jdmaster jdmerge jdphuff jdpostct jdsample jdtrans jerror
jfdctflt jidctflt jidctred jquant1 jquant2 jutils jmemmgr jmemansi)
tp_lib(tp_jpeg SOURCES ${JPG_SRC} INCLUDES ${JPG})
prefix_list(JAS_BASE "${JAS}/base" jas_cm jas_debug jas_getopt jas_icc jas_iccdata jas_image jas_init jas_malloc
jas_seq jas_stream jas_string jas_tmr jas_tvp jas_version)
prefix_list(JAS_JP2 "${JAS}/jp2" jp2_cod jp2_dec jp2_enc)
prefix_list(JAS_JPC "${JAS}/jpc" jpc_bs jpc_cs jpc_dec jpc_enc jpc_math jpc_mct jpc_mqcod jpc_mqdec jpc_mqenc jpc_qmfb
jpc_t1cod jpc_t1dec jpc_t1enc jpc_t2cod jpc_t2dec jpc_t2enc jpc_tagtree jpc_tsfb jpc_util)
tp_lib(tp_jasper SOURCES ${JAS_BASE} ${JAS_JP2} ${JAS_JPC} INCLUDES "${JAS}/include"
DEFS EXCLUDE_MIF_SUPPORT EXCLUDE_PNM_SUPPORT EXCLUDE_BMP_SUPPORT EXCLUDE_RAS_SUPPORT EXCLUDE_JPG_SUPPORT
EXCLUDE_PGX_SUPPORT)
prefix_list(LUA_CORE "${LUA}/src" lapi lcode ldebug ldo ldump lfunc lgc llex lmem lobject lopcodes lparser lstate
lstring ltable ltm lundump lvm lzio LuaPlusAddons)
prefix_list(LUA_LIB "${LUA}/src/lib" lauxlib lbaselib lstrlib ltablib lmathlib)
tp_lib(tp_lua SOURCES ${LUA_CORE} ${LUA_LIB} INCLUDES "${LUA}/include" "${LUA}/src")
prefix_list(OGG_SRC "${OGG}/src" bitwise framing)
tp_lib(tp_ogg SOURCES ${OGG_SRC} INCLUDES "${OGG}/include")
prefix_list(VORBIS_SRC "${VORBIS}/lib" analysis bitrate block codebook envelope floor0 floor1 info lookup lpc lsp
mapping0 mdct psy registry res0 sharedbook smallft synthesis window)
tp_lib(tp_vorbis SOURCES ${VORBIS_SRC} INCLUDES "${OGG}/include" "${VORBIS}/include" "${VORBIS}/lib")
tp_lib(tp_vorbisfile SOURCES "${VORBIS}/lib/vorbisfile.c" INCLUDES "${OGG}/include" "${VORBIS}/include")
# ---- the port ----------------------------------------------------------------------------------------------------------
file(GLOB_RECURSE ENGINE_SRC CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/core/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/gl/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/mac/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/game/*.cpp")
file(GLOB WIN_SRC CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/win/*.cpp")
# Mac-only files with a Windows replacement in src/win (see docs/port/windows.md):
# mac/link_stubs.cpp (link-only stubs) -> win/carbon_compat.cpp (working Carbon/AGL/URL Access stand-ins)
# mac/fileio.cpp (CoreFoundation, dirent d_type) -> win/fileio_win.cpp
# mac/drm/HardwareFingerprint.cpp (IOKit) -> win/hardwarefingerprint_win.cpp
# mac/flashhost.mm (WebKit; .mm is not globbed) -> win/flashhost_win.cpp
list(FILTER ENGINE_SRC EXCLUDE REGEX "/src/mac/(link_stubs|fileio)\\.cpp$|/src/mac/drm/HardwareFingerprint\\.cpp$")
# sdk-only files that are compiled but not linked (the shipped game has no TDisplay / TFlatFileMap symbols), as in port/Makefile
set(NOLINK_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/core/display.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/core/flatfilemap.cpp")
list(REMOVE_ITEM ENGINE_SRC ${NOLINK_SRC})
set(PORT_INCLUDES
"${CMAKE_CURRENT_SOURCE_DIR}/src/win/include" "${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/src/core" "${CMAKE_CURRENT_SOURCE_DIR}/src/gl" "${CMAKE_CURRENT_SOURCE_DIR}/src/mac"
"${CMAKE_CURRENT_SOURCE_DIR}/game" "${LUA}/src" "${OGG}/include" "${VORBIS}/include" "${JPG}" "${PNG}" "${Z}"
"${JAS}/include" "${PNG}/contrib/visupng" "${OPENAL_SRC}/include" "${CMAKE_CURRENT_SOURCE_DIR}/src/win")
# The game's boost has BOOST_HAS_THREADS (shared_ptr counts guarded by a pthread mutex at +12). boost's gcc.hpp leaves it
# undefined for MinGW, which made every shared_ptr count non-atomic across the sound and main threads.
set(PORT_DEFS BOOST_HAS_THREADS BOOST_HAS_PTHREADS BOOST_LWM_USE_PTHREADS NDEBUG PF_WINDOWS_PORT BOOST_NO_AUTO_PTR _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
set(PORT_OPTS -std=c++17 -w -g -fno-omit-frame-pointer ${PF_ARCH_FLAGS} -include pfwin_compat.h)
add_library(choc3_nolink OBJECT ${NOLINK_SRC})
target_include_directories(choc3_nolink PRIVATE ${PORT_INCLUDES})
target_compile_definitions(choc3_nolink PRIVATE ${PORT_DEFS})
target_compile_options(choc3_nolink PRIVATE ${PORT_OPTS})
set_target_properties(choc3_nolink PROPERTIES CXX_STANDARD 17)
add_executable(choc3port ${ENGINE_SRC} ${WIN_SRC})
target_include_directories(choc3port PRIVATE ${PORT_INCLUDES})
target_compile_definitions(choc3port PRIVATE ${PORT_DEFS})
target_compile_options(choc3port PRIVATE ${PORT_OPTS})
set_target_properties(choc3port PROPERTIES CXX_STANDARD 17 RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
# Order matters for static libs: vorbisfile -> vorbis -> ogg; png -> z; jasper, jpeg, lua (lua calls pf_* in the port).
target_link_libraries(choc3port PRIVATE tp_vorbisfile tp_vorbis tp_ogg tp_png tp_jasper tp_jpeg tp_lua tp_z
"${OPENAL_BUILD}/libOpenAL32.dll.a"
opengl32 glu32 wininet iphlpapi ws2_32 shell32 ole32 user32 gdi32 winmm pthread)
target_link_options(choc3port PRIVATE -static -Wl,--wrap=fopen)
# OpenAL Soft runtime next to the exe (LGPL: kept as a DLL).
add_custom_command(TARGET choc3port POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENAL_BUILD}/OpenAL32.dll" "$<TARGET_FILE_DIR:choc3port>/OpenAL32.dll")
# llvm-mingw runtime DLLs (libc++ is shared in the toolchain's i686 sysroot): copy them next to the exe too.
foreach(dll libc++.dll libunwind.dll libwinpthread-1.dll)
add_custom_command(TARGET choc3port POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${LLVM_MINGW_ROOT}/i686-w64-mingw32/bin/${dll}" "$<TARGET_FILE_DIR:choc3port>/${dll}")
endforeach()