diff options
Diffstat (limited to 'engine/cl_demo.h')
| -rw-r--r-- | engine/cl_demo.h | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/engine/cl_demo.h b/engine/cl_demo.h new file mode 100644 index 0000000..d849486 --- /dev/null +++ b/engine/cl_demo.h @@ -0,0 +1,189 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef CL_DEMO_H +#define CL_DEMO_H +#ifdef _WIN32 +#pragma once +#endif + +#include "demofile.h" +#include "cl_demoactionmanager.h" + +struct DemoCommandQueue +{ + DemoCommandQueue() + { + tick = 0; + } + int tick; + democmdinfo_t info; + int filepos; +}; + +// When skipping forward through a replay it is important to stop +// occasionally and process the backlog of packets. Otherwise if you +// skip forward too far you will cause data structures to grow far +// beyond their intended size. This can lead to overflows and out-of-memory +// errors, and it can waste memory because some of these data structures +// never release their memory after hitting a high-water mark. +const unsigned nMaxConsecutiveSkipPackets = 100; + +class CDemoPlayer : public IDemoPlayer +{ + +public: // IDemoPlayer interface implementation: + CDemoPlayer(); + ~CDemoPlayer(); + + virtual CDemoFile *GetDemoFile(); + + virtual bool StartPlayback( const char *filename, bool bAsTimeDemo ); + virtual void PausePlayback( float seconds ); + virtual void SkipToTick( int tick, bool bRelative, bool bPause ); + virtual void SetEndTick( int tick ); + virtual void ResumePlayback( void ); + virtual void StopPlayback( void ); + + virtual int GetPlaybackStartTick( void ); + virtual int GetPlaybackTick( void ); + virtual float GetPlaybackTimeScale( void ); + virtual int GetTotalTicks( void ); + + virtual bool IsPlayingBack( void ); + virtual bool IsPlaybackPaused( void ); + virtual bool IsPlayingTimeDemo( void ); + virtual bool IsSkipping( void ); + virtual bool CanSkipBackwards( void ) { return false; } + + virtual void SetPlaybackTimeScale( float timescale ); + virtual void InterpolateViewpoint(); // override viewpoint + virtual netpacket_t *ReadPacket( void ); + virtual void ResetDemoInterpolation( void ); + virtual int GetProtocolVersion(); + + virtual bool ShouldLoopDemos() { return true; } + virtual void OnLastDemoInLoopPlayed() {} + + virtual bool IsLoading( void ); + +public: // other public functions + void MarkFrame( float flFPSVariability ); + void SetBenchframe( int tick, const char *filename ); + void ResyncDemoClock( void ); + bool CheckPausedPlayback( void ); + void WriteTimeDemoResults( void ); + bool ParseAheadForInterval( int curtick, int intervalticks ); + void InterpolateDemoCommand( int targettick, DemoCommandQueue& prev, DemoCommandQueue& next ); + +protected: + bool OverrideView( democmdinfo_t& info ); + + virtual void OnStopCommand(); + +public: + + CDemoFile m_DemoFile; + int m_nStartTick; // For synchronizing playback during timedemo. + int m_nPreviousTick; + netpacket_t m_DemoPacket; // last read demo packet + bool m_bPlayingBack; // true if demo playback + bool m_bPlaybackPaused; // true if demo is paused right now + float m_flAutoResumeTime; // how long do we pause demo playback + float m_flPlaybackRateModifier; + int m_nSkipToTick; // skip to tick ASAP, -1 = off + int m_nEndTick; // if nonzero, stop playback once we reach this tick + bool m_bLoading; // true if demo is loading + + unsigned m_nSkipPacketsPlayed; // Track consecutive skip packets returned to avoid excess + + // view origin/angle interpolation: + CUtlVector< DemoCommandQueue > m_DestCmdInfo; + democmdinfo_t m_LastCmdInfo; + bool m_bInterpolateView; + bool m_bResetInterpolation; + + + // timedemo stuff: + bool m_bTimeDemo; // ture if in timedemo mode + int m_nTimeDemoStartFrame; // host_tickcount at start + double m_flTimeDemoStartTime; // Sys_FloatTime() at second frame of timedemo + float m_flTotalFPSVariability; // Frame rate variability + int m_nTimeDemoCurrentFrame; // last frame we read a packet + + // benchframe stuff + int m_nSnapshotTick; + char m_SnapshotFilename[MAX_OSPATH]; +}; + +class CDemoRecorder : public IDemoRecorder +{ +public: + ~CDemoRecorder(); + CDemoRecorder(); + + CDemoFile *GetDemoFile( void ); + int GetRecordingTick( void ); + + void StartRecording( const char *filename, bool bContinuously ); + void SetSignonState( int state ); + bool IsRecording( void ); + void PauseRecording( void ); + void ResumeRecording( void ); + void StopRecording( void ); + + void RecordCommand( const char *cmdstring ); // record a console command + void RecordUserInput( int cmdnumber ); // record a user input command + void RecordMessages( bf_read &data, int bits ); // add messages to current packet + void RecordPacket( void ); // packet finished, write all recorded stuff to file + void RecordServerClasses( ServerClass *pClasses ); // packet finished, write all recorded stuff to file + void RecordStringTables(); + + void ResetDemoInterpolation( void ); + +protected: + + void ResyncDemoClock( void ); + void StartupDemoFile( void ); + void StartupDemoHeader( void ); + void CloseDemoFile( void ); + void GetClientCmdInfo( democmdinfo_t& info ); + void WriteDemoCvars( void ); + void WriteBSPDecals( void ); + void WriteMessages( bf_write &message ); + bool ComputeNextIncrementalDemoFilename( char *name, int namesize ); + +public: + CDemoFile m_DemoFile; + + // For synchronizing playback during timedemo. + int m_nStartTick; // host_tickcount when starting recoring + + // Name of demo file we are appending onto. + char m_szDemoBaseName[ MAX_OSPATH ]; + + // For demo file handle + bool m_bIsDemoHeader; // true, if m_hDemoFile is the header file + bool m_bCloseDemoFile; // if true, demo file will be closed ASAP + + bool m_bRecording; // true if recording + bool m_bContinuously; // start new record after each + int m_nDemoNumber; // demo count, increases each changelevel + int m_nFrameCount; // # of demo frames in this segment. + + bf_write m_MessageData; // temp buffer for all network messages + + bool m_bResetInterpolation; +}; + +extern CDemoRecorder *g_pClientDemoRecorder; + +inline CDemoPlayer *ToClientDemoPlayer( IDemoPlayer *pDemoPlayer ) +{ + return static_cast< CDemoPlayer * >( pDemoPlayer ); +} + +#endif // CL_DEMO_H |