diff options
author | Colin Snover | 2017-04-01 22:01:22 -0500 |
---|---|---|
committer | Colin Snover | 2017-04-23 13:07:25 -0500 |
commit | 3d4fb4ccb4f8bed013e6be9f9c677a071e84266d (patch) | |
tree | 21fba33cf1f41ef856c6386e181b09fad17066e0 /engines | |
parent | 1962b1bb6d495365110094f200d50cc4cb303b75 (diff) | |
download | scummvm-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.cpp | 24 | ||||
-rw-r--r-- | engines/sci/engine/object.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/selector.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/selector.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 6 |
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; |