aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorNorbert Lange2009-06-19 14:30:09 +0000
committerNorbert Lange2009-06-19 14:30:09 +0000
commitc7697fb200a10f2c6406239b32d66cc7163c3d59 (patch)
tree011ce214b4ca548aaade6740f9621de9ddf567b6 /sound
parentc3596c184b032744d0a6d0d72879dcde854ec93e (diff)
downloadscummvm-rg350-c7697fb200a10f2c6406239b32d66cc7163c3d59.tar.gz
scummvm-rg350-c7697fb200a10f2c6406239b32d66cc7163c3d59.tar.bz2
scummvm-rg350-c7697fb200a10f2c6406239b32d66cc7163c3d59.zip
added support for SFX by using a seperate Player for them.
svn-id: r41676
Diffstat (limited to 'sound')
-rw-r--r--sound/mods/tfmx.cpp72
-rw-r--r--sound/mods/tfmx.h13
2 files changed, 77 insertions, 8 deletions
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;