ddnet/src/engine/shared/demo.h

190 lines
5.6 KiB
C
Raw Normal View History

2010-11-20 10:37:14 +00:00
/* (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. */
2010-10-30 11:48:59 +00:00
#ifndef ENGINE_SHARED_DEMO_H
#define ENGINE_SHARED_DEMO_H
2010-05-29 07:25:38 +00:00
#include <base/hash.h>
2010-05-29 07:25:38 +00:00
#include <engine/demo.h>
#include <engine/shared/protocol.h>
2021-07-19 18:14:12 +00:00
#include <functional>
#include <vector>
2010-05-29 07:25:38 +00:00
#include "snapshot.h"
2010-05-29 07:25:38 +00:00
2021-07-19 18:14:12 +00:00
typedef std::function<void()> TUpdateIntraTimesFunc;
2010-08-09 12:14:15 +00:00
class CDemoRecorder : public IDemoRecorder
2010-05-29 07:25:38 +00:00
{
class IConsole *m_pConsole;
2010-05-29 07:25:38 +00:00
IOHANDLE m_File;
char m_aCurrentFilename[IO_MAX_PATH_LENGTH];
2010-05-29 07:25:38 +00:00
int m_LastTickMarker;
int m_LastKeyFrame;
int m_FirstTick;
2010-05-29 07:25:38 +00:00
unsigned char m_aLastSnapshotData[CSnapshot::MAX_SIZE];
class CSnapshotDelta *m_pSnapshotDelta;
int m_NumTimelineMarkers;
int m_aTimelineMarkers[MAX_TIMELINE_MARKERS];
bool m_NoMapData;
unsigned char *m_pMapData;
DEMOFUNC_FILTER m_pfnFilter;
void *m_pUser;
2023-10-15 13:00:59 +00:00
void WriteTickMarker(int Tick, bool Keyframe);
2010-05-29 07:25:38 +00:00
void Write(int Type, const void *pData, int Size);
2010-05-29 07:25:38 +00:00
public:
CDemoRecorder(class CSnapshotDelta *pSnapshotDelta, bool NoMapData = false);
CDemoRecorder() {}
~CDemoRecorder() override;
int Start(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, const char *pNetversion, const char *pMap, const SHA256_DIGEST &Sha256, unsigned MapCrc, const char *pType, unsigned MapSize, unsigned char *pMapData, IOHANDLE MapFile = nullptr, DEMOFUNC_FILTER pfnFilter = nullptr, void *pUser = nullptr);
int Stop() override;
void AddDemoMarker();
void AddDemoMarker(int Tick);
2010-05-29 07:25:38 +00:00
void RecordSnapshot(int Tick, const void *pData, int Size);
void RecordMessage(const void *pData, int Size);
bool IsRecording() const override { return m_File != nullptr; }
char *GetCurrentFilename() override { return m_aCurrentFilename; }
void ClearCurrentFilename() { m_aCurrentFilename[0] = '\0'; }
int Length() const override { return (m_LastTickMarker - m_FirstTick) / SERVER_TICK_SPEED; }
2010-05-29 07:25:38 +00:00
};
class CDemoPlayer : public IDemoPlayer
{
public:
class IListener
2010-05-29 07:25:38 +00:00
{
public:
virtual ~IListener() {}
2010-05-29 07:25:38 +00:00
virtual void OnDemoPlayerSnapshot(void *pData, int Size) = 0;
virtual void OnDemoPlayerMessage(void *pData, int Size) = 0;
};
2010-05-29 07:25:38 +00:00
struct CPlaybackInfo
{
CDemoHeader m_Header;
CTimelineMarkers m_TimelineMarkers;
2010-05-29 07:25:38 +00:00
IDemoPlayer::CInfo m_Info;
2021-06-23 05:05:49 +00:00
int64_t m_LastUpdate;
int64_t m_CurrentTime;
2010-05-29 07:25:38 +00:00
int m_NextTick;
int m_PreviousTick;
2010-05-29 07:25:38 +00:00
float m_IntraTick;
2021-07-19 18:14:12 +00:00
float m_IntraTickSincePrev;
2010-05-29 07:25:38 +00:00
float m_TickTime;
};
private:
IListener *m_pListener;
2010-05-29 07:25:38 +00:00
2021-07-19 18:14:12 +00:00
TUpdateIntraTimesFunc m_UpdateIntraTimesFunc;
2010-05-29 07:25:38 +00:00
// Playback
struct SKeyFrame
2010-05-29 07:25:38 +00:00
{
long m_Filepos;
int m_Tick;
SKeyFrame(long Filepos, int Tick) :
m_Filepos(Filepos), m_Tick(Tick)
{
}
};
2010-05-29 07:25:38 +00:00
class IConsole *m_pConsole;
2010-05-29 07:25:38 +00:00
IOHANDLE m_File;
long m_MapOffset;
char m_aFilename[IO_MAX_PATH_LENGTH];
char m_aErrorMessage[256];
std::vector<SKeyFrame> m_vKeyFrames;
2014-08-12 14:21:06 +00:00
CMapInfo m_MapInfo;
int m_SpeedIndex;
2010-05-29 07:25:38 +00:00
CPlaybackInfo m_Info;
unsigned char m_aCompressedSnapshotData[CSnapshot::MAX_SIZE];
unsigned char m_aDecompressedSnapshotData[CSnapshot::MAX_SIZE];
unsigned char m_aCurrentSnapshotData[CSnapshot::MAX_SIZE];
unsigned char m_aDeltaSnapshotData[CSnapshot::MAX_SIZE];
2010-05-29 07:25:38 +00:00
unsigned char m_aLastSnapshotData[CSnapshot::MAX_SIZE];
int m_LastSnapshotDataSize;
class CSnapshotDelta *m_pSnapshotDelta;
bool m_UseVideo;
2023-11-15 11:11:58 +00:00
#if defined(CONF_VIDEORECORDER)
bool m_WasRecording = false;
2023-11-15 11:11:58 +00:00
#endif
enum EReadChunkHeaderResult
{
CHUNKHEADER_SUCCESS,
CHUNKHEADER_ERROR,
CHUNKHEADER_EOF,
};
EReadChunkHeaderResult ReadChunkHeader(int *pType, int *pSize, int *pTick);
2010-05-29 07:25:38 +00:00
void DoTick();
bool ScanFile();
2010-05-29 07:25:38 +00:00
int64_t Time();
2010-05-29 07:25:38 +00:00
public:
CDemoPlayer(class CSnapshotDelta *pSnapshotDelta, bool UseVideo);
CDemoPlayer(class CSnapshotDelta *pSnapshotDelta, bool UseVideo, TUpdateIntraTimesFunc &&UpdateIntraTimesFunc);
~CDemoPlayer() override;
2021-07-19 18:14:12 +00:00
void Construct(class CSnapshotDelta *pSnapshotDelta, bool UseVideo);
void SetListener(IListener *pListener);
2010-10-06 21:07:35 +00:00
int Load(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, int StorageType);
unsigned char *GetMapData(class IStorage *pStorage);
bool ExtractMap(class IStorage *pStorage);
2010-05-29 07:25:38 +00:00
int Play();
void Pause() override;
void Unpause() override;
void Stop(const char *pErrorMessage = "");
void SetSpeed(float Speed) override;
void SetSpeedIndex(int SpeedIndex) override;
void AdjustSpeedIndex(int Offset) override;
int SeekPercent(float Percent) override;
int SeekTime(float Seconds) override;
int SeekTick(ETickOffset TickOffset) override;
int SetPos(int WantedTick) override;
const CInfo *BaseInfo() const override { return &m_Info.m_Info; }
void GetDemoName(char *pBuffer, size_t BufferSize) const override;
bool GetDemoInfo(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, int StorageType, CDemoHeader *pDemoHeader, CTimelineMarkers *pTimelineMarkers, CMapInfo *pMapInfo, IOHANDLE *pFile = nullptr, char *pErrorMessage = nullptr, size_t ErrorMessageSize = 0) const override;
const char *Filename() { return m_aFilename; }
const char *ErrorMessage() { return m_aErrorMessage; }
int Update(bool RealTime = true);
2010-05-29 07:25:38 +00:00
const CPlaybackInfo *Info() const { return &m_Info; }
bool IsPlaying() const override { return m_File != nullptr; }
2022-07-12 19:23:35 +00:00
const CMapInfo *GetMapInfo() const { return &m_MapInfo; }
2014-08-12 14:21:06 +00:00
};
class CDemoEditor : public IDemoEditor
2014-08-12 14:21:06 +00:00
{
IConsole *m_pConsole;
IStorage *m_pStorage;
class CSnapshotDelta *m_pSnapshotDelta;
const char *m_pNetVersion;
public:
virtual void Init(const char *pNetVersion, class CSnapshotDelta *pSnapshotDelta, class IConsole *pConsole, class IStorage *pStorage);
void Slice(const char *pDemo, const char *pDst, int StartTick, int EndTick, DEMOFUNC_FILTER pfnFilter, void *pUser) override;
2010-05-29 07:25:38 +00:00
};
#endif