aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/scumm/player_v4a.cpp40
-rw-r--r--engines/scumm/player_v4a.h24
-rw-r--r--sound/mods/tfmx.cpp28
-rw-r--r--sound/mods/tfmx.h13
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);
}
}