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.

2371 lines
66 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Implements all the functions exported by the GameUI dll
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #include "client_pch.h"
  8. #include "tier0/platform.h"
  9. #ifdef IS_WINDOWS_PC
  10. #include "winlite.h"
  11. #endif
  12. #include "appframework/ilaunchermgr.h"
  13. #include <vgui_controls/Panel.h>
  14. #include <vgui_controls/EditablePanel.h>
  15. #include <matsys_controls/matsyscontrols.h>
  16. #include <vgui/Cursor.h>
  17. #include <vgui_controls/PHandle.h>
  18. #include "keys.h"
  19. #include "console.h"
  20. #include "gl_matsysiface.h"
  21. #include "cdll_engine_int.h"
  22. #include "demo.h"
  23. #include "sys_dll.h"
  24. #include "sound.h"
  25. #include "soundflags.h"
  26. #include "filesystem_engine.h"
  27. #include "igame.h"
  28. #include "con_nprint.h"
  29. #include "vgui_DebugSystemPanel.h"
  30. #include "tier0/vprof.h"
  31. #include "cl_demoactionmanager.h"
  32. #include "enginebugreporter.h"
  33. #include "engineperftools.h"
  34. #include "icolorcorrectiontools.h"
  35. #include "tier0/icommandline.h"
  36. #include "client.h"
  37. #include "server.h"
  38. #include "sys.h" // Sys_GetRegKeyValue()
  39. #include "vgui_drawtreepanel.h"
  40. #include "vgui_vprofpanel.h"
  41. #include "vgui/VGUI.h"
  42. #include "vgui/IInput.h"
  43. #include <vgui/IInputInternal.h>
  44. #include "vgui_controls/AnimationController.h"
  45. #include "vgui_vprofgraphpanel.h"
  46. #include "vgui_texturebudgetpanel.h"
  47. #include "vgui_budgetpanel.h"
  48. #include "ivideomode.h"
  49. #include "sourcevr/isourcevirtualreality.h"
  50. #include "cl_pluginhelpers.h"
  51. #include "cl_main.h" // CL_IsHL2Demo()
  52. #include "cl_steamauth.h"
  53. // interface to gameui dll
  54. #include <GameUI/IGameUI.h>
  55. #include <GameUI/IGameConsole.h>
  56. // interface to expose vgui root panels
  57. #include <ienginevgui.h>
  58. #include "VGuiMatSurface/IMatSystemSurface.h"
  59. #include "cl_texturelistpanel.h"
  60. #include "cl_demouipanel.h"
  61. #include "cl_foguipanel.h"
  62. #include "cl_txviewpanel.h"
  63. // vgui2 interface
  64. // note that GameUI project uses ..\public\vgui and ..\public\vgui_controls, not ..\utils\vgui\include
  65. #include <vgui/VGUI.h>
  66. #include <vgui/Cursor.h>
  67. #include <KeyValues.h>
  68. #include <vgui/ILocalize.h>
  69. #include <vgui/IPanel.h>
  70. #include <vgui/IScheme.h>
  71. #include <vgui/IVGui.h>
  72. #include <vgui/ISystem.h>
  73. #include <vgui/ISurface.h>
  74. #include <vgui_controls/EditablePanel.h>
  75. #include <vgui_controls/MenuButton.h>
  76. #include <vgui_controls/Menu.h>
  77. #include <vgui_controls/PHandle.h>
  78. #include "IVguiModule.h"
  79. #include "vgui_baseui_interface.h"
  80. #include "vgui_DebugSystemPanel.h"
  81. #include "toolframework/itoolframework.h"
  82. #include "filesystem/IQueuedLoader.h"
  83. #if defined( _X360 )
  84. #include "xbox/xbox_win32stubs.h"
  85. #endif
  86. #include "vgui_askconnectpanel.h"
  87. #if defined( REPLAY_ENABLED )
  88. #include "replay_internal.h"
  89. #endif
  90. // memdbgon must be the last include file in a .cpp file!!!
  91. #include "tier0/memdbgon.h"
  92. #ifndef USE_SDL
  93. extern HWND *pmainwindow;
  94. #endif
  95. extern IVEngineClient *engineClient;
  96. extern bool g_bTextMode;
  97. static int g_syncReportLevel = -1;
  98. void VGui_ActivateMouse();
  99. extern CreateInterfaceFn g_AppSystemFactory;
  100. // functions to reference GameUI and GameConsole functions, from GameUI.dll
  101. IGameUI *staticGameUIFuncs = NULL;
  102. IGameConsole *staticGameConsole = NULL;
  103. // cache some of the state we pass through to matsystemsurface, for visibility
  104. bool s_bWindowsInputEnabled = true;
  105. ConVar r_drawvgui( "r_drawvgui", "1", FCVAR_CHEAT, "Enable the rendering of vgui panels" );
  106. ConVar gameui_xbox( "gameui_xbox", "0", 0 );
  107. void Con_CreateConsolePanel( vgui::Panel *parent );
  108. void CL_CreateEntityReportPanel( vgui::Panel *parent );
  109. void ClearIOStates( void );
  110. // turn this on if you're tuning progress bars
  111. //#define ENABLE_LOADING_PROGRESS_PROFILING
  112. //-----------------------------------------------------------------------------
  113. // Purpose: Console command to hide the gameUI, most commonly called from gameUI.dll
  114. //-----------------------------------------------------------------------------
  115. CON_COMMAND( gameui_hide, "Hides the game UI" )
  116. {
  117. EngineVGui()->HideGameUI();
  118. }
  119. //-----------------------------------------------------------------------------
  120. // Purpose: Console command to activate the gameUI, most commonly called from gameUI.dll
  121. //-----------------------------------------------------------------------------
  122. CON_COMMAND( gameui_activate, "Shows the game UI" )
  123. {
  124. EngineVGui()->ActivateGameUI();
  125. }
  126. //-----------------------------------------------------------------------------
  127. // Purpose:
  128. //-----------------------------------------------------------------------------
  129. CON_COMMAND( gameui_preventescape, "Escape key doesn't hide game UI" )
  130. {
  131. EngineVGui()->SetNotAllowedToHideGameUI( true );
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Purpose:
  135. //-----------------------------------------------------------------------------
  136. CON_COMMAND( gameui_allowescapetoshow, "Escape key allowed to show game UI" )
  137. {
  138. EngineVGui()->SetNotAllowedToShowGameUI( false );
  139. }
  140. //-----------------------------------------------------------------------------
  141. // Purpose:
  142. //-----------------------------------------------------------------------------
  143. CON_COMMAND( gameui_preventescapetoshow, "Escape key doesn't show game UI" )
  144. {
  145. EngineVGui()->SetNotAllowedToShowGameUI( true );
  146. }
  147. //-----------------------------------------------------------------------------
  148. // Purpose:
  149. //-----------------------------------------------------------------------------
  150. CON_COMMAND( gameui_allowescape, "Escape key allowed to hide game UI" )
  151. {
  152. EngineVGui()->SetNotAllowedToHideGameUI( false );
  153. }
  154. //-----------------------------------------------------------------------------
  155. // Purpose: Console command to enable progress bar for next load
  156. //-----------------------------------------------------------------------------
  157. void BaseUI_ProgressEnabled_f()
  158. {
  159. EngineVGui()->EnabledProgressBarForNextLoad();
  160. }
  161. static ConCommand progress_enable("progress_enable", &BaseUI_ProgressEnabled_f );
  162. //-----------------------------------------------------------------------------
  163. // Purpose:
  164. //-----------------------------------------------------------------------------
  165. class CEnginePanel : public vgui::EditablePanel
  166. {
  167. typedef vgui::EditablePanel BaseClass;
  168. public:
  169. CEnginePanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
  170. {
  171. //m_bCanFocus = true;
  172. SetMouseInputEnabled( true );
  173. SetKeyBoardInputEnabled( true );
  174. }
  175. void EnableMouseFocus( bool state )
  176. {
  177. //m_bCanFocus = state;
  178. SetMouseInputEnabled( state );
  179. SetKeyBoardInputEnabled( state );
  180. }
  181. /* virtual vgui::VPANEL IsWithinTraverse(int x, int y, bool traversePopups)
  182. {
  183. if ( !m_bCanFocus )
  184. return NULL;
  185. vgui::VPANEL retval = BaseClass::IsWithinTraverse( x, y, traversePopups );
  186. if ( retval == GetVPanel() )
  187. return NULL;
  188. return retval;
  189. }*/
  190. //private:
  191. // bool m_bCanFocus;
  192. };
  193. //-----------------------------------------------------------------------------
  194. // Purpose:
  195. //-----------------------------------------------------------------------------
  196. class CStaticPanel : public vgui::Panel
  197. {
  198. typedef vgui::Panel BaseClass;
  199. public:
  200. CStaticPanel( vgui::Panel *pParent, const char *pName ) : vgui::Panel( pParent, pName )
  201. {
  202. SetCursor( vgui::dc_none );
  203. SetKeyBoardInputEnabled( false );
  204. SetMouseInputEnabled( false );
  205. }
  206. };
  207. vgui::VPanelHandle g_DrawTreeSelectedPanel;
  208. //-----------------------------------------------------------------------------
  209. // Purpose:
  210. //-----------------------------------------------------------------------------
  211. class CFocusOverlayPanel : public vgui::Panel
  212. {
  213. typedef vgui::Panel BaseClass;
  214. public:
  215. CFocusOverlayPanel( vgui::Panel *pParent, const char *pName );
  216. virtual void PostChildPaint( void );
  217. static void GetColorForSlot( int slot, int& r, int& g, int& b )
  218. {
  219. r = (int)( 124.0 + slot * 47.3 ) & 255;
  220. g = (int)( 63.78 - slot * 71.4 ) & 255;
  221. b = (int)( 188.42 + slot * 13.57 ) & 255;
  222. }
  223. bool DrawTitleSafeOverlay( void );
  224. bool DrawFocusPanelList( void );
  225. };
  226. //-----------------------------------------------------------------------------
  227. //
  228. // Purpose: Centerpoint for handling all user interface in the engine
  229. //
  230. //-----------------------------------------------------------------------------
  231. class CEngineVGui : public IEngineVGuiInternal
  232. {
  233. public:
  234. CEngineVGui();
  235. ~CEngineVGui();
  236. // Methods of IEngineVGui
  237. virtual vgui::VPANEL GetPanel( VGuiPanel_t type );
  238. // Methods of IEngineVGuiInternal
  239. virtual void Init();
  240. virtual void Connect();
  241. virtual void Shutdown();
  242. virtual bool SetVGUIDirectories();
  243. virtual bool IsInitialized() const;
  244. virtual bool Key_Event( const InputEvent_t &event );
  245. virtual void UpdateButtonState( const InputEvent_t &event );
  246. virtual void BackwardCompatibility_Paint();
  247. virtual void Paint( PaintMode_t mode );
  248. virtual void PostInit();
  249. CreateInterfaceFn GetGameUIFactory()
  250. {
  251. return m_GameUIFactory;
  252. }
  253. // handlers for game UI (main menu)
  254. virtual void ActivateGameUI();
  255. virtual bool HideGameUI();
  256. virtual bool IsGameUIVisible();
  257. // console
  258. virtual void ShowConsole();
  259. virtual void HideConsole();
  260. virtual bool IsConsoleVisible();
  261. virtual void ClearConsole();
  262. // level loading
  263. virtual void OnLevelLoadingStarted();
  264. virtual void OnLevelLoadingFinished();
  265. virtual void NotifyOfServerConnect(const char *game, int IP, int connectionPort, int queryPort);
  266. virtual void NotifyOfServerDisconnect();
  267. virtual void UpdateProgressBar(LevelLoadingProgress_e progress);
  268. virtual void UpdateCustomProgressBar( float progress, const wchar_t *desc );
  269. virtual void StartCustomProgress();
  270. virtual void FinishCustomProgress();
  271. virtual void EnabledProgressBarForNextLoad()
  272. {
  273. m_bShowProgressDialog = true;
  274. }
  275. // Should pause?
  276. virtual bool ShouldPause();
  277. virtual void ShowErrorMessage();
  278. virtual void SetNotAllowedToHideGameUI( bool bNotAllowedToHide )
  279. {
  280. m_bNotAllowedToHideGameUI = bNotAllowedToHide;
  281. }
  282. virtual void SetNotAllowedToShowGameUI( bool bNotAllowedToShow )
  283. {
  284. m_bNotAllowedToShowGameUI = bNotAllowedToShow;
  285. }
  286. void SetGameDLLPanelsVisible( bool show )
  287. {
  288. if ( !staticGameDLLPanel )
  289. {
  290. return;
  291. }
  292. staticGameDLLPanel->SetVisible( show );
  293. }
  294. virtual void ShowNewGameDialog( int chapter = -1 ); // -1 means just keep the currently select chapter
  295. // Xbox 360
  296. virtual void SessionNotification( const int notification, const int param = 0 );
  297. virtual void SystemNotification( const int notification );
  298. virtual void ShowMessageDialog( const uint nType, vgui::Panel *pOwner = NULL );
  299. virtual void UpdatePlayerInfo( uint64 nPlayerId, const char *pName, int nTeam, byte cVoiceState, int nPlayersNeeded, bool bHost );
  300. virtual void SessionSearchResult( int searchIdx, void *pHostData, XSESSION_SEARCHRESULT *pResult, int ping );
  301. virtual void OnCreditsFinished( void );
  302. // Storage device validation:
  303. // returns true right away if storage device has been previously selected.
  304. // otherwise returns false and will set the variable pointed by pStorageDeviceValidated to 1
  305. // once the storage device is selected by user.
  306. virtual bool ValidateStorageDevice( int *pStorageDeviceValidated );
  307. void SetProgressBias( float bias );
  308. void UpdateProgressBar( float progress );
  309. virtual void ConfirmQuit( void );
  310. private:
  311. vgui::Panel *GetRootPanel( VGuiPanel_t type );
  312. void SetEngineVisible( bool state );
  313. void DrawMouseFocus( void );
  314. void CreateVProfPanels( vgui::Panel *pParent );
  315. void DestroyVProfPanels( );
  316. virtual void Simulate();
  317. // debug overlays
  318. bool IsDebugSystemVisible();
  319. void HideDebugSystem();
  320. bool IsShiftKeyDown();
  321. bool IsAltKeyDown();
  322. bool IsCtrlKeyDown();
  323. CON_COMMAND_MEMBER_F( CEngineVGui, "debugsystemui", ToggleDebugSystemUI, "Show/hide the debug system UI.", FCVAR_CHEAT );
  324. private:
  325. enum { MAX_NUM_FACTORIES = 5 };
  326. CreateInterfaceFn m_FactoryList[MAX_NUM_FACTORIES];
  327. int m_iNumFactories;
  328. CSysModule *m_hStaticGameUIModule;
  329. CreateInterfaceFn m_GameUIFactory;
  330. // top level VGUI2 panel
  331. CStaticPanel *staticPanel;
  332. // base level panels for other subsystems, rooted on staticPanel
  333. CEnginePanel *staticClientDLLPanel;
  334. CEnginePanel *staticClientDLLToolsPanel;
  335. CEnginePanel *staticGameUIPanel;
  336. CEnginePanel *staticGameDLLPanel;
  337. // Want engine tools to be on top of other engine panels
  338. CEnginePanel *staticEngineToolsPanel;
  339. CDebugSystemPanel *staticDebugSystemPanel;
  340. CFocusOverlayPanel *staticFocusOverlayPanel;
  341. #ifdef VPROF_ENABLED
  342. CVProfPanel *m_pVProfPanel;
  343. CBudgetPanelEngine *m_pBudgetPanel;
  344. CTextureBudgetPanel *m_pTextureBudgetPanel;
  345. #endif
  346. // progress bar
  347. bool m_bShowProgressDialog;
  348. LevelLoadingProgress_e m_eLastProgressPoint;
  349. // progress bar debugging
  350. int m_nLastProgressPointRepeatCount;
  351. double m_flLoadingStartTime;
  352. struct LoadingProgressEntry_t
  353. {
  354. double flTime;
  355. LevelLoadingProgress_e eProgress;
  356. };
  357. CUtlVector<LoadingProgressEntry_t> m_LoadingProgress;
  358. bool m_bSaveProgress : 1;
  359. bool m_bNoShaderAPI : 1;
  360. // game ui hiding control
  361. bool m_bNotAllowedToHideGameUI : 1;
  362. bool m_bNotAllowedToShowGameUI : 1;
  363. vgui::IInputInternal *m_pInputInternal;
  364. // used to start the progress from an arbitrary position
  365. float m_ProgressBias;
  366. };
  367. //-----------------------------------------------------------------------------
  368. // Purpose: singleton accessor
  369. //-----------------------------------------------------------------------------
  370. static CEngineVGui g_EngineVGuiImp;
  371. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CEngineVGui, IEngineVGui, VENGINE_VGUI_VERSION, g_EngineVGuiImp );
  372. IEngineVGuiInternal *EngineVGui()
  373. {
  374. return &g_EngineVGuiImp;
  375. }
  376. //-----------------------------------------------------------------------------
  377. // The loader progress is updated by the queued loader. It uses an initial
  378. // reserved portion of the bar.
  379. //-----------------------------------------------------------------------------
  380. #define PROGRESS_RESERVE 0.50f
  381. class CLoaderProgress : public ILoaderProgress
  382. {
  383. public:
  384. CLoaderProgress()
  385. {
  386. // initialize to disabled state
  387. m_SnappedProgress = -1;
  388. }
  389. void BeginProgress()
  390. {
  391. g_EngineVGuiImp.SetProgressBias( 0 );
  392. m_SnappedProgress = 0;
  393. }
  394. void UpdateProgress( float progress )
  395. {
  396. if ( m_SnappedProgress == - 1 )
  397. {
  398. // not enabled
  399. return;
  400. }
  401. int snappedProgress = progress * 15;
  402. // Need excessive updates on the 360 to keep the XBox slider inny bar active
  403. if ( !IsX360() && ( snappedProgress <= m_SnappedProgress ) )
  404. {
  405. // prevent excessive updates
  406. return;
  407. }
  408. m_SnappedProgress = snappedProgress;
  409. // up to reserved
  410. g_EngineVGuiImp.UpdateProgressBar( PROGRESS_RESERVE * progress );
  411. }
  412. void EndProgress()
  413. {
  414. // the normal legacy bar now picks up after reserved region
  415. g_EngineVGuiImp.SetProgressBias( PROGRESS_RESERVE );
  416. m_SnappedProgress = -1;
  417. }
  418. private:
  419. int m_SnappedProgress;
  420. };
  421. static CLoaderProgress s_LoaderProgress;
  422. //-----------------------------------------------------------------------------
  423. // Purpose: Constructor
  424. //-----------------------------------------------------------------------------
  425. CEngineVGui::CEngineVGui()
  426. {
  427. staticPanel = NULL;
  428. staticClientDLLToolsPanel = NULL;
  429. staticClientDLLPanel = NULL;
  430. staticGameDLLPanel = NULL;
  431. staticGameUIPanel = NULL;
  432. staticEngineToolsPanel = NULL;
  433. staticDebugSystemPanel = NULL;
  434. staticFocusOverlayPanel = NULL;
  435. m_hStaticGameUIModule = NULL;
  436. m_GameUIFactory = NULL;
  437. #ifdef VPROF_ENABLED
  438. m_pVProfPanel = NULL;
  439. #endif
  440. m_bShowProgressDialog = false;
  441. m_bSaveProgress = false;
  442. m_bNoShaderAPI = false;
  443. m_bNotAllowedToHideGameUI = false;
  444. m_bNotAllowedToShowGameUI = false;
  445. m_pInputInternal = NULL;
  446. m_ProgressBias = 0;
  447. }
  448. //-----------------------------------------------------------------------------
  449. // Purpose: Destructor
  450. //-----------------------------------------------------------------------------
  451. CEngineVGui::~CEngineVGui()
  452. {
  453. }
  454. //-----------------------------------------------------------------------------
  455. // add all the base search paths used by VGUI (platform, skins directory, language dirs)
  456. //-----------------------------------------------------------------------------
  457. bool CEngineVGui::SetVGUIDirectories()
  458. {
  459. // Legacy, not supported anymore
  460. return true;
  461. }
  462. //-----------------------------------------------------------------------------
  463. // Setup the base vgui panels
  464. //-----------------------------------------------------------------------------
  465. void CEngineVGui::Init()
  466. {
  467. COM_TimestampedLog( "Loading gameui.dll" );
  468. // load the GameUI dll
  469. const char *szDllName = "GameUI";
  470. m_hStaticGameUIModule = g_pFileSystem->LoadModule(szDllName, "EXECUTABLE_PATH", true); // LoadModule() does a GetLocalCopy() call
  471. m_GameUIFactory = Sys_GetFactory(m_hStaticGameUIModule);
  472. if ( !m_GameUIFactory )
  473. {
  474. Error( "Could not load: %s\n", szDllName );
  475. }
  476. // get the initialization func
  477. staticGameUIFuncs = (IGameUI *)m_GameUIFactory(GAMEUI_INTERFACE_VERSION, NULL);
  478. if (!staticGameUIFuncs )
  479. {
  480. Error( "Could not get IGameUI interface %s from %s\n", GAMEUI_INTERFACE_VERSION, szDllName );
  481. }
  482. if ( IsPC() )
  483. {
  484. staticGameConsole = (IGameConsole *)m_GameUIFactory(GAMECONSOLE_INTERFACE_VERSION, NULL);
  485. if ( !staticGameConsole )
  486. {
  487. Sys_Error( "Could not get IGameConsole interface %s from %s\n", GAMECONSOLE_INTERFACE_VERSION, szDllName );
  488. }
  489. }
  490. vgui::VGui_InitMatSysInterfacesList( "BaseUI", &g_AppSystemFactory, 1 );
  491. // Get our langauge string
  492. char lang[ 64 ];
  493. lang[0] = 0;
  494. engineClient->GetUILanguage( lang, sizeof( lang ) );
  495. if ( lang[0] )
  496. vgui::system()->SetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\Source\\Language", lang );
  497. COM_TimestampedLog( "AttachToWindow" );
  498. // Need to be able to play sounds through vgui
  499. g_pMatSystemSurface->InstallPlaySoundFunc( VGui_PlaySound );
  500. COM_TimestampedLog( "Load Scheme File" );
  501. // load scheme
  502. const char *pStr = "Resource/SourceScheme.res";
  503. if ( !vgui::scheme()->LoadSchemeFromFile( pStr, "Tracker" ))
  504. {
  505. Sys_Error( "Error loading file %s\n", pStr );
  506. return;
  507. }
  508. if ( IsX360() )
  509. {
  510. CCommand ccommand;
  511. if ( CL_ShouldLoadBackgroundLevel( ccommand ) )
  512. {
  513. // Must be before the game ui base panel starts up
  514. // This is a hint to avoid the menu pop due to the impending background map
  515. // that the game ui is not aware of until 1 frame later.
  516. staticGameUIFuncs->SetProgressOnStart();
  517. }
  518. }
  519. COM_TimestampedLog( "vgui::ivgui()->Start()" );
  520. // Start the App running
  521. vgui::ivgui()->Start();
  522. vgui::ivgui()->SetSleep(false);
  523. // setup base panel for the whole VGUI System
  524. // The root panel for everything ( NULL parent makes it a child of the embedded panel )
  525. // Ideal hierarchy:
  526. COM_TimestampedLog( "Building Panels (staticPanel)" );
  527. // Root -- staticPanel
  528. // staticBackgroundImagePanel (from gamui) zpos == 0
  529. // staticClientDLLPanel ( zpos == 25 )
  530. // staticClientDLLToolsPanel ( zpos == 28
  531. // staticGameDLLPanel ( zpos == 30 )
  532. // staticEngineToolsPanel ( zpos == 75 )
  533. // staticGameUIPanel ( GameUI stuff ) ( zpos == 100 )
  534. // staticDebugSystemPanel ( Engine debug stuff ) zpos == 125 )
  535. staticPanel = new CStaticPanel( NULL, "staticPanel" );
  536. staticPanel->SetBounds( 0, 0, videomode->GetModeUIWidth(), videomode->GetModeUIHeight() );
  537. staticPanel->SetPaintBorderEnabled(false);
  538. staticPanel->SetPaintBackgroundEnabled(false);
  539. staticPanel->SetPaintEnabled(false);
  540. staticPanel->SetVisible(true);
  541. staticPanel->SetCursor( vgui::dc_none );
  542. staticPanel->SetZPos(0);
  543. staticPanel->SetVisible(true);
  544. staticPanel->SetParent( vgui::surface()->GetEmbeddedPanel() );
  545. COM_TimestampedLog( "Building Panels (staticClientDLLPanel)" );
  546. staticClientDLLPanel = new CEnginePanel( staticPanel, "staticClientDLLPanel" );
  547. staticClientDLLPanel->SetBounds( 0, 0, videomode->GetModeUIWidth(), videomode->GetModeUIHeight() );
  548. staticClientDLLPanel->SetPaintBorderEnabled(false);
  549. staticClientDLLPanel->SetPaintBackgroundEnabled(false);
  550. staticClientDLLPanel->SetKeyBoardInputEnabled( false ); // popups in the client DLL can enable this.
  551. staticClientDLLPanel->SetPaintEnabled(false);
  552. staticClientDLLPanel->SetVisible( false );
  553. staticClientDLLPanel->SetCursor( vgui::dc_none );
  554. staticClientDLLPanel->SetZPos( 25 );
  555. CreateAskConnectPanel( staticPanel->GetVPanel() );
  556. COM_TimestampedLog( "Building Panels (staticClientDLLToolsPanel)" );
  557. staticClientDLLToolsPanel = new CEnginePanel( staticPanel, "staticClientDLLToolsPanel" );
  558. staticClientDLLToolsPanel->SetBounds( 0, 0, videomode->GetModeUIWidth(), videomode->GetModeUIHeight() );
  559. staticClientDLLToolsPanel->SetPaintBorderEnabled(false);
  560. staticClientDLLToolsPanel->SetPaintBackgroundEnabled(false);
  561. staticClientDLLToolsPanel->SetKeyBoardInputEnabled( false ); // popups in the client DLL can enable this.
  562. staticClientDLLToolsPanel->SetPaintEnabled(false);
  563. staticClientDLLToolsPanel->SetVisible( true );
  564. staticClientDLLToolsPanel->SetCursor( vgui::dc_none );
  565. staticClientDLLToolsPanel->SetZPos( 28 );
  566. staticEngineToolsPanel = new CEnginePanel( staticPanel, "Engine Tools" );
  567. staticEngineToolsPanel->SetBounds( 0, 0, videomode->GetModeUIWidth(), videomode->GetModeUIHeight() );
  568. staticEngineToolsPanel->SetPaintBorderEnabled(false);
  569. staticEngineToolsPanel->SetPaintBackgroundEnabled(false);
  570. staticEngineToolsPanel->SetPaintEnabled(false);
  571. staticEngineToolsPanel->SetVisible( true );
  572. staticEngineToolsPanel->SetCursor( vgui::dc_none );
  573. staticEngineToolsPanel->SetZPos( 75 );
  574. COM_TimestampedLog( "Building Panels (staticGameUIPanel)" );
  575. staticGameUIPanel = new CEnginePanel( staticPanel, "GameUI Panel" );
  576. staticGameUIPanel->SetBounds( 0, 0, videomode->GetModeUIWidth(), videomode->GetModeUIHeight() );
  577. staticGameUIPanel->SetPaintBorderEnabled(false);
  578. staticGameUIPanel->SetPaintBackgroundEnabled(false);
  579. staticGameUIPanel->SetPaintEnabled(false);
  580. staticGameUIPanel->SetVisible( true );
  581. staticGameUIPanel->SetCursor( vgui::dc_none );
  582. staticGameUIPanel->SetZPos( 100 );
  583. staticGameDLLPanel = new CEnginePanel( staticPanel, "staticGameDLLPanel" );
  584. staticGameDLLPanel->SetBounds( 0, 0, videomode->GetModeUIWidth(), videomode->GetModeUIHeight() );
  585. staticGameDLLPanel->SetPaintBorderEnabled(false);
  586. staticGameDLLPanel->SetPaintBackgroundEnabled(false);
  587. staticGameDLLPanel->SetKeyBoardInputEnabled( false ); // popups in the game DLL can enable this.
  588. staticGameDLLPanel->SetPaintEnabled(false);
  589. staticGameDLLPanel->SetCursor( vgui::dc_none );
  590. staticGameDLLPanel->SetZPos( 135 );
  591. if ( CommandLine()->CheckParm( "-tools" ) != NULL )
  592. {
  593. staticGameDLLPanel->SetVisible( true );
  594. }
  595. else
  596. {
  597. staticGameDLLPanel->SetVisible( false );
  598. }
  599. if ( IsPC() )
  600. {
  601. COM_TimestampedLog( "Building Panels (staticDebugSystemPanel)" );
  602. staticDebugSystemPanel = new CDebugSystemPanel( staticPanel, "Engine Debug System" );
  603. staticDebugSystemPanel->SetZPos( 125 );
  604. // Install demo playback/editing UI
  605. CDemoUIPanel::InstallDemoUI( staticEngineToolsPanel );
  606. CDemoUIPanel2::Install( staticClientDLLPanel, staticEngineToolsPanel, true );
  607. // Install fog control panel UI
  608. CFogUIPanel::InstallFogUI( staticEngineToolsPanel );
  609. // Install texture view panel
  610. TxViewPanel::Install( staticEngineToolsPanel );
  611. COM_TimestampedLog( "Install bug reporter" );
  612. // Create and initialize bug reporting system
  613. bugreporter->InstallBugReportingUI( staticGameUIPanel, IEngineBugReporter::BR_AUTOSELECT );
  614. bugreporter->Init();
  615. COM_TimestampedLog( "Install perf tools" );
  616. // Create a performance toolkit system
  617. perftools->InstallPerformanceToolsUI( staticEngineToolsPanel );
  618. perftools->Init();
  619. // Create a color correction UI
  620. colorcorrectiontools->InstallColorCorrectionUI( staticEngineToolsPanel );
  621. colorcorrectiontools->Init();
  622. }
  623. // Make sure this is on top of everything
  624. staticFocusOverlayPanel = new CFocusOverlayPanel( staticPanel, "FocusOverlayPanel" );
  625. staticFocusOverlayPanel->SetBounds( 0, 0, videomode->GetModeUIWidth(), videomode->GetModeUIHeight() );
  626. staticFocusOverlayPanel->SetZPos( 150 );
  627. staticFocusOverlayPanel->MoveToFront();
  628. // Create engine vgui panels
  629. if ( IsPC() )
  630. {
  631. Con_CreateConsolePanel( staticEngineToolsPanel );
  632. CL_CreateEntityReportPanel( staticEngineToolsPanel );
  633. VGui_CreateDrawTreePanel( staticEngineToolsPanel );
  634. CL_CreateTextureListPanel( staticEngineToolsPanel );
  635. CreateVProfPanels( staticEngineToolsPanel );
  636. }
  637. staticEngineToolsPanel->LoadControlSettings( "scripts/EngineVGuiLayout.res" );
  638. COM_TimestampedLog( "materials->CacheUsedMaterials()" );
  639. // Make sure that these materials are in the materials cache
  640. materials->CacheUsedMaterials();
  641. COM_TimestampedLog( "g_pVGuiLocalize->AddFile" );
  642. // load the base localization file
  643. g_pVGuiLocalize->AddFile( "Resource/valve_%language%.txt" );
  644. COM_TimestampedLog( "staticGameUIFuncs->Initialize" );
  645. staticGameUIFuncs->Initialize( g_AppSystemFactory );
  646. COM_TimestampedLog( "staticGameUIFuncs->Start" );
  647. staticGameUIFuncs->Start();
  648. // don't need to load the "valve" localization file twice
  649. // Each mod acn have its own language.txt in addition to the valve_%%langauge%%.txt file under defaultgamedir.
  650. // load mod-specific localization file for kb_act.lst, user.scr, settings.scr, etc.
  651. char szFileName[MAX_PATH];
  652. Q_snprintf( szFileName, sizeof( szFileName ) - 1, "resource/%s_%%language%%.txt", GetCurrentMod() );
  653. szFileName[ sizeof( szFileName ) - 1 ] = '\0';
  654. g_pVGuiLocalize->AddFile( szFileName );
  655. // setup console
  656. if ( staticGameConsole )
  657. {
  658. staticGameConsole->Initialize();
  659. staticGameConsole->SetParent(staticGameUIPanel->GetVPanel());
  660. }
  661. if ( IsX360() )
  662. {
  663. // provide an interface for loader to send progress notifications
  664. g_pQueuedLoader->InstallProgress( &s_LoaderProgress );
  665. }
  666. // show the game UI
  667. COM_TimestampedLog( "ActivateGameUI()" );
  668. ActivateGameUI();
  669. if ( staticGameConsole &&
  670. !CommandLine()->CheckParm( "-forcestartupmenu" ) &&
  671. !CommandLine()->CheckParm( "-hideconsole" ) &&
  672. ( CommandLine()->FindParm( "-toconsole" ) || CommandLine()->FindParm( "-console" ) || CommandLine()->FindParm( "-rpt" ) || CommandLine()->FindParm( "-allowdebug" ) ) )
  673. {
  674. // activate the console
  675. staticGameConsole->Activate();
  676. }
  677. m_bNoShaderAPI = CommandLine()->FindParm( "-noshaderapi" );
  678. }
  679. void CEngineVGui::PostInit()
  680. {
  681. staticGameUIFuncs->PostInit();
  682. #if defined( _X360 )
  683. g_pMatSystemSurface->ClearTemporaryFontCache();
  684. #endif
  685. }
  686. //-----------------------------------------------------------------------------
  687. // Purpose: connects interfaces in gameui
  688. //-----------------------------------------------------------------------------
  689. void CEngineVGui::Connect()
  690. {
  691. m_pInputInternal = (vgui::IInputInternal *)g_GameSystemFactory( VGUI_INPUTINTERNAL_INTERFACE_VERSION, NULL );
  692. staticGameUIFuncs->Connect( g_GameSystemFactory );
  693. }
  694. //-----------------------------------------------------------------------------
  695. // Create/destroy the vprof panels
  696. //-----------------------------------------------------------------------------
  697. void CEngineVGui::CreateVProfPanels( vgui::Panel *pParent )
  698. {
  699. if ( IsX360() )
  700. return;
  701. #ifdef VPROF_ENABLED
  702. m_pVProfPanel = new CVProfPanel( pParent, "VProfPanel" );
  703. m_pBudgetPanel = new CBudgetPanelEngine( pParent, "BudgetPanel" );
  704. CreateVProfGraphPanel( pParent );
  705. m_pTextureBudgetPanel = new CTextureBudgetPanel( pParent, "TextureBudgetPanel" );
  706. #endif
  707. }
  708. void CEngineVGui::DestroyVProfPanels( )
  709. {
  710. if ( IsX360() )
  711. return;
  712. #ifdef VPROF_ENABLED
  713. if ( m_pVProfPanel )
  714. {
  715. delete m_pVProfPanel;
  716. m_pVProfPanel = NULL;
  717. }
  718. if ( m_pBudgetPanel )
  719. {
  720. delete m_pBudgetPanel;
  721. m_pBudgetPanel = NULL;
  722. }
  723. DestroyVProfGraphPanel();
  724. if ( m_pTextureBudgetPanel )
  725. {
  726. delete m_pTextureBudgetPanel;
  727. m_pTextureBudgetPanel = NULL;
  728. }
  729. #endif
  730. }
  731. //-----------------------------------------------------------------------------
  732. // Are we initialized?
  733. //-----------------------------------------------------------------------------
  734. bool CEngineVGui::IsInitialized() const
  735. {
  736. return staticPanel != NULL;
  737. }
  738. extern bool g_bUsingLegacyAppSystems;
  739. //-----------------------------------------------------------------------------
  740. // Purpose: Called to Shutdown the game UI system
  741. //-----------------------------------------------------------------------------
  742. void CEngineVGui::Shutdown()
  743. {
  744. if ( IsPC() && CL_IsHL2Demo() ) // if they are playing the demo then open the storefront on shutdown
  745. {
  746. vgui::system()->ShellExecute("open", "steam://store_demo/220");
  747. }
  748. if ( IsPC() && CL_IsPortalDemo() ) // if they are playing the demo then open the storefront on shutdown
  749. {
  750. vgui::system()->ShellExecute("open", "steam://store_demo/400");
  751. }
  752. DestroyVProfPanels();
  753. bugreporter->Shutdown();
  754. colorcorrectiontools->Shutdown();
  755. perftools->Shutdown();
  756. demoaction->Shutdown();
  757. if ( g_PluginManager )
  758. {
  759. g_PluginManager->Shutdown();
  760. }
  761. // HACK HACK: There was a bug in the old versions of the viewport which would crash in the case where the client .dll hadn't been fully unloaded, so
  762. // we'll leak this panel here instead!!!
  763. if ( g_bUsingLegacyAppSystems )
  764. {
  765. staticClientDLLPanel->SetParent( (vgui::VPANEL)0 );
  766. }
  767. // This will delete the engine subpanel since it's a child
  768. delete staticPanel;
  769. staticPanel = NULL;
  770. staticClientDLLToolsPanel = NULL;
  771. staticClientDLLPanel = NULL;
  772. staticEngineToolsPanel = NULL;
  773. staticDebugSystemPanel = NULL;
  774. staticFocusOverlayPanel = NULL;
  775. staticGameDLLPanel = NULL;
  776. // Give panels a chance to settle so things
  777. // Marked for deletion will actually get deleted
  778. vgui::ivgui()->RunFrame();
  779. // unload the gameUI
  780. staticGameUIFuncs->Shutdown();
  781. staticGameUIFuncs = NULL;
  782. staticGameConsole = NULL;
  783. staticGameUIPanel = NULL;
  784. // stop the App running
  785. vgui::ivgui()->Stop();
  786. // unload the dll
  787. Sys_UnloadModule(m_hStaticGameUIModule);
  788. m_hStaticGameUIModule = NULL;
  789. m_GameUIFactory = NULL;
  790. m_pInputInternal = NULL;
  791. }
  792. //-----------------------------------------------------------------------------
  793. // Purpose: Retrieve specified root panel
  794. //-----------------------------------------------------------------------------
  795. inline vgui::Panel *CEngineVGui::GetRootPanel( VGuiPanel_t type )
  796. {
  797. if ( sv.IsDedicated() )
  798. {
  799. return NULL;
  800. }
  801. switch ( type )
  802. {
  803. default:
  804. case PANEL_ROOT:
  805. return staticPanel;
  806. case PANEL_CLIENTDLL:
  807. return staticClientDLLPanel;
  808. case PANEL_GAMEUIDLL:
  809. return staticGameUIPanel;
  810. case PANEL_TOOLS:
  811. return staticEngineToolsPanel;
  812. case PANEL_GAMEDLL:
  813. return staticGameDLLPanel;
  814. case PANEL_CLIENTDLL_TOOLS:
  815. return staticClientDLLToolsPanel;
  816. }
  817. }
  818. vgui::VPANEL CEngineVGui::GetPanel( VGuiPanel_t type )
  819. {
  820. return GetRootPanel( type )->GetVPanel();
  821. }
  822. //-----------------------------------------------------------------------------
  823. // Purpose: Toggle engine panel active/inactive
  824. //-----------------------------------------------------------------------------
  825. void CEngineVGui::SetEngineVisible( bool state )
  826. {
  827. if ( staticClientDLLPanel )
  828. {
  829. staticClientDLLPanel->SetVisible( state );
  830. }
  831. }
  832. //-----------------------------------------------------------------------------
  833. // Should pause?
  834. //-----------------------------------------------------------------------------
  835. bool CEngineVGui::ShouldPause()
  836. {
  837. if ( IsPC() )
  838. {
  839. return bugreporter->ShouldPause() || perftools->ShouldPause();
  840. }
  841. return false;
  842. }
  843. //-----------------------------------------------------------------------------
  844. // Purpose:
  845. //-----------------------------------------------------------------------------
  846. void CEngineVGui::ConfirmQuit()
  847. {
  848. ActivateGameUI();
  849. staticGameUIFuncs->OnConfirmQuit();
  850. }
  851. //-----------------------------------------------------------------------------
  852. // Purpose: Shows any GameUI related panels
  853. //-----------------------------------------------------------------------------
  854. void CEngineVGui::ActivateGameUI()
  855. {
  856. if ( m_bNotAllowedToShowGameUI )
  857. return;
  858. if (!staticGameUIFuncs)
  859. return;
  860. #if defined( REPLAY_ENABLED )
  861. // Don't allow the game UI to be activated when a replay is being rendered
  862. if ( g_pReplayMovieManager && g_pReplayMovieManager->IsRendering() )
  863. return;
  864. #endif
  865. // clear any keys that might be stuck down
  866. ClearIOStates();
  867. staticGameUIPanel->SetVisible(true);
  868. staticGameUIPanel->MoveToFront();
  869. staticClientDLLPanel->SetVisible(false);
  870. staticClientDLLPanel->SetMouseInputEnabled(false);
  871. vgui::surface()->SetCursor( vgui::dc_arrow );
  872. //staticGameDLLPanel->SetVisible( true );
  873. //staticGameDLLPanel->SetMouseInputEnabled( true );
  874. SetEngineVisible( false );
  875. staticGameUIFuncs->OnGameUIActivated();
  876. }
  877. //-----------------------------------------------------------------------------
  878. // Purpose: Hides an Game UI related features (not client UI stuff tho!)
  879. //-----------------------------------------------------------------------------
  880. bool CEngineVGui::HideGameUI()
  881. {
  882. if ( m_bNotAllowedToHideGameUI )
  883. return false;
  884. const char *levelName = engineClient->GetLevelName();
  885. bool bInNonBgLevel = levelName && levelName[0] && !engineClient->IsLevelMainMenuBackground();
  886. if ( bInNonBgLevel )
  887. {
  888. staticGameUIPanel->SetVisible(false);
  889. staticGameUIPanel->SetPaintBackgroundEnabled(false);
  890. staticClientDLLPanel->SetVisible(true);
  891. staticClientDLLPanel->MoveToFront();
  892. staticClientDLLPanel->SetMouseInputEnabled(true);
  893. //staticGameDLLPanel->SetVisible( false );
  894. //staticGameDLLPanel->SetMouseInputEnabled(false);
  895. SetEngineVisible( true );
  896. staticGameUIFuncs->OnGameUIHidden();
  897. }
  898. else
  899. {
  900. // Tracker 18820: Pulling up options/console was perma-pausing the background levels, now we
  901. // unpause them when you hit the Esc key even though the UI remains...
  902. if ( levelName &&
  903. levelName[0] &&
  904. ( engineClient->GetMaxClients() <= 1 ) &&
  905. engineClient->IsPaused() )
  906. {
  907. Cbuf_AddText("unpause\n");
  908. }
  909. }
  910. VGui_MoveDrawTreePanelToFront();
  911. return true;
  912. }
  913. //-----------------------------------------------------------------------------
  914. // Purpose: Hides the game console (but not the complete GameUI!)
  915. //-----------------------------------------------------------------------------
  916. void CEngineVGui::HideConsole()
  917. {
  918. if ( IsX360() )
  919. return;
  920. if ( staticGameConsole )
  921. {
  922. staticGameConsole->Hide();
  923. }
  924. }
  925. //-----------------------------------------------------------------------------
  926. // Purpose: shows the console
  927. //-----------------------------------------------------------------------------
  928. void CEngineVGui::ShowConsole()
  929. {
  930. if ( IsX360() )
  931. return;
  932. ActivateGameUI();
  933. if ( staticGameConsole )
  934. {
  935. staticGameConsole->Activate();
  936. }
  937. }
  938. //-----------------------------------------------------------------------------
  939. // Purpose: returns true if the console is currently open
  940. //-----------------------------------------------------------------------------
  941. bool CEngineVGui::IsConsoleVisible()
  942. {
  943. if ( IsPC() )
  944. {
  945. return IsGameUIVisible() && staticGameConsole && staticGameConsole->IsConsoleVisible();
  946. }
  947. else
  948. {
  949. // xbox has no drop down console
  950. return false;
  951. }
  952. }
  953. //-----------------------------------------------------------------------------
  954. // Purpose: clears all text from the console
  955. //-----------------------------------------------------------------------------
  956. void CEngineVGui::ClearConsole()
  957. {
  958. if ( staticGameConsole )
  959. {
  960. staticGameConsole->Clear();
  961. }
  962. }
  963. //-----------------------------------------------------------------------------
  964. // Purpose: data accessor
  965. //-----------------------------------------------------------------------------
  966. bool CEngineVGui::IsGameUIVisible()
  967. {
  968. return staticGameUIPanel && staticGameUIPanel->IsVisible();
  969. }
  970. // list of progress bar strings
  971. struct LoadingProgressDescription_t
  972. {
  973. LevelLoadingProgress_e eProgress; // current progress
  974. int nPercent; // % of the total time this is at
  975. int nRepeat; // number of times this is expected to repeat (usually 0)
  976. const char *pszDesc; // user description of progress
  977. };
  978. LoadingProgressDescription_t g_ListenServerLoadingProgressDescriptions[] =
  979. {
  980. { PROGRESS_NONE, 0, 0, NULL },
  981. { PROGRESS_SPAWNSERVER, 2, 0, "#LoadingProgress_SpawningServer" },
  982. { PROGRESS_LOADWORLDMODEL, 4, 7, "#LoadingProgress_LoadMap" },
  983. { PROGRESS_CREATENETWORKSTRINGTABLES, 23, 0, NULL },
  984. { PROGRESS_PRECACHEWORLD, 23, 0, "#LoadingProgress_PrecacheWorld" },
  985. { PROGRESS_CLEARWORLD, 23, 0, NULL },
  986. { PROGRESS_LEVELINIT, 34, 0, "#LoadingProgress_LoadResources" },
  987. { PROGRESS_PRECACHE, 35, 239, NULL },
  988. { PROGRESS_ACTIVATESERVER, 68, 0, NULL },
  989. { PROGRESS_SIGNONCHALLENGE, 68, 0, NULL },
  990. { PROGRESS_SIGNONCONNECT, 70, 0, NULL },
  991. { PROGRESS_SIGNONCONNECTED, 73, 0, "#LoadingProgress_SignonLocal" },
  992. { PROGRESS_PROCESSSERVERINFO, 75, 0, NULL },
  993. { PROGRESS_PROCESSSTRINGTABLE, 77, 12, NULL }, // 16
  994. { PROGRESS_SIGNONNEW, 84, 0, NULL },
  995. { PROGRESS_SENDCLIENTINFO, 88, 0, NULL },
  996. { PROGRESS_SENDSIGNONDATA, 91, 0, "#LoadingProgress_SignonDataLocal" },
  997. { PROGRESS_SIGNONSPAWN, 94, 0, NULL },
  998. { PROGRESS_FULLYCONNECTED, 97, 0, NULL },
  999. { PROGRESS_READYTOPLAY, 99, 0, NULL },
  1000. { PROGRESS_HIGHESTITEM, 100, 0, NULL },
  1001. };
  1002. LoadingProgressDescription_t g_RemoteConnectLoadingProgressDescriptions[] =
  1003. {
  1004. { PROGRESS_NONE, 0, 0, NULL },
  1005. { PROGRESS_CHANGELEVEL, 1, 0, "#LoadingProgress_Changelevel" },
  1006. { PROGRESS_BEGINCONNECT, 5, 0, "#LoadingProgress_BeginConnect" },
  1007. { PROGRESS_SIGNONCHALLENGE, 10, 0, "#LoadingProgress_Connecting" },
  1008. { PROGRESS_SIGNONCONNECTED, 15, 0, NULL },
  1009. { PROGRESS_PROCESSSERVERINFO, 20, 0, "#LoadingProgress_ProcessServerInfo" },
  1010. { PROGRESS_PROCESSSTRINGTABLE, 25, 11, NULL },
  1011. { PROGRESS_LOADWORLDMODEL, 45, 7, "#LoadingProgress_LoadMap" },
  1012. { PROGRESS_SIGNONNEW, 75, 0, NULL },
  1013. { PROGRESS_SENDCLIENTINFO, 80, 0, "#LoadingProgress_SendClientInfo" },
  1014. { PROGRESS_SENDSIGNONDATA, 85, 0, "#LoadingProgress_SignonData" },
  1015. { PROGRESS_SIGNONSPAWN, 90, 0, NULL },
  1016. { PROGRESS_FULLYCONNECTED, 95, 0, NULL },
  1017. { PROGRESS_READYTOPLAY, 99, 0, NULL },
  1018. { PROGRESS_HIGHESTITEM, 100, 0, NULL },
  1019. };
  1020. static LoadingProgressDescription_t *g_pLoadingProgressDescriptions = NULL;
  1021. //-----------------------------------------------------------------------------
  1022. // Purpose: returns current progress point description
  1023. //-----------------------------------------------------------------------------
  1024. LoadingProgressDescription_t &GetProgressDescription(int eProgress)
  1025. {
  1026. // search for the item in the current list
  1027. int i = 0;
  1028. while (g_pLoadingProgressDescriptions[i].eProgress != PROGRESS_HIGHESTITEM)
  1029. {
  1030. // find the closest match
  1031. if (g_pLoadingProgressDescriptions[i].eProgress >= eProgress)
  1032. return g_pLoadingProgressDescriptions[i];
  1033. ++i;
  1034. }
  1035. // not found
  1036. return g_pLoadingProgressDescriptions[0];
  1037. }
  1038. //-----------------------------------------------------------------------------
  1039. // Purpose: transition handler
  1040. //-----------------------------------------------------------------------------
  1041. void CEngineVGui::OnLevelLoadingStarted()
  1042. {
  1043. if (!staticGameUIFuncs)
  1044. return;
  1045. ConVar *pSyncReportConVar = g_pCVar->FindVar( "fs_report_sync_opens" );
  1046. if ( pSyncReportConVar )
  1047. {
  1048. // If convar is set to 2, suppress warnings during level load
  1049. g_syncReportLevel = pSyncReportConVar->GetInt();
  1050. if ( g_syncReportLevel > 1 )
  1051. {
  1052. pSyncReportConVar->SetValue( 0 );
  1053. }
  1054. }
  1055. if ( IsX360() )
  1056. {
  1057. // TCR requirement, always!!!
  1058. m_bShowProgressDialog = true;
  1059. }
  1060. // we've starting loading a level/connecting to a server
  1061. staticGameUIFuncs->OnLevelLoadingStarted( m_bShowProgressDialog );
  1062. // reset progress bar timers
  1063. m_flLoadingStartTime = Plat_FloatTime();
  1064. m_LoadingProgress.RemoveAll();
  1065. m_eLastProgressPoint = PROGRESS_NONE;
  1066. m_nLastProgressPointRepeatCount = 0;
  1067. m_ProgressBias = 0;
  1068. // choose which progress bar to use
  1069. if (NET_IsMultiplayer())
  1070. {
  1071. // we're connecting
  1072. g_pLoadingProgressDescriptions = g_RemoteConnectLoadingProgressDescriptions;
  1073. }
  1074. else
  1075. {
  1076. g_pLoadingProgressDescriptions = g_ListenServerLoadingProgressDescriptions;
  1077. }
  1078. if ( m_bShowProgressDialog )
  1079. {
  1080. ActivateGameUI();
  1081. }
  1082. m_bShowProgressDialog = false;
  1083. }
  1084. //-----------------------------------------------------------------------------
  1085. // Purpose: transition handler
  1086. //-----------------------------------------------------------------------------
  1087. void CEngineVGui::OnLevelLoadingFinished()
  1088. {
  1089. if (!staticGameUIFuncs)
  1090. return;
  1091. staticGameUIFuncs->OnLevelLoadingFinished( gfExtendedError, gszDisconnectReason, gszExtendedDisconnectReason );
  1092. m_eLastProgressPoint = PROGRESS_NONE;
  1093. // clear any error message
  1094. gfExtendedError = false;
  1095. gszDisconnectReason[0] = 0;
  1096. gszExtendedDisconnectReason[0] = 0;
  1097. #if defined(ENABLE_LOADING_PROGRESS_PROFILING)
  1098. // display progress bar stats (for debugging/tuning progress bar)
  1099. float flEndTime = (float)Plat_FloatTime();
  1100. // add a finished entry
  1101. LoadingProgressEntry_t &entry = m_LoadingProgress[m_LoadingProgress.AddToTail()];
  1102. entry.flTime = flEndTime - m_flLoadingStartTime;
  1103. entry.eProgress = PROGRESS_HIGHESTITEM;
  1104. // dump the info
  1105. Msg("Level load timings:\n");
  1106. float flTotalTime = flEndTime - m_flLoadingStartTime;
  1107. int nRepeatCount = 0;
  1108. float flTimeTaken = 0.0f;
  1109. float flFirstLoadProgressTime = 0.0f;
  1110. for (int i = 0; i < m_LoadingProgress.Count() - 1; i++)
  1111. {
  1112. // keep track of time
  1113. flTimeTaken += (float)m_LoadingProgress[i+1].flTime - m_LoadingProgress[i].flTime;
  1114. // keep track of how often something is repeated
  1115. if (m_LoadingProgress[i+1].eProgress == m_LoadingProgress[i].eProgress)
  1116. {
  1117. if (nRepeatCount == 0)
  1118. {
  1119. flFirstLoadProgressTime = m_LoadingProgress[i].flTime;
  1120. }
  1121. ++nRepeatCount;
  1122. continue;
  1123. }
  1124. // work out the time it took to do this
  1125. if (nRepeatCount == 0)
  1126. {
  1127. flFirstLoadProgressTime = m_LoadingProgress[i].flTime;
  1128. }
  1129. int nPerc = (int)(100 * (flFirstLoadProgressTime / flTotalTime));
  1130. int nTickPerc = (int)(100 * ((float)m_LoadingProgress[i].eProgress / (float)PROGRESS_HIGHESTITEM));
  1131. // interpolated percentage is in between the real times and the most ticks
  1132. int nInterpPerc = (nPerc + nTickPerc) / 2;
  1133. Msg("\t%d\t%.3f\t\ttime: %d%%\t\tinterp: %d%%\t\trepeat: %d\n", m_LoadingProgress[i].eProgress, flTimeTaken, nPerc, nInterpPerc, nRepeatCount);
  1134. // reset accumlated vars
  1135. nRepeatCount = 0;
  1136. flTimeTaken = 0.0f;
  1137. }
  1138. #endif // ENABLE_LOADING_PROGRESS_PROFILING
  1139. HideGameUI();
  1140. // Restore convar setting after level load
  1141. if ( g_syncReportLevel > 1 )
  1142. {
  1143. ConVar *pSyncReportConVar = g_pCVar->FindVar( "fs_report_sync_opens" );
  1144. if ( pSyncReportConVar )
  1145. {
  1146. pSyncReportConVar->SetValue( g_syncReportLevel );
  1147. }
  1148. }
  1149. }
  1150. //-----------------------------------------------------------------------------
  1151. // Purpose: transition handler
  1152. //-----------------------------------------------------------------------------
  1153. void CEngineVGui::ShowErrorMessage()
  1154. {
  1155. if (!staticGameUIFuncs || !gfExtendedError)
  1156. return;
  1157. staticGameUIFuncs->OnLevelLoadingFinished( gfExtendedError, gszDisconnectReason, gszExtendedDisconnectReason );
  1158. m_eLastProgressPoint = PROGRESS_NONE;
  1159. // clear any error message
  1160. gfExtendedError = false;
  1161. gszDisconnectReason[0] = 0;
  1162. gszExtendedDisconnectReason[0] = 0;
  1163. HideGameUI();
  1164. }
  1165. //-----------------------------------------------------------------------------
  1166. // Purpose: Updates progress
  1167. //-----------------------------------------------------------------------------
  1168. void CEngineVGui::UpdateProgressBar(LevelLoadingProgress_e progress)
  1169. {
  1170. if (!staticGameUIFuncs)
  1171. return;
  1172. if ( !ThreadInMainThread() )
  1173. return;
  1174. #if defined(ENABLE_LOADING_PROGRESS_PROFILING)
  1175. // track the progress times, for debugging & tuning
  1176. LoadingProgressEntry_t &entry = m_LoadingProgress[m_LoadingProgress.AddToTail()];
  1177. entry.flTime = Plat_FloatTime() - m_flLoadingStartTime;
  1178. entry.eProgress = progress;
  1179. #endif
  1180. if (!g_pLoadingProgressDescriptions)
  1181. return;
  1182. // don't go backwards
  1183. if (progress < m_eLastProgressPoint)
  1184. return;
  1185. // count progress repeats
  1186. if (progress == m_eLastProgressPoint)
  1187. {
  1188. ++m_nLastProgressPointRepeatCount;
  1189. }
  1190. else
  1191. {
  1192. m_nLastProgressPointRepeatCount = 0;
  1193. }
  1194. // construct a string describing it
  1195. LoadingProgressDescription_t &desc = GetProgressDescription(progress);
  1196. // calculate partial progress
  1197. float flPerc = desc.nPercent / 100.0f;
  1198. if ( desc.nRepeat > 1 && m_nLastProgressPointRepeatCount )
  1199. {
  1200. // cap the repeat count
  1201. m_nLastProgressPointRepeatCount = min(m_nLastProgressPointRepeatCount, desc.nRepeat);
  1202. // next progress point
  1203. float flNextPerc = GetProgressDescription(progress + 1).nPercent / 100.0f;
  1204. // move along partially towards the next tick
  1205. flPerc += (flNextPerc - flPerc) * ((float)m_nLastProgressPointRepeatCount / desc.nRepeat);
  1206. }
  1207. // the bias allows the loading bar to have an optional reserved initial band
  1208. // isolated from the normal progress descriptions
  1209. flPerc = flPerc * ( 1.0f - m_ProgressBias ) + m_ProgressBias;
  1210. if ( staticGameUIFuncs->UpdateProgressBar( flPerc, desc.pszDesc ) )
  1211. {
  1212. // re-render vgui on screen
  1213. extern void V_RenderVGuiOnly();
  1214. V_RenderVGuiOnly();
  1215. }
  1216. m_eLastProgressPoint = progress;
  1217. }
  1218. //-----------------------------------------------------------------------------
  1219. // Purpose: Updates progress
  1220. //-----------------------------------------------------------------------------
  1221. void CEngineVGui::UpdateCustomProgressBar( float progress, const wchar_t *desc )
  1222. {
  1223. if (!staticGameUIFuncs)
  1224. return;
  1225. char ansi[1024];
  1226. g_pVGuiLocalize->ConvertUnicodeToANSI( desc, ansi, sizeof( ansi ) );
  1227. if ( staticGameUIFuncs->UpdateProgressBar( progress, ansi ) )
  1228. {
  1229. // re-render vgui on screen
  1230. extern void V_RenderVGuiOnly();
  1231. V_RenderVGuiOnly();
  1232. }
  1233. }
  1234. void CEngineVGui::StartCustomProgress()
  1235. {
  1236. if (!staticGameUIFuncs)
  1237. return;
  1238. // we've starting loading a level/connecting to a server
  1239. staticGameUIFuncs->OnLevelLoadingStarted(true);
  1240. m_bSaveProgress = staticGameUIFuncs->SetShowProgressText( true );
  1241. }
  1242. void CEngineVGui::FinishCustomProgress()
  1243. {
  1244. if (!staticGameUIFuncs)
  1245. return;
  1246. staticGameUIFuncs->SetShowProgressText( m_bSaveProgress );
  1247. staticGameUIFuncs->OnLevelLoadingFinished( false, "", "" );
  1248. }
  1249. void CEngineVGui::SetProgressBias( float bias )
  1250. {
  1251. m_ProgressBias = bias;
  1252. }
  1253. void CEngineVGui::UpdateProgressBar( float progress )
  1254. {
  1255. if ( !staticGameUIFuncs )
  1256. return;
  1257. if ( staticGameUIFuncs->UpdateProgressBar( progress, "" ) )
  1258. {
  1259. // re-render vgui on screen
  1260. extern void V_RenderVGuiOnly();
  1261. V_RenderVGuiOnly();
  1262. }
  1263. }
  1264. //-----------------------------------------------------------------------------
  1265. // Purpose: Returns 1 if the key event is handled, 0 if the engine should handle it
  1266. //-----------------------------------------------------------------------------
  1267. void CEngineVGui::UpdateButtonState( const InputEvent_t &event )
  1268. {
  1269. m_pInputInternal->UpdateButtonState( event );
  1270. }
  1271. //-----------------------------------------------------------------------------
  1272. // Purpose: Returns 1 if the key event is handled, 0 if the engine should handle it
  1273. //-----------------------------------------------------------------------------
  1274. bool CEngineVGui::Key_Event( const InputEvent_t &event )
  1275. {
  1276. bool bDown = event.m_nType != IE_ButtonReleased;
  1277. ButtonCode_t code = (ButtonCode_t)event.m_nData;
  1278. if ( IsPC() && IsShiftKeyDown() )
  1279. {
  1280. switch( code )
  1281. {
  1282. case KEY_F1:
  1283. if ( bDown )
  1284. {
  1285. Cbuf_AddText( "debugsystemui" );
  1286. }
  1287. return true;
  1288. case KEY_F2:
  1289. if ( bDown )
  1290. {
  1291. Cbuf_AddText( "demoui" );
  1292. }
  1293. return true;
  1294. }
  1295. }
  1296. #if defined( _WIN32 )
  1297. // Ignore alt tilde, since the Japanese IME uses this to toggle itself on/off
  1298. if ( IsPC() && code == KEY_BACKQUOTE && ( IsAltKeyDown() || IsCtrlKeyDown() ) )
  1299. return true;
  1300. #endif
  1301. // ESCAPE toggles game ui
  1302. if ( bDown && ( code == KEY_ESCAPE || code == KEY_XBUTTON_START || code == STEAMCONTROLLER_START) && !g_ClientDLL->HandleUiToggle() )
  1303. {
  1304. if ( IsPC() )
  1305. {
  1306. if ( IsGameUIVisible() )
  1307. {
  1308. // Don't allow hiding of the game ui if there's no level
  1309. const char *pLevelName = engineClient->GetLevelName();
  1310. if ( pLevelName && pLevelName[0] )
  1311. {
  1312. Cbuf_AddText( "gameui_hide" );
  1313. if ( IsDebugSystemVisible() )
  1314. {
  1315. Cbuf_AddText( "debugsystemui 0" );
  1316. }
  1317. }
  1318. }
  1319. else
  1320. {
  1321. Cbuf_AddText( "gameui_activate" );
  1322. }
  1323. return true;
  1324. }
  1325. if ( IsX360() && !IsGameUIVisible() )
  1326. {
  1327. // 360 UI does not toggle, engine does "show", but UI needs to handle "hide"
  1328. Cbuf_AddText( "gameui_activate" );
  1329. return true;
  1330. }
  1331. }
  1332. if ( g_pMatSystemSurface && g_pMatSystemSurface->HandleInputEvent( event ) )
  1333. {
  1334. // always let the engine handle the console keys
  1335. // FIXME: Do a lookup of the key bound to toggleconsole
  1336. // want to cache it off so the lookup happens only when keys are bound?
  1337. if ( IsPC() && ( code == KEY_BACKQUOTE ) )
  1338. return false;
  1339. return true;
  1340. }
  1341. return false;
  1342. }
  1343. void CEngineVGui::Simulate()
  1344. {
  1345. toolframework->VGui_PreSimulateAllTools();
  1346. if ( staticPanel )
  1347. {
  1348. VPROF_BUDGET( "CEngineVGui::Simulate", VPROF_BUDGETGROUP_OTHER_VGUI );
  1349. // update vgui animations
  1350. //!! currently this has to be done once per dll, because the anim controller object is in a lib;
  1351. //!! need to make it globally pumped (gameUI.dll has it's own version of this)
  1352. vgui::GetAnimationController()->UpdateAnimations( Sys_FloatTime() );
  1353. int w, h;
  1354. #if defined( USE_SDL )
  1355. uint width,height;
  1356. g_pLauncherMgr->RenderedSize( width, height, false ); // false = get
  1357. w = width;
  1358. h = height;
  1359. #else
  1360. if ( ::IsIconic( *pmainwindow ) )
  1361. {
  1362. w = videomode->GetModeWidth();
  1363. h = videomode->GetModeHeight();
  1364. }
  1365. else
  1366. {
  1367. RECT rect;
  1368. ::GetClientRect(*pmainwindow, &rect);
  1369. w = rect.right;
  1370. h = rect.bottom;
  1371. }
  1372. #endif
  1373. // don't hold this reference over RunFrame()
  1374. {
  1375. CMatRenderContextPtr pRenderContext( materials );
  1376. pRenderContext->Viewport( 0, 0, w, h );
  1377. }
  1378. staticGameUIFuncs->RunFrame();
  1379. vgui::ivgui()->RunFrame();
  1380. // Some debugging helpers
  1381. DrawMouseFocus();
  1382. VGui_UpdateDrawTreePanel();
  1383. VGui_UpdateTextureListPanel();
  1384. vgui::surface()->CalculateMouseVisible();
  1385. VGui_ActivateMouse();
  1386. }
  1387. // if ( !vgui::ivgui()->IsRunning() )
  1388. // Cbuf_AddText( "quit\n" );
  1389. toolframework->VGui_PostSimulateAllTools();
  1390. }
  1391. void CEngineVGui::BackwardCompatibility_Paint()
  1392. {
  1393. Paint( (PaintMode_t)(PAINT_UIPANELS | PAINT_INGAMEPANELS) );
  1394. }
  1395. //-----------------------------------------------------------------------------
  1396. // Purpose: paints all the vgui elements
  1397. //-----------------------------------------------------------------------------
  1398. void CEngineVGui::Paint( PaintMode_t mode )
  1399. {
  1400. VPROF_BUDGET( "CEngineVGui::Paint", VPROF_BUDGETGROUP_OTHER_VGUI );
  1401. if ( !staticPanel )
  1402. return;
  1403. // setup the base panel to cover the screen
  1404. vgui::VPANEL pVPanel = vgui::surface()->GetEmbeddedPanel();
  1405. if ( !pVPanel )
  1406. return;
  1407. bool drawVgui = r_drawvgui.GetBool();
  1408. // Don't draw the console at all if vgui is off during a time demo
  1409. if ( demoplayer->IsPlayingTimeDemo() && !drawVgui )
  1410. {
  1411. return;
  1412. }
  1413. if ( !drawVgui || m_bNoShaderAPI )
  1414. {
  1415. return;
  1416. }
  1417. // draw from the main panel down
  1418. vgui::Panel *panel = staticPanel;
  1419. // Force engine's root panel (staticPanel) to be full screen size
  1420. {
  1421. int x, y, w, h;
  1422. CMatRenderContextPtr pRenderContext( materials );
  1423. pRenderContext->GetViewport( x, y, w, h );
  1424. panel->SetBounds(0, 0, w, h); // ignore x and y here because the viewport takes care of that
  1425. }
  1426. panel->Repaint();
  1427. toolframework->VGui_PreRenderAllTools( mode );
  1428. // Paint both ( backward compatibility support )
  1429. // It's either the full screen, or just the client .dll stuff
  1430. if ( mode & PAINT_UIPANELS )
  1431. {
  1432. // Hide the client .dll, and paint everything else
  1433. bool saveVisible = staticClientDLLPanel->IsVisible();
  1434. bool saveToolsVisible = staticClientDLLToolsPanel->IsVisible();
  1435. staticClientDLLPanel->SetVisible( false );
  1436. staticClientDLLToolsPanel->SetVisible( false );
  1437. vgui::surface()->PaintTraverseEx(pVPanel, true );
  1438. staticClientDLLPanel->SetVisible( saveVisible );
  1439. staticClientDLLToolsPanel->SetVisible( saveToolsVisible );
  1440. }
  1441. if ( mode & PAINT_INGAMEPANELS )
  1442. {
  1443. bool bSaveVisible = vgui::ipanel()->IsVisible( pVPanel );
  1444. vgui::ipanel()->SetVisible( pVPanel, false );
  1445. // Remove the client .dll from the main hierarchy so that popups will only paint for the client .dll here
  1446. // NOTE: Disconnect each surface one at a time so that we don't draw popups twice
  1447. // Paint the client .dll only
  1448. vgui::VPANEL ingameRoot = staticClientDLLPanel->GetVPanel();
  1449. vgui::VPANEL saveParent = vgui::ipanel()->GetParent( ingameRoot );
  1450. vgui::ipanel()->SetParent( ingameRoot, 0 );
  1451. vgui::surface()->PaintTraverseEx( ingameRoot, true );
  1452. vgui::ipanel()->SetParent( ingameRoot, saveParent );
  1453. // Overlay the client .dll tools next
  1454. vgui::VPANEL ingameToolsRoot = staticClientDLLToolsPanel->GetVPanel();
  1455. vgui::VPANEL saveToolParent = vgui::ipanel()->GetParent( ingameToolsRoot );
  1456. vgui::ipanel()->SetParent( ingameToolsRoot, 0 );
  1457. vgui::surface()->PaintTraverseEx( ingameToolsRoot, true );
  1458. vgui::ipanel()->SetParent( ingameToolsRoot, saveToolParent );
  1459. vgui::ipanel()->SetVisible( pVPanel, bSaveVisible );
  1460. }
  1461. if ( mode & PAINT_CURSOR )
  1462. {
  1463. vgui::surface()->PaintSoftwareCursor();
  1464. }
  1465. toolframework->VGui_PostRenderAllTools( mode );
  1466. }
  1467. bool CEngineVGui::IsDebugSystemVisible( void )
  1468. {
  1469. return staticDebugSystemPanel ? staticDebugSystemPanel->IsVisible() : false;
  1470. }
  1471. void CEngineVGui::HideDebugSystem( void )
  1472. {
  1473. if ( staticDebugSystemPanel )
  1474. {
  1475. staticDebugSystemPanel->SetVisible( false );
  1476. SetEngineVisible( true );
  1477. }
  1478. }
  1479. void CEngineVGui::ToggleDebugSystemUI( const CCommand &args )
  1480. {
  1481. if ( !staticDebugSystemPanel )
  1482. return;
  1483. bool bVisible;
  1484. if ( args.ArgC() == 1 )
  1485. {
  1486. // toggle the game UI
  1487. bVisible = !IsDebugSystemVisible();
  1488. }
  1489. else
  1490. {
  1491. bVisible = atoi( args[1] ) != 0;
  1492. }
  1493. if ( !bVisible )
  1494. {
  1495. staticDebugSystemPanel->SetVisible( false );
  1496. SetEngineVisible( true );
  1497. }
  1498. else
  1499. {
  1500. // clear any keys that might be stuck down
  1501. ClearIOStates();
  1502. staticDebugSystemPanel->SetVisible( true );
  1503. SetEngineVisible( false );
  1504. }
  1505. }
  1506. bool CEngineVGui::IsShiftKeyDown( void )
  1507. {
  1508. if ( !vgui::input() )
  1509. return false;
  1510. return vgui::input()->IsKeyDown( KEY_LSHIFT ) || vgui::input()->IsKeyDown( KEY_RSHIFT );
  1511. }
  1512. bool CEngineVGui::IsAltKeyDown( void )
  1513. {
  1514. if ( !vgui::input() )
  1515. return false;
  1516. return vgui::input()->IsKeyDown( KEY_LALT ) || vgui::input()->IsKeyDown( KEY_RALT );
  1517. }
  1518. bool CEngineVGui::IsCtrlKeyDown( void )
  1519. {
  1520. if ( !vgui::input() )
  1521. return false;
  1522. return vgui::input()->IsKeyDown( KEY_LCONTROL ) || vgui::input()->IsKeyDown( KEY_RCONTROL );
  1523. }
  1524. //-----------------------------------------------------------------------------
  1525. // Purpose: notification
  1526. //-----------------------------------------------------------------------------
  1527. void CEngineVGui::NotifyOfServerConnect(const char *pchGame, int IP, int connectionPort, int queryPort)
  1528. {
  1529. if (!staticGameUIFuncs)
  1530. return;
  1531. staticGameUIFuncs->OnConnectToServer2( pchGame, IP, connectionPort, queryPort);
  1532. }
  1533. //-----------------------------------------------------------------------------
  1534. // Purpose: notification
  1535. //-----------------------------------------------------------------------------
  1536. void CEngineVGui::NotifyOfServerDisconnect()
  1537. {
  1538. if (!staticGameUIFuncs)
  1539. return;
  1540. staticGameUIFuncs->OnDisconnectFromServer( g_eSteamLoginFailure );
  1541. g_eSteamLoginFailure = 0;
  1542. }
  1543. //-----------------------------------------------------------------------------
  1544. // Xbox 360: Matchmaking sessions send progress notifications to GameUI
  1545. //-----------------------------------------------------------------------------
  1546. void CEngineVGui::SessionNotification( const int notification, const int param )
  1547. {
  1548. staticGameUIFuncs->SessionNotification( notification, param );
  1549. }
  1550. void CEngineVGui::SystemNotification( const int notification )
  1551. {
  1552. staticGameUIFuncs->SystemNotification( notification );
  1553. }
  1554. //-----------------------------------------------------------------------------
  1555. // Xbox 360: Show a message/error dialog
  1556. //-----------------------------------------------------------------------------
  1557. void CEngineVGui::ShowMessageDialog( const uint nType, vgui::Panel *pOwner )
  1558. {
  1559. ActivateGameUI();
  1560. staticGameUIFuncs->ShowMessageDialog( nType, pOwner );
  1561. }
  1562. void CEngineVGui::UpdatePlayerInfo( uint64 nPlayerId, const char *pName, int nTeam, byte cVoiceState, int nPlayersNeeded, bool bHost )
  1563. {
  1564. staticGameUIFuncs->UpdatePlayerInfo( nPlayerId, pName, nTeam, cVoiceState, nPlayersNeeded, bHost );
  1565. }
  1566. void CEngineVGui::SessionSearchResult( int searchIdx, void *pHostData, XSESSION_SEARCHRESULT *pResult, int ping )
  1567. {
  1568. staticGameUIFuncs->SessionSearchResult( searchIdx, pHostData, pResult, ping );
  1569. }
  1570. //-----------------------------------------------------------------------------
  1571. // A helper to play sounds through vgui
  1572. //-----------------------------------------------------------------------------
  1573. void VGui_PlaySound( const char *pFileName )
  1574. {
  1575. // Point at origin if they didn't specify a sound source.
  1576. Vector vDummyOrigin;
  1577. vDummyOrigin.Init();
  1578. CSfxTable *pSound = (CSfxTable*)S_PrecacheSound(pFileName);
  1579. if ( pSound )
  1580. {
  1581. S_MarkUISound( pSound );
  1582. StartSoundParams_t params;
  1583. params.staticsound = IsX360() ? true : false;
  1584. params.soundsource = cl.m_nViewEntity;
  1585. params.entchannel = CHAN_AUTO;
  1586. params.pSfx = pSound;
  1587. params.origin = vDummyOrigin;
  1588. params.pitch = PITCH_NORM;
  1589. params.soundlevel = SNDLVL_IDLE;
  1590. params.flags = 0;
  1591. params.fvol = 1.0f;
  1592. S_StartSound( params );
  1593. }
  1594. }
  1595. //-----------------------------------------------------------------------------
  1596. // Purpose:
  1597. //-----------------------------------------------------------------------------
  1598. void VGui_ActivateMouse()
  1599. {
  1600. if ( !g_ClientDLL )
  1601. return;
  1602. // Don't mess with mouse if not active
  1603. if ( !game->IsActiveApp() )
  1604. {
  1605. g_ClientDLL->IN_DeactivateMouse ();
  1606. return;
  1607. }
  1608. /*
  1609. //
  1610. // MIKE AND ALFRED: these panels should expose whether they want mouse input or not and
  1611. // CalculateMouseVisible will take them into account.
  1612. //
  1613. // If showing game ui, make sure nothing else is hooking it
  1614. if ( Base().IsGameUIVisible() || Base().IsDebugSystemVisible() )
  1615. {
  1616. g_ClientDLL->IN_DeactivateMouse();
  1617. return;
  1618. }
  1619. */
  1620. if ( vgui::surface()->IsCursorLocked() && !g_bTextMode )
  1621. {
  1622. g_ClientDLL->IN_ActivateMouse ();
  1623. }
  1624. else
  1625. {
  1626. g_ClientDLL->IN_DeactivateMouse ();
  1627. }
  1628. }
  1629. static ConVar mat_drawTitleSafe( "mat_drawTitleSafe", "0", 0, "Enable title safe overlay" );
  1630. CUtlVector< vgui::VPANEL > g_FocusPanelList;
  1631. ConVar vgui_drawfocus( "vgui_drawfocus", "0", 0, "Report which panel is under the mouse." );
  1632. CFocusOverlayPanel::CFocusOverlayPanel( vgui::Panel *pParent, const char *pName ) : vgui::Panel( pParent, pName )
  1633. {
  1634. SetPaintEnabled( false );
  1635. SetPaintBorderEnabled( false );
  1636. SetPaintBackgroundEnabled( false );
  1637. MakePopup();
  1638. SetPostChildPaintEnabled( true );
  1639. SetKeyBoardInputEnabled( false );
  1640. SetMouseInputEnabled( false );
  1641. }
  1642. bool CFocusOverlayPanel::DrawTitleSafeOverlay( void )
  1643. {
  1644. if ( !mat_drawTitleSafe.GetBool() )
  1645. return false;
  1646. int backBufferWidth, backBufferHeight;
  1647. materials->GetBackBufferDimensions( backBufferWidth, backBufferHeight );
  1648. int x, y, x1, y1;
  1649. // Required Title safe is TCR documented at inner 90% (RED)
  1650. int insetX = 0.05f * backBufferWidth;
  1651. int insetY = 0.05f * backBufferHeight;
  1652. x = insetX;
  1653. y = insetY;
  1654. x1 = backBufferWidth - insetX;
  1655. y1 = backBufferHeight - insetY;
  1656. vgui::surface()->DrawSetColor( 255, 0, 0, 255 );
  1657. vgui::surface()->DrawOutlinedRect( x, y, x1, y1 );
  1658. // Suggested Title Safe is TCR documented at inner 85% (YELLOW)
  1659. insetX = 0.075f * backBufferWidth;
  1660. insetY = 0.075f * backBufferHeight;
  1661. x = insetX;
  1662. y = insetY;
  1663. x1 = backBufferWidth - insetX;
  1664. y1 = backBufferHeight - insetY;
  1665. vgui::surface()->DrawSetColor( 255, 255, 0, 255 );
  1666. vgui::surface()->DrawOutlinedRect( x, y, x1, y1 );
  1667. return true;
  1668. }
  1669. void CFocusOverlayPanel::PostChildPaint( void )
  1670. {
  1671. BaseClass::PostChildPaint();
  1672. bool bNeedsMoveToFront = false;
  1673. if ( g_DrawTreeSelectedPanel )
  1674. {
  1675. int x, y, x1, y1;
  1676. vgui::ipanel()->GetClipRect( g_DrawTreeSelectedPanel, x, y, x1, y1 );
  1677. vgui::surface()->DrawSetColor( Color( 255, 0, 0, 255 ) );
  1678. vgui::surface()->DrawOutlinedRect( x, y, x1, y1 );
  1679. bNeedsMoveToFront = true;
  1680. }
  1681. if ( DrawTitleSafeOverlay() )
  1682. {
  1683. bNeedsMoveToFront = true;
  1684. }
  1685. if ( DrawFocusPanelList() )
  1686. {
  1687. bNeedsMoveToFront = true;
  1688. }
  1689. if ( bNeedsMoveToFront )
  1690. {
  1691. // will be valid for the next frame
  1692. MoveToFront();
  1693. }
  1694. }
  1695. bool CFocusOverlayPanel::DrawFocusPanelList( void )
  1696. {
  1697. if( !vgui_drawfocus.GetBool() )
  1698. return false;
  1699. int c = g_FocusPanelList.Size();
  1700. if ( c <= 0 )
  1701. return false;
  1702. int slot = 0;
  1703. int fullscreeninset = 0;
  1704. for ( int i = 0; i < c; i++ )
  1705. {
  1706. if ( slot > 31 )
  1707. break;
  1708. vgui::VPANEL vpanel = g_FocusPanelList[ i ];
  1709. if ( !vpanel )
  1710. continue;
  1711. if ( !vgui::ipanel()->IsVisible( vpanel ) )
  1712. return false;
  1713. // Convert panel bounds to screen space
  1714. int r, g, b;
  1715. GetColorForSlot( slot, r, g, b );
  1716. int x, y, x1, y1;
  1717. vgui::ipanel()->GetClipRect( vpanel, x, y, x1, y1 );
  1718. if ( (x1 - x) == videomode->GetModeUIWidth() &&
  1719. (y1 - y) == videomode->GetModeUIHeight() )
  1720. {
  1721. x += fullscreeninset;
  1722. y += fullscreeninset;
  1723. x1 -= fullscreeninset;
  1724. y1 -= fullscreeninset;
  1725. fullscreeninset++;
  1726. }
  1727. vgui::surface()->DrawSetColor( Color( r, g, b, 255 ) );
  1728. vgui::surface()->DrawOutlinedRect( x, y, x1, y1 );
  1729. slot++;
  1730. }
  1731. return true;
  1732. }
  1733. static void VGui_RecursiveFindPanels( CUtlVector< vgui::VPANEL >& panelList, vgui::VPANEL check, char const *panelname )
  1734. {
  1735. vgui::Panel *panel = vgui::ipanel()->GetPanel( check, "ENGINE" );
  1736. if ( !panel )
  1737. return;
  1738. if ( !Q_strncmp( panel->GetName(), panelname, strlen( panelname ) ) )
  1739. {
  1740. panelList.AddToTail( panel->GetVPanel() );
  1741. }
  1742. int childcount = panel->GetChildCount();
  1743. for ( int i = 0; i < childcount; i++ )
  1744. {
  1745. vgui::Panel *child = panel->GetChild( i );
  1746. VGui_RecursiveFindPanels( panelList, child->GetVPanel(), panelname );
  1747. }
  1748. }
  1749. void VGui_FindNamedPanels( CUtlVector< vgui::VPANEL >& panelList, char const *panelname )
  1750. {
  1751. vgui::VPANEL embedded = vgui::surface()->GetEmbeddedPanel();
  1752. // faster version of code below
  1753. // checks through each popup in order, top to bottom windows
  1754. int c = vgui::surface()->GetPopupCount();
  1755. for (int i = c - 1; i >= 0; i--)
  1756. {
  1757. vgui::VPANEL popup = vgui::surface()->GetPopup(i);
  1758. if ( !popup )
  1759. continue;
  1760. if ( embedded == popup )
  1761. continue;
  1762. VGui_RecursiveFindPanels( panelList, popup, panelname );
  1763. }
  1764. VGui_RecursiveFindPanels( panelList, embedded, panelname );
  1765. }
  1766. CON_COMMAND( vgui_togglepanel, "show/hide vgui panel by name." )
  1767. {
  1768. if ( args.ArgC() < 2 )
  1769. {
  1770. ConMsg( "Usage: vgui_showpanel panelname\n" );
  1771. return;
  1772. }
  1773. bool flip = false;
  1774. bool fg = true;
  1775. bool bg = true;
  1776. if ( args.ArgC() == 5 )
  1777. {
  1778. flip = atoi( args[ 2 ] ) ? true : false;
  1779. fg = atoi( args[ 3 ] ) ? true : false;
  1780. bg = atoi( args[ 4 ] ) ? true : false;
  1781. }
  1782. char const *panelname = args[ 1 ];
  1783. if ( !panelname || !panelname[ 0 ] )
  1784. return;
  1785. CUtlVector< vgui::VPANEL > panelList;
  1786. VGui_FindNamedPanels( panelList, panelname );
  1787. if ( !panelList.Size() )
  1788. {
  1789. ConMsg( "No panels starting with %s\n", panelname );
  1790. return;
  1791. }
  1792. for ( int i = 0; i < panelList.Size(); i++ )
  1793. {
  1794. vgui::VPANEL p = panelList[ i ];
  1795. if ( !p )
  1796. continue;
  1797. vgui::Panel *panel = vgui::ipanel()->GetPanel( p, "ENGINE");
  1798. if ( !panel )
  1799. continue;
  1800. Msg( "Toggling %s\n", panel->GetName() );
  1801. if ( fg )
  1802. {
  1803. panel->SetPaintEnabled( flip );
  1804. }
  1805. if ( bg )
  1806. {
  1807. panel->SetPaintBackgroundEnabled( flip );
  1808. }
  1809. }
  1810. }
  1811. static void VGui_RecursePanel( CUtlVector< vgui::VPANEL >& panelList, int x, int y, vgui::VPANEL check, bool include_hidden )
  1812. {
  1813. if( !include_hidden && !vgui::ipanel()->IsVisible( check ) )
  1814. {
  1815. return;
  1816. }
  1817. if ( vgui::ipanel()->IsWithinTraverse( check, x, y, false ) )
  1818. {
  1819. panelList.AddToTail( check );
  1820. }
  1821. int childcount = vgui::ipanel()->GetChildCount( check );
  1822. for ( int i = 0; i < childcount; i++ )
  1823. {
  1824. vgui::VPANEL child = vgui::ipanel()->GetChild( check, i );
  1825. VGui_RecursePanel( panelList, x, y, child, include_hidden );
  1826. }
  1827. }
  1828. void CEngineVGui::DrawMouseFocus( void )
  1829. {
  1830. VPROF( "CEngineVGui::DrawMouseFocus" );
  1831. g_FocusPanelList.RemoveAll();
  1832. if ( !vgui_drawfocus.GetBool() )
  1833. return;
  1834. staticFocusOverlayPanel->MoveToFront();
  1835. bool include_hidden = vgui_drawfocus.GetInt() == 2;
  1836. int x, y;
  1837. vgui::input()->GetCursorPos( x, y );
  1838. vgui::VPANEL embedded = vgui::surface()->GetEmbeddedPanel();
  1839. if ( vgui::surface()->IsCursorVisible() && vgui::surface()->IsWithin(x, y) )
  1840. {
  1841. // faster version of code below
  1842. // checks through each popup in order, top to bottom windows
  1843. int c = vgui::surface()->GetPopupCount();
  1844. for (int i = c - 1; i >= 0; i--)
  1845. {
  1846. vgui::VPANEL popup = vgui::surface()->GetPopup(i);
  1847. if ( !popup )
  1848. continue;
  1849. if ( popup == embedded )
  1850. continue;
  1851. if ( !vgui::ipanel()->IsVisible( popup ) )
  1852. continue;
  1853. VGui_RecursePanel( g_FocusPanelList, x, y, popup, include_hidden );
  1854. }
  1855. VGui_RecursePanel( g_FocusPanelList, x, y, embedded, include_hidden );
  1856. }
  1857. // Now draw them
  1858. con_nprint_t np;
  1859. np.time_to_live = 1.0f;
  1860. int c = g_FocusPanelList.Size();
  1861. int slot = 0;
  1862. for ( int i = 0; i < c; i++ )
  1863. {
  1864. if ( slot > 31 )
  1865. break;
  1866. vgui::VPANEL vpanel = g_FocusPanelList[ i ];
  1867. if ( !vpanel )
  1868. continue;
  1869. np.index = slot;
  1870. int r, g, b;
  1871. CFocusOverlayPanel::GetColorForSlot( slot, r, g, b );
  1872. np.color[ 0 ] = r / 255.0f;
  1873. np.color[ 1 ] = g / 255.0f;
  1874. np.color[ 2 ] = b / 255.0f;
  1875. Con_NXPrintf( &np, "%3i: %s\n", slot + 1, vgui::ipanel()->GetName(vpanel) );
  1876. slot++;
  1877. }
  1878. while ( slot <= 31 )
  1879. {
  1880. Con_NPrintf( slot, "" );
  1881. slot++;
  1882. }
  1883. }
  1884. void VGui_SetGameDLLPanelsVisible( bool show )
  1885. {
  1886. EngineVGui()->SetGameDLLPanelsVisible( show );
  1887. }
  1888. void CEngineVGui::ShowNewGameDialog( int chapter )
  1889. {
  1890. staticGameUIFuncs->ShowNewGameDialog( chapter );
  1891. }
  1892. void CEngineVGui::OnCreditsFinished( void )
  1893. {
  1894. staticGameUIFuncs->OnCreditsFinished();
  1895. }
  1896. bool CEngineVGui::ValidateStorageDevice(int *pStorageDeviceValidated)
  1897. {
  1898. return staticGameUIFuncs->ValidateStorageDevice( pStorageDeviceValidated );
  1899. }
  1900. //-----------------------------------------------------------------------------
  1901. // Dump the panel hierarchy
  1902. //-----------------------------------------------------------------------------
  1903. void DumpPanels_r( vgui::VPANEL panel, int level )
  1904. {
  1905. int i;
  1906. vgui::IPanel *ipanel = vgui::ipanel();
  1907. const char *pName = ipanel->GetName( panel );
  1908. char indentBuff[32];
  1909. for (i=0; i<level; i++)
  1910. {
  1911. indentBuff[i] = '.';
  1912. }
  1913. indentBuff[i] = '\0';
  1914. ConMsg( "%s%s\n", indentBuff, pName[0] ? pName : "???" );
  1915. int childcount = ipanel->GetChildCount( panel );
  1916. for ( i = 0; i < childcount; i++ )
  1917. {
  1918. vgui::VPANEL child = ipanel->GetChild( panel, i );
  1919. DumpPanels_r( child, level+1 );
  1920. }
  1921. }
  1922. void DumpPanels_f()
  1923. {
  1924. vgui::VPANEL embedded = vgui::surface()->GetEmbeddedPanel();
  1925. DumpPanels_r( embedded, 0 );
  1926. }
  1927. ConCommand DumpPanels("dump_panels", DumpPanels_f, "Dump Panel Tree" );
  1928. #if defined( _X360 )
  1929. //-----------------------------------------------------------------------------
  1930. // Purpose: For testing message dialogs
  1931. //-----------------------------------------------------------------------------
  1932. #include "vgui_controls/MessageDialog.h"
  1933. CON_COMMAND( dlg_normal, "Display a sample message dialog" )
  1934. {
  1935. EngineVGui()->ShowMessageDialog( MD_STANDARD_SAMPLE );
  1936. }
  1937. CON_COMMAND( dlg_warning, "Display a sample warning message dialog" )
  1938. {
  1939. EngineVGui()->ShowMessageDialog( MD_WARNING_SAMPLE );
  1940. }
  1941. CON_COMMAND( dlg_error, "Display a sample error message dialog" )
  1942. {
  1943. EngineVGui()->ShowMessageDialog( MD_ERROR_SAMPLE );
  1944. }
  1945. #endif