about summary refs log tree commit diff
path: root/src/engine
diff options
context:
space:
mode:
authoroy <Tom_Adams@web.de>2011-03-13 10:41:10 +0100
committeroy <Tom_Adams@web.de>2011-03-13 10:41:10 +0100
commitbe8f669333b01e32465c515728fccabaa627bd37 (patch)
tree7d15faa5df6a9f7149d25c3b2e0fcb93c16dca8d /src/engine
parenta04eb45354cfbdc32f92438400c11071ecf1bb6c (diff)
downloadzcatch-be8f669333b01e32465c515728fccabaa627bd37.tar.gz
zcatch-be8f669333b01e32465c515728fccabaa627bd37.zip
added extended demo infos in the demo browser
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/client/client.cpp10
-rw-r--r--src/engine/demo.h15
-rw-r--r--src/engine/shared/demo.cpp128
-rw-r--r--src/engine/shared/demo.h16
4 files changed, 90 insertions, 79 deletions
diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp
index 125991c1..5ed0b37b 100644
--- a/src/engine/client/client.cpp
+++ b/src/engine/client/client.cpp
@@ -2120,11 +2120,11 @@ const char *CClient::DemoPlayer_Play(const char *pFilename, int StorageType)
 		return "error loading demo";
 
 	// load map
-	Crc = (m_DemoPlayer.Info()->m_Header.m_aCrc[0]<<24)|
-		(m_DemoPlayer.Info()->m_Header.m_aCrc[1]<<16)|
-		(m_DemoPlayer.Info()->m_Header.m_aCrc[2]<<8)|
-		(m_DemoPlayer.Info()->m_Header.m_aCrc[3]);
-	pError = LoadMapSearch(m_DemoPlayer.Info()->m_Header.m_aMap, Crc);
+	Crc = (m_DemoPlayer.Info()->m_Header.m_aMapCrc[0]<<24)|
+		(m_DemoPlayer.Info()->m_Header.m_aMapCrc[1]<<16)|
+		(m_DemoPlayer.Info()->m_Header.m_aMapCrc[2]<<8)|
+		(m_DemoPlayer.Info()->m_Header.m_aMapCrc[3]);
+	pError = LoadMapSearch(m_DemoPlayer.Info()->m_Header.m_aMapName, Crc);
 	if(pError)
 	{
 		DisconnectWithReason(pError);
diff --git a/src/engine/demo.h b/src/engine/demo.h
index a6841a9e..1ba888a9 100644
--- a/src/engine/demo.h
+++ b/src/engine/demo.h
@@ -5,6 +5,19 @@
 
 #include "kernel.h"
 
+struct CDemoHeader
+{
+	unsigned char m_aMarker[7];
+	unsigned char m_Version;
+	char m_aNetversion[64];
+	char m_aMapName[64];
+	char m_aMapSize[4];
+	unsigned char m_aMapCrc[4];
+	char m_aType[8];
+	char m_aLength[4];
+	char m_aTimestamp[20];
+};
+
 class IDemoPlayer : public IInterface
 {
 	MACRO_INTERFACE("demoplayer", 0)
@@ -34,7 +47,7 @@ public:
 	virtual void Unpause() = 0;
 	virtual const CInfo *BaseInfo() const = 0;
 	virtual char *GetDemoName() = 0;
-	virtual bool GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, char *pMap, int BufferSize) const = 0;
+	virtual bool GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, CDemoHeader *pDemoHeader) const = 0;
 	virtual int GetDemoType() const = 0;
 };
 
diff --git a/src/engine/shared/demo.cpp b/src/engine/shared/demo.cpp
index 586e7318..87d0951c 100644
--- a/src/engine/shared/demo.cpp
+++ b/src/engine/shared/demo.cpp
@@ -2,7 +2,6 @@
 /* If you are missing that file, acquire a complete release at teeworlds.com.                */
 #include <base/system.h>
 #include <engine/console.h>
-#include <engine/shared/protocol.h>
 #include <engine/storage.h>
 #include "demo.h"
 #include "memheap.h"
@@ -11,12 +10,8 @@
 #include "network.h"
 
 static const unsigned char gs_aHeaderMarker[7] = {'T', 'W', 'D', 'E', 'M', 'O', 0};
-static const unsigned char gs_ActVersion = 2;
-static const unsigned char gs_VersionWithMap = 2;
-
-//Versions :
-//1 : 0.5.0
-//2 : 0.5.3/0.6.0, includes the map
+static const unsigned char gs_ActVersion = 3;
+static const int gs_LengthOffset = 152;
 
 
 CDemoRecorder::CDemoRecorder(class CSnapshotDelta *pSnapshotDelta)
@@ -72,25 +67,21 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con
 	mem_copy(Header.m_aMarker, gs_aHeaderMarker, sizeof(Header.m_aMarker));
 	Header.m_Version = gs_ActVersion;
 	str_copy(Header.m_aNetversion, pNetVersion, sizeof(Header.m_aNetversion));
-	str_copy(Header.m_aMap, pMap, sizeof(Header.m_aMap));
+	str_copy(Header.m_aMapName, pMap, sizeof(Header.m_aMapName));
+	int MapSize = io_length(MapFile);
+	Header.m_aMapSize[0] = (MapSize>>24)&0xff;
+	Header.m_aMapSize[1] = (MapSize>>16)&0xff;
+	Header.m_aMapSize[2] = (MapSize>>8)&0xff;
+	Header.m_aMapSize[3] = (MapSize)&0xff;
+	Header.m_aMapCrc[0] = (Crc>>24)&0xff;
+	Header.m_aMapCrc[1] = (Crc>>16)&0xff;
+	Header.m_aMapCrc[2] = (Crc>>8)&0xff;
+	Header.m_aMapCrc[3] = (Crc)&0xff;
 	str_copy(Header.m_aType, pType, sizeof(Header.m_aType));
-	Header.m_aCrc[0] = (Crc>>24)&0xff;
-	Header.m_aCrc[1] = (Crc>>16)&0xff;
-	Header.m_aCrc[2] = (Crc>>8)&0xff;
-	Header.m_aCrc[3] = (Crc)&0xff;
+	// Header.m_Length - add this on stop
+	str_timestamp(Header.m_aTimestamp, sizeof(Header.m_aTimestamp));
 	io_write(m_File, &Header, sizeof(Header));
 	
-	
-	// write map
-	// write map size
-	int MapSize = io_length(MapFile);
-	unsigned char aBufMapSize[4];
-	aBufMapSize[0] = (MapSize>>24)&0xff;
-	aBufMapSize[1] = (MapSize>>16)&0xff;
-	aBufMapSize[2] = (MapSize>>8)&0xff;
-	aBufMapSize[3] = (MapSize)&0xff;
-	io_write(m_File, &aBufMapSize, sizeof(aBufMapSize));
-		
 	// write map data
 	while(1)
 	{
@@ -253,6 +244,16 @@ int CDemoRecorder::Stop()
 {
 	if(!m_File)
 		return -1;
+
+	// add the demo length to the header
+	io_seek(m_File, gs_LengthOffset, IOSEEK_START);
+	int DemoLength = Length()/SERVER_TICK_SPEED;
+	char aLength[4];
+	aLength[0] = (DemoLength>>24)&0xff;
+	aLength[1] = (DemoLength>>16)&0xff;
+	aLength[2] = (DemoLength>>8)&0xff;
+	aLength[3] = (DemoLength)&0xff;
+	io_write(m_File, aLength, sizeof(aLength));
 		
 	m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", "Stopped recording");
 	io_close(m_File);
@@ -542,7 +543,6 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
 	mem_zero(&m_Info, sizeof(m_Info));
 	m_Info.m_Info.m_FirstTick = -1;
 	m_Info.m_Info.m_LastTick = -1;
-	//m_Info.start_tick = -1;
 	m_Info.m_NextTick = -1;
 	m_Info.m_Info.m_CurrentTick = -1;
 	m_Info.m_PreviousTick = -1;
@@ -561,6 +561,16 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
 		m_File = 0;
 		return -1;
 	}
+
+	if(m_Info.m_Header.m_Version < gs_ActVersion)
+	{
+		char aBuf[256];
+		str_format(aBuf, sizeof(aBuf), "demo version %d is not supported", m_Info.m_Header.m_Version);
+		m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_player", aBuf);
+		io_close(m_File);
+		m_File = 0;
+		return -1;
+	}
 	
 	// get demo type
 	if(!str_comp(m_Info.m_Header.m_aType, "client"))
@@ -569,40 +579,34 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
 		m_DemoType = DEMOTYPE_SERVER;
 	else DEMOTYPE_INVALID;
 	
-	// get map
-	if(m_Info.m_Header.m_Version >= gs_VersionWithMap)
-	{
-		// get map size
-		unsigned char aBufMapSize[4];
-		io_read(m_File, &aBufMapSize, sizeof(aBufMapSize));
-		int MapSize = (aBufMapSize[0]<<24) | (aBufMapSize[1]<<16) | (aBufMapSize[2]<<8) | (aBufMapSize[3]);
-		
-		// check if we already have the map
-		// TODO: improve map checking (maps folder, check crc)
-		int Crc = (m_Info.m_Header.m_aCrc[0]<<24) | (m_Info.m_Header.m_aCrc[1]<<16) | (m_Info.m_Header.m_aCrc[2]<<8) | (m_Info.m_Header.m_aCrc[3]);
-		char aMapFilename[128];
-		str_format(aMapFilename, sizeof(aMapFilename), "downloadedmaps/%s_%08x.map", m_Info.m_Header.m_aMap, Crc);
-		IOHANDLE MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_READ, IStorage::TYPE_ALL);
+	// read map
+	int MapSize = (m_Info.m_Header.m_aMapSize[0]<<24) | (m_Info.m_Header.m_aMapSize[1]<<16) | (m_Info.m_Header.m_aMapSize[2]<<8) | (m_Info.m_Header.m_aMapSize[3]);
+	
+	// check if we already have the map
+	// TODO: improve map checking (maps folder, check crc)
+	int Crc = (m_Info.m_Header.m_aMapCrc[0]<<24) | (m_Info.m_Header.m_aMapCrc[1]<<16) | (m_Info.m_Header.m_aMapCrc[2]<<8) | (m_Info.m_Header.m_aMapCrc[3]);
+	char aMapFilename[128];
+	str_format(aMapFilename, sizeof(aMapFilename), "downloadedmaps/%s_%08x.map", m_Info.m_Header.m_aMapName, Crc);
+	IOHANDLE MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_READ, IStorage::TYPE_ALL);
 		
-		if(MapFile)
-		{
-			io_skip(m_File, MapSize);
-			io_close(MapFile);
-		}
-		else if(MapSize > 0)
-		{
-			// get map data
-			unsigned char *pMapData = (unsigned char *)mem_alloc(MapSize, 1);
-			io_read(m_File, pMapData, MapSize);
+	if(MapFile)
+	{
+		io_skip(m_File, MapSize);
+		io_close(MapFile);
+	}
+	else if(MapSize > 0)
+	{
+		// get map data
+		unsigned char *pMapData = (unsigned char *)mem_alloc(MapSize, 1);
+		io_read(m_File, pMapData, MapSize);
 			
-			// save map
-			MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
-			io_write(MapFile, pMapData, MapSize);
-			io_close(MapFile);
+		// save map
+		MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
+		io_write(MapFile, pMapData, MapSize);
+		io_close(MapFile);
 			
-			// free data
-			mem_free(pMapData);
-		}
+		// free data
+		mem_free(pMapData);
 	}
 	
 	
@@ -758,22 +762,24 @@ char *CDemoPlayer::GetDemoName()
 	return pDemoShortName;
 }
 
-bool CDemoPlayer::GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, char *pMap, int BufferSize) const
+bool CDemoPlayer::GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, CDemoHeader *pDemoHeader) const
 {
+	if(!pDemoHeader)
+		return false;
+	
+	mem_zero(pDemoHeader, sizeof(CDemoHeader));
+
 	IOHANDLE File = pStorage->OpenFile(pFilename, IOFLAG_READ, StorageType);
 	if(!File)
 		return false;
 	
-	CDemoHeader Header;
-	io_read(File, &Header, sizeof(Header));
-	if(mem_comp(Header.m_aMarker, gs_aHeaderMarker, sizeof(gs_aHeaderMarker)) != 0)
+	io_read(File, pDemoHeader, sizeof(CDemoHeader));
+	if(mem_comp(pDemoHeader->m_aMarker, gs_aHeaderMarker, sizeof(gs_aHeaderMarker)) || pDemoHeader->m_Version < gs_ActVersion)
 	{
 		io_close(File);
 		return false;
 	}
 	
-	str_copy(pMap, Header.m_aMap, BufferSize);
-	
 	io_close(File);
 	return true;
 }
diff --git a/src/engine/shared/demo.h b/src/engine/shared/demo.h
index ad7566c7..ad8e82b5 100644
--- a/src/engine/shared/demo.h
+++ b/src/engine/shared/demo.h
@@ -4,17 +4,9 @@
 #define ENGINE_SHARED_DEMO_H
 
 #include <engine/demo.h>
-#include "snapshot.h"
+#include <engine/shared/protocol.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];
-};
+#include "snapshot.h"
 
 class CDemoRecorder : public IDemoRecorder
 {
@@ -39,7 +31,7 @@ public:
 
 	bool IsRecording() const { return m_File != 0; }
 
-	int Length() const { return m_LastTickMarker - m_FirstTick; }
+	int Length() const { return (m_LastTickMarker - m_FirstTick)/SERVER_TICK_SPEED; }
 };
 
 class CDemoPlayer : public IDemoPlayer
@@ -119,7 +111,7 @@ public:
 	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;
+	bool GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, CDemoHeader *pDemoHeader) const;
 	int GetDemoType() const;
 	
 	int Update();