mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
added demo markers by Choupom. Closes #837
This commit is contained in:
parent
e8f9145a0d
commit
fa81141110
|
@ -2169,6 +2169,11 @@ void CClient::DemoRecorder_Stop()
|
||||||
m_DemoRecorder.Stop();
|
m_DemoRecorder.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CClient::DemoRecorder_AddDemoMarker()
|
||||||
|
{
|
||||||
|
m_DemoRecorder.AddDemoMarker();
|
||||||
|
}
|
||||||
|
|
||||||
void CClient::Con_Record(IConsole::IResult *pResult, void *pUserData)
|
void CClient::Con_Record(IConsole::IResult *pResult, void *pUserData)
|
||||||
{
|
{
|
||||||
CClient *pSelf = (CClient *)pUserData;
|
CClient *pSelf = (CClient *)pUserData;
|
||||||
|
@ -2184,6 +2189,12 @@ void CClient::Con_StopRecord(IConsole::IResult *pResult, void *pUserData)
|
||||||
pSelf->DemoRecorder_Stop();
|
pSelf->DemoRecorder_Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CClient::Con_AddDemoMarker(IConsole::IResult *pResult, void *pUserData)
|
||||||
|
{
|
||||||
|
CClient *pSelf = (CClient *)pUserData;
|
||||||
|
pSelf->DemoRecorder_AddDemoMarker();
|
||||||
|
}
|
||||||
|
|
||||||
void CClient::ServerBrowserUpdate()
|
void CClient::ServerBrowserUpdate()
|
||||||
{
|
{
|
||||||
m_ResortServerBrowser = true;
|
m_ResortServerBrowser = true;
|
||||||
|
@ -2222,6 +2233,7 @@ void CClient::RegisterCommands()
|
||||||
m_pConsole->Register("play", "r", CFGFLAG_CLIENT|CFGFLAG_STORE, Con_Play, this, "Play the file specified");
|
m_pConsole->Register("play", "r", CFGFLAG_CLIENT|CFGFLAG_STORE, Con_Play, this, "Play the file specified");
|
||||||
m_pConsole->Register("record", "?s", CFGFLAG_CLIENT, Con_Record, this, "Record to the file");
|
m_pConsole->Register("record", "?s", CFGFLAG_CLIENT, Con_Record, this, "Record to the file");
|
||||||
m_pConsole->Register("stoprecord", "", CFGFLAG_CLIENT, Con_StopRecord, this, "Stop recording");
|
m_pConsole->Register("stoprecord", "", CFGFLAG_CLIENT, Con_StopRecord, this, "Stop recording");
|
||||||
|
m_pConsole->Register("add_demomarker", "", CFGFLAG_CLIENT, Con_AddDemoMarker, this, "Add demo timeline marker");
|
||||||
m_pConsole->Register("add_favorite", "s", CFGFLAG_CLIENT, Con_AddFavorite, this, "Add a server as a favorite");
|
m_pConsole->Register("add_favorite", "s", CFGFLAG_CLIENT, Con_AddFavorite, this, "Add a server as a favorite");
|
||||||
m_pConsole->Register("remove_favorite", "s", CFGFLAG_CLIENT, Con_RemoveFavorite, this, "Remove a server from favorites");
|
m_pConsole->Register("remove_favorite", "s", CFGFLAG_CLIENT, Con_RemoveFavorite, this, "Remove a server from favorites");
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,7 @@ public:
|
||||||
static void Con_Play(IConsole::IResult *pResult, void *pUserData);
|
static void Con_Play(IConsole::IResult *pResult, void *pUserData);
|
||||||
static void Con_Record(IConsole::IResult *pResult, void *pUserData);
|
static void Con_Record(IConsole::IResult *pResult, void *pUserData);
|
||||||
static void Con_StopRecord(IConsole::IResult *pResult, void *pUserData);
|
static void Con_StopRecord(IConsole::IResult *pResult, void *pUserData);
|
||||||
|
static void Con_AddDemoMarker(IConsole::IResult *pResult, void *pUserData);
|
||||||
static void ConchainServerBrowserUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
static void ConchainServerBrowserUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||||
|
|
||||||
void RegisterCommands();
|
void RegisterCommands();
|
||||||
|
@ -297,6 +298,7 @@ public:
|
||||||
void DemoRecorder_Start(const char *pFilename, bool WithTimestamp);
|
void DemoRecorder_Start(const char *pFilename, bool WithTimestamp);
|
||||||
void DemoRecorder_HandleAutoStart();
|
void DemoRecorder_HandleAutoStart();
|
||||||
void DemoRecorder_Stop();
|
void DemoRecorder_Stop();
|
||||||
|
void DemoRecorder_AddDemoMarker();
|
||||||
|
|
||||||
void AutoScreenshot_Start();
|
void AutoScreenshot_Start();
|
||||||
void AutoScreenshot_Cleanup();
|
void AutoScreenshot_Cleanup();
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
|
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MAX_TIMELINE_MARKERS=64
|
||||||
|
};
|
||||||
|
|
||||||
struct CDemoHeader
|
struct CDemoHeader
|
||||||
{
|
{
|
||||||
unsigned char m_aMarker[7];
|
unsigned char m_aMarker[7];
|
||||||
|
@ -16,6 +21,8 @@ struct CDemoHeader
|
||||||
char m_aType[8];
|
char m_aType[8];
|
||||||
char m_aLength[4];
|
char m_aLength[4];
|
||||||
char m_aTimestamp[20];
|
char m_aTimestamp[20];
|
||||||
|
char m_aNumTimelineMarkers[4];
|
||||||
|
char m_aTimelineMarkers[MAX_TIMELINE_MARKERS][4];
|
||||||
};
|
};
|
||||||
|
|
||||||
class IDemoPlayer : public IInterface
|
class IDemoPlayer : public IInterface
|
||||||
|
@ -31,6 +38,9 @@ public:
|
||||||
int m_FirstTick;
|
int m_FirstTick;
|
||||||
int m_CurrentTick;
|
int m_CurrentTick;
|
||||||
int m_LastTick;
|
int m_LastTick;
|
||||||
|
|
||||||
|
int m_NumTimelineMarkers;
|
||||||
|
int m_aTimelineMarkers[MAX_TIMELINE_MARKERS];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -42,7 +52,7 @@ public:
|
||||||
|
|
||||||
~IDemoPlayer() {}
|
~IDemoPlayer() {}
|
||||||
virtual void SetSpeed(float Speed) = 0;
|
virtual void SetSpeed(float Speed) = 0;
|
||||||
virtual int SetPos(float Precent) = 0;
|
virtual int SetPos(float Percent) = 0;
|
||||||
virtual void Pause() = 0;
|
virtual void Pause() = 0;
|
||||||
virtual void Unpause() = 0;
|
virtual void Unpause() = 0;
|
||||||
virtual const CInfo *BaseInfo() const = 0;
|
virtual const CInfo *BaseInfo() const = 0;
|
||||||
|
|
|
@ -13,8 +13,9 @@
|
||||||
#include "snapshot.h"
|
#include "snapshot.h"
|
||||||
|
|
||||||
static const unsigned char gs_aHeaderMarker[7] = {'T', 'W', 'D', 'E', 'M', 'O', 0};
|
static const unsigned char gs_aHeaderMarker[7] = {'T', 'W', 'D', 'E', 'M', 'O', 0};
|
||||||
static const unsigned char gs_ActVersion = 3;
|
static const unsigned char gs_ActVersion = 4;
|
||||||
static const int gs_LengthOffset = 152;
|
static const int gs_LengthOffset = 152;
|
||||||
|
static const int gs_NumMarkersOffset = 176;
|
||||||
|
|
||||||
|
|
||||||
CDemoRecorder::CDemoRecorder(class CSnapshotDelta *pSnapshotDelta)
|
CDemoRecorder::CDemoRecorder(class CSnapshotDelta *pSnapshotDelta)
|
||||||
|
@ -89,6 +90,8 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con
|
||||||
str_copy(Header.m_aType, pType, sizeof(Header.m_aType));
|
str_copy(Header.m_aType, pType, sizeof(Header.m_aType));
|
||||||
// Header.m_Length - add this on stop
|
// Header.m_Length - add this on stop
|
||||||
str_timestamp(Header.m_aTimestamp, sizeof(Header.m_aTimestamp));
|
str_timestamp(Header.m_aTimestamp, sizeof(Header.m_aTimestamp));
|
||||||
|
// Header.m_aNumTimelineMarkers - add this on stop
|
||||||
|
// Header.m_aTimelineMarkers - add this on stop
|
||||||
io_write(DemoFile, &Header, sizeof(Header));
|
io_write(DemoFile, &Header, sizeof(Header));
|
||||||
|
|
||||||
// write map data
|
// write map data
|
||||||
|
@ -105,6 +108,7 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con
|
||||||
m_LastKeyFrame = -1;
|
m_LastKeyFrame = -1;
|
||||||
m_LastTickMarker = -1;
|
m_LastTickMarker = -1;
|
||||||
m_FirstTick = -1;
|
m_FirstTick = -1;
|
||||||
|
m_NumTimelineMarkers = 0;
|
||||||
|
|
||||||
char aBuf[256];
|
char aBuf[256];
|
||||||
str_format(aBuf, sizeof(aBuf), "Recording to '%s'", pFilename);
|
str_format(aBuf, sizeof(aBuf), "Recording to '%s'", pFilename);
|
||||||
|
@ -266,6 +270,25 @@ int CDemoRecorder::Stop()
|
||||||
aLength[3] = (DemoLength)&0xff;
|
aLength[3] = (DemoLength)&0xff;
|
||||||
io_write(m_File, aLength, sizeof(aLength));
|
io_write(m_File, aLength, sizeof(aLength));
|
||||||
|
|
||||||
|
// add the timeline markers to the header
|
||||||
|
io_seek(m_File, gs_NumMarkersOffset, IOSEEK_START);
|
||||||
|
char aNumMarkers[4];
|
||||||
|
aNumMarkers[0] = (m_NumTimelineMarkers>>24)&0xff;
|
||||||
|
aNumMarkers[1] = (m_NumTimelineMarkers>>16)&0xff;
|
||||||
|
aNumMarkers[2] = (m_NumTimelineMarkers>>8)&0xff;
|
||||||
|
aNumMarkers[3] = (m_NumTimelineMarkers)&0xff;
|
||||||
|
io_write(m_File, aNumMarkers, sizeof(aNumMarkers));
|
||||||
|
for(int i = 0; i < m_NumTimelineMarkers; i++)
|
||||||
|
{
|
||||||
|
int Marker = m_aTimelineMarkers[i];
|
||||||
|
char aMarker[4];
|
||||||
|
aMarker[0] = (Marker>>24)&0xff;
|
||||||
|
aMarker[1] = (Marker>>16)&0xff;
|
||||||
|
aMarker[2] = (Marker>>8)&0xff;
|
||||||
|
aMarker[3] = (Marker)&0xff;
|
||||||
|
io_write(m_File, aMarker, sizeof(aMarker));
|
||||||
|
}
|
||||||
|
|
||||||
io_close(m_File);
|
io_close(m_File);
|
||||||
m_File = 0;
|
m_File = 0;
|
||||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", "Stopped recording");
|
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", "Stopped recording");
|
||||||
|
@ -273,6 +296,24 @@ int CDemoRecorder::Stop()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDemoRecorder::AddDemoMarker()
|
||||||
|
{
|
||||||
|
if(m_LastTickMarker < 0 || m_NumTimelineMarkers >= MAX_TIMELINE_MARKERS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// not more than 1 marker in a second
|
||||||
|
if(m_NumTimelineMarkers > 0)
|
||||||
|
{
|
||||||
|
int Diff = m_LastTickMarker - m_aTimelineMarkers[m_NumTimelineMarkers-1];
|
||||||
|
if(Diff < SERVER_TICK_SPEED*1.0f)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_aTimelineMarkers[m_NumTimelineMarkers++] = m_LastTickMarker;
|
||||||
|
|
||||||
|
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", "Added timeline marker");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CDemoPlayer::CDemoPlayer(class CSnapshotDelta *pSnapshotDelta)
|
CDemoPlayer::CDemoPlayer(class CSnapshotDelta *pSnapshotDelta)
|
||||||
|
@ -622,6 +663,16 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
|
||||||
mem_free(pMapData);
|
mem_free(pMapData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get timeline markers
|
||||||
|
int Num = ((m_Info.m_Header.m_aNumTimelineMarkers[0]<<24)&0xFF000000) | ((m_Info.m_Header.m_aNumTimelineMarkers[1]<<16)&0xFF0000) |
|
||||||
|
((m_Info.m_Header.m_aNumTimelineMarkers[2]<<8)&0xFF00) | (m_Info.m_Header.m_aNumTimelineMarkers[3]&0xFF);
|
||||||
|
m_Info.m_Info.m_NumTimelineMarkers = Num;
|
||||||
|
for(int i = 0; i < Num && i < MAX_TIMELINE_MARKERS; i++)
|
||||||
|
{
|
||||||
|
char *pTimelineMarker = m_Info.m_Header.m_aTimelineMarkers[i];
|
||||||
|
m_Info.m_Info.m_aTimelineMarkers[i] = ((pTimelineMarker[0]<<24)&0xFF000000) | ((pTimelineMarker[1]<<16)&0xFF0000) |
|
||||||
|
((pTimelineMarker[2]<<8)&0xFF00) | (pTimelineMarker[3]&0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
// scan the file for interessting points
|
// scan the file for interessting points
|
||||||
ScanFile();
|
ScanFile();
|
||||||
|
|
|
@ -17,6 +17,8 @@ class CDemoRecorder : public IDemoRecorder
|
||||||
int m_FirstTick;
|
int m_FirstTick;
|
||||||
unsigned char m_aLastSnapshotData[CSnapshot::MAX_SIZE];
|
unsigned char m_aLastSnapshotData[CSnapshot::MAX_SIZE];
|
||||||
class CSnapshotDelta *m_pSnapshotDelta;
|
class CSnapshotDelta *m_pSnapshotDelta;
|
||||||
|
int m_NumTimelineMarkers;
|
||||||
|
int m_aTimelineMarkers[MAX_TIMELINE_MARKERS];
|
||||||
|
|
||||||
void WriteTickMarker(int Tick, int Keyframe);
|
void WriteTickMarker(int Tick, int Keyframe);
|
||||||
void Write(int Type, const void *pData, int Size);
|
void Write(int Type, const void *pData, int Size);
|
||||||
|
@ -25,6 +27,7 @@ public:
|
||||||
|
|
||||||
int Start(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, const char *pNetversion, const char *pMap, unsigned MapCrc, const char *pType);
|
int Start(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, const char *pNetversion, const char *pMap, unsigned MapCrc, const char *pType);
|
||||||
int Stop();
|
int Stop();
|
||||||
|
void AddDemoMarker();
|
||||||
|
|
||||||
void RecordSnapshot(int Tick, const void *pData, int Size);
|
void RecordSnapshot(int Tick, const void *pData, int Size);
|
||||||
void RecordMessage(const void *pData, int Size);
|
void RecordMessage(const void *pData, int Size);
|
||||||
|
@ -108,7 +111,7 @@ public:
|
||||||
void Unpause();
|
void Unpause();
|
||||||
int Stop();
|
int Stop();
|
||||||
void SetSpeed(float Speed);
|
void SetSpeed(float Speed);
|
||||||
int SetPos(float Precent);
|
int SetPos(float Percent);
|
||||||
const CInfo *BaseInfo() const { return &m_Info.m_Info; }
|
const CInfo *BaseInfo() const { return &m_Info.m_Info; }
|
||||||
void GetDemoName(char *pBuffer, int BufferSize) const;
|
void GetDemoName(char *pBuffer, int BufferSize) const;
|
||||||
bool GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, CDemoHeader *pDemoHeader) const;
|
bool GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, CDemoHeader *pDemoHeader) const;
|
||||||
|
|
|
@ -86,15 +86,28 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
|
||||||
void *id = &s_SeekBarID;
|
void *id = &s_SeekBarID;
|
||||||
char aBuffer[128];
|
char aBuffer[128];
|
||||||
|
|
||||||
|
// draw seek bar
|
||||||
RenderTools()->DrawUIRect(&SeekBar, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 5.0f);
|
RenderTools()->DrawUIRect(&SeekBar, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 5.0f);
|
||||||
|
|
||||||
|
// draw filled bar
|
||||||
float Amount = CurrentTick/(float)TotalTicks;
|
float Amount = CurrentTick/(float)TotalTicks;
|
||||||
|
|
||||||
CUIRect FilledBar = SeekBar;
|
CUIRect FilledBar = SeekBar;
|
||||||
FilledBar.w = 10.0f + (FilledBar.w-10.0f)*Amount;
|
FilledBar.w = 10.0f + (FilledBar.w-10.0f)*Amount;
|
||||||
|
|
||||||
RenderTools()->DrawUIRect(&FilledBar, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 5.0f);
|
RenderTools()->DrawUIRect(&FilledBar, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 5.0f);
|
||||||
|
|
||||||
|
// draw markers
|
||||||
|
for(int i = 0; i < pInfo->m_NumTimelineMarkers; i++)
|
||||||
|
{
|
||||||
|
float Ratio = (pInfo->m_aTimelineMarkers[i]-pInfo->m_FirstTick) / (float)TotalTicks;
|
||||||
|
Graphics()->TextureSet(-1);
|
||||||
|
Graphics()->QuadsBegin();
|
||||||
|
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
IGraphics::CQuadItem QuadItem(SeekBar.x + (SeekBar.w-10.0f)*Ratio, SeekBar.y, UI()->PixelSize(), SeekBar.h);
|
||||||
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||||
|
Graphics()->QuadsEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw time
|
||||||
str_format(aBuffer, sizeof(aBuffer), "%d:%02d / %d:%02d",
|
str_format(aBuffer, sizeof(aBuffer), "%d:%02d / %d:%02d",
|
||||||
CurrentTick/SERVER_TICK_SPEED/60, (CurrentTick/SERVER_TICK_SPEED)%60,
|
CurrentTick/SERVER_TICK_SPEED/60, (CurrentTick/SERVER_TICK_SPEED)%60,
|
||||||
TotalTicks/SERVER_TICK_SPEED/60, (TotalTicks/SERVER_TICK_SPEED)%60);
|
TotalTicks/SERVER_TICK_SPEED/60, (TotalTicks/SERVER_TICK_SPEED)%60);
|
||||||
|
|
|
@ -74,6 +74,11 @@ CUIRect *CUI::Screen()
|
||||||
return &m_Screen;
|
return &m_Screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float CUI::PixelSize()
|
||||||
|
{
|
||||||
|
return Screen()->w/Graphics()->ScreenWidth();
|
||||||
|
}
|
||||||
|
|
||||||
void CUI::SetScale(float s)
|
void CUI::SetScale(float s)
|
||||||
{
|
{
|
||||||
g_Config.m_UiScale = (int)(s*100.0f);
|
g_Config.m_UiScale = (int)(s*100.0f);
|
||||||
|
|
|
@ -82,6 +82,7 @@ public:
|
||||||
void ConvertMouseMove(float *x, float *y);
|
void ConvertMouseMove(float *x, float *y);
|
||||||
|
|
||||||
CUIRect *Screen();
|
CUIRect *Screen();
|
||||||
|
float PixelSize();
|
||||||
void ClipEnable(const CUIRect *pRect);
|
void ClipEnable(const CUIRect *pRect);
|
||||||
void ClipDisable();
|
void ClipDisable();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue