[Scummvm-cvs-logs] SF.net SVN: scummvm:[54510] scummvm/trunk/engines/sci/engine

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Sat Nov 27 19:08:47 CET 2010


Revision: 54510
          http://scummvm.svn.sourceforge.net/scummvm/?rev=54510&view=rev
Author:   thebluegr
Date:     2010-11-27 18:08:47 +0000 (Sat, 27 Nov 2010)

Log Message:
-----------
SCI: Fixed bug #3034713 - "ICEMAN Demo: Fails to find base object"

This could happen because objects in scripts can be in the wrong order.
Same thing happens in the French and German version of KQ5 (bug #3035396).
Removed the scriptObjRemove() method, which is in fact a hack.

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/savegame.cpp
    scummvm/trunk/engines/sci/engine/script.cpp
    scummvm/trunk/engines/sci/engine/script.h

Modified: scummvm/trunk/engines/sci/engine/savegame.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cpp	2010-11-27 17:29:42 UTC (rev 54509)
+++ scummvm/trunk/engines/sci/engine/savegame.cpp	2010-11-27 18:08:47 UTC (rev 54510)
@@ -194,17 +194,23 @@
 
 		for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) {
 			reg_t addr = it->_value.getPos();
-			Object *obj = scr->scriptObjInit(addr, false);
+			scr->scriptObjInit(addr, false);
+		}
 
-			if (getSciVersion() < SCI_VERSION_1_1) {
+		// In SCI0-SCI1, we need to make two passes, as the objects in the
+		// script might be in the wrong order (e.g. in the demo of Iceman).
+		// Refer to bug #3034713
+		if (getSciVersion() < SCI_VERSION_1_1) {
+			for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) {
+				reg_t addr = it->_value.getPos();
+				Object *obj = scr->scriptObjInit(addr, false);
 				if (!obj->initBaseObject(this, addr, false)) {
-					// TODO/FIXME: This should not be happening at all. It might indicate a possible issue
-					// with the garbage collector. It happens for example in LSL5 (German, perhaps English too).
-					warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
-					scr->scriptObjRemove(addr);
+					error("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
+					//scr->scriptObjRemove(addr);
 				}
 			}
 		}
+
 	}
 }
 

Modified: scummvm/trunk/engines/sci/engine/script.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/script.cpp	2010-11-27 17:29:42 UTC (rev 54509)
+++ scummvm/trunk/engines/sci/engine/script.cpp	2010-11-27 18:08:47 UTC (rev 54510)
@@ -255,13 +255,6 @@
 	return obj;
 }
 
-void Script::scriptObjRemove(reg_t obj_pos) {
-	if (getSciVersion() < SCI_VERSION_1_1)
-		obj_pos.offset += 8;
-
-	_objects.erase(obj_pos.toUint16());
-}
-
 // This helper function is used by Script::relocateLocal and Object::relocate
 // Duplicate in segment.cpp and script.cpp
 static bool relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location, size_t scriptSize) {
@@ -580,42 +573,42 @@
 
 void Script::initialiseObjectsSci0(SegManager *segMan, SegmentId segmentId) {
 	bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
-	const byte *seeker = _buf + (oldScriptHeader ? 2 : 0);
 
-	do {
-		uint16 objType = READ_SCI11ENDIAN_UINT16(seeker);
-		if (!objType)
-			break;
+	// We need to make two passes, as the objects in the script might be in the
+	// wrong order (e.g. in the demo of Iceman) - refer to bug #3034713
+	for (int pass = 1; pass <= 2; pass++) {
+		const byte *seeker = _buf + (oldScriptHeader ? 2 : 0);
 
-		switch (objType) {
-		case SCI_OBJ_OBJECT:
-		case SCI_OBJ_CLASS:
-			{
-				reg_t addr = make_reg(segmentId, seeker - _buf + 4);
-				Object *obj = scriptObjInit(addr);
-				obj->initSpecies(segMan, addr);
+		do {
+			uint16 objType = READ_SCI11ENDIAN_UINT16(seeker);
+			if (!objType)
+				break;
 
-				if (!obj->initBaseObject(segMan, addr)) {
-					if ((_nr == 202 || _nr == 764) && g_sci->getGameId() == GID_KQ5) {
-						// WORKAROUND: Script 202 of KQ5 French and German 
-						// (perhaps Spanish too?) has an invalid object.
-						// This is non-fatal. Refer to bug #3035396.
-						// Same happens with script 764, it seems to contain junk towards its end
-					} else {
-						error("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
+			switch (objType) {
+			case SCI_OBJ_OBJECT:
+			case SCI_OBJ_CLASS:
+				{
+					reg_t addr = make_reg(segmentId, seeker - _buf + 4);
+					Object *obj = scriptObjInit(addr);
+					obj->initSpecies(segMan, addr);
+
+					if (pass == 2) {
+						if (!obj->initBaseObject(segMan, addr)) {
+							error("Failed to locate base object for object at %04X:%04X", PRINT_REG(addr));
+							//scriptObjRemove(addr);
+						}
 					}
-					scriptObjRemove(addr);
 				}
+				break;
+
+			default:
+				break;
 			}
-			break;
 
-		default:
-			break;
-		}
+			seeker += READ_SCI11ENDIAN_UINT16(seeker + 2);
+		} while ((uint32)(seeker - _buf) < getScriptSize() - 2);
+	}
 
-		seeker += READ_SCI11ENDIAN_UINT16(seeker + 2);
-	} while ((uint32)(seeker - _buf) < getScriptSize() - 2);
-
 	byte *relocationBlock = findBlockSCI0(SCI_OBJ_POINTERS);
 	if (relocationBlock)
 		relocateSci0Sci21(make_reg(segmentId, relocationBlock - getBuf() + 4));

Modified: scummvm/trunk/engines/sci/engine/script.h
===================================================================
--- scummvm/trunk/engines/sci/engine/script.h	2010-11-27 17:29:42 UTC (rev 54509)
+++ scummvm/trunk/engines/sci/engine/script.h	2010-11-27 18:08:47 UTC (rev 54510)
@@ -137,12 +137,6 @@
 	Object *scriptObjInit(reg_t obj_pos, bool fullObjectInit = true);
 
 	/**
-	 * Removes a script object
-	 * @param obj_pos	Location (segment, offset) of the object.
-	 */
-	void scriptObjRemove(reg_t obj_pos);
-
-	/**
 	 * Initializes the script's local variables
 	 * @param segMan	A reference to the segment manager
 	 */


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