r5sdk/r5dev/launcher/launcher.cpp
Kawe Mazidjatari 79910b0859 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.
2023-07-23 02:32:03 +02:00

114 lines
3.3 KiB
C++

//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Defines the entry point for the application.
//
// $NoKeywords: $
//===========================================================================//
#include "core/stdafx.h"
#include "core/logdef.h"
#include "tier0/crashhandler.h"
#include "tier0/commandline.h"
#include "tier1/strtools.h"
#include "launcher/launcher.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)
{
// Flush buffers every 5 seconds for every logger.
// Has to be done here, don't move this to SpdLog
// init, as this could cause deadlocks on certain
// compilers (VS2017)!!!
spdlog::flush_every(std::chrono::seconds(5));
int results = v_LauncherMain(hInstance);
DevMsg(eDLL_T::NONE, "%s returned: %s\n", __FUNCTION__, ExitCodeToString(results));
return results;
}
#if !defined (GAMEDLL_S0) || !defined (GAMEDLL_S1)
// Remove all but the last -game parameter.
// This is for mods based off something other than Half-Life 2 (like HL2MP mods).
// The Steam UI does 'steam -applaunch 320 -game c:\steam\steamapps\sourcemods\modname', but applaunch inserts
// its own -game parameter, which would supersede the one we really want if we didn't intercede here.
void RemoveSpuriousGameParameters()
{
// Find the last -game parameter.
int nGameArgs = 0;
char lastGameArg[MAX_PATH];
for (int i = 0; i < CommandLine()->ParmCount() - 1; i++)
{
if (Q_stricmp(CommandLine()->GetParm(i), "-game") == 0)
{
Q_snprintf(lastGameArg, sizeof(lastGameArg), "\"%s\"", CommandLine()->GetParm(i + 1));
++nGameArgs;
++i;
}
}
// We only care if > 1 was specified.
if (nGameArgs > 1)
{
CommandLine()->RemoveParm("-game");
CommandLine()->AppendParm("-game", lastGameArg);
}
}
#endif
const char* ExitCodeToString(int nCode)
{
switch (nCode)
{
case EXIT_SUCCESS:
return "EXIT_SUCCESS";
case EXIT_FAILURE:
return "EXIT_FAILURE";
default:
return "UNKNOWN_EXIT_CODE";
}
}
LONG WINAPI TopLevelExceptionFilter(EXCEPTION_POINTERS* pExceptionPointers)
{
// Don't run the unhandled exception filter from the
// game if we have a valid vectored exception filter.
if (g_CrashHandler)
{
return NULL;
}
return v_TopLevelExceptionFilter(pExceptionPointers);
}
void VLauncher::Attach(void) const
{
DetourAttach((LPVOID*)&v_CheckCPU, &CheckCPU);
DetourAttach((LPVOID*)&v_LauncherMain, &LauncherMain);
DetourAttach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter);
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
DetourAttach((LPVOID*)&v_RemoveSpuriousGameParameters, &RemoveSpuriousGameParameters);
#endif
}
void VLauncher::Detach(void) const
{
DetourDetach((LPVOID*)&v_CheckCPU, &CheckCPU);
DetourDetach((LPVOID*)&v_LauncherMain, &LauncherMain);
DetourDetach((LPVOID*)&v_TopLevelExceptionFilter, &TopLevelExceptionFilter);
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1)
DetourDetach((LPVOID*)&v_RemoveSpuriousGameParameters, &RemoveSpuriousGameParameters);
#endif
}