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