|
|
//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#include "gamelayer.h"
#include "gamerect.h"
#include "tier1/keyvalues.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/imaterialvar.h"
#include "tier1/utlbuffer.h"
#include "tier2/tier2.h"
#include "filesystem.h"
#include "rendersystem/irendercontext.h"
#include "tier2/fileutils.h"
#include "gameuisystemsurface.h"
#include "gameuidefinition.h"
#include "tier1/fmtstr.h"
#include "gamerect.h"
#include "gametext.h"
#include "hitarea.h"
#include "graphicgroup.h"
#include "dynamicrect.h"
#include "gameuiscript.h"
#include "gameuisystemmgr.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
BEGIN_DMXELEMENT_UNPACK ( CGameLayer ) DMXELEMENT_UNPACK_FIELD_UTLSTRING( "name", "", m_pName ) END_DMXELEMENT_UNPACK( CGameLayer, s_GameLayerUnpack )
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CGameLayer::CGameLayer( SublayerTypes_t layerType ) { m_pName = ""; m_LayerType = layerType; m_pTextureName = ""; m_hTexture = RENDER_TEXTURE_HANDLE_INVALID; m_Material = NULL; m_Sheet = NULL; m_SheetSymbol = UTL_INVAL_SYMBOL; m_bSheetSymbolCached = false; }
//-----------------------------------------------------------------------------
// Destructor
//-----------------------------------------------------------------------------
CGameLayer::~CGameLayer() { if ( m_Material.IsValid() ) { m_Material.Shutdown( true ); } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameLayer::Shutdown() { int nGraphicsCount = m_LayerGraphics.Count(); for ( int j = 0; j < nGraphicsCount; ++j ) { Assert( !m_LayerGraphics[j]->IsGroup() ); delete m_LayerGraphics[j]; m_LayerGraphics[j] = NULL; } m_LayerGraphics.RemoveAll(); }
//-----------------------------------------------------------------------------
// Load data from dmx file
//-----------------------------------------------------------------------------
bool CGameLayer::Unserialize( CDmxElement *pLayer, CUtlDict< CGameGraphic *, int > &unserializedGraphicMapping ) { pLayer->UnpackIntoStructure( this, s_GameLayerUnpack );
// Static graphics
if ( m_LayerType == SUBLAYER_STATIC ) { CDmxAttribute *pGraphics = pLayer->GetAttribute( "staticGraphics" ); const CUtlVector< CDmxElement * > &graphics = pGraphics->GetArray< CDmxElement * >( ); int nCount = graphics.Count(); for ( int i = 0; i < nCount; ++i ) { // What kind of graphic is this?
const char *pType = graphics[i]->GetValueString( "classtype" );
if ( !Q_stricmp( pType, "CDmeRectGeometry" ) ) { CGameRect *pGraphic = new CGameRect( "" ); if ( !pGraphic->Unserialize( graphics[i] ) ) { delete pGraphic; return false; } m_LayerGraphics.AddToTail( pGraphic ); char pBuf[255]; UniqueIdToString( graphics[i]->GetId(), pBuf, 255 ); unserializedGraphicMapping.Insert( pBuf, pGraphic ); } else if ( !Q_stricmp( pType, "CDmeHitAreaGeometry" ) ) { CHitArea *pGraphic = new CHitArea( "" ); if ( !pGraphic->Unserialize( graphics[i] ) ) { delete pGraphic; return false; } m_LayerGraphics.AddToTail( pGraphic );
char pBuf[255]; UniqueIdToString( graphics[i]->GetId(), pBuf, 255 ); unserializedGraphicMapping.Insert( pBuf, pGraphic ); } else { Warning( "CGameUIDefinition: Warning unknown static graphic type\n" ); } }
CDmxAttribute *pTextureName = pLayer->GetAttribute( "statictexture" ); if ( !pTextureName || pTextureName->GetType() != AT_STRING ) { return false; }
char textureName[128]; pTextureName->GetValueAsString( textureName, 128 ); InitSheetTexture( textureName ); } // Dynamic graphics
else if ( m_LayerType == SUBLAYER_DYNAMIC ) { CDmxAttribute *pGraphicsAttr = pLayer->GetAttribute( "dynamicGraphics" ); const CUtlVector< CDmxElement * > &graphics = pGraphicsAttr->GetArray< CDmxElement * >( ); for ( int i = 0; i < graphics.Count(); ++i ) { // What kind of graphic is this?
const char *pType = graphics[i]->GetValueString( "classtype" );
if ( !Q_stricmp( pType, "CDmeDynamicRectGeometry" ) ) { CDynamicRect *pGraphic = new CDynamicRect( "" ); if ( !pGraphic->Unserialize( graphics[i] ) ) { delete pGraphic; return false; } m_LayerGraphics.AddToTail( pGraphic ); char pBuf[255]; UniqueIdToString( graphics[i]->GetId(), pBuf, 255 ); unserializedGraphicMapping.Insert( pBuf, pGraphic ); } else { Warning( "CGameUIDefinition: Warning unknown static graphic type\n" ); } } } // Font graphics
else if ( m_LayerType == SUBLAYER_FONT ) { CDmxAttribute *pGraphics = pLayer->GetAttribute( "fontGraphics" ); const CUtlVector< CDmxElement * > &graphics = pGraphics->GetArray< CDmxElement * >( ); int nCount = graphics.Count(); for ( int i = 0; i < nCount; ++i ) { // What kind of graphic is this?
const char *pType = graphics[i]->GetValueString( "classtype" );
if ( !Q_stricmp( pType, "CDmeTextGeometry" ) ) { CGameText *pGraphic = new CGameText( "" ); if ( !pGraphic->Unserialize( graphics[i] ) ) { delete pGraphic; return false; } m_LayerGraphics.AddToTail( pGraphic ); char pBuf[255]; UniqueIdToString( graphics[i]->GetId(), pBuf, 255 ); GameGraphicMap_t graphicMapEntry; graphicMapEntry.m_Id = graphics[i]->GetId(); graphicMapEntry.pGraphic = pGraphic; unserializedGraphicMapping.Insert( pBuf, pGraphic ); } else { Warning( "CGameUIDefinition: Warning unknown font graphic type in gui file.\n" ); } } } else { Assert(0); // Unknown layer type!!
}
return true; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CGameLayer::InitSheetTexture() { Assert( m_pTextureName ); return InitSheetTexture( m_pTextureName ); }
//-----------------------------------------------------------------------------
// FIXME: Must go into rendersystem at some point
//-----------------------------------------------------------------------------
static HRenderTexture CreateTextureFromVTFFile( const char *pFileName, CSheet **ppSheet ) { static intp s_UniqueID = 0x4000000;
*ppSheet = NULL;
char pTemp[MAX_PATH]; Q_ComposeFileName( "materials/", pFileName, pTemp, sizeof(pTemp) ); Q_SetExtension( pTemp, "vtf", sizeof(pTemp) ); pFileName = pTemp;
char pTemp360[MAX_PATH]; if ( PLATFORM_EXT[0] ) { CreatePlatformFilename( pFileName, pTemp360, sizeof(pTemp360) ); pFileName = pTemp360; } CUtlBuffer fBuf; if ( !g_pFullFileSystem->ReadFile( pFileName, "GAME", fBuf ) ) { Warning( "Unable to read texture file %s\n", pFileName ); return RENDER_TEXTURE_HANDLE_INVALID; }
IVTFTexture *pVtfTexture = CreateVTFTexture(); #if !defined( _GAMECONSOLE )
pVtfTexture->Unserialize( fBuf ); #else
pVtfTexture->UnserializeFromBuffer( fBuf, true, false, false, 0 ); #endif
// we are only going to load the high mip
// pCurData is pointing at pixel data now
TextureHeader_t spec; memset( &spec, 0, sizeof(TextureHeader_t) ); spec.m_nWidth = pVtfTexture->Width(); spec.m_nHeight = pVtfTexture->Height(); spec.m_nNumMipLevels = 1; //pVtfTexture->MipCount();
spec.m_nDepth = pVtfTexture->Depth(); spec.m_nImageFormat = pVtfTexture->Format(); //spec.m_vecAverageColor.Init( pVtfTexture->Reflectivity().x, pVtfTexture->Reflectivity().y, pVtfTexture->Reflectivity().z, 1 );
char pResourceName[16]; Q_snprintf( pResourceName, sizeof(pResourceName), "%d", s_UniqueID ); HRenderTexture hRet = g_pRenderDevice->FindOrCreateTexture( "gamelayer", pResourceName, &spec ); ResourceAddRef( hRet ); s_UniqueID++; IRenderContext *pCtx = g_pRenderDevice->GetRenderContext( ); pCtx->SetTextureData( hRet, &spec, pVtfTexture->ImageData( 0, 0, 0 ), pVtfTexture->ComputeTotalSize(), pVtfTexture->IsPreTiled() ); pCtx->Submit( ); g_pRenderDevice->ReleaseRenderContext( pCtx ); ResourceRelease( hRet );
size_t nSheetByteCount; const void *pSheetData = pVtfTexture->GetResourceData( VTF_RSRC_SHEET, &nSheetByteCount ); if ( pSheetData ) { // expand compact sheet into fatter runtime form
CUtlBuffer bufLoad( pSheetData, nSheetByteCount, CUtlBuffer::READ_ONLY ); *ppSheet = new CSheet( bufLoad ); }
DestroyVTFTexture( pVtfTexture ); return hRet; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CGameLayer::InitSheetTexture( const char *pBaseTextureName ) { m_pTextureName = pBaseTextureName;
if ( !g_pRenderDevice ) { // Material names must be different for each menu.
CFmtStr materialName; switch ( m_LayerType ) { case SUBLAYER_STATIC: materialName.sprintf( "statictx_%s", pBaseTextureName ); break; case SUBLAYER_DYNAMIC: materialName.sprintf( "dynamictx_%s", pBaseTextureName ); break; case SUBLAYER_FONT: materialName.sprintf( "fonttx_%s", pBaseTextureName ); break; default: Assert(0); break; };
KeyValues *pVMTKeyValues = new KeyValues( "GameControls" ); pVMTKeyValues->SetString( "$basetexture", pBaseTextureName ); m_Material.Init( materialName, TEXTURE_GROUP_OTHER, pVMTKeyValues ); m_Material->Refresh(); m_Sheet.Set( LoadSheet( m_Material ) ); } else { CUtlString materialName; switch ( m_LayerType ) { case SUBLAYER_STATIC: CSheet *pSheet; m_hTexture = CreateTextureFromVTFFile( pBaseTextureName, &pSheet ); m_Sheet.Set( pSheet ); break; case SUBLAYER_DYNAMIC: break; case SUBLAYER_FONT: break; default: Assert(0); break; }; }
return true; }
//-----------------------------------------------------------------------------
// UI sheets
//-----------------------------------------------------------------------------
CSheet *CGameLayer::LoadSheet( IMaterial *pMaterial ) { if ( !pMaterial ) return NULL;
bool bFoundVar = false; IMaterialVar *pVar = pMaterial->FindVar( "$basetexture", &bFoundVar, true );
if ( bFoundVar && pVar && pVar->IsDefined() ) { ITexture *pTex = pVar->GetTextureValue(); if ( pTex && !pTex->IsError() ) { return LoadSheet( pTex->GetName(), pTex ); } }
return NULL; }
void CGameLayer::GetSheetTextureSize( int &nWidth, int &nHeight ) { if ( !m_Material ) return;
bool bFoundVar = false; IMaterialVar *pVar = m_Material->FindVar( "$basetexture", &bFoundVar, true );
if ( bFoundVar && pVar && pVar->IsDefined() ) { ITexture *pTex = pVar->GetTextureValue(); if ( pTex && !pTex->IsError() ) { nWidth = pTex->GetActualWidth(); nHeight = pTex->GetActualHeight(); } } }
//--------------------------------------------------------------------------------
// UI sheets
//--------------------------------------------------------------------------------
CSheet *CGameLayer::LoadSheet( char const *pszFname, ITexture *pTexture ) { //if ( !m_bShouldLoadSheets )
// return NULL;
//if ( m_SheetList.Defined( pszFname ) )
// return m_SheetList[ pszFname ];
CSheet *pNewSheet = NULL;
// get compact sheet representation held by texture
size_t numBytes; void const *pSheet = pTexture->GetResourceData( VTF_RSRC_SHEET, &numBytes ); if ( pSheet ) { // expand compact sheet into fatter runtime form
CUtlBuffer bufLoad( pSheet, numBytes, CUtlBuffer::READ_ONLY ); pNewSheet = new CSheet( bufLoad ); }
//m_SheetList[ pszFname ] = pNewSheet;
return pNewSheet; }
//--------------------------------------------------------------------------------
// Add a graphic to the list.
//--------------------------------------------------------------------------------
int CGameLayer::AddGraphic( CGameGraphic *pGraphic ) { return m_LayerGraphics.AddToTail( pGraphic ); }
//--------------------------------------------------------------------------------
// Remove a graphic from the list.
// Returns true if it was found and removed.
//--------------------------------------------------------------------------------
bool CGameLayer::RemoveGraphic( CGameGraphic *pGraphic ) { return m_LayerGraphics.FindAndRemove( pGraphic ); }
//--------------------------------------------------------------------------------
// Clear out the graphics list
//--------------------------------------------------------------------------------
void CGameLayer::ClearGraphics() { m_LayerGraphics.RemoveAll(); }
//--------------------------------------------------------------------------------
// Clear out the graphics list
//--------------------------------------------------------------------------------
bool CGameLayer::HasGraphic( CGameGraphic *pGraphic ) { int nCount = m_LayerGraphics.Count(); for ( int i = 0; i < nCount; ++i ) { if ( pGraphic == m_LayerGraphics[i] ) return true; } return false; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
IMaterial *CGameLayer::GetMaterial() { // FIXME
// NOTE: This has to be this way to ensure we don't load every freaking material @ startup
//Assert( IsPrecached() );
//if ( !IsPrecached() )
// return NULL;
return m_Material; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameLayer::InvalidateSheetSymbol() { m_bSheetSymbolCached = false; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameLayer::CacheSheetSymbol( CUtlSymbol sheetSymbol ) { m_SheetSymbol = sheetSymbol; m_bSheetSymbolCached = true; }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CUtlSymbol CGameLayer::GetSheetSymbol() const { Assert( IsSheetSymbolCached() ); return m_SheetSymbol; }
//-----------------------------------------------------------------------------
// Start playing animations
//-----------------------------------------------------------------------------
void CGameLayer::StartPlaying() { int nCount = m_LayerGraphics.Count(); for ( int i = 0; i < nCount; ++i ) { m_LayerGraphics[i]->StartPlaying(); } }
//-----------------------------------------------------------------------------
// Stop playing animations
//-----------------------------------------------------------------------------
void CGameLayer::StopPlaying() { int nCount = m_LayerGraphics.Count(); for ( int i = 0; i < nCount; ++i ) { m_LayerGraphics[i]->StopPlaying(); } }
//-----------------------------------------------------------------------------
// Move to the next available animation state
//-----------------------------------------------------------------------------
void CGameLayer::AdvanceState() { int nCount = m_LayerGraphics.Count(); for ( int i = 0; i < nCount; ++i ) { m_LayerGraphics[i]->AdvanceState(); } }
//-----------------------------------------------------------------------------
// Set all graphics to "default" state.
//-----------------------------------------------------------------------------
void CGameLayer::InitAnims() { int nCount = m_LayerGraphics.Count(); for ( int i = 0; i < nCount; ++i ) { m_LayerGraphics[i]->SetState( "default" ); } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameLayer::UpdateGeometry() { int nGraphicsCount = m_LayerGraphics.Count(); if ( nGraphicsCount == 0 ) { return; } for ( int i = 0; i < nGraphicsCount; ++i ) { m_LayerGraphics[i]->UpdateGeometry(); } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameLayer::UpdateRenderTransforms( const StageRenderInfo_t &stageRenderInfo ) { int nGraphicsCount = m_LayerGraphics.Count(); if ( nGraphicsCount == 0 ) { return; }
for ( int i = 0; i < nGraphicsCount; ++i ) { m_LayerGraphics[i]->UpdateRenderTransforms( stageRenderInfo ); } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameLayer::UpdateRenderData( CGameUIDefinition &gameUIDef, color32 parentColor, CUtlVector< LayerRenderLists_t > &renderLists ) { bool bDrawExtents = false;
int nGraphicsCount = m_LayerGraphics.Count(); if ( nGraphicsCount == 0 ) { return; } // Basic algorithm is one renderList per material.
// Static graphics are sorted so that they all use the same sheet texture.
// Font graphics are sorted by render order. Their rendergeometry contains the font ID to use
// Dynamic graphics could add renderlists, since the material can change.
// Dynamic graphics will keep adding to the same renderlist until the material's don't match.
// This adds draw calls but preserves render order.
if ( m_LayerType == SUBLAYER_DYNAMIC ) { int listIndex = -1; int layerIndex = -1; for ( int i = 0; i < nGraphicsCount; ++i ) { // Groups should never be in lists of layer graphics.
Assert( !m_LayerGraphics[i]->IsGroup() ); CGraphicGroup *pGroup = m_LayerGraphics[i]->GetGroup(); Assert( pGroup ); // Only dynamic graphics are allowed in dynamic sublayers.
Assert( m_LayerGraphics[i]->IsDynamic() );
// Get the material this graphic uses.
const char *pAlias = m_LayerGraphics[i]->GetMaterialAlias(); IMaterial *pAliasMaterial = g_pGameUISystemMgrImpl->GetImageAliasMaterial( pAlias ); // Is the material this graphic uses the same as the one in our current renderlist?
if ( i == 0 || renderLists[layerIndex].m_pMaterial != pAliasMaterial ) { // Our material has changed. Add a new renderlist for this material.
layerIndex = renderLists.AddToTail(); listIndex = renderLists[layerIndex].m_RenderGeometryLists.AddToTail(); renderLists[layerIndex].m_LayerType = m_LayerType; renderLists[layerIndex].m_pMaterial = pAliasMaterial; renderLists[layerIndex].m_pSheet = NULL; renderLists[layerIndex].m_hTexture = m_hTexture; } CUtlVector< RenderGeometryList_t > &renderGeometryLists = renderLists[layerIndex].m_RenderGeometryLists; Assert( layerIndex != -1 ); Assert( listIndex != -1 ); m_LayerGraphics[i]->UpdateRenderData( pGroup->GetResultantColor(), renderGeometryLists, listIndex ); } } else if ( m_LayerType == SUBLAYER_STATIC ) { int listIndex = -1; int layerIndex = -1;
layerIndex = renderLists.AddToTail(); listIndex = renderLists[layerIndex].m_RenderGeometryLists.AddToTail(); renderLists[layerIndex].m_LayerType = m_LayerType; renderLists[layerIndex].m_pMaterial = m_Material; renderLists[layerIndex].m_pSheet = m_Sheet; renderLists[layerIndex].m_hTexture = m_hTexture;
CUtlVector< RenderGeometryList_t > &renderGeometryLists = renderLists[layerIndex].m_RenderGeometryLists; Assert( layerIndex != -1 ); Assert( listIndex != -1 ); for ( int i = 0; i < nGraphicsCount; ++i ) { // Groups should never be in lists of layer graphics.
Assert( !m_LayerGraphics[i]->IsGroup() ); CGraphicGroup *pGroup = m_LayerGraphics[i]->GetGroup(); Assert( pGroup );
m_LayerGraphics[i]->UpdateRenderData( pGroup->GetResultantColor(), renderGeometryLists, listIndex ); }
if ( bDrawExtents ) { for ( int i = 0; i < nGraphicsCount; ++i ) { if ( !m_LayerGraphics[i]->IsGroup() ) { m_LayerGraphics[i]->DrawExtents( renderGeometryLists, listIndex ); } } } } else if ( m_LayerType == SUBLAYER_FONT ) { int listIndex = -1; int layerIndex = -1;
layerIndex = renderLists.AddToTail(); listIndex = renderLists[layerIndex].m_RenderGeometryLists.AddToTail(); renderLists[layerIndex].m_LayerType = m_LayerType; renderLists[layerIndex].m_pMaterial = m_Material; renderLists[layerIndex].m_pSheet = m_Sheet; renderLists[layerIndex].m_hTexture = m_hTexture;
CUtlVector< RenderGeometryList_t > &renderGeometryLists = renderLists[layerIndex].m_RenderGeometryLists; Assert( layerIndex != -1 ); Assert( listIndex != -1 );
for ( int i = 0; i < nGraphicsCount; ++i ) { // Groups should never be in lists of layer graphics.
Assert( !m_LayerGraphics[i]->IsGroup() ); CGraphicGroup *pGroup = m_LayerGraphics[i]->GetGroup(); Assert( pGroup );
m_LayerGraphics[i]->UpdateRenderData( pGroup->GetResultantColor(), renderGeometryLists, listIndex ); }
if ( bDrawExtents ) { // Find the static material and sheet
for ( int i = 0; i < renderLists.Count(); ++i ) { if ( renderLists[i].m_LayerType == SUBLAYER_STATIC ) { // Make another layer for rendering extents
// Only do this if there is a static texture around to use for rendering.
layerIndex = renderLists.AddToTail(); listIndex = renderLists[layerIndex].m_RenderGeometryLists.AddToTail(); renderLists[layerIndex].m_LayerType = SUBLAYER_STATIC; // must be static since these render as triangles.
renderLists[layerIndex].m_pMaterial = renderLists[i].m_pMaterial; renderLists[layerIndex].m_pSheet = renderLists[i].m_pSheet; renderLists[layerIndex].m_hTexture = renderLists[i].m_hTexture;
CUtlVector< RenderGeometryList_t > &renderGeometryLists2 = renderLists[layerIndex].m_RenderGeometryLists; Assert( layerIndex != -1 ); Assert( listIndex != -1 );
for ( int i = 0; i < nGraphicsCount; ++i ) { CGameText *pText = dynamic_cast<CGameText *>( m_LayerGraphics[i] ); Assert( pText ); pText->DrawExtents( renderGeometryLists2, listIndex ); } break; } } } } }
//-----------------------------------------------------------------------------
// Given a position, return the front most graphic under it.
//-----------------------------------------------------------------------------
CGameGraphic *CGameLayer::GetGraphic( int x, int y ) { int nGraphicCount = m_LayerGraphics.Count(); for ( int i = nGraphicCount-1; i >= 0; --i ) { CGameGraphic *pGraphic = m_LayerGraphics[i]; if ( pGraphic->HitTest( x, y ) ) return pGraphic; }
return NULL; }
//-----------------------------------------------------------------------------
// Given a position, return the front most graphic that can take input under it.
//-----------------------------------------------------------------------------
CGameGraphic *CGameLayer::GetMouseFocus( int x, int y ) { int nGraphicCount = m_LayerGraphics.Count(); for ( int i = nGraphicCount-1; i >= 0; --i ) { CGameGraphic *pGraphic = m_LayerGraphics[i]; if ( pGraphic->CanAcceptInput() && pGraphic->HitTest( x, y ) ) return pGraphic; }
return NULL; }
//-----------------------------------------------------------------------------
// Given a position, return the front most graphic that can take input under it.
//-----------------------------------------------------------------------------
CGameGraphic *CGameLayer::GetNextFocus( bool &bGetNext, CGameGraphic *pCurrentGraphic ) { int nGraphicCount = m_LayerGraphics.Count(); for ( int i = 0; i < nGraphicCount; ++i ) { CGameGraphic *pGraphic = m_LayerGraphics[i];
if ( bGetNext && pGraphic->CanAcceptInput() ) { return pGraphic; }
if ( pCurrentGraphic == pGraphic ) { bGetNext = true; } }
return NULL; }
//-----------------------------------------------------------------------------
// Given a name of a graphic, find it in this layer
//-----------------------------------------------------------------------------
CGameGraphic *CGameLayer::FindGraphicByName( const char *pName ) { int nGraphicCount = m_LayerGraphics.Count(); for ( int i = 0; i < nGraphicCount; ++i ) { CGameGraphic *pGraphic = m_LayerGraphics[i]->FindGraphicByName( pName ); if ( pGraphic ) { // Match.
return pGraphic; } } return NULL; }
|