2022-04-29 05:30:06 +02:00
|
|
|
//=====================================================================================//
|
|
|
|
//
|
|
|
|
// model loading and caching
|
|
|
|
//
|
|
|
|
// $NoKeywords: $
|
|
|
|
//=====================================================================================//
|
|
|
|
|
|
|
|
#include "core/stdafx.h"
|
2022-04-30 03:30:16 +02:00
|
|
|
#include "tier0/threadtools.h"
|
|
|
|
#include "tier1/cvar.h"
|
2022-04-29 05:30:06 +02:00
|
|
|
#include "datacache/mdlcache.h"
|
|
|
|
#include "datacache/imdlcache.h"
|
2022-05-06 00:51:49 +02:00
|
|
|
#include "datacache/idatacache.h"
|
2022-04-29 05:30:06 +02:00
|
|
|
#include "engine/sys_utils.h"
|
|
|
|
#include "rtech/rtech_utils.h"
|
|
|
|
#include "public/include/studio.h"
|
2022-05-01 23:03:20 +02:00
|
|
|
#include "tier1/utldict.h"
|
2022-04-29 05:30:06 +02:00
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: finds an MDL
|
|
|
|
// Input : *this -
|
|
|
|
// handle -
|
|
|
|
// *a3 -
|
|
|
|
// Output : a pointer to the studiohdr_t object
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-05-05 02:54:17 +02:00
|
|
|
studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2022-05-05 02:54:17 +02:00
|
|
|
studiodata_t* pStudioData; // rbx
|
|
|
|
void* pMDLCache; // rax
|
2022-05-05 14:53:48 +02:00
|
|
|
studiohdr_t* pStudioHdr; // rax
|
2022-04-29 05:30:06 +02:00
|
|
|
|
|
|
|
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
2022-05-05 02:54:17 +02:00
|
|
|
auto mdlDict = CUtlDict<studiodata_t*, MDLHandle_t>(m_MDLDict.Deref().GetPtr());
|
|
|
|
pStudioData = mdlDict.Find(static_cast<int64>(handle));
|
2022-04-29 05:30:06 +02:00
|
|
|
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
|
|
|
|
|
|
|
if (!g_pMDLFallback->m_hErrorMDL || !g_pMDLFallback->m_hEmptyMDL)
|
|
|
|
{
|
2022-05-05 02:54:17 +02:00
|
|
|
studiohdr_t* pStudioHDR = **reinterpret_cast<studiohdr_t***>(pStudioData);
|
2022-04-29 05:30:06 +02:00
|
|
|
string svStudio = ConvertToUnixPath(string(pStudioHDR->name));
|
|
|
|
|
|
|
|
if (strcmp(svStudio.c_str(), ERROR_MODEL) == 0)
|
|
|
|
{
|
|
|
|
g_pMDLFallback->m_pErrorHDR = pStudioHDR;
|
|
|
|
g_pMDLFallback->m_hErrorMDL = handle;
|
|
|
|
}
|
|
|
|
if (strcmp(svStudio.c_str(), EMPTY_MODEL) == 0)
|
|
|
|
{
|
|
|
|
g_pMDLFallback->m_pEmptyHDR = pStudioHDR;
|
|
|
|
g_pMDLFallback->m_hEmptyMDL = handle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-05 02:54:17 +02:00
|
|
|
if (!pStudioData)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
|
|
|
return g_pMDLFallback->m_pErrorHDR;
|
|
|
|
}
|
|
|
|
|
2022-05-05 14:53:48 +02:00
|
|
|
int nFlags = STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE | STUDIOHDR_FLAGS_OBSOLETE;
|
|
|
|
if ((pStudioData->m_nFlags & nFlags))
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2022-05-05 02:54:17 +02:00
|
|
|
pMDLCache = *reinterpret_cast<void**>(pStudioData);
|
|
|
|
if (pStudioData->m_MDLCache)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
|
|
|
if (a3)
|
|
|
|
{
|
2022-05-05 02:54:17 +02:00
|
|
|
FindCachedMDL(cache, pStudioData, a3);
|
|
|
|
pMDLCache = *reinterpret_cast<void**>(pStudioData);
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
LABEL_6:
|
2022-05-05 14:53:48 +02:00
|
|
|
pStudioHdr = *reinterpret_cast<studiohdr_t**>(pMDLCache);
|
|
|
|
if (pStudioHdr)
|
|
|
|
return pStudioHdr;
|
2022-04-29 05:30:06 +02:00
|
|
|
|
2022-05-05 02:54:17 +02:00
|
|
|
return FindUncachedMDL(cache, handle, pStudioData, a3);
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
2022-05-05 17:53:05 +02:00
|
|
|
pMDLCache = pStudioData->m_pAnimData;
|
2022-05-05 02:54:17 +02:00
|
|
|
if (pMDLCache)
|
2022-04-29 05:30:06 +02:00
|
|
|
goto LABEL_6;
|
|
|
|
}
|
2022-05-05 02:54:17 +02:00
|
|
|
return FindUncachedMDL(cache, handle, pStudioData, a3);
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: finds an MDL cached
|
|
|
|
// Input : *this -
|
|
|
|
// *a2 -
|
|
|
|
// *a3 -
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-05-05 17:53:05 +02:00
|
|
|
void CMDLCache::FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void* a3)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2022-04-30 03:30:16 +02:00
|
|
|
__int64 v6; // rax
|
|
|
|
|
|
|
|
if (a3)
|
|
|
|
{
|
2022-05-05 17:53:05 +02:00
|
|
|
pStudioData->m_Mutex.WaitForLock();
|
|
|
|
*(_QWORD*)((int64_t)a3 + 0x880) = *(_QWORD*)&pStudioData->pad[0x24];
|
|
|
|
v6 = *(_QWORD*)&pStudioData->pad[0x24];
|
2022-04-30 03:30:16 +02:00
|
|
|
if (v6)
|
2022-05-05 17:53:05 +02:00
|
|
|
*(_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();
|
2022-04-30 03:30:16 +02:00
|
|
|
}
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: finds an MDL uncached
|
|
|
|
// Input : *this -
|
|
|
|
// handle -
|
|
|
|
// *a3 -
|
2022-04-30 03:30:16 +02:00
|
|
|
// *a4 -
|
2022-04-29 05:30:06 +02:00
|
|
|
// Output : a pointer to the studiohdr_t object
|
|
|
|
//-----------------------------------------------------------------------------
|
2022-05-05 17:53:05 +02:00
|
|
|
studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2022-05-05 20:36:13 +02:00
|
|
|
const char* szModelName; // rdi
|
|
|
|
int64_t nExtensionOffset; // rax
|
|
|
|
studiohdr_t* pStudioHdr; // rdi
|
|
|
|
studiohdr_t** ppStudioHdr; // rax
|
|
|
|
void* pModelCache;
|
|
|
|
bool bOldModel{};
|
|
|
|
bool bInvalidHandle{};
|
2022-04-29 05:30:06 +02:00
|
|
|
|
2022-05-05 17:53:05 +02:00
|
|
|
pStudioData->m_Mutex.WaitForLock();
|
2022-04-29 05:30:06 +02:00
|
|
|
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
2022-05-05 20:36:13 +02:00
|
|
|
pModelCache = cache->m_pModelCacheSection;
|
|
|
|
szModelName = (const char*)(*(_QWORD*)((int64)pModelCache + 24 * static_cast<int64>(handle) + 8));
|
2022-04-29 05:30:06 +02:00
|
|
|
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
2022-05-05 20:36:13 +02:00
|
|
|
if (IsBadReadPtrV2((void*)szModelName))
|
2022-05-01 05:38:51 +02:00
|
|
|
{
|
|
|
|
bInvalidHandle = true;
|
|
|
|
goto LABEL_ERROR;
|
|
|
|
}
|
|
|
|
|
2022-05-05 20:36:13 +02:00
|
|
|
nExtensionOffset = -1i64;
|
2022-04-29 05:30:06 +02:00
|
|
|
do
|
2022-05-05 20:36:13 +02:00
|
|
|
++nExtensionOffset;
|
|
|
|
while (szModelName[nExtensionOffset]);
|
2022-04-29 05:30:06 +02:00
|
|
|
|
2022-05-05 20:36:13 +02:00
|
|
|
if (nExtensionOffset < 5 ||
|
|
|
|
(_stricmp(&szModelName[nExtensionOffset - 5], ".rmdl") != 0) &&
|
|
|
|
(_stricmp(&szModelName[nExtensionOffset - 5], ".rrig") != 0) &&
|
|
|
|
(_stricmp(&szModelName[nExtensionOffset - 5], ".rpak") != 0))
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2022-04-30 05:06:59 +02:00
|
|
|
bOldModel = true;
|
2022-04-29 05:30:06 +02:00
|
|
|
goto LABEL_ERROR;
|
|
|
|
}
|
|
|
|
|
2022-05-05 20:36:13 +02:00
|
|
|
LOBYTE(pStudioData->m_nGuidLock) = 1;
|
|
|
|
g_pRTech->StringToGuid(szModelName);
|
|
|
|
LOBYTE(pStudioData->m_nGuidLock) = 0;
|
|
|
|
|
|
|
|
if (!pStudioData->m_MDLCache)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2022-05-05 20:36:13 +02:00
|
|
|
ppStudioHdr = (studiohdr_t**)pStudioData->m_pAnimData;
|
|
|
|
if (ppStudioHdr)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2022-05-05 20:36:13 +02:00
|
|
|
pStudioHdr = *ppStudioHdr;
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-04-29 22:46:37 +02:00
|
|
|
LABEL_ERROR:
|
2022-05-04 02:25:27 +02:00
|
|
|
if (std::find(g_BadMDLHandles.begin(), g_BadMDLHandles.end(), handle) == g_BadMDLHandles.end())
|
2022-04-29 22:46:37 +02:00
|
|
|
{
|
2022-05-01 05:38:51 +02:00
|
|
|
if (bInvalidHandle)
|
|
|
|
Error(eDLL_T::ENGINE, "Model with handle \"hu\" not found; replacing with \"%s\".\n", handle, ERROR_MODEL);
|
|
|
|
else if (bOldModel)
|
2022-05-05 20:36:13 +02:00
|
|
|
Error(eDLL_T::ENGINE, "Attempted to load old model \"%s\"; replace with rmdl.\n", szModelName);
|
2022-05-01 05:38:51 +02:00
|
|
|
else
|
2022-04-30 05:06:59 +02:00
|
|
|
{
|
|
|
|
if (g_pMDLFallback->m_hErrorMDL)
|
2022-05-05 20:36:13 +02:00
|
|
|
Error(eDLL_T::ENGINE, "Model \"%s\" not found; replacing with \"%s\".\n", szModelName, ERROR_MODEL);
|
2022-04-30 05:06:59 +02:00
|
|
|
else
|
2022-05-05 20:36:13 +02:00
|
|
|
Error(eDLL_T::ENGINE, "Model \"%s\" not found and \"%s\" couldn't be loaded.\n", szModelName, ERROR_MODEL);
|
2022-04-30 05:06:59 +02:00
|
|
|
}
|
2022-04-30 03:30:16 +02:00
|
|
|
|
2022-05-04 02:25:27 +02:00
|
|
|
g_BadMDLHandles.push_back(handle);
|
2022-04-29 22:46:37 +02:00
|
|
|
}
|
2022-05-05 20:36:13 +02:00
|
|
|
pStudioHdr = g_pMDLFallback->m_pErrorHDR;
|
2022-04-30 03:30:16 +02:00
|
|
|
old_gather_props->SetValue(true); // mdl/error.rmdl fallback is not supported (yet) in the new GatherProps solution!
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-05-05 17:53:05 +02:00
|
|
|
v_CMDLCache__FindCachedMDL(cache, pStudioData, a4);
|
|
|
|
if ((__int64)*(studiohdr_t**)pStudioData)
|
2022-05-04 12:44:01 +02:00
|
|
|
{
|
2022-05-05 17:53:05 +02:00
|
|
|
if ((__int64)*(studiohdr_t**)pStudioData == 0xDEADFEEDDEADFEED)
|
2022-05-05 20:36:13 +02:00
|
|
|
pStudioHdr = g_pMDLFallback->m_pErrorHDR;
|
2022-05-04 12:44:01 +02:00
|
|
|
else
|
2022-05-05 20:36:13 +02:00
|
|
|
pStudioHdr = **(studiohdr_t***)pStudioData;
|
2022-05-04 12:44:01 +02:00
|
|
|
}
|
|
|
|
else
|
2022-05-05 20:36:13 +02:00
|
|
|
pStudioHdr = g_pMDLFallback->m_pErrorHDR;
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
2022-05-05 17:53:05 +02:00
|
|
|
pStudioData->m_Mutex.ReleaseWaiter();
|
2022-05-05 20:36:13 +02:00
|
|
|
return pStudioHdr;
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
|
2022-04-29 18:25:54 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: gets the studiohdr from cache pool by handle
|
|
|
|
// Input : *this -
|
|
|
|
// handle -
|
|
|
|
// Output : a pointer to the studiohdr_t object
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* pMDLCache, MDLHandle_t handle)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
|
|
|
__int64 v2; // rbx
|
|
|
|
__int64 v3; // rbx
|
|
|
|
__int64 v4; // rdx
|
2022-04-29 21:05:26 +02:00
|
|
|
studiohdr_t* result = nullptr; // rax
|
2022-04-29 05:30:06 +02:00
|
|
|
|
|
|
|
if (!handle)
|
|
|
|
{
|
2022-04-29 21:05:26 +02:00
|
|
|
LABEL_ERROR:
|
2022-04-29 05:30:06 +02:00
|
|
|
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);
|
|
|
|
|
|
|
|
return g_pMDLFallback->m_pErrorHDR;
|
|
|
|
}
|
|
|
|
|
|
|
|
v2 = handle;
|
|
|
|
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
|
|
|
v3 = *(_QWORD*)(m_MDLDict.Deref().GetPtr() + 24 * v2 + 16);
|
|
|
|
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
2022-04-29 22:11:35 +02:00
|
|
|
if (*(_QWORD*)(v3))
|
2022-04-29 21:05:26 +02:00
|
|
|
{
|
2022-04-29 22:11:35 +02:00
|
|
|
v4 = *(_QWORD*)(*(_QWORD*)(*(_QWORD*)v3 + 8i64) + 24i64);
|
|
|
|
if (v4)
|
|
|
|
result = (studiohdr_t*)(v4 + 16);
|
2022-04-29 21:05:26 +02:00
|
|
|
}
|
2022-04-29 05:30:06 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-04-29 18:25:54 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-05-06 00:51:49 +02:00
|
|
|
// Purpose: gets the studio hardware data from cache pool by handle
|
2022-04-29 18:25:54 +02:00
|
|
|
// Input : *this -
|
|
|
|
// handle -
|
2022-05-06 00:51:49 +02:00
|
|
|
// Output : a pointer to the studiohwdata_t object
|
2022-04-29 18:25:54 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
2022-05-06 00:51:49 +02:00
|
|
|
studiohwdata_t* CMDLCache::GetStudioHardware(CMDLCache* cache, MDLHandle_t handle)
|
2022-04-29 18:25:54 +02:00
|
|
|
{
|
2022-05-06 00:51:49 +02:00
|
|
|
studiodata_t* pStudioData; // rdi
|
|
|
|
void* pAnimData; // rbx
|
|
|
|
studiohwdata_t* result; // rax
|
2022-04-29 18:25:54 +02:00
|
|
|
|
|
|
|
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
2022-05-06 00:51:49 +02:00
|
|
|
pStudioData = *(studiodata_t**)(m_MDLDict.Deref().GetPtr() + 24 * static_cast<int64_t>(handle) + 16);
|
2022-04-29 18:25:54 +02:00
|
|
|
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
|
|
|
|
2022-05-06 00:51:49 +02:00
|
|
|
if (!pStudioData)
|
2022-04-29 18:25:54 +02:00
|
|
|
{
|
2022-04-29 22:11:35 +02:00
|
|
|
if (!g_pMDLFallback->m_hErrorMDL)
|
|
|
|
{
|
|
|
|
Error(eDLL_T::ENGINE, "Studio hardware with handle \"%hu\" not found and \"%s\" couldn't be loaded.\n", handle, ERROR_MODEL);
|
|
|
|
return nullptr;
|
|
|
|
}
|
2022-05-06 00:51:49 +02:00
|
|
|
pStudioData = *(studiodata_t**)(m_MDLDict.Deref().GetPtr() + 24i64 * g_pMDLFallback->m_hErrorMDL + 16);
|
2022-04-29 18:25:54 +02:00
|
|
|
}
|
|
|
|
|
2022-05-06 00:51:49 +02:00
|
|
|
if (pStudioData->m_MDLCache)
|
2022-04-29 18:25:54 +02:00
|
|
|
{
|
2022-05-06 00:51:49 +02:00
|
|
|
if (reinterpret_cast<int64_t>(pStudioData->m_MDLCache) == 0xDEADFEEDDEADFEED)
|
2022-05-04 12:44:01 +02:00
|
|
|
return nullptr;
|
|
|
|
|
2022-05-06 00:51:49 +02:00
|
|
|
pAnimData = (void*)*((_QWORD*)pStudioData->m_MDLCache + 1);
|
2022-04-29 18:25:54 +02:00
|
|
|
AcquireSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&*m_MDLLock));
|
2022-05-06 00:51:49 +02:00
|
|
|
v_CStudioHWDataRef__SetFlags(reinterpret_cast<CStudioHWDataRef*>(pAnimData), 1i64); // !!! DECLARED INLINE IN < S3 !!!
|
2022-04-29 18:25:54 +02:00
|
|
|
ReleaseSRWLockExclusive(reinterpret_cast<PSRWLOCK>(&*m_MDLLock));
|
|
|
|
}
|
2022-05-06 00:51:49 +02:00
|
|
|
if ((pStudioData->m_nFlags & STUDIODATA_FLAGS_STUDIOMESH_LOADED))
|
|
|
|
result = &pStudioData->m_pHardwareRef->m_HardwareData;
|
2022-04-29 18:25:54 +02:00
|
|
|
else
|
2022-05-06 00:51:49 +02:00
|
|
|
result = nullptr;
|
|
|
|
return result;
|
2022-04-29 18:25:54 +02:00
|
|
|
}
|
|
|
|
|
2022-05-01 05:38:51 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: gets the studio material glue from cache pool by handle
|
|
|
|
// Input : *this -
|
|
|
|
// handle -
|
|
|
|
// Output : a pointer to the CMaterialGlue object
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void* CMDLCache::GetStudioMaterialGlue(CMDLCache* cache, MDLHandle_t handle)
|
|
|
|
{
|
|
|
|
__int64 v2; // rbx
|
|
|
|
__int64 v3; // rbx
|
|
|
|
|
|
|
|
v2 = handle;
|
|
|
|
EnterCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
|
|
|
v3 = *(_QWORD*)(m_MDLDict.Deref().GetPtr() + 24 * v2 + 16);
|
|
|
|
LeaveCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(&*m_MDLMutex));
|
|
|
|
return (char*)v3 + 40;
|
|
|
|
}
|
|
|
|
|
2022-04-29 05:30:06 +02:00
|
|
|
void MDLCache_Attach()
|
|
|
|
{
|
|
|
|
DetourAttach((LPVOID*)&v_CMDLCache__FindMDL, &CMDLCache::FindMDL);
|
2022-04-30 03:30:16 +02:00
|
|
|
DetourAttach((LPVOID*)&v_CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL);
|
2022-04-29 05:30:06 +02:00
|
|
|
DetourAttach((LPVOID*)&v_CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL);
|
2022-05-06 00:51:49 +02:00
|
|
|
DetourAttach((LPVOID*)&v_CMDLCache__GetStudioHardware, &CMDLCache::GetStudioHardware);
|
2022-04-29 21:05:26 +02:00
|
|
|
DetourAttach((LPVOID*)&v_CMDLCache__GetStudioHDR, &CMDLCache::GetStudioHDR);
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MDLCache_Detach()
|
|
|
|
{
|
|
|
|
DetourDetach((LPVOID*)&v_CMDLCache__FindMDL, &CMDLCache::FindMDL);
|
2022-04-30 03:30:16 +02:00
|
|
|
DetourDetach((LPVOID*)&v_CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL);
|
2022-04-29 05:30:06 +02:00
|
|
|
DetourDetach((LPVOID*)&v_CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL);
|
2022-05-06 00:51:49 +02:00
|
|
|
DetourDetach((LPVOID*)&v_CMDLCache__GetStudioHardware, &CMDLCache::GetStudioHardware);
|
2022-04-29 21:05:26 +02:00
|
|
|
DetourDetach((LPVOID*)&v_CMDLCache__GetStudioHDR, &CMDLCache::GetStudioHDR);
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|