diff --git a/r5dev/datacache/mdlcache.cpp b/r5dev/datacache/mdlcache.cpp index 4e87f0fd..9f1d412f 100644 --- a/r5dev/datacache/mdlcache.cpp +++ b/r5dev/datacache/mdlcache.cpp @@ -77,7 +77,7 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3) return FindUncachedMDL(cache, handle, pStudioData, a3); } - pMDLCache = pStudioData->Unk0; + pMDLCache = pStudioData->m_pAnimData; if (pMDLCache) goto LABEL_6; } @@ -90,21 +90,21 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3) // *a2 - // *a3 - //----------------------------------------------------------------------------- -void CMDLCache::FindCachedMDL(CMDLCache* cache, void* a2, void* a3) +void CMDLCache::FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void* a3) { __int64 v6; // rax if (a3) { - CThreadFastMutex::WaitForLock((CThreadFastMutex*)a2 + 128); - *(_QWORD*)((int64_t)a3 + 2176) = *(_QWORD*)((int64_t)a2 + 88); - v6 = *(_QWORD*)((int64_t)a2 + 88); + pStudioData->m_Mutex.WaitForLock(); + *(_QWORD*)((int64_t)a3 + 0x880) = *(_QWORD*)&pStudioData->pad[0x24]; + v6 = *(_QWORD*)&pStudioData->pad[0x24]; if (v6) - *(_QWORD*)(v6 + 2168) = (int64_t)a3; - *(_QWORD*)((int64_t)a2 + 88) = (int64_t)a3; - *(_QWORD*)((int64_t)a3 + 2160) = (int64_t)cache; - *(_WORD*)((int64_t)a3 + 2184) = *(_WORD*)((int64_t)a2 + 20); - CThreadFastMutex::ReleaseWaiter((CThreadFastMutex*)a2 + 128); + *(_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; + pStudioData->m_Mutex.ReleaseWaiter(); } } @@ -116,7 +116,7 @@ void CMDLCache::FindCachedMDL(CMDLCache* cache, void* a2, void* a3) // *a4 - // Output : a pointer to the studiohdr_t object //----------------------------------------------------------------------------- -studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, void* a3, void* a4) +studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4) { const char* v8; // rdi __int64 v9; // rax @@ -131,7 +131,7 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, vo bool bOldModel {}; bool bInvalidHandle{}; - CThreadFastMutex::WaitForLock((CThreadFastMutex*)a3 + 0x80); + pStudioData->m_Mutex.WaitForLock(); EnterCriticalSection(reinterpret_cast(&*m_MDLMutex)); void* modelCache = cache->m_pModelCacheSection; v8 = (const char*)(*(_QWORD*)((int64)modelCache + 24 * static_cast(handle) + 8)); @@ -157,11 +157,11 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, vo } g_pRTech->StringToGuid(v8); - v16 = *(_QWORD*)a3 == 0i64; - *(_BYTE*)((int64)a3 + 152) = 0; + v16 = *(_QWORD*)pStudioData == 0i64; + *(_BYTE*)((int64)pStudioData + 152) = 0; if (v16) { - v18 = *(studiohdr_t***)((int64)a3 + 8); + v18 = *(studiohdr_t***)((int64)pStudioData + 8); if (v18) { v17 = *v18; @@ -191,18 +191,18 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, vo } else { - v_CMDLCache__FindCachedMDL(cache, a3, a4); - if ((__int64)*(studiohdr_t**)a3) + v_CMDLCache__FindCachedMDL(cache, pStudioData, a4); + if ((__int64)*(studiohdr_t**)pStudioData) { - if ((__int64)*(studiohdr_t**)a3 == 0xDEADFEEDDEADFEED) + if ((__int64)*(studiohdr_t**)pStudioData == 0xDEADFEEDDEADFEED) v17 = g_pMDLFallback->m_pErrorHDR; else - v17 = **(studiohdr_t***)a3; + v17 = **(studiohdr_t***)pStudioData; } else v17 = g_pMDLFallback->m_pErrorHDR; } - CThreadFastMutex::ReleaseWaiter((CThreadFastMutex*)a3 + 128); + pStudioData->m_Mutex.ReleaseWaiter(); return v17; } diff --git a/r5dev/datacache/mdlcache.h b/r5dev/datacache/mdlcache.h index cc787ba6..670448de 100644 --- a/r5dev/datacache/mdlcache.h +++ b/r5dev/datacache/mdlcache.h @@ -2,6 +2,7 @@ #define MDLCACHE_H #include "public/include/studio.h" #include "datacache/imdlcache.h" +#include "tier0/threadtools.h" struct RStaticProp_t { @@ -32,16 +33,21 @@ struct CMDLFallBack struct studiodata_t { void* m_MDLCache; - void* Unk0; + void* m_pAnimData; // !TODO: reverse struct. unsigned short m_nRefCount; unsigned short m_nFlags; MDLHandle_t m_Handle; +#ifndef GAMEDLL_S3 + void* Unk1; // TODO: unverified! + void* Unk2; // TODO: unverified! +#endif // !GAMEDLL_S3 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) + int Unk5; + char pad[72]; + CThreadFastMutex m_Mutex; + int m_nGuidLock; // always -1, set to 1 and 0 in CMDLCache::FindUncachedMDL. }; inline CMDLFallBack* g_pMDLFallback = new CMDLFallBack(); @@ -51,8 +57,8 @@ class CMDLCache { public: static studiohdr_t* FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3); - static void FindCachedMDL(CMDLCache* cache, void* a2, void* a3); - static studiohdr_t* FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, void* a3, void* a4); + 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 CStudioHWDataRef* GetStudioHardwareRef(CMDLCache* cache, MDLHandle_t handle); static void* GetStudioMaterialGlue(CMDLCache* cache, MDLHandle_t handle); diff --git a/r5dev/tier0/threadtools.h b/r5dev/tier0/threadtools.h index 6ead233a..ee1ff9a8 100644 --- a/r5dev/tier0/threadtools.h +++ b/r5dev/tier0/threadtools.h @@ -1,25 +1,35 @@ #ifndef THREADTOOLS_H #define THREADTOOLS_H //============================================================================= +class CThreadFastMutex; inline CMemory p_MutexInternal_WaitForLock; -inline auto v_MutexInternal_WaitForLock = p_MutexInternal_WaitForLock.RCast(); +inline auto v_MutexInternal_WaitForLock = p_MutexInternal_WaitForLock.RCast(); inline CMemory p_MutexInternal_ReleaseWaiter; -inline auto v_MutexInternal_ReleaseWaiter = p_MutexInternal_ReleaseWaiter.RCast(); +inline auto v_MutexInternal_ReleaseWaiter = p_MutexInternal_ReleaseWaiter.RCast(); /////////////////////////////////////////////////////////////////////////////// class CThreadFastMutex { public: - static int WaitForLock(CThreadFastMutex* mutex) - { - return v_MutexInternal_WaitForLock(mutex); + int WaitForLock(void) { + return v_MutexInternal_WaitForLock(this); } - static int ReleaseWaiter(CThreadFastMutex* mutex) - { - return v_MutexInternal_ReleaseWaiter(mutex); + int ReleaseWaiter(void) { + return v_MutexInternal_ReleaseWaiter(this); } + + uint32 GetOwnerId(void) const { return m_ownerID; } + int GetDepth(void) const { return m_depth; } + int GetAddend(void) const { return m_lAddend; } + HANDLE GetSemaphore(void) const { return m_hSemaphore; } + +private: + volatile uint32_t m_ownerID; + int m_depth; + volatile int m_lAddend; + HANDLE m_hSemaphore; }; /////////////////////////////////////////////////////////////////////////////// @@ -36,8 +46,8 @@ class HThreadTools : public IDetour p_MutexInternal_WaitForLock = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\x48\x8B\xD9\xFF\x15\x00\x00\x00\x00"), "xxxx?xxxx?xxxxxxxxxx????"); p_MutexInternal_ReleaseWaiter = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x20\x8B\x41\x04\x48\x8B\xD9\x83\xE8\x01"), "xxxxxxxxxxxxxxx"); - v_MutexInternal_WaitForLock = p_MutexInternal_WaitForLock.RCast(); /*48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B D9 FF 15 ?? ?? ?? ??*/ - v_MutexInternal_ReleaseWaiter = p_MutexInternal_ReleaseWaiter.RCast(); /*40 53 48 83 EC 20 8B 41 04 48 8B D9 83 E8 01*/ + v_MutexInternal_WaitForLock = p_MutexInternal_WaitForLock.RCast(); /*48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B D9 FF 15 ?? ?? ?? ??*/ + v_MutexInternal_ReleaseWaiter = p_MutexInternal_ReleaseWaiter.RCast(); /*40 53 48 83 EC 20 8B 41 04 48 8B D9 83 E8 01*/ } virtual void GetVar(void) const { } virtual void GetCon(void) const { }