From 2035e21667b746c346e9f95658109904a86597d3 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Mon, 26 Sep 2016 10:33:52 -0500 Subject: SCI32: Add workaround for kNumCels This workaround may be able to be vastly simplified in the future since, so far, simply returning the number of cels in loop 0 is enough to make all the scripts with this bug work as expected. --- engines/sci/engine/workarounds.cpp | 13 +++++++++++++ engines/sci/engine/workarounds.h | 1 + engines/sci/graphics/celobj32.cpp | 15 +++++++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index 85a7966baa..8012b5bffa 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -682,6 +682,19 @@ const SciWorkaroundEntry kNewWindow_workarounds[] = { SCI_WORKAROUNDENTRY_TERMINATOR }; +// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround +const SciWorkaroundEntry kNumCels_workarounds[] = { + { GID_GK1, 808, 64998, -1, "sDJEnters", "changeState", NULL, -1, { WORKAROUND_FAKE, 6 } }, // + { GID_GK2, 470, 64998, -1, "pLookieLoos", "lastCel", NULL, -1, { WORKAROUND_FAKE, 50 } }, // random background movement in the crime scene in Munich city centre + { GID_GK2, 470, 64998, -1, "pNewsCrew", "lastCel", NULL, -1, { WORKAROUND_FAKE, 18 } }, // random background movement in the crime scene in Munich city centre + { GID_GK2, 470, 64998, -1, "pLeberGroup", "lastCel", NULL, -1, { WORKAROUND_FAKE, 22 } }, // random background movement in the crime scene in Munich city centre + { GID_SQ6, 270, 64998, -1, "offWorld", "lastCel", NULL, -1, { WORKAROUND_FAKE, 3 } }, // when exiting the kidnapping room + { GID_SQ6, 320, 64998, -1, "wandererB", "lastCel", NULL, -1, { WORKAROUND_FAKE, 8 } }, // random background movement on Polysorbate LX street 3 + { GID_SQ6, 340, 64998, -1, "wandererB", "lastCel", NULL, -1, { WORKAROUND_FAKE, 8 } }, // random background movement on Polysorbate LX street 1 + { GID_SQ6, 530, 64998, -1, "monitors", "lastCel", NULL, -1, { WORKAROUND_FAKE, 5 } }, // random background movement during cutscene + SCI_WORKAROUNDENTRY_TERMINATOR +}; + // gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround const SciWorkaroundEntry kPalVarySetPercent_workarounds[] = { { GID_GK1, 370, 370, 0, "graceComeOut", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // there's an extra parameter in GK1, when changing chapters. This extra parameter seems to be a bug or just unimplemented functionality, as there's no visible change from the original in the chapter change room diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h index a272baecd9..d1e985dcf1 100644 --- a/engines/sci/engine/workarounds.h +++ b/engines/sci/engine/workarounds.h @@ -85,6 +85,7 @@ extern const SciWorkaroundEntry kIsObject_workarounds[]; extern const SciWorkaroundEntry kMemory_workarounds[]; extern const SciWorkaroundEntry kMoveCursor_workarounds[]; extern const SciWorkaroundEntry kNewWindow_workarounds[]; +extern const SciWorkaroundEntry kNumCels_workarounds[]; extern const SciWorkaroundEntry kPalVarySetPercent_workarounds[]; extern const SciWorkaroundEntry kRandom_workarounds[]; extern const SciWorkaroundEntry kReadNumber_workarounds[]; diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp index 5d2d5dd6a6..e5149246e4 100644 --- a/engines/sci/graphics/celobj32.cpp +++ b/engines/sci/graphics/celobj32.cpp @@ -28,6 +28,7 @@ #include "sci/graphics/palette32.h" #include "sci/graphics/remap32.h" #include "sci/graphics/text32.h" +#include "sci/engine/workarounds.h" namespace Sci { #pragma mark CelScaler @@ -819,8 +820,18 @@ int16 CelObjView::getNumCels(const GuiResourceId viewId, const int16 loopNo) { // explicitly trap the bad condition here and report it so that any other // game scripts relying on this broken behavior can be fixed as well if (loopNo == loopCount) { - const SciCallOrigin origin = g_sci->getEngineState()->getCurrentCallOrigin(); - error("[CelObjView::getNumCels]: loop number is equal to loop count in method %s::%s (room %d, script %d, localCall %x)", origin.objectName.c_str(), origin.methodName.c_str(), origin.roomNr, origin.scriptNr, origin.localCallOffset); + SciCallOrigin origin; + SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kNumCels_workarounds, &origin); + switch (solution.type) { + case WORKAROUND_NONE: + error("[CelObjView::getNumCels]: loop number is equal to loop count in method %s::%s (room %d, script %d, localCall %x)", origin.objectName.c_str(), origin.methodName.c_str(), origin.roomNr, origin.scriptNr, origin.localCallOffset); + case WORKAROUND_FAKE: + return (int16)solution.value; + case WORKAROUND_IGNORE: + return 0; + case WORKAROUND_STILLCALL: + break; + } } if (loopNo > loopCount || loopNo < 0) { -- cgit v1.2.3