diff options
author | athrxx | 2011-11-06 21:31:18 +0100 |
---|---|---|
committer | Johannes Schickel | 2011-12-26 16:18:10 +0100 |
commit | 2bcae2451a9e5e59c2ad30e5c8560d9b8e117501 (patch) | |
tree | 2a0256a6a046064338abc15222245bda2d1870aa /engines/kyra | |
parent | 2da431aa65da25388963687d398f4a40f2aeee73 (diff) | |
download | scummvm-rg350-2bcae2451a9e5e59c2ad30e5c8560d9b8e117501.tar.gz scummvm-rg350-2bcae2451a9e5e59c2ad30e5c8560d9b8e117501.tar.bz2 scummvm-rg350-2bcae2451a9e5e59c2ad30e5c8560d9b8e117501.zip |
KYRA: (AdLib Driver) - prevent squashing of sounds during halt track execution
This patch makes sure that the stopping track (track 0) does not squash sounds which get queued during the execution of the stopping track. This seems to be a hardware problem (original driver implementation not suitable for modern machines).
Diffstat (limited to 'engines/kyra')
-rw-r--r-- | engines/kyra/sound_adlib.cpp | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp index 983d3b6031..94a285d729 100644 --- a/engines/kyra/sound_adlib.cpp +++ b/engines/kyra/sound_adlib.cpp @@ -360,13 +360,17 @@ private: uint8 *_soundData; struct QueueEntry { + QueueEntry() : data(0), id(0), volume(0) {} + QueueEntry(uint8 *ptr, uint8 track, uint8 vol) : data(ptr), id(track), volume(vol) {} uint8 *data; + uint8 id; uint8 volume; }; QueueEntry _programQueue[16]; int _programStartTimeout; int _programQueueStart, _programQueueEnd; + bool _retrySounds; void adjustSfxData(uint8 *data, int volume); uint8 *_sfxPointer; @@ -450,6 +454,7 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, int version) { _sfxPointer = 0; _programQueueStart = _programQueueEnd = 0; + _retrySounds = false; } AdLibDriver::~AdLibDriver() { @@ -545,8 +550,7 @@ void AdLibDriver::queueTrack(int track, int volume) { return; } - _programQueue[_programQueueEnd].data = trackData; - _programQueue[_programQueueEnd].volume = volume; + _programQueue[_programQueueEnd] = QueueEntry(trackData, track, volume); _programQueueEnd = (_programQueueEnd + 1) & 15; } @@ -570,6 +574,7 @@ void AdLibDriver::stopAllChannels() { if (channel != 9) noteOff(chan); } + _retrySounds = false; } // timer callback @@ -598,13 +603,25 @@ void AdLibDriver::setupPrograms() { return; uint8 *ptr = _programQueue[_programQueueStart].data; - // Clear the queue entry - _programQueue[_programQueueStart].data = 0; - _programQueueStart = (_programQueueStart + 1) & 15; + + // The AdLib driver (in its old versions used for EOB) is not suitable for modern (fast) CPUs. + // The stop sound track (track 0 which has a priority of 50) will often still be busy when the + // next sound (with a lower priority) starts which will cause that sound to be skipped. We simply + // restart incoming sounds during stop sound execution. + // UPDATE: This stilly applies after introduction of the _programQueue. + QueueEntry retrySound; + if (_version < 3 && _programQueue[_programQueueStart].id == 0) + _retrySounds = true; + else if (_retrySounds) + retrySound = _programQueue[_programQueueStart]; // Adjust data in case we hit a sound effect. adjustSfxData(ptr, _programQueue[_programQueueStart].volume); + // Clear the queue entry + _programQueue[_programQueueStart].data = 0; + _programQueueStart = (_programQueueStart + 1) & 15; + const int chan = *ptr++; const int priority = *ptr++; @@ -632,6 +649,13 @@ void AdLibDriver::setupPrograms() { // This is (probably) required to assure that the sfx are started with // the correct priority and velocity. _programStartTimeout = 2; + + retrySound = QueueEntry(); + } + + if (retrySound.data) { + debugC(9, kDebugLevelSound, "AdLibDriver::setupPrograms(): WORKAROUND - Restarting skipped sound %d)", retrySound.id); + queueTrack(retrySound.id, retrySound.volume); } } |