[Scummvm-cvs-logs] SF.net SVN: scummvm:[34015] scummvm/trunk/engines/kyra/sound_towns.cpp
athrxx at users.sourceforge.net
athrxx at users.sourceforge.net
Tue Aug 19 03:00:16 CEST 2008
Revision: 34015
http://scummvm.svn.sourceforge.net/scummvm/?rev=34015&view=rev
Author: athrxx
Date: 2008-08-19 01:00:15 +0000 (Tue, 19 Aug 2008)
Log Message:
-----------
fixed bug that caused a lockup in certain configurations when the music was fading
Modified Paths:
--------------
scummvm/trunk/engines/kyra/sound_towns.cpp
Modified: scummvm/trunk/engines/kyra/sound_towns.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound_towns.cpp 2008-08-18 22:27:21 UTC (rev 34014)
+++ scummvm/trunk/engines/kyra/sound_towns.cpp 2008-08-19 01:00:15 UTC (rev 34015)
@@ -1592,7 +1592,7 @@
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 @@
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 @@
uint16 _tempo;
bool _musicPlaying;
bool _sfxPlaying;
- bool _fading;
+ uint8 _fading;
uint8 _looping;
uint32 _musicTickCounter;
@@ -2798,6 +2799,63 @@
*_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_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 @@
unlock();
}
-void TownsPC98_OpnDriver::fadeOut() {
+void TownsPC98_OpnDriver::fadeStep() {
if (!_musicPlaying)
return;
- if (_hasPCM) {
- lock();
- if (_updatePCMFlag & _pcmChannel->_idFlag)
- _pcmChannel->reset();
- unlock();
+ lock();
+
+ 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();
+ }
- 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();
+ if (!_fading) {
+ _fading = 19;
+ if (_hasPCM) {
+ if (_updatePCMFlag & _pcmChannel->_idFlag)
+ _pcmChannel->reset();
}
- for (int j = 0; j < _numSSG; j++) {
- if (_updateSSGFlag & _ssgChannels[j]->_idFlag)
- _ssgChannels[j]->fadeStep();
- }
-
- unlock();
-
- while (_musicPlaying) {
- if (_musicTickCounter >= dTime)
- break;
- }
+ } else {
+ if (!--_fading)
+ reset();
}
- reset();
+ unlock();
}
void TownsPC98_OpnDriver::callback() {
@@ -3831,7 +3825,13 @@
}
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::beginFadeOut() {
- _driver->fadeOut();
+ if (!_driver->musicPlaying())
+ return;
+
+ for (int i = 0; i < 20; i++) {
+ _driver->fadeStep();
+ _vm->delay(32);
+ }
+
haltTrack();
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list