etqw-sdk/source/framework/async/Demo.h

256 lines
6.9 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __DEMO_H__
#define __DEMO_H__
//#include "../../sys/sys_local.h"
#include "../UsercmdGen.h"
//===============================================================
//
// sdDemo
//
//===============================================================
#define DEMO_IDENT (('O'<<24)+('M'<<16)+('D'<<8)+'N')
#define DEMO_VERSION 3
#define JUMPSTART_IDENT (('O'<<24)+('D'<<16)+('S'<<8)+'J')
#define JUMPSTART_VERSION 1
#define KEYFRAMEFILE_IDENT (('F'<<24)+('F'<<16)+('K'<<8)+'D')
#define KEYFRAMEFILE_VERSION 1
class sdFrameBuffer;
class sdDemo {
public:
typedef enum demoState_e {
DS_IDLE,
DS_RECORDING,
DS_PLAYING
} demoState_t;
static const int TIMEDEMO_FRAME_MSEC;
static const int KEYFRAME_INTERVAL;
sdDemo();
void Record( const char* fileName );
void Stop();
void Play( const char* fileName, bool timeDemo = false );
void PlayJumpStart( const char* fileName );
static bool CheckVersion( const char* fileName );
demoState_t GetState() const { return state; }
bool IsRecording() const;
bool IsPlaying() const;
bool IsPaused() const;
bool IsTimeDemo() const;
bool IsRenderDemo() const;
bool IsGeneratingKeyFrames() const;
bool IsCuttingDemo() const;
void RecordMessage( const int time, const idBitMsg& msg, int clientPrediction );
bool PlayMessage( const int clientTime, void* data, int& size, const int maxSize, const int timeOut, int& clientPrediction );
void RecordUsercmd( const usercmd_t& usercmd );
void ReadUsercmd( int gameFrame );
void WriteUsercmd( idFile* file, const usercmd_t& usercmd );
bool ReadUsercmd( idFile* file, usercmd_t& usercmd );
void WriteKeyFrame( const int clientTime );
void RunFrame();
// silent stop called from idSessionLocal::Stop, not the same as the Stop() command
void SessionStop();
void Shutdown();
void IncrementDemoFrame() { numDemoFrames++; }
void CaptureRenderDemoFrame( const int gameTime );
const char* GetName() const { return fileName.c_str(); }
int GetRenderDemoFPS() const { return renderDemoFPS; }
int GetStartGameTime() const;
int GetPosition() const;
int GetLength() const;
int GetStartPosition() const;
int GetEndPosition() const;
int GetCutStartMarker() const;
int GetCutEndMarker() const;
usercmd_t GetCachedUsercmd( void ) const { return usercmd; }
void ForceMega();
static void DemoFileName( const char* base, idStr& fileName );
static void Toggle_f( const idCmdArgs& args );
static void Record_f( const idCmdArgs& args );
static void Stop_f( const idCmdArgs& args );
static void Play_f( const idCmdArgs& args );
static void PlayJumpStartDemo_f( const idCmdArgs& args );
static void Time_f( const idCmdArgs& args );
static void Render_f( const idCmdArgs& args );
static void GenerateKeyFrames_f( const idCmdArgs& args );
static void NextKeyFrame_f( const idCmdArgs& args );
static void PrevKeyFrame_f( const idCmdArgs& args );
static void Pause_f( const idCmdArgs& args );
static void CutPlaceStartMarker_f( const idCmdArgs& args );
static void CutPlaceEndMarker_f( const idCmdArgs& args );
static void Cut_f( const idCmdArgs& args );
static void WriteJumpStartDemo_f( const idCmdArgs& args );
public:
static idCVar debug;
static idCVar scale;
static idCVar snapshotDelay;
static idCVar prediction;
static idCVar forceMega;
private:
void Clear();
void DoRenderDemo( const int fps, const int startTime, const int endTime );
void TogglePause();
void WriteJumpStartDemo( const char* jumpStartFileName );
void WriteKeyFrameFile();
void ReadKeyFrames();
void PlayFromKeyFrame( const int keyFrame );
void StepKeyFrame( bool reverse );
void Cut( const char* fileName, const char* cutFileName );
void WriteCut();
void SetCutStartMarker();
void SetCutEndMarker();
void WriteHeader( idFile* file );
int ReadHeader( idFile* file, const idStr& headerFileName );
void WriteNetworkHeader( idFile* file );
void ReadNetworkHeader( idFile* file, bool keyFrame = false );
void WriteDict( idFile* file, const idDict* dict );
void ReadDict( idFile* file, idDict* dict );
void WriteByte( idFile* file, const byte value );
void WriteSignedChar( idFile* file, const signed char value );
void ReadByte( idFile* file, byte& value );
void ReadSignedChar( idFile* file, signed char& value );
static bool CheckVersion( idFile* file, const char* headerFileName, bool verbose );
private:
demoState_t state;
idStr fileName;
idFile* file;
int networkStreamOffset;
int usercmdOffset; // position in file for the ucmd start position record
int usercmdStart; // position in file of the ucmd stream, written at ucmd_offset in file
idFile* usercmdFile;
usercmd_t usercmd;
int startTime;
int startGameTime;
int nextMessageTime;
bool paused;
int numDemoFrames;
bool timeDemo;
bool renderDemo;
bool generatingKeyFrames;
bool cuttingDemo;
idDict userinfo; // backup userinfo to set it to what it was after demo replay
// demo rendering
sdFrameBuffer* renderDemoFrameBuffer;
int renderDemoFPS;
int renderStartTime;
int renderStopTime;
int renderStartFrame;
int renderEndFrame;
// key frames
struct keyFrame_t {
int offset;
int clientTime;
};
idFile* keyFrameFile;
int lastKeyFrameTime;
idList< keyFrame_t> keyFrames;
// demo cutting
idStr cutFileName;
int cutStartMarker;
int cutEndMarker;
};
ID_INLINE bool sdDemo::IsRecording() const {
return state == DS_RECORDING;
}
ID_INLINE bool sdDemo::IsPlaying() const {
return state == DS_PLAYING;
}
ID_INLINE bool sdDemo::IsPaused() const {
return paused;
}
ID_INLINE bool sdDemo::IsTimeDemo() const {
return timeDemo;
}
ID_INLINE bool sdDemo::IsRenderDemo() const {
return renderDemo;
}
ID_INLINE bool sdDemo::IsGeneratingKeyFrames() const {
return generatingKeyFrames;
}
ID_INLINE bool sdDemo::IsCuttingDemo() const {
return cuttingDemo;
}
ID_INLINE int sdDemo::GetStartGameTime() const {
return startGameTime;
}
ID_INLINE int sdDemo::GetPosition() const {
return ( file != NULL ? file->Tell() : -1 );
}
ID_INLINE int sdDemo::GetLength() const {
return ( file != NULL ? file->Length() : -1 );
}
ID_INLINE int sdDemo::GetStartPosition() const {
return networkStreamOffset;
}
ID_INLINE int sdDemo::GetEndPosition() const {
return ( file != NULL ? file->Length() - usercmdStart : -1 ) + networkStreamOffset;
}
ID_INLINE int sdDemo::GetCutStartMarker() const {
return cutStartMarker;
}
ID_INLINE int sdDemo::GetCutEndMarker() const {
return cutEndMarker;
}
#endif /* !__DEMO_H__ */