From 24dae59cb86c7298e168951d63990f830039e853 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Thu, 5 May 2022 02:54:17 +0200 Subject: [PATCH] Improve CMDLCache::FindMDL --- r5dev/datacache/mdlcache.cpp | 42 +++++++++++++++-------------------- r5dev/datacache/mdlcache.h | 24 ++++++++++++++------ r5dev/public/include/studio.h | 7 ++++++ 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/r5dev/datacache/mdlcache.cpp b/r5dev/datacache/mdlcache.cpp index d441c9d4..0b7867c8 100644 --- a/r5dev/datacache/mdlcache.cpp +++ b/r5dev/datacache/mdlcache.cpp @@ -23,26 +23,20 @@ // *a3 - // Output : a pointer to the studiohdr_t object //----------------------------------------------------------------------------- -studiohdr_t* CMDLCache::FindMDL(CMDLCache* pMDLCache, MDLHandle_t handle, void* a3) +studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3) { - __int64 v4; // rbp - __int64 v6; // rbx - __int64* v7; // rax - studiohdr_t* result; // rax + studiodata_t* pStudioData; // rbx + void* pMDLCache; // rax + studiohdr_t* result; // rax - v4 = handle; EnterCriticalSection(reinterpret_cast(&*m_MDLMutex)); - - // Example usage. - // auto mdlDict = CUtlDict<__int64, MDLHandle_t>(m_MDLDict.Deref().GetPtr()); // __int64 is studiodata_t* - // v6 = mdlDict.Find(v4); - - v6 = *(_QWORD*)(m_MDLDict.Deref().GetPtr() + 24 * v4 + 16); + auto mdlDict = CUtlDict(m_MDLDict.Deref().GetPtr()); + pStudioData = mdlDict.Find(static_cast(handle)); LeaveCriticalSection(reinterpret_cast(&*m_MDLMutex)); if (!g_pMDLFallback->m_hErrorMDL || !g_pMDLFallback->m_hEmptyMDL) { - studiohdr_t* pStudioHDR = **(studiohdr_t***)v6; + studiohdr_t* pStudioHDR = **reinterpret_cast(pStudioData); string svStudio = ConvertToUnixPath(string(pStudioHDR->name)); if (strcmp(svStudio.c_str(), ERROR_MODEL) == 0) @@ -57,7 +51,7 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* pMDLCache, MDLHandle_t handle, void* } } - if (!v6) + if (!pStudioData) { if (!g_pMDLFallback->m_hErrorMDL) Error(eDLL_T::ENGINE, "Model with handle \"%hu\" not found and \"%s\" couldn't be loaded.\n", handle, ERROR_MODEL); @@ -65,28 +59,28 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* pMDLCache, MDLHandle_t handle, void* return g_pMDLFallback->m_pErrorHDR; } - if ((*(_WORD*)(v6 + 18) & 0x600) != 0) + if ((pStudioData->m_nFlags & STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE | STUDIOHDR_FLAGS_OBSOLETE) != 0) { - v7 = *(__int64**)v6; - if (*(_QWORD*)v6) + pMDLCache = *reinterpret_cast(pStudioData); + if (pStudioData->m_MDLCache) { if (a3) { - FindCachedMDL(pMDLCache, (void*)v6, a3); - v7 = *(__int64**)v6; + FindCachedMDL(cache, pStudioData, a3); + pMDLCache = *reinterpret_cast(pStudioData); } LABEL_6: - result = (studiohdr_t*)*v7; + result = *reinterpret_cast(pMDLCache); if (result) return result; - return FindUncachedMDL(pMDLCache, v4, (void*)v6, a3); + return FindUncachedMDL(cache, handle, pStudioData, a3); } - v7 = *(__int64**)(v6 + 8); - if (v7) + pMDLCache = pStudioData->Unk0; + if (pMDLCache) goto LABEL_6; } - return FindUncachedMDL(pMDLCache, v4, (void*)v6, a3); + return FindUncachedMDL(cache, handle, pStudioData, a3); } //----------------------------------------------------------------------------- diff --git a/r5dev/datacache/mdlcache.h b/r5dev/datacache/mdlcache.h index abfbdf27..f09a6ddb 100644 --- a/r5dev/datacache/mdlcache.h +++ b/r5dev/datacache/mdlcache.h @@ -3,13 +3,6 @@ #include "public/include/studio.h" #include "datacache/imdlcache.h" -class CStudioHWDataRef -{ -public: - bool IsDataRef(void) const { return true; } - uint8_t m_pUnknown[0x90]{}; -}; - struct RStaticProp_t { studiohdr_t* m_pStudioHDR{}; @@ -34,6 +27,23 @@ struct CMDLFallBack m_hEmptyMDL = NULL; } }; + +// only models with type "mod_studio" have this data +struct studiodata_t +{ + void* m_MDLCache; + void* Unk0; + unsigned short m_nRefCount; + unsigned short m_nFlags; + MDLHandle_t m_Handle; + void* Unk3; // ptr to flags and model string. + CStudioHWDataRef* m_HardwareData; + void* Unk4; // contains material stuff (CMaterialGlue). + bool Unk5; + // !TODO: the rest.. + // they where empty in the current debug session (size 0xA0 in S3) +}; + inline CMDLFallBack* g_pMDLFallback = new CMDLFallBack(); inline vector g_BadMDLHandles; diff --git a/r5dev/public/include/studio.h b/r5dev/public/include/studio.h index aff7b578..6bbe0d5d 100644 --- a/r5dev/public/include/studio.h +++ b/r5dev/public/include/studio.h @@ -181,4 +181,11 @@ public: void* m_pMdlCacheVTable; }; +class CStudioHWDataRef +{ +public: + bool IsDataRef(void) const { return true; } + uint8_t m_pUnknown[0x90]{}; +}; + #endif // STUDIO_H