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

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Sun Apr 8 02:08:27 CEST 2007


Revision: 26414
          http://scummvm.svn.sourceforge.net/scummvm/?rev=26414&view=rev
Author:   drmccoy
Date:     2007-04-07 17:08:26 -0700 (Sat, 07 Apr 2007)

Log Message:
-----------
Restructured saving/loading. Should work for Gob3 now, too...

Modified Paths:
--------------
    scummvm/trunk/engines/gob/global.cpp
    scummvm/trunk/engines/gob/global.h
    scummvm/trunk/engines/gob/gob.cpp
    scummvm/trunk/engines/gob/gob.h
    scummvm/trunk/engines/gob/inter_v2.cpp
    scummvm/trunk/engines/gob/inter_v3.cpp
    scummvm/trunk/engines/gob/module.mk

Added 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

Modified: scummvm/trunk/engines/gob/global.cpp
===================================================================
--- scummvm/trunk/engines/gob/global.cpp	2007-04-08 00:00:38 UTC (rev 26413)
+++ scummvm/trunk/engines/gob/global.cpp	2007-04-08 00:08:26 UTC (rev 26414)
@@ -125,9 +125,6 @@
 
 	_inter_mouseX = 0;
 	_inter_mouseY = 0;
-
-	_savedBack = 0;
-	_savedBackSize = -1;
 }
 
 Global::~Global() {

Modified: scummvm/trunk/engines/gob/global.h
===================================================================
--- scummvm/trunk/engines/gob/global.h	2007-04-08 00:00:38 UTC (rev 26413)
+++ scummvm/trunk/engines/gob/global.h	2007-04-08 00:08:26 UTC (rev 26414)
@@ -125,13 +125,6 @@
 	int16 _inter_mouseX;
 	int16 _inter_mouseY;
 
-	// While using the notepad or changing the font, the original executable
-	// temporarily dumps Draw::_backSurface to a file. Since that's not really
-	// a nice thing to do, we work around it.
-	SurfaceDesc::Ptr _savedBack;
-	Video::Color _savedPal[256];
-	int32 _savedBackSize;
-
 	void clearVars(uint32 count) {
 		uint32 size = count * 4;
 

Modified: scummvm/trunk/engines/gob/gob.cpp
===================================================================
--- scummvm/trunk/engines/gob/gob.cpp	2007-04-08 00:00:38 UTC (rev 26413)
+++ scummvm/trunk/engines/gob/gob.cpp	2007-04-08 00:08:26 UTC (rev 26414)
@@ -47,11 +47,8 @@
 #include "gob/scenery.h"
 #include "gob/music.h"
 #include "gob/imd.h"
+#include "gob/saveload.h"
 
-// Use the original saves. Just for testing purposes, will be removed later
-// The new method is more convenient, and, more importantly, endian-safe
-//#define GOB_ORIGSAVES
-
 namespace Gob {
 
 #define MAX_TIME_DELTA 100
@@ -80,18 +77,6 @@
 	_copyProtection = ConfMan.getBool("copy_protection");
 	_quitRequested = false;
 
-	int i;
-	_saveFiles = new char*[3];
-	for (i = 0; i < 3; i++)
-		_saveFiles[i] = new char[_targetName.size() + 5];
-	sprintf(_saveFiles[0], "%s.cat", _targetName.c_str());
-	sprintf(_saveFiles[1], "%s.sav", _targetName.c_str());
-	sprintf(_saveFiles[2], "%s.blo", _targetName.c_str());
-	_saveSlotFile = new char[_targetName.size() + 5];
-	sprintf(_saveSlotFile, "%s.s00", _targetName.c_str());
-	memset(_saveIndex, 0, 600);
-	memset(_saveIndexSizes, 0, 600);
-
 	Common::addSpecialDebugLevel(kDebugFuncOp, "FuncOpcodes", "Script FuncOpcodes debug level");
 	Common::addSpecialDebugLevel(kDebugDrawOp, "DrawOpcodes", "Script DrawOpcodes debug level");
 	Common::addSpecialDebugLevel(kDebugGobOp, "GoblinOpcodes", "Script GoblinOpcodes debug level");
@@ -125,13 +110,9 @@
 	delete _draw;
 	delete _util;
 	delete _video;
+	delete _saveLoad;
 	delete[] _startTot;
 	delete[] _startTot0;
-
-	for (int i = 0; i < 3; i++)
-		delete[] _saveFiles[i];
-	delete[] _saveFiles;
-	delete[] _saveSlotFile;
 }
 
 int GobEngine::go() {
@@ -144,418 +125,6 @@
 	_quitRequested = true;
 }
 
-int32 GobEngine::getSaveSize(enum SaveFiles sFile) {
-	int32 size;
-	Common::InSaveFile *in;
-
-	size = -1;
-#ifndef GOB_ORIGSAVES
-	int i;
-	if (sFile == SAVE_CAT) {
-		for (i = 14; i >= 0; i--)
-			if ((in = _saveFileMan->openForLoading(getSaveSlotFile(i)))) {
-				size = (i + 1) * READ_LE_UINT32(_game->_totFileData + 0x2C) * 4 + 600;
-				delete in;
-				break;
-			}
-		debugC(1, kDebugFileIO, "Requested save games size: %d", size);
-		return size;
-	}
-#endif // GOB_ORIGSAVES
-
-	if (sFile == SAVE_SAV)
-		size = _global->_savedBack == 0 ? -1 : _global->_savedBackSize;
-	else if ((in = _saveFileMan->openForLoading(_saveFiles[(int) sFile]))) {
-		size = in->size();
-		delete in;
-	}
-
-	debugC(1, kDebugFileIO, "Requested size of file \"%s\": %d", _saveFiles[(int) sFile], size);
-
-	return size;
-}
-
-const char *GobEngine::getSaveSlotFile(int slot) {
-	static char *slotBase = _saveSlotFile + strlen(_targetName.c_str()) + 2;
-
-	snprintf(slotBase, 3, "%02d", slot);
-	return _saveSlotFile;
-}
-
-void GobEngine::saveGameData(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset) {
-	int16 index;
-	bool writePal;
-	char *sName;
-	byte *buf;
-	byte *oBuf;
-	int32 retSize;
-	int32 iSize;
-	int32 oSize;
-	int32 oOff;
-	SurfaceDesc *srcDesc;
-	Common::InSaveFile *in;
-	Common::OutSaveFile *out;
-
-	retSize = 0;
-	index = 0;
-	oBuf = 0;
-	in = 0;
-	writePal = false;
-	sName = _saveFiles[(int) sFile];
-
-	WRITE_VAR(1, 1);
-
-	if (sFile == SAVE_SAV) {
-		_global->_savedBackSize = -1;
-		if (size >= 0) {
-			warning("Invalid attempt at saving a sprite");
-			return;
-		}
-		if (size < -1000) {
-			size += 1000;
-			writePal = true;
-			memcpy((char *) _global->_savedPal, (char *) _global->_pPaletteDesc->vgaPal, 768);
-		}
-		index = -size - 1;
-		if ((index < 0) || (index >= 50)) {
-			warning("Invalid attempt at saving a sprite");
-			return;
-		}
-		srcDesc = _draw->_spritesArray[index];
-
-		_global->_savedBack =
-			_video->initSurfDesc(_vm->_global->_videoMode, srcDesc->getWidth(), srcDesc->getHeight(), 0);
-		_vm->_video->drawSprite(srcDesc, _global->_savedBack, 0, 0,
-				srcDesc->getWidth() - 1, srcDesc->getHeight() - 1, 0, 0, 0);
-
-		_global->_savedBackSize = _draw->getSpriteRectSize(index);
-		if (writePal)
-			_global->_savedBackSize += 768;
-
-		WRITE_VAR(1, 0);
-		return;
-	}
-
-	if (size < 0) {
-		warning("Invalid saving procedure");
-		return;
-	}
-
-	int32 varSize = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
-
-	if (size == 0) {
-		dataVar = 0;
-		size = varSize;
-	}
-	buf = _global->_inter_variables + dataVar;
-#ifndef GOB_ORIGSAVES
-	if (sFile == SAVE_CAT) {
-		if (saveGame((offset - 600) / varSize, dataVar, size, offset))
-			WRITE_VAR(1, 0);
-		return;
-	} else if (offset != 0) {
-		warning("Can't write file \"%s\": Can't correctly enfore endianness with offset", sName);
-		return;
-	}
-#endif // GOB_ORIGSAVES
-
-	if ((in = _saveFileMan->openForLoading(sName)))
-		iSize = in->size();
-	else
-		iSize = 0;
-
-	oOff = offset < 0 ? MAX((int32) 0, iSize - (-offset - 1)) : offset;
-	oSize = MAX(iSize, oOff + size);
-	oBuf = new byte[oSize];
-	memset(oBuf, 0, oSize);
-
-	if (in) {
-		in->read(oBuf, iSize);
-		delete in;
-	}
-
-	if (!(out = _saveFileMan->openForSaving(sName))) {
-		warning("Can't open file \"%s\" for writing", sName);
-		delete[] oBuf;
-		return;
-	}
-	
-	retSize = writeDataEndian(*out, buf, _global->_inter_variablesSizes + dataVar, size);
-
-	out->finalize();
-
-	if (out->ioFailed() || (retSize != size))
-		warning("Can't write file \"%s\"", sName);
-	else {
-		debugC(1, kDebugFileIO, "Saved file \"%s\" (%d, %d bytes at %d)",
-				sName, dataVar, size, offset);
-		WRITE_VAR(1, 0);
-	}
-
-	delete out;
-	delete[] oBuf;
-}
-
-bool GobEngine::saveGame(int saveSlot, int16 dataVar, int32 size, int32 offset) {
-	int32 varSize;
-	byte *varBuf;
-	byte *sizeBuf;
-	Common::OutSaveFile *out;
-
-	varBuf = _global->_inter_variables + dataVar;
-	sizeBuf = _global->_inter_variablesSizes + dataVar;
-	varSize = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
-	if ((offset == 0) && (size == 600)) {
-		memcpy(_saveIndex, varBuf, size);
-		memcpy(_saveIndexSizes, sizeBuf, size);
-		return true;
-	} else if ((((offset - 600) % varSize) == 0) && (size == varSize)) {
-		if (!(out = _saveFileMan->openForSaving(getSaveSlotFile(saveSlot)))) {
-			warning("Can't open file \"%s\" for writing", getSaveSlotFile(saveSlot));
-			return false;
-		}
-		writeDataEndian(*out, _saveIndex + saveSlot * 40, _saveIndexSizes + saveSlot * 40, 40);
-		writeDataEndian(*out, varBuf, sizeBuf, size);
-		out->finalize();
-		if (out->ioFailed()) {
-			warning("Can't save to slot %d", saveSlot);
-			return false;
-		}
-		debugC(1, kDebugFileIO, "Saved to slot %d", saveSlot);
-		delete out;
-		return true;
-	} else {
-		warning("Invalid saving procedure");
-		return false;
-	}
-}
-
-uint32 GobEngine::writeDataEndian(Common::OutSaveFile &out, byte *varBuf, byte *sizeBuf,
-		int32 size) {
-
-#ifndef GOB_ORIGSAVES
-
-	int i;
-	byte tmp[4];
-	uint32 written;
-
-	written = 0;
-	for (i = 0; i < size; i++, varBuf++) {
-		if (sizeBuf[i] == 3)
-			WRITE_LE_UINT32(tmp, *((uint32 *) varBuf));
-		else if (sizeBuf[i] == 1)
-			WRITE_LE_UINT16(tmp, *((uint16 *) varBuf));
-		else if (sizeBuf[i] == 0)
-			*tmp = *varBuf;
-		else {
-			warning("Can't write data, corrupted variables sizes");
-			return 0;
-		}
-		written += out.write(tmp, sizeBuf[i] + 1);
-		varBuf += sizeBuf[i];
-		i += sizeBuf[i];
-	}
-
-	out.write(sizeBuf, size);
-
-	return written;
-
-#else // GOB_ORIGSAVES
-
-	return out.write(varBuf, size);
-
-#endif // GOB_ORIGSAVES
-
-}
-
-void GobEngine::loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset) {
-	int32 sSize;
-	int32 retSize;
-	int16 index;
-	byte *buf;
-	char *sName;
-	bool readPal;
-	SurfaceDesc *destDesc;
-	Common::InSaveFile *in;
-
-	index = 0;
-	readPal = false;
-	sName = _saveFiles[(int) sFile];
-
-	WRITE_VAR(1, 1);
-	
-	if (sFile == SAVE_SAV) {
-		if (size >= 0) {
-			warning("Invalid attempt at loading a sprite");
-			return;
-		}
-		if (size < -1000) {
-			size += 1000;
-			readPal = true;
-			memcpy((char *) _global->_pPaletteDesc->vgaPal, (char *) _global->_savedPal, 768);
-		}
-		index = -size - 1;
-		if ((index < 0) || (index >= 50)) {
-			warning("Invalid attempt at loading a sprite");
-			return;
-		}
-		destDesc = _draw->_spritesArray[index];
-
-		if ((destDesc->getWidth() != _global->_savedBack->getWidth()) ||
-		    (destDesc->getHeight() != _global->_savedBack->getHeight())) {
-			warning("Resolution doesn't match while loading a sprite");
-			return;
-		}
-
-		_vm->_video->drawSprite(_global->_savedBack, destDesc, 0, 0,
-				destDesc->getWidth() - 1, destDesc->getHeight() - 1, 0, 0, 0);
-		if (index == 21) {
-			_vm->_draw->forceBlit();
-			_video->waitRetrace();
-		}
-
-		WRITE_VAR(1, 0);
-		return;
-	}
-
-	if (size < 0) {
-		warning("Invalid loading procedure");
-		return;
-	}
-
-	int32 varSize;
-	varSize = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
-	if (size == 0) {
-		dataVar = 0;
-		size = varSize;
-	}
-	buf = _global->_inter_variables + dataVar;
-#ifndef GOB_ORIGSAVES
-	if (sFile == SAVE_CAT) {
-		if (loadGame((offset - 600) / varSize, dataVar, size, offset))
-			WRITE_VAR(1, 0);
-		return;
-	} else if (offset != 0) {
-		warning("Can't read file \"%s\": Can't correctly enfore endianness with offset", sName);
-		return;
-	}
-#endif // GOB_ORIGSAVES
-
-	if (_global->_inter_resStr[0] == 0) {
-		WRITE_VAR(1, size);
-		return;
-	}
-
-	if (!(in = _saveFileMan->openForLoading(sName))) {
-		warning("Can't open file \"%s\" for reading", sName);
-		return;
-	}
-
-	debugC(1, kDebugFileIO, "Loading file \"%s\" (%d, %d bytes at %d)",
-			sName, dataVar, size, offset);
-
-	sSize = in->size();
-	_draw->animateCursor(4);
-	if (offset < 0)
-		in->seek(sSize - (-offset - 1), 0);
-	else
-		in->seek(offset, 0);
-
-	retSize = readDataEndian(*in, buf, _global->_inter_variablesSizes + dataVar, size);
-
-	if (retSize == size)
-		WRITE_VAR(1, 0);
-
-	delete in;
-	return;
-}
-
-bool GobEngine::loadGame(int saveSlot, int16 dataVar, int32 size, int32 offset) {
-	int i;
-	int32 varSize;
-	byte *varBuf;
-	byte *sizeBuf;
-	Common::InSaveFile *in;
-
-	varBuf = _global->_inter_variables + dataVar;
-	sizeBuf = _global->_inter_variablesSizes + dataVar;
-	varSize = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
-	if ((offset == 0) && (size == 600)) {
-		for (i = 0; i < 15; i++, varBuf += 40) {
-			if ((in = _saveFileMan->openForLoading(getSaveSlotFile(i)))) {
-				in->read(varBuf, 40);
-				delete in;
-			} else
-				memset(varBuf, 0, 40);
-		}
-		return true;
-	} else if ((((offset - 600) % varSize) == 0) && (size == varSize)) {
-		if (!(in = _saveFileMan->openForLoading(getSaveSlotFile(saveSlot)))) {
-			warning("Can't load from slot %d", saveSlot);
-			return false;
-		}
-		if (((in->size() / 2) - 40) != (uint32) varSize) {
-			warning("Can't load from slot %d: Wrong size", saveSlot);
-			return false;
-		}
-		in->seek(80);
-		readDataEndian(*in, varBuf, sizeBuf, size);
-		delete in;
-		debugC(1, kDebugFileIO, "Loading from slot %d", saveSlot);
-		return true;
-	} else {
-		warning("Invalid loading procedure");
-		return false;
-	}
-}
-
-uint32 GobEngine::readDataEndian(Common::InSaveFile &in, byte *varBuf, byte *sizeBuf,
-		int32 size) {
-
-#ifndef GOB_ORIGSAVES
-
-	uint32 read;
-	byte *vars;
-	byte *sizes;
-	int i;
-
-	vars = new byte[size];
-	sizes = new byte[size];
-
-	read = in.read(vars, size);
-	if (in.read(sizes, size) != read) {
-		warning("Can't read data: Corrupted variables sizes");
-		delete[] vars;
-		delete[] sizes;
-		return 0;
-	}
-
-	for (i = 0; i < size; i++) {
-		if (sizes[i] == 3)
-			*((uint32 *) (vars + i)) = READ_LE_UINT32(vars + i);
-		else if (sizes[i] == 1)
-			*((uint16 *) (vars + i)) = READ_LE_UINT16(vars + i);
-		else if (sizes[i] != 0) {
-			warning("Can't read data: Corrupted variables sizes");
-			return 0;
-		}
-		i += sizes[i];
-	}
-
-	memcpy(varBuf, vars, size);
-	memcpy(sizeBuf, sizes, size);
-	delete[] vars;
-	delete[] sizes;
-
-	return read;
-	
-#else // GOB_ORIGSAVES
-
-	return in.read(varBuf, size);
-
-#endif // GOB_ORIGSAVES
-}
-
 void GobEngine::validateLanguage() {
 	if (_vm->_global->_languageWanted != _vm->_global->_language) {
 		warning("Your game version doesn't support the requested language");
@@ -578,6 +147,7 @@
 	}
 
 	_adlib = 0;
+	_saveLoad = 0;
 	_global = new Global(this);
 	_util = new Util(this);
 	_dataIO = new DataIO(this);
@@ -607,6 +177,7 @@
 		_map = new Map_v2(this);
 		_goblin = new Goblin_v2(this);
 		_scenery = new Scenery_v2(this);
+		_saveLoad = new SaveLoad_v2(this, _targetName.c_str());
 	} else if (_features & Gob::GF_BARGON) {
 		_init = new Init_v2(this);
 		_video = new Video_v2(this);
@@ -618,6 +189,7 @@
 		_map = new Map_v2(this);
 		_goblin = new Goblin_v2(this);
 		_scenery = new Scenery_v2(this);
+		_saveLoad = new SaveLoad_v2(this, _targetName.c_str());
 	} else if (_features & Gob::GF_GOB3) {
 		_init = new Init_v2(this);
 		_video = new Video_v2(this);
@@ -629,6 +201,7 @@
 		_map = new Map_v2(this);
 		_goblin = new Goblin_v3(this);
 		_scenery = new Scenery_v2(this);
+		_saveLoad = new SaveLoad_v3(this, _targetName.c_str());
 	} else
 		error("GobEngine::init(): Unknown version of game engine");
 

Modified: scummvm/trunk/engines/gob/gob.h
===================================================================
--- scummvm/trunk/engines/gob/gob.h	2007-04-08 00:00:38 UTC (rev 26413)
+++ scummvm/trunk/engines/gob/gob.h	2007-04-08 00:08:26 UTC (rev 26414)
@@ -48,6 +48,7 @@
 class Parse;
 class Scenery;
 class Util;
+class SaveLoad;
 class Adlib;
 
 #define VARP(offs)			(_vm->_global->_inter_variables + (offs))
@@ -96,13 +97,6 @@
 	kDebugCollisions = 1 << 8
 };
 
-enum SaveFiles {
-	SAVE_CAT = 0, // Saves
-	SAVE_SAV,     // Holds a sprite, normally a cache for Draw::_backBuffer
-	              // (see Global::_savedBack)
-	SAVE_BLO      // Notes
-};
-
 inline char *strncpy0(char *dest, const char *src, size_t n) {
 	strncpy(dest, src, n);
 	dest[n] = 0;
@@ -163,21 +157,11 @@
 
 class GobEngine : public Engine {
 protected:
-	char **_saveFiles;
-	char *_saveSlotFile;
-	byte _saveIndex[600];
-	byte _saveIndexSizes[600];
 	GobEngine *_vm;
 
 	int go();
 	int init();
 
-	const char *getSaveSlotFile(int slot);
-	bool saveGame(int saveSlot, int16 dataVar, int32 size, int32 offset);
-	bool loadGame(int saveSlot, int16 dataVar, int32 size, int32 offset);
-	uint32 writeDataEndian(Common::OutSaveFile &out, byte *varBuf, byte *sizeBuf, int32 size);
-	uint32 readDataEndian(Common::InSaveFile &in, byte *varBuf, byte *sizeBuf, int32 size);
-
 	bool detectGame();
 
 public:
@@ -210,14 +194,12 @@
 	Parse *_parse;
 	Scenery *_scenery;
 	Inter *_inter;
+	SaveLoad *_saveLoad;
 	Adlib *_adlib;
 	ImdPlayer *_imdPlayer;
 
 	void shutdown();
 
-	int32 getSaveSize(enum SaveFiles sFile);
-	void saveGameData(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset);
-	void loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset);
 	const char *getLangDesc(int16 language) {
 		if ((language < 0) || (language > 8))
 			language = 2;

Modified: scummvm/trunk/engines/gob/inter_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v2.cpp	2007-04-08 00:00:38 UTC (rev 26413)
+++ scummvm/trunk/engines/gob/inter_v2.cpp	2007-04-08 00:08:26 UTC (rev 26414)
@@ -43,6 +43,7 @@
 #include "gob/scenery.h"
 #include "gob/sound.h"
 #include "gob/video.h"
+#include "gob/saveload.h"
 
 namespace Gob {
 
@@ -1776,21 +1777,16 @@
 	int16 handle;
 	int16 varOff;
 	int32 size;
+	SaveType type;
 
 	evalExpr(0);
 	varOff = _vm->_parse->parseVarIndex();
 
 	size = -1;
 	handle = 1;
-	if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf"))
-		size = _vm->getSaveSize(SAVE_CAT);
-	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat"))
-		size = _vm->getSaveSize(SAVE_CAT);
-	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf"))
-		size = _vm->getSaveSize(SAVE_SAV);
-	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf"))
-		size = _vm->getSaveSize(SAVE_BLO);
-	else {
+
+	type = _vm->_saveLoad->getSaveType(_vm->_global->_inter_resStr);
+	if (type == kSaveNone) {
 		handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr);
 
 		if (handle >= 0) {
@@ -1798,10 +1794,15 @@
 			size = _vm->_dataIO->getDataSize(_vm->_global->_inter_resStr);
 		} else
 			warning("File \"%s\" not found", _vm->_global->_inter_resStr);
-	}
+	} else
+		size = _vm->_saveLoad->getSize(type);
+
 	if (size == -1)
 		handle = -1;
 
+	debugC(2, kDebugFileIO, "Requested size of file \"%s\": %d",
+			_vm->_global->_inter_resStr, size);
+
 	WRITE_VAR_OFFSET(varOff, handle);
 	WRITE_VAR(16, (uint32) size);
 
@@ -1815,6 +1816,7 @@
 	int16 dataVar;
 	int16 handle;
 	byte *buf;
+	SaveType type;
 
 	evalExpr(0);
 	dataVar = _vm->_parse->parseVarIndex();
@@ -1825,18 +1827,12 @@
 	debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)",
 			_vm->_global->_inter_resStr, dataVar, size, offset);
 
-	if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) {
-		_vm->loadGameData(SAVE_CAT, dataVar, size, offset);
+	type = _vm->_saveLoad->getSaveType(_vm->_global->_inter_resStr);
+	if (type != kSaveNone) {
+		WRITE_VAR(1, 1);
+		if (_vm->_saveLoad->load(type, dataVar, size, offset))
+			WRITE_VAR(1, 0);
 		return false;
-	} else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat")) {
-		_vm->loadGameData(SAVE_CAT, dataVar, size, offset);
-		return false;
-	} else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf")) {
-		_vm->loadGameData(SAVE_SAV, dataVar, size, offset);
-		return false;
-	} else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf")) {
-		_vm->loadGameData(SAVE_BLO, dataVar, size, offset);
-		return false;
 	}
 
 	if (size < 0) {
@@ -1888,6 +1884,7 @@
 	int32 offset;
 	int32 size;
 	int16 dataVar;
+	SaveType type;
 
 	evalExpr(0);
 	dataVar = _vm->_parse->parseVarIndex();
@@ -1898,15 +1895,13 @@
 	debugC(2, kDebugFileIO, "Write to file \"%s\" (%d, %d bytes at %d)",
 			_vm->_global->_inter_resStr, dataVar, size, offset);
 
-	if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf"))
-		_vm->saveGameData(SAVE_CAT, dataVar, size, offset);
-	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat"))
-		_vm->saveGameData(SAVE_CAT, dataVar, size, offset);
-	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf"))
-		_vm->saveGameData(SAVE_SAV, dataVar, size, offset);
-	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf"))
-		_vm->saveGameData(SAVE_BLO, dataVar, size, offset);
-	else
+	WRITE_VAR(1, 1);
+
+	type = _vm->_saveLoad->getSaveType(_vm->_global->_inter_resStr);
+	if (type != kSaveNone) {
+		if (_vm->_saveLoad->save(type, dataVar, size, offset))
+			WRITE_VAR(1, 0);
+	} else
 		warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr);
 
 	return false;

Modified: scummvm/trunk/engines/gob/inter_v3.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v3.cpp	2007-04-08 00:00:38 UTC (rev 26413)
+++ scummvm/trunk/engines/gob/inter_v3.cpp	2007-04-08 00:08:26 UTC (rev 26414)
@@ -23,6 +23,7 @@
 
 #include "common/stdafx.h"
 #include "common/endian.h"
+#include "common/file.h"
 
 #include "gob/gob.h"
 #include "gob/inter.h"
@@ -518,7 +519,7 @@
 		OPCODE(o1_waitEndPlay),
 		OPCODE(o1_playComposition),
 		OPCODE(o2_getFreeMem),
-		OPCODE(o3_checkData),
+		OPCODE(o2_checkData),
 		/* 40 */
 		{NULL, ""},
 		OPCODE(o1_prepareStr),
@@ -536,8 +537,8 @@
 		OPCODE(o1_loadFont),
 		/* 4C */
 		OPCODE(o1_freeFont),
-		OPCODE(o3_readData),
-		OPCODE(o3_writeData),
+		OPCODE(o2_readData),
+		OPCODE(o2_writeData),
 		OPCODE(o1_manageDataFile),
 	};
 
@@ -891,130 +892,4 @@
 	return false;
 }
 
-bool Inter_v3::o3_checkData(OpFuncParams &params) {
-	int16 handle;
-	int16 varOff;
-	int32 size;
-
-	evalExpr(0);
-	varOff = _vm->_parse->parseVarIndex();
-
-	size = -1;
-	handle = 1;
-	if (!scumm_stricmp(_vm->_global->_inter_resStr, "intro.$$$"))
-		size = _vm->getSaveSize(SAVE_SAV);
-	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf"))
-		warning("Gob3 Stub: Requested save file size");
-	else {
-		handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr);
-
-		if (handle >= 0) {
-			_vm->_dataIO->closeData(handle);
-			size = _vm->_dataIO->getDataSize(_vm->_global->_inter_resStr);
-		} else
-			warning("File \"%s\" not found", _vm->_global->_inter_resStr);
-	}
-	if (size == -1)
-		handle = -1;
-
-	WRITE_VAR_OFFSET(varOff, handle);
-	WRITE_VAR(16, (uint32) size);
-
-	return false;
-}
-
-bool Inter_v3::o3_readData(OpFuncParams &params) {
-	int32 retSize;
-	int32 size;
-	int32 offset;
-	int16 dataVar;
-	int16 handle;
-	byte *buf;
-
-	evalExpr(0);
-	dataVar = _vm->_parse->parseVarIndex();
-	size = _vm->_parse->parseValExpr();
-	evalExpr(0);
-	offset = _vm->_global->_inter_resVal;
-
-	debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)",
-			_vm->_global->_inter_resStr, dataVar, size, offset);
-
-	if (!scumm_stricmp(_vm->_global->_inter_resStr, "intro.$$$")) {
-		_vm->loadGameData(SAVE_SAV, dataVar, size, offset);
-		return false;
-	} else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) {
-		warning("Gob3 Stub: Game state loading");
-		return false;
-	}
-
-	if (size < 0) {
-		warning("Attempted to read a raw sprite from file \"%s\"",
-				_vm->_global->_inter_resStr);
-		return false ;
-	} else if (size == 0) {
-		dataVar = 0;
-		size = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
-	}
-
-	buf = _vm->_global->_inter_variables + dataVar;
-	memset(_vm->_global->_inter_variablesSizes + dataVar, 0, size);
-
-	if (_vm->_global->_inter_resStr[0] == 0) {
-		WRITE_VAR(1, size);
-		return false;
-	}
-
-	WRITE_VAR(1, 1);
-	handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr);
-
-	if (handle < 0)
-		return false;
-
-	_vm->_draw->animateCursor(4);
-	if (offset < 0)
-		_vm->_dataIO->seekData(handle, -offset - 1, SEEK_END);
-	else
-		_vm->_dataIO->seekData(handle, offset, SEEK_SET);
-
-	if (((dataVar >> 2) == 59) && (size == 4)) {
-		WRITE_VAR(59, _vm->_dataIO->readUint32(handle));
-		// The scripts in some versions divide through 256^3 then,
-		// effectively doing a LE->BE conversion
-		if ((_vm->_platform != Common::kPlatformPC) && (VAR(59) < 256))
-			WRITE_VAR(59, SWAP_BYTES_32(VAR(59)));
-	} else
-		retSize = _vm->_dataIO->readData(handle, buf, size);
-
-	if (retSize == size)
-		WRITE_VAR(1, 0);
-
-	_vm->_dataIO->closeData(handle);
-	return false;
-}
-
-bool Inter_v3::o3_writeData(OpFuncParams &params) {
-	int32 offset;
-	int32 size;
-	int16 dataVar;
-
-	evalExpr(0);
-	dataVar = _vm->_parse->parseVarIndex();
-	size = _vm->_parse->parseValExpr();
-	evalExpr(0);
-	offset = _vm->_global->_inter_resVal;
-
-	debugC(2, kDebugFileIO, "Write to file \"%s\" (%d, %d bytes at %d)",
-			_vm->_global->_inter_resStr, dataVar, size, offset);
-
-	if (!scumm_stricmp(_vm->_global->_inter_resStr, "intro.$$$"))
-		_vm->saveGameData(SAVE_SAV, dataVar, size, offset);
-	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf"))
-		warning("Gob3 Stub: Game state saving");
-	else
-		warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr);
-
-	return false;
-}
-
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/module.mk
===================================================================
--- scummvm/trunk/engines/gob/module.mk	2007-04-08 00:00:38 UTC (rev 26413)
+++ scummvm/trunk/engines/gob/module.mk	2007-04-08 00:08:26 UTC (rev 26414)
@@ -38,6 +38,9 @@
 	parse.o \
 	parse_v1.o \
 	parse_v2.o \
+	saveload.o \
+	saveload_v2.o \
+	saveload_v3.o \
 	scenery.o \
 	scenery_v1.o \
 	scenery_v2.o \

Added: scummvm/trunk/engines/gob/saveload.cpp
===================================================================
--- scummvm/trunk/engines/gob/saveload.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/saveload.cpp	2007-04-08 00:08:26 UTC (rev 26414)
@@ -0,0 +1,511 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004 Ivan Dubrov
+ * Copyright (C) 2004-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "common/endian.h"
+#include "common/file.h"
+
+#include "gob/gob.h"
+#include "gob/saveload.h"
+#include "gob/global.h"
+#include "gob/draw.h"
+#include "gob/video.h"
+
+namespace Gob {
+
+SaveLoad::SaveLoad(GobEngine *vm, const char *targetName) : _vm(vm) {
+	_curSlot = -1;
+
+	_stagesCount = 0;
+	_buffer = 0;
+
+	_tempSprite = 0;
+	memset(_tempPal, 0, 768);
+	_tempSpriteSize = -1;
+
+	_saveFiles = new char*[5];
+
+	assert(_saveFiles);
+
+	_saveFiles[0] = new char[strlen(targetName) + 5];
+	_saveFiles[1] = 0;
+	_saveFiles[2] = new char[strlen(targetName) + 5];
+	_saveFiles[3] = _saveFiles[0];
+	_saveFiles[4] = 0;
+
+	assert(_saveFiles[0] && _saveFiles[2]);
+
+	sprintf(_saveFiles[0], "%s.s00", targetName);
+	sprintf(_saveFiles[2], "%s.blo", targetName);
+}
+
+SaveLoad::~SaveLoad() {
+	for (int i = 0; i < _stagesCount; i++)
+		delete[] _buffer[i];
+	delete[] _buffer;
+
+	delete _tempSprite;
+
+	delete[] _saveFiles[0];
+	delete[] _saveFiles[2];
+	delete[] _saveFiles; 
+}
+
+const char *SaveLoad::setCurSlot(int slot) {
+	static char *slotBase = _saveFiles[0] + strlen(_saveFiles[0]) - 2;
+
+	if (_curSlot != slot) {
+		_curSlot = slot;
+
+		if (_curSlot >= 0)
+			snprintf(slotBase, 3, "%02d", slot);
+	}
+
+	return _saveFiles[0];
+}
+
+uint32 SaveLoad::read(Common::ReadStream &in, byte *buf,
+		byte *sizes, uint32 count) {
+	uint32 nRead;
+
+	nRead = in.read(buf, count);
+	if (nRead != count) {
+		warning("Can't read data: requested %d, got %d", count, nRead);
+		return 0;
+	}
+
+	nRead = in.read(sizes, count);
+	if (nRead != count) {
+		warning("Can't read data sizes: requested %d, got %d", count, nRead);
+		return 0;
+	}
+
+	return count;
+}
+
+uint32 SaveLoad::write(Common::WriteStream &out, byte *buf,
+		byte *sizes, uint32 count) {
+	uint32 written;
+
+	written = out.write(buf, count);
+	if (written != count) {
+		warning("Can't write data: requested %d, wrote %d", count, written);
+		return 0;
+	}
+
+	written = out.write(sizes, count);
+	if (written != count) {
+		warning("Can't write data: requested %d, wrote %d", count, written);
+		return 0;
+	}
+
+	return count;
+}
+
+bool SaveLoad::loadDataEndian(Common::ReadStream &in,
+		int16 dataVar, uint32 size) {
+
+	bool retVal = false;
+
+	byte *varBuf = new byte[size];
+	byte *sizeBuf = new byte[size];
+
+	assert(varBuf && sizeBuf);
+
+	if (read(in, varBuf, sizeBuf, size) == size) {
+		if (fromEndian(varBuf, sizeBuf, size)) {
+			memcpy(_vm->_global->_inter_variables + dataVar, varBuf, size);
+			memcpy(_vm->_global->_inter_variablesSizes + dataVar, sizeBuf, size);
+			retVal = true;
+		}
+	}
+
+	delete[] varBuf;
+	delete[] sizeBuf;
+
+	return retVal;
+}
+
+bool SaveLoad::saveDataEndian(Common::WriteStream &out,
+		int16 dataVar, uint32 size) {
+
+	bool retVal = false;
+
+	byte *varBuf = new byte[size];
+	byte *sizeBuf = new byte[size];
+
+	assert(varBuf && sizeBuf);
+
+	memcpy(varBuf, _vm->_global->_inter_variables + dataVar, size);
+	memcpy(sizeBuf, _vm->_global->_inter_variablesSizes + dataVar, size);
+
+	if (toEndian(varBuf, sizeBuf, size))
+		if (write(out, varBuf, sizeBuf, size) == size)
+			retVal = true;
+
+	delete[] varBuf;
+	delete[] sizeBuf;
+
+	return retVal;
+}
+
+int32 SaveLoad::getSize(SaveType type) {
+	switch(type) {
+	case kSaveNone:
+		return -1;
+		break;
+
+	case kSaveGame:
+		return getSizeGame();
+		break;
+
+	case kSaveTempSprite:
+		return getSizeTempSprite();
+		break;
+
+	case kSaveNotes:
+		return getSizeNotes();
+		break;
+
+	case kSaveScreenshot:
+		return getSizeScreenshot();
+		break;
+
+	case kSaveIgnore:
+		return -1;
+		break;
+	}
+
+	return -1;
+}
+
+bool SaveLoad::load(SaveType type, int16 dataVar, int32 size, int32 offset) {
+	switch(type) {
+	case kSaveNone:
+		return false;
+		break;
+
+	case kSaveGame:
+		return loadGame(dataVar, size, offset);
+		break;
+
+	case kSaveTempSprite:
+		return loadTempSprite(dataVar, size, offset);
+		break;
+
+	case kSaveNotes:
+		return loadNotes(dataVar, size, offset);
+		break;
+
+	case kSaveScreenshot:
+		return loadScreenshot(dataVar, size, offset);
+		break;
+
+	case kSaveIgnore:
+		return true;
+		break;
+	}
+
+	return false;
+}
+
+bool SaveLoad::save(SaveType type, int16 dataVar, int32 size, int32 offset) {
+	switch(type) {
+	case kSaveNone:
+		return false;
+		break;
+
+	case kSaveGame:
+		return saveGame(dataVar, size, offset);
+		break;
+
+	case kSaveTempSprite:
+		return saveTempSprite(dataVar, size, offset);
+		break;
+
+	case kSaveNotes:
+		return saveNotes(dataVar, size, offset);
+		break;
+
+	case kSaveScreenshot:
+		return saveScreenshot(dataVar, size, offset);
+		break;
+
+	case kSaveIgnore:
+		return true;
+		break;
+	}
+
+	return false;
+}
+
+int32 SaveLoad::getSizeTempSprite() {
+	return _tempSpriteSize;
+}
+
+bool SaveLoad::loadTempSprite(int16 dataVar, int32 size, int32 offset) {
+	int index;
+	bool readPal;
+
+	if (size >= 0) {
+		warning("Invalid attempt at loading from the temporary sprite");
+		return false;
+	}
+
+	index = getSpriteIndex(size);
+	readPal = getSpritePalette(size);
+
+	if ((index < 0) || (index >= SPRITES_COUNT)) {
+		warning("Index out of range while loading from the temporary "
+				"sprite (%d)", index);
+		return false;
+	}
+
+	return loadTempSprite(index, readPal);
+}
+
+bool SaveLoad::saveTempSprite(int16 dataVar, int32 size, int32 offset) {
+	int index;
+	bool readPal;
+
+	if (size >= 0) {
+		warning("Invalid attempt at saving to the temporary sprite");
+		return false;
+	}
+
+	index = getSpriteIndex(size);
+	readPal = getSpritePalette(size);
+
+	if ((index < 0) || (index >= SPRITES_COUNT)) {
+		warning("Index out of range while saving to the temporary sprite (%d)",
+				index);
+		return false;
+	}
+
+	return saveTempSprite(index, readPal);
+}
+
+bool SaveLoad::loadTempSprite(uint32 index, bool palette) {
+	SurfaceDesc *sprite;
+
+	if (palette)
+		memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal,
+				(char *) _tempPal, 768);
+
+	sprite = _vm->_draw->_spritesArray[index];
+
+	if (!sprite) {
+		warning("Couldn't load from the temporary sprite: "
+				"No such sprite %d", index);
+		return false;
+	}
+
+	if ((sprite->getWidth() != _tempSprite->getWidth()) ||
+			(sprite->getHeight() != _tempSprite->getHeight())) {
+		warning("Resolution doesn't match while loading from the "
+				"temporary sprite (%d: %dx%d vs. %dx%d)", index,
+				sprite->getWidth(), sprite->getHeight(),
+				_tempSprite->getWidth(), _tempSprite->getHeight());
+		return false;
+	}
+
+	_vm->_video->drawSprite(_tempSprite, sprite, 0, 0,
+			sprite->getWidth() - 1, sprite->getHeight() - 1, 0, 0, 0);
+
+	if (index == 21) {
+		_vm->_draw->forceBlit();
+		_vm->_video->retrace();
+	}
+
+	return true;
+}
+
+bool SaveLoad::saveTempSprite(uint32 index, bool palette) {
+	SurfaceDesc *sprite = _vm->_draw->_spritesArray[index];
+
+	if (!sprite) {
+		warning("Couldn't save to the temporary sprite: "
+				"No such sprite %d", index);
+		return false;
+	}
+
+	delete _tempSprite;
+	_tempSprite = _vm->_video->initSurfDesc(_vm->_global->_videoMode,
+			sprite->getWidth(), sprite->getHeight(), 0);
+
+	_vm->_video->drawSprite(sprite, _tempSprite, 0, 0,
+			sprite->getWidth() - 1, sprite->getHeight() - 1, 0, 0, 0);
+
+	_tempSpriteSize = _vm->_draw->getSpriteRectSize(index);
+
+	if (palette) {
+		memcpy((char *) _tempPal,
+				(char *) _vm->_global->_pPaletteDesc->vgaPal, 768);
+		_tempSpriteSize += 768;
+	}
+
+	return true;
+}
+
+bool SaveLoad::loadSprite(Common::ReadStream &in, int32 size) {
+	SurfaceDesc *sprite;
+	byte *buf;
+	int nRead;
+	int index;
+	bool readPal;
+
+	if (size >= 0) {
+		warning("Invalid attempt at loading a sprite");
+		return false;
+	}
+
+	index = getSpriteIndex(size);
+	readPal = getSpritePalette(size);
+
+	if ((index < 0) || (index >= SPRITES_COUNT)) {
+		warning("Index out of range while loading a sprite (%d)",
+				index);
+		return false;
+	}
+
+	size = _vm->_draw->getSpriteRectSize(index);
+	sprite = _vm->_draw->_spritesArray[index];
+
+	if (!sprite) {
+		warning("Couldn't load sprite: No such sprite %d", index);
+		return false;
+	}
+
+	buf = new byte[MAX(768, size)];
+	assert(buf);
+
+	if (readPal) {
+		nRead = in.read(buf, 768);
+		if (nRead != 768) {
+			warning("Couldn't read a palette: requested 768, got %d", nRead);
+			delete[] buf;
+			return false;
+		}
+
+		memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal,
+				(char *) buf, 768);
+	}
+
+	nRead = in.read(buf, size);
+	if (nRead != size) {
+		warning("Couldn't read sprite data: requested %d, got %d", size, nRead);
+		delete[] buf;
+		return false;
+	}
+
+	memcpy((char *) sprite->getVidMem(), buf, size);
+
+	delete[] buf;
+	return true;
+}
+
+bool SaveLoad::saveSprite(Common::WriteStream &out, int32 size) {
+	SurfaceDesc *sprite;
+	int written;
+	int index;
+	bool readPal;
+
+	if (size >= 0) {
+		warning("Invalid attempt at saving a sprite");
+		return false;
+	}
+
+	index = getSpriteIndex(size);
+	readPal = getSpritePalette(size);
+
+	if ((index < 0) || (index >= SPRITES_COUNT)) {
+		warning("Index out of range while saving a sprite (%d)",
+				index);
+		return false;
+	}
+
+	size = _vm->_draw->getSpriteRectSize(index);
+	sprite = _vm->_draw->_spritesArray[index];
+
+	if (!sprite) {
+		warning("Couldn't save sprite: No such sprite %d", index);
+		return false;
+	}
+
+	if (readPal) {
+		written = out.write((char *) _vm->_global->_pPaletteDesc->vgaPal, 768);
+		if (written != 768) {
+			warning("Couldn't write a palette: requested 768, wrote %d", written);
+			return false;
+		}
+	}
+
+	written = out.write((char *) sprite->getVidMem(), size);
+	if (written != size) {
+		warning("Couldn't write a sprite: requested %d, wrote %d",
+				size, written);
+		return false;
+	}
+
+	return true;
+}
+
+bool SaveLoad::fromEndian(byte *buf, const byte *sizes, uint32 count) {
+	while (count-- > 0) {
+		if (*sizes == 3)
+			*((uint32 *) buf) = READ_LE_UINT32(buf);
+		else if (*sizes == 1)
+			*((uint16 *) buf) = READ_LE_UINT16(buf);
+		else if (*sizes != 0) {
+			warning("SaveLoad::fromEndian(): Corrupted variables sizes");
+			return false;
+		}
+
+		count -= *sizes;
+		buf += *sizes + 1;
+		sizes += *sizes + 1;
+	}
+
+	return true;
+}
+
+bool SaveLoad::toEndian(byte *buf, const byte *sizes, uint32 count) {
+	while (count-- > 0) {
+		if (*sizes == 3)
+			WRITE_LE_UINT32(buf, *((uint32 *) buf));
+		else if (*sizes == 1)
+			WRITE_LE_UINT16(buf, *((uint16 *) buf));
+		else if (*sizes != 0) {
+			warning("SaveLoad::toEndian(): Corrupted variables sizes");
+			return false;
+		}
+
+		count -= *sizes;
+		buf += *sizes + 1;
+		sizes += *sizes + 1;
+	}
+
+	return true;
+}
+
+} // End of namespace Gob


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

Added: scummvm/trunk/engines/gob/saveload.h
===================================================================
--- scummvm/trunk/engines/gob/saveload.h	                        (rev 0)
+++ scummvm/trunk/engines/gob/saveload.h	2007-04-08 00:08:26 UTC (rev 26414)
@@ -0,0 +1,162 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004 Ivan Dubrov
+ * Copyright (C) 2004-2006 The ScummVM project
+ *
+ * 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_SAVELOAD_H
+#define GOB_SAVELOAD_H
+
+#include "common/stream.h"
+
+#include "gob/video.h"
+
+namespace Gob {
+
+enum SaveType {
+	kSaveNone = -1,
+	kSaveGame,
+	kSaveTempSprite,
+	kSaveNotes,
+	kSaveScreenshot,
+	kSaveIgnore
+};
+
+class SaveLoad {
+public:
+	int32 getSize(SaveType type);
+	bool load(SaveType type, int16 dataVar, int32 size, int32 offset);
+	bool save(SaveType type, int16 dataVar, int32 size, int32 offset);
+
+	virtual SaveType getSaveType(const char *fileName) = 0;
+
+	SaveLoad(GobEngine *vm, const char *targetName);
+	virtual ~SaveLoad();
+
+protected:
+	int _curSlot;
+	char **_saveFiles;
+
+	int _stagesCount;
+	byte **_buffer;
+
+	// While using the notepad or changing the font, the original executable
+	// temporarily dumps Draw::_backSurface to a file. Since that's not really
+	// a nice thing to do, we work around it.
+	SurfaceDesc *_tempSprite;
+	Video::Color _tempPal[256];
+	int32 _tempSpriteSize;
+
+	GobEngine *_vm;
+
+	int getSpriteIndex(int32 size) {
+		if (size < -1000)
+			size += 1000;
+
+		return -size - 1;
+	}
+	bool getSpritePalette(int32 size) {
+		return size < -1000;
+	}
+
+	const char *setCurSlot(int slot);
+	bool fromEndian(byte *buf, const byte *sizes, uint32 count);
+	bool toEndian(byte *buf, const byte *sizes, uint32 count);
+	uint32 read(Common::ReadStream &in, byte *buf,
+			byte *sizes, uint32 count);
+	uint32 write(Common::WriteStream &out, byte *buf,
+			byte *sizes, uint32 count);
+
+	bool loadDataEndian(Common::ReadStream &in, int16 dataVar, uint32 size);
+	bool saveDataEndian(Common::WriteStream &out, int16 dataVar, uint32 size);
+
+	bool loadTempSprite(uint32 index, bool palette);
+	bool saveTempSprite(uint32 index, bool palette);
+	bool loadSprite(Common::ReadStream &in, int32 size);
+	bool saveSprite(Common::WriteStream &out, int32 size);
+
+	int32 getSizeTempSprite();
+	bool loadTempSprite(int16 dataVar, int32 size, int32 offset);
+	bool saveTempSprite(int16 dataVar, int32 size, int32 offset);
+
+	virtual uint32 getSaveGameSize() = 0;
+
+	virtual int32 getSizeGame() = 0;
+	virtual int32 getSizeNotes() = 0;
+	virtual int32 getSizeScreenshot() = 0;
+	virtual bool loadGame(int16 dataVar, int32 size, int32 offset) = 0;
+	virtual bool loadNotes(int16 dataVar, int32 size, int32 offset) = 0;
+	virtual bool loadScreenshot(int16 dataVar, int32 size, int32 offset) = 0;
+	virtual bool saveGame(int16 dataVar, int32 size, int32 offset) = 0;
+	virtual bool saveNotes(int16 dataVar, int32 size, int32 offset) = 0;
+	virtual bool saveScreenshot(int16 dataVar, int32 size, int32 offset) = 0;
+};
+
+class SaveLoad_v2 : public SaveLoad {
+public:
+	virtual SaveType getSaveType(const char *fileName);
+
+	SaveLoad_v2(GobEngine *vm, const char *targetName);
+	virtual ~SaveLoad_v2() {};
+
+protected:
+	virtual uint32 getSaveGameSize();
+
+	virtual int32 getSizeGame();
+	virtual int32 getSizeNotes();
+	virtual int32 getSizeScreenshot();
+	virtual bool loadGame(int16 dataVar, int32 size, int32 offset);
+	virtual bool loadNotes(int16 dataVar, int32 size, int32 offset);
+	virtual bool loadScreenshot(int16 dataVar, int32 size, int32 offset);
+	virtual bool saveGame(int16 dataVar, int32 size, int32 offset);
+	virtual bool saveNotes(int16 dataVar, int32 size, int32 offset);
+	virtual bool saveScreenshot(int16 dataVar, int32 size, int32 offset);
+};
+
+class SaveLoad_v3 : public SaveLoad_v2 {
+public:
+	virtual SaveType getSaveType(const char *fileName);
+
+	SaveLoad_v3(GobEngine *vm, const char *targetName);
+	virtual ~SaveLoad_v3() {};
+
+protected:
+	bool _useScreenshots;
+	bool _firstSizeGame;
+	int8 _saveSlot;
+
+	virtual uint32 getSaveGameSize();
+
+	virtual int32 getSizeGame();
+	virtual int32 getSizeNotes();
+	virtual int32 getSizeScreenshot();
+	virtual bool loadGame(int16 dataVar, int32 size, int32 offset);
+	virtual bool loadNotes(int16 dataVar, int32 size, int32 offset);
+	virtual bool loadScreenshot(int16 dataVar, int32 size, int32 offset);
+	virtual bool saveGame(int16 dataVar, int32 size, int32 offset);
+	virtual bool saveNotes(int16 dataVar, int32 size, int32 offset);
+	virtual bool saveScreenshot(int16 dataVar, int32 size, int32 offset);
+
+	bool saveGame(int32 screenshotSize);
+};
+
+} // End of namespace Gob
+
+#endif // GOB_SAVELOAD_H


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

Added: scummvm/trunk/engines/gob/saveload_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/saveload_v2.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/saveload_v2.cpp	2007-04-08 00:08:26 UTC (rev 26414)
@@ -0,0 +1,286 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004 Ivan Dubrov
+ * Copyright (C) 2004-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "common/endian.h"
+#include "common/file.h"
+
+#include "gob/gob.h"
+#include "gob/saveload.h"
+#include "gob/global.h"
+#include "gob/game.h"
+
+namespace Gob {
+
+SaveLoad_v2::SaveLoad_v2(GobEngine *vm, const char *targetName) :
+	SaveLoad(vm, targetName) {
+
+	_stagesCount = 1;
+
+	_buffer = new byte*[_stagesCount];
+
+	assert(_buffer);
+
+	_buffer[0] = 0;
+}
+
+SaveType SaveLoad_v2::getSaveType(const char *fileName) {
+	if (!scumm_stricmp(fileName, "cat.inf"))
+		return kSaveGame;
+	if (!scumm_stricmp(fileName, "cat.cat"))
+		return kSaveGame;
+	if (!scumm_stricmp(fileName, "save.inf"))
+		return kSaveTempSprite;
+	if (!scumm_stricmp(fileName, "bloc.inf"))
+		return kSaveNotes;
+
+	return kSaveNone;
+}
+
+uint32 SaveLoad_v2::getSaveGameSize() {
+	return 80 + (READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4) * 2;
+}
+
+int32 SaveLoad_v2::getSizeNotes() {
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
+	int32 size = -1;
+
+	in = saveMan->openForLoading(_saveFiles[(int) kSaveNotes]);
+	if (in) {
+		size = in->size();
+		delete in;
+	}
+
+	return size;
+}
+
+int32 SaveLoad_v2::getSizeGame() {
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
+
+	for (int i = 14; i >= 0; i--) {
+		in = saveMan->openForLoading(setCurSlot(i));
+		if (in) {
+			delete in;
+			return (i + 1) * READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) *
+				4 + 600;
+		}
+	}
+
+	return -1;
+}
+
+int32 SaveLoad_v2::getSizeScreenshot() {
+	return -1;
+}
+
+bool SaveLoad_v2::loadGame(int16 dataVar, int32 size, int32 offset) {
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
+	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+
+	if (size == 0) {
+		dataVar = 0;
+		size = varSize;
+	}
+
+	int slot = (offset - 600) / varSize;
+	int slotR = (offset - 600) % varSize;
+
+	if ((offset == 0) && (size == 600)) {
+
+		byte *varBuf = _vm->_global->_inter_variables + dataVar;
+		for (int i = 0; i < 15; i++, varBuf += 40) {
+			in = saveMan->openForLoading(setCurSlot(i));
+			if (in) {
+				in->read(varBuf, 40);
+				delete in;
+			} else
+				memset(varBuf, 0, 40);
+		}
+		memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 600);
+		return true;
+
+	} else if ((offset > 0) && (slot < 15) &&
+			(slotR == 0) && (size == varSize)) {
+
+		in = saveMan->openForLoading(setCurSlot(slot));
+		if (!in) {
+			warning("Can't open file for slot %d", slot);
+			return false;
+		}
+
+		uint32 sGameSize = getSaveGameSize();
+		uint32 fSize = in->size();
+		if (fSize != sGameSize) {
+			warning("Can't load from slot %d: Wrong size (%d, %d)", slot,
+					fSize, sGameSize);
+			delete in;
+			return false;
+		}
+
+		in->seek(80);
+		if (loadDataEndian(*in, dataVar, size)) {
+			delete in;
+			debugC(1, kDebugFileIO, "Loading from slot %d", slot);
+			return true;
+		}
+		delete in;
+
+	} else
+		warning("Invalid loading procedure (%d, %d, %d, %d)",
+				offset, size, slot, slotR);
+
+	return false;
+}
+
+bool SaveLoad_v2::loadNotes(int16 dataVar, int32 size, int32 offset) {
+	bool retVal;
+
+	if ((size <= 0) || (offset != 0)) {
+		warning("Invalid attempt at loading the notes (%d, %d)", size, offset);
+		return false;
+	}
+
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	char *sName = _saveFiles[(int) kSaveNotes];
+
+	Common::InSaveFile *in = saveMan->openForLoading(sName);
+	if (!in) {
+		warning("Can't open file \"%s\" for reading", sName);
+		return false;
+	}
+
+	retVal = loadDataEndian(*in, dataVar, size);
+	delete in;
+	return retVal;
+}
+
+bool SaveLoad_v2::loadScreenshot(int16 dataVar, int32 size, int32 offset) {
+	return false;
+}
+
+bool SaveLoad_v2::saveGame(int16 dataVar, int32 size, int32 offset) {
+	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+
+	if (size == 0) {
+		dataVar = 0;
+		size = varSize;
+	}
+
+	int slot = (offset - 600) / varSize;
+	int slotR = (offset - 600) % varSize;
+
+	if ((offset == 0) && (size == 600)) {
+
+		delete[] _buffer[0];
+		_buffer[0] = new byte[1200];
+		assert(_buffer[0]);
+
+		memcpy(_buffer[0], _vm->_global->_inter_variables + dataVar, 600);
+		memset(_buffer[0] + 600, 0, 600);
+
+		return true;
+
+	} else if ((offset > 0) && (slot < 15) &&
+			(slotR == 0) && (size == varSize)) {
+
+		if (!_buffer[0]) {
+			warning("Tried to save without writing the index first");
+			return false;
+		}
+
+		Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+		Common::OutSaveFile *out;
+		
+		out = saveMan->openForSaving(setCurSlot(slot));
+		if (!out) {
+			warning("Can't open file for slot %d for writing", slot);
+			delete[] _buffer[0];
+			_buffer[0] = 0;
+			return false;
+		}
+
+		bool retVal = false;
+
+		if (out->write(_buffer[0] + slot * 40, 40) == 40)
+			if (out->write(_buffer[0] + 600 + slot * 40, 40) == 40)
+				if (saveDataEndian(*out, dataVar, size)) {
+					out->finalize();
+					if (!out->ioFailed())
+						retVal = true;
+				}
+
+		if (!retVal)
+			warning("Can't save to slot %d", slot);
+		else
+			debugC(1, kDebugFileIO, "Saved to slot %d", slot);
+
+		delete[] _buffer[0];
+		_buffer[0] = 0;
+		delete out;
+
+		return retVal;
+
+	} else
+		warning("Invalid saving procedure (%d, %d, %d, %d)",
+				offset, size, slot, slotR);
+
+	return false;
+}
+
+bool SaveLoad_v2::saveNotes(int16 dataVar, int32 size, int32 offset) {
+	bool retVal;
+
+	if ((size <= 0) || (offset != 0)) {
+		warning("Invalid attempt at saving the notes (%d, %d)", size, offset);
+		return false;
+	}
+
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	char *sName = _saveFiles[(int) kSaveNotes];
+
+	Common::OutSaveFile *out = saveMan->openForSaving(sName);
+	if (!out) {
+		warning("Can't open file \"%s\" for writing", sName);
+		return false;
+	}
+
+	retVal = saveDataEndian(*out, dataVar, size);
+
+	out->finalize();
+	if (out->ioFailed()) {
+		warning("Can't save notes");
+		retVal = false;
+	}
+
+	delete out;
+	return retVal;
+}
+
+bool SaveLoad_v2::saveScreenshot(int16 dataVar, int32 size, int32 offset) {
+	return false;
+}
+
+} // End of namespace Gob


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

Added: scummvm/trunk/engines/gob/saveload_v3.cpp
===================================================================
--- scummvm/trunk/engines/gob/saveload_v3.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/saveload_v3.cpp	2007-04-08 00:08:26 UTC (rev 26414)
@@ -0,0 +1,428 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004 Ivan Dubrov
+ * Copyright (C) 2004-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "common/endian.h"
+#include "common/file.h"
+
+#include "gob/gob.h"
+#include "gob/saveload.h"
+#include "gob/global.h"
+#include "gob/game.h"
+
+namespace Gob {
+
+SaveLoad_v3::SaveLoad_v3(GobEngine *vm, const char *targetName) :
+	SaveLoad_v2(vm, targetName) {
+
+	_saveSlot = -1;
+	_stagesCount = 3;
+
+	_buffer = new byte*[_stagesCount];
+
+	assert(_buffer);
+
+	_buffer[0] = new byte[1000];
+	_buffer[1] = new byte[1200];
+	_buffer[2] = 0;
+
+	assert(_buffer[0] && _buffer[1]);
+
+	memset(_buffer[0], 0, 1000);
+	memset(_buffer[1], 0, 1200);
+
+	_useScreenshots = false;
+	_firstSizeGame = true;
+}
+
+SaveType SaveLoad_v3::getSaveType(const char *fileName) {
+	if (!scumm_stricmp(fileName, "cat.inf"))
+		return kSaveGame;
+	if (!scumm_stricmp(fileName, "ima.inf"))
+		return kSaveScreenshot;
+	if (!scumm_stricmp(fileName, "intro.$$$"))
+		return kSaveTempSprite;
+	if (!scumm_stricmp(fileName, "prot"))
+		return kSaveIgnore;
+	if (!scumm_stricmp(fileName, "config"))
+		return kSaveIgnore;
+
+	return kSaveNone;
+}
+
+uint32 SaveLoad_v3::getSaveGameSize() {
+	uint32 size;
+
+	size = 1040 + (READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4) * 2;
+	if (_useScreenshots)
+		size += 19968;
+
+	return size;
+}
+
+int32 SaveLoad_v3::getSizeNotes() {
+	return -1;
+}
+
+int32 SaveLoad_v3::getSizeGame() {
+	if (_firstSizeGame) {
+		_firstSizeGame = false;
+		return -1;
+	}
+
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
+	int32 size = -1;
+
+	int slot = _curSlot;
+	for (int i = 29; i >= 0; i--) {
+		in = saveMan->openForLoading(setCurSlot(i));
+		if (in) {
+			delete in;
+			size = (i + 1) * READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) *
+				4 + 1700;
+			break;
+		}
+	}
+	setCurSlot(slot);
+
+	return size;
+}
+
+int32 SaveLoad_v3::getSizeScreenshot() {
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
+	int32 size = -1;
+
+	_useScreenshots = true;
+	int slot = _curSlot;
+	for (int i = 29; i >= 0; i--) {
+		in = saveMan->openForLoading(setCurSlot(i));
+		if (in) {
+			delete in;
+			size = (i + 1) * 19968 + 80;
+			break;
+		}
+	}
+	setCurSlot(slot);
+
+	return size;
+}
+
+bool SaveLoad_v3::loadGame(int16 dataVar, int32 size, int32 offset) {
+	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
+
+	int slot = (offset - 1700) / varSize;
+	int slotR = (offset - 1700) % varSize;
+
+	if ((size > 0) && (offset < 500) && ((size + offset) <= 500)) {
+
+		memcpy(_vm->_global->_inter_variables + dataVar,
+				_buffer[0] + offset, size);
+		memcpy(_vm->_global->_inter_variablesSizes + dataVar,
+				_buffer[0] + offset + 500, size);
+		return true;
+
+	} else if ((size == 1200) && (offset == 500)) {
+
+		memset(_buffer[1], 0, 1200);
+
+		slot = _curSlot;
+		for (int i = 0; i < 30; i++) {
+			in = saveMan->openForLoading(setCurSlot(i));
+			if (in) {
+				in->seek(1000);
+				in->read(_buffer[1] + i * 40, 40);
+				delete in;
+			}
+		}
+		setCurSlot(slot);
+
+		memcpy(_vm->_global->_inter_variables + dataVar, _buffer[1], 1200);
+		memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 1200);
+		return true;
+
+	} else if ((offset > 0) && (slot < 30) &&
+			(slotR == 0) && (size == 0)) {
+
+		in = saveMan->openForLoading(setCurSlot(slot));
+		if (!in) {
+			warning("Can't open file for slot %d", slot);
+			return false;
+		}
+
+		uint32 sGameSize = getSaveGameSize();
+		uint32 fSize = in->size();
+		if (fSize != sGameSize) {
+			warning("Can't load from slot %d: Wrong size (%d, %d)", slot,
+					fSize, sGameSize);
+			delete in;
+			return false;
+		}
+
+		byte varBuf[500], sizeBuf[500];
+		if (read(*in, varBuf, sizeBuf, 500) == 500) {
+			if (fromEndian(varBuf, sizeBuf, 500)) {
+				memcpy(_buffer[0], varBuf, 500);
+				memcpy(_buffer[0] + 500, sizeBuf, 500);
+				in->seek(1040);
+				if (loadDataEndian(*in, 0, varSize)) {
+					delete in;
+					debugC(1, kDebugFileIO, "Loading from slot %d", slot);
+					return true;
+				}
+			}
+		}
+		delete in;
+
+	} else
+		warning("Invalid loading procedure (%d, %d, %d, %d)",
+				offset, size, slot, slotR);
+
+	return false;
+}
+
+bool SaveLoad_v3::loadNotes(int16 dataVar, int32 size, int32 offset) {
+	return false;
+}
+
+bool SaveLoad_v3::loadScreenshot(int16 dataVar, int32 size, int32 offset) {
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::InSaveFile *in;
+
+	int slot = (offset - 80) / 19968;
+	int slotR = (offset - 80) % 19968;
+
+	_useScreenshots = true;
+	if ((size == 40) && (offset == 40)) {
+		char buf[40];
+
+		memset(buf, 0, 40);
+
+		slot = _curSlot;
+		for (int i = 0; i < 30; i++) {
+			in = saveMan->openForLoading(setCurSlot(i));
+			if (in) {
+				delete in;
+				buf[i] = 1;
+			}
+		}
+		setCurSlot(slot);
+
+		memcpy(_vm->_global->_inter_variables + dataVar, buf, 40);
+		memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 40);
+		return true;
+
+	} else if ((offset > 0) && (slot < 30) &&
+			(slotR == 0) && (size < 0)) {
+
+		int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+
+		in = saveMan->openForLoading(setCurSlot(slot));
+		if (!in) {
+			warning("Can't open file for slot %d", slot);
+			return false;
+		}
+
+		uint32 sGameSize = getSaveGameSize();
+		uint32 fSize = in->size();
+		if (fSize != sGameSize) {
+			warning("Can't load screenshot from slot %d: Wrong size (%d, %d)",
+					slot, fSize, sGameSize);
+			delete in;
+			return false;
+		}
+
+		in->seek(1040 + varSize * 2);
+		return loadSprite(*in, size);
+
+	} else
+		warning("Invalid attempt at loading a screenshot (%d, %d, %d, %d)",
+				offset, size, slot, slotR);
+
+	return false;
+}
+
+bool SaveLoad_v3::saveGame(int16 dataVar, int32 size, int32 offset) {
+	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+
+	int slot = (offset - 1700) / varSize;
+	int slotR = (offset - 1700) % varSize;
+
+	if ((size > 0) && (offset < 500) && ((size + offset) <= 500)) {
+
+		memcpy(_buffer[0] + offset,
+				_vm->_global->_inter_variables + dataVar, size);
+		memcpy(_buffer[0] + offset + 500,
+				_vm->_global->_inter_variablesSizes + dataVar, size);
+
+		return true;
+
+	} else if ((size > 0) && (offset >= 500) && (offset < 1700) &&
+			((size + offset) <= 1700)) {
+
+		memcpy(_buffer[1] + offset - 500,
+				_vm->_global->_inter_variables + dataVar, size);
+
+		return true;
+
+	} else if ((offset > 0) && (slot < 30) &&
+			(slotR == 0) && (size == 0)) {
+
+		_saveSlot = -1;
+
+		delete _buffer[2];
+		_buffer[2] = new byte[varSize * 2];
+		assert(_buffer[2]);
+
+		memcpy(_buffer[2], _vm->_global->_inter_variables, varSize);
+		memcpy(_buffer[2] + varSize,
+				_vm->_global->_inter_variablesSizes, varSize);
+
+		if (!toEndian(_buffer[2], _buffer[2] + varSize, varSize)) {
+			delete _buffer[2];
+			_buffer[2] = 0;
+			return false;
+		}
+
+		_saveSlot = slot;
+
+		if (!_useScreenshots)
+			return saveGame(0);
+
+		return true;
+
+	} else
+		warning("Invalid saving procedure (%d, %d, %d, %d)",
+				offset, size, slot, slotR);
+
+	return false;
+}
+
+bool SaveLoad_v3::saveNotes(int16 dataVar, int32 size, int32 offset) {
+	return false;
+}
+
+bool SaveLoad_v3::saveScreenshot(int16 dataVar, int32 size, int32 offset) {
+	int slot = (offset - 80) / 19968;
+	int slotR = (offset - 80) % 19968;
+
+	_useScreenshots = true;
+
+	if ((offset < 80) && (size > 0)) {
+
+		return true;
+
+	} else if ((offset > 0) && (slot < 30) &&
+			(slotR == 0) && (size < 0)) {
+
+		return saveGame(size);
+
+	} else
+		warning("Invalid attempt at saving a screenshot (%d, %d, %d, %d)",
+				offset, size, slot, slotR);
+
+	return false;
+}
+
+bool SaveLoad_v3::saveGame(int32 screenshotSize) {
+	int8 slot = _saveSlot;
+
+	_saveSlot = -1;
+
+	if ((slot < 0) || (slot > 29)) {
+		warning("Can't save to slot %d: Out of range", slot);
+		delete[] _buffer[2];
+		_buffer[2] = 0;
+		return false;
+	}
+
+	if (!_buffer[2]) {
+		warning("Can't save to slot %d: No data", slot);
+		return false;
+	}
+
+	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+	Common::OutSaveFile *out;
+
+	out = saveMan->openForSaving(setCurSlot(slot));
+	if (!out) {
+		warning("Can't open file for slot %d for writing", slot);
+		delete[] _buffer[2];
+		_buffer[2] = 0;
+		return false;
+	}
+
+	int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+	byte varBuf[500], sizeBuf[500];
+
+	memcpy(varBuf, _buffer[0], 500);
+	memcpy(sizeBuf, _buffer[0] + 500, 500);
+
+	bool retVal = false;
+	if (toEndian(varBuf, sizeBuf, 500))
+		if (write(*out, varBuf, sizeBuf, 500) == 500)
+			if (out->write(_buffer[1] + slot * 40, 40) == 40)
+				if (out->write(_buffer[2], varSize * 2) == ((uint32) (varSize * 2))) {
+					out->flush();
+					if (!out->ioFailed())
+						retVal = true;
+				}
+
+	delete[] _buffer[2];
+	_buffer[2] = 0;
+
+	if (!retVal) {
+		warning("Can't save to slot %d", slot);
+		delete out;
+		return false;
+	}
+
+	if (_useScreenshots) {
+		if (screenshotSize >= 0) {
+			warning("Can't save to slot %d: Screenshot expected", slot);
+			delete out;
+			return false;
+		}
+
+		if (!saveSprite(*out, screenshotSize)) {
+			delete out;
+			return false;
+		}
+	}
+
+	out->finalize();
+	if (out->ioFailed()) {
+		warning("Can't save to slot %d", slot);
+		delete out;
+		return false;
+	}
+
+	debugC(1, kDebugFileIO, "Saved to slot %d", slot);
+	delete out;
+	return true;
+}
+
+} // End of namespace Gob


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


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