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

neuromancer noreply at scummvm.org
Sun Apr 30 18:30:57 UTC 2023


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

Summary:
c4a0d162fb FREESCAPE: refactored conditional handling to make it work with castle
de5fbf9b00 FREESCAPE: added support for using different languages in castle (DOS)


Commit: c4a0d162fb117c5e28c86c62070dd31f468b22d8
    https://github.com/scummvm/scummvm/commit/c4a0d162fb117c5e28c86c62070dd31f468b22d8
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-04-30T20:30:41+02:00

Commit Message:
FREESCAPE: refactored conditional handling to make it work with castle

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/language/8bitDetokeniser.cpp
    engines/freescape/language/8bitDetokeniser.h
    engines/freescape/language/instruction.cpp
    engines/freescape/language/token.h


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 385745bb4db..2bf19ab76ef 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -281,6 +281,7 @@ public:
 	void executeCode(FCLInstructionVector &code, bool shot, bool collided, bool timer);
 
 	// Instructions
+	bool checkConditional(FCLInstruction &instruction, bool shot, bool collided, bool timer, bool activated);
 	bool checkIfGreaterOrEqual(FCLInstruction &instruction);
 	void executeIncrementVariable(FCLInstruction &instruction);
 	void executeDecrementVariable(FCLInstruction &instruction);
diff --git a/engines/freescape/language/8bitDetokeniser.cpp b/engines/freescape/language/8bitDetokeniser.cpp
index 37b76ab9854..775140d972a 100644
--- a/engines/freescape/language/8bitDetokeniser.cpp
+++ b/engines/freescape/language/8bitDetokeniser.cpp
@@ -33,7 +33,7 @@ uint8 k8bitMaxVariable = 64;
 uint8 k8bitMaxShield = 64;
 uint8 k8bitMaxEnergy = 64;
 
-Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions, bool enableActivated) {
+Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition, FCLInstructionVector &instructions, bool multipleConditionals) {
 	Common::String detokenisedStream;
 	Common::Array<uint8>::size_type bytePointer = 0;
 	Common::Array<uint8>::size_type sizeOfTokenisedContent = tokenisedCondition.size();
@@ -56,28 +56,30 @@ Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition,
 
 	if (sizeOfTokenisedContent > 0)
 		detokenisedStream += Common::String::format("CONDITION FLAG: %x\n", tokenisedCondition[0]);
-	Token::Type newConditional = Token::UNKNOWN;
-	Token::Type oldConditional = Token::UNKNOWN;
+	uint16 newConditional = 0;
+	uint16 oldConditional = 0;
 
 	while (bytePointer < sizeOfTokenisedContent) {
 		// get the conditional type of the next operation
-		uint8 conditionalByte = tokenisedCondition[bytePointer];
-
-		if ((conditionalByte & 0xc0) && enableActivated) {
-			newConditional = Token::ACTIVATEDQ;
-		} else if (conditionalByte & 0x80)
-			newConditional = Token::SHOTQ;
-		else if (conditionalByte & 0x40)
-			newConditional = Token::TIMERQ;
+		uint8 conditionalByte = tokenisedCondition[bytePointer] & 0xc0;
+		//detokenisedStream += Common::String::format("CONDITION FLAG: %x\n", conditionalByte);
+		newConditional = 0;
+
+		if (conditionalByte == 0x40)
+			newConditional = kConditionalTimeout;
+		else if (conditionalByte == 0x80)
+			newConditional = kConditionalShot;
+		else if (conditionalByte == 0xc0)
+			newConditional = kConditionalActivated;
 		else
-			newConditional = Token::COLLIDEDQ;
+			newConditional = kConditionalCollided;
 
 		// if the conditional type has changed then end the old conditional,
 		// if we were in one, and begin a new one
 		if (bytePointer == 0 || newConditional != oldConditional) {
 			oldConditional = newConditional;
 			FCLInstruction branch;
-			branch = FCLInstruction(oldConditional);
+			branch = FCLInstruction(Token::CONDITIONAL);
 
 			if (bytePointer > 0) {
 				detokenisedStream += "ENDIF\n";
@@ -86,18 +88,23 @@ Common::String detokenise8bitCondition(Common::Array<uint8> &tokenisedCondition,
 			}
 
 			branch.setBranches(conditionalInstructions, nullptr);
+			branch.setSource(oldConditional); // conditional flag
 			instructions.push_back(branch);
 
-			if (oldConditional == Token::SHOTQ)
-				detokenisedStream += "IF SHOT? THEN\n";
-			else if (oldConditional == Token::TIMERQ)
-				detokenisedStream += "IF TIMER? THEN\n";
-			else if (oldConditional == Token::COLLIDEDQ)
-				detokenisedStream += "IF COLLIDED? THEN\n";
-			else if (oldConditional == Token::ACTIVATEDQ)
-				detokenisedStream += "IF ACTIVATED? THEN\n";
+			detokenisedStream += "IF ";
+
+			if (oldConditional & kConditionalShot)
+				detokenisedStream += "SHOT? ";
+			else if (oldConditional & kConditionalTimeout)
+				detokenisedStream += "TIMER? ";
+			else if (oldConditional & kConditionalCollided)
+				detokenisedStream += "COLLIDED? ";
+			else if (oldConditional & kConditionalActivated)
+				detokenisedStream += "ACTIVATED? ";
 			else
 				error("Invalid conditional: %x", oldConditional);
+
+			detokenisedStream += "THEN\n";
 		}
 
 		// get the actual operation
diff --git a/engines/freescape/language/8bitDetokeniser.h b/engines/freescape/language/8bitDetokeniser.h
index 08326c2d5c9..8ba7c11a3f0 100644
--- a/engines/freescape/language/8bitDetokeniser.h
+++ b/engines/freescape/language/8bitDetokeniser.h
@@ -36,6 +36,13 @@ enum {
 	k8bitVariableEnergyDrillerJet = 57
 };
 
+enum {
+	kConditionalShot = 1 << 0,
+	kConditionalTimeout = 1 << 1,
+	kConditionalCollided = 1 << 2,
+	kConditionalActivated = 1 << 3,
+};
+
 extern uint8 k8bitMaxVariable;
 extern uint8 k8bitMaxShield;
 extern uint8 k8bitMaxEnergy;
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index b27b8bbffc9..da9ed9ba5d4 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -148,31 +148,13 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
 			debugC(1, kFreescapeDebugCode, "Executing NOP at ip: %d", ip);
 			break;
 
-		case Token::ACTIVATEDQ:
-			if (shot) // TODO: implement interaction
+		case Token::CONDITIONAL:
+			if (checkConditional(instruction, shot, collided, timer, false)) // TODO: implement interaction
 				executeCode(*instruction._thenInstructions, shot, collided, timer);
 			// else branch is always empty
 			assert(instruction._elseInstructions == nullptr);
 			break;
 
-		case Token::COLLIDEDQ:
-			if (collided)
-				executeCode(*instruction._thenInstructions, shot, collided, timer);
-			// else branch is always empty
-			assert(instruction._elseInstructions == nullptr);
-			break;
-		case Token::SHOTQ:
-			if (shot)
-				executeCode(*instruction._thenInstructions, shot, collided, timer);
-			// else branch is always empty
-			assert(instruction._elseInstructions == nullptr);
-			break;
-		case Token::TIMERQ:
-			if (timer)
-				executeCode(*instruction._thenInstructions, shot, collided, timer);
-			// else branch is always empty
-			assert(instruction._elseInstructions == nullptr);
-			break;
 		case Token::VARNOTEQ:
 			if (executeEndIfNotEqual(instruction))
 				ip = codeSize;
@@ -355,6 +337,23 @@ bool FreescapeEngine::executeEndIfVisibilityIsEqual(FCLInstruction &instruction)
 	return (obj->isInvisible() == (value != 0));
 }
 
+bool FreescapeEngine::checkConditional(FCLInstruction &instruction, bool shot, bool collided, bool timer, bool activated) {
+	uint16 conditional = instruction._source;
+	bool result = false;
+
+	if (conditional & kConditionalShot)
+		result |= shot;
+	if (conditional & kConditionalTimeout)
+		result |= timer;
+	if (conditional & kConditionalCollided)
+		result |= collided;
+	if (conditional & kConditionalActivated)
+		result |= activated;
+
+	debugC(1, kFreescapeDebugCode, "Check if conditional %x is true: %d!", conditional, result);
+	return result;
+}
+
 bool FreescapeEngine::checkIfGreaterOrEqual(FCLInstruction &instruction) {
 	uint16 variable = instruction._source;
 	uint16 value = instruction._destination;
diff --git a/engines/freescape/language/token.h b/engines/freescape/language/token.h
index d108d93d780..a99d777b8bd 100644
--- a/engines/freescape/language/token.h
+++ b/engines/freescape/language/token.h
@@ -30,12 +30,11 @@ namespace Freescape {
 struct Token {
 public:
 	enum Type {
-		ACTIVATEDQ,
 		ADDVAR,
 		AGAIN,
 		AND,
 		ANDV,
-		COLLIDEDQ,
+		CONDITIONAL,
 		DELAY,
 		DESTROY,
 		DESTROYEDQ,
@@ -67,7 +66,6 @@ public:
 		SCREEN,
 		SOUND,
 		SETVAR,
-		SHOTQ,
 		START,
 		STARTANIM,
 		STOPANIM,
@@ -75,7 +73,6 @@ public:
 		SUBVAR,
 		SYNCSND,
 		THEN,
-		TIMERQ,
 		TOGVIS,
 		TRIGANIM,
 		UPDATEI,


Commit: de5fbf9b008710d75aa1dc9923b4806318de6608
    https://github.com/scummvm/scummvm/commit/de5fbf9b008710d75aa1dc9923b4806318de6608
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-04-30T20:30:41+02:00

Commit Message:
FREESCAPE: added support for using different languages in castle (DOS)

Changed paths:
    engines/freescape/detection.cpp
    engines/freescape/freescape.cpp
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp


diff --git a/engines/freescape/detection.cpp b/engines/freescape/detection.cpp
index 032e9bf425d..097a5e98d48 100644
--- a/engines/freescape/detection.cpp
+++ b/engines/freescape/detection.cpp
@@ -346,7 +346,7 @@ static const ADGameDescription gameDescriptions[] = {
 			{"CMH.EXE", 0, "1f3b67e649e718e239ebfd7c56e96d47", 63040},
 			AD_LISTEND
 		},
-		Common::EN_ANY,
+		Common::UNK_LANG,
 		Common::kPlatformDOS,
 		ADGF_UNSTABLE,
 		GUIO1(GUIO_NOMIDI)
@@ -619,6 +619,19 @@ public:
 	const DebugChannelDef *getDebugChannels() const override {
 		return debugFlagList;
 	}
+	DetectedGame toDetectedGame(const ADDetectedGame &adGame, ADDetectedGameExtraInfo *extraInfo) const override;
 };
 
+DetectedGame FreescapeMetaEngineDetection::toDetectedGame(const ADDetectedGame &adGame, ADDetectedGameExtraInfo *extraInfo) const {
+	DetectedGame game = AdvancedMetaEngineDetection::toDetectedGame(adGame);
+
+	// The AdvancedDetector model only allows specifying a single supported game language.
+	if (game.gameId == "castlemaster" && game.language == Common::UNK_LANG) {
+		game.appendGUIOptions(Common::getGameGUIOptionsDescriptionLanguage(Common::EN_ANY));
+		game.appendGUIOptions(Common::getGameGUIOptionsDescriptionLanguage(Common::FR_FRA));
+		game.appendGUIOptions(Common::getGameGUIOptionsDescriptionLanguage(Common::DE_DEU));
+	}
+	return game;
+}
+
 REGISTER_PLUGIN_STATIC(FREESCAPE_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, FreescapeMetaEngineDetection);
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 007ba3d185f..351b96692db 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -60,6 +60,8 @@ FreescapeEngine::FreescapeEngine(OSystem *syst, const ADGameDescription *gd)
 
 	_variant = gd->flags;
 
+	_language = Common::parseLanguage(ConfMan.get("language"));
+
 	if (!Common::parseBool(ConfMan.get("prerecorded_sounds"), _usePrerecordedSounds))
 		error("Failed to parse bool from prerecorded_sounds option");
 
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 2bf19ab76ef..66d56c02e82 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -95,6 +95,7 @@ public:
 
 	// Game selection
 	uint32 _variant;
+	Common::Language _language;
 	bool isDriller() { return _targetName.hasPrefix("driller") || _targetName.hasPrefix("spacestationoblivion"); }
 	bool isDark() { return _targetName.hasPrefix("darkside"); }
 	bool isEclipse() { return _targetName.hasPrefix("totaleclipse"); }
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index 7943c1a7578..c5747264ea2 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -143,7 +143,23 @@ void CastleEngine::loadAssetsDOSFullGame() {
 		_border->setPalette((byte *)&kCastleBorderDOSPalette, 0, 16);
 		file.close();
 
-		stream = decryptFile("CMLE");
+		switch (_language) {
+			case Common::ES_ESP:
+				stream = decryptFile("CMLS");
+				break;
+			case Common::FR_FRA:
+				stream = decryptFile("CMLF");
+				break;
+			case Common::DE_DEU:
+				stream = decryptFile("CMLG");
+				break;
+			case Common::EN_ANY:
+				stream = decryptFile("CMLE");
+				break;
+			default:
+				error("Invalid or unsupported language: %x", _language);
+		}
+
 		loadMessagesVariableSize(stream, 0x11, 164);
 		delete stream;
 




More information about the Scummvm-git-logs mailing list