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

neuromancer noreply at scummvm.org
Mon Jun 1 11:15:59 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:
fd84ee8ad9 SCUMM: RA1: allow mouse navigation in menus
3143a91c42 SCUMM: RA1: honor subtitles config
c4980b5fc1 SCUMM: RA2: honor subtitles config


Commit: fd84ee8ad906ab655792c72a9da6b58ba1ab039c
    https://github.com/scummvm/scummvm/commit/fd84ee8ad906ab655792c72a9da6b58ba1ab039c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-01T13:15:46+02:00

Commit Message:
SCUMM: RA1: allow mouse navigation in menus

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


diff --git a/engines/scumm/insane/rebel1/menu.cpp b/engines/scumm/insane/rebel1/menu.cpp
index cf8a11e568a..35ecd26bc26 100644
--- a/engines/scumm/insane/rebel1/menu.cpp
+++ b/engines/scumm/insane/rebel1/menu.cpp
@@ -26,6 +26,8 @@
 
 #include "audio/mixer.h"
 
+#include "graphics/cursorman.h"
+
 #include "scumm/scumm_v7.h"
 #include "scumm/smush/smush_player.h"
 #include "scumm/insane/rebel1/rebel.h"
@@ -43,6 +45,14 @@ const int kRA1MenuFrameW = 0xdc;
 const int kRA1MenuFrameH = 0x0f;
 const int kRA1MenuRowH = 0x0f;
 const byte kRA1MenuFrameColor = 0xdf;
+// Highlight-frame geometry shared by the render*Overlay drawing and the mouse hit-testing
+// (clicking menu items is a ScummVM-exclusive feature, so the rects must stay in sync).
+const int kRA1MainMenuFrameYBase    = 0x2c;  // frame Y = (item + 1) * kRA1MenuRowH + this
+const int kRA1OptionsFrameYBase     = 0x1d;  // frame Y = (item + 1) * kRA1MenuRowH + this
+const int kRA1LevelSelectFrameYBase = 0x2c;  // frame Y = row * kRA1MenuRowH + this
+const int kRA1LevelSelectLeftX      = 20;
+const int kRA1LevelSelectRightX     = 170;
+const int kRA1LevelSelectColW       = 130;
 const uint32 kRA1JoystickAxisEscGuardMs = 250;
 // Original picker traversal uses fixed max indices, not strlen(): passcodes
 // stop at 0x1d and high-score names stop at 0x37.
@@ -496,6 +506,70 @@ bool InsaneRebel1::handleControllerMenuAxis(int16 oldAxisX, int16 oldAxisY) {
 	return false;
 }
 
+// ScummVM-exclusive feature (not in the original game): let the player navigate and
+// activate the front-end menus with the mouse. Hovering highlights an item and a left
+// click activates it (same as pressing accept). The item hit-rectangles mirror the
+// highlight frames drawn by the render*Overlay() functions, so they share the
+// kRA1*FrameYBase / kRA1LevelSelect* geometry constants. Returns true if consumed.
+bool InsaneRebel1::handleMenuMouse(const Common::Event &event) {
+	if (!_menuActive || _textEntryActive || _highScoresActive)
+		return false;
+	if (event.type != Common::EVENT_MOUSEMOVE && event.type != Common::EVENT_LBUTTONDOWN)
+		return false;
+
+	const int mx = event.mouse.x;
+	const int my = event.mouse.y;
+	int *selection = nullptr;
+	int hit = -1;
+
+	if (_levelSelectActive) {
+		selection = &_levelSelectSel;
+		for (int i = 0; i < kRA1LevelSelectItemCount; i++) {
+			const int col = i / kRA1LevelSelectRowsPerCol;
+			const int row = i % kRA1LevelSelectRowsPerCol;
+			const int frameX = (col == 0) ? kRA1LevelSelectLeftX : kRA1LevelSelectRightX;
+			const int frameY = row * kRA1MenuRowH + kRA1LevelSelectFrameYBase;
+			if (mx >= frameX && mx < frameX + kRA1LevelSelectColW &&
+				my >= frameY && my < frameY + kRA1MenuFrameH) {
+				hit = i;
+				break;
+			}
+		}
+	} else if (_optionsActive) {
+		selection = &_optionsSel;
+		for (int i = 0; i < kOptionsItemCount; i++) {
+			const int frameY = (i + 1) * kRA1MenuRowH + kRA1OptionsFrameYBase;
+			if (mx >= kRA1MenuFrameX && mx < kRA1MenuFrameX + kRA1MenuFrameW &&
+				my >= frameY && my < frameY + kRA1MenuFrameH) {
+				hit = i;
+				break;
+			}
+		}
+	} else {
+		selection = &_menuSelection;
+		for (int i = 0; i < kRA1MainMenuItemCount; i++) {
+			const int frameY = (i + 1) * kRA1MenuRowH + kRA1MainMenuFrameYBase;
+			if (mx >= kRA1MenuFrameX && mx < kRA1MenuFrameX + kRA1MenuFrameW &&
+				my >= frameY && my < frameY + kRA1MenuFrameH) {
+				hit = i;
+				break;
+			}
+		}
+	}
+
+	if (hit < 0)
+		return false;
+
+	_activeInputSource = kInputSourceMouse;
+	*selection = hit;
+
+	// A left click activates the hovered item, just like pressing accept.
+	if (event.type == Common::EVENT_LBUTTONDOWN)
+		handleMenuCommand(kRA1MenuCommandAccept);
+
+	return true;
+}
+
 bool InsaneRebel1::notifyEvent(const Common::Event &event) {
 	// Global ScummVM dialogs pause the engine while their modal event loop runs.
 	// Do not consume those mouse/key events as RA1 gameplay/menu input, or the
@@ -507,6 +581,10 @@ bool InsaneRebel1::notifyEvent(const Common::Event &event) {
 		_activeInputSource = kInputSourceMouse;
 	}
 
+	// ScummVM-exclusive feature: mouse navigation/clicking of the RA1 front-end menus.
+	if (handleMenuMouse(event))
+		return true;
+
 	if (event.type == Common::EVENT_JOYAXIS_MOTION) {
 		_lastJoystickAxisEventTime = _vm->_system->getMillis();
 		debugC(DEBUG_INSANE, "RA1 input raw-joy-axis: axis=%d pos=%d menu=%d gameplay=%d storedAxis=(%d,%d)",
@@ -772,7 +850,7 @@ void InsaneRebel1::renderOptionsOverlay(byte *dst, int pitch, int width, int hei
 
 		if (i == _optionsSel)
 			drawRebel1MenuFrame(dst, pitch, width, height,
-				kRA1MenuFrameX, (i + 1) * kRA1MenuRowH + 0x1d, kRA1MenuFrameW);
+				kRA1MenuFrameX, (i + 1) * kRA1MenuRowH + kRA1OptionsFrameYBase, kRA1MenuFrameW);
 	}
 }
 
@@ -801,9 +879,9 @@ void InsaneRebel1::renderLevelSelectOverlay(byte *dst, int pitch, int width, int
 	};
 
 	const int menuY = 0x2d;
-	const int leftFrameX = 20;
-	const int rightFrameX = 170;
-	const int columnW = 130;
+	const int leftFrameX = kRA1LevelSelectLeftX;
+	const int rightFrameX = kRA1LevelSelectRightX;
+	const int columnW = kRA1LevelSelectColW;
 
 	for (int i = 0; i < kRA1LevelSelectItemCount; i++) {
 		const int col = i / kRA1LevelSelectRowsPerCol;
@@ -817,7 +895,7 @@ void InsaneRebel1::renderLevelSelectOverlay(byte *dst, int pitch, int width, int
 
 		if (i == _levelSelectSel)
 			drawRebel1MenuFrame(dst, pitch, width, height,
-				frameX, row * kRA1MenuRowH + 0x2c, columnW);
+				frameX, row * kRA1MenuRowH + kRA1LevelSelectFrameYBase, columnW);
 	}
 }
 
@@ -847,13 +925,20 @@ void InsaneRebel1::renderMainMenuItems(byte *dst, int pitch, int width, int heig
 
 		if (i == _menuSelection)
 			drawRebel1MenuFrame(dst, pitch, width, height,
-				kRA1MenuFrameX, (i + 1) * kRA1MenuRowH + 0x2c, kRA1MenuFrameW);
+				kRA1MenuFrameX, (i + 1) * kRA1MenuRowH + kRA1MainMenuFrameYBase, kRA1MenuFrameW);
 	}
 }
 
 void InsaneRebel1::renderMainMenuOverlay(byte *dst, int pitch, int width, int height) {
 	_menuFrameCounter++;
 
+	// ScummVM-exclusive feature: the menus are mouse-clickable, so keep the default
+	// arrow cursor visible. SmushPlayer::play() hides the system cursor for the whole
+	// video (and re-hides it every video), so re-assert visibility each rendered frame
+	// while a menu overlay is on screen. The arrow bitmap/palette is set in
+	// playMenuBackground(); gameplay hides it again via captureInteractiveVideoInput().
+	CursorMan.showMouse(true);
+
 	if (_textEntryActive) {
 		renderTextEntryOverlay(dst, pitch, width, height);
 		return;
@@ -913,6 +998,12 @@ void InsaneRebel1::playMenuBackground() {
 	_menuActive = true;
 	_menuConfirmed = false;
 	_menuFrameCounter = 0;
+	// Show ScummVM's built-in arrow pointer for the (mouse-clickable) menus. Set it once
+	// here; renderMainMenuOverlay() re-asserts showMouse() each frame because the SMUSH
+	// player forces the cursor off while a video plays. disableCursorPalette(false) ensures
+	// the arrow's own CLUT palette is used rather than the game palette.
+	CursorMan.disableCursorPalette(false);
+	CursorMan.setDefaultArrowCursor();
 	clearVideoBuffer();
 	playCinematic("OPEN/O1OPTION.ANM");
 	_menuActive = false;
diff --git a/engines/scumm/insane/rebel1/rebel.h b/engines/scumm/insane/rebel1/rebel.h
index 22f93bd3e49..8bedfdff0e0 100644
--- a/engines/scumm/insane/rebel1/rebel.h
+++ b/engines/scumm/insane/rebel1/rebel.h
@@ -529,6 +529,8 @@ private:
 	bool handleMenuCommand(RA1MenuCommand command);
 	bool handleControllerMenuAction(ScummAction action);
 	bool handleControllerMenuAxis(int16 oldAxisX, int16 oldAxisY);
+	// ScummVM-exclusive feature: navigate/click the menus with the mouse.
+	bool handleMenuMouse(const Common::Event &event);
 	bool handleTextEntryAction(ScummAction action);
 	bool handleTextEntryKey(const Common::Event &event);
 	void playMenuBackground();


Commit: 3143a91c420e08db3fb020ff1d7de0c159b80b3c
    https://github.com/scummvm/scummvm/commit/3143a91c420e08db3fb020ff1d7de0c159b80b3c
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-01T13:15:46+02:00

Commit Message:
SCUMM: RA1: honor subtitles config

Changed paths:
    engines/scumm/insane/rebel1/rebel.cpp
    engines/scumm/smush/rebel/smush_player_ra1.cpp


diff --git a/engines/scumm/insane/rebel1/rebel.cpp b/engines/scumm/insane/rebel1/rebel.cpp
index af3ecab61c7..9b4a89b174f 100644
--- a/engines/scumm/insane/rebel1/rebel.cpp
+++ b/engines/scumm/insane/rebel1/rebel.cpp
@@ -19,6 +19,7 @@
  *
  */
 
+#include "common/config-manager.h"
 #include "common/system.h"
 #include "common/events.h"
 #include "common/endian.h"
@@ -343,7 +344,10 @@ InsaneRebel1::InsaneRebel1(ScummEngine_v7 *scumm) : Insane(), _vm(scumm) {
 	_optRookieOneFemale = false;
 	_optMusicEnabled = !_vm->_mixer->isSoundTypeMuted(Audio::Mixer::kMusicSoundType);
 	_optSfxEnabled = !_vm->_mixer->isSoundTypeMuted(Audio::Mixer::kSFXSoundType);
-	_optTextEnabled = true;
+	// Initialize the dialogue-text (subtitles) toggle from ScummVM's global setting so the
+	// game and the in-game DIALOGUE TEXT menu label reflect it. The menu toggle writes the
+	// same "subtitles" key, and ra1HandleText() gates rendering on it.
+	_optTextEnabled = ConfMan.getBool("subtitles");
 	_optEnhancedControls = true;
 	_optControlsYFlip = false;
 	_optVolume = _vm->_mixer->getVolumeForSoundType(Audio::Mixer::kPlainSoundType) * 127 / Audio::Mixer::kMaxChannelVolume;
diff --git a/engines/scumm/smush/rebel/smush_player_ra1.cpp b/engines/scumm/smush/rebel/smush_player_ra1.cpp
index 6c6712b787c..aa213b17a65 100644
--- a/engines/scumm/smush/rebel/smush_player_ra1.cpp
+++ b/engines/scumm/smush/rebel/smush_player_ra1.cpp
@@ -24,6 +24,7 @@
 // Keep these in a dedicated file so the shared smush_player.cpp stays close
 // to upstream while RA1 behavior is isolated in one place.
 
+#include "common/config-manager.h"
 #include "common/endian.h"
 #include "common/memstream.h"
 
@@ -320,7 +321,13 @@ bool SmushPlayerRebel1::handleGameTextResource(uint32 subType, int32 subSize, Co
 	if (subType != MKTAG('T','E','X','T'))
 		return false;
 
-	ra1HandleText(subSize, b);
+	// RA1 dialogue subtitles. Only render them when subtitles are enabled — this honors
+	// both ScummVM's global "subtitles" setting and the in-game DIALOGUE TEXT toggle
+	// (which writes the same ConfMan key). Still return true so the base handler doesn't
+	// try to parse RA1's custom TEXT format. Querying ConfMan per chunk also lets the
+	// setting take effect mid-video.
+	if (ConfMan.getBool("subtitles"))
+		ra1HandleText(subSize, b);
 	return true;
 }
 


Commit: c4980b5fc133e82742b50b85e8f2810131f0a12d
    https://github.com/scummvm/scummvm/commit/c4980b5fc133e82742b50b85e8f2810131f0a12d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-01T13:15:46+02:00

Commit Message:
SCUMM: RA2: honor subtitles config

Changed paths:
    engines/scumm/insane/rebel2/iact.cpp
    engines/scumm/insane/rebel2/menu.cpp
    engines/scumm/insane/rebel2/rebel.cpp
    engines/scumm/smush/rebel/smush_player_ra2.cpp


diff --git a/engines/scumm/insane/rebel2/iact.cpp b/engines/scumm/insane/rebel2/iact.cpp
index fd69da34581..114ecc49136 100644
--- a/engines/scumm/insane/rebel2/iact.cpp
+++ b/engines/scumm/insane/rebel2/iact.cpp
@@ -19,6 +19,7 @@
  *
  */
 
+#include "common/config-manager.h"
 #include "common/system.h"
 #include "common/memstream.h"
 #include "common/util.h"
@@ -2510,13 +2511,18 @@ void InsaneRebel2::iactRebel2Opcode9(byte *renderBitmap, Common::SeekableReadStr
 	}
 	convertedText[dstIdx] = '\0';
 
-	// Draw the text string (with converted character indices)
-	if (textFlags & 0x04) {
-		// Word-wrapped text
-		_rebelMsgFont->drawStringWrap(convertedText, renderBitmap, clipRect, posX, posY, textColor, styleFlags);
-	} else {
-		// Single-line text
-		_rebelMsgFont->drawString(convertedText, renderBitmap, clipRect, posX, posY, textColor, styleFlags);
+	// Draw the text string (with converted character indices), but only when subtitles are
+	// enabled — opcode 9 is a subtitle/message path, so it honors ScummVM's global
+	// "subtitles" setting and the in-game TEXT toggle (same ConfMan key). The chunk is
+	// still fully parsed above so stream consumption is unaffected.
+	if (ConfMan.getBool("subtitles")) {
+		if (textFlags & 0x04) {
+			// Word-wrapped text
+			_rebelMsgFont->drawStringWrap(convertedText, renderBitmap, clipRect, posX, posY, textColor, styleFlags);
+		} else {
+			// Single-line text
+			_rebelMsgFont->drawString(convertedText, renderBitmap, clipRect, posX, posY, textColor, styleFlags);
+		}
 	}
 
 	debug("Rebel2 Opcode 9: Rendered subtitle at (%d,%d) flags=0x%x clip=(%d,%d,%d,%d)",
diff --git a/engines/scumm/insane/rebel2/menu.cpp b/engines/scumm/insane/rebel2/menu.cpp
index ffe9ccdb0cf..8dfdd0cac36 100644
--- a/engines/scumm/insane/rebel2/menu.cpp
+++ b/engines/scumm/insane/rebel2/menu.cpp
@@ -19,6 +19,7 @@
  *
  */
 
+#include "common/config-manager.h"
 #include "common/system.h"
 #include "common/events.h"
 #include "common/util.h"
@@ -1797,6 +1798,7 @@ int InsaneRebel2::processOptionsInput() {
 					break;
 				case 3:  // Text toggle
 					_optTextEnabled = !_optTextEnabled;
+					ConfMan.setBool("subtitles", _optTextEnabled);
 					break;
 				case 4:  // Controls toggle
 					_optControlsFlipped = !_optControlsFlipped;
diff --git a/engines/scumm/insane/rebel2/rebel.cpp b/engines/scumm/insane/rebel2/rebel.cpp
index ba9e1b5ed92..c843a74296b 100644
--- a/engines/scumm/insane/rebel2/rebel.cpp
+++ b/engines/scumm/insane/rebel2/rebel.cpp
@@ -454,7 +454,10 @@ InsaneRebel2::InsaneRebel2(ScummEngine_v7 *scumm) {
 	_optMusicEnabled = !_vm->_mixer->isSoundTypeMuted(Audio::Mixer::kMusicSoundType);
 	_optSfxEnabled = !_vm->_mixer->isSoundTypeMuted(Audio::Mixer::kSFXSoundType);
 	_optVoicesEnabled = !_vm->_mixer->isSoundTypeMuted(Audio::Mixer::kSpeechSoundType);
-	_optTextEnabled = true;
+	// Initialize the dialogue-text (subtitles) toggle from ScummVM's global setting so the
+	// game and the in-game TEXT menu label reflect it. The menu toggle writes the same
+	// "subtitles" key, which the text-render paths gate on.
+	_optTextEnabled = ConfMan.getBool("subtitles");
 	_optControlsFlipped = false;
 	_optRapidFire = false;
 	_optVolumeLevel = _vm->_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 2;
diff --git a/engines/scumm/smush/rebel/smush_player_ra2.cpp b/engines/scumm/smush/rebel/smush_player_ra2.cpp
index dc0ffb3b21b..1299f5034b0 100644
--- a/engines/scumm/smush/rebel/smush_player_ra2.cpp
+++ b/engines/scumm/smush/rebel/smush_player_ra2.cpp
@@ -24,6 +24,7 @@
 // Overrides the virtual hooks defined in SmushPlayer to provide
 // Rebel Assault 2 specific video, font, text and codec handling.
 
+#include "common/config-manager.h"
 #include "common/endian.h"
 #include "common/rect.h"
 #include "common/system.h"
@@ -189,7 +190,12 @@ bool SmushPlayerRebel2::handleGameFetch(int32 subSize, Common::SeekableReadStrea
 bool SmushPlayerRebel2::handleGameTextRendering(const char *str, int fontId, int color,
 												int pos_x, int pos_y, int left, int top,
 												int width, int height, TextStyleFlags flg) {
-	ra2HandleTextResource(str, fontId, color, pos_x, pos_y, left, top, width, height, flg);
+	// RA2 dialogue subtitles. Only render them when subtitles are enabled — this honors
+	// both ScummVM's global "subtitles" setting and the in-game TEXT toggle (which writes
+	// the same ConfMan key). Still return true so the base handler treats the chunk as
+	// handled. Querying ConfMan per chunk also lets the setting take effect mid-video.
+	if (ConfMan.getBool("subtitles"))
+		ra2HandleTextResource(str, fontId, color, pos_x, pos_y, left, top, width, height, flg);
 	return true;
 }
 




More information about the Scummvm-git-logs mailing list