aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorColin Snover2017-01-12 10:55:13 -0600
committerColin Snover2017-01-12 13:14:03 -0600
commit54e94c572aeb58e160537e2145c0fff44e862be3 (patch)
tree94cd9c1ddc9d0da233bfaf9b86f02a61c8483bb1 /engines/sci
parentd5f0d1fdb26caea8d734371a539be9ed5764a899 (diff)
downloadscummvm-rg350-54e94c572aeb58e160537e2145c0fff44e862be3.tar.gz
scummvm-rg350-54e94c572aeb58e160537e2145c0fff44e862be3.tar.bz2
scummvm-rg350-54e94c572aeb58e160537e2145c0fff44e862be3.zip
SCI32: Add workarounds, transitions, fixes for PQ4CD
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/kernel_tables.h8
-rw-r--r--engines/sci/engine/workarounds.cpp25
-rw-r--r--engines/sci/engine/workarounds.h3
-rw-r--r--engines/sci/graphics/paint32.cpp6
-rw-r--r--engines/sci/graphics/transitions32.cpp61
-rw-r--r--engines/sci/graphics/transitions32.h6
6 files changed, 95 insertions, 14 deletions
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index c611af4aee..ac4987e603 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -287,7 +287,7 @@ static const SciKernelMapSubEntry kPalVary_subops[] = {
{ SIG_SCI32, 6, MAP_CALL(PalVaryPauseResume), "i", NULL },
{ SIG_SCI32, 7, MAP_CALL(PalVarySetTarget), "i", NULL },
{ SIG_SCI32, 8, MAP_CALL(PalVarySetStart), "i", NULL },
- { SIG_SCI32, 9, MAP_CALL(PalVaryMergeStart), "i", NULL },
+ { SIG_SCI32, 9, MAP_CALL(PalVaryMergeStart), "i", kPalVaryMergeStart_workarounds },
#endif
SCI_SUBOPENTRY_TERMINATOR
};
@@ -512,7 +512,7 @@ static const SciKernelMapSubEntry kArray_subops[] = {
{ SIG_SCI32, 2, MAP_CALL(ArrayGetElement), "ri", NULL },
{ SIG_SCI32, 3, MAP_CALL(ArraySetElements), "ri(.*)", kArraySetElements_workarounds },
{ SIG_SCI32, 4, MAP_CALL(ArrayFree), "[0r]", NULL },
- { SIG_SCI32, 5, MAP_CALL(ArrayFill), "riii", NULL },
+ { SIG_SCI32, 5, MAP_CALL(ArrayFill), "riii", kArrayFill_workarounds },
{ SIG_SCI32, 6, MAP_CALL(ArrayCopy), "ririi", NULL },
// there is no subop 7
{ SIG_SCI32, 8, MAP_CALL(ArrayDuplicate), "r", NULL },
@@ -531,7 +531,7 @@ static const SciKernelMapSubEntry kString_subops[] = {
{ SIG_THRU_SCI21MID, 2, MAP_CALL(StringGetChar), "ri", NULL },
{ SIG_THRU_SCI21MID, 3, MAP_CALL(ArraySetElements), "ri(i*)", kArraySetElements_workarounds },
{ SIG_THRU_SCI21MID, 4, MAP_CALL(StringFree), "[0r]", NULL },
- { SIG_THRU_SCI21MID, 5, MAP_CALL(ArrayFill), "rii", NULL },
+ { SIG_THRU_SCI21MID, 5, MAP_CALL(ArrayFill), "rii", kArrayFill_workarounds },
{ SIG_THRU_SCI21MID, 6, MAP_CALL(ArrayCopy), "ririi", NULL },
{ SIG_SCI32, 7, MAP_CALL(StringCompare), "rr(i)", NULL },
@@ -860,7 +860,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(DeletePlane), SIG_EVERYWHERE, "o", NULL, NULL },
{ MAP_CALL(DeleteScreenItem), SIG_EVERYWHERE, "o", NULL, NULL },
{ "DisposeTextBitmap", kBitmapDestroy, SIG_SCI2, SIGFOR_ALL, "[r!]", NULL, NULL },
- { MAP_CALL(FrameOut), SIG_EVERYWHERE, "(i)", NULL, NULL },
+ { MAP_CALL(FrameOut), SIG_EVERYWHERE, "(i)", NULL, kFrameOut_workarounds },
{ MAP_CALL(GetHighPlanePri), SIG_EVERYWHERE, "", NULL, NULL },
{ MAP_CALL(InPolygon), SIG_EVERYWHERE, "iio", NULL, NULL },
{ MAP_CALL(IsHiRes), SIG_EVERYWHERE, "", NULL, NULL },
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 1201b9f029..560a383e24 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -352,6 +352,8 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_PEPPER, -1, 894, 0, "Package", "doVerb", NULL, 3, { WORKAROUND_FAKE, 0 } }, // using the hand on the book in the inventory - bug #5154
{ GID_PEPPER, 150, 928, 0, "Narrator", "startText", NULL, 0, { WORKAROUND_FAKE, 0 } }, // happens during the non-interactive demo of Pepper
{ GID_PQ4, -1, 25, 0, "iconToggle", "select", NULL, 1, { WORKAROUND_FAKE, 0 } }, // when toggling the icon bar to auto-hide or not
+ { GID_PQ4, 275, 64964, -1, "DPath", "init", NULL, 1, { WORKAROUND_FAKE, 0 } }, // when Sherry walks out of the morgue on day 3
+ { GID_PQ4, 240, 64964, -1, "DPath", "init", NULL, 1, { WORKAROUND_FAKE, 0 } }, // when encountering Sherry and the reporter outside the morgue at the end of day 3
{ GID_PQSWAT, -1, 64950, 0, NULL, "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Using any menus in-game
{ GID_PQSWAT, -1, 73, 0, "theLashInterface", "transmit", NULL, 0, { WORKAROUND_FAKE, 0 } }, // Clicking the transmit button in LASH
{ GID_PQSWAT, 2990, 2990, 0, "talkToSchienbly", "changeState", NULL, 1, { WORKAROUND_FAKE, 0 } }, // When the video of Schienbly talking for the first time ends
@@ -428,6 +430,12 @@ const SciWorkaroundEntry kArraySetElements_workarounds[] = {
};
// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
+const SciWorkaroundEntry kArrayFill_workarounds[] = {
+ { GID_PQ4, 540, 64918, 0, "Str", "callKernel", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when clicking on Hate Crimes in the computer on day 2
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kCelHigh_workarounds[] = {
{ GID_KQ5, -1, 255, 0, "deathIcon", "setSize", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // english floppy: when getting beaten up in the inn and probably more, called with 2nd parameter as object - bug #5049
{ GID_PQ2, -1, 255, 0, "DIcon", "setSize", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when showing picture within windows, called with 2nd/3rd parameters as objects
@@ -593,6 +601,17 @@ const SciWorkaroundEntry kFindKey_workarounds[] = {
SCI_WORKAROUNDENTRY_TERMINATOR
};
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
+const SciWorkaroundEntry kFrameOut_workarounds[] = {
+ { GID_PQ4, 360, 360, 0, "copCarInset", "init", NULL, 0, { WORKAROUND_STILLCALL, 1 } }, // When clicking hand on the impounded police car on day 3
+ { GID_PQ4, 360, 360, 0, "copCarInset", "dispose", NULL, 0, { WORKAROUND_STILLCALL, 1 } }, // When exiting the impounded police car on day 3
+ { GID_PQ4, 275, 275, 0, "checkSherry", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 1 } }, // When encountering Sherry and Sam in the morgue on day 3
+ { GID_PQ4, 725, 725, 0, "fridgeInset", "init", NULL, 0, { WORKAROUND_STILLCALL, 1 } }, // When opening the refrigerator at the end of day 4
+ { GID_PQ4, 725, 725, 0, "fridgeInset", "dispose", NULL, 0, { WORKAROUND_STILLCALL, 1 } }, // When exiting the refrigerator at the end of day 4
+ { GID_PQ4, 735, 735, 0, "medInset", "dispose", NULL, 0, { WORKAROUND_STILLCALL, 1 } }, // When exiting the medicine cabinet at the end of day 4
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kGraphDrawLine_workarounds[] = {
{ GID_ISLANDBRAIN, 300, 300, 0, "dudeViewer", "show", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // when looking at the gene explanation chart, gets called with 1 extra parameter
@@ -725,6 +744,12 @@ const SciWorkaroundEntry kPalVarySetPercent_workarounds[] = {
};
// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
+const SciWorkaroundEntry kPalVaryMergeStart_workarounds[] = {
+ { GID_PQ4, 170, 170, 0, "getHit", "changeState", NULL, 0, { WORKAROUND_STILLCALL, 0 } }, // Three extra parameters passed during the gunfight at the end of day 1
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// gameID, room,script,lvl, object-name, method-name, local-call-signature, index, workaround
const SciWorkaroundEntry kPlatform32_workarounds[] = {
{ GID_HOYLE5, -1, 0, 0, "hoyle4", "newRoom", NULL, 0, { WORKAROUND_FAKE, 1 } }, // at the start of the game, incorrectly uses SCI16 calling convention for kPlatform
SCI_WORKAROUNDENTRY_TERMINATOR
diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h
index 86b4ee2902..cb928faf09 100644
--- a/engines/sci/engine/workarounds.h
+++ b/engines/sci/engine/workarounds.h
@@ -72,6 +72,7 @@ extern const SciWorkaroundEntry kDoSoundPlay_workarounds[];
extern const SciWorkaroundEntry kDoSoundFade_workarounds[];
extern const SciWorkaroundEntry kFileIOOpen_workarounds[];
extern const SciWorkaroundEntry kFindKey_workarounds[];
+extern const SciWorkaroundEntry kFrameOut_workarounds[];
extern const SciWorkaroundEntry kDeleteKey_workarounds[];
extern const SciWorkaroundEntry kGetAngle_workarounds[];
extern const SciWorkaroundEntry kGraphDrawLine_workarounds[];
@@ -87,6 +88,7 @@ extern const SciWorkaroundEntry kMemory_workarounds[];
extern const SciWorkaroundEntry kMoveCursor_workarounds[];
extern const SciWorkaroundEntry kNewWindow_workarounds[];
extern const SciWorkaroundEntry kPalVarySetPercent_workarounds[];
+extern const SciWorkaroundEntry kPalVaryMergeStart_workarounds[];
extern const SciWorkaroundEntry kPlatform32_workarounds[];
extern const SciWorkaroundEntry kRandom_workarounds[];
extern const SciWorkaroundEntry kReadNumber_workarounds[];
@@ -94,6 +96,7 @@ extern const SciWorkaroundEntry kResCheck_workarounds[];
extern const SciWorkaroundEntry kPaletteUnsetFlag_workarounds[];
extern const SciWorkaroundEntry kSetCursor_workarounds[];
extern const SciWorkaroundEntry kArraySetElements_workarounds[];
+extern const SciWorkaroundEntry kArrayFill_workarounds[];
extern const SciWorkaroundEntry kSetPort_workarounds[];
extern const SciWorkaroundEntry kStrAt_workarounds[];
extern const SciWorkaroundEntry kStrCpy_workarounds[];
diff --git a/engines/sci/graphics/paint32.cpp b/engines/sci/graphics/paint32.cpp
index bf7c73623e..8a63365f03 100644
--- a/engines/sci/graphics/paint32.cpp
+++ b/engines/sci/graphics/paint32.cpp
@@ -121,7 +121,7 @@ void GfxPaint32::plotter(int x, int y, int color, void *data) {
reg_t GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, uint16 pattern, uint8 thickness, Common::Rect &outRect) {
const uint8 skipColor = color != kDefaultSkipColor ? kDefaultSkipColor : 0;
- // Line thickness is expected to be 2 * thickness + 1
+ // Line thickness is expected to be 2n + 1
thickness = (MAX<uint8>(1, thickness) - 1) | 1;
const uint8 halfThickness = thickness >> 1;
@@ -130,8 +130,8 @@ reg_t GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::
outRect.left = MIN<int16>(startPoint.x, endPoint.x);
outRect.top = MIN<int16>(startPoint.y, endPoint.y);
- outRect.right = MAX<int16>(startPoint.x, endPoint.x) + 1 + 1; // rect lower edge + thickness offset
- outRect.bottom = MAX<int16>(startPoint.y, endPoint.y) + 1 + 1; // rect lower edge + thickness offset
+ outRect.right = MAX<int16>(startPoint.x, endPoint.x) + 1;
+ outRect.bottom = MAX<int16>(startPoint.y, endPoint.y) + 1;
outRect.grow(halfThickness);
outRect.clip(Common::Rect(scriptWidth, scriptHeight));
diff --git a/engines/sci/graphics/transitions32.cpp b/engines/sci/graphics/transitions32.cpp
index a1ae352b6c..bc2825ba77 100644
--- a/engines/sci/graphics/transitions32.cpp
+++ b/engines/sci/graphics/transitions32.cpp
@@ -319,16 +319,20 @@ void GfxTransitions32::kernelSetShowStyle(const uint16 argc, const reg_t planeOb
if (createNewEntry) {
if (getSciVersion() <= SCI_VERSION_2_1_EARLY) {
switch (entry->type) {
+ case kShowStyleWipeLeft:
+ case kShowStyleWipeRight:
+ configure21EarlyHorizontalWipe(*entry, priority);
+ break;
case kShowStyleIrisOut:
case kShowStyleIrisIn:
configure21EarlyIris(*entry, priority);
- break;
+ break;
case kShowStyleDissolve:
configure21EarlyDissolve(*entry, priority, plane->_gameRect);
- break;
+ break;
default:
// do nothing
- break;
+ break;
}
}
@@ -377,6 +381,8 @@ ShowStyleList::iterator GfxTransitions32::deleteShowStyle(const ShowStyleList::i
g_sci->_gfxFrameout->deleteScreenItem(*showStyle->bitmapScreenItem);
}
break;
+ case kShowStyleWipeLeft:
+ case kShowStyleWipeRight:
case kShowStyleIrisOut:
case kShowStyleIrisIn:
if (getSciVersion() <= SCI_VERSION_2_1_EARLY) {
@@ -406,6 +412,33 @@ ShowStyleList::iterator GfxTransitions32::deleteShowStyle(const ShowStyleList::i
return _showStyles.erase(showStyle);
}
+void GfxTransitions32::configure21EarlyHorizontalWipe(PlaneShowStyle &showStyle, const int16 priority) {
+ showStyle.numEdges = 1;
+ const int divisions = showStyle.divisions;
+ showStyle.screenItems.reserve(divisions);
+
+ CelInfo32 celInfo;
+ celInfo.type = kCelTypeColor;
+ celInfo.color = showStyle.color;
+
+ for (int i = 0; i < divisions; ++i) {
+ Common::Rect rect;
+ rect.left = showStyle.width * i / divisions;
+ rect.top = 0;
+ rect.right = showStyle.width * (i + 1) / divisions;
+ rect.bottom = showStyle.height;
+ showStyle.screenItems.push_back(new ScreenItem(showStyle.plane, celInfo, rect));
+ showStyle.screenItems.back()->_priority = priority;
+ showStyle.screenItems.back()->_fixedPriority = true;
+ }
+
+ if (showStyle.fadeUp) {
+ for (int i = 0; i < divisions; ++i) {
+ g_sci->_gfxFrameout->addScreenItem(*showStyle.screenItems[i]);
+ }
+ }
+}
+
void GfxTransitions32::configure21EarlyIris(PlaneShowStyle &showStyle, const int16 priority) {
showStyle.numEdges = 4;
const int numScreenItems = showStyle.numEdges * showStyle.divisions;
@@ -506,13 +539,23 @@ bool GfxTransitions32::processShowStyle(PlaneShowStyle &showStyle, uint32 now) {
case kShowStyleHShutterIn:
case kShowStyleVShutterOut:
case kShowStyleVShutterIn:
- case kShowStyleWipeLeft:
- case kShowStyleWipeRight:
case kShowStyleWipeUp:
case kShowStyleWipeDown:
case kShowStyleDissolveNoMorph:
case kShowStyleMorph:
return processMorph(showStyle);
+ case kShowStyleWipeLeft:
+ if (getSciVersion() > SCI_VERSION_2_1_EARLY) {
+ return processMorph(showStyle);
+ } else {
+ return processWipe(-1, showStyle);
+ }
+ case kShowStyleWipeRight:
+ if (getSciVersion() > SCI_VERSION_2_1_EARLY) {
+ return processMorph(showStyle);
+ } else {
+ return processWipe(1, showStyle);
+ }
case kShowStyleDissolve:
if (getSciVersion() > SCI_VERSION_2_1_EARLY) {
return processMorph(showStyle);
@@ -608,11 +651,15 @@ void GfxTransitions32::processVShutterIn(PlaneShowStyle &showStyle) {
}
void GfxTransitions32::processWipeLeft(PlaneShowStyle &showStyle) {
- error("WipeLeft is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!");
+ if (getSciVersion() > SCI_VERSION_2_1_EARLY) {
+ error("WipeLeft is not known to be used by any SCI2.1mid+ game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!");
+ }
}
void GfxTransitions32::processWipeRight(PlaneShowStyle &showStyle) {
- error("WipeRight is not known to be used by any game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!");
+ if (getSciVersion() > SCI_VERSION_2_1_EARLY) {
+ error("WipeRight is not known to be used by any SCI2.1mid+ game. Please submit a bug report with details about the game you were playing and what you were doing that triggered this error. Thanks!");
+ }
}
void GfxTransitions32::processWipeUp(PlaneShowStyle &showStyle) {
diff --git a/engines/sci/graphics/transitions32.h b/engines/sci/graphics/transitions32.h
index 0c828a20f7..685012fada 100644
--- a/engines/sci/graphics/transitions32.h
+++ b/engines/sci/graphics/transitions32.h
@@ -331,6 +331,12 @@ private:
ShowStyleList::iterator deleteShowStyle(const ShowStyleList::iterator &showStyle);
/**
+ * Initializes the given PlaneShowStyle for a
+ * horizontal wipe effect for SCI2 to 2.1early.
+ */
+ void configure21EarlyHorizontalWipe(PlaneShowStyle &showStyle, const int16 priority);
+
+ /**
* Initializes the given PlaneShowStyle for an
* iris effect for SCI2 to 2.1early.
*/