aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/cine/cine.h1
-rw-r--r--engines/cine/prc.cpp9
-rw-r--r--engines/cine/prc.h2
-rw-r--r--engines/cine/script_fw.cpp14
-rw-r--r--engines/cine/various.cpp14
5 files changed, 34 insertions, 6 deletions
diff --git a/engines/cine/cine.h b/engines/cine/cine.h
index 710840c17e..7568d8310e 100644
--- a/engines/cine/cine.h
+++ b/engines/cine/cine.h
@@ -107,6 +107,7 @@ private:
extern CineEngine *g_cine;
#define BOOT_PRC_NAME "AUTO00.PRC"
+#define COPY_PROT_FAIL_PRC_NAME "L201.ANI"
enum {
VAR_MOUSE_X_MODE = 253,
diff --git a/engines/cine/prc.cpp b/engines/cine/prc.cpp
index 402c97b1a6..27b1044620 100644
--- a/engines/cine/prc.cpp
+++ b/engines/cine/prc.cpp
@@ -40,8 +40,9 @@ ScriptList objectScripts;
/*! \todo Is script size of 0 valid?
* \todo Fix script dump code
+ * @return Was the loading successful?
*/
-void loadPrc(const char *pPrcName) {
+bool loadPrc(const char *pPrcName) {
byte i;
uint16 numScripts;
byte *scriptPtr, *dataPtr;
@@ -52,9 +53,9 @@ void loadPrc(const char *pPrcName) {
scriptTable.clear();
// This is copy protection. Used to hang the machine
- if (!scumm_stricmp(pPrcName, "L201.ANI")) {
+ if (!scumm_stricmp(pPrcName, COPY_PROT_FAIL_PRC_NAME)) {
exitEngine = 1;
- return;
+ return false;
}
checkDataDisk(-1);
@@ -107,6 +108,8 @@ void loadPrc(const char *pPrcName) {
}
}
#endif
+
+ return true;
}
} // End of namespace Cine
diff --git a/engines/cine/prc.h b/engines/cine/prc.h
index f5129d28b1..05bb240372 100644
--- a/engines/cine/prc.h
+++ b/engines/cine/prc.h
@@ -31,7 +31,7 @@ namespace Cine {
extern ScriptList globalScripts;
extern ScriptList objectScripts;
-void loadPrc(const char *pPrcName);
+bool loadPrc(const char *pPrcName);
} // End of namespace Cine
diff --git a/engines/cine/script_fw.cpp b/engines/cine/script_fw.cpp
index 148e673095..54a4976000 100644
--- a/engines/cine/script_fw.cpp
+++ b/engines/cine/script_fw.cpp
@@ -1019,6 +1019,20 @@ int FWScript::o1_divVar() {
}
int FWScript::o1_compareVar() {
+ // WORKAROUND: A workaround for a script bug in script file CODE2.PRC
+ // in at least some of the Amiga and Atari ST versions of Future Wars.
+ // Fixes bug #2016647 (FW: crash with italian amiga version). A local
+ // variable 251 is compared against value 0 although it's quite apparent
+ // from the context in the script that instead global variable 251 should
+ // be compared against value 0. So looks like someone made a typo when
+ // making the scripts. Therefore we change that particular comparison
+ // from using the local variable 251 to using the global variable 251.
+ if (g_cine->getGameType() == Cine::GType_FW && scumm_stricmp(currentPrcName, "CODE2.PRC") == 0 &&
+ (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) &&
+ _script.getByte(_pos) == 251 && _script.getByte(_pos + 1) == 0 && _script.getWord(_pos + 2) == 0) {
+ return o1_compareGlobalVar();
+ }
+
byte varIdx = getNextByte();
byte varType = getNextByte();
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index 4b5d4efe13..69851aeff2 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -1518,12 +1518,22 @@ void mainLoopSub6(void) {
void checkForPendingDataLoad(void) {
if (newPrcName[0] != 0) {
- loadPrc(newPrcName);
+ bool loadPrcOk = loadPrc(newPrcName);
strcpy(currentPrcName, newPrcName);
strcpy(newPrcName, "");
- addScriptToList0(1);
+ // Check that the loading of the script file was successful before
+ // trying to add script 1 from it to the global scripts list. This
+ // fixes a crash when failing copy protection in Amiga or Atari ST
+ // versions of Future Wars.
+ if (loadPrcOk) {
+ addScriptToList0(1);
+ } else if (scumm_stricmp(currentPrcName, COPY_PROT_FAIL_PRC_NAME)) {
+ // We only show an error here for other files than the file that
+ // is loaded if copy protection fails (i.e. L201.ANI).
+ warning("checkForPendingDataLoad: loadPrc(%s) failed", currentPrcName);
+ }
}
if (newRelName[0] != 0) {