aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/object.cpp65
1 files changed, 58 insertions, 7 deletions
diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp
index a4e5d47660..0b2abf1c9b 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;
}