[Scummvm-cvs-logs] SF.net SVN: scummvm:[35111] scummvm/trunk/engines/sword1

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Tue Nov 18 17:31:55 CET 2008


Revision: 35111
          http://scummvm.svn.sourceforge.net/scummvm/?rev=35111&view=rev
Author:   thebluegr
Date:     2008-11-18 16:31:55 +0000 (Tue, 18 Nov 2008)

Log Message:
-----------
Applied a slightly modified version of my patch #2307224 - "BS1: Save/load overhaul"

Modified Paths:
--------------
    scummvm/trunk/engines/sword1/control.cpp
    scummvm/trunk/engines/sword1/control.h
    scummvm/trunk/engines/sword1/detection.cpp
    scummvm/trunk/engines/sword1/sword1.cpp
    scummvm/trunk/engines/sword1/sword1.h

Modified: scummvm/trunk/engines/sword1/control.cpp
===================================================================
--- scummvm/trunk/engines/sword1/control.cpp	2008-11-18 15:41:14 UTC (rev 35110)
+++ scummvm/trunk/engines/sword1/control.cpp	2008-11-18 16:31:55 UTC (rev 35111)
@@ -23,6 +23,7 @@
  *
  */
 
+#include <time.h>	// for extended infos
 
 #include "common/file.h"
 #include "common/util.h"
@@ -31,6 +32,7 @@
 #include "common/system.h"
 #include "common/config-manager.h"
 
+#include "graphics/thumbnail.h"
 #include "gui/message.h"
 
 #include "sword1/control.h"
@@ -509,6 +511,8 @@
 }
 
 void Control::setupSaveRestorePanel(bool saving) {
+	readSavegameDescriptions();
+
 	FrameHeader *savePanel = _resMan->fetchFrame(_resMan->openFetchRes(SR_WINDOW), 0);
 	uint16 panelX = (640 - _resMan->getUint16(savePanel->width)) / 2;
 	uint16 panelY = (480 - _resMan->getUint16(savePanel->height)) / 2;
@@ -690,22 +694,20 @@
 
 void Control::handleSaveKey(Common::KeyState kbd) {
 	if (_selectedSavegame < 255) {
-		uint8 len = strlen((char*)_saveNames[_selectedSavegame]);
+		uint8 len = _saveNames[_selectedSavegame].size();
 		if ((kbd.keycode == Common::KEYCODE_BACKSPACE) && len)  // backspace
-			_saveNames[_selectedSavegame][len - 1] = '\0';
+			_saveNames[_selectedSavegame].deleteLastChar();
 		else if (keyAccepted(kbd.ascii) && (len < 31)) {
-			_saveNames[_selectedSavegame][len] = kbd.ascii;
-			_saveNames[_selectedSavegame][len + 1] = '\0';
+			_saveNames[_selectedSavegame].insertChar(kbd.ascii, len);
 		}
 		showSavegameNames();
 	}
 }
 
 bool Control::saveToFile(void) {
-	if ((_selectedSavegame == 255) || !strlen((char*)_saveNames[_selectedSavegame]))
+	if ((_selectedSavegame == 255) || _saveNames[_selectedSavegame].size() == 0)
 		return false; // no saveslot selected or no name entered
 	saveGameToFile(_selectedSavegame);
-	writeSavegameDescriptions();
 	return true;
 }
 
@@ -717,33 +719,40 @@
 }
 
 void Control::readSavegameDescriptions(void) {
-	Common::InSaveFile *inf;
-	inf = _saveFileMan->openForLoading("SAVEGAME.INF");
-	_saveScrollPos = _saveFiles = 0;
+	char saveName[40];
+	Common::String pattern = ConfMan.get("gameid") + ".???";
+	Common::StringList filenames = _saveFileMan->listSavefiles(pattern.c_str());
+	sort(filenames.begin(), filenames.end());	// Sort (hopefully ensuring we are sorted numerically..)
+
+	int num = 0;
+	int slotNum = 0;
+	for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+		// Obtain the last 3 digits of the filename, since they correspond to the save slot
+		slotNum = atoi(file->c_str() + file->size() - 3);
+		
+		while (num < slotNum) {
+			_saveNames.push_back("");
+			num++;
+		}
+
+		if (slotNum >= 0 && slotNum <= 999) {
+			num++;
+			Common::InSaveFile *in = _saveFileMan->openForLoading(file->c_str());
+			if (in) {
+				in->readUint32LE();	// header
+				in->read(saveName, 40);
+				_saveNames.push_back(saveName);
+				delete in;
+			}
+		}
+	}
+
+	for (int i = _saveNames.size(); i < 1000; i++)
+		_saveNames.push_back("");
+
+	_saveScrollPos = 0;
 	_selectedSavegame = 255;
-	for (uint8 cnt = 0; cnt < 64; cnt++) {
-		memset(_saveNames[cnt], 0, sizeof(_saveNames[cnt]));
-	}
-	if (inf) {
-		uint8 curFileNum = 0;
-		uint8 ch;
-		do {
-			uint8 pos = 0;
-			do {
-				ch = inf->readByte();
-				if (pos < sizeof(_saveNames[curFileNum]) - 1) {
-					if ((ch == 10) || (ch == 255) || (inf->eos()))
-						_saveNames[curFileNum][pos++] = '\0';
-					else if (ch >= 32)
-						_saveNames[curFileNum][pos++] = ch;
-				}
-			} while ((ch != 10) && (ch != 255) && (!inf->eos()));
-			curFileNum++;
-		} while ((ch != 255) && (!inf->eos()));
-		_saveFiles = curFileNum;
-		_numSaves = _saveFiles;
-	}
-	delete inf;
+	_saveFiles = _numSaves = _saveNames.size();
 }
 
 int Control::displayMessage(const char *altButton, const char *message, ...) {
@@ -760,43 +769,59 @@
 	return result;
 }
 
-void Control::writeSavegameDescriptions(void) {
-	Common::OutSaveFile *outf;
-	outf = _saveFileMan->openForSaving("SAVEGAME.INF");
+bool Control::savegamesExist(void) {
+	Common::String pattern = ConfMan.get("gameid") + ".???";
+	Common::StringList saveNames = _saveFileMan->listSavefiles(pattern.c_str());
+	return saveNames.size() > 0;
+}
 
-	if (!outf) {
-		// Display an error message, and do nothing
-		displayMessage(0, "Can't create SAVEGAME.INF. (%s)", _saveFileMan->popErrorDesc().c_str());
+void Control::checkForOldSaveGames() {
+	Common::InSaveFile *inf = _saveFileMan->openForLoading("SAVEGAME.INF");
+
+	if (!inf) {
+		delete inf;
 		return;
 	}
 
-	// if the player accidently clicked the last slot and then deselected it again,
-	// we'd still have _saveFiles == 64, so get rid of the empty end.
-	while (strlen((char*)_saveNames[_saveFiles - 1]) == 0)
-		_saveFiles--;
-	for (uint8 cnt = 0; cnt < _saveFiles; cnt++) {
-		int len = strlen((char*)_saveNames[cnt]);
-		if (len > 0)
-			outf->write(_saveNames[cnt], len);
-		if (cnt < _saveFiles - 1)
-			outf->writeByte(10);
-		else
-			outf->writeByte(255);
+	GUI::MessageDialog dialog0(
+		"ScummVM found that you have old savefiles for Broken Sword 1 that should be converted.\n"
+		"The old save game format is no longer supported, so you will not be able to load your games if you don't convert them.\n\n"
+		"Press OK to convert them now, otherwise you will be asked again the next time you start the game.\n", "OK", "Cancel");
+
+	int choice = dialog0.runModal();
+	if (choice == GUI::kMessageCancel) {
+		// user pressed cancel
+		return;
 	}
-	outf->finalize();
-	if (outf->ioFailed())
-		displayMessage(0, "Can't write to SAVEGAME.INF. Device full? (%s)", _saveFileMan->popErrorDesc().c_str());
-	delete outf;
-}
 
-bool Control::savegamesExist(void) {
-	bool retVal = false;
-	Common::InSaveFile *inf;
-	inf = _saveFileMan->openForLoading("SAVEGAME.INF");
-	if (inf)
-		retVal = true;
-	delete inf;
-	return retVal;
+	// Convert every save slot we find in the index file to the new format
+	uint8 saveName[32];
+	uint8 slot = 0;
+	uint8 ch;
+
+	memset(saveName, 0, sizeof(saveName));
+
+	do {
+		uint8 pos = 0;
+		do {
+			ch = inf->readByte();
+			if (pos < sizeof(saveName) - 1) {
+				if ((ch == 10) || (ch == 255) || (inf->eos()))
+					saveName[pos++] = '\0';
+				else if (ch >= 32)
+					saveName[pos++] = ch;
+			}
+		} while ((ch != 10) && (ch != 255) && (!inf->eos()));
+
+		if (pos > 1)	// if the slot has a description
+			convertSaveGame(slot, (char*)saveName);
+		slot++;
+	} while ((ch != 255) && (!inf->eos()));
+
+	delete inf;	
+
+	// Delete index file
+	_saveFileMan->removeSavefile("SAVEGAME.INF");
 }
 
 void Control::showSavegameNames(void) {
@@ -805,7 +830,7 @@
 		uint8 textMode = TEXT_LEFT_ALIGN;
 		uint16 ycoord = _saveButtons[cnt].y + 2;
 		uint8 str[40];
-		sprintf((char*)str, "%d. %s", cnt + _saveScrollPos + 1, _saveNames[cnt + _saveScrollPos]);
+		sprintf((char*)str, "%d. %s", cnt + _saveScrollPos + 1, _saveNames[cnt + _saveScrollPos].c_str());
 		if (cnt + _saveScrollPos == _selectedSavegame) {
 			textMode |= TEXT_RED_FONT;
 			ycoord += 2;
@@ -821,10 +846,10 @@
 	_buttons[id - BUTTON_SAVE_SELECT1]->setSelected(1);
 	uint8 num = (id - BUTTON_SAVE_SELECT1) + _saveScrollPos;
 	if (saving && (_selectedSavegame != 255)) // the player may have entered something, clear it again
-		strcpy((char*)_saveNames[_selectedSavegame], (char*)_oldName);
+		_saveNames[_selectedSavegame] = _oldName;
 	if (num < _saveFiles) {
 		_selectedSavegame = num;
-		strcpy((char*)_oldName, (char*)_saveNames[num]); // save for later
+		_oldName = _saveNames[num]; // save for later
 	} else {
 		if (!saving)
 			_buttons[id - BUTTON_SAVE_SELECT1]->setSelected(0); // no save in slot, deselect it
@@ -832,7 +857,7 @@
 			if (_saveFiles <= num)
 				_saveFiles = num + 1;
 			_selectedSavegame = num;
-			_oldName[0] = '\0';
+			_oldName.clear();
 		}
 	}
 	if (_selectedSavegame < 255)
@@ -950,7 +975,7 @@
 void Control::saveGameToFile(uint8 slot) {
 	char fName[15];
 	uint16 cnt;
-	sprintf(fName, "SAVEGAME.%03d", slot);
+	sprintf(fName, "%s.%03d", ConfMan.get("gameid").c_str(), slot);
 	uint16 liveBuf[TOTAL_SECTIONS];
 	Common::OutSaveFile *outf;
 	outf = _saveFileMan->openForSaving(fName);
@@ -960,6 +985,31 @@
 		return;
 	}
 
+	outf->writeUint32LE(SAVEGAME_HEADER);
+	outf->write(_saveNames[slot].c_str(), 40);
+	outf->writeByte(SAVEGAME_VERSION);
+
+	// FIXME: at this point, we can't save a thumbnail of the game screen, as the save menu is shown
+#if 0
+	outf->writeByte(HAS_THUMBNAIL);
+
+	// Thumbnail
+	Graphics::saveThumbnail(*outf);
+#else
+	outf->writeByte(NO_THUMBNAIL);
+#endif
+
+	// Date / time
+	tm curTime;
+	_system->getTimeAndDate(curTime);
+
+	uint32 saveDate = (curTime.tm_mday & 0xFF) << 24 | ((curTime.tm_mon + 1) & 0xFF) << 16 | (curTime.tm_year + 1900) & 0xFFFF;
+	uint16 saveTime = (curTime.tm_hour & 0xFF) << 8 | (curTime.tm_min) & 0xFF;
+
+	outf->writeUint32BE(saveDate);
+	outf->writeUint16BE(saveTime);
+	// TODO: played time
+
 	_objMan->saveLiveList(liveBuf);
 	for (cnt = 0; cnt < TOTAL_SECTIONS; cnt++)
 		outf->writeUint16LE(liveBuf[cnt]);
@@ -987,7 +1037,7 @@
 bool Control::restoreGameFromFile(uint8 slot) {
 	char fName[15];
 	uint16 cnt;
-	sprintf(fName, "SAVEGAME.%03d", slot);
+	sprintf(fName, "%s.%03d", ConfMan.get("gameid").c_str(), slot);
 	Common::InSaveFile *inf;
 	inf = _saveFileMan->openForLoading(fName);
 	if (!inf) {
@@ -996,6 +1046,36 @@
 		return false;
 	}
 
+	uint saveHeader = inf->readUint32LE();
+	if (saveHeader != SAVEGAME_HEADER) {
+		// Display an error message, and do nothing
+		displayMessage(0, "Save game '%s' is corrupt", fName);
+		return false;		
+	}
+
+	inf->skip(40);		// skip description
+	uint8 saveVersion = inf->readByte();
+
+	if (saveVersion != SAVEGAME_VERSION) {
+		warning("Different save game version");
+		return false;
+	}
+	
+	bool hasThumbnail = inf->readByte();
+
+	if (hasThumbnail) {
+		// We don't need the thumbnail here, so just read it and discard it
+		Graphics::Surface *thumbnail = new Graphics::Surface();
+		assert(thumbnail);
+		Graphics::loadThumbnail(*inf, *thumbnail);
+		delete thumbnail;
+		thumbnail = 0;
+	}
+
+	inf->readUint32BE();	// save date
+	inf->readUint16BE();	// save time
+	// TODO: played time
+
 	_restoreBuf = (uint8*)malloc(
 		TOTAL_SECTIONS * 2 +
 		NUM_SCRIPT_VARS * 4 +
@@ -1026,6 +1106,90 @@
 	return true;
 }
 
+bool Control::convertSaveGame(uint8 slot, char* desc) {
+	char oldFileName[15];
+	char newFileName[40];
+	sprintf(oldFileName, "SAVEGAME.%03d", slot);
+	sprintf(newFileName, "%s.%03d", ConfMan.get("gameid").c_str(), slot);
+	uint8 *saveData;
+	int dataSize;
+
+	// Check if the new file already exists
+	Common::InSaveFile *testSave = _saveFileMan->openForLoading(newFileName);
+
+	if (testSave) {
+		delete testSave;
+
+		char msg[200];
+		sprintf(msg, "Target new save game already exists!\n"
+					 "Would you like to keep the old save game (%s) or the new one (%s)?\n",
+					 oldFileName, newFileName);
+		GUI::MessageDialog dialog0(msg, "Keep the old one", "Keep the new one");
+
+		int choice = dialog0.runModal();
+		if (choice == GUI::kMessageCancel) {
+			// User chose to keep the new game, so delete the old one
+			_saveFileMan->removeSavefile(oldFileName);
+			return true;
+		}
+	}
+
+	Common::InSaveFile *oldSave = _saveFileMan->openForLoading(oldFileName);
+	if (!oldSave) {
+		// Display a warning message and do nothing
+		warning("Can't open file '%s'", oldFileName);
+		return false;
+	}
+
+	// Read data from old type of save game
+	dataSize = oldSave->size();
+	saveData = new uint8[dataSize];
+	oldSave->read(saveData, dataSize);
+	delete oldSave;
+
+	// Now write the save data to a new type of save game
+	Common::OutSaveFile *newSave;
+	newSave = _saveFileMan->openForSaving(newFileName);
+	if (!newSave) {
+		// Display a warning message and do nothing
+		warning("Unable to create file '%s'. (%s)", newFileName, _saveFileMan->popErrorDesc().c_str());
+		free(saveData);
+		saveData = NULL;
+		return false;
+	}	
+
+	newSave->writeUint32LE(SAVEGAME_HEADER);
+	newSave->write(desc, 40);
+	newSave->writeByte(SAVEGAME_VERSION);
+	newSave->writeByte(NO_THUMBNAIL);
+
+	// Date / time
+	tm curTime;
+	_system->getTimeAndDate(curTime);
+
+	uint32 saveDate = (curTime.tm_mday & 0xFF) << 24 | ((curTime.tm_mon + 1) & 0xFF) << 16 | (curTime.tm_year + 1900) & 0xFFFF;
+	uint16 saveTime = (curTime.tm_hour & 0xFF) << 8 | (curTime.tm_min) & 0xFF;
+
+	newSave->writeUint32BE(saveDate);
+	newSave->writeUint16BE(saveTime);
+	// TODO: played time
+
+	newSave->write(saveData, dataSize);
+
+	newSave->finalize();
+	if (newSave->ioFailed())
+		warning("Couldn't write to file '%s'. Device full?", newFileName);
+	delete newSave;
+
+	// Delete old save
+	_saveFileMan->removeSavefile(oldFileName);
+
+	// Cleanup
+	free(saveData);
+	saveData = NULL;
+	return true;
+}
+
 void Control::doRestore(void) {
 	uint8 *bufPos = _restoreBuf;
 	_objMan->loadLiveList((uint16*)bufPos);

Modified: scummvm/trunk/engines/sword1/control.h
===================================================================
--- scummvm/trunk/engines/sword1/control.h	2008-11-18 15:41:14 UTC (rev 35110)
+++ scummvm/trunk/engines/sword1/control.h	2008-11-18 16:31:55 UTC (rev 35111)
@@ -43,6 +43,11 @@
 class Music;
 class Sound;
 
+#define SAVEGAME_HEADER MKID_BE('BS_1')
+#define SAVEGAME_VERSION 1
+#define HAS_THUMBNAIL 1
+#define NO_THUMBNAIL 0
+
 #define MAX_BUTTONS 16
 
 #define CONTROL_NOTHING_DONE 0
@@ -87,13 +92,19 @@
 	void doRestore(void);
 	void askForCd(void);
 	bool savegamesExist(void);
+	void readSavegameDescriptions(void);
+	void saveGameToFile(uint8 slot);
 	bool restoreGameFromFile(uint8 slot);
+	void checkForOldSaveGames();
+
+	void setSaveDescription(int slot, const char *desc) {
+		_saveNames[slot] = desc;
+	}
+
 private:
 	int displayMessage(const char *altButton, const char *message, ...);
 
-	void saveGameToFile(uint8 slot);
-	void readSavegameDescriptions(void);
-	void writeSavegameDescriptions(void);
+	bool convertSaveGame(uint8 slot, char* desc);
 	void showSavegameNames(void);
 	void deselectSaveslots(void);
 	uint8 *_restoreBuf;
@@ -101,8 +112,8 @@
 	uint8 _numSaves;
 	uint8 _saveScrollPos;
 	uint8 _selectedSavegame;
-	uint8 _saveNames[64][32];
-	uint8 _oldName[32];
+	Common::StringList _saveNames;
+	Common::String _oldName;
 	uint8 _cursorTick;
 	bool _cursorVisible;
 

Modified: scummvm/trunk/engines/sword1/detection.cpp
===================================================================
--- scummvm/trunk/engines/sword1/detection.cpp	2008-11-18 15:41:14 UTC (rev 35110)
+++ scummvm/trunk/engines/sword1/detection.cpp	2008-11-18 16:31:55 UTC (rev 35111)
@@ -24,12 +24,14 @@
  */
 
 #include "sword1/sword1.h"
+#include "sword1/control.h"
 
 #include "base/plugins.h"
 #include "common/config-manager.h"
 #include "common/file.h"
 #include "common/fs.h"
 #include "common/savefile.h"
+#include "graphics/thumbnail.h"
 
 #include "engines/metaengine.h"
 
@@ -81,6 +83,8 @@
 	virtual GameList detectGames(const Common::FSList &fslist) const;
 	virtual SaveStateList listSaves(const char *target) const;
 	virtual int getMaximumSaveSlot() const;
+	virtual void removeSaveState(const char *target, int slot) const;
+	SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
 
 	virtual Common::Error createInstance(OSystem *syst, Engine **engine) const;
 };
@@ -88,7 +92,11 @@
 bool SwordMetaEngine::hasFeature(MetaEngineFeature f) const {
 	return
 		(f == kSupportsListSaves) ||
-		(f == kSupportsLoadingDuringStartup);
+		(f == kSupportsLoadingDuringStartup) ||
+		(f == kSupportsDeleteSave) ||
+		(f == kSavesSupportMetaInfo) ||
+		(f == kSavesSupportThumbnail) ||
+		(f == kSavesSupportCreationDate);
 }
 
 bool Sword1::SwordEngine::hasFeature(EngineFeature f) const {
@@ -184,76 +192,130 @@
 
 SaveStateList SwordMetaEngine::listSaves(const char *target) const {
 	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+	Common::String pattern = target;
+	pattern += ".???";
 	SaveStateList saveList;
+	char saveName[40];
 
-	Common::String pattern = "SAVEGAME.???";
 	Common::StringList filenames = saveFileMan->listSavefiles(pattern.c_str());
-	sort(filenames.begin(), filenames.end());
-	Common::StringList::const_iterator file = filenames.begin();
+	sort(filenames.begin(), filenames.end());	// Sort (hopefully ensuring we are sorted numerically..)
 
-	Common::InSaveFile *in = saveFileMan->openForLoading("SAVEGAME.INF");
+	int slotNum = 0;
+	for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+		// Obtain the last 3 digits of the filename, since they correspond to the save slot
+		slotNum = atoi(file->c_str() + file->size() - 3);
+		
+		if (slotNum >= 0 && slotNum <= 999) {
+			Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
+			if (in) {
+				in->readUint32LE();	// header
+				in->read(saveName, 40);
+				saveList.push_back(SaveStateDescriptor(slotNum, saveName));
+				delete in;
+			}
+		}
+	}
 
+	return saveList;
+}
+
+int SwordMetaEngine::getMaximumSaveSlot() const { return 999; }
+
+void SwordMetaEngine::removeSaveState(const char *target, int slot) const {
+	char extension[6];
+	snprintf(extension, sizeof(extension), ".%03d", slot);
+
+	Common::String filename = target;
+	filename += extension;
+
+	g_system->getSavefileManager()->removeSavefile(filename.c_str());
+}
+
+SaveStateDescriptor SwordMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+	static char fileName[40];
+	sprintf(fileName, "%s.%03d", target, slot);
+	char name[40];
+
+	Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName);
+
 	if (in) {
-		Common::Array<uint32> offsets;
-		uint8 stop = 0;
-		int slotsInFile = 0;
+		in->skip(4);		// header
+		in->read(name, sizeof(name));
+		in->skip(1);		// version
 
-		// Find the offset for each savegame name in the file.
-		while (stop != 255 && !in->eos()) {
-			offsets.push_back(in->pos());
-			slotsInFile++;
-			stop = 0;
-			while (stop != 10 && stop != 255 && !in->eos())
-				stop = in->readByte();
+		SaveStateDescriptor desc(slot, name);
+
+		desc.setDeletableFlag(true);
+		desc.setWriteProtectedFlag(false);
+
+		bool hasThumbnail = in->readByte();
+		if (hasThumbnail) {
+			Graphics::Surface *thumbnail = new Graphics::Surface();
+			assert(thumbnail);
+			if (!Graphics::loadThumbnail(*in, *thumbnail)) {
+				delete thumbnail;
+				thumbnail = 0;
+			}
+
+			desc.setThumbnail(thumbnail);
 		}
 
-		// Match the savegames to the save slot names.
-		while (file != filenames.end()) {
-			char saveDesc[32];
+		uint32 saveDate = in->readUint32BE();
+		uint16 saveTime = in->readUint16BE();
 
-			if (file->compareToIgnoreCase("SAVEGAME.INF") == 0) {
-				file++;
-				continue;
-			}
+		int day = (saveDate >> 24) & 0xFF;
+		int month = (saveDate >> 16) & 0xFF;
+		int year = saveDate & 0xFFFF;
+
+		desc.setSaveDate(year, month, day);
 			
-			// Obtain the last 3 digits of the filename, since they correspond to the save slot
-			int slotNum = atoi(file->c_str() + file->size() - 3);
+		int hour = (saveTime >> 8) & 0xFF;
+		int minutes = saveTime & 0xFF;
 
-			if (slotNum >= 0 && slotNum < slotsInFile) {
-				in->seek(offsets[slotNum]);
+		desc.setSaveTime(hour, minutes);
 
-				uint pos = 0;
-				do {
-					stop = in->readByte();
-					if (pos < sizeof(saveDesc) - 1) {
-						if (stop == 10 || stop == 255 || in->eos())
-							saveDesc[pos++] = '\0';
-						else if (stop >= 32)
-							saveDesc[pos++] = stop;
-					}
-				} while (stop != 10 && stop != 255 && !in->eos());
-			}
+		// TODO: played time
 
-			if (saveDesc[0] == 0)
-				strcpy(saveDesc, "Unnamed savegame");
+		delete in;
 
-			// FIXME: The in-game dialog shows the first save slot as 1, not 0,
-			// but if we change the numbering here, the launcher won?t set
-			// "save_slot" correctly.
-			saveList.push_back(SaveStateDescriptor(slotNum, saveDesc));
-			file++;
-		}
+		return desc;
 	}
-
-	delete in;
-
-	return saveList;
+	
+	return SaveStateDescriptor();
 }
 
-int SwordMetaEngine::getMaximumSaveSlot() const { return 999; }
-
 #if PLUGIN_ENABLED_DYNAMIC(SWORD1)
 	REGISTER_PLUGIN_DYNAMIC(SWORD1, PLUGIN_TYPE_ENGINE, SwordMetaEngine);
 #else
 	REGISTER_PLUGIN_STATIC(SWORD1, PLUGIN_TYPE_ENGINE, SwordMetaEngine);
 #endif
+
+namespace Sword1 {
+
+// FIXME: Loading a game through the GMM crashes the game
+#if 0
+Common::Error SwordEngine::loadGameState(int slot) {
+	_systemVars.forceRestart = false;
+	_systemVars.controlPanelMode = CP_NORMAL;
+	_control->restoreGameFromFile(slot);
+	reinitialize();
+	_control->doRestore();
+	return Common::kNoError;	// TODO: return success/failure
+}
+
+Common::Error SwordEngine::saveGameState(int slot, const char *desc) {
+	_control->setSaveDescription(slot, desc);
+	_control->saveGameToFile(slot);
+	return Common::kNoError;	// TODO: return success/failure
+}
+
+bool SwordEngine::canLoadGameStateCurrently() { 
+	return mouseIsActive();
+}
+
+bool SwordEngine::canSaveGameStateCurrently() { 
+	return mouseIsActive();
+}
+#endif
+
+} // End of namespace Sword1

Modified: scummvm/trunk/engines/sword1/sword1.cpp
===================================================================
--- scummvm/trunk/engines/sword1/sword1.cpp	2008-11-18 15:41:14 UTC (rev 35110)
+++ scummvm/trunk/engines/sword1/sword1.cpp	2008-11-18 16:31:55 UTC (rev 35111)
@@ -484,7 +484,10 @@
 }
 
 Common::Error SwordEngine::go() {
+	_control->checkForOldSaveGames();
+
 	uint16 startPos = ConfMan.getInt("boot_param");
+	_control->readSavegameDescriptions();
 	if (startPos) {
 		_logic->startPositions(startPos);
 	} else {
@@ -660,4 +663,8 @@
 	} while (_system->getMillis() < start + amount);
 }
 
+bool SwordEngine::mouseIsActive() {
+	return Logic::_scriptVars[MOUSE_STATUS] & 1;
+}
+
 } // End of namespace Sword1

Modified: scummvm/trunk/engines/sword1/sword1.h
===================================================================
--- scummvm/trunk/engines/sword1/sword1.h	2008-11-18 15:41:14 UTC (rev 35110)
+++ scummvm/trunk/engines/sword1/sword1.h	2008-11-18 16:31:55 UTC (rev 35111)
@@ -79,12 +79,22 @@
 	void reinitialize(void);
 
 	uint32 _features;
+
+	bool mouseIsActive();
+
 protected:
 	// Engine APIs
 	virtual Common::Error init();
 	virtual Common::Error go();
 	virtual bool hasFeature(EngineFeature f) const;
 	virtual void syncSoundSettings();
+	// FIXME: Loading a game through the GMM crashes the game
+#if 0
+	Common::Error loadGameState(int slot);
+	Common::Error saveGameState(int slot, const char *desc);
+	bool canLoadGameStateCurrently();
+	bool canSaveGameStateCurrently();
+#endif
 
 private:
 	void delay(int32 amount);


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