arm7: decompile SND_unk_037FD440

This commit is contained in:
Michael Panzlaff
2021-08-01 02:45:26 +02:00
parent 9148e1b930
commit c2bd97bebc
5 changed files with 917 additions and 1625 deletions
File diff suppressed because it is too large Load Diff
+8 -5
View File
@@ -3,20 +3,23 @@
#include "nitro/types.h"
#include "nitro/SND_seq_shared.h"
#include "nitro/SND_work_shared.h"
struct SNDTrack *PlayerGetTrack(struct SNDPlayer *player, int track);
void PlayerStop(struct SNDPlayer *);
void TrackMute(struct SNDTrack *track, struct SNDPlayer *player, int muteMode);
void TrackReleaseChannels(struct SNDTrack *track, struct SNDPlayer *player, int release);
void TrackFreeChannels(struct SNDTrack *track);
BOOL PlayerStepTicks(struct SNDPlayer *player, u32 ticks);
void PlayerSetBank(struct SNDPlayer *player, struct SNDBankData *bankData);
void PlayerInit(struct SNDPlayer *player, struct SNDBankData *bankData);
int AllocateTrack(void);
void TrackInit(struct SNDTrack *track);
void TrackSetSeq(struct SNDTrack *track, const void *seq, u32 offset);
void SeqCacheFetch(const void *addr);
u8 SeqReadByte(const void *addr);
void TrackStart(struct SNDTrack *track, const void *seq, u32 offset);
void SeqCacheFetch(const u8 *addr);
u8 SeqReadByte(const u8 *addr);
u16 TrackReadU16(struct SNDTrack *track);
void PlayerSeqMain(struct SNDPlayer *player);
void PlayerUpdateChannelVolume(struct SNDPlayer *player);
void PlayerUpdateChannel(struct SNDPlayer *player);
#endif //GUARD_SND_UNK_H
+3 -3
View File
@@ -33,7 +33,7 @@ void SND_SeqMain(BOOL step) {
if (ply->flags.prepared) {
if (step && !ply->flags.paused)
PlayerSeqMain(ply);
PlayerUpdateChannelVolume(ply);
PlayerUpdateChannel(ply);
}
if (ply->flags.active)
@@ -50,7 +50,7 @@ void SND_PrepareSeq(int player, const void *seq, u32 offset, struct SNDBankData
if (ply->flags.active)
PlayerStop(ply);
PlayerSetBank(ply, bankData);
PlayerInit(ply, bankData);
int allocTrkIdx = AllocateTrack();
@@ -59,7 +59,7 @@ void SND_PrepareSeq(int player, const void *seq, u32 offset, struct SNDBankData
struct SNDTrack *trk = &SNDi_Work.tracks[allocTrkIdx];
TrackInit(trk);
TrackSetSeq(trk, seq, offset);
TrackStart(trk, seq, offset);
ply->tracks[0] = (u8)allocTrkIdx;
SeqCacheFetch(trk->cur);
+904
View File
@@ -0,0 +1,904 @@
#include "SND_unk_037FD440.h"
#include "SND_util.h"
#include "SND_lfo.h"
#include "SND_exChannel.h"
#include "SND_bank.h"
#define SND_TRACK_MUTE_MODE_UNMUTE 0
#define SND_TRACK_MUTE_MODE_MUTE 1
#define SND_TRACK_MUTE_MODE_MUTE_RELEASE 2
#define SND_TRACK_MUTE_MODE_MUTE_STOP 3
enum SNDSeqProc {
SND_PROC_SKIP_NOTES = 0,
SND_PROC_PLAY_NOTES = 1,
};
enum SNDSeqVal {
SND_SEQ_VAL_U8 = 0,
SND_SEQ_VAL_U16 = 1,
SND_SEQ_VAL_VLV = 2,
SND_SEQ_VAL_RAN = 3,
SND_SEQ_VAL_VAR = 4,
};
#define SND_TIMER_RATE 240
static struct {
const u8 *begin;
const u8 *end;
union {
u8 buf[16];
u32 buf32[4];
};
} sSeqCache;
static int sPrintEnabled;
static s16 *PlayerGetVariablePointer(const struct SNDPlayer *player, int var);
static void TrackUpdateChannel(struct SNDTrack *track, struct SNDPlayer *player, int release);
// TODO make static
void SeqCacheFetch(const u8 *addr) {
addr = (const u8 *)((u32)addr & ~3);
sSeqCache.begin = addr;
sSeqCache.end = sSeqCache.begin + 16;
const u32 *src = (const u32 *)addr;
sSeqCache.buf32[0] = src[0];
sSeqCache.buf32[1] = src[1];
sSeqCache.buf32[2] = src[2];
sSeqCache.buf32[3] = src[3];
}
// TODO make static
u8 SeqReadByte(const u8 *addr) {
if (addr < sSeqCache.begin || addr >= sSeqCache.end)
SeqCacheFetch(addr);
return sSeqCache.buf[(u32)addr - (u32)sSeqCache.begin];
}
static inline u8 TrackReadU8(struct SNDTrack *track) {
u8 retval = SeqReadByte(track->cur);
track->cur++;
return retval;
}
// TODO make static
u16 TrackReadU16(struct SNDTrack *track) {
int retval;
retval = TrackReadU8(track);
retval |= TrackReadU8(track) << 8;
return (u16)retval;
}
static u32 TrackReadU24(struct SNDTrack *track) {
u32 retval;
retval = TrackReadU8(track);
retval |= TrackReadU8(track) << 8;
retval |= TrackReadU8(track) << 16;
return retval;
}
static int TrackReadVLV(struct SNDTrack *track) {
int retval = 0;
int b;
do {
b = TrackReadU8(track);
retval = (retval << 7) | (b & 0x7F);
} while(b & 0x80);
return retval;
}
static int TrackParseValue(struct SNDTrack *track, struct SNDPlayer *player, int valueType) {
int retval;
int hi;
int lo;
int ran;
s16 *var;
// BUG: undefined behavior if invalid valueType is passed (uninitialized return value)
switch (valueType) {
case SND_SEQ_VAL_U8:
retval = TrackReadU8(track);
break;
case SND_SEQ_VAL_U16:
retval = TrackReadU16(track);
break;
case SND_SEQ_VAL_VLV:
retval = TrackReadVLV(track);
break;
case SND_SEQ_VAL_VAR:
var = PlayerGetVariablePointer(player, TrackReadU8(track));
if (var)
retval = *var;
break;
case SND_SEQ_VAL_RAN:
lo = TrackReadU16(track) << 16;
hi = (s16)TrackReadU16(track);
ran = SND_CalcRandom();
retval = hi - (lo >> 16);
retval += 1;
retval = (ran * retval) >> 16;
retval += lo >> 16;
break;
}
return retval;
}
// TODO make static
void TrackInit(struct SNDTrack *track) {
track->base = NULL;
track->cur = NULL;
track->flags.noteWait = TRUE;
track->flags.muted = FALSE;
track->flags.tie = FALSE;
track->flags.noteFinishWait = FALSE;
track->flags.portamento = FALSE;
track->flags.cmp = TRUE;
track->flags.channelMask = FALSE;
track->callStackDepth = 0;
track->program = 0;
track->priority = 64;
track->volume = 127;
track->expression = 127;
track->extFader = 0;
track->pan = 0;
track->extPan = 0;
track->pitchBend = 0;
track->extPitch = 0;
track->envAttack = 255;
track->envDecay = 255;
track->envSustain = 255;
track->envRelease = 255;
track->panRange = 127;
track->bendRange = 2;
track->portamentoKey = 60;
track->portamentoTime = 0;
track->sweepPitch = 0;
track->transpose = 0;
track->channelMask = 0xFFFF;
SND_InitLfoParam(&track->mod);
track->wait = 0;
track->channelLLHead = NULL;
}
// TODO make static
void TrackStart(struct SNDTrack *track, const void *seq, u32 offset) {
track->base = (const u8 *)seq;
track->cur = &track->base[offset];
}
// TODO make static later
void PlayerInit(struct SNDPlayer *player, struct SNDBankData *bank) {
player->flags.paused = FALSE;
player->bank = bank;
player->tempo = 120;
player->tempoRatio = 256;
player->tempoCounter = SND_TIMER_RATE;
player->volume = 0x7F;
player->extFader = 0;
player->prio = 64;
for (int i = 0; i < SND_TRACK_COUNT_PER_PLAYER; i++) {
player->tracks[i] = 0xFF;
}
if (SNDi_SharedWork) {
SNDi_SharedWork->players[player->playerId].tickCounter = 0;
for (int i = 0; i < SND_TRACK_COUNT_PER_PLAYER; i++) {
SNDi_SharedWork->players[player->playerId].localVars[i] = -1;
}
}
}
// TODO make static
void TrackReleaseChannels(struct SNDTrack *track, struct SNDPlayer *player, int release) {
TrackUpdateChannel(track, player, 0);
for (struct SNDExChannel *chn = track->channelLLHead; chn; chn = chn->channelLLNext) {
if (SND_IsExChannelActive(chn)) {
if (release >= 0)
SND_SetExChannelRelease(chn, release & 0xFF);
chn->priority = 1;
SND_ReleaseExChannel(chn);
}
}
}
// TODO make static
void TrackFreeChannels(struct SNDTrack *track) {
for (struct SNDExChannel *chn = track->channelLLHead; chn; chn = chn->channelLLNext) {
SND_FreeExChannel(chn);
}
track->channelLLHead = NULL;
}
void PlayerSeqMain(struct SNDPlayer *player) {
int ticks = 0;
int tempoInc;
int i;
while (player->tempoCounter >= SND_TIMER_RATE) {
player->tempoCounter -= SND_TIMER_RATE;
ticks++;
}
for (i = 0; i < ticks; i++) {
if (PlayerStepTicks(player, SND_PROC_PLAY_NOTES)) {
PlayerStop(player);
break;
}
}
if (SNDi_SharedWork) {
SNDi_SharedWork->players[player->playerId].tickCounter += i;
}
tempoInc = player->tempo;
tempoInc *= player->tempoRatio;
tempoInc >>= 8;
player->tempoCounter += tempoInc;
}
struct SNDTrack *PlayerGetTrack(struct SNDPlayer *player, int track) {
if (track > (SND_TRACK_COUNT_PER_PLAYER - 1))
return NULL;
if (player->tracks[track] == 0xFF)
return NULL;
return &SNDi_Work.tracks[player->tracks[track]];
}
static void TrackStop(struct SNDTrack *track, struct SNDPlayer *player) {
TrackReleaseChannels(track, player, -1);
TrackFreeChannels(track);
}
static void PlayerStopTrack(struct SNDPlayer *player, int trackIdx) {
struct SNDTrack *track = PlayerGetTrack(player, trackIdx);
if (track == NULL)
return;
TrackStop(track, player);
SNDi_Work.tracks[player->tracks[trackIdx]].flags.active = FALSE;
player->tracks[trackIdx] = 0xFF;
}
void PlayerStop(struct SNDPlayer *player) {
for (int i = 0; i < SND_TRACK_COUNT_PER_PLAYER; i++) {
PlayerStopTrack(player, i);
}
player->flags.active = FALSE;
}
static void ChannelCallback(struct SNDExChannel *chn, int status, void *track_) {
struct SNDExChannel *cur;
struct SNDTrack *track;
track = (struct SNDTrack *)track_;
if (status == 1) {
chn->priority = 0;
SND_FreeExChannel(chn);
}
if (track->channelLLHead == chn) {
track->channelLLHead = chn->channelLLNext;
} else {
cur = track->channelLLHead;
while (cur->channelLLNext) {
if (cur->channelLLNext == chn) {
cur->channelLLNext = chn->channelLLNext;
return;
}
cur = cur->channelLLNext;
}
}
}
static void TrackUpdateChannel(struct SNDTrack *track, struct SNDPlayer *player, int release) {
int vol;
int fader;
int pan;
int pitch;
vol = SNDi_DecibelSquareTable[track->volume] +
SNDi_DecibelSquareTable[track->expression] +
SNDi_DecibelSquareTable[player->volume];
fader = track->extFader + player->extFader;
pitch = track->pitchBend;
pitch *= track->bendRange << 6;
pitch >>= 7;
pitch += track->extPitch;
pan = track->pan;
if (track->panRange != 127)
pan = (pan * track->panRange + 0x40) >> 7;
pan += track->extPan;
if (vol < -0x8000)
vol = -0x8000;
if (fader < -0x8000)
fader = -0x8000;
if (pan < -128)
pan = -128;
else if (pan > 127)
pan = 127;
for (struct SNDExChannel *chn = track->channelLLHead; chn != NULL; chn = chn->channelLLNext) {
chn->userDecay2 = (short)fader;
if (chn->envStatus == 3)
continue;
chn->userDecay = (s16)vol;
chn->userPitch = (s16)pitch;
chn->userPan = (s8)pan;
chn->panRange = track->panRange;
chn->lfo.param = track->mod;
if (chn->length == 0 && release != 0) {
chn->priority = 1;
SND_ReleaseExChannel(chn);
}
}
}
// TODO make static
void PlayerUpdateChannel(struct SNDPlayer *player) {
for (int i = 0; i < SND_TRACK_COUNT_PER_PLAYER; i++) {
struct SNDTrack *trk = PlayerGetTrack(player, i);
if (trk) {
TrackUpdateChannel(trk, player, 1);
}
}
}
static void TrackPlayNote(struct SNDTrack *track, struct SNDPlayer *player, int midiKey, int velocity, int length) {
struct SNDExChannel *chn = NULL;
if (track->flags.tie) {
chn = track->channelLLHead;
if (chn) {
chn->midiKey = (u8)midiKey;
chn->velocity = (u8)velocity;
}
}
if (chn == NULL) {
struct SNDInstData inst;
if (!SND_ReadInstData(player->bank, track->program, midiKey, &inst))
return;
u32 allowedChannels;
switch (inst.type) {
case SND_INST_PCM:
case SND_INST_DIRECTPCM:
// all channels support PCM
allowedChannels = 0xFFFF;
break;
case SND_INST_PSG:
// only channels 8, 9, 10, 11, 12, 13 support PSG
allowedChannels = 0x3F00;
break;
case SND_INST_NOISE:
// only channels 14 and 15 support noise
allowedChannels = 0xC000;
break;
default:
return;
}
allowedChannels &= track->channelMask;
chn = SND_AllocExChannel(allowedChannels, player->prio + track->priority, track->flags.channelMask, ChannelCallback, track);
if (chn == NULL)
return;
if (!SND_NoteOn(chn, midiKey, velocity, track->flags.tie ? -1 : length, player->bank, &inst)) {
chn->priority = 0;
SND_FreeExChannel(chn);
return;
}
chn->channelLLNext = track->channelLLHead;
track->channelLLHead = chn;
}
if (track->envAttack != 0xFF)
SND_SetExChannelAttack(chn, track->envAttack);
if (track->envDecay != 0xFF)
SND_SetExChannelDecay(chn, track->envDecay);
if (track->envSustain != 0xFF)
SND_SetExChannelSustain(chn, track->envSustain);
if (track->envRelease != 0xFF)
SND_SetExChannelRelease(chn, track->envRelease);
chn->sweepPitch = track->sweepPitch;
if (track->flags.portamento)
chn->sweepPitch += (short)((track->portamentoKey - midiKey) << 6);
if (track->portamentoTime == 0) {
chn->sweepLength = length;
chn->flags.autoSweep = FALSE;
} else {
int swp = track->portamentoTime * track->portamentoTime;
swp *= chn->sweepPitch < 0 ? -chn->sweepPitch : chn->sweepPitch;
swp >>= 11;
chn->sweepLength = swp;
}
chn->sweepCounter = 0;
}
static int TrackStepTicks(struct SNDTrack *track, struct SNDPlayer *player, int trackIdx, u32 playNotes) {
(void)trackIdx;
struct SNDExChannel *chn;
u8 cmd;
enum SNDSeqVal valueType;
BOOL specialValueType;
BOOL runCmd;
s32 length;
int midiKey;
s32 par;
for (chn = track->channelLLHead; chn; chn = chn->channelLLNext) {
if (chn->length > 0)
chn->length--;
if (!chn->flags.autoSweep && chn->sweepCounter < chn->sweepLength)
chn->sweepCounter++;
}
if (track->flags.noteFinishWait) {
if (track->channelLLHead)
return 0;
track->flags.noteFinishWait = FALSE;
}
if (track->wait > 0) {
track->wait--;
if (track->wait > 0)
return 0;
}
SeqCacheFetch(track->cur);
while (track->wait == 0 && !track->flags.noteFinishWait) {
specialValueType = FALSE;
runCmd = TRUE;
cmd = TrackReadU8(track);
if (cmd == 0xA2) {
cmd = TrackReadU8(track);
runCmd = track->flags.cmp;
}
if (cmd == 0xA0) {
cmd = TrackReadU8(track);
valueType = SND_SEQ_VAL_RAN;
specialValueType = TRUE;
}
if (cmd == 0xA1) {
cmd = TrackReadU8(track);
valueType = SND_SEQ_VAL_VAR;
specialValueType = TRUE;
}
if ((cmd & 0x80) == 0) {
par = TrackReadU8(track);
length = TrackParseValue(track, player, specialValueType ? valueType : SND_SEQ_VAL_VLV);
midiKey = cmd + track->transpose;
if (!runCmd)
continue;
if (midiKey < 0)
midiKey = 0;
else if (midiKey > 127) {
midiKey = 127;
}
if (!track->flags.muted && playNotes != 0) {
TrackPlayNote(track, player, midiKey, par, (length > 0) ? length : -1);
}
track->portamentoKey = (u8)midiKey;
if (track->flags.noteWait) {
track->wait = length;
if (length == 0) {
track->flags.noteFinishWait = TRUE;
}
}
continue;
}
switch (cmd & 0xF0) {
case 0x80:
par = TrackParseValue(track, player, specialValueType ? valueType : SND_SEQ_VAL_VLV);
if (!runCmd)
break;
switch (cmd) {
case 0x80:
track->wait = par;
break;
case 0x81:
if (par < 0x10000)
track->program = (u16)par;
break;
}
break;
case 0x90:
switch (cmd) {
case 0x93:
{
u32 off;
struct SNDTrack *newTrack;
par = TrackReadU8(track);
off = TrackReadU24(track);
if (!runCmd)
break;
newTrack = PlayerGetTrack(player, par);
if (newTrack && newTrack != track) {
TrackStop(newTrack, player);
TrackStart(newTrack, track->base, off);
}
}
break;
case 0x94:
{
u32 off = TrackReadU24(track);
if (!runCmd)
break;
track->cur = &track->base[off];
}
break;
case 0x95:
{
u32 off = TrackReadU24(track);
if (!runCmd)
break;
if (track->callStackDepth < SND_TRACK_MAX_CALL) {
track->posCallStack[track->callStackDepth] = track->cur;
track->callStackDepth++;
track->cur = &track->base[off];
}
break;
}
}
break;
case 0xC0:
case 0xD0:
{
union {
u8 _u8;
s8 _s8;
} par;
par._u8 = (u8)TrackParseValue(track, player, specialValueType ? valueType : SND_SEQ_VAL_U8);
if (!runCmd)
break;
switch (cmd) {
case 0xC1:
track->volume = par._u8;
break;
case 0xD5:
track->expression = par._u8;
break;
case 0xC2:
player->volume = par._u8;
break;
case 0xC5:
track->bendRange = par._u8;
break;
case 0xC6:
track->priority = par._u8;
break;
case 0xC7:
track->flags.noteWait = par._u8;
break;
case 0xCF:
track->portamentoTime = par._u8;
break;
case 0xCA:
track->mod.depth = par._u8;
break;
case 0xCB:
track->mod.speed = par._u8;
break;
case 0xCC:
track->mod.target = par._u8;
break;
case 0xCD:
track->mod.range = par._u8;
break;
case 0xD0:
track->envAttack = par._u8;
break;
case 0xD1:
track->envDecay = par._u8;
break;
case 0xD2:
track->envSustain = par._u8;
break;
case 0xD3:
track->envRelease = par._u8;
break;
case 0xD4:
if (track->callStackDepth < SND_TRACK_MAX_CALL) {
track->posCallStack[track->callStackDepth] = track->cur;
track->loopCount[track->callStackDepth] = par._u8;
track->callStackDepth++;
}
break;
case 0xC8:
track->flags.tie = par._u8;
TrackReleaseChannels(track, player, -1);
TrackFreeChannels(track);
break;
case 0xD7:
TrackMute(track, player, par._u8);
break;
case 0xC9:
track->portamentoKey = (u8)(par._u8 + track->transpose);
track->flags.portamento = TRUE;
break;
case 0xCE:
track->flags.portamento = par._u8;
break;
case 0xC3:
track->transpose = par._s8;
break;
case 0xC4:
track->pitchBend = par._s8;
break;
case 0xC0:
track->pan = (s8)(par._u8 - 0x40);
break;
case 0xD6:
{
s16 *varPtr;
if (sPrintEnabled) {
varPtr = PlayerGetVariablePointer(player, par._u8);
}
}
break;
}
}
break;
case 0xE0:
{
s16 par = (s16)TrackParseValue(track, player, specialValueType ? valueType : SND_SEQ_VAL_U16);
if (!runCmd)
break;
switch (cmd) {
case 0xE3:
track->sweepPitch = par;
break;
case 0xE1:
player->tempo = (u16)par;
break;
case 0xE0:
track->mod.delay = (u16)par;
break;
}
}
break;
case 0xB0:
{
// TODO fix refalloc -> stack on varNum
int varNum = TrackReadU8(track);
s16 par = (s16)TrackParseValue(track, player, specialValueType ? valueType : SND_SEQ_VAL_U16);
s16 *varPtr = PlayerGetVariablePointer(player, varNum);
if (!runCmd)
break;
if (varPtr == NULL)
break;
switch (cmd) {
case 0xB0:
*varPtr = par;
break;
case 0xB1:
*varPtr += par;
break;
case 0xB2:
*varPtr -= par;
break;
case 0xB3:
*varPtr *= par;
break;
case 0xB4:
if (par != 0)
*varPtr /= par;
break;
case 0xB5:
if (par >= 0)
*varPtr <<= par;
else
*varPtr >>= -par;
break;
case 0xB6:
{
BOOL neg = FALSE;
if (par < 0) {
neg = TRUE;
par = (s16)(-par);
}
s32 random = SND_CalcRandom();
random = (random * (par + 1)) >> 16;
if (neg)
random = -random;
*varPtr = (s16)random;
}
break;
case 0xB7:
break;
case 0xB8:
track->flags.cmp = *varPtr == par;
break;
case 0xB9:
track->flags.cmp = *varPtr >= par;
break;
case 0xBA:
track->flags.cmp = *varPtr > par;
break;
case 0xBB:
track->flags.cmp = *varPtr <= par;
break;
case 0xBC:
track->flags.cmp = *varPtr < par;
break;
case 0xBD:
track->flags.cmp = *varPtr != par;
break;
}
}
break;
case 0xF0:
if (!runCmd)
break;
switch (cmd) {
case 0xFD:
if (track->callStackDepth != 0) {
track->callStackDepth--;
track->cur = track->posCallStack[track->callStackDepth];
}
break;
case 0xFC:
{
if (track->callStackDepth == 0)
break;
// gosh, this was nasty to figure out
u8 loopCount = track->loopCount[track->callStackDepth - 1];
if (loopCount != 0) {
loopCount--;
if (loopCount == 0) {
track->callStackDepth--;
break;
}
}
track->loopCount[track->callStackDepth - 1] = loopCount;
track->cur = track->posCallStack[track->callStackDepth - 1];
}
break;
case 0xFE:
break;
case 0xFF:
return -1;
}
break;
}
}
return 0;
}
BOOL PlayerStepTicks(struct SNDPlayer *player, u32 ticks) {
BOOL isPlaying = FALSE;
for (int i = 0; i < SND_TRACK_COUNT_PER_PLAYER; i++) {
struct SNDTrack *trk = PlayerGetTrack(player, i);
if (trk && trk->cur) {
if (TrackStepTicks(trk, player, i, ticks))
PlayerStopTrack(player, i);
else
isPlaying = TRUE;
}
}
return !isPlaying;
}
static s16 *PlayerGetVariablePointer(const struct SNDPlayer *player, int var) {
if (SNDi_SharedWork == NULL)
return NULL;
else if (var < 16) {
return &SNDi_SharedWork->players[player->playerId].localVars[var];
} else {
return &SNDi_SharedWork->globalVars[var - 16];
}
}
int AllocateTrack(void) {
for (int i = 0; i < SND_TRACK_COUNT; i++) {
if (!SNDi_Work.tracks[i].flags.active) {
SNDi_Work.tracks[i].flags.active = TRUE;
return i;
}
}
return -1;
}
// TODO make static after merging with SND_seq
void TrackMute(struct SNDTrack *track, struct SNDPlayer *player, int muteMode) {
switch (muteMode) {
case SND_TRACK_MUTE_MODE_UNMUTE:
track->flags.muted = FALSE;
break;
case SND_TRACK_MUTE_MODE_MUTE:
track->flags.muted = TRUE;
break;
case SND_TRACK_MUTE_MODE_MUTE_RELEASE:
track->flags.muted = TRUE;
TrackReleaseChannels(track, player, -1);
break;
case SND_TRACK_MUTE_MODE_MUTE_STOP:
track->flags.muted = TRUE;
TrackReleaseChannels(track, player, 127);
TrackFreeChannels(track);
break;
}
}
+2
View File
@@ -1,6 +1,8 @@
#ifndef GUARD_SND_SEQ_SHARED_H
#define GUARD_SND_SEQ_SHARED_H
#include "nitro/SND_exChannel_shared.h"
#define SND_TRACK_COUNT_PER_PLAYER 16
#define SND_INVALID_TRACK_INDEX 0xFF