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

neuromancer noreply at scummvm.org
Wed Jun 3 14:46:45 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:
b0f8595f44 SCUMM: RA2: fixed some coloring issue in certain fonts
bdb923e0a3 SCUMM: RA2: ESC should bring the scummvm menu instead of sending enter
faebc8510a SCUMM: RA2: refined controls for level 14


Commit: b0f8595f4414952706e225ae313767680a37b24e
    https://github.com/scummvm/scummvm/commit/b0f8595f4414952706e225ae313767680a37b24e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-03T16:23:44+02:00

Commit Message:
SCUMM: RA2: fixed some coloring issue in certain fonts

Changed paths:
    engines/scumm/smush/rebel/smush_player_ra2.cpp
    engines/scumm/smush/rebel/smush_player_ra2.h


diff --git a/engines/scumm/smush/rebel/smush_player_ra2.cpp b/engines/scumm/smush/rebel/smush_player_ra2.cpp
index 232ab3d9c92..64f483df637 100644
--- a/engines/scumm/smush/rebel/smush_player_ra2.cpp
+++ b/engines/scumm/smush/rebel/smush_player_ra2.cpp
@@ -195,6 +195,82 @@ bool SmushPlayerRebel2::handleGameFetch(int32 subSize, Common::SeekableReadStrea
 	return true;
 }
 
+bool SmushPlayerRebel2::handleGameTextResource(uint32 subType, int32 subSize, Common::SeekableReadStream &b) {
+	if (subType != MKTAG('T','E','X','T') && subType != MKTAG('T','R','E','S'))
+		return false;
+
+	if (subSize < 16) {
+		b.skip(subSize);
+		return true;
+	}
+
+	int posX = b.readSint16LE();
+	int posY = b.readSint16LE();
+	int flags = b.readSint16LE();
+	int left = b.readSint16LE();
+	int top = b.readSint16LE();
+	int width = b.readSint16LE();
+	int height = b.readSint16LE();
+	b.readUint16LE();
+
+	const char *str = nullptr;
+	char *text = nullptr;
+	int consumed = 16;
+
+	if (subType == MKTAG('T','E','X','T')) {
+		const int textSize = subSize - consumed;
+		if (textSize > 0) {
+			text = (char *)malloc(textSize + 1);
+			if (!text) {
+				b.skip(textSize);
+				return true;
+			}
+			b.read(text, textSize);
+			text[textSize] = 0;
+			consumed += textSize;
+			str = text;
+		}
+	} else if (subSize >= consumed + 2) {
+		int stringId = b.readUint16LE();
+		consumed += 2;
+		debugC(DEBUG_SMUSH, "SmushPlayerRebel2::handleGameTextResource: TRES string_id=%d pos=(%d,%d) flags=0x%x clip=(%d,%d,%d,%d) _strings=%p",
+			stringId, posX, posY, flags, left, top, width, height, (void *)_strings);
+		if (_strings)
+			str = _strings->get(stringId);
+	}
+
+	if (consumed < subSize)
+		b.skip(subSize - consumed);
+
+	if (!str) {
+		free(text);
+		return true;
+	}
+
+	int color = 1;
+	int fontId = 0;
+
+	while (str[0] == '^') {
+		if (str[1] == 'f' && Common::isDigit(str[2]) && Common::isDigit(str[3])) {
+			fontId = (str[2] - '0') * 10 + str[3] - '0';
+			str += 4;
+		} else if (str[1] == 'c' && Common::isDigit(str[2]) &&
+				Common::isDigit(str[3]) && Common::isDigit(str[4])) {
+			color = (str[2] - '0') * 100 + (str[3] - '0') * 10 + str[4] - '0';
+			str += 5;
+		} else {
+			break;
+		}
+	}
+
+	TextStyleFlags flg = (TextStyleFlags)(flags & 7);
+	if (ConfMan.getBool("subtitles"))
+		ra2HandleTextResource(str, fontId, color, posX, posY, left, top, width, height, flg);
+
+	free(text);
+	return true;
+}
+
 /**
  * RA2-specific text rendering using SmushMultiFont for inline font switching.
  */
diff --git a/engines/scumm/smush/rebel/smush_player_ra2.h b/engines/scumm/smush/rebel/smush_player_ra2.h
index 415401af885..5f4a33dbae8 100644
--- a/engines/scumm/smush/rebel/smush_player_ra2.h
+++ b/engines/scumm/smush/rebel/smush_player_ra2.h
@@ -38,6 +38,7 @@ protected:
 	void releaseGameVideoState() override;
 	bool shouldPreserveFrameBuffer() const override { return true; }
 	bool handleGameFetch(int32 subSize, Common::SeekableReadStream &b) override;
+	bool handleGameTextResource(uint32 subType, int32 subSize, Common::SeekableReadStream &b) override;
 	bool handleGameTextRendering(const char *str, int fontId, int color, int pos_x, int pos_y, int left, int top, int width, int height, TextStyleFlags flg) override;
 	bool shouldAlwaysShowSubtitles() const override { return true; }
 	SmushFont *getGameFont(int font) override;


Commit: bdb923e0a34e5ed89eb21c21df2a6506676ac224
    https://github.com/scummvm/scummvm/commit/bdb923e0a34e5ed89eb21c21df2a6506676ac224
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-03T16:34:31+02:00

Commit Message:
SCUMM: RA2: ESC should bring the scummvm menu instead of sending enter

Changed paths:
    engines/scumm/insane/rebel2/menu.cpp
    engines/scumm/insane/rebel2/rebel.cpp
    engines/scumm/insane/rebel2/rebel.h


diff --git a/engines/scumm/insane/rebel2/menu.cpp b/engines/scumm/insane/rebel2/menu.cpp
index b238e163ce7..f82fe30354e 100644
--- a/engines/scumm/insane/rebel2/menu.cpp
+++ b/engines/scumm/insane/rebel2/menu.cpp
@@ -114,7 +114,8 @@ Common::String InsaneRebel2::getRandomMenuVideo() {
 //
 // Returns -1 (no action) or a 0-based selected menu item.
 // Events captured by notifyEvent() before ScummEngine consumes them.
-// Keyboard: Up=0x148, Down=0x150, Enter=0x0d, ESC=0x1b.
+// Keyboard: Up=0x148, Down=0x150, Enter=0x0d.
+// Physical ESC is handled by notifyEvent() and opens the ScummVM menu.
 // Mouse mode (DAT_0047a806 == 1): Y position maps to selection.
 //
 int InsaneRebel2::processMenuInput() {
@@ -167,9 +168,9 @@ int InsaneRebel2::processMenuInput() {
 				break;
 
 			case Common::KEYCODE_ESCAPE:
-				// ESC - Quit (last item) - emulates key code 0x1b
+				// Synthetic custom back action - quit/back (last item)
 				result = _menuItemCount - 1;  // Select quit option
-				debug("Menu: ESC pressed - selecting quit (item %d)", result);
+				debug("Menu: Back action - selecting quit (item %d)", result);
 				break;
 
 			default:
@@ -898,10 +899,10 @@ int InsaneRebel2::processChapterSelectInput() {
 				break;
 
 			case Common::KEYCODE_ESCAPE:
-				// ESC = Back to main menu (same as selecting BACK)
+				// Synthetic custom back action (same as selecting BACK)
 				setVirtualKeyboardVisible(false);
 				result = 16;  // BACK index
-				debug("ChapterSelect: ESC pressed - back to menu");
+				debug("ChapterSelect: Back action - back to menu");
 				break;
 
 			case Common::KEYCODE_BACKSPACE:
@@ -1395,7 +1396,7 @@ int InsaneRebel2::processLevelSelectInput() {
 						debug("PilotName: confirmed '%s'", _pilotNameInput.c_str());
 					}
 				} else if (event.kbd.keycode == Common::KEYCODE_ESCAPE) {
-					// Cancel name entry — delete the pilot slot we created
+					// Synthetic custom back action - cancel name entry
 					if (_pilotEditIndex >= 0 && _pilotEditIndex < _numPilots) {
 						deletePilot(_pilotEditIndex);
 					}
diff --git a/engines/scumm/insane/rebel2/rebel.cpp b/engines/scumm/insane/rebel2/rebel.cpp
index 0585d558df7..471d2c96b98 100644
--- a/engines/scumm/insane/rebel2/rebel.cpp
+++ b/engines/scumm/insane/rebel2/rebel.cpp
@@ -97,6 +97,15 @@ bool isRebel2MenuDirectionKey(Common::KeyCode keycode) {
 	       keycode == Common::KEYCODE_RIGHT;
 }
 
+bool isRebel2MenuState(InsaneRebel2::GameState state) {
+	return state == InsaneRebel2::kStateMainMenu ||
+	       state == InsaneRebel2::kStatePilotSelect ||
+	       state == InsaneRebel2::kStateDifficultySelect ||
+	       state == InsaneRebel2::kStateChapterSelect ||
+	       state == InsaneRebel2::kStateOptions ||
+	       state == InsaneRebel2::kStateTopPilots;
+}
+
 InsaneRebel2::InsaneRebel2(ScummEngine_v7 *scumm) {
 	_vm = scumm;
 
@@ -600,6 +609,17 @@ void InsaneRebel2::openGameplayMainMenu(SmushPlayer *splayer) {
 	_lastGameplayMenuCloseTime = _vm->_system->getMillis();
 }
 
+void InsaneRebel2::openMenuMainMenu(SmushPlayer *splayer) {
+	if (splayer && !splayer->_paused) {
+		splayer->pause();
+		_vm->openMainMenuDialog();
+		splayer->unpause();
+		return;
+	}
+
+	_vm->openMainMenuDialog();
+}
+
 // notifyEvent -- EventObserver callback for global input dispatch.
 // Handles ESC (skip) and SPACE (pause) regardless of menu state.
 // Pause behavior matches original FUN_405A21: SPACE pauses, ANY key unpauses.
@@ -752,12 +772,7 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) {
 	if (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START ||
 		event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) {
 		const bool pressed = (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START);
-		const bool menuState = _gameState == kStateMainMenu ||
-		                       _gameState == kStatePilotSelect ||
-		                       _gameState == kStateDifficultySelect ||
-		                       _gameState == kStateChapterSelect ||
-		                       _gameState == kStateOptions ||
-		                       _gameState == kStateTopPilots;
+		const bool menuState = isRebel2MenuState(_gameState);
 
 		if (event.customType == kScummActionInsaneSkip) {
 			if (!pressed)
@@ -787,11 +802,8 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) {
 				return true;
 
 			if (_menuInputActive && menuState) {
-				Common::Event syntheticEvent = Common::Event();
-				syntheticEvent.type = Common::EVENT_KEYDOWN;
-				syntheticEvent.kbd.keycode = Common::KEYCODE_ESCAPE;
-				syntheticEvent.kbd.ascii = Common::ASCII_ESCAPE;
-				_menuEventQueue.push(syntheticEvent);
+				debug("Rebel2: Back/menu action in menu - opening ScummVM menu");
+				openMenuMainMenu(splayer);
 				return true;
 			}
 
@@ -903,6 +915,19 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) {
 		// consumed (and returned true for) the cases they handle.
 	}
 
+	if (_menuInputActive && isRebel2MenuState(_gameState) &&
+			(event.type == Common::EVENT_MAINMENU ||
+			 (event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE))) {
+		if (event.type == Common::EVENT_KEYDOWN && event.kbdRepeat) {
+			debug("Rebel2: Ignoring repeated ESC keydown in menu");
+			return true;
+		}
+
+		debug("Rebel2: Opening ScummVM menu from menu state");
+		openMenuMainMenu(splayer);
+		return true;
+	}
+
 	if (_menuInputActive && isMenuTextInputActive() && event.type == Common::EVENT_KEYDOWN) {
 		_menuEventQueue.push(event);
 		return true;
@@ -962,21 +987,11 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) {
 		switch (event.kbd.keycode) {
 		case Common::KEYCODE_ESCAPE:
 			// ESC handling depends on game state:
-			// - In menus: Select quit option and confirm
+			// - In menus: Open the ScummVM menu (handled above)
 			// - During gameplay: Pause and open ScummVM menu
 			// - During cutscenes/intros: Skip video
 			if (splayer) {
-				if (_menuInputActive && (_gameState == kStateMainMenu ||
-				                          _gameState == kStatePilotSelect ||
-				                          _gameState == kStateDifficultySelect ||
-				                          _gameState == kStateChapterSelect)) {
-					// In menu mode: Select quit option and confirm selection
-					// This emulates the assembly behavior from FUN_0041f5ae
-					_menuSelection = _menuItemCount - 1;  // Select last item (quit/back)
-					_menuSelectionConfirmed = true;
-					debug("Rebel2: ESC pressed in menu - selecting quit (item %d)", _menuSelection);
-					_vm->_smushVideoShouldFinish = true;
-				} else if (_gameState == kStateGameplay && _rebelHandler != 0) {
+				if (_gameState == kStateGameplay && _rebelHandler != 0) {
 					// During active gameplay (handler != 0): pause and open ScummVM menu.
 					debug("Rebel2: ESC pressed during gameplay - opening ScummVM menu");
 					openGameplayMainMenu(splayer);
diff --git a/engines/scumm/insane/rebel2/rebel.h b/engines/scumm/insane/rebel2/rebel.h
index 45ed0628a66..f2d5cdb3f78 100644
--- a/engines/scumm/insane/rebel2/rebel.h
+++ b/engines/scumm/insane/rebel2/rebel.h
@@ -522,6 +522,7 @@ public:
 	uint32 _lastGameplayMenuCloseTime;
 	uint32 _lastMenuGamepadNavigationTime;
 	void openGameplayMainMenu(SmushPlayer *splayer);
+	void openMenuMainMenu(SmushPlayer *splayer);
 	bool isBitSet(int n) override;
 	void setBit(int n) override;
 


Commit: faebc8510ac195db05db3f5b88da549262ee7b5c
    https://github.com/scummvm/scummvm/commit/faebc8510ac195db05db3f5b88da549262ee7b5c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-03T16:46:28+02:00

Commit Message:
SCUMM: RA2: refined controls for level 14

Changed paths:
    engines/scumm/insane/rebel2/rebel.cpp


diff --git a/engines/scumm/insane/rebel2/rebel.cpp b/engines/scumm/insane/rebel2/rebel.cpp
index 471d2c96b98..a777dc8353e 100644
--- a/engines/scumm/insane/rebel2/rebel.cpp
+++ b/engines/scumm/insane/rebel2/rebel.cpp
@@ -56,7 +56,7 @@ const uint32 kRA2MenuGamepadNavigationDebounceMs = 250;
 const uint32 kRA2MenuGamepadMouseSuppressMs = 250;
 
 bool rebel2UsesRelativeGamepadAim(int selectedLevel) {
-	return selectedLevel == 1 || selectedLevel == 5;
+	return selectedLevel == 1 || selectedLevel == 5 || selectedLevel == 14;
 }
 
 bool isRebel2RawMenuAxis(int axis) {
@@ -1680,7 +1680,7 @@ void InsaneRebel2::updateGameplayAimFromGamepad() {
 	bool activeGamepadAim = false;
 
 	if (_rebelHandler == 0x26 && rebel2UsesRelativeGamepadAim(_selectedLevel)) {
-		// Levels 1 and 5 play best with the older mouse-like gamepad behavior from
+		// Levels 1, 5, and 14 play best with the older mouse-like gamepad behavior from
 		// ec305dee371/0025c4e1086: pan the reticle directly and leave it where
 		// the player releases the stick. Later handler 0x26 levels keep the
 		// original-style centered mapping for obstacle avoidance.




More information about the Scummvm-git-logs mailing list