aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dists/msvc9/scummvm-tfmx.vcproj24
-rw-r--r--engines/scumm/player_v4a.cpp2
-rw-r--r--sound/mods/tfmx.cpp139
-rw-r--r--sound/mods/tfmx.h35
-rw-r--r--tfmx/tfmxplayer.cpp7
5 files changed, 163 insertions, 44 deletions
diff --git a/dists/msvc9/scummvm-tfmx.vcproj b/dists/msvc9/scummvm-tfmx.vcproj
index 0471eaaac2..226a957329 100644
--- a/dists/msvc9/scummvm-tfmx.vcproj
+++ b/dists/msvc9/scummvm-tfmx.vcproj
@@ -1994,6 +1994,14 @@
<File
RelativePath="..\..\tfmx\mxtxplayer.cpp"
>
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
</File>
<File
RelativePath="..\..\TFMX\README.txt"
@@ -2002,6 +2010,14 @@
<File
RelativePath="..\..\tfmx\tfmxdebug.cpp"
>
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
</File>
<File
RelativePath="..\..\tfmx\tfmxdebug.h"
@@ -2010,6 +2026,14 @@
<File
RelativePath="..\..\TFMX\tfmxplayer.cpp"
>
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
</File>
</Filter>
</Files>
diff --git a/engines/scumm/player_v4a.cpp b/engines/scumm/player_v4a.cpp
index 7c3aab0462..7c2b17ac3c 100644
--- a/engines/scumm/player_v4a.cpp
+++ b/engines/scumm/player_v4a.cpp
@@ -49,7 +49,7 @@ bool Player_V4A::init() {
if (mdatExists && sampleExists) {
Audio::Tfmx *play = new Audio::Tfmx(_mixer->getOutputRate(), true);
if (play->load(fileMdat, fileSample)) {
- play->setSignalPtr(_signal);
+ play->setSignalPtr(_signal, ARRAYSIZE(_signal));
_tfmxPlay = play;
} else
delete play;
diff --git a/sound/mods/tfmx.cpp b/sound/mods/tfmx.cpp
index b2826d6299..602045762d 100644
--- a/sound/mods/tfmx.cpp
+++ b/sound/mods/tfmx.cpp
@@ -30,9 +30,13 @@
#include "common/debug.h"
#include "sound/mods/tfmx.h"
-#ifdef _MSC_VER
-#include "tfmx/tfmxdebug.h"
-#endif
+
+// couple debug-functions
+namespace {
+ void displayPatternstep(const void *const vptr);
+ void displayMacroStep(const void *const vptr);
+}
+
namespace Audio {
const uint16 Tfmx::noteIntervalls[64] = {
@@ -99,10 +103,8 @@ void Tfmx::interrupt() {
// see if we have to run the macro-program
if (channel.macroRun) {
- if (!channel.macroWait) {
+ if (!channel.macroWait)
macroRun(channel);
- //assert( !channel.deferWait ); // we can remove this variable as it should be never true after macroRun?
- }
else
--channel.macroWait;
}
@@ -454,7 +456,7 @@ void Tfmx::macroRun(ChannelContext &channel) {
break;
case 0x20: // Signal. Parameters: signalnumber/value
- if (_playerCtx.signal)
+ if (_playerCtx.numSignals > macroPtr[1])
_playerCtx.signal[macroPtr[1]] = READ_BE_UINT16(&macroPtr[2]);
continue;
@@ -612,15 +614,7 @@ bool Tfmx::patternRun(PatternContext &pattern) {
continue;
case 10: // fade master volume
- _playerCtx.fadeCount = _playerCtx.fadeSkip = patternPtr[1];
- _playerCtx.fadeEndVolume = (int8)patternPtr[3];
- if (_playerCtx.fadeSkip) {
- const int diff = _playerCtx.fadeEndVolume - _playerCtx.volume;
- _playerCtx.fadeDelta = (diff != 0) ? ((diff > 0) ? 1 : -1) : 0;
- } else {
- _playerCtx.volume = _playerCtx.fadeEndVolume;
- _playerCtx.fadeDelta = 0;
- }
+ initFadeCommand((uint8)patternPtr[1], (int8)patternPtr[1]);
++_trackCtx.posInd;
continue;
@@ -642,7 +636,7 @@ bool Tfmx::patternRun(PatternContext &pattern) {
continue;
case 13: // Cue
- if (_playerCtx.signal)
+ if (_playerCtx.numSignals > patternPtr[1])
_playerCtx.signal[patternPtr[1]] = READ_BE_UINT16(&patternPtr[2]);
continue;
@@ -709,16 +703,8 @@ bool Tfmx::trackRun(const bool incStep) {
break;
}
case 4: // Fade
- _playerCtx.fadeCount = _playerCtx.fadeSkip = (uint8)READ_BE_UINT16(&trackData[2]);
- _playerCtx.fadeEndVolume = (int8)READ_BE_UINT16(&trackData[3]);
-
- if (_playerCtx.fadeSkip) {
- const int diff = _playerCtx.fadeEndVolume - _playerCtx.volume;
- _playerCtx.fadeDelta = (diff != 0) ? ((diff > 0) ? 1 : -1) : 0;
- } else {
- _playerCtx.volume = _playerCtx.fadeEndVolume;
- _playerCtx.fadeDelta = 0;
- }
+ // load the LSB of the 16bit words
+ initFadeCommand(((uint8 *)&trackData[2])[1], ((int8 *)&trackData[3])[1]);
break;
case 3: // Unknown, stops player aswell
@@ -919,6 +905,14 @@ void Tfmx::doMacro(int note, int macro, int relVol, int finetune, int channelNo)
startPaula();
}
+void Tfmx::stopMacroEffect(int channel) {
+ assert(0 <= channel && channel < kNumVoices);
+ Common::StackLock lock(_mutex);
+ unlockMacroChannel(_channelCtx[channel]);
+ clearMacroProgramm(_channelCtx[channel]);
+ Paula::disableChannel(_channelCtx[channel].paulaChannel);
+}
+
void Tfmx::stopSong(bool stopAudio) {
Common::StackLock lock(_mutex);
_playerCtx.song = -1;
@@ -994,3 +988,94 @@ int Tfmx::doSfx(uint16 sfxIndex, bool unlockChannel) {
}
} // End of namespace Audio
+
+// some debugging functions
+namespace {
+#ifndef NDEBUG
+void displayMacroStep(const void *const vptr) {
+ const char *tableMacros[] = {
+ "DMAoff+Resetxx/xx/xx flag/addset/vol ",
+ "DMAon (start sample at selected begin) ",
+ "SetBegin xxxxxx sample-startadress",
+ "SetLen ..xxxx sample-length ",
+ "Wait ..xxxx count (VBI''s) ",
+ "Loop xx/xxxx count/step ",
+ "Cont xx/xxxx macro-number/step ",
+ "-------------STOP----------------------",
+ "AddNote xx/xxxx note/detune ",
+ "SetNote xx/xxxx note/detune ",
+ "Reset Vibrato-Portamento-Envelope ",
+ "Portamento xx/../xx count/speed ",
+ "Vibrato xx/../xx speed/intensity ",
+ "AddVolume ....xx volume 00-3F ",
+ "SetVolume ....xx volume 00-3F ",
+ "Envelope xx/xx/xx speed/count/endvol",
+ "Loop key up xx/xxxx count/step ",
+ "AddBegin xx/xxxx count/add to start",
+ "AddLen ..xxxx add to sample-len ",
+ "DMAoff stop sample but no clear ",
+ "Wait key up ....xx count (VBI''s) ",
+ "Go submacro xx/xxxx macro-number/step ",
+ "--------Return to old macro------------",
+ "Setperiod ..xxxx DMA period ",
+ "Sampleloop ..xxxx relative adress ",
+ "-------Set one shot sample-------------",
+ "Wait on DMA ..xxxx count (Wavecycles)",
+ "Random play xx/xx/xx macro/speed/mode ",
+ "Splitkey xx/xxxx key/macrostep ",
+ "Splitvolume xx/xxxx volume/macrostep ",
+ "Addvol+note xx/fe/xx note/CONST./volume",
+ "SetPrevNote xx/xxxx note/detune ",
+ "Signal xx/xxxx signalnumber/value",
+ "Play macro xx/.x/xx macro/chan/detune ",
+ "SID setbeg xxxxxx sample-startadress",
+ "SID setlen xx/xxxx buflen/sourcelen ",
+ "SID op3 ofs xxxxxx offset ",
+ "SID op3 frq xx/xxxx speed/amplitude ",
+ "SID op2 ofs xxxxxx offset ",
+ "SID op2 frq xx/xxxx speed/amplitude ",
+ "SID op1 xx/xx/xx speed/amplitude/TC",
+ "SID stop xx.... flag (1=clear all)"
+ };
+
+ const byte *const macroData = (const byte *const)vptr;
+ if (macroData[0] < ARRAYSIZE(tableMacros))
+ debug("%s %02X%02X%02X", tableMacros[macroData[0]], macroData[1], macroData[2], macroData[3]);
+ else
+ debug("Unkown Macro #%02X %02X%02X%02X", macroData[0], macroData[1], macroData[2], macroData[3]);
+}
+
+void displayPatternstep(const void *const vptr) {
+ const char *tablePatterns[] = {
+ "End --Next track step--",
+ "Loop[count / step.w]",
+ "Cont[patternno./ step.w]",
+ "Wait[count 00-FF--------",
+ "Stop--Stop this pattern-",
+ "Kup^-Set key up/channel]",
+ "Vibr[speed / rate.b]",
+ "Enve[speed /endvolume.b]",
+ "GsPt[patternno./ step.w]",
+ "RoPt-Return old pattern-",
+ "Fade[speed /endvolume.b]",
+ "PPat[patt./track+transp]",
+ "Lock---------ch./time.b]",
+ "Cue [number.b/ value.w]",
+ "Stop-Stop custompattern-",
+ "NOP!-no operation-------"
+ };
+
+ const byte *const patData = (const byte *const)vptr;
+ const byte command = patData[0];
+ if (command < 0xF0) { // Playnote
+ const byte flags = command >> 6; // 0-1 means note+detune, 2 means wait, 3 means portamento?
+ char *flagsSt[] = { "Note ", "Note ", "Wait ", "Porta" };
+ debug("%s %02X%02X%02X%02X", flagsSt[flags], patData[0], patData[1], patData[2], patData[3]);
+ } else
+ debug("%s %02X%02X%02X",tablePatterns[command & 0xF], patData[1], patData[2], patData[3]);
+}
+#else
+void displayMacroStep(const void *const vptr, int chan, int index) {}
+void displayPatternstep(const void *const vptr) {}
+#endif
+} // End of namespace
diff --git a/sound/mods/tfmx.h b/sound/mods/tfmx.h
index 2f05b0da70..267c122ce3 100644
--- a/sound/mods/tfmx.h
+++ b/sound/mods/tfmx.h
@@ -45,7 +45,6 @@ public:
Tfmx(int rate, bool stereo);
virtual ~Tfmx();
- void interrupt();
void stopSong(bool stopAudio = true);
void doSong(int songPos, bool stopAudio = false);
int doSfx(uint16 sfxIndex, bool unlockChannel = false);
@@ -53,17 +52,13 @@ public:
bool load(Common::SeekableReadStream &musicData, Common::SeekableReadStream &sampleData);
int getTicks() const { return _playerCtx.tickCount; }
int getSongIndex() const { return _playerCtx.song; }
- void setSignalPtr(uint16 *ptr) { _playerCtx.signal = ptr; }
- void stopMacroEffect(int channel) {
- assert(0 <= channel && channel < kNumVoices);
- Common::StackLock lock(_mutex);
- unlockMacroChannel(_channelCtx[channel]);
- clearMacroProgramm(_channelCtx[channel]);
- Paula::disableChannel(_channelCtx[channel].paulaChannel);
- }
+ void setSignalPtr(uint16 *ptr, uint16 numSignals) { _playerCtx.signal = ptr; _playerCtx.numSignals = numSignals; }
+ void stopMacroEffect(int channel);
+
+protected:
+ void interrupt();
-// Note: everythings public so the debug-Routines work.
-// private:
+private:
enum { kPalDefaultCiaVal = 11822, kNtscDefaultCiaVal = 14320, kCiaBaseInterval = 0x1B51F8 };
enum { kNumVoices = 4, kNumChannels = 8, kNumSubsongs = 32, kMaxPatternOffsets = 128, kMaxMacroOffsets = 128 };
@@ -146,7 +141,7 @@ public:
uint16 macroReturnStep;
uint8 macroLoopCount;
bool macroRun;
- int8 macroSfxRun;
+ int8 macroSfxRun; //!< values are the folowing: -1 macro disabled, 0 macro init, 1 macro running
uint32 customMacro;
uint8 customMacroIndex;
@@ -225,10 +220,11 @@ public:
int tickCount;
uint16 *signal;
+ uint16 numSignals;
bool stopWithLastPattern; //!< hack to automatically stop the whole player if no Pattern is running
} _playerCtx;
-private:
+
static void initMacroProgramm(ChannelContext &channel) {
channel.macroStep = 0;
channel.macroWait = 0;
@@ -283,6 +279,19 @@ private:
channel.period = channel.refPeriod;
}
+ void initFadeCommand(const uint8 fadeTempo, const int8 endVol) {
+ _playerCtx.fadeCount = _playerCtx.fadeSkip = fadeTempo;
+ _playerCtx.fadeEndVolume = endVol;
+
+ if (fadeTempo) {
+ const int diff = _playerCtx.fadeEndVolume - _playerCtx.volume;
+ _playerCtx.fadeDelta = (diff != 0) ? ((diff > 0) ? 1 : -1) : 0;
+ } else {
+ _playerCtx.volume = endVol;
+ _playerCtx.fadeDelta = 0;
+ }
+ }
+
void effects(ChannelContext &channel);
void macroRun(ChannelContext &channel);
void advancePatterns();
diff --git a/tfmx/tfmxplayer.cpp b/tfmx/tfmxplayer.cpp
index 16b71c5496..a41b79dc41 100644
--- a/tfmx/tfmxplayer.cpp
+++ b/tfmx/tfmxplayer.cpp
@@ -19,6 +19,7 @@ using namespace Common;
#define MUSICFILE "mdat.monkey"
#define SAMPLEFILE "smpl.monkey"
+const int samplerate = 48000;
Audio::Tfmx *loadTfmxfile(const char *mdatName, const char *sampleName) {
FSNode fileDir(FILEDIR);
@@ -37,7 +38,7 @@ Audio::Tfmx *loadTfmxfile(const char *mdatName, const char *sampleName) {
return 0;
}
- Audio::Tfmx *player = new Audio::Tfmx(44100, true);
+ Audio::Tfmx *player = new Audio::Tfmx(samplerate, true);
player->load(*musicIn, *sampleIn);
delete musicIn;
delete sampleIn;
@@ -135,7 +136,7 @@ void modcmdmain(const int argc, const char *const argv[]) {
Common::FSNode file("out.raw");
WriteStream *wav = file.createWriteStream();
int16 buf[2 * 1024];
- int32 maxsamples = (maxsecs <= 0) ? 0 : maxsecs * 44100;
+ int32 maxsamples = (maxsecs <= 0) ? 0 : maxsecs * samplerate;
while (!player->endOfData() && maxsamples > 0) {
int read = player->readBuffer(buf, ARRAYSIZE(buf));
wav->write(buf, read * 2);
@@ -143,7 +144,7 @@ void modcmdmain(const int argc, const char *const argv[]) {
}
delete wav;
- runFlac(2, 16, 44100, "out.raw");
+ runFlac(2, 16, samplerate, "out.raw");
}
#ifdef _MSC_VER