diff --git a/.gitignore b/.gitignore index 212e6ec..a2d9bd4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ *.iml **/msvc/Debug* **/msvc/Release* +**/msvc/Tests +**/msvc/Test Fixes **/msvc/*.sdf **/msvc/*.opensdf **/msvc/*.user diff --git a/dep/cppunitlite/include/cppunitlite/Assertions.h b/dep/cppunitlite/include/cppunitlite/Assertions.h index b191559..3974024 100644 --- a/dep/cppunitlite/include/cppunitlite/Assertions.h +++ b/dep/cppunitlite/include/cppunitlite/Assertions.h @@ -15,4 +15,6 @@ public: static void UInt32Equals(std::string message, unsigned int expected, unsigned int actual, const char* fileName, long lineNumber); static void CharEquals(std::string message, char expected, char actual, const char* fileName, long lineNumber); + + static void DoubleEquals(std::string message, double expected, double actual, double epsilon, const char* fileName, long lineNumber); }; diff --git a/dep/cppunitlite/include/cppunitlite/Test.h b/dep/cppunitlite/include/cppunitlite/Test.h index 9f18329..5b9561a 100644 --- a/dep/cppunitlite/include/cppunitlite/Test.h +++ b/dep/cppunitlite/include/cppunitlite/Test.h @@ -70,12 +70,8 @@ protected: { Assertions::CharEquals(msg,expected, actual, __FILE__, __LINE__); } -#define DOUBLES_EQUAL(expected,actual,threshold)\ -{ double actualTemp = actual; \ - double expectedTemp = expected; \ - if (fabs ((expectedTemp)-(actualTemp)) > threshold) \ -{ result_.addFailure (Failure (name_, __FILE__, __LINE__, \ -StringFrom((double)expectedTemp), StringFrom((double)actualTemp))); return; } } +#define DOUBLES_EQUAL(msg, expected,actual,threshold)\ +{ Assertions::DoubleEquals(msg,expected, actual, threshold, __FILE__, __LINE__); } diff --git a/dep/cppunitlite/src/Assertions.cpp b/dep/cppunitlite/src/Assertions.cpp index e856de7..ada346a 100644 --- a/dep/cppunitlite/src/Assertions.cpp +++ b/dep/cppunitlite/src/Assertions.cpp @@ -1,6 +1,7 @@ #include "cppunitlite/Assertions.h" #include +#include #include #include @@ -53,4 +54,12 @@ void Assertions::CharEquals(std::string message, char expected, char actual, con ss << message << " (expected '" << expected << "', got '" << actual << "')"; throw TestFailException(ss.str(), std::string(fileName), lineNumber); } -} \ No newline at end of file +} + +void Assertions::DoubleEquals(std::string message, double expected, double actual, double epsilon, const char* fileName, long lineNumber) { + if (abs(expected - actual) > epsilon) { + std::stringstream ss; + ss << message << " (expected '" << expected << "', got '" << actual << "')"; + throw TestFailException(ss.str(), std::string(fileName), lineNumber); + } +} diff --git a/msvc/ReHLDS.sln b/msvc/ReHLDS.sln index cf5e61d..b1aff52 100644 --- a/msvc/ReHLDS.sln +++ b/msvc/ReHLDS.sln @@ -30,6 +30,7 @@ Global Debug|Win32 = Debug|Win32 Release Play|Win32 = Release Play|Win32 Release|Win32 = Release|Win32 + Test Fixes|Win32 = Test Fixes|Win32 Tests|Win32 = Tests|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution @@ -47,6 +48,8 @@ Global {70A2B904-B7DB-4C48-8DE0-AF567360D572}.Release Play|Win32.Build.0 = Release Play|Win32 {70A2B904-B7DB-4C48-8DE0-AF567360D572}.Release|Win32.ActiveCfg = Release|Win32 {70A2B904-B7DB-4C48-8DE0-AF567360D572}.Release|Win32.Build.0 = Release|Win32 + {70A2B904-B7DB-4C48-8DE0-AF567360D572}.Test Fixes|Win32.ActiveCfg = Test Fixes|Win32 + {70A2B904-B7DB-4C48-8DE0-AF567360D572}.Test Fixes|Win32.Build.0 = Test Fixes|Win32 {70A2B904-B7DB-4C48-8DE0-AF567360D572}.Tests|Win32.ActiveCfg = Tests|Win32 {70A2B904-B7DB-4C48-8DE0-AF567360D572}.Tests|Win32.Build.0 = Tests|Win32 {CEB94F7C-E459-4673-AABB-36E2074396C0}.Debug Play|Win32.ActiveCfg = Debug|Win32 @@ -63,6 +66,8 @@ Global {CEB94F7C-E459-4673-AABB-36E2074396C0}.Release Play|Win32.Build.0 = Release|Win32 {CEB94F7C-E459-4673-AABB-36E2074396C0}.Release|Win32.ActiveCfg = Release|Win32 {CEB94F7C-E459-4673-AABB-36E2074396C0}.Release|Win32.Build.0 = Release|Win32 + {CEB94F7C-E459-4673-AABB-36E2074396C0}.Test Fixes|Win32.ActiveCfg = Debug|Win32 + {CEB94F7C-E459-4673-AABB-36E2074396C0}.Test Fixes|Win32.Build.0 = Debug|Win32 {CEB94F7C-E459-4673-AABB-36E2074396C0}.Tests|Win32.ActiveCfg = Debug|Win32 {CEB94F7C-E459-4673-AABB-36E2074396C0}.Tests|Win32.Build.0 = Debug|Win32 {792DF067-9904-4579-99B9-46C17277ADE3}.Debug Play|Win32.ActiveCfg = Debug|Win32 @@ -79,6 +84,8 @@ Global {792DF067-9904-4579-99B9-46C17277ADE3}.Release Play|Win32.Build.0 = Release|Win32 {792DF067-9904-4579-99B9-46C17277ADE3}.Release|Win32.ActiveCfg = Release|Win32 {792DF067-9904-4579-99B9-46C17277ADE3}.Release|Win32.Build.0 = Release|Win32 + {792DF067-9904-4579-99B9-46C17277ADE3}.Test Fixes|Win32.ActiveCfg = Debug|Win32 + {792DF067-9904-4579-99B9-46C17277ADE3}.Test Fixes|Win32.Build.0 = Debug|Win32 {792DF067-9904-4579-99B9-46C17277ADE3}.Tests|Win32.ActiveCfg = Debug|Win32 {792DF067-9904-4579-99B9-46C17277ADE3}.Tests|Win32.Build.0 = Debug|Win32 EndGlobalSection diff --git a/rehlds/engine/mathlib.cpp b/rehlds/engine/mathlib.cpp index 4e986be..72b5a1c 100644 --- a/rehlds/engine/mathlib.cpp +++ b/rehlds/engine/mathlib.cpp @@ -398,15 +398,15 @@ void CrossProduct(const vec_t *v1, const vec_t *v2, vec_t *cross) { #ifdef REHLDS_FIXES __m128 a = _mm_loadu_ps(v1), b = _mm_loadu_ps(v2); - __m128 m = _mm_sub_ps( _mm_mul_ps(b, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1))), - _mm_mul_ps(a, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1))) - ); + __m128 tmp1 = _mm_mul_ps(a, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1))); + __m128 tmp2 = _mm_mul_ps(b, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1))); + __m128 m = _mm_sub_ps(tmp1, tmp2); xmm2vec(cross, _mm_shuffle_ps(m, m, _MM_SHUFFLE(3, 0, 2, 1))); #else // REHLDS_FIXES - cross[0] = v2[2] * v1[1] - v1[2] * v2[1]; + cross[0] = v1[1] * v2[2] - v1[2] * v2[1]; cross[1] = v1[2] * v2[0] - v1[0] * v2[2]; - cross[2] = v1[0] * v2[1] - v2[0] * v1[1]; + cross[2] = v1[0] * v2[1] - v1[1] * v2[0]; #endif // REHLDS_FIXES } diff --git a/rehlds/msvc/ReHLDS.vcxproj b/rehlds/msvc/ReHLDS.vcxproj index 9addf4f..30d485e 100644 --- a/rehlds/msvc/ReHLDS.vcxproj +++ b/rehlds/msvc/ReHLDS.vcxproj @@ -29,6 +29,10 @@ Release Win32 + + Test Fixes + Win32 + Tests Win32 @@ -91,11 +95,13 @@ true + true true true true + true true true @@ -108,6 +114,7 @@ true true true + true true false true @@ -125,6 +132,7 @@ true true true + true @@ -136,6 +144,7 @@ true true true + true true @@ -146,6 +155,7 @@ true true true + true @@ -158,6 +168,7 @@ true true true + true @@ -183,7 +194,9 @@ precompiled.h precompiled.h Create + Create precompiled.h + precompiled.h @@ -201,12 +214,20 @@ true true + + true + true + true + true + true + true true true true false + false true @@ -469,6 +490,7 @@ true true true + true true @@ -477,6 +499,7 @@ true true true + true @@ -528,6 +551,12 @@ v120_xp MultiByte + + Application + true + v120_xp + MultiByte + DynamicLibrary false @@ -563,6 +592,9 @@ + + + @@ -588,6 +620,9 @@ filesystem_stdio + + filesystem_stdio + filesystem_stdio @@ -604,7 +639,7 @@ Level3 Disabled true - REHLDS_SELF;HOOK_ENGINE;REHLDS_FIXES;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REHLDS_OPT_PEDANTIC;REHLDS_SELF;HOOK_ENGINE;REHLDS_FIXES;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) Precise /arch:IA32 %(AdditionalOptions) MultiThreadedDebug @@ -642,7 +677,7 @@ Level3 Disabled true - REHLDS_SELF;REHLDS_FIXES;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REHLDS_OPT_PEDANTIC;REHLDS_SELF;REHLDS_FIXES;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) Precise /arch:IA32 %(AdditionalOptions) MultiThreadedDebug @@ -679,7 +714,7 @@ Level3 Disabled true - REHLDS_SELF;HOOK_ENGINE;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REHLDS_OPT_PEDANTIC;REHLDS_SELF;HOOK_ENGINE;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) Precise /arch:IA32 %(AdditionalOptions) MultiThreadedDebug @@ -715,7 +750,7 @@ Level3 Disabled true - REHLDS_SELF;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REHLDS_OPT_PEDANTIC;REHLDS_SELF;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) Precise /arch:IA32 %(AdditionalOptions) MultiThreadedDebug @@ -754,7 +789,7 @@ Level3 Disabled true - REHLDS_SELF;HOOK_ENGINE;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REHLDS_OPT_PEDANTIC;REHLDS_SELF;HOOK_ENGINE;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) Precise /arch:IA32 %(AdditionalOptions) MultiThreadedDebug @@ -790,7 +825,7 @@ Level3 Disabled true - REHLDS_SELF;_BUILD_FROM_IDE;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + REHLDS_OPT_PEDANTIC;REHLDS_SELF;_BUILD_FROM_IDE;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) MultiThreadedDebug Use precompiled.h @@ -815,6 +850,41 @@ subversion.always.run + + + IF EXIST "$(ProjectDir)PreBuild.bat" (CALL "$(ProjectDir)PreBuild.bat" "$(ProjectDir)..\version\" "$(ProjectDir)..\") + Setup version from SVN revision + + + $(ProjectDir)\..\;$(ProjectDir)\..\hookers\;$(ProjectDir)\..\metamod\include\;$(ProjectDir)\..\public\rehlds\;$(ProjectDir)\..\common;$(ProjectDir)\..\engine;$(ProjectDir)\..\public;$(ProjectDir)\..\pm_shared;$(ProjectDir)\..\rehlds\;$(ProjectDir)\..\testsuite\;$(VCInstallDir)UnitTest\include;$(SolutionDir)..\dep\bzip2\include\;$(SolutionDir)..\dep\cppunitlite\include\;%(AdditionalIncludeDirectories) + Level3 + Disabled + true + REHLDS_OPT_PEDANTIC;REHLDS_FIXES;REHLDS_SELF;_BUILD_FROM_IDE;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;_DEBUG;%(PreprocessorDefinitions) + MultiThreadedDebug + Use + precompiled.h + + + true + psapi.lib;ws2_32.lib;$(ProjectDir)../lib/steam_api.lib;%(AdditionalDependencies) + + + + + $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + copy /Y "$(ProjectDir)..\lib\steam_api.dll" "$(OutDir)" + Automatic deployment script + + + echo Empty Action + Force build to run Pre-Build event + subversion.always.run + subversion.always.run + + IF EXIST "$(ProjectDir)PreBuild.bat" (CALL "$(ProjectDir)PreBuild.bat" "$(ProjectDir)..\version\" "$(ProjectDir)..\") @@ -827,7 +897,7 @@ true true true - REHLDS_SELF;HOOK_ENGINE;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + REHLDS_OPT_PEDANTIC;REHLDS_SELF;HOOK_ENGINE;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreaded /arch:IA32 %(AdditionalOptions) Use @@ -866,7 +936,7 @@ true true true - REHLDS_SELF;HOOK_ENGINE;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + REHLDS_OPT_PEDANTIC;REHLDS_SELF;HOOK_ENGINE;REHLDS_CHECKS;USE_BREAKPAD_HANDLER;DEDICATED;SWDS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) MultiThreaded /arch:IA32 %(AdditionalOptions) Use diff --git a/rehlds/msvc/ReHLDS.vcxproj.filters b/rehlds/msvc/ReHLDS.vcxproj.filters index b5eb9bd..84bece4 100644 --- a/rehlds/msvc/ReHLDS.vcxproj.filters +++ b/rehlds/msvc/ReHLDS.vcxproj.filters @@ -322,6 +322,9 @@ engine + + unittests + diff --git a/rehlds/unittests/mathlib_tests.cpp b/rehlds/unittests/mathlib_tests.cpp new file mode 100644 index 0000000..fbb2658 --- /dev/null +++ b/rehlds/unittests/mathlib_tests.cpp @@ -0,0 +1,283 @@ +#include "precompiled.h" +#include "cppunitlite/TestHarness.h" + +TEST(AngleVectorsTest, MathLib, 1000) { + Sys_CheckCpuInstructionsSupport(); + CHECK("SSE4.1 Support", cpuinfo.sse4_1); + + struct testdata_t { + vec3_t angles; + vec3_t forward, right, up; + }; + + testdata_t testdata[2] = { + { { 21.0f, 65.0f, 162.0f }, { 0.39455f, 0.84611f, -0.35837f }, { -0.90875f, 0.30156f, -0.28849f }, { 0.13602f, -0.43949f, -0.88789f } }, + { { 106.0f, 142.0f, 62.0f }, { 0.21721f, -0.16970f, -0.96126f }, { 0.95785f, -0.15259f, 0.24337f }, { 0.18798f, 0.97361f, -0.12940f } } + }; + + for (int sse = 0; sse <= 1; sse++) { + vec3_t forward, right, up; + + for (int i = 0; i < ARRAYSIZE(testdata); i++) { + AngleVectors(testdata[i].angles, forward, right, up); + + DOUBLES_EQUAL("forward[0] mismatch", testdata[i].forward[0], forward[0], 0.00001); + DOUBLES_EQUAL("forward[1] mismatch", testdata[i].forward[1], forward[1], 0.00001); + DOUBLES_EQUAL("forward[2] mismatch", testdata[i].forward[2], forward[2], 0.00001); + + DOUBLES_EQUAL("right[0] mismatch", testdata[i].right[0], right[0], 0.00001); + DOUBLES_EQUAL("right[1] mismatch", testdata[i].right[1], right[1], 0.00001); + DOUBLES_EQUAL("right[2] mismatch", testdata[i].right[2], right[2], 0.00001); + + DOUBLES_EQUAL("up[0] mismatch", testdata[i].up[0], up[0], 0.00001); + DOUBLES_EQUAL("up[1] mismatch", testdata[i].up[1], up[1], 0.00001); + DOUBLES_EQUAL("up[2] mismatch", testdata[i].up[2], up[2], 0.00001); + } + + cpuinfo.sse4_1 = 0; + } +} + +TEST(AngleVectorsTransposeTest, MathLib, 1000) { + Sys_CheckCpuInstructionsSupport(); + CHECK("SSE4.1 Support", cpuinfo.sse4_1); + + struct testdata_t { + vec3_t angles; + vec3_t forward, right, up; + }; + + testdata_t testdata[2] = { + { { 21.0f, 65.0f, 162.0f }, { 0.39455f, 0.90875f, 0.13602f }, { 0.84611f, -0.30157f, -0.43949f }, { -0.35837f, 0.28849f, -0.88789f } }, + { { 106.0f, 142.0f, 62.0f }, { 0.21721f, -0.95785f, 0.18798f }, { -0.16970f, 0.15259f, 0.97361f }, { -0.96126f, -0.24337f, -0.12940f } } + }; + + for (int sse = 0; sse <= 1; sse++) { + vec3_t forward, right, up; + + for (int i = 0; i < ARRAYSIZE(testdata); i++) { + AngleVectorsTranspose(testdata[i].angles, forward, right, up); + + DOUBLES_EQUAL("forward[0] mismatch", testdata[i].forward[0], forward[0], 0.00001); + DOUBLES_EQUAL("forward[1] mismatch", testdata[i].forward[1], forward[1], 0.00001); + DOUBLES_EQUAL("forward[2] mismatch", testdata[i].forward[2], forward[2], 0.00001); + + DOUBLES_EQUAL("right[0] mismatch", testdata[i].right[0], right[0], 0.00001); + DOUBLES_EQUAL("right[1] mismatch", testdata[i].right[1], right[1], 0.00001); + DOUBLES_EQUAL("right[2] mismatch", testdata[i].right[2], right[2], 0.00001); + + DOUBLES_EQUAL("up[0] mismatch", testdata[i].up[0], up[0], 0.00001); + DOUBLES_EQUAL("up[1] mismatch", testdata[i].up[1], up[1], 0.00001); + DOUBLES_EQUAL("up[2] mismatch", testdata[i].up[2], up[2], 0.00001); + } + + cpuinfo.sse4_1 = 0; + } +} + +TEST(AngleMatrixTest, MathLib, 1000) { + Sys_CheckCpuInstructionsSupport(); + CHECK("SSE4.1 Support", cpuinfo.sse4_1); + + struct testdata_t { + vec3_t angles; + vec_t matrix0[4]; + vec_t matrix1[4]; + vec_t matrix2[4]; + }; + + testdata_t testdata[2] = { + { { 21.0f, 65.0f, 162.0f }, { 0.39455f, 0.90875f, 0.13602f, 0.0f }, { 0.84611f, -0.30157f, -0.43949f, 0.0f }, { -0.35837f, 0.28849f, -0.88789f, 0.0f } }, + { { 106.0f, 142.0f, 62.0f }, { 0.21721f, -0.95785f, 0.18798f, 0.0f }, { -0.16970f, 0.15259f, 0.97361f, 0.0f }, { -0.96126f, -0.24337f, -0.12940f, 0.0f } } + }; + + for (int sse = 0; sse <= 1; sse++) { + float rotationmatrix[3][4]; + + for (int i = 0; i < ARRAYSIZE(testdata); i++) { + AngleMatrix(testdata[i].angles, rotationmatrix); + + DOUBLES_EQUAL("rotationmatrix[0][0] mismatch", testdata[i].matrix0[0], rotationmatrix[0][0], 0.00001); + DOUBLES_EQUAL("rotationmatrix[0][1] mismatch", testdata[i].matrix0[1], rotationmatrix[0][1], 0.00001); + DOUBLES_EQUAL("rotationmatrix[0][2] mismatch", testdata[i].matrix0[2], rotationmatrix[0][2], 0.00001); + DOUBLES_EQUAL("rotationmatrix[0][3] mismatch", testdata[i].matrix0[3], rotationmatrix[0][3], 0.00001); + + DOUBLES_EQUAL("rotationmatrix[1][0] mismatch", testdata[i].matrix1[0], rotationmatrix[1][0], 0.00001); + DOUBLES_EQUAL("rotationmatrix[1][1] mismatch", testdata[i].matrix1[1], rotationmatrix[1][1], 0.00001); + DOUBLES_EQUAL("rotationmatrix[1][2] mismatch", testdata[i].matrix1[2], rotationmatrix[1][2], 0.00001); + DOUBLES_EQUAL("rotationmatrix[1][3] mismatch", testdata[i].matrix1[3], rotationmatrix[1][3], 0.00001); + + DOUBLES_EQUAL("rotationmatrix[2][0] mismatch", testdata[i].matrix2[0], rotationmatrix[2][0], 0.00001); + DOUBLES_EQUAL("rotationmatrix[2][1] mismatch", testdata[i].matrix2[1], rotationmatrix[2][1], 0.00001); + DOUBLES_EQUAL("rotationmatrix[2][2] mismatch", testdata[i].matrix2[2], rotationmatrix[2][2], 0.00001); + DOUBLES_EQUAL("rotationmatrix[2][3] mismatch", testdata[i].matrix2[3], rotationmatrix[2][3], 0.00001); + } + + cpuinfo.sse4_1 = 0; + } +} + +TEST(DotProductTest, MathLib, 1000) { + Sys_CheckCpuInstructionsSupport(); + CHECK("SSE4.1 Support", cpuinfo.sse4_1); + + struct testdata_t { + vec3_t v1; + vec3_t v2; + float res; + }; + + testdata_t testdata[2] = { + { { 41.5f, 7.32f, -9.22f }, { 13.3f, -0.5f, 8.09f }, 473.70023f }, + { { -16.1f, -0.09f, 1.2f }, { 8.2f, 1.2f, -6.66f }, -140.12001f }, + }; + + for (int sse = 0; sse <= 1; sse++) { + + for (int i = 0; i < ARRAYSIZE(testdata); i++) { + double res = _DotProduct(testdata[i].v1, testdata[i].v2); + DOUBLES_EQUAL("_DotProduct mismatch", testdata[i].res, res, 0.00001); + } + + cpuinfo.sse4_1 = 0; + } +} + +TEST(CrossProductTest, MathLib, 1000) { + Sys_CheckCpuInstructionsSupport(); + CHECK("SSE4.1 Support", cpuinfo.sse4_1); + + struct testdata_t { + vec3_t v1; + vec3_t v2; + vec3_t res; + }; + + testdata_t testdata[2] = { + { { 41.5f, 7.32f, -9.22f }, { 13.3f, -0.5f, 8.09f }, { 54.60880f, -458.36102f, -118.10600f } }, + { { -16.1f, -0.09f, 1.2f }, { 8.2f, 1.2f, -6.66f }, { -0.84060f, -97.38600f, -18.58200f } }, + }; + + for (int sse = 0; sse <= 1; sse++) { + vec3_t res; + + for (int i = 0; i < ARRAYSIZE(testdata); i++) { + CrossProduct(testdata[i].v1, testdata[i].v2, res); + + DOUBLES_EQUAL("CrossProduct[0] mismatch", testdata[i].res[0], res[0], 0.00001); + DOUBLES_EQUAL("CrossProduct[1] mismatch", testdata[i].res[1], res[1], 0.00001); + DOUBLES_EQUAL("CrossProduct[2] mismatch", testdata[i].res[2], res[2], 0.00001); + } + + cpuinfo.sse4_1 = 0; + } +} + +TEST(LengthTest, MathLib, 1000) { + Sys_CheckCpuInstructionsSupport(); + CHECK("SSE4.1 Support", cpuinfo.sse4_1); + + struct testdata_t { + vec3_t v; + float l; + }; + + testdata_t testdata[2] = { + { { 41.5f, 7.32f, -9.22f }, 43.13746f }, + { { -16.1f, -0.09f, 1.2f }, 16.14491f }, + }; + + for (int sse = 0; sse <= 1; sse++) { + for (int i = 0; i < ARRAYSIZE(testdata); i++) { + double res = Length(testdata[i].v); + + DOUBLES_EQUAL("Length mismatch", testdata[i].l, res, 0.00001); + } + + cpuinfo.sse4_1 = 0; + } +} + +TEST(Length2DTest, MathLib, 1000) { + Sys_CheckCpuInstructionsSupport(); + CHECK("SSE4.1 Support", cpuinfo.sse4_1); + + struct testdata_t { + vec3_t v; + float l; + }; + + testdata_t testdata[2] = { + { { 41.5f, 7.32f, -9.22f }, 42.14063f }, + { { -16.1f, -0.09f, 1.2f }, 16.10025f }, + }; + + for (int sse = 0; sse <= 1; sse++) { + for (int i = 0; i < ARRAYSIZE(testdata); i++) { + double res = Length2D(testdata[i].v); + + DOUBLES_EQUAL("Length mismatch", testdata[i].l, res, 0.00001); + } + + cpuinfo.sse4_1 = 0; + } +} + +TEST(VectorNormalizeTest, MathLib, 1000) { + Sys_CheckCpuInstructionsSupport(); + CHECK("SSE4.1 Support", cpuinfo.sse4_1); + + struct testdata_t { + vec3_t vecIn; + vec3_t vecOut; + float l; + }; + + testdata_t testdata[2] = { + { { 41.5f, 7.32f, -9.22f }, { 0.96204f, 0.16969f, -0.21374f }, 43.13746f }, + { { -16.1f, -0.09f, 1.2f }, { -0.99722f, -0.00557f, 0.07433f }, 16.14491f }, + }; + + for (int sse = 0; sse <= 1; sse++) { + for (int i = 0; i < ARRAYSIZE(testdata); i++) { + vec3_t v; + memcpy(&v[0], &testdata[i].vecIn[0], sizeof(v)); + double res = VectorNormalize(v); + + DOUBLES_EQUAL("VectorNormalize.len mismatch", testdata[i].l, res, 0.00001); + DOUBLES_EQUAL("VectorNormalize[0] mismatch", testdata[i].vecOut[0], v[0], 0.00001); + DOUBLES_EQUAL("VectorNormalize[1] mismatch", testdata[i].vecOut[1], v[1], 0.00001); + DOUBLES_EQUAL("VectorNormalize[2] mismatch", testdata[i].vecOut[2], v[2], 0.00001); + } + + cpuinfo.sse4_1 = 0; + } +} + +TEST(VectorAnglesTest, MathLib, 1000) { + Sys_CheckCpuInstructionsSupport(); + CHECK("SSE4.1 Support", cpuinfo.sse4_1); + + struct testdata_t { + vec3_t forward; + vec3_t angles; + }; + + testdata_t testdata[2] = { + { { 0.96204f, 0.16969f, -0.21374f }, { 347.65839f, 10.00326f, 0.0f } }, + { { -0.99722f, -0.00557f, 0.07433f }, { 4.26272f, 180.32002f, 0.0f } }, + }; + + for (int sse = 0; sse <= 1; sse++) { + for (int i = 0; i < ARRAYSIZE(testdata); i++) { + vec3_t angles; + VectorAngles(testdata[i].forward, angles); + + DOUBLES_EQUAL("VectorAngles[0] mismatch", testdata[i].angles[0], angles[0], 0.00001); + DOUBLES_EQUAL("VectorAngles[1] mismatch", testdata[i].angles[1], angles[1], 0.00001); + DOUBLES_EQUAL("VectorAngles[2] mismatch", testdata[i].angles[2], angles[2], 0.00001); + } + + cpuinfo.sse4_1 = 0; + } +} \ No newline at end of file