aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/sound_adlib.cpp
diff options
context:
space:
mode:
authorathrxx2011-11-06 21:31:18 +0100
committerJohannes Schickel2011-12-26 16:18:10 +0100
commit2bcae2451a9e5e59c2ad30e5c8560d9b8e117501 (patch)
tree2a0256a6a046064338abc15222245bda2d1870aa /engines/kyra/sound_adlib.cpp
parent2da431aa65da25388963687d398f4a40f2aeee73 (diff)
downloadscummvm-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/sound_adlib.cpp')
-rw-r--r--engines/kyra/sound_adlib.cpp34
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);
}
}