[Scummvm-git-logs] scummvm master -> db7fca93b744d21782a6f6163983efda03a524f2
bluegr
noreply at scummvm.org
Mon Mar 9 20:06:11 UTC 2026
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
db7fca93b7 SCUMM: MI1 SEGA CD - Add the option to use the original 'wait' cursor on the pause menu
Commit: db7fca93b744d21782a6f6163983efda03a524f2
https://github.com/scummvm/scummvm/commit/db7fca93b744d21782a6f6163983efda03a524f2
Author: Robert Megone (robert.megone at gmail.com)
Date: 2026-03-09T22:06:06+02:00
Commit Message:
SCUMM: MI1 SEGA CD - Add the option to use the original 'wait' cursor on the pause menu
Changed paths:
engines/scumm/cursor.cpp
engines/scumm/dialogs.cpp
engines/scumm/dialogs.h
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index b9a1b90cb55..5ddbb08c7f0 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -19,6 +19,7 @@
*
*/
+#include "common/config-manager.h"
#include "common/system.h"
#include "common/macresman.h"
#include "common/util.h"
@@ -217,6 +218,75 @@ static const byte segacd_cross_cursor[256] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};
+// Sega CD Monkey Island wait cursor
+static const byte segacd_wait_cursor_frames[4][160] = {
+ { // frame 0
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF,
+ 0x01, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x01,
+ 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01,
+ 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF
+ },
+ { // frame 1
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF,
+ 0x01, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01,
+ 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x0F, 0x01,
+ 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF
+ },
+ { // frame 2
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF,
+ 0x01, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01,
+ 0x01, 0x0F, 0x01, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01,
+ 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF
+ },
+ { // frame 3
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x01, 0x0F, 0x0F, 0x01, 0xFF,
+ 0x01, 0x0F, 0x0F, 0x01, 0x0F, 0x01, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x01,
+ 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01,
+ 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF, 0xFF, 0x01, 0x0F, 0x0F, 0x0F, 0x0F, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x0F, 0x01, 0x01, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF
+ },
+};
+
+static void buildSegaCdMonkeyPauseCursorFrame(byte *dst16x16, int frame) {
+ const int kOutW = 16;
+ const int kOutH = 16;
+ const int kSrcW = 10;
+ const int kSrcH = 16;
+ const int kXOff = (kOutW - kSrcW) / 2;
+ const int kYOff = 0;
+
+ if (frame < 0)
+ frame = 0;
+ frame &= 3;
+
+ memset(dst16x16, 0xFF, kOutW * kOutH);
+
+ for (int y = 0; y < kSrcH; y++) {
+ for (int x = 0; x < kSrcW; x++) {
+ const byte v = segacd_wait_cursor_frames[frame][y * kSrcW + x];
+
+ if (v != 0xFF) {
+ dst16x16[(y + kYOff) * kOutW + (x + kXOff)] = v;
+ }
+ }
+ }
+}
+
#ifdef ENABLE_SCUMM_7_8
static const byte default_v7_cursor[] = {
0x01,0x01,0x01,0x01, 0x00,0x0F,0x00, 0x01,0x01,0x01,0x01,
@@ -258,6 +328,57 @@ static const byte default_v8_cursor[] = {
#endif
void ScummEngine_v5::animateCursor() {
+ const bool isSegaCdMonkey = (_game.platform == Common::kPlatformSegaCD && _game.id == GID_MONKEY);
+ const bool wantPauseWaitCursor = isSegaCdMonkey && isUsingOriginalGUI() && _mainMenuIsActive && ConfMan.getBool("sega_cd_wait_cursor_when_paused");
+
+ if (wantPauseWaitCursor) {
+ if (_cursor.animate != 2) {
+ _cursor.width = 16;
+ _cursor.height = 16;
+ _cursor.hotspotX = 7;
+ _cursor.hotspotY = 7;
+
+ _cursor.animate = 2;
+ _cursor.animateIndex = 0;
+
+ buildSegaCdMonkeyPauseCursorFrame(_grabbedCursor, 0);
+ updateCursor();
+ return;
+ }
+ } else if (_cursor.animate == 2 && isSegaCdMonkey) {
+ _cursor.animate = 0;
+ _cursor.animateIndex = 0;
+ setBuiltinCursor(0);
+ return;
+ }
+
+
+if (_cursor.animate == 2) {
+ static uint32 sNextTick = 0;
+ static uint8 sFrame = 0;
+ static const uint32 kFrameMs = 200;
+
+ const uint32 now = _system->getMillis();
+
+ if (_cursor.animateIndex == 0) {
+ sFrame = 0;
+ sNextTick = now + kFrameMs;
+ buildSegaCdMonkeyPauseCursorFrame(_grabbedCursor, sFrame);
+ updateCursor();
+ _cursor.animateIndex = 1;
+ return;
+ }
+
+ if ((int32)(now - sNextTick) >= 0) {
+ sFrame = (sFrame + 1) & 3;
+ sNextTick = now + kFrameMs;
+ buildSegaCdMonkeyPauseCursorFrame(_grabbedCursor, sFrame);
+ updateCursor();
+ }
+
+ return;
+}
+
if (_cursor.animate) {
if (!(_cursor.animateIndex & 0x1)) {
setBuiltinCursor((_cursor.animateIndex >> 1) & 3);
@@ -976,6 +1097,25 @@ void ScummEngine_v2::setSnailCursor() {
if (_macGui)
return;
+ // Monkey Island (Sega CD) has an animated wait cursor for the original pause menu.
+ // Only enable it when enabled from the game options dialog.
+ if (_game.platform == Common::kPlatformSegaCD && _game.id == GID_MONKEY &&
+ isUsingOriginalGUI() && _mainMenuIsActive &&
+ ConfMan.getBool("sega_cd_wait_cursor_when_paused")) {
+
+ _cursor.width = 16;
+ _cursor.height = 16;
+ _cursor.hotspotX = 7;
+ _cursor.hotspotY = 7;
+
+ _cursor.animate = 2;
+ _cursor.animateIndex = 0;
+
+ buildSegaCdMonkeyPauseCursorFrame(_grabbedCursor, 0);
+ updateCursor();
+ return;
+ }
+
byte color;
if (_game.platform == Common::kPlatformC64 || _game.platform == Common::kPlatformApple2GS)
color = default_v0_cursor_colors[1];
@@ -1091,24 +1231,28 @@ void ScummEngine_v5::setBuiltinCursor(int idx) {
}
if (_game.platform == Common::kPlatformSegaCD) {
- //_cursor.animate = 0;
- _cursor.width = 16;
- _cursor.height = 16;
- _cursor.hotspotX = 7;
- _cursor.hotspotY = 7;
- byte arr[256];
- for (int i = 0; i < 256; i++) {
- if (segacd_cross_cursor[i] != 0x00)
- arr[i] = segacd_cross_cursor[i];
- else
- arr[i] = 0x01; // TODO: Brown during cutscenes or dialogs (or something else?)
- }
-
+ if (_cursor.animate == 2) {
+ _cursor.animate = 0;
+ _cursor.animateIndex = 0;
+ }
- CursorMan.replaceCursor(arr, 16, 16, 7, 7, 0xFF);
- return;
+ _cursor.width = 16;
+ _cursor.height = 16;
+ _cursor.hotspotX = 7;
+ _cursor.hotspotY = 7;
+
+ byte arr[256];
+ for (int i = 0; i < 256; i++) {
+ if (segacd_cross_cursor[i] != 0x00)
+ arr[i] = segacd_cross_cursor[i];
+ else
+ arr[i] = 0x01; // TODO: Brown during cutscenes or dialogs (or something else?)
}
+ CursorMan.replaceCursor(arr, 16, 16, 7, 7, 0xFF);
+ return;
+}
+
int i, j;
uint16 color;
const uint16 *src = _cursorImages[_currentCursor];
diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp
index b15c11a04d2..852d6773531 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -1221,6 +1221,13 @@ GUI::CheckboxWidget *ScummOptionsContainerWidget::createSegaShadowModeCheckbox(G
);
}
+GUI::CheckboxWidget *ScummOptionsContainerWidget::createSegaCdWaitCursorWhenPausedCheckbox(GuiObject *boss, const Common::String &name) {
+ return new GUI::CheckboxWidget(boss, name,
+ _("Show wait cursor when paused"),
+ _("When paused, show the animated wait cursor from the original Sega CD version.")
+ );
+}
+
GUI::CheckboxWidget *ScummOptionsContainerWidget::createCopyProtectionCheckbox(GuiObject *boss, const Common::String &name) {
return new GUI::CheckboxWidget(boss, name,
_("Enable copy protection"),
@@ -1694,6 +1701,9 @@ MI1CdGameOptionsWidget::MI1CdGameOptionsWidget(GuiObject *boss, const Common::St
if (platform == Common::kPlatformSegaCD)
_enableSegaShadowModeCheckbox = createSegaShadowModeCheckbox(widgetsBoss(), "MI1CdGameOptionsDialog.EnableSegaShadowMode");
+ if (platform == Common::kPlatformSegaCD)
+ _enableSegaCdWaitCursorWhenPausedCheckbox = createSegaCdWaitCursorWhenPausedCheckbox(widgetsBoss(), "MI1CdGameOptionsDialog.EnableSegaCdWaitCursorWhenPaused");
+
GUI::StaticTextWidget *text = new GUI::StaticTextWidget(widgetsBoss(), "MI1CdGameOptionsDialog.IntroAdjustmentLabel", _("Intro Adjust:"));
text->setAlign(Graphics::TextAlign::kTextAlignEnd);
@@ -1729,6 +1739,13 @@ void MI1CdGameOptionsWidget::load() {
if (_enableSegaShadowModeCheckbox)
_enableSegaShadowModeCheckbox->setState(ConfMan.getBool("enable_sega_shadow_mode", _domain));
+ if (_enableSegaCdWaitCursorWhenPausedCheckbox) {
+ bool enabled = false;
+ if (ConfMan.hasKey("sega_cd_wait_cursor_when_paused", _domain))
+ enabled = ConfMan.getBool("sega_cd_wait_cursor_when_paused", _domain);
+ _enableSegaCdWaitCursorWhenPausedCheckbox->setState(enabled);
+ }
+
int introAdjustment = 0;
int outlookAdjustment = 0;
@@ -1755,6 +1772,9 @@ bool MI1CdGameOptionsWidget::save() {
if (_enableSegaShadowModeCheckbox)
ConfMan.setBool("enable_sega_shadow_mode", _enableSegaShadowModeCheckbox->getState(), _domain);
+ if (_enableSegaCdWaitCursorWhenPausedCheckbox)
+ ConfMan.setBool("sega_cd_wait_cursor_when_paused", _enableSegaCdWaitCursorWhenPausedCheckbox->getState(), _domain);
+
ConfMan.setInt("mi1_intro_adjustment", _introAdjustmentSlider->getValue(), _domain);
ConfMan.setInt("mi1_outlook_adjustment", _outlookAdjustmentSlider->getValue(), _domain);
ConfMan.setBool("original_gui", _enableOriginalGUICheckbox->getState(), _domain);
@@ -1777,6 +1797,9 @@ void MI1CdGameOptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common:
if (platform == Common::kPlatformSegaCD)
layouts.addWidget("EnableSegaShadowMode", "Checkbox");
+ if (platform == Common::kPlatformSegaCD)
+ layouts.addWidget("EnableSegaCdWaitCursorWhenPaused", "Checkbox");
+
#ifdef USE_TTS
layouts.addWidget("EnableTTS", "Checkbox");
#endif
diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h
index 094288a1cf9..f0a2ef98c1c 100644
--- a/engines/scumm/dialogs.h
+++ b/engines/scumm/dialogs.h
@@ -241,6 +241,7 @@ protected:
GUI::CheckboxWidget *createOriginalGUICheckbox(GuiObject *boss, const Common::String &name);
GUI::CheckboxWidget *createGammaCorrectionCheckbox(GuiObject *boss, const Common::String &name);
GUI::CheckboxWidget *createSegaShadowModeCheckbox(GuiObject *boss, const Common::String &name);
+ GUI::CheckboxWidget *createSegaCdWaitCursorWhenPausedCheckbox(GuiObject *boss, const Common::String &name);
GUI::CheckboxWidget *createCopyProtectionCheckbox(GuiObject *boss, const Common::String &name);
#ifdef USE_TTS
GUI::CheckboxWidget *createEnableTTSCheckbox(GuiObject *boss, const Common::String &name);
@@ -388,6 +389,7 @@ private:
GUI::CheckboxWidget *_enableOriginalGUICheckbox = nullptr;
GUI::CheckboxWidget *_enableSegaShadowModeCheckbox = nullptr;
+ GUI::CheckboxWidget *_enableSegaCdWaitCursorWhenPausedCheckbox = nullptr;
#ifdef USE_TTS
GUI::CheckboxWidget *_enableTTSCheckbox = nullptr;
#endif
More information about the Scummvm-git-logs
mailing list