diff --git a/conker/Makefile b/conker/Makefile index 039058bd..16b591ca 100644 --- a/conker/Makefile +++ b/conker/Makefile @@ -114,6 +114,10 @@ LDFLAGS = -T $(BUILD_DIR)/$(LD_SCRIPT) -Map $(TARGET).map -T undefined_syms.$(VE $(BUILD_DIR)/$(SRC_DIR)/libultra/audio/%.o: OPT_FLAGS := -g +# n_alStreamCrc5Word was compiled at -O1 in the original (scheduled, register +# locals), unlike the surrounding -g audio code, so it lives in its own TU. +$(BUILD_DIR)/$(SRC_DIR)/libultra/audio/n_streamcrc.c.o: OPT_FLAGS := -O1 + # TODO: blindly move all of this into libultra/audio $(BUILD_DIR)/$(SRC_DIR)/init_17F10.c.o: OPT_FLAGS := -g $(BUILD_DIR)/$(SRC_DIR)/init_17F80.c.o: OPT_FLAGS := -g diff --git a/conker/conker.us.yaml b/conker/conker.us.yaml index 10c6fac8..be7fdb64 100644 --- a/conker/conker.us.yaml +++ b/conker/conker.us.yaml @@ -774,7 +774,8 @@ segments: - [0x21F1C0, c, libultra/io/pfsisplug2] # dupe of libultra/io/pfsisplug - [0x21F530, asm, libultra/io/contramread2] # dupe of libultra/io/contramread - [0x21f8e0, asm, libultra/io/contramwrite2] # dupe of libultra/io/contramwrite - - [0x21fc90, c, libultra/audio/game_21FC90] # -g + - [0x21fc90, c, libultra/audio/n_streamcrc] # -O1 (CRC-5/CRC-8 helpers, split out of game_21FC90) + - [0x21fe10, c, libultra/audio/game_21FC90] # -g - [0x221290, c, game_221290] - [0x225d20, asm] - [0x2270a0, asm] diff --git a/conker/include/2.0L/PR/n_libaudio.h b/conker/include/2.0L/PR/n_libaudio.h index c74e3063..06fc3386 100644 --- a/conker/include/2.0L/PR/n_libaudio.h +++ b/conker/include/2.0L/PR/n_libaudio.h @@ -87,6 +87,8 @@ void n_alSynRemovePlayer( ALPlayer *client); void n_alSynSetFXMix(N_ALVoice *v, u8 fxmix); void n_alSynSetFXParam(ALFxRef fx, s16 paramID, void *param); void n_alSynFreeFX(ALFxRef *fx); +void n_alSynFilter11(N_ALVoice *v, u8 arg1); +void n_alSynFilter13(N_ALVoice *v, f32 arg1); void n_alSynSetPan(N_ALVoice *v, u8 pan); void n_alSynSetPitch( N_ALVoice *v, f32 pitch); void n_alSynSetPriority( N_ALVoice *voice, s16 priority); @@ -168,6 +170,33 @@ typedef struct { u8 pad4[0x8]; } N_ALUnknownEvent2; +typedef struct N_ALStreamState { + s32 dataStart; + s32 pad4; + s32 pad8; + s16 pan; + s16 volume; + s16 currentLeft; + s16 currentRight; + s16 pad14; + s16 pad16; + u16 leftRateFrac; + s16 leftRate; + s16 targetLeft; + u16 rightRateFrac; + s16 rightRate; + s16 targetRight; + s16 needsEnvelopeUpdate; + s16 pad26; + s32 rampSamplesDone; + s32 rampSamplesTotal; + u8 pad30[0x58]; + s32 targetVolume; + u8 pad8C[0x4]; + u32 requestedRampSamples; + s16 targetPan; +} N_ALStreamState; + typedef struct { u8 unk0; u8 unk1; @@ -292,6 +321,12 @@ typedef struct { /* 0x8D */ u8 unk8D; } N_ALCSPlayer; +typedef struct N_ALCSPExtraChanState { + u8 pad0[0x24]; + s32 releaseTime; + u8 useCustomReleaseTime; +} N_ALCSPExtraChanState; + /* * Sequence data representation routines @@ -300,7 +335,7 @@ void n_alSeqNextEvent(ALSeq *seq, N_ALEvent *event); void n_alSeqNewMarker(ALSeq *seq, ALSeqMarker *m, u32 ticks); void n_alCSeqNew(ALCSeq *seq, u8 *ptr); -void n_alCSeqNextEvent(ALCSeq *seq, N_ALEvent *evt); +void n_alCSeqNextEvent(ALCSeq *seq, N_ALEvent *evt, s32 arg2); void n_alCSeqNewMarker(ALCSeq *seq, ALCSeqMarker *m, u32 ticks); @@ -377,7 +412,59 @@ typedef struct { /* 0x50 */ ALMicroTime curTime; } N_ALSndPlayer; -void n_alSndpNew(N_ALSndPlayer *sndp, ALSndpConfig *c); +typedef struct N_ALSndpSoundState { + /* 0x00 */ ALLink node; + /* 0x08 */ u8 pad8[0x4]; + /* 0x0C */ ALSound *sound; + /* 0x10 */ u8 voice[0x20]; /* Embedded N_ALVoice storage; Conker's local header is truncated to 0x20 bytes. */ + /* 0x30 */ f32 basePitch; + /* 0x34 */ f32 pitch; + /* 0x38 */ struct N_ALSndpSoundState **handle; + /* 0x3C */ ALBank *bank; + /* 0x40 */ s32 retryCount; + /* 0x44 */ u16 vol; + /* 0x46 */ u8 pad46[0x6]; + /* 0x4C */ s16 soundNum; + /* 0x4E */ s8 priority; + /* 0x4F */ u8 pan; + /* 0x50 */ u8 fxmix; + /* 0x51 */ u8 fxbus; + /* 0x52 */ u8 pad52; + /* 0x53 */ u8 flags; + /* 0x54 */ u8 state; +} N_ALSndpSoundState; + +typedef struct { + /* 0x00 */ ALPlayer node; + /* 0x14 */ ALEventQueue evtq; + /* 0x28 */ N_ALEvent nextEvent; + /* 0x38 */ N_ALSynth *drvr; + /* 0x3C */ s32 target; + /* 0x40 */ N_ALSndpSoundState *sndState; + /* 0x44 */ s32 maxSounds; + /* 0x48 */ ALMicroTime frameTime; + /* 0x4C */ ALMicroTime nextDelta; + /* 0x50 */ ALMicroTime curTime; + /* 0x54 */ s32 soundTableCount; +} N_ALSndPlayerExtended; + +typedef struct { + s16 type; + u8 pad2[2]; + N_ALSndpSoundState *state; + u8 pad8[8]; +} N_ALSndpEventPayload; + +typedef struct { + /* 0x00 */ s32 maxStates; + /* 0x04 */ s32 maxEvents; + /* 0x08 */ s32 maxSounds; + /* 0x0C */ ALHeap *heap; + /* 0x10 */ s32 soundTableCount; + /* 0x14 */ u16 maxVolumes; +} N_ALSndpConfig; + +void n_alSndpNew(N_ALSndpConfig *c); void n_alSndpDelete(void); ALSndId n_alSndpAllocate(ALSound *sound); void n_alSndpDeallocate(ALSndId id); diff --git a/conker/include/2.0L/PR/n_libaudio_s_to_n.h b/conker/include/2.0L/PR/n_libaudio_s_to_n.h index de3e0f9c..87b0862b 100644 --- a/conker/include/2.0L/PR/n_libaudio_s_to_n.h +++ b/conker/include/2.0L/PR/n_libaudio_s_to_n.h @@ -91,7 +91,7 @@ #define ALSndpEvent N_ALSndpEvent #define ALSndPlayer N_ALSndPlayer -#define alSndpNew( a, b) n_alSndpNew( a, b) +#define alSndpNew( a, b) n_alSndpNew( b) #define alSndpDelete( a) n_alSndpDelete() #define alSndpAllocate( a, b) n_alSndpAllocate( b) #define alSndpDeallocate( a, b) n_alSndpDeallocate( b) diff --git a/conker/include/functions.h b/conker/include/functions.h index 382b4681..9debf82b 100644 --- a/conker/include/functions.h +++ b/conker/include/functions.h @@ -108,29 +108,36 @@ void func_1001263C(s32 arg0, s32 arg1, s32 arg2); void func_100126E8(s32 arg0, s32 arg1); s32 func_10012718(u16 arg0, struct127 *arg1, s32 arg2, s16 arg3, u16 arg4); s32 func_100127D0(void); -void func_10012A28(struct121 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_10012B84(struct11 *arg0, s32 arg1); -void func_10012BD0(struct11 *arg0, s32 arg1); +s32 n_alStreamGetState(void); +void n_alStreamStart(s32 dataStart, s32 dataLength); +void n_alStreamSetPan(s32 pan, s32 immediate); +void n_alStreamSetLoadInfo(s32 commandCount, s32 sampleRate); +void n_alStreamSetDoneCallback(void (*callback)(s32)); +void n_alStreamSetVolumeRamp(s32 volume, s32 rampSamples); +void n_alStreamForceStop(void); +void n_alStreamResume(void); +void n_alStreamStop(void); +void n_alBnkfPatchBank(struct121 *bank, s32 bankFileOffset, s32 sampleTableOffset, s32 sampleBankBase); +void n_alBnkfPatchSingleWaveBaseList(struct11 *waveList, s32 sampleBankBase); +void n_alBnkfPatchWaveBaseList(struct11 *waveList, s32 sampleBankBase); void func_10012C5C(struct9 *arg0, s32 arg1, s32 arg2); void func_10012CFC(struct12 *arg0, s32 arg1, s32 arg2); -f32 func_10012D80(u8 arg0); -s32 func_10012E04(s32 *arg0, f32 *arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5); -s32 func_10012F94(struct124 *arg0, f32 *arg1); -void func_100131D8(s32 *arg0); -void func_100131FC(struct13 *arg0, s32 arg1); -void func_10015550(struct26 *arg0, s32 arg1); -s32 func_10015878(struct04 *arg0); -void func_10016E90(struct31 *arg0); -void func_10016F00(struct154 *arg0); -struct31 *func_10017100(s32 arg0, s16 arg1); -void func_10017298(struct31 *arg0); -s32 func_100173C4(struct31 **arg0); -void func_10017594(struct31 *arg0); -void func_100176C4(void); -void func_100176EC(void); -void func_10017714(s32 arg0, s16 arg1, s32 arg2); -void func_10017870(u8 arg0); -void func_10017944(s32 arg0, u32 arg1); +f32 n_alOscDepthToCents(u8 depth); +s32 n_alOscInit(s32 *oscState, f32 *initValue, u8 oscType, u8 oscRate, u8 oscDepth, u8 oscDelay); +s32 n_alOscUpdate(struct124 *oscState, f32 *updateValue); +void n_alOscStop(s32 *oscState); +void n_alOscSetCallbacks(struct13 *arg0, s32 arg1); +s32 _n_sndpVoiceHandler(struct04 *arg0); +struct31 *sndp_alloc_state(s32 arg0, s16 arg1); +void sndp_free_state2(struct31 *arg0); +s32 sndp_get_state(struct31 **arg0); +void sndp_post_stopall_event(struct31 *arg0); +void sndp_stop_all(void); +void sndp_stop_nodecays(void); +void sndp_post_event(struct31 *arg0, s16 arg1, s32 arg2); +void n_alSndpSetChannelValue(u8 channel, u16 value); +void n_alSndpSetOutputMode(u8 outputMode); +void n_alSndpSetOutputRoute(s32 slot, u32 route); s32 func_10017A80(struct26 *arg0); void func_10017AA0(struct26 *arg0); void func_10017AF0(struct26 *arg0, s32 arg1); @@ -148,20 +155,24 @@ void n_alClose(s32 arg0); s32 _n_timeToSamplesNoRound(s32 micros); s32 _n_timeToSamples(s32 micros); f32 alCents2Ratio(s32 arg0); -void func_10019B50(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_10019C28(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_10019CD0(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_10019D6C(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_10019ED8(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_10019F38(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_10019F98(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_1001A224(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_1001A2F8(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_1001A39C(struct26 *arg0, s32 arg1, s32 arg2, u32 arg3); -void func_1001A3E0(struct24 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_1001A3FC(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_1001A9DC(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); -void func_1001AA08(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPHandleChlVolCtrl(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPHandleChlPanCtrl(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPHandleChlPriorityCtrl(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPPostOsMesg(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPSetChlFxId(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPSetChlFilter12(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPSetChlFilter13Pitch(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPSetChlFilter11(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPSetChlSustain(struct26 *arg0, s32 arg1, s32 arg2, u32 arg3); +void n_alCSPSetChlFXMix80(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPSetChlFXMix7F(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPSetChlFXBus(struct26 *arg0, s32 arg1, s32 arg2, u32 arg3); +void n_alCSPSetStreamFileGroup(struct24 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPPlayStreamFile(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPStartChlFade(struct26 *arg0, struct25 *arg1, s32 arg2, s32 arg3); +void n_alCSPStepChlFade(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPSetChlFadeSpeed(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); +void n_alCSPSetChlFadeEnd(struct26 *arg0, s32 arg1, s32 arg2, s32 arg3); s32 __n_vsDelta(struct07 *arg0, s32 arg1); void func_1001B620(struct26 *arg0, s32 arg1); void func_1001CBF0(f32 arg0, f32 arg1, f32 arg2, struct17 *arg3, struct17 *arg4); @@ -169,7 +180,7 @@ void func_1001CD54(struct125 *arg0); f32 func_1001CEA4(s32 arg0); void func_1001D6E8(struct42 *arg0, s32 (*arg1)(s32 arg), struct15 *arg2); s32 func_1001D9B0(s16 arg0); -s32 func_1001DA28(s16 arg0); +ALFxRef n_alSynGetOutputLPRef(s16 bus); void func_1001DAA0(s32 arg0, s16 arg1, s32 arg2); void func_1001DAE4(struct139 *arg0, s16 arg1, s32 *arg2); // void func_1001E170(struct22 *arg0, s32 *w, f32 pitch, s16 vol, u8 pan, u8 fxmix, u8 arg6, f32 arg7, u8 arg8, s32 arg9); @@ -989,12 +1000,9 @@ void func_100114D0(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s //func_10012020 //func_1001263C //func_100126E8 -// void func_10017870(u8 arg0); -void func_100186DC(void *arg0, void *arg1); -void func_10018790(void *arg0, s32 arg1, u32 arg2, u32 arg3); -// void func_10019D98(struct26 *arg0, u8 arg1); -// void func_1001A030(struct26 *arg0, s32 arg1, s32 arg2, u32 arg3); -// void func_1001A508(struct26 *arg0, struct25 *arg1, s32 arg2, s32 arg3); +// void n_alSndpSetOutputMode(u8 outputMode); +void n_alCSeqNewLoopStartMarkers(ALCSeq *seq, ALCSeqMarker *m, u32 markerCount, u32 firstLoopIndex); +// void n_alCSPApplyChlFilterPitch(struct26 *arg0, u8 arg1); //func_1001AAE0 //func_1001ADA4 //func_1001AFEC @@ -1124,7 +1132,8 @@ void func_151D9B8C(u8 arg0, f32 arg1, u8 arg2, s32 arg3, struct17 *arg4, s16 arg void func_151DA08C(u8 arg0, f32 arg1, f32 arg2, u8 arg3, s16 arg4, s32 arg5, void *arg6, s32 arg7, s32 arg8); void func_151DBCBC(u8 arg0, f32 arg1, s16 arg2, s32 arg3, void *arg4, u8 arg5, s32 arg6); void func_151EF954(f32 arg0[4][4], f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7); -void func_151F3C4C(void); +void n_alStreamSetReadCallback(s32 (*readCallback)(void *state, void *dst, s32 len, s32 offset)); +s32 n_alStreamRead(void *state, void *dst, s32 len, s32 offset); void func_151FA130(void); void func_1019EA88(void); #endif diff --git a/conker/include/macro.inc b/conker/include/macro.inc index b02b19df..2d1d6a81 100644 --- a/conker/include/macro.inc +++ b/conker/include/macro.inc @@ -15,7 +15,13 @@ \label: .endm +.macro enddlabel label +.endm + .macro jlabel label .global \label \label: .endm + +.macro nonmatching label, size +.endm diff --git a/conker/include/structs.h b/conker/include/structs.h index e6017876..350438b3 100644 --- a/conker/include/structs.h +++ b/conker/include/structs.h @@ -270,7 +270,7 @@ typedef struct { s32 unk2C; s32 unk30; s16 unk34; - s8 unk36; + u8 streamFileGroup; } struct24; struct struct27 { diff --git a/conker/include/variables.h b/conker/include/variables.h index 29508e72..ea666224 100644 --- a/conker/include/variables.h +++ b/conker/include/variables.h @@ -4,6 +4,8 @@ #include "structs.h" #include "sched.h" +struct N_ALStreamState; + /* defined */ // 0x0002C200 @@ -1367,7 +1369,7 @@ extern s32 D_800E0964; extern s16 D_800E0968[]; extern s32 D_800E0990[]; extern u8 D_800E0A10; -extern struct186 D_800E0D80; // libaudio struct? +extern struct N_ALStreamState D_800E0D80; // end of zero'd out section diff --git a/conker/src/game_161520.c b/conker/src/game_161520.c index 2c5e6185..1552ea12 100644 --- a/conker/src/game_161520.c +++ b/conker/src/game_161520.c @@ -2,6 +2,8 @@ #include "functions.h" #include "variables.h" +extern f32 D_800A4828; + // requires jump table #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15134070.s") @@ -90,7 +92,8 @@ void func_1513477C(struct102 *arg0) { #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_151347CC.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_151348F0.s") +void func_151348F0(f32 arg0, f32 arg1, s32 arg2, s32 arg3) { +} #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15134908.s") @@ -98,7 +101,8 @@ void func_1513477C(struct102 *arg0) { #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15134C98.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15134CD4.s") +void func_15134CD4(f32 arg0, f32 arg1, s32 arg2, s32 arg3) { +} #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15134CEC.s") @@ -106,9 +110,13 @@ void func_1513477C(struct102 *arg0) { #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15134E48.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_151352EC.s") +void func_151352EC(struct102 *arg0) { + func_15169804(arg0); +} -#pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_1513530C.s") +void func_1513530C(struct102 *arg0) { + func_15169824(arg0); +} #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_1513532C.s") @@ -122,7 +130,12 @@ void func_1513477C(struct102 *arg0) { #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_151355B8.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15135658.s") +s32 func_15135658(struct259 *arg0) { + s32 ret = 1; + + arg0->unk74 = 1.0f; + return ret; +} f32 func_15135670(s32 arg0) { // "power", "../Effects/Blood/blood.c" @@ -143,7 +156,17 @@ f32 func_15135670(s32 arg0) { #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15136918.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15136A1C.s") +s32 func_15136A1C(struct102 *arg0) { + s16 idx = arg0->unk1C; + + if (idx < 32) { + s32 value = idx * 8; + if (value < arg0->unk28) { + arg0->unk28 = value; + } + } + return 1; +} #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15136A50.s") @@ -159,7 +182,10 @@ f32 func_15135670(s32 arg0) { #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15137C64.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15137E10.s") +s32 func_15137E10(struct259 *arg0) { + arg0->unk74 = ((func_150ADA68() * 50.0f) + 580.0f) * D_800A4828; + return 1; +} #pragma GLOBAL_ASM("asm/nonmatchings/game_161520/func_15137E60.s") diff --git a/conker/src/game_169510.c b/conker/src/game_169510.c index c59b819a..27ab92c2 100644 --- a/conker/src/game_169510.c +++ b/conker/src/game_169510.c @@ -526,15 +526,48 @@ void func_1513F680(struct171 *arg0, u8 arg1, u8 arg2, u8 arg3, u8 arg4) { arg0->unk73 = arg4; } -#pragma GLOBAL_ASM("asm/nonmatchings/game_169510/func_1513F6C0.s") - +void func_1513F6C0(struct210 *arg0, u8 arg1, u8 arg2) { + arg0->unk80 = arg1; + arg0->unk81 = arg2; +} + +// s32 func_1513F6E8(void *arg0_raw) { +// typedef struct { +// u8 pad0[0x2C]; +// f32 unk2C; +// f32 unk30; +// u8 pad34[0xF4]; +// f32 unk128; +// } Game169510Motion; +// +// Game169510Motion *arg0 = (Game169510Motion *)arg0_raw; +// f32 value = arg0->unk128; +// +// arg0->unk2C += value * D_800BE9A4; +// arg0->unk30 += value * D_800BE9A4; +// return 1; +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_169510/func_1513F6E8.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_169510/func_1513F728.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_169510/func_1513FA2C.s") +void func_1513FAB4(void *arg0, s32 arg1, f32 *arg2, s16 arg3); -#pragma GLOBAL_ASM("asm/nonmatchings/game_169510/func_1513FA70.s") +void func_1513FA2C(void *arg0, s16 arg1) { + f32 sp18[2]; + + sp18[0] = 1.0f; + sp18[1] = 1.0f; + func_1513FAB4(arg0, 0, sp18, arg1); +} + +void func_1513FA70(void *arg0, s16 arg1) { + f32 sp18[2]; + + sp18[0] = 1.0f; + sp18[1] = 1.0f; + func_1513FAB4(arg0, 1, sp18, arg1); +} #pragma GLOBAL_ASM("asm/nonmatchings/game_169510/func_1513FAB4.s") diff --git a/conker/src/game_16DC80.c b/conker/src/game_16DC80.c index f2dd9c70..b707b675 100644 --- a/conker/src/game_16DC80.c +++ b/conker/src/game_16DC80.c @@ -3,7 +3,6 @@ #include "functions.h" #include "variables.h" - #pragma GLOBAL_ASM("asm/nonmatchings/game_16DC80/func_151407D0.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16DC80/func_151408A4.s") @@ -16,8 +15,22 @@ void func_151411C4(struct210 *arg0) { func_1513CAA0(arg0); } +// void func_151411E4(Game16DC80Obj *arg0) { +// if (arg0->unk154 != 0) { +// func_1517E134(arg0->unk154); +// } +// D_800DC9F0--; +// D_80089F9C[arg0->unk168](arg0); +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_16DC80/func_151411E4.s") +// void func_15141250(Game16DC80Obj *arg0) { +// if (arg0->unk154 != 0) { +// func_1517E134(arg0->unk154); +// } +// D_800DC9F0--; +// D_80089FE4[arg0->unk168](arg0); +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_16DC80/func_15141250.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16DC80/func_151412BC.s") @@ -63,9 +76,11 @@ s32 func_15141818(s32 arg0, s32 arg1) { // return temp_f0; // } -#pragma GLOBAL_ASM("asm/nonmatchings/game_16DC80/func_15141928.s") -// s32 func_15141928(void *arg0) { -// void *temp_v0 = arg0->unk178; -// func_1514182C(arg0, arg0->unk17C, arg0->unk170, arg0->unk174, temp_v0->unk0, temp_v0->unk8); +// s32 func_15141928(Game16DC80Obj *arg0) { +// Game16DC80Vec3f *temp_v0; +// +// temp_v0 = arg0->unk178; +// func_1514182C(arg0, &arg0->unk17C, arg0->unk170, arg0->unk174, temp_v0->unk0, temp_v0->unk8); // return 1; // } +#pragma GLOBAL_ASM("asm/nonmatchings/game_16DC80/func_15141928.s") diff --git a/conker/src/game_16EE20.c b/conker/src/game_16EE20.c index 46dc83c4..3c46990c 100644 --- a/conker/src/game_16EE20.c +++ b/conker/src/game_16EE20.c @@ -4,6 +4,10 @@ #include "variables.h" +extern f32 D_800A5624; +extern f32 D_800A5628; +void func_15143794(s16 arg0, s16 arg1, f32 arg2); + void func_15141970(struct37 *arg0) { func_1514EDF0(arg0, arg0->unk2C); } @@ -95,17 +99,40 @@ s32 func_151422F8(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142838.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142914.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_151429E0.s") +// s32 func_15142A5C(struct127 *arg0) { +// typedef struct { +// u8 pad0[0x3C]; +// s16 unk3C; +// } struct197_local; +// +// struct197_local *temp_v0 = (struct197_local *)arg0->unk2D0; +// +// if (temp_v0->unk3C > 0) { +// return 1; +// } +// return 0; +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142A5C.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142A80.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142AC0.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142B04.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142B44.s") +f32 func_15142A80(f32 arg0) { + return ((1.0f - arg0) * (arg0 - 2.0f) * arg0) * D_800A5624; +} +f32 func_15142AC0(f32 arg0) { + return ((arg0 + 1.0f) * (arg0 - 1.0f) * (arg0 - 2.0f)) * 0.5f; +} +f32 func_15142B04(f32 arg0) { + return ((2.0f - arg0) * (arg0 + 1.0f) * arg0) * 0.5f; +} +f32 func_15142B44(f32 arg0) { + return ((arg0 + 1.0f) * (arg0 - 1.0f) * arg0) * D_800A5628; +} #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142B7C.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142C10.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142CF0.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142E24.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15142FBC.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15143044.s") +s32 func_15143044(u8 arg0, s32 arg1) { + return (s16)(0x7FFF - arg0); +} #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_1514306C.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15143134.s") @@ -165,7 +192,9 @@ s32 func_151422F8(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_151436B4.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_1514373C.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15143794.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15143834.s") +void func_15143834(s16 arg0, s16 arg1, f32 arg2) { + func_15143794(arg0, arg1, arg2); +} #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15143874.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_151438D8.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15143D18.s") @@ -176,7 +205,13 @@ s32 func_15143E08(struct127 *arg0) { } #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15143E24.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15143E64.s") +f32 func_15143E64(f32 *arg0) { + f32 x = arg0[0]; + f32 y = arg0[1]; + f32 z = arg0[2]; + + return sqrtf((x * x) + (y * y) + (z * z)); +} #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15143E94.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_1514401C.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_151441A4.s") @@ -188,7 +223,9 @@ s32 func_15143E08(struct127 *arg0) { #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_1514470C.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15144A74.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15144AA8.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15144B34.s") +f32 *func_15144B34(s32 arg0) { + return &D_800DBFF0[arg0].unk2F8; +} #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15144B68.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_16EE20/func_15144BC8.s") diff --git a/conker/src/game_1897A0.c b/conker/src/game_1897A0.c index 3798d88f..d93e69e8 100644 --- a/conker/src/game_1897A0.c +++ b/conker/src/game_1897A0.c @@ -3,6 +3,15 @@ #include "functions.h" #include "variables.h" +typedef struct { + u8 pad0[0x25]; + u8 unk25; + u8 pad26[0x6]; + s8 unk2C; + u8 pad2D; + s8 unk2E; +} Game1897A0Ring; + #pragma GLOBAL_ASM("asm/nonmatchings/game_1897A0/func_1515C2F0.s") // void *func_1515C2F0(void *arg0, void *arg1, s32 arg2, s32 arg3, u8 arg4, s32 arg5) { @@ -47,25 +56,22 @@ // return 1; // } -#pragma GLOBAL_ASM("asm/nonmatchings/game_1897A0/func_1515D030.s") -// s32 func_1515D030(void *arg0, ? arg1) { -// s8 temp_v0; -// s32 phi_v1; +// s32 func_1515D030(Game1897A0Ring *arg0, s32 arg1) { +// s32 ret; // -// temp_v0 = arg0->unk2C; -// if ((s32) temp_v0 >= 3) { -// arg0->unk2C = (s8) (temp_v0 - 1); -// arg0->unk2E = (s8) (arg0->unk2E - 1); -// phi_v1 = 1; -// if ((s32) arg0->unk2E < 0) { -// arg0->unk2E = (s8) (arg0->unk25 - 1); -// phi_v1 = 1; +// ret = 1; +// if (arg0->unk2C >= 3) { +// arg0->unk2C = arg0->unk2C - 1; +// arg0->unk2E = arg0->unk2E - 1; +// if (arg0->unk2E < 0) { +// arg0->unk2E = arg0->unk25 - 1; // } // } else { -// phi_v1 = 0; +// ret = 0; // } -// return phi_v1; +// return ret; // } +#pragma GLOBAL_ASM("asm/nonmatchings/game_1897A0/func_1515D030.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1897A0/func_1515D088.s") // s32 func_1515D088(void *arg0) { diff --git a/conker/src/game_1944C0.c b/conker/src/game_1944C0.c index c012c69c..2a5ec8b6 100644 --- a/conker/src/game_1944C0.c +++ b/conker/src/game_1944C0.c @@ -4,6 +4,44 @@ #include "variables.h" +void func_15168B10(s32 arg0, s32 arg1); +void *func_15167A68(s32 arg0, s32 arg1, s32 arg2, s32 arg3, u8 arg4, s32 arg5); +extern u8 D_800D2DAB; + +typedef struct { + u8 pad0[0xE4]; + u8 unkE4; +} Game1944C0Dispatch; + +typedef struct { + u8 pad0[0x40]; + s32 unk40; +} Game1944C0CopySrc; + +typedef struct { + u8 pad0[0x90]; + u8 unk90[0x60]; +} Game1944C0CopyDst; + +typedef struct { + u8 pad0[0x3B]; + u8 unk3B; +} Game1944C0Payload; + +typedef struct { + void *payload; + u8 unk4; +} Game1944C0StackPayload; + +typedef struct { + u8 pad0[0xC]; + u8 unkC; +} Game1944C0EventObject; + +typedef struct { + u8 unk0; +} Game1944C0EventPayloadHeader; + #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15167010.s") // NON-MATCHING: not hugely far away // void func_15167010(void) { @@ -20,6 +58,25 @@ // } #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_1516706C.s") +// NEAR-MATCHING: loop body matches, but IDO schedules the setup as +// `addiu s0, D_8008CB64` before `addiu s1, D_8008CB70`; target asm needs +// the low-half setup in `s1` then `s0` order. Reordering declarations flips +// both high-half and low-half setup instead of only the low-half instructions. +// extern void (*D_8008CB64[])(void); +// extern void (*D_8008CB70[])(void); +// void func_1516706C(void) { +// void (**table)(void) = D_8008CB64; +// void (**end)(void) = D_8008CB70; +// void (*func)(void); +// +// do { +// func = *table; +// if (func != NULL) { +// func(); +// } +// table++; +// } while (table != end); +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_151670C0.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_151671E8.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15167310.s") @@ -34,7 +91,9 @@ #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_1516865C.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168800.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168870.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168A2C.s") +void func_15168A2C(s32 arg0) { + func_15168B10(arg0, 0); +} #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168A4C.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168A9C.s") // void *func_15168A9C(struct12 *arg0) { @@ -64,26 +123,110 @@ void func_15168B10(s32 arg0, s32 arg1) { } #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168B44.s") +// void func_15168BAC(Game1944C0Dispatch *arg0) { +// u8 idx = arg0->unkE4; +// +// if (idx != 0) { +// D_8008CA20[idx](arg0); +// } +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168BAC.s") + +// void func_15168BE4(Game1944C0CopySrc *arg0, u8 arg1, s32 arg2) { +// Game1944C0CopyDst *temp_v0; +// +// if (arg0->unk40 != 0) { +// temp_v0 = func_15167A68(0x10, arg2, 0xF0, 1, arg1, 1); +// if (temp_v0 != NULL) { +// bcopy(arg0, temp_v0->unk90, 0x60); +// } +// } +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168BE4.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168C4C.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168E34.s") +void func_15168E34(u32 *arg0, u32 arg1) { + u32 value = *arg0; + + if ((value & 0x0F000000) == 0) { + *arg0 = value + arg1; + } +} #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168E54.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168F08.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15168F84.s") +void func_15168F84(s32 arg0, s32 *arg1, s32 *arg2) { + if (arg0 == 0) { + *arg1 = 1; + *arg2 = 0x41; + return; + } + if (arg0 == 1) { + *arg1 = 0x42; + *arg2 = 0x4F; + return; + } + if (arg0 == 2) { + *arg1 = 0x50; + *arg2 = 0x58; + return; + } + if (arg0 == 3) { + *arg1 = 0x59; + *arg2 = 0x5C; + return; + } + if (arg0 == 5) { + *arg1 = 0x61; + *arg2 = 0x63; + return; + } + if (arg0 == 6) { + *arg1 = 0x64; + *arg2 = 0x65; + return; + } + *arg1 = 0x5D; + *arg2 = 0x60; +} #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15169040.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15169070.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15169260.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_1516944C.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_151695F0.s") +// void func_1516962C(s32 arg0, Game1944C0Payload *arg1, u8 arg2) { +// Game1944C0StackPayload sp18; +// +// sp18.payload = arg1; +// sp18.unk4 = arg1->unk3B; +// func_1516944C(arg0, (s32)&sp18, arg2); +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_1516962C.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_15169668.s") +s32 func_15169668(s32 arg0, s32 arg1, s32 arg2, s32 arg3) { + D_800D2DAB = 1; + return arg0; +} +// void func_1516968C(Game1944C0EventObject *arg0, Game1944C0EventPayloadHeader *arg1, u8 arg2) { +// if ((arg2 == 0xF) || (arg2 == 0x10)) { +// if (arg1->unk0 == arg0->unkC) { +// func_1516972C(arg0); +// } +// } +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_1516968C.s") + +// void func_151696DC(struct102 *arg0) { +// s32 i; +// +// for (i = 0; i < D_800DD190; i = (s8)(i + 1)) { +// if (arg0 == ((void **)D_800DD198)[i]) { +// ((void **)D_800DD198)[i] = (void *)arg0->unk8; +// } +// } +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_1944C0/func_151696DC.s") void func_1516972C(struct102 *arg0) { void (*func)(struct102 *arg0); - func_151696DC(); + func_151696DC(arg0); if (arg0->unk0 >= 2) { func = D_8008B4D0[arg0->unk0].unk0; @@ -98,7 +241,7 @@ void func_1516972C(struct102 *arg0) { void func_1516979C(struct102 *arg0) { void (*func)(struct102 *arg0); - func_151696DC(); + func_151696DC(arg0); func = D_8008B4D4[arg0->unk0].unk0; if (func != NULL) { func(arg0); diff --git a/conker/src/game_2D4B0.c b/conker/src/game_2D4B0.c index 06e5f18d..386aba20 100644 --- a/conker/src/game_2D4B0.c +++ b/conker/src/game_2D4B0.c @@ -414,7 +414,7 @@ void func_15000090(void) { // func_1000E40C(sp66, sp68); // } // } -// func_10017944(1, sp6D); +// n_alSndpSetOutputRoute(1, sp6D); // } #pragma GLOBAL_ASM("asm/nonmatchings/game_2D4B0/func_150006E0.s") diff --git a/conker/src/game_30E90.c b/conker/src/game_30E90.c index 9e4acd1b..ff688916 100644 --- a/conker/src/game_30E90.c +++ b/conker/src/game_30E90.c @@ -19,15 +19,16 @@ void func_150045BC(void) { #pragma GLOBAL_ASM("asm/nonmatchings/game_30E90/func_150045C4.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_30E90/func_150049A4.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_30E90/func_15004A4C.s") -// NON-MATCHING: not this... + // void func_15004A4C(void) { -// u32 i; +// s32 i; +// // for (i = 0; i < D_800DBEF0; i++) { -// D_800DBEFC[i] = D_800DBEF8[i] = 0; -// // D_800DBEFC[i] = 0; +// ((s32 *)D_800DBEF8[0])[i] = 0; +// ((s8 *)*((s32 *)D_800DBEFC))[i] = 0; // } // } +#pragma GLOBAL_ASM("asm/nonmatchings/game_30E90/func_15004A4C.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_30E90/func_15004AAC.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_30E90/func_15004BF0.s") diff --git a/conker/src/game_40490.c b/conker/src/game_40490.c index 86ac98d1..f8ec6fbd 100644 --- a/conker/src/game_40490.c +++ b/conker/src/game_40490.c @@ -146,6 +146,17 @@ s32 func_1501407C(s32 arg0) { #pragma GLOBAL_ASM("asm/nonmatchings/game_40490/func_15014144.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_40490/func_15014220.s") +// s32 func_150142AC(struct134 *arg0) { +// s32 idx; +// +// arg0->unk16 |= 4; +// idx = ((struct133 *)arg0)->unk1B; +// if ((idx < 0) || (idx >= 3)) { +// return 1; +// } +// D_800D9AA0[idx] = arg0; +// return 1; +// } #pragma GLOBAL_ASM("asm/nonmatchings/game_40490/func_150142AC.s") #pragma GLOBAL_ASM("asm/nonmatchings/game_40490/func_150142EC.s") diff --git a/conker/src/game_43620.c b/conker/src/game_43620.c index 2e8bd4da..300aff91 100644 --- a/conker/src/game_43620.c +++ b/conker/src/game_43620.c @@ -29,5 +29,5 @@ // D_800E0D80.unk24 = 1; // D_800E0D80.unk14 = 0x7FFC; // D_800E0D80.unk16 = 0; -// func_151F3C34(func_151F3C4C, tmp, 64); +// n_alStreamSetReadCallback(n_alStreamRead); // } diff --git a/conker/src/game_981E0.c b/conker/src/game_981E0.c index 11eac3ad..3bdf7348 100644 --- a/conker/src/game_981E0.c +++ b/conker/src/game_981E0.c @@ -1449,7 +1449,10 @@ void func_15072AF8(void) { } #pragma GLOBAL_ASM("asm/nonmatchings/game_981E0/func_15072B44.s") -#pragma GLOBAL_ASM("asm/nonmatchings/game_981E0/func_15072DA0.s") +void func_15072DA0(void) { + D_800D154C->unk2F8 &= 0xFFF8; + D_800D154C->unk2F8 |= D_800D1580; +} void func_15072DD8(void) { func_15083568(D_800D154C, D_800D1580, 1.0f, 0); diff --git a/conker/src/init_12560.c b/conker/src/init_12560.c index a88f269d..77ded51c 100644 --- a/conker/src/init_12560.c +++ b/conker/src/init_12560.c @@ -11,18 +11,18 @@ void func_10012560(s32 arg0) { void func_10012588(s32 arg0) { func_15016170(arg0); func_15043A00(&D_800427A0, &D_800427B0, 64); - func_151F3C1C(func_10012560); + n_alStreamSetDoneCallback(func_10012560); } void func_100125CC(s32 arg0) { - s32 res = func_151F2CDC(); + s32 res = n_alStreamGetState(); if ((arg0 != 30) || (D_800BE9F8 != 27)) { if (res == 1) { - func_151F2D6C(0, 11010); + n_alStreamSetVolumeRamp(0, 11010); return; } if (res != 0) { - func_151F2BA8(); + n_alStreamForceStop(); } } } @@ -35,14 +35,14 @@ void func_1001263C(s32 arg0, s32 arg1, s32 arg2) { temp_v0 = func_1502B020(&sp18, 2, 22, arg0); D_800427F4 = (s16) arg0; if ((temp_v0 != 0) && (sp18 != 0)) { - func_151F2D6C(arg1, 0); - func_151F2DFC(arg2, 1); + n_alStreamSetVolumeRamp(arg1, 0); + n_alStreamSetPan(arg2, 1); if (arg0 != 0xD2) { - func_151F2E4C(10, 11000); + n_alStreamSetLoadInfo(10, 11000); } else { - func_151F2E4C(0, 0); + n_alStreamSetLoadInfo(0, 0); } - func_151F2960(temp_v0, sp18); + n_alStreamStart(temp_v0, sp18); } } @@ -65,7 +65,7 @@ s32 func_10012718(u16 arg0, struct127 *arg1, s32 arg2, s16 arg3, u16 arg4) { } s32 func_100127D0(void) { - s32 tmp = func_151F2CDC(); + s32 tmp = n_alStreamGetState(); if (tmp == 1 || tmp == 2 || tmp == 5) { return 1; diff --git a/conker/src/init_8180.c b/conker/src/init_8180.c index 7b8c14da..470dcf6a 100644 --- a/conker/src/init_8180.c +++ b/conker/src/init_8180.c @@ -1,10 +1,8 @@ +#include #include #include "macros.h" - -typedef struct { - u8 pad0[0x760]; -} struct247; // something naudio related? +#include "structs.h" extern N_ALCSPlayer *D_8003C900[]; extern ALCSeq D_8003CA58[]; @@ -24,7 +22,7 @@ void func_10017D80(N_ALCSPlayer *arg0, u8 arg1, u8 arg2); void func_10017DF0(N_ALCSPlayer *csp, f32 arg1, f32 arg2); void func_10017E4C(N_ALCSPlayer *csp, u8 chan, u8 arg2); void func_10017F10(N_ALCSPlayer *arg0, u8 arg1, u8 arg2, u8 arg3, s32 arg4); -void func_10018790(N_ALCSPlayer *arg0, s32 arg1, u32 arg2, u32 arg3); +void n_alCSeqNewLoopStartMarkers(ALCSeq *seq, ALCSeqMarker *m, u32 markerCount, u32 firstLoopIndex); void func_10018D00(N_ALCSPlayer *arg0, s16 arg1); void func_10018D50(N_ALCSPlayer *seqp); @@ -167,13 +165,13 @@ void func_10008BC0(u8 idx, f32 arg1, f32 arg2) { } void func_10008C04(u8 idx, u8 arg1, s32 arg2) { - func_10018790(&D_8003CA58[idx], &D_8003CD48[idx], arg1, arg2); + n_alCSeqNewLoopStartMarkers(&D_8003CA58[idx], &D_8003CD48[idx], arg1, arg2); } #pragma GLOBAL_ASM("asm/nonmatchings/init_8180/func_10008C6C.s") // NON-MATCHING: need to determine what these variables hold // void func_10008C6C(u8 idx, u8 arg1) { -// func_100186DC(&D_8003CA58[idx], &D_8003CD48[idx + (arg1 * 0xEC)]); // (idx * 0x760) +// alCSeqSetLoc(&D_8003CA58[idx], &D_8003CD48[idx + (arg1 * 0xEC)]); // (idx * 0x760) // } #pragma GLOBAL_ASM("asm/nonmatchings/init_8180/func_10008CE8.s") diff --git a/conker/src/init_EB00.c b/conker/src/init_EB00.c index 955ea317..c56e324c 100644 --- a/conker/src/init_EB00.c +++ b/conker/src/init_EB00.c @@ -110,7 +110,7 @@ s32 func_1000EF40(struct57 *arg0, struct57 *arg1, s32 *arg2, s32 arg3, s32 arg4, #pragma GLOBAL_ASM("asm/nonmatchings/init_EB00/func_1000EFB4.s") #pragma GLOBAL_ASM("asm/nonmatchings/init_EB00/func_1000F1A8.s") -void func_10017780(u8 arg0, u16 arg1); +void n_alSndpSetChannelValue(u8 channel, u16 value); s32* allocate_memory(s32, s32, s32, s32); void func_1000F248(s32 arg0) { u16 tmp; @@ -150,9 +150,9 @@ void func_1000F248(s32 arg0) { } func_10011E88(arg0); D_80041F60 = D_80041F61 = 0; - func_10017780(0, D_80041F56); - func_10017780(1, D_80041F56); - func_10017780(2, 23000); + n_alSndpSetChannelValue(0, D_80041F56); + n_alSndpSetChannelValue(1, D_80041F56); + n_alSndpSetChannelValue(2, 23000); // fakematch if (arg0) {} } @@ -163,7 +163,7 @@ s32 func_1000F3D0(u16 arg0) { temp_v1 = &D_800425E0[arg0 & 0xF]; if (temp_v1->unk8 != 0) { if ((temp_v1->unk0 == arg0) || (arg0 == (arg0 & 0xF))) { - if (func_100173C4(&temp_v1->unk8) != 0) { + if (sndp_get_state(&temp_v1->unk8) != 0) { return 1; } } @@ -219,7 +219,7 @@ s32 func_1000F44C(u16 arg0) { // phi_a1 = (u16)0x10; // } // } -// func_10017714((((sp18 & 0xF) * 0xC) + 0x80040000) - 0x25E8, phi_a1, arg2); +// sndp_post_event((((sp18 & 0xF) * 0xC) + 0x80040000) - 0x25E8, phi_a1, arg2); // } // } // } @@ -446,7 +446,7 @@ void func_100111C8(u16 arg0) { if ((tmp->unk8 != 0) && (tmp->unk0 == arg0)) { tmp->unk0 = 0; tmp->unk4 = 0; - func_10017594(tmp->unk8); + sndp_post_stopall_event(tmp->unk8); tmp->unk8 = 0; } } @@ -456,7 +456,7 @@ void func_1001123C(u16 arg0) { if ((tmp->unk8 != 0) && (tmp->unk0 == arg0)) { if (func_100112BC(arg0, 1) == 0) { - func_10017594(tmp->unk8); + sndp_post_stopall_event(tmp->unk8); tmp->unk8 = 0; } } diff --git a/conker/src/libultra/audio/game_21FC90.c b/conker/src/libultra/audio/game_21FC90.c index 610a6eed..7eb631b7 100644 --- a/conker/src/libultra/audio/game_21FC90.c +++ b/conker/src/libultra/audio/game_21FC90.c @@ -1,7 +1,11 @@ #include -extern s32 D_800E0E00; +typedef void (*N_ALStreamDoneCallback)(s32); +typedef s32 (*N_ALStreamReadCallback)(void *state, void *dst, s32 len, s32 offset); + +extern N_ALStreamDoneCallback D_800E0E00; extern s32 D_800E0E04; +extern s32 D_800E0E08; extern s32 D_800E0E10; extern s16 D_800E0E14; extern s16 D_800E0E16; @@ -11,116 +15,285 @@ extern s32 D_800E0E20; extern s32 D_800E0E24; extern s32 D_800E0E28; extern s32 *D_800E0E30; // 0x8000 -extern s32 D_800E0D80; // libaudio struct? +extern s32 D_800E0D80; // First word of N_ALStreamState. extern s16 D_800E0DB0; extern s16 D_800E0DB2; extern s32 D_800E0DD8; extern s32 D_800E0DE0; extern s32 D_800E0DE4; -extern s32 D_800E0DFC; +extern N_ALStreamReadCallback D_800E0DFC; +extern s16 D_8002BC10[]; +extern s16 D_8002BD0E[]; +extern u8 D_800428C1; +extern u8 D_800428C2; + +#define STREAM_VOLUME_LIMIT 0x8000 +#define STREAM_VOLUME_MAX 0x7FFF + +#define STREAM_PREFETCH_SIZE 0x810 +#define STREAM_DMA_CACHED_BASE 0x80000000 +#define STREAM_AUDIO_FRAME_SAMPLES 0xB8 + +#define STREAM_STATE_PLAYING 1 +#define STREAM_STATE_STOPPING 2 +#define STREAM_STATE_TEARDOWN 3 +#define STREAM_STATE_START_PENDING 5 +#define STREAM_STATE_FADE_OUT 6 +#define STREAM_STATE_FADE_IN 7 + +#define STREAM_TRANSITION_DELAY 5 +#define STREAM_LOADING_STATE 4 +#define STREAM_PAN_MIN 0 +#define STREAM_PAN_CENTER 0x40 +#define STREAM_PAN_LIMIT 0x80 +#define STREAM_PAN_MAX 0x7F +#define STREAM_DATA_BUFFER_SIZE 0x8000 +#define STREAM_BANK_ID 0x17 + +#define gStreamState D_800E0E04 +#define gStreamTargetVolume D_800E0E08 +#define gStreamVolumeRampSamples D_800E0E10 +#define gStreamCurrentPan D_800E0E14 +#define gStreamTargetPan D_800E0E16 +#define gStreamTransitionDelay D_800E0E18 +#define gStreamInitialized D_800E0E2C +#define gStreamVoice0 D_800E0E20 +#define gStreamVoice1 D_800E0E24 +#define gStreamVoice2 D_800E0E28 +#define gStreamDataBuffer D_800E0E30 +#define gStreamLoadCommandCount D_800E0DB2 +#define gStreamLoadSampleRate D_800E0DB0 +#define gStreamLoadMode D_800E0DD8 +#define gStreamDoneCallback D_800E0E00 +#define gStreamDataStart D_800E0D80 +#define gStreamDataLength D_800E0DE0 +#define gStreamReadOffset D_800E0DE4 +#define gStreamReadCallback D_800E0DFC +#define gStreamStateBlock (*(N_ALStreamState *) &D_800E0D80) +typedef ALDMAproc (*N_ALStreamDMANew)(void *state); -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/game_21FC90/func_151F27E0.s") +/* Conker stores a stream DMA-new callback in N_ALSynth's custom pad at 0x24. */ +#define n_alStreamDmaNew() (((N_ALStreamDMANew *) n_syn->pad24)[0]) -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/game_21FC90/func_151F2890.s") -void func_151F2960(s32 arg0, s32 arg1) { - if (D_800E0DFC == 0) { +/* The CRC-5/CRC-8 stream helpers (func_151F27E0, func_151F2890) live in their + * own -O1 translation unit (src/libultra/audio/n_streamcrc.c); the rest of this + * file is -g/-O0. */ + +void n_alStreamStart(s32 dataStart, s32 dataLength) { + if (gStreamReadCallback == 0) { return; } - D_800E0E04 = 4; - if (D_800E0E2C == 0) { - D_800E0E2C = 1; - D_800E0E30 = allocate_memory(0x8000, 0xFF, 2, 1); - if (D_800E0E30 == 0) { - D_800E0E2C = 0; + gStreamState = STREAM_LOADING_STATE; + if (gStreamInitialized == 0) { + gStreamInitialized = 1; + gStreamDataBuffer = allocate_memory(STREAM_DATA_BUFFER_SIZE, 0xFF, 2, 1); + if (gStreamDataBuffer == 0) { + gStreamInitialized = 0; return; } - D_800E0E20 = func_1502B5C8(0, 2, 0x17, 4); - if (D_800E0E20 != 0) { - func_100043B4(D_800E0E20, 0xFF); + gStreamVoice0 = func_1502B5C8(0, 2, STREAM_BANK_ID, 4); + if (gStreamVoice0 != 0) { + func_100043B4(gStreamVoice0, 0xFF); } - D_800E0E24 = func_1502B5C8(0, 2, 0x17, 5); - if (D_800E0E24 != 0) { - func_100043B4(D_800E0E24, 0xFF); + gStreamVoice1 = func_1502B5C8(0, 2, STREAM_BANK_ID, 5); + if (gStreamVoice1 != 0) { + func_100043B4(gStreamVoice1, 0xFF); } - D_800E0E28 = func_1502B5C8(0, 2, 0x17, 6); - if (D_800E0E28 != 0) { - func_100043B4(D_800E0E28, 0xFF); + gStreamVoice2 = func_1502B5C8(0, 2, STREAM_BANK_ID, 6); + if (gStreamVoice2 != 0) { + func_100043B4(gStreamVoice2, 0xFF); } - if ((D_800E0E20 == 0) || (D_800E0E24 == 0) || (D_800E0E28 == 0)) { - if (D_800E0E20 != 0) { - func_10004074(D_800E0E20); + if ((gStreamVoice0 == 0) || (gStreamVoice1 == 0) || (gStreamVoice2 == 0)) { + if (gStreamVoice0 != 0) { + func_10004074(gStreamVoice0); } - if (D_800E0E24 != 0) { - func_10004074(D_800E0E24); + if (gStreamVoice1 != 0) { + func_10004074(gStreamVoice1); } - if (D_800E0E28 != 0) { - func_10004074(D_800E0E28); + if (gStreamVoice2 != 0) { + func_10004074(gStreamVoice2); } - func_10004074(D_800E0E30); - D_800E0E30 = 0; - D_800E0E2C = 0; + func_10004074(gStreamDataBuffer); + gStreamDataBuffer = 0; + gStreamInitialized = 0; return; } func_151F3DE0(); } - D_800E0D80 = arg0; - D_800E0DE0 = arg1; - D_800E0DE4 = 0; - D_800E0E10 = 0; - D_800E0E18 = 5; - D_800E0E04 = 5; + gStreamDataStart = dataStart; + gStreamDataLength = dataLength; + gStreamReadOffset = 0; + gStreamVolumeRampSamples = 0; + gStreamTransitionDelay = STREAM_TRANSITION_DELAY; + gStreamState = STREAM_STATE_START_PENDING; } -void func_151F2BA8(void) { +void n_alStreamForceStop(void) { u32 mask = osSetIntMask(1); - D_800E0E04 = 3; + gStreamState = STREAM_STATE_TEARDOWN; osSetIntMask(mask); } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/game_21FC90/func_151F2BE8.s") +void n_alStreamStop(void) { + u32 mask; -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/game_21FC90/func_151F2C4C.s") + mask = osSetIntMask(1); + if (gStreamState == STREAM_STATE_START_PENDING) { + gStreamState = STREAM_STATE_FADE_OUT; + } else { + gStreamState = STREAM_STATE_STOPPING; + } + osSetIntMask(mask); +} -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/game_21FC90/func_151F2CDC.s") +void n_alStreamResume(void) { + u32 mask; -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/game_21FC90/func_151F2D6C.s") + mask = osSetIntMask(1); + if (gStreamState == STREAM_STATE_STOPPING) { + gStreamTransitionDelay = STREAM_TRANSITION_DELAY; + gStreamState = STREAM_STATE_FADE_IN; + } else if (gStreamState == STREAM_STATE_FADE_OUT) { + gStreamTransitionDelay = STREAM_TRANSITION_DELAY; + gStreamState = STREAM_STATE_START_PENDING; + } + osSetIntMask(mask); +} + +s32 n_alStreamGetState(void) { + s32 state; + u32 mask; + + state = 0; + mask = osSetIntMask(1); + if ((gStreamState == STREAM_STATE_PLAYING) || + (gStreamState == STREAM_STATE_START_PENDING) || + (gStreamState == STREAM_STATE_FADE_OUT) || + (gStreamState == STREAM_STATE_FADE_IN) || + (gStreamState == STREAM_STATE_STOPPING)) { + state = gStreamState; + } + osSetIntMask(mask); + return state; +} -void func_151F2DFC(s32 arg0, s32 arg1) { - if (arg0 >= 0x80) { - arg0 = (u16)0x7F; +void n_alStreamSetVolumeRamp(s32 volume, s32 rampSamples) { + u32 mask; + + mask = osSetIntMask(1); + if (volume < 0) { + gStreamTargetVolume = 0; + } else if (volume >= STREAM_VOLUME_LIMIT) { + gStreamTargetVolume = STREAM_VOLUME_MAX; } else { - if (arg0 < 0) { - arg0 = (u16)0; + gStreamTargetVolume = volume; + } + gStreamVolumeRampSamples = rampSamples; + osSetIntMask(mask); +} + +void n_alStreamSetPan(s32 pan, s32 immediate) { + if (pan >= STREAM_PAN_LIMIT) { + pan = (u16) STREAM_PAN_MAX; + } else { + if (pan < STREAM_PAN_MIN) { + pan = (u16) STREAM_PAN_MIN; } } - D_800E0E16 = arg0; - if (arg1 != 0) { - D_800E0E14 = (s16) D_800E0E16; + gStreamTargetPan = pan; + if (immediate != 0) { + gStreamCurrentPan = (s16) gStreamTargetPan; } } -void func_151F2E4C(s32 arg0, s32 arg1) { - D_800E0DB2 = arg0; - D_800E0DB0 = arg1; - if (D_800E0DD8 == 0) { - D_800E0DD8 = 2; +void n_alStreamSetLoadInfo(s32 commandCount, s32 sampleRate) { + gStreamLoadCommandCount = commandCount; + gStreamLoadSampleRate = sampleRate; + if (gStreamLoadMode == 0) { + gStreamLoadMode = 2; } } #pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/game_21FC90/func_151F2E88.s") -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/game_21FC90/func_151F39E4.s") +void n_alStreamUpdateEnvelope(N_ALStreamState *state) { + if ((state->volume != state->targetVolume) || (state->pan != state->targetPan)) { + if (state->rampSamplesDone >= state->rampSamplesTotal) { + state->targetLeft = (D_8002BC10[state->pan] * state->volume) >> 15; + state->targetRight = (D_8002BD0E[-state->pan] * state->volume) >> 15; + state->rampSamplesDone = state->rampSamplesTotal; + state->currentLeft = state->targetLeft; + state->currentRight = state->targetRight; + } else { + state->currentLeft = _getVol(state->currentLeft, state->rampSamplesDone, state->leftRate, + state->leftRateFrac); + state->currentRight = _getVol(state->currentRight, state->rampSamplesDone, state->rightRate, + state->rightRateFrac); + } + if (state->currentLeft == 0) { + state->currentLeft = 1; + } + if (state->currentRight == 0) { + state->currentRight = 1; + } + state->volume = state->targetVolume; + if ((state->volume == 0) && (state->requestedRampSamples != 0)) { + n_alStreamForceStop(); + } + if (state->pan != state->targetPan) { + if (D_800428C2 != 0) { + state->pan = (state->targetPan >> 1) + 0x20; + } else if (D_800428C1 != 0) { + state->pan = 0x40; + } else { + state->pan = state->targetPan; + } + } + state->rampSamplesDone = 0; + state->rampSamplesTotal = + ((state->requestedRampSamples + (STREAM_AUDIO_FRAME_SAMPLES - 1)) / STREAM_AUDIO_FRAME_SAMPLES) * + STREAM_AUDIO_FRAME_SAMPLES; + state->needsEnvelopeUpdate = 1; + } +} + +void n_alStreamSetDoneCallback(N_ALStreamDoneCallback callback) { + gStreamDoneCallback = callback; +} -void func_151F3C1C(s32 arg0) { - D_800E0E00 = arg0; +void n_alStreamSetReadCallback(N_ALStreamReadCallback readCallback) { + gStreamReadCallback = readCallback; } -void func_151F3C34(s32 arg0) { - D_800E0DFC = arg0; +s32 n_alStreamRead(void *state, void *dst, s32 len, s32 offset) { + void *src; + ALDMAproc dmaProc; + + if (offset != -1) { + gStreamReadOffset = offset; + } + if (gStreamReadOffset + len > gStreamDataLength) { + len = gStreamDataLength - gStreamReadOffset; + } + + dmaProc = n_alStreamDmaNew()(&src); + src = (void *) dmaProc(gStreamDataStart + gStreamReadOffset, len, 0); + if (src == 0) { + return 0; + } + src = (void *) ((s32) src + STREAM_DMA_CACHED_BASE); + osInvalDCache(src, len); + bcopy(src, dst, len); + gStreamReadOffset += len; + return len; } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/game_21FC90/func_151F3C4C.s") +void n_alStreamPrefetch(void) { + void *dmaState; + ALDMAproc dmaProc; -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/game_21FC90/func_151F3D78.s") + dmaProc = n_alStreamDmaNew()(&dmaState); + dmaProc(gStreamDataStart + gStreamReadOffset, STREAM_PREFETCH_SIZE, 0); +} diff --git a/conker/src/libultra/audio/init_128D0.c b/conker/src/libultra/audio/init_128D0.c index d7acc471..401f6776 100644 --- a/conker/src/libultra/audio/init_128D0.c +++ b/conker/src/libultra/audio/init_128D0.c @@ -7,6 +7,41 @@ #include "functions.h" #include "variables.h" +#define OSCTYPE_TREM 1 +#define OSCTYPE_VIB 128 +#define OSC_RATE_BASE 0x103 +#define OSC_DELAY_SHIFT 14 +#define OSC_TREM_BASE_VOLUME 0x7F +#define OSC_TWO_PI 6.2831854820251465f +#define OSC_STATE_SIZE 0x2C + +typedef struct124 ConkerOscState; +typedef struct121 ConkerBank; +typedef struct11 ConkerWaveBaseList; + +#define BNKF_SAMPLE_BANK_BASE(sampleBankId) (((sampleBankId) & -8) << 5) + +#define oscNext unk0 +#define oscType unk4 +#define oscPeriod unk22 +#define oscPhase unk24 +#define tremoloDepth unk0 +#define tremoloBaseVolume unk1 +#define vibratoDepthCents unk0 + +#define bankInstrumentCount unk0 +#define bankPatched unk2 +#define bankPercussion unk8 +#define bankInstruments unkC + +#define waveListPatched unk3 +#define waveBaseCount unkE +#define waveBases unk10 + +void n_alBnkfPatchBank(ConkerBank *bank, s32 bankFileOffset, s32 sampleTableOffset, s32 sampleBankBase); +void n_alBnkfPatchSingleWaveBaseList(ConkerWaveBaseList *waveList, s32 sampleBankBase); +void n_alBnkfPatchWaveBaseList(ConkerWaveBaseList *waveList, s32 sampleBankBase); + void alSeqFileNew(ALSeqFile *arg0, u8 *base) { s32 offset = base; s32 i; @@ -17,74 +52,74 @@ void alSeqFileNew(ALSeqFile *arg0, u8 *base) { } } -// non-vanila alBnkfNew -void func_10012934(ALBankFile *file, u8 *table, s32 arg2) { - s32 offset = file; - s32 woffset = table; - s32 sp1C = arg2; +// Conker's bank files can point at sample banks outside the loaded bank file. +void n_alBnkfNew(ALBankFile *file, u8 *sampleTable, s32 sampleBankId) { + s32 bankFileOffset = file; + s32 sampleTableOffset = sampleTable; + s32 sampleBankBase = sampleBankId; s32 i; ALFailIf(file->revision != AL_BANK_VERSION, ERR_ALBNKFNEW); for (i = 0; i < file->bankCount; i++) { - file->bankArray[i] = (ALBank *)((u8 *)file->bankArray[i] + offset) ; // (s32)sp24; // ?? + file->bankArray[i] = (ALBank *)((u8 *)file->bankArray[i] + bankFileOffset); if (file->bankArray[i] != 0) { - func_10012A28(file->bankArray[i], offset, woffset, sp1C); + n_alBnkfPatchBank((ConkerBank *) file->bankArray[i], bankFileOffset, sampleTableOffset, sampleBankBase); } } } -void func_10012A28(struct121 *arg0, s32 arg1, s32 arg2, s32 arg3) { +void n_alBnkfPatchBank(ConkerBank *bank, s32 bankFileOffset, s32 sampleTableOffset, s32 sampleBankBase) { s32 i; - s32 tmp; + s32 baseOffset; - if (arg0->unk2 != 0) { + if (bank->bankPatched != 0) { return; } - arg0->unk2 = 1; + bank->bankPatched = 1; - if (arg0->unk8 != 0) { - arg0->unk8 += arg1; - func_10012B84(arg0->unk8, arg3); + if (bank->bankPercussion != 0) { + bank->bankPercussion += bankFileOffset; + n_alBnkfPatchSingleWaveBaseList((ConkerWaveBaseList *) bank->bankPercussion, sampleBankBase); } - for (i = 0; i < arg0->unk0; i ++) { - if (arg0->unkC[i] != 0) { + for (i = 0; i < bank->bankInstrumentCount; i ++) { + if (bank->bankInstruments[i] != 0) { if (i == 0) { - arg0->unkC[i] += arg1; - func_10012BD0(arg0->unkC[i], arg3); + bank->bankInstruments[i] += bankFileOffset; + n_alBnkfPatchWaveBaseList((ConkerWaveBaseList *) bank->bankInstruments[i], sampleBankBase); } else { - tmp = (arg3 & -8) << 5; - arg0->unkC[i] += tmp; + baseOffset = BNKF_SAMPLE_BANK_BASE(sampleBankBase); + bank->bankInstruments[i] += baseOffset; } } } } -void func_10012B84(struct11 *arg0, s32 arg1) { - if (arg0->unk3) { +void n_alBnkfPatchSingleWaveBaseList(ConkerWaveBaseList *waveList, s32 sampleBankBase) { + if (waveList->waveListPatched) { return; } - arg0->unk3 = 1; - arg1 = (0xFFFFFFF8 & arg1) << 5; - arg0->unk10[0] += arg1; + waveList->waveListPatched = 1; + sampleBankBase = BNKF_SAMPLE_BANK_BASE(sampleBankBase); + waveList->waveBases[0] += sampleBankBase; } -void func_10012BD0(struct11 *arg0, s32 arg1) { +void n_alBnkfPatchWaveBaseList(ConkerWaveBaseList *waveList, s32 sampleBankBase) { s32 i; - if (arg0->unk3 != 0) { + if (waveList->waveListPatched != 0) { return; } - arg0->unk3 = 1; + waveList->waveListPatched = 1; - arg1 = (arg1 & -8) << 5; + sampleBankBase = BNKF_SAMPLE_BANK_BASE(sampleBankBase); - for (i = 0; i < arg0->unkE; i++) + for (i = 0; i < waveList->waveBaseCount; i++) { - arg0->unk10[i] += arg1; + waveList->waveBases[i] += sampleBankBase; } } @@ -113,48 +148,48 @@ void func_10012CFC(struct12 *arg0, s32 arg1, s32 arg2) { } } -f32 func_10012D80(u8 arg0) { +f32 n_alOscDepthToCents(u8 depth) { f32 sp4 = 1.0309929847717285f; f32 sp0 = 1.0f; - while (arg0) + while (depth) { - if (arg0 & 1) { + if (depth & 1) { sp0 *= sp4; } sp4 *= sp4; - arg0 = (u32)arg0 >> 1; + depth = (u32)depth >> 1; } return sp0; } -s32 func_10012E04(s32 *arg0, f32 *arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5) { - struct124 *sp2C; +s32 n_alOscInit(s32 *oscState, f32 *initValue, u8 oscType, u8 oscRate, u8 oscDepth, u8 oscDelay) { + ConkerOscState *state; s32 ret; ret = 0; - if (arg5 == 0) { + if (oscDelay == 0) { return 0; } if (D_80042800 != 0) { - sp2C = D_80042800; - D_80042800 = D_80042800->unk0; - sp2C->unk4 = arg2; - *arg0 = sp2C; - ret = arg5 << 0xE; - switch (arg2) { - case 1: - sp2C->unk24 = 0; - sp2C->unk22 = 0x103 - arg3; - sp2C->data.i.unk0 = arg4 >> 1; - sp2C->data.i.unk1 = 0x7F - sp2C->data.i.unk0; - *arg1 = sp2C->data.i.unk1; + state = D_80042800; + D_80042800 = D_80042800->oscNext; + state->oscType = oscType; + *oscState = state; + ret = oscDelay << OSC_DELAY_SHIFT; + switch (oscType) { + case OSCTYPE_TREM: + state->oscPhase = 0; + state->oscPeriod = OSC_RATE_BASE - oscRate; + state->data.i.tremoloDepth = oscDepth >> 1; + state->data.i.tremoloBaseVolume = OSC_TREM_BASE_VOLUME - state->data.i.tremoloDepth; + *initValue = state->data.i.tremoloBaseVolume; break; - case 128: - sp2C->data.f.unk0 = func_10012D80(arg4); - sp2C->unk24 = 0; - sp2C->unk22 = 0x103 - arg3; - *arg1 = 1.0f; + case OSCTYPE_VIB: + state->data.f.vibratoDepthCents = n_alOscDepthToCents(oscDepth); + state->oscPhase = 0; + state->oscPeriod = OSC_RATE_BASE - oscRate; + *initValue = 1.0f; break; default: break; @@ -163,35 +198,35 @@ s32 func_10012E04(s32 *arg0, f32 *arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5) { return ret; } -s32 func_10012F94(struct124 *arg0, f32 *arg1) { +s32 n_alOscUpdate(ConkerOscState *oscState, f32 *updateValue) { f32 sp2C; - struct124 *sp28; + ConkerOscState *state; s32 ret; - sp28 = arg0; - ret = 16000; + state = oscState; + ret = AL_USEC_PER_FRAME; - switch (sp28->unk4) + switch (state->oscType) { - case 1: // guess this means union is u8s - sp28->unk24 = (u16)sp28->unk24 + 1; - if ((u16)sp28->unk24 >= (u16)sp28->unk22) { - sp28->unk24 = 0; + case OSCTYPE_TREM: + state->oscPhase = (u16)state->oscPhase + 1; + if ((u16)state->oscPhase >= (u16)state->oscPeriod) { + state->oscPhase = 0; } - sp2C = (f32)(u16)sp28->unk24 / (f32) (u16)sp28->unk22; - sp2C = sinf(sp2C * 6.2831854820251465f); // 2 * PI - sp2C = sp28->data.i.unk0 * sp2C; - *arg1 = sp28->data.i.unk1 + sp2C; + sp2C = (f32)(u16)state->oscPhase / (f32) (u16)state->oscPeriod; + sp2C = sinf(sp2C * OSC_TWO_PI); + sp2C = state->data.i.tremoloDepth * sp2C; + *updateValue = state->data.i.tremoloBaseVolume + sp2C; break; - case 128: // guess this means float? - sp28->unk24 = (u16)sp28->unk24 + 1; - if ((u16)sp28->unk24 >= (u16)sp28->unk22) { - sp28->unk24 = 0; + case OSCTYPE_VIB: + state->oscPhase = (u16)state->oscPhase + 1; + if ((u16)state->oscPhase >= (u16)state->oscPeriod) { + state->oscPhase = 0; } - sp2C = (f32)(u16) sp28->unk24 / (f32)(u16) sp28->unk22; - sp2C = sinf(sp2C * 6.2831854820251465f) * sp28->data.f.unk0; - *arg1 = alCents2Ratio(sp2C); + sp2C = (f32)(u16) state->oscPhase / (f32)(u16) state->oscPeriod; + sp2C = sinf(sp2C * OSC_TWO_PI) * state->data.f.vibratoDepthCents; + *updateValue = alCents2Ratio(sp2C); break; default: break; @@ -200,26 +235,26 @@ s32 func_10012F94(struct124 *arg0, f32 *arg1) { return ret; } -void func_100131D8(s32 *arg0) { - *arg0 = (s32*)D_80042800; - D_80042800 = arg0; +void n_alOscStop(s32 *oscState) { + *oscState = (s32*)D_80042800; + D_80042800 = oscState; } -void func_100131FC(struct13 *arg0, s32 arg1) { +void n_alOscSetCallbacks(struct13 *arg0, s32 arg1) { s32 *sp24; s32 i; - D_80042804 = alHeapDBAlloc(0, 0, arg0->unkC, arg1, 0x2C); + D_80042804 = alHeapDBAlloc(0, 0, arg0->unkC, arg1, OSC_STATE_SIZE); D_80042800 = (s32) D_80042804; D_80042800 = (s32) D_80042804; // ??? sp24 = D_80042804; for (i = 0; i < (arg1 - 1); i++) { - *sp24 = (i * 0x2C) + D_80042804 + 0x2C; // is this an array? + *sp24 = (i * OSC_STATE_SIZE) + D_80042804 + OSC_STATE_SIZE; // is this an array? sp24 = *sp24; } *sp24 = 0; - arg0->unk10 = func_10012E04; - arg0->unk14 = func_10012F94; - arg0->unk18 = func_100131D8; + arg0->unk10 = n_alOscInit; + arg0->unk14 = n_alOscUpdate; + arg0->unk18 = n_alOscStop; } diff --git a/conker/src/libultra/audio/init_15550.c b/conker/src/libultra/audio/init_15550.c index 4cd9e5ee..9791b766 100644 --- a/conker/src/libultra/audio/init_15550.c +++ b/conker/src/libultra/audio/init_15550.c @@ -1,52 +1,115 @@ #include - -typedef struct { - s32 pad0; - u8 unk4; - s8 unk5; // used -} struct152; - -typedef struct { - s32 pad0; - struct152 *unk4; -} struct153; - -typedef struct { - u8 pad0[0xC]; - struct153 *unkC; - u8 pad10[0x24]; - f32 unk34; // used -} struct154; - -extern N_ALUnknownStruct1 *D_8002BA20; -extern N_ALUnknownStruct1 *D_8002BA24; -extern N_ALUnknownStruct1 *D_8002BA28; -extern N_ALSndPlayer *D_8002BA2C; +extern N_ALSndpSoundState *D_8002BA20; +extern N_ALSndpSoundState *D_8002BA24; +extern N_ALSndpSoundState *D_8002BA28; +extern N_ALSndPlayerExtended *D_8002BA2C; extern s16 D_8002BA30; - -void func_10017298(N_ALUnknownStruct1 *arg0); - -void func_10015550(N_ALCSPlayer *csp, s32 arg1) { +extern u16 *D_800428B8; + +s32 _n_sndpVoiceHandler(N_ALSndPlayer *sndp); +N_ALSndpSoundState *sndp_alloc_state(s32 bank, s16 soundIndex); +void sndp_free_state2(N_ALSndpSoundState *state); +void n_alSndpFlushVoiceEvents(ALEventQueue *evtq, N_ALSndpSoundState *voice, u16 typeMask); + +#define g_SndpAllocStatesHead D_8002BA20 +#define g_SndpAllocStatesTail D_8002BA24 +#define g_SndpFreeStatesHead D_8002BA28 +#define g_SndPlayer D_8002BA2C +#define g_SndpNumPlaying D_8002BA30 +#define g_SndpVolumeTable D_800428B8 + +#define SNDP_PLAY_EVT 0x001 +#define SNDP_PITCH_EVT 0x010 +#define SNDP_API_EVT 0x020 +#define SNDP_END_EVT 0x080 +#define SNDP_STOPALL_EVT 0x400 +#define SNDP_VOLTBL_EVT 0x800 +#define SNDP_PLAY_SOUND_EVT 0x4000 + +#define SNDP_LEAF_FLAG 0x01 +#define SNDP_STATE_READY_MASK 0x03 +#define SNDP_HAS_VOICE_FLAG 0x04 +#define SNDP_RELATIVE_DELAY_FLAG 0x10 +#define SNDP_PARENT_OF_LEAF_FLAG 0x10 +#define SNDP_HAS_DETUNE_PITCH_FLAG 0x20 +#define SNDP_CLEAR_PARENT_FLAG_MASK (~SNDP_PARENT_OF_LEAF_FLAG) +#define SNDP_CHANNEL_MASK 0x1F +#define SNDP_ALL_EVENT_TYPES 0xFFFF +#define SNDP_VOLUME_TABLE_FULL 0x7FFF +#define SNDP_MAX_PRIORITY 0x40 +#define SNDP_INITIAL_RETRY_COUNT 2 +#define SNDP_STATE_READY 5 +#define SNDP_PITCH_UPDATE_DELAY 33333 +#define SNDP_STATE_VOICE(state) ((N_ALVoice *) (state)->voice) + +void n_alCSPSetBank(N_ALCSPlayer *csp, ALBank *bank) { N_ALEvent event; - event.type = 14; - event.msg.midi.ticks = arg1; + event.type = AL_SEQP_BANK_EVT; + event.msg.spbank.bank = bank; n_alEvtqPostEvent(&csp->evtq, &event, 0, 2); } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_15550/func_100155A0.s") +void n_alSndpNew(N_ALSndpConfig *config) { + u32 stateIndex; + void *ptr; + N_ALEvent event; + N_ALSndpSoundState *states; + N_ALSndpSoundState *state; + N_ALSndpSoundState *prevState; + + g_SndPlayer->maxSounds = config->maxSounds; + g_SndPlayer->target = 0; + g_SndPlayer->drvr = n_syn; + g_SndPlayer->frameTime = AL_USEC_PER_FRAME; + + ptr = alHeapDBAlloc(0, 0, config->heap, config->maxStates, sizeof(N_ALSndpSoundState)); + g_SndPlayer->sndState = ptr; + g_SndPlayer->soundTableCount = config->soundTableCount; + + ptr = alHeapDBAlloc(0, 0, config->heap, config->maxEvents, sizeof(N_ALEventListItem)); + n_alEvtqNew(&g_SndPlayer->evtq, ptr, config->maxEvents); + + g_SndpFreeStatesHead = g_SndPlayer->sndState; + + for (stateIndex = 1; stateIndex < (u32) config->maxStates; stateIndex++) { + states = g_SndPlayer->sndState; + state = &states[stateIndex]; + prevState = &states[stateIndex - 1]; + state->node.next = prevState->node.next; + state->node.prev = &prevState->node; + if (prevState->node.next != 0) { + prevState->node.next->prev = &state->node; + } + prevState->node.next = &state->node; + } + + g_SndpVolumeTable = alHeapDBAlloc(0, 0, config->heap, sizeof(u16), config->maxVolumes); + for (stateIndex = 0; stateIndex < config->maxVolumes; stateIndex++) { + g_SndpVolumeTable[stateIndex] = SNDP_VOLUME_TABLE_FULL; + } + + g_SndPlayer->node.next = 0; + g_SndPlayer->node.handler = (ALVoiceHandler) _n_sndpVoiceHandler; + g_SndPlayer->node.clientData = g_SndPlayer; + n_alSynAddPlayer(&g_SndPlayer->node); -s32 func_10015878(N_ALSndPlayer *sp) { + event.type = SNDP_API_EVT; + n_alEvtqPostEvent(&g_SndPlayer->evtq, &event, g_SndPlayer->frameTime, 3); + g_SndPlayer->nextDelta = n_alEvtqNextEvent(&g_SndPlayer->evtq, &g_SndPlayer->nextEvent); +} + +s32 _n_sndpVoiceHandler(N_ALSndPlayer *sp) { N_ALSndPlayer *alsp; N_ALEvent event; alsp = sp; do { switch (alsp->nextEvent.type) { - case 32: - event.type = 32; + case SNDP_API_EVT: + event.type = SNDP_API_EVT; n_alEvtqPostEvent(&alsp->evtq, &event, alsp->frameTime, 3); break; default: @@ -63,305 +126,279 @@ s32 func_10015878(N_ALSndPlayer *sp) { // jump table #pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_15550/_n_handleEvent.s") -void func_10016E90(N_ALUnknownStruct1 *arg0) { - if ((arg0->unk53 & 4) != 0) { - n_alSynStopVoice(&arg0->unk10); - n_alSynFreeVoice(&arg0->unk10); +void sndp_free_state(N_ALSndpSoundState *state) { + if ((state->flags & SNDP_HAS_VOICE_FLAG) != 0) { + n_alSynStopVoice(SNDP_STATE_VOICE(state)); + n_alSynFreeVoice(SNDP_STATE_VOICE(state)); } - func_10017298(arg0); - func_10016F80(&D_8002BA2C->evtq, arg0, 0xFFFF); + sndp_free_state2(state); + n_alSndpFlushVoiceEvents(&g_SndPlayer->evtq, state, SNDP_ALL_EVENT_TYPES); } -void func_10016F00(struct154 *arg0) { +void sndp_apply_detune_pitch(N_ALSndpSoundState *state) { N_ALEvent event; f32 res; - res = alCents2Ratio(arg0->unkC->unk4->unk5) * arg0->unk34; + res = alCents2Ratio(state->sound->keyMap->detune) * state->pitch; - event.type = 16; - /* TODO: check if this is the right struct */ - event.msg.vol.voice = arg0; + event.type = SNDP_PITCH_EVT; + event.msg.vol.voice = (N_ALVoice *) state; event.msg.vol.delta = *(s32*)&res; - n_alEvtqPostEvent(&D_8002BA2C->evtq, &event, 33333, 2); + n_alEvtqPostEvent(&g_SndPlayer->evtq, &event, SNDP_PITCH_UPDATE_DELAY, 2); +} + +void n_alSndpFlushVoiceEvents(ALEventQueue *evtq, N_ALSndpSoundState *voice, u16 typeMask) { + N_ALEventListItem *current; + N_ALEventListItem *next; + N_ALEventListItem *item; + N_ALEventListItem *nextEvent; + N_ALEvent *event; + s32 mask; + ALLink *unlink; + ALLink *freeItem; + ALEventQueue *queue; + + mask = osSetIntMask(1); + current = (N_ALEventListItem *) evtq->allocList.next; + if (current != 0) { + do { + next = (N_ALEventListItem *) current->node.next; + item = current; + nextEvent = next; + event = &item->evt; + if ((event->msg.unknown1.unk0 == (N_ALUnknownStruct1 *) voice) && (((u16) event->type & typeMask) != 0)) { + if (nextEvent != 0) { + nextEvent->delta += item->delta; + } + unlink = (ALLink *) current; + if (unlink->next != 0) { + unlink->next->prev = unlink->prev; + } + if (unlink->prev != 0) { + unlink->prev->next = unlink->next; + } + freeItem = (ALLink *) current; + queue = evtq; + freeItem->next = queue->freeList.next; + freeItem->prev = &queue->freeList; + if (queue->freeList.next != 0) { + queue->freeList.next->prev = freeItem; + } + queue->freeList.next = freeItem; + } + current = next; + } while (current != 0); + } + osSetIntMask(mask); } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_15550/func_10016F80.s") -// void func_10016F80(void *arg0, s32 arg1, u16 arg2) { -// void *sp3C; -// void *sp38; -// void *sp34; -// void *sp30; -// void *sp2C; -// s32 sp28; -// void *sp24; -// void *sp20; -// void *sp1C; -// -// sp28 = osSetIntMask(1); -// sp3C = arg0->unk8; -// if (sp3C != 0) { -// loop_1: -// sp38 = *sp3C; -// sp34 = sp3C; -// sp30 = sp38; -// sp2C = sp34 + 0xC; -// if ((sp2C->unk4 == arg1) && ((sp2C->unk0 & arg2) != 0)) { -// if (sp30 != 0) { -// sp30->unk8 = (s32) (sp30->unk8 + sp34->unk8); -// } -// sp24 = sp3C; -// if (sp24->unk0 != 0) { -// sp24->unk0->unk4 = (s32) sp24->unk4; -// } -// if (sp24->unk4 != 0) { -// *sp24->unk4 = (s32) sp24->unk0; -// } -// sp20 = sp3C; -// sp1C = arg0; -// sp20->unk0 = (s32) *sp1C; -// sp20->unk4 = sp1C; -// if (*sp1C != 0) { -// (*sp1C)->unk4 = sp20; -// } -// *sp1C = sp20; -// } -// sp3C = sp38; -// if (sp3C != 0) { -// goto loop_1; -// } -// } -// osSetIntMask(sp28); -// } - -N_ALUnknownStruct1 *func_10017100(s32 arg0, s16 arg1) { - N_ALUnknownStruct1 *sp24; +N_ALSndpSoundState *sndp_alloc_state(s32 bank, s16 soundIndex) { + N_ALSndpSoundState *state; u32 mask; - N_ALUnknownStruct1 *sp1C; + N_ALSndpSoundState *unlink; mask = osSetIntMask(1); - sp24 = D_8002BA28; - if (sp24 != 0) { - D_8002BA28 = sp24->node.next; - sp1C = sp24; - if (sp1C->node.next) { - sp1C->node.next->prev = sp1C->node.prev; + state = g_SndpFreeStatesHead; + if (state != 0) { + g_SndpFreeStatesHead = (N_ALSndpSoundState *) state->node.next; + unlink = state; + if (unlink->node.next) { + unlink->node.next->prev = unlink->node.prev; } - if (sp1C->node.prev) { - sp1C->node.prev->next = sp1C->node.next; + if (unlink->node.prev) { + unlink->node.prev->next = unlink->node.next; } - if (D_8002BA20) { - sp24->node.next = D_8002BA20; - sp24->node.prev = NULL; - D_8002BA20->node.prev = sp24; - D_8002BA20 = sp24; + if (g_SndpAllocStatesHead) { + state->node.next = &g_SndpAllocStatesHead->node; + state->node.prev = NULL; + g_SndpAllocStatesHead->node.prev = &state->node; + g_SndpAllocStatesHead = state; } else { - sp24->node.prev = 0; - sp24->node.next = sp24->node.prev; - D_8002BA20 = sp24; - D_8002BA24 = sp24; + state->node.prev = 0; + state->node.next = state->node.prev; + g_SndpAllocStatesHead = state; + g_SndpAllocStatesTail = state; } osSetIntMask(mask); - sp24->unkC = 0; - sp24->unk4C = arg1; - sp24->unk3C = arg0; - sp24->unk4E = 64; - sp24->unk54 = 5; - sp24->unk40 = 2; - sp24->unk53 = 0; - sp24->unk38 = 0; - sp24->unk30 = 1.0f; + state->sound = 0; + state->soundNum = soundIndex; + state->bank = (ALBank *) bank; + state->priority = SNDP_MAX_PRIORITY; + state->state = SNDP_STATE_READY; + state->retryCount = SNDP_INITIAL_RETRY_COUNT; + state->flags = 0; + state->handle = 0; + state->basePitch = 1.0f; } else { osSetIntMask(mask); } - return sp24; + return state; } -void func_10017298(N_ALUnknownStruct1 *arg0) { - N_ALUnknownStruct1 *sp4; +void sndp_free_state2(N_ALSndpSoundState *state) { + N_ALSndpSoundState *unlink; - if (D_8002BA20 == arg0) { - D_8002BA20 = arg0->node.next; + if (g_SndpAllocStatesHead == state) { + g_SndpAllocStatesHead = (N_ALSndpSoundState *) state->node.next; } - if (D_8002BA24 == arg0) { - D_8002BA24 = arg0->node.prev; + if (g_SndpAllocStatesTail == state) { + g_SndpAllocStatesTail = (N_ALSndpSoundState *) state->node.prev; } - sp4 = arg0; - if (sp4->node.next) { - sp4->node.next->prev = sp4->node.prev; + unlink = state; + if (unlink->node.next) { + unlink->node.next->prev = unlink->node.prev; } - if (sp4->node.prev) { - sp4->node.prev->next = sp4->node.next; + if (unlink->node.prev) { + unlink->node.prev->next = unlink->node.next; } - if (D_8002BA28) { - arg0->node.next = D_8002BA28; - arg0->node.prev = NULL; - D_8002BA28->node.prev = arg0; - D_8002BA28 = arg0; + if (g_SndpFreeStatesHead) { + state->node.next = &g_SndpFreeStatesHead->node; + state->node.prev = NULL; + g_SndpFreeStatesHead->node.prev = &state->node; + g_SndpFreeStatesHead = state; } else { - arg0->node.prev = NULL; - arg0->node.next = arg0->node.prev; - D_8002BA28 = arg0; + state->node.prev = NULL; + state->node.next = state->node.prev; + g_SndpFreeStatesHead = state; } - if (arg0->unk53 & 4) { - D_8002BA30 -= 1; + if (state->flags & SNDP_HAS_VOICE_FLAG) { + g_SndpNumPlaying -= 1; } - arg0->unk54 = 0; - if (arg0->unk38) { - if (*arg0->unk38 == (s32)arg0) { - *arg0->unk38 = 0; + state->state = AL_STOPPED; + if (state->handle) { + if (*state->handle == state) { + *state->handle = 0; } - arg0->unk38 = NULL; + state->handle = NULL; } } -s32 func_100173C4(N_ALUnknownEvent2 *arg0) { +s32 sndp_get_state(N_ALSndpSoundState **handle) { s32 ret; s32 mask; ret = 0; - if (arg0->unk0) { + if (*handle) { mask = __osDisableInt(); - if (arg0->unk0) { - ret = arg0->unk0->unk54; + if (*handle) { + ret = (*handle)->state; } __osRestoreInt(mask); } return ret; } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_15550/func_10017438.s") -// void *func_10017438(s32 arg0, s16 arg1, u16 arg2, u8 arg3, f32 arg4, u8 arg5, u8 arg6, void *arg7) { -// void *sp34; -// void *sp30; -// s16 sp2E; -// s32 sp28; -// void *sp1C; -// s16 sp18; -// -// sp30 = NULL; -// sp2E = 0; -// if (arg1 != 0) { -// loop_1: -// sp34 = func_10017100(arg0, arg1 - 1); -// if (sp34 != 0) { -// (*(void *)0x8002BA2C)->unk3C = sp34; -// sp18 = 0x4000; -// sp1C = sp34; -// sp34->unk4F = arg3; -// sp34->unk44 = arg2; -// sp34->unk34 = arg4; -// sp34->unk50 = arg5; -// sp34->unk51 = arg6; -// sp28 = 0; -// n_alEvtqPostEvent(D_8002BA2C + 20, &sp18, sp28 + 1, 2); -// sp30 = sp34; -// } -// arg1 = (u16)0; -// if (arg1 != 0) { -// if (sp34 != 0) { -// goto loop_1; -// } -// } -// if ((sp30 == 0) || (sp30->unk53 = (u8) (sp30->unk53 | 1), sp30->unk38 = arg7, (sp2E != 0))) { -// -// } -// } -// if (arg7 != 0) { -// *arg7 = sp30; -// } -// return sp30; -// } - -void func_10017594(N_ALUnknownStruct1 *arg0) { +N_ALSndpSoundState *n_alSndpPlaySound(ALBank *bank, s16 soundNum, u16 vol, ALPan pan, f32 pitch, u8 fxmix, u8 fxbus, + N_ALSndpSoundState **handle) { + N_ALSndpSoundState *state; + N_ALSndpSoundState *leafState; + s16 done; + s32 delay; + N_ALSndpEventPayload event; + + leafState = NULL; + done = 0; + if (soundNum != 0) { + do { + state = sndp_alloc_state((s32) bank, soundNum - 1); + if (state != 0) { + g_SndPlayer->target = (s32) state; + event.type = SNDP_PLAY_SOUND_EVT; + event.state = state; + state->pan = pan; + state->vol = vol; + state->pitch = pitch; + state->fxmix = fxmix; + state->fxbus = fxbus; + delay = 0; + n_alEvtqPostEvent(&g_SndPlayer->evtq, (N_ALEvent *) &event, delay + 1, 2); + leafState = state; + } + soundNum = 0; + } while ((soundNum != 0) && (state != 0)); + if (leafState != 0) { + leafState->flags |= SNDP_LEAF_FLAG; + leafState->handle = handle; + if (done != 0) { + } + } + } + if (handle != 0) { + *handle = leafState; + } + return leafState; +} + +void sndp_post_stopall_event(N_ALSndpSoundState *state) { N_ALEvent event; - if (arg0) { - event.type = 1024; - event.msg.unknown1.unk0 = arg0; - event.msg.unknown1.unk0->unk53 &= -0x11; - n_alEvtqPostEvent(&D_8002BA2C->evtq, &event, 0, 2); + if (state) { + event.type = SNDP_STOPALL_EVT; + event.msg.unknown1.unk0 = (N_ALUnknownStruct1 *) state; + ((N_ALSndpSoundState *) event.msg.unknown1.unk0)->flags &= SNDP_CLEAR_PARENT_FLAG_MASK; + n_alEvtqPostEvent(&g_SndPlayer->evtq, &event, 0, 2); } } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_15550/func_10017604.s") -// NON-MATCHING: stack isnt quite right -// void func_10017604(u8 arg0) { -// s32 mask; -// struct31 *sp20; -// u16 foo; -// s16 sp1C; -// struct31 *sp18; -// -// mask = osSetIntMask(1); -// sp18 = D_8002BA20; -// if (sp18 != 0) { -// do -// { -// sp1C = 1024; -// sp20 = sp18; -// if ((sp18->unk53 & arg0) == arg0) { -// sp20->unk53 = sp20->unk53 & -0x11; -// n_alEvtqPostEvent(D_8002BA2C + 20, &sp1C, 0, 2); -// } -// sp18 = sp18->unk0; -// } -// while (sp18); -// } -// osSetIntMask(mask); -// } - -void func_100176C4(void) { - func_10017604(1); +void sndp_post_stopall_event_bulk(u8 flags) { + s32 mask; + N_ALSndpEventPayload event; + N_ALSndpSoundState *state; + + mask = osSetIntMask(1); + state = g_SndpAllocStatesHead; + if (state != 0) { + do { + event.type = SNDP_STOPALL_EVT; + event.state = state; + if ((state->flags & flags) == flags) { + event.state->flags &= SNDP_CLEAR_PARENT_FLAG_MASK; + n_alEvtqPostEvent(&g_SndPlayer->evtq, (N_ALEvent *) &event, 0, 2); + } + state = (N_ALSndpSoundState *) state->node.next; + } while (state != 0); + } + osSetIntMask(mask); } -void func_100176EC(void) { - func_10017604(3); +void sndp_stop_all(void) { + sndp_post_stopall_event_bulk(SNDP_LEAF_FLAG); } -void func_10017714(s32 arg0, s16 type, s32 arg2) { +void sndp_stop_nodecays(void) { + sndp_post_stopall_event_bulk(SNDP_STATE_READY_MASK); +} + +void sndp_post_event(N_ALSndpSoundState *state, s16 type, s32 data) { N_ALEvent event; - if (arg0 != 0) { + if (state != 0) { event.type = type; - event.msg.vol.voice = arg0; - event.msg.vol.delta = arg2; - n_alEvtqPostEvent(&D_8002BA2C->evtq, &event, 0, 2); + event.msg.vol.voice = (N_ALVoice *) state; + event.msg.vol.delta = data; + n_alEvtqPostEvent(&g_SndPlayer->evtq, &event, 0, 2); } } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_15550/func_10017780.s") -// NON-MATCHING: far from matching -// void func_10017780(u8 arg0, u16 arg1) { -// s32 sp34; -// struct31 *sp30; -// s32 sp2C; -// struct31 *sp20; -// s16 sp1C; -// struct31 *temp_t4; -// struct31 *temp_t4_2; -// -// sp34 = osSetIntMask(1); -// sp30 = D_8002BA20; -// D_800428B8[arg0] = arg1; -// sp2C = 0; -// if (sp30 != 0) { -// do -// { -// temp_t4 = sp30->unkC; -// // if ((temp_t4 != 0) && ((temp_t4->unk4->unk2 & 0x1F) == arg0)) { -// // sp1C = 1024; -// // sp20 = sp30; -// // n_alEvtqPostEvent(D_8002BA2C + 20, &sp1C, 0, 2); -// // } -// sp2C = sp2C + 1; -// temp_t4_2 = sp30->unk0; -// sp30 = temp_t4_2; -// } -// while (temp_t4_2 != 0); -// } -// osSetIntMask(sp34); -// } +void n_alSndpSetChannelValue(u8 channel, u16 value) { + s32 mask; + N_ALSndpSoundState *state; + s32 voiceIndex; + N_ALSndpEventPayload event; + + mask = osSetIntMask(1); + state = g_SndpAllocStatesHead; + g_SndpVolumeTable[channel] = value; + for (voiceIndex = 0; state != 0; voiceIndex++, state = (N_ALSndpSoundState *) state->node.next) { + if ((state->sound != 0) && ((state->sound->keyMap->keyMin & SNDP_CHANNEL_MASK) == channel)) { + event.type = SNDP_VOLTBL_EVT; + event.state = state; + n_alEvtqPostEvent(&g_SndPlayer->evtq, (N_ALEvent *) &event, 0, 2); + } + } + osSetIntMask(mask); +} diff --git a/conker/src/libultra/audio/init_17870.c b/conker/src/libultra/audio/init_17870.c index 595019f0..c6999c06 100644 --- a/conker/src/libultra/audio/init_17870.c +++ b/conker/src/libultra/audio/init_17870.c @@ -3,64 +3,84 @@ #include "functions.h" #include "variables.h" +#define AUDIO_OUTPUT_MODE_MONO 1 +#define AUDIO_OUTPUT_MODE_STEREO 2 +#define AUDIO_OUTPUT_MODE_HEADPHONES 3 +#define AUDIO_OUTPUT_MODE_SURROUND 4 -void func_10017870(u8 arg0) { - s32 i; +#define AUDIO_OUTPUT_ROUTE_STEREO 2 +#define AUDIO_OUTPUT_ROUTE_SURROUND 3 +#define AUDIO_OUTPUT_ROUTE_CENTER 4 +#define AUDIO_OUTPUT_ROUTE_MONO 5 - D_800428C0 = (u8)0; - D_800428C1 = (u8)0; - D_800428C2 = (u8)0; +#define AUDIO_OUTPUT_SLOT_COUNT 2 - switch (arg0) { +#define gAudioOutputSurroundEnabled D_800428C0 +#define gAudioOutputMonoEnabled D_800428C1 +#define gAudioOutputNarrowPanEnabled D_800428C2 +#define gAudioOutputLeftMixFlags D_800428C4 +#define gAudioOutputRightMixFlags D_800428C6 +#define gAudioOutputRoutes D_800428C8 - case 1: - D_800428C1 = (u8)1; +void n_alSndpSetOutputRoute(s32 slot, u32 route); + +void n_alSndpSetOutputMode(u8 outputMode) { + s32 slot; + + gAudioOutputSurroundEnabled = 0; + gAudioOutputMonoEnabled = 0; + gAudioOutputNarrowPanEnabled = 0; + + switch (outputMode) { + + case AUDIO_OUTPUT_MODE_MONO: + gAudioOutputMonoEnabled = 1; break; - case 3: - D_800428C2 = (u8)1; + case AUDIO_OUTPUT_MODE_HEADPHONES: + gAudioOutputNarrowPanEnabled = 1; break; - case 4: - D_800428C0 = (u8)1; + case AUDIO_OUTPUT_MODE_SURROUND: + gAudioOutputSurroundEnabled = 1; break; } - for(i = 0; i < 2; i++) { - func_10017944(i, 0); + for(slot = 0; slot < AUDIO_OUTPUT_SLOT_COUNT; slot++) { + n_alSndpSetOutputRoute(slot, 0); } } -void func_10017944(s32 arg0, u32 arg1) { - if (arg1 == 0) { - arg1 = D_800428C8[arg0]; +void n_alSndpSetOutputRoute(s32 slot, u32 route) { + if (route == 0) { + route = gAudioOutputRoutes[slot]; } - D_800428C4[arg0] = 0; - D_800428C6[arg0] = 0; + gAudioOutputLeftMixFlags[slot] = 0; + gAudioOutputRightMixFlags[slot] = 0; - switch (arg1) + switch (route) { - case 2: - if (D_800428C0 != 0) { - D_800428C6[arg0] = 1; + case AUDIO_OUTPUT_ROUTE_STEREO: + if (gAudioOutputSurroundEnabled != 0) { + gAudioOutputRightMixFlags[slot] = 1; } break; - case 3: - if (D_800428C0 != 0) { - D_800428C4[arg0] = 1; + case AUDIO_OUTPUT_ROUTE_SURROUND: + if (gAudioOutputSurroundEnabled != 0) { + gAudioOutputLeftMixFlags[slot] = 1; } break; - case 4: - if (D_800428C1 == 0) { - D_800428C4[arg0] = 1; + case AUDIO_OUTPUT_ROUTE_CENTER: + if (gAudioOutputMonoEnabled == 0) { + gAudioOutputLeftMixFlags[slot] = 1; } break; - case 5: - if (D_800428C1 == 0) { - D_800428C4[arg0] = 1; - D_800428C6[arg0] = 1; + case AUDIO_OUTPUT_ROUTE_MONO: + if (gAudioOutputMonoEnabled == 0) { + gAudioOutputLeftMixFlags[slot] = 1; + gAudioOutputRightMixFlags[slot] = 1; } break; } - D_800428C8[arg0] = arg1; + gAudioOutputRoutes[slot] = route; } diff --git a/conker/src/libultra/audio/init_19B50.c b/conker/src/libultra/audio/init_19B50.c index c5fbd9ae..1142072f 100644 --- a/conker/src/libultra/audio/init_19B50.c +++ b/conker/src/libultra/audio/init_19B50.c @@ -1,172 +1,266 @@ +#include #include +#include "structs.h" #include "n_sndp.h" +#include "n_seqp.h" +void n_alSynFilter13(N_ALVoice *voice, f32 pitch); +f32 func_1001CEA4(s32 cents); +void n_alCSPStepChlFade(N_ALCSPlayer *seqp, s32 event, s32 chan, s32 arg3); +extern f32 fabsf(f32); +#pragma intrinsic (fabsf) -void func_10019B50(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 vol) { - N_ALSoundState *state; - s16 tmp; +#define CSP_MIN_RELEASE_TIME 0x3E80 +#define CSP_DEFAULT_CHL_FADE_SPEED 0x88 +#define CSP_CHL_FADE_DURATION_MASK 0x7F +#define CSP_CHL_FADE_STEP_EVENT 0xFE + +void n_alCSPHandleChlVolCtrl(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 vol) { + N_ALSoundState *voiceState; + s16 voiceVol; seqp->chanState[chan].vol = vol; - for(state = seqp->vAllocHead; state != NULL; state = state->voice.node.next) { - if ((state->chan == chan) && (state->unk38 != 3)) { - tmp = __n_vsVol(state, seqp); - n_alSynSetVol(&state->voice.node.prev, tmp, __n_vsDelta(state, seqp->curTime)); + for(voiceState = seqp->vAllocHead; voiceState != NULL; voiceState = voiceState->voice.node.next) { + if ((voiceState->chan == chan) && (voiceState->unk38 != 3)) { + voiceVol = __n_vsVol(voiceState, seqp); + n_alSynSetVol(&voiceState->voice.node.prev, voiceVol, __n_vsDelta(voiceState, seqp->curTime)); } } } -void func_10019C28(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 pan) { - N_ALSoundState *state; - u8 tmp; +void n_alCSPHandleChlPanCtrl(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 pan) { + N_ALSoundState *voiceState; + u8 voicePan; seqp->chanState[chan].pan = pan; - for (state = seqp->vAllocHead; state != NULL; state = state->voice.node.next) { - if ((state->chan == chan)) { - tmp = __n_vsPan(state, seqp); - func_1001E2A0(&state->voice.node.prev, tmp); + for (voiceState = seqp->vAllocHead; voiceState != NULL; voiceState = voiceState->voice.node.next) { + if ((voiceState->chan == chan)) { + voicePan = __n_vsPan(voiceState, seqp); + func_1001E2A0(&voiceState->voice.node.prev, voicePan); } } } -void func_10019CD0(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 priority) { +void n_alCSPHandleChlPriorityCtrl(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 priority) { seqp->chanState[chan].priority = priority; } -void func_10019CFC(N_ALCSPlayer *seqp, s32 arg1, s32 arg2, s32 arg3) { +void n_alCSPPostOsMesg(N_ALCSPlayer *seqp, s32 arg1, s32 arg2, s32 msgValue) { if (seqp->unk84 != 0) { - osSendMesg(seqp->unk84, (arg3 & 7) | 0x10 | ((seqp->node.samplesLeft << 5) & -0x100), 0); + osSendMesg(seqp->unk84, (msgValue & 7) | 0x10 | ((seqp->node.samplesLeft << 5) & -0x100), 0); } } -void func_10019D6C(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 arg3) { - seqp->chanState[chan].unk8 = arg3; +void n_alCSPSetChlFxId(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 fxId) { + seqp->chanState[chan].unk8 = fxId; } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_19B50/func_10019D98.s") +void n_alCSPApplyChlFilterPitch(N_ALCSPlayer *seqp, u8 chan) { + N_ALVoiceState *voiceState; + s16 filter12; + s8 pitchOffset; + f32 pitchBend; + + pitchOffset = seqp->chanState[chan].unk15 - 0x40; + pitchBend = seqp->chanState[chan].pitchBend; + + for (voiceState = seqp->vAllocHead; voiceState != NULL; voiceState = voiceState->next) { + if (voiceState->channel == chan) { + filter12 = seqp->chanState[chan].unk14; + n_alSynSetPan(&voiceState->voice, filter12); + if (filter12 != 0) { + n_alSynFilter13(&voiceState->voice, + func_1001CEA4((voiceState->key - voiceState->sound->keyMap->keyBase) + pitchOffset) * + 440.0f * pitchBend); + } + } + } +} -void func_10019ED8(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 arg3) { - seqp->chanState[chan].unk14 = arg3; - func_10019D98(seqp, chan); +void n_alCSPSetChlFilter12(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 filter12) { + seqp->chanState[chan].unk14 = filter12; + n_alCSPApplyChlFilterPitch(seqp, chan); } -void func_10019F38(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 arg3) { - seqp->chanState[chan].unk15 = arg3; - func_10019D98(seqp, chan); +void n_alCSPSetChlFilter13Pitch(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 pitchOffset) { + seqp->chanState[chan].unk15 = pitchOffset; + n_alCSPApplyChlFilterPitch(seqp, chan); } -void func_10019F98(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 arg3) { - N_ALSoundState *state; - seqp->chanState[chan].unk16 = arg3; - for (state = seqp->vAllocHead; state != NULL; state = state->voice.node.next) { - if (state->chan == chan) { - func_1001E350(&state->voice.node.prev, arg3); +void n_alCSPSetChlFilter11(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 filter11) { + N_ALSoundState *voiceState; + seqp->chanState[chan].unk16 = filter11; + for (voiceState = seqp->vAllocHead; voiceState != NULL; voiceState = voiceState->voice.node.next) { + if (voiceState->chan == chan) { + n_alSynFilter11(&voiceState->voice.node.prev, filter11); } } } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_19B50/func_1001A030.s") +void n_alCSPSetChlSustain(N_ALCSPlayer *seqp, s32 arg1, s32 chan, u32 sustain) { + N_ALVoiceState *state; + register s32 releaseTime; -void func_1001A224(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 arg3) { - N_ALSoundState *state; + seqp->chanState[chan].sustain = sustain; + for (state = seqp->vAllocHead; state != NULL; state = state->next) { + if ((state->channel == chan) && (state->phase != AL_PHASE_RELEASE)) { + if (sustain >= (AL_SUSTAIN + 1)) { + if (state->phase == AL_PHASE_NOTEON) { + state->phase = AL_PHASE_SUSTAIN; + } + } else { + if (state->phase == AL_PHASE_SUSTAIN) { + state->phase = AL_PHASE_NOTEON; + } else if (state->phase == AL_PHASE_SUSTREL) { + state->phase = AL_PHASE_RELEASE; + if (((N_ALCSPExtraChanState *) &seqp->chanState[chan])->useCustomReleaseTime) { + if (((N_ALCSPExtraChanState *) &seqp->chanState[chan])->releaseTime < CSP_MIN_RELEASE_TIME) { + releaseTime = CSP_MIN_RELEASE_TIME; + } else { + releaseTime = ((N_ALCSPExtraChanState *) &seqp->chanState[chan])->releaseTime; + } + __n_seqpReleaseVoice((N_ALSeqPlayer *) seqp, &state->voice, releaseTime); + } else { + if (state->sound->envelope->releaseTime < CSP_MIN_RELEASE_TIME) { + releaseTime = CSP_MIN_RELEASE_TIME; + } else { + releaseTime = state->sound->envelope->releaseTime; + } + __n_seqpReleaseVoice((N_ALSeqPlayer *) seqp, &state->voice, releaseTime); + } + } + } + } + } +} - seqp->chanState[chan].fxmix = (seqp->chanState[chan].fxmix & 0x7F) | (arg3 << 7); - for (state = seqp->vAllocHead; state != NULL; state = state->voice.node.next) { - if ((state->chan == chan) && (state->unk38 != 3)) { - n_alSynSetFXMix(&state->voice.node.prev, seqp->chanState[chan].fxmix); +void n_alCSPSetChlFXMix80(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 fxmix80) { + N_ALSoundState *voiceState; + + seqp->chanState[chan].fxmix = (seqp->chanState[chan].fxmix & 0x7F) | (fxmix80 << 7); + for (voiceState = seqp->vAllocHead; voiceState != NULL; voiceState = voiceState->voice.node.next) { + if ((voiceState->chan == chan) && (voiceState->unk38 != 3)) { + n_alSynSetFXMix(&voiceState->voice.node.prev, seqp->chanState[chan].fxmix); } } } -void func_1001A2F8(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 arg3) { - arg3 = arg3 & 0x7F; - seqp->chanState[chan].fxmix = (seqp->chanState[chan].fxmix & 0x80) | arg3; - func_1001A224(seqp, arg1, chan, seqp->chanState[chan].fxmix >> 7); +void n_alCSPSetChlFXMix7F(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 fxmix7F) { + fxmix7F = fxmix7F & 0x7F; + seqp->chanState[chan].fxmix = (seqp->chanState[chan].fxmix & 0x80) | fxmix7F; + n_alCSPSetChlFXMix80(seqp, arg1, chan, seqp->chanState[chan].fxmix >> 7); } -void func_1001A39C(N_ALCSPlayer *seqp, s32 arg1, s32 chan, u32 arg3) { - if (arg3 < n_syn->maxAuxBusses) { - seqp->chanState[chan].unkB = arg3; +void n_alCSPSetChlFXBus(N_ALCSPlayer *seqp, s32 arg1, s32 chan, u32 fxbus) { + if (fxbus < n_syn->maxAuxBusses) { + seqp->chanState[chan].unkB = fxbus; } } -// FIXME: -typedef struct { - u8 pad0[0x36]; - u8 unk36; -} struct24; +void n_alCSPSetStreamFileGroup(struct24 *state, s32 arg1, s32 arg2, s32 group) { + state->streamFileGroup = group; +} -void func_1001A3E0(struct24 *arg0, s32 arg1, s32 arg2, s32 arg3) { - arg0->unk36 = arg3; +void n_alCSPPlayStreamFile(struct24 *state, s32 arg1, s32 arg2, s32 fileIndex) { + func_1001263C(state->streamFileGroup * 100 + fileIndex, 0x7FFF, 0x40); } -void func_1001A3FC(struct24 *arg0, s32 arg1, s32 arg2, s32 arg3) { - func_1001263C(arg0->unk36 * 100 + arg3, 0x7FFF, 0x40); +void n_alCSPApplyChlVol(N_ALCSPlayer *seqp, u8 chan) { + N_ALSoundState *voiceState; + s16 vol; + + for (voiceState = seqp->vAllocHead; voiceState != NULL; voiceState = voiceState->voice.node.next) { + if ((voiceState->chan == chan) && (voiceState->unk38 != 3)) { + vol = __n_vsVol(voiceState, seqp); + n_alSynSetVol(&voiceState->voice.node.prev, vol, __n_vsDelta(voiceState, seqp->curTime)); + } + } } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_19B50/func_1001A45C.s") -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_19B50/func_1001A508.s") +void n_alCSPStartChlFade(N_ALCSPlayer *seqp, N_ALEvent *event, s32 chan, s32 target) { + f32 fadeDelta; + + if (seqp->chanState[chan].unkF == 0) { + seqp->chanState[chan].unkF = CSP_DEFAULT_CHL_FADE_SPEED; + } + if (seqp->chanState[chan].unkE != target) { + fadeDelta = target - seqp->chanState[chan].unkD; + seqp->chanState[chan].unk10 = fadeDelta / (seqp->chanState[chan].unkF & CSP_CHL_FADE_DURATION_MASK); + seqp->chanState[chan].unk10 = fabsf(seqp->chanState[chan].unk10); + if (seqp->chanState[chan].unkE == seqp->chanState[chan].unkD) { + seqp->chanState[chan].unkE = target; + } else { + seqp->chanState[chan].unkE = target; + return; + } + } else { + return; + } + event->msg.midi.byte1 = CSP_CHL_FADE_STEP_EVENT; + n_alCSPStepChlFade(seqp, (s32) event, chan, target); +} -void func_1001A704(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 arg3) { - u8 sp2F; - u8 sp2E; - s32 sp28; - s32 sp24; - f32 sp20; - f32 sp1C; +void n_alCSPStepChlFade(N_ALCSPlayer *seqp, s32 event, s32 chan, s32 arg3) { + u8 currentFadeVol; + u8 targetFadeVol; + s32 fadeDelta; + s32 fadeStep; + f32 fadeStepFloat; + f32 eventDelayScale; - sp2F = seqp->chanState[chan].unkD; - sp2E = seqp->chanState[chan].unkE; - sp20 = seqp->chanState[chan].unk10; - sp28 = sp2E - sp2F; - if (sp28 > 0) { + currentFadeVol = seqp->chanState[chan].unkD; + targetFadeVol = seqp->chanState[chan].unkE; + fadeStepFloat = seqp->chanState[chan].unk10; + fadeDelta = targetFadeVol - currentFadeVol; + if (fadeDelta > 0) { if (seqp->chanState[chan].unkF & 0x80) { - sp20 = sp20 * 2.0f; + fadeStepFloat = fadeStepFloat * 2.0f; } - sp24 = sp20; - if (sp24 == 0) { - sp24 = 1; - sp1C = 1.0f / sp20; + fadeStep = fadeStepFloat; + if (fadeStep == 0) { + fadeStep = 1; + eventDelayScale = 1.0f / fadeStepFloat; } else { - sp1C = sp24 / sp20; + eventDelayScale = fadeStep / fadeStepFloat; } - if (sp28 > sp24) { - sp28 = sp24; + if (fadeDelta > fadeStep) { + fadeDelta = fadeStep; } } else { - sp24 = sp20; - if (sp24 == 0) { - sp24 = 1; - sp1C = sp20; + fadeStep = fadeStepFloat; + if (fadeStep == 0) { + fadeStep = 1; + eventDelayScale = fadeStepFloat; } else { - sp1C = sp24 / sp20; + eventDelayScale = fadeStep / fadeStepFloat; } - sp24 = -sp24; - if (sp28 < sp24) { - sp28 = sp24; + fadeStep = -fadeStep; + if (fadeDelta < fadeStep) { + fadeDelta = fadeStep; } } - sp2F = sp28 + sp2F; - seqp->chanState[chan].unkD = sp2F; - if (sp2F != sp2E) { - n_alEvtqPostEvent(&seqp->evtq, arg1, seqp->uspt * 100 * sp1C, 2); + currentFadeVol = fadeDelta + currentFadeVol; + seqp->chanState[chan].unkD = currentFadeVol; + if (currentFadeVol != targetFadeVol) { + n_alEvtqPostEvent(&seqp->evtq, event, seqp->uspt * 100 * eventDelayScale, 2); } - if (sp2F != 0) { + if (currentFadeVol != 0) { seqp->chanMask |= (1 << chan); } else { seqp->chanMask &= ~(1 << chan); } - func_1001A45C(seqp, chan); + n_alCSPApplyChlVol(seqp, chan); } -void func_1001A9DC(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 arg3) { - seqp->chanState[chan].unkF = arg3; +void n_alCSPSetChlFadeSpeed(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 fadeSpeed) { + seqp->chanState[chan].unkF = fadeSpeed; } -void func_1001AA08(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 arg3) { - seqp->chanState[chan].unkD = arg3; - seqp->chanState[chan].unkE = arg3; - if (arg3 == 0) { +void n_alCSPSetChlFadeEnd(N_ALCSPlayer *seqp, s32 arg1, s32 chan, s32 fadeVol) { + seqp->chanState[chan].unkD = fadeVol; + seqp->chanState[chan].unkE = fadeVol; + if (fadeVol == 0) { seqp->chanMask &= (1 << chan) ^ 0xFFFF; // disable } else { seqp->chanMask |= 1 << chan; } - func_1001A45C(seqp, chan); + n_alCSPApplyChlVol(seqp, chan); } diff --git a/conker/src/libultra/audio/init_1D900.c b/conker/src/libultra/audio/init_1D900.c index a4e5f7fd..06482a1a 100644 --- a/conker/src/libultra/audio/init_1D900.c +++ b/conker/src/libultra/audio/init_1D900.c @@ -33,18 +33,16 @@ s32 func_1001D9B0(s16 arg0) { } } -// this is not right. -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/init_1D900/func_1001DA28.s") -// s32 func_1001DA28(s16 arg0) { -// N_ALMainBus *sp4; -// -// sp4 = n_syn->mainBus; -// if (sp4->filter.handler == func_1001E530) { -// return n_syn->auxBus[arg0].sources; -// } else { -// return 0; -// } -// } +ALFxRef n_alSynGetOutputLPRef(s16 bus) { + N_ALMainBus *sp4; + + sp4 = n_syn->mainBus; + if (sp4->filter.handler == func_1001E530) { + return n_syn->auxBus[bus].fx_array[7]; + } else { + return 0; + } +} void func_1001DAA0(s32 arg0, s16 arg1, s32 arg2) { s32 sp1C = arg0; diff --git a/conker/src/libultra/audio/init_1E350.c b/conker/src/libultra/audio/init_1E350.c index 6bf6b093..6aa42da7 100644 --- a/conker/src/libultra/audio/init_1E350.c +++ b/conker/src/libultra/audio/init_1E350.c @@ -2,8 +2,7 @@ #include #include "n_synthInternals.h" - -void func_1001E350(N_ALVoice *v, u8 fxmix) { +void n_alSynFilter11(N_ALVoice *v, u8 filter) { ALParam *update; if (v->pvoice) { @@ -12,7 +11,7 @@ void func_1001E350(N_ALVoice *v, u8 fxmix) { update->delta = n_syn->paramSamples + v->pvoice->offset; update->type = 17; - update->data.i = fxmix; + update->data.i = filter; update->next = 0; n_alEnvmixerParam(v->pvoice, AL_FILTER_ADD_UPDATE, update); } diff --git a/conker/src/libultra/audio/n_csplayer.c b/conker/src/libultra/audio/n_csplayer.c index a16d4636..9d50efd1 100644 --- a/conker/src/libultra/audio/n_csplayer.c +++ b/conker/src/libultra/audio/n_csplayer.c @@ -175,7 +175,44 @@ void __n_CSPHandleMetaMsg(N_ALCSPlayer *seqp, N_ALEvent *event) } } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_csplayer/__n_CSPRepostEvent.s") +void __n_CSPRepostEvent(ALEventQueue *evtq, N_ALEventListItem *item) +{ + ALLink *node; + N_ALEventListItem *nextItem; + ALLink *element; + ALLink *after; + ALLink *element2; + ALLink *after2; + + for (node = &evtq->allocList; node != 0; node = node->next) { + if (!node->next) { + element = (ALLink *)item; + after = node; + element->next = after->next; + element->prev = after; + if (after->next) { + after->next->prev = element; + } + after->next = element; + break; + } else { + nextItem = (N_ALEventListItem *)node->next; + if (item->delta < nextItem->delta) { + nextItem->delta -= item->delta; + element2 = (ALLink *)item; + after2 = node; + element2->next = after2->next; + element2->prev = after2; + if (after2->next) { + after2->next->prev = element2; + } + after2->next = element2; + break; + } + item->delta -= nextItem->delta; + } + } +} void __n_setUsptFromTempo (N_ALCSPlayer *seqp, f32 tempo) { diff --git a/conker/src/libultra/audio/n_csq.c b/conker/src/libultra/audio/n_csq.c index 39406cd6..a4f40d78 100644 --- a/conker/src/libultra/audio/n_csq.c +++ b/conker/src/libultra/audio/n_csq.c @@ -1,37 +1,215 @@ #include -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_csq/n_alCSeqNew.s") -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_csq/n_alCSeqNextEvent.s") -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_csq/__n_alCSeqGetTrackEvent.s") -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_csq/func_100186DC.s") -// void func_100186DC(void *arg0, void *arg1) { -// s32 sp4; -// s32 temp_t0; -// s32 temp_t4; -// s32 temp_t5; -// s32 temp_t8; -// -// arg0->unk4 = (s32) arg1->unk0; -// arg0->unkC = (s32) arg1->unk4; -// arg0->unk10 = (s32) arg1->unk8; -// sp4 = 0; -// loop_1: -// temp_t0 = sp4 * 4; -// (arg0 + temp_t0)->unk18 = (s32) (arg1 + temp_t0)->unkC; -// temp_t5 = sp4 * 4; -// (arg0 + temp_t5)->unk58 = (s32) (arg1 + temp_t5)->unk4C; -// (arg0 + sp4)->unk98 = (u8) (arg1 + sp4)->unk8C; -// (arg0 + sp4)->unkA8 = (u8) (arg1 + sp4)->unk9C; -// temp_t8 = sp4 * 4; -// (arg0 + temp_t8)->unkB8 = (s32) (arg1 + temp_t8)->unkAC; -// temp_t4 = sp4 + 1; -// sp4 = temp_t4; -// if (temp_t4 < 0x10) { -// goto loop_1; -// } -// } - -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_csq/func_10018790.s") +#define CONKER_AL_TRACK_END 0x13 +#define CONKER_AL_CSP_LOOPSTART 0x14 +#define CONKER_AL_CSP_LOOPEND 0x15 + +u8 __getTrackByte(ALCSeq *seq, s32 track); +u32 __readVarLen(ALCSeq *seq, s32 track); +u32 __n_alCSeqGetTrackEvent(ALCSeq *seq, u32 track, N_ALEvent *event, s32 arg3); + +void n_alCSeqNew(ALCSeq *seq, u8 *ptr) { + u32 i; + u32 tmpOff; + u32 flagTmp; + + seq->base = (ALCMidiHdr *)ptr; + seq->validTracks = 0; + seq->lastDeltaTicks = 0; + seq->lastTicks = 0; + seq->deltaFlag = 1; + + for (i = 0; i < 16; i++) { + seq->lastStatus[i] = 0; + seq->curBUPtr[i] = 0; + seq->curBULen[i] = 0; + tmpOff = seq->base->trackOffset[i]; + + if (tmpOff != 0) { + flagTmp = 1 << i; + seq->validTracks |= flagTmp; + seq->curLoc[i] = ptr + tmpOff; + seq->evtDeltaTicks[i] = __readVarLen(seq, i); + } else { + seq->curLoc[i] = 0; + } + } + + seq->qnpt = 1.0f / (f32)seq->base->division; +} +void n_alCSeqNextEvent(ALCSeq *seq, N_ALEvent *evt, s32 arg2) { + u32 i; + u32 firstTime = -1; + u32 firstTrack = -1; + u32 lastTicks = seq->lastDeltaTicks; + + for (i = 0; i < 16; i++) { + if ((seq->validTracks >> i) & 1) { + if (seq->deltaFlag != 0) { + seq->evtDeltaTicks[i] -= lastTicks; + } + + if (seq->evtDeltaTicks[i] < firstTime) { + firstTime = seq->evtDeltaTicks[i]; + firstTrack = i; + } + } + } + + if (firstTrack != -1) { + __n_alCSeqGetTrackEvent(seq, firstTrack, evt, arg2); + } else { + evt->type = CONKER_AL_TRACK_END; + } + + evt->msg.midi.ticks = firstTime; + seq->lastTicks += firstTime; + seq->lastDeltaTicks = firstTime; + + if (evt->type != CONKER_AL_TRACK_END) { + seq->evtDeltaTicks[firstTrack] += __readVarLen(seq, firstTrack); + } + + seq->deltaFlag = 1; +} +u32 __n_alCSeqGetTrackEvent(ALCSeq *seq, u32 track, N_ALEvent *event, s32 arg3) { + u32 offset; + u8 status; + u8 loopCt; + u8 curLpCt; + u8 *tmpPtr; + + status = __getTrackByte(seq, track); + + if (status == AL_MIDI_Meta) { + u8 type = __getTrackByte(seq, track); + + if (type == AL_MIDI_META_TEMPO) { + event->type = AL_TEMPO_EVT; + event->msg.tempo.status = status; + event->msg.tempo.type = type; + event->msg.tempo.byte1 = __getTrackByte(seq, track); + event->msg.tempo.byte2 = __getTrackByte(seq, track); + event->msg.tempo.byte3 = __getTrackByte(seq, track); + seq->lastStatus[track] = 0; + } else if (type == AL_MIDI_META_EOT) { + u32 flagMask = 1 << track; + + seq->validTracks ^= flagMask; + if (seq->validTracks != 0) { + event->type = CONKER_AL_TRACK_END; + } else { + event->type = AL_SEQ_END_EVT; + } + } else if (type == AL_CMIDI_LOOPSTART_CODE) { + status = __getTrackByte(seq, track); + event->msg.loop.count = status << 8; + status = __getTrackByte(seq, track); + event->msg.loop.count += status; + seq->lastStatus[track] = 0; + event->type = CONKER_AL_CSP_LOOPSTART; + } else if (type == AL_CMIDI_LOOPEND_CODE) { + tmpPtr = seq->curLoc[track]; + loopCt = *tmpPtr++; + curLpCt = *tmpPtr; + if (curLpCt == 0 || arg3 == 0) { + *tmpPtr = loopCt; + seq->curLoc[track] = tmpPtr + 5; + } else { + if (curLpCt != 0xFF) { + *tmpPtr = curLpCt - 1; + } + tmpPtr++; + offset = *tmpPtr++ << 24; + offset += *tmpPtr++ << 16; + offset += *tmpPtr++ << 8; + offset += *tmpPtr++; + seq->curLoc[track] = tmpPtr - offset; + } + seq->lastStatus[track] = 0; + event->type = CONKER_AL_CSP_LOOPEND; + } + } else { + event->type = AL_SEQ_MIDI_EVT; + if (status & 0x80) { + event->msg.midi.status = (status & 0xF0) | track; + event->msg.midi.byte1 = __getTrackByte(seq, track); + seq->lastStatus[track] = event->msg.midi.status; + } else { + event->msg.midi.status = seq->lastStatus[track]; + event->msg.midi.byte1 = status; + } + + if (((event->msg.midi.status & 0xF0) != AL_MIDI_ProgramChange) && + ((event->msg.midi.status & 0xF0) != AL_MIDI_ChannelPressure)) { + event->msg.midi.byte2 = __getTrackByte(seq, track); + if ((event->msg.midi.status & 0xF0) == AL_MIDI_NoteOn) { + event->msg.midi.duration = __readVarLen(seq, track); + } + } else { + event->msg.midi.byte2 = 0; + } + } + + return 1; +} +void alCSeqSetLoc(ALCSeq *seq, ALCSeqMarker *m) { + s32 i; + + seq->validTracks = m->validTracks; + seq->lastTicks = m->lastTicks; + seq->lastDeltaTicks = m->lastDeltaTicks; + + for (i = 0; i < 16; i++) { + seq->curLoc[i] = m->curLoc[i]; + seq->curBUPtr[i] = m->curBUPtr[i]; + seq->curBULen[i] = m->curBULen[i]; + seq->lastStatus[i] = m->lastStatus[i]; + seq->evtDeltaTicks[i] = m->evtDeltaTicks[i]; + } +} + +void n_alCSeqNewLoopStartMarkers(ALCSeq *seq, ALCSeqMarker *m, u32 markerCount, u32 firstLoopIndex) { + N_ALEvent evt; + ALCSeq tempSeq; + s32 i; + s32 j; + ALCSeqMarker m2; + + n_alCSeqNew(&tempSeq, (u8 *)seq->base); + + for (j = 0; j < markerCount; j++) { + m[j].lastTicks = 0; + } + + do { + m2.validTracks = tempSeq.validTracks; + m2.lastTicks = tempSeq.lastTicks; + m2.lastDeltaTicks = tempSeq.lastDeltaTicks; + + for (i = 0; i < 16; i++) { + m2.curLoc[i] = tempSeq.curLoc[i]; + m2.curBUPtr[i] = tempSeq.curBUPtr[i]; + m2.curBULen[i] = tempSeq.curBULen[i]; + m2.lastStatus[i] = tempSeq.lastStatus[i]; + m2.evtDeltaTicks[i] = tempSeq.evtDeltaTicks[i]; + } + + n_alCSeqNextEvent(&tempSeq, &evt, 0); + + if (evt.type == CONKER_AL_CSP_LOOPSTART) { + if (((evt.msg.loop.count >> 8) >= firstLoopIndex) && ((evt.msg.loop.count >> 8) < firstLoopIndex + markerCount)) { + if (m[(evt.msg.loop.count >> 8) - firstLoopIndex].lastTicks == 0) { + m[(evt.msg.loop.count >> 8) - firstLoopIndex] = m2; + + if (--j <= 0) { + return; + } + } + } + } + } while (evt.type != AL_SEQ_END_EVT); +} u8 __getTrackByte(ALCSeq *seq, s32 track) { u8 theByte; diff --git a/conker/src/libultra/audio/n_streamcrc.c b/conker/src/libultra/audio/n_streamcrc.c new file mode 100644 index 00000000..a120f4f5 --- /dev/null +++ b/conker/src/libultra/audio/n_streamcrc.c @@ -0,0 +1,97 @@ +#include "n_libaudio.h" + +/* + * Stream CRC helpers. + * + * These two functions form their own translation unit because the original + * game compiled them at -O1 (instruction scheduling, register-resident locals) + * while the rest of game_21FC90.c is -g/-O0. They are contiguous in the ROM + * (0x151F27E0..0x151F2960); the -O0 stream code resumes at n_alStreamStart. + */ + +/* + * CRC-5 over a 16-bit word, processed MSB-first, using polynomial 0x15 + * (x^5 + x^2 + 1). The running remainder is kept in the low 5 bits of `crc`. + * + * The `(u8) bit` cast forces the `andi $a1, 0xFF` byte read of the + * register-resident bit that -O1 otherwise elides. + */ + +#define CRC5_POLYNOMIAL 0x15 /* x^5 + x^2 + 1 (low 5 bits) */ +#define CRC5_MSB 0x10 /* top bit of the 5-bit remainder */ +#define CRC5_MASK 0x1F /* keeps only the 5-bit result */ +#define WORD_TEST_BIT 0x400 /* input bit consumed each step (bit 10) */ +#define WORD_BITS 16 /* shift/feed iterations */ + +u8 n_alStreamCrc5Word(u16 value) { + u8 crc; + u8 feedback; + s32 i; + register s32 bit; + + crc = 0; + for (i = 0; i < WORD_BITS; i++) { + /* If the top bit is set, it falls out on the shift below, so fold the + * polynomial back in afterwards. */ + if (crc & CRC5_MSB) { + feedback = CRC5_POLYNOMIAL; + } else { + feedback = 0; + } + crc <<= 1; + if (value & WORD_TEST_BIT) { + bit = 1; + } else { + bit = 0; + } + crc |= (u8) bit; + value <<= 1; + crc ^= feedback; + } + return crc & CRC5_MASK; +} + +/* + * CRC-8 over a 32-byte block, processed MSB-first, using polynomial 0x85 + * (x^8 + x^7 + x^2 + 1). After the 32 data bytes, one final iteration shifts in + * eight trailing zero bits to flush the remainder. + */ + +#define CRC8_POLYNOMIAL 0x85 /* x^8 + x^7 + x^2 + 1 */ +#define CRC8_MSB 0x80 /* top bit of the 8-bit remainder */ +#define BLOCK_BYTES 32 /* data bytes; iteration BLOCK_BYTES is the flush */ + +u8 n_alStreamCrc8Block(u8 *data) { + u8 crc; + u8 feedback; + s32 i; + s32 j; + register s32 bit; + + crc = 0; + for (i = 0; i <= BLOCK_BYTES; i++) { + for (j = 7; j >= 0; j--) { + if (crc & CRC8_MSB) { + feedback = CRC8_POLYNOMIAL; + } else { + feedback = 0; + } + crc <<= 1; + if (i == BLOCK_BYTES) { + /* Flush iteration: feed a trailing zero bit. Keep this `| 0`; + * folding it into the branch below changes -O1 scheduling. */ + crc |= 0; + } else { + if (data[0] & (1 << j)) { + bit = 1; + } else { + bit = 0; + } + crc |= bit; + } + crc ^= feedback; + } + data++; + } + return crc; +} diff --git a/conker/src/libultra/audio/n_synsetpitch2.c b/conker/src/libultra/audio/n_synsetpitch2.c index 5f510500..fbd4f1f6 100644 --- a/conker/src/libultra/audio/n_synsetpitch2.c +++ b/conker/src/libultra/audio/n_synsetpitch2.c @@ -2,9 +2,7 @@ #include #include "n_synthInternals.h" - -// set pitch 2 ? -void func_1001CA90( N_ALVoice *v, f32 pitch) { +void n_alSynFilter13(N_ALVoice *v, f32 pitch) { ALParam *update; if (v->pvoice) { diff --git a/conker/src/libultra/audio/n_synthInternals.h b/conker/src/libultra/audio/n_synthInternals.h index 83fb47f9..a6d85000 100644 --- a/conker/src/libultra/audio/n_synthInternals.h +++ b/conker/src/libultra/audio/n_synthInternals.h @@ -55,9 +55,13 @@ typedef struct { typedef struct N_PVoice_s { ALLink node; - struct N_ALVoice_s *vvoice; + /* Reused as a link while moving physical voices between synth lists. */ + union { + struct N_ALVoice_s *vvoice; + ALLink voiceLink; + }; /* RARE CUSTOM */ - u8 pad[0x8]; + u8 pad[0x4]; /** ALLoadFilter *********************************/ ADPCM_STATE *dc_state; ADPCM_STATE *dc_lstate; diff --git a/conker/src/libultra/audio/n_synthesizer.c b/conker/src/libultra/audio/n_synthesizer.c index 9a3f64bc..7e91470e 100644 --- a/conker/src/libultra/audio/n_synthesizer.c +++ b/conker/src/libultra/audio/n_synthesizer.c @@ -1,6 +1,13 @@ #include "n_synthInternals.h" extern f32 D_8002C750; +Acmd *func_1001FB40(s32 sampleOffset, Acmd *p); +s32 __n_nextSampleTime(ALPlayer **client); +s32 _n_timeToSamplesNoRound(s32 micros); + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif #pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_synthesizer/n_alSynNew.s") // void n_alSynNew(struct07 *arg0) { @@ -116,74 +123,48 @@ extern f32 D_8002C750; // D_8002BA44->unk3C = sp34; // } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_synthesizer/n_alAudioFrame.s") -// void *n_alAudioFrame(void *arg0, void *arg1, s32 arg2, u32 arg3) { -// void *sp3C; -// void *sp38; -// s32 sp34; -// s32 sp30; -// void *sp2C; -// void *sp28; -// s32 temp_t5_2; -// void *temp_t0; -// void *temp_t1; -// void *temp_t2; -// void *temp_t5; -// void *temp_t7; -// void *temp_t8; -// void *temp_t9; -// -// sp38 = arg0; -// sp30 = arg2; -// if (*D_8002BA44 == 0) { -// *arg1 = 0; -// return arg0; -// } -// D_8002BA44->unk1C = func_10019A04(&sp3C); -// temp_t2 = D_8002BA44; -// if ((u32) (temp_t2->unk1C - temp_t2->unk20) < arg3) { -// loop_3: -// temp_t7 = D_8002BA44; -// temp_t7->unk1C = (s32) (temp_t7->unk1C & -0x10); -// sp3C->unk10 = (s32) (sp3C->unk10 + _n_timeToSamplesNoRound(sp3C->unk8(sp3C))); -// D_8002BA44->unk1C = func_10019A04(&sp3C); -// temp_t5 = D_8002BA44; -// if ((u32) (temp_t5->unk1C - temp_t5->unk20) < arg3) { -// goto loop_3; -// } -// } -// temp_t9 = D_8002BA44; -// temp_t9->unk1C = (s32) (temp_t9->unk1C & -0x10); -// if ((s32) arg3 > 0) { -// loop_5: -// temp_t5_2 = D_8002BA44->unk58; -// if (temp_t5_2 < (s32) arg3) { -// sp34 = temp_t5_2; -// } else { -// sp34 = (s32) arg3; -// } -// sp38 = func_1001FB40(D_8002BA44->unk20, sp38); -// temp_t0 = sp38; -// sp38 = temp_t0 + 8; -// sp2C = temp_t0; -// *sp2C = 0xD000000; -// temp_t1 = sp38; -// sp38 = temp_t1 + 8; -// sp28 = temp_t1; -// sp28->unk0 = 0x62E0000; -// sp28->unk4 = sp30; -// arg3 = arg3 - sp34; -// sp30 = sp30 + (sp34 * 2 * 2); -// temp_t8 = D_8002BA44; -// temp_t8->unk20 = (s32) (temp_t8->unk20 + sp34); -// if ((s32) arg3 > 0) { -// goto loop_5; -// } -// } -// *arg1 = (s32) ((s32) (sp38 - arg0) >> 3); -// _collectPVoices(); -// return sp38; -// } +Acmd *n_alAudioFrame(Acmd *cmdList, s32 *cmdLen, s16 *outBuf, s32 outLen) { + ALPlayer *client; + Acmd *cmdlEnd = cmdList; + s32 nOut; + s16 *lOutBuf = outBuf; + Acmd *cmdPtr; + Acmd *cmdPtr2; + + if (n_syn->head == 0) { + *cmdLen = 0; + return cmdList; + } + + for (n_syn->paramSamples = __n_nextSampleTime(&client); + (u32)(n_syn->paramSamples - n_syn->curSamples) < (u32)outLen; + n_syn->paramSamples = __n_nextSampleTime(&client)) { + n_syn->paramSamples &= ~0xf; + client->samplesLeft += _n_timeToSamplesNoRound((*client->handler)(client)); + } + + n_syn->paramSamples &= ~0xf; + + while (outLen > 0) { + nOut = MIN(n_syn->maxOutSamples, outLen); + + cmdlEnd = func_1001FB40(n_syn->curSamples, cmdlEnd); + cmdPtr = cmdlEnd++; + cmdPtr->words.w0 = 0x0D000000; + + cmdPtr2 = cmdlEnd++; + cmdPtr2->words.w0 = 0x062E0000; + cmdPtr2->words.w1 = (u32)lOutBuf; + + outLen -= nOut; + lOutBuf += nOut << 1; + n_syn->curSamples += nOut; + } + + *cmdLen = (s32)(cmdlEnd - cmdList); + _n_collectPVoices(); + return cmdlEnd; +} ALParam *__n_allocParam(void) { ALParam *update = 0; @@ -203,8 +184,74 @@ void _n_freeParam(ALParam *param) n_syn->paramList = param; } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_synthesizer/_n_collectPVoices.s") -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_synthesizer/_n_freePVoice.s") +void _n_collectPVoices(void) { + ALLink *dl; + ALLink *element; + ALLink *linkElement; + ALLink *after; + ALLink *voiceLink; + + while ((dl = n_syn->pLameList.next) != 0) { + element = dl; + + if (element->next != 0) { + element->next->prev = element->prev; + } + + if (element->prev != 0) { + element->prev->next = element->next; + } + + linkElement = dl; + after = &n_syn->pFreeList; + linkElement->next = after->next; + linkElement->prev = after; + + if (after->next != 0) { + after->next->prev = linkElement; + } + + after->next = linkElement; + + voiceLink = &((N_PVoice *)dl)->voiceLink; + + if (voiceLink->next != 0) { + voiceLink->next->prev = voiceLink->prev; + } + + if (voiceLink->prev != 0) { + voiceLink->prev->next = voiceLink->next; + } + + ((N_PVoice *)dl)->voiceLink.next = 0; + ((N_PVoice *)dl)->voiceLink.prev = 0; + } +} + +void _n_freePVoice(N_PVoice *pvoice) { + N_PVoice *voice = pvoice; + ALLink *element; + ALLink *after; + + if (((ALLink *)voice)->next != 0) { + ((ALLink *)voice)->next->prev = ((ALLink *)voice)->prev; + } + + if (((ALLink *)voice)->prev != 0) { + ((ALLink *)voice)->prev->next = ((ALLink *)voice)->next; + } + + element = (ALLink *)pvoice; + after = &n_syn->pLameList; + element->next = after->next; + element->prev = after; + + if (after->next != 0) { + after->next->prev = element; + } + + after->next = element; +} s32 _n_timeToSamplesNoRound(s32 micros) { f32 tmp = (((f32) micros * (f32) n_syn->outputRate) / D_8002C750) + 0.5f; // 1000000.0f @@ -216,43 +263,21 @@ s32 _n_timeToSamples( s32 micros) return _n_timeToSamplesNoRound( micros) & ~0xf; } -#pragma GLOBAL_ASM("asm/nonmatchings/libultra/audio/n_synthesizer/__n_nextSampleTime.s") -// static s32 __n_nextSampleTime(ALPlayer **client) -// { -// ALMicroTime temp,delta = 0x7fffffff; /* max delta for s32 */ -// ALPlayer *cl; -// -// /* assert(D_8002BA44->head); */ -// *client = 0; -// -// #if 0 -// for (cl = D_8002BA44->head; cl != 0; cl = cl->next) { -// if ((cl->samplesLeft - D_8002BA44->curSamples) < delta) { -// *client = cl; -// delta = cl->samplesLeft - D_8002BA44->curSamples; -// } -// } -// #endif -// -// if( D_8002BA44->n_sndp ) -// if( (temp = D_8002BA44->n_sndp->samplesLeft - D_8002BA44->curSamples) < delta ) { -// *client = D_8002BA44->n_sndp; -// delta = temp; -// } -// -// if( D_8002BA44->n_seqp1 ) -// if( (temp = D_8002BA44->n_seqp1->samplesLeft - D_8002BA44->curSamples) < delta ) { -// *client = D_8002BA44->n_seqp1; -// delta = temp; -// } -// -// if( D_8002BA44->n_seqp2 ) -// if( (D_8002BA44->n_seqp2->samplesLeft - D_8002BA44->curSamples) < delta ) { -// *client = D_8002BA44->n_seqp2; -// } -// -// return (*client)->samplesLeft; -// } +s32 __n_nextSampleTime(ALPlayer **client) { + u32 delta = 0x7fffffff; + ALPlayer *cl; + + *client = 0; + + for (cl = n_syn->head; cl != 0; cl = cl->next) { + if ((cl->samplesLeft - n_syn->curSamples) < delta) { + *client = cl; + delta = cl->samplesLeft - n_syn->curSamples; + } + } + + return (*client)->samplesLeft; +} // s32 func_10019A04(void *arg0) { // u32 sp4; diff --git a/conker/symbol_addrs.us.txt b/conker/symbol_addrs.us.txt index 31e337f5..808db5de 100644 --- a/conker/symbol_addrs.us.txt +++ b/conker/symbol_addrs.us.txt @@ -16,6 +16,15 @@ osMapTLBRdb = 0x10008120; alHeapInit = 0x10012820; alHeapDBAlloc = 0x10012844; alSeqFileNew = 0x100128D0; +n_alBnkfNew = 0x10012934; +n_alBnkfPatchBank = 0x10012A28; +n_alBnkfPatchSingleWaveBaseList = 0x10012B84; +n_alBnkfPatchWaveBaseList = 0x10012BD0; +n_alOscDepthToCents = 0x10012D80; +n_alOscInit = 0x10012E04; +n_alOscUpdate = 0x10012F94; +n_alOscStop = 0x100131D8; +n_alOscSetCallbacks = 0x100131FC; n_alCSPNew = 0x10013320; __n_CSPVoiceHandler = 0x10013598; __n_CSPHandleNextSeqEvent = 0x10014048; @@ -24,12 +33,31 @@ __n_CSPHandleMetaMsg = 0x10015044; __n_CSPRepostEvent = 0x10015310; __n_setUsptFromTempo = 0x10015464; __n_CSPPostNextSeqEvent = 0x100154AC; +n_alCSPSetBank = 0x10015550; +n_alSndpNew = 0x100155A0; +_n_sndpVoiceHandler = 0x10015878; _n_handleEvent = 0x10015944; +sndp_free_state = 0x10016E90; +sndp_apply_detune_pitch = 0x10016F00; +n_alSndpFlushVoiceEvents = 0x10016F80; +sndp_alloc_state = 0x10017100; +sndp_free_state2 = 0x10017298; +sndp_get_state = 0x100173C4; +n_alSndpPlaySound = 0x10017438; +sndp_post_stopall_event = 0x10017594; +sndp_post_stopall_event_bulk = 0x10017604; +sndp_stop_all = 0x100176C4; +sndp_stop_nodecays = 0x100176EC; +sndp_post_event = 0x10017714; +n_alSndpSetChannelValue = 0x10017780; +n_alSndpSetOutputMode = 0x10017870; +n_alSndpSetOutputRoute = 0x10017944; n_alCSPGetState = 0x10017A80; n_alCSPGetTempo = 0x10017EC0; n_alCSeqNew = 0x10017F80; n_alCSeqNextEvent = 0x10018100; __n_alCSeqGetTrackEvent = 0x100182A8; +alCSeqSetLoc = 0x100186DC; __getTrackByte = 0x100189D0; __readVarLen = 0x10018BC4; n_alInit = 0x10018DA0; @@ -44,6 +72,26 @@ _n_timeToSamplesNoRound = 0x10019964; _n_timeToSamples = 0x100199C8; __n_nextSampleTime = 0x10019A04; alCents2Ratio = 0x10019AB0; +n_alCSPHandleChlVolCtrl = 0x10019B50; +n_alCSPHandleChlPanCtrl = 0x10019C28; +n_alCSPHandleChlPriorityCtrl = 0x10019CD0; +n_alCSPPostOsMesg = 0x10019CFC; +n_alCSPSetChlFxId = 0x10019D6C; +n_alCSPApplyChlFilterPitch = 0x10019D98; +n_alCSPSetChlFilter12 = 0x10019ED8; +n_alCSPSetChlFilter13Pitch = 0x10019F38; +n_alCSPSetChlFilter11 = 0x10019F98; +n_alCSPSetChlSustain = 0x1001A030; +n_alCSPSetChlFXMix80 = 0x1001A224; +n_alCSPSetChlFXMix7F = 0x1001A2F8; +n_alCSPSetChlFXBus = 0x1001A39C; +n_alCSPSetStreamFileGroup = 0x1001A3E0; +n_alCSPPlayStreamFile = 0x1001A3FC; +n_alCSPApplyChlVol = 0x1001A45C; +n_alCSPStartChlFade = 0x1001A508; +n_alCSPStepChlFade = 0x1001A704; +n_alCSPSetChlFadeSpeed = 0x1001A9DC; +n_alCSPSetChlFadeEnd = 0x1001AA08; __n_seqpReleaseVoice = 0x1001ABA0; __n_mapVoice = 0x1001AF28; __n_vsVol = 0x1001B200; @@ -62,15 +110,18 @@ n_alSynStopVoice = 0x1001C770; n_alSynFreeVoice = 0x1001C810; n_alSynSetVol = 0x1001C910; n_alSynSetPitch = 0x1001C9E0; +n_alSynFilter13 = 0x1001CA90; n_alSynSetPan = 0x1001CB40; init_lpfilter = 0x1001CD54; n_alFxNew = 0x1001D124; alN_PVoiceNew = 0x1001D6E8; n_alSynSetFXMix = 0x1001D900; +n_alSynGetOutputLPRef = 0x1001DA28; __alCSeqNextDelta = 0x1001DBA0; n_alSynAllocVoice = 0x1001DC80; _allocatePVoice = 0x1001DF3C; n_alSynStartVoiceParams = 0x1001E170; +n_alSynFilter11 = 0x1001E350; n_alSynDelete = 0x1001E480; n_alSynSetPriority = 0x1001FFE0; n_alEnvmixerParam = 0x10020978; @@ -239,6 +290,21 @@ __osContRamRead2 = 0x151F2080; __osPackRamReadData2 = 0x151F22C4; __osContRamWrite2 = 0x151F2430; __osPackRamWriteData2 = 0x151F2660; +n_alStreamCrc5Word = 0x151F27E0; +n_alStreamCrc8Block = 0x151F2890; +n_alStreamStart = 0x151F2960; +n_alStreamForceStop = 0x151F2BA8; +n_alStreamStop = 0x151F2BE8; +n_alStreamResume = 0x151F2C4C; +n_alStreamGetState = 0x151F2CDC; +n_alStreamSetVolumeRamp = 0x151F2D6C; +n_alStreamSetPan = 0x151F2DFC; +n_alStreamSetLoadInfo = 0x151F2E4C; +n_alStreamUpdateEnvelope = 0x151F39E4; +n_alStreamSetDoneCallback = 0x151F3C1C; +n_alStreamSetReadCallback = 0x151F3C34; +n_alStreamRead = 0x151F3C4C; +n_alStreamPrefetch = 0x151F3D78; __osMaxControllers = 0x80042A51; __osContInitialized = 0x8002BE10;