mirror of
https://github.com/pret/pmd-sky.git
synced 2026-08-24 11:35:06 -05:00
Decomp the last four DSE track-event handlers in arm9
Decompile from asm: DseTrackEvent_WaitUntilFadeout 0x0207199C DseTrackEvent_EndTrack 0x020719C8 DseTrackEvent_SubLoopBegin 0x02071A1C DseTrackEvent_SubLoopEnd 0x02071A5C This empties asm/main_0207199C.s and asm/main_02071A1C.s, so both files and their .inc are removed rather than split, and the handlers merge into the adjacent sources added by the previous commit. EndTrack confirms the second parameter's type, which the previous commit could only infer from the dispatcher: it writes 1 to the byte at offset 3 of that argument, which is field_0x0.has_looped in struct dse_sequence. A track that reaches the end of its main loop setting has_looped is consistent, and no other struct in dse.h places a byte with that meaning at offset 3. SubLoopBegin and SubLoopEnd index track->loop_stack, the existing struct dse_sub_loop[4] at offset 0x24 with a 12-byte stride, which is what the asm's multiply by 0xc computes. SubLoopEnd needed two changes past the obvious form. Its index and count locals are int, not u8: at byte width the compiler inserts and rX, rX, #0xff after each decrement, which the target does not have. And the early return has to be the fall-through path -- written as an early return the compiler if-converts the tail into predicated stores, where the target branches with bxeq lr. Inverting the condition, so the longer body sits inside the if, produces the branch. DseVoice_CountNumActiveInChannel and DseChannel_DeallocateVoices are still asm; their prototypes are provisional and declared in this file's header. Neither was declared anywhere else in the tree. No comments are added to any pmd-sky file. Authored by Claude (Opus 5) under human direction. Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
.public DseChannel_DeallocateVoices
|
||||
.public DseVoice_CountNumActiveInChannel
|
||||
@@ -1 +0,0 @@
|
||||
#pragma once
|
||||
@@ -1,44 +0,0 @@
|
||||
.include "asm/macros.inc"
|
||||
.include "main_0207199C.inc"
|
||||
|
||||
.text
|
||||
|
||||
arm_func_start DseTrackEvent_WaitUntilFadeout
|
||||
DseTrackEvent_WaitUntilFadeout: ; 0x0207199C
|
||||
stmdb sp!, {r3, r4, r5, lr}
|
||||
mov r5, r0
|
||||
mov r0, r3
|
||||
mov r4, r2
|
||||
bl DseVoice_CountNumActiveInChannel
|
||||
cmp r0, #0
|
||||
ldrgtb r0, [r5], #-1
|
||||
addle r5, r5, #1
|
||||
strgt r0, [r4, #0xc]
|
||||
mov r0, r5
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
arm_func_end DseTrackEvent_WaitUntilFadeout
|
||||
|
||||
arm_func_start DseTrackEvent_EndTrack
|
||||
DseTrackEvent_EndTrack: ; 0x020719C8
|
||||
stmdb sp!, {r4, lr}
|
||||
ldr ip, [r2, #0x20]
|
||||
mov r4, r0
|
||||
cmp ip, #0
|
||||
bne _020719F4
|
||||
mov r1, #0
|
||||
mov r0, r3
|
||||
strb r1, [r2, #2]
|
||||
sub r4, r4, #1
|
||||
bl DseChannel_DeallocateVoices
|
||||
b _02071A0C
|
||||
_020719F4:
|
||||
ldrh r3, [r2, #0xa]
|
||||
mov r0, #1
|
||||
add r3, r3, #1
|
||||
strh r3, [r2, #0xa]
|
||||
strb r0, [r1, #3]
|
||||
ldr r4, [r2, #0x20]
|
||||
_02071A0C:
|
||||
mov r0, r4
|
||||
ldmia sp!, {r4, pc}
|
||||
arm_func_end DseTrackEvent_EndTrack
|
||||
@@ -1,43 +0,0 @@
|
||||
.include "asm/macros.inc"
|
||||
.include "main_02071A1C.inc"
|
||||
|
||||
.text
|
||||
|
||||
arm_func_start DseTrackEvent_SubLoopBegin
|
||||
DseTrackEvent_SubLoopBegin: ; 0x02071A1C
|
||||
stmdb sp!, {r4, lr}
|
||||
ldrb r4, [r2, #6]
|
||||
mov r1, #0xc
|
||||
ldrb lr, [r0], #1
|
||||
smulbb r1, r4, r1
|
||||
add r3, r2, #0x24
|
||||
str r0, [r3, r1]
|
||||
add ip, r3, r1
|
||||
mov r1, #0
|
||||
str r1, [ip, #4]
|
||||
strb lr, [ip, #8]
|
||||
ldrb r3, [r2, #4]
|
||||
add r1, r4, #1
|
||||
strb r3, [ip, #9]
|
||||
strb r1, [r2, #6]
|
||||
ldmia sp!, {r4, pc}
|
||||
arm_func_end DseTrackEvent_SubLoopBegin
|
||||
|
||||
arm_func_start DseTrackEvent_SubLoopEnd
|
||||
DseTrackEvent_SubLoopEnd: ; 0x02071A5C
|
||||
ldrb ip, [r2, #6]
|
||||
add r3, r2, #0x24
|
||||
mov r1, #0xc
|
||||
sub ip, ip, #1
|
||||
mla r3, ip, r1, r3
|
||||
ldrb r1, [r3, #8]
|
||||
subs r1, r1, #1
|
||||
streqb ip, [r2, #6]
|
||||
bxeq lr
|
||||
str r0, [r3, #4]
|
||||
strb r1, [r3, #8]
|
||||
ldrb r0, [r3, #9]
|
||||
strb r0, [r2, #4]
|
||||
ldr r0, [r3]
|
||||
bx lr
|
||||
arm_func_end DseTrackEvent_SubLoopEnd
|
||||
@@ -3,11 +3,16 @@
|
||||
|
||||
#include "dse.h"
|
||||
|
||||
s32 DseVoice_CountNumActiveInChannel(struct dse_channel* channel);
|
||||
void DseChannel_DeallocateVoices(struct dse_channel* channel);
|
||||
|
||||
u8* DseTrackEvent_Invalid(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
u8* DseTrackEvent_WaitSame(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
u8* DseTrackEvent_WaitDelta(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
u8* DseTrackEvent_Wait8(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
u8* DseTrackEvent_Wait16(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
u8* DseTrackEvent_Wait24(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
u8* DseTrackEvent_WaitUntilFadeout(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
u8* DseTrackEvent_EndTrack(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,5 +4,7 @@
|
||||
#include "dse.h"
|
||||
|
||||
u8* DseTrackEvent_MainLoopBegin(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
u8* DseTrackEvent_SubLoopBegin(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
u8* DseTrackEvent_SubLoopEnd(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel);
|
||||
|
||||
#endif
|
||||
|
||||
2
main.lsf
2
main.lsf
@@ -253,9 +253,7 @@ Static main
|
||||
Object src/main_0206C98C.o
|
||||
Object asm/main_0206C9BC.o
|
||||
Object src/main_0207191C.o
|
||||
Object asm/main_0207199C.o
|
||||
Object src/main_02071A14.o
|
||||
Object asm/main_02071A1C.o
|
||||
Object lib/DSE/src/main_02071A98.o
|
||||
Object lib/DSE/asm/main_02071AC0.o
|
||||
Object lib/DSE/src/main_02071BF4.o
|
||||
|
||||
@@ -41,3 +41,28 @@ u8* DseTrackEvent_Wait24(u8* position, struct dse_sequence* seq, struct dse_trac
|
||||
track->wait_ticks_left = track->previous_wait_ticks;
|
||||
return position;
|
||||
}
|
||||
|
||||
u8* DseTrackEvent_WaitUntilFadeout(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel)
|
||||
{
|
||||
if (DseVoice_CountNumActiveInChannel(channel) > 0) {
|
||||
track->wait_ticks_left = *position;
|
||||
position--;
|
||||
} else {
|
||||
position++;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
u8* DseTrackEvent_EndTrack(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel)
|
||||
{
|
||||
if (track->loop_start == NULL) {
|
||||
track->is_playing = FALSE;
|
||||
position--;
|
||||
DseChannel_DeallocateVoices(channel);
|
||||
} else {
|
||||
track->main_loop_count++;
|
||||
seq->field_0x0.has_looped = TRUE;
|
||||
position = track->loop_start;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
@@ -5,3 +5,33 @@ u8* DseTrackEvent_MainLoopBegin(u8* position, struct dse_sequence* seq, struct d
|
||||
track->loop_start = position;
|
||||
return position;
|
||||
}
|
||||
|
||||
u8* DseTrackEvent_SubLoopBegin(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel)
|
||||
{
|
||||
u8 idx = track->loop_stack_index;
|
||||
u8 count = *position++;
|
||||
struct dse_sub_loop* loop = &track->loop_stack[idx];
|
||||
|
||||
loop->start = position;
|
||||
loop->end = NULL;
|
||||
loop->count = count;
|
||||
loop->octave = track->current_octave;
|
||||
track->loop_stack_index = idx + 1;
|
||||
return position;
|
||||
}
|
||||
|
||||
u8* DseTrackEvent_SubLoopEnd(u8* position, struct dse_sequence* seq, struct dse_track* track, struct dse_channel* channel)
|
||||
{
|
||||
int idx = track->loop_stack_index - 1;
|
||||
struct dse_sub_loop* loop = &track->loop_stack[idx];
|
||||
int count = loop->count - 1;
|
||||
|
||||
if (count != 0) {
|
||||
loop->end = position;
|
||||
loop->count = count;
|
||||
track->current_octave = loop->octave;
|
||||
return loop->start;
|
||||
}
|
||||
track->loop_stack_index = idx;
|
||||
return position;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user