//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //===========================================================================// #include "cbase.h" #include "toolframework_client.h" #include "igamesystem.h" #include "tier1/KeyValues.h" #include "toolframework/iclientenginetools.h" #include "client_factorylist.h" #include "iviewrender.h" #include "materialsystem/imaterialvar.h" extern IViewRender *view; class CToolFrameworkClient : public CBaseGameSystemPerFrame { public: // Methods of IGameSystem virtual bool Init(); virtual void LevelInitPreEntity(); virtual void LevelInitPostEntity(); virtual void LevelShutdownPreEntity(); virtual void LevelShutdownPostEntity(); virtual void PreRender(); virtual void PostRender(); public: // Other public methods void PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg ); void AdjustEngineViewport( int& x, int& y, int& width, int& height ); bool SetupEngineView( Vector &origin, QAngle &angles, float &fov ); bool SetupAudioState( AudioState_t &audioState ); bool IsThirdPersonCamera(); IClientEngineTools *m_pTools; }; //----------------------------------------------------------------------------- // Singleton //----------------------------------------------------------------------------- static CToolFrameworkClient g_ToolFrameworkClient; #ifndef NO_TOOLFRAMEWORK bool ToolsEnabled() { return g_ToolFrameworkClient.m_pTools && g_ToolFrameworkClient.m_pTools->InToolMode(); } #endif IGameSystem *ToolFrameworkClientSystem() { return &g_ToolFrameworkClient; } bool CToolFrameworkClient::Init() { factorylist_t list; FactoryList_Retrieve( list ); m_pTools = ( IClientEngineTools * )list.appSystemFactory( VCLIENTENGINETOOLS_INTERFACE_VERSION, NULL ); return ( m_pTools != NULL ); } void CToolFrameworkClient::LevelInitPreEntity() { if ( m_pTools ) { m_pTools->LevelInitPreEntityAllTools(); } } void CToolFrameworkClient::LevelInitPostEntity() { if ( m_pTools ) { m_pTools->LevelInitPostEntityAllTools(); } } void CToolFrameworkClient::LevelShutdownPreEntity() { if ( m_pTools ) { m_pTools->LevelShutdownPreEntityAllTools(); } } void CToolFrameworkClient::LevelShutdownPostEntity() { if ( m_pTools ) { m_pTools->LevelShutdownPostEntityAllTools(); } } void CToolFrameworkClient::PreRender() { if ( m_pTools ) { m_pTools->PreRenderAllTools(); } } void CToolFrameworkClient::PostRender() { if ( m_pTools ) { m_pTools->PostRenderAllTools(); } } //----------------------------------------------------------------------------- // Should we render with a 3rd person camera? //----------------------------------------------------------------------------- bool CToolFrameworkClient::IsThirdPersonCamera() { if ( !m_pTools ) return false; return m_pTools->IsThirdPersonCamera( ); } bool ToolFramework_IsThirdPersonCamera( ) { return g_ToolFrameworkClient.IsThirdPersonCamera( ); } //----------------------------------------------------------------------------- // Posts a message to all tools //----------------------------------------------------------------------------- void CToolFrameworkClient::PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg ) { if ( m_pTools ) { m_pTools->PostToolMessage( hEntity, msg ); } } void ToolFramework_PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg ) { g_ToolFrameworkClient.PostToolMessage( hEntity, msg ); } //----------------------------------------------------------------------------- // View manipulation //----------------------------------------------------------------------------- void CToolFrameworkClient::AdjustEngineViewport( int& x, int& y, int& width, int& height ) { if ( m_pTools ) { m_pTools->AdjustEngineViewport( x, y, width, height ); } } void ToolFramework_AdjustEngineViewport( int& x, int& y, int& width, int& height ) { g_ToolFrameworkClient.AdjustEngineViewport( x, y, width, height ); } //----------------------------------------------------------------------------- // View manipulation //----------------------------------------------------------------------------- bool CToolFrameworkClient::SetupEngineView( Vector &origin, QAngle &angles, float &fov ) { if ( !m_pTools ) return false; return m_pTools->SetupEngineView( origin, angles, fov ); } bool ToolFramework_SetupEngineView( Vector &origin, QAngle &angles, float &fov ) { return g_ToolFrameworkClient.SetupEngineView( origin, angles, fov ); } //----------------------------------------------------------------------------- // microphone manipulation //----------------------------------------------------------------------------- bool CToolFrameworkClient::SetupAudioState( AudioState_t &audioState ) { if ( !m_pTools ) return false; return m_pTools->SetupAudioState( audioState ); } bool ToolFramework_SetupAudioState( AudioState_t &audioState ) { return g_ToolFrameworkClient.SetupAudioState( audioState ); } //----------------------------------------------------------------------------- // Helper class to indicate ownership of effects //----------------------------------------------------------------------------- CRecordEffectOwner::CRecordEffectOwner( C_BaseEntity *pEntity, bool bIsViewModel ) { m_bToolsEnabled = ToolsEnabled() && clienttools->IsInRecordingMode(); if ( m_bToolsEnabled ) { KeyValues *msg = new KeyValues( "EffectsOwner" ); msg->SetInt( "viewModel", bIsViewModel ); ToolFramework_PostToolMessage( pEntity ? pEntity->GetToolHandle() : HTOOLHANDLE_INVALID, msg ); msg->deleteThis(); } } CRecordEffectOwner::~CRecordEffectOwner() { if ( m_bToolsEnabled ) { KeyValues *msg = new KeyValues( "EffectsOwner" ); ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg ); msg->deleteThis(); } } //----------------------------------------------------------------------------- // material recording - primarily for proxy materials //----------------------------------------------------------------------------- void WriteFloat( char *&buf, float f) { *( float* )buf = f; buf += sizeof( float ); } void WriteInt( char *&buf, int i ) { *( int* )buf = i; buf += sizeof( int ); } void WritePtr( char *&buf, void *p ) { *( void** )buf = p; buf += sizeof( void* ); } void ToolFramework_RecordMaterialParams( IMaterial *pMaterial ) { Assert( pMaterial ); if ( !pMaterial ) return; if ( !clienttools->IsInRecordingMode() ) return; C_BaseEntity *pEnt = view->GetCurrentlyDrawingEntity(); if ( !pEnt || !pEnt->IsToolRecording() ) return; KeyValues *msg = new KeyValues( "material_proxy_state" ); msg->SetString( "mtlName", pMaterial->GetName() ); msg->SetString( "groupName", pMaterial->GetTextureGroupName() ); int nParams = pMaterial->ShaderParamCount(); IMaterialVar **pParams = pMaterial->GetShaderParams(); char str[ 256 ]; for ( int i = 0; i < nParams; ++i ) { IMaterialVar *pVar = pParams[ i ]; const char *pVarName = pVar->GetName(); MaterialVarType_t vartype = pVar->GetType(); switch ( vartype ) { case MATERIAL_VAR_TYPE_FLOAT: msg->SetFloat( pVarName, pVar->GetFloatValue() ); break; case MATERIAL_VAR_TYPE_INT: msg->SetInt( pVarName, pVar->GetIntValue() ); break; case MATERIAL_VAR_TYPE_STRING: msg->SetString( pVarName, pVar->GetStringValue() ); break; case MATERIAL_VAR_TYPE_FOURCC: Assert( 0 ); // JDTODO break; case MATERIAL_VAR_TYPE_VECTOR: { const float *pVal = pVar->GetVecValue(); int dim = pVar->VectorSize(); switch ( dim ) { case 2: V_snprintf( str, sizeof( str ), "vector2d: %f %f", pVal[ 0 ], pVal[ 1 ] ); break; case 3: V_snprintf( str, sizeof( str ), "vector3d: %f %f %f", pVal[ 0 ], pVal[ 1 ], pVal[ 2 ] ); break; case 4: V_snprintf( str, sizeof( str ), "vector4d: %f %f %f %f", pVal[ 0 ], pVal[ 1 ], pVal[ 2 ], pVal[ 3 ] ); break; default: Assert( 0 ); *str = 0; } msg->SetString( pVarName, str ); } break; case MATERIAL_VAR_TYPE_MATRIX: { const VMatrix &matrix = pVar->GetMatrixValue(); const float *pVal = matrix.Base(); V_snprintf( str, sizeof( str ), "matrix: %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f", pVal[ 0 ], pVal[ 1 ], pVal[ 2 ], pVal[ 3 ], pVal[ 4 ], pVal[ 5 ], pVal[ 6 ], pVal[ 7 ], pVal[ 8 ], pVal[ 9 ], pVal[ 10 ], pVal[ 11 ], pVal[ 12 ], pVal[ 13 ], pVal[ 14 ], pVal[ 15 ] ); msg->SetString( pVarName, str ); } break; case MATERIAL_VAR_TYPE_TEXTURE: // V_snprintf( str, sizeof( str ), "texture: %x", pVar->GetTextureValue() ); // msg->SetString( pVarName, str ); break; case MATERIAL_VAR_TYPE_MATERIAL: // V_snprintf( str, sizeof( str ), "material: %x", pVar->GetMaterialValue() ); // msg->SetString( pVarName, str ); break; case MATERIAL_VAR_TYPE_UNDEFINED: // Assert( 0 ); // these appear to be (mostly? all?) textures, although I don't know why they're not caught by the texture case above... break; // JDTODO default: Assert( 0 ); } } Assert( pEnt->GetToolHandle() ); ToolFramework_PostToolMessage( pEnt->GetToolHandle(), msg ); msg->deleteThis(); }