aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
authorWillem Jan Palenstijn2011-03-13 14:46:57 +0100
committerWillem Jan Palenstijn2011-03-13 14:48:38 +0100
commit5b820cee64f54a0c28772fb40256334a7206ea53 (patch)
tree1add53f302e877177716b483487a82b4b443fc40 /engines/sci/engine
parent40333617ee4a0fede7c8cdec81a025ccab06e9e3 (diff)
downloadscummvm-rg350-5b820cee64f54a0c28772fb40256334a7206ea53.tar.gz
scummvm-rg350-5b820cee64f54a0c28772fb40256334a7206ea53.tar.bz2
scummvm-rg350-5b820cee64f54a0c28772fb40256334a7206ea53.zip
SCI: Restore full object state after collision in DoBresen
This makes the workaround for the hang in the Colonel's Bequest shower scene (bug #3122075) unnecessary.
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/kmovement.cpp20
-rw-r--r--engines/sci/engine/script_patches.cpp47
2 files changed, 14 insertions, 53 deletions
diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp
index 392db56419..eb5a39a9a7 100644
--- a/engines/sci/engine/kmovement.cpp
+++ b/engines/sci/engine/kmovement.cpp
@@ -292,8 +292,6 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
mover_moveCnt = 0;
int16 client_x = readSelectorValue(segMan, client, SELECTOR(x));
int16 client_y = readSelectorValue(segMan, client, SELECTOR(y));
- int16 client_org_x = client_x;
- int16 client_org_y = client_y;
int16 mover_x = readSelectorValue(segMan, mover, SELECTOR(x));
int16 mover_y = readSelectorValue(segMan, mover, SELECTOR(y));
int16 mover_xAxis = readSelectorValue(segMan, mover, SELECTOR(b_xAxis));
@@ -312,7 +310,14 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
writeSelectorValue(segMan, mover, SELECTOR(xLast), client_x);
writeSelectorValue(segMan, mover, SELECTOR(yLast), client_y);
}
- // sierra sci saves full client selector variables here
+
+ // Store backups of all client selector variables. We will restore them
+ // in case of a collision.
+ Object* clientObject = segMan->getObject(client);
+ uint clientVarNum = clientObject->getVarCount();
+ reg_t* clientBackup = new reg_t[clientVarNum];
+ for (uint i = 0; i < clientVarNum; ++i)
+ clientBackup[i] = clientObject->getVariable(i);
if (mover_xAxis) {
if (ABS(mover_x - client_x) < ABS(mover_dx))
@@ -360,9 +365,10 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
}
if (collision) {
- // sierra restores full client variables here, seems that restoring x/y is enough
- writeSelectorValue(segMan, client, SELECTOR(x), client_org_x);
- writeSelectorValue(segMan, client, SELECTOR(y), client_org_y);
+ // We restore the backup of the client variables
+ for (uint i = 0; i < clientVarNum; ++i)
+ clientObject->getVariableRef(i) = clientBackup[i];
+
mover_i1 = mover_org_i1;
mover_i2 = mover_org_i2;
mover_di = mover_org_di;
@@ -370,6 +376,8 @@ reg_t kDoBresen(EngineState *s, int argc, reg_t *argv) {
uint16 client_signal = readSelectorValue(segMan, client, SELECTOR(signal));
writeSelectorValue(segMan, client, SELECTOR(signal), client_signal | kSignalHitObstacle);
}
+ delete[] clientBackup;
+
writeSelectorValue(segMan, mover, SELECTOR(b_i1), mover_i1);
writeSelectorValue(segMan, mover, SELECTOR(b_i2), mover_i2);
writeSelectorValue(segMan, mover, SELECTOR(b_di), mover_di);
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index d292c4a430..33e62b21ae 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -668,50 +668,6 @@ const SciScriptSignature larry6Signatures[] = {
};
// ===========================================================================
-// This is a heap patch, and it modifies the properties of an object, instead
-// of patching script code.
-// Prevent the murderer from getting stuck behind the door in Colonel's
-// Bequest, room 215. Fixes bug #3122075.
-// TODO/FIXME: Add a proper fix for this. There is a regression in this
-// scene with the new kInitBresen and kDoBresen functions (r52467). Using
-// just the "old" kInitBresen works. This hack is added for now because the
-// two functions are quite complex. The "old" versions were created based
-// on observations, and not on the interpreter itself, thus they have a lot
-// of differences in the way they behave and set variables to the mover object.
-// Since this is just a death scene where Laura is supposed to die anyway,
-// figuring out the exact cause of this is just not worth the effort.
-// Differences between the new and the old kInitBresen to the MoveTo object:
-// dy: 1 (new) - 2 (old)
-// b-i1: 20 (new) - 12 (old)
-// b-di: 65526 (new) - 65516 (old)
-// Performing the changes above to MoveTo (0017:033a) allows the killer to
-// move. Note that the actual issue might not be with kInitBresen/kDoBresen,
-// and there might be another underlying problem here.
-
-const byte laurabow1SignatureKillerPosition[] = {
- 12,
- 0x5f, 0x00, // y
- 0x00, 0x00, // x
- 0x00, 0x00, // z
- 0x00, 0x00, // heading
- 0x02, 0x00, // yStep
- 0x0f, 0x01, // view
- 0
-};
-
-const uint16 laurabow1PatchKillerPosition[] = {
- 0x5f, 0x00, // y (same)
- 0x06, 0x00, // x (changed to 6)
- PATCH_END
-};
-
-// script, description, magic DWORD, adjust
-const SciScriptSignature laurabow1Signatures[] = {
- { 215, "actor position for shower scene", 1, PATCH_MAGICDWORD(0x02, 0x00, 0x0f, 0x01), -8, laurabow1SignatureKillerPosition, laurabow1PatchKillerPosition },
- SCI_SIGNATUREENTRY_TERMINATOR
-};
-
-// ===========================================================================
// rm560::doit was supposed to close the painting, when Heimlich enters the
// room. The code is buggy, so it actually closes the painting, when heimlich
// is not in the room. We fix that.
@@ -1151,9 +1107,6 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
case GID_KQ6:
signatureTable = kq6Signatures;
break;
- case GID_LAURABOW:
- signatureTable = laurabow1Signatures;
- break;
case GID_LAURABOW2:
signatureTable = laurabow2Signatures;
break;