r5sdk/r5dev/engine/sys_dll2.cpp
Kawe Mazidjatari edc52ad669 IDetour: remove extraneous pointer assignments
Originally, we store the search results in a CMemory instance which we then assign to the actual function pointer. CMemory is just a pointer class; we can assign the results directly to the actual function pointer. This commit reduces a lot of code verbosity, and also reduced roughly 2KiB worth of static pointers in the resulting executable. This commit also officially deprecates the support for any GameDLL's below S3 (Season 3), since it makes more sense to port the assets from earlier/later games back to the version this SDK supports.
2024-04-05 17:19:32 +02:00

269 lines
9.3 KiB
C++
Raw Blame History

//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "core/stdafx.h"
#include "tier0/commandline.h"
#include "tier1/cmd.h"
#include "tier1/cvar.h"
#include "tier1/strtools.h"
#include "engine/sys_engine.h"
#include "engine/sys_dll.h"
#include "engine/sys_dll2.h"
#include "engine/host_cmd.h"
#include "engine/traceinit.h"
#ifndef DEDICATED
#include "engine/sys_mainwind.h"
#include "inputsystem/inputsystem.h"
#include "vgui/vgui_baseui_interface.h"
#include "materialsystem/cmaterialsystem.h"
#include "windows/id3dx.h"
#include "client/vengineclient_impl.h"
#include "geforce/reflex.h"
#endif // !DEDICATED
#include "rtech/rtech_utils.h"
#include "filesystem/filesystem.h"
constexpr char DFS_ENABLE_PATH[] = "/vpk/enable.txt";
//-----------------------------------------------------------------------------
// Figure out if we're running a Valve mod or not.
//-----------------------------------------------------------------------------
static bool IsValveMod(const char* pModName)
{
return (Q_stricmp(pModName, "cstrike") == 0 ||
Q_stricmp(pModName, "dod") == 0 ||
Q_stricmp(pModName, "hl1mp") == 0 ||
Q_stricmp(pModName, "tf") == 0 ||
Q_stricmp(pModName, "hl2mp") == 0 ||
Q_stricmp(pModName, "csgo") == 0);
}
//-----------------------------------------------------------------------------
// Figure out if we're running a Respawn mod or not.
//-----------------------------------------------------------------------------
static bool IsRespawnMod(const char* pModName)
{
return (Q_stricmp(pModName, "r1") == 0 ||
Q_stricmp(pModName, "r2") == 0 ||
Q_stricmp(pModName, "r5") == 0);
}
//-----------------------------------------------------------------------------
// Initialize the VPK and file cache system
//-----------------------------------------------------------------------------
static void InitVPKSystem()
{
char szCacheEnableFilePath[260]; // [rsp+20h] [rbp-118h] BYREF
char bFixSlashes = FileSystem()->GetCurrentDirectory(szCacheEnableFilePath, sizeof(szCacheEnableFilePath)) ? szCacheEnableFilePath[0] : '\0';
size_t nCachePathLen = strlen(szCacheEnableFilePath);
size_t nCacheFileLen = sizeof(DFS_ENABLE_PATH)-1;
if ((nCachePathLen + nCacheFileLen) < 0x104 || (nCacheFileLen = (sizeof(szCacheEnableFilePath)-1) - nCachePathLen, nCachePathLen != (sizeof(szCacheEnableFilePath)-1)))
{
strncat(szCacheEnableFilePath, DFS_ENABLE_PATH, nCacheFileLen)[sizeof(szCacheEnableFilePath)-1] = '\0';
bFixSlashes = szCacheEnableFilePath[0];
}
if (bFixSlashes)
{
V_FixSlashes(szCacheEnableFilePath, '/');
}
if (!CommandLine()->CheckParm("-novpk") && FileSystem()->FileExists(szCacheEnableFilePath, nullptr))
{
FileSystem()->AddSearchPath(".", "MAIN", SearchPathAdd_t::PATH_ADD_TO_TAIL);
#ifndef DEDICATED
FileSystem()->SetVPKCacheModeClient();
FileSystem()->MountVPKFile("vpk/client_frontend.bsp");
#else // Dedicated runs server vpk's and must have 'vpk/mp_common.bsp' mounted.
FileSystem()->SetVPKCacheModeServer();
FileSystem()->MountVPKFile("vpk/server_mp_common.bsp");
#endif // !DEDICATED
}
}
InitReturnVal_t CEngineAPI::VInit(CEngineAPI* pEngineAPI)
{
return CEngineAPI__Init(pEngineAPI);
}
//-----------------------------------------------------------------------------
// Initialization, shutdown of a mod.
//-----------------------------------------------------------------------------
bool CEngineAPI::VModInit(CEngineAPI* pEngineAPI, const char* pModName, const char* pGameDir)
{
// Register new Pak Assets here!
//RTech_RegisterAsset(0, 1, "", nullptr, nullptr, nullptr, CMemory(0x1660AD0A8).RCast<void**>(), 8, 8, 8, 0, 0xFFFFFFC);
bool results = CEngineAPI__ModInit(pEngineAPI, pModName, pGameDir);
if (!IsValveMod(pModName) && !IsRespawnMod(pModName))
{
#ifndef DEDICATED
g_pEngineClient->SetRestrictServerCommands(true); // Restrict server commands.
g_pEngineClient->SetRestrictClientCommands(true); // Restrict client commands.
#endif // !DEDICATED
}
return results;
}
//-----------------------------------------------------------------------------
// Sets startup info
//-----------------------------------------------------------------------------
void CEngineAPI::VSetStartupInfo(CEngineAPI* pEngineAPI, StartupInfo_t* pStartupInfo)
{
if (*g_bTextMode)
{
return;
}
const size_t nBufLen = sizeof(pStartupInfo->m_szBaseDirectory);
strncpy(g_szBaseDir, pStartupInfo->m_szBaseDirectory, nBufLen);
g_pEngineParms->baseDirectory = g_szBaseDir;
g_szBaseDir[nBufLen-1] = '\0';
void** pCurrentInstance = &pEngineAPI->m_StartupInfo.m_pInstance;
size_t nInstances = 6;
do
{
pCurrentInstance += 16;
uint64_t pInstance = *(_QWORD*)&pStartupInfo->m_pInstance;
pStartupInfo = (StartupInfo_t*)((char*)pStartupInfo + 128);
*((_QWORD*)pCurrentInstance - 8) = pInstance;
*((_QWORD*)pCurrentInstance - 7) = *(_QWORD*)&pStartupInfo[-1].m_pParentAppSystemGroup[132];
*((_QWORD*)pCurrentInstance - 6) = *(_QWORD*)&pStartupInfo[-1].m_pParentAppSystemGroup[148];
*((_QWORD*)pCurrentInstance - 5) = *(_QWORD*)&pStartupInfo[-1].m_pParentAppSystemGroup[164];
*((_QWORD*)pCurrentInstance - 4) = *(_QWORD*)&pStartupInfo[-1].m_pParentAppSystemGroup[180];
*((_QWORD*)pCurrentInstance - 3) = *(_QWORD*)&pStartupInfo[-1].m_pParentAppSystemGroup[196];
*((_QWORD*)pCurrentInstance - 2) = *(_QWORD*)&pStartupInfo[-1].m_pParentAppSystemGroup[212];
*((_QWORD*)pCurrentInstance - 1) = *(_QWORD*)&pStartupInfo[-1].m_pParentAppSystemGroup[228];
--nInstances;
} while (nInstances);
*(_QWORD*)pCurrentInstance = *(_QWORD*)&pStartupInfo->m_pInstance;
*((_QWORD*)pCurrentInstance + 1) = *(_QWORD*)&pStartupInfo->m_szBaseDirectory[8];
InitVPKSystem();
v_TRACEINIT(NULL, "COM_InitFilesystem( m_StartupInfo.m_szInitialMod )", "COM_ShutdownFileSystem()");
v_COM_InitFilesystem(pEngineAPI->m_StartupInfo.m_szInitialMod);
*g_bTextMode = true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEngineAPI::PumpMessages()
{
#ifndef DEDICATED
MSG msg;
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
if (in_syncRT->GetBool())
(*g_fnSyncRTWithIn)();
g_pInputSystem->PollInputState(v_UIEventDispatcher);
g_pGame->DispatchAllStoredGameMessages();
#endif // !DEDICATED
}
void CEngineAPI::UpdateLowLatencyParameters()
{
#ifndef DEDICATED
const bool bUseLowLatencyMode = gfx_nvnUseLowLatency->GetBool();
const bool bUseLowLatencyBoost = gfx_nvnUseLowLatencyBoost->GetBool();
const bool bUseMarkersToOptimize = gfx_nvnUseMarkersToOptimize->GetBool();
float fpsMax = fps_max_gfx->GetFloat();
if (fpsMax == -1.0f)
{
const float globalFps = fps_max->GetFloat();
// Make sure the global fps limiter is 'unlimited'
// before we let the gfx frame limiter cap it to
// the desktop's refresh rate; not adhering to
// this will result in a major performance drop.
if (globalFps == 0.0f)
fpsMax = g_pGame->GetTVRefreshRate();
else
fpsMax = 0.0f; // Don't let NVIDIA limit the frame rate.
}
GFX_UpdateLowLatencyParameters(D3D11Device(), bUseLowLatencyMode,
bUseLowLatencyBoost, bUseMarkersToOptimize, fpsMax);
#endif // !DEDICATED
}
void CEngineAPI::RunLowLatencyFrame()
{
#ifndef DEDICATED
if (GFX_IsLowLatencySDKEnabled())
{
if (GFX_HasPendingLowLatencyParameterUpdates())
{
UpdateLowLatencyParameters();
}
GFX_RunLowLatencyFrame(D3D11Device());
}
#endif // !DEDICATED
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CEngineAPI::MainLoop()
{
#ifndef DEDICATED
bool bRunLowLatency = false;
#endif // !DEDICATED
// Main message pump
while (true)
{
// Pump messages unless someone wants to quit
if (g_pEngine->GetQuitting() != IEngine::QUIT_NOTQUITTING)
{
if (g_pEngine->GetQuitting() != IEngine::QUIT_TODESKTOP) {
return true;
}
return false;
}
#ifndef DEDICATED
if (bRunLowLatency) {
CEngineAPI::RunLowLatencyFrame();
bRunLowLatency = false;
}
CEngineAPI::PumpMessages();
#endif // !DEDICATED
if (g_pEngine->Frame())
{
#ifndef DEDICATED
// Only run reflex if we ran an actual engine frame.
bRunLowLatency = true;
#endif // !DEDICATED
}
}
}
///////////////////////////////////////////////////////////////////////////////
void VSys_Dll2::Detour(const bool bAttach) const
{
DetourSetup(&CEngineAPI__Init, &CEngineAPI::VInit, bAttach);
DetourSetup(&CEngineAPI__ModInit, &CEngineAPI::VModInit, bAttach);
DetourSetup(&CEngineAPI__PumpMessages, &CEngineAPI::PumpMessages, bAttach);
DetourSetup(&CEngineAPI__MainLoop, &CEngineAPI::MainLoop, bAttach);
DetourSetup(&CEngineAPI__SetStartupInfo, &CEngineAPI::VSetStartupInfo, bAttach);
}