Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/audio/load_sh.c
7857 views
1
#ifdef VERSION_SH
2
#include <ultra64.h>
3
4
#include "data.h"
5
#include "external.h"
6
#include "heap.h"
7
#include "load.h"
8
#include "seqplayer.h"
9
10
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
11
12
struct SharedDma {
13
/*0x0*/ u8 *buffer; // target, points to pre-allocated buffer
14
/*0x4*/ uintptr_t source; // device address
15
/*0x8*/ u16 sizeUnused; // set to bufSize, never read
16
/*0xA*/ u16 bufSize; // size of buffer
17
/*0xC*/ u8 unused2; // set to 0, never read
18
/*0xD*/ u8 reuseIndex; // position in sSampleDmaReuseQueue1/2, if ttl == 0
19
/*0xE*/ u8 ttl; // duration after which the DMA can be discarded
20
}; // size = 0x10
21
22
void port_eu_init(void);
23
void patch_sound(struct AudioBankSound *sound, struct AudioBank *memBase, struct PatchStruct *patchInfo);
24
void *func_802f3f08(s32 poolIdx, s32 idx, s32 numChunks, s32 arg3, OSMesgQueue *retQueue);
25
26
struct Note *gNotes;
27
28
UNUSED static u32 pad;
29
30
struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS];
31
struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS];
32
struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS];
33
34
struct SequenceChannel gSequenceChannelNone;
35
struct AudioListItem gLayerFreeList;
36
struct NotePool gNoteFreeLists;
37
38
struct AudioBankSample *D_SH_8034EA88[0x80];
39
struct UnkStructSH8034EC88 D_SH_8034EC88[0x80];
40
s32 D_SH_8034F688; // index into D_SH_8034EA88
41
s32 D_SH_8034F68C; // index or size for D_SH_8034EC88
42
43
struct PendingDmaAudioBank {
44
s8 inProgress;
45
s8 timer;
46
s8 medium;
47
struct AudioBank *audioBank;
48
uintptr_t devAddr;
49
void *vAddr;
50
u32 remaining;
51
u32 transferSize;
52
u32 encodedInfo;
53
OSMesgQueue *retQueue;
54
OSMesgQueue dmaRetQueue;
55
OSMesg mesgs[1];
56
OSIoMesg ioMesg;
57
};
58
struct PendingDmaAudioBank sPendingDmaAudioBanks[16];
59
60
OSMesgQueue gUnkQueue1;
61
OSMesg gUnkMesgBufs1[0x10];
62
OSMesgQueue gUnkQueue2;
63
OSMesg gUnkMesgBufs2[0x10];
64
65
OSMesgQueue gCurrAudioFrameDmaQueue;
66
OSMesg gCurrAudioFrameDmaMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE];
67
OSIoMesg gCurrAudioFrameDmaIoMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE];
68
69
OSMesgQueue gAudioDmaMesgQueue;
70
OSMesg gAudioDmaMesg;
71
OSIoMesg gAudioDmaIoMesg;
72
73
struct SharedDma *sSampleDmas;
74
u32 gSampleDmaNumListItems;
75
u32 sSampleDmaListSize1;
76
u32 sUnused80226B40; // set to 0, never read
77
78
// Circular buffer of DMAs with ttl = 0. tail <= head, wrapping around mod 256.
79
u8 sSampleDmaReuseQueue1[256];
80
u8 sSampleDmaReuseQueue2[256];
81
u8 sSampleDmaReuseQueueTail1;
82
u8 sSampleDmaReuseQueueTail2;
83
u8 sSampleDmaReuseQueueHead1;
84
u8 sSampleDmaReuseQueueHead2;
85
86
ALSeqFile *gSeqFileHeader;
87
ALSeqFile *gAlCtlHeader;
88
ALSeqFile *gAlTbl;
89
u8 *gAlBankSets;
90
u16 gSequenceCount;
91
92
struct CtlEntry *gCtlEntries;
93
94
struct AudioBufferParametersEU gAudioBufferParameters;
95
u32 sDmaBufSize;
96
s32 gMaxAudioCmds;
97
s32 gMaxSimultaneousNotes;
98
99
s16 gTempoInternalToExternal;
100
101
s8 gSoundMode;
102
103
s8 gAudioUpdatesPerFrame;
104
105
extern u64 gAudioGlobalsStartMarker;
106
extern u64 gAudioGlobalsEndMarker;
107
108
extern u8 gSoundDataADSR[]; // ctl
109
extern u8 gSoundDataRaw[]; // tbl
110
extern u8 gMusicData[]; // sequences
111
112
ALSeqFile *get_audio_file_header(s32 arg0);
113
114
void *func_sh_802f3688(s32 bankId);
115
void *get_bank_or_seq_wrapper(s32 arg0, s32 arg1);
116
void func_sh_802f3d78(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3);
117
void func_sh_802f3c38(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 medium);
118
s32 func_sh_802f3dd0(OSIoMesg *m, s32 pri, s32 direction, uintptr_t devAddr,
119
void *dramAddr, s32 size, OSMesgQueue *retQueue, s32 medium, UNUSED const char *reason);
120
void func_sh_802f4a4c(s32 audioResetStatus);
121
void func_sh_802f4bd8(struct PendingDmaSample *arg0, s32 len);
122
void func_sh_802f4c5c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3);
123
struct PendingDmaAudioBank *func_sh_802f4cb4(uintptr_t devAddr, void *vAddr, s32 size,
124
s32 medium, s32 numChunks, OSMesgQueue *retQueue, s32 encodedInfo);
125
void func_sh_802f4dcc(s32 audioResetStatus);
126
void func_sh_802f4e50(struct PendingDmaAudioBank *audioBank, s32 audioResetStatus);
127
void func_sh_802f50ec(struct PendingDmaAudioBank *arg0, size_t len);
128
void func_sh_802f517c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3);
129
BAD_RETURN(s32) func_sh_802f5310(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo, s32 arg3);
130
s32 func_sh_802f573c(s32 audioResetStatus);
131
void *func_sh_802f3564(s32 seqId);
132
s32 func_sh_802f3ec4(s32 arg0, uintptr_t *arg1);
133
void func_sh_802f3ed4(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED void *vAddr, UNUSED size_t nbytes);
134
135
s32 canonicalize_index(s32 poolIdx, s32 idx);
136
137
void decrease_sample_dma_ttls() {
138
u32 i;
139
140
for (i = 0; i < sSampleDmaListSize1; i++) {
141
struct SharedDma *temp = &sSampleDmas[i];
142
if (temp->ttl != 0) {
143
temp->ttl--;
144
if (temp->ttl == 0) {
145
temp->reuseIndex = sSampleDmaReuseQueueHead1;
146
sSampleDmaReuseQueue1[sSampleDmaReuseQueueHead1++] = (u8) i;
147
}
148
}
149
}
150
151
for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) {
152
struct SharedDma *temp = &sSampleDmas[i];
153
if (temp->ttl != 0) {
154
temp->ttl--;
155
if (temp->ttl == 0) {
156
temp->reuseIndex = sSampleDmaReuseQueueHead2;
157
sSampleDmaReuseQueue2[sSampleDmaReuseQueueHead2++] = (u8) i;
158
}
159
}
160
}
161
162
sUnused80226B40 = 0;
163
}
164
165
extern char shindouDebugPrint62[]; // "SUPERDMA"
166
void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef, s32 medium) {
167
UNUSED s32 sp60;
168
struct SharedDma *dma;
169
s32 hasDma = FALSE;
170
uintptr_t dmaDevAddr;
171
UNUSED u32 pad;
172
u32 dmaIndex;
173
u32 transfer;
174
ssize_t bufferPos;
175
u32 i;
176
177
if (arg2 != 0 || *dmaIndexRef >= sSampleDmaListSize1) {
178
for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) {
179
dma = &sSampleDmas[i];
180
bufferPos = devAddr - dma->source;
181
if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) {
182
// We already have a DMA request for this memory range.
183
if (dma->ttl == 0 && sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2) {
184
// Move the DMA out of the reuse queue, by swapping it with the
185
// tail, and then incrementing the tail.
186
if (dma->reuseIndex != sSampleDmaReuseQueueTail2) {
187
sSampleDmaReuseQueue2[dma->reuseIndex] =
188
sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2];
189
sSampleDmas[sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]].reuseIndex =
190
dma->reuseIndex;
191
}
192
sSampleDmaReuseQueueTail2++;
193
}
194
dma->ttl = 60;
195
*dmaIndexRef = (u8) i;
196
return &dma->buffer[(devAddr - dma->source)];
197
}
198
}
199
200
if (sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2 && arg2 != 0) {
201
// Allocate a DMA from reuse queue 2. This queue can be empty, since
202
// TTL 60 is pretty large.
203
dmaIndex = sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2];
204
sSampleDmaReuseQueueTail2++;
205
dma = sSampleDmas + dmaIndex;
206
hasDma = TRUE;
207
}
208
} else {
209
dma = sSampleDmas + *dmaIndexRef;
210
bufferPos = devAddr - dma->source;
211
if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) {
212
// We already have DMA for this memory range.
213
if (dma->ttl == 0) {
214
// Move the DMA out of the reuse queue, by swapping it with the
215
// tail, and then incrementing the tail.
216
if (dma->reuseIndex != sSampleDmaReuseQueueTail1) {
217
sSampleDmaReuseQueue1[dma->reuseIndex] =
218
sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1];
219
sSampleDmas[sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]].reuseIndex =
220
dma->reuseIndex;
221
}
222
sSampleDmaReuseQueueTail1++;
223
}
224
dma->ttl = 2;
225
return dma->buffer + (devAddr - dma->source);
226
}
227
}
228
229
if (!hasDma) {
230
if (1) {}
231
// Allocate a DMA from reuse queue 1. This queue will hopefully never
232
// be empty, since TTL 2 is so small.
233
dmaIndex = sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1++];
234
dma = sSampleDmas + dmaIndex;
235
hasDma = TRUE;
236
}
237
238
transfer = dma->bufSize;
239
dmaDevAddr = devAddr & ~0xF;
240
dma->ttl = 2;
241
dma->source = dmaDevAddr;
242
dma->sizeUnused = transfer;
243
func_sh_802f3dd0(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, OS_READ,
244
dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue, medium, shindouDebugPrint62);
245
*dmaIndexRef = dmaIndex;
246
return (devAddr - dmaDevAddr) + dma->buffer;
247
}
248
249
void init_sample_dma_buffers(UNUSED s32 arg0) {
250
s32 i;
251
252
sDmaBufSize = 0x2D0;
253
sSampleDmas = sound_alloc_uninitialized(&gNotesAndBuffersPool,
254
gMaxSimultaneousNotes * 4 * sizeof(struct SharedDma) * gAudioBufferParameters.presetUnk4);
255
256
for (i = 0; i < gMaxSimultaneousNotes * 3 * gAudioBufferParameters.presetUnk4; i++)
257
{
258
if ((sSampleDmas[gSampleDmaNumListItems].buffer = sound_alloc_uninitialized(&gNotesAndBuffersPool, sDmaBufSize)) == NULL) {
259
break;
260
}
261
sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize;
262
sSampleDmas[gSampleDmaNumListItems].source = 0;
263
sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0;
264
sSampleDmas[gSampleDmaNumListItems].unused2 = 0;
265
sSampleDmas[gSampleDmaNumListItems].ttl = 0;
266
gSampleDmaNumListItems++;
267
}
268
269
for (i = 0; (u32) i < gSampleDmaNumListItems; i++) {
270
sSampleDmaReuseQueue1[i] = (u8) i;
271
sSampleDmas[i].reuseIndex = (u8) i;
272
}
273
274
for (i = gSampleDmaNumListItems; i < 0x100; i++) {
275
sSampleDmaReuseQueue1[i] = 0;
276
}
277
278
sSampleDmaReuseQueueTail1 = 0;
279
sSampleDmaReuseQueueHead1 = (u8) gSampleDmaNumListItems;
280
sSampleDmaListSize1 = gSampleDmaNumListItems;
281
282
sDmaBufSize = 0x2D0;
283
for (i = 0; i < gMaxSimultaneousNotes; i++) {
284
if ((sSampleDmas[gSampleDmaNumListItems].buffer = sound_alloc_uninitialized(&gNotesAndBuffersPool, sDmaBufSize)) == NULL) {
285
break;
286
}
287
sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize;
288
sSampleDmas[gSampleDmaNumListItems].source = 0;
289
sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0;
290
sSampleDmas[gSampleDmaNumListItems].unused2 = 0;
291
sSampleDmas[gSampleDmaNumListItems].ttl = 0;
292
gSampleDmaNumListItems++;
293
}
294
295
for (i = sSampleDmaListSize1; (u32) i < gSampleDmaNumListItems; i++) {
296
sSampleDmaReuseQueue2[i - sSampleDmaListSize1] = (u8) i;
297
sSampleDmas[i].reuseIndex = (u8)(i - sSampleDmaListSize1);
298
}
299
300
// This probably meant to touch the range size1..size2 as well... but it
301
// doesn't matter, since these values are never read anyway.
302
for (i = gSampleDmaNumListItems; i < 0x100; i++) {
303
sSampleDmaReuseQueue2[i] = sSampleDmaListSize1;
304
}
305
306
sSampleDmaReuseQueueTail2 = 0;
307
sSampleDmaReuseQueueHead2 = gSampleDmaNumListItems - sSampleDmaListSize1;
308
}
309
310
void patch_seq_file(ALSeqFile *seqFile, u8 *data, u16 arg2) {
311
s32 i;
312
313
seqFile->unk2 = arg2;
314
seqFile->data = data;
315
for (i = 0; i < seqFile->seqCount; i++) {
316
if (seqFile->seqArray[i].len != 0 && seqFile->seqArray[i].medium == 2) {
317
seqFile->seqArray[i].offset += (uintptr_t)data;
318
}
319
}
320
}
321
322
struct AudioBank *load_banks_immediate(s32 seqId, s32 *outDefaultBank) {
323
u8 bank;
324
s32 offset;
325
s32 i;
326
void *ret;
327
328
offset = ((u16 *)gAlBankSets)[canonicalize_index(0, seqId)];
329
bank = 0xFF;
330
for (i = gAlBankSets[offset++]; i > 0; i--) {
331
bank = gAlBankSets[offset++];
332
ret = func_sh_802f3688(bank);
333
}
334
*outDefaultBank = bank;
335
return ret;
336
}
337
338
void preload_sequence(u32 seqId, s32 preloadMask) {
339
UNUSED s32 pad;
340
s32 temp;
341
342
seqId = canonicalize_index(0, seqId);
343
if (preloadMask & PRELOAD_BANKS) {
344
load_banks_immediate(seqId, &temp);
345
}
346
if (preloadMask & PRELOAD_SEQUENCE) {
347
func_sh_802f3564(seqId);
348
}
349
}
350
351
s32 func_sh_802f2f38(struct AudioBankSample *sample, s32 bankId) {
352
u8 *sp24;
353
354
if (sample->isPatched == TRUE && sample->medium != 0) {
355
sp24 = func_sh_802f1d90(sample->size, bankId, sample->sampleAddr, sample->medium);
356
if (sp24 == NULL) {
357
return -1;
358
}
359
if (sample->medium == 1) {
360
func_sh_802f3d78((uintptr_t) sample->sampleAddr, sp24, sample->size, gAlTbl->unk2);
361
} else {
362
func_sh_802f3c38((uintptr_t) sample->sampleAddr, sp24, sample->size, sample->medium);
363
}
364
sample->medium = 0;
365
sample->sampleAddr = sp24;
366
}
367
#ifdef AVOID_UB
368
return 0;
369
#endif
370
}
371
372
s32 func_sh_802f3024(s32 bankId, s32 instId, s32 arg2) {
373
struct Instrument *instr;
374
struct Drum *drum;
375
376
if (instId < 0x7F) {
377
instr = get_instrument_inner(bankId, instId);
378
if (instr == NULL) {
379
return -1;
380
}
381
if (instr->normalRangeLo != 0) {
382
func_sh_802f2f38(instr->lowNotesSound.sample, bankId);
383
}
384
func_sh_802f2f38(instr->normalNotesSound.sample, bankId);
385
if (instr->normalRangeHi != 0x7F) {
386
func_sh_802f2f38(instr->highNotesSound.sample, bankId);
387
}
388
//! @bug missing return
389
} else if (instId == 0x7F) {
390
drum = get_drum(bankId, arg2);
391
if (drum == NULL) {
392
return -1;
393
}
394
func_sh_802f2f38(drum->sound.sample, bankId);
395
return 0;
396
}
397
#ifdef AVOID_UB
398
return 0;
399
#endif
400
}
401
402
void func_sh_802f30f4(s32 arg0, s32 arg1, s32 arg2, OSMesgQueue *arg3) {
403
if (func_802f3f08(2, canonicalize_index(2, arg0), arg1, arg2, arg3) == 0) {
404
osSendMesg(arg3, 0, 0);
405
}
406
}
407
408
void func_sh_802f3158(s32 seqId, s32 numChunks, s32 arg2, OSMesgQueue *retQueue) {
409
s32 val;
410
s32 v;
411
412
val = ((u16 *) gAlBankSets)[canonicalize_index(0, seqId)];
413
v = gAlBankSets[val++];
414
415
while (v > 0) {
416
func_802f3f08(1, canonicalize_index(1, gAlBankSets[val++]), numChunks, arg2, retQueue);
417
v--;
418
}
419
}
420
421
u8 *func_sh_802f3220(u32 seqId, u32 *a1) {
422
s32 val;
423
424
val = ((u16 *) gAlBankSets)[canonicalize_index(0, seqId)];
425
*a1 = gAlBankSets[val++];
426
if (*a1 == 0) {
427
return NULL;
428
}
429
return &gAlBankSets[val];
430
}
431
432
void func_sh_802f3288(s32 idx) {
433
s32 bankId;
434
s32 s2;
435
436
idx = ((u16*)gAlBankSets)[canonicalize_index(0, idx)];
437
s2 = gAlBankSets[idx++];
438
while (s2 > 0) {
439
s2--;
440
bankId = canonicalize_index(1, gAlBankSets[idx++]);
441
442
if (unk_pool1_lookup(1, bankId) == NULL) {
443
func_sh_802f3368(bankId);
444
if (gBankLoadStatus[bankId] != SOUND_LOAD_STATUS_5) {
445
gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_NOT_LOADED;
446
}
447
448
continue;
449
}
450
451
}
452
}
453
454
BAD_RETURN(s32) func_sh_802f3368(s32 bankId) {
455
struct SoundMultiPool *pool = &gBankLoadedPool;
456
struct TemporaryPool *temporary = &pool->temporary;
457
struct PersistentPool *persistent;
458
u32 i;
459
460
if (temporary->entries[0].id == bankId) {
461
temporary->entries[0].id = -1;
462
} else if (temporary->entries[1].id == bankId) {
463
temporary->entries[1].id = -1;
464
}
465
466
persistent = &pool->persistent;
467
for (i = 0; i < persistent->numEntries; i++) {
468
if (persistent->entries[i].id == bankId) {
469
persistent->entries[i].id = -1;
470
}
471
472
}
473
474
discard_bank(bankId);
475
}
476
477
478
void load_sequence_internal(s32 player, s32 seqId, s32 loadAsync);
479
void load_sequence(u32 player, u32 seqId, s32 loadAsync) {
480
load_sequence_internal(player, seqId, loadAsync);
481
}
482
483
void load_sequence_internal(s32 player, s32 seqId, UNUSED s32 loadAsync) {
484
struct SequencePlayer *seqPlayer;
485
u8 *sequenceData;
486
u32 s0;
487
s32 count;
488
u8 bank;
489
s32 i;
490
491
seqPlayer = &gSequencePlayers[player];
492
493
seqId = canonicalize_index(0, seqId);
494
sequence_player_disable(seqPlayer);
495
496
s0 = ((u16 *) gAlBankSets)[seqId];
497
count = gAlBankSets[s0++];
498
bank = 0xff;
499
500
while (count > 0) {
501
bank = gAlBankSets[s0++];
502
func_sh_802f3688(bank);
503
count--;
504
}
505
506
sequenceData = func_sh_802f3564(seqId);
507
init_sequence_player(player);
508
seqPlayer->seqId = seqId;
509
seqPlayer->defaultBank[0] = bank;
510
seqPlayer->enabled = 1;
511
seqPlayer->seqData = sequenceData;
512
seqPlayer->scriptState.pc = sequenceData;
513
seqPlayer->scriptState.depth = 0;
514
seqPlayer->delay = 0;
515
seqPlayer->finished = 0;
516
517
for (i = 0; i < 0x10; i++) {
518
}
519
}
520
521
void *func_sh_802f3564(s32 seqId) {
522
s32 seqId2 = canonicalize_index(0, seqId);
523
s32 temp;
524
return func_sh_802f3764(0, seqId2, &temp);
525
}
526
527
extern u8 gUnkLoadStatus[0x40];
528
529
void *func_sh_802f3598(s32 idx, s32 *medium) {
530
void *ret;
531
ALSeqFile *f;
532
s32 temp;
533
s32 sp28;
534
535
f = get_audio_file_header(2);
536
idx = canonicalize_index(2, idx);
537
ret = get_bank_or_seq_wrapper(2, idx);
538
if (ret != NULL) {
539
if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
540
gUnkLoadStatus[idx] = SOUND_LOAD_STATUS_COMPLETE;
541
}
542
543
*medium = 0;
544
return ret;
545
}
546
547
temp = f->seqArray[idx].magic;
548
if (temp == 4) {
549
*medium = f->seqArray[idx].medium;
550
return f->seqArray[idx].offset;
551
} else {
552
ret = func_sh_802f3764(2, idx, &sp28);
553
if (ret != 0) {
554
*medium = 0;
555
return ret;
556
}
557
558
*medium = f->seqArray[idx].medium;
559
}
560
return f->seqArray[idx].offset;
561
562
}
563
564
void *func_sh_802f3688(s32 bankId) {
565
void *ret;
566
s32 bankId1;
567
s32 bankId2;
568
s32 sp38;
569
struct PatchStruct patchInfo;
570
571
bankId = canonicalize_index(1, bankId);
572
bankId1 = gCtlEntries[bankId].bankId1;
573
bankId2 = gCtlEntries[bankId].bankId2;
574
575
patchInfo.bankId1 = bankId1;
576
patchInfo.bankId2 = bankId2;
577
578
if (patchInfo.bankId1 != 0xFF) {
579
patchInfo.baseAddr1 = func_sh_802f3598(patchInfo.bankId1, &patchInfo.medium1);
580
} else {
581
patchInfo.baseAddr1 = NULL;
582
}
583
584
if (bankId2 != 0xFF) {
585
patchInfo.baseAddr2 = func_sh_802f3598(bankId2, &patchInfo.medium2);
586
} else {
587
patchInfo.baseAddr2 = NULL;
588
}
589
590
if ((ret = func_sh_802f3764(1, bankId, &sp38)) == NULL) {
591
return NULL;
592
}
593
594
if (sp38 == 1) {
595
func_sh_802f5310(bankId, ret, &patchInfo, 0);
596
}
597
598
return ret;
599
}
600
601
void *func_sh_802f3764(s32 poolIdx, s32 idx, s32 *arg2) {
602
s32 size;
603
ALSeqFile *f;
604
void *vAddr;
605
s32 medium;
606
UNUSED u32 pad2;
607
u8 *devAddr;
608
s8 loadStatus;
609
s32 sp18;
610
611
vAddr = get_bank_or_seq_wrapper(poolIdx, idx);
612
if (vAddr != NULL) {
613
*arg2 = 0;
614
loadStatus = SOUND_LOAD_STATUS_COMPLETE;
615
} else {
616
f = get_audio_file_header(poolIdx);
617
size = f->seqArray[idx].len;
618
size = ALIGN16(size);
619
medium = f->seqArray[idx].medium;
620
sp18 = f->seqArray[idx].magic;
621
devAddr = f->seqArray[idx].offset;
622
623
624
switch (sp18)
625
{
626
case 0:
627
vAddr = unk_pool1_alloc(poolIdx, idx, size);
628
if (vAddr == NULL) {
629
return vAddr;
630
}
631
break;
632
case 1:
633
vAddr = alloc_bank_or_seq(poolIdx, size, 1, idx);
634
if (vAddr == NULL) {
635
return vAddr;
636
}
637
break;
638
case 2:
639
vAddr = alloc_bank_or_seq(poolIdx, size, 0, idx);
640
if (vAddr == NULL) {
641
return vAddr;
642
}
643
break;
644
645
case 3:
646
case 4:
647
vAddr = alloc_bank_or_seq(poolIdx, size, 2, idx);
648
if (vAddr == NULL) {
649
return vAddr;
650
}
651
break;
652
}
653
654
*arg2 = 1;
655
if (medium == 1) {
656
func_sh_802f3d78((uintptr_t) devAddr, vAddr, size, f->unk2);
657
} else {
658
func_sh_802f3c38((uintptr_t) devAddr, vAddr, size, medium);
659
}
660
661
switch (sp18) {
662
case 0:
663
loadStatus = SOUND_LOAD_STATUS_5;
664
break;
665
666
default:
667
loadStatus = SOUND_LOAD_STATUS_COMPLETE;
668
break;
669
}
670
}
671
672
switch (poolIdx) {
673
case 0:
674
if (gSeqLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
675
gSeqLoadStatus[idx] = loadStatus;
676
}
677
break;
678
679
case 1:
680
if (gBankLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
681
gBankLoadStatus[idx] = loadStatus;
682
}
683
break;
684
685
case 2:
686
if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
687
gUnkLoadStatus[idx] = loadStatus;
688
}
689
break;
690
}
691
692
return vAddr;
693
}
694
695
s32 canonicalize_index(s32 poolIdx, s32 idx) {
696
ALSeqFile *f;
697
698
f = get_audio_file_header(poolIdx);
699
if (f->seqArray[idx].len == 0) {
700
idx = (s32) (uintptr_t) f->seqArray[idx].offset;
701
}
702
return idx;
703
}
704
705
void *get_bank_or_seq_wrapper(s32 poolIdx, s32 id) {
706
void *ret;
707
708
ret = unk_pool1_lookup(poolIdx, id);
709
if (ret != NULL) {
710
return ret;
711
}
712
ret = get_bank_or_seq(poolIdx, 2, id);
713
if (ret != 0) {
714
return ret;
715
}
716
return NULL;
717
}
718
719
ALSeqFile *get_audio_file_header(s32 poolIdx) {
720
ALSeqFile *ret;
721
switch (poolIdx) {
722
default:
723
ret = NULL;
724
break;
725
case 0:
726
ret = gSeqFileHeader;
727
break;
728
case 1:
729
ret = gAlCtlHeader;
730
break;
731
case 2:
732
ret = gAlTbl;
733
break;
734
}
735
return ret;
736
}
737
738
void patch_audio_bank(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo) {
739
struct Instrument *instrument;
740
void **itInstrs;
741
struct Instrument **end;
742
s32 i;
743
void *patched;
744
struct Drum *drum;
745
s32 numDrums;
746
s32 numInstruments;
747
748
#define BASE_OFFSET(x, base) (void *)((uintptr_t) (x) + (uintptr_t) base)
749
#define PATCH(x, base) (patched = BASE_OFFSET(x, base))
750
#define PATCH_MEM(x) x = PATCH(x, mem)
751
752
numDrums = gCtlEntries[bankId].numDrums;
753
numInstruments = gCtlEntries[bankId].numInstruments;
754
itInstrs = (void **) mem->drums;
755
if (mem->drums) {
756
}
757
if (itInstrs != NULL && numDrums != 0) {
758
if (1) {
759
mem->drums = PATCH(itInstrs, mem);
760
}
761
for (i = 0; i < numDrums; i++) {
762
patched = mem->drums[i];
763
if (patched != NULL) {
764
drum = PATCH(patched, mem);
765
mem->drums[i] = drum;
766
if (drum->loaded == 0) {
767
patch_sound(&drum->sound, mem, patchInfo);
768
patched = drum->envelope;
769
drum->envelope = BASE_OFFSET(patched, mem);
770
drum->loaded = 1;
771
}
772
773
}
774
}
775
}
776
777
if (numInstruments > 0) {
778
itInstrs = (void **) mem->instruments;
779
end = numInstruments + (struct Instrument **) itInstrs;
780
781
do {
782
if (*itInstrs != NULL) {
783
*itInstrs = BASE_OFFSET(*itInstrs, mem);
784
instrument = *itInstrs;
785
786
if (instrument->loaded == 0) {
787
if (instrument->normalRangeLo != 0) {
788
patch_sound(&instrument->lowNotesSound, mem, patchInfo);
789
}
790
patch_sound(&instrument->normalNotesSound, mem, patchInfo);
791
if (instrument->normalRangeHi != 0x7F) {
792
patch_sound(&instrument->highNotesSound, mem, patchInfo);
793
}
794
patched = instrument->envelope;
795
796
instrument->envelope = BASE_OFFSET(patched, mem);
797
instrument->loaded = 1;
798
}
799
}
800
itInstrs = (void **) ((struct Instrument **) itInstrs) + 1;
801
} while ((struct Instrument **) itInstrs != ((void) 0, end)); //! This is definitely fake
802
}
803
gCtlEntries[bankId].drums = mem->drums;
804
gCtlEntries[bankId].instruments = mem->instruments;
805
#undef PATCH_MEM
806
#undef PATCH
807
#undef BASE_OFFSET
808
}
809
810
extern char shindouDebugPrint81[]; // "FastCopy"
811
extern char shindouDebugPrint82[]; // "FastCopy"
812
void func_sh_802f3c38(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 medium) {
813
nbytes = ALIGN16(nbytes);
814
osInvalDCache(vAddr, nbytes);
815
816
again:
817
if (gAudioLoadLockSH != 0) {
818
goto again;
819
}
820
821
if (nbytes >= 0x400U) {
822
func_sh_802f3dd0(&gAudioDmaIoMesg, 1, 0, devAddr, vAddr, 0x400, &gAudioDmaMesgQueue, medium, shindouDebugPrint81);
823
osRecvMesg(&gAudioDmaMesgQueue, NULL, 1);
824
nbytes = nbytes - 0x400;
825
devAddr = devAddr + 0x400;
826
vAddr = (u8*)vAddr + 0x400;
827
goto again;
828
}
829
830
if (nbytes != 0) {
831
func_sh_802f3dd0(&gAudioDmaIoMesg, 1, 0, devAddr, vAddr, nbytes, &gAudioDmaMesgQueue, medium, shindouDebugPrint82);
832
osRecvMesg(&gAudioDmaMesgQueue, NULL, 1);
833
}
834
}
835
836
void func_sh_802f3d78(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) {
837
uintptr_t sp1C;
838
839
sp1C = devAddr;
840
osInvalDCache(vAddr, nbytes);
841
func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes);
842
}
843
844
s32 func_sh_802f3dd0(OSIoMesg *m, s32 pri, s32 direction, uintptr_t devAddr, void *dramAddr, s32 size, OSMesgQueue *retQueue, s32 medium, UNUSED const char *reason) {
845
OSPiHandle *handle;
846
if (gAudioLoadLockSH >= 0x11U) {
847
return -1;
848
}
849
switch (medium) {
850
case 2:
851
handle = osCartRomInit();
852
break;
853
case 3:
854
handle = osDriveRomInit();
855
break;
856
default:
857
return 0;
858
}
859
if ((size & 0xf) != 0) {
860
size = ALIGN16(size);
861
}
862
m->hdr.pri = pri;
863
m->hdr.retQueue = retQueue;
864
m->dramAddr = dramAddr;
865
m->devAddr = devAddr;
866
m->size = size;
867
handle->transferInfo.cmdType = 2;
868
osEPiStartDma(handle, m, direction);
869
return 0;
870
}
871
872
s32 func_sh_802f3ec4(UNUSED s32 arg0, UNUSED uintptr_t *arg1) {
873
return 0;
874
}
875
876
void func_sh_802f3ed4(UNUSED s32 arg0, UNUSED s32 arg1, UNUSED void *vAddr, UNUSED size_t nbytes) {
877
}
878
879
void *func_sh_802f3ee8(s32 poolIdx, s32 idx) {
880
s32 temp;
881
return func_sh_802f3764(poolIdx, idx, &temp);
882
}
883
884
void *func_802f3f08(s32 poolIdx, s32 idx, s32 numChunks, s32 arg3, OSMesgQueue *retQueue) {
885
s32 size;
886
ALSeqFile *f;
887
void *vAddr;
888
s32 medium;
889
s32 sp18;
890
uintptr_t devAddr;
891
s32 loadStatus;
892
893
switch (poolIdx) {
894
case 0:
895
if (gSeqLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) {
896
return 0;
897
}
898
break;
899
case 1:
900
if (gBankLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) {
901
return 0;
902
}
903
break;
904
case 2:
905
if (gUnkLoadStatus[idx] == SOUND_LOAD_STATUS_IN_PROGRESS) {
906
return 0;
907
}
908
break;
909
910
}
911
vAddr = get_bank_or_seq_wrapper(poolIdx, idx);
912
if (vAddr != NULL) {
913
loadStatus = 2;
914
osSendMesg(retQueue, (OSMesg) (arg3 << 0x18), 0);
915
} else {
916
f = get_audio_file_header(poolIdx);
917
size = f->seqArray[idx].len;
918
size = ALIGN16(size);
919
medium = f->seqArray[idx].medium;
920
sp18 = f->seqArray[idx].magic;
921
devAddr = (uintptr_t) f->seqArray[idx].offset;
922
loadStatus = 2;
923
924
switch (sp18) {
925
case 0:
926
vAddr = unk_pool1_alloc(poolIdx, idx, size);
927
if (vAddr == NULL) {
928
return vAddr;
929
}
930
loadStatus = SOUND_LOAD_STATUS_5;
931
break;
932
case 1:
933
vAddr = alloc_bank_or_seq(poolIdx, size, 1, idx);
934
if (vAddr == NULL) {
935
return vAddr;
936
}
937
break;
938
case 2:
939
vAddr = alloc_bank_or_seq(poolIdx, size, 0, idx);
940
if (vAddr == NULL) {
941
return vAddr;
942
}
943
break;
944
945
case 4:
946
case 3:
947
vAddr = alloc_bank_or_seq(poolIdx, size, 2, idx);
948
if (vAddr == NULL) {
949
return vAddr;
950
}
951
break;
952
}
953
954
func_sh_802f4cb4(devAddr, vAddr, size, medium, numChunks, retQueue, (arg3 << 0x18) | (poolIdx << 0x10) | (idx << 8) | loadStatus);
955
loadStatus = SOUND_LOAD_STATUS_IN_PROGRESS;
956
}
957
958
switch (poolIdx) {
959
case 0:
960
if (gSeqLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
961
gSeqLoadStatus[idx] = loadStatus;
962
}
963
break;
964
965
case 1:
966
if (gBankLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
967
gBankLoadStatus[idx] = loadStatus;
968
}
969
break;
970
971
case 2:
972
if (gUnkLoadStatus[idx] != SOUND_LOAD_STATUS_5) {
973
gUnkLoadStatus[idx] = loadStatus;
974
}
975
break;
976
}
977
978
return vAddr;
979
}
980
981
void func_sh_802f41e4(s32 audioResetStatus) {
982
func_sh_802f4a4c(audioResetStatus);
983
func_sh_802f573c(audioResetStatus);
984
func_sh_802f4dcc(audioResetStatus);
985
}
986
987
#if defined(VERSION_SH)
988
u8 gShindouSoundBanksHeader[] = {
989
#include "sound/ctl_header.inc.c"
990
};
991
992
u8 gBankSetsData[] = {
993
#include "sound/bank_sets.inc.c"
994
};
995
996
u8 gShindouSampleBanksHeader[] = {
997
#include "sound/tbl_header.inc.c"
998
};
999
1000
u8 gShindouSequencesHeader[] = {
1001
#include "sound/sequences_header.inc.c"
1002
};
1003
#endif
1004
1005
// (void) must be omitted from parameters
1006
void audio_init() {
1007
UNUSED s8 pad[0x34];
1008
s32 i, j, k;
1009
s32 lim;
1010
u64 *ptr64;
1011
void *data;
1012
UNUSED u8 pad2[4];
1013
s32 seqCount;
1014
1015
gAudioLoadLockSH = 0;
1016
1017
for (i = 0; i < gAudioHeapSize / 8; i++) {
1018
((u64 *) gAudioHeap)[i] = 0;
1019
}
1020
1021
#ifdef TARGET_N64
1022
// It seems boot.s doesn't clear the .bss area for audio, so do it here.
1023
lim = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8;
1024
ptr64 = &gAudioGlobalsStartMarker;
1025
for (k = lim; k >= 0; k--) {
1026
*ptr64++ = 0;
1027
}
1028
#endif
1029
1030
D_EU_802298D0 = 16.713f;
1031
gRefreshRate = 60;
1032
port_eu_init();
1033
1034
#ifdef TARGET_N64
1035
eu_stubbed_printf_3("Clear Workarea %x -%x size %x \n",
1036
(uintptr_t) &gAudioGlobalsStartMarker,
1037
(uintptr_t) &gAudioGlobalsEndMarker,
1038
(uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker
1039
);
1040
#endif
1041
1042
eu_stubbed_printf_1("AudioHeap is %x\n", gAudioHeapSize);
1043
1044
for (i = 0; i < NUMAIBUFFERS; i++) {
1045
gAiBufferLengths[i] = 0xa0;
1046
}
1047
1048
gAudioFrameCount = 0;
1049
gAudioTaskIndex = 0;
1050
gCurrAiBufferIndex = 0;
1051
gSoundMode = 0;
1052
gAudioTask = NULL;
1053
gAudioTasks[0].task.t.data_size = 0;
1054
gAudioTasks[1].task.t.data_size = 0;
1055
osCreateMesgQueue(&gAudioDmaMesgQueue, &gAudioDmaMesg, 1);
1056
osCreateMesgQueue(&gCurrAudioFrameDmaQueue, gCurrAudioFrameDmaMesgBufs,
1057
ARRAY_COUNT(gCurrAudioFrameDmaMesgBufs));
1058
osCreateMesgQueue(&gUnkQueue1, gUnkMesgBufs1, 0x10);
1059
osCreateMesgQueue(&gUnkQueue2, gUnkMesgBufs2, 0x10);
1060
gCurrAudioFrameDmaCount = 0;
1061
gSampleDmaNumListItems = 0;
1062
1063
sound_init_main_pools(gAudioInitPoolSize);
1064
1065
for (i = 0; i < NUMAIBUFFERS; i++) {
1066
gAiBuffers[i] = sound_alloc_uninitialized(&gAudioInitPool, AIBUFFER_LEN);
1067
1068
for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) {
1069
gAiBuffers[i][j] = 0;
1070
}
1071
}
1072
1073
gAudioResetPresetIdToLoad = 0;
1074
gAudioResetStatus = 1;
1075
audio_shut_down_and_reset_step();
1076
1077
// Not sure about these prints
1078
eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0);
1079
eu_stubbed_printf_3("Heap %x %x %x\n", 0, 0, 0);
1080
eu_stubbed_printf_0("Main Heap Initialize.\n");
1081
1082
// Load headers for sounds and sequences
1083
gSeqFileHeader = (ALSeqFile *) gShindouSequencesHeader;
1084
gAlCtlHeader = (ALSeqFile *) gShindouSoundBanksHeader;
1085
gAlTbl = (ALSeqFile *) gShindouSampleBanksHeader;
1086
gAlBankSets = gBankSetsData;
1087
gSequenceCount = (s16) gSeqFileHeader->seqCount;
1088
patch_seq_file(gSeqFileHeader, gMusicData, D_SH_80315EF4);
1089
patch_seq_file(gAlCtlHeader, gSoundDataADSR, D_SH_80315EF8);
1090
patch_seq_file(gAlTbl, gSoundDataRaw, D_SH_80315EFC);
1091
seqCount = gAlCtlHeader->seqCount;
1092
gCtlEntries = sound_alloc_uninitialized(&gAudioInitPool, seqCount * sizeof(struct CtlEntry));
1093
for (i = 0; i < seqCount; i++) {
1094
gCtlEntries[i].bankId1 = (u8) ((gAlCtlHeader->seqArray[i].ctl.as_s16.bankAndFf >> 8) & 0xff);
1095
gCtlEntries[i].bankId2 = (u8) (gAlCtlHeader->seqArray[i].ctl.as_s16.bankAndFf & 0xff);
1096
gCtlEntries[i].numInstruments = (u8) ((gAlCtlHeader->seqArray[i].ctl.as_s16.numInstrumentsAndDrums >> 8) & 0xff);
1097
gCtlEntries[i].numDrums = (u8) (gAlCtlHeader->seqArray[i].ctl.as_s16.numInstrumentsAndDrums & 0xff);
1098
}
1099
data = sound_alloc_uninitialized(&gAudioInitPool, D_SH_80315EF0);
1100
if (data == NULL) {
1101
D_SH_80315EF0 = 0;
1102
}
1103
sound_alloc_pool_init(&gUnkPool1.pool, data, D_SH_80315EF0);
1104
init_sequence_players();
1105
}
1106
1107
s32 func_sh_802f47c8(s32 bankId, u8 idx, s8 *io) {
1108
struct AudioBankSample *sample = func_sh_802f4978(bankId, idx);
1109
struct PendingDmaSample *temp;
1110
if (sample == NULL) {
1111
*io = 0;
1112
return -1;
1113
}
1114
if (sample->medium == 0) {
1115
*io = 2;
1116
return 0;
1117
}
1118
temp = &D_SH_80343D00.arr[D_SH_80343D00.someIndex];
1119
if (temp->state == 3) {
1120
temp->state = 0;
1121
}
1122
temp->sample = *sample;
1123
temp->io = io;
1124
temp->vAddr = func_sh_802f1d40(sample->size, bankId, sample->sampleAddr, sample->medium);
1125
if (temp->vAddr == NULL) {
1126
if (sample->medium == 1 || sample->codec == CODEC_SKIP) {
1127
*io = 0;
1128
return -1;
1129
} else {
1130
*io = 3;
1131
return -1;
1132
}
1133
}
1134
temp->state = 1;
1135
temp->remaining = ALIGN16(sample->size);
1136
temp->resultSampleAddr = (u8 *) temp->vAddr;
1137
temp->devAddr = (uintptr_t) sample->sampleAddr;
1138
temp->medium = sample->medium;
1139
temp->bankId = bankId;
1140
temp->idx = idx;
1141
D_SH_80343D00.someIndex ^= 1;
1142
return 0;
1143
}
1144
1145
struct AudioBankSample *func_sh_802f4978(s32 bankId, s32 idx) {
1146
struct Drum *drum;
1147
struct Instrument *inst;
1148
struct AudioBankSample *ret;
1149
1150
if (idx < 128) {
1151
inst = get_instrument_inner(bankId, idx);
1152
if (inst == 0) {
1153
return NULL;
1154
}
1155
ret = inst->normalNotesSound.sample;
1156
} else {
1157
drum = get_drum(bankId, idx - 128);
1158
if (drum == 0) {
1159
return NULL;
1160
}
1161
ret = drum->sound.sample;
1162
}
1163
return ret;
1164
}
1165
1166
void stub_sh_802f49dc(void) {
1167
}
1168
1169
void func_sh_802f49e4(struct PendingDmaSample *arg0) {
1170
struct AudioBankSample *sample = func_sh_802f4978(arg0->bankId, arg0->idx);
1171
if (sample != NULL) {
1172
arg0->sample = *sample;
1173
sample->sampleAddr = arg0->resultSampleAddr;
1174
sample->medium = 0;
1175
}
1176
}
1177
1178
void func_sh_802f4a4c(s32 audioResetStatus) {
1179
ALSeqFile *alTbl;
1180
struct PendingDmaSample *entry;
1181
1182
s32 i;
1183
1184
alTbl = gAlTbl;
1185
1186
for (i = 0; i < 2; i++) {
1187
entry = &D_SH_80343D00.arr[i];
1188
switch (entry->state) {
1189
case 2:
1190
osRecvMesg(&entry->queue, NULL, 1);
1191
if (audioResetStatus != 0) {
1192
entry->state = 3;
1193
break;
1194
}
1195
// fallthrough
1196
case 1:
1197
entry->state = 2;
1198
if (entry->remaining == 0) {
1199
func_sh_802f49e4(entry);
1200
entry->state = 3;
1201
*entry->io = 1;
1202
} else if (entry->remaining < 0x1000) {
1203
if (entry->medium == 1) {
1204
func_sh_802f4c5c(entry->devAddr, entry->vAddr, entry->remaining, alTbl->unk2);
1205
} else {
1206
func_sh_802f4bd8(entry, entry->remaining);
1207
}
1208
entry->remaining = 0;
1209
} else {
1210
if (entry->medium == 1) {
1211
func_sh_802f4c5c(entry->devAddr, entry->vAddr, 0x1000, alTbl->unk2);
1212
} else {
1213
func_sh_802f4bd8(entry, 0x1000);
1214
}
1215
entry->remaining = (s32) (entry->remaining - 0x1000);
1216
entry->vAddr = (u8 *) entry->vAddr + 0x1000;
1217
entry->devAddr = entry->devAddr + 0x1000;
1218
}
1219
break;
1220
}
1221
}
1222
}
1223
1224
extern char shindouDebugPrint102[]; // "SLOWCOPY"
1225
void func_sh_802f4bd8(struct PendingDmaSample *arg0, s32 len) { // len must be signed
1226
osInvalDCache(arg0->vAddr, len);
1227
osCreateMesgQueue(&arg0->queue, arg0->mesgs, 1);
1228
func_sh_802f3dd0(&arg0->ioMesg, 0, 0, arg0->devAddr, arg0->vAddr, len, &arg0->queue, arg0->medium, shindouDebugPrint102);
1229
}
1230
1231
void func_sh_802f4c5c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) {
1232
uintptr_t sp1C;
1233
1234
sp1C = devAddr;
1235
osInvalDCache(vAddr, nbytes);
1236
func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes);
1237
}
1238
1239
struct PendingDmaAudioBank *func_sh_802f4cb4(uintptr_t devAddr, void *vAddr, s32 size, s32 medium, s32 numChunks, OSMesgQueue *retQueue, s32 encodedInfo) {
1240
struct PendingDmaAudioBank *item;
1241
s32 i;
1242
1243
for (i = 0; i < ARRAY_COUNT(sPendingDmaAudioBanks); i++) {
1244
if (sPendingDmaAudioBanks[i].inProgress == 0) {
1245
item = &sPendingDmaAudioBanks[i];
1246
break;
1247
}
1248
}
1249
if (i == ARRAY_COUNT(sPendingDmaAudioBanks)) {
1250
return NULL;
1251
}
1252
1253
item->inProgress = 1;
1254
item->devAddr = devAddr;
1255
item->audioBank = vAddr;
1256
item->vAddr = vAddr;
1257
item->remaining = size;
1258
if (numChunks == 0) {
1259
item->transferSize = 0x1000;
1260
} else {
1261
item->transferSize = ((size / numChunks) + 0xFF) & ~0xFF;
1262
if (item->transferSize < 0x100) {
1263
item->transferSize = 0x100;
1264
}
1265
}
1266
item->retQueue = retQueue;
1267
item->timer = 3;
1268
item->medium = medium;
1269
item->encodedInfo = encodedInfo;
1270
osCreateMesgQueue(&item->dmaRetQueue, item->mesgs, 1);
1271
return item;
1272
}
1273
1274
void func_sh_802f4dcc(s32 audioResetStatus) {
1275
s32 i;
1276
1277
if (gAudioLoadLockSH != 1) {
1278
for (i = 0; i < ARRAY_COUNT(sPendingDmaAudioBanks); i++) {
1279
if (sPendingDmaAudioBanks[i].inProgress == 1) {
1280
func_sh_802f4e50(&sPendingDmaAudioBanks[i], audioResetStatus);
1281
}
1282
}
1283
}
1284
}
1285
1286
void func_sh_802f4e50(struct PendingDmaAudioBank *audioBank, s32 audioResetStatus) {
1287
ALSeqFile *alSeqFile;
1288
u32 *encodedInfo;
1289
OSMesg mesg;
1290
u32 temp;
1291
u32 bankId;
1292
s32 bankId1;
1293
s32 bankId2;
1294
struct PatchStruct patchStruct;
1295
alSeqFile = gAlTbl;
1296
if (audioBank->timer >= 2) {
1297
audioBank->timer--;
1298
return;
1299
}
1300
if (audioBank->timer == 1) {
1301
audioBank->timer = 0;
1302
} else {
1303
if (audioResetStatus != 0) {
1304
osRecvMesg(&audioBank->dmaRetQueue, NULL, OS_MESG_BLOCK);
1305
audioBank->inProgress = 0;
1306
return;
1307
}
1308
if (osRecvMesg(&audioBank->dmaRetQueue, NULL, OS_MESG_NOBLOCK) == -1) {
1309
return;
1310
}
1311
}
1312
1313
encodedInfo = &audioBank->encodedInfo;
1314
if (audioBank->remaining == 0) {
1315
mesg = (OSMesg) audioBank->encodedInfo;
1316
#pragma GCC diagnostic push
1317
#if defined(__clang__)
1318
#pragma GCC diagnostic ignored "-Wself-assign"
1319
#endif
1320
mesg = mesg; //! needs an extra read from mesg here to match...
1321
#pragma GCC diagnostic pop
1322
temp = *encodedInfo;
1323
bankId = (temp >> 8) & 0xFF;
1324
switch ((u8) (temp >> 0x10)) {
1325
case 0:
1326
if (gSeqLoadStatus[bankId] != SOUND_LOAD_STATUS_5) {
1327
gSeqLoadStatus[bankId] = (u8) (temp & 0xFF);
1328
}
1329
break;
1330
case 2:
1331
if (gUnkLoadStatus[bankId] != SOUND_LOAD_STATUS_5) {
1332
gUnkLoadStatus[bankId] = (u8) (temp & 0xFF);
1333
}
1334
break;
1335
case 1:
1336
if (gBankLoadStatus[bankId] != SOUND_LOAD_STATUS_5) {
1337
gBankLoadStatus[bankId] = (u8) (temp & 0xFF);
1338
}
1339
bankId1 = gCtlEntries[bankId].bankId1;
1340
bankId2 = gCtlEntries[bankId].bankId2;
1341
patchStruct.bankId1 = bankId1;
1342
patchStruct.bankId2 = bankId2;
1343
if (bankId1 != 0xFF) {
1344
patchStruct.baseAddr1 = func_sh_802f3598(bankId1, &patchStruct.medium1);
1345
} else {
1346
patchStruct.baseAddr1 = NULL;
1347
}
1348
if (bankId2 != 0xFF) {
1349
patchStruct.baseAddr2 = func_sh_802f3598(bankId2, &patchStruct.medium2);
1350
} else {
1351
patchStruct.baseAddr2 = NULL;
1352
}
1353
1354
func_sh_802f5310(bankId, audioBank->audioBank, &patchStruct, 1);
1355
break;
1356
}
1357
mesg = (OSMesg) audioBank->encodedInfo;
1358
audioBank->inProgress = 0;
1359
osSendMesg(audioBank->retQueue, mesg, OS_MESG_NOBLOCK);
1360
} else if (audioBank->remaining < audioBank->transferSize) {
1361
if (audioBank->medium == 1) {
1362
func_sh_802f517c(audioBank->devAddr, audioBank->vAddr, audioBank->remaining, alSeqFile->unk2);
1363
} else {
1364
func_sh_802f50ec(audioBank, audioBank->remaining);
1365
}
1366
1367
audioBank->remaining = 0;
1368
} else {
1369
if (audioBank->medium == 1) {
1370
func_sh_802f517c(audioBank->devAddr, audioBank->vAddr, audioBank->transferSize, alSeqFile->unk2);
1371
} else {
1372
func_sh_802f50ec(audioBank, audioBank->transferSize);
1373
}
1374
1375
audioBank->remaining -= audioBank->transferSize;
1376
audioBank->devAddr += audioBank->transferSize;
1377
audioBank->vAddr = ((u8 *) audioBank->vAddr) + audioBank->transferSize;
1378
}
1379
}
1380
1381
extern char shindouDebugPrint110[]; // "BGCOPY"
1382
void func_sh_802f50ec(struct PendingDmaAudioBank *arg0, size_t len) {
1383
len += 0xf;
1384
len &= ~0xf;
1385
osInvalDCache(arg0->vAddr, len);
1386
osCreateMesgQueue(&arg0->dmaRetQueue, arg0->mesgs, 1);
1387
func_sh_802f3dd0(&arg0->ioMesg, 0, 0, arg0->devAddr, arg0->vAddr, len, &arg0->dmaRetQueue, arg0->medium, shindouDebugPrint110);
1388
}
1389
1390
1391
void func_sh_802f517c(uintptr_t devAddr, void *vAddr, size_t nbytes, s32 arg3) {
1392
uintptr_t sp1C;
1393
1394
sp1C = devAddr;
1395
osInvalDCache(vAddr, nbytes);
1396
func_sh_802f3ed4(func_sh_802f3ec4(arg3, &sp1C), sp1C, vAddr, nbytes);
1397
}
1398
1399
void patch_sound(struct AudioBankSound *sound, struct AudioBank *memBase, struct PatchStruct *patchInfo) {
1400
struct AudioBankSample *sample;
1401
void *patched;
1402
1403
#define PATCH(x, base) (patched = (void *)((uintptr_t) (x) + (uintptr_t) base))
1404
1405
if ((uintptr_t) sound->sample <= 0x80000000) {
1406
sample = sound->sample = PATCH(sound->sample, memBase);
1407
if (sample->size != 0 && sample->isPatched != TRUE) {
1408
sample->loop = PATCH(sample->loop, memBase);
1409
sample->book = PATCH(sample->book, memBase);
1410
switch (sample->medium) {
1411
case 0:
1412
sample->sampleAddr = PATCH(sample->sampleAddr, patchInfo->baseAddr1);
1413
sample->medium = patchInfo->medium1;
1414
break;
1415
case 1:
1416
sample->sampleAddr = PATCH(sample->sampleAddr, patchInfo->baseAddr2);
1417
sample->medium = patchInfo->medium2;
1418
break;
1419
1420
case 2:
1421
case 3:
1422
break;
1423
}
1424
sample->isPatched = TRUE;
1425
if (sample->bit1 && sample->medium != 0) {
1426
D_SH_8034EA88[D_SH_8034F688++] = sample;
1427
}
1428
}
1429
}
1430
#undef PATCH
1431
}
1432
1433
BAD_RETURN(s32) func_sh_802f5310(s32 bankId, struct AudioBank *mem, struct PatchStruct *patchInfo, s32 arg3) {
1434
UNUSED u32 pad[2];
1435
u8 *addr;
1436
UNUSED u32 pad1[3];
1437
s32 sp4C;
1438
struct AudioBankSample *temp_s0;
1439
s32 i;
1440
uintptr_t count;
1441
s32 temp;
1442
1443
sp4C = 0;
1444
if (D_SH_8034F68C != 0) {
1445
sp4C = 1;
1446
} else {
1447
D_SH_80343CF0 = 0;
1448
}
1449
D_SH_8034F688 = 0;
1450
patch_audio_bank(bankId, mem, patchInfo);
1451
1452
count = 0;
1453
for (i = 0; i < D_SH_8034F688; i++) {
1454
count += ALIGN16(D_SH_8034EA88[i]->size);
1455
}
1456
1457
for (i = 0; i < D_SH_8034F688; i++) {
1458
if (D_SH_8034F68C != 0x78) {
1459
temp_s0 = D_SH_8034EA88[i];
1460
switch (arg3) {
1461
case 0:
1462
temp = temp_s0->medium = patchInfo->medium1;
1463
if (temp != 0) {
1464
if (temp_s0->size) {
1465
}
1466
addr = func_sh_802f1d90(temp_s0->size, patchInfo->bankId1, temp_s0->sampleAddr, temp_s0->medium);
1467
} else {
1468
temp = temp_s0->medium = patchInfo->medium2;
1469
if (temp != 0) {
1470
addr = func_sh_802f1d90(temp_s0->size, patchInfo->bankId2, temp_s0->sampleAddr, temp_s0->medium);
1471
}
1472
}
1473
break;
1474
1475
case 1:
1476
temp = temp_s0->medium = patchInfo->medium1;
1477
if (temp != 0) {
1478
addr = func_sh_802f1d40(temp_s0->size, patchInfo->bankId1, temp_s0->sampleAddr, temp_s0->medium);
1479
} else {
1480
temp = temp_s0->medium = patchInfo->medium2;
1481
if (temp != 0) {
1482
addr = func_sh_802f1d40(temp_s0->size, patchInfo->bankId2, temp_s0->sampleAddr, temp_s0->medium);
1483
}
1484
}
1485
break;
1486
}
1487
switch ((uintptr_t) addr) {
1488
case 0:
1489
break;
1490
default:
1491
switch (arg3) {
1492
case 0:
1493
if (temp_s0->medium == 1) {
1494
func_sh_802f3d78((uintptr_t) temp_s0->sampleAddr, addr, temp_s0->size, gAlTbl->unk2);
1495
temp_s0->sampleAddr = addr;
1496
temp_s0->medium = 0;
1497
} else {
1498
func_sh_802f3c38((uintptr_t) temp_s0->sampleAddr, addr, temp_s0->size, temp_s0->medium);
1499
temp_s0->sampleAddr = addr;
1500
temp_s0->medium = 0;
1501
}
1502
break;
1503
1504
case 1:
1505
D_SH_8034EC88[D_SH_8034F68C].sample = temp_s0;
1506
D_SH_8034EC88[D_SH_8034F68C].ramAddr = addr;
1507
D_SH_8034EC88[D_SH_8034F68C].encodedInfo = (D_SH_8034F68C << 24) | 0xffffff;
1508
D_SH_8034EC88[D_SH_8034F68C].isFree = FALSE;
1509
D_SH_8034EC88[D_SH_8034F68C].endAndMediumIdentification = temp_s0->sampleAddr + temp_s0->size + temp_s0->medium;
1510
D_SH_8034F68C++;
1511
break;
1512
}
1513
}
1514
continue;
1515
}
1516
break;
1517
}
1518
1519
D_SH_8034F688 = 0;
1520
if (D_SH_8034F68C != 0 && sp4C == 0) {
1521
temp_s0 = D_SH_8034EC88[D_SH_8034F68C - 1].sample;
1522
temp = (temp_s0->size >> 12);
1523
temp += 1;
1524
count = (uintptr_t) temp_s0->sampleAddr;
1525
func_sh_802f4cb4(
1526
count,
1527
D_SH_8034EC88[D_SH_8034F68C - 1].ramAddr,
1528
temp_s0->size,
1529
temp_s0->medium,
1530
temp,
1531
&gUnkQueue2,
1532
D_SH_8034EC88[D_SH_8034F68C - 1].encodedInfo);
1533
}
1534
}
1535
1536
s32 func_sh_802f573c(s32 audioResetStatus) {
1537
struct AudioBankSample *sample;
1538
u32 idx;
1539
u8 *sampleAddr;
1540
u32 size;
1541
s32 unk;
1542
u8 *added;
1543
1544
if (D_SH_8034F68C > 0) {
1545
if (audioResetStatus != 0) {
1546
if (osRecvMesg(&gUnkQueue2, (OSMesg *) &idx, OS_MESG_NOBLOCK)){
1547
}
1548
D_SH_8034F68C = 0;
1549
return 0;
1550
}
1551
if (osRecvMesg(&gUnkQueue2, (OSMesg *) &idx, OS_MESG_NOBLOCK) == -1) {
1552
return 0;
1553
}
1554
idx >>= 0x18;
1555
if (D_SH_8034EC88[idx].isFree == FALSE) {
1556
sample = D_SH_8034EC88[idx].sample;
1557
added = (sample->sampleAddr + sample->size + sample->medium);
1558
if (added == D_SH_8034EC88[idx].endAndMediumIdentification) {
1559
sample->sampleAddr = D_SH_8034EC88[idx].ramAddr;
1560
sample->medium = 0;
1561
}
1562
D_SH_8034EC88[idx].isFree = TRUE;
1563
}
1564
1565
next:
1566
if (D_SH_8034F68C > 0) {
1567
if (D_SH_8034EC88[D_SH_8034F68C - 1].isFree == TRUE) {
1568
D_SH_8034F68C--;
1569
goto next;
1570
}
1571
sample = D_SH_8034EC88[D_SH_8034F68C - 1].sample;
1572
sampleAddr = sample->sampleAddr;
1573
size = sample->size;
1574
unk = size >> 0xC;
1575
unk += 1;
1576
added = ((sampleAddr + size) + sample->medium);
1577
if (added != D_SH_8034EC88[D_SH_8034F68C - 1].endAndMediumIdentification) {
1578
D_SH_8034EC88[D_SH_8034F68C - 1].isFree = TRUE;
1579
D_SH_8034F68C--;
1580
goto next;
1581
}
1582
size = sample->size;
1583
func_sh_802f4cb4((uintptr_t) sampleAddr, D_SH_8034EC88[D_SH_8034F68C - 1].ramAddr, size, sample->medium,
1584
unk, &gUnkQueue2, D_SH_8034EC88[D_SH_8034F68C - 1].encodedInfo);
1585
}
1586
}
1587
return 1;
1588
}
1589
1590
s32 func_sh_802f5900(struct AudioBankSample *sample, s32 numLoaded, struct AudioBankSample *arg2[]) {
1591
s32 i;
1592
1593
for (i = 0; i < numLoaded; i++) {
1594
if (sample->sampleAddr == arg2[i]->sampleAddr) {
1595
break;
1596
}
1597
}
1598
if (i == numLoaded) {
1599
arg2[numLoaded++] = sample;
1600
}
1601
return numLoaded;
1602
}
1603
1604
s32 func_sh_802f5948(s32 bankId, struct AudioBankSample *list[]) {
1605
s32 i;
1606
struct Drum *drum;
1607
struct Instrument *inst;
1608
s32 numLoaded;
1609
s32 numDrums;
1610
s32 numInstruments;
1611
1612
numLoaded = 0;
1613
numDrums = gCtlEntries[bankId].numDrums;
1614
numInstruments = gCtlEntries[bankId].numInstruments;
1615
1616
for (i = 0; i < numDrums; i++) {
1617
drum = get_drum(bankId, i);
1618
if (drum == NULL) {
1619
continue;
1620
}
1621
numLoaded = func_sh_802f5900(drum->sound.sample, numLoaded, list);
1622
}
1623
for (i = 0; i < numInstruments; i++) {
1624
inst = get_instrument_inner(bankId, i);
1625
if (inst == NULL) {
1626
continue;
1627
1628
}
1629
if (inst->normalRangeLo != 0) {
1630
numLoaded = func_sh_802f5900(inst->lowNotesSound.sample, numLoaded, list);
1631
}
1632
if (inst->normalRangeHi != 127) {
1633
numLoaded = func_sh_802f5900(inst->highNotesSound.sample, numLoaded, list);
1634
}
1635
numLoaded = func_sh_802f5900(inst->normalNotesSound.sample, numLoaded, list);
1636
}
1637
return numLoaded;
1638
}
1639
#endif
1640
1641