aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorColin Snover2017-04-01 22:01:22 -0500
committerColin Snover2017-04-23 13:07:25 -0500
commit3d4fb4ccb4f8bed013e6be9f9c677a071e84266d (patch)
tree21fba33cf1f41ef856c6386e181b09fad17066e0 /engines
parent1962b1bb6d495365110094f200d50cc4cb303b75 (diff)
downloadscummvm-rg350-3d4fb4ccb4f8bed013e6be9f9c677a071e84266d.tar.gz
scummvm-rg350-3d4fb4ccb4f8bed013e6be9f9c677a071e84266d.tar.bz2
scummvm-rg350-3d4fb4ccb4f8bed013e6be9f9c677a071e84266d.zip
SCI32: Fix mustSetViewVisible for SCI3
In SCI2/2.1, variable indexes are used along with a range encoded in the interpreter executable to determine whether an object variable is a view-related variable. Operands to aTop, sTop, ipToa, dpToa, ipTos, and dpTos are byte offsets into an object, which are divided by two to get the varindex to check against the interpreter range. In SCI3, objects in game scripts contain groups of 32 selectors, and each group has a flag that says whether or not the selectors in that group are view-related. Operands to aTop, sTop, ipToa, dpToa, ipTos, and dpTos are selectors.
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/object.cpp24
-rw-r--r--engines/sci/engine/object.h2
-rw-r--r--engines/sci/engine/selector.cpp4
-rw-r--r--engines/sci/engine/selector.h2
-rw-r--r--engines/sci/engine/vm.cpp6
5 files changed, 27 insertions, 11 deletions
diff --git a/engines/sci/engine/object.cpp b/engines/sci/engine/object.cpp
index edd721a1a3..9861e02a16 100644
--- a/engines/sci/engine/object.cpp
+++ b/engines/sci/engine/object.cpp
@@ -270,13 +270,29 @@ bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClas
}
#ifdef ENABLE_SCI32
-bool Object::mustSetViewVisible(const int index) const {
+bool Object::mustSetViewVisible(int index, const bool fromPropertyOp) const {
if (getSciVersion() == SCI_VERSION_3) {
- if ((uint)index < getVarCount()) {
- return _mustSetViewVisible[getVarSelector(index) >> 5];
+ // In SCI3, visible flag lookups are based on selectors
+
+ if (!fromPropertyOp) {
+ // varindexes must be converted to selectors
+ index = getVarSelector(index);
}
- return false;
+
+ if (index == -1) {
+ error("Selector %d is invalid for object %04x:%04x", index, PRINT_REG(_pos));
+ }
+
+ return _mustSetViewVisible[index >> 5];
} else {
+ // In SCI2, visible flag lookups are based on varindexes
+
+ if (fromPropertyOp) {
+ // property offsets must be converted to varindexes
+ assert((index % 2) == 0);
+ index >>= 1;
+ }
+
int minIndex, maxIndex;
if (g_sci->_features->usesAlternateSelectors()) {
minIndex = 24;
diff --git a/engines/sci/engine/object.h b/engines/sci/engine/object.h
index 992b6cdbc2..3b81497261 100644
--- a/engines/sci/engine/object.h
+++ b/engines/sci/engine/object.h
@@ -277,7 +277,7 @@ public:
void syncBaseObject(const SciSpan<const byte> &ptr) { _baseObj = ptr; }
#ifdef ENABLE_SCI32
- bool mustSetViewVisible(int selector) const;
+ bool mustSetViewVisible(const int index, const bool fromPropertyOp) const;
#endif
private:
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index 7f509f3968..e28ae799c6 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -230,8 +230,8 @@ reg_t readSelector(SegManager *segMan, reg_t object, Selector selectorId) {
}
#ifdef ENABLE_SCI32
-void updateInfoFlagViewVisible(Object *obj, int index) {
- if (getSciVersion() >= SCI_VERSION_2 && obj->mustSetViewVisible(index)) {
+void updateInfoFlagViewVisible(Object *obj, int index, bool fromPropertyOp) {
+ if (getSciVersion() >= SCI_VERSION_2 && obj->mustSetViewVisible(index, fromPropertyOp)) {
obj->setInfoSelectorFlag(kInfoFlagViewVisible);
}
}
diff --git a/engines/sci/engine/selector.h b/engines/sci/engine/selector.h
index f2e4ec0b7f..c6ecd9dd26 100644
--- a/engines/sci/engine/selector.h
+++ b/engines/sci/engine/selector.h
@@ -218,7 +218,7 @@ void invokeSelector(EngineState *s, reg_t object, int selectorId,
* This function checks if index is in the right range, and sets the flag
* on obj.-info- if it is.
*/
-void updateInfoFlagViewVisible(Object *obj, int index);
+void updateInfoFlagViewVisible(Object *obj, int index, bool fromPropertyOp = false);
#endif
} // End of namespace Sci
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index ad6234b68e..1df3c601ee 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -1148,7 +1148,7 @@ void run_vm(EngineState *s) {
// Accumulator To Property
validate_property(s, obj, opparams[0]) = s->r_acc;
#ifdef ENABLE_SCI32
- updateInfoFlagViewVisible(obj, opparams[0]>>1);
+ updateInfoFlagViewVisible(obj, opparams[0], true);
#endif
break;
@@ -1161,7 +1161,7 @@ void run_vm(EngineState *s) {
// Stack To Property
validate_property(s, obj, opparams[0]) = POP32();
#ifdef ENABLE_SCI32
- updateInfoFlagViewVisible(obj, opparams[0]>>1);
+ updateInfoFlagViewVisible(obj, opparams[0], true);
#endif
break;
@@ -1178,7 +1178,7 @@ void run_vm(EngineState *s) {
else
opProperty -= 1;
#ifdef ENABLE_SCI32
- updateInfoFlagViewVisible(obj, opparams[0]>>1);
+ updateInfoFlagViewVisible(obj, opparams[0], true);
#endif
if (opcode == op_ipToa || opcode == op_dpToa)
s->r_acc = opProperty;