Skip to content

Commit

Permalink
libcommon: Detect the serialized map state format from the header
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Mar 17, 2014
1 parent 9fa76a1 commit 21bdf43
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 317 deletions.
13 changes: 3 additions & 10 deletions doomsday/plugins/common/include/p_saveg.h
Expand Up @@ -35,7 +35,8 @@ class MapStateWriter;
*
* @return New reader instance if recognized. Ownership given to the caller.
*/
std::auto_ptr<de::game::MapStateReader> SV_MapStateReader(de::game::SavedSession &session);
std::auto_ptr<de::game::MapStateReader>
SV_MapStateReader(de::game::SavedSession const &session, de::String mapUriStr);

DENG_EXTERN_C int saveToRealPlayerNum[MAXPLAYERS];

Expand Down Expand Up @@ -88,12 +89,6 @@ void SV_ReadLine(Line *line, MapStateReader *msr);
void SV_WriteSector(Sector *sec, MapStateWriter *msw);
void SV_ReadSector(Sector *sec, MapStateReader *msr);

#endif // __cplusplus

#ifdef __cplusplus
extern "C" {
#endif

#if !__JHEXEN__
/**
* Saves a snapshot of the world, a still image.
Expand All @@ -104,8 +99,6 @@ void SV_SaveGameClient(uint gameId);
void SV_LoadGameClient(uint gameId);
#endif

#ifdef __cplusplus
} // extern "C"
#endif
#endif // __cplusplus

#endif // LIBCOMMON_SAVESTATE_H
46 changes: 13 additions & 33 deletions doomsday/plugins/common/include/p_saveio.h
Expand Up @@ -23,9 +23,10 @@

#include <de/game/SavedSession>
#include <de/Path>
#include <de/Reader>
#include <de/reader.h>
#include <de/writer.h>
#include "lzss.h"
#include "lzss.h" /// @todo remove me

typedef enum savestatesegment_e {
ASEG_MAP_HEADER = 102, // Hexen only
Expand All @@ -44,39 +45,18 @@ typedef enum savestatesegment_e {
ASEG_WORLDSCRIPTDATA // Hexen only
} savestatesegment_t;

#if __JHEXEN__
typedef union saveptr_u {
byte *b;
short *w;
int *l;
float *f;
} saveptr_t;
#endif

/*
* File management
*/

bool SV_ExistingFile(de::Path filePath);

int SV_RemoveFile(de::Path filePath);

void SV_CopyFile(de::Path srcFilePath, de::Path destFilePath);

bool SV_OpenFile(de::Path filePath, bool write);

void SV_CloseFile();
bool SV_OpenFile(de::File const &file);

#if __JHEXEN__
saveptr_t *SV_HxSavePtr();

void SV_HxSetSaveEndPtr(void *endPtr);

size_t SV_HxBytesLeft();

void SV_HxReleaseSaveBuffer();
#endif // __JHEXEN__
/// @todo remove me
bool SV_OpenFile_LZSS(de::Path filePath);
void SV_CloseFile_LZSS();

#if 0
/**
* Exit with a fatal error if the value at the current location in the
* game-save file does not match that associated with the segment id.
Expand All @@ -89,19 +69,19 @@ void SV_BeginSegment(int segmentId);

void SV_EndSegment();

#endif

void SV_WriteSessionMetadata(de::game::SessionMetadata const &metadata, Writer *writer);

void SV_WriteConsistencyBytes();

void SV_ReadConsistencyBytes();

/**
* Seek forward @a offset bytes in the save file.
*/
void SV_Seek(uint offset);
//void SV_ReadConsistencyBytes();

Writer *SV_NewWriter();

Reader *SV_NewReader();

/// Provides access to the wrapped de::Reader instance used for deserialization.
de::Reader &SV_RawReader();

#endif // LIBCOMMON_SAVESTATE_INPUT_OUTPUT_H
15 changes: 7 additions & 8 deletions doomsday/plugins/common/src/g_game.cpp
Expand Up @@ -1371,8 +1371,8 @@ int G_DoLoadMap(loadmap_params_t *p)

// Is MapInfo data available for this map?
ddmapinfo_t mapInfo;
AutoStr *mapUriStr = Uri_Compose(p->mapUri);
bool haveMapInfo = Def_Get(DD_DEF_MAP_INFO, Str_Text(mapUriStr), &mapInfo);
de::String mapUriStr = Str_Text(Uri_Compose(p->mapUri));
bool haveMapInfo = Def_Get(DD_DEF_MAP_INFO, mapUriStr.toUtf8().constData(), &mapInfo);

P_SetupMap(p->mapUri);
initFogForMap(haveMapInfo? &mapInfo : 0);
Expand All @@ -1389,7 +1389,7 @@ int G_DoLoadMap(loadmap_params_t *p)
try
{
de::game::SavedSession &session = G_SaveSlots()["base"].savedSession();
SV_MapStateReader(session)->read(Str_Text(Uri_Compose(gameMapUri)));
SV_MapStateReader(session, mapUriStr)->read(mapUriStr);
}
catch(de::Error const &er)
{
Expand Down Expand Up @@ -3006,7 +3006,7 @@ void G_DoLeaveMap()
// SaveSlot &sslot = G_SaveSlots()["base"];
de::Path const mapStateFilePath(Str_Text(Uri_Compose(gameMapUri)));

if(!SV_OpenFile(mapStateFilePath, true/*for write*/))
if(!SV_OpenFile_LZSS(mapStateFilePath))
{
throw de::Error("G_DoLeaveMap", "Failed opening \"" + de::NativePath(mapStateFilePath).pretty() + "\" for write");
}
Expand All @@ -3019,10 +3019,8 @@ void G_DoLeaveMap()

MapStateWriter(thingArchive).write(writer);

// Close the output file
SV_CloseFile();

Writer_Delete(writer);
SV_CloseFile_LZSS();
}
}
else // Entering new hub.
Expand Down Expand Up @@ -3267,7 +3265,8 @@ void G_DoLoadSession(de::String slotId)
mapTime = metadata.geti("mapTime");
#endif

SV_MapStateReader(session)->read(Str_Text(Uri_Resolved(gameMapUri)));
de::String mapUriStr = Str_Text(Uri_Resolved(gameMapUri));
SV_MapStateReader(session, mapUriStr)->read(mapUriStr);

// Make note of the last used save slot.
Con_SetInteger2("game-save-last-slot", slotId.toInt(), SVF_WRITE_OVERRIDE);
Expand Down
10 changes: 5 additions & 5 deletions doomsday/plugins/common/src/gamestatewriter.cpp
Expand Up @@ -129,9 +129,9 @@ void GameStateWriter::write(Path const &stateFilePath, Path const &mapStateFileP
NetSv_SaveGame(metadata["sessionId"].value().asNumber());
#endif

if(!SV_OpenFile(stateFilePath, true/*for writing*/))
if(!SV_OpenFile_LZSS(stateFilePath))
{
throw FileAccessError("GameStateWriter", "Failed opening \"" + NativePath(stateFilePath).pretty() + "\"");
throw FileAccessError("GameStateWriter", "Failed opening \"" + NativePath(stateFilePath).pretty() + "\" for write");
}

d->writer = SV_NewWriter();
Expand All @@ -151,16 +151,16 @@ void GameStateWriter::write(Path const &stateFilePath, Path const &mapStateFileP
{
// The map state is actually written to a separate file.
// Close the game state file.
SV_CloseFile();
SV_CloseFile_LZSS();

// Open the map state file.
SV_OpenFile(mapStateFilePath, true/*for write*/);
SV_OpenFile_LZSS(mapStateFilePath);
}

d->writeMap();

d->writeConsistencyBytes(); // To be absolutely sure...
SV_CloseFile();
SV_CloseFile_LZSS();

// Cleanup.
delete d->thingArchive; d->thingArchive = 0;
Expand Down
85 changes: 4 additions & 81 deletions doomsday/plugins/common/src/mapstatereader.cpp
Expand Up @@ -35,9 +35,7 @@
#include "r_common.h"
#include "thinkerinfo.h"
#include <de/ArrayValue>
#include <de/FixedByteArray>
#include <de/NativePath>
#include <de/Reader>
#include <de/String>

namespace internal
Expand All @@ -58,81 +56,6 @@ namespace internal
DENG2_UNUSED(mapVersion);
#endif
}

static de::Reader *reader;

static char sri8(reader_s *r)
{
if(!r) return 0;
int8_t val;
DENG2_ASSERT(reader);
*reader >> val;
return char(val);
}

static short sri16(reader_s *r)
{
if(!r) return 0;
int16_t val;
DENG2_ASSERT(reader);
*reader >> val;
return short(val);
}

static int sri32(reader_s *r)
{
if(!r) return 0;
DENG2_ASSERT(reader);
int32_t val;
*reader >> val;
return int(val);
}

static float srf(reader_s *r)
{
if(!r) return 0;
DENG2_ASSERT(reader);
DENG2_ASSERT(sizeof(float) == 4);
int32_t val;
*reader >> val;
float rerVal = 0;
std::memcpy(&rerVal, &val, 4);
return rerVal;
}

static void srd(reader_s *r, char *data, int len)
{
if(!r) return;
DENG2_ASSERT(reader);
if(data)
{
de::Block tmp(len);
*reader >> de::FixedByteArray(tmp);
tmp.get(0, (de::Block::Byte *)data, len);
}
else
{
reader->seek(len);
}
}

static reader_s *newReader()
{
DENG2_ASSERT(reader != 0);
return Reader_NewWithCallbacks(sri8, sri16, sri32, srf, srd);
}

static void closeFile()
{
delete reader; reader = 0;
}

static bool openFile(de::File const &file)
{
closeFile();
reader = new de::Reader(file);
return true;
}
}

using namespace internal;
Expand Down Expand Up @@ -180,7 +103,7 @@ DENG2_PIMPL(MapStateReader)
void beginSegment(int segId)
{
#if __JHEXEN__
if(segId == ASEG_END && (::reader)->source()->size() - (::reader)->offset() < 4)
if(segId == ASEG_END && SV_RawReader().source()->size() - SV_RawReader().offset() < 4)
{
App_Log(DE2_LOG_WARNING, "Savegame lacks ASEG_END marker (unexpected end-of-file)");
return;
Expand Down Expand Up @@ -815,8 +738,8 @@ void MapStateReader::read(String const &mapUriStr)
game::SessionMetadata const &metadata = session().metadata();

File const &mapStateFile = pack.locate<File>(Path("maps") / mapUriStr + "State");
openFile(mapStateFile);
d->reader = newReader();
SV_OpenFile(mapStateFile);
d->reader = SV_NewReader();

d->saveVersion = metadata.geti("version");
d->mapVersion = d->saveVersion; // Default: mapVersion == saveVersion
Expand Down Expand Up @@ -864,7 +787,7 @@ void MapStateReader::read(String const &mapUriStr)
SV_ClearTargetPlayers();
#endif

closeFile();
SV_CloseFile();

// Notify the players that weren't in the savegame.
d->kickMissingPlayers();
Expand Down

0 comments on commit 21bdf43

Please sign in to comment.