diff options
author | Martin Kiewitz | 2015-07-02 13:17:21 +0200 |
---|---|---|
committer | Martin Kiewitz | 2015-07-02 13:17:21 +0200 |
commit | 903309fbb7ce5c9dbc66c988169ac109def20e16 (patch) | |
tree | ee5c8f8bf676dcd5cbe6397616cdb3291d56722e | |
parent | 50d9fb24d32ba0722b52b2e021568db2fdda4ac9 (diff) | |
download | scummvm-rg350-903309fbb7ce5c9dbc66c988169ac109def20e16.tar.gz scummvm-rg350-903309fbb7ce5c9dbc66c988169ac109def20e16.tar.bz2 scummvm-rg350-903309fbb7ce5c9dbc66c988169ac109def20e16.zip |
AUDIO: Miles Audio AdLib: implement sustain
fixes broken music in Return To Zork (demo)
also added comments about those special cases (useful for testing)
-rw-r--r-- | audio/miles_adlib.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/audio/miles_adlib.cpp b/audio/miles_adlib.cpp index 6697122492..a48aba304c 100644 --- a/audio/miles_adlib.cpp +++ b/audio/miles_adlib.cpp @@ -34,6 +34,10 @@ namespace Audio { // Miles Audio AdLib/OPL3 driver // // TODO: currently missing: OPL3 4-op voices +// +// Special cases (great for testing): +// - sustain feature is used by Return To Zork (demo) right at the start +// - sherlock holmes 2 does lots of priority sorts right at the start of the intro #define MILES_ADLIB_VIRTUAL_FMVOICES_COUNT_MAX 20 #define MILES_ADLIB_PHYSICAL_FMVOICES_COUNT_MAX 18 @@ -255,6 +259,8 @@ private: void releaseFmVoice(byte virtualFmVoice); + void releaseSustain(byte midiChannel); + void updatePhysicalFmVoice(byte virtualFmVoice, bool keyOn, uint16 registerUpdateFlags); void controlChange(byte midiChannel, byte controllerNumber, byte controllerValue); @@ -692,6 +698,19 @@ void MidiDriver_Miles_AdLib::releaseFmVoice(byte virtualFmVoice) { _midiChannels[midiChannel].currentActiveVoicesCount--; } +void MidiDriver_Miles_AdLib::releaseSustain(byte midiChannel) { + // Search through all virtual FM-Voices for currently sustained notes and call noteOff on them + for (byte virtualFmVoice = 0; virtualFmVoice < _modeVirtualFmVoicesCount; virtualFmVoice++) { + if (_virtualFmVoices[virtualFmVoice].inUse) { + if ((_virtualFmVoices[virtualFmVoice].actualMidiChannel == midiChannel) && (_virtualFmVoices[virtualFmVoice].sustained)) { + // is currently sustained + // so do a noteOff (which will check current sustain controller) + noteOff(midiChannel, _virtualFmVoices[virtualFmVoice].currentOriginalMidiNote); + } + } + } +} + void MidiDriver_Miles_AdLib::updatePhysicalFmVoice(byte virtualFmVoice, bool keyOn, uint16 registerUpdateFlags) { byte midiChannel = _virtualFmVoices[virtualFmVoice].actualMidiChannel; @@ -937,7 +956,7 @@ void MidiDriver_Miles_AdLib::controlChange(byte midiChannel, byte controllerNumb case MILES_CONTROLLER_SUSTAIN: _midiChannels[midiChannel].currentSustain = controllerValue; if (controllerValue < 64) { - // release sustain TODO + releaseSustain(midiChannel); } break; @@ -948,7 +967,7 @@ void MidiDriver_Miles_AdLib::controlChange(byte midiChannel, byte controllerNumb case MILES_CONTROLLER_RESET_ALL: _midiChannels[midiChannel].currentSustain = 0; - // release sustain TODO + releaseSustain(midiChannel); _midiChannels[midiChannel].currentModulation = 0; _midiChannels[midiChannel].currentVolumeExpression = 127; _midiChannels[midiChannel].currentPitchBender = MILES_PITCHBENDER_DEFAULT; |