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

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Mon Jun 14 21:37:19 CEST 2010


Revision: 49666
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49666&view=rev
Author:   thebluegr
Date:     2010-06-14 19:37:19 +0000 (Mon, 14 Jun 2010)

Log Message:
-----------
Cleanup of the SCI0 object initialization code

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

Modified: scummvm/trunk/engines/sci/engine/script.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/script.cpp	2010-06-14 18:19:45 UTC (rev 49665)
+++ scummvm/trunk/engines/sci/engine/script.cpp	2010-06-14 19:37:19 UTC (rev 49666)
@@ -192,8 +192,7 @@
 				return;
 			}
 
-			_classTable[species].reg.segment = seg;
-			_classTable[species].reg.offset = classpos;
+			setClassOffset(species, make_reg(seg, classpos));
 		}
 		seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2;
 	}
@@ -231,85 +230,69 @@
 
 void script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) {
 	int objType;
-	uint32 objLength = 0;
+	reg_t addr;
 	bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
-	uint16 curOffset = oldScriptHeader ? 2 : 0;
 
-	// Now do a first pass through the script objects to find all the object classes
+	// The script is initialized in 2 passes. 
+	// Pass 1: creates a lookup table of all used classes
+	// Pass 2: loads classes and objects
 
-	do {
-		objType = scr->getHeap(curOffset);
-		if (!objType)
-			break;
+	for (uint16 pass = 0; pass <= 1; pass++) {
+		uint16 objLength = 0;
+		uint16 curOffset = oldScriptHeader ? 2 : 0;
 
-		objLength = scr->getHeap(curOffset + 2);
-		curOffset += 4;		// skip header
+		do {
+			objType = scr->getHeap(curOffset);
+			if (!objType)
+				break;
 
-		switch (objType) {
-		case SCI_OBJ_CLASS: {
-			int classpos = curOffset - SCRIPT_OBJECT_MAGIC_OFFSET;
-			int species = scr->getHeap(curOffset - SCRIPT_OBJECT_MAGIC_OFFSET + SCRIPT_SPECIES_OFFSET);
-			if (species < 0 || species >= (int)segMan->classTableSize()) {
-				if (species == (int)segMan->classTableSize()) {
-					// Happens in the LSL2 demo
-					warning("Applying workaround for an off-by-one invalid species access");
-					segMan->resizeClassTable(segMan->classTableSize() + 1);
-				} else {
-					error("Invalid species %d(0x%x) not in interval "
-							  "[0,%d) while instantiating script at segment %d\n",
-							  species, species, segMan->classTableSize(),
-							  segmentId);
-					return;
-				}
-			}
+			objLength = scr->getHeap(curOffset + 2);
+			curOffset += 4;		// skip header
+			addr = make_reg(segmentId, curOffset);;
 
-			segMan->setClassOffset(species, make_reg(segmentId, classpos));
-			// Set technical class position-- into the block allocated for it
-		}
-		break;
+			switch (objType) {
+			case SCI_OBJ_CODE:
+				if (pass == 0)
+					scr->scriptAddCodeBlock(addr);
+				break;
+			case SCI_OBJ_OBJECT:
+			case SCI_OBJ_CLASS:
+				if (pass == 0 && objType == SCI_OBJ_CLASS) {
+					int classpos = curOffset + 8;	// SCRIPT_OBJECT_MAGIC_OFFSET
+					int species = scr->getHeap(classpos);
 
-		default:
-			break;
-		}
+					if (species == (int)segMan->classTableSize()) {
+						// Happens in the LSL2 demo
+						warning("Applying workaround for an off-by-one invalid species access");
+						segMan->resizeClassTable(segMan->classTableSize() + 1);
+					} else if (species < 0 || species > (int)segMan->classTableSize()) {
+						error("Invalid species %d(0x%x) not in interval "
+								  "[0,%d) while instantiating script at segment %d\n",
+								  species, species, segMan->classTableSize(),
+								  segmentId);
+						return;
+					}
 
-		curOffset += objLength - 4;
-	} while (objType != 0 && curOffset < scr->getScriptSize() - 2);
+					segMan->setClassOffset(species, make_reg(segmentId, classpos));
+				} else if (pass == 1) {
+					Object *obj = scr->scriptObjInit(addr);
+					obj->initSpecies(segMan, addr);
 
-	// And now a second pass to adjust objects and class pointers, and the general pointers
-	objLength = 0;
-	curOffset = oldScriptHeader ? 2 : 0;
+					if (!obj->initBaseObject(segMan, addr)) {
+						warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
+						scr->scriptObjRemove(addr);
+					}
+				}
+				break;
 
-	do {
-		objType = scr->getHeap(curOffset);
-		if (!objType)
-			break;
-
-		objLength = scr->getHeap(curOffset + 2);
-		curOffset += 4;		// skip header
-
-		reg_t addr = make_reg(segmentId, curOffset);
-
-		switch (objType) {
-		case SCI_OBJ_CODE:
-			scr->scriptAddCodeBlock(addr);
-			break;
-		case SCI_OBJ_OBJECT:
-		case SCI_OBJ_CLASS: { // object or class?
-			Object *obj = scr->scriptObjInit(addr);
-			obj->initSpecies(segMan, addr);
-
-			if (!obj->initBaseObject(segMan, addr)) {
-				warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
-				scr->scriptObjRemove(addr);
+			default:
+				break;
 			}
-		} // if object or class
-		break;
-		default:
-			break;
-		}
 
-		curOffset += objLength - 4;
-	} while (objType != 0 && curOffset < scr->getScriptSize() - 2);
+			curOffset += objLength - 4;
+		} while (objType != 0 && curOffset < scr->getScriptSize() - 2);
+	}	// for
+
 }
 
 int script_instantiate(ResourceManager *resMan, SegManager *segMan, int scriptNum) {
@@ -411,16 +394,11 @@
 		script_uninstantiate_sci0(segMan, script_nr, segment);
 	// FIXME: Add proper script uninstantiation for SCI 1.1
 
-	if (scr->getLockers())
-		return; // if xxx.lockers > 0
-
-	// Otherwise unload it completely
-	// Explanation: I'm starting to believe that this work is done by SCI itself.
-	scr->markDeleted();
-
-	debugC(kDebugLevelScripts, "Unloaded script 0x%x.", script_nr);
-
-	return;
+	if (!scr->getLockers()) {
+		// The actual script deletion seems to be done by SCI scripts themselves
+		scr->markDeleted();
+		debugC(kDebugLevelScripts, "Unloaded script 0x%x.", script_nr);
+	}
 }
 
 


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