aboutsummaryrefslogtreecommitdiff
path: root/engines/fullpipe
diff options
context:
space:
mode:
authorEugene Sandulenko2016-09-18 22:45:21 +0200
committerEugene Sandulenko2016-09-18 22:45:37 +0200
commit61d8ec8b7fae1bcd28084ddebf28ade67de3e20f (patch)
tree2c61a735bf7dbf4584b9179d3a121bea0e227a87 /engines/fullpipe
parent8bdabc16bde7b5d197797a9f1f2ff474ff7e726b (diff)
downloadscummvm-rg350-61d8ec8b7fae1bcd28084ddebf28ade67de3e20f.tar.gz
scummvm-rg350-61d8ec8b7fae1bcd28084ddebf28ade67de3e20f.tar.bz2
scummvm-rg350-61d8ec8b7fae1bcd28084ddebf28ade67de3e20f.zip
FULLPIPE: Implemented savefile loading
Diffstat (limited to 'engines/fullpipe')
-rw-r--r--engines/fullpipe/gameloader.h4
-rw-r--r--engines/fullpipe/stateloader.cpp135
-rw-r--r--engines/fullpipe/statesaver.cpp9
3 files changed, 144 insertions, 4 deletions
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index fc5db9c62c..d984020ff1 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -81,7 +81,7 @@ struct FullpipeSavegameHeader {
};
struct SaveHeader {
- int32 saveSize;
+ int32 version;
char magic[32];
int32 updateCounter;
int32 unkField;
@@ -109,6 +109,8 @@ class GameLoader : public CObject {
void readSavegame(const char *fname);
void writeSavegame(Scene *sc, const char *fname);
+ void addVar(GameVar *var, GameVar *subvar);
+
void restoreDefPicAniInfos();
GameProject *_gameProject;
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index 1323c23f77..3d74e93566 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -25,6 +25,7 @@
#include "common/file.h"
#include "common/array.h"
#include "common/list.h"
+#include "common/memstream.h"
#include "fullpipe/objects.h"
#include "fullpipe/gameloader.h"
@@ -38,7 +39,139 @@
namespace Fullpipe {
void GameLoader::readSavegame(const char *fname) {
- warning("STUB: readSavegame(%s)", fname);
+ SaveHeader header;
+ Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(fname);
+
+ header.version = saveFile->readUint32LE();
+ saveFile->read(header.magic, 32);
+ header.updateCounter = saveFile->readUint32LE();
+ header.unkField = saveFile->readUint32LE();
+ header.encSize = saveFile->readUint32LE();
+
+ if (header.version != 48)
+ return;
+
+ _updateCounter = header.updateCounter;
+
+ byte *data = (byte *)malloc(header.encSize);
+ saveFile->read(data, header.encSize);
+
+ byte *map = (byte *)malloc(800);
+ saveFile->read(map, 800);
+
+ MfcArchive temp(new Common::MemoryReadStream(map, 800));
+
+ if (_savegameCallback)
+ _savegameCallback(&temp, false);
+
+ delete saveFile;
+
+ // Deobfuscate the data
+ for (uint i = 0; i < header.encSize; i++)
+ data[i] -= i & 0x7f;
+
+ MfcArchive *archive = new MfcArchive(new Common::MemoryReadStream(data, header.encSize));
+
+ GameVar var;
+
+ var.load(*archive);
+
+ GameVar *v = _gameVar->getSubVarByName("OBJSTATES");
+
+ if (!v) {
+ v = _gameVar->addSubVarAsInt("OBJSTATES", 0);
+
+ if (!v) {
+ warning("No state to save");
+ delete archive;
+ return;
+ }
+ }
+
+ addVar(&var, v);
+
+ getGameLoaderInventory()->loadPartial(*archive);
+
+ int32 arrSize = archive->readUint32LE();
+
+ for (uint i = 0; i < arrSize; i++) {
+ _sc2array[i]._picAniInfosCount = archive->readUint32LE();
+
+ free(_sc2array[i]._picAniInfos);
+ _sc2array[i]._picAniInfos = (PicAniInfo **)malloc(sizeof(PicAniInfo *) * _sc2array[i]._picAniInfosCount);
+
+ for (uint j = 0; j < _sc2array[i]._picAniInfosCount; j++) {
+ _sc2array[i]._picAniInfos[j] = new PicAniInfo();
+ _sc2array[i]._picAniInfos[j]->load(*archive);
+ }
+ }
+
+ delete archive;
+
+ getGameLoaderInventory()->rebuildItemRects();
+
+ PreloadItem preloadItem;
+
+ v = _gameVar->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");
+
+ if (v) {
+ if (g_fp->_currentScene)
+ preloadItem.preloadId1 = g_fp->_currentScene->_sceneId & 0xffff;
+ else
+ preloadItem.preloadId1 = 0;
+
+ preloadItem.param = v->getSubVarAsInt("Entrance");
+ preloadItem.preloadId2 = 0;
+ preloadItem.sceneId = v->getSubVarAsInt("Scene");
+
+ if (_preloadCallback) {
+ if (!_preloadCallback(preloadItem, 0))
+ return;
+ }
+
+ clearGlobalMessageQueueList1();
+
+ if (g_fp->_currentScene)
+ unloadScene(g_fp->_currentScene->_sceneId);
+
+ g_fp->_currentScene = 0;
+
+ if (_preloadCallback)
+ _preloadCallback(preloadItem, 50);
+
+ loadScene(preloadItem.sceneId);
+
+ ExCommand *ex = new ExCommand(preloadItem.sceneId, 17, 62, 0, 0, 0, 1, 0, 0, 0);
+ ex->_excFlags = 2;
+ ex->_param = preloadItem.param;
+
+ if (_preloadCallback)
+ _preloadCallback(preloadItem, 100);
+
+ ex->postMessage();
+ }
+}
+
+void GameLoader::addVar(GameVar *var, GameVar *subvar) {
+ if (var && subvar) {
+ int type = var->_varType;
+ if (type == subvar->_varType && (!type || type == 1))
+ subvar->_value.intValue = var->_value.intValue;
+
+ for (GameVar *v = var->_subVars; v; v = v->_nextVarObj) {
+ GameVar *nv = subvar->getSubVarByName(v->_varName);
+ if (!nv) {
+ nv = new GameVar;
+ nv->_varName = (char *)calloc(strlen(v->_varName) + 1, 1);
+ strcpy(nv->_varName, v->_varName);
+ nv->_varType = v->_varType;
+
+ subvar->addSubVar(nv);
+ }
+
+ addVar(v, nv);
+ }
+ }
}
void gameLoaderSavegameCallback(MfcArchive *archive, bool mode) {
diff --git a/engines/fullpipe/statesaver.cpp b/engines/fullpipe/statesaver.cpp
index 8f4077877c..c63587a560 100644
--- a/engines/fullpipe/statesaver.cpp
+++ b/engines/fullpipe/statesaver.cpp
@@ -48,7 +48,7 @@ void GameLoader::writeSavegame(Scene *sc, const char *fname) {
saveScenePicAniInfos(sc->_sceneId);
memset(&header, 0, sizeof(header));
- header.saveSize = 48;
+ header.version = 48; // '0'
strcpy(header.magic, "FullPipe Savegame");
header.updateCounter = _updateCounter;
header.unkField = 1;
@@ -103,13 +103,18 @@ void GameLoader::writeSavegame(Scene *sc, const char *fname) {
// Now dump it into save file
Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(fname);
- saveFile->write(&header, sizeof(header));
+ saveFile->writeUint32LE(header.version);
+ saveFile->write(header.magic, 32);
+ saveFile->writeUint32LE(header.updateCounter);
+ saveFile->writeUint32LE(header.unkField);
+ saveFile->writeUint32LE(header.encSize);
saveFile->write(stream.getData(), stream.size());
saveFile->finalize();
delete saveFile;
+ delete archive;
}