[Scummvm-cvs-logs] SF.net SVN: scummvm:[35855] scummvm/trunk/engines/groovie

jvprat at users.sourceforge.net jvprat at users.sourceforge.net
Wed Jan 14 00:22:48 CET 2009


Revision: 35855
          http://scummvm.svn.sourceforge.net/scummvm/?rev=35855&view=rev
Author:   jvprat
Date:     2009-01-13 23:22:47 +0000 (Tue, 13 Jan 2009)

Log Message:
-----------
Reduced savegame code duplication and added savegame format versioning.

Modified Paths:
--------------
    scummvm/trunk/engines/groovie/detection.cpp
    scummvm/trunk/engines/groovie/module.mk
    scummvm/trunk/engines/groovie/script.cpp

Added Paths:
-----------
    scummvm/trunk/engines/groovie/saveload.cpp
    scummvm/trunk/engines/groovie/saveload.h

Modified: scummvm/trunk/engines/groovie/detection.cpp
===================================================================
--- scummvm/trunk/engines/groovie/detection.cpp	2009-01-13 23:00:14 UTC (rev 35854)
+++ scummvm/trunk/engines/groovie/detection.cpp	2009-01-13 23:22:47 UTC (rev 35855)
@@ -26,6 +26,7 @@
 #include "common/savefile.h"
 
 #include "groovie/groovie.h"
+#include "groovie/saveload.h"
 
 namespace Groovie {
 
@@ -200,6 +201,7 @@
 	SaveStateList listSaves(const char *target) const;
 	int getMaximumSaveSlot() const;
 	void removeSaveState(const char *target, int slot) const;
+	SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
 };
 
 bool GroovieMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *gd) const {
@@ -213,76 +215,38 @@
 	return
 		(f == kSupportsListSaves) ||
 		(f == kSupportsLoadingDuringStartup) ||
-		(f == kSupportsDeleteSave);
-		//(f == kSavesSupportCreationDate)
+		(f == kSupportsDeleteSave) ||
+		(f == kSavesSupportMetaInfo);
 }
 
 SaveStateList GroovieMetaEngine::listSaves(const char *target) const {
-	Common::SaveFileManager *sfm = g_system->getSavefileManager();
-	SaveStateList list;
-
-	// Get the list of savefiles
-	Common::String pattern = Common::String(target) + ".00?";
-	Common::StringList savefiles = sfm->listSavefiles(pattern.c_str());
-
-	// Sort the list of filenames
-	sort(savefiles.begin(), savefiles.end());
-
-	// Fill the information for the existing savegames
-	Common::StringList::iterator it = savefiles.begin();
-	while (it != savefiles.end()) {
-		int slot = it->lastChar() - '0';
-		if (slot >= 0 && slot <= 9) {
-			Common::InSaveFile *file = sfm->openForLoading(it->c_str());
-
-			// Read the savegame description
-			Common::String description;
-			unsigned char c = 1;
-			for (int i = 0; (c != 0) && (i < 15); i++) {
-				c = file->readByte();
-				switch (c) {
-				case 0:
-					break;
-				case 16: // @
-					c = ' ';
-					break;
-				case 244: // $
-					c = 0;
-					break;
-				default:
-					c += 0x30;
-				}
-				if (c != 0) {
-					description += c;
-				}
-			}
-			delete file;
-
-			list.push_back(SaveStateDescriptor(slot, description));
-		}
-		it++;
-	}
-
-	return list;
+	return SaveLoad::listValidSaves(target);
 }
 
 int GroovieMetaEngine::getMaximumSaveSlot() const {
-	return 9;
+	return SaveLoad::getMaximumSlot();
 }
 
 void GroovieMetaEngine::removeSaveState(const char *target, int slot) const {
-	if (slot < 0 || slot > 9) {
+	if (!SaveLoad::isSlotValid(slot)) {
 		// Invalid slot, do nothing
 		return;
 	}
 
-	char extension[6];
-	snprintf(extension, sizeof(extension), ".00%01d", slot);
+	Common::String filename = SaveLoad::getSlotSaveName(target, slot);
+	g_system->getSavefileManager()->removeSavefile(filename.c_str());
+}
 
-	Common::String filename = target;
-	filename += extension;
+SaveStateDescriptor GroovieMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+	SaveStateDescriptor desc;
 
-	g_system->getSavefileManager()->removeSavefile(filename.c_str());
+	Common::InSaveFile *savefile = SaveLoad::openForLoading(target, slot, &desc);
+	if (savefile) {
+		// Loaded correctly
+		delete savefile;
+	}
+
+	return desc;
 }
 
 } // End of namespace Groovie

Modified: scummvm/trunk/engines/groovie/module.mk
===================================================================
--- scummvm/trunk/engines/groovie/module.mk	2009-01-13 23:00:14 UTC (rev 35854)
+++ scummvm/trunk/engines/groovie/module.mk	2009-01-13 23:22:47 UTC (rev 35855)
@@ -13,6 +13,7 @@
 	player.o \
 	resource.o \
 	roq.o \
+	saveload.o \
 	script.o \
 	vdx.o
 

Added: scummvm/trunk/engines/groovie/saveload.cpp
===================================================================
--- scummvm/trunk/engines/groovie/saveload.cpp	                        (rev 0)
+++ scummvm/trunk/engines/groovie/saveload.cpp	2009-01-13 23:22:47 UTC (rev 35855)
@@ -0,0 +1,168 @@
+/* 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 "groovie/saveload.h"
+
+#include "common/system.h"
+
+#define SUPPORTED_SAVEFILE_VERSION 1
+// 0 - Just script variables, compatible with the original
+// 1 - Added one byte with version number at the beginning
+
+namespace Groovie {
+
+int SaveLoad::getMaximumSlot() {
+	return 9;
+}
+
+bool SaveLoad::isSlotValid(int slot) {
+	return slot >= 0 && slot <= getMaximumSlot();
+}
+
+Common::String SaveLoad::getSlotSaveName(const Common::String &target, int slot) {
+	return target + ".00" + ('0' + slot);
+}
+
+SaveStateList SaveLoad::listValidSaves(const Common::String &target) {
+	SaveStateList list;
+
+	// Get the list of savefiles
+	Common::String pattern = target + ".00?";
+	Common::StringList savefiles = g_system->getSavefileManager()->listSavefiles(pattern.c_str());
+
+	// Sort the list of filenames
+	sort(savefiles.begin(), savefiles.end());
+
+	// Fill the information for the existing savegames
+	Common::StringList::iterator it = savefiles.begin();
+	while (it != savefiles.end()) {
+		int slot = it->lastChar() - '0';
+		SaveStateDescriptor descriptor;
+		Common::InSaveFile *file = SaveLoad::openForLoading(target, slot, &descriptor);
+		if (file) {
+			// It's a valid savefile, save the descriptor
+			delete file;
+			list.push_back(descriptor);
+		}
+		it++;
+	}
+
+	return list;
+}
+
+Common::InSaveFile *SaveLoad::openForLoading(const Common::String &target, int slot, SaveStateDescriptor *descriptor) {
+	// Validate the slot number
+	if (!isSlotValid(slot)) {
+		return NULL;
+	}
+
+	// Open the savefile
+	Common::String savename = getSlotSaveName(target, slot);
+	Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(savename.c_str());
+	if (!savefile) {
+		return NULL;
+	}
+
+	// Read the savefile version
+	uint8 version;
+	if (savefile->size() == 1024) {
+		version = 0;
+	} else {
+		version = savefile->readByte();
+	}
+
+	// Verify we can read this version
+	if (version > SUPPORTED_SAVEFILE_VERSION) {
+		//TODO: show the error about unsupported savefile version
+	}
+
+	// Save the current position as the start for the engine data
+	int metaDataSize = savefile->pos();
+
+	// Fill the SaveStateDescriptor if it was provided
+	if (descriptor) {
+		// Initialize the SaveStateDescriptor
+		descriptor->setVal("save_slot", Common::String('0' + slot));
+		descriptor->setDeletableFlag(true);
+		descriptor->setWriteProtectedFlag(false);
+
+		// TODO: Add extra information
+		//setSaveDate(int year, int month, int day)
+		//setSaveTime(int hour, int min)
+		//setPlayTime(int hours, int minutes)
+
+		// Read the savegame description
+		Common::String description;
+		unsigned char c = 1;
+		for (int i = 0; (c != 0) && (i < 15); i++) {
+			c = savefile->readByte();
+			switch (c) {
+				case 0:
+					break;
+				case 16: // @
+					c = ' ';
+					break;
+				case 244: // $
+					c = 0;
+					break;
+				default:
+					c += 0x30;
+			}
+			if (c != 0) {
+				description += c;
+			}
+		}
+		descriptor->setVal("description", description);
+	}
+
+	// Return a substream, skipping the metadata
+	Common::SeekableSubReadStream *sub = new Common::SeekableSubReadStream(savefile, metaDataSize, savefile->size(), true);
+
+	// Move to the beginning of the substream
+	sub->seek(0, SEEK_SET);
+
+	return sub;
+}
+
+Common::OutSaveFile *SaveLoad::openForSaving(const Common::String &target, int slot) {
+	// Validate the slot number
+	if (!isSlotValid(slot)) {
+		return NULL;
+	}
+
+	// Open the savefile
+	Common::String savename = getSlotSaveName(target, slot);
+	Common::OutSaveFile *savefile = g_system->getSavefileManager()->openForSaving(savename.c_str());
+	if (!savefile) {
+		return NULL;
+	}
+
+	// Write the savefile version
+	savefile->writeByte(SUPPORTED_SAVEFILE_VERSION);
+
+	return savefile;
+}
+
+} // End of Groovie namespace


Property changes on: scummvm/trunk/engines/groovie/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/groovie/saveload.h
===================================================================
--- scummvm/trunk/engines/groovie/saveload.h	                        (rev 0)
+++ scummvm/trunk/engines/groovie/saveload.h	2009-01-13 23:22:47 UTC (rev 35855)
@@ -0,0 +1,51 @@
+/* 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 GROOVIE_SAVELOAD_H
+#define GROOVIE_SAVELOAD_H
+
+#include "common/savefile.h"
+#include "engines/game.h"
+
+namespace Groovie {
+
+class SaveLoad {
+public:
+	// Validating slot numbers
+	static int getMaximumSlot();
+	static bool isSlotValid(int slot);
+
+	// Getting information
+	static Common::String getSlotSaveName(const Common::String &target, int slot);
+	static SaveStateList listValidSaves(const Common::String &target);
+
+	// Opening savefiles
+	static Common::InSaveFile *openForLoading(const Common::String &target, int slot, SaveStateDescriptor *descriptor = NULL);
+	static Common::OutSaveFile *openForSaving(const Common::String &target, int slot);
+};
+
+} // End of Groovie namespace
+
+#endif // GROOVIE_SAVELOAD_H


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

Modified: scummvm/trunk/engines/groovie/script.cpp
===================================================================
--- scummvm/trunk/engines/groovie/script.cpp	2009-01-13 23:00:14 UTC (rev 35854)
+++ scummvm/trunk/engines/groovie/script.cpp	2009-01-13 23:22:47 UTC (rev 35855)
@@ -28,11 +28,11 @@
 #include "groovie/script.h"
 #include "groovie/groovie.h"
 #include "groovie/cell.h"
+#include "groovie/saveload.h"
 
 #include "common/config-manager.h"
 #include "common/endian.h"
 #include "common/events.h"
-#include "common/savefile.h"
 
 #define NUM_OPCODES 90
 
@@ -360,8 +360,7 @@
 }
 
 void Script::loadgame(uint slot) {
-	Common::String filename = ConfMan.getActiveDomainName() + ".00" + ('0' + slot);
-	Common::InSaveFile *file = _vm->_system->getSavefileManager()->openForLoading(filename.c_str());
+	Common::InSaveFile *file = SaveLoad::openForLoading(ConfMan.getActiveDomainName(), slot);
 
 	// Loading the variables. It is endian safe because they're byte variables
 	file->read(_variables, 0x400);
@@ -372,11 +371,13 @@
 void Script::savegame(uint slot) {
 	char save[15];
 	char newchar;
-	Common::String filename = ConfMan.getActiveDomainName() + ".00" + ('0' + slot);
-	Common::OutSaveFile *file = _vm->_system->getSavefileManager()->openForSaving(filename.c_str());
+	Common::OutSaveFile *file = SaveLoad::openForSaving(ConfMan.getActiveDomainName(), slot);
 
 	// Saving the variables. It is endian safe because they're byte variables
 	file->write(_variables, 0x400);
+	delete file;
+
+	// Cache the saved name
 	for (int i = 0; i < 15; i++) {
 		newchar = _variables[i] + 0x30;
 		if ((newchar < 0x30 || newchar > 0x39) && (newchar < 0x41 || newchar > 0x7A)) {
@@ -387,8 +388,6 @@
 		}
 	}
 	_saveNames[slot] = save;
-
-	delete file;
 }
 
 // OPCODES
@@ -1217,8 +1216,6 @@
 
 	Common::Rect rect(left, top, right, bottom);
 	if (hotspot(rect, address, cursor)) {
-		char savename[15];
-
 		if (_hotspotSlot == slot) {
 			return;
 		}
@@ -1227,8 +1224,7 @@
 		if (!_font) {
 			_font = new Font(_vm->_system);
 		}
-		strcpy(savename, _saveNames[slot].c_str());
-		_font->printstring(savename);
+		_font->printstring(_saveNames[slot].c_str());
 
 		// Save the currently highlighted slot
 		_hotspotSlot = slot;
@@ -1252,54 +1248,33 @@
 void Script::o_checkvalidsaves() {
 	debugScript(1, true, "CHECKVALIDSAVES");
 
-	// Reset the array of valid saves
+	// Reset the array of valid saves and the savegame names cache
 	for (int i = 0; i < 10; i++) {
 		setVariable(i, 0);
+		_saveNames[i] = "E M P T Y";
 	}
 
 	// Get the list of savefiles
-	Common::String pattern = ConfMan.getActiveDomainName() + ".00?";
-	Common::StringList savefiles = _vm->_system->getSavefileManager()->listSavefiles(pattern.c_str());
+	SaveStateList list = SaveLoad::listValidSaves(ConfMan.getActiveDomainName());
 
 	// Mark the existing savefiles as valid
 	uint count = 0;
-	Common::StringList::iterator it = savefiles.begin();
-	while (it != savefiles.end()) {
-		int8 n = it->lastChar() - '0';
-		if (n >= 0 && n <= 9) {
-			// TODO: Check the contents of the file?
-			debugScript(2, true, "  Found valid savegame: %s", it->c_str());
-			setVariable(n, 1);
+	SaveStateList::iterator it = list.begin();
+	while (it != list.end()) {
+		int8 slot = it->getVal("save_slot").lastChar() - '0';
+		if (SaveLoad::isSlotValid(slot)) {
+			debugScript(2, true, "  Found valid savegame: %s", it->getVal("description").c_str());
+
+			// Mark this slot as used
+			setVariable(slot, 1);
+
+			// Cache this slot's description
+			_saveNames[slot] = it->getVal("description");
 			count++;
 		}
 		it++;
 	}
 
-	for (int slots = 0; slots < 10; slots++) {
-		char savename[15];
-		Common::String filename = ConfMan.getActiveDomainName() + ".00" + ('0' + slots);
-		Common::StringList files = _vm->_system->getSavefileManager()->listSavefiles(filename.c_str());
-		if (!files.empty()) {
-			Common::InSaveFile *file = _vm->_system->getSavefileManager()->openForLoading(filename.c_str());
-			if (file) {
-				uint8 i;
-				char temp;
-
-				for (i = 0; i < 15; i++) {
-					file->read(&temp, 1);
-					savename[i] = temp + 0x30;
-				}
-
-				delete file;
-			} else {
-				strcpy(savename, "ERROR");
-			}
-		} else {
-			strcpy(savename, "E M P T Y");
-		}
-		_saveNames[slots] = savename;
-	}
-
 	// Save the number of valid saves
 	setVariable(0x104, count);
 	debugScript(1, true, "  Found %d valid savegames", count);


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