load.c (35650B)
1 #if !defined(VERSION_SH) && !defined(VERSION_CN) 2 #include <ultra64.h> 3 #include <PR/os.h> 4 5 #include "data.h" 6 #include "external.h" 7 #include "heap.h" 8 #include "load.h" 9 #include "seqplayer.h" 10 11 #define ALIGN16(val) (((val) + 0xF) & ~0xF) 12 13 struct SharedDma { 14 /*0x0*/ u8 *buffer; // target, points to pre-allocated buffer 15 /*0x4*/ uintptr_t source; // device address 16 /*0x8*/ u16 sizeUnused; // set to bufSize, never read 17 /*0xA*/ u16 bufSize; // size of buffer 18 /*0xC*/ u8 unused2; // set to 0, never read 19 /*0xD*/ u8 reuseIndex; // position in sSampleDmaReuseQueue1/2, if ttl == 0 20 /*0xE*/ u8 ttl; // duration after which the DMA can be discarded 21 }; // size = 0x10 22 23 // EU only 24 void port_eu_init(void); 25 26 struct Note *gNotes; 27 28 #if defined(VERSION_EU) 29 UNUSED static u8 pad[4]; 30 #endif 31 32 struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS]; 33 struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS]; 34 struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS]; 35 36 struct SequenceChannel gSequenceChannelNone; 37 struct AudioListItem gLayerFreeList; 38 struct NotePool gNoteFreeLists; 39 40 OSMesgQueue gCurrAudioFrameDmaQueue; 41 OSMesg gCurrAudioFrameDmaMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE]; 42 OSIoMesg gCurrAudioFrameDmaIoMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE]; 43 44 OSMesgQueue gAudioDmaMesgQueue; 45 OSMesg gAudioDmaMesg; 46 OSIoMesg gAudioDmaIoMesg; 47 48 struct SharedDma sSampleDmas[0x60]; 49 u32 gSampleDmaNumListItems; // sh: 0x803503D4 50 u32 sSampleDmaListSize1; // sh: 0x803503D8 51 u32 sUnused80226B40; // set to 0, never read, sh: 0x803503DC 52 53 // Circular buffer of DMAs with ttl = 0. tail <= head, wrapping around mod 256. 54 u8 sSampleDmaReuseQueue1[256]; 55 u8 sSampleDmaReuseQueue2[256]; 56 u8 sSampleDmaReuseQueueTail1; 57 u8 sSampleDmaReuseQueueTail2; 58 u8 sSampleDmaReuseQueueHead1; // sh: 0x803505E2 59 u8 sSampleDmaReuseQueueHead2; // sh: 0x803505E3 60 61 // bss correct up to here 62 63 ALSeqFile *gSeqFileHeader; 64 ALSeqFile *gAlCtlHeader; 65 ALSeqFile *gAlTbl; 66 u8 *gAlBankSets; 67 u16 gSequenceCount; 68 69 struct CtlEntry *gCtlEntries; // sh: 0x803505F8 70 71 #if defined(VERSION_EU) 72 u32 padEuBss1; 73 struct AudioBufferParametersEU gAudioBufferParameters; 74 #else 75 s32 gAiFrequency; 76 #endif 77 78 u32 sDmaBufSize; 79 s32 gMaxAudioCmds; 80 s32 gMaxSimultaneousNotes; 81 82 #if defined(VERSION_EU) 83 s16 gTempoInternalToExternal; 84 #else 85 s32 gSamplesPerFrameTarget; 86 s32 gMinAiBufferLength; 87 88 s16 gTempoInternalToExternal; 89 90 s8 gAudioUpdatesPerFrame; 91 #endif 92 93 s8 gSoundMode; 94 95 #if defined(VERSION_EU) 96 s8 gAudioUpdatesPerFrame; 97 #endif 98 99 extern u64 gAudioGlobalsStartMarker; 100 extern u64 gAudioGlobalsEndMarker; 101 102 extern u8 gSoundDataADSR[]; // sound_data.ctl 103 extern u8 gSoundDataRaw[]; // sound_data.tbl 104 extern u8 gMusicData[]; // sequences.s 105 extern u8 gBankSetsData[]; // bank_sets.s 106 107 ALSeqFile *get_audio_file_header(s32 arg0); 108 109 /** 110 * Performs an immediate DMA copy 111 */ 112 void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) { 113 eu_stubbed_printf_3("Romcopy %x -> %x ,size %x\n", devAddr, vAddr, nbytes); 114 osInvalDCache(vAddr, nbytes); 115 osPiStartDma(&gAudioDmaIoMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, vAddr, nbytes, 116 &gAudioDmaMesgQueue); 117 osRecvMesg(&gAudioDmaMesgQueue, NULL, OS_MESG_BLOCK); 118 eu_stubbed_printf_0("Romcopyend\n"); 119 } 120 121 #ifdef VERSION_EU 122 u8 audioString34[] = "CAUTION:WAVE CACHE FULL %d"; 123 u8 audioString35[] = "BASE %x %x\n"; 124 u8 audioString36[] = "LOAD %x %x %x\n"; 125 u8 audioString37[] = "INSTTOP %x\n"; 126 u8 audioString38[] = "INSTMAP[0] %x\n"; 127 u8 audioString39[] = "already flags %d\n"; 128 u8 audioString40[] = "already flags %d\n"; 129 u8 audioString41[] = "ERR:SLOW BANK DMA BUSY\n"; 130 u8 audioString42[] = "ERR:SLOW DMA BUSY\n"; 131 u8 audioString43[] = "Check %d bank %d\n"; 132 u8 audioString44[] = "Cache Check\n"; 133 u8 audioString45[] = "NO BANK ERROR\n"; 134 u8 audioString46[] = "BANK %d LOADING START\n"; 135 u8 audioString47[] = "BANK %d LOAD MISS (NO MEMORY)!\n"; 136 u8 audioString48[] = "BANK %d ALREADY CACHED\n"; 137 u8 audioString49[] = "BANK LOAD MISS! FOR %d\n"; 138 #endif 139 140 /** 141 * Performs an asynchronus (normal priority) DMA copy 142 */ 143 void audio_dma_copy_async(uintptr_t devAddr, void *vAddr, size_t nbytes, OSMesgQueue *queue, OSIoMesg *mesg) { 144 osInvalDCache(vAddr, nbytes); 145 osPiStartDma(mesg, OS_MESG_PRI_NORMAL, OS_READ, devAddr, vAddr, nbytes, queue); 146 } 147 148 /** 149 * Performs a partial asynchronous (normal priority) DMA copy. This is limited 150 * to 0x1000 bytes transfer at once. 151 */ 152 void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg) { 153 #if defined(VERSION_EU) 154 ssize_t transfer = (*remaining >= 0x1000 ? 0x1000 : *remaining); 155 #else 156 ssize_t transfer = (*remaining < 0x1000 ? *remaining : 0x1000); 157 #endif 158 *remaining -= transfer; 159 osInvalDCache(*vAddr, transfer); 160 osPiStartDma(mesg, OS_MESG_PRI_NORMAL, OS_READ, *devAddr, *vAddr, transfer, queue); 161 *devAddr += transfer; 162 *vAddr += transfer; 163 } 164 165 void decrease_sample_dma_ttls() { 166 u32 i; 167 168 for (i = 0; i < sSampleDmaListSize1; i++) { 169 #if defined(VERSION_EU) 170 struct SharedDma *temp = &sSampleDmas[i]; 171 #else 172 struct SharedDma *temp = sSampleDmas + i; 173 #endif 174 if (temp->ttl != 0) { 175 temp->ttl--; 176 if (temp->ttl == 0) { 177 temp->reuseIndex = sSampleDmaReuseQueueHead1; 178 sSampleDmaReuseQueue1[sSampleDmaReuseQueueHead1++] = (u8) i; 179 } 180 } 181 } 182 183 for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { 184 #if defined(VERSION_EU) 185 struct SharedDma *temp = &sSampleDmas[i]; 186 #else 187 struct SharedDma *temp = sSampleDmas + i; 188 #endif 189 if (temp->ttl != 0) { 190 temp->ttl--; 191 if (temp->ttl == 0) { 192 temp->reuseIndex = sSampleDmaReuseQueueHead2; 193 sSampleDmaReuseQueue2[sSampleDmaReuseQueueHead2++] = (u8) i; 194 } 195 } 196 } 197 198 sUnused80226B40 = 0; 199 } 200 201 void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) { 202 s32 hasDma = FALSE; 203 struct SharedDma *dma; 204 uintptr_t dmaDevAddr; 205 u32 transfer; 206 u32 i; 207 u32 dmaIndex; 208 ssize_t bufferPos; 209 UNUSED u32 pad; 210 211 if (arg2 != 0 || *dmaIndexRef >= sSampleDmaListSize1) { 212 for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) { 213 #if defined(VERSION_EU) 214 dma = &sSampleDmas[i]; 215 #else 216 dma = sSampleDmas + i; 217 #endif 218 bufferPos = devAddr - dma->source; 219 if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) { 220 // We already have a DMA request for this memory range. 221 if (dma->ttl == 0 && sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2) { 222 // Move the DMA out of the reuse queue, by swapping it with the 223 // tail, and then incrementing the tail. 224 if (dma->reuseIndex != sSampleDmaReuseQueueTail2) { 225 sSampleDmaReuseQueue2[dma->reuseIndex] = 226 sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]; 227 sSampleDmas[sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]].reuseIndex = 228 dma->reuseIndex; 229 } 230 sSampleDmaReuseQueueTail2++; 231 } 232 dma->ttl = 60; 233 *dmaIndexRef = (u8) i; 234 #if defined(VERSION_EU) 235 return &dma->buffer[(devAddr - dma->source)]; 236 #else 237 return (devAddr - dma->source) + dma->buffer; 238 #endif 239 } 240 } 241 242 if (sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2 && arg2 != 0) { 243 // Allocate a DMA from reuse queue 2. This queue can be empty, since 244 // TTL 60 is pretty large. 245 dmaIndex = sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]; 246 sSampleDmaReuseQueueTail2++; 247 dma = sSampleDmas + dmaIndex; 248 hasDma = TRUE; 249 } 250 } else { 251 #if defined(VERSION_EU) 252 dma = sSampleDmas; 253 dma += *dmaIndexRef; 254 #else 255 dma = sSampleDmas + *dmaIndexRef; 256 #endif 257 bufferPos = devAddr - dma->source; 258 if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) { 259 // We already have DMA for this memory range. 260 if (dma->ttl == 0) { 261 // Move the DMA out of the reuse queue, by swapping it with the 262 // tail, and then incrementing the tail. 263 if (dma->reuseIndex != sSampleDmaReuseQueueTail1) { 264 #if defined(VERSION_EU) 265 if (1) { 266 } 267 #endif 268 sSampleDmaReuseQueue1[dma->reuseIndex] = 269 sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]; 270 sSampleDmas[sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]].reuseIndex = 271 dma->reuseIndex; 272 } 273 sSampleDmaReuseQueueTail1++; 274 } 275 dma->ttl = 2; 276 #if defined(VERSION_EU) 277 return dma->buffer + (devAddr - dma->source); 278 #else 279 return (devAddr - dma->source) + dma->buffer; 280 #endif 281 } 282 } 283 284 if (!hasDma) { 285 // Allocate a DMA from reuse queue 1. This queue will hopefully never 286 // be empty, since TTL 2 is so small. 287 dmaIndex = sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1++]; 288 dma = sSampleDmas + dmaIndex; 289 hasDma = TRUE; 290 } 291 292 transfer = dma->bufSize; 293 dmaDevAddr = devAddr & ~0xF; 294 dma->ttl = 2; 295 dma->source = dmaDevAddr; 296 dma->sizeUnused = transfer; 297 #ifdef VERSION_US 298 osInvalDCache(dma->buffer, transfer); 299 #endif 300 #if defined(VERSION_EU) 301 osPiStartDma(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, 302 OS_READ, dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue); 303 *dmaIndexRef = dmaIndex; 304 return (devAddr - dmaDevAddr) + dma->buffer; 305 #else 306 gCurrAudioFrameDmaCount++; 307 osPiStartDma(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount - 1], OS_MESG_PRI_NORMAL, 308 OS_READ, dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue); 309 *dmaIndexRef = dmaIndex; 310 return dma->buffer + (devAddr - dmaDevAddr); 311 #endif 312 } 313 314 315 void init_sample_dma_buffers(UNUSED s32 arg0) { 316 s32 i; 317 #if defined(VERSION_EU) 318 #define j i 319 #else 320 s32 j; 321 #endif 322 323 #if defined(VERSION_EU) 324 sDmaBufSize = 0x400; 325 #else 326 sDmaBufSize = 144 * 9; 327 #endif 328 329 #if defined(VERSION_EU) 330 for (i = 0; i < gMaxSimultaneousNotes * 3 * gAudioBufferParameters.presetUnk4; i++) 331 #else 332 for (i = 0; i < gMaxSimultaneousNotes * 3; i++) 333 #endif 334 { 335 sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize); 336 if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) { 337 #if defined(VERSION_EU) 338 break; 339 #else 340 goto out1; 341 #endif 342 } 343 sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; 344 sSampleDmas[gSampleDmaNumListItems].source = 0; 345 sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0; 346 sSampleDmas[gSampleDmaNumListItems].unused2 = 0; 347 sSampleDmas[gSampleDmaNumListItems].ttl = 0; 348 gSampleDmaNumListItems++; 349 } 350 #if defined(VERSION_JP) || defined(VERSION_US) 351 out1: 352 #endif 353 354 for (i = 0; (u32) i < gSampleDmaNumListItems; i++) { 355 sSampleDmaReuseQueue1[i] = (u8) i; 356 sSampleDmas[i].reuseIndex = (u8) i; 357 } 358 359 for (j = gSampleDmaNumListItems; j < 0x100; j++) { 360 sSampleDmaReuseQueue1[j] = 0; 361 } 362 363 sSampleDmaReuseQueueTail1 = 0; 364 sSampleDmaReuseQueueHead1 = (u8) gSampleDmaNumListItems; 365 sSampleDmaListSize1 = gSampleDmaNumListItems; 366 367 #if defined(VERSION_EU) 368 sDmaBufSize = 0x200; 369 #else 370 sDmaBufSize = 160 * 9; 371 #endif 372 for (i = 0; i < gMaxSimultaneousNotes; i++) { 373 sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize); 374 if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) { 375 #if defined(VERSION_EU) 376 break; 377 #else 378 goto out2; 379 #endif 380 } 381 sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize; 382 sSampleDmas[gSampleDmaNumListItems].source = 0; 383 sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0; 384 sSampleDmas[gSampleDmaNumListItems].unused2 = 0; 385 sSampleDmas[gSampleDmaNumListItems].ttl = 0; 386 gSampleDmaNumListItems++; 387 } 388 #if defined(VERSION_JP) || defined(VERSION_US) 389 out2: 390 #endif 391 392 for (i = sSampleDmaListSize1; (u32) i < gSampleDmaNumListItems; i++) { 393 sSampleDmaReuseQueue2[i - sSampleDmaListSize1] = (u8) i; 394 sSampleDmas[i].reuseIndex = (u8)(i - sSampleDmaListSize1); 395 } 396 397 // This probably meant to touch the range size1..size2 as well... but it 398 // doesn't matter, since these values are never read anyway. 399 for (j = gSampleDmaNumListItems; j < 0x100; j++) { 400 sSampleDmaReuseQueue2[j] = sSampleDmaListSize1; 401 } 402 403 sSampleDmaReuseQueueTail2 = 0; 404 sSampleDmaReuseQueueHead2 = gSampleDmaNumListItems - sSampleDmaListSize1; 405 #if defined(VERSION_EU) 406 #undef j 407 #endif 408 } 409 410 #if defined(VERSION_JP) || defined(VERSION_US) 411 // This function gets optimized out on US due to being static and never called 412 UNUSED static 413 #endif 414 void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED u8 *offsetBase) { 415 struct AudioBankSample *sample; 416 void *patched; 417 UNUSED u8 *mem; // unused on US 418 419 #define PATCH(x, base) (patched = (void *)((uintptr_t) (x) + (uintptr_t) base)) 420 421 if (sound->sample != NULL) { 422 sample = sound->sample = PATCH(sound->sample, memBase); 423 if (sample->loaded == 0) { 424 sample->sampleAddr = PATCH(sample->sampleAddr, offsetBase); 425 sample->loop = PATCH(sample->loop, memBase); 426 sample->book = PATCH(sample->book, memBase); 427 sample->loaded = 1; 428 } 429 #if defined(VERSION_EU) 430 else if (sample->loaded == 0x80) { 431 PATCH(sample->sampleAddr, offsetBase); 432 mem = soundAlloc(&gNotesAndBuffersPool, sample->sampleSize); 433 if (mem == NULL) { 434 sample->sampleAddr = patched; 435 sample->loaded = 1; 436 } else { 437 audio_dma_copy_immediate((uintptr_t) patched, mem, sample->sampleSize); 438 sample->loaded = 0x81; 439 sample->sampleAddr = mem; 440 } 441 sample->loop = PATCH(sample->loop, memBase); 442 sample->book = PATCH(sample->book, memBase); 443 } 444 #endif 445 } 446 447 #undef PATCH 448 } 449 450 #ifdef VERSION_EU 451 #define PATCH_SOUND patch_sound 452 #else 453 // copt inline of the above 454 #define PATCH_SOUND(_sound, mem, offset) \ 455 { \ 456 struct AudioBankSound *sound = _sound; \ 457 struct AudioBankSample *sample; \ 458 void *patched; \ 459 if ((*sound).sample != (void *) 0) \ 460 { \ 461 patched = (void *)(((uintptr_t)(*sound).sample) + ((uintptr_t)((u8 *) mem))); \ 462 (*sound).sample = patched; \ 463 sample = (*sound).sample; \ 464 if ((*sample).loaded == 0) \ 465 { \ 466 patched = (void *)(((uintptr_t)(*sample).sampleAddr) + ((uintptr_t) offset)); \ 467 (*sample).sampleAddr = patched; \ 468 patched = (void *)(((uintptr_t)(*sample).loop) + ((uintptr_t)((u8 *) mem))); \ 469 (*sample).loop = patched; \ 470 patched = (void *)(((uintptr_t)(*sample).book) + ((uintptr_t)((u8 *) mem))); \ 471 (*sample).book = patched; \ 472 (*sample).loaded = 1; \ 473 } \ 474 } \ 475 } 476 #endif 477 478 // on US/JP this inlines patch_sound, using some -sopt compiler flag 479 void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums) { 480 struct Instrument *instrument; 481 struct Instrument **itInstrs; 482 struct Instrument **end; 483 struct AudioBank *temp; 484 u32 i; 485 void *patched; 486 struct Drum *drum; 487 struct Drum **drums; 488 #if defined(VERSION_EU) 489 u32 numDrums2; 490 #endif 491 492 #define BASE_OFFSET_REAL(x, base) (void *)((uintptr_t) (x) + (uintptr_t) base) 493 #define PATCH(x, base) (patched = BASE_OFFSET_REAL(x, base)) 494 #define PATCH_MEM(x) x = PATCH(x, mem) 495 496 #if defined(VERSION_JP) || defined(VERSION_US) 497 #define BASE_OFFSET(x, base) BASE_OFFSET_REAL(x, base) 498 #else 499 #define BASE_OFFSET(x, base) BASE_OFFSET_REAL(base, x) 500 #endif 501 502 drums = mem->drums; 503 #if defined(VERSION_JP) || defined(VERSION_US) 504 if (drums != NULL && numDrums > 0) { 505 mem->drums = (void *)((uintptr_t) drums + (uintptr_t) mem); 506 if (numDrums > 0) //! unneeded when -sopt is enabled 507 for (i = 0; i < numDrums; i++) { 508 #else 509 numDrums2 = numDrums; 510 if (drums != NULL && numDrums2 > 0) { 511 mem->drums = PATCH(drums, mem); 512 for (i = 0; i < numDrums2; i++) { 513 #endif 514 patched = mem->drums[i]; 515 if (patched != NULL) { 516 drum = PATCH(patched, mem); 517 mem->drums[i] = drum; 518 if (drum->loaded == 0) { 519 #if defined(VERSION_JP) || defined(VERSION_US) 520 //! copt replaces drum with 'patched' for these two lines 521 PATCH_SOUND(&(*(struct Drum *)patched).sound, mem, offset); 522 patched = (*(struct Drum *)patched).envelope; 523 #else 524 patch_sound(&drum->sound, (u8 *) mem, offset); 525 patched = drum->envelope; 526 #endif 527 drum->envelope = BASE_OFFSET(mem, patched); 528 drum->loaded = 1; 529 } 530 531 } 532 } 533 } 534 535 //! Doesn't affect EU, but required for US/JP 536 temp = &*mem; 537 #if defined(VERSION_JP) || defined(VERSION_US) 538 if (numInstruments >= 1) 539 #endif 540 if (numInstruments > 0) { 541 //! Doesn't affect EU, but required for US/JP 542 struct Instrument **tempInst; 543 itInstrs = temp->instruments; 544 tempInst = temp->instruments; 545 end = numInstruments + tempInst; 546 547 #if defined(VERSION_JP) || defined(VERSION_US) 548 l2: 549 #else 550 do { 551 #endif 552 if (*itInstrs != NULL) { 553 *itInstrs = BASE_OFFSET(*itInstrs, mem); 554 instrument = *itInstrs; 555 556 if (instrument->loaded == 0) { 557 PATCH_SOUND(&instrument->lowNotesSound, (u8 *) mem, offset); 558 PATCH_SOUND(&instrument->normalNotesSound, (u8 *) mem, offset); 559 PATCH_SOUND(&instrument->highNotesSound, (u8 *) mem, offset); 560 patched = instrument->envelope; 561 instrument->envelope = BASE_OFFSET(mem, patched); 562 instrument->loaded = 1; 563 } 564 } 565 itInstrs++; 566 #if defined(VERSION_JP) || defined(VERSION_US) 567 //! goto generated by copt, required to match US/JP 568 if (end != itInstrs) { 569 goto l2; 570 } 571 #else 572 } while (end != itInstrs); 573 #endif 574 } 575 #undef PATCH_MEM 576 #undef PATCH 577 #undef BASE_OFFSET_REAL 578 #undef BASE_OFFSET 579 #undef PATCH_SOUND 580 } 581 582 struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1) { 583 UNUSED u32 pad1[4]; 584 u32 buf[4]; 585 u32 numInstruments, numDrums; 586 struct AudioBank *ret; 587 u8 *ctlData; 588 s32 alloc; 589 590 // (This is broken if the length is 1 (mod 16), but that never happens -- 591 // it's always divisible by 4.) 592 alloc = gAlCtlHeader->seqArray[bankId].len + 0xf; 593 alloc = ALIGN16(alloc); 594 alloc -= 0x10; 595 ctlData = gAlCtlHeader->seqArray[bankId].offset; 596 ret = alloc_bank_or_seq(&gBankLoadedPool, 1, alloc, arg1, bankId); 597 if (ret == NULL) { 598 return NULL; 599 } 600 601 audio_dma_copy_immediate((uintptr_t) ctlData, buf, 0x10); 602 numInstruments = buf[0]; 603 numDrums = buf[1]; 604 audio_dma_copy_immediate((uintptr_t)(ctlData + 0x10), ret, alloc); 605 patch_audio_bank(ret, gAlTbl->seqArray[bankId].offset, numInstruments, numDrums); 606 gCtlEntries[bankId].numInstruments = (u8) numInstruments; 607 gCtlEntries[bankId].numDrums = (u8) numDrums; 608 gCtlEntries[bankId].instruments = ret->instruments; 609 gCtlEntries[bankId].drums = ret->drums; 610 gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_COMPLETE; 611 return ret; 612 } 613 614 struct AudioBank *bank_load_async(s32 bankId, s32 arg1, struct SequencePlayer *seqPlayer) { 615 u32 numInstruments, numDrums; 616 UNUSED u32 pad1[2]; 617 u32 buf[4]; 618 UNUSED u32 pad2; 619 size_t alloc; 620 struct AudioBank *ret; 621 u8 *ctlData; 622 OSMesgQueue *mesgQueue; 623 #if defined(VERSION_EU) 624 UNUSED u32 pad3; 625 #endif 626 627 alloc = gAlCtlHeader->seqArray[bankId].len + 0xf; 628 alloc = ALIGN16(alloc); 629 alloc -= 0x10; 630 ctlData = gAlCtlHeader->seqArray[bankId].offset; 631 ret = alloc_bank_or_seq(&gBankLoadedPool, 1, alloc, arg1, bankId); 632 if (ret == NULL) { 633 return NULL; 634 } 635 636 audio_dma_copy_immediate((uintptr_t) ctlData, buf, 0x10); 637 numInstruments = buf[0]; 638 numDrums = buf[1]; 639 seqPlayer->loadingBankId = (u8) bankId; 640 #if defined(VERSION_EU) 641 gCtlEntries[bankId].numInstruments = numInstruments; 642 gCtlEntries[bankId].numDrums = numDrums; 643 gCtlEntries[bankId].instruments = ret->instruments; 644 gCtlEntries[bankId].drums = 0; 645 seqPlayer->bankDmaCurrMemAddr = (u8 *) ret; 646 seqPlayer->bankDmaCurrDevAddr = (uintptr_t)(ctlData + 0x10); 647 seqPlayer->bankDmaRemaining = alloc; 648 if (1) { 649 } 650 #else 651 seqPlayer->loadingBankNumInstruments = numInstruments; 652 seqPlayer->loadingBankNumDrums = numDrums; 653 seqPlayer->bankDmaCurrMemAddr = (u8 *) ret; 654 seqPlayer->loadingBank = ret; 655 seqPlayer->bankDmaCurrDevAddr = (uintptr_t)(ctlData + 0x10); 656 seqPlayer->bankDmaRemaining = alloc; 657 #endif 658 mesgQueue = &seqPlayer->bankDmaMesgQueue; 659 osCreateMesgQueue(mesgQueue, &seqPlayer->bankDmaMesg, 1); 660 #if defined(VERSION_JP) || defined(VERSION_US) 661 seqPlayer->bankDmaMesg = NULL; 662 #endif 663 seqPlayer->bankDmaInProgress = TRUE; 664 audio_dma_partial_copy_async(&seqPlayer->bankDmaCurrDevAddr, &seqPlayer->bankDmaCurrMemAddr, 665 &seqPlayer->bankDmaRemaining, mesgQueue, &seqPlayer->bankDmaIoMesg); 666 gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_IN_PROGRESS; 667 return ret; 668 } 669 670 void *sequence_dma_immediate(s32 seqId, s32 arg1) { 671 s32 seqLength; 672 void *ptr; 673 u8 *seqData; 674 675 seqLength = gSeqFileHeader->seqArray[seqId].len + 0xf; 676 seqLength = ALIGN16(seqLength); 677 seqData = gSeqFileHeader->seqArray[seqId].offset; 678 ptr = alloc_bank_or_seq(&gSeqLoadedPool, 1, seqLength, arg1, seqId); 679 if (ptr == NULL) { 680 return NULL; 681 } 682 683 audio_dma_copy_immediate((uintptr_t) seqData, ptr, seqLength); 684 gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE; 685 return ptr; 686 } 687 688 void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer) { 689 s32 seqLength; 690 void *ptr; 691 u8 *seqData; 692 OSMesgQueue *mesgQueue; 693 694 eu_stubbed_printf_1("Seq %d Loading Start\n", seqId); 695 seqLength = gSeqFileHeader->seqArray[seqId].len + 0xf; 696 seqLength = ALIGN16(seqLength); 697 seqData = gSeqFileHeader->seqArray[seqId].offset; 698 ptr = alloc_bank_or_seq(&gSeqLoadedPool, 1, seqLength, arg1, seqId); 699 if (ptr == NULL) { 700 eu_stubbed_printf_0("Heap Overflow Error\n"); 701 return NULL; 702 } 703 704 if (seqLength <= 0x40) { 705 // Immediately load short sequenece 706 audio_dma_copy_immediate((uintptr_t) seqData, ptr, seqLength); 707 if (1) { 708 } 709 gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE; 710 } else { 711 audio_dma_copy_immediate((uintptr_t) seqData, ptr, 0x40); 712 mesgQueue = &seqPlayer->seqDmaMesgQueue; 713 osCreateMesgQueue(mesgQueue, &seqPlayer->seqDmaMesg, 1); 714 #if defined(VERSION_JP) || defined(VERSION_US) 715 seqPlayer->seqDmaMesg = NULL; 716 #endif 717 seqPlayer->seqDmaInProgress = TRUE; 718 audio_dma_copy_async((uintptr_t)(seqData + 0x40), (u8 *) ptr + 0x40, seqLength - 0x40, mesgQueue, 719 &seqPlayer->seqDmaIoMesg); 720 gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_IN_PROGRESS; 721 } 722 return ptr; 723 } 724 725 u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) { 726 void *temp; 727 u32 bankId; 728 u16 offset; 729 u8 i; 730 u8 ret; 731 732 *nullCount = 0; 733 *nonNullCount = 0; 734 #if defined(VERSION_EU) 735 offset = ((u16 *) gAlBankSets)[seqId]; 736 for (i = gAlBankSets[offset++], ret = 0; i != 0; i--) { 737 bankId = gAlBankSets[offset++]; 738 #else 739 offset = ((u16 *) gAlBankSets)[seqId] + 1; 740 for (i = gAlBankSets[offset - 1], ret = 0; i != 0; i--) { 741 offset++; 742 bankId = gAlBankSets[offset - 1]; 743 #endif 744 745 if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { 746 #if defined(VERSION_EU) 747 temp = get_bank_or_seq(&gBankLoadedPool, 2, bankId); 748 #else 749 temp = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]); 750 #endif 751 } else { 752 temp = NULL; 753 } 754 755 if (temp == NULL) { 756 (*nullCount)++; 757 ret = bankId; 758 } else { 759 (*nonNullCount)++; 760 } 761 } 762 763 return ret; 764 } 765 766 struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) { 767 void *ret; 768 u32 bankId; 769 u16 offset; 770 u8 i; 771 772 offset = ((u16 *) gAlBankSets)[seqId]; 773 #ifdef VERSION_EU 774 for (i = gAlBankSets[offset++]; i != 0; i--) { 775 bankId = gAlBankSets[offset++]; 776 #else 777 offset++; 778 for (i = gAlBankSets[offset - 1]; i != 0; i--) { 779 offset++; 780 bankId = gAlBankSets[offset - 1]; 781 #endif 782 783 if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { 784 #ifdef VERSION_EU 785 ret = get_bank_or_seq(&gBankLoadedPool, 2, bankId); 786 #else 787 ret = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]); 788 #endif 789 } else { 790 ret = NULL; 791 } 792 793 if (ret == NULL) { 794 ret = bank_load_immediate(bankId, 2); 795 } 796 } 797 *outDefaultBank = bankId; 798 return ret; 799 } 800 801 void preload_sequence(u32 seqId, u8 preloadMask) { 802 void *sequenceData; 803 u8 temp; 804 805 if (seqId >= gSequenceCount) { 806 return; 807 } 808 809 gAudioLoadLock = AUDIO_LOCK_LOADING; 810 if (preloadMask & PRELOAD_BANKS) { 811 load_banks_immediate(seqId, &temp); 812 } 813 814 if (preloadMask & PRELOAD_SEQUENCE) { 815 // @bug should be IS_SEQ_LOAD_COMPLETE 816 if (IS_BANK_LOAD_COMPLETE(seqId) == TRUE) { 817 eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId); 818 sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId); 819 } else { 820 sequenceData = NULL; 821 } 822 if (sequenceData == NULL && sequence_dma_immediate(seqId, 2) == NULL) { 823 gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; 824 return; 825 } 826 } 827 828 gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; 829 } 830 831 void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync); 832 833 void load_sequence(u32 player, u32 seqId, s32 loadAsync) { 834 if (!loadAsync) { 835 gAudioLoadLock = AUDIO_LOCK_LOADING; 836 } 837 load_sequence_internal(player, seqId, loadAsync); 838 if (!loadAsync) { 839 gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; 840 } 841 } 842 843 void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) { 844 void *sequenceData; 845 struct SequencePlayer *seqPlayer = &gSequencePlayers[player]; 846 UNUSED u32 padding[2]; 847 848 if (seqId >= gSequenceCount) { 849 return; 850 } 851 852 sequence_player_disable(seqPlayer); 853 if (loadAsync) { 854 s32 numMissingBanks = 0; 855 s32 dummy = 0; 856 s32 bankId = get_missing_bank(seqId, &dummy, &numMissingBanks); 857 if (numMissingBanks == 1) { 858 eu_stubbed_printf_0("Ok,one bank slow load Start \n"); 859 if (bank_load_async(bankId, 2, seqPlayer) == NULL) { 860 return; 861 } 862 // @bug This should set the last bank (i.e. the first in the JSON) 863 // as default, not the missing one. This code path never gets 864 // taken, though -- all sequence loading is synchronous. 865 seqPlayer->defaultBank[0] = bankId; 866 } else { 867 eu_stubbed_printf_1("Sorry,too many %d bank is none.fast load Start \n", numMissingBanks); 868 if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) { 869 return; 870 } 871 } 872 } else if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) { 873 return; 874 } 875 876 eu_stubbed_printf_2("Seq %d:Default Load Id is %d\n", seqId, seqPlayer->defaultBank[0]); 877 eu_stubbed_printf_0("Seq Loading Start\n"); 878 879 seqPlayer->seqId = seqId; 880 sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId); 881 if (sequenceData == NULL) { 882 if (seqPlayer->seqDmaInProgress) { 883 eu_stubbed_printf_0("Error:Before Sequence-SlowDma remain.\n"); 884 eu_stubbed_printf_0(" Cancel Seq Start.\n"); 885 return; 886 } 887 if (loadAsync) { 888 sequenceData = sequence_dma_async(seqId, 2, seqPlayer); 889 } else { 890 sequenceData = sequence_dma_immediate(seqId, 2); 891 } 892 893 if (sequenceData == NULL) { 894 return; 895 } 896 } 897 898 eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId); 899 init_sequence_player(player); 900 seqPlayer->scriptState.depth = 0; 901 seqPlayer->delay = 0; 902 seqPlayer->enabled = TRUE; 903 seqPlayer->seqData = sequenceData; 904 seqPlayer->scriptState.pc = sequenceData; 905 } 906 907 // (void) must be omitted from parameters to fix stack with -framepointer 908 void audio_init() { 909 #if defined(VERSION_EU) 910 UNUSED s8 pad[16]; 911 #else 912 UNUSED s8 pad[32]; 913 #endif 914 #if defined(VERSION_JP) || defined(VERSION_US) 915 u8 buf[0x10]; 916 #endif 917 s32 i, j, k; 918 UNUSED s32 lim1; // lim1 unused in EU 919 #if defined(VERSION_EU) 920 UNUSED u8 buf[0x10]; 921 s32 UNUSED lim2, lim3; 922 #else 923 s32 lim2, lim3; 924 #endif 925 UNUSED u32 size; 926 UNUSED u64 *ptr64; 927 void *data; 928 UNUSED s32 pad2; 929 930 gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED; 931 932 #if defined(VERSION_JP) || defined(VERSION_US) 933 lim1 = gUnusedCount80333EE8; 934 for (i = 0; i < lim1; i++) { 935 gUnused80226E58[i] = 0; 936 gUnused80226E98[i] = 0; 937 } 938 939 lim2 = gAudioHeapSize; 940 for (i = 0; i <= lim2 / 8 - 1; i++) { 941 ((u64 *) gAudioHeap)[i] = 0; 942 } 943 944 #ifdef TARGET_N64 945 // It seems boot.s doesn't clear the .bss area for audio, so do it here. 946 i = 0; 947 lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8; 948 ptr64 = &gAudioGlobalsStartMarker - 1; 949 for (k = lim3; k >= 0; k--) { 950 i++; 951 ptr64[i] = 0; 952 } 953 #endif 954 955 #else 956 for (i = 0; i < gAudioHeapSize / 8; i++) { 957 ((u64 *) gAudioHeap)[i] = 0; 958 } 959 960 #ifdef TARGET_N64 961 // It seems boot.s doesn't clear the .bss area for audio, so do it here. 962 lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8; 963 ptr64 = &gAudioGlobalsStartMarker; 964 for (k = lim3; k >= 0; k--) { 965 *ptr64++ = 0; 966 } 967 #endif 968 969 D_EU_802298D0 = 20.03042f; 970 gRefreshRate = 50; 971 port_eu_init(); 972 if (k) { 973 } 974 #endif 975 976 #ifdef TARGET_N64 977 eu_stubbed_printf_3( 978 "Clear Workarea %x -%x size %x \n", 979 (uintptr_t) &gAudioGlobalsStartMarker, 980 (uintptr_t) &gAudioGlobalsEndMarker, 981 (uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker 982 ); 983 #endif 984 985 eu_stubbed_printf_1("AudioHeap is %x\n", gAudioHeapSize); 986 987 for (i = 0; i < NUMAIBUFFERS; i++) { 988 gAiBufferLengths[i] = 0xa0; 989 } 990 991 gAudioFrameCount = 0; 992 gAudioTaskIndex = 0; 993 gCurrAiBufferIndex = 0; 994 gSoundMode = 0; 995 gAudioTask = NULL; 996 gAudioTasks[0].task.t.data_size = 0; 997 gAudioTasks[1].task.t.data_size = 0; 998 osCreateMesgQueue(&gAudioDmaMesgQueue, &gAudioDmaMesg, 1); 999 osCreateMesgQueue(&gCurrAudioFrameDmaQueue, gCurrAudioFrameDmaMesgBufs, 1000 ARRAY_COUNT(gCurrAudioFrameDmaMesgBufs)); 1001 gCurrAudioFrameDmaCount = 0; 1002 gSampleDmaNumListItems = 0; 1003 1004 sound_init_main_pools(gAudioInitPoolSize); 1005 1006 for (i = 0; i < NUMAIBUFFERS; i++) { 1007 gAiBuffers[i] = soundAlloc(&gAudioInitPool, AIBUFFER_LEN); 1008 1009 for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) { 1010 gAiBuffers[i][j] = 0; 1011 } 1012 } 1013 1014 #if defined(VERSION_EU) 1015 gAudioResetPresetIdToLoad = 0; 1016 gAudioResetStatus = 1; 1017 audio_shut_down_and_reset_step(); 1018 #else 1019 audio_reset_session(&gAudioSessionPresets[0]); 1020 #endif 1021 1022 // Not sure about these prints 1023 eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0); 1024 eu_stubbed_printf_3("Heap %x %x %x\n", 0, 0, 0); 1025 eu_stubbed_printf_0("Main Heap Initialize.\n"); 1026 1027 // Load headers for sounds and sequences 1028 gSeqFileHeader = (ALSeqFile *) buf; 1029 data = gMusicData; 1030 audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, 0x10); 1031 gSequenceCount = gSeqFileHeader->seqCount; 1032 #if defined(VERSION_EU) 1033 size = gSequenceCount * sizeof(ALSeqData) + 4; 1034 size = ALIGN16(size); 1035 #else 1036 size = ALIGN16(gSequenceCount * sizeof(ALSeqData) + 4); 1037 #endif 1038 gSeqFileHeader = soundAlloc(&gAudioInitPool, size); 1039 audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, size); 1040 alSeqFileNew(gSeqFileHeader, data); 1041 1042 // Load header for CTL (instrument metadata) 1043 gAlCtlHeader = (ALSeqFile *) buf; 1044 data = gSoundDataADSR; 1045 audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, 0x10); 1046 size = gAlCtlHeader->seqCount * sizeof(ALSeqData) + 4; 1047 size = ALIGN16(size); 1048 gCtlEntries = soundAlloc(&gAudioInitPool, gAlCtlHeader->seqCount * sizeof(struct CtlEntry)); 1049 gAlCtlHeader = soundAlloc(&gAudioInitPool, size); 1050 audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, size); 1051 alSeqFileNew(gAlCtlHeader, data); 1052 1053 // Load header for TBL (raw sound data) 1054 gAlTbl = (ALSeqFile *) buf; 1055 audio_dma_copy_immediate((uintptr_t) data, gAlTbl, 0x10); 1056 size = gAlTbl->seqCount * sizeof(ALSeqData) + 4; 1057 size = ALIGN16(size); 1058 gAlTbl = soundAlloc(&gAudioInitPool, size); 1059 audio_dma_copy_immediate((uintptr_t) gSoundDataRaw, gAlTbl, size); 1060 alSeqFileNew(gAlTbl, gSoundDataRaw); 1061 1062 // Load bank sets for each sequence 1063 gAlBankSets = soundAlloc(&gAudioInitPool, 0x100); 1064 audio_dma_copy_immediate((uintptr_t) gBankSetsData, gAlBankSets, 0x100); 1065 1066 init_sequence_players(); 1067 gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; 1068 // Should probably contain the sizes of the data banks, but those aren't 1069 // easily accessible from here. 1070 eu_stubbed_printf_0("---------- Init Completed. ------------\n"); 1071 eu_stubbed_printf_1(" Syndrv :[%6d]\n", 0); // gSoundDataADSR 1072 eu_stubbed_printf_1(" Seqdrv :[%6d]\n", 0); // gMusicData 1073 eu_stubbed_printf_1(" audiodata :[%6d]\n", 0); // gSoundDataRaw 1074 eu_stubbed_printf_0("---------------------------------------\n"); 1075 } 1076 #endif