[Scummvm-git-logs] scummvm master -> 4e92ffd25ff0670309daadd8eb874f5428c3193b

Helco noreply at scummvm.org
Mon Jun 29 16:44:13 UTC 2026


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

Summary:
bd19753e99 ALCACHOFA: Improve fallback for character size query
bf18b70cb3 ALCACHOFA: Fix potential integer underflow
b0a2d2eca2 ALCACHOFA: V2: Add exceptions for mamelucos
29ee1ec56c ALCACHOFA: V2: Add SayTextOnlySound
4e92ffd25f ALCACHOFA: V2: Fix talking to YAFAR


Commit: bd19753e994a21e88a66f7843d94a5bcc30c1957
    https://github.com/scummvm/scummvm/commit/bd19753e994a21e88a66f7843d94a5bcc30c1957
Author: Helco (hermann.noll at hotmail.com)
Date: 2026-06-29T18:41:42+02:00

Commit Message:
ALCACHOFA: Improve fallback for character size query

Changed paths:
    engines/alcachofa/shape.cpp


diff --git a/engines/alcachofa/shape.cpp b/engines/alcachofa/shape.cpp
index a0bde018bd1..ac6cb7aa628 100644
--- a/engines/alcachofa/shape.cpp
+++ b/engines/alcachofa/shape.cpp
@@ -380,6 +380,8 @@ int8 PathFindingShape::orderAt(Point query) const {
 
 float PathFindingShape::depthAt(Point query) const {
 	int32 polygon = polygonContaining(query);
+	if (polygon < 0)
+		query = closestPointTo(query, polygon);
 	return polygon < 0 ? 1.0f : at(polygon).depthAt(query);
 }
 


Commit: bf18b70cb3686743c5f9bdb9de25e3fffc4cc002
    https://github.com/scummvm/scummvm/commit/bf18b70cb3686743c5f9bdb9de25e3fffc4cc002
Author: Helco (hermann.noll at hotmail.com)
Date: 2026-06-29T18:41:42+02:00

Commit Message:
ALCACHOFA: Fix potential integer underflow

Changed paths:
    engines/alcachofa/script.cpp


diff --git a/engines/alcachofa/script.cpp b/engines/alcachofa/script.cpp
index 2ad7b9c8c21..ef59e72fe07 100644
--- a/engines/alcachofa/script.cpp
+++ b/engines/alcachofa/script.cpp
@@ -143,6 +143,10 @@ bool Script::hasProcedure(const Common::String &procedure) const {
 }
 
 String Script::procedureAt(uint32 pc) const {
+	// this can only happen if an error occurs before we load the script
+	if (_procedures.empty())
+		return "<none>";
+
 	// this method is very inefficient but it is only used for debugging
 	typedef Pair<String, uint32> Node;
 	Array<Node> sorted;


Commit: b0a2d2eca2c8505962c5591259238504fc0e950f
    https://github.com/scummvm/scummvm/commit/b0a2d2eca2c8505962c5591259238504fc0e950f
Author: Helco (hermann.noll at hotmail.com)
Date: 2026-06-29T18:41:43+02:00

Commit Message:
ALCACHOFA: V2: Add exceptions for mamelucos

Changed paths:
    engines/alcachofa/detection_tables.h
    engines/alcachofa/game-v2.cpp


diff --git a/engines/alcachofa/detection_tables.h b/engines/alcachofa/detection_tables.h
index ec6db19eed2..db80f2f7f0c 100644
--- a/engines/alcachofa/detection_tables.h
+++ b/engines/alcachofa/detection_tables.h
@@ -177,7 +177,7 @@ const AlcachofaGameDescription gameDescriptions[] = {
 	//
 	{
 		{
-			"corvino",
+			"mamelucos",
 			"Mortadelo y Filemón: Mamelucos a la Romana",
 			AD_ENTRY2s(
 				"Fondos/MUSEO_O.ANI", "830443af2290a96a95703a17c1915c21", 9732,
diff --git a/engines/alcachofa/game-v2.cpp b/engines/alcachofa/game-v2.cpp
index ce1827d9109..488a61efbcb 100644
--- a/engines/alcachofa/game-v2.cpp
+++ b/engines/alcachofa/game-v2.cpp
@@ -238,6 +238,9 @@ public:
 				} else if (ch == 0xD1) {
 					u32String[i] = 0xF1; // Ñ -> ñ
 					hasChanges = true;
+				} else if (ch == 0xC9) {
+					u32String[i] = 0xE9; // É -> é
+					hasChanges = true;
 				}
 			}
 			return hasChanges ? u32String.encode() : String();
@@ -519,6 +522,39 @@ public:
 	Path getVideoPath(int32 videoId) override {
 		return Path(String::format("Bin/DATA%02d.BIN", videoId));
 	}
+
+	void missingAnimation(const String &filename) override {
+		if (filename.equalsIgnoreCase("AUTÓGRAFO.ANI") ||
+			filename.equalsIgnoreCase("GOMA3.ANI") ||
+			filename.equalsIgnoreCase("IMAN.ANI") ||
+			filename.equalsIgnoreCase("BOTELLA WHISKEY.ANI") ||
+			filename.equalsIgnoreCase("VASO LLENO.ANI") ||
+			filename.equalsIgnoreCase("VASO VACIO.ANI") ||
+			filename.equalsIgnoreCase("PAÑUELO.ANI") ||
+			filename.equalsIgnoreCase("PAÑUELO CON EXTRAÑAS MANCHAS.ANI") ||
+			filename.equalsIgnoreCase("TABLÓN.ANI") ||
+			filename.equalsIgnoreCase("TENAZAS.ANI") ||
+			filename.equalsIgnoreCase("VASO QUITANERVIOS.ANI") ||
+			filename.equalsIgnoreCase("PEGAMENTO.ANI") ||
+			filename.equalsIgnoreCase("MEDIO EURO.ANI") ||
+			filename.equalsIgnoreCase("BOTELLA LICOR.ANI") ||
+			filename.equalsIgnoreCase("OSCAR TECNOLOGICO.ANI") ||
+			filename.equalsIgnoreCase("COSA RARA CON BOMBILLA.ANI") ||
+			filename.equalsIgnoreCase("CONTRATO SIN FIRMAR.ANI") ||
+			filename.equalsIgnoreCase("CONTRATO FIRMADO.ANI") ||
+			filename.equalsIgnoreCase("BOTELLA CHAMPAGNE.ANI") ||
+			filename.equalsIgnoreCase("BOMBA.ANI") ||
+			filename.equalsIgnoreCase("OTRA BOMBA.ANI") ||
+			filename.equalsIgnoreCase("BOMBA CON RELOJ.ANI"))
+			return;
+		GameWithVersion2_1::missingAnimation(filename);
+	}
+
+	void missingSound(const String &filename) override {
+		if (filename.equalsIgnoreCase("Sonidos/T2"))
+			return;
+		GameWithVersion2_1::missingSound(filename);
+	}
 };
 
 Game *Game::createForSecta() {


Commit: 29ee1ec56c4f82b9a36371217b873b0ba0442cb7
    https://github.com/scummvm/scummvm/commit/29ee1ec56c4f82b9a36371217b873b0ba0442cb7
Author: Helco (hermann.noll at hotmail.com)
Date: 2026-06-29T18:41:43+02:00

Commit Message:
ALCACHOFA: V2: Add SayTextOnlySound

Changed paths:
    engines/alcachofa/game-objects.cpp
    engines/alcachofa/game-v2.cpp
    engines/alcachofa/objects.h
    engines/alcachofa/script.cpp
    engines/alcachofa/script.h


diff --git a/engines/alcachofa/game-objects.cpp b/engines/alcachofa/game-objects.cpp
index 6247d5ed273..b60287d7bd8 100644
--- a/engines/alcachofa/game-objects.cpp
+++ b/engines/alcachofa/game-objects.cpp
@@ -315,10 +315,11 @@ void Character::trigger(const char *action) {
 }
 
 struct SayTextTask final : public Task {
-	SayTextTask(Process &process, Character *character, int32 dialogId)
+	SayTextTask(Process &process, Character *character, int32 dialogId, const char *dialogSound)
 		: Task(process)
 		, _character(character)
-		, _dialogId(dialogId) {}
+		, _dialogId(dialogId)
+		, _dialogSound(dialogSound) {}
 
 	SayTextTask(Process &process, Serializer &s)
 		: Task(process) {
@@ -337,7 +338,7 @@ struct SayTextTask final : public Task {
 			if (_soundHandle == SoundHandle {}) {
 				bool hasMortadeloVoice = g_engine->game().hasMortadeloVoice(_character);
 				_soundHandle = g_engine->sounds().playVoice(
-					String::format(hasMortadeloVoice ? "M%04d" : "%04d", _dialogId),
+					_dialogSound.empty() ? String::format(hasMortadeloVoice ? "M%04d" : "%04d", _dialogId) : _dialogSound,
 					0);
 			}
 			isSoundStillPlaying = g_engine->sounds().isAlive(_soundHandle);
@@ -346,7 +347,8 @@ struct SayTextTask final : public Task {
 				_character->_isTalking = false;
 
 			if (g_engine->config().subtitles() &&
-				process().isActiveForPlayer()) {
+				process().isActiveForPlayer() &&
+				_dialogId >= 0) {
 				g_engine->drawQueue().add<TextDrawRequest>(
 					g_engine->globalUI().dialogFont(),
 					g_engine->world().getDialogLine(_dialogId),
@@ -375,6 +377,8 @@ struct SayTextTask final : public Task {
 		Task::syncGame(s);
 		syncObjectAsString(s, _character);
 		s.syncAsSint32LE(_dialogId);
+		if (_dialogId == -1)
+			s.syncString(_dialogSound);
 	}
 
 	const char *taskName() const override;
@@ -382,12 +386,13 @@ struct SayTextTask final : public Task {
 private:
 	Character *_character = nullptr;
 	int32 _dialogId = 0;
+	String _dialogSound = nullptr;
 	SoundHandle _soundHandle = {};
 };
 DECLARE_TASK(SayTextTask)
 
-Task *Character::sayText(Process &process, int32 dialogId) {
-	return new SayTextTask(process, this, dialogId);
+Task *Character::sayText(Process &process, int32 dialogId, const char *dialogSound) {
+	return new SayTextTask(process, this, dialogId, dialogSound);
 }
 
 void Character::resetTalking() {
@@ -1096,7 +1101,7 @@ struct DialogMenuTask final : public Task {
 			if (_clickedLineI != UINT_MAX) {
 				TASK_YIELD(2);
 				process().lockInteraction();
-				TASK_WAIT(3, _character->sayText(process(), _character->_dialogLines[_clickedLineI]._dialogId));
+				TASK_WAIT(3, _character->sayText(process(), _character->_dialogLines[_clickedLineI]._dialogId, nullptr));
 				int32 returnValue = _character->_dialogLines[_clickedLineI]._returnValue;
 				_character->_dialogLines.clear();
 				TASK_RETURN(returnValue);
diff --git a/engines/alcachofa/game-v2.cpp b/engines/alcachofa/game-v2.cpp
index 488a61efbcb..0ce93b0a3c5 100644
--- a/engines/alcachofa/game-v2.cpp
+++ b/engines/alcachofa/game-v2.cpp
@@ -102,7 +102,7 @@ static constexpr const ScriptKernelTask kScriptKernelTaskMap[] = {
 	ScriptKernelTask::PlayMusic,
 	ScriptKernelTask::StopMusic,
 	ScriptKernelTask::WaitForMusicToEnd,
-	ScriptKernelTask::SayTextV2, // *might* be used in secta, unused in corvino
+	ScriptKernelTask::SayTextOnlySound, // only used in secta/escarabajo with subtitles off (speaking with YAFAR)
 	ScriptKernelTask::AnimateCharacter, // from here on only corvino
 	ScriptKernelTask::AnimateTalking,
 	ScriptKernelTask::ClearInventory,
diff --git a/engines/alcachofa/objects.h b/engines/alcachofa/objects.h
index 33f4dccb95d..f6dee1de5b2 100644
--- a/engines/alcachofa/objects.h
+++ b/engines/alcachofa/objects.h
@@ -506,7 +506,7 @@ public:
 	void trigger(const char *action) override;
 	const char *typeName() const override;
 
-	Task *sayText(Process &process, int32 dialogId);
+	Task *sayText(Process &process, int32 dialogId, const char *dialogSound);
 	void resetTalking();
 	void talkUsing(ObjectBase *talkObject);
 	Task *animate(Process &process, ObjectBase *animateObject);
diff --git a/engines/alcachofa/script.cpp b/engines/alcachofa/script.cpp
index ef59e72fe07..da8f847ad66 100644
--- a/engines/alcachofa/script.cpp
+++ b/engines/alcachofa/script.cpp
@@ -956,7 +956,16 @@ private:
 				_character = g_engine->game().unknownSayTextCharacter(characterName, dialogId);
 			if (_character == nullptr)
 				return TaskReturn::finish(1);
-			return TaskReturn::waitFor(_character->sayText(process(), dialogId));
+			return TaskReturn::waitFor(_character->sayText(process(), dialogId, nullptr));
+		};
+		case ScriptKernelTask::SayTextOnlySound: {
+			const char *dialogSound = getStringArg(1);
+			Character *_character = getObjectArg<Character>(0);
+			if (_character == nullptr)
+				_character = g_engine->game().unknownSayTextCharacter(getStringArg(0), -1);
+			if (_character == nullptr)
+				return TaskReturn::finish(1);
+			return TaskReturn::waitFor(_character->sayText(process(), -1, dialogSound));
 		};
 		case ScriptKernelTask::SetDialogLineReturn:
 			relatedCharacter().setLastDialogReturnValue(getNumberArg(0));
diff --git a/engines/alcachofa/script.h b/engines/alcachofa/script.h
index c5e84aaab18..de2280cdb59 100644
--- a/engines/alcachofa/script.h
+++ b/engines/alcachofa/script.h
@@ -83,7 +83,7 @@ enum class ScriptKernelTask {
 	StopAndTurnMe,
 	ChangeCharacter,
 	SayText,
-	SayTextV2, // TODO: Reverse engineer this variant
+	SayTextOnlySound, // only used in secta with subtitles turned off...
 	Go,
 	Put,
 	ChangeCharacterRoom,


Commit: 4e92ffd25ff0670309daadd8eb874f5428c3193b
    https://github.com/scummvm/scummvm/commit/4e92ffd25ff0670309daadd8eb874f5428c3193b
Author: Helco (hermann.noll at hotmail.com)
Date: 2026-06-29T18:41:43+02:00

Commit Message:
ALCACHOFA: V2: Fix talking to YAFAR

Changed paths:
    engines/alcachofa/camera.cpp
    engines/alcachofa/game-v2.cpp


diff --git a/engines/alcachofa/camera.cpp b/engines/alcachofa/camera.cpp
index 4aa2e8c620a..7bce709e8d8 100644
--- a/engines/alcachofa/camera.cpp
+++ b/engines/alcachofa/camera.cpp
@@ -251,6 +251,9 @@ void CameraV1::setRoomBounds(Graphic &background) {
 
 void CameraV2::setRoomBounds(Graphic &background) {
 	Point bgSize = background.animation().imageSize(0);
+	if (bgSize == Point(0, 0)) // this fixes a bug in secta/escarabajo with subtitles off when talking to YAFAR
+		bgSize = Point(800, 600);
+
 	float scaleFactor = background.scale() / (float)kBaseScale;
 	Point screenSize(g_system->getWidth(), g_system->getHeight());
 	_roomMin = as2D(background.topLeft()) * scaleFactor + as2D(screenSize / 2);
diff --git a/engines/alcachofa/game-v2.cpp b/engines/alcachofa/game-v2.cpp
index 0ce93b0a3c5..1b5e2870183 100644
--- a/engines/alcachofa/game-v2.cpp
+++ b/engines/alcachofa/game-v2.cpp
@@ -283,6 +283,28 @@ public:
 		return static_cast<char>(0xA3);
 	}
 
+	
+
+	void missingAnimation(const String &filename) override {
+		// missing background, not actually necessary as graphic objects cover the entire room
+		if (filename.equalsIgnoreCase("HISTORIA_CLEOPATRA")) {
+			// unrelated to the animation, if we query this we apparently entered the room
+			// there is an original script bug where triggering this dialog twice
+			// only the last graphic object is active blocking all others
+			// we fix this by restoring the original state
+			const Room *room = g_engine->player().currentRoom();
+			ObjectBase *firstPicture = room->getObjectByName("OL Cleo1");
+			ObjectBase *lastPicture = room->getObjectByName("OL Cleo10");
+			if (firstPicture != nullptr && lastPicture != nullptr &&
+				!firstPicture->isEnabled() && lastPicture->isEnabled()) {
+				firstPicture->toggle(true);
+				lastPicture->toggle(false);
+			}
+			return; // and we still ignore the missing background
+		}
+		GameWithVersion2::missingAnimation(filename);
+	}
+
 	PointObject *unknownCamLerpTarget(const char *action, const char *name) override {
 		// Original bug: a main character being reinterpret_cast to a PointObject, undefined behavior ensues
 		if (scumm_stricmp(name, "FILEMON"))




More information about the Scummvm-git-logs mailing list