diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index 9f0f79d4c97..cf6336ce0bf 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -193,6 +193,12 @@ static const ExtraGuiOption fmtownsTrimTo200 = { false }; +static const ExtraGuiOption macV3LowQualityMusic = { + _s("Play simplified music"), + _s("This music was presumably intended for low-end Macs, and uses only one channel."), + "mac_v3_low_quality_music", + false, +}; const ExtraGuiOptions ScummMetaEngineDetection::getExtraGuiOptions(const Common::String &target) const { ExtraGuiOptions options; @@ -209,6 +215,9 @@ const ExtraGuiOptions ScummMetaEngineDetection::getExtraGuiOptions(const Common: if (target.empty() || (ConfMan.get("platform", target) == "fmtowns" && guiOptions.contains(GUIO_TRIM_FMTOWNS_TO_200_PIXELS))) { options.push_back(fmtownsTrimTo200); } + if (target.empty() || (ConfMan.get("gameid", target) == "loom" && ConfMan.get("platform", target) == "macintosh" && ConfMan.get("extra", target) != "Steam")) { + options.push_back(macV3LowQualityMusic); + } return options; } diff --git a/engines/scumm/players/player_v3m.cpp b/engines/scumm/players/player_v3m.cpp index 0fcf6170b49..7bd90b8821b 100644 --- a/engines/scumm/players/player_v3m.cpp +++ b/engines/scumm/players/player_v3m.cpp @@ -96,13 +96,29 @@ namespace Scumm { -Player_V3M::Player_V3M(ScummEngine *scumm, Audio::Mixer *mixer) - : Player_Mac(scumm, mixer, 5, 0x1E, true) { +Player_V3M::Player_V3M(ScummEngine *scumm, Audio::Mixer *mixer, bool lowQuality) + : Player_Mac(scumm, mixer, 5, lowQuality ? 01 : 0x1E, true) { assert(_vm->_game.id == GID_LOOM); - // Channel 0 seems to be what was played on low-end macs, that couldn't - // handle multi-channel music and play the game at the same time. I'm - // not sure if stream 4 is ever used, but let's use it just in case. + // This is guesswork, but there are five music channels. + // + // Channel 0 seems to be a one-voice arrangement of the melody, + // presumably intended for low-end Macs. So that is used for the + // low-quality music. + // + // Channels 1-4 are the full arrangement of the melody, so that is what + // is used by default. Channel 4 never seems to be used - in fact, most + // of the time it uses the "silent" instrument, but we include it + // anyway, just in case. + // + // I wish I could hear this on real hardware, because Mac emulation is + // still a bit wonky here. But the low quality music seems to be close + // to what I hear in Mini vMac, when emulating an old black and white + // Mac, and the standard music is close to what I hear in Basilisk II. + // + // The original could further degrade the sound quality by playing it + // through the Mac synth instead of using digitized instruments, but + // we don't support that at all. } bool Player_V3M::loadMusic(const byte *ptr) { @@ -124,8 +140,7 @@ bool Player_V3M::loadMusic(const byte *ptr) { return false; } - uint i; - for (i = 0; i < 5; i++) { + for (int i = 0; i < 5; i++) { int instrument = READ_BE_UINT16(ptr + 20 + 2 * i); int offset = READ_BE_UINT16(ptr + 30 + 2 * i); diff --git a/engines/scumm/players/player_v3m.h b/engines/scumm/players/player_v3m.h index ea2d10e252f..c1d8e30ef3b 100644 --- a/engines/scumm/players/player_v3m.h +++ b/engines/scumm/players/player_v3m.h @@ -42,7 +42,7 @@ class ScummEngine; */ class Player_V3M : public Player_Mac { public: - Player_V3M(ScummEngine *scumm, Audio::Mixer *mixer); + Player_V3M(ScummEngine *scumm, Audio::Mixer *mixer, bool lowQuality); bool loadMusic(const byte *ptr) override; bool getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity) override; diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index d422a5e2da5..b40ab9ef38d 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -2162,7 +2162,7 @@ void ScummEngine::setupMusic(int midi, const Common::String &macInstrumentFile) } else if (_game.platform == Common::kPlatformAmiga && _game.version <= 4) { _musicEngine = new Player_V4A(this, _mixer); } else if (_game.platform == Common::kPlatformMacintosh && _game.id == GID_LOOM) { - _musicEngine = new Player_V3M(this, _mixer); + _musicEngine = new Player_V3M(this, _mixer, ConfMan.getBool("mac_v3_low_quality_music")); ((Player_V3M *)_musicEngine)->init(macInstrumentFile); } else if (_game.platform == Common::kPlatformMacintosh && _game.id == GID_MONKEY) { _musicEngine = new Player_V5M(this, _mixer);