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 <noreply@anthropic.com>
This commit is contained in:
cecilarmitais
2026-08-16 16:06:07 -07:00
parent 882d2edf64
commit 59fad373cc
13 changed files with 89 additions and 92 deletions

View File

@@ -1 +0,0 @@
#pragma once

View File

@@ -1 +0,0 @@
#pragma once

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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