core/convar_sm_dota.h
author Nicholas Hastings <skamonkey@gmail.com>
Sun Jun 30 10:45:19 2013 -0400 (2013-06-30)
changeset 3927 9371ebf3fb35
parent 3899 fd4ec50a0d6c
child 3942 7aaa00382627
permissions -rw-r--r--
Updated ambuild script for new l4d2 library names.
     1 //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
     2 //
     3 // Purpose: 
     4 //
     5 // $Workfile:     $
     6 // $Date:         $
     7 //
     8 //-----------------------------------------------------------------------------
     9 // $NoKeywords: $
    10 //===========================================================================//
    11 
    12 #ifndef CONVAR_H
    13 #define CONVAR_H
    14 
    15 #if _WIN32
    16 #pragma once
    17 #endif
    18 
    19 #include "tier0/dbg.h"
    20 #include "tier1/iconvar.h"
    21 #include "tier1/utlvector.h"
    22 #include "tier1/utlstring.h"
    23 #include "Color.h"
    24 #include "icvar.h"
    25 
    26 #ifdef _WIN32
    27 #define FORCEINLINE_CVAR FORCEINLINE
    28 #elif POSIX
    29 #define FORCEINLINE_CVAR inline
    30 #else
    31 #error "implement me"
    32 #endif
    33 
    34 
    35 //-----------------------------------------------------------------------------
    36 // Uncomment me to test for threading issues for material system convars
    37 // NOTE: You want to disable all threading when you do this
    38 // +host_thread_mode 0 +r_threaded_particles 0 +sv_parallel_packentities 0 +sv_disable_querycache 0
    39 //-----------------------------------------------------------------------------
    40 //#define CONVAR_TEST_MATERIAL_THREAD_CONVARS 1
    41 
    42 
    43 //-----------------------------------------------------------------------------
    44 // Forward declarations
    45 //-----------------------------------------------------------------------------
    46 class ConVar;
    47 class CCommand;
    48 class ConCommand;
    49 class ConCommandBase;
    50 struct characterset_t;
    51 
    52 
    53 
    54 //-----------------------------------------------------------------------------
    55 // Any executable that wants to use ConVars need to implement one of
    56 // these to hook up access to console variables.
    57 //-----------------------------------------------------------------------------
    58 class IConCommandBaseAccessor
    59 {
    60 public:
    61 	// Flags is a combination of FCVAR flags in cvar.h.
    62 	// hOut is filled in with a handle to the variable.
    63 	virtual bool RegisterConCommandBase( ConCommandBase *pVar ) = 0;
    64 };
    65 
    66 
    67 //-----------------------------------------------------------------------------
    68 // Helper method for console development
    69 //-----------------------------------------------------------------------------
    70 #if defined( _X360 )
    71 void ConVar_PublishToVXConsole();
    72 #endif
    73 
    74 
    75 //-----------------------------------------------------------------------------
    76 // Called when a ConCommand needs to execute
    77 //-----------------------------------------------------------------------------
    78 typedef void ( *FnCommandCallbackV1_t )( void );
    79 typedef void ( *FnCommandCallback_t )( void *pUnknown, const CCommand &command );
    80 
    81 #define COMMAND_COMPLETION_MAXITEMS		64
    82 #define COMMAND_COMPLETION_ITEM_LENGTH	64
    83 
    84 //-----------------------------------------------------------------------------
    85 // Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings
    86 //-----------------------------------------------------------------------------
    87 typedef int  ( *FnCommandCompletionCallback )( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] );
    88 
    89 
    90 //-----------------------------------------------------------------------------
    91 // Interface version
    92 //-----------------------------------------------------------------------------
    93 class ICommandCallback
    94 {
    95 public:
    96 	virtual void CommandCallback( const CCommand &command ) = 0;
    97 };
    98 
    99 class ICommandCallback2
   100 {
   101 public:
   102 	virtual void CommandCallback( void *pUnknown, const CCommand &command ) = 0;
   103 };
   104 
   105 class ICommandCompletionCallback
   106 {
   107 public:
   108 	virtual int  CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) = 0;
   109 };
   110 
   111 //-----------------------------------------------------------------------------
   112 // Purpose: The base console invoked command/cvar interface
   113 //-----------------------------------------------------------------------------
   114 class ConCommandBase
   115 {
   116 	friend class CCvar;
   117 	friend class ConVar;
   118 	friend class ConCommand;
   119 	friend void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor );
   120 	friend void ConVar_PublishToVXConsole();
   121 
   122 	// FIXME: Remove when ConVar changes are done
   123 	friend class CDefaultCvar;
   124 
   125 public:
   126 								ConCommandBase( void );
   127 								ConCommandBase( const char *pName, const char *pHelpString = 0, 
   128 									int flags = 0 );
   129 
   130 	virtual						~ConCommandBase( void );
   131 
   132 	virtual	bool				IsCommand( void ) const;
   133 
   134 	// Check flag
   135 	virtual bool				IsFlagSet( int flag ) const;
   136 	// Set flag
   137 	virtual void				AddFlags( int flags );
   138 	// Clear flag
   139 	virtual void				RemoveFlags( int flags );
   140 
   141 	virtual int					GetFlags() const;
   142 
   143 	// Return name of cvar
   144 	virtual const char			*GetName( void ) const;
   145 
   146 	// Return help text for cvar
   147 	virtual const char			*GetHelpText( void ) const;
   148 
   149 	// Deal with next pointer
   150 	const ConCommandBase		*GetNext( void ) const;
   151 	ConCommandBase				*GetNext( void );
   152 	
   153 	virtual bool				IsRegistered( void ) const;
   154 
   155 	// Returns the DLL identifier
   156 	virtual CVarDLLIdentifier_t	GetDLLIdentifier() const;
   157 
   158 protected:
   159 	virtual void				Create( const char *pName, const char *pHelpString = 0, 
   160 									int flags = 0 );
   161 
   162 	// Used internally by OneTimeInit to initialize/shutdown
   163 	virtual void				Init();
   164 	void						Shutdown();
   165 
   166 	// Internal copy routine ( uses new operator from correct module )
   167 	char						*CopyString( const char *from );
   168 
   169 private:
   170 	// Next ConVar in chain
   171 	// Prior to register, it points to the next convar in the DLL.
   172 	// Once registered, though, m_pNext is reset to point to the next
   173 	// convar in the global list
   174 	ConCommandBase				*m_pNext;
   175 
   176 	// Has the cvar been added to the global list?
   177 	bool						m_bRegistered;
   178 
   179 	// Static data
   180 	const char 					*m_pszName;
   181 	const char 					*m_pszHelpString;
   182 	
   183 	// ConVar flags
   184 	int							m_nFlags;
   185 
   186 protected:
   187 	// ConVars add themselves to this list for the executable. 
   188 	// Then ConVar_Register runs through  all the console variables 
   189 	// and registers them into a global list stored in vstdlib.dll
   190 	static ConCommandBase		*s_pConCommandBases;
   191 
   192 	// ConVars in this executable use this 'global' to access values.
   193 	static IConCommandBaseAccessor	*s_pAccessor;
   194 public:
   195 	inline void SetFlags(int flags)	
   196 	{ 
   197 		m_nFlags = flags; 
   198 	}
   199 };
   200 
   201 
   202 //-----------------------------------------------------------------------------
   203 // Command tokenizer
   204 //-----------------------------------------------------------------------------
   205 class CCommand
   206 {
   207 public:
   208 	CCommand();
   209 	CCommand( int nArgC, const char **ppArgV );
   210 	bool Tokenize( const char *pCommand, characterset_t *pBreakSet = NULL );
   211 	void Reset();
   212 
   213 	int ArgC() const;
   214 	const char **ArgV() const;
   215 	const char *ArgS() const;					// All args that occur after the 0th arg, in string form
   216 	const char *GetCommandString() const;		// The entire command in string form, including the 0th arg
   217 	const char *operator[]( int nIndex ) const;	// Gets at arguments
   218 	const char *Arg( int nIndex ) const;		// Gets at arguments
   219 	
   220 	// Helper functions to parse arguments to commands.
   221 	const char* FindArg( const char *pName ) const;
   222 	int FindArgInt( const char *pName, int nDefaultVal ) const;
   223 
   224 	static int MaxCommandLength();
   225 	static characterset_t* DefaultBreakSet();
   226 
   227 private:
   228 	enum
   229 	{
   230 		COMMAND_MAX_ARGC = 64,
   231 		COMMAND_MAX_LENGTH = 512,
   232 	};
   233 
   234 	int		m_nArgc;
   235 	int		m_nArgv0Size;
   236 	char	m_pArgSBuffer[ COMMAND_MAX_LENGTH ];
   237 	char	m_pArgvBuffer[ COMMAND_MAX_LENGTH ];
   238 	const char*	m_ppArgv[ COMMAND_MAX_ARGC ];
   239 };
   240 
   241 inline int CCommand::MaxCommandLength()
   242 {
   243 	return COMMAND_MAX_LENGTH - 1;
   244 }
   245 
   246 inline int CCommand::ArgC() const
   247 {
   248 	return m_nArgc;
   249 }
   250 
   251 inline const char **CCommand::ArgV() const
   252 {
   253 	return m_nArgc ? (const char**)m_ppArgv : NULL;
   254 }
   255 
   256 inline const char *CCommand::ArgS() const
   257 {
   258 	return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
   259 }
   260 
   261 inline const char *CCommand::GetCommandString() const
   262 {
   263 	return m_nArgc ? m_pArgSBuffer : "";
   264 }
   265 
   266 inline const char *CCommand::Arg( int nIndex ) const
   267 {
   268 	// FIXME: Many command handlers appear to not be particularly careful
   269 	// about checking for valid argc range. For now, we're going to
   270 	// do the extra check and return an empty string if it's out of range
   271 	if ( nIndex < 0 || nIndex >= m_nArgc )
   272 		return "";
   273 	return m_ppArgv[nIndex];
   274 }
   275 
   276 inline const char *CCommand::operator[]( int nIndex ) const
   277 {
   278 	return Arg( nIndex );
   279 }
   280 
   281 
   282 //-----------------------------------------------------------------------------
   283 // Purpose: The console invoked command
   284 //-----------------------------------------------------------------------------
   285 class ConCommand : public ConCommandBase
   286 {
   287 friend class CCvar;
   288 
   289 public:
   290 	typedef ConCommandBase BaseClass;
   291 
   292 	ConCommand( const char *pName, FnCommandCallbackV1_t callback, 
   293 		const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
   294 	ConCommand( const char *pName, FnCommandCallback_t callback, 
   295 		const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
   296 	ConCommand( const char *pName, ICommandCallback *pCallback, 
   297 		const char *pHelpString = 0, int flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 );
   298 	ConCommand( const char *pName, ICommandCallback2 *pCallback, 
   299 		const char *pHelpString = 0, int flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 );
   300 
   301 	virtual ~ConCommand( void );
   302 
   303 	virtual	bool IsCommand( void ) const;
   304 
   305 	virtual int AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands );
   306 
   307 	virtual bool CanAutoComplete( void );
   308 
   309 	// Invoke the function
   310 	virtual void Dispatch( void *pUnknown, const CCommand &command );
   311 
   312 private:
   313 	// NOTE: To maintain backward compat, we have to be very careful:
   314 	// All public virtual methods must appear in the same order always
   315 	// since engine code will be calling into this code, which *does not match*
   316 	// in the mod code; it's using slightly different, but compatible versions
   317 	// of this class. Also: Be very careful about adding new fields to this class.
   318 	// Those fields will not exist in the version of this class that is instanced
   319 	// in mod code.
   320 
   321 	// Call this function when executing the command
   322 	union
   323 	{
   324 		FnCommandCallbackV1_t m_fnCommandCallbackV1;
   325 		FnCommandCallback_t m_fnCommandCallback;
   326 		ICommandCallback *m_pCommandCallback; 
   327 		ICommandCallback2 *m_pCommandCallback2; 
   328 	};
   329 
   330 	union
   331 	{
   332 		FnCommandCompletionCallback	m_fnCompletionCallback;
   333 		ICommandCompletionCallback *m_pCommandCompletionCallback;
   334 	};
   335 
   336 	bool m_bHasCompletionCallback : 1;
   337 	bool m_bUsingNewCommandCallback : 1;
   338 	bool m_bUsingCommandCallbackInterface : 1;
   339 	bool m_bUsingCommandCallbackInterface2 : 1;
   340 public:
   341 	inline FnCommandCallback_t GetCallback() const
   342 	{ 
   343 		return m_fnCommandCallback; 
   344 	}
   345 };
   346 
   347 
   348 //-----------------------------------------------------------------------------
   349 // Purpose: A console variable
   350 //-----------------------------------------------------------------------------
   351 class ConVar : public ConCommandBase, public IConVar
   352 {
   353 friend class CCvar;
   354 friend class ConVarRef;
   355 friend class SplitScreenConVarRef;
   356 
   357 public:
   358 	typedef ConCommandBase BaseClass;
   359 
   360 								ConVar( const char *pName, const char *pDefaultValue, int flags = 0);
   361 
   362 								ConVar( const char *pName, const char *pDefaultValue, int flags, 
   363 									const char *pHelpString );
   364 								ConVar( const char *pName, const char *pDefaultValue, int flags, 
   365 									const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax );
   366 								ConVar( const char *pName, const char *pDefaultValue, int flags, 
   367 									const char *pHelpString, FnChangeCallback_t callback );
   368 								ConVar( const char *pName, const char *pDefaultValue, int flags, 
   369 									const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax,
   370 									FnChangeCallback_t callback );
   371 
   372 	virtual						~ConVar( void );
   373 
   374 	virtual bool				IsFlagSet( int flag ) const;
   375 	virtual const char*			GetHelpText( void ) const;
   376 	virtual bool				IsRegistered( void ) const;
   377 	virtual const char			*GetName( void ) const;
   378 	// Return name of command (usually == GetName(), except in case of FCVAR_SS_ADDED vars
   379 	virtual const char			*GetBaseName( void ) const;
   380 	virtual int					GetSplitScreenPlayerSlot() const;
   381 
   382 	virtual void				AddFlags( int flags );
   383 	virtual int					GetFlags() const;
   384 	virtual	bool				IsCommand( void ) const;
   385 
   386 	// Install a change callback (there shouldn't already be one....)
   387 	void InstallChangeCallback( FnChangeCallback_t callback, bool bInvoke = true );
   388 	void RemoveChangeCallback( FnChangeCallback_t callbackToRemove );
   389 
   390 	int GetChangeCallbackCount() const { return m_pParent->m_fnChangeCallbacks.Count(); }
   391 	FnChangeCallback_t GetChangeCallback( int slot ) const { return m_pParent->m_fnChangeCallbacks[ slot ]; }
   392 
   393 	// Retrieve value
   394 	FORCEINLINE_CVAR float			GetFloat( void ) const;
   395 	FORCEINLINE_CVAR int			GetInt( void ) const;
   396 	FORCEINLINE_CVAR Color			GetColor( void ) const;
   397 	FORCEINLINE_CVAR bool			GetBool() const {  return !!GetInt(); }
   398 	FORCEINLINE_CVAR char const	   *GetString( void ) const;
   399 
   400 	// Compiler driven selection for template use
   401 	template <typename T> T Get( void ) const;
   402 	template <typename T> T Get( T * ) const;
   403 
   404 	// Any function that allocates/frees memory needs to be virtual or else you'll have crashes
   405 	//  from alloc/free across dll/exe boundaries.
   406 	
   407 	// These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue).
   408 	virtual void				SetValue( const char *value );
   409 	virtual void				SetValue( float value );
   410 	virtual void				SetValue( int value );
   411 	virtual void				SetValue( Color value );
   412 	
   413 	// Reset to default value
   414 	void						Revert( void );
   415 
   416 	// True if it has a min/max setting
   417 	bool						HasMin() const;
   418 	bool						HasMax() const;
   419 
   420 	bool						GetMin( float& minVal ) const;
   421 	bool						GetMax( float& maxVal ) const;
   422 
   423 	float						GetMinValue() const;
   424 	float						GetMaxValue() const;
   425 
   426 	const char					*GetDefault( void ) const;
   427 
   428 	// Value
   429 	struct CVValue_t
   430 	{
   431 		char						*m_pszString;
   432 		int							m_StringLength;
   433 
   434 		// Values
   435 		float						m_fValue;
   436 		int							m_nValue;
   437 	};
   438 
   439 	FORCEINLINE_CVAR CVValue_t &GetRawValue()
   440 	{
   441 		return m_Value;
   442 	}
   443 	FORCEINLINE_CVAR const CVValue_t &GetRawValue() const
   444 	{
   445 		return m_Value;
   446 	}
   447 
   448 private:
   449 	bool						InternalSetColorFromString( const char *value );
   450 	// Called by CCvar when the value of a var is changing.
   451 	virtual void				InternalSetValue(const char *value);
   452 	// For CVARs marked FCVAR_NEVER_AS_STRING
   453 	virtual void				InternalSetFloatValue( float fNewValue );
   454 	virtual void				InternalSetIntValue( int nValue );
   455 	virtual void				InternalSetColorValue( Color value );
   456 
   457 	virtual bool				ClampValue( float& value );
   458 	virtual void				ChangeStringValue( const char *tempVal, float flOldValue );
   459 
   460 	virtual void				Create( const char *pName, const char *pDefaultValue, int flags = 0,
   461 									const char *pHelpString = 0, bool bMin = false, float fMin = 0.0,
   462 									bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0 );
   463 
   464 	// Used internally by OneTimeInit to initialize.
   465 	virtual void				Init();
   466 
   467 
   468 
   469 protected:
   470 
   471 	// This either points to "this" or it points to the original declaration of a ConVar.
   472 	// This allows ConVars to exist in separate modules, and they all use the first one to be declared.
   473 	// m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar).
   474 	ConVar						*m_pParent;
   475 
   476 	// Static data
   477 	const char					*m_pszDefaultValue;
   478 	
   479 	CVValue_t					m_Value;
   480 
   481 	// Min/Max values
   482 	bool						m_bHasMin;
   483 	float						m_fMinVal;
   484 	bool						m_bHasMax;
   485 	float						m_fMaxVal;
   486 	
   487 	// Call this function when ConVar changes
   488 	CUtlVector< FnChangeCallback_t > m_fnChangeCallbacks;
   489 public:
   490 	inline void SetMin(bool set, float min=0.0)
   491 	{ 
   492 		m_bHasMin = set; 
   493 		m_fMinVal = min; 
   494 	}
   495 	inline void SetMax(bool set, float max=0.0)
   496 	{
   497 		m_bHasMax = set;
   498 		m_fMaxVal = max; 
   499 	}
   500 };
   501 
   502 
   503 //-----------------------------------------------------------------------------
   504 // Purpose: Return ConVar value as a float
   505 // Output : float
   506 //-----------------------------------------------------------------------------
   507 FORCEINLINE_CVAR float ConVar::GetFloat( void ) const
   508 {
   509 #ifdef CONVAR_TEST_MATERIAL_THREAD_CONVARS
   510 	Assert( ThreadInMainThread() || IsFlagSet( FCVAR_MATERIAL_THREAD_MASK | FCVAR_ACCESSIBLE_FROM_THREADS ) );
   511 #endif
   512 	return m_pParent->m_Value.m_fValue;
   513 }
   514 
   515 //-----------------------------------------------------------------------------
   516 // Purpose: Return ConVar value as an int
   517 // Output : int
   518 //-----------------------------------------------------------------------------
   519 FORCEINLINE_CVAR int ConVar::GetInt( void ) const 
   520 {
   521 #ifdef CONVAR_TEST_MATERIAL_THREAD_CONVARS
   522 	Assert( ThreadInMainThread() || IsFlagSet( FCVAR_MATERIAL_THREAD_MASK | FCVAR_ACCESSIBLE_FROM_THREADS ) );
   523 #endif
   524 	return m_pParent->m_Value.m_nValue;
   525 }
   526 
   527 //-----------------------------------------------------------------------------
   528 // Purpose: Return ConVar value as a color
   529 // Output : Color
   530 //-----------------------------------------------------------------------------
   531 FORCEINLINE_CVAR Color ConVar::GetColor( void ) const 
   532 {
   533 #ifdef CONVAR_TEST_MATERIAL_THREAD_CONVARS
   534 	Assert( ThreadInMainThread() || IsFlagSet( FCVAR_MATERIAL_THREAD_MASK | FCVAR_ACCESSIBLE_FROM_THREADS ) );
   535 #endif
   536 	unsigned char *pColorElement = ((unsigned char *)&m_pParent->m_Value.m_nValue);
   537 	return Color( pColorElement[0], pColorElement[1], pColorElement[2], pColorElement[3] );
   538 }
   539 
   540 
   541 //-----------------------------------------------------------------------------
   542 
   543 template <> FORCEINLINE_CVAR float			ConVar::Get<float>( void ) const		{ return GetFloat(); }
   544 template <> FORCEINLINE_CVAR int			ConVar::Get<int>( void ) const			{ return GetInt(); }
   545 template <> FORCEINLINE_CVAR bool			ConVar::Get<bool>( void ) const			{ return GetBool(); }
   546 template <> FORCEINLINE_CVAR const char *	ConVar::Get<const char *>( void ) const	{ return GetString(); }
   547 template <> FORCEINLINE_CVAR float			ConVar::Get<float>( float *p ) const				{ return ( *p = GetFloat() ); }
   548 template <> FORCEINLINE_CVAR int			ConVar::Get<int>( int *p ) const					{ return ( *p = GetInt() ); }
   549 template <> FORCEINLINE_CVAR bool			ConVar::Get<bool>( bool *p ) const					{ return ( *p = GetBool() ); }
   550 template <> FORCEINLINE_CVAR const char *	ConVar::Get<const char *>( char const **p ) const	{ return ( *p = GetString() ); }
   551 
   552 //-----------------------------------------------------------------------------
   553 // Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
   554 // Output : const char *
   555 //-----------------------------------------------------------------------------
   556 FORCEINLINE_CVAR const char *ConVar::GetString( void ) const 
   557 {
   558 #ifdef CONVAR_TEST_MATERIAL_THREAD_CONVARS
   559 	Assert( ThreadInMainThread() || IsFlagSet( FCVAR_MATERIAL_THREAD_MASK | FCVAR_ACCESSIBLE_FROM_THREADS ) );
   560 #endif
   561 	if ( m_nFlags & FCVAR_NEVER_AS_STRING )
   562 		return "FCVAR_NEVER_AS_STRING";
   563 	
   564 	char const *str = m_pParent->m_Value.m_pszString;
   565 	return str ? str : "";
   566 }
   567 
   568 class CSplitScreenAddedConVar : public ConVar
   569 {
   570 	typedef ConVar BaseClass;
   571 public:
   572 	CSplitScreenAddedConVar( int nSplitScreenSlot, const char *pName, const ConVar *pBaseVar ) :
   573 		BaseClass
   574 		( 
   575 			pName, 
   576 			pBaseVar->GetDefault(), 
   577 			// Keep basevar flags, except remove _SS and add _SS_ADDED instead
   578 			( pBaseVar->GetFlags() & ~FCVAR_SS ) | FCVAR_SS_ADDED, 
   579 			pBaseVar->GetHelpText(), 
   580 			pBaseVar->HasMin(),
   581 			pBaseVar->GetMinValue(),
   582 			pBaseVar->HasMax(),
   583 			pBaseVar->GetMaxValue()
   584 		),
   585 		m_pBaseVar( pBaseVar ),
   586 		m_nSplitScreenSlot( nSplitScreenSlot )
   587 	{
   588 		for ( int i = 0; i < pBaseVar->GetChangeCallbackCount(); ++i )
   589 		{
   590 			InstallChangeCallback( pBaseVar->GetChangeCallback( i ), false );
   591 		}
   592 		Assert( nSplitScreenSlot >= 1 );
   593 		Assert( nSplitScreenSlot < MAX_SPLITSCREEN_CLIENTS );
   594 		Assert( m_pBaseVar );
   595 		Assert( IsFlagSet( FCVAR_SS_ADDED ) );
   596 		Assert( !IsFlagSet( FCVAR_SS ) );
   597 	}
   598 
   599 	const ConVar *GetBaseVar() const;
   600 	virtual const char *GetBaseName() const;
   601 	void SetSplitScreenPlayerSlot( int nSlot );
   602 	virtual int GetSplitScreenPlayerSlot() const;
   603 
   604 protected:
   605 
   606 	const ConVar	*m_pBaseVar;
   607 	int		m_nSplitScreenSlot;
   608 };
   609 
   610 FORCEINLINE_CVAR const ConVar *CSplitScreenAddedConVar::GetBaseVar() const 
   611 { 
   612 	Assert( m_pBaseVar );
   613 	return m_pBaseVar; 
   614 }
   615 
   616 FORCEINLINE_CVAR const char *CSplitScreenAddedConVar::GetBaseName() const 
   617 { 
   618 	Assert( m_pBaseVar );
   619 	return m_pBaseVar->GetName(); 
   620 }
   621 
   622 FORCEINLINE_CVAR void CSplitScreenAddedConVar::SetSplitScreenPlayerSlot( int nSlot ) 
   623 { 
   624 	m_nSplitScreenSlot = nSlot; 
   625 }
   626 
   627 FORCEINLINE_CVAR int CSplitScreenAddedConVar::GetSplitScreenPlayerSlot() const 
   628 { 
   629 	return m_nSplitScreenSlot; 
   630 }
   631 
   632 //-----------------------------------------------------------------------------
   633 // Used to read/write convars that already exist (replaces the FindVar method)
   634 //-----------------------------------------------------------------------------
   635 class ConVarRef
   636 {
   637 public:
   638 	ConVarRef( const char *pName );
   639 	ConVarRef( const char *pName, bool bIgnoreMissing );
   640 	ConVarRef( IConVar *pConVar );
   641 
   642 	void Init( const char *pName, bool bIgnoreMissing );
   643 	bool IsValid() const;
   644 	bool IsFlagSet( int nFlags ) const;
   645 	IConVar *GetLinkedConVar();
   646 
   647 	// Get/Set value
   648 	float GetFloat( void ) const;
   649 	int GetInt( void ) const;
   650 	Color GetColor( void ) const;
   651 	bool GetBool() const { return !!GetInt(); }
   652 	const char *GetString( void ) const;
   653 
   654 	void SetValue( const char *pValue );
   655 	void SetValue( float flValue );
   656 	void SetValue( int nValue );
   657 	void SetValue( Color value );
   658 	void SetValue( bool bValue );
   659 
   660 	const char *GetName() const;
   661 
   662 	const char *GetDefault() const;
   663 
   664 	const char *GetBaseName() const;
   665 
   666 	int	GetSplitScreenPlayerSlot() const;
   667 
   668 private:
   669 	// High-speed method to read convar data
   670 	IConVar *m_pConVar;
   671 	ConVar *m_pConVarState;
   672 };
   673 
   674 
   675 //-----------------------------------------------------------------------------
   676 // Did we find an existing convar of that name?
   677 //-----------------------------------------------------------------------------
   678 FORCEINLINE_CVAR bool ConVarRef::IsFlagSet( int nFlags ) const
   679 {
   680 	return ( m_pConVar->IsFlagSet( nFlags ) != 0 );
   681 }
   682 
   683 FORCEINLINE_CVAR IConVar *ConVarRef::GetLinkedConVar()
   684 {
   685 	return m_pConVar;
   686 }
   687 
   688 FORCEINLINE_CVAR const char *ConVarRef::GetName() const
   689 {
   690 	return m_pConVar->GetName();
   691 }
   692 
   693 FORCEINLINE_CVAR const char *ConVarRef::GetBaseName() const
   694 {
   695 	return m_pConVar->GetBaseName();
   696 }
   697 
   698 FORCEINLINE_CVAR int ConVarRef::GetSplitScreenPlayerSlot() const
   699 {
   700 	return m_pConVar->GetSplitScreenPlayerSlot();
   701 }
   702 
   703 //-----------------------------------------------------------------------------
   704 // Purpose: Return ConVar value as a float
   705 //-----------------------------------------------------------------------------
   706 FORCEINLINE_CVAR float ConVarRef::GetFloat( void ) const
   707 {
   708 	return m_pConVarState->m_Value.m_fValue;
   709 }
   710 
   711 //-----------------------------------------------------------------------------
   712 // Purpose: Return ConVar value as an int
   713 //-----------------------------------------------------------------------------
   714 FORCEINLINE_CVAR int ConVarRef::GetInt( void ) const 
   715 {
   716 	return m_pConVarState->m_Value.m_nValue;
   717 }
   718 
   719 //-----------------------------------------------------------------------------
   720 // Purpose: Return ConVar value as a color
   721 //-----------------------------------------------------------------------------
   722 FORCEINLINE_CVAR Color ConVarRef::GetColor( void ) const 
   723 {
   724 	return m_pConVarState->GetColor();
   725 }
   726 
   727 //-----------------------------------------------------------------------------
   728 // Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
   729 //-----------------------------------------------------------------------------
   730 FORCEINLINE_CVAR const char *ConVarRef::GetString( void ) const 
   731 {
   732 	Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) );
   733 	return m_pConVarState->m_Value.m_pszString;
   734 }
   735 
   736 
   737 FORCEINLINE_CVAR void ConVarRef::SetValue( const char *pValue )
   738 {
   739 	m_pConVar->SetValue( pValue );
   740 }
   741 
   742 FORCEINLINE_CVAR void ConVarRef::SetValue( float flValue )
   743 {
   744 	m_pConVar->SetValue( flValue );
   745 }
   746 
   747 FORCEINLINE_CVAR void ConVarRef::SetValue( int nValue )
   748 {
   749 	m_pConVar->SetValue( nValue );
   750 }
   751 
   752 FORCEINLINE_CVAR void ConVarRef::SetValue( Color value )
   753 {
   754 	m_pConVar->SetValue( value );
   755 }
   756 
   757 FORCEINLINE_CVAR void ConVarRef::SetValue( bool bValue )
   758 {
   759 	m_pConVar->SetValue( bValue ? 1 : 0 );
   760 }
   761 
   762 FORCEINLINE_CVAR const char *ConVarRef::GetDefault() const
   763 {
   764 	return m_pConVarState->m_pszDefaultValue;
   765 }
   766 
   767 //-----------------------------------------------------------------------------
   768 // Helper for referencing splitscreen convars (i.e., "name" and "name2")
   769 //-----------------------------------------------------------------------------
   770 class SplitScreenConVarRef
   771 {
   772 public:
   773 	SplitScreenConVarRef( const char *pName );
   774 	SplitScreenConVarRef( const char *pName, bool bIgnoreMissing );
   775 	SplitScreenConVarRef( IConVar *pConVar );
   776 
   777 	void Init( const char *pName, bool bIgnoreMissing );
   778 	bool IsValid() const;
   779 	bool IsFlagSet( int nFlags ) const;
   780 
   781 	// Get/Set value
   782 	float GetFloat( int nSlot ) const;
   783 	int GetInt( int nSlot ) const;
   784 	Color GetColor( int nSlot ) const;
   785 	bool GetBool( int nSlot ) const { return !!GetInt( nSlot ); }
   786 	const char *GetString( int nSlot  ) const;
   787 
   788 	void SetValue( int nSlot, const char *pValue );
   789 	void SetValue( int nSlot, float flValue );
   790 	void SetValue( int nSlot, int nValue );
   791 	void SetValue( int nSlot, Color value );
   792 	void SetValue( int nSlot, bool bValue );
   793 
   794 	const char *GetName( int nSlot ) const;
   795 
   796 	const char *GetDefault() const;
   797 
   798 	const char *GetBaseName() const;
   799 
   800 private:
   801 	struct cv_t
   802 	{
   803 		IConVar *m_pConVar;
   804 		ConVar *m_pConVarState;
   805 	};
   806 
   807 	cv_t	m_Info[ MAX_SPLITSCREEN_CLIENTS ];
   808 };
   809 
   810 //-----------------------------------------------------------------------------
   811 // Did we find an existing convar of that name?
   812 //-----------------------------------------------------------------------------
   813 FORCEINLINE_CVAR bool SplitScreenConVarRef::IsFlagSet( int nFlags ) const
   814 {
   815 	return ( m_Info[ 0 ].m_pConVar->IsFlagSet( nFlags ) != 0 );
   816 }
   817 
   818 FORCEINLINE_CVAR const char *SplitScreenConVarRef::GetName( int nSlot ) const
   819 {
   820 	return m_Info[ nSlot ].m_pConVar->GetName();
   821 }
   822 
   823 FORCEINLINE_CVAR const char *SplitScreenConVarRef::GetBaseName() const
   824 {
   825 	return m_Info[ 0 ].m_pConVar->GetBaseName();
   826 }
   827 
   828 //-----------------------------------------------------------------------------
   829 // Purpose: Return ConVar value as a float
   830 //-----------------------------------------------------------------------------
   831 FORCEINLINE_CVAR float SplitScreenConVarRef::GetFloat( int nSlot ) const
   832 {
   833 	return m_Info[ nSlot ].m_pConVarState->m_Value.m_fValue;
   834 }
   835 
   836 //-----------------------------------------------------------------------------
   837 // Purpose: Return ConVar value as an int
   838 //-----------------------------------------------------------------------------
   839 FORCEINLINE_CVAR int SplitScreenConVarRef::GetInt( int nSlot ) const 
   840 {
   841 	return m_Info[ nSlot ].m_pConVarState->m_Value.m_nValue;
   842 }
   843 
   844 //-----------------------------------------------------------------------------
   845 // Purpose: Return ConVar value as an int
   846 //-----------------------------------------------------------------------------
   847 FORCEINLINE_CVAR Color SplitScreenConVarRef::GetColor( int nSlot ) const 
   848 {
   849 	return m_Info[ nSlot ].m_pConVarState->GetColor();
   850 }
   851 
   852 //-----------------------------------------------------------------------------
   853 // Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
   854 //-----------------------------------------------------------------------------
   855 FORCEINLINE_CVAR const char *SplitScreenConVarRef::GetString( int nSlot ) const 
   856 {
   857 	Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) );
   858 	return m_Info[ nSlot ].m_pConVarState->m_Value.m_pszString;
   859 }
   860 
   861 
   862 FORCEINLINE_CVAR void SplitScreenConVarRef::SetValue( int nSlot, const char *pValue )
   863 {
   864 	m_Info[ nSlot ].m_pConVar->SetValue( pValue );
   865 }
   866 
   867 FORCEINLINE_CVAR void SplitScreenConVarRef::SetValue( int nSlot, float flValue )
   868 {
   869 	m_Info[ nSlot ].m_pConVar->SetValue( flValue );
   870 }
   871 
   872 FORCEINLINE_CVAR void SplitScreenConVarRef::SetValue( int nSlot, int nValue )
   873 {
   874 	m_Info[ nSlot ].m_pConVar->SetValue( nValue );
   875 }
   876 
   877 FORCEINLINE_CVAR void SplitScreenConVarRef::SetValue( int nSlot, Color value )
   878 {
   879 	m_Info[ nSlot ].m_pConVar->SetValue( value );
   880 }
   881 
   882 FORCEINLINE_CVAR void SplitScreenConVarRef::SetValue( int nSlot, bool bValue )
   883 {
   884 	m_Info[ nSlot ].m_pConVar->SetValue( bValue ? 1 : 0 );
   885 }
   886 
   887 FORCEINLINE_CVAR const char *SplitScreenConVarRef::GetDefault() const
   888 {
   889 	return m_Info[ 0 ].m_pConVarState->m_pszDefaultValue;
   890 }
   891 
   892 //-----------------------------------------------------------------------------
   893 // Called by the framework to register ConCommands with the ICVar
   894 //-----------------------------------------------------------------------------
   895 void ConVar_Register( int nCVarFlag = 0, IConCommandBaseAccessor *pAccessor = NULL );
   896 void ConVar_Unregister( );
   897 
   898 
   899 //-----------------------------------------------------------------------------
   900 // Utility methods 
   901 //-----------------------------------------------------------------------------
   902 void ConVar_PrintDescription( const ConCommandBase *pVar );
   903 
   904 
   905 //-----------------------------------------------------------------------------
   906 // Purpose: Utility class to quickly allow ConCommands to call member methods
   907 //-----------------------------------------------------------------------------
   908 #ifdef _MSC_VER
   909 #pragma warning (disable : 4355 )
   910 #endif
   911 
   912 template< class T >
   913 class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, public ICommandCompletionCallback
   914 {
   915 	typedef ConCommand BaseClass;
   916 	typedef void ( T::*FnMemberCommandCallback_t )( const CCommand &command );
   917 	typedef int  ( T::*FnMemberCommandCompletionCallback_t )( const char *pPartial, CUtlVector< CUtlString > &commands );
   918 
   919 public:
   920 	CConCommandMemberAccessor( T* pOwner, const char *pName, FnMemberCommandCallback_t callback, const char *pHelpString = 0,
   921 		int flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0 ) :
   922 		BaseClass( pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL )
   923 	{
   924 		m_pOwner = pOwner;
   925 		m_Func = callback;
   926 		m_CompletionFunc = completionFunc;
   927 	}
   928 
   929 	~CConCommandMemberAccessor()
   930 	{
   931 		Shutdown();
   932 	}
   933 
   934 	void SetOwner( T* pOwner )
   935 	{
   936 		m_pOwner = pOwner;
   937 	}
   938 
   939 	virtual void CommandCallback( const CCommand &command )
   940 	{
   941 		Assert( m_pOwner && m_Func );
   942 		(m_pOwner->*m_Func)( command );
   943 	}
   944 
   945 	virtual int  CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands )
   946 	{
   947 		Assert( m_pOwner && m_CompletionFunc );
   948 		return (m_pOwner->*m_CompletionFunc)( pPartial, commands );
   949 	}
   950 
   951 private:
   952 	T* m_pOwner;
   953 	FnMemberCommandCallback_t m_Func;
   954 	FnMemberCommandCompletionCallback_t m_CompletionFunc;
   955 };
   956 
   957 #ifdef _MSC_VER
   958 #pragma warning ( default : 4355 )
   959 #endif
   960 
   961 //-----------------------------------------------------------------------------
   962 // Purpose: Utility macros to quicky generate a simple console command
   963 //-----------------------------------------------------------------------------
   964 #define CON_COMMAND( name, description ) \
   965    static void name( void *pUnknown, const CCommand &args ); \
   966    static ConCommand name##_command( #name, name, description ); \
   967    static void name( void *pUnknown, const CCommand &args )
   968 
   969 #ifdef CLIENT_DLL
   970 	#define CON_COMMAND_SHARED( name, description ) \
   971 		static void name( void *pUnknown, const CCommand &args ); \
   972 		static ConCommand name##_command_client( #name "_client", name, description ); \
   973 		static void name( void *pUnknown, const CCommand &args )
   974 #else
   975 	#define CON_COMMAND_SHARED( name, description ) \
   976 		static void name( void *pUnknown, const CCommand &args ); \
   977 		static ConCommand name##_command( #name, name, description ); \
   978 		static void name( void *pUnknown, const CCommand &args )
   979 #endif
   980 
   981 
   982 #define CON_COMMAND_F( name, description, flags ) \
   983 	static void name( void *pUnknown, const CCommand &args ); \
   984 	static ConCommand name##_command( #name, name, description, flags ); \
   985 	static void name( void *pUnknown, const CCommand &args )
   986 
   987 #ifdef CLIENT_DLL
   988 	#define CON_COMMAND_F_SHARED( name, description, flags ) \
   989 		static void name( void *pUnknown, const CCommand &args ); \
   990 		static ConCommand name##_command_client( #name "_client", name, description, flags ); \
   991 		static void name( void *pUnknown, const CCommand &args )
   992 #else
   993 	#define CON_COMMAND_F_SHARED( name, description, flags ) \
   994 		static void name( void *pUnknown, const CCommand &args ); \
   995 		static ConCommand name##_command( #name, name, description, flags ); \
   996 		static void name( void *pUnknown, const CCommand &args )
   997 #endif
   998 
   999 
  1000 #define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \
  1001 	static void name( void *pUnknown, const CCommand &args ); \
  1002 	static ConCommand name##_command( #name, name, description, flags, completion ); \
  1003 	static void name( void *pUnknown, const CCommand &args )
  1004 
  1005 #ifdef CLIENT_DLL
  1006 	#define CON_COMMAND_F_COMPLETION_SHARED( name, description, flags, completion ) \
  1007 		static void name( void *pUnknown, const CCommand &args ); \
  1008 		static ConCommand name##_command_client( #name "_client", name, description, flags, completion ); \
  1009 		static void name( void *pUnknown, const CCommand &args )
  1010 #else
  1011 	#define CON_COMMAND_F_COMPLETION_SHARED( name, description, flags, completion ) \
  1012 		static void name( void *pUnknown, const CCommand &args ); \
  1013 		static ConCommand name##_command( #name, name, description, flags, completion ); \
  1014 		static void name( void *pUnknown, const CCommand &args )
  1015 #endif
  1016 
  1017 
  1018 #define CON_COMMAND_EXTERN( name, _funcname, description ) \
  1019 	void _funcname( void *pUnknown, const CCommand &args ); \
  1020 	static ConCommand name##_command( #name, _funcname, description ); \
  1021 	void _funcname( void *pUnknown, const CCommand &args )
  1022 
  1023 #define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \
  1024 	void _funcname( void *pUnknown, const CCommand &args ); \
  1025 	static ConCommand name##_command( #name, _funcname, description, flags ); \
  1026 	void _funcname( void *pUnknown, const CCommand &args )
  1027 
  1028 #define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \
  1029 	void _funcname( void *pUnknown, const CCommand &args );						\
  1030 	friend class CCommandMemberInitializer_##_funcname;			\
  1031 	class CCommandMemberInitializer_##_funcname					\
  1032 	{															\
  1033 	public:														\
  1034 		CCommandMemberInitializer_##_funcname() : m_ConCommandAccessor( NULL, name, &_thisclass::_funcname, description, flags )	\
  1035 		{														\
  1036 			m_ConCommandAccessor.SetOwner( GET_OUTER( _thisclass, m_##_funcname##_register ) );	\
  1037 		}														\
  1038 	private:													\
  1039 		CConCommandMemberAccessor< _thisclass > m_ConCommandAccessor;	\
  1040 	};															\
  1041 																\
  1042 	CCommandMemberInitializer_##_funcname m_##_funcname##_register;		\
  1043 
  1044 
  1045 #endif // CONVAR_H