|
|
//====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose: Implmentation of IEngineTool callback interface
// Tool .dlls can call back through this interface to talk to the engine
//
//=============================================================================
#include "ienginetoolinternal.h"
#include "EngineSoundInternal.h"
#include "vengineserver_impl.h"
#include "cdll_engine_int.h"
#include "toolframework/ienginetool.h"
#include "client.h"
#include "server.h"
#include "con_nprint.h"
#include "toolframework/itoolframework.h"
#include "sound.h"
#include "screen.h"
#include "render.h"
#include "gl_matsysiface.h"
#include "cl_main.h"
#include "sys_dll.h"
#include "ivideomode.h"
#include "voice.h"
#include "filesystem_engine.h"
#include "enginetrace.h"
#include "Overlay.h"
#include "r_efx.h"
#include "r_local.h"
#include "lightcache.h"
#include "ispatialpartitioninternal.h"
#include "networkstringtableserver.h"
#include "networkstringtable.h"
#include "igame.h"
#include "gl_rmain.h"
#ifndef DEDICATED
#include "vgui_baseui_interface.h"
#endif
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
// External variables and APIs needed
extern CSysModule *g_GameDLL; extern ConVar host_timescale; extern CGlobalVars g_ServerGlobalVariables; void SV_ForceSend(); CreateInterfaceFn ClientDLL_GetFactory( void ); extern CNetworkStringTableContainer *networkStringTableContainerServer;
IOverlayMgr *OverlayMgr();
void SV_ForceSend();
extern ConVar host_framerate;
void CL_StartMovie( const char *filename, int flags, int nWidth, int nHeight, float flFrameRate, int jpeg_quality ); void CL_EndMovie(); bool CL_IsRecordingMovie(); void VGui_SetGameDLLPanelsVisible( bool show ); float AudioSource_GetSoundDuration( char const *pName );
//-----------------------------------------------------------------------------
// Purpose: Singleton implementation of external tools callback interface
//-----------------------------------------------------------------------------
class CEngineTool : public IEngineToolInternal { public: CEngineTool();
// Methods of IEngineToolFramework
// Take over input
virtual void ShowCursor( bool show ); virtual bool IsCursorVisible() const;
// Helpers for implementing a tool switching UI
virtual int GetToolCount() const; virtual const char *GetToolName( int index ) const; virtual void SwitchToTool( int index );
virtual bool IsTopmostTool( const IToolSystem *sys ) const; virtual const IToolSystem *GetToolSystem( int index ) const; virtual IToolSystem *GetTopmostTool();
// If module not already loaded, loads it and optionally switches to first tool in module. Returns false if load failed or tool already loaded
virtual bool LoadToolModule( char const *pToolModule, bool bSwitchToFirst );
public: // Retrieve factories from server.dll and client.dll to get at specific interfaces defined within
virtual void GetServerFactory( CreateInterfaceFn& factory ); virtual void GetClientFactory( CreateInterfaceFn& factory );
// Issue a console command
virtual void Command( const char *cmd ); // Flush console command buffer right away
virtual void Execute();
// If in a level, get name of current level
virtual const char *GetCurrentMap(); virtual void ChangeToMap( const char *mapname ); virtual bool IsMapValid( const char *mapname );
// Method for causing engine to call client to render scene with no view model or overlays
virtual void RenderView( CViewSetup &view, int nFlags, int nWhatToRender );
// Returns true if the player is fully connected and active in game (i.e, not still loading)
virtual bool IsInGame(); // Returns true if the player is connected, but not necessarily active in game (could still be loading)
virtual bool IsConnected();
virtual int GetMaxClients(); // Tools might want to ensure single player, e.g.
virtual bool IsGamePaused(); virtual void SetGamePaused( bool paused );
virtual float GetTimescale(); // host_timescale ConVar multiplied by the game timescale
virtual void SetTimescale( float scale );
// Real time is unscaled, but is updated once per frame
virtual float GetRealTime(); virtual float GetRealFrameTime(); // unscaled
virtual float Time(); // Get high precision timer (for profiling?)
// Host time is scaled
virtual float HostFrameTime(); // host_frametime
virtual float HostTime(); // host_time
virtual int HostTick(); // host_tickcount
virtual int HostFrameCount(); // total famecount
virtual float ServerTime(); // gpGlobals->curtime on server
virtual float ServerFrameTime(); // gpGlobals->frametime on server
virtual int ServerTick(); // gpGlobals->tickcount on server
virtual float ServerTickInterval(); // tick interval on server
virtual float ClientTime(); // gpGlobals->curtime on client
virtual float ClientFrameTime(); // gpGlobals->frametime on client
virtual int ClientTick(); // gpGlobals->tickcount on client
virtual void SetClientFrameTime( float frametime ); // gpGlobals->frametime on client
// Currently the engine doesn't like to do networking when it's paused, but if a tool changes entity state, it can be useful to force
// a network update to get that state over to the client
virtual void ForceUpdateDuringPause();
// Maybe through modelcache???
virtual model_t *GetModel( HTOOLHANDLE hEntity ); // Get the .mdl file used by entity (if it's a cbaseanimating)
virtual studiohdr_t *GetStudioModel( HTOOLHANDLE hEntity );
// SINGLE PLAYER/LISTEN SERVER ONLY (just matching the client .dll api for this)
// Prints the formatted string to the notification area of the screen ( down the right hand edge
// numbered lines starting at position 0
virtual void Con_NPrintf( int pos, const char *fmt, ... ); // SINGLE PLAYER/LISTEN SERVER ONLY(just matching the client .dll api for this)
// Similar to Con_NPrintf, but allows specifying custom text color and duration information
virtual void Con_NXPrintf( const struct con_nprint_s *info, const char *fmt, ... );
// Get the current game directory (hl2, tf2, hl1, cstrike, etc.)
virtual void GetGameDir( char *szGetGameDir, int maxlength );
// Do we need separate rects for the 3d "viewport" vs. the tools surface??? and can we control viewports from
virtual void GetScreenSize( int& width, int &height );
virtual int StartSound( int iUserData, bool staticsound, int iEntIndex, int iChannel, const char *pSample, float flVolume, soundlevel_t iSoundlevel, const Vector& origin, const Vector& direction, int iFlags = 0, int iPitch = PITCH_NORM, bool bUpdatePositions = true, float delay = 0.0f, int speakerentity = -1 );
virtual void StopSoundByGuid( int guid ); virtual void SetVolumeByGuid( int guid, float flVolume ); virtual bool IsSoundStillPlaying( int guid ); virtual bool GetSoundChannelVolume( const char* sound, float &flVolumeLeft, float &flVolumeRight ) { return false; } virtual float GetSoundDuration( int guid ); virtual void ReloadSound( const char *pSample ); virtual void StopAllSounds( ); virtual void SetAudioState( const AudioState_t &audioState ); virtual void SetMainView( const Vector &vecOrigin, const QAngle &angles ); virtual bool GetPlayerView( CViewSetup &playerView, int x, int y, int w, int h ); virtual void CreatePickingRay( const CViewSetup &viewSetup, int x, int y, Vector& org, Vector& forward ); virtual bool IsLoopingSound( int guid );
virtual void InstallQuitHandler( void *pvUserData, FnQuitHandler func ); virtual void TakeTGAScreenShot( const char *filename, int width, int height ); // Even if game is paused, force networking to update to get new server state down to client
virtual void ForceSend();
virtual bool IsRecordingMovie();
// NOTE: Params can contain file name, frame rate, output avi, output raw, and duration
virtual void StartMovieRecording( KeyValues *pMovieParams ); virtual void EndMovieRecording(); virtual void CancelMovieRecording(); virtual AVIHandle_t GetRecordingAVIHandle();
virtual void StartRecordingVoiceToFile( const char *filename, const char *pPathID = 0 ); virtual void StopRecordingVoiceToFile(); virtual bool IsVoiceRecording();
virtual void TraceRay( const Ray_t &ray, unsigned int fMask, ITraceFilter *pTraceFilter, CBaseTrace *pTrace ); virtual void TraceRayServer( const Ray_t &ray, unsigned int fMask, ITraceFilter *pTraceFilter, CBaseTrace *pTrace );
bool CanQuit(); void UpdateScreenshot();
bool ShouldSuppressDeInit() const;
virtual bool IsConsoleVisible(); virtual int GetPointContents( const Vector &vecPosition ); virtual int GetActiveDLights( dlight_t *pList[MAX_DLIGHTS] ); virtual int GetLightingConditions( const Vector &vecPosition, Vector *pColors, int nMaxLocalLights, LightDesc_t *pLocalLights );
// precache methods
virtual bool PrecacheSound( const char *pName, bool bPreload = false ); virtual bool PrecacheModel( const char *pName, bool bPreload = false );
virtual float GetMono16Samples( const char *pszName, CUtlVector< short >& sampleList );
virtual void GetWorldToScreenMatrixForView( const CViewSetup &view, VMatrix *pVMatrix ); virtual SpatialPartitionHandle_t CreatePartitionHandle( IHandleEntity *pEntity, SpatialPartitionListMask_t listMask, const Vector& mins, const Vector& maxs ); virtual void DestroyPartitionHandle( SpatialPartitionHandle_t hPartition ); virtual void InstallPartitionQueryCallback( IPartitionQueryCallback *pQuery ); virtual void RemovePartitionQueryCallback( IPartitionQueryCallback *pQuery ); virtual void ElementMoved( SpatialPartitionHandle_t handle, const Vector& mins, const Vector& maxs );
virtual float GetSoundDuration( const char *pszName );
virtual void ValidateSoundCache( char const *pchSoundName ); virtual void PrefetchSound( char const *pchSoundName );
virtual void* GetEngineHwnd(); virtual void OnModeChanged( bool bGameMode ); public: // Methods of IEngineToolInternal
virtual void SetIsInGame( bool bIsInGame );
virtual float GetSoundElapsedTime( int guid ); virtual bool GetPreventSound( void );
private: bool m_bIsInGame;
struct QuitHandler_t { void *userdata; FnQuitHandler func; };
CUtlVector< QuitHandler_t > m_QuitHandlers;
char m_szScreenshotFile[ MAX_OSPATH ]; int m_nScreenshotWidth; int m_nScreenshotHeight;
bool m_bRecordingMovie; bool m_bSuppressDeInit; char m_szVoiceoverFile[ MAX_OSPATH ]; };
//-----------------------------------------------------------------------------
// Singleton
//-----------------------------------------------------------------------------
static CEngineTool g_EngineTool; IEngineToolInternal *g_pEngineToolInternal = &g_EngineTool;
void EngineTool_InstallQuitHandler( void *pvUserData, FnQuitHandler func ) { g_EngineTool.InstallQuitHandler( pvUserData, func ); }
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool EngineTool_CheckQuitHandlers() { return g_EngineTool.CanQuit(); }
void EngineTool_UpdateScreenshot() { g_EngineTool.UpdateScreenshot(); }
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CEngineTool::CEngineTool() { m_bIsInGame = false; m_szScreenshotFile[ 0 ] = 0; m_nScreenshotWidth = 180; m_nScreenshotHeight = 100;
m_bRecordingMovie = false; m_bSuppressDeInit = false; m_szVoiceoverFile[ 0 ] = 0; }
//-----------------------------------------------------------------------------
// Singleton
//-----------------------------------------------------------------------------
void CEngineTool::ShowCursor( bool show ) { Assert( 0 ); }
bool CEngineTool::IsCursorVisible() const { Assert( 0 ); return true; }
int CEngineTool::GetPointContents( const Vector &vecPosition ) { return g_pEngineTraceClient->GetPointContents( vecPosition, NULL ); }
int CEngineTool::GetActiveDLights( dlight_t *pList[MAX_DLIGHTS] ) { return g_pEfx->CL_GetActiveDLights( pList ); }
bool WorldLightToMaterialLight( dworldlight_t* pWorldLight, LightDesc_t& light );
int CEngineTool::GetLightingConditions( const Vector &vecLightingOrigin, Vector *pColors, int nMaxLocalLights, LightDesc_t *pLocalLights ) { LightcacheGetDynamic_Stats stats; LightingState_t state; LightcacheGetDynamic( vecLightingOrigin, state, stats, NULL ); Assert( state.numlights >= 0 && state.numlights < MAXLOCALLIGHTS ); memcpy( pColors, state.r_boxcolor, sizeof(state.r_boxcolor) );
int nLightCount = 0; for ( int i = 0; i < state.numlights; ++i ) { LightDesc_t *pLightDesc = &pLocalLights[nLightCount]; if (!WorldLightToMaterialLight( state.locallight[i], *pLightDesc )) continue;
// Apply lightstyle
float bias = LightStyleValue( state.locallight[i]->style );
// Deal with overbrighting + bias
pLightDesc->m_Color[0] *= bias; pLightDesc->m_Color[1] *= bias; pLightDesc->m_Color[2] *= bias;
if ( ++nLightCount >= nMaxLocalLights ) break; } return nLightCount; }
void CEngineTool::GetServerFactory( CreateInterfaceFn& factory ) { factory = Sys_GetFactory( g_GameDLL ); }
void CEngineTool::GetClientFactory( CreateInterfaceFn& factory ) { factory = ClientDLL_GetFactory(); }
void CEngineTool::Command( const char *cmd ) { Cbuf_AddText( Cbuf_GetCurrentPlayer(), cmd ); }
void CEngineTool::Execute() { Cbuf_Execute(); }
const char *CEngineTool::GetCurrentMap() { if ( sv.IsDedicated() ) return "Dedicated Server";
if ( !GetBaseLocalClient().IsConnected() ) { if ( sv.IsLoading() ) return sv.GetMapName();
return ""; }
return GetBaseLocalClient().m_szLevelName; }
void CEngineTool::ChangeToMap( const char *mapname ) { if ( modelloader->Map_IsValid( mapname ) ) { Cbuf_AddText( Cbuf_GetCurrentPlayer(), va( "map \"%s\"\n", mapname ) ); } }
bool CEngineTool::IsMapValid( const char *mapname ) { return modelloader->Map_IsValid( mapname ); }
// Allows tools to kick off rendering by having the engine call the client
void CEngineTool::RenderView( CViewSetup &view, int nFlags, int whatToRender ) { // Call client
ACTIVE_SPLITSCREEN_PLAYER_GUARD( 0 ); g_ClientDLL->RenderView( view, nFlags, whatToRender ); }
void CEngineTool::SetIsInGame( bool bIsInGame ) { m_bIsInGame = bIsInGame; }
bool CEngineTool::IsInGame() { return m_bIsInGame && GetBaseLocalClient().IsConnected(); }
bool CEngineTool::IsConnected() { return GetBaseLocalClient().IsConnected(); }
int CEngineTool::GetMaxClients() { return GetBaseLocalClient().m_nMaxClients; }
bool CEngineTool::IsGamePaused() { return GetBaseLocalClient().IsPaused(); }
bool CEngineTool::IsConsoleVisible() { #ifdef DEDICATED
return false; #else
return EngineVGui()->IsConsoleVisible(); #endif
}
void CEngineTool::SetGamePaused( bool paused ) { sv.SetPaused( paused ); }
float CEngineTool::GetTimescale() { return host_timescale.GetFloat() * sv.GetTimescale(); }
void CEngineTool::SetTimescale( float scale ) { host_timescale.SetValue( scale ); }
float CEngineTool::Time() { return Plat_FloatTime(); }
// Real time is unscaled, but is updated once per frame
float CEngineTool::GetRealTime() { return realtime; }
float CEngineTool::GetRealFrameTime() { return host_frametime_unscaled; }
float CEngineTool::HostFrameTime() { return host_frametime; }
float CEngineTool::HostTime() { return host_time; }
int CEngineTool::HostTick() { return host_tickcount; }
int CEngineTool::HostFrameCount() { return host_framecount; }
float CEngineTool::ServerTime() { return g_ServerGlobalVariables.curtime; }
float CEngineTool::ServerFrameTime() { return g_ServerGlobalVariables.frametime; } int CEngineTool::ServerTick() { return g_ServerGlobalVariables.tickcount; }
float CEngineTool::ServerTickInterval() { return g_ServerGlobalVariables.interval_per_tick; }
float CEngineTool::ClientTime() { return g_ClientGlobalVariables.curtime; }
float CEngineTool::ClientFrameTime() { return g_ClientGlobalVariables.frametime; }
int CEngineTool::ClientTick() { return g_ClientGlobalVariables.tickcount; }
void CEngineTool::SetClientFrameTime( float frametime ) { g_ClientGlobalVariables.frametime = frametime; }
void CEngineTool::ForceUpdateDuringPause() { SV_ForceSend(); }
model_t *CEngineTool::GetModel( HTOOLHANDLE hEntity ) { Assert( 0 ); return NULL; }
studiohdr_t *CEngineTool::GetStudioModel( HTOOLHANDLE hEntity ) { Assert( 0 ); return NULL; }
void CEngineTool::Con_NPrintf( int pos, const char *fmt, ... ) { char buf[ 1024 ]; va_list argptr; va_start( argptr, fmt ); _vsnprintf( buf, sizeof( buf ) - 1, fmt, argptr ); va_end( argptr );
return ::Con_NPrintf( pos, "%s", buf ); }
void CEngineTool::Con_NXPrintf( const struct con_nprint_s *info, const char *fmt, ... ) { char buf[ 1024 ]; va_list argptr; va_start( argptr, fmt ); _vsnprintf( buf, sizeof( buf ) - 1, fmt, argptr ); va_end( argptr );
::Con_NXPrintf( info, "%s", buf ); }
void CEngineTool::GetGameDir( char *szGetGameDir, int maxlength ) { Q_strncpy( szGetGameDir, com_gamedir, maxlength ); }
void CEngineTool::GetScreenSize( int& width, int &height ) { CMatRenderContextPtr pRenderContext( materials );
pRenderContext->GetWindowSize( width, height ); }
//-----------------------------------------------------------------------------
// Purpose: Helpers for implementing a tool switching UI
// Input : -
// Output : int
//-----------------------------------------------------------------------------
int CEngineTool::GetToolCount() const { return toolframework->GetToolCount(); }
//-----------------------------------------------------------------------------
// Purpose:
// Input : index -
// Output : char
//-----------------------------------------------------------------------------
const char *CEngineTool::GetToolName( int index ) const { return toolframework->GetToolName( index ); }
//-----------------------------------------------------------------------------
// Purpose:
// Input : index -
//-----------------------------------------------------------------------------
void CEngineTool::SwitchToTool( int index ) { toolframework->SwitchToTool( index ); }
bool CEngineTool::IsTopmostTool( const IToolSystem *sys ) const { return toolframework->IsTopmostTool( sys ); }
IToolSystem *CEngineTool::GetTopmostTool() { return toolframework->GetTopmostTool(); }
const IToolSystem *CEngineTool::GetToolSystem( int index ) const { return toolframework->GetToolSystem( index ); }
// If module not already loaded, loads it and optionally switches to first tool in module. Returns false if load failed or tool already loaded
bool CEngineTool::LoadToolModule( char const *pToolModule, bool bSwitchToFirst ) { return toolframework->LoadToolModule( pToolModule, bSwitchToFirst ); }
void CEngineTool::ValidateSoundCache( char const *pchSoundName ) { S_ValidateSoundCache( pchSoundName ); }
void CEngineTool::PrefetchSound( char const *pchSoundName ) { S_PrefetchSound( pchSoundName, false ); }
int CEngineTool::StartSound( int iUserData, bool staticsound, int iEntIndex, int iChannel, const char *pSample, float flVolume, soundlevel_t iSoundlevel, const Vector& origin, const Vector& direction, int iFlags /*= 0*/, int iPitch /*= PITCH_NORM*/, bool bUpdatePositions /*= true*/, float delay /*= 0.0f*/, int speakerentity /*= -1*/ ) { StartSoundParams_t params; params.userdata = iUserData; params.staticsound = staticsound; params.soundsource = iEntIndex; params.entchannel = iChannel; params.pSfx = S_PrecacheSound( pSample ); params.origin = origin; params.direction = direction; params.bUpdatePositions = bUpdatePositions; params.fvol = flVolume; params.soundlevel = iSoundlevel; params.flags = iFlags; params.pitch = iPitch; params.fromserver = false; params.delay = delay; params.speakerentity = speakerentity; params.bToolSound = true;
int guid = S_StartSound( params );
return guid; }
void CEngineTool::StopSoundByGuid( int guid ) { S_StopSoundByGuid( guid ); }
void CEngineTool::SetVolumeByGuid( int guid, float flVolume ) { S_SetVolumeByGuid( guid, flVolume ); }
bool CEngineTool::IsSoundStillPlaying( int guid ) { return S_IsSoundStillPlaying( guid ); }
float CEngineTool::GetSoundDuration( int guid ) { return S_SoundDurationByGuid( guid ); } float CEngineTool::GetSoundElapsedTime( int guid ) { return S_GetElapsedTimeByGuid( guid ); }
void* CEngineTool::GetEngineHwnd() { return game->GetMainWindow(); }
float CEngineTool::GetSoundDuration( const char *pszName ) { return AudioSource_GetSoundDuration( pszName ); }
void CEngineTool::ReloadSound( const char *pSample ) { S_ReloadSound( pSample ); }
void CEngineTool::StopAllSounds( ) { S_StopAllSounds( true ); } bool CEngineTool::GetPreventSound( ) { return S_GetPreventSound( ); }
// Returns if the sound is looping
bool CEngineTool::IsLoopingSound( int guid ) { return S_IsLoopingSoundByGuid( guid ); }
void CEngineTool::TraceRay( const Ray_t &ray, unsigned int fMask, ITraceFilter *pTraceFilter, CBaseTrace *pTrace ) { trace_t tempTrace;
g_pEngineTraceClient->TraceRay( ray, fMask, pTraceFilter, &tempTrace );
memcpy( pTrace, &tempTrace, sizeof ( CBaseTrace ) ); }
void CEngineTool::TraceRayServer( const Ray_t &ray, unsigned int fMask, ITraceFilter *pTraceFilter, CBaseTrace *pTrace ) { trace_t tempTrace;
g_pEngineTraceServer->TraceRay( ray, fMask, pTraceFilter, &tempTrace );
memcpy( pTrace, &tempTrace, sizeof ( CBaseTrace ) ); }
void CEngineTool::SetAudioState( const AudioState_t &audioState ) { Host_SetAudioState( audioState ); }
// Sets the location of the main view
void CEngineTool::SetMainView( const Vector &vecOrigin, const QAngle &angles ) { g_EngineRenderer->SetMainView( vecOrigin, angles ); }
static float ScaleFOVByWidthRatio( float fovDegrees, float ratio ) { float halfAngleRadians = fovDegrees * ( 0.5f * M_PI / 180.0f ); float t = tan( halfAngleRadians ); t *= ratio; float retDegrees = ( 180.0f / M_PI ) * atan( t ); return retDegrees * 2.0f; }
// Gets the player view
bool CEngineTool::GetPlayerView( CViewSetup &viewSetup, int x, int y, int w, int h ) { if ( g_ClientDLL ) { if ( !g_ClientDLL->GetPlayerView( viewSetup ) ) return false;
// Initialize view setup given the desired rectangle
viewSetup.x = x; viewSetup.y = y; viewSetup.width = w; viewSetup.height = h; viewSetup.m_flAspectRatio = (viewSetup.height != 0) ? (float)viewSetup.width / (float)viewSetup.height : 4.0f / 3.0f; viewSetup.m_bRenderToSubrectOfLargerScreen = true; viewSetup.fov = ScaleFOVByWidthRatio( viewSetup.fov, viewSetup.m_flAspectRatio / ( 4.0f / 3.0f ) ); viewSetup.fovViewmodel = ScaleFOVByWidthRatio( viewSetup.fovViewmodel, viewSetup.m_flAspectRatio / ( 4.0f / 3.0f ) ); return true; } return false; }
//-----------------------------------------------------------------------------
// From a location on the screen, figure out the vector into the world
//-----------------------------------------------------------------------------
void CEngineTool::CreatePickingRay( const CViewSetup &viewSetup, int x, int y, Vector& org, Vector& forward ) { // Remap x and y into -1 to 1 normalized space
float xf, yf; xf = ( 2.0f * (float)x / (float)viewSetup.width ) - 1.0f; yf = ( 2.0f * (float)y / (float)viewSetup.height ) - 1.0f;
// Flip y axis
yf = -yf;
VMatrix worldToScreen; GetWorldToScreenMatrixForView( viewSetup, &worldToScreen ); VMatrix screenToWorld; MatrixInverseGeneral( worldToScreen, screenToWorld );
// Create two points at the normalized mouse x, y pos and at the near and far z planes (0 and 1 depth)
Vector v1, v2; v1.Init( xf, yf, 0.0f ); v2.Init( xf, yf, 1.0f ); Vector o2; // Transform the two points by the screen to world matrix
screenToWorld.V3Mul( v1, org ); // ray start origin
screenToWorld.V3Mul( v2, o2 ); // ray end origin
VectorSubtract( o2, org, forward ); forward.NormalizeInPlace(); }
//-----------------------------------------------------------------------------
// Purpose: Returns true if all handlers say we can quit the engine
//-----------------------------------------------------------------------------
bool CEngineTool::CanQuit() { int c = m_QuitHandlers.Count(); for ( int i = 0; i < c; ++i ) { QuitHandler_t& qh = m_QuitHandlers[ i ]; FnQuitHandler func = qh.func; if ( func ) { if ( !func( qh.userdata ) ) { return false; } } }
return true; }
void CEngineTool::InstallQuitHandler( void *pvUserData, FnQuitHandler func ) { QuitHandler_t qh; qh.userdata = pvUserData; qh.func = func;
m_QuitHandlers.AddToTail( qh ); }
// precache methods
bool CEngineTool::PrecacheSound( const char *pName, bool bPreload ) { if ( pName && TestSoundChar( pName, CHAR_SENTENCE ) ) return true;
bool bState = networkStringTableContainerServer->Lock( false ); int flags = bPreload ? RES_PRELOAD : 0; int i = sv.PrecacheSound( pName, flags ); networkStringTableContainerServer->Lock( bState ); return i >= 0; }
bool CEngineTool::PrecacheModel( const char *pName, bool bPreload ) { int flags = bPreload ? RES_PRELOAD : 0; bool bState = networkStringTableContainerServer->Lock( false ); int i = sv.PrecacheModel( pName, flags ); networkStringTableContainerServer->Lock( bState ); return i >= 0; }
void CEngineTool::TakeTGAScreenShot( const char *filename, int width, int height ) { Q_strncpy( m_szScreenshotFile, filename, sizeof( m_szScreenshotFile ) );
m_nScreenshotWidth = width; m_nScreenshotHeight = height; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CEngineTool::UpdateScreenshot() { if ( g_LostVideoMemory ) return;
if ( m_szScreenshotFile[0] ) { g_ClientDLL->WriteSaveGameScreenshotOfSize( m_szScreenshotFile, m_nScreenshotWidth, m_nScreenshotHeight ); m_szScreenshotFile[0] = 0; } }
// Even if game is paused, force networking to update to get new server state down to client
void CEngineTool::ForceSend() { SV_ForceSend(); }
bool CEngineTool::IsRecordingMovie() { if ( m_bRecordingMovie ) { Assert( CL_IsRecordingMovie() ); return true; } return false; }
// NOTE: Params can contain file name, frame rate, output avi, output raw, and duration
void CEngineTool::StartMovieRecording( KeyValues *pMovieParams ) { if ( CL_IsRecordingMovie() ) { Warning( "Can't record movie, already recording!!!\n" ); return; }
if ( m_bRecordingMovie ) return;
int jpeg_quality = DEFAULT_JPEG_QUALITY;
int flags = 0; if ( pMovieParams->GetInt( "outputavi", 0 ) ) { if ( pMovieParams->GetInt( "avisoundonly", 0 ) ) { flags |= MovieInfo_t::FMOVIE_AVISOUND; } else { flags |= MovieInfo_t::FMOVIE_AVI | MovieInfo_t::FMOVIE_AVISOUND; } } if ( pMovieParams->GetInt( "outputtga", 0 ) ) { flags |= MovieInfo_t::FMOVIE_TGA; } if ( pMovieParams->GetInt( "outputjpg", 0 ) ) { flags |= MovieInfo_t::FMOVIE_JPG; jpeg_quality = pMovieParams->GetInt( "jpeg_quality" ); } if ( pMovieParams->GetInt( "outputwav", 0 ) ) { flags |= MovieInfo_t::FMOVIE_WAV; }
const char *pFileName = pMovieParams->GetString( "filename", NULL ); if ( !pFileName ) { Warning( "Output filename not specified!\n" ); return; }
int nWidth = pMovieParams->GetInt( "width", videomode->GetModeWidth() ); int nHeight = pMovieParams->GetInt( "height", videomode->GetModeHeight() ); float flFrameRate = pMovieParams->GetFloat( "framerate", 30.0f );
m_bRecordingMovie = true; CL_StartMovie( pFileName, flags, nWidth, nHeight, flFrameRate, jpeg_quality ); }
void CEngineTool::EndMovieRecording() { if ( !m_bRecordingMovie ) return;
CL_EndMovie(); m_bRecordingMovie = false; }
void CEngineTool::CancelMovieRecording() { EndMovieRecording(); }
AVIHandle_t CEngineTool::GetRecordingAVIHandle() { if ( !CL_IsRecordingMovie() ) return AVIHANDLE_INVALID; return g_hCurrentAVI; }
bool CEngineTool::ShouldSuppressDeInit() const { return m_bSuppressDeInit; }
void CEngineTool::StartRecordingVoiceToFile( const char *filename, const char *pPathID /*= 0*/ ) { FileHandle_t fh = g_pFileSystem->Open( filename, "wb", pPathID ); if ( fh != FILESYSTEM_INVALID_HANDLE ) { byte foo = 'b';
g_pFileSystem->Write( &foo, 1, fh ); g_pFileSystem->Close( fh ); }
g_pFileSystem->RelativePathToFullPath( filename, pPathID, m_szVoiceoverFile, sizeof( m_szVoiceoverFile ) );
g_pFileSystem->RemoveFile( filename, pPathID );
#if !defined( NO_VOICE )
if ( IsVoiceRecording() ) { Voice_RecordStop(); } m_bSuppressDeInit = true;
Voice_ForceInit(); Voice_RecordStart( m_szVoiceoverFile, NULL, NULL); #endif
}
void CEngineTool::StopRecordingVoiceToFile() { #if !defined( NO_VOICE )
Voice_RecordStop(); m_bSuppressDeInit = false; #endif
}
float CEngineTool::GetMono16Samples( const char *pszName, CUtlVector< short >& sampleList ) { return S_GetMono16Samples( pszName, sampleList ); }
void CEngineTool::GetWorldToScreenMatrixForView( const CViewSetup &view, VMatrix *pVMatrix ) { VMatrix worldToView, viewToProjection; view.ComputeViewMatrices( &worldToView, &viewToProjection, pVMatrix ); }
SpatialPartitionHandle_t CEngineTool::CreatePartitionHandle( IHandleEntity *pEntity, SpatialPartitionListMask_t listMask, const Vector& mins, const Vector& maxs ) { return SpatialPartition()->CreateHandle( pEntity, listMask, mins, maxs ); }
void CEngineTool::DestroyPartitionHandle( SpatialPartitionHandle_t hPartition ) { SpatialPartition()->DestroyHandle( hPartition ); }
void CEngineTool::InstallPartitionQueryCallback( IPartitionQueryCallback *pQuery ) { SpatialPartition()->InstallQueryCallback( pQuery ); }
void CEngineTool::RemovePartitionQueryCallback( IPartitionQueryCallback *pQuery ) { SpatialPartition()->RemoveQueryCallback( pQuery ); }
void CEngineTool::ElementMoved( SpatialPartitionHandle_t handle, const Vector& mins, const Vector& maxs ) { SpatialPartition()->ElementMoved( handle, mins, maxs ); }
bool CEngineTool::IsVoiceRecording() { #if !defined( NO_VOICE )
return Voice_IsRecording(); #else
return false; #endif
}
void CEngineTool::OnModeChanged( bool bGameMode ) { EngineVGui()->OnToolModeChanged( bGameMode ); }
bool EngineTool_SuppressDeInit() { return g_EngineTool.ShouldSuppressDeInit(); }
void EngineTool_OverrideSampleRate( int& rate ) { if ( EngineTool_SuppressDeInit() ) { rate = 11025; } }
// Expose complex interface
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CEngineTool, IEngineTool, VENGINETOOL_INTERFACE_VERSION, g_EngineTool ); // Expose simple interface
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CEngineTool, IEngineToolFramework, VENGINETOOLFRAMEWORK_INTERFACE_VERSION, g_EngineTool );
|