[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 &params) {
 		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