[Scummvm-git-logs] scummvm master -> b33d0068ddf98b83267751076b289e9eb0f6d1c3

Helco noreply at scummvm.org
Thu Jun 11 17:17:43 UTC 2026


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

Summary:
856fa1436e ALCACHOFA: V2: Add initial game variants for corvino
301d7f1dec ALCACHOFA: Fix saving through ScummVM menu
b33d0068dd ALCACHOFA: CORVINO: Adapt initial script, sound and text differences


Commit: 856fa1436ebeab69d7fecc05ca7a567b62a4cf29
    https://github.com/scummvm/scummvm/commit/856fa1436ebeab69d7fecc05ca7a567b62a4cf29
Author: Helco (hermann.noll at hotmail.com)
Date: 2026-06-11T19:17:13+02:00

Commit Message:
ALCACHOFA: V2: Add initial game variants for corvino

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


diff --git a/engines/alcachofa/game-v2.cpp b/engines/alcachofa/game-v2.cpp
index 0ad459dd50c..cd6beccc576 100644
--- a/engines/alcachofa/game-v2.cpp
+++ b/engines/alcachofa/game-v2.cpp
@@ -210,6 +210,27 @@ public:
 	bool doesRoomHaveBackground(const Room *room) override {
 		return !room->name().equalsIgnoreCase("Global");
 	}
+
+	String reencodePath(const String &path) override {
+		if (!_hasMessedUpEncoding)
+			return Game::reencodePath(path);
+
+		// Some of the Steam releases have wrong characters due to a messed up UTF8 conversion
+		U32String u32String = path.decode(Common::CodePage::kISO8859_1);
+		for (uint i = 0; i < u32String.size(); i++) {
+			const auto ch = u32String[i];
+			if (ch == 0xC1) // Á -> ╡
+				u32String[i] = 0x2561;
+			else if (ch == 0xD3) // Ó -> α
+				u32String[i] = 0x03B1;
+			else if (ch == 0xCD) // Í -> ╓
+				u32String[i] = 0x2553;
+		}
+		return u32String.encode();
+	}
+
+protected:
+	bool _hasMessedUpEncoding = false;
 };
 
 class GameWithVersion2_0 : public GameWithVersion2 {
@@ -246,18 +267,21 @@ static constexpr const char *kMapFilesSecta[] = {
 	"Mapas/global.emc",
 	nullptr
 };
+static const char *const *const kMapFilesCorvino = kMapFilesSecta;
 
 static constexpr const char *kMapFilesMoscu[] = {
 	"Mapas/mapa1.emc",
 	"Mapas/global.emc",
 	nullptr
 };
+static const char *const *const kMapFilesBalones = kMapFilesMoscu;
 
 static constexpr const char *kMapFilesEscarabajo[] = {
 	"Mapas/mapa2.emc",
 	"Mapas/global.emc",
 	nullptr
 };
+static const char *const *const kMapFilesMamelucos = kMapFilesEscarabajo;
 
 class GameSecta : public GameWithVersion2_0 {
 public:
@@ -333,27 +357,58 @@ public:
 	bool isKnownBadVideo(int32 videoId) override {
 		return videoId == 0; // MPEG-4 codec is unsupported
 	}
+};
 
-	String reencodePath(const String &path) override {
-		if (!_hasMessedUpEncoding)
-			return Game::reencodePath(path);
+class GameWithVersion2_1 : public GameWithVersion2 {
+public:
+	char getTextFileKey() override {
+		return static_cast<char>(0x60);
+	}
 
-		// The Steam release has wrong characters due to some messed up UTF8 conversion
-		U32String u32String = path.decode(Common::CodePage::kISO8859_1);
-		for (uint i = 0; i < u32String.size(); i++) {
-			const auto ch = u32String[i];
-			if (ch == 0xC1) // Á -> ╡
-				u32String[i] = 0x2561;
-			else if (ch == 0xD3) // Ó -> α
-				u32String[i] = 0x03B1;
-			else if (ch == 0xCD) // Í -> ╓
-				u32String[i] = 0x2553;
-		}
-		return u32String.encode();
+	String getMusicPath(int32 trackId) override {
+		return String::format("Sonidos/T%02d", trackId);
 	}
+};
 
-private:
-	bool _hasMessedUpEncoding = false;
+class GameCorvino : public GameWithVersion2_1 {
+public:
+	void onLoadedGameFiles() override {
+		g_engine->script().variable("EsJuegoCompleto") = 0;
+	}
+
+	const char *const *getMapFiles() override {
+		return kMapFilesCorvino;
+	}
+};
+
+class GameBalones : public GameWithVersion2_1 {
+public:
+	GameBalones() {
+		_hasMessedUpEncoding = !SearchMan.hasFile(Path(reencode("Animaciones/aut\xD3grafo.ani")));
+	}
+
+	void onLoadedGameFiles() override {
+		g_engine->script().variable("EsJuegoCompleto") = 1;
+	}
+
+	const char *const *getMapFiles() override {
+		return kMapFilesBalones;
+	}
+};
+
+class GameMamelucos : public GameWithVersion2_1 {
+public:
+	GameMamelucos() {
+		_hasMessedUpEncoding = !SearchMan.hasFile(Path(reencode("Animaciones/EST\xC1TICOS FILEM\xD3N.ANI")));
+	}
+
+	void onLoadedGameFiles() override {
+		g_engine->script().variable("EsJuegoCompleto") = 2;
+	}
+
+	const char *const *getMapFiles() override {
+		return kMapFilesMamelucos;
+	}
 };
 
 Game *Game::createForSecta() {
@@ -368,4 +423,16 @@ Game *Game::createForEscarabajo() {
 	return new GameEscarabajo();
 }
 
+Game *Game::createForCorvino() {
+	return new GameCorvino();
+}
+
+Game *Game::createForBalones() {
+	return new GameBalones();
+}
+
+Game *Game::createForMamelucos() {
+	return new GameMamelucos();
+}
+
 }
diff --git a/engines/alcachofa/game.cpp b/engines/alcachofa/game.cpp
index 042b8b868b2..3e5b1562caf 100644
--- a/engines/alcachofa/game.cpp
+++ b/engines/alcachofa/game.cpp
@@ -242,6 +242,16 @@ Game *Game::create() {
 			return createForEscarabajo();
 		}
 		break;
+	case EngineVersion::V2_1:
+		switch (*desc.desc.gameId) {
+		case 'c':
+			return createForCorvino();
+		case 'b':
+			return createForBalones();
+		case 'm':
+			return createForMamelucos();
+		}
+		break;
 	case EngineVersion::V3_0:
 	case EngineVersion::V3_1:
 		return createForMovieAdventureSpecial();
diff --git a/engines/alcachofa/game.h b/engines/alcachofa/game.h
index fee703beb25..1fa369e3dac 100644
--- a/engines/alcachofa/game.h
+++ b/engines/alcachofa/game.h
@@ -133,6 +133,9 @@ public:
 	static Game *createForSecta(); // V2
 	static Game *createForMoscu(); // V2
 	static Game *createForEscarabajo(); // V2
+	static Game *createForCorvino(); // V2
+	static Game *createForBalones(); // V2
+	static Game *createForMamelucos(); // V2
 
 	const Message _message;
 };


Commit: 301d7f1decd8c2456a30d5dd3cdb9b4ca036160c
    https://github.com/scummvm/scummvm/commit/301d7f1decd8c2456a30d5dd3cdb9b4ca036160c
Author: Helco (hermann.noll at hotmail.com)
Date: 2026-06-11T19:17:13+02:00

Commit Message:
ALCACHOFA: Fix saving through ScummVM menu

Changed paths:
    engines/alcachofa/alcachofa.cpp


diff --git a/engines/alcachofa/alcachofa.cpp b/engines/alcachofa/alcachofa.cpp
index 081435ab463..8aa2ec0a859 100644
--- a/engines/alcachofa/alcachofa.cpp
+++ b/engines/alcachofa/alcachofa.cpp
@@ -320,7 +320,7 @@ void AlcachofaEngine::pauseEngineIntern(bool pause) {
 bool AlcachofaEngine::canLoadGameStateCurrently(U32String *msg) {
 	if (_menu == nullptr)
 		return false; // the autosave wants to trigger even during error() while starting the game
-	if (!isInSpecialGameLoop())
+	if (isInSpecialGameLoop())
 		return false;
 	return
 		(menu().isOpen() && menu().interactionSemaphore().isReleased()) ||


Commit: b33d0068ddf98b83267751076b289e9eb0f6d1c3
    https://github.com/scummvm/scummvm/commit/b33d0068ddf98b83267751076b289e9eb0f6d1c3
Author: Helco (hermann.noll at hotmail.com)
Date: 2026-06-11T19:17:13+02:00

Commit Message:
ALCACHOFA: CORVINO: Adapt initial script, sound and text differences

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


diff --git a/engines/alcachofa/alcachofa.h b/engines/alcachofa/alcachofa.h
index 53d5c6f723b..4dc6ca7ee34 100644
--- a/engines/alcachofa/alcachofa.h
+++ b/engines/alcachofa/alcachofa.h
@@ -118,6 +118,7 @@ public:
 	inline EngineVersion version() const { return gameDescription().engineVersion; }
 	inline bool isV1() const { return gameDescription().isVersionBetween(10, 19); }
 	inline bool isV2() const { return gameDescription().isVersionBetween(20, 29); }
+	inline bool isV20() const { return gameDescription().isVersionBetween(20, 20); }
 	inline bool isV3() const { return gameDescription().isVersionBetween(30, 39); }
 
 	inline const AlcachofaGameDescription &gameDescription() const { return *_gameDescription; }
diff --git a/engines/alcachofa/game-v2.cpp b/engines/alcachofa/game-v2.cpp
index cd6beccc576..76c7b92227f 100644
--- a/engines/alcachofa/game-v2.cpp
+++ b/engines/alcachofa/game-v2.cpp
@@ -102,7 +102,12 @@ static constexpr const ScriptKernelTask kScriptKernelTaskMap[] = {
 	ScriptKernelTask::PlayMusic,
 	ScriptKernelTask::StopMusic,
 	ScriptKernelTask::WaitForMusicToEnd,
-	ScriptKernelTask::SayTextV2
+	ScriptKernelTask::SayTextV2, // *might* be used in secta, unused in corvino
+	ScriptKernelTask::AnimateCharacter, // from here on only corvino
+	ScriptKernelTask::AnimateTalking,
+	ScriptKernelTask::ClearInventory,
+	ScriptKernelTask::WaitForMouseClick,
+	ScriptKernelTask::ResetCharacter
 };
 
 class GameWithVersion2 : public Game {
@@ -157,10 +162,6 @@ public:
 		script.variable("textoson") = g_engine->config().subtitles() ? 1 : 0;
 	}
 
-	Path getVideoPath(int32 videoId) override {
-		return Path(String::format("Bin/DATA%02d.BIN", videoId));
-	}
-
 	String getSoundPath(const char *filename) override {
 		return String("Sonidos/") + filename;
 	}
@@ -243,6 +244,10 @@ public:
 		script.fixNestedMenuPop(20898); // Filemon talking to MANOLO in FILE_PIRAMIDE
 	}
 
+	Path getVideoPath(int32 videoId) override {
+		return Path(String::format("Bin/DATA%02d.BIN", videoId));
+	}
+
 	char getTextFileKey() override {
 		return static_cast<char>(0xA3);
 	}
@@ -361,12 +366,22 @@ public:
 
 class GameWithVersion2_1 : public GameWithVersion2 {
 public:
+	Path getVideoPath(int32 videoId) override {
+		return Path(String::format("Data/DATA%02d.BIN", videoId));
+	}
+
 	char getTextFileKey() override {
 		return static_cast<char>(0x60);
 	}
 
 	String getMusicPath(int32 trackId) override {
-		return String::format("Sonidos/T%02d", trackId);
+		return String::format("Sonidos/T%d", trackId);
+	}
+
+	void missingAnimation(const Common::String &fileName) override {
+		if (fileName == "VARITA.ANI") // this one seems bad, it is the inventory icon for I_RAMAS
+			return;
+		return GameWithVersion2::missingAnimation(fileName);
 	}
 };
 
@@ -379,6 +394,11 @@ public:
 	const char *const *getMapFiles() override {
 		return kMapFilesCorvino;
 	}
+
+	bool isKnownBadVideo(int32 videoId) override {
+		// These use DV codec in the steam release
+		return videoId < 2;
+	}
 };
 
 class GameBalones : public GameWithVersion2_1 {
diff --git a/engines/alcachofa/rooms.cpp b/engines/alcachofa/rooms.cpp
index f7ee4356e46..2c85ccee336 100644
--- a/engines/alcachofa/rooms.cpp
+++ b/engines/alcachofa/rooms.cpp
@@ -911,6 +911,12 @@ static char *trimTrailing(char *start, char *end) {
 	return end;
 }
 
+static bool isEmptyLine(const char *start, const char *end) {
+	while (start < end && isSpace(*start))
+		start++;
+	return start >= end;
+}
+
 void World::loadLocalizedNames() {
 	const char *filename = g_engine->game().getObjectFileName();
 	char textFileKey = g_engine->game().getTextFileKey();
@@ -946,6 +952,11 @@ void World::loadLocalizedNames() {
 		// key#value
 		while (lineStart < fileEnd) {
 			char *lineEnd = find(lineStart, fileEnd, '\n');
+			if (isEmptyLine(lineStart, lineEnd)) {
+				// empty lines are only in Corvino/Balones/Mamelucos
+				lineStart = lineEnd + 1;
+				continue;
+			}
 			char *keyEnd = find(lineStart, lineEnd, '#');
 			if (keyEnd == lineStart || keyEnd == lineEnd || keyEnd + 1 == lineEnd)
 				error("Invalid localized name line separator");
diff --git a/engines/alcachofa/script.h b/engines/alcachofa/script.h
index 378a3391a36..c324825b21b 100644
--- a/engines/alcachofa/script.h
+++ b/engines/alcachofa/script.h
@@ -128,7 +128,9 @@ enum class ScriptKernelTask {
 	FadeOut2,
 	LerpCamXYZ,
 	LerpCamToObjectKeepingZ,
-	Disguise
+	Disguise,
+	WaitForMouseClick, // only V2.1
+	ResetCharacter     // only V2.1
 };
 
 enum class ScriptFlags {
diff --git a/engines/alcachofa/sounds.cpp b/engines/alcachofa/sounds.cpp
index 7275759bc3d..15e416c2345 100644
--- a/engines/alcachofa/sounds.cpp
+++ b/engines/alcachofa/sounds.cpp
@@ -118,11 +118,11 @@ private:
 };
 
 static AudioStream *loadSND(File *file) {
-	// in V2 SND files are raw U8 PCM in mono 22100 encrypted with XOR
-	if (g_engine->isV2())
+	// only in V2.0 SND files are raw U8 PCM in mono 22100 encrypted with XOR
+	if (g_engine->isV20())
 		return makeRawStream(new XORReadStream(file, 0x55, DisposeAfterUse::YES), 22100, FLAG_UNSIGNED);
 
-	// in V1/V3 SND files are just WAV files with removed headers
+	// everywhere else SND files are just WAV files with removed headers
 	const uint32 endOfFormat = file->readUint32LE() + 2 * sizeof(uint32);
 	if (endOfFormat < 24)
 		error("Invalid SND format size");




More information about the Scummvm-git-logs mailing list