[Scummvm-git-logs] scummvm master -> 7faa62d66f122123b17d749891bba5897e57ef19
NMIError
60350957+NMIError at users.noreply.github.com
Sun Aug 8 20:12:16 UTC 2021
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
1cb0f6b474 ULTIMA8: Fix AdLib music
88e214745d ULTIMA8: Enable MIDI config tabs for Ultima 8
994609e91c AUDIO/MIDI: Make Miles pitch bend range v3 specific
04f3083f4d ULTIMA8: Fix SFX and speech volume control
7fb83e71b5 AUDIO/MIDI: Add timer proc to null multisource driver
0245ae15b0 AUDIO/MIDI: Add reset source volume to multisource drivers
543591c9c5 ULTIMA8: Add music fade-out in intro
7faa62d66f ULTIMA8: Pause audio when ScummVM dialogs are shown
Commit: 1cb0f6b474753dd16403a02095a6dfc46b85d607
https://github.com/scummvm/scummvm/commit/1cb0f6b474753dd16403a02095a6dfc46b85d607
Author: Coen Rampen (crampen at gmail.com)
Date: 2021-08-08T22:12:05+02:00
Commit Message:
ULTIMA8: Fix AdLib music
To make the Ultima 8 AdLib music sound like the original interpreter, the
MidiPlayer class has been updated to use the Miles MIDI drivers. This allows
the game's AdLib instruments to be used. Because the Audio::MidiPlayer does not
work well with the Miles drivers, I've removed the dependency on this class and
implemented the necessary functionality in the Ultima 8 MidiPlayer.
Changed paths:
engines/ultima/ultima8/audio/midi_player.cpp
engines/ultima/ultima8/audio/midi_player.h
engines/ultima/ultima8/ultima8.cpp
diff --git a/engines/ultima/ultima8/audio/midi_player.cpp b/engines/ultima/ultima8/audio/midi_player.cpp
index 0a05b9460f..807fe5945a 100644
--- a/engines/ultima/ultima8/audio/midi_player.cpp
+++ b/engines/ultima/ultima8/audio/midi_player.cpp
@@ -21,36 +21,64 @@
*/
#include "ultima/ultima8/audio/midi_player.h"
+
#include "ultima/ultima8/ultima8.h"
+#include "ultima/ultima8/audio/music_flex.h"
+#include "ultima/ultima8/games/game_data.h"
+
#include "audio/midiparser.h"
+#include "audio/miles.h"
namespace Ultima {
namespace Ultima8 {
byte MidiPlayer::_callbackData[2];
-MidiPlayer::MidiPlayer() {
- MidiPlayer::createDriver();
+MidiPlayer::MidiPlayer() : _parser(nullptr) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
- _isFMSynth = MidiDriver::getMusicType(dev) == MT_ADLIB;
+ MusicType musicType = MidiDriver::getMusicType(dev);
+
+ switch (musicType) {
+ case MT_ADLIB:
+ MusicFlex *musicFlex;
+ musicFlex = GameData::get_instance()->getMusic();
+ _driver = Audio::MidiDriver_Miles_AdLib_create("", "", musicFlex->getAdlibTimbres(), nullptr);
+ break;
+ case MT_MT32:
+ case MT_GM:
+ _driver = Audio::MidiDriver_Miles_MIDI_create(MT_GM, "");
+ break;
+ default:
+ _driver = new MidiDriver_NULL_Multisource();
+ break;
+ }
+
+ _isFMSynth = (musicType == MT_ADLIB);
_callbackData[0] = 0;
_callbackData[1] = 0;
if (_driver) {
int retValue = _driver->open();
if (retValue == 0) {
- if (_nativeMT32)
- _driver->sendMT32Reset();
- else
- _driver->sendGMReset();
-
+ _driver->property(MidiDriver::PROP_USER_VOLUME_SCALING, true);
_driver->setTimerCallback(this, &timerCallback);
+ syncSoundSettings();
}
}
}
MidiPlayer::~MidiPlayer() {
- _driver->close();
+ if (_parser) {
+ _parser->unloadMusic();
+ delete _parser;
+ _parser = 0;
+ }
+
+ if (_driver) {
+ _driver->close();
+ delete _driver;
+ _driver = 0;
+ }
}
void MidiPlayer::load(byte *data, size_t size, int seqNo, bool speedHack) {
@@ -59,32 +87,32 @@ void MidiPlayer::load(byte *data, size_t size, int seqNo, bool speedHack) {
assert(seqNo == 0 || seqNo == 1);
- stop();
+ if (_parser) {
+ _parser->unloadMusic();
+ delete _parser;
+ _parser = 0;
+ }
if (size < 4)
error("load() wrong music resource size");
if (READ_BE_UINT32(data) != MKTAG('F', 'O', 'R', 'M')) {
warning("load() Unexpected signature");
- _isPlaying = false;
} else {
- _parser = MidiParser::createParser_XMIDI(xmidiCallback, _callbackData + seqNo);
+ _parser = MidiParser::createParser_XMIDI(xmidiCallback, _callbackData + seqNo, 0);
- _parser->setMidiDriver(this);
+ _parser->setMidiDriver(_driver);
_parser->setTimerRate(_driver->getBaseTempo());
if (speedHack)
_parser->setTempo(_driver->getBaseTempo() * 2);
- _parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
_parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
_parser->property(MidiParser::mpDisableAutoStartPlayback, 1);
- int volume = g_engine->_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
- setVolume(volume);
-
if (!_parser->loadMusic(data, size))
error("load() wrong music resource");
}
}
+
void MidiPlayer::play(int trackNo, int branchIndex) {
if (!_parser)
return;
@@ -103,17 +131,30 @@ void MidiPlayer::play(int trackNo, int branchIndex) {
if (!_parser->startPlaying()) {
warning("play() failed to start playing");
- } else {
- _isPlaying = true;
}
}
+void MidiPlayer::stop() {
+ if (_parser)
+ _parser->stopPlaying();
+}
+
+bool MidiPlayer::isPlaying() {
+ return _parser && _parser->isPlaying();
+}
+
+void MidiPlayer::syncSoundSettings() {
+ if (_driver)
+ _driver->syncSoundSettings();
+}
+
bool MidiPlayer::hasBranchIndex(uint8 index) {
return _parser && _parser->hasJumpIndex(index);
}
void MidiPlayer::setLooping(bool loop) {
- _parser->property(MidiParser::mpAutoLoop, loop);
+ if (_parser)
+ _parser->property(MidiParser::mpAutoLoop, loop);
}
void MidiPlayer::xmidiCallback(byte eventData, void *data) {
@@ -123,6 +164,14 @@ void MidiPlayer::xmidiCallback(byte eventData, void *data) {
*static_cast<byte*>(data) = eventData;
}
+void MidiPlayer::onTimer() {
+ if (_parser)
+ _parser->onTimer();
+}
+
+void MidiPlayer::timerCallback(void *data) {
+ ((MidiPlayer *)data)->onTimer();
+}
} // End of namespace Ultima8
} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/audio/midi_player.h b/engines/ultima/ultima8/audio/midi_player.h
index ec21cdbd4e..3238c8348c 100644
--- a/engines/ultima/ultima8/audio/midi_player.h
+++ b/engines/ultima/ultima8/audio/midi_player.h
@@ -24,15 +24,16 @@
#define ULTIMA8_AUDIO_MIDI_PLAYER_H
#include "audio/mixer.h"
-#include "audio/midiplayer.h"
+#include "audio/mididrv_ms.h"
+#include "audio/midiparser.h"
namespace Ultima {
namespace Ultima8 {
-class MidiPlayer : public Audio::MidiPlayer {
+class MidiPlayer {
public:
MidiPlayer();
- ~MidiPlayer() override;
+ ~MidiPlayer();
/**
* Load the specified music data
@@ -46,6 +47,21 @@ public:
*/
void play(int trackNo, int branchNo);
+ /**
+ * Stop the currently playing track.
+ */
+ void stop();
+
+ /**
+ * Returns true if a track is playing.
+ */
+ bool isPlaying();
+
+ /**
+ * Synchronizes the user volume settings with those of the game.
+ */
+ void syncSoundSettings();
+
/**
* Sets whether the music should loop
*/
@@ -67,7 +83,14 @@ public:
assert(seq == 0 || seq == 1);
return _callbackData[seq];
}
+
+ void onTimer();
+ static void timerCallback(void *data);
+
private:
+ MidiDriver_Multisource *_driver;
+ MidiParser *_parser;
+
bool _isFMSynth;
static byte _callbackData[2];
};
diff --git a/engines/ultima/ultima8/ultima8.cpp b/engines/ultima/ultima8/ultima8.cpp
index 9408e16047..c9b0f4c8f6 100644
--- a/engines/ultima/ultima8/ultima8.cpp
+++ b/engines/ultima/ultima8/ultima8.cpp
@@ -1232,7 +1232,7 @@ void Ultima8Engine::syncSoundSettings() {
AudioMixer *audioMixer = AudioMixer::get_instance();
MidiPlayer *midiPlayer = audioMixer ? audioMixer->getMidiPlayer() : nullptr;
if (midiPlayer)
- midiPlayer->setVolume(_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType));
+ midiPlayer->syncSoundSettings();
}
void Ultima8Engine::applyGameSettings() {
Commit: 88e214745d7b80001edea4cb504a8ebe42de2a2b
https://github.com/scummvm/scummvm/commit/88e214745d7b80001edea4cb504a8ebe42de2a2b
Author: Coen Rampen (crampen at gmail.com)
Date: 2021-08-08T22:12:06+02:00
Commit Message:
ULTIMA8: Enable MIDI config tabs for Ultima 8
Ultima 8 uses MIDI, but the MIDI configuration tabs were disabled. This commit
enables the MIDI configuration by removing the GUIO_NOMIDI flag from the
detection entries.
Changed paths:
engines/ultima/detection_tables.h
diff --git a/engines/ultima/detection_tables.h b/engines/ultima/detection_tables.h
index f83bf49622..eb2a0c7e28 100644
--- a/engines/ultima/detection_tables.h
+++ b/engines/ultima/detection_tables.h
@@ -24,7 +24,7 @@ namespace Ultima {
#define GAMEOPTION_ORIGINAL_SAVELOAD GUIO_GAMEOPTIONS1
-#define GUI_OPTIONS_ULTIMA8 GUIO2(GUIO_NOMIDI, GAMEOPTION_ORIGINAL_SAVELOAD)
+#define GUI_OPTIONS_ULTIMA8 GUIO1(GAMEOPTION_ORIGINAL_SAVELOAD)
static const UltimaGameDescription GAME_DESCRIPTIONS[] = {
#ifndef RELEASE_BUILD
Commit: 994609e91ca0071977dce6d328f2af2af168c5fd
https://github.com/scummvm/scummvm/commit/994609e91ca0071977dce6d328f2af2af168c5fd
Author: Coen Rampen (crampen at gmail.com)
Date: 2021-08-08T22:12:06+02:00
Commit Message:
AUDIO/MIDI: Make Miles pitch bend range v3 specific
Miles version 3 introduced support for the MIDI pitch bend range RPN using the
data entry MSB controller. The ScummVM implementation would also process this
controller for Miles version 2 games. This caused a problem in Ultima 8, which
used Miles 2 and which had MIDI data that contained some (probably leftover)
data entry MSB events. These had no effect in the original interpreter, but in
ScummVM they caused the pitch bend range to change, resulting in incorrect
playback.
This is fixed by only processing the data entry MSB controller events when
Miles version is set to 3.
Changed paths:
audio/miles_adlib.cpp
diff --git a/audio/miles_adlib.cpp b/audio/miles_adlib.cpp
index 3e62a9428e..74311289f6 100644
--- a/audio/miles_adlib.cpp
+++ b/audio/miles_adlib.cpp
@@ -1026,8 +1026,15 @@ void MidiDriver_Miles_AdLib::controlChange(byte midiChannel, byte controllerNumb
break;
case MILES_CONTROLLER_PITCH_RANGE:
+ // Note that this is in fact the MIDI data entry MSB controller. To use
+ // this to set pitch bend range, the pitch bend range RPN should first
+ // be selected using the RPN MSB and LSB controllers.
+ // MSS does not support the RPN controllers and assumes that any use of
+ // the data entry MSB controller is to set the pitch bend range.
+
// Miles Audio 3 feature
- _midiChannels[midiChannel].currentPitchRange = controllerValue;
+ if (_milesVersion == MILES_VERSION_3)
+ _midiChannels[midiChannel].currentPitchRange = controllerValue;
break;
case MIDI_CONTROLLER_RESET_ALL_CONTROLLERS:
Commit: 04f3083f4db31121878be42cd03c13b5ad4e25fc
https://github.com/scummvm/scummvm/commit/04f3083f4db31121878be42cd03c13b5ad4e25fc
Author: Coen Rampen (crampen at gmail.com)
Date: 2021-08-08T22:12:06+02:00
Commit Message:
ULTIMA8: Fix SFX and speech volume control
The SFX and speech user volume controls for Ultima 8 did not work because
digital audio was played using the plain sound type instead of SFX or speech.
To distinguish between the two, a flag was added to the AudioChannel::playSample
function to indicate if the sample is a sound effect or speech.
Changed paths:
engines/ultima/ultima8/audio/audio_channel.cpp
engines/ultima/ultima8/audio/audio_channel.h
engines/ultima/ultima8/audio/audio_mixer.cpp
engines/ultima/ultima8/audio/audio_mixer.h
engines/ultima/ultima8/audio/audio_process.cpp
engines/ultima/ultima8/audio/audio_process.h
engines/ultima/ultima8/graphics/skf_player.cpp
diff --git a/engines/ultima/ultima8/audio/audio_channel.cpp b/engines/ultima/ultima8/audio/audio_channel.cpp
index 892d192fe0..afbe249a2b 100644
--- a/engines/ultima/ultima8/audio/audio_channel.cpp
+++ b/engines/ultima/ultima8/audio/audio_channel.cpp
@@ -39,7 +39,7 @@ AudioChannel::AudioChannel(Audio::Mixer *mixer, uint32 sampleRate, bool stereo)
AudioChannel::~AudioChannel(void) {
}
-void AudioChannel::playSample(AudioSample *sample, int loop, int priority, bool paused, uint32 pitchShift, int lvol, int rvol) {
+void AudioChannel::playSample(AudioSample *sample, int loop, int priority, bool paused, bool isSpeech, uint32 pitchShift, int lvol, int rvol) {
_sample = sample;
_loop = loop;
_priority = priority;
@@ -93,7 +93,7 @@ void AudioChannel::playSample(AudioSample *sample, int loop, int priority, bool
// Play it
int vol = (_lVol + _rVol) / 2; // range is 0 ~ 255
int balance = (_rVol - _lVol) / 2; // range is -127 ~ +127
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, stream, -1, vol, balance);
+ _mixer->playStream(isSpeech ? Audio::Mixer::kSpeechSoundType : Audio::Mixer::kSFXSoundType, &_soundHandle, stream, -1, vol, balance);
if (paused)
_mixer->pauseHandle(_soundHandle, true);
}
diff --git a/engines/ultima/ultima8/audio/audio_channel.h b/engines/ultima/ultima8/audio/audio_channel.h
index 19db199658..a02536a959 100644
--- a/engines/ultima/ultima8/audio/audio_channel.h
+++ b/engines/ultima/ultima8/audio/audio_channel.h
@@ -62,8 +62,8 @@ public:
void stop();
- void playSample(AudioSample *sample, int loop, int priority, bool paused,
- uint32 pitchShift, int lvol, int rvol);
+ void playSample(AudioSample *sample, int loop, int priority, bool paused,
+ bool isSpeech, uint32 pitchShift, int lvol, int rvol);
void playMusicStream(Audio::AudioStream *stream);
diff --git a/engines/ultima/ultima8/audio/audio_mixer.cpp b/engines/ultima/ultima8/audio/audio_mixer.cpp
index 11dad9c0d5..ebd85fce87 100644
--- a/engines/ultima/ultima8/audio/audio_mixer.cpp
+++ b/engines/ultima/ultima8/audio/audio_mixer.cpp
@@ -87,7 +87,7 @@ void AudioMixer::reset() {
Unlock();
}
-int AudioMixer::playSample(AudioSample *sample, int loop, int priority, bool paused, uint32 pitch_shift, int lvol, int rvol, bool ambient) {
+int AudioMixer::playSample(AudioSample *sample, int loop, int priority, bool paused, bool isSpeech, uint32 pitch_shift, int lvol, int rvol, bool ambient) {
int lowest = -1;
int lowprior = 65536;
@@ -109,7 +109,7 @@ int AudioMixer::playSample(AudioSample *sample, int loop, int priority, bool pau
}
if (i != maxchan || lowprior < priority)
- _channels[lowest]->playSample(sample, loop, priority, paused, pitch_shift, lvol, rvol);
+ _channels[lowest]->playSample(sample, loop, priority, paused, isSpeech, pitch_shift, lvol, rvol);
else
lowest = -1;
diff --git a/engines/ultima/ultima8/audio/audio_mixer.h b/engines/ultima/ultima8/audio/audio_mixer.h
index 87b989ff65..327e01c655 100644
--- a/engines/ultima/ultima8/audio/audio_mixer.h
+++ b/engines/ultima/ultima8/audio/audio_mixer.h
@@ -58,7 +58,7 @@ public:
void reset();
void createProcesses();
- int playSample(AudioSample *sample, int loop, int priority, bool paused, uint32 pitch_shift, int lvol, int rvol, bool ambient);
+ int playSample(AudioSample *sample, int loop, int priority, bool paused, bool isSpeech, uint32 pitch_shift, int lvol, int rvol, bool ambient);
bool isPlaying(int chan);
void stopSample(int chan);
diff --git a/engines/ultima/ultima8/audio/audio_process.cpp b/engines/ultima/ultima8/audio/audio_process.cpp
index ddfc08fead..c2d29af5a0 100644
--- a/engines/ultima/ultima8/audio/audio_process.cpp
+++ b/engines/ultima/ultima8/audio/audio_process.cpp
@@ -156,7 +156,7 @@ bool AudioProcess::continueSpeech(SampleInfo &si) {
// hack to prevent playSample from deleting 'si'
si._channel = -1;
- int channel = playSample(sample, 200, 0);
+ int channel = playSample(sample, 200, 0, true);
if (channel == -1)
return false;
@@ -224,9 +224,9 @@ bool AudioProcess::loadData(Common::ReadStream *rs, uint32 version) {
return true;
}
-int AudioProcess::playSample(AudioSample *sample, int priority, int loops, uint32 pitchShift, int16 lVol, int16 rVol, bool ambient) {
+int AudioProcess::playSample(AudioSample *sample, int priority, int loops, bool isSpeech, uint32 pitchShift, int16 lVol, int16 rVol, bool ambient) {
AudioMixer *mixer = AudioMixer::get_instance();
- int channel = mixer->playSample(sample, loops, priority, false, pitchShift, lVol, rVol, ambient);
+ int channel = mixer->playSample(sample, loops, priority, false, isSpeech, pitchShift, lVol, rVol, ambient);
if (channel == -1) return channel;
@@ -281,7 +281,7 @@ void AudioProcess::playSFX(int sfxNum, int priority, ObjId objId, int loops,
if (objId) calculateSoundVolume(objId, lVol, rVol);
}
- int channel = playSample(sample, priority, loops, pitchShift, (lVol * volume) / 256, (rVol * volume) / 256, ambient);
+ int channel = playSample(sample, priority, loops, false, pitchShift, (lVol * volume) / 256, (rVol * volume) / 256, ambient);
if (channel == -1) return;
// Update list
@@ -377,7 +377,7 @@ bool AudioProcess::playSpeech(const Std::string &barked, int shapeNum, ObjId obj
AudioSample *sample = speechflex->getSample(index);
if (!sample) return false;
- int channel = playSample(sample, 200, 0, pitchShift, volume, volume);
+ int channel = playSample(sample, 200, 0, true, pitchShift, volume, volume);
if (channel == -1) return false;
diff --git a/engines/ultima/ultima8/audio/audio_process.h b/engines/ultima/ultima8/audio/audio_process.h
index 025946d678..587fbef075 100644
--- a/engines/ultima/ultima8/audio/audio_process.h
+++ b/engines/ultima/ultima8/audio/audio_process.h
@@ -117,9 +117,9 @@ public:
//! play a sample (without storing a SampleInfo)
//! returns channel sample is played on, or -1
- int playSample(AudioSample *sample, int priority, int loops,
+ int playSample(AudioSample *sample, int priority, int loops, bool isSpeech = false,
uint32 pitchShift = PITCH_SHIFT_NONE, int16 lVol = 255,
- int16 rVol = 255, bool ambient=false);
+ int16 rVol = 255, bool ambient = false);
//! pause all currently playing samples
void pauseAllSamples();
diff --git a/engines/ultima/ultima8/graphics/skf_player.cpp b/engines/ultima/ultima8/graphics/skf_player.cpp
index bb9bab5fcc..ec2a207938 100644
--- a/engines/ultima/ultima8/graphics/skf_player.cpp
+++ b/engines/ultima/ultima8/graphics/skf_player.cpp
@@ -232,7 +232,7 @@ void SKFPlayer::run() {
bool stereo = (buf[8] == 2);
s = new RawAudioSample(buf + 34, bufsize - 34,
rate, true, stereo);
- audioproc->playSample(s, 0x60, 0);
+ audioproc->playSample(s, 0x60, 0, true);
// FIXME: memory leak! (sample is never deleted)
}
Commit: 7fb83e71b57be0d4a2e428b7f1955cd4c52845f2
https://github.com/scummvm/scummvm/commit/7fb83e71b57be0d4a2e428b7f1955cd4c52845f2
Author: Coen Rampen (crampen at gmail.com)
Date: 2021-08-08T22:12:06+02:00
Commit Message:
AUDIO/MIDI: Add timer proc to null multisource driver
This adds a timer proc to the null multisource MIDI driver to drive the fading
process. The null driver does not have any audio to fade, but without this the
fades will just hang and isFading will remain true. The fades are now
effectively timers so game behavior will remain consistent whether MIDI is
turned on or off.
Changed paths:
audio/mididrv_ms.cpp
audio/mididrv_ms.h
diff --git a/audio/mididrv_ms.cpp b/audio/mididrv_ms.cpp
index aac6d41264..aad088f30c 100644
--- a/audio/mididrv_ms.cpp
+++ b/audio/mididrv_ms.cpp
@@ -252,3 +252,20 @@ void MidiDriver_Multisource::onTimer() {
if (_timer_proc && _timer_param)
_timer_proc(_timer_param);
}
+
+MidiDriver_NULL_Multisource::~MidiDriver_NULL_Multisource() {
+ g_system->getTimerManager()->removeTimerProc(timerCallback);
+}
+
+int MidiDriver_NULL_Multisource::open() {
+ // Setup a timer callback so "fades" will end after the specified time
+ // (effectively becoming timers, because there is no audio).
+ _timerRate = getBaseTempo();
+ g_system->getTimerManager()->installTimerProc(timerCallback, _timerRate, this, "MidiDriver_NULL_Multisource");
+ return 0;
+}
+
+void MidiDriver_NULL_Multisource::timerCallback(void *data) {
+ MidiDriver_NULL_Multisource *driver = (MidiDriver_NULL_Multisource *)data;
+ driver->onTimer();
+}
diff --git a/audio/mididrv_ms.h b/audio/mididrv_ms.h
index 942401be4e..1c5e33308b 100644
--- a/audio/mididrv_ms.h
+++ b/audio/mididrv_ms.h
@@ -364,7 +364,9 @@ protected:
class MidiDriver_NULL_Multisource : public MidiDriver_Multisource {
public:
- int open() override { return 0; }
+ ~MidiDriver_NULL_Multisource();
+
+ int open() override;
bool isOpen() const override { return true; }
void close() override { }
uint32 getBaseTempo() override { return 10000; }
@@ -376,6 +378,8 @@ public:
using MidiDriver_Multisource::stopAllNotes;
void stopAllNotes(uint8 source, uint8 channel) override { }
+ static void timerCallback(void *data);
+
protected:
void applySourceVolume(uint8 source) override { }
};
Commit: 0245ae15b08be4c88797e7ba7cd39c10108cfebe
https://github.com/scummvm/scummvm/commit/0245ae15b08be4c88797e7ba7cd39c10108cfebe
Author: Coen Rampen (crampen at gmail.com)
Date: 2021-08-08T22:12:06+02:00
Commit Message:
AUDIO/MIDI: Add reset source volume to multisource drivers
This adds a convenience function to reset the source volume to the source
neutral volume.
Changed paths:
audio/mididrv_ms.cpp
audio/mididrv_ms.h
diff --git a/audio/mididrv_ms.cpp b/audio/mididrv_ms.cpp
index aad088f30c..27fdbf09ba 100644
--- a/audio/mididrv_ms.cpp
+++ b/audio/mididrv_ms.cpp
@@ -224,6 +224,18 @@ void MidiDriver_Multisource::setSourceVolume(uint8 source, uint16 volume) {
applySourceVolume(source);
}
+void MidiDriver_Multisource::resetSourceVolume() {
+ for (int i = 0; i < MAXIMUM_SOURCES; ++i) {
+ resetSourceVolume(i);
+ }
+}
+
+void MidiDriver_Multisource::resetSourceVolume(uint8 source) {
+ assert(source < MAXIMUM_SOURCES);
+
+ setSourceVolume(source, _sources[source].neutralVolume);
+}
+
void MidiDriver_Multisource::setSourceNeutralVolume(uint16 volume) {
for (int i = 0; i < MAXIMUM_SOURCES; ++i) {
setSourceNeutralVolume(i, volume);
diff --git a/audio/mididrv_ms.h b/audio/mididrv_ms.h
index 1c5e33308b..bd20ca4aad 100644
--- a/audio/mididrv_ms.h
+++ b/audio/mididrv_ms.h
@@ -212,6 +212,14 @@ public:
* @param volume The new source volume for the specified source.
*/
void setSourceVolume(uint8 source, uint16 volume);
+ /**
+ * Resets the source volume for all sources to each source's neutral volume.
+ */
+ void resetSourceVolume();
+ /**
+ * Resets the volume for this source to its neutral volume.
+ */
+ void resetSourceVolume(uint8 source);
/**
* Sets the neutral volume for all sources. See the source-specific
* setSourceNeutralVolume function for details.
Commit: 543591c9c5ccea6fde8fe3e46a5e94237c9fa8b0
https://github.com/scummvm/scummvm/commit/543591c9c5ccea6fde8fe3e46a5e94237c9fa8b0
Author: Coen Rampen (crampen at gmail.com)
Date: 2021-08-08T22:12:06+02:00
Commit Message:
ULTIMA8: Add music fade-out in intro
In the Ultima 8 intro, the last music track fades out in the original
interpreter, but in ScummVM it stopped abruptly. This seems to be because the
SKF_SlowStopMusic action was not fully implemented. This commit adds an
implementation to this action, which restores the fade-out in the intro.
Changed paths:
engines/ultima/ultima8/audio/cru_music_process.h
engines/ultima/ultima8/audio/midi_player.cpp
engines/ultima/ultima8/audio/midi_player.h
engines/ultima/ultima8/audio/music_process.h
engines/ultima/ultima8/audio/u8_music_process.cpp
engines/ultima/ultima8/audio/u8_music_process.h
engines/ultima/ultima8/graphics/skf_player.cpp
diff --git a/engines/ultima/ultima8/audio/cru_music_process.h b/engines/ultima/ultima8/audio/cru_music_process.h
index 75684f43fc..f8b1d51953 100644
--- a/engines/ultima/ultima8/audio/cru_music_process.h
+++ b/engines/ultima/ultima8/audio/cru_music_process.h
@@ -72,6 +72,11 @@ public:
//! Restore the last requested non-combat track (eg, at the end of combat)
void restoreMusic() override;
+ //! Fading is not used, so this does nothing
+ void fadeMusic(uint16 length) override { };
+ //! Fading is not used, so this returns false
+ bool isFading() override { return false; };
+
//! Save the current track state - used when the menu is opened
void saveTrackState() override;
//! Bring back the track state from before it was put on hold
diff --git a/engines/ultima/ultima8/audio/midi_player.cpp b/engines/ultima/ultima8/audio/midi_player.cpp
index 807fe5945a..d79d7a4db4 100644
--- a/engines/ultima/ultima8/audio/midi_player.cpp
+++ b/engines/ultima/ultima8/audio/midi_player.cpp
@@ -114,7 +114,7 @@ void MidiPlayer::load(byte *data, size_t size, int seqNo, bool speedHack) {
}
void MidiPlayer::play(int trackNo, int branchIndex) {
- if (!_parser)
+ if (!_parser || !_driver)
return;
if (!_parser->setTrack(trackNo)) {
@@ -129,6 +129,11 @@ void MidiPlayer::play(int trackNo, int branchIndex) {
}
}
+ // Abort any active fades and reset the source volume to neutral.
+ if (_driver->isFading(0))
+ _driver->abortFade(0);
+ _driver->resetSourceVolume(0);
+
if (!_parser->startPlaying()) {
warning("play() failed to start playing");
}
@@ -143,6 +148,15 @@ bool MidiPlayer::isPlaying() {
return _parser && _parser->isPlaying();
}
+void MidiPlayer::startFadeOut(uint16 length) {
+ if (_driver)
+ _driver->startFade(0, 1500, 0);
+}
+
+bool MidiPlayer::isFading() {
+ return _driver && _driver->isFading(0);
+}
+
void MidiPlayer::syncSoundSettings() {
if (_driver)
_driver->syncSoundSettings();
diff --git a/engines/ultima/ultima8/audio/midi_player.h b/engines/ultima/ultima8/audio/midi_player.h
index 3238c8348c..a4b6ed4a2c 100644
--- a/engines/ultima/ultima8/audio/midi_player.h
+++ b/engines/ultima/ultima8/audio/midi_player.h
@@ -57,6 +57,16 @@ public:
*/
bool isPlaying();
+ /**
+ * Starts a fade-out of the specified duration (in milliseconds).
+ */
+ void startFadeOut(uint16 length);
+
+ /**
+ * Returns true if the music is currently fading.
+ */
+ bool isFading();
+
/**
* Synchronizes the user volume settings with those of the game.
*/
diff --git a/engines/ultima/ultima8/audio/music_process.h b/engines/ultima/ultima8/audio/music_process.h
index 12991a81ae..d33b5deea7 100644
--- a/engines/ultima/ultima8/audio/music_process.h
+++ b/engines/ultima/ultima8/audio/music_process.h
@@ -66,6 +66,11 @@ public:
//! Restore the last requested non-combat track (eg, at the end of combat)
virtual void restoreMusic() = 0;
+ //! Fades out the music over the specified time (in milliseconds)
+ virtual void fadeMusic(uint16 length) = 0;
+ //! Returns true if the music is currently fading
+ virtual bool isFading() = 0;
+
//! Save the current track state - used when the menu is opened
virtual void saveTrackState() = 0;
//! Bring back the track state from before it was put on hold
diff --git a/engines/ultima/ultima8/audio/u8_music_process.cpp b/engines/ultima/ultima8/audio/u8_music_process.cpp
index abcd97aa2f..a164cd8859 100644
--- a/engines/ultima/ultima8/audio/u8_music_process.cpp
+++ b/engines/ultima/ultima8/audio/u8_music_process.cpp
@@ -90,6 +90,15 @@ void U8MusicProcess::restoreMusic() {
playMusic_internal(_trackState._lastRequest);
}
+void U8MusicProcess::fadeMusic(uint16 length) {
+ if (_midiPlayer && _midiPlayer->isPlaying())
+ _midiPlayer->startFadeOut(length);
+}
+
+bool U8MusicProcess::isFading() {
+ return _midiPlayer && _midiPlayer->isFading();
+}
+
void U8MusicProcess::getTrackState(TrackState &trackState) const {
trackState = _trackState;
}
diff --git a/engines/ultima/ultima8/audio/u8_music_process.h b/engines/ultima/ultima8/audio/u8_music_process.h
index c86036d411..ead9d59c04 100644
--- a/engines/ultima/ultima8/audio/u8_music_process.h
+++ b/engines/ultima/ultima8/audio/u8_music_process.h
@@ -100,6 +100,11 @@ public:
//! Restore the last requested non-combat track (eg, at the end of combat)
void restoreMusic() override;
+ //! Fades out the music over the specified time (in milliseconds)
+ void fadeMusic(uint16 length) override;
+ //! Returns true if the music is currently fading
+ bool isFading() override;
+
//! Save the current track state - used when the menu is opened
void saveTrackState() override;
//! Bring back the track state from before it was put on hold
diff --git a/engines/ultima/ultima8/graphics/skf_player.cpp b/engines/ultima/ultima8/graphics/skf_player.cpp
index ec2a207938..fa78306a59 100644
--- a/engines/ultima/ultima8/graphics/skf_player.cpp
+++ b/engines/ultima/ultima8/graphics/skf_player.cpp
@@ -141,6 +141,8 @@ void SKFPlayer::paint(RenderSurface *surf, int /*lerp*/) {
void SKFPlayer::run() {
if (!_playing || !_buffer) return;
+ MusicProcess *musicproc = MusicProcess::get_instance();
+
// if doing something, continue
if (_curAction) {
if (_curAction == SKF_FadeOut || _curAction == SKF_FadeWhite) {
@@ -149,6 +151,15 @@ void SKFPlayer::run() {
} else if (_curAction == SKF_FadeIn) {
_fadeLevel--;
if (_fadeLevel == 0) _curAction = 0; // done
+ } else if (_curAction == SKF_SlowStopMusic) {
+ if (!musicproc || !musicproc->isFading()) {
+ if (musicproc)
+ musicproc->playMusic(0); // stop playback
+ _curAction = 0; // done
+ } else {
+ // continue to wait for fade to finish
+ return;
+ }
} else {
pout << "Unknown fade action: " << _curAction << Std::endl;
}
@@ -169,7 +180,6 @@ void SKFPlayer::run() {
Font *redfont;
redfont = FontManager::get_instance()->getGameFont(6, true);
- MusicProcess *musicproc = MusicProcess::get_instance();
AudioProcess *audioproc = AudioProcess::get_instance();
bool subtitles = ConfMan.getBool("subtitles");
@@ -207,7 +217,9 @@ void SKFPlayer::run() {
break;
case SKF_SlowStopMusic:
// pout << "SlowStopMusic" << Std::endl;
- if (musicproc && !_introMusicHack) musicproc->playMusic(0);
+ if (musicproc)
+ musicproc->fadeMusic(1500);
+ _curAction = SKF_SlowStopMusic;
break;
case SKF_PlaySFX:
// pout << "PlaySFX " << _events[_curEvent]->_data << Std::endl;
Commit: 7faa62d66f122123b17d749891bba5897e57ef19
https://github.com/scummvm/scummvm/commit/7faa62d66f122123b17d749891bba5897e57ef19
Author: Coen Rampen (crampen at gmail.com)
Date: 2021-08-08T22:12:07+02:00
Commit Message:
ULTIMA8: Pause audio when ScummVM dialogs are shown
When showing the ScummVM menu using Ctrl-F5, gameplay in Ultima 8 would pause,
but MIDI music would continue to play (AdLib would pause) and sound effects
would finish playing as well. This commit pauses all music and digital audio
when the ScummVM menu is shown.
Changed paths:
engines/ultima/ultima8/audio/midi_player.cpp
engines/ultima/ultima8/audio/midi_player.h
engines/ultima/ultima8/ultima8.cpp
engines/ultima/ultima8/ultima8.h
diff --git a/engines/ultima/ultima8/audio/midi_player.cpp b/engines/ultima/ultima8/audio/midi_player.cpp
index d79d7a4db4..632798b559 100644
--- a/engines/ultima/ultima8/audio/midi_player.cpp
+++ b/engines/ultima/ultima8/audio/midi_player.cpp
@@ -144,6 +144,16 @@ void MidiPlayer::stop() {
_parser->stopPlaying();
}
+void MidiPlayer::pause(bool pause) {
+ if (_parser) {
+ if (pause) {
+ _parser->pausePlaying();
+ } else {
+ _parser->resumePlaying();
+ }
+ }
+}
+
bool MidiPlayer::isPlaying() {
return _parser && _parser->isPlaying();
}
diff --git a/engines/ultima/ultima8/audio/midi_player.h b/engines/ultima/ultima8/audio/midi_player.h
index a4b6ed4a2c..08fd8cd28f 100644
--- a/engines/ultima/ultima8/audio/midi_player.h
+++ b/engines/ultima/ultima8/audio/midi_player.h
@@ -52,6 +52,11 @@ public:
*/
void stop();
+ /**
+ * Pause or resume playback of the current track.
+ */
+ void pause(bool pause);
+
/**
* Returns true if a track is playing.
*/
diff --git a/engines/ultima/ultima8/ultima8.cpp b/engines/ultima/ultima8/ultima8.cpp
index c9b0f4c8f6..d88db30e32 100644
--- a/engines/ultima/ultima8/ultima8.cpp
+++ b/engines/ultima/ultima8/ultima8.cpp
@@ -186,6 +186,16 @@ bool Ultima8Engine::initialize() {
void Ultima8Engine::deinitialize() {
}
+void Ultima8Engine::pauseEngineIntern(bool pause) {
+ if (_mixer)
+ _mixer->pauseAll(pause);
+ if (_audioMixer) {
+ MidiPlayer *midiPlayer = _audioMixer->getMidiPlayer();
+ if (midiPlayer)
+ midiPlayer->pause(pause);
+ }
+}
+
bool Ultima8Engine::hasFeature(EngineFeature f) const {
return
(f == kSupportsSubtitleOptions) ||
diff --git a/engines/ultima/ultima8/ultima8.h b/engines/ultima/ultima8/ultima8.h
index b74a526dc1..4a11b1d2a4 100644
--- a/engines/ultima/ultima8/ultima8.h
+++ b/engines/ultima/ultima8/ultima8.h
@@ -172,6 +172,8 @@ protected:
bool initialize() override;
+ void pauseEngineIntern(bool pause) override;
+
/**
* Returns the data archive folder and version that's required
*/
More information about the Scummvm-git-logs
mailing list