summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Panzlaff <michael.panzlaff@fau.de>2021-07-07 02:27:19 +0200
committerMichael Panzlaff <michael.panzlaff@fau.de>2021-08-25 18:03:47 +0200
commit6fda29badc3e915d019ab6f6c1cddc19d18614b2 (patch)
treeafd1c99f0dca88ae0d3ac2f265e729ff7531bfa2
parentc607834736e32183b56150e478f90ee7edc233af (diff)
arm7: decompile SND_channel
-rw-r--r--arm7/asm/SND_channel.s208
-rw-r--r--arm7/lib/include/SND_channel.h4
-rw-r--r--arm7/lib/include/SND_exChannel.h12
-rw-r--r--arm7/lib/include/SND_lfo.h2
-rw-r--r--arm7/lib/src/SND_channel.c116
-rw-r--r--arm7/lib/src/SND_lfo.c2
-rw-r--r--include/nitro/SND_exChannel_shared.h6
7 files changed, 131 insertions, 219 deletions
diff --git a/arm7/asm/SND_channel.s b/arm7/asm/SND_channel.s
deleted file mode 100644
index 44744493..00000000
--- a/arm7/asm/SND_channel.s
+++ /dev/null
@@ -1,208 +0,0 @@
- .include "asm/macros.inc"
- .include "global.inc"
-
- .text
-
- arm_func_start ExChannelLfoUpdate
-ExChannelLfoUpdate: ; 0x037FC530
- stmdb sp!, {r4, r5, r6, lr}
- mov r6, r0
- mov r5, r1
- add r0, r6, #40 ; 0x28
- bl SND_GetLfoValue
- mov r4, r0
- mov ip, r0, asr #31
- mov r3, #0
- cmp ip, r3
- cmpeq r0, r3
- beq _037FC5B0
- ldrb r1, [r6, #40] ; 0x28
- cmp r1, #0
- beq _037FC59C
- cmp r1, #1
- beq _037FC584
- cmp r1, #2
- moveq ip, ip, lsl #6
- orreq ip, ip, r0, lsr #26
- moveq r4, r0, lsl #6
- b _037FC5A8
-_037FC584:
- mov r2, #60 ; 0x3c
- umull r4, r1, r0, r2
- mla r1, r0, r3, r1
- mla r1, ip, r2, r1
- mov ip, r1
- b _037FC5A8
-_037FC59C:
- mov ip, ip, lsl #6
- orr ip, ip, r0, lsr #26
- mov r4, r0, lsl #6
-_037FC5A8:
- mov r4, r4, lsr #14
- orr r4, r4, ip, lsl #18
-_037FC5B0:
- cmp r5, #0
- beq _037FC5C0
- add r0, r6, #40 ; 0x28
- bl SND_UpdateLfo
-_037FC5C0:
- mov r0, r4
- ldmia sp!, {r4, r5, r6, lr}
- bx lr
-
- arm_func_start ExChannelSweepUpdate
-ExChannelSweepUpdate: ; 0x037FC5CC
- stmdb sp!, {r4, r5, lr}
- sub sp, sp, #4
- mov r4, r0
- mov r5, r1
- ldrsh r3, [r4, #50] ; 0x32
- cmp r3, #0
- moveq r0, #0
- beq _037FC630
- ldr r0, [r4, #20]
- ldr r2, [r4, #24]
- cmp r0, r2
- movge r0, #0
- bge _037FC630
- sub r0, r2, r0
- smull r0, r1, r3, r0
- mov r3, r2, asr #31
- bl _ll_sdiv
- cmp r5, #0
- beq _037FC630
- ldrb r1, [r4, #3]
- mov r1, r1, lsl #29
- movs r1, r1, lsr #31
- ldrne r1, [r4, #20]
- addne r1, r1, #1
- strne r1, [r4, #20]
-_037FC630:
- add sp, sp, #4
- ldmia sp!, {r4, r5, lr}
- bx lr
-
- arm_func_start ExChannelVolumeCmp
-ExChannelVolumeCmp: ; 0x037FC63C
- stmfd sp!, {lr}
- sub sp, sp, #4
- ldrh lr, [r0, #36] ; 0x24
- and r2, lr, #255 ; 0xff
- ldrh ip, [r1, #36] ; 0x24
- and r0, ip, #255 ; 0xff
- mov r2, r2, lsl #4
- mov r3, r0, lsl #4
- ldr r1, _037FC698 ; =sSampleDataShiftTable
- ldrb r0, [r1, lr, asr #8]
- mov r2, r2, asr r0
- ldrb r0, [r1, ip, asr #8]
- mov r0, r3, asr r0
- cmp r2, r0
- beq _037FC688
- cmp r2, r0
- movlt r0, #1
- mvnge r0, #0
- b _037FC68C
-_037FC688:
- mov r0, #0
-_037FC68C:
- add sp, sp, #4
- ldmia sp!, {lr}
- bx lr
-_037FC698: .word sSampleDataShiftTable
-
- arm_func_start ExChannelStart
-ExChannelStart: ; 0x037FC69C
- stmdb sp!, {r4, lr}
- mov r4, r0
- ldr r0, _037FC6E4 ; =0xFFFE9680
- str r0, [r4, #16]
- mov r0, #0
- strb r0, [r4, #2]
- str r1, [r4, #52] ; 0x34
- add r0, r4, #40 ; 0x28
- bl SND_StartLfo
- ldrb r0, [r4, #3]
- orr r0, r0, #2
- strb r0, [r4, #3]
- ldrb r0, [r4, #3]
- bic r0, r0, #1
- orr r0, r0, #1
- strb r0, [r4, #3]
- ldmia sp!, {r4, lr}
- bx lr
-_037FC6E4: .word 0xFFFE9680
-
- arm_func_start ExChannelSetup
-ExChannelSetup: ; 0x037FC6E8
- stmdb sp!, {r4, lr}
- mov r4, r0
- mov ip, #0
- str ip, [r4, #80] ; 0x50
- str r1, [r4, #72] ; 0x48
- str r2, [r4, #76] ; 0x4c
- str ip, [r4, #52] ; 0x34
- strb r3, [r4, #34] ; 0x22
- mov r1, #127 ; 0x7f
- strh r1, [r4, #36] ; 0x24
- ldrb r2, [r4, #3]
- bic r2, r2, #2
- strb r2, [r4, #3]
- ldrb r2, [r4, #3]
- orr r2, r2, #4
- strb r2, [r4, #3]
- mov r2, #60 ; 0x3c
- strb r2, [r4, #8]
- strb r2, [r4, #5]
- strb r1, [r4, #9]
- strb ip, [r4, #10]
- strh ip, [r4, #12]
- strh ip, [r4, #6]
- strh ip, [r4, #14]
- strb ip, [r4, #11]
- strb r1, [r4, #4]
- strh ip, [r4, #50] ; 0x32
- str ip, [r4, #24]
- str ip, [r4, #20]
- bl SND_SetExChannelAttack
- mov r0, r4
- mov r1, #127 ; 0x7f
- bl SND_SetExChannelDecay
- mov r0, r4
- mov r1, #127 ; 0x7f
- bl SND_SetExChannelSustain
- mov r0, r4
- mov r1, #127 ; 0x7f
- bl SND_SetExChannelRelease
- add r0, r4, #40 ; 0x28
- bl SND_InitLfoParam
- ldmia sp!, {r4, lr}
- bx lr
-
- arm_func_start CalcDecayCoeff
-CalcDecayCoeff: ; 0x037FC794
- stmfd sp!, {lr}
- sub sp, sp, #4
- mov r1, r0
- cmp r1, #127 ; 0x7f
- ldreq r0, _037FC7F0 ; =0x0000FFFF
- beq _037FC7E4
- cmp r1, #126 ; 0x7e
- moveq r0, #15360 ; 0x3c00
- beq _037FC7E4
- cmp r1, #50 ; 0x32
- movlt r0, r1, lsl #1
- addlt r0, r0, #1
- movlt r0, r0, lsl #16
- movlt r0, r0, lsr #16
- blt _037FC7E4
- mov r0, #7680 ; 0x1e00
- rsb r1, r1, #126 ; 0x7e
- bl _s32_div_f
- mov r0, r0, lsl #16
- mov r0, r0, lsr #16
-_037FC7E4:
- add sp, sp, #4
- ldmia sp!, {lr}
- bx lr
-_037FC7F0: .word 0x0000FFFF
diff --git a/arm7/lib/include/SND_channel.h b/arm7/lib/include/SND_channel.h
index 718e7e2b..ea179968 100644
--- a/arm7/lib/include/SND_channel.h
+++ b/arm7/lib/include/SND_channel.h
@@ -3,6 +3,8 @@
#include "nitro/types.h"
+#include "SND_exChannel.h"
+
void SND_SetupChannelPcm(
s32 chnIdx,
const void *data,
@@ -40,6 +42,6 @@ void SND_SetChannelPan(s32 chnIdx, s32 pan);
void SND_SetChannelTimer(s32 chnIdx, s32 timer);
// TODO move this function to SND_exChannel.c
-u16 CalcDecayCoeff(s32 value);
+u16 CalcDecayCoeff(int value);
#endif //GUARD_SND_CHANNEL_H
diff --git a/arm7/lib/include/SND_exChannel.h b/arm7/lib/include/SND_exChannel.h
index dfd93f21..fcc3a548 100644
--- a/arm7/lib/include/SND_exChannel.h
+++ b/arm7/lib/include/SND_exChannel.h
@@ -6,8 +6,6 @@
#include "nitro/SND_exChannel_shared.h"
#include "nitro/SND_main_shared.h"
-typedef void (*SNDExChannelCallback)(struct SNDExChannel *chn, s32 status, void *userData);
-
void SND_ExChannelInit(void);
void SND_UpdateExChannel(void);
void SND_ExChannelMain(BOOL step);
@@ -26,10 +24,10 @@ void SND_FreeExChannel(struct SNDExChannel *chn);
BOOL SND_IsChannelActive(s32 idx);
// TODO internal functions, move these so exChannel
-s32 ExChannelSweepUpdate(struct SNDExChannel *chn, BOOL step);
-s32 ExChannelLfoUpdate(struct SNDExChannel *chn, BOOL step);
-void ExChannelStart(struct SNDExChannel *chn, s32);
-s32 ExChannelVolumeCmp(struct SNDExChannel *chn_a, struct SNDExChannel *chn_b);
-void ExChannelSetup(struct SNDExChannel *, SNDExChannelCallback callback, void *callbackUserData, s32 priority);
+int ExChannelSweepUpdate(struct SNDExChannel *chn, BOOL step);
+int ExChannelLfoUpdate(struct SNDExChannel *chn, BOOL step);
+void ExChannelStart(struct SNDExChannel *chn, int length);
+int ExChannelVolumeCmp(struct SNDExChannel *chn_a, struct SNDExChannel *chn_b);
+void ExChannelSetup(struct SNDExChannel *, SNDExChannelCallback callback, void *callbackUserData, int priority);
#endif //GUARD_SND_EXCHANNEL_H
diff --git a/arm7/lib/include/SND_lfo.h b/arm7/lib/include/SND_lfo.h
index 05d4647e..43055c27 100644
--- a/arm7/lib/include/SND_lfo.h
+++ b/arm7/lib/include/SND_lfo.h
@@ -8,6 +8,6 @@
void SND_InitLfoParam(struct SNDLfoParam *lfoParam);
void SND_StartLfo(struct SNDLfo *lfo);
void SND_UpdateLfo(struct SNDLfo *lfo);
-s32 SND_LfoGetValue(struct SNDLfo *lfo);
+int SND_GetLfoValue(struct SNDLfo *lfo);
#endif //GUARD_SND_LFO_H
diff --git a/arm7/lib/src/SND_channel.c b/arm7/lib/src/SND_channel.c
new file mode 100644
index 00000000..66acf606
--- /dev/null
+++ b/arm7/lib/src/SND_channel.c
@@ -0,0 +1,116 @@
+#include "SND_channel.h"
+
+#include "SND_lfo.h"
+
+// TODO remove this extern once we actually know where this table is
+extern u8 sSampleDataShiftTable[4];
+
+u16 CalcDecayCoeff(int vol) {
+ if (vol == 127)
+ return 0xFFFF;
+ else if (vol == 126)
+ return 0x3C00;
+ else if (vol < 50)
+ return (u16)(vol * 2 + 1);
+ else
+ return (u16)(0x1E00 / (126 - vol));
+}
+
+void ExChannelSetup(struct SNDExChannel *chn, SNDExChannelCallback callback, void *callbackUserData, int priority) {
+ chn->channelLLNext = NULL;
+ chn->callback = callback;
+ chn->callbackUserData = callbackUserData;
+ chn->length = 0;
+ chn->priority = (u8)priority;
+ chn->volume = 127;
+ chn->flags.start = FALSE;
+ chn->flags.autoSweep = TRUE;
+ chn->midiKey = 60;
+ chn->rootMidiKey = 60;
+ chn->velocity = 127;
+ chn->initPan = 0;
+ chn->userDecay = 0;
+ chn->userDecay2 = 0;
+ chn->userPitch = 0;
+ chn->userPan = 0;
+ chn->panRange = 127;
+ chn->sweepPitch = 0;
+ chn->sweepLength = 0;
+ chn->sweepCounter = 0;
+
+ SND_SetExChannelAttack(chn, 127);
+ SND_SetExChannelDecay(chn, 127);
+ SND_SetExChannelSustain(chn, 127);
+ SND_SetExChannelRelease(chn, 127);
+ SND_InitLfoParam(&chn->lfo.param);
+}
+
+void ExChannelStart(struct SNDExChannel *chn, int length) {
+ chn->envAttenuation = -92544;
+ chn->envStatus = 0;
+ chn->length = length;
+ SND_StartLfo(&chn->lfo);
+ chn->flags.start = TRUE;
+ chn->flags.active = TRUE;
+}
+
+int ExChannelVolumeCmp(struct SNDExChannel *chn_a, struct SNDExChannel *chn_b) {
+ int vol_a = chn_a->volume & 0xFF;
+ int vol_b = chn_b->volume & 0xFF;
+
+ vol_a <<= 4;
+ vol_b <<= 4;
+
+ vol_a >>= sSampleDataShiftTable[chn_a->volume >> 8];
+ vol_b >>= sSampleDataShiftTable[chn_b->volume >> 8];
+
+ if (vol_a != vol_b) {
+ if (vol_a < vol_b)
+ return 1;
+ else
+ return -1;
+ }
+ return 0;
+}
+
+int ExChannelSweepUpdate(struct SNDExChannel *chn, BOOL step) {
+ s64 result;
+
+ if (chn->sweepPitch == 0) {
+ result = 0;
+ } else if (chn->sweepCounter >= chn->sweepLength) {
+ result = 0;
+ } else {
+ result = (s64)chn->sweepPitch * (chn->sweepLength - chn->sweepCounter) / chn->sweepLength;
+
+ if (step && chn->flags.autoSweep)
+ chn->sweepCounter++;
+ }
+
+ return (int)result;
+}
+
+int ExChannelLfoUpdate(struct SNDExChannel *chn, BOOL step) {
+ s64 result = SND_GetLfoValue(&chn->lfo);
+
+ if (result != 0) {
+ switch (chn->lfo.param.target) {
+ case SND_LFO_VOLUME:
+ result *= 60;
+ break;
+ case SND_LFO_PITCH:
+ result <<= 6;
+ break;
+ case SND_LFO_PAN:
+ result <<= 6;
+ break;
+ }
+ result >>= 14;
+ }
+
+ if (step) {
+ SND_UpdateLfo(&chn->lfo);
+ }
+
+ return (int)result;
+}
diff --git a/arm7/lib/src/SND_lfo.c b/arm7/lib/src/SND_lfo.c
index eca98197..262c6d27 100644
--- a/arm7/lib/src/SND_lfo.c
+++ b/arm7/lib/src/SND_lfo.c
@@ -32,7 +32,7 @@ void SND_UpdateLfo(struct SNDLfo *lfo) {
}
}
-s32 SND_GetLfoValue(struct SNDLfo *lfo) {
+int SND_GetLfoValue(struct SNDLfo *lfo) {
if (lfo->param.depth == 0) {
return 0;
} else if (lfo->delayCounter < lfo->param.delay) {
diff --git a/include/nitro/SND_exChannel_shared.h b/include/nitro/SND_exChannel_shared.h
index 386e6ac8..c7743cd6 100644
--- a/include/nitro/SND_exChannel_shared.h
+++ b/include/nitro/SND_exChannel_shared.h
@@ -45,6 +45,10 @@ struct SNDLfo {
u16 counter; // 0x8
}; // size = 0xA
+struct SNDExChannel;
+
+typedef void (*SNDExChannelCallback)(struct SNDExChannel *chn, int status, void *userData);
+
struct SNDExChannel {
u8 id; // 0x00
u8 type; // 0x01
@@ -95,7 +99,7 @@ struct SNDExChannel {
s32 dutyCycle;
}; // 0x44
- void (*callback)(struct SNDExChannel *chn, u32 status, void *userData); // 0x48
+ SNDExChannelCallback callback; // 0x48
void *callbackUserData; // 0x4C
struct SNDExChannel *channelLLNext; // 0x50