added demo markers by Choupom. Closes #837

This commit is contained in:
oy 2012-01-10 23:13:19 +01:00
parent e8f9145a0d
commit fa81141110
8 changed files with 102 additions and 5 deletions

View file

@ -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");

View file

@ -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();

View file

@ -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;

View file

@ -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();

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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();