[Scummvm-git-logs] scummvm master -> 61d8ec8b7fae1bcd28084ddebf28ade67de3e20f

sev- sev at scummvm.org
Sun Sep 18 22:45:44 CEST 2016


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
61d8ec8b7f FULLPIPE: Implemented savefile loading


Commit: 61d8ec8b7fae1bcd28084ddebf28ade67de3e20f
    https://github.com/scummvm/scummvm/commit/61d8ec8b7fae1bcd28084ddebf28ade67de3e20f
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2016-09-18T22:45:37+02:00

Commit Message:
FULLPIPE: Implemented savefile loading

Changed paths:
    engines/fullpipe/gameloader.h
    engines/fullpipe/stateloader.cpp
    engines/fullpipe/statesaver.cpp



diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index fc5db9c..d984020 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 1323c23..3d74e93 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 8f40778..c63587a 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;
 }
 
 





More information about the Scummvm-git-logs mailing list