mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
The 'DirectX_Init()' call was performed late in code, shortly after the window has been created (at this point all device objects and window handles are valid), but the 'DirectX_Shutdown()' call was performed on DLL_DETACH, which was way too late, as the objects were already destroyed at this point. This wasn't an issue before, as we created our own objects in the old DX code. But due to optimizations, we were using the same pointers as the game (noticeable performance boost), but did not adjust the shutdown to accommodate the changes. The shutdown is now performed while the device objects and window handles are valid. Code has been tested on Nvidia and AMD systems, and has confirmed to fix the aforementioned issues.
190 lines
4.9 KiB
C++
190 lines
4.9 KiB
C++
#include "core/stdafx.h"
|
|
#include "core/r5dev.h"
|
|
#include "core/init.h"
|
|
#include "core/logdef.h"
|
|
#include "core/logger.h"
|
|
#include "tier0/basetypes.h"
|
|
#include "tier0/crashhandler.h"
|
|
/*****************************************************************************/
|
|
#ifndef DEDICATED
|
|
#include "windows/id3dx.h"
|
|
#include "windows/input.h"
|
|
#endif // !DEDICATED
|
|
#include "windows/console.h"
|
|
#include "windows/system.h"
|
|
#include "mathlib/mathlib.h"
|
|
#include "launcher/launcher.h"
|
|
|
|
#ifndef DEDICATED
|
|
#define SDK_DEFAULT_CFG "cfg/startup_default.cfg"
|
|
#else
|
|
#define SDK_DEFAULT_CFG "cfg/startup_dedi_default.cfg"
|
|
#endif
|
|
|
|
//#############################################################################
|
|
// INITIALIZATION
|
|
//#############################################################################
|
|
|
|
void Crash_Callback()
|
|
{
|
|
// Shutdown SpdLog to flush all buffers.
|
|
SpdLog_Shutdown();
|
|
|
|
// TODO[ AMOS ]: This is where we want to call backtrace from.
|
|
}
|
|
|
|
void Tier0_Init()
|
|
{
|
|
#if !defined (DEDICATED)
|
|
g_GameDll = CModule("r5apex.exe");
|
|
g_RadVideoToolsDll = CModule("bink2w64.dll");
|
|
g_RadAudioDecoderDll = CModule("binkawin64.dll");
|
|
g_RadAudioSystemDll = CModule("mileswin64.dll");
|
|
#if !defined (CLIENT_DLL)
|
|
g_SDKDll = CModule("gamesdk.dll");
|
|
#else // This dll is loaded from 'bin/x64_retail//'
|
|
g_SDKDll = CModule("client.dll");
|
|
#endif // !CLIENT_DLL
|
|
#else // No DirectX and Miles imports.
|
|
g_GameDll = CModule("r5apex_ds.exe");
|
|
g_SDKDll = CModule("dedicated.dll");
|
|
#endif // !DEDICATED
|
|
|
|
// Setup logger callback sink.
|
|
g_CoreMsgVCallback = &EngineLoggerSink;
|
|
|
|
// Setup crash callback.
|
|
g_CrashHandler->SetCrashCallback(&Crash_Callback);
|
|
}
|
|
|
|
void SDK_Init()
|
|
{
|
|
if (strstr(GetCommandLineA(), "-launcher"))
|
|
{
|
|
g_svCmdLine = GetCommandLineA();
|
|
}
|
|
else
|
|
{
|
|
g_svCmdLine = LoadConfigFile(SDK_DEFAULT_CFG);
|
|
}
|
|
#ifndef DEDICATED
|
|
if (g_svCmdLine.find("-wconsole") != std::string::npos)
|
|
{
|
|
Console_Init();
|
|
}
|
|
#else
|
|
Console_Init();
|
|
#endif // !DEDICATED
|
|
|
|
SpdLog_Init();
|
|
Winsock_Init(); // Initialize Winsock.
|
|
|
|
for (size_t i = 0; i < SDK_ARRAYSIZE(R5R_EMBLEM); i++)
|
|
{
|
|
std::string svEscaped = StringEscape(R5R_EMBLEM[i]);
|
|
spdlog::info("{:s}{:s}{:s}\n", g_svRedF, svEscaped, g_svReset);
|
|
}
|
|
spdlog::info("\n");
|
|
|
|
Systems_Init();
|
|
WinSys_Init();
|
|
|
|
#ifndef DEDICATED
|
|
Input_Init();
|
|
#endif // !DEDICATED
|
|
|
|
// Initialize cURL with rebuilt memory callbacks
|
|
// featuring the game's memalloc implementation.
|
|
// this is required in order to hook cURL code
|
|
// in-game, as we otherwise would manage memory
|
|
// memory created by the game's implementation,
|
|
// using the standard one.
|
|
curl_global_init_mem(CURL_GLOBAL_ALL,
|
|
&R_malloc,
|
|
&R_free,
|
|
&R_realloc,
|
|
&R_strdup,
|
|
&R_calloc);
|
|
lzham_enable_fail_exceptions(true);
|
|
}
|
|
|
|
//#############################################################################
|
|
// SHUTDOWN
|
|
//#############################################################################
|
|
|
|
void SDK_Shutdown()
|
|
{
|
|
static bool bShutDown = false;
|
|
assert(!bShutDown);
|
|
if (bShutDown)
|
|
{
|
|
spdlog::error("Recursive shutdown!\n");
|
|
return;
|
|
}
|
|
bShutDown = true;
|
|
spdlog::info("Shutdown GameSDK\n");
|
|
|
|
curl_global_cleanup();
|
|
|
|
Winsock_Shutdown();
|
|
Systems_Shutdown();
|
|
WinSys_Shutdown();
|
|
|
|
#ifndef DEDICATED
|
|
Input_Shutdown();
|
|
#endif // !DEDICATED
|
|
|
|
Console_Shutdown();
|
|
SpdLog_Shutdown();
|
|
}
|
|
|
|
//#############################################################################
|
|
// ENTRYPOINT
|
|
//#############################################################################
|
|
|
|
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.
|
|
|
|
NOTE_UNUSED(hModule);
|
|
NOTE_UNUSED(lpReserved);
|
|
|
|
#if !defined (DEDICATED) && !defined (CLIENT_DLL)
|
|
// This dll is imported by the game executable, we cannot circumvent it.
|
|
// To solve the recursive init problem, we check if -noworkerdll is passed.
|
|
// If this is passed, the worker dll will not be initialized, which allows
|
|
// us to load the client dll (or any other dll) instead, or load the game
|
|
// without the SDK.
|
|
s_bNoWorkerDll = !!strstr(GetCommandLineA(), "-noworkerdll");
|
|
#endif // !DEDICATED && CLIENT_DLL
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
{
|
|
if (!s_bNoWorkerDll)
|
|
{
|
|
Tier0_Init();
|
|
SDK_Init();
|
|
}
|
|
else // Destroy crash handler.
|
|
{
|
|
g_CrashHandler->~CCrashHandler();
|
|
g_CrashHandler = nullptr;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
{
|
|
if (!s_bNoWorkerDll)
|
|
{
|
|
SDK_Shutdown();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|