seq_channel_layer_process_script_copt.inc.c (18731B)
1 //! Copt inlining for US/JP. Here be dragons 2 // This version is basically identical to EU 3 4 #include <ultra64.h> 5 #include <macros.h> 6 7 #include "audio/heap.h" 8 #include "audio/data.h" 9 #include "audio/load.h" 10 #include "audio/seqplayer.h" 11 #include "audio/external.h" 12 #include "audio/effects.h" 13 14 #define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80) 15 #define PORTAMENTO_MODE(x) ((x).mode & ~0x80) 16 #define PORTAMENTO_MODE_1 1 17 #define PORTAMENTO_MODE_2 2 18 #define PORTAMENTO_MODE_3 3 19 #define PORTAMENTO_MODE_4 4 20 #define PORTAMENTO_MODE_5 5 21 22 #define COPT 0 23 #if COPT 24 #define M64_READ_U8(state, dst) \ 25 dst = m64_read_u8(state); 26 #else 27 #define M64_READ_U8(state, dst) \ 28 { \ 29 u8 * _ptr_pc; \ 30 u8 _pc; \ 31 _ptr_pc = (*state).pc; \ 32 ((*state).pc)++; \ 33 _pc = *_ptr_pc; \ 34 dst = _pc; \ 35 } 36 #endif 37 38 39 #if COPT 40 #define M64_READ_S16(state, dst) \ 41 dst = m64_read_s16(state); 42 #else 43 #define M64_READ_S16(state, dst) \ 44 { \ 45 s16 _ret; \ 46 _ret = *(*state).pc << 8; \ 47 ((*state).pc)++; \ 48 _ret = *(*state).pc | _ret; \ 49 ((*state).pc)++; \ 50 dst = _ret; \ 51 } 52 #endif 53 #if COPT 54 #define M64_READ_COMPRESSED_U16(state, dst) \ 55 dst = m64_read_compressed_u16(state); 56 #else 57 #define M64_READ_COMPRESSED_U16(state, dst) \ 58 { \ 59 u16 ret = *(state->pc++); \ 60 if (ret & 0x80) { \ 61 ret = (ret << 8) & 0x7f00; \ 62 ret = *(state->pc++) | ret; \ 63 } \ 64 dst = ret; \ 65 } 66 #endif 67 68 #if COPT 69 #define GET_INSTRUMENT(seqChannel, instId, _instOut, _adsr, dst, l) \ 70 dst = get_instrument(seqChannel, instId, _instOut, _adsr); 71 #else 72 #define GET_INSTRUMENT(seqChannel, instId, _instOut, _adsr, dst, l) \ 73 { \ 74 struct AdsrSettings *adsr = _adsr; \ 75 struct Instrument **instOut = _instOut;\ 76 u8 _instId = instId; \ 77 struct Instrument *inst; \ 78 UNUSED u32 pad; \ 79 /* copt inlines instId here */ \ 80 if (instId >= gCtlEntries[(*seqChannel).bankId].numInstruments) { \ 81 _instId = gCtlEntries[(*seqChannel).bankId].numInstruments; \ 82 if (_instId == 0) { \ 83 dst = 0; \ 84 goto ret ## l; \ 85 } \ 86 _instId--; \ 87 } \ 88 inst = gCtlEntries[(*seqChannel).bankId].instruments[_instId]; \ 89 if (inst == NULL) { \ 90 while (_instId != 0xff) { \ 91 inst = gCtlEntries[(*seqChannel).bankId].instruments[_instId]; \ 92 if (inst != NULL) { \ 93 goto gi ## l; \ 94 } \ 95 _instId--; \ 96 } \ 97 gi ## l:; \ 98 } \ 99 if (((uintptr_t) gBankLoadedPool.persistent.pool.start <= (uintptr_t) inst \ 100 && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.persistent.pool.start \ 101 + gBankLoadedPool.persistent.pool.size)) \ 102 || ((uintptr_t) gBankLoadedPool.temporary.pool.start <= (uintptr_t) inst \ 103 && (uintptr_t) inst <= (uintptr_t)(gBankLoadedPool.temporary.pool.start \ 104 + gBankLoadedPool.temporary.pool.size))) { \ 105 (*adsr).envelope = (*inst).envelope; \ 106 (*adsr).releaseRate = (*inst).releaseRate; \ 107 *instOut = inst; \ 108 _instId++; \ 109 goto ret ## l; \ 110 } \ 111 gAudioErrorFlags = _instId + 0x20000; \ 112 *instOut = NULL; \ 113 ret ## l: ; \ 114 } 115 #endif 116 117 void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) { 118 struct SequencePlayer *seqPlayer; // sp5C, t4 119 struct SequenceChannel *seqChannel; // sp58, t5 120 struct M64ScriptState *state; 121 struct Portamento *portamento; 122 struct AudioBankSound *sound; 123 struct Instrument *instrument; 124 struct Drum *drum; 125 s32 temp_a0_5; 126 u8 sameSound; 127 u8 cmd; // a0 sp3E, EU s2 128 u8 cmdSemitone; // sp3D, t0 129 u16 sp3A; // t2, a0, a1 130 f32 tuning; // f0 131 s32 vel; // sp30, t3 132 s32 usedSemitone; // a1 133 f32 freqScale; // sp28, f0 134 f32 sp24; 135 f32 temp_f12; 136 f32 temp_f2; 137 138 //! Copt: manually inline these functions in the scope of this routine 139 #ifdef __sgi 140 #pragma inline routine(m64_read_u8) 141 #pragma inline routine(m64_read_compressed_u16) 142 #pragma inline routine(m64_read_s16) 143 #pragma inline routine(get_instrument) 144 #endif 145 146 sameSound = TRUE; 147 if ((*layer).enabled == FALSE) { 148 return; 149 } 150 151 if ((*layer).delay > 1) { 152 (*layer).delay--; 153 if (!layer->stopSomething && layer->delay <= layer->duration) { 154 seq_channel_layer_note_decay(layer); 155 layer->stopSomething = TRUE; 156 } 157 return; 158 } 159 160 if (!layer->continuousNotes) { 161 seq_channel_layer_note_decay(layer); 162 } 163 164 if (PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_1 || 165 PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_2) { 166 layer->portamento.mode = 0; 167 } 168 169 seqChannel = (*layer).seqChannel; 170 seqPlayer = (*seqChannel).seqPlayer; 171 for (;;) { 172 state = &layer->scriptState; 173 //M64_READ_U8(state, cmd); 174 { 175 u8 *_ptr_pc; 176 _ptr_pc = (*state).pc++; 177 cmd = *_ptr_pc; 178 } 179 180 if (cmd <= 0xc0) { 181 break; 182 } 183 184 switch (cmd) { 185 case 0xff: // layer_end; function return or end of script 186 if (state->depth == 0) { 187 // N.B. this function call is *not* inlined even though it's 188 // within the same file, unlike in the rest of this function. 189 seq_channel_layer_disable(layer); 190 return; 191 } 192 state->depth--, state->pc = state->stack[state->depth]; 193 break; 194 195 case 0xfc: // layer_call 196 M64_READ_S16(state, sp3A); 197 state->depth++, state->stack[state->depth - 1] = state->pc; 198 state->pc = seqPlayer->seqData + sp3A; 199 break; 200 201 case 0xf8: // layer_loop; loop start, N iterations (or 256 if N = 0) 202 M64_READ_U8(state, state->remLoopIters[state->depth]); 203 state->depth++, state->stack[state->depth - 1] = state->pc; 204 break; 205 206 case 0xf7: // layer_loopend 207 if (--state->remLoopIters[state->depth - 1] != 0) { 208 state->pc = state->stack[state->depth - 1]; 209 } else { 210 state->depth--; 211 } 212 break; 213 214 case 0xfb: // layer_jump 215 M64_READ_S16(state, sp3A); 216 state->pc = seqPlayer->seqData + sp3A; 217 break; 218 219 case 0xc1: // layer_setshortnotevelocity 220 case 0xca: // layer_setpan 221 temp_a0_5 = *(state->pc++); 222 if (cmd == 0xc1) { 223 layer->velocitySquare = (f32)(temp_a0_5 * temp_a0_5); 224 } else { 225 layer->pan = (f32) temp_a0_5 / US_FLOAT(128.0); 226 } 227 break; 228 229 case 0xc2: // layer_transpose; set transposition in semitones 230 case 0xc9: // layer_setshortnoteduration 231 temp_a0_5 = *(state->pc++); 232 if (cmd == 0xc9) { 233 layer->noteDuration = temp_a0_5; 234 } else { 235 layer->transposition = temp_a0_5; 236 } 237 break; 238 239 case 0xc4: // layer_somethingon 240 case 0xc5: // layer_somethingoff 241 //! copt needs a ternary: 242 //layer->continuousNotes = (cmd == 0xc4) ? TRUE : FALSE; 243 { 244 u8 setting; 245 if (cmd == 0xc4) { 246 setting = TRUE; 247 } else { 248 setting = FALSE; 249 } 250 layer->continuousNotes = setting; 251 seq_channel_layer_note_decay(layer); 252 } 253 break; 254 255 case 0xc3: // layer_setshortnotedefaultplaypercentage 256 M64_READ_COMPRESSED_U16(state, sp3A); 257 layer->shortNoteDefaultPlayPercentage = sp3A; 258 break; 259 260 case 0xc6: // layer_setinstr 261 M64_READ_U8(state, cmdSemitone); 262 263 if (cmdSemitone < 127) { 264 GET_INSTRUMENT(seqChannel, cmdSemitone, &(*layer).instrument, &(*layer).adsr, cmdSemitone, 1); 265 } 266 break; 267 268 case 0xc7: // layer_portamento 269 M64_READ_U8(state, (*layer).portamento.mode); 270 M64_READ_U8(state, cmdSemitone); 271 272 cmdSemitone = cmdSemitone + (*seqChannel).transposition; 273 cmdSemitone += (*layer).transposition; 274 cmdSemitone += (*seqPlayer).transposition; 275 276 if (cmdSemitone >= 0x80) { 277 cmdSemitone = 0; 278 } 279 layer->portamentoTargetNote = cmdSemitone; 280 281 // If special, the next param is u8 instead of var 282 if (PORTAMENTO_IS_SPECIAL((*layer).portamento)) { 283 layer->portamentoTime = *((state)->pc++); 284 break; 285 } 286 287 M64_READ_COMPRESSED_U16(state, sp3A); 288 layer->portamentoTime = sp3A; 289 break; 290 291 case 0xc8: // layer_disableportamento 292 layer->portamento.mode = 0; 293 break; 294 295 default: 296 switch (cmd & 0xf0) { 297 case 0xd0: // layer_setshortnotevelocityfromtable 298 sp3A = seqPlayer->shortNoteVelocityTable[cmd & 0xf]; 299 (*layer).velocitySquare = (f32)(sp3A * sp3A); 300 break; 301 case 0xe0: // layer_setshortnotedurationfromtable 302 (*layer).noteDuration = seqPlayer->shortNoteDurationTable[cmd & 0xf]; 303 break; 304 } 305 } 306 } 307 308 if (cmd == 0xc0) { // layer_delay 309 M64_READ_COMPRESSED_U16(state, layer->delay); 310 layer->stopSomething = TRUE; 311 } else { 312 layer->stopSomething = FALSE; 313 314 if (seqChannel->largeNotes == TRUE) { 315 switch (cmd & 0xc0) { 316 case 0x00: // layer_note0 (play percentage, velocity, duration) 317 M64_READ_COMPRESSED_U16(state, sp3A); 318 vel = *((*state).pc++); 319 layer->noteDuration = *((*state).pc++); 320 layer->playPercentage = sp3A; 321 goto l1090; 322 323 case 0x40: // layer_note1 (play percentage, velocity) 324 M64_READ_COMPRESSED_U16(state, sp3A); 325 vel = *((*state).pc++); 326 layer->noteDuration = 0; 327 layer->playPercentage = sp3A; 328 goto l1090; 329 330 case 0x80: // layer_note2 (velocity, duration; uses last play percentage) 331 sp3A = layer->playPercentage; 332 vel = *((*state).pc++); 333 layer->noteDuration = *((*state).pc++); 334 goto l1090; 335 } 336 l1090: 337 cmdSemitone = cmd - (cmd & 0xc0); 338 layer->velocitySquare = vel * vel; 339 } else { 340 switch (cmd & 0xc0) { 341 case 0x00: // play note, type 0 (play percentage) 342 M64_READ_COMPRESSED_U16(state, sp3A); 343 layer->playPercentage = sp3A; 344 goto l1138; 345 346 case 0x40: // play note, type 1 (uses default play percentage) 347 sp3A = layer->shortNoteDefaultPlayPercentage; 348 goto l1138; 349 350 case 0x80: // play note, type 2 (uses last play percentage) 351 sp3A = layer->playPercentage; 352 goto l1138; 353 } 354 l1138: 355 356 cmdSemitone = cmd - (cmd & 0xc0); 357 } 358 359 layer->delay = sp3A; 360 layer->duration = layer->noteDuration * sp3A / 256; 361 if ((seqPlayer->muted && (seqChannel->muteBehavior & MUTE_BEHAVIOR_STOP_NOTES) != 0) 362 || seqChannel->stopSomething2 363 || !seqChannel->hasInstrument 364 ) { 365 layer->stopSomething = TRUE; 366 } else { 367 if (seqChannel->instOrWave == 0) { // drum 368 cmdSemitone += (*seqChannel).transposition + (*layer).transposition; 369 if (cmdSemitone >= gCtlEntries[seqChannel->bankId].numDrums) { 370 cmdSemitone = gCtlEntries[seqChannel->bankId].numDrums; 371 if (cmdSemitone == 0) { 372 // this goto looks a bit like a function return... 373 layer->stopSomething = TRUE; 374 goto skip; 375 } 376 377 cmdSemitone--; 378 } 379 380 drum = gCtlEntries[seqChannel->bankId].drums[cmdSemitone]; 381 if (drum == NULL) { 382 layer->stopSomething = TRUE; 383 } else { 384 layer->adsr.envelope = drum->envelope; 385 layer->adsr.releaseRate = drum->releaseRate; 386 layer->pan = FLOAT_CAST(drum->pan) / US_FLOAT(128.0); 387 layer->sound = &drum->sound; 388 layer->freqScale = layer->sound->tuning; 389 } 390 391 skip:; 392 } else { // instrument 393 cmdSemitone += (*seqPlayer).transposition + (*seqChannel).transposition + (*layer).transposition; 394 if (cmdSemitone >= 0x80) { 395 layer->stopSomething = TRUE; 396 } else { 397 instrument = layer->instrument; 398 if (instrument == NULL) { 399 instrument = seqChannel->instrument; 400 } 401 402 if (layer->portamento.mode != 0) { 403 //! copt needs a ternary: 404 //usedSemitone = (layer->portamentoTargetNote < cmdSemitone) ? cmdSemitone : layer->portamentoTargetNote; 405 if (layer->portamentoTargetNote < cmdSemitone) { 406 usedSemitone = cmdSemitone; 407 } else { 408 usedSemitone = layer->portamentoTargetNote; 409 } 410 411 if (instrument != NULL) { 412 sound = (u8) usedSemitone < instrument->normalRangeLo ? &instrument->lowNotesSound 413 : (u8) usedSemitone <= instrument->normalRangeHi ? 414 &instrument->normalNotesSound : &instrument->highNotesSound; 415 416 sameSound = (sound == (*layer).sound); 417 layer->sound = sound; 418 tuning = (*sound).tuning; 419 } else { 420 layer->sound = NULL; 421 tuning = 1.0f; 422 } 423 424 temp_f2 = gNoteFrequencies[cmdSemitone] * tuning; 425 temp_f12 = gNoteFrequencies[layer->portamentoTargetNote] * tuning; 426 427 portamento = &layer->portamento; 428 switch (PORTAMENTO_MODE(layer->portamento)) { 429 case PORTAMENTO_MODE_1: 430 case PORTAMENTO_MODE_3: 431 case PORTAMENTO_MODE_5: 432 sp24 = temp_f2; 433 freqScale = temp_f12; 434 goto l13cc; 435 436 case PORTAMENTO_MODE_2: 437 case PORTAMENTO_MODE_4: 438 freqScale = temp_f2; 439 sp24 = temp_f12; 440 goto l13cc; 441 } 442 l13cc: 443 portamento->extent = sp24 / freqScale - US_FLOAT(1.0); 444 if (PORTAMENTO_IS_SPECIAL((*layer).portamento)) { 445 portamento->speed = US_FLOAT(32512.0) * FLOAT_CAST((*seqPlayer).tempo) 446 / ((f32)(*layer).delay * (f32) gTempoInternalToExternal 447 * FLOAT_CAST((*layer).portamentoTime)); 448 } else { 449 portamento->speed = US_FLOAT(127.0) / FLOAT_CAST((*layer).portamentoTime); 450 } 451 portamento->cur = 0.0f; 452 layer->freqScale = freqScale; 453 if (PORTAMENTO_MODE((*layer).portamento) == PORTAMENTO_MODE_5) { 454 layer->portamentoTargetNote = cmdSemitone; 455 } 456 } else if (instrument != NULL) { 457 sound = cmdSemitone < instrument->normalRangeLo ? 458 &instrument->lowNotesSound : cmdSemitone <= instrument->normalRangeHi ? 459 &instrument->normalNotesSound : &instrument->highNotesSound; 460 461 sameSound = (sound == (*layer).sound); 462 layer->sound = sound; 463 layer->freqScale = gNoteFrequencies[cmdSemitone] * (*sound).tuning; 464 } else { 465 layer->sound = NULL; 466 layer->freqScale = gNoteFrequencies[cmdSemitone]; 467 } 468 } 469 } 470 layer->delayUnused = layer->delay; 471 } 472 } 473 474 if (layer->stopSomething == TRUE) { 475 if (layer->note != NULL || layer->continuousNotes) { 476 seq_channel_layer_note_decay(layer); 477 } 478 return; 479 } 480 481 cmdSemitone = FALSE; 482 if (!layer->continuousNotes) { 483 cmdSemitone = TRUE; 484 } else if (layer->note == NULL || layer->status == SOUND_LOAD_STATUS_NOT_LOADED) { 485 cmdSemitone = TRUE; 486 } else if (sameSound == FALSE) { 487 seq_channel_layer_note_decay(layer); 488 cmdSemitone = TRUE; 489 } else if (layer->sound == NULL) { 490 init_synthetic_wave(layer->note, layer); 491 } 492 493 if (cmdSemitone != FALSE) { 494 (*layer).note = alloc_note(layer); 495 } 496 497 if (layer->note != NULL && layer->note->parentLayer == layer) { 498 note_vibrato_init(layer->note); 499 } 500 }