mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
CMDLCache code improvements
Slightly mapped out the CMDLCache class, to the point the pointers to its members are no longer needed. Also fixed a bug were the studiodata pointer was dereferenced before checking if its not null, this check did exist, but was performed too late. Fully implemented the CUtlDict class for m_MDLDict. Slightly optimized the initialization of the error model handles.
This commit is contained in:
parent
2cfed900d0
commit
abe68def03
@ -29,25 +29,31 @@ std::unordered_set<MDLHandle_t> g_vBadMDLHandles;
|
||||
studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
|
||||
{
|
||||
studiohdr_t* pStudioHdr; // rax
|
||||
studiodata_t* pStudioData = cache->GetStudioData(handle);
|
||||
|
||||
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
||||
studiodata_t* pStudioData = m_MDLDict->Find(handle);
|
||||
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
||||
|
||||
if (!g_pMDLFallback->m_hErrorMDL || !g_pMDLFallback->m_hEmptyMDL)
|
||||
if (pStudioData)
|
||||
{
|
||||
if (pStudioData->m_MDLCache)
|
||||
{
|
||||
studiohdr_t* pStudioHDR = **reinterpret_cast<studiohdr_t***>(pStudioData);
|
||||
if (pStudioHDR)
|
||||
|
||||
if (!g_pMDLFallback->m_hErrorMDL)
|
||||
{
|
||||
const string svStudio = ConvertToUnixPath(pStudioHDR->name);
|
||||
if (svStudio.compare(ERROR_MODEL) == NULL)
|
||||
CUtlString studioPathFixed(pStudioHDR->name);
|
||||
studioPathFixed.FixSlashes(INCORRECT_PATH_SEPARATOR);
|
||||
|
||||
if (studioPathFixed.IsEqual_CaseInsensitive(ERROR_MODEL))
|
||||
{
|
||||
g_pMDLFallback->m_pErrorHDR = pStudioHDR;
|
||||
g_pMDLFallback->m_hErrorMDL = handle;
|
||||
}
|
||||
else if (svStudio.compare(EMPTY_MODEL) == NULL)
|
||||
}
|
||||
else if (!g_pMDLFallback->m_hEmptyMDL)
|
||||
{
|
||||
CUtlString studioPathFixed(pStudioHDR->name);
|
||||
studioPathFixed.FixSlashes(INCORRECT_PATH_SEPARATOR);
|
||||
|
||||
if (studioPathFixed.IsEqual_CaseInsensitive(EMPTY_MODEL))
|
||||
{
|
||||
g_pMDLFallback->m_pEmptyHDR = pStudioHDR;
|
||||
g_pMDLFallback->m_hEmptyMDL = handle;
|
||||
@ -55,8 +61,7 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pStudioData)
|
||||
else
|
||||
{
|
||||
pStudioHdr = GetErrorModel();
|
||||
|
||||
@ -136,27 +141,20 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
|
||||
studiohdr_t** ppStudioHdr; // rax
|
||||
|
||||
pStudioData->m_Mutex.WaitForLock();
|
||||
const char* szModelName = cache->GetModelName(handle);
|
||||
|
||||
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
||||
void* pModelCache = cache->m_pModelCacheSection;
|
||||
char* szModelName = (char*)(*(_QWORD*)((int64)pModelCache + 24 * static_cast<int64>(handle) + 8));
|
||||
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
||||
|
||||
if (IsBadReadPtrV2(reinterpret_cast<void*>(szModelName)))
|
||||
pStudioHdr = GetErrorModel();
|
||||
if (!IsKnownBadModel(handle))
|
||||
{
|
||||
pStudioHdr = GetErrorModel();
|
||||
if (!IsKnownBadModel(handle))
|
||||
{
|
||||
if (!pStudioHdr)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model with handle \"%hu\" not found and \"%s\" couldn't be loaded.\n", handle, ERROR_MODEL);
|
||||
else
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Model with handle \"%hu\" not found; replacing with \"%s\".\n", handle, ERROR_MODEL);
|
||||
}
|
||||
|
||||
pStudioData->m_Mutex.ReleaseWaiter();
|
||||
return pStudioHdr;
|
||||
if (!pStudioHdr)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model with handle \"%hu\" not found and \"%s\" couldn't be loaded.\n", handle, ERROR_MODEL);
|
||||
else
|
||||
Error(eDLL_T::ENGINE, NO_ERROR, "Model with handle \"%hu\" not found; replacing with \"%s\".\n", handle, ERROR_MODEL);
|
||||
}
|
||||
|
||||
pStudioData->m_Mutex.ReleaseWaiter();
|
||||
return pStudioHdr;
|
||||
|
||||
size_t nFileNameLen = strlen(szModelName);
|
||||
|
||||
if (nFileNameLen < 5 ||
|
||||
@ -208,7 +206,7 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
|
||||
FindCachedMDL(cache, pStudioData, a4);
|
||||
if ((__int64)*(studiohdr_t**)pStudioData)
|
||||
{
|
||||
if ((__int64)*(studiohdr_t**)pStudioData == 0xDEADFEEDDEADFEED)
|
||||
if ((DataCacheHandle_t)*(studiohdr_t**)pStudioData == DC_INVALID_HANDLE)
|
||||
{
|
||||
pStudioHdr = GetErrorModel();
|
||||
if (!IsKnownBadModel(handle))
|
||||
@ -244,7 +242,7 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
|
||||
// handle -
|
||||
// Output : a pointer to the studiohdr_t object
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* pMDLCache, MDLHandle_t handle)
|
||||
studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* cache, MDLHandle_t handle)
|
||||
{
|
||||
studiohdr_t* pStudioHdr = nullptr; // rax
|
||||
|
||||
@ -257,12 +255,11 @@ studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* pMDLCache, MDLHandle_t handle)
|
||||
return pStudioHdr;
|
||||
}
|
||||
|
||||
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
||||
studiodata_t* pStudioData = m_MDLDict->Find(handle);
|
||||
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
||||
studiodata_t* pStudioData = cache->GetStudioData(handle);
|
||||
|
||||
if (*(_QWORD*)(pStudioData))
|
||||
{
|
||||
if (reinterpret_cast<int64_t>(pStudioData->m_MDLCache) != 0xDEADFEEDDEADFEED)
|
||||
if (pStudioData->m_MDLCache != DC_INVALID_HANDLE)
|
||||
{
|
||||
void* v4 = *(void**)(*((_QWORD*)pStudioData->m_MDLCache + 1) + 24i64);
|
||||
if (v4)
|
||||
@ -280,9 +277,7 @@ studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* pMDLCache, MDLHandle_t handle)
|
||||
//-----------------------------------------------------------------------------
|
||||
studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
||||
studiodata_t* pStudioData = m_MDLDict->Find(handle);
|
||||
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
||||
studiodata_t* pStudioData = cache->GetStudioData(handle);
|
||||
|
||||
if (!pStudioData)
|
||||
{
|
||||
@ -291,21 +286,21 @@ studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle)
|
||||
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Studio hardware with handle \"%hu\" not found and \"%s\" couldn't be loaded.\n", handle, ERROR_MODEL);
|
||||
return nullptr;
|
||||
}
|
||||
pStudioData = m_MDLDict->Find(g_pMDLFallback->m_hErrorMDL);
|
||||
pStudioData = cache->GetStudioData(g_pMDLFallback->m_hErrorMDL);
|
||||
}
|
||||
|
||||
if (pStudioData->m_MDLCache)
|
||||
{
|
||||
if (reinterpret_cast<int64_t>(pStudioData->m_MDLCache) == 0xDEADFEEDDEADFEED)
|
||||
if (pStudioData->m_MDLCache == DC_INVALID_HANDLE)
|
||||
return nullptr;
|
||||
|
||||
void* pAnimData = (void*)*((_QWORD*)pStudioData->m_MDLCache + 1);
|
||||
|
||||
AcquireSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&*m_MDLLock));
|
||||
AcquireSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&*g_pMDLLock));
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
v_CStudioHWDataRef__SetFlags(reinterpret_cast<CStudioHWDataRef*>(pAnimData), 1i64); // !!! DECLARED INLINE IN < S3 !!!
|
||||
#endif
|
||||
ReleaseSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&*m_MDLLock));
|
||||
ReleaseSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&*g_pMDLLock));
|
||||
}
|
||||
if ((pStudioData->m_nFlags & STUDIODATA_FLAGS_STUDIOMESH_LOADED))
|
||||
return &pStudioData->m_pHardwareRef->m_HardwareData;
|
||||
@ -313,21 +308,6 @@ studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the studio material glue from cache pool by handle
|
||||
// Input : *this -
|
||||
// handle -
|
||||
// Output : a pointer to the CMaterialGlue object
|
||||
//-----------------------------------------------------------------------------
|
||||
void* CMDLCache::GetMaterialTable(CMDLCache* cache, MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
||||
studiodata_t* pStudioData = m_MDLDict->Find(handle);
|
||||
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
||||
|
||||
return &pStudioData->m_pMaterialTable;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: gets the error model
|
||||
// Output : *studiohdr_t
|
||||
|
@ -63,7 +63,7 @@ struct studiodata_t
|
||||
extern RMDLFallBack_t* g_pMDLFallback;
|
||||
extern std::unordered_set<MDLHandle_t> g_vBadMDLHandles;
|
||||
|
||||
class CMDLCache
|
||||
class CMDLCache : public IMDLCache
|
||||
{
|
||||
public:
|
||||
static studiohdr_t* FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3);
|
||||
@ -71,15 +71,41 @@ public:
|
||||
static studiohdr_t* FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4);
|
||||
static studiohdr_t* GetStudioHDR(CMDLCache* cache, MDLHandle_t handle);
|
||||
static studiohwdata_t* GetHardwareData(CMDLCache* cache, MDLHandle_t handle);
|
||||
static void* GetMaterialTable(CMDLCache* cache, MDLHandle_t handle);
|
||||
static studiohdr_t* GetErrorModel(void);
|
||||
static bool IsKnownBadModel(MDLHandle_t handle);
|
||||
|
||||
CMDLCache* m_pVTable;
|
||||
void* m_pStrCmp; // string compare func;
|
||||
void* m_pModelCacheSection; // IDataCacheSection*
|
||||
int m_nModelCacheFrameLocks; //
|
||||
// TODO..
|
||||
|
||||
studiodata_t* GetStudioData(MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&m_MDLMutex));
|
||||
studiodata_t* pStudioData = m_MDLDict.Element(handle);
|
||||
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&m_MDLMutex));
|
||||
|
||||
return pStudioData;
|
||||
}
|
||||
|
||||
const char* GetModelName(MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&m_MDLMutex));
|
||||
const char* szModelName = m_MDLDict.GetElementName(handle);
|
||||
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&m_MDLMutex));
|
||||
|
||||
return szModelName;
|
||||
}
|
||||
|
||||
void* GetMaterialTable(MDLHandle_t handle)
|
||||
{
|
||||
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&m_MDLMutex));
|
||||
studiodata_t* pStudioData = m_MDLDict.Element(handle);
|
||||
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&m_MDLMutex));
|
||||
|
||||
return &pStudioData->m_pMaterialTable;
|
||||
}
|
||||
|
||||
private:
|
||||
CUtlDict<studiodata_t*, MDLHandle_t> m_MDLDict;
|
||||
LPCRITICAL_SECTION m_MDLMutex;
|
||||
// !TODO: reverse the rest
|
||||
};
|
||||
|
||||
inline CMemory p_CMDLCache__FindMDL;
|
||||
@ -100,10 +126,8 @@ inline auto v_CMDLCache__GetHardwareData = p_CMDLCache__GetHardwareData.RCast<st
|
||||
inline CMemory p_CStudioHWDataRef__SetFlags; // Probably incorrect.
|
||||
inline auto v_CStudioHWDataRef__SetFlags = p_CStudioHWDataRef__SetFlags.RCast<bool (*)(CStudioHWDataRef* ref, int64_t flags)>();
|
||||
#endif
|
||||
inline CUtlDict<studiodata_t*, MDLHandle_t>* m_MDLDict;
|
||||
inline LPCRITICAL_SECTION* m_MDLMutex = nullptr;
|
||||
inline PSRWLOCK* m_MDLLock = nullptr;
|
||||
inline CMDLCache* g_MDLCache = nullptr;
|
||||
inline CMDLCache* g_pMDLCache = nullptr;
|
||||
inline PSRWLOCK* g_pMDLLock = nullptr; // Possibly a member? research required.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VMDLCache : public IDetour
|
||||
@ -120,10 +144,8 @@ class VMDLCache : public IDetour
|
||||
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
|
||||
LogFunAdr("CStudioHWDataRef::SetFlags", p_CStudioHWDataRef__SetFlags.GetPtr());
|
||||
#endif
|
||||
LogVarAdr("m_MDLMutex", reinterpret_cast<uintptr_t>(m_MDLMutex));
|
||||
LogVarAdr("m_MDLLock", reinterpret_cast<uintptr_t>(m_MDLLock));
|
||||
LogVarAdr("m_MDLDict", reinterpret_cast<uintptr_t>(m_MDLDict));
|
||||
LogVarAdr("g_MDLCache", reinterpret_cast<uintptr_t>(g_MDLCache));
|
||||
LogVarAdr("g_MDLCache", reinterpret_cast<uintptr_t>(g_pMDLCache));
|
||||
LogVarAdr("g_MDLLock", reinterpret_cast<uintptr_t>(g_pMDLLock));
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
@ -163,15 +185,11 @@ class VMDLCache : public IDetour
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
{
|
||||
m_MDLMutex = g_GameDll.FindPatternSIMD("48 83 EC 28 BA ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? FF 15 ?? ?? ?? ?? 0F B6 05 ?? ?? ?? ??")
|
||||
.FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<LPCRITICAL_SECTION*>();
|
||||
// Get MDLCache singleton from CStudioRenderContext::Connect
|
||||
g_pMDLCache = g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? 48 85 C0 48 0F 45 C8 FF 05 ?? ?? ?? ?? 48 83 3D ?? ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ??")
|
||||
.FindPatternSelf("48 8D 05").ResolveRelativeAddressSelf(0x3, 0x7).RCast<CMDLCache*>();
|
||||
|
||||
m_MDLLock = p_CMDLCache__GetHardwareData.Offset(0x35).FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<PSRWLOCK*>();
|
||||
|
||||
m_MDLDict = p_CMDLCache__FindMDL.FindPattern("48 8B 05").ResolveRelativeAddressSelf(0x3, 0x7).RCast<CUtlDict<studiodata_t*, MDLHandle_t>*>();
|
||||
|
||||
g_MDLCache = g_GameDll.FindPatternSIMD("48 8B 0D ?? ?? ?? ?? 44 0F B7 82 ?? ?? ?? ?? 48 8B 01 48 FF A0")
|
||||
.ResolveRelativeAddressSelf(0x3, 0x7).RCast<CMDLCache*>();
|
||||
g_pMDLLock = p_CMDLCache__GetHardwareData.Offset(0x35).FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<PSRWLOCK*>();
|
||||
}
|
||||
virtual void GetCon(void) const { }
|
||||
virtual void Attach(void) const;
|
||||
|
@ -8,12 +8,12 @@
|
||||
void* __fastcall CStaticProp_Init(int64_t thisptr, int64_t a2, unsigned int idx, unsigned int a4, StaticPropLump_t* lump, int64_t a6, int64_t a7)
|
||||
{
|
||||
MDLHandle_t handle = *reinterpret_cast<uint16_t*>(a7 + 0x140);
|
||||
studiohdr_t* pStudioHdr = g_MDLCache->FindMDL(g_MDLCache, handle, nullptr);
|
||||
studiohdr_t* pStudioHdr = g_pMDLCache->FindMDL(g_pMDLCache, handle, nullptr);
|
||||
|
||||
if (lump->m_Skin >= pStudioHdr->numskinfamilies)
|
||||
{
|
||||
Error(eDLL_T::ENGINE, NO_ERROR,
|
||||
"Invalid skin index for static prop %i with model '%s' (got %i, max %i)\n",
|
||||
"Invalid skin index for static prop #%i with model '%s' (got %i, max %i)\n",
|
||||
idx, pStudioHdr->name, lump->m_Skin, pStudioHdr->numskinfamilies-1);
|
||||
|
||||
lump->m_Skin = 0;
|
||||
|
@ -6,6 +6,6 @@
|
||||
//---------------------------------------------------------
|
||||
FORWARD_DECLARE_HANDLE(memhandle_t);
|
||||
typedef memhandle_t DataCacheHandle_t;
|
||||
#define DC_INVALID_HANDLE ((DataCacheHandle_t)0)
|
||||
#define DC_INVALID_HANDLE ((DataCacheHandle_t)0xDEADFEEDDEADFEED)
|
||||
|
||||
#endif // IDATACACHE_H
|
||||
|
@ -43,4 +43,11 @@ enum MDLCacheDataType_t
|
||||
MDLCACHE_VERTEXES,
|
||||
MDLCACHE_DECODEDANIMBLOCK
|
||||
};
|
||||
|
||||
abstract_class IMDLCache : public IAppSystem
|
||||
{
|
||||
// !TODO: map this out.
|
||||
};
|
||||
|
||||
|
||||
#endif // !IMDLCACHE_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user