Fix rare crash

This crash happens when the BSP is missing a lot of shaders and materials.
The call originates from 'R_DrawWorldMeshesDepthOnly()', but it is unclear which missing shader is causing the nullptr.  checking for a nullptr here should be sufficient to deal with this kind of missing shader
This commit is contained in:
Kawe Mazidjatari 2022-04-30 20:35:08 +02:00
parent a4314b1c37
commit 4ead3ab1c9
2 changed files with 43 additions and 0 deletions

View File

@ -47,13 +47,36 @@ void HStreamDB_Init(const char* pszStreamDBFile)
StreamDB_Init(pszStreamDBFile);
}
//---------------------------------------------------------------------------------
// Purpose: draw frame
//---------------------------------------------------------------------------------
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
void* __fastcall DispatchDrawCall(int64_t a1, uint64_t a2, int a3, int a4, char a5, int a6, uint_8t a7, int64_t a8, uint32_t a9, uint32_t a10, __m128* a11, int a12)
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
void* __fastcall DispatchDrawCall(int64_t a1, uint64_t a2, int a3, int a4, int64_t a5, int a6, uint8_t a7, int64_t a8, uint32_t a9, uint32_t a10, int a11, __m128* a12, int a13, int64_t a14)
#endif
{
// This only happens when the BSP is in a horrible condition (bad depth buffer draw calls!)
// but allows you to load BSP's with virtually all missing shaders/materials and models
// being replaced with 'material_for_aspect/error.rpak' and 'mdl/error.rmdl'.
if (!s_pRenderContext.GetValue<void*>())
return nullptr;
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
return v_DispatchDrawCall(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
return v_DispatchDrawCall(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
#endif
}
///////////////////////////////////////////////////////////////////////////////
void CMaterialSystem_Attach()
{
DetourAttach((LPVOID*)&StreamDB_Init, &HStreamDB_Init);
DetourAttach((LPVOID*)&v_DispatchDrawCall, &DispatchDrawCall);
}
void CMaterialSystem_Detach()
{
DetourDetach((LPVOID*)&StreamDB_Init, &HStreamDB_Init);
DetourDetach((LPVOID*)&v_DispatchDrawCall, &DispatchDrawCall);
}

View File

@ -4,12 +4,22 @@
inline CMemory p_CMaterialSystem__Init;
inline auto CMaterialSystem__Init = p_CMaterialSystem__Init.RCast<void* (*)(void* thisptr)>();
#ifndef DEDICATED
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
inline CMemory P_DrawFrame;
inline auto V_DrawFrame = P_DrawFrame.RCast<void* (*)(int64_t a1, uint64_t a2, int a3, int a4, char a5, int a6, uint_8t a7, int64_t a8, uint32_t a9, uint32_t a10, __m128* a11, int a12)>();
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
inline CMemory p_DispatchDrawCall;
inline auto v_DispatchDrawCall = p_DispatchDrawCall.RCast<void* (*)(int64_t a1, uint64_t a2, int a3, int a4, int64_t a5, int a6, uint8_t a7, int64_t a8, uint32_t a9, uint32_t a10, int a11, __m128* a12, int a13, int64_t a14)>();
#endif
inline CMemory p_DrawStreamOverlay;
inline auto DrawStreamOverlay = p_DrawStreamOverlay.RCast<const char* (*)(void* thisptr, uint8_t* a2, void* unused, void* a4)>();
inline CMemory p_StreamDB_Init;
inline auto StreamDB_Init = p_StreamDB_Init.RCast<void (*)(const char* pszStreamDbFile)>();
inline CMemory s_pRenderContext;
inline void* g_pMaterialSystem = nullptr;
inline int* total_streaming_tex_memory = nullptr;
inline int* unfree_streaming_tex_memory = nullptr;
@ -25,7 +35,9 @@ class HMaterialSystem : public IDetour
{
std::cout << "| FUN: CMaterialSystem::Init : 0x" << std::hex << std::uppercase << p_CMaterialSystem__Init.GetPtr() << std::setw(nPad) << " |" << std::endl;
#ifndef DEDICATED
std::cout << "| FUN: DispatchDrawCall : 0x" << std::hex << std::uppercase << p_DispatchDrawCall.GetPtr() << std::setw(nPad) << " |" << std::endl;
std::cout << "| FUN: DrawStreamOverlay : 0x" << std::hex << std::uppercase << p_DrawStreamOverlay.GetPtr() << std::setw(nPad) << " |" << std::endl;
std::cout << "| VAR: s_pRenderContext : 0x" << std::hex << std::uppercase << s_pRenderContext.GetPtr() << std::setw(nPad) << " |" << std::endl;
std::cout << "| FUN: StreamDB_Init : 0x" << std::hex << std::uppercase << p_StreamDB_Init.GetPtr() << std::setw(nPad) << " |" << std::endl;
std::cout << "| VAR: g_pMaterialSystem : 0x" << std::hex << std::uppercase << g_pMaterialSystem << std::setw(0) << " |" << std::endl;
#endif // !DEDICATED
@ -36,6 +48,13 @@ class HMaterialSystem : public IDetour
p_CMaterialSystem__Init = g_mGameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x70\x48\x83\x3D\x00\x00\x00\x00\x00"), "xxxx?xxxxxxxxxxxxxxxxxx?????");
CMaterialSystem__Init = p_CMaterialSystem__Init.RCast<void* (*)(void*)>(); /*48 89 5C 24 ?? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 70 48 83 3D ?? ?? ?? ?? ??*/
#ifndef DEDICATED
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
p_DispatchDrawCall = g_mGameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x44\x89\x4C\x24\x00\x44\x89\x44\x24\x00\x48\x89\x4C\x24\x00\x55\x53"), "xxxx?xxxx?xxxx?xx");
v_DispatchDrawCall = p_DispatchDrawCall.RCast<void* (*)(int64_t, uint64_t, int, int, char, int, uint8_t, int64_t, uint32_t, uint32_t, __m128*, int)>();
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
p_DispatchDrawCall = g_mGameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x44\x89\x4C\x24\x00\x44\x89\x44\x24\x00\x48\x89\x4C\x24\x00\x55\x53\x56"), "xxxx?xxxx?xxxx?xxx");
v_DispatchDrawCall = p_DispatchDrawCall.RCast<void* (*)(int64_t, uint64_t, int, int, int64_t, int, uint8_t, int64_t, uint32_t, uint32_t, int, __m128*, int, int64_t )>();
#endif
p_DrawStreamOverlay = g_mGameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x41\x56\xB8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x2B\xE0\xC6\x02\x00"), "xxx????x????xxxxxx");
DrawStreamOverlay = p_DrawStreamOverlay.RCast<const char* (*)(void*, uint8_t*, void*, void*)>(); // 41 56 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 C6 02 00 //
@ -46,6 +65,7 @@ class HMaterialSystem : public IDetour
virtual void GetVar(void) const
{
#ifndef DEDICATED
s_pRenderContext = p_DispatchDrawCall.FindPattern("48 8B ?? ?? ?? ?? 01").ResolveRelativeAddressSelf(0x3, 0x7);
g_pMaterialSystem = g_mGameDll.FindPatternSIMD(reinterpret_cast<rsig_t>(
"\x48\x8B\x0D\x00\x00\x00\x00\x48\x85\xC9\x74\x11\x48\x8B\x01\x48\x8D\x15\x00\x00\x00\x00"), "xxx????xxxxxxxxxxx????").ResolveRelativeAddressSelf(0x3, 0x7).RCast<void*>();