diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /vstdlib/cvar.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'vstdlib/cvar.cpp')
| -rw-r--r-- | vstdlib/cvar.cpp | 899 |
1 files changed, 899 insertions, 0 deletions
diff --git a/vstdlib/cvar.cpp b/vstdlib/cvar.cpp new file mode 100644 index 0000000..72aca7b --- /dev/null +++ b/vstdlib/cvar.cpp @@ -0,0 +1,899 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// + +#include "vstdlib/cvar.h" +#include <ctype.h> +#include "tier0/icommandline.h" +#include "tier1/utlrbtree.h" +#include "tier1/strtools.h" +#include "tier1/KeyValues.h" +#include "tier1/convar.h" +#include "tier0/vprof.h" +#include "tier1/tier1.h" +#include "tier1/utlbuffer.h" + +#ifdef _X360 +#include "xbox/xbox_console.h" +#endif + +#ifdef POSIX +#include <wctype.h> +#include <wchar.h> +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Default implementation of CvarQuery +//----------------------------------------------------------------------------- +class CDefaultCvarQuery : public CBaseAppSystem< ICvarQuery > +{ +public: + virtual void *QueryInterface( const char *pInterfaceName ) + { + if ( !Q_stricmp( pInterfaceName, CVAR_QUERY_INTERFACE_VERSION ) ) + return (ICvarQuery*)this; + return NULL; + + } + + virtual bool AreConVarsLinkable( const ConVar *child, const ConVar *parent ) + { + return true; + } +}; + +static CDefaultCvarQuery s_DefaultCvarQuery; +static ICvarQuery *s_pCVarQuery = NULL; + + +//----------------------------------------------------------------------------- +// Default implementation +//----------------------------------------------------------------------------- +class CCvar : public ICvar +{ +public: + CCvar(); + + // Methods of IAppSystem + virtual bool Connect( CreateInterfaceFn factory ); + virtual void Disconnect(); + virtual void *QueryInterface( const char *pInterfaceName ); + virtual InitReturnVal_t Init(); + virtual void Shutdown(); + + // Inherited from ICVar + virtual CVarDLLIdentifier_t AllocateDLLIdentifier(); + virtual void RegisterConCommand( ConCommandBase *pCommandBase ); + virtual void UnregisterConCommand( ConCommandBase *pCommandBase ); + virtual void UnregisterConCommands( CVarDLLIdentifier_t id ); + virtual const char* GetCommandLineValue( const char *pVariableName ); + virtual ConCommandBase *FindCommandBase( const char *name ); + virtual const ConCommandBase *FindCommandBase( const char *name ) const; + virtual ConVar *FindVar ( const char *var_name ); + virtual const ConVar *FindVar ( const char *var_name ) const; + virtual ConCommand *FindCommand( const char *name ); + virtual const ConCommand *FindCommand( const char *name ) const; + virtual ConCommandBase *GetCommands( void ); + virtual const ConCommandBase *GetCommands( void ) const; + virtual void InstallGlobalChangeCallback( FnChangeCallback_t callback ); + virtual void RemoveGlobalChangeCallback( FnChangeCallback_t callback ); + virtual void CallGlobalChangeCallbacks( ConVar *var, const char *pOldString, float flOldValue ); + virtual void InstallConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ); + virtual void RemoveConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ); + virtual void ConsoleColorPrintf( const Color& clr, const char *pFormat, ... ) const; + virtual void ConsolePrintf( const char *pFormat, ... ) const; + virtual void ConsoleDPrintf( const char *pFormat, ... ) const; + virtual void RevertFlaggedConVars( int nFlag ); + virtual void InstallCVarQuery( ICvarQuery *pQuery ); + +#if defined( _X360 ) + virtual void PublishToVXConsole( ); +#endif + + virtual bool IsMaterialThreadSetAllowed( ) const; + virtual void QueueMaterialThreadSetValue( ConVar *pConVar, const char *pValue ); + virtual void QueueMaterialThreadSetValue( ConVar *pConVar, int nValue ); + virtual void QueueMaterialThreadSetValue( ConVar *pConVar, float flValue ); + virtual bool HasQueuedMaterialThreadConVarSets() const; + virtual int ProcessQueuedMaterialThreadConVarSets(); +private: + enum + { + CONSOLE_COLOR_PRINT = 0, + CONSOLE_PRINT, + CONSOLE_DPRINT, + }; + + void DisplayQueuedMessages( ); + + CUtlVector< FnChangeCallback_t > m_GlobalChangeCallbacks; + CUtlVector< IConsoleDisplayFunc* > m_DisplayFuncs; + int m_nNextDLLIdentifier; + ConCommandBase *m_pConCommandList; + + // temporary console area so we can store prints before console display funs are installed + mutable CUtlBuffer m_TempConsoleBuffer; +protected: + + // internals for ICVarIterator + class CCVarIteratorInternal : public ICVarIteratorInternal + { + public: + CCVarIteratorInternal( CCvar *outer ) + : m_pOuter( outer ) + //, m_pHash( &outer->m_CommandHash ), // remember my CCvar, + //m_hashIter( -1, -1 ) // and invalid iterator + , m_pCur( NULL ) + {} + virtual void SetFirst( void ); + virtual void Next( void ); + virtual bool IsValid( void ); + virtual ConCommandBase *Get( void ); + protected: + CCvar * const m_pOuter; + //CConCommandHash * const m_pHash; + //CConCommandHash::CCommandHashIterator_t m_hashIter; + ConCommandBase *m_pCur; + }; + + virtual ICVarIteratorInternal *FactoryInternalIterator( void ); + friend class CCVarIteratorInternal; + + enum ConVarSetType_t + { + CONVAR_SET_STRING = 0, + CONVAR_SET_INT, + CONVAR_SET_FLOAT, + }; + struct QueuedConVarSet_t + { + ConVar *m_pConVar; + ConVarSetType_t m_nType; + int m_nInt; + float m_flFloat; + CUtlString m_String; + }; + CUtlVector< QueuedConVarSet_t > m_QueuedConVarSets; + bool m_bMaterialSystemThreadSetAllowed; + +private: + // Standard console commands -- DO NOT PLACE ANY HIGHER THAN HERE BECAUSE THESE MUST BE THE FIRST TO DESTRUCT + CON_COMMAND_MEMBER_F( CCvar, "find", Find, "Find concommands with the specified string in their name/help text.", 0 ) +}; + +void CCvar::CCVarIteratorInternal::SetFirst( void ) RESTRICT +{ + //m_hashIter = m_pHash->First(); + m_pCur = m_pOuter->GetCommands(); +} + +void CCvar::CCVarIteratorInternal::Next( void ) RESTRICT +{ + //m_hashIter = m_pHash->Next( m_hashIter ); + if ( m_pCur ) + m_pCur = m_pCur->GetNext(); +} + +bool CCvar::CCVarIteratorInternal::IsValid( void ) RESTRICT +{ + //return m_pHash->IsValidIterator( m_hashIter ); + return m_pCur != NULL; +} + +ConCommandBase *CCvar::CCVarIteratorInternal::Get( void ) RESTRICT +{ + Assert( IsValid( ) ); + //return (*m_pHash)[m_hashIter]; + return m_pCur; +} + +ICvar::ICVarIteratorInternal *CCvar::FactoryInternalIterator( void ) +{ + return new CCVarIteratorInternal( this ); +} + +//----------------------------------------------------------------------------- +// Factor for CVars +//----------------------------------------------------------------------------- +static CCvar s_Cvar; +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CCvar, ICvar, CVAR_INTERFACE_VERSION, s_Cvar ); + + +//----------------------------------------------------------------------------- +// Returns a CVar dictionary for tool usage +//----------------------------------------------------------------------------- +CreateInterfaceFn VStdLib_GetICVarFactory() +{ + return Sys_GetFactoryThis(); +} + + +//----------------------------------------------------------------------------- +// Constructor +//----------------------------------------------------------------------------- +CCvar::CCvar() : m_TempConsoleBuffer( 0, 1024 ) +{ + m_nNextDLLIdentifier = 0; + m_pConCommandList = NULL; + + m_bMaterialSystemThreadSetAllowed = false; +} + + +//----------------------------------------------------------------------------- +// Methods of IAppSystem +//----------------------------------------------------------------------------- +bool CCvar::Connect( CreateInterfaceFn factory ) +{ + ConnectTier1Libraries( &factory, 1 ); + + s_pCVarQuery = (ICvarQuery*)factory( CVAR_QUERY_INTERFACE_VERSION, NULL ); + if ( !s_pCVarQuery ) + { + s_pCVarQuery = &s_DefaultCvarQuery; + } + + ConVar_Register(); + return true; +} + +void CCvar::Disconnect() +{ + ConVar_Unregister(); + s_pCVarQuery = NULL; + DisconnectTier1Libraries(); +} + +InitReturnVal_t CCvar::Init() +{ + return INIT_OK; +} + +void CCvar::Shutdown() +{ +} + +void *CCvar::QueryInterface( const char *pInterfaceName ) +{ + // We implement the ICvar interface + if ( !V_strcmp( pInterfaceName, CVAR_INTERFACE_VERSION ) ) + return (ICvar*)this; + + return NULL; +} + + +//----------------------------------------------------------------------------- +// Method allowing the engine ICvarQuery interface to take over +//----------------------------------------------------------------------------- +void CCvar::InstallCVarQuery( ICvarQuery *pQuery ) +{ + Assert( s_pCVarQuery == &s_DefaultCvarQuery ); + s_pCVarQuery = pQuery ? pQuery : &s_DefaultCvarQuery; +} + + +//----------------------------------------------------------------------------- +// Used by DLLs to be able to unregister all their commands + convars +//----------------------------------------------------------------------------- +CVarDLLIdentifier_t CCvar::AllocateDLLIdentifier() +{ + return m_nNextDLLIdentifier++; +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *variable - +//----------------------------------------------------------------------------- +void CCvar::RegisterConCommand( ConCommandBase *variable ) +{ + // Already registered + if ( variable->IsRegistered() ) + return; + + variable->m_bRegistered = true; + + const char *pName = variable->GetName(); + if ( !pName || !pName[0] ) + { + variable->m_pNext = NULL; + return; + } + + // If the variable is already defined, then setup the new variable as a proxy to it. + const ConCommandBase *pOther = FindVar( variable->GetName() ); + if ( pOther ) + { + if ( variable->IsCommand() || pOther->IsCommand() ) + { + Warning( "WARNING: unable to link %s and %s because one or more is a ConCommand.\n", variable->GetName(), pOther->GetName() ); + } + else + { + // This cast is ok because we make sure they're ConVars above. + const ConVar *pChildVar = static_cast< const ConVar* >( variable ); + const ConVar *pParentVar = static_cast< const ConVar* >( pOther ); + + // See if it's a valid linkage + if ( s_pCVarQuery->AreConVarsLinkable( pChildVar, pParentVar ) ) + { + // Make sure the default values are the same (but only spew about this for FCVAR_REPLICATED) + if( pChildVar->m_pszDefaultValue && pParentVar->m_pszDefaultValue && + pChildVar->IsFlagSet( FCVAR_REPLICATED ) && pParentVar->IsFlagSet( FCVAR_REPLICATED ) ) + { + if( Q_stricmp( pChildVar->m_pszDefaultValue, pParentVar->m_pszDefaultValue ) != 0 ) + { + Warning( "Parent and child ConVars with different default values! %s child: %s parent: %s (parent wins)\n", + variable->GetName(), pChildVar->m_pszDefaultValue, pParentVar->m_pszDefaultValue ); + } + } + + const_cast<ConVar*>( pChildVar )->m_pParent = const_cast<ConVar*>( pParentVar )->m_pParent; + + // Absorb material thread related convar flags + const_cast<ConVar*>( pParentVar )->m_nFlags |= pChildVar->m_nFlags & ( FCVAR_MATERIAL_THREAD_MASK | FCVAR_ACCESSIBLE_FROM_THREADS ); + + // check the parent's callbacks and slam if doesn't have, warn if both have callbacks + if( pChildVar->m_fnChangeCallback ) + { + if ( !pParentVar->m_fnChangeCallback ) + { + const_cast<ConVar*>( pParentVar )->m_fnChangeCallback = pChildVar->m_fnChangeCallback; + } + else + { + Warning( "Convar %s has multiple different change callbacks\n", variable->GetName() ); + } + } + + // make sure we don't have conflicting help strings. + if ( pChildVar->m_pszHelpString && Q_strlen( pChildVar->m_pszHelpString ) != 0 ) + { + if ( pParentVar->m_pszHelpString && Q_strlen( pParentVar->m_pszHelpString ) != 0 ) + { + if ( Q_stricmp( pParentVar->m_pszHelpString, pChildVar->m_pszHelpString ) != 0 ) + { + Warning( "Convar %s has multiple help strings:\n\tparent (wins): \"%s\"\n\tchild: \"%s\"\n", + variable->GetName(), pParentVar->m_pszHelpString, pChildVar->m_pszHelpString ); + } + } + else + { + const_cast<ConVar *>( pParentVar )->m_pszHelpString = pChildVar->m_pszHelpString; + } + } + + // make sure we don't have conflicting FCVAR_CHEAT flags. + if ( ( pChildVar->m_nFlags & FCVAR_CHEAT ) != ( pParentVar->m_nFlags & FCVAR_CHEAT ) ) + { + Warning( "Convar %s has conflicting FCVAR_CHEAT flags (child: %s, parent: %s, parent wins)\n", + variable->GetName(), ( pChildVar->m_nFlags & FCVAR_CHEAT ) ? "FCVAR_CHEAT" : "no FCVAR_CHEAT", + ( pParentVar->m_nFlags & FCVAR_CHEAT ) ? "FCVAR_CHEAT" : "no FCVAR_CHEAT" ); + } + + // make sure we don't have conflicting FCVAR_REPLICATED flags. + if ( ( pChildVar->m_nFlags & FCVAR_REPLICATED ) != ( pParentVar->m_nFlags & FCVAR_REPLICATED ) ) + { + Warning( "Convar %s has conflicting FCVAR_REPLICATED flags (child: %s, parent: %s, parent wins)\n", + variable->GetName(), ( pChildVar->m_nFlags & FCVAR_REPLICATED ) ? "FCVAR_REPLICATED" : "no FCVAR_REPLICATED", + ( pParentVar->m_nFlags & FCVAR_REPLICATED ) ? "FCVAR_REPLICATED" : "no FCVAR_REPLICATED" ); + } + + // make sure we don't have conflicting FCVAR_DONTRECORD flags. + if ( ( pChildVar->m_nFlags & FCVAR_DONTRECORD ) != ( pParentVar->m_nFlags & FCVAR_DONTRECORD ) ) + { + Warning( "Convar %s has conflicting FCVAR_DONTRECORD flags (child: %s, parent: %s, parent wins)\n", + variable->GetName(), ( pChildVar->m_nFlags & FCVAR_DONTRECORD ) ? "FCVAR_DONTRECORD" : "no FCVAR_DONTRECORD", + ( pParentVar->m_nFlags & FCVAR_DONTRECORD ) ? "FCVAR_DONTRECORD" : "no FCVAR_DONTRECORD" ); + } + } + } + + variable->m_pNext = NULL; + return; + } + + // link the variable in + variable->m_pNext = m_pConCommandList; + m_pConCommandList = variable; +} + +void CCvar::UnregisterConCommand( ConCommandBase *pCommandToRemove ) +{ + // Not registered? Don't bother + if ( !pCommandToRemove->IsRegistered() ) + return; + + pCommandToRemove->m_bRegistered = false; + + // FIXME: Should we make this a doubly-linked list? Would remove faster + ConCommandBase *pPrev = NULL; + for( ConCommandBase *pCommand = m_pConCommandList; pCommand; pCommand = pCommand->m_pNext ) + { + if ( pCommand != pCommandToRemove ) + { + pPrev = pCommand; + continue; + } + + if ( pPrev == NULL ) + { + m_pConCommandList = pCommand->m_pNext; + } + else + { + pPrev->m_pNext = pCommand->m_pNext; + } + pCommand->m_pNext = NULL; + break; + } +} + +// Crash here in TF2, so I'm adding some debugging stuff. +#ifdef WIN32 +#pragma optimize( "", off ) +#endif +void CCvar::UnregisterConCommands( CVarDLLIdentifier_t id ) +{ + ConCommandBase *pNewList; + ConCommandBase *pCommand, *pNext; + + int iCommandsLooped = 0; + + pNewList = NULL; + pCommand = m_pConCommandList; + while ( pCommand ) + { + pNext = pCommand->m_pNext; + if ( pCommand->GetDLLIdentifier() != id ) + { + pCommand->m_pNext = pNewList; + pNewList = pCommand; + } + else + { + // Unlink + pCommand->m_bRegistered = false; + pCommand->m_pNext = NULL; + } + + pCommand = pNext; + iCommandsLooped++; + } + + m_pConCommandList = pNewList; +} +#ifdef WIN32 +#pragma optimize( "", on ) +#endif + + +//----------------------------------------------------------------------------- +// Finds base commands +//----------------------------------------------------------------------------- +const ConCommandBase *CCvar::FindCommandBase( const char *name ) const +{ + const ConCommandBase *cmd = GetCommands(); + for ( ; cmd; cmd = cmd->GetNext() ) + { + if ( !Q_stricmp( name, cmd->GetName() ) ) + return cmd; + } + return NULL; +} + +ConCommandBase *CCvar::FindCommandBase( const char *name ) +{ + ConCommandBase *cmd = GetCommands(); + for ( ; cmd; cmd = cmd->GetNext() ) + { + if ( !Q_stricmp( name, cmd->GetName() ) ) + return cmd; + } + return NULL; +} + + +//----------------------------------------------------------------------------- +// Purpose Finds ConVars +//----------------------------------------------------------------------------- +const ConVar *CCvar::FindVar( const char *var_name ) const +{ + VPROF_INCREMENT_COUNTER( "CCvar::FindVar", 1 ); + VPROF( "CCvar::FindVar" ); + const ConCommandBase *var = FindCommandBase( var_name ); + if ( !var || var->IsCommand() ) + return NULL; + + return static_cast<const ConVar*>(var); +} + +ConVar *CCvar::FindVar( const char *var_name ) +{ + VPROF_INCREMENT_COUNTER( "CCvar::FindVar", 1 ); + VPROF( "CCvar::FindVar" ); + ConCommandBase *var = FindCommandBase( var_name ); + if ( !var || var->IsCommand() ) + return NULL; + + return static_cast<ConVar*>( var ); +} + + +//----------------------------------------------------------------------------- +// Purpose Finds ConCommands +//----------------------------------------------------------------------------- +const ConCommand *CCvar::FindCommand( const char *pCommandName ) const +{ + const ConCommandBase *var = FindCommandBase( pCommandName ); + if ( !var || !var->IsCommand() ) + return NULL; + + return static_cast<const ConCommand*>(var); +} + +ConCommand *CCvar::FindCommand( const char *pCommandName ) +{ + ConCommandBase *var = FindCommandBase( pCommandName ); + if ( !var || !var->IsCommand() ) + return NULL; + + return static_cast<ConCommand*>( var ); +} + + +const char* CCvar::GetCommandLineValue( const char *pVariableName ) +{ + int nLen = Q_strlen(pVariableName); + char *pSearch = (char*)stackalloc( nLen + 2 ); + pSearch[0] = '+'; + memcpy( &pSearch[1], pVariableName, nLen + 1 ); + return CommandLine()->ParmValue( pSearch ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +ConCommandBase *CCvar::GetCommands( void ) +{ + return m_pConCommandList; +} + +const ConCommandBase *CCvar::GetCommands( void ) const +{ + return m_pConCommandList; +} + + +//----------------------------------------------------------------------------- +// Install, remove global callbacks +//----------------------------------------------------------------------------- +void CCvar::InstallGlobalChangeCallback( FnChangeCallback_t callback ) +{ + Assert( callback && m_GlobalChangeCallbacks.Find( callback ) < 0 ); + m_GlobalChangeCallbacks.AddToTail( callback ); +} + +void CCvar::RemoveGlobalChangeCallback( FnChangeCallback_t callback ) +{ + Assert( callback ); + m_GlobalChangeCallbacks.FindAndRemove( callback ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CCvar::CallGlobalChangeCallbacks( ConVar *var, const char *pOldString, float flOldValue ) +{ + int nCallbackCount = m_GlobalChangeCallbacks.Count(); + for ( int i = 0; i < nCallbackCount; ++i ) + { + (*m_GlobalChangeCallbacks[i])( var, pOldString, flOldValue ); + } +} + + +//----------------------------------------------------------------------------- +// Sets convars containing the flags to their default value +//----------------------------------------------------------------------------- +void CCvar::RevertFlaggedConVars( int nFlag ) +{ + for (const ConCommandBase *var= GetCommands() ; var ; var=var->GetNext()) + { + if ( var->IsCommand() ) + continue; + + ConVar *pCvar = ( ConVar * )var; + + if ( !pCvar->IsFlagSet( nFlag ) ) + continue; + + // It's == to the default value, don't count + if ( !Q_stricmp( pCvar->GetDefault(), pCvar->GetString() ) ) + continue; + + pCvar->Revert(); + + // DevMsg( "%s = \"%s\" (reverted)\n", cvar->GetName(), cvar->GetString() ); + } +} + + +//----------------------------------------------------------------------------- +// Deal with queued material system convars +//----------------------------------------------------------------------------- +bool CCvar::IsMaterialThreadSetAllowed( ) const +{ + Assert( ThreadInMainThread() ); + return m_bMaterialSystemThreadSetAllowed; +} + +void CCvar::QueueMaterialThreadSetValue( ConVar *pConVar, const char *pValue ) +{ + Assert( ThreadInMainThread() ); + int j = m_QueuedConVarSets.AddToTail(); + m_QueuedConVarSets[j].m_pConVar = pConVar; + m_QueuedConVarSets[j].m_nType = CONVAR_SET_STRING; + m_QueuedConVarSets[j].m_String = pValue; +} + +void CCvar::QueueMaterialThreadSetValue( ConVar *pConVar, int nValue ) +{ + Assert( ThreadInMainThread() ); + int j = m_QueuedConVarSets.AddToTail(); + m_QueuedConVarSets[j].m_pConVar = pConVar; + m_QueuedConVarSets[j].m_nType = CONVAR_SET_INT; + m_QueuedConVarSets[j].m_nInt = nValue; +} + +void CCvar::QueueMaterialThreadSetValue( ConVar *pConVar, float flValue ) +{ + Assert( ThreadInMainThread() ); + int j = m_QueuedConVarSets.AddToTail(); + m_QueuedConVarSets[j].m_pConVar = pConVar; + m_QueuedConVarSets[j].m_nType = CONVAR_SET_FLOAT; + m_QueuedConVarSets[j].m_flFloat = flValue; +} + +bool CCvar::HasQueuedMaterialThreadConVarSets() const +{ + Assert( ThreadInMainThread() ); + return m_QueuedConVarSets.Count() > 0; +} + +int CCvar::ProcessQueuedMaterialThreadConVarSets() +{ + Assert( ThreadInMainThread() ); + m_bMaterialSystemThreadSetAllowed = true; + + int nUpdateFlags = 0; + int nCount = m_QueuedConVarSets.Count(); + for ( int i = 0; i < nCount; ++i ) + { + const QueuedConVarSet_t& set = m_QueuedConVarSets[i]; + switch( set.m_nType ) + { + case CONVAR_SET_FLOAT: + set.m_pConVar->SetValue( set.m_flFloat ); + break; + case CONVAR_SET_INT: + set.m_pConVar->SetValue( set.m_nInt ); + break; + case CONVAR_SET_STRING: + set.m_pConVar->SetValue( set.m_String ); + break; + } + + nUpdateFlags |= set.m_pConVar->GetFlags() & FCVAR_MATERIAL_THREAD_MASK; + } + + m_QueuedConVarSets.RemoveAll(); + m_bMaterialSystemThreadSetAllowed = false; + return nUpdateFlags; +} + + +//----------------------------------------------------------------------------- +// Display queued messages +//----------------------------------------------------------------------------- +void CCvar::DisplayQueuedMessages( ) +{ + // Display any queued up messages + if ( m_TempConsoleBuffer.TellPut() == 0 ) + return; + + Color clr; + int nStringLength; + while( m_TempConsoleBuffer.IsValid() ) + { + int nType = m_TempConsoleBuffer.GetChar(); + if ( nType == CONSOLE_COLOR_PRINT ) + { + clr.SetRawColor( m_TempConsoleBuffer.GetInt() ); + } + nStringLength = m_TempConsoleBuffer.PeekStringLength(); + char* pTemp = (char*)stackalloc( nStringLength + 1 ); + m_TempConsoleBuffer.GetStringManualCharCount( pTemp, nStringLength + 1 ); + + switch( nType ) + { + case CONSOLE_COLOR_PRINT: + ConsoleColorPrintf( clr, pTemp ); + break; + + case CONSOLE_PRINT: + ConsolePrintf( pTemp ); + break; + + case CONSOLE_DPRINT: + ConsoleDPrintf( pTemp ); + break; + } + } + + m_TempConsoleBuffer.Purge(); +} + + +//----------------------------------------------------------------------------- +// Install a console printer +//----------------------------------------------------------------------------- +void CCvar::InstallConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ) +{ + Assert( m_DisplayFuncs.Find( pDisplayFunc ) < 0 ); + m_DisplayFuncs.AddToTail( pDisplayFunc ); + DisplayQueuedMessages(); +} + +void CCvar::RemoveConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ) +{ + m_DisplayFuncs.FindAndRemove( pDisplayFunc ); +} + +void CCvar::ConsoleColorPrintf( const Color& clr, const char *pFormat, ... ) const +{ + char temp[ 8192 ]; + va_list argptr; + va_start( argptr, pFormat ); + _vsnprintf( temp, sizeof( temp ) - 1, pFormat, argptr ); + va_end( argptr ); + temp[ sizeof( temp ) - 1 ] = 0; + + int c = m_DisplayFuncs.Count(); + if ( c == 0 ) + { + m_TempConsoleBuffer.PutChar( CONSOLE_COLOR_PRINT ); + m_TempConsoleBuffer.PutInt( clr.GetRawColor() ); + m_TempConsoleBuffer.PutString( temp ); + return; + } + + for ( int i = 0 ; i < c; ++i ) + { + m_DisplayFuncs[ i ]->ColorPrint( clr, temp ); + } +} + +void CCvar::ConsolePrintf( const char *pFormat, ... ) const +{ + char temp[ 8192 ]; + va_list argptr; + va_start( argptr, pFormat ); + _vsnprintf( temp, sizeof( temp ) - 1, pFormat, argptr ); + va_end( argptr ); + temp[ sizeof( temp ) - 1 ] = 0; + + int c = m_DisplayFuncs.Count(); + if ( c == 0 ) + { + m_TempConsoleBuffer.PutChar( CONSOLE_PRINT ); + m_TempConsoleBuffer.PutString( temp ); + return; + } + + for ( int i = 0 ; i < c; ++i ) + { + m_DisplayFuncs[ i ]->Print( temp ); + } +} + +void CCvar::ConsoleDPrintf( const char *pFormat, ... ) const +{ + char temp[ 8192 ]; + va_list argptr; + va_start( argptr, pFormat ); + _vsnprintf( temp, sizeof( temp ) - 1, pFormat, argptr ); + va_end( argptr ); + temp[ sizeof( temp ) - 1 ] = 0; + + int c = m_DisplayFuncs.Count(); + if ( c == 0 ) + { + m_TempConsoleBuffer.PutChar( CONSOLE_DPRINT ); + m_TempConsoleBuffer.PutString( temp ); + return; + } + + for ( int i = 0 ; i < c; ++i ) + { + m_DisplayFuncs[ i ]->DPrint( temp ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +#if defined( _X360 ) + +void CCvar::PublishToVXConsole() +{ + const char *commands[4096]; + const char *helptext[4096]; + const ConCommandBase *pCur; + int numCommands = 0; + + // iterate and publish commands to the remote console + for ( pCur = m_pConCommandList; pCur; pCur=pCur->GetNext() ) + { + // add unregistered commands to list + if ( numCommands < sizeof(commands)/sizeof(commands[0]) ) + { + commands[numCommands] = pCur->GetName(); + helptext[numCommands] = pCur->GetHelpText(); + numCommands++; + } + } + + if ( numCommands ) + { + XBX_rAddCommands( numCommands, commands, helptext ); + } +} + +#endif + + +//----------------------------------------------------------------------------- +// Console commands +//----------------------------------------------------------------------------- +void CCvar::Find( const CCommand &args ) +{ + const char *search; + const ConCommandBase *var; + + if ( args.ArgC() != 2 ) + { + ConMsg( "Usage: find <string>\n" ); + return; + } + + // Get substring to find + search = args[1]; + + // Loop through vars and print out findings + for ( var = GetCommands(); var; var=var->GetNext() ) + { + if ( var->IsFlagSet(FCVAR_DEVELOPMENTONLY) || var->IsFlagSet(FCVAR_HIDDEN) ) + continue; + + if ( !Q_stristr( var->GetName(), search ) && + !Q_stristr( var->GetHelpText(), search ) ) + continue; + + ConVar_PrintDescription( var ); + } +} + + |