aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/metaengine.h1
-rw-r--r--engines/sci/engine/script.cpp2
-rw-r--r--engines/sci/engine/script_patches.cpp70
-rw-r--r--engines/sci/engine/workarounds.cpp5
-rw-r--r--engines/sci/graphics/animate.cpp26
-rw-r--r--engines/sci/graphics/animate.h1
-rw-r--r--engines/sci/graphics/view.cpp2
7 files changed, 96 insertions, 11 deletions
diff --git a/engines/metaengine.h b/engines/metaengine.h
index 7519feaaa4..964eee071c 100644
--- a/engines/metaengine.h
+++ b/engines/metaengine.h
@@ -231,6 +231,7 @@ private:
friend class Common::Singleton<SingletonBaseType>;
public:
+ GameDescriptor findGameOnePlugAtATime(const Common::String &gameName, const EnginePlugin **plugin = NULL) const;
GameDescriptor findGame(const Common::String &gameName, const EnginePlugin **plugin = NULL) const;
GameList detectGames(const Common::FSList &fslist) const;
const EnginePlugin::List &getPlugins() const;
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 3ba550adf9..4c940804b8 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -332,6 +332,8 @@ uint16 Script::validateExportFunc(int pubfunct) {
if (offset == 0) {
// Check if the game has a second export table (e.g. script 912 in Camelot)
// Fixes bug #3039785
+ if (g_sci->getGameId() == GID_ECOQUEST) // cheap fix in here for eco quest 1, [md5] plz look into this TODO FIXME
+ return offset;
const uint16 *secondExportTable = (const uint16 *)findBlock(SCI_OBJ_EXPORTS, 0);
if (secondExportTable) {
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index ef7b7dcb41..5fc93421cd 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -51,6 +51,70 @@ struct SciScriptSignature {
// - if not EOS, an adjust offset and the actual bytes
// - rinse and repeat
+// stayAndHelp::changeState (0) is called when ego swims to the left or right
+// boundaries of room 660. Normally a textbox is supposed to get on screen
+// but the call is wrong, so not only do we get an error message the script
+// is also hanging because the cue won't get sent out
+// This also happens in sierra sci - ffs. bug #3038387
+const byte ecoquest1SignatureStayAndHelp[] = {
+ 40,
+ 0x3f, 0x01, // link 01
+ 0x87, 0x01, // lap param[1]
+ 0x65, 0x14, // aTop state
+ 0x36, // push
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x31, 0x1c, // bnt [next state]
+ 0x76, // push0
+ 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off)
+ 0x38, 0x22, 0x01, // pushi 0122
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag global[0]
+ 0x4a, 0x06, // send 06 - ego::setMotion(0)
+ 0x39, 0x6e, // pushi 6e (selector init)
+ 0x39, 0x04, // pushi 04
+ 0x76, // push0
+ 0x76, // push0
+ 0x39, 0x17, // pushi 17
+ 0x7c, // pushSelf
+ 0x51, 0x82, // class EcoNarrator
+ 0x4a, 0x0c, // send 0c - EcoNarrator::init(0, 0, 23, self) (BADLY BROKEN!)
+ 0x33, // jmp [end]
+ 0
+};
+
+const uint16 ecoquest1PatchStayAndHelp[] = {
+ 0x87, 0x01, // lap param[1]
+ 0x65, 0x14, // aTop state
+ 0x36, // push
+ 0x2f, 0x22, // bt [next state] (this optimization saves 6 bytes)
+ 0x39, 0x00, // pushi 0 (wasting 1 byte here)
+ 0x45, 0x01, 0x00, // callb export1 from script 0 (switching control off)
+ 0x38, 0x22, 0x01, // pushi 0122
+ 0x78, // push1
+ 0x76, // push0
+ 0x81, 0x00, // lag global[0]
+ 0x4a, 0x06, // send 06 - ego::setMotion(0)
+ 0x39, 0x6e, // pushi 6e (selector init)
+ 0x39, 0x06, // pushi 06
+ 0x39, 0x02, // pushi 02 (additional 2 bytes)
+ 0x76, // push0
+ 0x76, // push0
+ 0x39, 0x17, // pushi 17
+ 0x7c, // pushSelf
+ 0x38, 0x80, 0x02, // pushi 280 (additional 3 bytes)
+ 0x51, 0x82, // class EcoNarrator
+ 0x4a, 0x10, // send 10 - EcoNarrator::init(2, 0, 0, 23, self, 640)
+ PATCH_END
+};
+
+// script, description, magic DWORD, adjust
+const SciScriptSignature ecoquest1Signatures[] = {
+ { 660, "CD: bad messagebox and freeze", PATCH_MAGICDWORD(0x38, 0x22, 0x01, 0x78), -17, ecoquest1SignatureStayAndHelp, ecoquest1PatchStayAndHelp },
+ { 0, NULL, 0, 0, NULL, NULL }
+};
// daySixBeignet::changeState (4) is called when the cop goes out and sets cycles to 220.
// this is not enough time to get to the door, so we patch that to 23 seconds
@@ -85,7 +149,7 @@ const byte gk1SignatureDay6PoliceSleep[] = {
0x35, 0x08, // ldi 08
0x1a, // eq?
0x31, // bnt [next state check]
- +1, 5, // [skip 1 byte, offset of bnt]
+ +1, 6, // [skip 1 byte, offset of bnt]
0x34, 0xdc, 0x00, // ldi 220
0x65, 0x1a, // aTop cycles
0x32, // jmp [end]
@@ -346,6 +410,8 @@ int32 Script::findSignature(const SciScriptSignature *signature, const byte *scr
void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uint32 scriptSize) {
const SciScriptSignature *signatureTable = NULL;
+ if (g_sci->getGameId() == GID_ECOQUEST)
+ signatureTable = ecoquest1Signatures;
if (g_sci->getGameId() == GID_GK1)
signatureTable = gk1Signatures;
// hoyle4 now works due workaround inside GfxPorts
@@ -362,7 +428,7 @@ void Script::matchSignatureAndPatch(uint16 scriptNr, byte *scriptData, const uin
int32 foundOffset = findSignature(signatureTable, scriptData, scriptSize);
if (foundOffset != -1) {
// found, so apply the patch
- warning("matched %s on script %d offset %d", signatureTable->description, scriptNr, foundOffset);
+ warning("matched and patched %s on script %d offset %d", signatureTable->description, scriptNr, foundOffset);
applyPatch(signatureTable->patch, scriptData, scriptSize, foundOffset);
}
}
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 4dc4ae93d8..013858dbcc 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -114,6 +114,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_JONES, 764, 255, 0, "", "export 0", -1, 14, { WORKAROUND_FAKE, 0 } }, // jones/ega&vga only - called when the game starts
{ GID_KQ5, -1, 0, 0, "", "export 29", -1, 3, { WORKAROUND_FAKE, 0 } }, // called when playing harp for the harpies or when aborting dialog in toy shop, is used for kDoAudio - bug #3034700
{ GID_KQ5, 25, 25, 0, "rm025", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // inside witch forest, when going to the room where the walking rock is
+ { GID_KQ5, 55, 55, 0, "helpScript", "doit", -1, 0, { WORKAROUND_FAKE, 0 } }, // when giving the tambourine to the monster in the labyrinth (only happens at one of the locations) - bug #3041262
{ GID_KQ6, -1, 30, 0, "rats", "changeState", -1, -1, { WORKAROUND_FAKE, 0 } }, // rats in the catacombs (temps 1 - 5) - bugs #3034597, #3035495, #3035824
{ GID_KQ6, 210, 210, 0, "rm210", "scriptCheck", -1, 0, { WORKAROUND_FAKE, 1 } }, // using inventory in that room - bug #3034565
{ GID_KQ6, 500, 500, 0, "rm500", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // going to island of the beast
@@ -124,8 +125,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_LAURABOW, -1, 967, 0, "myIcon", "cycle", -1, 1, { WORKAROUND_FAKE, 0 } }, // having any portrait conversation coming up (initial bug #3034985)
{ GID_LAURABOW2, -1, 24, 0, "gcWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu
{ GID_LAURABOW2, -1, 21, 0, "dropCluesCode", "doit", -1, 1, { WORKAROUND_FAKE, 0x7fff } }, // when asking some questions (e.g. the reporter about the burglary, or the policeman about Ziggy). Must be big, as the game scripts perform lt on it and start deleting journal entries - bugs #3035068, #3036274
- { GID_LAURABOW2, -1, 90, 0, "aTut", "init", -1, 6, { WORKAROUND_FAKE, 0 } }, // Random actors in museum (bug #3041257)
- { GID_LAURABOW2, -1, 90, 0, "aZiggy", "init", -1, 6, { WORKAROUND_FAKE, 0 } }, // Random actors in museum (bug #3041257)
+ { GID_LAURABOW2, -1, 90, 1, "MuseumActor", "init", -1, 6, { WORKAROUND_FAKE, 0 } }, // Random actors in museum (bug #3041257)
{ GID_LAURABOW2, 240, 240, 0, "sSteveAnimates", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // Steve Dorian's idle animation at the docks - bug #3036291
{ GID_LONGBOW, -1, 213, 0, "clear", "handleEvent", -1, 0, { WORKAROUND_FAKE, 0 } }, // When giving an answer using the druid hand sign code in any room
{ GID_LONGBOW, -1, 213, 0, "letter", "handleEvent", 0xa8, 1, { WORKAROUND_FAKE, 0 } }, // When using the druid hand sign code in any room - bug #3036601
@@ -155,6 +155,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_QFG3, 330, 330, -1, "Teller", "doChild", -1, -1, { WORKAROUND_FAKE, 0 } }, // when talking to King Rajah about "Rajah" (bug #3036390, temp 1) or "Tarna" (temp 0), or when clicking on yourself and saying "Greet" (bug #3039774, temp 1)
{ GID_QFG3, 700, 700, -1, "monsterIsDead", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // in the jungle, after winning any fight, bug #3040624
{ GID_QFG3, 470, 470, -1, "rm470", "notify", -1, 0, { WORKAROUND_FAKE, 0 } }, // closing the character screen in the Simbani village in the room with the bridge, bug #3040565
+ { GID_QFG3, 490, 490, -1, "computersMove", "changeState", -1, 0, { WORKAROUND_FAKE, 0 } }, // when finishing awari game, bug #3040579
{ GID_QFG4, -1, 15, -1, "charInitScreen", "dispatchEvent", -1, 5, { WORKAROUND_FAKE, 0 } }, // floppy version, when viewing the character screen
{ GID_QFG4, -1, 64917, -1, "controlPlane", "setBitmap", -1, 3, { WORKAROUND_FAKE, 0 } }, // floppy version, when entering the game menu
{ GID_QFG4, -1, 64917, -1, "Plane", "setBitmap", -1, 3, { WORKAROUND_FAKE, 0 } }, // floppy version, happen sometimes in fights
diff --git a/engines/sci/graphics/animate.cpp b/engines/sci/graphics/animate.cpp
index ab4362cda9..913b369790 100644
--- a/engines/sci/graphics/animate.cpp
+++ b/engines/sci/graphics/animate.cpp
@@ -243,6 +243,8 @@ void GfxAnimate::fill(byte &old_picNotValid) {
}
}
+ //warning("%s", _s->_segMan->getObjectName(curObject));
+
if (!view->isScaleable()) {
// Laura Bow 2 (especially floppy) depends on this, some views are not supposed to be scaleable
// this "feature" was removed in later versions of SCI1.1
@@ -516,6 +518,19 @@ void GfxAnimate::reAnimate(Common::Rect rect) {
}
}
+void GfxAnimate::preprocessAddToPicList() {
+ AnimateList::iterator it;
+ const AnimateList::iterator end = _list.end();
+
+ for (it = _list.begin(); it != end; ++it) {
+ if (it->priority == -1)
+ it->priority = _ports->kernelCoordinateToPriority(it->y);
+
+ // Do not allow priority to get changed by fill()
+ it->signal |= kSignalFixedPriority;
+ }
+}
+
void GfxAnimate::addToPicDrawCels() {
reg_t curObject;
GfxView *view = NULL;
@@ -525,17 +540,11 @@ void GfxAnimate::addToPicDrawCels() {
for (it = _list.begin(); it != end; ++it) {
curObject = it->object;
- if (it->priority == -1)
- it->priority = _ports->kernelCoordinateToPriority(it->y);
-
// Get the corresponding view
view = _cache->getView(it->viewId);
- // Create rect according to coordinates and given cel
- view->getCelRect(it->loopNo, it->celNo, it->x, it->y, it->z, it->celRect);
-
// draw corresponding cel
- _paint16->drawCel(it->viewId, it->loopNo, it->celNo, it->celRect, it->priority, it->paletteNo);
+ _paint16->drawCel(it->viewId, it->loopNo, it->celNo, it->celRect, it->priority, it->paletteNo, it->scaleX, it->scaleY);
if ((it->signal & kSignalIgnoreActor) == 0) {
it->celRect.top = CLIP<int16>(_ports->kernelPriorityToCoordinate(it->priority) - 1, it->celRect.top, it->celRect.bottom - 1);
_paint16->fillRect(it->celRect, GFX_SCREEN_MASK_CONTROL, 0, 0, 15);
@@ -679,6 +688,7 @@ void GfxAnimate::addToPicSetPicNotValid() {
void GfxAnimate::kernelAddToPicList(reg_t listReference, int argc, reg_t *argv) {
List *list;
+ byte tempPicNotValid = 0;
_ports->setPort((Port *)_ports->_picWind);
@@ -687,6 +697,8 @@ void GfxAnimate::kernelAddToPicList(reg_t listReference, int argc, reg_t *argv)
error("kAddToPic called with non-list as parameter");
makeSortedList(list);
+ preprocessAddToPicList();
+ fill(tempPicNotValid);
addToPicDrawCels();
addToPicSetPicNotValid();
diff --git a/engines/sci/graphics/animate.h b/engines/sci/graphics/animate.h
index 7e82187eed..c2101e5384 100644
--- a/engines/sci/graphics/animate.h
+++ b/engines/sci/graphics/animate.h
@@ -100,6 +100,7 @@ public:
void updateScreen(byte oldPicNotValid);
void restoreAndDelete(int argc, reg_t *argv);
void reAnimate(Common::Rect rect);
+ void preprocessAddToPicList();
void addToPicDrawCels();
void addToPicDrawView(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 leftPos, int16 topPos, int16 priority, int16 control);
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index 1c865f6bcf..5f48574dcb 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -256,6 +256,8 @@ void GfxView::initData(GuiResourceId resourceId) {
cel->scriptHeight = cel->height = READ_SCI11ENDIAN_UINT16(celData + 2);
cel->displaceX = READ_SCI11ENDIAN_UINT16(celData + 4);
cel->displaceY = READ_SCI11ENDIAN_UINT16(celData + 6);
+ if (cel->displaceY < 0)
+ cel->displaceY += 255; // sierra did this adjust in their sci1.1 getCelRect() - not sure about sci32
assert(cel->width && cel->height);