aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMartin Kiewitz2010-09-03 18:14:59 +0000
committerMartin Kiewitz2010-09-03 18:14:59 +0000
commit87b78b1673037409604cdb4a1a5d6884af71bac1 (patch)
treeff386819ec9c9cf1575575d8e27096857b617867 /engines
parentb7a2fd899e07c3ae47bf5c845aadba6991c33666 (diff)
downloadscummvm-rg350-87b78b1673037409604cdb4a1a5d6884af71bac1.tar.gz
scummvm-rg350-87b78b1673037409604cdb4a1a5d6884af71bac1.tar.bz2
scummvm-rg350-87b78b1673037409604cdb4a1a5d6884af71bac1.zip
SCI: kClone/kDisposeClone behaviour more accurate
now also checking -info- selector, if object is supposed to get freed. Fixes kq4 early hanging (in intro, when opening door, etc.) svn-id: r52508
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/kscripts.cpp24
-rw-r--r--engines/sci/engine/selector.cpp2
-rw-r--r--engines/sci/engine/selector.h1
-rw-r--r--engines/sci/engine/static_selectors.cpp2
4 files changed, 21 insertions, 8 deletions
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index a5501c160f..d99302b3d4 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -172,27 +172,37 @@ reg_t kClone(EngineState *s, int argc, reg_t *argv) {
s->_segMan->getScript(parent_obj->getPos().segment)->incrementLockers();
s->_segMan->getScript(clone_obj->getPos().segment)->incrementLockers();
+ // Mark as clone for scripts as well
+ uint16 infoSelector = readSelectorValue(s->_segMan, clone_addr, SELECTOR(_info_));
+ writeSelectorValue(s->_segMan, clone_addr, SELECTOR(_info_), (infoSelector & 0x7fff) | 1);
+
return clone_addr;
}
extern void _k_view_list_mark_free(EngineState *s, reg_t off);
reg_t kDisposeClone(EngineState *s, int argc, reg_t *argv) {
- reg_t victim_addr = argv[0];
- Clone *victim_obj = s->_segMan->getObject(victim_addr);
+ reg_t obj = argv[0];
+ Clone *object = s->_segMan->getObject(obj);
- if (!victim_obj) {
+ if (!object) {
error("Attempt to dispose non-class/object at %04x:%04x",
- PRINT_REG(victim_addr));
+ PRINT_REG(obj));
return s->r_acc;
}
- if (!victim_obj->isClone()) {
- // SCI silently ignores this behaviour; some games actually depend on it
+ if (!object->isClone()) {
+ // SCI silently ignores non-clones; some games actually depend on it
return s->r_acc;
}
- victim_obj->markAsFreed();
+ // SCI uses this technique to find out, if it's a clone and if it's supposed to get freed
+ // At least kq4early relies on this behaviour. The scripts clone "Sound", then set bit 1 manually
+ // and call kDisposeClone later. In that case we may not free it, otherwise we will run into issues
+ // later, because kIsObject would then return false and Sound object wouldn't get checked.
+ uint16 infoSelector = readSelectorValue(s->_segMan, obj, SELECTOR(_info_));
+ if ((infoSelector & 3) == 1)
+ object->markAsFreed();
return s->r_acc;
}
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index 436a4b98ff..b31f52aa13 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -50,7 +50,7 @@ namespace Sci {
void Kernel::mapSelectors() {
// species
// superClass
- // -info-
+ FIND_SELECTOR2(_info_, "-info-");
FIND_SELECTOR(y);
FIND_SELECTOR(x);
FIND_SELECTOR(view);
diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h
index 63ec11fab1..98157c3eaf 100644
--- a/engines/sci/engine/selector.h
+++ b/engines/sci/engine/selector.h
@@ -40,6 +40,7 @@ struct SelectorCache {
}
// Statically defined selectors, (almost the) same in all SCI versions
+ Selector _info_;
Selector y;
Selector x;
Selector view, loop, cel; ///< Description of a specific image
diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp
index de7adb68c4..8ba10c5569 100644
--- a/engines/sci/engine/static_selectors.cpp
+++ b/engines/sci/engine/static_selectors.cpp
@@ -98,6 +98,7 @@ static const char * const sci2Selectors[] = {
#endif
static const SelectorRemap sciSelectorRemap[] = {
+ { SCI_VERSION_0_EARLY, SCI_VERSION_1_LATE, "-info-", 2 },
{ SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE, "moveDone", 170 },
{ SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE, "points", 316 },
{ SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE, "flags", 368 },
@@ -106,6 +107,7 @@ static const SelectorRemap sciSelectorRemap[] = {
{ SCI_VERSION_1_EARLY, SCI_VERSION_1_LATE, "topString", 101 },
{ SCI_VERSION_1_EARLY, SCI_VERSION_1_LATE, "flags", 102 },
// SCI1.1
+ { SCI_VERSION_1_1, SCI_VERSION_2_1, "-info-",4103 },
{ SCI_VERSION_1_1, SCI_VERSION_1_1, "nodePtr", 41 },
{ SCI_VERSION_1_1, SCI_VERSION_1_1, "cantBeHere", 54 },
{ SCI_VERSION_1_1, SCI_VERSION_1_1, "topString", 98 },