3
@author Tobi Vollebregt
4
@brief Defines the Spring demofile format
6
This file defines the Spring demofile format and which parts of it are supposed
7
to be stable (can be used safely by 3rd party applications) or unstable (format
8
may change every Spring release without notice).
14
#include "Platform/byteorder.h"
15
#include <boost/cstdint.hpp>
17
/** The first 16 bytes of each demofile. */
18
#define DEMOFILE_MAGIC "spring demofile"
20
/** The current demofile version. Only change on major modifications for which
21
appending stuff to DemoFileHeader is not sufficient. */
22
#define DEMOFILE_VERSION 4
27
@brief Spring demo file main header
29
Demo file layout is like this:
33
- Startscript (scriptSize)
34
- Demo stream (demoStreamSize)
35
- Player statistics, one PlayerStatistic for each player
36
- Team statistics, consisting of:
37
- Array of numTeams dwords indicating the number of
38
CTeam::Statistics for each team.
39
- Array of all CTeam::Statistics (total number of items is the
40
sum of the elements in the array of dwords).
42
The header is designed to be extensible: it contains a version field and a
43
headerSize field to support this. The version field is a major version number
44
of the file format, if this changes, anything may have changed in the file.
45
It is not supposed to change often (if at all). The headerSize field is a
46
minor version number, which happens to be equal to sizeof(DemoFileHeader).
48
If Spring didn't cleanup properly (crashed), the demoStreamSize is 0 and it
49
can be assumed the demo stream continues until the end of the file.
53
char magic[16]; ///< DEMOFILE_MAGIC
54
int version; ///< DEMOFILE_VERSION
55
int headerSize; ///< Size of the DemoFileHeader, minor version number.
56
char versionString[16]; ///< Spring version string, e.g. "0.75b2", "0.75b2+svn4123"
57
boost::uint8_t gameID[16]; ///< Unique game identifier. Identical for each player of the game.
58
boost::uint64_t unixTime; ///< Unix time when game was started.
59
int scriptSize; ///< Size of startscript.
60
int demoStreamSize; ///< Size of the demo stream.
61
int gameTime; ///< Total number of seconds game time.
62
int wallclockTime; ///< Total number of seconds wallclock time.
63
int numPlayers; ///< Number of players for which stats are saved.
64
int playerStatSize; ///< Size of the entire player statistics chunk.
65
int playerStatElemSize; ///< sizeof(CPlayer::Statistics)
66
int numTeams; ///< Number of teams for which stats are saved.
67
int teamStatSize; ///< Size of the entire team statistics chunk.
68
int teamStatElemSize; ///< sizeof(CTeam::Statistics)
69
int teamStatPeriod; ///< Interval (in seconds) between team stats.
70
int winningAllyTeam; ///< The ally team that won the game, -1 if unknown.
72
/// Change structure from host endian to little endian or vice versa.
74
version = swabdword(version);
75
headerSize = swabdword(headerSize);
76
// FIXME endian: unixTime = swabqword(unixTime);
77
scriptSize = swabdword(scriptSize);
78
demoStreamSize = swabdword(demoStreamSize);
79
gameTime = swabdword(gameTime);
80
wallclockTime = swabdword(wallclockTime);
81
numPlayers = swabdword(numPlayers);
82
playerStatSize = swabdword(playerStatSize);
83
playerStatElemSize = swabdword(playerStatElemSize);
84
numTeams = swabdword(numTeams);
85
teamStatSize = swabdword(teamStatSize);
86
teamStatElemSize = swabdword(teamStatElemSize);
87
teamStatPeriod = swabdword(teamStatPeriod);
88
winningAllyTeam = swabdword(winningAllyTeam);
93
@brief Spring demo stream chunk header
95
The demo stream layout is as follows:
97
- DemoStreamChunkHeader
98
- length bytes raw data from network stream
99
- DemoStreamChunkHeader
100
- length bytes raw data from network stream
103
struct DemoStreamChunkHeader
105
float modGameTime; ///< Gametime at which this chunk was written/should be read.
106
boost::uint32_t length; ///< Length of the chunk of data following this header.
108
/// Change structure from host endian to little endian or vice versa.
110
modGameTime = swabfloat(modGameTime);
111
length = swabdword(length);