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.

390 lines
11 KiB

  1. //========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: master for refresh, status bar, console, chat, notify, etc
  4. //
  5. //=====================================================================================//
  6. #include "render_pch.h"
  7. #include "client.h"
  8. #include "console.h"
  9. #include "screen.h"
  10. #include "sound.h"
  11. #include "sbar.h"
  12. #include "debugoverlay.h"
  13. #include "cdll_int.h"
  14. #include "gl_matsysiface.h"
  15. #include "cdll_engine_int.h"
  16. #include "demo.h"
  17. #include "cl_main.h"
  18. #include "vgui_baseui_interface.h"
  19. #include "con_nprint.h"
  20. #include "sys_mainwind.h"
  21. #include "ivideomode.h"
  22. #include "lightcache.h"
  23. #include "toolframework/itoolframework.h"
  24. #include "datacache/idatacache.h"
  25. #include "sys_dll.h"
  26. #include "host.h"
  27. #include "MapReslistGenerator.h"
  28. #include "tier1/callqueue.h"
  29. #include "tier0/icommandline.h"
  30. #include "matchmaking/imatchframework.h"
  31. #include "cl_steamauth.h"
  32. #include "scaleformui/scaleformui.h"
  33. // memdbgon must be the last include file in a .cpp file!!!
  34. #include "tier0/memdbgon.h"
  35. ConVar g_cv_miniprofiler_dump( "miniprofiler_dump", "0" );
  36. #if defined( _X360 )
  37. ConVar g_cv_frame_pcm( "frame_pcm", "0" );
  38. bool g_started_frame_pcm = false;
  39. #endif
  40. DLL_IMPORT void PublishAllMiniProfilers(int nHistoryMax);
  41. // In other C files.
  42. extern bool V_CheckGamma( void );
  43. extern void V_RenderView( void );
  44. extern void V_RenderVGuiOnly( void );
  45. extern bool HostState_IsTransitioningToLoad();
  46. bool scr_initialized; // ready to draw
  47. bool scr_disabled_for_loading;
  48. bool scr_drawloading;
  49. int scr_nextdrawtick; // A hack to let things settle on reload/reconnect
  50. float scr_loadingStartTime;
  51. static bool scr_engineevent_loadingstarted; // whether OnEngineLevelLoadingStarted has been fired
  52. //-----------------------------------------------------------------------------
  53. // Purpose:
  54. //-----------------------------------------------------------------------------
  55. void SCR_Init (void)
  56. {
  57. scr_initialized = true;
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Purpose:
  61. //-----------------------------------------------------------------------------
  62. void SCR_Shutdown( void )
  63. {
  64. scr_initialized = false;
  65. }
  66. //-----------------------------------------------------------------------------
  67. // Purpose: starts loading
  68. //-----------------------------------------------------------------------------
  69. void SCR_BeginLoadingPlaque( const char *levelName /*= NULL*/ )
  70. {
  71. if ( !scr_drawloading )
  72. {
  73. MEM_ALLOC_CREDIT();
  74. #if defined( _DEMO ) && defined( _X360 )
  75. // disable demo timeouts during loading
  76. Host_EnableDemoTimeout( false );
  77. #endif
  78. scr_loadingStartTime = Plat_FloatTime();
  79. // make sure game UI is allowed to show (gets disabled if chat window is up)
  80. EngineVGui()->SetNotAllowedToShowGameUI( false );
  81. // force QMS to serialize during loading
  82. Host_AllowQueuedMaterialSystem( false );
  83. scr_drawloading = true;
  84. S_StopAllSounds( true );
  85. S_PreventSound( true ); //this will stop audio from reaching the mixer until SCR_EndLoadingPlaque is called.
  86. S_OnLoadScreen( true );
  87. g_pFileSystem->AsyncFinishAll();
  88. g_pMDLCache->FinishPendingLoads();
  89. // redraw with no console and the loading plaque
  90. Con_ClearNotify();
  91. // NULL HudText clears HudMessage system
  92. if ( g_ClientDLL )
  93. {
  94. g_ClientDLL->CenterStringOff();
  95. g_ClientDLL->HudText( NULL );
  96. }
  97. // let everybody know we're starting loading
  98. EngineVGui()->OnLevelLoadingStarted( levelName, HostState_IsTransitioningToLoad() );
  99. scr_engineevent_loadingstarted = true;
  100. g_pMatchFramework->GetEventsSubscription()->BroadcastEvent( new KeyValues(
  101. "OnEngineLevelLoadingStarted", "name", levelName ) );
  102. // Don't run any more simulation on the client!!!
  103. g_ClientGlobalVariables.frametime = 0.0f;
  104. host_framecount++;
  105. g_ClientGlobalVariables.framecount = host_framecount;
  106. // Ensure the screen is painted to reflect the loading state
  107. SCR_UpdateScreen();
  108. host_framecount++;
  109. g_ClientGlobalVariables.framecount = host_framecount;
  110. SCR_UpdateScreen();
  111. g_ClientGlobalVariables.frametime = GetBaseLocalClient().GetFrameTime();
  112. scr_disabled_for_loading = true;
  113. }
  114. }
  115. //-----------------------------------------------------------------------------
  116. // Purpose: finished loading
  117. //-----------------------------------------------------------------------------
  118. void SCR_EndLoadingPlaque( void )
  119. {
  120. // MATCHMAKING:UNDONE: This pattern came over from l4d but needed to change since the new clients don't have the same mission/game structure
  121. if ( scr_drawloading )
  122. {
  123. #if defined( _DEMO ) && defined( _X360 )
  124. // allow demo timeouts
  125. Host_EnableDemoTimeout( true );
  126. #endif
  127. scr_engineevent_loadingstarted = false;
  128. EngineVGui()->HideLoadingPlaque();
  129. if ( g_pMatchFramework )
  130. {
  131. scr_engineevent_loadingstarted = false;
  132. EngineVGui()->HideLoadingPlaque();
  133. KeyValues *kv = new KeyValues( "OnEngineLevelLoadingFinished" );
  134. if ( gfExtendedError )
  135. {
  136. kv->SetInt( "error", gfExtendedError );
  137. kv->SetString( "reason", gszDisconnectReason );
  138. }
  139. #ifndef NO_TOOLFRAMEWORK
  140. if ( toolframework->InToolMode() )
  141. {
  142. // Make a copy of the message to send to the tools framework
  143. KeyValues *pToolMsg = kv->MakeCopy();
  144. // Notify the active tool that the level has finished loading
  145. toolframework->PostMessage( pToolMsg );
  146. pToolMsg->deleteThis();
  147. }
  148. #endif
  149. g_pMatchFramework->GetEventsSubscription()->BroadcastEvent( kv );
  150. return;
  151. }
  152. return;
  153. }
  154. else if ( gfExtendedError )
  155. {
  156. #if !defined( CSTRIKE15 )
  157. if ( IsPC() )
  158. {
  159. EngineVGui()->ShowErrorMessage();
  160. }
  161. #endif
  162. }
  163. if ( scr_engineevent_loadingstarted )
  164. {
  165. // Keep firing Tick event only between LoadingStarted and LoadingFinished
  166. g_pMatchFramework->GetEventsSubscription()->BroadcastEvent( new KeyValues( "OnEngineLevelLoadingTick" ) );
  167. }
  168. }
  169. //-----------------------------------------------------------------------------
  170. // Purpose: This is called every frame, and can also be called explicitly to flush
  171. // text to the screen.
  172. //-----------------------------------------------------------------------------
  173. void SCR_UpdateScreen( void )
  174. {
  175. R_StudioCheckReinitLightingCache();
  176. // Always force the Gamma Table to be rebuilt. Otherwise,
  177. // we'll load textures with an all white gamma lookup table.
  178. V_CheckGamma();
  179. // This is a HACK to let things settle for a bit on level start
  180. // NOTE: If you remove scr_nextdrawtick, remove it from enginetool.cpp too
  181. if ( scr_nextdrawtick != 0 )
  182. {
  183. if ( host_tickcount < scr_nextdrawtick )
  184. return;
  185. scr_nextdrawtick = 0;
  186. }
  187. if ( scr_disabled_for_loading )
  188. {
  189. if ( !Host_IsSinglePlayerGame() )
  190. {
  191. V_RenderVGuiOnly();
  192. }
  193. // Put this here to avoid a crappy alt+tab situation:
  194. // 1. g_LostVideoMemory is only cleared if we can call CheckDeviceLost
  195. // 2. CheckDeviceLost can only get called if we present
  196. // 3. Present can only get called in SCR_UpdateScreen if scr_disabled_for_loading is cleared
  197. // 4. scr_disabled_for_loading can only be cleared if we disable the loading plaque
  198. // 5. The loading plaque can only be disabled if we get a call to CL_FullyConnected
  199. // 6. CL_FullyConnected only gets called if we get a snapshot from the server
  200. // 7. In single player we only send snapshots if g_LostVideoMemory is cleared
  201. // 8. goto step 1
  202. if ( !IsGameConsole() && g_LostVideoMemory )
  203. {
  204. Shader_SwapBuffers();
  205. }
  206. return;
  207. }
  208. if ( !scr_initialized || !con_initialized )
  209. {
  210. // not initialized yet
  211. return;
  212. }
  213. // Let demo system overwrite view origin/angles during playback
  214. if ( demoplayer->IsPlayingBack() )
  215. {
  216. demoplayer->InterpolateViewpoint();
  217. }
  218. materials->BeginFrame( host_frametime );
  219. CMatRenderContextPtr pRenderContext;
  220. pRenderContext.GetFrom( materials );
  221. pRenderContext->RenderScaleformSlot(SF_RESERVED_BEGINFRAME_SLOT);
  222. if( EngineVGui()->IsGameUIVisible() || IsSteam3ClientGameOverlayActive() )
  223. {
  224. pRenderContext->AntiAliasingHint( AA_HINT_MENU );
  225. }
  226. if ( pRenderContext->GetCallQueue() )
  227. {
  228. pRenderContext->GetCallQueue()->QueueCall( g_pMDLCache, &IMDLCache::BeginCoarseLock );
  229. }
  230. pRenderContext.SafeRelease();
  231. EngineVGui()->Simulate();
  232. {
  233. CMatRenderContextPtr pRenderContext( materials );
  234. PIXEVENT( pRenderContext, "framestagenotify" );
  235. ClientDLL_FrameStageNotify( FRAME_RENDER_START );
  236. }
  237. Host_BeginThreadedSound();
  238. // Simulation meant to occur before any views are rendered
  239. // This needs to happen before the client DLL is called because the client DLL depends on
  240. // some of the setup in FRAME_RENDER_START.
  241. g_EngineRenderer->FrameBegin();
  242. toolframework->RenderFrameBegin();
  243. GetBaseLocalClient().UpdateAreaBits_BackwardsCompatible();
  244. Shader_BeginRendering();
  245. // Draw world, etc.
  246. V_RenderView();
  247. pRenderContext.GetFrom( materials );
  248. pRenderContext->RenderScaleformSlot(SF_RESERVED_ENDFRAME_SLOT);
  249. pRenderContext.SafeRelease();
  250. CL_TakeSnapshotAndSwap();
  251. ClientDLL_FrameStageNotify( FRAME_RENDER_END );
  252. toolframework->RenderFrameEnd();
  253. g_EngineRenderer->FrameEnd();
  254. pRenderContext.GetFrom( materials );
  255. if ( pRenderContext->GetCallQueue() )
  256. {
  257. pRenderContext->GetCallQueue()->QueueCall( g_pMDLCache, &IMDLCache::EndCoarseLock );
  258. }
  259. pRenderContext.SafeRelease();
  260. materials->EndFrame();
  261. #if !defined( _CERT )
  262. PublishAllMiniProfilers( g_cv_miniprofiler_dump.GetInt() );
  263. #if defined( _X360 )
  264. if ( g_started_frame_pcm )
  265. {
  266. g_started_frame_pcm = false;
  267. PMCStopAndReport();
  268. }
  269. if ( g_cv_frame_pcm.GetInt() )
  270. {
  271. g_cv_frame_pcm.SetValue("0");
  272. g_started_frame_pcm = true;
  273. PMCInstallAndStart(ePMCSetup(PMC_SETUP_OVERVIEW_PB0T0 + GetCurrentProcessorNumber()));
  274. }
  275. #endif
  276. #endif
  277. // NOTE: It isn't super awesome to do this here, but it has to occur after
  278. // the client DLL where it knows its read in all entities, which happens in
  279. // ClientDLL_FrameStageNotify( FRAME_RENDER_START )
  280. #ifndef DEDICATED
  281. if ( IsPC() )
  282. {
  283. static bool s_bTestedBuildCubemaps = false;
  284. CClientState &cl = GetBaseLocalClient();
  285. if ( !s_bTestedBuildCubemaps && cl.IsActive() )
  286. {
  287. s_bTestedBuildCubemaps = true;
  288. int i;
  289. if( (i = CommandLine()->FindParm( "-buildcubemaps" )) != 0 )
  290. {
  291. int numIterations = 1;
  292. if( CommandLine()->ParmCount() > i + 1 )
  293. {
  294. numIterations = atoi( CommandLine()->GetParm(i+1) );
  295. }
  296. if( numIterations == 0 )
  297. {
  298. numIterations = 1;
  299. }
  300. char cmd[ 1024 ] = { 0 };
  301. V_snprintf( cmd, sizeof( cmd ), "buildcubemaps %u;quit\n", numIterations );
  302. Cbuf_AddText( Cbuf_GetCurrentPlayer(), cmd );
  303. }
  304. else if( CommandLine()->FindParm( "-buildmodelforworld" ) )
  305. {
  306. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "buildmodelforworld;quit\n" );
  307. }
  308. else if( CommandLine()->FindParm( "-navanalyze" ) )
  309. {
  310. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "sv_cheats 1;nav_edit 1;nav_analyze_scripted\n" );
  311. }
  312. else if( CommandLine()->FindParm( "-navforceanalyze" ) )
  313. {
  314. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "sv_cheats 1;nav_edit 1;nav_analyze_scripted force\n" );
  315. }
  316. else if ( CommandLine()->FindParm("-exit") )
  317. {
  318. Cbuf_AddText( Cbuf_GetCurrentPlayer(), "quit\n" );
  319. }
  320. }
  321. }
  322. #endif
  323. }