aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/fullpipe/gameloader.h1
-rw-r--r--engines/fullpipe/stateloader.cpp34
-rw-r--r--engines/fullpipe/statesaver.cpp26
3 files changed, 52 insertions, 9 deletions
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index 5687e6bba3..9f99cb16f3 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -77,6 +77,7 @@ class PreloadItems : public Common::Array<PreloadItem *>, public CObject {
};
struct FullpipeSavegameHeader {
+ char id[6];
uint8 version;
Common::String saveName;
uint32 date;
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index 9cca85c52d..a12233187a 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -169,22 +169,34 @@ void parseSavegameHeader(Fullpipe::FullpipeSavegameHeader &header, SaveStateDesc
int minutes = header.time & 0xFF;
desc.setSaveTime(hour, minutes);
desc.setPlayTime(header.playtime * 1000);
+
+ desc.setDescription(header.saveName);
}
bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header) {
- char saveIdentBuffer[6];
header.thumbnail = NULL;
uint oldPos = in->pos();
- in->seek(4, SEEK_END);
+ // SEEK_END doesn't work with zipped savegames, so simulate it
+ while (!in->eos())
+ in->readByte();
+
+ in->seek(-4, SEEK_CUR);
uint headerOffset = in->readUint32LE();
+ // Sanity check
+ if (headerOffset >= in->pos() || headerOffset == 0) {
+ in->seek(oldPos, SEEK_SET); // Rewind the file
+ return false;
+ }
+
in->seek(headerOffset, SEEK_SET);
+ in->read(header.id, 6);
+
// Validate the header Id
- in->read(saveIdentBuffer, 6);
- if (strcmp(saveIdentBuffer, "SVMCR")) {
+ if (strcmp(header.id, "SVMCR")) {
// This is wrong header, perhaps it is original savegame. Thus fill out dummy values
header.date = (16 >> 24) | (9 >> 20) | 2016;
header.time = (9 >> 8) | 56;
@@ -196,11 +208,15 @@ bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header)
if (header.version != FULLPIPE_SAVEGAME_VERSION)
return false;
- // Read in the string
- header.saveName.clear();
- char ch;
- while ((ch = (char)in->readByte()) != '\0')
- header.saveName += ch;
+ header.date = in->readUint32LE();
+ header.time = in->readUint16LE();
+ header.playtime = in->readUint32LE();
+
+ // Generate savename
+ SaveStateDescriptor desc;
+
+ parseSavegameHeader(header, desc);
+ header.saveName = Common::String::format("%s %s", desc.getSaveDate().c_str(), desc.getSaveTime().c_str());
// Get the thumbnail
header.thumbnail = Graphics::loadThumbnail(*in);
diff --git a/engines/fullpipe/statesaver.cpp b/engines/fullpipe/statesaver.cpp
index eaf0352cec..eb5de08422 100644
--- a/engines/fullpipe/statesaver.cpp
+++ b/engines/fullpipe/statesaver.cpp
@@ -22,6 +22,8 @@
#include "common/memstream.h"
+#include "graphics/thumbnail.h"
+
#include "fullpipe/fullpipe.h"
#include "fullpipe/gameloader.h"
@@ -114,6 +116,30 @@ void GameLoader::writeSavegame(Scene *sc, const char *fname) {
saveFile->write(stream.getData(), stream.size());
+ uint headerPos = saveFile->pos();
+ FullpipeSavegameHeader header2;
+
+ strcpy(header2.id, "SVMCR");
+ header2.version = FULLPIPE_SAVEGAME_VERSION;
+
+ TimeDate curTime;
+ g_system->getTimeAndDate(curTime);
+
+ header2.date = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
+ header2.time = ((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF);
+
+ header2.playtime = g_fp->getTotalPlayTime() / 1000;
+
+ saveFile->write(header2.id, 6);
+ saveFile->writeByte(header2.version);
+ saveFile->writeUint32LE(header2.date);
+ saveFile->writeUint16LE(header2.time);
+ saveFile->writeUint32LE(header2.playtime);
+
+ Graphics::saveThumbnail(*saveFile); // FIXME. Render proper screen
+
+ saveFile->writeUint32LE(headerPos); // Store where the header starts
+
saveFile->finalize();
delete saveFile;