Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ endif()

include(cmake/config.cmake)
include(cmake/gamespy.cmake)
if (IS_VS6_BUILD)
add_library(gamemath INTERFACE)
else()
include(cmake/gamemath.cmake)
endif()
include(cmake/lzhl.cmake)
include(cmake/stb.cmake)

Expand Down
1 change: 1 addition & 0 deletions Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ target_include_directories(corei_libraries_source_wwvegas INTERFACE "Libraries/S
target_include_directories(corei_main INTERFACE "Main")

target_sources(corei_libraries_include PRIVATE
Libraries/Include/Lib/BaseDefines.h
Libraries/Include/Lib/BaseType.h
Libraries/Include/Lib/BaseTypeCore.h
Libraries/Include/Lib/trig.h
Expand Down
27 changes: 27 additions & 0 deletions Core/GameEngine/Include/Common/BezierSegment.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,36 @@

#include <d3dx8math.h>
#include "Common/STLTypedefs.h"
#include "Lib/BaseDefines.h"

#define USUAL_TOLERANCE 1.0f

class BezierMath
{
public:
static void D3DXVec4Transform(D3DXVECTOR4* out, const D3DXVECTOR4* v, const D3DXMATRIX* m)
{
#if USE_DETERMINISTIC_MATH
const float x = v->x, y = v->y, z = v->z, w = v->w;
out->x = ((x * m->m[0][0] + y * m->m[1][0]) + z * m->m[2][0]) + w * m->m[3][0];
out->y = ((x * m->m[0][1] + y * m->m[1][1]) + z * m->m[2][1]) + w * m->m[3][1];
out->z = ((x * m->m[0][2] + y * m->m[1][2]) + z * m->m[2][2]) + w * m->m[3][2];
out->w = ((x * m->m[0][3] + y * m->m[1][3]) + z * m->m[2][3]) + w * m->m[3][3];
#else
::D3DXVec4Transform(out, v, m);
#endif
}

static float D3DXVec4Dot(const D3DXVECTOR4* a, const D3DXVECTOR4* b)
{
#if USE_DETERMINISTIC_MATH
return ((a->x * b->x + a->y * b->y) + a->z * b->z) + a->w * b->w;
#else
return ::D3DXVec4Dot(a, b);
#endif
}
};

class BezierSegment
{
protected:
Expand Down
5 changes: 5 additions & 0 deletions Core/GameEngine/Include/Common/Diagnostic/SimulationMathCrc.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@

#pragma once

// Flags for diagnostic math benchmarks
#define RUN_MATH_BENCHMARK_REPLAY400_FLAG (0)

class SimulationMathCrc
{
public:
static UnsignedInt calculate();
static void runBenchmark(int iterations = 10000);
static void runBenchmarkOnFrame(UnsignedInt frame);
};
4 changes: 1 addition & 3 deletions Core/GameEngine/Include/Common/GameDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@
// Note: Retail compatibility must not be broken before this project officially does.
// Use RETAIL_COMPATIBLE_CRC and RETAIL_COMPATIBLE_XFER_SAVE to guard breaking changes.

#ifndef RETAIL_COMPATIBLE_CRC
#define RETAIL_COMPATIBLE_CRC (1) // Game is expected to be CRC compatible with retail Generals 1.08, Zero Hour 1.04
#endif
// RETAIL_COMPATIBLE_CRC is default defined in BaseDefines.h

#ifndef RETAIL_COMPATIBLE_XFER_SAVE
#define RETAIL_COMPATIBLE_XFER_SAVE (1) // Game is expected to be Xfer Save compatible with retail Generals 1.08, Zero Hour 1.04
Expand Down
6 changes: 3 additions & 3 deletions Core/GameEngine/Source/Common/Bezier/BezFwdIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ void BezFwdIterator::start()
D3DXVECTOR4 pz(mBezSeg.m_controlPoints[0].z, mBezSeg.m_controlPoints[1].z, mBezSeg.m_controlPoints[2].z, mBezSeg.m_controlPoints[3].z);

D3DXVECTOR4 cVec[3];
D3DXVec4Transform(&cVec[0], &px, &BezierSegment::s_bezBasisMatrix);
D3DXVec4Transform(&cVec[1], &py, &BezierSegment::s_bezBasisMatrix);
D3DXVec4Transform(&cVec[2], &pz, &BezierSegment::s_bezBasisMatrix);
BezierMath::D3DXVec4Transform(&cVec[0], &px, &BezierSegment::s_bezBasisMatrix);
BezierMath::D3DXVec4Transform(&cVec[1], &py, &BezierSegment::s_bezBasisMatrix);
BezierMath::D3DXVec4Transform(&cVec[2], &pz, &BezierSegment::s_bezBasisMatrix);

mCurrPoint = mBezSeg.m_controlPoints[0];

Expand Down
8 changes: 4 additions & 4 deletions Core/GameEngine/Source/Common/Bezier/BezierSegment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ void BezierSegment::evaluateBezSegmentAtT(Real tValue, Coord3D *outResult) const
D3DXVECTOR4 zCoords(m_controlPoints[0].z, m_controlPoints[1].z, m_controlPoints[2].z, m_controlPoints[3].z);

D3DXVECTOR4 tResult;
D3DXVec4Transform(&tResult, &tVec, &BezierSegment::s_bezBasisMatrix);
BezierMath::D3DXVec4Transform(&tResult, &tVec, &BezierSegment::s_bezBasisMatrix);

outResult->x = D3DXVec4Dot(&xCoords, &tResult);
outResult->y = D3DXVec4Dot(&yCoords, &tResult);
outResult->z = D3DXVec4Dot(&zCoords, &tResult);
outResult->x = BezierMath::D3DXVec4Dot(&xCoords, &tResult);
outResult->y = BezierMath::D3DXVec4Dot(&yCoords, &tResult);
outResult->z = BezierMath::D3DXVec4Dot(&zCoords, &tResult);
}

//-------------------------------------------------------------------------------------------------
Expand Down
117 changes: 103 additions & 14 deletions Core/GameEngine/Source/Common/Diagnostic/SimulationMathCrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
#include "GameLogic/FPUControl.h"

#include <math.h>
#include <stdio.h>
#include <time.h>

static void appendSimulationMathCrc(XferCRC &xfer)
static void appendSimulationMathCrc_Deterministic(XferCRC &xfer)
{
Matrix3D matrix;
Matrix3D factorsMatrix;
Expand All @@ -37,18 +39,48 @@ static void appendSimulationMathCrc(XferCRC &xfer)
0.9f, 1.0f, 2.1f, 1.2f);

factorsMatrix.Set(
WWMath::Sin(0.7f) * log10f(2.3f),
WWMath::Cos(1.1f) * powf(1.1f, 2.0f),
tanf(0.3f),
asinf(0.967302263f),
acosf(0.967302263f),
atanf(0.967302263f) * powf(1.1f, 2.0f),
atan2f(0.4f, 1.3f),
sinhf(0.2f),
coshf(0.4f) * tanhf(0.5f),
sqrtf(55788.84375f),
expf(0.1f) * log10f(2.3f),
logf(1.4f));
WWMath::Sinf(0.7f) * WWMath::Log10f(2.3f),
WWMath::Cosf(1.1f) * WWMath::Powf(1.1f, 2.0f),
WWMath::Tanf(0.3f),
WWMath::Asinf(0.967302263f),
WWMath::Acosf(0.967302263f),
WWMath::Atanf(0.967302263f) * WWMath::Powf(1.1f, 2.0f),
WWMath::Atan2f(0.4f, 1.3f),
WWMath::Sinhf(0.2f),
WWMath::Coshf(0.4f) * WWMath::Tanhf(0.5f),
WWMath::Sqrtf(55788.84375f),
WWMath::Expf(0.1f) * WWMath::Log10f(2.3f),
WWMath::Logf(1.4f));

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

xfer.xferMatrix3D(&matrix);
}

static void appendSimulationMathCrc_Native(XferCRC &xfer)
{
Matrix3D matrix;
Matrix3D factorsMatrix;

matrix.Set(
4.1f, 1.2f, 0.3f, 0.4f,
0.5f, 3.6f, 0.7f, 0.8f,
0.9f, 1.0f, 2.1f, 1.2f);

factorsMatrix.Set(
(float)(::sin(0.7) * ::log10(2.3)),
(float)(::cos(1.1) * ::pow(1.1, 2.0)),
(float)::tan(0.3),
(float)::asin(0.967302263),
(float)::acos(0.967302263),
(float)(::atan(0.967302263) * ::pow(1.1, 2.0)),
(float)::atan2(0.4, 1.3),
(float)::sinh(0.2),
(float)(::cosh(0.4) * ::tanh(0.5)),
(float)::sqrt(55788.84375),
(float)(::exp(0.1) * ::log10(2.3)),
(float)::log(1.4));

Matrix3D::Multiply(matrix, factorsMatrix, &matrix);
matrix.Get_Inverse(matrix);
Expand All @@ -63,11 +95,68 @@ UnsignedInt SimulationMathCrc::calculate()

setFPMode();

appendSimulationMathCrc(xfer);
appendSimulationMathCrc_Deterministic(xfer);

_fpreset();

xfer.close();

return xfer.getCRC();
}

void SimulationMathCrc::runBenchmark(int iterations)
{
int i;
clock_t startDet = clock();
UnsignedInt crcDet = 0;

setFPMode();

for (i = 0; i < iterations; ++i)
{
XferCRC xfer;
xfer.open("SimMathDet");
appendSimulationMathCrc_Deterministic(xfer);
xfer.close();
if (i == 0)
crcDet = xfer.getCRC();
}
_fpreset();
clock_t endDet = clock();
double timeDetMs = (double)(endDet - startDet) / CLOCKS_PER_SEC * 1000.0;

clock_t startNat = clock();
UnsignedInt crcNat = 0;

setFPMode();

for (i = 0; i < iterations; ++i)
{
XferCRC xfer;
xfer.open("SimMathNat");
appendSimulationMathCrc_Native(xfer);
xfer.close();
if (i == 0)
crcNat = xfer.getCRC();
}
_fpreset();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
clock_t endNat = clock();
double timeNatMs = (double)(endNat - startNat) / CLOCKS_PER_SEC * 1000.0;

printf("\n================ MATH BENCHMARK (%d iterations) ================\n", iterations);
printf("Deterministic (WWMath): CRC = %08X, Time = %.2f ms\n", crcDet, timeDetMs);
printf("Native (system math): CRC = %08X, Time = %.2f ms\n", crcNat, timeNatMs);
printf("===========================================================\n\n");
}

void SimulationMathCrc::runBenchmarkOnFrame(UnsignedInt frame)
{
static bool s_benchmarkRun = false;

if (s_benchmarkRun || frame != 400)
return;

runBenchmark(10000);
setFPMode();
s_benchmarkRun = true;
}
4 changes: 2 additions & 2 deletions Core/GameEngine/Source/Common/INI/INI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1788,15 +1788,15 @@ void INI::parseDurationReal( INI *ini, void * /*instance*/, void *store, const v
void INI::parseDurationUnsignedInt( INI *ini, void * /*instance*/, void *store, const void* /*userData*/ )
{
UnsignedInt val = scanUnsignedInt(ini->getNextToken());
*(UnsignedInt *)store = (UnsignedInt)ceilf(ConvertDurationFromMsecsToFrames((Real)val));
*(UnsignedInt *)store = (UnsignedInt)WWMath::Ceilf(ConvertDurationFromMsecsToFrames((Real)val));
}

// ------------------------------------------------------------------------------------------------
// parse a duration in msec and convert to duration in integral number of frames, (unsignedshort) rounding UP
void INI::parseDurationUnsignedShort( INI *ini, void * /*instance*/, void *store, const void* /*userData*/ )
{
UnsignedInt val = scanUnsignedInt(ini->getNextToken());
*(UnsignedShort *)store = (UnsignedShort)ceilf(ConvertDurationFromMsecsToFrames((Real)val));
*(UnsignedShort *)store = (UnsignedShort)WWMath::Ceilf(ConvertDurationFromMsecsToFrames((Real)val));
}

//-------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
if (TheInGameUI->isInForceAttackMode())
{
const Real snapRadians = DEG_TO_RADF(45);
targetAngle = WWMath::Round(targetAngle / snapRadians) * snapRadians;
targetAngle = WWMath::Roundf(targetAngle / snapRadians) * snapRadians;
}

TheTacticalView->userSetAngle(targetAngle);
Expand Down
Loading
Loading