diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp
index cba0a20d27a..92eea10c3dc 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -699,4 +699,69 @@ void LoomTownsDifficultyDialog::handleCommand(GUI::CommandSender *sender, uint32
}
}
+EgaLoomOptionsWidget::EgaLoomOptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain) :
+ OptionsContainerWidget(boss, name, "EgaLoomOptionsDialog", false, domain) {
+ new GUI::StaticTextWidget(widgetsBoss(), "EgaLoomOptionsDialog.OvertureTicksHeader", _("Overture Timing:"));
+
+ _overtureTicksSlider = new GUI::SliderWidget(widgetsBoss(), "EgaLoomOptionsDialog.OvertureTicks", _("Adjusts how quickly the Overture transition happens when using replacement audio tracks."), kOvertureTicksChanged);
+
+ // Each step of the slider changes the assumed length of the Loom
+ // Overture by ten SCUMM ticks. When I timed it, I was able to set the
+ // transition to happen anywhere between approximately 1:30 and 2:20,
+ // which should be more than enough. I think it's nice if the interval
+ // is small enough that you can set the slider back to 0 at reasonable
+ // screen resolutions.
+
+ _overtureTicksSlider->setMinValue(-200);
+ _overtureTicksSlider->setMaxValue(200);
+
+ _overtureTicksLabel = new GUI::StaticTextWidget(widgetsBoss(), "EgaLoomOptionsDialog.OvertureTicksLabel", Common::U32String());
+
+ _overtureTicksLabel->setFlags(GUI::WIDGET_CLEARBG);
+}
+
+void EgaLoomOptionsWidget::load() {
+ int loomOvertureTicks = DEFAULT_LOOM_OVERTURE_TICKS;
+
+ if (ConfMan.hasKey("loom_overture_ticks", _domain))
+ loomOvertureTicks = ConfMan.getInt("loom_overture_ticks", _domain);
+
+ _overtureTicksSlider->setValue(loomOvertureTicks);
+ updateOvertureTicksLabel();
+}
+
+bool EgaLoomOptionsWidget::save() {
+ ConfMan.setInt("loom_overture_ticks", _overtureTicksSlider->getValue(), _domain);
+ return true;
+}
+
+void EgaLoomOptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const {
+ layouts.addDialog(layoutName, overlayedLayout)
+ .addLayout(GUI::ThemeLayout::kLayoutHorizontal)
+ .addPadding(16, 16, 16, 16)
+ .addWidget("OvertureTicksHeader", "OptionsLabel")
+ .addWidget("OvertureTicks", "WideSlider")
+ .addSpace(8)
+ .addWidget("OvertureTicksLabel", "SmallLabel")
+ .closeLayout()
+ .closeDialog();
+}
+
+void EgaLoomOptionsWidget::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
+
+ switch (cmd) {
+ case kOvertureTicksChanged:
+ updateOvertureTicksLabel();
+ break;
+ default:
+ GUI::OptionsContainerWidget::handleCommand(sender, cmd, data);
+ break;
+ }
+}
+
+void EgaLoomOptionsWidget::updateOvertureTicksLabel() {
+ _overtureTicksLabel->setValue(_overtureTicksSlider->getValue());
+ _overtureTicksLabel->markAsDirty();
+}
+
} // End of namespace Scumm
diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h
index 555cf822b1d..69b51cb3dac 100644
--- a/engines/scumm/dialogs.h
+++ b/engines/scumm/dialogs.h
@@ -209,6 +209,31 @@ private:
int _difficulty;
};
+/**
+ * Options widget for EGA Loom
+ */
+class EgaLoomOptionsWidget : public GUI::OptionsContainerWidget {
+public:
+ EgaLoomOptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain);
+ ~EgaLoomOptionsWidget() override {};
+
+ void load() override;
+ bool save() override;
+
+private:
+ enum {
+ kOvertureTicksChanged = 'OTCH'
+ };
+
+ void defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const override;
+ void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) override;
+
+ GUI::SliderWidget *_overtureTicksSlider;
+ GUI::StaticTextWidget *_overtureTicksLabel;
+
+ void updateOvertureTicksLabel();
+};
+
} // End of namespace Scumm
#endif
diff --git a/engines/scumm/metaengine.cpp b/engines/scumm/metaengine.cpp
index ac86b1e0229..6a8b838e214 100644
--- a/engines/scumm/metaengine.cpp
+++ b/engines/scumm/metaengine.cpp
@@ -32,6 +32,7 @@
#include "scumm/he/intern_he.h"
#include "scumm/scumm_v0.h"
#include "scumm/scumm_v8.h"
+#include "scumm/dialogs.h"
#include "scumm/resource.h"
// Files related for detection.
@@ -522,6 +523,26 @@ SaveStateDescriptor ScummMetaEngine::querySaveMetaInfos(const char *target, int
return desc;
}
+GUI::OptionsContainerWidget *ScummMetaEngine::buildEngineOptionsWidgetDynamic(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const {
+ if (ConfMan.get("gameid", target) != "loom")
+ return nullptr;
+
+ // These Loom settings are only relevant for the EGA version, so
+ // exclude non-DOS versions. If the game was added a long time ago,
+ // the platform may still be listed as unknown.
+
+ Common::Platform platform = Common::parsePlatform(ConfMan.get("platform", target));
+ if (platform != Common::kPlatformUnknown && platform != Common::kPlatformDOS)
+ return nullptr;
+
+ if (ConfMan.get("extra", target) == "Steam")
+ return nullptr;
+
+ // And yet, after all this, we still can't be sure that it's not the
+ // VGA version or a demo...
+ return new Scumm::EgaLoomOptionsWidget(boss, name, target);
+}
+
#if PLUGIN_ENABLED_DYNAMIC(SCUMM)
REGISTER_PLUGIN_DYNAMIC(SCUMM, PLUGIN_TYPE_ENGINE, ScummMetaEngine);
#else
diff --git a/engines/scumm/metaengine.h b/engines/scumm/metaengine.h
index a1e75330f9c..051e8f4d4ff 100644
--- a/engines/scumm/metaengine.h
+++ b/engines/scumm/metaengine.h
@@ -35,6 +35,8 @@ class ScummMetaEngine : public MetaEngine {
int getMaximumSaveSlot() const override;
void removeSaveState(const char *target, int slot) const override;
SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override;
+
+ GUI::OptionsContainerWidget *buildEngineOptionsWidgetDynamic(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const override;
};
#endif // SCUMM_METAENGINE_H
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 9a49562a96d..496094926e9 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1541,6 +1541,7 @@ void ScummEngine::setupScumm(const Common::String &macResourceFile) {
bool useReplacementAudioTracks = (_game.id == GID_LOOM && !(_game.features & GF_AUDIOTRACKS));
if (useReplacementAudioTracks) {
+ ConfMan.registerDefault("loom_overture_ticks", DEFAULT_LOOM_OVERTURE_TICKS);
_system->getAudioCDManager()->open();
}
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index d206632752d..b1e106dbf20 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -98,6 +98,7 @@ Sound::Sound(ScummEngine *parent, Audio::Mixer *mixer, bool useReplacementAudioT
_loomSteamCD.balance = 0;
_isLoomSteam = _vm->_game.id == GID_LOOM && Common::File::exists("CDDA.SOU");
+ _loomOvertureTicks = DEFAULT_LOOM_OVERTURE_TICKS + 10 * ConfMan.getInt("loom_overture_ticks");
_loomSteamCDAudioHandle = new Audio::SoundHandle();
_talkChannelHandle = new Audio::SoundHandle();
@@ -127,8 +128,8 @@ bool Sound::isRolandLoom() const {
// Ozawa version of No. 10 Scène (Moderato). Good enough for now, but maybe it
// needs to be configurable to accommodate for different recordings?
-#define TICKS_TO_TIMER(x) ((((x) * 278) / 8940) + 1)
-#define TIMER_TO_TICKS(x) ((((x) - 1) * 8940) / 278)
+#define TICKS_TO_TIMER(x) ((((x) * 278) / _loomOvertureTicks) + 1)
+#define TIMER_TO_TICKS(x) ((((x) - 1) * _loomOvertureTicks) / 278)
void Sound::updateMusicTimer(int ticks) {
bool isLoomOverture = (isRolandLoom() && _currentCDSound == 56 && !(_vm->_game.features & GF_DEMO));
diff --git a/engines/scumm/sound.h b/engines/scumm/sound.h
index 50e2d463f3b..acb13135e2b 100644
--- a/engines/scumm/sound.h
+++ b/engines/scumm/sound.h
@@ -29,6 +29,8 @@
#include "backends/audiocd/audiocd.h"
#include "scumm/file.h"
+#define DEFAULT_LOOM_OVERTURE_TICKS 8940
+
namespace Audio {
class Mixer;
class SoundHandle;
@@ -94,6 +96,7 @@ protected:
bool _useReplacementAudioTracks;
int _musicTimer;
uint32 _scummTicks;
+ uint32 _loomOvertureTicks;
public:
Audio::SoundHandle *_talkChannelHandle; // Handle of mixer channel actor is talking on
diff --git a/gui/themes/common/highres_layout.stx b/gui/themes/common/highres_layout.stx
index 8da7c36f9d3..f2a12c0d885 100644
--- a/gui/themes/common/highres_layout.stx
+++ b/gui/themes/common/highres_layout.stx
@@ -103,6 +103,9 @@
+
diff --git a/gui/themes/common/lowres_layout.stx b/gui/themes/common/lowres_layout.stx
index d79c5594b6b..cd9a2466464 100644
--- a/gui/themes/common/lowres_layout.stx
+++ b/gui/themes/common/lowres_layout.stx
@@ -96,6 +96,9 @@
+
diff --git a/gui/themes/residualvm.zip b/gui/themes/residualvm.zip
index 04f1aca3284..e4ea070aab4 100644
Binary files a/gui/themes/residualvm.zip and b/gui/themes/residualvm.zip differ
diff --git a/gui/themes/residualvm/THEMERC b/gui/themes/residualvm/THEMERC
index 0a96b70c755..1f30724c367 100644
--- a/gui/themes/residualvm/THEMERC
+++ b/gui/themes/residualvm/THEMERC
@@ -1,3 +1,3 @@
-[SCUMMVM_STX0.9.1:ResidualVM Modern Theme Remastered:No Author]
+[SCUMMVM_STX0.9.2:ResidualVM Modern Theme Remastered:No Author]
%using ../common
%using ../common-svg
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index 09289b8cc3b..798214670cb 100644
Binary files a/gui/themes/scummclassic.zip and b/gui/themes/scummclassic.zip differ
diff --git a/gui/themes/scummclassic/THEMERC b/gui/themes/scummclassic/THEMERC
index 1bd6884510c..02be869634e 100644
--- a/gui/themes/scummclassic/THEMERC
+++ b/gui/themes/scummclassic/THEMERC
@@ -1 +1 @@
-[SCUMMVM_STX0.9.1:ScummVM Classic Theme:No Author]
+[SCUMMVM_STX0.9.2:ScummVM Classic Theme:No Author]
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index ce551747cb6..4f4740d961f 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -87,6 +87,9 @@
+
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 64612c6c0b8..cbed3bd2f40 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -84,6 +84,9 @@
+
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index 7fc9c6a3952..cc3ee55323b 100644
Binary files a/gui/themes/scummmodern.zip and b/gui/themes/scummmodern.zip differ
diff --git a/gui/themes/scummmodern/THEMERC b/gui/themes/scummmodern/THEMERC
index cf23ba05de2..1e3edcb3f05 100644
--- a/gui/themes/scummmodern/THEMERC
+++ b/gui/themes/scummmodern/THEMERC
@@ -1,2 +1,2 @@
-[SCUMMVM_STX0.9.1:ScummVM Modern Theme:No Author]
+[SCUMMVM_STX0.9.2:ScummVM Modern Theme:No Author]
%using ../common
diff --git a/gui/themes/scummremastered.zip b/gui/themes/scummremastered.zip
index d8683cd27c3..3b00ebddde8 100644
Binary files a/gui/themes/scummremastered.zip and b/gui/themes/scummremastered.zip differ
diff --git a/gui/themes/scummremastered/THEMERC b/gui/themes/scummremastered/THEMERC
index 3122cbf07bf..cc0ce935f39 100644
--- a/gui/themes/scummremastered/THEMERC
+++ b/gui/themes/scummremastered/THEMERC
@@ -1,3 +1,3 @@
-[SCUMMVM_STX0.9.1:ScummVM Modern Theme Remastered:No Author]
+[SCUMMVM_STX0.9.2:ScummVM Modern Theme Remastered:No Author]
%using ../common
%using ../common-svg