From 49e013d164538e2afc39c37f1b4bc156720ece86 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 1 Nov 2026 17:12:26 +0100 Subject: [PATCH] bugfix(baseheightmap): Restore Generals retail compatibility from floor math changes in BaseHeightMapRenderObjClass::getHeightMapHeight() Merging the Height Map code made getHeightMapHeight() of Generals use fast_float_floor instead of floorf. The game sets the FPU to round to nearest, under which fast_float_floor returns n-1 for negative whole numbers. Positions on a negative multiple of the cell size then use the neighbouring cell and get a different height. A retail compatible Zero Hour keeps fast_float_floor, because its replays depend on its results. All other configurations use WWMath::Floorf, which is floorf, or gm_floorf with deterministic math. This restores the retail heights for a retail compatible Generals. Without retail compatibility, Generals and Zero Hour now floor these positions right. The FAST_REAL_TRUNC, FAST_REAL_CEIL and FAST_REAL_FLOOR macros lost their last user and are removed. --- .../Source/W3DDevice/GameClient/BaseHeightMap.cpp | 9 +++++++-- Core/Libraries/Source/Lib/Include/Lib/BaseFunctions.h | 4 ---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp index 10df2b9d77f..19d7e5dc8ea 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp @@ -908,8 +908,13 @@ Real BaseHeightMapRenderObjClass::getHeightMapHeight(Real x, Real y, Coord3D* no float xdiv = x * MAP_XY_FACTOR_INV; float ydiv = y * MAP_XY_FACTOR_INV; - float ixf = FAST_REAL_FLOOR(xdiv); - float iyf = FAST_REAL_FLOOR(ydiv); +#if RTS_ZEROHOUR && RETAIL_COMPATIBLE_CRC + float ixf = fast_float_floor(xdiv); + float iyf = fast_float_floor(ydiv); +#else + float ixf = WWMath::Floorf(xdiv); + float iyf = WWMath::Floorf(ydiv); +#endif float fx = xdiv - ixf; //get fraction float fy = ydiv - iyf; //get fraction diff --git a/Core/Libraries/Source/Lib/Include/Lib/BaseFunctions.h b/Core/Libraries/Source/Lib/Include/Lib/BaseFunctions.h index 9a359d02cdd..c481fb73c0d 100644 --- a/Core/Libraries/Source/Lib/Include/Lib/BaseFunctions.h +++ b/Core/Libraries/Source/Lib/Include/Lib/BaseFunctions.h @@ -101,10 +101,6 @@ __forceinline float fast_float_ceil(float f) #define REAL_TO_INT_FLOOR(x) (fast_float2long_round(fast_float_floor(x))) #endif -#define FAST_REAL_TRUNC(x) fast_float_trunc(x) -#define FAST_REAL_CEIL(x) fast_float_ceil(x) -#define FAST_REAL_FLOOR(x) fast_float_floor(x) - //------------------------------------------------------------------------------------------------- // Checking whether a size matches the bit flags count from an enum definition: // enum MyEnum