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

1169 lines
38 KiB

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