[Scummvm-cvs-logs] scummvm master -> 78e7f5b51c04a7751c9c6462a542257f817261d3

wjp wjp at usecode.org
Sat Dec 14 14:20:25 CET 2013


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:
78e7f5b51c SCI: Make second pass when loading objects


Commit: 78e7f5b51c04a7751c9c6462a542257f817261d3
    https://github.com/scummvm/scummvm/commit/78e7f5b51c04a7751c9c6462a542257f817261d3
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2013-12-14T05:19:33-08:00

Commit Message:
SCI: Make second pass when loading objects

This is because objects may be loaded before their base objects,
which causes initBaseObject to fail for SCI0.

Script::initializeObjectsSci0 already did this, but
SegManager::saveLoadWithSerializer did not when calling
initBaseObject after loading a savegame.

Changed paths:
    engines/sci/engine/object.cpp
    engines/sci/engine/savegame.cpp



diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp
index b28026b..6f219b3 100644
--- a/engines/sci/engine/object.cpp
+++ b/engines/sci/engine/object.cpp
@@ -175,6 +175,7 @@ bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClas
 			_variables.resize(baseObj->getVarCount());
 		// Copy base from species class, as we need its selector IDs
 		_baseObj = baseObj->_baseObj;
+		assert(_baseObj);
 		if (doInitSuperClass)
 			initSuperClass(segMan, addr);
 
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 16b88b5..ce9a672 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -219,25 +219,30 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
 
 	syncArray<Class>(s, _classTable);
 
-	// Now that all scripts are loaded, init their objects
-	for (uint i = 0; i < _heap.size(); i++) {
-		if (!_heap[i] ||  _heap[i]->getType() != SEG_TYPE_SCRIPT)
-			continue;
+	// Now that all scripts are loaded, init their objects.
+	// Just like in Script::initializeObjectsSci0, we do two passes
+	// in case an object is loaded before its base.
+	int passes = getSciVersion() < SCI_VERSION_1_1 ? 2 : 1;
+	for (int pass = 1; pass <= passes; ++pass) {
+		for (uint i = 0; i < _heap.size(); i++) {
+			if (!_heap[i] ||  _heap[i]->getType() != SEG_TYPE_SCRIPT)
+				continue;
 
-		Script *scr = (Script *)_heap[i];
-		scr->syncLocalsBlock(this);
+			Script *scr = (Script *)_heap[i];
+			scr->syncLocalsBlock(this);
 
-		ObjMap objects = scr->getObjectMap();
-		for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) {
-			reg_t addr = it->_value.getPos();
-			Object *obj = scr->scriptObjInit(addr, false);
+			ObjMap objects = scr->getObjectMap();
+			for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) {
+				reg_t addr = it->_value.getPos();
+				Object *obj = scr->scriptObjInit(addr, false);
 
-			if (getSciVersion() < SCI_VERSION_1_1) {
-				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));
-					objects.erase(addr.toUint16());
+				if (pass == 2) {
+					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));
+						objects.erase(addr.toUint16());
+					}
 				}
 			}
 		}






More information about the Scummvm-git-logs mailing list