From 59fad373ccbf213db7422ff81f54e63da7c204aa Mon Sep 17 00:00:00 2001 From: cecilarmitais Date: Sun, 16 Aug 2026 16:06:07 -0700 Subject: [PATCH] Decomp three LFO setup track events; complete struct dse_lfo_settings Decompile from asm: DseTrackEvent_SetupVolumeLfo 0x020724A8 DseTrackEvent_SetupPanLfo 0x020726C4 DseTrackEvent_SetupLfo 0x02072770 Each reads five bytes and initialises one lfo_settings entry: waveform index, a signed 16-bit amplitude, a phase-change time, and zeroes for the envelope fields. The two fixed-slot handlers also set type and output_type, using the same slot-to-output_type mapping as the Use handlers -- 2 for volume, 3 for pan. SetupLfo is the indexed form and takes its slot from channel + 0x61. struct dse_lfo_settings gains field_0xE. All four of these handlers store a zero byte at that offset, which the struct previously described as trailing padding. The struct's size is unchanged: it already rounded to 0x10 for the s32 amplitude's alignment, and the 0x10 stride is confirmed by the shift-by-4 the asm uses to index the array. Adding the field is therefore byte-neutral to every existing user, which the build confirms. All five stream bytes are read into locals before the first store. Reading them inline instead interleaves the loads between stores, and the target issues all five ldrb up front. DseTrackEvent_SetupKeyBendLfo is deliberately not included. It is the same shape and reaches an instruction-for-instruction identical body -- every mnemonic, offset and immediate matches -- differing only in which registers the allocator picks, at score 65. Reordering the locals, introducing an explicit amplitude temporary, and dropping the pointer local were all tried and moved the score without closing it. It is left in asm rather than landed as a near-match. 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 --- lib/DSE/asm/include/main_020724A8.inc | 1 - lib/DSE/asm/include/main_02072770.inc | 1 - lib/DSE/asm/main_020724A8.s | 31 --------------------------- lib/DSE/asm/main_02072668.s | 27 ----------------------- lib/DSE/asm/main_02072770.s | 30 -------------------------- lib/DSE/include/dse.h | 1 + lib/DSE/include/main_020724A8.h | 8 +++++++ lib/DSE/include/main_020726C4.h | 8 +++++++ lib/DSE/include/main_02072770.h | 8 +++++++ lib/DSE/src/main_020724A8.c | 21 ++++++++++++++++++ lib/DSE/src/main_020726C4.c | 21 ++++++++++++++++++ lib/DSE/src/main_02072770.c | 19 ++++++++++++++++ main.lsf | 5 +++-- 13 files changed, 89 insertions(+), 92 deletions(-) delete mode 100644 lib/DSE/asm/include/main_020724A8.inc delete mode 100644 lib/DSE/asm/include/main_02072770.inc delete mode 100644 lib/DSE/asm/main_020724A8.s delete mode 100644 lib/DSE/asm/main_02072770.s create mode 100644 lib/DSE/include/main_020724A8.h create mode 100644 lib/DSE/include/main_020726C4.h create mode 100644 lib/DSE/include/main_02072770.h create mode 100644 lib/DSE/src/main_020724A8.c create mode 100644 lib/DSE/src/main_020726C4.c create mode 100644 lib/DSE/src/main_02072770.c diff --git a/lib/DSE/asm/include/main_020724A8.inc b/lib/DSE/asm/include/main_020724A8.inc deleted file mode 100644 index 6f70f09b..00000000 --- a/lib/DSE/asm/include/main_020724A8.inc +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/lib/DSE/asm/include/main_02072770.inc b/lib/DSE/asm/include/main_02072770.inc deleted file mode 100644 index 6f70f09b..00000000 --- a/lib/DSE/asm/include/main_02072770.inc +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/lib/DSE/asm/main_020724A8.s b/lib/DSE/asm/main_020724A8.s deleted file mode 100644 index 69a1e143..00000000 --- a/lib/DSE/asm/main_020724A8.s +++ /dev/null @@ -1,31 +0,0 @@ - .include "asm/macros.inc" - .include "include/main_020724A8.inc" - - .text - - arm_func_start DseTrackEvent_SetupVolumeLfo -DseTrackEvent_SetupVolumeLfo: ; 0x020724A8 - stmdb sp!, {r3, r4, r5, lr} - ldrb r5, [r0] - ldrb r1, [r0, #1] - ldrb r4, [r0, #2] - ldrb lr, [r0, #3] - ldrb ip, [r0, #4] - mov r2, #1 - add r1, r5, r1, lsl #8 - mov r1, r1, lsl #0x10 - strb r2, [r3, #0x85] - mov r2, #2 - strb r2, [r3, #0x86] - strb ip, [r3, #0x87] - mov r1, r1, asr #0x10 - str r1, [r3, #0x88] - add r1, r4, lr, lsl #8 - strh r1, [r3, #0x8c] - mov r1, #0 - strh r1, [r3, #0x8e] - strh r1, [r3, #0x90] - strb r1, [r3, #0x92] - add r0, r0, #5 - ldmia sp!, {r3, r4, r5, pc} - arm_func_end DseTrackEvent_SetupVolumeLfo diff --git a/lib/DSE/asm/main_02072668.s b/lib/DSE/asm/main_02072668.s index fd513afd..11dbf561 100644 --- a/lib/DSE/asm/main_02072668.s +++ b/lib/DSE/asm/main_02072668.s @@ -30,30 +30,3 @@ _020726B8: add r0, r5, #3 ldmia sp!, {r4, r5, r6, pc} arm_func_end DseTrackEvent_PanFade - - arm_func_start DseTrackEvent_SetupPanLfo -DseTrackEvent_SetupPanLfo: ; 0x020726C4 - stmdb sp!, {r3, r4, r5, lr} - ldrb r5, [r0] - ldrb r1, [r0, #1] - ldrb r4, [r0, #2] - ldrb lr, [r0, #3] - ldrb ip, [r0, #4] - mov r2, #1 - add r1, r5, r1, lsl #8 - mov r1, r1, lsl #0x10 - strb r2, [r3, #0x95] - mov r2, #3 - strb r2, [r3, #0x96] - strb ip, [r3, #0x97] - mov r1, r1, asr #0x10 - str r1, [r3, #0x98] - add r1, r4, lr, lsl #8 - strh r1, [r3, #0x9c] - mov r1, #0 - strh r1, [r3, #0x9e] - strh r1, [r3, #0xa0] - strb r1, [r3, #0xa2] - add r0, r0, #5 - ldmia sp!, {r3, r4, r5, pc} - arm_func_end DseTrackEvent_SetupPanLfo diff --git a/lib/DSE/asm/main_02072770.s b/lib/DSE/asm/main_02072770.s deleted file mode 100644 index 41a0a4e2..00000000 --- a/lib/DSE/asm/main_02072770.s +++ /dev/null @@ -1,30 +0,0 @@ - .include "asm/macros.inc" - .include "include/main_02072770.inc" - - .text - - arm_func_start DseTrackEvent_SetupLfo -DseTrackEvent_SetupLfo: ; 0x02072770 - stmdb sp!, {r4, lr} - ldrb r2, [r0] - ldrb r1, [r0, #1] - ldrb ip, [r3, #0x61] - add r3, r3, #0x74 - add r1, r2, r1, lsl #8 - mov r1, r1, lsl #0x10 - ldrb r4, [r0, #2] - ldrb lr, [r0, #3] - ldrb r2, [r0, #4] - add r3, r3, ip, lsl #4 - mov r1, r1, asr #0x10 - strb r2, [r3, #3] - str r1, [r3, #4] - add r1, r4, lr, lsl #8 - strh r1, [r3, #8] - mov r1, #0 - strh r1, [r3, #0xa] - strh r1, [r3, #0xc] - strb r1, [r3, #0xe] - add r0, r0, #5 - ldmia sp!, {r4, pc} - arm_func_end DseTrackEvent_SetupLfo diff --git a/lib/DSE/include/dse.h b/lib/DSE/include/dse.h index 0ddede90..96f6b11e 100644 --- a/lib/DSE/include/dse.h +++ b/lib/DSE/include/dse.h @@ -150,6 +150,7 @@ struct dse_lfo_settings { u16 lfo_phase_change_msec; u16 msec_until_lfo_started; u16 lfo_envelope_len_msec; + u8 field_0xE; }; struct dse_wavebank { diff --git a/lib/DSE/include/main_020724A8.h b/lib/DSE/include/main_020724A8.h new file mode 100644 index 00000000..63b57ddc --- /dev/null +++ b/lib/DSE/include/main_020724A8.h @@ -0,0 +1,8 @@ +#ifndef PMDSKY_MAIN_020724A8_H +#define PMDSKY_MAIN_020724A8_H + +#include "dse.h" + +u8* DseTrackEvent_SetupVolumeLfo(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel); + +#endif diff --git a/lib/DSE/include/main_020726C4.h b/lib/DSE/include/main_020726C4.h new file mode 100644 index 00000000..2578042c --- /dev/null +++ b/lib/DSE/include/main_020726C4.h @@ -0,0 +1,8 @@ +#ifndef PMDSKY_MAIN_020726C4_H +#define PMDSKY_MAIN_020726C4_H + +#include "dse.h" + +u8* DseTrackEvent_SetupPanLfo(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel); + +#endif diff --git a/lib/DSE/include/main_02072770.h b/lib/DSE/include/main_02072770.h new file mode 100644 index 00000000..a12f43fb --- /dev/null +++ b/lib/DSE/include/main_02072770.h @@ -0,0 +1,8 @@ +#ifndef PMDSKY_MAIN_02072770_H +#define PMDSKY_MAIN_02072770_H + +#include "dse.h" + +u8* DseTrackEvent_SetupLfo(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel); + +#endif diff --git a/lib/DSE/src/main_020724A8.c b/lib/DSE/src/main_020724A8.c new file mode 100644 index 00000000..0dbefe8f --- /dev/null +++ b/lib/DSE/src/main_020724A8.c @@ -0,0 +1,21 @@ +#include "main_020724A8.h" + +u8* DseTrackEvent_SetupVolumeLfo(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel) +{ + u8 b0 = ptr_next_byte[0]; + u8 b1 = ptr_next_byte[1]; + u8 b2 = ptr_next_byte[2]; + u8 b3 = ptr_next_byte[3]; + u8 b4 = ptr_next_byte[4]; + struct dse_lfo_settings *lfo = &channel->lfo_settings[1]; + + lfo->type = 1; + lfo->output_type = 2; + lfo->lfo_waveform_index = b4; + lfo->amplitude = (s16) (b0 + (b1 << 8)); + lfo->lfo_phase_change_msec = b2 + (b3 << 8); + lfo->msec_until_lfo_started = 0; + lfo->lfo_envelope_len_msec = 0; + lfo->field_0xE = 0; + return ptr_next_byte + 5; +} diff --git a/lib/DSE/src/main_020726C4.c b/lib/DSE/src/main_020726C4.c new file mode 100644 index 00000000..a05449dc --- /dev/null +++ b/lib/DSE/src/main_020726C4.c @@ -0,0 +1,21 @@ +#include "main_020726C4.h" + +u8* DseTrackEvent_SetupPanLfo(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel) +{ + u8 b0 = ptr_next_byte[0]; + u8 b1 = ptr_next_byte[1]; + u8 b2 = ptr_next_byte[2]; + u8 b3 = ptr_next_byte[3]; + u8 b4 = ptr_next_byte[4]; + struct dse_lfo_settings *lfo = &channel->lfo_settings[2]; + + lfo->type = 1; + lfo->output_type = 3; + lfo->lfo_waveform_index = b4; + lfo->amplitude = (s16) (b0 + (b1 << 8)); + lfo->lfo_phase_change_msec = b2 + (b3 << 8); + lfo->msec_until_lfo_started = 0; + lfo->lfo_envelope_len_msec = 0; + lfo->field_0xE = 0; + return ptr_next_byte + 5; +} diff --git a/lib/DSE/src/main_02072770.c b/lib/DSE/src/main_02072770.c new file mode 100644 index 00000000..818bc7e5 --- /dev/null +++ b/lib/DSE/src/main_02072770.c @@ -0,0 +1,19 @@ +#include "main_02072770.h" + +u8* DseTrackEvent_SetupLfo(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel) +{ + u8 b0 = ptr_next_byte[0]; + u8 b1 = ptr_next_byte[1]; + u8 b2 = ptr_next_byte[2]; + u8 b3 = ptr_next_byte[3]; + u8 b4 = ptr_next_byte[4]; + struct dse_lfo_settings *lfo = &channel->lfo_settings[channel->field_0x5A[7]]; + + lfo->lfo_waveform_index = b4; + lfo->amplitude = (s16) (b0 + (b1 << 8)); + lfo->lfo_phase_change_msec = b2 + (b3 << 8); + lfo->msec_until_lfo_started = 0; + lfo->lfo_envelope_len_msec = 0; + lfo->field_0xE = 0; + return ptr_next_byte + 5; +} diff --git a/main.lsf b/main.lsf index ed264c22..a23efd5f 100644 --- a/main.lsf +++ b/main.lsf @@ -274,13 +274,14 @@ Static main Object lib/DSE/src/main_02072310.o Object lib/DSE/asm/main_020723C0.o Object lib/DSE/src/main_0207241C.o - Object lib/DSE/asm/main_020724A8.o + Object lib/DSE/src/main_020724A8.o Object lib/DSE/src/main_02072504.o Object lib/DSE/src/main_02072554.o Object lib/DSE/src/main_020725D4.o Object lib/DSE/asm/main_02072668.o + Object lib/DSE/src/main_020726C4.o Object lib/DSE/src/main_02072720.o - Object lib/DSE/asm/main_02072770.o + Object lib/DSE/src/main_02072770.o Object lib/DSE/src/main_020727C8.o Object lib/DSE/asm/main_020727FC.o Object lib/DSE/src/main_02072938.o