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.

1803 lines
52 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose: Engine system for loading and managing tools
  4. //
  5. //=============================================================================
  6. #include "quakedef.h"
  7. #include "tier0/icommandline.h"
  8. #include "toolframework/itooldictionary.h"
  9. #include "toolframework/itoolsystem.h"
  10. #include "toolframework/itoolframework.h"
  11. #include "toolframework/iclientenginetools.h"
  12. #include "toolframework/iserverenginetools.h"
  13. #include "tier1/keyvalues.h"
  14. #include "tier1/utlvector.h"
  15. #include "tier1/tier1.h"
  16. #include "filesystem_engine.h"
  17. #include "toolframework/itoolframework.h"
  18. #include "IHammer.h"
  19. #include "baseclientstate.h"
  20. #include "sys.h"
  21. #include "tier1/fmtstr.h"
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include "tier0/memdbgon.h"
  24. class IToolSystem;
  25. extern CreateInterfaceFn g_AppSystemFactory;
  26. extern IHammer *g_pHammer;
  27. typedef bool (*FnQuitHandler)( void *pvUserData );
  28. void EngineTool_InstallQuitHandler( void *pvUserData, FnQuitHandler func );
  29. struct ToolModule_t
  30. {
  31. ToolModule_t() : m_pModule( NULL ), m_pDictionary( NULL ) {}
  32. ToolModule_t &operator =( const ToolModule_t &other )
  33. {
  34. if ( this == &other )
  35. return *this;
  36. m_sDllName = other.m_sDllName;
  37. m_sFirstTool = other.m_sFirstTool;
  38. m_pModule = other.m_pModule;
  39. m_pDictionary = other.m_pDictionary;
  40. m_Systems.CopyArray( other.m_Systems.Base(), other.m_Systems.Count() );
  41. return *this;
  42. }
  43. CUtlString m_sDllName;
  44. CUtlString m_sFirstTool;
  45. CSysModule *m_pModule;
  46. IToolDictionary *m_pDictionary;
  47. CUtlVector< IToolSystem * > m_Systems;
  48. };
  49. //-----------------------------------------------------------------------------
  50. // Purpose: -tools loads framework
  51. //-----------------------------------------------------------------------------
  52. class CToolFrameworkInternal : public CBaseAppSystem< IToolFrameworkInternal >
  53. {
  54. public:
  55. // Here's where the app systems get to learn about each other
  56. virtual bool Connect( CreateInterfaceFn factory );
  57. virtual void Disconnect();
  58. // Here's where systems can access other interfaces implemented by this object
  59. // Returns NULL if it doesn't implement the requested interface
  60. virtual void *QueryInterface( const char *pInterfaceName );
  61. // Init, shutdown
  62. virtual InitReturnVal_t Init();
  63. virtual void Shutdown();
  64. virtual bool CanQuit();
  65. public:
  66. // Level init, shutdown
  67. virtual void ClientLevelInitPreEntityAllTools();
  68. // entities are created / spawned / precached here
  69. virtual void ClientLevelInitPostEntityAllTools();
  70. virtual void ClientLevelShutdownPreEntityAllTools();
  71. // Entities are deleted / released here...
  72. virtual void ClientLevelShutdownPostEntityAllTools();
  73. virtual void ClientPreRenderAllTools();
  74. virtual void ClientPostRenderAllTools();
  75. virtual bool IsThirdPersonCamera();
  76. virtual bool IsToolRecording();
  77. // Level init, shutdown
  78. virtual void ServerLevelInitPreEntityAllTools();
  79. // entities are created / spawned / precached here
  80. virtual void ServerLevelInitPostEntityAllTools();
  81. virtual void ServerLevelShutdownPreEntityAllTools();
  82. // Entities are deleted / released here...
  83. virtual void ServerLevelShutdownPostEntityAllTools();
  84. // end of level shutdown
  85. // Called each frame before entities think
  86. virtual void ServerFrameUpdatePreEntityThinkAllTools();
  87. // called after entities think
  88. virtual void ServerFrameUpdatePostEntityThinkAllTools();
  89. virtual void ServerPreClientUpdateAllTools();
  90. const char* GetEntityData( const char *pActualEntityData );
  91. virtual void ServerPreSetupVisibilityAllTools();
  92. virtual bool PostInit();
  93. virtual bool ServerInit( CreateInterfaceFn serverFactory );
  94. virtual bool ClientInit( CreateInterfaceFn clientFactory );
  95. virtual void ServerShutdown();
  96. virtual void ClientShutdown();
  97. virtual void Think( bool finalTick );
  98. virtual void PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg );
  99. virtual void AdjustEngineViewport( int& x, int& y, int& width, int& height );
  100. virtual bool SetupEngineView( Vector &origin, QAngle &angles, float &fov );
  101. virtual bool SetupAudioState( AudioState_t &audioState );
  102. virtual int GetToolCount();
  103. virtual const char* GetToolName( int index );
  104. virtual void SwitchToTool( int index );
  105. virtual IToolSystem* SwitchToTool( const char* pToolName );
  106. virtual bool IsTopmostTool( const IToolSystem *sys );
  107. virtual const IToolSystem *GetToolSystem( int index ) const;
  108. virtual IToolSystem *GetTopmostTool();
  109. virtual bool LoadToolModule( char const *pToolModule, bool bSwitchToFirst );
  110. virtual void PostMessage( KeyValues *msg );
  111. virtual bool GetSoundSpatialization( int iUserData, int guid, SpatializationInfo_t& info );
  112. virtual void HostRunFrameBegin();
  113. virtual void HostRunFrameEnd();
  114. virtual void RenderFrameBegin();
  115. virtual void RenderFrameEnd();
  116. virtual void VGui_PreRenderAllTools( int paintMode );
  117. virtual void VGui_PostRenderAllTools( int paintMode );
  118. virtual void VGui_PreSimulateAllTools();
  119. virtual void VGui_PostSimulateAllTools();
  120. // Are we using tools?
  121. virtual bool InToolMode();
  122. // Should the game be allowed to render the world?
  123. virtual bool ShouldGameRenderView();
  124. // Should sounds from the game be played
  125. virtual bool ShouldGamePlaySounds();
  126. virtual IMaterialProxy *LookupProxy( const char *proxyName );
  127. virtual bool LoadFilmmaker();
  128. virtual void UnloadFilmmaker();
  129. ToolModule_t *Find( char const *pModuleName );
  130. void UnloadTools( char const *pModule, bool bCheckCanQuit );
  131. void GetModules( CUtlVector< CUtlString > &list );
  132. private:
  133. void LoadToolsFromEngineToolsManifest();
  134. void LoadToolsFromCommandLine( CUtlVector< CUtlString > &list );
  135. ToolModule_t *LoadToolsFromLibrary( const char *dllname );
  136. void InvokeMethod( ToolSystemFunc_t f );
  137. void InvokeMethodInt( ToolSystemFunc_Int_t f, int arg );
  138. void ShutdownTools();
  139. // Purpose: Shuts down all modules
  140. void ShutdownModules();
  141. // Purpose: Shuts down all tool dictionaries
  142. void ShutdownToolDictionaries();
  143. CUtlVector< IToolSystem * > m_ToolSystems;
  144. CUtlVector< ToolModule_t > m_Modules;
  145. int m_nActiveToolIndex;
  146. bool m_bInToolMode;
  147. CreateInterfaceFn m_ClientFactory;
  148. CreateInterfaceFn m_ServerFactory;
  149. };
  150. static CToolFrameworkInternal g_ToolFrameworkInternal;
  151. IToolFrameworkInternal *toolframework = &g_ToolFrameworkInternal;
  152. //-----------------------------------------------------------------------------
  153. // Purpose: Used to invoke a method of all added Game systems in order
  154. // Input : f - function to execute
  155. //-----------------------------------------------------------------------------
  156. void CToolFrameworkInternal::InvokeMethod( ToolSystemFunc_t f )
  157. {
  158. int toolCount = m_ToolSystems.Count();
  159. for ( int i = 0; i < toolCount; ++i )
  160. {
  161. IToolSystem *sys = m_ToolSystems[i];
  162. (sys->*f)();
  163. }
  164. }
  165. //-----------------------------------------------------------------------------
  166. // Purpose: Used to invoke a method of all added Game systems in order
  167. // Input : f - function to execute
  168. //-----------------------------------------------------------------------------
  169. void CToolFrameworkInternal::InvokeMethodInt( ToolSystemFunc_Int_t f, int arg )
  170. {
  171. int toolCount = m_ToolSystems.Count();
  172. for ( int i = 0; i < toolCount; ++i )
  173. {
  174. IToolSystem *sys = m_ToolSystems[i];
  175. (sys->*f)( arg );
  176. }
  177. }
  178. //-----------------------------------------------------------------------------
  179. // Purpose: Here's where the app systems get to learn about each other
  180. // Input : factory -
  181. // Output : Returns true on success, false on failure.
  182. //-----------------------------------------------------------------------------
  183. bool CToolFrameworkInternal::Connect( CreateInterfaceFn factory )
  184. {
  185. return true;
  186. }
  187. //-----------------------------------------------------------------------------
  188. // Purpose:
  189. // Input : -
  190. //-----------------------------------------------------------------------------
  191. void CToolFrameworkInternal::Disconnect()
  192. {
  193. }
  194. //-----------------------------------------------------------------------------
  195. // Purpose:
  196. // Input : *pvUserData -
  197. // Output : static bool
  198. //-----------------------------------------------------------------------------
  199. static bool CToolFrameworkInternal_QuitHandler( void *pvUserData )
  200. {
  201. CToolFrameworkInternal *tfm = reinterpret_cast< CToolFrameworkInternal * >( pvUserData );
  202. if ( tfm )
  203. {
  204. return tfm->CanQuit();
  205. }
  206. return true;
  207. }
  208. //-----------------------------------------------------------------------------
  209. // Purpose: Init, shutdown
  210. // Input : -
  211. // Output : InitReturnVal_t
  212. //-----------------------------------------------------------------------------
  213. InitReturnVal_t CToolFrameworkInternal::Init()
  214. {
  215. m_bInToolMode = false;
  216. m_nActiveToolIndex = -1;
  217. m_ClientFactory = m_ServerFactory = NULL;
  218. // Disabled in REL for now
  219. #if 1
  220. #ifndef DEDICATED
  221. EngineTool_InstallQuitHandler( this, CToolFrameworkInternal_QuitHandler );
  222. // FIXME: Eventually this should be -edit
  223. if ( CommandLine()->FindParm( "-tools" ) )
  224. {
  225. CUtlVector< CUtlString > vecToolList;
  226. int toolParamIndex = CommandLine()->FindParm( "-tools" );
  227. if ( toolParamIndex != 0 )
  228. {
  229. // See if additional tools were specified
  230. for ( int i = toolParamIndex + 1; i < CommandLine()->ParmCount(); ++i )
  231. {
  232. char const *pToolName = CommandLine()->GetParm( i );
  233. if ( !pToolName || !*pToolName || *pToolName == '-' || *pToolName == '+' )
  234. break;
  235. vecToolList.AddToTail( CUtlString( pToolName ) );
  236. }
  237. }
  238. if ( vecToolList.Count() > 0 )
  239. {
  240. LoadToolsFromCommandLine( vecToolList );
  241. }
  242. else
  243. {
  244. LoadToolsFromEngineToolsManifest();
  245. }
  246. }
  247. #endif
  248. #endif
  249. return INIT_OK;
  250. }
  251. //-----------------------------------------------------------------------------
  252. // Purpose: Called at end of Host_Init
  253. //-----------------------------------------------------------------------------
  254. bool CToolFrameworkInternal::PostInit()
  255. {
  256. bool bRetVal = true;
  257. int toolCount = m_ToolSystems.Count();
  258. for ( int i = 0; i < toolCount; ++i )
  259. {
  260. IToolSystem *system = m_ToolSystems[ i ];
  261. // FIXME: Should this really get access to a list if factories
  262. bool success = system->Init( );
  263. if ( !success )
  264. {
  265. bRetVal = false;
  266. }
  267. }
  268. // Activate first tool if we didn't encounter an error
  269. if ( bRetVal )
  270. {
  271. SwitchToTool( 0 );
  272. }
  273. return bRetVal;
  274. }
  275. //-----------------------------------------------------------------------------
  276. // Purpose:
  277. // Input : -
  278. //-----------------------------------------------------------------------------
  279. void CToolFrameworkInternal::Shutdown()
  280. {
  281. // Shut down all tools
  282. ShutdownTools();
  283. }
  284. //-----------------------------------------------------------------------------
  285. // Purpose:
  286. // Input : finalTick -
  287. //-----------------------------------------------------------------------------
  288. void CToolFrameworkInternal::Think( bool finalTick )
  289. {
  290. int toolCount = m_ToolSystems.Count();
  291. for ( int i = 0; i < toolCount; ++i )
  292. {
  293. IToolSystem *system = m_ToolSystems[ i ];
  294. system->Think( finalTick );
  295. }
  296. }
  297. //-----------------------------------------------------------------------------
  298. // Purpose:
  299. // Input : serverFactory -
  300. // Output : Returns true on success, false on failure.
  301. //-----------------------------------------------------------------------------
  302. bool CToolFrameworkInternal::ServerInit( CreateInterfaceFn serverFactory )
  303. {
  304. m_ServerFactory = serverFactory;
  305. bool retval = true;
  306. int toolCount = m_ToolSystems.Count();
  307. for ( int i = 0; i < toolCount; ++i )
  308. {
  309. IToolSystem *system = m_ToolSystems[ i ];
  310. // FIXME: Should this really get access to a list if factories
  311. bool success = system->ServerInit( serverFactory );
  312. if ( !success )
  313. {
  314. retval = false;
  315. }
  316. }
  317. return retval;
  318. }
  319. //-----------------------------------------------------------------------------
  320. // Purpose:
  321. // Input : clientFactory -
  322. // Output : Returns true on success, false on failure.
  323. //-----------------------------------------------------------------------------
  324. bool CToolFrameworkInternal::ClientInit( CreateInterfaceFn clientFactory )
  325. {
  326. m_ClientFactory = clientFactory;
  327. bool retval = true;
  328. int toolCount = m_ToolSystems.Count();
  329. for ( int i = 0; i < toolCount; ++i )
  330. {
  331. IToolSystem *system = m_ToolSystems[ i ];
  332. // FIXME: Should this really get access to a list if factories
  333. bool success = system->ClientInit( clientFactory );
  334. if ( !success )
  335. {
  336. retval = false;
  337. }
  338. }
  339. return retval;
  340. }
  341. //-----------------------------------------------------------------------------
  342. // Purpose:
  343. // Input : -
  344. //-----------------------------------------------------------------------------
  345. void CToolFrameworkInternal::ServerShutdown()
  346. {
  347. // Reverse order
  348. int toolCount = m_ToolSystems.Count();
  349. for ( int i = toolCount - 1; i >= 0; --i )
  350. {
  351. IToolSystem *system = m_ToolSystems[ i ];
  352. system->ServerShutdown();
  353. }
  354. }
  355. //-----------------------------------------------------------------------------
  356. // Purpose:
  357. // Input : -
  358. //-----------------------------------------------------------------------------
  359. void CToolFrameworkInternal::ClientShutdown()
  360. {
  361. // Reverse order
  362. int toolCount = m_ToolSystems.Count();
  363. for ( int i = toolCount - 1; i >= 0; --i )
  364. {
  365. IToolSystem *system = m_ToolSystems[ i ];
  366. system->ClientShutdown();
  367. }
  368. }
  369. //-----------------------------------------------------------------------------
  370. // Purpose:
  371. // Input : -
  372. // Output : Returns true on success, false on failure.
  373. //-----------------------------------------------------------------------------
  374. bool CToolFrameworkInternal::CanQuit()
  375. {
  376. int toolCount = m_ToolSystems.Count();
  377. for ( int i = 0; i < toolCount; ++i )
  378. {
  379. IToolSystem *system = m_ToolSystems[ i ];
  380. bool canquit = system->CanQuit( "OnQuit" );
  381. if ( !canquit )
  382. {
  383. return false;
  384. }
  385. }
  386. return true;
  387. }
  388. //-----------------------------------------------------------------------------
  389. // Purpose: Shuts down all modules
  390. //-----------------------------------------------------------------------------
  391. void CToolFrameworkInternal::ShutdownModules()
  392. {
  393. // Shutdown dictionaries
  394. int i;
  395. for ( i = m_Modules.Count(); --i >= 0; )
  396. {
  397. Assert( !m_Modules[i].m_pDictionary );
  398. Sys_UnloadModule( m_Modules[i].m_pModule );
  399. m_Modules[i].m_pModule = NULL;
  400. }
  401. m_Modules.RemoveAll();
  402. }
  403. //-----------------------------------------------------------------------------
  404. // Purpose: Shuts down all tool dictionaries
  405. //-----------------------------------------------------------------------------
  406. void CToolFrameworkInternal::ShutdownToolDictionaries()
  407. {
  408. // Shutdown dictionaries
  409. int i;
  410. for ( i = m_Modules.Count(); --i >= 0; )
  411. {
  412. m_Modules[i].m_pDictionary->Shutdown();
  413. }
  414. for ( i = m_Modules.Count(); --i >= 0; )
  415. {
  416. m_Modules[i].m_pDictionary->Disconnect();
  417. m_Modules[i].m_pDictionary = NULL;
  418. }
  419. }
  420. //-----------------------------------------------------------------------------
  421. // Purpose: Shuts down all tools
  422. // Input : -
  423. //-----------------------------------------------------------------------------
  424. void CToolFrameworkInternal::ShutdownTools()
  425. {
  426. // Deactivate tool
  427. SwitchToTool( -1 );
  428. // Reverse order
  429. int i;
  430. int toolCount = m_ToolSystems.Count();
  431. for ( i = toolCount - 1; i >= 0; --i )
  432. {
  433. IToolSystem *system = m_ToolSystems[ i ];
  434. system->Shutdown();
  435. }
  436. m_ToolSystems.RemoveAll();
  437. ShutdownToolDictionaries();
  438. ShutdownModules();
  439. }
  440. //-----------------------------------------------------------------------------
  441. // Purpose: Adds tool from specified library
  442. // Input : *dllname -
  443. //-----------------------------------------------------------------------------
  444. ToolModule_t *CToolFrameworkInternal::LoadToolsFromLibrary( const char *dllname )
  445. {
  446. CSysModule *module = Sys_LoadModule( dllname );
  447. if ( !module )
  448. {
  449. Warning( "CToolFrameworkInternal::LoadToolsFromLibrary: Unable to load '%s'\n", dllname );
  450. return NULL;
  451. }
  452. CreateInterfaceFn factory = Sys_GetFactory( module );
  453. if ( !factory )
  454. {
  455. Sys_UnloadModule( module );
  456. Warning( "CToolFrameworkInternal::LoadToolsFromLibrary: Dll '%s' has no factory\n", dllname );
  457. return NULL;
  458. }
  459. IToolDictionary *dictionary = ( IToolDictionary * )factory( VTOOLDICTIONARY_INTERFACE_VERSION, NULL );
  460. if ( !dictionary )
  461. {
  462. Sys_UnloadModule( module );
  463. Warning( "CToolFrameworkInternal::LoadToolsFromLibrary: Dll '%s' doesn't support '%s'\n", dllname, VTOOLDICTIONARY_INTERFACE_VERSION );
  464. return NULL;
  465. }
  466. if ( !dictionary->Connect( g_AppSystemFactory ) )
  467. {
  468. Sys_UnloadModule( module );
  469. Warning( "CToolFrameworkInternal::LoadToolsFromLibrary: Dll '%s' connection phase failed.\n", dllname );
  470. return NULL;
  471. }
  472. if ( dictionary->Init( ) != INIT_OK )
  473. {
  474. Sys_UnloadModule( module );
  475. Warning( "CToolFrameworkInternal::LoadToolsFromLibrary: Dll '%s' initialization phase failed.\n", dllname );
  476. return NULL;
  477. }
  478. dictionary->CreateTools();
  479. int idx = m_Modules.AddToTail();
  480. ToolModule_t *tm = &m_Modules[ idx ];
  481. tm->m_pDictionary = dictionary;
  482. tm->m_pModule = module;
  483. tm->m_sDllName = dllname;
  484. bool first = true;
  485. int toolCount = dictionary->GetToolCount();
  486. for ( int i = 0; i < toolCount; ++i )
  487. {
  488. IToolSystem *tool = dictionary->GetTool( i );
  489. if ( tool )
  490. {
  491. Msg( "Loaded tool '%s'\n", tool->GetToolName() );
  492. if ( first )
  493. {
  494. first = false;
  495. tm->m_sFirstTool = tool->GetToolName();
  496. }
  497. // Add to global dictionary
  498. m_ToolSystems.AddToTail( tool );
  499. // Add to local dicitionary
  500. tm->m_Systems.AddToTail( tool );
  501. }
  502. }
  503. // If this is Hammer, get a pointer to the Hammer interface.
  504. g_pHammer = (IHammer*)factory( INTERFACEVERSION_HAMMER, NULL );
  505. return tm;
  506. }
  507. //-----------------------------------------------------------------------------
  508. // Load filmmaker (used by Replay system)
  509. //-----------------------------------------------------------------------------
  510. bool g_bReplayLoadedTools = false; // This used where significant CommandLine()->CheckParm("-tools") logic is used
  511. bool CToolFrameworkInternal::LoadFilmmaker()
  512. {
  513. if ( V_stricmp( COM_GetModDirectory(), "tf" ) )
  514. return false;
  515. extern bool g_bReplayLoadedTools;
  516. #ifndef DEDICATED
  517. extern CreateInterfaceFn g_ClientFactory;
  518. #endif
  519. extern CreateInterfaceFn g_ServerFactory;
  520. LoadToolsFromLibrary( "tools/ifm.dll" );
  521. #ifndef DEDICATED
  522. ClientInit( g_ClientFactory );
  523. #endif
  524. ServerInit( g_ServerFactory );
  525. PostInit();
  526. g_bReplayLoadedTools = true;
  527. return true;
  528. }
  529. //-----------------------------------------------------------------------------
  530. // Unload filmmaker (used by Replay system)
  531. //-----------------------------------------------------------------------------
  532. void CToolFrameworkInternal::UnloadFilmmaker()
  533. {
  534. if ( V_stricmp( COM_GetModDirectory(), "tf" ) )
  535. return;
  536. ServerShutdown();
  537. ClientShutdown();
  538. ShutdownTools();
  539. g_bReplayLoadedTools = false;
  540. }
  541. //-----------------------------------------------------------------------------
  542. // Are we using tools?
  543. //-----------------------------------------------------------------------------
  544. bool CToolFrameworkInternal::InToolMode()
  545. {
  546. extern bool g_bReplayLoadedTools;
  547. return m_bInToolMode || g_bReplayLoadedTools;
  548. }
  549. //-----------------------------------------------------------------------------
  550. // Should the game be allowed to render the world?
  551. //-----------------------------------------------------------------------------
  552. bool CToolFrameworkInternal::ShouldGameRenderView()
  553. {
  554. if ( m_nActiveToolIndex >= 0 )
  555. {
  556. IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
  557. Assert( tool );
  558. return tool->ShouldGameRenderView( );
  559. }
  560. return true;
  561. }
  562. //-----------------------------------------------------------------------------
  563. // Should sounds from the game be played
  564. //-----------------------------------------------------------------------------
  565. bool CToolFrameworkInternal::ShouldGamePlaySounds()
  566. {
  567. if ( m_nActiveToolIndex >= 0 )
  568. {
  569. IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
  570. Assert( tool );
  571. return tool->ShouldGamePlaySounds();
  572. }
  573. return true;
  574. }
  575. IMaterialProxy *CToolFrameworkInternal::LookupProxy( const char *proxyName )
  576. {
  577. int toolCount = GetToolCount();
  578. for ( int i = 0; i < toolCount; ++i )
  579. {
  580. IToolSystem *tool = m_ToolSystems[ i ];
  581. Assert( tool );
  582. IMaterialProxy *matProxy = tool->LookupProxy( proxyName );
  583. if ( matProxy )
  584. {
  585. return matProxy;
  586. }
  587. }
  588. return NULL;
  589. }
  590. void CToolFrameworkInternal::LoadToolsFromCommandLine( CUtlVector< CUtlString > &list )
  591. {
  592. m_bInToolMode = true;
  593. // CHECK both bin/tools and gamedir/bin/tools
  594. for ( int i = 0; i < list.Count(); ++i )
  595. {
  596. LoadToolsFromLibrary( CFmtStr( "tools/%s.dll", list[ i ].String() ) );
  597. }
  598. }
  599. //-----------------------------------------------------------------------------
  600. // Purpose: FIXME: Should scan a KeyValues file
  601. // Input : -
  602. //-----------------------------------------------------------------------------
  603. void CToolFrameworkInternal::LoadToolsFromEngineToolsManifest()
  604. {
  605. m_bInToolMode = true;
  606. // Load rootdir/bin/enginetools.txt
  607. KeyValues *kv = new KeyValues( "enginetools" );
  608. Assert( kv );
  609. // Load enginetools.txt if it available and fallback to sdkenginetools.txt
  610. char szToolConfigFile[25];
  611. if ( g_pFileSystem->FileExists( "enginetools.txt", "EXECUTABLE_PATH" ) )
  612. {
  613. V_strncpy( szToolConfigFile, "enginetools.txt", sizeof( szToolConfigFile ) );
  614. }
  615. else
  616. {
  617. V_strncpy( szToolConfigFile, "sdkenginetools.txt", sizeof( szToolConfigFile ) );
  618. }
  619. if ( kv && kv->LoadFromFile( g_pFileSystem, szToolConfigFile, "EXECUTABLE_PATH" ) )
  620. {
  621. for ( KeyValues *tool = kv->GetFirstSubKey();
  622. tool != NULL;
  623. tool = tool->GetNextKey() )
  624. {
  625. if ( !Q_stricmp( tool->GetName(), "library" ) )
  626. {
  627. // CHECK both bin/tools and gamedir/bin/tools
  628. LoadToolsFromLibrary( tool->GetString() );
  629. }
  630. }
  631. kv->deleteThis();
  632. }
  633. }
  634. ToolModule_t *CToolFrameworkInternal::Find( char const *pModuleName )
  635. {
  636. for ( int i = 0; i < m_Modules.Count(); ++i )
  637. {
  638. ToolModule_t *tm = &m_Modules[ i ];
  639. if ( !Q_stricmp( tm->m_sDllName.String(), pModuleName ) )
  640. return tm;
  641. }
  642. return NULL;
  643. }
  644. //-----------------------------------------------------------------------------
  645. // Purpose: Simple helper class for doing autocompletion of all files in a specific directory by extension
  646. //-----------------------------------------------------------------------------
  647. class CToolAutoCompleteFileList
  648. {
  649. public:
  650. CToolAutoCompleteFileList( const char *cmdname, const char *subdir, const char *extension )
  651. {
  652. m_pszCommandName = cmdname;
  653. m_pszSubDir = subdir;
  654. m_pszExtension = extension;
  655. }
  656. int AutoCompletionFunc( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] );
  657. private:
  658. const char *m_pszCommandName;
  659. const char *m_pszSubDir;
  660. const char *m_pszExtension;
  661. };
  662. //-----------------------------------------------------------------------------
  663. // Purpose: Fills in a list of commands based on specified subdirectory and extension into the format:
  664. // commandname subdir/filename.ext
  665. // commandname subdir/filename2.ext
  666. // Returns number of files in list for autocompletion
  667. //-----------------------------------------------------------------------------
  668. int CToolAutoCompleteFileList::AutoCompletionFunc( char const *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
  669. {
  670. char const *cmdname = m_pszCommandName;
  671. char *substring = (char *)partial;
  672. if ( Q_strstr( partial, cmdname ) )
  673. {
  674. substring = (char *)partial + strlen( cmdname ) + 1;
  675. }
  676. // Search the directory structure.
  677. char searchpath[MAX_QPATH];
  678. if ( m_pszSubDir && m_pszSubDir[0] && Q_strcasecmp( m_pszSubDir, "NULL" ) )
  679. {
  680. Q_snprintf(searchpath,sizeof(searchpath),"%s/*.%s", m_pszSubDir, m_pszExtension );
  681. }
  682. else
  683. {
  684. Q_snprintf(searchpath,sizeof(searchpath),"*.%s", m_pszExtension );
  685. }
  686. CUtlSymbolTable entries( 0, 0, true );
  687. CUtlVector< CUtlSymbol > symbols;
  688. char const *findfn = Sys_FindFirstEx( searchpath, "EXECUTABLE_PATH", NULL, 0 );
  689. while ( findfn )
  690. {
  691. char sz[ MAX_QPATH ] = { 0 };
  692. Q_StripExtension( findfn, sz, sizeof( sz ) );
  693. bool add = false;
  694. // Insert into lookup
  695. if ( substring[0] )
  696. {
  697. if ( !Q_strncasecmp( findfn, substring, strlen( substring ) ) )
  698. {
  699. add = true;
  700. }
  701. }
  702. else
  703. {
  704. add = true;
  705. }
  706. if ( add )
  707. {
  708. CUtlSymbol sym = entries.AddString( findfn );
  709. int idx = symbols.Find( sym );
  710. if ( idx == symbols.InvalidIndex() )
  711. {
  712. symbols.AddToTail( sym );
  713. }
  714. }
  715. findfn = Sys_FindNext( NULL, 0 );
  716. // Too many
  717. if ( symbols.Count() >= COMMAND_COMPLETION_MAXITEMS )
  718. break;
  719. }
  720. Sys_FindClose();
  721. for ( int i = 0; i < symbols.Count(); i++ )
  722. {
  723. char const *filename = entries.String( symbols[ i ] );
  724. Q_snprintf( commands[ i ], sizeof( commands[ i ] ), "%s %s", cmdname, filename );
  725. // Remove .dem
  726. commands[ i ][ strlen( commands[ i ] ) - 4 ] = 0;
  727. }
  728. return symbols.Count();
  729. }
  730. static int g_ToolLoad_CompletionFunc( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
  731. {
  732. static CToolAutoCompleteFileList ToolLoad_Complete( "toolload", "tools", "dll" );
  733. return ToolLoad_Complete.AutoCompletionFunc( partial, commands );
  734. }
  735. // This now works in most cases, however it will not work once the sfm has run a python script since when python imports modules, it doesn't properly unload them,
  736. // So they stick around in memory and crash the second time you load the ifm.dll (or maybe on the second unload). This is a pretty serious flaw in python25.dll
  737. //-----------------------------------------------------------------------------
  738. // Purpose: Simple helper class for doing autocompletion of all files in a specific directory by extension
  739. //-----------------------------------------------------------------------------
  740. class CToolUnloadAutoCompleteFileList
  741. {
  742. public:
  743. CToolUnloadAutoCompleteFileList( const char *cmdname )
  744. {
  745. m_pszCommandName = cmdname;
  746. }
  747. int AutoCompletionFunc( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
  748. {
  749. char const *cmdname = m_pszCommandName;
  750. char *substring = (char *)partial;
  751. if ( Q_strstr( partial, cmdname ) )
  752. {
  753. substring = (char *)partial + strlen( cmdname ) + 1;
  754. }
  755. CUtlVector< CUtlString > modules;
  756. int c = 0;
  757. g_ToolFrameworkInternal.GetModules( modules );
  758. for ( int i = 0; i < modules.Count(); i++ )
  759. {
  760. char const *pFileName = modules[ i ].String();
  761. char filename[ MAX_PATH ];
  762. Q_FileBase( pFileName, filename, sizeof( filename ) );
  763. bool add = false;
  764. // Insert into lookup
  765. if ( substring[0] )
  766. {
  767. if ( !Q_strncasecmp( filename, substring, strlen( substring ) ) )
  768. {
  769. add = true;
  770. }
  771. }
  772. else
  773. {
  774. add = true;
  775. }
  776. if ( add )
  777. {
  778. Q_snprintf( commands[ c ], sizeof( commands[ c ] ), "%s %s", cmdname, filename );
  779. ++c;
  780. }
  781. }
  782. return c;
  783. }
  784. private:
  785. const char *m_pszCommandName;
  786. };
  787. static int g_ToolUnload_CompletionFunc( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
  788. {
  789. static CToolUnloadAutoCompleteFileList ToolUnload_Complete( "toolunload" );
  790. return ToolUnload_Complete.AutoCompletionFunc( partial, commands );
  791. }
  792. void Tool_Unload_f( const CCommand &args )
  793. {
  794. if ( !toolframework->InToolMode() )
  795. return;
  796. if ( args.ArgC() < 2 )
  797. {
  798. ConMsg ("toolunload <toolname> [-nosave]: unloads a tool\n");
  799. return;
  800. }
  801. bool bPromptForSave = true;
  802. if ( args.ArgC() > 2 )
  803. {
  804. if ( Q_stricmp( "-nosave", args.Arg( 2 ) ) == 0 )
  805. {
  806. bPromptForSave = false;
  807. }
  808. }
  809. char fn[ MAX_PATH ];
  810. Q_FileBase( args.Arg( 1 ), fn, sizeof( fn ) );
  811. CFmtStr module( "tools/%s.dll", fn );
  812. g_ToolFrameworkInternal.UnloadTools( module, bPromptForSave );
  813. }
  814. static ConCommand ToolUnload( "toolunload", Tool_Unload_f, "Unload a tool.", 0, g_ToolUnload_CompletionFunc );
  815. // If module not already loaded, loads it and optionally switches to first tool in module
  816. bool CToolFrameworkInternal::LoadToolModule( char const *pToolModule, bool bSwitchToFirst )
  817. {
  818. CFmtStr module( "tools/%s.dll", pToolModule );
  819. ToolModule_t *tm = Find( module );
  820. if ( tm )
  821. {
  822. // Already loaded
  823. return true;
  824. }
  825. tm = LoadToolsFromLibrary( module );
  826. if ( !tm )
  827. {
  828. ConMsg( "failed to load tools from %s\n", pToolModule );
  829. return false;
  830. }
  831. for ( int i = 0; i < tm->m_Systems.Count(); ++i )
  832. {
  833. IToolSystem *sys = tm->m_Systems[ i ];
  834. if ( sys )
  835. {
  836. sys->ClientInit( m_ClientFactory );
  837. sys->ServerInit( m_ServerFactory );
  838. sys->Init();
  839. }
  840. }
  841. // Since this is a late init, do some more work
  842. if ( bSwitchToFirst )
  843. {
  844. SwitchToTool( tm->m_sFirstTool.String() );
  845. }
  846. return true;
  847. }
  848. void CToolFrameworkInternal::GetModules( CUtlVector< CUtlString > &list )
  849. {
  850. for ( int i = 0; i < m_Modules.Count(); ++i )
  851. {
  852. CUtlString str;
  853. str = m_Modules[ i ].m_sDllName;
  854. list.AddToTail( str );
  855. }
  856. }
  857. void CToolFrameworkInternal::UnloadTools( char const *pModule, bool bCheckCanQuit )
  858. {
  859. ToolModule_t *tm = g_ToolFrameworkInternal.Find( pModule );
  860. if ( !tm )
  861. {
  862. ConMsg( "module %s not loaded\n", pModule );
  863. return;
  864. }
  865. if ( bCheckCanQuit )
  866. {
  867. for ( int i = tm->m_Systems.Count() - 1; i >= 0; --i )
  868. {
  869. IToolSystem *sys = tm->m_Systems[ i ];
  870. if ( !sys->CanQuit( "OnUnload" ) )
  871. {
  872. Msg( "Can't unload %s, %s not ready to exit\n",
  873. pModule, sys->GetToolName() );
  874. return;
  875. }
  876. }
  877. }
  878. for ( int i = tm->m_Systems.Count() - 1; i >= 0; --i )
  879. {
  880. IToolSystem *sys = tm->m_Systems[ i ];
  881. int idx = m_ToolSystems.Find( sys );
  882. if ( idx == m_nActiveToolIndex )
  883. {
  884. sys->OnToolDeactivate();
  885. m_nActiveToolIndex = -1;
  886. }
  887. sys->Shutdown();
  888. sys->ServerShutdown();
  889. sys->ClientShutdown();
  890. m_ToolSystems.Remove( idx );
  891. }
  892. tm->m_pDictionary->Shutdown();
  893. tm->m_pDictionary->Disconnect();
  894. // This (should) discards and material proxies being held onto by any materials in the tool
  895. materials->UncacheUnusedMaterials( false );
  896. Sys_UnloadModule( tm->m_pModule );
  897. for ( int i = 0; i < m_Modules.Count(); ++i )
  898. {
  899. if ( m_Modules[ i ].m_pModule == tm->m_pModule )
  900. {
  901. m_Modules.Remove( i );
  902. break;
  903. }
  904. }
  905. // Switch to another tool, or set the active index to -1 if none left!!!
  906. SwitchToTool( 0 );
  907. }
  908. void Tool_Load_f( const CCommand &args )
  909. {
  910. if ( !toolframework->InToolMode() )
  911. return;
  912. if ( args.ArgC() != 2 )
  913. {
  914. ConMsg ("toolload <toolname>: loads a tool\n");
  915. return;
  916. }
  917. char fn[ MAX_PATH ];
  918. Q_FileBase( args.Arg( 1 ), fn, sizeof( fn ) );
  919. CFmtStr module( "tools/%s.dll", fn );
  920. if ( g_ToolFrameworkInternal.Find( module ) )
  921. {
  922. ConMsg( "module %s already loaded\n", module.Access() );
  923. return;
  924. }
  925. g_ToolFrameworkInternal.LoadToolModule( fn, true );
  926. }
  927. static ConCommand ToolLoad( "toolload", Tool_Load_f, "Load a tool.", 0, g_ToolLoad_CompletionFunc );
  928. //-----------------------------------------------------------------------------
  929. // Purpose: Level init, shutdown
  930. // Input : -
  931. //-----------------------------------------------------------------------------
  932. void CToolFrameworkInternal::ClientLevelInitPreEntityAllTools()
  933. {
  934. InvokeMethod( &IToolSystem::ClientLevelInitPreEntity );
  935. }
  936. //-----------------------------------------------------------------------------
  937. // Purpose:
  938. // Input : -
  939. //-----------------------------------------------------------------------------
  940. void CToolFrameworkInternal::ClientLevelInitPostEntityAllTools()
  941. {
  942. InvokeMethod( &IToolSystem::ClientLevelInitPostEntity );
  943. }
  944. //-----------------------------------------------------------------------------
  945. // Purpose:
  946. // Input : -
  947. //-----------------------------------------------------------------------------
  948. void CToolFrameworkInternal::ClientLevelShutdownPreEntityAllTools()
  949. {
  950. InvokeMethod( &IToolSystem::ClientLevelShutdownPreEntity );
  951. }
  952. //-----------------------------------------------------------------------------
  953. // Purpose: Entities are deleted / released here...
  954. //-----------------------------------------------------------------------------
  955. void CToolFrameworkInternal::ClientLevelShutdownPostEntityAllTools()
  956. {
  957. InvokeMethod( &IToolSystem::ClientLevelShutdownPostEntity );
  958. }
  959. //-----------------------------------------------------------------------------
  960. // Purpose:
  961. //-----------------------------------------------------------------------------
  962. void CToolFrameworkInternal::ClientPreRenderAllTools()
  963. {
  964. InvokeMethod( &IToolSystem::ClientPreRender );
  965. }
  966. //-----------------------------------------------------------------------------
  967. // Purpose:
  968. //-----------------------------------------------------------------------------
  969. bool CToolFrameworkInternal::IsThirdPersonCamera()
  970. {
  971. if ( m_nActiveToolIndex >= 0 )
  972. {
  973. IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
  974. Assert( tool );
  975. return tool->IsThirdPersonCamera( );
  976. }
  977. return false;
  978. }
  979. // is the current tool recording?
  980. bool CToolFrameworkInternal::IsToolRecording()
  981. {
  982. if ( m_nActiveToolIndex >= 0 )
  983. {
  984. IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
  985. Assert( tool );
  986. return tool->IsToolRecording( );
  987. }
  988. return false;
  989. }
  990. //-----------------------------------------------------------------------------
  991. // Purpose:
  992. //-----------------------------------------------------------------------------
  993. void CToolFrameworkInternal::ClientPostRenderAllTools()
  994. {
  995. InvokeMethod( &IToolSystem::ClientPostRender );
  996. }
  997. //-----------------------------------------------------------------------------
  998. // Purpose: Level init, shutdown
  999. //-----------------------------------------------------------------------------
  1000. void CToolFrameworkInternal::ServerLevelInitPreEntityAllTools()
  1001. {
  1002. InvokeMethod( &IToolSystem::ServerLevelInitPreEntity );
  1003. }
  1004. //-----------------------------------------------------------------------------
  1005. // Purpose: entities are created / spawned / precached here
  1006. // Input : -
  1007. //-----------------------------------------------------------------------------
  1008. void CToolFrameworkInternal::ServerLevelInitPostEntityAllTools()
  1009. {
  1010. InvokeMethod( &IToolSystem::ServerLevelInitPostEntity );
  1011. }
  1012. //-----------------------------------------------------------------------------
  1013. // Purpose:
  1014. // Input : -
  1015. //-----------------------------------------------------------------------------
  1016. void CToolFrameworkInternal::ServerLevelShutdownPreEntityAllTools()
  1017. {
  1018. InvokeMethod( &IToolSystem::ServerLevelShutdownPreEntity );
  1019. }
  1020. //-----------------------------------------------------------------------------
  1021. // Purpose: Entities are deleted / released here...
  1022. // Input : -
  1023. //-----------------------------------------------------------------------------
  1024. void CToolFrameworkInternal::ServerLevelShutdownPostEntityAllTools()
  1025. {
  1026. InvokeMethod( &IToolSystem::ServerLevelShutdownPostEntity );
  1027. }
  1028. //-----------------------------------------------------------------------------
  1029. // Purpose: Called each frame before entities think
  1030. // Input : -
  1031. //-----------------------------------------------------------------------------
  1032. void CToolFrameworkInternal::ServerFrameUpdatePreEntityThinkAllTools()
  1033. {
  1034. InvokeMethod( &IToolSystem::ServerFrameUpdatePreEntityThink );
  1035. }
  1036. //-----------------------------------------------------------------------------
  1037. // Purpose: Called after entities think
  1038. // Input : -
  1039. //-----------------------------------------------------------------------------
  1040. void CToolFrameworkInternal::ServerFrameUpdatePostEntityThinkAllTools()
  1041. {
  1042. InvokeMethod( &IToolSystem::ServerFrameUpdatePostEntityThink );
  1043. }
  1044. //-----------------------------------------------------------------------------
  1045. // Purpose: Called before client networking occurs on the server
  1046. // Input : -
  1047. //-----------------------------------------------------------------------------
  1048. void CToolFrameworkInternal::ServerPreClientUpdateAllTools()
  1049. {
  1050. InvokeMethod( &IToolSystem::ServerPreClientUpdate );
  1051. }
  1052. //-----------------------------------------------------------------------------
  1053. // The server uses this to call into the tools to get the actual
  1054. // entities to spawn on startup
  1055. //-----------------------------------------------------------------------------
  1056. const char* CToolFrameworkInternal::GetEntityData( const char *pActualEntityData )
  1057. {
  1058. if ( m_nActiveToolIndex >= 0 )
  1059. {
  1060. IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
  1061. Assert( tool );
  1062. return tool->GetEntityData( pActualEntityData );
  1063. }
  1064. return pActualEntityData;
  1065. }
  1066. void* CToolFrameworkInternal::QueryInterface( const char *pInterfaceName )
  1067. {
  1068. int toolCount = m_ToolSystems.Count();
  1069. for ( int i = 0; i < toolCount; ++i )
  1070. {
  1071. IToolSystem *tool = m_ToolSystems[ i ];
  1072. Assert( tool );
  1073. void *pRet = tool->QueryInterface( pInterfaceName );
  1074. if ( pRet )
  1075. return pRet;
  1076. }
  1077. return NULL;
  1078. }
  1079. void CToolFrameworkInternal::ServerPreSetupVisibilityAllTools()
  1080. {
  1081. InvokeMethod( &IToolSystem::ServerPreSetupVisibility );
  1082. }
  1083. //-----------------------------------------------------------------------------
  1084. // Purpose: Post a message to tools
  1085. // Input : hEntity -
  1086. // *msg -
  1087. //-----------------------------------------------------------------------------
  1088. void CToolFrameworkInternal::PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg )
  1089. {
  1090. // FIXME: Only message topmost tool?
  1091. int toolCount = m_ToolSystems.Count();
  1092. for ( int i = 0; i < toolCount; ++i )
  1093. {
  1094. IToolSystem *tool = m_ToolSystems[ i ];
  1095. Assert( tool );
  1096. tool->PostToolMessage( hEntity, msg );
  1097. }
  1098. }
  1099. //-----------------------------------------------------------------------------
  1100. // Purpose: Only active tool gets to adjust viewport
  1101. // Input : x -
  1102. // y -
  1103. // width -
  1104. // height -
  1105. //-----------------------------------------------------------------------------
  1106. void CToolFrameworkInternal::AdjustEngineViewport( int& x, int& y, int& width, int& height )
  1107. {
  1108. if ( m_nActiveToolIndex >= 0 )
  1109. {
  1110. IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
  1111. Assert( tool );
  1112. tool->AdjustEngineViewport( x, y, width, height );
  1113. }
  1114. }
  1115. //-----------------------------------------------------------------------------
  1116. // Purpose: Only active tool gets to set the camera/view
  1117. //-----------------------------------------------------------------------------
  1118. bool CToolFrameworkInternal::SetupEngineView( Vector &origin, QAngle &angles, float &fov )
  1119. {
  1120. if ( m_nActiveToolIndex < 0 )
  1121. return false;
  1122. IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
  1123. Assert( tool );
  1124. return tool->SetupEngineView( origin, angles, fov );
  1125. }
  1126. //-----------------------------------------------------------------------------
  1127. // Purpose: Only active tool gets to set the microphone
  1128. //-----------------------------------------------------------------------------
  1129. bool CToolFrameworkInternal::SetupAudioState( AudioState_t &audioState )
  1130. {
  1131. if ( m_nActiveToolIndex < 0 )
  1132. return false;
  1133. IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
  1134. Assert( tool );
  1135. return tool->SetupAudioState( audioState );
  1136. }
  1137. //-----------------------------------------------------------------------------
  1138. // Purpose:
  1139. // Input : -
  1140. //-----------------------------------------------------------------------------
  1141. void CToolFrameworkInternal::VGui_PreRenderAllTools( int paintMode )
  1142. {
  1143. InvokeMethodInt( &IToolSystem::VGui_PreRender, paintMode );
  1144. }
  1145. //-----------------------------------------------------------------------------
  1146. // Purpose:
  1147. // Input : -
  1148. //-----------------------------------------------------------------------------
  1149. void CToolFrameworkInternal::VGui_PostRenderAllTools( int paintMode )
  1150. {
  1151. InvokeMethodInt( &IToolSystem::VGui_PostRender, paintMode );
  1152. }
  1153. void CToolFrameworkInternal::VGui_PreSimulateAllTools()
  1154. {
  1155. InvokeMethod( &IToolSystem::VGui_PreSimulate );
  1156. }
  1157. void CToolFrameworkInternal::VGui_PostSimulateAllTools()
  1158. {
  1159. InvokeMethod( &IToolSystem::VGui_PostSimulate );
  1160. }
  1161. //-----------------------------------------------------------------------------
  1162. // Purpose:
  1163. // Input : -
  1164. // Output : int
  1165. //-----------------------------------------------------------------------------
  1166. int CToolFrameworkInternal::GetToolCount()
  1167. {
  1168. return m_ToolSystems.Count();
  1169. }
  1170. //-----------------------------------------------------------------------------
  1171. // Purpose:
  1172. // Input : index -
  1173. // Output : const char
  1174. //-----------------------------------------------------------------------------
  1175. const char *CToolFrameworkInternal::GetToolName( int index )
  1176. {
  1177. if ( index < 0 || index >= m_ToolSystems.Count() )
  1178. {
  1179. return "";
  1180. }
  1181. IToolSystem *sys = m_ToolSystems[ index ];
  1182. if ( sys )
  1183. {
  1184. return sys->GetToolName();
  1185. }
  1186. return "";
  1187. }
  1188. //-----------------------------------------------------------------------------
  1189. // Purpose:
  1190. // Input : index -
  1191. //-----------------------------------------------------------------------------
  1192. void CToolFrameworkInternal::SwitchToTool( int index )
  1193. {
  1194. if ( ( m_ToolSystems.Count() < 1 ) || ( index >= m_ToolSystems.Count() ) )
  1195. {
  1196. m_nActiveToolIndex = -1;
  1197. return;
  1198. }
  1199. if ( index != m_nActiveToolIndex )
  1200. {
  1201. if ( m_nActiveToolIndex >= 0 )
  1202. {
  1203. IToolSystem *pOldTool = m_ToolSystems[ m_nActiveToolIndex ];
  1204. pOldTool->OnToolDeactivate();
  1205. }
  1206. m_nActiveToolIndex = index;
  1207. if ( m_nActiveToolIndex >= 0 )
  1208. {
  1209. IToolSystem *pNewTool = m_ToolSystems[ m_nActiveToolIndex ];
  1210. pNewTool->OnToolActivate();
  1211. }
  1212. }
  1213. }
  1214. //-----------------------------------------------------------------------------
  1215. // Switches to a named tool
  1216. //-----------------------------------------------------------------------------
  1217. IToolSystem *CToolFrameworkInternal::SwitchToTool( const char* pToolName )
  1218. {
  1219. int nCount = GetToolCount();
  1220. for ( int i = 0; i < nCount; ++i )
  1221. {
  1222. if ( !Q_stricmp( pToolName, GetToolName(i) ) )
  1223. {
  1224. SwitchToTool( i );
  1225. return m_ToolSystems[i];
  1226. }
  1227. }
  1228. return NULL;
  1229. }
  1230. //-----------------------------------------------------------------------------
  1231. // Purpose:
  1232. // Input : *sys -
  1233. // Output : Returns true on success, false on failure.
  1234. //-----------------------------------------------------------------------------
  1235. bool CToolFrameworkInternal::IsTopmostTool( const IToolSystem *sys )
  1236. {
  1237. if ( m_ToolSystems.Count() <= 0 || ( m_nActiveToolIndex < 0 ) )
  1238. return false;
  1239. return ( m_ToolSystems[ m_nActiveToolIndex ] == sys );
  1240. }
  1241. IToolSystem *CToolFrameworkInternal::GetTopmostTool()
  1242. {
  1243. return m_nActiveToolIndex >= 0 ? m_ToolSystems[ m_nActiveToolIndex ] : NULL;
  1244. }
  1245. //-----------------------------------------------------------------------------
  1246. // returns a tool system by index
  1247. //-----------------------------------------------------------------------------
  1248. const IToolSystem *CToolFrameworkInternal::GetToolSystem( int index ) const
  1249. {
  1250. if ( ( index < 0 ) || ( index >= m_ToolSystems.Count() ) )
  1251. return NULL;
  1252. return m_ToolSystems[index];
  1253. }
  1254. void CToolFrameworkInternal::PostMessage( KeyValues *msg )
  1255. {
  1256. if ( m_nActiveToolIndex >= 0 )
  1257. {
  1258. IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
  1259. Assert( tool );
  1260. tool->PostToolMessage( 0, msg );
  1261. }
  1262. }
  1263. bool CToolFrameworkInternal::GetSoundSpatialization( int iUserData, int guid, SpatializationInfo_t& info )
  1264. {
  1265. if ( m_nActiveToolIndex >= 0 )
  1266. {
  1267. IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
  1268. Assert( tool );
  1269. return tool->GetSoundSpatialization( iUserData, guid, info );
  1270. }
  1271. return true;
  1272. }
  1273. void CToolFrameworkInternal::HostRunFrameBegin()
  1274. {
  1275. InvokeMethod( &IToolSystem::HostRunFrameBegin );
  1276. }
  1277. void CToolFrameworkInternal::HostRunFrameEnd()
  1278. {
  1279. InvokeMethod( &IToolSystem::HostRunFrameEnd );
  1280. }
  1281. //-----------------------------------------------------------------------------
  1282. // Purpose:
  1283. // Input : -
  1284. //-----------------------------------------------------------------------------
  1285. void CToolFrameworkInternal::RenderFrameBegin()
  1286. {
  1287. #ifndef DEDICATED
  1288. ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 );
  1289. #endif
  1290. InvokeMethod( &IToolSystem::RenderFrameBegin );
  1291. }
  1292. //-----------------------------------------------------------------------------
  1293. // Purpose:
  1294. // Input : -
  1295. //-----------------------------------------------------------------------------
  1296. void CToolFrameworkInternal::RenderFrameEnd()
  1297. {
  1298. #ifndef DEDICATED
  1299. ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 );
  1300. #endif
  1301. InvokeMethod( &IToolSystem::RenderFrameEnd );
  1302. }
  1303. // Exposed because it's an IAppSystem
  1304. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CToolFrameworkInternal, IToolFrameworkInternal, VTOOLFRAMEWORK_INTERFACE_VERSION, g_ToolFrameworkInternal );
  1305. //-----------------------------------------------------------------------------
  1306. // Purpose: exposed from engine to client .dll
  1307. //-----------------------------------------------------------------------------
  1308. class CClientEngineTools : public IClientEngineTools
  1309. {
  1310. public:
  1311. virtual void LevelInitPreEntityAllTools();
  1312. virtual void LevelInitPostEntityAllTools();
  1313. virtual void LevelShutdownPreEntityAllTools();
  1314. virtual void LevelShutdownPostEntityAllTools();
  1315. virtual void PreRenderAllTools();
  1316. virtual void PostRenderAllTools();
  1317. virtual void PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg );
  1318. virtual void AdjustEngineViewport( int& x, int& y, int& width, int& height );
  1319. virtual bool SetupEngineView( Vector &origin, QAngle &angles, float &fov );
  1320. virtual bool SetupAudioState( AudioState_t &audioState );
  1321. virtual void VGui_PreRenderAllTools( int paintMode );
  1322. virtual void VGui_PostRenderAllTools( int paintMode );
  1323. virtual bool IsThirdPersonCamera( );
  1324. virtual bool InToolMode();
  1325. };
  1326. EXPOSE_SINGLE_INTERFACE( CClientEngineTools, IClientEngineTools, VCLIENTENGINETOOLS_INTERFACE_VERSION );
  1327. //-----------------------------------------------------------------------------
  1328. // Purpose:
  1329. // Input : -
  1330. //-----------------------------------------------------------------------------
  1331. void CClientEngineTools::LevelInitPreEntityAllTools()
  1332. {
  1333. g_ToolFrameworkInternal.ClientLevelInitPreEntityAllTools();
  1334. }
  1335. //-----------------------------------------------------------------------------
  1336. // Purpose:
  1337. // Input : -
  1338. //-----------------------------------------------------------------------------
  1339. void CClientEngineTools::LevelInitPostEntityAllTools()
  1340. {
  1341. g_ToolFrameworkInternal.ClientLevelInitPostEntityAllTools();
  1342. }
  1343. //-----------------------------------------------------------------------------
  1344. // Purpose:
  1345. // Input : -
  1346. //-----------------------------------------------------------------------------
  1347. void CClientEngineTools::LevelShutdownPreEntityAllTools()
  1348. {
  1349. g_ToolFrameworkInternal.ClientLevelShutdownPreEntityAllTools();
  1350. }
  1351. //-----------------------------------------------------------------------------
  1352. // Purpose:
  1353. // Input : -
  1354. //-----------------------------------------------------------------------------
  1355. void CClientEngineTools::LevelShutdownPostEntityAllTools()
  1356. {
  1357. g_ToolFrameworkInternal.ClientLevelShutdownPostEntityAllTools();
  1358. }
  1359. //-----------------------------------------------------------------------------
  1360. // Purpose:
  1361. // Input : -
  1362. //-----------------------------------------------------------------------------
  1363. void CClientEngineTools::PreRenderAllTools()
  1364. {
  1365. g_ToolFrameworkInternal.ClientPreRenderAllTools();
  1366. }
  1367. //-----------------------------------------------------------------------------
  1368. // Purpose:
  1369. // Input : -
  1370. //-----------------------------------------------------------------------------
  1371. void CClientEngineTools::PostRenderAllTools()
  1372. {
  1373. g_ToolFrameworkInternal.ClientPostRenderAllTools();
  1374. }
  1375. //-----------------------------------------------------------------------------
  1376. // Purpose:
  1377. // Input : hEntity -
  1378. // *msg -
  1379. //-----------------------------------------------------------------------------
  1380. void CClientEngineTools::PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg )
  1381. {
  1382. g_ToolFrameworkInternal.PostToolMessage( hEntity, msg );
  1383. }
  1384. //-----------------------------------------------------------------------------
  1385. // Purpose:
  1386. // Input : x -
  1387. // y -
  1388. // width -
  1389. // height -
  1390. //-----------------------------------------------------------------------------
  1391. void CClientEngineTools::AdjustEngineViewport( int& x, int& y, int& width, int& height )
  1392. {
  1393. g_ToolFrameworkInternal.AdjustEngineViewport( x, y, width, height );
  1394. }
  1395. bool CClientEngineTools::SetupEngineView( Vector &origin, QAngle &angles, float &fov )
  1396. {
  1397. return g_ToolFrameworkInternal.SetupEngineView( origin, angles, fov );
  1398. }
  1399. bool CClientEngineTools::SetupAudioState( AudioState_t &audioState )
  1400. {
  1401. return g_ToolFrameworkInternal.SetupAudioState( audioState );
  1402. }
  1403. //-----------------------------------------------------------------------------
  1404. // Purpose:
  1405. //-----------------------------------------------------------------------------
  1406. void CClientEngineTools::VGui_PreRenderAllTools( int paintMode )
  1407. {
  1408. g_ToolFrameworkInternal.VGui_PreRenderAllTools( paintMode );
  1409. }
  1410. //-----------------------------------------------------------------------------
  1411. // Purpose:
  1412. //-----------------------------------------------------------------------------
  1413. void CClientEngineTools::VGui_PostRenderAllTools( int paintMode )
  1414. {
  1415. g_ToolFrameworkInternal.VGui_PostRenderAllTools( paintMode );
  1416. }
  1417. //-----------------------------------------------------------------------------
  1418. // Purpose:
  1419. //-----------------------------------------------------------------------------
  1420. bool CClientEngineTools::IsThirdPersonCamera( )
  1421. {
  1422. return g_ToolFrameworkInternal.IsThirdPersonCamera( );
  1423. }
  1424. bool CClientEngineTools::InToolMode()
  1425. {
  1426. return g_ToolFrameworkInternal.InToolMode();
  1427. }
  1428. //-----------------------------------------------------------------------------
  1429. // Purpose: Exposed to server.dll
  1430. //-----------------------------------------------------------------------------
  1431. class CServerEngineTools : public IServerEngineTools
  1432. {
  1433. public:
  1434. // Inherited from IServerEngineTools
  1435. virtual void LevelInitPreEntityAllTools();
  1436. virtual void LevelInitPostEntityAllTools();
  1437. virtual void LevelShutdownPreEntityAllTools();
  1438. virtual void LevelShutdownPostEntityAllTools();
  1439. virtual void FrameUpdatePreEntityThinkAllTools();
  1440. virtual void FrameUpdatePostEntityThinkAllTools();
  1441. virtual void PreClientUpdateAllTools();
  1442. virtual void PreSetupVisibilityAllTools();
  1443. virtual const char* GetEntityData( const char *pActualEntityData );
  1444. virtual void* QueryInterface( const char *pInterfaceName );
  1445. virtual bool InToolMode();
  1446. };
  1447. EXPOSE_SINGLE_INTERFACE( CServerEngineTools, IServerEngineTools, VSERVERENGINETOOLS_INTERFACE_VERSION );
  1448. //-----------------------------------------------------------------------------
  1449. // Purpose:
  1450. // Input : -
  1451. //-----------------------------------------------------------------------------
  1452. void CServerEngineTools::LevelInitPreEntityAllTools()
  1453. {
  1454. g_ToolFrameworkInternal.ServerLevelInitPreEntityAllTools();
  1455. }
  1456. //-----------------------------------------------------------------------------
  1457. // Purpose:
  1458. // Input : -
  1459. //-----------------------------------------------------------------------------
  1460. void CServerEngineTools::LevelInitPostEntityAllTools()
  1461. {
  1462. g_ToolFrameworkInternal.ServerLevelInitPostEntityAllTools();
  1463. }
  1464. //-----------------------------------------------------------------------------
  1465. // Purpose:
  1466. // Input : -
  1467. //-----------------------------------------------------------------------------
  1468. void CServerEngineTools::LevelShutdownPreEntityAllTools()
  1469. {
  1470. g_ToolFrameworkInternal.ServerLevelShutdownPreEntityAllTools();
  1471. }
  1472. //-----------------------------------------------------------------------------
  1473. // Purpose:
  1474. // Input : -
  1475. //-----------------------------------------------------------------------------
  1476. void CServerEngineTools::LevelShutdownPostEntityAllTools()
  1477. {
  1478. g_ToolFrameworkInternal.ServerLevelShutdownPostEntityAllTools();
  1479. }
  1480. //-----------------------------------------------------------------------------
  1481. // Purpose:
  1482. // Input : -
  1483. //-----------------------------------------------------------------------------
  1484. void CServerEngineTools::FrameUpdatePreEntityThinkAllTools()
  1485. {
  1486. g_ToolFrameworkInternal.ServerFrameUpdatePreEntityThinkAllTools();
  1487. }
  1488. //-----------------------------------------------------------------------------
  1489. // Purpose:
  1490. // Input : -
  1491. //-----------------------------------------------------------------------------
  1492. void CServerEngineTools::FrameUpdatePostEntityThinkAllTools()
  1493. {
  1494. g_ToolFrameworkInternal.ServerFrameUpdatePostEntityThinkAllTools();
  1495. }
  1496. //-----------------------------------------------------------------------------
  1497. // Purpose:
  1498. // Input : -
  1499. //-----------------------------------------------------------------------------
  1500. void CServerEngineTools::PreClientUpdateAllTools()
  1501. {
  1502. g_ToolFrameworkInternal.ServerPreClientUpdateAllTools();
  1503. }
  1504. //-----------------------------------------------------------------------------
  1505. // The server uses this to call into the tools to get the actual
  1506. // entities to spawn on startup
  1507. //-----------------------------------------------------------------------------
  1508. const char* CServerEngineTools::GetEntityData( const char *pActualEntityData )
  1509. {
  1510. return g_ToolFrameworkInternal.GetEntityData( pActualEntityData );
  1511. }
  1512. void* CServerEngineTools::QueryInterface( const char *pInterfaceName )
  1513. {
  1514. return g_ToolFrameworkInternal.QueryInterface( pInterfaceName );
  1515. }
  1516. void CServerEngineTools::PreSetupVisibilityAllTools()
  1517. {
  1518. return g_ToolFrameworkInternal.ServerPreSetupVisibilityAllTools();
  1519. }
  1520. bool CServerEngineTools::InToolMode()
  1521. {
  1522. return g_ToolFrameworkInternal.InToolMode();
  1523. }