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

neuromancer noreply at scummvm.org
Mon Jun 1 21:39:04 UTC 2026


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

Summary:
361a7b6f5c SCUMM: RA2: show virtual keyboard when entering text
ec9b91d1e9 SCUMM: RA1: option to play all the levels


Commit: 361a7b6f5c2926b00ce7458a3f76bf49ce15696e
    https://github.com/scummvm/scummvm/commit/361a7b6f5c2926b00ce7458a3f76bf49ce15696e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-01T23:38:46+02:00

Commit Message:
SCUMM: RA2: show virtual keyboard when entering text

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 5a7221e3ad1..20bd7ef213c 100644
--- a/engines/scumm/insane/rebel2/menu.cpp
+++ b/engines/scumm/insane/rebel2/menu.cpp
@@ -50,6 +50,35 @@ void InsaneRebel2::resetMenu() {
 	_menuInactivityTimer = 0;
 	_menuRepeatDelay = 0;
 	_menuSelectionConfirmed = false;
+	setVirtualKeyboardVisible(false);
+}
+
+bool InsaneRebel2::isMenuTextInputActive() const {
+	if (!_menuInputActive)
+		return false;
+
+	if (_gameState == kStatePilotSelect && _pilotMenuMode == kPilotModeNameInput)
+		return true;
+
+	return _gameState == kStateChapterSelect &&
+	       _chapterSelection >= 0 &&
+	       _chapterSelection < 16 &&
+	       !_chapterUnlocked[_chapterSelection];
+}
+
+void InsaneRebel2::setVirtualKeyboardVisible(bool visible) {
+	if (!_vm->_system->hasFeature(OSystem::kFeatureVirtualKeyboard))
+		return;
+
+	if (_virtualKeyboardActive == visible)
+		return;
+
+	_vm->_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, visible);
+	_virtualKeyboardActive = visible;
+}
+
+void InsaneRebel2::updateMenuVirtualKeyboard() {
+	setVirtualKeyboardVisible(isMenuTextInputActive());
 }
 
 // unlockAllChapters -- Debug mode unlock (FUN_00415CF8 lines 60-71, DAT_0047ab34=='d').
@@ -716,6 +745,7 @@ int InsaneRebel2::runChapterSelect() {
 	_passwordInput = "";
 	_menuRepeatDelay = 0;
 	_gameState = kStateChapterSelect;
+	updateMenuVirtualKeyboard();
 
 	SmushPlayer *splayer = ((ScummEngine_v7 *)_vm)->_splayer;
 
@@ -753,6 +783,7 @@ int InsaneRebel2::runChapterSelect() {
 		splayer->play("OPEN/O_LEVEL.SAN", 12);
 
 		if (_vm->shouldQuit()) {
+			setVirtualKeyboardVisible(false);
 			_menuInputActive = false;
 			return kChapterSelectQuit;
 		}
@@ -771,6 +802,7 @@ int InsaneRebel2::runChapterSelect() {
 		if (_chapterSelection == 16) {
 			// BACK selected (index 16 = 17th item)
 			debug("Rebel2: BACK to main menu selected");
+			setVirtualKeyboardVisible(false);
 			_menuInputActive = false;
 			return kChapterSelectBack;
 		}
@@ -780,6 +812,7 @@ int InsaneRebel2::runChapterSelect() {
 				// Unlocked chapter — play it
 				_selectedChapter = _chapterSelection;
 				debug("Rebel2: Chapter %d selected (unlocked)", _selectedChapter + 1);
+				setVirtualKeyboardVisible(false);
 				_menuInputActive = false;
 				return kChapterSelectPlay;
 			}
@@ -801,6 +834,7 @@ int InsaneRebel2::runChapterSelect() {
 					// Update iactBit for video preview (original jumps to LAB_00415d88)
 					setBit(16 - _chapterSelection);
 					_passwordInput.clear();
+					updateMenuVirtualKeyboard();
 					debug("Rebel2: Chapter %d unlocked via password", _chapterSelection + 1);
 					continue;  // Re-render with updated unlock state
 				}
@@ -811,6 +845,7 @@ int InsaneRebel2::runChapterSelect() {
 		}
 	}
 
+	setVirtualKeyboardVisible(false);
 	_menuInputActive = false;
 	return kChapterSelectQuit;
 }
@@ -838,6 +873,7 @@ int InsaneRebel2::processChapterSelectInput() {
 				_passwordInput.clear();
 				// Update preview offset (FUN_00425170: Y = selected * -50 + 75)
 				_previewOffsetY = _chapterSelection * -50 + 75;
+				updateMenuVirtualKeyboard();
 				debug("ChapterSelect: Selection changed to %d (UP) offsetY=%d", _chapterSelection, _previewOffsetY);
 				break;
 
@@ -850,6 +886,7 @@ int InsaneRebel2::processChapterSelectInput() {
 				_passwordInput.clear();
 				// Update preview offset (FUN_00425170: Y = selected * -50 + 75)
 				_previewOffsetY = _chapterSelection * -50 + 75;
+				updateMenuVirtualKeyboard();
 				debug("ChapterSelect: Selection changed to %d (DOWN) offsetY=%d", _chapterSelection, _previewOffsetY);
 				break;
 
@@ -863,6 +900,7 @@ int InsaneRebel2::processChapterSelectInput() {
 
 			case Common::KEYCODE_ESCAPE:
 				// ESC = Back to main menu (same as selecting BACK)
+				setVirtualKeyboardVisible(false);
 				result = 16;  // BACK index
 				debug("ChapterSelect: ESC pressed - back to menu");
 				break;
@@ -897,6 +935,7 @@ int InsaneRebel2::processChapterSelectInput() {
 					if (event.mouse.y >= itemY - 1 && event.mouse.y < itemY + 9) {
 						_chapterSelection = i;
 						_previewOffsetY = _chapterSelection * -50 + 75;
+						updateMenuVirtualKeyboard();
 						result = _chapterSelection;
 						debug("ChapterSelect: Item %d selected (mouse)", _chapterSelection);
 						break;
@@ -918,6 +957,7 @@ int InsaneRebel2::processChapterSelectInput() {
 						if (i != _chapterSelection) {
 							_chapterSelection = i;
 							_previewOffsetY = _chapterSelection * -50 + 75;
+							updateMenuVirtualKeyboard();
 							debug(5, "ChapterSelect: Hover changed to %d", _chapterSelection);
 						}
 						break;
@@ -1183,6 +1223,7 @@ int InsaneRebel2::runLevelSelect() {
 	_pilotMenuMode = kPilotModeSelect;
 	_pilotNameInput = "";
 	_pilotEditIndex = -1;
+	updateMenuVirtualKeyboard();
 
 	SmushPlayer *splayer = ((ScummEngine_v7 *)_vm)->_splayer;
 
@@ -1195,6 +1236,7 @@ int InsaneRebel2::runLevelSelect() {
 		splayer->play(menuVideo.c_str(), 12);
 
 		if (_vm->shouldQuit()) {
+			setVirtualKeyboardVisible(false);
 			_menuInputActive = false;
 			return kLevelSelectQuit;
 		}
@@ -1233,6 +1275,7 @@ int InsaneRebel2::runLevelSelect() {
 				Common::strlcpy(_pilots[_pilotEditIndex].name, _pilotNameInput.c_str(),
 				                sizeof(_pilots[_pilotEditIndex].name));
 			}
+			setVirtualKeyboardVisible(false);
 			_pilotMenuMode = kPilotModeDifficulty;
 			_gameState = kStateDifficultySelect;
 			_difficultySelection = 2;
@@ -1280,6 +1323,7 @@ int InsaneRebel2::runLevelSelect() {
 
 			debug("Rebel2: Pilot '%s' selected (slot %d, difficulty %d)",
 			      _pilots[_activePilot].name, _activePilot, _difficulty);
+			setVirtualKeyboardVisible(false);
 			_menuInputActive = false;
 			return kLevelSelectPlay;
 
@@ -1291,6 +1335,7 @@ int InsaneRebel2::runLevelSelect() {
 				_pilotNameInput = "";
 				_pilotMenuMode = kPilotModeNameInput;
 				_levelItemCount = _numPilots + 4;
+				updateMenuVirtualKeyboard();
 				debug("Rebel2: NEW PILOT - entering name for slot %d", newIdx);
 			}
 			continue;
@@ -1317,11 +1362,13 @@ int InsaneRebel2::runLevelSelect() {
 
 		} else if (_levelSelection == _numPilots + 3) {
 			// RETURN TO MAIN MENU
+			setVirtualKeyboardVisible(false);
 			_menuInputActive = false;
 			return kLevelSelectBack;
 		}
 	}
 
+	setVirtualKeyboardVisible(false);
 	_menuInputActive = false;
 	return kLevelSelectQuit;
 }
@@ -1343,6 +1390,7 @@ int InsaneRebel2::processLevelSelectInput() {
 				    event.kbd.keycode == Common::KEYCODE_KP_ENTER) {
 					// Confirm name — signal back to runLevelSelect()
 					if (_pilotNameInput.size() > 0) {
+						setVirtualKeyboardVisible(false);
 						_menuSelectionConfirmed = true;
 						_vm->_smushVideoShouldFinish = true;
 						debug("PilotName: confirmed '%s'", _pilotNameInput.c_str());
@@ -1354,6 +1402,7 @@ int InsaneRebel2::processLevelSelectInput() {
 					}
 					_pilotMenuMode = kPilotModeSelect;
 					_levelItemCount = _numPilots + 4;
+					updateMenuVirtualKeyboard();
 					debug("PilotName: cancelled");
 				} else if (event.kbd.keycode == Common::KEYCODE_BACKSPACE) {
 					// Backspace — remove last character
@@ -1378,6 +1427,7 @@ int InsaneRebel2::processLevelSelectInput() {
 				}
 				_pilotMenuMode = kPilotModeSelect;
 				_levelItemCount = _numPilots + 4;
+				updateMenuVirtualKeyboard();
 			}
 		}
 		return -1;
diff --git a/engines/scumm/insane/rebel2/rebel.cpp b/engines/scumm/insane/rebel2/rebel.cpp
index 501186e152b..bfec3000e6a 100644
--- a/engines/scumm/insane/rebel2/rebel.cpp
+++ b/engines/scumm/insane/rebel2/rebel.cpp
@@ -505,6 +505,7 @@ InsaneRebel2::InsaneRebel2(ScummEngine_v7 *scumm) {
 
 	// Initialize menu input capture system
 	_menuInputActive = false;
+	_virtualKeyboardActive = false;
 
 	// Analog stick state for gamepad aiming (mirrors RA1's analog model).
 	// Ingested from EVENT_CUSTOM_BACKEND_ACTION_AXIS, read with a deadzone and
@@ -526,6 +527,8 @@ InsaneRebel2::InsaneRebel2(ScummEngine_v7 *scumm) {
 
 
 InsaneRebel2::~InsaneRebel2() {
+	setVirtualKeyboardVisible(false);
+
 	// Unregister EventObserver
 	_vm->_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
 
@@ -877,6 +880,11 @@ bool InsaneRebel2::notifyEvent(const Common::Event &event) {
 		// consumed (and returned true for) the cases they handle.
 	}
 
+	if (_menuInputActive && isMenuTextInputActive() && event.type == Common::EVENT_KEYDOWN) {
+		_menuEventQueue.push(event);
+		return true;
+	}
+
 	const bool gameplayMenuTrigger = (event.type == Common::EVENT_MAINMENU) ||
 		(event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE);
 	if (gameplayMenuTrigger && _gameState == kStateGameplay && _lastGameplayMenuCloseTime != 0) {
diff --git a/engines/scumm/insane/rebel2/rebel.h b/engines/scumm/insane/rebel2/rebel.h
index 6f24d48a69f..0477679bd45 100644
--- a/engines/scumm/insane/rebel2/rebel.h
+++ b/engines/scumm/insane/rebel2/rebel.h
@@ -57,6 +57,7 @@ public:
 	// Menu input event queue - events are captured by notifyEvent() and processed by processMenuInput()
 	Common::Queue<Common::Event> _menuEventQueue;
 	bool _menuInputActive;  // True when we're capturing menu input events
+	bool _virtualKeyboardActive;
 
 	// ---------------------------------------------------------------------------
 	// Menu System
@@ -125,6 +126,9 @@ public:
 
 	// Reset menu state for fresh start
 	void resetMenu();
+	bool isMenuTextInputActive() const;
+	void setVirtualKeyboardVisible(bool visible);
+	void updateMenuVirtualKeyboard();
 
 	// ---------------------------------------------------------------------------
 	// Chapter Selection Screen (FUN_00415CF8)


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

Commit Message:
SCUMM: RA1: option to play all the levels

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


diff --git a/engines/scumm/detection.h b/engines/scumm/detection.h
index db1da1ba8df..cd6dbfa9d43 100644
--- a/engines/scumm/detection.h
+++ b/engines/scumm/detection.h
@@ -40,6 +40,7 @@ namespace Scumm {
 #define GAMEOPTION_TTS                                       GUIO_GAMEOPTIONS9
 #define GAMEOPTION_REBEL2_HIRES                              GUIO_GAMEOPTIONS10
 #define GAMEOPTION_REBEL2_UNLOCK_ALL                         GUIO_GAMEOPTIONS11
+#define GAMEOPTION_REBEL1_UNLOCK_ALL                         GUIO_GAMEOPTIONS12
 
 /**
  * Descriptor of a specific SCUMM game. Used internally to store
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index b1bcb6e8b46..9c2260772c4 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -228,7 +228,7 @@ static const GameSettings gameVariantsTable[] = {
 	{"ft",   "Remastered", 0, GID_FT,  7, 0, MDT_NONE, GF_DOUBLEFINE_PAK, UNK, GUIO5(GUIO_NOMIDI, GAMEOPTION_ENHANCEMENTS, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO, GAMEOPTION_TTS)},
 	{"ft",   "Demo", 0, GID_FT,  7, 0, MDT_NONE, GF_DEMO, UNK, GUIO4(GUIO_NOMIDI, GAMEOPTION_ORIGINALGUI, GAMEOPTION_LOWLATENCYAUDIO, GAMEOPTION_TTS)},
 
-	{"rebel1", "", 0, GID_REBEL1, 7, 0, MDT_NONE, 0, Common::kPlatformDOS, GUIO1(GUIO_NOMIDI)},
+	{"rebel1", "", 0, GID_REBEL1, 7, 0, MDT_NONE, 0, Common::kPlatformDOS, GUIO2(GUIO_NOMIDI, GAMEOPTION_REBEL1_UNLOCK_ALL)},
 
 	{"rebel2", "", 0, GID_REBEL2, 7, 0, MDT_NONE, 0, Common::kPlatformDOS, GUIO3(GUIO_NOMIDI, GAMEOPTION_REBEL2_HIRES, GAMEOPTION_REBEL2_UNLOCK_ALL)},
 	{"rebel2", "Demo", 0, GID_REBEL2, 7, 0, MDT_NONE, GF_DEMO, Common::kPlatformDOS, GUIO3(GUIO_NOMIDI, GAMEOPTION_REBEL2_HIRES, GAMEOPTION_REBEL2_UNLOCK_ALL)},
diff --git a/engines/scumm/insane/rebel1/menu.cpp b/engines/scumm/insane/rebel1/menu.cpp
index 68bbd4aae9d..2de991ea72b 100644
--- a/engines/scumm/insane/rebel1/menu.cpp
+++ b/engines/scumm/insane/rebel1/menu.cpp
@@ -262,6 +262,18 @@ static void drawRebel1MenuFrame(byte *dst, int pitch, int width, int height, int
 	}
 }
 
+int InsaneRebel1::getMainMenuItemCount() const {
+	return _unlockAllLevels ? kRA1MainMenuItemCount : kRA1MainMenuItemCount - 1;
+}
+
+int InsaneRebel1::getMainMenuResultForSelection(int selection) const {
+	if (selection < 0 || selection >= getMainMenuItemCount())
+		return kRA1MainMenuItemCount;
+	if (_unlockAllLevels || selection < 3)
+		return selection + 1;
+	return selection + 2;
+}
+
 void InsaneRebel1::beginTextEntry(bool passcodeMode) {
 	_textEntryActive = true;
 	_textEntryPasscodeMode = passcodeMode;
@@ -456,15 +468,17 @@ bool InsaneRebel1::handleMenuCommand(RA1MenuCommand command) {
 		}
 	}
 
+	const int mainMenuItemCount = getMainMenuItemCount();
+
 	switch (command) {
 	case kRA1MenuCommandUp:
-		_menuSelection = (_menuSelection + kRA1MainMenuItemCount - 1) % kRA1MainMenuItemCount;
+		_menuSelection = (_menuSelection + mainMenuItemCount - 1) % mainMenuItemCount;
 		return true;
 	case kRA1MenuCommandDown:
-		_menuSelection = (_menuSelection + 1) % kRA1MainMenuItemCount;
+		_menuSelection = (_menuSelection + 1) % mainMenuItemCount;
 		return true;
 	case kRA1MenuCommandCancel:
-		_menuSelection = kRA1MainMenuItemCount - 1;
+		_menuSelection = mainMenuItemCount - 1;
 		// fall through
 	case kRA1MenuCommandAccept:
 		_menuConfirmed = true;
@@ -475,11 +489,15 @@ bool InsaneRebel1::handleMenuCommand(RA1MenuCommand command) {
 	case kRA1MenuCommandSelect3:
 	case kRA1MenuCommandSelect4:
 	case kRA1MenuCommandSelect5:
-	case kRA1MenuCommandSelect6:
-		_menuSelection = command - kRA1MenuCommandSelect1;
+	case kRA1MenuCommandSelect6: {
+		const int selection = command - kRA1MenuCommandSelect1;
+		if (selection >= mainMenuItemCount)
+			return false;
+		_menuSelection = selection;
 		_menuConfirmed = true;
 		_vm->_smushVideoShouldFinish = true;
 		return true;
+	}
 	default:
 		return false;
 	}
@@ -563,7 +581,8 @@ bool InsaneRebel1::handleMenuMouse(const Common::Event &event) {
 		}
 	} else {
 		selection = &_menuSelection;
-		for (int i = 0; i < kRA1MainMenuItemCount; i++) {
+		const int mainMenuItemCount = getMainMenuItemCount();
+		for (int i = 0; i < mainMenuItemCount; i++) {
 			const int frameY = (i + 1) * kRA1MenuRowH + kRA1MainMenuFrameYBase;
 			if (mx >= kRA1MenuFrameX && mx < kRA1MenuFrameX + kRA1MenuFrameW &&
 				my >= frameY && my < frameY + kRA1MenuFrameH) {
@@ -962,7 +981,7 @@ void InsaneRebel1::renderLevelSelectOverlay(byte *dst, int pitch, int width, int
 
 void InsaneRebel1::renderMainMenuItems(byte *dst, int pitch, int width, int height) {
 	// --- Main menu ---
-	const char *kMenuItems[kRA1MainMenuItemCount] = {
+	const char *const kMenuItems[kRA1MainMenuItemCount] = {
 		"START NEW GAME",
 		"GAME OPTIONS",
 		"ENTER PASSCODE",
@@ -970,6 +989,15 @@ void InsaneRebel1::renderMainMenuItems(byte *dst, int pitch, int width, int heig
 		"CONTINUE DEMO",
 		"EXIT TO DOS"
 	};
+	const char *const kMenuItemsLocked[kRA1MainMenuItemCount - 1] = {
+		"START NEW GAME",
+		"GAME OPTIONS",
+		"ENTER PASSCODE",
+		"CONTINUE DEMO",
+		"EXIT TO DOS"
+	};
+	const char *const *menuItems = _unlockAllLevels ? kMenuItems : kMenuItemsLocked;
+	const int mainMenuItemCount = getMainMenuItemCount();
 
 	// Center title
 	const int titleW = getFontBankStringWidth("MAIN MENU");
@@ -977,12 +1005,12 @@ void InsaneRebel1::renderMainMenuItems(byte *dst, int pitch, int width, int heig
 	drawMenuTitleText(dst, pitch, width, height, titleX, 30, "MAIN MENU");
 
 	// Draw menu items centered horizontally
-	for (int i = 0; i < kRA1MainMenuItemCount; i++) {
-		const int textW = getMenuTalkTextWidth(kMenuItems[i]);
+	for (int i = 0; i < mainMenuItemCount; i++) {
+		const int textW = getMenuTalkTextWidth(menuItems[i]);
 		const int textX = getRebel1MenuCenteredX(textW);
 		const int y = 0x3c + i * kRA1MenuRowH;
 
-		drawMenuTalkText(dst, pitch, width, height, textX, y, kMenuItems[i]);
+		drawMenuTalkText(dst, pitch, width, height, textX, y, menuItems[i]);
 
 		if (i == _menuSelection)
 			drawRebel1MenuFrame(dst, pitch, width, height,
@@ -1086,7 +1114,7 @@ int InsaneRebel1::runMainMenu() {
 			return kRA1MainMenuItemCount;
 
 		if (_menuConfirmed)
-			return _menuSelection + 1;
+			return getMainMenuResultForSelection(_menuSelection);
 	}
 
 	return kRA1MainMenuItemCount;
@@ -1197,6 +1225,9 @@ void InsaneRebel1::runOptionsMenu() {
 }
 
 int InsaneRebel1::runLevelSelectMenu() {
+	if (!_unlockAllLevels)
+		return 0;
+
 	_levelSelectSel = CLIP(_startLevel - 1, 0, kRA1NumLevels - 1);
 	_levelSelectActive = true;
 
diff --git a/engines/scumm/insane/rebel1/rebel.cpp b/engines/scumm/insane/rebel1/rebel.cpp
index f8efc33a1ea..d4b1a7929bc 100644
--- a/engines/scumm/insane/rebel1/rebel.cpp
+++ b/engines/scumm/insane/rebel1/rebel.cpp
@@ -312,6 +312,7 @@ InsaneRebel1::InsaneRebel1(ScummEngine_v7 *scumm) : Insane(), _vm(scumm) {
 	_hudRenderFlag = 0;
 	_hudDirtyFlag = 0;
 	_maxChapterUnlocked = 0;
+	_unlockAllLevels = ConfMan.getBool("rebel1_unlock_all");
 	_interactiveVideoActive = false;
 	_restoreInteractiveVideoAudioState = false;
 	memset(_savedInteractiveVideoTrackState, 0, sizeof(_savedInteractiveVideoTrackState));
diff --git a/engines/scumm/insane/rebel1/rebel.h b/engines/scumm/insane/rebel1/rebel.h
index 83e8381390c..eab04823b21 100644
--- a/engines/scumm/insane/rebel1/rebel.h
+++ b/engines/scumm/insane/rebel1/rebel.h
@@ -482,6 +482,7 @@ private:
 	byte _hudRenderFlag;         // 0x7600: 0xFF when HUD should render (set by combat mode handlers)
 	byte _hudDirtyFlag;          // 0x7601: 0xFF after HUD redraw (set by renderHUD)
 	int16 _maxChapterUnlocked;   // 0x7730: highest unlocked passcode slot (0=none)
+	bool _unlockAllLevels;       // ScummVM option: expose level select without passcodes
 
 	static const int16 kMaxHealth = 98;
 	static const int16 kDeathTimerInit = 30;
@@ -543,6 +544,8 @@ private:
 	bool handleMenuMouse(const Common::Event &event);
 	bool handleTextEntryAction(ScummAction action);
 	bool handleTextEntryKey(const Common::Event &event);
+	int getMainMenuItemCount() const;
+	int getMainMenuResultForSelection(int selection) const;
 	void playMenuBackground();
 	bool runTextEntryMenuLoop();
 	void beginTextEntry(bool passcodeMode);
@@ -551,7 +554,7 @@ private:
 	const char *getChapterCompletePassword(int passwordIndex) const;
 	bool _menuActive;
 	bool _menuConfirmed;
-	int _menuSelection; // 0..5 maps to return values 1..6
+	int _menuSelection; // Visible main-menu row; mapped to return values by getMainMenuResultForSelection().
 	int _menuFrameCounter;
 
 	// Options submenu state — RunGameOptionsMenu (0x14B42)
diff --git a/engines/scumm/metaengine.cpp b/engines/scumm/metaengine.cpp
index d0e91a67b89..7c7a5d0396d 100644
--- a/engines/scumm/metaengine.cpp
+++ b/engines/scumm/metaengine.cpp
@@ -896,6 +896,15 @@ static const ExtraGuiOption enableRebel2UnlockAll = {
 	0
 };
 
+const ExtraGuiOption enableRebel1UnlockAll = {
+	_s("Unlock all levels"),
+	_s("All levels will be available without requiring passwords"),
+	"rebel1_unlock_all",
+	false,
+	0,
+	0
+};
+
 const ExtraGuiOptions ScummMetaEngine::getExtraGuiOptions(const Common::String &target) const {
 	ExtraGuiOptions options;
 	// Query the GUI options
@@ -943,6 +952,9 @@ const ExtraGuiOptions ScummMetaEngine::getExtraGuiOptions(const Common::String &
 	if (target.empty() || guiOptions.contains(GAMEOPTION_REBEL2_UNLOCK_ALL)) {
 		options.push_back(enableRebel2UnlockAll);
 	}
+	if (target.empty() || guiOptions.contains(GAMEOPTION_REBEL1_UNLOCK_ALL)) {
+		options.push_back(enableRebel1UnlockAll);
+	}
 	if (target.empty() || gameid == "comi") {
 		options.push_back(comiObjectLabelsOption);
 




More information about the Scummvm-git-logs mailing list