sys_audio_C870.c Initial work (#135)

* func_8000BFE8

* func_8000BF6C

* func_8000BFD8

* func_8000BF94

* func_8000BFA8

* func_8000E1C4

* func_8000DBE4

* func_8000C0C0

* func_8000C1F8

* func_8000C13C

* matching

* various fixes

* AudioHeap_SearchRegularCaches

* func_8000CAF4

* func_8000DC84

* func_8000DC84

* .

* sf64 audio provisional header

* .
This commit is contained in:
Alejandro Asenjo Nitti 2024-02-18 12:43:21 -03:00 committed by GitHub
parent 0b13c0edef
commit e3b26ca666
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 1322 additions and 32 deletions

View file

@ -62,7 +62,8 @@
"sys.h": "c",
"fox_option_assets.h": "c",
"mods.h": "c",
"i5.h": "c"
"i5.h": "c",
"sf64audio_provisional.h": "c"
},
"C_Cpp_Runner.msvcBatchPath": ""
}

View file

@ -252,6 +252,7 @@ $(shell mkdir -p $(BUILD_DIR)/linker_scripts/$(VERSION) $(BUILD_DIR)/linker_scri
# per-file flags
build/src/main/sys_audio_17650.o: OPTFLAGS := -O2 -g0
build/src/main/sys_audio_C870.o: OPTFLAGS := -O2 -g0
build/src/main/sys_audio_1EB50.o: OPTFLAGS := -O1 -g0
build/src/main/sys_sprintf.o: OPTFLAGS := -O2 -g0
build/src/main/sys_math64.o: OPTFLAGS := -O2 -g0

28
include/alignment.h Normal file
View file

@ -0,0 +1,28 @@
#ifndef ALIGNMENT_H
#define ALIGNMENT_H
#define ALIGN8(val) (((val) + 7) & ~7)
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
#define ALIGN32(val) (((val) + 0x1F) & ~0x1F)
#define ALIGN64(val) (((val) + 0x3F) & ~0x3F)
#define ALIGN256(val) (((val) + 0xFF) & ~0xFF)
#ifdef __GNUC__
#define ALIGNED8 __attribute__ ((aligned (8)))
#else
#define ALIGNED8
#endif
#ifdef __sgi /* IDO compiler */
#define ALIGNOF(x) __builtin_alignof(x)
#elif (__STDC_VERSION__ >= 201112L) /* C11 */
#define ALIGNOF(x) _Alignof(x)
#else /* __GNUC__ */
#define ALIGNOF(x) __alignof__(x)
#endif
#define ALIGN_MASK(n) (~((n) - 1))
#define ALIGNOF_MASK(x) ALIGN_MASK(ALIGNOF(x))
#endif

View file

@ -1,6 +1,8 @@
#ifndef MACROS_H
#define MACROS_H
#include "alignment.h"
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240

File diff suppressed because it is too large Load diff

View file

@ -29,34 +29,34 @@ func_8000BC70 = 0x8000BC70;
func_8000BD38 = 0x8000BD38;
func_8000BE24 = 0x8000BE24;
func_8000BE94 = 0x8000BE94;
func_8000BF14 = 0x8000BF14;
func_8000BF6C = 0x8000BF6C;
func_8000BF94 = 0x8000BF94;
func_8000BFA8 = 0x8000BFA8;
func_8000BFD8 = 0x8000BFD8;
AudioHeap_Alloc = 0x8000BF14;
AudioHeap_InitPool = 0x8000BF6C;
AudioHeap_InitPersistentCache = 0x8000BF94;
AudioHeap_InitTemporaryCache = 0x8000BFA8;
AudioHeap_ResetPool = 0x8000BFD8;
func_8000BFE8 = 0x8000BFE8;
func_8000C044 = 0x8000C044;
func_8000C0C0 = 0x8000C0C0;
func_8000C13C = 0x8000C13C;
func_8000C1F8 = 0x8000C1F8;
func_8000C2B4 = 0x8000C2B4;
func_8000C990 = 0x8000C990;
func_8000C9E8 = 0x8000C9E8;
AudioHeap_SearchCaches = 0x8000C990;
AudioHeap_SearchRegularCaches = 0x8000C9E8;
func_8000CAF4 = 0x8000CAF4;
func_8000CEC8 = 0x8000CEC8;
func_8000D08C = 0x8000D08C;
func_8000D104 = 0x8000D104;
func_8000D4A8 = 0x8000D4A8;
func_8000DB0C = 0x8000DB0C;
AudioHeap_SearchPermanentCache = 0x8000DB0C;
func_8000DB64 = 0x8000DB64;
func_8000DBE4 = 0x8000DBE4;
func_8000DC34 = 0x8000DC34;
func_8000DC84 = 0x8000DC84;
func_8000DCD4 = 0x8000DCD4;
func_8000DD68 = 0x8000DD68;
AudioHeap_AllocTemporarySampleCacheEntry = 0x8000DD68;
func_8000DFFC = 0x8000DFFC;
func_8000E1C4 = 0x8000E1C4;
func_8000E208 = 0x8000E208;
AudioHeap_AllocPersistentSampleCacheEntry = 0x8000E208;
func_8000E290 = 0x8000E290;

View file

@ -1,4 +1,54 @@
#include "common.h"
#include "global.h"
#include "sf64audio_provisional.h"
typedef struct {
/* 0x00 */ s32 unk_00;
/* 0x04 */ s32 unk_04;
/* 0x08 */ s32 unk_08;
/* 0x0C */ s32 unk_0C;
/* 0x10 */ s32 unk_10;
/* 0x14 */ s32 unk_14;
/* 0x18 */ char pad_18[0x6];
/* 0x1E */ s16 unk_1E;
/* 0x20 */ s32 unk_20;
/* 0x24 */ char pad24[0x6];
/* 0x2A */ s16 unk_2A;
} UnkStruct_func_8000BFA8;
typedef struct {
/* 0x00 */ char pad00;
/* 0x01 */ s8 unk_01;
/* 0x02 */ s8 unk_02;
/* 0x03 */ char pad[0x5];
/* 0x08 */ s32 unk_08;
/* 0x08 */ s32 unk_0C;
} UnkStruct_8000E1C4_1;
typedef struct {
/* 0x00 */ u8 unk_00;
/* 0x04 */ s32 unk_04;
} UnkStruct_8000E1C4_2;
extern s32 D_800C7C30;
extern AudioAllocPool D_8014C1C0;
extern AudioAllocPool D_8014C1D0;
extern AudioAllocPool D_8014C1E0;
extern AudioAllocPool D_8014C210;
extern AudioAllocPool D_8014C220;
extern AudioAllocPool D_8014C230;
extern AudioPersistentCache D_8014C240; // seqCache
extern AudioTemporaryCache D_8014C3D4; // fontCache
extern AudioAllocPool D_8014C3D8;
extern AudioPersistentCache D_8014C410;
extern AudioAllocPool D_8014C420;
extern AudioTemporaryCache D_8014C5A4;
extern AudioPersistentCache D_8014C5E0; // sampleBankCache
extern AudioTemporaryCache D_8014C774;
SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(s32);
void* AudioHeap_SearchRegularCaches(s32 tableType, s32 cache, s32 id);
void* AudioHeap_SearchPermanentCache(s32 tableType, s32 id);
SampleCacheEntry* AudioHeap_AllocPersistentSampleCacheEntry(u32);
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000BC70.s")
@ -8,60 +58,241 @@
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000BE94.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000BF14.s")
void* AudioHeap_Alloc(AudioAllocPool* pool, u32 size) {
u32 aligned = ALIGN16(size);
u8* ramAddr = pool->curRamAddr;
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000BF6C.s")
if (pool->startRamAddr + pool->size >= pool->curRamAddr + aligned) {
pool->curRamAddr += aligned;
} else {
return NULL;
}
pool->numEntries++;
return ramAddr;
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000BF94.s")
void AudioHeap_InitPool(AudioAllocPool* pool, void* ramAddr, u32 size) {
pool->curRamAddr = pool->startRamAddr = (u8*) ALIGN16((u32) ramAddr);
pool->size = size - ((u32) ramAddr & 0xF);
pool->numEntries = 0;
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000BFA8.s")
void AudioHeap_InitPersistentCache(AudioPersistentCache* persistent) {
persistent->pool.numEntries = 0;
persistent->numEntries = 0;
persistent->pool.curRamAddr = persistent->pool.startRamAddr;
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000BFD8.s")
void AudioHeap_InitTemporaryCache(AudioTemporaryCache* temporary) {
temporary->pool.numEntries = 0;
temporary->pool.curRamAddr = temporary->pool.startRamAddr;
temporary->nextSide = 0;
temporary->entries[0].ramAddr = temporary->pool.startRamAddr;
temporary->entries[1].ramAddr = temporary->pool.startRamAddr + temporary->pool.size;
temporary->entries[0].id = -1;
temporary->entries[1].id = -1;
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000BFE8.s")
void AudioHeap_ResetPool(AudioAllocPool* pool) {
pool->numEntries = 0;
pool->curRamAddr = pool->startRamAddr;
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000C044.s")
void func_8000BFE8(s32 arg0) {
AudioHeap_InitPool(&D_8014C1D0, gAudioDataBuffer, arg0);
AudioHeap_InitPool(&D_8014C1C0, &gAudioDataBuffer[arg0], D_800C7C30 - arg0);
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000C0C0.s")
void func_8000C044(AudioSessionPoolSplit* split) {
D_8014C1C0.curRamAddr = D_8014C1C0.startRamAddr;
AudioHeap_InitPool(&D_8014C1E0, AudioHeap_Alloc(&D_8014C1C0, split->miscPoolSize), split->miscPoolSize);
AudioHeap_InitPool(&D_8014C210, AudioHeap_Alloc(&D_8014C1C0, split->cachePoolSize), split->cachePoolSize);
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000C13C.s")
void func_8000C0C0(AudioCommonPoolSplit* split) {
D_8014C210.curRamAddr = D_8014C210.startRamAddr;
AudioHeap_InitPool(&D_8014C220, AudioHeap_Alloc(&D_8014C210, split->seqCacheSize), split->seqCacheSize);
AudioHeap_InitPool(&D_8014C230, AudioHeap_Alloc(&D_8014C210, split->fontCacheSize), split->fontCacheSize);
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000C1F8.s")
void func_8000C13C(AudioCommonPoolSplit* split) {
D_8014C220.curRamAddr = D_8014C220.startRamAddr;
AudioHeap_InitPool(&D_8014C240.pool, AudioHeap_Alloc(&D_8014C220, split->seqCacheSize), split->seqCacheSize);
AudioHeap_InitPool(&D_8014C410.pool, AudioHeap_Alloc(&D_8014C220, split->fontCacheSize), split->fontCacheSize);
AudioHeap_InitPool(&D_8014C5E0.pool, AudioHeap_Alloc(&D_8014C220, split->sampleBankCacheSize),
split->sampleBankCacheSize);
AudioHeap_InitPersistentCache(&D_8014C240);
AudioHeap_InitPersistentCache(&D_8014C410);
AudioHeap_InitPersistentCache(&D_8014C5E0);
}
void func_8000C1F8(AudioCommonPoolSplit* split) {
D_8014C230.curRamAddr = D_8014C230.startRamAddr;
AudioHeap_InitPool(&D_8014C3D4.pool, AudioHeap_Alloc(&D_8014C230, split->seqCacheSize), split->seqCacheSize);
AudioHeap_InitPool(&D_8014C5A4.pool, AudioHeap_Alloc(&D_8014C230, split->fontCacheSize), split->fontCacheSize);
AudioHeap_InitPool(&D_8014C774.pool, AudioHeap_Alloc(&D_8014C230, split->sampleBankCacheSize),
split->sampleBankCacheSize);
AudioHeap_InitTemporaryCache(&D_8014C3D4);
AudioHeap_InitTemporaryCache(&D_8014C5A4);
AudioHeap_InitTemporaryCache(&D_8014C774);
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000C2B4.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000C990.s")
s32 AudioHeap_SearchCaches(s32 tableType, s32 cache, s32 id) {
void* ramAddr;
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000C9E8.s")
// Always search the permanent cache in addition to the regular ones.
ramAddr = AudioHeap_SearchPermanentCache(tableType, id);
if (ramAddr != NULL) {
return ramAddr;
}
if (cache == CACHE_PERMANENT) {
return NULL;
}
return AudioHeap_SearchRegularCaches(tableType, cache, id);
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000CAF4.s")
void* AudioHeap_SearchRegularCaches(s32 tableType, s32 cache, s32 id) {
u32 i;
AudioCache* loadedCache;
AudioTemporaryCache* temporary;
AudioPersistentCache* persistent;
switch (tableType) {
case SEQUENCE_TABLE:
loadedCache = (AudioCache*) &D_8014C240;
break;
case FONT_TABLE:
loadedCache = (AudioCache*) &D_8014C410;
break;
case SAMPLE_TABLE:
loadedCache = (AudioCache*) &D_8014C5E0;
break;
}
temporary = &loadedCache->temporary;
if (cache == CACHE_TEMPORARY) {
if (temporary->entries[0].id == id) {
temporary->nextSide = 1;
return temporary->entries[0].ramAddr;
} else if (temporary->entries[1].id == id) {
temporary->nextSide = 0;
return temporary->entries[1].ramAddr;
} else {
return NULL;
}
}
persistent = &loadedCache->persistent;
for (i = 0; i < persistent->numEntries; i++) {
if (persistent->entries[i].id == id) {
return persistent->entries[i].ramAddr;
}
}
if (cache == CACHE_EITHER) {
return AudioHeap_SearchCaches(tableType, CACHE_TEMPORARY, id);
}
return NULL;
}
void func_8000CAF4(f32 p, f32 q, u16* out) {
// With the bug below fixed, this mysterious unused function computes two recurrences
// out[0..7] = a_i, out[8..15] = b_i, where
// a_{-2} = b_{-1} = 262159 = 2^18 + 15
// a_{-1} = b_{-2} = 0
// a_i = q * a_{i-1} + p * a_{i-2}
// b_i = q * b_{i-1} + p * b_{i-2}
// These grow exponentially if p < -1 or p + |q| > 1.
s32 i;
f32 tmp[16];
tmp[0] = (f32) (q * 262159.0f);
tmp[8] = (f32) (p * 262159.0f);
tmp[1] = (f32) ((q * p) * 262159.0f);
tmp[9] = (f32) (((p * p) + q) * 262159.0f);
for (i = 2; i < 8; i++) {
//! @bug value should be stored to tmp[i] and tmp[8 + i], otherwise we read
//! garbage in later loop iterations.
out[i] = q * tmp[i - 2] + p * tmp[i - 1];
out[8 + i] = q * tmp[6 + i] + p * tmp[7 + i];
}
for (i = 0; i < 16; i++) {
out[i] = tmp[i];
}
}
// Likely AudioHeap_UpdateReverbs
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000CEC8.s")
// Likely AudioHeap_ClearCurrentAiBuffer
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000D08C.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000D104.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000D4A8.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000DB0C.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/AudioHeap_SearchPermanentCache.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000DB64.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000DBE4.s")
bool func_8000DBE4(s32 size, s32 fontId, s32 sampleAddr, s8 medium) {
SampleCacheEntry* entry = AudioHeap_AllocTemporarySampleCacheEntry(size);
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000DC34.s")
if (entry != NULL) {
entry->sampleBankId = fontId;
entry->sampleAddr = sampleAddr;
entry->origMedium = medium;
return entry->allocatedAddr;
} else {
return false;
}
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000DC84.s")
s32 func_8000DC34(s32 size, s32 fontId, s32 sampleAddr, s8 medium) {
SampleCacheEntry* entry = AudioHeap_AllocPersistentSampleCacheEntry(size);
if (entry != NULL) {
entry->sampleBankId = fontId;
entry->sampleAddr = sampleAddr;
entry->origMedium = medium;
return entry->allocatedAddr;
} else {
return false;
}
}
u8* func_8000DC84(u32 size, s32 fontId, s32 sampleAddr, s8 medium) {
SampleCacheEntry* entry = AudioHeap_AllocPersistentSampleCacheEntry(size);
if (entry != NULL) {
entry->sampleBankId = fontId;
entry->sampleAddr = sampleAddr;
entry->origMedium = medium;
return entry->allocatedAddr;
} else {
return NULL;
}
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000DCD4.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000DD68.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/AudioHeap_AllocTemporarySampleCacheEntry.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000DFFC.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000E1C4.s")
void func_8000E1C4(UnkStruct_8000E1C4_1* arg0, UnkStruct_8000E1C4_2* arg1) {
if ((arg1 != NULL) && (arg1->unk_04 == arg0->unk_08)) {
arg1->unk_04 = arg0->unk_0C;
arg1->unk_00 = (((arg0->unk_01 & 0xFF) * 4) & 0xC) | (arg1->unk_00 & 0xFFF3);
}
}
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000E208.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/AudioHeap_AllocPersistentSampleCacheEntry.s")
#pragma GLOBAL_ASM("asm/us/nonmatchings/main/sys_audio_C870/func_8000E290.s")