Recovers the game's event-posting API so the engine can post events and the
compare harness can see them. Until now the owner's event list was invisible to
every layer: B3's replace-mode oracle failed by exactly one item across 40,300
(an unposted EVENT_RESEARCH_OVERBUDGET) while its compare read clean, and B2's
clean compare bounds the economy fields only.
New pure module src/game/events:
* EventStorage / TurnEvents / PlayerEvent -- the list is bucketed by TURN, not
flat, which the save-editor struct notes had wrong.
* EventStorage::Post reproducing the original's rules, including the four that
change save bytes: the FLT_MAX (not infinity) default position; action 0 with
no subject and no position storing as 2; per-bucket dedup that compares
message/image/location/position/action but NOT summary; and EvNxID starting
at 0 and being promoted to 1 on the first post.
* PruneOldTurns reproduced with its off-by-one: of a leading run of buckets
older than turn-50 it erases n-1, so one stale bucket always survives. The
survivor is serialized, so correcting it would diverge.
* research_events: the five events the research path raises, their EvImg
identifiers and string-table keys, and the 0.8 completion split evaluated
against (double)0.8f rather than the decimal 0.8.
Localized text is deliberately absent: only the EVENTSUM_/EVENTMSG_ keys are
here and the text resolves through a caller-supplied lookup, as the game does.
The four event offsets the B3 hook carried as local literals now come from the
generated header; they are read off instructions rather than inferred from the
save schema.
tests/game_events: 112 checks including a replay of the event list
turn3-state.sav actually holds. ctest 31/31 -> 32/32.
docs/E-events.md carries the proposed region and Coverage wording for the next
B3 recapture.
104 lines
5.7 KiB
CMake
104 lines
5.7 KiB
CMake
cmake_minimum_required(VERSION 3.25)
|
|
project(sots-engine LANGUAGES C CXX)
|
|
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
|
|
# Build id stamped into the shim log banner (tools/build-shim.sh passes git describe + UTC time).
|
|
set(SHIM_BUILD_ID "dev" CACHE STRING "Build identifier logged by the shim")
|
|
|
|
# Provenance of the binary facts: the generated header's own "Source:" line, forwarded verbatim
|
|
# so every shim.log records which RE snapshot the RVAs came from.
|
|
file(STRINGS include/generated/sots_addresses.h _addr_provenance REGEX "^// Source:")
|
|
list(GET _addr_provenance 0 _addr_provenance)
|
|
string(REGEX REPLACE "^// " "" SOTS_ADDR_PROVENANCE "${_addr_provenance}")
|
|
|
|
add_library(sots_addresses INTERFACE)
|
|
target_include_directories(sots_addresses INTERFACE ${CMAKE_SOURCE_DIR}/include)
|
|
|
|
# ---- engine modules (host + cross): pure, oracle-verified code accrues here ----
|
|
add_subdirectory(src/mars/parse) # brace-block + .effect readers (lib mars_parse)
|
|
add_subdirectory(src/mars/text) # flat-kv, id-manifest, csv (lib mars_text)
|
|
add_subdirectory(src/game/sim) # strategic formulas, pure (lib sots_game_sim)
|
|
add_subdirectory(src/mars/vfs) # .gob ZIP reader + native override (lib mars_vfs, miniz)
|
|
add_subdirectory(src/mars/stream) # Streamable save format + gzip (lib mars_stream)
|
|
add_subdirectory(src/mars/rng) # MT19937 (lib mars_rng)
|
|
add_subdirectory(src/game/config) # flat KEY/value constants loader (lib sots_game_config)
|
|
add_subdirectory(src/game/data) # typed catalogs on mars/parse+text (lib game_data)
|
|
add_subdirectory(src/game/effects) # tech effects (TechId table + apply) (lib game_effects)
|
|
add_subdirectory(src/game/design) # ship-design rules + derived stats (lib game_design)
|
|
add_subdirectory(src/game/events) # player event log + research events (lib sots_game_events)
|
|
|
|
# ---- shim trace/compare infrastructure (host-testable; linked into binkw32) ----
|
|
add_library(shim_trace STATIC
|
|
src/shim/trace/sha256.cpp
|
|
src/shim/trace/emitter.cpp
|
|
src/shim/trace/tracer.cpp
|
|
src/shim/trace/selftest.cpp)
|
|
target_include_directories(shim_trace PUBLIC ${CMAKE_SOURCE_DIR}/src)
|
|
target_compile_options(shim_trace PRIVATE -Wall -Wextra -Werror)
|
|
if(MINGW)
|
|
target_compile_definitions(shim_trace PUBLIC __USE_MINGW_ANSI_STDIO=1) # C99 %lld/%.17g
|
|
endif()
|
|
|
|
# ---- B1 budget adapter: ServerPlayer snapshot <-> game::sim economy (pure, host-tested) ----
|
|
add_library(shim_budget STATIC src/shim/hooks/budget_inputs.cpp)
|
|
target_link_libraries(shim_budget PUBLIC shim_trace sots_game_sim)
|
|
target_compile_options(shim_budget PRIVATE -Wall -Wextra -Werror)
|
|
|
|
# ---- B2 tech-effect adapter: ServerPlayer fields <-> game::effects state (pure, host-tested) ----
|
|
add_library(shim_techfx STATIC src/shim/hooks/tech_effect_fields.cpp)
|
|
target_link_libraries(shim_techfx PUBLIC shim_trace sots_addresses sots_game_effects)
|
|
target_compile_options(shim_techfx PRIVATE -Wall -Wextra -Werror)
|
|
|
|
# ---- B4 colony adapter: ServerSystem snapshot <-> game::sim colony turn (pure, host-tested) ----
|
|
add_library(shim_colony STATIC src/shim/hooks/colony_inputs.cpp)
|
|
target_link_libraries(shim_colony PUBLIC shim_trace sots_game_sim)
|
|
target_compile_options(shim_colony PRIVATE -Wall -Wextra -Werror)
|
|
|
|
# ---- B4 movement adapter: StarFleet snapshot <-> game::sim movement (pure, host-tested) ----
|
|
add_library(shim_movement STATIC src/shim/hooks/movement_inputs.cpp)
|
|
target_link_libraries(shim_movement PUBLIC shim_trace sots_game_sim)
|
|
target_compile_options(shim_movement PRIVATE -Wall -Wextra -Werror)
|
|
|
|
if(WIN32)
|
|
# ---- shim: proxy binkw32.dll that the original game loads (Phase 2 frontend) ----
|
|
add_library(minhook STATIC
|
|
third_party/minhook/src/buffer.c
|
|
third_party/minhook/src/hook.c
|
|
third_party/minhook/src/trampoline.c
|
|
third_party/minhook/src/hde/hde32.c)
|
|
target_include_directories(minhook PUBLIC third_party/minhook/include)
|
|
|
|
# ---- hooks: one descriptor per hooked game function (src/shim/hooks/*) ----
|
|
add_library(shim_hooks STATIC src/shim/hooks/global_consts.cpp src/shim/hooks/dictionaries.cpp
|
|
src/shim/hooks/research.cpp
|
|
src/shim/hooks/tech_effects.cpp
|
|
src/shim/hooks/compute_budget.cpp
|
|
src/shim/hooks/colony_turn.cpp
|
|
src/shim/hooks/fleet_movement.cpp)
|
|
target_link_libraries(shim_hooks PUBLIC shim_trace sots_addresses sots_game_config sots_game_sim
|
|
sots_game_effects mars_rng shim_budget shim_techfx
|
|
shim_colony shim_movement)
|
|
target_compile_options(shim_hooks PRIVATE -Wall -Wextra -Werror)
|
|
|
|
add_library(binkw32 SHARED src/shim/main.cpp src/shim/binkw32.def)
|
|
target_link_libraries(binkw32 PRIVATE minhook sots_addresses shim_trace shim_hooks)
|
|
target_compile_definitions(binkw32 PRIVATE
|
|
SHIM_BUILD_ID="${SHIM_BUILD_ID}"
|
|
SOTS_ADDR_PROVENANCE="${SOTS_ADDR_PROVENANCE}")
|
|
# Must be exactly binkw32.dll (no "lib" prefix); export names come solely from the .def.
|
|
set_target_properties(binkw32 PROPERTIES PREFIX "" OUTPUT_NAME "binkw32")
|
|
else()
|
|
# ---- host: engine module tests (ctest) + a header smoke test ----
|
|
enable_testing()
|
|
add_executable(addr_smoke tests/addr_smoke.cpp)
|
|
target_link_libraries(addr_smoke PRIVATE sots_addresses)
|
|
add_test(NAME addr_smoke COMMAND addr_smoke)
|
|
foreach(_t mars_parse game_config game_data game_design game_sim mars_stream mars_text mars_vfs shim_trace game_effects game_events shim_budget shim_techfx shim_colony shim_movement)
|
|
if(EXISTS ${CMAKE_SOURCE_DIR}/tests/${_t}/CMakeLists.txt)
|
|
add_subdirectory(tests/${_t})
|
|
endif()
|
|
endforeach()
|
|
endif()
|