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.

3009 lines
83 KiB

  1. //===== Copyright 1996-2005, 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. #elif OSX
  12. #include <Carbon/Carbon.h>
  13. #endif
  14. #include "appframework/ilaunchermgr.h"
  15. #include <vgui_controls/Panel.h>
  16. #include <vgui_controls/EditablePanel.h>
  17. #include <matsys_controls/matsyscontrols.h>
  18. #include <vgui/Cursor.h>
  19. #include <vgui_controls/PHandle.h>
  20. #include "keys.h"
  21. #include "console.h"
  22. #include "gl_matsysiface.h"
  23. #include "cdll_engine_int.h"
  24. #include "demo.h"
  25. #include "sys_dll.h"
  26. #include "sound.h"
  27. #include "soundflags.h"
  28. #include "filesystem_engine.h"
  29. #include "igame.h"
  30. #include "con_nprint.h"
  31. #include "vgui_DebugSystemPanel.h"
  32. #include "tier0/vprof.h"
  33. #include "cl_demoactionmanager.h"
  34. #include "enginebugreporter.h"
  35. #include "engineperftools.h"
  36. #include "icolorcorrectiontools.h"
  37. #include "tier0/icommandline.h"
  38. #include "client.h"
  39. #include "server.h"
  40. #include "sys.h" // Sys_GetRegKeyValue()
  41. #include "vgui_drawtreepanel.h"
  42. #include "vgui_vprofpanel.h"
  43. #include "vgui/vgui.h"
  44. #include "vgui/IInput.h"
  45. #include <vgui/IInputInternal.h>
  46. #include "vgui_controls/AnimationController.h"
  47. #include "vgui_vprofgraphpanel.h"
  48. #include "vgui_texturebudgetpanel.h"
  49. #include "vgui_budgetpanel.h"
  50. #include "Steam.h" // for SteamGetUser()
  51. #include "ivideomode.h"
  52. #include "cl_pluginhelpers.h"
  53. #include "cl_main.h" // CL_IsHL2Demo()
  54. #include "cl_steamauth.h"
  55. #include "inputsystem/iinputstacksystem.h"
  56. // interface to gameui dll
  57. #include <GameUI/IGameUI.h>
  58. #include <GameUI/IGameConsole.h>
  59. // interface to expose vgui root panels
  60. #include <ienginevgui.h>
  61. #include "VGuiMatSurface/IMatSystemSurface.h"
  62. #include "cl_texturelistpanel.h"
  63. #include "cl_demouipanel.h"
  64. #include "cl_foguipanel.h"
  65. #include "cl_txviewpanel.h"
  66. // vgui2 interface
  67. // note that GameUI project uses ..\public\vgui and ..\public\vgui_controls, not ..\utils\vgui\include
  68. #include <vgui/vgui.h>
  69. #include <vgui/Cursor.h>
  70. #include <keyvalues.h>
  71. #include <vgui/ILocalize.h>
  72. #include <vgui/IPanel.h>
  73. #include <vgui/IScheme.h>
  74. #include <vgui/IVGui.h>
  75. #include <vgui/ISystem.h>
  76. #include <vgui/ISurface.h>
  77. #include <vgui_controls/EditablePanel.h>
  78. #include <vgui_controls/MenuButton.h>
  79. #include <vgui_controls/Menu.h>
  80. #include <vgui_controls/PHandle.h>
  81. #include "IVguiModule.h"
  82. #include "vgui_baseui_interface.h"
  83. #include "vgui_DebugSystemPanel.h"
  84. #include "toolframework/itoolframework.h"
  85. #include "filesystem/IQueuedLoader.h"
  86. #include "LoadScreenUpdate.h"
  87. #include "tier0/etwprof.h"
  88. #if defined( _X360 )
  89. #include "xbox/xbox_win32stubs.h"
  90. #endif
  91. #include "vgui_askconnectpanel.h"
  92. #include "tier1/tokenset.h"
  93. #if defined( INCLUDE_SCALEFORM )
  94. #include "scaleformui/scaleformui.h"
  95. #endif
  96. // memdbgon must be the last include file in a .cpp file!!!
  97. #include "tier0/memdbgon.h"
  98. using namespace vgui;
  99. extern IVEngineClient *engineClient;
  100. extern HWND *pmainwindow;
  101. extern bool g_bTextMode;
  102. static int g_syncReportLevel = -1;
  103. static void VGui_PlaySound(const char *pFileName);
  104. void VGui_ActivateMouse();
  105. extern CreateInterfaceFn g_AppSystemFactory;
  106. // functions to reference GameUI and GameConsole functions, from GameUI.dll
  107. IGameUI *staticGameUIFuncs = NULL;
  108. IGameUI* GetGameUI( void )
  109. {
  110. return staticGameUIFuncs;
  111. }
  112. IGameConsole *staticGameConsole = NULL;
  113. // cache some of the state we pass through to matsystemsurface, for visibility
  114. bool s_bWindowsInputEnabled = true;
  115. ConVar r_drawvgui( "r_drawvgui", "1", FCVAR_CHEAT, "Enable the rendering of vgui panels" );
  116. ConVar gameui_xbox( "gameui_xbox", "0", 0 );
  117. // Tracks whether console window is open or not - true as soon as we receive the request to open it, until after it has shutdown
  118. ConVar cv_console_window_open( "console_window_open", NULL, FCVAR_HIDDEN, "Is the console window active" );
  119. ConVar cv_ignore_ui_activate_key( "ignore_ui_activate_key", NULL, FCVAR_HIDDEN, "When set will ignore UI activation key" );
  120. ConVar cv_vguipanel_active( "vgui_panel_active", NULL, FCVAR_HIDDEN, "Is a vgui panel currently active" );
  121. ConVar cv_server_browser_dialog_open( "server_browser_dialog_open", NULL, FCVAR_HIDDEN, "Is the server browser window active" );
  122. void Con_CreateConsolePanel( Panel *parent );
  123. void CL_CreateEntityReportPanel( Panel *parent );
  124. void ClearIOStates( void );
  125. #ifdef IHV_DEMO
  126. // Enabled for IHV demos
  127. void CreateWatermarkPanel( Panel *parent );
  128. #endif
  129. // turn this on if you're tuning progress bars
  130. // #define ENABLE_LOADING_PROGRESS_PROFILING
  131. #define PT( x ) #x, x
  132. static tokenset_t< LevelLoadingProgress_e > g_ProgressTokens[]=
  133. {
  134. { PT( PROGRESS_DEFAULT ) },
  135. { PT( PROGRESS_NONE ) },
  136. { PT( PROGRESS_CHANGELEVEL ) },
  137. { PT( PROGRESS_SPAWNSERVER ) },
  138. { PT( PROGRESS_LOADWORLDMODEL ) },
  139. { PT( PROGRESS_CRCMAP ) },
  140. { PT( PROGRESS_CRCCLIENTDLL ) },
  141. { PT( PROGRESS_CREATENETWORKSTRINGTABLES ) },
  142. { PT( PROGRESS_PRECACHEWORLD ) },
  143. { PT( PROGRESS_CLEARWORLD ) },
  144. { PT( PROGRESS_LEVELINIT ) },
  145. { PT( PROGRESS_PRECACHE ) },
  146. { PT( PROGRESS_ACTIVATESERVER ) },
  147. { PT( PROGRESS_BEGINCONNECT ) },
  148. { PT( PROGRESS_SIGNONCHALLENGE ) },
  149. { PT( PROGRESS_SIGNONCONNECT ) },
  150. { PT( PROGRESS_SIGNONCONNECTED ) },
  151. { PT( PROGRESS_PROCESSSERVERINFO ) },
  152. { PT( PROGRESS_PROCESSSTRINGTABLE ) },
  153. { PT( PROGRESS_SIGNONNEW ) },
  154. { PT( PROGRESS_SENDCLIENTINFO ) },
  155. { PT( PROGRESS_SENDSIGNONDATA ) },
  156. { PT( PROGRESS_SIGNONSPAWN ) },
  157. { PT( PROGRESS_CREATEENTITIES ) },
  158. { PT( PROGRESS_FULLYCONNECTED ) },
  159. { PT( PROGRESS_PRECACHELIGHTING ) },
  160. { PT( PROGRESS_READYTOPLAY ) },
  161. { PT( PROGRESS_HIGHESTITEM ) },
  162. { NULL, PROGRESS_INVALID }
  163. };
  164. //-----------------------------------------------------------------------------
  165. // Purpose: Console command to hide the gameUI, most commonly called from gameUI.dll
  166. //-----------------------------------------------------------------------------
  167. CON_COMMAND( gameui_hide, "Hides the game UI" )
  168. {
  169. EngineVGui()->HideGameUI();
  170. }
  171. //-----------------------------------------------------------------------------
  172. // Purpose: Console command to activate the gameUI, most commonly called from gameUI.dll
  173. //-----------------------------------------------------------------------------
  174. CON_COMMAND( gameui_activate, "Shows the game UI" )
  175. {
  176. EngineVGui()->ActivateGameUI();
  177. }
  178. //-----------------------------------------------------------------------------
  179. // Purpose:
  180. //-----------------------------------------------------------------------------
  181. CON_COMMAND( gameui_preventescape, "Escape key doesn't hide game UI" )
  182. {
  183. EngineVGui()->SetNotAllowedToHideGameUI( true );
  184. }
  185. //-----------------------------------------------------------------------------
  186. // Purpose:
  187. //-----------------------------------------------------------------------------
  188. CON_COMMAND( gameui_allowescapetoshow, "Escape key allowed to show game UI" )
  189. {
  190. EngineVGui()->SetNotAllowedToShowGameUI( false );
  191. }
  192. //-----------------------------------------------------------------------------
  193. // Purpose:
  194. //-----------------------------------------------------------------------------
  195. CON_COMMAND( gameui_preventescapetoshow, "Escape key doesn't show game UI" )
  196. {
  197. EngineVGui()->SetNotAllowedToShowGameUI( true );
  198. }
  199. //-----------------------------------------------------------------------------
  200. // Purpose:
  201. //-----------------------------------------------------------------------------
  202. CON_COMMAND( gameui_allowescape, "Escape key allowed to hide game UI" )
  203. {
  204. EngineVGui()->SetNotAllowedToHideGameUI( false );
  205. }
  206. //-----------------------------------------------------------------------------
  207. // Purpose: Console command to enable progress bar for next load
  208. //-----------------------------------------------------------------------------
  209. void BaseUI_ProgressEnabled_f()
  210. {
  211. EngineVGui()->EnabledProgressBarForNextLoad();
  212. }
  213. static ConCommand progress_enable("progress_enable", &BaseUI_ProgressEnabled_f );
  214. //-----------------------------------------------------------------------------
  215. // Purpose:
  216. //-----------------------------------------------------------------------------
  217. class CEnginePanel : public EditablePanel
  218. {
  219. typedef EditablePanel BaseClass;
  220. public:
  221. CEnginePanel( Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
  222. {
  223. //m_bCanFocus = true;
  224. SetMouseInputEnabled( true );
  225. SetKeyBoardInputEnabled( true );
  226. }
  227. CEnginePanel( VPANEL parent, const char *pName ) : BaseClass( NULL, pName )
  228. {
  229. SetParent( parent );
  230. //m_bCanFocus = true;
  231. SetMouseInputEnabled( true );
  232. SetKeyBoardInputEnabled( true );
  233. }
  234. void EnableMouseFocus( bool state )
  235. {
  236. //m_bCanFocus = state;
  237. SetMouseInputEnabled( state );
  238. SetKeyBoardInputEnabled( state );
  239. }
  240. };
  241. //-----------------------------------------------------------------------------
  242. // Purpose:
  243. //-----------------------------------------------------------------------------
  244. class CStaticPanel : public Panel
  245. {
  246. typedef Panel BaseClass;
  247. public:
  248. CStaticPanel( Panel *pParent, const char *pName ) : Panel( pParent, pName )
  249. {
  250. SetCursor( dc_none );
  251. SetKeyBoardInputEnabled( false );
  252. SetMouseInputEnabled( false );
  253. }
  254. };
  255. vgui::VPanelHandle g_DrawTreeSelectedPanel;
  256. //-----------------------------------------------------------------------------
  257. // Purpose:
  258. //-----------------------------------------------------------------------------
  259. class CFocusOverlayPanel : public Panel
  260. {
  261. typedef Panel BaseClass;
  262. public:
  263. CFocusOverlayPanel( Panel *pParent, const char *pName );
  264. virtual void PostChildPaint( void );
  265. static void GetColorForSlot( int slot, int& r, int& g, int& b )
  266. {
  267. r = (int)( 124.0 + slot * 47.3 ) & 255;
  268. g = (int)( 63.78 - slot * 71.4 ) & 255;
  269. b = (int)( 188.42 + slot * 13.57 ) & 255;
  270. }
  271. bool DrawTitleSafeOverlay( void );
  272. bool DrawFocusPanelList( void );
  273. bool DrawKeyFocusPanel( void );
  274. };
  275. //-----------------------------------------------------------------------------
  276. // Purpose:
  277. //-----------------------------------------------------------------------------
  278. class CTransitionEffectPanel : public EditablePanel
  279. {
  280. typedef EditablePanel BaseClass;
  281. public:
  282. CTransitionEffectPanel( Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
  283. {
  284. SetBounds( 0, 0, videomode->GetModeWidth(), videomode->GetModeHeight() );
  285. SetPaintBorderEnabled( false );
  286. SetPaintBackgroundEnabled( false );
  287. SetPaintEnabled( true );
  288. SetVisible( true );
  289. SetCursor( dc_none );
  290. SetMouseInputEnabled( false );
  291. SetKeyBoardInputEnabled( true );
  292. }
  293. bool IsEffectEnabled()
  294. {
  295. return staticGameUIFuncs->IsTransitionEffectEnabled();
  296. }
  297. };
  298. //-----------------------------------------------------------------------------
  299. //
  300. // Purpose: Centerpoint for handling all user interface in the engine
  301. //
  302. //-----------------------------------------------------------------------------
  303. class CEngineVGui : public IEngineVGuiInternal
  304. {
  305. public:
  306. CEngineVGui();
  307. ~CEngineVGui();
  308. // Methods of IEngineVGui
  309. virtual VPANEL GetPanel( VGuiPanel_t type );
  310. // Methods of IEngineVGuiInternal
  311. virtual void Init();
  312. virtual void Connect();
  313. virtual void Shutdown();
  314. virtual bool SetVGUIDirectories();
  315. virtual bool IsInitialized() const;
  316. virtual bool Key_Event( const InputEvent_t &event );
  317. virtual void UpdateButtonState( const InputEvent_t &event );
  318. virtual void BackwardCompatibility_Paint();
  319. virtual void Paint( PaintMode_t mode );
  320. virtual void PostInit();
  321. CreateInterfaceFn GetGameUIFactory()
  322. {
  323. return m_GameUIFactory;
  324. }
  325. // handlers for game UI (main menu)
  326. virtual void ActivateGameUI();
  327. virtual bool HideGameUI();
  328. virtual bool IsGameUIVisible();
  329. // console
  330. virtual void ShowConsole();
  331. virtual void HideConsole();
  332. virtual bool IsConsoleVisible();
  333. virtual void ClearConsole();
  334. // level loading
  335. virtual void OnLevelLoadingStarted( char const *levelName, bool bLocalServer );
  336. virtual void OnLevelLoadingFinished();
  337. virtual void NotifyOfServerConnect(const char *game, int IP, int connectionPort, int queryPort);
  338. virtual void NotifyOfServerDisconnect();
  339. virtual void UpdateProgressBar(LevelLoadingProgress_e progress, bool showDialog = true );
  340. virtual void UpdateCustomProgressBar( float progress, const wchar_t *desc );
  341. virtual void StartCustomProgress();
  342. virtual void FinishCustomProgress();
  343. virtual void UpdateSecondaryProgressBarWithFile( float progress, const char *pDesc, int nBytesTotal );
  344. virtual void UpdateSecondaryProgressBar( float progress, const wchar_t *desc );
  345. virtual void StartLoadingScreenForCommand( const char* command );
  346. virtual void StartLoadingScreenForKeyValues( KeyValues* keyValues );
  347. virtual void EnabledProgressBarForNextLoad()
  348. {
  349. m_bShowProgressDialog = true;
  350. }
  351. // Should pause?
  352. virtual bool ShouldPause();
  353. virtual void ShowErrorMessage();
  354. virtual void SetNotAllowedToHideGameUI( bool bNotAllowedToHide )
  355. {
  356. m_bNotAllowedToHideGameUI = bNotAllowedToHide;
  357. }
  358. virtual void SetNotAllowedToShowGameUI( bool bNotAllowedToShow )
  359. {
  360. m_bNotAllowedToShowGameUI = bNotAllowedToShow;
  361. }
  362. virtual void HideLoadingPlaque( void )
  363. {
  364. if ( scr_drawloading )
  365. {
  366. OnLevelLoadingFinished();
  367. S_OnLoadScreen( false );
  368. }
  369. S_PreventSound(false);//it is now safe to use audio again.
  370. scr_disabled_for_loading = false;
  371. scr_drawloading = false;
  372. }
  373. void SetGameDLLPanelsVisible( bool show )
  374. {
  375. if ( !staticGameDLLPanel )
  376. {
  377. return;
  378. }
  379. staticGameDLLPanel->SetVisible( show );
  380. }
  381. // Allows the level loading progress to show map-specific info
  382. virtual void SetProgressLevelName( const char *levelName );
  383. virtual void OnToolModeChanged( bool bGameMode );
  384. virtual InputContextHandle_t GetGameUIInputContext() { return m_hGameUIInputContext; }
  385. virtual void NeedConnectionProblemWaitScreen();
  386. virtual void ShowPasswordUI( char const *pchCurrentPW );
  387. void SetProgressBias( float bias );
  388. void UpdateProgressBar( float progress, const char *pszDesc = NULL, bool showDialog = true );
  389. virtual bool IsPlayingFullScreenVideo();
  390. private:
  391. Panel *GetRootPanel( VGuiPanel_t type );
  392. void SetEngineVisible( bool state );
  393. void DrawMouseFocus( void );
  394. void DrawKeyFocus( void );
  395. void CreateVProfPanels( Panel *pParent );
  396. void DestroyVProfPanels( );
  397. void HideVProfPanels();
  398. virtual void Simulate();
  399. // debug overlays
  400. bool IsDebugSystemVisible();
  401. void HideDebugSystem();
  402. bool IsShiftKeyDown();
  403. bool IsAltKeyDown();
  404. bool IsCtrlKeyDown();
  405. CON_COMMAND_MEMBER_F( CEngineVGui, "debugsystemui", ToggleDebugSystemUI, "Show/hide the debug system UI.", FCVAR_CHEAT );
  406. void PreparePanel( Panel *panel, int nZPos, bool bVisible = true );
  407. private:
  408. enum { MAX_NUM_FACTORIES = 5 };
  409. CreateInterfaceFn m_FactoryList[MAX_NUM_FACTORIES];
  410. int m_iNumFactories;
  411. CSysModule *m_hStaticGameUIModule;
  412. CreateInterfaceFn m_GameUIFactory;
  413. // top level VGUI2 panel
  414. CStaticPanel *staticPanel;
  415. // base level panels for other subsystems, rooted on staticPanel
  416. CEnginePanel *staticClientDLLPanel;
  417. CEnginePanel *staticClientDLLToolsPanel;
  418. CEnginePanel *staticGameUIPanel;
  419. CEnginePanel *staticGameUIBackgroundPanel;
  420. CEnginePanel *staticGameDLLPanel;
  421. // Want engine tools to be on top of other engine panels
  422. CEnginePanel *staticEngineToolsPanel;
  423. CDebugSystemPanel *staticDebugSystemPanel;
  424. CEnginePanel *staticSteamOverlayPanel;
  425. CFocusOverlayPanel *staticFocusOverlayPanel;
  426. CTransitionEffectPanel *staticTransitionPanel;
  427. #ifdef VPROF_ENABLED
  428. CVProfPanel *m_pVProfPanel;
  429. CBudgetPanelEngine *m_pBudgetPanel;
  430. CTextureBudgetPanel *m_pTextureBudgetPanel;
  431. #endif
  432. // progress bar
  433. bool m_bShowProgressDialog;
  434. LevelLoadingProgress_e m_eLastProgressPoint;
  435. // progress bar debugging
  436. int m_nLastProgressPointRepeatCount;
  437. double m_flLoadingStartTime;
  438. struct LoadingProgressEntry_t
  439. {
  440. double flTime;
  441. LevelLoadingProgress_e eProgress;
  442. };
  443. CUtlVector<LoadingProgressEntry_t> m_LoadingProgress;
  444. bool m_bSaveProgress : 1;
  445. bool m_bNoShaderAPI : 1;
  446. // game ui hiding control
  447. bool m_bNotAllowedToHideGameUI : 1;
  448. bool m_bNotAllowedToShowGameUI : 1;
  449. IInputInternal *m_pInputInternal;
  450. // used to start the progress from an arbitrary position
  451. float m_ProgressBias;
  452. InputContextHandle_t m_hGameUIInputContext;
  453. IMaterial *m_pConstantColorMaterial;
  454. };
  455. //-----------------------------------------------------------------------------
  456. // Purpose: singleton accessor
  457. //-----------------------------------------------------------------------------
  458. static CEngineVGui g_EngineVGuiImp;
  459. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CEngineVGui, IEngineVGui, VENGINE_VGUI_VERSION, g_EngineVGuiImp );
  460. IEngineVGuiInternal *EngineVGui()
  461. {
  462. return &g_EngineVGuiImp;
  463. }
  464. //-----------------------------------------------------------------------------
  465. // The loader progress is updated by the queued loader. It uses an initial
  466. // reserved portion of the bar.
  467. //-----------------------------------------------------------------------------
  468. #define PROGRESS_RESERVE 0.50f
  469. class CLoaderProgress : public ILoaderProgress
  470. {
  471. public:
  472. CLoaderProgress()
  473. {
  474. // initialize to disabled state
  475. m_SnappedProgress = -1;
  476. m_flLastProgress = 0.0f;
  477. }
  478. void BeginProgress()
  479. {
  480. g_EngineVGuiImp.SetProgressBias( 0 );
  481. m_SnappedProgress = 0;
  482. }
  483. void UpdateProgress( float progress, bool bForce )
  484. {
  485. if ( !bForce )
  486. {
  487. m_flLastProgress = progress;
  488. }
  489. if ( m_SnappedProgress == - 1 && !bForce )
  490. {
  491. // not enabled
  492. return;
  493. }
  494. int snappedProgress = progress * 15;
  495. // Need excessive updates on the console to keep the XBox slider inny bar/XMB active
  496. if ( !IsGameConsole() && ( snappedProgress <= m_SnappedProgress ) )
  497. {
  498. // prevent excessive updates
  499. return;
  500. }
  501. m_SnappedProgress = snappedProgress;
  502. // up to reserved
  503. g_EngineVGuiImp.UpdateProgressBar( bForce ? 1.0f : ( PROGRESS_RESERVE * progress ) );
  504. }
  505. void EndProgress()
  506. {
  507. // the normal legacy bar now picks up after reserved region
  508. g_EngineVGuiImp.SetProgressBias( PROGRESS_RESERVE );
  509. m_SnappedProgress = -1;
  510. }
  511. void PauseNonInteractiveProgress( bool bPause )
  512. {
  513. PauseLoadingUpdates( bPause );
  514. }
  515. private:
  516. int m_SnappedProgress;
  517. float m_flLastProgress;
  518. };
  519. static CLoaderProgress s_LoaderProgress;
  520. //-----------------------------------------------------------------------------
  521. // Purpose: Constructor
  522. //-----------------------------------------------------------------------------
  523. CEngineVGui::CEngineVGui()
  524. {
  525. staticPanel = NULL;
  526. staticClientDLLToolsPanel = NULL;
  527. staticClientDLLPanel = NULL;
  528. staticGameDLLPanel = NULL;
  529. staticGameUIPanel = NULL;
  530. staticGameUIBackgroundPanel = NULL;
  531. staticEngineToolsPanel = NULL;
  532. staticDebugSystemPanel = NULL;
  533. staticSteamOverlayPanel = NULL;
  534. staticFocusOverlayPanel = NULL;
  535. staticTransitionPanel = NULL;
  536. m_hGameUIInputContext = INPUT_CONTEXT_HANDLE_INVALID;
  537. m_hStaticGameUIModule = NULL;
  538. m_GameUIFactory = NULL;
  539. #ifdef VPROF_ENABLED
  540. m_pVProfPanel = NULL;
  541. #endif
  542. m_bShowProgressDialog = false;
  543. m_bSaveProgress = false;
  544. m_bNoShaderAPI = false;
  545. m_bNotAllowedToHideGameUI = false;
  546. m_bNotAllowedToShowGameUI = false;
  547. m_pInputInternal = NULL;
  548. m_ProgressBias = 0;
  549. m_pConstantColorMaterial = NULL;
  550. }
  551. //-----------------------------------------------------------------------------
  552. // Purpose: Destructor
  553. //-----------------------------------------------------------------------------
  554. CEngineVGui::~CEngineVGui()
  555. {
  556. }
  557. //-----------------------------------------------------------------------------
  558. // add all the base search paths used by VGUI (platform, skins directory, language dirs)
  559. //-----------------------------------------------------------------------------
  560. bool CEngineVGui::SetVGUIDirectories()
  561. {
  562. // add vgui skins directory last
  563. #if defined(_WIN32)
  564. if ( IsPC() )
  565. {
  566. char temp[ 512 ];
  567. char skin[128];
  568. skin[0] = 0;
  569. Sys_GetRegKeyValue("Software\\Valve\\Steam", "Skin", skin, sizeof(skin), "");
  570. if (strlen(skin) > 0)
  571. {
  572. sprintf( temp, "%s/platform/skins/%s", GetBaseDirectory(), skin );
  573. g_pFileSystem->AddSearchPath( temp, "SKIN" );
  574. }
  575. }
  576. #endif
  577. return true;
  578. }
  579. void CEngineVGui::PreparePanel( Panel *panel, int nZPos, bool bVisible /*= true*/ )
  580. {
  581. panel->SetBounds( 0, 0, videomode->GetModeWidth(), videomode->GetModeHeight() );
  582. panel->SetPaintBorderEnabled(false);
  583. panel->SetPaintBackgroundEnabled(false);
  584. panel->SetPaintEnabled(false);
  585. panel->SetVisible(true);
  586. panel->SetCursor( dc_none );
  587. panel->SetVisible( bVisible );
  588. panel->SetZPos( nZPos );
  589. }
  590. //-----------------------------------------------------------------------------
  591. // Setup the base vgui panels
  592. //-----------------------------------------------------------------------------
  593. void CEngineVGui::Init()
  594. {
  595. const char *szDllName = "";
  596. if ( CommandLine()->FindParm( "-gameuidll" ) )
  597. {
  598. COM_TimestampedLog( "Loading gameui.dll" );
  599. // load the GameUI dll
  600. szDllName = "gameui";
  601. m_hStaticGameUIModule = g_pFileSystem->LoadModule(szDllName, "GAMEBIN", true); // LoadModule() does a GetLocalCopy() call
  602. m_GameUIFactory = Sys_GetFactory(m_hStaticGameUIModule);
  603. if ( !m_GameUIFactory )
  604. {
  605. Error( "Could not load: %s\n", szDllName );
  606. }
  607. }
  608. else
  609. {
  610. // Get the gameui interfaces from client.dll
  611. extern CreateInterfaceFn g_ClientFactory;
  612. m_GameUIFactory = g_ClientFactory;
  613. szDllName = "client";
  614. }
  615. // get the initialization func
  616. staticGameUIFuncs = (IGameUI *)m_GameUIFactory(GAMEUI_INTERFACE_VERSION, NULL);
  617. if (!staticGameUIFuncs )
  618. {
  619. Error( "Could not get IGameUI interface %s from %s\n", GAMEUI_INTERFACE_VERSION, szDllName );
  620. }
  621. if ( IsPC() )
  622. {
  623. staticGameConsole = (IGameConsole *)m_GameUIFactory(GAMECONSOLE_INTERFACE_VERSION, NULL);
  624. if ( !staticGameConsole )
  625. {
  626. Sys_Error( "Could not get IGameConsole interface %s from %s\n", GAMECONSOLE_INTERFACE_VERSION, szDllName );
  627. }
  628. }
  629. // Create UI Input contexts
  630. // NOTE: The GameUI context may or may not be used by the client
  631. // so we'll start it out disabled
  632. m_hGameUIInputContext = g_pInputStackSystem->PushInputContext();
  633. g_pInputStackSystem->EnableInputContext( m_hGameUIInputContext, false );
  634. InputContextHandle_t hVGuiInputContext = g_pInputStackSystem->PushInputContext();
  635. g_pMatSystemSurface->SetInputContext( hVGuiInputContext );
  636. VGui_InitMatSysInterfacesList( "BaseUI", &g_AppSystemFactory, 1 );
  637. #ifdef OSX
  638. if ( Steam3Client().SteamApps() )
  639. {
  640. // just follow the language steam wants you to be
  641. const char *lang = Steam3Client().SteamApps()->GetCurrentGameLanguage();
  642. if ( lang && Q_strlen(lang) )
  643. vgui::system()->SetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\Language", lang );
  644. }
  645. #endif
  646. COM_TimestampedLog( "AttachToWindow" );
  647. // Need to be able to play sounds through vgui
  648. g_pMatSystemSurface->InstallPlaySoundFunc( VGui_PlaySound );
  649. COM_TimestampedLog( "Load Scheme File" );
  650. // load scheme
  651. const char *pStr = "Resource/SourceScheme.res";
  652. if ( !scheme()->LoadSchemeFromFile( pStr, "Tracker" ))
  653. {
  654. Sys_Error( "Error loading file %s\n", pStr );
  655. return;
  656. }
  657. if ( IsGameConsole() )
  658. {
  659. CCommand ccommand;
  660. if ( CL_ShouldLoadBackgroundLevel( ccommand ) )
  661. {
  662. // Must be before the game ui base panel starts up
  663. // This is a hint to avoid the menu pop due to the impending background map
  664. // that the game ui is not aware of until 1 frame later.
  665. staticGameUIFuncs->SetProgressOnStart();
  666. }
  667. }
  668. COM_TimestampedLog( "ivgui()->Start()" );
  669. // Start the App running
  670. ivgui()->Start();
  671. ivgui()->SetSleep(false);
  672. bool bTools = CommandLine()->CheckParm( "-tools" ) != NULL;
  673. // setup base panel for the whole VGUI System
  674. // The root panel for everything ( NULL parent makes it a child of the embedded panel )
  675. // Ideal hierarchy:
  676. // Root -- staticPanel
  677. #if defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  678. // staticGameUIBackgroundPanel ( loading image only ) (zpos 0)
  679. // staticClientDLLPanel ( zpos == 25 )
  680. // staticClientDLLPanelFullscreen ( zpos == 26 )
  681. // staticGameUIPanel ( GameUI stuff, zpos 40 )
  682. // staticClientDLLToolsPanel ( zpos == 28 )
  683. // staticGameDLLPanel ( zpos == 50 ) [ Tool Framework Root ]
  684. // staticEngineToolsPanel ( zpos == 75 )
  685. // staticDebugSystemPanel ( Engine debug stuff ) zpos == 125 )
  686. // staticSteamOverlayPanel (STEAM OVERLAY ON PS3) zpos = 140
  687. // staticFocusOverlayPanel (zpos == 150)
  688. #endif
  689. COM_TimestampedLog( "Building Panels (staticPanel)" );
  690. staticPanel = new CStaticPanel( NULL, "staticPanel" );
  691. staticPanel->SetParent( surface()->GetEmbeddedPanel() );
  692. PreparePanel( staticPanel, 0 );
  693. COM_TimestampedLog( "Building Panels (staticGameUIBackgroundPanel)" );
  694. staticGameUIBackgroundPanel = new CEnginePanel( staticPanel, "GameUI Background Panel" );
  695. PreparePanel( staticGameUIBackgroundPanel, 0 );
  696. COM_TimestampedLog( "Building Panels (staticClientDLLPanel)" );
  697. staticClientDLLPanel = new CEnginePanel( staticPanel, "staticClientDLLPanel" );
  698. PreparePanel( staticClientDLLPanel, 25, false );
  699. staticClientDLLPanel->SetKeyBoardInputEnabled( false ); // popups in the client DLL can enable this.
  700. // This panel has it's own animation controller, which makes it 1.1Mb to instance
  701. // which is too much on the console which doesn't support plugins anyway.
  702. if ( IsPC() )
  703. {
  704. COM_TimestampedLog( "Building Panels (CreateAskConnectPanel)" );
  705. CreateAskConnectPanel( staticPanel->GetVPanel() );
  706. }
  707. COM_TimestampedLog( "Building Panels (staticClientDLLToolsPanel)" );
  708. staticClientDLLToolsPanel = new CEnginePanel( staticPanel, "staticClientDLLToolsPanel" );
  709. PreparePanel( staticClientDLLToolsPanel, 28 );
  710. // popups in the client DLL can enable this.
  711. staticClientDLLToolsPanel->SetKeyBoardInputEnabled( false );
  712. COM_TimestampedLog( "Building Panels (staticGameUIPanel)" );
  713. staticGameUIPanel = new CEnginePanel( staticPanel, "GameUI Panel" );
  714. #if defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  715. PreparePanel( staticGameUIPanel, 40 );
  716. #else
  717. PreparePanel( staticGameUIPanel, 100 );
  718. #endif
  719. COM_TimestampedLog( "Building Panels (staticGameDLLPanel)" );
  720. staticGameDLLPanel = new CEnginePanel( staticPanel, "staticGameDLLPanel" );
  721. #if defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  722. PreparePanel( staticGameDLLPanel, 50 );
  723. #else
  724. PreparePanel( staticGameDLLPanel, 135 );
  725. #endif
  726. staticGameDLLPanel->SetKeyBoardInputEnabled( false ); // popups in the game DLL can enable this.
  727. COM_TimestampedLog( "Building Panels (Engine Tools)" );
  728. staticEngineToolsPanel = new CEnginePanel( bTools ? staticGameDLLPanel->GetVPanel() : staticPanel->GetVPanel(), "Engine Tools" );
  729. #if defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  730. PreparePanel( staticEngineToolsPanel, 75 );
  731. #else
  732. PreparePanel( staticEngineToolsPanel, 100 );
  733. #endif
  734. staticEngineToolsPanel->SetKeyBoardInputEnabled( false ); // popups in the game DLL can enable this.
  735. staticEngineToolsPanel->SetMouseInputEnabled( false ); // popups in the game DLL can enable this.
  736. if ( IsPC() )
  737. {
  738. COM_TimestampedLog( "Building Panels (staticDebugSystemPanel)" );
  739. staticDebugSystemPanel = new CDebugSystemPanel( staticPanel, "Engine Debug System" );
  740. staticDebugSystemPanel->SetZPos( 125 );
  741. // Install demo playback/editing UI
  742. CDemoUIPanel::InstallDemoUI( staticEngineToolsPanel );
  743. //CDemoUIPanel2::Install( staticClientDLLPanel, staticEngineToolsPanel, true );
  744. // Install fog control panel UI
  745. CFogUIPanel::InstallFogUI( staticEngineToolsPanel );
  746. // Install texture view panel
  747. TxViewPanel::Install( staticEngineToolsPanel );
  748. /*
  749. COM_TimestampedLog( "Install bug reporter" );
  750. // Create and initialize bug reporting system
  751. bugreporter->InstallBugReportingUI( staticGameUIPanel, IEngineBugReporter::BR_AUTOSELECT );
  752. bugreporter->Init();
  753. */
  754. COM_TimestampedLog( "Install perf tools" );
  755. // Create a performance toolkit system
  756. perftools->InstallPerformanceToolsUI( staticEngineToolsPanel );
  757. perftools->Init();
  758. // Create a color correction UI
  759. colorcorrectiontools->InstallColorCorrectionUI( staticEngineToolsPanel );
  760. colorcorrectiontools->Init();
  761. }
  762. COM_TimestampedLog( "Building Panels (staticTransitionPanel)" );
  763. staticTransitionPanel = new CTransitionEffectPanel( staticPanel, "TransitionEffect" );
  764. staticTransitionPanel->SetZPos( 135 );
  765. if ( IsPS3() )
  766. {
  767. COM_TimestampedLog( "Building Panels (staticSteamOverlayPanel)" );
  768. staticSteamOverlayPanel = new CEnginePanel( staticPanel, "Steam Overlay" );
  769. staticSteamOverlayPanel->SetZPos( 140 );
  770. staticSteamOverlayPanel->SetKeyBoardInputEnabled( false );
  771. staticSteamOverlayPanel->SetMouseInputEnabled( false );
  772. }
  773. COM_TimestampedLog( "Building Panels (FocusOverlayPanel)" );
  774. // Make sure this is on top of everything
  775. staticFocusOverlayPanel = new CFocusOverlayPanel( staticPanel, "FocusOverlayPanel" );
  776. staticFocusOverlayPanel->SetBounds( 0, 0, videomode->GetModeWidth(), videomode->GetModeHeight() );
  777. staticFocusOverlayPanel->SetZPos( 150 );
  778. staticFocusOverlayPanel->MoveToFront();
  779. COM_TimestampedLog( "Building Panels (console, entity report, drawtree, texturelist, vprof)" );
  780. // Create engine vgui panels
  781. if ( IsPC() )
  782. {
  783. #ifdef IHV_DEMO
  784. // if ( GetSteamUniverse() == k_EUniversePublic ) // IHV_DEMO - we must remove this before we publicly release
  785. // {
  786. // CreateWatermarkPanel( staticEngineToolsPanel );
  787. // }
  788. #endif
  789. Con_CreateConsolePanel( staticEngineToolsPanel );
  790. CL_CreateEntityReportPanel( staticEngineToolsPanel );
  791. VGui_CreateDrawTreePanel( staticEngineToolsPanel );
  792. CL_CreateTextureListPanel( staticEngineToolsPanel );
  793. CreateVProfPanels( staticEngineToolsPanel );
  794. }
  795. #ifndef _CERT
  796. else if ( IsGameConsole() )
  797. {
  798. Con_CreateConsolePanel( staticEngineToolsPanel );
  799. CL_CreateEntityReportPanel( staticEngineToolsPanel );
  800. if ( IsX360() )
  801. {
  802. CreateVProfPanels( staticGameDLLPanel );
  803. }
  804. }
  805. #endif // !_CERT
  806. staticEngineToolsPanel->LoadControlSettings( "scripts/EngineVGuiLayout.res" );
  807. // Loading the .res will show some panels which really should stay hidden
  808. HideVProfPanels();
  809. COM_TimestampedLog( "materials->CacheUsedMaterials()" );
  810. // This material is used by CPotteryWheelPanel::Paint() to copy stencil to the render target's alpha. Not sure of the best place to put it, but this needs to be done sometime before the used materials are precached.
  811. m_pConstantColorMaterial = materials->FindMaterial( "dev/constant_color", TEXTURE_GROUP_OTHER, true );
  812. if ( m_pConstantColorMaterial )
  813. {
  814. m_pConstantColorMaterial->IncrementReferenceCount();
  815. }
  816. // Make sure that these materials are in the materials cache
  817. materials->CacheUsedMaterials();
  818. COM_TimestampedLog( "g_pVGuiLocalize->AddFile" );
  819. // load the base localization file
  820. g_pVGuiLocalize->AddFile( "Resource/valve_%language%.txt" );
  821. char szFileName[MAX_PATH];
  822. // We also want to load the localization file for the base game. Nomrally, all these values would already be in valve_language.txt, but
  823. // with CSGO we decided to move them into csgo_language (which is NOT a mod).
  824. Q_snprintf( szFileName, sizeof( szFileName ) - 1, "resource/%s_%%language%%.txt", GetCurrentGame() );
  825. szFileName[ sizeof( szFileName ) - 1 ] = '\0';
  826. g_pVGuiLocalize->AddFile( szFileName );
  827. // don't need to load the "valve" localization file twice
  828. // Each mod can have its own language.txt in addition to the valve_%%langauge%%.txt file under defaultgamedir.
  829. // load mod-specific localization file for kb_act.lst, user.scr, settings.scr, etc.
  830. Q_snprintf( szFileName, sizeof( szFileName ) - 1, "resource/%s_%%language%%.txt", GetCurrentMod() );
  831. szFileName[ sizeof( szFileName ) - 1 ] = '\0';
  832. g_pVGuiLocalize->AddFile( szFileName );
  833. // Load a low-violence-specific string file to override strings in the mod string file
  834. if ( g_bLowViolence )
  835. {
  836. Q_snprintf( szFileName, sizeof( szFileName ) - 1, "resource/%s_%%language%%_lv.txt", GetCurrentMod() );
  837. szFileName[ sizeof( szFileName ) - 1 ] = '\0';
  838. g_pVGuiLocalize->AddFile( szFileName );
  839. }
  840. COM_TimestampedLog( "staticGameUIFuncs->Initialize" );
  841. staticGameUIFuncs->Initialize( g_GameSystemFactory );
  842. COM_TimestampedLog( "staticGameUIFuncs->Start" );
  843. staticGameUIFuncs->Start();
  844. // setup console
  845. if ( staticGameConsole )
  846. {
  847. staticGameConsole->Initialize();
  848. #if defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  849. staticGameConsole->SetParent(staticEngineToolsPanel->GetVPanel());
  850. #elif !defined (CSTRIKE15)
  851. staticGameConsole->SetParent(staticGameUIPanel->GetVPanel());
  852. #endif
  853. }
  854. if ( IsGameConsole() )
  855. {
  856. // provide an interface for loader to send progress notifications
  857. g_pQueuedLoader->InstallProgress( &s_LoaderProgress );
  858. }
  859. // show the game UI
  860. COM_TimestampedLog( "ActivateGameUI()" );
  861. ActivateGameUI();
  862. if ( staticGameConsole &&
  863. !CommandLine()->CheckParm( "-forcestartupmenu" ) &&
  864. !CommandLine()->CheckParm( "-hideconsole" ) &&
  865. ( CommandLine()->FindParm( "-toconsole" ) || CommandLine()->FindParm( "-console" ) || CommandLine()->FindParm( "-rpt" ) || CommandLine()->FindParm( "-allowdebug" ) ) )
  866. {
  867. // activate the console
  868. staticGameConsole->Activate();
  869. }
  870. m_bNoShaderAPI = CommandLine()->FindParm( "-noshaderapi" ) ? true : false;
  871. }
  872. void CEngineVGui::PostInit()
  873. {
  874. staticGameUIFuncs->PostInit();
  875. #if defined( _GAMECONSOLE )
  876. g_pMatSystemSurface->ClearTemporaryFontCache();
  877. #endif
  878. }
  879. //-----------------------------------------------------------------------------
  880. // Purpose: connects interfaces in gameui
  881. //-----------------------------------------------------------------------------
  882. void CEngineVGui::Connect()
  883. {
  884. m_pInputInternal = (IInputInternal *)g_GameSystemFactory( VGUI_INPUTINTERNAL_INTERFACE_VERSION, NULL );
  885. staticGameUIFuncs->Connect( g_GameSystemFactory );
  886. #if OSX
  887. // g_pLauncherMgr = (ILauncherMgr *)g_GameSystemFactory( COCOAMGR_INTERFACE_VERSION, NULL );
  888. #endif
  889. #if LINUX
  890. // g_pLauncherMgr = (ILauncherMgr *)g_GameSystemFactory( LINUXMGR_INTERFACE_VERSION, NULL );
  891. #endif
  892. #if defined( _WIN32 ) && defined( DX_TO_GL_ABSTRACTION )
  893. // g_pLauncherMgr = (ILauncherMgr *)g_GameSystemFactory( WINMGR_INTERFACE_VERSION, NULL );
  894. #endif
  895. }
  896. //-----------------------------------------------------------------------------
  897. // Create/destroy the vprof panels
  898. //-----------------------------------------------------------------------------
  899. void CEngineVGui::CreateVProfPanels( Panel *pParent )
  900. {
  901. #ifdef _CERT
  902. if ( IsGameConsole() )
  903. return;
  904. #endif
  905. #ifdef VPROF_ENABLED
  906. m_pVProfPanel = new CVProfPanel( pParent, "VProfPanel" );
  907. m_pBudgetPanel = new CBudgetPanelEngine( pParent, "BudgetPanel" );
  908. CreateVProfGraphPanel( pParent );
  909. m_pTextureBudgetPanel = new CTextureBudgetPanel( pParent, "TextureBudgetPanel" );
  910. #endif
  911. }
  912. void CEngineVGui::HideVProfPanels()
  913. {
  914. #ifdef _CERT
  915. if ( IsGameConsole() )
  916. return;
  917. #endif
  918. #ifdef VPROF_ENABLED
  919. m_pVProfPanel->SetVisible( false );
  920. m_pBudgetPanel->SetVisible( false );
  921. HideVProfGraphPanel();
  922. m_pTextureBudgetPanel->SetVisible( false );
  923. #endif
  924. }
  925. void CEngineVGui::DestroyVProfPanels( )
  926. {
  927. #ifdef _CERT
  928. if ( IsGameConsole() )
  929. return;
  930. #endif
  931. #ifdef VPROF_ENABLED
  932. if ( m_pVProfPanel )
  933. {
  934. delete m_pVProfPanel;
  935. m_pVProfPanel = NULL;
  936. }
  937. if ( m_pBudgetPanel )
  938. {
  939. delete m_pBudgetPanel;
  940. m_pBudgetPanel = NULL;
  941. }
  942. DestroyVProfGraphPanel();
  943. if ( m_pTextureBudgetPanel )
  944. {
  945. delete m_pTextureBudgetPanel;
  946. m_pTextureBudgetPanel = NULL;
  947. }
  948. #endif
  949. }
  950. //-----------------------------------------------------------------------------
  951. // Are we initialized?
  952. //-----------------------------------------------------------------------------
  953. bool CEngineVGui::IsInitialized() const
  954. {
  955. return staticPanel != NULL;
  956. }
  957. extern bool g_bUsingLegacyAppSystems;
  958. //-----------------------------------------------------------------------------
  959. // Purpose: Called to Shutdown the game UI system
  960. //-----------------------------------------------------------------------------
  961. void CEngineVGui::Shutdown()
  962. {
  963. if ( m_pConstantColorMaterial )
  964. {
  965. m_pConstantColorMaterial->DecrementReferenceCount();
  966. m_pConstantColorMaterial = NULL;
  967. }
  968. if ( IsPC() && CL_IsHL2Demo() ) // if they are playing the demo then open the storefront on shutdown
  969. {
  970. system()->ShellExecute("open", "steam://store_demo/220");
  971. }
  972. if ( IsPC() && CL_IsPortalDemo() ) // if they are playing the demo then open the storefront on shutdown
  973. {
  974. vgui::system()->ShellExecute("open", "steam://store_demo/400");
  975. }
  976. DestroyVProfPanels();
  977. bugreporter->Shutdown();
  978. colorcorrectiontools->Shutdown();
  979. perftools->Shutdown();
  980. demoaction->Shutdown();
  981. if ( g_PluginManager )
  982. {
  983. g_PluginManager->Shutdown();
  984. }
  985. // 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
  986. // we'll leak this panel here instead!!!
  987. if ( g_bUsingLegacyAppSystems )
  988. {
  989. staticClientDLLPanel->SetParent( (VPANEL)0 );
  990. }
  991. if ( staticGameConsole )
  992. {
  993. staticGameConsole->Shutdown();
  994. staticGameConsole = NULL;
  995. }
  996. staticGameUIPanel = NULL;
  997. staticClientDLLToolsPanel = NULL;
  998. staticClientDLLPanel = NULL;
  999. staticEngineToolsPanel = NULL;
  1000. staticDebugSystemPanel = NULL;
  1001. staticSteamOverlayPanel = NULL;
  1002. staticFocusOverlayPanel = NULL;
  1003. staticGameDLLPanel = NULL;
  1004. // This will delete the engine subpanel since it's a child
  1005. delete staticPanel;
  1006. staticPanel = NULL;
  1007. // Give panels a chance to settle so things
  1008. // Marked for deletion will actually get deleted
  1009. {
  1010. FORCE_DEFAULT_SPLITSCREEN_PLAYER_GUARD;
  1011. ivgui()->RunFrame();
  1012. }
  1013. // unload the gameUI
  1014. staticGameUIFuncs->Shutdown();
  1015. staticGameUIFuncs = NULL;
  1016. // stop the App running
  1017. ivgui()->Stop();
  1018. // Disable the input contexts
  1019. if ( m_hGameUIInputContext != INPUT_CONTEXT_HANDLE_INVALID )
  1020. {
  1021. g_pMatSystemSurface->SetInputContext( INPUT_CONTEXT_HANDLE_INVALID );
  1022. g_pInputStackSystem->PopInputContext(); // VGui
  1023. g_pInputStackSystem->PopInputContext(); // GameUI
  1024. m_hGameUIInputContext = INPUT_CONTEXT_HANDLE_INVALID;
  1025. }
  1026. // unload the dll
  1027. if ( m_hStaticGameUIModule )
  1028. {
  1029. Sys_UnloadModule(m_hStaticGameUIModule);
  1030. }
  1031. m_hStaticGameUIModule = NULL;
  1032. m_GameUIFactory = NULL;
  1033. m_pInputInternal = NULL;
  1034. }
  1035. //-----------------------------------------------------------------------------
  1036. // Purpose: Retrieve specified root panel
  1037. //-----------------------------------------------------------------------------
  1038. inline Panel *CEngineVGui::GetRootPanel( VGuiPanel_t type )
  1039. {
  1040. if ( sv.IsDedicated() )
  1041. {
  1042. return NULL;
  1043. }
  1044. switch ( type )
  1045. {
  1046. default:
  1047. case PANEL_ROOT:
  1048. return staticPanel;
  1049. case PANEL_CLIENTDLL:
  1050. return staticClientDLLPanel;
  1051. case PANEL_GAMEUIDLL:
  1052. return staticGameUIPanel;
  1053. case PANEL_TOOLS:
  1054. return staticEngineToolsPanel;
  1055. case PANEL_GAMEDLL:
  1056. return staticGameDLLPanel;
  1057. case PANEL_CLIENTDLL_TOOLS:
  1058. return staticClientDLLToolsPanel;
  1059. case PANEL_GAMEUIBACKGROUND:
  1060. return staticGameUIBackgroundPanel;
  1061. case PANEL_TRANSITIONEFFECT:
  1062. return staticTransitionPanel;
  1063. case PANEL_STEAMOVERLAY:
  1064. return staticSteamOverlayPanel;
  1065. }
  1066. }
  1067. VPANEL CEngineVGui::GetPanel( VGuiPanel_t type )
  1068. {
  1069. return GetRootPanel( type )->GetVPanel();
  1070. }
  1071. //-----------------------------------------------------------------------------
  1072. // Purpose: Toggle engine panel active/inactive
  1073. //-----------------------------------------------------------------------------
  1074. void CEngineVGui::SetEngineVisible( bool state )
  1075. {
  1076. if ( staticClientDLLPanel )
  1077. {
  1078. staticClientDLLPanel->SetVisible( state );
  1079. }
  1080. }
  1081. //-----------------------------------------------------------------------------
  1082. // Should pause?
  1083. //-----------------------------------------------------------------------------
  1084. bool CEngineVGui::ShouldPause()
  1085. {
  1086. if ( IsPC() )
  1087. {
  1088. return bugreporter->ShouldPause() || perftools->ShouldPause();
  1089. }
  1090. return false;
  1091. }
  1092. //-----------------------------------------------------------------------------
  1093. // Purpose: Shows any GameUI related panels
  1094. //-----------------------------------------------------------------------------
  1095. void CEngineVGui::ActivateGameUI()
  1096. {
  1097. if ( m_bNotAllowedToShowGameUI )
  1098. return;
  1099. if (!staticGameUIFuncs)
  1100. return;
  1101. // clear any keys that might be stuck down
  1102. ClearIOStates();
  1103. staticGameUIPanel->SetVisible(true);
  1104. staticGameUIBackgroundPanel->SetVisible( true );
  1105. staticGameUIPanel->MoveToFront();
  1106. staticClientDLLPanel->SetVisible(false);
  1107. staticClientDLLPanel->SetMouseInputEnabled(false);
  1108. surface()->SetCursor( dc_arrow );
  1109. //staticGameDLLPanel->SetVisible( true );
  1110. //staticGameDLLPanel->SetMouseInputEnabled( true );
  1111. SetEngineVisible( false );
  1112. staticGameUIFuncs->OnGameUIActivated();
  1113. //Reapplying this hack so that the game doesn't pause when the player opens up the menu.
  1114. //This existed initially but was removed with the Portal 2 integration.
  1115. #if defined( CSTRIKE15 )
  1116. if ( sv.IsPlayingSoloAgainstBots() )
  1117. {
  1118. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "pause\n" );
  1119. }
  1120. #endif
  1121. }
  1122. //-----------------------------------------------------------------------------
  1123. // Purpose: Hides an Game UI related features (not client UI stuff tho!)
  1124. //-----------------------------------------------------------------------------
  1125. bool CEngineVGui::HideGameUI()
  1126. {
  1127. if ( m_bNotAllowedToHideGameUI )
  1128. return false;
  1129. if (!staticGameUIFuncs)
  1130. return false;
  1131. const char *levelName = engineClient->GetLevelName();
  1132. bool bInNonBgLevel = levelName && levelName[0] && !engineClient->IsLevelMainMenuBackground();
  1133. if ( bInNonBgLevel )
  1134. {
  1135. staticGameUIPanel->SetVisible(false);
  1136. staticGameUIBackgroundPanel->SetVisible( false );
  1137. #if !defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  1138. staticGameUIPanel->SetPaintBackgroundEnabled(false);
  1139. #endif
  1140. staticClientDLLPanel->SetVisible(true);
  1141. staticClientDLLPanel->MoveToFront();
  1142. staticClientDLLPanel->SetMouseInputEnabled(true);
  1143. //staticGameDLLPanel->SetVisible( false );
  1144. //staticGameDLLPanel->SetMouseInputEnabled(false);
  1145. SetEngineVisible( true );
  1146. staticGameUIFuncs->OnGameUIHidden();
  1147. }
  1148. #if defined (CSTRIKE15)
  1149. // Decouple the pause menu and console window: ensure we hide the console when the game UI is hidden (eg. when we hit ESC key)
  1150. HideConsole();
  1151. #endif // CSTRIKE15
  1152. // Tracker 18820: Pulling up options/console was perma-pausing the background levels, now we
  1153. // unpause them when you hit the Esc key even though the UI remains...
  1154. if ( levelName &&
  1155. levelName[0] &&
  1156. ( ( engineClient->GetMaxClients() <= 1 ) || sv.IsPlayingSoloAgainstBots() ) &&
  1157. engineClient->IsPaused() )
  1158. {
  1159. Cbuf_AddText(Cbuf_GetCurrentPlayer(), "unpause\n");
  1160. }
  1161. VGui_MoveDrawTreePanelToFront();
  1162. return true;
  1163. }
  1164. //-----------------------------------------------------------------------------
  1165. // Purpose: Hides the game console (but not the complete GameUI!)
  1166. //-----------------------------------------------------------------------------
  1167. void CEngineVGui::HideConsole()
  1168. {
  1169. if ( IsGameConsole() )
  1170. return;
  1171. if ( staticGameConsole )
  1172. {
  1173. staticGameConsole->Hide();
  1174. }
  1175. }
  1176. //-----------------------------------------------------------------------------
  1177. // Purpose: shows the console
  1178. //-----------------------------------------------------------------------------
  1179. void CEngineVGui::ShowConsole()
  1180. {
  1181. if ( IsGameConsole() )
  1182. return;
  1183. if ( staticGameConsole )
  1184. {
  1185. staticGameConsole->Activate();
  1186. }
  1187. }
  1188. //-----------------------------------------------------------------------------
  1189. // Purpose: returns true if the console is currently open
  1190. //-----------------------------------------------------------------------------
  1191. bool CEngineVGui::IsConsoleVisible()
  1192. {
  1193. if ( IsPC() )
  1194. {
  1195. return staticGameConsole && staticGameConsole->IsConsoleVisible();
  1196. }
  1197. else
  1198. {
  1199. // xbox has no drop down console
  1200. return false;
  1201. }
  1202. }
  1203. //-----------------------------------------------------------------------------
  1204. // Purpose: clears all text from the console
  1205. //-----------------------------------------------------------------------------
  1206. void CEngineVGui::ClearConsole()
  1207. {
  1208. if ( staticGameConsole )
  1209. {
  1210. staticGameConsole->Clear();
  1211. }
  1212. }
  1213. //-----------------------------------------------------------------------------
  1214. // Purpose: data accessor
  1215. //-----------------------------------------------------------------------------
  1216. bool CEngineVGui::IsGameUIVisible()
  1217. {
  1218. return staticGameUIPanel && staticGameUIPanel->IsVisible();
  1219. }
  1220. // list of progress bar strings
  1221. struct LoadingProgressDescription_t
  1222. {
  1223. LevelLoadingProgress_e eProgress; // current progress
  1224. int nPercent; // % of the total time this is at
  1225. int nRepeat; // number of times this is expected to repeat (usually 0)
  1226. const char *pszDesc; // user description of progress
  1227. };
  1228. LoadingProgressDescription_t g_ListenServerLoadingProgressDescriptions[] =
  1229. {
  1230. { PROGRESS_NONE, 0, 0, NULL },
  1231. { PROGRESS_SPAWNSERVER, 5, 0, "#LoadingProgress_SpawningServer" },
  1232. { PROGRESS_LOADWORLDMODEL, 8, 5, "#LoadingProgress_LoadMap" },
  1233. { PROGRESS_CREATENETWORKSTRINGTABLES, 12, 0, NULL },
  1234. { PROGRESS_PRECACHEWORLD, 15, 0, "#LoadingProgress_PrecacheWorld" },
  1235. { PROGRESS_CLEARWORLD, 16, 20, NULL },
  1236. { PROGRESS_LEVELINIT, 20, 200, "#LoadingProgress_LoadResources" },
  1237. { PROGRESS_ACTIVATESERVER, 50, 0, NULL },
  1238. { PROGRESS_SIGNONCHALLENGE, 51, 0, "#LoadingProgress_Connecting" },
  1239. { PROGRESS_SIGNONCONNECT, 55, 0, NULL },
  1240. { PROGRESS_SIGNONCONNECTED, 56, 1, "#LoadingProgress_SignonLocal" },
  1241. { PROGRESS_PROCESSSERVERINFO, 58, 0, NULL },
  1242. { PROGRESS_PROCESSSTRINGTABLE, 60, 3, NULL }, // 16
  1243. { PROGRESS_SIGNONNEW, 63, 200, NULL },
  1244. { PROGRESS_SENDCLIENTINFO, 80, 1, NULL },
  1245. { PROGRESS_SENDSIGNONDATA, 81, 1, "#LoadingProgress_SignonDataLocal" },
  1246. { PROGRESS_SIGNONSPAWN, 83, 10, NULL },
  1247. { PROGRESS_CREATEENTITIES, 85, 3, NULL },
  1248. { PROGRESS_FULLYCONNECTED, 86, 0, NULL },
  1249. { PROGRESS_PRECACHELIGHTING, 87, 50, NULL },
  1250. { PROGRESS_READYTOPLAY, 95, 100, NULL },
  1251. { PROGRESS_HIGHESTITEM, 100, 0, NULL },
  1252. };
  1253. LoadingProgressDescription_t g_RemoteConnectLoadingProgressDescriptions[] =
  1254. {
  1255. { PROGRESS_NONE, 0, 0, NULL },
  1256. { PROGRESS_CHANGELEVEL, 1, 0, "#LoadingProgress_Changelevel" },
  1257. { PROGRESS_BEGINCONNECT, 5, 0, "#LoadingProgress_BeginConnect" },
  1258. { PROGRESS_SIGNONCHALLENGE, 10, 0, "#LoadingProgress_Connecting" },
  1259. { PROGRESS_SIGNONCONNECTED, 11, 0, NULL },
  1260. { PROGRESS_PROCESSSERVERINFO, 12, 0, "#LoadingProgress_ProcessServerInfo" },
  1261. { PROGRESS_PROCESSSTRINGTABLE, 15, 3, NULL },
  1262. { PROGRESS_LOADWORLDMODEL, 20, 14, "#LoadingProgress_LoadMap" },
  1263. { PROGRESS_SIGNONNEW, 30, 200, "#LoadingProgress_PrecacheWorld" },
  1264. { PROGRESS_SENDCLIENTINFO, 60, 1, "#LoadingProgress_SendClientInfo" },
  1265. { PROGRESS_SENDSIGNONDATA, 64, 1, "#LoadingProgress_SignonData" },
  1266. { PROGRESS_SIGNONSPAWN, 65, 10, NULL },
  1267. { PROGRESS_CREATEENTITIES, 85, 3, NULL },
  1268. { PROGRESS_FULLYCONNECTED, 86, 0, NULL },
  1269. { PROGRESS_PRECACHELIGHTING, 87, 50, NULL },
  1270. { PROGRESS_READYTOPLAY, 95, 100, NULL },
  1271. { PROGRESS_HIGHESTITEM, 100, 0, NULL },
  1272. };
  1273. static LoadingProgressDescription_t *g_pLoadingProgressDescriptions = NULL;
  1274. //-----------------------------------------------------------------------------
  1275. // Purpose: returns current progress point description
  1276. //-----------------------------------------------------------------------------
  1277. LoadingProgressDescription_t &GetProgressDescription(LevelLoadingProgress_e eProgress)
  1278. {
  1279. // search for the item in the current list
  1280. int i = 0;
  1281. while ( true )
  1282. {
  1283. // find the closest match
  1284. if (g_pLoadingProgressDescriptions[i].eProgress >= eProgress)
  1285. return g_pLoadingProgressDescriptions[i];
  1286. if ( g_pLoadingProgressDescriptions[i].eProgress == PROGRESS_HIGHESTITEM )
  1287. break;
  1288. ++i;
  1289. }
  1290. // not found
  1291. return g_pLoadingProgressDescriptions[0];
  1292. }
  1293. //-----------------------------------------------------------------------------
  1294. // Purpose: transition handler
  1295. //-----------------------------------------------------------------------------
  1296. void CEngineVGui::OnLevelLoadingStarted( char const *levelName, bool bLocalServer )
  1297. {
  1298. if (!staticGameUIFuncs)
  1299. return;
  1300. ConVar *pSyncReportConVar = g_pCVar->FindVar( "fs_report_sync_opens" );
  1301. if ( pSyncReportConVar )
  1302. {
  1303. // If convar is set to 2, suppress warnings during level load
  1304. g_syncReportLevel = pSyncReportConVar->GetInt();
  1305. if ( g_syncReportLevel > 1 )
  1306. {
  1307. pSyncReportConVar->SetValue( 0 );
  1308. }
  1309. }
  1310. if ( IsGameConsole() || IsPC() )
  1311. {
  1312. // TCR requirement, always!!!
  1313. m_bShowProgressDialog = true;
  1314. }
  1315. // we've starting loading a level/connecting to a server
  1316. staticGameUIFuncs->OnLevelLoadingStarted( levelName, m_bShowProgressDialog );
  1317. // reset progress bar timers
  1318. m_flLoadingStartTime = Plat_FloatTime();
  1319. m_LoadingProgress.RemoveAll();
  1320. m_eLastProgressPoint = PROGRESS_NONE;
  1321. m_nLastProgressPointRepeatCount = 0;
  1322. m_ProgressBias = 0;
  1323. // choose which progress bar to use
  1324. if ( !bLocalServer )
  1325. {
  1326. // we're connecting
  1327. g_pLoadingProgressDescriptions = g_RemoteConnectLoadingProgressDescriptions;
  1328. }
  1329. else
  1330. {
  1331. g_pLoadingProgressDescriptions = g_ListenServerLoadingProgressDescriptions;
  1332. }
  1333. if ( m_bShowProgressDialog )
  1334. {
  1335. ActivateGameUI();
  1336. }
  1337. m_bShowProgressDialog = false;
  1338. }
  1339. void CEngineVGui::StartLoadingScreenForCommand( const char* command )
  1340. {
  1341. staticGameUIFuncs->StartLoadingScreenForCommand( command );
  1342. }
  1343. void CEngineVGui::StartLoadingScreenForKeyValues( KeyValues* keyValues )
  1344. {
  1345. staticGameUIFuncs->StartLoadingScreenForKeyValues( keyValues );
  1346. }
  1347. //-----------------------------------------------------------------------------
  1348. // Purpose: transition handler
  1349. //-----------------------------------------------------------------------------
  1350. void CEngineVGui::OnLevelLoadingFinished()
  1351. {
  1352. if (!staticGameUIFuncs)
  1353. return;
  1354. staticGameUIFuncs->OnLevelLoadingFinished( gfExtendedError, gszDisconnectReason, gszExtendedDisconnectReason );
  1355. m_eLastProgressPoint = PROGRESS_NONE;
  1356. // clear any error message
  1357. gfExtendedError = false;
  1358. gszDisconnectReason[0] = 0;
  1359. gszExtendedDisconnectReason[0] = 0;
  1360. #if defined(ENABLE_LOADING_PROGRESS_PROFILING)
  1361. // display progress bar stats (for debugging/tuning progress bar)
  1362. float flEndTime = (float)Plat_FloatTime();
  1363. // add a finished entry
  1364. LoadingProgressEntry_t &entry = m_LoadingProgress[m_LoadingProgress.AddToTail()];
  1365. entry.flTime = flEndTime - m_flLoadingStartTime;
  1366. entry.eProgress = PROGRESS_HIGHESTITEM;
  1367. // dump the info
  1368. Msg("Level load timings:\n");
  1369. float flTotalTime = flEndTime - m_flLoadingStartTime;
  1370. int nRepeatCount = 0;
  1371. float flTimeTaken = 0.0f;
  1372. float flFirstLoadProgressTime = 0.0f;
  1373. for (int i = 0; i < m_LoadingProgress.Count() - 1; i++)
  1374. {
  1375. // keep track of time
  1376. flTimeTaken += (float)m_LoadingProgress[i+1].flTime - m_LoadingProgress[i].flTime;
  1377. // keep track of how often something is repeated
  1378. if (m_LoadingProgress[i+1].eProgress == m_LoadingProgress[i].eProgress)
  1379. {
  1380. if (nRepeatCount == 0)
  1381. {
  1382. flFirstLoadProgressTime = m_LoadingProgress[i].flTime;
  1383. }
  1384. ++nRepeatCount;
  1385. continue;
  1386. }
  1387. // work out the time it took to do this
  1388. if (nRepeatCount == 0)
  1389. {
  1390. flFirstLoadProgressTime = m_LoadingProgress[i].flTime;
  1391. }
  1392. int nPerc = (int)(100 * (flFirstLoadProgressTime / flTotalTime));
  1393. int nTickPerc = (int)(100 * ((float)m_LoadingProgress[i].eProgress / (float)PROGRESS_HIGHESTITEM));
  1394. // interpolated percentage is in between the real times and the most ticks
  1395. int nInterpPerc = (nPerc + nTickPerc) / 2;
  1396. Msg("\t%2d/%50.50s\t%.3f\t\ttime: %d%%\t\tinterp: %d%%\t\trepeat: %d\n", m_LoadingProgress[i].eProgress, g_ProgressTokens->GetNameByToken( m_LoadingProgress[i].eProgress ), flTimeTaken, nPerc, nInterpPerc, nRepeatCount);
  1397. // reset accumlated vars
  1398. nRepeatCount = 0;
  1399. flTimeTaken = 0.0f;
  1400. }
  1401. #endif // ENABLE_LOADING_PROGRESS_PROFILING
  1402. // Restore convar setting after level load
  1403. if ( g_syncReportLevel > 1 )
  1404. {
  1405. ConVar *pSyncReportConVar = g_pCVar->FindVar( "fs_report_sync_opens" );
  1406. if ( pSyncReportConVar )
  1407. {
  1408. pSyncReportConVar->SetValue( g_syncReportLevel );
  1409. }
  1410. }
  1411. }
  1412. //-----------------------------------------------------------------------------
  1413. // Purpose: transition handler
  1414. //-----------------------------------------------------------------------------
  1415. void CEngineVGui::ShowErrorMessage()
  1416. {
  1417. if (!staticGameUIFuncs || !gfExtendedError)
  1418. return;
  1419. staticGameUIFuncs->OnLevelLoadingFinished( gfExtendedError, gszDisconnectReason, gszExtendedDisconnectReason );
  1420. m_eLastProgressPoint = PROGRESS_NONE;
  1421. // clear any error message
  1422. gfExtendedError = false;
  1423. gszDisconnectReason[0] = 0;
  1424. gszExtendedDisconnectReason[0] = 0;
  1425. HideGameUI();
  1426. }
  1427. //-----------------------------------------------------------------------------
  1428. // Purpose: Updates progress
  1429. //-----------------------------------------------------------------------------
  1430. #define LOADING_PRESENT_UPDATE_INTERVAL 0.05f
  1431. double g_flLastUpdateTime = 0.0f;
  1432. void CEngineVGui::UpdateProgressBar( LevelLoadingProgress_e progress, bool showDialog )
  1433. {
  1434. if (!staticGameUIFuncs)
  1435. return;
  1436. if ( !ThreadInMainThread() )
  1437. return;
  1438. // Don't update in tools mode; it renders the tools too, which takes forever!
  1439. if ( toolframework->InToolMode() )
  1440. return;
  1441. if (!g_pLoadingProgressDescriptions)
  1442. return;
  1443. // don't go backwards
  1444. if (progress < m_eLastProgressPoint)
  1445. return;
  1446. bool bNewCheckpoint = progress != m_eLastProgressPoint;
  1447. // Early time-based throttle for UpdateProgressBar
  1448. double t = Plat_FloatTime();
  1449. float dt = t - g_flLastUpdateTime;
  1450. if ( ( !bNewCheckpoint && ( dt < LOADING_PRESENT_UPDATE_INTERVAL ) ) ||
  1451. g_pMaterialSystem->IsInFrame() )
  1452. {
  1453. return;
  1454. }
  1455. #if defined(ENABLE_LOADING_PROGRESS_PROFILING)
  1456. if ( dt > 0.5f )
  1457. {
  1458. Msg( "%f msec gap in %s\n", 1000.0f * dt, g_ProgressTokens->GetNameByToken( progress ) );
  1459. }
  1460. // track the progress times, for debugging & tuning
  1461. LoadingProgressEntry_t &entry = m_LoadingProgress[m_LoadingProgress.AddToTail()];
  1462. entry.flTime = Plat_FloatTime() - m_flLoadingStartTime;
  1463. entry.eProgress = progress;
  1464. #endif
  1465. // count progress repeats
  1466. if ( !bNewCheckpoint )
  1467. {
  1468. ++m_nLastProgressPointRepeatCount;
  1469. #if defined(ENABLE_LOADING_PROGRESS_PROFILING)
  1470. //if ( !( m_nLastProgressPointRepeatCount % 500 ) )
  1471. {
  1472. Msg( "Repeating %s [%d] at %f\n", g_ProgressTokens->GetNameByToken( progress ), m_nLastProgressPointRepeatCount, t - m_flLoadingStartTime );
  1473. }
  1474. #endif
  1475. }
  1476. else
  1477. {
  1478. m_nLastProgressPointRepeatCount = 0;
  1479. #if defined(ENABLE_LOADING_PROGRESS_PROFILING)
  1480. Msg( "Entering %s at %f\n", g_ProgressTokens->GetNameByToken( progress ), t - m_flLoadingStartTime );
  1481. #endif
  1482. }
  1483. // construct a string describing it
  1484. LoadingProgressDescription_t &desc = GetProgressDescription(progress);
  1485. // calculate partial progress
  1486. float flPerc = desc.nPercent / 100.0f;
  1487. if ( desc.nRepeat > 1 && m_nLastProgressPointRepeatCount )
  1488. {
  1489. // cap the repeat count
  1490. m_nLastProgressPointRepeatCount = MIN(m_nLastProgressPointRepeatCount, desc.nRepeat);
  1491. // next progress point
  1492. float flNextPerc = GetProgressDescription((LevelLoadingProgress_e)((int)progress + 1)).nPercent / 100.0f;
  1493. // move along partially towards the next tick
  1494. flPerc += (flNextPerc - flPerc) * ((float)m_nLastProgressPointRepeatCount / desc.nRepeat);
  1495. }
  1496. // the bias allows the loading bar to have an optional reserved initial band
  1497. // isolated from the normal progress descriptions
  1498. flPerc = flPerc * ( 1.0f - m_ProgressBias ) + m_ProgressBias;
  1499. // Send loading progress to the server
  1500. GetBaseLocalClient().SendLoadingProgress( (int)(flPerc * 100) );
  1501. UpdateProgressBar( flPerc, desc.pszDesc, showDialog );
  1502. // Help with profiling load times.
  1503. ETWMarkPrintf( "UpdateProgressBar to %s, stage %d, took %1.3f s", desc.pszDesc, progress, Plat_FloatTime() - g_flLastUpdateTime );
  1504. m_eLastProgressPoint = progress;
  1505. // NOTE: It is necessary to re-read time, since Refresh
  1506. // may block, and if it does, it'll force a refresh every allocation
  1507. // if we don't resample time after the block
  1508. g_flLastUpdateTime = Plat_FloatTime();
  1509. }
  1510. //-----------------------------------------------------------------------------
  1511. // Purpose: Updates progress
  1512. //-----------------------------------------------------------------------------
  1513. void CEngineVGui::UpdateCustomProgressBar( float progress, const wchar_t *desc )
  1514. {
  1515. char ansi[1024];
  1516. g_pVGuiLocalize->ConvertUnicodeToANSI( desc, ansi, sizeof( ansi ) );
  1517. UpdateProgressBar( progress, ansi );
  1518. }
  1519. void CEngineVGui::StartCustomProgress()
  1520. {
  1521. if (!staticGameUIFuncs)
  1522. return;
  1523. // we've starting loading a level/connecting to a server
  1524. staticGameUIFuncs->OnLevelLoadingStarted( NULL, true );
  1525. m_bSaveProgress = staticGameUIFuncs->SetShowProgressText( true );
  1526. }
  1527. void CEngineVGui::FinishCustomProgress()
  1528. {
  1529. if (!staticGameUIFuncs)
  1530. return;
  1531. staticGameUIFuncs->SetShowProgressText( m_bSaveProgress );
  1532. staticGameUIFuncs->OnLevelLoadingFinished( false, "", "" );
  1533. }
  1534. void CEngineVGui::SetProgressBias( float bias )
  1535. {
  1536. m_ProgressBias = bias;
  1537. }
  1538. void CEngineVGui::UpdateProgressBar( float progress, const char *pDesc, bool showDialog )
  1539. {
  1540. if ( !staticGameUIFuncs )
  1541. return;
  1542. bool bUpdated = staticGameUIFuncs->UpdateProgressBar( progress, pDesc ? pDesc : "", showDialog );
  1543. if ( staticGameUIFuncs->LoadingProgressWantsIsolatedRender( false ) )
  1544. {
  1545. while ( staticGameUIFuncs->LoadingProgressWantsIsolatedRender( true ) )
  1546. {
  1547. extern void V_RenderVGuiOnly();
  1548. V_RenderVGuiOnly();
  1549. if ( g_ClientGlobalVariables.frametime != 0.0f && g_ClientGlobalVariables.frametime != 0.1f)
  1550. {
  1551. static ConVarRef host_timescale( "host_timescale" );
  1552. float timeScale = host_timescale.GetFloat() * sv.GetTimescale();
  1553. if ( timeScale <= 0.0f )
  1554. timeScale = 1.0f;
  1555. g_pScaleformUI->RunFrame( g_ClientGlobalVariables.frametime / timeScale );
  1556. }
  1557. else
  1558. {
  1559. break;
  1560. }
  1561. }
  1562. }
  1563. else if ( bUpdated )
  1564. {
  1565. g_pScaleformUI->RunFrame( 0 );
  1566. // re-render vgui on screen
  1567. extern void V_RenderVGuiOnly();
  1568. V_RenderVGuiOnly();
  1569. }
  1570. }
  1571. void CEngineVGui::UpdateSecondaryProgressBarWithFile( float progress, const char *pPath, int nBytesTotal )
  1572. {
  1573. if ( !pPath )
  1574. return;
  1575. char szFile[MAX_PATH];
  1576. V_strcpy_safe( szFile, pPath );
  1577. //V_StripFilename(szFile);
  1578. wchar_t wszPercent[ 10 ];
  1579. V_snwprintf( wszPercent, ARRAYSIZE( wszPercent ), L"%d%%", (int)(100*progress) );
  1580. wchar_t wszMegs[ 64 ];
  1581. char szBytes[32];
  1582. V_strcpy_safe( szBytes, V_pretifymem(nBytesTotal) );
  1583. V_strtowcs( szBytes, -1, wszMegs, ARRAYSIZE( wszMegs ) );
  1584. wchar_t wszFile[ MAX_PLAYER_NAME_LENGTH ];
  1585. g_pVGuiLocalize->ConvertANSIToUnicode( szFile, wszFile, sizeof( wszFile ) );
  1586. wchar_t szWideBuff[ 256 ];
  1587. g_pVGuiLocalize->ConstructString( szWideBuff, sizeof( szWideBuff ), g_pVGuiLocalize->Find( "#SFUI_DownLoading_" ), 3, wszFile, wszPercent, wszMegs );
  1588. UpdateSecondaryProgressBar( progress, szWideBuff );
  1589. }
  1590. void CEngineVGui::UpdateSecondaryProgressBar( float progress, const wchar_t *desc )
  1591. {
  1592. if ( !staticGameUIFuncs )
  1593. return;
  1594. bool bUpdated = staticGameUIFuncs->UpdateSecondaryProgressBar( progress, desc ? desc : L"" );
  1595. if ( staticGameUIFuncs->LoadingProgressWantsIsolatedRender( false ) )
  1596. {
  1597. while ( staticGameUIFuncs->LoadingProgressWantsIsolatedRender( true ) )
  1598. {
  1599. extern void V_RenderVGuiOnly();
  1600. V_RenderVGuiOnly();
  1601. if ( g_ClientGlobalVariables.frametime != 0.0f && g_ClientGlobalVariables.frametime != 0.1f)
  1602. {
  1603. static ConVarRef host_timescale( "host_timescale" );
  1604. float timeScale = host_timescale.GetFloat() * sv.GetTimescale();
  1605. if ( timeScale <= 0.0f )
  1606. timeScale = 1.0f;
  1607. g_pScaleformUI->RunFrame( g_ClientGlobalVariables.frametime / timeScale );
  1608. }
  1609. else
  1610. {
  1611. break;
  1612. }
  1613. }
  1614. }
  1615. else if ( bUpdated )
  1616. {
  1617. g_pScaleformUI->RunFrame( 0 );
  1618. // re-render vgui on screen
  1619. extern void V_RenderVGuiOnly();
  1620. V_RenderVGuiOnly();
  1621. }
  1622. }
  1623. //-----------------------------------------------------------------------------
  1624. // Purpose: Returns 1 if the key event is handled, 0 if the engine should handle it
  1625. //-----------------------------------------------------------------------------
  1626. void CEngineVGui::UpdateButtonState( const InputEvent_t &event )
  1627. {
  1628. m_pInputInternal->UpdateButtonState( event );
  1629. }
  1630. //-----------------------------------------------------------------------------
  1631. // Purpose: Returns 1 if the key event is handled, 0 if the engine should handle it
  1632. //-----------------------------------------------------------------------------
  1633. bool CEngineVGui::Key_Event( const InputEvent_t &event )
  1634. {
  1635. bool bDown = ( event.m_nType == IE_ButtonPressed ) || ( event.m_nType == IE_ButtonDoubleClicked );
  1636. ButtonCode_t code = (ButtonCode_t)event.m_nData;
  1637. if ( IsPC() && IsShiftKeyDown() )
  1638. {
  1639. switch( code )
  1640. {
  1641. case KEY_F1:
  1642. if ( bDown )
  1643. {
  1644. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "debugsystemui" );
  1645. }
  1646. return true;
  1647. case KEY_F2:
  1648. if ( bDown )
  1649. {
  1650. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "demoui" );
  1651. }
  1652. return true;
  1653. }
  1654. }
  1655. #if defined( _WIN32 )
  1656. // Ignore alt tilde, since the Japanese IME uses this to toggle itself on/off
  1657. if ( IsPC() && code == KEY_BACKQUOTE && ( IsAltKeyDown() || IsCtrlKeyDown() ) )
  1658. return event.m_nType != IE_ButtonReleased;
  1659. #endif
  1660. // ESCAPE toggles game ui
  1661. bool isConsole = IsX360() || IsPS3();
  1662. ButtonCode_t uiToggleKey = isConsole ? KEY_XBUTTON_START : KEY_ESCAPE;
  1663. ButtonCode_t baseButtonCode = GetBaseButtonCode( code );
  1664. // make sure PS3 supports the console default press (START) or ESCAPE
  1665. bool isUIToggleKey = ( baseButtonCode == uiToggleKey ) ||
  1666. ( IsPS3() && baseButtonCode == KEY_ESCAPE ) ;
  1667. // Hitting the Start button on any xbox controller brings up the game ui, so translate to base code space
  1668. if ( bDown && isUIToggleKey )
  1669. {
  1670. if ( IsPC() )
  1671. {
  1672. if ( cv_console_window_open.GetBool() )
  1673. {
  1674. HideConsole();
  1675. }
  1676. else if ( IsGameUIVisible() )
  1677. {
  1678. // gameui_hide on console start button but not ESC key.
  1679. if ( baseButtonCode != KEY_ESCAPE )
  1680. {
  1681. // Don't allow hiding of the game ui if there's no level
  1682. const char *pLevelName = engineClient->GetLevelName();
  1683. if ( pLevelName && pLevelName[0] )
  1684. {
  1685. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "gameui_hide" );
  1686. if ( IsDebugSystemVisible() )
  1687. {
  1688. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "debugsystemui 0" );
  1689. }
  1690. }
  1691. }
  1692. }
  1693. else if ( !cv_ignore_ui_activate_key.GetBool() )
  1694. {
  1695. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "gameui_activate" );
  1696. }
  1697. return true;
  1698. }
  1699. if ( IsGameConsole() && !IsGameUIVisible() )
  1700. {
  1701. // console UI does not toggle, engine does "show", but UI needs to handle "hide"
  1702. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "gameui_activate" );
  1703. return true;
  1704. }
  1705. }
  1706. if ( g_pMatSystemSurface && g_pMatSystemSurface->HandleInputEvent( event ) )
  1707. {
  1708. // always let the engine handle the console keys
  1709. // FIXME: Do a lookup of the key bound to toggleconsole
  1710. // want to cache it off so the lookup happens only when keys are bound?
  1711. if ( IsPC() && ( code == KEY_BACKQUOTE ) )
  1712. return false;
  1713. return event.m_nType != IE_ButtonReleased; // don't trap key up events
  1714. }
  1715. return false;
  1716. }
  1717. void CEngineVGui::Simulate()
  1718. {
  1719. if ( IsGameConsole() && r_drawvgui.GetInt() == 0 )
  1720. {
  1721. return;
  1722. }
  1723. toolframework->VGui_PreSimulateAllTools();
  1724. if ( staticPanel )
  1725. {
  1726. VPROF_BUDGET( "CEngineVGui::Simulate", "VGUI_Simulate" );
  1727. // update vgui animations
  1728. //!! currently this has to be done once per dll, because the anim controller object is in a lib;
  1729. //!! need to make it globally pumped (gameUI.dll has it's own version of this)
  1730. GetAnimationController()->UpdateAnimations( Sys_FloatTime() );
  1731. int w, h;
  1732. #if defined( USE_SDL ) || defined( OSX )
  1733. uint width,height;
  1734. g_pLauncherMgr->RenderedSize( width, height, false ); // false = get
  1735. w = width;
  1736. h = height;
  1737. #elif defined( WIN32 )
  1738. if ( ::IsIconic( *pmainwindow ) )
  1739. {
  1740. w = videomode->GetModeWidth();
  1741. h = videomode->GetModeHeight();
  1742. }
  1743. else
  1744. {
  1745. RECT rect;
  1746. ::GetClientRect(*pmainwindow, &rect);
  1747. w = rect.right;
  1748. h = rect.bottom;
  1749. }
  1750. #elif defined( _PS3 )
  1751. g_pMaterialSystem->GetBackBufferDimensions( w, h );
  1752. #else
  1753. #error
  1754. #endif
  1755. // don't hold this reference over RunFrame()
  1756. {
  1757. CMatRenderContextPtr pRenderContext( materials );
  1758. pRenderContext->Viewport( 0, 0, w, h );
  1759. }
  1760. staticGameUIFuncs->RunFrame();
  1761. surface()->CalculateMouseVisible();
  1762. {
  1763. FORCE_DEFAULT_SPLITSCREEN_PLAYER_GUARD;
  1764. ivgui()->RunFrame();
  1765. }
  1766. // Some debugging helpers
  1767. DrawMouseFocus();
  1768. DrawKeyFocus();
  1769. VGui_UpdateDrawTreePanel();
  1770. VGui_UpdateTextureListPanel();
  1771. VGui_ActivateMouse();
  1772. }
  1773. toolframework->VGui_PostSimulateAllTools();
  1774. }
  1775. void CEngineVGui::BackwardCompatibility_Paint()
  1776. {
  1777. Paint( (PaintMode_t)(PAINT_UIPANELS | PAINT_INGAMEPANELS) );
  1778. }
  1779. class CVGuiPaintHelper
  1780. {
  1781. public:
  1782. void AddUIPanel( VPANEL panel );
  1783. void Paint( VPANEL rootPanel, PaintMode_t mode );
  1784. private:
  1785. struct Entry_t
  1786. {
  1787. bool m_bWasVisible;
  1788. VPANEL m_pVPanel;
  1789. VPANEL m_Parent;
  1790. };
  1791. typedef void (CVGuiPaintHelper::*mapFunc)( Entry_t &entry );
  1792. void MapOverEntries( mapFunc mapper );
  1793. // Mapping functions
  1794. void MapHide( Entry_t &entry );
  1795. void MapRestore( Entry_t &entry );
  1796. void MapPaintTraverse( Entry_t &entry );
  1797. CUtlVector< Entry_t > m_Entries;
  1798. };
  1799. void CVGuiPaintHelper::AddUIPanel( VPANEL panel )
  1800. {
  1801. Entry_t e;
  1802. e.m_pVPanel = panel;
  1803. e.m_bWasVisible = ipanel()->IsVisible( panel );
  1804. e.m_Parent = ipanel()->GetParent( panel );
  1805. m_Entries.AddToTail( e );
  1806. }
  1807. void CVGuiPaintHelper::MapOverEntries( mapFunc mapper )
  1808. {
  1809. for ( int i = 0; i < m_Entries.Count(); ++i )
  1810. {
  1811. (this->*mapper)( m_Entries[ i ] );
  1812. }
  1813. }
  1814. void CVGuiPaintHelper::MapHide( Entry_t &entry )
  1815. {
  1816. ipanel()->SetVisible( entry.m_pVPanel, false );
  1817. }
  1818. void CVGuiPaintHelper::MapRestore( Entry_t &entry )
  1819. {
  1820. ipanel()->SetVisible( entry.m_pVPanel, entry.m_bWasVisible );
  1821. }
  1822. void CVGuiPaintHelper::MapPaintTraverse( Entry_t &entry )
  1823. {
  1824. ipanel()->SetParent( entry.m_pVPanel, 0 );
  1825. surface()->PaintTraverseEx( entry.m_pVPanel, true );
  1826. ipanel()->SetParent( entry.m_pVPanel, entry.m_Parent );
  1827. }
  1828. void CVGuiPaintHelper::Paint( VPANEL rootPanel, PaintMode_t mode )
  1829. {
  1830. if ( mode & PAINT_UIPANELS )
  1831. {
  1832. MapOverEntries( &CVGuiPaintHelper::MapHide );
  1833. surface()->PaintTraverseEx( rootPanel, true );
  1834. MapOverEntries( &CVGuiPaintHelper::MapRestore );
  1835. }
  1836. if ( mode & PAINT_INGAMEPANELS )
  1837. {
  1838. bool bSaveVisible = ipanel()->IsVisible( rootPanel );
  1839. ipanel()->SetVisible( rootPanel, false );
  1840. MapOverEntries( &CVGuiPaintHelper::MapPaintTraverse );
  1841. ipanel()->SetVisible( rootPanel, bSaveVisible );
  1842. }
  1843. }
  1844. //-----------------------------------------------------------------------------
  1845. // Purpose: paints all the vgui elements
  1846. //-----------------------------------------------------------------------------
  1847. void CEngineVGui::Paint( PaintMode_t mode )
  1848. {
  1849. VPROF_BUDGET( "CEngineVGui::Paint", VPROF_BUDGETGROUP_OTHER_VGUI );
  1850. if ( !staticPanel )
  1851. return;
  1852. // setup the base panel to cover the screen
  1853. VPANEL pVPanel = surface()->GetEmbeddedPanel();
  1854. if ( !pVPanel )
  1855. return;
  1856. bool drawVgui = IsGameConsole() ? ( r_drawvgui.GetInt() == 1 ) : r_drawvgui.GetBool();
  1857. // Don't draw the console at all if vgui is off during a time demo
  1858. if ( demoplayer->IsPlayingTimeDemo() && !drawVgui )
  1859. {
  1860. return;
  1861. }
  1862. if ( !drawVgui || m_bNoShaderAPI )
  1863. {
  1864. return;
  1865. }
  1866. int w, h;
  1867. #if defined( USE_SDL ) || defined ( OSX )
  1868. uint width,height;
  1869. g_pLauncherMgr->RenderedSize( width, height, false ); // false = get
  1870. w = width;
  1871. h = height;
  1872. #elif defined( WIN32 )
  1873. if ( ::IsIconic( *pmainwindow ) )
  1874. {
  1875. w = videomode->GetModeWidth();
  1876. h = videomode->GetModeHeight();
  1877. }
  1878. else
  1879. {
  1880. RECT rect;
  1881. ::GetClientRect(*pmainwindow, &rect);
  1882. w = rect.right;
  1883. h = rect.bottom;
  1884. }
  1885. #elif defined( _PS3 )
  1886. g_pMaterialSystem->GetBackBufferDimensions( w, h );
  1887. #else
  1888. #error
  1889. #endif
  1890. Panel *panel = staticPanel;
  1891. panel->SetBounds(0, 0, w, h);
  1892. panel->Repaint();
  1893. toolframework->VGui_PreRenderAllTools( mode );
  1894. // Paint both ( backward compatibility support )
  1895. CVGuiPaintHelper helper;
  1896. VPANEL fullscreenClientDLLPanel = ClientDLL_GetFullscreenClientDLLVPanel();
  1897. switch( mode )
  1898. {
  1899. case PAINT_UIPANELS:
  1900. {
  1901. // AddUIPanel excludes the 2 non-fullscreen panels from rendering in this pass
  1902. int childcount = ipanel()->GetChildCount( staticClientDLLPanel->GetVPanel() );
  1903. for ( int i = 0; i < childcount; i++ )
  1904. {
  1905. // child always returns null, not in the same module!
  1906. VPANEL child = ipanel()->GetChild( staticClientDLLPanel->GetVPanel(), i );
  1907. if ( child && child != fullscreenClientDLLPanel )
  1908. {
  1909. helper.AddUIPanel( child );
  1910. }
  1911. }
  1912. }
  1913. break;
  1914. case PAINT_INGAMEPANELS:
  1915. {
  1916. int childcount = ipanel()->GetChildCount( staticClientDLLPanel->GetVPanel() );
  1917. for ( int i = 0; i < childcount; i++ )
  1918. {
  1919. // child always returns null, not in the same module!
  1920. VPANEL child = ipanel()->GetChild( staticClientDLLPanel->GetVPanel(), i );
  1921. if ( child && child != fullscreenClientDLLPanel )
  1922. {
  1923. int iMessageContext = ipanel()->GetMessageContextId( child );
  1924. if ( iMessageContext == splitscreen->GetActiveSplitScreenPlayerSlot() )
  1925. {
  1926. helper.AddUIPanel( child );
  1927. }
  1928. }
  1929. }
  1930. }
  1931. break;
  1932. default:
  1933. break;
  1934. }
  1935. #if defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  1936. helper.AddUIPanel( staticGameUIPanel->GetVPanel() );
  1937. #endif
  1938. helper.AddUIPanel( staticClientDLLToolsPanel->GetVPanel() );
  1939. // Prevent Steam Overlay from rendering prematurely
  1940. if ( staticSteamOverlayPanel )
  1941. {
  1942. ipanel()->SetVisible( staticSteamOverlayPanel->GetVPanel(), false );
  1943. }
  1944. if ( staticTransitionPanel )
  1945. {
  1946. ipanel()->SetVisible( staticTransitionPanel->GetVPanel(), false );
  1947. }
  1948. // It's either the full screen, or just the client .dll stuff
  1949. helper.Paint( pVPanel, mode );
  1950. if ( staticTransitionPanel && ( mode & PAINT_UIPANELS ) && staticTransitionPanel->IsEffectEnabled() )
  1951. {
  1952. ipanel()->SetVisible( staticTransitionPanel->GetVPanel(), true );
  1953. VPANEL vPanelRememberParent = ipanel()->GetParent( staticTransitionPanel->GetVPanel() );
  1954. ipanel()->SetParent( staticTransitionPanel->GetVPanel(), 0 );
  1955. surface()->PaintTraverseEx( staticTransitionPanel->GetVPanel(), false );
  1956. ipanel()->SetParent( staticTransitionPanel->GetVPanel(), vPanelRememberParent );
  1957. }
  1958. // Paint Steam Overlay
  1959. if ( staticSteamOverlayPanel && ( mode & PAINT_UIPANELS ) )
  1960. {
  1961. ipanel()->SetVisible( staticSteamOverlayPanel->GetVPanel(), true );
  1962. VPANEL vPanelRememberParent = ipanel()->GetParent( staticSteamOverlayPanel->GetVPanel() );
  1963. ipanel()->SetParent( staticSteamOverlayPanel->GetVPanel(), 0 );
  1964. surface()->PaintTraverseEx( staticSteamOverlayPanel->GetVPanel(), false );
  1965. ipanel()->SetParent( staticSteamOverlayPanel->GetVPanel(), vPanelRememberParent );
  1966. }
  1967. toolframework->VGui_PostRenderAllTools( mode );
  1968. }
  1969. bool CEngineVGui::IsDebugSystemVisible( void )
  1970. {
  1971. return staticDebugSystemPanel ? staticDebugSystemPanel->IsVisible() : false;
  1972. }
  1973. void CEngineVGui::HideDebugSystem( void )
  1974. {
  1975. if ( staticDebugSystemPanel )
  1976. {
  1977. staticDebugSystemPanel->SetVisible( false );
  1978. SetEngineVisible( true );
  1979. }
  1980. }
  1981. void CEngineVGui::ToggleDebugSystemUI( const CCommand &args )
  1982. {
  1983. if ( !staticDebugSystemPanel )
  1984. return;
  1985. bool bVisible;
  1986. if ( args.ArgC() == 1 )
  1987. {
  1988. // toggle the game UI
  1989. bVisible = !IsDebugSystemVisible();
  1990. }
  1991. else
  1992. {
  1993. bVisible = atoi( args[1] ) != 0;
  1994. }
  1995. if ( !bVisible )
  1996. {
  1997. staticDebugSystemPanel->SetVisible( false );
  1998. SetEngineVisible( true );
  1999. }
  2000. else
  2001. {
  2002. // clear any keys that might be stuck down
  2003. ClearIOStates();
  2004. staticDebugSystemPanel->SetVisible( true );
  2005. SetEngineVisible( false );
  2006. }
  2007. }
  2008. bool CEngineVGui::IsShiftKeyDown( void )
  2009. {
  2010. if ( !input() )
  2011. return false;
  2012. return input()->IsKeyDown( KEY_LSHIFT ) || input()->IsKeyDown( KEY_RSHIFT );
  2013. }
  2014. bool CEngineVGui::IsAltKeyDown( void )
  2015. {
  2016. if ( !input() )
  2017. return false;
  2018. return input()->IsKeyDown( KEY_LALT ) || input()->IsKeyDown( KEY_RALT );
  2019. }
  2020. bool CEngineVGui::IsCtrlKeyDown( void )
  2021. {
  2022. if ( !input() )
  2023. return false;
  2024. return input()->IsKeyDown( KEY_LCONTROL ) || input()->IsKeyDown( KEY_RCONTROL );
  2025. }
  2026. //-----------------------------------------------------------------------------
  2027. // Purpose: notification
  2028. //-----------------------------------------------------------------------------
  2029. void CEngineVGui::NotifyOfServerConnect(const char *game, int IP, int connectionPort, int queryPort)
  2030. {
  2031. if (!staticGameUIFuncs)
  2032. return;
  2033. staticGameUIFuncs->OnConnectToServer2(game, IP, connectionPort, queryPort);
  2034. }
  2035. //-----------------------------------------------------------------------------
  2036. // Purpose: notification
  2037. //-----------------------------------------------------------------------------
  2038. void CEngineVGui::NotifyOfServerDisconnect()
  2039. {
  2040. if (!staticGameUIFuncs)
  2041. return;
  2042. staticGameUIFuncs->OnDisconnectFromServer( g_eSteamLoginFailure );
  2043. g_eSteamLoginFailure = 0;
  2044. }
  2045. //-----------------------------------------------------------------------------
  2046. // A helper to play sounds through vgui
  2047. //-----------------------------------------------------------------------------
  2048. void VGui_PlaySound( const char *pFileName )
  2049. {
  2050. //Put '+' on the front of sounds to make them play without spatialization.
  2051. char buf[2048];
  2052. Q_snprintf( buf, sizeof( buf ), "%c%s", '+', pFileName );
  2053. // Point at origin if they didn't specify a sound source.
  2054. Vector vDummyOrigin;
  2055. vDummyOrigin.Init();
  2056. CSfxTable *pSound = (CSfxTable*)S_PrecacheSound( buf );
  2057. if ( pSound )
  2058. {
  2059. S_MarkUISound( pSound );
  2060. ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 );
  2061. StartSoundParams_t params;
  2062. params.staticsound = IsGameConsole() ? true : false;
  2063. params.soundsource = GetLocalClient().GetViewEntity();
  2064. params.entchannel = CHAN_AUTO;
  2065. params.pSfx = pSound;
  2066. params.origin = vDummyOrigin;
  2067. params.pitch = PITCH_NORM;
  2068. params.soundlevel = SNDLVL_IDLE;
  2069. params.flags = 0;
  2070. params.fvol = 1.0f;
  2071. S_StartSound( params );
  2072. }
  2073. }
  2074. //-----------------------------------------------------------------------------
  2075. // Purpose:
  2076. //-----------------------------------------------------------------------------
  2077. void VGui_ActivateMouse()
  2078. {
  2079. if ( !g_ClientDLL )
  2080. return;
  2081. // Don't mess with mouse if not active
  2082. if ( !game->IsActiveApp() )
  2083. {
  2084. g_ClientDLL->IN_DeactivateMouse ();
  2085. return;
  2086. }
  2087. /*
  2088. //
  2089. // MIKE AND ALFRED: these panels should expose whether they want mouse input or not and
  2090. // CalculateMouseVisible will take them into account.
  2091. //
  2092. // If showing game ui, make sure nothing else is hooking it
  2093. if ( Base().IsGameUIVisible() || Base().IsDebugSystemVisible() )
  2094. {
  2095. g_ClientDLL->IN_DeactivateMouse();
  2096. return;
  2097. }
  2098. */
  2099. if ( surface()->IsCursorLocked() && !g_bTextMode )
  2100. {
  2101. g_ClientDLL->IN_ActivateMouse ();
  2102. }
  2103. else
  2104. {
  2105. g_ClientDLL->IN_DeactivateMouse ();
  2106. }
  2107. }
  2108. static ConVar mat_drawTitleSafe( "mat_drawTitleSafe", "0", 0, "Enable title safe overlay" );
  2109. CUtlVector< VPANEL > g_FocusPanelList;
  2110. ConVar vgui_drawfocus( "vgui_drawfocus", "0", 0, "Report which panel is under the mouse." );
  2111. VPANEL g_KeyFocusPanel = NULL;
  2112. ConVar vgui_drawkeyfocus( "vgui_drawkeyfocus", "0", 0, "Report which panel has keyboard focus." );
  2113. CFocusOverlayPanel::CFocusOverlayPanel( Panel *pParent, const char *pName ) : Panel( pParent, pName )
  2114. {
  2115. SetPaintEnabled( false );
  2116. SetPaintBorderEnabled( false );
  2117. SetPaintBackgroundEnabled( false );
  2118. MakePopup();
  2119. SetPostChildPaintEnabled( true );
  2120. SetKeyBoardInputEnabled( false );
  2121. SetMouseInputEnabled( false );
  2122. }
  2123. bool CFocusOverlayPanel::DrawTitleSafeOverlay( void )
  2124. {
  2125. if ( !mat_drawTitleSafe.GetBool() )
  2126. return false;
  2127. int backBufferWidth, backBufferHeight;
  2128. materials->GetBackBufferDimensions( backBufferWidth, backBufferHeight );
  2129. int x, y, x1, y1, insetX, insetY;
  2130. if ( IsX360() || !IsPS3() )
  2131. {
  2132. // Required Xbox360 Title safe is TCR documented at inner 90% (RED)
  2133. insetX = 0.05f * backBufferWidth;
  2134. insetY = 0.05f * backBufferHeight;
  2135. x = insetX;
  2136. y = insetY;
  2137. x1 = backBufferWidth - insetX;
  2138. y1 = backBufferHeight - insetY;
  2139. vgui::surface()->DrawSetColor( 255, 0, 0, 255 );
  2140. vgui::surface()->DrawOutlinedRect( x, y, x1, y1 );
  2141. // Suggested Xbox360 Title Safe is TCR documented at inner 85% (YELLOW)
  2142. insetX = 0.075f * backBufferWidth;
  2143. insetY = 0.075f * backBufferHeight;
  2144. x = insetX;
  2145. y = insetY;
  2146. x1 = backBufferWidth - insetX;
  2147. y1 = backBufferHeight - insetY;
  2148. vgui::surface()->DrawSetColor( 255, 255, 0, 255 );
  2149. vgui::surface()->DrawOutlinedRect( x, y, x1, y1 );
  2150. }
  2151. else if ( IsPS3() )
  2152. {
  2153. // Required PS3 Title Safe is TCR documented at inner 85% (RED)
  2154. insetX = 0.075f * backBufferWidth;
  2155. insetY = 0.075f * backBufferHeight;
  2156. x = insetX;
  2157. y = insetY;
  2158. x1 = backBufferWidth - insetX;
  2159. y1 = backBufferHeight - insetY;
  2160. vgui::surface()->DrawSetColor( 255, 0, 0, 255 );
  2161. vgui::surface()->DrawOutlinedRect( x, y, x1, y1 );
  2162. }
  2163. return true;
  2164. }
  2165. void CFocusOverlayPanel::PostChildPaint( void )
  2166. {
  2167. BaseClass::PostChildPaint();
  2168. bool bNeedsMoveToFront = false;
  2169. if ( g_DrawTreeSelectedPanel )
  2170. {
  2171. int x, y, x1, y1;
  2172. ipanel()->GetClipRect( g_DrawTreeSelectedPanel, x, y, x1, y1 );
  2173. surface()->DrawSetColor( Color( 255, 0, 0, 255 ) );
  2174. surface()->DrawOutlinedRect( x, y, x1, y1 );
  2175. bNeedsMoveToFront = true;
  2176. }
  2177. if ( DrawTitleSafeOverlay() )
  2178. {
  2179. bNeedsMoveToFront = true;
  2180. }
  2181. if ( DrawFocusPanelList() )
  2182. {
  2183. bNeedsMoveToFront = true;
  2184. }
  2185. if ( DrawKeyFocusPanel() )
  2186. {
  2187. bNeedsMoveToFront = true;
  2188. }
  2189. if ( bNeedsMoveToFront )
  2190. {
  2191. // will be valid for the next frame
  2192. MoveToFront();
  2193. }
  2194. }
  2195. bool CFocusOverlayPanel::DrawKeyFocusPanel( void )
  2196. {
  2197. if( !vgui_drawkeyfocus.GetBool() )
  2198. return false;
  2199. if ( g_KeyFocusPanel )
  2200. {
  2201. int x, y, x1, y1;
  2202. ipanel()->GetClipRect( g_KeyFocusPanel, x, y, x1, y1 );
  2203. if ( (x1 - x) == videomode->GetModeWidth() &&
  2204. (y1 - y) == videomode->GetModeHeight() )
  2205. {
  2206. x++;
  2207. y++;
  2208. x1--;
  2209. y1--;
  2210. }
  2211. const int FOCUS_BLINK_PERIOD = 500;
  2212. if ( system()->GetTimeMillis() % FOCUS_BLINK_PERIOD > FOCUS_BLINK_PERIOD/2 )
  2213. {
  2214. surface()->DrawSetColor( Color( 0, 0, 0, 255 ) );
  2215. }
  2216. else
  2217. {
  2218. surface()->DrawSetColor( Color( 255, 255, 255, 255 ) );
  2219. }
  2220. surface()->DrawOutlinedRect( x, y, x1, y1 );
  2221. }
  2222. return true;
  2223. }
  2224. bool CFocusOverlayPanel::DrawFocusPanelList( void )
  2225. {
  2226. if( !vgui_drawfocus.GetBool() )
  2227. return false;
  2228. int c = g_FocusPanelList.Count();
  2229. if ( c <= 0 )
  2230. return false;
  2231. int slot = 0;
  2232. int fullscreeninset = 0;
  2233. for ( int i = 0; i < c; i++ )
  2234. {
  2235. if ( slot > 31 )
  2236. break;
  2237. VPANEL vpanel = g_FocusPanelList[ i ];
  2238. if ( !vpanel )
  2239. continue;
  2240. if ( !ipanel()->IsFullyVisible( vpanel ) )
  2241. return false;
  2242. // Convert panel bounds to screen space
  2243. int r, g, b;
  2244. GetColorForSlot( slot, r, g, b );
  2245. int x, y, x1, y1;
  2246. ipanel()->GetClipRect( vpanel, x, y, x1, y1 );
  2247. if ( (x1 - x) == videomode->GetModeWidth() &&
  2248. (y1 - y) == videomode->GetModeHeight() )
  2249. {
  2250. x += fullscreeninset;
  2251. y += fullscreeninset;
  2252. x1 -= fullscreeninset;
  2253. y1 -= fullscreeninset;
  2254. fullscreeninset++;
  2255. }
  2256. surface()->DrawSetColor( Color( r, g, b, 255 ) );
  2257. surface()->DrawOutlinedRect( x, y, x1, y1 );
  2258. slot++;
  2259. }
  2260. return true;
  2261. }
  2262. static void VGui_RecursiveFindPanels( CUtlVector< VPANEL >& panelList, VPANEL check, char const *panelname )
  2263. {
  2264. Panel *panel = ipanel()->GetPanel( check, "ENGINE" );
  2265. if ( !panel )
  2266. return;
  2267. if ( StringHasPrefixCaseSensitive( panel->GetName(), panelname ) )
  2268. {
  2269. panelList.AddToTail( panel->GetVPanel() );
  2270. }
  2271. int childcount = panel->GetChildCount();
  2272. for ( int i = 0; i < childcount; i++ )
  2273. {
  2274. Panel *child = panel->GetChild( i );
  2275. VGui_RecursiveFindPanels( panelList, child->GetVPanel(), panelname );
  2276. }
  2277. }
  2278. void VGui_FindNamedPanels( CUtlVector< VPANEL >& panelList, char const *panelname )
  2279. {
  2280. VPANEL embedded = surface()->GetEmbeddedPanel();
  2281. // faster version of code below
  2282. // checks through each popup in order, top to bottom windows
  2283. int c = surface()->GetPopupCount();
  2284. for (int i = c - 1; i >= 0; i--)
  2285. {
  2286. VPANEL popup = surface()->GetPopup(i);
  2287. if ( !popup )
  2288. continue;
  2289. if ( embedded == popup )
  2290. continue;
  2291. VGui_RecursiveFindPanels( panelList, popup, panelname );
  2292. }
  2293. VGui_RecursiveFindPanels( panelList, embedded, panelname );
  2294. }
  2295. CON_COMMAND( vgui_togglepanel, "show/hide vgui panel by name." )
  2296. {
  2297. if ( args.ArgC() < 2 )
  2298. {
  2299. ConMsg( "Usage: vgui_showpanel panelname\n" );
  2300. return;
  2301. }
  2302. bool flip = false;
  2303. bool fg = true;
  2304. bool bg = true;
  2305. if ( args.ArgC() == 5 )
  2306. {
  2307. flip = atoi( args[ 2 ] ) ? true : false;
  2308. fg = atoi( args[ 3 ] ) ? true : false;
  2309. bg = atoi( args[ 4 ] ) ? true : false;
  2310. }
  2311. char const *panelname = args[ 1 ];
  2312. if ( !panelname || !panelname[ 0 ] )
  2313. return;
  2314. CUtlVector< VPANEL > panelList;
  2315. VGui_FindNamedPanels( panelList, panelname );
  2316. if ( !panelList.Count() )
  2317. {
  2318. ConMsg( "No panels starting with %s\n", panelname );
  2319. return;
  2320. }
  2321. for ( int i = 0; i < panelList.Count(); i++ )
  2322. {
  2323. VPANEL p = panelList[ i ];
  2324. if ( !p )
  2325. continue;
  2326. Panel *panel = ipanel()->GetPanel( p, "ENGINE");
  2327. if ( !panel )
  2328. continue;
  2329. Msg( "Toggling %s\n", panel->GetName() );
  2330. if ( fg )
  2331. {
  2332. panel->SetPaintEnabled( flip );
  2333. }
  2334. if ( bg )
  2335. {
  2336. panel->SetPaintBackgroundEnabled( flip );
  2337. }
  2338. }
  2339. }
  2340. static void VGui_RecursePanel( CUtlVector< VPANEL >& panelList, int x, int y, VPANEL check, bool include_hidden )
  2341. {
  2342. if( !include_hidden && !ipanel()->IsVisible( check ) )
  2343. {
  2344. return;
  2345. }
  2346. if ( ipanel()->IsWithinTraverse( check, x, y, false ) )
  2347. {
  2348. if ( panelList.Find( check ) == panelList.InvalidIndex() )
  2349. panelList.AddToTail( check );
  2350. }
  2351. int childcount = ipanel()->GetChildCount( check );
  2352. for ( int i = 0; i < childcount; i++ )
  2353. {
  2354. VPANEL child = ipanel()->GetChild( check, i );
  2355. VGui_RecursePanel( panelList, x, y, child, include_hidden );
  2356. }
  2357. }
  2358. void CEngineVGui::DrawKeyFocus( void )
  2359. {
  2360. VPROF( "CEngineVGui::DrawKeyFocus" );
  2361. if ( !vgui_drawkeyfocus.GetBool() )
  2362. return;
  2363. staticFocusOverlayPanel->MoveToFront();
  2364. g_KeyFocusPanel = input()->GetFocus();
  2365. }
  2366. void CEngineVGui::DrawMouseFocus( void )
  2367. {
  2368. VPROF( "CEngineVGui::DrawMouseFocus" );
  2369. g_FocusPanelList.RemoveAll();
  2370. if ( !vgui_drawfocus.GetBool() )
  2371. return;
  2372. staticFocusOverlayPanel->MoveToFront();
  2373. bool include_hidden = vgui_drawfocus.GetInt() == 2;
  2374. int x, y;
  2375. input()->GetCursorPos( x, y );
  2376. VPANEL embedded = surface()->GetEmbeddedPanel();
  2377. if ( surface()->IsCursorVisible() && surface()->IsWithin(x, y) )
  2378. {
  2379. // faster version of code below
  2380. // checks through each popup in order, top to bottom windows
  2381. int c = surface()->GetPopupCount();
  2382. for (int i = c - 1; i >= 0; i--)
  2383. {
  2384. VPANEL popup = surface()->GetPopup(i);
  2385. if ( !popup )
  2386. continue;
  2387. if ( popup == embedded )
  2388. continue;
  2389. if ( !ipanel()->IsVisible( popup ) )
  2390. continue;
  2391. VGui_RecursePanel( g_FocusPanelList, x, y, popup, include_hidden );
  2392. }
  2393. VGui_RecursePanel( g_FocusPanelList, x, y, embedded, include_hidden );
  2394. }
  2395. // Now draw them
  2396. con_nprint_t np;
  2397. np.time_to_live = 1.0f;
  2398. int c = g_FocusPanelList.Count();
  2399. int slot = 0;
  2400. for ( int i = 0; i < c; i++ )
  2401. {
  2402. if ( slot > 31 )
  2403. break;
  2404. VPANEL vpanel = g_FocusPanelList[ i ];
  2405. if ( !vpanel )
  2406. continue;
  2407. np.index = slot;
  2408. int r, g, b;
  2409. CFocusOverlayPanel::GetColorForSlot( slot, r, g, b );
  2410. np.color[ 0 ] = r / 255.0f;
  2411. np.color[ 1 ] = g / 255.0f;
  2412. np.color[ 2 ] = b / 255.0f;
  2413. bool bThisOne = false;
  2414. if ( input()->GetMouseFocus() == vpanel )
  2415. {
  2416. bThisOne = true;
  2417. }
  2418. Con_NXPrintf( &np, "%s %3i: %s(vpanel%d)(ctx%d)\n", bThisOne ? "-->" : " ", slot + 1, ipanel()->GetName(vpanel), vpanel, ipanel()->GetMessageContextId( vpanel ) );
  2419. slot++;
  2420. }
  2421. while ( slot <= 31 )
  2422. {
  2423. Con_NPrintf( slot, "" );
  2424. slot++;
  2425. }
  2426. }
  2427. void VGui_SetGameDLLPanelsVisible( bool show )
  2428. {
  2429. EngineVGui()->SetGameDLLPanelsVisible( show );
  2430. }
  2431. void CEngineVGui::SetProgressLevelName( const char *levelName )
  2432. {
  2433. // staticGameUIFuncs->SetProgressLevelName( levelName );
  2434. }
  2435. void CEngineVGui::OnToolModeChanged( bool bGameMode )
  2436. {
  2437. //#if defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  2438. staticEngineToolsPanel->SetParent( bGameMode ? staticPanel->GetVPanel() : staticGameDLLPanel->GetVPanel() );
  2439. staticEngineToolsPanel->SetMouseInputEnabled( false );
  2440. staticEngineToolsPanel->SetKeyBoardInputEnabled( false );
  2441. //#endif
  2442. }
  2443. void CEngineVGui::NeedConnectionProblemWaitScreen()
  2444. {
  2445. return staticGameUIFuncs->NeedConnectionProblemWaitScreen();
  2446. }
  2447. void CEngineVGui::ShowPasswordUI( char const *pchCurrentPW )
  2448. {
  2449. // staticGameUIFuncs->ShowPasswordUI( pchCurrentPW );
  2450. }
  2451. bool CEngineVGui::IsPlayingFullScreenVideo()
  2452. {
  2453. return staticGameUIFuncs->IsPlayingFullScreenVideo();
  2454. }
  2455. //-----------------------------------------------------------------------------
  2456. // Dump the panel hierarchy
  2457. //-----------------------------------------------------------------------------
  2458. void DumpPanels_r( VPANEL panel, int level, bool bVisibleOnly )
  2459. {
  2460. int i;
  2461. const char *pName = ipanel()->GetName( panel );
  2462. bool bVisible = ipanel()->IsVisible( panel );
  2463. if ( bVisibleOnly && !bVisible )
  2464. {
  2465. // cull
  2466. return;
  2467. }
  2468. char indentBuff[32];
  2469. for ( i = 0; i < level; i++ )
  2470. {
  2471. indentBuff[i] = '.';
  2472. }
  2473. indentBuff[i] = '\0';
  2474. ConMsg( "%s%s%s\n", indentBuff, pName[0] ? pName : "???", bVisible ? " (Visible)" : " (Not Visible)" );
  2475. int childcount = ipanel()->GetChildCount( panel );
  2476. for ( i = 0; i < childcount; i++ )
  2477. {
  2478. VPANEL child = ipanel()->GetChild( panel, i );
  2479. DumpPanels_r( child, level+1, bVisibleOnly );
  2480. }
  2481. }
  2482. CON_COMMAND( vgui_dump_panels, "vgui_dump_panels [visible]" )
  2483. {
  2484. bool bVisibleOnly = ( args.ArgC() == 2 ) && ( !V_stricmp( args[1], "visible" ) );
  2485. VPANEL embedded = surface()->GetEmbeddedPanel();
  2486. DumpPanels_r( embedded, 0, bVisibleOnly );
  2487. }