[Scummvm-git-logs] scummvm master -> 9bd992e4781a11d6ecb6c6a253a54bba33f9f3d6
bluegr
noreply at scummvm.org
Wed Jan 1 12:42:08 UTC 2025
This automated email contains information about 99 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
1510972a6d SCUMM: MACGUI: Add very broken Mac GUI for v6 and v7
f3544d849d SCUMM: MACGUI: More work in progress
27234fff13 SCUMM: MACGUI: Initial "About" implementation for V6-7 games
e830cc9c40 SCUMM: MACGUI: Fix gamma correction for v6-7 About screens
1822cad2cc SCUMM: MACGUI: First attempt at black screen while menu is open
a522f65a60 SCUMM: MACGUI: Fix clearing background on menu activation in v6-7
5cb4e6bae0 SCUMM: MACGUI: Add missing menu for v6-v7
3d62119b70 SCUMM: MACGUI: Very early (very broken) work on the v6-v7 quit dialog
03c6e54643 SCUMM: MACGUI: Implement the rest of the V6-7 quit dialog
9159dfa273 SCUMM: MACGUI: Small cleanup
f35329a88f SCUMM: MACGUI: Simplify v6-v7 dialog border drawing
d253793b22 SCUMM: MACGUI: Black out the screen for all v6-7 dialogs
f07e873e38 SCUMM: MACGUI: Add todo comment
7c1191758a SCUMM: MACGUI: Implement v6 restart dialog
423bbb3cc6 SCUMM: MACGUI: Implement "Skip scene" menu item.
7d3109d0ef SCUMM: MACGUI: Update Mac window manager from SMUSH player
af2a1231cb SCUMM: MACGUI: Use the real palette, not the engine palette
8b6cf94b83 SCUMM: MACGUI: Fix game name in v6-v7 Apple menu
337aa4508b SCUMM: MACGUI: Use _gameName for v6-v7 restart dialog
60fff6d344 SCUMM: MACGUI: Initial v6/v7 save/load dialogs, plus other fixes
15a059ddbd SCUMM: MACGUI: Implement much of the remaining v6-7 menus
25c304f892 SCUMM: MACGUI: Fix bugs in icon loader, plus early v6-7 options dialog
e5b964a24c SCUMM: MACGUI: Complete rework of v6-7 window palettes
645e0297fc SCUMM: MACGUI: Make OK the default button in v6-7 options dialogs
7380767714 SCUMM: MACGUI: Add missing static graphics to DOTT options dialog
2d1ad751b0 SCUMM: MACGUI: Add missing static graphics to Sam & Max options dialog
acaf166943 SCUMM: MACGUI: Add missing static graphics to Full Throttle options
75a54c3298 SCUMM: MACGUI: Add missing static graphics to Maniac Mansion options
c6b5fb6876 SCUMM: MACGUI: Work in progress on the drop down list widget
4c2e85f112 SCUMM: MACGUI: Finish drop down implementation, at least for now
281c2bacbc SCUMM: MACGUI: Combine MacIcon and MacPicture into a single widget
ad87f9305b SCUMM: MACGUI: Fix palette regression with monochrome images
96067ff55a SCUMM: MACGUI: Preliminary work on image slider to support V6-7 sliders
d940e901de SCUMM: MACGUI: The slider widgets sort of work
892f847a6a SCUMM: MACGUI: Use correct bounds for icons
e718203314 SCUMM: MACGUI: Add mechanism to override the calculated slider stops
d4b243bb67 SCUMM: MACGUI: Add "snap while dragging" for MacImageSlider
a40fcc5401 SCUMM: MACGUI: Add support for icon masks
98e470db26 SCUMM: MACGUI: Add missing "override" keyword
16380da1f7 SCUMM: MACGUI: Add support for The Dig Mac demo
9aa269edf7 SCUMM: MACGUI: Add support for Sam & Max demo
4145ac26d9 SCUMM: MACGUI: Fix memory leaks
abd9993850 SCUMM: MACGUI: Allow the Mac Fate of Atlantis demo to run
deda2580cc SCUMM: MACGUI: Remove leftover debug message
7572fba8f3 SCUMM: MACGUI: Hopefully fix palette regression
9d943381ac SCUMM: MACGUI: Attempt to fix menu glitch for earlier games
ac238093f2 SCUMM: MACGUI: Add About dialog for Mac Fate of Atlantis Demo
bee7c7f779 SCUMM: MACGUI: Adjust "About" timing for the Fate of Atlantis Mac Demo
6ecaf36e71 SCUMM: MACGUI: Hopefully fix crash with non-English v6-7 games
267e04ca96 SCUMM: MACGUI: Further tweaks to the Fate of Atlantis demo About dialog
7b0368d79a SCUMM: MACGUI: Hopefully fix detection of floppy Fate of Atlantis
6f911caf73 SCUMM: MACGUI: Simplified Indy 4 floppy version check
b807285ee6 SCUMM: MACGUI: Minor cleanup
a26f5c1853 SCUMM: MACGUI: Fix major oops when dealing with "user items" in dialogs
3dcd69ed18 SCUMM: MACGUI: Silence warning about unknown DITL item
ac9e6adef9 SCUMM: MACGUI: Renamed the drop down list to pop-up menu
3e56e56ee7 SCUMM: MACGUI: Generate pop-up menus from the DITL resource
c45ea28c5d SCUMM: MACGUI: Read menu IDs from MBAR resource where available
4a0de6e4c7 SCUMM: MACGUI: Remove hardcoded "Game" menu name
cb5a60a791 SCUMM: MACGUI: Clarify comment a bit
2c7b998cec SCUMM: MACGUI: Rework the dialog window event loop
e199e1c9e5 SCUMM: MACGUI: Add thumbnail support to V6-7 open dialog. Kind of.
8c86e4547c SCUMM: MACGUI: Fix thumbnail color quantization a bit
76f9ea673f SCUMM: MACGUI: Fix palette glitch
84f4010eba SCUMM: MACGUI: Slightly better color quantization for v6-7 thumbnails
4ac5ae532c SCUMM: MACGUI: Minor cleanup
e3f6937928 SCUMM: MACGUI: Fix regression from using String's Pascal string reader
2e6b5d6778 SCUMM: MACGUI: Enable Mac GUI for Full Throttle demo
92e7d9400f GRAPHICS: MACGUI: Add callback for when the menu is activated
0e82eec28c SCUMM: MACGUI: Use the Mac Window Manager menu activation callback
84dc3e883d SCUMM: MACGUI: Fix About dialog for Full Throttle demo
c474edcf97 SCUMM: MACGUI: Simplify word wrapping in demo About dialogs
528c1899d0 SCUMM: MACGUI: Populate the options dialogs with the actual settings
eeff511c1d SCUMM: (SAM/Mac) - fix icon color init/remap
5b3fc0cdf9 SCUMM: MACGUI: Use ConfMan to retrieve volume settings
4e20519d20 SCUMM: MACGUI: Options dialog cleanup
ee2b30964a SCUMM: cleanup v7/8 specific syncSoundSettings() code
9c6d67b6a1 SCUMM: (SCUMM6/7/Mac) - implement sound mute menu option
55efc98248 SCUMM: (IMS/Mac) - fix volume init values
060c751878 SCUMM: MACGUI: Add very untested code for saving most v6-7 options
e0b5cd8ebe SCUMM: Fix build when v7 and v8 aren't enabled
583ea2667f SCUMM: Remove unnecessary version check from v7 function
10e76ae3e6 SCUMM: MACGUI: Fix Digital iMUSE volume setting.
e88c6fbfba SCUMM: MACGUI: Don't crash on restart if there is no restart dialog
e848d6b3a7 SCUMM: MACGUI: Fix interval for text speed sliders
ba6b348cf5 SCUMM: MACGUI: Word wrap static text widgets by default
8189e25520 SCUMM: MACGUI: Save v6-7 subtitle/voice settings from options dialog
16fa744d9a SCUMM: MACGUI: Implement "Resume Game"
71f592d5c5 SCUMM: Hopefully fix pausing of SMUSH movies
b999d69ef4 SCUMM: MACGUI: Fix v6-7 slider widgets that don't start at 0
76f33960c2 SCUMM: Prevent SMUSH palette changes and screen updates while paused
d192e864f1 SCUMM: MACGUI: Suppress Mac GUI if a message banner is active
a1db6d8f6d IMAGE: Make the mask a Surface instead of a buffer
13263586e8 SCUMM: MACGUI: Don't erase slider handle before it's been drawn
3745e51b01 IMAGE: Remove unnecessary mask-related methods
30b6acf9aa SCUMM: MACGUI: Adapted better color quantizer from Dr. Dobb's
6533fa6217 SCUMM: MACGUI: Fix corner case when reducing the octree
3df5f20e41 SCUMM: MACGUI: Cleanup
9bd992e478 SCUMM: MACGUI: Clean up color quantization code a bit
Commit: 1510972a6d72c8947d73d3f3b9ff31eeffd16633
https://github.com/scummvm/scummvm/commit/1510972a6d72c8947d73d3f3b9ff31eeffd16633
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add very broken Mac GUI for v6 and v7
Changed paths:
A engines/scumm/macgui/macgui_v6.cpp
A engines/scumm/macgui/macgui_v6.h
engines/scumm/macgui/macgui.cpp
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_strings.cpp
engines/scumm/macgui/macgui_v5.cpp
engines/scumm/module.mk
engines/scumm/scumm.cpp
engines/scumm/scumm.h
diff --git a/engines/scumm/macgui/macgui.cpp b/engines/scumm/macgui/macgui.cpp
index 8ecbbffffa3..839abaa8086 100644
--- a/engines/scumm/macgui/macgui.cpp
+++ b/engines/scumm/macgui/macgui.cpp
@@ -27,6 +27,7 @@
#include "scumm/macgui/macgui_indy3.h"
#include "scumm/macgui/macgui_loom.h"
#include "scumm/macgui/macgui_v5.h"
+#include "scumm/macgui/macgui_v6.h"
namespace Scumm {
@@ -46,6 +47,13 @@ MacGui::MacGui(ScummEngine *vm, const Common::Path &resourceFile) {
_impl = new MacV5Gui(vm, resourceFile);
break;
+ case GID_TENTACLE:
+ case GID_SAMNMAX:
+ case GID_DIG:
+ case GID_FT:
+ _impl = new MacV6Gui(vm, resourceFile);
+ break;
+
default:
error("MacGui: Invalid game id %d", vm->_game.id);
break;
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 989965976e7..e93276a9605 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -217,6 +217,10 @@ bool MacGuiImpl::initialize() {
maxMenu = 130;
break;
case GID_MONKEY:
+ case GID_TENTACLE:
+ case GID_SAMNMAX:
+ case GID_DIG:
+ case GID_FT:
maxMenu = 131;
break;
default:
@@ -459,7 +463,7 @@ void MacGuiImpl::updateWindowManager() {
}
}
- if (_vm->_game.version > 3) {
+ if (_vm->_game.version > 3 && _vm->_game.version < 6) {
Graphics::MacMenuItem *windowMenu = menu->getMenuItem("Window");
Graphics::MacMenuItem *hideDesktopMenu = menu->getSubMenuItem(windowMenu, 0);
Graphics::MacMenuItem *hideBarMenu = menu->getSubMenuItem(windowMenu, 1);
diff --git a/engines/scumm/macgui/macgui_strings.cpp b/engines/scumm/macgui/macgui_strings.cpp
index 61a8b1f2491..6153400bddb 100644
--- a/engines/scumm/macgui/macgui_strings.cpp
+++ b/engines/scumm/macgui/macgui_strings.cpp
@@ -603,6 +603,17 @@ static const MacGuiImpl::MacSTRSParsingEntry strsIndy4FloppyVariant2Table[] = {
#undef SKIP_P
bool MacGuiImpl::readStrings() {
+ if (_vm->_game.version >= 6) {
+ // TODO: Fix this!
+ _strsStrings.clear();
+ _strsStrings.reserve(128);
+ for (int i = 0; i < 128; i++) {
+ _strsStrings.emplace_back("");
+ }
+ _strsStrings[kMSIAboutGameName] = "Some Game";
+ return true;
+ }
+
Common::MacResManager resource;
resource.open(_resourceFile);
uint32 strsLen = resource.getResLength(MKTAG('S', 'T', 'R', 'S'), 0);
diff --git a/engines/scumm/macgui/macgui_v5.cpp b/engines/scumm/macgui/macgui_v5.cpp
index 6f137ef3761..8d72691224d 100644
--- a/engines/scumm/macgui/macgui_v5.cpp
+++ b/engines/scumm/macgui/macgui_v5.cpp
@@ -36,7 +36,6 @@
#include "scumm/macgui/macgui_v5.h"
#include "scumm/music.h"
#include "scumm/sound.h"
-#include "scumm/verbs.h"
namespace Scumm {
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
new file mode 100644
index 00000000000..6004a979b04
--- /dev/null
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -0,0 +1,95 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+#include "common/config-manager.h"
+#include "common/macresman.h"
+
+#include "engines/engine.h"
+
+#if 0
+#include "graphics/maccursor.h"
+#include "graphics/macgui/macfontmanager.h"
+#include "graphics/macgui/macwindowmanager.h"
+#include "graphics/surface.h"
+#endif
+
+#include "scumm/scumm.h"
+#include "scumm/detection.h"
+#include "scumm/macgui/macgui_impl.h"
+#include "scumm/macgui/macgui_v6.h"
+
+#if 0
+#include "scumm/music.h"
+#include "scumm/sound.h"
+#include "scumm/verbs.h"
+#endif
+
+namespace Scumm {
+
+// ===========================================================================
+// The Mac SCUMM v6 (and later) GUI.
+// ===========================================================================
+
+MacV6Gui::MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile) : MacGuiImpl(vm, resourceFile) {
+}
+
+const Graphics::Font *MacV6Gui::getFontByScummId(int32 id) {
+ // V5 games do not use CharsetRendererMac
+ return nullptr;
+}
+
+bool MacV6Gui::getFontParams(FontId fontId, int &id, int &size, int &slant) const {
+ return false;
+}
+
+bool MacV6Gui::handleMenu(int id, Common::String &name) {
+ if (MacGuiImpl::handleMenu(id, name))
+ return true;
+
+ return false;
+}
+
+void MacV6Gui::runAboutDialog() {
+}
+
+bool MacV6Gui::runOptionsDialog() {
+ return false;
+}
+
+void MacV6Gui::resetAfterLoad() {
+ reset();
+}
+
+bool MacV6Gui::handleEvent(Common::Event event) {
+ if (MacGuiImpl::handleEvent(event))
+ return true;
+
+ if (_vm->isPaused())
+ return false;
+
+ if (_vm->_userPut <= 0)
+ return false;
+
+ return false;
+}
+
+} // End of namespace Scumm
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
new file mode 100644
index 00000000000..f2353c37137
--- /dev/null
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -0,0 +1,60 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SCUMM_MACGUI_MACGUI_V6_H
+#define SCUMM_MACGUI_MACGUI_V6_H
+
+#include "common/events.h"
+#include "common/rect.h"
+#include "common/str.h"
+
+namespace Scumm {
+
+class MacGuiImpl;
+
+class MacV6Gui : public MacGuiImpl {
+public:
+ MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile);
+ ~MacV6Gui() {}
+
+ const Common::String name() const override { return _strsStrings[kMSIGameName]; }
+ int getNumColors() const override { return 256; }
+
+ bool handleEvent(Common::Event event) override;
+
+ const Graphics::Font *getFontByScummId(int32 id) override;
+
+ void setupCursor(int &width, int &height, int &hotspotX, int &hotspotY, int &animate) override {};
+
+ void resetAfterLoad() override;
+ void update(int delta) override {}
+
+protected:
+ bool getFontParams(FontId fontId, int &id, int &size, int &slant) const override;
+
+ bool handleMenu(int id, Common::String &name) override;
+
+ void runAboutDialog() override;
+ bool runOptionsDialog() override;
+};
+
+} // End of namespace Scumm
+#endif
diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk
index 9741f967bc5..3b770ae2842 100644
--- a/engines/scumm/module.mk
+++ b/engines/scumm/module.mk
@@ -47,6 +47,7 @@ MODULE_OBJS := \
macgui/macgui_loom.o \
macgui/macgui_strings.o \
macgui/macgui_v5.o \
+ macgui/macgui_v6.o \
macgui/macgui_widgets.o \
metaengine.o \
midiparser_ro.o \
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index e0e0cf00c7c..5ad65a8b163 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1223,142 +1223,117 @@ Common::Error ScummEngine::init() {
_macScreen->create(640, _useMacScreenCorrectHeight ? 480 : 400, Graphics::PixelFormat::createFormatCLUT8());
}
+ struct MacFileName {
+ byte _id;
+ const char *_name;
+ };
+
// \xAA is a trademark glyph in Mac OS Roman. We try that, but
// also the Windows version, the UTF-8 version, and just plain
// without in case the file system can't handle exotic
// characters like that.
- if (_game.id == GID_INDY3) {
- static const char *indyFileNames[] = {
- "Indy\xAA",
- "Indy\x99",
- "Indy\xE2\x84\xA2",
- "Indy"
- };
-
- for (int i = 0; i < ARRAYSIZE(indyFileNames); i++) {
- if (resource.exists(indyFileNames[i])) {
- macResourceFile = indyFileNames[i];
-
- _textSurfaceMultiplier = 2;
- // FIXME: THIS IS A TEMPORARY WORKAROUND!
- // The reason why we are initializing the Mac GUI even without original GUI active
- // is because the engine will attempt to load Mac fonts from resources... using the
- // _macGui object. This is not optimal, ideally we would want to decouple resource
- // handling from the responsibilities of a simulated OS interface.
- _macGui = new MacGui(this, macResourceFile);
+ MacFileName macFileNames[] = {
+ { GID_MANIAC, "Day of the Tentacle", },
+ { GID_INDY3, "Indy\xAA" },
+ { GID_INDY3, "Indy\x99" },
+ { GID_INDY3, "Indy\xE2\x84\xA2" },
+ { GID_INDY3, "Indy" },
+ { GID_LOOM, "Loom\xAA" },
+ { GID_LOOM, "Loom\x99" },
+ { GID_LOOM, "Loom\xE2\x84\xA2" },
+ { GID_LOOM, "Loom" },
+ { GID_MONKEY, "Monkey Island" },
+ { GID_INDY4, "Fate of Atlantis" },
+ { GID_INDY4, "Fate of Atlantis 1.1" },
+ { GID_INDY4, "Indy Fate" },
+ { GID_INDY4, "fate v1.5" },
+ { GID_INDY4, "Indy 12/15/92" },
+ { GID_INDY4, "Indy 12-15-92" },
+ { GID_INDY4, "Fate of Atlantis v1.5" },
+ { GID_INDY4, "Fate of Atlantis v.1.5" },
+ { GID_MONKEY2, "LeChuck's Revenge" },
+ { GID_TENTACLE, "Day of the Tentacle" },
+ { GID_SAMNMAX, "Sam & Max" },
+ { GID_DIG, "The Dig" },
+ { GID_FT, "Full Throttle" }
+ };
+
+ bool macScumm = false;
+
+ char filename[40];
+
+ for (int i = 0; i < ARRAYSIZE(macFileNames); i++) {
+ if (_game.id == macFileNames[i]._id) {
+ macScumm = true;
+
+ strncpy(filename, macFileNames[i]._name, sizeof(filename));
+
+ if (resource.exists(filename)) {
+ macResourceFile = filename;
break;
}
- }
- if (macResourceFile.empty()) {
- return Common::Error(Common::kReadingFailed, _("This game requires the 'Indy' Macintosh executable for its fonts."));
- }
+ for (int j = 0; filename[j]; j++)
+ if (filename[j] == ' ')
+ filename[j] = '_';
- } else if (_game.id == GID_LOOM) {
- static const char *loomFileNames[] = {
- "Loom\xAA",
- "Loom\x99",
- "Loom\xE2\x84\xA2",
- "Loom"
- };
-
- for (int i = 0; i < ARRAYSIZE(loomFileNames); i++) {
- if (resource.exists(loomFileNames[i])) {
- macResourceFile = loomFileNames[i];
-
- _textSurfaceMultiplier = 2;
- // FIXME: THIS IS A TEMPORARY WORKAROUND!
- // The reason why we are initializing the Mac GUI even without original GUI active
- // is because the engine will attempt to load Mac fonts from resources... using the
- // _macGui object. This is not optimal, ideally we would want to decouple resource
- // handling from the responsibilities of a simulated OS interface.
- _macGui = new MacGui(this, macResourceFile);
+ if (resource.exists(filename)) {
+ macResourceFile = filename;
break;
}
}
+ }
- if (macResourceFile.empty()) {
- return Common::Error(Common::kReadingFailed, _("This game requires the 'Loom' Macintosh executable for its music and fonts."));
- }
- } else if (_game.id == GID_MONKEY) {
- // Try both with and without underscore in the
- // filename, because some tools (e.g. hfsutils) may
- // turn the space into an underscore.
-
- static const char *monkeyIslandFileNames[] = {
- "Monkey Island",
- "Monkey_Island"
- };
-
- for (int i = 0; i < ARRAYSIZE(monkeyIslandFileNames); i++) {
- if (resource.exists(monkeyIslandFileNames[i])) {
- macResourceFile = monkeyIslandFileNames[i];
- break;
- }
- }
+ if (macScumm) {
+ const char *gameName;
+
+ if (_game.id == GID_MANIAC)
+ gameName = "Maniac Mansion";
+ else if (_game.id == GID_INDY3)
+ gameName = "Indiana Jones and the Last Crusade";
+ else if (_game.id == GID_LOOM)
+ gameName = "Loom";
+ else if (_game.id == GID_MONKEY)
+ gameName = "The Secret of Monkey Island";
+ else if (_game.id == GID_INDY4)
+ gameName = "Indiana Jones and the Fate of Atlantis";
+ else if (_game.id == GID_MONKEY2)
+ gameName = "Monkey Island 2: LeChuck's Revenge";
+ else if (_game.id == GID_TENTACLE)
+ gameName = "The Day of the Tentacle";
+ else if (_game.id == GID_SAMNMAX)
+ gameName = "Sam & Max Hit the Road";
+ else if (_game.id == GID_DIG)
+ gameName = "The Dig";
+ else if (_game.id == GID_FT)
+ gameName = "Full Throttle";
+ else
+ gameName = "Unknown";
if (macResourceFile.empty()) {
- GUI::MessageDialog dialog(_("Could not find the 'Monkey Island' Macintosh executable to read resources\n"
- "and instruments from. Music and Mac GUI will be disabled."), _("OK"));
- dialog.runModal();
- } else if (isUsingOriginalGUI()) {
- _macGui = new MacGui(this, macResourceFile);
- }
- } else if (_game.id == GID_INDY4 && _language != Common::JA_JPN) {
- static const char *indy4FileNames[] = {
- "Fate of Atlantis",
- "Fate_of_Atlantis",
- "Fate of Atlantis 1.1",
- "Fate_of_Atlantis_1.1",
- "Indy Fate",
- "Indy_Fate",
- "fate_v1.5",
- "Indy 12/15/92",
- "Indy_12/15/92",
- "Indy 12-15-92",
- "Indy_12-15-92",
- "Fate of Atlantis v1.5",
- "Fate_of_Atlantis_v1.5",
- "Fate of Atlantis v.1.5",
- "Fate_of_Atlantis_v.1.5"
- };
-
- for (int i = 0; i < ARRAYSIZE(indy4FileNames); i++) {
- if (resource.exists(indy4FileNames[i])) {
- macResourceFile = indy4FileNames[i];
- break;
+ if (_game.id == GID_INDY3) {
+ return Common::Error(Common::kReadingFailed, Common::U32String::format(_("This game requires the '%s' Macintosh executable for its fonts."), gameName));
}
- }
- if (macResourceFile.empty()) {
- GUI::MessageDialog dialog(_("Could not find the 'Fate of Atlantis' Macintosh executable.\n"
- "Mac GUI will not be shown."),
- _("OK"));
- dialog.runModal();
- } else if (isUsingOriginalGUI()) {
- _macGui = new MacGui(this, macResourceFile);
- }
- } else if (_game.id == GID_MONKEY2) {
- static const char *monkeyIsland2FileNames[] = {
- "LeChuck's Revenge",
- "LeChuck's_Revenge"};
-
- for (int i = 0; i < ARRAYSIZE(monkeyIsland2FileNames); i++) {
- if (resource.exists(monkeyIsland2FileNames[i])) {
- macResourceFile = monkeyIsland2FileNames[i];
- break;
+ if (_game.id == GID_LOOM || _game.id == GID_TENTACLE || _game.id == GID_SAMNMAX) {
+ return Common::Error(Common::kReadingFailed, Common::U32String::format(_("This game requires the '%s' Macintosh executable for its music and fonts."), gameName));
}
- }
- if (macResourceFile.empty()) {
- GUI::MessageDialog dialog(_("Could not find the 'LeChuck's Revenge' Macintosh executable.\n"
- "Mac GUI will not be shown."),
- _("OK"));
+ GUI::MessageDialog dialog(Common::U32String::format(
+ _("Could not find the '%s' Macintosh executable to read resources from. Music and Mac GUI will be disabled"), gameName), _("OK"));
dialog.runModal();
- } else if (isUsingOriginalGUI()) {
+ } else if (isUsingOriginalGUI() || _game.id == GID_INDY3 || _game.id == GID_LOOM) {
+ // FIXME: THIS IS A TEMPORARY WORKAROUND!
+ // The reason why we are initializing the Mac GUI even without original GUI active
+ // is because the engine will attempt to load Mac fonts from resources... using the
+ // _macGui object. This is not optimal, ideally we would want to decouple resource
+ // handling from the responsibilities of a simulated OS interface.
_macGui = new MacGui(this, macResourceFile);
}
+
+ if (_game.id == GID_INDY3 || _game.id == GID_LOOM)
+ _textSurfaceMultiplier = 2;
}
if (!macResourceFile.empty()) {
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 3c502e701eb..5cf8e843ae6 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -511,6 +511,7 @@ class ScummEngine : public Engine, public Common::Serializable {
friend class MacIndy3Gui;
friend class MacLoomGui;
friend class MacV5Gui;
+ friend class MacV6Gui;
friend class LogicHEBasketball;
public:
Commit: f3544d849da9750a931e839b971f4ef6d98cc54a
https://github.com/scummvm/scummvm/commit/f3544d849da9750a931e839b971f4ef6d98cc54a
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: More work in progress
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 6004a979b04..b094968dd86 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -25,15 +25,17 @@
#include "engines/engine.h"
+#include "graphics/macgui/macwindowmanager.h"
+
#if 0
#include "graphics/maccursor.h"
#include "graphics/macgui/macfontmanager.h"
-#include "graphics/macgui/macwindowmanager.h"
#include "graphics/surface.h"
#endif
#include "scumm/scumm.h"
#include "scumm/detection.h"
+#include "scumm/file.h"
#include "scumm/macgui/macgui_impl.h"
#include "scumm/macgui/macgui_v6.h"
@@ -62,13 +64,142 @@ bool MacV6Gui::getFontParams(FontId fontId, int &id, int &size, int &slant) cons
}
bool MacV6Gui::handleMenu(int id, Common::String &name) {
- if (MacGuiImpl::handleMenu(id, name))
+ // Don't call the original method. The menus are too different.
+ // TODO: Separate the common code into its own method?
+
+ // This menu item (e.g. a menu separator) has no action, so it's
+ // handled trivially.
+ if (id == 0)
+ return true;
+
+ // This is how we keep the menu bar visible.
+ Graphics::MacMenu *menu = _windowManager->getMenu();
+
+ // If the menu is opened through a shortcut key, force it to activate
+ // to avoid screen corruption. In that case, we also force the menu to
+ // close afterwards, or the game will stay paused. Which is
+ // particularly bad during a restart.
+
+ if (!menu->_active) {
+ _windowManager->activateMenu();
+ _forceMenuClosed = true;
+ }
+
+ menu->closeMenu();
+ menu->setActive(true);
+ menu->setVisible(true);
+ updateWindowManager();
+
+ int saveSlotToHandle = -1;
+ Common::String savegameName;
+
+ // The Dig and Full Throttle don't have a Restart menu entry
+ if (_vm->_game.version > 6 && id >= 204 && id < 300)
+ id++;
+
+ PauseToken token;
+
+ switch (id) {
+ case 100: // About
+ token = _vm->pauseEngine();
+ runAboutDialog();
+ token.clear();
+ return true;
+
+ case 200: // Open
+ debug("Open");
+ if (runOpenDialog(saveSlotToHandle)) {
+ if (saveSlotToHandle > -1) {
+ _vm->loadGameState(saveSlotToHandle);
+ }
+ }
+
+ return true;
+
+ case 201: // Save
+ debug("Save");
+ _vm->beginTextInput();
+ if (runSaveDialog(saveSlotToHandle, savegameName)) {
+ if (saveSlotToHandle > -1) {
+ _vm->saveGameState(saveSlotToHandle, savegameName);
+ }
+ }
+ _vm->endTextInput();
+ return true;
+
+ case 202:
+ debug("Skip scene");
+ return true;
+
+ case 203:
+ debug("Resume");
+ return true;
+
+ case 204: // Restart
+ debug("Restart");
+ if (runRestartDialog())
+ _vm->restart();
+ return true;
+
+ case 205:
+ debug("Preferences");
+ break;
+
+ case 206:
+ debug("Quit");
+ break;
+
+ // In the original, the Edit menu is active during save dialogs, though
+ // only Cut, Copy and Paste.
+
+ case 300: // Undo
+ case 301: // Cut
+ case 302: // Copy
+ case 303: // Paste
+ case 304: // Clear
return true;
+ case 403:
+ debug("Graphics smoothing");
+ break;
+ }
+
return false;
}
void MacV6Gui::runAboutDialog() {
+ ScummFile aboutFile(_vm);
+
+ if (!_vm->openFile(aboutFile, "ABOUT"))
+ return;
+
+ while (!aboutFile.eos()) {
+ uint32 r = aboutFile.readByte();
+ uint32 g = aboutFile.readByte();
+ uint32 b = aboutFile.readByte();
+
+ uint32 color = (r << 16) | (g << 8) | b;
+ }
+
+ aboutFile.close();
+
+ while (!_vm->shouldQuit()) {
+ Common::Event event;
+
+ while (_system->getEventManager()->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ case Common::EVENT_KEYDOWN:
+ return;
+
+ default:
+ break;
+ }
+ }
+
+ _system->delayMillis(10);
+ _system->updateScreen();
+ }
}
bool MacV6Gui::runOptionsDialog() {
Commit: 27234fff136a30120585775e07e800b86e44ace0
https://github.com/scummvm/scummvm/commit/27234fff136a30120585775e07e800b86e44ace0
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Initial "About" implementation for V6-7 games
Changed paths:
engines/scumm/macgui/macgui_strings.cpp
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_strings.cpp b/engines/scumm/macgui/macgui_strings.cpp
index 6153400bddb..3bd2dda5179 100644
--- a/engines/scumm/macgui/macgui_strings.cpp
+++ b/engines/scumm/macgui/macgui_strings.cpp
@@ -610,7 +610,7 @@ bool MacGuiImpl::readStrings() {
for (int i = 0; i < 128; i++) {
_strsStrings.emplace_back("");
}
- _strsStrings[kMSIAboutGameName] = "Some Game";
+ _strsStrings[kMSIAboutGameName] = "About some game...";
return true;
}
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index b094968dd86..ab9f31f71dc 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -25,14 +25,17 @@
#include "engines/engine.h"
+#include "graphics/palette.h"
+#include "graphics/paletteman.h"
#include "graphics/macgui/macwindowmanager.h"
#if 0
#include "graphics/maccursor.h"
#include "graphics/macgui/macfontmanager.h"
-#include "graphics/surface.h"
#endif
+#include "graphics/surface.h"
+
#include "scumm/scumm.h"
#include "scumm/detection.h"
#include "scumm/file.h"
@@ -97,13 +100,9 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
if (_vm->_game.version > 6 && id >= 204 && id < 300)
id++;
- PauseToken token;
-
switch (id) {
case 100: // About
- token = _vm->pauseEngine();
runAboutDialog();
- token.clear();
return true;
case 200: // Open
@@ -169,28 +168,71 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
void MacV6Gui::runAboutDialog() {
ScummFile aboutFile(_vm);
-
if (!_vm->openFile(aboutFile, "ABOUT"))
return;
- while (!aboutFile.eos()) {
- uint32 r = aboutFile.readByte();
- uint32 g = aboutFile.readByte();
- uint32 b = aboutFile.readByte();
+ PauseToken token = _vm->pauseEngine();
+
+ Graphics::Surface *screen = _vm->_macScreen;
+ Graphics::Surface screenCopy;
+ Graphics::Palette paletteCopy = _system->getPaletteManager()->grabPalette(0, 256);
+
+ screenCopy.copyFrom(*screen);
+
+ const int aboutW = 480;
+ const int aboutH = 299;
+
+ Common::Rect aboutArea(aboutW, aboutH);
+
+ const int aboutX = (screen->w - aboutW) / 2;
+ const int aboutY = (screen->h - aboutH) / 2;
+
+ aboutArea.moveTo(aboutX, aboutY);
+
+ Graphics::Surface aboutImage = screen->getSubArea(aboutArea);
+ Graphics::Palette palette(256);
+
+ uint black = 0;
- uint32 color = (r << 16) | (g << 8) | b;
+ for (uint i = 0; i < 256; i++) {
+ byte r = aboutFile.readByte();
+ byte g = aboutFile.readByte();
+ byte b = aboutFile.readByte();
+ palette.set(i, r, g, b);
+
+ if (r == 0 && g == 0 && b == 0)
+ black = i;
+ }
+
+ screen->fillRect(Common::Rect(screen->w, screen->h), black);
+
+ for (int y = 0; y < aboutH; y++) {
+ for (int x = 0; x < aboutW; x++) {
+ byte *dst = (byte *)aboutImage.getBasePtr(x, y);
+ *dst = aboutFile.readByte();
+ }
}
aboutFile.close();
- while (!_vm->shouldQuit()) {
+ _system->getPaletteManager()->setPalette(palette);
+ _system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
+
+ bool done = false;
+
+ while (!_vm->shouldQuit() && !done) {
Common::Event event;
while (_system->getEventManager()->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_LBUTTONDOWN:
+ done = true;
+ break;
+
case Common::EVENT_KEYDOWN:
- return;
+ if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
+ done = true;
+ break;
default:
break;
@@ -200,6 +242,13 @@ void MacV6Gui::runAboutDialog() {
_system->delayMillis(10);
_system->updateScreen();
}
+
+ _system->getPaletteManager()->setPalette(paletteCopy);
+ screen->copyFrom(screenCopy);
+ _system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
+ _system->updateScreen();
+
+ token.clear();
}
bool MacV6Gui::runOptionsDialog() {
Commit: e830cc9c406b7d93ba94f74f5979a26a7c0ee468
https://github.com/scummvm/scummvm/commit/e830cc9c406b7d93ba94f74f5979a26a7c0ee468
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix gamma correction for v6-7 About screens
I was bypassing it by going directly to the palette manager.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index ab9f31f71dc..dbf4835a73f 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -175,7 +175,9 @@ void MacV6Gui::runAboutDialog() {
Graphics::Surface *screen = _vm->_macScreen;
Graphics::Surface screenCopy;
- Graphics::Palette paletteCopy = _system->getPaletteManager()->grabPalette(0, 256);
+ byte paletteCopy[3 * 256];
+
+ memcpy(paletteCopy, _vm->_currentPalette, sizeof(paletteCopy));
screenCopy.copyFrom(*screen);
@@ -190,7 +192,6 @@ void MacV6Gui::runAboutDialog() {
aboutArea.moveTo(aboutX, aboutY);
Graphics::Surface aboutImage = screen->getSubArea(aboutArea);
- Graphics::Palette palette(256);
uint black = 0;
@@ -198,12 +199,13 @@ void MacV6Gui::runAboutDialog() {
byte r = aboutFile.readByte();
byte g = aboutFile.readByte();
byte b = aboutFile.readByte();
- palette.set(i, r, g, b);
+ _vm->setPalColor(i, r, g, b);
if (r == 0 && g == 0 && b == 0)
black = i;
}
+ _vm->updatePalette();
screen->fillRect(Common::Rect(screen->w, screen->h), black);
for (int y = 0; y < aboutH; y++) {
@@ -215,7 +217,6 @@ void MacV6Gui::runAboutDialog() {
aboutFile.close();
- _system->getPaletteManager()->setPalette(palette);
_system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
bool done = false;
@@ -243,9 +244,14 @@ void MacV6Gui::runAboutDialog() {
_system->updateScreen();
}
- _system->getPaletteManager()->setPalette(paletteCopy);
+ byte *p = paletteCopy;
+
+ for (int i = 0; i < 256; i++, p += 3)
+ _vm->setPalColor(i, p[0], p[1], p[2]);
+
screen->copyFrom(screenCopy);
_system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
+ _vm->updatePalette();
_system->updateScreen();
token.clear();
Commit: 1822cad2ccc2e95a25eb17a3cbe4b11ea8448295
https://github.com/scummvm/scummvm/commit/1822cad2ccc2e95a25eb17a3cbe4b11ea8448295
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: First attempt at black screen while menu is open
This doesn't quite work, but I want to save this before trying to fix
it, because it could get so much worse...
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index e93276a9605..474541f506d 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -451,16 +451,11 @@ void MacGuiImpl::updateWindowManager() {
saveMenu->enabled = canSave;
if (isActive) {
- if (!_menuIsActive) {
- _cursorWasVisible = CursorMan.showMouse(true);
- _windowManager->pushCursor(Graphics::MacGUIConstants::kMacCursorArrow);
- }
+ if (!_menuIsActive)
+ onMenuOpen();
} else {
- if (_menuIsActive) {
- if (_windowManager->getCursorType() == Graphics::MacGUIConstants::kMacCursorArrow)
- _windowManager->popCursor();
- CursorMan.showMouse(_cursorWasVisible);
- }
+ if (_menuIsActive)
+ onMenuClose();
}
if (_vm->_game.version > 3 && _vm->_game.version < 6) {
@@ -513,6 +508,17 @@ void MacGuiImpl::updateWindowManager() {
_windowManager->draw();
}
+void MacGuiImpl::onMenuOpen() {
+ _cursorWasVisible = CursorMan.showMouse(true);
+ _windowManager->pushCursor(Graphics::MacGUIConstants::kMacCursorArrow);
+}
+
+void MacGuiImpl::onMenuClose() {
+ if (_windowManager->getCursorType() == Graphics::MacGUIConstants::kMacCursorArrow)
+ _windowManager->popCursor();
+ CursorMan.showMouse(_cursorWasVisible);
+}
+
// ---------------------------------------------------------------------------
// Font handling
// ---------------------------------------------------------------------------
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 67ea4d60edc..7efa767e2c8 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -219,6 +219,8 @@ protected:
Common::String getDialogString(Common::SeekableReadStream *res, int len);
virtual bool handleMenu(int id, Common::String &name);
+ virtual void onMenuOpen();
+ virtual void onMenuClose();
virtual void runAboutDialog() = 0;
virtual bool runOpenDialog(int &saveSlotToHandle);
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index dbf4835a73f..a8a4d241c82 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -55,6 +55,17 @@ namespace Scumm {
// ===========================================================================
MacV6Gui::MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile) : MacGuiImpl(vm, resourceFile) {
+ _backupPalette = nullptr;
+ _backupSurface = nullptr;
+}
+
+MacV6Gui::~MacV6Gui() {
+ if (_backupSurface) {
+ _backupSurface->free();
+ delete _backupSurface;
+ }
+
+ delete _backupPalette;
}
const Graphics::Font *MacV6Gui::getFontByScummId(int32 id) {
@@ -166,6 +177,62 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return false;
}
+void MacV6Gui::onMenuOpen() {
+ MacGuiImpl::onMenuOpen();
+
+ Graphics::Surface *screen = _vm->_macScreen;
+
+ _backupSurface = new Graphics::Surface();
+ _backupSurface->copyFrom(*screen);
+
+ _backupPalette = new byte[256 * 3];
+
+ screen->fillRect(Common::Rect(screen->w, screen->h), 255);
+ memcpy(_backupPalette, _vm->_currentPalette, 256 * 3);
+
+ // HACK: Make sure we have the Mac window manager's preferred colors
+
+ _vm->setPalColor(0, 0, 0, 0); // Black
+ _vm->setPalColor(1, 0x80, 0x80, 0x80); // Gray80
+ _vm->setPalColor(2, 0x88, 0x88, 0x88); // Gray88
+ _vm->setPalColor(3, 0xEE, 0xEE, 0xEE); // GrayEE
+ _vm->setPalColor(4, 0xFF, 0xFF, 0xFF); // White
+ _vm->setPalColor(5, 0x00, 0xFF, 0x00); // Green
+ _vm->setPalColor(6, 0x00, 0xCF, 0x00); // Green2
+
+ for (int i = 7; i < 256; i++)
+ _vm->setPalColor(i, 0, 0, 0);
+
+ _vm->updatePalette();
+ _system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
+ _system->updateScreen();
+
+ // HACK: Make sure the Mac window manager is operating on a blank screen
+ _windowManager->disableScreenCopy();
+ _windowManager->activateScreenCopy();
+}
+
+void MacV6Gui::onMenuClose() {
+ MacGuiImpl::onMenuClose();
+ Graphics::Surface *screen = _vm->_macScreen;
+
+ screen->copyFrom(*_backupSurface);
+
+ byte *p = _backupPalette;
+ for (int i = 0; i < 256; i++, p += 3)
+ _vm->setPalColor(i, p[0], p[1], p[2]);
+
+ _system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
+ _vm->updatePalette();
+
+ _backupSurface->free();
+ delete _backupSurface;
+ _backupSurface = nullptr;
+
+ delete _backupPalette;
+ _backupPalette = nullptr;
+}
+
void MacV6Gui::runAboutDialog() {
ScummFile aboutFile(_vm);
if (!_vm->openFile(aboutFile, "ABOUT"))
@@ -173,17 +240,10 @@ void MacV6Gui::runAboutDialog() {
PauseToken token = _vm->pauseEngine();
- Graphics::Surface *screen = _vm->_macScreen;
- Graphics::Surface screenCopy;
- byte paletteCopy[3 * 256];
-
- memcpy(paletteCopy, _vm->_currentPalette, sizeof(paletteCopy));
-
- screenCopy.copyFrom(*screen);
-
const int aboutW = 480;
const int aboutH = 299;
+ Graphics::Surface *screen = _vm->_macScreen;
Common::Rect aboutArea(aboutW, aboutH);
const int aboutX = (screen->w - aboutW) / 2;
@@ -205,7 +265,8 @@ void MacV6Gui::runAboutDialog() {
black = i;
}
- _vm->updatePalette();
+ // The screen is already black, but what's black in the palette may
+ // have changed. Also, we want to clear the menu area.
screen->fillRect(Common::Rect(screen->w, screen->h), black);
for (int y = 0; y < aboutH; y++) {
@@ -218,6 +279,7 @@ void MacV6Gui::runAboutDialog() {
aboutFile.close();
_system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
+ _vm->updatePalette();
bool done = false;
@@ -244,16 +306,6 @@ void MacV6Gui::runAboutDialog() {
_system->updateScreen();
}
- byte *p = paletteCopy;
-
- for (int i = 0; i < 256; i++, p += 3)
- _vm->setPalColor(i, p[0], p[1], p[2]);
-
- screen->copyFrom(screenCopy);
- _system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
- _vm->updatePalette();
- _system->updateScreen();
-
token.clear();
}
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index f2353c37137..191229c6196 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -31,9 +31,13 @@ namespace Scumm {
class MacGuiImpl;
class MacV6Gui : public MacGuiImpl {
+private:
+ byte *_backupPalette;
+ Graphics::Surface *_backupSurface;
+
public:
MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile);
- ~MacV6Gui() {}
+ ~MacV6Gui();
const Common::String name() const override { return _strsStrings[kMSIGameName]; }
int getNumColors() const override { return 256; }
@@ -51,6 +55,8 @@ protected:
bool getFontParams(FontId fontId, int &id, int &size, int &slant) const override;
bool handleMenu(int id, Common::String &name) override;
+ void onMenuOpen() override;
+ void onMenuClose() override;
void runAboutDialog() override;
bool runOptionsDialog() override;
Commit: a522f65a60275a825e5a8aa88a10fc9ebb7e16b1
https://github.com/scummvm/scummvm/commit/a522f65a60275a825e5a8aa88a10fc9ebb7e16b1
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix clearing background on menu activation in v6-7
Also made some functions overridable, one of which should keep the game
from crashing on exit.
Changed paths:
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 7efa767e2c8..7a63affbda4 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -727,8 +727,8 @@ public:
virtual void resetAfterLoad() = 0;
virtual void update(int delta) = 0;
- bool runQuitDialog();
- bool runRestartDialog();
+ virtual bool runQuitDialog();
+ virtual bool runRestartDialog();
virtual void setupCursor(int &width, int &height, int &hotspotX, int &hotspotY, int &animate) = 0;
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index a8a4d241c82..9ad879862bf 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -208,8 +208,7 @@ void MacV6Gui::onMenuOpen() {
_system->updateScreen();
// HACK: Make sure the Mac window manager is operating on a blank screen
- _windowManager->disableScreenCopy();
- _windowManager->activateScreenCopy();
+ _windowManager->_screenCopy->copyFrom(*screen);
}
void MacV6Gui::onMenuClose() {
@@ -313,6 +312,14 @@ bool MacV6Gui::runOptionsDialog() {
return false;
}
+bool MacV6Gui::runQuitDialog() {
+ return true;
+}
+
+bool MacV6Gui::runRestartDialog() {
+ return true;
+}
+
void MacV6Gui::resetAfterLoad() {
reset();
}
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 191229c6196..f7e6a9dd6ed 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -60,6 +60,8 @@ protected:
void runAboutDialog() override;
bool runOptionsDialog() override;
+ bool runQuitDialog() override;
+ bool runRestartDialog() override;
};
} // End of namespace Scumm
Commit: 5cb4e6bae075a288e57fd66c806ef5c6a588a04b
https://github.com/scummvm/scummvm/commit/5cb4e6bae075a288e57fd66c806ef5c6a588a04b
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add missing menu for v6-v7
I don't know why I thought they should have one menu less.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 474541f506d..08cc39cad3a 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -209,6 +209,8 @@ bool MacGuiImpl::initialize() {
{ 0, nullptr, 0, 0, false }
};
+ // TODO: For V6-7 games we could look at the MBAR resource.
+
Common::String aboutMenuDef = _strsStrings[kMSIAboutGameName].c_str();
int maxMenu = -1;
switch (_vm->_game.id) {
@@ -217,10 +219,6 @@ bool MacGuiImpl::initialize() {
maxMenu = 130;
break;
case GID_MONKEY:
- case GID_TENTACLE:
- case GID_SAMNMAX:
- case GID_DIG:
- case GID_FT:
maxMenu = 131;
break;
default:
Commit: 3d62119b7015182f7f7d2c7992898837af8aea0a
https://github.com/scummvm/scummvm/commit/3d62119b7015182f7f7d2c7992898837af8aea0a
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Very early (very broken) work on the v6-v7 quit dialog
Apparently we need to figure out the appropriate size from the DITL
resource, which doesn't contain that information yet ResEdit somehow
remembers it? Hmm...
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 08cc39cad3a..31ea2864514 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -790,6 +790,11 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
res->skip(len);
break;
}
+ case 32:
+ // Icon
+ res->skip(len);
+ break;
+
case 64:
// Picture
window->addPicture(r, res->readUint16BE(), enabled);
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 9ad879862bf..6f90b66f541 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -156,7 +156,8 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
break;
case 206:
- debug("Quit");
+ if (runQuitDialog())
+ _vm->quitGame();
break;
// In the original, the Edit menu is active during save dialogs, though
@@ -313,6 +314,15 @@ bool MacV6Gui::runOptionsDialog() {
}
bool MacV6Gui::runQuitDialog() {
+ MacDialogWindow *window = createDialog(128);
+
+ Common::Array<int> deferredActionsIds;
+
+ while (!_vm->shouldQuit()) {
+ int clicked = window->runDialog(deferredActionsIds);
+ }
+
+ delete window;
return true;
}
Commit: 03c6e54643168965c9d5d476643ee69d920f5489
https://github.com/scummvm/scummvm/commit/03c6e54643168965c9d5d476643ee69d920f5489
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Implement the rest of the V6-7 quit dialog
It's getting a bit messy, but I'm just exploring...
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index 8130b7df3a9..db05c0a847c 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -79,15 +79,34 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
s->fillRect(r, _white);
if (windowStyle == kWindowStyleNormal) {
- int growths[] = { 1, -3, -1 };
+ if (_gui->_vm->_game.version < 6) {
+ int growths[] = { 1, -3, -1 };
- for (int i = 0; i < ARRAYSIZE(growths); i++) {
- r.grow(growths[i]);
+ for (int i = 0; i < ARRAYSIZE(growths); i++) {
+ r.grow(growths[i]);
+ s->frameRect(r, _black);
+ }
+ } else {
+ uint32 c1 = _gui->_windowManager->findBestColor(0xCC, 0xCC, 0xFF);
+ uint32 c2 = _gui->_windowManager->findBestColor(0xBB, 0xBB, 0xBB);
+ uint32 c3 = _gui->_windowManager->findBestColor(0x66, 0x66, 0x99);
+
+ r.grow(1);
+ s->frameRect(r, _black);
+ r.grow(-2);
+ s->frameRect(r, c2);
+ r.grow(-2);
+ s->frameRect(r, _black);
+
+ s->hLine(r.left - 3, r.top - 3, r.right + 1, c1);
+ s->hLine(r.left, r.bottom, r.right, c1);
+ s->vLine(r.left - 3, r.top - 2, r.bottom + 1, c1);
+ s->vLine(r.right, r.top, r.bottom, c1);
- s->hLine(r.left, r.top, r.right - 1, _black);
- s->hLine(r.left, r.bottom - 1, r.right - 1, _black);
- s->vLine(r.left, r.top + 1, r.bottom - 2, _black);
- s->vLine(r.right - 1, r.top + 1, r.bottom - 2, _black);
+ s->hLine(r.left - 1, r.top - 1, r.right, c3);
+ s->hLine(r.left - 3, r.bottom + 2, r.right + 2, c3);
+ s->vLine(r.left - 1, r.top, r.bottom, c3);
+ s->vLine(r.right + 2, r.top - 3, r.bottom + 1, c3);
}
} else if (windowStyle == kWindowStyleRounded) {
r.grow(1);
@@ -118,6 +137,19 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
// thing that is actually used for is the Edit menu, which we
// don't implement. In ScummVM, the menu bar is just a drawing
// at the point, so we can retouch it to look correct.
+ //
+ // However, the Mac Window Manager's ideas of what's black and
+ // what's white may no longer be valid.
+
+ for (int y = 0; y < 19; y++) {
+ for (int x = 0; x < 640; x++) {
+ uint32 color = realScreen->getPixel(x, y);
+ if (color == _gui->_windowManager->_colorWhite)
+ realScreen->setPixel(x, y, _white);
+ else if (color == _gui->_windowManager->_colorBlack)
+ realScreen->setPixel(x, y, _black);
+ }
+ }
if (menuStyle == kMenuStyleDisabled) {
for (int y = 0; y < 19; y++) {
@@ -130,7 +162,10 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
for (int y = 1; y < 19; y++) {
for (int x = 10; x < 38; x++) {
uint32 color = realScreen->getPixel(x, y);
- realScreen->setPixel(x, y, _gui->_windowManager->inverter(color));
+ if (color == _black)
+ realScreen->setPixel(x, y, _white);
+ else
+ realScreen->setPixel(x, y, _black);
}
}
}
@@ -234,6 +269,12 @@ MacGuiImpl::MacEditText *MacGuiImpl::MacDialogWindow::addEditText(Common::Rect b
return editText;
}
+MacGuiImpl::MacIcon *MacGuiImpl::MacDialogWindow::addIcon(Common::Rect bounds, int id, bool enabled) {
+ MacGuiImpl::MacIcon *icon = new MacIcon(this, bounds, id, false);
+ addWidget(icon, kWidgetIcon);
+ return icon;
+}
+
MacGuiImpl::MacPicture *MacGuiImpl::MacDialogWindow::addPicture(Common::Rect bounds, int id, bool enabled) {
MacGuiImpl::MacPicture *picture = new MacPicture(this, bounds, id, false);
addWidget(picture, kWidgetPicture);
@@ -328,6 +369,11 @@ void MacGuiImpl::MacDialogWindow::undrawBeamCursor() {
}
void MacGuiImpl::MacDialogWindow::update(bool fullRedraw) {
+ if (_dirtyPalette) {
+ _gui->_vm->updatePalette();
+ _dirtyPalette = false;
+ }
+
for (uint i = 0; i < _widgets.size(); i++) {
if (_widgets[i]->isVisible())
_widgets[i]->draw();
@@ -676,6 +722,17 @@ MacGuiImpl::MacWidget *MacGuiImpl::MacDialogWindow::getWidget(MacWidgetType type
return nullptr;
}
+void MacGuiImpl::MacDialogWindow::setPalette(const Graphics::Palette *palette) {
+ for (uint i = 0; i < palette->size(); i++) {
+ byte r, g, b;
+
+ palette->get(i, r, g, b);
+ _gui->_vm->setPalColor(i, r, g, b);
+ }
+
+ _dirtyPalette = true;
+}
+
void MacGuiImpl::MacDialogWindow::drawSprite(const Graphics::Surface *sprite, int x, int y) {
_innerSurface.copyRectToSurface(*sprite, x, y, Common::Rect(sprite->w, sprite->h));
markRectAsDirty(Common::Rect(x, y, x + sprite->w, y + sprite->h));
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 31ea2864514..7433a211651 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -405,8 +405,6 @@ void MacGuiImpl::updateWindowManager() {
// original did allow you to open the menu with Alt even when the
// cursor was visible, so for now it's a feature.
- bool isActive = _windowManager->isMenuActive();
-
bool saveCondition = true;
bool loadCondition = true;
@@ -448,7 +446,7 @@ void MacGuiImpl::updateWindowManager() {
if (saveMenu)
saveMenu->enabled = canSave;
- if (isActive) {
+ if (_windowManager->isMenuActive()) {
if (!_menuIsActive)
onMenuOpen();
} else {
@@ -498,8 +496,6 @@ void MacGuiImpl::updateWindowManager() {
}
}
- _menuIsActive = isActive;
-
if (menu->isVisible())
updatePalette();
@@ -507,11 +503,13 @@ void MacGuiImpl::updateWindowManager() {
}
void MacGuiImpl::onMenuOpen() {
+ _menuIsActive = true;
_cursorWasVisible = CursorMan.showMouse(true);
_windowManager->pushCursor(Graphics::MacGUIConstants::kMacCursorArrow);
}
void MacGuiImpl::onMenuClose() {
+ _menuIsActive = false;
if (_windowManager->getCursorType() == Graphics::MacGUIConstants::kMacCursorArrow)
_windowManager->popCursor();
CursorMan.showMouse(_cursorWasVisible);
@@ -587,6 +585,66 @@ bool MacGuiImpl::getFontParams(FontId fontId, int &id, int &size, int &slant) co
}
}
+// ---------------------------------------------------------------------------
+// Icon loader
+// ---------------------------------------------------------------------------
+
+Graphics::Surface *MacGuiImpl::loadIcon(int id, Graphics::Palette **palette) {
+ Common::MacResManager resource;
+ Graphics::Surface *s = nullptr;
+
+ resource.open(_resourceFile);
+
+ Common::SeekableReadStream *res = resource.getResource(MKTAG('c', 'i', 'c', 'n'), id);
+
+ if (res) {
+ // TODO: This is based on the Pegasus engine. Convert into
+ // common code, perhaps?
+
+ Image::PICTDecoder::PixMap pixMap = Image::PICTDecoder::readPixMap(*res);
+
+ // Mask section
+ res->skip(4);
+ uint16 maskRowBytes = res->readUint16BE();
+ res->skip(3 * 2);
+ res->readUint16BE();
+
+ // Bitmap section
+ res->skip(4);
+ uint16 rowBytes = res->readUint16BE();
+ res->readUint16BE(); // top
+ res->readUint16BE(); // left
+ uint16 height = res->readUint16BE(); // bottom
+ res->readUint16BE(); // right
+
+ // Data section
+ res->skip(4);
+ res->skip(maskRowBytes * height);
+ res->skip(rowBytes * height);
+
+ // Palette
+ res->skip(6);
+ uint numColors = res->readUint16BE() + 1;
+
+ *palette = new Graphics::Palette(numColors);
+
+ for (uint i = 0; i < numColors; i++) {
+ res->skip(2);
+ uint16 r = res->readUint16BE();
+ uint16 g = res->readUint16BE();
+ uint16 b = res->readUint16BE();
+
+ (*palette)->set(i, r >> 8, g >> 8, b >> 8);
+ }
+
+ s = new Graphics::Surface();
+ s->create(pixMap.rowBytes, pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8());
+ res->read(s->getPixels(), pixMap.rowBytes * pixMap.bounds.height());
+ }
+
+ return s;
+}
+
// ---------------------------------------------------------------------------
// PICT loader
// ---------------------------------------------------------------------------
@@ -600,7 +658,7 @@ Graphics::Surface *MacGuiImpl::loadPict(int id) {
Common::SeekableReadStream *res = resource.getResource(MKTAG('P', 'I', 'C', 'T'), id);
Image::PICTDecoder pict;
- if (pict.loadStream(*res)) {
+ if (res && pict.loadStream(*res)) {
const Graphics::Surface *s1 = pict.getSurface();
const byte *palette = pict.getPalette();
@@ -700,13 +758,20 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
// Compensate for the original not drawing the game at the very top of
// the screen.
bounds.translate(0, -40);
- } else {
+ } else if (_vm->_game.version < 6) {
bounds.top = 0;
bounds.left = 0;
bounds.bottom = 86;
bounds.right = 340;
bounds.translate(86, 88);
+ } else {
+ bounds.top = 0;
+ bounds.left = 0;
+ bounds.bottom = 113;
+ bounds.right = 267;
+
+ bounds.translate(187, 94);
}
delete res;
@@ -792,7 +857,7 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
}
case 32:
// Icon
- res->skip(len);
+ window->addIcon(r, res->readUint16BE(), enabled);
break;
case 64:
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 7a63affbda4..2a77a7afcbe 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -44,6 +44,7 @@ class OSystem;
namespace Graphics {
struct Surface;
+class Palette;
class MacWindowManager;
}
@@ -125,6 +126,7 @@ public:
kWidgetCheckbox,
kWidgetStaticText,
kWidgetEditText,
+ kWidgetIcon,
kWidgetPicture,
kWidgetSlider,
kWidgetListBox,
@@ -432,6 +434,21 @@ public:
void handleMouseMove(Common::Event &event) override;
};
+ class MacIcon : public MacWidget {
+ private:
+ Graphics::Surface *_icon = nullptr;
+ Graphics::Palette *_palette = nullptr;
+
+ public:
+ MacIcon(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, int id, bool enabled);
+ ~MacIcon();
+
+ Graphics::Palette *getPalette() const { return _palette; }
+ Graphics::Surface *getIcon() const { return _icon; }
+
+ void draw(bool drawFocused = false);
+ };
+
class MacPicture : public MacWidget {
private:
Graphics::Surface *_picture = nullptr;
@@ -625,6 +642,7 @@ public:
Common::StringArray _substitutions;
Common::Array<Common::Rect> _dirtyRects;
+ bool _dirtyPalette = false;
void copyToScreen(Graphics::Surface *s = nullptr) const;
@@ -663,6 +681,7 @@ public:
MacGuiImpl::MacCheckbox *addCheckbox(Common::Rect bounds, Common::String text, bool enabled);
MacGuiImpl::MacStaticText *addStaticText(Common::Rect bounds, Common::String text, bool enabled, Graphics::TextAlign alignment = Graphics::kTextAlignLeft);
MacGuiImpl::MacEditText *addEditText(Common::Rect bounds, Common::String text, bool enabled);
+ MacGuiImpl::MacIcon *addIcon(Common::Rect bounds, int id, bool enabled);
MacGuiImpl::MacPicture *addPicture(Common::Rect bounds, int id, bool enabled);
MacGuiImpl::MacSlider *addSlider(int x, int y, int h, int minValue, int maxValue, int pageSize, bool enabled);
MacGuiImpl::MacPictureSlider *addPictureSlider(int backgroundId, int handleId, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin = 0, int rightMargin = 0);
@@ -683,6 +702,7 @@ public:
void drawDottedHLine(int x0, int y, int x1);
void fillPattern(Common::Rect r, uint16 pattern, bool fillBlack = true, bool fillWhite = true);
+ void setPalette(const Graphics::Palette *palette);
void drawSprite(const Graphics::Surface *sprite, int x, int y);
void drawSprite(const Graphics::Surface *sprite, int x, int y, Common::Rect clipRect);
void drawTexts(Common::Rect r, const TextLine *lines, bool inverse = false);
@@ -698,8 +718,8 @@ public:
virtual int getNumColors() const = 0;
Graphics::Surface *surface() { return _surface; }
- uint32 getBlack() const;
- uint32 getWhite() const;
+ virtual uint32 getBlack() const;
+ virtual uint32 getWhite() const;
virtual const Common::String name() const = 0;
@@ -720,6 +740,7 @@ public:
const Graphics::Font *getFont(FontId fontId);
virtual const Graphics::Font *getFontByScummId(int32 id) = 0;
+ Graphics::Surface *loadIcon(int id, Graphics::Palette **palette);
Graphics::Surface *loadPict(int id);
virtual bool isVerbGuiActive() const { return false; }
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 6f90b66f541..b22e252eaf3 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -178,6 +178,14 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return false;
}
+uint32 MacV6Gui::getBlack() const {
+ return 255;
+}
+
+uint32 MacV6Gui::getWhite() const {
+ return 251;
+}
+
void MacV6Gui::onMenuOpen() {
MacGuiImpl::onMenuOpen();
@@ -191,19 +199,30 @@ void MacV6Gui::onMenuOpen() {
screen->fillRect(Common::Rect(screen->w, screen->h), 255);
memcpy(_backupPalette, _vm->_currentPalette, 256 * 3);
- // HACK: Make sure we have the Mac window manager's preferred colors
-
- _vm->setPalColor(0, 0, 0, 0); // Black
- _vm->setPalColor(1, 0x80, 0x80, 0x80); // Gray80
- _vm->setPalColor(2, 0x88, 0x88, 0x88); // Gray88
- _vm->setPalColor(3, 0xEE, 0xEE, 0xEE); // GrayEE
- _vm->setPalColor(4, 0xFF, 0xFF, 0xFF); // White
- _vm->setPalColor(5, 0x00, 0xFF, 0x00); // Green
- _vm->setPalColor(6, 0x00, 0xCF, 0x00); // Green2
-
- for (int i = 7; i < 256; i++)
+ for (int i = 0; i < 256; i++)
_vm->setPalColor(i, 0, 0, 0);
+ // HACK: Make sure we have the Mac window manager's preferred colors
+ // and other GUI elements. We put it at the end, because the beginning
+ // of the palette is reserved for icon palettes.
+ //
+ // TODO: Make sure that this palette doesn't get overwritten!
+ //
+ // TODO: Make sure this palette is available to the GUI even when the
+ // menu hasn't been opened by mouseover!
+
+ _vm->setPalColor(255, 0, 0, 0); // Black
+ _vm->setPalColor(254, 0x80, 0x80, 0x80); // Gray80
+ _vm->setPalColor(253, 0x88, 0x88, 0x88); // Gray88
+ _vm->setPalColor(252, 0xEE, 0xEE, 0xEE); // GrayEE
+ _vm->setPalColor(251, 0xFF, 0xFF, 0xFF); // White
+ _vm->setPalColor(250, 0x00, 0xFF, 0x00); // Green
+ _vm->setPalColor(249, 0x00, 0xCF, 0x00); // Green2
+
+ _vm->setPalColor(248, 0xCC, 0xCC, 0xFF);
+ _vm->setPalColor(247, 0xBB, 0xBB, 0xBB);
+ _vm->setPalColor(246, 0x66, 0x66, 0x99);
+
_vm->updatePalette();
_system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
_system->updateScreen();
@@ -316,14 +335,33 @@ bool MacV6Gui::runOptionsDialog() {
bool MacV6Gui::runQuitDialog() {
MacDialogWindow *window = createDialog(128);
+ MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
+ MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
+ MacStaticText *textWidget = (MacStaticText *)window->getWidget(kWidgetStaticText);
+
+ textWidget->setWordWrap(true);
+
+ window->setDefaultWidget(buttonOk);
+
Common::Array<int> deferredActionsIds;
+ // When quitting, the default action is to quit
+ bool ret = true;
+
while (!_vm->shouldQuit()) {
int clicked = window->runDialog(deferredActionsIds);
+
+ if (clicked == buttonOk->getId())
+ break;
+
+ if (clicked == buttonCancel->getId()) {
+ ret = false;
+ break;
+ }
}
delete window;
- return true;
+ return ret;
}
bool MacV6Gui::runRestartDialog() {
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index f7e6a9dd6ed..4f5800bc44c 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -39,6 +39,9 @@ public:
MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile);
~MacV6Gui();
+ uint32 getBlack() const override;
+ uint32 getWhite() const override;
+
const Common::String name() const override { return _strsStrings[kMSIGameName]; }
int getNumColors() const override { return 256; }
@@ -55,7 +58,8 @@ protected:
bool getFontParams(FontId fontId, int &id, int &size, int &slant) const override;
bool handleMenu(int id, Common::String &name) override;
- void onMenuOpen() override;
+
+ void onMenuOpen() override;
void onMenuClose() override;
void runAboutDialog() override;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 391949f38e5..03df9f32b23 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -803,6 +803,34 @@ void MacGuiImpl::MacEditText::handleMouseMove(Common::Event &event) {
updateSelection(event.mouse.x, event.mouse.y);
}
+// ---------------------------------------------------------------------------
+// Icon widget
+// ---------------------------------------------------------------------------
+
+MacGuiImpl::MacIcon::MacIcon(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, int id, bool enabled) : MacWidget(window, bounds, "Icon", enabled) {
+ _icon = _window->_gui->loadIcon(id, &_palette);
+}
+
+MacGuiImpl::MacIcon::~MacIcon() {
+ if (_icon) {
+ _icon->free();
+ delete _icon;
+ }
+}
+
+void MacGuiImpl::MacIcon::draw(bool drawFocused) {
+ if (!_redraw && !_fullRedraw)
+ return;
+
+ debug(1, "MacGuiImpl::MacIcon: Drawing icon %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
+
+ _window->setPalette(_palette);
+ _window->drawSprite(_icon, _bounds.left, _bounds.top);
+
+ _redraw = false;
+ _fullRedraw = false;
+}
+
// ---------------------------------------------------------------------------
// Picture widget
// ---------------------------------------------------------------------------
Commit: 9159dfa2733bf7e03e03ebb7716104c732c845cc
https://github.com/scummvm/scummvm/commit/9159dfa2733bf7e03e03ebb7716104c732c845cc
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Small cleanup
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index db05c0a847c..c5194e361d6 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -141,13 +141,18 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
// However, the Mac Window Manager's ideas of what's black and
// what's white may no longer be valid.
- for (int y = 0; y < 19; y++) {
- for (int x = 0; x < 640; x++) {
- uint32 color = realScreen->getPixel(x, y);
- if (color == _gui->_windowManager->_colorWhite)
- realScreen->setPixel(x, y, _white);
- else if (color == _gui->_windowManager->_colorBlack)
- realScreen->setPixel(x, y, _black);
+ uint32 macWhite = _gui->_windowManager->_colorWhite;
+ uint32 macBlack = _gui->_windowManager->_colorBlack;
+
+ if (macWhite != _white || macBlack != _black) {
+ for (int y = 0; y < 19; y++) {
+ for (int x = 0; x < realScreen->w; x++) {
+ uint32 color = realScreen->getPixel(x, y);
+ if (color == macWhite)
+ realScreen->setPixel(x, y, _white);
+ else if (color == macBlack)
+ realScreen->setPixel(x, y, _black);
+ }
}
}
Commit: f35329a88fa4e639b27f088850de04ed29156ad4
https://github.com/scummvm/scummvm/commit/f35329a88fa4e639b27f088850de04ed29156ad4
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Simplify v6-v7 dialog border drawing
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index c5194e361d6..90655beaebb 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -87,26 +87,17 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
s->frameRect(r, _black);
}
} else {
- uint32 c1 = _gui->_windowManager->findBestColor(0xCC, 0xCC, 0xFF);
- uint32 c2 = _gui->_windowManager->findBestColor(0xBB, 0xBB, 0xBB);
- uint32 c3 = _gui->_windowManager->findBestColor(0x66, 0x66, 0x99);
+ uint32 light = _gui->_windowManager->findBestColor(0xCC, 0xCC, 0xFF);
+ uint32 medium = _gui->_windowManager->findBestColor(0xBB, 0xBB, 0xBB);
+ uint32 dark = _gui->_windowManager->findBestColor(0x66, 0x66, 0x99);
- r.grow(1);
s->frameRect(r, _black);
- r.grow(-2);
- s->frameRect(r, c2);
- r.grow(-2);
- s->frameRect(r, _black);
-
- s->hLine(r.left - 3, r.top - 3, r.right + 1, c1);
- s->hLine(r.left, r.bottom, r.right, c1);
- s->vLine(r.left - 3, r.top - 2, r.bottom + 1, c1);
- s->vLine(r.right, r.top, r.bottom, c1);
-
- s->hLine(r.left - 1, r.top - 1, r.right, c3);
- s->hLine(r.left - 3, r.bottom + 2, r.right + 2, c3);
- s->vLine(r.left - 1, r.top, r.bottom, c3);
- s->vLine(r.right + 2, r.top - 3, r.bottom + 1, c3);
+ s->frameRect(Common::Rect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1), dark);
+ s->frameRect(Common::Rect(r.left + 1, r.top + 1, r.right - 2, r.bottom - 2), light);
+ s->frameRect(Common::Rect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2), medium);
+ s->frameRect(Common::Rect(r.left + 3, r.top + 3, r.right - 3, r.bottom - 3), dark);
+ s->frameRect(Common::Rect(r.left + 4, r.top + 4, r.right - 3, r.bottom - 3), light);
+ s->frameRect(Common::Rect(r.left + 4, r.top + 4, r.right - 4, r.bottom - 4), _black);
}
} else if (windowStyle == kWindowStyleRounded) {
r.grow(1);
Commit: d253793b223ddafcc2d50236023d3a93c7e20f3b
https://github.com/scummvm/scummvm/commit/d253793b223ddafcc2d50236023d3a93c7e20f3b
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Black out the screen for all v6-7 dialogs
I.e. not just when opening them from the menu.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index 90655beaebb..3bcda8f8425 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -40,17 +40,12 @@ namespace Scumm {
// ---------------------------------------------------------------------------
MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, Graphics::Surface *from, Common::Rect bounds, MacDialogWindowStyle windowStyle, MacDialogMenuStyle menuStyle) : _gui(gui), _system(system), _from(from), _bounds(bounds) {
- _gui->updatePalette();
-
// Only apply menu style if the menu is open.
Graphics::MacMenu *menu = _gui->_windowManager->getMenu();
if (!menu->_active)
menuStyle = kMenuStyleNone;
- _black = _gui->getBlack();
- _white = _gui->getWhite();
-
_pauseToken = _gui->_vm->pauseEngine();
// Remember if the screen was shaking. We don't use the SCUMM engine's
@@ -60,6 +55,12 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
_shakeWasEnabled = _gui->_vm->_shakeEnabled;
_gui->_vm->setShake(0);
+ _gui->lightsOff();
+ _gui->updatePalette();
+
+ _black = _gui->getBlack();
+ _white = _gui->getWhite();
+
_backup = new Graphics::Surface();
_backup->create(bounds.width(), bounds.height(), Graphics::PixelFormat::createFormatCLUT8());
_backup->copyRectToSurface(*_from, 0, 0, bounds);
@@ -189,6 +190,8 @@ MacGuiImpl::MacDialogWindow::~MacDialogWindow() {
_widgets.clear();
_pauseToken.clear();
_gui->_vm->setShake(_shakeWasEnabled);
+
+ _gui->lightsOn();
}
void MacGuiImpl::MacDialogWindow::copyToScreen(Graphics::Surface *s) const {
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 2a77a7afcbe..8af06cdb2b3 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -224,6 +224,9 @@ protected:
virtual void onMenuOpen();
virtual void onMenuClose();
+ virtual void lightsOff() {}
+ virtual void lightsOn() {}
+
virtual void runAboutDialog() = 0;
virtual bool runOpenDialog(int &saveSlotToHandle);
virtual bool runSaveDialog(int &saveSlotToHandle, Common::String &saveName);
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index b22e252eaf3..23484b30410 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -186,70 +186,81 @@ uint32 MacV6Gui::getWhite() const {
return 251;
}
-void MacV6Gui::onMenuOpen() {
- MacGuiImpl::onMenuOpen();
-
- Graphics::Surface *screen = _vm->_macScreen;
+void MacV6Gui::lightsOff() {
+ if (_lightLevel++ == 0) {
+ Graphics::Surface *screen = _vm->_macScreen;
- _backupSurface = new Graphics::Surface();
- _backupSurface->copyFrom(*screen);
+ _backupSurface = new Graphics::Surface();
+ _backupSurface->copyFrom(*screen);
- _backupPalette = new byte[256 * 3];
+ _backupPalette = new byte[256 * 3];
- screen->fillRect(Common::Rect(screen->w, screen->h), 255);
- memcpy(_backupPalette, _vm->_currentPalette, 256 * 3);
+ screen->fillRect(Common::Rect(screen->w, screen->h), 255);
+ memcpy(_backupPalette, _vm->_currentPalette, 256 * 3);
- for (int i = 0; i < 256; i++)
- _vm->setPalColor(i, 0, 0, 0);
+ for (int i = 0; i < 256; i++)
+ _vm->setPalColor(i, 0, 0, 0);
- // HACK: Make sure we have the Mac window manager's preferred colors
- // and other GUI elements. We put it at the end, because the beginning
- // of the palette is reserved for icon palettes.
- //
- // TODO: Make sure that this palette doesn't get overwritten!
- //
- // TODO: Make sure this palette is available to the GUI even when the
- // menu hasn't been opened by mouseover!
+ // HACK: Make sure we have the Mac window manager's preferred colors
+ // and other GUI elements. We put it at the end, because the beginning
+ // of the palette is reserved for icon palettes.
+ //
+ // TODO: Make sure that this palette doesn't get overwritten!
- _vm->setPalColor(255, 0, 0, 0); // Black
- _vm->setPalColor(254, 0x80, 0x80, 0x80); // Gray80
- _vm->setPalColor(253, 0x88, 0x88, 0x88); // Gray88
- _vm->setPalColor(252, 0xEE, 0xEE, 0xEE); // GrayEE
- _vm->setPalColor(251, 0xFF, 0xFF, 0xFF); // White
- _vm->setPalColor(250, 0x00, 0xFF, 0x00); // Green
- _vm->setPalColor(249, 0x00, 0xCF, 0x00); // Green2
+ _vm->setPalColor(255, 0, 0, 0); // Black
+ _vm->setPalColor(254, 0x80, 0x80, 0x80); // Gray80
+ _vm->setPalColor(253, 0x88, 0x88, 0x88); // Gray88
+ _vm->setPalColor(252, 0xEE, 0xEE, 0xEE); // GrayEE
+ _vm->setPalColor(251, 0xFF, 0xFF, 0xFF); // White
+ _vm->setPalColor(250, 0x00, 0xFF, 0x00); // Green
+ _vm->setPalColor(249, 0x00, 0xCF, 0x00); // Green2
- _vm->setPalColor(248, 0xCC, 0xCC, 0xFF);
- _vm->setPalColor(247, 0xBB, 0xBB, 0xBB);
- _vm->setPalColor(246, 0x66, 0x66, 0x99);
+ _vm->setPalColor(248, 0xCC, 0xCC, 0xFF);
+ _vm->setPalColor(247, 0xBB, 0xBB, 0xBB);
+ _vm->setPalColor(246, 0x66, 0x66, 0x99);
- _vm->updatePalette();
- _system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
- _system->updateScreen();
+ _vm->updatePalette();
+ _system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
+ _system->updateScreen();
- // HACK: Make sure the Mac window manager is operating on a blank screen
- _windowManager->_screenCopy->copyFrom(*screen);
+ // HACK: Make sure the Mac window manager is operating on a blank screen
+ if (_windowManager->_screenCopy)
+ _windowManager->_screenCopy->copyFrom(*screen);
+ }
}
-void MacV6Gui::onMenuClose() {
- MacGuiImpl::onMenuClose();
- Graphics::Surface *screen = _vm->_macScreen;
+void MacV6Gui::lightsOn() {
+ assert(_lightLevel > 0);
- screen->copyFrom(*_backupSurface);
+ if (--_lightLevel == 0) {
+ Graphics::Surface *screen = _vm->_macScreen;
- byte *p = _backupPalette;
- for (int i = 0; i < 256; i++, p += 3)
- _vm->setPalColor(i, p[0], p[1], p[2]);
+ screen->copyFrom(*_backupSurface);
- _system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
- _vm->updatePalette();
+ byte *p = _backupPalette;
+ for (int i = 0; i < 256; i++, p += 3)
+ _vm->setPalColor(i, p[0], p[1], p[2]);
- _backupSurface->free();
- delete _backupSurface;
- _backupSurface = nullptr;
+ _system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
+ _vm->updatePalette();
- delete _backupPalette;
- _backupPalette = nullptr;
+ _backupSurface->free();
+ delete _backupSurface;
+ _backupSurface = nullptr;
+
+ delete _backupPalette;
+ _backupPalette = nullptr;
+ }
+}
+
+void MacV6Gui::onMenuOpen() {
+ MacGuiImpl::onMenuOpen();
+ lightsOff();
+}
+
+void MacV6Gui::onMenuClose() {
+ MacGuiImpl::onMenuClose();
+ lightsOn();
}
void MacV6Gui::runAboutDialog() {
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 4f5800bc44c..5326f6246dd 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -35,6 +35,8 @@ private:
byte *_backupPalette;
Graphics::Surface *_backupSurface;
+ int _lightLevel = 0;
+
public:
MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile);
~MacV6Gui();
@@ -59,6 +61,9 @@ protected:
bool handleMenu(int id, Common::String &name) override;
+ void lightsOff() override;
+ void lightsOn() override;
+
void onMenuOpen() override;
void onMenuClose() override;
Commit: f07e873e382cd03d3cfb75f3497e13f115b5dda2
https://github.com/scummvm/scummvm/commit/f07e873e382cd03d3cfb75f3497e13f115b5dda2
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add todo comment
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 23484b30410..70e2c6246b6 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -344,6 +344,7 @@ bool MacV6Gui::runOptionsDialog() {
}
bool MacV6Gui::runQuitDialog() {
+ // TODO: 192 in Maniac Mansion? The icon looks wrong in that one.
MacDialogWindow *window = createDialog(128);
MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
Commit: 7c1191758a545fe1524c70587e929313198d284a
https://github.com/scummvm/scummvm/commit/7c1191758a545fe1524c70587e929313198d284a
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Implement v6 restart dialog
Oddly enough, only Day of the Tentacle (and, by extension, Maniac
Mansion) seems to have one?
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 70e2c6246b6..796a58c8bf0 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -146,9 +146,13 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return true;
case 204: // Restart
- debug("Restart");
- if (runRestartDialog())
+ if (runRestartDialog()) {
+ // WORKAROUND: Don't turn the lights back on because
+ // that will mess up the palette.
+ _lightLevel = 0;
+
_vm->restart();
+ }
return true;
case 205:
@@ -230,7 +234,9 @@ void MacV6Gui::lightsOff() {
}
void MacV6Gui::lightsOn() {
- assert(_lightLevel > 0);
+ // This will happen on restart
+ if (_lightLevel == 0)
+ return;
if (--_lightLevel == 0) {
Graphics::Surface *screen = _vm->_macScreen;
@@ -377,7 +383,42 @@ bool MacV6Gui::runQuitDialog() {
}
bool MacV6Gui::runRestartDialog() {
- return true;
+ // TODO: 193 in Maniac Mansion? The icon looks wrong in that one.
+ MacDialogWindow *window = createDialog(137);
+
+ MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
+ MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
+ MacStaticText *textWidget = (MacStaticText *)window->getWidget(kWidgetStaticText);
+
+ textWidget->setWordWrap(true);
+
+ window->setDefaultWidget(buttonOk);
+
+ // Only Day of the Tentacle seems to have a Restart dialog?
+ window->addSubstitution("");
+ window->addSubstitution("");
+ window->addSubstitution("");
+ window->addSubstitution("Day of the Tentacle");
+
+ Common::Array<int> deferredActionsIds;
+
+ // When quitting, the default action is to quit
+ bool ret = true;
+
+ while (!_vm->shouldQuit()) {
+ int clicked = window->runDialog(deferredActionsIds);
+
+ if (clicked == buttonOk->getId())
+ break;
+
+ if (clicked == buttonCancel->getId()) {
+ ret = false;
+ break;
+ }
+ }
+
+ delete window;
+ return ret;
}
void MacV6Gui::resetAfterLoad() {
Commit: 423bbb3cc68e5999c85d1606999b26d94f2b2e17
https://github.com/scummvm/scummvm/commit/423bbb3cc68e5999c85d1606999b26d94f2b2e17
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Implement "Skip scene" menu item.
The shortcut command doesn't work, though.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 796a58c8bf0..21f9423ef9d 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -138,7 +138,7 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return true;
case 202:
- debug("Skip scene");
+ _vm->processKeyboard(Common::KEYCODE_ESCAPE);
return true;
case 203:
Commit: 7d3109d0ef1585e7bc973c9cade79afc8fe9a8d5
https://github.com/scummvm/scummvm/commit/7d3109d0ef1585e7bc973c9cade79afc8fe9a8d5
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Update Mac window manager from SMUSH player
But the whole palette save/restore thing doesn't work properly here. I
guess we need to save the actual palette, not the engine palette.
Changed paths:
engines/scumm/smush/smush_player.cpp
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index f892d2e03a6..613873cf238 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -35,6 +35,7 @@
#include "scumm/scumm.h"
#include "scumm/scumm_v7.h"
#include "scumm/sound.h"
+#include "scumm/macgui/macgui.h"
#include "scumm/smush/codec37.h"
#include "scumm/smush/codec47.h"
#include "scumm/smush/smush_font.h"
@@ -1329,6 +1330,10 @@ void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 st
_imuseDigital->stopSMUSHAudio(); // For DIG & COMI
break;
}
+
+ if (_vm->_macGui)
+ _vm->_macGui->updateWindowManager();
+
_vm->_system->delayMillis(10);
}
Commit: af2a1231cb4706ad9bdf9890229c9fc0843ec636
https://github.com/scummvm/scummvm/commit/af2a1231cb4706ad9bdf9890229c9fc0843ec636
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Use the real palette, not the engine palette
The engine palette doesn't always properly reflect what's on screen
(e.g. during SMUSH movies), so we have to use the real palette.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index 3bcda8f8425..88a03872a17 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -23,6 +23,7 @@
#include "graphics/cursorman.h"
#include "graphics/macgui/macwindowmanager.h"
+#include "graphics/paletteman.h"
#include "graphics/primitives.h"
#include "graphics/surface.h"
@@ -55,7 +56,7 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
_shakeWasEnabled = _gui->_vm->_shakeEnabled;
_gui->_vm->setShake(0);
- _gui->lightsOff();
+ _gui->saveScreen();
_gui->updatePalette();
_black = _gui->getBlack();
@@ -191,7 +192,7 @@ MacGuiImpl::MacDialogWindow::~MacDialogWindow() {
_pauseToken.clear();
_gui->_vm->setShake(_shakeWasEnabled);
- _gui->lightsOn();
+ _gui->restoreScreen();
}
void MacGuiImpl::MacDialogWindow::copyToScreen(Graphics::Surface *s) const {
@@ -203,6 +204,32 @@ void MacGuiImpl::MacDialogWindow::copyToScreen(Graphics::Surface *s) const {
void MacGuiImpl::MacDialogWindow::show() {
_visible = true;
+
+ // Icons have their own palette, so we have to update it. It's assumed
+ // that this will clash with any other part of the palette.
+
+ MacIcon *icon = (MacIcon *)getWidget(kWidgetIcon, 0);
+
+ if (icon) {
+ Graphics::Palette *palette = icon->getPalette();
+ Graphics::Palette *paletteCopy = new Graphics::Palette(palette->size());
+
+ for (uint i = 0; i < palette->size(); i++) {
+ byte r, g, b;
+
+ palette->get(i, r, g, b);
+
+ r = _gui->_vm->_macGammaCorrectionLookUp[r];
+ g = _gui->_vm->_macGammaCorrectionLookUp[g];
+ b = _gui->_vm->_macGammaCorrectionLookUp[b];
+
+ paletteCopy->set(i, r, g, b);
+ }
+
+ _system->getPaletteManager()->setPalette(*paletteCopy);
+ delete paletteCopy;
+ }
+
copyToScreen();
_dirtyRects.clear();
_gui->_windowManager->pushCursor(Graphics::MacGUIConstants::kMacCursorArrow);
@@ -721,17 +748,6 @@ MacGuiImpl::MacWidget *MacGuiImpl::MacDialogWindow::getWidget(MacWidgetType type
return nullptr;
}
-void MacGuiImpl::MacDialogWindow::setPalette(const Graphics::Palette *palette) {
- for (uint i = 0; i < palette->size(); i++) {
- byte r, g, b;
-
- palette->get(i, r, g, b);
- _gui->_vm->setPalColor(i, r, g, b);
- }
-
- _dirtyPalette = true;
-}
-
void MacGuiImpl::MacDialogWindow::drawSprite(const Graphics::Surface *sprite, int x, int y) {
_innerSurface.copyRectToSurface(*sprite, x, y, Common::Rect(sprite->w, sprite->h));
markRectAsDirty(Common::Rect(x, y, x + sprite->w, y + sprite->h));
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 7433a211651..e2d46b0629c 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -97,7 +97,7 @@ void MacGuiImpl::setPaletteDirty() {
}
void MacGuiImpl::updatePalette() {
- if (_paletteDirty) {
+ if (_paletteDirty && !_suspendPaletteUpdates) {
_paletteDirty = false;
_windowManager->passPalette(_vm->_currentPalette, getNumColors());
}
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 8af06cdb2b3..6b2e8fd15df 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -143,6 +143,7 @@ protected:
Common::Path _resourceFile;
bool _paletteDirty = false;
+ bool _suspendPaletteUpdates = false;
bool _menuIsActive = false;
bool _cursorWasVisible = false;
@@ -224,8 +225,10 @@ protected:
virtual void onMenuOpen();
virtual void onMenuClose();
- virtual void lightsOff() {}
- virtual void lightsOn() {}
+ // For older games, there is no problem with displaying the Mac GUI and
+ // the game at the same time. For newer, there is.
+ virtual void saveScreen() {}
+ virtual void restoreScreen() {}
virtual void runAboutDialog() = 0;
virtual bool runOpenDialog(int &saveSlotToHandle);
@@ -705,7 +708,6 @@ public:
void drawDottedHLine(int x0, int y, int x1);
void fillPattern(Common::Rect r, uint16 pattern, bool fillBlack = true, bool fillWhite = true);
- void setPalette(const Graphics::Palette *palette);
void drawSprite(const Graphics::Surface *sprite, int x, int y);
void drawSprite(const Graphics::Surface *sprite, int x, int y, Common::Rect clipRect);
void drawTexts(Common::Rect r, const TextLine *lines, bool inverse = false);
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 21f9423ef9d..fc9a600848a 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -55,14 +55,14 @@ namespace Scumm {
// ===========================================================================
MacV6Gui::MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile) : MacGuiImpl(vm, resourceFile) {
+ _backupScreen = nullptr;
_backupPalette = nullptr;
- _backupSurface = nullptr;
}
MacV6Gui::~MacV6Gui() {
- if (_backupSurface) {
- _backupSurface->free();
- delete _backupSurface;
+ if (_backupScreen) {
+ _backupScreen->free();
+ delete _backupScreen;
}
delete _backupPalette;
@@ -146,13 +146,8 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return true;
case 204: // Restart
- if (runRestartDialog()) {
- // WORKAROUND: Don't turn the lights back on because
- // that will mess up the palette.
- _lightLevel = 0;
-
+ if (runRestartDialog())
_vm->restart();
- }
return true;
case 205:
@@ -190,69 +185,81 @@ uint32 MacV6Gui::getWhite() const {
return 251;
}
-void MacV6Gui::lightsOff() {
- if (_lightLevel++ == 0) {
+void MacV6Gui::saveScreen() {
+ if (_screenSaveLevel++ == 0) {
+ _suspendPaletteUpdates = true;
+
Graphics::Surface *screen = _vm->_macScreen;
- _backupSurface = new Graphics::Surface();
- _backupSurface->copyFrom(*screen);
+ _backupScreen = new Graphics::Surface();
+ _backupScreen->copyFrom(*screen);
+
+ // We have to grab the actual palette, becaues the engine
+ // palette may not be what's on screen, e.g. during SMUSH
+ // movies.
_backupPalette = new byte[256 * 3];
- screen->fillRect(Common::Rect(screen->w, screen->h), 255);
- memcpy(_backupPalette, _vm->_currentPalette, 256 * 3);
+ _system->getPaletteManager()->grabPalette(_backupPalette, 0, 256);
+
+ Graphics::Palette palette(256);
- for (int i = 0; i < 256; i++)
- _vm->setPalColor(i, 0, 0, 0);
+ // Colors used by the Mac Window Manager
+ palette.set(255, 0x00, 0x00, 0x00); // Black
+ palette.set(254, 0x80, 0x80, 0x80); // Gray80
+ palette.set(253, 0x88, 0x88, 0x88); // Gray88
+ palette.set(252, 0xEE, 0xEE, 0xEE); // GrayEE
+ palette.set(251, 0xFF, 0xFF, 0xFF); // White
+ palette.set(250, 0x00, 0xFF, 0x00); // Green
+ palette.set(249, 0x00, 0xCF, 0x00); // Green2
- // HACK: Make sure we have the Mac window manager's preferred colors
- // and other GUI elements. We put it at the end, because the beginning
- // of the palette is reserved for icon palettes.
- //
- // TODO: Make sure that this palette doesn't get overwritten!
+ // Colors used by Mac dialog window borders
+ palette.set(248, 0xCC, 0xCC, 0xFF);
+ palette.set(247, 0xBB, 0xBB, 0xBB);
+ palette.set(246, 0x66, 0x66, 0x99);
- _vm->setPalColor(255, 0, 0, 0); // Black
- _vm->setPalColor(254, 0x80, 0x80, 0x80); // Gray80
- _vm->setPalColor(253, 0x88, 0x88, 0x88); // Gray88
- _vm->setPalColor(252, 0xEE, 0xEE, 0xEE); // GrayEE
- _vm->setPalColor(251, 0xFF, 0xFF, 0xFF); // White
- _vm->setPalColor(250, 0x00, 0xFF, 0x00); // Green
- _vm->setPalColor(249, 0x00, 0xCF, 0x00); // Green2
+ for (int i = 0; i < 246; i++)
+ palette.set(i, 0x00, 0x00, 0x00);
- _vm->setPalColor(248, 0xCC, 0xCC, 0xFF);
- _vm->setPalColor(247, 0xBB, 0xBB, 0xBB);
- _vm->setPalColor(246, 0x66, 0x66, 0x99);
+ _windowManager->passPalette(palette.data(), 256);
- _vm->updatePalette();
+ for (int i = 0; i < 256; i++) {
+ byte r, g, b;
+
+ palette.get(i, r, g, b);
+ r = _vm->_macGammaCorrectionLookUp[r];
+ g = _vm->_macGammaCorrectionLookUp[g];
+ b = _vm->_macGammaCorrectionLookUp[b];
+ palette.set(i, r, g, b);
+ }
+
+ screen->fillRect(Common::Rect(screen->w, screen->h), getBlack());
_system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
- _system->updateScreen();
- // HACK: Make sure the Mac window manager is operating on a blank screen
+ _system->getPaletteManager()->setPalette(palette);
+
if (_windowManager->_screenCopy)
- _windowManager->_screenCopy->copyFrom(*screen);
+ _windowManager->_screenCopy->copyFrom(*_vm->_macScreen);
+
+ _system->updateScreen();
}
}
-void MacV6Gui::lightsOn() {
- // This will happen on restart
- if (_lightLevel == 0)
- return;
+void MacV6Gui::restoreScreen() {
+ if (--_screenSaveLevel == 0) {
+ _suspendPaletteUpdates = false;
- if (--_lightLevel == 0) {
Graphics::Surface *screen = _vm->_macScreen;
- screen->copyFrom(*_backupSurface);
-
- byte *p = _backupPalette;
- for (int i = 0; i < 256; i++, p += 3)
- _vm->setPalColor(i, p[0], p[1], p[2]);
+ screen->copyFrom(*_backupScreen);
_system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
- _vm->updatePalette();
- _backupSurface->free();
- delete _backupSurface;
- _backupSurface = nullptr;
+ _system->getPaletteManager()->setPalette(_backupPalette, 0, 256);
+
+ _backupScreen->free();
+ delete _backupScreen;
+ _backupScreen = nullptr;
delete _backupPalette;
_backupPalette = nullptr;
@@ -261,12 +268,12 @@ void MacV6Gui::lightsOn() {
void MacV6Gui::onMenuOpen() {
MacGuiImpl::onMenuOpen();
- lightsOff();
+ saveScreen();
}
void MacV6Gui::onMenuClose() {
MacGuiImpl::onMenuClose();
- lightsOn();
+ restoreScreen();
}
void MacV6Gui::runAboutDialog() {
@@ -291,14 +298,21 @@ void MacV6Gui::runAboutDialog() {
uint black = 0;
+ Graphics::Palette palette(256);
+
for (uint i = 0; i < 256; i++) {
byte r = aboutFile.readByte();
byte g = aboutFile.readByte();
byte b = aboutFile.readByte();
- _vm->setPalColor(i, r, g, b);
if (r == 0 && g == 0 && b == 0)
black = i;
+
+ r = _vm->_macGammaCorrectionLookUp[r];
+ g = _vm->_macGammaCorrectionLookUp[g];
+ b = _vm->_macGammaCorrectionLookUp[b];
+
+ palette.set(i, r, g, b);
}
// The screen is already black, but what's black in the palette may
@@ -315,7 +329,7 @@ void MacV6Gui::runAboutDialog() {
aboutFile.close();
_system->copyRectToScreen(screen->getBasePtr(0, 0), screen->pitch, 0, 0, screen->w, screen->h);
- _vm->updatePalette();
+ _system->getPaletteManager()->setPalette(palette);
bool done = false;
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 5326f6246dd..f7109802fda 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -32,10 +32,10 @@ class MacGuiImpl;
class MacV6Gui : public MacGuiImpl {
private:
+ Graphics::Surface *_backupScreen;
byte *_backupPalette;
- Graphics::Surface *_backupSurface;
- int _lightLevel = 0;
+ int _screenSaveLevel = 0;
public:
MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile);
@@ -61,8 +61,8 @@ protected:
bool handleMenu(int id, Common::String &name) override;
- void lightsOff() override;
- void lightsOn() override;
+ void saveScreen() override;
+ void restoreScreen() override;
void onMenuOpen() override;
void onMenuClose() override;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 03df9f32b23..1ee96e04462 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -824,7 +824,6 @@ void MacGuiImpl::MacIcon::draw(bool drawFocused) {
debug(1, "MacGuiImpl::MacIcon: Drawing icon %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
- _window->setPalette(_palette);
_window->drawSprite(_icon, _bounds.left, _bounds.top);
_redraw = false;
Commit: 8b6cf94b83015ac19e05eacd68031451097dc0e3
https://github.com/scummvm/scummvm/commit/8b6cf94b83015ac19e05eacd68031451097dc0e3
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix game name in v6-v7 Apple menu
Changed paths:
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_strings.cpp
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 6b2e8fd15df..4acf537ba4b 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -238,7 +238,7 @@ protected:
bool runOkCancelDialog(Common::String text);
- bool readStrings();
+ virtual bool readStrings();
void parseSTRSBlock(uint8 *strsData, const MacSTRSParsingEntry *parsingTable, int parsingTableSize);
// These are non interactable, no point in having them as widgets for now...
diff --git a/engines/scumm/macgui/macgui_strings.cpp b/engines/scumm/macgui/macgui_strings.cpp
index 3bd2dda5179..3b4fa2fa620 100644
--- a/engines/scumm/macgui/macgui_strings.cpp
+++ b/engines/scumm/macgui/macgui_strings.cpp
@@ -603,14 +603,12 @@ static const MacGuiImpl::MacSTRSParsingEntry strsIndy4FloppyVariant2Table[] = {
#undef SKIP_P
bool MacGuiImpl::readStrings() {
- if (_vm->_game.version >= 6) {
- // TODO: Fix this!
+ if (_vm->_game.version >= 6 || _vm->_game.id == GID_MANIAC) {
_strsStrings.clear();
_strsStrings.reserve(128);
for (int i = 0; i < 128; i++) {
_strsStrings.emplace_back("");
}
- _strsStrings[kMSIAboutGameName] = "About some game...";
return true;
}
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index fc9a600848a..d417a75960c 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -57,6 +57,19 @@ namespace Scumm {
MacV6Gui::MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile) : MacGuiImpl(vm, resourceFile) {
_backupScreen = nullptr;
_backupPalette = nullptr;
+
+ if (_vm->_game.id == GID_TENTACLE)
+ _gameName = "Day of the Tentacle";
+ else if (_vm->_game.id == GID_SAMNMAX)
+ _gameName = "Sam & Max";
+ else if (_vm->_game.id == GID_DIG)
+ _gameName = "The Dig";
+ else if (_vm->_game.id == GID_FT)
+ _gameName = "Full Throttle";
+ else if (_vm->_game.id == GID_MANIAC)
+ _gameName = "Maniac Mansion";
+ else
+ _gameName = "Some Game I Do Not Know";
}
MacV6Gui::~MacV6Gui() {
@@ -68,8 +81,18 @@ MacV6Gui::~MacV6Gui() {
delete _backupPalette;
}
+bool MacV6Gui::readStrings() {
+ _strsStrings.clear();
+ _strsStrings.reserve(128);
+ for (int i = 0; i < 128; i++)
+ _strsStrings.emplace_back("");
+
+ _strsStrings[kMSIAboutGameName] = "About " + _gameName + "...";
+ return true;
+}
+
const Graphics::Font *MacV6Gui::getFontByScummId(int32 id) {
- // V5 games do not use CharsetRendererMac
+ // V6 and V7 games (and Maniac Mansion) do not use CharsetRendererMac
return nullptr;
}
@@ -408,11 +431,14 @@ bool MacV6Gui::runRestartDialog() {
window->setDefaultWidget(buttonOk);
- // Only Day of the Tentacle seems to have a Restart dialog?
window->addSubstitution("");
window->addSubstitution("");
window->addSubstitution("");
- window->addSubstitution("Day of the Tentacle");
+
+ if (_vm->_game.id == GID_TENTACLE)
+ window->addSubstitution("Day of the Tentacle");
+ else
+ window->addSubstitution("Sam & Max");
Common::Array<int> deferredActionsIds;
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index f7109802fda..5ed28e9a06c 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -32,6 +32,8 @@ class MacGuiImpl;
class MacV6Gui : public MacGuiImpl {
private:
+ Common::String _gameName;
+
Graphics::Surface *_backupScreen;
byte *_backupPalette;
@@ -41,6 +43,8 @@ public:
MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile);
~MacV6Gui();
+ bool readStrings() override;
+
uint32 getBlack() const override;
uint32 getWhite() const override;
Commit: 337aa4508b887df9e1652ee0ae8364de535dfe31
https://github.com/scummvm/scummvm/commit/337aa4508b887df9e1652ee0ae8364de535dfe31
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Use _gameName for v6-v7 restart dialog
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index d417a75960c..2dba5cb37d5 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -434,11 +434,7 @@ bool MacV6Gui::runRestartDialog() {
window->addSubstitution("");
window->addSubstitution("");
window->addSubstitution("");
-
- if (_vm->_game.id == GID_TENTACLE)
- window->addSubstitution("Day of the Tentacle");
- else
- window->addSubstitution("Sam & Max");
+ window->addSubstitution(_gameName);
Common::Array<int> deferredActionsIds;
Commit: 60fff6d3444f03fe315360ec63b1e8aa4b32475e
https://github.com/scummvm/scummvm/commit/60fff6d3444f03fe315360ec63b1e8aa4b32475e
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Initial v6/v7 save/load dialogs, plus other fixes
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_indy3.cpp
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index e2d46b0629c..0ca7d9ff745 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -607,20 +607,20 @@ Graphics::Surface *MacGuiImpl::loadIcon(int id, Graphics::Palette **palette) {
res->skip(4);
uint16 maskRowBytes = res->readUint16BE();
res->skip(3 * 2);
- res->readUint16BE();
+ uint16 maskHeight = res->readUint16BE();
// Bitmap section
res->skip(4);
- uint16 rowBytes = res->readUint16BE();
+ uint16 bitmapRowBytes = res->readUint16BE();
res->readUint16BE(); // top
res->readUint16BE(); // left
- uint16 height = res->readUint16BE(); // bottom
+ uint16 bitmapHeight = res->readUint16BE(); // bottom
res->readUint16BE(); // right
// Data section
res->skip(4);
- res->skip(maskRowBytes * height);
- res->skip(rowBytes * height);
+ res->skip(maskRowBytes * maskHeight);
+ res->skip(bitmapRowBytes * bitmapHeight);
// Palette
res->skip(6);
@@ -638,8 +638,23 @@ Graphics::Surface *MacGuiImpl::loadIcon(int id, Graphics::Palette **palette) {
}
s = new Graphics::Surface();
- s->create(pixMap.rowBytes, pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8());
- res->read(s->getPixels(), pixMap.rowBytes * pixMap.bounds.height());
+ s->create(pixMap.bounds.width(), pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8());
+
+ if (pixMap.pixelSize == 2) {
+ byte *buf = new byte[pixMap.rowBytes];
+ for (int y = 0; y < pixMap.bounds.height(); y++) {
+ res->read(buf, pixMap.rowBytes);
+ for (int x = 0; x < pixMap.rowBytes; x++) {
+ s->setPixel(4 * x, y, (buf[x] >> 6) & 0x03);
+ s->setPixel(4 * x + 1, y, (buf[x] >> 4) & 0x03);
+ s->setPixel(4 * x + 2, y, (buf[x] >> 2) & 0x03);
+ s->setPixel(4 * x + 3, y, buf[x] & 0x03);
+ }
+ }
+ delete[] buf;
+ } else if (pixMap.pixelSize == 8) {
+ res->read(s->getPixels(), pixMap.rowBytes * pixMap.bounds.height());
+ }
}
return s;
@@ -734,17 +749,12 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
Common::MacResManager resource;
Common::SeekableReadStream *res;
- Common::String saveGameFileAsResStr, gameFileResStr;
- saveGameFileAsResStr = _strsStrings[kMSISaveGameFileAs].c_str();
- gameFileResStr = _strsStrings[kMSIGameFile].c_str();
+ Common::String gameFileResStr = _strsStrings[kMSIGameFile].c_str();
resource.open(_resourceFile);
Common::Rect bounds;
- bool isOpenDialog = dialogId == 4000 || dialogId == 4001;
- bool isSaveDialog = dialogId == 3998 || dialogId == 3999;
-
res = resource.getResource(MKTAG('D', 'L', 'O', 'G'), dialogId);
if (res) {
bounds.top = res->readUint16BE();
@@ -806,23 +816,12 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
case 0:
{
// User item
-
- // Skip drive label box and listbox
- bool doNotDraw = (isOpenDialog && (i == 6 || i == 7)) || ((isOpenDialog || isSaveDialog) && i == 3);
- if (!doNotDraw) {
- window->innerSurface()->frameRect(r, black);
- } else if (_vm->_game.id == GID_INDY3 && i == 3) {
- drawFakeDriveLabel(window, Common::Rect(r.left + 5, r.top, r.right, r.bottom), "ScummVM");
- }
-
+// window->innerSurface()->frameRect(r, black);
break;
}
case 4:
// Button
str = getDialogString(res, len);
- if ((isOpenDialog || isSaveDialog) && (i == 4 || i == 5)) // "Eject" and "Drive"
- enabled = false;
-
window->addButton(r, str, enabled);
break;
@@ -835,9 +834,6 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
case 8:
// Static text
str = getDialogString(res, len);
- if (isSaveDialog && i == 2)
- str = saveGameFileAsResStr;
-
window->addStaticText(r, str, enabled);
break;
diff --git a/engines/scumm/macgui/macgui_indy3.cpp b/engines/scumm/macgui/macgui_indy3.cpp
index 5b0edd8a0d8..457434a29b5 100644
--- a/engines/scumm/macgui/macgui_indy3.cpp
+++ b/engines/scumm/macgui/macgui_indy3.cpp
@@ -1369,8 +1369,13 @@ bool MacIndy3Gui::runOpenDialog(int &saveSlotToHandle) {
MacButton *buttonSave = (MacButton *)window->getWidget(kWidgetButton, 0);
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 2);
+ MacButton *buttonEject = (MacButton *)window->getWidget(kWidgetButton, 3);
+ MacButton *buttonDrive = (MacButton *)window->getWidget(kWidgetButton, 4);
window->setDefaultWidget(buttonSave);
+ buttonEject->setEnabled(false);
+ buttonDrive->setEnabled(false);
+
window->addSubstitution(Common::String::format("%d", _vm->VAR(244)));
window->addSubstitution(Common::String::format("%d", _vm->VAR(245)));
@@ -1382,6 +1387,7 @@ bool MacIndy3Gui::runOpenDialog(int &saveSlotToHandle) {
MacListBox *listBox = window->addListBox(Common::Rect(14, 41, 232, 187), savegameNames, true);
drawFakePathList(window, Common::Rect(14, 18, 231, 37), "Indy Last Crusade");
+ drawFakeDriveLabel(window, Common::Rect(239, 41, 349, 61), "ScummVM");
// When quitting, the default action is to not open a saved game
bool ret = false;
@@ -1425,9 +1431,16 @@ bool MacIndy3Gui::runSaveDialog(int &saveSlotToHandle, Common::String &saveName)
MacButton *buttonSave = (MacButton *)window->getWidget(kWidgetButton, 0);
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
+ MacButton *buttonEject = (MacButton *)window->getWidget(kWidgetButton, 2);
+ MacButton *buttonDrive = (MacButton *)window->getWidget(kWidgetButton, 3);
+ MacStaticText *saveText = (MacStaticText *)window->getWidget(kWidgetStaticText, 0);
MacEditText *editText = (MacEditText *)window->getWidget(kWidgetEditText);
window->setDefaultWidget(buttonSave);
+ buttonEject->setEnabled(false);
+ buttonDrive->setEnabled(false);
+ saveText->setText(_strsStrings[kMSISaveGameFileAs]);
+
window->addSubstitution(Common::String::format("%d", _vm->VAR(244)));
window->addSubstitution(Common::String::format("%d", _vm->VAR(245)));
@@ -1437,6 +1450,7 @@ bool MacIndy3Gui::runSaveDialog(int &saveSlotToHandle, Common::String &saveName)
prepareSaveLoad(savegameNames, busySlots, slotIds, ARRAYSIZE(busySlots));
drawFakePathList(window, Common::Rect(16, 8, 198, 27), "Indy Last Crusade");
+ drawFakeDriveLabel(window, Common::Rect(205, 31, 304, 51), "ScummVM");
int firstAvailableSlot = -1;
for (int i = 0; i < ARRAYSIZE(busySlots); i++) {
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 2dba5cb37d5..7db83716e77 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -20,7 +20,6 @@
*/
#include "common/system.h"
-#include "common/config-manager.h"
#include "common/macresman.h"
#include "engines/engine.h"
@@ -28,12 +27,6 @@
#include "graphics/palette.h"
#include "graphics/paletteman.h"
#include "graphics/macgui/macwindowmanager.h"
-
-#if 0
-#include "graphics/maccursor.h"
-#include "graphics/macgui/macfontmanager.h"
-#endif
-
#include "graphics/surface.h"
#include "scumm/scumm.h"
@@ -42,12 +35,6 @@
#include "scumm/macgui/macgui_impl.h"
#include "scumm/macgui/macgui_v6.h"
-#if 0
-#include "scumm/music.h"
-#include "scumm/sound.h"
-#include "scumm/verbs.h"
-#endif
-
namespace Scumm {
// ===========================================================================
@@ -78,7 +65,7 @@ MacV6Gui::~MacV6Gui() {
delete _backupScreen;
}
- delete _backupPalette;
+ delete[] _backupPalette;
}
bool MacV6Gui::readStrings() {
@@ -140,7 +127,6 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return true;
case 200: // Open
- debug("Open");
if (runOpenDialog(saveSlotToHandle)) {
if (saveSlotToHandle > -1) {
_vm->loadGameState(saveSlotToHandle);
@@ -150,7 +136,6 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return true;
case 201: // Save
- debug("Save");
_vm->beginTextInput();
if (runSaveDialog(saveSlotToHandle, savegameName)) {
if (saveSlotToHandle > -1) {
@@ -284,7 +269,7 @@ void MacV6Gui::restoreScreen() {
delete _backupScreen;
_backupScreen = nullptr;
- delete _backupPalette;
+ delete[] _backupPalette;
_backupPalette = nullptr;
}
}
@@ -382,13 +367,164 @@ void MacV6Gui::runAboutDialog() {
token.clear();
}
+bool MacV6Gui::runOpenDialog(int &saveSlotToHandle) {
+ // Widgets:
+ //
+ // 0 - Open button
+ // 1 - Cancel button
+ // 2 - Unknown item type 129
+ // 3 - User item
+ // 4 - Eject button
+ // 5 - Desktop button
+ // 6 - User item
+ // 7 - User item
+ // 8 - Picture (thumbnail?)
+ //
+ // Not in Maniac Mansion:
+ //
+ // 9 - User item
+ // 10 - "Where you were:" text
+
+ int dialogId = (_vm->_game.id == GID_MANIAC) ? 384 : 256;
+
+ MacDialogWindow *window = createDialog(dialogId);
+
+ MacButton *buttonSave = (MacButton *)window->getWidget(kWidgetButton, 0);
+ MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
+ MacButton *buttonEject = (MacButton *)window->getWidget(kWidgetButton, 2);
+ MacButton *buttonDesktop = (MacButton *)window->getWidget(kWidgetButton, 3);
+
+
+ window->setDefaultWidget(buttonSave);
+ buttonEject->setEnabled(false);
+ buttonDesktop->setEnabled(false);
+
+ bool availSlots[100];
+ int slotIds[100];
+ Common::StringArray savegameNames;
+ prepareSaveLoad(savegameNames, availSlots, slotIds, ARRAYSIZE(availSlots));
+
+ MacListBox *listBox;
+
+ if (_vm->_game.id == GID_MANIAC) {
+ listBox = window->addListBox(Common::Rect(10, 31, 228, 161), savegameNames, true);
+ drawFakePathList(window, Common::Rect(10, 8, 228, 27), _gameName.c_str());
+ drawFakeDriveLabel(window, Common::Rect(238, 10, 335, 26), "ScummVM");
+ } else {
+ listBox = window->addListBox(Common::Rect(184, 31, 402, 161), savegameNames, true);
+ drawFakePathList(window, Common::Rect(184, 8, 402, 27), _gameName.c_str());
+ drawFakeDriveLabel(window, Common::Rect(412, 10, 509, 26), "ScummVM");
+ window->innerSurface()->frameRect(Common::Rect(11, 31, 173, 133), getBlack());
+ }
+
+ // When quitting, the default action is to not open a saved game
+ bool ret = false;
+ Common::Array<int> deferredActionsIds;
+
+ while (!_vm->shouldQuit()) {
+ int clicked = window->runDialog(deferredActionsIds);
+
+ if (clicked == buttonSave->getId() || clicked == listBox->getId()) {
+ ret = true;
+ saveSlotToHandle =
+ listBox->getValue() < ARRAYSIZE(slotIds) ? slotIds[listBox->getValue()] : -1;
+ break;
+ }
+
+ if (clicked == buttonCancel->getId())
+ break;
+ }
+
+ delete window;
+ return ret;
+}
+
+bool MacV6Gui::runSaveDialog(int &saveSlotToHandle, Common::String &saveName) {
+ // Widgets:
+ //
+ // 0 - Save button
+ // 1 - Cancel button
+ // 2 - Unknown item type 129
+ // 3 - User item
+ // 4 - Eject button
+ // 5 - Desktop button
+ // 6 - User item
+ // 7 - User item
+ // 8 - Picture
+ // 9 - "Save as:" text
+ // 10 - User item
+
+ int dialogId = (_vm->_game.id == GID_MANIAC) ? 386 : 258;
+
+ MacDialogWindow *window = createDialog(dialogId);
+
+ MacButton *buttonSave = (MacButton *)window->getWidget(kWidgetButton, 0);
+ MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
+ MacButton *buttonEject = (MacButton *)window->getWidget(kWidgetButton, 2);
+ MacButton *buttonDrive = (MacButton *)window->getWidget(kWidgetButton, 3);
+ MacEditText *editText = (MacEditText *)window->getWidget(kWidgetEditText);
+
+ window->setDefaultWidget(buttonSave);
+ buttonEject->setEnabled(false);
+ buttonDrive->setEnabled(false);
+
+ bool busySlots[100];
+ int slotIds[100];
+ Common::StringArray savegameNames;
+ prepareSaveLoad(savegameNames, busySlots, slotIds, ARRAYSIZE(busySlots));
+
+ drawFakePathList(window, Common::Rect(14, 8, 232, 27), _gameName.c_str());
+ drawFakeDriveLabel(window, Common::Rect(242, 10, 339, 26), "ScummVM");
+
+ int firstAvailableSlot = -1;
+ for (int i = 0; i < ARRAYSIZE(busySlots); i++) {
+ if (!busySlots[i]) {
+ firstAvailableSlot = i;
+ break;
+ }
+ }
+
+ window->addListBox(Common::Rect(14, 31, 232, 129), savegameNames, true, true);
+
+ // When quitting, the default action is not to save a game
+ bool ret = false;
+ Common::Array<int> deferredActionsIds;
+
+ while (!_vm->shouldQuit()) {
+ int clicked = window->runDialog(deferredActionsIds);
+
+ if (clicked == buttonSave->getId()) {
+ ret = true;
+ saveName = editText->getText();
+ saveSlotToHandle = firstAvailableSlot;
+ break;
+ }
+
+ if (clicked == buttonCancel->getId())
+ break;
+
+ if (clicked == kDialogWantsAttention) {
+ // Cycle through deferred actions
+ for (uint i = 0; i < deferredActionsIds.size(); i++) {
+ if (deferredActionsIds[i] == editText->getId()) {
+ // Disable "Save" button when text is empty
+ buttonSave->setEnabled(!editText->getText().empty());
+ }
+ }
+ }
+ }
+
+ delete window;
+ return ret;
+}
+
bool MacV6Gui::runOptionsDialog() {
return false;
}
bool MacV6Gui::runQuitDialog() {
- // TODO: 192 in Maniac Mansion? The icon looks wrong in that one.
- MacDialogWindow *window = createDialog(128);
+ int dialogId = (_vm->_game.id == GID_MANIAC) ? 192 : 128;
+ MacDialogWindow *window = createDialog(dialogId);
MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
@@ -420,8 +556,8 @@ bool MacV6Gui::runQuitDialog() {
}
bool MacV6Gui::runRestartDialog() {
- // TODO: 193 in Maniac Mansion? The icon looks wrong in that one.
- MacDialogWindow *window = createDialog(137);
+ int dialogId = (_vm->_game.id == GID_MANIAC) ? 193 : 137;
+ MacDialogWindow *window = createDialog(dialogId);
MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 5ed28e9a06c..a9149cf2a84 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -72,6 +72,8 @@ protected:
void onMenuClose() override;
void runAboutDialog() override;
+ bool runOpenDialog(int &saveSlotToHandle) override;
+ bool runSaveDialog(int &saveSlotToHandle, Common::String &saveName) override;
bool runOptionsDialog() override;
bool runQuitDialog() override;
bool runRestartDialog() override;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 1ee96e04462..43863943c45 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -851,7 +851,8 @@ void MacGuiImpl::MacPicture::draw(bool drawFocused) {
debug(1, "MacGuiImpl::MacPicture: Drawing picture %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
- _window->drawSprite(_picture, _bounds.left, _bounds.top);
+ if (_picture)
+ _window->drawSprite(_picture, _bounds.left, _bounds.top);
_redraw = false;
_fullRedraw = false;
Commit: 15a059ddbd971655f0e716e43d9258e352c46754
https://github.com/scummvm/scummvm/commit/15a059ddbd971655f0e716e43d9258e352c46754
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Implement much of the remaining v6-7 menus
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 0ca7d9ff745..ca36310b786 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -491,9 +491,40 @@ void MacGuiImpl::updateWindowManager() {
menu->getSubMenuItem(speechMenu, 1)->checked = true;
break;
default:
- warning("MacGuiImpl::updateWindowManager(): Invalid voice mode");
+ warning("MacGuiImpl::updateWindowManager(): Invalid voice mode %d", _vm->_voiceMode);
+ break;
}
}
+ } else if (_vm->_game.version >= 6) {
+ Graphics::MacMenuItem *videoMenu = menu->getMenuItem("Video");
+
+ menu->getSubMenuItem(videoMenu, 0)->enabled = false;
+ menu->getSubMenuItem(videoMenu, 1)->enabled = false;
+ menu->getSubMenuItem(videoMenu, 2)->checked = true;
+ menu->getSubMenuItem(videoMenu, 3)->checked = _vm->_useMacGraphicsSmoothing;
+
+ Graphics::MacMenuItem *soundMenu = menu->getMenuItem("Sound");
+
+ menu->getSubMenuItem(soundMenu, 0)->checked = false; // Music
+ menu->getSubMenuItem(soundMenu, 1)->checked = false; // Effects
+ menu->getSubMenuItem(soundMenu, 5)->checked = false; // Text Only
+ menu->getSubMenuItem(soundMenu, 6)->checked = false; // Voice Only
+ menu->getSubMenuItem(soundMenu, 7)->checked = false; // Text & Voice
+
+ switch (_vm->_voiceMode) {
+ case 0: // Voice Only
+ menu->getSubMenuItem(soundMenu, 6)->checked = true;
+ break;
+ case 1: // Voice and Text
+ menu->getSubMenuItem(soundMenu, 7)->checked = true;
+ break;
+ case 2: // Text Only
+ menu->getSubMenuItem(soundMenu, 5)->checked = true;
+ break;
+ default:
+ warning("MacGuiImpl::updateWindowManager(): Invalid voice mode %d", _vm->_voiceMode);
+ break;
+ }
}
if (menu->isVisible())
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 7db83716e77..2bc6207d3f1 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -20,6 +20,7 @@
*/
#include "common/system.h"
+#include "common/config-manager.h"
#include "common/macresman.h"
#include "engines/engine.h"
@@ -165,7 +166,7 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
case 206:
if (runQuitDialog())
_vm->quitGame();
- break;
+ return true;
// In the original, the Edit menu is active during save dialogs, though
// only Cut, Copy and Paste.
@@ -177,9 +178,64 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
case 304: // Clear
return true;
- case 403:
- debug("Graphics smoothing");
+ case 403: // Graphics Smoothing
+ _vm->mac_toggleSmoothing();
+ return true;
+
+ case 500: // Music
+ debug("Music");
+ break;
+
+ case 501: // Effects
+ debug("Effects");
break;
+
+ case 502: // Toggle Text & Voice
+ switch (_vm->_voiceMode) {
+ case 0: // Voice Only -> Text & Voice
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", false);
+ break;
+
+ case 1: // Text & Voice -> Text Only
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", true);
+ break;
+
+ case 2: // Text Only -> Voice Only
+ ConfMan.setBool("subtitles", false);
+ ConfMan.setBool("speech_mute", false);
+ break;
+
+ default:
+ warning("Invalid voice mode %d", _vm->_voiceMode);
+ return true;
+ }
+
+ ConfMan.flushToDisk();
+ _vm->syncSoundSettings();
+ return true;
+
+ case 503: // Text Only
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", true);
+ ConfMan.flushToDisk();
+ _vm->syncSoundSettings();
+ return true;
+
+ case 504: // Voice Only
+ ConfMan.setBool("subtitles", false);
+ ConfMan.setBool("speech_mute", false);
+ ConfMan.flushToDisk();
+ _vm->syncSoundSettings();
+ return true;
+
+ case 505: // Text & Voice
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", false);
+ ConfMan.flushToDisk();
+ _vm->syncSoundSettings();
+ return true;
}
return false;
Commit: 25c304f892190cb7b1a17c3dc018644ba4c18aca
https://github.com/scummvm/scummvm/commit/25c304f892190cb7b1a17c3dc018644ba4c18aca
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix bugs in icon loader, plus early v6-7 options dialog
This isn't really ready for use, but I want to commit because I embark
on another experiment.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_indy3.cpp
engines/scumm/macgui/macgui_loom.cpp
engines/scumm/macgui/macgui_v5.cpp
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index ca36310b786..19ce335c627 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -637,8 +637,10 @@ Graphics::Surface *MacGuiImpl::loadIcon(int id, Graphics::Palette **palette) {
// Mask section
res->skip(4);
uint16 maskRowBytes = res->readUint16BE();
- res->skip(3 * 2);
- uint16 maskHeight = res->readUint16BE();
+ res->readUint16BE(); // top
+ res->readUint16BE(); // left
+ uint16 maskHeight = res->readUint16BE(); // bottom
+ res->readUint16BE(); // right
// Bitmap section
res->skip(4);
@@ -675,16 +677,27 @@ Graphics::Surface *MacGuiImpl::loadIcon(int id, Graphics::Palette **palette) {
byte *buf = new byte[pixMap.rowBytes];
for (int y = 0; y < pixMap.bounds.height(); y++) {
res->read(buf, pixMap.rowBytes);
- for (int x = 0; x < pixMap.rowBytes; x++) {
- s->setPixel(4 * x, y, (buf[x] >> 6) & 0x03);
- s->setPixel(4 * x + 1, y, (buf[x] >> 4) & 0x03);
- s->setPixel(4 * x + 2, y, (buf[x] >> 2) & 0x03);
- s->setPixel(4 * x + 3, y, buf[x] & 0x03);
+ for (int x = 0; x < pixMap.bounds.width(); x += 4) {
+ for (int i = 0; i < 4 && x + i < pixMap.bounds.width(); i++) {
+ s->setPixel(x + i, y, (buf[x / 4] >> (6 - 2 * i)) & 0x03);
+ }
}
}
delete[] buf;
+ } else if (pixMap.pixelSize == 4) {
+ byte *buf = new byte[pixMap.rowBytes];
+ for (int y = 0; y < pixMap.bounds.height(); y++) {
+ res->read(buf, pixMap.rowBytes);
+ for (int x = 0; x < pixMap.bounds.width(); x += 2) {
+ for (int i = 0; i < 2 && x + i < pixMap.bounds.width(); i++) {
+ s->setPixel(x + i, y, (buf[x / 2] >> (4 - 4 * i)) & 0x0F);
+ }
+ }
+ }
} else if (pixMap.pixelSize == 8) {
res->read(s->getPixels(), pixMap.rowBytes * pixMap.bounds.height());
+ } else {
+ error("MacGuiImpl::loadIcon(): Invalid pixel size %d", pixMap.pixelSize);
}
}
diff --git a/engines/scumm/macgui/macgui_indy3.cpp b/engines/scumm/macgui/macgui_indy3.cpp
index 457434a29b5..3b1bc5ccf29 100644
--- a/engines/scumm/macgui/macgui_indy3.cpp
+++ b/engines/scumm/macgui/macgui_indy3.cpp
@@ -1088,16 +1088,16 @@ bool MacIndy3Gui::handleMenu(int id, Common::String &name) {
switch (id) {
case 204: // IQ Points
runIqPointsDialog();
- break;
+ return true;
case 205: // Options
runOptionsDialog();
- break;
+ return true;
case 206: // Quit
if (runQuitDialog())
_vm->quitGame();
- break;
+ return true;
default:
debug("MacIndy3Gui::handleMenu: Unknown menu command: %d", id);
diff --git a/engines/scumm/macgui/macgui_loom.cpp b/engines/scumm/macgui/macgui_loom.cpp
index 5a040993d68..54271d811fb 100644
--- a/engines/scumm/macgui/macgui_loom.cpp
+++ b/engines/scumm/macgui/macgui_loom.cpp
@@ -137,16 +137,16 @@ bool MacLoomGui::handleMenu(int id, Common::String &name) {
switch (id) {
case 101: // Drafts inventory
runDraftsInventory();
- break;
+ return true;
case 204: // Options
runOptionsDialog();
- break;
+ return true;
case 205: // Quit
if (runQuitDialog())
_vm->quitGame();
- break;
+ return true;
default:
warning("Unknown menu command: %d", id);
diff --git a/engines/scumm/macgui/macgui_v5.cpp b/engines/scumm/macgui/macgui_v5.cpp
index 8d72691224d..ad46cc74d90 100644
--- a/engines/scumm/macgui/macgui_v5.cpp
+++ b/engines/scumm/macgui/macgui_v5.cpp
@@ -134,16 +134,16 @@ bool MacV5Gui::handleMenu(int id, Common::String &name) {
switch (id) {
case 204: // Fix color map
- break; // Do a no-op
+ return true;
case 205: // Options
runOptionsDialog();
- break;
+ return true;
case 206: // Quit
if (runQuitDialog())
_vm->quitGame();
- break;
+ return true;
// Window menu
case 402: // Tiny
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 2bc6207d3f1..30a9da474bc 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -160,8 +160,8 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return true;
case 205:
- debug("Preferences");
- break;
+ runOptionsDialog();
+ return true;
case 206:
if (runQuitDialog())
@@ -236,6 +236,10 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
ConfMan.flushToDisk();
_vm->syncSoundSettings();
return true;
+
+ default:
+ warning("Unknown menu command: %d", id);
+ break;
}
return false;
@@ -442,7 +446,6 @@ bool MacV6Gui::runOpenDialog(int &saveSlotToHandle) {
// 10 - "Where you were:" text
int dialogId = (_vm->_game.id == GID_MANIAC) ? 384 : 256;
-
MacDialogWindow *window = createDialog(dialogId);
MacButton *buttonSave = (MacButton *)window->getWidget(kWidgetButton, 0);
@@ -575,7 +578,56 @@ bool MacV6Gui::runSaveDialog(int &saveSlotToHandle, Common::String &saveName) {
}
bool MacV6Gui::runOptionsDialog() {
- return false;
+ // TODO: How to guarantee that the window has all the colors it needs
+ // for its pictures?
+
+ // There are too many different variations to list all widgets here.
+ // The important thing that they share are that the first three buttons
+ // are OK, Cancel, and Defaults, and that with the exception of Maniac
+ // Mansion they expect the first text to contain the name of the game
+ // as "^3".
+ //
+ // Strangely enough, Day of the Tentacle seems to use a lot more "User
+ // items" than the other ones, which means we'll have to hard-code them
+ // here instead.
+
+ int dialogId = (_vm->_game.id == GID_MANIAC) ? 385 : 257;
+
+ MacDialogWindow *window = createDialog(dialogId);
+
+ MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
+ MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
+ // MacButton *buttonDefaults = (MacButton *)window->getWidget(kWidgetButton, 2);
+
+ if (_vm->_game.id != GID_MANIAC) {
+ window->addSubstitution("");
+ window->addSubstitution("");
+ window->addSubstitution("");
+ window->addSubstitution(_gameName);
+ }
+
+ // When quitting, the default action is not to not apply options
+ bool ret = false;
+ Common::Array<int> deferredActionsIds;
+
+ while (!_vm->shouldQuit()) {
+ int clicked = window->runDialog(deferredActionsIds);
+
+ if (clicked == buttonOk->getId()) {
+ ret = true;
+ break;
+ }
+
+ if (clicked == buttonCancel->getId())
+ break;
+ }
+
+ if (ret) {
+ // Update settings
+ }
+
+ delete window;
+ return ret;
}
bool MacV6Gui::runQuitDialog() {
Commit: e5b964a24c6be55348c770fe1e8985732de2a4f6
https://github.com/scummvm/scummvm/commit/e5b964a24c6be55348c770fe1e8985732de2a4f6
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Complete rework of v6-7 window palettes
When a dialog window is created now, all palettes from the individual
widgets (icons and pictures) are collected and combined into a single
palette. The widget palettes are remapped to this. The icon decoder is
now a proper image decoder, which makes icons and pictures very similar
to handle.
Changed paths:
A image/cicn.cpp
A image/cicn.h
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
engines/scumm/macgui/macgui_widgets.cpp
image/module.mk
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index 88a03872a17..3acf35e1a47 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -56,9 +56,6 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
_shakeWasEnabled = _gui->_vm->_shakeEnabled;
_gui->_vm->setShake(0);
- _gui->saveScreen();
- _gui->updatePalette();
-
_black = _gui->getBlack();
_white = _gui->getWhite();
@@ -205,31 +202,6 @@ void MacGuiImpl::MacDialogWindow::copyToScreen(Graphics::Surface *s) const {
void MacGuiImpl::MacDialogWindow::show() {
_visible = true;
- // Icons have their own palette, so we have to update it. It's assumed
- // that this will clash with any other part of the palette.
-
- MacIcon *icon = (MacIcon *)getWidget(kWidgetIcon, 0);
-
- if (icon) {
- Graphics::Palette *palette = icon->getPalette();
- Graphics::Palette *paletteCopy = new Graphics::Palette(palette->size());
-
- for (uint i = 0; i < palette->size(); i++) {
- byte r, g, b;
-
- palette->get(i, r, g, b);
-
- r = _gui->_vm->_macGammaCorrectionLookUp[r];
- g = _gui->_vm->_macGammaCorrectionLookUp[g];
- b = _gui->_vm->_macGammaCorrectionLookUp[b];
-
- paletteCopy->set(i, r, g, b);
- }
-
- _system->getPaletteManager()->setPalette(*paletteCopy);
- delete paletteCopy;
- }
-
copyToScreen();
_dirtyRects.clear();
_gui->_windowManager->pushCursor(Graphics::MacGUIConstants::kMacCursorArrow);
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 19ce335c627..11bdf45aaa1 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -29,6 +29,7 @@
#include "graphics/fonts/macfont.h"
#include "graphics/macgui/macwindowmanager.h"
+#include "image/cicn.h"
#include "image/pict.h"
#include "scumm/macgui/macgui_impl.h"
@@ -616,91 +617,60 @@ bool MacGuiImpl::getFontParams(FontId fontId, int &id, int &size, int &slant) co
}
}
+Graphics::Surface *MacGuiImpl::createRemappedSurface(const Graphics::Surface *surface, const byte *palette, int colorCount) {
+ Graphics::Surface *s = new Graphics::Surface();
+ s->create(surface->w, surface->h, Graphics::PixelFormat::createFormatCLUT8());
+
+ byte paletteMap[256];
+ memset(paletteMap, 0, ARRAYSIZE(paletteMap));
+
+ for (int i = 0; i < colorCount; i++) {
+ int r = palette[3 * i];
+ int g = palette[3 * i + 1];
+ int b = palette[3 * i + 2];
+
+ uint32 c = _windowManager->findBestColor(r, g, b);
+ paletteMap[i] = c;
+ }
+
+ if (palette) {
+ for (int y = 0; y < s->h; y++) {
+ for (int x = 0; x < s->w; x++) {
+ int color = surface->getPixel(x, y);
+ s->setPixel(x, y, paletteMap[color]);
+ }
+ }
+ } else {
+ s->copyFrom(*surface);
+ }
+
+ return s;
+}
+
// ---------------------------------------------------------------------------
// Icon loader
// ---------------------------------------------------------------------------
-Graphics::Surface *MacGuiImpl::loadIcon(int id, Graphics::Palette **palette) {
+Graphics::Surface *MacGuiImpl::loadIcon(int id) {
Common::MacResManager resource;
- Graphics::Surface *s = nullptr;
resource.open(_resourceFile);
Common::SeekableReadStream *res = resource.getResource(MKTAG('c', 'i', 'c', 'n'), id);
- if (res) {
- // TODO: This is based on the Pegasus engine. Convert into
- // common code, perhaps?
-
- Image::PICTDecoder::PixMap pixMap = Image::PICTDecoder::readPixMap(*res);
-
- // Mask section
- res->skip(4);
- uint16 maskRowBytes = res->readUint16BE();
- res->readUint16BE(); // top
- res->readUint16BE(); // left
- uint16 maskHeight = res->readUint16BE(); // bottom
- res->readUint16BE(); // right
-
- // Bitmap section
- res->skip(4);
- uint16 bitmapRowBytes = res->readUint16BE();
- res->readUint16BE(); // top
- res->readUint16BE(); // left
- uint16 bitmapHeight = res->readUint16BE(); // bottom
- res->readUint16BE(); // right
-
- // Data section
- res->skip(4);
- res->skip(maskRowBytes * maskHeight);
- res->skip(bitmapRowBytes * bitmapHeight);
-
- // Palette
- res->skip(6);
- uint numColors = res->readUint16BE() + 1;
-
- *palette = new Graphics::Palette(numColors);
-
- for (uint i = 0; i < numColors; i++) {
- res->skip(2);
- uint16 r = res->readUint16BE();
- uint16 g = res->readUint16BE();
- uint16 b = res->readUint16BE();
-
- (*palette)->set(i, r >> 8, g >> 8, b >> 8);
- }
+ Image::CicnDecoder iconDecoder;
+ Graphics::Surface *s = nullptr;
- s = new Graphics::Surface();
- s->create(pixMap.bounds.width(), pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8());
+ if (res && iconDecoder.loadStream(*res)) {
+ const Graphics::Surface *surface = iconDecoder.getSurface();
+ const byte *palette = iconDecoder.getPalette();
- if (pixMap.pixelSize == 2) {
- byte *buf = new byte[pixMap.rowBytes];
- for (int y = 0; y < pixMap.bounds.height(); y++) {
- res->read(buf, pixMap.rowBytes);
- for (int x = 0; x < pixMap.bounds.width(); x += 4) {
- for (int i = 0; i < 4 && x + i < pixMap.bounds.width(); i++) {
- s->setPixel(x + i, y, (buf[x / 4] >> (6 - 2 * i)) & 0x03);
- }
- }
- }
- delete[] buf;
- } else if (pixMap.pixelSize == 4) {
- byte *buf = new byte[pixMap.rowBytes];
- for (int y = 0; y < pixMap.bounds.height(); y++) {
- res->read(buf, pixMap.rowBytes);
- for (int x = 0; x < pixMap.bounds.width(); x += 2) {
- for (int i = 0; i < 2 && x + i < pixMap.bounds.width(); i++) {
- s->setPixel(x + i, y, (buf[x / 2] >> (4 - 4 * i)) & 0x0F);
- }
- }
- }
- } else if (pixMap.pixelSize == 8) {
- res->read(s->getPixels(), pixMap.rowBytes * pixMap.bounds.height());
- } else {
- error("MacGuiImpl::loadIcon(): Invalid pixel size %d", pixMap.pixelSize);
- }
+ s = createRemappedSurface(surface, palette, iconDecoder.getPaletteColorCount());
}
+ delete res;
+ resource.close();
+
return s;
}
@@ -710,46 +680,19 @@ Graphics::Surface *MacGuiImpl::loadIcon(int id, Graphics::Palette **palette) {
Graphics::Surface *MacGuiImpl::loadPict(int id) {
Common::MacResManager resource;
- Graphics::Surface *s = nullptr;
resource.open(_resourceFile);
Common::SeekableReadStream *res = resource.getResource(MKTAG('P', 'I', 'C', 'T'), id);
- Image::PICTDecoder pict;
- if (res && pict.loadStream(*res)) {
- const Graphics::Surface *s1 = pict.getSurface();
- const byte *palette = pict.getPalette();
-
- s = new Graphics::Surface();
- s->create(s1->w, s1->h, Graphics::PixelFormat::createFormatCLUT8());
-
- byte paletteMap[256];
- memset(paletteMap, 0, ARRAYSIZE(paletteMap));
-
- for (int i = 0; i < pict.getPaletteColorCount(); i++) {
- int r = palette[3 * i];
- int g = palette[3 * i + 1];
- int b = palette[3 * i + 2];
+ Image::PICTDecoder pictDecoder;
+ Graphics::Surface *s = nullptr;
- uint32 c = _windowManager->findBestColor(r, g, b);
- paletteMap[i] = c;
- }
+ if (res && pictDecoder.loadStream(*res)) {
+ const Graphics::Surface *surface = pictDecoder.getSurface();
+ const byte *palette = pictDecoder.getPalette();
- if (!pict.getPaletteColorCount()) {
- paletteMap[0] = getWhite();
- paletteMap[1] = getBlack();
- }
-
- if (palette) {
- for (int y = 0; y < s->h; y++) {
- for (int x = 0; x < s->w; x++) {
- int color = s1->getPixel(x, y);
- s->setPixel(x, y, paletteMap[color]);
- }
- }
- } else
- s->copyFrom(*s1);
+ s = createRemappedSurface(surface, palette, pictDecoder.getPaletteColorCount());
}
delete res;
@@ -830,6 +773,98 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
delete res;
+ if (_vm->_game.version >= 6 || _vm->_game.id == GID_MANIAC) {
+ res = resource.getResource(MKTAG('D', 'I', 'T', 'L'), dialogId);
+
+ if (res) {
+ saveScreen();
+
+ Common::HashMap<uint32, byte> paletteMap;
+
+ // Mac window manager colors. Do we need all of these?
+
+ paletteMap[0x000000] = 1; // Black
+ paletteMap[0x808080] = 1; // Gray80
+ paletteMap[0x888888] = 1; // Gray88
+ paletteMap[0xEEEEEE] = 1; // GrayEE
+ paletteMap[0xFFFFFF] = 1; // White
+ paletteMap[0x00FF00] = 1; // Green
+ paletteMap[0x00CF00] = 1; // Green2
+
+ // Mac dialog window borders
+ paletteMap[0xCCCCFF] = 1;
+ paletteMap[0xBBBBBB] = 1;
+ paletteMap[0x666699] = 1;
+
+ int numItems = res->readUint16BE() + 1;
+
+ for (int i = 0; i < numItems; i++) {
+ res->skip(12);
+ int type = res->readByte();
+ int len = res->readByte();
+
+ Image::PICTDecoder pictDecoder;
+ Image::CicnDecoder iconDecoder;
+
+ const byte *palette = nullptr;
+ int paletteColorCount = 0;
+
+ Common::SeekableReadStream *imageRes = nullptr;
+ Image::ImageDecoder *decoder = nullptr;
+
+ switch (type & 0x7F) {
+ case 32:
+ imageRes = resource.getResource(MKTAG('c', 'i', 'c', 'n'), res->readUint16BE());
+ decoder = &iconDecoder;
+ break;
+
+ case 64:
+ imageRes = resource.getResource(MKTAG('P', 'I', 'C', 'T'), res->readUint16BE());
+ decoder = &pictDecoder;
+ break;
+
+ default:
+ res->skip(len);
+ break;
+ }
+
+ if (imageRes && decoder->loadStream(*imageRes)) {
+ palette = decoder->getPalette();
+ paletteColorCount = decoder->getPaletteColorCount();
+ for (int j = 0; j < paletteColorCount; j++) {
+ uint32 color = (palette[3 * j] << 16) | (palette[3 * j + 1] << 8) | palette[3 * j + 2];
+ paletteMap[color] = 1;
+ }
+ }
+ }
+
+ Graphics::Palette palette(paletteMap.size());
+ int numColors = 0;
+
+ for (auto &k : paletteMap) {
+ int r = (k._key >> 16) & 0xFF;
+ int g = (k._key >> 8) & 0xFF;
+ int b = k._key & 0xFF;
+
+ palette.set(numColors++, r, g, b);
+ }
+
+ _windowManager->passPalette(palette.data(), numColors);
+
+ for (int i = 0; i < numColors; i++) {
+ byte r, g, b;
+
+ palette.get(i, r, g, b);
+ r = _vm->_macGammaCorrectionLookUp[r];
+ g = _vm->_macGammaCorrectionLookUp[g];
+ b = _vm->_macGammaCorrectionLookUp[b];
+ palette.set(i, r, g, b);
+ }
+
+ _system->getPaletteManager()->setPalette(palette);
+ }
+ }
+
MacDialogWindow *window = createWindow(bounds);
res = resource.getResource(MKTAG('D', 'I', 'T', 'L'), dialogId);
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 4acf537ba4b..4c5b2b4a0e9 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -245,6 +245,8 @@ protected:
void drawFakePathList(MacDialogWindow *window, Common::Rect r, const char *text);
void drawFakeDriveLabel(MacDialogWindow *window, Common::Rect r, const char *text);
+ Graphics::Surface *createRemappedSurface(const Graphics::Surface *surface, const byte *palette, int colorCount);
+
public:
class MacGuiObject {
protected:
@@ -443,13 +445,11 @@ public:
class MacIcon : public MacWidget {
private:
Graphics::Surface *_icon = nullptr;
- Graphics::Palette *_palette = nullptr;
public:
MacIcon(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, int id, bool enabled);
~MacIcon();
- Graphics::Palette *getPalette() const { return _palette; }
Graphics::Surface *getIcon() const { return _icon; }
void draw(bool drawFocused = false);
@@ -723,8 +723,8 @@ public:
virtual int getNumColors() const = 0;
Graphics::Surface *surface() { return _surface; }
- virtual uint32 getBlack() const;
- virtual uint32 getWhite() const;
+ uint32 getBlack() const;
+ uint32 getWhite() const;
virtual const Common::String name() const = 0;
@@ -745,7 +745,7 @@ public:
const Graphics::Font *getFont(FontId fontId);
virtual const Graphics::Font *getFontByScummId(int32 id) = 0;
- Graphics::Surface *loadIcon(int id, Graphics::Palette **palette);
+ Graphics::Surface *loadIcon(int id);
Graphics::Surface *loadPict(int id);
virtual bool isVerbGuiActive() const { return false; }
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 30a9da474bc..a9711f27fa0 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -245,14 +245,6 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return false;
}
-uint32 MacV6Gui::getBlack() const {
- return 255;
-}
-
-uint32 MacV6Gui::getWhite() const {
- return 251;
-}
-
void MacV6Gui::saveScreen() {
if (_screenSaveLevel++ == 0) {
_suspendPaletteUpdates = true;
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index a9149cf2a84..8a743a2f0db 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -45,9 +45,6 @@ public:
bool readStrings() override;
- uint32 getBlack() const override;
- uint32 getWhite() const override;
-
const Common::String name() const override { return _strsStrings[kMSIGameName]; }
int getNumColors() const override { return 256; }
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 43863943c45..0bed5086a2c 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -808,7 +808,7 @@ void MacGuiImpl::MacEditText::handleMouseMove(Common::Event &event) {
// ---------------------------------------------------------------------------
MacGuiImpl::MacIcon::MacIcon(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, int id, bool enabled) : MacWidget(window, bounds, "Icon", enabled) {
- _icon = _window->_gui->loadIcon(id, &_palette);
+ _icon = _window->_gui->loadIcon(id);
}
MacGuiImpl::MacIcon::~MacIcon() {
@@ -824,7 +824,8 @@ void MacGuiImpl::MacIcon::draw(bool drawFocused) {
debug(1, "MacGuiImpl::MacIcon: Drawing icon %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
- _window->drawSprite(_icon, _bounds.left, _bounds.top);
+ if (_icon)
+ _window->drawSprite(_icon, _bounds.left, _bounds.top);
_redraw = false;
_fullRedraw = false;
diff --git a/image/cicn.cpp b/image/cicn.cpp
new file mode 100644
index 00000000000..6df1f83b091
--- /dev/null
+++ b/image/cicn.cpp
@@ -0,0 +1,130 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/stream.h"
+
+#include "image/cicn.h"
+#include "image/pict.h"
+
+#include "graphics/pixelformat.h"
+#include "graphics/surface.h"
+
+namespace Image {
+
+CicnDecoder::CicnDecoder() {
+ _surface = nullptr;
+ _palette = nullptr;
+ _paletteColorCount = 0;
+}
+
+CicnDecoder::~CicnDecoder() {
+ destroy();
+}
+
+void CicnDecoder::destroy() {
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ _surface = nullptr;
+ }
+
+ delete[] _palette;
+ _palette = nullptr;
+
+ _paletteColorCount = 0;
+}
+
+bool CicnDecoder::loadStream(Common::SeekableReadStream &stream) {
+ destroy();
+
+ Image::PICTDecoder::PixMap pixMap = Image::PICTDecoder::readPixMap(stream);
+
+ // Mask header
+ stream.skip(4);
+ uint16 maskRowBytes = stream.readUint16BE();
+ stream.readUint16BE(); // top
+ stream.readUint16BE(); // left
+ uint16 maskHeight = stream.readUint16BE(); // bottom
+ stream.readUint16BE(); // right
+
+ // Bitmap header
+ stream.skip(4);
+ uint16 bitmapRowBytes = stream.readUint16BE();
+ stream.readUint16BE(); // top
+ stream.readUint16BE(); // left
+ uint16 bitmapHeight = stream.readUint16BE(); // bottom
+ stream.readUint16BE(); // right
+
+ // Mask and bitmap data
+ stream.skip(4);
+ stream.skip(maskRowBytes * maskHeight);
+ stream.skip(bitmapRowBytes * bitmapHeight);
+
+ // Palette
+ stream.skip(6);
+ _paletteColorCount = stream.readUint16BE() + 1;
+
+ _palette = new byte[3 * _paletteColorCount];
+
+ byte *p = _palette;
+
+ for (uint i = 0; i < _paletteColorCount; i++) {
+ stream.skip(2);
+ *p++ = stream.readUint16BE() >> 8;
+ *p++ = stream.readUint16BE() >> 8;
+ *p++ = stream.readUint16BE() >> 8;
+ }
+
+ _surface = new Graphics::Surface();
+ _surface->create(pixMap.bounds.width(), pixMap.bounds.height(), Graphics::PixelFormat::createFormatCLUT8());
+
+ if (pixMap.pixelSize == 2) {
+ byte *buf = new byte[pixMap.rowBytes];
+ for (int y = 0; y < pixMap.bounds.height(); y++) {
+ stream.read(buf, pixMap.rowBytes);
+ for (int x = 0; x < pixMap.bounds.width(); x += 4) {
+ for (int i = 0; i < 4 && x + i < pixMap.bounds.width(); i++) {
+ _surface->setPixel(x + i, y, (buf[x / 4] >> (6 - 2 * i)) & 0x03);
+ }
+ }
+ }
+ delete[] buf;
+ } else if (pixMap.pixelSize == 4) {
+ byte *buf = new byte[pixMap.rowBytes];
+ for (int y = 0; y < pixMap.bounds.height(); y++) {
+ stream.read(buf, pixMap.rowBytes);
+ for (int x = 0; x < pixMap.bounds.width(); x += 2) {
+ for (int i = 0; i < 2 && x + i < pixMap.bounds.width(); i++) {
+ _surface->setPixel(x + i, y, (buf[x / 2] >> (4 - 4 * i)) & 0x0F);
+ }
+ }
+ }
+ delete[] buf;
+ } else if (pixMap.pixelSize == 8) {
+ stream.read(_surface->getPixels(), pixMap.rowBytes * pixMap.bounds.height());
+ } else {
+ error("CicnDecoder::loadStream(): Invalid pixel size %d", pixMap.pixelSize);
+ }
+
+ return true;
+}
+
+} // End of namespace Image
diff --git a/image/cicn.h b/image/cicn.h
new file mode 100644
index 00000000000..4eebd7a0152
--- /dev/null
+++ b/image/cicn.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef IMAGE_CICN_H
+#define IMAGE_CICN_H
+
+#include "image/image_decoder.h"
+
+namespace Image {
+
+/**
+ * @defgroup image_cicn cicn decoder
+ * @ingroup image
+ *
+ * @brief Decoder for cicn images.
+ *
+ * Used in engines:
+ * - SCUMM
+ * @{
+ */
+
+class CicnDecoder : public ImageDecoder {
+public:
+ CicnDecoder();
+ virtual ~CicnDecoder();
+
+ // ImageDecoder API
+ void destroy() override;
+ bool loadStream(Common::SeekableReadStream &stream) override;
+ const Graphics::Surface *getSurface() const override { return _surface; }
+ const byte *getPalette() const override { return _palette; }
+ uint16 getPaletteColorCount() const override { return _paletteColorCount; }
+
+private:
+ Graphics::Surface *_surface;
+ byte *_palette;
+ uint16 _paletteColorCount;
+
+};
+
+/** @} */
+} // End of namespace Image
+
+#endif
diff --git a/image/module.mk b/image/module.mk
index 1eee3be286e..60e74270b65 100644
--- a/image/module.mk
+++ b/image/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
ani.o \
bmp.o \
cel_3do.o \
+ cicn.o \
icocur.o \
iff.o \
jpeg.o \
Commit: 645e0297fcf225f5f87c464f20e501733b134b8f
https://github.com/scummvm/scummvm/commit/645e0297fcf225f5f87c464f20e501733b134b8f
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Make OK the default button in v6-7 options dialogs
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index a9711f27fa0..a38eb5578aa 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -598,9 +598,12 @@ bool MacV6Gui::runOptionsDialog() {
window->addSubstitution(_gameName);
}
+ window->setDefaultWidget(buttonOk);
+
+ Common::Array<int> deferredActionsIds;
+
// When quitting, the default action is not to not apply options
bool ret = false;
- Common::Array<int> deferredActionsIds;
while (!_vm->shouldQuit()) {
int clicked = window->runDialog(deferredActionsIds);
Commit: 7380767714c5c332f045c0b5c97d18074a0ef19f
https://github.com/scummvm/scummvm/commit/7380767714c5c332f045c0b5c97d18074a0ef19f
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add missing static graphics to DOTT options dialog
Also fixed some palette issues along the way.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index 3acf35e1a47..b5ace204980 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -91,12 +91,12 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
uint32 dark = _gui->_windowManager->findBestColor(0x66, 0x66, 0x99);
s->frameRect(r, _black);
- s->frameRect(Common::Rect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1), dark);
- s->frameRect(Common::Rect(r.left + 1, r.top + 1, r.right - 2, r.bottom - 2), light);
- s->frameRect(Common::Rect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2), medium);
- s->frameRect(Common::Rect(r.left + 3, r.top + 3, r.right - 3, r.bottom - 3), dark);
- s->frameRect(Common::Rect(r.left + 4, r.top + 4, r.right - 3, r.bottom - 3), light);
- s->frameRect(Common::Rect(r.left + 4, r.top + 4, r.right - 4, r.bottom - 4), _black);
+ s->frameRect(Common::Rect(r.left, r.top, r.right, r.bottom), dark);
+ s->frameRect(Common::Rect(r.left, r.top, r.right - 1, r.bottom - 1), light);
+ s->frameRect(Common::Rect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1), medium);
+ s->frameRect(Common::Rect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2), dark);
+ s->frameRect(Common::Rect(r.left + 3, r.top + 3, r.right - 2, r.bottom - 2), light);
+ s->frameRect(Common::Rect(r.left + 3, r.top + 3, r.right - 3, r.bottom - 3), _black);
}
} else if (windowStyle == kWindowStyleRounded) {
r.grow(1);
@@ -131,8 +131,8 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
// However, the Mac Window Manager's ideas of what's black and
// what's white may no longer be valid.
- uint32 macWhite = _gui->_windowManager->_colorWhite;
- uint32 macBlack = _gui->_windowManager->_colorBlack;
+ uint32 macWhite = _gui->_macWhite;
+ uint32 macBlack = _gui->_macBlack;
if (macWhite != _white || macBlack != _black) {
for (int y = 0; y < 19; y++) {
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 11bdf45aaa1..da703bfabb1 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -622,17 +622,25 @@ Graphics::Surface *MacGuiImpl::createRemappedSurface(const Graphics::Surface *su
s->create(surface->w, surface->h, Graphics::PixelFormat::createFormatCLUT8());
byte paletteMap[256];
- memset(paletteMap, 0, ARRAYSIZE(paletteMap));
+ memset(paletteMap, 0, sizeof(paletteMap));
for (int i = 0; i < colorCount; i++) {
int r = palette[3 * i];
int g = palette[3 * i + 1];
int b = palette[3 * i + 2];
- uint32 c = _windowManager->findBestColor(r, g, b);
+ uint32 c;
+
+ c = _windowManager->findBestColor(r, g, b);
paletteMap[i] = c;
}
+ // Colors outside the palette are not remapped. Some images use 0xFF
+ // for black, and that's what we're using too.
+
+ for (int i = colorCount; i < 256; i++)
+ paletteMap[i] = i;
+
if (palette) {
for (int y = 0; y < s->h; y++) {
for (int x = 0; x < s->w; x++) {
@@ -705,6 +713,39 @@ Graphics::Surface *MacGuiImpl::loadPict(int id) {
// Window handling
// ---------------------------------------------------------------------------
+// In the older Mac games, the GUI and game graphics are made to coexist, so
+// the GUI should look good regardless of what's on screen. In the newer ones
+// there is no such guarantee, so the screen is blacked out whenever the GUI
+// is shown.
+//
+// We hard-code the upper part of the palette to have all the colors used by
+// the Mac Window manager and window borders. This is so that drawing the
+// window will not mess up what's already on screen. The lower part is used for
+// any graphical elements (pictures and icons) in the window. Anything in
+// between is set to black.
+//
+// The Mac window manager gets the palette before gamma correction, the backend
+// gets it afterwards.
+
+void MacGuiImpl::setMacGuiColors(Graphics::Palette &palette) {
+ // Colors used by the Mac Window Manager
+ palette.set(255, 0x00, 0x00, 0x00); // Black
+ palette.set(254, 0xFF, 0xFF, 0xFF); // White
+ palette.set(253, 0x80, 0x80, 0x80); // Gray80
+ palette.set(252, 0x88, 0x88, 0x88); // Gray88
+ palette.set(251, 0xEE, 0xEE, 0xEE); // GrayEE
+ palette.set(250, 0x00, 0xFF, 0x00); // Green
+ palette.set(249, 0x00, 0xCF, 0x00); // Green2
+
+ // Colors used by Mac dialog window borders
+ palette.set(248, 0xCC, 0xCC, 0xFF);
+ palette.set(247, 0xBB, 0xBB, 0xBB);
+ palette.set(246, 0x66, 0x66, 0x99);
+
+ for (int i = 0; i < 246; i++)
+ palette.set(i, 0x00, 0x00, 0x00);
+}
+
MacGuiImpl::MacDialogWindow *MacGuiImpl::createWindow(Common::Rect bounds, MacDialogWindowStyle windowStyle, MacDialogMenuStyle menuStyle) {
if (bounds.left < 0 || bounds.top < 0 || bounds.right >= 640 || bounds.bottom >= 400) {
// This happens with the Last Crusade file dialogs.
@@ -773,6 +814,9 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
delete res;
+ _macWhite = _windowManager->_colorWhite;
+ _macBlack = _windowManager->_colorBlack;
+
if (_vm->_game.version >= 6 || _vm->_game.id == GID_MANIAC) {
res = resource.getResource(MKTAG('D', 'I', 'T', 'L'), dialogId);
@@ -780,21 +824,10 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
saveScreen();
Common::HashMap<uint32, byte> paletteMap;
+ int numWindowColors = 0;
- // Mac window manager colors. Do we need all of these?
-
- paletteMap[0x000000] = 1; // Black
- paletteMap[0x808080] = 1; // Gray80
- paletteMap[0x888888] = 1; // Gray88
- paletteMap[0xEEEEEE] = 1; // GrayEE
- paletteMap[0xFFFFFF] = 1; // White
- paletteMap[0x00FF00] = 1; // Green
- paletteMap[0x00CF00] = 1; // Green2
-
- // Mac dialog window borders
- paletteMap[0xCCCCFF] = 1;
- paletteMap[0xBBBBBB] = 1;
- paletteMap[0x666699] = 1;
+ // Additional colors for hard-coded elements
+ paletteMap[0xCDCDCD] = numWindowColors++;
int numItems = res->readUint16BE() + 1;
@@ -833,25 +866,30 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
paletteColorCount = decoder->getPaletteColorCount();
for (int j = 0; j < paletteColorCount; j++) {
uint32 color = (palette[3 * j] << 16) | (palette[3 * j + 1] << 8) | palette[3 * j + 2];
- paletteMap[color] = 1;
+ if (!paletteMap.contains(color))
+ paletteMap[color] = numWindowColors++;
}
}
}
- Graphics::Palette palette(paletteMap.size());
- int numColors = 0;
+ Graphics::Palette palette(256);
+ setMacGuiColors(palette);
for (auto &k : paletteMap) {
int r = (k._key >> 16) & 0xFF;
int g = (k._key >> 8) & 0xFF;
int b = k._key & 0xFF;
+ palette.set(k._value, r, g, b);
+ }
- palette.set(numColors++, r, g, b);
+ for (int i = 0; i < 256; i++) {
+ byte r, g, b;
+ palette.get(i, r, g, b);
}
- _windowManager->passPalette(palette.data(), numColors);
+ _windowManager->passPalette(palette.data(), 256);
- for (int i = 0; i < numColors; i++) {
+ for (int i = 0; i < 256; i++) {
byte r, g, b;
palette.get(i, r, g, b);
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 4c5b2b4a0e9..a6ba58b78e6 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -723,8 +723,11 @@ public:
virtual int getNumColors() const = 0;
Graphics::Surface *surface() { return _surface; }
- uint32 getBlack() const;
- uint32 getWhite() const;
+ virtual uint32 getBlack() const;
+ virtual uint32 getWhite() const;
+
+ uint32 _macWhite;
+ uint32 _macBlack;
virtual const Common::String name() const = 0;
@@ -763,6 +766,8 @@ public:
virtual void initTextAreaForActor(Actor *a, byte color) {}
virtual void printCharToTextArea(int chr, int x, int y, int color) {}
+ void setMacGuiColors(Graphics::Palette &palette);
+
MacDialogWindow *createWindow(Common::Rect bounds, MacDialogWindowStyle style = kWindowStyleNormal, MacDialogMenuStyle menuStyle = kMenuStyleDisabled);
MacDialogWindow *createDialog(int dialogId);
void drawBanner(char *message);
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index a38eb5578aa..1a6ea23a586 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -264,22 +264,7 @@ void MacV6Gui::saveScreen() {
Graphics::Palette palette(256);
- // Colors used by the Mac Window Manager
- palette.set(255, 0x00, 0x00, 0x00); // Black
- palette.set(254, 0x80, 0x80, 0x80); // Gray80
- palette.set(253, 0x88, 0x88, 0x88); // Gray88
- palette.set(252, 0xEE, 0xEE, 0xEE); // GrayEE
- palette.set(251, 0xFF, 0xFF, 0xFF); // White
- palette.set(250, 0x00, 0xFF, 0x00); // Green
- palette.set(249, 0x00, 0xCF, 0x00); // Green2
-
- // Colors used by Mac dialog window borders
- palette.set(248, 0xCC, 0xCC, 0xFF);
- palette.set(247, 0xBB, 0xBB, 0xBB);
- palette.set(246, 0x66, 0x66, 0x99);
-
- for (int i = 0; i < 246; i++)
- palette.set(i, 0x00, 0x00, 0x00);
+ setMacGuiColors(palette);
_windowManager->passPalette(palette.data(), 256);
@@ -336,6 +321,47 @@ void MacV6Gui::onMenuClose() {
restoreScreen();
}
+void MacV6Gui::drawSliderBackground(MacDialogWindow *window, int x, int y, int width, int ticks) {
+ Graphics::Surface *s = window->innerSurface();
+
+ uint32 gray = _windowManager->findBestColor(0xCD, 0xCD, 0xCD);
+ uint32 black = getBlack();
+
+ Common::Rect r(width, 12);
+ r.moveTo(x, y);
+
+ s->fillRect(r, gray);
+ s->frameRect(r, black);
+
+ int yt = y + 14;
+
+ for (int i = 0; i < ticks; i++) {
+ int ht = ((i % 4) == 0) ? 4 : 2;
+ s->vLine(x + (i * (width - 1)) / (ticks - 1), yt, yt + ht, black);
+ }
+}
+
+void MacV6Gui::drawDottedFrame(MacDialogWindow *window, Common::Rect bounds, int x1, int x2) {
+ Graphics::Surface *s = window->innerSurface();
+ uint32 black = getBlack();
+
+ for (int x = bounds.left; x < bounds.right; x++) {
+ if (((x + bounds.bottom - 1) & 1) == 0)
+ s->setPixel(x, bounds.bottom - 1, black);
+
+ if ((x <= x1 || x >= x2) && ((x + bounds.top) & 1) == 0)
+ s->setPixel(x, bounds.top, black);
+ }
+
+ for (int y = bounds.top; y < bounds.bottom; y++) {
+ if (((bounds.left + y) & 1) == 0)
+ s->setPixel(bounds.left, y, black);
+
+ if (((bounds.right - 1 + y) & 1) == 0)
+ s->setPixel(bounds.right - 1, y, black);
+ }
+}
+
void MacV6Gui::runAboutDialog() {
ScummFile aboutFile(_vm);
if (!_vm->openFile(aboutFile, "ABOUT"))
@@ -600,6 +626,44 @@ bool MacV6Gui::runOptionsDialog() {
window->setDefaultWidget(buttonOk);
+ if (_vm->_game.id == GID_TENTACLE) {
+ // Unlike the other games, Day of the Tentacle uses a lot of
+ // "user items" which we don't have a way to parse.
+
+ drawSliderBackground(window, 152, 63, 147, 17);
+ drawSliderBackground(window, 152, 87, 147, 17);
+ drawSliderBackground(window, 151, 177, 147, 9);
+
+ Common::Point spritePos[] = {
+ Common::Point(133, 87),
+ Common::Point(310, 86),
+ Common::Point(125, 175),
+ Common::Point(307, 175)
+ };
+
+ for (int i = 0; i < ARRAYSIZE(spritePos); i++) {
+ Graphics::Surface *s = loadPict(1000 + i);
+ if (s) {
+ window->drawSprite(s, spritePos[i].x, spritePos[i].y);
+ s->free();
+ delete s;
+ }
+ }
+
+ uint32 black = getBlack();
+
+ const Graphics::Font *font = getFont(kSystemFont);
+ font->drawString(window->innerSurface(), "Volume Settings", 27, 33, 110, black);
+ font->drawString(window->innerSurface(), "Voice & Effects:", 23, 85, 105, black);
+ font->drawString(window->innerSurface(), "Text & Voice Settings", 26, 122, 140, black);
+ font->drawString(window->innerSurface(), "Interact using:", 21, 149, 105, black);
+ font->drawString(window->innerSurface(), "Text Speed:", 22, 175, 105, black);
+ font->drawString(window->innerSurface(), "Video Quality:", 21, 219, 105, black);
+
+ drawDottedFrame(window, Common::Rect(12, 41, 337, 113), 21, 137);
+ drawDottedFrame(window, Common::Rect(11, 130, 336, 203), 20, 168);
+ }
+
Common::Array<int> deferredActionsIds;
// When quitting, the default action is not to not apply options
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 8a743a2f0db..f53d969314e 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -48,6 +48,10 @@ public:
const Common::String name() const override { return _strsStrings[kMSIGameName]; }
int getNumColors() const override { return 256; }
+ // See setMacGuiColors()
+ uint32 getBlack() const override { return 255; }
+ uint32 getWhite() const override { return 254; }
+
bool handleEvent(Common::Event event) override;
const Graphics::Font *getFontByScummId(int32 id) override;
@@ -68,6 +72,9 @@ protected:
void onMenuOpen() override;
void onMenuClose() override;
+ void drawSliderBackground(MacDialogWindow *window, int x, int y, int width, int ticks);
+ void drawDottedFrame(MacDialogWindow *window, Common::Rect bounds, int x1, int x2);
+
void runAboutDialog() override;
bool runOpenDialog(int &saveSlotToHandle) override;
bool runSaveDialog(int &saveSlotToHandle, Common::String &saveName) override;
Commit: 2d1ad751b06809610e98e2289987e4ac5493f944
https://github.com/scummvm/scummvm/commit/2d1ad751b06809610e98e2289987e4ac5493f944
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add missing static graphics to Sam & Max options dialog
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index da703bfabb1..85594538256 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -823,6 +823,18 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
if (res) {
saveScreen();
+ // Collect the palettes from all the icons and pictures
+ // in the dialog, and combine them into a single palette
+ // that they will all be remapped to use. This is
+ // probably not what the original did, as the colors
+ // become slightly different. Maybe the original just
+ // picked one of the palettes, and then used the
+ // closest available colors for the rest?
+ //
+ // That might explain why some of them have seemingly
+ // larger palettes than necessary, but why not use the
+ // exact colors when we can?
+
Common::HashMap<uint32, byte> paletteMap;
int numWindowColors = 0;
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 1a6ea23a586..0bd446a54d7 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -596,18 +596,11 @@ bool MacV6Gui::runSaveDialog(int &saveSlotToHandle, Common::String &saveName) {
}
bool MacV6Gui::runOptionsDialog() {
- // TODO: How to guarantee that the window has all the colors it needs
- // for its pictures?
-
// There are too many different variations to list all widgets here.
// The important thing that they share are that the first three buttons
// are OK, Cancel, and Defaults, and that with the exception of Maniac
// Mansion they expect the first text to contain the name of the game
// as "^3".
- //
- // Strangely enough, Day of the Tentacle seems to use a lot more "User
- // items" than the other ones, which means we'll have to hard-code them
- // here instead.
int dialogId = (_vm->_game.id == GID_MANIAC) ? 385 : 257;
@@ -626,6 +619,10 @@ bool MacV6Gui::runOptionsDialog() {
window->setDefaultWidget(buttonOk);
+ Graphics::Surface *surface = window->innerSurface();
+ const Graphics::Font *font = getFont(kSystemFont);
+ uint32 black = getBlack();
+
if (_vm->_game.id == GID_TENTACLE) {
// Unlike the other games, Day of the Tentacle uses a lot of
// "user items" which we don't have a way to parse.
@@ -650,18 +647,29 @@ bool MacV6Gui::runOptionsDialog() {
}
}
- uint32 black = getBlack();
+ font->drawString(surface, "Volume Settings", 27, 33, 110, black);
+ font->drawString(surface, "Voice & Effects:", 23, 85, 105, black);
+ font->drawString(surface, "Text & Voice Settings", 26, 122, 140, black);
+ font->drawString(surface, "Interact using:", 21, 149, 105, black);
+ font->drawString(surface, "Text Speed:", 22, 175, 105, black);
+ font->drawString(surface, "Video Quality:", 21, 219, 105, black);
- const Graphics::Font *font = getFont(kSystemFont);
- font->drawString(window->innerSurface(), "Volume Settings", 27, 33, 110, black);
- font->drawString(window->innerSurface(), "Voice & Effects:", 23, 85, 105, black);
- font->drawString(window->innerSurface(), "Text & Voice Settings", 26, 122, 140, black);
- font->drawString(window->innerSurface(), "Interact using:", 21, 149, 105, black);
- font->drawString(window->innerSurface(), "Text Speed:", 22, 175, 105, black);
- font->drawString(window->innerSurface(), "Video Quality:", 21, 219, 105, black);
+ // Yes, the frames really are supposed to be slightly
+ // misaligned to match the original appearance.
drawDottedFrame(window, Common::Rect(12, 41, 337, 113), 21, 137);
drawDottedFrame(window, Common::Rect(11, 130, 336, 203), 20, 168);
+ } else if (_vm->_game.id == GID_SAMNMAX) {
+ drawSliderBackground(window, 152, 63, 147, 17);
+ drawSliderBackground(window, 152, 87, 147, 17);
+ drawSliderBackground(window, 152, 111, 147, 17);
+ drawSliderBackground(window, 152, 203, 147, 9);
+
+ font->drawString(surface, "Interact using:", 22, 175, 105, black);
+ font->drawString(surface, "Video Quality:", 22, 245, 105, black);
+
+ drawDottedFrame(window, Common::Rect(12, 41, 337, 136), 21, 137);
+ drawDottedFrame(window, Common::Rect(12, 156, 337, 229), 20, 168);
}
Common::Array<int> deferredActionsIds;
Commit: acaf166943686b2ca4dab7e1d5c04001c4123002
https://github.com/scummvm/scummvm/commit/acaf166943686b2ca4dab7e1d5c04001c4123002
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add missing static graphics to Full Throttle options
And The Dig, but that turned out to be identical to Sam & Max.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 0bd446a54d7..1d2c7713ec0 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -659,7 +659,7 @@ bool MacV6Gui::runOptionsDialog() {
drawDottedFrame(window, Common::Rect(12, 41, 337, 113), 21, 137);
drawDottedFrame(window, Common::Rect(11, 130, 336, 203), 20, 168);
- } else if (_vm->_game.id == GID_SAMNMAX) {
+ } else if (_vm->_game.id == GID_SAMNMAX || _vm->_game.id == GID_DIG) {
drawSliderBackground(window, 152, 63, 147, 17);
drawSliderBackground(window, 152, 87, 147, 17);
drawSliderBackground(window, 152, 111, 147, 17);
@@ -670,6 +670,17 @@ bool MacV6Gui::runOptionsDialog() {
drawDottedFrame(window, Common::Rect(12, 41, 337, 136), 21, 137);
drawDottedFrame(window, Common::Rect(12, 156, 337, 229), 20, 168);
+ } else if (_vm->_game.id == GID_FT) {
+ drawSliderBackground(window, 152, 63, 147, 17);
+ drawSliderBackground(window, 152, 87, 147, 17);
+ drawSliderBackground(window, 152, 111, 147, 17);
+ drawSliderBackground(window, 152, 231, 147, 9);
+
+ font->drawString(surface, "Interact using:", 22, 203, 105, black);
+ font->drawString(surface, "Video Quality:", 22, 273, 105, black);
+
+ drawDottedFrame(window, Common::Rect(12, 41, 337, 164), 21, 137);
+ drawDottedFrame(window, Common::Rect(12, 184, 337, 257), 20, 168);
}
Common::Array<int> deferredActionsIds;
Commit: 75a54c3298ca9f8512063e11817a305d0245fc9f
https://github.com/scummvm/scummvm/commit/75a54c3298ca9f8512063e11817a305d0245fc9f
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add missing static graphics to Maniac Mansion options
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 1d2c7713ec0..195b2da8601 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -321,7 +321,7 @@ void MacV6Gui::onMenuClose() {
restoreScreen();
}
-void MacV6Gui::drawSliderBackground(MacDialogWindow *window, int x, int y, int width, int ticks) {
+void MacV6Gui::drawSliderBackground(MacDialogWindow *window, int x, int y, int width, int numMarkings, int primaryMarkings) {
Graphics::Surface *s = window->innerSurface();
uint32 gray = _windowManager->findBestColor(0xCD, 0xCD, 0xCD);
@@ -335,9 +335,9 @@ void MacV6Gui::drawSliderBackground(MacDialogWindow *window, int x, int y, int w
int yt = y + 14;
- for (int i = 0; i < ticks; i++) {
- int ht = ((i % 4) == 0) ? 4 : 2;
- s->vLine(x + (i * (width - 1)) / (ticks - 1), yt, yt + ht, black);
+ for (int i = 0; i < numMarkings; i++) {
+ int ht = ((i % primaryMarkings) == 0) ? 4 : 2;
+ s->vLine(x + (i * (width - 1)) / (numMarkings - 1), yt, yt + ht, black);
}
}
@@ -659,6 +659,10 @@ bool MacV6Gui::runOptionsDialog() {
drawDottedFrame(window, Common::Rect(12, 41, 337, 113), 21, 137);
drawDottedFrame(window, Common::Rect(11, 130, 336, 203), 20, 168);
+ } else if (_vm->_game.id == GID_MANIAC) {
+ drawSliderBackground(window, 152, 41, 147, 17);
+ drawSliderBackground(window, 152, 72, 147, 10, 5);
+ font->drawString(surface, "Video Quality:", 22, 101, 105, black);
} else if (_vm->_game.id == GID_SAMNMAX || _vm->_game.id == GID_DIG) {
drawSliderBackground(window, 152, 63, 147, 17);
drawSliderBackground(window, 152, 87, 147, 17);
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index f53d969314e..913acefd484 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -72,7 +72,7 @@ protected:
void onMenuOpen() override;
void onMenuClose() override;
- void drawSliderBackground(MacDialogWindow *window, int x, int y, int width, int ticks);
+ void drawSliderBackground(MacDialogWindow *window, int x, int y, int width, int numMarkings, int primaryMarkings = 4);
void drawDottedFrame(MacDialogWindow *window, Common::Rect bounds, int x1, int x2);
void runAboutDialog() override;
Commit: c6b5fb68764efa77f5107a86f71551b23e87ef9a
https://github.com/scummvm/scummvm/commit/c6b5fb68764efa77f5107a86f71551b23e87ef9a
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Work in progress on the drop down list widget
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index b5ace204980..8e468b146c3 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -303,6 +303,12 @@ MacGuiImpl::MacListBox *MacGuiImpl::MacDialogWindow::addListBox(Common::Rect bou
return listBox;
}
+MacGuiImpl::MacDropDownList *MacGuiImpl::MacDialogWindow::addDropDownList(Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled) {
+ MacGuiImpl::MacDropDownList *dropDownList = new MacDropDownList(this, bounds, text, textWidth, texts, enabled);
+ addWidget(dropDownList, kWidgetDropDownList);
+ return dropDownList;
+}
+
void MacGuiImpl::MacDialogWindow::markRectAsDirty(Common::Rect r) {
_dirtyRects.push_back(r);
}
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index a6ba58b78e6..1cf4881c512 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -130,7 +130,8 @@ public:
kWidgetPicture,
kWidgetSlider,
kWidgetListBox,
- kWidgetPictureSlider
+ kWidgetPictureSlider,
+ kWidgetDropDownList
};
protected:
@@ -604,6 +605,24 @@ public:
bool handleKeyDown(Common::Event &event);
};
+ class MacDropDownList : public MacWidget {
+ private:
+ Common::StringArray _texts;
+ int _textWidth;
+ Graphics::Surface _dropDownBackground;
+ Common::Rect _dropDownBounds;
+
+ public:
+ MacDropDownList(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled);
+ ~MacDropDownList();
+
+ bool findWidget(int x, int y) const;
+ void draw(bool drawFocused = false);
+
+ void handleMouseDown(Common::Event &event);
+ bool handleMouseUp(Common::Event &event);
+ };
+
class MacDialogWindow {
private:
uint32 _black;
@@ -692,6 +711,7 @@ public:
MacGuiImpl::MacSlider *addSlider(int x, int y, int h, int minValue, int maxValue, int pageSize, bool enabled);
MacGuiImpl::MacPictureSlider *addPictureSlider(int backgroundId, int handleId, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin = 0, int rightMargin = 0);
MacGuiImpl::MacListBox *addListBox(Common::Rect bounds, Common::StringArray texts, bool enabled, bool contentUntouchable = false);
+ MacGuiImpl::MacDropDownList *addDropDownList(Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled);
void addSubstitution(Common::String text) { _substitutions.push_back(text); }
void replaceSubstitution(int nr, Common::String text) { _substitutions[nr] = text; }
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 195b2da8601..3778a608bb3 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -623,6 +623,22 @@ bool MacV6Gui::runOptionsDialog() {
const Graphics::Font *font = getFont(kSystemFont);
uint32 black = getBlack();
+ MacDropDownList *interactionDropDown = nullptr;
+ MacDropDownList *videoQualityDropDown = nullptr;
+
+ Common::StringArray interactMode;
+
+ if (_vm->_game.id != GID_MANIAC) {
+ interactMode.push_back("Text Only");
+ interactMode.push_back("Voice Only");
+ interactMode.push_back("Text & Voice");
+ }
+
+ Common::StringArray videoQuality;
+ videoQuality.push_back("Double Size");
+ videoQuality.push_back("Interlaced");
+ videoQuality.push_back("Small");
+
if (_vm->_game.id == GID_TENTACLE) {
// Unlike the other games, Day of the Tentacle uses a lot of
// "user items" which we don't have a way to parse.
@@ -650,41 +666,45 @@ bool MacV6Gui::runOptionsDialog() {
font->drawString(surface, "Volume Settings", 27, 33, 110, black);
font->drawString(surface, "Voice & Effects:", 23, 85, 105, black);
font->drawString(surface, "Text & Voice Settings", 26, 122, 140, black);
- font->drawString(surface, "Interact using:", 21, 149, 105, black);
font->drawString(surface, "Text Speed:", 22, 175, 105, black);
- font->drawString(surface, "Video Quality:", 21, 219, 105, black);
// Yes, the frames really are supposed to be slightly
// misaligned to match the original appearance.
drawDottedFrame(window, Common::Rect(12, 41, 337, 113), 21, 137);
drawDottedFrame(window, Common::Rect(11, 130, 336, 203), 20, 168);
+
+ interactionDropDown = window->addDropDownList(Common::Rect(17, 148, 322, 167), "Interact using:", 125, interactMode, true);
+ videoQualityDropDown = window->addDropDownList(Common::Rect(17, 218, 322, 237), "Video Quality:", 125, videoQuality, false);
+
+ interactionDropDown->setValue(2);
+ videoQualityDropDown->setValue(0);
} else if (_vm->_game.id == GID_MANIAC) {
drawSliderBackground(window, 152, 41, 147, 17);
drawSliderBackground(window, 152, 72, 147, 10, 5);
- font->drawString(surface, "Video Quality:", 22, 101, 105, black);
+
+ videoQualityDropDown = window->addDropDownList(Common::Rect(18, 100, 323, 119), "Video Quality:", 125, videoQuality, false);
} else if (_vm->_game.id == GID_SAMNMAX || _vm->_game.id == GID_DIG) {
drawSliderBackground(window, 152, 63, 147, 17);
drawSliderBackground(window, 152, 87, 147, 17);
drawSliderBackground(window, 152, 111, 147, 17);
drawSliderBackground(window, 152, 203, 147, 9);
- font->drawString(surface, "Interact using:", 22, 175, 105, black);
- font->drawString(surface, "Video Quality:", 22, 245, 105, black);
-
drawDottedFrame(window, Common::Rect(12, 41, 337, 136), 21, 137);
drawDottedFrame(window, Common::Rect(12, 156, 337, 229), 20, 168);
+
+ interactionDropDown = window->addDropDownList(Common::Rect(18, 174, 323, 193), "Interact using:", 125, interactMode, true);
+ videoQualityDropDown = window->addDropDownList(Common::Rect(18, 244, 323, 263), "Video Quality:", 125, videoQuality, false);
} else if (_vm->_game.id == GID_FT) {
drawSliderBackground(window, 152, 63, 147, 17);
drawSliderBackground(window, 152, 87, 147, 17);
drawSliderBackground(window, 152, 111, 147, 17);
drawSliderBackground(window, 152, 231, 147, 9);
- font->drawString(surface, "Interact using:", 22, 203, 105, black);
- font->drawString(surface, "Video Quality:", 22, 273, 105, black);
-
drawDottedFrame(window, Common::Rect(12, 41, 337, 164), 21, 137);
drawDottedFrame(window, Common::Rect(12, 184, 337, 257), 20, 168);
+ interactionDropDown = window->addDropDownList(Common::Rect(18, 202, 323, 221), "Interact using:", 125, interactMode, true);
+ videoQualityDropDown = window->addDropDownList(Common::Rect(18, 272, 323, 291), "Video Quality:", 125, videoQuality, false);
}
Common::Array<int> deferredActionsIds;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 0bed5086a2c..0603cc67c50 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -401,7 +401,7 @@ MacGuiImpl::MacEditText::MacEditText(MacGuiImpl::MacDialogWindow *window, Common
}
bool MacGuiImpl::MacEditText::findWidget(int x, int y) const {
- // Once we start dragging the handle, any mouse position is considered
+ // Once we start drag-selecting, any mouse position is considered
// within the widget.
if (_window->getFocusedWidget() == this)
@@ -1614,4 +1614,121 @@ bool MacGuiImpl::MacListBox::handleKeyDown(Common::Event &event) {
return false;
}
+// ---------------------------------------------------------------------------
+// Drop down widget
+// ---------------------------------------------------------------------------
+
+MacGuiImpl::MacDropDownList::MacDropDownList(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled) : MacWidget(window, bounds, text, enabled), _textWidth(textWidth), _texts(texts) {
+ _black = _window->_gui->getBlack();
+ _white = _window->_gui->getWhite();
+
+ _dropDownBounds.left = _bounds.left + _textWidth;
+ _dropDownBounds.right = _bounds.right;
+}
+
+MacGuiImpl::MacDropDownList::~MacDropDownList() {
+ _texts.clear();
+ _dropDownBackground.free();
+}
+
+bool MacGuiImpl::MacDropDownList::findWidget(int x, int y) const {
+ // Once we have opened the drop down list, any mouse position is
+ // considered within the widget.
+
+ if (_window->getFocusedWidget() == this)
+ return true;
+
+ return _bounds.contains(x, y);
+}
+
+void MacGuiImpl::MacDropDownList::draw(bool drawFocused) {
+ if (!_redraw && !_fullRedraw)
+ return;
+
+ debug(1, "MacGuiImpl::MacDropDownList: Drawing list box (_fullRedraw = %d, drawFocused = %d)", _fullRedraw, drawFocused);
+
+ // I don't know how Mac originally drew disabled drop downs lists, or
+ // if that was even a thing. For our purposes, the text is still
+ // relevant. We just need to make it obvious that you can't change it
+ // in any way.
+
+ uint32 fg, bg;
+ bool focused = drawFocused || _window->getFocusedWidget() == this;
+
+ if (focused) {
+ fg = _white;
+ bg = _black;
+ } else {
+ fg = _black;
+ bg = _white;
+ }
+
+ Graphics::Surface *s = _window->innerSurface();
+ const Graphics::Font *font = _window->_gui->getFont(kSystemFont);
+
+ s->fillRect(Common::Rect(_bounds.left, _bounds.top + 1, _bounds.left + _textWidth, _bounds.bottom - 2), bg);
+ font->drawString(s, _text, _bounds.left, _bounds.top + 1, _textWidth, fg, Graphics::kTextAlignLeft, 4);
+
+ if (focused) {
+ Common::Rect r = _dropDownBounds;
+ r.bottom--;
+ r.right--;
+
+ s->fillRect(r, _white);
+ s->frameRect(r, _black);
+ s->hLine(r.left + 3, r.bottom, r.right, _black);
+ s->vLine(r.right, r.top + 3, r.bottom - 1, _black);
+
+ for (uint i = 0; i < _texts.size(); i++) {
+ font->drawString(s, _texts[i], _dropDownBounds.left, _dropDownBounds.top + 16 * i + 1, _dropDownBounds.width() - 3, _black, Graphics::kTextAlignLeft, 15);
+ }
+
+ font->drawString(s, "\x12", _dropDownBounds.left, _bounds.top + 1, 15, _black, Graphics::kTextAlignLeft, 3);
+ } else {
+ s->frameRect(Common::Rect(_bounds.left + _textWidth, _bounds.top, _bounds.right - 1, _bounds.bottom - 1), _black);
+ s->hLine(_bounds.left + _textWidth + 3, _bounds.bottom - 1, _bounds.right - 1, _black);
+ s->vLine(_bounds.right - 1, _bounds.top + 3, _bounds.bottom - 2, _black);
+
+ font->drawString(s, _texts[_value], _bounds.left + _textWidth + 15, _bounds.top + 1, _bounds.width() - _textWidth - 25, _black);
+
+ const uint16 arrowDownIcon[16] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FF8, 0x1FF0, 0x0FE0,
+ 0x07C0, 0x0380, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ const uint16 disabledArrowDownIcon[16] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2AA8, 0x1550, 0x0AA0,
+ 0x0540, 0x0280, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+
+ Common::Rect iconRect(16, 16);
+ iconRect.moveTo(_bounds.right - 20, _bounds.top + 1);
+
+ drawBitmap(iconRect, _enabled ? arrowDownIcon : disabledArrowDownIcon, _black);
+ }
+
+ _redraw = false;
+ _fullRedraw = false;
+
+ _window->markRectAsDirty(_bounds);
+ if (focused)
+ _window->markRectAsDirty(_dropDownBounds);
+}
+
+void MacGuiImpl::MacDropDownList::handleMouseDown(Common::Event &event) {
+ _dropDownBounds.top = _bounds.top - 16 * _value;
+ _dropDownBounds.bottom = _bounds.bottom + 16 * (_texts.size() - _value - 1);
+
+ Graphics::Surface background = _window->innerSurface()->getSubArea(_dropDownBounds);
+
+ _dropDownBackground.free();
+ _dropDownBackground.copyFrom(background);
+}
+
+bool MacGuiImpl::MacDropDownList::handleMouseUp(Common::Event &event) {
+ _window->drawSprite(&_dropDownBackground, _dropDownBounds.left, _dropDownBounds.top);
+
+ return false;
+}
+
} // End of namespace Scumm
Commit: 4c2e85f11218c19cefdecce1d0604d68f8f7430c
https://github.com/scummvm/scummvm/commit/4c2e85f11218c19cefdecce1d0604d68f8f7430c
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Finish drop down implementation, at least for now
Changed paths:
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 1cf4881c512..0b118afbad8 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -609,6 +609,8 @@ public:
private:
Common::StringArray _texts;
int _textWidth;
+ bool _menuVisible = false;
+ int _selected;
Graphics::Surface _dropDownBackground;
Common::Rect _dropDownBounds;
@@ -621,6 +623,7 @@ public:
void handleMouseDown(Common::Event &event);
bool handleMouseUp(Common::Event &event);
+ void handleMouseMove(Common::Event &event);
};
class MacDialogWindow {
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 0603cc67c50..494d7fd604f 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -1679,17 +1679,35 @@ void MacGuiImpl::MacDropDownList::draw(bool drawFocused) {
s->hLine(r.left + 3, r.bottom, r.right, _black);
s->vLine(r.right, r.top + 3, r.bottom - 1, _black);
- for (uint i = 0; i < _texts.size(); i++) {
- font->drawString(s, _texts[i], _dropDownBounds.left, _dropDownBounds.top + 16 * i + 1, _dropDownBounds.width() - 3, _black, Graphics::kTextAlignLeft, 15);
- }
+ Common::Rect textRect(r.left + 1, r.top + 1, r.right - 1, r.top + 17);
+
+ for (int i = 0; i < (int)_texts.size(); i++) {
+ if (i == _selected) {
+ fg = _white;
+ bg = _black;
+ } else {
+ fg = _black;
+ bg = _white;
+ }
+
+ s->fillRect(textRect, bg);
- font->drawString(s, "\x12", _dropDownBounds.left, _bounds.top + 1, 15, _black, Graphics::kTextAlignLeft, 3);
+ font->drawString(s, _texts[i], textRect.left, textRect.top, textRect.width(), fg, Graphics::kTextAlignLeft, 14);
+
+ if (i == _value)
+ font->drawString(s, "\x12", textRect.left + 2, textRect.top, 10, fg);
+
+ textRect.translate(0, 16);
+ }
} else {
- s->frameRect(Common::Rect(_bounds.left + _textWidth, _bounds.top, _bounds.right - 1, _bounds.bottom - 1), _black);
- s->hLine(_bounds.left + _textWidth + 3, _bounds.bottom - 1, _bounds.right - 1, _black);
- s->vLine(_bounds.right - 1, _bounds.top + 3, _bounds.bottom - 2, _black);
+ Common::Rect r(_bounds.left + _textWidth, _bounds.top, _bounds.right - 1, _bounds.bottom - 1);
- font->drawString(s, _texts[_value], _bounds.left + _textWidth + 15, _bounds.top + 1, _bounds.width() - _textWidth - 25, _black);
+ s->fillRect(r, _white);
+ s->frameRect(r, _black);
+ s->hLine(r.left + 3, r.bottom, r.right, _black);
+ s->vLine(r.right, r.top + 3, r.bottom - 1, _black);
+
+ font->drawString(s, _texts[_value], r.left, r.top + 1, r.width() - 20, _black, Graphics::kTextAlignLeft, 15);
const uint16 arrowDownIcon[16] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FF8, 0x1FF0, 0x0FE0,
@@ -1702,7 +1720,7 @@ void MacGuiImpl::MacDropDownList::draw(bool drawFocused) {
};
Common::Rect iconRect(16, 16);
- iconRect.moveTo(_bounds.right - 20, _bounds.top + 1);
+ iconRect.moveTo(r.right - 19, r.top + 1);
drawBitmap(iconRect, _enabled ? arrowDownIcon : disabledArrowDownIcon, _black);
}
@@ -1723,12 +1741,68 @@ void MacGuiImpl::MacDropDownList::handleMouseDown(Common::Event &event) {
_dropDownBackground.free();
_dropDownBackground.copyFrom(background);
+
+ _menuVisible = true;
+ _selected = _value;
}
bool MacGuiImpl::MacDropDownList::handleMouseUp(Common::Event &event) {
+ if (_selected != -1) {
+ int selected = _selected;
+
+ for (int i = 0; i < 6; i++) {
+ if (_selected == selected)
+ _selected = -1;
+ else
+ _selected = selected;
+
+ // It is a bit wasteful to redraw the entire widget
+ // just for this. It's also a lot easier.
+
+ setRedraw();
+ _window->update();
+
+ for (int j = 0; j < 3; j++) {
+ Common::Event e;
+ while (_window->_system->getEventManager()->pollEvent(e))
+ ;
+ _window->_system->delayMillis(10);
+ _window->_system->updateScreen();
+ }
+ }
+
+ setValue(selected);
+ }
+
_window->drawSprite(&_dropDownBackground, _dropDownBounds.left, _dropDownBounds.top);
+ _menuVisible = false;
return false;
}
+void MacGuiImpl::MacDropDownList::handleMouseMove(Common::Event &event) {
+ if (!_menuVisible)
+ return;
+
+ Common::Rect menuBounds(_dropDownBounds.left + 1, _dropDownBounds.top + 1, _dropDownBounds.right - 2, _dropDownBounds.bottom - 2);
+
+ int selected = -1;
+
+ if (menuBounds.contains(event.mouse.x, event.mouse.y)) {
+ selected = (event.mouse.y - menuBounds.top) / 16;
+
+ int maxValue = _texts.size() - 1;
+
+ if (selected > maxValue) {
+ warning("MacGuiImpl::MacDropDownList::handleMouseMove: Max selection value exceeded");
+ selected = -1;
+ }
+ }
+
+ if (selected != _selected) {
+ _selected = selected;
+ setRedraw();
+ }
+}
+
} // End of namespace Scumm
Commit: 281c2bacbc418ad16ea32719717b4cb810325e7e
https://github.com/scummvm/scummvm/commit/281c2bacbc418ad16ea32719717b4cb810325e7e
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Combine MacIcon and MacPicture into a single widget
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_indy3.cpp
engines/scumm/macgui/macgui_loom.cpp
engines/scumm/macgui/macgui_v5.cpp
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index 8e468b146c3..ff90b5de57c 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -267,15 +267,15 @@ MacGuiImpl::MacEditText *MacGuiImpl::MacDialogWindow::addEditText(Common::Rect b
return editText;
}
-MacGuiImpl::MacIcon *MacGuiImpl::MacDialogWindow::addIcon(Common::Rect bounds, int id, bool enabled) {
- MacGuiImpl::MacIcon *icon = new MacIcon(this, bounds, id, false);
+MacGuiImpl::MacImage *MacGuiImpl::MacDialogWindow::addIcon(Common::Rect bounds, int id, bool enabled) {
+ MacGuiImpl::MacImage *icon = new MacImage(this, bounds, _gui->loadIcon(id), false);
addWidget(icon, kWidgetIcon);
return icon;
}
-MacGuiImpl::MacPicture *MacGuiImpl::MacDialogWindow::addPicture(Common::Rect bounds, int id, bool enabled) {
- MacGuiImpl::MacPicture *picture = new MacPicture(this, bounds, id, false);
- addWidget(picture, kWidgetPicture);
+MacGuiImpl::MacImage *MacGuiImpl::MacDialogWindow::addPicture(Common::Rect bounds, int id, bool enabled) {
+ MacGuiImpl::MacImage *picture = new MacImage(this, bounds, _gui->loadPict(id), false);
+ addWidget(picture, kWidgetImage);
return picture;
}
@@ -285,15 +285,15 @@ MacGuiImpl::MacSlider *MacGuiImpl::MacDialogWindow::addSlider(int x, int y, int
return slider;
}
-MacGuiImpl::MacPictureSlider *MacGuiImpl::MacDialogWindow::addPictureSlider(int backgroundId, int handleId, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin, int rightMargin) {
- MacPicture *background = (MacPicture *)_widgets[backgroundId];
- MacPicture *handle = (MacPicture *)_widgets[handleId];
+MacGuiImpl::MacImageSlider *MacGuiImpl::MacDialogWindow::addImageSlider(int backgroundId, int handleId, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin, int rightMargin) {
+ MacImage *background = (MacImage *)_widgets[backgroundId];
+ MacImage *handle = (MacImage *)_widgets[handleId];
background->setVisible(false);
handle->setVisible(false);
- MacGuiImpl::MacPictureSlider *slider = new MacPictureSlider(this, background, handle, enabled, minX, maxX, minValue, maxValue, leftMargin, rightMargin);
- addWidget(slider, kWidgetPictureSlider);
+ MacGuiImpl::MacImageSlider *slider = new MacImageSlider(this, background, handle, enabled, minX, maxX, minValue, maxValue, leftMargin, rightMargin);
+ addWidget(slider, kWidgetImageSlider);
return slider;
}
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 0b118afbad8..7c9371513d0 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -127,10 +127,10 @@ public:
kWidgetStaticText,
kWidgetEditText,
kWidgetIcon,
- kWidgetPicture,
+ kWidgetImage,
kWidgetSlider,
kWidgetListBox,
- kWidgetPictureSlider,
+ kWidgetImageSlider,
kWidgetDropDownList
};
@@ -443,28 +443,15 @@ public:
void handleMouseMove(Common::Event &event) override;
};
- class MacIcon : public MacWidget {
+ class MacImage : public MacWidget {
private:
- Graphics::Surface *_icon = nullptr;
+ Graphics::Surface *_image = nullptr;
public:
- MacIcon(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, int id, bool enabled);
- ~MacIcon();
+ MacImage(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Graphics::Surface *surface, bool enabled);
+ ~MacImage();
- Graphics::Surface *getIcon() const { return _icon; }
-
- void draw(bool drawFocused = false);
- };
-
- class MacPicture : public MacWidget {
- private:
- Graphics::Surface *_picture = nullptr;
-
- public:
- MacPicture(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, int id, bool enabled);
- ~MacPicture();
-
- Graphics::Surface *getPicture() const { return _picture; }
+ Graphics::Surface *getImage() const { return _image; }
void draw(bool drawFocused = false);
};
@@ -537,10 +524,10 @@ public:
void handleWheelDown();
};
- class MacPictureSlider : public MacSliderBase {
+ class MacImageSlider : public MacSliderBase {
private:
- MacPicture *_background;
- MacPicture *_handle;
+ MacImage *_background;
+ MacImage *_handle;
int _minX;
int _maxX;
@@ -548,7 +535,7 @@ public:
void drawHandle();
public:
- MacPictureSlider(MacGuiImpl::MacDialogWindow *window, MacPicture *background, MacPicture *handle, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin, int rightMargin)
+ MacImageSlider(MacGuiImpl::MacDialogWindow *window, MacImage *background, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin, int rightMargin)
: MacSliderBase(window, background->getBounds(), minValue, maxValue, minX + leftMargin, maxX - rightMargin, enabled),
_background(background), _handle(handle), _minX(minX),
_maxX(maxX) {}
@@ -709,10 +696,10 @@ public:
MacGuiImpl::MacCheckbox *addCheckbox(Common::Rect bounds, Common::String text, bool enabled);
MacGuiImpl::MacStaticText *addStaticText(Common::Rect bounds, Common::String text, bool enabled, Graphics::TextAlign alignment = Graphics::kTextAlignLeft);
MacGuiImpl::MacEditText *addEditText(Common::Rect bounds, Common::String text, bool enabled);
- MacGuiImpl::MacIcon *addIcon(Common::Rect bounds, int id, bool enabled);
- MacGuiImpl::MacPicture *addPicture(Common::Rect bounds, int id, bool enabled);
+ MacGuiImpl::MacImage *addIcon(Common::Rect bounds, int id, bool enabled);
+ MacGuiImpl::MacImage *addPicture(Common::Rect bounds, int id, bool enabled);
MacGuiImpl::MacSlider *addSlider(int x, int y, int h, int minValue, int maxValue, int pageSize, bool enabled);
- MacGuiImpl::MacPictureSlider *addPictureSlider(int backgroundId, int handleId, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin = 0, int rightMargin = 0);
+ MacGuiImpl::MacImageSlider *addImageSlider(int backgroundId, int handleId, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin = 0, int rightMargin = 0);
MacGuiImpl::MacListBox *addListBox(Common::Rect bounds, Common::StringArray texts, bool enabled, bool contentUntouchable = false);
MacGuiImpl::MacDropDownList *addDropDownList(Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled);
diff --git a/engines/scumm/macgui/macgui_indy3.cpp b/engines/scumm/macgui/macgui_indy3.cpp
index 3b1bc5ccf29..37eb62a3fe2 100644
--- a/engines/scumm/macgui/macgui_indy3.cpp
+++ b/engines/scumm/macgui/macgui_indy3.cpp
@@ -1529,7 +1529,7 @@ bool MacIndy3Gui::runOptionsDialog() {
if (!sound)
checkboxMusic->setEnabled(false);
- MacPictureSlider *sliderTextSpeed = window->addPictureSlider(4, 5, true, 5, 105, 0, 9);
+ MacImageSlider *sliderTextSpeed = window->addImageSlider(4, 5, true, 5, 105, 0, 9);
sliderTextSpeed->setValue(textSpeed);
window->addSubstitution(Common::String::format("%d", _vm->VAR(_vm->VAR_MACHINE_SPEED)));
diff --git a/engines/scumm/macgui/macgui_loom.cpp b/engines/scumm/macgui/macgui_loom.cpp
index 54271d811fb..1089405beac 100644
--- a/engines/scumm/macgui/macgui_loom.cpp
+++ b/engines/scumm/macgui/macgui_loom.cpp
@@ -530,10 +530,10 @@ bool MacLoomGui::runOptionsDialog() {
if (!sound)
checkboxMusic->setEnabled(false);
- MacPictureSlider *sliderTextSpeed = window->addPictureSlider(4, 5, true, 5, 105, 0, 9);
+ MacImageSlider *sliderTextSpeed = window->addImageSlider(4, 5, true, 5, 105, 0, 9);
sliderTextSpeed->setValue(textSpeed);
- MacPictureSlider *sliderMusicQuality = window->addPictureSlider(8, 9, true, 5, 69, 0, 2, 6, 4);
+ MacImageSlider *sliderMusicQuality = window->addImageSlider(8, 9, true, 5, 69, 0, 2, 6, 4);
sliderMusicQuality->setValue(musicQualityOption);
// Machine rating
diff --git a/engines/scumm/macgui/macgui_v5.cpp b/engines/scumm/macgui/macgui_v5.cpp
index ad46cc74d90..dd79a19c3ca 100644
--- a/engines/scumm/macgui/macgui_v5.cpp
+++ b/engines/scumm/macgui/macgui_v5.cpp
@@ -836,8 +836,8 @@ bool MacV5Gui::runOptionsDialog() {
MacCheckbox *checkboxSound = (MacCheckbox *)window->getWidget(kWidgetCheckbox, 0);
MacCheckbox *checkboxMusic = nullptr;
- MacPictureSlider *sliderTextSpeed = window->addPictureSlider(4, 5, true, 5, 105, 0, 9);
- MacPictureSlider *sliderMusicQuality = window->addPictureSlider(8, 9, true, 5, 69, 0, 2, 6, 4);
+ MacImageSlider *sliderTextSpeed = window->addImageSlider(4, 5, true, 5, 105, 0, 9);
+ MacImageSlider *sliderMusicQuality = window->addImageSlider(8, 9, true, 5, 69, 0, 2, 6, 4);
bool sound = !ConfMan.hasKey("mute") || !ConfMan.getBool("mute");
bool music;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 494d7fd604f..7aed160745b 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -804,56 +804,28 @@ void MacGuiImpl::MacEditText::handleMouseMove(Common::Event &event) {
}
// ---------------------------------------------------------------------------
-// Icon widget
+// Image widget
// ---------------------------------------------------------------------------
-MacGuiImpl::MacIcon::MacIcon(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, int id, bool enabled) : MacWidget(window, bounds, "Icon", enabled) {
- _icon = _window->_gui->loadIcon(id);
+MacGuiImpl::MacImage::MacImage(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Graphics::Surface *surface, bool enabled) : MacWidget(window, bounds, "Picture", enabled) {
+ _image = surface;
}
-MacGuiImpl::MacIcon::~MacIcon() {
- if (_icon) {
- _icon->free();
- delete _icon;
+MacGuiImpl::MacImage::~MacImage() {
+ if (_image) {
+ _image->free();
+ delete _image;
}
}
-void MacGuiImpl::MacIcon::draw(bool drawFocused) {
+void MacGuiImpl::MacImage::draw(bool drawFocused) {
if (!_redraw && !_fullRedraw)
return;
- debug(1, "MacGuiImpl::MacIcon: Drawing icon %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
+ debug(1, "MacGuiImpl::MacImage: Drawing picture %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
- if (_icon)
- _window->drawSprite(_icon, _bounds.left, _bounds.top);
-
- _redraw = false;
- _fullRedraw = false;
-}
-
-// ---------------------------------------------------------------------------
-// Picture widget
-// ---------------------------------------------------------------------------
-
-MacGuiImpl::MacPicture::MacPicture(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, int id, bool enabled) : MacWidget(window, bounds, "Picture", enabled) {
- _picture = _window->_gui->loadPict(id);
-}
-
-MacGuiImpl::MacPicture::~MacPicture() {
- if (_picture) {
- _picture->free();
- delete _picture;
- }
-}
-
-void MacGuiImpl::MacPicture::draw(bool drawFocused) {
- if (!_redraw && !_fullRedraw)
- return;
-
- debug(1, "MacGuiImpl::MacPicture: Drawing picture %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
-
- if (_picture)
- _window->drawSprite(_picture, _bounds.left, _bounds.top);
+ if (_image)
+ _window->drawSprite(_image, _bounds.left, _bounds.top);
_redraw = false;
_fullRedraw = false;
@@ -1290,12 +1262,12 @@ void MacGuiImpl::MacSlider::handleWheelDown() {
}
// ---------------------------------------------------------------------------
-// Picture slider widget. This is the custom slider widget used for the Loom
+// Image slider widget. This is the custom slider widget used for the Loom
// and Indy 3 options dialogs. It consists of a background image and a slider
// drag handle.
// ---------------------------------------------------------------------------
-bool MacGuiImpl::MacPictureSlider::findWidget(int x, int y) const {
+bool MacGuiImpl::MacImageSlider::findWidget(int x, int y) const {
// Once we start dragging the handle, any mouse position is considered
// within the widget.
@@ -1305,14 +1277,14 @@ bool MacGuiImpl::MacPictureSlider::findWidget(int x, int y) const {
return _bounds.contains(x, y);
}
-void MacGuiImpl::MacPictureSlider::draw(bool drawFocused) {
+void MacGuiImpl::MacImageSlider::draw(bool drawFocused) {
if (!_redraw && !_fullRedraw)
return;
- debug(1, "MacGuiImpl::MacPictureSlider: Drawing slider %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
+ debug(1, "MacGuiImpl::MacImageSlider: Drawing slider %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
if (_fullRedraw) {
- _window->drawSprite(_background->getPicture(), _bounds.left, _bounds.top);
+ _window->drawSprite(_background->getImage(), _bounds.left, _bounds.top);
drawHandle();
}
@@ -1320,25 +1292,25 @@ void MacGuiImpl::MacPictureSlider::draw(bool drawFocused) {
_fullRedraw = false;
}
-void MacGuiImpl::MacPictureSlider::eraseHandle() {
+void MacGuiImpl::MacImageSlider::eraseHandle() {
Common::Rect r = _handle->getBounds();
int y = r.top - _bounds.top;
int w = r.width();
int h = r.height();
- Graphics::Surface *background = _background->getPicture();
+ Graphics::Surface *background = _background->getImage();
Graphics::Surface sprite = background->getSubArea(Common::Rect(_handlePos, y, _handlePos + w, y + h));
_window->drawSprite(&sprite, _bounds.left + _handlePos, r.top);
}
-void MacGuiImpl::MacPictureSlider::drawHandle() {
- Graphics::Surface *sprite = _handle->getPicture();
+void MacGuiImpl::MacImageSlider::drawHandle() {
+ Graphics::Surface *sprite = _handle->getImage();
Common::Rect r = _handle->getBounds();
_window->drawSprite(sprite, _bounds.left + _handlePos, r.top);
}
-void MacGuiImpl::MacPictureSlider::handleMouseDown(Common::Event &event) {
+void MacGuiImpl::MacImageSlider::handleMouseDown(Common::Event &event) {
int mouseX = event.mouse.x;
int handleWidth = _handle->getBounds().width();
@@ -1350,7 +1322,7 @@ void MacGuiImpl::MacPictureSlider::handleMouseDown(Common::Event &event) {
handleMouseMove(event);
}
-bool MacGuiImpl::MacPictureSlider::handleMouseUp(Common::Event &event) {
+bool MacGuiImpl::MacImageSlider::handleMouseUp(Common::Event &event) {
// Erase the drag rect, since the handle might not end up in
// the exact same spot.
int newValue = calculateValueFromPos();
@@ -1365,7 +1337,7 @@ bool MacGuiImpl::MacPictureSlider::handleMouseUp(Common::Event &event) {
return false;
}
-void MacGuiImpl::MacPictureSlider::handleMouseMove(Common::Event &event) {
+void MacGuiImpl::MacImageSlider::handleMouseMove(Common::Event &event) {
int newPos = CLIP<int>(event.mouse.x - _bounds.left - _grabOffset, _minX, _maxX);
if (newPos != _handlePos) {
@@ -1375,7 +1347,7 @@ void MacGuiImpl::MacPictureSlider::handleMouseMove(Common::Event &event) {
}
}
-void MacGuiImpl::MacPictureSlider::handleWheelUp() {
+void MacGuiImpl::MacImageSlider::handleWheelUp() {
int newValue = MAX(_minValue, _value + 1);
if (_value != newValue) {
@@ -1385,7 +1357,7 @@ void MacGuiImpl::MacPictureSlider::handleWheelUp() {
}
}
-void MacGuiImpl::MacPictureSlider::handleWheelDown() {
+void MacGuiImpl::MacImageSlider::handleWheelDown() {
int newValue = MIN(_maxValue, _value - 1);
if (_value != newValue) {
Commit: ad87f9305bf7c12b2ff1b8da714759edb1651546
https://github.com/scummvm/scummvm/commit/ad87f9305bf7c12b2ff1b8da714759edb1651546
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix palette regression with monochrome images
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 85594538256..1084513e64d 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -624,6 +624,16 @@ Graphics::Surface *MacGuiImpl::createRemappedSurface(const Graphics::Surface *su
byte paletteMap[256];
memset(paletteMap, 0, sizeof(paletteMap));
+ const byte monoPalette[] = {
+ 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00
+ };
+
+ if (colorCount == 0) {
+ colorCount = 2;
+ palette = monoPalette;
+ }
+
for (int i = 0; i < colorCount; i++) {
int r = palette[3 * i];
int g = palette[3 * i + 1];
Commit: 96067ff55a7e27d4f50039a89283de3faaf361db
https://github.com/scummvm/scummvm/commit/96067ff55a7e27d4f50039a89283de3faaf361db
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Preliminary work on image slider to support V6-7 sliders
I'm committing this while I consider how to get transparency to work for
the slider handle.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index ff90b5de57c..ae97849a536 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -267,8 +267,8 @@ MacGuiImpl::MacEditText *MacGuiImpl::MacDialogWindow::addEditText(Common::Rect b
return editText;
}
-MacGuiImpl::MacImage *MacGuiImpl::MacDialogWindow::addIcon(Common::Rect bounds, int id, bool enabled) {
- MacGuiImpl::MacImage *icon = new MacImage(this, bounds, _gui->loadIcon(id), false);
+MacGuiImpl::MacImage *MacGuiImpl::MacDialogWindow::addIcon(int x, int y, int id, bool enabled) {
+ MacGuiImpl::MacImage *icon = new MacImage(this, Common::Rect(x, y, x + 32, y + 32), _gui->loadIcon(id), false);
addWidget(icon, kWidgetIcon);
return icon;
}
@@ -297,6 +297,14 @@ MacGuiImpl::MacImageSlider *MacGuiImpl::MacDialogWindow::addImageSlider(int back
return slider;
}
+MacGuiImpl::MacImageSlider *MacGuiImpl::MacDialogWindow::addImageSlider(Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue) {
+ handle->setVisible(false);
+
+ MacGuiImpl::MacImageSlider *slider = new MacImageSlider(this, bounds, handle, enabled, minX, maxX, minValue, maxValue);
+ addWidget(slider, kWidgetImageSlider);
+ return slider;
+}
+
MacGuiImpl::MacListBox *MacGuiImpl::MacDialogWindow::addListBox(Common::Rect bounds, Common::StringArray texts, bool enabled, bool contentUntouchable) {
MacGuiImpl::MacListBox *listBox = new MacListBox(this, bounds, texts, enabled, contentUntouchable);
addWidget(listBox, kWidgetListBox);
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 1084513e64d..e2c4efd44f0 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -645,8 +645,7 @@ Graphics::Surface *MacGuiImpl::createRemappedSurface(const Graphics::Surface *su
paletteMap[i] = c;
}
- // Colors outside the palette are not remapped. Some images use 0xFF
- // for black, and that's what we're using too.
+ // Colors outside the palette are not remapped.
for (int i = colorCount; i < 256; i++)
paletteMap[i] = i;
@@ -655,7 +654,12 @@ Graphics::Surface *MacGuiImpl::createRemappedSurface(const Graphics::Surface *su
for (int y = 0; y < s->h; y++) {
for (int x = 0; x < s->w; x++) {
int color = surface->getPixel(x, y);
- s->setPixel(x, y, paletteMap[color]);
+ if (color > colorCount)
+ color = getBlack();
+ else
+ color = paletteMap[color];
+
+ s->setPixel(x, y, color);
}
}
} else {
@@ -827,6 +831,8 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
_macWhite = _windowManager->_colorWhite;
_macBlack = _windowManager->_colorBlack;
+
+debug("Collect palette");
if (_vm->_game.version >= 6 || _vm->_game.id == GID_MANIAC) {
res = resource.getResource(MKTAG('D', 'I', 'T', 'L'), dialogId);
@@ -992,7 +998,7 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
}
case 32:
// Icon
- window->addIcon(r, res->readUint16BE(), enabled);
+ window->addIcon(r.left, r.top, res->readUint16BE(), enabled);
break;
case 64:
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 7c9371513d0..6f0cf25ff1d 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -526,10 +526,11 @@ public:
class MacImageSlider : public MacSliderBase {
private:
- MacImage *_background;
+ Graphics::Surface *_background;
MacImage *_handle;
int _minX;
int _maxX;
+ bool _freeBackground = false;
void eraseHandle();
void drawHandle();
@@ -537,8 +538,10 @@ public:
public:
MacImageSlider(MacGuiImpl::MacDialogWindow *window, MacImage *background, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin, int rightMargin)
: MacSliderBase(window, background->getBounds(), minValue, maxValue, minX + leftMargin, maxX - rightMargin, enabled),
- _background(background), _handle(handle), _minX(minX),
+ _background(background->getImage()), _handle(handle), _minX(minX),
_maxX(maxX) {}
+ MacImageSlider(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue);
+ ~MacImageSlider();
bool findWidget(int x, int y) const;
void draw(bool drawFocused = false);
@@ -696,10 +699,11 @@ public:
MacGuiImpl::MacCheckbox *addCheckbox(Common::Rect bounds, Common::String text, bool enabled);
MacGuiImpl::MacStaticText *addStaticText(Common::Rect bounds, Common::String text, bool enabled, Graphics::TextAlign alignment = Graphics::kTextAlignLeft);
MacGuiImpl::MacEditText *addEditText(Common::Rect bounds, Common::String text, bool enabled);
- MacGuiImpl::MacImage *addIcon(Common::Rect bounds, int id, bool enabled);
+ MacGuiImpl::MacImage *addIcon(int x, int y, int id, bool enabled);
MacGuiImpl::MacImage *addPicture(Common::Rect bounds, int id, bool enabled);
MacGuiImpl::MacSlider *addSlider(int x, int y, int h, int minValue, int maxValue, int pageSize, bool enabled);
MacGuiImpl::MacImageSlider *addImageSlider(int backgroundId, int handleId, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin = 0, int rightMargin = 0);
+ MacGuiImpl::MacImageSlider *addImageSlider(Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue);
MacGuiImpl::MacListBox *addListBox(Common::Rect bounds, Common::StringArray texts, bool enabled, bool contentUntouchable = false);
MacGuiImpl::MacDropDownList *addDropDownList(Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled);
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 3778a608bb3..d9fab7163c6 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -339,6 +339,8 @@ void MacV6Gui::drawSliderBackground(MacDialogWindow *window, int x, int y, int w
int ht = ((i % primaryMarkings) == 0) ? 4 : 2;
s->vLine(x + (i * (width - 1)) / (numMarkings - 1), yt, yt + ht, black);
}
+
+ window->addIcon(x - 6, y - 4, 300, true);
}
void MacV6Gui::drawDottedFrame(MacDialogWindow *window, Common::Rect bounds, int x1, int x2) {
@@ -703,6 +705,7 @@ bool MacV6Gui::runOptionsDialog() {
drawDottedFrame(window, Common::Rect(12, 41, 337, 164), 21, 137);
drawDottedFrame(window, Common::Rect(12, 184, 337, 257), 20, 168);
+
interactionDropDown = window->addDropDownList(Common::Rect(18, 202, 323, 221), "Interact using:", 125, interactMode, true);
videoQualityDropDown = window->addDropDownList(Common::Rect(18, 272, 323, 291), "Video Quality:", 125, videoQuality, false);
}
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 7aed160745b..26d9490e0d9 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -1267,6 +1267,19 @@ void MacGuiImpl::MacSlider::handleWheelDown() {
// drag handle.
// ---------------------------------------------------------------------------
+MacGuiImpl::MacImageSlider::MacImageSlider(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue)
+ : MacSliderBase(window, bounds, minX, maxX, minX, maxX, enabled), _handle(handle), _minX(minX), _maxX(maxX) {
+ _background->copyFrom(window->innerSurface()->getSubArea(bounds));
+ _freeBackground = true;
+}
+
+MacGuiImpl::MacImageSlider::~MacImageSlider() {
+ if (_freeBackground && _background) {
+ _background->free();
+ delete _background;
+ }
+}
+
bool MacGuiImpl::MacImageSlider::findWidget(int x, int y) const {
// Once we start dragging the handle, any mouse position is considered
// within the widget.
@@ -1284,7 +1297,7 @@ void MacGuiImpl::MacImageSlider::draw(bool drawFocused) {
debug(1, "MacGuiImpl::MacImageSlider: Drawing slider %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
if (_fullRedraw) {
- _window->drawSprite(_background->getImage(), _bounds.left, _bounds.top);
+ _window->drawSprite(_background, _bounds.left, _bounds.top);
drawHandle();
}
@@ -1298,8 +1311,7 @@ void MacGuiImpl::MacImageSlider::eraseHandle() {
int w = r.width();
int h = r.height();
- Graphics::Surface *background = _background->getImage();
- Graphics::Surface sprite = background->getSubArea(Common::Rect(_handlePos, y, _handlePos + w, y + h));
+ Graphics::Surface sprite = _background->getSubArea(Common::Rect(_handlePos, y, _handlePos + w, y + h));
_window->drawSprite(&sprite, _bounds.left + _handlePos, r.top);
}
Commit: d940e901de0ef5ae3ea4909fadd9a421f028aefd
https://github.com/scummvm/scummvm/commit/d940e901de0ef5ae3ea4909fadd9a421f028aefd
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: The slider widgets sort of work
Changed paths:
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 6f0cf25ff1d..cf5ed49b5b7 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -538,8 +538,7 @@ public:
public:
MacImageSlider(MacGuiImpl::MacDialogWindow *window, MacImage *background, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin, int rightMargin)
: MacSliderBase(window, background->getBounds(), minValue, maxValue, minX + leftMargin, maxX - rightMargin, enabled),
- _background(background->getImage()), _handle(handle), _minX(minX),
- _maxX(maxX) {}
+ _background(background->getImage()), _handle(handle), _minX(minX), _maxX(maxX) {}
MacImageSlider(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue);
~MacImageSlider();
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index d9fab7163c6..fcde139df7a 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -321,28 +321,6 @@ void MacV6Gui::onMenuClose() {
restoreScreen();
}
-void MacV6Gui::drawSliderBackground(MacDialogWindow *window, int x, int y, int width, int numMarkings, int primaryMarkings) {
- Graphics::Surface *s = window->innerSurface();
-
- uint32 gray = _windowManager->findBestColor(0xCD, 0xCD, 0xCD);
- uint32 black = getBlack();
-
- Common::Rect r(width, 12);
- r.moveTo(x, y);
-
- s->fillRect(r, gray);
- s->frameRect(r, black);
-
- int yt = y + 14;
-
- for (int i = 0; i < numMarkings; i++) {
- int ht = ((i % primaryMarkings) == 0) ? 4 : 2;
- s->vLine(x + (i * (width - 1)) / (numMarkings - 1), yt, yt + ht, black);
- }
-
- window->addIcon(x - 6, y - 4, 300, true);
-}
-
void MacV6Gui::drawDottedFrame(MacDialogWindow *window, Common::Rect bounds, int x1, int x2) {
Graphics::Surface *s = window->innerSurface();
uint32 black = getBlack();
@@ -364,6 +342,31 @@ void MacV6Gui::drawDottedFrame(MacDialogWindow *window, Common::Rect bounds, int
}
}
+MacGuiImpl::MacImageSlider *MacV6Gui::addSlider(MacDialogWindow *window, int x, int y, int width, int numMarkings, int primaryMarkings) {
+ Graphics::Surface *s = window->innerSurface();
+
+ uint32 gray = _windowManager->findBestColor(0xCD, 0xCD, 0xCD);
+ uint32 black = getBlack();
+
+ Common::Rect r(width, 12);
+ r.moveTo(x, y);
+
+ s->fillRect(r, gray);
+ s->frameRect(r, black);
+
+ int yt = y + 14;
+
+ for (int i = 0; i < numMarkings; i++) {
+ int ht = ((i % primaryMarkings) == 0) ? 4 : 2;
+ s->vLine(x + (i * (width - 1)) / (numMarkings - 1), yt, yt + ht, black);
+ }
+
+ MacImage *handle = window->addIcon(x - 6, y - 4, 300, true);
+ MacImageSlider *slider = window->addImageSlider(Common::Rect(x - 6, y - 4, x + width + 7, y + 16), handle, true, 0, width - 1, 0, numMarkings - 1);
+
+ return slider;
+}
+
void MacV6Gui::runAboutDialog() {
ScummFile aboutFile(_vm);
if (!_vm->openFile(aboutFile, "ABOUT"))
@@ -645,10 +648,6 @@ bool MacV6Gui::runOptionsDialog() {
// Unlike the other games, Day of the Tentacle uses a lot of
// "user items" which we don't have a way to parse.
- drawSliderBackground(window, 152, 63, 147, 17);
- drawSliderBackground(window, 152, 87, 147, 17);
- drawSliderBackground(window, 151, 177, 147, 9);
-
Common::Point spritePos[] = {
Common::Point(133, 87),
Common::Point(310, 86),
@@ -676,36 +675,40 @@ bool MacV6Gui::runOptionsDialog() {
drawDottedFrame(window, Common::Rect(12, 41, 337, 113), 21, 137);
drawDottedFrame(window, Common::Rect(11, 130, 336, 203), 20, 168);
+ addSlider(window, 152, 63, 147, 17);
+ addSlider(window, 152, 87, 147, 17);
+ addSlider(window, 151, 177, 147, 9);
+
interactionDropDown = window->addDropDownList(Common::Rect(17, 148, 322, 167), "Interact using:", 125, interactMode, true);
videoQualityDropDown = window->addDropDownList(Common::Rect(17, 218, 322, 237), "Video Quality:", 125, videoQuality, false);
interactionDropDown->setValue(2);
videoQualityDropDown->setValue(0);
} else if (_vm->_game.id == GID_MANIAC) {
- drawSliderBackground(window, 152, 41, 147, 17);
- drawSliderBackground(window, 152, 72, 147, 10, 5);
+ addSlider(window, 152, 41, 147, 17);
+ addSlider(window, 152, 72, 147, 10, 5);
videoQualityDropDown = window->addDropDownList(Common::Rect(18, 100, 323, 119), "Video Quality:", 125, videoQuality, false);
} else if (_vm->_game.id == GID_SAMNMAX || _vm->_game.id == GID_DIG) {
- drawSliderBackground(window, 152, 63, 147, 17);
- drawSliderBackground(window, 152, 87, 147, 17);
- drawSliderBackground(window, 152, 111, 147, 17);
- drawSliderBackground(window, 152, 203, 147, 9);
-
drawDottedFrame(window, Common::Rect(12, 41, 337, 136), 21, 137);
drawDottedFrame(window, Common::Rect(12, 156, 337, 229), 20, 168);
+ addSlider(window, 152, 63, 147, 17);
+ addSlider(window, 152, 87, 147, 17);
+ addSlider(window, 152, 111, 147, 17);
+ addSlider(window, 152, 203, 147, 9);
+
interactionDropDown = window->addDropDownList(Common::Rect(18, 174, 323, 193), "Interact using:", 125, interactMode, true);
videoQualityDropDown = window->addDropDownList(Common::Rect(18, 244, 323, 263), "Video Quality:", 125, videoQuality, false);
} else if (_vm->_game.id == GID_FT) {
- drawSliderBackground(window, 152, 63, 147, 17);
- drawSliderBackground(window, 152, 87, 147, 17);
- drawSliderBackground(window, 152, 111, 147, 17);
- drawSliderBackground(window, 152, 231, 147, 9);
-
drawDottedFrame(window, Common::Rect(12, 41, 337, 164), 21, 137);
drawDottedFrame(window, Common::Rect(12, 184, 337, 257), 20, 168);
+ addSlider(window, 152, 63, 147, 17);
+ addSlider(window, 152, 87, 147, 17);
+ addSlider(window, 152, 111, 147, 17);
+ addSlider(window, 152, 231, 147, 9);
+
interactionDropDown = window->addDropDownList(Common::Rect(18, 202, 323, 221), "Interact using:", 125, interactMode, true);
videoQualityDropDown = window->addDropDownList(Common::Rect(18, 272, 323, 291), "Video Quality:", 125, videoQuality, false);
}
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 913acefd484..c8f10177c9d 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -72,9 +72,10 @@ protected:
void onMenuOpen() override;
void onMenuClose() override;
- void drawSliderBackground(MacDialogWindow *window, int x, int y, int width, int numMarkings, int primaryMarkings = 4);
void drawDottedFrame(MacDialogWindow *window, Common::Rect bounds, int x1, int x2);
+ MacGuiImpl::MacImageSlider *addSlider(MacDialogWindow *window, int x, int y, int width, int numMarkings, int primaryMarkings = 4);
+
void runAboutDialog() override;
bool runOpenDialog(int &saveSlotToHandle) override;
bool runSaveDialog(int &saveSlotToHandle, Common::String &saveName) override;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 26d9490e0d9..3f09cd3a67e 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -1268,7 +1268,8 @@ void MacGuiImpl::MacSlider::handleWheelDown() {
// ---------------------------------------------------------------------------
MacGuiImpl::MacImageSlider::MacImageSlider(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue)
- : MacSliderBase(window, bounds, minX, maxX, minX, maxX, enabled), _handle(handle), _minX(minX), _maxX(maxX) {
+ : MacSliderBase(window, bounds, minValue, maxValue, minX, maxX, enabled), _handle(handle), _minX(minX), _maxX(maxX) {
+ _background = new Graphics::Surface();
_background->copyFrom(window->innerSurface()->getSubArea(bounds));
_freeBackground = true;
}
Commit: 892f847a6adbc3a9b0426bee713d5681163366e0
https://github.com/scummvm/scummvm/commit/892f847a6adbc3a9b0426bee713d5681163366e0
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Use correct bounds for icons
They're not all 32x32 pixels.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index ae97849a536..4f9d665bcbf 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -268,15 +268,16 @@ MacGuiImpl::MacEditText *MacGuiImpl::MacDialogWindow::addEditText(Common::Rect b
}
MacGuiImpl::MacImage *MacGuiImpl::MacDialogWindow::addIcon(int x, int y, int id, bool enabled) {
- MacGuiImpl::MacImage *icon = new MacImage(this, Common::Rect(x, y, x + 32, y + 32), _gui->loadIcon(id), false);
- addWidget(icon, kWidgetIcon);
- return icon;
+ Graphics::Surface *icon = _gui->loadIcon(id);
+ MacGuiImpl::MacImage *image = new MacImage(this, Common::Rect(x, y, x + icon->w, y + icon->h), icon, false);
+ addWidget(image, kWidgetIcon);
+ return image;
}
MacGuiImpl::MacImage *MacGuiImpl::MacDialogWindow::addPicture(Common::Rect bounds, int id, bool enabled) {
- MacGuiImpl::MacImage *picture = new MacImage(this, bounds, _gui->loadPict(id), false);
- addWidget(picture, kWidgetImage);
- return picture;
+ MacGuiImpl::MacImage *image = new MacImage(this, bounds, _gui->loadPict(id), false);
+ addWidget(image, kWidgetImage);
+ return image;
}
MacGuiImpl::MacSlider *MacGuiImpl::MacDialogWindow::addSlider(int x, int y, int h, int minValue, int maxValue, int pageSize, bool enabled) {
Commit: e718203314113d4fc028b7d49a85ee523f97de09
https://github.com/scummvm/scummvm/commit/e718203314113d4fc028b7d49a85ee523f97de09
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add mechanism to override the calculated slider stops
Useful for the v6-7 sliders, which have to line up with the markings.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index e2c4efd44f0..f551c285a46 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -831,8 +831,6 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
_macWhite = _windowManager->_colorWhite;
_macBlack = _windowManager->_colorBlack;
-
-debug("Collect palette");
if (_vm->_game.version >= 6 || _vm->_game.id == GID_MANIAC) {
res = resource.getResource(MKTAG('D', 'I', 'T', 'L'), dialogId);
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index cf5ed49b5b7..4f7dc348bc6 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -465,6 +465,9 @@ public:
int _handlePos = -1;
int _grabOffset = -1;
+ Common::HashMap<int, int> _posToValue;
+ Common::HashMap<int, int> _valueToPos;
+
int calculateValueFromPos() const;
int calculatePosFromValue() const;
@@ -474,10 +477,20 @@ public:
_minValue(minValue), _maxValue(maxValue),
_minPos(minPos), _maxPos(maxPos) {}
+ virtual ~MacSliderBase() {
+ _posToValue.clear();
+ _valueToPos.clear();
+ }
+
void getFocus() {}
void loseFocus() {}
void setValue(int value);
+
+ void addStop(int pos, int value) {
+ _posToValue[pos] = value;
+ _valueToPos[value] = pos;
+ }
};
class MacSlider : public MacSliderBase {
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index fcde139df7a..3e94a5b95a9 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -356,14 +356,24 @@ MacGuiImpl::MacImageSlider *MacV6Gui::addSlider(MacDialogWindow *window, int x,
int yt = y + 14;
+ int *positions = new int[numMarkings];
+
for (int i = 0; i < numMarkings; i++) {
int ht = ((i % primaryMarkings) == 0) ? 4 : 2;
- s->vLine(x + (i * (width - 1)) / (numMarkings - 1), yt, yt + ht, black);
+ int xt = x + (i * (width - 1)) / (numMarkings - 1);
+ s->vLine(xt, yt, yt + ht, black);
+ positions[i] = xt - x;
}
MacImage *handle = window->addIcon(x - 6, y - 4, 300, true);
MacImageSlider *slider = window->addImageSlider(Common::Rect(x - 6, y - 4, x + width + 7, y + 16), handle, true, 0, width - 1, 0, numMarkings - 1);
+ for (int i = 0; i < numMarkings; i++)
+ slider->addStop(positions[i], i);
+
+ slider->setValue(0);
+
+ delete[] positions;
return slider;
}
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 3f09cd3a67e..d0d99cbcc4c 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -841,8 +841,13 @@ void MacGuiImpl::MacSliderBase::setValue(int value) {
}
int MacGuiImpl::MacSliderBase::calculateValueFromPos() const {
- int posRange = _maxPos - _minPos;
+ int value;
+
+ if (_posToValue.tryGetVal(_handlePos, value))
+ return value;
+
int posOffset = _handlePos - _minPos;
+ int posRange = _maxPos - _minPos;
int valueRange = _maxValue - _minValue;
int valueOffset = (posRange / 2 + valueRange * posOffset) / posRange;
@@ -851,6 +856,11 @@ int MacGuiImpl::MacSliderBase::calculateValueFromPos() const {
}
int MacGuiImpl::MacSliderBase::calculatePosFromValue() const {
+ int pos;
+
+ if (_valueToPos.tryGetVal(_value, pos))
+ return pos;
+
int valueRange = _maxValue - _minValue;
int valueOffset = _value - _minValue;
Commit: d4b243bb67ff6dbcff4dfae1804f1382a54194f0
https://github.com/scummvm/scummvm/commit/d4b243bb67ff6dbcff4dfae1804f1382a54194f0
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add "snap while dragging" for MacImageSlider
Used for v6-7 sliders. It's probably a bit off, but not enough to be
noticeable.
Changed paths:
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 4f7dc348bc6..6eace9cd78b 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -468,6 +468,8 @@ public:
Common::HashMap<int, int> _posToValue;
Common::HashMap<int, int> _valueToPos;
+ int calculateValueFromPos(int pos) const;
+ int calculatePosFromValue(int value) const;
int calculateValueFromPos() const;
int calculatePosFromValue() const;
@@ -544,6 +546,7 @@ public:
int _minX;
int _maxX;
bool _freeBackground = false;
+ bool _snapWhileDragging = false;
void eraseHandle();
void drawHandle();
@@ -558,6 +561,8 @@ public:
bool findWidget(int x, int y) const;
void draw(bool drawFocused = false);
+ void setSnapWhileDragging(bool snap) { _snapWhileDragging = snap; }
+
void handleMouseDown(Common::Event &event);
bool handleMouseUp(Common::Event &event);
void handleMouseMove(Common::Event &event);
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 3e94a5b95a9..52596caa805 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -371,6 +371,7 @@ MacGuiImpl::MacImageSlider *MacV6Gui::addSlider(MacDialogWindow *window, int x,
for (int i = 0; i < numMarkings; i++)
slider->addStop(positions[i], i);
+ slider->setSnapWhileDragging(true);
slider->setValue(0);
delete[] positions;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index d0d99cbcc4c..5b1036df2cd 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -841,12 +841,16 @@ void MacGuiImpl::MacSliderBase::setValue(int value) {
}
int MacGuiImpl::MacSliderBase::calculateValueFromPos() const {
+ return calculateValueFromPos(_handlePos);
+}
+
+int MacGuiImpl::MacSliderBase::calculateValueFromPos(int pos) const {
int value;
- if (_posToValue.tryGetVal(_handlePos, value))
+ if (_posToValue.tryGetVal(pos, value))
return value;
- int posOffset = _handlePos - _minPos;
+ int posOffset = pos - _minPos;
int posRange = _maxPos - _minPos;
int valueRange = _maxValue - _minValue;
@@ -856,13 +860,17 @@ int MacGuiImpl::MacSliderBase::calculateValueFromPos() const {
}
int MacGuiImpl::MacSliderBase::calculatePosFromValue() const {
+ return calculatePosFromValue(_value);
+}
+
+int MacGuiImpl::MacSliderBase::calculatePosFromValue(int value) const {
int pos;
- if (_valueToPos.tryGetVal(_value, pos))
+ if (_valueToPos.tryGetVal(value, pos))
return pos;
int valueRange = _maxValue - _minValue;
- int valueOffset = _value - _minValue;
+ int valueOffset = value - _minValue;
int posRange = _maxPos - _minPos;
int posOffset = (valueRange / 2 + posRange * valueOffset) / valueRange;
@@ -1361,7 +1369,15 @@ bool MacGuiImpl::MacImageSlider::handleMouseUp(Common::Event &event) {
}
void MacGuiImpl::MacImageSlider::handleMouseMove(Common::Event &event) {
- int newPos = CLIP<int>(event.mouse.x - _bounds.left - _grabOffset, _minX, _maxX);
+ int newPos;
+
+ if (_snapWhileDragging) {
+ // Even when overriding the stops, the calculated one should
+ // be close enough here.
+ int newValue = calculateValueFromPos(CLIP<int>(event.mouse.x - _bounds.left - _handle->getImage()->w / 2, _minX, _maxX));
+ newPos = calculatePosFromValue(newValue);
+ } else
+ newPos = CLIP<int>(event.mouse.x - _bounds.left - _grabOffset, _minX, _maxX);
if (newPos != _handlePos) {
eraseHandle();
Commit: a40fcc54010d6d25156e637f6e0d03e9f3f21ade
https://github.com/scummvm/scummvm/commit/a40fcc54010d6d25156e637f6e0d03e9f3f21ade
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add support for icon masks
This fixes transparency for the slider widget handles in v6-7 games.
Someone may want to adjust the image decoder later, but it will do for
now. Not all icons have useful masks, but some do.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_widgets.cpp
image/cicn.cpp
image/cicn.h
image/image_decoder.h
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index 4f9d665bcbf..229c7deff90 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -268,14 +268,15 @@ MacGuiImpl::MacEditText *MacGuiImpl::MacDialogWindow::addEditText(Common::Rect b
}
MacGuiImpl::MacImage *MacGuiImpl::MacDialogWindow::addIcon(int x, int y, int id, bool enabled) {
- Graphics::Surface *icon = _gui->loadIcon(id);
- MacGuiImpl::MacImage *image = new MacImage(this, Common::Rect(x, y, x + icon->w, y + icon->h), icon, false);
+ MacImageMask *mask;
+ Graphics::Surface *icon = _gui->loadIcon(id, &mask);
+ MacGuiImpl::MacImage *image = new MacImage(this, Common::Rect(x, y, x + icon->w, y + icon->h), icon, mask, false);
addWidget(image, kWidgetIcon);
return image;
}
MacGuiImpl::MacImage *MacGuiImpl::MacDialogWindow::addPicture(Common::Rect bounds, int id, bool enabled) {
- MacGuiImpl::MacImage *image = new MacImage(this, bounds, _gui->loadPict(id), false);
+ MacGuiImpl::MacImage *image = new MacImage(this, bounds, _gui->loadPict(id), nullptr, false);
addWidget(image, kWidgetImage);
return image;
}
@@ -735,6 +736,22 @@ MacGuiImpl::MacWidget *MacGuiImpl::MacDialogWindow::getWidget(MacWidgetType type
return nullptr;
}
+void MacGuiImpl::MacDialogWindow::drawSprite(const MacImage *image, int x, int y) {
+ const Graphics::Surface *surface = image->getImage();
+ const MacImageMask *mask = image->getMask();
+
+ if (mask) {
+ for (int y1 = 0; y1 < mask->h; y1++) {
+ for (int x1 = 0; x1 < mask->w; x1++) {
+ if (!mask->isMasked(x1, y1))
+ _innerSurface.setPixel(x + x1, y + y1, surface->getPixel(x1, y1));
+ }
+ }
+ markRectAsDirty(Common::Rect(x, y, x + surface->w, y + surface->h));
+ } else
+ drawSprite(image->getImage(), x, y);
+}
+
void MacGuiImpl::MacDialogWindow::drawSprite(const Graphics::Surface *sprite, int x, int y) {
_innerSurface.copyRectToSurface(*sprite, x, y, Common::Rect(sprite->w, sprite->h));
markRectAsDirty(Common::Rect(x, y, x + sprite->w, y + sprite->h));
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index f551c285a46..afd2396ee3f 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -673,7 +673,7 @@ Graphics::Surface *MacGuiImpl::createRemappedSurface(const Graphics::Surface *su
// Icon loader
// ---------------------------------------------------------------------------
-Graphics::Surface *MacGuiImpl::loadIcon(int id) {
+Graphics::Surface *MacGuiImpl::loadIcon(int id, MacImageMask **mask) {
Common::MacResManager resource;
resource.open(_resourceFile);
@@ -687,6 +687,17 @@ Graphics::Surface *MacGuiImpl::loadIcon(int id) {
const Graphics::Surface *surface = iconDecoder.getSurface();
const byte *palette = iconDecoder.getPalette();
+ if (iconDecoder.hasMask()) {
+ *mask = new MacImageMask();
+ uint maskSize = iconDecoder.getMaskRowBytes() * iconDecoder.getMaskHeight();
+ (*mask)->w = surface->w;
+ (*mask)->h = iconDecoder.getMaskHeight();
+ (*mask)->rowBytes = iconDecoder.getMaskRowBytes();
+
+ (*mask)->data = new byte[maskSize];
+ memcpy((*mask)->data, iconDecoder.getMask(), maskSize);
+ }
+
s = createRemappedSurface(surface, palette, iconDecoder.getPaletteColorCount());
}
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 6eace9cd78b..f467da7f24d 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -443,15 +443,34 @@ public:
void handleMouseMove(Common::Event &event) override;
};
+ struct MacImageMask {
+ uint16 w;
+ uint16 h;
+ uint16 rowBytes;
+ byte *data;
+
+ bool isMasked(int x, int y) const {
+ if (x < 0 || x >= w || y < 0 || y >= h)
+ return false;
+ return (data[y * rowBytes + x / 8] & (0x80 >> (x % 8))) == 0;
+ }
+ };
+
class MacImage : public MacWidget {
private:
Graphics::Surface *_image = nullptr;
+ uint16 _maskRowBytes = 0;
+ uint16 _maskHeight = 0;
+ const MacImageMask *_mask = nullptr;
public:
- MacImage(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Graphics::Surface *surface, bool enabled);
+ MacImage(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Graphics::Surface *surface, MacImageMask *mask, bool enabled);
~MacImage();
Graphics::Surface *getImage() const { return _image; }
+ const MacImageMask *getMask() const { return _mask; }
+ uint16 getMaskRowBytes() const { return _maskRowBytes; }
+ uint16 getMaskHeight() const { return _maskHeight; }
void draw(bool drawFocused = false);
};
@@ -739,6 +758,7 @@ public:
void drawDottedHLine(int x0, int y, int x1);
void fillPattern(Common::Rect r, uint16 pattern, bool fillBlack = true, bool fillWhite = true);
+ void drawSprite(const MacImage *image, int x, int y);
void drawSprite(const Graphics::Surface *sprite, int x, int y);
void drawSprite(const Graphics::Surface *sprite, int x, int y, Common::Rect clipRect);
void drawTexts(Common::Rect r, const TextLine *lines, bool inverse = false);
@@ -779,7 +799,7 @@ public:
const Graphics::Font *getFont(FontId fontId);
virtual const Graphics::Font *getFontByScummId(int32 id) = 0;
- Graphics::Surface *loadIcon(int id);
+ Graphics::Surface *loadIcon(int id, MacImageMask **mask);
Graphics::Surface *loadPict(int id);
virtual bool isVerbGuiActive() const { return false; }
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 5b1036df2cd..2f01db00613 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -807,8 +807,9 @@ void MacGuiImpl::MacEditText::handleMouseMove(Common::Event &event) {
// Image widget
// ---------------------------------------------------------------------------
-MacGuiImpl::MacImage::MacImage(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Graphics::Surface *surface, bool enabled) : MacWidget(window, bounds, "Picture", enabled) {
+MacGuiImpl::MacImage::MacImage(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Graphics::Surface *surface, MacImageMask *mask, bool enabled) : MacWidget(window, bounds, "Picture", enabled) {
_image = surface;
+ _mask = mask;
}
MacGuiImpl::MacImage::~MacImage() {
@@ -816,6 +817,10 @@ MacGuiImpl::MacImage::~MacImage() {
_image->free();
delete _image;
}
+ if (_mask) {
+ delete[] _mask->data;
+ delete _mask;
+ }
}
void MacGuiImpl::MacImage::draw(bool drawFocused) {
@@ -825,7 +830,7 @@ void MacGuiImpl::MacImage::draw(bool drawFocused) {
debug(1, "MacGuiImpl::MacImage: Drawing picture %d (_fullRedraw = %d, drawFocused = %d, _value = %d)", _id, _fullRedraw, drawFocused, _value);
if (_image)
- _window->drawSprite(_image, _bounds.left, _bounds.top);
+ _window->drawSprite(this, _bounds.left, _bounds.top);
_redraw = false;
_fullRedraw = false;
@@ -1335,10 +1340,8 @@ void MacGuiImpl::MacImageSlider::eraseHandle() {
}
void MacGuiImpl::MacImageSlider::drawHandle() {
- Graphics::Surface *sprite = _handle->getImage();
Common::Rect r = _handle->getBounds();
-
- _window->drawSprite(sprite, _bounds.left + _handlePos, r.top);
+ _window->drawSprite(_handle, _bounds.left + _handlePos, r.top);
}
void MacGuiImpl::MacImageSlider::handleMouseDown(Common::Event &event) {
diff --git a/image/cicn.cpp b/image/cicn.cpp
index 6df1f83b091..1dd51f92d90 100644
--- a/image/cicn.cpp
+++ b/image/cicn.cpp
@@ -33,6 +33,9 @@ CicnDecoder::CicnDecoder() {
_surface = nullptr;
_palette = nullptr;
_paletteColorCount = 0;
+ _mask = nullptr;
+ _maskRowBytes = 0;
+ _maskHeight = 0;
}
CicnDecoder::~CicnDecoder() {
@@ -48,10 +51,16 @@ void CicnDecoder::destroy() {
delete[] _palette;
_palette = nullptr;
-
_paletteColorCount = 0;
+
+ delete[] _mask;
+ _mask = nullptr;
+ _maskRowBytes = 0;
+ _maskHeight = 0;
}
+
+
bool CicnDecoder::loadStream(Common::SeekableReadStream &stream) {
destroy();
@@ -59,10 +68,10 @@ bool CicnDecoder::loadStream(Common::SeekableReadStream &stream) {
// Mask header
stream.skip(4);
- uint16 maskRowBytes = stream.readUint16BE();
+ _maskRowBytes = stream.readUint16BE();
stream.readUint16BE(); // top
stream.readUint16BE(); // left
- uint16 maskHeight = stream.readUint16BE(); // bottom
+ _maskHeight = stream.readUint16BE(); // bottom
stream.readUint16BE(); // right
// Bitmap header
@@ -75,7 +84,11 @@ bool CicnDecoder::loadStream(Common::SeekableReadStream &stream) {
// Mask and bitmap data
stream.skip(4);
- stream.skip(maskRowBytes * maskHeight);
+
+ if (_maskRowBytes && _maskHeight) {
+ _mask = new byte[_maskRowBytes * _maskHeight];
+ stream.read(_mask, _maskRowBytes * _maskHeight);
+ }
stream.skip(bitmapRowBytes * bitmapHeight);
// Palette
diff --git a/image/cicn.h b/image/cicn.h
index 4eebd7a0152..1de4a394035 100644
--- a/image/cicn.h
+++ b/image/cicn.h
@@ -48,12 +48,17 @@ public:
const Graphics::Surface *getSurface() const override { return _surface; }
const byte *getPalette() const override { return _palette; }
uint16 getPaletteColorCount() const override { return _paletteColorCount; }
+ const byte *getMask() const override { return _mask; }
+ virtual uint16 getMaskRowBytes() const override { return _maskRowBytes; }
+ virtual uint16 getMaskHeight() const override { return _maskHeight; }
private:
Graphics::Surface *_surface;
byte *_palette;
uint16 _paletteColorCount;
-
+ byte *_mask;
+ uint16 _maskRowBytes;
+ uint16 _maskHeight;
};
/** @} */
diff --git a/image/image_decoder.h b/image/image_decoder.h
index cf19408bd41..4393b28c57c 100644
--- a/image/image_decoder.h
+++ b/image/image_decoder.h
@@ -113,6 +113,22 @@ public:
virtual bool hasTransparentColor() const { return false; }
/** Return the transparent color. */
virtual uint32 getTransparentColor() const { return 0; }
+
+ /**
+ * Get the mask data for the decoded image.
+ */
+ virtual const byte *getMask() const { return 0; }
+
+ /**
+ * Query whether the decoded image has a palette.
+ */
+ virtual bool hasMask() const { return getMaskRowBytes() != 0 && getMaskHeight() != 0; }
+
+ /** Return the number of bytes per row in the mask */
+ virtual uint16 getMaskRowBytes() const { return 0; }
+
+ /** Return the height of the mask */
+ virtual uint16 getMaskHeight() const { return 0; }
};
/** @} */
} // End of namespace Image
Commit: 98e470db263697b18ac7773ecb2ed219b8bde33b
https://github.com/scummvm/scummvm/commit/98e470db263697b18ac7773ecb2ed219b8bde33b
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add missing "override" keyword
Virtual functions that weren't ever overriden have been made
non-virtual.
Changed paths:
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_indy3.h
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index f467da7f24d..92e1830a936 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -339,7 +339,7 @@ public:
public:
MacButton(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::String text, bool enabled) : MacWidget(window, bounds, text, enabled) {}
- void draw(bool drawFocused = false);
+ void draw(bool drawFocused = false) override;
bool handleMouseUp(Common::Event &event) { return true; }
};
@@ -351,9 +351,9 @@ public:
public:
MacCheckbox(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::String text, bool enabled);
- bool findWidget(int x, int y) const;
- void draw(bool drawFocused = false);
- bool handleMouseUp(Common::Event &event);
+ bool findWidget(int x, int y) const override;
+ void draw(bool drawFocused = false) override;
+ bool handleMouseUp(Common::Event &event) override;
};
// The dialogs add texts as disabled, but we don't want it to be drawn
@@ -377,8 +377,8 @@ public:
_bg = _white;
}
- void getFocus() {}
- void loseFocus() {}
+ void getFocus() override {}
+ void loseFocus() override {}
void setWordWrap(bool wordWrap) { _wordWrap = wordWrap; }
@@ -397,7 +397,7 @@ public:
}
}
- void draw(bool drawFocused = false);
+ void draw(bool drawFocused = false) override;
};
class MacEditText : public MacWidget {
@@ -472,7 +472,7 @@ public:
uint16 getMaskRowBytes() const { return _maskRowBytes; }
uint16 getMaskHeight() const { return _maskHeight; }
- void draw(bool drawFocused = false);
+ void draw(bool drawFocused = false) override;
};
class MacSliderBase : public MacWidget {
@@ -503,10 +503,10 @@ public:
_valueToPos.clear();
}
- void getFocus() {}
- void loseFocus() {}
+ void getFocus() override {}
+ void loseFocus() override {}
- void setValue(int value);
+ void setValue(int value) override;
void addStop(int pos, int value) {
_posToValue[pos] = value;
@@ -546,16 +546,16 @@ public:
bool isScrollable() const { return (_maxValue - _minValue) > 0; }
int getPageSize() const { return _pageSize; }
- bool findWidget(int x, int y) const;
- void draw(bool drawFocued = false);
+ bool findWidget(int x, int y) const override;
+ void draw(bool drawFocued = false) override;
void redrawHandle(int oldValue, int newValue);
- void handleMouseDown(Common::Event &event);
- bool handleMouseUp(Common::Event &event);
- void handleMouseMove(Common::Event &event);
- void handleMouseHeld();
- void handleWheelUp();
- void handleWheelDown();
+ void handleMouseDown(Common::Event &event) override;
+ bool handleMouseUp(Common::Event &event) override;
+ void handleMouseMove(Common::Event &event) override;
+ void handleMouseHeld() override;
+ void handleWheelUp() override;
+ void handleWheelDown() override;
};
class MacImageSlider : public MacSliderBase {
@@ -577,16 +577,16 @@ public:
MacImageSlider(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue);
~MacImageSlider();
- bool findWidget(int x, int y) const;
- void draw(bool drawFocused = false);
+ bool findWidget(int x, int y) const override;
+ void draw(bool drawFocused = false) override;
void setSnapWhileDragging(bool snap) { _snapWhileDragging = snap; }
- void handleMouseDown(Common::Event &event);
- bool handleMouseUp(Common::Event &event);
- void handleMouseMove(Common::Event &event);
- void handleWheelUp();
- void handleWheelDown();
+ void handleMouseDown(Common::Event &event) override;
+ bool handleMouseUp(Common::Event &event) override;
+ void handleMouseMove(Common::Event &event) override;
+ void handleWheelUp() override;
+ void handleWheelDown() override;
};
class MacListBox : public MacWidget {
@@ -603,32 +603,28 @@ public:
MacListBox(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::StringArray texts, bool enabled, bool contentUntouchable = true);
~MacListBox();
- void getFocus() {}
- void loseFocus() {}
+ void getFocus() override {}
+ void loseFocus() override {}
- void setValue(int value) {
+ void setValue(int value) override {
if (value != _value) {
_value = value;
updateTexts();
}
}
- int getValue() {
- return _value;
- }
+ bool findWidget(int x, int y) const override;
+ void setRedraw(bool fullRedraw = false) override;
+ void draw(bool drawFocused = false) override;
- bool findWidget(int x, int y) const;
- void setRedraw(bool fullRedraw = false);
- void draw(bool drawFocused = false);
-
- void handleMouseDown(Common::Event &event);
- bool handleDoubleClick(Common::Event &event);
- bool handleMouseUp(Common::Event &event);
- void handleMouseMove(Common::Event &event);
- void handleMouseHeld();
- void handleWheelUp();
- void handleWheelDown();
- bool handleKeyDown(Common::Event &event);
+ void handleMouseDown(Common::Event &event) override;
+ bool handleDoubleClick(Common::Event &event) override;
+ bool handleMouseUp(Common::Event &event) override;
+ void handleMouseMove(Common::Event &event) override;
+ void handleMouseHeld() override;
+ void handleWheelUp() override;
+ void handleWheelDown() override;
+ bool handleKeyDown(Common::Event &event) override;
};
class MacDropDownList : public MacWidget {
@@ -644,12 +640,12 @@ public:
MacDropDownList(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled);
~MacDropDownList();
- bool findWidget(int x, int y) const;
- void draw(bool drawFocused = false);
+ bool findWidget(int x, int y) const override;
+ void draw(bool drawFocused = false) override;
- void handleMouseDown(Common::Event &event);
- bool handleMouseUp(Common::Event &event);
- void handleMouseMove(Common::Event &event);
+ void handleMouseDown(Common::Event &event) override;
+ bool handleMouseUp(Common::Event &event) override;
+ void handleMouseMove(Common::Event &event) override;
};
class MacDialogWindow {
@@ -793,7 +789,7 @@ public:
virtual bool handleEvent(Common::Event event);
static void menuCallback(int id, Common::String &name, void *data);
- virtual bool initialize();
+ bool initialize();
void updateWindowManager();
const Graphics::Font *getFont(FontId fontId);
diff --git a/engines/scumm/macgui/macgui_indy3.h b/engines/scumm/macgui/macgui_indy3.h
index 42065800b65..b35b6ec9864 100644
--- a/engines/scumm/macgui/macgui_indy3.h
+++ b/engines/scumm/macgui/macgui_indy3.h
@@ -168,12 +168,12 @@ private:
void threaten() { _kill = true; }
bool isDying() const { return _kill; }
- void reset();
+ void reset() override;
virtual void updateVerb(int verbslot);
- void draw();
- void undraw();
+ void draw() override;
+ void undraw() override;
};
class Button : public VerbWidget {
@@ -183,13 +183,13 @@ private:
public:
Button(int x, int y, int width, int height);
- bool handleEvent(Common::Event &event);
+ bool handleEvent(Common::Event &event) override;
- void reset();
- void timeOut();
- void updateVerb(int verbslot);
+ void reset() override;
+ void timeOut() override;
+ void updateVerb(int verbslot) override;
- void draw();
+ void draw() override;
};
class Inventory : public VerbWidget {
@@ -206,11 +206,11 @@ private:
void scroll(ScrollDirection dir);
int getHandlePosition();
- void reset();
+ void reset() override;
- bool handleEvent(Common::Event &event);
+ bool handleEvent(Common::Event &event) override;
- void draw();
+ void draw() override;
};
class ScrollButton : public Widget {
@@ -219,11 +219,11 @@ private:
ScrollButton(int x, int y, int width, int height, ScrollDirection direction);
- bool handleEvent(Common::Event &event);
- bool handleMouseHeld(Common::Point &pressed, Common::Point &held);
+ bool handleEvent(Common::Event &event) override;
+ bool handleMouseHeld(Common::Point &pressed, Common::Point &held) override;
void timeOut();
- void draw();
+ void draw() override;
};
class Slot : public Widget {
@@ -242,12 +242,12 @@ private:
void setObject(int n);
int getObject() const { return _obj; }
- void reset();
+ void reset() override;
- bool handleEvent(Common::Event &event);
+ bool handleEvent(Common::Event &event) override;
void timeOut();
- void draw();
+ void draw() override;
};
Slot *_slots[6];
@@ -261,16 +261,16 @@ private:
Inventory(int x, int y, int width, int height);
~Inventory();
- void setRedraw(bool redraw);
+ void setRedraw(bool redraw) override;
- void reset();
+ void reset() override;
- bool handleEvent(Common::Event &event);
- bool handleMouseHeld(Common::Point &pressed, Common::Point &held);
- void updateTimer(int delta);
- void updateVerb(int verbslot);
+ bool handleEvent(Common::Event &event) override;
+ bool handleMouseHeld(Common::Point &pressed, Common::Point &held) override;
+ void updateTimer(int delta) override;
+ void updateVerb(int verbslot) override;
- void draw();
+ void draw() override;
};
Common::HashMap<int, VerbWidget *> _widgets;
Commit: 16380da1f74f5619cfb0bd18a301dd1375d29273
https://github.com/scummvm/scummvm/commit/16380da1f74f5619cfb0bd18a301dd1375d29273
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add support for The Dig Mac demo
This one uses a regular dialog for About. Unfortunately, our Sam & Max
and Full Throttle Mac demos don't have any resource fork, and our Fate
of Atlantis Mac demo has an unrecognized string table.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_widgets.cpp
engines/scumm/scumm.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index afd2396ee3f..6bc8b0453b5 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -797,6 +797,30 @@ Common::String MacGuiImpl::getDialogString(Common::SeekableReadStream *res, int
}
MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
+ Common::Rect bounds;
+
+ // Default dialog sizes for dialogs without a DITL resource.
+
+ if (_vm->_game.version < 6) {
+ bounds.top = 0;
+ bounds.left = 0;
+ bounds.bottom = 86;
+ bounds.right = 340;
+
+ bounds.translate(86, 88);
+ } else {
+ bounds.top = 0;
+ bounds.left = 0;
+ bounds.bottom = 113;
+ bounds.right = 267;
+
+ bounds.translate(187, 94);
+ }
+
+ return createDialog(dialogId, bounds);
+}
+
+MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect bounds) {
uint32 black = getBlack();
Common::MacResManager resource;
@@ -806,8 +830,6 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
resource.open(_resourceFile);
- Common::Rect bounds;
-
res = resource.getResource(MKTAG('D', 'L', 'O', 'G'), dialogId);
if (res) {
bounds.top = res->readUint16BE();
@@ -821,20 +843,6 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
// Compensate for the original not drawing the game at the very top of
// the screen.
bounds.translate(0, -40);
- } else if (_vm->_game.version < 6) {
- bounds.top = 0;
- bounds.left = 0;
- bounds.bottom = 86;
- bounds.right = 340;
-
- bounds.translate(86, 88);
- } else {
- bounds.top = 0;
- bounds.left = 0;
- bounds.bottom = 113;
- bounds.right = 267;
-
- bounds.translate(187, 94);
}
delete res;
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 92e1830a936..4eb619c577a 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -817,6 +817,7 @@ public:
MacDialogWindow *createWindow(Common::Rect bounds, MacDialogWindowStyle style = kWindowStyleNormal, MacDialogMenuStyle menuStyle = kMenuStyleDisabled);
MacDialogWindow *createDialog(int dialogId);
+ MacDialogWindow *createDialog(int dialogId, Common::Rect bounds);
void drawBanner(char *message);
void undrawBanner();
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 52596caa805..63c6a68e302 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -58,6 +58,9 @@ MacV6Gui::MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile) : MacGuiIm
_gameName = "Maniac Mansion";
else
_gameName = "Some Game I Do Not Know";
+
+ if (_vm->_game.features & GF_DEMO)
+ _gameName += " Demo";
}
MacV6Gui::~MacV6Gui() {
@@ -379,6 +382,25 @@ MacGuiImpl::MacImageSlider *MacV6Gui::addSlider(MacDialogWindow *window, int x,
}
void MacV6Gui::runAboutDialog() {
+ if (_vm->_game.id == GID_DIG && (_vm->_game.features & GF_DEMO)) {
+ MacDialogWindow *window = createDialog(136, Common::Rect(121, 15, 519, 364));
+ MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
+
+ window->setDefaultWidget(buttonOk);
+
+ Common::Array<int> deferredActionsIds;
+
+ while (!_vm->shouldQuit()) {
+ int clicked = window->runDialog(deferredActionsIds);
+
+ if (clicked == buttonOk->getId())
+ break;
+ }
+
+ delete window;
+ return;
+ }
+
ScummFile aboutFile(_vm);
if (!_vm->openFile(aboutFile, "ABOUT"))
return;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 2f01db00613..7cbeae2aecb 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -114,8 +114,25 @@ int MacGuiImpl::MacWidget::drawText(Common::String text, int x, int y, int w, ui
if (wordWrap) {
maxLineWidth = font->wordWrapText(text, w, lines);
} else {
- lines.push_back(text);
- maxLineWidth = font->getStringWidth(text);
+ if (text.contains('\r')) {
+ Common::String line = "";
+
+ for (uint i = 0; i < text.size(); i++) {
+ if (text[i] != '\r')
+ line += text[i];
+
+ if (text[i] == '\r' || i == text.size() - 1) {
+ int lineWidth = font->getStringWidth(line);
+ if (lineWidth > maxLineWidth)
+ maxLineWidth = lineWidth;
+ lines.push_back(line);
+ line = "";
+ }
+ }
+ } else {
+ lines.push_back(text);
+ maxLineWidth = font->getStringWidth(text);
+ }
}
// Draw the text. Disabled text is implemented as a filter on top of
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 5ad65a8b163..5e30654f332 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1252,11 +1252,15 @@ Common::Error ScummEngine::init() {
{ GID_INDY4, "Indy 12-15-92" },
{ GID_INDY4, "Fate of Atlantis v1.5" },
{ GID_INDY4, "Fate of Atlantis v.1.5" },
+// { GID_INDY4, "Indy Demo" },
{ GID_MONKEY2, "LeChuck's Revenge" },
{ GID_TENTACLE, "Day of the Tentacle" },
{ GID_SAMNMAX, "Sam & Max" },
+// { GID_SAMNMAX, "Sam & Max Demo" },
{ GID_DIG, "The Dig" },
- { GID_FT, "Full Throttle" }
+ { GID_DIG, "The Dig Demo" },
+ { GID_FT, "Full Throttle" },
+// { GID_FT, "Full Throttle Demo" }
};
bool macScumm = false;
Commit: 9aa269edf7b223ff0898e2fc184cbff1c8f8786f
https://github.com/scummvm/scummvm/commit/9aa269edf7b223ff0898e2fc184cbff1c8f8786f
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add support for Sam & Max demo
This used to be hosted on the LucasArts FTP server.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/scumm.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 63c6a68e302..ccf7de2e482 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -382,8 +382,23 @@ MacGuiImpl::MacImageSlider *MacV6Gui::addSlider(MacDialogWindow *window, int x,
}
void MacV6Gui::runAboutDialog() {
- if (_vm->_game.id == GID_DIG && (_vm->_game.features & GF_DEMO)) {
- MacDialogWindow *window = createDialog(136, Common::Rect(121, 15, 519, 364));
+ if (_vm->_game.features & GF_DEMO) {
+ // HACK: Use the largest bounds as default for unknown demos
+ Common::Rect bounds(117, 5, 523, 384);
+
+ if (_vm->_game.id == GID_SAMNMAX) {
+ bounds.left = 117;
+ bounds.top = 5;
+ bounds.right = 523;
+ bounds.bottom = 384;
+ } else if (_vm->_game.id == GID_DIG) {
+ bounds.left = 121;
+ bounds.top = 15;
+ bounds.right = 519;
+ bounds.bottom = 364;
+ }
+
+ MacDialogWindow *window = createDialog(136, bounds);
MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
window->setDefaultWidget(buttonOk);
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 5e30654f332..ea237181958 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1256,7 +1256,7 @@ Common::Error ScummEngine::init() {
{ GID_MONKEY2, "LeChuck's Revenge" },
{ GID_TENTACLE, "Day of the Tentacle" },
{ GID_SAMNMAX, "Sam & Max" },
-// { GID_SAMNMAX, "Sam & Max Demo" },
+ { GID_SAMNMAX, "Sam & Max Demo" },
{ GID_DIG, "The Dig" },
{ GID_DIG, "The Dig Demo" },
{ GID_FT, "Full Throttle" },
Commit: 4145ac26d99cc19b217da22d7bb215fae063a21f
https://github.com/scummvm/scummvm/commit/4145ac26d99cc19b217da22d7bb215fae063a21f
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix memory leaks
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 6bc8b0453b5..502135e171a 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -915,8 +915,12 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect
paletteMap[color] = numWindowColors++;
}
}
+
+ delete imageRes;
}
+ delete res;
+
Graphics::Palette palette(256);
setMacGuiColors(palette);
Commit: abd99938501edb492d91a029ed9a84bb747873dd
https://github.com/scummvm/scummvm/commit/abd99938501edb492d91a029ed9a84bb747873dd
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Allow the Mac Fate of Atlantis demo to run
But I think this was originally non-interactive, so it's not really
playable. Also, the About dialog needs some serious work, because it
currently crashes. (Probably from loading non-existing graphics.) I'm
not sure how to properly detect which version is running, though.
Changed paths:
engines/scumm/macgui/macgui_strings.cpp
engines/scumm/macgui/macgui_v5.cpp
engines/scumm/macgui/macgui_widgets.cpp
engines/scumm/scumm.cpp
diff --git a/engines/scumm/macgui/macgui_strings.cpp b/engines/scumm/macgui/macgui_strings.cpp
index 3b4fa2fa620..bb2168741c8 100644
--- a/engines/scumm/macgui/macgui_strings.cpp
+++ b/engines/scumm/macgui/macgui_strings.cpp
@@ -599,6 +599,51 @@ static const MacGuiImpl::MacSTRSParsingEntry strsIndy4FloppyVariant2Table[] = {
{ MacGuiImpl::kMSIAboutString37, MacGuiImpl::kStrPascal, 1 },
};
+static const MacGuiImpl::MacSTRSParsingEntry strsIndy4DemoTable[] = {
+ SKIP_C(98),
+ SKIP_P(1),
+ { MacGuiImpl::kMSIAboutGameName, MacGuiImpl::kStrPascal, 1 },
+ SKIP_C(1),
+ { MacGuiImpl::kMSIAreYouSureYouWantToQuit, MacGuiImpl::kStrC, 1 },
+ { MacGuiImpl::kMSIAreYouSureYouWantToRestart, MacGuiImpl::kStrC, 1 },
+ SKIP_C(1),
+ SKIP_P(1),
+ { MacGuiImpl::kMSIGameName, MacGuiImpl::kStrPascal, 1 },
+ SKIP_C(9),
+ { MacGuiImpl::kMSIAboutString1, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString2, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString3, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString4, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString5, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString6, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString7, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString8, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString9, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString10, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString11, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString12, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString13, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString14, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString15, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString16, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString17, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString18, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString19, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString20, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString21, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString22, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString23, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString24, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString25, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString26, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString27, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString29, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString30, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString31, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString32, MacGuiImpl::kStrPascal, 1 },
+ { MacGuiImpl::kMSIAboutString33, MacGuiImpl::kStrPascal, 1 },
+};
+
#undef SKIP_C
#undef SKIP_P
@@ -684,6 +729,10 @@ bool MacGuiImpl::readStrings() {
parsingTable = strsIndy4CDVariant2Table;
parsingTableSize = ARRAYSIZE(strsIndy4CDVariant2Table);
break;
+ case 6312: // Demo
+ parsingTable = strsIndy4DemoTable;
+ parsingTableSize = ARRAYSIZE(strsIndy4DemoTable);
+ break;
}
}
@@ -721,6 +770,7 @@ void MacGuiImpl::parseSTRSBlock(uint8 *strsData, const MacSTRSParsingEntry *pars
} else {
error("MacGuiImpl::parseSTRSBlock(): invalid parsing method encountered (%d)", entry.parsingMethod);
}
+debug("_strs[%d] = '%s'", entry.strId, _strsStrings[entry.strId].c_str());
}
}
}
diff --git a/engines/scumm/macgui/macgui_v5.cpp b/engines/scumm/macgui/macgui_v5.cpp
index dd79a19c3ca..b209ce83bd5 100644
--- a/engines/scumm/macgui/macgui_v5.cpp
+++ b/engines/scumm/macgui/macgui_v5.cpp
@@ -98,33 +98,30 @@ bool MacV5Gui::getFontParams(FontId fontId, int &id, int &size, int &slant) cons
}
void MacV5Gui::setupCursor(int &width, int &height, int &hotspotX, int &hotspotY, int &animate) {
- if (_vm->_game.id == GID_MONKEY) {
+ Common::MacResManager resource;
+ Graphics::MacCursor macCursor;
+
+ resource.open(_resourceFile);
+
+ Common::SeekableReadStream *curs = resource.getResource(MKTAG('C', 'U', 'R', 'S'), 128);
+
+ if (curs && macCursor.readFromStream(*curs)) {
+ width = macCursor.getWidth();
+ height = macCursor.getHeight();
+ hotspotX = macCursor.getHotspotX();
+ hotspotY = macCursor.getHotspotY();
+ animate = 0;
+
+ _windowManager->replaceCursor(Graphics::MacGUIConstants::kMacCursorCustom, &macCursor);
+ } else {
+ // Monkey Island 1 uses the arrow cursor, and we have to use it
+ // for the Fate of Atlantis demo as well.
_windowManager->replaceCursor(Graphics::MacGUIConstants::kMacCursorArrow);
width = 11;
height = 16;
hotspotX = 1;
hotspotY = 3;
animate = 0;
- } else if (_vm->_game.version == 5) {
- Common::MacResManager resource;
- Graphics::MacCursor macCursor;
-
- resource.open(_resourceFile);
-
- Common::SeekableReadStream *curs = resource.getResource(MKTAG('C', 'U', 'R', 'S'), 128);
-
- if (macCursor.readFromStream(*curs)) {
- width = macCursor.getWidth();
- height = macCursor.getHeight();
- hotspotX = macCursor.getHotspotX();
- hotspotY = macCursor.getHotspotY();
- animate = 0;
-
- _windowManager->replaceCursor(Graphics::MacGUIConstants::kMacCursorCustom, &macCursor);
- }
-
- delete curs;
- resource.close();
}
}
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 7cbeae2aecb..c51e112375c 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -855,6 +855,13 @@ void MacGuiImpl::MacImage::draw(bool drawFocused) {
// ---------------------------------------------------------------------------
// Slider base class
+//
+// The idea here is that _maxPos and _minPos correspond to _maxValue and
+// _minValue respectively. The position can be calculated from the value and
+// vice versa.
+//
+// For more exact positioning, where you have to match it exactly to a visible
+// ruler, you can use addStop() to override the calculated values.
// ---------------------------------------------------------------------------
void MacGuiImpl::MacSliderBase::setValue(int value) {
@@ -1305,6 +1312,10 @@ void MacGuiImpl::MacSlider::handleWheelDown() {
// Image slider widget. This is the custom slider widget used for the Loom
// and Indy 3 options dialogs. It consists of a background image and a slider
// drag handle.
+//
+// In addition to the min and max value positions, this one also maintains a
+// _minX and _maxX position to which the handle can be dragged. This is only
+// used for the older games.
// ---------------------------------------------------------------------------
MacGuiImpl::MacImageSlider::MacImageSlider(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue)
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index ea237181958..b910bc32606 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1252,7 +1252,7 @@ Common::Error ScummEngine::init() {
{ GID_INDY4, "Indy 12-15-92" },
{ GID_INDY4, "Fate of Atlantis v1.5" },
{ GID_INDY4, "Fate of Atlantis v.1.5" },
-// { GID_INDY4, "Indy Demo" },
+ { GID_INDY4, "Indy Demo" },
{ GID_MONKEY2, "LeChuck's Revenge" },
{ GID_TENTACLE, "Day of the Tentacle" },
{ GID_SAMNMAX, "Sam & Max" },
Commit: deda2580cc165b4373f84704f97410fea1219ecb
https://github.com/scummvm/scummvm/commit/deda2580cc165b4373f84704f97410fea1219ecb
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Remove leftover debug message
Changed paths:
engines/scumm/macgui/macgui_strings.cpp
diff --git a/engines/scumm/macgui/macgui_strings.cpp b/engines/scumm/macgui/macgui_strings.cpp
index bb2168741c8..eb7060fafaa 100644
--- a/engines/scumm/macgui/macgui_strings.cpp
+++ b/engines/scumm/macgui/macgui_strings.cpp
@@ -770,7 +770,6 @@ void MacGuiImpl::parseSTRSBlock(uint8 *strsData, const MacSTRSParsingEntry *pars
} else {
error("MacGuiImpl::parseSTRSBlock(): invalid parsing method encountered (%d)", entry.parsingMethod);
}
-debug("_strs[%d] = '%s'", entry.strId, _strsStrings[entry.strId].c_str());
}
}
}
Commit: 7572fba8f3f8c8d1b8c7d2b156a8897287ad76f2
https://github.com/scummvm/scummvm/commit/7572fba8f3f8c8d1b8c7d2b156a8897287ad76f2
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Hopefully fix palette regression
Opening the quit dialog wouldn't always update the palette.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 502135e171a..00cb8cb678a 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -950,7 +950,8 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect
_system->getPaletteManager()->setPalette(palette);
}
- }
+ } else
+ updatePalette();
MacDialogWindow *window = createWindow(bounds);
Commit: 9d943381acc7feb667b50fdf2491224d287c45c8
https://github.com/scummvm/scummvm/commit/9d943381acc7feb667b50fdf2491224d287c45c8
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Attempt to fix menu glitch for earlier games
This is getting a bit messy.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 00cb8cb678a..bb152f571f1 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -772,6 +772,12 @@ void MacGuiImpl::setMacGuiColors(Graphics::Palette &palette) {
}
MacGuiImpl::MacDialogWindow *MacGuiImpl::createWindow(Common::Rect bounds, MacDialogWindowStyle windowStyle, MacDialogMenuStyle menuStyle) {
+ if (_vm->_game.version < 6 && _vm->_game.id != GID_MANIAC) {
+ updatePalette();
+ _macBlack = _windowManager->_colorBlack;
+ _macWhite = _windowManager->_colorWhite;
+ }
+
if (bounds.left < 0 || bounds.top < 0 || bounds.right >= 640 || bounds.bottom >= 400) {
// This happens with the Last Crusade file dialogs.
bounds.moveTo((640 - bounds.width()) / 2, 27);
@@ -950,8 +956,7 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect
_system->getPaletteManager()->setPalette(palette);
}
- } else
- updatePalette();
+ }
MacDialogWindow *window = createWindow(bounds);
Commit: ac238093f2eae9acc77ad1aee1546d2ad5367db3
https://github.com/scummvm/scummvm/commit/ac238093f2eae9acc77ad1aee1546d2ad5367db3
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add About dialog for Mac Fate of Atlantis Demo
Now I just need to add the correct timings for it.
Changed paths:
engines/scumm/macgui/macgui_v5.cpp
engines/scumm/macgui/macgui_v5.h
diff --git a/engines/scumm/macgui/macgui_v5.cpp b/engines/scumm/macgui/macgui_v5.cpp
index b209ce83bd5..7d0480ff071 100644
--- a/engines/scumm/macgui/macgui_v5.cpp
+++ b/engines/scumm/macgui/macgui_v5.cpp
@@ -198,7 +198,10 @@ void MacV5Gui::runAboutDialog() {
runAboutDialogMI2(window);
break;
case GID_INDY4:
- runAboutDialogIndy4(window);
+ if (_strsStrings[kMSIAboutString34] != "")
+ runAboutDialogIndy4(window);
+ else
+ runAboutDialogIndy4Demo(window);
break;
default:
break;
@@ -779,9 +782,6 @@ void MacV5Gui::runAboutDialogIndy4(MacDialogWindow *window) {
break;
}
- if (aboutPages[page].drawArea != 2)
- window->markRectAsDirty(drawArea);
-
if (aboutPages[page].text) {
if (aboutPages[page].drawArea == 1) {
window->drawTextBox(drawArea, aboutPages[page].text);
@@ -805,6 +805,148 @@ void MacV5Gui::runAboutDialogIndy4(MacDialogWindow *window) {
delete indianaJones;
}
+void MacV5Gui::runAboutDialogIndy4Demo(MacDialogWindow *window) {
+ Graphics::Surface *s = window->innerSurface();
+
+ Graphics::Surface *lucasArts = loadPict(5000);
+
+ const TextLine page3[] = {
+ { 0, 68, kStyleBold, Graphics::kTextAlignCenter, _strsStrings[kMSIAboutString2].c_str() }, // "PRESENTS"
+ TEXT_END_MARKER
+ };
+
+ const TextLine page4[] = {
+ { 0, 5, kStyleHeaderSimple1, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString3].c_str() }, // "Indiana Jones"
+ { 73, 18, kStyleBold, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString5].c_str() }, // "and the"
+ { 40, 31, kStyleHeaderSimple1, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString4].c_str() }, // "Fate of Atlantis"
+// { 317, 4, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString3].c_str() }, // "\xA8"
+ { 178, 125, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString6].c_str() }, // "TM & \xA9 1990 LucasArts Entertainment Company."
+ { 312, 138, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString7].c_str() }, // "All rights reserved."
+ TEXT_END_MARKER
+ };
+
+ const TextLine page5[] = {
+ { 0, 47, kStyleRegular, Graphics::kTextAlignCenter, _strsStrings[kMSIAboutString8].c_str() }, // "Macintosh version by
+ { 50, 62, kStyleHeaderSimple2, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString9].c_str() }, // "Eric Johnston"
+ TEXT_END_MARKER
+ };
+
+ const TextLine page6[] = {
+ { 85, 32, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString10].c_str() }, // "Created by"
+ { 55, 47, kStyleHeaderSimple2, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString12].c_str() }, // "Hal Barwood"
+ { 58, 70, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString11].c_str() }, // "Macintosh Scripting by"
+ { 44, 85, kStyleHeaderSimple2, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString13].c_str() }, // "Alric Wilmunder"
+ TEXT_END_MARKER
+ };
+
+ const TextLine page7[] = {
+ { 59, 27, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString14].c_str() }, // "SCUMM Story System"
+ { 85, 37, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString15].c_str() }, // "created by"
+ { 35, 57, kStyleHeaderSimple2, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString17].c_str() }, // "Ron Gilbert"
+ { 102, 72, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString16].c_str() }, // "and"
+ { 59, 87, kStyleHeaderSimple2, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString18].c_str() }, // "Aric Wilmunder"
+ TEXT_END_MARKER
+ };
+
+ const TextLine page8[] = {
+ { 29, 37, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString19].c_str() }, // "Stumped? Hint books are available!"
+ { 15, 55, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString22].c_str() }, // "In the U.S. call"
+ { 89, 55, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString20].c_str() }, // "1 (800) STAR-WARS"
+ { 89, 65, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString24].c_str() }, // "that\xD5s 1 (800) 782-7927"
+ { 19, 85, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString23].c_str() }, // "In Canada call"
+ { 89, 85, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString21].c_str() }, // "1 (800) 828-7927"
+ TEXT_END_MARKER
+ };
+
+ const TextLine page9[] = {
+ { 27, 32, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString25].c_str() }, // "Need a hint NOW? Having problems?"
+ { 6, 47, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString29].c_str() }, // "For technical support call"
+ { 130, 47, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString26].c_str() }, // "1 (415) 721-3333"
+ { 62, 57, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString30].c_str() }, // "For hints call"
+ { 130, 57, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString27].c_str() }, // "1 (900) 740-JEDI"
+ { 5, 72, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString31].c_str() }, // "The charge for the hint line is 75\xA2 per minute."
+ { 10, 82, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString32].c_str() }, // "(You must have your parents\xD5 permission to"
+ { 25, 92, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString33].c_str() }, // "call this number if you are under 18.)"
+ TEXT_END_MARKER
+ };
+
+ AboutPage aboutPages[] = {
+ { nullptr, 0, 2800 },
+ { nullptr, 0, 100 },
+ { nullptr, 0, 100 },
+ { page3, 0, 2100 },
+ { page4, 0, 2900 },
+ { page5, 1, 4200 },
+ { page6, 1, 4300 },
+ { page7, 1, 4200 },
+ { page8, 1, 14100 },
+ { page9, 1, 0 }
+ };
+
+ Common::Rect drawAreas[] = {
+ Common::Rect(0, 2, s->w, s->h - 2),
+ Common::Rect(176, 10, s->w - 10, s->h - 10)
+ };
+
+ int page = 0;
+
+ window->show();
+
+ uint32 black = getBlack();
+ uint32 white = getWhite();
+
+ while (!_vm->shouldQuit() && page < ARRAYSIZE(aboutPages)) {
+ Common::Rect &drawArea = drawAreas[aboutPages[page].drawArea];
+
+ switch (page) {
+ case 0:
+ s->fillRect(drawArea, black);
+ window->drawSprite(lucasArts, 64, 2, drawArea);
+ break;
+
+ case 1:
+ window->fillPattern(drawArea, 0xD7D7, false, true);
+ break;
+
+ case 2:
+ window->fillPattern(drawArea, 0x5A5A, false, true);
+ break;
+
+ case 3:
+ s->fillRect(drawArea, white);
+ break;
+
+ case 4:
+ s->fillRect(drawArea, white);
+ break;
+
+ case 5:
+ s->fillRect(Common::Rect(178, 129, s->w - 2, s->h - 2), white);
+ window->markRectAsDirty(Common::Rect(178, 129, s->w - 2, s->h - 2));
+ break;
+
+ default:
+ break;
+ }
+
+ if (aboutPages[page].text) {
+ if (aboutPages[page].drawArea == 1) {
+ window->drawTextBox(drawArea, aboutPages[page].text);
+ } else {
+ window->drawTexts(drawArea, aboutPages[page].text);
+ }
+ }
+
+ window->markRectAsDirty(drawArea);
+ window->update();
+ delay(aboutPages[page].delayMs);
+ page++;
+ }
+
+ lucasArts->free();
+ delete lucasArts;
+}
+
bool MacV5Gui::runOptionsDialog() {
// Widgets:
//
diff --git a/engines/scumm/macgui/macgui_v5.h b/engines/scumm/macgui/macgui_v5.h
index 66642522469..77ade05d153 100644
--- a/engines/scumm/macgui/macgui_v5.h
+++ b/engines/scumm/macgui/macgui_v5.h
@@ -68,6 +68,7 @@ private:
void runAboutDialogMI1(MacDialogWindow *window);
void runAboutDialogMI2(MacDialogWindow *window);
void runAboutDialogIndy4(MacDialogWindow *window);
+ void runAboutDialogIndy4Demo(MacDialogWindow *window);
void drawShadow(Graphics::Surface *s, int x, int y, int h, Common::Pair<int, int> *drawData);
};
Commit: bee7c7f77949c18b0e458823a12591c89716ec31
https://github.com/scummvm/scummvm/commit/bee7c7f77949c18b0e458823a12591c89716ec31
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Adjust "About" timing for the Fate of Atlantis Mac Demo
This should be close enough.
Changed paths:
engines/scumm/macgui/macgui_v5.cpp
diff --git a/engines/scumm/macgui/macgui_v5.cpp b/engines/scumm/macgui/macgui_v5.cpp
index 7d0480ff071..6719fa366a6 100644
--- a/engines/scumm/macgui/macgui_v5.cpp
+++ b/engines/scumm/macgui/macgui_v5.cpp
@@ -871,15 +871,15 @@ void MacV5Gui::runAboutDialogIndy4Demo(MacDialogWindow *window) {
};
AboutPage aboutPages[] = {
- { nullptr, 0, 2800 },
+ { nullptr, 0, 3500 },
{ nullptr, 0, 100 },
{ nullptr, 0, 100 },
- { page3, 0, 2100 },
- { page4, 0, 2900 },
- { page5, 1, 4200 },
- { page6, 1, 4300 },
- { page7, 1, 4200 },
- { page8, 1, 14100 },
+ { page3, 0, 2000 },
+ { page4, 0, 7000 },
+ { page5, 1, 4100 },
+ { page6, 1, 4100 },
+ { page7, 1, 4100 },
+ { page8, 1, 14000 },
{ page9, 1, 0 }
};
Commit: 6ecaf36e711f56941ccd93e7360bdcc4e551bd27
https://github.com/scummvm/scummvm/commit/6ecaf36e711f56941ccd93e7360bdcc4e551bd27
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Hopefully fix crash with non-English v6-7 games
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index bb152f571f1..4a522b9bcf0 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -497,14 +497,18 @@ void MacGuiImpl::updateWindowManager() {
}
}
} else if (_vm->_game.version >= 6) {
- Graphics::MacMenuItem *videoMenu = menu->getMenuItem("Video");
+ // We can't use the name of the menus here, because there are
+ // non-English versions. Let's hope the menu positions are
+ // always the same, at least!
+
+ Graphics::MacMenuItem *videoMenu = menu->getMenuItem(3);
menu->getSubMenuItem(videoMenu, 0)->enabled = false;
menu->getSubMenuItem(videoMenu, 1)->enabled = false;
menu->getSubMenuItem(videoMenu, 2)->checked = true;
menu->getSubMenuItem(videoMenu, 3)->checked = _vm->_useMacGraphicsSmoothing;
- Graphics::MacMenuItem *soundMenu = menu->getMenuItem("Sound");
+ Graphics::MacMenuItem *soundMenu = menu->getMenuItem(4);
menu->getSubMenuItem(soundMenu, 0)->checked = false; // Music
menu->getSubMenuItem(soundMenu, 1)->checked = false; // Effects
Commit: 267e04ca960b6912da8f1a34a5fab81cb0c2bfba
https://github.com/scummvm/scummvm/commit/267e04ca960b6912da8f1a34a5fab81cb0c2bfba
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Further tweaks to the Fate of Atlantis demo About dialog
Changed paths:
engines/scumm/macgui/macgui_v5.cpp
diff --git a/engines/scumm/macgui/macgui_v5.cpp b/engines/scumm/macgui/macgui_v5.cpp
index 6719fa366a6..1d803d305a8 100644
--- a/engines/scumm/macgui/macgui_v5.cpp
+++ b/engines/scumm/macgui/macgui_v5.cpp
@@ -810,12 +810,12 @@ void MacV5Gui::runAboutDialogIndy4Demo(MacDialogWindow *window) {
Graphics::Surface *lucasArts = loadPict(5000);
- const TextLine page3[] = {
+ const TextLine page4[] = {
{ 0, 68, kStyleBold, Graphics::kTextAlignCenter, _strsStrings[kMSIAboutString2].c_str() }, // "PRESENTS"
TEXT_END_MARKER
};
- const TextLine page4[] = {
+ const TextLine page5[] = {
{ 0, 5, kStyleHeaderSimple1, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString3].c_str() }, // "Indiana Jones"
{ 73, 18, kStyleBold, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString5].c_str() }, // "and the"
{ 40, 31, kStyleHeaderSimple1, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString4].c_str() }, // "Fate of Atlantis"
@@ -825,13 +825,13 @@ void MacV5Gui::runAboutDialogIndy4Demo(MacDialogWindow *window) {
TEXT_END_MARKER
};
- const TextLine page5[] = {
+ const TextLine page6[] = {
{ 0, 47, kStyleRegular, Graphics::kTextAlignCenter, _strsStrings[kMSIAboutString8].c_str() }, // "Macintosh version by
{ 50, 62, kStyleHeaderSimple2, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString9].c_str() }, // "Eric Johnston"
TEXT_END_MARKER
};
- const TextLine page6[] = {
+ const TextLine page7[] = {
{ 85, 32, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString10].c_str() }, // "Created by"
{ 55, 47, kStyleHeaderSimple2, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString12].c_str() }, // "Hal Barwood"
{ 58, 70, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString11].c_str() }, // "Macintosh Scripting by"
@@ -839,7 +839,7 @@ void MacV5Gui::runAboutDialogIndy4Demo(MacDialogWindow *window) {
TEXT_END_MARKER
};
- const TextLine page7[] = {
+ const TextLine page8[] = {
{ 59, 27, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString14].c_str() }, // "SCUMM Story System"
{ 85, 37, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString15].c_str() }, // "created by"
{ 35, 57, kStyleHeaderSimple2, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString17].c_str() }, // "Ron Gilbert"
@@ -848,7 +848,7 @@ void MacV5Gui::runAboutDialogIndy4Demo(MacDialogWindow *window) {
TEXT_END_MARKER
};
- const TextLine page8[] = {
+ const TextLine page9[] = {
{ 29, 37, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString19].c_str() }, // "Stumped? Hint books are available!"
{ 15, 55, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString22].c_str() }, // "In the U.S. call"
{ 89, 55, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString20].c_str() }, // "1 (800) STAR-WARS"
@@ -858,7 +858,7 @@ void MacV5Gui::runAboutDialogIndy4Demo(MacDialogWindow *window) {
TEXT_END_MARKER
};
- const TextLine page9[] = {
+ const TextLine page10[] = {
{ 27, 32, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString25].c_str() }, // "Need a hint NOW? Having problems?"
{ 6, 47, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString29].c_str() }, // "For technical support call"
{ 130, 47, kStyleRegular, Graphics::kTextAlignLeft, _strsStrings[kMSIAboutString26].c_str() }, // "1 (415) 721-3333"
@@ -874,16 +874,18 @@ void MacV5Gui::runAboutDialogIndy4Demo(MacDialogWindow *window) {
{ nullptr, 0, 3500 },
{ nullptr, 0, 100 },
{ nullptr, 0, 100 },
- { page3, 0, 2000 },
- { page4, 0, 7000 },
- { page5, 1, 4100 },
- { page6, 1, 4100 },
- { page7, 1, 4100 },
- { page8, 1, 14000 },
- { page9, 1, 0 }
+ { nullptr, 0, 100 },
+ { page4, 1, 2100 },
+ { page5, 1, 7000 },
+ { page6, 2, 4200 },
+ { page7, 2, 4200 },
+ { page8, 2, 4200 },
+ { page9, 2, 14100 },
+ { page10, 2, 0 }
};
Common::Rect drawAreas[] = {
+ Common::Rect(2, 2, s->w - 2, s->h - 2),
Common::Rect(0, 2, s->w, s->h - 2),
Common::Rect(176, 10, s->w - 10, s->h - 10)
};
@@ -913,16 +915,13 @@ void MacV5Gui::runAboutDialogIndy4Demo(MacDialogWindow *window) {
break;
case 3:
+ case 5:
s->fillRect(drawArea, white);
break;
- case 4:
- s->fillRect(drawArea, white);
- break;
-
- case 5:
- s->fillRect(Common::Rect(178, 129, s->w - 2, s->h - 2), white);
- window->markRectAsDirty(Common::Rect(178, 129, s->w - 2, s->h - 2));
+ case 6:
+ s->fillRect(Common::Rect(176, 129, s->w - 2, s->h - 2), white);
+ window->markRectAsDirty(Common::Rect(176, 129, s->w - 2, s->h - 2));
break;
default:
@@ -930,7 +929,7 @@ void MacV5Gui::runAboutDialogIndy4Demo(MacDialogWindow *window) {
}
if (aboutPages[page].text) {
- if (aboutPages[page].drawArea == 1) {
+ if (aboutPages[page].drawArea == 2) {
window->drawTextBox(drawArea, aboutPages[page].text);
} else {
window->drawTexts(drawArea, aboutPages[page].text);
Commit: 7b0368d79a9d3582f19cfadc07ca5547ecbf183c
https://github.com/scummvm/scummvm/commit/7b0368d79a9d3582f19cfadc07ca5547ecbf183c
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Hopefully fix detection of floppy Fate of Atlantis
It now triggers on whether or not we have the "rough" string.
Changed paths:
engines/scumm/macgui/macgui_v5.cpp
diff --git a/engines/scumm/macgui/macgui_v5.cpp b/engines/scumm/macgui/macgui_v5.cpp
index 1d803d305a8..8a185a3d62f 100644
--- a/engines/scumm/macgui/macgui_v5.cpp
+++ b/engines/scumm/macgui/macgui_v5.cpp
@@ -621,7 +621,7 @@ void MacV5Gui::runAboutDialogMI2(MacDialogWindow *window) {
}
void MacV5Gui::runAboutDialogIndy4(MacDialogWindow *window) {
- bool isFloppyVersion = _vm->_game.variant && !strcmp(_vm->_game.variant, "Floppy");
+ bool isFloppyVersion = (_strsStrings[kMSIAboutString38] != "");
Graphics::Surface *s = window->innerSurface();
Commit: 6f911caf73447b5d06dd367ad716d5f2c4234de4
https://github.com/scummvm/scummvm/commit/6f911caf73447b5d06dd367ad716d5f2c4234de4
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Simplified Indy 4 floppy version check
Because on second thougth, we no longer need it. If the string is empty,
it just won't show.
Changed paths:
engines/scumm/macgui/macgui_v5.cpp
diff --git a/engines/scumm/macgui/macgui_v5.cpp b/engines/scumm/macgui/macgui_v5.cpp
index 8a185a3d62f..6c7c20d3d9f 100644
--- a/engines/scumm/macgui/macgui_v5.cpp
+++ b/engines/scumm/macgui/macgui_v5.cpp
@@ -621,8 +621,6 @@ void MacV5Gui::runAboutDialogMI2(MacDialogWindow *window) {
}
void MacV5Gui::runAboutDialogIndy4(MacDialogWindow *window) {
- bool isFloppyVersion = (_strsStrings[kMSIAboutString38] != "");
-
Graphics::Surface *s = window->innerSurface();
Graphics::Surface *lucasArts = loadPict(5000);
@@ -676,17 +674,10 @@ void MacV5Gui::runAboutDialogIndy4(MacDialogWindow *window) {
TEXT_END_MARKER
};
- // Annoyingly, this page is missing a string in the CD version of the
- // game so we need two different versions. Note that the "rough" command
- // does work in both versions.
-
- const TextLine page10_cd[] = {
- { 2, 19, kStyleRegular, Graphics::kTextAlignCenter, _strsStrings[kMSIAboutString22].c_str() }, // "\xD2djm\xD3 Sound and Music System \xA91992 Eric Johnston
- { 2, 39, kStyleRegular, Graphics::kTextAlignCenter, _strsStrings[kMSIAboutString23].c_str() }, // "\xD2epx\xD3 Graphics Smoothing System \xA91992 Eric Johnson
- TEXT_END_MARKER
- };
+ // In the CD version, kMSIAboutString38 is empty. Probably because it
+ // added a menu item for it instead.
- const TextLine page10_floppy[] = {
+ const TextLine page10[] = {
{ 2, 19, kStyleRegular, Graphics::kTextAlignCenter, _strsStrings[kMSIAboutString22].c_str() }, // "\xD2djm\xD3 Sound and Music System \xA91992 Eric Johnston
{ 2, 39, kStyleRegular, Graphics::kTextAlignCenter, _strsStrings[kMSIAboutString23].c_str() }, // "\xD2epx\xD3 Graphics Smoothing System \xA91992 Eric Johnson
{ 2, 54, kStyleRegular, Graphics::kTextAlignCenter, _strsStrings[kMSIAboutString38].c_str() }, // "Type 'rough' to see the difference."
@@ -726,7 +717,7 @@ void MacV5Gui::runAboutDialogIndy4(MacDialogWindow *window) {
{ page7, 1, 4300 },
{ page8, 1, 4200 },
{ page9, 1, 4200 },
- { nullptr, 1, 4200 },
+ { page10, 1, 4200 },
{ page11, 1, 14100 },
{ page12, 1, 0 }
};
@@ -774,10 +765,6 @@ void MacV5Gui::runAboutDialogIndy4(MacDialogWindow *window) {
window->markRectAsDirty(Common::Rect(178, 129, s->w - 2, s->h - 2));
break;
- case 10:
- aboutPages[10].text = isFloppyVersion ? page10_floppy : page10_cd;
- break;
-
default:
break;
}
Commit: b807285ee62edd37bce0c2e556fbf2827920230e
https://github.com/scummvm/scummvm/commit/b807285ee62edd37bce0c2e556fbf2827920230e
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Minor cleanup
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 4a522b9bcf0..6be243b6184 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -990,11 +990,9 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect
switch (type & 0x7F) {
case 0:
- {
// User item
// window->innerSurface()->frameRect(r, black);
break;
- }
case 4:
// Button
str = getDialogString(res, len);
Commit: a26f5c1853845f1ebd4e5b48fc7e63fc8a4d7633
https://github.com/scummvm/scummvm/commit/a26f5c1853845f1ebd4e5b48fc7e63fc8a4d7633
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix major oops when dealing with "user items" in dialogs
I had forgotten to skip the data for the user item when parsing the DITL
resource. For most games this made no difference because the size was 0.
But for Day of the Tentacle, that was not the case. It turns out that a
lot of stuff that I was drawing manually was there all along!
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 6be243b6184..d385816ce15 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -992,6 +992,7 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect
case 0:
// User item
// window->innerSurface()->frameRect(r, black);
+ res->skip(len);
break;
case 4:
// Button
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index ccf7de2e482..1ac94d24aab 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -672,10 +672,6 @@ bool MacV6Gui::runOptionsDialog() {
window->setDefaultWidget(buttonOk);
- Graphics::Surface *surface = window->innerSurface();
- const Graphics::Font *font = getFont(kSystemFont);
- uint32 black = getBlack();
-
MacDropDownList *interactionDropDown = nullptr;
MacDropDownList *videoQualityDropDown = nullptr;
@@ -693,30 +689,6 @@ bool MacV6Gui::runOptionsDialog() {
videoQuality.push_back("Small");
if (_vm->_game.id == GID_TENTACLE) {
- // Unlike the other games, Day of the Tentacle uses a lot of
- // "user items" which we don't have a way to parse.
-
- Common::Point spritePos[] = {
- Common::Point(133, 87),
- Common::Point(310, 86),
- Common::Point(125, 175),
- Common::Point(307, 175)
- };
-
- for (int i = 0; i < ARRAYSIZE(spritePos); i++) {
- Graphics::Surface *s = loadPict(1000 + i);
- if (s) {
- window->drawSprite(s, spritePos[i].x, spritePos[i].y);
- s->free();
- delete s;
- }
- }
-
- font->drawString(surface, "Volume Settings", 27, 33, 110, black);
- font->drawString(surface, "Voice & Effects:", 23, 85, 105, black);
- font->drawString(surface, "Text & Voice Settings", 26, 122, 140, black);
- font->drawString(surface, "Text Speed:", 22, 175, 105, black);
-
// Yes, the frames really are supposed to be slightly
// misaligned to match the original appearance.
Commit: 3dcd69ed18356a3e78ca9361f9b1dafc533df0e7
https://github.com/scummvm/scummvm/commit/3dcd69ed18356a3e78ca9361f9b1dafc533df0e7
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Silence warning about unknown DITL item
We know type 7 are controls, we just don't know (yet) what to do with
them. At the very least, we may be able to extract some texts from the
corresponding CNTL resource.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index d385816ce15..b1d33dee6d9 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -1006,6 +1006,11 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect
window->addCheckbox(r, str, enabled);
break;
+ case 7:
+ // Control
+ res->skip(len);
+ break;
+
case 8:
// Static text
str = getDialogString(res, len);
Commit: ac9e6adef95f753308e41ec1832dab670ebafb3f
https://github.com/scummvm/scummvm/commit/ac9e6adef95f753308e41ec1832dab670ebafb3f
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Renamed the drop down list to pop-up menu
For consistency with Inside Machintosh.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index 229c7deff90..14d86d1a6fc 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -313,10 +313,10 @@ MacGuiImpl::MacListBox *MacGuiImpl::MacDialogWindow::addListBox(Common::Rect bou
return listBox;
}
-MacGuiImpl::MacDropDownList *MacGuiImpl::MacDialogWindow::addDropDownList(Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled) {
- MacGuiImpl::MacDropDownList *dropDownList = new MacDropDownList(this, bounds, text, textWidth, texts, enabled);
- addWidget(dropDownList, kWidgetDropDownList);
- return dropDownList;
+MacGuiImpl::MacPopUpMenu *MacGuiImpl::MacDialogWindow::addPopUpMenu(Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled) {
+ MacGuiImpl::MacPopUpMenu *popUpMenu = new MacPopUpMenu(this, bounds, text, textWidth, texts, enabled);
+ addWidget(popUpMenu, kWidgetPopUpMenu);
+ return popUpMenu;
}
void MacGuiImpl::MacDialogWindow::markRectAsDirty(Common::Rect r) {
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 4eb619c577a..03eeae1e47e 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -131,7 +131,7 @@ public:
kWidgetSlider,
kWidgetListBox,
kWidgetImageSlider,
- kWidgetDropDownList
+ kWidgetPopUpMenu
};
protected:
@@ -627,18 +627,18 @@ public:
bool handleKeyDown(Common::Event &event) override;
};
- class MacDropDownList : public MacWidget {
+ class MacPopUpMenu : public MacWidget {
private:
Common::StringArray _texts;
int _textWidth;
bool _menuVisible = false;
int _selected;
- Graphics::Surface _dropDownBackground;
- Common::Rect _dropDownBounds;
+ Graphics::Surface _popUpBackground;
+ Common::Rect _popUpBounds;
public:
- MacDropDownList(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled);
- ~MacDropDownList();
+ MacPopUpMenu(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled);
+ ~MacPopUpMenu();
bool findWidget(int x, int y) const override;
void draw(bool drawFocused = false) override;
@@ -737,7 +737,7 @@ public:
MacGuiImpl::MacImageSlider *addImageSlider(int backgroundId, int handleId, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin = 0, int rightMargin = 0);
MacGuiImpl::MacImageSlider *addImageSlider(Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue);
MacGuiImpl::MacListBox *addListBox(Common::Rect bounds, Common::StringArray texts, bool enabled, bool contentUntouchable = false);
- MacGuiImpl::MacDropDownList *addDropDownList(Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled);
+ MacGuiImpl::MacPopUpMenu *addPopUpMenu(Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled);
void addSubstitution(Common::String text) { _substitutions.push_back(text); }
void replaceSubstitution(int nr, Common::String text) { _substitutions[nr] = text; }
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 1ac94d24aab..79305758257 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -672,8 +672,8 @@ bool MacV6Gui::runOptionsDialog() {
window->setDefaultWidget(buttonOk);
- MacDropDownList *interactionDropDown = nullptr;
- MacDropDownList *videoQualityDropDown = nullptr;
+ MacPopUpMenu *interactionPopUp = nullptr;
+ MacPopUpMenu *videoQualityPopUp = nullptr;
Common::StringArray interactMode;
@@ -699,16 +699,16 @@ bool MacV6Gui::runOptionsDialog() {
addSlider(window, 152, 87, 147, 17);
addSlider(window, 151, 177, 147, 9);
- interactionDropDown = window->addDropDownList(Common::Rect(17, 148, 322, 167), "Interact using:", 125, interactMode, true);
- videoQualityDropDown = window->addDropDownList(Common::Rect(17, 218, 322, 237), "Video Quality:", 125, videoQuality, false);
+ interactionPopUp = window->addPopUpMenu(Common::Rect(17, 148, 322, 167), "Interact using:", 125, interactMode, true);
+ videoQualityPopUp = window->addPopUpMenu(Common::Rect(17, 218, 322, 237), "Video Quality:", 125, videoQuality, false);
- interactionDropDown->setValue(2);
- videoQualityDropDown->setValue(0);
+ interactionPopUp->setValue(2);
+ videoQualityPopUp->setValue(0);
} else if (_vm->_game.id == GID_MANIAC) {
addSlider(window, 152, 41, 147, 17);
addSlider(window, 152, 72, 147, 10, 5);
- videoQualityDropDown = window->addDropDownList(Common::Rect(18, 100, 323, 119), "Video Quality:", 125, videoQuality, false);
+ videoQualityPopUp = window->addPopUpMenu(Common::Rect(18, 100, 323, 119), "Video Quality:", 125, videoQuality, false);
} else if (_vm->_game.id == GID_SAMNMAX || _vm->_game.id == GID_DIG) {
drawDottedFrame(window, Common::Rect(12, 41, 337, 136), 21, 137);
drawDottedFrame(window, Common::Rect(12, 156, 337, 229), 20, 168);
@@ -718,8 +718,8 @@ bool MacV6Gui::runOptionsDialog() {
addSlider(window, 152, 111, 147, 17);
addSlider(window, 152, 203, 147, 9);
- interactionDropDown = window->addDropDownList(Common::Rect(18, 174, 323, 193), "Interact using:", 125, interactMode, true);
- videoQualityDropDown = window->addDropDownList(Common::Rect(18, 244, 323, 263), "Video Quality:", 125, videoQuality, false);
+ interactionPopUp = window->addPopUpMenu(Common::Rect(18, 174, 323, 193), "Interact using:", 125, interactMode, true);
+ videoQualityPopUp = window->addPopUpMenu(Common::Rect(18, 244, 323, 263), "Video Quality:", 125, videoQuality, false);
} else if (_vm->_game.id == GID_FT) {
drawDottedFrame(window, Common::Rect(12, 41, 337, 164), 21, 137);
drawDottedFrame(window, Common::Rect(12, 184, 337, 257), 20, 168);
@@ -729,8 +729,8 @@ bool MacV6Gui::runOptionsDialog() {
addSlider(window, 152, 111, 147, 17);
addSlider(window, 152, 231, 147, 9);
- interactionDropDown = window->addDropDownList(Common::Rect(18, 202, 323, 221), "Interact using:", 125, interactMode, true);
- videoQualityDropDown = window->addDropDownList(Common::Rect(18, 272, 323, 291), "Video Quality:", 125, videoQuality, false);
+ interactionPopUp = window->addPopUpMenu(Common::Rect(18, 202, 323, 221), "Interact using:", 125, interactMode, true);
+ videoQualityPopUp = window->addPopUpMenu(Common::Rect(18, 272, 323, 291), "Video Quality:", 125, videoQuality, false);
}
Common::Array<int> deferredActionsIds;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index c51e112375c..4eda7958285 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -1660,20 +1660,20 @@ bool MacGuiImpl::MacListBox::handleKeyDown(Common::Event &event) {
// Drop down widget
// ---------------------------------------------------------------------------
-MacGuiImpl::MacDropDownList::MacDropDownList(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled) : MacWidget(window, bounds, text, enabled), _textWidth(textWidth), _texts(texts) {
+MacGuiImpl::MacPopUpMenu::MacPopUpMenu(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled) : MacWidget(window, bounds, text, enabled), _textWidth(textWidth), _texts(texts) {
_black = _window->_gui->getBlack();
_white = _window->_gui->getWhite();
- _dropDownBounds.left = _bounds.left + _textWidth;
- _dropDownBounds.right = _bounds.right;
+ _popUpBounds.left = _bounds.left + _textWidth;
+ _popUpBounds.right = _bounds.right;
}
-MacGuiImpl::MacDropDownList::~MacDropDownList() {
+MacGuiImpl::MacPopUpMenu::~MacPopUpMenu() {
_texts.clear();
- _dropDownBackground.free();
+ _popUpBackground.free();
}
-bool MacGuiImpl::MacDropDownList::findWidget(int x, int y) const {
+bool MacGuiImpl::MacPopUpMenu::findWidget(int x, int y) const {
// Once we have opened the drop down list, any mouse position is
// considered within the widget.
@@ -1683,11 +1683,11 @@ bool MacGuiImpl::MacDropDownList::findWidget(int x, int y) const {
return _bounds.contains(x, y);
}
-void MacGuiImpl::MacDropDownList::draw(bool drawFocused) {
+void MacGuiImpl::MacPopUpMenu::draw(bool drawFocused) {
if (!_redraw && !_fullRedraw)
return;
- debug(1, "MacGuiImpl::MacDropDownList: Drawing list box (_fullRedraw = %d, drawFocused = %d)", _fullRedraw, drawFocused);
+ debug(1, "MacGuiImpl::MacPopUpMenu: Drawing list box (_fullRedraw = %d, drawFocused = %d)", _fullRedraw, drawFocused);
// I don't know how Mac originally drew disabled drop downs lists, or
// if that was even a thing. For our purposes, the text is still
@@ -1712,7 +1712,7 @@ void MacGuiImpl::MacDropDownList::draw(bool drawFocused) {
font->drawString(s, _text, _bounds.left, _bounds.top + 1, _textWidth, fg, Graphics::kTextAlignLeft, 4);
if (focused) {
- Common::Rect r = _dropDownBounds;
+ Common::Rect r = _popUpBounds;
r.bottom--;
r.right--;
@@ -1772,23 +1772,23 @@ void MacGuiImpl::MacDropDownList::draw(bool drawFocused) {
_window->markRectAsDirty(_bounds);
if (focused)
- _window->markRectAsDirty(_dropDownBounds);
+ _window->markRectAsDirty(_popUpBounds);
}
-void MacGuiImpl::MacDropDownList::handleMouseDown(Common::Event &event) {
- _dropDownBounds.top = _bounds.top - 16 * _value;
- _dropDownBounds.bottom = _bounds.bottom + 16 * (_texts.size() - _value - 1);
+void MacGuiImpl::MacPopUpMenu::handleMouseDown(Common::Event &event) {
+ _popUpBounds.top = _bounds.top - 16 * _value;
+ _popUpBounds.bottom = _bounds.bottom + 16 * (_texts.size() - _value - 1);
- Graphics::Surface background = _window->innerSurface()->getSubArea(_dropDownBounds);
+ Graphics::Surface background = _window->innerSurface()->getSubArea(_popUpBounds);
- _dropDownBackground.free();
- _dropDownBackground.copyFrom(background);
+ _popUpBackground.free();
+ _popUpBackground.copyFrom(background);
_menuVisible = true;
_selected = _value;
}
-bool MacGuiImpl::MacDropDownList::handleMouseUp(Common::Event &event) {
+bool MacGuiImpl::MacPopUpMenu::handleMouseUp(Common::Event &event) {
if (_selected != -1) {
int selected = _selected;
@@ -1816,17 +1816,17 @@ bool MacGuiImpl::MacDropDownList::handleMouseUp(Common::Event &event) {
setValue(selected);
}
- _window->drawSprite(&_dropDownBackground, _dropDownBounds.left, _dropDownBounds.top);
+ _window->drawSprite(&_popUpBackground, _popUpBounds.left, _popUpBounds.top);
_menuVisible = false;
return false;
}
-void MacGuiImpl::MacDropDownList::handleMouseMove(Common::Event &event) {
+void MacGuiImpl::MacPopUpMenu::handleMouseMove(Common::Event &event) {
if (!_menuVisible)
return;
- Common::Rect menuBounds(_dropDownBounds.left + 1, _dropDownBounds.top + 1, _dropDownBounds.right - 2, _dropDownBounds.bottom - 2);
+ Common::Rect menuBounds(_popUpBounds.left + 1, _popUpBounds.top + 1, _popUpBounds.right - 2, _popUpBounds.bottom - 2);
int selected = -1;
@@ -1836,7 +1836,7 @@ void MacGuiImpl::MacDropDownList::handleMouseMove(Common::Event &event) {
int maxValue = _texts.size() - 1;
if (selected > maxValue) {
- warning("MacGuiImpl::MacDropDownList::handleMouseMove: Max selection value exceeded");
+ warning("MacGuiImpl::MacPopUpMenu::handleMouseMove: Max selection value exceeded");
selected = -1;
}
}
Commit: 3e56e56ee73bcfdec8b81e65c1fb503330ff1461
https://github.com/scummvm/scummvm/commit/3e56e56ee73bcfdec8b81e65c1fb503330ff1461
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Generate pop-up menus from the DITL resource
This way we no longer hard-code English texts.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index 14d86d1a6fc..216b238b9a9 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -20,6 +20,7 @@
*/
#include "common/system.h"
+#include "common/macresman.h"
#include "graphics/cursorman.h"
#include "graphics/macgui/macwindowmanager.h"
@@ -319,6 +320,57 @@ MacGuiImpl::MacPopUpMenu *MacGuiImpl::MacDialogWindow::addPopUpMenu(Common::Rect
return popUpMenu;
}
+void MacGuiImpl::MacDialogWindow::addControl(Common::Rect bounds, uint16 controlId) {
+ Common::MacResManager resource;
+
+ resource.open(_gui->_resourceFile);
+
+ Common::SeekableReadStream *cntl = resource.getResource(MKTAG('C', 'N', 'T', 'L'), controlId);
+ if (cntl) {
+ byte cntlHeader[22];
+
+ cntl->read(cntlHeader, sizeof(cntlHeader));
+ Common::String cntlText = cntl->readPascalString();
+
+ uint16 procId = READ_BE_UINT16(cntlHeader + 16);
+
+ if ((procId & 0xFFF0) == 0x03F0) {
+ uint16 textWidth = READ_BE_UINT16(cntlHeader + 12);
+ uint16 menuId = READ_BE_UINT16(cntlHeader + 14);
+
+ Common::SeekableReadStream *menu = resource.getResource(MKTAG('M', 'E', 'N', 'U'), menuId);
+ if (menu) {
+ menu->skip(14);
+ menu->skip(menu->readByte());
+
+ Common::StringArray items;
+
+ while (true) {
+ Common::String str;
+
+ str = menu->readPascalString();
+
+ if (str.empty())
+ break;
+
+ items.push_back(str);
+ menu->skip(4);
+ }
+
+ delete menu;
+
+ addPopUpMenu(bounds, cntlText, textWidth, items, true);
+ } else
+ warning("MacGuiImpl::addPopUpMenu: Could not load MENU %d", menuId);
+ } else
+ warning("MacGuiImpl::addPopUpMenu: Unknown control ProcID: %d", procId);
+ delete cntl;
+ } else
+ warning("MacGuiImpl::addPopUpMenu: Could not load CNTL %d", controlId);
+
+ resource.close();
+}
+
void MacGuiImpl::MacDialogWindow::markRectAsDirty(Common::Rect r) {
_dirtyRects.push_back(r);
}
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index b1d33dee6d9..d4bdbb12bcb 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -797,15 +797,6 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createWindow(Common::Rect bounds, MacDi
return new MacDialogWindow(this, _system, _surface, bounds, windowStyle, menuStyle);
}
-Common::String MacGuiImpl::getDialogString(Common::SeekableReadStream *res, int len) {
- Common::String str;
-
- for (int i = 0; i < len; i++)
- str += res->readByte();
-
- return str;
-}
-
MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId) {
Common::Rect bounds;
@@ -996,24 +987,27 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect
break;
case 4:
// Button
- str = getDialogString(res, len);
+ res->seek(-1, SEEK_CUR);
+ str = res->readPascalString();
window->addButton(r, str, enabled);
break;
case 5:
// Checkbox
- str = getDialogString(res, len);
+ res->seek(-1, SEEK_CUR);
+ str = res->readPascalString();
window->addCheckbox(r, str, enabled);
break;
case 7:
// Control
- res->skip(len);
+ window->addControl(r, res->readUint16BE());
break;
case 8:
// Static text
- str = getDialogString(res, len);
+ res->seek(-1, SEEK_CUR);
+ str = res->readPascalString();
window->addStaticText(r, str, enabled);
break;
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 03eeae1e47e..a3d4b55b9e1 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -220,8 +220,6 @@ protected:
virtual bool getFontParams(FontId fontId, int &id, int &size, int &slant) const;
- Common::String getDialogString(Common::SeekableReadStream *res, int len);
-
virtual bool handleMenu(int id, Common::String &name);
virtual void onMenuOpen();
virtual void onMenuClose();
@@ -733,12 +731,15 @@ public:
MacGuiImpl::MacEditText *addEditText(Common::Rect bounds, Common::String text, bool enabled);
MacGuiImpl::MacImage *addIcon(int x, int y, int id, bool enabled);
MacGuiImpl::MacImage *addPicture(Common::Rect bounds, int id, bool enabled);
+ MacGuiImpl::
MacGuiImpl::MacSlider *addSlider(int x, int y, int h, int minValue, int maxValue, int pageSize, bool enabled);
MacGuiImpl::MacImageSlider *addImageSlider(int backgroundId, int handleId, bool enabled, int minX, int maxX, int minValue, int maxValue, int leftMargin = 0, int rightMargin = 0);
MacGuiImpl::MacImageSlider *addImageSlider(Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue);
MacGuiImpl::MacListBox *addListBox(Common::Rect bounds, Common::StringArray texts, bool enabled, bool contentUntouchable = false);
MacGuiImpl::MacPopUpMenu *addPopUpMenu(Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled);
+ void addControl(Common::Rect bounds, uint16 controlId);
+
void addSubstitution(Common::String text) { _substitutions.push_back(text); }
void replaceSubstitution(int nr, Common::String text) { _substitutions[nr] = text; }
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 79305758257..e49bdb1edd1 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -663,30 +663,33 @@ bool MacV6Gui::runOptionsDialog() {
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
// MacButton *buttonDefaults = (MacButton *)window->getWidget(kWidgetButton, 2);
+ MacPopUpMenu *interactionPopUp = nullptr;
+ MacPopUpMenu *videoQualityPopUp = nullptr;
+
if (_vm->_game.id != GID_MANIAC) {
window->addSubstitution("");
window->addSubstitution("");
window->addSubstitution("");
window->addSubstitution(_gameName);
+
+ interactionPopUp = (MacPopUpMenu *)window->getWidget(kWidgetPopUpMenu, 0);
+ videoQualityPopUp = (MacPopUpMenu *)window->getWidget(kWidgetPopUpMenu, 1);
+ } else {
+ videoQualityPopUp = (MacPopUpMenu *)window->getWidget(kWidgetPopUpMenu, 0);
}
- window->setDefaultWidget(buttonOk);
+ if (interactionPopUp)
+ interactionPopUp->setValue(2);
- MacPopUpMenu *interactionPopUp = nullptr;
- MacPopUpMenu *videoQualityPopUp = nullptr;
+ // Note: The video quality menu contains an additional "Graphics
+ // Smoothing" entry. I don't know why it doesn't show up in the
+ // original, but as long as we disabled the pop-up that's not a
+ // problem. My future self can thank me later.
- Common::StringArray interactMode;
+ videoQualityPopUp->setValue(1);
+ videoQualityPopUp->setEnabled(false);
- if (_vm->_game.id != GID_MANIAC) {
- interactMode.push_back("Text Only");
- interactMode.push_back("Voice Only");
- interactMode.push_back("Text & Voice");
- }
-
- Common::StringArray videoQuality;
- videoQuality.push_back("Double Size");
- videoQuality.push_back("Interlaced");
- videoQuality.push_back("Small");
+ window->setDefaultWidget(buttonOk);
if (_vm->_game.id == GID_TENTACLE) {
// Yes, the frames really are supposed to be slightly
@@ -698,17 +701,9 @@ bool MacV6Gui::runOptionsDialog() {
addSlider(window, 152, 63, 147, 17);
addSlider(window, 152, 87, 147, 17);
addSlider(window, 151, 177, 147, 9);
-
- interactionPopUp = window->addPopUpMenu(Common::Rect(17, 148, 322, 167), "Interact using:", 125, interactMode, true);
- videoQualityPopUp = window->addPopUpMenu(Common::Rect(17, 218, 322, 237), "Video Quality:", 125, videoQuality, false);
-
- interactionPopUp->setValue(2);
- videoQualityPopUp->setValue(0);
} else if (_vm->_game.id == GID_MANIAC) {
addSlider(window, 152, 41, 147, 17);
addSlider(window, 152, 72, 147, 10, 5);
-
- videoQualityPopUp = window->addPopUpMenu(Common::Rect(18, 100, 323, 119), "Video Quality:", 125, videoQuality, false);
} else if (_vm->_game.id == GID_SAMNMAX || _vm->_game.id == GID_DIG) {
drawDottedFrame(window, Common::Rect(12, 41, 337, 136), 21, 137);
drawDottedFrame(window, Common::Rect(12, 156, 337, 229), 20, 168);
@@ -717,9 +712,6 @@ bool MacV6Gui::runOptionsDialog() {
addSlider(window, 152, 87, 147, 17);
addSlider(window, 152, 111, 147, 17);
addSlider(window, 152, 203, 147, 9);
-
- interactionPopUp = window->addPopUpMenu(Common::Rect(18, 174, 323, 193), "Interact using:", 125, interactMode, true);
- videoQualityPopUp = window->addPopUpMenu(Common::Rect(18, 244, 323, 263), "Video Quality:", 125, videoQuality, false);
} else if (_vm->_game.id == GID_FT) {
drawDottedFrame(window, Common::Rect(12, 41, 337, 164), 21, 137);
drawDottedFrame(window, Common::Rect(12, 184, 337, 257), 20, 168);
@@ -728,9 +720,6 @@ bool MacV6Gui::runOptionsDialog() {
addSlider(window, 152, 87, 147, 17);
addSlider(window, 152, 111, 147, 17);
addSlider(window, 152, 231, 147, 9);
-
- interactionPopUp = window->addPopUpMenu(Common::Rect(18, 202, 323, 221), "Interact using:", 125, interactMode, true);
- videoQualityPopUp = window->addPopUpMenu(Common::Rect(18, 272, 323, 291), "Video Quality:", 125, videoQuality, false);
}
Common::Array<int> deferredActionsIds;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 4eda7958285..59710b176ae 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -1664,6 +1664,8 @@ MacGuiImpl::MacPopUpMenu::MacPopUpMenu(MacGuiImpl::MacDialogWindow *window, Comm
_black = _window->_gui->getBlack();
_white = _window->_gui->getWhite();
+ _bounds.bottom--;
+
_popUpBounds.left = _bounds.left + _textWidth;
_popUpBounds.right = _bounds.right;
}
Commit: c45ea28c5dea383c28e9fe999bcd00a6b749cf16
https://github.com/scummvm/scummvm/commit/c45ea28c5dea383c28e9fe999bcd00a6b749cf16
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Read menu IDs from MBAR resource where available
This should get rid of the last hard-coded English text for v6-7 games.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index d4bdbb12bcb..c68fd2c9f18 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -23,6 +23,7 @@
#include "common/config-manager.h"
#include "common/enc-internal.h"
#include "common/macresman.h"
+#include "common/str.h"
#include "graphics/cursorman.h"
#include "graphics/paletteman.h"
@@ -210,70 +211,52 @@ bool MacGuiImpl::initialize() {
{ 0, nullptr, 0, 0, false }
};
- // TODO: For V6-7 games we could look at the MBAR resource.
-
- Common::String aboutMenuDef = _strsStrings[kMSIAboutGameName].c_str();
- int maxMenu = -1;
- switch (_vm->_game.id) {
- case GID_INDY3:
- case GID_LOOM:
- maxMenu = 130;
- break;
- case GID_MONKEY:
- maxMenu = 131;
- break;
- default:
- maxMenu = 132;
- }
-
- if (_vm->_game.id == GID_LOOM) {
- aboutMenuDef += ";";
-
- if (!_vm->enhancementEnabled(kEnhUIUX))
- aboutMenuDef += "(";
-
- aboutMenuDef += "Drafts Inventory";
- }
-
- menu->addStaticMenus(menuSubItems);
- menu->createSubMenuFromString(0, aboutMenuDef.c_str(), 0);
-
menu->setCommandsCallback(menuCallback, this);
- for (int i = 129; i <= maxMenu; i++) {
- Common::SeekableReadStream *res = resource.getResource(MKTAG('M', 'E', 'N', 'U'), i);
+ // Newer games define their menus through an MBAR resource
- if (!res)
- continue;
+ Common::SeekableReadStream *mbar = resource.getResource(MKTAG('M', 'B', 'A', 'R'), 128);
- Common::StringArray *menuDef = Graphics::MacMenu::readMenuFromResource(res);
- Common::String name = menuDef->operator[](0);
- Common::String string = menuDef->operator[](1);
- int id = menu->addMenuItem(nullptr, name);
+ if (mbar) {
+ uint16 numMenus = mbar->readUint16BE();
+ for (uint i = 0; i < numMenus; i++) {
+ uint16 menuId = mbar->readUint16BE();
+ addMenu(menu, menuId);
+ }
+ delete mbar;
+ } else {
+ Common::String aboutMenuDef = _strsStrings[kMSIAboutGameName].c_str();
+ int maxMenu = -1;
+ switch (_vm->_game.id) {
+ case GID_INDY3:
+ case GID_LOOM:
+ maxMenu = 130;
+ break;
+ case GID_MONKEY:
+ maxMenu = 131;
+ break;
+ default:
+ maxMenu = 132;
+ }
- // The CD version of Fate of Atlantis has a menu item
- // for toggling graphics smoothing. We retroactively
- // add that to the remaining V5 games, but not to
- // Loom and Last Crusade.
+ if (_vm->_game.id == GID_LOOM) {
+ aboutMenuDef += ";";
- if (_vm->enhancementEnabled(kEnhUIUX)) {
- if ((_vm->_game.id == GID_MONKEY || _vm->_game.id == GID_MONKEY2) && id == 3) {
- string += ";(-;Smooth Graphics";
- }
+ if (!_vm->enhancementEnabled(kEnhUIUX))
+ aboutMenuDef += "(";
- // Floppy version
- if (_vm->_game.id == GID_INDY4 && !string.contains("Smooth Graphics") && id == 3) {
- string += ";(-;Smooth Graphics";
- }
+ aboutMenuDef += "Drafts Inventory";
}
- menu->createSubMenuFromString(id, string.c_str(), 0);
+ menu->addStaticMenus(menuSubItems);
+ menu->createSubMenuFromString(0, aboutMenuDef.c_str(), 0);
- delete menuDef;
- delete res;
- }
+ for (int i = 129; i <= maxMenu; i++) {
+ addMenu(menu, i);
+ }
- resource.close();
+ resource.close();
+ }
// Assign sensible IDs to the menu items
@@ -285,10 +268,16 @@ bool MacGuiImpl::initialize() {
int id = 100 * (i + 1);
for (int j = 0; j < numberOfMenuItems; j++) {
Graphics::MacMenuItem *subItem = menu->getSubMenuItem(item, j);
- Common::String name = menu->getName(subItem);
+ Common::String str = menu->getName(subItem);
- if (!name.empty())
+ if (!str.empty()) {
menu->setAction(subItem, id++);
+ }
+
+ if (str.contains("^3")) {
+ Common::replace(str, "^3", name());
+ menu->setName(subItem, str);
+ }
}
}
}
@@ -312,6 +301,46 @@ bool MacGuiImpl::initialize() {
return true;
}
+void MacGuiImpl::addMenu(Graphics::MacMenu *menu, int menuId) {
+ Common::MacResManager resource;
+
+ resource.open(_resourceFile);
+
+ Common::SeekableReadStream *res = resource.getResource(MKTAG('M', 'E', 'N', 'U'), menuId);
+
+ if (!res) {
+ resource.close();
+ return;
+ }
+
+ Common::StringArray *menuDef = Graphics::MacMenu::readMenuFromResource(res);
+ Common::String name = menuDef->operator[](0);
+ Common::String string = menuDef->operator[](1);
+ int id = menu->addMenuItem(nullptr, name);
+
+ // The CD version of Fate of Atlantis has a menu item for toggling graphics
+ // smoothing. We retroactively add that to the remaining V5 games, but not
+ // to Loom and Last Crusade.
+
+ if (_vm->enhancementEnabled(kEnhUIUX)) {
+ if ((_vm->_game.id == GID_MONKEY || _vm->_game.id == GID_MONKEY2) && id == 3) {
+ string += ";(-;Smooth Graphics";
+ }
+
+ // Floppy version
+ if (_vm->_game.id == GID_INDY4 && !string.contains("Smooth Graphics") && id == 3) {
+ string += ";(-;Smooth Graphics";
+ }
+ }
+
+ menu->createSubMenuFromString(id, string.c_str(), 0);
+
+ delete menuDef;
+ delete res;
+
+ resource.close();
+}
+
bool MacGuiImpl::handleMenu(int id, Common::String &name) {
// This menu item (e.g. a menu separator) has no action, so it's
// handled trivially.
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index a3d4b55b9e1..82cb0deaf73 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -46,6 +46,7 @@ namespace Graphics {
struct Surface;
class Palette;
class MacWindowManager;
+class MacMenu;
}
namespace Scumm {
@@ -240,6 +241,8 @@ protected:
virtual bool readStrings();
void parseSTRSBlock(uint8 *strsData, const MacSTRSParsingEntry *parsingTable, int parsingTableSize);
+ void addMenu(Graphics::MacMenu *menu, int menuId);
+
// These are non interactable, no point in having them as widgets for now...
void drawFakePathList(MacDialogWindow *window, Common::Rect r, const char *text);
void drawFakeDriveLabel(MacDialogWindow *window, Common::Rect r, const char *text);
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index e49bdb1edd1..e215b461e6c 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -77,8 +77,6 @@ bool MacV6Gui::readStrings() {
_strsStrings.reserve(128);
for (int i = 0; i < 128; i++)
_strsStrings.emplace_back("");
-
- _strsStrings[kMSIAboutGameName] = "About " + _gameName + "...";
return true;
}
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index c8f10177c9d..198482af448 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -45,7 +45,7 @@ public:
bool readStrings() override;
- const Common::String name() const override { return _strsStrings[kMSIGameName]; }
+ const Common::String name() const override { return _gameName; }
int getNumColors() const override { return 256; }
// See setMacGuiColors()
Commit: 4a0de6e4c730c8c10f31ce5449d21e88e1733767
https://github.com/scummvm/scummvm/commit/4a0de6e4c730c8c10f31ce5449d21e88e1733767
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Remove hardcoded "Game" menu name
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index c68fd2c9f18..e2d5672e92c 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -466,7 +466,7 @@ void MacGuiImpl::updateWindowManager() {
bool canLoad = _vm->canLoadGameStateCurrently() && loadCondition;
bool canSave = _vm->canSaveGameStateCurrently() && saveCondition;
- Graphics::MacMenuItem *gameMenu = menu->getMenuItem("Game");
+ Graphics::MacMenuItem *gameMenu = menu->getMenuItem(1);
Graphics::MacMenuItem *loadMenu = menu->getSubMenuItem(gameMenu, 0);
Graphics::MacMenuItem *saveMenu = menu->getSubMenuItem(gameMenu, 1);
Commit: cb5a60a7917e83aa8f8e2e6aabe9164978b264fe
https://github.com/scummvm/scummvm/commit/cb5a60a7917e83aa8f8e2e6aabe9164978b264fe
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Clarify comment a bit
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index e215b461e6c..26615282e22 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -382,6 +382,7 @@ MacGuiImpl::MacImageSlider *MacV6Gui::addSlider(MacDialogWindow *window, int x,
void MacV6Gui::runAboutDialog() {
if (_vm->_game.features & GF_DEMO) {
// HACK: Use the largest bounds as default for unknown demos
+ // It would be nice if we could figure these out automatically
Common::Rect bounds(117, 5, 523, 384);
if (_vm->_game.id == GID_SAMNMAX) {
Commit: 2c7b998cec0c98f25f9c360749f2327b66f256f2
https://github.com/scummvm/scummvm/commit/2c7b998cec0c98f25f9c360749f2327b66f256f2
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Rework the dialog window event loop
Each dialog now has an event queue. The runDialog() method consumes all
ScummVM events and transforms them into dialog events. This should make
it easier to have widgets depend on each other, e.g. I want the v6-7
Open dialog to update the thumbnail picture.
This may have caused regressions, but initial tests seemed promising.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_indy3.cpp
engines/scumm/macgui/macgui_loom.cpp
engines/scumm/macgui/macgui_v5.cpp
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index 216b238b9a9..e3344594c63 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -513,12 +513,22 @@ void MacGuiImpl::MacDialogWindow::fillPattern(Common::Rect r, uint16 pattern, bo
markRectAsDirty(r);
}
-int MacGuiImpl::MacDialogWindow::runDialog(Common::Array<int> &deferredActionIds) {
+void MacGuiImpl::MacDialogWindow::queueEvent(MacWidget *widget, MacDialogEventType type) {
+ MacDialogEvent event;
+
+ event.widget = widget;
+ event.type = type;
+
+ _eventQueue.push(event);
+}
+
+bool MacGuiImpl::MacDialogWindow::runDialog(MacGuiImpl::MacDialogEvent &dialogEvent) {
+ for (uint i = 0; i < _widgets.size(); i++)
+ _widgets[i]->rememberValue();
+
// The first time the function is called, show the dialog and redraw
// all widgets completely.
- deferredActionIds.clear();
-
if (!_visible) {
show();
@@ -530,229 +540,224 @@ int MacGuiImpl::MacDialogWindow::runDialog(Common::Array<int> &deferredActionIds
}
}
- // Run the dialog until something interesting happens to a widget. It's
- // up to the caller to repeat the calls to runDialog() until the dialog
- // has ended.
+ // Handle all incoming events and turn them into dialog events.
bool buttonPressed = false;
uint32 nextMouseRepeat = 0;
- while (!_gui->_vm->shouldQuit()) {
- Common::Event event;
- int widgetId = -1;
+ Common::Event event;
- while (_system->getEventManager()->pollEvent(event)) {
- // Adjust mouse coordinates to the dialog window
+ while (_system->getEventManager()->pollEvent(event)) {
+ // Adjust mouse coordinates to the dialog window
- if (Common::isMouseEvent(event)) {
- _realMousePos.x = event.mouse.x;
- _realMousePos.y = event.mouse.y;
+ if (Common::isMouseEvent(event)) {
+ _realMousePos.x = event.mouse.x;
+ _realMousePos.y = event.mouse.y;
- event.mouse.x -= (_bounds.left + _margin);
- event.mouse.y -= (_bounds.top + _margin);
+ event.mouse.x -= (_bounds.left + _margin);
+ event.mouse.y -= (_bounds.top + _margin);
- _oldMousePos = _mousePos;
+ _oldMousePos = _mousePos;
- _mousePos.x = event.mouse.x;
- _mousePos.y = event.mouse.y;
+ _mousePos.x = event.mouse.x;
+ _mousePos.y = event.mouse.y;
- // Update engine mouse position
- _gui->_vm->_mouse.x = _realMousePos.x / 2;
- _gui->_vm->_mouse.y = _realMousePos.y / 2;
- }
+ // Update engine mouse position
+ _gui->_vm->_mouse.x = _realMousePos.x / 2;
+ _gui->_vm->_mouse.y = _realMousePos.y / 2;
+ }
- int w;
-
- switch (event.type) {
- case Common::EVENT_LBUTTONDOWN:
- // When a widget is clicked, it becomes the
- // focused widget. Focused widgets are often
- // indicated by some sort of highlight, e.g.
- // buttons become inverted.
- //
- // This highlight is usually only shown while
- // the mouse is within the widget bounds, but
- // as long as it remains focused it can regain
- // the highlight by moving the cursor back into
- // the widget bounds again.
- //
- // It's unclear to me if Macs should handle
- // double clicks on mouse down, mouse up or
- // both.
-
- buttonPressed = true;
- nextMouseRepeat = _system->getMillis() + 40;
- setFocusedWidget(event.mouse.x, event.mouse.y);
- if (_focusedWidget) {
- _focusedWidget->handleMouseDown(event);
-
- uint32 now = _system->getMillis();
- bool doubleClick =
- (now - _lastClickTime < 500 &&
- ABS(event.mouse.x - _lastClickPos.x) < 5 &&
- ABS(event.mouse.y - _lastClickPos.y) < 5);
-
- _lastClickTime = _system->getMillis();
- _lastClickPos.x = event.mouse.x;
- _lastClickPos.y = event.mouse.y;
-
- if (doubleClick && _focusedWidget->handleDoubleClick(event))
- return _focusedWidget->getId();
- }
- break;
+ int w;
+
+ switch (event.type) {
+ case Common::EVENT_LBUTTONDOWN:
+ // When a widget is clicked, it becomes the focused
+ // widget. Focused widgets are often indicated by some
+ // sort of highlight, e.g. buttons become inverted.
+ //
+ // This highlight is usually only shown while the mouse
+ // is within the widget bounds, but as long as it
+ // remains focused it can regain the highlight by
+ // moving the cursor back into the widget bounds again.
+ //
+ // It's unclear to me if Macs should handle double
+ // clicks on mouse down, mouse up or both.
+
+ buttonPressed = true;
+ nextMouseRepeat = _system->getMillis() + 40;
+ setFocusedWidget(event.mouse.x, event.mouse.y);
+ if (_focusedWidget) {
+ _focusedWidget->handleMouseDown(event);
+
+ uint32 now = _system->getMillis();
+ bool doubleClick =
+ (now - _lastClickTime < 500 &&
+ ABS(event.mouse.x - _lastClickPos.x) < 5 &&
+ ABS(event.mouse.y - _lastClickPos.y) < 5);
+
+ _lastClickTime = _system->getMillis();
+ _lastClickPos.x = event.mouse.x;
+ _lastClickPos.y = event.mouse.y;
+
+ if (doubleClick && _focusedWidget->handleDoubleClick(event))
+ queueEvent(_focusedWidget, kDialogClick);
+ }
+ break;
- case Common::EVENT_LBUTTONUP:
- buttonPressed = false;
+ case Common::EVENT_LBUTTONUP:
+ buttonPressed = false;
- // Only the focused widget receives the button
- // up event. If the widget handles the event,
- // control is passed back to the caller of
- // runDialog() so that it can react, e.g. to
- // the user clicking the "Okay" button.
+ // Only the focused widget receives the button up
+ // event. If the widget handles the event, it produces
+ // a dialog click event.
- if (_focusedWidget) {
- MacWidget *widget = _focusedWidget;
+ if (_focusedWidget) {
+ MacWidget *widget = _focusedWidget;
- if (widget->findWidget(event.mouse.x, event.mouse.y)) {
- widgetId = widget->getId();
- if (widget->handleMouseUp(event)) {
- clearFocusedWidget();
- return widgetId;
- }
+ if (widget->findWidget(event.mouse.x, event.mouse.y)) {
+ if (widget->handleMouseUp(event)) {
+ clearFocusedWidget();
+ queueEvent(widget, kDialogClick);
}
-
- clearFocusedWidget();
}
- updateCursor();
- break;
+ clearFocusedWidget();
+ }
- case Common::EVENT_MOUSEMOVE:
- // The "beam" cursor can be hidden, but will
- // become visible again when the user moves
- // the mouse.
+ updateCursor();
+ break;
- if (_beamCursor)
- _beamCursorVisible = true;
+ case Common::EVENT_MOUSEMOVE:
+ // The "beam" cursor can be hidden, but will become
+ // visible again when the user moves the mouse.
- // Only the focused widget receives mouse move
- // events, and then only if the mouse is within
- // the widget's area of control. This are of
- // control is usually the widget bounds, but
- // widgets can redefine findWidget() to change
- // this, e.g. for slider widgets.
+ if (_beamCursor)
+ _beamCursorVisible = true;
- if (_focusedWidget) {
- bool wasActive = _focusedWidget->findWidget(_oldMousePos.x, _oldMousePos.y);
- bool isActive = _focusedWidget->findWidget(_mousePos.x, _mousePos.y);
+ // Only the focused widget receives mouse move events,
+ // and then only if the mouse is within the widget's
+ // area of control. This are of control is usually the
+ // widget bounds, but widgets can redefine findWidget()
+ // to change this, e.g. for slider widgets.
- if (wasActive != isActive)
- _focusedWidget->setRedraw();
+ if (_focusedWidget) {
+ bool wasActive = _focusedWidget->findWidget(_oldMousePos.x, _oldMousePos.y);
+ bool isActive = _focusedWidget->findWidget(_mousePos.x, _mousePos.y);
- // The widget gets mouse events while
- // it's active, but also one last one
- // when it becomes inactive.
+ if (wasActive != isActive)
+ _focusedWidget->setRedraw();
- if (isActive || wasActive)
- _focusedWidget->handleMouseMove(event);
- } else {
- updateCursor();
- }
+ // The widget gets mouse events while it's
+ // active, but also one last one when it
+ // becomes inactive.
+
+ if (isActive || wasActive)
+ _focusedWidget->handleMouseMove(event);
+ } else {
+ updateCursor();
+ }
+ break;
+
+ case Common::EVENT_WHEELUP:
+ if (!_gui->_vm->enhancementEnabled(kEnhUIUX) || _focusedWidget)
break;
- case Common::EVENT_WHEELUP:
- if (!_gui->_vm->enhancementEnabled(kEnhUIUX) || _focusedWidget)
- break;
+ w = findWidget(event.mouse.x, event.mouse.y);
+ if (w >= 0)
+ _widgets[w]->handleWheelUp();
- w = findWidget(event.mouse.x, event.mouse.y);
- if (w >= 0)
- _widgets[w]->handleWheelUp();
+ break;
+ case Common::EVENT_WHEELDOWN:
+ if (!_gui->_vm->enhancementEnabled(kEnhUIUX) || _focusedWidget)
break;
- case Common::EVENT_WHEELDOWN:
- if (!_gui->_vm->enhancementEnabled(kEnhUIUX) || _focusedWidget)
- break;
+ w = findWidget(event.mouse.x, event.mouse.y);
+ if (w >= 0)
+ _widgets[w]->handleWheelDown();
- w = findWidget(event.mouse.x, event.mouse.y);
- if (w >= 0)
- _widgets[w]->handleWheelDown();
+ break;
+ case Common::EVENT_KEYDOWN:
+ // Ignore keyboard while mouse is pressed
+ if (buttonPressed)
break;
- case Common::EVENT_KEYDOWN:
- // Ignore keyboard while mouse is pressed
- if (buttonPressed)
- break;
-
- // Handle default button
- if (event.kbd.keycode == Common::KEYCODE_RETURN) {
- MacWidget *widget = getDefaultWidget();
- if (widget && widget->isEnabled() && widget->isVisible()) {
- for (int i = 0; i < 2; i++) {
- widget->setRedraw();
- widget->draw(i == 0);
- update();
-
- for (int j = 0; j < 10; j++) {
- _system->delayMillis(10);
- _system->updateScreen();
- }
+ // Handle default button
+ if (event.kbd.keycode == Common::KEYCODE_RETURN) {
+ MacWidget *widget = getDefaultWidget();
+ if (widget && widget->isEnabled() && widget->isVisible()) {
+ for (int i = 0; i < 2; i++) {
+ widget->setRedraw();
+ widget->draw(i == 0);
+ update();
+
+ for (int j = 0; j < 10; j++) {
+ _system->delayMillis(10);
+ _system->updateScreen();
}
-
- return widget->getId();
}
+
+ queueEvent(widget, kDialogClick);
}
+ }
- // Otherwise, give widgets a chance to react
- // to key presses. All widgets get a chance,
- // whether or not they are focused. This may
- // be a bad idea, if there is ever more than
- // one edit text widget in the window.
- //
- // Typing hides the "beam" cursor.
-
- for (uint i = 0; i < _widgets.size(); i++) {
- if (_widgets[i]->isVisible() && _widgets[i]->isEnabled() && _widgets[i]->handleKeyDown(event)) {
- if (_beamCursor) {
- _beamCursorVisible = false;
- undrawBeamCursor();
- }
+ // Otherwise, give widgets a chance to react to key
+ // presses. All widgets get a chance, whether or not
+ // they are focused. This may be a bad idea if there
+ // is ever more than one edit text widget in the
+ // window.
+ //
+ // Typing hides the "beam" cursor.
+
+ for (uint i = 0; i < _widgets.size(); i++) {
+ if (_widgets[i]->isVisible() && _widgets[i]->isEnabled() && _widgets[i]->handleKeyDown(event)) {
+ if (_beamCursor) {
+ _beamCursorVisible = false;
+ undrawBeamCursor();
+ }
- if (_widgets[i]->shouldDeferAction())
- deferredActionIds.push_back(_widgets[i]->getId());
+ if (_widgets[i]->reactsToKeyDown())
+ queueEvent(_widgets[i], kDialogKeyDown);
- break;
- }
+ break;
}
+ }
- if (!deferredActionIds.empty())
- return kDialogWantsAttention;
-
- break;
+ break;
- default:
- break;
- }
+ default:
+ break;
}
+ }
- // A focused widget implies that the mouse button is being
- // held down. It must be active and visible, so it can receive
- // mouse repeat events, e.g. for holding down scroll buttons
- // on a slider widget.
+ // A focused widget implies that the mouse button is being held down.
+ // It must be active and visible, so it can receive mouse repeat
+ // events, e.g. for holding down scroll buttons on a slider widget.
- if (_focusedWidget && _system->getMillis() > nextMouseRepeat) {
- nextMouseRepeat = _system->getMillis() + 40;
- _focusedWidget->handleMouseHeld();
- }
+ if (_focusedWidget && _system->getMillis() > nextMouseRepeat) {
+ nextMouseRepeat = _system->getMillis() + 40;
+ _focusedWidget->handleMouseHeld();
+ }
- _system->delayMillis(10);
- update();
- _system->updateScreen();
+ for (uint i = 0; i < _widgets.size(); i++) {
+ if (_widgets[i]->valueHasChanged())
+ queueEvent(_widgets[i], kDialogValueChange);
}
- return kDialogQuit;
+ if (!_eventQueue.empty()) {
+ dialogEvent = _eventQueue.pop();
+ return true;
+ }
+
+ return false;
+}
+
+void MacGuiImpl::MacDialogWindow::delayAndUpdate() {
+ _system->delayMillis(10);
+ update();
+ _system->updateScreen();
}
void MacGuiImpl::MacDialogWindow::updateCursor() {
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index e2d5672e92c..7d619237efa 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -1112,27 +1112,36 @@ bool MacGuiImpl::runOpenDialog(int &saveSlotToHandle) {
window->setDefaultWidget(buttonOpen);
- // When quitting, the default action is to not open a saved game
- bool ret = false;
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ MacDialogEvent event;
- if (clicked == buttonOpen->getId() || clicked == listBox->getId()) {
- saveSlotToHandle =
- listBox->getValue() < ARRAYSIZE(slotIds) ?
- slotIds[listBox->getValue()] : -1;
- ret = true;
- break;
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonOpen || event.widget == listBox) {
+ saveSlotToHandle =
+ listBox->getValue() < ARRAYSIZE(slotIds) ?
+ slotIds[listBox->getValue()] : -1;
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
+
+ break;
+
+ default:
+ break;
+ }
}
- if (clicked == buttonCancel->getId())
- break;
+ window->delayAndUpdate();
}
+ // When quitting, do not load the saved game
delete window;
- return ret;
+ return false;
}
bool MacGuiImpl::runSaveDialog(int &saveSlotToHandle, Common::String &saveName) {
@@ -1183,36 +1192,43 @@ bool MacGuiImpl::runSaveDialog(int &saveSlotToHandle, Common::String &saveName)
window->setDefaultWidget(buttonSave);
editText->selectAll();
- // When quitting, the default action is to not open a saved game
- bool ret = false;
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ MacDialogEvent event;
- if (clicked == buttonSave->getId()) {
- ret = true;
- saveName = editText->getText();
- saveSlotToHandle = firstAvailableSlot;
- break;
- }
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonSave) {
+ saveName = editText->getText();
+ saveSlotToHandle = firstAvailableSlot;
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
- if (clicked == buttonCancel->getId())
- break;
+ break;
- if (clicked == kDialogWantsAttention) {
- // Cycle through deferred actions
- for (uint i = 0; i < deferredActionsIds.size(); i++) {
- if (deferredActionsIds[i] == editText->getId()) {
+ case kDialogKeyDown:
+ if (event.widget == editText) {
// Disable "Save" button when text is empty
buttonSave->setEnabled(!editText->getText().empty());
}
+
+ break;
+
+ default:
+ break;
}
}
+
+ window->delayAndUpdate();
}
+ // When quitting, do not save the game
delete window;
- return ret;
+ return false;
}
void MacGuiImpl::prepareSaveLoad(Common::StringArray &savegameNames, bool *availSlots, int *slotIds, int size) {
@@ -1259,25 +1275,31 @@ bool MacGuiImpl::runOkCancelDialog(Common::String text) {
window->setDefaultWidget(buttonOk);
window->addSubstitution(text);
- // When quitting, the default action is to quit
- bool ret = true;
-
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ MacDialogEvent event;
- if (clicked == buttonOk->getId())
- break;
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonOk) {
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
- if (clicked == buttonCancel->getId()) {
- ret = false;
- break;
+ default:
+ break;
+ }
}
+
+ window->delayAndUpdate();
}
+ // Quitting is the same as clicking Ok
delete window;
- return ret;
+ return true;
}
void MacGuiImpl::drawFakePathList(MacDialogWindow *window, Common::Rect r, const char *text) {
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 82cb0deaf73..cc86dfe2d42 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -35,11 +35,6 @@
#include "graphics/font.h"
#include "graphics/surface.h"
-// Use negative values for these. Zero and upwards are reserved for widget IDs.
-
-#define kDialogQuit -1
-#define kDialogWantsAttention -2
-
class OSystem;
namespace Graphics {
@@ -279,6 +274,7 @@ public:
bool _fullRedraw = false;
Common::String _text;
+ int _oldValue = 0;
int _value = 0;
int drawText(Common::String text, int x, int y, int w, uint32 fg = 0, uint32 bg = 0, Graphics::TextAlign align = Graphics::kTextAlignLeft, bool wordWrap = false, int deltax = 0) const;
@@ -308,11 +304,19 @@ public:
virtual void setValue(int value);
int getValue() const { return _value; }
+ void rememberValue() {
+ _oldValue = _value;
+ }
+
+ bool valueHasChanged() {
+ return _oldValue != _value;
+ }
+
Common::String getText() const;
virtual bool useBeamCursor() { return false; }
virtual bool findWidget(int x, int y) const;
- virtual bool shouldDeferAction() { return false; }
+ virtual bool reactsToKeyDown() { return false; }
virtual void draw(bool drawFocused = false) = 0;
@@ -433,7 +437,7 @@ public:
bool useBeamCursor() override { return true; }
bool findWidget(int x, int y) const override;
- bool shouldDeferAction() override { return true; }
+ bool reactsToKeyDown() override { return true; }
void draw(bool drawFocused = false) override;
@@ -649,8 +653,20 @@ public:
void handleMouseMove(Common::Event &event) override;
};
+ enum MacDialogEventType {
+ kDialogClick,
+ kDialogValueChange,
+ kDialogKeyDown
+ };
+
+ struct MacDialogEvent {
+ MacWidget *widget;
+ MacDialogEventType type;
+ };
+
class MacDialogWindow {
private:
+ Common::Queue<MacDialogEvent> _eventQueue;
uint32 _black;
uint32 _white;
@@ -695,6 +711,8 @@ public:
Common::Array<Common::Rect> _dirtyRects;
bool _dirtyPalette = false;
+ void queueEvent(MacGuiImpl::MacWidget *widget, MacGuiImpl::MacDialogEventType type);
+
void copyToScreen(Graphics::Surface *s = nullptr) const;
void addWidget(MacWidget *widget, MacWidgetType type);
@@ -712,7 +730,8 @@ public:
bool isVisible() const { return _visible; }
void show();
- int runDialog(Common::Array<int> &deferredActionIds);
+ bool runDialog(MacDialogEvent &dialogEvent);
+ void delayAndUpdate();
void updateCursor();
MacWidget *getWidget(MacWidgetType type, int nr = 0) const;
diff --git a/engines/scumm/macgui/macgui_indy3.cpp b/engines/scumm/macgui/macgui_indy3.cpp
index 37eb62a3fe2..424c0fa6d2a 100644
--- a/engines/scumm/macgui/macgui_indy3.cpp
+++ b/engines/scumm/macgui/macgui_indy3.cpp
@@ -1367,12 +1367,12 @@ bool MacIndy3Gui::runOpenDialog(int &saveSlotToHandle) {
MacDialogWindow *window = createDialog((_vm->_renderMode == Common::kRenderMacintoshBW) ? 4000 : 4001);
- MacButton *buttonSave = (MacButton *)window->getWidget(kWidgetButton, 0);
+ MacButton *buttonOpen = (MacButton *)window->getWidget(kWidgetButton, 0);
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 2);
MacButton *buttonEject = (MacButton *)window->getWidget(kWidgetButton, 3);
MacButton *buttonDrive = (MacButton *)window->getWidget(kWidgetButton, 4);
- window->setDefaultWidget(buttonSave);
+ window->setDefaultWidget(buttonOpen);
buttonEject->setEnabled(false);
buttonDrive->setEnabled(false);
@@ -1389,26 +1389,35 @@ bool MacIndy3Gui::runOpenDialog(int &saveSlotToHandle) {
drawFakePathList(window, Common::Rect(14, 18, 231, 37), "Indy Last Crusade");
drawFakeDriveLabel(window, Common::Rect(239, 41, 349, 61), "ScummVM");
- // When quitting, the default action is to not open a saved game
- bool ret = false;
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ MacDialogEvent event;
+
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonOpen || event.widget == listBox) {
+ saveSlotToHandle =
+ listBox->getValue() < ARRAYSIZE(slotIds) ? slotIds[listBox->getValue()] : -1;
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
- if (clicked == buttonSave->getId() || clicked == listBox->getId()) {
- ret = true;
- saveSlotToHandle =
- listBox->getValue() < ARRAYSIZE(slotIds) ? slotIds[listBox->getValue()] : -1;
- break;
+ break;
+
+ default:
+ break;
+ }
}
- if (clicked == buttonCancel->getId())
- break;
+ window->delayAndUpdate();
}
+ // When quitting, do not load the saved game
delete window;
- return ret;
+ return false;
}
bool MacIndy3Gui::runSaveDialog(int &saveSlotToHandle, Common::String &saveName) {
@@ -1462,36 +1471,43 @@ bool MacIndy3Gui::runSaveDialog(int &saveSlotToHandle, Common::String &saveName)
window->addListBox(Common::Rect(16, 31, 199, 129), savegameNames, true, true);
- // When quitting, the default action is not to save a game
- bool ret = false;
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
-
- if (clicked == buttonSave->getId()) {
- ret = true;
- saveName = editText->getText();
- saveSlotToHandle = firstAvailableSlot;
- break;
- }
+ MacDialogEvent event;
+
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonSave) {
+ saveName = editText->getText();
+ saveSlotToHandle = firstAvailableSlot;
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
- if (clicked == buttonCancel->getId())
- break;
+ break;
- if (clicked == kDialogWantsAttention) {
- // Cycle through deferred actions
- for (uint i = 0; i < deferredActionsIds.size(); i++) {
- if (deferredActionsIds[i] == editText->getId()) {
+ case kDialogKeyDown:
+ if (event.widget == editText) {
// Disable "Save" button when text is empty
buttonSave->setEnabled(!editText->getText().empty());
}
+
+ break;
+
+ default:
+ break;
}
}
+
+ window->delayAndUpdate();
}
+ // When quitting, do not save the game
delete window;
- return ret;
+ return false;
}
bool MacIndy3Gui::runOptionsDialog() {
@@ -1534,54 +1550,61 @@ bool MacIndy3Gui::runOptionsDialog() {
window->addSubstitution(Common::String::format("%d", _vm->VAR(_vm->VAR_MACHINE_SPEED)));
- // When quitting, the default action is not to not apply options
- bool ret = false;
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
-
- if (clicked == buttonOk->getId()) {
- ret = true;
- break;
- }
-
- if (clicked == buttonCancel->getId())
- break;
-
- if (clicked == checkboxSound->getId())
- checkboxMusic->setEnabled(checkboxSound->getValue() != 0);
- }
-
- if (ret) {
- // Update settings
-
- // TEXT SPEED
- _vm->_defaultTextSpeed = CLIP<int>(sliderTextSpeed->getValue(), 0, 9);
- ConfMan.setInt("original_gui_text_speed", _vm->_defaultTextSpeed);
- _vm->setTalkSpeed(_vm->_defaultTextSpeed);
+ MacDialogEvent event;
+
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonOk) {
+ // Update settings
+
+ // TEXT SPEED
+ _vm->_defaultTextSpeed = CLIP<int>(sliderTextSpeed->getValue(), 0, 9);
+ ConfMan.setInt("original_gui_text_speed", _vm->_defaultTextSpeed);
+ _vm->setTalkSpeed(_vm->_defaultTextSpeed);
+
+ // SOUND&MUSIC ACTIVATION
+ // 0 - Sound&Music on
+ // 1 - Sound on, music off
+ // 2 - Sound&Music off
+ bool disableSound = checkboxSound->getValue() == 0;
+ bool disableMusic = checkboxMusic->getValue() == 0;
+
+ _vm->_musicEngine->toggleMusic(!disableMusic);
+ _vm->_musicEngine->toggleSoundEffects(!disableSound);
+ ConfMan.setBool("music_mute", disableMusic);
+ ConfMan.setBool("mute", disableSound);
+ ConfMan.flushToDisk();
+
+ _vm->syncSoundSettings();
+
+ // SCROLLING ACTIVATION
+ _vm->_snapScroll = checkboxScrolling->getValue() == 0;
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
- // SOUND&MUSIC ACTIVATION
- // 0 - Sound&Music on
- // 1 - Sound on, music off
- // 2 - Sound&Music off
- bool disableSound = checkboxSound->getValue() == 0;
- bool disableMusic = checkboxMusic->getValue() == 0;
+ break;
- _vm->_musicEngine->toggleMusic(!disableMusic);
- _vm->_musicEngine->toggleSoundEffects(!disableSound);
- ConfMan.setBool("music_mute", disableMusic);
- ConfMan.setBool("mute", disableSound);
- ConfMan.flushToDisk();
+ case kDialogValueChange:
+ if (event.widget == checkboxSound)
+ checkboxMusic->setEnabled(checkboxSound->getValue() != 0);
+ break;
- _vm->syncSoundSettings();
+ default:
+ break;
+ }
+ }
- // SCROLLING ACTIVATION
- _vm->_snapScroll = checkboxScrolling->getValue() == 0;
+ window->delayAndUpdate();
}
delete window;
- return ret;
+ return false;
}
bool MacIndy3Gui::runIqPointsDialog() {
@@ -1596,8 +1619,8 @@ bool MacIndy3Gui::runIqPointsDialog() {
MacDialogWindow *window = createDialog((_vm->_renderMode == Common::kRenderMacintoshBW) ? 1001 : 1002);
- MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
- MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
+ MacButton *buttonDone = (MacButton *)window->getWidget(kWidgetButton, 0);
+ MacButton *buttonReset = (MacButton *)window->getWidget(kWidgetButton, 1);
MacStaticText *textSeriesIQ = (MacStaticText *)window->getWidget(kWidgetStaticText, 2);
@@ -1605,21 +1628,31 @@ bool MacIndy3Gui::runIqPointsDialog() {
window->addSubstitution(Common::String::format("%d", _vm->VAR(244)));
window->addSubstitution(Common::String::format("%d", _vm->VAR(245)));
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ MacDialogEvent event;
+
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonDone) {
+ delete window;
+ return true;
+ } else if (event.widget == buttonReset) {
+ if (!_vm->enhancementEnabled(kEnhUIUX) || runOkCancelDialog("Are you sure you want to reset the series IQ score?")) {
+ ((ScummEngine_v4 *)_vm)->clearSeriesIQPoints();
+ window->replaceSubstitution(1, Common::String::format("%d", _vm->VAR(245)));
+ textSeriesIQ->setRedraw(true);
+ }
+ }
- if (clicked == buttonOk->getId())
- break;
+ break;
- if (clicked == buttonCancel->getId()) {
- if (!_vm->enhancementEnabled(kEnhUIUX) || runOkCancelDialog("Are you sure you want to reset the series IQ score?")) {
- ((ScummEngine_v4 *)_vm)->clearSeriesIQPoints();
- window->replaceSubstitution(1, Common::String::format("%d", _vm->VAR(245)));
- textSeriesIQ->setRedraw(true);
+ default:
+ break;
}
}
+
+ window->delayAndUpdate();
}
delete window;
diff --git a/engines/scumm/macgui/macgui_loom.cpp b/engines/scumm/macgui/macgui_loom.cpp
index 1089405beac..95e7cc81d1d 100644
--- a/engines/scumm/macgui/macgui_loom.cpp
+++ b/engines/scumm/macgui/macgui_loom.cpp
@@ -539,69 +539,76 @@ bool MacLoomGui::runOptionsDialog() {
// Machine rating
window->addSubstitution(Common::String::format("%d", _vm->VAR(53)));
- // When quitting, the default action is not to not apply options
- bool ret = false;
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
-
- if (clicked == buttonOk->getId()) {
- ret = true;
- break;
- }
-
- if (clicked == buttonCancel->getId())
- break;
-
- if (clicked == checkboxSound->getId())
- checkboxMusic->setEnabled(checkboxSound->getValue() != 0);
- }
-
- if (ret) {
- // Update settings
-
- // TEXT SPEED
- _vm->_defaultTextSpeed = CLIP<int>(sliderTextSpeed->getValue(), 0, 9);
- ConfMan.setInt("original_gui_text_speed", _vm->_defaultTextSpeed);
- _vm->setTalkSpeed(_vm->_defaultTextSpeed);
-
- // SOUND&MUSIC ACTIVATION
- // 0 - Sound&Music on
- // 1 - Sound on, music off
- // 2 - Sound&Music off
- int musicVariableValue = 0;
-
- if (checkboxSound->getValue() == 0)
- musicVariableValue = 2;
- else if (checkboxSound->getValue() == 1 && checkboxMusic->getValue() == 0)
- musicVariableValue = 1;
+ MacDialogEvent event;
- _vm->_musicEngine->toggleMusic(musicVariableValue == 0);
- _vm->_musicEngine->toggleSoundEffects(musicVariableValue < 2);
- ConfMan.setBool("music_mute", musicVariableValue > 0);
- ConfMan.setBool("mute", musicVariableValue == 2);
-
- // SCROLLING ACTIVATION
- _vm->_snapScroll = checkboxScrolling->getValue() == 0;
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonOk) {
+ // TEXT SPEED
+ _vm->_defaultTextSpeed = CLIP<int>(sliderTextSpeed->getValue(), 0, 9);
+ ConfMan.setInt("original_gui_text_speed", _vm->_defaultTextSpeed);
+ _vm->setTalkSpeed(_vm->_defaultTextSpeed);
+
+ // SOUND&MUSIC ACTIVATION
+ // 0 - Sound&Music on
+ // 1 - Sound on, music off
+ // 2 - Sound&Music off
+ int musicVariableValue = 0;
+
+ if (checkboxSound->getValue() == 0)
+ musicVariableValue = 2;
+ else if (checkboxSound->getValue() == 1 && checkboxMusic->getValue() == 0)
+ musicVariableValue = 1;
+
+ _vm->_musicEngine->toggleMusic(musicVariableValue == 0);
+ _vm->_musicEngine->toggleSoundEffects(musicVariableValue < 2);
+ ConfMan.setBool("music_mute", musicVariableValue > 0);
+ ConfMan.setBool("mute", musicVariableValue == 2);
+
+ // SCROLLING ACTIVATION
+ _vm->_snapScroll = checkboxScrolling->getValue() == 0;
+
+ if (_vm->VAR_CAMERA_FAST_X != 0xFF)
+ _vm->VAR(_vm->VAR_CAMERA_FAST_X) = _vm->_snapScroll;
+
+ // FULL ANIMATION ACTIVATION
+ _vm->VAR(_vm->VAR_MACHINE_SPEED) = checkboxFullAnimation->getValue() == 1 ? 0 : 1;
+
+ // MUSIC QUALITY SELECTOR
+ musicQuality = musicQuality * 3 + 1 + sliderMusicQuality->getValue();
+ _vm->_musicEngine->setQuality(musicQuality);
+ ConfMan.setInt("mac_snd_quality", musicQuality);
+
+ _vm->syncSoundSettings();
+ ConfMan.flushToDisk();
+
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
- if (_vm->VAR_CAMERA_FAST_X != 0xFF)
- _vm->VAR(_vm->VAR_CAMERA_FAST_X) = _vm->_snapScroll;
+ break;
- // FULL ANIMATION ACTIVATION
- _vm->VAR(_vm->VAR_MACHINE_SPEED) = checkboxFullAnimation->getValue() == 1 ? 0 : 1;
+ case kDialogValueChange:
+ if (event.widget == checkboxSound) {
+ checkboxMusic->setEnabled(checkboxSound->getValue() != 0);
+ }
+ break;
- // MUSIC QUALITY SELECTOR
- musicQuality = musicQuality * 3 + 1 + sliderMusicQuality->getValue();
- _vm->_musicEngine->setQuality(musicQuality);
- ConfMan.setInt("mac_snd_quality", musicQuality);
+ default:
+ break;
+ }
+ }
- _vm->syncSoundSettings();
- ConfMan.flushToDisk();
+ window->delayAndUpdate();
}
delete window;
- return ret;
+ return false;
}
void MacLoomGui::resetAfterLoad() {
diff --git a/engines/scumm/macgui/macgui_v5.cpp b/engines/scumm/macgui/macgui_v5.cpp
index 6c7c20d3d9f..4956b51ebca 100644
--- a/engines/scumm/macgui/macgui_v5.cpp
+++ b/engines/scumm/macgui/macgui_v5.cpp
@@ -989,56 +989,63 @@ bool MacV5Gui::runOptionsDialog() {
sliderTextSpeed->setValue(textSpeed);
sliderMusicQuality->setValue(musicQualityOption);
- // When quitting, the default action is not to not apply options
- bool ret = false;
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
-
- if (clicked == buttonOk->getId()) {
- ret = true;
- break;
- }
-
- if (clicked == buttonCancel->getId())
- break;
-
- if (clicked == checkboxSound->getId() && checkboxMusic)
- checkboxMusic->setEnabled(checkboxSound->getValue() != 0);
- }
-
- if (ret) {
- // Update settings
-
- // TEXT SPEED
- _vm->_defaultTextSpeed = CLIP<int>(sliderTextSpeed->getValue(), 0, 9);
- ConfMan.setInt("original_gui_text_speed", _vm->_defaultTextSpeed);
- _vm->setTalkSpeed(_vm->_defaultTextSpeed);
-
- // SOUND&MUSIC ACTIVATION
- sound = checkboxSound->getValue();
- music = checkboxMusic ? checkboxMusic->getValue() : sound;
+ MacDialogEvent event;
+
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonOk) {
+ // TEXT SPEED
+ _vm->_defaultTextSpeed = CLIP<int>(sliderTextSpeed->getValue(), 0, 9);
+ ConfMan.setInt("original_gui_text_speed", _vm->_defaultTextSpeed);
+ _vm->setTalkSpeed(_vm->_defaultTextSpeed);
+
+ // SOUND&MUSIC ACTIVATION
+ sound = checkboxSound->getValue();
+ music = checkboxMusic ? checkboxMusic->getValue() : sound;
+
+ if (!sound)
+ music = false;
+
+ _vm->_musicEngine->toggleMusic(music);
+ _vm->_musicEngine->toggleSoundEffects(sound);
+ ConfMan.setBool("music_mute", !music);
+ ConfMan.setBool("mute", !sound);
+
+ // MUSIC QUALITY SELECTOR
+ musicQuality = musicQuality * 3 + 1 + sliderMusicQuality->getValue();
+ _vm->_musicEngine->setQuality(musicQuality);
+ ConfMan.setInt("mac_snd_quality", musicQuality);
+
+ _vm->syncSoundSettings();
+ ConfMan.flushToDisk();
+
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
- if (!sound)
- music = false;
+ break;
- _vm->_musicEngine->toggleMusic(music);
- _vm->_musicEngine->toggleSoundEffects(sound);
- ConfMan.setBool("music_mute", !music);
- ConfMan.setBool("mute", !sound);
+ case kDialogValueChange:
+ if (event.widget == checkboxSound && checkboxMusic) {
+ checkboxMusic->setEnabled(checkboxSound->getValue() != 0);
+ }
+ break;
- // MUSIC QUALITY SELECTOR
- musicQuality = musicQuality * 3 + 1 + sliderMusicQuality->getValue();
- _vm->_musicEngine->setQuality(musicQuality);
- ConfMan.setInt("mac_snd_quality", musicQuality);
+ default:
+ break;
+ }
+ }
- _vm->syncSoundSettings();
- ConfMan.flushToDisk();
+ window->delayAndUpdate();
}
delete window;
- return ret;
+ return false;
}
void MacV5Gui::resetAfterLoad() {
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 26615282e22..e31408edbb3 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -402,13 +402,24 @@ void MacV6Gui::runAboutDialog() {
window->setDefaultWidget(buttonOk);
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ MacDialogEvent event;
+
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonOk) {
+ delete window;
+ return;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
- if (clicked == buttonOk->getId())
- break;
+ window->delayAndUpdate();
}
delete window;
@@ -546,26 +557,35 @@ bool MacV6Gui::runOpenDialog(int &saveSlotToHandle) {
window->innerSurface()->frameRect(Common::Rect(11, 31, 173, 133), getBlack());
}
- // When quitting, the default action is to not open a saved game
- bool ret = false;
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ MacDialogEvent event;
- if (clicked == buttonSave->getId() || clicked == listBox->getId()) {
- ret = true;
- saveSlotToHandle =
- listBox->getValue() < ARRAYSIZE(slotIds) ? slotIds[listBox->getValue()] : -1;
- break;
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonSave || event.widget == listBox) {
+ saveSlotToHandle =
+ listBox->getValue() < ARRAYSIZE(slotIds) ? slotIds[listBox->getValue()] : -1;
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
+
+ break;
+
+ default:
+ break;
+ }
}
- if (clicked == buttonCancel->getId())
- break;
+ window->delayAndUpdate();
}
+ // When quitting, do not load the saved game
delete window;
- return ret;
+ return false;
}
bool MacV6Gui::runSaveDialog(int &saveSlotToHandle, Common::String &saveName) {
@@ -615,36 +635,41 @@ bool MacV6Gui::runSaveDialog(int &saveSlotToHandle, Common::String &saveName) {
window->addListBox(Common::Rect(14, 31, 232, 129), savegameNames, true, true);
- // When quitting, the default action is not to save a game
- bool ret = false;
- Common::Array<int> deferredActionsIds;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ MacDialogEvent event;
- if (clicked == buttonSave->getId()) {
- ret = true;
- saveName = editText->getText();
- saveSlotToHandle = firstAvailableSlot;
- break;
- }
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonSave) {
+ saveName = editText->getText();
+ saveSlotToHandle = firstAvailableSlot;
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
- if (clicked == buttonCancel->getId())
- break;
+ break;
- if (clicked == kDialogWantsAttention) {
- // Cycle through deferred actions
- for (uint i = 0; i < deferredActionsIds.size(); i++) {
- if (deferredActionsIds[i] == editText->getId()) {
- // Disable "Save" button when text is empty
+ case kDialogValueChange:
+ if (event.widget == editText) {
buttonSave->setEnabled(!editText->getText().empty());
}
+ break;
+
+ default:
+ break;
}
}
+
+ window->delayAndUpdate();
}
+ // When quitting, do not save the game
delete window;
- return ret;
+ return false;
}
bool MacV6Gui::runOptionsDialog() {
@@ -660,7 +685,7 @@ bool MacV6Gui::runOptionsDialog() {
MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
- // MacButton *buttonDefaults = (MacButton *)window->getWidget(kWidgetButton, 2);
+ MacButton *buttonDefaults = (MacButton *)window->getWidget(kWidgetButton, 2);
MacPopUpMenu *interactionPopUp = nullptr;
MacPopUpMenu *videoQualityPopUp = nullptr;
@@ -721,29 +746,33 @@ bool MacV6Gui::runOptionsDialog() {
addSlider(window, 152, 231, 147, 9);
}
- Common::Array<int> deferredActionsIds;
+ while (!_vm->shouldQuit()) {
+ MacDialogEvent event;
- // When quitting, the default action is not to not apply options
- bool ret = false;
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonOk) {
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ } else if (event.widget == buttonDefaults) {
+ }
- while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ break;
- if (clicked == buttonOk->getId()) {
- ret = true;
- break;
+ default:
+ break;
+ }
}
- if (clicked == buttonCancel->getId())
- break;
- }
-
- if (ret) {
- // Update settings
+ window->delayAndUpdate();
}
delete window;
- return ret;
+ return false;
}
bool MacV6Gui::runQuitDialog() {
@@ -758,25 +787,33 @@ bool MacV6Gui::runQuitDialog() {
window->setDefaultWidget(buttonOk);
- Common::Array<int> deferredActionsIds;
-
- // When quitting, the default action is to quit
- bool ret = true;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ MacDialogEvent event;
- if (clicked == buttonOk->getId())
- break;
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonOk) {
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
- if (clicked == buttonCancel->getId()) {
- ret = false;
- break;
+ break;
+
+ default:
+ break;
+ }
}
+
+ window->delayAndUpdate();
}
+ // When quitting, quit
delete window;
- return ret;
+ return true;
}
bool MacV6Gui::runRestartDialog() {
@@ -796,25 +833,33 @@ bool MacV6Gui::runRestartDialog() {
window->addSubstitution("");
window->addSubstitution(_gameName);
- Common::Array<int> deferredActionsIds;
-
- // When quitting, the default action is to quit
- bool ret = true;
-
while (!_vm->shouldQuit()) {
- int clicked = window->runDialog(deferredActionsIds);
+ MacDialogEvent event;
- if (clicked == buttonOk->getId())
- break;
+ while (window->runDialog(event)) {
+ switch (event.type) {
+ case kDialogClick:
+ if (event.widget == buttonOk) {
+ delete window;
+ return true;
+ } else if (event.widget == buttonCancel) {
+ delete window;
+ return false;
+ }
- if (clicked == buttonCancel->getId()) {
- ret = false;
- break;
+ break;
+
+ default:
+ break;
+ }
}
+
+ window->delayAndUpdate();
}
+ // When quitting, do not restart
delete window;
- return ret;
+ return false;
}
void MacV6Gui::resetAfterLoad() {
Commit: e199e1c9e599ed8dae589088550b3dec98dd2007
https://github.com/scummvm/scummvm/commit/e199e1c9e599ed8dae589088550b3dec98dd2007
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add thumbnail support to V6-7 open dialog. Kind of.
I mean, the color quantization is so broken it's not even funny, but it
is updating the thumbnail when the selection changes, and that's a
direct result of yesterday's dialog event loop restructuring. So I count
this as a win. Let's commit it before I break anything even worse.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 7d619237efa..cec117203f7 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -961,11 +961,6 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect
palette.set(k._value, r, g, b);
}
- for (int i = 0; i < 256; i++) {
- byte r, g, b;
- palette.get(i, r, g, b);
- }
-
_windowManager->passPalette(palette.data(), 256);
for (int i = 0; i < 256; i++) {
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index e31408edbb3..93c6a0218b3 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -24,6 +24,8 @@
#include "common/macresman.h"
#include "engines/engine.h"
+#include "engines/metaengine.h"
+#include "engines/savestate.h"
#include "graphics/palette.h"
#include "graphics/paletteman.h"
@@ -508,6 +510,64 @@ void MacV6Gui::runAboutDialog() {
token.clear();
}
+void MacV6Gui::updateThumbnail(MacDialogWindow *window, Common::Rect thumbnailRect, int saveSlot) {
+ if (_vm->_game.id == GID_MANIAC)
+ return;
+
+ if (saveSlot < 0)
+ return;
+
+ SaveStateDescriptor desc = _vm->getMetaEngine()->querySaveMetaInfos(_vm->_targetName.c_str(), saveSlot);
+
+ const Graphics::Surface *thumbnail = desc.getThumbnail();
+ Graphics::Surface drawArea = window->innerSurface()->getSubArea(thumbnailRect);
+
+ Common::HashMap<uint32, byte> paletteMap;
+
+ int diff = thumbnail->h - thumbnailRect.height();
+
+ int yMin = diff / 2;
+ int yMax = thumbnail->h - (diff / 2);
+
+ assert(thumbnailRect.width() == thumbnail->w);
+ assert(thumbnailRect.height() == yMax - yMin);
+
+ // We don't know in advance how many colors the thumbnail is going to
+ // use. Reduce the image to a smaller palette.
+ //
+ // FIXME: THIS IS SO BROKEN IT'S NOT EVEN FUNNY!
+
+ int numColors = 0;
+
+ for (int y = yMin; y < yMax; y++) {
+ for (int x = 0; x < thumbnail->w; x++) {
+ uint32 color = thumbnail->getPixel(x, y) & 0xC0E0C0;
+
+ if (!paletteMap.contains(color))
+ paletteMap[color] = numColors++;
+ }
+ }
+
+ Graphics::Palette palette(numColors);
+
+ for (auto &k : paletteMap) {
+ int r = (k._key >> 16) & 0xFF;
+ int g = (k._key >> 8) & 0xFF;
+ int b = k._key & 0xFF;
+ palette.set(k._value, r, g, b);
+ }
+
+ for (int y = 0; y < drawArea.h; y++) {
+ for (int x = 0; x < drawArea.w; x++) {
+ byte color = paletteMap[thumbnail->getPixel(x, y + yMin) & 0xC0E0C0];
+ drawArea.setPixel(x, y, color);
+ }
+ }
+
+ _system->getPaletteManager()->setPalette(palette);
+ window->markRectAsDirty(thumbnailRect);
+}
+
bool MacV6Gui::runOpenDialog(int &saveSlotToHandle) {
// Widgets:
//
@@ -534,7 +594,6 @@ bool MacV6Gui::runOpenDialog(int &saveSlotToHandle) {
MacButton *buttonEject = (MacButton *)window->getWidget(kWidgetButton, 2);
MacButton *buttonDesktop = (MacButton *)window->getWidget(kWidgetButton, 3);
-
window->setDefaultWidget(buttonSave);
buttonEject->setEnabled(false);
buttonDesktop->setEnabled(false);
@@ -544,6 +603,8 @@ bool MacV6Gui::runOpenDialog(int &saveSlotToHandle) {
Common::StringArray savegameNames;
prepareSaveLoad(savegameNames, availSlots, slotIds, ARRAYSIZE(availSlots));
+ Common::Rect thumbnailRect(12, 32, 172, 132);
+
MacListBox *listBox;
if (_vm->_game.id == GID_MANIAC) {
@@ -554,9 +615,12 @@ bool MacV6Gui::runOpenDialog(int &saveSlotToHandle) {
listBox = window->addListBox(Common::Rect(184, 31, 402, 161), savegameNames, true);
drawFakePathList(window, Common::Rect(184, 8, 402, 27), _gameName.c_str());
drawFakeDriveLabel(window, Common::Rect(412, 10, 509, 26), "ScummVM");
- window->innerSurface()->frameRect(Common::Rect(11, 31, 173, 133), getBlack());
+ window->innerSurface()->frameRect(Common::Rect(thumbnailRect.left - 1, thumbnailRect.top - 1, thumbnailRect.right + 1, thumbnailRect.bottom + 1), getBlack());
}
+ int saveSlot = listBox->getValue() < ARRAYSIZE(slotIds) ? slotIds[listBox->getValue()] : -1;
+ updateThumbnail(window, thumbnailRect, saveSlot);
+
while (!_vm->shouldQuit()) {
MacDialogEvent event;
@@ -575,6 +639,13 @@ bool MacV6Gui::runOpenDialog(int &saveSlotToHandle) {
break;
+ case kDialogValueChange:
+ if (event.widget == listBox) {
+ saveSlot = listBox->getValue() < ARRAYSIZE(slotIds) ? slotIds[listBox->getValue()] : -1;
+ updateThumbnail(window, thumbnailRect, saveSlot);
+ }
+ break;
+
default:
break;
}
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 198482af448..248f4e5faee 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -61,6 +61,8 @@ public:
void resetAfterLoad() override;
void update(int delta) override {}
+ void updateThumbnail(MacDialogWindow *window, Common::Rect thimbnailRect, int saveSlot);
+
protected:
bool getFontParams(FontId fontId, int &id, int &size, int &slant) const override;
Commit: 8c86e4547cb0b6280dd71bd47b09eadab2a7255f
https://github.com/scummvm/scummvm/commit/8c86e4547cb0b6280dd71bd47b09eadab2a7255f
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix thumbnail color quantization a bit
It's still very bad. We could do better.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 93c6a0218b3..3c48f8eb902 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -535,13 +535,19 @@ void MacV6Gui::updateThumbnail(MacDialogWindow *window, Common::Rect thumbnailRe
// We don't know in advance how many colors the thumbnail is going to
// use. Reduce the image to a smaller palette.
//
- // FIXME: THIS IS SO BROKEN IT'S NOT EVEN FUNNY!
+ // FIXME: This is a very stupid method. We should be able to do a lot
+ // better than this.
int numColors = 0;
for (int y = yMin; y < yMax; y++) {
for (int x = 0; x < thumbnail->w; x++) {
- uint32 color = thumbnail->getPixel(x, y) & 0xC0E0C0;
+ uint32 color = thumbnail->getPixel(x, y);
+
+ byte r, g, b;
+ thumbnail->format.colorToRGB(color, r, g, b);
+
+ color = ((r << 16) | (g << 8) | b) & 0xC0E0C0;
if (!paletteMap.contains(color))
paletteMap[color] = numColors++;
@@ -559,8 +565,13 @@ void MacV6Gui::updateThumbnail(MacDialogWindow *window, Common::Rect thumbnailRe
for (int y = 0; y < drawArea.h; y++) {
for (int x = 0; x < drawArea.w; x++) {
- byte color = paletteMap[thumbnail->getPixel(x, y + yMin) & 0xC0E0C0];
- drawArea.setPixel(x, y, color);
+ uint32 color = thumbnail->getPixel(x, y + yMin);
+ byte r, g, b;
+ thumbnail->format.colorToRGB(color, r, g, b);
+
+ color = ((r << 16) | (g << 8) | b) & 0xC0E0C0;
+
+ drawArea.setPixel(x, y, paletteMap[color]);
}
}
Commit: 76f9ea673f0bae8b65c1cc10662181176a203d3d
https://github.com/scummvm/scummvm/commit/76f9ea673f0bae8b65c1cc10662181176a203d3d
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix palette glitch
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index e3344594c63..aa1dc7ae193 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -136,7 +136,7 @@ MacGuiImpl::MacDialogWindow::MacDialogWindow(MacGuiImpl *gui, OSystem *system, G
uint32 macBlack = _gui->_macBlack;
if (macWhite != _white || macBlack != _black) {
- for (int y = 0; y < 19; y++) {
+ for (int y = 0; y < 20; y++) {
for (int x = 0; x < realScreen->w; x++) {
uint32 color = realScreen->getPixel(x, y);
if (color == macWhite)
Commit: 84f4010ebadaf7c522506363a87f1f43e7086a51
https://github.com/scummvm/scummvm/commit/84f4010ebadaf7c522506363a87f1f43e7086a51
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Slightly better color quantization for v6-7 thumbnails
I'm not going to go with any clever algorithm to get representative
colors, I'm just going to go with the 246 most common ones. (The
remaining 10 are reserved for the Mac GUI.)
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 3c48f8eb902..7e9216e1771 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -510,7 +510,19 @@ void MacV6Gui::runAboutDialog() {
token.clear();
}
-void MacV6Gui::updateThumbnail(MacDialogWindow *window, Common::Rect thumbnailRect, int saveSlot) {
+struct colorInfo {
+ uint32 color;
+ uint16 count;
+};
+
+static int compareColorInfo(const void *p1, const void *p2) {
+ int c1 = ((const colorInfo *)p1)->count;
+ int c2 = ((const colorInfo *)p2)->count;
+
+ return c2 - c1;
+}
+
+void MacV6Gui::updateThumbnail(MacDialogWindow *window, Common::Rect drawArea, int saveSlot) {
if (_vm->_game.id == GID_MANIAC)
return;
@@ -520,25 +532,30 @@ void MacV6Gui::updateThumbnail(MacDialogWindow *window, Common::Rect thumbnailRe
SaveStateDescriptor desc = _vm->getMetaEngine()->querySaveMetaInfos(_vm->_targetName.c_str(), saveSlot);
const Graphics::Surface *thumbnail = desc.getThumbnail();
- Graphics::Surface drawArea = window->innerSurface()->getSubArea(thumbnailRect);
- Common::HashMap<uint32, byte> paletteMap;
+ Common::HashMap<uint32, uint16> paletteMap;
- int diff = thumbnail->h - thumbnailRect.height();
+ int diff = thumbnail->h - drawArea.height();
int yMin = diff / 2;
int yMax = thumbnail->h - (diff / 2);
- assert(thumbnailRect.width() == thumbnail->w);
- assert(thumbnailRect.height() == yMax - yMin);
+ assert(drawArea.width() == thumbnail->w);
+ assert(drawArea.height() == yMax - yMin);
+
+ Common::Rect thumbnailRect(0, yMin, drawArea.width(), yMax);
// We don't know in advance how many colors the thumbnail is going to
// use. Reduce the image to a smaller palette.
//
- // FIXME: This is a very stupid method. We should be able to do a lot
- // better than this.
-
- int numColors = 0;
+ // I'm not going to do any fancy color quantization here. Maybe if one
+ // is added to the ScummVM common code, but not just for this.
+ //
+ // The thumbnail is asserted to be 160x100 pixels. We know it started
+ // out with at most 256 colors, and that any further colors were added
+ // when scaling it down, and are presumably close to the original ones.
+ // Even in the most pathological case, there will never be more than
+ // 16,000 distinct colors.
for (int y = yMin; y < yMax; y++) {
for (int x = 0; x < thumbnail->w; x++) {
@@ -547,36 +564,49 @@ void MacV6Gui::updateThumbnail(MacDialogWindow *window, Common::Rect thumbnailRe
byte r, g, b;
thumbnail->format.colorToRGB(color, r, g, b);
- color = ((r << 16) | (g << 8) | b) & 0xC0E0C0;
+ // If the color wasn't 565 before, make it so
+ color = ((r << 16) | (g << 8) | b) & 0xF8FCF8;
- if (!paletteMap.contains(color))
- paletteMap[color] = numColors++;
+ paletteMap[color]++;
}
}
- Graphics::Palette palette(numColors);
+ colorInfo *colors = new colorInfo[paletteMap.size()];
+ int count = 0;
for (auto &k : paletteMap) {
- int r = (k._key >> 16) & 0xFF;
- int g = (k._key >> 8) & 0xFF;
- int b = k._key & 0xFF;
- palette.set(k._value, r, g, b);
+ colors[count].color = k._key;
+ colors[count].count = k._value;
+ count++;
}
- for (int y = 0; y < drawArea.h; y++) {
- for (int x = 0; x < drawArea.w; x++) {
- uint32 color = thumbnail->getPixel(x, y + yMin);
- byte r, g, b;
- thumbnail->format.colorToRGB(color, r, g, b);
+ qsort(colors, count, sizeof(colorInfo), compareColorInfo);
- color = ((r << 16) | (g << 8) | b) & 0xC0E0C0;
+ // Pick the - at most - 246 most popular colors. Note that we do not
+ // gamma correct them. They presumably already were when the thumbnail
+ // was created.
- drawArea.setPixel(x, y, paletteMap[color]);
- }
+ int numColors = MIN(count, 246);
+ Graphics::Palette palette(numColors);
+
+ for (int i = 0; i < numColors; i++) {
+ int r = ((colors[i].color) >> 16) & 0xFF;
+ int g = ((colors[i].color) >> 8) & 0xFF;
+ int b = (colors[i].color) & 0xFF;
+
+ palette.set(i, r, g, b);
}
+ delete[] colors;
_system->getPaletteManager()->setPalette(palette);
- window->markRectAsDirty(thumbnailRect);
+
+ Graphics::Surface *palettedThumbnail = thumbnail->convertTo(window->innerSurface()->format, nullptr, 0, palette.data(), palette.size());
+
+ window->innerSurface()->copyRectToSurface(*palettedThumbnail, drawArea.left, drawArea.top, thumbnailRect);
+ window->markRectAsDirty(drawArea);
+
+ palettedThumbnail->free();
+ delete palettedThumbnail;
}
bool MacV6Gui::runOpenDialog(int &saveSlotToHandle) {
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 248f4e5faee..712c0efed82 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -61,7 +61,7 @@ public:
void resetAfterLoad() override;
void update(int delta) override {}
- void updateThumbnail(MacDialogWindow *window, Common::Rect thimbnailRect, int saveSlot);
+ void updateThumbnail(MacDialogWindow *window, Common::Rect drawArea, int saveSlot);
protected:
bool getFontParams(FontId fontId, int &id, int &size, int &slant) const override;
Commit: 4ac5ae532c1f344bd9e00a161334a16670668a00
https://github.com/scummvm/scummvm/commit/4ac5ae532c1f344bd9e00a161334a16670668a00
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Minor cleanup
Changed paths:
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 59710b176ae..2eb2a3820bc 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -1657,15 +1657,13 @@ bool MacGuiImpl::MacListBox::handleKeyDown(Common::Event &event) {
}
// ---------------------------------------------------------------------------
-// Drop down widget
+// Pop-up menu widget
// ---------------------------------------------------------------------------
MacGuiImpl::MacPopUpMenu::MacPopUpMenu(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Common::String text, int textWidth, Common::StringArray texts, bool enabled) : MacWidget(window, bounds, text, enabled), _textWidth(textWidth), _texts(texts) {
_black = _window->_gui->getBlack();
_white = _window->_gui->getWhite();
- _bounds.bottom--;
-
_popUpBounds.left = _bounds.left + _textWidth;
_popUpBounds.right = _bounds.right;
}
@@ -1710,7 +1708,7 @@ void MacGuiImpl::MacPopUpMenu::draw(bool drawFocused) {
Graphics::Surface *s = _window->innerSurface();
const Graphics::Font *font = _window->_gui->getFont(kSystemFont);
- s->fillRect(Common::Rect(_bounds.left, _bounds.top + 1, _bounds.left + _textWidth, _bounds.bottom - 2), bg);
+ s->fillRect(Common::Rect(_bounds.left, _bounds.top + 1, _bounds.left + _textWidth, _bounds.bottom - 3), bg);
font->drawString(s, _text, _bounds.left, _bounds.top + 1, _textWidth, fg, Graphics::kTextAlignLeft, 4);
if (focused) {
@@ -1744,7 +1742,7 @@ void MacGuiImpl::MacPopUpMenu::draw(bool drawFocused) {
textRect.translate(0, 16);
}
} else {
- Common::Rect r(_bounds.left + _textWidth, _bounds.top, _bounds.right - 1, _bounds.bottom - 1);
+ Common::Rect r(_bounds.left + _textWidth, _bounds.top, _bounds.right - 1, _bounds.bottom - 2);
s->fillRect(r, _white);
s->frameRect(r, _black);
@@ -1779,7 +1777,7 @@ void MacGuiImpl::MacPopUpMenu::draw(bool drawFocused) {
void MacGuiImpl::MacPopUpMenu::handleMouseDown(Common::Event &event) {
_popUpBounds.top = _bounds.top - 16 * _value;
- _popUpBounds.bottom = _bounds.bottom + 16 * (_texts.size() - _value - 1);
+ _popUpBounds.bottom = _bounds.bottom - 1 + 16 * (_texts.size() - _value - 1);
Graphics::Surface background = _window->innerSurface()->getSubArea(_popUpBounds);
Commit: e3f693792861e8b5940b25e273d3c039e879822f
https://github.com/scummvm/scummvm/commit/e3f693792861e8b5940b25e273d3c039e879822f
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix regression from using String's Pascal string reader
It converted \r into \n which broke the code that checks if the text
includes line breaks. This broken the About dialogs for the v6-7
Macintosh demos.
Changed paths:
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 2eb2a3820bc..babfe6171d6 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -114,14 +114,14 @@ int MacGuiImpl::MacWidget::drawText(Common::String text, int x, int y, int w, ui
if (wordWrap) {
maxLineWidth = font->wordWrapText(text, w, lines);
} else {
- if (text.contains('\r')) {
+ if (text.contains('\n')) {
Common::String line = "";
for (uint i = 0; i < text.size(); i++) {
- if (text[i] != '\r')
+ if (text[i] != '\n')
line += text[i];
- if (text[i] == '\r' || i == text.size() - 1) {
+ if (text[i] == '\n' || i == text.size() - 1) {
int lineWidth = font->getStringWidth(line);
if (lineWidth > maxLineWidth)
maxLineWidth = lineWidth;
Commit: 2e6b5d67784995534843cf436486ade61b28a5f2
https://github.com/scummvm/scummvm/commit/2e6b5d67784995534843cf436486ade61b28a5f2
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Enable Mac GUI for Full Throttle demo
Unfortunately, the one we're providing is broken.
Changed paths:
engines/scumm/scumm.cpp
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index b910bc32606..45dd52b0b29 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1260,7 +1260,7 @@ Common::Error ScummEngine::init() {
{ GID_DIG, "The Dig" },
{ GID_DIG, "The Dig Demo" },
{ GID_FT, "Full Throttle" },
-// { GID_FT, "Full Throttle Demo" }
+ { GID_FT, "Full Throttle Demo" }
};
bool macScumm = false;
Commit: 92e7d9400f65cd835635d9c2fa03ea3d1cd31bfb
https://github.com/scummvm/scummvm/commit/92e7d9400f65cd835635d9c2fa03ea3d1cd31bfb
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
GRAPHICS: MACGUI: Add callback for when the menu is activated
The LucasArts SCUMM games need to know when this happens so that they
can turn the screen black. Polling the window manager for the menu
status probably wasn't good enough, because it seemed there were cases
where the menu was both activated and opened too quickly for the game to
have a chance to register it happening.
There is no callback for when the menu is deactivated. I could be wrong,
but I don't think this is quite as sensitive?
Changed paths:
graphics/macgui/macwindowmanager.cpp
graphics/macgui/macwindowmanager.h
diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index 5ebe20ff65a..e584fd853f9 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -446,6 +446,9 @@ void MacWindowManager::activateMenu() {
activateScreenCopy();
}
+ if (_activateMenuCallback != nullptr)
+ _activateMenuCallback(_engineAM);
+
_menu->setVisible(true);
}
@@ -1444,6 +1447,11 @@ void MacWindowManager::setEngineRedrawCallback(void *engine, void (*redrawCallba
_redrawEngineCallback = redrawCallback;
}
+void MacWindowManager::setEngineActivateMenuCallback(void *engine, void (*activateMenuCallback)(void *)) {
+ _engineAM = engine;
+ _activateMenuCallback = activateMenuCallback;
+}
+
void MacWindowManager::printWMMode(int debuglevel) {
Common::String out;
diff --git a/graphics/macgui/macwindowmanager.h b/graphics/macgui/macwindowmanager.h
index 42a22e4ddc9..a00646c7dcf 100644
--- a/graphics/macgui/macwindowmanager.h
+++ b/graphics/macgui/macwindowmanager.h
@@ -343,6 +343,7 @@ public:
void setEngine(Engine *engine);
void setEngineRedrawCallback(void *engine, void (*redrawCallback)(void *engine));
+ void setEngineActivateMenuCallback(void *engine, void (*redrawCallback)(void *engine));
void passPalette(const byte *palette, uint size);
template <typename T> void decomposeColor(uint32 color, byte &r, byte &g, byte &b);
@@ -462,6 +463,8 @@ private:
Engine *_engineP;
void *_engineR;
void (*_redrawEngineCallback)(void *engine);
+ void *_engineAM;
+ void (*_activateMenuCallback)(void *engine);
MacCursorType _tempType = kMacCursorArrow;
Common::Stack<MacCursorType> _cursorTypeStack;
Commit: 0e82eec28c06a1b0db7794f9359994c433becb0b
https://github.com/scummvm/scummvm/commit/0e82eec28c06a1b0db7794f9359994c433becb0b
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Use the Mac Window Manager menu activation callback
I hope this will put a stop to the infrequent wrong palette when menus
were opened.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index cec117203f7..873155df7e4 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -39,6 +39,12 @@
namespace Scumm {
+static void activateMenuCallback(void *ref) {
+ MacGuiImpl *gui = (MacGuiImpl *)ref;
+
+ gui->onMenuOpen();
+}
+
// ===========================================================================
// Base class for Macintosh game user interface. Handles menus, fonts, image
// loading, etc.
@@ -195,6 +201,7 @@ bool MacGuiImpl::initialize() {
_windowManager = new Graphics::MacWindowManager(menuMode);
_windowManager->setEngine(_vm);
_windowManager->setScreen(640, _vm->_useMacScreenCorrectHeight ? 480 : 400);
+ _windowManager->setEngineActivateMenuCallback(this, activateMenuCallback);
if (_vm->isUsingOriginalGUI()) {
_windowManager->setMenuHotzone(Common::Rect(640, 23));
@@ -476,13 +483,8 @@ void MacGuiImpl::updateWindowManager() {
if (saveMenu)
saveMenu->enabled = canSave;
- if (_windowManager->isMenuActive()) {
- if (!_menuIsActive)
- onMenuOpen();
- } else {
- if (_menuIsActive)
- onMenuClose();
- }
+ if (!_windowManager->isMenuActive() && _menuIsActive)
+ onMenuClose();
if (_vm->_game.version > 3 && _vm->_game.version < 6) {
Graphics::MacMenuItem *windowMenu = menu->getMenuItem("Window");
@@ -568,16 +570,20 @@ void MacGuiImpl::updateWindowManager() {
}
void MacGuiImpl::onMenuOpen() {
- _menuIsActive = true;
- _cursorWasVisible = CursorMan.showMouse(true);
- _windowManager->pushCursor(Graphics::MacGUIConstants::kMacCursorArrow);
+ if (!_menuIsActive) {
+ _menuIsActive = true;
+ _cursorWasVisible = CursorMan.showMouse(true);
+ _windowManager->pushCursor(Graphics::MacGUIConstants::kMacCursorArrow);
+ }
}
void MacGuiImpl::onMenuClose() {
- _menuIsActive = false;
- if (_windowManager->getCursorType() == Graphics::MacGUIConstants::kMacCursorArrow)
- _windowManager->popCursor();
- CursorMan.showMouse(_cursorWasVisible);
+ if (_menuIsActive) {
+ _menuIsActive = false;
+ if (_windowManager->getCursorType() == Graphics::MacGUIConstants::kMacCursorArrow)
+ _windowManager->popCursor();
+ CursorMan.showMouse(_cursorWasVisible);
+ }
}
// ---------------------------------------------------------------------------
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index cc86dfe2d42..09447527932 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -130,6 +130,9 @@ public:
kWidgetPopUpMenu
};
+ virtual void onMenuOpen();
+ virtual void onMenuClose();
+
protected:
ScummEngine *_vm = nullptr;
OSystem *_system = nullptr;
@@ -217,8 +220,6 @@ protected:
virtual bool getFontParams(FontId fontId, int &id, int &size, int &slant) const;
virtual bool handleMenu(int id, Common::String &name);
- virtual void onMenuOpen();
- virtual void onMenuClose();
// For older games, there is no problem with displaying the Mac GUI and
// the game at the same time. For newer, there is.
Commit: 84dc3e883d73928e3a4db3c5b208e00064398fee
https://github.com/scummvm/scummvm/commit/84dc3e883d73928e3a4db3c5b208e00064398fee
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix About dialog for Full Throttle demo
Turns out that it has the exact same dimensions as The Dig demo.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 7e9216e1771..2daba68e4c4 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -392,7 +392,7 @@ void MacV6Gui::runAboutDialog() {
bounds.top = 5;
bounds.right = 523;
bounds.bottom = 384;
- } else if (_vm->_game.id == GID_DIG) {
+ } else if (_vm->_game.id == GID_DIG || _vm->_game.id == GID_FT) {
bounds.left = 121;
bounds.top = 15;
bounds.right = 519;
Commit: c474edcf979d619c1995d4e7cd45e74f8c5f0d96
https://github.com/scummvm/scummvm/commit/c474edcf979d619c1995d4e7cd45e74f8c5f0d96
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Simplify word wrapping in demo About dialogs
Now that we use \n instead of \r, the word wrapper should be able to
handle the strings just fine.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index aa1dc7ae193..bb4b10eb110 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -781,7 +781,13 @@ void MacGuiImpl::MacDialogWindow::updateCursor() {
}
}
-MacGuiImpl::MacWidget *MacGuiImpl::MacDialogWindow::getWidget(MacWidgetType type, int nr) const {
+MacGuiImpl::MacWidget *MacGuiImpl::MacDialogWindow::getWidget(uint nr) const {
+ if (nr < _widgets.size())
+ return _widgets[nr];
+ return nullptr;
+}
+
+MacGuiImpl::MacWidget *MacGuiImpl::MacDialogWindow::getWidget(MacWidgetType type, uint nr) const {
for (uint i = 0; i < _widgets.size(); i++) {
if (_widgets[i]->getType() == type) {
if (nr == 0)
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 09447527932..1a1521f00e9 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -735,7 +735,10 @@ public:
void delayAndUpdate();
void updateCursor();
- MacWidget *getWidget(MacWidgetType type, int nr = 0) const;
+ uint getNumWidgets() const { return _widgets.size(); }
+
+ MacWidget *getWidget(uint nr) const;
+ MacWidget *getWidget(MacWidgetType type, uint nr = 0) const;
void setDefaultWidget(MacWidget *widget) { _defaultWidget = widget; }
MacWidget *getDefaultWidget() const { return _defaultWidget; }
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 2daba68e4c4..405fdb897c4 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -404,6 +404,12 @@ void MacV6Gui::runAboutDialog() {
window->setDefaultWidget(buttonOk);
+ for (uint i = 0; i < window->getNumWidgets(); i++) {
+ MacWidget *widget = window->getWidget(i);
+ if (widget->getType() == kWidgetStaticText)
+ ((MacStaticText *)widget)->setWordWrap(true);
+ }
+
while (!_vm->shouldQuit()) {
MacDialogEvent event;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index babfe6171d6..2b400ce5a17 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -114,25 +114,8 @@ int MacGuiImpl::MacWidget::drawText(Common::String text, int x, int y, int w, ui
if (wordWrap) {
maxLineWidth = font->wordWrapText(text, w, lines);
} else {
- if (text.contains('\n')) {
- Common::String line = "";
-
- for (uint i = 0; i < text.size(); i++) {
- if (text[i] != '\n')
- line += text[i];
-
- if (text[i] == '\n' || i == text.size() - 1) {
- int lineWidth = font->getStringWidth(line);
- if (lineWidth > maxLineWidth)
- maxLineWidth = lineWidth;
- lines.push_back(line);
- line = "";
- }
- }
- } else {
- lines.push_back(text);
- maxLineWidth = font->getStringWidth(text);
- }
+ lines.push_back(text);
+ maxLineWidth = font->getStringWidth(text);
}
// Draw the text. Disabled text is implemented as a filter on top of
Commit: 528c1899d0c6b800b52fcd0f138e07d050a76b83
https://github.com/scummvm/scummvm/commit/528c1899d0c6b800b52fcd0f138e07d050a76b83
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Populate the options dialogs with the actual settings
They are still not saved, however.
Changed paths:
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 1a1521f00e9..be9dbfa8844 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -512,6 +512,8 @@ public:
void getFocus() override {}
void loseFocus() override {}
+ int getMinValue() const { return _minValue; }
+ int getMaxValue() const { return _maxValue; }
void setValue(int value) override;
void addStop(int pos, int value) {
@@ -583,6 +585,8 @@ public:
MacImageSlider(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, MacImage *handle, bool enabled, int minX, int maxX, int minValue, int maxValue);
~MacImageSlider();
+ void setValue(int value) override;
+
bool findWidget(int x, int y) const override;
void draw(bool drawFocused = false) override;
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 405fdb897c4..4e878c7e9ca 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -23,6 +23,8 @@
#include "common/config-manager.h"
#include "common/macresman.h"
+#include "audio/mixer.h"
+
#include "engines/engine.h"
#include "engines/metaengine.h"
#include "engines/savestate.h"
@@ -805,6 +807,13 @@ bool MacV6Gui::runOptionsDialog() {
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
MacButton *buttonDefaults = (MacButton *)window->getWidget(kWidgetButton, 2);
+ MacImageSlider *sliderMusicVolume = nullptr;
+ MacImageSlider *effectVolumeSlider = nullptr;
+ MacImageSlider *voiceVolumeSlider = nullptr;
+ MacImageSlider *sliderTextSpeed = nullptr;
+
+ MacCheckbox *spoolMusicCheckbox = nullptr;
+
MacPopUpMenu *interactionPopUp = nullptr;
MacPopUpMenu *videoQualityPopUp = nullptr;
@@ -820,9 +829,6 @@ bool MacV6Gui::runOptionsDialog() {
videoQualityPopUp = (MacPopUpMenu *)window->getWidget(kWidgetPopUpMenu, 0);
}
- if (interactionPopUp)
- interactionPopUp->setValue(2);
-
// Note: The video quality menu contains an additional "Graphics
// Smoothing" entry. I don't know why it doesn't show up in the
// original, but as long as we disabled the pop-up that's not a
@@ -840,30 +846,71 @@ bool MacV6Gui::runOptionsDialog() {
drawDottedFrame(window, Common::Rect(12, 41, 337, 113), 21, 137);
drawDottedFrame(window, Common::Rect(11, 130, 336, 203), 20, 168);
- addSlider(window, 152, 63, 147, 17);
- addSlider(window, 152, 87, 147, 17);
- addSlider(window, 151, 177, 147, 9);
+ sliderMusicVolume = addSlider(window, 152, 63, 147, 17);
+ voiceVolumeSlider = addSlider(window, 152, 87, 147, 17);
+ sliderTextSpeed = addSlider(window, 151, 177, 147, 9);
} else if (_vm->_game.id == GID_MANIAC) {
- addSlider(window, 152, 41, 147, 17);
- addSlider(window, 152, 72, 147, 10, 5);
+ sliderMusicVolume = addSlider(window, 152, 41, 147, 17);
+ sliderTextSpeed = addSlider(window, 152, 72, 147, 10, 5);
} else if (_vm->_game.id == GID_SAMNMAX || _vm->_game.id == GID_DIG) {
drawDottedFrame(window, Common::Rect(12, 41, 337, 136), 21, 137);
drawDottedFrame(window, Common::Rect(12, 156, 337, 229), 20, 168);
- addSlider(window, 152, 63, 147, 17);
- addSlider(window, 152, 87, 147, 17);
- addSlider(window, 152, 111, 147, 17);
- addSlider(window, 152, 203, 147, 9);
+ sliderMusicVolume = addSlider(window, 152, 63, 147, 17);
+ effectVolumeSlider = addSlider(window, 152, 87, 147, 17);
+ voiceVolumeSlider = addSlider(window, 152, 111, 147, 17);
+ sliderTextSpeed = addSlider(window, 152, 203, 147, 9);
} else if (_vm->_game.id == GID_FT) {
drawDottedFrame(window, Common::Rect(12, 41, 337, 164), 21, 137);
drawDottedFrame(window, Common::Rect(12, 184, 337, 257), 20, 168);
- addSlider(window, 152, 63, 147, 17);
- addSlider(window, 152, 87, 147, 17);
- addSlider(window, 152, 111, 147, 17);
- addSlider(window, 152, 231, 147, 9);
+ sliderMusicVolume = addSlider(window, 152, 63, 147, 17);
+ effectVolumeSlider = addSlider(window, 152, 87, 147, 17);
+ voiceVolumeSlider = addSlider(window, 152, 111, 147, 17);
+ sliderTextSpeed = addSlider(window, 152, 231, 147, 9);
+
+ spoolMusicCheckbox = (MacCheckbox *)window->getWidget(kWidgetCheckbox, 0);
+ }
+
+ if (interactionPopUp) {
+ switch (_vm->_voiceMode) {
+ case 0: // Voice Only
+ interactionPopUp->setValue(1);
+ break;
+ case 1: // Voice And Text
+ interactionPopUp->setValue(2);
+ break;
+ case 2: // Text Only
+ interactionPopUp->setValue(0);
+ break;
+ default:
+ warning("MacGuiImpl::MacV6Gui::runOptionsDialog(): Invalid voice mode %d", _vm->_voiceMode);
+ break;
+ }
+ }
+
+ int musicVolume = 0;
+ int effectVolume = 0;
+ int voiceVolume = 0;
+
+ if (sliderMusicVolume) {
+ musicVolume = _vm->_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 16;
+ sliderMusicVolume->setValue(musicVolume);
}
+ if (effectVolumeSlider) {
+ effectVolume = _vm->_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 16;
+ effectVolumeSlider->setValue(effectVolume);
+ }
+
+ if (voiceVolumeSlider) {
+ voiceVolume = _vm->_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 16;
+ voiceVolumeSlider->setValue(voiceVolume);
+ }
+
+ if (sliderTextSpeed)
+ sliderTextSpeed->setValue(_vm->_defaultTextSpeed);
+
while (!_vm->shouldQuit()) {
MacDialogEvent event;
@@ -877,6 +924,18 @@ bool MacV6Gui::runOptionsDialog() {
delete window;
return false;
} else if (event.widget == buttonDefaults) {
+ if (sliderMusicVolume)
+ sliderMusicVolume->setValue(16);
+ if (effectVolumeSlider)
+ effectVolumeSlider->setValue(12);
+ if (voiceVolumeSlider)
+ voiceVolumeSlider->setValue(16);
+ if (interactionPopUp)
+ interactionPopUp->setValue(1);
+ if (sliderTextSpeed)
+ sliderTextSpeed->setValue(4);
+ if (spoolMusicCheckbox)
+ spoolMusicCheckbox->setValue(1);
}
break;
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 2b400ce5a17..ccaa0fe3f9b 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -848,7 +848,8 @@ void MacGuiImpl::MacImage::draw(bool drawFocused) {
// ---------------------------------------------------------------------------
void MacGuiImpl::MacSliderBase::setValue(int value) {
- _value = CLIP(value, _minValue, _maxValue);
+ int newValue = CLIP(value, _minValue, _maxValue);
+ MacWidget::setValue(newValue);
_handlePos = calculatePosFromValue();
}
@@ -1315,6 +1316,14 @@ MacGuiImpl::MacImageSlider::~MacImageSlider() {
}
}
+void MacGuiImpl::MacImageSlider::setValue(int value) {
+ int newValue = CLIP(value, _minValue, _maxValue);
+ MacWidget::setValue(newValue);
+ eraseHandle();
+ _handlePos = calculatePosFromValue();
+ drawHandle();
+}
+
bool MacGuiImpl::MacImageSlider::findWidget(int x, int y) const {
// Once we start dragging the handle, any mouse position is considered
// within the widget.
Commit: eeff511c1d4551f5f155b89b1443408512fd956e
https://github.com/scummvm/scummvm/commit/eeff511c1d4551f5f155b89b1443408512fd956e
Author: athrxx (athrxx at scummvm.org)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: (SAM/Mac) - fix icon color init/remap
I just added a step that is present in the second resource processing
loop of MacGuiImpl::createDialog(), but not in the first one.
(fixes at least SAM German, but possibly other things, too)
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 873155df7e4..ad8ca87b029 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -952,6 +952,9 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect
}
}
+ if (len & 1)
+ res->skip(1);
+
delete imageRes;
}
Commit: 5b3fc0cdf919c1abe6fc5f0188a93ec56d6270cf
https://github.com/scummvm/scummvm/commit/5b3fc0cdf919c1abe6fc5f0188a93ec56d6270cf
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Use ConfMan to retrieve volume settings
I was using some mindless cut-and-paste from COMI, which uses Digital
iMUSE. That's not a guarantee here.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 4e878c7e9ca..b37e5293013 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -894,17 +894,17 @@ bool MacV6Gui::runOptionsDialog() {
int voiceVolume = 0;
if (sliderMusicVolume) {
- musicVolume = _vm->_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 16;
+ musicVolume = ConfMan.getInt("music_volume") / 16;
sliderMusicVolume->setValue(musicVolume);
}
if (effectVolumeSlider) {
- effectVolume = _vm->_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 16;
+ effectVolume = ConfMan.getInt("sfx_volume") / 16;
effectVolumeSlider->setValue(effectVolume);
}
if (voiceVolumeSlider) {
- voiceVolume = _vm->_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 16;
+ voiceVolume = ConfMan.getInt("speech_volume") / 16;
voiceVolumeSlider->setValue(voiceVolume);
}
Commit: 4e20519d20078c9fb27e5fed591e2aebcfd17bf7
https://github.com/scummvm/scummvm/commit/4e20519d20078c9fb27e5fed591e2aebcfd17bf7
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Options dialog cleanup
The "spool music" checkbox for Full Throttle is disabled for now. When
implemented, it should probably be tied to the "music_mute" setting, but
that's only used for earlier games at the moment.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index b37e5293013..0325732d86d 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -808,14 +808,14 @@ bool MacV6Gui::runOptionsDialog() {
MacButton *buttonDefaults = (MacButton *)window->getWidget(kWidgetButton, 2);
MacImageSlider *sliderMusicVolume = nullptr;
- MacImageSlider *effectVolumeSlider = nullptr;
- MacImageSlider *voiceVolumeSlider = nullptr;
+ MacImageSlider *sliderEffectVolume = nullptr;
+ MacImageSlider *sliderVoiceVolume = nullptr;
MacImageSlider *sliderTextSpeed = nullptr;
- MacCheckbox *spoolMusicCheckbox = nullptr;
+ MacCheckbox *checkboxSpoolMusic = nullptr;
- MacPopUpMenu *interactionPopUp = nullptr;
- MacPopUpMenu *videoQualityPopUp = nullptr;
+ MacPopUpMenu *popUpInteraction = nullptr;
+ MacPopUpMenu *popUpVideoQuality = nullptr;
if (_vm->_game.id != GID_MANIAC) {
window->addSubstitution("");
@@ -823,10 +823,10 @@ bool MacV6Gui::runOptionsDialog() {
window->addSubstitution("");
window->addSubstitution(_gameName);
- interactionPopUp = (MacPopUpMenu *)window->getWidget(kWidgetPopUpMenu, 0);
- videoQualityPopUp = (MacPopUpMenu *)window->getWidget(kWidgetPopUpMenu, 1);
+ popUpInteraction = (MacPopUpMenu *)window->getWidget(kWidgetPopUpMenu, 0);
+ popUpVideoQuality = (MacPopUpMenu *)window->getWidget(kWidgetPopUpMenu, 1);
} else {
- videoQualityPopUp = (MacPopUpMenu *)window->getWidget(kWidgetPopUpMenu, 0);
+ popUpVideoQuality = (MacPopUpMenu *)window->getWidget(kWidgetPopUpMenu, 0);
}
// Note: The video quality menu contains an additional "Graphics
@@ -834,8 +834,8 @@ bool MacV6Gui::runOptionsDialog() {
// original, but as long as we disabled the pop-up that's not a
// problem. My future self can thank me later.
- videoQualityPopUp->setValue(1);
- videoQualityPopUp->setEnabled(false);
+ popUpVideoQuality->setValue(1);
+ popUpVideoQuality->setEnabled(false);
window->setDefaultWidget(buttonOk);
@@ -847,7 +847,7 @@ bool MacV6Gui::runOptionsDialog() {
drawDottedFrame(window, Common::Rect(11, 130, 336, 203), 20, 168);
sliderMusicVolume = addSlider(window, 152, 63, 147, 17);
- voiceVolumeSlider = addSlider(window, 152, 87, 147, 17);
+ sliderVoiceVolume = addSlider(window, 152, 87, 147, 17);
sliderTextSpeed = addSlider(window, 151, 177, 147, 9);
} else if (_vm->_game.id == GID_MANIAC) {
sliderMusicVolume = addSlider(window, 152, 41, 147, 17);
@@ -857,31 +857,31 @@ bool MacV6Gui::runOptionsDialog() {
drawDottedFrame(window, Common::Rect(12, 156, 337, 229), 20, 168);
sliderMusicVolume = addSlider(window, 152, 63, 147, 17);
- effectVolumeSlider = addSlider(window, 152, 87, 147, 17);
- voiceVolumeSlider = addSlider(window, 152, 111, 147, 17);
+ sliderEffectVolume = addSlider(window, 152, 87, 147, 17);
+ sliderVoiceVolume = addSlider(window, 152, 111, 147, 17);
sliderTextSpeed = addSlider(window, 152, 203, 147, 9);
} else if (_vm->_game.id == GID_FT) {
drawDottedFrame(window, Common::Rect(12, 41, 337, 164), 21, 137);
drawDottedFrame(window, Common::Rect(12, 184, 337, 257), 20, 168);
sliderMusicVolume = addSlider(window, 152, 63, 147, 17);
- effectVolumeSlider = addSlider(window, 152, 87, 147, 17);
- voiceVolumeSlider = addSlider(window, 152, 111, 147, 17);
+ sliderEffectVolume = addSlider(window, 152, 87, 147, 17);
+ sliderVoiceVolume = addSlider(window, 152, 111, 147, 17);
sliderTextSpeed = addSlider(window, 152, 231, 147, 9);
- spoolMusicCheckbox = (MacCheckbox *)window->getWidget(kWidgetCheckbox, 0);
+ checkboxSpoolMusic = (MacCheckbox *)window->getWidget(kWidgetCheckbox, 0);
}
- if (interactionPopUp) {
+ if (popUpInteraction) {
switch (_vm->_voiceMode) {
case 0: // Voice Only
- interactionPopUp->setValue(1);
+ popUpInteraction->setValue(1);
break;
case 1: // Voice And Text
- interactionPopUp->setValue(2);
+ popUpInteraction->setValue(2);
break;
case 2: // Text Only
- interactionPopUp->setValue(0);
+ popUpInteraction->setValue(0);
break;
default:
warning("MacGuiImpl::MacV6Gui::runOptionsDialog(): Invalid voice mode %d", _vm->_voiceMode);
@@ -892,20 +892,31 @@ bool MacV6Gui::runOptionsDialog() {
int musicVolume = 0;
int effectVolume = 0;
int voiceVolume = 0;
+ int spoolMusic = 1;
if (sliderMusicVolume) {
musicVolume = ConfMan.getInt("music_volume") / 16;
sliderMusicVolume->setValue(musicVolume);
}
- if (effectVolumeSlider) {
+ if (sliderEffectVolume) {
effectVolume = ConfMan.getInt("sfx_volume") / 16;
- effectVolumeSlider->setValue(effectVolume);
+ sliderEffectVolume->setValue(effectVolume);
}
- if (voiceVolumeSlider) {
+ if (sliderVoiceVolume) {
voiceVolume = ConfMan.getInt("speech_volume") / 16;
- voiceVolumeSlider->setValue(voiceVolume);
+ sliderVoiceVolume->setValue(voiceVolume);
+ }
+
+ if (checkboxSpoolMusic) {
+#if 0
+ spoolMusic = ConfMan.getBool("music_mute") ? 0 : 1;
+ checkboxSpoolMusic->setValue(spoolMusic);
+#else
+ checkboxSpoolMusic->setValue(spoolMusic);
+ checkboxSpoolMusic->setEnabled(false);
+#endif
}
if (sliderTextSpeed)
@@ -926,16 +937,16 @@ bool MacV6Gui::runOptionsDialog() {
} else if (event.widget == buttonDefaults) {
if (sliderMusicVolume)
sliderMusicVolume->setValue(16);
- if (effectVolumeSlider)
- effectVolumeSlider->setValue(12);
- if (voiceVolumeSlider)
- voiceVolumeSlider->setValue(16);
- if (interactionPopUp)
- interactionPopUp->setValue(1);
+ if (sliderEffectVolume)
+ sliderEffectVolume->setValue(12);
+ if (sliderVoiceVolume)
+ sliderVoiceVolume->setValue(16);
+ if (popUpInteraction)
+ popUpInteraction->setValue(1);
if (sliderTextSpeed)
sliderTextSpeed->setValue(4);
- if (spoolMusicCheckbox)
- spoolMusicCheckbox->setValue(1);
+ if (checkboxSpoolMusic)
+ checkboxSpoolMusic->setValue(1);
}
break;
Commit: ee2b30964a3e886006098f1ea4586bce4387cfdd
https://github.com/scummvm/scummvm/commit/ee2b30964a3e886006098f1ea4586bce4387cfdd
Author: athrxx (athrxx at scummvm.org)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: cleanup v7/8 specific syncSoundSettings() code
Changed paths:
engines/scumm/scumm.cpp
engines/scumm/scumm_v7.h
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 45dd52b0b29..7a5cb94c3ea 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -2417,43 +2417,6 @@ void ScummEngine::syncSoundSettings() {
if (!_setupIsComplete)
return;
- if (isUsingOriginalGUI() && _game.version > 6) {
- int guiTextStatus = 0;
- if (ConfMan.getBool("speech_mute")) {
- guiTextStatus = 2;
- } else if (ConfMan.getBool("subtitles")) {
- guiTextStatus = 1;
- }
-
- // Mainly used by COMI
- ConfMan.setInt("original_gui_text_status", guiTextStatus);
- _voiceMode = guiTextStatus;
-
- if (VAR_VOICE_MODE != 0xFF)
- VAR(VAR_VOICE_MODE) = _voiceMode;
-
- if (ConfMan.hasKey("original_gui_text_speed", _targetName)) {
- // If the value has been changed from the GMM, sync it...
- if (getTalkSpeed() != ConfMan.getInt("original_gui_text_speed")) {
- ConfMan.setInt("original_gui_text_speed", getTalkSpeed());
- }
-
- _defaultTextSpeed = ConfMan.getInt("original_gui_text_speed");
-
- if (VAR_CHARINC != 0xFF)
- VAR(VAR_CHARINC) = 9 - _defaultTextSpeed;
- }
-
-#ifdef ENABLE_SCUMM_7_8
- if (_game.version >= 7 && _imuseDigital) {
- _imuseDigital->diMUSESetMusicGroupVol(ConfMan.getInt("music_volume") / 2);
- _imuseDigital->diMUSESetVoiceGroupVol(ConfMan.getInt("speech_volume") / 2);
- _imuseDigital->diMUSESetSFXGroupVol(ConfMan.getInt("sfx_volume") / 2);
- }
-#endif
- return;
- }
-
Engine::syncSoundSettings();
// Sync the engine with the config manager
@@ -2497,6 +2460,49 @@ void ScummEngine::syncSoundSettings() {
}
+void ScummEngine_v7::syncSoundSettings() {
+ if (!_setupIsComplete)
+ return;
+
+ if (!isUsingOriginalGUI()) {
+ ScummEngine::syncSoundSettings();
+ return;
+ }
+
+ int guiTextStatus = 0;
+ if (ConfMan.getBool("speech_mute")) {
+ guiTextStatus = 2;
+ } else if (ConfMan.getBool("subtitles")) {
+ guiTextStatus = 1;
+ }
+
+ // Mainly used by COMI
+ ConfMan.setInt("original_gui_text_status", guiTextStatus);
+ _voiceMode = guiTextStatus;
+
+ if (VAR_VOICE_MODE != 0xFF)
+ VAR(VAR_VOICE_MODE) = _voiceMode;
+
+ if (ConfMan.hasKey("original_gui_text_speed", _targetName)) {
+ // If the value has been changed from the GMM, sync it...
+ if (getTalkSpeed() != ConfMan.getInt("original_gui_text_speed")) {
+ ConfMan.setInt("original_gui_text_speed", getTalkSpeed());
+ }
+
+ _defaultTextSpeed = ConfMan.getInt("original_gui_text_speed");
+ if (VAR_CHARINC != 0xFF)
+ VAR(VAR_CHARINC) = 9 - _defaultTextSpeed;
+ }
+
+#ifdef ENABLE_SCUMM_7_8
+ if (_game.version >= 7 && _imuseDigital) {
+ _imuseDigital->diMUSESetMusicGroupVol(ConfMan.getInt("music_volume") / 2);
+ _imuseDigital->diMUSESetVoiceGroupVol(ConfMan.getInt("speech_volume") / 2);
+ _imuseDigital->diMUSESetSFXGroupVol(ConfMan.getInt("sfx_volume") / 2);
+ }
+#endif
+}
+
void ScummEngine::setTalkSpeed(int talkspeed) {
ConfMan.setInt("talkspeed", (talkspeed * 255 + 9 / 2) / 9);
}
diff --git a/engines/scumm/scumm_v7.h b/engines/scumm/scumm_v7.h
index c5ab2e5cf02..9f5ba82769d 100644
--- a/engines/scumm/scumm_v7.h
+++ b/engines/scumm/scumm_v7.h
@@ -57,6 +57,8 @@ protected:
Insane *_insane;
public:
+ void syncSoundSettings() override;
+
SmushMixer *_smixer;
SmushPlayer *_splayer;
Commit: 9c6d67b6a15627527e571dcdb32bb2845d8e2dc5
https://github.com/scummvm/scummvm/commit/9c6d67b6a15627527e571dcdb32bb2845d8e2dc5
Author: athrxx (athrxx at scummvm.org)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: (SCUMM6/7/Mac) - implement sound mute menu option
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/scumm.cpp
engines/scumm/scumm.h
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index ad8ca87b029..88ed828f6df 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -541,8 +541,8 @@ void MacGuiImpl::updateWindowManager() {
Graphics::MacMenuItem *soundMenu = menu->getMenuItem(4);
- menu->getSubMenuItem(soundMenu, 0)->checked = false; // Music
- menu->getSubMenuItem(soundMenu, 1)->checked = false; // Effects
+ menu->getSubMenuItem(soundMenu, 0)->checked = (_vm->_soundEnabled & 2); // Music
+ menu->getSubMenuItem(soundMenu, 1)->checked = (_vm->_soundEnabled & 1); // Effects
menu->getSubMenuItem(soundMenu, 5)->checked = false; // Text Only
menu->getSubMenuItem(soundMenu, 6)->checked = false; // Voice Only
menu->getSubMenuItem(soundMenu, 7)->checked = false; // Text & Voice
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 0325732d86d..fa1f96f8c67 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -121,6 +121,7 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
updateWindowManager();
int saveSlotToHandle = -1;
+ bool syncSoundSettings = false;
Common::String savegameName;
// The Dig and Full Throttle don't have a Restart menu entry
@@ -188,11 +189,15 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return true;
case 500: // Music
- debug("Music");
+ _vm->_soundEnabled ^= 2;
+ ConfMan.setBool("music_mute", !(_vm->_soundEnabled & 2));
+ syncSoundSettings = true;
break;
case 501: // Effects
- debug("Effects");
+ _vm->_soundEnabled ^= 1;
+ ConfMan.setBool("sfx_mute", !(_vm->_soundEnabled & 1));
+ syncSoundSettings = true;
break;
case 502: // Toggle Text & Voice
@@ -214,39 +219,41 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
default:
warning("Invalid voice mode %d", _vm->_voiceMode);
- return true;
+ return true;
}
- ConfMan.flushToDisk();
- _vm->syncSoundSettings();
- return true;
+ syncSoundSettings = true;
+ break;
case 503: // Text Only
ConfMan.setBool("subtitles", true);
ConfMan.setBool("speech_mute", true);
- ConfMan.flushToDisk();
- _vm->syncSoundSettings();
- return true;
+ syncSoundSettings = true;
+ break;
case 504: // Voice Only
ConfMan.setBool("subtitles", false);
ConfMan.setBool("speech_mute", false);
- ConfMan.flushToDisk();
- _vm->syncSoundSettings();
- return true;
+ syncSoundSettings = true;
+ break;
case 505: // Text & Voice
ConfMan.setBool("subtitles", true);
ConfMan.setBool("speech_mute", false);
- ConfMan.flushToDisk();
- _vm->syncSoundSettings();
- return true;
+ syncSoundSettings = true;
+ break;
default:
warning("Unknown menu command: %d", id);
break;
}
+ if (syncSoundSettings) {
+ ConfMan.flushToDisk();
+ _vm->syncSoundSettings();
+ return true;
+ }
+
return false;
}
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 7a5cb94c3ea..1d04ac0309a 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -2432,6 +2432,18 @@ void ScummEngine::syncSoundSettings() {
soundVolumeMusic = soundVolumeSfx = 0;
}
+ _soundEnabled = ((ConfMan.hasKey("music_mute") && ConfMan.getBool("music_mute")) ? 0 : 2) | ((ConfMan.hasKey("sfx_mute") && ConfMan.getBool("sfx_mute")) ? 0 : 1);
+
+ if (_game.version >= 6 && _game.platform == Common::kPlatformMacintosh) {
+ if (_game.version == 6) {
+ if (!(_soundEnabled & 2))
+ soundVolumeMusic = 0;
+ } else {
+ _mixer->muteSoundType(Audio::Mixer::kMusicSoundType, !(_soundEnabled & 2));
+ }
+ _mixer->muteSoundType(Audio::Mixer::kSFXSoundType, !(_soundEnabled & 1));
+ }
+
if (_musicEngine) {
_musicEngine->setMusicVolume(soundVolumeMusic);
_musicEngine->setSfxVolume(soundVolumeSfx);
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 5cf8e843ae6..4ef6a75a38f 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1521,6 +1521,7 @@ public:
byte *_shadowPalette = nullptr;
bool _skipDrawObject = 0;
int _voiceMode = 0;
+ int _soundEnabled = 0;
// HE specific
byte _HEV7ActorPalette[256];
Commit: 55efc98248c26bf79fd60012e92ceb15d7875d62
https://github.com/scummvm/scummvm/commit/55efc98248c26bf79fd60012e92ceb15d7875d62
Author: athrxx (athrxx at scummvm.org)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: (IMS/Mac) - fix volume init values
Changed paths:
engines/scumm/imuse/drivers/macintosh.cpp
diff --git a/engines/scumm/imuse/drivers/macintosh.cpp b/engines/scumm/imuse/drivers/macintosh.cpp
index aa5ab88f31f..5c8b9c85935 100644
--- a/engines/scumm/imuse/drivers/macintosh.cpp
+++ b/engines/scumm/imuse/drivers/macintosh.cpp
@@ -1294,7 +1294,7 @@ namespace Scumm {
using namespace IMSMacintosh;
IMuseDriver_Macintosh::IMuseDriver_Macintosh(ScummEngine *vm, Audio::Mixer *mixer, byte gameID) : MidiDriver(), _isOpen(false), _device(nullptr), _imsParts(nullptr), _channels(nullptr),
- _numParts(32), _numChannels(8), _baseTempo(16666), _quality(1), _musicVolume(0), _sfxVolume(0), _version(-1) {
+ _numParts(32), _numChannels(8), _baseTempo(16666), _quality(1), _musicVolume(0xFFFFFFFF), _sfxVolume(0xFFFFFFFF), _version(-1) {
switch (gameID) {
case GID_TENTACLE:
Commit: 060c751878879fddf4100485adb118d8b59b9332
https://github.com/scummvm/scummvm/commit/060c751878879fddf4100485adb118d8b59b9332
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Add very untested code for saving most v6-7 options
We have visitors, so I'm not going to turn up the volume to verify that
the volume sliders work correctly!
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index fa1f96f8c67..b4f1564f7cd 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -37,6 +37,7 @@
#include "scumm/scumm.h"
#include "scumm/detection.h"
#include "scumm/file.h"
+#include "scumm/imuse_digi/dimuse_engine.h"
#include "scumm/macgui/macgui_impl.h"
#include "scumm/macgui/macgui_v6.h"
@@ -54,10 +55,12 @@ MacV6Gui::MacV6Gui(ScummEngine *vm, const Common::Path &resourceFile) : MacGuiIm
_gameName = "Day of the Tentacle";
else if (_vm->_game.id == GID_SAMNMAX)
_gameName = "Sam & Max";
+#ifdef ENABLE_SCUMM_7_8
else if (_vm->_game.id == GID_DIG)
_gameName = "The Dig";
else if (_vm->_game.id == GID_FT)
_gameName = "Full Throttle";
+#endif
else if (_vm->_game.id == GID_MANIAC)
_gameName = "Maniac Mansion";
else
@@ -401,11 +404,13 @@ void MacV6Gui::runAboutDialog() {
bounds.top = 5;
bounds.right = 523;
bounds.bottom = 384;
+#ifdef ENABLE_SCUMM_7_8
} else if (_vm->_game.id == GID_DIG || _vm->_game.id == GID_FT) {
bounds.left = 121;
bounds.top = 15;
bounds.right = 519;
bounds.bottom = 364;
+#endif
}
MacDialogWindow *window = createDialog(136, bounds);
@@ -799,6 +804,44 @@ bool MacV6Gui::runSaveDialog(int &saveSlotToHandle, Common::String &saveName) {
return false;
}
+void MacV6Gui::setVolume(int type, int volume) {
+ const char *keys[] = {
+ "music_volume",
+ "sfx_volume",
+ "speech_volume"
+ };
+
+ const Audio::Mixer::SoundType soundTypes[] = {
+ Audio::Mixer::kMusicSoundType,
+ Audio::Mixer::kSFXSoundType,
+ Audio::Mixer::kSpeechSoundType
+ };
+
+ volume = CLIP(16 * volume, 0, 256);
+
+ if (_vm->_game.version >= 7) {
+#ifdef ENABLE_SCUMM_7_8
+ int dimuseVolume = CLIP(8 * volume, 0, 127);
+
+ switch (type) {
+ case 0:
+ _vm->_imuseDigital->diMUSESetMusicGroupVol(dimuseVolume);
+ break;
+ case 1:
+ _vm->_imuseDigital->diMUSESetSFXGroupVol(dimuseVolume);
+ break;
+ case 2:
+ _vm->_imuseDigital->diMUSESetVoiceGroupVol(dimuseVolume);
+ break;
+ }
+#endif
+ } else {
+ _vm->_mixer->setVolumeForSoundType(soundTypes[type], volume);
+ }
+
+ ConfMan.setInt(keys[type], volume);
+}
+
bool MacV6Gui::runOptionsDialog() {
// There are too many different variations to list all widgets here.
// The important thing that they share are that the first three buttons
@@ -819,7 +862,9 @@ bool MacV6Gui::runOptionsDialog() {
MacImageSlider *sliderVoiceVolume = nullptr;
MacImageSlider *sliderTextSpeed = nullptr;
+#ifdef ENABLE_SCUMM_7_8
MacCheckbox *checkboxSpoolMusic = nullptr;
+#endif
MacPopUpMenu *popUpInteraction = nullptr;
MacPopUpMenu *popUpVideoQuality = nullptr;
@@ -867,6 +912,7 @@ bool MacV6Gui::runOptionsDialog() {
sliderEffectVolume = addSlider(window, 152, 87, 147, 17);
sliderVoiceVolume = addSlider(window, 152, 111, 147, 17);
sliderTextSpeed = addSlider(window, 152, 203, 147, 9);
+#ifdef ENABLE_SCUMM_7_8
} else if (_vm->_game.id == GID_FT) {
drawDottedFrame(window, Common::Rect(12, 41, 337, 164), 21, 137);
drawDottedFrame(window, Common::Rect(12, 184, 337, 257), 20, 168);
@@ -877,7 +923,9 @@ bool MacV6Gui::runOptionsDialog() {
sliderTextSpeed = addSlider(window, 152, 231, 147, 9);
checkboxSpoolMusic = (MacCheckbox *)window->getWidget(kWidgetCheckbox, 0);
- }
+#endif
+ } else
+ error("MacV6Gui::runOptionsDialog: Unknown game");
if (popUpInteraction) {
switch (_vm->_voiceMode) {
@@ -899,12 +947,13 @@ bool MacV6Gui::runOptionsDialog() {
int musicVolume = 0;
int effectVolume = 0;
int voiceVolume = 0;
- int spoolMusic = 1;
- if (sliderMusicVolume) {
- musicVolume = ConfMan.getInt("music_volume") / 16;
- sliderMusicVolume->setValue(musicVolume);
- }
+ // There is always a music volume slider. The rest are not guaranteed.
+ // If there is a voice volume slider but no effect volume slider, the
+ // voice volume slider cover both.
+
+ musicVolume = ConfMan.getInt("music_volume") / 16;
+ sliderMusicVolume->setValue(musicVolume);
if (sliderEffectVolume) {
effectVolume = ConfMan.getInt("sfx_volume") / 16;
@@ -916,15 +965,10 @@ bool MacV6Gui::runOptionsDialog() {
sliderVoiceVolume->setValue(voiceVolume);
}
- if (checkboxSpoolMusic) {
-#if 0
- spoolMusic = ConfMan.getBool("music_mute") ? 0 : 1;
- checkboxSpoolMusic->setValue(spoolMusic);
-#else
- checkboxSpoolMusic->setValue(spoolMusic);
- checkboxSpoolMusic->setEnabled(false);
+#ifdef ENABLE_SCUMM_7_8
+ if (checkboxSpoolMusic)
+ checkboxSpoolMusic->setValue(_vm->_spooledMusicIsToBeEnabled);
#endif
- }
if (sliderTextSpeed)
sliderTextSpeed->setValue(_vm->_defaultTextSpeed);
@@ -936,6 +980,56 @@ bool MacV6Gui::runOptionsDialog() {
switch (event.type) {
case kDialogClick:
if (event.widget == buttonOk) {
+ musicVolume = sliderMusicVolume->getValue();
+
+ if (_vm->_game.id == GID_MANIAC) {
+ effectVolume = musicVolume;
+ } else if (_vm->_game.id == GID_TENTACLE) {
+ musicVolume = sliderMusicVolume->getValue();
+ voiceVolume = sliderVoiceVolume->getValue();
+ effectVolume = voiceVolume;
+ } else {
+ musicVolume = sliderMusicVolume->getValue();
+ effectVolume = sliderEffectVolume->getValue();
+ voiceVolume = sliderVoiceVolume->getValue();
+ }
+
+ setVolume(0, musicVolume);
+ setVolume(1, effectVolume);
+
+ if (sliderVoiceVolume) {
+ voiceVolume = sliderVoiceVolume->getValue();
+ setVolume(2, voiceVolume);
+ }
+
+ // FIXME: DOS versions use 0-9, Mac versions... 0-8? 1-9?
+ _vm->_defaultTextSpeed = sliderTextSpeed->getValue();
+ ConfMan.setInt("original_gui_text_speed", _vm->_defaultTextSpeed);
+ _vm->setTalkSpeed(_vm->_defaultTextSpeed);
+
+#ifdef ENABLE_SCUMM_7_8
+ if (checkboxSpoolMusic) {
+ bool spoolMusic = (checkboxSpoolMusic->getValue() != 0);
+
+ _vm->_spooledMusicIsToBeEnabled = spoolMusic;
+
+ if (_vm->_imuseDigital) {
+ if (spoolMusic) {
+ _vm->_imuseDigital->diMUSEEnableSpooledMusic();
+ } else {
+ _vm->_imuseDigital->diMUSEDisableSpooledMusic();
+ }
+ }
+ }
+#endif
+
+ // TODO: Save "interact using"
+
+ ConfMan.flushToDisk();
+
+ if (_vm->_game.version < 7)
+ _vm->syncSoundSettings();
+
delete window;
return true;
} else if (event.widget == buttonCancel) {
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 712c0efed82..ce64fe1ab6e 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -78,6 +78,8 @@ protected:
MacGuiImpl::MacImageSlider *addSlider(MacDialogWindow *window, int x, int y, int width, int numMarkings, int primaryMarkings = 4);
+ void setVolume(int type, int volume);
+
void runAboutDialog() override;
bool runOpenDialog(int &saveSlotToHandle) override;
bool runSaveDialog(int &saveSlotToHandle, Common::String &saveName) override;
Commit: e0b5cd8ebe92d73ea37d4539ed4fcf7805d44f4c
https://github.com/scummvm/scummvm/commit/e0b5cd8ebe92d73ea37d4539ed4fcf7805d44f4c
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: Fix build when v7 and v8 aren't enabled
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/scumm.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index b4f1564f7cd..d182e56a446 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -1046,8 +1046,10 @@ bool MacV6Gui::runOptionsDialog() {
popUpInteraction->setValue(1);
if (sliderTextSpeed)
sliderTextSpeed->setValue(4);
+#ifdef ENABLE_SCUMM_7_8
if (checkboxSpoolMusic)
checkboxSpoolMusic->setValue(1);
+#endif
}
break;
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 1d04ac0309a..25bd5c5bfc5 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -2472,6 +2472,7 @@ void ScummEngine::syncSoundSettings() {
}
+#ifdef ENABLE_SCUMM_7_8
void ScummEngine_v7::syncSoundSettings() {
if (!_setupIsComplete)
return;
@@ -2506,14 +2507,13 @@ void ScummEngine_v7::syncSoundSettings() {
VAR(VAR_CHARINC) = 9 - _defaultTextSpeed;
}
-#ifdef ENABLE_SCUMM_7_8
if (_game.version >= 7 && _imuseDigital) {
_imuseDigital->diMUSESetMusicGroupVol(ConfMan.getInt("music_volume") / 2);
_imuseDigital->diMUSESetVoiceGroupVol(ConfMan.getInt("speech_volume") / 2);
_imuseDigital->diMUSESetSFXGroupVol(ConfMan.getInt("sfx_volume") / 2);
}
-#endif
}
+#endif
void ScummEngine::setTalkSpeed(int talkspeed) {
ConfMan.setInt("talkspeed", (talkspeed * 255 + 9 / 2) / 9);
Commit: 583ea2667f4ac7d13d10e95e1a898385e0796ac5
https://github.com/scummvm/scummvm/commit/583ea2667f4ac7d13d10e95e1a898385e0796ac5
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: Remove unnecessary version check from v7 function
Changed paths:
engines/scumm/scumm.cpp
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 25bd5c5bfc5..8ee6db85093 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -2507,7 +2507,7 @@ void ScummEngine_v7::syncSoundSettings() {
VAR(VAR_CHARINC) = 9 - _defaultTextSpeed;
}
- if (_game.version >= 7 && _imuseDigital) {
+ if (_imuseDigital) {
_imuseDigital->diMUSESetMusicGroupVol(ConfMan.getInt("music_volume") / 2);
_imuseDigital->diMUSESetVoiceGroupVol(ConfMan.getInt("speech_volume") / 2);
_imuseDigital->diMUSESetSFXGroupVol(ConfMan.getInt("sfx_volume") / 2);
Commit: 10e76ae3e6e8f9d2181e6abcf99669bf3d35dcd1
https://github.com/scummvm/scummvm/commit/10e76ae3e6e8f9d2181e6abcf99669bf3d35dcd1
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix Digital iMUSE volume setting.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index d182e56a446..474a70bbfef 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -817,7 +817,10 @@ void MacV6Gui::setVolume(int type, int volume) {
Audio::Mixer::kSpeechSoundType
};
- volume = CLIP(16 * volume, 0, 256);
+ // Input volume comes from the options dialog slider. It's 0-16.
+ // The regular mixer uses 0-256 while Digital iMUSE uses 0-127.
+
+ int mixerVolume = CLIP(16 * volume, 0, 256);
if (_vm->_game.version >= 7) {
#ifdef ENABLE_SCUMM_7_8
@@ -836,10 +839,10 @@ void MacV6Gui::setVolume(int type, int volume) {
}
#endif
} else {
- _vm->_mixer->setVolumeForSoundType(soundTypes[type], volume);
+ _vm->_mixer->setVolumeForSoundType(soundTypes[type], mixerVolume);
}
- ConfMan.setInt(keys[type], volume);
+ ConfMan.setInt(keys[type], mixerVolume);
}
bool MacV6Gui::runOptionsDialog() {
Commit: e88c6fbfba92d9f17903d17b7113aea6e27d9a00
https://github.com/scummvm/scummvm/commit/e88c6fbfba92d9f17903d17b7113aea6e27d9a00
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Don't crash on restart if there is no restart dialog
Full Throttle and The Dig don't have one, for one thing. At the moment,
we just restart without asking. Let's see how annoying that becomes.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index 88ed828f6df..d24724b16c8 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -888,107 +888,108 @@ MacGuiImpl::MacDialogWindow *MacGuiImpl::createDialog(int dialogId, Common::Rect
if (_vm->_game.version >= 6 || _vm->_game.id == GID_MANIAC) {
res = resource.getResource(MKTAG('D', 'I', 'T', 'L'), dialogId);
+ if (!res)
+ return nullptr;
- if (res) {
- saveScreen();
-
- // Collect the palettes from all the icons and pictures
- // in the dialog, and combine them into a single palette
- // that they will all be remapped to use. This is
- // probably not what the original did, as the colors
- // become slightly different. Maybe the original just
- // picked one of the palettes, and then used the
- // closest available colors for the rest?
- //
- // That might explain why some of them have seemingly
- // larger palettes than necessary, but why not use the
- // exact colors when we can?
-
- Common::HashMap<uint32, byte> paletteMap;
- int numWindowColors = 0;
-
- // Additional colors for hard-coded elements
- paletteMap[0xCDCDCD] = numWindowColors++;
-
- int numItems = res->readUint16BE() + 1;
-
- for (int i = 0; i < numItems; i++) {
- res->skip(12);
- int type = res->readByte();
- int len = res->readByte();
-
- Image::PICTDecoder pictDecoder;
- Image::CicnDecoder iconDecoder;
-
- const byte *palette = nullptr;
- int paletteColorCount = 0;
-
- Common::SeekableReadStream *imageRes = nullptr;
- Image::ImageDecoder *decoder = nullptr;
-
- switch (type & 0x7F) {
- case 32:
- imageRes = resource.getResource(MKTAG('c', 'i', 'c', 'n'), res->readUint16BE());
- decoder = &iconDecoder;
- break;
-
- case 64:
- imageRes = resource.getResource(MKTAG('P', 'I', 'C', 'T'), res->readUint16BE());
- decoder = &pictDecoder;
- break;
-
- default:
- res->skip(len);
- break;
- }
+ saveScreen();
- if (imageRes && decoder->loadStream(*imageRes)) {
- palette = decoder->getPalette();
- paletteColorCount = decoder->getPaletteColorCount();
- for (int j = 0; j < paletteColorCount; j++) {
- uint32 color = (palette[3 * j] << 16) | (palette[3 * j + 1] << 8) | palette[3 * j + 2];
- if (!paletteMap.contains(color))
- paletteMap[color] = numWindowColors++;
- }
- }
+ // Collect the palettes from all the icons and pictures in the
+ // dialog, and combine them into a single palette that they
+ // will all be remapped to use. This is probably not what the
+ // original did, as the colors become slightly different. Maybe
+ // the original just picked one of the palettes, and then used
+ // the closest available colors for the rest?
+ //
+ // That might explain why some of them have seemingly larger
+ // palettes than necessary, but why not use the exact colors
+ // when we can?
- if (len & 1)
- res->skip(1);
+ Common::HashMap<uint32, byte> paletteMap;
+ int numWindowColors = 0;
- delete imageRes;
- }
+ // Additional colors for hard-coded elements
+ paletteMap[0xCDCDCD] = numWindowColors++;
+
+ int numItems = res->readUint16BE() + 1;
- delete res;
+ for (int i = 0; i < numItems; i++) {
+ res->skip(12);
+ int type = res->readByte();
+ int len = res->readByte();
- Graphics::Palette palette(256);
- setMacGuiColors(palette);
+ Image::PICTDecoder pictDecoder;
+ Image::CicnDecoder iconDecoder;
- for (auto &k : paletteMap) {
- int r = (k._key >> 16) & 0xFF;
- int g = (k._key >> 8) & 0xFF;
- int b = k._key & 0xFF;
- palette.set(k._value, r, g, b);
- }
+ const byte *palette = nullptr;
+ int paletteColorCount = 0;
- _windowManager->passPalette(palette.data(), 256);
+ Common::SeekableReadStream *imageRes = nullptr;
+ Image::ImageDecoder *decoder = nullptr;
- for (int i = 0; i < 256; i++) {
- byte r, g, b;
+ switch (type & 0x7F) {
+ case 32:
+ imageRes = resource.getResource(MKTAG('c', 'i', 'c', 'n'), res->readUint16BE());
+ decoder = &iconDecoder;
+ break;
+
+ case 64:
+ imageRes = resource.getResource(MKTAG('P', 'I', 'C', 'T'), res->readUint16BE());
+ decoder = &pictDecoder;
+ break;
+
+ default:
+ res->skip(len);
+ break;
+ }
- palette.get(i, r, g, b);
- r = _vm->_macGammaCorrectionLookUp[r];
- g = _vm->_macGammaCorrectionLookUp[g];
- b = _vm->_macGammaCorrectionLookUp[b];
- palette.set(i, r, g, b);
+ if (imageRes && decoder->loadStream(*imageRes)) {
+ palette = decoder->getPalette();
+ paletteColorCount = decoder->getPaletteColorCount();
+ for (int j = 0; j < paletteColorCount; j++) {
+ uint32 color = (palette[3 * j] << 16) | (palette[3 * j + 1] << 8) | palette[3 * j + 2];
+ if (!paletteMap.contains(color))
+ paletteMap[color] = numWindowColors++;
+ }
}
- _system->getPaletteManager()->setPalette(palette);
+ if (len & 1)
+ res->skip(1);
+
+ delete imageRes;
}
- }
- MacDialogWindow *window = createWindow(bounds);
+ delete res;
+
+ Graphics::Palette palette(256);
+ setMacGuiColors(palette);
+
+ for (auto &k : paletteMap) {
+ int r = (k._key >> 16) & 0xFF;
+ int g = (k._key >> 8) & 0xFF;
+ int b = k._key & 0xFF;
+ palette.set(k._value, r, g, b);
+ }
+
+ _windowManager->passPalette(palette.data(), 256);
+
+ for (int i = 0; i < 256; i++) {
+ byte r, g, b;
+
+ palette.get(i, r, g, b);
+ r = _vm->_macGammaCorrectionLookUp[r];
+ g = _vm->_macGammaCorrectionLookUp[g];
+ b = _vm->_macGammaCorrectionLookUp[b];
+ palette.set(i, r, g, b);
+ }
+
+ _system->getPaletteManager()->setPalette(palette);
+ }
res = resource.getResource(MKTAG('D', 'I', 'T', 'L'), dialogId);
+ if (!res)
+ return nullptr;
+
+ MacDialogWindow *window = createWindow(bounds);
if (res) {
int numItems = res->readUint16BE() + 1;
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 474a70bbfef..98c19abf7ab 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -1114,6 +1114,10 @@ bool MacV6Gui::runRestartDialog() {
int dialogId = (_vm->_game.id == GID_MANIAC) ? 193 : 137;
MacDialogWindow *window = createDialog(dialogId);
+ // If there is no dialog, just restart without asking.
+ if (!window)
+ return true;
+
MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
MacStaticText *textWidget = (MacStaticText *)window->getWidget(kWidgetStaticText);
Commit: e848d6b3a75bc506133877398bb2e61da286d7dc
https://github.com/scummvm/scummvm/commit/e848d6b3a75bc506133877398bb2e61da286d7dc
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix interval for text speed sliders
With the exception of Maniac Mansion, the Mac version apparently uses
1-9 instead of 0-9 as the text speed interval.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 98c19abf7ab..403d97a8b84 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -357,7 +357,9 @@ void MacV6Gui::drawDottedFrame(MacDialogWindow *window, Common::Rect bounds, int
}
}
-MacGuiImpl::MacImageSlider *MacV6Gui::addSlider(MacDialogWindow *window, int x, int y, int width, int numMarkings, int primaryMarkings) {
+MacGuiImpl::MacImageSlider *MacV6Gui::addSlider(MacDialogWindow *window, int x, int y, int width, int minValue, int maxValue, int primaryMarkings) {
+ int numMarkings = (maxValue - minValue) + 1;
+
Graphics::Surface *s = window->innerSurface();
uint32 gray = _windowManager->findBestColor(0xCD, 0xCD, 0xCD);
@@ -384,7 +386,7 @@ MacGuiImpl::MacImageSlider *MacV6Gui::addSlider(MacDialogWindow *window, int x,
MacImageSlider *slider = window->addImageSlider(Common::Rect(x - 6, y - 4, x + width + 7, y + 16), handle, true, 0, width - 1, 0, numMarkings - 1);
for (int i = 0; i < numMarkings; i++)
- slider->addStop(positions[i], i);
+ slider->addStop(positions[i], minValue + i);
slider->setSnapWhileDragging(true);
slider->setValue(0);
@@ -901,29 +903,29 @@ bool MacV6Gui::runOptionsDialog() {
drawDottedFrame(window, Common::Rect(12, 41, 337, 113), 21, 137);
drawDottedFrame(window, Common::Rect(11, 130, 336, 203), 20, 168);
- sliderMusicVolume = addSlider(window, 152, 63, 147, 17);
- sliderVoiceVolume = addSlider(window, 152, 87, 147, 17);
- sliderTextSpeed = addSlider(window, 151, 177, 147, 9);
+ sliderMusicVolume = addSlider(window, 152, 63, 147, 0, 16);
+ sliderVoiceVolume = addSlider(window, 152, 87, 147, 0, 16);
+ sliderTextSpeed = addSlider(window, 151, 177, 147, 1, 9);
} else if (_vm->_game.id == GID_MANIAC) {
- sliderMusicVolume = addSlider(window, 152, 41, 147, 17);
- sliderTextSpeed = addSlider(window, 152, 72, 147, 10, 5);
+ sliderMusicVolume = addSlider(window, 152, 41, 147, 0, 16);
+ sliderTextSpeed = addSlider(window, 152, 72, 147, 0, 9, 5);
} else if (_vm->_game.id == GID_SAMNMAX || _vm->_game.id == GID_DIG) {
drawDottedFrame(window, Common::Rect(12, 41, 337, 136), 21, 137);
drawDottedFrame(window, Common::Rect(12, 156, 337, 229), 20, 168);
- sliderMusicVolume = addSlider(window, 152, 63, 147, 17);
- sliderEffectVolume = addSlider(window, 152, 87, 147, 17);
- sliderVoiceVolume = addSlider(window, 152, 111, 147, 17);
- sliderTextSpeed = addSlider(window, 152, 203, 147, 9);
+ sliderMusicVolume = addSlider(window, 152, 63, 147, 0, 16);
+ sliderEffectVolume = addSlider(window, 152, 87, 147, 0, 16);
+ sliderVoiceVolume = addSlider(window, 152, 111, 147, 0, 16);
+ sliderTextSpeed = addSlider(window, 152, 203, 147, 1, 9);
#ifdef ENABLE_SCUMM_7_8
} else if (_vm->_game.id == GID_FT) {
drawDottedFrame(window, Common::Rect(12, 41, 337, 164), 21, 137);
drawDottedFrame(window, Common::Rect(12, 184, 337, 257), 20, 168);
- sliderMusicVolume = addSlider(window, 152, 63, 147, 17);
- sliderEffectVolume = addSlider(window, 152, 87, 147, 17);
- sliderVoiceVolume = addSlider(window, 152, 111, 147, 17);
- sliderTextSpeed = addSlider(window, 152, 231, 147, 9);
+ sliderMusicVolume = addSlider(window, 152, 63, 147, 0, 16);
+ sliderEffectVolume = addSlider(window, 152, 87, 147, 0, 16);
+ sliderVoiceVolume = addSlider(window, 152, 111, 147, 0, 16);
+ sliderTextSpeed = addSlider(window, 152, 231, 147, 1, 9);
checkboxSpoolMusic = (MacCheckbox *)window->getWidget(kWidgetCheckbox, 0);
#endif
@@ -1005,7 +1007,9 @@ bool MacV6Gui::runOptionsDialog() {
setVolume(2, voiceVolume);
}
- // FIXME: DOS versions use 0-9, Mac versions... 0-8? 1-9?
+ // The DOS version uses 0-9. Apparently the Mac version
+ // uses 1-9 instead, except for Maniac Mansion.
+
_vm->_defaultTextSpeed = sliderTextSpeed->getValue();
ConfMan.setInt("original_gui_text_speed", _vm->_defaultTextSpeed);
_vm->setTalkSpeed(_vm->_defaultTextSpeed);
@@ -1048,7 +1052,7 @@ bool MacV6Gui::runOptionsDialog() {
if (popUpInteraction)
popUpInteraction->setValue(1);
if (sliderTextSpeed)
- sliderTextSpeed->setValue(4);
+ sliderTextSpeed->setValue((_vm->_game.id == GID_MANIAC) ? 4 : 5);
#ifdef ENABLE_SCUMM_7_8
if (checkboxSpoolMusic)
checkboxSpoolMusic->setValue(1);
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index ce64fe1ab6e..b5c8aa5a014 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -76,7 +76,7 @@ protected:
void drawDottedFrame(MacDialogWindow *window, Common::Rect bounds, int x1, int x2);
- MacGuiImpl::MacImageSlider *addSlider(MacDialogWindow *window, int x, int y, int width, int numMarkings, int primaryMarkings = 4);
+ MacGuiImpl::MacImageSlider *addSlider(MacDialogWindow *window, int x, int y, int width, int minValue, int maxValue, int primaryMarkings = 4);
void setVolume(int type, int volume);
Commit: ba6b348cf59c186f9006b7e234558e26fa25fc53
https://github.com/scummvm/scummvm/commit/ba6b348cf59c186f9006b7e234558e26fa25fc53
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Word wrap static text widgets by default
This simplifies support for translated versions of v6-7 games where
apparently they sometimes kept the English texts and just added another
text on top of it.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index d24724b16c8..fec67862bc0 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -1273,9 +1273,6 @@ bool MacGuiImpl::runOkCancelDialog(Common::String text) {
MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
- MacStaticText *textWidget = (MacStaticText *)window->getWidget(kWidgetStaticText);
-
- textWidget->setWordWrap(true);
window->setDefaultWidget(buttonOk);
window->addSubstitution(text);
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index be9dbfa8844..8c70b5d2395 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -371,7 +371,7 @@ public:
uint32 _fg;
uint32 _bg;
Graphics::TextAlign _alignment = Graphics::kTextAlignLeft;
- bool _wordWrap = false;
+ bool _wordWrap = true;
public:
MacStaticText(
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 403d97a8b84..910a2aac1a0 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -420,12 +420,6 @@ void MacV6Gui::runAboutDialog() {
window->setDefaultWidget(buttonOk);
- for (uint i = 0; i < window->getNumWidgets(); i++) {
- MacWidget *widget = window->getWidget(i);
- if (widget->getType() == kWidgetStaticText)
- ((MacStaticText *)widget)->setWordWrap(true);
- }
-
while (!_vm->shouldQuit()) {
MacDialogEvent event;
@@ -1079,9 +1073,6 @@ bool MacV6Gui::runQuitDialog() {
MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
- MacStaticText *textWidget = (MacStaticText *)window->getWidget(kWidgetStaticText);
-
- textWidget->setWordWrap(true);
window->setDefaultWidget(buttonOk);
@@ -1124,9 +1115,6 @@ bool MacV6Gui::runRestartDialog() {
MacButton *buttonOk = (MacButton *)window->getWidget(kWidgetButton, 0);
MacButton *buttonCancel = (MacButton *)window->getWidget(kWidgetButton, 1);
- MacStaticText *textWidget = (MacStaticText *)window->getWidget(kWidgetStaticText);
-
- textWidget->setWordWrap(true);
window->setDefaultWidget(buttonOk);
Commit: 8189e255207d24073e0f35395f3fce371ae1f449
https://github.com/scummvm/scummvm/commit/8189e255207d24073e0f35395f3fce371ae1f449
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Save v6-7 subtitle/voice settings from options dialog
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 910a2aac1a0..91066fa7142 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -1024,12 +1024,25 @@ bool MacV6Gui::runOptionsDialog() {
}
#endif
- // TODO: Save "interact using"
+ if (popUpInteraction) {
+ switch (popUpInteraction->getValue()) {
+ case 0: // Text Only
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", true);
+ break;
+ case 1: // Voice Only
+ ConfMan.setBool("subtitles", false);
+ ConfMan.setBool("speech_mute", false);
+ break;
+ case 2: // Text & Voice
+ ConfMan.setBool("subtitles", true);
+ ConfMan.setBool("speech_mute", false);
+ break;
+ }
+ }
ConfMan.flushToDisk();
-
- if (_vm->_game.version < 7)
- _vm->syncSoundSettings();
+ _vm->syncSoundSettings();
delete window;
return true;
Commit: 16fa744d9a8da9fb72e33dfd6f19813c3c0e3578
https://github.com/scummvm/scummvm/commit/16fa744d9a8da9fb72e33dfd6f19813c3c0e3578
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Implement "Resume Game"
That was easy! bringing up the Mac menu pauses the game, and "to resume
playing again, choose Resume Game from he Game menu, or simply click the
mouse somewhere away from the menubar."
Well, we don't do the latter. But doing the former is just a matter of
doing... well, nothing.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 91066fa7142..23d88cf35d9 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -160,7 +160,8 @@ bool MacV6Gui::handleMenu(int id, Common::String &name) {
return true;
case 203:
- debug("Resume");
+ // Resume is supposed to simply close the Mac menu, and that
+ // happens automatically when selecting any menu item.
return true;
case 204: // Restart
Commit: 71f592d5c5cc1c44ac4f863b44999e7aa09a2ac0
https://github.com/scummvm/scummvm/commit/71f592d5c5cc1c44ac4f863b44999e7aa09a2ac0
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: Hopefully fix pausing of SMUSH movies
Primarily for the Mac GUI, where the sound would pause but the movie
would keep playing. There's still something awkward about bringing up
the Mac GUI during Full Throttle's biker fights, but once they're there
they seem to work fine.
Changed paths:
engines/scumm/smush/smush_player.cpp
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 613873cf238..3b2ec5ae311 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -1239,42 +1239,46 @@ void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 st
int skipped = 0;
for (;;) {
- uint32 now, elapsed;
bool skipFrame = false;
- if (_insanity) {
- // Seeking makes a mess of trying to sync the audio to
- // the sound. Sync to time instead.
- now = _vm->_system->getMillis() - _pauseTime;
- elapsed = now - _startTime;
- } else if (_vm->_mixer->isSoundHandleActive(*_compressedFileSoundHandle)) {
- // Compressed SMUSH files.
- elapsed = _vm->_mixer->getSoundElapsedTime(*_compressedFileSoundHandle);
- } else if (_vm->_mixer->isSoundHandleActive(*_IACTchannel)) {
- // Curse of Monkey Island SMUSH files.
- elapsed = _vm->_mixer->getSoundElapsedTime(*_IACTchannel);
- } else {
- // For other SMUSH files, we don't necessarily have any
- // one channel to sync against, so we have to use
- // elapsed real time.
- now = _vm->_system->getMillis() - _pauseTime;
- elapsed = now - _startTime;
- }
+ if (!_paused) {
+ uint32 now, elapsed;
+
+ if (_insanity) {
+ // Seeking makes a mess of trying to sync the audio to
+ // the sound. Sync to time instead.
+ now = _vm->_system->getMillis() - _pauseTime;
+ elapsed = now - _startTime;
+ } else if (_vm->_mixer->isSoundHandleActive(*_compressedFileSoundHandle)) {
+ // Compressed SMUSH files.
+ elapsed = _vm->_mixer->getSoundElapsedTime(*_compressedFileSoundHandle);
+ } else if (_vm->_mixer->isSoundHandleActive(*_IACTchannel)) {
+ // Curse of Monkey Island SMUSH files.
+ elapsed = _vm->_mixer->getSoundElapsedTime(*_IACTchannel);
+ } else {
+ // For other SMUSH files, we don't necessarily have any
+ // one channel to sync against, so we have to use
+ // elapsed real time.
+ now = _vm->_system->getMillis() - _pauseTime;
+ elapsed = now - _startTime;
+ }
- if (elapsed >= ((_frame - _startFrame) * 1000) / _speed) {
- if (elapsed >= ((_frame + 1) * 1000) / _speed)
- skipFrame = true;
- else
- skipFrame = false;
- timerCallback();
- }
+ if (elapsed >= ((_frame - _startFrame) * 1000) / _speed) {
+ if (elapsed >= ((_frame + 1) * 1000) / _speed)
+ skipFrame = true;
+ else
+ skipFrame = false;
+ timerCallback();
+ }
- _vm->scummLoop_handleSound();
+ _vm->scummLoop_handleSound();
- if (_warpNeeded) {
- _vm->_system->warpMouse(_vm->_macScreen ? _warpX * 2 : _warpX, _vm->_macScreen ? (_warpY * 2 + 2 * _vm->_macScreenDrawOffset) : _warpY);
- _warpNeeded = false;
+ if (_warpNeeded) {
+ _vm->_system->warpMouse(_vm->_macScreen ? _warpX * 2 : _warpX, _vm->_macScreen ? (_warpY * 2 + 2 * _vm->_macScreenDrawOffset) : _warpY);
+ _warpNeeded = false;
+ }
}
+
_vm->parseEvents();
_vm->processInput();
if (_palDirtyMax >= _palDirtyMin) {
@@ -1331,8 +1335,10 @@ void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 st
break;
}
- if (_vm->_macGui)
+ if (_vm->_macGui) {
_vm->_macGui->updateWindowManager();
+ _vm->_system->updateScreen();
+ }
_vm->_system->delayMillis(10);
}
Commit: b999d69ef4cea7e28cd5361cd8edc3f5bb8a375d
https://github.com/scummvm/scummvm/commit/b999d69ef4cea7e28cd5361cd8edc3f5bb8a375d
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix v6-7 slider widgets that don't start at 0
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 23d88cf35d9..77076597708 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -384,13 +384,13 @@ MacGuiImpl::MacImageSlider *MacV6Gui::addSlider(MacDialogWindow *window, int x,
}
MacImage *handle = window->addIcon(x - 6, y - 4, 300, true);
- MacImageSlider *slider = window->addImageSlider(Common::Rect(x - 6, y - 4, x + width + 7, y + 16), handle, true, 0, width - 1, 0, numMarkings - 1);
+ MacImageSlider *slider = window->addImageSlider(Common::Rect(x - 6, y - 4, x + width + 7, y + 16), handle, true, 0, width - 1, minValue, maxValue);
for (int i = 0; i < numMarkings; i++)
slider->addStop(positions[i], minValue + i);
slider->setSnapWhileDragging(true);
- slider->setValue(0);
+ slider->setValue(minValue);
delete[] positions;
return slider;
Commit: 76f33960c27169c81fe48bd13437e4a3efd56529
https://github.com/scummvm/scummvm/commit/76f33960c27169c81fe48bd13437e4a3efd56529
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: Prevent SMUSH palette changes and screen updates while paused
Perhaps this will fix the remaining Mac GUI SMUSH glitch?
Changed paths:
engines/scumm/smush/smush_player.cpp
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 3b2ec5ae311..30c35b4c89d 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -1281,48 +1281,52 @@ void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 st
_vm->parseEvents();
_vm->processInput();
- if (_palDirtyMax >= _palDirtyMin) {
- // Apply gamma correction for Mac versions
- if (_vm->_macScreen) {
- byte palette[768];
- memcpy(palette, _pal, 768);
- for (int i = 0; i < ARRAYSIZE(palette); i++) {
- palette[i] = _vm->_macGammaCorrectionLookUp[_pal[i]];
- }
- _vm->_system->getPaletteManager()->setPalette(palette + _palDirtyMin * 3, _palDirtyMin, _palDirtyMax - _palDirtyMin + 1);
- } else {
- _vm->_system->getPaletteManager()->setPalette(_pal + _palDirtyMin * 3, _palDirtyMin, _palDirtyMax - _palDirtyMin + 1);
- }
+ if (!_paused) {
+ if (_palDirtyMax >= _palDirtyMin) {
+ // Apply gamma correction for Mac versions
+ if (_vm->_macScreen) {
+ byte palette[768];
+ memcpy(palette, _pal, 768);
+ for (int i = 0; i < ARRAYSIZE(palette); i++) {
+ palette[i] = _vm->_macGammaCorrectionLookUp[_pal[i]];
+ }
- _palDirtyMax = -1;
- _palDirtyMin = 256;
- skipFrame = false;
- }
- if (skipFrame) {
- if (++skipped > 10) {
+ _vm->_system->getPaletteManager()->setPalette(palette + _palDirtyMin * 3, _palDirtyMin, _palDirtyMax - _palDirtyMin + 1);
+ } else {
+ _vm->_system->getPaletteManager()->setPalette(_pal + _palDirtyMin * 3, _palDirtyMin, _palDirtyMax - _palDirtyMin + 1);
+ }
+
+ _palDirtyMax = -1;
+ _palDirtyMin = 256;
skipFrame = false;
- skipped = 0;
}
- } else
- skipped = 0;
- if (_updateNeeded) {
- if (!skipFrame) {
- // WORKAROUND for bug #2415: "FT DEMO: assertion triggered
- // when playing movie". Some frames there are 384 x 224
- int frameWidth = MIN(_width, _vm->_screenWidth);
- int frameHeight = MIN(_height, _vm->_screenHeight);
-
- if (_vm->_macScreen) {
- _vm->mac_drawBufferToScreen(_dst, frameWidth, 0, 0, frameWidth, frameHeight);
- } else {
- _vm->_system->copyRectToScreen(_dst, _width, 0, 0, frameWidth, frameHeight);
+ if (skipFrame) {
+ if (++skipped > 10) {
+ skipFrame = false;
+ skipped = 0;
}
+ } else
+ skipped = 0;
+ if (_updateNeeded) {
+ if (!skipFrame) {
+ // WORKAROUND for bug #2415: "FT DEMO: assertion triggered
+ // when playing movie". Some frames there are 384 x 224
+ int frameWidth = MIN(_width, _vm->_screenWidth);
+ int frameHeight = MIN(_height, _vm->_screenHeight);
+
+ if (_vm->_macScreen) {
+ _vm->mac_drawBufferToScreen(_dst, frameWidth, 0, 0, frameWidth, frameHeight);
+ } else {
+ _vm->_system->copyRectToScreen(_dst, _width, 0, 0, frameWidth, frameHeight);
+ }
- _vm->_system->updateScreen();
- _updateNeeded = false;
+ _vm->_system->updateScreen();
+ _updateNeeded = false;
+ }
}
}
+
if (_endOfFile)
break;
if (_vm->shouldQuit() || _vm->_saveLoadFlag || _vm->_smushVideoShouldFinish) {
Commit: d192e864f1df74261774aafb87d5ac66ea00b970
https://github.com/scummvm/scummvm/commit/d192e864f1df74261774aafb87d5ac66ea00b970
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Suppress Mac GUI if a message banner is active
This is similar to the fix we already had for Loom and Last Crusade,
except now we also look for the SCUMM engine's own message banners.
Changed paths:
engines/scumm/macgui/macgui_impl.cpp
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index fec67862bc0..ba07b3afd74 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -115,7 +115,7 @@ bool MacGuiImpl::handleEvent(Common::Event event) {
// The situation we're trying to avoid here is the user opening e.g.
// the save dialog using keyboard shortcuts while the game is paused.
- if (_bannerWindow)
+ if (_bannerWindow || _vm->_messageBannerActive)
return false;
return _windowManager->processEvent(event);
Commit: a1db6d8f6d0bc6fe050c9acfcaa692a337c165d3
https://github.com/scummvm/scummvm/commit/a1db6d8f6d0bc6fe050c9acfcaa692a337c165d3
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
IMAGE: Make the mask a Surface instead of a buffer
This is consistent with other masking.
Changed paths:
engines/scumm/macgui/macgui_dialogwindow.cpp
engines/scumm/macgui/macgui_impl.cpp
engines/scumm/macgui/macgui_impl.h
engines/scumm/macgui/macgui_widgets.cpp
image/cicn.cpp
image/cicn.h
image/image_decoder.h
diff --git a/engines/scumm/macgui/macgui_dialogwindow.cpp b/engines/scumm/macgui/macgui_dialogwindow.cpp
index bb4b10eb110..07ad2055a66 100644
--- a/engines/scumm/macgui/macgui_dialogwindow.cpp
+++ b/engines/scumm/macgui/macgui_dialogwindow.cpp
@@ -269,10 +269,15 @@ MacGuiImpl::MacEditText *MacGuiImpl::MacDialogWindow::addEditText(Common::Rect b
}
MacGuiImpl::MacImage *MacGuiImpl::MacDialogWindow::addIcon(int x, int y, int id, bool enabled) {
- MacImageMask *mask;
- Graphics::Surface *icon = _gui->loadIcon(id, &mask);
- MacGuiImpl::MacImage *image = new MacImage(this, Common::Rect(x, y, x + icon->w, y + icon->h), icon, mask, false);
- addWidget(image, kWidgetIcon);
+ Graphics::Surface *icon = nullptr;
+ Graphics::Surface *mask = nullptr;
+ MacGuiImpl::MacImage *image = nullptr;
+
+ if (_gui->loadIcon(id, &icon, &mask)) {
+ image = new MacImage(this, Common::Rect(x, y, x + icon->w, y + icon->h), icon, mask, false);
+ addWidget(image, kWidgetIcon);
+ }
+
return image;
}
@@ -801,12 +806,12 @@ MacGuiImpl::MacWidget *MacGuiImpl::MacDialogWindow::getWidget(MacWidgetType type
void MacGuiImpl::MacDialogWindow::drawSprite(const MacImage *image, int x, int y) {
const Graphics::Surface *surface = image->getImage();
- const MacImageMask *mask = image->getMask();
+ const Graphics::Surface *mask = image->getMask();
if (mask) {
for (int y1 = 0; y1 < mask->h; y1++) {
for (int x1 = 0; x1 < mask->w; x1++) {
- if (!mask->isMasked(x1, y1))
+ if (mask->getPixel(x1, y1) == 255)
_innerSurface.setPixel(x + x1, y + y1, surface->getPixel(x1, y1));
}
}
diff --git a/engines/scumm/macgui/macgui_impl.cpp b/engines/scumm/macgui/macgui_impl.cpp
index ba07b3afd74..0539b12bcd2 100644
--- a/engines/scumm/macgui/macgui_impl.cpp
+++ b/engines/scumm/macgui/macgui_impl.cpp
@@ -712,7 +712,8 @@ Graphics::Surface *MacGuiImpl::createRemappedSurface(const Graphics::Surface *su
// Icon loader
// ---------------------------------------------------------------------------
-Graphics::Surface *MacGuiImpl::loadIcon(int id, MacImageMask **mask) {
+bool MacGuiImpl::loadIcon(int id, Graphics::Surface **icon, Graphics::Surface **mask) {
+ bool result = false;
Common::MacResManager resource;
resource.open(_resourceFile);
@@ -720,30 +721,25 @@ Graphics::Surface *MacGuiImpl::loadIcon(int id, MacImageMask **mask) {
Common::SeekableReadStream *res = resource.getResource(MKTAG('c', 'i', 'c', 'n'), id);
Image::CicnDecoder iconDecoder;
- Graphics::Surface *s = nullptr;
+
+ *icon = nullptr;
+ *mask = nullptr;
if (res && iconDecoder.loadStream(*res)) {
- const Graphics::Surface *surface = iconDecoder.getSurface();
+ result = true;
+ const Graphics::Surface *s1 = iconDecoder.getSurface();
+ const Graphics::Surface *s2 = iconDecoder.getMask();
const byte *palette = iconDecoder.getPalette();
- if (iconDecoder.hasMask()) {
- *mask = new MacImageMask();
- uint maskSize = iconDecoder.getMaskRowBytes() * iconDecoder.getMaskHeight();
- (*mask)->w = surface->w;
- (*mask)->h = iconDecoder.getMaskHeight();
- (*mask)->rowBytes = iconDecoder.getMaskRowBytes();
-
- (*mask)->data = new byte[maskSize];
- memcpy((*mask)->data, iconDecoder.getMask(), maskSize);
- }
-
- s = createRemappedSurface(surface, palette, iconDecoder.getPaletteColorCount());
+ *icon = createRemappedSurface(s1, palette, iconDecoder.getPaletteColorCount());
+ *mask = new Graphics::Surface();
+ (*mask)->copyFrom(*s2);
}
delete res;
resource.close();
- return s;
+ return result;
}
// ---------------------------------------------------------------------------
diff --git a/engines/scumm/macgui/macgui_impl.h b/engines/scumm/macgui/macgui_impl.h
index 8c70b5d2395..5bcca04937c 100644
--- a/engines/scumm/macgui/macgui_impl.h
+++ b/engines/scumm/macgui/macgui_impl.h
@@ -449,34 +449,17 @@ public:
void handleMouseMove(Common::Event &event) override;
};
- struct MacImageMask {
- uint16 w;
- uint16 h;
- uint16 rowBytes;
- byte *data;
-
- bool isMasked(int x, int y) const {
- if (x < 0 || x >= w || y < 0 || y >= h)
- return false;
- return (data[y * rowBytes + x / 8] & (0x80 >> (x % 8))) == 0;
- }
- };
-
class MacImage : public MacWidget {
private:
Graphics::Surface *_image = nullptr;
- uint16 _maskRowBytes = 0;
- uint16 _maskHeight = 0;
- const MacImageMask *_mask = nullptr;
+ Graphics::Surface *_mask = nullptr;
public:
- MacImage(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Graphics::Surface *surface, MacImageMask *mask, bool enabled);
+ MacImage(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Graphics::Surface *surface, Graphics::Surface *mask, bool enabled);
~MacImage();
Graphics::Surface *getImage() const { return _image; }
- const MacImageMask *getMask() const { return _mask; }
- uint16 getMaskRowBytes() const { return _maskRowBytes; }
- uint16 getMaskHeight() const { return _maskHeight; }
+ Graphics::Surface *getMask() const { return _mask; }
void draw(bool drawFocused = false) override;
};
@@ -826,7 +809,7 @@ public:
const Graphics::Font *getFont(FontId fontId);
virtual const Graphics::Font *getFontByScummId(int32 id) = 0;
- Graphics::Surface *loadIcon(int id, MacImageMask **mask);
+ bool loadIcon(int id, Graphics::Surface **icon, Graphics::Surface **mask);
Graphics::Surface *loadPict(int id);
virtual bool isVerbGuiActive() const { return false; }
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index ccaa0fe3f9b..8c5d165b092 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -807,7 +807,7 @@ void MacGuiImpl::MacEditText::handleMouseMove(Common::Event &event) {
// Image widget
// ---------------------------------------------------------------------------
-MacGuiImpl::MacImage::MacImage(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Graphics::Surface *surface, MacImageMask *mask, bool enabled) : MacWidget(window, bounds, "Picture", enabled) {
+MacGuiImpl::MacImage::MacImage(MacGuiImpl::MacDialogWindow *window, Common::Rect bounds, Graphics::Surface *surface, Graphics::Surface *mask, bool enabled) : MacWidget(window, bounds, "Picture", enabled) {
_image = surface;
_mask = mask;
}
@@ -818,7 +818,7 @@ MacGuiImpl::MacImage::~MacImage() {
delete _image;
}
if (_mask) {
- delete[] _mask->data;
+ _mask->free();
delete _mask;
}
}
diff --git a/image/cicn.cpp b/image/cicn.cpp
index 1dd51f92d90..b7c05648e9d 100644
--- a/image/cicn.cpp
+++ b/image/cicn.cpp
@@ -34,8 +34,6 @@ CicnDecoder::CicnDecoder() {
_palette = nullptr;
_paletteColorCount = 0;
_mask = nullptr;
- _maskRowBytes = 0;
- _maskHeight = 0;
}
CicnDecoder::~CicnDecoder() {
@@ -53,10 +51,11 @@ void CicnDecoder::destroy() {
_palette = nullptr;
_paletteColorCount = 0;
- delete[] _mask;
- _mask = nullptr;
- _maskRowBytes = 0;
- _maskHeight = 0;
+ if (_mask) {
+ _mask->free();
+ delete _mask;
+ _mask = nullptr;
+ }
}
@@ -68,11 +67,11 @@ bool CicnDecoder::loadStream(Common::SeekableReadStream &stream) {
// Mask header
stream.skip(4);
- _maskRowBytes = stream.readUint16BE();
+ uint16 maskRowBytes = stream.readUint16BE();
stream.readUint16BE(); // top
stream.readUint16BE(); // left
- _maskHeight = stream.readUint16BE(); // bottom
- stream.readUint16BE(); // right
+ uint16 maskHeight = stream.readUint16BE(); // bottom
+ uint16 maskWidth = stream.readUint16BE(); // right
// Bitmap header
stream.skip(4);
@@ -85,9 +84,23 @@ bool CicnDecoder::loadStream(Common::SeekableReadStream &stream) {
// Mask and bitmap data
stream.skip(4);
- if (_maskRowBytes && _maskHeight) {
- _mask = new byte[_maskRowBytes * _maskHeight];
- stream.read(_mask, _maskRowBytes * _maskHeight);
+ if (maskRowBytes && maskHeight) {
+ _mask = new Graphics::Surface();
+ _mask->create(maskWidth, maskHeight, Graphics::PixelFormat::createFormatCLUT8());
+
+ byte *mask = new byte[maskRowBytes * maskHeight];
+ stream.read(mask, maskRowBytes * maskHeight);
+
+ for (uint y = 0; y < maskHeight; y++) {
+ for (uint x = 0; x < maskWidth; x++) {
+ if ((mask[y * maskRowBytes + x / 8] & (0x80 >> (x % 8))) == 0)
+ _mask->setPixel(x, y, 0);
+ else
+ _mask->setPixel(x, y, 255);
+ }
+ }
+
+ delete[] mask;
}
stream.skip(bitmapRowBytes * bitmapHeight);
diff --git a/image/cicn.h b/image/cicn.h
index 1de4a394035..44475748691 100644
--- a/image/cicn.h
+++ b/image/cicn.h
@@ -48,17 +48,13 @@ public:
const Graphics::Surface *getSurface() const override { return _surface; }
const byte *getPalette() const override { return _palette; }
uint16 getPaletteColorCount() const override { return _paletteColorCount; }
- const byte *getMask() const override { return _mask; }
- virtual uint16 getMaskRowBytes() const override { return _maskRowBytes; }
- virtual uint16 getMaskHeight() const override { return _maskHeight; }
+ const Graphics::Surface *getMask() const override { return _mask; }
private:
Graphics::Surface *_surface;
byte *_palette;
uint16 _paletteColorCount;
- byte *_mask;
- uint16 _maskRowBytes;
- uint16 _maskHeight;
+ Graphics::Surface *_mask;
};
/** @} */
diff --git a/image/image_decoder.h b/image/image_decoder.h
index 4393b28c57c..7242f1684c5 100644
--- a/image/image_decoder.h
+++ b/image/image_decoder.h
@@ -117,7 +117,7 @@ public:
/**
* Get the mask data for the decoded image.
*/
- virtual const byte *getMask() const { return 0; }
+ virtual const Graphics::Surface *getMask() const { return 0; }
/**
* Query whether the decoded image has a palette.
Commit: 13263586e82c01cd5a345582522a624289a20fdb
https://github.com/scummvm/scummvm/commit/13263586e82c01cd5a345582522a624289a20fdb
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Don't erase slider handle before it's been drawn
Changed paths:
engines/scumm/macgui/macgui_widgets.cpp
diff --git a/engines/scumm/macgui/macgui_widgets.cpp b/engines/scumm/macgui/macgui_widgets.cpp
index 8c5d165b092..81fd5e58a68 100644
--- a/engines/scumm/macgui/macgui_widgets.cpp
+++ b/engines/scumm/macgui/macgui_widgets.cpp
@@ -1350,6 +1350,9 @@ void MacGuiImpl::MacImageSlider::draw(bool drawFocused) {
}
void MacGuiImpl::MacImageSlider::eraseHandle() {
+ if (_handlePos == -1)
+ return;
+
Common::Rect r = _handle->getBounds();
int y = r.top - _bounds.top;
int w = r.width();
Commit: 3745e51b01828295bf3036f80aaf3e92583b50d4
https://github.com/scummvm/scummvm/commit/3745e51b01828295bf3036f80aaf3e92583b50d4
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
IMAGE: Remove unnecessary mask-related methods
Changed paths:
image/image_decoder.h
diff --git a/image/image_decoder.h b/image/image_decoder.h
index 7242f1684c5..9cf74bfdce6 100644
--- a/image/image_decoder.h
+++ b/image/image_decoder.h
@@ -120,15 +120,9 @@ public:
virtual const Graphics::Surface *getMask() const { return 0; }
/**
- * Query whether the decoded image has a palette.
+ * Query whether the decoded image has a mask.
*/
- virtual bool hasMask() const { return getMaskRowBytes() != 0 && getMaskHeight() != 0; }
-
- /** Return the number of bytes per row in the mask */
- virtual uint16 getMaskRowBytes() const { return 0; }
-
- /** Return the height of the mask */
- virtual uint16 getMaskHeight() const { return 0; }
+ virtual bool hasMask() const { return getMask() != 0; }
};
/** @} */
} // End of namespace Image
Commit: 30b6acf9aa0f9bd3dac40716ea064e8145789dfd
https://github.com/scummvm/scummvm/commit/30b6acf9aa0f9bd3dac40716ea064e8145789dfd
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Adapted better color quantizer from Dr. Dobb's
This should be in graphics, not engines/scumm/macgui but I'm keeping it
here for now to avoid conflict, because there's been some activity in
graphics lately.
Changed paths:
engines/scumm/macgui/macgui_v6.cpp
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_v6.cpp b/engines/scumm/macgui/macgui_v6.cpp
index 77076597708..32980e606bf 100644
--- a/engines/scumm/macgui/macgui_v6.cpp
+++ b/engines/scumm/macgui/macgui_v6.cpp
@@ -527,18 +527,6 @@ void MacV6Gui::runAboutDialog() {
token.clear();
}
-struct colorInfo {
- uint32 color;
- uint16 count;
-};
-
-static int compareColorInfo(const void *p1, const void *p2) {
- int c1 = ((const colorInfo *)p1)->count;
- int c2 = ((const colorInfo *)p2)->count;
-
- return c2 - c1;
-}
-
void MacV6Gui::updateThumbnail(MacDialogWindow *window, Common::Rect drawArea, int saveSlot) {
if (_vm->_game.id == GID_MANIAC)
return;
@@ -563,16 +551,10 @@ void MacV6Gui::updateThumbnail(MacDialogWindow *window, Common::Rect drawArea, i
Common::Rect thumbnailRect(0, yMin, drawArea.width(), yMax);
// We don't know in advance how many colors the thumbnail is going to
- // use. Reduce the image to a smaller palette.
- //
- // I'm not going to do any fancy color quantization here. Maybe if one
- // is added to the ScummVM common code, but not just for this.
- //
- // The thumbnail is asserted to be 160x100 pixels. We know it started
- // out with at most 256 colors, and that any further colors were added
- // when scaling it down, and are presumably close to the original ones.
- // Even in the most pathological case, there will never be more than
- // 16,000 distinct colors.
+ // use. Reduce the image to a smaller palette. We reserve 10 colors for
+ // the Mac GUI itself.
+
+ ColorQuantizer quantizer(245);
for (int y = yMin; y < yMax; y++) {
for (int x = 0; x < thumbnail->w; x++) {
@@ -581,43 +563,17 @@ void MacV6Gui::updateThumbnail(MacDialogWindow *window, Common::Rect drawArea, i
byte r, g, b;
thumbnail->format.colorToRGB(color, r, g, b);
- // If the color wasn't 565 before, make it so
- color = ((r << 16) | (g << 8) | b) & 0xF8FCF8;
-
- paletteMap[color]++;
+ quantizer.addColor(r, g, b);
}
}
- colorInfo *colors = new colorInfo[paletteMap.size()];
- int count = 0;
-
- for (auto &k : paletteMap) {
- colors[count].color = k._key;
- colors[count].count = k._value;
- count++;
- }
-
- qsort(colors, count, sizeof(colorInfo), compareColorInfo);
-
- // Pick the - at most - 246 most popular colors. Note that we do not
- // gamma correct them. They presumably already were when the thumbnail
- // was created.
-
- int numColors = MIN(count, 246);
- Graphics::Palette palette(numColors);
-
- for (int i = 0; i < numColors; i++) {
- int r = ((colors[i].color) >> 16) & 0xFF;
- int g = ((colors[i].color) >> 8) & 0xFF;
- int b = (colors[i].color) & 0xFF;
+ Graphics::Palette *palette = quantizer.getPalette();
+ _system->getPaletteManager()->setPalette(*palette);
+ delete palette;
- palette.set(i, r, g, b);
- }
-
- delete[] colors;
- _system->getPaletteManager()->setPalette(palette);
+ Graphics::Palette fullPalette = _system->getPaletteManager()->grabPalette(0, 256);
- Graphics::Surface *palettedThumbnail = thumbnail->convertTo(window->innerSurface()->format, nullptr, 0, palette.data(), palette.size());
+ Graphics::Surface *palettedThumbnail = thumbnail->convertTo(window->innerSurface()->format, nullptr, 0, fullPalette.data(), fullPalette.size());
window->innerSurface()->copyRectToSurface(*palettedThumbnail, drawArea.left, drawArea.top, thumbnailRect);
window->markRectAsDirty(drawArea);
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index b5c8aa5a014..3c8029333d9 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -26,6 +26,9 @@
#include "common/rect.h"
#include "common/str.h"
+// For the color quantizer
+#include "common/stack.h"
+
namespace Scumm {
class MacGuiImpl;
@@ -88,5 +91,208 @@ protected:
bool runRestartDialog() override;
};
+// This code is heavily based on "Color Quantization using Octrees" by Dean
+// Clark, published in - I think - the January 1996 issue of Dr. Dobb's Journal.
+//
+// FIXME: The intention is that this should be moved to common code, but we keep
+// it here for now to avoid conflicts.
+
+#define kOctreeDepth 6
+
+struct OctreeNode {
+ byte level;
+ bool isLeaf;
+ uint32 numPixels;
+ uint32 sumRed;
+ uint32 sumGreen;
+ uint32 sumBlue;
+ OctreeNode *child[8];
+ OctreeNode *nextNode;
+};
+
+class Octree {
+private:
+ uint _leafLevel = kOctreeDepth - 1;
+
+ OctreeNode *_root = nullptr;
+ uint _numLeaves = 0;
+ uint _maxLeaves = 0;
+
+ OctreeNode *_reduceList[kOctreeDepth - 1];
+ Common::Stack<OctreeNode *> _nodePool;
+
+ OctreeNode *allocateNode(byte level) {
+ OctreeNode *node;
+
+ if (!_nodePool.empty())
+ node = _nodePool.pop();
+ else
+ node = new OctreeNode();
+
+ if (level == _leafLevel) {
+ node->isLeaf = true;
+ _numLeaves++;
+ } else
+ node->isLeaf = false;
+
+ node->level = level;
+ node->numPixels = 0;
+ node->sumRed = 0;
+ node->sumGreen = 0;
+ node->sumBlue = 0;
+ node->nextNode = nullptr;
+
+ for (int i = 0; i < 8; i++)
+ node->child[i] = nullptr;
+
+ return node;
+ }
+
+ void releaseNode(OctreeNode *node) {
+ _nodePool.push(node);
+ }
+
+ void deleteNodeRecursively(OctreeNode *node) {
+ if (!node)
+ return;
+
+ for (int i = 0; i < 8; i++)
+ deleteNodeRecursively(node->child[i]);
+
+ delete node;
+ }
+
+ int getChildIndex(byte r, byte g, byte b, byte level) {
+ byte bit = (0x80 >> level);
+ byte rbit = (r & bit) >> (5 - level);
+ byte gbit = (g & bit) >> (6 - level);
+ byte bbit = (b & bit) >> (7 - level);
+
+ return rbit | gbit | bbit;
+ }
+
+ void reduceTree() {
+ while (!_reduceList[_leafLevel - 1])
+ _leafLevel--;
+
+ OctreeNode *node = _reduceList[_leafLevel - 1];
+ _reduceList[_leafLevel - 1] = _reduceList[_leafLevel - 1]->nextNode;
+
+ uint32 sumRed = 0;
+ uint32 sumGreen = 0;
+ uint32 sumBlue = 0;
+
+ byte numChildren = 0;
+
+ for (int i = 0; i < 8; i++) {
+ OctreeNode *child = node->child[i];
+
+ if (child) {
+ numChildren++;
+ sumRed += child->sumRed;
+ sumGreen += child->sumGreen;
+ sumBlue += child->sumBlue;
+ node->numPixels += child->numPixels;
+ releaseNode(child);
+ node->child[i] = nullptr;
+ }
+ }
+
+ node->isLeaf = true;
+ node->sumRed = sumRed;
+ node->sumGreen = sumGreen;
+ node->sumBlue = sumBlue;
+
+ _numLeaves -= (numChildren - 1);
+ }
+
+ Graphics::Palette *_palette;
+ uint _colorIndex;
+
+ void getPalette(OctreeNode *node) {
+ if (node->isLeaf) {
+ byte r = node->sumRed / node->numPixels;
+ byte g = node->sumGreen / node->numPixels;
+ byte b = node->sumBlue / node->numPixels;
+ _palette->set(_colorIndex, r, g, b);
+ _colorIndex++;
+ } else {
+ for (uint i = 0; i < 8; i++) {
+ if (node->child[i])
+ getPalette(node->child[i]);
+ }
+ }
+ }
+
+public:
+ Octree(int maxLeaves) : _maxLeaves(maxLeaves) {
+ for (uint i = 0; i < kOctreeDepth; i++)
+ _reduceList[i] = nullptr;
+ }
+
+ ~Octree() {
+ while (!_nodePool.empty())
+ delete _nodePool.pop();
+ deleteNodeRecursively(_root);
+ }
+
+ void insert(byte r, byte g, byte b) {
+ insert(&_root, r, g, b, 0);
+ }
+
+ void insert(OctreeNode **node, byte r, byte g, byte b, uint level) {
+ if (*node == nullptr) {
+ *node = allocateNode(level);
+ if (level != _leafLevel) {
+ (*node)->nextNode = _reduceList[level];
+ _reduceList[level] = *node;
+ }
+ }
+
+ if ((*node)->isLeaf) {
+ (*node)->numPixels++;
+ (*node)->sumRed += r;
+ (*node)->sumGreen += g;
+ (*node)->sumBlue += b;
+ } else {
+ insert(&((*node)->child[getChildIndex(r, g, b, level)]), r, g, b, level + 1);
+ }
+
+ if (_numLeaves > _maxLeaves)
+ reduceTree();
+ }
+
+ Graphics::Palette *getPalette() {
+ _palette = new Graphics::Palette(_maxLeaves);
+ _colorIndex = 0;
+
+ getPalette(_root);
+
+ return _palette;
+ }
+};
+
+class ColorQuantizer {
+private:
+ Octree *_octree = nullptr;
+
+public:
+ ColorQuantizer(int maxColors) {
+ _octree = new Octree(maxColors);
+ }
+
+ ~ColorQuantizer() {
+ delete _octree;
+ }
+
+ void addColor(byte r, byte g, byte b) {
+ _octree->insert(r, g, b);
+ }
+
+ Graphics::Palette *getPalette() {
+ return _octree->getPalette();
+ }
+};
+
} // End of namespace Scumm
#endif
Commit: 6533fa62171869c4316fd91f0d011211a852b815
https://github.com/scummvm/scummvm/commit/6533fa62171869c4316fd91f0d011211a852b815
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Fix corner case when reducing the octree
It's theoretically possible that the node will only have one child, and
then the number of leaves will stay the same.
Changed paths:
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 3c8029333d9..3b5c965c58d 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -172,6 +172,7 @@ private:
}
void reduceTree() {
+ // TODO: Figure out why we change _leafLevel like this
while (!_reduceList[_leafLevel - 1])
_leafLevel--;
@@ -258,7 +259,9 @@ public:
insert(&((*node)->child[getChildIndex(r, g, b, level)]), r, g, b, level + 1);
}
- if (_numLeaves > _maxLeaves)
+ // Usually one reduction would be enough, but it's possible
+ // that the reduction will not actually remove any leaves.
+ while (_numLeaves > _maxLeaves)
reduceTree();
}
Commit: 3df5f20e41a5951b69ebf7877b06de604da59a47
https://github.com/scummvm/scummvm/commit/3df5f20e41a5951b69ebf7877b06de604da59a47
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Cleanup
Changed paths:
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 3b5c965c58d..20831833bdf 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -162,15 +162,6 @@ private:
delete node;
}
- int getChildIndex(byte r, byte g, byte b, byte level) {
- byte bit = (0x80 >> level);
- byte rbit = (r & bit) >> (5 - level);
- byte gbit = (g & bit) >> (6 - level);
- byte bbit = (b & bit) >> (7 - level);
-
- return rbit | gbit | bbit;
- }
-
void reduceTree() {
// TODO: Figure out why we change _leafLevel like this
while (!_reduceList[_leafLevel - 1])
@@ -256,7 +247,13 @@ public:
(*node)->sumGreen += g;
(*node)->sumBlue += b;
} else {
- insert(&((*node)->child[getChildIndex(r, g, b, level)]), r, g, b, level + 1);
+ byte bit = (0x80 >> level);
+ byte rbit = (r & bit) >> (5 - level);
+ byte gbit = (g & bit) >> (6 - level);
+ byte bbit = (b & bit) >> (7 - level);
+ int idx = rbit | gbit | bbit;
+
+ insert(&((*node)->child[idx]), r, g, b, level + 1);
}
// Usually one reduction would be enough, but it's possible
Commit: 9bd992e4781a11d6ecb6c6a253a54bba33f9f3d6
https://github.com/scummvm/scummvm/commit/9bd992e4781a11d6ecb6c6a253a54bba33f9f3d6
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2025-01-01T14:41:20+02:00
Commit Message:
SCUMM: MACGUI: Clean up color quantization code a bit
Mostly comments, but I also don't understand why reduceTree() would
reduce the height of the entire octree, and not just the subtree it is
pruning. So I've changed that, but added a comment to describe what I
did there.
Changed paths:
engines/scumm/macgui/macgui_v6.h
diff --git a/engines/scumm/macgui/macgui_v6.h b/engines/scumm/macgui/macgui_v6.h
index 20831833bdf..6fdcef6c2d3 100644
--- a/engines/scumm/macgui/macgui_v6.h
+++ b/engines/scumm/macgui/macgui_v6.h
@@ -110,6 +110,19 @@ struct OctreeNode {
OctreeNode *nextNode;
};
+// An octree is a tree where each node has up to eight children. Colors are
+// inserted into it by looking at the bits of the R, G, and B components one
+// bit at a time, starting at the most significant bit. These three bits form
+// a value from 0 to 7, indicating which child node to enter.
+//
+// This means that adjacent leaves in the tree will represent colors that are
+// close together. Once the tree has more leaves than we want, we take all
+// leaves under one node, combine them, and make their parent a new leaf with
+// their average color. The old leaves are then discarded.
+//
+// The depth of the tree is the number of bits we look at. Technically this
+// would be eight, but six should be enough.
+
class Octree {
private:
uint _leafLevel = kOctreeDepth - 1;
@@ -162,13 +175,69 @@ private:
delete node;
}
+ void insert(OctreeNode **node, byte r, byte g, byte b, uint level) {
+ if (*node == nullptr) {
+ *node = allocateNode(level);
+ if (level != _leafLevel) {
+ (*node)->nextNode = _reduceList[level];
+ _reduceList[level] = *node;
+ }
+ }
+
+ // Once we encounter a leaf, add the color there. This is not
+ // necessarily at the bottom of the tree, so I guess it would
+ // not be out of the question to transform the leaf into a
+ // regular node. But I saw no mention of this in the article.
+
+ if ((*node)->isLeaf) {
+ (*node)->numPixels++;
+ (*node)->sumRed += r;
+ (*node)->sumGreen += g;
+ (*node)->sumBlue += b;
+ } else {
+ byte bit = (0x80 >> level);
+ byte rbit = (r & bit) >> (5 - level);
+ byte gbit = (g & bit) >> (6 - level);
+ byte bbit = (b & bit) >> (7 - level);
+ int idx = rbit | gbit | bbit;
+
+ insert(&((*node)->child[idx]), r, g, b, level + 1);
+ }
+
+ // Usually one reduction would be enough, but it's possible
+ // that the reduction will not actually remove any leaves.
+
+ while (_numLeaves > _maxLeaves)
+ reduceTree();
+ }
+
void reduceTree() {
- // TODO: Figure out why we change _leafLevel like this
- while (!_reduceList[_leafLevel - 1])
- _leafLevel--;
+ // In the original article, once a reduce list has been emptied
+ // the leaf level was decreased, meaning that the tree could
+ // never again grow beyond that height. I don't understand why,
+ // so I have made this a local variable instead.
- OctreeNode *node = _reduceList[_leafLevel - 1];
- _reduceList[_leafLevel - 1] = _reduceList[_leafLevel - 1]->nextNode;
+ int level = _leafLevel - 1;
+
+ while (!_reduceList[level])
+ level--;
+
+ // There are several possible approaches to picking the node to
+ // reduce. Picking the one with the largest number of pixels
+ // may leave more color for fine details. Picking the one with
+ // the smallest may will sacrifice detail, but may preserve
+ // subtle gradations in large areas. This picks the first one,
+ // i.e. the most recently inserted one, so it's pretty random.
+ //
+ // On the contrary, it stated that "any new colors whose path
+ // through the tree take them through [a node that was turned
+ // into a leaf] now stop here".
+
+ OctreeNode *node = _reduceList[level];
+ _reduceList[level] = _reduceList[level]->nextNode;
+
+ // Combine all the leaves into their parent, and make the
+ // parent a leaf.
uint32 sumRed = 0;
uint32 sumGreen = 0;
@@ -232,36 +301,6 @@ public:
insert(&_root, r, g, b, 0);
}
- void insert(OctreeNode **node, byte r, byte g, byte b, uint level) {
- if (*node == nullptr) {
- *node = allocateNode(level);
- if (level != _leafLevel) {
- (*node)->nextNode = _reduceList[level];
- _reduceList[level] = *node;
- }
- }
-
- if ((*node)->isLeaf) {
- (*node)->numPixels++;
- (*node)->sumRed += r;
- (*node)->sumGreen += g;
- (*node)->sumBlue += b;
- } else {
- byte bit = (0x80 >> level);
- byte rbit = (r & bit) >> (5 - level);
- byte gbit = (g & bit) >> (6 - level);
- byte bbit = (b & bit) >> (7 - level);
- int idx = rbit | gbit | bbit;
-
- insert(&((*node)->child[idx]), r, g, b, level + 1);
- }
-
- // Usually one reduction would be enough, but it's possible
- // that the reduction will not actually remove any leaves.
- while (_numLeaves > _maxLeaves)
- reduceTree();
- }
-
Graphics::Palette *getPalette() {
_palette = new Graphics::Palette(_maxLeaves);
_colorIndex = 0;
More information about the Scummvm-git-logs
mailing list