You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Refresh 12
This commit is contained in:
@@ -333,11 +333,11 @@ s16 gEuUnknownWave7[256] = {
|
||||
0x0000, 0x8d2e, 0x4e20, 0xe14e, 0x0000, 0x1eb2, 0xb1e0, 0x72d2, 0x0000, 0x8d2e, 0x4e20, 0xe14e,
|
||||
0x0000, 0x1eb2, 0xb1e0, 0x72d2,
|
||||
};
|
||||
// u8 buffer_remove2[764] = { 0 };
|
||||
s16 *gWaveSamples[6] = { sSawtoothWaves, sTriangleWaves, sSineWaves, sSquareWaves, sEuUnknownWave6, gEuUnknownWave7 };
|
||||
#endif
|
||||
|
||||
#ifndef VERSION_EU
|
||||
#else
|
||||
// !VERSION_EU
|
||||
|
||||
s16 sSineWave[0x40] = {
|
||||
0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, 23169, 25329, 27244,
|
||||
28897, 30272, 31356, 32137, 32609, 0x7FFF, 32609, 32137, 31356, 30272, 28897,
|
||||
@@ -584,7 +584,7 @@ f32 gVolRampingRhs128[128] = {
|
||||
s16 gTatumsPerBeat = TATUMS_PER_BEAT;
|
||||
s8 gUnusedCount80333EE8 = UNUSED_COUNT_80333EE8;
|
||||
s32 gAudioHeapSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_HEAP_SIZE);
|
||||
s32 D_80333EF0 = DOUBLE_SIZE_ON_64_BIT(D_80333EF0_VAL);
|
||||
s32 gAudioInitPoolSize = DOUBLE_SIZE_ON_64_BIT(AUDIO_INIT_POOL_SIZE);
|
||||
volatile s32 gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
|
||||
@@ -62,8 +62,8 @@ extern f32 gVolRampingRhs128[128];
|
||||
// non-constant .data
|
||||
extern s16 gTatumsPerBeat;
|
||||
extern s8 gUnusedCount80333EE8;
|
||||
extern s32 gAudioHeapSize;
|
||||
extern s32 D_80333EF0; // amount of heap designated to gAudioInitPool, 0x2500
|
||||
extern s32 gAudioHeapSize; // AUDIO_HEAP_SIZE
|
||||
extern s32 gAudioInitPoolSize; // AUDIO_INIT_POOL_SIZE
|
||||
extern volatile s32 gAudioLoadLock;
|
||||
|
||||
// .bss
|
||||
@@ -103,15 +103,14 @@ extern u16 gUnused80226E98[0x10];
|
||||
|
||||
extern u32 gAudioRandom;
|
||||
|
||||
//make my life easier
|
||||
#ifdef VERSION_EU
|
||||
#define UNUSED_COUNT_80333EE8 24
|
||||
#define AUDIO_HEAP_SIZE 0x2c500
|
||||
#define D_80333EF0_VAL 0x2c00
|
||||
#define AUDIO_INIT_POOL_SIZE 0x2c00
|
||||
#else
|
||||
#define UNUSED_COUNT_80333EE8 16
|
||||
#define AUDIO_HEAP_SIZE 0x31150
|
||||
#define D_80333EF0_VAL 0x2500
|
||||
#define AUDIO_INIT_POOL_SIZE 0x2500
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -502,6 +502,7 @@ s32 adsr_update(struct AdsrState *adsr) {
|
||||
return 0.0f;
|
||||
}
|
||||
if (adsr->current > 1.0f) {
|
||||
eu_stubbed_printf_1("Audio:Envp: overflow %f\n", adsr->current);
|
||||
return 1.0f;
|
||||
}
|
||||
return adsr->current;
|
||||
|
||||
@@ -19,136 +19,6 @@
|
||||
#define EU_FLOAT(x) x
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_EU
|
||||
u8 audioString1[] = "pitch %x: delaybytes %d : olddelay %d\n";
|
||||
u8 audioString2[] = "cont %x: delaybytes %d : olddelay %d\n";
|
||||
u8 audioString3[] = "Warning:Kill Note %x \n";
|
||||
u8 audioString4[] = "Kill Voice %d (ID %d) %d\n";
|
||||
u8 audioString5[] = "Warning: Running Sequence's data disappear!\n";
|
||||
u8 audioString6[] = "Heap OverFlow : Not Allocate %d!\n";
|
||||
u8 audioString7[] = "DataHeap Not Allocate \n";
|
||||
u8 audioString8[] = "StayHeap Not Allocate %d\n";
|
||||
u8 audioString9[] = "AutoHeap Not Allocate %d\n";
|
||||
u8 audioString10[] = "WARNING: NO FREE AUTOSEQ AREA.\n";
|
||||
u8 audioString11[] = "WARNING: NO STOP AUTO AREA.\n";
|
||||
u8 audioString12[] = " AND TRY FORCE TO STOP SIDE \n";
|
||||
u8 audioString13[] = "TWO SIDES ARE LOADING... ALLOC CANCELED.\n";
|
||||
u8 audioString14[] = "WARNING: Before Area Overlaid After.";
|
||||
u8 audioString15[] = "WARNING: After Area Overlaid Before.";
|
||||
u8 audioString16[] = "MEMORY:SzHeapAlloc ERROR: sza->side %d\n";
|
||||
u8 audioString17[] = "MEMORY:StayHeap OVERFLOW.";
|
||||
u8 audioString18[] = "MEMORY:StayHeap OVERFLOW (REQ:%d)";
|
||||
u8 audioString19[] = "Auto Heap Unhit for ID %d\n";
|
||||
u8 audioString20[] = "Cache hit %d at stay %d\n";
|
||||
u8 audioString20_[] = "%d ";
|
||||
u8 audioString20__[] = "\n";
|
||||
u8 audioString20___[] = "%d ";
|
||||
u8 audioString20____[] = "\n";
|
||||
u8 audioString21[] = "Heap Reconstruct Start %x\n";
|
||||
u8 audioString22[] = "SFrame Sample %d %d %d\n";
|
||||
u8 audioString23[] = "AHPBASE %x\n";
|
||||
u8 audioString24[] = "AHPCUR %x\n";
|
||||
u8 audioString25[] = "HeapTop %x\n";
|
||||
u8 audioString26[] = "SynoutRate %d / %d \n";
|
||||
u8 audioString27[] = "FXSIZE %d\n";
|
||||
u8 audioString28[] = "FXCOMP %d\n";
|
||||
u8 audioString29[] = "FXDOWN %d\n";
|
||||
u8 audioString30[] = "WaveCacheLen: %d\n";
|
||||
u8 audioString31[] = "SpecChange Finished\n";
|
||||
u8 audioString31_[] = "";
|
||||
u8 audioString32[] = "Romcopy %x -> %x ,size %x\n";
|
||||
u8 audioString33[] = "Romcopyend\n";
|
||||
u8 audioString34[] = "CAUTION:WAVE CACHE FULL %d";
|
||||
u8 audioString35[] = "BASE %x %x\n";
|
||||
u8 audioString36[] = "LOAD %x %x %x\n";
|
||||
u8 audioString37[] = "INSTTOP %x\n";
|
||||
u8 audioString38[] = "INSTMAP[0] %x\n";
|
||||
u8 audioString39[] = "already flags %d\n";
|
||||
u8 audioString40[] = "already flags %d\n";
|
||||
u8 audioString41[] = "ERR:SLOW BANK DMA BUSY\n";
|
||||
u8 audioString42[] = "ERR:SLOW DMA BUSY\n";
|
||||
u8 audioString43[] = "Check %d bank %d\n";
|
||||
u8 audioString44[] = "Cache Check\n";
|
||||
u8 audioString45[] = "NO BANK ERROR\n";
|
||||
u8 audioString46[] = "BANK %d LOADING START\n";
|
||||
u8 audioString47[] = "BANK %d LOAD MISS (NO MEMORY)!\n";
|
||||
u8 audioString48[] = "BANK %d ALREADY CACHED\n";
|
||||
u8 audioString49[] = "BANK LOAD MISS! FOR %d\n";
|
||||
u8 audioString50[] = "Seq %d Loading Start\n";
|
||||
u8 audioString51[] = "Heap Overflow Error\n";
|
||||
u8 audioString52[] = "SEQ %d ALREADY CACHED\n";
|
||||
u8 audioString53[] = "Ok,one bank slow load Start \n";
|
||||
u8 audioString54[] = "Sorry,too many %d bank is none.fast load Start \n";
|
||||
u8 audioString55[] = "Seq %d:Default Load Id is %d\n";
|
||||
u8 audioString56[] = "Seq Loading Start\n";
|
||||
u8 audioString57[] = "Error:Before Sequence-SlowDma remain.\n";
|
||||
u8 audioString58[] = " Cancel Seq Start.\n";
|
||||
u8 audioString59[] = "SEQ %d ALREADY CACHED\n";
|
||||
u8 audioString60[] = "Clear Workarea %x -%x size %x \n";
|
||||
u8 audioString61[] = "AudioHeap is %x\n";
|
||||
u8 audioString62[] = "Heap reset.Synth Change %x \n";
|
||||
u8 audioString63[] = "Heap %x %x %x\n";
|
||||
u8 audioString64[] = "Main Heap Initialize.\n";
|
||||
u8 audioString65[] = "---------- Init Completed. ------------\n";
|
||||
u8 audioString66[] = " Syndrv :[%6d]\n";
|
||||
u8 audioString67[] = " Seqdrv :[%6d]\n";
|
||||
u8 audioString68[] = " audiodata :[%6d]\n";
|
||||
u8 audioString69[] = "---------------------------------------\n";
|
||||
u8 audioString69_[] = "";
|
||||
u8 audioString70[] = "Audio: setvol: volume minus %f\n";
|
||||
u8 audioString71[] = "Audio: setvol: volume overflow %f\n";
|
||||
u8 audioString72[] = "Audio: setpitch: pitch minus %f\n";
|
||||
u8 audioString73[] = "Audio: voiceman: No bank error %d\n";
|
||||
u8 audioString74[] = "Audio: voiceman: progNo. overflow %d,%d\n";
|
||||
u8 audioString75[] = "Audio: voiceman: progNo. undefined %d,%d\n";
|
||||
u8 audioString76[] = "Audio: voiceman: BAD Voicepointer %x,%d,%d\n";
|
||||
u8 audioString77[] = "Audio: voiceman: Percussion Overflow %d,%d\n";
|
||||
u8 audioString78[] = "Percussion Pointer Error\n";
|
||||
u8 audioString79[] = "Audio: voiceman: Percpointer NULL %d,%d\n";
|
||||
u8 audioString80[] = "CAUTION:SUB IS SEPARATED FROM GROUP";
|
||||
u8 audioString81[] = "Error:Wait Track disappear\n";
|
||||
u8 audioString82[] = "Slow Release Batting\n";
|
||||
u8 audioString83[] = "Audio:Wavemem: Bad voiceno (%d)\n";
|
||||
u8 audioString84[] = "Audio: C-Alloc : Dealloc voice is NULL\n";
|
||||
u8 audioString85[] = "Alloc Error:Dim voice-Alloc %d";
|
||||
u8 audioString86[] = "Error:Same List Add\n";
|
||||
u8 audioString87[] = "Already Cut\n";
|
||||
u8 audioString88[] = "Audio: C-Alloc : lowerPrio is NULL\n";
|
||||
u8 audioString89[] = "Sub Limited Warning: Drop Voice";
|
||||
u8 audioString90[] = "Warning: Drop Voice";
|
||||
u8 audioString91[] = "Warning: Drop Voice";
|
||||
u8 audioString92[] = "Warning: Drop Voice";
|
||||
u8 audioString93[] = "Audio:Envp: overflow %f\n";
|
||||
u8 audioString93_[] = "";
|
||||
u8 audioString94[] = "Audio:Track:Warning: No Free Notetrack\n";
|
||||
u8 audioString95[] = "SUBTRACK DIM\n";
|
||||
u8 audioString96[] = "Audio:Track: Warning SUBTRACK PARENT CHANGED\n";
|
||||
u8 audioString97[] = "GROUP 0:";
|
||||
u8 audioString98[] = "GROUP 1:";
|
||||
u8 audioString99[] = "SEQID %d,BANKID %d\n";
|
||||
u8 audioString100[] = "ERR:SUBTRACK %d NOT ALLOCATED\n";
|
||||
u8 audioString101[] = "Error:Same List Add\n";
|
||||
u8 audioString102[] = "Macro Level Over Error!\n";
|
||||
u8 audioString103[] = "Macro Level Over Error!\n";
|
||||
u8 audioString104[] = "WARNING: NPRG: cannot change %d\n";
|
||||
u8 audioString105[] = "Audio:Track:NOTE:UNDEFINED NOTE COM. %x\n";
|
||||
u8 audioString106[] = "Audio: Note:Velocity Error %d\n";
|
||||
u8 audioString107[] = "Error: Your assignchannel is stolen.\n";
|
||||
u8 audioString108[] = "Audio:Track :Call Macro Level Over Error!\n";
|
||||
u8 audioString109[] = "Audio:Track :Loops Macro Level Over Error!\n";
|
||||
u8 audioString110[] = "SUB:ERR:BANK %d NOT CACHED.\n";
|
||||
u8 audioString111[] = "SUB:ERR:BANK %d NOT CACHED.\n";
|
||||
u8 audioString112[] = "Audio:Track: CTBLCALL Macro Level Over Error!\n";
|
||||
u8 audioString113[] = "Err :Sub %x ,address %x:Undefined SubTrack Function %x";
|
||||
u8 audioString114[] = "Disappear Sequence or Bank %d\n";
|
||||
u8 audioString115[] = "Macro Level Over Error!\n";
|
||||
u8 audioString116[] = "Macro Level Over Error!\n";
|
||||
u8 audioString117[] = "Group:Undefine upper C0h command (%x)\n";
|
||||
u8 audioString118[] = "Group:Undefined Command\n";
|
||||
u8 audioString118_[] = "";
|
||||
u8 audioString118__[] = "";
|
||||
#endif
|
||||
|
||||
// N.B. sound banks are different from the audio banks referred to in other
|
||||
// files. We should really fix our naming to be less ambiguous...
|
||||
#define MAX_BG_MUSIC_QUEUE_SIZE 6
|
||||
@@ -160,15 +30,6 @@ u8 audioString118__[] = "";
|
||||
#define SAMPLES_TO_OVERPRODUCE 0x10
|
||||
#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x40
|
||||
|
||||
// No-op printf macro which leaves string literals in rodata in IDO. (IDO
|
||||
// doesn't support variadic macros, so instead they let the parameter list
|
||||
// expand to a no-op comma expression.) See also goddard/gd_main.h.
|
||||
#ifdef __sgi
|
||||
#define stubbed_printf
|
||||
#else
|
||||
#define stubbed_printf(...)
|
||||
#endif
|
||||
|
||||
struct Sound {
|
||||
s32 soundBits;
|
||||
f32 *position;
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
extern s32 gAudioErrorFlags;
|
||||
extern f32 gDefaultSoundArgs[3];
|
||||
|
||||
// defined in data.c, used by the game
|
||||
extern u32 gAudioRandom;
|
||||
|
||||
extern u8 gAudioSPTaskYieldBuffer[]; // ucode yield data ptr; only used in JP
|
||||
|
||||
struct SPTask *create_next_audio_frame_task(void);
|
||||
|
||||
104
src/audio/heap.c
104
src/audio/heap.c
@@ -167,11 +167,17 @@ void discard_bank(s32 bankId) {
|
||||
struct Note *note = &gNotes[i];
|
||||
|
||||
#ifdef VERSION_EU
|
||||
if (note->noteSubEu.bankId == bankId) {
|
||||
if (note->noteSubEu.bankId == bankId)
|
||||
#else
|
||||
if (note->bankId == bankId) {
|
||||
if (note->bankId == bankId)
|
||||
#endif
|
||||
{
|
||||
// (These prints are unclear. Arguments are picked semi-randomly.)
|
||||
eu_stubbed_printf_1("Warning:Kill Note %x \n", i);
|
||||
if (note->priority >= NOTE_PRIORITY_MIN) {
|
||||
eu_stubbed_printf_3("Kill Voice %d (ID %d) %d\n", note->waveId,
|
||||
bankId, note->priority);
|
||||
eu_stubbed_printf_0("Warning: Running Sequence's data disappear!\n");
|
||||
note->parentLayer->enabled = FALSE;
|
||||
note->parentLayer->finished = TRUE;
|
||||
}
|
||||
@@ -209,6 +215,7 @@ void *soundAlloc(struct SoundAllocPool *pool, u32 size) {
|
||||
*pos = 0;
|
||||
}
|
||||
} else {
|
||||
eu_stubbed_printf_1("Heap OverFlow : Not Allocate %d!\n", size);
|
||||
return NULL;
|
||||
}
|
||||
return start;
|
||||
@@ -309,7 +316,7 @@ static void unused_803163D4(void) {
|
||||
void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg3, s32 id) {
|
||||
// arg3 = 0, 1 or 2?
|
||||
|
||||
struct TemporaryPool *tp; // sp30
|
||||
struct TemporaryPool *tp;
|
||||
struct PersistentPool *persistent = &arg0->persistent;
|
||||
struct SoundAllocPool *pool;
|
||||
void *ret;
|
||||
@@ -342,17 +349,17 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
|
||||
isSound = TRUE;
|
||||
}
|
||||
|
||||
firstVal = (tp->entries[0].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[0].id]); // a3, a2
|
||||
secondVal = (tp->entries[1].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[1].id]); // a1
|
||||
firstVal = (tp->entries[0].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[0].id]);
|
||||
secondVal = (tp->entries[1].id == (s8)nullID ? SOUND_LOAD_STATUS_NOT_LOADED : table[tp->entries[1].id]);
|
||||
|
||||
#ifndef VERSION_EU
|
||||
leftNotLoaded = (firstVal == SOUND_LOAD_STATUS_NOT_LOADED);
|
||||
leftDiscardable = (firstVal == SOUND_LOAD_STATUS_DISCARDABLE); // t0
|
||||
leftDiscardable = (firstVal == SOUND_LOAD_STATUS_DISCARDABLE);
|
||||
leftAvail = (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS);
|
||||
rightNotLoaded = (secondVal == SOUND_LOAD_STATUS_NOT_LOADED);
|
||||
rightDiscardable = (secondVal == SOUND_LOAD_STATUS_DISCARDABLE);
|
||||
rightAvail = (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS);
|
||||
bothDiscardable = (leftDiscardable && rightDiscardable); // a0
|
||||
bothDiscardable = (leftDiscardable && rightDiscardable);
|
||||
|
||||
if (leftNotLoaded) {
|
||||
tp->nextSide = 0;
|
||||
@@ -360,7 +367,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
|
||||
tp->nextSide = 1;
|
||||
} else if (bothDiscardable) {
|
||||
// Use the opposite side from last time.
|
||||
} else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) { //??!
|
||||
} else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) { // ??! (I blame copt)
|
||||
tp->nextSide = 0;
|
||||
} else if (rightDiscardable) {
|
||||
tp->nextSide = 1;
|
||||
@@ -373,27 +380,42 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
if (0) {
|
||||
// It's unclear where these string literals go.
|
||||
eu_stubbed_printf_0("DataHeap Not Allocate \n");
|
||||
eu_stubbed_printf_1("StayHeap Not Allocate %d\n", 0);
|
||||
eu_stubbed_printf_1("AutoHeap Not Allocate %d\n", 0);
|
||||
}
|
||||
|
||||
if (firstVal == SOUND_LOAD_STATUS_NOT_LOADED) {
|
||||
tp->nextSide = 0;
|
||||
} else if (secondVal == SOUND_LOAD_STATUS_NOT_LOADED) {
|
||||
tp->nextSide = 1;
|
||||
} else if ((firstVal == SOUND_LOAD_STATUS_DISCARDABLE) && (secondVal == SOUND_LOAD_STATUS_DISCARDABLE)) {
|
||||
// Use the opposite side from last time.
|
||||
} else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) {
|
||||
tp->nextSide = 0;
|
||||
} else if (secondVal == SOUND_LOAD_STATUS_DISCARDABLE) {
|
||||
tp->nextSide = 1;
|
||||
} else if (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
|
||||
tp->nextSide = 0;
|
||||
} else if (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
|
||||
tp->nextSide = 1;
|
||||
} else {
|
||||
// Both left and right sides are being loaded into.
|
||||
return NULL;
|
||||
eu_stubbed_printf_0("WARNING: NO FREE AUTOSEQ AREA.\n");
|
||||
if ((firstVal == SOUND_LOAD_STATUS_DISCARDABLE) && (secondVal == SOUND_LOAD_STATUS_DISCARDABLE)) {
|
||||
// Use the opposite side from last time.
|
||||
} else if (firstVal == SOUND_LOAD_STATUS_DISCARDABLE) {
|
||||
tp->nextSide = 0;
|
||||
} else if (secondVal == SOUND_LOAD_STATUS_DISCARDABLE) {
|
||||
tp->nextSide = 1;
|
||||
} else {
|
||||
eu_stubbed_printf_0("WARNING: NO STOP AUTO AREA.\n");
|
||||
eu_stubbed_printf_0(" AND TRY FORCE TO STOP SIDE \n");
|
||||
if (firstVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
|
||||
tp->nextSide = 0;
|
||||
} else if (secondVal != SOUND_LOAD_STATUS_IN_PROGRESS) {
|
||||
tp->nextSide = 1;
|
||||
} else {
|
||||
// Both left and right sides are being loaded into.
|
||||
eu_stubbed_printf_0("TWO SIDES ARE LOADING... ALLOC CANCELED.\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pool = &arg0->temporary.pool; // a1
|
||||
pool = &arg0->temporary.pool;
|
||||
if (tp->entries[tp->nextSide].id != (s8)nullID) {
|
||||
table[tp->entries[tp->nextSide].id] = SOUND_LOAD_STATUS_NOT_LOADED;
|
||||
if (isSound == TRUE) {
|
||||
@@ -410,6 +432,8 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
|
||||
pool->cur = pool->start + size;
|
||||
|
||||
if (tp->entries[1].ptr < pool->cur) {
|
||||
eu_stubbed_printf_0("WARNING: Before Area Overlaid After.");
|
||||
|
||||
// Throw out the entry on the other side if it doesn't fit.
|
||||
// (possible @bug: what if it's currently being loaded?)
|
||||
table[tp->entries[1].id] = SOUND_LOAD_STATUS_NOT_LOADED;
|
||||
@@ -444,6 +468,8 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
|
||||
tp->entries[1].size = size;
|
||||
|
||||
if (tp->entries[1].ptr < pool->cur) {
|
||||
eu_stubbed_printf_0("WARNING: After Area Overlaid Before.");
|
||||
|
||||
table[tp->entries[0].id] = SOUND_LOAD_STATUS_NOT_LOADED;
|
||||
|
||||
switch (isSound) {
|
||||
@@ -463,6 +489,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
|
||||
break;
|
||||
|
||||
default:
|
||||
eu_stubbed_printf_1("MEMORY:SzHeapAlloc ERROR: sza->side %d\n", tp->nextSide);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -486,6 +513,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
|
||||
{
|
||||
switch (arg3) {
|
||||
case 2:
|
||||
eu_stubbed_printf_0("MEMORY:StayHeap OVERFLOW.");
|
||||
#ifdef VERSION_EU
|
||||
return alloc_bank_or_seq(arg0, arg1, size, 0, id);
|
||||
#else
|
||||
@@ -494,6 +522,7 @@ void *alloc_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 size, s32 arg
|
||||
return ret;
|
||||
#endif
|
||||
case 1:
|
||||
eu_stubbed_printf_1("MEMORY:StayHeap OVERFLOW (REQ:%d)", arg1 * size);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -523,11 +552,13 @@ void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id) {
|
||||
temporary->nextSide = 0;
|
||||
return temporary->entries[1].ptr;
|
||||
}
|
||||
eu_stubbed_printf_1("Auto Heap Unhit for ID %d\n", id);
|
||||
return NULL;
|
||||
} else {
|
||||
struct PersistentPool *persistent = &arg0->persistent;
|
||||
for (i = 0; i < persistent->numEntries; i++) {
|
||||
if (id == persistent->entries[i].id) {
|
||||
eu_stubbed_printf_2("Cache hit %d at stay %d\n", id, i);
|
||||
return persistent->entries[i].ptr;
|
||||
}
|
||||
}
|
||||
@@ -537,7 +568,7 @@ void *get_bank_or_seq(struct SoundMultiPool *arg0, s32 arg1, s32 id) {
|
||||
return get_bank_or_seq(arg0, 0, id);
|
||||
#else
|
||||
// Prevent tail call optimization by using a temporary.
|
||||
// (Did they compile with -Wo,-notail?)
|
||||
// Either copt or -Wo,-notail.
|
||||
ret = get_bank_or_seq(arg0, 0, id);
|
||||
return ret;
|
||||
#endif
|
||||
@@ -567,25 +598,27 @@ void func_eu_802e27e4_unused(f32 arg0, f32 arg1, u16 *arg2) {
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
eu_stubbed_printf_1("%d ", arg2[i]);
|
||||
}
|
||||
eu_stubbed_printf_0("\n");
|
||||
|
||||
for (i = 8; i < 16; i += 4) {
|
||||
for (i = 8; i < 16; i++) {
|
||||
eu_stubbed_printf_1("%d ", arg2[i]);
|
||||
}
|
||||
eu_stubbed_printf_0("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_EU
|
||||
void decrease_reverb_gain(void) {
|
||||
#ifdef VERSION_EU
|
||||
s32 i;
|
||||
for (i = 0; i < gNumSynthesisReverbs; i++) {
|
||||
gSynthesisReverbs[i].reverbGain -= gSynthesisReverbs[i].reverbGain / 8;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void decrease_reverb_gain(void) {
|
||||
gSynthesisReverb.reverbGain -= gSynthesisReverb.reverbGain / 4;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef VERSION_EU
|
||||
s32 audio_shut_down_and_reset_step(void) {
|
||||
@@ -679,10 +712,10 @@ void audio_reset_session(void) {
|
||||
#ifndef VERSION_EU
|
||||
s32 frames;
|
||||
s32 remainingDmas;
|
||||
#endif
|
||||
#ifdef VERSION_EU
|
||||
#else
|
||||
struct SynthesisReverb *reverb;
|
||||
#endif
|
||||
eu_stubbed_printf_1("Heap Reconstruct Start %x\n", gAudioResetPresetIdToLoad);
|
||||
|
||||
#ifndef VERSION_EU
|
||||
if (gAudioLoadLock != AUDIO_LOCK_UNINITIALIZED) {
|
||||
@@ -936,3 +969,16 @@ void audio_reset_session(void) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef VERSION_EU
|
||||
u8 audioString22[] = "SFrame Sample %d %d %d\n";
|
||||
u8 audioString23[] = "AHPBASE %x\n";
|
||||
u8 audioString24[] = "AHPCUR %x\n";
|
||||
u8 audioString25[] = "HeapTop %x\n";
|
||||
u8 audioString26[] = "SynoutRate %d / %d \n";
|
||||
u8 audioString27[] = "FXSIZE %d\n";
|
||||
u8 audioString28[] = "FXCOMP %d\n";
|
||||
u8 audioString29[] = "FXDOWN %d\n";
|
||||
u8 audioString30[] = "WaveCacheLen: %d\n";
|
||||
u8 audioString31[] = "SpecChange Finished\n";
|
||||
#endif
|
||||
|
||||
@@ -63,6 +63,29 @@
|
||||
#define FLOAT_CAST(x) (f32) (s32) (x)
|
||||
#endif
|
||||
|
||||
// No-op printf macro which leaves string literals in rodata in IDO. IDO
|
||||
// doesn't support variadic macros, so instead we let the parameter list
|
||||
// expand to a no-op comma expression. Another possibility is that it might
|
||||
// have expanded to something with "if (0)". See also goddard/gd_main.h.
|
||||
// On US/JP, -sopt optimizes away these except for external.c.
|
||||
#ifdef __sgi
|
||||
#define stubbed_printf
|
||||
#else
|
||||
#define stubbed_printf(...)
|
||||
#endif
|
||||
|
||||
#ifdef VERSION_EU
|
||||
#define eu_stubbed_printf_0(msg) stubbed_printf(msg)
|
||||
#define eu_stubbed_printf_1(msg, a) stubbed_printf(msg, a)
|
||||
#define eu_stubbed_printf_2(msg, a, b) stubbed_printf(msg, a, b)
|
||||
#define eu_stubbed_printf_3(msg, a, b, c) stubbed_printf(msg, a, b, c)
|
||||
#else
|
||||
#define eu_stubbed_printf_0(msg)
|
||||
#define eu_stubbed_printf_1(msg, a)
|
||||
#define eu_stubbed_printf_2(msg, a, b)
|
||||
#define eu_stubbed_printf_3(msg, a, b, c)
|
||||
#endif
|
||||
|
||||
struct NotePool;
|
||||
|
||||
struct AudioListItem
|
||||
@@ -202,6 +225,7 @@ struct M64ScriptState {
|
||||
u8 depth;
|
||||
}; // size = 0x1C
|
||||
|
||||
// Also known as a Group, according to debug strings.
|
||||
struct SequencePlayer
|
||||
{
|
||||
/*US/JP, EU */
|
||||
@@ -326,6 +350,8 @@ struct NoteAttributes
|
||||
#endif
|
||||
}; // size = 0x10
|
||||
|
||||
// Also known as a SubTrack, according to debug strings.
|
||||
// Confusingly, a SubTrack is a container of Tracks.
|
||||
struct SequenceChannel
|
||||
{
|
||||
/* U/J, EU */
|
||||
@@ -394,7 +420,8 @@ struct SequenceChannel
|
||||
/*0x80, 0x84*/ struct NotePool notePool;
|
||||
}; // size = 0xC0, 0xC4 in EU
|
||||
|
||||
struct SequenceChannelLayer // Maybe SequenceTrack?
|
||||
// Also known as a Track, according to debug strings.
|
||||
struct SequenceChannelLayer
|
||||
{
|
||||
/* U/J, EU */
|
||||
/*0x00, 0x00*/ u8 enabled : 1;
|
||||
@@ -507,6 +534,11 @@ struct Note
|
||||
/* U/J, EU */
|
||||
/*0xA4, 0x00*/ struct AudioListItem listItem;
|
||||
/* 0x10*/ struct NoteSynthesisState synthesisState;
|
||||
// The next members are actually part of a struct (NotePlaybackState), but
|
||||
// that results in messy US/EU ifdefs. Instead we cast to a struct pointer
|
||||
// when needed... This breaks alignment on non-N64 platforms, which we hack
|
||||
// around by skipping the padding in that case.
|
||||
// TODO: use macros or something instead.
|
||||
#ifdef TARGET_N64
|
||||
u8 pad0[12];
|
||||
#endif
|
||||
@@ -527,6 +559,7 @@ struct Note
|
||||
/* , 0xB0*/ struct NoteSubEu noteSubEu;
|
||||
}; // size = 0xC0
|
||||
#else
|
||||
// volatile Note, needed in synthesis_process_notes
|
||||
struct vNote
|
||||
{
|
||||
/* U/J, EU */
|
||||
|
||||
@@ -107,12 +107,33 @@ extern u8 gBankSetsData[]; // bank_sets.s
|
||||
* Performs an immediate DMA copy
|
||||
*/
|
||||
void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) {
|
||||
eu_stubbed_printf_3("Romcopy %x -> %x ,size %x\n", devAddr, vAddr, nbytes);
|
||||
osInvalDCache(vAddr, nbytes);
|
||||
osPiStartDma(&gAudioDmaIoMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, vAddr, nbytes,
|
||||
&gAudioDmaMesgQueue);
|
||||
osRecvMesg(&gAudioDmaMesgQueue, NULL, OS_MESG_BLOCK);
|
||||
eu_stubbed_printf_0("Romcopyend\n");
|
||||
}
|
||||
|
||||
#ifdef VERSION_EU
|
||||
u8 audioString34[] = "CAUTION:WAVE CACHE FULL %d";
|
||||
u8 audioString35[] = "BASE %x %x\n";
|
||||
u8 audioString36[] = "LOAD %x %x %x\n";
|
||||
u8 audioString37[] = "INSTTOP %x\n";
|
||||
u8 audioString38[] = "INSTMAP[0] %x\n";
|
||||
u8 audioString39[] = "already flags %d\n";
|
||||
u8 audioString40[] = "already flags %d\n";
|
||||
u8 audioString41[] = "ERR:SLOW BANK DMA BUSY\n";
|
||||
u8 audioString42[] = "ERR:SLOW DMA BUSY\n";
|
||||
u8 audioString43[] = "Check %d bank %d\n";
|
||||
u8 audioString44[] = "Cache Check\n";
|
||||
u8 audioString45[] = "NO BANK ERROR\n";
|
||||
u8 audioString46[] = "BANK %d LOADING START\n";
|
||||
u8 audioString47[] = "BANK %d LOAD MISS (NO MEMORY)!\n";
|
||||
u8 audioString48[] = "BANK %d ALREADY CACHED\n";
|
||||
u8 audioString49[] = "BANK LOAD MISS! FOR %d\n";
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Performs an asynchronus (normal priority) DMA copy
|
||||
*/
|
||||
@@ -666,11 +687,13 @@ void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer)
|
||||
u8 *seqData;
|
||||
OSMesgQueue *mesgQueue;
|
||||
|
||||
eu_stubbed_printf_1("Seq %d Loading Start\n", seqId);
|
||||
seqLength = gSeqFileHeader->seqArray[seqId].len + 0xf;
|
||||
seqLength = ALIGN16(seqLength);
|
||||
seqData = gSeqFileHeader->seqArray[seqId].offset;
|
||||
ptr = alloc_bank_or_seq(&gSeqLoadedPool, 1, seqLength, arg1, seqId);
|
||||
if (ptr == NULL) {
|
||||
eu_stubbed_printf_0("Heap Overflow Error\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -678,8 +701,8 @@ void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer)
|
||||
// Immediately load short sequenece
|
||||
audio_dma_copy_immediate((uintptr_t) seqData, ptr, seqLength);
|
||||
if (1) {
|
||||
gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE;
|
||||
}
|
||||
gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE;
|
||||
} else {
|
||||
audio_dma_copy_immediate((uintptr_t) seqData, ptr, 0x40);
|
||||
mesgQueue = &seqPlayer->seqDmaMesgQueue;
|
||||
@@ -742,12 +765,12 @@ struct AudioBank *load_banks_immediate(s32 seqId, u8 *arg1) {
|
||||
u16 offset;
|
||||
u8 i;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
offset = ((u16 *) gAlBankSets)[seqId];
|
||||
#ifdef VERSION_EU
|
||||
for (i = gAlBankSets[offset++]; i != 0; i--) {
|
||||
bankId = gAlBankSets[offset++];
|
||||
#else
|
||||
offset = ((u16 *) gAlBankSets)[seqId] + 1;
|
||||
offset++;
|
||||
for (i = gAlBankSets[offset - 1]; i != 0; i--) {
|
||||
offset++;
|
||||
bankId = gAlBankSets[offset - 1];
|
||||
@@ -787,6 +810,7 @@ void preload_sequence(u32 seqId, u8 preloadMask) {
|
||||
if (preloadMask & PRELOAD_SEQUENCE) {
|
||||
// @bug should be IS_SEQ_LOAD_COMPLETE
|
||||
if (IS_BANK_LOAD_COMPLETE(seqId) == TRUE) {
|
||||
eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId);
|
||||
sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId);
|
||||
} else {
|
||||
sequenceData = NULL;
|
||||
@@ -828,6 +852,7 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) {
|
||||
s32 dummy = 0;
|
||||
s32 bankId = get_missing_bank(seqId, &dummy, &numMissingBanks);
|
||||
if (numMissingBanks == 1) {
|
||||
eu_stubbed_printf_0("Ok,one bank slow load Start \n");
|
||||
if (bank_load_async(bankId, 2, seqPlayer) == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -835,17 +860,25 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) {
|
||||
// as default, not the missing one. This code path never gets
|
||||
// taken, though -- all sequence loading is synchronous.
|
||||
seqPlayer->defaultBank[0] = bankId;
|
||||
} else if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) {
|
||||
return;
|
||||
} else {
|
||||
eu_stubbed_printf_1("Sorry,too many %d bank is none.fast load Start \n", numMissingBanks);
|
||||
if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
eu_stubbed_printf_2("Seq %d:Default Load Id is %d\n", seqId, seqPlayer->defaultBank[0]);
|
||||
eu_stubbed_printf_0("Seq Loading Start\n");
|
||||
|
||||
seqPlayer->seqId = seqId;
|
||||
sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId);
|
||||
if (sequenceData == NULL) {
|
||||
if (seqPlayer->seqDmaInProgress) {
|
||||
eu_stubbed_printf_0("Error:Before Sequence-SlowDma remain.\n");
|
||||
eu_stubbed_printf_0(" Cancel Seq Start.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -860,6 +893,7 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) {
|
||||
}
|
||||
}
|
||||
|
||||
eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId);
|
||||
init_sequence_player(player);
|
||||
seqPlayer->scriptState.depth = 0;
|
||||
seqPlayer->delay = 0;
|
||||
@@ -935,6 +969,16 @@ void audio_init() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_N64
|
||||
eu_stubbed_printf_3("Clear Workarea %x -%x size %x \n",
|
||||
(uintptr_t) &gAudioGlobalsStartMarker,
|
||||
(uintptr_t) &gAudioGlobalsEndMarker,
|
||||
(uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker
|
||||
);
|
||||
#endif
|
||||
|
||||
eu_stubbed_printf_1("AudioHeap is %x\n", gAudioHeapSize);
|
||||
|
||||
for (i = 0; i < NUMAIBUFFERS; i++) {
|
||||
gAiBufferLengths[i] = 0xa0;
|
||||
}
|
||||
@@ -952,7 +996,7 @@ void audio_init() {
|
||||
gCurrAudioFrameDmaCount = 0;
|
||||
gSampleDmaNumListItems = 0;
|
||||
|
||||
sound_init_main_pools(D_80333EF0);
|
||||
sound_init_main_pools(gAudioInitPoolSize);
|
||||
|
||||
for (i = 0; i < NUMAIBUFFERS; i++) {
|
||||
gAiBuffers[i] = soundAlloc(&gAudioInitPool, AIBUFFER_LEN);
|
||||
@@ -970,6 +1014,11 @@ void audio_init() {
|
||||
audio_reset_session(&gAudioSessionPresets[0]);
|
||||
#endif
|
||||
|
||||
// Not sure about these prints
|
||||
eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0);
|
||||
eu_stubbed_printf_3("Heap %x %x %x\n", 0, 0, 0);
|
||||
eu_stubbed_printf_0("Main Heap Initialize.\n");
|
||||
|
||||
// Load header for sequence data (assets/music_data.sbk.s)
|
||||
gSeqFileHeader = (ALSeqFile *) buf;
|
||||
data = gMusicData;
|
||||
@@ -1011,5 +1060,12 @@ void audio_init() {
|
||||
|
||||
init_sequence_players();
|
||||
gAudioLoadLock = AUDIO_LOCK_NOT_LOADING;
|
||||
}
|
||||
|
||||
// Should probably contain the sizes of the data banks, but those aren't
|
||||
// easily accessible from here.
|
||||
eu_stubbed_printf_0("---------- Init Completed. ------------\n");
|
||||
eu_stubbed_printf_1(" Syndrv :[%6d]\n", 0); // gSoundDataADSR
|
||||
eu_stubbed_printf_1(" Seqdrv :[%6d]\n", 0); // gMusicData
|
||||
eu_stubbed_printf_1(" audiodata :[%6d]\n", 0); // gSoundDataRaw
|
||||
eu_stubbed_printf_0("---------------------------------------\n");
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ extern struct NotePool gNoteFreeLists;
|
||||
extern OSMesgQueue gCurrAudioFrameDmaQueue;
|
||||
extern u32 gSampleDmaNumListItems;
|
||||
extern ALSeqFile *gAlTbl;
|
||||
extern ALSeqFile *gSeqFileHeader;
|
||||
extern u8 *gAlBankSets;
|
||||
|
||||
extern struct CtlEntry *gCtlEntries;
|
||||
|
||||
@@ -55,8 +55,14 @@ void note_set_vel_pan_reverb(struct Note *note, f32 velocity, u8 pan, u8 reverb)
|
||||
volRight = gDefaultPanVolume[127 - pan];
|
||||
}
|
||||
|
||||
velocity = MAX(0.0f, velocity);
|
||||
velocity = MIN(32767.f, velocity);
|
||||
if (velocity < 0.0f) {
|
||||
stubbed_printf("Audio: setvol: volume minus %f\n", velocity);
|
||||
velocity = 0.0f;
|
||||
}
|
||||
if (velocity > 32767.f) {
|
||||
stubbed_printf("Audio: setvol: volume overflow %f\n", velocity);
|
||||
velocity = 32767.f;
|
||||
}
|
||||
|
||||
sub->targetVolLeft = ((s32) (velocity * volLeft) & 0xffff) >> 5;
|
||||
sub->targetVolRight = ((s32) (velocity * volRight) & 0xffff) >> 5;
|
||||
@@ -79,6 +85,7 @@ void note_set_resampling_rate(struct Note *note, f32 resamplingRateInput) {
|
||||
struct NoteSubEu *tempSub = ¬e->noteSubEu;
|
||||
|
||||
if (resamplingRateInput < 0.0f) {
|
||||
stubbed_printf("Audio: setpitch: pitch minus %f\n", resamplingRateInput);
|
||||
resamplingRateInput = 0.0f;
|
||||
}
|
||||
if (resamplingRateInput < 2.0f) {
|
||||
@@ -117,17 +124,21 @@ struct Instrument *get_instrument_inner(s32 bankId, s32 instId) {
|
||||
struct Instrument *inst;
|
||||
|
||||
if (IS_BANK_LOAD_COMPLETE(bankId) == FALSE) {
|
||||
stubbed_printf("Audio: voiceman: No bank error %d\n", bankId);
|
||||
gAudioErrorFlags = bankId + 0x10000000;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (instId >= gCtlEntries[bankId].numInstruments) {
|
||||
stubbed_printf("Audio: voiceman: progNo. overflow %d,%d\n",
|
||||
instId, gCtlEntries[bankId].numInstruments);
|
||||
gAudioErrorFlags = ((bankId << 8) + instId) + 0x3000000;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inst = gCtlEntries[bankId].instruments[instId];
|
||||
if (inst == NULL) {
|
||||
stubbed_printf("Audio: voiceman: progNo. undefined %d,%d\n", bankId, instId);
|
||||
gAudioErrorFlags = ((bankId << 8) + instId) + 0x1000000;
|
||||
return inst;
|
||||
}
|
||||
@@ -141,6 +152,7 @@ struct Instrument *get_instrument_inner(s32 bankId, s32 instId) {
|
||||
return inst;
|
||||
}
|
||||
|
||||
stubbed_printf("Audio: voiceman: BAD Voicepointer %x,%d,%d\n", inst, bankId, instId);
|
||||
gAudioErrorFlags = ((bankId << 8) + instId) + 0x2000000;
|
||||
return NULL;
|
||||
}
|
||||
@@ -148,16 +160,20 @@ struct Instrument *get_instrument_inner(s32 bankId, s32 instId) {
|
||||
struct Drum *get_drum(s32 bankId, s32 drumId) {
|
||||
struct Drum *drum;
|
||||
if (drumId >= gCtlEntries[bankId].numDrums) {
|
||||
stubbed_printf("Audio: voiceman: Percussion Overflow %d,%d\n",
|
||||
drumId, gCtlEntries[bankId].numDrums);
|
||||
gAudioErrorFlags = ((bankId << 8) + drumId) + 0x4000000;
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
#ifndef NO_SEGMENTED_MEMORY
|
||||
if ((uintptr_t) gCtlEntries[bankId].drums < 0x80000000U) {
|
||||
return 0;
|
||||
stubbed_printf("Percussion Pointer Error\n");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
drum = gCtlEntries[bankId].drums[drumId];
|
||||
if (drum == NULL) {
|
||||
stubbed_printf("Audio: voiceman: Percpointer NULL %d,%d\n", bankId, drumId);
|
||||
gAudioErrorFlags = ((bankId << 8) + drumId) + 0x5000000;
|
||||
}
|
||||
return drum;
|
||||
@@ -232,8 +248,8 @@ void process_notes(void) {
|
||||
#endif
|
||||
s32 i;
|
||||
|
||||
// Macro versions of audio_list_push_front and audio_list_remove
|
||||
// (PREPEND does not actually need to be a macro, but it seems likely.)
|
||||
// Macro versions of audio_list_push_front and audio_list_remove.
|
||||
// Should ideally be changed to use copt.
|
||||
#define PREPEND(item, head_arg) \
|
||||
((it = (item), it->prev != NULL) \
|
||||
? it \
|
||||
@@ -257,6 +273,7 @@ void process_notes(void) {
|
||||
if (!playbackState->parentLayer->enabled && playbackState->priority >= NOTE_PRIORITY_MIN) {
|
||||
goto c;
|
||||
} else if (playbackState->parentLayer->seqChannel->seqPlayer == NULL) {
|
||||
eu_stubbed_printf_0("CAUTION:SUB IS SEPARATED FROM GROUP");
|
||||
sequence_channel_disable(playbackState->parentLayer->seqChannel);
|
||||
playbackState->priority = NOTE_PRIORITY_STOPPING;
|
||||
continue;
|
||||
@@ -292,6 +309,7 @@ void process_notes(void) {
|
||||
playbackState->wantedParentLayer = NO_LAYER;
|
||||
// don't skip
|
||||
} else {
|
||||
eu_stubbed_printf_0("Error:Wait Track disappear\n");
|
||||
note_disable(note);
|
||||
audio_list_remove(¬e->listItem);
|
||||
audio_list_push_back(¬e->listItem.pool->disabled, ¬e->listItem);
|
||||
@@ -435,7 +453,10 @@ void seq_channel_layer_decay_release_internal(struct SequenceChannelLayer *seqLa
|
||||
|
||||
if (note->parentLayer != seqLayer) {
|
||||
#ifdef VERSION_EU
|
||||
if (note->parentLayer == NO_LAYER && note->wantedParentLayer == NO_LAYER && note->prevParentLayer == seqLayer && target != ADSR_STATE_DECAY) {
|
||||
if (note->parentLayer == NO_LAYER && note->wantedParentLayer == NO_LAYER &&
|
||||
note->prevParentLayer == seqLayer && target != ADSR_STATE_DECAY) {
|
||||
// Just guessing that this printf goes here... it's hard to parse.
|
||||
eu_stubbed_printf_0("Slow Release Batting\n");
|
||||
note->adsr.fadeOutVel = gAudioBufferParameters.updatesPerFrameInv;
|
||||
note->adsr.action |= ADSR_ACTION_RELEASE;
|
||||
}
|
||||
@@ -503,6 +524,7 @@ s32 build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLaye
|
||||
u8 sampleCountIndex;
|
||||
|
||||
if (waveId < 128) {
|
||||
stubbed_printf("Audio:Wavemem: Bad voiceno (%d)\n", waveId);
|
||||
waveId = 128;
|
||||
}
|
||||
|
||||
@@ -531,6 +553,7 @@ s32 build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLaye
|
||||
|
||||
return sampleCountIndex;
|
||||
}
|
||||
|
||||
#else
|
||||
void build_synthetic_wave(struct Note *note, struct SequenceChannelLayer *seqLayer) {
|
||||
s32 i;
|
||||
@@ -671,7 +694,11 @@ void note_pool_clear(struct NotePool *pool) {
|
||||
#ifdef VERSION_EU
|
||||
for (;;) {
|
||||
cur = source->next;
|
||||
if (cur == source || cur == NULL) {
|
||||
if (cur == source) {
|
||||
break;
|
||||
}
|
||||
if (cur == NULL) {
|
||||
eu_stubbed_printf_0("Audio: C-Alloc : Dealloc voice is NULL\n");
|
||||
break;
|
||||
}
|
||||
audio_list_remove(cur);
|
||||
@@ -703,6 +730,7 @@ void note_pool_fill(struct NotePool *pool, s32 count) {
|
||||
|
||||
for (i = 0, j = 0; j < count; i++) {
|
||||
if (i == 4) {
|
||||
eu_stubbed_printf_1("Alloc Error:Dim voice-Alloc %d", count);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -741,7 +769,9 @@ void note_pool_fill(struct NotePool *pool, s32 count) {
|
||||
|
||||
void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *item) {
|
||||
// add 'item' to the front of the list given by 'list', if it's not in any list
|
||||
if (item->prev == NULL) {
|
||||
if (item->prev != NULL) {
|
||||
eu_stubbed_printf_0("Error:Same List Add\n");
|
||||
} else {
|
||||
item->prev = list;
|
||||
item->next = list->next;
|
||||
list->next->prev = item;
|
||||
@@ -753,14 +783,16 @@ void audio_list_push_front(struct AudioListItem *list, struct AudioListItem *ite
|
||||
|
||||
void audio_list_remove(struct AudioListItem *item) {
|
||||
// remove 'item' from the list it's in, if any
|
||||
if (item->prev != NULL) {
|
||||
if (item->prev == NULL) {
|
||||
eu_stubbed_printf_0("Already Cut\n");
|
||||
} else {
|
||||
item->prev->next = item->next;
|
||||
item->next->prev = item->prev;
|
||||
item->prev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct Note *pop_node_with_value_less_equal(struct AudioListItem *list, s32 limit) {
|
||||
struct Note *pop_node_with_lower_prio(struct AudioListItem *list, s32 limit) {
|
||||
struct AudioListItem *cur = list->next;
|
||||
struct AudioListItem *best;
|
||||
|
||||
@@ -894,8 +926,10 @@ struct Note *alloc_note_from_decaying(struct NotePool *pool, struct SequenceChan
|
||||
|
||||
struct Note *alloc_note_from_active(struct NotePool *pool, struct SequenceChannelLayer *seqLayer) {
|
||||
struct Note *note =
|
||||
pop_node_with_value_less_equal(&pool->active, seqLayer->seqChannel->notePriority);
|
||||
if (note != NULL) {
|
||||
pop_node_with_lower_prio(&pool->active, seqLayer->seqChannel->notePriority);
|
||||
if (note == NULL) {
|
||||
eu_stubbed_printf_0("Audio: C-Alloc : lowerPrio is NULL\n");
|
||||
} else {
|
||||
func_80319728(note, seqLayer);
|
||||
audio_list_push_back(&pool->releasing, ¬e->listItem);
|
||||
}
|
||||
@@ -928,6 +962,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) {
|
||||
if (!(ret = alloc_note_from_disabled(&seqLayer->seqChannel->notePool, seqLayer))
|
||||
&& !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->notePool, seqLayer))
|
||||
&& !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))) {
|
||||
eu_stubbed_printf_0("Sub Limited Warning: Drop Voice");
|
||||
seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED;
|
||||
return NULL;
|
||||
}
|
||||
@@ -941,6 +976,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) {
|
||||
&& !(ret = alloc_note_from_decaying(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))
|
||||
&& !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))
|
||||
&& !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))) {
|
||||
eu_stubbed_printf_0("Warning: Drop Voice");
|
||||
seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED;
|
||||
return NULL;
|
||||
}
|
||||
@@ -951,6 +987,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) {
|
||||
if (!(ret = alloc_note_from_disabled(&gNoteFreeLists, seqLayer))
|
||||
&& !(ret = alloc_note_from_decaying(&gNoteFreeLists, seqLayer))
|
||||
&& !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) {
|
||||
eu_stubbed_printf_0("Warning: Drop Voice");
|
||||
seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED;
|
||||
return NULL;
|
||||
}
|
||||
@@ -966,6 +1003,7 @@ struct Note *alloc_note(struct SequenceChannelLayer *seqLayer) {
|
||||
&& !(ret = alloc_note_from_active(&seqLayer->seqChannel->notePool, seqLayer))
|
||||
&& !(ret = alloc_note_from_active(&seqLayer->seqChannel->seqPlayer->notePool, seqLayer))
|
||||
&& !(ret = alloc_note_from_active(&gNoteFreeLists, seqLayer))) {
|
||||
eu_stubbed_printf_0("Warning: Drop Voice");
|
||||
seqLayer->status = SOUND_LOAD_STATUS_NOT_LOADED;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1011,7 +1049,6 @@ void reclaim_notes(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void note_init_all(void) {
|
||||
struct Note *note;
|
||||
s32 i;
|
||||
|
||||
@@ -141,7 +141,6 @@ void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
|
||||
|
||||
case 0x82:
|
||||
case 0x88:
|
||||
// load_sequence(arg1, arg2, 0);
|
||||
load_sequence(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3);
|
||||
func_8031D690(cmd->u.s.arg1, cmd->u2.as_s32);
|
||||
break;
|
||||
|
||||
@@ -198,6 +198,7 @@ void sequence_player_init_channels(struct SequencePlayer *seqPlayer, u16 channel
|
||||
}
|
||||
seqChannel = allocate_sequence_channel();
|
||||
if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) {
|
||||
eu_stubbed_printf_0("Audio:Track:Warning: No Free Notetrack\n");
|
||||
gAudioErrorFlags = i + 0x10000;
|
||||
seqPlayer->channels[i] = seqChannel;
|
||||
} else {
|
||||
@@ -221,6 +222,7 @@ void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 chan
|
||||
struct SequenceChannel *seqChannel;
|
||||
s32 i;
|
||||
|
||||
eu_stubbed_printf_0("SUBTRACK DIM\n");
|
||||
for (i = 0; i < CHANNELS_MAX; i++) {
|
||||
if (channelBits & 1) {
|
||||
seqChannel = seqPlayer->channels[i];
|
||||
@@ -230,7 +232,9 @@ void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 chan
|
||||
seqChannel->seqPlayer = NULL;
|
||||
}
|
||||
#ifdef VERSION_EU
|
||||
if (0) {}
|
||||
else {
|
||||
stubbed_printf("Audio:Track: Warning SUBTRACK PARENT CHANGED\n");
|
||||
}
|
||||
#endif
|
||||
seqPlayer->channels[i] = &gSequenceChannelNone;
|
||||
}
|
||||
@@ -243,27 +247,30 @@ void sequence_player_disable_channels(struct SequencePlayer *seqPlayer, u16 chan
|
||||
}
|
||||
}
|
||||
|
||||
void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *arg2) {
|
||||
void sequence_channel_enable(struct SequencePlayer *seqPlayer, u8 channelIndex, void *script) {
|
||||
struct SequenceChannel *seqChannel = seqPlayer->channels[channelIndex];
|
||||
s32 i;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) == FALSE) {
|
||||
#ifdef VERSION_EU
|
||||
struct SequencePlayer *bgMusic = &gSequencePlayers[0];
|
||||
struct SequencePlayer *miscMusic = &gSequencePlayers[1];
|
||||
|
||||
if (seqPlayer == bgMusic) {
|
||||
stubbed_printf("GROUP 0:");
|
||||
} else if (seqPlayer == miscMusic) {
|
||||
stubbed_printf("GROUP 1:");
|
||||
} else {
|
||||
stubbed_printf("SEQID %d,BANKID %d\n",
|
||||
seqPlayer->seqId, seqPlayer->defaultBank[0]);
|
||||
}
|
||||
} else {
|
||||
#else
|
||||
if (IS_SEQUENCE_CHANNEL_VALID(seqChannel) != FALSE) {
|
||||
stubbed_printf("ERR:SUBTRACK %d NOT ALLOCATED\n", channelIndex);
|
||||
#endif
|
||||
} else {
|
||||
seqChannel->enabled = TRUE;
|
||||
seqChannel->finished = FALSE;
|
||||
seqChannel->scriptState.depth = 0;
|
||||
seqChannel->scriptState.pc = arg2;
|
||||
seqChannel->scriptState.pc = script;
|
||||
seqChannel->delay = 0;
|
||||
for (i = 0; i < LAYERS_MAX; i++) {
|
||||
if (seqChannel->layers[i] != NULL) {
|
||||
@@ -309,7 +316,9 @@ void sequence_player_disable(struct SequencePlayer *seqPlayer) {
|
||||
* Add an item to the end of a list, if it's not already in any list.
|
||||
*/
|
||||
void audio_list_push_back(struct AudioListItem *list, struct AudioListItem *item) {
|
||||
if (item->prev == NULL) {
|
||||
if (item->prev != NULL) {
|
||||
eu_stubbed_printf_0("Error:Same List Add\n");
|
||||
} else {
|
||||
list->prev->next = item;
|
||||
item->prev = list->prev;
|
||||
item->next = list;
|
||||
@@ -479,12 +488,18 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
|
||||
break;
|
||||
|
||||
case 0xfc: // layer_call
|
||||
if (0 && state->depth >= 4) {
|
||||
eu_stubbed_printf_0("Macro Level Over Error!\n");
|
||||
}
|
||||
sp3A = m64_read_s16(state);
|
||||
state->stack[state->depth++] = state->pc;
|
||||
state->pc = seqPlayer->seqData + sp3A;
|
||||
break;
|
||||
|
||||
case 0xf8: // layer_loop; loop start, N iterations (or 256 if N = 0)
|
||||
if (0 && state->depth >= 4) {
|
||||
eu_stubbed_printf_0("Macro Level Over Error!\n");
|
||||
}
|
||||
state->remLoopIters[state->depth] = m64_read_u8(state);
|
||||
state->stack[state->depth++] = state->pc;
|
||||
break;
|
||||
@@ -571,9 +586,8 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
|
||||
break;
|
||||
}
|
||||
|
||||
cmd = get_instrument(seqChannel, cmd, &layer->instrument, &layer->adsr);
|
||||
layer->instOrWave = cmd;
|
||||
if (cmd == 0) {
|
||||
if ((layer->instOrWave = get_instrument(seqChannel, cmd, &layer->instrument, &layer->adsr)) == 0) {
|
||||
eu_stubbed_printf_1("WARNING: NPRG: cannot change %d\n", cmd);
|
||||
layer->instOrWave = 0xff;
|
||||
}
|
||||
#endif
|
||||
@@ -627,6 +641,9 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
|
||||
case 0xe0: // layer_setshortnotedurationfromtable
|
||||
layer->noteDuration = seqPlayer->shortNoteDurationTable[cmd & 0xf];
|
||||
break;
|
||||
default:
|
||||
eu_stubbed_printf_1("Audio:Track:NOTE:UNDEFINED NOTE COM. %x\n", cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -891,6 +908,10 @@ void seq_channel_layer_process_script(struct SequenceChannelLayer *layer) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
u8 audioString106[] = "Audio: Note:Velocity Error %d\n";
|
||||
u8 audioString107[] = "Error: Your assignchannel is stolen.\n";
|
||||
|
||||
#elif defined(NON_MATCHING)
|
||||
// US/JP version with macros to simulate inlining by copt. Edit if you dare.
|
||||
#include "seq_channel_layer_process_script.h"
|
||||
@@ -986,7 +1007,6 @@ void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume)
|
||||
}
|
||||
|
||||
#ifdef NON_MATCHING
|
||||
//rodata: 0xf3e30
|
||||
void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
struct M64ScriptState *state;
|
||||
struct SequencePlayer *seqPlayer;
|
||||
@@ -1086,6 +1106,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
goto out;
|
||||
#endif
|
||||
case 0xfc: // chan_call
|
||||
if (0 && state->depth >= 4) {
|
||||
eu_stubbed_printf_0("Audio:Track :Call Macro Level Over Error!\n");
|
||||
}
|
||||
sp5A = m64_read_s16(state);
|
||||
#ifdef VERSION_EU
|
||||
state->stack[state->depth++] = state->pc;
|
||||
@@ -1096,6 +1119,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
break;
|
||||
|
||||
case 0xf8: // chan_loop; loop start, N iterations (or 256 if N = 0)
|
||||
if (0 && state->depth >= 4) {
|
||||
eu_stubbed_printf_0("Audio:Track :Loops Macro Level Over Error!\n");
|
||||
}
|
||||
state->remLoopIters[state->depth] = m64_read_u8(state);
|
||||
#ifdef VERSION_EU
|
||||
state->stack[state->depth++] = state->pc;
|
||||
@@ -1132,9 +1158,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
break;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
case 0xf4:
|
||||
case 0xf3:
|
||||
case 0xf2:
|
||||
case 0xf4: // chan_jump_rel
|
||||
case 0xf3: // chan_beqz_rel
|
||||
case 0xf2: // chan_bltz_rel
|
||||
tempSigned = m64_read_u8(state);
|
||||
if (cmd == 0xf3 && value != 0)
|
||||
break;
|
||||
@@ -1177,7 +1203,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
break;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
case 0xeb:
|
||||
case 0xeb: // chan_setbankandinstr
|
||||
temp = m64_read_u8(state);
|
||||
// Switch to the temp's (0-indexed) bank in this sequence's
|
||||
// bank set. Note that in the binary format (not in the JSON!)
|
||||
@@ -1188,6 +1214,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
// temp should be in a saved register across this call
|
||||
if (get_bank_or_seq(&gBankLoadedPool, 2, temp) != NULL) {
|
||||
seqChannel->bankId = temp;
|
||||
} else {
|
||||
eu_stubbed_printf_1("SUB:ERR:BANK %d NOT CACHED.\n", temp);
|
||||
}
|
||||
// fallthrough
|
||||
#endif
|
||||
@@ -1322,6 +1350,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
// temp should be in a saved register across this call
|
||||
if (get_bank_or_seq(&gBankLoadedPool, 2, temp) != NULL) {
|
||||
seqChannel->bankId = temp;
|
||||
} else {
|
||||
eu_stubbed_printf_1("SUB:ERR:BANK %d NOT CACHED.\n", temp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1381,6 +1411,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
#endif
|
||||
case 0xe4: // chan_dyncall
|
||||
if (value != -1) {
|
||||
if (0 && state->depth >= 4) {
|
||||
eu_stubbed_printf_0("Audio:Track: CTBLCALL Macro Level Over Error!\n");
|
||||
}
|
||||
u8(*thingy)[2] = *seqChannel->dynTable;
|
||||
#ifdef VERSION_EU
|
||||
state->stack[state->depth++] = state->pc;
|
||||
@@ -1389,6 +1422,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
#endif
|
||||
sp5A = thingy[value][1] + (thingy[value][0] << 8);
|
||||
state->pc = seqPlayer->seqData + sp5A;
|
||||
if (0 && sp5A >= gSeqFileHeader->seqArray[seqPlayer->seqId].len) {
|
||||
eu_stubbed_printf_3("Err :Sub %x ,address %x:Undefined SubTrack Function %x", seqChannel, state->pc, sp5A);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1433,7 +1469,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
seqChannel->freqScale = 1.0f;
|
||||
break;
|
||||
|
||||
case 0xe9:
|
||||
case 0xe9: // chan_setnotepriority
|
||||
seqChannel->notePriority = m64_read_u8(state);
|
||||
break;
|
||||
#endif
|
||||
@@ -1470,7 +1506,7 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) {
|
||||
break;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
case 0x60:
|
||||
case 0x60: // chan_delayshort
|
||||
seqChannel->delay = loBits;
|
||||
goto out;
|
||||
#endif
|
||||
@@ -1621,6 +1657,7 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
|
||||
// If discarded, bail out.
|
||||
if (IS_SEQ_LOAD_COMPLETE(seqPlayer->seqId) == FALSE
|
||||
|| IS_BANK_LOAD_COMPLETE(seqPlayer->defaultBank[0]) == FALSE) {
|
||||
eu_stubbed_printf_1("Disappear Sequence or Bank %d\n", seqPlayer->seqId);
|
||||
sequence_player_disable(seqPlayer);
|
||||
return;
|
||||
}
|
||||
@@ -1685,6 +1722,9 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
|
||||
|
||||
case 0xfc: // seq_call
|
||||
u16v = m64_read_s16(state);
|
||||
if (0 && state->depth >= 4) {
|
||||
eu_stubbed_printf_0("Macro Level Over Error!\n");
|
||||
}
|
||||
#ifdef VERSION_EU
|
||||
state->stack[state->depth++] = state->pc;
|
||||
#else
|
||||
@@ -1694,6 +1734,9 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
|
||||
break;
|
||||
|
||||
case 0xf8: // seq_loop; loop start, N iterations (or 256 if N = 0)
|
||||
if (0 && state->depth >= 4) {
|
||||
eu_stubbed_printf_0("Macro Level Over Error!\n");
|
||||
}
|
||||
state->remLoopIters[state->depth] = m64_read_u8(state);
|
||||
#ifdef VERSION_EU
|
||||
state->stack[state->depth++] = state->pc;
|
||||
@@ -1913,6 +1956,10 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
|
||||
case 0xc8: // seq_subtract
|
||||
value = value - m64_read_u8(state);
|
||||
break;
|
||||
|
||||
default:
|
||||
eu_stubbed_printf_1("Group:Undefine upper C0h command (%x)\n", cmd);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
loBits = cmd & 0xf;
|
||||
@@ -1967,6 +2014,10 @@ void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) {
|
||||
case 0xd9:
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
eu_stubbed_printf_0("Group:Undefined Command\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,11 +71,12 @@ f32 gLeftVolRampings[3][1024];
|
||||
f32 gRightVolRampings[3][1024];
|
||||
f32 *gCurrentLeftVolRamping; // Points to any of the three left buffers above
|
||||
f32 *gCurrentRightVolRamping; // Points to any of the three right buffers above
|
||||
|
||||
u8 audioString1[] = "pitch %x: delaybytes %d : olddelay %d\n";
|
||||
u8 audioString2[] = "cont %x: delaybytes %d : olddelay %d\n";
|
||||
|
||||
#else
|
||||
struct SynthesisReverb gSynthesisReverb;
|
||||
#endif
|
||||
|
||||
#ifndef VERSION_EU
|
||||
u8 sAudioSynthesisPad[0x20];
|
||||
#endif
|
||||
|
||||
@@ -614,8 +615,6 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) {
|
||||
u8 *sampleAddr; // sp120, spF4
|
||||
#endif
|
||||
|
||||
// sp6c is a temporary!
|
||||
|
||||
#ifdef VERSION_EU
|
||||
s32 samplesLenAdjusted; // 108, spEC
|
||||
// Might have been used to store (samplesLenFixedPoint >> 0x10), but doing so causes strange
|
||||
|
||||
@@ -314,12 +314,12 @@ struct GraphNodeObject *init_graph_node_object(struct AllocOnlyPool *pool,
|
||||
vec3s_copy(graphNode->angle, angle);
|
||||
graphNode->sharedChild = sharedChild;
|
||||
graphNode->throwMatrix = NULL;
|
||||
graphNode->unk38.animID = 0;
|
||||
graphNode->unk38.curAnim = NULL;
|
||||
graphNode->unk38.animFrame = 0;
|
||||
graphNode->unk38.animFrameAccelAssist = 0;
|
||||
graphNode->unk38.animAccel = 0x10000;
|
||||
graphNode->unk38.animTimer = 0;
|
||||
graphNode->animInfo.animID = 0;
|
||||
graphNode->animInfo.curAnim = NULL;
|
||||
graphNode->animInfo.animFrame = 0;
|
||||
graphNode->animInfo.animFrameAccelAssist = 0;
|
||||
graphNode->animInfo.animAccel = 0x10000;
|
||||
graphNode->animInfo.animTimer = 0;
|
||||
graphNode->node.flags |= GRAPH_RENDER_HAS_ANIMATION;
|
||||
}
|
||||
|
||||
@@ -698,7 +698,7 @@ void geo_obj_init(struct GraphNodeObject *graphNode, void *sharedChild, Vec3f po
|
||||
graphNode->sharedChild = sharedChild;
|
||||
graphNode->unk4C = 0;
|
||||
graphNode->throwMatrix = NULL;
|
||||
graphNode->unk38.curAnim = NULL;
|
||||
graphNode->animInfo.curAnim = NULL;
|
||||
|
||||
graphNode->node.flags |= GRAPH_RENDER_ACTIVE;
|
||||
graphNode->node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
@@ -717,12 +717,12 @@ void geo_obj_init_spawninfo(struct GraphNodeObject *graphNode, struct SpawnInfo
|
||||
graphNode->pos[1] = (f32) spawn->startPos[1];
|
||||
graphNode->pos[2] = (f32) spawn->startPos[2];
|
||||
|
||||
graphNode->unk18 = spawn->areaIndex;
|
||||
graphNode->unk19 = spawn->activeAreaIndex;
|
||||
graphNode->areaIndex = spawn->areaIndex;
|
||||
graphNode->activeAreaIndex = spawn->activeAreaIndex;
|
||||
graphNode->sharedChild = spawn->unk18;
|
||||
graphNode->unk4C = spawn;
|
||||
graphNode->throwMatrix = NULL;
|
||||
graphNode->unk38.curAnim = 0;
|
||||
graphNode->animInfo.curAnim = 0;
|
||||
|
||||
graphNode->node.flags |= GRAPH_RENDER_ACTIVE;
|
||||
graphNode->node.flags &= ~GRAPH_RENDER_INVISIBLE;
|
||||
@@ -737,11 +737,11 @@ void geo_obj_init_animation(struct GraphNodeObject *graphNode, struct Animation
|
||||
struct Animation **animSegmented = segmented_to_virtual(animPtrAddr);
|
||||
struct Animation *anim = segmented_to_virtual(*animSegmented);
|
||||
|
||||
if (graphNode->unk38.curAnim != anim) {
|
||||
graphNode->unk38.curAnim = anim;
|
||||
graphNode->unk38.animFrame = anim->unk04 + ((anim->flags & ANIM_FLAG_FORWARD) ? 1 : -1);
|
||||
graphNode->unk38.animAccel = 0;
|
||||
graphNode->unk38.animYTrans = 0;
|
||||
if (graphNode->animInfo.curAnim != anim) {
|
||||
graphNode->animInfo.curAnim = anim;
|
||||
graphNode->animInfo.animFrame = anim->startFrame + ((anim->flags & ANIM_FLAG_FORWARD) ? 1 : -1);
|
||||
graphNode->animInfo.animAccel = 0;
|
||||
graphNode->animInfo.animYTrans = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,15 +752,15 @@ void geo_obj_init_animation_accel(struct GraphNodeObject *graphNode, struct Anim
|
||||
struct Animation **animSegmented = segmented_to_virtual(animPtrAddr);
|
||||
struct Animation *anim = segmented_to_virtual(*animSegmented);
|
||||
|
||||
if (graphNode->unk38.curAnim != anim) {
|
||||
graphNode->unk38.curAnim = anim;
|
||||
graphNode->unk38.animYTrans = 0;
|
||||
graphNode->unk38.animFrameAccelAssist =
|
||||
(anim->unk04 << 16) + ((anim->flags & ANIM_FLAG_FORWARD) ? animAccel : -animAccel);
|
||||
graphNode->unk38.animFrame = graphNode->unk38.animFrameAccelAssist >> 16;
|
||||
if (graphNode->animInfo.curAnim != anim) {
|
||||
graphNode->animInfo.curAnim = anim;
|
||||
graphNode->animInfo.animYTrans = 0;
|
||||
graphNode->animInfo.animFrameAccelAssist =
|
||||
(anim->startFrame << 16) + ((anim->flags & ANIM_FLAG_FORWARD) ? animAccel : -animAccel);
|
||||
graphNode->animInfo.animFrame = graphNode->animInfo.animFrameAccelAssist >> 16;
|
||||
}
|
||||
|
||||
graphNode->unk38.animAccel = animAccel;
|
||||
graphNode->animInfo.animAccel = animAccel;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -789,7 +789,7 @@ s32 retrieve_animation_index(s32 frame, u16 **attributes) {
|
||||
* whether it plays forwards or backwards, and whether it stops or loops at
|
||||
* the end etc.
|
||||
*/
|
||||
s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist) {
|
||||
s16 geo_update_animation_frame(struct AnimInfo *obj, s32 *accelAssist) {
|
||||
s32 result;
|
||||
struct Animation *anim;
|
||||
|
||||
@@ -810,11 +810,11 @@ s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist
|
||||
result = (obj->animFrame - 1) << 16;
|
||||
}
|
||||
|
||||
if (GET_HIGH_S16_OF_32(result) < anim->unk06) {
|
||||
if (GET_HIGH_S16_OF_32(result) < anim->loopStart) {
|
||||
if (anim->flags & ANIM_FLAG_NOLOOP) {
|
||||
SET_HIGH_S16_OF_32(result, anim->unk06);
|
||||
SET_HIGH_S16_OF_32(result, anim->loopStart);
|
||||
} else {
|
||||
SET_HIGH_S16_OF_32(result, anim->unk08 - 1);
|
||||
SET_HIGH_S16_OF_32(result, anim->loopEnd - 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -824,11 +824,11 @@ s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist
|
||||
result = (obj->animFrame + 1) << 16;
|
||||
}
|
||||
|
||||
if (GET_HIGH_S16_OF_32(result) >= anim->unk08) {
|
||||
if (GET_HIGH_S16_OF_32(result) >= anim->loopEnd) {
|
||||
if (anim->flags & ANIM_FLAG_NOLOOP) {
|
||||
SET_HIGH_S16_OF_32(result, anim->unk08 - 1);
|
||||
SET_HIGH_S16_OF_32(result, anim->loopEnd - 1);
|
||||
} else {
|
||||
SET_HIGH_S16_OF_32(result, anim->unk06);
|
||||
SET_HIGH_S16_OF_32(result, anim->loopStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -849,7 +849,7 @@ s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist
|
||||
* animations without lateral translation.
|
||||
*/
|
||||
void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f position) {
|
||||
struct Animation *animation = obj->unk38.curAnim;
|
||||
struct Animation *animation = obj->animInfo.curAnim;
|
||||
u16 *attribute;
|
||||
s16 *values;
|
||||
s16 frame;
|
||||
@@ -858,7 +858,7 @@ void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f posit
|
||||
attribute = segmented_to_virtual((void *) animation->index);
|
||||
values = segmented_to_virtual((void *) animation->values);
|
||||
|
||||
frame = obj->unk38.animFrame;
|
||||
frame = obj->animInfo.animFrame;
|
||||
|
||||
if (frame < 0) {
|
||||
frame = 0;
|
||||
|
||||
@@ -420,7 +420,7 @@ void geo_obj_init_animation_accel(struct GraphNodeObject *graphNode, struct Anim
|
||||
|
||||
s32 retrieve_animation_index(s32 frame, u16 **attributes);
|
||||
|
||||
s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist);
|
||||
s16 geo_update_animation_frame(struct AnimInfo *obj, s32 *accelAssist);
|
||||
void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f position);
|
||||
|
||||
struct GraphNodeRoot *geo_find_root(struct GraphNode *graphNode);
|
||||
|
||||
@@ -159,7 +159,8 @@ void mtxf_copy(Mat4 dest, Mat4 src) {
|
||||
void mtxf_identity(Mat4 mtx) {
|
||||
register s32 i;
|
||||
register f32 *dest;
|
||||
// Note: These loops need to be on one line to match on PAL
|
||||
// These loops must be one line to match on -O2
|
||||
|
||||
// initialize everything except the first and last cells to 0
|
||||
for (dest = (f32 *) mtx + 1, i = 0; i < 14; dest++, i++) *dest = 0;
|
||||
|
||||
|
||||
@@ -199,8 +199,8 @@ s32 find_wall_collisions(struct WallCollisionData *colData) {
|
||||
|
||||
// World (level) consists of a 16x16 grid. Find where the collision is on
|
||||
// the grid (round toward -inf)
|
||||
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F;
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F;
|
||||
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
|
||||
|
||||
// Check for surfaces belonging to objects.
|
||||
node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next;
|
||||
@@ -307,8 +307,8 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
|
||||
s16 cellZ, cellX;
|
||||
struct Surface *ceil, *dynamicCeil;
|
||||
struct SurfaceNode *surfaceList;
|
||||
f32 height = 20000.0f;
|
||||
f32 dynamicHeight = 20000.0f;
|
||||
f32 height = CELL_HEIGHT_LIMIT;
|
||||
f32 dynamicHeight = CELL_HEIGHT_LIMIT;
|
||||
s16 x, y, z;
|
||||
|
||||
//! (Parallel Universes) Because position is casted to an s16, reaching higher
|
||||
@@ -327,8 +327,8 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
|
||||
}
|
||||
|
||||
// Each level is split into cells to limit load, find the appropriate cell.
|
||||
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF;
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF;
|
||||
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
|
||||
|
||||
// Check for surfaces belonging to objects.
|
||||
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next;
|
||||
@@ -486,7 +486,7 @@ f32 find_floor_height(f32 x, f32 y, f32 z) {
|
||||
f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
|
||||
struct SurfaceNode *surfaceList;
|
||||
struct Surface *floor;
|
||||
f32 floorHeight = -11000.0f;
|
||||
f32 floorHeight = FLOOR_LOWER_LIMIT;
|
||||
|
||||
// Would normally cause PUs, but dynamic floors unload at that range.
|
||||
s16 x = (s16) xPos;
|
||||
@@ -494,8 +494,8 @@ f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfl
|
||||
s16 z = (s16) zPos;
|
||||
|
||||
// Each level is split into cells to limit load, find the appropriate cell.
|
||||
s16 cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F;
|
||||
s16 cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F;
|
||||
s16 cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
|
||||
s16 cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
|
||||
|
||||
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
|
||||
floor = find_floor_from_list(surfaceList, x, y, z, &floorHeight);
|
||||
@@ -514,8 +514,8 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
|
||||
struct Surface *floor, *dynamicFloor;
|
||||
struct SurfaceNode *surfaceList;
|
||||
|
||||
f32 height = -11000.0f;
|
||||
f32 dynamicHeight = -11000.0f;
|
||||
f32 height = FLOOR_LOWER_LIMIT;
|
||||
f32 dynamicHeight = FLOOR_LOWER_LIMIT;
|
||||
|
||||
//! (Parallel Universes) Because position is casted to an s16, reaching higher
|
||||
// float locations can return floors despite them not existing there.
|
||||
@@ -534,8 +534,8 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
|
||||
}
|
||||
|
||||
// Each level is split into cells to limit load, find the appropriate cell.
|
||||
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF;
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF;
|
||||
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
|
||||
|
||||
// Check for surfaces belonging to objects.
|
||||
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
|
||||
@@ -591,7 +591,7 @@ f32 find_water_level(f32 x, f32 z) {
|
||||
s32 numRegions;
|
||||
s16 val;
|
||||
f32 loX, hiX, loZ, hiZ;
|
||||
f32 waterLevel = -11000.0f;
|
||||
f32 waterLevel = FLOOR_LOWER_LIMIT;
|
||||
s16 *p = gEnvironmentRegions;
|
||||
|
||||
if (p != NULL) {
|
||||
@@ -627,7 +627,7 @@ f32 find_poison_gas_level(f32 x, f32 z) {
|
||||
UNUSED s32 unused;
|
||||
s16 val;
|
||||
f32 loX, hiX, loZ, hiZ;
|
||||
f32 gasLevel = -11000.0f;
|
||||
f32 gasLevel = FLOOR_LOWER_LIMIT;
|
||||
s16 *p = gEnvironmentRegions;
|
||||
|
||||
if (p != NULL) {
|
||||
@@ -689,25 +689,25 @@ void debug_surface_list_info(f32 xPos, f32 zPos) {
|
||||
s32 cellX = (xPos + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
s32 cellZ = (zPos + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
|
||||
list = gStaticSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_FLOORS].next;
|
||||
list = gStaticSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_FLOORS].next;
|
||||
numFloors += surface_list_length(list);
|
||||
|
||||
list = gDynamicSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_FLOORS].next;
|
||||
list = gDynamicSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_FLOORS].next;
|
||||
numFloors += surface_list_length(list);
|
||||
|
||||
list = gStaticSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_WALLS].next;
|
||||
list = gStaticSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_WALLS].next;
|
||||
numWalls += surface_list_length(list);
|
||||
|
||||
list = gDynamicSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_WALLS].next;
|
||||
list = gDynamicSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_WALLS].next;
|
||||
numWalls += surface_list_length(list);
|
||||
|
||||
list = gStaticSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_CEILS].next;
|
||||
list = gStaticSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_CEILS].next;
|
||||
numCeils += surface_list_length(list);
|
||||
|
||||
list = gDynamicSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_CEILS].next;
|
||||
list = gDynamicSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_CEILS].next;
|
||||
numCeils += surface_list_length(list);
|
||||
|
||||
print_debug_top_down_mapinfo("area %x", cellZ * 16 + cellX);
|
||||
print_debug_top_down_mapinfo("area %x", cellZ * NUM_CELLS + cellX);
|
||||
|
||||
// Names represent ground, walls, and roofs as found in SMS.
|
||||
print_debug_top_down_mapinfo("dg %d", numFloors);
|
||||
|
||||
@@ -5,8 +5,11 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define LEVEL_BOUNDARY_MAX 0x2000
|
||||
#define CELL_SIZE 0x400
|
||||
#define LEVEL_BOUNDARY_MAX 0x2000
|
||||
#define CELL_SIZE 0x400
|
||||
|
||||
#define CELL_HEIGHT_LIMIT 20000.f
|
||||
#define FLOOR_LOWER_LIMIT -11000.f
|
||||
|
||||
struct WallCollisionData
|
||||
{
|
||||
|
||||
@@ -21,8 +21,8 @@ s32 unused8038BE90;
|
||||
* Partitions for course and object surfaces. The arrays represent
|
||||
* the 16x16 cells that each level is split into.
|
||||
*/
|
||||
SpatialPartitionCell gStaticSurfacePartition[16][16];
|
||||
SpatialPartitionCell gDynamicSurfacePartition[16][16];
|
||||
SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS];
|
||||
SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
|
||||
|
||||
/**
|
||||
* Pools of data to contain either surface nodes or surfaces.
|
||||
@@ -83,7 +83,7 @@ static struct Surface *alloc_surface(void) {
|
||||
* Iterates through the entire partition, clearing the surfaces.
|
||||
*/
|
||||
static void clear_spatial_partition(SpatialPartitionCell *cells) {
|
||||
register s32 i = 16 * 16;
|
||||
register s32 i = NUM_CELLS * NUM_CELLS;
|
||||
|
||||
while (i--) {
|
||||
(*cells)[SPATIAL_PARTITION_FLOORS].next = NULL;
|
||||
@@ -201,18 +201,18 @@ static s16 lower_cell_index(s16 coord) {
|
||||
s16 index;
|
||||
|
||||
// Move from range [-0x2000, 0x2000) to [0, 0x4000)
|
||||
coord += 0x2000;
|
||||
coord += LEVEL_BOUNDARY_MAX;
|
||||
if (coord < 0) {
|
||||
coord = 0;
|
||||
}
|
||||
|
||||
// [0, 16)
|
||||
index = coord / 0x400;
|
||||
index = coord / CELL_SIZE;
|
||||
|
||||
// Include extra cell if close to boundary
|
||||
//! Some wall checks are larger than the buffer, meaning wall checks can
|
||||
// miss walls that are near a cell border.
|
||||
if (coord % 0x400 < 50) {
|
||||
if (coord % CELL_SIZE < 50) {
|
||||
index -= 1;
|
||||
}
|
||||
|
||||
@@ -233,23 +233,23 @@ static s16 upper_cell_index(s16 coord) {
|
||||
s16 index;
|
||||
|
||||
// Move from range [-0x2000, 0x2000) to [0, 0x4000)
|
||||
coord += 0x2000;
|
||||
coord += LEVEL_BOUNDARY_MAX;
|
||||
if (coord < 0) {
|
||||
coord = 0;
|
||||
}
|
||||
|
||||
// [0, 16)
|
||||
index = coord / 0x400;
|
||||
index = coord / CELL_SIZE;
|
||||
|
||||
// Include extra cell if close to boundary
|
||||
//! Some wall checks are larger than the buffer, meaning wall checks can
|
||||
// miss walls that are near a cell border.
|
||||
if (coord % 0x400 > 0x400 - 50) {
|
||||
if (coord % CELL_SIZE > CELL_SIZE - 50) {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
if (index > 15) {
|
||||
index = 15;
|
||||
if (index > (NUM_CELLS - 1)) {
|
||||
index = (NUM_CELLS - 1);
|
||||
}
|
||||
|
||||
// Potentially < 0, but since lower index is >= 0, not exploitable
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
// NUM_CELLS needs to be a power of 2 so that the bitwise
|
||||
// in surface_collision.c functions can work properly
|
||||
#define NUM_CELLS 16
|
||||
|
||||
struct SurfaceNode
|
||||
{
|
||||
struct SurfaceNode *next;
|
||||
@@ -23,8 +27,8 @@ typedef struct SurfaceNode SpatialPartitionCell[3];
|
||||
// Needed for bs bss reordering memes.
|
||||
extern s32 unused8038BE90;
|
||||
|
||||
extern SpatialPartitionCell gStaticSurfacePartition[16][16];
|
||||
extern SpatialPartitionCell gDynamicSurfacePartition[16][16];
|
||||
extern SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS];
|
||||
extern SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
|
||||
extern struct SurfaceNode *sSurfaceNodePool;
|
||||
extern struct Surface *sSurfacePool;
|
||||
extern s16 sSurfacePoolSize;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user