DataCache: cleanup mdlcache code

Cleanup and fixup CMDLCache::GetVCollide (originally named CMDLCache::GetStudioHdr which was incorrect).
This commit is contained in:
Kawe Mazidjatari 2024-01-04 16:12:25 +01:00
parent 17900c4150
commit 4c798b1eb1
4 changed files with 163 additions and 89 deletions

View File

@ -29,30 +29,10 @@ std::unordered_set<MDLHandle_t> g_vBadMDLHandles;
studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
{
studiodata_t* pStudioData = cache->GetStudioData(handle);
studiohdr_t* pStudioHdr;
if (pStudioData)
if (!pStudioData)
{
if (pStudioData->m_MDLCache &&
pStudioData->m_MDLCache != DC_INVALID_HANDLE)
{
studiohdr_t* pStudioHDR = **reinterpret_cast<studiohdr_t***>(pStudioData);
if (!g_pMDLFallback->m_hErrorMDL && V_ComparePath(pStudioHDR->name, ERROR_MODEL))
{
g_pMDLFallback->m_pErrorHDR = pStudioHDR;
g_pMDLFallback->m_hErrorMDL = handle;
}
else if (!g_pMDLFallback->m_hEmptyMDL && V_ComparePath(pStudioHDR->name, EMPTY_MODEL))
{
g_pMDLFallback->m_pEmptyHDR = pStudioHDR;
g_pMDLFallback->m_hEmptyMDL = handle;
}
}
}
else
{
pStudioHdr = GetErrorModel();
studiohdr_t* const pStudioHdr = GetErrorModel();
if (!IsKnownBadModel(handle))
{
@ -65,28 +45,54 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
return pStudioHdr;
}
int nFlags = STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE | STUDIOHDR_FLAGS_OBSOLETE;
studiocache_t* studioCache = pStudioData->GetStudioCache();
// Store error and empty fallback models.
if (studioCache && studioCache != DC_INVALID_HANDLE)
{
studiohdr_t* const pStudioHDR = pStudioData->GetStudioCache()->GetStudioHdr();
if (pStudioHDR)
{
if (!g_pMDLFallback->m_hErrorMDL && V_ComparePath(pStudioHDR->name, ERROR_MODEL))
{
g_pMDLFallback->m_pErrorHDR = pStudioHDR;
g_pMDLFallback->m_hErrorMDL = handle;
}
else if (!g_pMDLFallback->m_hEmptyMDL && V_ComparePath(pStudioHDR->name, EMPTY_MODEL))
{
g_pMDLFallback->m_pEmptyHDR = pStudioHDR;
g_pMDLFallback->m_hEmptyMDL = handle;
}
}
}
const int nFlags = STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE | STUDIOHDR_FLAGS_OBSOLETE;
if ((pStudioData->m_nFlags & nFlags))
{
void* pMDLCache = *reinterpret_cast<void**>(pStudioData);
if (pStudioData->m_MDLCache)
if (studioCache)
{
if (a3)
{
FindCachedMDL(cache, pStudioData, a3);
pMDLCache = *reinterpret_cast<void**>(pStudioData);
studioCache = pStudioData->m_pStudioCache;
}
pStudioHdr = *reinterpret_cast<studiohdr_t**>(pMDLCache);
studiohdr_t* const pStudioHdr = studioCache->GetStudioHdr();
if (pStudioHdr)
return pStudioHdr;
return FindUncachedMDL(cache, handle, pStudioData, a3);
}
pMDLCache = pStudioData->m_pAnimData;
if (pMDLCache)
studioanimcache_t* const animCache = pStudioData->m_pAnimCache;
if (animCache)
{
pStudioHdr = *reinterpret_cast<studiohdr_t**>(pMDLCache);
studiohdr_t* const pStudioHdr = animCache->GetStudioHdr();
if (pStudioHdr)
return pStudioHdr;
}
@ -129,9 +135,9 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
AUTO_LOCK(pStudioData->m_Mutex);
const char* szModelName = cache->GetModelName(handle);
size_t nFileNameLen = strlen(szModelName);
const size_t nFileNameLen = strlen(szModelName);
studiohdr_t* pStudioHdr;
studiohdr_t* pStudioHdr = nullptr;
if (nFileNameLen < 5 ||
(Q_stricmp(&szModelName[nFileNameLen - 5], ".rmdl") != 0) &&
@ -150,16 +156,16 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
return pStudioHdr;
}
LOBYTE(pStudioData->m_nGuidLock) = 1;
pStudioData->m_bSearchingModelName = true;
g_pRTech->StringToGuid(szModelName);
LOBYTE(pStudioData->m_nGuidLock) = 0;
pStudioData->m_bSearchingModelName = false;
if (!pStudioData->m_MDLCache)
if (!pStudioData->m_pStudioCache)
{
studiohdr_t** pAnimData = (studiohdr_t**)pStudioData->m_pAnimData;
if (pAnimData)
studioanimcache_t* const animCache = pStudioData->GetAnimCache();
if (animCache)
{
pStudioHdr = *pAnimData;
pStudioHdr = animCache->GetStudioHdr();
}
else
{
@ -178,11 +184,11 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
else
{
FindCachedMDL(cache, pStudioData, a4);
DataCacheHandle_t dataHandle = pStudioData->m_MDLCache;
studiocache_t* const dataCache = pStudioData->GetStudioCache();
if (dataHandle)
if (dataCache)
{
if (dataHandle == DC_INVALID_HANDLE)
if (dataCache == DC_INVALID_HANDLE)
{
pStudioHdr = GetErrorModel();
if (!IsKnownBadModel(handle))
@ -194,11 +200,12 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
}
}
else
pStudioHdr = *(studiohdr_t**)dataHandle;
pStudioHdr = dataCache->GetStudioHdr();
}
else
{
pStudioHdr = GetErrorModel();
if (!IsKnownBadModel(handle))
{
if (!pStudioHdr)
@ -209,6 +216,7 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
}
}
assert(pStudioHdr);
return pStudioHdr;
}
@ -218,30 +226,28 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
// handle -
// Output : a pointer to the studiohdr_t object
//-----------------------------------------------------------------------------
studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* cache, MDLHandle_t handle)
vcollide_t* CMDLCache::GetVCollide(CMDLCache* cache, MDLHandle_t handle)
{
studiohdr_t* pStudioHdr = nullptr; // rax
if (!handle)
{
pStudioHdr = GetErrorModel();
if (!pStudioHdr)
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Attempted to load model with no handle and \"%s\" couldn't be loaded.\n", ERROR_MODEL);
return pStudioHdr;
Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to get vcollide with no handle.\n");
return nullptr;
}
studiodata_t* pStudioData = cache->GetStudioData(handle);
DataCacheHandle_t dataCache = pStudioData->m_MDLCache;
const studiodata_t* const pStudioData = cache->GetStudioData(handle);
const studiocache_t* const dataCache = pStudioData->GetStudioCache();
if (dataCache &&
dataCache != DC_INVALID_HANDLE)
if (dataCache && dataCache != DC_INVALID_HANDLE)
{
void* v4 = *(void**)(*((_QWORD*)dataCache + 1) + 24i64);
if (v4)
pStudioHdr = (studiohdr_t*)((char*)v4 + 0x10);
CStudioVCollide* const pVCollide = dataCache->GetPhysicsCache()->GetStudioVCollide();
if (pVCollide)
{
return pVCollide->GetVCollide();
}
}
return pStudioHdr;
return nullptr;
}
//-----------------------------------------------------------------------------
@ -252,7 +258,7 @@ studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* cache, MDLHandle_t handle)
//-----------------------------------------------------------------------------
studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle)
{
studiodata_t* pStudioData = cache->GetStudioData(handle);
const studiodata_t* pStudioData = cache->GetStudioData(handle);
if (!pStudioData)
{
@ -264,21 +270,22 @@ studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle)
pStudioData = cache->GetStudioData(g_pMDLFallback->m_hErrorMDL);
}
DataCacheHandle_t dataCache = pStudioData->m_MDLCache;
const studiocache_t* const dataCache = pStudioData->GetStudioCache();
if (dataCache)
{
if (dataCache == DC_INVALID_HANDLE)
return nullptr;
void* pAnimData = (void*)*((_QWORD*)dataCache + 1);
studiophysicscache_t* const physicsCache = dataCache->GetPhysicsCache();
AcquireSRWLockExclusive(g_pMDLLock);
CStudioHWDataRef__SetFlags(reinterpret_cast<CStudioHWDataRef*>(pAnimData), 1i64); // !!! DECLARED INLINE IN < S3 !!!
CStudioHWDataRef__SetFlags(reinterpret_cast<CStudioHWDataRef*>(physicsCache), 1i64); // !!! DECLARED INLINE IN < S3 !!!
ReleaseSRWLockExclusive(g_pMDLLock);
}
if ((pStudioData->m_nFlags & STUDIODATA_FLAGS_STUDIOMESH_LOADED))
return &pStudioData->m_pHardwareRef->m_HardwareData;
return pStudioData->GetHardwareDataRef()->GetHardwareData();
else
return nullptr;
}
@ -313,5 +320,5 @@ void VMDLCache::Detour(const bool bAttach) const
DetourSetup(&CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL, bAttach);
DetourSetup(&CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL, bAttach);
DetourSetup(&CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData, bAttach);
DetourSetup(&CMDLCache__GetStudioHDR, &CMDLCache::GetStudioHDR, bAttach);
DetourSetup(&CMDLCache__GetVCollide, &CMDLCache::GetVCollide, bAttach);
}

View File

@ -2,17 +2,12 @@
#define MDLCACHE_H
#include "tier0/threadtools.h"
#include "tier1/utldict.h"
#include "tier1/refcount.h"
#include "datacache/idatacache.h"
#include "datacache/imdlcache.h"
#include "public/studio.h"
struct RStaticProp_t
{
studiohdr_t* m_pStudioHDR{};
CStudioHWDataRef* m_pHardWareData{};
const char* m_szPropName{};
uint8_t m_pUnknown[0x62]{};
};
#include "public/vphysics/vcollide.h"
#include "public/rtech/ipakfile.h"
struct RMDLFallBack_t
{
@ -39,11 +34,78 @@ struct RMDLFallBack_t
}
};
struct CStudioVCollide : public CRefCounted<>
{
public:
//~CStudioVCollide() // TODO: add g_PhysicsCollision to SDK
//{
// g_pPhysicsCollision->VCollideUnload(&m_vcollide);
//}
vcollide_t* GetVCollide()
{
return &m_vcollide;
}
private:
vcollide_t m_vcollide;
};
class CStudioPhysicsGeoms : public CRefCounted<>
{
int unk1;
void* m_pGeomDataDesc;
int unk2;
__int16 unk3;
__int16 unk4;
};
struct studiophysicscache_t
{
inline CStudioVCollide* GetStudioVCollide() const { return m_pVCollide; }
inline CStudioPhysicsGeoms* GetPhysicsGeoms() const { return m_pPhysicsGeoms; }
int unk0;
int unk1;
int unk2;
int unk3;
int unk4;
int unk5;
CStudioVCollide* m_pVCollide;
CStudioPhysicsGeoms* m_pPhysicsGeoms;
};
struct studiocache_t
{
inline studiohdr_t* GetStudioHdr() const { return m_pStudioHdr; }
inline studiophysicscache_t* GetPhysicsCache() const { return m_pPhysicsCache; }
studiohdr_t* m_pStudioHdr;
studiophysicscache_t* m_pPhysicsCache;
const char* m_szPropName;
uint8_t m_pUnknown[98];
};
struct studioanimcache_t
{
inline studiohdr_t* GetStudioHdr() const { return m_pStudioHdr; }
studiohdr_t* m_pStudioHdr;
const char* m_pszRigName;
int unk0;
int m_nSequenceCount;
void** m_pAnimSequences;
// TODO reverse the rest
};
// only models with type "mod_studio" have this data
struct studiodata_t
{
DataCacheHandle_t m_MDLCache;
void* m_pAnimData; // !TODO: reverse struct.
inline studiocache_t* GetStudioCache() const { return m_pStudioCache; }
inline studioanimcache_t* GetAnimCache() const { return m_pAnimCache; }
inline CStudioHWDataRef* GetHardwareDataRef() const { return m_pHardwareRef; }
studiocache_t* m_pStudioCache;
studioanimcache_t* m_pAnimCache; // !TODO: reverse struct.
unsigned short m_nRefCount;
unsigned short m_nFlags;
MDLHandle_t m_Handle;
@ -53,7 +115,8 @@ struct studiodata_t
int Unk5;
char pad[72];
CThreadFastMutex m_Mutex;
int m_nGuidLock; // always -1, set to 1 and 0 in CMDLCache::FindUncachedMDL.
bool m_bSearchingModelName;
PakHandle_t m_PakHandle;
};
extern RMDLFallBack_t* g_pMDLFallback;
@ -65,13 +128,14 @@ public:
static studiohdr_t* FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3);
static void FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void* a3);
static studiohdr_t* FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4);
static studiohdr_t* GetStudioHDR(CMDLCache* cache, MDLHandle_t handle);
static vcollide_t* GetVCollide(CMDLCache* cache, MDLHandle_t handle);
static studiohwdata_t* GetHardwareData(CMDLCache* cache, MDLHandle_t handle);
static studiohdr_t* GetErrorModel(void);
static bool IsKnownBadModel(MDLHandle_t handle);
studiodata_t* GetStudioData(MDLHandle_t handle)
inline studiodata_t* GetStudioData(MDLHandle_t handle)
{
EnterCriticalSection(&m_MDLMutex);
studiodata_t* pStudioData = m_MDLDict.Element(handle);
@ -80,7 +144,7 @@ public:
return pStudioData;
}
const char* GetModelName(MDLHandle_t handle)
inline const char* GetModelName(MDLHandle_t handle)
{
EnterCriticalSection(&m_MDLMutex);
const char* szModelName = m_MDLDict.GetElementName(handle);
@ -89,7 +153,7 @@ public:
return szModelName;
}
void* GetMaterialTable(MDLHandle_t handle)
inline void* GetMaterialTable(MDLHandle_t handle)
{
EnterCriticalSection(&m_MDLMutex);
studiodata_t* pStudioData = m_MDLDict.Element(handle);
@ -108,7 +172,7 @@ inline studiohdr_t*(*CMDLCache__FindMDL)(CMDLCache* pCache, MDLHandle_t handle,
inline void(*CMDLCache__FindCachedMDL)(CMDLCache* pCache, studiodata_t* pStudioData, void* a3);
inline studiohdr_t*(*CMDLCache__FindUncachedMDL)(CMDLCache* pCache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4);
inline studiohdr_t*(*CMDLCache__GetStudioHDR)(CMDLCache* pCache, MDLHandle_t handle);
inline vcollide_t*(*CMDLCache__GetVCollide)(CMDLCache* pCache, MDLHandle_t handle);
inline studiohwdata_t*(*CMDLCache__GetHardwareData)(CMDLCache* pCache, MDLHandle_t handle);
inline bool(*CStudioHWDataRef__SetFlags)(CStudioHWDataRef* ref, int64_t flags); // Probably incorrect name.
@ -124,7 +188,7 @@ class VMDLCache : public IDetour
LogFunAdr("CMDLCache::FindMDL", CMDLCache__FindMDL);
LogFunAdr("CMDLCache::FindCachedMDL", CMDLCache__FindCachedMDL);
LogFunAdr("CMDLCache::FindUncachedMDL", CMDLCache__FindUncachedMDL);
LogFunAdr("CMDLCache::GetStudioHDR", CMDLCache__GetStudioHDR);
LogFunAdr("CMDLCache::GetVCollide", CMDLCache__GetVCollide);
LogFunAdr("CMDLCache::GetHardwareData", CMDLCache__GetHardwareData);
LogFunAdr("CStudioHWDataRef::SetFlags", CStudioHWDataRef__SetFlags);
@ -136,7 +200,7 @@ class VMDLCache : public IDetour
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F1 0F B7 EA").GetPtr(CMDLCache__FindMDL);
g_GameDll.FindPatternSIMD("4D 85 C0 74 7A 48 89 6C 24 ??").GetPtr(CMDLCache__FindCachedMDL);
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 48 8B E9 0F B7 FA").GetPtr(CMDLCache__FindUncachedMDL);
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 5C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 03 48 8B 48 08").GetPtr(CMDLCache__GetStudioHDR);
g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 5C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 03 48 8B 48 08").GetPtr(CMDLCache__GetVCollide);
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 7C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 1F").GetPtr(CMDLCache__GetHardwareData);
g_GameDll.FindPatternSIMD("48 83 EC 08 4C 8D 14 12").GetPtr(CStudioHWDataRef__SetFlags);
}

View File

@ -6,6 +6,6 @@
//---------------------------------------------------------
FORWARD_DECLARE_HANDLE(memhandle_t);
typedef memhandle_t DataCacheHandle_t;
#define DC_INVALID_HANDLE ((DataCacheHandle_t)0xDEADFEEDDEADFEED)
#define DC_INVALID_HANDLE ((void*)0xDEADFEEDDEADFEED)
#endif // IDATACACHE_H

View File

@ -1066,14 +1066,17 @@ private:
CMDLCache* m_pMDLCache;
};
class CStudioHWDataRef
template<class T>
class CStudioAssetEmbeddedRef : public CRefCounted<>
{
protected:
T m_Embedded;
};
class CStudioHWDataRef : public CStudioAssetEmbeddedRef<studiohwdata_t>
{
public:
bool IsDataRef(void) const { return true; }
CStudioHWDataRef* m_pVTable;
uint8_t pad0[0x8];
studiohwdata_t m_HardwareData;
studiohwdata_t* GetHardwareData() { return &m_Embedded; }
};
#endif // STUDIO_H