sqwarmed/sdk_src/game/shared/precache_register.cpp

343 lines
10 KiB
C++

//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "cbase.h"
#include "precache_register.h"
#include "tier1/KeyValues.h"
#include "tier2/tier2.h"
#include "datacache/iresourceaccesscontrol.h"
#include "filesystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static const char *s_pPrecacheResourceTypeName[] =
{
"vgui_resource",
"material",
"model",
"scriptsound", // NOTE: This is named this way for backward compat in reading from kv files
"particle_system",
"entity",
"decal",
"pmaterial",
"dependency_file",
"game_material_decals",
"physics_gamesounds",
"shared",
};
//-----------------------------------------------------------------------------
// Provides callback to do actual precaching of resources
//-----------------------------------------------------------------------------
class CPrecacheHandler : public IPrecacheHandler
{
public:
void CacheResource( PrecacheResourceType_t nType, const char *pName, bool bPrecache, ResourceList_t hResourceList, int *pIndex = NULL );
private:
void CacheResourceFile( const char *pFilename, bool bPrecache, ResourceList_t hResourceList );
void PrecacheGameMaterialDecals( bool bPrecache, ResourceList_t hResourceList );
void PrecachePhysicsSounds( const char *pName, bool bPrecache, ResourceList_t hResourceList );
};
//-----------------------------------------------------------------------------
// Singletons
//-----------------------------------------------------------------------------
static CPrecacheRegister s_PrecacheRegister;
CPrecacheRegister *g_pPrecacheRegister = &s_PrecacheRegister;
static CPrecacheHandler s_PrecacheHandler;
IPrecacheHandler *g_pPrecacheHandler = &s_PrecacheHandler;
bool CPrecacheRegister::Init()
{
return true;
}
//-----------------------------------------------------------------------------
// Level startup, shutdown
//-----------------------------------------------------------------------------
void CPrecacheRegister::LevelInitPreEntity()
{
COM_TimestampedLog( "LevelInitPreEntity - PreCache - Start" );
g_pPrecacheSystem->Cache( g_pPrecacheHandler, GLOBAL, NULL, true, RESOURCE_LIST_INVALID, false );
COM_TimestampedLog( "LevelInitPreEntity - PreCache - Finish" );
#ifdef CLIENT_DLL
//FIXME: Double check this
//Finally, force the cache of these materials
COM_TimestampedLog( "LevelInitPreEntity - CacheUsedMaterials - Start" );
materials->CacheUsedMaterials();
COM_TimestampedLog( "LevelInitPreEntity - CacheUsedMaterials - Finish" );
#endif
}
void CPrecacheRegister::LevelShutdownPostEntity()
{
// FIXME: How to uncache all resources cached during the course of the level?
g_pPrecacheSystem->UncacheAll( g_pPrecacheHandler );
if ( g_pResourceAccessControl )
{
g_pResourceAccessControl->DestroyAllResourceLists();
}
}
//-----------------------------------------------------------------------------
// Purpose: Precache game-specific models & sounds
//-----------------------------------------------------------------------------
void CPrecacheHandler::CacheResourceFile( const char *pFilename, bool bPrecache, ResourceList_t hResourceList )
{
COMPILE_TIME_ASSERT( ARRAYSIZE(s_pPrecacheResourceTypeName) == PRECACHE_RESOURCE_TYPE_COUNT );
KeyValues *pValues = new KeyValues( "ResourceFile" );
if ( !pValues->LoadFromFile( g_pFullFileSystem, pFilename, "GAME" ) )
{
Warning( "Can't open %s for client precache info.", pFilename );
pValues->deleteThis();
return;
}
for ( KeyValues *pData = pValues->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
{
const char *pszType = pData->GetName();
const char *pszFile = pData->GetString();
if ( Q_strlen( pszType ) == 0 || Q_strlen( pszFile ) == 0 )
continue;
bool bFoundMatch = false;
for ( int i = 0; i < PRECACHE_RESOURCE_TYPE_COUNT; ++i )
{
if ( !Q_stricmp( pData->GetName(), s_pPrecacheResourceTypeName[i] ) )
{
CacheResource( (PrecacheResourceType_t)i, pszFile, bPrecache, hResourceList );
bFoundMatch = true;
break;
}
}
if ( !bFoundMatch )
{
Warning( "Error in precache file \"%s\":\n", pFilename );
Warning( "\tUnknown resource type specified \"%s\", value \"%s\"\n", pszType, pszFile );
}
}
pValues->deleteThis();
}
//-----------------------------------------------------------------------------
// Precaches game material decals
//-----------------------------------------------------------------------------
void CPrecacheHandler::PrecacheGameMaterialDecals( bool bPrecache, ResourceList_t hResourceList )
{
}
void CPrecacheHandler::PrecachePhysicsSounds( const char *pName, bool bPrecache, ResourceList_t hResourceList )
{
if ( !bPrecache )
return;
// precache the surface prop sounds
bool bBulletSounds = !Q_stricmp( pName, "BulletSounds" );
bool bStepSounds = !Q_stricmp( pName, "StepSounds" );
bool bPhysicsImpactSounds = !Q_stricmp( pName, "PhysicsImpactSounds" );
for ( int i = 0; i < physprops->SurfacePropCount(); i++ )
{
surfacedata_t *pprop = physprops->GetSurfaceData( i );
Assert( pprop );
if ( bBulletSounds )
{
const char *pSoundName = physprops->GetString( pprop->sounds.bulletImpact );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
}
if ( bStepSounds )
{
const char *pSoundName = physprops->GetString( pprop->sounds.walkStepLeft );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
pSoundName = physprops->GetString( pprop->sounds.walkStepRight );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
pSoundName = physprops->GetString( pprop->sounds.runStepLeft );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
pSoundName = physprops->GetString( pprop->sounds.runStepRight );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
}
if ( bPhysicsImpactSounds )
{
const char *pSoundName = physprops->GetString( pprop->sounds.impactSoft );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
pSoundName = physprops->GetString( pprop->sounds.impactHard );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
pSoundName = physprops->GetString( pprop->sounds.scrapeSmooth );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
pSoundName = physprops->GetString( pprop->sounds.scrapeRough );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
pSoundName = physprops->GetString( pprop->sounds.rolling );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
pSoundName = physprops->GetString( pprop->sounds.breakSound );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
pSoundName = physprops->GetString( pprop->sounds.strainSound );
CacheResource( GAMESOUND, pSoundName, bPrecache, hResourceList, NULL );
}
}
}
//-----------------------------------------------------------------------------
// Caches/uncaches resources
//-----------------------------------------------------------------------------
void CPrecacheHandler::CacheResource( PrecacheResourceType_t nType, const char *pName,
bool bPrecache, ResourceList_t hResourceList, int *pIndex )
{
if ( bPrecache )
{
if ( pIndex )
{
*pIndex = 0;
}
switch( nType )
{
case VGUI_RESOURCE:
break;
case MATERIAL:
PrecacheMaterial( pName );
if ( pIndex )
{
*pIndex = GetMaterialIndex( pName );
}
if ( hResourceList != RESOURCE_LIST_INVALID )
{
g_pResourceAccessControl->AddResource( hResourceList, RESOURCE_MATERIAL, pName );
}
break;
case PARTICLE_MATERIAL:
{
#ifdef CLIENT_DLL
// FIXME: NOTE! This is not 64-bit safe.
// Hopefully we can remove PARTICLE_MATERIAL soon though.
// It can go away once we retire the old-style particle system
int nIndex = (int)( ParticleMgr()->GetPMaterial( pName ) );
#else
int nIndex = 0;
#endif
if ( pIndex )
{
*pIndex = nIndex;
}
}
break;
case GAME_MATERIAL_DECALS:
PrecacheGameMaterialDecals( bPrecache, hResourceList );
break;
case PHYSICS_GAMESOUNDS:
PrecachePhysicsSounds( pName, bPrecache, hResourceList );
break;
case DECAL:
{
int nIndex = UTIL_PrecacheDecal( pName, true );
if ( pIndex )
{
*pIndex = nIndex;
}
}
break;
case MODEL:
{
int nIndex = CBaseEntity::PrecacheModel( pName );
if ( pIndex )
{
*pIndex = nIndex;
}
if ( hResourceList != RESOURCE_LIST_INVALID )
{
g_pResourceAccessControl->AddResource( hResourceList, RESOURCE_MODEL, pName );
}
}
break;
case GAMESOUND:
{
int nIndex = CBaseEntity::PrecacheScriptSound( pName );
if ( pIndex )
{
*pIndex = nIndex;
}
if ( hResourceList != RESOURCE_LIST_INVALID )
{
g_pResourceAccessControl->AddResource( hResourceList, RESOURCE_GAMESOUND, pName );
}
}
break;
case PARTICLE_SYSTEM:
PrecacheParticleSystem( pName );
if ( pIndex )
{
*pIndex = GetParticleSystemIndex( pName );
}
if ( hResourceList != RESOURCE_LIST_INVALID )
{
g_pResourceAccessControl->AddResource( hResourceList, RESOURCE_PARTICLE_SYSTEM, pName );
}
break;
case ENTITY:
UTIL_PrecacheOther( pName );
break;
case SHARED:
g_pPrecacheSystem->Cache( this, SHARED_SYSTEM, pName, bPrecache, hResourceList, false );
break;
case KV_DEP_FILE:
CacheResourceFile( pName, bPrecache, hResourceList );
break;
}
return;
}
// Blat out value
if ( pIndex )
{
*pIndex = 0;
}
switch( nType )
{
case VGUI_RESOURCE:
break;
case MATERIAL:
break;
case MODEL:
break;
case GAMESOUND:
break;
case PARTICLE_SYSTEM:
break;
case ENTITY:
break;
case DECAL:
break;
case KV_DEP_FILE:
break;
}
}