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

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Sun May 31 04:15:44 CEST 2009


Revision: 41056
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41056&view=rev
Author:   drmccoy
Date:     2009-05-31 02:15:43 +0000 (Sun, 31 May 2009)

Log Message:
-----------
- A new save system for the GobEngine, one that is not fundamentally broken and is versioned. Unfortunately, this invalidates most save games created on big-endian machines, since endian-issues was a main problem with the old system
- Removed the now superfluous variables sizes

Modified Paths:
--------------
    scummvm/trunk/engines/gob/gob.cpp
    scummvm/trunk/engines/gob/gob.h
    scummvm/trunk/engines/gob/helper.h
    scummvm/trunk/engines/gob/inter.cpp
    scummvm/trunk/engines/gob/inter.h
    scummvm/trunk/engines/gob/inter_v1.cpp
    scummvm/trunk/engines/gob/inter_v2.cpp
    scummvm/trunk/engines/gob/map_v2.cpp
    scummvm/trunk/engines/gob/map_v4.cpp
    scummvm/trunk/engines/gob/module.mk
    scummvm/trunk/engines/gob/parse.cpp
    scummvm/trunk/engines/gob/parse_v1.cpp
    scummvm/trunk/engines/gob/parse_v2.cpp
    scummvm/trunk/engines/gob/variables.cpp
    scummvm/trunk/engines/gob/variables.h

Added Paths:
-----------
    scummvm/trunk/engines/gob/save/
    scummvm/trunk/engines/gob/save/saveconverter.cpp
    scummvm/trunk/engines/gob/save/saveconverter.h
    scummvm/trunk/engines/gob/save/saveconverter_v2.cpp
    scummvm/trunk/engines/gob/save/saveconverter_v3.cpp
    scummvm/trunk/engines/gob/save/saveconverter_v4.cpp
    scummvm/trunk/engines/gob/save/saveconverter_v6.cpp
    scummvm/trunk/engines/gob/save/savefile.cpp
    scummvm/trunk/engines/gob/save/savefile.h
    scummvm/trunk/engines/gob/save/savehandler.cpp
    scummvm/trunk/engines/gob/save/savehandler.h
    scummvm/trunk/engines/gob/save/saveload.cpp
    scummvm/trunk/engines/gob/save/saveload.h
    scummvm/trunk/engines/gob/save/saveload_v2.cpp
    scummvm/trunk/engines/gob/save/saveload_v3.cpp
    scummvm/trunk/engines/gob/save/saveload_v4.cpp
    scummvm/trunk/engines/gob/save/saveload_v6.cpp

Removed Paths:
-------------
    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/saveload_v4.cpp
    scummvm/trunk/engines/gob/saveload_v6.cpp

Modified: scummvm/trunk/engines/gob/gob.cpp
===================================================================
--- scummvm/trunk/engines/gob/gob.cpp	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/gob.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -47,7 +47,7 @@
 #include "gob/parse.h"
 #include "gob/scenery.h"
 #include "gob/videoplayer.h"
-#include "gob/saveload.h"
+#include "gob/save/saveload.h"
 
 namespace Gob {
 
@@ -368,7 +368,7 @@
 		_map = new Map_v2(this);
 		_goblin = new Goblin_v3(this);
 		_scenery = new Scenery_v2(this);
-		_saveLoad = new SaveLoad_v3(this, _targetName.c_str());
+		_saveLoad = new SaveLoad_v3(this, _targetName.c_str(), SaveLoad_v3::kScreenshotTypeGob3);
 		break;
 
 	case kGameTypeLostInTime:
@@ -382,7 +382,7 @@
 		_map = new Map_v2(this);
 		_goblin = new Goblin_v3(this);
 		_scenery = new Scenery_v2(this);
-		_saveLoad = new SaveLoad_v3(this, _targetName.c_str(), 4768, 0, 50);
+		_saveLoad = new SaveLoad_v3(this, _targetName.c_str(), SaveLoad_v3::kScreenshotTypeLost);
 		break;
 
 	case kGameTypeWoodruff:
@@ -413,7 +413,7 @@
 		_map = new Map_v4(this);
 		_goblin = new Goblin_v4(this);
 		_scenery = new Scenery_v2(this);
-		_saveLoad = new SaveLoad_v4(this, _targetName.c_str());
+		_saveLoad = new SaveLoad(this, _targetName.c_str());
 		break;
 
 	case kGameTypeAdibou4:

Modified: scummvm/trunk/engines/gob/gob.h
===================================================================
--- scummvm/trunk/engines/gob/gob.h	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/gob.h	2009-05-31 02:15:43 UTC (rev 41056)
@@ -65,8 +65,8 @@
 #define READ_VARO_UINT32(off)       _vm->_inter->_variables->readOff32(off)
 #define READ_VARO_UINT16(off)       _vm->_inter->_variables->readOff16(off)
 #define READ_VARO_UINT8(off)        _vm->_inter->_variables->readOff8(off)
-#define GET_VAR_STR(var)            _vm->_inter->_variables->getAddressVarString(var, 0)
-#define GET_VARO_STR(off)           _vm->_inter->_variables->getAddressOffString(off, 0)
+#define GET_VAR_STR(var)            _vm->_inter->_variables->getAddressVarString(var)
+#define GET_VARO_STR(off)           _vm->_inter->_variables->getAddressOffString(off)
 #define GET_VAR_FSTR(var)           _vm->_inter->_variables->getAddressVarString(var)
 #define GET_VARO_FSTR(off)          _vm->_inter->_variables->getAddressOffString(off)
 
@@ -78,11 +78,14 @@
 #define VAR(var)                    READ_VAR_UINT32(var)
 
 
+// WARNING: Reordering these will invalidate save games!
 enum Endianness {
 	kEndiannessLE,
 	kEndiannessBE
 };
 
+// WARNING: Reordering these will invalidate save games!
+//          Add new games to the bottom of the list.
 enum GameType {
 	kGameTypeNone = 0,
 	kGameTypeGob1,

Modified: scummvm/trunk/engines/gob/helper.h
===================================================================
--- scummvm/trunk/engines/gob/helper.h	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/helper.h	2009-05-31 02:15:43 UTC (rev 41056)
@@ -49,6 +49,22 @@
 	return nstr;
 }
 
+/** A strcat that new[]s the buffer. */
+inline char *strdupcat(const char *str1, const char *str2) {
+	if (!str1 || !str2)
+		return 0;
+
+	size_t len1 = strlen(str1);
+	size_t len2 = strlen(str2);
+
+	char *nstr = new char[len1 + len2 + 1];
+
+	memcpy(nstr, str1, len1);
+	memcpy(nstr + len1, str2, len2 + 1);
+
+	return nstr;
+}
+
 /** A "smart" reference counting templated class. */
 template<typename T>
 class ReferenceCounter {

Modified: scummvm/trunk/engines/gob/inter.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter.cpp	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/inter.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -56,7 +56,6 @@
 	_soundStopVal = 0;
 
 	memset(_varStack, 0, 300);
-	memset(_varSizesStack, 0, 300);
 	_varStackPos = 0;
 
 	_noBusyWait = false;

Modified: scummvm/trunk/engines/gob/inter.h
===================================================================
--- scummvm/trunk/engines/gob/inter.h	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/inter.h	2009-05-31 02:15:43 UTC (rev 41056)
@@ -92,7 +92,6 @@
 	int16 _animPalDir[8];
 
 	byte _varStack[300];
-	byte _varSizesStack[300];
 	int16 _varStackPos;
 
 	// The busy-wait detection in o1_keyFunc breaks fast scrolling in Ween

Modified: scummvm/trunk/engines/gob/inter_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v1.cpp	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/inter_v1.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -948,8 +948,7 @@
 			_vm->_mult->_objects[i].pPosY = new VariableReference(*_vm->_inter->_variables, offPosY);
 
 			_vm->_mult->_objects[i].pAnimData =
-				(Mult::Mult_AnimData *) _variables->getAddressOff8(offAnim,
-						_vm->_global->_inter_animDataSize);
+				(Mult::Mult_AnimData *) _variables->getAddressOff8(offAnim);
 
 			_vm->_mult->_objects[i].pAnimData->isStatic = 1;
 			_vm->_mult->_objects[i].tick = 0;
@@ -2234,7 +2233,7 @@
 		if (((dataVar >> 2) == 59) && (size == 4))
 			WRITE_VAR(59, stream->readUint32LE());
 		else
-			retSize = stream->read((byte *) _variables->getAddressOff8(dataVar, size), size);
+			retSize = stream->read((byte *) _variables->getAddressOff8(dataVar), size);
 
 		if (retSize == size)
 			WRITE_VAR(1, 0);

Modified: scummvm/trunk/engines/gob/inter_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v2.cpp	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/inter_v2.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -42,7 +42,7 @@
 #include "gob/parse.h"
 #include "gob/scenery.h"
 #include "gob/video.h"
-#include "gob/saveload.h"
+#include "gob/save/saveload.h"
 #include "gob/videoplayer.h"
 #include "gob/sound/sound.h"
 
@@ -890,8 +890,7 @@
 			_vm->_mult->_objects[i].pPosY = new VariableReference(*_vm->_inter->_variables, offPosY);
 
 			_vm->_mult->_objects[i].pAnimData =
-				(Mult::Mult_AnimData *) _variables->getAddressOff8(offAnim,
-						_vm->_global->_inter_animDataSize);
+				(Mult::Mult_AnimData *) _variables->getAddressOff8(offAnim);
 
 			_vm->_mult->_objects[i].pAnimData->isStatic = 1;
 			_vm->_mult->_objects[i].tick = 0;
@@ -1162,23 +1161,18 @@
 			varOff = _vm->_parse->parseVarIndex();
 			_vm->_global->_inter_execPtr++;
 
-			_variables->copyTo(varOff, _varStack + _varStackPos,
-					_varSizesStack + _varStackPos,
-					_vm->_global->_inter_animDataSize * 4);
+			_variables->copyTo(varOff, _varStack + _varStackPos, _vm->_global->_inter_animDataSize * 4);
 
 			_varStackPos += _vm->_global->_inter_animDataSize * 4;
 			_varStack[_varStackPos] = _vm->_global->_inter_animDataSize * 4;
-			_varSizesStack[_varStackPos] = _vm->_global->_inter_animDataSize * 4;
 
 		} else {
 			if (evalExpr(&varOff) != 20)
 				_vm->_global->_inter_resVal = 0;
 
 			memcpy(_varStack + _varStackPos, &_vm->_global->_inter_resVal, 4);
-			memcpy(_varSizesStack + _varStackPos, &_vm->_global->_inter_resVal, 4);
 			_varStackPos += 4;
 			_varStack[_varStackPos] = 4;
-			_varSizesStack[_varStackPos] = 4;
 		}
 	}
 }
@@ -1186,19 +1180,15 @@
 void Inter_v2::o2_popVars() {
 	byte count;
 	int16 varOff;
-	int16 sizeV;
-	int16 sizeS;
+	int16 size;
 
 	count = *_vm->_global->_inter_execPtr++;
 	for (int i = 0; i < count; i++) {
 		varOff = _vm->_parse->parseVarIndex();
-		sizeV = _varStack[--_varStackPos];
-		sizeS = _varSizesStack[_varStackPos];
-		assert(sizeV == sizeS);
+		size = _varStack[--_varStackPos];
 
-		_varStackPos -= sizeV;
-		_variables->copyFrom(varOff, _varStack + _varStackPos,
-				_varSizesStack + _varStackPos, sizeV);
+		_varStackPos -= size;
+		_variables->copyFrom(varOff, _varStack + _varStackPos, size);
 	}
 }
 
@@ -1934,7 +1924,7 @@
 		size = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
 	}
 
-	buf = _variables->getAddressOff8(dataVar, size);
+	buf = _variables->getAddressOff8(dataVar);
 
 	if (_vm->_global->_inter_resStr[0] == 0) {
 		WRITE_VAR(1, size);

Modified: scummvm/trunk/engines/gob/map_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/map_v2.cpp	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/map_v2.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -56,12 +56,12 @@
 	uint32 passPos;
 
 	var = _vm->_parse->parseVarIndex();
-	variables = _vm->_inter->_variables->getAddressOff8(var, 0);
+	variables = _vm->_inter->_variables->getAddressOff8(var);
 
 	id = _vm->_inter->load16();
 
 	if (id == -1) {
-		_passMap = (int8 *) _vm->_inter->_variables->getAddressOff8(var, 0);
+		_passMap = (int8 *) _vm->_inter->_variables->getAddressOff8(var);
 		return;
 	}
 
@@ -105,7 +105,7 @@
 	tmpPos = mapData.pos();
 	mapData.seek(passPos);
 	if ((variables != 0) &&
-	    (variables != _vm->_inter->_variables->getAddressOff8(0, 0))) {
+	    (variables != _vm->_inter->_variables->getAddressOff8(0))) {
 
 		_passMap = (int8 *) variables;
 		mapHeight = _screenHeight / _tilesHeight;
@@ -114,7 +114,7 @@
 		for (int i = 0; i < mapHeight; i++) {
 			for (int j = 0; j < mapWidth; j++)
 				setPass(j, i, mapData.readSByte());
-			_vm->_inter->_variables->getAddressOff8(var + i * _passWidth, mapWidth);
+			_vm->_inter->_variables->getAddressOff8(var + i * _passWidth);
 		}
 	}
 	mapData.seek(tmpPos);

Modified: scummvm/trunk/engines/gob/map_v4.cpp
===================================================================
--- scummvm/trunk/engines/gob/map_v4.cpp	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/map_v4.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -54,7 +54,7 @@
 	uint32 passPos;
 
 	var = _vm->_parse->parseVarIndex();
-	variables = _vm->_inter->_variables->getAddressOff8(var, 0);
+	variables = _vm->_inter->_variables->getAddressOff8(var);
 
 	id = _vm->_inter->load16();
 
@@ -62,7 +62,7 @@
 		warning("Woodruff Stub: loadMapObjects ID >= 65520");
 		return;
 	} else if (id == -1) {
-		_passMap = (int8 *) _vm->_inter->_variables->getAddressOff8(var, 0);
+		_passMap = (int8 *) _vm->_inter->_variables->getAddressOff8(var);
 		return;
 	}
 
@@ -121,7 +121,7 @@
 	tmpPos = mapData.pos();
 	mapData.seek(passPos);
 	if ((variables != 0) &&
-	    (variables != _vm->_inter->_variables->getAddressOff8(0, 0))) {
+	    (variables != _vm->_inter->_variables->getAddressOff8(0))) {
 
 		_passMap = (int8 *) variables;
 		mapHeight = _screenHeight / _tilesHeight;
@@ -130,7 +130,7 @@
 		for (int i = 0; i < mapHeight; i++) {
 			for (int j = 0; j < mapWidth; j++)
 				setPass(j, i, mapData.readSByte());
-			_vm->_inter->_variables->getAddressOff8(var + i * _passWidth, mapWidth);
+			_vm->_inter->_variables->getAddressOff8(var + i * _passWidth);
 		}
 	}
 	mapData.seek(tmpPos);

Modified: scummvm/trunk/engines/gob/module.mk
===================================================================
--- scummvm/trunk/engines/gob/module.mk	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/module.mk	2009-05-31 02:15:43 UTC (rev 41056)
@@ -46,11 +46,6 @@
 	parse.o \
 	parse_v1.o \
 	parse_v2.o \
-	saveload.o \
-	saveload_v2.o \
-	saveload_v3.o \
-	saveload_v4.o \
-	saveload_v6.o \
 	scenery.o \
 	scenery_v1.o \
 	scenery_v2.o \
@@ -63,6 +58,18 @@
 	demos/demoplayer.o \
 	demos/scnplayer.o \
 	demos/batplayer.o \
+	save/savefile.o \
+	save/savehandler.o \
+	save/saveload.o \
+	save/saveload_v2.o \
+	save/saveload_v3.o \
+	save/saveload_v4.o \
+	save/saveload_v6.o \
+	save/saveconverter.o \
+	save/saveconverter_v2.o \
+	save/saveconverter_v3.o \
+	save/saveconverter_v4.o \
+	save/saveconverter_v6.o \
 	sound/sound.o \
 	sound/sounddesc.o \
 	sound/pcspeaker.o \

Modified: scummvm/trunk/engines/gob/parse.cpp
===================================================================
--- scummvm/trunk/engines/gob/parse.cpp	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/parse.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -44,7 +44,7 @@
 		offset = ptr - _vm->_game->_totFileData;
 		break;
 	case kInterVar:
-		offset = ptr - ((byte *) _vm->_inter->_variables->getAddressOff8(0, 0));
+		offset = ptr - ((byte *) _vm->_inter->_variables->getAddressOff8(0));
 		break;
 	case kResStr:
 		offset = ptr - ((byte *) _vm->_global->_inter_resStr);
@@ -64,7 +64,7 @@
 		ptr = _vm->_game->_totFileData;
 		break;
 	case kInterVar:
-		ptr = (byte *) _vm->_inter->_variables->getAddressOff8(0, 0);
+		ptr = (byte *) _vm->_inter->_variables->getAddressOff8(0);
 		break;
 	case kResStr:
 		ptr = (byte *) _vm->_global->_inter_resStr;

Modified: scummvm/trunk/engines/gob/parse_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/parse_v1.cpp	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/parse_v1.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -375,7 +375,7 @@
 			case OP_LOAD_VAR_STR:
 				*operPtr = OP_LOAD_IMM_STR;
 				temp = _vm->_inter->load16() * 4;
-				*valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(temp, 0),
+				*valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(temp),
 						kInterVar);
 				if (*_vm->_global->_inter_execPtr == 13) {
 					_vm->_global->_inter_execPtr++;
@@ -404,7 +404,7 @@
 					break;
 				}
 				*valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(
-							temp * 4 + offset * _vm->_global->_inter_animDataSize * 4, 0),
+							temp * 4 + offset * _vm->_global->_inter_animDataSize * 4),
 						kInterVar);
 				if (*_vm->_global->_inter_execPtr == 13) {
 					_vm->_global->_inter_execPtr++;

Modified: scummvm/trunk/engines/gob/parse_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/parse_v2.cpp	2009-05-31 01:24:08 UTC (rev 41055)
+++ scummvm/trunk/engines/gob/parse_v2.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -554,7 +554,7 @@
 					*valPtr = (int16) READ_VARO_UINT16(varPos + temp * 2 + offset * 2);
 				else if (operation == OP_ARRAY_STR) {
 					*valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(
-								varPos + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4, 0),
+								varPos + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4),
 							kInterVar);
 					if (*_vm->_global->_inter_execPtr == 13) {
 						_vm->_global->_inter_execPtr++;
@@ -612,7 +612,7 @@
 			case OP_LOAD_VAR_STR:
 				*operPtr = OP_LOAD_IMM_STR;
 				temp = _vm->_inter->load16() * 4;
-				*valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(varPos + temp, 0), kInterVar);
+				*valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(varPos + temp), kInterVar);
 				if (*_vm->_global->_inter_execPtr == 13) {
 					_vm->_global->_inter_execPtr++;
 					temp += parseValExpr(OP_END_MARKER);


Property changes on: scummvm/trunk/engines/gob/save
___________________________________________________________________
Added: svn:ignore
   + .deps
*.o
lib*.a


Added: scummvm/trunk/engines/gob/save/saveconverter.cpp
===================================================================
--- scummvm/trunk/engines/gob/save/saveconverter.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/saveconverter.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,443 @@
+/* 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 "common/savefile.h"
+
+#include "gob/gob.h"
+#include "gob/save/saveconverter.h"
+#include "gob/save/savefile.h"
+#include "gob/save/savehandler.h"
+#include "gob/helper.h"
+
+namespace Gob {
+
+SaveConverter::SaveConverter(GobEngine *vm, const char *fileName) : _vm(vm) {
+	_fileName = strdupcpy(fileName);
+
+	_data = 0;
+	_stream = 0;
+}
+
+SaveConverter::~SaveConverter() {
+	delete[] _fileName;
+
+	delete _stream;
+	delete[] _data;
+}
+
+void SaveConverter::clear() {
+	delete[] _data;
+	delete _stream;
+
+	_data = 0;
+	_stream = 0;
+}
+
+void SaveConverter::setFileName(const char *fileName) {
+	clear();
+
+	delete[] _fileName;
+
+	_fileName = strdupcpy(fileName);
+}
+
+Common::InSaveFile *SaveConverter::openSave() const {
+	if (!_fileName)
+		return 0;
+
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	return saveMan->openForLoading(_fileName);
+}
+
+void SaveConverter::displayWarning() const {
+	warning("Old save format detected, trying to convert. If this does not work, your "
+	        "save is broken and can't be used anymore. Sorry for the inconvenience");
+}
+
+char *SaveConverter::getDescription(const char *fileName) {
+	setFileName(fileName);
+	return getDescription();
+}
+
+char *SaveConverter::getDescription() const {
+	Common::InSaveFile *save;
+
+	// Test if it's an old savd
+	if (!isOldSave(&save) || !save)
+		return 0;
+
+	char *desc = getDescription(*save);
+
+	delete save;
+	return desc;
+}
+
+uint32 SaveConverter::getActualSize(Common::InSaveFile **save) const {
+	Common::InSaveFile *saveFile = openSave();
+
+	if (!saveFile)
+		return false;
+
+	// Is it a valid new save?
+	if (SaveContainer::isSave(*saveFile)) {
+		delete saveFile;
+		return false;
+	}
+
+	int32 saveSize = saveFile->size();
+
+	if (saveSize <= 0) {
+		delete saveFile;
+		return 0;
+	}
+
+	if (save)
+		*save = saveFile;
+	else
+		delete saveFile;
+
+	return saveSize;
+}
+
+bool SaveConverter::swapDataEndian(byte *data, const byte *sizes, uint32 count) {
+	if (!data || !sizes || (count == 0))
+		return false;
+
+	while (count-- > 0) {
+		if      (*sizes == 3) // 32bit value (3 additional bytes)
+			*((uint32 *) data) = SWAP_BYTES_32(*((uint32 *) data));
+		else if (*sizes == 1) // 16bit value (1 additional byte)
+			*((uint16 *) data) = SWAP_BYTES_16(*((uint16 *) data));
+		else if (*sizes != 0) // else, it has to be an 8bit value
+			return false;
+
+		count -= *sizes;
+		data += *sizes + 1;
+		sizes += *sizes + 1;
+	}
+
+	return true;
+}
+
+SavePartInfo *SaveConverter::readInfo(Common::SeekableReadStream &stream,
+	uint32 descLength, bool hasSizes) const {
+
+	uint32 varSize = SaveHandler::getVarSize(_vm);
+	if (varSize == 0)
+		return 0;
+
+	char *desc = getDescription(stream);
+	if (!desc)
+		return 0;
+
+	// If it has sizes, skip them
+	if (hasSizes)
+		if (!stream.skip(descLength)) {
+			delete[] desc;
+			return 0;
+		}
+
+	SavePartInfo *info = new SavePartInfo(descLength, (uint32) _vm->getGameType(),
+			0, _vm->getEndianness(), varSize);
+
+	info->setDesc(desc);
+
+	delete[] desc;
+
+	return info;
+}
+
+byte *SaveConverter::readData(Common::SeekableReadStream &stream,
+		uint32 count, bool endian) const {
+
+	byte *data = new byte[count];
+
+	// Read variable data
+	if (stream.read(data, count) != count) {
+		delete[] data;
+		return 0;
+	}
+
+	/* Check the endianness. The old save data was always written
+	 * as little endian, so we might need to swap the bytes. */
+
+	if (endian && (_vm->getEndianness() == kEndiannessBE)) {
+		// Big endian => swapping needed
+
+		// Read variable sizes
+		byte *sizes = new byte[count];
+		if (stream.read(sizes, count) != count) {
+			delete[] data;
+			delete[] sizes;
+			return 0;
+		}
+
+		// Swap bytes
+		if (!swapDataEndian(data, sizes, count)) {
+			delete[] data;
+			delete[] sizes;
+			return 0;
+		}
+
+		delete[] sizes;
+
+	} else {
+		// Little endian => just skip the sizes part
+
+		if (!stream.skip(count)) {
+			delete[] data;
+			return 0;
+		}
+	}
+
+	return data;
+}
+
+SavePartVars *SaveConverter::readVars(Common::SeekableReadStream &stream,
+		uint32 count, bool endian) const {
+
+	byte *data = readData(stream, count, endian);
+	if (!data)
+		return 0;
+
+	SavePartVars *vars = new SavePartVars(_vm, count);
+
+	// Read variables into part
+	if (!vars->readFromRaw(data, count)) {
+		delete[] data;
+		delete vars;
+		return 0;
+	}
+
+	delete[] data;
+	return vars;
+}
+
+SavePartMem *SaveConverter::readMem(Common::SeekableReadStream &stream,
+		uint32 count, bool endian) const {
+
+	byte *data = readData(stream, count, endian);
+	if (!data)
+		return 0;
+
+	SavePartMem *mem = new SavePartMem(count);
+
+	// Read mem into part
+	if (!mem->readFrom(data, 0, count)) {
+		delete[] data;
+		delete mem;
+		return 0;
+	}
+
+	delete[] data;
+	return mem;
+}
+
+SavePartSprite *SaveConverter::readSprite(Common::SeekableReadStream &stream,
+		uint32 width, uint32 height, bool palette) const {
+
+	assert((width > 0) && (height > 0));
+
+	uint32 spriteSize = width * height;
+
+	byte pal[768];
+	if (palette)
+		if (stream.read(pal, 768) != 768)
+			return 0;
+
+	byte *data = new byte[spriteSize];
+
+	// Read variable data
+	if (stream.read(data, spriteSize) != spriteSize) {
+		delete[] data;
+		return 0;
+	}
+
+	SavePartSprite *sprite = new SavePartSprite(width, height);
+
+	if (!sprite->readSpriteRaw(data, spriteSize)) {
+		delete[] data;
+		return 0;
+	}
+
+	delete[] data;
+
+	if (palette)
+		if (!sprite->readPalette(pal))
+			return 0;
+
+	return sprite;
+}
+
+bool SaveConverter::createStream(SaveWriter &writer) {
+	// Allocate memory for the internal new save data
+	uint32 contSize = writer.getSize();
+	_data = new byte[contSize];
+
+	// Save the newly created new save data
+	Common::MemoryWriteStream writeStream(_data, contSize);
+	if (!writer.save(writeStream))
+		return false;
+
+	// Create a reading stream upon that new save data
+	_stream = new Common::MemoryReadStream(_data, contSize);
+
+	return true;
+}
+
+/* Stream functions. If the new save data stream is available, redirect the stream
+ * operations to that stream. Normal stream error behaviour if not. */
+
+bool SaveConverter::err() const {
+	if (!_data || !_stream)
+		return true;
+
+	return _stream->err();
+}
+
+void SaveConverter::clearErr() {
+	if (!_data || !_stream)
+		return;
+
+	_stream->clearErr();
+}
+
+bool SaveConverter::eos() const {
+	if (!_data || !_stream)
+		return true;
+
+	return _stream->eos();
+}
+
+uint32 SaveConverter::read(void *dataPtr, uint32 dataSize) {
+	if (!_data || !_stream)
+		return 0;
+
+	return _stream->read(dataPtr, dataSize);
+}
+
+int32 SaveConverter::pos() const {
+	if (!_data || !_stream)
+		return -1;
+
+	return _stream->pos();
+}
+
+int32 SaveConverter::size() const {
+	if (!_data || !_stream)
+		return -1;
+
+	return _stream->size();
+}
+
+bool SaveConverter::seek(int32 offset, int whence) {
+	if (!_data || !_stream)
+		return false;
+
+	return _stream->seek(offset, whence);
+}
+
+
+SaveConverter_Notes::SaveConverter_Notes(GobEngine *vm, uint32 notesSize,
+		const char *fileName) : SaveConverter(vm, fileName) {
+
+	_size = notesSize;
+}
+
+SaveConverter_Notes::~SaveConverter_Notes() {
+}
+
+int SaveConverter_Notes::isOldSave(Common::InSaveFile **save) const {
+	if (_size == 0)
+		return 0;
+
+	uint32 saveSize = getActualSize(save);
+	if (saveSize == 0)
+		return 0;
+
+	// The size of the old save always follows that rule
+	if (saveSize == (_size * 2))
+		return 1;
+
+	// Not an old save, clean up
+	if (save) {
+		delete *save;
+		*save = 0;
+	}
+
+	return 0;
+}
+
+char *SaveConverter_Notes::getDescription(Common::SeekableReadStream &save) const  {
+	return 0;
+}
+
+bool SaveConverter_Notes::loadFail(SavePartVars *vars, Common::InSaveFile *save) {
+	delete vars;
+	delete save;
+
+	clear();
+
+	return false;
+}
+
+// Loads the old save by constructing a new save containing the old save's data
+bool SaveConverter_Notes::load() {
+	if (_size == 0)
+		return false;
+
+	Common::InSaveFile *save;
+
+	// Test if it's an old savd
+	if (!isOldSave(&save) || !save)
+		return false;
+
+	displayWarning();
+
+	SaveWriter writer(1, 0);
+
+	SavePartVars *vars = readVars(*save, _size, false);
+	if (!vars)
+		return loadFail(0, save);
+
+	// We don't need the save anymore
+	delete save;
+
+	// Write all parts
+	if (!writer.writePart(0, vars))
+		return loadFail(0, 0);
+
+	// We don't need this anymore
+	delete vars;
+
+	// Create the final read stream
+	if (!createStream(writer))
+		return loadFail(0, 0);
+
+	return true;
+}
+
+} // End of namespace Gob


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

Added: scummvm/trunk/engines/gob/save/saveconverter.h
===================================================================
--- scummvm/trunk/engines/gob/save/saveconverter.h	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/saveconverter.h	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,206 @@
+/* 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$
+ *
+ */
+
+#ifndef GOB_SAVE_SAVECONVERTER_H
+#define GOB_SAVE_SAVECONVERTER_H
+
+#include "common/stream.h"
+
+namespace Gob {
+
+class GobEngine;
+class SavePartInfo;
+class SavePartVars;
+class SavePartMem;
+class SavePartSprite;
+class SaveWriter;
+
+/** A wrapping stream class for old saves. */
+class SaveConverter : public Common::SeekableReadStream {
+public:
+	SaveConverter(GobEngine *vm, const char *fileName = 0);
+	virtual ~SaveConverter();
+
+	/** Clear the converter. */
+	virtual void clear();
+	/** Set the filename on which to operate. */
+	virtual void setFileName(const char *fileName);
+
+	/** Is it actually an old save? */
+	virtual int isOldSave(Common::InSaveFile **save = 0) const = 0;
+	/** Directly return the description without processing the whole save. */
+	virtual char *getDescription(Common::SeekableReadStream &save) const = 0;
+	/** Load the whole save. */
+	virtual bool load() = 0;
+
+	/** Set the name and return the description. */
+	char *getDescription(const char *fileName);
+	/** Get the current fileName's description. */
+	char *getDescription() const;
+
+	// Stream
+	virtual bool err() const;
+	virtual void clearErr();
+	// ReadStream
+	virtual bool eos() const;
+	virtual uint32 read(void *dataPtr, uint32 dataSize);
+	// SeekableReadStream
+	virtual int32 pos() const;
+	virtual int32 size() const;
+	virtual bool seek(int32 offset, int whence = SEEK_SET);
+
+protected:
+	GobEngine *_vm;
+
+	char *_fileName;
+
+	byte *_data;
+	Common::MemoryReadStream *_stream;
+
+	Common::InSaveFile *openSave() const;
+
+	/** Write a warning to stdout to notify the user what's going on. */
+	virtual void displayWarning() const;
+
+	virtual uint32 getActualSize(Common::InSaveFile **save = 0) const;
+
+	SavePartInfo *readInfo(Common::SeekableReadStream &stream,
+		uint32 descLength, bool hasSizes = true) const;
+	SavePartVars *readVars(Common::SeekableReadStream &stream,
+			uint32 count, bool endian) const;
+	SavePartMem *readMem(Common::SeekableReadStream &stream,
+			uint32 count, bool endian) const;
+	SavePartSprite *readSprite(Common::SeekableReadStream &stream,
+			uint32 width, uint32 height, bool palette) const;
+
+	bool createStream(SaveWriter &writer);
+
+	/** Swap the endianness of the complete data area. */
+	static bool swapDataEndian(byte *data, const byte *sizes, uint32 count);
+
+private:
+	byte *readData(Common::SeekableReadStream &stream,
+			uint32 count, bool endian) const;
+};
+
+/** A wrapper for old notes saves. */
+class SaveConverter_Notes : public SaveConverter {
+public:
+	SaveConverter_Notes(GobEngine *vm, uint32 notesSize, const char *fileName = 0);
+	~SaveConverter_Notes();
+
+	int isOldSave(Common::InSaveFile **save = 0) const;
+	char *getDescription(Common::SeekableReadStream &save) const;
+
+	bool load();
+
+private:
+	uint32 _size;
+
+	bool loadFail(SavePartVars *vars, Common::InSaveFile *save);
+};
+
+/** A wrapper for old v2-style saves (Gobliins 2, Ween: The Prophecy and Bargon Attack). */
+class SaveConverter_v2 : public SaveConverter {
+public:
+	SaveConverter_v2(GobEngine *vm, const char *fileName = 0);
+	~SaveConverter_v2();
+
+	int isOldSave(Common::InSaveFile **save = 0) const;
+	char *getDescription(Common::SeekableReadStream &save) const;
+
+	bool load();
+
+private:
+	static const uint32 kSlotCount = 15;
+	static const uint32 kSlotNameLength = 40;
+
+	bool loadFail(SavePartInfo *info, SavePartVars *vars,
+			Common::InSaveFile *save);
+};
+
+/** A wrapper for old v3-style saves (Goblins 3 and Lost in Time). */
+class SaveConverter_v3 : public SaveConverter {
+public:
+	SaveConverter_v3(GobEngine *vm, const char *fileName = 0);
+	~SaveConverter_v3();
+
+	int isOldSave(Common::InSaveFile **save = 0) const;
+	char *getDescription(Common::SeekableReadStream &save) const;
+
+	bool load();
+
+private:
+	static const uint32 kSlotCount = 30;
+	static const uint32 kSlotNameLength = 40;
+
+	bool loadFail(SavePartInfo *info, SavePartVars *vars,
+			SavePartSprite *sprite, Common::InSaveFile *save);
+
+	void getScreenShotProps(int type,
+			bool &used, uint32 &width, uint32 &height);
+};
+
+/** A wrapper for old v4-style saves (Woodruff). */
+class SaveConverter_v4 : public SaveConverter {
+public:
+	SaveConverter_v4(GobEngine *vm, const char *fileName = 0);
+	~SaveConverter_v4();
+
+	int isOldSave(Common::InSaveFile **save = 0) const;
+	char *getDescription(Common::SeekableReadStream &save) const;
+
+	bool load();
+
+private:
+	static const uint32 kSlotCount = 60;
+	static const uint32 kSlotNameLength = 40;
+
+	bool loadFail(SavePartInfo *info, SavePartVars *vars,
+			SavePartMem *props, Common::InSaveFile *save);
+};
+
+/** A wrapper for old v6-style saves (Urban Runner). */
+class SaveConverter_v6 : public SaveConverter {
+public:
+	SaveConverter_v6(GobEngine *vm, const char *fileName = 0);
+	~SaveConverter_v6();
+
+	int isOldSave(Common::InSaveFile **save = 0) const;
+	char *getDescription(Common::SeekableReadStream &save) const;
+
+	bool load();
+
+private:
+	static const uint32 kSlotCount = 15;
+	static const uint32 kSlotNameLength = 40;
+
+	bool loadFail(SavePartInfo *info, SavePartVars *vars,
+			Common::InSaveFile *save);
+};
+
+} // End of namespace Gob
+
+#endif // GOB_SAVE_SAVECONVERTER_H


Property changes on: scummvm/trunk/engines/gob/save/saveconverter.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/engines/gob/save/saveconverter_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/save/saveconverter_v2.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/saveconverter_v2.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,135 @@
+/* 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 "common/savefile.h"
+
+#include "gob/gob.h"
+#include "gob/save/saveconverter.h"
+#include "gob/save/savefile.h"
+#include "gob/save/savehandler.h"
+
+namespace Gob {
+
+SaveConverter_v2::SaveConverter_v2(GobEngine *vm, const char *fileName) :
+	SaveConverter(vm, fileName) {
+}
+
+SaveConverter_v2::~SaveConverter_v2() {
+}
+
+int SaveConverter_v2::isOldSave(Common::InSaveFile **save) const {
+	uint32 varSize = SaveHandler::getVarSize(_vm);
+	if (varSize == 0)
+		return 0;
+
+	uint32 saveSize = getActualSize(save);
+	if (saveSize == 0)
+		return 0;
+
+	// The size of the old save always follows that rule
+	if (saveSize == (varSize * 2 + kSlotNameLength * 2))
+		return 1;
+
+	// Not an old save, clean up
+	if (save) {
+		delete *save;
+		*save = 0;
+	}
+
+	return 0;
+}
+
+char *SaveConverter_v2::getDescription(Common::SeekableReadStream &save) const {
+	char *desc = new char[kSlotNameLength];
+
+	// Read the description
+	if (save.read(desc, kSlotNameLength) != kSlotNameLength) {
+		delete desc;
+		return 0;
+	}
+
+	return desc;
+}
+
+bool SaveConverter_v2::loadFail(SavePartInfo *info, SavePartVars *vars,
+		Common::InSaveFile *save) {
+
+	delete info;
+	delete vars;
+	delete save;
+
+	clear();
+
+	return false;
+}
+
+// Loads the old save by constructing a new save containing the old save's data
+bool SaveConverter_v2::load() {
+	clear();
+
+	uint32 varSize = SaveHandler::getVarSize(_vm);
+	if (varSize == 0)
+		return false;
+
+	Common::InSaveFile *save;
+
+	// Test if it's an old savd
+	if (!isOldSave(&save) || !save)
+		return false;
+
+	displayWarning();
+
+	SaveWriter writer(2, 0);
+
+	SavePartInfo *info = readInfo(*save, kSlotNameLength);
+	if (!info)
+		return loadFail(0, 0, save);
+
+	SavePartVars *vars = readVars(*save, varSize, true);
+	if (!vars)
+		return loadFail(info, 0, save);
+
+	// We don't need the save anymore
+	delete save;
+
+	// Write all parts
+	if (!writer.writePart(0, info))
+		return loadFail(info, vars, 0);
+	if (!writer.writePart(1, vars))
+		return loadFail(info, vars, 0);
+
+	// We don't need those anymore
+	delete info;
+	delete vars;
+
+	// Create the final read stream
+	if (!createStream(writer))
+		return loadFail(0, 0, 0);
+
+	return true;
+}
+
+} // End of namespace Gob


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

Added: scummvm/trunk/engines/gob/save/saveconverter_v3.cpp
===================================================================
--- scummvm/trunk/engines/gob/save/saveconverter_v3.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/saveconverter_v3.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,188 @@
+/* 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 "common/savefile.h"
+
+#include "gob/gob.h"
+#include "gob/save/saveconverter.h"
+#include "gob/save/savefile.h"
+#include "gob/save/savehandler.h"
+
+namespace Gob {
+
+SaveConverter_v3::SaveConverter_v3(GobEngine *vm, const char *fileName) :
+	SaveConverter(vm, fileName) {
+}
+
+SaveConverter_v3::~SaveConverter_v3() {
+}
+
+int SaveConverter_v3::isOldSave(Common::InSaveFile **save) const {
+	uint32 varSize = SaveHandler::getVarSize(_vm);
+	if (varSize == 0)
+		return 0;
+
+	uint32 saveSize = getActualSize(save);
+	if (saveSize == 0)
+		return 0;
+
+	// The size of the old save always follows one of these rules
+	if (saveSize == (varSize * 2 + kSlotNameLength + 1000))
+		return 1; // No screenshot
+	if (saveSize == (varSize * 2 + kSlotNameLength + 1000 + 19968))
+		return 2; // Big screenshot, Goblins 3
+	if (saveSize == (varSize * 2 + kSlotNameLength + 1000 + 4768))
+		return 3; // Small screenshot, Lost in Time
+
+	// Not an old save, clean up
+	if (save) {
+		delete *save;
+		*save = 0;
+	}
+
+	return 0;
+}
+
+char *SaveConverter_v3::getDescription(Common::SeekableReadStream &save) const {
+	// The description starts at 1000
+	if (!save.seek(1000))
+		return 0;
+
+	char *desc = new char[kSlotNameLength];
+
+	// Read the description
+	if (save.read(desc, kSlotNameLength) != kSlotNameLength) {
+		delete desc;
+		return 0;
+	}
+
+	return desc;
+}
+
+bool SaveConverter_v3::loadFail(SavePartInfo *info, SavePartVars *vars,
+		SavePartSprite *sprite, Common::InSaveFile *save) {
+
+	delete info;
+	delete vars;
+	delete sprite;
+	delete save;
+
+	clear();
+
+	return false;
+}
+
+void SaveConverter_v3::getScreenShotProps(int type,
+		bool &used, uint32 &width, uint32 &height) {
+
+	switch (type) {
+	case 2:
+		used   = true;
+		width  = 120;
+		height = 160;
+		break;
+
+	case 3:
+		used   = true;
+		width  = 80;
+		height = 50;
+		break;
+
+	default:
+		used   = false;
+		width  = 0;
+		height = 0;
+		break;
+	}
+}
+
+// Loads the old save by constructing a new save containing the old save's data
+bool SaveConverter_v3::load() {
+	clear();
+
+	uint32 varSize = SaveHandler::getVarSize(_vm);
+	if (varSize == 0)
+		return false;
+
+	Common::InSaveFile *save;
+
+	int type = isOldSave(&save);
+
+	// Test if it's an old savd
+	if ((type == 0) || !save)
+		return false;
+
+	displayWarning();
+
+	bool screenShot;
+	uint32 screenShotWidth;
+	uint32 screenShotHeight;
+
+	getScreenShotProps(type, screenShot, screenShotWidth, screenShotHeight);
+
+	SaveWriter writer(screenShot ? 3 : 2, 0);
+
+	SavePartInfo *info = readInfo(*save, kSlotNameLength, false);
+	if (!info)
+		return loadFail(0, 0, 0, save);
+
+	SavePartVars *vars = readVars(*save, varSize, true);
+	if (!vars)
+		return loadFail(info, 0, 0, save);
+
+	if (screenShot) {
+		SavePartSprite *sprite = readSprite(*save, screenShotWidth, screenShotHeight, true);
+
+		if (!sprite)
+			return loadFail(info, vars, 0, save);
+
+		if (!writer.writePart(2, sprite))
+			return loadFail(info, vars, sprite, save);
+
+		delete sprite;
+	}
+
+	// We don't need the save anymore
+	delete save;
+
+	// Write all parts
+	if (!writer.writePart(0, info))
+		return loadFail(info, vars, 0, 0);
+	if (!writer.writePart(1, vars))
+		return loadFail(info, vars, 0, 0);
+
+	// We don't need those anymore
+	delete info;
+	delete vars;
+
+	// Create the final read stream
+	if (!createStream(writer))
+		return loadFail(0, 0, 0, 0);
+
+	return true;
+}
+
+} // End of namespace Gob


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

Added: scummvm/trunk/engines/gob/save/saveconverter_v4.cpp
===================================================================
--- scummvm/trunk/engines/gob/save/saveconverter_v4.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/saveconverter_v4.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,147 @@
+/* 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 "common/savefile.h"
+
+#include "gob/gob.h"
+#include "gob/save/saveconverter.h"
+#include "gob/save/savefile.h"
+#include "gob/save/savehandler.h"
+
+namespace Gob {
+
+SaveConverter_v4::SaveConverter_v4(GobEngine *vm, const char *fileName) :
+	SaveConverter(vm, fileName) {
+}
+
+SaveConverter_v4::~SaveConverter_v4() {
+}
+
+int SaveConverter_v4::isOldSave(Common::InSaveFile **save) const {
+	uint32 varSize = SaveHandler::getVarSize(_vm);
+	if (varSize == 0)
+		return 0;
+
+	uint32 saveSize = getActualSize(save);
+	if (saveSize == 0)
+		return 0;
+
+	// The size of the old save always follows that rule
+	if (saveSize == (varSize * 2 + kSlotNameLength + 1000 + 512000))
+		return 1;
+
+	// Not an old save, clean up
+	if (save) {
+		delete *save;
+		*save = 0;
+	}
+
+	return 0;
+}
+
+char *SaveConverter_v4::getDescription(Common::SeekableReadStream &save) const {
+	// The description starts at 1000
+	if (!save.seek(1000))
+		return 0;
+
+	char *desc = new char[kSlotNameLength];
+
+	// Read the description
+	if (save.read(desc, kSlotNameLength) != kSlotNameLength) {
+		delete desc;
+		return 0;
+	}
+
+	return desc;
+}
+
+bool SaveConverter_v4::loadFail(SavePartInfo *info, SavePartVars *vars,
+		SavePartMem *props, Common::InSaveFile *save) {
+
+	delete info;
+	delete vars;
+	delete props;
+	delete save;
+
+	clear();
+
+	return false;
+}
+
+// Loads the old save by constructing a new save containing the old save's data
+bool SaveConverter_v4::load() {
+	clear();
+
+	uint32 varSize = SaveHandler::getVarSize(_vm);
+	if (varSize == 0)
+		return false;
+
+	Common::InSaveFile *save;
+
+	// Test if it's an old savd
+	if (!isOldSave(&save) || !save)
+		return false;
+
+	displayWarning();
+
+	SaveWriter writer(3, 0);
+
+	SavePartInfo *info = readInfo(*save, kSlotNameLength, false);
+	if (!info)
+		return loadFail(0, 0, 0, save);
+
+	SavePartVars *vars = readVars(*save, varSize, true);
+	if (!vars)
+		return loadFail(info, 0, 0, save);
+
+	SavePartMem *props = readMem(*save, 256000, true);
+	if (!props)
+		return loadFail(info, vars, 0, save);
+
+	// We don't need the save anymore
+	delete save;
+
+	// Write all parts
+	if (!writer.writePart(0, info))
+		return loadFail(info, vars, props, 0);
+	if (!writer.writePart(1, vars))
+		return loadFail(info, vars, props, 0);
+	if (!writer.writePart(2, props))
+		return loadFail(info, vars, props, 0);
+
+	// We don't need those anymore
+	delete info;
+	delete vars;
+	delete props;
+
+	// Create the final read stream
+	if (!createStream(writer))
+		return loadFail(0, 0, 0, 0);
+
+	return true;
+}
+
+} // End of namespace Gob


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

Added: scummvm/trunk/engines/gob/save/saveconverter_v6.cpp
===================================================================
--- scummvm/trunk/engines/gob/save/saveconverter_v6.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/saveconverter_v6.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,135 @@
+/* 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 "common/savefile.h"
+
+#include "gob/gob.h"
+#include "gob/save/saveconverter.h"
+#include "gob/save/savefile.h"
+#include "gob/save/savehandler.h"
+
+namespace Gob {
+
+SaveConverter_v6::SaveConverter_v6(GobEngine *vm, const char *fileName) :
+	SaveConverter(vm, fileName) {
+}
+
+SaveConverter_v6::~SaveConverter_v6() {
+}
+
+int SaveConverter_v6::isOldSave(Common::InSaveFile **save) const {
+	uint32 varSize = SaveHandler::getVarSize(_vm);
+	if (varSize == 0)
+		return 0;
+
+	uint32 saveSize = getActualSize(save);
+	if (saveSize == 0)
+		return 0;
+
+	// The size of the old save always follows that rule
+	if (saveSize == (varSize * 2 + kSlotNameLength * 2))
+		return 1;
+
+	// Not an old save, clean up
+	if (save) {
+		delete *save;
+		*save = 0;
+	}
+
+	return 0;
+}
+
+char *SaveConverter_v6::getDescription(Common::SeekableReadStream &save) const {
+	char *desc = new char[kSlotNameLength];
+
+	// Read the description
+	if (save.read(desc, kSlotNameLength) != kSlotNameLength) {
+		delete desc;
+		return 0;
+	}
+
+	return desc;
+}
+
+bool SaveConverter_v6::loadFail(SavePartInfo *info, SavePartVars *vars,
+		Common::InSaveFile *save) {
+
+	delete info;
+	delete vars;
+	delete save;
+
+	clear();
+
+	return false;
+}
+
+// Loads the old save by constructing a new save containing the old save's data
+bool SaveConverter_v6::load() {
+	clear();
+
+	uint32 varSize = SaveHandler::getVarSize(_vm);
+	if (varSize == 0)
+		return false;
+
+	Common::InSaveFile *save;
+
+	// Test if it's an old savd
+	if (!isOldSave(&save) || !save)
+		return false;
+
+	displayWarning();
+
+	SaveWriter writer(2, 0);
+
+	SavePartInfo *info = readInfo(*save, kSlotNameLength);
+	if (!info)
+		return loadFail(0, 0, save);
+
+	SavePartVars *vars = readVars(*save, varSize, true);
+	if (!vars)
+		return loadFail(info, 0, save);
+
+	// We don't need the save anymore
+	delete save;
+
+	// Write all parts
+	if (!writer.writePart(0, info))
+		return loadFail(info, vars, 0);
+	if (!writer.writePart(1, vars))
+		return loadFail(info, vars, 0);
+
+	// We don't need those anymore
+	delete info;
+	delete vars;
+
+	// Create the final read stream
+	if (!createStream(writer))
+		return loadFail(0, 0, 0);
+
+	return true;
+}
+
+} // End of namespace Gob


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

Added: scummvm/trunk/engines/gob/save/savefile.cpp
===================================================================
--- scummvm/trunk/engines/gob/save/savefile.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/savefile.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,979 @@
+/* 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/util.h"
+#include "common/endian.h"
+#include "common/system.h"
+#include "common/savefile.h"
+
+#include "gob/gob.h"
+#include "gob/save/savefile.h"
+#include "gob/video.h"
+#include "gob/helper.h"
+#include "gob/inter.h"
+#include "gob/variables.h"
+
+namespace Gob {
+
+static inline bool flushStream(Common::WriteStream &stream) {
+	// Flush and check for errors
+
+	if (!stream.flush())
+		return false;
+	if (stream.err())
+		return false;
+
+	return true;
+}
+
+SaveHeader::SaveHeader(uint32 type, uint32 version, uint32 size) {
+	_type = type;
+	_version = version;
+	_size = size;
+}
+
+bool SaveHeader::read(Common::ReadStream &stream) {
+	// Read the header and verify the global IDs
+	if (stream.readUint32BE() != kID1)
+		return false;
+	if (stream.readUint32BE() != kID2)
+		return false;
+
+	_type = stream.readUint32BE();
+	_version = stream.readUint32LE();
+	_size = stream.readUint32LE();
+
+	return !stream.err();
+}
+
+bool SaveHeader::verify(Common::ReadStream &stream) const {
+	// Compare the header with the stream's content
+
+	if (stream.readUint32BE() != kID1)
+		return false;
+	if (stream.readUint32BE() != kID2)
+		return false;
+	if (stream.readUint32BE() != _type)
+		return false;
+	if (stream.readUint32LE() != _version)
+		return false;
+	if (stream.readUint32LE() != _size)
+		return false;
+
+	return !stream.err();
+}
+
+bool SaveHeader::verifyReadSize(Common::ReadStream &stream) {
+	// Compare the header with the stream's content, expect for the size
+
+	if (stream.readUint32BE() != kID1)
+		return false;
+	if (stream.readUint32BE() != kID2)
+		return false;
+	if (stream.readUint32BE() != _type)
+		return false;
+	if (stream.readUint32LE() != _version)
+		return false;
+
+	// Read the size out of the stream instead
+	_size = stream.readUint32LE();
+
+	return !stream.err();
+}
+
+bool SaveHeader::write(Common::WriteStream &stream) const {
+	stream.writeUint32BE(kID1);
+	stream.writeUint32BE(kID2);
+	stream.writeUint32BE(_type);
+	stream.writeUint32LE(_version);
+	stream.writeUint32LE(_size);
+
+	return flushStream(stream);
+}
+
+uint32 SaveHeader::getType() const {
+	return _type;
+}
+
+uint32 SaveHeader::getVersion() const {
+	return _version;
+}
+
+uint32 SaveHeader::getSize() const {
+	return _size;
+}
+
+void SaveHeader::setType(uint32 type) {
+	_type = type;
+}
+
+void SaveHeader::setVersion(uint32 version) {
+	_version = version;
+}
+
+void SaveHeader::setSize(uint32 size) {
+	_size = size;
+}
+
+SavePart::SavePart() {
+}
+
+SavePart::~SavePart() {
+}
+
+uint32 SavePart::getSize() const {
+	// A part's size is the content's size plus the header's size
+	return _header.getSize() + SaveHeader::kSize;
+}
+
+SavePartMem::SavePartMem(uint32 size) : SavePart(), _size(size) {
+	_header.setType(kID);
+	_header.setVersion(kVersion);
+	_header.setSize(size);
+
+	_data = new byte[size];
+}
+
+SavePartMem::~SavePartMem() {
+	delete[] _data;
+}
+
+bool SavePartMem::read(Common::ReadStream &stream) {
+	if (!_header.verify(stream))
+		return false;
+
+	if (stream.read(_data, _size) != _size)
+		return false;
+
+	return !stream.err();
+}
+
+bool SavePartMem::write(Common::WriteStream &stream) const {
+	if (!_header.write(stream))
+		return false;
+
+	if (stream.write(_data, _size) != _size)
+		return false;
+
+	return flushStream(stream);
+}
+
+bool SavePartMem::readFrom(const byte *data, uint32 offset, uint32 size) {
+	if ((offset + size) > _size)
+		return false;
+
+	memcpy(_data + offset, data, size);
+
+	return true;
+}
+
+bool SavePartMem::writeInto(byte *data, uint32 offset, uint32 size) const {
+	if ((offset + size) > _size)
+		return false;
+
+	memcpy(data, _data + offset, size);
+
+	return true;
+}
+
+SavePartVars::SavePartVars(GobEngine *vm, uint32 size) : SavePart(), _size(size), _vm(vm) {
+	_header.setType(kID);
+	_header.setVersion(kVersion);
+	_header.setSize(size);
+
+	_data = new byte[size];
+}
+
+SavePartVars::~SavePartVars() {
+	delete[] _data;
+}
+
+bool SavePartVars::read(Common::ReadStream &stream) {
+	if (!_header.verify(stream))
+		return false;
+
+	if (stream.read(_data, _size) != _size)
+		return false;
+
+	return !stream.err();
+}
+
+bool SavePartVars::write(Common::WriteStream &stream) const {
+	if (!_header.write(stream))
+		return false;
+
+	if (stream.write(_data, _size) != _size)
+		return false;
+
+	return flushStream(stream);
+}
+
+bool SavePartVars::readFrom(uint32 var, uint32 offset, uint32 size) {
+	if (!_vm->_inter->_variables)
+		return false;
+
+	if ((offset + size) > _size)
+		return false;
+
+	// Get raw variables
+	return _vm->_inter->_variables->copyTo(var, _data + offset, size);
+}
+
+bool SavePartVars::readFromRaw(const byte *data, uint32 size) {
+	if (size != _size)
+		return false;
+
+	memcpy(_data, data, size);
+	return true;
+}
+
+bool SavePartVars::writeInto(uint32 var, uint32 offset, uint32 size) const {
+	if (!_vm->_inter->_variables)
+		return false;
+
+	if ((offset + size) > _size)
+		return false;
+
+	// Write raw variables
+	if (!_vm->_inter->_variables->copyFrom(var, _data + offset, size))
+		return false;
+
+	return true;
+}
+
+SavePartSprite::SavePartSprite(uint32 width, uint32 height) {
+	assert((width > 0) && (height > 0));
+
+	_width = width;
+	_height = height;
+
+	_header.setType(kID);
+	_header.setVersion(kVersion);
+	//            width + height +      sprite      + palette
+	_header.setSize(4   +   4    + _width * _height +  768);
+
+	_dataSprite  = new byte[_width * _height];
+	_dataPalette = new byte[768];
+
+	memset(_dataSprite,  0, _width * _height);
+	memset(_dataPalette, 0, 768);
+}
+
+SavePartSprite::~SavePartSprite() {
+	delete[] _dataSprite;
+	delete[] _dataPalette;
+}
+
+bool SavePartSprite::read(Common::ReadStream &stream) {
+	if (!_header.verify(stream))
+		return false;
+
+	// The sprite's dimensions have to fit
+	if (stream.readUint32LE() != _width)
+		return false;
+	if (stream.readUint32LE() != _height)
+		return false;
+
+	// Sprite data
+	if (stream.read(_dataSprite, _width * _height) != (_width * _height))
+		return false;
+
+	// Palette data
+	if (stream.read(_dataPalette, 768) != 768)
+		return false;
+
+	return !stream.err();
+}
+
+bool SavePartSprite::write(Common::WriteStream &stream) const {
+	if (!_header.write(stream))
+		return false;
+
+	// The sprite's dimensions
+	stream.writeUint32LE(_width);
+	stream.writeUint32LE(_height);
+
+	// Sprite data
+	if (stream.write(_dataSprite, _width * _height) != (_width * _height))
+		return false;
+
+	// Palette data
+	if (stream.write(_dataPalette, 768) != 768)
+		return false;
+
+	return flushStream(stream);
+}
+
+bool SavePartSprite::readPalette(const byte *palette) {
+	memcpy(_dataPalette, palette, 768);
+
+	return true;
+}
+
+bool SavePartSprite::readSprite(const SurfaceDesc *sprite) {
+	if (!sprite)
+		return false;
+
+	// The sprite's dimensions have to fit
+	if (((uint32) sprite->getWidth()) != _width)
+		return false;
+	if (((uint32) sprite->getHeight()) != _height)
+		return false;
+
+	memcpy(_dataSprite, sprite->getVidMem(), _width * _height);
+
+	return true;
+}
+
+bool SavePartSprite::readSpriteRaw(const byte *data, uint32 size) {
+	if (size != (_width * _height))
+		return false;
+
+	memcpy(_dataSprite, data, size);
+	return true;
+}
+
+bool SavePartSprite::writePalette(byte *palette) const {
+	memcpy(palette, _dataPalette, 768);
+
+	return true;
+}
+
+bool SavePartSprite::writeSprite(SurfaceDesc *sprite) const {
+	if (!sprite)
+		return false;
+
+	// The sprite's dimensions have to fit
+	if (((uint32) sprite->getWidth()) != _width)
+		return false;
+	if (((uint32) sprite->getHeight()) != _height)
+		return false;
+
+	memcpy(sprite->getVidMem(), _dataSprite, _width * _height);
+
+	return true;
+}
+
+SavePartInfo::SavePartInfo(uint32 descMaxLength, uint32 gameID,
+		uint32 gameVersion, byte endian, uint32 varCount) {
+
+	_header.setType(kID);
+	_header.setVersion(kVersion);
+	//                        descMaxLength + gameID + gameVersion + endian + varCount
+	_header.setSize(descMaxLength + 4       +   4    +     4       +    1   +    4);
+
+	_descMaxLength = descMaxLength;
+	_gameID = gameID;
+	_gameVersion = gameVersion;
+	_endian = endian;
+	_varCount = varCount;
+
+	_desc = new char[_descMaxLength + 1];
+	memset(_desc, 0, _descMaxLength + 1);
+}
+
+SavePartInfo::~SavePartInfo() {
+	delete[] _desc;
+}
+
+const char *SavePartInfo::getDesc() const {
+	return _desc;
+}
+
+uint32 SavePartInfo::getDescMaxLength() const {
+	return _descMaxLength;
+}
+
+void SavePartInfo::setVarCount(uint32 varCount) {
+	_varCount = varCount;
+}
+
+void SavePartInfo::setDesc(const char *desc) {
+	if (!desc) {
+		memset(_desc, 0, _descMaxLength + 1);
+		return;
+	}
+
+	uint32 n = MIN<uint32>(strlen(desc), _descMaxLength);
+
+	// Copy the description and fill with 0
+	memcpy(_desc, desc, n);
+	memset(_desc + n, 0, _descMaxLength + 1 - n);
+}
+
+void SavePartInfo::setDesc(const byte *desc, uint32 size) {
+	if (!desc || !size) {
+		memset(_desc, 0, _descMaxLength + 1);
+		return;
+	}
+
+	uint32 n = MIN<uint32>(size, _descMaxLength);
+	memcpy(_desc, desc, n);
+	memset(_desc + n, 0, _descMaxLength + 1 - n);
+}
+
+bool SavePartInfo::read(Common::ReadStream &stream) {
+	if (!_header.verify(stream))
+		return false;
+
+	if (stream.readUint32LE() != _gameID)
+		return false;
+	if (stream.readUint32LE() != _gameVersion)
+		return false;
+	if (stream.readByte() != _endian)
+		return false;
+	if (stream.readUint32LE() != _varCount)
+		return false;
+	if (stream.readUint32LE() != _descMaxLength)
+		return false;
+
+	if (stream.read(_desc, _descMaxLength) != _descMaxLength)
+		return false;
+
+	_desc[_descMaxLength] = 0;
+
+	return !stream.err();
+}
+
+bool SavePartInfo::write(Common::WriteStream &stream) const {
+	if (!_header.write(stream))
+		return false;
+
+	stream.writeUint32LE(_gameID);
+	stream.writeUint32LE(_gameVersion);
+	stream.writeByte(_endian);
+	stream.writeUint32LE(_varCount);
+	stream.writeUint32LE(_descMaxLength);
+
+	if (stream.write(_desc, _descMaxLength) != _descMaxLength)
+		return false;
+
+	return flushStream(stream);
+}
+
+SaveContainer::Part::Part(uint32 s) {
+	size = s;
+	data = new byte[size];
+}
+
+SaveContainer::Part::~Part() {
+	delete[] data;
+}
+
+Common::WriteStream *SaveContainer::Part::createWriteStream() {
+	return new Common::MemoryWriteStream(data, size);
+}
+
+Common::ReadStream *SaveContainer::Part::createReadStream() const {
+	return new Common::MemoryReadStream(data, size);
+}
+
+SaveContainer::SaveContainer(uint32 partCount, uint32 slot) {
+	assert(partCount > 0);
+
+	_slot = slot;
+	_partCount = partCount;
+
+	_parts.resize(partCount);
+	for (PartIterator it = _parts.begin(); it != _parts.end(); ++it)
+		*it = 0;
+
+	_header.setType(kID);
+	_header.setVersion(kVersion);
+	_header.setSize(4); // uint32 # of parts
+}
+
+SaveContainer::~SaveContainer() {
+	clear();
+}
+
+uint32 SaveContainer::getSlot() const {
+	return _slot;
+}
+
+uint32 SaveContainer::getSize() const {
+	return _header.getSize() + SaveHeader::kSize;
+}
+
+bool SaveContainer::hasAllParts() const {
+	for (PartConstIterator it = _parts.begin(); it != _parts.end(); ++it)
+		if (!*it)
+			return false;
+
+	return true;
+}
+
+uint32 SaveContainer::calcSize() const {
+	uint32 size = 4; // uint32 # of parts
+
+	for (PartConstIterator it = _parts.begin(); it != _parts.end(); ++it)
+		if (*it)
+			//              uint32 part size
+			size += (*it)->size + 4;
+
+	return size;
+}
+
+void SaveContainer::clear() {
+	for (PartIterator it = _parts.begin(); it != _parts.end(); ++it) {
+		Part *&p = *it;
+
+		delete p;
+		p = 0;
+	}
+}
+
+bool SaveContainer::writePart(uint32 partN, const SavePart *part) {
+	// Sanity checks
+	if (!part)
+		return false;
+	if (partN >= _partCount)
+		return false;
+
+	Part *&p = _parts[partN];
+
+	delete p;
+	// Create the part
+	p = new Part(part->getSize());
+
+	Common::WriteStream *pStream = p->createWriteStream();
+
+	// Write
+	if (!part->write(*pStream)) {
+		delete p;
+		p = 0;
+
+		delete pStream;
+		return false;
+	}
+
+	delete pStream;
+
+	// Update size
+	_header.setSize(calcSize());
+
+	return true;
+}
+
+bool SaveContainer::readPart(uint32 partN, SavePart *part) const {
+	// Sanity checks
+	if (!part)
+		return false;
+	if (partN >= _partCount)
+		return false;
+
+	const Part * const &p = _parts[partN];
+
+	// Check if the part actually exists
+	if (!p)
+		return false;
+
+	Common::ReadStream *pStream = p->createReadStream();
+
+	// Read
+	if (!part->read(*pStream)) {
+		delete pStream;
+		return false;
+	}
+
+	delete pStream;
+	return true;
+}
+
+bool SaveContainer::readPartHeader(uint32 partN, SaveHeader *header) const {
+	// Sanity checks
+	if (!header)
+		return false;
+	if (partN >= _partCount)
+		return false;
+
+	const Part * const &p = _parts[partN];
+
+	// Check if the part actually exists
+	if (!p)
+		return false;
+
+	Common::ReadStream *pStream = p->createReadStream();
+
+	// Read
+	if (!header->read(*pStream)) {
+		delete pStream;
+		return false;
+	}
+
+	delete pStream;
+	return true;
+}
+
+bool SaveContainer::read(Common::ReadStream &stream) {
+	// Verify the header and get the container's size
+	if (!_header.verifyReadSize(stream))
+		return false;
+
+	// The part count has to be correct
+	if (stream.readUint32LE() != _partCount)
+		return false;
+
+	// Iterate over all parts
+	for (PartIterator it = _parts.begin(); it != _parts.end(); ++it) {
+		// Read the size
+		uint32 size = stream.readUint32LE();
+
+		if (stream.err()) {
+			clear();
+			return false;
+		}
+
+		Part *&p = *it;
+
+		delete p;
+		// Create a suitable part
+		p = new Part(size);
+	}
+
+	// Update size
+	_header.setSize(calcSize());
+
+	// Iterate over all parts
+	for (PartIterator it = _parts.begin(); it != _parts.end(); ++it) {
+		Part *&p = *it;
+
+		// Read the part
+		if (stream.read(p->data, p->size) != p->size) {
+			clear();
+			return false;
+		}
+	}
+
+	return !stream.err();
+}
+
+bool SaveContainer::write(Common::WriteStream &stream) const {
+	// Write the header
+	if (!_header.write(stream))
+		return false;
+
+	// Write the part count
+	stream.writeUint32LE(_partCount);
+
+	// Iterate over all parts
+	for (PartConstIterator it = _parts.begin(); it != _parts.end(); ++it) {
+		// Part doesn't actually exist => error
+		if (!*it)
+			return false;
+
+		// Write the part's size
+		stream.writeUint32LE((*it)->size);
+	}
+
+	if (!flushStream(stream))
+		return false;
+
+	// Iterate over all parts
+	for (PartConstIterator it = _parts.begin(); it != _parts.end(); ++it) {
+		Part * const &p = *it;
+
+		// Write the part
+		if (stream.write(p->data, p->size) != p->size)
+			return false;
+	}
+
+	return flushStream(stream);
+}
+
+Common::Array<SaveContainer::PartInfo> *SaveContainer::getPartsInfo(Common::SeekableReadStream &stream) {
+	Common::Array<PartInfo> *parts = 0;
+
+	// Remember the stream's position to seek back to
+	uint32 startPos = stream.pos();
+
+	SaveHeader header;
+
+	header.setType(kID);
+	header.setVersion(kVersion);
+
+	// Verify the header
+	if (!header.verifyReadSize(stream)) {
+		// Seek back
+		stream.seek(startPos);
+		return 0;
+	}
+
+	// Read the part count
+	uint32 partCount = stream.readUint32LE();
+
+	// Create a part information array
+	parts = new Common::Array<PartInfo>;
+	parts->resize(partCount);
+
+	// Read all part sizes
+	for (uint32 i = 0; i < partCount; i++)
+		(*parts)[i].size = stream.readUint32LE();
+
+	// Iterate over all parts
+	for (uint32 i = 0; i < partCount; i++) {
+		// The part's offset (from the starting point of the stream)
+		(*parts)[i].offset = stream.pos() - startPos;
+
+		SaveHeader partHeader;
+
+		// Read the header
+		if (!partHeader.read(stream)) {
+			// Seek back
+			stream.seek(startPos);
+			delete parts;
+			return 0;
+		}
+
+		// Fill in the ID
+		(*parts)[i].id = partHeader.getType();
+
+		// Skip the part's content
+		stream.skip(partHeader.getSize());
+	}
+
+	if (stream.err()) {
+		delete parts;
+		parts = 0;
+	}
+
+	// Seek back
+	stream.seek(startPos);
+
+	return parts;
+}
+
+bool SaveContainer::isSave(Common::SeekableReadStream &stream) {
+	// Remember the stream's position to seek back to
+	uint32 startPos = stream.pos();
+
+	SaveHeader header;
+
+	header.setType(kID);
+	header.setVersion(kVersion);
+
+	bool result = header.verifyReadSize(stream);
+
+	// Seek back
+	stream.seek(startPos);
+
+	return result;
+}
+
+
+SaveReader::SaveReader(uint32 partCount, uint32 slot, const char *fileName) :
+	SaveContainer(partCount, slot) {
+
+	_fileName = strdupcpy(fileName);
+	_stream = 0;
+
+	_loaded = false;
+}
+
+SaveReader::SaveReader(uint32 partCount, uint32 slot, Common::SeekableReadStream &stream) :
+	SaveContainer(partCount, slot) {
+
+	_fileName = 0;
+	_stream = &stream;
+
+	_loaded = false;
+}
+
+SaveReader::~SaveReader() {
+	delete[] _fileName;
+}
+
+// Open the save and read it
+bool SaveReader::load() {
+
+	Common::InSaveFile *in = 0;
+	Common::SeekableReadStream *stream;
+
+	if (_fileName) {
+		in = openSave();
+
+		if (!in)
+			return false;
+
+		stream = in;
+	} else if (_stream)
+		stream = _stream;
+	else
+		return false;
+
+	if (!SaveContainer::read(*stream)) {
+		delete in;
+		return false;
+	}
+
+	delete in;
+	_loaded = true;
+	return true;
+}
+
+bool SaveReader::readPartHeader(uint32 partN, SaveHeader *header) const {
+	// The save has to be loaded
+	if (!_loaded)
+		return false;
+
+	return SaveContainer::readPartHeader(partN, header);
+}
+
+bool SaveReader::readPart(uint32 partN, SavePart *part) const {
+	// The save has to be loaded
+	if (!_loaded)
+		return false;
+
+	if (!SaveContainer::readPart(partN, part))
+		return false;
+
+	return true;
+}
+
+Common::InSaveFile *SaveReader::openSave(const char *fileName) {
+	if (!fileName)
+		return 0;
+
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	return saveMan->openForLoading(fileName);
+}
+
+Common::InSaveFile *SaveReader::openSave() {
+	return openSave(_fileName);
+}
+
+bool SaveReader::getInfo(Common::SeekableReadStream &stream, SavePartInfo &info) {
+	// Remeber the stream's starting position to seek back to
+	uint32 startPos = stream.pos();
+
+	// Get parts' basic information
+	Common::Array<SaveContainer::PartInfo> *partsInfo = getPartsInfo(stream);
+
+	// No parts => fail
+	if (!partsInfo) {
+		stream.seek(startPos);
+		return false;
+	}
+
+	bool result = false;
+	// Iterate over all parts
+	for (Common::Array<SaveContainer::PartInfo>::iterator it = partsInfo->begin();
+	     it != partsInfo->end(); ++it) {
+
+		// Check for the info part
+		if (it->id == SavePartInfo::kID) {
+			if (!stream.seek(it->offset))
+				break;
+
+			// Read it
+			result = info.read(stream);
+			break;
+		}
+	}
+
+	stream.seek(startPos);
+
+	delete partsInfo;
+	return result;
+}
+
+bool SaveReader::getInfo(const char *fileName, SavePartInfo &info) {
+	Common::InSaveFile *in = openSave(fileName);
+
+	if (!in)
+		return false;
+
+	bool result = getInfo(*in, info);
+
+	delete in;
+
+	return result;
+}
+
+SaveWriter::SaveWriter(uint32 partCount, uint32 slot, const char *fileName) :
+	SaveContainer(partCount, slot) {
+
+	_fileName = strdupcpy(fileName);
+}
+
+SaveWriter::~SaveWriter() {
+	delete[] _fileName;
+}
+
+bool SaveWriter::writePart(uint32 partN, const SavePart *part) {
+	// Write the part
+	if (!SaveContainer::writePart(partN, part))
+		return false;
+
+	// If all parts have been written, save and clear
+	if (hasAllParts() && canSave()) {
+		if (save()) {
+			clear();
+			return true;
+		}
+
+		return false;
+	}
+
+	return true;
+}
+
+bool SaveWriter::save(Common::WriteStream &stream) {
+	return SaveContainer::write(stream);
+}
+
+bool SaveWriter::save() {
+	Common::OutSaveFile *out = openSave();
+
+	if (!out)
+		return false;
+
+	bool success = save(*out);
+
+	delete out;
+
+	return success;
+}
+
+bool SaveWriter::canSave() const {
+	if (!_fileName)
+		return false;
+	
+	return true;
+}
+
+Common::OutSaveFile *SaveWriter::openSave(const char *fileName) {
+	if (!fileName)
+		return 0;
+
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	return saveMan->openForSaving(fileName);
+}
+
+Common::OutSaveFile *SaveWriter::openSave() {
+	return openSave(_fileName);
+}
+
+} // End of namespace Gob


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

Added: scummvm/trunk/engines/gob/save/savefile.h
===================================================================
--- scummvm/trunk/engines/gob/save/savefile.h	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/savefile.h	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,347 @@
+/* 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$
+ *
+ */
+
+#ifndef GOB_SAVE_SAVEFILE_H
+#define GOB_SAVE_SAVEFILE_H
+
+#include "common/endian.h"
+#include "common/array.h"
+#include "common/savefile.h"
+
+namespace Gob {
+
+class GobEngine;
+class SurfaceDesc;
+
+/** A class wrapping a save part header.
+  *
+  * A save part header consists of 4 fields:
+  * ID      : The 8 character ID \0SCVMGOB
+  * Type    : The 4 character ID for this part's type
+  * Version : This part's version. Each type has its own version counter
+  * Size    : The size of the contents, i.e. excluding this header
+*/
+class SaveHeader {
+public:
+	/** The size of the header. */
+	static const int kSize = 20;
+	static const uint32 kID1 = MKID_BE('\0SCV');
+	static const uint32 kID2 = MKID_BE('MGOB');
+
+	SaveHeader(uint32 type = 0, uint32 version = 0, uint32 size = 0);
+
+	/** Read the header out of a stream into this class. */
+	bool read(Common::ReadStream &stream);
+	/** Read the header out of a stream and checks it against this class's contents. */
+	bool verify(Common::ReadStream &stream) const;
+	/** Read the header out of a stream and checks it against this class's contents,
+	 *  but read the size field instead.
+	 */
+	bool verifyReadSize(Common::ReadStream &stream);
+	/** Write this class's contents into a stream. */
+	bool write(Common::WriteStream &stream) const;
+
+	uint32 getType() const;
+	uint32 getVersion() const;
+	uint32 getSize() const;
+
+	void setType(uint32 type);
+	void setVersion(uint32 version);
+	void setSize(uint32 size);
+
+private:
+	/** An ID specifying the part's type. */
+	uint32 _type;
+	/** The part's version. */
+	uint32 _version;
+	/** The size of the contents. */
+	uint32 _size;
+};
+
+/** An abstract class for a part in a save file. */
+class SavePart {
+public:
+	SavePart();
+	virtual ~SavePart();
+
+	/** Return the total size of the part. */
+	virtual uint32 getSize() const;
+
+	/** Read the part (with header) out of the stream. */
+	virtual bool read(Common::ReadStream &stream) = 0;
+	/** Write the part (with header) into the stream. */
+	virtual bool write(Common::WriteStream &stream) const = 0;
+
+protected:
+	SaveHeader _header;
+};
+
+/** A save part consisting of plain memory. */
+class SavePartMem : public SavePart {
+public:
+	static const uint32 kVersion = 1;
+	static const uint32 kID = MKID_BE('PMEM');
+
+	SavePartMem(uint32 size);
+	~SavePartMem();
+
+	bool read(Common::ReadStream &stream);
+	bool write(Common::WriteStream &stream) const;
+
+	/** Read size bytes of data into the part at the specified offset. */
+	bool readFrom(const byte *data, uint32 offset, uint32 size);
+	/** Write size bytes of the part at the specified offset int data. */
+	bool writeInto(byte *data, uint32 offset, uint32 size) const;
+
+private:
+	uint32 _size;
+	byte *_data;
+};
+
+/** A save part holding script variables. */
+class SavePartVars : public SavePart {
+public:
+	static const uint32 kVersion = 1;
+	static const uint32 kID = MKID_BE('VARS');
+
+	SavePartVars(GobEngine *vm, uint32 size);
+	~SavePartVars();
+
+	bool read(Common::ReadStream &stream);
+	bool write(Common::WriteStream &stream) const;
+
+	/** Read size bytes of variables starting at var into the part at the specified offset. */
+	bool readFrom(uint32 var, uint32 offset, uint32 size);
+	/** Write size bytes of the part at the specified offset into the variable starting at var. */
+	bool writeInto(uint32 var, uint32 offset, uint32 size) const;
+
+	/** Read size bytes of raw data into the part. */
+	bool readFromRaw(const byte *data, uint32 size);
+
+private:
+	GobEngine *_vm;
+
+	uint32 _size;
+	byte *_data;
+};
+
+/** A save part holding a sprite. */
+class SavePartSprite : public SavePart {
+public:
+	static const uint32 kVersion = 1;
+	static const uint32 kID = MKID_BE('SPRT');
+
+	SavePartSprite(uint32 width, uint32 height);
+	~SavePartSprite();
+
+	bool read(Common::ReadStream &stream);
+	bool write(Common::WriteStream &stream) const;
+
+	/** Read a palette into the part. */
+	bool readPalette(const byte *palette);
+	/** Read a sprite into the part. */
+	bool readSprite(const SurfaceDesc *sprite);
+	
+	/** Read size bytes of raw data into the sprite. */
+	bool readSpriteRaw(const byte *data, uint32 size);
+
+	/** Write a palette out of the part. */
+	bool writePalette(byte *palette) const;
+	/** Write a sprite out of the part. */
+	bool writeSprite(SurfaceDesc *sprite) const;
+
+private:
+	uint32 _width;
+	uint32 _height;
+
+	byte *_dataSprite;
+	byte *_dataPalette;
+};
+
+/** A save part containing informations about the save's game. */
+class SavePartInfo : public SavePart {
+public:
+	static const uint32 kVersion = 1;
+	static const uint32 kID = MKID_BE('INFO');
+
+	/** The constructor.
+	 *
+	 *  @param descMaxLength The maximal number of bytes that fit into the description.
+	 *  @param gameID An ID for the game (Gob1, Gob2, Gob3, ...).
+	 *  @param gameVersion An ID for game specific versioning
+	 *  @param endian Endianness of the platform the game originally ran on.
+	 *  @param varCount The number of script variables.
+	 */
+	SavePartInfo(uint32 descMaxLength, uint32 gameID,
+			uint32 gameVersion, byte endian, uint32 varCount);
+	~SavePartInfo();
+
+	/** Return the save's description. */
+	const char *getDesc() const;
+	/** Return the description's maximal length. */
+	uint32 getDescMaxLength() const;
+
+	/** Set the variable count. */
+	void setVarCount(uint32 varCount);
+	/** Set the save's description. */
+	void setDesc(const char *desc = 0);
+	/** Set the save's description. */
+	void setDesc(const byte *desc, uint32 size);
+
+	bool read(Common::ReadStream &stream);
+	bool write(Common::WriteStream &stream) const;
+
+private:
+	char *_desc;
+	uint32 _descMaxLength;
+	uint32 _gameID;
+	uint32 _gameVersion;
+	uint32 _varCount;
+	byte _endian;
+};
+
+/** A container for several save parts. */
+class SaveContainer {
+public:
+	static const uint32 kVersion = 1;
+	static const uint32 kID = MKID_BE('CONT');
+
+	/** The constructor.
+	 *
+	 *  @param partCount The number parts this container shall hold.
+	 *  @param slot The save slot this save's for.
+	 */
+	SaveContainer(uint32 partCount, uint32 slot);
+	~SaveContainer();
+
+	uint32 getSlot() const;
+	uint32 getSize() const;
+
+	/** All parts filled? */
+	bool hasAllParts() const;
+
+	/** Empty all parts. */
+	void clear();
+
+	/** Write a SavePart into the container's part. */
+	bool writePart(uint32 partN, const SavePart *part);
+	/** Read the container's part's content into a SavePart. */
+	bool readPart(uint32 partN, SavePart *part) const;
+	/** Read only the container's part's header. */
+	bool readPartHeader(uint32 partN, SaveHeader *header) const;
+
+	/** Checks if the stream is a valid save container. */
+	static bool isSave(Common::SeekableReadStream &stream);
+
+protected:
+	/** A part. */
+	struct Part {
+		uint32 size;
+		byte *data;
+
+		Part(uint32 s);
+		~Part();
+
+		Common::WriteStream *createWriteStream();
+		Common::ReadStream *createReadStream() const;
+	};
+
+	/** Basic information about a part. */
+	struct PartInfo {
+		uint32 id;
+		uint32 offset;
+		uint32 size;
+	};
+
+	typedef Common::Array<Part *>::iterator PartIterator;
+	typedef Common::Array<Part *>::const_iterator PartConstIterator;
+
+	uint32 _partCount;
+	uint32 _slot;
+
+	SaveHeader _header;
+	Common::Array<Part *> _parts;
+
+	uint32 calcSize() const;
+
+	bool read(Common::ReadStream &stream);
+	bool write(Common::WriteStream &stream) const;
+
+	/** Get an array containing basic information about all parts in the container in the stream. */
+	static Common::Array<PartInfo> *getPartsInfo(Common::SeekableReadStream &stream);
+};
+
+/** Reads a save. */
+class SaveReader : public SaveContainer {
+public:
+	SaveReader(uint32 partCount, uint32 slot, const char *fileName);
+	SaveReader(uint32 partCount, uint32 slot, Common::SeekableReadStream &stream);
+	~SaveReader();
+
+	bool load();
+
+	bool readPart(uint32 partN, SavePart *part) const;
+	bool readPartHeader(uint32 partN, SaveHeader *header) const;
+
+	/** Find and read the save's info part. */
+	static bool getInfo(Common::SeekableReadStream &stream, SavePartInfo &info);
+	/** Find and read the save's info part. */
+	static bool getInfo(const char *fileName, SavePartInfo &info);
+
+protected:
+	char *_fileName;
+	Common::SeekableReadStream *_stream;
+
+	bool _loaded;
+
+	static Common::InSaveFile *openSave(const char *fileName);
+	Common::InSaveFile *openSave();
+};
+
+/** Writes a save. */
+class SaveWriter: public SaveContainer {
+public:
+	SaveWriter(uint32 partCount, uint32 slot, const char *fileName = 0);
+	~SaveWriter();
+
+	bool writePart(uint32 partN, const SavePart *part);
+
+	bool save(Common::WriteStream &stream);
+
+protected:
+	bool save();
+
+	char *_fileName;
+
+	/** Is everything ready for saving? */
+	bool canSave() const;
+
+	static Common::OutSaveFile *openSave(const char *fileName);
+	Common::OutSaveFile *openSave();
+};
+
+} // End of namespace Gob
+
+#endif // GOB_SAVE_SAVEFILE_H


Property changes on: scummvm/trunk/engines/gob/save/savefile.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/engines/gob/save/savehandler.cpp
===================================================================
--- scummvm/trunk/engines/gob/save/savehandler.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/savehandler.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,503 @@
+/* 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/save/savehandler.h"
+#include "gob/save/savefile.h"
+#include "gob/save/saveconverter.h"
+#include "gob/global.h"
+#include "gob/video.h"
+#include "gob/draw.h"
+#include "gob/variables.h"
+#include "gob/inter.h"
+
+namespace Gob {
+
+SlotFile::SlotFile(GobEngine *vm, uint32 slotCount, const char *base) : _vm(vm) {
+	_base = strdupcpy(base);
+	_slotCount = slotCount;
+}
+
+SlotFile::~SlotFile() {
+	delete[] _base;
+}
+
+const char *SlotFile::getBase() const {
+	return _base;
+}
+
+uint32 SlotFile::getSlotMax() const {
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
+
+	// Find the last filled save slot and base the save file size calculate on that
+	for (int i = (_slotCount - 1); i >= 0; i--) {
+		char *slotFile = build(i);
+
+		if (!slotFile)
+			continue;
+
+		in = saveMan->openForLoading(slotFile);
+		delete[] slotFile;
+
+		if (in) {
+			delete in;
+			return i + 1;
+		}
+	}
+
+	return 0;
+}
+
+int32 SlotFile::tallyUpFiles(uint32 slotSize, uint32 indexSize) const {
+	uint32 maxSlot = getSlotMax();
+
+	if (maxSlot == 0)
+		return -1;
+
+	return ((maxSlot * slotSize) + indexSize);
+}
+
+void SlotFile::buildIndex(byte *buffer, SavePartInfo &info,
+		SaveConverter *converter) const {
+
+	uint32 descLength = info.getDescMaxLength();
+
+	// Iterate over all files
+	for (uint32 i = 0; i < _slotCount; i++, buffer += descLength) {
+		char *slotFile = build(i);
+
+		if (slotFile) {
+			char *desc = 0;
+
+			if (converter && (desc = converter->getDescription(slotFile)))
+				// Old style save
+				memcpy(buffer, desc, descLength);
+			else if (SaveReader::getInfo(slotFile, info))
+				// New style save
+				memcpy(buffer, info.getDesc(), descLength);
+			else
+				// No known format, fill with 0
+				memset(buffer, 0, descLength);
+
+			delete[] desc;
+
+		} else
+			// No valid slot, fill with 0
+			memset(buffer, 0, descLength);
+
+		delete[] slotFile;
+	}
+}
+
+bool SlotFile::exists(const char *name) const {
+	Common::InSaveFile *in = openRead(name);
+	bool result = (in != 0);
+	delete in;
+	return result;
+}
+
+bool SlotFile::exists(int slot) const {
+	Common::InSaveFile *in = openRead(slot);
+	bool result = (in != 0);
+	delete in;
+	return result;
+}
+
+bool SlotFile::exists() const {
+	Common::InSaveFile *in = openRead();
+	bool result = (in != 0);
+	delete in;
+	return result;
+}
+
+Common::InSaveFile *SlotFile::openRead(const char *name) const {
+	if (!name)
+		return 0;
+
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+
+	return saveMan->openForLoading(name);
+}
+
+Common::InSaveFile *SlotFile::openRead(int slot) const {
+	char *name = build(slot);
+	Common::InSaveFile *result = openRead(name);
+	delete[] name;
+	return result;
+}
+
+Common::InSaveFile *SlotFile::openRead() const {
+	char *name = build();
+	Common::InSaveFile *result = openRead(name);
+	delete[] name;
+	return result;
+}
+
+Common::OutSaveFile *SlotFile::openWrite(const char *name) const {
+	if (!name)
+		return 0;
+
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+
+	return saveMan->openForSaving(name);
+}
+
+Common::OutSaveFile *SlotFile::openWrite(int slot) const {
+	char *name = build(slot);
+	Common::OutSaveFile *result = openWrite(name);
+	delete[] name;
+	return result;
+}
+
+Common::OutSaveFile *SlotFile::openWrite() const {
+	char *name = build();
+	Common::OutSaveFile *result = openWrite(name);
+	delete[] name;
+	return result;
+}
+
+
+SlotFileIndexed::SlotFileIndexed(GobEngine *vm, uint32 slotCount,
+		const char *base, const char *extStub) : SlotFile(vm, slotCount, base) {
+
+	_ext = strdupcpy(extStub);
+}
+
+SlotFileIndexed::~SlotFileIndexed() {
+	delete[] _ext;
+}
+
+char *SlotFileIndexed::build(int slot) const {
+	if ((slot < 0) || (((uint32) slot) >= _slotCount))
+		return 0;
+
+	size_t len = strlen(_base) + strlen(_ext) + 4;
+
+	char *slotFile = new char[len];
+
+	snprintf(slotFile, len, "%s.%s%02d", _base, _ext, slot);
+
+	return slotFile;
+}
+
+char *SlotFileIndexed::build() const {
+	return 0;
+}
+
+
+SlotFileStatic::SlotFileStatic(GobEngine *vm, const char *base,
+		const char *ext) : SlotFile(vm, 1, base) {
+
+	_ext = strdupcat(".", ext);
+}
+
+SlotFileStatic::~SlotFileStatic() {
+	delete[] _ext;
+}
+
+int SlotFileStatic::getSlot(int32 offset) const {
+	return -1;
+}
+
+int SlotFileStatic::getSlotRemainder(int32 offset) const {
+	return -1;
+}
+
+char *SlotFileStatic::build(int slot) const {
+	return 0;
+}
+
+char *SlotFileStatic::build() const {
+	return strdupcat(_base, _ext);
+}
+
+
+SaveHandler::SaveHandler(GobEngine *vm) : _vm(vm) {
+}
+
+SaveHandler::~SaveHandler() {
+}
+
+uint32 SaveHandler::getVarSize(GobEngine *vm) {
+	// Sanity checks
+	if (!vm || !vm->_inter || !vm->_inter->_variables)
+		return 0;
+
+	return vm->_inter->_variables->getSize();
+}
+
+
+TempSpriteHandler::TempSpriteHandler(GobEngine *vm) : SaveHandler(vm) {
+	_sprite = 0;
+}
+
+TempSpriteHandler::~TempSpriteHandler() {
+	delete _sprite;
+}
+
+int32 TempSpriteHandler::getSize() {
+	if (!_sprite)
+		return -1;
+
+	return _sprite->getSize();
+}
+
+bool TempSpriteHandler::load(int16 dataVar, int32 size, int32 offset) {
+	// Sprite available?
+	if (!_sprite)
+		return false;
+
+	// Sprite requested?
+	if (!isSprite(size))
+		return false;
+
+	// Index sane?
+	int index = getIndex(size);
+	if ((index < 0) || (index >= SPRITES_COUNT))
+		return false;
+
+	SurfaceDesc *sprite = _vm->_draw->_spritesArray[index];
+
+	// Target sprite exists?
+	if (!sprite)
+		return false;
+
+	// Load the sprite
+	if (!_sprite->writeSprite(sprite))
+		return false;
+
+	// Handle palette
+	if (usesPalette(size)) {
+		if (!_sprite->writePalette((byte *) _vm->_global->_pPaletteDesc->vgaPal))
+			return false;
+
+		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+	}
+
+	if (index == 21) {
+		// We wrote into the backbuffer, blit
+		_vm->_draw->forceBlit();
+		_vm->_video->retrace();
+	} else if (index == 20)
+		// We wrote into the frontbuffer, retrace
+		_vm->_video->retrace();
+
+	return true;
+}
+
+bool TempSpriteHandler::save(int16 dataVar, int32 size, int32 offset) {
+	SurfaceDesc *sprite;
+
+	if (!createSprite(dataVar, size, offset, &sprite))
+		return false;
+
+	// Save the sprite
+	if (!_sprite->readSprite(sprite))
+		return false;
+
+	// Handle palette
+	if (usesPalette(size)) {
+		if (!_sprite->readPalette((const byte *) _vm->_global->_pPaletteDesc->vgaPal))
+			return false;
+	}
+
+	return true;
+}
+
+bool TempSpriteHandler::createSprite(int16 dataVar, int32 size,
+		int32 offset, SurfaceDesc **sprite) {
+
+	delete _sprite;
+	_sprite = 0;
+
+	// Sprite requested?
+	if (!isSprite(size))
+		return false;
+
+	// Index sane?
+	int index = getIndex(size);
+	if ((index < 0) || (index >= SPRITES_COUNT))
+		return false;
+
+	SurfaceDesc *sprt = _vm->_draw->_spritesArray[index];
+
+	// Sprite exists?
+	if (!sprt)
+		return false;
+
+	// Create a new temporary sprite
+	_sprite = new SavePartSprite(sprt->getWidth(), sprt->getHeight());
+
+	if (sprite)
+		*sprite = sprt;
+
+	return true;
+}
+
+// A negative size is the flag for using a sprite
+bool TempSpriteHandler::isSprite(int32 size) {
+	return (size < 0);
+}
+
+// Contruct the index
+int TempSpriteHandler::getIndex(int32 size) {
+	// Palette flag
+	if (size < -1000)
+		size += 1000;
+
+	return (-size - 1);
+}
+
+// A size smaller than -1000 indicates palette usage
+bool TempSpriteHandler::usesPalette(int32 size) {
+	return (size < -1000);
+}
+
+
+NotesHandler::File::File(GobEngine *vm, const char *base) :
+	SlotFileStatic(vm, base, "blo") {
+}
+
+NotesHandler::File::~File() {
+}
+
+NotesHandler::NotesHandler(uint32 notesSize, GobEngine *vm, const char *target) :
+	SaveHandler(vm) {
+
+	_notesSize = notesSize;
+
+	_file = new File(vm, target);
+
+	_notes = new SavePartVars(vm, _notesSize);
+}
+
+NotesHandler::~NotesHandler() {
+	delete _file;
+	delete _notes;
+}
+
+int32 NotesHandler::getSize() {
+	char *fileName = _file->build();
+
+	if (!fileName)
+		return -1;
+
+	Common::InSaveFile *saveFile;
+
+	SaveConverter_Notes converter(_vm, _notesSize, fileName);
+	if (converter.isOldSave(&saveFile)) {
+		// Old save, get the size olden-style
+
+		int32 size = saveFile->size();
+
+		delete saveFile;
+		return size;
+	}
+
+	SaveReader reader(1, 0, fileName);
+	SaveHeader header;
+
+	delete[] fileName;
+
+	if (!reader.load())
+		return -1;
+
+	if (!reader.readPartHeader(0, &header))
+		return -1;
+
+	// Return the part's size
+	return header.getSize();
+}
+
+bool NotesHandler::load(int16 dataVar, int32 size, int32 offset) {
+	if ((dataVar < 0) || (size < 0) || (offset < 0))
+		return false;
+
+	char *fileName = _file->build();
+
+	if (!fileName)
+		return false;
+
+	SaveReader *reader;
+
+	SaveConverter_Notes converter(_vm, _notesSize, fileName);
+	if (converter.isOldSave()) {
+		// Old save, plug the converter in
+		if (!converter.load())
+			return false;
+
+		reader = new SaveReader(1, 0, converter);
+
+	} else
+		// New save, load directly
+		reader = new SaveReader(1, 0, fileName);
+
+	SavePartVars vars(_vm, _notesSize);
+
+	delete[] fileName;
+
+	if (!reader->load()) {
+		delete reader;
+		return false;
+	}
+
+	if (!reader->readPart(0, &vars)) {
+		delete reader;
+		return false;
+	}
+
+	if (!vars.writeInto(dataVar, offset, size)) {
+		delete reader;
+		return false;
+	}
+
+	delete reader;
+	return true;
+}
+
+bool NotesHandler::save(int16 dataVar, int32 size, int32 offset) {
+	if ((dataVar < 0) || (size < 0) || (offset < 0))
+		return false;
+
+	char *fileName = _file->build();
+
+	if (!fileName)
+		return false;
+
+	SaveWriter writer(1, 0, fileName);
+	SavePartVars vars(_vm, _notesSize);
+
+	delete[] fileName;
+
+	if (!vars.readFrom(dataVar, offset, size))
+		return false;
+
+	return writer.writePart(0, &vars);
+}
+
+} // End of namespace Gob


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

Added: scummvm/trunk/engines/gob/save/savehandler.h
===================================================================
--- scummvm/trunk/engines/gob/save/savehandler.h	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/savehandler.h	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,191 @@
+/* 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$
+ *
+ */
+
+#ifndef GOB_SAVE_SAVEHANDLER_H
+#define GOB_SAVE_SAVEHANDLER_H
+
+#include "common/savefile.h"
+
+namespace Gob {
+
+class GobEngine;
+class SurfaceDesc;
+class SavePartInfo;
+class SavePartVars;
+class SavePartSprite;
+class SaveConverter;
+
+/** Slot file related class. */
+class SlotFile {
+public:
+	/** The constructor.
+	 *
+	 *  @param slotCount Number of slots.
+	 *  @param base The file's base string.
+	 */
+	SlotFile(GobEngine *vm, uint32 slotCount, const char *base);
+	virtual ~SlotFile();
+
+	/** Returns the base string. */
+	virtual const char *getBase() const;
+
+	/** Calculates which slot to use. */
+	virtual int getSlot(int32 offset) const = 0;
+	/** Calculates the slot remainder, for error checking. */
+	virtual int getSlotRemainder(int32 offset) const = 0;
+
+	/** Build the save file name. */
+	virtual char *build(int slot) const = 0;
+	/** Build the save file name. */
+	virtual char *build() const = 0;
+
+	/** Returns the highest filled slot number. */
+	virtual uint32 getSlotMax() const;
+
+	/** Returns the size of all existing slots + the index. */
+	virtual int32 tallyUpFiles(uint32 slotSize, uint32 indexSize) const;
+
+	/** Creates an index in buffer. */
+	virtual void buildIndex(byte *buffer, SavePartInfo &info,
+			SaveConverter *converter = 0) const;
+
+	virtual bool exists(const char *name) const;
+	virtual bool exists(int slot) const;
+	virtual bool exists() const;
+
+	virtual Common::InSaveFile *openRead(const char *name) const;
+	virtual Common::InSaveFile *openRead(int slot) const;
+	virtual Common::InSaveFile *openRead() const;
+
+	virtual Common::OutSaveFile *openWrite(const char *name) const;
+	virtual Common::OutSaveFile *openWrite(int slot) const;
+	virtual Common::OutSaveFile *openWrite() const;
+
+protected:
+	GobEngine *_vm;
+	char *_base;
+
+	uint32 _slotCount;
+};
+
+/** An indexed slot file ("foobar.s00", "foobar.s01", ...). */
+class SlotFileIndexed : public SlotFile {
+public:
+	SlotFileIndexed(GobEngine *vm, uint32 slotCount, const char *base,
+			const char *extStub);
+	~SlotFileIndexed();
+
+	char *build(int slot) const;
+	char *build() const;
+
+protected:
+	char *_ext;
+};
+
+/** A static slot file ("foo.bar"). */
+class SlotFileStatic : public SlotFile {
+public:
+	SlotFileStatic(GobEngine *vm, const char *base, const char *ext);
+	~SlotFileStatic();
+
+	int getSlot(int32 offset) const;
+	int getSlotRemainder(int32 offset) const;
+
+	char *build(int slot) const;
+	char *build() const;
+
+protected:
+	char *_ext;
+};
+
+/** A handler for a specific save file. */
+class SaveHandler {
+public:
+	SaveHandler(GobEngine *vm);
+	virtual ~SaveHandler();
+
+	/** Returns the file's (virtual) size. */
+	virtual int32 getSize() = 0;
+	/** Loads (parts of) the file. */
+	virtual bool load(int16 dataVar, int32 size, int32 offset) = 0;
+	/** Saves (parts of) the file. */
+	virtual bool save(int16 dataVar, int32 size, int32 offset) = 0;
+
+	static uint32 getVarSize(GobEngine *vm);
+
+protected:
+	GobEngine *_vm;
+};
+
+/** A handler for temporary sprites. */
+class TempSpriteHandler : public SaveHandler {
+public:
+	TempSpriteHandler(GobEngine *vm);
+	~TempSpriteHandler();
+
+	int32 getSize();
+	bool load(int16 dataVar, int32 size, int32 offset);
+	bool save(int16 dataVar, int32 size, int32 offset);
+
+	/** Create a fitting sprite. */
+	bool createSprite(int16 dataVar, int32 size,
+			int32 offset, SurfaceDesc **sprite = 0);
+
+protected:
+	SavePartSprite *_sprite;
+
+	/** Determine whether using a sprite was requested. */
+	static bool isSprite(int32 size);
+	/** Determine which sprite is meant. */
+	static int getIndex(int32 size);
+	/** Determine whether the palette should be used too. */
+	static bool usesPalette(int32 size);
+};
+
+/** A handler for notes. */
+class NotesHandler : public SaveHandler {
+public:
+	NotesHandler(uint32 notesSize, GobEngine *vm, const char *target);
+	~NotesHandler();
+
+	int32 getSize();
+	bool load(int16 dataVar, int32 size, int32 offset);
+	bool save(int16 dataVar, int32 size, int32 offset);
+
+private:
+	class File : public SlotFileStatic {
+	public:
+		File(GobEngine *vm, const char *base);
+		~File();
+	};
+
+	uint32 _notesSize;
+	File *_file;
+	SavePartVars *_notes;
+};
+
+} // End of namespace Gob
+
+#endif // GOB_SAVE_SAVEHANDLER_H


Property changes on: scummvm/trunk/engines/gob/save/savehandler.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/engines/gob/save/saveload.cpp
===================================================================
--- scummvm/trunk/engines/gob/save/saveload.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/saveload.cpp	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,135 @@
+/* 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 "common/savefile.h"
+
+#include "gob/gob.h"
+#include "gob/save/saveload.h"
+#include "gob/helper.h"
+#include "gob/global.h"
+#include "gob/video.h"
+#include "gob/draw.h"
+
+namespace Gob {
+
+SaveLoad::SaveLoad(GobEngine *vm, const char *targetName) : _vm(vm) {
+	_targetName = strdupcpy(targetName);
+}
+
+SaveLoad::~SaveLoad() {
+	delete[] _targetName;
+}
+
+const char *SaveLoad::stripPath(const char *fileName) {
+	const char *backSlash;
+	if ((backSlash = strrchr(fileName, '\\')))
+		return backSlash + 1;
+
+	return fileName;
+}
+
+int32 SaveLoad::getSize(const char *fileName) {
+	debugC(3, kDebugSaveLoad, "Requested size of save file \"%s\"", fileName);
+
+	SaveHandler *handler = getHandler(fileName);
+
+	if (!handler) {
+		warning("No save handler for \"%s\"", fileName);
+		return -1;
+	}
+
+	int32 size = handler->getSize();
+
+	debugC(4, kDebugSaveLoad, "Size is %d", size);
+	
+	return size;
+}
+
+bool SaveLoad::load(const char *fileName, int16 dataVar, int32 size, int32 offset) {
+	debugC(3, kDebugSaveLoad, "Requested loading of save file \"%s\" - %d, %d, %d",
+			fileName, dataVar, size, offset);
+
+	SaveHandler *handler = getHandler(fileName);
+
+	if (!handler) {
+		warning("No save handler for \"%s\" (%d, %d, %d)", fileName, dataVar, size, offset);
+		return false;
+	}
+
+	if (!handler->load(dataVar, size, offset)) {
+		const char *desc = getDescription(fileName);
+
+		if (!desc)
+			desc = "Unkown";
+
+		warning("Could not load %s (\"%s\" (%d, %d, %d))",
+				desc, fileName, dataVar, size, offset);
+		return false;
+	}
+
+	debugC(3, kDebugSaveLoad, "Successfully loaded game");
+	return true;
+}
+
+bool SaveLoad::save(const char *fileName, int16 dataVar, int32 size, int32 offset) {
+	debugC(3, kDebugSaveLoad, "Requested saving of save file \"%s\" - %d, %d, %d",
+			fileName, dataVar, size, offset);
+
+	SaveHandler *handler = getHandler(fileName);
+
+	if (!handler) {
+		warning("No save handler for \"%s\" (%d, %d, %d)", fileName, dataVar, size, offset);
+		return false;
+	}
+
+	if (!handler->save(dataVar, size, offset)) {
+		const char *desc = getDescription(fileName);
+
+		if (!desc)
+			desc = "Unkown";
+
+		warning("Could not save %s (\"%s\" (%d, %d, %d))",
+				desc, fileName, dataVar, size, offset);
+		return false;
+	}
+
+	debugC(3, kDebugSaveLoad, "Successfully saved game");
+	return true;
+}
+
+SaveLoad::SaveMode SaveLoad::getSaveMode(const char *fileName) const {
+	return kSaveModeNone;
+}
+
+SaveHandler *SaveLoad::getHandler(const char *fileName) const {
+	return 0;
+}
+
+const char *SaveLoad::getDescription(const char *fileName) const {
+	return 0;
+}
+
+} // End of namespace Gob


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

Added: scummvm/trunk/engines/gob/save/saveload.h
===================================================================
--- scummvm/trunk/engines/gob/save/saveload.h	                        (rev 0)
+++ scummvm/trunk/engines/gob/save/saveload.h	2009-05-31 02:15:43 UTC (rev 41056)
@@ -0,0 +1,452 @@
+/* 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$
+ *
+ */
+
+#ifndef GOB_SAVE_SAVELOAD_H
+#define GOB_SAVE_SAVELOAD_H
+
+#include "gob/save/savefile.h"
+#include "gob/save/savehandler.h"
+
+namespace Gob {
+

@@ Diff output truncated at 100000 characters. @@

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