[Scummvm-cvs-logs] scummvm master -> 2dee92a908b84ae870bfdbfd00318549485b7984

dreammaster dreammaster at scummvm.org
Mon Aug 6 12:04:41 CEST 2012


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
2dee92a908 TINSEL: Fixed portability issue with earlier savegames


Commit: 2dee92a908b84ae870bfdbfd00318549485b7984
    https://github.com/scummvm/scummvm/commit/2dee92a908b84ae870bfdbfd00318549485b7984
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2012-08-06T03:03:56-07:00

Commit Message:
TINSEL: Fixed portability issue with earlier savegames

Changed paths:
    engines/tinsel/dialogs.cpp
    engines/tinsel/dialogs.h
    engines/tinsel/saveload.cpp



diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index dde3484..56ee2ea 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -1263,6 +1263,20 @@ static INV_OBJECT *GetInvObject(int id) {
 }
 
 /**
+ * Returns true if the given id represents a valid inventory object
+ */
+bool GetIsInvObject(int id) {
+	INV_OBJECT *pObject = g_invObjects;
+
+	for (int i = 0; i < g_numObjects; i++, pObject++) {
+		if (pObject->id == id)
+			return true;
+	}
+
+	return false;
+}
+
+/**
  * Convert item ID number to index.
  */
 static int GetObjectIndex(int id) {
diff --git a/engines/tinsel/dialogs.h b/engines/tinsel/dialogs.h
index 8c48eb8..ab53ba7 100644
--- a/engines/tinsel/dialogs.h
+++ b/engines/tinsel/dialogs.h
@@ -152,6 +152,8 @@ void InvSetLimit(int invno, int n);
 void InvSetSize(int invno, int MinWidth, int MinHeight,
 		int StartWidth, int StartHeight, int MaxWidth, int MaxHeight);
 
+bool GetIsInvObject(int id);
+
 int WhichInventoryOpen();
 
 bool IsTopWindow();
diff --git a/engines/tinsel/saveload.cpp b/engines/tinsel/saveload.cpp
index 0a552c8..518e27f 100644
--- a/engines/tinsel/saveload.cpp
+++ b/engines/tinsel/saveload.cpp
@@ -55,8 +55,7 @@ namespace Tinsel {
  * only saves/loads those which are valid for the version of the savegame
  * which is being loaded/saved currently.
  */
-#define CURRENT_VER 1
-// TODO: Not yet used
+#define CURRENT_VER 2
 
 /**
  * An auxillary macro, used to specify savegame versions. We use this instead
@@ -97,12 +96,13 @@ struct SaveGameHeader {
 	TimeDate dateTime;
 	bool scnFlag;
 	byte language;
+	uint16 numInterpreters;			// Savegame version 2 or later only
 };
 
 enum {
 	DW1_SAVEGAME_ID = 0x44575399,	// = 'DWSc' = "DiscWorld 1 ScummVM"
 	DW2_SAVEGAME_ID = 0x44573253,	// = 'DW2S' = "DiscWorld 2 ScummVM"
-	SAVEGAME_HEADER_SIZE = 4 + 4 + 4 + SG_DESC_LEN + 7 + 1 + 1
+	SAVEGAME_HEADER_SIZE = 4 + 4 + 4 + SG_DESC_LEN + 7 + 1 + 1 + 2
 };
 
 #define SAVEGAME_ID (TinselV2 ? (uint32)DW2_SAVEGAME_ID : (uint32)DW1_SAVEGAME_ID)
@@ -186,6 +186,15 @@ static bool syncSaveGameHeader(Common::Serializer &s, SaveGameHeader &hdr) {
 		}
 	}
 
+	// Handle the number of interpreter contexts that will be saved in the savegame
+	if (tmp >= 2) {
+		tmp -= 2;
+		hdr.numInterpreters = NUM_INTERPRET;
+		s.syncAsUint16LE(hdr.numInterpreters);
+	} else {
+		hdr.numInterpreters = (TinselV2 ? 70 : 64) - 20;
+	}
+
 	// Skip over any extra bytes
 	s.skip(tmp);
 	return true;
@@ -262,7 +271,7 @@ static void syncSoundReel(Common::Serializer &s, SOUNDREELS &sr) {
 	s.syncAsSint32LE(sr.actorCol);
 }
 
-static void syncSavedData(Common::Serializer &s, SAVED_DATA &sd) {
+static void syncSavedData(Common::Serializer &s, SAVED_DATA &sd, int numInterp) {
 	s.syncAsUint32LE(sd.SavedSceneHandle);
 	s.syncAsUint32LE(sd.SavedBgroundHandle);
 	for (int i = 0; i < MAX_MOVERS; ++i)
@@ -273,7 +282,7 @@ static void syncSavedData(Common::Serializer &s, SAVED_DATA &sd) {
 	s.syncAsSint32LE(sd.NumSavedActors);
 	s.syncAsSint32LE(sd.SavedLoffset);
 	s.syncAsSint32LE(sd.SavedToffset);
-	for (int i = 0; i < NUM_INTERPRET; ++i)
+	for (int i = 0; i < numInterp; ++i)
 		sd.SavedICInfo[i].syncWithSerializer(s);
 	for (int i = 0; i < MAX_POLY; ++i)
 		s.syncAsUint32LE(sd.SavedDeadPolys[i]);
@@ -422,7 +431,7 @@ char *ListEntry(int i, letype which) {
 		return NULL;
 }
 
-static void DoSync(Common::Serializer &s) {
+static bool DoSync(Common::Serializer &s, int numInterp) {
 	int	sg = 0;
 
 	if (TinselV2) {
@@ -434,7 +443,7 @@ static void DoSync(Common::Serializer &s) {
 	if (TinselV2 && s.isLoading())
 		HoldItem(INV_NOICON);
 
-	syncSavedData(s, *g_srsd);
+	syncSavedData(s, *g_srsd, numInterp);
 	syncGlobInfo(s);		// Glitter globals
 	syncInvInfo(s);			// Inventory data
 
@@ -443,6 +452,10 @@ static void DoSync(Common::Serializer &s) {
 		sg = WhichItemHeld();
 	s.syncAsSint32LE(sg);
 	if (s.isLoading()) {
+		if (sg != -1 && !GetIsInvObject(sg))
+			// Not a valid inventory object, so return false
+			return false;
+
 		if (TinselV2)
 			g_thingHeld = sg;
 		else
@@ -459,7 +472,7 @@ static void DoSync(Common::Serializer &s) {
 	if (*g_SaveSceneSsCount != 0) {
 		SAVED_DATA *sdPtr = g_SaveSceneSsData;
 		for (int i = 0; i < *g_SaveSceneSsCount; ++i, ++sdPtr)
-			syncSavedData(s, *sdPtr);
+			syncSavedData(s, *sdPtr, numInterp);
 
 		// Flag that there is a saved scene to return to. Note that in this context 'saved scene'
 		// is a stored scene to return to from another scene, such as from the Summoning Book close-up
@@ -469,6 +482,8 @@ static void DoSync(Common::Serializer &s) {
 
 	if (!TinselV2)
 		syncAllActorsAlive(s);
+
+	return true;
 }
 
 /**
@@ -487,8 +502,23 @@ static bool DoRestore() {
 		delete f;	// Invalid header, or savegame too new -> skip it
 		return false;
 	}
+	
+	// Load in the data. For older savegame versions, we potentially need to load the data twice, once
+	// for pre 1.5 savegames, and if that fails, a second time for 1.5 savegames
+	int numInterpreters = hdr.numInterpreters;
+	int32 currentPos = f->pos();
+	for (int tryNumber = 0; tryNumber < ((hdr.ver >= 2) ? 1 : 2); ++tryNumber) {
+		// If it's the second loop iteration, try with the 1.5 savegame number of interpreter contexts
+		if (tryNumber == 1) {
+			f->seek(currentPos);
+			numInterpreters = 80;
+		}
 
-	DoSync(s);
+		// Load the savegame data
+		if (DoSync(s, numInterpreters))
+			// Data load was successful (or likely), so break out of loop
+			break;
+	}
 
 	uint32 id = f->readSint32LE();
 	if (id != (uint32)0xFEEDFACE)
@@ -575,7 +605,7 @@ static void DoSave() {
 		return;
 	}
 
-	DoSync(s);
+	DoSync(s, hdr.numInterpreters);
 
 	// Write out the special Id for Discworld savegames
 	f->writeUint32LE(0xFEEDFACE);






More information about the Scummvm-git-logs mailing list