[Scummvm-cvs-logs] scummvm master -> c1cdc49ac57880c069607600b53d1ee958b723a2

wjp wjp at usecode.org
Mon Mar 14 20:35:22 CET 2011


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:
c1cdc49ac5 SCI: Add code to enumerate shadowed selectors


Commit: c1cdc49ac57880c069607600b53d1ee958b723a2
    https://github.com/scummvm/scummvm/commit/c1cdc49ac57880c069607600b53d1ee958b723a2
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2011-03-14T12:34:16-07:00

Commit Message:
SCI: Add code to enumerate shadowed selectors

If an object defines more variables than its base class, some method
selectors may be hidden. This code tries to enumerate the affected
selectors. It may be useful for mass-scanning objects using
'find_callk Dummy'.

It's disabled by default currently since it does things to partially
uninitialized objects that I can't guarantee are 100% safe at this
point.

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



diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp
index a4e5d47..0b2abf1 100644
--- a/engines/sci/engine/object.cpp
+++ b/engines/sci/engine/object.cpp
@@ -172,8 +172,16 @@ bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClas
 	const Object *baseObj = segMan->getObject(getSpeciesSelector());
 
 	if (baseObj) {
-		if (_variables.size() != baseObj->getVarCount()) {
-			warning("Object %04x:%04x varnum doesn't match baseObj's: obj %d, base %d ", PRINT_REG(_pos), _variables.size(), baseObj->getVarCount());
+		uint originalVarCount = _variables.size();
+
+		if (_variables.size() != baseObj->getVarCount())
+			_variables.resize(baseObj->getVarCount());
+		// Copy base from species class, as we need its selector IDs
+		_baseObj = baseObj->_baseObj;
+		if (doInitSuperClass)
+			initSuperClass(segMan, addr);
+
+		if (_variables.size() != originalVarCount) {
 			// These objects are probably broken.
 			// An example is 'witchCage' in script 200 in KQ5 (#3034714),
 			// but also 'girl' in script 216 and 'door' in script 22.
@@ -182,12 +190,55 @@ bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClas
 
 			// The effect is that a number of its method selectors may be
 			// treated as variable selectors, causing unpredictable effects.
+			int objScript = segMan->getScript(_pos.segment)->getScriptNumber();
+
+			// We have to do a little bit of work to get the name of the object
+			// before any relocations are done.
+			reg_t nameReg = getNameSelector();
+			const char *name;
+			if (nameReg.isNull()) {
+				name = "<no name>";
+			} else {
+				nameReg.segment = _pos.segment;
+				name = segMan->derefString(nameReg);
+				if (!name)
+					name = "<invalid name>";
+			}
+
+			warning("Object %04x:%04x (name %s, script %d) varnum doesn't "
+			        "match baseObj's: obj %d, base %d ", PRINT_REG(_pos),
+			        name, objScript, originalVarCount, baseObj->getVarCount());
+
+#if 0
+			// We enumerate the methods selectors which could be hidden here
+			if (getSciVersion() <= SCI_VERSION_2_1) {
+				const SegmentRef objRef = segMan->dereference(baseObj->_pos);
+				assert(objRef.isRaw);
+				uint segBound = objRef.maxSize/2 - baseObj->getVarCount();
+				const byte* buf = (const byte *)baseObj->_baseVars;
+				if (!buf) {
+					// While loading this may happen due to objects being loaded
+					// out of order, and we can't proceed then, unfortunately.
+					segBound = 0;
+				}
+				for (uint i = baseObj->getVarCount();
+				         i < originalVarCount && i < segBound; ++i) {
+					uint16 slc = READ_SCI11ENDIAN_UINT16(buf + 2*i);
+					// Skip any numbers which happen to be varselectors too
+					bool found = false;
+					for (uint j = 0; j < baseObj->getVarCount() && !found; ++j)
+						found = READ_SCI11ENDIAN_UINT16(buf + 2*j) == slc;
+					if (found) continue;
+					// Skip any selectors which aren't method selectors,
+					// so couldn't be mistaken for varselectors
+					if (lookupSelector(segMan, _pos, slc, 0, 0) != kSelectorMethod) continue;
+					warning("    Possibly affected selector: %02x (%s)", slc,
+					        g_sci->getKernel()->getSelectorName(slc).c_str());
+				}
+			}
+#endif
 		}
-		_variables.resize(baseObj->getVarCount());
-		// Copy base from species class, as we need its selector IDs
-		_baseObj = baseObj->_baseObj;
-		if (doInitSuperClass)
-			initSuperClass(segMan, addr);
+
 		return true;
 	}
 






More information about the Scummvm-git-logs mailing list