aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorMatthew Hoops2010-07-30 18:45:28 +0000
committerMatthew Hoops2010-07-30 18:45:28 +0000
commit75b5ac38fbd2c75fab5d0f794a44ec906ee48c05 (patch)
treec80ad547057eb5d7ff7251073ae8bc50058b56f6 /engines/sci
parent839ba339ed58d66b7cb6f1fd69b0a85294f6f51f (diff)
downloadscummvm-rg350-75b5ac38fbd2c75fab5d0f794a44ec906ee48c05.tar.gz
scummvm-rg350-75b5ac38fbd2c75fab5d0f794a44ec906ee48c05.tar.bz2
scummvm-rg350-75b5ac38fbd2c75fab5d0f794a44ec906ee48c05.zip
SCI: Fix saving/restoring games in fan games
The SCI Studio function library incorrectly calls kDeviceInfo with one parameter to get the current device. svn-id: r51514
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/kernel_tables.h2
-rw-r--r--engines/sci/engine/kfile.cpp8
-rw-r--r--engines/sci/engine/workarounds.cpp13
-rw-r--r--engines/sci/engine/workarounds.h1
4 files changed, 23 insertions, 1 deletions
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 9652d4c25c..7a377258f7 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -319,7 +319,7 @@ static SciKernelMapEntry s_kernelMap[] = {
{ MAP_CALL(CoordPri), SIG_EVERYWHERE, "i(i)", NULL, NULL },
{ MAP_CALL(CosDiv), SIG_EVERYWHERE, "ii", NULL, NULL },
{ MAP_CALL(DeleteKey), SIG_EVERYWHERE, "l.", NULL, NULL },
- { MAP_CALL(DeviceInfo), SIG_EVERYWHERE, "i(r)(r)(i)", NULL, NULL }, // subop
+ { MAP_CALL(DeviceInfo), SIG_EVERYWHERE, "i(r)(r)(i)", NULL, kDeviceInfo_workarounds }, // subop
{ MAP_CALL(Display), SIG_EVERYWHERE, "[ir]([ir!]*)", NULL, NULL },
// ^ we allow invalid references here, because kDisplay gets called with those in e.g. pq3 during intro
// restoreBits() checks and skips invalid handles, so that's fine. Sierra SCI behaved the same
diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index d4ba467b25..4f0ad12285 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -282,6 +282,14 @@ enum {
};
reg_t kDeviceInfo(EngineState *s, int argc, reg_t *argv) {
+ if (g_sci->getGameId() == GID_FANMADE && argc == 1) {
+ // WORKAROUND: The fan game script library calls kDeviceInfo with one parameter.
+ // According to the scripts, it wants to call CurDevice. However, it fails to
+ // provide the subop to the function.
+ s->_segMan->strcpy(argv[0], "/");
+ return s->r_acc;
+ }
+
int mode = argv[0].toUint16();
switch (mode) {
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index fa1f3d7eca..e2d63b9d7c 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -139,6 +139,19 @@ const SciWorkaroundEntry kCelWide_workarounds[] = {
};
// gameID, room,script,lvl, object-name, method-name, call,index, workaround
+const SciWorkaroundEntry kDeviceInfo_workarounds[] = {
+ { GID_FANMADE, -1, 994, 1, "Game", "save", 0xd1c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Cascade Quest)
+ { GID_FANMADE, -1, 994, 1, "Game", "save", 0xe55, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Demo Quest)
+ { GID_FANMADE, -1, 994, 1, "Game", "save", 0xe57, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (I Want My C64 Back)
+ { GID_FANMADE, -1, 994, 1, "Game", "save", 0xe5c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Most of them)
+ { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xd1c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Cascade Quest)
+ { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xe55, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Demo Quest)
+ { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xe57, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (I Want My C64 Back)
+ { GID_FANMADE, -1, 994, 1, "Game", "restore", 0xe5c, 0, { WORKAROUND_STILLCALL, 0 } }, // In fanmade games, this is called with one parameter for CurDevice (Most of them)
+ SCI_WORKAROUNDENTRY_TERMINATOR
+};
+
+// gameID, room,script,lvl, object-name, method-name, call,index, workaround
const SciWorkaroundEntry kDisplay_workarounds[] = {
{ GID_ISLANDBRAIN, 300, 300, 0, "geneDude", "show", -1, 0, { WORKAROUND_IGNORE, 0 } }, // when looking at the gene explanation chart - a parameter is an object
{ GID_SQ4, 391, 391, 0, "doCatalog", "mode", 0x84, 0, { WORKAROUND_IGNORE, 0 } }, // clicking on catalog in roboter sale - a parameter is an object
diff --git a/engines/sci/engine/workarounds.h b/engines/sci/engine/workarounds.h
index 6fa08b8a69..acb0c22e6c 100644
--- a/engines/sci/engine/workarounds.h
+++ b/engines/sci/engine/workarounds.h
@@ -75,6 +75,7 @@ extern const SciWorkaroundEntry uninitializedReadWorkarounds[];
extern const SciWorkaroundEntry kAbs_workarounds[];
extern const SciWorkaroundEntry kCelHigh_workarounds[];
extern const SciWorkaroundEntry kCelWide_workarounds[];
+extern const SciWorkaroundEntry kDeviceInfo_workarounds[];
extern const SciWorkaroundEntry kDisplay_workarounds[];
extern const SciWorkaroundEntry kDisposeScript_workarounds[];
extern const SciWorkaroundEntry kDoSoundFade_workarounds[];