[Scummvm-git-logs] scummvm master -> 1c801b4c24891a1f86e82cd9ee0121596bb543ed
sdelamarre
noreply at scummvm.org
Sat Apr 22 22:58:06 UTC 2023
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
1c801b4c24 GOB: workaround for an infinite loop in Adibou2 flower garden activity
Commit: 1c801b4c24891a1f86e82cd9ee0121596bb543ed
https://github.com/scummvm/scummvm/commit/1c801b4c24891a1f86e82cd9ee0121596bb543ed
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2023-04-23T00:57:57+02:00
Commit Message:
GOB: workaround for an infinite loop in Adibou2 flower garden activity
Changed paths:
engines/gob/detection/detection.h
engines/gob/detection/tables_adibou2.h
engines/gob/gob.h
engines/gob/inter_v1.cpp
engines/gob/metaengine.cpp
engines/gob/script.cpp
engines/gob/script.h
diff --git a/engines/gob/detection/detection.h b/engines/gob/detection/detection.h
index 0fe31bac945..81981b990b8 100644
--- a/engines/gob/detection/detection.h
+++ b/engines/gob/detection/detection.h
@@ -70,7 +70,8 @@ enum Features {
};
enum AdditionalGameFlags {
- GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND = 1 << 0
+ GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND = 1 << 0,
+ GF_ENABLE_ADIBOU2_FLOWERS_INFINITE_LOOP_WORKAROUND = 1 << 1,
};
struct GOBGameDescription {
diff --git a/engines/gob/detection/tables_adibou2.h b/engines/gob/detection/tables_adibou2.h
index e6c691f6339..98154eb0fcb 100644
--- a/engines/gob/detection/tables_adibou2.h
+++ b/engines/gob/detection/tables_adibou2.h
@@ -75,7 +75,7 @@
AD_ENTRY1s("intro.stk", "f2b797819aeedee557e904b0b5ccd82e", 8736454),
FR_FRA,
kPlatformWindows,
- GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND,
+ GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND | GF_ENABLE_ADIBOU2_FLOWERS_INFINITE_LOOP_WORKAROUND,
GUIO0()
},
kGameTypeAdibou2,
@@ -89,7 +89,7 @@
AD_ENTRY1s("intro.stk", "7b1f1f6f6477f54401e95d913f75e333", 8736904),
FR_FRA,
kPlatformWindows,
- GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND,
+ GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND | GF_ENABLE_ADIBOU2_FLOWERS_INFINITE_LOOP_WORKAROUND,
GUIO0()
},
kGameTypeAdibou2,
@@ -103,7 +103,7 @@
AD_ENTRY1s("intro.stk", "1e49c39a4a3ce6032a84b712539c2d63", 8738134),
FR_FRA,
kPlatformWindows,
- GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND,
+ GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND | GF_ENABLE_ADIBOU2_FLOWERS_INFINITE_LOOP_WORKAROUND,
GUIO0()
},
kGameTypeAdibou2,
@@ -117,7 +117,7 @@
AD_ENTRY1s("intro.stk", "092707829555f27706920e4cacf1fada", 8737958),
FR_FRA,
kPlatformWindows,
- GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND,
+ GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND | GF_ENABLE_ADIBOU2_FLOWERS_INFINITE_LOOP_WORKAROUND,
GUIO0()
},
kGameTypeAdibou2,
@@ -178,7 +178,7 @@
AD_ENTRY1s("intro.stk", "718a51862406136c28639489a9ba950a", 956350),
DE_DEU,
kPlatformWindows,
- ADGF_NO_FLAGS,
+ GF_ENABLE_ADIBOU2_FLOWERS_INFINITE_LOOP_WORKAROUND,
GUIO0()
},
kGameTypeAdibou2,
@@ -210,7 +210,7 @@
AD_ENTRY1s("intro.stk", "0b996fcd8929245fecddc4d9169843d0", 956682),
ES_ESP,
kPlatformWindows,
- ADGF_NO_FLAGS,
+ GF_ENABLE_ADIBOU2_FLOWERS_INFINITE_LOOP_WORKAROUND,
GUIO0()
},
kGameTypeAdibou2,
@@ -226,7 +226,7 @@
AD_ENTRY1s("intro.stk", "718a51862406136c28639489a9ba950a", 956350),
EN_ANY,
kPlatformWindows,
- ADGF_NO_FLAGS,
+ GF_ENABLE_ADIBOU2_FLOWERS_INFINITE_LOOP_WORKAROUND,
GUIO0()},
kGameTypeAdibou2,
kFeatures640x480,
diff --git a/engines/gob/gob.h b/engines/gob/gob.h
index e05eb22a56f..3244ce14f1c 100644
--- a/engines/gob/gob.h
+++ b/engines/gob/gob.h
@@ -169,6 +169,7 @@ public:
bool _resourceSizeWorkaround;
bool _enableAdibou2FreeBananasWorkaround;
+ bool _enableAdibou2FlowersInfiniteLoopWorkaround;
Global *_global;
Util *_util;
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 370c71fbea4..fb312b66637 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -854,6 +854,29 @@ void Inter_v1::o1_if(OpFuncParams ¶ms) {
WRITE_VAR(285, 0);
}
+ if (_vm->getGameType() == kGameTypeAdibou2 &&
+ _vm->_enableAdibou2FlowersInfiniteLoopWorkaround &&
+ _vm->isCurrentTot("FLORAL.tot") &&
+ (_vm->_game->_script->pos() == 30743 ||
+ _vm->_game->_script->pos() == 31074 ||
+ _vm->_game->_script->pos() == 31109) &&
+ _vm->_game->_script->peekByte() == 15 && // "offset from an array"
+ _vm->_game->_script->peekByte(7) == OP_LOAD_VAR_INT32 &&
+ _vm->_game->_script->peekByte(11) == 97 && // end of "offset from an array"
+ _vm->_game->_script->peekByte(12) == OP_LOAD_VAR_INT32 &&
+ _vm->_game->_script->peekByte(13) == 2 && // offset of the flower state in the flower struct
+ _vm->_game->_script->peekByte(15) == OP_GREATER) {
+ // WORKAROUND an infinite loop in Adibou2 "Flower Garden" activity.
+ // At most 30 flowers can exist at the same time. When the max is reached,
+ // the script iterates over the possible spots until it finds one that is
+ // occupied by a flower (status >= 1) and removes it. But it wrongly checks
+ // for strict inequality ("status > 1") instead of "status >= 1", so if all
+ // flowers happen to be at status 1 (meaning they have not grown at all yet),
+ // the script loops forever.
+ // We fix this by changing the comparison operator to ">=".
+ _vm->_game->_script->writeByte(15, OP_GEQ);
+ }
+
int pos = _vm->_game->_script->pos();
boolRes = _vm->_game->_script->evalBool();
diff --git a/engines/gob/metaengine.cpp b/engines/gob/metaengine.cpp
index f3531b049cb..ebfecbd380e 100644
--- a/engines/gob/metaengine.cpp
+++ b/engines/gob/metaengine.cpp
@@ -81,6 +81,7 @@ void GobEngine::initGame(const GOBGameDescription *gd) {
_platform = gd->desc.platform;
_enableAdibou2FreeBananasWorkaround = gd->desc.flags & GF_ENABLE_ADIBOU2_FREE_BANANAS_WORKAROUND;
+ _enableAdibou2FlowersInfiniteLoopWorkaround = gd->desc.flags & GF_ENABLE_ADIBOU2_FLOWERS_INFINITE_LOOP_WORKAROUND;
}
} // End of namespace Gob
diff --git a/engines/gob/script.cpp b/engines/gob/script.cpp
index 6edd60f8ca0..25a634e0505 100644
--- a/engines/gob/script.cpp
+++ b/engines/gob/script.cpp
@@ -261,6 +261,10 @@ char *Script::peekString(int32 offset) {
return (char *)(_totPtr + offset);
}
+void Script::writeByte(int32 offset, byte v) {
+ _totPtr[offset] = v;
+}
+
uint16 Script::readVarIndex(uint16 *size, uint16 *type) {
return _expression->parseVarIndex(size, type);
}
diff --git a/engines/gob/script.h b/engines/gob/script.h
index 04954547efb..714ba5ca25d 100644
--- a/engines/gob/script.h
+++ b/engines/gob/script.h
@@ -118,6 +118,9 @@ public:
/** Push the current script position and branch to the specified offset. */
void call(uint32 offset);
+ /** Override a byte into the loaded script data (used for some script bugs workarounds) */
+ void writeByte(int32 offset, byte v);
+
// Fixed properties
uint8 getVersionMajor () const;
uint8 getVersionMinor () const;
More information about the Scummvm-git-logs
mailing list