[Scummvm-git-logs] scummvm master -> 5dd11f4604b9008149b9a74b2807dc9fd9cb62ef

sdelamarre noreply at scummvm.org
Fri Apr 24 21:45:24 UTC 2026


This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
0c2b049036 GOB: Workaround for lost "mouse up" events after o1_setMousePos in Adi4
320a85a7a9 GOB: Fix frame synchronization of some videos in Adi4
88c01006a3 GOB: More fixes in drawButton (Adi4)
ff4cf86112 GOB: Fix multi-lines buttons (Adi4)
d6e5d71dcd GOB: Fix a delayed blit when a sound-only video is playing (Adi4)
5dd11f4604 GOB: Fix a missing temporary sprite save handler for Adi4


Commit: 0c2b049036355bd717185d793bb1eac19f6540ed
    https://github.com/scummvm/scummvm/commit/0c2b049036355bd717185d793bb1eac19f6540ed
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2026-04-24T23:07:02+02:00

Commit Message:
GOB: Workaround for lost "mouse up" events after o1_setMousePos in Adi4

Setting the mouse position through opcode o1_setMousePos calls
g_system->warpMouse(), which calls purgeMouseEvents(), which will eat
any pending "mouse up" event. This lead to a lock in Adi4 "cereal farm"
simulation activity, where the script is waiting for a mouse up event
that gets intercepted by the purge, if the click was fast enough.

Consider removing util.cpp's _mouseButtons state, to use only
EventManager's buttonState, which is protected against purgeMouseEvents();
That way, no sync would be needed at all.

Changed paths:
    engines/gob/inter_v1.cpp
    engines/gob/util.cpp
    engines/gob/util.h


diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 18936403f40..dbd9a180f4f 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -1889,9 +1889,18 @@ void Inter_v1::o1_setMousePos(OpFuncParams &params) {
 	_vm->_draw->adjustCoords(0, &_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY);
 	_vm->_global->_inter_mouseX -= _vm->_video->_scrollOffsetX;
 	_vm->_global->_inter_mouseY -= _vm->_video->_scrollOffsetY;
-	if (_vm->_global->_useMouse != 0)
+	if (_vm->_global->_useMouse != 0) {
 		_vm->_util->setMousePos(_vm->_global->_inter_mouseX,
 				_vm->_global->_inter_mouseY);
+		if (_vm->getGameType() == kGameTypeAdi4) {
+			// WORKAROUND: setMousePos() calls g_system->warpMouse() which calls purgeMouseEvents(),
+			// which will eat any pending mouse up event. This lead to a lock in Adi4 "cereal farm"
+			// simulation activity, where the script is waiting for a mouse up event that gets intercepted
+			// by the purge, if the click was fast enough.
+			// Force syncing with the EventManager's mouse state to recover from this as a workaround.
+			_vm->_util->forceMouseButtonsSync();
+		}
+	}
 }
 
 void Inter_v1::o1_setFrameRate(OpFuncParams &params) {
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index a522acbbe7b..4282bc50b9d 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -421,6 +421,20 @@ void Util::forceMouseUp(bool onlyWhenSynced) {
 	_mouseButtons             = kMouseButtonsNone;
 }
 
+// TODO: Consider removing _mouseButtons to use only EventManager's buttonState, making this sync unnecessary.
+void Util::forceMouseButtonsSync() {
+	int backendButtonState = g_system->getEventManager()->getButtonState();
+
+	_mouseButtons = kMouseButtonsNone;
+	if (backendButtonState & Common::EventManager::LBUTTON)
+		_mouseButtons = (MouseButtons) (((uint32) _mouseButtons) | ((uint32) kMouseButtonsLeft));
+
+	if (backendButtonState & Common::EventManager::RBUTTON)
+		_mouseButtons = (MouseButtons) (((uint32) _mouseButtons) | ((uint32) kMouseButtonsRight));
+
+	_vm->_game->_mouseButtons = _mouseButtons;
+}
+
 void Util::clearPalette() {
 	int16 i;
 	byte colors[768];
diff --git a/engines/gob/util.h b/engines/gob/util.h
index f95ba5f238b..c24755229b8 100644
--- a/engines/gob/util.h
+++ b/engines/gob/util.h
@@ -124,6 +124,7 @@ public:
 	void waitMouseDown();
 	void waitMouseRelease(char drawMouse);
 	void forceMouseUp(bool onlyWhenSynced = false);
+	void forceMouseButtonsSync();
 
 	void clearPalette();
 	int16 getFrameRate();


Commit: 320a85a7a9f3f6538bebbec11b640e03c2c3b9c1
    https://github.com/scummvm/scummvm/commit/320a85a7a9f3f6538bebbec11b640e03c2c3b9c1
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2026-04-24T23:07:03+02:00

Commit Message:
GOB: Fix frame synchronization of some videos in Adi4

The synchronization in playFrame was wrongly disabled for non-live
videos.

Fix a glitch when the wheat bags appears/disappear on the balance in
the "cereal farm" simulation in Adi4.

Changed paths:
    engines/gob/videoplayer.cpp


diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index 01b75bad8d0..98fc093c74b 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -490,8 +490,7 @@ bool VideoPlayer::play(int slot, Properties &properties) {
 
 		bool playFrameResult = playFrame(slot, properties);
 		if ((_vm->getGameType() == kGameTypeAdibou2 || _vm->getGameType() == kGameTypeAdi4) &&
-				!playFrameResult &&
-				slot < kLiveVideoSlotCount) {
+				!playFrameResult) {
 			_vm->_util->processInput();
 			_vm->_video->retrace();
 			_vm->_util->delay(5);


Commit: 88c01006a3224749a068a46f3485ebb0c84015c0
    https://github.com/scummvm/scummvm/commit/88c01006a3224749a068a46f3485ebb0c84015c0
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2026-04-24T23:07:03+02:00

Commit Message:
GOB: More fixes in drawButton (Adi4)

Fix a bug in "Adi4 Français CE2", "News item" exercise, where label where
displayed outside its button.

Changed paths:
    engines/gob/draw.cpp


diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index 8a39de94b4e..797183635f3 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -567,8 +567,8 @@ void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 botto
 				str2++;
 				str2 = strchr(str2, '\\');
 			} while (str2);
-			deltaY = (bottom - right + 1 - (strLen * _fonts[fontIndex]->getCharHeight())) / (strLen + 1);
-			offY = right + deltaY;
+			deltaY = (bottom - top + 1 - (strLen * _fonts[fontIndex]->getCharHeight())) / (strLen + 1);
+			offY = top + deltaY;
 			for (int i = 0; paramStr[i]; i++) {
 				int j = 0;
 				while (paramStr[i] && paramStr[i] != 92)
@@ -579,7 +579,7 @@ void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 botto
 				_textToPrint = str;
 				width = stringLength(str, fontIndex);
 				adjustCoords(1, &width, nullptr);
-				_destSpriteX += (top - left + 1 - width) / 2;
+				_destSpriteX += (right - left + 1 - width) / 2;
 				spriteOperation(DRAW_PRINTTEXT);
 				offY += deltaY + _fonts[fontIndex]->getCharHeight();
 			}


Commit: ff4cf86112435ca8ec14ce906099d189385c12a4
    https://github.com/scummvm/scummvm/commit/ff4cf86112435ca8ec14ce906099d189385c12a4
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2026-04-24T23:07:03+02:00

Commit Message:
GOB: Fix multi-lines buttons (Adi4)

Fix garbage text displayed on a third line after two-lines buttons,
in "Adi4 Français CE2", "News item" exercise.

Changed paths:
    engines/gob/draw.cpp


diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index 797183635f3..88110039486 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -535,7 +535,7 @@ void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 botto
 				WRITE_VAR(24, (uint32) 0);
 			WRITE_VAR(25, (uint32) shortId);
 			if (_hotspotText)
-				Common::strlcpy(_hotspotText, paramStr, 40);
+				Common::strlcpy(_hotspotText, paramStr, _vm->_global->_inter_animDataSize * 4);
 		}
 		_vm->_inter->funcBlock(0);
 		_vm->_game->_script->pop();
@@ -544,7 +544,7 @@ void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 botto
 	Common::strcpy_s(paramStr, 200, tmpStr);
 
 	if (fontIndex >= kFontCount) {
-		warning("Draw::oPlaytoons_sub_F_1B(): Font %d > Count %d", fontIndex, kFontCount);
+		warning("Draw::drawButton(): Font %d > Count %d", fontIndex, kFontCount);
 		return;
 	}
 
@@ -556,24 +556,26 @@ void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 botto
 		_fontIndex = fontIndex;
 		_frontColor = color;
 		if (_vm->_game->_script->getVersionMinor() >= 4 && strchr(paramStr, '\\')) {
+			// Multi-lines button
 			char str[80];
 			char *str2;
-			int16 strLen= 0;
+			int16 nbrOfLines = 0;
 			int16 offY, deltaY;
 
 			str2 = paramStr;
 			do {
-				strLen++;
+				nbrOfLines++;
 				str2++;
 				str2 = strchr(str2, '\\');
 			} while (str2);
-			deltaY = (bottom - top + 1 - (strLen * _fonts[fontIndex]->getCharHeight())) / (strLen + 1);
+			deltaY = (bottom - top + 1 - (nbrOfLines * _fonts[fontIndex]->getCharHeight())) / (nbrOfLines + 1);
 			offY = top + deltaY;
-			for (int i = 0; paramStr[i]; i++) {
+			int i = 0;
+			while (true) {
 				int j = 0;
-				while (paramStr[i] && paramStr[i] != 92)
+				while (paramStr[i] != '\0' && paramStr[i] != '\\')
 					str[j++] = paramStr[i++];
-				str[j] = 0;
+				str[j] = '\0';
 				_destSpriteX = left;
 				_destSpriteY = offY;
 				_textToPrint = str;
@@ -581,7 +583,12 @@ void Draw::drawButton(uint16 id, int16 left, int16 top, int16 right, int16 botto
 				adjustCoords(1, &width, nullptr);
 				_destSpriteX += (right - left + 1 - width) / 2;
 				spriteOperation(DRAW_PRINTTEXT);
+				if (paramStr[i] == '\0')
+					break; // End of the string
+
+				// We are at a '\', new line
 				offY += deltaY + _fonts[fontIndex]->getCharHeight();
+				++i;
 			}
 		} else {
 			_destSpriteX = left;


Commit: d6e5d71dcd781fcd322c8f1d99210e60cae1a1b8
    https://github.com/scummvm/scummvm/commit/d6e5d71dcd781fcd322c8f1d99210e60cae1a1b8
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2026-04-24T23:41:17+02:00

Commit Message:
GOB: Fix a delayed blit when a sound-only video is playing (Adi4)

Fix text not being visible while the voice-over is not terminated, in the
reading comprehension exercises of Adi4 / Language 8-9 years.

Changed paths:
    engines/gob/videoplayer.cpp


diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index 98fc093c74b..e10e6e50e43 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -177,6 +177,10 @@ int VideoPlayer::openVideo(bool primary, const Common::String &file, Properties
 		if (!(video->decoder = openVideo(file, properties)))
 			return -1;
 
+		if (!(properties.flags & kFlagNoVideo) && !video->decoder->hasVideo()
+				&& (_vm->getGameType() == kGameTypeAdibou2 || _vm->getGameType() == kGameTypeAdi4)) // TODO: May be needed by other games
+			_vm->_draw->blitInvalidated();
+
 		if (video->decoder->hasVideo() && !(properties.flags & kFlagNoVideo) &&
 		    (video->decoder->isPaletted() != !_vm->isTrueColor())) {
 			if (properties.switchColorMode) {


Commit: 5dd11f4604b9008149b9a74b2807dc9fd9cb62ef
    https://github.com/scummvm/scummvm/commit/5dd11f4604b9008149b9a74b2807dc9fd9cb62ef
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2026-04-24T23:42:27+02:00

Commit Message:
GOB: Fix a missing temporary sprite save handler for Adi4

Fixes a black screen when returning from an exercise's help to the
exercise itself.

Changed paths:
    engines/gob/save/saveload.h
    engines/gob/save/saveload_v7.cpp


diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h
index 5677c1638d8..3ddddbe5ce7 100644
--- a/engines/gob/save/saveload.h
+++ b/engines/gob/save/saveload.h
@@ -1118,6 +1118,7 @@ protected:
 	GameFileHandler             *_adibou2AppliIniHandler[kAdibou2NbrOfApplications];
 
 	FakeFileHandler             *_adi4TempFileHandler[kAdi4NbrOfTempFiles];
+	TempSpriteHandler           *_adi4TempSpriteHandler;
 	GameFileHandler             *_adi4GameFileHandler[kAdi4NbrOfGameFiles];
 
 	SaveHandler *getHandler(const char *fileName) const override;
diff --git a/engines/gob/save/saveload_v7.cpp b/engines/gob/save/saveload_v7.cpp
index 5d0c70d14d3..69c6d9b260f 100644
--- a/engines/gob/save/saveload_v7.cpp
+++ b/engines/gob/save/saveload_v7.cpp
@@ -943,6 +943,9 @@ SaveLoad_v7::SaveFile SaveLoad_v7::_saveFiles[] = {
 	{"adi.tmp", kSaveModeSave, nullptr, nullptr},
 	{"adi4.tmp", kSaveModeSave, nullptr, nullptr},
 
+	// Temporary sprites
+	{"ADI.$$$", kSaveModeSave, nullptr, nullptr},
+
 	// Persitent files
 	{"RETURN_FROM_GAMEBOX", kSaveModeSave, nullptr, nullptr}, // Fictive file used to simulate returning from Gamebox in ScummVM
 	{"TEMP/ADI4.PHO", kSaveModeSave, nullptr, nullptr},
@@ -2104,6 +2107,8 @@ SaveLoad_v7::SaveLoad_v7(GobEngine *vm, const char *targetName) :
 		_saveFiles[index++].handler = _adi4TempFileHandler[i] = new FakeFileHandler(_vm);
 	}
 
+	_saveFiles[index++].handler = _adi4TempSpriteHandler = new TempSpriteHandler(_vm);
+
 	int indexAdi4file = 0;
 	_saveFiles[index++].handler = _adi4GameFileHandler[indexAdi4file++] = new GameFileHandler(_vm,
 																							  targetName,
@@ -2182,6 +2187,8 @@ SaveLoad_v7::~SaveLoad_v7() {
 		delete _adi4TempFileHandler[i];
 	}
 
+	delete _adi4TempSpriteHandler;
+
 	for (uint32 i = 0; i < kAdi4NbrOfGameFiles; i++) {
 		delete _adi4GameFileHandler[i];
 	}




More information about the Scummvm-git-logs mailing list