about summary refs log tree commit diff
path: root/src/engine/shared/demorec.h
blob: cdf46e99a3e60a7a973a1f804b8a5885bd453644 (plain)
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
#ifndef ENGINE_SHARED_DEMOREC_H
#define ENGINE_SHARED_DEMOREC_H

#include <engine/demo.h>
#include "snapshot.h"

struct CDemoHeader
{
	char m_aMarker[8];
	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;
	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; }
};

class CDemoPlayer : public IDemoPlayer
{
public:
	class IListner
	{
	public:
		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;
	CKeyFrame *m_pKeyFrames;

	CPlaybackInfo m_Info;
	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 Play();
	void Pause();
	void Unpause();
	int Stop();	
	void SetSpeed(float Speed);
	int SetPos(float Precent);
	const CInfo *BaseInfo() const { return &m_Info.m_Info; }
	
	int Update();
	
	const CPlaybackInfo *Info() const { return &m_Info; }
	int IsPlaying() const { return m_File != 0; }
};

#endif