Skip to content

Commit 779f714

Browse files
committed
fix(math): Enforce USE_DETERMINISTIC_MATH and complete deterministic coverage
1 parent 65fa335 commit 779f714

4 files changed

Lines changed: 33 additions & 17 deletions

File tree

Core/GameEngine/Source/Common/Diagnostic/SimulationMathCrc.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,16 @@ static void appendSimulationMathCrc(XferCRC &xfer)
3939
factorsMatrix.Set(
4040
WWMath::Sin(0.7f) * log10f(2.3f),
4141
WWMath::Cos(1.1f) * powf(1.1f, 2.0f),
42-
tanf(0.3f),
43-
asinf(0.967302263f),
44-
acosf(0.967302263f),
42+
WWMath::TanfOrigin(0.3f),
43+
WWMath::ASinfOrigin(0.967302263f),
44+
WWMath::ACosfOrigin(0.967302263f),
4545
WWMath::AtanfOrigin(0.967302263f) * WWMath::PowfOrigin(1.1f, 2.0f),
4646
WWMath::Atan2fOrigin(0.4f, 1.3f),
47-
sinhf(0.2f),
48-
coshf(0.4f) * tanhf(0.5f),
47+
WWMath::SinhfOrigin(0.2f),
48+
WWMath::CoshfOrigin(0.4f) * WWMath::TanhfOrigin(0.5f),
4949
WWMath::SqrtfOrigin(55788.84375f),
5050
WWMath::ExpfOrigin(0.1f) * WWMath::Log10fOrigin(2.3f),
51-
logf(1.4f));
51+
WWMath::LogfOrigin(1.4f));
5252

5353
Matrix3D::Multiply(matrix, factorsMatrix, &matrix);
5454
matrix.Get_Inverse(matrix);

Core/Libraries/Source/WWVegas/WWMath/wwmath.h

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,26 @@
4646
#if !(defined(_MSC_VER) && _MSC_VER < 1300)
4747
#if defined(__has_include) && __has_include("gmath.h")
4848
#include "gmath.h"
49-
#define USE_DETERMINISTIC_MATH
5049
#endif
5150
#endif
5251

52+
#if !(defined(_MSC_VER) && _MSC_VER < 1300)
53+
#define USE_DETERMINISTIC_MATH
54+
#endif
55+
5356
/*
5457
** Some global constants.
5558
*/
56-
#define WWMATH_EPSILON 0.0001f
57-
#define WWMATH_EPSILON2 WWMATH_EPSILON * WWMATH_EPSILON
59+
#define WWMATH_EPSILON 0.0001f
60+
#define WWMATH_EPSILON2 WWMATH_EPSILON * WWMATH_EPSILON
5861
#define WWMATH_PI 3.141592654f
59-
#define WWMATH_TWO_PI 6.283185308f
60-
#define WWMATH_FLOAT_MAX (FLT_MAX)
61-
#define WWMATH_FLOAT_MIN (FLT_MIN)
62-
#define WWMATH_SQRT2 1.414213562f
63-
#define WWMATH_SQRT3 1.732050808f
64-
#define WWMATH_OOSQRT2 0.707106781f
65-
#define WWMATH_OOSQRT3 0.577350269f
62+
#define WWMATH_TWO_PI 6.283185308f
63+
#define WWMATH_FLOAT_MAX (FLT_MAX)
64+
#define WWMATH_FLOAT_MIN (FLT_MIN)
65+
#define WWMATH_SQRT2 1.414213562f
66+
#define WWMATH_SQRT3 1.732050808f
67+
#define WWMATH_OOSQRT2 0.707106781f
68+
#define WWMATH_OOSQRT3 0.577350269f
6669

6770
/*
6871
** Macros to convert between degrees and radians
@@ -168,6 +171,9 @@ static WWINLINE float Atan2(float y,float x) { return static_cast<float>(atan2(
168171

169172
// Origin wrappers: replace bare CRT math calls in GameLogic.
170173
// Each wrapper preserves the exact type (float vs double) of the vanilla CRT call.
174+
// Note: double overloads narrow to float before calling GameMath (gm_*f).
175+
// GameMath only provides float-precision functions. All call sites pass float-width
176+
// values, so the narrowing is lossless in practice.
171177
#ifdef USE_DETERMINISTIC_MATH
172178
static WWINLINE double SqrtOrigin(double x) { return (double)gm_sqrtf((float)x); }
173179
static WWINLINE float SqrtfOrigin(float x) { return gm_sqrtf(x); }
@@ -189,6 +195,10 @@ static WWINLINE float Atan2(float y,float x) { return static_cast<float>(atan2(
189195
static WWINLINE float CeilfOrigin(float x) { return gm_ceilf(x); }
190196
static WWINLINE float ExpfOrigin(float x) { return gm_expf(x); }
191197
static WWINLINE float Log10fOrigin(float x) { return gm_log10f(x); }
198+
static WWINLINE float LogfOrigin(float x) { return gm_logf(x); }
199+
static WWINLINE float SinhfOrigin(float x) { return gm_sinhf(x); }
200+
static WWINLINE float CoshfOrigin(float x) { return gm_coshf(x); }
201+
static WWINLINE float TanhfOrigin(float x) { return gm_tanhf(x); }
192202
#else
193203
static WWINLINE double SqrtOrigin(double x) { return sqrt(x); }
194204
static WWINLINE float SqrtfOrigin(float x) { return sqrtf(x); }
@@ -210,6 +220,10 @@ static WWINLINE float Atan2(float y,float x) { return static_cast<float>(atan2(
210220
static WWINLINE float CeilfOrigin(float x) { return ceilf(x); }
211221
static WWINLINE float ExpfOrigin(float x) { return expf(x); }
212222
static WWINLINE float Log10fOrigin(float x) { return log10f(x); }
223+
static WWINLINE float LogfOrigin(float x) { return logf(x); }
224+
static WWINLINE float SinhfOrigin(float x) { return sinhf(x); }
225+
static WWINLINE float CoshfOrigin(float x) { return coshf(x); }
226+
static WWINLINE float TanhfOrigin(float x) { return tanhf(x); }
213227
#endif
214228
static WWINLINE float Sign(float val);
215229
static WWINLINE float Ceil(float val) { return ceilf(val); }

Generals/Code/GameEngine/Source/Common/System/Trig.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
** Command & Conquer Generals Zero Hour(tm)
2+
** Command & Conquer Generals(tm)
33
** Copyright 2025 Electronic Arts Inc.
44
**
55
** This program is free software: you can redistribute it and/or modify

cmake/gamemath.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# FORCE is required to guarantee cross-platform bit-exact determinism.
2+
# Intrinsics would use platform-specific SIMD, breaking CRC parity between architectures.
13
set(GM_ENABLE_INTRINSICS OFF CACHE BOOL "Disable intrinsics for cross-arch determinism" FORCE)
24
set(GM_ENABLE_TESTS OFF CACHE BOOL "Disable GameMath tests" FORCE)
35

0 commit comments

Comments
 (0)