Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

820 lines
24 KiB

//===== 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;
}