Add ability to skip POPCNT and SS(S)E 3 CPU extension tests

Experimental, but this should allow for running the game or dedicated server on a select few CPU's that appear to have SSSE 3, but not POPCNT. Still needs testing if it actually does work after emulating POPCNT instructions.
This commit is contained in:
Kawe Mazidjatari 2023-07-23 02:32:03 +02:00
parent af81954b7f
commit 79910b0859
3 changed files with 33 additions and 1 deletions

View File

@ -79,6 +79,15 @@ void SDK_Init()
{ {
Tier0_Init(); Tier0_Init();
// Allow skipping this check, as the popcnt instruction can be emulated.
// this allows CPU's like the 'Intel Pentium E5400' to run the dedicated
// server still.
if (!CommandLine()->CheckParm("-nocputest"))
{
// Check CPU as early as possible; error out if CPU isn't supported.
CheckCPU();
}
if (!CommandLine()->CheckParm("-launcher")) if (!CommandLine()->CheckParm("-launcher"))
{ {
CommandLine()->AppendParametersFromFile(SDK_DEFAULT_CFG); CommandLine()->AppendParametersFromFile(SDK_DEFAULT_CFG);
@ -147,7 +156,6 @@ void SDK_Shutdown()
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{ {
CheckCPU(); // Check CPU as early as possible; error out if CPU isn't supported.
MathLib_Init(); // Initialize Mathlib. MathLib_Init(); // Initialize Mathlib.
NOTE_UNUSED(lpReserved); NOTE_UNUSED(lpReserved);

View File

@ -12,6 +12,19 @@
#include "launcher/launcher.h" #include "launcher/launcher.h"
#include <eiface.h> #include <eiface.h>
static void CheckCPU()
{
// Allow skipping this check, as the popcnt instruction can be emulated.
// this allows CPU's like the 'Intel Pentium E5400' to run the dedicated
// server still.
if (!CommandLine()->CheckParm("-nocputest"))
{
// Run the game's implementation of CheckCPU
// for SSE 3, SSSE 3 and POPCNT.
v_CheckCPU();
}
}
int LauncherMain(HINSTANCE hInstance) int LauncherMain(HINSTANCE hInstance)
{ {
// Flush buffers every 5 seconds for every logger. // Flush buffers every 5 seconds for every logger.
@ -81,6 +94,8 @@ LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* pExceptionPointers)
void VLauncher::Attach(void) const void VLauncher::Attach(void) const
{ {
DetourAttach((LPVOID*)&v_CheckCPU, &CheckCPU);
DetourAttach((LPVOID*)&v_LauncherMain, &LauncherMain); DetourAttach((LPVOID*)&v_LauncherMain, &LauncherMain);
DetourAttach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter); DetourAttach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter);
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
@ -89,6 +104,8 @@ void VLauncher::Attach(void) const
} }
void VLauncher::Detach(void) const void VLauncher::Detach(void) const
{ {
DetourDetach((LPVOID*)&v_CheckCPU, &CheckCPU);
DetourDetach((LPVOID*)&v_LauncherMain, &LauncherMain); DetourDetach((LPVOID*)&v_LauncherMain, &LauncherMain);
DetourDetach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter); DetourDetach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter);
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)

View File

@ -1,6 +1,9 @@
#ifndef LAUNCHER_H #ifndef LAUNCHER_H
#define LAUNCHER_H #define LAUNCHER_H
inline CMemory p_CheckCPU;
inline void(*v_CheckCPU)(void);
inline CMemory p_LauncherMain; inline CMemory p_LauncherMain;
inline int(*v_LauncherMain)(HINSTANCE hInstance); inline int(*v_LauncherMain)(HINSTANCE hInstance);
@ -19,6 +22,7 @@ class VLauncher : public IDetour
{ {
virtual void GetAdr(void) const virtual void GetAdr(void) const
{ {
LogFunAdr("CheckCPU", p_CheckCPU.GetPtr());
LogFunAdr("LauncherMain", p_LauncherMain.GetPtr()); LogFunAdr("LauncherMain", p_LauncherMain.GetPtr());
LogFunAdr("TopLevelExceptionFilter", p_TopLevelExceptionFilter.GetPtr()); LogFunAdr("TopLevelExceptionFilter", p_TopLevelExceptionFilter.GetPtr());
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) #if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
@ -27,6 +31,9 @@ class VLauncher : public IDetour
} }
virtual void GetFun(void) const virtual void GetFun(void) const
{ {
p_CheckCPU = g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 33 C9");
v_CheckCPU = p_CheckCPU.RCast<void(*)(void)>();
p_LauncherMain = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 8B C8 E8 ?? ?? ?? ?? CC").FollowNearCallSelf(); p_LauncherMain = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 8B C8 E8 ?? ?? ?? ?? CC").FollowNearCallSelf();
v_LauncherMain = p_LauncherMain.RCast<int(*)(HINSTANCE)>(); v_LauncherMain = p_LauncherMain.RCast<int(*)(HINSTANCE)>();