Team Fortress 2 Source Code as on 22/4/2020
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.

311 lines
7.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: The main manager of the UI
  4. //
  5. // $Revision: $
  6. // $NoKeywords: $
  7. //===========================================================================//
  8. #include "inputmanager.h"
  9. #include "legion.h"
  10. #include "uimanager.h"
  11. #include "inputsystem/iinputsystem.h"
  12. #include "tier2/tier2.h"
  13. #include "tier1/convar.h"
  14. //-----------------------------------------------------------------------------
  15. // Singleton accessor
  16. //-----------------------------------------------------------------------------
  17. static CInputManager s_InputManager;
  18. extern CInputManager *g_pInputManager = &s_InputManager;
  19. //-----------------------------------------------------------------------------
  20. // Initialization
  21. //-----------------------------------------------------------------------------
  22. bool CInputManager::Init()
  23. {
  24. // FIXME: Read keybindings from a file
  25. m_KeyBindings.SetBinding( "w", "+forward" );
  26. m_KeyBindings.SetBinding( "s", "+back" );
  27. m_KeyBindings.SetBinding( "`", "toggleconsole" );
  28. m_ButtonUpToEngine.ClearAll();
  29. return true;
  30. }
  31. //-----------------------------------------------------------------------------
  32. // Add a command into the command queue
  33. //-----------------------------------------------------------------------------
  34. void CInputManager::AddCommand( const char *pCommand )
  35. {
  36. m_CommandBuffer.AddText( pCommand );
  37. }
  38. //-----------------------------------------------------------------------------
  39. // FIXME! This is necessary only because of an artifact of how ConCommands used to work
  40. //-----------------------------------------------------------------------------
  41. static ConCommand *FindNamedCommand( char const *name )
  42. {
  43. // look through the command list for all matches
  44. ConCommandBase const *cmd = (ConCommandBase const *)vgui::icvar()->GetCommands();
  45. while (cmd)
  46. {
  47. if (!Q_strcmp( name, cmd->GetName() ) )
  48. {
  49. if ( cmd->IsCommand() )
  50. {
  51. return ( ConCommand * )cmd;
  52. }
  53. }
  54. cmd = cmd->GetNext();
  55. }
  56. return NULL;
  57. }
  58. //-----------------------------------------------------------------------------
  59. // Purpose:
  60. //-----------------------------------------------------------------------------
  61. void CInputManager::PrintConCommandBaseDescription( const ConCommandBase *pVar )
  62. {
  63. bool bMin, bMax;
  64. float fMin, fMax;
  65. const char *pStr;
  66. Assert( pVar );
  67. Color clr;
  68. clr.SetColor( 255, 100, 100, 255 );
  69. if ( !pVar->IsCommand() )
  70. {
  71. ConVar *var = ( ConVar * )pVar;
  72. bMin = var->GetMin( fMin );
  73. bMax = var->GetMax( fMax );
  74. char const *value = NULL;
  75. char tempVal[ 32 ];
  76. if ( var->IsBitSet( FCVAR_NEVER_AS_STRING ) )
  77. {
  78. value = tempVal;
  79. if ( fabs( (float)var->GetInt() - var->GetFloat() ) < 0.000001 )
  80. {
  81. Q_snprintf( tempVal, sizeof( tempVal ), "%d", var->GetInt() );
  82. }
  83. else
  84. {
  85. Q_snprintf( tempVal, sizeof( tempVal ), "%f", var->GetFloat() );
  86. }
  87. }
  88. else
  89. {
  90. value = var->GetString();
  91. }
  92. if ( value )
  93. {
  94. Msg( "\"%s\" = \"%s\"", var->GetName(), value );
  95. if ( Q_stricmp( value, var->GetDefault() ) )
  96. {
  97. Msg( " ( def. \"%s\" )", var->GetDefault() );
  98. }
  99. }
  100. if ( bMin )
  101. {
  102. Msg( " min. %f", fMin );
  103. }
  104. if ( bMax )
  105. {
  106. Msg( " max. %f", fMax );
  107. }
  108. Msg( "\n" );
  109. }
  110. else
  111. {
  112. ConCommand *var = ( ConCommand * )pVar;
  113. Msg( "\"%s\"\n", var->GetName() );
  114. }
  115. // PrintConCommandBaseFlags( pVar );
  116. pStr = pVar->GetHelpText();
  117. if ( pStr && pStr[0] )
  118. {
  119. Msg( " - %s\n", pStr );
  120. }
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Per-frame update
  124. //-----------------------------------------------------------------------------
  125. void CInputManager::ProcessCommands( )
  126. {
  127. m_CommandBuffer.BeginProcessingCommands( 1 );
  128. while ( m_CommandBuffer.DequeueNextCommand() )
  129. {
  130. const CCommand& args = m_CommandBuffer.GetCommand();
  131. const ConCommandBase *pCommand = FindNamedCommand( args[ 0 ] );
  132. if ( pCommand && pCommand->IsCommand() )
  133. {
  134. // FIXME: Um... yuck!?!
  135. ConCommand *pConCommand = const_cast<ConCommand*>( static_cast<const ConCommand*>( pCommand ) );
  136. pConCommand->Dispatch( args );
  137. continue;
  138. }
  139. ConVar *pConVar = g_pCVar->FindVar( args[0] );
  140. if ( !pConVar )
  141. continue;
  142. // perform a variable print or set
  143. if ( args.ArgC() == 1 )
  144. {
  145. PrintConCommandBaseDescription( pConVar );
  146. continue;
  147. }
  148. // Note that we don't want the tokenized list, send down the entire string
  149. // except for surrounding quotes
  150. char remaining[1024];
  151. const char *pArgS = args.ArgS();
  152. int nLen = Q_strlen( pArgS );
  153. bool bIsQuoted = pArgS[0] == '\"';
  154. if ( !bIsQuoted )
  155. {
  156. Q_strncpy( remaining, args.ArgS(), sizeof(remaining) );
  157. }
  158. else
  159. {
  160. --nLen;
  161. Q_strncpy( remaining, &pArgS[1], sizeof(remaining) );
  162. }
  163. // Now strip off any trailing spaces
  164. char *p = remaining + nLen - 1;
  165. while ( p >= remaining )
  166. {
  167. if ( *p > ' ' )
  168. break;
  169. *p-- = 0;
  170. }
  171. // Strip off ending quote
  172. if ( bIsQuoted && p >= remaining )
  173. {
  174. if ( *p == '\"' )
  175. {
  176. *p = 0;
  177. }
  178. }
  179. if ( pConVar->IsBitSet( FCVAR_NEVER_AS_STRING ) )
  180. {
  181. pConVar->SetValue( (float)atof( remaining ) );
  182. }
  183. else
  184. {
  185. pConVar->SetValue( remaining );
  186. }
  187. }
  188. m_CommandBuffer.EndProcessingCommands();
  189. }
  190. //-----------------------------------------------------------------------------
  191. // Per-frame update
  192. //-----------------------------------------------------------------------------
  193. void CInputManager::Update( )
  194. {
  195. char cmd[1024];
  196. g_pInputSystem->PollInputState();
  197. int nEventCount = g_pInputSystem->GetEventCount();
  198. const InputEvent_t* pEvents = g_pInputSystem->GetEventData( );
  199. for ( int i = 0; i < nEventCount; ++i )
  200. {
  201. if ( pEvents[i].m_nType == IE_Quit )
  202. {
  203. IGameManager::Stop();
  204. break;
  205. }
  206. bool bBypassVGui = false;
  207. switch( pEvents[i].m_nType )
  208. {
  209. case IE_AppActivated:
  210. if ( pEvents[i].m_nData == 0 )
  211. {
  212. m_ButtonUpToEngine.ClearAll();
  213. }
  214. break;
  215. case IE_ButtonReleased:
  216. {
  217. // This logic is necessary to deal with switching back + forth
  218. // between vgui + the engine. If we downclick in the engine,
  219. // the engine must get the upclick.
  220. ButtonCode_t code = (ButtonCode_t)pEvents[i].m_nData;
  221. if ( m_ButtonUpToEngine[ code ] )
  222. {
  223. m_ButtonUpToEngine.Clear( code );
  224. bBypassVGui = true;
  225. }
  226. }
  227. break;
  228. default:
  229. break;
  230. }
  231. if ( !bBypassVGui )
  232. {
  233. if ( g_pUIManager->ProcessInputEvent( pEvents[i] ) )
  234. continue;
  235. }
  236. // FIXME: Add game keybinding system here
  237. bool bButtonDown = ( pEvents[i].m_nType == IE_ButtonPressed );
  238. bool bButtonUp = ( pEvents[i].m_nType == IE_ButtonReleased );
  239. if ( bButtonDown || bButtonUp )
  240. {
  241. ButtonCode_t code = (ButtonCode_t)pEvents[i].m_nData;
  242. if ( bButtonDown )
  243. {
  244. m_ButtonUpToEngine.Set( code );
  245. }
  246. const char *pBinding = m_KeyBindings.GetBindingForButton( code );
  247. if ( !pBinding )
  248. continue;
  249. if ( pBinding[0] != '+' )
  250. {
  251. if ( bButtonDown )
  252. {
  253. m_CommandBuffer.AddText( pBinding );
  254. }
  255. continue;
  256. }
  257. Q_snprintf( cmd, sizeof(cmd), "%c%s %i\n", bButtonUp ? '-' : '+', &pBinding[1], code );
  258. m_CommandBuffer.AddText( cmd );
  259. continue;
  260. }
  261. }
  262. ProcessCommands();
  263. }