aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/scumm/player_v4a.cpp29
-rw-r--r--engines/scumm/player_v4a.h6
-rw-r--r--sound/mods/tfmx.cpp72
-rw-r--r--sound/mods/tfmx.h13
-rw-r--r--tfmx/tfmxplayer.cpp8
5 files changed, 111 insertions, 17 deletions
diff --git a/engines/scumm/player_v4a.cpp b/engines/scumm/player_v4a.cpp
index 1483b67b42..e25f59f5f7 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), _slots(), _musicId(), _tfmxPlay(0) {
+ : _vm(scumm), _mixer(mixer), _slots(), _musicId(), _tfmxPlay(0), _tfmxSfx(0), _musicHandle(), _sfxHandle() {
init();
}
@@ -52,6 +52,14 @@ bool Player_V4A::init() {
_tfmxPlay = play;
} else
delete play;
+
+ play = new Audio::Tfmx(_mixer->getOutputRate(), true);
+ fileMdat.seek(0);
+ fileSample.seek(0);
+ if (play->load(fileMdat, fileSample)) {
+ _tfmxSfx = play;
+ } else
+ delete play;
}
return _tfmxPlay != 0;
}
@@ -111,19 +119,28 @@ void Player_V4A::startSound(int nr) {
int index = monkeyCommands[val];
if (index < 0) {
// SoundFX
- debug("Tfmx: Soundpattern %i", -index - 1);
+ index = -index - 1;
+ debug("Tfmx: Soundpattern %i", index);
+
+ _tfmxSfx->doSong(0x18);
+ _tfmxSfx->doSfx(index);
+
+ if (!_mixer->isSoundHandleActive(_sfxHandle))
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, _tfmxSfx, -1, Audio::Mixer::kMaxChannelVolume, 0, false, false);
} else {
// Song
debug("Tfmx: Song %i", index);
assert(_tfmxPlay);
- _mixer->stopHandle(_musicHandle);
_tfmxPlay->doSong(index);
_musicId = nr;
-
- _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, _tfmxPlay, -1, Audio::Mixer::kMaxChannelVolume, 0, false, false);
- _musicLastTicks = g_system->getMillis();
+
+
+ if (!_mixer->isSoundHandleActive(_musicHandle))
+ _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, _tfmxPlay, -1, Audio::Mixer::kMaxChannelVolume, 0, false, false);
+ else
+ debug("Player_V4A:: Song started while another was still running"); // Tfmx class doesnt support this properly yet
}
}
diff --git a/engines/scumm/player_v4a.h b/engines/scumm/player_v4a.h
index 6f7f6bc99f..9c122e3992 100644
--- a/engines/scumm/player_v4a.h
+++ b/engines/scumm/player_v4a.h
@@ -56,12 +56,12 @@ private:
ScummEngine *_vm;
Audio::Tfmx *_tfmxPlay;
+ Audio::Tfmx *_tfmxSfx;
Audio::Mixer *_mixer;
Audio::SoundHandle _musicHandle;
+ Audio::SoundHandle _sfxHandle;
- int _musicLastTicks;
-
- enum {V4A_MAXSFX = 8};
+ enum {V4A_MAXSFX = 1};
struct SoundSlot {
int id;
diff --git a/sound/mods/tfmx.cpp b/sound/mods/tfmx.cpp
index 7272848ae1..be9f9ebf73 100644
--- a/sound/mods/tfmx.cpp
+++ b/sound/mods/tfmx.cpp
@@ -49,7 +49,7 @@ Tfmx::Tfmx(int rate, bool stereo)
: Paula(stereo, rate), _resource() {
_playerCtx.enabled = false;
_playerCtx.song = -1;
- _playerCtx.stopWithLastPattern = true;
+ _playerCtx.stopWithLastPattern = false;
for (int i = 0; i < kNumVoices; ++i)
_channelCtx[i].paulaChannel = (byte)i;
@@ -73,6 +73,25 @@ void Tfmx::interrupt() {
}
}
+ if (channel.sfxLockTime >= 0)
+ --channel.sfxLockTime;
+ else {
+ channel.sfxLocked = false;
+ channel.customMacroPrio = 0;
+ }
+
+ if (channel.customMacro) {
+ const byte *const noteCmd = (const byte *)&channel.customMacro;
+ const int channelNo = (&channel - _channelCtx);
+
+ channel.sfxLocked = false;
+ noteCommand(noteCmd[0], noteCmd[1], (noteCmd[2] & 0xF0) | channelNo, noteCmd[3]);
+ channel.customMacro = 0;
+ channel.sfxLocked = (channel.customMacroPrio != 0);
+ }
+
+
+
// TODO: Sometimes a macro will be executed here
// apply timebased effects on Parameters
@@ -103,11 +122,6 @@ void Tfmx::interrupt() {
}
void Tfmx::effects(ChannelContext &channel) {
- if (channel.sfxLockTime >= 0)
- --channel.sfxLockTime;
- else
- channel.sfxLocked = false;
-
// addBegin
// TODO: macroNote pending?
@@ -782,12 +796,16 @@ bool Tfmx::load(Common::SeekableReadStream &musicData, Common::SeekableReadStrea
uint32 offTrackstep = musicData.readUint32BE();
uint32 offPatternP = musicData.readUint32BE();
uint32 offMacroP = musicData.readUint32BE();
+ _resource._sfxTableOffset = 0x200;
+ bool getSfxIndex = false;
// This is how MI`s TFMX-Player tests for unpacked Modules.
if (offTrackstep == 0) {
offTrackstep = 0x600 + 0x200;
offPatternP = 0x200 + 0x200;
offMacroP = 0x400 + 0x200;
+ getSfxIndex = true;
+ _resource._sfxTableOffset = 0x5FC;
}
_resource._trackstepOffset = offTrackstep;
@@ -800,6 +818,9 @@ bool Tfmx::load(Common::SeekableReadStream &musicData, Common::SeekableReadStrea
res = musicData.err();
assert(!res);
+ if (getSfxIndex)
+ _resource._sfxTableOffset = _patternOffset[127];
+
// Read in macro starting offsets
musicData.seek(offMacroP);
for (int i = 0; i < kMaxMacroOffsets; ++i)
@@ -859,6 +880,7 @@ bool Tfmx::load(Common::SeekableReadStream &musicData, Common::SeekableReadStrea
void Tfmx::doMacro(int macro, int note) {
assert(0 <= macro && macro < kMaxMacroOffsets);
assert(0 <= note && note < 0xC0);
+ Common::StackLock lock(_mutex);
_playerCtx.song = -1;
_playerCtx.volume = 0x40;
@@ -885,6 +907,7 @@ void Tfmx::doMacro(int macro, int note) {
void Tfmx::doSong(int songPos) {
assert(0 <= songPos && songPos < kNumSubsongs);
+ Common::StackLock lock(_mutex);
_playerCtx.song = (int8)songPos;
_playerCtx.volume = 0x40;
@@ -906,8 +929,6 @@ void Tfmx::doSong(int songPos) {
_playerCtx.patternCount = 0;
- _playerCtx.pendingTrackstep = true;
-
for (int i = 0; i < kNumChannels; ++i) {
_patternCtx[i].command = 0xFF;
_patternCtx[i].expose = 0;
@@ -920,11 +941,46 @@ void Tfmx::doSong(int songPos) {
_channelCtx[i].vibValue = 0;
stopChannel(_channelCtx[i]);
_channelCtx[i].volume = 0;
+ _channelCtx[i].customMacro = 0;
}
setTimerBaseValue(kPalCiaClock);
setInterruptFreqUnscaled(ciaIntervall);
+
+ while (trackStep())
+ ;
+ _playerCtx.pendingTrackstep = false;
startPaula();
}
+void Tfmx::doSfx(int sfxIndex) {
+ assert(0 <= sfxIndex && sfxIndex < 128);
+ Common::StackLock lock(_mutex);
+
+ const byte *sfxEntry = _resource.getSfxPtr(sfxIndex);
+
+ if (sfxEntry[0] == 0xFB) {
+ // custompattern
+ const uint8 patCmd = sfxEntry[2];
+ const int8 patExp = (int8)sfxEntry[3];
+ } else {
+ // custommacro
+ // byte index = (_playerCtx.song >= 0) ? sfxEntry[2] : sfxEntry[4];
+ const byte channelNo = sfxEntry[2] % kNumVoices;
+ const byte priority = sfxEntry[5] & 0x7F;
+
+ ChannelContext &channel = _channelCtx[channelNo];
+
+ 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;
+ }
+ }
+ }
+}
+
}
diff --git a/sound/mods/tfmx.h b/sound/mods/tfmx.h
index bcb25fbf8b..9761cef494 100644
--- a/sound/mods/tfmx.h
+++ b/sound/mods/tfmx.h
@@ -47,6 +47,7 @@ public:
void interrupt();
void doSong(int songPos);
+ void doSfx(int sfxIndex);
void doMacro(int macro, int note);
bool load(Common::SeekableReadStream &musicData, Common::SeekableReadStream &sampleData);
int getTicks() {return _playerCtx.tickCount;}
@@ -60,6 +61,7 @@ public:
struct Resource {
uint32 _trackstepOffset; //!< Offset in mdat
+ uint32 _sfxTableOffset;
byte *_mdatData; //!< Currently the whole mdat-File
byte *_sampleData; //!< Currently the whole sample-File
@@ -72,6 +74,13 @@ public:
uint32 headerUnknown;
char textField[6 * 40];
+ const byte *getSfxPtr(uint8 index = 0) {
+ byte *sfxPtr = (byte *)(_mdatData + _sfxTableOffset + index * 8);
+
+ boundaryCheck(_mdatData, _mdatLen, sfxPtr, 8);
+ return sfxPtr;
+ }
+
const uint16 *getTrackPtr(uint16 trackstep = 0) {
uint16 *trackData = (uint16 *)(_mdatData + _trackstepOffset + 16 * trackstep);
@@ -128,6 +137,10 @@ public:
uint8 macroLoopCount;
bool macroRun;
+ uint32 customMacro;
+ uint8 customMacroIndex;
+ uint8 customMacroPrio;
+
bool sfxLocked;
int16 sfxLockTime;
bool keyUp;
diff --git a/tfmx/tfmxplayer.cpp b/tfmx/tfmxplayer.cpp
index b286d6d43d..82e93412e1 100644
--- a/tfmx/tfmxplayer.cpp
+++ b/tfmx/tfmxplayer.cpp
@@ -121,6 +121,14 @@ void tfmxmain(const int argc, const char *const argv[]) {
player->doSong(param);
hasCmd = true;
}
+ } else if (!strcmp("-c", argv[i])) {
+ if (i + 1 < argc) {
+ param = atoi(argv[++i]);
+ debug( "play custom %02X", param);
+ player->doSong(0x18);
+ player->doSfx(param);
+ hasCmd = true;
+ }
} else if (!strcmp("-flac", argv[i])) {
playflag = 2;
}