mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
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.
269 lines
9.3 KiB
C++
269 lines
9.3 KiB
C++
//===== 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);
|
||
}
|