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.

304 lines
9.0 KiB

  1. //===== Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ====//
  2. //
  3. // Purpose: Contains all utility methods for the new game UI system
  4. //
  5. //===========================================================================//
  6. #include "cbase.h"
  7. #include "gameui.h"
  8. #include "game_controls/igameuisystemmgr.h"
  9. #include "tier1/timeutils.h"
  10. #include "cdll_client_int.h"
  11. #include "soundemittersystem/isoundemittersystembase.h"
  12. #include "engine/ienginesound.h"
  13. #include "filesystem.h"
  14. #include "inputsystem/iinputstacksystem.h"
  15. #include "gameui/basemodpanel.h"
  16. #include "gameui/nuggets/ui_nugget.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include "tier0/memdbgon.h"
  19. // A logging channel used during engine initialization
  20. DEFINE_LOGGING_CHANNEL_NO_TAGS( LOG_GameUI, "GameUI" );
  21. LINK_GAME_CONTROLS_LIB();
  22. // A utility function to determine if we are running as part of game ui base mod panel
  23. inline bool IsPartOfGameUiBaseModPanel()
  24. {
  25. BaseModUI::CBaseModPanel *pPanel = BaseModUI::CBaseModPanel::GetSingletonPtr();
  26. if ( !pPanel )
  27. return false;
  28. return pPanel->IsVisible();
  29. }
  30. //-----------------------------------------------------------------------------
  31. // Default game ui sound playback implementation
  32. //-----------------------------------------------------------------------------
  33. class CInGameUISoundPlayback : public IGameUISoundPlayback
  34. {
  35. public:
  36. void *EmitSound( const char *pSoundName )
  37. {
  38. if ( developer.GetBool() )
  39. {
  40. // Ensure the sound is valid
  41. int nSoundIndex = g_pSoundEmitterSystem->GetSoundIndex( pSoundName );
  42. if ( !g_pSoundEmitterSystem->IsValidIndex( nSoundIndex ) )
  43. {
  44. Log_Warning( LOG_GameUI, "Attempted to play invalid sound \"%s\"\n", pSoundName );
  45. return NULL;
  46. }
  47. const char *pSourceFile = g_pSoundEmitterSystem->GetSourceFileForSound( nSoundIndex );
  48. if ( !Q_stristr( pSourceFile, "game_sounds_ui.txt" ) )
  49. {
  50. Log_Warning( LOG_GameUI, "Attempted to play invalid sound \"%s\". This sound must be defined\n"
  51. "in game_sounds_ui.txt but was defined in \"%s\" instead.\n", pSoundName, pSourceFile );
  52. return NULL;
  53. }
  54. }
  55. // Pull data from parameters
  56. CSoundParameters params;
  57. HSOUNDSCRIPTHASH handle = SOUNDEMITTER_INVALID_HASH;
  58. if ( !soundemitterbase->GetParametersForSoundEx( pSoundName, handle, params, GENDER_NONE, true ) )
  59. {
  60. Log_Warning( LOG_GameUI, "Attempted to play invalid sound \"%s\"\n", pSoundName );
  61. return NULL;
  62. }
  63. if ( !params.soundname[0] )
  64. {
  65. Log_Warning( LOG_GameUI, "Attempted to play invalid sound \"%s\", which has no .wav!\n", pSoundName );
  66. return NULL;
  67. }
  68. float st = 0.0f;
  69. if ( params.delay_msec != 0.0f )
  70. {
  71. st = gpGlobals->curtime + (float)params.delay_msec / 1000.f;
  72. }
  73. CLocalPlayerFilter filter;
  74. enginesound->EmitSound(
  75. filter,
  76. SOUND_FROM_LOCAL_PLAYER,
  77. params.channel,
  78. pSoundName,
  79. handle,
  80. params.soundname,
  81. params.volume,
  82. (soundlevel_t)params.soundlevel,
  83. params.m_nRandomSeed,
  84. 0, // flags
  85. params.pitch,
  86. NULL,
  87. NULL,
  88. NULL,
  89. true,
  90. st );
  91. return (void*)enginesound->GetGuidForLastSoundEmitted();
  92. }
  93. void StopSound( void *pSoundHandle )
  94. {
  95. if ( !pSoundHandle || !g_pSoundSystem )
  96. return;
  97. int nGuid = (int)pSoundHandle;
  98. enginesound->StopSoundByGuid( nGuid );
  99. }
  100. };
  101. static CInGameUISoundPlayback s_InGameUISoundPlayback;
  102. //-----------------------------------------------------------------------------
  103. // Instantiate singleton game system
  104. //-----------------------------------------------------------------------------
  105. static CGameUIGameSystem s_GameUIGameSystem;
  106. CGameUIGameSystem *g_pGameUIGameSystem = &s_GameUIGameSystem;
  107. //-----------------------------------------------------------------------------
  108. // Initialization
  109. //-----------------------------------------------------------------------------
  110. bool CGameUIGameSystem::Init()
  111. {
  112. g_pGameUISystemMgr->UseGameInputSystemEventQueue( true );
  113. g_pGameUISystemMgr->SetSoundPlayback( &s_InGameUISoundPlayback );
  114. g_pGameUISystemMgr->SetInputContext( engine->GetInputContext( ENGINE_INPUT_CONTEXT_GAMEUI ) );
  115. // Register all client nugget factories
  116. CUiNuggetFactoryRegistrarBase::RegisterAll();
  117. return true;
  118. }
  119. void CGameUIGameSystem::Shutdown()
  120. {
  121. g_pGameUISystemMgr->SetSoundPlayback( NULL );
  122. g_pGameUISystemMgr->SetInputContext( INPUT_CONTEXT_HANDLE_INVALID );
  123. }
  124. //-----------------------------------------------------------------------------
  125. // PostInit
  126. //-----------------------------------------------------------------------------
  127. void CGameUIGameSystem::PostInit()
  128. {
  129. // This cannot happen in Init() because the audio system isn't set up
  130. // at that point, and it needs to be for precache to succeed
  131. PrecacheGameUISounds();
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Precaches all game UI sounds
  135. //-----------------------------------------------------------------------------
  136. void CGameUIGameSystem::PrecacheGameUISounds()
  137. {
  138. // Precache all UI sounds. These must exist in the game_sounds_ui.txt script file
  139. KeyValues *pUIGameSounds = new KeyValues( "Game Instructor Counts" );
  140. if ( !pUIGameSounds->LoadFromFile( g_pFullFileSystem, "scripts/game_sounds_ui.txt", "GAME" ) )
  141. {
  142. pUIGameSounds->deleteThis();
  143. return;
  144. }
  145. for ( KeyValues *pKey = pUIGameSounds; pKey; pKey = pKey->GetNextKey() )
  146. {
  147. const char *pSoundName = pKey->GetName();
  148. int nSoundIndex = soundemitterbase->GetSoundIndex( pSoundName );
  149. if ( !soundemitterbase->IsValidIndex( nSoundIndex ) )
  150. {
  151. Log_Warning( LOG_GameUI, "GameUI: Unable to precache gamesound \"%s\"\n", pSoundName );
  152. continue;
  153. }
  154. CSoundParametersInternal *pInternal = soundemitterbase->InternalGetParametersForSound( nSoundIndex );
  155. if ( !pInternal )
  156. {
  157. Log_Warning( LOG_GameUI, "GameUI: Unable to precache gamesound \"%s\"\n", pSoundName );
  158. continue;
  159. }
  160. int nWaveCount = pInternal->NumSoundNames();
  161. if ( !nWaveCount )
  162. {
  163. Log_Warning( LOG_GameUI, "GameUI: game_sounds_ui.txt entry '%s' has no waves listed under 'wave' or 'rndwave' key!!!\n", pSoundName );
  164. continue;
  165. }
  166. for( int nWave = 0; nWave < nWaveCount; ++nWave )
  167. {
  168. const char *pWavName = soundemitterbase->GetWaveName( pInternal->GetSoundNames()[ nWave ].symbol );
  169. enginesound->PrecacheSound( pWavName, true, true );
  170. }
  171. }
  172. pUIGameSounds->deleteThis();
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Reloads game GUI sounds
  176. //-----------------------------------------------------------------------------
  177. void CGameUIGameSystem::ReloadSounds()
  178. {
  179. // Should I stop all currently playing sounds?
  180. PrecacheGameUISounds();
  181. }
  182. //-----------------------------------------------------------------------------
  183. // Init any render targets needed by the UI.
  184. //-----------------------------------------------------------------------------
  185. void CGameUIGameSystem::InitRenderTargets()
  186. {
  187. g_pGameUISystemMgr->InitRenderTargets();
  188. }
  189. //-----------------------------------------------------------------------------
  190. // Init any render targets needed by the UI.
  191. //-----------------------------------------------------------------------------
  192. IMaterialProxy *CGameUIGameSystem::CreateProxy( const char *proxyName )
  193. {
  194. return g_pGameUISystemMgr->CreateProxy( proxyName );
  195. }
  196. //-----------------------------------------------------------------------------
  197. // Renders the game UI
  198. //-----------------------------------------------------------------------------
  199. void CGameUIGameSystem::Render( const Rect_t &viewport, float flCurrentTime )
  200. {
  201. g_pGameUISystemMgr->Render( viewport, DmeTime_t( flCurrentTime ) );
  202. }
  203. //-----------------------------------------------------------------------------
  204. // Registers an input event
  205. //-----------------------------------------------------------------------------
  206. bool CGameUIGameSystem::RegisterInputEvent( const InputEvent_t &iEvent )
  207. {
  208. if ( !g_pGameUISystemMgr->GetGameUIVisible() )
  209. return false;
  210. switch( iEvent.m_nType )
  211. {
  212. case IE_ButtonPressed:
  213. {
  214. // NOTE: data2 is the virtual key code (data1 contains the scan-code one)
  215. ButtonCode_t code = (ButtonCode_t)iEvent.m_nData2;
  216. if ( code == KEY_BACKQUOTE )
  217. {
  218. return false;
  219. }
  220. else if ( code == KEY_ESCAPE )
  221. {
  222. return false;
  223. }
  224. }
  225. break;
  226. case IE_ButtonReleased:
  227. {
  228. // NOTE: data2 is the virtual key code (data1 contains the scan-code one)
  229. ButtonCode_t code = (ButtonCode_t)iEvent.m_nData2;
  230. if ( code == KEY_BACKQUOTE )
  231. {
  232. return false;
  233. }
  234. else if ( code == KEY_ESCAPE )
  235. {
  236. return false;
  237. }
  238. }
  239. break;
  240. default:
  241. break;
  242. }
  243. g_pGameUISystemMgr->RegisterInputEvent( iEvent );
  244. // FIXME: This is a hack; we're saying that the system eats the
  245. // input as long as a menu is visible
  246. return g_pGameUISystemMgr->GetGameUIVisible();
  247. }
  248. //-----------------------------------------------------------------------------
  249. // Simulates the next frame
  250. //-----------------------------------------------------------------------------
  251. void CGameUIGameSystem::Update( float frametime )
  252. {
  253. if ( IsPartOfGameUiBaseModPanel() )
  254. // Prevent double-updates during a frame when running as part of game ui
  255. // base mod panel rendering and event processing
  256. return;
  257. g_pGameUISystemMgr->RunFrame();
  258. }