diff options
author | Willem Jan Palenstijn | 2011-03-13 14:46:57 +0100 |
---|---|---|
committer | Willem Jan Palenstijn | 2011-03-13 14:48:38 +0100 |
commit | 5b820cee64f54a0c28772fb40256334a7206ea53 (patch) | |
tree | 1add53f302e877177716b483487a82b4b443fc40 /engines/sci/engine | |
parent | 40333617ee4a0fede7c8cdec81a025ccab06e9e3 (diff) | |
download | scummvm-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.cpp | 20 | ||||
-rw-r--r-- | engines/sci/engine/script_patches.cpp | 47 |
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; |