From a4fa54550a9b32ee154df6ca8ca25dfabcd35564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbj=C3=B6rn=20Andersson?= Date: Sun, 18 Jul 2021 21:13:42 +0200 Subject: [PATCH] SCUMM: Add support for Mac Loom low quality music This is guesswork, but it seems like the first channel always contains a complete rendition of the music. I think that's intended for low-end Macs, while the other voices (four, but the last one never seems to be used) is the standard version of the music. It doesn't sound particularly good, and also not quite as with Mini vMac (I'm not fully prepared to rule out emulation problems), but it seems reasonably close. --- engines/scumm/detection.cpp | 9 +++++++++ engines/scumm/players/player_v3m.cpp | 29 +++++++++++++++++++++------- engines/scumm/players/player_v3m.h | 2 +- engines/scumm/scumm.cpp | 2 +- 4 files changed, 33 insertions(+), 9 deletions(-) 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);