1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#ifndef ENGINE_SHARED_DEMO_H
#define ENGINE_SHARED_DEMO_H
#include <engine/demo.h>
#include "snapshot.h"
struct CDemoHeader
{
unsigned char m_aMarker[7];
unsigned char m_Version;
char m_aNetversion[64];
char m_aMap[64];
unsigned char m_aCrc[4];
char m_aType[8];
};
class CDemoRecorder : public IDemoRecorder
{
class IConsole *m_pConsole;
IOHANDLE m_File;
int m_LastTickMarker;
int m_LastKeyFrame;
int m_FirstTick;
unsigned char m_aLastSnapshotData[CSnapshot::MAX_SIZE];
class CSnapshotDelta *m_pSnapshotDelta;
void WriteTickMarker(int Tick, int Keyframe);
void Write(int Type, const void *pData, int Size);
public:
CDemoRecorder(class CSnapshotDelta *pSnapshotDelta);
int Start(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, const char *pNetversion, const char *pMap, int MapCrc, const char *pType);
int Stop();
void RecordSnapshot(int Tick, const void *pData, int Size);
void RecordMessage(const void *pData, int Size);
bool IsRecording() const { return m_File != 0; }
int Length() const { return m_LastTickMarker - m_FirstTick; }
};
class CDemoPlayer : public IDemoPlayer
{
public:
class IListner
{
public:
virtual ~IListner() {}
virtual void OnDemoPlayerSnapshot(void *pData, int Size) = 0;
virtual void OnDemoPlayerMessage(void *pData, int Size) = 0;
};
struct CPlaybackInfo
{
CDemoHeader m_Header;
IDemoPlayer::CInfo m_Info;
int64 m_LastUpdate;
int64 m_CurrentTime;
int m_SeekablePoints;
int m_NextTick;
int m_PreviousTick;
float m_IntraTick;
float m_TickTime;
};
private:
IListner *m_pListner;
// Playback
struct CKeyFrame
{
long m_Filepos;
int m_Tick;
};
struct CKeyFrameSearch
{
CKeyFrame m_Frame;
CKeyFrameSearch *m_pNext;
};
class IConsole *m_pConsole;
IOHANDLE m_File;
char m_aFilename[256];
CKeyFrame *m_pKeyFrames;
CPlaybackInfo m_Info;
int m_DemoType;
unsigned char m_aLastSnapshotData[CSnapshot::MAX_SIZE];
int m_LastSnapshotDataSize;
class CSnapshotDelta *m_pSnapshotDelta;
int ReadChunkHeader(int *pType, int *pSize, int *pTick);
void DoTick();
void ScanFile();
int NextFrame();
public:
CDemoPlayer(class CSnapshotDelta *m_pSnapshotDelta);
void SetListner(IListner *pListner);
int Load(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, int StorageType);
int Play();
void Pause();
void Unpause();
int Stop();
void SetSpeed(float Speed);
int SetPos(float Precent);
const CInfo *BaseInfo() const { return &m_Info.m_Info; }
char *GetDemoName();
bool GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, char *pMap, int BufferSize) const;
int GetDemoType() const;
int Update();
const CPlaybackInfo *Info() const { return &m_Info; }
int IsPlaying() const { return m_File != 0; }
};
#endif
|