[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