jaudio_NES: add enums for MML commands

This commit is contained in:
Cuyler36
2025-11-01 11:44:19 -04:00
parent e2d9c7ae87
commit 6c81937894
2 changed files with 658 additions and 195 deletions
+179 -179
View File
@@ -173,26 +173,26 @@ static s32 Common_Com(group* group, macro* macro, s32 cmd, s32 arg) {
s8 rel;
switch (cmd) {
case SEQCMD_STOP_SCRIPT:
case COMMON_CMD_STOP_SCRIPT:
if (macro->depth == 0) {
return COMMON_SCRIPT_END;
}
macro->pc = macro->stack[--macro->depth];
break;
case SEQCMD_DELAY_N_FRAMES:
case COMMON_CMD_DELAY_N_FRAMES:
return Nas_ReadLengthData(macro);
case SEQCMD_DELAY_1_FRAME:
case COMMON_CMD_DELAY_1_FRAME:
return 1;
case SEQCMD_CALL:
case COMMON_CMD_CALL:
macro->stack[macro->depth++] = macro->pc;
macro->pc = group->seq_data + (arg & 0xFFFF);
break;
case SEQCMD_LOOP:
case COMMON_CMD_LOOP:
macro->remaining_loop_iters[macro->depth] = arg & 0xFF;
macro->stack[macro->depth++] = macro->pc;
break;
case SEQCMD_LOOP_END:
case COMMON_CMD_LOOP_END:
iters = macro->remaining_loop_iters[macro->depth - 1];
iters--;
macro->remaining_loop_iters[macro->depth - 1] = iters;
@@ -202,31 +202,31 @@ static s32 Common_Com(group* group, macro* macro, s32 cmd, s32 arg) {
macro->depth--;
}
break;
case SEQCMD_BREAK:
case COMMON_CMD_BREAK:
macro->depth--;
break;
case SEQCMD_BRANCH_ABS_GREQ_ZERO:
case SEQCMD_BRANCH_ABS_NOT_EQ_ZERO:
case SEQCMD_BRANCH_ABS_EQ_ZERO:
case SEQCMD_BRANCH_ABS:
case COMMON_CMD_BRANCH_ABS_GREQ_ZERO:
case COMMON_CMD_BRANCH_ABS_NOT_EQ_ZERO:
case COMMON_CMD_BRANCH_ABS_EQ_ZERO:
case COMMON_CMD_BRANCH_ABS:
abs = arg & 0xFFFF;
if (cmd == SEQCMD_BRANCH_ABS_EQ_ZERO && macro->value != 0) {
if (cmd == COMMON_CMD_BRANCH_ABS_EQ_ZERO && macro->value != 0) {
break;
} else if (cmd == SEQCMD_BRANCH_ABS_NOT_EQ_ZERO && macro->value >= 0) {
} else if (cmd == COMMON_CMD_BRANCH_ABS_NOT_EQ_ZERO && macro->value >= 0) {
break;
} else if (cmd == SEQCMD_BRANCH_ABS_GREQ_ZERO && macro->value < 0) {
} else if (cmd == COMMON_CMD_BRANCH_ABS_GREQ_ZERO && macro->value < 0) {
break;
} else {
macro->pc = group->seq_data + abs;
}
break;
case SEQCMD_BRANCH_REL_NOT_EQ_ZERO:
case SEQCMD_BRANCH_REL_EQ_ZERO:
case SEQCMD_BRANCH_REL:
case COMMON_CMD_BRANCH_REL_NOT_EQ_ZERO:
case COMMON_CMD_BRANCH_REL_EQ_ZERO:
case COMMON_CMD_BRANCH_REL:
rel = (s8)(arg & 0xFF);
if (cmd == SEQCMD_BRANCH_REL_EQ_ZERO && macro->value != 0) {
if (cmd == COMMON_CMD_BRANCH_REL_EQ_ZERO && macro->value != 0) {
break;
} else if (cmd == SEQCMD_BRANCH_REL_NOT_EQ_ZERO && macro->value >= 0) {
} else if (cmd == COMMON_CMD_BRANCH_REL_NOT_EQ_ZERO && macro->value >= 0) {
break;
} else {
macro->pc += rel;
@@ -561,13 +561,13 @@ static void Nas_NoteSeq(note* n) {
}
cmd = __SetNote(n, cmd);
} while (cmd == -1 && n->delay == 0);
} while (cmd == COMMON_SCRIPT_END && n->delay == 0);
if (cmd != -1) {
if (cmd != COMMON_SCRIPT_END) {
cmd = __SetVoice(n, cmd);
}
if (cmd != -1) {
if (cmd != COMMON_SCRIPT_END) {
__SetChannel(n, cmd);
}
@@ -640,11 +640,11 @@ static s32 __Command_Seq(note* n) {
while (TRUE) {
cmd = Nas_ReadByteData(m);
if (cmd <= 0xC0) {
if (cmd <= NOTE_CMD_MUTE) {
return cmd;
}
if (cmd >= SEQCMD_BRANCH_REL_NOT_EQ_ZERO) {
if (cmd >= COMMON_CMD_BRANCH_REL_NOT_EQ_ZERO) {
cmdArgU16 = Convert_Com(m, cmd);
if (Common_Com(grp, m, cmd, cmdArgU16) == 0) {
@@ -657,42 +657,42 @@ static s32 __Command_Seq(note* n) {
}
switch (cmd) {
case 0xC1:
case 0xCA:
case NOTE_CMD_SET_VELOCITY_SQ:
case NOTE_CMD_SET_PAN:
cmdArgU8 = *m->pc++;
if (cmd == 0xC1) {
if (cmd == NOTE_CMD_SET_VELOCITY_SQ) {
n->velocity_square = (f32)(cmdArgU8 * cmdArgU8) / (f32)(127 * 127);
} else {
n->pan = cmdArgU8;
}
break;
case 0xC2:
case 0xC9:
case NOTE_CMD_SET_TRANSPOSITION:
case NOTE_CMD_SET_GATE_TIME:
cmdArgU8 = *m->pc++;
if (cmd == 0xC9) {
if (cmd == NOTE_CMD_SET_GATE_TIME) {
n->gate_time = cmdArgU8;
} else {
n->transposition = cmdArgU8;
}
break;
case 0xC4:
case 0xC5:
n->continuous = cmd == 0xC4;
case NOTE_CMD_CONTINUOUS_ON:
case NOTE_CMD_CONTINUOUS_OFF:
n->continuous = cmd == NOTE_CMD_CONTINUOUS_ON;
n->_00bit1 = FALSE;
Nas_Release_Channel(n);
break;
case 0xC3:
case NOTE_CMD_SET_SHORT_NOTE_DEFAULT_DELAY:
n->short_note_default_delay = Nas_ReadLengthData(m);
break;
case 0xC6:
case NOTE_CMD_SET_INSTRUMENT:
cmdArgU8 = Nas_ReadByteData(m);
if (cmdArgU8 >= 0x7E) {
if (cmdArgU8 == 0x7E) {
// effect/sfx
n->inst_or_wave = 1;
n->inst_or_wave = VOICE_TYPE_SOUND_EFF;
} else if (cmdArgU8 == 0x7F) {
// percussion/drum
n->inst_or_wave = 0;
n->inst_or_wave = VOICE_TYPE_PERCUSSION;
} else {
// synth wave
n->inst_or_wave = cmdArgU8;
@@ -711,7 +711,7 @@ static s32 __Command_Seq(note* n) {
}
}
break;
case 0xC7:
case NOTE_CMD_ENABLE_SWEEP:
n->portamento_sweep.mode = Nas_ReadByteData(m);
cmdArgU8 = Nas_ReadByteData(m);
cmdArgU8 = cmdArgU8 + subtrack->transposition;
@@ -736,39 +736,39 @@ static s32 __Command_Seq(note* n) {
n->portamento_time = Nas_ReadLengthData(m);
}
break;
case 0xC8:
case NOTE_CMD_DISABLE_SWEEP:
n->portamento_sweep.mode = PORTAMENTO_MODE_OFF;
break;
case 0xCB:
case NOTE_CMD_SET_ADSR_ENVELOPE_DECAY_IDX:
n->adsr_env.envelope = (envdat*)(grp->seq_data + (Nas_ReadWordData(m) & 0xFFFF));
// fallthrough 0xCB -> 0xCF
case 0xCF:
case NOTE_CMD_SET_ADSR_DECAY_IDX:
n->adsr_env.decay_idx = Nas_ReadByteData(m);
break;
case 0xCC:
case NOTE_CMD_IGNORE_DRUM_PAN:
n->ignore_drum_pan = TRUE;
break;
case 0xCD:
case NOTE_CMD_SET_STEREO_PHASE:
*(u8*)&n->stereo_phase = Nas_ReadByteData(m);
break;
case 0xCE:
case NOTE_CMD_SET_BEND:
cmdArgU8 = 128 + Nas_ReadByteData(m);
n->bend = PCENTTABLE2[cmdArgU8];
break;
case 0xF0:
case NOTE_CMD_DISABLE_FLAGS:
cmdArgU16 = Nas_ReadWordData(m);
n->_0A.asU16 &= cmdArgU16 ^ 0xFFFF;
break;
case 0xF1:
case NOTE_CMD_SET_SURROUND_EFFECT_IDX:
n->surround_effect_idx = Nas_ReadByteData(m);
break;
default:
switch (cmd & 0xF0) {
case 0xD0:
case NOTE_CMD_SHORT_NOTE_VELOCITY_SQ_MASK:
velocity = grp->short_note_velocity_tbl[cmd & 0xF];
n->velocity_square = (f32)(velocity * velocity) / (f32)(127 * 127);
break;
case 0xE0:
case NOTE_CMD_SET_SHORT_NOTE_GATE_TIME_MASK:
n->gate_time = grp->short_note_gate_time_tbl[cmd & 0xF];
break;
}
@@ -1248,7 +1248,7 @@ static void Nas_SubSeq(sub* subtrack) {
hi_bits = hi_bits << 1;
}
if (cmd >= 0xF2) {
if (cmd >= COMMON_CMD_BRANCH_REL_NOT_EQ_ZERO) {
s32 delay = Common_Com(grp, m, cmd, cmdArgs[0]);
if (delay != 0) {
@@ -1262,27 +1262,27 @@ static void Nas_SubSeq(sub* subtrack) {
}
} else {
switch ((u8)cmd) {
case 0xEA: // stop subtrack seq script
case SUBTRACK_CMD_STOP: // stop subtrack seq script
subtrack->stop_script = TRUE;
goto note_seq;
case 0xF1: // alloc voices
case SUBTRACK_CMD_ALLOC_VOICES: // alloc voices
Nas_DeAllocAllVoices(&subtrack->channel_node);
Nas_AllocVoices(&subtrack->channel_node, cmdArgs[0] & 0xFF);
break;
case 0xF0: // dealloc voices
case SUBTRACK_CMD_DEALLOC_VOICES: // dealloc voices
Nas_DeAllocAllVoices(&subtrack->channel_node);
break;
case 0xC2: // set dynamic table
case SUBTRACK_CMD_SET_DYNTBL: // set dynamic table
subtrack->dyn_tbl = (unsigned char(*)[][2])&grp->seq_data[(u16)cmdArgs[0]];
break;
case 0xC5: // jump to entry in dynamic table
case SUBTRACK_CMD_JMP_DYNTBL: // jump to entry in dynamic table
if (m->value != -1) {
data = (*subtrack->dyn_tbl)[m->value];
cmdArgU16 = (u16)((data[0] << 8) + data[1]);
m->pc = (u8*)&grp->seq_data[cmdArgU16];
}
break;
case 0xEB: // Load subtrack bank and set instruments
case SUBTRACK_CMD_INIT_INSTRUMENTS: // Load subtrack bank and set instruments
cmdArgU8 = cmdArgs[0];
if (grp->bank_id != 0xFF) {
cmdArgU16 = AG.map_header[grp->seq_id];
@@ -1296,76 +1296,76 @@ static void Nas_SubSeq(sub* subtrack) {
cmdArgs[0] = cmdArgs[1];
// fallthrough 0xEB -> 0xC1
case 0xC1: // Set subtrack voice
case SUBTRACK_CMD_VOICE_SET: // Set subtrack voice
Nas_SubVoiceSet(subtrack, cmdArgs[0]);
break;
case 0xC3: // turn off large notes
case SUBTRACK_CMD_LARGE_NOTE_ON: // turn off large notes
subtrack->large_notes = FALSE;
break;
case 0xC4: // turn on large notes
case SUBTRACK_CMD_LARGE_NOTE_OFF: // turn on large notes
subtrack->large_notes = TRUE;
break;
case 0xDF: // set volume
case SUBTRACK_CMD_SET_VOL: // set volume
cmdArgU8 = (u8)cmdArgs[0];
Nas_SubVolumeSet(subtrack, cmdArgU8);
subtrack->changes.flags.volume = TRUE;
break;
case 0xE0: // set volume scale
case SUBTRACK_CMD_SET_VOL_SCALE: // set volume scale
cmdArgU8 = (u8)cmdArgs[0];
subtrack->volume_scale = (f32)(s32)cmdArgU8 / 128.0f;
subtrack->changes.flags.volume = TRUE;
break;
case 0xDE: // set frequency scale
case SUBTRACK_CMD_SET_FREQ_SCALE: // set frequency scale
cmdArgU16 = (u16)cmdArgs[0];
subtrack->frequency_scale = (f32)(s32)cmdArgU16 / (f32)0x8000;
subtrack->changes.flags.frequency_scale = TRUE;
break;
case 0xD3: // large bend pitch
case SUBTRACK_CMD_LARGE_BEND_PITCH: // large bend pitch
cmdArgU8 = (u8)cmdArgs[0];
cmdArgU8 += 128;
subtrack->frequency_scale = PCENTTABLE[cmdArgU8];
subtrack->changes.flags.frequency_scale = TRUE;
break;
case 0xEE: // small bend pitch
case SUBTRACK_CMD_SMALL_BEND_PITCH: // small bend pitch
cmdArgU8 = 128 + (u8)cmdArgs[0];
subtrack->frequency_scale = PCENTTABLE2[cmdArgU8];
subtrack->changes.flags.frequency_scale = TRUE;
break;
case 0xDD: // set pan
case SUBTRACK_CMD_SET_PAN: // set pan
cmdArgU8 = (u8)cmdArgs[0];
subtrack->new_pan = cmdArgU8;
subtrack->changes.flags.pan = TRUE;
break;
case 0xDC: // set pan mix/channel weight
case SUBTRACK_CMD_SET_PAN_WEIGHT: // set pan mix/channel weight
cmdArgU8 = (u8)cmdArgs[0];
subtrack->pan_channel_weight = cmdArgU8;
subtrack->changes.flags.pan = TRUE;
break;
case 0xDB: // set transposition
case SUBTRACK_CMD_SET_TRANSPOSITION: // set transposition
cmdArgS8 = (s8)cmdArgs[0];
subtrack->transposition = cmdArgS8;
break;
case 0xDA: // set envelope
case SUBTRACK_CMD_SET_ENVELOPE: // set envelope
cmdArgU16 = (u16)cmdArgs[0];
subtrack->adsr_env.envelope = (envdat*)&grp->seq_data[cmdArgU16];
break;
case 0xD9: // set decay index
case SUBTRACK_CMD_SET_DECAY_IDX: // set decay index
cmdArgU8 = (u8)cmdArgs[0];
subtrack->adsr_env.decay_idx = cmdArgU8;
break;
case 0xD8: // set vibrato depth
case SUBTRACK_CMD_SET_VIBRATO_DEPTH: // set vibrato depth
cmdArgU8 = (u8)cmdArgs[0];
subtrack->vibrato_params.depth_target = cmdArgU8 * 8;
subtrack->vibrato_params.depth_start = 0;
subtrack->vibrato_params.depth_change_delay = 0;
break;
case 0xD7: // set vibrato rate
case SUBTRACK_CMD_SET_VIBRATO_RATE: // set vibrato rate
cmdArgU8 = (u8)cmdArgs[0];
subtrack->vibrato_params.rate_target = cmdArgU8 * 32;
subtrack->vibrato_params.rate_start = cmdArgU8 * 32;
subtrack->vibrato_params.rate_change_delay = 0;
break;
case 0xE2: // set vibrato depth linear
case SUBTRACK_CMD_SET_VIBRATO_DEPTH_LINEAR: // set vibrato depth linear
cmdArgU8 = (u8)cmdArgs[0];
subtrack->vibrato_params.depth_start = cmdArgU8 * 8;
cmdArgU8 = (u8)cmdArgs[1];
@@ -1373,7 +1373,7 @@ static void Nas_SubSeq(sub* subtrack) {
cmdArgU8 = (u8)cmdArgs[2];
subtrack->vibrato_params.depth_change_delay = cmdArgU8 * 16;
break;
case 0xE1: // set vibrato rate linear
case SUBTRACK_CMD_SET_VIBRATO_RATE_LINEAR: // set vibrato rate linear
cmdArgU8 = (u8)cmdArgs[0];
subtrack->vibrato_params.rate_start = cmdArgU8 * 32;
cmdArgU8 = (u8)cmdArgs[1];
@@ -1381,15 +1381,15 @@ static void Nas_SubSeq(sub* subtrack) {
cmdArgU8 = (u8)cmdArgs[2];
subtrack->vibrato_params.rate_change_delay = cmdArgU8 * 16;
break;
case 0xE3: // set vibrato delay
case SUBTRACK_CMD_SET_VIBRATO_DELAY: // set vibrato delay
cmdArgU8 = (u8)cmdArgs[0];
subtrack->vibrato_params.delay = cmdArgU8 * 16;
break;
case 0xD4: // set reverb volume
case SUBTRACK_CMD_SET_REVERB_VOL: // set reverb volume
cmdArgU8 = (u8)cmdArgs[0];
subtrack->target_reverb_vol = cmdArgU8;
break;
case 0xC6: // set bank
case SUBTRACK_CMD_SET_INSTRUMENT_BANK: // set bank
cmdArgU8 = cmdArgs[0];
if (grp->bank_id != 0xFF) {
cmdArgU16 = AG.map_header[grp->seq_id]; // get offset for bank info for seq
@@ -1401,48 +1401,48 @@ static void Nas_SubSeq(sub* subtrack) {
subtrack->bank_id = cmdArgU8;
}
break;
case 0xC7: // write to sequence script
case SUBTRACK_CMD_WRITE_GROUP_SEQ: // write to sequence script
cmdArgU8 = (u8)cmdArgs[0];
cmdArgU16 = (u16)cmdArgs[1];
seq_data = &grp->seq_data[cmdArgU16];
seq_data[0] = (u8)m->value + cmdArgU8;
break;
case 0xC8: // subtract macro value
case 0xCC: // set macro value
case 0xC9: // bit& macro value
case SUBTRACK_CMD_MACRO_SUBTRACT: // subtract macro value
case SUBTRACK_CMD_MACRO_SET: // set macro value
case SUBTRACK_CMD_MACRO_AND: // bit& macro value
cmdArgS8 = (s8)cmdArgs[0];
if (cmd == 0xC8) {
if (cmd == SUBTRACK_CMD_MACRO_SUBTRACT) {
m->value -= cmdArgS8;
} else if (cmd == 0xCC) {
} else if (cmd == SUBTRACK_CMD_MACRO_SET) {
m->value = cmdArgS8;
} else {
m->value &= cmdArgS8;
}
break;
case 0xCD: // disable subtrack
case SUBTRACK_CMD_DISABLE_SUBTRACK: // disable subtrack
cmdArgU8 = (u8)cmdArgs[0];
Nas_ReleaseSubTrack(grp->subtracks[cmdArgU8]);
break;
case 0xCA: // set mute flags
case SUBTRACK_CMD_SET_MUTE_FLAGS: // set mute flags
cmdArgU8 = (u8)cmdArgs[0];
subtrack->mute_flags = cmdArgU8;
subtrack->changes.flags.volume = TRUE;
break;
case 0xCB: // load macro register value from table
case SUBTRACK_CMD_MACRO_LOAD_FROM_GROUP_SEQ: // load macro register value from table
cmdArgU16 = (u16)cmdArgs[0];
m->value = grp->seq_data[(u32)(cmdArgU16 + m->value)];
break;
case 0xCE: // set stored sequence data index
case SUBTRACK_CMD_SET_DYNVAL: // set stored sequence data index
cmdArgU16 = (u16)cmdArgs[0];
subtrack->dynamic_value = cmdArgU16;
break;
case 0xCF: // write u16 into sequence script
case SUBTRACK_CMD_WRITE_DYNVAL_TO_GROUP_SEQ: // write u16 into sequence script
cmdArgU16 = (u16)cmdArgs[0];
seq_data = &grp->seq_data[cmdArgU16];
seq_data[0] = (subtrack->dynamic_value >> 8) & 0xFF;
seq_data[1] = subtrack->dynamic_value & 0xFF;
break;
case 0xD0: // stereo phase effects
case SUBTRACK_CMD_STEREO_PHASE_SET: // stereo phase effects
cmdArgU8 = (u8)cmdArgs[0];
if (cmdArgU8 & 0x80) {
subtrack->stereo_effects = TRUE;
@@ -1452,19 +1452,19 @@ static void Nas_SubSeq(sub* subtrack) {
*(u8*)&subtrack->stereo_phase = cmdArgU8 & 0x7F;
break;
case 0xD1: // set note allocation policy
case SUBTRACK_CMD_SET_NOTE_ALLOC_POLICY: // set note allocation policy
cmdArgU8 = (u8)cmdArgs[0];
subtrack->note_alloc_policy = cmdArgU8;
break;
case 0xD2: // set sustain
case SUBTRACK_CMD_SET_SUSTAIN: // set sustain
cmdArgU8 = (u8)cmdArgs[0];
subtrack->adsr_env.sustain = cmdArgU8;
break;
case 0xE5: // set reverb index
case SUBTRACK_CMD_SET_REVERB_IDX: // set reverb index
cmdArgU8 = (u8)cmdArgs[0];
subtrack->reverb_idx = cmdArgU8;
break;
case 0xE4: // dynamic call
case SUBTRACK_CMD_DYNTBL_CALL: // dynamic call
if (m->value != -1) {
data = (*subtrack->dyn_tbl)[m->value];
/* @BUG - missing stack depth bounds check */
@@ -1473,11 +1473,11 @@ static void Nas_SubSeq(sub* subtrack) {
m->pc = &grp->seq_data[cmdArgU16];
}
break;
case 0xE6: // set book ofs
case SUBTRACK_CMD_SET_BOOK_OFS: // set book ofs
cmdArgU8 = (u8)cmdArgs[0];
subtrack->book_ofs = cmdArgU8;
break;
case 0xE7: //
case SUBTRACK_CMD_SET_ENV_PARAMS_FROM_GROUP_SEQ: //
cmdArgU16 = (u16)cmdArgs[0];
data = &grp->seq_data[cmdArgU16];
subtrack->mute_flags = data[0];
@@ -1491,7 +1491,7 @@ static void Nas_SubSeq(sub* subtrack) {
/* @BUG - didn't update reverb state as changed */
subtrack->changes.flags.pan = TRUE;
break;
case 0xE8: //
case SUBTRACK_CMD_SET_ENV_PARAMS: //
subtrack->mute_flags = cmdArgs[0];
subtrack->note_alloc_policy = cmdArgs[1];
cmdArgU8 = (u8)cmdArgs[2];
@@ -1504,7 +1504,7 @@ static void Nas_SubSeq(sub* subtrack) {
/* @BUG - didn't update reverb state as changed */
subtrack->changes.flags.pan = TRUE;
break;
case 0xEC: // reset vibrato
case SUBTRACK_CMD_RESET_VIBRATO: // reset vibrato
subtrack->frequency_scale = 1.0f;
subtrack->vibrato_params.depth_target = 0;
subtrack->vibrato_params.depth_start = 0;
@@ -1523,23 +1523,23 @@ static void Nas_SubSeq(sub* subtrack) {
subtrack->sample_start_pos = 0;
subtrack->_E0 = 0;
break;
case 0xE9: // set priority
case SUBTRACK_CMD_SET_PRIORITY: // set priority
cmdArgU8 = (u8)cmdArgs[0];
Nas_PriorityChanger(subtrack, cmdArgU8);
break;
case 0xED: // set gain
case SUBTRACK_CMD_SET_GAIN: // set gain
cmdArgU8 = (u8)cmdArgs[0];
subtrack->gain = cmdArgU8;
break;
case 0xB0: // set filter
case SUBTRACK_CMD_SET_FILTER: // set filter
cmdArgU16 = (u16)cmdArgs[0];
data = &grp->seq_data[cmdArgU16];
subtrack->filter = (s16*)data;
break;
case 0xB1: // clear filter
case SUBTRACK_CMD_CLEAR_FILTER: // clear filter
subtrack->filter = nullptr;
break;
case 0xB3: // load filter
case SUBTRACK_CMD_LOAD_FILTER: // load filter
cmdArgU8 = (u8)cmdArgs[0];
if (subtrack->filter != nullptr) {
lo_bits = (cmdArgU8 >> 4) & 0xF;
@@ -1547,59 +1547,59 @@ static void Nas_SubSeq(sub* subtrack) {
Nas_SetBPFilter(subtrack->filter, lo_bits, cmdArgU8);
}
break;
case 0xB2: // load dynamic idx
case SUBTRACK_CMD_LOAD_DYNVAL_FROM_GROUP_SEQ: // load dynamic idx
cmdArgU16 = (u16)cmdArgs[0];
subtrack->dynamic_value = *(u16*)&grp->seq_data[cmdArgU16 + m->value * 2];
break;
case 0xB4: // set dynamic table
case SUBTRACK_CMD_SET_DYNTBL_FROM_GROUP_SEQ: // set dynamic table
subtrack->dyn_tbl = (unsigned char(*)[][2]) & grp->seq_data[subtrack->dynamic_value];
break;
case 0xB5: // read from dynamic table
case SUBTRACK_CMD_LOAD_DYNVAL_FROM_DYNTBL: // read from dynamic table
subtrack->dynamic_value = ((u16*)subtrack->dyn_tbl)[m->value];
break;
case 0xB6: // read to macro register from dynamic table
case SUBTRACK_CMD_MACRO_LOAD_FROM_DYNTBL: // read to macro register from dynamic table
m->value = (*subtrack->dyn_tbl)[0][m->value];
break;
case 0xB7: // random dynamic value
case SUBTRACK_CMD_RANDOM_DYNVAL: // random dynamic value
if (cmdArgs[0] == 0) {
subtrack->dynamic_value = Nap_GetRandom();
} else {
subtrack->dynamic_value = Nap_GetRandom() % cmdArgs[0];
}
break;
case 0xB8: // macro register random value
case SUBTRACK_CMD_MACRO_RANDOM_VAL: // macro register random value
if (cmdArgs[0] == 0) {
m->value = Nap_GetRandom();
} else {
m->value = Nap_GetRandom() % cmdArgs[0];
}
break;
case 0xB9: // set velocity random variance
case SUBTRACK_CMD_SET_VEL_RANDOM_VARIANCE: // set velocity random variance
cmdArgU8 = (u8)cmdArgs[0];
subtrack->velocity_random_variance = cmdArgU8;
break;
case 0xBA: // set gate time random variance
case SUBTRACK_CMD_SET_GATE_TIME_RANDOM_VARIANCE: // set gate time random variance
cmdArgU8 = (u8)cmdArgs[0];
subtrack->gate_time_random_variance = cmdArgU8;
break;
case 0xBB: // set comb filter size & gain
case SUBTRACK_CMD_SET_COMB_FILTER_SIZE_GAIN: // set comb filter size & gain
cmdArgU8 = (u8)cmdArgs[0];
subtrack->comb_filter_size = cmdArgU8;
cmdArgU16 = (u16)cmdArgs[1];
subtrack->comb_filter_gain = cmdArgU16;
break;
case 0xBC: // Add to dynamic value
case SUBTRACK_CMD_ADD_DYNVAL: // Add to dynamic value
subtrack->dynamic_value += cmdArgs[0];
break;
case 0xA8: // Dynamic value bit shift & negate (when s16), differs from OoT and MM
case SUBTRACK_CMD_DYNVAL_SPECIAL: // Dynamic value bit shift & negate (when s16), differs from OoT and MM
new_var2 = (subtrack->dynamic_value & 0x7F);
new_var2 |= 0x8000 | ((subtrack->dynamic_value & 0x7FC0) << 1);
subtrack->dynamic_value = new_var2;
break;
case 0xBD: // set sample start pos
case SUBTRACK_CMD_SET_SAMPLE_START_POS: // set sample start pos
subtrack->sample_start_pos = cmdArgs[0];
break;
case 0xBE: // call custom sequence callback and update macro register value
case SUBTRACK_CMD_MACRO_SET_FROM_CALLBACK: // call custom sequence callback and update macro register value
if (cmdArgs[0] <= 4) {
if (AG.seq_callbacks[cmdArgs[0]] != nullptr) {
NA_CALLBACK = AG.seq_callbacks[cmdArgs[0]];
@@ -1607,37 +1607,37 @@ static void Nas_SubSeq(sub* subtrack) {
}
}
break;
case 0xA0: // read from sfx state using macro register value as index
case 0xA1: // read from sfx state using dynamic value as index
case 0xA2: // write to sfx state using macro register value as index
case 0xA3: // write to sfx state using dynamic value as index
if (cmd == 0xA0 || cmd == 0xA2) {
case SUBTRACK_CMD_MACRO_LOAD_FROM_SFX_STATE: // read from sfx state using macro register value as index
case SUBTRACK_CMD_MACRO_LOAD_FROM_SFX_STATE_DYNVAL: // read from sfx state using dynamic value as index
case SUBTRACK_CMD_SFX_STATE_SET: // write to sfx state using macro register value as index
case SUBTRACK_CMD_SFX_STATE_SET_DYNVAL: // write to sfx state using dynamic value as index
if (cmd == SUBTRACK_CMD_MACRO_LOAD_FROM_SFX_STATE || cmd == SUBTRACK_CMD_SFX_STATE_SET) {
cmdArgU16 = cmdArgs[0];
} else {
cmdArgU16 = subtrack->dynamic_value;
}
if (subtrack->sfx_state != nullptr) {
if (cmd == 0xA0 || cmd == 0xA1) {
if (cmd == SUBTRACK_CMD_MACRO_LOAD_FROM_SFX_STATE || cmd == SUBTRACK_CMD_MACRO_LOAD_FROM_SFX_STATE_DYNVAL) {
m->value = subtrack->sfx_state[cmdArgU16];
} else {
subtrack->sfx_state[cmdArgU16] = m->value;
}
}
break;
case 0xA4: // set surround effect index
case SUBTRACK_CMD_SURROUND_EFFECT_IDX_SET: // set surround effect index
subtrack->surround_effect_idx = cmdArgs[0];
break;
case 0xA5: // add subtrack index to macro register value
case SUBTRACK_CMD_MACRO_ADD_SUBTRACK_IDX: // add subtrack index to macro register value
m->value += subtrack->subtrack_idx;
break;
case 0xA6: // Set value in sequence data to macro register value plus arg value
case SUBTRACK_CMD_WRITE_GOUP_SEQ_OFFSET_BY_SUBTRACK: // Set value in sequence data to macro register value plus arg value
cmdArgU8 = (u8)cmdArgs[0];
cmdArgU16 = (u16)cmdArgs[1];
seq_data = &grp->seq_data[cmdArgU16 + subtrack->subtrack_idx];
*seq_data = (u8)m->value + cmdArgU8;
break;
case 0xA7: // manipulate macro register value
case SUBTRACK_CMD_MACRO_BIT_MOD: // manipulate macro register value
u32 shift = (cmdArgs[0] & 0xF);
lo_bits = (m->value & 0x80);
new_var2 = (cmdArgs[0] & 0x80);
@@ -1659,19 +1659,19 @@ static void Nas_SubSeq(sub* subtrack) {
}
}
// continue;
} else if (cmd >= 0x70) {
} else if (cmd >= SUBTRACK_CMD_PORT_WRITE_MACRO_REG_MASK) {
s32 hi_bits = (cmd & (u8)~7);
lo_bits = cmd;
lo_bits &= ~0xF8;
/* if command is not in range [0x70, 0x77] and the lower 4 bits are >= 4, set them to be 0xY0*/
if (hi_bits != 0x70 && lo_bits >= ARRAY_COUNT(subtrack->note_layers)) {
if (hi_bits != SUBTRACK_CMD_PORT_WRITE_MACRO_REG_MASK && lo_bits >= ARRAY_COUNT(subtrack->note_layers)) {
lo_bits = 0;
}
switch (hi_bits) {
// [0x80 - 0x83]
case 0x80: // macro register value = subtrack->note_layers[idx]->finished
case SUBTRACK_CMD_READ_NOTE_FINISHED_MASK: // macro register value = subtrack->note_layers[idx]->finished
if (subtrack->note_layers[lo_bits] != nullptr) {
m->value = subtrack->note_layers[lo_bits]->finished;
} else {
@@ -1679,18 +1679,18 @@ static void Nas_SubSeq(sub* subtrack) {
}
break;
// [0x88 - 0x8B]
case 0x88: // start note layer and initialize note macro pc
case SUBTRACK_CMD_NOTE_SET_PC_MASK: // start note layer and initialize note macro pc
cmdArgU16 = Nas_ReadWordData(m);
if (Nas_EntryNoteTrack(subtrack, lo_bits) == 0) {
subtrack->note_layers[lo_bits]->macro_player.pc = &grp->seq_data[cmdArgU16];
}
break;
// [0x90 - 0x93]
case 0x90: // stop note layer
case SUBTRACK_CMD_NOTE_STOP_MASK: // stop note layer
Nas_CloseNoteTrack(subtrack, lo_bits);
break;
// [0x98 - 0x9B]
case 0x98: // start note layer and initialize note macro pc from data at macro register offset
case SUBTRACK_CMD_NOTE_START_DYNTBL_MASK: // start note layer and initialize note macro pc from data at macro register offset
if (m->value != -1) {
if (Nas_EntryNoteTrack(subtrack, lo_bits) != -1) {
data = (*subtrack->dyn_tbl)[m->value];
@@ -1700,11 +1700,11 @@ static void Nas_SubSeq(sub* subtrack) {
}
break;
// [0x70 - 0x77]
case 0x70: // write macro register value into subtrack port
case SUBTRACK_CMD_PORT_WRITE_MACRO_REG_MASK: // write macro register value into subtrack port
subtrack->port[lo_bits] = m->value;
break;
// [0x78 - 0x7B]
case 0x78: // start note layer and initialize note macro pc from subtrack pc and rel offset
case SUBTRACK_CMD_NOTE_START_MASK: // start note layer and initialize note macro pc from subtrack pc and rel offset
temp1 = Nas_ReadWordData(m);
if (Nas_EntryNoteTrack(subtrack, lo_bits) == 0) {
subtrack->note_layers[lo_bits]->macro_player.pc = m->pc + temp1;
@@ -1716,7 +1716,7 @@ static void Nas_SubSeq(sub* subtrack) {
lo_bits = cmd & 0xF; // each command has 16 indicies which come from the lower 4 bits
switch (cmd & 0xF0) {
// [0x00, 0x0F]
case 0x00: // set delay
case SUBTRACK_CMD_DELAY_MASK: // set delay
subtrack->delay = lo_bits;
if (lo_bits == 0) {
break; /* clear delay, continue processing */
@@ -1724,7 +1724,7 @@ static void Nas_SubSeq(sub* subtrack) {
goto note_seq; /* delay > 0 so stop processing subtrack commands for now */
}
// [0x10, 0x17] & [0x18, 0x1F]
case 0x10: // load new wave samples
case SUBTRACK_CMD_VOICELOAD_MASK: // load new wave samples
if (lo_bits < 8) {
subtrack->port[lo_bits] = -1; // clear port
/* Load samples from bank with inst id being macro's register value, load result in
@@ -1738,28 +1738,28 @@ static void Nas_SubSeq(sub* subtrack) {
}
break;
// [0x60, 0x6F] (only 0x60, 0x67 are valid)
case 0x60: // read port value into macro register value
case SUBTRACK_CMD_MACRO_READ_PORT0_MASK: // read port value into macro register value
m->value = subtrack->port[lo_bits];
if (lo_bits < 2) {
subtrack->port[lo_bits] = -1;
}
break;
// [0x50, 0x5F] (only 0x50, 0x57 are valid)
case 0x50: // subtrack port value from macro register value
case SUBTRACK_CMD_MACRO_SUBTRACT_MASK: // subtrack port value from macro register value
m->value -= subtrack->port[lo_bits];
break;
// [0x20, 0x2F]
case 0x20: // start subtrack
case SUBTRACK_CMD_START_SUBTRACK_MASK: // start subtrack
cmdArgU16 = (u16)Nas_ReadWordData(m);
Nas_OpenSub(grp, lo_bits, &grp->seq_data[cmdArgU16]);
break;
// [0x30, 0x3F]
case 0x30: // set subtrack port to this subtrack's macro register value
case SUBTRACK_CMD_WRITE_SUBTRACK_PORT_MASK: // set subtrack port to this subtrack's macro register value
cmdArgU8 = Nas_ReadByteData(m);
grp->subtracks[lo_bits]->port[cmdArgU8] = m->value;
break;
// [0x40, 0x4F]
case 0x40: // set this subtrack's macro register value to other subtrack's port
case SUBTRACK_CMD_READ_SUBTRACK_PORT_MASK: // set this subtrack's macro register value to other subtrack's port
cmdArgU8 = Nas_ReadByteData(m);
m->value = grp->subtracks[lo_bits]->port[cmdArgU8];
break;
@@ -1838,7 +1838,7 @@ static void Nas_GroupSeq(group* grp) {
/* Sequence group commands processing loop */
while (TRUE) {
cmd = Nas_ReadByteData(m);
if (cmd >= 0xF2) {
if (cmd >= COMMON_CMD_BRANCH_REL_NOT_EQ_ZERO) {
u16 arg = Convert_Com(m, cmd);
delay = Common_Com(grp, m, cmd, arg);
@@ -1854,22 +1854,22 @@ static void Nas_GroupSeq(group* grp) {
}
} else if (cmd >= 0xC0) {
switch (cmd) {
case 0xF1: // reserve voices
case GRP_CMD_RESERVE_VOICES: // reserve voices
Nas_DeAllocAllVoices(&grp->channel_node);
cmd = Nas_ReadByteData(m);
Nas_AllocVoices(&grp->channel_node, (u8)cmd);
break;
case 0xF0: // release voices
case GRP_CMD_RELEASE_VOICES: // release voices
Nas_DeAllocAllVoices(&grp->channel_node);
break;
case 0xDF: // absolute transposition
case GRP_CMD_TRANSPOSITION_ABSOLUTE: // absolute transposition
grp->transposition = 0;
// fallthrough 0xDF -> 0xDE
case 0xDE: // relative transposition
case GRP_CMD_TRANSPOSITION_RELATIVE: // relative transposition
argU8 = Nas_ReadByteData(m);
grp->transposition = grp->transposition + (s8)argU8;
break;
case 0xDD: // set tempo
case GRP_CMD_SET_TEMPO: // set tempo
grp->tempo = Nas_ReadByteData(m) * AUDIO_TATUMS_PER_BEAT;
if (grp->tempo > AG.max_tempo) {
grp->tempo = AG.max_tempo;
@@ -1878,10 +1878,10 @@ static void Nas_GroupSeq(group* grp) {
grp->tempo = 1;
}
break;
case 0xDC: // adjust tempo relative
case GRP_CMD_SET_TEMPO_CHANGE: // adjust tempo relative
grp->tempo_change = (s8)Nas_ReadByteData(m) * AUDIO_TATUMS_PER_BEAT;
break;
case 0xDA: // change volume
case GRP_CMD_CHANGE_VOLUME: // change volume
cmd = Nas_ReadByteData(m);
temp = Nas_ReadWordData(m);
switch (cmd) {
@@ -1899,7 +1899,7 @@ static void Nas_GroupSeq(group* grp) {
break;
}
break;
case 0xDB: // set volume
case GRP_CMD_SET_VOLUME: // set volume
tempf32 = (s32)Nas_ReadByteData(m) / 127.0f;
switch (grp->state) {
case GROUP_STATE_FADE_IN:
@@ -1921,39 +1921,39 @@ static void Nas_GroupSeq(group* grp) {
break;
}
break;
case 0xD9: // set volume scale
case GRP_CMD_SET_VOLUME_SCALE: // set volume scale
grp->fade_volume_scale = (s8)Nas_ReadByteData(m) / 127.0f;
break;
case 0xD7: // initialize subtracks
case GRP_CMD_ALLOC_SUBTRACKS: // initialize subtracks
temp = Nas_ReadWordData(m);
Nas_AllocSub(grp, temp);
break;
case 0xD6: // [ineffective] - disable subtracks
case GRP_CMD_DISABLE_SUBTRACKS: // [ineffective] - disable subtracks
Nas_ReadWordData(m);
break;
case 0xD5: // set mute scale
case GRP_CMD_SET_MUTE_SCALE: // set mute scale
grp->mute_volume_scale = (s8)Nas_ReadByteData(m) / 127.0f;
break;
case 0xD4: // mute
case GRP_CMD_MUTE: // mute
grp->flags.muted = TRUE;
break;
case 0xD3: // set mute behaivor
case GRP_CMD_SET_MUTE_BEHAVIOR: // set mute behaivor
grp->mute_flags = Nas_ReadByteData(m);
break;
case 0xD1: // set short note gate-time table
case 0xD2: // set short note velocity table
case GRP_CMD_SET_SHORT_NOTE_GATE_TIME_TBL: // set short note gate-time table
case GRP_CMD_SET_SHORT_NOTE_VELOCITY_TBL: // set short note velocity table
temp = Nas_ReadWordData(m);
data3 = &grp->seq_data[temp];
if (cmd == 0xD2) {
if (cmd == GRP_CMD_SET_SHORT_NOTE_VELOCITY_TBL) {
grp->short_note_velocity_tbl = data3;
} else {
grp->short_note_gate_time_tbl = data3;
}
break;
case 0xD0: // set note allocation policy
case GRP_CMD_SET_NOTE_ALLOC_POLICY: // set note allocation policy
grp->note_alloc_policy = Nas_ReadByteData(m);
break;
case 0xCE: // set macro register value to random value
case GRP_CMD_MACRO_VALUE_RANDOM: // set macro register value to random value
cmd = Nas_ReadByteData(m);
if (cmd == 0) {
/* 0-255 */
@@ -1963,7 +1963,7 @@ static void Nas_GroupSeq(group* grp) {
m->value = (AG.audio_random_seed >> 2) % cmd;
}
break;
case 0xCD: // dynamic look-up table call
case GRP_CMD_DYN_TBL_CALL: // dynamic look-up table call
temp = Nas_ReadWordData(m);
if (m->value != -1 && m->depth != 3) {
data1 = &grp->seq_data[(u32)(temp + (m->value << 1))];
@@ -1972,22 +1972,22 @@ static void Nas_GroupSeq(group* grp) {
m->pc = &grp->seq_data[temp];
}
break;
case 0xCC: // set macro register value
case GRP_CMD_MACRO_VALUE_LOAD: // set macro register value
m->value = Nas_ReadByteData(m);
break;
case 0xC9: // macro register bit mask
case GRP_CMD_MACRO_VALUE_BIT_AND: // macro register bit mask
m->value &= Nas_ReadByteData(m);
break;
case 0xC8: // macro register subtraction
case GRP_CMD_MACRO_VALUE_SUBTRACT: // macro register subtraction
m->value -= Nas_ReadByteData(m);
break;
case 0xC7: // write macro register value to sequence data
case GRP_CMD_MACRO_VALUE_STORE: // write macro register value to sequence data
cmd = Nas_ReadByteData(m);
temp = Nas_ReadWordData(m);
data2 = &grp->seq_data[temp];
data2[0] = (u8)m->value + cmd;
break;
case 0xC2: // dynamic lookup branch (no return)
case GRP_CMD_DYNAMIC_BRANCH: // dynamic lookup branch (no return)
temp = Nas_ReadWordData(m);
if (m->value != -1) {
data4 = &grp->seq_data[(u32)(temp + (m->value << 1))];
@@ -1995,17 +1995,17 @@ static void Nas_GroupSeq(group* grp) {
m->pc = &grp->seq_data[temp];
}
break;
case 0xC6: // stop script
case GRP_CMD_STOP_SEQ: // stop script
grp->flags.stop_seq_script = TRUE;
return;
case 0xC5: // update counter
case GRP_CMD_UPDATE_COUNTER: // update counter
grp->counter = Nas_ReadWordData(m);
break;
case 0xEF: //
case GRP_CMD_EF: //
Nas_ReadWordData(m);
Nas_ReadByteData(m);
break;
case 0xC4: // start sequence script
case GRP_CMD_START_SEQ: // start sequence script
/* Get sequence group index */
cmd = Nas_ReadByteData(m);
if (cmd == 0xFF) {
@@ -2017,7 +2017,7 @@ static void Nas_GroupSeq(group* grp) {
return; // stop processing since we just used this group for a new sequence
}
break;
case 0xC3: // mute subtracks from u16 bitfield
case GRP_CMD_MUTE_SUBTRACKS: // mute subtracks from u16 bitfield
temp = Nas_ReadWordData(m);
if (m->value != -1) {
new_var = (u16*)(grp->seq_data + (u32)(temp + m->value * 2));
@@ -2029,7 +2029,7 @@ static void Nas_GroupSeq(group* grp) {
}
break;
}
} else if (cmd == 0xBE) {
} else if (cmd == GRP_CMD_CALLBACK) {
cmd = Nas_ReadByteData(m);
if (cmd <= 4) {
if (AG.seq_callbacks[cmd] != nullptr) {
@@ -2044,47 +2044,47 @@ static void Nas_GroupSeq(group* grp) {
cmd_lo_bits = cmd & 0x0F;
switch (cmd & 0xF0) {
// [0x00, 0x0F]
case 0x00: // macro register value = !subtrack->enabled
case GRP_CMD_MACRO_VALUE_LOAD_SUBTRACK_DISABLED_MASK: // macro register value = !subtrack->enabled
m->value = grp->subtracks[cmd_lo_bits]->enabled ^ TRUE;
break;
// [0x50, 0x57] @BUG - ([0x58, 0x5F] end here but would result in undefined behavior)
case 0x50: // macro register subtract port value
case GRP_CMD_MACRO_VALUE_SUBTRACT_FROM_PORT_MASK: // macro register subtract port value
m->value -= grp->port[cmd_lo_bits];
break;
// [0x70, 0x77] @BUG - ([0x78, 0x7F] end here but would result in undefined behavior)
case 0x70: // write macro register value into port
case GRP_CMD_MACRO_VALUE_WRITE_PORT_MASK: // write macro register value into port
grp->port[cmd_lo_bits] = m->value;
break;
// [0x80, 0x87] @BUG - ([0x88, 0x8F] end here but would result in undefined behavior)
case 0x80: // read macro register value from port
case GRP_CMD_MACRO_VALUE_READ_PORT_MASK: // read macro register value from port
m->value = grp->port[cmd_lo_bits];
if (cmd_lo_bits < 2) {
grp->port[cmd_lo_bits] = -1;
}
break;
// [0x40, 0x4F]
case 0x40: // disable subtrack
case GRP_CMD_DISABLE_SUBTRACK_MASK: // disable subtrack
Nas_ReleaseSubTrack(grp->subtracks[cmd_lo_bits]);
break;
// [0x90, 0x9F]
case 0x90: // start subtrack w/ absolute script address
case GRP_CMD_START_SUBTRACK_MASK: // start subtrack w/ absolute script address
temp = Nas_ReadWordData(m);
Nas_OpenSub(grp, cmd_lo_bits, &grp->seq_data[temp]);
break;
// [0xA0, 0xAF]
case 0xA0: // start subtrack w/ relative script address
case GRP_CMD_START_RELATIVE_SUBTRACK_MASK: // start subtrack w/ relative script address
tempS = Nas_ReadWordData(m);
Nas_OpenSub(grp, cmd_lo_bits, &m->pc[tempS]);
break;
// [0xB0, 0xB7] @BUG - ([0xB8, 0xBF] end here but would result in undefined behavior)
case 0xB0: // load sequence
case GRP_CMD_SEQ_LOAD_MASK: // load sequence
cmd = Nas_ReadByteData(m);
temp = Nas_ReadWordData(m);
data2 = &grp->seq_data[temp];
SeqLoad(cmd, data2, &grp->port[cmd_lo_bits]);
break;
// [0x60, 0x67] @BUG - ([0x68, 0x6F] end here but would result in undefined behavior)
case 0x60: // async load
case GRP_CMD_ASYNC_LOAD_MASK: // async load
cmd = (u8)Nas_ReadByteData(m);
argU8 = Nas_ReadByteData(m);
MK_load(cmd, argU8, (u8*)&grp->port[cmd_lo_bits]);