aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Kagerer2008-08-19 01:00:15 +0000
committerFlorian Kagerer2008-08-19 01:00:15 +0000
commit95745179f5a37fe664a5ca76dc7cb40afc68e457 (patch)
tree42654e867f6e65e62530636c1828c0c636f05859
parent106a38efc392713d76df83f98beaad2e4996a5e2 (diff)
downloadscummvm-rg350-95745179f5a37fe664a5ca76dc7cb40afc68e457.tar.gz
scummvm-rg350-95745179f5a37fe664a5ca76dc7cb40afc68e457.tar.bz2
scummvm-rg350-95745179f5a37fe664a5ca76dc7cb40afc68e457.zip
fixed bug that caused a lockup in certain configurations when the music was fading
svn-id: r34015
-rw-r--r--engines/kyra/sound_towns.cpp183
1 files changed, 95 insertions, 88 deletions
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index 8678498855..5fce99f495 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -1592,7 +1592,7 @@ public:
void loadMusicData(uint8 *data, bool loadPaused = false);
void loadSoundEffectData(uint8 *data, uint8 trackNum);
void reset();
- void fadeOut();
+ void fadeStep();
void pause() { _musicPlaying = false; }
void cont() { _musicPlaying = true; }
@@ -1601,6 +1601,7 @@ public:
void nextTick(int32 *buffer, uint32 bufferSize);
bool looping() { return _looping == _updateChannelsFlag ? true : false; }
+ bool musicPlaying() { return _musicPlaying; }
// AudioStream interface
int inline readBuffer(int16 *buffer, const int numSamples);
@@ -1660,7 +1661,7 @@ protected:
uint16 _tempo;
bool _musicPlaying;
bool _sfxPlaying;
- bool _fading;
+ uint8 _fading;
uint8 _looping;
uint32 _musicTickCounter;
@@ -2798,6 +2799,63 @@ void TownsPC98_OpnSquareSineSource::writeReg(uint8 address, uint8 value, bool fo
*_regIndex = value;
}
+void TownsPC98_OpnSquareSineSource::nextTick(int32 *buffer, uint32 bufferSize) {
+ if (!_ready)
+ return;
+
+ for (uint32 i = 0; i < bufferSize; i++) {
+ _timer += _tickLength;
+ while (_timer > 0x30000) {
+ _timer -= 0x30000;
+
+ if (++_nTick >= (_reg[6] & 0x1f)) {
+ if ((_rand + 1) & 2)
+ _outN ^= 1;
+
+ _rand = (((_rand & 1) ^ ((_rand >> 3) & 1)) << 16) | (_rand >> 1);
+ _nTick = 0;
+ }
+
+ for (int ii = 0; ii < 3; ii++) {
+ if (++_channels[ii].tick >= (((_reg[ii * 2 + 1] & 0x0f) << 8) | _reg[ii * 2])) {
+ _channels[ii].tick = 0;
+ _channels[ii].smp ^= 1;
+ }
+ _channels[ii].out = (_channels[ii].smp | ((_reg[7] >> ii) & 1)) & (_outN | ((_reg[7] >> (ii + 3)) & 1));
+ }
+
+ if (_evpUpdate) {
+ if (++_evpUpdateCnt >= ((_reg[12] << 8) | _reg[11])) {
+ _evpUpdateCnt = 0;
+
+ if (--_evpTimer < 0) {
+ if (_cont) {
+ _evpTimer &= 0x1f;
+ } else {
+ _evpUpdate = false;
+ _evpTimer = 0;
+ }
+ }
+ }
+ }
+ _pReslt = _evpTimer ^ _attack;
+ updatesRegs();
+ }
+
+ int32 finOut = 0;
+ for (int ii = 0; ii < 3; ii++) {
+ if ((_reg[ii + 8] >> 4) & 1)
+ finOut += _tleTable[_channels[ii].out ? _pReslt : 0];
+ else
+ finOut += _tlTable[_channels[ii].out ? (_reg[ii + 8] & 0x0f) : 0];
+ }
+
+ finOut /= 2;
+ buffer[i << 1] += finOut;
+ buffer[(i << 1) + 1] += finOut;
+ }
+}
+
void TownsPC98_OpnSquareSineSource::updatesRegs() {
for (int i = 0; i < _updateRequest;) {
uint8 b = _updateRequestBuf[i++];
@@ -2977,63 +3035,6 @@ void TownsPC98_OpnPercussionSource::advanceInput(PcmInstrument *ins) {
}
}
-void TownsPC98_OpnSquareSineSource::nextTick(int32 *buffer, uint32 bufferSize) {
- if (!_ready)
- return;
-
- for (uint32 i = 0; i < bufferSize; i++) {
- _timer += _tickLength;
- while (_timer > 0x30000) {
- _timer -= 0x30000;
-
- if (++_nTick >= (_reg[6] & 0x1f)) {
- if ((_rand + 1) & 2)
- _outN ^= 1;
-
- _rand = (((_rand & 1) ^ ((_rand >> 3) & 1)) << 16) | (_rand >> 1);
- _nTick = 0;
- }
-
- for (int ii = 0; ii < 3; ii++) {
- if (++_channels[ii].tick >= (((_reg[ii * 2 + 1] & 0x0f) << 8) | _reg[ii * 2])) {
- _channels[ii].tick = 0;
- _channels[ii].smp ^= 1;
- }
- _channels[ii].out = (_channels[ii].smp | ((_reg[7] >> ii) & 1)) & (_outN | ((_reg[7] >> (ii + 3)) & 1));
- }
-
- if (_evpUpdate) {
- if (++_evpUpdateCnt >= ((_reg[12] << 8) | _reg[11])) {
- _evpUpdateCnt = 0;
-
- if (--_evpTimer < 0) {
- if (_cont) {
- _evpTimer &= 0x1f;
- } else {
- _evpUpdate = false;
- _evpTimer = 0;
- }
- }
- }
- }
- _pReslt = _evpTimer ^ _attack;
- updatesRegs();
- }
-
- int32 finOut = 0;
- for (int ii = 0; ii < 3; ii++) {
- if ((_reg[ii + 8] >> 4) & 1)
- finOut += _tleTable[_channels[ii].out ? _pReslt : 0];
- else
- finOut += _tlTable[_channels[ii].out ? (_reg[ii + 8] & 0x0f) : 0];
- }
-
- finOut /= 2;
- buffer[i << 1] += finOut;
- buffer[(i << 1) + 1] += finOut;
- }
-}
-
TownsPC98_OpnDriver::TownsPC98_OpnDriver(Audio::Mixer *mixer, OpnType type) :
_mixer(mixer), _trackPtr(0), _musicPlaying(false), _sfxPlaying(false), _fading(false), _channels(0),
_ssgChannels(0), _sfxChannels(0), _pcmChannel(0), _looping(0), _opnCarrier(_drvTables + 76),
@@ -3317,41 +3318,34 @@ void TownsPC98_OpnDriver::reset() {
unlock();
}
-void TownsPC98_OpnDriver::fadeOut() {
+void TownsPC98_OpnDriver::fadeStep() {
if (!_musicPlaying)
return;
- if (_hasPCM) {
- lock();
- if (_updatePCMFlag & _pcmChannel->_idFlag)
- _pcmChannel->reset();
- unlock();
- }
-
- for (int i = 0; i < 20; i++) {
- lock();
-
- _fading = true;
-
- uint32 dTime = _musicTickCounter + 2;
- for (int j = 0; j < _numChan; j++) {
- if (_updateChannelsFlag & _channels[j]->_idFlag)
- _channels[j]->fadeStep();
- }
- for (int j = 0; j < _numSSG; j++) {
- if (_updateSSGFlag & _ssgChannels[j]->_idFlag)
- _ssgChannels[j]->fadeStep();
- }
+ lock();
- unlock();
+ for (int j = 0; j < _numChan; j++) {
+ if (_updateChannelsFlag & _channels[j]->_idFlag)
+ _channels[j]->fadeStep();
+ }
+
+ for (int j = 0; j < _numSSG; j++) {
+ if (_updateSSGFlag & _ssgChannels[j]->_idFlag)
+ _ssgChannels[j]->fadeStep();
+ }
- while (_musicPlaying) {
- if (_musicTickCounter >= dTime)
- break;
+ if (!_fading) {
+ _fading = 19;
+ if (_hasPCM) {
+ if (_updatePCMFlag & _pcmChannel->_idFlag)
+ _pcmChannel->reset();
}
+ } else {
+ if (!--_fading)
+ reset();
}
- reset();
+ unlock();
}
void TownsPC98_OpnDriver::callback() {
@@ -3831,7 +3825,13 @@ void SoundPC98::haltTrack() {
}
void SoundPC98::beginFadeOut() {
- _driver->fadeOut();
+ if (!_driver->musicPlaying())
+ return;
+
+ for (int i = 0; i < 20; i++) {
+ _driver->fadeStep();
+ _vm->delay(32);
+ }
haltTrack();
}
@@ -3930,7 +3930,14 @@ void SoundTownsPC98_v2::haltTrack() {
}
void SoundTownsPC98_v2::beginFadeOut() {
- _driver->fadeOut();
+ if (!_driver->musicPlaying())
+ return;
+
+ for (int i = 0; i < 20; i++) {
+ _driver->fadeStep();
+ _vm->delay(32);
+ }
+
haltTrack();
}