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.
1078 lines
28 KiB
1078 lines
28 KiB
//========= Copyright 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 "gl_rmain.h" |
|
#include "vprof_telemetry.h" |
|
|
|
#ifndef SWDS |
|
#include "vgui_baseui_interface.h" |
|
#endif |
|
|
|
// 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 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(); |
|
|
|
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(); // Could do this via ConVar system, too |
|
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 bool IsSoundStillPlaying( int guid ); |
|
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 IVideoRecorder *GetActiveVideoRecorder(); |
|
|
|
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 ); |
|
|
|
public: |
|
// Methods of IEngineToolInternal |
|
virtual void SetIsInGame( bool bIsInGame ); |
|
|
|
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 ); |
|
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( cmd ); |
|
} |
|
|
|
void CEngineTool::Execute() |
|
{ |
|
Cbuf_Execute(); |
|
} |
|
|
|
const char *CEngineTool::GetCurrentMap() |
|
{ |
|
if ( sv.IsDedicated() ) |
|
return "Dedicated Server"; |
|
|
|
if ( !cl.IsConnected() ) |
|
{ |
|
if ( sv.IsLoading() ) |
|
return sv.GetMapName(); |
|
|
|
return ""; |
|
} |
|
|
|
return cl.m_szLevelFileName; |
|
} |
|
|
|
void CEngineTool::ChangeToMap( const char *mapname ) |
|
{ |
|
if ( modelloader->Map_IsValid( mapname ) ) |
|
{ |
|
Cbuf_AddText( 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 |
|
g_ClientDLL->RenderView( view, nFlags, whatToRender ); |
|
} |
|
|
|
void CEngineTool::SetIsInGame( bool bIsInGame ) |
|
{ |
|
m_bIsInGame = bIsInGame; |
|
} |
|
|
|
bool CEngineTool::IsInGame() |
|
{ |
|
return m_bIsInGame && cl.IsConnected(); |
|
} |
|
|
|
bool CEngineTool::IsConnected() |
|
{ |
|
return cl.IsConnected(); |
|
} |
|
|
|
int CEngineTool::GetMaxClients() |
|
{ |
|
return cl.m_nMaxClients; |
|
} |
|
|
|
bool CEngineTool::IsGamePaused() |
|
{ |
|
return cl.IsPaused(); |
|
} |
|
|
|
bool CEngineTool::IsConsoleVisible() |
|
{ |
|
#ifdef SWDS |
|
return false; |
|
#else |
|
return EngineVGui()->IsConsoleVisible(); |
|
#endif |
|
} |
|
|
|
void CEngineTool::SetGamePaused( bool paused ) |
|
{ |
|
sv.SetPaused( paused ); |
|
} |
|
|
|
float CEngineTool::GetTimescale() |
|
{ |
|
return host_timescale.GetFloat(); |
|
} |
|
|
|
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; |
|
} |
|
|
|
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 ); |
|
} |
|
|
|
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.suppressrecording = true; |
|
|
|
int guid = S_StartSound( params ); |
|
|
|
return guid; |
|
} |
|
|
|
void CEngineTool::StopSoundByGuid( int guid ) |
|
{ |
|
S_StopSoundByGuid( guid ); |
|
} |
|
|
|
bool CEngineTool::IsSoundStillPlaying( int guid ) |
|
{ |
|
return S_IsSoundStillPlaying( guid ); |
|
} |
|
|
|
float CEngineTool::GetSoundDuration( int guid ) |
|
{ |
|
return S_SoundDurationByGuid( guid ); |
|
} |
|
|
|
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 ); |
|
} |
|
|
|
// 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 ) |
|
{ |
|
tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s(%s, %s)", __FUNCTION__, tmDynamicString( TELEMETRY_LEVEL0, pName ), bPreload ? "true" : "false" ); |
|
|
|
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; |
|
VideoSystem_t videoSystem = VideoSystem::NONE; |
|
if ( pMovieParams->GetInt( "outputavi", 0 ) ) |
|
{ |
|
Warning( "Got a request to record a movie using AVI, but AVI is deprecated. Using QuickTime/H264 instead.\n" ); |
|
videoSystem = VideoSystem::QUICKTIME; |
|
if ( pMovieParams->GetInt( "avisoundonly", 0 ) ) |
|
{ |
|
flags |= MovieInfo_t::FMOVIE_VIDSOUND; |
|
} |
|
else |
|
{ |
|
flags |= MovieInfo_t::FMOVIE_VID | MovieInfo_t::FMOVIE_VIDSOUND; |
|
} |
|
} |
|
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->GetModeStereoWidth() ); |
|
int nHeight = pMovieParams->GetInt( "height", videomode->GetModeStereoHeight() ); |
|
float flFrameRate = pMovieParams->GetFloat( "framerate", 30.0f ); |
|
|
|
m_bRecordingMovie = true; |
|
CL_StartMovie( pFileName, flags, nWidth, nHeight, flFrameRate, jpeg_quality, videoSystem ); |
|
} |
|
|
|
void CEngineTool::EndMovieRecording() |
|
{ |
|
if ( !m_bRecordingMovie ) |
|
return; |
|
|
|
CL_EndMovie(); |
|
m_bRecordingMovie = false; |
|
} |
|
|
|
void CEngineTool::CancelMovieRecording() |
|
{ |
|
EndMovieRecording(); |
|
} |
|
|
|
|
|
IVideoRecorder *CEngineTool::GetActiveVideoRecorder() |
|
{ |
|
if ( !CL_IsRecordingMovie() ) |
|
{ |
|
return NULL; |
|
} |
|
|
|
return g_pVideoRecorder; |
|
} |
|
|
|
void Voice_ForceInit(); |
|
|
|
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; |
|
ComputeViewMatrices( &worldToView, &viewToProjection, pVMatrix, view ); |
|
} |
|
|
|
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 |
|
} |
|
|
|
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 );
|
|
|