diff options
-rw-r--r-- | engines/tinsel/music.cpp | 9 | ||||
-rw-r--r-- | engines/tinsel/sound.cpp | 42 | ||||
-rw-r--r-- | engines/tinsel/sound.h | 4 |
3 files changed, 50 insertions, 5 deletions
diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp index 91f0312101..dab2a897fc 100644 --- a/engines/tinsel/music.cpp +++ b/engines/tinsel/music.cpp @@ -135,10 +135,10 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) { if (ConfMan.hasKey("mute")) mute = ConfMan.getBool("mute"); - // TODO: The Macintosh version of DW1 does not use MIDI for music + // The Macintosh version of DW1 uses raw PCM for music if (TinselV1Mac) - return true; - + return _vm->_sound->playDW1MacMusic(dwFileOffset); + SetMidiVolume(mute ? 0 : _vm->_config->_musicVolume); // the index and length of the last tune loaded @@ -285,7 +285,8 @@ void OpenMidiFiles() { if (TinselV0 || TinselV2) return; - // TODO: The Macintosh version of DW1 does not use MIDI for music + // The Macintosh version of DW1 does not use MIDI for music. + // It uses PCM music instead, which is quite big to be preloaded here. if (TinselV1Mac) return; diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp index 794e3f7f4c..886f10c5e8 100644 --- a/engines/tinsel/sound.cpp +++ b/engines/tinsel/sound.cpp @@ -177,6 +177,48 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound return true; } +bool SoundManager::playDW1MacMusic(int dwFileOffset) { + Common::File s; + + if (!s.open("midi.dat")) + error(CANNOT_FIND_FILE, "midi.dat"); + + s.seek(dwFileOffset); + uint32 length = s.readUint32BE(); + + // TODO: It's a bad idea to load the music track in a buffer. + // We should use a readStream instead, and keep midi.dat open. + // However, the track lengths aren't that big (about 1-4MB), + // so this shouldn't be a major issue. + byte *soundData = (byte *)malloc(length); + assert(soundData); + + // read all of the sample + if (s.read(soundData, length) != length) + error(FILE_IS_CORRUPT, "midi.dat"); + + Common::SeekableReadStream *memStream = new Common::MemoryReadStream(soundData, length); + + Audio::SoundHandle *handle = &_channels[kChannelDW1MacMusic].handle; + //_channels[kChannelDW1MacMusic].sampleNum = dwFileOffset; + + // Stop any previously playing music track + _vm->_mixer->stopHandle(*handle); + + // FIXME: Should set this in a different place ;) + _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, _vm->_config->_musicVolume); + + // TODO: Compression support (MP3/OGG/FLAC) for midi.dat in DW1 Mac + Audio::RewindableAudioStream *musicStream = Audio::makeRawStream(memStream, 22050, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); + + if (musicStream) + _vm->_mixer->playStream(Audio::Mixer::kMusicSoundType, handle, Audio::makeLoopingAudioStream(musicStream, 0)); + + s.close(); + + return true; +} + // playSample for DiscWorld 2 bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int priority, Audio::Mixer::SoundType type, Audio::SoundHandle *handle) { diff --git a/engines/tinsel/sound.h b/engines/tinsel/sound.h index ea5eb45907..8510c1618f 100644 --- a/engines/tinsel/sound.h +++ b/engines/tinsel/sound.h @@ -51,7 +51,8 @@ protected: enum { kChannelTalk = 0, kChannelTinsel1 = 0, // Always using this channel for DW1 - kChannelSFX = 1 + kChannelSFX = 1, + kChannelDW1MacMusic = 2 }; static const int kNumChannels = kChannelSFX + kNumSFX; @@ -108,6 +109,7 @@ public: bool playSample(int id, Audio::Mixer::SoundType type, Audio::SoundHandle *handle = 0); bool playSample(int id, int sub, bool bLooped, int x, int y, int priority, Audio::Mixer::SoundType type, Audio::SoundHandle *handle = 0); + bool playDW1MacMusic(int dwFileOffset); void stopAllSamples(); // Stops any currently playing sample void stopSpecSample(int id, int sub = 0); // Stops a specific sample |