1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-05-12 12:03:48 +00:00

Document Table For Sequence Instruction Arguments (#1242)

* Document Table For Sequence Instruction Arguments

* Add small bit of docs

* More cleanup

* Shorten Macros

* Add another comment

* rm cast

* Cleanup

* More consistency

* instruction

* Better ret name

* PR suggestions

* Small fix
This commit is contained in:
engineer124 2022-06-01 04:39:56 +10:00 committed by GitHub
parent bd6b51a869
commit d6a7d43735
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -15,30 +15,139 @@ u16 AudioSeq_ScriptReadCompressedU16(SeqScriptState* state);
u8 AudioSeq_GetInstrument(SequenceChannel* channel, u8 instId, Instrument** instOut, AdsrSettings* adsr); u8 AudioSeq_GetInstrument(SequenceChannel* channel, u8 instId, Instrument** instOut, AdsrSettings* adsr);
u8 D_80130520[] = { /**
0x81, 0x00, 0x81, 0x01, 0x00, 0x00, 0x00, 0x81, 0x01, 0x01, 0x01, 0x42, 0x81, 0xC2, 0x00, 0x00, * sSeqInstructionArgsTable is a table for each sequence instruction
0x00, 0x01, 0x81, 0x00, 0x00, 0x00, 0x01, 0x42, 0x01, 0x01, 0x01, 0x81, 0x01, 0x01, 0x81, 0x81, * that contains both how many arguments an instruction takes, as well
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x01, 0x01, 0x01, 0x81, 0x01, * as the type of each argument
0x01, 0x03, 0x03, 0x01, 0x00, 0x01, 0x01, 0x81, 0x03, 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x82, *
0x00, 0x01, 0x01, 0x01, 0x01, 0x81, 0x00, 0x00, 0x01, 0x81, 0x81, 0x81, 0x81, 0x00, 0x00, 0x00, * sSeqInstructionArgsTable is bitpacked as follows:
* abcUUUnn
*
* n - number of arguments that the sequence instruction takes
*
* a - bitFlag for the type of arg0 if it exists
* b - bitFlag for the type of arg1 if it exists
* c - bitFlag for the type of arg2 if it exists
*
* bitFlag on - argument is s16
* bitFlag off - argument is u8
*
* U - Unused
*/
// CMD_ARGS_(NUMBER_OF_ARGS)
#define CMD_ARGS_0() 0
#define CMD_ARGS_1(arg0Type) (((sizeof(arg0Type) - 1) << 7) | 1)
#define CMD_ARGS_2(arg0Type, arg1Type) (((sizeof(arg0Type) - 1) << 7) | ((sizeof(arg1Type) - 1) << 6) | 2)
#define CMD_ARGS_3(arg0Type, arg1Type, arg2Type) \
(((sizeof(arg0Type) - 1) << 7) | ((sizeof(arg1Type) - 1) << 6) | ((sizeof(arg2Type) - 1) << 5) | 3)
u8 sSeqInstructionArgsTable[] = {
CMD_ARGS_1(s16), // 0xB0
CMD_ARGS_0(), // 0xB1
CMD_ARGS_1(s16), // 0xB2
CMD_ARGS_1(u8), // 0xB3
CMD_ARGS_0(), // 0xB4
CMD_ARGS_0(), // 0xB5
CMD_ARGS_0(), // 0xB6
CMD_ARGS_1(s16), // 0xB7
CMD_ARGS_1(u8), // 0xB8
CMD_ARGS_1(u8), // 0xB9
CMD_ARGS_1(u8), // 0xBA
CMD_ARGS_2(u8, s16), // 0xBB
CMD_ARGS_1(s16), // 0xBC
CMD_ARGS_2(s16, s16), // 0xBD
CMD_ARGS_0(), // 0xBE
CMD_ARGS_0(), // 0xBF
CMD_ARGS_0(), // 0xC0
CMD_ARGS_1(u8), // 0xC1
CMD_ARGS_1(s16), // 0xC2
CMD_ARGS_0(), // 0xC3
CMD_ARGS_0(), // 0xC4
CMD_ARGS_0(), // 0xC5
CMD_ARGS_1(u8), // 0xC6
CMD_ARGS_2(u8, s16), // 0xC7
CMD_ARGS_1(u8), // 0xC8
CMD_ARGS_1(u8), // 0xC9
CMD_ARGS_1(u8), // 0xCA
CMD_ARGS_1(s16), // 0xCB
CMD_ARGS_1(u8), // 0xCC
CMD_ARGS_1(u8), // 0xCD
CMD_ARGS_1(s16), // 0xCE
CMD_ARGS_1(s16), // 0xCF
CMD_ARGS_1(u8), // 0xD0
CMD_ARGS_1(u8), // 0xD1
CMD_ARGS_1(u8), // 0xD2
CMD_ARGS_1(u8), // 0xD3
CMD_ARGS_1(u8), // 0xD4
CMD_ARGS_1(u8), // 0xD5
CMD_ARGS_1(u8), // 0xD6
CMD_ARGS_1(u8), // 0xD7
CMD_ARGS_1(u8), // 0xD8
CMD_ARGS_1(u8), // 0xD9
CMD_ARGS_1(s16), // 0xDA
CMD_ARGS_1(u8), // 0xDB
CMD_ARGS_1(u8), // 0xDC
CMD_ARGS_1(u8), // 0xDD
CMD_ARGS_1(s16), // 0xDE
CMD_ARGS_1(u8), // 0xDF
CMD_ARGS_1(u8), // 0xE0
CMD_ARGS_3(u8, u8, u8), // 0xE1
CMD_ARGS_3(u8, u8, u8), // 0xE2
CMD_ARGS_1(u8), // 0xE3
CMD_ARGS_0(), // 0xE4
CMD_ARGS_1(u8), // 0xE5
CMD_ARGS_1(u8), // 0xE6
CMD_ARGS_1(s16), // 0xE7
CMD_ARGS_3(u8, u8, u8), // 0xE8
CMD_ARGS_1(u8), // 0xE9
CMD_ARGS_0(), // 0xEA
CMD_ARGS_2(u8, u8), // 0xEB
CMD_ARGS_0(), // 0xEC
CMD_ARGS_1(u8), // 0xED
CMD_ARGS_1(u8), // 0xEE
CMD_ARGS_2(s16, u8), // 0xEF
CMD_ARGS_0(), // 0xF0
CMD_ARGS_1(u8), // 0xF1
// Control flow instructions (>= 0xF2) can only have 0 or 1 args
CMD_ARGS_1(u8), // 0xF2
CMD_ARGS_1(u8), // 0xF3
CMD_ARGS_1(u8), // 0xF4
CMD_ARGS_1(s16), // 0xF5
CMD_ARGS_0(), // 0xF6
CMD_ARGS_0(), // 0xF7
CMD_ARGS_1(u8), // 0xF8
CMD_ARGS_1(s16), // 0xF9
CMD_ARGS_1(s16), // 0xFA
CMD_ARGS_1(s16), // 0xFB
CMD_ARGS_1(s16), // 0xFC
CMD_ARGS_0(), // 0xFD
CMD_ARGS_0(), // 0xFE
CMD_ARGS_0(), // 0xFF
}; };
u16 AudioSeq_GetScriptControlFlowArgument(SeqScriptState* state, u8 arg1) { /**
u8 temp_v0 = D_80130520[arg1 - 0xB0]; * Read and return the argument from the sequence script for a control flow instruction.
u8 loBits = temp_v0 & 3; * Control flow instructions (>= 0xF2) can only have 0 or 1 args.
u16 ret = 0; * @return the argument value for a control flow instruction, or 0 if there is no argument
*/
u16 AudioSeq_GetScriptControlFlowArgument(SeqScriptState* state, u8 cmd) {
u8 highBits = sSeqInstructionArgsTable[cmd - 0xB0];
u8 lowBits = highBits & 3;
u16 cmdArg = 0;
if (loBits == 1) { // only 1 argument
if ((temp_v0 & 0x80) == 0) { if (lowBits == 1) {
ret = AudioSeq_ScriptReadU8(state); if (!(highBits & 0x80)) {
cmdArg = AudioSeq_ScriptReadU8(state);
} else { } else {
ret = AudioSeq_ScriptReadS16(state); cmdArg = AudioSeq_ScriptReadS16(state);
} }
} }
return ret; return cmdArg;
} }
s32 AudioSeq_HandleScriptFlowControl(SequencePlayer* seqPlayer, SeqScriptState* state, s32 cmd, s32 arg) { s32 AudioSeq_HandleScriptFlowControl(SequencePlayer* seqPlayer, SeqScriptState* state, s32 cmd, s32 cmdArg) {
switch (cmd) { switch (cmd) {
case 0xFF: case 0xFF:
if (state->depth == 0) { if (state->depth == 0) {
@ -55,11 +164,11 @@ s32 AudioSeq_HandleScriptFlowControl(SequencePlayer* seqPlayer, SeqScriptState*
case 0xFC: case 0xFC:
state->stack[state->depth++] = state->pc; state->stack[state->depth++] = state->pc;
state->pc = seqPlayer->seqData + (u16)arg; state->pc = seqPlayer->seqData + (u16)cmdArg;
break; break;
case 0xF8: case 0xF8:
state->remLoopIters[state->depth] = arg; state->remLoopIters[state->depth] = cmdArg;
state->stack[state->depth++] = state->pc; state->stack[state->depth++] = state->pc;
break; break;
@ -89,7 +198,7 @@ s32 AudioSeq_HandleScriptFlowControl(SequencePlayer* seqPlayer, SeqScriptState*
if (cmd == 0xF5 && state->value < 0) { if (cmd == 0xF5 && state->value < 0) {
break; break;
} }
state->pc = seqPlayer->seqData + (u16)arg; state->pc = seqPlayer->seqData + (u16)cmdArg;
break; break;
case 0xF2: case 0xF2:
@ -101,7 +210,7 @@ s32 AudioSeq_HandleScriptFlowControl(SequencePlayer* seqPlayer, SeqScriptState*
if (cmd == 0xF2 && state->value >= 0) { if (cmd == 0xF2 && state->value >= 0) {
break; break;
} }
state->pc += (s8)(arg & 0xFF); state->pc += (s8)(cmdArg & 0xFF);
break; break;
} }
@ -471,6 +580,8 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) {
SequencePlayer* seqPlayer = channel->seqPlayer; SequencePlayer* seqPlayer = channel->seqPlayer;
u16 sp3A; u16 sp3A;
u8 cmd; u8 cmd;
u16 cmdArg;
u8 tempByte;
for (;;) { for (;;) {
cmd = AudioSeq_ScriptReadU8(state); cmd = AudioSeq_ScriptReadU8(state);
@ -478,9 +589,9 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) {
return cmd; return cmd;
} }
if (cmd >= 0xF2) { if (cmd >= 0xF2) {
u16 arg = AudioSeq_GetScriptControlFlowArgument(state, cmd); cmdArg = AudioSeq_GetScriptControlFlowArgument(state, cmd);
if (AudioSeq_HandleScriptFlowControl(seqPlayer, state, cmd, arg) == 0) { if (AudioSeq_HandleScriptFlowControl(seqPlayer, state, cmd, cmdArg) == 0) {
continue; continue;
} }
AudioSeq_SeqLayerDisable(layer); AudioSeq_SeqLayerDisable(layer);
@ -490,8 +601,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) {
switch (cmd) { switch (cmd) {
case 0xC1: // layer_setshortnotevelocity case 0xC1: // layer_setshortnotevelocity
case 0xCA: // layer_setpan case 0xCA: // layer_setpan
{ tempByte = *(state->pc++);
u8 tempByte = *(state->pc++);
if (cmd == 0xC1) { if (cmd == 0xC1) {
layer->velocitySquare = (f32)(tempByte * tempByte) / 16129.0f; layer->velocitySquare = (f32)(tempByte * tempByte) / 16129.0f;
@ -499,12 +609,10 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) {
layer->pan = tempByte; layer->pan = tempByte;
} }
break; break;
}
case 0xC9: // layer_setshortnotegatetime case 0xC9: // layer_setshortnotegatetime
case 0xC2: // layer_transpose; set transposition in semitones case 0xC2: // layer_transpose; set transposition in semitones
{ tempByte = *(state->pc++);
u8 tempByte = *(state->pc++);
if (cmd == 0xC9) { if (cmd == 0xC9) {
layer->gateTime = tempByte; layer->gateTime = tempByte;
@ -512,7 +620,6 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) {
layer->transposition = tempByte; layer->transposition = tempByte;
} }
break; break;
}
case 0xC4: // layer_continuousnoteson case 0xC4: // layer_continuousnoteson
case 0xC5: // layer_continuousnotesoff case 0xC5: // layer_continuousnotesoff
@ -586,7 +693,6 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) {
sp3A = AudioSeq_ScriptReadS16(state); sp3A = AudioSeq_ScriptReadS16(state);
layer->adsr.envelope = (AdsrEnvelope*)(seqPlayer->seqData + sp3A); layer->adsr.envelope = (AdsrEnvelope*)(seqPlayer->seqData + sp3A);
// fallthrough // fallthrough
case 0xCF: case 0xCF:
layer->adsr.decayIndex = AudioSeq_ScriptReadU8(state); layer->adsr.decayIndex = AudioSeq_ScriptReadU8(state);
break; break;
@ -599,11 +705,10 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) {
layer->stereo.asByte = AudioSeq_ScriptReadU8(state); layer->stereo.asByte = AudioSeq_ScriptReadU8(state);
break; break;
case 0xCE: { case 0xCE:
u8 tempByte = AudioSeq_ScriptReadU8(state); tempByte = AudioSeq_ScriptReadU8(state);
layer->unk_34 = gBendPitchTwoSemitonesFrequencies[(tempByte + 0x80) & 0xFF]; layer->unk_34 = gBendPitchTwoSemitonesFrequencies[(tempByte + 0x80) & 0xFF];
break; break;
}
default: default:
switch (cmd & 0xF0) { switch (cmd & 0xF0) {
@ -611,6 +716,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) {
sp3A = seqPlayer->shortNoteVelocityTable[cmd & 0xF]; sp3A = seqPlayer->shortNoteVelocityTable[cmd & 0xF];
layer->velocitySquare = (f32)(sp3A * sp3A) / 16129.0f; layer->velocitySquare = (f32)(sp3A * sp3A) / 16129.0f;
break; break;
case 0xE0: // layer_setshortnotegatetimefromtable case 0xE0: // layer_setshortnotegatetimefromtable
layer->gateTime = (u8)seqPlayer->shortNoteGateTimeTable[cmd & 0xF]; layer->gateTime = (u8)seqPlayer->shortNoteGateTimeTable[cmd & 0xF];
break; break;
@ -989,27 +1095,28 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
s32 param; s32 param;
s16 pad1; s16 pad1;
u16 offset; u16 offset;
u32 parameters[3]; u32 cmdArgs[3];
s8 signedParam; s8 signedParam;
u8 command = AudioSeq_ScriptReadU8(scriptState); u8 cmd = AudioSeq_ScriptReadU8(scriptState);
u8 lowBits; u8 lowBits;
u8 highBits; u8 highBits;
s32 result; s32 result;
s32 pad2; s32 pad2;
if (command >= 0xB0) { if (cmd >= 0xB0) {
highBits = D_80130520[(s32)command - 0xB0]; highBits = sSeqInstructionArgsTable[cmd - 0xB0];
lowBits = highBits & 3; lowBits = highBits & 3;
// read in arguments for the instruction
for (i = 0; i < lowBits; i++, highBits <<= 1) { for (i = 0; i < lowBits; i++, highBits <<= 1) {
if (!(highBits & 0x80)) { if (!(highBits & 0x80)) {
parameters[i] = AudioSeq_ScriptReadU8(scriptState); cmdArgs[i] = AudioSeq_ScriptReadU8(scriptState);
} else { } else {
parameters[i] = AudioSeq_ScriptReadS16(scriptState); cmdArgs[i] = AudioSeq_ScriptReadS16(scriptState);
} }
} }
if (command >= 0xF2) { if (cmd >= 0xF2) {
result = AudioSeq_HandleScriptFlowControl(seqPlayer, scriptState, command, parameters[0]); result = AudioSeq_HandleScriptFlowControl(seqPlayer, scriptState, cmd, cmdArgs[0]);
if (result != 0) { if (result != 0) {
if (result == -1) { if (result == -1) {
@ -1020,22 +1127,26 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
break; break;
} }
} else { } else {
switch (command) { switch (cmd) {
case 0xEA: case 0xEA:
channel->stopScript = true; channel->stopScript = true;
goto exit_loop; goto exit_loop;
case 0xF1: case 0xF1:
Audio_NotePoolClear(&channel->notePool); Audio_NotePoolClear(&channel->notePool);
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
Audio_NotePoolFill(&channel->notePool, command); Audio_NotePoolFill(&channel->notePool, cmd);
break; break;
case 0xF0: case 0xF0:
Audio_NotePoolClear(&channel->notePool); Audio_NotePoolClear(&channel->notePool);
break; break;
case 0xC2: case 0xC2:
offset = (u16)parameters[0]; offset = (u16)cmdArgs[0];
channel->dynTable = (void*)&seqPlayer->seqData[offset]; channel->dynTable = (void*)&seqPlayer->seqData[offset];
break; break;
case 0xC5: case 0xC5:
if (scriptState->value != -1) { if (scriptState->value != -1) {
@ -1045,196 +1156,227 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
channel->dynTable = (void*)&seqPlayer->seqData[offset]; channel->dynTable = (void*)&seqPlayer->seqData[offset];
} }
break; break;
case 0xEB: case 0xEB:
result = (u8)parameters[0]; result = (u8)cmdArgs[0];
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
if (seqPlayer->defaultFont != 0xFF) { if (seqPlayer->defaultFont != 0xFF) {
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId]; offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
lowBits = gAudioContext.sequenceFontTable[offset]; lowBits = gAudioContext.sequenceFontTable[offset];
command = gAudioContext.sequenceFontTable[offset + lowBits - result]; cmd = gAudioContext.sequenceFontTable[offset + lowBits - result];
} }
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) { if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, cmd)) {
channel->fontId = command; channel->fontId = cmd;
} }
parameters[0] = parameters[1]; cmdArgs[0] = cmdArgs[1];
// NOTE: Intentional fallthrough // fallthrough
case 0xC1: case 0xC1:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
AudioSeq_SetInstrument(channel, command); AudioSeq_SetInstrument(channel, cmd);
break; break;
case 0xC3: case 0xC3:
channel->largeNotes = false; channel->largeNotes = false;
break; break;
case 0xC4: case 0xC4:
channel->largeNotes = true; channel->largeNotes = true;
break; break;
case 0xDF: case 0xDF:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
AudioSeq_SequenceChannelSetVolume(channel, command); AudioSeq_SequenceChannelSetVolume(channel, cmd);
channel->changes.s.volume = true; channel->changes.s.volume = true;
break; break;
case 0xE0: case 0xE0:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->volumeScale = (f32)(s32)command / 128.0f; channel->volumeScale = (f32)(s32)cmd / 128.0f;
channel->changes.s.volume = true; channel->changes.s.volume = true;
break; break;
case 0xDE: case 0xDE:
offset = (u16)parameters[0]; offset = (u16)cmdArgs[0];
channel->freqScale = (f32)(s32)offset / 32768.0f; channel->freqScale = (f32)(s32)offset / 32768.0f;
channel->changes.s.freqScale = true; channel->changes.s.freqScale = true;
break; break;
case 0xD3: case 0xD3:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
command += 0x80; cmd += 0x80;
channel->freqScale = gBendPitchOneOctaveFrequencies[command]; channel->freqScale = gBendPitchOneOctaveFrequencies[cmd];
channel->changes.s.freqScale = true; channel->changes.s.freqScale = true;
break; break;
case 0xEE: case 0xEE:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
command += 0x80; cmd += 0x80;
channel->freqScale = gBendPitchTwoSemitonesFrequencies[command]; channel->freqScale = gBendPitchTwoSemitonesFrequencies[cmd];
channel->changes.s.freqScale = true; channel->changes.s.freqScale = true;
break; break;
case 0xDD: case 0xDD:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->newPan = command; channel->newPan = cmd;
channel->changes.s.pan = true; channel->changes.s.pan = true;
break; break;
case 0xDC: case 0xDC:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->panChannelWeight = command; channel->panChannelWeight = cmd;
channel->changes.s.pan = true; channel->changes.s.pan = true;
break; break;
case 0xDB: case 0xDB:
signedParam = (s8)parameters[0]; signedParam = (s8)cmdArgs[0];
channel->transposition = signedParam; channel->transposition = signedParam;
break; break;
case 0xDA: case 0xDA:
offset = (u16)parameters[0]; offset = (u16)cmdArgs[0];
channel->adsr.envelope = (AdsrEnvelope*)&seqPlayer->seqData[offset]; channel->adsr.envelope = (AdsrEnvelope*)&seqPlayer->seqData[offset];
break; break;
case 0xD9: case 0xD9:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->adsr.decayIndex = command; channel->adsr.decayIndex = cmd;
break; break;
case 0xD8: case 0xD8:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->vibratoExtentTarget = command * 8; channel->vibratoExtentTarget = cmd * 8;
channel->vibratoExtentStart = 0; channel->vibratoExtentStart = 0;
channel->vibratoExtentChangeDelay = 0; channel->vibratoExtentChangeDelay = 0;
break; break;
case 0xD7: case 0xD7:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->vibratoRateChangeDelay = 0; channel->vibratoRateChangeDelay = 0;
channel->vibratoRateTarget = command * 32; channel->vibratoRateTarget = cmd * 32;
channel->vibratoRateStart = command * 32; channel->vibratoRateStart = cmd * 32;
break; break;
case 0xE2: case 0xE2:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->vibratoExtentStart = command * 8; channel->vibratoExtentStart = cmd * 8;
command = (u8)parameters[1]; cmd = (u8)cmdArgs[1];
channel->vibratoExtentTarget = command * 8; channel->vibratoExtentTarget = cmd * 8;
command = (u8)parameters[2]; cmd = (u8)cmdArgs[2];
channel->vibratoExtentChangeDelay = command * 16; channel->vibratoExtentChangeDelay = cmd * 16;
break; break;
case 0xE1: case 0xE1:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->vibratoRateStart = command * 32; channel->vibratoRateStart = cmd * 32;
command = (u8)parameters[1]; cmd = (u8)cmdArgs[1];
channel->vibratoRateTarget = command * 32; channel->vibratoRateTarget = cmd * 32;
command = (u8)parameters[2]; cmd = (u8)cmdArgs[2];
channel->vibratoRateChangeDelay = command * 16; channel->vibratoRateChangeDelay = cmd * 16;
break; break;
case 0xE3: case 0xE3:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->vibratoDelay = command * 16; channel->vibratoDelay = cmd * 16;
break; break;
case 0xD4: case 0xD4:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->reverb = command; channel->reverb = cmd;
break; break;
case 0xC6: case 0xC6:
result = (u8)parameters[0]; result = (u8)cmdArgs[0];
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
if (seqPlayer->defaultFont != 0xFF) { if (seqPlayer->defaultFont != 0xFF) {
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId]; offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
lowBits = gAudioContext.sequenceFontTable[offset]; lowBits = gAudioContext.sequenceFontTable[offset];
command = gAudioContext.sequenceFontTable[offset + lowBits - result]; cmd = gAudioContext.sequenceFontTable[offset + lowBits - result];
} }
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) { if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, cmd)) {
channel->fontId = command; channel->fontId = cmd;
} }
break; break;
case 0xC7: case 0xC7:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
offset = (u16)parameters[1]; offset = (u16)cmdArgs[1];
test = &seqPlayer->seqData[offset]; test = &seqPlayer->seqData[offset];
test[0] = (u8)scriptState->value + command; test[0] = (u8)scriptState->value + cmd;
break; break;
case 0xC8: case 0xC8:
case 0xCC: case 0xCC:
case 0xC9: case 0xC9:
signedParam = (s8)parameters[0]; signedParam = (s8)cmdArgs[0];
if (command == 0xC8) { if (cmd == 0xC8) {
scriptState->value -= signedParam; scriptState->value -= signedParam;
} else if (command == 0xCC) { } else if (cmd == 0xCC) {
scriptState->value = signedParam; scriptState->value = signedParam;
} else { } else {
scriptState->value &= signedParam; scriptState->value &= signedParam;
} }
break; break;
case 0xCD: case 0xCD:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
AudioSeq_SequenceChannelDisable(seqPlayer->channels[command]); AudioSeq_SequenceChannelDisable(seqPlayer->channels[cmd]);
break; break;
case 0xCA: case 0xCA:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->muteBehavior = command; channel->muteBehavior = cmd;
channel->changes.s.volume = true; channel->changes.s.volume = true;
break; break;
case 0xCB:
offset = (u16)parameters[0];
case 0xCB:
offset = (u16)cmdArgs[0];
scriptState->value = *(seqPlayer->seqData + (u32)(offset + scriptState->value)); scriptState->value = *(seqPlayer->seqData + (u32)(offset + scriptState->value));
break; break;
case 0xCE: case 0xCE:
offset = (u16)parameters[0]; offset = (u16)cmdArgs[0];
channel->unk_22 = offset; channel->unk_22 = offset;
break; break;
case 0xCF: case 0xCF:
offset = (u16)parameters[0]; offset = (u16)cmdArgs[0];
test = &seqPlayer->seqData[offset]; test = &seqPlayer->seqData[offset];
test[0] = (channel->unk_22 >> 8) & 0xFF; test[0] = (channel->unk_22 >> 8) & 0xFF;
test[1] = channel->unk_22 & 0xFF; test[1] = channel->unk_22 & 0xFF;
break; break;
case 0xD0: case 0xD0:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
if (command & 0x80) { if (cmd & 0x80) {
channel->stereoHeadsetEffects = true; channel->stereoHeadsetEffects = true;
} else { } else {
channel->stereoHeadsetEffects = false; channel->stereoHeadsetEffects = false;
} }
channel->stereo.asByte = command & 0x7F; channel->stereo.asByte = cmd & 0x7F;
break; break;
case 0xD1: case 0xD1:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->noteAllocPolicy = command; channel->noteAllocPolicy = cmd;
break; break;
case 0xD2: case 0xD2:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->adsr.sustain = command; channel->adsr.sustain = cmd;
break; break;
case 0xE5: case 0xE5:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->reverbIndex = command; channel->reverbIndex = cmd;
break; break;
case 0xE4: case 0xE4:
if (scriptState->value != -1) { if (scriptState->value != -1) {
data = (*channel->dynTable)[scriptState->value]; data = (*channel->dynTable)[scriptState->value];
@ -1244,12 +1386,14 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
scriptState->pc = seqPlayer->seqData + offset; scriptState->pc = seqPlayer->seqData + offset;
} }
break; break;
case 0xE6: case 0xE6:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->bookOffset = command; channel->bookOffset = cmd;
break; break;
case 0xE7: case 0xE7:
offset = (u16)parameters[0]; offset = (u16)cmdArgs[0];
data = &seqPlayer->seqData[offset]; data = &seqPlayer->seqData[offset];
channel->muteBehavior = data[0]; channel->muteBehavior = data[0];
data += 3; data += 3;
@ -1264,11 +1408,12 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
//! @bug: Not marking reverb state as changed //! @bug: Not marking reverb state as changed
channel->changes.s.pan = true; channel->changes.s.pan = true;
break; break;
case 0xE8: case 0xE8:
channel->muteBehavior = parameters[0]; channel->muteBehavior = cmdArgs[0];
channel->noteAllocPolicy = parameters[1]; channel->noteAllocPolicy = cmdArgs[1];
command = (u8)parameters[2]; cmd = (u8)cmdArgs[2];
AudioSeq_SetChannelPriorities(channel, command); AudioSeq_SetChannelPriorities(channel, cmd);
channel->transposition = (s8)AudioSeq_ScriptReadU8(scriptState); channel->transposition = (s8)AudioSeq_ScriptReadU8(scriptState);
channel->newPan = AudioSeq_ScriptReadU8(scriptState); channel->newPan = AudioSeq_ScriptReadU8(scriptState);
channel->panChannelWeight = AudioSeq_ScriptReadU8(scriptState); channel->panChannelWeight = AudioSeq_ScriptReadU8(scriptState);
@ -1277,6 +1422,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
//! @bug: Not marking reverb state as changed //! @bug: Not marking reverb state as changed
channel->changes.s.pan = true; channel->changes.s.pan = true;
break; break;
case 0xEC: case 0xEC:
channel->vibratoExtentTarget = 0; channel->vibratoExtentTarget = 0;
channel->vibratoExtentStart = 0; channel->vibratoExtentStart = 0;
@ -1294,82 +1440,97 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
channel->bookOffset = 0; channel->bookOffset = 0;
channel->freqScale = 1.0f; channel->freqScale = 1.0f;
break; break;
case 0xE9: case 0xE9:
AudioSeq_SetChannelPriorities(channel, (u8)parameters[0]); AudioSeq_SetChannelPriorities(channel, (u8)cmdArgs[0]);
break; break;
case 0xED: case 0xED:
command = (u8)parameters[0]; cmd = (u8)cmdArgs[0];
channel->unk_0C = command; channel->unk_0C = cmd;
break; break;
case 0xB0: case 0xB0:
offset = (u16)parameters[0]; offset = (u16)cmdArgs[0];
data = seqPlayer->seqData + offset; data = seqPlayer->seqData + offset;
channel->filter = (s16*)data; channel->filter = (s16*)data;
break; break;
case 0xB1: case 0xB1:
channel->filter = NULL; channel->filter = NULL;
break; break;
case 0xB3: case 0xB3:
command = parameters[0]; cmd = cmdArgs[0];
if (channel->filter != NULL) { if (channel->filter != NULL) {
lowBits = (command >> 4) & 0xF; // LowPassCutoff lowBits = (cmd >> 4) & 0xF; // LowPassCutoff
command &= 0xF; // HighPassCutoff cmd &= 0xF; // HighPassCutoff
AudioHeap_LoadFilter(channel->filter, lowBits, command); AudioHeap_LoadFilter(channel->filter, lowBits, cmd);
} }
break; break;
case 0xB2: case 0xB2:
offset = (u16)parameters[0]; offset = (u16)cmdArgs[0];
channel->unk_22 = *(u16*)(seqPlayer->seqData + (u32)(offset + scriptState->value * 2)); channel->unk_22 = *(u16*)(seqPlayer->seqData + (u32)(offset + scriptState->value * 2));
break; break;
case 0xB4: case 0xB4:
channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22]; channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22];
break; break;
case 0xB5: case 0xB5:
channel->unk_22 = ((u16*)(channel->dynTable))[scriptState->value]; channel->unk_22 = ((u16*)(channel->dynTable))[scriptState->value];
break; break;
case 0xB6: case 0xB6:
scriptState->value = (*channel->dynTable)[0][scriptState->value]; scriptState->value = (*channel->dynTable)[0][scriptState->value];
break; break;
case 0xB7: case 0xB7:
channel->unk_22 = (parameters[0] == 0) ? gAudioContext.audioRandom & 0xFFFF channel->unk_22 = (cmdArgs[0] == 0) ? gAudioContext.audioRandom & 0xFFFF
: gAudioContext.audioRandom % parameters[0]; : gAudioContext.audioRandom % cmdArgs[0];
break; break;
case 0xB8: case 0xB8:
scriptState->value = (parameters[0] == 0) ? gAudioContext.audioRandom & 0xFFFF scriptState->value = (cmdArgs[0] == 0) ? gAudioContext.audioRandom & 0xFFFF
: gAudioContext.audioRandom % parameters[0]; : gAudioContext.audioRandom % cmdArgs[0];
break; break;
case 0xBD: {
case 0xBD:
result = Audio_NextRandom(); result = Audio_NextRandom();
channel->unk_22 = (parameters[0] == 0) ? (u32)result & 0xFFFF : (u32)result % parameters[0]; channel->unk_22 = (cmdArgs[0] == 0) ? (u32)result & 0xFFFF : (u32)result % cmdArgs[0];
channel->unk_22 += parameters[1]; channel->unk_22 += cmdArgs[1];
pad2 = (channel->unk_22 / 0x100) + 0x80; // i is wrong here pad2 = (channel->unk_22 / 0x100) + 0x80; // i is wrong here
param = channel->unk_22 % 0x100; param = channel->unk_22 % 0x100;
channel->unk_22 = (pad2 << 8) | param; channel->unk_22 = (pad2 << 8) | param;
} break;
case 0xB9:
channel->velocityRandomVariance = parameters[0];
break; break;
case 0xBA:
channel->gateTimeRandomVariance = parameters[0];
break;
case 0xBB:
channel->unk_0F = parameters[0];
channel->unk_20 = parameters[1];
break;
case 0xBC:
channel->unk_22 += parameters[0];
break;
}
}
} else if (command >= 0x70) {
lowBits = command & 0x7;
if ((command & 0xF8) != 0x70 && lowBits >= 4) { case 0xB9:
channel->velocityRandomVariance = cmdArgs[0];
break;
case 0xBA:
channel->gateTimeRandomVariance = cmdArgs[0];
break;
case 0xBB:
channel->unk_0F = cmdArgs[0];
channel->unk_20 = cmdArgs[1];
break;
case 0xBC:
channel->unk_22 += cmdArgs[0];
break;
}
}
} else if (cmd >= 0x70) {
lowBits = cmd & 0x7;
if ((cmd & 0xF8) != 0x70 && lowBits >= 4) {
lowBits = 0; lowBits = 0;
} }
switch (command & 0xF8) { switch (cmd & 0xF8) {
case 0x80: case 0x80:
if (channel->layers[lowBits] != NULL) { if (channel->layers[lowBits] != NULL) {
scriptState->value = channel->layers[lowBits]->finished; scriptState->value = channel->layers[lowBits]->finished;
@ -1377,27 +1538,30 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
scriptState->value = -1; scriptState->value = -1;
} }
break; break;
case 0x88: case 0x88:
offset = AudioSeq_ScriptReadS16(scriptState); offset = AudioSeq_ScriptReadS16(scriptState);
if (!AudioSeq_SeqChannelSetLayer(channel, lowBits)) { if (!AudioSeq_SeqChannelSetLayer(channel, lowBits)) {
channel->layers[lowBits]->scriptState.pc = &seqPlayer->seqData[offset]; channel->layers[lowBits]->scriptState.pc = &seqPlayer->seqData[offset];
} }
break; break;
case 0x90: case 0x90:
AudioSeq_SeqLayerFree(channel, lowBits); AudioSeq_SeqLayerFree(channel, lowBits);
break; break;
case 0x98:
if (scriptState->value == -1 || AudioSeq_SeqChannelSetLayer(channel, lowBits) == -1) {
break;
}
case 0x98:
if (scriptState->value != -1 && AudioSeq_SeqChannelSetLayer(channel, lowBits) != -1) {
data = (*channel->dynTable)[scriptState->value]; data = (*channel->dynTable)[scriptState->value];
offset = (data[0] << 8) + data[1]; offset = (data[0] << 8) + data[1];
channel->layers[lowBits]->scriptState.pc = &seqPlayer->seqData[offset]; channel->layers[lowBits]->scriptState.pc = &seqPlayer->seqData[offset];
}
break; break;
case 0x70: case 0x70:
channel->soundScriptIO[lowBits] = scriptState->value; channel->soundScriptIO[lowBits] = scriptState->value;
break; break;
case 0x78: case 0x78:
pad1 = AudioSeq_ScriptReadS16(scriptState); pad1 = AudioSeq_ScriptReadS16(scriptState);
if (!AudioSeq_SeqChannelSetLayer(channel, lowBits)) { if (!AudioSeq_SeqChannelSetLayer(channel, lowBits)) {
@ -1406,13 +1570,13 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
break; break;
} }
} else { } else {
lowBits = command & 0xF; lowBits = cmd & 0xF;
switch (command & 0xF0) { switch (cmd & 0xF0) {
case 0x00: { case 0x00:
channel->delay = lowBits; channel->delay = lowBits;
goto exit_loop; goto exit_loop;
}
case 0x10: case 0x10:
if (lowBits < 8) { if (lowBits < 8) {
channel->soundScriptIO[lowBits] = -1; channel->soundScriptIO[lowBits] = -1;
@ -1429,26 +1593,31 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
} }
} }
break; break;
case 0x60: case 0x60:
scriptState->value = channel->soundScriptIO[lowBits]; scriptState->value = channel->soundScriptIO[lowBits];
if (lowBits < 2) { if (lowBits < 2) {
channel->soundScriptIO[lowBits] = -1; channel->soundScriptIO[lowBits] = -1;
} }
break; break;
case 0x50: case 0x50:
scriptState->value -= channel->soundScriptIO[lowBits]; scriptState->value -= channel->soundScriptIO[lowBits];
break; break;
case 0x20: case 0x20:
offset = AudioSeq_ScriptReadS16(scriptState); offset = AudioSeq_ScriptReadS16(scriptState);
AudioSeq_SequenceChannelEnable(seqPlayer, lowBits, &seqPlayer->seqData[offset]); AudioSeq_SequenceChannelEnable(seqPlayer, lowBits, &seqPlayer->seqData[offset]);
break; break;
case 0x30: case 0x30:
command = AudioSeq_ScriptReadU8(scriptState); cmd = AudioSeq_ScriptReadU8(scriptState);
seqPlayer->channels[lowBits]->soundScriptIO[command] = scriptState->value; seqPlayer->channels[lowBits]->soundScriptIO[cmd] = scriptState->value;
break; break;
case 0x40: case 0x40:
command = AudioSeq_ScriptReadU8(scriptState); cmd = AudioSeq_ScriptReadU8(scriptState);
scriptState->value = seqPlayer->channels[lowBits]->soundScriptIO[command]; scriptState->value = seqPlayer->channels[lowBits]->soundScriptIO[cmd];
break; break;
} }
} }