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-10-14 02:31:10 +02:00
|
|
|
#include "tier1/utldict.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 "rtech/rtech_utils.h"
|
2022-08-09 17:18:07 +02:00
|
|
|
#include "public/studio.h"
|
2022-04-29 05:30:06 +02:00
|
|
|
|
2024-01-05 01:22:55 +01:00
|
|
|
CStudioFallbackHandler g_StudioMdlFallbackHandler;
|
|
|
|
#define IS_VALID_DATACACHE_HANDLE(cacheHandle) (cacheHandle && cacheHandle != DC_INVALID_HANDLE)
|
2022-04-29 05:30:06 +02:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: finds an MDL
|
|
|
|
// Input : *this -
|
|
|
|
// handle -
|
|
|
|
// *a3 -
|
|
|
|
// Output : a pointer to the studiohdr_t object
|
|
|
|
//-----------------------------------------------------------------------------
|
2024-01-04 21:19:32 +01:00
|
|
|
studiohdr_t* CMDLCache::FindMDL(CMDLCache* const cache, const MDLHandle_t handle, void* a3)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
studiodata_t* const studioData = cache->GetStudioData(handle);
|
2022-04-29 05:30:06 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!studioData)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2024-01-04 16:12:25 +01:00
|
|
|
studiohdr_t* const pStudioHdr = GetErrorModel();
|
|
|
|
|
|
|
|
if (!IsKnownBadModel(handle))
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2024-01-04 16:12:25 +01:00
|
|
|
if (!pStudioHdr)
|
|
|
|
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model with handle \"%hu\" not found and \"%s\" couldn't be loaded.\n", handle, ERROR_MODEL);
|
|
|
|
else
|
|
|
|
Error(eDLL_T::ENGINE, NO_ERROR, "Model with handle \"%hu\" not found; replacing with \"%s\".\n", handle, ERROR_MODEL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pStudioHdr;
|
|
|
|
}
|
|
|
|
|
2024-01-07 02:02:40 +01:00
|
|
|
studiomodelcache_t* modelCache = studioData->GetModelCache();
|
2023-06-19 13:53:56 +02:00
|
|
|
|
2024-01-04 16:12:25 +01:00
|
|
|
// Store error and empty fallback models.
|
2024-01-07 01:39:15 +01:00
|
|
|
if (IS_VALID_DATACACHE_HANDLE(modelCache))
|
2024-01-04 16:12:25 +01:00
|
|
|
{
|
2024-01-07 02:02:40 +01:00
|
|
|
studiohdr_t* const studioHdr = studioData->GetModelCache()->GetStudioHdr();
|
2024-01-04 16:12:25 +01:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if (studioHdr)
|
2024-01-04 16:12:25 +01:00
|
|
|
{
|
2024-01-05 01:22:55 +01:00
|
|
|
// 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.
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!HasErrorModel() && ((studioData->flags & STUDIODATA_ERROR_MODEL)
|
|
|
|
|| V_ComparePath(studioHdr->name, ERROR_MODEL)))
|
2023-06-19 13:53:56 +02:00
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
g_StudioMdlFallbackHandler.SetFallbackModel(studioHdr, handle);
|
2022-05-18 02:04:37 +02:00
|
|
|
}
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
}
|
2022-05-06 13:19:06 +02:00
|
|
|
|
2024-01-04 16:12:25 +01:00
|
|
|
const int nFlags = STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE | STUDIOHDR_FLAGS_OBSOLETE;
|
2022-04-29 05:30:06 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if ((studioData->flags & nFlags))
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2024-01-07 01:42:26 +01:00
|
|
|
if (IS_VALID_DATACACHE_HANDLE(modelCache))
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
|
|
|
if (a3)
|
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
FindCachedMDL(cache, studioData, a3);
|
2024-01-07 02:02:40 +01:00
|
|
|
modelCache = studioData->GetModelCache();
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
2022-10-15 00:07:51 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
studiohdr_t* const pStudioHdr = modelCache->GetStudioHdr();
|
2024-01-04 16:12:25 +01:00
|
|
|
|
2022-05-05 14:53:48 +02:00
|
|
|
if (pStudioHdr)
|
|
|
|
return pStudioHdr;
|
2022-04-29 05:30:06 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
return FindUncachedMDL(cache, handle, studioData, a3);
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
2024-01-04 16:12:25 +01:00
|
|
|
|
2024-01-07 02:02:40 +01:00
|
|
|
studioanimcache_t* const animCache = studioData->GetAnimCache();
|
2024-01-04 16:12:25 +01:00
|
|
|
|
2024-01-07 01:42:26 +01:00
|
|
|
if (IS_VALID_DATACACHE_HANDLE(animCache))
|
2022-10-15 00:07:51 +02:00
|
|
|
{
|
2024-01-04 16:12:25 +01:00
|
|
|
studiohdr_t* const pStudioHdr = animCache->GetStudioHdr();
|
|
|
|
|
2022-10-15 00:07:51 +02:00
|
|
|
if (pStudioHdr)
|
|
|
|
return pStudioHdr;
|
|
|
|
}
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
2024-01-07 01:39:15 +01:00
|
|
|
return FindUncachedMDL(cache, handle, studioData, a3);
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: finds an MDL cached
|
|
|
|
// Input : *this -
|
2022-05-18 01:00:46 +02:00
|
|
|
// *pStudioData -
|
2022-04-29 05:30:06 +02:00
|
|
|
// *a3 -
|
|
|
|
//-----------------------------------------------------------------------------
|
2024-01-04 21:19:32 +01:00
|
|
|
void CMDLCache::FindCachedMDL(CMDLCache* const cache, studiodata_t* const pStudioData, void* a3)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2022-04-30 03:30:16 +02:00
|
|
|
if (a3)
|
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
AUTO_LOCK(pStudioData->mutex);
|
2023-07-02 11:38:36 +02:00
|
|
|
|
2022-05-05 17:53:05 +02:00
|
|
|
*(_QWORD*)((int64_t)a3 + 0x880) = *(_QWORD*)&pStudioData->pad[0x24];
|
2022-05-06 02:32:25 +02:00
|
|
|
int64_t 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;
|
2024-01-07 01:39:15 +01:00
|
|
|
*(_WORD*)((int64_t)a3 + 0x888) = pStudioData->modelHandle;
|
2022-04-30 03:30:16 +02:00
|
|
|
}
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: finds an MDL uncached
|
|
|
|
// Input : *this -
|
|
|
|
// handle -
|
2022-05-18 01:00:46 +02:00
|
|
|
// *pStudioData -
|
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
|
|
|
|
//-----------------------------------------------------------------------------
|
2024-01-04 21:19:32 +01:00
|
|
|
studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* const cache, const MDLHandle_t handle, studiodata_t* pStudioData, void* a4)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
AUTO_LOCK(pStudioData->mutex);
|
2022-04-29 05:30:06 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
const char* modelName = cache->GetModelName(handle);
|
|
|
|
const size_t fileNameLen = strlen(modelName);
|
2022-04-29 05:30:06 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
studiohdr_t* studioHdr = nullptr;
|
2023-07-02 11:38:36 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if (fileNameLen < 5 ||
|
|
|
|
(Q_stricmp(&modelName[fileNameLen - 5], ".rmdl") != 0) &&
|
|
|
|
(Q_stricmp(&modelName[fileNameLen - 5], ".rrig") != 0) &&
|
|
|
|
(Q_stricmp(&modelName[fileNameLen - 5], ".rpak") != 0))
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
studioHdr = GetErrorModel();
|
2022-05-06 13:19:06 +02:00
|
|
|
if (!IsKnownBadModel(handle))
|
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!studioHdr)
|
|
|
|
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Attempted to load old model \"%s\" and \"%s\" couldn't be loaded.\n", modelName, ERROR_MODEL);
|
2022-05-06 13:19:06 +02:00
|
|
|
else
|
2024-01-07 01:39:15 +01:00
|
|
|
Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to load old model \"%s\"; replacing with \"%s\".\n", modelName, ERROR_MODEL);
|
2022-05-06 13:19:06 +02:00
|
|
|
}
|
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
return studioHdr;
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
pStudioData->processing = true;
|
|
|
|
g_pRTech->StringToGuid(modelName);
|
|
|
|
pStudioData->processing = false;
|
2022-05-05 20:36:13 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!pStudioData->modelCache)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2024-01-04 16:12:25 +01:00
|
|
|
studioanimcache_t* const animCache = pStudioData->GetAnimCache();
|
2024-01-07 01:44:09 +01:00
|
|
|
if (IS_VALID_DATACACHE_HANDLE(animCache))
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
studioHdr = animCache->GetStudioHdr();
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
studioHdr = GetErrorModel();
|
2022-05-06 13:19:06 +02:00
|
|
|
if (!IsKnownBadModel(handle))
|
2022-04-29 22:46:37 +02:00
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!studioHdr)
|
|
|
|
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" not found and \"%s\" couldn't be loaded.\n", modelName, ERROR_MODEL);
|
2022-05-01 05:38:51 +02:00
|
|
|
else
|
2024-01-07 01:39:15 +01:00
|
|
|
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" not found; replacing with \"%s\".\n", modelName, ERROR_MODEL);
|
2022-04-29 22:46:37 +02:00
|
|
|
}
|
2022-05-06 13:19:06 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
return studioHdr;
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-05-18 01:00:46 +02:00
|
|
|
FindCachedMDL(cache, pStudioData, a4);
|
2024-01-07 02:02:40 +01:00
|
|
|
studiomodelcache_t* const modelCache = pStudioData->GetModelCache();
|
2023-06-25 14:56:04 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if (modelCache)
|
2022-05-04 12:44:01 +02:00
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
if (modelCache == DC_INVALID_HANDLE)
|
2022-05-06 13:19:06 +02:00
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
studioHdr = GetErrorModel();
|
2022-05-06 13:19:06 +02:00
|
|
|
if (!IsKnownBadModel(handle))
|
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!studioHdr)
|
|
|
|
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" has bad studio data and \"%s\" couldn't be loaded.\n", modelName, ERROR_MODEL);
|
2022-05-06 13:19:06 +02:00
|
|
|
else
|
2024-01-07 01:39:15 +01:00
|
|
|
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" has bad studio data; replacing with \"%s\".\n", modelName, ERROR_MODEL);
|
2022-05-06 13:19:06 +02:00
|
|
|
}
|
|
|
|
}
|
2022-05-04 12:44:01 +02:00
|
|
|
else
|
2024-01-07 01:39:15 +01:00
|
|
|
studioHdr = modelCache->GetStudioHdr();
|
2022-05-04 12:44:01 +02:00
|
|
|
}
|
|
|
|
else
|
2022-05-06 13:19:06 +02:00
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
studioHdr = GetErrorModel();
|
2024-01-04 16:12:25 +01:00
|
|
|
|
2022-05-06 13:19:06 +02:00
|
|
|
if (!IsKnownBadModel(handle))
|
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!studioHdr)
|
|
|
|
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Model \"%s\" has no studio data and \"%s\" couldn't be loaded.\n", modelName, ERROR_MODEL);
|
2022-05-06 13:19:06 +02:00
|
|
|
else
|
2024-01-07 01:39:15 +01:00
|
|
|
Error(eDLL_T::ENGINE, NO_ERROR, "Model \"%s\" has no studio data; replacing with \"%s\".\n", modelName, ERROR_MODEL);
|
2022-05-06 13:19:06 +02:00
|
|
|
}
|
|
|
|
}
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
2023-06-25 02:31:50 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
assert(studioHdr);
|
|
|
|
return studioHdr;
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
studiomodelcache_t* CMDLCache::GetModelCache(const MDLHandle_t handle)
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2024-01-04 21:19:32 +01:00
|
|
|
if (handle == MDLHANDLE_INVALID)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
const studiodata_t* const studioData = GetStudioData(handle);
|
|
|
|
|
|
|
|
if (!studioData)
|
|
|
|
return nullptr;
|
2024-01-04 16:12:25 +01:00
|
|
|
|
2024-01-07 02:02:40 +01:00
|
|
|
studiomodelcache_t* const modelCache = studioData->GetModelCache();
|
2024-01-07 01:39:15 +01:00
|
|
|
return modelCache;
|
2024-01-04 21:19:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: gets the vcollide data from cache pool by handle
|
|
|
|
// Input : *this -
|
|
|
|
// handle -
|
|
|
|
// Output : a pointer to the vcollide_t object
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
vcollide_t* CMDLCache::GetVCollide(CMDLCache* const cache, const MDLHandle_t handle)
|
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
studiomodelcache_t* const modelCache = cache->GetModelCache(handle);
|
2024-01-05 01:22:55 +01:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!IS_VALID_DATACACHE_HANDLE(modelCache))
|
2024-01-05 01:22:55 +01:00
|
|
|
{
|
2024-01-07 02:02:40 +01:00
|
|
|
Warning(eDLL_T::ENGINE, "Attempted to load collision data on model \"%s\" with invalid studio data!\n", cache->GetModelName(handle));
|
2024-01-05 01:22:55 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
studiophysicsref_t* const physicsCache = modelCache->GetPhysicsCache();
|
2024-01-04 21:19:32 +01:00
|
|
|
|
|
|
|
if (!physicsCache)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
CStudioVCollide* const pVCollide = physicsCache->GetStudioVCollide();
|
|
|
|
|
|
|
|
if (!pVCollide)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return pVCollide->GetVCollide();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: gets the physics geometry data from cache pool by handle
|
|
|
|
// Input : *this -
|
|
|
|
// handle -
|
|
|
|
// Output : a pointer to the physics geometry descriptor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void* CMDLCache::GetPhysicsGeometry(CMDLCache* const cache, const MDLHandle_t handle)
|
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
studiomodelcache_t* const modelCache = cache->GetModelCache(handle);
|
2024-01-05 01:22:55 +01:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!IS_VALID_DATACACHE_HANDLE(modelCache))
|
2024-01-05 01:22:55 +01:00
|
|
|
{
|
|
|
|
Warning(eDLL_T::ENGINE, "Attempted to load physics geometry on model \"%s\" with invalid studio data!\n", cache->GetModelName(handle));
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
studiophysicsref_t* const physicsRef = modelCache->GetPhysicsCache();
|
2024-01-04 21:19:32 +01:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!physicsRef)
|
2024-01-04 21:19:32 +01:00
|
|
|
return nullptr;
|
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
CStudioPhysicsGeoms* const physicsGeoms = physicsRef->GetPhysicsGeoms();
|
2024-01-04 21:19:32 +01:00
|
|
|
|
|
|
|
if (!physicsGeoms)
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
return physicsGeoms->GetGeometryData();
|
2022-04-29 05:30:06 +02:00
|
|
|
}
|
|
|
|
|
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
|
|
|
//-----------------------------------------------------------------------------
|
2024-01-04 21:19:32 +01:00
|
|
|
studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* const cache, const MDLHandle_t handle)
|
2022-04-29 18:25:54 +02:00
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
const studiodata_t* studioData = nullptr; cache->GetStudioData(handle);
|
|
|
|
const studiomodelcache_t* modelCache = cache->GetModelCache(handle);
|
2022-04-29 18:25:54 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if (!IS_VALID_DATACACHE_HANDLE(modelCache))
|
2022-04-29 18:25:54 +02:00
|
|
|
{
|
2024-01-05 01:22:55 +01:00
|
|
|
if (!HasErrorModel())
|
2022-04-29 22:11:35 +02:00
|
|
|
{
|
2024-01-05 01:22:55 +01:00
|
|
|
Error(eDLL_T::ENGINE, NO_ERROR, "Studio hardware for model \"%s\" not found and \"%s\" couldn't be loaded!\n",
|
|
|
|
cache->GetModelName(handle), ERROR_MODEL);
|
|
|
|
|
|
|
|
assert(0); // Should never be hit!
|
2022-04-29 22:11:35 +02:00
|
|
|
return nullptr;
|
|
|
|
}
|
2024-01-05 01:22:55 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// Only spew the message once.
|
|
|
|
if (g_StudioMdlFallbackHandler.AddToSuppressionList(handle))
|
|
|
|
{
|
|
|
|
Warning(eDLL_T::ENGINE, "Studio hardware for model \"%s\" not found; replacing with \"%s\".\n",
|
|
|
|
cache->GetModelName(handle), ERROR_MODEL);
|
|
|
|
}
|
|
|
|
}
|
2023-06-25 14:56:04 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
studioData = cache->GetStudioData(GetErrorModelHandle());
|
2024-01-07 02:02:40 +01:00
|
|
|
modelCache = studioData->GetModelCache();
|
2024-01-05 01:22:55 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-01-07 01:39:15 +01:00
|
|
|
studioData = cache->GetStudioData(handle);
|
2024-01-05 01:22:55 +01:00
|
|
|
}
|
2022-05-04 12:44:01 +02:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
studiophysicsref_t* const physicsRef = modelCache->GetPhysicsCache();
|
2022-05-06 02:32:25 +02:00
|
|
|
|
2024-01-04 21:19:32 +01:00
|
|
|
AcquireSRWLockExclusive(g_pMDLLock);
|
2024-01-07 01:39:15 +01:00
|
|
|
CMDLCache__CheckData(physicsRef, 1i64); // !!! DECLARED INLINE IN < S3 !!!
|
2024-01-04 21:19:32 +01:00
|
|
|
ReleaseSRWLockExclusive(g_pMDLLock);
|
2024-01-04 16:12:25 +01:00
|
|
|
|
2024-01-07 01:39:15 +01:00
|
|
|
if ((studioData->flags & STUDIODATA_FLAGS_STUDIOMESH_LOADED))
|
|
|
|
return studioData->GetHardwareDataRef()->GetHardwareData();
|
2024-01-04 21:19:32 +01:00
|
|
|
|
|
|
|
return nullptr;
|
2022-04-29 18:25:54 +02:00
|
|
|
}
|
|
|
|
|
2022-05-06 13:19:06 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: gets the error model
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
studiohdr_t* CMDLCache::GetErrorModel(void)
|
|
|
|
{
|
2024-01-05 01:22:55 +01:00
|
|
|
// NOTE: must enable the old gather props logic for fallback models to draw !!!
|
|
|
|
// The new one won't call GetHardwareData on bad model handles.
|
|
|
|
// TODO[ AMOS ]: move this elsewhere; correct place is GatherStaticPropsSecondPass().
|
|
|
|
g_StudioMdlFallbackHandler.EnableLegacyGatherProps();
|
|
|
|
|
|
|
|
return g_StudioMdlFallbackHandler.GetFallbackModelHeader();
|
|
|
|
}
|
|
|
|
const char* CMDLCache::GetErrorModelName(void)
|
|
|
|
{
|
|
|
|
const studiohdr_t* const errorStudioHdr = g_StudioMdlFallbackHandler.GetFallbackModelHeader();
|
|
|
|
assert(errorStudioHdr);
|
|
|
|
|
|
|
|
return errorStudioHdr ? errorStudioHdr->name : "(invalid)";
|
2022-05-06 13:19:06 +02:00
|
|
|
}
|
2024-01-04 21:19:32 +01:00
|
|
|
MDLHandle_t CMDLCache::GetErrorModelHandle(void)
|
|
|
|
{
|
2024-01-05 01:22:55 +01:00
|
|
|
return g_StudioMdlFallbackHandler.GetFallbackModelHandle();
|
|
|
|
}
|
|
|
|
bool CMDLCache::HasErrorModel(void)
|
|
|
|
{
|
|
|
|
return g_StudioMdlFallbackHandler.HasFallbackModel();
|
2024-01-04 21:19:32 +01:00
|
|
|
}
|
2022-05-06 13:19:06 +02:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2023-02-13 23:50:37 +01:00
|
|
|
// Purpose: checks if this model handle is within the set of bad models
|
2022-05-06 13:19:06 +02:00
|
|
|
// Input : handle -
|
|
|
|
// Output : true if exist, false otherwise
|
|
|
|
//-----------------------------------------------------------------------------
|
2024-01-04 21:19:32 +01:00
|
|
|
bool CMDLCache::IsKnownBadModel(const MDLHandle_t handle)
|
2022-05-06 13:19:06 +02:00
|
|
|
{
|
2024-01-05 01:22:55 +01:00
|
|
|
// Only adds if it didn't exist yet, else it returns false.
|
|
|
|
return g_StudioMdlFallbackHandler.AddBadModelHandle(handle);
|
2022-05-06 13:19:06 +02:00
|
|
|
}
|
|
|
|
|
2023-11-26 13:21:20 +01:00
|
|
|
void VMDLCache::Detour(const bool bAttach) const
|
2022-04-29 05:30:06 +02:00
|
|
|
{
|
2024-01-02 15:21:36 +01:00
|
|
|
DetourSetup(&CMDLCache__FindMDL, &CMDLCache::FindMDL, bAttach);
|
|
|
|
DetourSetup(&CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL, bAttach);
|
|
|
|
DetourSetup(&CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL, bAttach);
|
2024-01-07 01:39:15 +01:00
|
|
|
|
2024-01-04 16:12:25 +01:00
|
|
|
DetourSetup(&CMDLCache__GetVCollide, &CMDLCache::GetVCollide, bAttach);
|
2024-01-04 21:19:32 +01:00
|
|
|
DetourSetup(&CMDLCache__GetPhysicsGeometry, &CMDLCache::GetPhysicsGeometry, bAttach);
|
2024-01-07 01:39:15 +01:00
|
|
|
|
|
|
|
DetourSetup(&CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData, bAttach);
|
2024-01-02 15:21:36 +01:00
|
|
|
}
|