[Scummvm-cvs-logs] SF.net SVN: scummvm:[40014] scummvm/trunk/engines/scumm

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Sun Apr 19 03:01:54 CEST 2009


Revision: 40014
          http://scummvm.svn.sourceforge.net/scummvm/?rev=40014&view=rev
Author:   fingolfin
Date:     2009-04-19 01:01:54 +0000 (Sun, 19 Apr 2009)

Log Message:
-----------
SCUMM: Moved o5_saveLoadGame and o5_saveLoadVars to ScummEngine_v4 (the highest SCUMM version to implement these opcodes. Actually, our code was bugged in so far as we only ever invoked o5_saveLoadGame in V3 games, never in V4 games (but this properly never mattered ;)

Modified Paths:
--------------
    scummvm/trunk/engines/scumm/saveload.cpp
    scummvm/trunk/engines/scumm/script_v0.cpp
    scummvm/trunk/engines/scumm/script_v2.cpp
    scummvm/trunk/engines/scumm/script_v4.cpp
    scummvm/trunk/engines/scumm/script_v5.cpp
    scummvm/trunk/engines/scumm/scumm.cpp
    scummvm/trunk/engines/scumm/scumm_v3.h
    scummvm/trunk/engines/scumm/scumm_v4.h
    scummvm/trunk/engines/scumm/scumm_v5.h

Modified: scummvm/trunk/engines/scumm/saveload.cpp
===================================================================
--- scummvm/trunk/engines/scumm/saveload.cpp	2009-04-19 01:01:28 UTC (rev 40013)
+++ scummvm/trunk/engines/scumm/saveload.cpp	2009-04-19 01:01:54 UTC (rev 40014)
@@ -179,7 +179,7 @@
 }
 
 
-void ScummEngine_v3::prepareSavegame() {
+void ScummEngine_v4::prepareSavegame() {
 	Common::MemoryWriteStreamDynamic *memStream;
 	Common::WriteStream *writeStream;
 
@@ -205,7 +205,7 @@
 	delete writeStream;
 }
 
-bool ScummEngine_v3::savePreparedSavegame(int slot, char *desc) {
+bool ScummEngine_v4::savePreparedSavegame(int slot, char *desc) {
 	bool success;
 	Common::String filename;
 	Common::OutSaveFile *out;

Modified: scummvm/trunk/engines/scumm/script_v0.cpp
===================================================================
--- scummvm/trunk/engines/scumm/script_v0.cpp	2009-04-19 01:01:28 UTC (rev 40013)
+++ scummvm/trunk/engines/scumm/script_v0.cpp	2009-04-19 01:01:54 UTC (rev 40014)
@@ -78,7 +78,7 @@
 	/* 20 */
 	OPCODE(0x20, o5_stopMusic);
 	OPCODE(0x21, o2_putActor);
-	OPCODE(0x22, o5_saveLoadGame);
+	OPCODE(0x22, o4_saveLoadGame);
 	OPCODE(0x23, o_stopCurrentScript);
 	/* 24 */
 	OPCODE(0x24, o_unknown2);
@@ -238,7 +238,7 @@
 	/* A0 */
 	OPCODE(0xa0, o5_stopObjectCode);
 	OPCODE(0xa1, o2_putActor);
-	OPCODE(0xa2, o5_saveLoadGame);
+	OPCODE(0xa2, o4_saveLoadGame);
 	OPCODE(0xa3, o_stopCurrentScript);
 	/* A4 */
 	OPCODE(0xa4, o_unknown2);

Modified: scummvm/trunk/engines/scumm/script_v2.cpp
===================================================================
--- scummvm/trunk/engines/scumm/script_v2.cpp	2009-04-19 01:01:28 UTC (rev 40013)
+++ scummvm/trunk/engines/scumm/script_v2.cpp	2009-04-19 01:01:54 UTC (rev 40014)
@@ -80,7 +80,7 @@
 	/* 20 */
 	OPCODE(0x20, o5_stopMusic);
 	OPCODE(0x21, o2_putActor);
-	OPCODE(0x22, o5_saveLoadGame);
+	OPCODE(0x22, o4_saveLoadGame);
 	OPCODE(0x23, o2_getActorY);
 	/* 24 */
 	OPCODE(0x24, o2_loadRoomWithEgo);
@@ -240,7 +240,7 @@
 	/* A0 */
 	OPCODE(0xa0, o5_stopObjectCode);
 	OPCODE(0xa1, o2_putActor);
-	OPCODE(0xa2, o5_saveLoadGame);
+	OPCODE(0xa2, o4_saveLoadGame);
 	OPCODE(0xa3, o2_getActorY);
 	/* A4 */
 	OPCODE(0xa4, o2_loadRoomWithEgo);

Modified: scummvm/trunk/engines/scumm/script_v4.cpp
===================================================================
--- scummvm/trunk/engines/scumm/script_v4.cpp	2009-04-19 01:01:28 UTC (rev 40013)
+++ scummvm/trunk/engines/scumm/script_v4.cpp	2009-04-19 01:01:54 UTC (rev 40014)
@@ -47,13 +47,19 @@
 	OPCODE(0xdc, o4_oldRoomEffect);
 
 	OPCODE(0x0f, o4_ifState);
+	OPCODE(0x4f, o4_ifState);
+	OPCODE(0x8f, o4_ifState);
+	OPCODE(0xcf, o4_ifState);
+
 	OPCODE(0x2f, o4_ifNotState);
-	OPCODE(0x4f, o4_ifState);
 	OPCODE(0x6f, o4_ifNotState);
-	OPCODE(0x8f, o4_ifState);
 	OPCODE(0xaf, o4_ifNotState);
-	OPCODE(0xcf, o4_ifState);
 	OPCODE(0xef, o4_ifNotState);
+
+	OPCODE(0xa7, o4_saveLoadVars);
+
+	OPCODE(0x22, o4_saveLoadGame);
+	OPCODE(0xa2, o4_saveLoadGame);
 }
 
 void ScummEngine_v4::o4_ifState() {
@@ -171,4 +177,311 @@
 	}
 }
 
+void ScummEngine_v4::o4_saveLoadVars() {
+	if (fetchScriptByte() == 1)
+		saveVars();
+	else
+		loadVars();
+}
+
+enum StringIds {
+	// The string IDs used by Indy3 to store the episode resp. series IQ points.
+	// Note that we save the episode IQ points but load the series IQ points,
+	// which matches the original Indy3 save/load code. See also the notes
+	// on Feature Request #1666521.
+	STRINGID_IQ_EPISODE = 7,
+	STRINGID_IQ_SERIES = 9,
+	// The string IDs of the first savegame name, used as an offset to determine
+	// the IDs of all savenames.
+	// Loom is the only game whose savenames start with a different ID.
+	STRINGID_SAVENAME1 = 10,
+	STRINGID_SAVENAME1_LOOM = 9
+};
+
+void ScummEngine_v4::saveVars() {
+	int a, b;
+
+	while ((_opcode = fetchScriptByte()) != 0) {
+		switch (_opcode & 0x1F) {
+		case 0x01: // write a range of variables
+			getResultPos();
+			a = _resultVarNumber;
+			getResultPos();
+			b = _resultVarNumber;
+			debug(0, "stub saveVars: vars %d -> %d", a, b);
+			break;
+		case 0x02: // write a range of string variables
+			a = getVarOrDirectByte(PARAM_1);
+			b = getVarOrDirectByte(PARAM_2);
+
+			if (a == STRINGID_IQ_EPISODE && b == STRINGID_IQ_EPISODE) {
+				if (_game.id == GID_INDY3) {
+					saveIQPoints();
+				}
+				break;
+			}
+			// FIXME: changing savegame-names not supported
+			break;
+		case 0x03: // open file
+			a = resStrLen(_scriptPointer);
+			strncpy(_saveLoadVarsFilename, (const char *)_scriptPointer, a);
+			_saveLoadVarsFilename[a] = '\0';
+			_scriptPointer += a + 1;
+			break;
+		case 0x04:
+			return;
+		case 0x1F: // close file
+			_saveLoadVarsFilename[0] = '\0';
+			return;
+		}
+	}
+}
+
+void ScummEngine_v4::loadVars() {
+	int a, b;
+
+	while ((_opcode = fetchScriptByte()) != 0) {
+		switch (_opcode & 0x1F) {
+		case 0x01: // read a range of variables
+			getResultPos();
+			a = _resultVarNumber;
+			getResultPos();
+			b = _resultVarNumber;
+			debug(0, "stub loadVars: vars %d -> %d", a, b);
+			break;
+		case 0x02: // read a range of string variables
+			a = getVarOrDirectByte(PARAM_1);
+			b = getVarOrDirectByte(PARAM_2);
+
+			int slot;
+			int slotSize;
+			byte* slotContent;
+			int savegameId;
+			bool avail_saves[100];
+
+			if (a == STRINGID_IQ_SERIES && b == STRINGID_IQ_SERIES) {
+				// Zak256 loads the IQ script-slot but does not use it -> ignore it
+				if (_game.id == GID_INDY3) {
+					byte *ptr = getResourceAddress(rtString, STRINGID_IQ_SERIES);
+					if (ptr) {
+						int size = getResourceSize(rtString, STRINGID_IQ_SERIES);
+						loadIQPoints(ptr, size);
+					}
+				}
+				break;
+			}
+
+			listSavegames(avail_saves, ARRAYSIZE(avail_saves));
+			for (slot = a; slot <= b; ++slot) {
+				slotSize = getResourceSize(rtString, slot);
+				slotContent = getResourceAddress(rtString, slot);
+
+				// load savegame names
+				savegameId = slot - a + 1;
+				Common::String name;
+				if (avail_saves[savegameId] && getSavegameName(savegameId, name)) {
+					int pos;
+					const char *ptr = name.c_str();
+					// slotContent ends with {'\0','@'} -> max. length = slotSize-2
+					for (pos = 0; pos < slotSize - 2; ++pos) {
+						if (!ptr[pos])
+							break;
+						// replace special characters
+						if (ptr[pos] >= 32 && ptr[pos] <= 122 && ptr[pos] != 64)
+							slotContent[pos] = ptr[pos];
+						else
+							slotContent[pos] = '_';
+					}
+					slotContent[pos] = '\0';
+				} else {
+					slotContent[0] = '\0';
+				}
+			}
+			break;
+		case 0x03: // open file
+			a = resStrLen(_scriptPointer);
+			strncpy(_saveLoadVarsFilename, (const char *)_scriptPointer, a);
+			_saveLoadVarsFilename[a] = '\0';
+			_scriptPointer += a + 1;
+			break;
+		case 0x04:
+			return;
+		case 0x1F: // close file
+			_saveLoadVarsFilename[0] = '\0';
+			return;
+		}
+	}
+}
+
+/**
+ * IQ Point calculation for Indy3.
+ * The scripts that perform this task are
+ * - script-9 (save/load dialog initialization, loads room 14),
+ * - room-14-204 (load series IQ string),
+ * - room-14-205 (save series IQ string),
+ * - room-14-206 (calculate series IQ string).
+ * Unfortunately script-9 contains lots of GUI stuff so calling this script
+ * directly is not possible. The other scripts depend on script-9.
+ */
+void ScummEngine_v4::updateIQPoints() {
+	int seriesIQ;
+	// IQString[0..72] corresponds to each puzzle's IQ.
+	// IQString[73] indicates that the IQ-file was loaded successfully and is always 0 when
+	// the IQ is calculated, hence it will be ignored here.
+	const int NUM_PUZZLES = 73;
+	byte seriesIQString[NUM_PUZZLES];
+	byte *episodeIQString;
+	int episodeIQStringSize;
+
+	// load string with IQ points given per puzzle in any savegame
+	// IMPORTANT: the resource string STRINGID_IQ_SERIES is only valid while
+	// the original save/load dialog is executed, so do not use it here.
+	memset(seriesIQString, 0, sizeof(seriesIQString));
+	loadIQPoints(seriesIQString, sizeof(seriesIQString));
+
+	// string with IQ points given per puzzle in current savegame
+	episodeIQString = getResourceAddress(rtString, STRINGID_IQ_EPISODE);
+	if (!episodeIQString)
+		return;
+	episodeIQStringSize = getResourceSize(rtString, STRINGID_IQ_EPISODE);
+	if (episodeIQStringSize < NUM_PUZZLES)
+		return;
+
+	// merge episode and series IQ strings and calculate series IQ
+	seriesIQ = 0;
+	// iterate over puzzles
+	for (int i = 0; i < NUM_PUZZLES ; ++i) {
+		byte puzzleIQ = seriesIQString[i];
+		// if puzzle is solved copy points to episode string
+		if (puzzleIQ > 0)
+			episodeIQString[i] = puzzleIQ;
+		// add puzzle's IQ-points to series IQ
+		seriesIQ += episodeIQString[i];
+	}
+	_scummVars[245] = seriesIQ;
+
+	// save series IQ string
+	saveIQPoints();
+}
+
+void ScummEngine_v4::saveIQPoints() {
+	// save Indy3 IQ-points
+	Common::OutSaveFile *file;
+	Common::String filename = _targetName + ".iq";
+
+	file = _saveFileMan->openForSaving(filename.c_str());
+	if (file != NULL) {
+		byte *ptr = getResourceAddress(rtString, STRINGID_IQ_EPISODE);
+		if (ptr) {
+			int size = getResourceSize(rtString, STRINGID_IQ_EPISODE);
+			file->write(ptr, size);
+		}
+		delete file;
+	}
+}
+
+void ScummEngine_v4::loadIQPoints(byte *ptr, int size) {
+	// load Indy3 IQ-points
+	Common::InSaveFile *file;
+	Common::String filename = _targetName + ".iq";
+
+	file = _saveFileMan->openForLoading(filename.c_str());
+	if (file != NULL) {
+		byte *tmp = (byte*)malloc(size);
+		int nread = file->read(tmp, size);
+		if (nread == size) {
+			memcpy(ptr, tmp, size);
+		}
+		free(tmp);
+		delete file;
+	}
+}
+
+void ScummEngine_v4::o4_saveLoadGame() {
+	getResultPos();
+	byte a = getVarOrDirectByte(PARAM_1);
+	byte slot = a & 0x1F;
+	byte result = 0;
+
+	// Slot numbers in older games start with 0, in newer games with 1
+	if (_game.version <= 2)
+		slot++;
+
+	if ((_game.id == GID_MANIAC) && (_game.version <= 1)) {
+		// Convert older load/save screen
+		// 1 Load
+		// 2 Save
+		slot = 1;
+		if (a == 1)
+			_opcode = 0x40;
+		else if ((a == 2) || (_game.platform == Common::kPlatformNES))
+			_opcode = 0x80;
+	} else {
+		_opcode = a & 0xE0;
+	}
+
+	switch (_opcode) {
+	case 0x00: // num slots available
+		result = 100;
+		break;
+	case 0x20: // drive
+		if (_game.version <= 3) {
+			// 0 = ???
+			// [1,2] = disk drive [A:,B:]
+			// 3 = hard drive
+			result = 3;
+		} else {
+			// set current drive
+			result = 1;
+		}
+		break;
+	case 0x40: // load
+		if (loadState(slot, false))
+			result = 3; // sucess
+		else
+			result = 5; // failed to load
+		break;
+	case 0x80: // save
+		if (_game.version <= 3) {
+			char name[32];
+			if (_game.version <= 2) {
+				// use generic name
+				sprintf(name, "Game %c", 'A'+slot-1);
+			} else {
+				// use name entered by the user
+				char* ptr;
+				int firstSlot = (_game.id == GID_LOOM) ? STRINGID_SAVENAME1_LOOM : STRINGID_SAVENAME1;
+				ptr = (char*)getStringAddress(slot + firstSlot - 1);
+				strncpy(name, ptr, sizeof(name));
+			}
+
+			if (savePreparedSavegame(slot, name))
+				result = 0;
+			else
+				result = 2;
+		} else {
+			result = 2; // failed to save
+		}
+		break;
+	case 0xC0: // test if save exists
+		{
+		Common::InSaveFile *file;
+		bool avail_saves[100];
+
+		listSavegames(avail_saves, ARRAYSIZE(avail_saves));
+		Common::String filename = makeSavegameName(slot, false);
+		if (avail_saves[slot] && (file = _saveFileMan->openForLoading(filename.c_str()))) {
+			result = 6; // save file exists
+			delete file;
+		} else
+			result = 7; // save file does not exist
+		}
+		break;
+	default:
+		error("o4_saveLoadGame: unknown subopcode %d", _opcode);
+	}
+
+	setResult(result);
+}
+
 } // End of namespace Scumm

Modified: scummvm/trunk/engines/scumm/script_v5.cpp
===================================================================
--- scummvm/trunk/engines/scumm/script_v5.cpp	2009-04-19 01:01:28 UTC (rev 40013)
+++ scummvm/trunk/engines/scumm/script_v5.cpp	2009-04-19 01:01:54 UTC (rev 40014)
@@ -248,7 +248,7 @@
 	OPCODE(0xa4, o5_loadRoomWithEgo);
 	OPCODE(0xa5, o5_pickupObject);
 	OPCODE(0xa6, o5_setVarRange);
-	OPCODE(0xa7, o5_saveLoadVars);
+	OPCODE(0xa7, o5_dummy);
 	/* A8 */
 	OPCODE(0xa8, o5_notEqualZero);
 	OPCODE(0xa9, o5_setOwnerOf);
@@ -831,6 +831,13 @@
 	putState(obj, state);
 }
 
+void ScummEngine_v5::o5_dummy() {
+	// The KIXX XL release of Monkey Island 2 (Amiga disk) used opcode 0xa7
+	// as dummy, in order to remove copy protection and keep level selection.
+	if (_opcode != 0xa7 || _game.id == GID_MONKEY2)
+		warning("o5_dummy invoked (opcode %d)", _opcode);
+}
+
 void ScummEngine_v5::o5_getStringWidth() {
 	int string, width = 0;
 	byte *ptr;
@@ -845,231 +852,6 @@
 	setResult(width);
 }
 
-enum StringIds {
-	// The string IDs used by Indy3 to store the episode resp. series IQ points.
-	// Note that we save the episode IQ points but load the series IQ points,
-	// which matches the original Indy3 save/load code. See also the notes
-	// on Feature Request #1666521.
-	STRINGID_IQ_EPISODE = 7,
-	STRINGID_IQ_SERIES = 9,
-	// The string IDs of the first savegame name, used as an offset to determine
-	// the IDs of all savenames.
-	// Loom is the only game whose savenames start with a different ID.
-	STRINGID_SAVENAME1 = 10,
-	STRINGID_SAVENAME1_LOOM = 9
-};
-
-void ScummEngine_v5::o5_saveLoadVars() {
-	// The KIXX XL release of Monkey Island 2 (Amiga disk) used this opcode
-	// as dummy, in order to remove copy protection and keep level selection.
-	if (_game.version == 5)
-		return;
-
-	if (fetchScriptByte() == 1)
-		saveVars();
-	else
-		loadVars();
-}
-
-void ScummEngine_v5::saveVars() {
-	int a, b;
-
-	while ((_opcode = fetchScriptByte()) != 0) {
-		switch (_opcode & 0x1F) {
-		case 0x01: // write a range of variables
-			getResultPos();
-			a = _resultVarNumber;
-			getResultPos();
-			b = _resultVarNumber;
-			debug(0, "stub saveVars: vars %d -> %d", a, b);
-			break;
-		case 0x02: // write a range of string variables
-			a = getVarOrDirectByte(PARAM_1);
-			b = getVarOrDirectByte(PARAM_2);
-
-			if (a == STRINGID_IQ_EPISODE && b == STRINGID_IQ_EPISODE) {
-				if (_game.id == GID_INDY3) {
-					saveIQPoints();
-				}
-				break;
-			}
-			// FIXME: changing savegame-names not supported
-			break;
-		case 0x03: // open file
-			a = resStrLen(_scriptPointer);
-			strncpy(_saveLoadVarsFilename, (const char *)_scriptPointer, a);
-			_saveLoadVarsFilename[a] = '\0';
-			_scriptPointer += a + 1;
-			break;
-		case 0x04:
-			return;
-		case 0x1F: // close file
-			_saveLoadVarsFilename[0] = '\0';
-			return;
-		}
-	}
-}
-
-void ScummEngine_v5::loadVars() {
-	int a, b;
-
-	while ((_opcode = fetchScriptByte()) != 0) {
-		switch (_opcode & 0x1F) {
-		case 0x01: // read a range of variables
-			getResultPos();
-			a = _resultVarNumber;
-			getResultPos();
-			b = _resultVarNumber;
-			debug(0, "stub loadVars: vars %d -> %d", a, b);
-			break;
-		case 0x02: // read a range of string variables
-			a = getVarOrDirectByte(PARAM_1);
-			b = getVarOrDirectByte(PARAM_2);
-
-			int slot;
-			int slotSize;
-			byte* slotContent;
-			int savegameId;
-			bool avail_saves[100];
-
-			if (a == STRINGID_IQ_SERIES && b == STRINGID_IQ_SERIES) {
-				// Zak256 loads the IQ script-slot but does not use it -> ignore it
-				if (_game.id == GID_INDY3) {
-					byte *ptr = getResourceAddress(rtString, STRINGID_IQ_SERIES);		
-					if (ptr) {
-						int size = getResourceSize(rtString, STRINGID_IQ_SERIES);
-						loadIQPoints(ptr, size);
-					}
-				}
-				break;
-			}
-
-			listSavegames(avail_saves, ARRAYSIZE(avail_saves));
-			for (slot = a; slot <= b; ++slot) {
-				slotSize = getResourceSize(rtString, slot);
-				slotContent = getResourceAddress(rtString, slot);
-
-				// load savegame names
-				savegameId = slot - a + 1;
-				Common::String name;
-				if (avail_saves[savegameId] && getSavegameName(savegameId, name)) {
-					int pos;
-					const char *ptr = name.c_str();
-					// slotContent ends with {'\0','@'} -> max. length = slotSize-2
-					for (pos = 0; pos < slotSize - 2; ++pos) {
-						if (!ptr[pos])
-							break;
-						// replace special characters
-						if (ptr[pos] >= 32 && ptr[pos] <= 122 && ptr[pos] != 64)
-							slotContent[pos] = ptr[pos];
-						else
-							slotContent[pos] = '_';
-					}
-					slotContent[pos] = '\0';
-				} else {
-					slotContent[0] = '\0';
-				}
-			}
-			break;
-		case 0x03: // open file
-			a = resStrLen(_scriptPointer);
-			strncpy(_saveLoadVarsFilename, (const char *)_scriptPointer, a);
-			_saveLoadVarsFilename[a] = '\0';
-			_scriptPointer += a + 1;
-			break;
-		case 0x04:
-			return;
-		case 0x1F: // close file
-			_saveLoadVarsFilename[0] = '\0';
-			return;
-		}
-	}
-}
-
-/**
- * IQ Point calculation for Indy3. 
- * The scripts that perform this task are 
- * - script-9 (save/load dialog initialization, loads room 14), 
- * - room-14-204 (load series IQ string), 
- * - room-14-205 (save series IQ string), 
- * - room-14-206 (calculate series IQ string).
- * Unfortunately script-9 contains lots of GUI stuff so calling this script
- * directly is not possible. The other scripts depend on script-9.
- */
-void ScummEngine_v5::updateIQPoints() {
-	int seriesIQ;
-	// IQString[0..72] corresponds to each puzzle's IQ.
-	// IQString[73] indicates that the IQ-file was loaded successfully and is always 0 when
-	// the IQ is calculated, hence it will be ignored here.
-	const int NUM_PUZZLES = 73;
-	byte seriesIQString[NUM_PUZZLES];
-	byte *episodeIQString;
-	int episodeIQStringSize;
-
-	// load string with IQ points given per puzzle in any savegame
-	// IMPORTANT: the resource string STRINGID_IQ_SERIES is only valid while
-	// the original save/load dialog is executed, so do not use it here.
-	memset(seriesIQString, 0, sizeof(seriesIQString));
-	loadIQPoints(seriesIQString, sizeof(seriesIQString));
-
-	// string with IQ points given per puzzle in current savegame
-	episodeIQString = getResourceAddress(rtString, STRINGID_IQ_EPISODE);
-	if (!episodeIQString)
-		return;
-	episodeIQStringSize = getResourceSize(rtString, STRINGID_IQ_EPISODE);
-	if (episodeIQStringSize < NUM_PUZZLES)
-		return;
-
-	// merge episode and series IQ strings and calculate series IQ
-	seriesIQ = 0;
-	// iterate over puzzles
-	for (int i = 0; i < NUM_PUZZLES ; ++i) {
-		byte puzzleIQ = seriesIQString[i];
-		// if puzzle is solved copy points to episode string
-		if (puzzleIQ > 0)
-			episodeIQString[i] = puzzleIQ;
-		// add puzzle's IQ-points to series IQ
-		seriesIQ += episodeIQString[i];
-	}
-	_scummVars[245] = seriesIQ;
-
-	// save series IQ string
-	saveIQPoints();
-}
-
-void ScummEngine_v5::saveIQPoints() {
-	// save Indy3 IQ-points
-	Common::OutSaveFile *file;
-	Common::String filename = _targetName + ".iq";
-
-	file = _saveFileMan->openForSaving(filename.c_str());
-	if (file != NULL) {
-		byte *ptr = getResourceAddress(rtString, STRINGID_IQ_EPISODE);
-		if (ptr) {
-			int size = getResourceSize(rtString, STRINGID_IQ_EPISODE);
-			file->write(ptr, size);
-		}
-		delete file;
-	}
-}
-
-void ScummEngine_v5::loadIQPoints(byte *ptr, int size) {
-	// load Indy3 IQ-points
-	Common::InSaveFile *file;
-	Common::String filename = _targetName + ".iq";
-
-	file = _saveFileMan->openForLoading(filename.c_str());
-	if (file != NULL) {
-		byte *tmp = (byte*)malloc(size);
-		int nread = file->read(tmp, size);
-		if (nread == size) {
-			memcpy(ptr, tmp, size);
-		}
-		free(tmp);
-		delete file;
-	}
-}
-
 void ScummEngine_v5::o5_expression() {
 	int dst, i;
 
@@ -1249,99 +1031,7 @@
 	setResult(getObjY(a));
 }
 
-void ScummEngine_v5::o5_saveLoadGame() {
-	getResultPos();
-	byte a = getVarOrDirectByte(PARAM_1);
-	byte slot = a & 0x1F;
-	byte result = 0;
-
-	// Slot numbers in older games start with 0, in newer games with 1
-	if (_game.version <= 2)
-		slot++;
-
-	if ((_game.id == GID_MANIAC) && (_game.version <= 1)) {
-		// Convert older load/save screen
-		// 1 Load
-		// 2 Save
-		slot = 1;
-		if (a == 1)
-			_opcode = 0x40;
-		else if ((a == 2) || (_game.platform == Common::kPlatformNES))
-			_opcode = 0x80;
-	} else {
-		_opcode = a & 0xE0;
-	}
-
-	switch (_opcode) {
-	case 0x00: // num slots available
-		result = 100;
-		break;
-	case 0x20: // drive
-		if (_game.version <= 3) {
-			// 0 = ???
-			// [1,2] = disk drive [A:,B:]
-			// 3 = hard drive
-			result = 3;
-		} else {
-			// set current drive
-			result = 1;
-		}
-		break;
-	case 0x40: // load
-		if (loadState(slot, false))
-			result = 3; // sucess
-		else
-			result = 5; // failed to load
-		break;
-	case 0x80: // save
-		if (_game.version <= 3) {
-			char name[32];
-			if (_game.version <= 2) {
-				// use generic name
-				sprintf(name, "Game %c", 'A'+slot-1);
-			} else {
-				// use name entered by the user
-				char* ptr;
-				int firstSlot = (_game.id == GID_LOOM) ? STRINGID_SAVENAME1_LOOM : STRINGID_SAVENAME1;
-				ptr = (char*)getStringAddress(slot + firstSlot - 1);
-				strncpy(name, ptr, sizeof(name));
-			}
-
-			if (((ScummEngine_v3 *)this)->savePreparedSavegame(slot, name))
-				result = 0;
-			else
-				result = 2;
-		} else {
-			result = 2; // failed to save
-		}
-		break;
-	case 0xC0: // test if save exists
-		{
-		Common::InSaveFile *file;
-		bool avail_saves[100];
-
-		listSavegames(avail_saves, ARRAYSIZE(avail_saves));
-		Common::String filename = makeSavegameName(slot, false);
-		if (avail_saves[slot] && (file = _saveFileMan->openForLoading(filename.c_str()))) {
-			result = 6; // save file exists
-			delete file;
-		} else
-			result = 7; // save file does not exist
-		}
-		break;
-	default:
-		error("o5_saveLoadGame: unknown subopcode %d", _opcode);
-	}
-
-	setResult(result);
-}
-
 void ScummEngine_v5::o5_getAnimCounter() {
-	if (_game.version == 3) {
-		o5_saveLoadGame();
-		return;
-	}
-
 	getResultPos();
 
 	int act = getVarOrDirectByte(PARAM_1);
@@ -2407,7 +2097,7 @@
 	// WORKAROUND: Indy3 does not save the series IQ automatically after changing it.
 	// Save on IQ increment (= script 125 was executed).
 	if (_game.id == GID_INDY3 && script == 125)
-		updateIQPoints();
+		((ScummEngine_v4 *)this)->updateIQPoints();
 }
 
 void ScummEngine_v5::o5_stopObjectCode() {

Modified: scummvm/trunk/engines/scumm/scumm.cpp
===================================================================
--- scummvm/trunk/engines/scumm/scumm.cpp	2009-04-19 01:01:28 UTC (rev 40013)
+++ scummvm/trunk/engines/scumm/scumm.cpp	2009-04-19 01:01:54 UTC (rev 40014)
@@ -2082,6 +2082,19 @@
 	}
 }
 
+void ScummEngine_v4::scummLoop_handleSaveLoad() {
+	// copy saveLoadFlag as handleSaveLoad() resets it
+	byte saveLoad = _saveLoadFlag;
+
+	ScummEngine_v5::scummLoop_handleSaveLoad();
+
+	// update IQ points after loading
+	if (saveLoad == 2) {
+		if (_game.id == GID_INDY3)
+			updateIQPoints();
+	}
+}
+
 void ScummEngine_v5::scummLoop_handleSaveLoad() {
 	// copy saveLoadFlag as handleSaveLoad() resets it
 	byte saveLoad = _saveLoadFlag;
@@ -2090,8 +2103,6 @@
 
 	// update IQ points after loading
 	if (saveLoad == 2) {
-		if (_game.id == GID_INDY3)
-			updateIQPoints();
 		if (_game.id == GID_INDY4)
 			runScript(145, 0, 0, 0);
 	}

Modified: scummvm/trunk/engines/scumm/scumm_v3.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm_v3.h	2009-04-19 01:01:28 UTC (rev 40013)
+++ scummvm/trunk/engines/scumm/scumm_v3.h	2009-04-19 01:01:54 UTC (rev 40014)
@@ -35,21 +35,6 @@
  */
 class ScummEngine_v3 : public ScummEngine_v4 {
 public:
-
-	/**
-	 * Prepared savegame used by the orginal save/load dialog.
-	 * Must be valid as long as the savescreen is active. As we are not
-	 * notified when the savescreen is closed, memory is only freed on a game
-	 * reset, at the destruction of the engine or when the original save/load
-	 * dialog is entered the next time.
-	 */
-	Common::SeekableReadStream *_savePreparedSavegame;
-
-	void prepareSavegame();
-	bool savePreparedSavegame(int slot, char *desc);
-
-
-public:
 	ScummEngine_v3(OSystem *syst, const DetectorResult &dr);
 	~ScummEngine_v3();
 

Modified: scummvm/trunk/engines/scumm/scumm_v4.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm_v4.h	2009-04-19 01:01:28 UTC (rev 40013)
+++ scummvm/trunk/engines/scumm/scumm_v4.h	2009-04-19 01:01:54 UTC (rev 40014)
@@ -34,7 +34,22 @@
  * Engine for version 4 SCUMM games; GF_SMALL_HEADER is always set for these.
  */
 class ScummEngine_v4 : public ScummEngine_v5 {
+	friend class ScummEngine_v5;
 public:
+
+	/**
+	 * Prepared savegame used by the orginal save/load dialog.
+	 * Must be valid as long as the savescreen is active. As we are not
+	 * notified when the savescreen is closed, memory is only freed on a game
+	 * reset, at the destruction of the engine or when the original save/load
+	 * dialog is entered the next time.
+	 */
+	Common::SeekableReadStream *_savePreparedSavegame;
+
+	void prepareSavegame();
+	bool savePreparedSavegame(int slot, char *desc);
+
+public:
 	ScummEngine_v4(OSystem *syst, const DetectorResult &dr);
 
 	virtual void resetScumm();
@@ -42,6 +57,8 @@
 protected:
 	virtual void setupOpcodes();
 
+	virtual void scummLoop_handleSaveLoad();
+
 	virtual void readResTypeList(int id);
 	virtual void readIndexFile();
 	virtual void loadCharset(int no);
@@ -51,11 +68,19 @@
 
 	virtual void resetRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL);
 
+	void saveVars();
+	void loadVars();
+	void saveIQPoints();
+	void loadIQPoints(byte *ptr, int size);
+	void updateIQPoints();
+
 	/* Version 4 script opcodes */
 	void o4_ifState();
 	void o4_ifNotState();
 	void o4_oldRoomEffect();
 	void o4_pickupObject();
+	void o4_saveLoadGame();
+	void o4_saveLoadVars();
 };
 
 

Modified: scummvm/trunk/engines/scumm/scumm_v5.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm_v5.h	2009-04-19 01:01:28 UTC (rev 40013)
+++ scummvm/trunk/engines/scumm/scumm_v5.h	2009-04-19 01:01:54 UTC (rev 40014)
@@ -72,11 +72,6 @@
 	virtual void readMAXS(int blockSize);
 
 	int getWordVararg(int *ptr);
-	void saveVars();
-	void loadVars();
-	void saveIQPoints();
-	void loadIQPoints(byte *ptr, int size);
-	void updateIQPoints();
 
 	virtual int getVar();
 	virtual int getVarOrDirectByte(byte mask);
@@ -109,6 +104,7 @@
 	void o5_doSentence();
 	void o5_drawBox();
 	void o5_drawObject();
+	void o5_dummy();
 	void o5_endCutscene();
 	void o5_equalZero();
 	void o5_expression();
@@ -167,8 +163,6 @@
 	void o5_systemOps();
 	void o5_resourceRoutines();
 	void o5_roomOps();
-	void o5_saveLoadGame();
-	void o5_saveLoadVars();
 	void o5_saveRestoreVerbs();
 	void o5_setCameraAt();
 	void o5_setClass();


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