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.
189 lines
5.8 KiB
189 lines
5.8 KiB
//========= 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() = default; |
|
|
|
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
|
|
|