2022-03-01 02:39:46 +01:00
|
|
|
//===========================================================================//
|
|
|
|
//
|
|
|
|
// Purpose: Model loading / unloading interface
|
|
|
|
//
|
|
|
|
// $NoKeywords: $
|
|
|
|
//===========================================================================//
|
|
|
|
|
|
|
|
#include "core/stdafx.h"
|
|
|
|
#include "engine/cmodel_bsp.h"
|
|
|
|
#include "engine/modelloader.h"
|
2022-04-29 05:30:06 +02:00
|
|
|
#include "datacache/mdlcache.h"
|
2023-05-20 14:06:36 +02:00
|
|
|
#ifndef DEDICATED
|
|
|
|
#include <vgui/vgui_baseui_interface.h>
|
|
|
|
#endif // !DEDICATED
|
|
|
|
#include <filesystem/filesystem.h>
|
2022-03-01 02:39:46 +01:00
|
|
|
|
2022-04-29 05:30:06 +02:00
|
|
|
model_t* pErrorMDL = nullptr;
|
|
|
|
|
2023-05-20 14:06:36 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose: checks if the lump type is valid and used
|
|
|
|
// Input : lumpType -
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool IsLumpIdxValid(int lumpType)
|
|
|
|
{
|
|
|
|
switch (lumpType)
|
|
|
|
{
|
|
|
|
case LUMP_PLANES:
|
|
|
|
case LUMP_VERTICES:
|
|
|
|
case LUMP_SHADOW_ENVIRONMENTS:
|
|
|
|
case LUMP_SURFACE_NAMES:
|
|
|
|
case LUMP_CONTENTS_MASKS:
|
|
|
|
case LUMP_SURFACE_PROPERTIES:
|
|
|
|
case LUMP_BVH_NODES:
|
|
|
|
case LUMP_BVH_LEAF_DATA:
|
|
|
|
case LUMP_PACKED_VERTICES:
|
|
|
|
case LUMP_VERTEX_NORMALS:
|
|
|
|
case LUMP_UNKNOWN_37:
|
|
|
|
case LUMP_UNKNOWN_38:
|
|
|
|
case LUMP_UNKNOWN_39:
|
|
|
|
case LUMP_VERTEX_UNLIT:
|
|
|
|
case LUMP_VERTEX_LIT_FLAT:
|
|
|
|
case LUMP_VERTEX_LIT_BUMP:
|
|
|
|
case LUMP_VERTEX_UNLIT_TS:
|
|
|
|
case LUMP_MESH_INDICES:
|
|
|
|
case LUMP_LIGHTMAP_DATA_SKY:
|
|
|
|
case LUMP_CSM_AABB_NODES:
|
|
|
|
case LUMP_CSM_OBJ_REFERENCES:
|
|
|
|
case LUMP_LIGHTPROBES:
|
|
|
|
case LUMP_LIGHTPROBE_TREE:
|
|
|
|
case LUMP_LIGHTPROBE_REFERENCES:
|
|
|
|
case LUMP_LIGHTMAP_DATA_REAL_TIME_LIGHTS:
|
|
|
|
case LUMP_CELL_BSP_NODES:
|
|
|
|
case LUMP_CELLS:
|
|
|
|
case LUMP_PORTALS:
|
|
|
|
case LUMP_PORTAL_VERTICES:
|
|
|
|
case LUMP_PORTAL_EDGES:
|
|
|
|
case LUMP_PORTAL_VERTEX_EDGES:
|
|
|
|
case LUMP_PORTAL_VERTEX_REFERENCES:
|
|
|
|
case LUMP_PORTAL_EDGE_REFERENCES:
|
|
|
|
case LUMP_PORTAL_EDGE_INTERSECT_AT_EDGE:
|
|
|
|
case LUMP_PORTAL_EDGE_INTERSECT_AT_VERTEX:
|
|
|
|
case LUMP_PORTAL_EDGE_INTERSECT_HEADER:
|
|
|
|
case LUMP_OCCLUSION_MESH_VERTICES:
|
|
|
|
case LUMP_OCCLUSION_MESH_INDICES:
|
|
|
|
case LUMP_CELL_AABB_NODES:
|
|
|
|
case LUMP_OBJ_REFERENCES:
|
|
|
|
case LUMP_OBJ_REFERENCE_BOUNDS:
|
|
|
|
case LUMP_SHADOW_MESH_OPAQUE_VERTICES:
|
|
|
|
case LUMP_SHADOW_MESH_INDICES:
|
|
|
|
case LUMP_SHADOW_MESHES:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-29 05:30:06 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
// Input : *loader -
|
|
|
|
// *model -
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CModelLoader::LoadModel(CModelLoader* loader, model_t* model)
|
|
|
|
{
|
|
|
|
//if (!pErrorMDL)
|
|
|
|
//{
|
|
|
|
// if (strcmp(model->szPathName, ERROR_MODEL) == 0)
|
|
|
|
// {
|
|
|
|
// pErrorMDL = model;
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
//string svExtension = model->szPathName;
|
|
|
|
//size_t npos = svExtension.find(".");
|
|
|
|
//if (npos != string::npos)
|
|
|
|
//{
|
|
|
|
// svExtension = svExtension.substr(npos + 1);
|
|
|
|
//}
|
|
|
|
|
|
|
|
//if (strcmp(svExtension.c_str(), "rmdl") == 0 && strcmp(model->szPathName, ERROR_MODEL) != 0)
|
|
|
|
//{
|
|
|
|
// studiohdr_t* pStudioHDR = g_MDLCache->FindMDL(g_MDLCache->m_pVTable, model->studio, 0);
|
|
|
|
// if (pStudioHDR == pErrorStudioHDR)
|
|
|
|
// {
|
|
|
|
// model = pErrorMDL;
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
return CModelLoader__LoadModel(loader, model);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
// Input : *loader -
|
|
|
|
// *model -
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
uint64_t CModelLoader::Map_LoadModelGuts(CModelLoader* loader, model_t* model)
|
2022-03-01 02:39:46 +01:00
|
|
|
{
|
2022-04-29 05:30:06 +02:00
|
|
|
return CModelLoader__Map_LoadModelGuts(loader, model);
|
2022-03-01 02:39:46 +01:00
|
|
|
}
|
|
|
|
|
2023-05-20 14:06:36 +02:00
|
|
|
void CMapLoadHelper::Constructor(CMapLoadHelper* loader, int lumpToLoad)
|
2023-05-19 20:21:11 +01:00
|
|
|
{
|
2023-05-20 14:06:36 +02:00
|
|
|
#ifndef DEDICATED
|
|
|
|
g_pEngineVGui->UpdateProgressBar(PROGRESS_DEFAULT);
|
|
|
|
#endif // !DEDICATED
|
|
|
|
|
|
|
|
if (lumpToLoad > HEADER_LUMPS-1)
|
|
|
|
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Can't load lump %i, range is 0 to %i!!!", lumpToLoad, HEADER_LUMPS-1);
|
|
|
|
|
|
|
|
loader->m_nLumpID = lumpToLoad;
|
|
|
|
loader->m_nLumpSize = 0;
|
|
|
|
loader->m_pData = nullptr;
|
|
|
|
loader->m_pRawData = nullptr;
|
|
|
|
loader->m_pUncompressedData = nullptr;
|
|
|
|
loader->m_nUncompressedLumpSize = 0;
|
|
|
|
loader->m_bUncompressedDataExternal = 0;
|
|
|
|
loader->m_bExternal = false;
|
|
|
|
loader->m_bUnk = false;
|
|
|
|
loader->m_nLumpOffset = -1;
|
|
|
|
|
|
|
|
if (lumpToLoad <= s_MapHeader->lastLump)
|
|
|
|
{
|
|
|
|
lump_t* lump = &s_MapHeader->lumps[lumpToLoad];
|
|
|
|
|
|
|
|
int lumpOffset = lump->fileofs;
|
|
|
|
if (!lumpOffset)
|
|
|
|
return; // Idk if this is correct.
|
|
|
|
|
|
|
|
int lumpSize = lump->filelen;
|
|
|
|
if (lumpSize)
|
|
|
|
{
|
|
|
|
loader->m_nLumpSize = lumpSize;
|
|
|
|
loader->m_nLumpOffset = lump->fileofs;
|
|
|
|
loader->m_nLumpVersion = lump->version;
|
|
|
|
|
|
|
|
FileHandle_t mapFileHandle = *s_MapFileHandle;
|
|
|
|
|
|
|
|
if (mapFileHandle == FILESYSTEM_INVALID_HANDLE)
|
|
|
|
{
|
|
|
|
Error(eDLL_T::ENGINE, EXIT_FAILURE, "Can't load map from invalid handle!!!");
|
|
|
|
lumpSize = loader->m_nLumpSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
loader->m_nUncompressedLumpSize = lumpSize;
|
|
|
|
|
|
|
|
char pathBuf[MAX_PATH];
|
|
|
|
FileSystemCache fileCache;
|
|
|
|
|
|
|
|
fileCache.pBuffer = nullptr;
|
|
|
|
|
|
|
|
if (IsLumpIdxValid(lumpToLoad)
|
|
|
|
&& (V_snprintf(pathBuf, sizeof(pathBuf), "%s.%.4X.bsp_lump", s_szMapPathName, lumpToLoad), FileSystem()->ReadFromCache(pathBuf, &fileCache)))
|
|
|
|
{
|
|
|
|
loader->m_pRawData = nullptr;
|
|
|
|
loader->m_pData = fileCache.pBuffer->pData;
|
|
|
|
loader->m_bExternal = true;
|
|
|
|
loader->m_bUnk = fileCache.pBuffer->nUnk0 == 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int bytesToRead = lumpSize ? lumpSize : 1;
|
|
|
|
loader->m_pRawData = MemAllocSingleton()->Alloc<byte>(bytesToRead);
|
|
|
|
|
|
|
|
if (loader->m_nLumpSize)
|
|
|
|
{
|
|
|
|
FileHandle_t hLumpFile = FileSystem()->Open(pathBuf, "rb");
|
|
|
|
|
2023-05-20 13:49:12 +01:00
|
|
|
loader->m_pData = loader->m_pRawData;
|
|
|
|
|
2023-05-20 14:06:36 +02:00
|
|
|
if (hLumpFile != FILESYSTEM_INVALID_HANDLE)
|
|
|
|
{
|
|
|
|
FileSystem()->ReadEx(loader->m_pRawData, bytesToRead, bytesToRead, hLumpFile);
|
|
|
|
FileSystem()->Close(hLumpFile);
|
|
|
|
|
2023-05-20 13:49:12 +01:00
|
|
|
loader->m_pRawData = nullptr;
|
2023-05-20 14:06:36 +02:00
|
|
|
loader->m_bExternal = true;
|
|
|
|
}
|
|
|
|
else // Seek to offset in packed BSP file to load the lump.
|
|
|
|
{
|
|
|
|
FileSystem()->Seek(mapFileHandle, loader->m_nLumpOffset, FILESYSTEM_SEEK_HEAD);
|
|
|
|
FileSystem()->ReadEx(loader->m_pRawData, bytesToRead, bytesToRead, mapFileHandle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
loader->m_nLumpSize = 0;
|
|
|
|
loader->m_nLumpOffset = 0;
|
|
|
|
loader->m_nLumpVersion = 0;
|
|
|
|
}
|
2023-05-19 20:21:11 +01:00
|
|
|
}
|
|
|
|
|
2022-03-01 02:39:46 +01:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2023-01-25 02:26:52 +01:00
|
|
|
void VModelLoader::Attach() const
|
2022-03-01 02:39:46 +01:00
|
|
|
{
|
2022-04-29 05:30:06 +02:00
|
|
|
DetourAttach((LPVOID*)&CModelLoader__LoadModel, &CModelLoader::LoadModel);
|
|
|
|
DetourAttach((LPVOID*)&CModelLoader__Map_LoadModelGuts, &CModelLoader::Map_LoadModelGuts);
|
2023-05-19 20:21:11 +01:00
|
|
|
|
|
|
|
DetourAttach((LPVOID*)&CMapLoadHelper__CMapLoadHelper, &CMapLoadHelper::Constructor);
|
2022-03-01 02:39:46 +01:00
|
|
|
}
|
|
|
|
|
2023-01-25 02:26:52 +01:00
|
|
|
void VModelLoader::Detach() const
|
2022-03-01 02:39:46 +01:00
|
|
|
{
|
2022-04-29 05:30:06 +02:00
|
|
|
DetourDetach((LPVOID*)&CModelLoader__LoadModel, &CModelLoader::LoadModel);
|
|
|
|
DetourDetach((LPVOID*)&CModelLoader__Map_LoadModelGuts, &CModelLoader::Map_LoadModelGuts);
|
2023-05-19 20:21:11 +01:00
|
|
|
|
|
|
|
DetourDetach((LPVOID*)&CMapLoadHelper__CMapLoadHelper, &CMapLoadHelper::Constructor);
|
2022-03-01 02:39:46 +01:00
|
|
|
}
|