feat(math): Route game logic math through WWMath with 3-mode deterministic support#2670
feat(math): Route game logic math through WWMath with 3-mode deterministic support#2670Okladnoj wants to merge 4 commits intoTheSuperHackers:mainfrom
Conversation
Integrate GameMath library (fdlibm) for bit-perfect cross-platform floating-point reproducibility. When USE_DETERMINISTIC_MATH is active, all WWMath functions (Sin, Cos, Sqrt, Inv_Sqrt, Float_To_Long, Acos, Asin, Atan, Atan2) use fdlibm instead of x87 asm or system CRT. - Add GameMath via FetchContent with global include paths - Replace Trig.cpp with inline WWMath::*Trig wrappers - Add WWMath::*Origin wrappers for bare CRT calls in game logic - Prioritize USE_DETERMINISTIC_MATH over _MSC_VER/_M_IX86 guards - Verified: win32 replay CRC matches original x87 output
Add global Sqrt(double) to trig.h/Trig.cpp, routing through WWMath::SqrtOrigin(). Replace 5 bare CRT sqrt() calls in BaseType.h (Coord2D::length, Coord2D::toAngle, ICoord2D::length, Coord3D::length, ICoord3D::length) with the new Sqrt() gateway. This closes the last known CRT math leak in CRC-critical code paths. Same pattern as existing Sin/Cos/ACos routing via Trig.cpp.
|
| Filename | Overview |
|---|---|
| Core/Libraries/Source/WWVegas/WWMath/wwmath.h | Core of the PR: adds USE_DETERMINISTIC_MATH block and ~80 new Origin/Trig inline wrappers over GameMath gm_* functions; USE_DETERMINISTIC_MATH is defined unconditionally for non-VC6 regardless of whether gmath.h was found (discussed in prior threads), and double overloads silently narrow to float before calling gm_*f (also in prior threads). |
| cmake/gamemath.cmake | New CMake module: fetches GameMath at a pinned commit, disables intrinsics/tests with FORCE overrides, and adds a global include_directories for gmath.h — a CMake anti-pattern that could cause silent link failures in targets that include wwmath.h without linking gamemath. |
| Core/GameEngine/Source/Common/Diagnostic/SimulationMathCrc.cpp | Math CRC fingerprint updated to use WWMath Origin wrappers; remaining raw CRT calls (tanf/asinf/acosf) replaced with deterministic equivalents per prior thread; sinhf/coshf/tanhf/logf wrappers now go through GameMath equivalents. |
| Core/Libraries/Include/Lib/BaseType.h | sqrt → Sqrt migration in Coord2D/Coord3D/ICoord2D/ICoord3D length() methods; changes are mechanical and correct. |
| Core/Libraries/Include/Lib/trig.h | Adds double Sqrt(double x) declaration to the global trig helper header; consistent with the new Trig.cpp implementation that routes through WWMath::SqrtOrigin. |
| Core/Libraries/Source/WWVegas/WWMath/CMakeLists.txt | Links gamemath as a PUBLIC dependency of core_wwmath for non-VC6 builds, ensuring transitive propagation to downstream targets. |
| Generals/Code/GameEngine/Source/Common/System/Trig.cpp | All five trig functions redirected to WWMath::*Trig wrappers; new double Sqrt(double) added that routes through SqrtOrigin. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp | Comprehensive routing of fabs/sqrtf/atan2/fabsf calls to WWMath Origin wrappers in physics simulation — mechanical and consistent. |
| CMakeLists.txt | Includes gamemath.cmake for non-VC6 builds via a conditional include block; minimal and correct. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Math call site\ne.g. sqrtf / fabs / atan2] --> B{Compiler target?}
B -- VC6\n_MSC_VER < 1300 --> C[x87 inline ASM\noriginal WWMath]
B -- Non-VC6 --> D{USE_DETERMINISTIC_MATH\nalways defined}
D -- gmath.h found\nvia global include_dirs --> E[GameMath gm_*f\ncross-platform deterministic]
D -- gmath.h NOT found\nlinker error --> F[Link failure\nunresolved gm_* symbols]
E --> G[WWMath::*Origin / *Trig\ninline wrappers in wwmath.h]
G --> H[Game logic\nsimulation result]
C --> H
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
cmake/gamemath.cmake:14-16
**Global `include_directories` pollutes all target include paths**
`include_directories()` is a directory-scope CMake command that injects `${gamemath_SOURCE_DIR}/include` into every target compiled under this directory. Combined with `USE_DETERMINISTIC_MATH` being unconditionally defined on non-VC6, any target that transitively includes `wwmath.h` but does **not** link `core_wwmath` (or `gamemath` directly) will compile cleanly (because `gmath.h` is now found globally) but fail at link time with unresolved `gm_*` symbols. The comment acknowledges the intent, but the modern CMake idiom — `target_include_directories(core_wwmath PUBLIC ${gamemath_SOURCE_DIR}/include)` — achieves the same ODR-safe propagation to all downstream consumers of `core_wwmath` without silently affecting unrelated targets.
Reviews (3): Last reviewed commit: "fix(math): Restore original formatting a..." | Re-trigger Greptile
Here is what replay playback looks like at the moment.
I’m testing this on a separate branch: I slightly adjusted the CI there so I can run Win32 and get access to the game resources. |
854cc7b to
779f714
Compare
|
You did not review the changes you made with AI. It has issues that you should fix before asking it to be reviewed. |
…erage - Restore original Trig.cpp code (author comments, defines, REGENERATE_TRIG_TABLES) - Keep only functional changes: sinf->WWMath::SinTrig redirects + Sqrt(double) - Restore original tab alignment in wwmath.h #define block - Route remaining CRT calls in SimulationMathCrc through WWMath (sinh/cosh/tanh/logf) - Add cmake comments explaining FORCE usage

Rework of #2602, incorporating review feedback:
USE_DETERMINISTIC_MATHunconditional for non-VC6 — missinggmath.his now a compile error instead of silent fallback to x87/CRTCI: win32 + vc6 ✅, replay checks ✅
Open question: Replay checks pass both with and without
USE_DETERMINISTIC_MATH, even though golden replays were recorded with an x87 build. The replays may not containMSG_LOGIC_CRCmessages, meaning the check only validates absence of crashes rather than game state CRC parity. If anyone has insight on this — please share.