aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kiewitz2010-09-05 15:34:25 +0000
committerMartin Kiewitz2010-09-05 15:34:25 +0000
commit49c8d1a549deb7abdb49339c81031ea46c7716b5 (patch)
tree9586f08cfc3803bf43614553fd4b2c395b4b3cd8
parent13e24af0cace8599d31c8bb7381fa9fce49a8e6e (diff)
downloadscummvm-rg350-49c8d1a549deb7abdb49339c81031ea46c7716b5.tar.gz
scummvm-rg350-49c8d1a549deb7abdb49339c81031ea46c7716b5.tar.bz2
scummvm-rg350-49c8d1a549deb7abdb49339c81031ea46c7716b5.zip
SCI: kClone cleanup
and fixing possible crash & typo svn-id: r52565
-rw-r--r--engines/sci/engine/kscripts.cpp49
-rw-r--r--engines/sci/engine/segment.h3
2 files changed, 25 insertions, 27 deletions
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index ef99c4cc85..a975ce2988 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -143,23 +143,23 @@ reg_t kResCheck(EngineState *s, int argc, reg_t *argv) {
}
reg_t kClone(EngineState *s, int argc, reg_t *argv) {
- reg_t parent_addr = argv[0];
- const Object *parent_obj = s->_segMan->getObject(parent_addr);
- const bool parentIsClone = parent_obj->isClone();
- reg_t clone_addr;
- Clone *clone_obj; // same as Object*
-
- if (!parent_obj) {
- error("Attempt to clone non-object/class at %04x:%04x failed", PRINT_REG(parent_addr));
+ reg_t parentAddr = argv[0];
+ const Object *parentObj = s->_segMan->getObject(parentAddr);
+ reg_t cloneAddr;
+ Clone *cloneObj; // same as Object*
+
+ if (!parentObj) {
+ error("Attempt to clone non-object/class at %04x:%04x failed", PRINT_REG(parentAddr));
return NULL_REG;
}
- debugC(2, kDebugLevelMemory, "Attempting to clone from %04x:%04x", PRINT_REG(parent_addr));
+ debugC(2, kDebugLevelMemory, "Attempting to clone from %04x:%04x", PRINT_REG(parentAddr));
- clone_obj = s->_segMan->allocateClone(&clone_addr);
+ uint16 infoSelector = readSelectorValue(s->_segMan, parentAddr, SELECTOR(_info_));
+ cloneObj = s->_segMan->allocateClone(&cloneAddr);
- if (!clone_obj) {
- error("Cloning %04x:%04x failed-- internal error", PRINT_REG(parent_addr));
+ if (!cloneObj) {
+ error("Cloning %04x:%04x failed-- internal error", PRINT_REG(parentAddr));
return NULL_REG;
}
@@ -168,24 +168,25 @@ reg_t kClone(EngineState *s, int argc, reg_t *argv) {
// invalidate all pointers, references and iterators to data in the clones
// segment.
//
- // The reason why it might invalidate those is, that the segement code
+ // The reason why it might invalidate those is, that the segment code
// (Table) uses Common::Array for internal storage. Common::Array now
// might invalidate references to its contained data, when it has to
// extend the internal storage size.
- if (parentIsClone)
- parent_obj = s->_segMan->getObject(parent_addr);
+ if (infoSelector & kInfoFlagClone)
+ parentObj = s->_segMan->getObject(parentAddr);
- *clone_obj = *parent_obj;
+ *cloneObj = *parentObj;
// Mark as clone
- clone_obj->markAsClone(); // sets bit 0 of -info- selector
- clone_obj->setSpeciesSelector(clone_obj->getPos());
- if (parent_obj->isClass())
- clone_obj->setSuperClassSelector(parent_obj->getPos());
- s->_segMan->getScript(parent_obj->getPos().segment)->incrementLockers();
- s->_segMan->getScript(clone_obj->getPos().segment)->incrementLockers();
-
- return clone_addr;
+ writeSelectorValue(s->_segMan, cloneAddr, SELECTOR(_info_), infoSelector | kInfoFlagClone);
+
+ cloneObj->setSpeciesSelector(cloneObj->getPos());
+ if (parentObj->isClass())
+ cloneObj->setSuperClassSelector(parentObj->getPos());
+ s->_segMan->getScript(parentObj->getPos().segment)->incrementLockers();
+ s->_segMan->getScript(cloneObj->getPos().segment)->incrementLockers();
+
+ return cloneAddr;
}
extern void _k_view_list_mark_free(EngineState *s, reg_t off);
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 3c7addfab2..6eca708e2e 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -290,9 +290,6 @@ public:
bool isClass() const { return (getInfoSelector().offset & kInfoFlagClass); }
const Object *getClass(SegManager *segMan) const;
- void markAsClone() { setInfoSelector(make_reg(0, getInfoSelector().offset | kInfoFlagClone)); }
- bool isClone() const { return (getInfoSelector().offset & kInfoFlagClone); }
-
void markAsFreed() { _flags |= OBJECT_FLAG_FREED; }
bool isFreed() const { return _flags & OBJECT_FLAG_FREED; }