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.

491 lines
14 KiB

  1. //=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
  2. //
  3. // The copyright to the contents herein is the property of Valve, L.L.C.
  4. // The contents may be used and/or copied only with the written permission of
  5. // Valve, L.L.C., or in accordance with the terms and conditions stipulated in
  6. // the agreement/contract under which the contents have been supplied.
  7. //
  8. // $Header: $
  9. // $NoKeywords: $
  10. //
  11. // Material editor
  12. //=============================================================================
  13. #include "vstdlib/cvar.h"
  14. #include "appframework/vguimatsysapp.h"
  15. #include "soundsystem/isoundsystem.h"
  16. #include "nowindows.h"
  17. #include "FileSystem.h"
  18. #include "vgui/IVGui.h"
  19. #include "vgui/ISystem.h"
  20. //#include "vgui/IScheme.h"
  21. #include "vgui/ILocalize.h"
  22. #include "vgui/ISurface.h"
  23. #include "tier0/dbg.h"
  24. #include "tier0/icommandline.h"
  25. #include "materialsystem/MaterialSystem_Config.h"
  26. #include "VGuiMatSurface/IMatSystemSurface.h"
  27. #include "vstdlib/iprocessutils.h"
  28. #include "matsys_controls/matsyscontrols.h"
  29. #include "datacache/idatacache.h"
  30. #include "vgui_controls/frame.h"
  31. #include "materialsystem/IMaterialSystemHardwareConfig.h"
  32. #include "materialsystem/materialsystemutil.h"
  33. #include "vgui/keycode.h"
  34. #include "tier0/vprof.h"
  35. #include "inputsystem/iinputsystem.h"
  36. #include "game_controls/igameuisystemmgr.h"
  37. #include "console_logging.h"
  38. #include "vscript/ivscript.h"
  39. #include "materialsystem/imaterialproxyfactory.h"
  40. #include "tier1/interface.h"
  41. #include "materialsystem/IMaterialProxy.h"
  42. #include "materialsystem/imaterial.h"
  43. #include "materialsystem/imaterialvar.h"
  44. LINK_GAME_CONTROLS_LIB();
  45. using namespace vgui;
  46. //-----------------------------------------------------------------------------
  47. // Forward declarations
  48. //-----------------------------------------------------------------------------
  49. const MaterialSystem_Config_t *g_pMaterialSystemConfig;
  50. //-----------------------------------------------------------------------------
  51. // A material proxy that resets the base texture to use the dynamic texture
  52. //-----------------------------------------------------------------------------
  53. class CPerftestGameControlsProxy : public IMaterialProxy
  54. {
  55. public:
  56. CPerftestGameControlsProxy();
  57. virtual ~CPerftestGameControlsProxy(){};
  58. virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
  59. virtual void OnBind( void *pProxyData );
  60. virtual void Release( void ) { delete this; }
  61. virtual IMaterial *GetMaterial();
  62. private:
  63. IMaterialVar* m_BaseTextureVar;
  64. };
  65. CPerftestGameControlsProxy::CPerftestGameControlsProxy(): m_BaseTextureVar( NULL )
  66. {
  67. }
  68. bool CPerftestGameControlsProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
  69. {
  70. bool bFoundVar;
  71. m_BaseTextureVar = pMaterial->FindVar( "$basetexture", &bFoundVar, false );
  72. return bFoundVar;
  73. }
  74. void CPerftestGameControlsProxy::OnBind( void *pProxyData )
  75. {
  76. const char *pBaseTextureName = ( const char * )pProxyData;
  77. ITexture *pTexture = g_pMaterialSystem->FindTexture( pBaseTextureName, TEXTURE_GROUP_OTHER, true );
  78. m_BaseTextureVar->SetTextureValue( pTexture );
  79. }
  80. IMaterial *CPerftestGameControlsProxy::GetMaterial()
  81. {
  82. return m_BaseTextureVar->GetOwningMaterial();
  83. }
  84. static CPerftestGameControlsProxy s_CPerftestGameControlsProxy;
  85. //-----------------------------------------------------------------------------
  86. // Factory to create dynamic material. ( Return in this case. )
  87. //-----------------------------------------------------------------------------
  88. class CPerftestMaterialProxyFactory : public IMaterialProxyFactory
  89. {
  90. public:
  91. IMaterialProxy *CreateProxy( const char *proxyName );
  92. void DeleteProxy( IMaterialProxy *pProxy );
  93. CreateInterfaceFn GetFactory();
  94. };
  95. static CPerftestMaterialProxyFactory s_DynamicMaterialProxyFactory;
  96. IMaterialProxy *CPerftestMaterialProxyFactory::CreateProxy( const char *proxyName )
  97. {
  98. if ( Q_strcmp( proxyName, "GameControlsProxy" ) == NULL )
  99. {
  100. return static_cast< IMaterialProxy * >( &s_CPerftestGameControlsProxy );
  101. }
  102. return NULL;
  103. }
  104. void CPerftestMaterialProxyFactory::DeleteProxy( IMaterialProxy *pProxy )
  105. {
  106. }
  107. CreateInterfaceFn CPerftestMaterialProxyFactory::GetFactory()
  108. {
  109. return Sys_GetFactoryThis();
  110. }
  111. //-----------------------------------------------------------------------------
  112. // The application object
  113. //-----------------------------------------------------------------------------
  114. class CVguiPerfTestApp : public CVguiMatSysApp
  115. {
  116. typedef CVguiMatSysApp BaseClass;
  117. public:
  118. // Methods of IApplication
  119. virtual bool Create();
  120. virtual bool PreInit();
  121. virtual int Main();
  122. virtual bool AppUsesReadPixels() { return true; }
  123. private:
  124. bool SetupSearchPaths();
  125. virtual const char *GetAppName() { return "VguiPerfTest"; }
  126. bool RunPerfTest( CMatRenderContextPtr &pRenderContext, const char *pMenuName );
  127. void CVguiPerfTestApp::PlayMenuSound( const char *pSoundFileName );
  128. };
  129. DEFINE_WINDOWED_STEAM_APPLICATION_OBJECT( CVguiPerfTestApp );
  130. //-----------------------------------------------------------------------------
  131. // Create all singleton systems
  132. //-----------------------------------------------------------------------------
  133. bool CVguiPerfTestApp::Create()
  134. {
  135. if ( !BaseClass::Create() )
  136. return false;
  137. AppSystemInfo_t appSystems[] =
  138. {
  139. { "vstdlib.dll", PROCESS_UTILS_INTERFACE_VERSION },
  140. { "vstdlib.dll", EVENTSYSTEM_INTERFACE_VERSION }, // input event support
  141. // { "studiorender.dll", STUDIO_RENDER_INTERFACE_VERSION },
  142. // { "vphysics.dll", VPHYSICS_INTERFACE_VERSION },
  143. { "datacache.dll", DATACACHE_INTERFACE_VERSION }, // needed for sound system.
  144. // { "datacache.dll", MDLCACHE_INTERFACE_VERSION },
  145. { "vscript.dll", VSCRIPT_INTERFACE_VERSION }, // scripting support
  146. { "soundsystem.dll", SOUNDSYSTEM_INTERFACE_VERSION }, // sound support
  147. { "", "" } // Required to terminate the list
  148. };
  149. AddSystem( g_pGameUISystemMgr, GAMEUISYSTEMMGR_INTERFACE_VERSION );
  150. return AddSystems( appSystems );
  151. }
  152. //-----------------------------------------------------------------------------
  153. // Init, shutdown
  154. //-----------------------------------------------------------------------------
  155. bool CVguiPerfTestApp::PreInit( )
  156. {
  157. MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
  158. if ( !BaseClass::PreInit() )
  159. return false;
  160. // initialize interfaces
  161. CreateInterfaceFn appFactory = GetFactory();
  162. if (!vgui::VGui_InitMatSysInterfacesList( "VguiPerfTest", &appFactory, 1 ))
  163. return false;
  164. if ( !g_pFullFileSystem || !g_pMaterialSystem || !g_pVGui || !g_pVGuiSurface || !g_pMatSystemSurface || !g_pEventSystem )
  165. {
  166. Warning( "Perf Test App is missing a required interface!\n" );
  167. return false;
  168. }
  169. // Add paths...
  170. if ( !SetupSearchPaths() )
  171. return false;
  172. materials->SetMaterialProxyFactory( &s_DynamicMaterialProxyFactory );
  173. return true;
  174. }
  175. //-----------------------------------------------------------------------------
  176. // Sets up the game path
  177. //-----------------------------------------------------------------------------
  178. bool CVguiPerfTestApp::SetupSearchPaths()
  179. {
  180. if ( !BaseClass::SetupSearchPaths( NULL, false, true ) )
  181. return false;
  182. return true;
  183. }
  184. // Replace first underscore (if any) with \0 and return
  185. // This handles special mods like tf_movies, l4d_movies, tf_comics
  186. // As a result, such mods will use the gpu_level settings etc from the base mod
  187. void StripModSuffix2( char *pModName )
  188. {
  189. int i = 0;
  190. while ( pModName[i] != '\0' ) // Walk to the end of the string
  191. {
  192. if ( pModName[i] == '_') // If we hit an underscore
  193. {
  194. pModName[i] = '\0'; // Terminate the string here and bail out
  195. return;
  196. }
  197. i++;
  198. }
  199. }
  200. //-----------------------------------------------------------------------------
  201. // main application
  202. //-----------------------------------------------------------------------------
  203. int CVguiPerfTestApp::Main()
  204. {
  205. CConsoleLoggingListener consoleLoggingListener;
  206. LoggingSystem_PushLoggingState();
  207. LoggingSystem_RegisterLoggingListener( &consoleLoggingListener );
  208. LoggingSystem_SetChannelSpewLevelByTag( "Console", LS_MESSAGE );
  209. LoggingSystem_SetChannelSpewLevelByTag( "Developer", LS_ERROR );
  210. LoggingSystem_SetChannelSpewLevelByTag( "DeveloperVerbose", LS_ERROR );
  211. CSimpleLoggingListener simpleLoggingListner( false );
  212. LoggingSystem_RegisterLoggingListener( &simpleLoggingListner );
  213. g_pMaterialSystem->ModInit();
  214. if (!SetVideoMode())
  215. return 0;
  216. g_pDataCache->SetSize( 64 * 1024 * 1024 );
  217. g_pMaterialSystemConfig = &g_pMaterialSystem->GetCurrentConfigForVideoCard();
  218. // configuration settings
  219. vgui::system()->SetUserConfigFile( "VguiPerfTest.vdf", "EXECUTABLE_PATH");
  220. // If you load a vgui panel you must load up a scheme.
  221. // load scheme
  222. if (!vgui::scheme()->LoadSchemeFromFile( "resource/BoxRocket.res", "VguiPerfTest" ))
  223. {
  224. Assert( 0 );
  225. }
  226. // load the boxrocket localization file
  227. g_pVGuiLocalize->AddFile( "resource/boxrocket_%language%.txt" );
  228. // load the mod localization file
  229. // Construct the mod name so we can use the mod-specific encrypted config files
  230. char pModPath[MAX_PATH];
  231. V_snprintf( pModPath, sizeof(pModPath), "" );
  232. g_pFullFileSystem->GetSearchPath( "MOD", false, pModPath, sizeof( pModPath ) );
  233. char pModName[32];
  234. V_StripTrailingSlash( pModPath );
  235. V_FileBase( pModPath, pModName, sizeof( pModName ) );
  236. StripModSuffix2( pModName );
  237. // Language file is a file of the form "resource/nimbus_%language%.txt"
  238. CUtlString pModLanguageFile;
  239. pModLanguageFile += "resource/";
  240. pModLanguageFile += pModName;
  241. pModLanguageFile += "_%language%.txt";
  242. g_pVGuiLocalize->AddFile( pModLanguageFile.Get() );
  243. // start vgui
  244. g_pVGui->Start();
  245. // add our main window
  246. //vgui::PHandle hMainPanel;
  247. // load the base localization file
  248. g_pVGuiLocalize->AddFile( "Resource/valve_%language%.txt" );
  249. g_pFullFileSystem->AddSearchPath( "platform", "PLATFORM" );
  250. g_pVGuiLocalize->AddFile( "Resource/vgui_%language%.txt");
  251. // run app frame loop
  252. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  253. const char *pGuiFileName = CommandLine()->ParmValue( "-gui" );
  254. bool bReload = true;
  255. while ( bReload )
  256. {
  257. bReload = RunPerfTest( pRenderContext, pGuiFileName );
  258. }
  259. g_pMaterialSystem->ModShutdown();
  260. LoggingSystem_PopLoggingState();
  261. return 1;
  262. }
  263. //-----------------------------------------------------------------------------
  264. // returns true if ui should reload
  265. //-----------------------------------------------------------------------------
  266. bool CVguiPerfTestApp::RunPerfTest( CMatRenderContextPtr &pRenderContext, const char *pMenuName )
  267. {
  268. g_pGameUISystemMgr->Shutdown();
  269. g_pGameUISystemMgr->Init();
  270. g_pMaterialSystem->BeginRenderTargetAllocation();
  271. g_pGameUISystemMgr->InitRenderTargets();
  272. g_pMaterialSystem->EndRenderTargetAllocation();
  273. if ( !pMenuName )
  274. {
  275. pMenuName = "menu_1";
  276. }
  277. g_pGameUISystemMgr->LoadGameUIScreen( KeyValues::AutoDeleteInline(
  278. new KeyValues( pMenuName ) ) );
  279. g_VProfCurrentProfile.Reset();
  280. g_VProfCurrentProfile.ResetPeaks();
  281. g_VProfCurrentProfile.Start();
  282. float m_flTotalTime = 0;
  283. float flStartTime = Plat_FloatTime();
  284. {
  285. KeyValues *kvEvent = new KeyValues( "StartPlaying" );
  286. kvEvent->SetFloat( "time", 0 );
  287. g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
  288. }
  289. int frameCount = 0;
  290. bool bReload = false;
  291. bool bAbleToAdvance = true;
  292. vgui::VPANEL root = g_pVGuiSurface->GetEmbeddedPanel();
  293. g_pVGuiSurface->Invalidate( root );
  294. while ( g_pVGui->IsRunning() )
  295. {
  296. AppPumpMessages();
  297. g_pSoundSystem->Update( Plat_FloatTime() );
  298. g_pMaterialSystem->BeginFrame( 0 );
  299. pRenderContext->ClearColor4ub( 0, 0, 0, 255 );
  300. //pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
  301. pRenderContext->ClearBuffers( true, true );
  302. // Handle all input to game ui.
  303. g_pGameUISystemMgr->RunFrame();
  304. // Must call run frame for close button to work.
  305. g_pVGui->RunFrame(); // need to load a default scheme for this to work.
  306. //g_pVGuiSurface->PaintTraverseEx( root, true );
  307. Rect_t viewport;
  308. pRenderContext->GetViewport( viewport.x, viewport.y, viewport.width, viewport.height );
  309. float flCurrentRenderTime = Plat_FloatTime() - flStartTime;
  310. g_pGameUISystemMgr->Render( viewport, DmeTime_t( flCurrentRenderTime ) );
  311. g_pMaterialSystem->EndFrame();
  312. g_pMaterialSystem->SwapBuffers();
  313. g_VProfCurrentProfile.MarkFrame();
  314. frameCount++;
  315. //if ( frameCount >= 5000 )
  316. // break;
  317. if ( g_pInputSystem->IsButtonDown( KEY_ESCAPE ) )
  318. {
  319. bReload = true;
  320. break;
  321. }
  322. else if ( g_pInputSystem->IsButtonDown( KEY_PAD_PLUS ) )
  323. {
  324. m_flTotalTime = 0;
  325. {
  326. KeyValues *kvEvent = new KeyValues( "StartPlaying" );
  327. kvEvent->SetFloat( "time", m_flTotalTime );
  328. g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
  329. }
  330. }
  331. else if ( g_pInputSystem->IsButtonDown( KEY_PAD_MINUS ) )
  332. {
  333. KeyValues *kvEvent = new KeyValues( "StopPlaying" );
  334. g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
  335. }
  336. else if ( g_pInputSystem->IsButtonDown( KEY_PAD_DIVIDE ) )
  337. {
  338. KeyValues *kvEvent = new KeyValues( "ShowCursorCoords" );
  339. g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
  340. }
  341. else if ( g_pInputSystem->IsButtonDown( KEY_PAD_9 ) )
  342. {
  343. KeyValues *kvEvent = new KeyValues( "ShowGraphicName" );
  344. g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
  345. }
  346. else if ( g_pInputSystem->IsButtonDown( KEY_PAD_MULTIPLY ) )
  347. {
  348. if ( bAbleToAdvance )
  349. {
  350. KeyValues *kvEvent = new KeyValues( "AdvanceState" );
  351. g_pGameUISystemMgr->SendEventToAllScreens( kvEvent );
  352. }
  353. bAbleToAdvance = false;
  354. }
  355. else if ( !g_pInputSystem->IsButtonDown( KEY_PAD_MULTIPLY ) )
  356. {
  357. bAbleToAdvance = true;
  358. }
  359. }
  360. g_VProfCurrentProfile.Stop();
  361. g_VProfCurrentProfile.OutputReport( VPRT_FULL & ~VPRT_HIERARCHY, NULL );
  362. return bReload;
  363. }
  364. //-----------------------------------------------------------------------------
  365. //
  366. //-----------------------------------------------------------------------------
  367. void CVguiPerfTestApp::PlayMenuSound( const char *pSoundFileName )
  368. {
  369. if ( pSoundFileName == NULL || pSoundFileName[ 0 ] == '\0' )
  370. return;
  371. if ( !Q_stristr( pSoundFileName, ".wav" ) )
  372. return;
  373. char filename[ 256 ];
  374. sprintf( filename, "sound/%s", pSoundFileName );
  375. CAudioSource *pAudioSource = g_pSoundSystem->FindOrAddSound( filename );
  376. if ( pAudioSource == NULL )
  377. return;
  378. g_pSoundSystem->PlaySound( pAudioSource, 1.0f, NULL );
  379. }