|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#define SUPPORT_CUSTOM_FONT_FORMAT
#ifdef SUPPORT_CUSTOM_FONT_FORMAT
#define _WIN32_WINNT 0x0500
#endif
#include "gameuischeme.h"
#include "gameuisystemsurface.h"
#include "vgui/ISystem.h"
#include "tier1/utlbuffer.h"
#include "gameuisystemmgr.h"
#include "tier1/KeyValues.h"
#include "vgui_surfacelib/fontmanager.h"
#include "vgui/isurface.h"
#include "vgui_controls/controls.h" // has system()
#if defined( _X360 )
#include "xbox/xbox_win32stubs.h"
#endif
#include "xbox/xboxstubs.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define FONT_ALIAS_NAME_LENGTH 64
CGameUISchemeManager g_GameUISchemeManager; CGameUISchemeManager *g_pGameUISchemeManager = &g_GameUISchemeManager;
//-----------------------------------------------------------------------------
// Helper function for getting the language the game ui should use.
//-----------------------------------------------------------------------------
static void HelperGetLanguage( char *pLanguageBuf, int bufSize ) { bool bValid = false; if ( IsPC() ) { bValid = vgui::system()->GetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\Language", pLanguageBuf, bufSize - 1 ); } else { Q_strncpy( pLanguageBuf, XBX_GetLanguageString(), bufSize ); bValid = true; }
if ( !bValid ) { Q_strncpy( pLanguageBuf, "english", bufSize ); } }
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CGameUISchemeManager::CGameUISchemeManager() { // 0th element is null, since that would be an invalid handle
CGameUIScheme *nullScheme = new CGameUIScheme(); m_Schemes.AddToTail(nullScheme); Assert( g_pGameUISystemSurface ); }
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CGameUISchemeManager::~CGameUISchemeManager() { int i; for ( i = 0; i < m_Schemes.Count(); i++ ) { delete m_Schemes[i]; m_Schemes[i] = NULL; } m_Schemes.RemoveAll();
Shutdown( false ); }
//-----------------------------------------------------------------------------
// Purpose: Reloads the schemes from the files
//-----------------------------------------------------------------------------
void CGameUISchemeManager::ReloadSchemes() { int count = m_Schemes.Count(); Shutdown( false ); // reload the scheme
for (int i = 1; i < count; i++) { LoadSchemeFromFile( m_Schemes[i]->GetFileName(), m_Schemes[i]->GetName() ); } }
//-----------------------------------------------------------------------------
// Purpose: Reload the fonts in all schemes
//-----------------------------------------------------------------------------
void CGameUISchemeManager::ReloadFonts( int inScreenTall ) { for (int i = 1; i < m_Schemes.Count(); i++) { m_Schemes[i]->ReloadFontGlyphs( inScreenTall ); } }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CGameUISchemeManager::Shutdown( bool full ) { // Full shutdown kills the null scheme
for( int i = full ? 0 : 1; i < m_Schemes.Count(); i++ ) { m_Schemes[i]->Shutdown( full ); }
if ( full ) { m_Schemes.RemoveAll(); } }
//-----------------------------------------------------------------------------
// Purpose: Find an already loaded scheme
//-----------------------------------------------------------------------------
IGameUIScheme * CGameUISchemeManager::FindLoadedScheme( const char *pFilename ) { // Find the scheme in the list of already loaded schemes
for ( int i = 1; i < m_Schemes.Count(); i++ ) { char const *schemeFileName = m_Schemes[i]->GetFileName(); if ( !stricmp( schemeFileName, pFilename ) ) return m_Schemes[i]; }
return NULL; }
//-----------------------------------------------------------------------------
// First scheme loaded becomes the default scheme,
// and all subsequent loaded scheme are derivatives of that
//-----------------------------------------------------------------------------
IGameUIScheme * CGameUISchemeManager::LoadSchemeFromFileEx( const char *pFilename, const char *tag ) { // Look to see if we've already got this scheme...
CGameUIScheme * hScheme = ( CGameUIScheme * ) FindLoadedScheme( pFilename ); if ( hScheme ) { if ( hScheme->IsActive() ) { if ( IsPC() ) { hScheme->ReloadFontGlyphs(); } return hScheme; } } else { hScheme = new CGameUIScheme(); m_Schemes.AddToTail( hScheme ); }
KeyValues *data; data = new KeyValues("Scheme");
data->UsesEscapeSequences( true ); // VGUI uses this
// look first in skins directory
bool result = data->LoadFromFile( g_pFullFileSystem, pFilename, "SKIN" ); if (!result) { result = data->LoadFromFile( g_pFullFileSystem, pFilename, "GAME" ); if ( !result ) { // look in any directory
result = data->LoadFromFile( g_pFullFileSystem, pFilename, NULL ); } }
if (!result) { data->deleteThis(); return 0; } if ( IsPC() ) { ConVarRef cl_hud_minmode( "cl_hud_minmode", true ); if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() ) { data->ProcessResolutionKeys( "_minmode" ); } }
hScheme->SetActive( true ); hScheme->LoadFromFile( pFilename, tag, data );
return hScheme; }
//-----------------------------------------------------------------------------
// Purpose: loads a scheme from disk
//-----------------------------------------------------------------------------
IGameUIScheme * CGameUISchemeManager::LoadSchemeFromFile( const char *fileName, const char *tag ) { return LoadSchemeFromFileEx( fileName, tag ); }
//-----------------------------------------------------------------------------
// Purpose: returns a handle to the default (first loaded) scheme
//-----------------------------------------------------------------------------
IGameUIScheme * CGameUISchemeManager::GetDefaultScheme() { if ( m_Schemes.Count() >= 2 ) return m_Schemes[1]; else if ( m_Schemes.Count() > 0 ) return m_Schemes[0]; else return NULL; }
//-----------------------------------------------------------------------------
// Purpose: returns a handle to the scheme identified by "tag"
//-----------------------------------------------------------------------------
IGameUIScheme * CGameUISchemeManager::GetScheme( const char *tag ) { for ( int i=1; i<m_Schemes.Count(); i++ ) { if ( !stricmp( tag, m_Schemes[i]->GetName() ) ) { return m_Schemes[i]; } } return GetDefaultScheme(); // default scheme
}
//-----------------------------------------------------------------------------
// gets the proportional coordinates for doing screen-size independant panel layouts
// use these for font, image and panel size scaling (they all use the pixel height of the display for scaling)
//-----------------------------------------------------------------------------
int CGameUISchemeManager::GetProportionalScaledValueEx( CGameUIScheme *pScheme, int normalizedValue, int screenTall ) { return GetProportionalScaledValue( normalizedValue, screenTall ); }
//-----------------------------------------------------------------------------
// Purpose: converts a value into proportional mode
//-----------------------------------------------------------------------------
int CGameUISchemeManager::GetProportionalScaledValue( int normalizedValue, int screenTall ) { int tall; if ( screenTall == -1 ) { g_pGameUISystemMgrImpl->GetScreenHeightForFontLoading( tall ); } else { tall = screenTall; } return GetProportionalScaledValue_( tall, normalizedValue ); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CGameUISchemeManager::GetProportionalScaledValue_( int screenTall, int normalizedValue ) { int baseWide, baseTall; g_pGameUISystemSurface->GetProportionalBase( baseWide, baseTall ); double scale = (double)screenTall / (double)baseTall;
return (int)( normalizedValue * scale ); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameUISchemeManager::SpewFonts( void ) { for ( int i = 1; i < m_Schemes.Count(); i++ ) { m_Schemes[i]->SpewFonts(); } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameUISchemeManager::SetLanguage( const char *pLanguage ) { g_pGameUISystemSurface->SetLanguage( pLanguage ); }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
const char *CGameUISchemeManager::GetLanguage() { return g_pGameUISystemSurface->GetLanguage(); }
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CGameUIScheme::CGameUIScheme() { m_pFileName = ""; m_pTag = ""; m_pData = NULL; SetActive( false ); }
CGameUIScheme::~CGameUIScheme() { }
//-----------------------------------------------------------------------------
// Purpose: loads a scheme from from disk into memory
//-----------------------------------------------------------------------------
void CGameUIScheme::LoadFromFile( const char *pFilename, const char *inTag, KeyValues *inKeys ) { COM_TimestampedLog( "CScheme::LoadFromFile( %s )", pFilename );
m_pFileName = pFilename; m_pData = inKeys;
// override the scheme name with the tag name
KeyValues *name = m_pData->FindKey( "Name", true ); name->SetString("Name", inTag);
if ( inTag ) { m_pTag = inTag; } else { Error( "You need to name the scheme (%s)!", m_pFileName.Get() ); m_pTag = "default"; }
LoadFonts(); }
//-----------------------------------------------------------------------------
// Purpose: Set the range of character values this font can be used on
//-----------------------------------------------------------------------------
bool CGameUIScheme::GetFontRange( const char *fontname, int &nMin, int &nMax ) { for ( int i = 0 ; i < m_FontRanges.Count() ; i++ ) { if ( Q_stricmp( m_FontRanges[i]._fontName.String(), fontname ) == 0 ) { nMin = m_FontRanges[i]._min; nMax = m_FontRanges[i]._max; return true; } }
return false; }
//-----------------------------------------------------------------------------
// Purpose: Get the range of character values this font can be used on
//-----------------------------------------------------------------------------
void CGameUIScheme::SetFontRange( const char *fontname, int nMin, int nMax ) { for ( int i = 0 ; i < m_FontRanges.Count() ; i++ ) { if ( Q_stricmp( m_FontRanges[i]._fontName.String(), fontname ) == 0 ) { m_FontRanges[i]._min = nMin; m_FontRanges[i]._max = nMax;
return; } }
// not already in our list
int iIndex = m_FontRanges.AddToTail(); m_FontRanges[iIndex]._fontName = fontname; m_FontRanges[iIndex]._min = nMin; m_FontRanges[iIndex]._max = nMax; }
//-----------------------------------------------------------------------------
// Purpose: adds all the font specifications to the surface
//-----------------------------------------------------------------------------
void CGameUIScheme::LoadFonts() { // get our language
const char *pLanguage = g_GameUISchemeManager.GetLanguage();
// add our custom fonts
for ( KeyValues *kv = m_pData->FindKey("CustomFontFiles", true)->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey() ) { const char *fontFile = kv->GetString(); if (fontFile && *fontFile) { g_pGameUISystemSurface->AddCustomFontFile( fontFile ); } else { // we have a block to read
int nRangeMin = 0, nRangeMax = 0; const char *pszName = NULL; bool bUseRange = false;
for ( KeyValues *pData = kv->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() ) { const char *pszKey = pData->GetName(); if ( !Q_stricmp( pszKey, "font" ) ) { fontFile = pData->GetString(); } else if ( !Q_stricmp( pszKey, "name" ) ) { pszName = pData->GetString(); } else { // we must have a language
if ( Q_stricmp( pLanguage, pszKey ) == 0 ) // matches the language we're running?
{ // get the range
KeyValues *pRange = pData->FindKey( "range" ); if ( pRange ) { bUseRange = true; sscanf( pRange->GetString(), "%x %x", &nRangeMin, &nRangeMax );
if ( nRangeMin > nRangeMax ) { int nTemp = nRangeMin; nRangeMin = nRangeMax; nRangeMax = nTemp; } } } } }
if ( fontFile && *fontFile ) { g_pGameUISystemSurface->AddCustomFontFile( fontFile );
if ( bUseRange ) { SetFontRange( pszName, nRangeMin, nRangeMax ); } } } }
// add bitmap fonts
for ( KeyValues *kv = m_pData->FindKey("BitmapFontFiles", true)->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey() ) { const char *fontFile = kv->GetString(); if (fontFile && *fontFile) { bool bSuccess = g_pGameUISystemSurface->AddBitmapFontFile( fontFile ); if ( bSuccess ) { // refer to the font by a user specified symbol
g_pGameUISystemSurface->SetBitmapFontName( kv->GetName(), fontFile ); } } }
// create the fonts
for (KeyValues *kv = m_pData->FindKey("Fonts", true)->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey()) { for ( int i = 0; i < 2; i++ ) { // create the base font
bool proportionalFont = i ? true : false; const char *fontName = GetMungedFontName( kv->GetName(), m_pTag.Get(), proportionalFont ); // first time it adds a normal font, and then a proportional one
FontHandle_t font = g_pGameUISystemSurface->CreateFont(); int j = m_FontAliases.AddToTail(); m_FontAliases[j]._fontName = fontName; m_FontAliases[j]._trueFontName = kv->GetName(); m_FontAliases[j]._font = font; m_FontAliases[j].m_bProportional = proportionalFont; } }
// load in the font glyphs
ReloadFontGlyphs(); }
//-----------------------------------------------------------------------------
// Purpose: Reloads all scheme fonts
// Supply a language if you don't want to use the one in the registry.
//-----------------------------------------------------------------------------
void CGameUIScheme::ReloadFontGlyphs( int inScreenTall ) { int screenTall; // get our current resolution
if ( inScreenTall == -1 ) { //int screenWide;
g_pGameUISystemMgrImpl->GetScreenHeightForFontLoading( screenTall ); } else // this will make fonts be the correct size in the editor, where the stage size is the screen size.
{ screenTall = inScreenTall; } // check our language; some have minimum sizes
int minimumFontHeight = GetMinimumFontHeightForCurrentLanguage( g_GameUISchemeManager.GetLanguage() );
// add the data to all the fonts
KeyValues *fonts = m_pData->FindKey( "Fonts", true ); for (int i = 0; i < m_FontAliases.Count(); i++) { KeyValues *kv = fonts->FindKey( m_FontAliases[i]._trueFontName.String(), true ); // walk through creating adding the first matching glyph set to the font
for ( KeyValues *fontdata = kv->GetFirstSubKey(); fontdata != NULL; fontdata = fontdata->GetNextKey() ) { // skip over fonts not meant for this resolution
int fontYResMin = 0, fontYResMax = 0; sscanf( fontdata->GetString( "yres", "" ), "%d %d", &fontYResMin, &fontYResMax ); if ( fontYResMin ) { if ( !fontYResMax ) { fontYResMax = fontYResMin; } // check the range
if ( screenTall < fontYResMin || screenTall > fontYResMax ) continue; }
int flags = 0; if (fontdata->GetInt( "italic" )) { flags |= FONTFLAG_ITALIC; } if (fontdata->GetInt( "underline" )) { flags |= FONTFLAG_UNDERLINE; } if (fontdata->GetInt( "strikeout" )) { flags |= FONTFLAG_STRIKEOUT; } if (fontdata->GetInt( "symbol" )) { flags |= FONTFLAG_SYMBOL; } if (fontdata->GetInt( "antialias" ) && g_pGameUISystemSurface->SupportsFontFeature( FONT_FEATURE_ANTIALIASED_FONTS ) ) { flags |= FONTFLAG_ANTIALIAS; } if (fontdata->GetInt( "dropshadow" ) && g_pGameUISystemSurface->SupportsFontFeature( FONT_FEATURE_DROPSHADOW_FONTS ) ) { flags |= FONTFLAG_DROPSHADOW; } if (fontdata->GetInt( "outline" ) && g_pGameUISystemSurface->SupportsFontFeature( FONT_FEATURE_OUTLINE_FONTS ) ) { flags |= FONTFLAG_OUTLINE; } if (fontdata->GetInt( "custom" )) { flags |= FONTFLAG_CUSTOM; } if (fontdata->GetInt( "bitmap" )) { flags |= FONTFLAG_BITMAP; } if (fontdata->GetInt( "rotary" )) { flags |= FONTFLAG_ROTARY; } if (fontdata->GetInt( "additive" )) { flags |= FONTFLAG_ADDITIVE; }
int fontTall = fontdata->GetInt( "tall" ); int blur = fontdata->GetInt( "blur" ); int scanlines = fontdata->GetInt( "scanlines" ); float scalex = fontdata->GetFloat( "scalex", 1.0f ); float scaley = fontdata->GetFloat( "scaley", 1.0f );
// only grow this font if it doesn't have a resolution filter specified
if ( ( !fontYResMin && !fontYResMax ) && m_FontAliases[i].m_bProportional ) { fontTall = g_GameUISchemeManager.GetProportionalScaledValueEx( this, fontTall, screenTall ); blur = g_GameUISchemeManager.GetProportionalScaledValueEx( this, blur ); scanlines = g_GameUISchemeManager.GetProportionalScaledValueEx( this, scanlines ); scalex = g_GameUISchemeManager.GetProportionalScaledValueEx( this, scalex * 10000.0f ) * 0.0001f; scaley = g_GameUISchemeManager.GetProportionalScaledValueEx( this, scaley * 10000.0f ) * 0.0001f; }
// clip the font size so that fonts can't be too big
if ( fontTall > 127 ) { fontTall = 127; }
// check our minimum font height
if ( fontTall < minimumFontHeight ) { fontTall = minimumFontHeight; } if ( flags & FONTFLAG_BITMAP ) { // add the new set
g_pGameUISystemSurface->SetBitmapFontGlyphSet( m_FontAliases[i]._font, g_pGameUISystemSurface->GetBitmapFontName( fontdata->GetString( "name" ) ), scalex, scaley, flags); } else { int nRangeMin, nRangeMax; if ( GetFontRange( fontdata->GetString( "name" ), nRangeMin, nRangeMax ) ) { // add the new set
g_pGameUISystemSurface->SetFontGlyphSet( m_FontAliases[i]._font, fontdata->GetString( "name" ), fontTall, fontdata->GetInt( "weight" ), blur, scanlines, flags, nRangeMin, nRangeMax); } else { // add the new set
g_pGameUISystemSurface->SetFontGlyphSet( m_FontAliases[i]._font, fontdata->GetString( "name" ), fontTall, fontdata->GetInt( "weight" ), blur, scanlines, flags); } }
// don't add any more
break; } } }
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameUIScheme::SpewFonts( void ) { Msg( "Game UI Scheme: %s (%s)\n", GetName(), GetFileName() ); for ( int i = 0; i < m_FontAliases.Count(); i++ ) { Msg( " %2d: HFont:0x%8.8x, %s, %s, font:%s, tall:%d\n", i, m_FontAliases[i]._font, m_FontAliases[i]._trueFontName.String(), m_FontAliases[i]._fontName.String(), g_pGameUISystemSurface->GetFontName( m_FontAliases[i]._font ), g_pGameUISystemSurface->GetFontTall( m_FontAliases[i]._font ) ); } }
//-----------------------------------------------------------------------------
// Purpose: Kills the scheme
//-----------------------------------------------------------------------------
void CGameUIScheme::Shutdown( bool full ) { SetActive( false );
m_FontRanges.RemoveAll();
if (m_pData) { m_pData->deleteThis(); m_pData = NULL; }
if ( full ) { delete this; } }
//-----------------------------------------------------------------------------
// Finds a font in the alias list
//-----------------------------------------------------------------------------
FontHandle_t CGameUIScheme::FindFontInAliasList( const char *fontName ) { // FIXME: Slow!!!
for (int i = m_FontAliases.Count(); --i >= 0; ) { if ( !strnicmp( fontName, m_FontAliases[i]._fontName.String(), FONT_ALIAS_NAME_LENGTH ) ) return m_FontAliases[i]._font; }
// No dice
return 0; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : font -
// Output : char const
//-----------------------------------------------------------------------------
char const *CGameUIScheme::GetFontName( const FontHandle_t &font ) { for (int i = m_FontAliases.Count(); --i >= 0; ) { FontHandle_t fnt = ( FontHandle_t )m_FontAliases[i]._font; if ( fnt == font ) return m_FontAliases[i]._trueFontName.String(); }
return "<Unknown font>"; }
//-----------------------------------------------------------------------------
// material Setting methods
//-----------------------------------------------------------------------------
FontHandle_t CGameUIScheme::GetFont( const char *fontName, bool proportional ) { // First look in the list of aliases...
return FindFontInAliasList( GetMungedFontName( fontName, m_pTag.Get(), proportional ) ); }
//-----------------------------------------------------------------------------
// Return the vgui name of the font that is the same truefont name and one size up.
// bUp is if true you want the next size up or the next size down.
//-----------------------------------------------------------------------------
FontHandle_t CGameUIScheme::GetFontNextSize( bool bUp, const char *fontName, bool proportional ) { FontHandle_t currentFontHandle = GetFont( fontName, proportional ); // Current font name wasn't found.
if ( currentFontHandle == 0 ) { return currentFontHandle; }
int currentFontTall = g_pGameUISystemSurface->GetFontTall( currentFontHandle ); const char* pCurrentFontName = g_pGameUISystemSurface->GetFontName( currentFontHandle );
// Now find the closest font with this name that is the smallest size up
int sizeDifference = INT_MAX; FontHandle_t closestFontHandle = 0; for (int i = m_FontAliases.Count(); --i > 0; ) { if ( proportional != m_FontAliases[i].m_bProportional ) continue;
FontHandle_t testFontHandle = m_FontAliases[i]._font; const char* pTestFontName = g_pGameUISystemSurface->GetFontName( testFontHandle ); if ( currentFontHandle != testFontHandle ) { if ( !Q_stricmp( pCurrentFontName, pTestFontName ) ) // font name is the same.
{ int thisFontTall = g_pGameUISystemSurface->GetFontTall( testFontHandle ); int diff; if ( bUp ) // get next size up
{ diff = thisFontTall - currentFontTall; } else // get next size down.
{ diff = currentFontTall - thisFontTall; }
if ( diff > 0 && diff < sizeDifference ) { sizeDifference = diff; closestFontHandle = testFontHandle; } } } }
if ( closestFontHandle != 0 ) { return closestFontHandle; } else { return currentFontHandle; } }
//-----------------------------------------------------------------------------
// Purpose: returns a char string of the munged name this font is stored as in the font manager
//-----------------------------------------------------------------------------
const char *CGameUIScheme::GetMungedFontName( const char *fontName, const char *scheme, bool proportional ) { static char mungeBuffer[ 64 ]; if ( scheme ) { Q_snprintf( mungeBuffer, sizeof( mungeBuffer ), "%s%s-%s", fontName, scheme, proportional ? "p" : "no" ); } else { Q_snprintf( mungeBuffer, sizeof( mungeBuffer ), "%s-%s", fontName, proportional ? "p" : "no" ); // we don't want the "(null)" snprintf appends
} return mungeBuffer; }
//-----------------------------------------------------------------------------
// Purpose: gets the minimum font height for the current language
//-----------------------------------------------------------------------------
int CGameUIScheme::GetMinimumFontHeightForCurrentLanguage( const char *pLanguage ) { char language[64]; bool bValid; if ( IsPC() ) { if ( pLanguage ) { Q_strncpy( language, pLanguage, sizeof(language)-1 ); bValid = true; } else { bValid = vgui::system()->GetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\Language", language, sizeof(language)-1 ); } } else { Q_strncpy( language, XBX_GetLanguageString(), sizeof( language ) ); bValid = true; }
if ( bValid ) { if (!stricmp(language, "korean") || !stricmp(language, "koreana") || !stricmp(language, "tchinese") || !stricmp(language, "schinese") || !stricmp(language, "japanese")) { // the bitmap-based fonts for these languages simply don't work with a pt. size of less than 9 (13 pixels)
return 13; }
if ( !stricmp(language, "thai" ) ) { // thai has problems below 18 pts
return 18; } }
// no special minimum height required
return 0; }
void CGameUIScheme::SetActive( bool bActive ) { m_bActive = bActive; }
bool CGameUIScheme::IsActive() const { return m_bActive; }
|