mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-02 23:49:40 +00:00
cf351dffe6
Added "addBeginn" Effect, not used by MI but simple to implemt. svn-id: r41910
201 lines
6.7 KiB
C++
201 lines
6.7 KiB
C++
#include "common/scummsys.h"
|
|
#include "common/endian.h"
|
|
#include "common/debug.h"
|
|
#include "common/stream.h"
|
|
#include "common/util.h"
|
|
|
|
#include "sound/mods/tfmx.h"
|
|
|
|
#include "tfmx/tfmxdebug.h"
|
|
|
|
|
|
const char *pattcmds[]={
|
|
"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 char *macrocmds[]={
|
|
"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 char *const trackstepFmt[] = {
|
|
"---Stop Player----",
|
|
"Loop step/count ",
|
|
"Tempo tempo/ciaDiv",
|
|
"Timeshare ?/? ",
|
|
"Fade start/end "
|
|
};
|
|
|
|
void displayPatternstep(const void *const vptr) {
|
|
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",pattcmds[command&0xF], patData[1], patData[2], patData[3]);
|
|
}
|
|
|
|
}
|
|
|
|
void displayTrackstep(const void *const vptr) {
|
|
const uint16 *const trackData = (const uint16 *const)vptr;
|
|
|
|
if (trackData[0] == FROM_BE_16(0xEFFE)) {
|
|
// 16 byte Trackstep Command
|
|
const uint16 command = READ_BE_UINT16(&trackData[1]);
|
|
const uint16 param1 = READ_BE_UINT16(&trackData[2]);
|
|
const uint16 param2 = READ_BE_UINT16(&trackData[3]);
|
|
|
|
|
|
if (command >= ARRAYSIZE(trackstepFmt))
|
|
debug("Unknown (%04X) : %04X %04X", command, param1, param2);
|
|
else
|
|
debug("%s: %04X %04X", trackstepFmt[command], param1, param2);
|
|
} else {
|
|
const byte *const ptr = (const byte *const)vptr;
|
|
// 8 commands for Patterns
|
|
debug("%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X",
|
|
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7],
|
|
ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]);
|
|
}
|
|
}
|
|
|
|
void displayMacroStep(const void *const vptr, int chan, int index) {
|
|
const byte *const macroData = (const byte *const)vptr;
|
|
|
|
if (macroData[0] < ARRAYSIZE(macrocmds))
|
|
debug("%02X %02X %s %02X%02X%02X", chan, index, macrocmds[macroData[0]], macroData[1], macroData[2], macroData[3]);
|
|
else
|
|
debug("%02X %02X Unkown Macro #%02X %02X%02X%02X", chan, index, macroData[0], macroData[1], macroData[2], macroData[3]);
|
|
}
|
|
|
|
void displayMacroStep(const void *const vptr) {
|
|
const byte *const macroData = (const byte *const)vptr;
|
|
|
|
if (macroData[0] < ARRAYSIZE(macrocmds))
|
|
debug("%s %02X%02X%02X", macrocmds[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 dumpTracksteps(Audio::Tfmx &player, uint16 first, uint16 last) {
|
|
for ( ; first <= last; ++first) {
|
|
displayTrackstep(player._resource.getTrackPtr(first));
|
|
}
|
|
}
|
|
|
|
void dumpTrackstepsBySong(Audio::Tfmx &player, int song) {
|
|
debug("Song %02X: Pos %02X - %02X. Tempo: %02X", song, player._subsong[song].songstart, player._subsong[song].songend, player._subsong[song].tempo);
|
|
dumpTracksteps(player, player._subsong[song].songstart, player._subsong[song].songend);
|
|
debug("");
|
|
}
|
|
|
|
void dumpMacro(Audio::Tfmx &player, uint16 macroIndex, uint16 len, uint16 start) {
|
|
const uint32 * macroPtr = player._resource.getMacroPtr(player._macroOffset[macroIndex]);
|
|
bool untilMacroStop = (len == 0);
|
|
while (len--) {
|
|
displayMacroStep(macroPtr++);
|
|
}
|
|
while (untilMacroStop) {
|
|
untilMacroStop = *(const byte *)macroPtr != 7;
|
|
displayMacroStep(macroPtr++);
|
|
}
|
|
}
|
|
|
|
void dumpPattern(Audio::Tfmx &player, uint16 pattIndex, uint16 len, uint16 start) {
|
|
const uint32 * pattPtr = player._resource.getPatternPtr(player._patternOffset[pattIndex]);
|
|
if (len == 0)
|
|
len = (player._patternOffset[pattIndex+1] - player._patternOffset[pattIndex])/4;
|
|
bool untilMacroStop = (len == 0);
|
|
while (len--) {
|
|
displayPatternstep(pattPtr++);
|
|
}
|
|
while (untilMacroStop) {
|
|
byte cmd = *(const byte *)pattPtr;
|
|
untilMacroStop = cmd != 0 && cmd != 4;
|
|
displayPatternstep(pattPtr++);
|
|
}
|
|
}
|
|
|
|
void countAllMacros1(Audio::Tfmx &player, uint16 macroIndex, int *list) {
|
|
const uint32 * macroPtr = player._resource.getMacroPtr(player._macroOffset[macroIndex]);
|
|
bool untilMacroStop = true;
|
|
while (untilMacroStop) {
|
|
const int type = *(const byte *)macroPtr++;
|
|
untilMacroStop = type != 7;
|
|
list[type]++;
|
|
}
|
|
}
|
|
|
|
void countAllMacros(Audio::Tfmx &player) {
|
|
int list[256] = {0};
|
|
for (int i = 0; i < 128; ++i)
|
|
countAllMacros1(player, i, list);
|
|
byte fakeMacro[4] = {0};
|
|
for (int i = 0; i < 256; ++i) {
|
|
fakeMacro[0] = (byte)i;
|
|
if (list[i] > 0)
|
|
displayMacroStep(fakeMacro);
|
|
}
|
|
|
|
}
|