From 49c8d1a549deb7abdb49339c81031ea46c7716b5 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sun, 5 Sep 2010 15:34:25 +0000 Subject: SCI: kClone cleanup and fixing possible crash & typo svn-id: r52565 --- engines/sci/engine/kscripts.cpp | 49 +++++++++++++++++++++-------------------- engines/sci/engine/segment.h | 3 --- 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; } -- cgit v1.2.3