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.

1069 lines
32 KiB

  1. //===== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Implements all the functions exported by the GameUI dll
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #if defined( _WIN32 ) && !defined( _X360 )
  8. #include <windows.h>
  9. #endif
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <stdio.h>
  13. #if defined( WIN32 )
  14. #include <io.h>
  15. #include <direct.h>
  16. #endif
  17. #include <tier0/dbg.h>
  18. #ifdef SendMessage
  19. #undef SendMessage
  20. #endif
  21. #include "FileSystem.h"
  22. #include "GameUI_Interface.h"
  23. #include "Sys_Utils.h"
  24. #include "string.h"
  25. #include "tier0/icommandline.h"
  26. // interface to engine
  27. #include "EngineInterface.h"
  28. #include "VGuiSystemModuleLoader.h"
  29. #include "bitmap/TGALoader.h"
  30. #include "GameConsole.h"
  31. #include "LoadingDialog.h"
  32. #include "CDKeyEntryDialog.h"
  33. #include "ModInfo.h"
  34. #include "game/client/IGameClientExports.h"
  35. #include "materialsystem/imaterialsystem.h"
  36. #include "matchmaking/imatchframework.h"
  37. #include "ixboxsystem.h"
  38. #include "iachievementmgr.h"
  39. #include "IGameUIFuncs.h"
  40. #include "IEngineVGUI.h"
  41. // vgui2 interface
  42. // note that GameUI project uses ..\vgui2\include, not ..\utils\vgui\include
  43. #include "vgui/Cursor.h"
  44. #include "tier1/KeyValues.h"
  45. #include "vgui/ILocalize.h"
  46. #include "vgui/IPanel.h"
  47. #include "vgui/IScheme.h"
  48. #include "vgui/IVGui.h"
  49. #include "vgui/ISystem.h"
  50. #include "vgui/ISurface.h"
  51. #include "vgui_controls/Menu.h"
  52. #include "vgui_controls/PHandle.h"
  53. #include "tier3/tier3.h"
  54. #include "matsys_controls/matsyscontrols.h"
  55. #ifndef NO_STEAM
  56. #include "steam/steam_api.h"
  57. #endif
  58. #include "protocol.h"
  59. #if defined( SWARM_DLL )
  60. #include "swarm/basemodpanel.h"
  61. #include "swarm/basemodui.h"
  62. typedef BaseModUI::CBaseModPanel UI_BASEMOD_PANEL_CLASS;
  63. inline UI_BASEMOD_PANEL_CLASS & GetUiBaseModPanelClass() { return UI_BASEMOD_PANEL_CLASS::GetSingleton(); }
  64. inline UI_BASEMOD_PANEL_CLASS & ConstructUiBaseModPanelClass() { return * new UI_BASEMOD_PANEL_CLASS(); }
  65. class IMatchExtSwarm *g_pMatchExt = NULL;
  66. #elif defined( PORTAL2 )
  67. #include "portal2/basemodpanel.h"
  68. #include "portal2/basemodui.h"
  69. typedef BaseModUI::CBaseModPanel UI_BASEMOD_PANEL_CLASS;
  70. inline UI_BASEMOD_PANEL_CLASS & GetUiBaseModPanelClass() { return UI_BASEMOD_PANEL_CLASS::GetSingleton(); }
  71. inline UI_BASEMOD_PANEL_CLASS & ConstructUiBaseModPanelClass() { return * new UI_BASEMOD_PANEL_CLASS(); }
  72. class IMatchExtPortal2 *g_pMatchExt = NULL;
  73. #elif defined( PORTAL2_UITEST_DLL )
  74. #include "portal2uitest/basemodpanel.h"
  75. #include "portal2uitest/basemodui.h"
  76. typedef BaseModUI::CBaseModPanel UI_BASEMOD_PANEL_CLASS;
  77. inline UI_BASEMOD_PANEL_CLASS & GetUiBaseModPanelClass() { return UI_BASEMOD_PANEL_CLASS::GetSingleton(); }
  78. inline UI_BASEMOD_PANEL_CLASS & ConstructUiBaseModPanelClass() { return * new UI_BASEMOD_PANEL_CLASS(); }
  79. IMatchExtPortal2 g_MatchExtPortal2;
  80. class IMatchExtPortal2 *g_pMatchExtPortal2 = &g_MatchExtPortal2;
  81. #elif defined( CSTRIKE15 )
  82. #include "cstrike15/basemodpanel.h"
  83. #include "cstrike15/basemodui.h"
  84. typedef BaseModUI::CBaseModPanel UI_BASEMOD_PANEL_CLASS;
  85. inline UI_BASEMOD_PANEL_CLASS & GetUiBaseModPanelClass() { return UI_BASEMOD_PANEL_CLASS::GetSingleton(); }
  86. inline UI_BASEMOD_PANEL_CLASS & ConstructUiBaseModPanelClass() { return * new UI_BASEMOD_PANEL_CLASS(); }
  87. class IMatchExtCStrike15 *g_pMatchExt = NULL;
  88. #else
  89. #include "BasePanel.h"
  90. typedef CBasePanel UI_BASEMOD_PANEL_CLASS;
  91. inline UI_BASEMOD_PANEL_CLASS & GetUiBaseModPanelClass() { return *BasePanel(); }
  92. inline UI_BASEMOD_PANEL_CLASS & ConstructUiBaseModPanelClass() { return *BasePanelSingleton(); }
  93. #endif
  94. #ifdef _X360
  95. #include "xbox/xbox_win32stubs.h"
  96. #endif // _GAMECONSOLE
  97. #ifdef _PS3
  98. #include "ps3/ps3_core.h"
  99. #include "ps3/ps3_win32stubs.h"
  100. #endif // _GAMECONSOLE
  101. #include "tier0/dbg.h"
  102. #include "engine/IEngineSound.h"
  103. #include "gameui_util.h"
  104. // memdbgon must be the last include file in a .cpp file!!!
  105. #include "tier0/memdbgon.h"
  106. IEngineVGui *enginevguifuncs = NULL;
  107. #ifdef _X360
  108. IXOnline *xonline = NULL; // 360 only
  109. #endif
  110. vgui::ISurface *enginesurfacefuncs = NULL;
  111. IAchievementMgr *achievementmgr = NULL;
  112. class CGameUI;
  113. CGameUI *g_pGameUI = NULL;
  114. class CLoadingDialog;
  115. vgui::DHANDLE<CLoadingDialog> g_hLoadingDialog;
  116. vgui::VPANEL g_hLoadingBackgroundDialog = NULL;
  117. static CGameUI g_GameUI;
  118. void VGui_ClearTransitionVideoPanels();
  119. static IGameClientExports *g_pGameClientExports = NULL;
  120. IGameClientExports *GameClientExports()
  121. {
  122. return g_pGameClientExports;
  123. }
  124. //-----------------------------------------------------------------------------
  125. // Purpose: singleton accessor
  126. //-----------------------------------------------------------------------------
  127. CGameUI &GameUI()
  128. {
  129. return g_GameUI;
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Purpose: hack function to give the module loader access to the main panel handle
  133. // only used in VguiSystemModuleLoader
  134. //-----------------------------------------------------------------------------
  135. vgui::VPANEL GetGameUIBasePanel()
  136. {
  137. return GetUiBaseModPanelClass().GetVPanel();
  138. }
  139. EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CGameUI, IGameUI, GAMEUI_INTERFACE_VERSION, g_GameUI);
  140. //-----------------------------------------------------------------------------
  141. // Purpose: Constructor
  142. //-----------------------------------------------------------------------------
  143. CGameUI::CGameUI()
  144. {
  145. g_pGameUI = this;
  146. m_bTryingToLoadFriends = false;
  147. m_iFriendsLoadPauseFrames = 0;
  148. m_iGameIP = 0;
  149. m_iGameConnectionPort = 0;
  150. m_iGameQueryPort = 0;
  151. m_bActivatedUI = false;
  152. m_szPreviousStatusText[0] = 0;
  153. m_bIsConsoleUI = false;
  154. m_bHasSavedThisMenuSession = false;
  155. m_bOpenProgressOnStart = false;
  156. m_iPlayGameStartupSound = 0;
  157. }
  158. //-----------------------------------------------------------------------------
  159. // Purpose: Destructor
  160. //-----------------------------------------------------------------------------
  161. CGameUI::~CGameUI()
  162. {
  163. g_pGameUI = NULL;
  164. }
  165. //-----------------------------------------------------------------------------
  166. // Purpose: Initialization
  167. //-----------------------------------------------------------------------------
  168. void CGameUI::Initialize( CreateInterfaceFn factory )
  169. {
  170. MEM_ALLOC_CREDIT();
  171. ConnectTier1Libraries( &factory, 1 );
  172. ConnectTier2Libraries( &factory, 1 );
  173. ConVar_Register( FCVAR_CLIENTDLL );
  174. ConnectTier3Libraries( &factory, 1 );
  175. enginesound = (IEngineSound *)factory(IENGINESOUND_CLIENT_INTERFACE_VERSION, NULL);
  176. engine = (IVEngineClient *)factory( VENGINE_CLIENT_INTERFACE_VERSION, NULL );
  177. bik = (IBik*)factory( BIK_INTERFACE_VERSION, NULL );
  178. #ifndef NO_STEAM
  179. #ifndef _PS3
  180. SteamAPI_InitSafe();
  181. #endif
  182. steamapicontext->Init();
  183. #endif
  184. CGameUIConVarRef var( "gameui_xbox" );
  185. m_bIsConsoleUI = var.IsValid() && var.GetBool();
  186. vgui::VGui_InitInterfacesList( "GameUI", &factory, 1 );
  187. vgui::VGui_InitMatSysInterfacesList( "GameUI", &factory, 1 );
  188. // load localization file
  189. g_pVGuiLocalize->AddFile( "Resource/gameui_%language%.txt", "GAME", true );
  190. // load mod info
  191. ModInfo().LoadCurrentGameInfo();
  192. // load localization file for kb_act.lst
  193. g_pVGuiLocalize->AddFile( "Resource/valve_%language%.txt", "GAME", true );
  194. bool bFailed = false;
  195. enginevguifuncs = (IEngineVGui *)factory( VENGINE_VGUI_VERSION, NULL );
  196. enginesurfacefuncs = (vgui::ISurface *)factory(VGUI_SURFACE_INTERFACE_VERSION, NULL);
  197. gameuifuncs = (IGameUIFuncs *)factory( VENGINE_GAMEUIFUNCS_VERSION, NULL );
  198. xboxsystem = (IXboxSystem *)factory( XBOXSYSTEM_INTERFACE_VERSION, NULL );
  199. #ifdef _X360
  200. xonline = (IXOnline *)factory( XONLINE_INTERFACE_VERSION, NULL );
  201. #endif
  202. #ifdef SWARM_DLL
  203. g_pMatchExt = ( IMatchExtSwarm * ) factory( IMATCHEXT_SWARM_INTERFACE, NULL );
  204. #endif
  205. bFailed = !enginesurfacefuncs || !gameuifuncs || !enginevguifuncs ||
  206. !xboxsystem ||
  207. #ifdef _X360
  208. !xonline ||
  209. #endif
  210. #ifdef SWARM_DLL
  211. !g_pMatchExt ||
  212. #endif
  213. !g_pMatchFramework;
  214. if ( bFailed )
  215. {
  216. Error( "CGameUI::Initialize() failed to get necessary interfaces\n" );
  217. }
  218. // setup base panel
  219. UI_BASEMOD_PANEL_CLASS& factoryBasePanel = ConstructUiBaseModPanelClass(); // explicit singleton instantiation
  220. factoryBasePanel.SetBounds( 0, 0, 640, 480 );
  221. factoryBasePanel.SetPaintBorderEnabled( false );
  222. factoryBasePanel.SetPaintBackgroundEnabled( true );
  223. factoryBasePanel.SetPaintEnabled( true );
  224. factoryBasePanel.SetVisible( true );
  225. factoryBasePanel.SetMouseInputEnabled( IsPC() );
  226. // factoryBasePanel.SetKeyBoardInputEnabled( IsPC() );
  227. factoryBasePanel.SetKeyBoardInputEnabled( true );
  228. vgui::VPANEL rootpanel = enginevguifuncs->GetPanel( PANEL_GAMEUIDLL );
  229. factoryBasePanel.SetParent( rootpanel );
  230. }
  231. void CGameUI::PostInit()
  232. {
  233. if ( IsGameConsole() )
  234. {
  235. enginesound->PrecacheSound( "UI/buttonrollover.wav", true, true );
  236. enginesound->PrecacheSound( "UI/buttonclick.wav", true, true );
  237. enginesound->PrecacheSound( "UI/buttonclickrelease.wav", true, true );
  238. enginesound->PrecacheSound( "player/suit_denydevice.wav", true, true );
  239. enginesound->PrecacheSound( "UI/menu_accept.wav", true, true );
  240. enginesound->PrecacheSound( "UI/menu_focus.wav", true, true );
  241. enginesound->PrecacheSound( "UI/menu_invalid.wav", true, true );
  242. enginesound->PrecacheSound( "UI/menu_back.wav", true, true );
  243. }
  244. #ifdef GAMEUI_BASEMODPANEL_VGUI
  245. // to know once client dlls have been loaded
  246. BaseModUI::CUIGameData::Get()->OnGameUIPostInit();
  247. #endif
  248. }
  249. //-----------------------------------------------------------------------------
  250. // Purpose: Sets the specified panel as the background panel for the loading
  251. // dialog. If NULL, default background is used. If you set a panel,
  252. // it should be full-screen with an opaque background, and must be a VGUI popup.
  253. //-----------------------------------------------------------------------------
  254. void CGameUI::SetLoadingBackgroundDialog( vgui::VPANEL panel )
  255. {
  256. g_hLoadingBackgroundDialog = panel;
  257. }
  258. //-----------------------------------------------------------------------------
  259. // Purpose: connects to client interfaces
  260. //-----------------------------------------------------------------------------
  261. void CGameUI::Connect( CreateInterfaceFn gameFactory )
  262. {
  263. g_pGameClientExports = (IGameClientExports *)gameFactory(GAMECLIENTEXPORTS_INTERFACE_VERSION, NULL);
  264. achievementmgr = engine->GetAchievementMgr();
  265. if (!g_pGameClientExports)
  266. {
  267. Error("CGameUI::Initialize() failed to get necessary interfaces\n");
  268. }
  269. m_GameFactory = gameFactory;
  270. }
  271. //-----------------------------------------------------------------------------
  272. // Purpose: Callback function; sends platform Shutdown message to specified window
  273. //-----------------------------------------------------------------------------
  274. int __stdcall SendShutdownMsgFunc(WHANDLE hwnd, int lparam)
  275. {
  276. Sys_PostMessage(hwnd, Sys_RegisterWindowMessage("ShutdownValvePlatform"), 0, 1);
  277. return 1;
  278. }
  279. //-----------------------------------------------------------------------------
  280. // Purpose: Searches for GameStartup*.mp3 files in the sound/ui folder and plays one
  281. //-----------------------------------------------------------------------------
  282. void CGameUI::PlayGameStartupSound()
  283. {
  284. #if defined( LEFT4DEAD )
  285. // L4D not using this path, L4D UI now handling with background menu movies
  286. return;
  287. #endif
  288. if ( IsGameConsole() )
  289. return;
  290. if ( CommandLine()->FindParm( "-nostartupsound" ) )
  291. return;
  292. FileFindHandle_t fh;
  293. CUtlVector<char *> fileNames;
  294. char path[ 512 ];
  295. Q_snprintf( path, sizeof( path ), "sound/ui/gamestartup*.mp3" );
  296. Q_FixSlashes( path );
  297. char const *fn = g_pFullFileSystem->FindFirstEx( path, "MOD", &fh );
  298. if ( fn )
  299. {
  300. do
  301. {
  302. char ext[ 10 ];
  303. Q_ExtractFileExtension( fn, ext, sizeof( ext ) );
  304. if ( !Q_stricmp( ext, "mp3" ) )
  305. {
  306. char temp[ 512 ];
  307. Q_snprintf( temp, sizeof( temp ), "ui/%s", fn );
  308. char *found = new char[ strlen( temp ) + 1 ];
  309. Q_strncpy( found, temp, strlen( temp ) + 1 );
  310. Q_FixSlashes( found );
  311. fileNames.AddToTail( found );
  312. }
  313. fn = g_pFullFileSystem->FindNext( fh );
  314. } while ( fn );
  315. g_pFullFileSystem->FindClose( fh );
  316. }
  317. // did we find any?
  318. if ( fileNames.Count() > 0 )
  319. {
  320. int index = Plat_MSTime() % fileNames.Count();
  321. if ( fileNames.IsValidIndex( index ) && fileNames[index] )
  322. {
  323. char found[ 512 ];
  324. // escape chars "*#" make it stream, and be affected by snd_musicvolume
  325. Q_snprintf( found, sizeof( found ), "play *#%s", fileNames[index] );
  326. engine->ClientCmd_Unrestricted( found );
  327. }
  328. fileNames.PurgeAndDeleteElements();
  329. }
  330. }
  331. //-----------------------------------------------------------------------------
  332. // Purpose: Called to setup the game UI
  333. //-----------------------------------------------------------------------------
  334. void CGameUI::Start()
  335. {
  336. // determine Steam location for configuration
  337. if ( !FindPlatformDirectory( m_szPlatformDir, sizeof( m_szPlatformDir ) ) )
  338. return;
  339. if ( IsPC() )
  340. {
  341. // setup config file directory
  342. char szConfigDir[512];
  343. Q_strncpy( szConfigDir, m_szPlatformDir, sizeof( szConfigDir ) );
  344. Q_strncat( szConfigDir, "config", sizeof( szConfigDir ), COPY_ALL_CHARACTERS );
  345. Msg( "Steam config directory: %s\n", szConfigDir );
  346. g_pFullFileSystem->AddSearchPath(szConfigDir, "CONFIG");
  347. g_pFullFileSystem->CreateDirHierarchy("", "CONFIG");
  348. // user dialog configuration
  349. vgui::system()->SetUserConfigFile("InGameDialogConfig.vdf", "CONFIG");
  350. g_pFullFileSystem->AddSearchPath( "platform", "PLATFORM" );
  351. }
  352. // localization
  353. g_pVGuiLocalize->AddFile( "Resource/platform_%language%.txt");
  354. g_pVGuiLocalize->AddFile( "Resource/vgui_%language%.txt");
  355. Sys_SetLastError( SYS_NO_ERROR );
  356. if ( IsPC() )
  357. {
  358. // Delay playing the startup music until two frames
  359. // this allows cbuf commands that occur on the first frame that may start a map
  360. m_iPlayGameStartupSound = 2;
  361. // now we are set up to check every frame to see if we can friends/server browser
  362. m_bTryingToLoadFriends = true;
  363. m_iFriendsLoadPauseFrames = 1;
  364. }
  365. }
  366. //-----------------------------------------------------------------------------
  367. // Purpose: Validates the user has a cdkey in the registry
  368. //-----------------------------------------------------------------------------
  369. void CGameUI::ValidateCDKey()
  370. {
  371. }
  372. //-----------------------------------------------------------------------------
  373. // Purpose: Finds which directory the platform resides in
  374. // Output : Returns true on success, false on failure.
  375. //-----------------------------------------------------------------------------
  376. bool CGameUI::FindPlatformDirectory(char *platformDir, int bufferSize)
  377. {
  378. platformDir[0] = '\0';
  379. if ( platformDir[0] == '\0' )
  380. {
  381. // we're not under steam, so setup using path relative to game
  382. if ( IsPC() )
  383. {
  384. #ifdef IS_WINDOWS_PC
  385. if ( ::GetModuleFileName( ( HINSTANCE )GetModuleHandle( NULL ), platformDir, bufferSize ) )
  386. #else
  387. if ( getcwd( platformDir, bufferSize ) )
  388. #endif
  389. {
  390. V_AppendSlash( platformDir, bufferSize );
  391. Q_strncat(platformDir, "platform", bufferSize, COPY_ALL_CHARACTERS );
  392. V_AppendSlash( platformDir, bufferSize );
  393. return true;
  394. }
  395. }
  396. else
  397. {
  398. // xbox fetches the platform path from exisiting platform search path
  399. // path to executeable is not correct for xbox remote configuration
  400. if ( g_pFullFileSystem->GetSearchPath( "PLATFORM", false, platformDir, bufferSize ) )
  401. {
  402. char *pSeperator = strchr( platformDir, ';' );
  403. if ( pSeperator )
  404. *pSeperator = '\0';
  405. return true;
  406. }
  407. }
  408. Error( "Unable to determine platform directory\n" );
  409. return false;
  410. }
  411. return (platformDir[0] != 0);
  412. }
  413. //-----------------------------------------------------------------------------
  414. // Purpose: Called to Shutdown the game UI system
  415. //-----------------------------------------------------------------------------
  416. void CGameUI::Shutdown()
  417. {
  418. #ifdef GAMEUI_BASEMODPANEL_VGUI
  419. BaseModUI::CUIGameData::Shutdown();
  420. #endif
  421. // notify all the modules of Shutdown
  422. g_VModuleLoader.ShutdownPlatformModules();
  423. // unload the modules them from memory
  424. g_VModuleLoader.UnloadPlatformModules();
  425. ModInfo().FreeModInfo();
  426. #ifndef NO_STEAM
  427. steamapicontext->Clear();
  428. #endif
  429. ConVar_Unregister();
  430. DisconnectTier3Libraries();
  431. DisconnectTier2Libraries();
  432. DisconnectTier1Libraries();
  433. }
  434. //-----------------------------------------------------------------------------
  435. // Purpose: just wraps an engine call to activate the gameUI
  436. //-----------------------------------------------------------------------------
  437. void CGameUI::ActivateGameUI()
  438. {
  439. engine->ExecuteClientCmd("gameui_activate");
  440. // Lock the UI to a particular player
  441. SetGameUIActiveSplitScreenPlayerSlot( engine->GetActiveSplitScreenPlayerSlot() );
  442. }
  443. //-----------------------------------------------------------------------------
  444. // Purpose: just wraps an engine call to hide the gameUI
  445. //-----------------------------------------------------------------------------
  446. void CGameUI::HideGameUI()
  447. {
  448. engine->ExecuteClientCmd("gameui_hide");
  449. }
  450. //-----------------------------------------------------------------------------
  451. // Purpose: Toggle allowing the engine to hide the game UI with the escape key
  452. //-----------------------------------------------------------------------------
  453. void CGameUI::PreventEngineHideGameUI()
  454. {
  455. engine->ExecuteClientCmd("gameui_preventescape");
  456. }
  457. //-----------------------------------------------------------------------------
  458. // Purpose: Toggle allowing the engine to hide the game UI with the escape key
  459. //-----------------------------------------------------------------------------
  460. void CGameUI::AllowEngineHideGameUI()
  461. {
  462. engine->ExecuteClientCmd("gameui_allowescape");
  463. }
  464. //-----------------------------------------------------------------------------
  465. // Purpose: Activate the game UI
  466. //-----------------------------------------------------------------------------
  467. void CGameUI::OnGameUIActivated()
  468. {
  469. bool bWasActive = m_bActivatedUI;
  470. m_bActivatedUI = true;
  471. // Lock the UI to a particular player
  472. if ( !bWasActive )
  473. {
  474. SetGameUIActiveSplitScreenPlayerSlot( engine->GetActiveSplitScreenPlayerSlot() );
  475. }
  476. // pause the server in case it is pausable
  477. engine->ClientCmd_Unrestricted( "setpause nomsg" );
  478. SetSavedThisMenuSession( false );
  479. UI_BASEMOD_PANEL_CLASS &ui = GetUiBaseModPanelClass();
  480. bool bNeedActivation = true;
  481. if ( ui.IsVisible() )
  482. {
  483. // Already visible, maybe don't need activation
  484. if ( !IsInLevel() && IsInBackgroundLevel() )
  485. bNeedActivation = false;
  486. }
  487. if ( bNeedActivation )
  488. {
  489. GetUiBaseModPanelClass().OnGameUIActivated();
  490. }
  491. }
  492. //-----------------------------------------------------------------------------
  493. // Purpose: Hides the game ui, in whatever state it's in
  494. //-----------------------------------------------------------------------------
  495. void CGameUI::OnGameUIHidden()
  496. {
  497. bool bWasActive = m_bActivatedUI;
  498. m_bActivatedUI = false;
  499. // unpause the game when leaving the UI
  500. engine->ClientCmd_Unrestricted( "unpause nomsg" );
  501. GetUiBaseModPanelClass().OnGameUIHidden();
  502. // Restore to default
  503. if ( bWasActive )
  504. {
  505. SetGameUIActiveSplitScreenPlayerSlot( 0 );
  506. }
  507. }
  508. //-----------------------------------------------------------------------------
  509. // Purpose: paints all the vgui elements
  510. //-----------------------------------------------------------------------------
  511. void CGameUI::RunFrame()
  512. {
  513. if ( IsGameConsole() && m_bOpenProgressOnStart )
  514. {
  515. StartProgressBar();
  516. m_bOpenProgressOnStart = false;
  517. }
  518. int wide, tall;
  519. #if defined( TOOLFRAMEWORK_VGUI_REFACTOR )
  520. // resize the background panel to the screen size
  521. vgui::VPANEL clientDllPanel = enginevguifuncs->GetPanel( PANEL_ROOT );
  522. int x, y;
  523. vgui::ipanel()->GetPos( clientDllPanel, x, y );
  524. vgui::ipanel()->GetSize( clientDllPanel, wide, tall );
  525. staticPanel->SetBounds( x, y, wide,tall );
  526. #else
  527. vgui::surface()->GetScreenSize(wide, tall);
  528. GetUiBaseModPanelClass().SetSize(wide, tall);
  529. #endif
  530. // Run frames
  531. g_VModuleLoader.RunFrame();
  532. GetUiBaseModPanelClass().RunFrame();
  533. // Play the start-up music the first time we run frame
  534. if ( IsPC() && m_iPlayGameStartupSound > 0 )
  535. {
  536. m_iPlayGameStartupSound--;
  537. if ( !m_iPlayGameStartupSound )
  538. {
  539. PlayGameStartupSound();
  540. }
  541. }
  542. if ( IsPC() && m_bTryingToLoadFriends && m_iFriendsLoadPauseFrames-- < 1 )
  543. {
  544. // we got the mutex, so load Friends/Serverbrowser
  545. // clear the loading flag
  546. m_bTryingToLoadFriends = false;
  547. g_VModuleLoader.LoadPlatformModules(&m_GameFactory, 1, false);
  548. // notify the game of our game name
  549. const char *fullGamePath = engine->GetGameDirectory();
  550. const char *pathSep = strrchr( fullGamePath, '/' );
  551. if ( !pathSep )
  552. {
  553. pathSep = strrchr( fullGamePath, '\\' );
  554. }
  555. if ( pathSep )
  556. {
  557. KeyValues *pKV = new KeyValues("ActiveGameName" );
  558. pKV->SetString( "name", pathSep + 1 );
  559. pKV->SetInt( "appid", engine->GetAppID() );
  560. KeyValues *modinfo = new KeyValues("ModInfo");
  561. if ( modinfo->LoadFromFile( g_pFullFileSystem, "gameinfo.txt" ) )
  562. {
  563. pKV->SetString( "game", modinfo->GetString( "game", "" ) );
  564. }
  565. modinfo->deleteThis();
  566. g_VModuleLoader.PostMessageToAllModules( pKV );
  567. }
  568. // notify the ui of a game connect if we're already in a game
  569. if (m_iGameIP)
  570. {
  571. SendConnectedToGameMessage();
  572. }
  573. }
  574. }
  575. //-----------------------------------------------------------------------------
  576. // Purpose: Called when the game connects to a server
  577. //-----------------------------------------------------------------------------
  578. void CGameUI::OLD_OnConnectToServer(const char *game, int IP, int port)
  579. {
  580. // Nobody should use this anymore because the query port and the connection port can be different.
  581. // Use OnConnectToServer2 instead.
  582. Assert( false );
  583. OnConnectToServer2( game, IP, port, port );
  584. }
  585. //-----------------------------------------------------------------------------
  586. // Purpose: Called when the game connects to a server
  587. //-----------------------------------------------------------------------------
  588. void CGameUI::OnConnectToServer2(const char *game, int IP, int connectionPort, int queryPort)
  589. {
  590. m_iGameIP = IP;
  591. m_iGameConnectionPort = connectionPort;
  592. m_iGameQueryPort = queryPort;
  593. SendConnectedToGameMessage();
  594. }
  595. void CGameUI::SendConnectedToGameMessage()
  596. {
  597. MEM_ALLOC_CREDIT();
  598. KeyValues *kv = new KeyValues( "ConnectedToGame" );
  599. kv->SetInt( "ip", m_iGameIP );
  600. kv->SetInt( "connectionport", m_iGameConnectionPort );
  601. kv->SetInt( "queryport", m_iGameQueryPort );
  602. g_VModuleLoader.PostMessageToAllModules( kv );
  603. }
  604. //-----------------------------------------------------------------------------
  605. // Purpose: Called when the game disconnects from a server
  606. //-----------------------------------------------------------------------------
  607. void CGameUI::OnDisconnectFromServer( uint8 eSteamLoginFailure )
  608. {
  609. m_iGameIP = 0;
  610. m_iGameConnectionPort = 0;
  611. m_iGameQueryPort = 0;
  612. VGui_ClearTransitionVideoPanels();
  613. if ( g_hLoadingBackgroundDialog )
  614. {
  615. vgui::ivgui()->PostMessage( g_hLoadingBackgroundDialog, new KeyValues("DisconnectedFromGame"), NULL );
  616. }
  617. g_VModuleLoader.PostMessageToAllModules(new KeyValues("DisconnectedFromGame"));
  618. if ( eSteamLoginFailure == STEAMLOGINFAILURE_NOSTEAMLOGIN )
  619. {
  620. if ( g_hLoadingDialog )
  621. {
  622. g_hLoadingDialog->DisplayNoSteamConnectionError();
  623. }
  624. }
  625. else if ( eSteamLoginFailure == STEAMLOGINFAILURE_VACBANNED )
  626. {
  627. if ( g_hLoadingDialog )
  628. {
  629. g_hLoadingDialog->DisplayVACBannedError();
  630. }
  631. }
  632. else if ( eSteamLoginFailure == STEAMLOGINFAILURE_LOGGED_IN_ELSEWHERE )
  633. {
  634. if ( g_hLoadingDialog )
  635. {
  636. g_hLoadingDialog->DisplayLoggedInElsewhereError();
  637. }
  638. }
  639. }
  640. //-----------------------------------------------------------------------------
  641. // Purpose: activates the loading dialog on level load start
  642. //-----------------------------------------------------------------------------
  643. void CGameUI::OnLevelLoadingStarted( const char *levelName, bool bShowProgressDialog )
  644. {
  645. g_VModuleLoader.PostMessageToAllModules( new KeyValues( "LoadingStarted" ) );
  646. GetUiBaseModPanelClass().OnLevelLoadingStarted( levelName, bShowProgressDialog );
  647. ShowLoadingBackgroundDialog();
  648. if ( bShowProgressDialog )
  649. {
  650. StartProgressBar();
  651. }
  652. // Don't play the start game sound if this happens before we get to the first frame
  653. m_iPlayGameStartupSound = 0;
  654. }
  655. //-----------------------------------------------------------------------------
  656. // Purpose: closes any level load dialog
  657. //-----------------------------------------------------------------------------
  658. void CGameUI::OnLevelLoadingFinished(bool bError, const char *failureReason, const char *extendedReason)
  659. {
  660. StopProgressBar( bError, failureReason, extendedReason );
  661. // notify all the modules
  662. g_VModuleLoader.PostMessageToAllModules( new KeyValues( "LoadingFinished" ) );
  663. HideLoadingBackgroundDialog();
  664. }
  665. //-----------------------------------------------------------------------------
  666. // Purpose: Updates progress bar
  667. // Output : Returns true if screen should be redrawn
  668. //-----------------------------------------------------------------------------
  669. bool CGameUI::UpdateProgressBar(float progress, const char *statusText)
  670. {
  671. return GetUiBaseModPanelClass().UpdateProgressBar(progress, statusText);
  672. }
  673. //-----------------------------------------------------------------------------
  674. // Purpose:
  675. //-----------------------------------------------------------------------------
  676. void CGameUI::SetProgressLevelName( const char *levelName )
  677. {
  678. MEM_ALLOC_CREDIT();
  679. if ( g_hLoadingBackgroundDialog )
  680. {
  681. KeyValues *pKV = new KeyValues( "ProgressLevelName" );
  682. pKV->SetString( "levelName", levelName );
  683. vgui::ivgui()->PostMessage( g_hLoadingBackgroundDialog, pKV, NULL );
  684. }
  685. if ( g_hLoadingDialog.Get() )
  686. {
  687. // TODO: g_hLoadingDialog->SetLevelName( levelName );
  688. }
  689. }
  690. //-----------------------------------------------------------------------------
  691. // Purpose:
  692. //-----------------------------------------------------------------------------
  693. void CGameUI::StartProgressBar()
  694. {
  695. }
  696. //-----------------------------------------------------------------------------
  697. // Purpose: returns true if the screen should be updated
  698. //-----------------------------------------------------------------------------
  699. bool CGameUI::ContinueProgressBar( float progressFraction )
  700. {
  701. if (!g_hLoadingDialog.Get())
  702. return false;
  703. g_hLoadingDialog->Activate();
  704. return g_hLoadingDialog->SetProgressPoint(progressFraction);
  705. }
  706. //-----------------------------------------------------------------------------
  707. // Purpose: stops progress bar, displays error if necessary
  708. //-----------------------------------------------------------------------------
  709. void CGameUI::StopProgressBar(bool bError, const char *failureReason, const char *extendedReason)
  710. {
  711. if (!g_hLoadingDialog.Get())
  712. return;
  713. if ( !IsGameConsole() && bError )
  714. {
  715. // turn the dialog to error display mode
  716. g_hLoadingDialog->DisplayGenericError(failureReason, extendedReason);
  717. }
  718. else
  719. {
  720. // close loading dialog
  721. g_hLoadingDialog->Close();
  722. g_hLoadingDialog = NULL;
  723. }
  724. // should update the background to be in a transition here
  725. }
  726. //-----------------------------------------------------------------------------
  727. // Purpose: sets loading info text
  728. //-----------------------------------------------------------------------------
  729. bool CGameUI::SetProgressBarStatusText(const char *statusText)
  730. {
  731. if (!g_hLoadingDialog.Get())
  732. return false;
  733. if (!statusText)
  734. return false;
  735. if (!stricmp(statusText, m_szPreviousStatusText))
  736. return false;
  737. g_hLoadingDialog->SetStatusText(statusText);
  738. Q_strncpy(m_szPreviousStatusText, statusText, sizeof(m_szPreviousStatusText));
  739. return true;
  740. }
  741. //-----------------------------------------------------------------------------
  742. // Purpose:
  743. //-----------------------------------------------------------------------------
  744. void CGameUI::SetSecondaryProgressBar(float progress /* range [0..1] */)
  745. {
  746. if (!g_hLoadingDialog.Get())
  747. return;
  748. g_hLoadingDialog->SetSecondaryProgress(progress);
  749. }
  750. //-----------------------------------------------------------------------------
  751. // Purpose:
  752. //-----------------------------------------------------------------------------
  753. void CGameUI::SetSecondaryProgressBarText(const char *statusText)
  754. {
  755. if (!g_hLoadingDialog.Get())
  756. return;
  757. g_hLoadingDialog->SetSecondaryProgressText(statusText);
  758. }
  759. //-----------------------------------------------------------------------------
  760. // Purpose: Returns prev settings
  761. //-----------------------------------------------------------------------------
  762. bool CGameUI::SetShowProgressText( bool show )
  763. {
  764. if (!g_hLoadingDialog.Get())
  765. return false;
  766. return g_hLoadingDialog->SetShowProgressText( show );
  767. }
  768. //-----------------------------------------------------------------------------
  769. // Purpose: returns true if we're currently playing the game
  770. //-----------------------------------------------------------------------------
  771. bool CGameUI::IsInLevel()
  772. {
  773. const char *levelName = engine->GetLevelName();
  774. if (levelName && levelName[0] && !engine->IsLevelMainMenuBackground())
  775. {
  776. return true;
  777. }
  778. return false;
  779. }
  780. //-----------------------------------------------------------------------------
  781. // Purpose: returns true if we're at the main menu and a background level is loaded
  782. //-----------------------------------------------------------------------------
  783. bool CGameUI::IsInBackgroundLevel()
  784. {
  785. const char *levelName = engine->GetLevelName();
  786. if (levelName && levelName[0] && engine->IsLevelMainMenuBackground())
  787. {
  788. return true;
  789. }
  790. return false;
  791. }
  792. //-----------------------------------------------------------------------------
  793. // Purpose: returns true if we're in a multiplayer game
  794. //-----------------------------------------------------------------------------
  795. bool CGameUI::IsInMultiplayer()
  796. {
  797. return (IsInLevel() && engine->GetMaxClients() > 1);
  798. }
  799. //-----------------------------------------------------------------------------
  800. // Purpose: returns true if we're console ui
  801. //-----------------------------------------------------------------------------
  802. bool CGameUI::IsConsoleUI()
  803. {
  804. return m_bIsConsoleUI;
  805. }
  806. //-----------------------------------------------------------------------------
  807. // Purpose: returns true if we've saved without closing the menu
  808. //-----------------------------------------------------------------------------
  809. bool CGameUI::HasSavedThisMenuSession()
  810. {
  811. return m_bHasSavedThisMenuSession;
  812. }
  813. void CGameUI::SetSavedThisMenuSession( bool bState )
  814. {
  815. m_bHasSavedThisMenuSession = bState;
  816. }
  817. //-----------------------------------------------------------------------------
  818. // Purpose: Makes the loading background dialog visible, if one has been set
  819. //-----------------------------------------------------------------------------
  820. void CGameUI::ShowLoadingBackgroundDialog()
  821. {
  822. if ( g_hLoadingBackgroundDialog )
  823. {
  824. vgui::VPANEL panel = GetUiBaseModPanelClass().GetVPanel();
  825. vgui::ipanel()->SetParent( g_hLoadingBackgroundDialog, panel );
  826. vgui::ipanel()->MoveToFront( g_hLoadingBackgroundDialog );
  827. }
  828. }
  829. //-----------------------------------------------------------------------------
  830. // Purpose: Hides the loading background dialog, if one has been set
  831. //-----------------------------------------------------------------------------
  832. void CGameUI::HideLoadingBackgroundDialog()
  833. {
  834. if ( g_hLoadingBackgroundDialog )
  835. {
  836. if ( engine->IsInGame() )
  837. {
  838. vgui::ivgui()->PostMessage( g_hLoadingBackgroundDialog, new KeyValues( "LoadedIntoGame" ), NULL );
  839. }
  840. else
  841. {
  842. vgui::ipanel()->SetVisible( g_hLoadingBackgroundDialog, false );
  843. vgui::ipanel()->MoveToBack( g_hLoadingBackgroundDialog );
  844. }
  845. vgui::ivgui()->PostMessage( g_hLoadingBackgroundDialog, new KeyValues("HideAsLoadingPanel"), NULL );
  846. }
  847. }
  848. //-----------------------------------------------------------------------------
  849. // Purpose: Returns whether a loading background dialog has been set
  850. //-----------------------------------------------------------------------------
  851. bool CGameUI::HasLoadingBackgroundDialog()
  852. {
  853. return ( NULL != g_hLoadingBackgroundDialog );
  854. }
  855. //-----------------------------------------------------------------------------
  856. // Purpose: Xbox 360 calls from engine to GameUI
  857. //-----------------------------------------------------------------------------
  858. void CGameUI::ShowMessageDialog( const uint nType, vgui::Panel *pOwner )
  859. {
  860. // GetUiBaseModPanelClass()->ShowMessageDialog( nType, pOwner );
  861. }
  862. //-----------------------------------------------------------------------------
  863. void CGameUI::NeedConnectionProblemWaitScreen()
  864. {
  865. #ifdef GAMEUI_BASEMODPANEL_VGUI
  866. BaseModUI::CUIGameData::Get()->NeedConnectionProblemWaitScreen();
  867. #endif
  868. }
  869. void CGameUI::ShowPasswordUI( char const *pchCurrentPW )
  870. {
  871. #ifdef GAMEUI_BASEMODPANEL_VGUI
  872. BaseModUI::CUIGameData::Get()->ShowPasswordUI( pchCurrentPW );
  873. #endif
  874. }
  875. //-----------------------------------------------------------------------------
  876. void CGameUI::SetProgressOnStart()
  877. {
  878. m_bOpenProgressOnStart = true;
  879. }
  880. #if defined( _GAMECONSOLE ) && defined( _DEMO )
  881. void CGameUI::OnDemoTimeout()
  882. {
  883. GetUiBaseModPanelClass().OnDemoTimeout();
  884. }
  885. #endif