mirror of
https://github.com/pret/pokediamond.git
synced 2026-08-26 18:54:02 -05:00
arm7: decompile SND_channel
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
116
arm7/lib/src/SND_channel.c
Normal file
116
arm7/lib/src/SND_channel.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user