diff options
| author | Florian Kagerer | 2008-08-19 01:00:15 +0000 | 
|---|---|---|
| committer | Florian Kagerer | 2008-08-19 01:00:15 +0000 | 
| commit | 95745179f5a37fe664a5ca76dc7cb40afc68e457 (patch) | |
| tree | 42654e867f6e65e62530636c1828c0c636f05859 | |
| parent | 106a38efc392713d76df83f98beaad2e4996a5e2 (diff) | |
| download | scummvm-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.cpp | 183 | 
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();  } | 
