[Scummvm-cvs-logs] SF.net SVN: scummvm: [31989] scummvm/trunk/engines/gob

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Sat May 10 22:59:43 CEST 2008


Revision: 31989
          http://scummvm.svn.sourceforge.net/scummvm/?rev=31989&view=rev
Author:   drmccoy
Date:     2008-05-10 13:59:43 -0700 (Sat, 10 May 2008)

Log Message:
-----------
Restructured saving/loading and added a stub for Woodruff

Modified Paths:
--------------
    scummvm/trunk/engines/gob/gob.cpp
    scummvm/trunk/engines/gob/gob.h
    scummvm/trunk/engines/gob/inter_v2.cpp
    scummvm/trunk/engines/gob/module.mk
    scummvm/trunk/engines/gob/saveload.cpp
    scummvm/trunk/engines/gob/saveload.h
    scummvm/trunk/engines/gob/saveload_v2.cpp
    scummvm/trunk/engines/gob/saveload_v3.cpp
    scummvm/trunk/engines/gob/video.h

Added Paths:
-----------
    scummvm/trunk/engines/gob/saveload_v4.cpp

Modified: scummvm/trunk/engines/gob/gob.cpp
===================================================================
--- scummvm/trunk/engines/gob/gob.cpp	2008-05-10 19:57:49 UTC (rev 31988)
+++ scummvm/trunk/engines/gob/gob.cpp	2008-05-10 20:59:43 UTC (rev 31989)
@@ -89,6 +89,7 @@
 	Common::addSpecialDebugLevel(kDebugParser, "Parser", "Parser debug level");
 	Common::addSpecialDebugLevel(kDebugGameFlow, "Gameflow", "Gameflow debug level");
 	Common::addSpecialDebugLevel(kDebugFileIO, "FileIO", "File Input/Output debug level");
+	Common::addSpecialDebugLevel(kDebugSaveLoad, "SaveLoad", "Saving/Loading debug level");
 	Common::addSpecialDebugLevel(kDebugGraphics, "Graphics", "Graphics debug level");
 	Common::addSpecialDebugLevel(kDebugCollisions, "Collisions", "Collisions debug level");
 
@@ -353,7 +354,7 @@
 			_map = new Map_v4(this);
 			_goblin = new Goblin_v4(this);
 			_scenery = new Scenery_v2(this);
-			_saveLoad = new SaveLoad_v3(this, _targetName.c_str());
+			_saveLoad = new SaveLoad_v4(this, _targetName.c_str());
 			break;
 
 		default:

Modified: scummvm/trunk/engines/gob/gob.h
===================================================================
--- scummvm/trunk/engines/gob/gob.h	2008-05-10 19:57:49 UTC (rev 31988)
+++ scummvm/trunk/engines/gob/gob.h	2008-05-10 20:59:43 UTC (rev 31989)
@@ -104,8 +104,9 @@
 	kDebugParser = 1 << 4,
 	kDebugGameFlow = 1 << 5,
 	kDebugFileIO = 1 << 6,
-	kDebugGraphics = 1 << 7,
-	kDebugCollisions = 1 << 8
+	kDebugSaveLoad = 1 << 7,
+	kDebugGraphics = 1 << 8,
+	kDebugCollisions = 1 << 9
 };
 
 inline char *strncpy0(char *dest, const char *src, size_t n) {

Modified: scummvm/trunk/engines/gob/inter_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v2.cpp	2008-05-10 19:57:49 UTC (rev 31988)
+++ scummvm/trunk/engines/gob/inter_v2.cpp	2008-05-10 20:59:43 UTC (rev 31989)
@@ -1911,7 +1911,7 @@
 	int16 handle;
 	int16 varOff;
 	int32 size;
-	SaveType type;
+	SaveLoad::SaveMode mode;
 
 	evalExpr(0);
 	varOff = _vm->_parse->parseVarIndex();
@@ -1919,8 +1919,8 @@
 	size = -1;
 	handle = 1;
 
-	type = _vm->_saveLoad->getSaveType(_vm->_global->_inter_resStr);
-	if (type == kSaveNone) {
+	mode = _vm->_saveLoad->getSaveMode(_vm->_global->_inter_resStr);
+	if (mode == SaveLoad::kSaveModeNone) {
 		handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr);
 
 		if (handle >= 0) {
@@ -1928,8 +1928,8 @@
 			size = _vm->_dataIO->getDataSize(_vm->_global->_inter_resStr);
 		} else
 			warning("File \"%s\" not found", _vm->_global->_inter_resStr);
-	} else
-		size = _vm->_saveLoad->getSize(type);
+	} else if (mode == SaveLoad::kSaveModeSave)
+		size = _vm->_saveLoad->getSize(_vm->_global->_inter_resStr);
 
 	if (size == -1)
 		handle = -1;
@@ -1950,7 +1950,7 @@
 	int16 dataVar;
 	int16 handle;
 	byte *buf;
-	SaveType type;
+	SaveLoad::SaveMode mode;
 
 	evalExpr(0);
 	dataVar = _vm->_parse->parseVarIndex();
@@ -1962,13 +1962,14 @@
 	debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)",
 			_vm->_global->_inter_resStr, dataVar, size, offset);
 
-	type = _vm->_saveLoad->getSaveType(_vm->_global->_inter_resStr);
-	if (type != kSaveNone) {
+	mode = _vm->_saveLoad->getSaveMode(_vm->_global->_inter_resStr);
+	if (mode == SaveLoad::kSaveModeSave) {
 		WRITE_VAR(1, 1);
-		if (_vm->_saveLoad->load(type, dataVar, size, offset))
+		if (_vm->_saveLoad->load(_vm->_global->_inter_resStr, dataVar, size, offset))
 			WRITE_VAR(1, 0);
 		return false;
-	}
+	} else if (mode == SaveLoad::kSaveModeIgnore)
+		return false;
 
 	if (size < 0) {
 		warning("Attempted to read a raw sprite from file \"%s\"",
@@ -2021,7 +2022,7 @@
 	int32 offset;
 	int32 size;
 	int16 dataVar;
-	SaveType type;
+	SaveLoad::SaveMode mode;
 
 	evalExpr(0);
 	dataVar = _vm->_parse->parseVarIndex();
@@ -2034,11 +2035,11 @@
 
 	WRITE_VAR(1, 1);
 
-	type = _vm->_saveLoad->getSaveType(_vm->_global->_inter_resStr);
-	if (type != kSaveNone) {
-		if (_vm->_saveLoad->save(type, dataVar, size, offset))
+	mode = _vm->_saveLoad->getSaveMode(_vm->_global->_inter_resStr);
+	if (mode == SaveLoad::kSaveModeSave) {
+		if (_vm->_saveLoad->save(_vm->_global->_inter_resStr, dataVar, size, offset))
 			WRITE_VAR(1, 0);
-	} else
+	} else if (mode == SaveLoad::kSaveModeNone)
 		warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr);
 
 	return false;

Modified: scummvm/trunk/engines/gob/module.mk
===================================================================
--- scummvm/trunk/engines/gob/module.mk	2008-05-10 19:57:49 UTC (rev 31988)
+++ scummvm/trunk/engines/gob/module.mk	2008-05-10 20:59:43 UTC (rev 31989)
@@ -44,6 +44,7 @@
 	saveload.o \
 	saveload_v2.o \
 	saveload_v3.o \
+	saveload_v4.o \
 	scenery.o \
 	scenery_v1.o \
 	scenery_v2.o \

Modified: scummvm/trunk/engines/gob/saveload.cpp
===================================================================
--- scummvm/trunk/engines/gob/saveload.cpp	2008-05-10 19:57:49 UTC (rev 31988)
+++ scummvm/trunk/engines/gob/saveload.cpp	2008-05-10 20:59:43 UTC (rev 31989)
@@ -24,458 +24,495 @@
  */
 
 #include "common/endian.h"
-#include "common/file.h"
+#include "common/savefile.h"
 
 #include "gob/gob.h"
 #include "gob/saveload.h"
-#include "gob/global.h"
 #include "gob/draw.h"
-#include "gob/video.h"
 
 namespace Gob {
 
-SaveLoad::SaveLoad(GobEngine *vm, const char *targetName) : _vm(vm) {
-	_curSlot = -1;
+TempSprite::TempSprite() {
+	_sprite = 0;
+	_width = _height = 0;
+	_size = -1;
+	memset(_palette, 0, 768);
+}
 
-	_stagesCount = 0;
-	_buffer = 0;
+TempSprite::~TempSprite() {
+	delete[] _sprite;
+}
 
-	_tempSprite = 0;
-	memset(_tempPal, 0, 768);
-	_tempSpriteSize = -1;
+int TempSprite::getSpriteIndex(int32 size) const {
+	if (size < -1000)
+		size += 1000;
 
-	_saveFiles = new char*[5];
+	return -size - 1;
+}
 
-	assert(_saveFiles);
+bool TempSprite::getSpritePalette(int32 size) const {
+	return size < -1000;
+}
 
-	_saveFiles[0] = new char[strlen(targetName) + 5];
-	_saveFiles[1] = 0;
-	_saveFiles[2] = new char[strlen(targetName) + 5];
-	_saveFiles[3] = _saveFiles[0];
-	_saveFiles[4] = 0;
+bool TempSprite::getProperties(int16 dataVar, int32 size, int32 offset,
+		int &index, bool &palette) const {
 
-	assert(_saveFiles[0] && _saveFiles[2]);
+	if (size >= 0) {
+		warning("Invalid index (%d)", size);
+		return false;
+	}
 
-	sprintf(_saveFiles[0], "%s.s00", targetName);
-	sprintf(_saveFiles[2], "%s.blo", targetName);
-}
+	index = getSpriteIndex(size);
+	palette = getSpritePalette(size);
 
-SaveLoad::~SaveLoad() {
-	if (_buffer) {
-		for (int i = 0; i < _stagesCount; i++)
-			delete[] _buffer[i];
-		delete[] _buffer;
+	if ((index < 0) || (index >= SPRITES_COUNT)) {
+		warning("Index out of range (%d)", index);
+		return false;
 	}
 
-	delete _tempSprite;
+	return true;
+}
 
-	delete[] _saveFiles[0];
-	delete[] _saveFiles[2];
-	delete[] _saveFiles;
+int32 TempSprite::getSize() const {
+	return _size;
 }
 
-const char *SaveLoad::setCurSlot(int slot) {
-	static char *slotBase = _saveFiles[0] + strlen(_saveFiles[0]) - 2;
+bool TempSprite::saveSprite(const SurfaceDesc &surfDesc) {
+	delete[] _sprite;
 
-	if (_curSlot != slot) {
-		_curSlot = slot;
+	_width = surfDesc.getWidth();
+	_height = surfDesc.getHeight();
+	_size = _width * _height;
+	_sprite = new byte[_size];
 
-		if (_curSlot >= 0)
-			snprintf(slotBase, 3, "%02d", slot);
-	}
+	memcpy(_sprite, surfDesc.getVidMem(), _size);
 
-	return _saveFiles[0];
+	return true;
 }
 
-uint32 SaveLoad::read(Common::ReadStream &in, byte *buf,
-		byte *sizes, uint32 count) {
-	uint32 nRead;
+bool TempSprite::savePalette(const Video::Color *palette) {
+	memcpy((byte *) _palette, (byte *) palette, 768);
+	return true;
+}
 
-	nRead = in.read(buf, count);
-	if (nRead != count) {
-		warning("Can't read data: requested %d, got %d", count, nRead);
-		return 0;
+bool TempSprite::loadSprite(SurfaceDesc &surfDesc) {
+	if (!_sprite) {
+		warning("No sprite saved");
+		return false;
 	}
 
-	nRead = in.read(sizes, count);
-	if (nRead != count) {
-		warning("Can't read data sizes: requested %d, got %d", count, nRead);
-		return 0;
+	if (_size != (surfDesc.getWidth() * surfDesc.getHeight())) {
+		warning("Dimensions don't match (%dx%d - %dx%d",
+				_width, _height, surfDesc.getWidth(), surfDesc.getHeight());
+		return false;
 	}
 
-	return count;
+	memcpy(surfDesc.getVidMem(), _sprite, _size);
+
+	return true;
 }
 
-uint32 SaveLoad::write(Common::WriteStream &out, byte *buf,
-		byte *sizes, uint32 count) {
-	uint32 written;
+bool TempSprite::loadPalette(Video::Color *palette) {
+	memcpy((byte *) palette, (byte *) _palette, 768);
+	return true;
+}
 
-	written = out.write(buf, count);
-	if (written != count) {
-		warning("Can't write data: requested %d, wrote %d", count, written);
-		return 0;
+bool TempSprite::toBuffer(byte *buffer, int32 size, bool palette) const {
+
+	int32 haveSize = _size + (palette ? 768 : 0);
+	if (size != haveSize) {
+		warning("Sizes don't match (%d != %d)", size, haveSize);
+		return false;
 	}
 
-	written = out.write(sizes, count);
-	if (written != count) {
-		warning("Can't write data: requested %d, wrote %d", count, written);
-		return 0;
+	if (palette) {
+		memcpy(buffer, (byte *) _palette, 768);
+		buffer += 768;
 	}
 
-	return count;
+	memcpy(buffer, _sprite, _size);
+
+	return true;
 }
 
-bool SaveLoad::loadDataEndian(Common::ReadStream &in,
-		int16 dataVar, uint32 size) {
+bool TempSprite::fromBuffer(const byte *buffer, int32 size, bool palette) {
+	if (palette) {
+		memcpy((byte *) _palette, buffer, 768);
+		buffer += 768;
+		size -= 768;
+	}
 
-	bool retVal = false;
+	_size = size;
 
-	byte *varBuf = new byte[size];
-	byte *sizeBuf = new byte[size];
+	delete[] _sprite;
+	_sprite = new byte[_size];
 
-	assert(varBuf && sizeBuf);
+	memcpy(_sprite, buffer, _size);
 
-	if (read(in, varBuf, sizeBuf, size) == size) {
-		if (fromEndian(varBuf, sizeBuf, size)) {
-			memcpy(_vm->_global->_inter_variables + dataVar, varBuf, size);
-			memcpy(_vm->_global->_inter_variablesSizes + dataVar, sizeBuf, size);
-			retVal = true;
-		}
-	}
+	return true;
+}
 
-	delete[] varBuf;
-	delete[] sizeBuf;
 
-	return retVal;
+PlainSave::PlainSave() {
 }
 
-bool SaveLoad::saveDataEndian(Common::WriteStream &out,
-		int16 dataVar, uint32 size) {
+PlainSave::~PlainSave() {
+}
 
-	bool retVal = false;
+bool PlainSave::save(int16 dataVar, int32 size, int32 offset, const char *name,
+		const byte *variables, const byte *variableSizes) const {
 
-	byte *varBuf = new byte[size];
-	byte *sizeBuf = new byte[size];
+	if ((size <= 0) || (offset != 0)) {
+		warning("Invalid size (%d) or offset (%d)", size, offset);
+		return false;
+	}
 
-	assert(varBuf && sizeBuf);
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::OutSaveFile *out = saveMan->openForSaving(name);
 
-	memcpy(varBuf, _vm->_global->_inter_variables + dataVar, size);
-	memcpy(sizeBuf, _vm->_global->_inter_variablesSizes + dataVar, size);
+	if (!out) {
+		warning("Can't open file \"%s\" for writing", name);
+		return false;
+	}
 
-	if (toEndian(varBuf, sizeBuf, size))
-		if (write(out, varBuf, sizeBuf, size) == size)
-			retVal = true;
+	bool retVal;
+	retVal = SaveLoad::saveDataEndian(*out, dataVar, size, variables, variableSizes);
 
-	delete[] varBuf;
-	delete[] sizeBuf;
+	out->finalize();
+	if (out->ioFailed()) {
+		warning("Can't write to file \"%s\"", name);
+		retVal = false;
+	}
 
+	delete out;
 	return retVal;
 }
 
-int32 SaveLoad::getSize(SaveType type) {
-	switch (type) {
-	case kSaveNone:
-		return -1;
-		break;
+bool PlainSave::load(int16 dataVar, int32 size, int32 offset, const char *name,
+		byte *variables, byte *variableSizes) const {
 
-	case kSaveGame:
-		return getSizeGame();
-		break;
+	if ((size <= 0) || (offset != 0)) {
+		warning("Invalid size (%d) or offset (%d)", size, offset);
+		return false;
+	}
 
-	case kSaveTempSprite:
-		return getSizeTempSprite();
-		break;
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in = saveMan->openForLoading(name);
 
-	case kSaveNotes:
-		return getSizeNotes();
-		break;
-
-	case kSaveScreenshot:
-		return getSizeScreenshot();
-		break;
-
-	case kSaveIgnore:
-		return -1;
-		break;
+	if (!in) {
+		warning("Can't open file \"%s\" for reading", name);
+		return false;
 	}
 
-	return -1;
+	bool retVal = SaveLoad::loadDataEndian(*in, dataVar, size, variables, variableSizes);
+	delete in;
+	return retVal;
 }
 
-bool SaveLoad::load(SaveType type, int16 dataVar, int32 size, int32 offset) {
-	switch (type) {
-	case kSaveNone:
-		return false;
-		break;
 
-	case kSaveGame:
-		return loadGame(dataVar, size, offset);
-		break;
+StagedSave::StagedSave() {
+	_mode = kModeNone;
+	_name = 0;
+	_loaded = false;
+}
 
-	case kSaveTempSprite:
-		return loadTempSprite(dataVar, size, offset);
-		break;
+StagedSave::~StagedSave() {
+	clear();
+}
 
-	case kSaveNotes:
-		return loadNotes(dataVar, size, offset);
-		break;
+void StagedSave::addStage(int32 size, bool endianed) {
+	int32 offset = 0;
 
-	case kSaveScreenshot:
-		return loadScreenshot(dataVar, size, offset);
-		break;
+	if (!_stages.empty())
+		offset = _stages[_stages.size() - 1].offset +
+		         _stages[_stages.size() - 1].size;
 
-	case kSaveIgnore:
-		return true;
-		break;
-	}
-
-	return false;
+	Stage stage(size, offset, endianed);
+	_stages.push_back(stage);
 }
 
-bool SaveLoad::save(SaveType type, int16 dataVar, int32 size, int32 offset) {
-	switch (type) {
-	case kSaveNone:
-		return false;
-		break;
+int StagedSave::findStage(int16 dataVar, int32 size, int32 offset) const {
+	for (uint i = 0; i < _stages.size(); i++)
+		if ((_stages[i].size == size) &&
+		    (_stages[i].offset == offset))
+			return i;
 
-	case kSaveGame:
-		return saveGame(dataVar, size, offset);
-		break;
+	return -1;
+}
 
-	case kSaveTempSprite:
-		return saveTempSprite(dataVar, size, offset);
-		break;
+bool StagedSave::allSaved() const {
+	for (uint i = 0; i < _stages.size(); i++)
+		if (!_stages[i].bufVar)
+			return false;
 
-	case kSaveNotes:
-		return saveNotes(dataVar, size, offset);
-		break;
+	return true;
+}
 
-	case kSaveScreenshot:
-		return saveScreenshot(dataVar, size, offset);
-		break;
+uint32 StagedSave::getSize() const {
+	uint32 size = 0;
 
-	case kSaveIgnore:
-		return true;
-		break;
+	for (uint i = 0; i < _stages.size(); i++) {
+		if (_stages[i].endianed)
+			size += 2 * _stages[i].size;
+		else
+			size += _stages[i].size;
 	}
+	
+	return size;
+}
 
-	return false;
+void StagedSave::clear() {
+	for (uint i = 0; i < _stages.size(); i++) {
+		delete[] _stages[i].bufVar;
+		delete[] _stages[i].bufVarSizes;
+		_stages[i].bufVar = 0;
+		_stages[i].bufVarSizes = 0;
+	}
+
+	delete[] _name;
+	_name = 0;
+
+	_mode = kModeNone;
+	_loaded = false;
 }
 
-int32 SaveLoad::getSizeTempSprite() {
-	return _tempSpriteSize;
+void StagedSave::assertMode(Mode mode, const char *name) {
+	if ((_mode != mode) || ((name[0] != '\0') && strcmp(_name, name))) {
+		clear();
+		_mode = mode;
+		_name = new char[strlen(name) + 1];
+		strcpy(_name, name);
+	}
 }
 
-bool SaveLoad::loadTempSprite(int16 dataVar, int32 size, int32 offset) {
-	int index;
-	bool readPal;
+bool StagedSave::save(int16 dataVar, int32 size, int32 offset, const char *name,
+		const byte *variables, const byte *variableSizes) {
 
-	if (size >= 0) {
-		warning("Invalid attempt at loading from the temporary sprite");
+	if ((dataVar < 0) || (size <= 0) || (offset < 0)) {
+		warning("Invalid dataVar (%d), size (%d) or offset (%d)", dataVar, size, offset);
 		return false;
 	}
 
-	index = getSpriteIndex(size);
-	readPal = getSpritePalette(size);
+	int stage = findStage(dataVar, size, offset);
+	if (stage == -1) {
+		warning("Invalid saving procedure");
+		return false;
+	}
 
-	if ((index < 0) || (index >= SPRITES_COUNT)) {
-		warning("Index out of range while loading from the temporary "
-				"sprite (%d)", index);
+	if (!variables || (_stages[stage].endianed && !variableSizes)) {
+		warning("Missing data");
 		return false;
 	}
 
-	return loadTempSprite(index, readPal);
-}
+	assertMode(kModeSave, name);
 
-bool SaveLoad::saveTempSprite(int16 dataVar, int32 size, int32 offset) {
-	int index;
-	bool readPal;
+	_stages[stage].bufVar = new byte[size];
+	memcpy(_stages[stage].bufVar, variables + dataVar, size);
 
-	if (size >= 0) {
-		warning("Invalid attempt at saving to the temporary sprite");
-		return false;
+	if (_stages[stage].endianed) {
+		_stages[stage].bufVarSizes = new byte[size];
+		memcpy(_stages[stage].bufVarSizes, variableSizes + dataVar, size);
 	}
 
-	index = getSpriteIndex(size);
-	readPal = getSpritePalette(size);
-
-	if ((index < 0) || (index >= SPRITES_COUNT)) {
-		warning("Index out of range while saving to the temporary sprite (%d)",
-				index);
-		return false;
+	if (allSaved()) {
+		bool result = write();
+		clear();
+		return result;
 	}
 
-	return saveTempSprite(index, readPal);
+	return true;
 }
 
-bool SaveLoad::loadTempSprite(uint32 index, bool palette) {
-	SurfaceDesc *sprite;
+bool StagedSave::load(int16 dataVar, int32 size, int32 offset, const char *name,
+		byte *variables, byte *variableSizes) {
 
-	if (palette) {
-		memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal,
-				(char *) _tempPal, 768);
-		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
-	}
-
-	sprite = _vm->_draw->_spritesArray[index];
-
-	if (!sprite) {
-		warning("Couldn't load from the temporary sprite: "
-				"No such sprite %d", index);
+	if ((dataVar < 0) || (size <= 0) || (offset < 0)) {
+		warning("Invalid dataVar (%d), size (%d) or offset (%d)", dataVar, size, offset);
 		return false;
 	}
 
-	if ((sprite->getWidth() != _tempSprite->getWidth()) ||
-			(sprite->getHeight() != _tempSprite->getHeight())) {
-		warning("Resolution doesn't match while loading from the "
-				"temporary sprite (%d: %dx%d vs. %dx%d)", index,
-				sprite->getWidth(), sprite->getHeight(),
-				_tempSprite->getWidth(), _tempSprite->getHeight());
+	int stage = findStage(dataVar, size, offset);
+	if (stage == -1) {
+		warning("Invalid loading procedure");
 		return false;
 	}
 
-	_vm->_video->drawSprite(_tempSprite, sprite, 0, 0,
-			sprite->getWidth() - 1, sprite->getHeight() - 1, 0, 0, 0);
+	assertMode(kModeLoad, name);
 
-	if (index == 21) {
-		_vm->_draw->forceBlit();
-		_vm->_video->retrace();
+	if (!_loaded) {
+		if (!read()) {
+			clear();
+			return false;
+		}
 	}
 
+	if (variables)
+		memcpy(variables + dataVar, _stages[stage].bufVar, size);
+	if (_stages[stage].endianed && variableSizes)
+		memcpy(variableSizes + dataVar, _stages[stage].bufVarSizes, size);
+
 	return true;
 }
 
-bool SaveLoad::saveTempSprite(uint32 index, bool palette) {
-	SurfaceDesc *sprite = _vm->_draw->_spritesArray[index];
+bool StagedSave::write() const {
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::OutSaveFile *out = saveMan->openForSaving(_name);
 
-	if (!sprite) {
-		warning("Couldn't save to the temporary sprite: "
-				"No such sprite %d", index);
+	if (!out) {
+		warning("Can't open file \"%s\" for writing", _name);
 		return false;
 	}
 
-	delete _tempSprite;
-	_tempSprite = _vm->_video->initSurfDesc(_vm->_global->_videoMode,
-			sprite->getWidth(), sprite->getHeight(), 0);
+	bool result = true;
+	for (uint i = 0; (i < _stages.size()) && result; i++) {
+		if (!_stages[i].endianed) {
 
-	_vm->_video->drawSprite(sprite, _tempSprite, 0, 0,
-			sprite->getWidth() - 1, sprite->getHeight() - 1, 0, 0, 0);
+			uint32 written = out->write(_stages[i].bufVar, _stages[i].size);
 
-	_tempSpriteSize = _vm->_draw->getSpriteRectSize(index);
+			result = (written == ((uint32) _stages[i].size));
+			if (!result)
+				warning("Can't write data: requested %d, wrote %d", _stages[i].size, written);
 
-	if (palette) {
-		memcpy((char *) _tempPal,
-				(char *) _vm->_global->_pPaletteDesc->vgaPal, 768);
-		_tempSpriteSize += 768;
+		} else
+			result = SaveLoad::saveDataEndian(*out, 0, _stages[i].size,
+					_stages[i].bufVar, _stages[i].bufVarSizes);
 	}
 
-	return true;
+	if (result) {
+		out->finalize();
+		if (out->ioFailed()) {
+			warning("Can't write to file \"%s\"", _name);
+			result = false;
+		}
+	}
+
+	delete out;
+	return result;
 }
 
-bool SaveLoad::loadSprite(Common::ReadStream &in, int32 size) {
-	SurfaceDesc *sprite;
-	byte *buf;
-	int nRead;
-	int index;
-	bool readPal;
+bool StagedSave::read() {
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in = saveMan->openForLoading(_name);
 
-	if (size >= 0) {
-		warning("Invalid attempt at loading a sprite");
+	if (!in) {
+		warning("Can't open file \"%s\" for reading", _name);
 		return false;
 	}
 
-	index = getSpriteIndex(size);
-	readPal = getSpritePalette(size);
-
-	if ((index < 0) || (index >= SPRITES_COUNT)) {
-		warning("Index out of range while loading a sprite (%d)",
-				index);
+	uint32 saveSize = getSize();
+	if (in->size() != saveSize) {
+		warning("Wrong size (%d != %d)", in->size(), saveSize);
 		return false;
 	}
 
-	size = _vm->_draw->getSpriteRectSize(index);
-	sprite = _vm->_draw->_spritesArray[index];
+	bool result = true;
+	for (uint i = 0; ((i < _stages.size()) && result); i++) {
+		_stages[i].bufVar = new byte[_stages[i].size];
 
-	if (!sprite) {
-		warning("Couldn't load sprite: No such sprite %d", index);
-		return false;
-	}
+		if (!_stages[i].endianed) {
 
-	buf = new byte[MAX<int>(768, size)];
-	assert(buf);
+			uint32 nRead = in->read(_stages[i].bufVar, _stages[i].size);
 
-	if (readPal) {
-		nRead = in.read(buf, 768);
-		if (nRead != 768) {
-			warning("Couldn't read a palette: requested 768, got %d", nRead);
-			delete[] buf;
-			return false;
-		}
+			result = (nRead == ((uint32) _stages[i].size));
+			if (!result)
+				warning("Can't read data: requested %d, got %d", _stages[i].size, nRead);
 
-		memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal,
-				(char *) buf, 768);
-		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
-	}
+		} else {
+			_stages[i].bufVarSizes = new byte[_stages[i].size];
 
-	nRead = in.read(buf, size);
-	if (nRead != size) {
-		warning("Couldn't read sprite data: requested %d, got %d", size, nRead);
-		delete[] buf;
-		return false;
+			result = SaveLoad::loadDataEndian(*in, 0, _stages[i].size,
+					_stages[i].bufVar, _stages[i].bufVarSizes);
+		}
 	}
 
-	memcpy((char *) sprite->getVidMem(), buf, size);
+	if (result)
+		_loaded = true;
 
-	delete[] buf;
-	return true;
+	delete in;
+	return result;
 }
 
-bool SaveLoad::saveSprite(Common::WriteStream &out, int32 size) {
-	SurfaceDesc *sprite;
-	int written;
-	int index;
-	bool readPal;
 
-	if (size >= 0) {
-		warning("Invalid attempt at saving a sprite");
-		return false;
-	}
+SaveLoad::SaveLoad(GobEngine *vm, const char *targetName) : _vm(vm) {
 
-	index = getSpriteIndex(size);
-	readPal = getSpritePalette(size);
+	_targetName = new char[strlen(targetName) + 1];
+	strcpy(_targetName, targetName);
+}
 
-	if ((index < 0) || (index >= SPRITES_COUNT)) {
-		warning("Index out of range while saving a sprite (%d)",
-				index);
-		return false;
-	}
+SaveLoad::~SaveLoad() {
+	delete[] _targetName;
+}
 
-	size = _vm->_draw->getSpriteRectSize(index);
-	sprite = _vm->_draw->_spritesArray[index];
+int32 SaveLoad::getSize(const char *fileName) {
+	int type;
 
-	if (!sprite) {
-		warning("Couldn't save sprite: No such sprite %d", index);
+	type = getSaveType(stripPath(fileName));
+	if (type == -1)
+		return -1;
+
+	debugC(3, kDebugSaveLoad, "Requested size of save file \"%s\" (type %d)",
+			fileName, type);
+
+	return getSizeVersioned(type);
+}
+
+bool SaveLoad::load(const char *fileName, int16 dataVar, int32 size, int32 offset) {
+	int type;
+
+	type = getSaveType(stripPath(fileName));
+	if (type == -1)
 		return false;
-	}
 
-	if (readPal) {
-		written = out.write((char *) _vm->_global->_pPaletteDesc->vgaPal, 768);
-		if (written != 768) {
-			warning("Couldn't write a palette: requested 768, wrote %d", written);
-			return false;
-		}
-	}
+	debugC(3, kDebugSaveLoad, "Requested loading of save file \"%s\" (type %d) - %d, %d, %d",
+			fileName, type, dataVar, size, offset);
 
-	written = out.write((char *) sprite->getVidMem(), size);
-	if (written != size) {
-		warning("Couldn't write a sprite: requested %d, wrote %d",
-				size, written);
+	return loadVersioned(type, dataVar, size, offset);
+}
+
+bool SaveLoad::save(const char *fileName, int16 dataVar, int32 size, int32 offset) {
+	int type;
+
+	type = getSaveType(stripPath(fileName));
+	if (type == -1)
 		return false;
-	}
 
-	return true;
+	debugC(3, kDebugSaveLoad, "Requested saving of save file \"%s\" (type %d) - %d, %d, %d",
+			fileName, type, dataVar, size, offset);
+
+	return saveVersioned(type, dataVar, size, offset);
 }
 
+const char *SaveLoad::stripPath(const char *fileName) {
+	const char *backSlash;
+	if ((backSlash = strrchr(fileName, '\\')))
+		return backSlash + 1;
+
+	return fileName;
+}
+
+char *SaveLoad::setCurrentSlot(char *destName, int slot) {
+	char *slotBase = destName + strlen(destName) - 2;
+
+	snprintf(slotBase, 3, "%02d", slot);
+
+	return destName;
+}
+
+void SaveLoad::buildIndex(byte *buffer, char *name, int n, int32 size, int32 offset) {
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
+
+	for (int i = 0; i < n; i++, buffer += size) {
+		in = saveMan->openForLoading(setCurrentSlot(name, i));
+		if (in) {
+			in->seek(offset);
+			in->read(buffer, size);
+			delete in;
+		} else
+			memset(buffer, 0, size);
+	}
+}
+
 bool SaveLoad::fromEndian(byte *buf, const byte *sizes, uint32 count) {
 	while (count-- > 0) {
 		if (*sizes == 3)
@@ -514,4 +551,89 @@
 	return true;
 }
 
+uint32 SaveLoad::read(Common::ReadStream &in,
+		byte *buf, byte *sizes, uint32 count) {
+	uint32 nRead;
+
+	nRead = in.read(buf, count);
+	if (nRead != count) {
+		warning("Can't read data: requested %d, got %d", count, nRead);
+		return 0;
+	}
+
+	nRead = in.read(sizes, count);
+	if (nRead != count) {
+		warning("Can't read data sizes: requested %d, got %d", count, nRead);
+		return 0;
+	}
+
+	return count;
+}
+
+uint32 SaveLoad::write(Common::WriteStream &out,
+		const byte *buf, const byte *sizes, uint32 count) {
+	uint32 written;
+
+	written = out.write(buf, count);
+	if (written != count) {
+		warning("Can't write data: requested %d, wrote %d", count, written);
+		return 0;
+	}
+
+	written = out.write(sizes, count);
+	if (written != count) {
+		warning("Can't write data: requested %d, wrote %d", count, written);
+		return 0;
+	}
+
+	return count;
+}
+
+bool SaveLoad::loadDataEndian(Common::ReadStream &in,
+		int16 dataVar, uint32 size, byte *variables, byte *variableSizes) {
+
+	bool retVal = false;
+
+	byte *varBuf = new byte[size];
+	byte *sizeBuf = new byte[size];
+
+	assert(varBuf && sizeBuf);
+
+	if (read(in, varBuf, sizeBuf, size) == size) {
+		if (fromEndian(varBuf, sizeBuf, size)) {
+			memcpy(variables + dataVar, varBuf, size);
+			memcpy(variableSizes + dataVar, sizeBuf, size);
+			retVal = true;
+		}
+	}
+
+	delete[] varBuf;
+	delete[] sizeBuf;
+
+	return retVal;
+}
+
+bool SaveLoad::saveDataEndian(Common::WriteStream &out,
+		int16 dataVar, uint32 size, const byte *variables, const byte *variableSizes) {
+
+	bool retVal = false;
+
+	byte *varBuf = new byte[size];
+	byte *sizeBuf = new byte[size];
+
+	assert(varBuf && sizeBuf);
+
+	memcpy(varBuf, variables + dataVar, size);
+	memcpy(sizeBuf, variableSizes + dataVar, size);
+
+	if (toEndian(varBuf, sizeBuf, size))
+		if (write(out, varBuf, sizeBuf, size) == size)
+			retVal = true;
+
+	delete[] varBuf;
+	delete[] sizeBuf;
+
+	return retVal;
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/saveload.h
===================================================================
--- scummvm/trunk/engines/gob/saveload.h	2008-05-10 19:57:49 UTC (rev 31988)
+++ scummvm/trunk/engines/gob/saveload.h	2008-05-10 20:59:43 UTC (rev 31989)
@@ -26,145 +26,319 @@
 #ifndef GOB_SAVELOAD_H
 #define GOB_SAVELOAD_H
 
+#include "common/array.h"
 #include "common/stream.h"
 
 #include "gob/video.h"
 
 namespace Gob {
 
-enum SaveType {
-	kSaveNone = -1,
-	kSaveGame,
-	kSaveTempSprite,
-	kSaveNotes,
-	kSaveScreenshot,
-	kSaveIgnore
+class TempSprite {
+public:
+	TempSprite();
+	~TempSprite();
+
+	bool getProperties(int16 dataVar, int32 size, int32 offset,
+			int &index, bool &palette) const;
+
+	int32 getSize() const;
+
+	bool saveSprite(const SurfaceDesc &surfDesc);
+	bool savePalette(const Video::Color *palette);
+	bool loadSprite(SurfaceDesc &surfDesc);
+	bool loadPalette(Video::Color *palette);
+
+	bool toBuffer(byte *buffer, int32 size, bool palette) const;
+	bool fromBuffer(const byte *buffer, int32 size, bool palette);
+	
+private:
+	byte *_sprite;
+	int16 _width;
+	int16 _height;
+	int32 _size;
+	Video::Color _palette[256];
+
+	int getSpriteIndex(int32 size) const;
+	bool getSpritePalette(int32 size) const;
 };
 
+class PlainSave {
+public:
+	PlainSave();
+	~PlainSave();
+
+	bool save(int16 dataVar, int32 size, int32 offset, const char *name,
+			const byte *variables, const byte *variableSizes) const;
+	bool load(int16 dataVar, int32 size, int32 offset, const char *name,
+			byte *variables, byte *variableSizes) const;
+};
+
+class StagedSave {
+public:
+	StagedSave();
+	~StagedSave();
+
+	void addStage(int32 size, bool endianed = true);
+
+	bool save(int16 dataVar, int32 size, int32 offset, const char *name,
+			const byte *variables, const byte *variableSizes);
+	bool load(int16 dataVar, int32 size, int32 offset, const char *name,
+			byte *variables, byte *variableSizes);
+
+private:
+	struct Stage {
+		byte *bufVar;
+		byte *bufVarSizes;
+		int32 size;
+		int32 offset;
+		bool endianed;
+
+		Stage(int32 s = 0, int32 off = 0, bool end = true) :
+			bufVar(0), bufVarSizes(0), size(s), offset(off), endianed(end) {}
+	};
+
+	enum Mode {
+		kModeNone,
+		kModeSave,
+		kModeLoad
+	};
+
+	Common::Array<Stage> _stages;
+	enum Mode _mode;
+	char *_name;
+
+	bool _loaded;
+
+	int findStage(int16 dataVar, int32 size, int32 offset) const;
+	bool allSaved() const;
+
+	uint32 getSize() const;
+
+	void clear();
+	void assertMode(Mode mode, const char *name);
+
+	bool write() const;
+	bool read();
+};
+
 class SaveLoad {
 public:
-	int32 getSize(SaveType type);
-	bool load(SaveType type, int16 dataVar, int32 size, int32 offset);
-	bool save(SaveType type, int16 dataVar, int32 size, int32 offset);
+	enum SaveMode {
+		kSaveModeNone,
+		kSaveModeIgnore,
+		kSaveModeSave
+	};
 
-	virtual SaveType getSaveType(const char *fileName) = 0;
-
 	SaveLoad(GobEngine *vm, const char *targetName);
 	virtual ~SaveLoad();
 
-protected:
-	int _curSlot;
-	char **_saveFiles;
+	virtual SaveMode getSaveMode(const char *fileName) = 0;
 
-	int _stagesCount;
-	byte **_buffer;
+	int32 getSize(const char *fileName);
+	bool load(const char *fileName, int16 dataVar, int32 size, int32 offset);
+	bool save(const char *fileName, int16 dataVar, int32 size, int32 offset);
 
-	// While using the notepad or changing the font, the original executable
-	// temporarily dumps Draw::_backSurface to a file. Since that's not really
-	// a nice thing to do, we work around it.
-	SurfaceDesc *_tempSprite;
-	Video::Color _tempPal[256];
-	int32 _tempSpriteSize;
+	char *setCurrentSlot(char *destName, int slot);
+	void buildIndex(byte *buffer, char *name, int n, int32 size, int32 offset = 0);
 
-	GobEngine *_vm;
+	static const char *stripPath(const char *fileName);
 
-	int getSpriteIndex(int32 size) {
-		if (size < -1000)
-			size += 1000;
+	static bool fromEndian(byte *buf, const byte *sizes, uint32 count);
+	static bool toEndian(byte *buf, const byte *sizes, uint32 count);
+	static uint32 read(Common::ReadStream &in,
+			byte *buf, byte *sizes, uint32 count);
+	static uint32 write(Common::WriteStream &out,
+			const byte *buf, const byte *sizes, uint32 count);
 
-		return -size - 1;
-	}
-	bool getSpritePalette(int32 size) {
-		return size < -1000;
-	}
+	static bool loadDataEndian(Common::ReadStream &in,
+			int16 dataVar, uint32 size, byte *variables, byte *variableSizes);
+	static bool saveDataEndian(Common::WriteStream &out,
+			int16 dataVar, uint32 size, const byte *variables, const byte *variableSizes);
 
-	const char *setCurSlot(int slot);
-	bool fromEndian(byte *buf, const byte *sizes, uint32 count);
-	bool toEndian(byte *buf, const byte *sizes, uint32 count);
-	uint32 read(Common::ReadStream &in, byte *buf,
-			byte *sizes, uint32 count);
-	uint32 write(Common::WriteStream &out, byte *buf,
-			byte *sizes, uint32 count);
+protected:
+	GobEngine *_vm;
 
-	bool loadDataEndian(Common::ReadStream &in, int16 dataVar, uint32 size);
-	bool saveDataEndian(Common::WriteStream &out, int16 dataVar, uint32 size);
+	char *_targetName;
 
-	bool loadTempSprite(uint32 index, bool palette);
-	bool saveTempSprite(uint32 index, bool palette);
-	bool loadSprite(Common::ReadStream &in, int32 size);
-	bool saveSprite(Common::WriteStream &out, int32 size);
+	virtual int getSaveType(const char *fileName) = 0;
 
-	int32 getSizeTempSprite();
-	bool loadTempSprite(int16 dataVar, int32 size, int32 offset);
-	bool saveTempSprite(int16 dataVar, int32 size, int32 offset);
-
-	virtual uint32 getSaveGameSize() = 0;
-
-	virtual int32 getSizeGame() = 0;
-	virtual int32 getSizeNotes() = 0;
-	virtual int32 getSizeScreenshot() = 0;
-	virtual bool loadGame(int16 dataVar, int32 size, int32 offset) = 0;
-	virtual bool loadNotes(int16 dataVar, int32 size, int32 offset) = 0;
-	virtual bool loadScreenshot(int16 dataVar, int32 size, int32 offset) = 0;
-	virtual bool saveGame(int16 dataVar, int32 size, int32 offset) = 0;
-	virtual bool saveNotes(int16 dataVar, int32 size, int32 offset) = 0;
-	virtual bool saveScreenshot(int16 dataVar, int32 size, int32 offset) = 0;
+	virtual int32 getSizeVersioned(int type) = 0;
+	virtual bool loadVersioned(int type, int16 dataVar, int32 size, int32 offset) = 0;
+	virtual bool saveVersioned(int type, int16 dataVar, int32 size, int32 offset) = 0;
 };
 
 class SaveLoad_v2 : public SaveLoad {
 public:
-	virtual SaveType getSaveType(const char *fileName);
+	enum SaveType {
+		kSaveGame,
+		kSaveTempSprite,
+		kSaveNotes
+	};
 
 	SaveLoad_v2(GobEngine *vm, const char *targetName);
-	virtual ~SaveLoad_v2() {}
+	virtual ~SaveLoad_v2();
 
+	virtual SaveMode getSaveMode(const char *fileName);
+
 protected:
-	virtual uint32 getSaveGameSize();
+	struct SaveFile {
+		const char *sourceName;
+		char *destName;
+		SaveMode mode;
+		SaveType type;
+	};
 
-	virtual int32 getSizeGame();
-	virtual int32 getSizeNotes();
-	virtual int32 getSizeScreenshot();
-	virtual bool loadGame(int16 dataVar, int32 size, int32 offset);
-	virtual bool loadNotes(int16 dataVar, int32 size, int32 offset);
-	virtual bool loadScreenshot(int16 dataVar, int32 size, int32 offset);
-	virtual bool saveGame(int16 dataVar, int32 size, int32 offset);
-	virtual bool saveNotes(int16 dataVar, int32 size, int32 offset);
-	virtual bool saveScreenshot(int16 dataVar, int32 size, int32 offset);
+	static SaveFile _saveFiles[];
 
-	void initBuffer();
+	int32 _varSize;
+
+	TempSprite _tmpSprite;
+	PlainSave _notes;
+	StagedSave _save;
+
+	byte _indexBuffer[600];
+	bool _hasIndex;
+
+	virtual int getSaveType(const char *fileName);
+
+	virtual int32 getSizeVersioned(int type);
+	virtual bool loadVersioned(int type, int16 dataVar, int32 size, int32 offset);
+	virtual bool saveVersioned(int type, int16 dataVar, int32 size, int32 offset);
+
+	int getSlot(int32 offset) const;
+	int getSlotRemainder(int32 offset) const;
+
+	int32 getSizeGame(SaveFile &saveFile);
+	int32 getSizeTempSprite(SaveFile &saveFile);
+	int32 getSizeNotes(SaveFile &saveFile);
+
+	bool loadGame(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+	bool loadTempSprite(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+	bool loadNotes(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+
+	bool saveGame(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+	bool saveTempSprite(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+	bool saveNotes(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+
+	void assertInited();
 };
 
-class SaveLoad_v3 : public SaveLoad_v2 {
+enum SaveType {
+	kSaveNone = -1,
+	kSaveGame,
+	kSaveTempSprite,
+	kSaveNotes,
+	kSaveScreenshot,
+	kSaveIgnore
+};
+
+class SaveLoad_v3 : public SaveLoad {
 public:
-	virtual SaveType getSaveType(const char *fileName);
+	enum SaveType {
+		kSaveNone,
+		kSaveGame,
+		kSaveTempSprite,
+		kSaveNotes,
+		kSaveScreenshot
+	};
 
-	SaveLoad_v3(GobEngine *vm, const char *targetName, uint32 screenshotSize = 19968,
+	SaveLoad_v3(GobEngine *vm, const char *targetName,
+			uint32 screenshotSize = 19968,
 			int32 indexOffset = 40, int32 screenshotOffset = 80);
-	virtual ~SaveLoad_v3() {}
+	virtual ~SaveLoad_v3();
 
+	virtual SaveMode getSaveMode(const char *fileName);
+
 protected:
+	struct SaveFile {
+		const char *sourceName;
+		char *destName;
+		SaveMode mode;
+		SaveType type;
+		int slot;
+	};
+
 	bool _useScreenshots;
 	bool _firstSizeGame;
-	int8 _saveSlot;
 
 	uint32 _screenshotSize;
 	int32 _indexOffset;
 	int32 _screenshotOffset;
 
-	virtual uint32 getSaveGameSize();
+	static SaveFile _saveFiles[];
 
-	virtual int32 getSizeGame();
-	virtual int32 getSizeScreenshot();
-	virtual bool loadGame(int16 dataVar, int32 size, int32 offset);
-	virtual bool loadScreenshot(int16 dataVar, int32 size, int32 offset);
-	virtual bool saveGame(int16 dataVar, int32 size, int32 offset);
-	virtual bool saveNotes(int16 dataVar, int32 size, int32 offset);
-	virtual bool saveScreenshot(int16 dataVar, int32 size, int32 offset);
+	int32 _varSize;
 
-	bool saveGame(int32 screenshotSize);
-	void initBuffer();
+	TempSprite _screenshot;
+	TempSprite _tmpSprite;
+	PlainSave _notes;
+	StagedSave _save;
+
+	byte _propBuffer[1000];
+	byte _indexBuffer[1200];
+	bool _hasIndex;
+
+	virtual int getSaveType(const char *fileName);
+
+	virtual int32 getSizeVersioned(int type);
+	virtual bool loadVersioned(int type, int16 dataVar, int32 size, int32 offset);
+	virtual bool saveVersioned(int type, int16 dataVar, int32 size, int32 offset);
+
+	int getSlot(int32 offset) const;
+	int getSlotRemainder(int32 offset) const;
+
+	int32 getSizeGame(SaveFile &saveFile);
+	int32 getSizeTempSprite(SaveFile &saveFile);
+	int32 getSizeNotes(SaveFile &saveFile);
+	int32 getSizeScreenshot(SaveFile &saveFile);
+
+	bool loadGame(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+	bool loadTempSprite(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+	bool loadNotes(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+	bool loadScreenshot(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+
+	bool saveGame(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+	bool saveTempSprite(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+	bool saveNotes(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+	bool saveScreenshot(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
+
+	void assertInited();
+
+	void buildScreenshotIndex(byte *buffer, char *name, int n);
 };
 
+class SaveLoad_v4 : public SaveLoad {
+public:
+	enum SaveType {
+		kSaveNone
+	};
+
+	SaveLoad_v4(GobEngine *vm, const char *targetName);
+	virtual ~SaveLoad_v4();
+
+	virtual SaveMode getSaveMode(const char *fileName);
+
+protected:
+	struct SaveFile {
+		const char *sourceName;
+		char *destName;
+		SaveMode mode;
+		SaveType type;
+	};
+
+	static SaveFile _saveFiles[];
+
+	int32 _varSize;
+
+	virtual int getSaveType(const char *fileName);
+
+	virtual int32 getSizeVersioned(int type);
+	virtual bool loadVersioned(int type, int16 dataVar, int32 size, int32 offset);
+	virtual bool saveVersioned(int type, int16 dataVar, int32 size, int32 offset);
+
+	void assertInited();
+};
+
 } // End of namespace Gob
 
 #endif // GOB_SAVELOAD_H

Modified: scummvm/trunk/engines/gob/saveload_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/saveload_v2.cpp	2008-05-10 19:57:49 UTC (rev 31988)
+++ scummvm/trunk/engines/gob/saveload_v2.cpp	2008-05-10 20:59:43 UTC (rev 31989)
@@ -24,273 +24,346 @@
  */
 
 #include "common/endian.h"
-#include "common/file.h"
+#include "common/savefile.h"
 
 #include "gob/gob.h"
 #include "gob/saveload.h"
 #include "gob/global.h"
 #include "gob/game.h"
+#include "gob/draw.h"
 
 namespace Gob {
 
+SaveLoad_v2::SaveFile SaveLoad_v2::_saveFiles[] = {
+	{  "cat.inf", 0, kSaveModeSave, kSaveGame},
+	{  "cat.cat", 0, kSaveModeSave, kSaveGame},
+	{ "save.inf", 0, kSaveModeSave, kSaveTempSprite},
+	{ "bloc.inf", 0, kSaveModeSave, kSaveNotes}
+};
+
 SaveLoad_v2::SaveLoad_v2(GobEngine *vm, const char *targetName) :
-	SaveLoad(vm, targetName) {
+		SaveLoad(vm, targetName) {
 
-	_stagesCount = 1;
+	_saveFiles[0].destName = new char[strlen(targetName) + 5];
+	_saveFiles[1].destName = _saveFiles[0].destName;
+	_saveFiles[2].destName = 0;
+	_saveFiles[3].destName = new char[strlen(targetName) + 5];
+
+	sprintf(_saveFiles[0].destName, "%s.s00", targetName);
+	sprintf(_saveFiles[3].destName, "%s.blo", targetName);
+
+	_varSize = 0;
+	_hasIndex = false;
 }
 
-SaveType SaveLoad_v2::getSaveType(const char *fileName) {
-	const char *backSlash;
-	if ((backSlash = strrchr(fileName, '\\')))
-		fileName = backSlash + 1;
+SaveLoad_v2::~SaveLoad_v2() {
+	delete[] _saveFiles[0].destName;
+	delete[] _saveFiles[3].destName;
+}
 
-	if (!scumm_stricmp(fileName, "cat.inf"))
-		return kSaveGame;
-	if (!scumm_stricmp(fileName, "cat.cat"))
-		return kSaveGame;
-	if (!scumm_stricmp(fileName, "save.inf"))
-		return kSaveTempSprite;
-	if (!scumm_stricmp(fileName, "bloc.inf"))
-		return kSaveNotes;
+SaveLoad::SaveMode SaveLoad_v2::getSaveMode(const char *fileName) {
+	for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
+		if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))
+			return _saveFiles[i].mode;
 
-	return kSaveNone;
+	return kSaveModeNone;
 }
 
-uint32 SaveLoad_v2::getSaveGameSize() {
-	return 80 + (READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4) * 2;
+int SaveLoad_v2::getSaveType(const char *fileName) {
+	for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
+		if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))
+			return i;
+
+	return -1;
 }
 
-int32 SaveLoad_v2::getSizeNotes() {
-	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
-	Common::InSaveFile *in;
-	int32 size = -1;
+int32 SaveLoad_v2::getSizeVersioned(int type) {
+	assertInited();
 
-	in = saveMan->openForLoading(_saveFiles[(int) kSaveNotes]);
-	if (in) {
-		size = in->size();
-		delete in;
+	switch (_saveFiles[type].type) {
+	case kSaveGame:
+		return getSizeGame(_saveFiles[type]);
+	case kSaveTempSprite:
+		return getSizeTempSprite(_saveFiles[type]);
+	case kSaveNotes:
+		return getSizeNotes(_saveFiles[type]);
 	}
 
-	return size;
+	return -1;
 }
 
-int32 SaveLoad_v2::getSizeGame() {
+bool SaveLoad_v2::loadVersioned(int type, int16 dataVar, int32 size, int32 offset) {
+	assertInited();
+
+	switch (_saveFiles[type].type) {
+	case kSaveGame:
+		if (loadGame(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While loading from slot %d", getSlot(offset));
+		break;
+
+	case kSaveTempSprite:
+		if(loadTempSprite(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While loading the temporary sprite");
+		break;
+
+	case kSaveNotes:
+		if (loadNotes(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While loading the notes");
+		break;
+	}
+
+	return false;
+}
+
+bool SaveLoad_v2::saveVersioned(int type, int16 dataVar, int32 size, int32 offset) {
+	assertInited();
+
+	switch (_saveFiles[type].type) {
+	case kSaveGame:
+		if (saveGame(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While saving to slot %d", getSlot(offset));
+		break;
+
+	case kSaveTempSprite:
+		if(saveTempSprite(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While saving the temporary sprite");
+		break;
+
+	case kSaveNotes:
+		if (saveNotes(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While saving the notes");
+		break;
+	}
+
+	return false;
+}
+
+int SaveLoad_v2::getSlot(int32 offset) const {
+	return ((offset - 600) / _varSize);
+}
+
+int SaveLoad_v2::getSlotRemainder(int32 offset) const {
+	return ((offset - 600) % _varSize);
+}
+
+int32 SaveLoad_v2::getSizeGame(SaveFile &saveFile) {
 	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
 	Common::InSaveFile *in;
 
 	for (int i = 14; i >= 0; i--) {
-		in = saveMan->openForLoading(setCurSlot(i));
+		in = saveMan->openForLoading(setCurrentSlot(saveFile.destName, i));
 		if (in) {
 			delete in;
-			return (i + 1) * READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) *
-				4 + 600;
+			return (i + 1) * _varSize + 600;
 		}
 	}
 
 	return -1;
 }
 
-int32 SaveLoad_v2::getSizeScreenshot() {
-	return -1;
+int32 SaveLoad_v2::getSizeTempSprite(SaveFile &saveFile) {
+	return _tmpSprite.getSize();
 }
 
-bool SaveLoad_v2::loadGame(int16 dataVar, int32 size, int32 offset) {
+int32 SaveLoad_v2::getSizeNotes(SaveFile &saveFile) {
 	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
 	Common::InSaveFile *in;
-	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+	int32 size = -1;
 
+	in = saveMan->openForLoading(saveFile.destName);
+	if (in) {
+		size = in->size();
+		delete in;
+	}
+
+	return size;
+}
+
+bool SaveLoad_v2::loadGame(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
+
 	if (size == 0) {
 		dataVar = 0;
-		size = varSize;
+		size = _varSize;
 	}
 
-	int slot = (offset - 600) / varSize;
-	int slotR = (offset - 600) % varSize;
+	if (offset == 0) {
+		debugC(3, kDebugSaveLoad, "Loading save index");
 
-	if ((offset == 0) && (size == 600)) {
+		if (size != 600) {
+			warning("Requested index has wrong size (%d)", size);
+			return false;
+		}
 
-		byte *varBuf = _vm->_global->_inter_variables + dataVar;
-		for (int i = 0; i < 15; i++, varBuf += 40) {
-			in = saveMan->openForLoading(setCurSlot(i));
-			if (in) {
-				in->read(varBuf, 40);
-				delete in;
-			} else
-				memset(varBuf, 0, 40);
-		}
+		SaveLoad::buildIndex(_vm->_global->_inter_variables + dataVar,
+				saveFile.destName, 15, 40);
 		memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 600);
-		return true;
 
-	} else if ((offset > 0) && (slot < 15) &&
-			(slotR == 0) && (size == varSize)) {
+	} else {
+		int slot = getSlot(offset);
+		int slotRem = getSlotRemainder(offset);
 
-		in = saveMan->openForLoading(setCurSlot(slot));
-		if (!in) {
-			warning("Can't open file for slot %d", slot);
+		debugC(2, kDebugSaveLoad, "Loading from slot %d", slot); 
+
+		SaveLoad::setCurrentSlot(saveFile.destName, slot);
+
+		if ((slot >= 15) || (slotRem != 0)) {
+			warning("Invalid loading procedure (%d, %d, %d, %d, %d)",
+					dataVar, size, offset, slot, slotRem);
 			return false;
 		}
 
-		uint32 sGameSize = getSaveGameSize();
-		uint32 fSize = in->size();
-		if (fSize != sGameSize) {
-			warning("Can't load from slot %d: Wrong size (%d, %d)", slot,
-					fSize, sGameSize);
-			delete in;
+		if (!_save.load(dataVar, size, 40, saveFile.destName,
+					_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes))
 			return false;
-		}
+	}
 
-		in->seek(80);
-		if (loadDataEndian(*in, dataVar, size)) {
-			delete in;
-			debugC(1, kDebugFileIO, "Loading from slot %d", slot);
-			return true;
-		}
-		delete in;
+	return true;
+}
 
-	} else
-		warning("Invalid loading procedure (%d, %d, %d, %d)",
-				offset, size, slot, slotR);
+bool SaveLoad_v2::loadTempSprite(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
 
-	return false;
-}
+	debugC(3, kDebugSaveLoad, "Loading from the temporary sprite");
 
-bool SaveLoad_v2::loadNotes(int16 dataVar, int32 size, int32 offset) {
-	bool retVal;
+	int index;
+	bool palette;
 
-	if ((size <= 0) || (offset != 0)) {
-		warning("Invalid attempt at loading the notes (%d, %d)", size, offset);
+	if (!_tmpSprite.getProperties(dataVar, size, offset, index, palette))
 		return false;
-	}
 
-	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
-	char *sName = _saveFiles[(int) kSaveNotes];
+	if (!_tmpSprite.loadSprite(*_vm->_draw->_spritesArray[index]))
+		return false;
 
-	Common::InSaveFile *in = saveMan->openForLoading(sName);
-	if (!in) {
-		warning("Can't open file \"%s\" for reading", sName);
-		return false;
+	if (palette) {
+		if (!_tmpSprite.loadPalette(_vm->_global->_pPaletteDesc->vgaPal))
+			return false;
+
+		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
 	}
 
-	retVal = loadDataEndian(*in, dataVar, size);
-	delete in;
-	return retVal;
+	if (index == 21) {
+		_vm->_draw->forceBlit();
+		_vm->_video->retrace();
+	}
+
+	return true;
 }
 
-bool SaveLoad_v2::loadScreenshot(int16 dataVar, int32 size, int32 offset) {
-	return false;
+bool SaveLoad_v2::loadNotes(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
+
+	debugC(2, kDebugSaveLoad, "Loading the notes");
+
+	return _notes.load(dataVar, size, offset, saveFile.destName,
+			_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes);
 }
 
-bool SaveLoad_v2::saveGame(int16 dataVar, int32 size, int32 offset) {
-	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+bool SaveLoad_v2::saveGame(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
 
-	initBuffer();
-
 	if (size == 0) {
 		dataVar = 0;
-		size = varSize;
+		size = _varSize;
 	}
 
-	int slot = (offset - 600) / varSize;
-	int slotR = (offset - 600) % varSize;
+	if (offset == 0) {
+		debugC(3, kDebugSaveLoad, "Saving save index");
 
-	if ((offset == 0) && (size == 600)) {
+		if (size != 600) {
+			warning("Requested index has wrong size (%d)", size);
+			return false;
+		}
 
-		delete[] _buffer[0];
-		_buffer[0] = new byte[1200];
-		assert(_buffer[0]);
+		memcpy(_indexBuffer, _vm->_global->_inter_variables + dataVar, 600);
+		_hasIndex = true;
 
-		memcpy(_buffer[0], _vm->_global->_inter_variables + dataVar, 600);
-		memset(_buffer[0] + 600, 0, 600);
+	} else {
+		int slot = getSlot(offset);
+		int slotRem = getSlotRemainder(offset);
 
-		return true;
+		debugC(2, kDebugSaveLoad, "Saving to slot %d", slot);
 
-	} else if ((offset > 0) && (slot < 15) &&
-			(slotR == 0) && (size == varSize)) {
+		SaveLoad::setCurrentSlot(saveFile.destName, slot);
 
-		if (!_buffer[0]) {
-			warning("Tried to save without writing the index first");
+		if ((slot >= 15) || (slotRem != 0)) {
+			warning("Invalid saving procedure (%d, %d, %d, %d, %d)",
+					dataVar, size, offset, slot, slotRem);
 			return false;
 		}
 
-		Common::SaveFileManager *saveMan = g_system->getSavefileManager();
-		Common::OutSaveFile *out;
-
-		out = saveMan->openForSaving(setCurSlot(slot));
-		if (!out) {
-			warning("Can't open file for slot %d for writing", slot);
-			delete[] _buffer[0];
-			_buffer[0] = 0;
+		if (!_hasIndex) {
+			warning("No index written yet");
 			return false;
 		}
 
-		bool retVal = false;
+		_hasIndex = false;
 
-		if (out->write(_buffer[0] + slot * 40, 40) == 40)
-			if (out->write(_buffer[0] + 600 + slot * 40, 40) == 40)
-				if (saveDataEndian(*out, dataVar, size)) {
-					out->finalize();
-					if (!out->ioFailed())
-						retVal = true;
-				}
+		byte sizes[40];
+		memset(sizes, 0, 40);
+		if(!_save.save(0, 40, 0, saveFile.destName, _indexBuffer + (slot * 40), sizes))
+			return false;
 
-		if (!retVal)
-			warning("Can't save to slot %d", slot);
-		else
-			debugC(1, kDebugFileIO, "Saved to slot %d", slot);
+		if (!_save.save(dataVar, size, 40, saveFile.destName,
+					_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes))
+			return false;
 
-		delete[] _buffer[0];
-		_buffer[0] = 0;
-		delete out;
+	}
 
-		return retVal;
+	return true;
+}
 
-	} else
-		warning("Invalid saving procedure (%d, %d, %d, %d)",
-				offset, size, slot, slotR);
+bool SaveLoad_v2::saveTempSprite(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
 
-	return false;
-}
+	debugC(3, kDebugSaveLoad, "Saving to the temporary sprite");
 
-bool SaveLoad_v2::saveNotes(int16 dataVar, int32 size, int32 offset) {
-	bool retVal;
+	int index;
+	bool palette;
 
-	if ((size <= 0) || (offset != 0)) {
-		warning("Invalid attempt at saving the notes (%d, %d)", size, offset);
+	if (!_tmpSprite.getProperties(dataVar, size, offset, index, palette))
 		return false;
-	}
 
-	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
-	char *sName = _saveFiles[(int) kSaveNotes];
-
-	Common::OutSaveFile *out = saveMan->openForSaving(sName);
-	if (!out) {
-		warning("Can't open file \"%s\" for writing", sName);
+	if (!_tmpSprite.saveSprite(*_vm->_draw->_spritesArray[index]))
 		return false;
-	}
 
-	retVal = saveDataEndian(*out, dataVar, size);
+	if (palette)
+		if (!_tmpSprite.savePalette(_vm->_global->_pPaletteDesc->vgaPal))
+			return false;
 
-	out->finalize();
-	if (out->ioFailed()) {
-		warning("Can't save notes");
-		retVal = false;
-	}
-
-	delete out;
-	return retVal;
+	return true;
 }
 
-bool SaveLoad_v2::saveScreenshot(int16 dataVar, int32 size, int32 offset) {
+bool SaveLoad_v2::saveNotes(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
+
+	debugC(2, kDebugSaveLoad, "Saving the notes");
+
+	return _notes.save(dataVar, size, offset, saveFile.destName,
+			_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes);
 	return false;
 }
 
-void SaveLoad_v2::initBuffer() {
-	if (_buffer)
+void SaveLoad_v2::assertInited() {
+	if (_varSize > 0)
 		return;
 
-	_buffer = new byte*[_stagesCount];
-	assert(_buffer);
-	_buffer[0] = 0;
+	_varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+
+	_save.addStage(40);
+	_save.addStage(_varSize);
 }
 
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/saveload_v3.cpp
===================================================================
--- scummvm/trunk/engines/gob/saveload_v3.cpp	2008-05-10 19:57:49 UTC (rev 31988)
+++ scummvm/trunk/engines/gob/saveload_v3.cpp	2008-05-10 20:59:43 UTC (rev 31989)
@@ -24,62 +24,178 @@
  */
 
 #include "common/endian.h"
-#include "common/file.h"
+#include "common/savefile.h"
 
 #include "gob/gob.h"
 #include "gob/saveload.h"
 #include "gob/global.h"
 #include "gob/game.h"
+#include "gob/draw.h"
 
 namespace Gob {
 
+SaveLoad_v3::SaveFile SaveLoad_v3::_saveFiles[] = {
+	{    "cat.inf", 0, kSaveModeSave,   kSaveGame,       -1},
+	{    "ima.inf", 0, kSaveModeSave,   kSaveScreenshot, -1},
+	{  "intro.$$$", 0, kSaveModeSave,   kSaveTempSprite, -1},
+	{   "bloc.inf", 0, kSaveModeSave,   kSaveNotes,      -1},
+	{   "prot",     0, kSaveModeIgnore, kSaveNone,       -1},
+	{ "config",     0, kSaveModeIgnore, kSaveNone,       -1},
+};
+
 SaveLoad_v3::SaveLoad_v3(GobEngine *vm, const char *targetName,
 		uint32 screenshotSize, int32 indexOffset, int32 screenshotOffset) :
-	SaveLoad_v2(vm, targetName) {
+	SaveLoad(vm, targetName) {
 
 	_screenshotSize = screenshotSize;
 	_indexOffset = indexOffset;
 	_screenshotOffset = screenshotOffset;
 
-	_saveSlot = -1;
-	_stagesCount = 3;
-
 	_useScreenshots = false;
 	_firstSizeGame = true;
+
+	_saveFiles[0].destName = new char[strlen(targetName) + 5];
+	_saveFiles[1].destName = _saveFiles[0].destName;
+	_saveFiles[2].destName = 0;
+	_saveFiles[3].destName = new char[strlen(targetName) + 5];
+	_saveFiles[4].destName = 0;
+	_saveFiles[5].destName = 0;
+
+	sprintf(_saveFiles[0].destName, "%s.s00", targetName);
+	sprintf(_saveFiles[3].destName, "%s.blo", targetName);
+
+	_varSize = 0;
+	_hasIndex = false;
+	memset(_propBuffer, 0, 1000);
 }
 
-SaveType SaveLoad_v3::getSaveType(const char *fileName) {
-	const char *backSlash;
-	if ((backSlash = strrchr(fileName, '\\')))
-		fileName = backSlash + 1;
+SaveLoad_v3::~SaveLoad_v3() {
+	delete[] _saveFiles[0].destName;
+	delete[] _saveFiles[3].destName;
+}
 
-	if (!scumm_stricmp(fileName, "cat.inf"))
-		return kSaveGame;
-	if (!scumm_stricmp(fileName, "ima.inf"))
-		return kSaveScreenshot;
-	if (!scumm_stricmp(fileName, "intro.$$$"))
-		return kSaveTempSprite;
-	if (!scumm_stricmp(fileName, "bloc.inf"))
-		return kSaveNotes;
-	if (!scumm_stricmp(fileName, "prot"))
-		return kSaveIgnore;
-	if (!scumm_stricmp(fileName, "config"))
-		return kSaveIgnore;
+SaveLoad::SaveMode SaveLoad_v3::getSaveMode(const char *fileName) {
+	for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
+		if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))
+			return _saveFiles[i].mode;
 
-	return kSaveNone;
+	return kSaveModeNone;
 }
 
-uint32 SaveLoad_v3::getSaveGameSize() {
-	uint32 size;
+int SaveLoad_v3::getSaveType(const char *fileName) {
+	for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
+		if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))
+			return i;
 
-	size = 1040 + (READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4) * 2;
-	if (_useScreenshots)
-		size += _screenshotSize;
+	return -1;
+}
 
-	return size;
+int32 SaveLoad_v3::getSizeVersioned(int type) {
+	assertInited();
+
+	switch (_saveFiles[type].type) {
+	case kSaveGame:
+		return getSizeGame(_saveFiles[type]);
+	case kSaveTempSprite:
+		return getSizeTempSprite(_saveFiles[type]);
+	case kSaveNotes:
+		return getSizeNotes(_saveFiles[type]);
+	case kSaveScreenshot:
+		return getSizeScreenshot(_saveFiles[type]);
+	default:
+		break;
+	}
+
+	return -1;
 }
 
-int32 SaveLoad_v3::getSizeGame() {
+bool SaveLoad_v3::loadVersioned(int type, int16 dataVar, int32 size, int32 offset) {
+	assertInited();
+
+	switch (_saveFiles[type].type) {
+	case kSaveGame:
+		if (loadGame(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While loading from slot %d", getSlot(offset));
+		break;
+
+	case kSaveTempSprite:
+		if(loadTempSprite(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While loading the temporary sprite");
+		break;
+
+	case kSaveNotes:
+		if (loadNotes(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While loading the notes");
+		break;
+
+	case kSaveScreenshot:
+		if (loadScreenshot(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While loading a screenshot");
+		break;
+
+	default:
+		break;
+	}
+
+	return false;
+}
+
+bool SaveLoad_v3::saveVersioned(int type, int16 dataVar, int32 size, int32 offset) {
+	assertInited();
+
+	switch (_saveFiles[type].type) {
+	case kSaveGame:
+		if (saveGame(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While saving to slot %d", getSlot(offset));
+		break;
+
+	case kSaveTempSprite:
+		if(saveTempSprite(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While saving the temporary sprite");
+		break;
+
+	case kSaveNotes:
+		if (saveNotes(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While saving the notes");
+		break;
+
+	case kSaveScreenshot:
+		if (saveScreenshot(_saveFiles[type], dataVar, size, offset))
+			return true;
+
+		warning("While saving a screenshot");
+		break;
+
+	default:
+		break;
+	}
+
+	return false;
+}
+
+int SaveLoad_v3::getSlot(int32 offset) const {
+	return ((offset - 1700) / _varSize);
+}
+
+int SaveLoad_v3::getSlotRemainder(int32 offset) const {
+	return ((offset - 1700) % _varSize);
+}
+
+int32 SaveLoad_v3::getSizeGame(SaveFile &saveFile) {
 	if (_firstSizeGame) {
 		_firstSizeGame = false;
 		return -1;
@@ -89,358 +205,413 @@
 	Common::InSaveFile *in;
 	int32 size = -1;
 
-	int slot = _curSlot;
+	int slot = saveFile.slot;
 	for (int i = 29; i >= 0; i--) {
-		in = saveMan->openForLoading(setCurSlot(i));
+		in = saveMan->openForLoading(setCurrentSlot(saveFile.destName, i));
 		if (in) {
 			delete in;
-			size = (i + 1) * READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) *
-				4 + 1700;
+			size = (i + 1) * _varSize + 1700;
 			break;
 		}
 	}
-	setCurSlot(slot);
+	setCurrentSlot(saveFile.destName, slot);
 
 	return size;
 }
 
-int32 SaveLoad_v3::getSizeScreenshot() {
+int32 SaveLoad_v3::getSizeTempSprite(SaveFile &saveFile) {
+	return _tmpSprite.getSize();
+}
+
+int32 SaveLoad_v3::getSizeNotes(SaveFile &saveFile) {
 	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
 	Common::InSaveFile *in;
 	int32 size = -1;
 
-	_useScreenshots = true;
-	int slot = _curSlot;
+	in = saveMan->openForLoading(saveFile.destName);
+	if (in) {
+		size = in->size();
+		delete in;
+	}
+
+	return size;
+}
+
+int32 SaveLoad_v3::getSizeScreenshot(SaveFile &saveFile) {
+	if (!_useScreenshots) {
+		_useScreenshots = true;
+		_save.addStage(_screenshotSize, false);
+	}
+
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
+	int32 size = -1;
+
+	int slot = saveFile.slot;
 	for (int i = 29; i >= 0; i--) {
-		in = saveMan->openForLoading(setCurSlot(i));
+		in = saveMan->openForLoading(setCurrentSlot(saveFile.destName, i));
 		if (in) {
 			delete in;
 			size = (i + 1) * _screenshotSize + _screenshotOffset;
 			break;
 		}
 	}
-	setCurSlot(slot);
+	setCurrentSlot(saveFile.destName, slot);
 
 	return size;
 }
 
-bool SaveLoad_v3::loadGame(int16 dataVar, int32 size, int32 offset) {
-	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
-	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
-	Common::InSaveFile *in;
+bool SaveLoad_v3::loadGame(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
 
-	int slot = (offset - 1700) / varSize;
-	int slotR = (offset - 1700) % varSize;
+	if (size == 0) {
+		dataVar = 0;
+		size = _varSize;
+	}
 
-	initBuffer();
+	if (offset < 500) {
+		debugC(3, kDebugSaveLoad, "Loading global properties");
 
-	if ((size > 0) && (offset < 500) && ((size + offset) <= 500)) {
+		if ((size + offset) > 500) {
+			warning("Wrong global properties list size (%d, %d)", size, offset);
+			return false;
+		}
 
 		memcpy(_vm->_global->_inter_variables + dataVar,
-				_buffer[0] + offset, size);
+				_propBuffer + offset, size);
 		memcpy(_vm->_global->_inter_variablesSizes + dataVar,
-				_buffer[0] + offset + 500, size);
-		return true;
+				_propBuffer + offset + 500, size);
 
-	} else if ((size == 1200) && (offset == 500)) {
+	} else if (offset == 500) {
+		debugC(3, kDebugSaveLoad, "Loading save index");
 
-		memset(_buffer[1], 0, 1200);
-
-		slot = _curSlot;
-		for (int i = 0; i < 30; i++) {
-			in = saveMan->openForLoading(setCurSlot(i));
-			if (in) {
-				in->seek(1000);
-				in->read(_buffer[1] + i * 40, 40);
-				delete in;
-			}
+		if (size != 1200) {
+			warning("Requested index has wrong size (%d)", size);
+			return false;
 		}
-		setCurSlot(slot);
 
-		memcpy(_vm->_global->_inter_variables + dataVar, _buffer[1], 1200);
+		int slot = saveFile.slot;
+
+		SaveLoad::buildIndex(_vm->_global->_inter_variables + dataVar,
+				saveFile.destName, 30, 40, 1000);
 		memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 1200);
-		return true;
 
-	} else if ((offset > 0) && (slot < 30) &&
-			(slotR == 0) && (size == 0)) {
+		setCurrentSlot(saveFile.destName, slot);
 
-		in = saveMan->openForLoading(setCurSlot(slot));
-		if (!in) {
-			warning("Can't open file for slot %d", slot);
+	} else {
+		saveFile.slot = getSlot(offset);
+		int slotRem = getSlotRemainder(offset);
+
+		debugC(2, kDebugSaveLoad, "Loading from slot %d", saveFile.slot); 
+
+		SaveLoad::setCurrentSlot(saveFile.destName, saveFile.slot);
+
+		if ((saveFile.slot < 0) || (saveFile.slot >= 30) || (slotRem != 0)) {
+			warning("Invalid loading procedure (%d, %d, %d, %d, %d)",
+					dataVar, size, offset, saveFile.slot, slotRem);
 			return false;
 		}
 
-		uint32 sGameSize = getSaveGameSize();
-		uint32 fSize = in->size();
-		if (fSize != sGameSize) {
-			warning("Can't load from slot %d: Wrong size (%d, %d)", slot,
-					fSize, sGameSize);
-			delete in;
+		if (!_save.load(dataVar, size, 540, saveFile.destName,
+					_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes))
 			return false;
-		}
+	}
 
-		byte varBuf[500], sizeBuf[500];
-		if (read(*in, varBuf, sizeBuf, 500) == 500) {
-			if (fromEndian(varBuf, sizeBuf, 500)) {
-				memcpy(_buffer[0], varBuf, 500);
-				memcpy(_buffer[0] + 500, sizeBuf, 500);
-				in->seek(1040);
-				if (loadDataEndian(*in, 0, varSize)) {
-					delete in;
-					debugC(1, kDebugFileIO, "Loading from slot %d", slot);
-					return true;
-				}
-			}
-		}
-		delete in;
+	return true;
+}
 
-	} else
-		warning("Invalid loading procedure (%d, %d, %d, %d)",
-				offset, size, slot, slotR);
+bool SaveLoad_v3::loadTempSprite(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
 
-	return false;
+	debugC(3, kDebugSaveLoad, "Loading from the temporary sprite");
+
+	int index;
+	bool palette;
+
+	if (!_tmpSprite.getProperties(dataVar, size, offset, index, palette))
+		return false;
+
+	if (!_tmpSprite.loadSprite(*_vm->_draw->_spritesArray[index]))
+		return false;
+
+	if (palette) {
+		if (!_tmpSprite.loadPalette(_vm->_global->_pPaletteDesc->vgaPal))
+			return false;
+
+		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+	}
+
+	if (index == 21) {
+		_vm->_draw->forceBlit();
+		_vm->_video->retrace();
+	}
+
+	return true;
 }
 
-bool SaveLoad_v3::loadScreenshot(int16 dataVar, int32 size, int32 offset) {
-	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
-	Common::InSaveFile *in;
+bool SaveLoad_v3::loadNotes(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
 
-	int slot = (offset - _screenshotOffset) / _screenshotSize;
-	int slotR = (offset - _screenshotOffset) % _screenshotSize;
+	debugC(2, kDebugSaveLoad, "Loading the notes");
 
-	_useScreenshots = true;
-	if ((size == 40) && (offset == _indexOffset)) {
-		char buf[40];
+	return _notes.load(dataVar, size, offset, saveFile.destName,
+			_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes);
+}
 
-		memset(buf, 0, 40);
+bool SaveLoad_v3::loadScreenshot(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
 
-		slot = _curSlot;
-		for (int i = 0; i < 30; i++) {
-			in = saveMan->openForLoading(setCurSlot(i));
-			if (in) {
-				delete in;
-				buf[i] = 1;
-			}
+	debugC(3, kDebugSaveLoad, "Loading a screenshot");
+
+	if (!_useScreenshots) {
+		_useScreenshots = true;
+		_save.addStage(_screenshotSize, false);
+	}
+
+	if (offset == _indexOffset) {
+		if (size != 40) {
+			warning("Requested index has wrong size (%d)", size);
+			return false;
 		}
-		setCurSlot(slot);
 
-		memcpy(_vm->_global->_inter_variables + dataVar, buf, 40);
+		byte buffer[40];
+		memset(buffer, 0, 40);
+
+		int slot = saveFile.slot;
+		buildScreenshotIndex(buffer, saveFile.destName, 30);
+		setCurrentSlot(saveFile.destName, slot);
+
+		memcpy(_vm->_global->_inter_variables + dataVar, buffer, 40);
 		memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 40);
-		return true;
 
-	} else if ((offset > 0) && (slot < 30) &&
-			(slotR == 0) && (size < 0)) {
+	} else {
+		saveFile.slot = (offset - _screenshotOffset) / _screenshotSize;
+		int slotRem = (offset - _screenshotOffset) % _screenshotSize;
 
-		int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+		SaveLoad::setCurrentSlot(saveFile.destName, saveFile.slot);
 
-		in = saveMan->openForLoading(setCurSlot(slot));
-		if (!in) {
-			warning("Can't open file for slot %d", slot);
+		if ((saveFile.slot < 0) || (saveFile.slot >= 30) || (slotRem != 0)) {
+			warning("Invalid loading procedure (%d, %d, %d, %d, %d)",
+					dataVar, size, offset, saveFile.slot, slotRem);
 			return false;
 		}
 
-		uint32 sGameSize = getSaveGameSize();
-		uint32 fSize = in->size();
-		if (fSize != sGameSize) {
-			warning("Can't load screenshot from slot %d: Wrong size (%d, %d)",
-					slot, fSize, sGameSize);
-			delete in;
+		byte *buffer = new byte[_screenshotSize];
+
+		if (!_save.load(0, _screenshotSize, _varSize + 540, saveFile.destName, buffer, 0)) {
+			delete[] buffer;
 			return false;
 		}
 
-		in->seek(1040 + varSize * 2);
+		int index;
+		bool palette;
 
-		bool success = loadSprite(*in, size);
-		delete in;
-		return success;
+		if (!_screenshot.getProperties(dataVar, size, offset, index, palette)) {
+			delete[] buffer;
+			return false;
+		}
 
-	} else
-		warning("Invalid attempt at loading a screenshot (%d, %d, %d, %d)",
-				offset, size, slot, slotR);
+		if (!_screenshot.fromBuffer(buffer, _screenshotSize, palette)) {
+			delete[] buffer;
+			return false;
+		}
 
-	return false;
+		if (!_screenshot.loadSprite(*_vm->_draw->_spritesArray[index])) {
+			delete[] buffer;
+			return false;
+		}
+
+		if (palette) {
+			if (!_screenshot.loadPalette(_vm->_global->_pPaletteDesc->vgaPal)) {
+				delete[] buffer;
+				return false;
+			}
+			_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+		}
+
+		delete[] buffer;
+	}
+
+	return true;
 }
 
-bool SaveLoad_v3::saveGame(int16 dataVar, int32 size, int32 offset) {
-	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+bool SaveLoad_v3::saveGame(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
 
-	int slot = (offset - 1700) / varSize;
-	int slotR = (offset - 1700) % varSize;
+	if (size == 0) {
+		dataVar = 0;
+		size = _varSize;
+	}
 
-	initBuffer();
+	if (offset < 500) {
+		debugC(3, kDebugSaveLoad, "Loading global properties");
 
-	if ((size > 0) && (offset < 500) && ((size + offset) <= 500)) {
+		if ((size + offset) > 500) {
+			warning("Wrong global properties list size (%d, %d)", size, offset);
+			return false;
+		}
 
-		memcpy(_buffer[0] + offset,
+		memcpy(_propBuffer + offset,
 				_vm->_global->_inter_variables + dataVar, size);
-		memcpy(_buffer[0] + offset + 500,
+		memcpy(_propBuffer + offset + 500,
 				_vm->_global->_inter_variablesSizes + dataVar, size);
 
-		return true;
+	} else if (offset == 500) {
+		debugC(3, kDebugSaveLoad, "Saving save index");
 
-	} else if ((size > 0) && (offset >= 500) && (offset < 1700) &&
-			((size + offset) <= 1700)) {
+		if (size != 1200) {
+			warning("Requested index has wrong size (%d)", size);
+			return false;
+		}
 
-		memcpy(_buffer[1] + offset - 500,
-				_vm->_global->_inter_variables + dataVar, size);
+		memcpy(_indexBuffer, _vm->_global->_inter_variables + dataVar, size);
+		_hasIndex = true;
 
-		return true;
+	} else {
+		saveFile.slot = getSlot(offset);
+		int slotRem = getSlotRemainder(offset);
 
-	} else if ((offset > 0) && (slot < 30) &&
-			(slotR == 0) && (size == 0)) {
+		debugC(2, kDebugSaveLoad, "Saving to slot %d", saveFile.slot);
 
-		_saveSlot = -1;
+		SaveLoad::setCurrentSlot(saveFile.destName, saveFile.slot);
 
-		delete _buffer[2];
-		_buffer[2] = new byte[varSize * 2];
-		assert(_buffer[2]);
+		if ((saveFile.slot < 0) || (saveFile.slot >= 30) || (slotRem != 0)) {
+			warning("Invalid saving procedure (%d, %d, %d, %d, %d)",
+					dataVar, size, offset, saveFile.slot, slotRem);
+			return false;
+		}
 
-		memcpy(_buffer[2], _vm->_global->_inter_variables, varSize);
-		memcpy(_buffer[2] + varSize,
-				_vm->_global->_inter_variablesSizes, varSize);
-
-		if (!toEndian(_buffer[2], _buffer[2] + varSize, varSize)) {
-			delete _buffer[2];
-			_buffer[2] = 0;
+		if (!_hasIndex) {
+			warning("No index written yet");
 			return false;
 		}
 
-		_saveSlot = slot;
+		_hasIndex = false;
 
-		if (!_useScreenshots)
-			return saveGame(0);
+		if(!_save.save(0, 500, 0, saveFile.destName, _propBuffer, _propBuffer + 500))
+			return false;
 
-		return true;
+		if(!_save.save(0, 40, 500, saveFile.destName, _indexBuffer + (saveFile.slot * 40), 0))
+			return false;
 
-	} else
-		warning("Invalid saving procedure (%d, %d, %d, %d)",
-				offset, size, slot, slotR);
+		if (!_save.save(dataVar, size, 540, saveFile.destName,
+					_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes))
+			return false;
 
-	return false;
-}
+	}
 
-bool SaveLoad_v3::saveNotes(int16 dataVar, int32 size, int32 offset) {
-	return SaveLoad_v2::saveNotes(dataVar, size - 160, offset);
+	return true;
 }
 
-bool SaveLoad_v3::saveScreenshot(int16 dataVar, int32 size, int32 offset) {
-	int slot = (offset - _screenshotOffset) / _screenshotSize;
-	int slotR = (offset - _screenshotOffset) % _screenshotSize;
+bool SaveLoad_v3::saveTempSprite(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
 
-	_useScreenshots = true;
+	debugC(3, kDebugSaveLoad, "Saving to the temporary sprite");
 
-	if ((offset < _screenshotOffset) && (size > 0)) {
+	int index;
+	bool palette;
 
-		return true;
+	if (!_tmpSprite.getProperties(dataVar, size, offset, index, palette))
+		return false;
 
-	} else if ((offset > 0) && (slot < 30) &&
-			(slotR == 0) && (size < 0)) {
+	if (!_tmpSprite.saveSprite(*_vm->_draw->_spritesArray[index]))
+		return false;
 
-		return saveGame(size);
+	if (palette)
+		if (!_tmpSprite.savePalette(_vm->_global->_pPaletteDesc->vgaPal))
+			return false;
 
-	} else
-		warning("Invalid attempt at saving a screenshot (%d, %d, %d, %d)",
-				offset, size, slot, slotR);
+	return true;
+}
 
+bool SaveLoad_v3::saveNotes(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
+
+	debugC(2, kDebugSaveLoad, "Saving the notes");
+
+	return _notes.save(dataVar, size - 160, offset, saveFile.destName,
+			_vm->_global->_inter_variables, _vm->_global->_inter_variablesSizes);
 	return false;
 }
 
-bool SaveLoad_v3::saveGame(int32 screenshotSize) {
-	int8 slot = _saveSlot;
+bool SaveLoad_v3::saveScreenshot(SaveFile &saveFile,
+		int16 dataVar, int32 size, int32 offset) {
 
-	_saveSlot = -1;
+	debugC(3, kDebugSaveLoad, "Saving a screenshot");
 
-	initBuffer();
-
-	if ((slot < 0) || (slot > 29)) {
-		warning("Can't save to slot %d: Out of range", slot);
-		delete[] _buffer[2];
-		_buffer[2] = 0;
-		return false;
+	if (!_useScreenshots) {
+		_useScreenshots = true;
+		_save.addStage(_screenshotSize, false);
 	}
 
-	if (!_buffer[2]) {
-		warning("Can't save to slot %d: No data", slot);
-		return false;
-	}
+	if (offset >= _screenshotOffset) {
 
-	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
-	Common::OutSaveFile *out;
+		saveFile.slot = (offset - _screenshotOffset) / _screenshotSize;
+		int slotRem = (offset - _screenshotOffset) % _screenshotSize;
 
-	out = saveMan->openForSaving(setCurSlot(slot));
-	if (!out) {
-		warning("Can't open file for slot %d for writing", slot);
-		delete[] _buffer[2];
-		_buffer[2] = 0;
-		return false;
-	}
+		setCurrentSlot(saveFile.destName, saveFile.slot);
 
-	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
-	byte varBuf[500], sizeBuf[500];
+		if ((saveFile.slot < 0) || (saveFile.slot >= 30) || (slotRem != 0)) {
+			warning("Invalid saving procedure (%d, %d, %d, %d, %d)",
+					dataVar, size, offset, saveFile.slot, slotRem);
+			return false;
+		}
 
-	memcpy(varBuf, _buffer[0], 500);
-	memcpy(sizeBuf, _buffer[0] + 500, 500);
+		int index;
+		bool palette;
 
-	bool retVal = false;
-	if (toEndian(varBuf, sizeBuf, 500))
-		if (write(*out, varBuf, sizeBuf, 500) == 500)
-			if (out->write(_buffer[1] + slot * 40, 40) == 40)
-				if (out->write(_buffer[2], varSize * 2) == ((uint32) (varSize * 2))) {
-					out->flush();
-					if (!out->ioFailed())
-						retVal = true;
-				}
+		if (!_screenshot.getProperties(dataVar, size, offset, index, palette))
+			return false;
 
-	delete[] _buffer[2];
-	_buffer[2] = 0;
+		if (!_screenshot.saveSprite(*_vm->_draw->_spritesArray[index]))
+			return false;
 
-	if (!retVal) {
-		warning("Can't save to slot %d", slot);
-		delete out;
-		return false;
-	}
+		if (palette)
+			if (!_screenshot.savePalette(_vm->_global->_pPaletteDesc->vgaPal))
+				return false;
 
-	if (_useScreenshots) {
-		if (screenshotSize >= 0) {
-			warning("Can't save to slot %d: Screenshot expected", slot);
-			delete out;
+		
+		byte *buffer = new byte[_screenshotSize];
+
+		if (!_screenshot.toBuffer(buffer, _screenshotSize, palette)) {
+			delete[] buffer;
 			return false;
 		}
 
-		if (!saveSprite(*out, screenshotSize)) {
-			delete out;
+		if (!_save.save(0, _screenshotSize, _varSize + 540, saveFile.destName, buffer, 0)) {
+			delete[] buffer;
 			return false;
 		}
-	}
 
-	out->finalize();
-	if (out->ioFailed()) {
-		warning("Can't save to slot %d", slot);
-		delete out;
-		return false;
+		delete[] buffer;
 	}
 
-	debugC(1, kDebugFileIO, "Saved to slot %d", slot);
-	delete out;
 	return true;
 }
 
-void SaveLoad_v3::initBuffer() {
-	if (_buffer)
+void SaveLoad_v3::assertInited() {
+	if (_varSize > 0)
 		return;
 
-	_buffer = new byte*[_stagesCount];
+	_varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
 
-	assert(_buffer);
+	_save.addStage(500);
+	_save.addStage(40, false);
+	_save.addStage(_varSize);
+}
 
-	_buffer[0] = new byte[1000];
-	_buffer[1] = new byte[1200];
-	_buffer[2] = 0;
+void SaveLoad_v3::buildScreenshotIndex(byte *buffer, char *name, int n) {
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
 
-	assert(_buffer[0] && _buffer[1]);
-
-	memset(_buffer[0], 0, 1000);
-	memset(_buffer[1], 0, 1200);
+	memset(buffer, 0, n);
+	for (int i = 0; i < n; i++) {
+		in = saveMan->openForLoading(setCurrentSlot(name, i));
+		if (in) {
+			delete in;
+			buffer[i] = 1;
+		}
+	}
 }
 
 } // End of namespace Gob

Added: scummvm/trunk/engines/gob/saveload_v4.cpp
===================================================================
--- scummvm/trunk/engines/gob/saveload_v4.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/saveload_v4.cpp	2008-05-10 20:59:43 UTC (rev 31989)
@@ -0,0 +1,80 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/endian.h"
+
+#include "gob/gob.h"
+#include "gob/saveload.h"
+#include "gob/game.h"
+
+namespace Gob {
+
+SaveLoad_v4::SaveFile SaveLoad_v4::_saveFiles[] = {
+	{ "", 0, kSaveModeNone, kSaveNone }
+};
+
+SaveLoad_v4::SaveLoad_v4(GobEngine *vm, const char *targetName) :
+	SaveLoad(vm, targetName) {
+
+	_varSize = 0;
+}
+
+SaveLoad_v4::~SaveLoad_v4() {
+}
+
+SaveLoad::SaveMode SaveLoad_v4::getSaveMode(const char *fileName) {
+	return kSaveModeNone;
+}
+
+int SaveLoad_v4::getSaveType(const char *fileName) {
+	return -1;
+}
+
+int32 SaveLoad_v4::getSizeVersioned(int type) {
+	assertInited();
+
+	return -1;
+}
+
+bool SaveLoad_v4::loadVersioned(int type, int16 dataVar, int32 size, int32 offset) {
+	assertInited();
+
+	return false;
+}
+
+bool SaveLoad_v4::saveVersioned(int type, int16 dataVar, int32 size, int32 offset) {
+	assertInited();
+
+	return false;
+}
+
+void SaveLoad_v4::assertInited() {
+	if (_varSize > 0)
+		return;
+
+	_varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+}
+
+} // End of namespace Gob


Property changes on: scummvm/trunk/engines/gob/saveload_v4.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native

Modified: scummvm/trunk/engines/gob/video.h
===================================================================
--- scummvm/trunk/engines/gob/video.h	2008-05-10 19:57:49 UTC (rev 31988)
+++ scummvm/trunk/engines/gob/video.h	2008-05-10 20:59:43 UTC (rev 31989)
@@ -37,10 +37,11 @@
 public:
 	int16 _vidMode;
 
-	int16 getWidth() { return _width; }
-	int16 getHeight() { return _height; }
+	int16 getWidth() const { return _width; }
+	int16 getHeight() const { return _height; }
 	byte *getVidMem() { return _vidMem; }
-	bool hasOwnVidMem() { return _ownVidMem; }
+	const byte *getVidMem() const { return _vidMem; }
+	bool hasOwnVidMem() const { return _ownVidMem; }
 
 	void setVidMem(byte *vidMem);
 	void resize(int16 width, int16 height);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list