diff options
-rw-r--r-- | engines/scumm/player_v4a.cpp | 40 | ||||
-rw-r--r-- | engines/scumm/player_v4a.h | 24 | ||||
-rw-r--r-- | sound/mods/tfmx.cpp | 28 | ||||
-rw-r--r-- | sound/mods/tfmx.h | 13 |
4 files changed, 81 insertions, 24 deletions
diff --git a/engines/scumm/player_v4a.cpp b/engines/scumm/player_v4a.cpp index 1c438392c4..f44d77089e 100644 --- a/engines/scumm/player_v4a.cpp +++ b/engines/scumm/player_v4a.cpp @@ -33,7 +33,7 @@ namespace Scumm { Player_V4A::Player_V4A(ScummEngine *scumm, Audio::Mixer *mixer) - : _vm(scumm), _mixer(mixer), _musicId(), _tfmxPlay(0), _tfmxSfx(0), _musicHandle(), _sfxHandle() { + : _vm(scumm), _mixer(mixer), _musicId(), _sfxSlots(), _tfmxPlay(0), _tfmxSfx(0), _musicHandle(), _sfxHandle() { init(); } @@ -72,21 +72,31 @@ Player_V4A::~Player_V4A() { } void Player_V4A::setMusicVolume(int vol) { - debug("player_v4a: setMusicVolume %i", vol); + debug(5, "player_v4a: setMusicVolume %i", vol); } void Player_V4A::stopAllSounds() { - if (_musicId) - stopSound(_musicId); + debug(5, "player_v4a: stopAllSounds"); + if (_tfmxPlay) + _tfmxPlay->stopSong(); + _musicId = 0; + if (_tfmxSfx) + _tfmxSfx->stopSong(); + clearSfxSlots(); } void Player_V4A::stopSound(int nr) { + debug(5, "player_v4a: stopSound %d", nr); if (nr == _musicId) { _tfmxPlay->stopSong(); - //_mixer->stopHandle(_musicHandle); _musicId = 0; - } else - warning("player_v4a: stop Sound %d", nr); + } else { + const int chan = getSfxChan(nr); + if (chan != -1) { + setSfxSlot(chan, 0); + _tfmxSfx->stopMacroEffect(chan); + } + } } void Player_V4A::startSound(int nr) { @@ -106,7 +116,7 @@ void Player_V4A::startSound(int nr) { const int val = ptr[9]; if (val < 0 || val >= ARRAYSIZE(monkeyCommands)) { - debug(3, "Tfmx: illegal Songnumber %i", val); + warning("player_v4a: illegal Songnumber %i", val); return; } @@ -114,21 +124,27 @@ void Player_V4A::startSound(int nr) { return; int index = monkeyCommands[val]; + const byte type = ptr[6]; if (index < 0) { // SoundFX index = -index - 1; - debug(5, "player_v4a: play custom %i", index); + debug(3, "player_v4a: play %d: custom %i - %02X", nr, index, type); if (_tfmxSfx->getSongIndex() < 0) _tfmxSfx->doSong(0x18); - _tfmxSfx->doSfx(index); + const int chan = _tfmxSfx->doSfx(index); + if (chan >= 0 && chan < ARRAYSIZE(_sfxSlots)) + setSfxSlot(chan, nr, type); + else + warning("player_v4a: custom %i is not of required type", index); if (!_mixer->isSoundHandleActive(_sfxHandle)) _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, _tfmxSfx, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true); } else { // Song - debug(5, "player_v4a: play song %i", index); - assert(_tfmxPlay); + debug(3, "player_v4a: play %d: song %i - %02X", nr, index, type); + if (ptr[6] != 0x7F) + warning("player_v4a: Song has wrong type"); _tfmxPlay->doSong(index); _musicId = nr; diff --git a/engines/scumm/player_v4a.h b/engines/scumm/player_v4a.h index 5e83adbf67..a261235867 100644 --- a/engines/scumm/player_v4a.h +++ b/engines/scumm/player_v4a.h @@ -62,6 +62,30 @@ private: Audio::SoundHandle _sfxHandle; int _musicId; + + struct SfxChan { + int id; + byte type; + } _sfxSlots[4]; + + int getSfxChan(int id) const { + for (int i = 0; i < ARRAYSIZE(_sfxSlots); ++i) + if (_sfxSlots[i].id == id) + return i; + return -1; + } + + void setSfxSlot(int channel, int id, byte type = 0) { + _sfxSlots[channel].id = id; + _sfxSlots[channel].type = type; + } + + void clearSfxSlots() { + for (int i = 0; i < ARRAYSIZE(_sfxSlots); ++i){ + _sfxSlots[i].id = 0; + _sfxSlots[i].type = 0; + } + } bool init(); }; diff --git a/sound/mods/tfmx.cpp b/sound/mods/tfmx.cpp index 1d5422d9fc..26879f85a6 100644 --- a/sound/mods/tfmx.cpp +++ b/sound/mods/tfmx.cpp @@ -139,19 +139,19 @@ void Tfmx::effects(ChannelContext &channel) { } // portamento - if (channel.portaDelta && !(--channel.portaCount)) { + if (channel.portaDelta && --channel.portaCount == 0) { channel.portaCount = channel.portaSkip; bool resetPorta = true; - uint16 period = channel.refPeriod; - const uint16 portaVal = channel.portaValue; + uint16 period = channel.refPeriod; // d1 + uint16 portaVal = channel.portaValue; // d0 if (period > portaVal) { - period = ((uint32)period * (uint16)((1 << 8) - channel.portaDelta)) >> 8; + portaVal = ((uint32)portaVal * (uint16)((1 << 8) + channel.portaDelta)) >> 8; resetPorta = (period <= portaVal); } else if (period < portaVal) { - period = ((uint32)period * (uint16)((1 << 8) + channel.portaDelta)) >> 8; + portaVal = ((uint32)portaVal * (uint16)((1 << 8) - channel.portaDelta)) >> 8; resetPorta = (period >= portaVal); } @@ -159,7 +159,7 @@ void Tfmx::effects(ChannelContext &channel) { channel.portaDelta = 0; channel.portaValue = channel.refPeriod & 0x7FF; } else { - channel.period = period & 0x7FF; + channel.period = channel.portaValue = portaVal & 0x7FF; //Paula::setChannelPeriod(channel.paulaChannel, channel.period); } } @@ -903,8 +903,10 @@ void Tfmx::doMacro(int note, int macro, int relVol, int finetune, int channelNo) void Tfmx::stopSong(bool stopAudio) { Common::StackLock lock(_mutex); _playerCtx.song = -1; - if (stopAudio) + if (stopAudio) { stopMacroChannels(); + stopPaula(); + } } void Tfmx::doSong(int songPos, bool stopAudio) { @@ -912,8 +914,10 @@ void Tfmx::doSong(int songPos, bool stopAudio) { Common::StackLock lock(_mutex); stopPatternChannels(); - if (stopAudio) + if (stopAudio) { stopMacroChannels(); + stopPaula(); + } _playerCtx.song = (int8)songPos; @@ -939,7 +943,7 @@ void Tfmx::doSong(int songPos, bool stopAudio) { startPaula(); } -void Tfmx::doSfx(int sfxIndex) { +int Tfmx::doSfx(int sfxIndex, bool unlockChannel) { assert(0 <= sfxIndex && sfxIndex < 128); Common::StackLock lock(_mutex); @@ -955,15 +959,21 @@ void Tfmx::doSfx(int sfxIndex) { const byte priority = sfxEntry[5] & 0x7F; ChannelContext &channel = _channelCtx[channelNo]; + if (unlockChannel) + unlockMacroChannel(channel); + const int16 sfxLocktime = channel.sfxLockTime; if (priority >= channel.customMacroPrio || sfxLocktime < 0) { if (sfxIndex != channel.customMacroIndex || sfxLocktime < 0 || (sfxEntry[5] < 0x80)) { channel.customMacro = READ_UINT32(sfxEntry); // intentionally not "endian-correct" channel.customMacroPrio = priority; channel.customMacroIndex = (uint8)sfxIndex; + debug(3, "Tfmx: running Macro %08X on channel %i - priority: %02X", TO_BE_32(channel.customMacro), channelNo, priority); + return channelNo; } } } + return -1; } } diff --git a/sound/mods/tfmx.h b/sound/mods/tfmx.h index 195b582c69..91ea408834 100644 --- a/sound/mods/tfmx.h +++ b/sound/mods/tfmx.h @@ -48,12 +48,19 @@ public: void interrupt(); void stopSong(bool stopAudio = true); void doSong(int songPos, bool stopAudio = false); - void doSfx(int sfxIndex); + int doSfx(int sfxIndex, bool unlockChannel = false); void doMacro(int note, int macro, int relVol = 0, int finetune = 0, int channelNo = 0); bool load(Common::SeekableReadStream &musicData, Common::SeekableReadStream &sampleData); int getTicks() {return _playerCtx.tickCount;} int getSongIndex() {return _playerCtx.song;} - uint16 getSignal(int index) {return _playerCtx.signal[index];} + uint16 getSignal(int index) {return (index < ARRAYSIZE(_playerCtx.signal)) ? _playerCtx.signal[index] : 0xFFFF;} + void stopMacroEffect(int channel) { + assert(0 <= channel && channel < kNumVoices); + Common::StackLock lock(_mutex); + unlockMacroChannel(_channelCtx[channel]); + clearMacroProgramm(_channelCtx[channel]); + Paula::disableChannel(_channelCtx[channel].paulaChannel); + } // Note: everythings public so the debug-Routines work. // private: @@ -270,7 +277,7 @@ public: channel.refPeriod = ((uint32)noteInt * finetune >> 8); if (!channel.portaDelta) { channel.period = channel.refPeriod; - Paula::setChannelPeriod(channel.paulaChannel, channel.period); + //Paula::setChannelPeriod(channel.paulaChannel, channel.period); } } |