[Scummvm-git-logs] scummvm master -> 6cad083f84ed3ab5b1cd1bc054308ce26930d6c4

sev- sev at scummvm.org
Thu Nov 3 23:51:35 CET 2016


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

Summary:
49fad58b2a COMPOSER: Preliminary (non-functional) game saving/loading support
529a82a50a COMPOSER/JANITORIAL: Corrected a number of formatting issues in and around new functions related to saving.
2b58f42b8c COMPOSER: Continued work on saving/loading functionality.
70220384cd COMPOSER: game saving/loading now actually works
4e1f98a155 COMPOSER: failed attempt to correct audio sync issue
bbcf4a9218 COMPOSER: Fixed audio issues after save-game load.
3d6eb8b49d COMPOSER: cleaned up miscellaneous gcc warnings and formatting issues.
1f1928c9ac COMPOSER: Added new file to module.mk
027bab88fb COMPOSER: Added support for saving/loading in V1 games.
c4c6cce78e COMPOSER: Completely removed unnecessary #ifdefs
d91368aa1a COMPOSER: Saving/loading code deduplication
69a6a200a2 COMPOSER: Fixed some scope issues
582006d1cf COMPOSER: Added loading from launcher support
483cad039e COMPOSER: Enable autosaving.
a9441186b7 COMPOSER: Better spacing of autosaves
5649ce55fc COMPOSER: Various formatting fixes.
74c75e36ca COMPOSER: Fix for issue when save_slot is in config.
a946e9eab9 COMPOSER: Include config manager header in composer.cpp again
17f3626214 COMPOSER: Delete leftover git conflict marker
c3994cd6ea COMPOSER: Add missing 'typename' prior to dependent type name
ec06c04faa COMPOSER: Use setPixel() and getPixel() methods to read and write to private pixel member
6cad083f84 Merge pull request #851 from angstsmurf/composer-gmm-new


Commit: 49fad58b2a1555da765b0ac1c20ea480fcb3b9a9
    https://github.com/scummvm/scummvm/commit/49fad58b2a1555da765b0ac1c20ea480fcb3b9a9
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:08:10+02:00

Commit Message:
COMPOSER: Preliminary (non-functional) game saving/loading support

Changed paths:
  A engines/composer/saveload.cpp
    engines/composer/composer.h
    engines/composer/detection.cpp



diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index d1a85e9..b570d16 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -150,6 +150,13 @@ class ComposerEngine : public Engine {
 protected:
 	Common::Error run();
 
+#ifdef SAVING_ANYWHERE
+	bool canLoadGameStateCurrently() { return true; }
+	Common::Error loadGameState(int slot);
+	bool canSaveGameStateCurrently() { return true; }
+	Common::Error saveGameState(int slot, const Common::String &desc);
+#endif
+
 public:
 	ComposerEngine(OSystem *syst, const ComposerGameDescription *gameDesc);
 	virtual ~ComposerEngine();
@@ -210,6 +217,9 @@ private:
 	uint16 _mouseSpriteId;
 	Common::Point _mouseOffset;
 
+#ifdef SAVING_ANYWHERE
+	Common::String makeSaveGameName(int slot);
+#endif
 	Common::String getStringFromConfig(const Common::String &section, const Common::String &key);
 	Common::String getFilename(const Common::String &section, uint id);
 	Common::String mangleFilename(Common::String filename);
diff --git a/engines/composer/detection.cpp b/engines/composer/detection.cpp
index 689a72a..1157623 100644
--- a/engines/composer/detection.cpp
+++ b/engines/composer/detection.cpp
@@ -21,6 +21,11 @@
  */
 
 #include "base/plugins.h"
+#ifdef SAVING_ANYWHERE
+#include "common/savefile.h"
+#include "common/serializer.h"
+#include "common/str-array.h"
+#endif //SAVING_ANYWHERE
 #include "engines/advancedDetector.h"
 
 #include "composer/composer.h"
@@ -448,6 +453,8 @@ public:
 
 	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
 	virtual bool hasFeature(MetaEngineFeature f) const;
+	virtual int getMaximumSaveSlot() const;
+	virtual SaveStateList listSaves(const char* target) const;
 };
 
 bool ComposerMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
@@ -459,11 +466,60 @@ bool ComposerMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD
 }
 
 bool ComposerMetaEngine::hasFeature(MetaEngineFeature f) const {
+#ifdef SAVING_ANYWHERE
+		return (f == kSupportsListSaves);
+#else
 	return false;
+#endif //SAVING_ANYWHERE
+}
+
+#ifdef SAVING_ANYWHERE
+Common::String getSaveName(Common::InSaveFile *in) {
+	Common::Serializer ser(in,NULL);
+	Common::String name;
+	uint32 tmp;
+	ser.syncAsUint32LE(tmp);
+	ser.syncAsUint32LE(tmp);
+	ser.syncString(name);
+	return name;
+}
+int ComposerMetaEngine::getMaximumSaveSlot() const {
+	return 99;
+}
+SaveStateList ComposerMetaEngine::listSaves(const char *target) const {
+	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+	Common::StringArray filenames;
+	Common::String saveDesc;
+	Common::String pattern = Common::String::format("%s.??",target);
+
+	filenames = saveFileMan->listSavefiles(pattern);
+	sort(filenames.begin(), filenames.end());	// Sort (hopefully ensuring we are sorted numerically..)
+
+	SaveStateList saveList;
+	for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+		// Obtain the last 3 digits of the filename, since they correspond to the save slot
+		int slotNum = atoi(file->c_str() + file->size() - 2);
+
+		if (slotNum >= 0 && slotNum <= 99) {
+			Common::InSaveFile *in = saveFileMan->openForLoading(*file);
+			if (in) {
+				saveDesc = getSaveName(in);
+				saveList.push_back(SaveStateDescriptor(slotNum, saveDesc));
+				delete in;
+			}
+		}
+	}
+
+	return saveList;
 }
+#endif //SAVING_ANYWHERE
 
 bool Composer::ComposerEngine::hasFeature(EngineFeature f) const {
-	return (f == kSupportsRTL);
+	return (f == kSupportsRTL 
+#ifdef SAVING_ANYWHERE
+			|| f == kSupportsSavingDuringRuntime || f == kSupportsLoadingDuringRuntime
+#endif //SAVING_ANYWHERE
+			);
 }
 
 #if PLUGIN_ENABLED_DYNAMIC(COMPOSER)
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
new file mode 100644
index 0000000..2ce32ee
--- /dev/null
+++ b/engines/composer/saveload.cpp
@@ -0,0 +1,243 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef SAVING_ANYWHERE
+#include "common/config-manager.h"
+#include "common/memstream.h"
+#include "common/savefile.h"
+#include "common/serializer.h"
+#include "common/system.h"
+#include "common/zlib.h"
+#include "graphics/palette.h"
+
+#include "composer/composer.h"
+#include "composer/graphics.h"
+
+namespace Composer {
+Common::String ComposerEngine::makeSaveGameName(int slot) {
+	return (_targetName + Common::String::format(".%02d",slot));
+}
+
+Common::Error ComposerEngine::loadGameState(int slot) {
+	Common::String filename = makeSaveGameName(slot);
+	Common::InSaveFile *in;
+	if (!(in = _saveFileMan->openForLoading(filename)))
+		return Common::kPathNotFile;
+
+	Common::Serializer ser(in, NULL);
+	byte magic[4];
+	ser.syncBytes(magic,4);
+	if (magic[0] != 'C' || magic[1] != 'M' || magic[2] != 'P' || magic[3] != 'S') 
+		return Common::kUnknownError;
+
+	for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) {
+		delete *i;
+	}
+	_anims.clear();
+
+	for (Common::List<Pipe *>::iterator i = _pipes.begin(); i != _pipes.end(); i++) {
+		delete *i;
+	}
+	_pipes.clear();
+
+	ser.syncVersion(0);
+	Common::String desc;
+	ser.syncString(desc);
+	uint32 tmp;
+	ser.syncAsUint32LE(tmp);
+	_rnd->setSeed(tmp);
+	ser.syncAsUint32LE(_currentTime);
+	uint32 timeDelta = _system->getMillis() - _currentTime;
+	_currentTime += timeDelta;
+	ser.syncAsUint32LE(_lastTime);
+	_lastTime += timeDelta;
+	ser.syncString(_bookGroup);
+	_libraries.clear();
+	ser.syncAsUint32LE(tmp);
+	for (uint32 i = tmp; i >0; i--) {
+		uint16 id;
+		ser.syncAsUint16LE(id);
+		loadLibrary(id);
+	}
+	_sprites.clear();
+	ser.syncAsUint32LE(tmp);
+	for (uint32 i = tmp; i >0; i--) {
+		uint16 id;
+		ser.syncAsUint16LE(id);
+		Sprite sprite;
+		sprite._id = id;
+		initSprite(sprite);
+		_sprites.push_back(sprite);
+	}
+
+	_pendingPageChanges.clear();
+	ser.syncAsUint32LE(tmp);
+	for (uint32 i = tmp; i >0; i--) {
+		uint16 id;
+		bool remove;
+		ser.syncAsUint16LE(id);
+		ser.syncAsByte(remove);
+		_pendingPageChanges.push_back(PendingPageChange(id,remove));
+	}
+	_stack.clear();
+	ser.syncAsUint32LE(tmp);
+	for (uint32 i = tmp; i >0; i--) {
+		uint16 svar;
+		ser.syncAsUint16LE(svar);
+		_stack.push_back(svar);
+	}
+	_vars.clear();
+	ser.syncAsUint32LE(tmp);
+	for (uint32 i = tmp; i >0; i--) {
+		uint16 var;
+		ser.syncAsUint16LE(var);
+		_vars.push_back(var);
+	}
+
+	for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) {
+		delete *i;
+	}
+	_oldScripts.clear();
+	ser.syncAsUint32LE(tmp);
+	for (uint32 i = tmp; i >0; i--) {
+		uint16 id;
+		uint32 delay;
+		ser.syncAsUint16LE(id);
+		ser.syncAsUint32LE(delay);
+		OldScript *oTmp = new OldScript(id,getResource(ID_SCRP, id));
+		oTmp->_currDelay = delay;
+		_oldScripts.push_back(oTmp);
+	}
+	_queuedScripts.clear();
+	ser.syncAsUint32LE(tmp);
+	for (uint32 i = tmp; i >0; i--) {
+		QueuedScript qTmp;
+		ser.syncAsUint32LE(qTmp._baseTime);
+		qTmp._baseTime += timeDelta;
+		ser.syncAsUint32LE(qTmp._duration);
+		ser.syncAsUint32LE(qTmp._count);
+		if(qTmp._count !=0) {
+			assert(qTmp._count != 0);
+		}
+		ser.syncAsUint16LE(qTmp._scriptId);
+		_queuedScripts.push_back(qTmp);
+	}
+
+	ser.syncAsByte(_mouseEnabled);
+	ser.syncAsByte(_mouseVisible);
+	ser.syncAsUint16LE(_mouseSpriteId);
+	_dirtyRects.clear();
+
+	_dirtyRects.push_back(Common::Rect(0,0,640,480));
+	byte palbuf[256 * 3];
+	ser.syncBytes(palbuf,256 * 3);
+	_system->getPaletteManager()->setPalette(palbuf,0,256);
+	_needsUpdate = true;
+
+	return Common::kNoError;
+}
+
+Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc) {
+	Common::String filename = makeSaveGameName(slot);
+	Common::OutSaveFile *out;
+	if (!(out = _saveFileMan->openForSaving(filename)))
+		return Common::kWritingFailed;
+
+	Common::Serializer ser(NULL, out);
+	byte magic[4] = {'C', 'M', 'P', 'S'};
+	ser.syncBytes(magic,4);
+	ser.syncVersion(0);
+	Common::String desctmp = desc;
+	ser.syncString(desctmp);
+	uint32 tmp = _rnd->getSeed();
+	ser.syncAsUint32LE(tmp);
+	ser.syncAsUint32LE(_currentTime);
+	ser.syncAsUint32LE(_lastTime);
+	ser.syncString(_bookGroup);
+	tmp = _libraries.size();
+	ser.syncAsUint32LE(tmp);
+	for (Common::List<Library>::const_iterator i = _libraries.begin(); i != _libraries.end(); i++) {
+		uint16 tmp = (*i)._id;
+		ser.syncAsUint16LE(tmp);
+	}
+	tmp = _sprites.size();
+	ser.syncAsUint32LE(tmp);
+	for (Common::List<Sprite>::const_iterator i = _sprites.begin(); i != _sprites.end(); i++) {
+		uint16 tmp = (*i)._id;
+		ser.syncAsUint16LE(tmp);
+	}
+	tmp = _pendingPageChanges.size();
+	ser.syncAsUint32LE(tmp);
+	for (Common::Array<PendingPageChange>::const_iterator i = _pendingPageChanges.begin(); i != _pendingPageChanges.end(); i++) {
+		uint16 tmp = (*i)._pageId;
+		bool tmpb = (*i)._remove;
+		ser.syncAsUint16LE(tmp);
+		ser.syncAsByte(tmpb);
+	}
+	tmp = _stack.size();
+	ser.syncAsUint32LE(tmp);
+	for (Common::Array<uint16>::const_iterator i = _stack.begin(); i != _stack.end(); i++) {
+		uint16 tmp = (*i);
+		ser.syncAsUint16LE(tmp);
+	}
+	tmp = _vars.size();
+	ser.syncAsUint32LE(tmp);
+	for (Common::Array<uint16>::const_iterator i = _vars.begin(); i != _vars.end(); i++) {
+		uint16 tmp = (*i);
+		ser.syncAsUint16LE(tmp);
+	}
+	tmp = _oldScripts.size();
+	ser.syncAsUint32LE(tmp);
+	for (Common::List<OldScript *>::const_iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) {
+		uint16 tmp16 = (*i)->_id;
+		tmp = (*i)->_currDelay;
+		ser.syncAsUint16LE(tmp16);
+		ser.syncAsUint32LE(tmp);
+	}
+	tmp = _queuedScripts.size();
+	ser.syncAsUint32LE(tmp);
+	for (Common::Array<QueuedScript>::const_iterator i = _queuedScripts.begin(); i != _queuedScripts.end(); i++) {
+		tmp = (*i)._baseTime;
+		ser.syncAsUint32LE(tmp);
+		tmp = (*i)._duration;
+		ser.syncAsUint32LE(tmp);
+		tmp = (*i)._count;
+		if(tmp !=0) {
+			assert(tmp != 0);
+		}
+		uint16 tmp16 = (*i)._scriptId;
+		ser.syncAsUint32LE(tmp);
+		ser.syncAsUint16LE(tmp16);
+	}
+	ser.syncAsByte(_mouseEnabled);
+	ser.syncAsByte(_mouseVisible);
+	ser.syncAsUint16LE(_mouseSpriteId);
+
+	byte palbuf[256 * 3];
+	_system->getPaletteManager()->grabPalette(palbuf,0,256);
+	ser.syncBytes(palbuf,256 * 3);
+
+	out->finalize();
+	return Common::kNoError;
+}
+}
+#endif


Commit: 529a82a50a299e80bca5553b66c4796c88582471
    https://github.com/scummvm/scummvm/commit/529a82a50a299e80bca5553b66c4796c88582471
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:08:23+02:00

Commit Message:
COMPOSER/JANITORIAL: Corrected a number of formatting issues in and around new functions related to saving.

Changed paths:
    engines/composer/detection.cpp
    engines/composer/saveload.cpp



diff --git a/engines/composer/detection.cpp b/engines/composer/detection.cpp
index 1157623..3a8fb0d 100644
--- a/engines/composer/detection.cpp
+++ b/engines/composer/detection.cpp
@@ -25,7 +25,7 @@
 #include "common/savefile.h"
 #include "common/serializer.h"
 #include "common/str-array.h"
-#endif //SAVING_ANYWHERE
+#endif // SAVING_ANYWHERE
 #include "engines/advancedDetector.h"
 
 #include "composer/composer.h"
@@ -470,12 +470,12 @@ bool ComposerMetaEngine::hasFeature(MetaEngineFeature f) const {
 		return (f == kSupportsListSaves);
 #else
 	return false;
-#endif //SAVING_ANYWHERE
+#endif // SAVING_ANYWHERE
 }
 
 #ifdef SAVING_ANYWHERE
 Common::String getSaveName(Common::InSaveFile *in) {
-	Common::Serializer ser(in,NULL);
+	Common::Serializer ser(in, NULL);
 	Common::String name;
 	uint32 tmp;
 	ser.syncAsUint32LE(tmp);
@@ -490,7 +490,7 @@ SaveStateList ComposerMetaEngine::listSaves(const char *target) const {
 	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
 	Common::StringArray filenames;
 	Common::String saveDesc;
-	Common::String pattern = Common::String::format("%s.??",target);
+	Common::String pattern = Common::String::format("%s.??", target);
 
 	filenames = saveFileMan->listSavefiles(pattern);
 	sort(filenames.begin(), filenames.end());	// Sort (hopefully ensuring we are sorted numerically..)
@@ -512,13 +512,13 @@ SaveStateList ComposerMetaEngine::listSaves(const char *target) const {
 
 	return saveList;
 }
-#endif //SAVING_ANYWHERE
+#endif // SAVING_ANYWHERE
 
 bool Composer::ComposerEngine::hasFeature(EngineFeature f) const {
 	return (f == kSupportsRTL 
 #ifdef SAVING_ANYWHERE
 			|| f == kSupportsSavingDuringRuntime || f == kSupportsLoadingDuringRuntime
-#endif //SAVING_ANYWHERE
+#endif // SAVING_ANYWHERE
 			);
 }
 
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index 2ce32ee..6922452 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -34,7 +34,7 @@
 
 namespace Composer {
 Common::String ComposerEngine::makeSaveGameName(int slot) {
-	return (_targetName + Common::String::format(".%02d",slot));
+	return (_targetName + Common::String::format(".%02d", slot));
 }
 
 Common::Error ComposerEngine::loadGameState(int slot) {
@@ -45,7 +45,7 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 
 	Common::Serializer ser(in, NULL);
 	byte magic[4];
-	ser.syncBytes(magic,4);
+	ser.syncBytes(magic, 4);
 	if (magic[0] != 'C' || magic[1] != 'M' || magic[2] != 'P' || magic[3] != 'S') 
 		return Common::kUnknownError;
 
@@ -73,14 +73,14 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	ser.syncString(_bookGroup);
 	_libraries.clear();
 	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i >0; i--) {
+	for (uint32 i = tmp; i > 0; i--) {
 		uint16 id;
 		ser.syncAsUint16LE(id);
 		loadLibrary(id);
 	}
 	_sprites.clear();
 	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i >0; i--) {
+	for (uint32 i = tmp; i > 0; i--) {
 		uint16 id;
 		ser.syncAsUint16LE(id);
 		Sprite sprite;
@@ -91,23 +91,23 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 
 	_pendingPageChanges.clear();
 	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i >0; i--) {
+	for (uint32 i = tmp; i > 0; i--) {
 		uint16 id;
 		bool remove;
 		ser.syncAsUint16LE(id);
 		ser.syncAsByte(remove);
-		_pendingPageChanges.push_back(PendingPageChange(id,remove));
+		_pendingPageChanges.push_back(PendingPageChange(id, remove));
 	}
 	_stack.clear();
 	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i >0; i--) {
+	for (uint32 i = tmp; i > 0; i--) {
 		uint16 svar;
 		ser.syncAsUint16LE(svar);
 		_stack.push_back(svar);
 	}
 	_vars.clear();
 	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i >0; i--) {
+	for (uint32 i = tmp; i > 0; i--) {
 		uint16 var;
 		ser.syncAsUint16LE(var);
 		_vars.push_back(var);
@@ -118,24 +118,24 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	}
 	_oldScripts.clear();
 	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i >0; i--) {
+	for (uint32 i = tmp; i > 0; i--) {
 		uint16 id;
 		uint32 delay;
 		ser.syncAsUint16LE(id);
 		ser.syncAsUint32LE(delay);
-		OldScript *oTmp = new OldScript(id,getResource(ID_SCRP, id));
+		OldScript *oTmp = new OldScript(id, getResource(ID_SCRP, id));
 		oTmp->_currDelay = delay;
 		_oldScripts.push_back(oTmp);
 	}
 	_queuedScripts.clear();
 	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i >0; i--) {
+	for (uint32 i = tmp; i > 0; i--) {
 		QueuedScript qTmp;
 		ser.syncAsUint32LE(qTmp._baseTime);
 		qTmp._baseTime += timeDelta;
 		ser.syncAsUint32LE(qTmp._duration);
 		ser.syncAsUint32LE(qTmp._count);
-		if(qTmp._count !=0) {
+		if(qTmp._count != 0) {
 			assert(qTmp._count != 0);
 		}
 		ser.syncAsUint16LE(qTmp._scriptId);
@@ -147,10 +147,10 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	ser.syncAsUint16LE(_mouseSpriteId);
 	_dirtyRects.clear();
 
-	_dirtyRects.push_back(Common::Rect(0,0,640,480));
+	_dirtyRects.push_back(Common::Rect(0, 0, 640, 480));
 	byte palbuf[256 * 3];
-	ser.syncBytes(palbuf,256 * 3);
-	_system->getPaletteManager()->setPalette(palbuf,0,256);
+	ser.syncBytes(palbuf, 256 * 3);
+	_system->getPaletteManager()->setPalette(palbuf, 0, 256);
 	_needsUpdate = true;
 
 	return Common::kNoError;
@@ -164,7 +164,7 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 
 	Common::Serializer ser(NULL, out);
 	byte magic[4] = {'C', 'M', 'P', 'S'};
-	ser.syncBytes(magic,4);
+	ser.syncBytes(magic, 4);
 	ser.syncVersion(0);
 	Common::String desctmp = desc;
 	ser.syncString(desctmp);
@@ -221,7 +221,7 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 		tmp = (*i)._duration;
 		ser.syncAsUint32LE(tmp);
 		tmp = (*i)._count;
-		if(tmp !=0) {
+		if(tmp != 0) {
 			assert(tmp != 0);
 		}
 		uint16 tmp16 = (*i)._scriptId;
@@ -233,8 +233,8 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	ser.syncAsUint16LE(_mouseSpriteId);
 
 	byte palbuf[256 * 3];
-	_system->getPaletteManager()->grabPalette(palbuf,0,256);
-	ser.syncBytes(palbuf,256 * 3);
+	_system->getPaletteManager()->grabPalette(palbuf, 0, 256);
+	ser.syncBytes(palbuf, 256 * 3);
 
 	out->finalize();
 	return Common::kNoError;


Commit: 2b58f42b8c35e002a19acd60755ef2c62d32a042
    https://github.com/scummvm/scummvm/commit/2b58f42b8c35e002a19acd60755ef2c62d32a042
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:08:53+02:00

Commit Message:
COMPOSER: Continued work on saving/loading functionality.

Changed paths:
    engines/composer/graphics.cpp
    engines/composer/resource.cpp
    engines/composer/resource.h
    engines/composer/saveload.cpp



diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp
index 8769463..b69e09d 100644
--- a/engines/composer/graphics.cpp
+++ b/engines/composer/graphics.cpp
@@ -44,9 +44,9 @@ bool Sprite::contains(const Common::Point &pos) const {
 }
 
 enum {
-	kAnimOpEvent = 1,
-	kAnimOpPlayWave = 2,
-	kAnimOpPlayAnim = 3,
+	kAnimOpEvent = 1, 
+	kAnimOpPlayWave = 2, 
+	kAnimOpPlayAnim = 3, 
 	kAnimOpDrawSprite = 4
 };
 
@@ -124,7 +124,7 @@ void ComposerEngine::playAnimation(uint16 animId, int16 x, int16 y, int16 eventP
 		// and then fish the requested animation out of it.
 		if (type != 1) {
 			_pipeStreams.push_back(stream);
-			newPipe = new Pipe(stream);
+			newPipe = new Pipe(stream, animId);
 			_pipes.push_front(newPipe);
 			newPipe->nextFrame();
 			stream = newPipe->getResource(ID_ANIM, animId, false);
@@ -376,7 +376,7 @@ void ComposerEngine::playPipe(uint16 id) {
 	}
 
 	Common::SeekableReadStream *stream = getResource(ID_PIPE, id);
-	OldPipe *pipe = new OldPipe(stream);
+	OldPipe *pipe = new OldPipe(stream, id);
 	_pipes.push_front(pipe);
 	//pipe->nextFrame();
 
diff --git a/engines/composer/resource.cpp b/engines/composer/resource.cpp
index d867f73..3e787cc 100644
--- a/engines/composer/resource.cpp
+++ b/engines/composer/resource.cpp
@@ -248,10 +248,11 @@ bool ComposerArchive::openStream(Common::SeekableReadStream *stream) {
 	return true;
 }
 
-Pipe::Pipe(Common::SeekableReadStream *stream) {
+Pipe::Pipe(Common::SeekableReadStream *stream, uint16 pipeId) {
 	_offset = 0;
 	_stream = stream;
 	_anim = NULL;
+	_pipeId = pipeId;
 }
 
 Pipe::~Pipe() {
@@ -335,7 +336,7 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer
 	return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES);
 }
 
-OldPipe::OldPipe(Common::SeekableReadStream *stream) : Pipe(stream), _currFrame(0) {
+OldPipe::OldPipe(Common::SeekableReadStream *stream, uint16 pipeId) : Pipe(stream, pipeId), _currFrame(0) {
 	uint32 tag = _stream->readUint32BE();
 	if (tag != ID_PIPE)
 		error("invalid tag for pipe (%08x)", tag);
diff --git a/engines/composer/resource.h b/engines/composer/resource.h
index b624da1..52748ba 100644
--- a/engines/composer/resource.h
+++ b/engines/composer/resource.h
@@ -106,7 +106,7 @@ struct PipeResource {
 
 class Pipe {
 public:
-	Pipe(Common::SeekableReadStream *stream);
+	Pipe(Common::SeekableReadStream *stream, uint16 pipeId);
 	virtual ~Pipe();
 	virtual void nextFrame();
 
@@ -116,6 +116,11 @@ public:
 	Common::SeekableReadStream *getResource(uint32 tag, uint16 id, bool buffering);
 
 	virtual const Common::Array<uint16> *getScripts() { return NULL; }
+#ifdef SAVING_ANYWHERE
+	uint16 id() const { return _pipeId; }
+	uint32 offset() const { return _offset; }
+	void setOffset(uint32 offset) { while (_offset < offset) nextFrame(); }
+#endif
 
 protected:
 	Common::SeekableReadStream *_stream;
@@ -123,13 +128,16 @@ protected:
 	typedef Common::HashMap<uint16, PipeResource> ResourceMap;
 	typedef Common::HashMap<uint32, ResourceMap> TypeMap;
 	TypeMap _types;
+#ifdef SAVING_ANYWHERE
+	uint16 _pipeId;
+#endif
 
 	uint32 _offset;
 };
 
 class OldPipe : public Pipe {
 public:
-	OldPipe(Common::SeekableReadStream *stream);
+	OldPipe(Common::SeekableReadStream *stream, uint16 pipeId);
 	void nextFrame();
 
 	const Common::Array<uint16> *getScripts() { return &_scripts; }
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index 6922452..c9437d2 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -54,11 +54,6 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	}
 	_anims.clear();
 
-	for (Common::List<Pipe *>::iterator i = _pipes.begin(); i != _pipes.end(); i++) {
-		delete *i;
-	}
-	_pipes.clear();
-
 	ser.syncVersion(0);
 	Common::String desc;
 	ser.syncString(desc);
@@ -85,7 +80,20 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 		ser.syncAsUint16LE(id);
 		Sprite sprite;
 		sprite._id = id;
-		initSprite(sprite);
+		ser.syncAsSint16LE(sprite._pos.x);
+		ser.syncAsSint16LE(sprite._pos.y);
+		ser.syncAsUint16LE(sprite._surface.w);
+		ser.syncAsUint16LE(sprite._surface.h);
+		ser.syncAsUint16LE(sprite._surface.pitch);
+		ser.syncAsUint16LE(sprite._zorder);
+		sprite._surface.pixels = malloc(sprite._surface.h * sprite._surface.pitch);
+		byte *dest = static_cast<byte *>(sprite._surface.pixels);
+		for (uint16 y = 0; y < sprite._surface.h; y++) {
+			for (uint16 x = 0; x < sprite._surface.w; x++) {
+				ser.syncAsByte(dest[x]);
+			}
+			dest += sprite._surface.pitch;
+		}
 		_sprites.push_back(sprite);
 	}
 
@@ -141,12 +149,35 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 		ser.syncAsUint16LE(qTmp._scriptId);
 		_queuedScripts.push_back(qTmp);
 	}
-
+	ser.syncAsSint16LE(_lastMousePos.x);
+	ser.syncAsSint16LE(_lastMousePos.y);
 	ser.syncAsByte(_mouseEnabled);
 	ser.syncAsByte(_mouseVisible);
 	ser.syncAsUint16LE(_mouseSpriteId);
 	_dirtyRects.clear();
 
+	for (Common::List<Pipe *>::iterator i = _pipes.begin(); i != _pipes.end(); i++) {
+		delete *i;
+	}
+	_pipes.clear();
+	for (Common::Array<Common::SeekableReadStream *>::iterator i = _pipeStreams.begin(); i != _pipeStreams.end(); i++) {
+		delete *i;
+	}
+	_pipeStreams.clear();
+
+	ser.syncAsUint32LE(tmp);
+	for (uint32 i = tmp; i > 0; i--) {
+		uint16 id;
+		uint32 offset;
+		ser.syncAsUint16LE(id);
+		ser.syncAsUint32LE(offset);
+		Common::SeekableReadStream *stream = getResource(ID_ANIM, id);
+		Pipe *pipe = new Pipe(stream, id);
+		pipe->setOffset(offset);
+		_pipes.push_back(pipe);
+		_pipeStreams.push_back(stream);
+	}
+
 	_dirtyRects.push_back(Common::Rect(0, 0, 640, 480));
 	byte palbuf[256 * 3];
 	ser.syncBytes(palbuf, 256 * 3);
@@ -182,8 +213,21 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	tmp = _sprites.size();
 	ser.syncAsUint32LE(tmp);
 	for (Common::List<Sprite>::const_iterator i = _sprites.begin(); i != _sprites.end(); i++) {
-		uint16 tmp = (*i)._id;
-		ser.syncAsUint16LE(tmp);
+		Sprite sprite(*i);
+		ser.syncAsUint16LE(sprite._id);
+		ser.syncAsSint16LE(sprite._pos.x);
+		ser.syncAsSint16LE(sprite._pos.y);
+		ser.syncAsUint16LE(sprite._surface.w);
+		ser.syncAsUint16LE(sprite._surface.h);
+		ser.syncAsUint16LE(sprite._surface.pitch);
+		ser.syncAsUint16LE(sprite._zorder);
+		byte *src = static_cast<byte *>((*i)._surface.pixels);
+		for (uint16 y = 0; y < sprite._surface.h; y++) {
+			for (uint x = 0; x < sprite._surface.w; x++) {
+				ser.syncAsByte(src[x]);
+			}
+			src += (*i)._surface.pitch;
+		}
 	}
 	tmp = _pendingPageChanges.size();
 	ser.syncAsUint32LE(tmp);
@@ -228,10 +272,21 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 		ser.syncAsUint32LE(tmp);
 		ser.syncAsUint16LE(tmp16);
 	}
+	ser.syncAsSint16LE(_lastMousePos.x);
+	ser.syncAsSint16LE(_lastMousePos.y);
 	ser.syncAsByte(_mouseEnabled);
 	ser.syncAsByte(_mouseVisible);
 	ser.syncAsUint16LE(_mouseSpriteId);
 
+	tmp = _pipes.size();
+	ser.syncAsUint32LE(tmp);
+	for (Common::List<Pipe *>::const_iterator i = _pipes.begin(); i != _pipes.end(); i++) {
+		uint16 tmp16 = (*i)->id();
+		tmp = (*i)->offset();
+		ser.syncAsUint16LE(tmp16);
+		ser.syncAsUint32LE(tmp);
+	}
+
 	byte palbuf[256 * 3];
 	_system->getPaletteManager()->grabPalette(palbuf, 0, 256);
 	ser.syncBytes(palbuf, 256 * 3);


Commit: 70220384cd726131b099ee4eb801c9a0f617a8bd
    https://github.com/scummvm/scummvm/commit/70220384cd726131b099ee4eb801c9a0f617a8bd
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:09:04+02:00

Commit Message:
COMPOSER: game saving/loading now actually works

Changed paths:
    engines/composer/saveload.cpp



diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index c9437d2..ce0a60b 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -154,7 +154,6 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	ser.syncAsByte(_mouseEnabled);
 	ser.syncAsByte(_mouseVisible);
 	ser.syncAsUint16LE(_mouseSpriteId);
-	_dirtyRects.clear();
 
 	for (Common::List<Pipe *>::iterator i = _pipes.begin(); i != _pipes.end(); i++) {
 		delete *i;
@@ -174,10 +173,11 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 		Common::SeekableReadStream *stream = getResource(ID_ANIM, id);
 		Pipe *pipe = new Pipe(stream, id);
 		pipe->setOffset(offset);
-		_pipes.push_back(pipe);
+		_pipes.push_front(pipe);
 		_pipeStreams.push_back(stream);
 	}
 
+	_dirtyRects.clear();
 	_dirtyRects.push_back(Common::Rect(0, 0, 640, 480));
 	byte palbuf[256 * 3];
 	ser.syncBytes(palbuf, 256 * 3);
@@ -206,7 +206,7 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	ser.syncString(_bookGroup);
 	tmp = _libraries.size();
 	ser.syncAsUint32LE(tmp);
-	for (Common::List<Library>::const_iterator i = _libraries.begin(); i != _libraries.end(); i++) {
+	for (Common::List<Library>::const_iterator i = _libraries.reverse_begin(); i != _libraries.end(); i--) {
 		uint16 tmp = (*i)._id;
 		ser.syncAsUint16LE(tmp);
 	}
@@ -280,7 +280,7 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 
 	tmp = _pipes.size();
 	ser.syncAsUint32LE(tmp);
-	for (Common::List<Pipe *>::const_iterator i = _pipes.begin(); i != _pipes.end(); i++) {
+	for (Common::List<Pipe *>::const_iterator i = _pipes.reverse_begin(); i != _pipes.end(); i--) {
 		uint16 tmp16 = (*i)->id();
 		tmp = (*i)->offset();
 		ser.syncAsUint16LE(tmp16);


Commit: 4e1f98a155ede58bfa0105f761dfb1e852f47938
    https://github.com/scummvm/scummvm/commit/4e1f98a155ede58bfa0105f761dfb1e852f47938
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:09:14+02:00

Commit Message:
COMPOSER: failed attempt to correct audio sync issue

Changed paths:
    engines/composer/graphics.cpp
    engines/composer/graphics.h
    engines/composer/resource.cpp
    engines/composer/saveload.cpp



diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp
index b69e09d..2c50cb1 100644
--- a/engines/composer/graphics.cpp
+++ b/engines/composer/graphics.cpp
@@ -57,6 +57,9 @@ Animation::Animation(Common::SeekableReadStream *stream, uint16 id, Common::Poin
 
 	// probably total size?
 	uint32 unknown = _stream->readUint32LE();
+#ifdef SAVING_ANYWHERE
+	_size = unknown;
+#endif
 
 	debug(8, "anim: size %d, state %08x, unknown %08x", size, _state, unknown);
 
diff --git a/engines/composer/graphics.h b/engines/composer/graphics.h
index a8f37dd..cfa581d 100644
--- a/engines/composer/graphics.h
+++ b/engines/composer/graphics.h
@@ -59,6 +59,9 @@ struct Animation {
 	uint32 _eventParam;
 
 	uint32 _state;
+#ifdef SAVING_ANYWHERE
+	uint32 _size;
+#endif
 
 	Common::Array<AnimationEntry> _entries;
 
diff --git a/engines/composer/resource.cpp b/engines/composer/resource.cpp
index 3e787cc..0bb7e8a 100644
--- a/engines/composer/resource.cpp
+++ b/engines/composer/resource.cpp
@@ -252,7 +252,9 @@ Pipe::Pipe(Common::SeekableReadStream *stream, uint16 pipeId) {
 	_offset = 0;
 	_stream = stream;
 	_anim = NULL;
+#ifdef SAVING_ANYWHERE
 	_pipeId = pipeId;
+#endif
 }
 
 Pipe::~Pipe() {
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index ce0a60b..0cbf749 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -21,6 +21,8 @@
  */
 
 #ifdef SAVING_ANYWHERE
+#include "audio/audiostream.h"
+#include "audio/decoders/raw.h"
 #include "common/config-manager.h"
 #include "common/memstream.h"
 #include "common/savefile.h"
@@ -49,11 +51,6 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	if (magic[0] != 'C' || magic[1] != 'M' || magic[2] != 'P' || magic[3] != 'S') 
 		return Common::kUnknownError;
 
-	for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) {
-		delete *i;
-	}
-	_anims.clear();
-
 	ser.syncVersion(0);
 	Common::String desc;
 	ser.syncString(desc);
@@ -66,36 +63,17 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	ser.syncAsUint32LE(_lastTime);
 	_lastTime += timeDelta;
 	ser.syncString(_bookGroup);
-	_libraries.clear();
+	Common::Array<uint16> libIds;
+	for (Common::List<Library>::iterator i = _libraries.begin(); i != _libraries.end(); i++) 
+		libIds.push_back((*i)._id);
+	for (uint32 i = 0; i < libIds.size(); i++) 
+		unloadLibrary(libIds[i]);
 	ser.syncAsUint32LE(tmp);
 	for (uint32 i = tmp; i > 0; i--) {
 		uint16 id;
 		ser.syncAsUint16LE(id);
 		loadLibrary(id);
 	}
-	_sprites.clear();
-	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i > 0; i--) {
-		uint16 id;
-		ser.syncAsUint16LE(id);
-		Sprite sprite;
-		sprite._id = id;
-		ser.syncAsSint16LE(sprite._pos.x);
-		ser.syncAsSint16LE(sprite._pos.y);
-		ser.syncAsUint16LE(sprite._surface.w);
-		ser.syncAsUint16LE(sprite._surface.h);
-		ser.syncAsUint16LE(sprite._surface.pitch);
-		ser.syncAsUint16LE(sprite._zorder);
-		sprite._surface.pixels = malloc(sprite._surface.h * sprite._surface.pitch);
-		byte *dest = static_cast<byte *>(sprite._surface.pixels);
-		for (uint16 y = 0; y < sprite._surface.h; y++) {
-			for (uint16 x = 0; x < sprite._surface.w; x++) {
-				ser.syncAsByte(dest[x]);
-			}
-			dest += sprite._surface.pitch;
-		}
-		_sprites.push_back(sprite);
-	}
 
 	_pendingPageChanges.clear();
 	ser.syncAsUint32LE(tmp);
@@ -177,6 +155,94 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 		_pipeStreams.push_back(stream);
 	}
 
+	for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) {
+		delete *i;
+	}
+	_anims.clear();
+	ser.syncAsUint32LE(tmp);
+	for (uint32 i = tmp; i > 0; i--) {
+		uint16 animId, x, y;
+		uint32 offset, state, param, size;
+		ser.syncAsUint16LE(animId);
+		ser.syncAsUint32LE(offset);
+		ser.syncAsUint16LE(x);
+		ser.syncAsUint16LE(y);
+		ser.syncAsUint32LE(state);
+		ser.syncAsUint32LE(param);
+		ser.syncAsUint32LE(size);
+		Common::SeekableReadStream *stream = NULL;
+
+		//TODO: extract following out into "loadAnim"
+		// First, check the existing pipes.
+		for (Common::List<Pipe *>::iterator j = _pipes.begin(); j != _pipes.end(); j++) {
+			Pipe *pipe = *j;
+			if (!pipe->hasResource(ID_ANIM, animId))
+				continue;
+			stream = pipe->getResource(ID_ANIM, animId, false);
+			if (stream->size() >= size) break;
+			stream = NULL;
+		}
+		// If we didn't find it, try the libraries.
+		if (!stream) {
+			Common::List<Library>::iterator i;
+			for (i = _libraries.begin(); i != _libraries.end(); i++) {
+				if (!hasResource(ID_ANIM, animId)) continue;
+				stream = getResource(ID_ANIM, animId);
+				if (stream->size() >= size) break;
+				stream = NULL;
+			}
+			if (!stream) {
+				warning("ignoring attempt to play invalid anim %d", animId);
+				continue;
+			}
+
+			uint32 type = i->_archive->getResourceFlags(ID_ANIM, animId);
+
+			// If the resource is a pipe itself, then load the pipe
+			// and then fish the requested animation out of it.
+			if (type != 1) {
+				_pipeStreams.push_back(stream);
+				Pipe *newPipe = new Pipe(stream, animId);
+				_pipes.push_front(newPipe);
+				newPipe->nextFrame();
+				stream = newPipe->getResource(ID_ANIM, animId, false);
+			}
+		}
+
+		Animation *anim = new Animation(stream, animId, Common::Point(x, y), param);
+		anim->_offset = offset;
+		anim->_state = state;
+		uint32 tmp2;
+		ser.syncAsUint32LE(tmp2);
+		for (uint32 j = 0; j < tmp2; j++) {
+			ser.syncAsUint32LE(anim->_entries[j].state);
+			ser.syncAsUint16LE(anim->_entries[j].counter);
+			ser.syncAsUint16LE(anim->_entries[j].prevValue);
+		}
+		_anims.push_back(anim);
+	}
+	_sprites.clear();
+	ser.syncAsUint32LE(tmp);
+	for (uint32 i = tmp; i > 0; i--) {
+		Sprite sprite;
+		ser.syncAsUint16LE(sprite._id);
+		ser.syncAsUint16LE(sprite._animId);
+		ser.syncAsSint16LE(sprite._pos.x);
+		ser.syncAsSint16LE(sprite._pos.y);
+		ser.syncAsUint16LE(sprite._surface.w);
+		ser.syncAsUint16LE(sprite._surface.h);
+		ser.syncAsUint16LE(sprite._surface.pitch);
+		ser.syncAsUint16LE(sprite._zorder);
+		sprite._surface.pixels = malloc(sprite._surface.h * sprite._surface.pitch);
+		byte *dest = static_cast<byte *>(sprite._surface.pixels);
+		for (uint16 y = 0; y < sprite._surface.h; y++) {
+			for (uint16 x = 0; x < sprite._surface.w; x++) {
+				ser.syncAsByte(dest[x]);
+			}
+			dest += sprite._surface.pitch;
+		}
+		_sprites.push_back(sprite);
+	}
 	_dirtyRects.clear();
 	_dirtyRects.push_back(Common::Rect(0, 0, 640, 480));
 	byte palbuf[256 * 3];
@@ -184,6 +250,17 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	_system->getPaletteManager()->setPalette(palbuf, 0, 256);
 	_needsUpdate = true;
 
+	_mixer->stopAll();
+	_audioStream = NULL;
+	ser.syncAsUint32LE(tmp);
+	tmp <<= 1;
+	byte *audioBuf = (byte *)malloc(tmp);
+	ser.syncBytes(audioBuf, tmp);
+	_audioStream = Audio::makeQueuingAudioStream(22050, false);
+	_audioStream->queueBuffer(audioBuf, tmp, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
+	_currSoundPriority = 0;
+	if (!_mixer->isSoundHandleActive(_soundHandle))
+		_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _audioStream);
 	return Common::kNoError;
 }
 
@@ -207,27 +284,8 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	tmp = _libraries.size();
 	ser.syncAsUint32LE(tmp);
 	for (Common::List<Library>::const_iterator i = _libraries.reverse_begin(); i != _libraries.end(); i--) {
-		uint16 tmp = (*i)._id;
-		ser.syncAsUint16LE(tmp);
-	}
-	tmp = _sprites.size();
-	ser.syncAsUint32LE(tmp);
-	for (Common::List<Sprite>::const_iterator i = _sprites.begin(); i != _sprites.end(); i++) {
-		Sprite sprite(*i);
-		ser.syncAsUint16LE(sprite._id);
-		ser.syncAsSint16LE(sprite._pos.x);
-		ser.syncAsSint16LE(sprite._pos.y);
-		ser.syncAsUint16LE(sprite._surface.w);
-		ser.syncAsUint16LE(sprite._surface.h);
-		ser.syncAsUint16LE(sprite._surface.pitch);
-		ser.syncAsUint16LE(sprite._zorder);
-		byte *src = static_cast<byte *>((*i)._surface.pixels);
-		for (uint16 y = 0; y < sprite._surface.h; y++) {
-			for (uint x = 0; x < sprite._surface.w; x++) {
-				ser.syncAsByte(src[x]);
-			}
-			src += (*i)._surface.pitch;
-		}
+		uint16 tmp16 = (*i)._id;
+		ser.syncAsUint16LE(tmp16);
 	}
 	tmp = _pendingPageChanges.size();
 	ser.syncAsUint32LE(tmp);
@@ -240,14 +298,14 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	tmp = _stack.size();
 	ser.syncAsUint32LE(tmp);
 	for (Common::Array<uint16>::const_iterator i = _stack.begin(); i != _stack.end(); i++) {
-		uint16 tmp = (*i);
-		ser.syncAsUint16LE(tmp);
+		uint16 tmp16 = (*i);
+		ser.syncAsUint16LE(tmp16);
 	}
 	tmp = _vars.size();
 	ser.syncAsUint32LE(tmp);
 	for (Common::Array<uint16>::const_iterator i = _vars.begin(); i != _vars.end(); i++) {
-		uint16 tmp = (*i);
-		ser.syncAsUint16LE(tmp);
+		uint16 tmp16 = (*i);
+		ser.syncAsUint16LE(tmp16);
 	}
 	tmp = _oldScripts.size();
 	ser.syncAsUint32LE(tmp);
@@ -287,10 +345,62 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 		ser.syncAsUint32LE(tmp);
 	}
 
-	byte palbuf[256 * 3];
-	_system->getPaletteManager()->grabPalette(palbuf, 0, 256);
-	ser.syncBytes(palbuf, 256 * 3);
-
+	tmp = _anims.size();
+	ser.syncAsUint32LE(tmp);
+	for (Common::List<Animation *>::const_iterator i = _anims.begin(); i != _anims.end(); i++) {
+		uint16 tmp16 = (*i)->_id;
+		tmp = (*i)->_offset;
+		ser.syncAsUint16LE(tmp16);
+		ser.syncAsUint32LE(tmp);
+		tmp16 = (*i)->_basePos.x;
+		ser.syncAsUint16LE(tmp16);
+		tmp16 = (*i)->_basePos.y;
+		ser.syncAsUint16LE(tmp16);
+		tmp = (*i)->_state;
+		ser.syncAsUint32LE(tmp);
+		tmp = (*i)->_eventParam;
+		ser.syncAsUint32LE(tmp);
+		tmp = (*i)->_size;
+		ser.syncAsUint32LE(tmp);
+		tmp = (*i)->_entries.size();
+		ser.syncAsUint32LE(tmp);
+		for (Common::Array<AnimationEntry>::const_iterator j = (*i)->_entries.begin(); j != (*i)->_entries.end(); j++) {
+			tmp = (*j).state;
+			tmp16 = (*j).counter;
+			ser.syncAsUint32LE(tmp);
+			ser.syncAsUint16LE(tmp16);
+			tmp16 = (*j).prevValue;
+			ser.syncAsUint16LE(tmp16);
+		}
+	}
+	tmp = _sprites.size();
+	ser.syncAsUint32LE(tmp);
+	for (Common::List<Sprite>::const_iterator i = _sprites.begin(); i != _sprites.end(); i++) {
+		Sprite sprite(*i);
+		ser.syncAsUint16LE(sprite._id);
+		ser.syncAsUint16LE(sprite._animId);
+		ser.syncAsSint16LE(sprite._pos.x);
+		ser.syncAsSint16LE(sprite._pos.y);
+		ser.syncAsUint16LE(sprite._surface.w);
+		ser.syncAsUint16LE(sprite._surface.h);
+		ser.syncAsUint16LE(sprite._surface.pitch);
+		ser.syncAsUint16LE(sprite._zorder);
+		byte *src = static_cast<byte *>((*i)._surface.pixels);
+		for (uint16 y = 0; y < sprite._surface.h; y++) {
+			for (uint x = 0; x < sprite._surface.w; x++) {
+				ser.syncAsByte(src[x]);
+			}
+			src += (*i)._surface.pitch;
+		}
+	}
+	byte paletteBuffer[256 * 3];
+	_system->getPaletteManager()->grabPalette(paletteBuffer, 0, 256);
+	ser.syncBytes(paletteBuffer, 256 * 3);
+	byte *audioBuffer = (byte *)malloc(22050 * 60 * 2);
+ 	int32 numSamples = _audioStream->readBuffer((int16 *)audioBuffer, 22050 * 60);
+	if (numSamples == -1) numSamples = 0;
+	ser.syncAsUint32LE(numSamples);
+	ser.syncBytes((byte *)audioBuffer, numSamples * 2);
 	out->finalize();
 	return Common::kNoError;
 }


Commit: bbcf4a921842bdf6edd3d11741e7b32b82d47b70
    https://github.com/scummvm/scummvm/commit/bbcf4a921842bdf6edd3d11741e7b32b82d47b70
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:09:25+02:00

Commit Message:
COMPOSER: Fixed audio issues after save-game load.

Changed paths:
    engines/composer/resource.cpp
    engines/composer/resource.h
    engines/composer/saveload.cpp



diff --git a/engines/composer/resource.cpp b/engines/composer/resource.cpp
index 0bb7e8a..b433cd6 100644
--- a/engines/composer/resource.cpp
+++ b/engines/composer/resource.cpp
@@ -248,12 +248,12 @@ bool ComposerArchive::openStream(Common::SeekableReadStream *stream) {
 	return true;
 }
 
-Pipe::Pipe(Common::SeekableReadStream *stream, uint16 pipeId) {
+Pipe::Pipe(Common::SeekableReadStream *stream, uint16 id) {
 	_offset = 0;
 	_stream = stream;
 	_anim = NULL;
 #ifdef SAVING_ANYWHERE
-	_pipeId = pipeId;
+	_pipeId = id;
 #endif
 }
 
@@ -263,6 +263,8 @@ Pipe::~Pipe() {
 void Pipe::nextFrame() {
 	if (_offset == (uint)_stream->size())
 		return;
+	_bufferedResources.push_back(_currBufferedResources);
+	_currBufferedResources.clear();
 
 	_stream->seek(_offset, SEEK_SET);
 
@@ -315,8 +317,10 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer
 	if (res.entries.size() == 1) {
 		Common::SeekableReadStream *stream = new Common::SeekableSubReadStream(_stream,
 			res.entries[0].offset, res.entries[0].offset + res.entries[0].size);
-		if (buffering)
+		if (buffering) {
 			_types[tag].erase(id);
+			_currBufferedResources[tag].push_back(id);
+		}
 		return stream;
 	}
 
@@ -333,8 +337,10 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer
 		_stream->read(buffer + offset, res.entries[i].size);
 		offset += res.entries[i].size;
 	}
-	if (buffering)
+	if (buffering) {
 		_types[tag].erase(id);
+		_currBufferedResources[tag].push_back(id);
+	}
 	return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES);
 }
 
diff --git a/engines/composer/resource.h b/engines/composer/resource.h
index 52748ba..55d7c20 100644
--- a/engines/composer/resource.h
+++ b/engines/composer/resource.h
@@ -106,7 +106,7 @@ struct PipeResource {
 
 class Pipe {
 public:
-	Pipe(Common::SeekableReadStream *stream, uint16 pipeId);
+	Pipe(Common::SeekableReadStream *stream, uint16 id);
 	virtual ~Pipe();
 	virtual void nextFrame();
 
@@ -117,9 +117,11 @@ public:
 
 	virtual const Common::Array<uint16> *getScripts() { return NULL; }
 #ifdef SAVING_ANYWHERE
-	uint16 id() const { return _pipeId; }
+	uint16 pipeId() const { return _pipeId; }
 	uint32 offset() const { return _offset; }
-	void setOffset(uint32 offset) { while (_offset < offset) nextFrame(); }
+	void setOffset(uint32 off) { while (_offset < off) nextFrame(); }
+	typedef Common::HashMap<uint32, Common::List<uint16>> DelMap;
+	Common::Array<DelMap> _bufferedResources;
 #endif
 
 protected:
@@ -130,6 +132,7 @@ protected:
 	TypeMap _types;
 #ifdef SAVING_ANYWHERE
 	uint16 _pipeId;
+	DelMap _currBufferedResources;
 #endif
 
 	uint32 _offset;
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index 0cbf749..ca23b61 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -150,9 +150,23 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 		ser.syncAsUint32LE(offset);
 		Common::SeekableReadStream *stream = getResource(ID_ANIM, id);
 		Pipe *pipe = new Pipe(stream, id);
-		pipe->setOffset(offset);
 		_pipes.push_front(pipe);
 		_pipeStreams.push_back(stream);
+		ser.syncAsUint32LE(tmp);
+		for (uint32 j = tmp; j > 0; j--) {
+			ser.syncAsUint32LE(tmp);
+			for (uint32 k = tmp; k > 0; k--) {
+				uint32 tag;
+				ser.syncAsUint32LE(tag);
+				ser.syncAsUint32LE(tmp);
+				for (uint32 l = tmp; l > 0; l--) {
+					ser.syncAsUint16LE(id);
+					pipe->getResource(tag, id, true);
+				}
+			}
+			pipe->nextFrame();
+		}
+		pipe->setOffset(offset);
 	}
 
 	for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) {
@@ -162,7 +176,8 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	ser.syncAsUint32LE(tmp);
 	for (uint32 i = tmp; i > 0; i--) {
 		uint16 animId, x, y;
-		uint32 offset, state, param, size;
+		uint32 offset, state, param;
+		int32 size;
 		ser.syncAsUint16LE(animId);
 		ser.syncAsUint32LE(offset);
 		ser.syncAsUint16LE(x);
@@ -252,15 +267,18 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 
 	_mixer->stopAll();
 	_audioStream = NULL;
-	ser.syncAsUint32LE(tmp);
-	tmp <<= 1;
-	byte *audioBuf = (byte *)malloc(tmp);
-	ser.syncBytes(audioBuf, tmp);
+
+	ser.syncAsSint16LE(_currSoundPriority);
+	int32 numSamples;
+	ser.syncAsSint32LE(numSamples);
+	int16 *audioBuffer = (int16 *)malloc(numSamples * 2);
+	for (int32 i = 0; i < numSamples; i++)
+		ser.syncAsSint16LE(audioBuffer[i]);
 	_audioStream = Audio::makeQueuingAudioStream(22050, false);
-	_audioStream->queueBuffer(audioBuf, tmp, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
-	_currSoundPriority = 0;
+	_audioStream->queueBuffer((byte *)audioBuffer, numSamples * 2, DisposeAfterUse::YES, Audio::FLAG_16BITS);
 	if (!_mixer->isSoundHandleActive(_soundHandle))
 		_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _audioStream);
+
 	return Common::kNoError;
 }
 
@@ -339,10 +357,26 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	tmp = _pipes.size();
 	ser.syncAsUint32LE(tmp);
 	for (Common::List<Pipe *>::const_iterator i = _pipes.reverse_begin(); i != _pipes.end(); i--) {
-		uint16 tmp16 = (*i)->id();
+		uint16 tmp16 = (*i)->pipeId();
 		tmp = (*i)->offset();
 		ser.syncAsUint16LE(tmp16);
 		ser.syncAsUint32LE(tmp);
+		tmp = (*i)->_bufferedResources.size();
+		ser.syncAsUint32LE(tmp);
+		for (Common::Array<Pipe::DelMap>::const_iterator j = (*i)->_bufferedResources.begin(); j != (*i)->_bufferedResources.end(); j++) {
+			tmp = (*j).size();
+			ser.syncAsUint32LE(tmp);
+			for (Pipe::DelMap::const_iterator k = (*j).begin(); k != (*j).end(); k++) {
+				tmp = (*k)._key;
+				ser.syncAsUint32LE(tmp);
+				tmp = (*k)._value.size();
+				ser.syncAsUint32LE(tmp);
+				for (Common::List<uint16>::const_iterator l = (*k)._value.begin(); l != (*k)._value.end(); l++) {
+					tmp16 = (*l);
+					ser.syncAsUint16LE(tmp16);
+				}
+			}
+		}
 	}
 
 	tmp = _anims.size();
@@ -396,11 +430,15 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	byte paletteBuffer[256 * 3];
 	_system->getPaletteManager()->grabPalette(paletteBuffer, 0, 256);
 	ser.syncBytes(paletteBuffer, 256 * 3);
-	byte *audioBuffer = (byte *)malloc(22050 * 60 * 2);
- 	int32 numSamples = _audioStream->readBuffer((int16 *)audioBuffer, 22050 * 60);
-	if (numSamples == -1) numSamples = 0;
-	ser.syncAsUint32LE(numSamples);
-	ser.syncBytes((byte *)audioBuffer, numSamples * 2);
+
+	ser.syncAsSint16LE(_currSoundPriority);
+	int16 audioBuffer[22050];
+	int32 numSamples = _audioStream->readBuffer(audioBuffer, 22050);
+	if (numSamples  == -1) numSamples = 0;
+	ser.syncAsSint32LE(numSamples);
+	for (int32 i = 0; i < numSamples; i++)
+		ser.syncAsSint16LE(audioBuffer[i]);
+
 	out->finalize();
 	return Common::kNoError;
 }


Commit: 3d6eb8b49d759d2bc6c1507fdc91b7f9e42303cf
    https://github.com/scummvm/scummvm/commit/3d6eb8b49d759d2bc6c1507fdc91b7f9e42303cf
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:09:35+02:00

Commit Message:
COMPOSER: cleaned up miscellaneous gcc warnings and formatting issues.

Changed paths:
    engines/composer/resource.cpp
    engines/composer/resource.h
    engines/composer/saveload.cpp



diff --git a/engines/composer/resource.cpp b/engines/composer/resource.cpp
index b433cd6..063ee9c 100644
--- a/engines/composer/resource.cpp
+++ b/engines/composer/resource.cpp
@@ -263,7 +263,9 @@ Pipe::~Pipe() {
 void Pipe::nextFrame() {
 	if (_offset == (uint)_stream->size())
 		return;
+#ifdef SAVING_ANYWHERE
 	_bufferedResources.push_back(_currBufferedResources);
+#endif
 	_currBufferedResources.clear();
 
 	_stream->seek(_offset, SEEK_SET);
@@ -319,7 +321,9 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer
 			res.entries[0].offset, res.entries[0].offset + res.entries[0].size);
 		if (buffering) {
 			_types[tag].erase(id);
+#ifdef SAVING_ANYWHERE
 			_currBufferedResources[tag].push_back(id);
+#endif
 		}
 		return stream;
 	}
@@ -339,7 +343,9 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer
 	}
 	if (buffering) {
 		_types[tag].erase(id);
+#ifdef SAVING_ANYWHERE
 		_currBufferedResources[tag].push_back(id);
+#endif
 	}
 	return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES);
 }
diff --git a/engines/composer/resource.h b/engines/composer/resource.h
index 55d7c20..6383a2f 100644
--- a/engines/composer/resource.h
+++ b/engines/composer/resource.h
@@ -117,10 +117,10 @@ public:
 
 	virtual const Common::Array<uint16> *getScripts() { return NULL; }
 #ifdef SAVING_ANYWHERE
-	uint16 pipeId() const { return _pipeId; }
-	uint32 offset() const { return _offset; }
-	void setOffset(uint32 off) { while (_offset < off) nextFrame(); }
-	typedef Common::HashMap<uint32, Common::List<uint16>> DelMap;
+	uint16 getPipeId() const { return _pipeId; }
+	uint32 getOffset() const { return _offset; }
+	void setOffset(uint32 offset) { while (_offset < offset) nextFrame(); }
+	typedef Common::HashMap<uint32, Common::List<uint16> > DelMap;
 	Common::Array<DelMap> _bufferedResources;
 #endif
 
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index ca23b61..c959f38 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -199,8 +199,8 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 		}
 		// If we didn't find it, try the libraries.
 		if (!stream) {
-			Common::List<Library>::iterator i;
-			for (i = _libraries.begin(); i != _libraries.end(); i++) {
+			Common::List<Library>::iterator j;
+			for (j = _libraries.begin(); j != _libraries.end(); j++) {
 				if (!hasResource(ID_ANIM, animId)) continue;
 				stream = getResource(ID_ANIM, animId);
 				if (stream->size() >= size) break;
@@ -211,7 +211,7 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 				continue;
 			}
 
-			uint32 type = i->_archive->getResourceFlags(ID_ANIM, animId);
+			uint32 type = j->_archive->getResourceFlags(ID_ANIM, animId);
 
 			// If the resource is a pipe itself, then load the pipe
 			// and then fish the requested animation out of it.
@@ -308,9 +308,9 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	tmp = _pendingPageChanges.size();
 	ser.syncAsUint32LE(tmp);
 	for (Common::Array<PendingPageChange>::const_iterator i = _pendingPageChanges.begin(); i != _pendingPageChanges.end(); i++) {
-		uint16 tmp = (*i)._pageId;
+		uint16 tmp16 = (*i)._pageId;
 		bool tmpb = (*i)._remove;
-		ser.syncAsUint16LE(tmp);
+		ser.syncAsUint16LE(tmp16);
 		ser.syncAsByte(tmpb);
 	}
 	tmp = _stack.size();
@@ -357,8 +357,8 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	tmp = _pipes.size();
 	ser.syncAsUint32LE(tmp);
 	for (Common::List<Pipe *>::const_iterator i = _pipes.reverse_begin(); i != _pipes.end(); i--) {
-		uint16 tmp16 = (*i)->pipeId();
-		tmp = (*i)->offset();
+		uint16 tmp16 = (*i)->getPipeId();
+		tmp = (*i)->getOffset();
 		ser.syncAsUint16LE(tmp16);
 		ser.syncAsUint32LE(tmp);
 		tmp = (*i)->_bufferedResources.size();


Commit: 1f1928c9ac41705dcd82416a62d9efde370d8d8a
    https://github.com/scummvm/scummvm/commit/1f1928c9ac41705dcd82416a62d9efde370d8d8a
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:09:47+02:00

Commit Message:
COMPOSER: Added new file to module.mk

Changed paths:
    engines/composer/module.mk



diff --git a/engines/composer/module.mk b/engines/composer/module.mk
index c879d53..74465cf 100644
--- a/engines/composer/module.mk
+++ b/engines/composer/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS = \
 	detection.o \
 	graphics.o \
 	resource.o \
+	saveload.o \
 	scripting.o
 
 # This module can be built as a plugin


Commit: 027bab88fba3187c2fcf2211d0aba5f6cec09a6c
    https://github.com/scummvm/scummvm/commit/027bab88fba3187c2fcf2211d0aba5f6cec09a6c
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:09:59+02:00

Commit Message:
COMPOSER: Added support for saving/loading in V1 games.

Changed paths:
    engines/composer/composer.cpp
    engines/composer/composer.h
    engines/composer/resource.cpp
    engines/composer/resource.h
    engines/composer/saveload.cpp



diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp
index 73d97e1..2ef6acc 100644
--- a/engines/composer/composer.cpp
+++ b/engines/composer/composer.cpp
@@ -378,7 +378,9 @@ void ComposerEngine::loadLibrary(uint id) {
 	}
 
 	Common::String filename;
-
+#ifdef SAVING_ANYWHERE
+	Common::String oldGroup = _bookGroup;
+#endif
 	if (getGameType() == GType_ComposerV1) {
 		if (!id || _bookGroup.empty())
 			filename = getStringFromConfig("Common", "StartPage");
@@ -412,6 +414,9 @@ void ComposerEngine::loadLibrary(uint id) {
 	Library library;
 
 	library._id = id;
+#ifdef SAVING_ANYWHERE
+	library._group = oldGroup;
+#endif
 	library._archive = new ComposerArchive();
 	if (!library._archive->openFile(filename))
 		error("failed to open '%s'", filename.c_str());
diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index b570d16..82457be 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -114,6 +114,9 @@ struct Library {
 	uint _id;
 	Archive *_archive;
 
+#ifdef SAVING_ANYWHERE
+	Common::String _group;
+#endif
 	Common::List<Button> _buttons;
 	Common::List<KeyboardHandler> _keyboardHandlers;
 };
diff --git a/engines/composer/resource.cpp b/engines/composer/resource.cpp
index 063ee9c..8192da9 100644
--- a/engines/composer/resource.cpp
+++ b/engines/composer/resource.cpp
@@ -263,10 +263,6 @@ Pipe::~Pipe() {
 void Pipe::nextFrame() {
 	if (_offset == (uint)_stream->size())
 		return;
-#ifdef SAVING_ANYWHERE
-	_bufferedResources.push_back(_currBufferedResources);
-#endif
-	_currBufferedResources.clear();
 
 	_stream->seek(_offset, SEEK_SET);
 
@@ -322,7 +318,11 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer
 		if (buffering) {
 			_types[tag].erase(id);
 #ifdef SAVING_ANYWHERE
-			_currBufferedResources[tag].push_back(id);
+			bool found = false;
+			for (Common::List<uint16>::const_iterator i = _bufferedResources[tag].begin(); !found && (i != _bufferedResources[tag].end()); i++)
+				if ((*i) == id) found = true;
+			if (!found)
+				_bufferedResources[tag].push_back(id);
 #endif
 		}
 		return stream;
@@ -344,7 +344,11 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer
 	if (buffering) {
 		_types[tag].erase(id);
 #ifdef SAVING_ANYWHERE
-		_currBufferedResources[tag].push_back(id);
+		bool found = false;
+		for (Common::List<uint16>::const_iterator i = _bufferedResources[tag].begin(); !found && (i != _bufferedResources[tag].end()); i++)
+			if ((*i) == id) found = true;
+		if (!found)
+			_bufferedResources[tag].push_back(id);
 #endif
 	}
 	return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES);
diff --git a/engines/composer/resource.h b/engines/composer/resource.h
index 6383a2f..9e297e1 100644
--- a/engines/composer/resource.h
+++ b/engines/composer/resource.h
@@ -118,10 +118,10 @@ public:
 	virtual const Common::Array<uint16> *getScripts() { return NULL; }
 #ifdef SAVING_ANYWHERE
 	uint16 getPipeId() const { return _pipeId; }
-	uint32 getOffset() const { return _offset; }
-	void setOffset(uint32 offset) { while (_offset < offset) nextFrame(); }
+	virtual uint32 getOffset() const { return _offset; }
+	virtual void setOffset(uint32 offset) { while (_offset < offset) nextFrame(); }
 	typedef Common::HashMap<uint32, Common::List<uint16> > DelMap;
-	Common::Array<DelMap> _bufferedResources;
+	DelMap _bufferedResources;
 #endif
 
 protected:
@@ -132,7 +132,6 @@ protected:
 	TypeMap _types;
 #ifdef SAVING_ANYWHERE
 	uint16 _pipeId;
-	DelMap _currBufferedResources;
 #endif
 
 	uint32 _offset;
@@ -144,6 +143,10 @@ public:
 	void nextFrame();
 
 	const Common::Array<uint16> *getScripts() { return &_scripts; }
+#ifdef SAVING_ANYWHERE
+	uint32 getOffset() const { return _currFrame; }
+	void setOffset(uint32 offset) { while (_currFrame < offset) nextFrame(); }
+#endif
 
 protected:
 	uint32 _currFrame, _numFrames;
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index c959f38..ed26616 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -62,7 +62,6 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	_currentTime += timeDelta;
 	ser.syncAsUint32LE(_lastTime);
 	_lastTime += timeDelta;
-	ser.syncString(_bookGroup);
 	Common::Array<uint16> libIds;
 	for (Common::List<Library>::iterator i = _libraries.begin(); i != _libraries.end(); i++) 
 		libIds.push_back((*i)._id);
@@ -72,8 +71,10 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	for (uint32 i = tmp; i > 0; i--) {
 		uint16 id;
 		ser.syncAsUint16LE(id);
+		ser.syncString(_bookGroup);
 		loadLibrary(id);
 	}
+	ser.syncString(_bookGroup);
 
 	_pendingPageChanges.clear();
 	ser.syncAsUint32LE(tmp);
@@ -106,11 +107,13 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	ser.syncAsUint32LE(tmp);
 	for (uint32 i = tmp; i > 0; i--) {
 		uint16 id;
-		uint32 delay;
+		uint32 pos, delay;
+		ser.syncAsUint32LE(pos);
 		ser.syncAsUint16LE(id);
 		ser.syncAsUint32LE(delay);
 		OldScript *oTmp = new OldScript(id, getResource(ID_SCRP, id));
 		oTmp->_currDelay = delay;
+		oTmp->_stream->seek(pos, SEEK_SET);
 		_oldScripts.push_back(oTmp);
 	}
 	_queuedScripts.clear();
@@ -148,25 +151,29 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 		uint32 offset;
 		ser.syncAsUint16LE(id);
 		ser.syncAsUint32LE(offset);
-		Common::SeekableReadStream *stream = getResource(ID_ANIM, id);
-		Pipe *pipe = new Pipe(stream, id);
+		Pipe *pipe;
+		Common::SeekableReadStream *stream;
+		if (getGameType() == GType_ComposerV1) {
+			stream = getResource(ID_PIPE, id);
+			pipe = new OldPipe(stream, id);
+		} else {
+			stream = getResource(ID_ANIM, id);
+			pipe = new Pipe(stream, id);
+		}
 		_pipes.push_front(pipe);
 		_pipeStreams.push_back(stream);
+		pipe->setOffset(offset);
 		ser.syncAsUint32LE(tmp);
 		for (uint32 j = tmp; j > 0; j--) {
+			uint32 tag;
+			ser.syncAsUint32LE(tag);
 			ser.syncAsUint32LE(tmp);
 			for (uint32 k = tmp; k > 0; k--) {
-				uint32 tag;
-				ser.syncAsUint32LE(tag);
-				ser.syncAsUint32LE(tmp);
-				for (uint32 l = tmp; l > 0; l--) {
-					ser.syncAsUint16LE(id);
+				ser.syncAsUint16LE(id);
+				if (pipe->hasResource(tag, id))
 					pipe->getResource(tag, id, true);
-				}
 			}
-			pipe->nextFrame();
 		}
-		pipe->setOffset(offset);
 	}
 
 	for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) {
@@ -298,13 +305,15 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	ser.syncAsUint32LE(tmp);
 	ser.syncAsUint32LE(_currentTime);
 	ser.syncAsUint32LE(_lastTime);
-	ser.syncString(_bookGroup);
 	tmp = _libraries.size();
 	ser.syncAsUint32LE(tmp);
 	for (Common::List<Library>::const_iterator i = _libraries.reverse_begin(); i != _libraries.end(); i--) {
 		uint16 tmp16 = (*i)._id;
+		Common::String tmps = (*i)._group;
 		ser.syncAsUint16LE(tmp16);
+		ser.syncString(tmps);
 	}
+	ser.syncString(_bookGroup);
 	tmp = _pendingPageChanges.size();
 	ser.syncAsUint32LE(tmp);
 	for (Common::Array<PendingPageChange>::const_iterator i = _pendingPageChanges.begin(); i != _pendingPageChanges.end(); i++) {
@@ -328,6 +337,8 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	tmp = _oldScripts.size();
 	ser.syncAsUint32LE(tmp);
 	for (Common::List<OldScript *>::const_iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) {
+		tmp = (*i)->_stream->pos();
+		ser.syncAsUint32LE(tmp);
 		uint16 tmp16 = (*i)->_id;
 		tmp = (*i)->_currDelay;
 		ser.syncAsUint16LE(tmp16);
@@ -363,18 +374,14 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 		ser.syncAsUint32LE(tmp);
 		tmp = (*i)->_bufferedResources.size();
 		ser.syncAsUint32LE(tmp);
-		for (Common::Array<Pipe::DelMap>::const_iterator j = (*i)->_bufferedResources.begin(); j != (*i)->_bufferedResources.end(); j++) {
-			tmp = (*j).size();
+		for (Pipe::DelMap::const_iterator j = (*i)->_bufferedResources.begin(); j != (*i)->_bufferedResources.end(); j++) {
+			tmp = (*j)._key;
+			ser.syncAsUint32LE(tmp);
+			tmp = (*j)._value.size();
 			ser.syncAsUint32LE(tmp);
-			for (Pipe::DelMap::const_iterator k = (*j).begin(); k != (*j).end(); k++) {
-				tmp = (*k)._key;
-				ser.syncAsUint32LE(tmp);
-				tmp = (*k)._value.size();
-				ser.syncAsUint32LE(tmp);
-				for (Common::List<uint16>::const_iterator l = (*k)._value.begin(); l != (*k)._value.end(); l++) {
-					tmp16 = (*l);
-					ser.syncAsUint16LE(tmp16);
-				}
+			for (Common::List<uint16>::const_iterator k = (*j)._value.begin(); k != (*j)._value.end(); k++) {
+				tmp16 = (*k);
+				ser.syncAsUint16LE(tmp16);
 			}
 		}
 	}


Commit: c4c6cce78ea67f26b1c2017ebb15f00612c4d41b
    https://github.com/scummvm/scummvm/commit/c4c6cce78ea67f26b1c2017ebb15f00612c4d41b
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:10:11+02:00

Commit Message:
COMPOSER: Completely removed unnecessary #ifdefs

Changed paths:
    engines/composer/composer.cpp
    engines/composer/composer.h
    engines/composer/detection.cpp
    engines/composer/graphics.cpp
    engines/composer/graphics.h
    engines/composer/resource.cpp
    engines/composer/resource.h
    engines/composer/saveload.cpp



diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp
index 2ef6acc..e9a91b1 100644
--- a/engines/composer/composer.cpp
+++ b/engines/composer/composer.cpp
@@ -378,9 +378,7 @@ void ComposerEngine::loadLibrary(uint id) {
 	}
 
 	Common::String filename;
-#ifdef SAVING_ANYWHERE
 	Common::String oldGroup = _bookGroup;
-#endif
 	if (getGameType() == GType_ComposerV1) {
 		if (!id || _bookGroup.empty())
 			filename = getStringFromConfig("Common", "StartPage");
@@ -414,9 +412,7 @@ void ComposerEngine::loadLibrary(uint id) {
 	Library library;
 
 	library._id = id;
-#ifdef SAVING_ANYWHERE
 	library._group = oldGroup;
-#endif
 	library._archive = new ComposerArchive();
 	if (!library._archive->openFile(filename))
 		error("failed to open '%s'", filename.c_str());
diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index 82457be..928072b 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -114,9 +114,7 @@ struct Library {
 	uint _id;
 	Archive *_archive;
 
-#ifdef SAVING_ANYWHERE
 	Common::String _group;
-#endif
 	Common::List<Button> _buttons;
 	Common::List<KeyboardHandler> _keyboardHandlers;
 };
@@ -153,12 +151,10 @@ class ComposerEngine : public Engine {
 protected:
 	Common::Error run();
 
-#ifdef SAVING_ANYWHERE
 	bool canLoadGameStateCurrently() { return true; }
 	Common::Error loadGameState(int slot);
 	bool canSaveGameStateCurrently() { return true; }
 	Common::Error saveGameState(int slot, const Common::String &desc);
-#endif
 
 public:
 	ComposerEngine(OSystem *syst, const ComposerGameDescription *gameDesc);
@@ -220,9 +216,7 @@ private:
 	uint16 _mouseSpriteId;
 	Common::Point _mouseOffset;
 
-#ifdef SAVING_ANYWHERE
 	Common::String makeSaveGameName(int slot);
-#endif
 	Common::String getStringFromConfig(const Common::String &section, const Common::String &key);
 	Common::String getFilename(const Common::String &section, uint id);
 	Common::String mangleFilename(Common::String filename);
diff --git a/engines/composer/detection.cpp b/engines/composer/detection.cpp
index 3a8fb0d..bd0c432 100644
--- a/engines/composer/detection.cpp
+++ b/engines/composer/detection.cpp
@@ -21,11 +21,9 @@
  */
 
 #include "base/plugins.h"
-#ifdef SAVING_ANYWHERE
 #include "common/savefile.h"
 #include "common/serializer.h"
 #include "common/str-array.h"
-#endif // SAVING_ANYWHERE
 #include "engines/advancedDetector.h"
 
 #include "composer/composer.h"
@@ -466,14 +464,9 @@ bool ComposerMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD
 }
 
 bool ComposerMetaEngine::hasFeature(MetaEngineFeature f) const {
-#ifdef SAVING_ANYWHERE
-		return (f == kSupportsListSaves);
-#else
-	return false;
-#endif // SAVING_ANYWHERE
+	return (f == kSupportsListSaves);
 }
 
-#ifdef SAVING_ANYWHERE
 Common::String getSaveName(Common::InSaveFile *in) {
 	Common::Serializer ser(in, NULL);
 	Common::String name;
@@ -512,14 +505,11 @@ SaveStateList ComposerMetaEngine::listSaves(const char *target) const {
 
 	return saveList;
 }
-#endif // SAVING_ANYWHERE
 
 bool Composer::ComposerEngine::hasFeature(EngineFeature f) const {
 	return (f == kSupportsRTL 
-#ifdef SAVING_ANYWHERE
-			|| f == kSupportsSavingDuringRuntime || f == kSupportsLoadingDuringRuntime
-#endif // SAVING_ANYWHERE
-			);
+		|| f == kSupportsSavingDuringRuntime 
+		|| f == kSupportsLoadingDuringRuntime);
 }
 
 #if PLUGIN_ENABLED_DYNAMIC(COMPOSER)
diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp
index 2c50cb1..312534f 100644
--- a/engines/composer/graphics.cpp
+++ b/engines/composer/graphics.cpp
@@ -57,9 +57,7 @@ Animation::Animation(Common::SeekableReadStream *stream, uint16 id, Common::Poin
 
 	// probably total size?
 	uint32 unknown = _stream->readUint32LE();
-#ifdef SAVING_ANYWHERE
 	_size = unknown;
-#endif
 
 	debug(8, "anim: size %d, state %08x, unknown %08x", size, _state, unknown);
 
diff --git a/engines/composer/graphics.h b/engines/composer/graphics.h
index cfa581d..4805e50 100644
--- a/engines/composer/graphics.h
+++ b/engines/composer/graphics.h
@@ -59,9 +59,7 @@ struct Animation {
 	uint32 _eventParam;
 
 	uint32 _state;
-#ifdef SAVING_ANYWHERE
 	uint32 _size;
-#endif
 
 	Common::Array<AnimationEntry> _entries;
 
diff --git a/engines/composer/resource.cpp b/engines/composer/resource.cpp
index 8192da9..fa1811c 100644
--- a/engines/composer/resource.cpp
+++ b/engines/composer/resource.cpp
@@ -252,9 +252,7 @@ Pipe::Pipe(Common::SeekableReadStream *stream, uint16 id) {
 	_offset = 0;
 	_stream = stream;
 	_anim = NULL;
-#ifdef SAVING_ANYWHERE
 	_pipeId = id;
-#endif
 }
 
 Pipe::~Pipe() {
@@ -317,13 +315,11 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer
 			res.entries[0].offset, res.entries[0].offset + res.entries[0].size);
 		if (buffering) {
 			_types[tag].erase(id);
-#ifdef SAVING_ANYWHERE
 			bool found = false;
 			for (Common::List<uint16>::const_iterator i = _bufferedResources[tag].begin(); !found && (i != _bufferedResources[tag].end()); i++)
 				if ((*i) == id) found = true;
 			if (!found)
 				_bufferedResources[tag].push_back(id);
-#endif
 		}
 		return stream;
 	}
@@ -343,13 +339,11 @@ Common::SeekableReadStream *Pipe::getResource(uint32 tag, uint16 id, bool buffer
 	}
 	if (buffering) {
 		_types[tag].erase(id);
-#ifdef SAVING_ANYWHERE
 		bool found = false;
 		for (Common::List<uint16>::const_iterator i = _bufferedResources[tag].begin(); !found && (i != _bufferedResources[tag].end()); i++)
 			if ((*i) == id) found = true;
 		if (!found)
 			_bufferedResources[tag].push_back(id);
-#endif
 	}
 	return new Common::MemoryReadStream(buffer, size, DisposeAfterUse::YES);
 }
diff --git a/engines/composer/resource.h b/engines/composer/resource.h
index 9e297e1..fc4e20a 100644
--- a/engines/composer/resource.h
+++ b/engines/composer/resource.h
@@ -116,13 +116,11 @@ public:
 	Common::SeekableReadStream *getResource(uint32 tag, uint16 id, bool buffering);
 
 	virtual const Common::Array<uint16> *getScripts() { return NULL; }
-#ifdef SAVING_ANYWHERE
 	uint16 getPipeId() const { return _pipeId; }
 	virtual uint32 getOffset() const { return _offset; }
 	virtual void setOffset(uint32 offset) { while (_offset < offset) nextFrame(); }
 	typedef Common::HashMap<uint32, Common::List<uint16> > DelMap;
 	DelMap _bufferedResources;
-#endif
 
 protected:
 	Common::SeekableReadStream *_stream;
@@ -130,9 +128,7 @@ protected:
 	typedef Common::HashMap<uint16, PipeResource> ResourceMap;
 	typedef Common::HashMap<uint32, ResourceMap> TypeMap;
 	TypeMap _types;
-#ifdef SAVING_ANYWHERE
 	uint16 _pipeId;
-#endif
 
 	uint32 _offset;
 };
@@ -143,10 +139,8 @@ public:
 	void nextFrame();
 
 	const Common::Array<uint16> *getScripts() { return &_scripts; }
-#ifdef SAVING_ANYWHERE
 	uint32 getOffset() const { return _currFrame; }
 	void setOffset(uint32 offset) { while (_currFrame < offset) nextFrame(); }
-#endif
 
 protected:
 	uint32 _currFrame, _numFrames;
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index ed26616..c56b95f 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -20,7 +20,6 @@
  *
  */
 
-#ifdef SAVING_ANYWHERE
 #include "audio/audiostream.h"
 #include "audio/decoders/raw.h"
 #include "common/config-manager.h"
@@ -450,4 +449,3 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	return Common::kNoError;
 }
 }
-#endif


Commit: d91368aa1a2f7b4bc7b270cfbd72db9c97b9441f
    https://github.com/scummvm/scummvm/commit/d91368aa1a2f7b4bc7b270cfbd72db9c97b9441f
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:11:17+02:00

Commit Message:
COMPOSER: Saving/loading code deduplication

Changed paths:
    engines/composer/composer.h
    engines/composer/graphics.cpp
    engines/composer/saveload.cpp



diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index 928072b..e968242 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -29,6 +29,8 @@
 #include "common/debug.h"
 #include "common/debug-channels.h"
 #include "common/error.h"
+=======
+#include "common/serializer.h"
 #include "common/textconsole.h"
 #include "common/rect.h"
 
@@ -148,6 +150,8 @@ struct OldScript {
 };
 
 class ComposerEngine : public Engine {
+	template <typename T>
+	friend void sync(Common::Serializer &ser, T &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion);
 protected:
 	Common::Error run();
 
@@ -238,6 +242,7 @@ private:
 	void tickOldScripts();
 	bool tickOldScript(OldScript *script);
 
+	void loadAnimation(Animation *&anim, uint16 animId, int16 x, int16 y, int16 eventParam, int32 size = 0);
 	void playAnimation(uint16 animId, int16 param1, int16 param2, int16 param3);
 	void stopAnimation(Animation *anim, bool localOnly = false, bool pipesOnly = false);
 	void playWaveForAnim(uint16 id, uint16 priority, bool bufferingOnly);
diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp
index 312534f..32b9812 100644
--- a/engines/composer/graphics.cpp
+++ b/engines/composer/graphics.cpp
@@ -83,17 +83,7 @@ void Animation::seekToCurrPos() {
 	_stream->seek(_offset, SEEK_SET);
 }
 
-void ComposerEngine::playAnimation(uint16 animId, int16 x, int16 y, int16 eventParam) {
-	// First, we check if this animation is already playing,
-	// and if it is, we sabotage that running one first.
-	for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) {
-		Animation *anim = *i;
-		if (anim->_id != animId)
-			continue;
-
-		stopAnimation(*i);
-	}
-
+void ComposerEngine::loadAnimation(Animation *&anim, uint16 animId, int16 x, int16 y, int16 eventParam, int32 size) {
 	Common::SeekableReadStream *stream = NULL;
 	Pipe *newPipe = NULL;
 
@@ -103,7 +93,10 @@ void ComposerEngine::playAnimation(uint16 animId, int16 x, int16 y, int16 eventP
 		if (!pipe->hasResource(ID_ANIM, animId))
 			continue;
 		stream = pipe->getResource(ID_ANIM, animId, false);
-		break;
+
+		// When loading from savegame, make sure we have the correct stream
+		if ((!size) || (stream->size() >= size)) break;
+		stream = NULL;
 	}
 
 	// If we didn't find it, try the libraries.
@@ -112,14 +105,16 @@ void ComposerEngine::playAnimation(uint16 animId, int16 x, int16 y, int16 eventP
 			warning("ignoring attempt to play invalid anim %d", animId);
 			return;
 		}
-		stream = getResource(ID_ANIM, animId);
+		Common::List<Library>::iterator j;
+		for (j = _libraries.begin(); j != _libraries.end(); j++) {
+			stream = j->_archive->getResource(ID_ANIM, animId);
 
-		uint32 type = 0;
-		for (Common::List<Library>::iterator i = _libraries.begin(); i != _libraries.end(); i++)
-			if (i->_archive->hasResource(ID_ANIM, animId)) {
-				type = i->_archive->getResourceFlags(ID_ANIM, animId);
-				break;
-			}
+			// When loading from savegame, make sure we have the correct stream
+			if ((!size) || (stream->size() >= size)) break;
+			stream = NULL;
+		}
+
+		uint32 type = j->_archive->getResourceFlags(ID_ANIM, animId);
 
 		// If the resource is a pipe itself, then load the pipe
 		// and then fish the requested animation out of it.
@@ -132,13 +127,28 @@ void ComposerEngine::playAnimation(uint16 animId, int16 x, int16 y, int16 eventP
 		}
 	}
 
-	Animation *anim = new Animation(stream, animId, Common::Point(x, y), eventParam);
-	_anims.push_back(anim);
-	runEvent(kEventAnimStarted, animId, eventParam, 0);
+	anim = new Animation(stream, animId, Common::Point(x, y), eventParam);
 	if (newPipe)
 		newPipe->_anim = anim;
 }
 
+void ComposerEngine::playAnimation(uint16 animId, int16 x, int16 y, int16 eventParam) {
+	// First, we check if this animation is already playing,
+	// and if it is, we sabotage that running one first.
+	for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) {
+		Animation *anim = *i;
+		if (anim->_id != animId)
+			continue;
+
+		stopAnimation(*i);
+	}
+
+	Animation *anim = NULL;
+	loadAnimation(anim, animId, x, y, eventParam);
+	_anims.push_back(anim);
+	runEvent(kEventAnimStarted, animId, eventParam, 0);
+}
+
 void ComposerEngine::stopAnimation(Animation *anim, bool localOnly, bool pipesOnly) {
 	// disable the animation
 	anim->_state = 0;
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index c56b95f..7bbdcd3 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -34,11 +34,249 @@
 #include "composer/graphics.h"
 
 namespace Composer {
+ComposerEngine *vm = NULL;
+uint32 timeDelta; 
+
+template <class T>
+void sync(Common::Serializer &ser, T &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion);
+template <class T>
+void syncArray(Common::Serializer &ser, Common::Array<T> &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion) {
+	if (ser.isSaving()) {
+		uint32 size = data.size();
+		ser.syncAsUint32LE(size, minVersion, maxVersion);
+		for (Common::Array<T>::iterator i = data.begin(); i != data.end(); i++) {
+			sync<T>(ser, *i, minVersion, maxVersion);
+		}
+	} else {
+		uint32 size;
+		data.clear();
+		ser.syncAsUint32LE(size, minVersion, maxVersion);
+		for (uint32 i = 0; i < size; i++) {
+			T item;
+			sync<T>(ser, item, minVersion, maxVersion);
+			data.push_back(item);
+		}
+	}
+}
+template <class T>
+void syncList(Common::Serializer &ser, Common::List<T> &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion) {
+	if (ser.isSaving()) {
+		uint32 size = data.size();
+		ser.syncAsUint32LE(size, minVersion, maxVersion);
+		for (Common::List<T>::iterator i = data.begin(); i != data.end(); i++) {
+			sync<T>(ser, *i, minVersion, maxVersion);
+		}
+	} else {
+		uint32 size;
+		data.clear();
+		ser.syncAsUint32LE(size, minVersion, maxVersion);
+		for (uint32 i = 0; i < size; i++) {
+			T item;
+			sync<T>(ser, item, minVersion, maxVersion);
+			data.push_back(item);
+		}
+	}
+}
+template <class T>
+void syncListReverse(Common::Serializer &ser, Common::List<T> &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion) {
+	if (ser.isSaving()) {
+		uint32 size = data.size();
+		ser.syncAsUint32LE(size, minVersion, maxVersion);
+		for (Common::List<T>::iterator i = data.reverse_begin(); i != data.end(); i--) {
+			sync<T>(ser, *i, minVersion, maxVersion);
+		}
+	} else {
+		uint32 size;
+		data.clear();
+		ser.syncAsUint32LE(size, minVersion, maxVersion);
+		for (uint32 i = 0; i < size; i++) {
+			T item;
+			sync<T>(ser, item, minVersion, maxVersion);
+			data.push_front(item);
+		}
+	}
+}
+template<>
+void sync<uint16> (Common::Serializer &ser, uint16 &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+	ser.syncAsUint16LE(data, minVersion, maxVersion);
+}
+template<>
+void sync<uint32> (Common::Serializer &ser, uint32 &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+	ser.syncAsUint32LE(data, minVersion, maxVersion);
+}
+template<>
+void sync<Library> (Common::Serializer &ser, Library &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+	if (ser.isSaving()) {
+		ser.syncAsUint16LE(data._id, minVersion, maxVersion);
+		ser.syncString(data._group, minVersion, maxVersion);
+	} else {
+		uint16 id;
+		ComposerEngine *vm = (ComposerEngine *)g_engine;
+		ser.syncAsUint16LE(id, minVersion, maxVersion);
+		ser.syncString(vm->_bookGroup, minVersion, maxVersion);
+		vm->loadLibrary(id);
+	}
+}
+template <>
+void syncListReverse<Library> (Common::Serializer &ser, Common::List<Library> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+	if (ser.isSaving()) {
+		uint32 size = data.size();
+		ser.syncAsUint32LE(size, minVersion, maxVersion);
+		for (Common::List<Library>::iterator i = data.reverse_begin(); i != data.end(); i--) {
+			sync<Library>(ser, *i, minVersion, maxVersion);
+		}
+	} else {
+		uint32 size;
+		ser.syncAsUint32LE(size, minVersion, maxVersion);
+		for (uint32 i = 0; i < size; i++) {
+			Library item;
+			sync<Library>(ser, item, minVersion, maxVersion);
+		}
+	}
+}
+template<>
+void sync<PendingPageChange> (Common::Serializer &ser, PendingPageChange &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+	ser.syncAsUint16LE(data._pageId, minVersion, maxVersion);
+	ser.syncAsByte(data._remove, minVersion, maxVersion);
+}
+template<>
+void sync<OldScript *> (Common::Serializer &ser, OldScript *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+	uint16 id;
+	uint32 pos, delay;
+	if (ser.isSaving()) {
+		pos = data->_stream->pos();
+		id = data->_id;
+		delay = data->_currDelay;
+	}
+	ser.syncAsUint32LE(pos);
+	ser.syncAsUint16LE(id);
+	ser.syncAsUint32LE(delay);
+	if (ser.isLoading()) {
+		data = new OldScript(id, vm->getResource(ID_SCRP, id));
+		data->_currDelay = delay;
+		data->_stream->seek(pos, SEEK_SET);
+	}
+}
+template<>
+void sync<QueuedScript> (Common::Serializer &ser, QueuedScript &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+	ser.syncAsUint32LE(data._baseTime);
+	ser.syncAsUint32LE(data._duration);	
+	ser.syncAsUint32LE(data._count);
+	ser.syncAsUint16LE(data._scriptId);
+	if (ser.isLoading()) data._baseTime += timeDelta;
+}
+template<>
+void sync<Pipe *> (Common::Serializer &ser, Pipe *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+	uint16 id;
+	uint32 offset, tmp;
+	if (ser.isSaving()) {
+		id = data->getPipeId();
+		offset = data->getOffset();
+		tmp = data->_bufferedResources.size();
+	}
+	ser.syncAsUint16LE(id);
+	ser.syncAsUint32LE(offset);
+
+	if (ser.isLoading()) {
+		// On load, get and initialize streams
+		Common::SeekableReadStream *stream;
+		if (vm->getGameType() == GType_ComposerV1) {
+			stream = vm->getResource(ID_PIPE, id);
+			data = new OldPipe(stream, id);
+		} else {
+			stream = vm->getResource(ID_ANIM, id);
+			data = new Pipe(stream, id);
+		}
+		vm->_pipeStreams.push_back(stream);
+		data->setOffset(offset);
+		ser.syncAsUint32LE(tmp);
+		for (uint32 j = tmp; j > 0; j--) {
+			uint32 tag;
+			ser.syncAsUint32LE(tag);
+			ser.syncAsUint32LE(tmp);
+			for (uint32 k = tmp; k > 0; k--) {
+				ser.syncAsUint16LE(id);
+				if (data->hasResource(tag, id))
+					data->getResource(tag, id, true);
+			}
+		}
+	} else {
+		ser.syncAsUint32LE(tmp);
+		for (Pipe::DelMap::iterator i = data->_bufferedResources.begin(); i != data->_bufferedResources.end(); i++) {
+			uint32 key = (*i)._key;
+			ser.syncAsUint32LE(key);
+			syncList<uint16> (ser, (*i)._value, minVersion, maxVersion);
+		}
+	}
+}
+template<>
+void sync<AnimationEntry> (Common::Serializer &ser, AnimationEntry &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+	ser.syncAsUint32LE(data.state);
+	ser.syncAsUint16LE(data.counter);
+	ser.syncAsUint16LE(data.prevValue);
+}
+template<>
+void sync<Animation *> (Common::Serializer &ser, Animation *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+	uint16 animId, x, y;
+	uint32 offset, state, param;
+	int32 size;
+	if (ser.isSaving()) {
+		animId = data->_id;
+		offset = data->_offset;
+		x = data->_basePos.x;
+		y = data->_basePos.x;
+		state = data->_state;
+		param = data->_eventParam;
+		size = data->_size;
+	}
+	ser.syncAsUint16LE(animId);
+	ser.syncAsUint32LE(offset);
+	ser.syncAsUint16LE(x);
+	ser.syncAsUint16LE(y);
+	ser.syncAsUint32LE(state);
+	ser.syncAsUint32LE(param);
+	ser.syncAsUint32LE(size);
+	if (ser.isLoading()) {
+		// On load, get and initialize streams
+		vm->loadAnimation(data, animId, x, y, param, size);
+		data->_offset = offset;
+		data->_state = state;
+		uint32 tmp;
+		ser.syncAsUint32LE(tmp);
+		for (uint32 i = 0; i < tmp; i++) {
+			sync<AnimationEntry> (ser, data->_entries[i], minVersion, maxVersion);
+		}
+	} else {
+		syncArray<AnimationEntry> (ser, data->_entries, minVersion, maxVersion);
+	}
+}
+template<>
+void sync<Sprite> (Common::Serializer &ser, Sprite &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+		ser.syncAsUint16LE(data._id);
+		ser.syncAsUint16LE(data._animId);
+		ser.syncAsSint16LE(data._pos.x);
+		ser.syncAsSint16LE(data._pos.y);
+		ser.syncAsUint16LE(data._surface.w);
+		ser.syncAsUint16LE(data._surface.h);
+		ser.syncAsUint16LE(data._surface.pitch);
+		ser.syncAsUint16LE(data._zorder);
+		if (ser.isLoading())
+			data._surface.pixels = malloc(data._surface.h * data._surface.pitch);
+		byte *pix = static_cast<byte *>(data._surface.pixels);
+		for (uint16 y = 0; y < data._surface.h; y++) {
+			for (uint16 x = 0; x < data._surface.w; x++) {
+				ser.syncAsByte(pix[x]);
+			}
+			pix += data._surface.pitch;
+		}
+
+}
 Common::String ComposerEngine::makeSaveGameName(int slot) {
 	return (_targetName + Common::String::format(".%02d", slot));
 }
 
 Common::Error ComposerEngine::loadGameState(int slot) {
+	vm = this;
 	Common::String filename = makeSaveGameName(slot);
 	Common::InSaveFile *in;
 	if (!(in = _saveFileMan->openForLoading(filename)))
@@ -57,214 +295,62 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	ser.syncAsUint32LE(tmp);
 	_rnd->setSeed(tmp);
 	ser.syncAsUint32LE(_currentTime);
-	uint32 timeDelta = _system->getMillis() - _currentTime;
+	timeDelta = _system->getMillis() - _currentTime;
 	_currentTime += timeDelta;
 	ser.syncAsUint32LE(_lastTime);
 	_lastTime += timeDelta;
+
+	// Unload all Libraries
 	Common::Array<uint16> libIds;
 	for (Common::List<Library>::iterator i = _libraries.begin(); i != _libraries.end(); i++) 
 		libIds.push_back((*i)._id);
 	for (uint32 i = 0; i < libIds.size(); i++) 
 		unloadLibrary(libIds[i]);
-	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i > 0; i--) {
-		uint16 id;
-		ser.syncAsUint16LE(id);
-		ser.syncString(_bookGroup);
-		loadLibrary(id);
-	}
+
+	syncListReverse<Library> (ser, _libraries);
 	ser.syncString(_bookGroup);
 
-	_pendingPageChanges.clear();
-	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i > 0; i--) {
-		uint16 id;
-		bool remove;
-		ser.syncAsUint16LE(id);
-		ser.syncAsByte(remove);
-		_pendingPageChanges.push_back(PendingPageChange(id, remove));
-	}
-	_stack.clear();
-	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i > 0; i--) {
-		uint16 svar;
-		ser.syncAsUint16LE(svar);
-		_stack.push_back(svar);
-	}
-	_vars.clear();
-	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i > 0; i--) {
-		uint16 var;
-		ser.syncAsUint16LE(var);
-		_vars.push_back(var);
-	}
+	syncArray<PendingPageChange> (ser, _pendingPageChanges);
+	syncArray<uint16> (ser, _stack);
+	syncArray<uint16> (ser, _vars);
 
+	// Free outdated pointers
 	for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) {
 		delete *i;
 	}
-	_oldScripts.clear();
-	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i > 0; i--) {
-		uint16 id;
-		uint32 pos, delay;
-		ser.syncAsUint32LE(pos);
-		ser.syncAsUint16LE(id);
-		ser.syncAsUint32LE(delay);
-		OldScript *oTmp = new OldScript(id, getResource(ID_SCRP, id));
-		oTmp->_currDelay = delay;
-		oTmp->_stream->seek(pos, SEEK_SET);
-		_oldScripts.push_back(oTmp);
-	}
-	_queuedScripts.clear();
-	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i > 0; i--) {
-		QueuedScript qTmp;
-		ser.syncAsUint32LE(qTmp._baseTime);
-		qTmp._baseTime += timeDelta;
-		ser.syncAsUint32LE(qTmp._duration);
-		ser.syncAsUint32LE(qTmp._count);
-		if(qTmp._count != 0) {
-			assert(qTmp._count != 0);
-		}
-		ser.syncAsUint16LE(qTmp._scriptId);
-		_queuedScripts.push_back(qTmp);
-	}
+
+	syncList<OldScript *> (ser, _oldScripts);
+	syncArray<QueuedScript> (ser, _queuedScripts);
+
 	ser.syncAsSint16LE(_lastMousePos.x);
 	ser.syncAsSint16LE(_lastMousePos.y);
+	g_system->warpMouse(_lastMousePos.x, _lastMousePos.y);
 	ser.syncAsByte(_mouseEnabled);
 	ser.syncAsByte(_mouseVisible);
 	ser.syncAsUint16LE(_mouseSpriteId);
 
+	// Free outdated pointers
 	for (Common::List<Pipe *>::iterator i = _pipes.begin(); i != _pipes.end(); i++) {
 		delete *i;
 	}
-	_pipes.clear();
 	for (Common::Array<Common::SeekableReadStream *>::iterator i = _pipeStreams.begin(); i != _pipeStreams.end(); i++) {
 		delete *i;
 	}
-	_pipeStreams.clear();
 
-	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i > 0; i--) {
-		uint16 id;
-		uint32 offset;
-		ser.syncAsUint16LE(id);
-		ser.syncAsUint32LE(offset);
-		Pipe *pipe;
-		Common::SeekableReadStream *stream;
-		if (getGameType() == GType_ComposerV1) {
-			stream = getResource(ID_PIPE, id);
-			pipe = new OldPipe(stream, id);
-		} else {
-			stream = getResource(ID_ANIM, id);
-			pipe = new Pipe(stream, id);
-		}
-		_pipes.push_front(pipe);
-		_pipeStreams.push_back(stream);
-		pipe->setOffset(offset);
-		ser.syncAsUint32LE(tmp);
-		for (uint32 j = tmp; j > 0; j--) {
-			uint32 tag;
-			ser.syncAsUint32LE(tag);
-			ser.syncAsUint32LE(tmp);
-			for (uint32 k = tmp; k > 0; k--) {
-				ser.syncAsUint16LE(id);
-				if (pipe->hasResource(tag, id))
-					pipe->getResource(tag, id, true);
-			}
-		}
-	}
+	_pipeStreams.clear();
+	syncListReverse<Pipe *> (ser, _pipes);
 
+	// Free outdated pointers
 	for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) {
 		delete *i;
 	}
-	_anims.clear();
-	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i > 0; i--) {
-		uint16 animId, x, y;
-		uint32 offset, state, param;
-		int32 size;
-		ser.syncAsUint16LE(animId);
-		ser.syncAsUint32LE(offset);
-		ser.syncAsUint16LE(x);
-		ser.syncAsUint16LE(y);
-		ser.syncAsUint32LE(state);
-		ser.syncAsUint32LE(param);
-		ser.syncAsUint32LE(size);
-		Common::SeekableReadStream *stream = NULL;
-
-		//TODO: extract following out into "loadAnim"
-		// First, check the existing pipes.
-		for (Common::List<Pipe *>::iterator j = _pipes.begin(); j != _pipes.end(); j++) {
-			Pipe *pipe = *j;
-			if (!pipe->hasResource(ID_ANIM, animId))
-				continue;
-			stream = pipe->getResource(ID_ANIM, animId, false);
-			if (stream->size() >= size) break;
-			stream = NULL;
-		}
-		// If we didn't find it, try the libraries.
-		if (!stream) {
-			Common::List<Library>::iterator j;
-			for (j = _libraries.begin(); j != _libraries.end(); j++) {
-				if (!hasResource(ID_ANIM, animId)) continue;
-				stream = getResource(ID_ANIM, animId);
-				if (stream->size() >= size) break;
-				stream = NULL;
-			}
-			if (!stream) {
-				warning("ignoring attempt to play invalid anim %d", animId);
-				continue;
-			}
-
-			uint32 type = j->_archive->getResourceFlags(ID_ANIM, animId);
 
-			// If the resource is a pipe itself, then load the pipe
-			// and then fish the requested animation out of it.
-			if (type != 1) {
-				_pipeStreams.push_back(stream);
-				Pipe *newPipe = new Pipe(stream, animId);
-				_pipes.push_front(newPipe);
-				newPipe->nextFrame();
-				stream = newPipe->getResource(ID_ANIM, animId, false);
-			}
-		}
+	syncList<Animation *> (ser, _anims);
+	syncList<Sprite> (ser, _sprites);
 
-		Animation *anim = new Animation(stream, animId, Common::Point(x, y), param);
-		anim->_offset = offset;
-		anim->_state = state;
-		uint32 tmp2;
-		ser.syncAsUint32LE(tmp2);
-		for (uint32 j = 0; j < tmp2; j++) {
-			ser.syncAsUint32LE(anim->_entries[j].state);
-			ser.syncAsUint16LE(anim->_entries[j].counter);
-			ser.syncAsUint16LE(anim->_entries[j].prevValue);
-		}
-		_anims.push_back(anim);
-	}
-	_sprites.clear();
-	ser.syncAsUint32LE(tmp);
-	for (uint32 i = tmp; i > 0; i--) {
-		Sprite sprite;
-		ser.syncAsUint16LE(sprite._id);
-		ser.syncAsUint16LE(sprite._animId);
-		ser.syncAsSint16LE(sprite._pos.x);
-		ser.syncAsSint16LE(sprite._pos.y);
-		ser.syncAsUint16LE(sprite._surface.w);
-		ser.syncAsUint16LE(sprite._surface.h);
-		ser.syncAsUint16LE(sprite._surface.pitch);
-		ser.syncAsUint16LE(sprite._zorder);
-		sprite._surface.pixels = malloc(sprite._surface.h * sprite._surface.pitch);
-		byte *dest = static_cast<byte *>(sprite._surface.pixels);
-		for (uint16 y = 0; y < sprite._surface.h; y++) {
-			for (uint16 x = 0; x < sprite._surface.w; x++) {
-				ser.syncAsByte(dest[x]);
-			}
-			dest += sprite._surface.pitch;
-		}
-		_sprites.push_back(sprite);
-	}
 	_dirtyRects.clear();
+
+	// Redraw the whole screen
 	_dirtyRects.push_back(Common::Rect(0, 0, 640, 480));
 	byte palbuf[256 * 3];
 	ser.syncBytes(palbuf, 256 * 3);
@@ -274,6 +360,7 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	_mixer->stopAll();
 	_audioStream = NULL;
 
+	// Restore the buffered audio
 	ser.syncAsSint16LE(_currSoundPriority);
 	int32 numSamples;
 	ser.syncAsSint32LE(numSamples);
@@ -291,6 +378,7 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc) {
 	Common::String filename = makeSaveGameName(slot);
 	Common::OutSaveFile *out;
+	vm = this;
 	if (!(out = _saveFileMan->openForSaving(filename)))
 		return Common::kWritingFailed;
 
@@ -304,135 +392,26 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	ser.syncAsUint32LE(tmp);
 	ser.syncAsUint32LE(_currentTime);
 	ser.syncAsUint32LE(_lastTime);
-	tmp = _libraries.size();
-	ser.syncAsUint32LE(tmp);
-	for (Common::List<Library>::const_iterator i = _libraries.reverse_begin(); i != _libraries.end(); i--) {
-		uint16 tmp16 = (*i)._id;
-		Common::String tmps = (*i)._group;
-		ser.syncAsUint16LE(tmp16);
-		ser.syncString(tmps);
-	}
+
+	syncListReverse<Library> (ser, _libraries);
 	ser.syncString(_bookGroup);
-	tmp = _pendingPageChanges.size();
-	ser.syncAsUint32LE(tmp);
-	for (Common::Array<PendingPageChange>::const_iterator i = _pendingPageChanges.begin(); i != _pendingPageChanges.end(); i++) {
-		uint16 tmp16 = (*i)._pageId;
-		bool tmpb = (*i)._remove;
-		ser.syncAsUint16LE(tmp16);
-		ser.syncAsByte(tmpb);
-	}
-	tmp = _stack.size();
-	ser.syncAsUint32LE(tmp);
-	for (Common::Array<uint16>::const_iterator i = _stack.begin(); i != _stack.end(); i++) {
-		uint16 tmp16 = (*i);
-		ser.syncAsUint16LE(tmp16);
-	}
-	tmp = _vars.size();
-	ser.syncAsUint32LE(tmp);
-	for (Common::Array<uint16>::const_iterator i = _vars.begin(); i != _vars.end(); i++) {
-		uint16 tmp16 = (*i);
-		ser.syncAsUint16LE(tmp16);
-	}
-	tmp = _oldScripts.size();
-	ser.syncAsUint32LE(tmp);
-	for (Common::List<OldScript *>::const_iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) {
-		tmp = (*i)->_stream->pos();
-		ser.syncAsUint32LE(tmp);
-		uint16 tmp16 = (*i)->_id;
-		tmp = (*i)->_currDelay;
-		ser.syncAsUint16LE(tmp16);
-		ser.syncAsUint32LE(tmp);
-	}
-	tmp = _queuedScripts.size();
-	ser.syncAsUint32LE(tmp);
-	for (Common::Array<QueuedScript>::const_iterator i = _queuedScripts.begin(); i != _queuedScripts.end(); i++) {
-		tmp = (*i)._baseTime;
-		ser.syncAsUint32LE(tmp);
-		tmp = (*i)._duration;
-		ser.syncAsUint32LE(tmp);
-		tmp = (*i)._count;
-		if(tmp != 0) {
-			assert(tmp != 0);
-		}
-		uint16 tmp16 = (*i)._scriptId;
-		ser.syncAsUint32LE(tmp);
-		ser.syncAsUint16LE(tmp16);
-	}
+
+	syncArray<PendingPageChange> (ser, _pendingPageChanges);
+	syncArray<uint16> (ser, _stack);
+	syncArray<uint16> (ser, _vars);
+	syncList<OldScript *> (ser, _oldScripts);
+	syncArray<QueuedScript> (ser, _queuedScripts);
+
 	ser.syncAsSint16LE(_lastMousePos.x);
 	ser.syncAsSint16LE(_lastMousePos.y);
 	ser.syncAsByte(_mouseEnabled);
 	ser.syncAsByte(_mouseVisible);
 	ser.syncAsUint16LE(_mouseSpriteId);
 
-	tmp = _pipes.size();
-	ser.syncAsUint32LE(tmp);
-	for (Common::List<Pipe *>::const_iterator i = _pipes.reverse_begin(); i != _pipes.end(); i--) {
-		uint16 tmp16 = (*i)->getPipeId();
-		tmp = (*i)->getOffset();
-		ser.syncAsUint16LE(tmp16);
-		ser.syncAsUint32LE(tmp);
-		tmp = (*i)->_bufferedResources.size();
-		ser.syncAsUint32LE(tmp);
-		for (Pipe::DelMap::const_iterator j = (*i)->_bufferedResources.begin(); j != (*i)->_bufferedResources.end(); j++) {
-			tmp = (*j)._key;
-			ser.syncAsUint32LE(tmp);
-			tmp = (*j)._value.size();
-			ser.syncAsUint32LE(tmp);
-			for (Common::List<uint16>::const_iterator k = (*j)._value.begin(); k != (*j)._value.end(); k++) {
-				tmp16 = (*k);
-				ser.syncAsUint16LE(tmp16);
-			}
-		}
-	}
+	syncListReverse<Pipe *> (ser, _pipes);
+	syncList<Animation *> (ser, _anims);
+	syncList<Sprite> (ser, _sprites);
 
-	tmp = _anims.size();
-	ser.syncAsUint32LE(tmp);
-	for (Common::List<Animation *>::const_iterator i = _anims.begin(); i != _anims.end(); i++) {
-		uint16 tmp16 = (*i)->_id;
-		tmp = (*i)->_offset;
-		ser.syncAsUint16LE(tmp16);
-		ser.syncAsUint32LE(tmp);
-		tmp16 = (*i)->_basePos.x;
-		ser.syncAsUint16LE(tmp16);
-		tmp16 = (*i)->_basePos.y;
-		ser.syncAsUint16LE(tmp16);
-		tmp = (*i)->_state;
-		ser.syncAsUint32LE(tmp);
-		tmp = (*i)->_eventParam;
-		ser.syncAsUint32LE(tmp);
-		tmp = (*i)->_size;
-		ser.syncAsUint32LE(tmp);
-		tmp = (*i)->_entries.size();
-		ser.syncAsUint32LE(tmp);
-		for (Common::Array<AnimationEntry>::const_iterator j = (*i)->_entries.begin(); j != (*i)->_entries.end(); j++) {
-			tmp = (*j).state;
-			tmp16 = (*j).counter;
-			ser.syncAsUint32LE(tmp);
-			ser.syncAsUint16LE(tmp16);
-			tmp16 = (*j).prevValue;
-			ser.syncAsUint16LE(tmp16);
-		}
-	}
-	tmp = _sprites.size();
-	ser.syncAsUint32LE(tmp);
-	for (Common::List<Sprite>::const_iterator i = _sprites.begin(); i != _sprites.end(); i++) {
-		Sprite sprite(*i);
-		ser.syncAsUint16LE(sprite._id);
-		ser.syncAsUint16LE(sprite._animId);
-		ser.syncAsSint16LE(sprite._pos.x);
-		ser.syncAsSint16LE(sprite._pos.y);
-		ser.syncAsUint16LE(sprite._surface.w);
-		ser.syncAsUint16LE(sprite._surface.h);
-		ser.syncAsUint16LE(sprite._surface.pitch);
-		ser.syncAsUint16LE(sprite._zorder);
-		byte *src = static_cast<byte *>((*i)._surface.pixels);
-		for (uint16 y = 0; y < sprite._surface.h; y++) {
-			for (uint x = 0; x < sprite._surface.w; x++) {
-				ser.syncAsByte(src[x]);
-			}
-			src += (*i)._surface.pitch;
-		}
-	}
 	byte paletteBuffer[256 * 3];
 	_system->getPaletteManager()->grabPalette(paletteBuffer, 0, 256);
 	ser.syncBytes(paletteBuffer, 256 * 3);
@@ -448,4 +427,4 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	out->finalize();
 	return Common::kNoError;
 }
-}
+} // End of namespace Composer


Commit: 69a6a200a21083b1ee7970d82fad0384a64bdcef
    https://github.com/scummvm/scummvm/commit/69a6a200a21083b1ee7970d82fad0384a64bdcef
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:11:51+02:00

Commit Message:
COMPOSER: Fixed some scope issues

Changed paths:
    engines/composer/composer.h
    engines/composer/saveload.cpp



diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index e968242..5b44bf3 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -150,11 +150,17 @@ struct OldScript {
 };
 
 class ComposerEngine : public Engine {
-	template <typename T>
-	friend void sync(Common::Serializer &ser, T &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion);
 protected:
 	Common::Error run();
 
+	template <typename T>
+	void syncArray(Common::Serializer &ser, Common::Array<T> &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion);
+	template <typename T>
+	void syncList(Common::Serializer &ser, Common::List<T> &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion);
+	template <typename T>
+	void syncListReverse(Common::Serializer &ser, Common::List<T> &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion);
+	template <typename T>
+	void sync(Common::Serializer &ser, T &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion);
 	bool canLoadGameStateCurrently() { return true; }
 	Common::Error loadGameState(int slot);
 	bool canSaveGameStateCurrently() { return true; }
@@ -183,7 +189,7 @@ private:
 	Audio::QueuingAudioStream *_audioStream;
 	uint16 _currSoundPriority;
 
-	uint32 _currentTime, _lastTime;
+	uint32 _currentTime, _lastTime, _timeDelta;
 
 	bool _needsUpdate;
 	Common::Array<Common::Rect> _dirtyRects;
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index 7bbdcd3..3d62641 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -34,13 +34,9 @@
 #include "composer/graphics.h"
 
 namespace Composer {
-ComposerEngine *vm = NULL;
-uint32 timeDelta; 
 
 template <class T>
-void sync(Common::Serializer &ser, T &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion);
-template <class T>
-void syncArray(Common::Serializer &ser, Common::Array<T> &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion) {
+void ComposerEngine::syncArray(Common::Serializer &ser, Common::Array<T> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	if (ser.isSaving()) {
 		uint32 size = data.size();
 		ser.syncAsUint32LE(size, minVersion, maxVersion);
@@ -59,7 +55,7 @@ void syncArray(Common::Serializer &ser, Common::Array<T> &data, Common::Serializ
 	}
 }
 template <class T>
-void syncList(Common::Serializer &ser, Common::List<T> &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion) {
+void ComposerEngine::syncList(Common::Serializer &ser, Common::List<T> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	if (ser.isSaving()) {
 		uint32 size = data.size();
 		ser.syncAsUint32LE(size, minVersion, maxVersion);
@@ -78,7 +74,7 @@ void syncList(Common::Serializer &ser, Common::List<T> &data, Common::Serializer
 	}
 }
 template <class T>
-void syncListReverse(Common::Serializer &ser, Common::List<T> &data, Common::Serializer::Version minVersion = 0, Common::Serializer::Version maxVersion = Common::Serializer::kLastVersion) {
+void ComposerEngine::syncListReverse(Common::Serializer &ser, Common::List<T> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	if (ser.isSaving()) {
 		uint32 size = data.size();
 		ser.syncAsUint32LE(size, minVersion, maxVersion);
@@ -97,28 +93,27 @@ void syncListReverse(Common::Serializer &ser, Common::List<T> &data, Common::Ser
 	}
 }
 template<>
-void sync<uint16> (Common::Serializer &ser, uint16 &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<uint16> (Common::Serializer &ser, uint16 &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	ser.syncAsUint16LE(data, minVersion, maxVersion);
 }
 template<>
-void sync<uint32> (Common::Serializer &ser, uint32 &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<uint32> (Common::Serializer &ser, uint32 &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	ser.syncAsUint32LE(data, minVersion, maxVersion);
 }
 template<>
-void sync<Library> (Common::Serializer &ser, Library &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<Library> (Common::Serializer &ser, Library &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	if (ser.isSaving()) {
 		ser.syncAsUint16LE(data._id, minVersion, maxVersion);
 		ser.syncString(data._group, minVersion, maxVersion);
 	} else {
 		uint16 id;
-		ComposerEngine *vm = (ComposerEngine *)g_engine;
 		ser.syncAsUint16LE(id, minVersion, maxVersion);
-		ser.syncString(vm->_bookGroup, minVersion, maxVersion);
-		vm->loadLibrary(id);
+		ser.syncString(_bookGroup, minVersion, maxVersion);
+		loadLibrary(id);
 	}
 }
 template <>
-void syncListReverse<Library> (Common::Serializer &ser, Common::List<Library> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::syncListReverse<Library> (Common::Serializer &ser, Common::List<Library> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	if (ser.isSaving()) {
 		uint32 size = data.size();
 		ser.syncAsUint32LE(size, minVersion, maxVersion);
@@ -135,12 +130,12 @@ void syncListReverse<Library> (Common::Serializer &ser, Common::List<Library> &d
 	}
 }
 template<>
-void sync<PendingPageChange> (Common::Serializer &ser, PendingPageChange &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<PendingPageChange> (Common::Serializer &ser, PendingPageChange &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	ser.syncAsUint16LE(data._pageId, minVersion, maxVersion);
 	ser.syncAsByte(data._remove, minVersion, maxVersion);
 }
 template<>
-void sync<OldScript *> (Common::Serializer &ser, OldScript *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<OldScript *> (Common::Serializer &ser, OldScript *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	uint16 id;
 	uint32 pos, delay;
 	if (ser.isSaving()) {
@@ -152,21 +147,21 @@ void sync<OldScript *> (Common::Serializer &ser, OldScript *&data, Common::Seria
 	ser.syncAsUint16LE(id);
 	ser.syncAsUint32LE(delay);
 	if (ser.isLoading()) {
-		data = new OldScript(id, vm->getResource(ID_SCRP, id));
+		data = new OldScript(id, getResource(ID_SCRP, id));
 		data->_currDelay = delay;
 		data->_stream->seek(pos, SEEK_SET);
 	}
 }
 template<>
-void sync<QueuedScript> (Common::Serializer &ser, QueuedScript &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<QueuedScript> (Common::Serializer &ser, QueuedScript &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	ser.syncAsUint32LE(data._baseTime);
 	ser.syncAsUint32LE(data._duration);	
 	ser.syncAsUint32LE(data._count);
 	ser.syncAsUint16LE(data._scriptId);
-	if (ser.isLoading()) data._baseTime += timeDelta;
+	if (ser.isLoading()) data._baseTime += _timeDelta;
 }
 template<>
-void sync<Pipe *> (Common::Serializer &ser, Pipe *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<Pipe *> (Common::Serializer &ser, Pipe *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	uint16 id;
 	uint32 offset, tmp;
 	if (ser.isSaving()) {
@@ -180,14 +175,14 @@ void sync<Pipe *> (Common::Serializer &ser, Pipe *&data, Common::Serializer::Ver
 	if (ser.isLoading()) {
 		// On load, get and initialize streams
 		Common::SeekableReadStream *stream;
-		if (vm->getGameType() == GType_ComposerV1) {
-			stream = vm->getResource(ID_PIPE, id);
+		if (getGameType() == GType_ComposerV1) {
+			stream = getResource(ID_PIPE, id);
 			data = new OldPipe(stream, id);
 		} else {
-			stream = vm->getResource(ID_ANIM, id);
+			stream = getResource(ID_ANIM, id);
 			data = new Pipe(stream, id);
 		}
-		vm->_pipeStreams.push_back(stream);
+		_pipeStreams.push_back(stream);
 		data->setOffset(offset);
 		ser.syncAsUint32LE(tmp);
 		for (uint32 j = tmp; j > 0; j--) {
@@ -210,13 +205,13 @@ void sync<Pipe *> (Common::Serializer &ser, Pipe *&data, Common::Serializer::Ver
 	}
 }
 template<>
-void sync<AnimationEntry> (Common::Serializer &ser, AnimationEntry &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<AnimationEntry> (Common::Serializer &ser, AnimationEntry &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	ser.syncAsUint32LE(data.state);
 	ser.syncAsUint16LE(data.counter);
 	ser.syncAsUint16LE(data.prevValue);
 }
 template<>
-void sync<Animation *> (Common::Serializer &ser, Animation *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<Animation *> (Common::Serializer &ser, Animation *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	uint16 animId, x, y;
 	uint32 offset, state, param;
 	int32 size;
@@ -238,7 +233,7 @@ void sync<Animation *> (Common::Serializer &ser, Animation *&data, Common::Seria
 	ser.syncAsUint32LE(size);
 	if (ser.isLoading()) {
 		// On load, get and initialize streams
-		vm->loadAnimation(data, animId, x, y, param, size);
+		loadAnimation(data, animId, x, y, param, size);
 		data->_offset = offset;
 		data->_state = state;
 		uint32 tmp;
@@ -251,7 +246,7 @@ void sync<Animation *> (Common::Serializer &ser, Animation *&data, Common::Seria
 	}
 }
 template<>
-void sync<Sprite> (Common::Serializer &ser, Sprite &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<Sprite> (Common::Serializer &ser, Sprite &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 		ser.syncAsUint16LE(data._id);
 		ser.syncAsUint16LE(data._animId);
 		ser.syncAsSint16LE(data._pos.x);
@@ -276,7 +271,6 @@ Common::String ComposerEngine::makeSaveGameName(int slot) {
 }
 
 Common::Error ComposerEngine::loadGameState(int slot) {
-	vm = this;
 	Common::String filename = makeSaveGameName(slot);
 	Common::InSaveFile *in;
 	if (!(in = _saveFileMan->openForLoading(filename)))
@@ -295,10 +289,10 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	ser.syncAsUint32LE(tmp);
 	_rnd->setSeed(tmp);
 	ser.syncAsUint32LE(_currentTime);
-	timeDelta = _system->getMillis() - _currentTime;
-	_currentTime += timeDelta;
+	_timeDelta = _system->getMillis() - _currentTime;
+	_currentTime += _timeDelta;
 	ser.syncAsUint32LE(_lastTime);
-	_lastTime += timeDelta;
+	_lastTime += _timeDelta;
 
 	// Unload all Libraries
 	Common::Array<uint16> libIds;
@@ -378,7 +372,6 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc) {
 	Common::String filename = makeSaveGameName(slot);
 	Common::OutSaveFile *out;
-	vm = this;
 	if (!(out = _saveFileMan->openForSaving(filename)))
 		return Common::kWritingFailed;
 


Commit: 582006d1cf8cca321ffcd02bba86f828156c088a
    https://github.com/scummvm/scummvm/commit/582006d1cf8cca321ffcd02bba86f828156c088a
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:12:04+02:00

Commit Message:
COMPOSER: Added loading from launcher support

Changed paths:
    engines/composer/composer.cpp
    engines/composer/detection.cpp



diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp
index e9a91b1..e5b4236 100644
--- a/engines/composer/composer.cpp
+++ b/engines/composer/composer.cpp
@@ -169,7 +169,10 @@ Common::Error ComposerEngine::run() {
 		} else if (_needsUpdate) {
 			redraw();
 		}
-
+		if (ConfMan.hasKey("save_slot")) {
+			loadGameState(ConfMan.getInt("save_slot"));
+			ConfMan.removeKey("save_slot", Common::ConfigManager::kTransientDomain);
+		}
 		while (_eventMan->pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_LBUTTONDOWN:
diff --git a/engines/composer/detection.cpp b/engines/composer/detection.cpp
index bd0c432..8de3b33 100644
--- a/engines/composer/detection.cpp
+++ b/engines/composer/detection.cpp
@@ -464,7 +464,7 @@ bool ComposerMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD
 }
 
 bool ComposerMetaEngine::hasFeature(MetaEngineFeature f) const {
-	return (f == kSupportsListSaves);
+	return ((f == kSupportsListSaves) || (f == kSupportsLoadingDuringStartup));
 }
 
 Common::String getSaveName(Common::InSaveFile *in) {


Commit: 483cad039efec6ba28962e0a93e1e6a417487bf4
    https://github.com/scummvm/scummvm/commit/483cad039efec6ba28962e0a93e1e6a417487bf4
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:12:19+02:00

Commit Message:
COMPOSER: Enable autosaving.

Changed paths:
    engines/composer/composer.cpp
    engines/composer/composer.h
    engines/composer/saveload.cpp



diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp
index e5b4236..f3e5958 100644
--- a/engines/composer/composer.cpp
+++ b/engines/composer/composer.cpp
@@ -120,6 +120,7 @@ Common::Error ComposerEngine::run() {
 	else
 		warning("FPS in book.ini is zero. Defaulting to 8...");
 	uint32 lastDrawTime = 0;
+	_lastSaveTime = _system->getMillis();
 
 	while (!shouldQuit()) {
 		for (uint i = 0; i < _pendingPageChanges.size(); i++) {
@@ -173,6 +174,8 @@ Common::Error ComposerEngine::run() {
 			loadGameState(ConfMan.getInt("save_slot"));
 			ConfMan.removeKey("save_slot", Common::ConfigManager::kTransientDomain);
 		}
+		if (shouldPerformAutoSave(_lastSaveTime))
+			saveGameState(0, "Autosave");
 		while (_eventMan->pollEvent(event)) {
 			switch (event.type) {
 			case Common::EVENT_LBUTTONDOWN:
diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index 5b44bf3..9ae1c1d 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -189,7 +189,7 @@ private:
 	Audio::QueuingAudioStream *_audioStream;
 	uint16 _currSoundPriority;
 
-	uint32 _currentTime, _lastTime, _timeDelta;
+	uint32 _currentTime, _lastTime, _timeDelta, _lastSaveTime;
 
 	bool _needsUpdate;
 	Common::Array<Common::Rect> _dirtyRects;
diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index 3d62641..f0cf421 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -372,6 +372,7 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc) {
 	Common::String filename = makeSaveGameName(slot);
 	Common::OutSaveFile *out;
+	_lastSaveTime = _system->getMillis();
 	if (!(out = _saveFileMan->openForSaving(filename)))
 		return Common::kWritingFailed;
 


Commit: a9441186b759ceb6455ed9168cf6037a7538dbb9
    https://github.com/scummvm/scummvm/commit/a9441186b759ceb6455ed9168cf6037a7538dbb9
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:12:34+02:00

Commit Message:
COMPOSER: Better spacing of autosaves

Changed paths:
    engines/composer/saveload.cpp



diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index f0cf421..919fd0d 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -366,6 +366,10 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	if (!_mixer->isSoundHandleActive(_soundHandle))
 		_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _audioStream);
 
+
+	// Reset autosave duration on load
+	_lastSaveTime = _system->getMillis();
+
 	return Common::kNoError;
 }
 


Commit: 5649ce55fc867d711ae3fb5dfd26f3be879995b0
    https://github.com/scummvm/scummvm/commit/5649ce55fc867d711ae3fb5dfd26f3be879995b0
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:12:45+02:00

Commit Message:
COMPOSER: Various formatting fixes.

Changed paths:
    engines/composer/saveload.cpp



diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index 919fd0d..55544d7 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -35,7 +35,7 @@
 
 namespace Composer {
 
-template <class T>
+template<class T>
 void ComposerEngine::syncArray(Common::Serializer &ser, Common::Array<T> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	if (ser.isSaving()) {
 		uint32 size = data.size();
@@ -54,7 +54,7 @@ void ComposerEngine::syncArray(Common::Serializer &ser, Common::Array<T> &data,
 		}
 	}
 }
-template <class T>
+template<class T>
 void ComposerEngine::syncList(Common::Serializer &ser, Common::List<T> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	if (ser.isSaving()) {
 		uint32 size = data.size();
@@ -73,7 +73,7 @@ void ComposerEngine::syncList(Common::Serializer &ser, Common::List<T> &data, Co
 		}
 	}
 }
-template <class T>
+template<class T>
 void ComposerEngine::syncListReverse(Common::Serializer &ser, Common::List<T> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	if (ser.isSaving()) {
 		uint32 size = data.size();
@@ -93,15 +93,15 @@ void ComposerEngine::syncListReverse(Common::Serializer &ser, Common::List<T> &d
 	}
 }
 template<>
-void ComposerEngine::sync<uint16> (Common::Serializer &ser, uint16 &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<uint16>(Common::Serializer &ser, uint16 &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	ser.syncAsUint16LE(data, minVersion, maxVersion);
 }
 template<>
-void ComposerEngine::sync<uint32> (Common::Serializer &ser, uint32 &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<uint32>(Common::Serializer &ser, uint32 &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	ser.syncAsUint32LE(data, minVersion, maxVersion);
 }
 template<>
-void ComposerEngine::sync<Library> (Common::Serializer &ser, Library &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<Library>(Common::Serializer &ser, Library &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	if (ser.isSaving()) {
 		ser.syncAsUint16LE(data._id, minVersion, maxVersion);
 		ser.syncString(data._group, minVersion, maxVersion);
@@ -112,8 +112,8 @@ void ComposerEngine::sync<Library> (Common::Serializer &ser, Library &data, Comm
 		loadLibrary(id);
 	}
 }
-template <>
-void ComposerEngine::syncListReverse<Library> (Common::Serializer &ser, Common::List<Library> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+template<>
+void ComposerEngine::syncListReverse<Library>(Common::Serializer &ser, Common::List<Library> &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	if (ser.isSaving()) {
 		uint32 size = data.size();
 		ser.syncAsUint32LE(size, minVersion, maxVersion);
@@ -130,12 +130,12 @@ void ComposerEngine::syncListReverse<Library> (Common::Serializer &ser, Common::
 	}
 }
 template<>
-void ComposerEngine::sync<PendingPageChange> (Common::Serializer &ser, PendingPageChange &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<PendingPageChange>(Common::Serializer &ser, PendingPageChange &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	ser.syncAsUint16LE(data._pageId, minVersion, maxVersion);
 	ser.syncAsByte(data._remove, minVersion, maxVersion);
 }
 template<>
-void ComposerEngine::sync<OldScript *> (Common::Serializer &ser, OldScript *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<OldScript *>(Common::Serializer &ser, OldScript *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	uint16 id;
 	uint32 pos, delay;
 	if (ser.isSaving()) {
@@ -153,7 +153,7 @@ void ComposerEngine::sync<OldScript *> (Common::Serializer &ser, OldScript *&dat
 	}
 }
 template<>
-void ComposerEngine::sync<QueuedScript> (Common::Serializer &ser, QueuedScript &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<QueuedScript>(Common::Serializer &ser, QueuedScript &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	ser.syncAsUint32LE(data._baseTime);
 	ser.syncAsUint32LE(data._duration);	
 	ser.syncAsUint32LE(data._count);
@@ -161,7 +161,7 @@ void ComposerEngine::sync<QueuedScript> (Common::Serializer &ser, QueuedScript &
 	if (ser.isLoading()) data._baseTime += _timeDelta;
 }
 template<>
-void ComposerEngine::sync<Pipe *> (Common::Serializer &ser, Pipe *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<Pipe *>(Common::Serializer &ser, Pipe *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	uint16 id;
 	uint32 offset, tmp;
 	if (ser.isSaving()) {
@@ -200,18 +200,18 @@ void ComposerEngine::sync<Pipe *> (Common::Serializer &ser, Pipe *&data, Common:
 		for (Pipe::DelMap::iterator i = data->_bufferedResources.begin(); i != data->_bufferedResources.end(); i++) {
 			uint32 key = (*i)._key;
 			ser.syncAsUint32LE(key);
-			syncList<uint16> (ser, (*i)._value, minVersion, maxVersion);
+			syncList<uint16>(ser, (*i)._value, minVersion, maxVersion);
 		}
 	}
 }
 template<>
-void ComposerEngine::sync<AnimationEntry> (Common::Serializer &ser, AnimationEntry &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<AnimationEntry>(Common::Serializer &ser, AnimationEntry &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	ser.syncAsUint32LE(data.state);
 	ser.syncAsUint16LE(data.counter);
 	ser.syncAsUint16LE(data.prevValue);
 }
 template<>
-void ComposerEngine::sync<Animation *> (Common::Serializer &ser, Animation *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<Animation *>(Common::Serializer &ser, Animation *&data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 	uint16 animId, x, y;
 	uint32 offset, state, param;
 	int32 size;
@@ -239,14 +239,14 @@ void ComposerEngine::sync<Animation *> (Common::Serializer &ser, Animation *&dat
 		uint32 tmp;
 		ser.syncAsUint32LE(tmp);
 		for (uint32 i = 0; i < tmp; i++) {
-			sync<AnimationEntry> (ser, data->_entries[i], minVersion, maxVersion);
+			sync<AnimationEntry>(ser, data->_entries[i], minVersion, maxVersion);
 		}
 	} else {
-		syncArray<AnimationEntry> (ser, data->_entries, minVersion, maxVersion);
+		syncArray<AnimationEntry>(ser, data->_entries, minVersion, maxVersion);
 	}
 }
 template<>
-void ComposerEngine::sync<Sprite> (Common::Serializer &ser, Sprite &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
+void ComposerEngine::sync<Sprite>(Common::Serializer &ser, Sprite &data, Common::Serializer::Version minVersion, Common::Serializer::Version maxVersion) {
 		ser.syncAsUint16LE(data._id);
 		ser.syncAsUint16LE(data._animId);
 		ser.syncAsSint16LE(data._pos.x);
@@ -301,20 +301,20 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	for (uint32 i = 0; i < libIds.size(); i++) 
 		unloadLibrary(libIds[i]);
 
-	syncListReverse<Library> (ser, _libraries);
+	syncListReverse<Library>(ser, _libraries);
 	ser.syncString(_bookGroup);
 
-	syncArray<PendingPageChange> (ser, _pendingPageChanges);
-	syncArray<uint16> (ser, _stack);
-	syncArray<uint16> (ser, _vars);
+	syncArray<PendingPageChange>(ser, _pendingPageChanges);
+	syncArray<uint16>(ser, _stack);
+	syncArray<uint16>(ser, _vars);
 
 	// Free outdated pointers
 	for (Common::List<OldScript *>::iterator i = _oldScripts.begin(); i != _oldScripts.end(); i++) {
 		delete *i;
 	}
 
-	syncList<OldScript *> (ser, _oldScripts);
-	syncArray<QueuedScript> (ser, _queuedScripts);
+	syncList<OldScript *>(ser, _oldScripts);
+	syncArray<QueuedScript>(ser, _queuedScripts);
 
 	ser.syncAsSint16LE(_lastMousePos.x);
 	ser.syncAsSint16LE(_lastMousePos.y);
@@ -332,15 +332,15 @@ Common::Error ComposerEngine::loadGameState(int slot) {
 	}
 
 	_pipeStreams.clear();
-	syncListReverse<Pipe *> (ser, _pipes);
+	syncListReverse<Pipe *>(ser, _pipes);
 
 	// Free outdated pointers
 	for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) {
 		delete *i;
 	}
 
-	syncList<Animation *> (ser, _anims);
-	syncList<Sprite> (ser, _sprites);
+	syncList<Animation *>(ser, _anims);
+	syncList<Sprite>(ser, _sprites);
 
 	_dirtyRects.clear();
 
@@ -391,14 +391,14 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	ser.syncAsUint32LE(_currentTime);
 	ser.syncAsUint32LE(_lastTime);
 
-	syncListReverse<Library> (ser, _libraries);
+	syncListReverse<Library>(ser, _libraries);
 	ser.syncString(_bookGroup);
 
-	syncArray<PendingPageChange> (ser, _pendingPageChanges);
-	syncArray<uint16> (ser, _stack);
-	syncArray<uint16> (ser, _vars);
-	syncList<OldScript *> (ser, _oldScripts);
-	syncArray<QueuedScript> (ser, _queuedScripts);
+	syncArray<PendingPageChange>(ser, _pendingPageChanges);
+	syncArray<uint16>(ser, _stack);
+	syncArray<uint16>(ser, _vars);
+	syncList<OldScript *>(ser, _oldScripts);
+	syncArray<QueuedScript>(ser, _queuedScripts);
 
 	ser.syncAsSint16LE(_lastMousePos.x);
 	ser.syncAsSint16LE(_lastMousePos.y);
@@ -406,9 +406,9 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc
 	ser.syncAsByte(_mouseVisible);
 	ser.syncAsUint16LE(_mouseSpriteId);
 
-	syncListReverse<Pipe *> (ser, _pipes);
-	syncList<Animation *> (ser, _anims);
-	syncList<Sprite> (ser, _sprites);
+	syncListReverse<Pipe *>(ser, _pipes);
+	syncList<Animation *>(ser, _anims);
+	syncList<Sprite>(ser, _sprites);
 
 	byte paletteBuffer[256 * 3];
 	_system->getPaletteManager()->grabPalette(paletteBuffer, 0, 256);


Commit: 74c75e36cac3c8b93be94c41df72ad1ea1c295fa
    https://github.com/scummvm/scummvm/commit/74c75e36cac3c8b93be94c41df72ad1ea1c295fa
Author: upthorn (upthorn at gmail.com)
Date: 2016-10-18T02:12:56+02:00

Commit Message:
COMPOSER: Fix for issue when save_slot is in config.

Changed paths:
    engines/composer/composer.cpp



diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp
index f3e5958..061ec49 100644
--- a/engines/composer/composer.cpp
+++ b/engines/composer/composer.cpp
@@ -121,6 +121,8 @@ Common::Error ComposerEngine::run() {
 		warning("FPS in book.ini is zero. Defaulting to 8...");
 	uint32 lastDrawTime = 0;
 	_lastSaveTime = _system->getMillis();
+	
+	bool loadFromLauncher = ConfMan.hasKey("save_slot");
 
 	while (!shouldQuit()) {
 		for (uint i = 0; i < _pendingPageChanges.size(); i++) {
@@ -170,9 +172,9 @@ Common::Error ComposerEngine::run() {
 		} else if (_needsUpdate) {
 			redraw();
 		}
-		if (ConfMan.hasKey("save_slot")) {
+		if (loadFromLauncher) {
 			loadGameState(ConfMan.getInt("save_slot"));
-			ConfMan.removeKey("save_slot", Common::ConfigManager::kTransientDomain);
+			loadFromLauncher = false;
 		}
 		if (shouldPerformAutoSave(_lastSaveTime))
 			saveGameState(0, "Autosave");


Commit: a946e9eab95201d4ee3dd0d4eaeb3a088fb819fe
    https://github.com/scummvm/scummvm/commit/a946e9eab95201d4ee3dd0d4eaeb3a088fb819fe
Author: angstsmurf (ignalina at me.com)
Date: 2016-10-18T02:57:04+02:00

Commit Message:
COMPOSER: Include config manager header in composer.cpp again

It was removed in 253e18c

Changed paths:
    engines/composer/composer.cpp



diff --git a/engines/composer/composer.cpp b/engines/composer/composer.cpp
index 061ec49..13ba761 100644
--- a/engines/composer/composer.cpp
+++ b/engines/composer/composer.cpp
@@ -21,6 +21,7 @@
  */
 #include "common/scummsys.h"
 
+#include "common/config-manager.h"
 #include "common/events.h"
 #include "common/random.h"
 #include "common/keyboard.h"


Commit: 17f3626214d3244bfe07b4f263c99be2de07a289
    https://github.com/scummvm/scummvm/commit/17f3626214d3244bfe07b4f263c99be2de07a289
Author: angstsmurf (ignalina at me.com)
Date: 2016-10-18T02:58:19+02:00

Commit Message:
COMPOSER: Delete leftover git conflict marker

Changed paths:
    engines/composer/composer.h



diff --git a/engines/composer/composer.h b/engines/composer/composer.h
index 9ae1c1d..a4b421b 100644
--- a/engines/composer/composer.h
+++ b/engines/composer/composer.h
@@ -29,7 +29,6 @@
 #include "common/debug.h"
 #include "common/debug-channels.h"
 #include "common/error.h"
-=======
 #include "common/serializer.h"
 #include "common/textconsole.h"
 #include "common/rect.h"


Commit: c3994cd6ea1a616164869f54659339b462aafc2a
    https://github.com/scummvm/scummvm/commit/c3994cd6ea1a616164869f54659339b462aafc2a
Author: angstsmurf (ignalina at me.com)
Date: 2016-10-18T03:03:15+02:00

Commit Message:
COMPOSER: Add missing 'typename' prior to dependent type name

Changed paths:
    engines/composer/saveload.cpp



diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index 55544d7..ae55f90 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -40,7 +40,7 @@ void ComposerEngine::syncArray(Common::Serializer &ser, Common::Array<T> &data,
 	if (ser.isSaving()) {
 		uint32 size = data.size();
 		ser.syncAsUint32LE(size, minVersion, maxVersion);
-		for (Common::Array<T>::iterator i = data.begin(); i != data.end(); i++) {
+		for (typename Common::Array<T>::iterator i = data.begin(); i != data.end(); i++) {
 			sync<T>(ser, *i, minVersion, maxVersion);
 		}
 	} else {
@@ -59,7 +59,7 @@ void ComposerEngine::syncList(Common::Serializer &ser, Common::List<T> &data, Co
 	if (ser.isSaving()) {
 		uint32 size = data.size();
 		ser.syncAsUint32LE(size, minVersion, maxVersion);
-		for (Common::List<T>::iterator i = data.begin(); i != data.end(); i++) {
+		for (typename Common::List<T>::iterator i = data.begin(); i != data.end(); i++) {
 			sync<T>(ser, *i, minVersion, maxVersion);
 		}
 	} else {
@@ -78,7 +78,7 @@ void ComposerEngine::syncListReverse(Common::Serializer &ser, Common::List<T> &d
 	if (ser.isSaving()) {
 		uint32 size = data.size();
 		ser.syncAsUint32LE(size, minVersion, maxVersion);
-		for (Common::List<T>::iterator i = data.reverse_begin(); i != data.end(); i--) {
+		for (typename Common::List<T>::iterator i = data.reverse_begin(); i != data.end(); i--) {
 			sync<T>(ser, *i, minVersion, maxVersion);
 		}
 	} else {


Commit: ec06c04faa7a14e3586849a670ff8db71d43a7ca
    https://github.com/scummvm/scummvm/commit/ec06c04faa7a14e3586849a670ff8db71d43a7ca
Author: angstsmurf (ignalina at me.com)
Date: 2016-10-18T03:09:19+02:00

Commit Message:
COMPOSER: Use setPixel() and getPixel() methods to read and write to private pixel member

Changed paths:
    engines/composer/saveload.cpp



diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp
index ae55f90..ea657a9 100644
--- a/engines/composer/saveload.cpp
+++ b/engines/composer/saveload.cpp
@@ -256,8 +256,8 @@ void ComposerEngine::sync<Sprite>(Common::Serializer &ser, Sprite &data, Common:
 		ser.syncAsUint16LE(data._surface.pitch);
 		ser.syncAsUint16LE(data._zorder);
 		if (ser.isLoading())
-			data._surface.pixels = malloc(data._surface.h * data._surface.pitch);
-		byte *pix = static_cast<byte *>(data._surface.pixels);
+			data._surface.setPixels(malloc(data._surface.h * data._surface.pitch));
+		byte *pix = static_cast<byte *>(data._surface.getPixels());
 		for (uint16 y = 0; y < data._surface.h; y++) {
 			for (uint16 x = 0; x < data._surface.w; x++) {
 				ser.syncAsByte(pix[x]);


Commit: 6cad083f84ed3ab5b1cd1bc054308ce26930d6c4
    https://github.com/scummvm/scummvm/commit/6cad083f84ed3ab5b1cd1bc054308ce26930d6c4
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2016-11-03T23:51:18+01:00

Commit Message:
Merge pull request #851 from angstsmurf/composer-gmm-new

COMPOSER: Support GMM saving/loading and load from launcher

Changed paths:
  A engines/composer/saveload.cpp
    engines/composer/composer.cpp
    engines/composer/composer.h
    engines/composer/detection.cpp
    engines/composer/graphics.cpp
    engines/composer/graphics.h
    engines/composer/module.mk
    engines/composer/resource.cpp
    engines/composer/resource.h








More information about the Scummvm-git-logs mailing list