DataCache: cleanup & improvements

* follow naming convention of studio.h.
* renamed studiocache_t to studiomodelcache_t.
* merged 'ModelHeader' struct with studiomodelcache_t.
* add 'physfile_t' structure.
This commit is contained in:
Kawe Mazidjatari 2024-01-07 01:39:15 +01:00
parent a85d9a556e
commit f961b3b013
4 changed files with 151 additions and 113 deletions

View File

@ -27,9 +27,9 @@ CStudioFallbackHandler g_StudioMdlFallbackHandler;
//-----------------------------------------------------------------------------
studiohdr_t* CMDLCache::FindMDL(CMDLCache* const cache, const MDLHandle_t handle, void* a3)
{
studiodata_t* const pStudioData = cache->GetStudioData(handle);
studiodata_t* const studioData = cache->GetStudioData(handle);
if (!pStudioData)
if (!studioData)
{
studiohdr_t* const pStudioHdr = GetErrorModel();
@ -44,46 +44,46 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* const cache, const MDLHandle_t handle
return pStudioHdr;
}
studiocache_t* studioCache = pStudioData->GetStudioCache();
studiomodelcache_t* modelCache = studioData->GetStudioCache();
// Store error and empty fallback models.
if (IS_VALID_DATACACHE_HANDLE(studioCache))
if (IS_VALID_DATACACHE_HANDLE(modelCache))
{
studiohdr_t* const pStudioHDR = pStudioData->GetStudioCache()->GetStudioHdr();
studiohdr_t* const studioHdr = studioData->GetStudioCache()->GetStudioHdr();
if (pStudioHDR)
if (studioHdr)
{
// Typically, you would only check for '(m_nFlags & STUDIODATA_ERROR_MODEL)',
// but for some reason this game doesn't have this flag set on that model.
if (!HasErrorModel() && ((pStudioData->m_nFlags & STUDIODATA_ERROR_MODEL)
|| V_ComparePath(pStudioHDR->name, ERROR_MODEL)))
if (!HasErrorModel() && ((studioData->flags & STUDIODATA_ERROR_MODEL)
|| V_ComparePath(studioHdr->name, ERROR_MODEL)))
{
g_StudioMdlFallbackHandler.SetFallbackModel(pStudioHDR, handle);
g_StudioMdlFallbackHandler.SetFallbackModel(studioHdr, handle);
}
}
}
const int nFlags = STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE | STUDIOHDR_FLAGS_OBSOLETE;
if ((pStudioData->m_nFlags & nFlags))
if ((studioData->flags & nFlags))
{
if (studioCache)
if (modelCache)
{
if (a3)
{
FindCachedMDL(cache, pStudioData, a3);
studioCache = pStudioData->m_pStudioCache;
FindCachedMDL(cache, studioData, a3);
modelCache = studioData->modelCache;
}
studiohdr_t* const pStudioHdr = studioCache->GetStudioHdr();
studiohdr_t* const pStudioHdr = modelCache->GetStudioHdr();
if (pStudioHdr)
return pStudioHdr;
return FindUncachedMDL(cache, handle, pStudioData, a3);
return FindUncachedMDL(cache, handle, studioData, a3);
}
studioanimcache_t* const animCache = pStudioData->m_pAnimCache;
studioanimcache_t* const animCache = studioData->animCache;
if (animCache)
{
@ -93,7 +93,7 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* const cache, const MDLHandle_t handle
return pStudioHdr;
}
}
return FindUncachedMDL(cache, handle, pStudioData, a3);
return FindUncachedMDL(cache, handle, studioData, a3);
}
//-----------------------------------------------------------------------------
@ -106,7 +106,7 @@ void CMDLCache::FindCachedMDL(CMDLCache* const cache, studiodata_t* const pStudi
{
if (a3)
{
AUTO_LOCK(pStudioData->m_Mutex);
AUTO_LOCK(pStudioData->mutex);
*(_QWORD*)((int64_t)a3 + 0x880) = *(_QWORD*)&pStudioData->pad[0x24];
int64_t v6 = *(_QWORD*)&pStudioData->pad[0x24];
@ -114,7 +114,7 @@ void CMDLCache::FindCachedMDL(CMDLCache* const cache, studiodata_t* const pStudi
*(_QWORD*)(v6 + 0x878) = (int64_t)a3;
*(_QWORD*)&pStudioData->pad[0x24] = (int64_t)a3;
*(_QWORD*)((int64_t)a3 + 0x870) = (int64_t)cache;
*(_WORD*)((int64_t)a3 + 0x888) = pStudioData->m_Handle;
*(_WORD*)((int64_t)a3 + 0x888) = pStudioData->modelHandle;
}
}
@ -128,95 +128,95 @@ void CMDLCache::FindCachedMDL(CMDLCache* const cache, studiodata_t* const pStudi
//-----------------------------------------------------------------------------
studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* const cache, const MDLHandle_t handle, studiodata_t* pStudioData, void* a4)
{
AUTO_LOCK(pStudioData->m_Mutex);
AUTO_LOCK(pStudioData->mutex);
const char* szModelName = cache->GetModelName(handle);
const size_t nFileNameLen = strlen(szModelName);
const char* modelName = cache->GetModelName(handle);
const size_t fileNameLen = strlen(modelName);
studiohdr_t* pStudioHdr = nullptr;
studiohdr_t* studioHdr = nullptr;
if (nFileNameLen < 5 ||
(Q_stricmp(&szModelName[nFileNameLen - 5], ".rmdl") != 0) &&
(Q_stricmp(&szModelName[nFileNameLen - 5], ".rrig") != 0) &&
(Q_stricmp(&szModelName[nFileNameLen - 5], ".rpak") != 0))
if (fileNameLen < 5 ||
(Q_stricmp(&modelName[fileNameLen - 5], ".rmdl") != 0) &&
(Q_stricmp(&modelName[fileNameLen - 5], ".rrig") != 0) &&
(Q_stricmp(&modelName[fileNameLen - 5], ".rpak") != 0))
{
pStudioHdr = GetErrorModel();
studioHdr = GetErrorModel();
if (!IsKnownBadModel(handle))
{
if (!pStudioHdr)
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Attempted to load old model \"%s\" and \"%s\" couldn't be loaded.\n", szModelName, ERROR_MODEL);
if (!studioHdr)
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Attempted to load old model \"%s\" and \"%s\" couldn't be loaded.\n", modelName, ERROR_MODEL);
else
Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to load old model \"%s\"; replacing with \"%s\".\n", szModelName, ERROR_MODEL);
Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to load old model \"%s\"; replacing with \"%s\".\n", modelName, ERROR_MODEL);
}
return pStudioHdr;
return studioHdr;
}
pStudioData->m_bSearchingModelName = true;
g_pRTech->StringToGuid(szModelName);
pStudioData->m_bSearchingModelName = false;
pStudioData->processing = true;
g_pRTech->StringToGuid(modelName);
pStudioData->processing = false;
if (!pStudioData->m_pStudioCache)
if (!pStudioData->modelCache)
{
studioanimcache_t* const animCache = pStudioData->GetAnimCache();
if (animCache)
{
pStudioHdr = animCache->GetStudioHdr();
studioHdr = animCache->GetStudioHdr();
}
else
{
pStudioHdr = GetErrorModel();
studioHdr = GetErrorModel();
if (!IsKnownBadModel(handle))
{
if (!pStudioHdr)
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" not found and \"%s\" couldn't be loaded.\n", szModelName, ERROR_MODEL);
if (!studioHdr)
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" not found and \"%s\" couldn't be loaded.\n", modelName, ERROR_MODEL);
else
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" not found; replacing with \"%s\".\n", szModelName, ERROR_MODEL);
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" not found; replacing with \"%s\".\n", modelName, ERROR_MODEL);
}
return pStudioHdr;
return studioHdr;
}
}
else
{
FindCachedMDL(cache, pStudioData, a4);
studiocache_t* const dataCache = pStudioData->GetStudioCache();
studiomodelcache_t* const modelCache = pStudioData->GetStudioCache();
if (dataCache)
if (modelCache)
{
if (dataCache == DC_INVALID_HANDLE)
if (modelCache == DC_INVALID_HANDLE)
{
pStudioHdr = GetErrorModel();
studioHdr = GetErrorModel();
if (!IsKnownBadModel(handle))
{
if (!pStudioHdr)
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" has bad studio data and \"%s\" couldn't be loaded.\n", szModelName, ERROR_MODEL);
if (!studioHdr)
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" has bad studio data and \"%s\" couldn't be loaded.\n", modelName, ERROR_MODEL);
else
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" has bad studio data; replacing with \"%s\".\n", szModelName, ERROR_MODEL);
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" has bad studio data; replacing with \"%s\".\n", modelName, ERROR_MODEL);
}
}
else
pStudioHdr = dataCache->GetStudioHdr();
studioHdr = modelCache->GetStudioHdr();
}
else
{
pStudioHdr = GetErrorModel();
studioHdr = GetErrorModel();
if (!IsKnownBadModel(handle))
{
if (!pStudioHdr)
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" has no studio data and \"%s\" couldn't be loaded.\n", szModelName, ERROR_MODEL);
if (!studioHdr)
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" has no studio data and \"%s\" couldn't be loaded.\n", modelName, ERROR_MODEL);
else
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" has no studio data; replacing with \"%s\".\n", szModelName, ERROR_MODEL);
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" has no studio data; replacing with \"%s\".\n", modelName, ERROR_MODEL);
}
}
}
assert(pStudioHdr);
return pStudioHdr;
assert(studioHdr);
return studioHdr;
}
studiocache_t* CMDLCache::GetStudioCache(const MDLHandle_t handle)
studiomodelcache_t* CMDLCache::GetModelCache(const MDLHandle_t handle)
{
if (handle == MDLHANDLE_INVALID)
return nullptr;
@ -226,8 +226,8 @@ studiocache_t* CMDLCache::GetStudioCache(const MDLHandle_t handle)
if (!studioData)
return nullptr;
studiocache_t* const studioCache = studioData->GetStudioCache();
return studioCache;
studiomodelcache_t* const modelCache = studioData->GetStudioCache();
return modelCache;
}
//-----------------------------------------------------------------------------
@ -238,15 +238,15 @@ studiocache_t* CMDLCache::GetStudioCache(const MDLHandle_t handle)
//-----------------------------------------------------------------------------
vcollide_t* CMDLCache::GetVCollide(CMDLCache* const cache, const MDLHandle_t handle)
{
studiocache_t* const studioCache = cache->GetStudioCache(handle);
studiomodelcache_t* const modelCache = cache->GetModelCache(handle);
if (!IS_VALID_DATACACHE_HANDLE(studioCache))
if (!IS_VALID_DATACACHE_HANDLE(modelCache))
{
Warning(eDLL_T::ENGINE, "Attempted to load vcollide on model \"%s\" with invalid studio data!\n", cache->GetModelName(handle));
return nullptr;
}
studiophysicsref_t* const physicsCache = studioCache->GetPhysicsCache();
studiophysicsref_t* const physicsCache = modelCache->GetPhysicsCache();
if (!physicsCache)
return nullptr;
@ -267,20 +267,20 @@ vcollide_t* CMDLCache::GetVCollide(CMDLCache* const cache, const MDLHandle_t han
//-----------------------------------------------------------------------------
void* CMDLCache::GetPhysicsGeometry(CMDLCache* const cache, const MDLHandle_t handle)
{
studiocache_t* const studioCache = cache->GetStudioCache(handle);
studiomodelcache_t* const modelCache = cache->GetModelCache(handle);
if (!IS_VALID_DATACACHE_HANDLE(studioCache))
if (!IS_VALID_DATACACHE_HANDLE(modelCache))
{
Warning(eDLL_T::ENGINE, "Attempted to load physics geometry on model \"%s\" with invalid studio data!\n", cache->GetModelName(handle));
return nullptr;
}
studiophysicsref_t* const physicsCache = studioCache->GetPhysicsCache();
studiophysicsref_t* const physicsRef = modelCache->GetPhysicsCache();
if (!physicsCache)
if (!physicsRef)
return nullptr;
CStudioPhysicsGeoms* const physicsGeoms = physicsCache->GetPhysicsGeoms();
CStudioPhysicsGeoms* const physicsGeoms = physicsRef->GetPhysicsGeoms();
if (!physicsGeoms)
return nullptr;
@ -296,10 +296,10 @@ void* CMDLCache::GetPhysicsGeometry(CMDLCache* const cache, const MDLHandle_t ha
//-----------------------------------------------------------------------------
studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* const cache, const MDLHandle_t handle)
{
const studiodata_t* pStudioData = nullptr; cache->GetStudioData(handle);
const studiocache_t* studioCache = cache->GetStudioCache(handle);
const studiodata_t* studioData = nullptr; cache->GetStudioData(handle);
const studiomodelcache_t* modelCache = cache->GetModelCache(handle);
if (!IS_VALID_DATACACHE_HANDLE(studioCache))
if (!IS_VALID_DATACACHE_HANDLE(modelCache))
{
if (!HasErrorModel())
{
@ -319,22 +319,22 @@ studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* const cache, const MDLHand
}
}
pStudioData = cache->GetStudioData(GetErrorModelHandle());
studioCache = pStudioData->GetStudioCache();
studioData = cache->GetStudioData(GetErrorModelHandle());
modelCache = studioData->GetStudioCache();
}
else
{
pStudioData = cache->GetStudioData(handle);
studioData = cache->GetStudioData(handle);
}
studiophysicsref_t* const physicsCache = studioCache->GetPhysicsCache();
studiophysicsref_t* const physicsRef = modelCache->GetPhysicsCache();
AcquireSRWLockExclusive(g_pMDLLock);
CMDLCache__CheckData(physicsCache, 1i64); // !!! DECLARED INLINE IN < S3 !!!
CMDLCache__CheckData(physicsRef, 1i64); // !!! DECLARED INLINE IN < S3 !!!
ReleaseSRWLockExclusive(g_pMDLLock);
if ((pStudioData->m_nFlags & STUDIODATA_FLAGS_STUDIOMESH_LOADED))
return pStudioData->GetHardwareDataRef()->GetHardwareData();
if ((studioData->flags & STUDIODATA_FLAGS_STUDIOMESH_LOADED))
return studioData->GetHardwareDataRef()->GetHardwareData();
return nullptr;
}
@ -383,7 +383,9 @@ void VMDLCache::Detour(const bool bAttach) const
DetourSetup(&CMDLCache__FindMDL, &CMDLCache::FindMDL, bAttach);
DetourSetup(&CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL, bAttach);
DetourSetup(&CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL, bAttach);
DetourSetup(&CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData, bAttach);
DetourSetup(&CMDLCache__GetVCollide, &CMDLCache::GetVCollide, bAttach);
DetourSetup(&CMDLCache__GetPhysicsGeometry, &CMDLCache::GetPhysicsGeometry, bAttach);
DetourSetup(&CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData, bAttach);
}

View File

@ -6,6 +6,7 @@
#include "datacache/idatacache.h"
#include "datacache/imdlcache.h"
#include "public/studio.h"
#include "public/vphysics/phyfile.h"
#include "public/vphysics/vcollide.h"
#include "public/rtech/ipakfile.h"
@ -96,7 +97,7 @@ private:
std::unordered_set<MDLHandle_t> m_BadMdlHandles;
// Don't spam on these handles when trying to get
// hardware data.
// cache data.
std::unordered_set<MDLHandle_t> m_SuppressedHandles;
};
@ -131,8 +132,8 @@ private:
struct studiophysicsref_t
{
inline CStudioVCollide* GetStudioVCollide() const { return m_pVCollide; }
inline CStudioPhysicsGeoms* GetPhysicsGeoms() const { return m_pPhysicsGeoms; }
inline CStudioVCollide* GetStudioVCollide() const { return vCollide; }
inline CStudioPhysicsGeoms* GetPhysicsGeoms() const { return physicsGeoms; }
int unk0;
int unk1;
@ -140,53 +141,65 @@ struct studiophysicsref_t
int unk3;
int unk4;
int unk5;
CStudioVCollide* m_pVCollide;
CStudioPhysicsGeoms* m_pPhysicsGeoms;
CStudioVCollide* vCollide;
CStudioPhysicsGeoms* physicsGeoms;
};
struct studiocache_t
struct studiomodelcache_t
{
inline studiohdr_t* GetStudioHdr() const { return m_pStudioHdr; }
inline studiophysicsref_t* GetPhysicsCache() const { return m_pPhysicsCache; }
inline studiohdr_t* GetStudioHdr() const { return studioHeader; }
inline studiophysicsref_t* GetPhysicsCache() const { return physicsCache; }
studiohdr_t* m_pStudioHdr;
studiophysicsref_t* m_pPhysicsCache;
const char* m_szPropName;
uint8_t m_pUnknown[98];
studiohdr_t* studioHeader;
studiophysicsref_t* physicsCache;
const char* modelName;
char gap_18[8];
phyheader_t* physicsHeader;
void* unk_28;
void* staticPropData;
void* animRigs;
int numAnimRigs;
int unk_44;
int streamedDataSize;
char gap_4C[8];
int numAnimSeqs;
void* m_pAnimSeqs;
char gap_60[24];
};
struct studioanimcache_t
{
inline studiohdr_t* GetStudioHdr() const { return m_pStudioHdr; }
inline studiohdr_t* GetStudioHdr() const { return studioHdr; }
studiohdr_t* m_pStudioHdr;
const char* m_pszRigName;
studiohdr_t* studioHdr;
const char* rigName;
int unk0;
int m_nSequenceCount;
void** m_pAnimSequences;
// TODO reverse the rest
int numSequences;
PakPage_t sequences;
int unk1;
int unk2;
};
// only models with type "mod_studio" have this data
struct studiodata_t
{
inline studiocache_t* GetStudioCache() const { return m_pStudioCache; }
inline studioanimcache_t* GetAnimCache() const { return m_pAnimCache; }
inline CStudioHWDataRef* GetHardwareDataRef() const { return m_pHardwareRef; }
inline studiomodelcache_t* GetStudioCache() const { return modelCache; }
inline studioanimcache_t* GetAnimCache() const { return animCache; }
inline CStudioHWDataRef* GetHardwareDataRef() const { return hardwareRef; }
studiocache_t* m_pStudioCache;
studioanimcache_t* m_pAnimCache; // !TODO: reverse struct.
unsigned short m_nRefCount;
unsigned short m_nFlags;
MDLHandle_t m_Handle;
studiomodelcache_t* modelCache;
studioanimcache_t* animCache;
unsigned short refCount;
unsigned short flags;
MDLHandle_t modelHandle;
void* Unk3; // ptr to flags and model string.
CStudioHWDataRef* m_pHardwareRef;
void* m_pMaterialTable; // contains a large table of CMaterialGlue objects.
CStudioHWDataRef* hardwareRef;
void* materialTable; // contains a large table of CMaterialGlue objects.
int Unk5;
char pad[72];
CThreadFastMutex m_Mutex;
bool m_bSearchingModelName;
PakHandle_t m_PakHandle;
CThreadFastMutex mutex;
bool processing;
PakHandle_t pakHandle;
};
extern CStudioFallbackHandler g_StudioMdlFallbackHandler;
@ -198,7 +211,7 @@ public:
static void FindCachedMDL(CMDLCache* const cache, studiodata_t* const pStudioData, void* a3);
static studiohdr_t* FindUncachedMDL(CMDLCache* const cache, const MDLHandle_t handle, studiodata_t* const pStudioData, void* a4);
studiocache_t* GetStudioCache(const MDLHandle_t handle);
studiomodelcache_t* GetModelCache(const MDLHandle_t handle);
static vcollide_t* GetVCollide(CMDLCache* const cache, const MDLHandle_t handle);
static void* GetPhysicsGeometry(CMDLCache* const cache, const MDLHandle_t handle);
@ -235,7 +248,7 @@ public:
studiodata_t* const studioData = m_MDLDict.Element(handle);
LeaveCriticalSection(&m_MDLMutex);
return &studioData->m_pMaterialTable;
return &studioData->materialTable;
}
private:
@ -248,10 +261,10 @@ inline studiohdr_t*(*CMDLCache__FindMDL)(CMDLCache* const pCache, const MDLHandl
inline void(*CMDLCache__FindCachedMDL)(CMDLCache* const pCache, studiodata_t* const pStudioData, void* a3);
inline studiohdr_t*(*CMDLCache__FindUncachedMDL)(CMDLCache* const pCache, MDLHandle_t handle, studiodata_t* const pStudioData, void* a4);
inline studiohwdata_t* (*CMDLCache__GetHardwareData)(CMDLCache* const pCache, const MDLHandle_t handle);
inline vcollide_t*(*CMDLCache__GetVCollide)(CMDLCache* const pCache, const MDLHandle_t handle);
inline void* (*CMDLCache__GetPhysicsGeometry)(CMDLCache* const pCache, const MDLHandle_t handle);
inline studiohwdata_t* (*CMDLCache__GetHardwareData)(CMDLCache* const pCache, const MDLHandle_t handle);
inline bool(*CMDLCache__CheckData)(void* const ref, const int64_t type); // Probably incorrect name.
inline CMDLCache* g_pMDLCache = nullptr;
@ -265,9 +278,9 @@ class VMDLCache : public IDetour
LogFunAdr("CMDLCache::FindMDL", CMDLCache__FindMDL);
LogFunAdr("CMDLCache::FindCachedMDL", CMDLCache__FindCachedMDL);
LogFunAdr("CMDLCache::FindUncachedMDL", CMDLCache__FindUncachedMDL);
LogFunAdr("CMDLCache::GetHardwareData", CMDLCache__GetHardwareData);
LogFunAdr("CMDLCache::GetVCollide", CMDLCache__GetVCollide);
LogFunAdr("CMDLCache::GetPhysicsGeometry", CMDLCache__GetPhysicsGeometry);
LogFunAdr("CMDLCache::GetHardwareData", CMDLCache__GetHardwareData);
LogFunAdr("CMDLCache::CheckData", CMDLCache__CheckData);
LogVarAdr("g_MDLCache", g_pMDLCache);

View File

@ -0,0 +1,22 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef PHYFILE_H
#define PHYFILE_H
#pragma once
typedef struct phyheader_s
{
int size;
int id;
short numsolids;
short align;
int checksum; // checksum of source .rmdl file
int keyvalueindex;
} phyheader_t;
#endif // PHYFILE_H

View File

@ -10,6 +10,7 @@ add_sources( SOURCE_GROUP "Private"
)
add_sources( SOURCE_GROUP "Public"
"${ENGINE_SOURCE_DIR}/public/vphysics/phyfile.h"
"${ENGINE_SOURCE_DIR}/public/vphysics/vcollide.h"
"${ENGINE_SOURCE_DIR}/public/trace.h"
"${ENGINE_SOURCE_DIR}/public/gametrace.h"