made demo readable for custom map that user doesn't have (#5)

This commit is contained in:
Choupom 2010-09-03 21:17:32 +02:00 committed by oy
parent 3dd1ea0d8f
commit 0198e51fa3
3 changed files with 80 additions and 2 deletions

View file

@ -289,7 +289,7 @@ unsigned io_read(IOHANDLE io, void *buffer, unsigned size)
return fread(buffer, 1, size, (FILE*)io);
}
unsigned io_skip(IOHANDLE io, unsigned size)
unsigned io_skip(IOHANDLE io, int size)
{
fseek((FILE*)io, size, SEEK_CUR);
return size;

View file

@ -222,7 +222,7 @@ unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
Returns:
Number of bytes skipped.
*/
unsigned io_skip(IOHANDLE io, unsigned size);
unsigned io_skip(IOHANDLE io, int size);
/*
Function: io_write

View file

@ -10,6 +10,8 @@
#include "engine.h"
static const unsigned char gs_aHeaderMarker[8] = {'T', 'W', 'D', 'E', 'M', 'O', 0, 1};
static const unsigned char gs_aMapMarker[5] = {'M', 'A', 'P', 0, 1};
CDemoRecorder::CDemoRecorder(class CSnapshotDelta *pSnapshotDelta)
{
@ -50,6 +52,38 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con
Header.m_aCrc[3] = (Crc)&0xff;
io_write(m_File, &Header, sizeof(Header));
// write map
char aMapFilename[128];
str_format(aMapFilename, sizeof(aMapFilename), "downloadedmaps/%s_%08x.map", pMap, Crc);
IOHANDLE MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_READ);
if(MapFile)
{
// write map marker
io_write(m_File, &gs_aMapMarker, sizeof(gs_aMapMarker));
// 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)
{
unsigned char aChunk[1024*64];
int Bytes = io_read(MapFile, &aChunk, sizeof(aChunk));
if(Bytes <= 0)
break;
io_write(m_File, &aChunk, Bytes);
}
io_close(MapFile);
}
m_LastKeyFrame = -1;
m_LastTickMarker = -1;
@ -498,6 +532,50 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
return -1;
}
// check if the demo includes a map
unsigned char aMapMarker[5];
io_read(m_File, &aMapMarker, sizeof(aMapMarker));
if(mem_comp(aMapMarker, gs_aMapMarker, sizeof(gs_aMapMarker)) == 0)
{
// 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
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);
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);
io_write(MapFile, pMapData, MapSize);
io_close(MapFile);
// free data
mem_free(pMapData);
}
}
else // no map in the demo
{
io_skip(m_File, -sizeof(aMapMarker));
}
// scan the file for interessting points
ScanFile();