[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