Decomped DseTrackEvent_SongVolumeFade

Decomped by @Snioflake
This commit is contained in:
AnonymousRandomPerson 2025-08-06 19:51:24 -04:00
parent ad23efbadc
commit 607b7b4ee7
7 changed files with 273 additions and 57 deletions

View File

@ -30,7 +30,6 @@
.public _022B8330
.public _022B9584
.public _s32_div_f
.public _u32_div_f
.public sub_0207C8B8
.public sub_0207C8E0
.public sub_0207CA04

View File

@ -1,50 +1,8 @@
.include "asm/macros.inc"
.include "main_02071C3C.inc"
.include "main_02071CC8.inc"
.text
arm_func_start DseTrackEvent_SongVolumeFade
DseTrackEvent_SongVolumeFade: ; 0x02071C3C
stmdb sp!, {r4, r5, r6, lr}
mov r5, r0
ldrb r2, [r5]
ldrb r0, [r5, #1]
mov r4, r1
add r0, r2, r0, lsl #8
mov r0, r0, lsl #0x10
movs r1, r0, lsr #0x10
moveq r6, #0
beq _02071C84
mov r0, #0x3e8
mul r0, r1, r0
ldr r1, _02071CC4 ; =DRIVER_WORK
ldrsh r1, [r1, #0x28]
bl _u32_div_f
mov r0, r0, lsl #0x10
movs r6, r0, lsr #0x10
moveq r6, #1
_02071C84:
ldrb r0, [r5, #2]
cmp r6, #0
mov r1, r0, lsl #0x10
str r1, [r4, #0x70]
streq r1, [r4, #0x68]
beq _02071CB8
ldr r0, [r4, #0x68]
subs r0, r1, r0
moveq r6, #0
beq _02071CB8
mov r1, r6
bl _s32_div_f
str r0, [r4, #0x6c]
_02071CB8:
strh r6, [r4, #0x74]
add r0, r5, #3
ldmia sp!, {r4, r5, r6, pc}
.align 2, 0
_02071CC4: .word DRIVER_WORK
arm_func_end DseTrackEvent_SongVolumeFade
arm_func_start DseTrackEvent_RestoreEnvelopeDefaults
DseTrackEvent_RestoreEnvelopeDefaults: ; 0x02071CC8
stmdb sp!, {r4, lr}

View File

@ -1,6 +1,9 @@
#ifndef PMDSKY_DSE_H
#define PMDSKY_DSE_H
#include "file.h"
#include "thread.h"
struct dse_fade {
s32 current;
s32 delta;
@ -24,20 +27,20 @@ struct dse_lfo {
u16 lfo_envelope_ticks_left;
s32 envelope_level;
s32 envelope_delta;
u8 *output_ptr;
u8 *waveform_callback;
struct dse_lfo *next;
u8* output_ptr;
u8* waveform_callback;
struct dse_lfo* next;
};
struct dse_lfo_bank {
s16 outputs[6];
struct dse_lfo *lfo_list;
struct dse_lfo* lfo_list;
struct dse_lfo lfos[4];
};
struct dse_sub_loop {
u8 *start;
u8 *end;
u8* start;
u8* end;
u8 count;
u8 octave;
u8 field4_0xa;
@ -87,7 +90,7 @@ struct dse_track {
u8* position;
u8* loop_start;
struct dse_sub_loop loop_stack[4];
struct dse_channel *channel;
struct dse_channel* channel;
u8 field_0x58;
u8 field_0x59;
u8 field_0x5a;
@ -202,7 +205,7 @@ struct dse_channel {
struct dse_note_list* held_notes_list;
struct dse_wavebank* wavebank;
struct dse_instrument* instrument;
struct dse_synth *container;
struct dse_synth* container;
};
struct dse_instrument_split {
@ -254,7 +257,7 @@ struct dse_synth {
u8 clear_volume_and_timer;
u8 field_0xA;
u8 num_voices;
struct dse_synth *next;
struct dse_synth* next;
struct dse_channel channels[16]; /* flexible */
};
@ -268,7 +271,7 @@ struct dse_note_parameters {
struct dse_note_list {
struct dse_note_parameters parameters;
s32 duration;
struct dse_note_list *next;
struct dse_note_list* next;
};
struct dse_sequence_unk_0x0 {
@ -336,4 +339,126 @@ struct dse_sequence {
struct dse_track tracks[16];
};
struct dse_note {
u8 is_note_on;
u8 is_held;
u8 note_number;
s8 volume;
s32 duration;
};
struct dse_note_list_node {
struct dse_note note;
struct dse_note_list_node* next;
};
struct dse_se_bank {
void* file;
s16 field_0x4;
u16 id;
struct dse_se_bank* next;
void* seq_location;
void* mcrl_location;
void* bnkl_location;
u8 field_0x18[4];
};
struct dse_heap_allocator {
void* allocate_fun;
void* free_fun;
void* arg;
};
struct dse_mainbank {
u16 id;
u16 num_wavi;
u32 pcm_data_offset;
void* wavi_data;
u32 field_0xC;
u32 field_0x10;
struct file_stream file;
struct dse_mainbank* next;
};
struct dse_driver_work {
s8 initialized;
u8 stopped;
u16 unknown_0x2;
s32 error_code;
u32 error_data;
u32 error_data2;
s32 error2_code;
u32 error2_data;
u32 error2_data2;
void* error_callback;
void* error2_callback;
u32 field_0x24;
s16 microseconds_per_driver_tick;
u16 field_0x2A;
s32 total_driver_ticks;
s32 driver_tick_rate;
u32 current_rng_seed;
u8 field_0x38;
u8 field_0x39;
u8 last_se_bank_num_sequences;
u8 last_se_bank_tracks_per_sequence;
u8 field_0x3C;
s8 field_0x3D;
u16 field_0x3E;
u8 global_volumes[16];
struct dse_note_list_node notes[128];
struct dse_note_list_node* free_notes_list;
u32 field_0x654;
struct dse_synth* synth_list;
u32 field_0x65C;
struct dse_wavebank* loaded_wavebanks_list;
struct dse_sequence* bgm_sequences_list;
struct dse_sequence* se_sequences_list;
struct dse_se_bank* loaded_effect_banks;
u8 field_0x670[132];
void* heap_node_list;
void* heap_end;
s32 heap_size;
struct dse_heap_allocator heap_allocator;
u8 field_0x70C[36];
s16 num_voices;
u16 active_voices_bits;
u16 start_voices_bits;
u16 deactivate_voices_bits;
u16 deallocate_voices_bits;
u16 field_0x73C;
struct dse_voice voices[16];
u16 field_0x1CFC;
u16 field_0x1CFE;
s32 num_active_voices;
s32 prev_nom_active_voices;
s32 ticks_until_num_active_voices_timeout;
u32 microseconds_per_driver_tick_2;
u32 field_1D10;
u32 field_1D14;
struct thread driver_thread;
void* driver_stack;
u32 field_0x1DDC;
struct dse_mainbank* loaded_mainbanks;
s32 mainbank_max_read_size;
void* mainbank_read_callback;
void* mainbank_read_callback_param;
u8 loader_thread_priority;
u8 field_0x1DF1;
s8 quit_sample_loader;
s8 is_sample_loader_sleeping;
struct thread sample_loader_thread;
void* sample_loader_thread_stack;
struct dse_wavebank* loading_bank;
void* loading_bank_pcm_data;
};
#endif //PMDSKY_DSE_H

View File

@ -5,5 +5,6 @@
u8* DseTrackEvent_Dummy1Byte(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel);
u8* DseTrackEvent_SetInstrument(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel);
u8* DseTrackEvent_SongVolumeFade(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel);
#endif //PMDSKY_MAIN_02071BF4_H

94
include/thread.h Normal file
View File

@ -0,0 +1,94 @@
#ifndef PMDSKY_THREAD_H
#define PMDSKY_THREAD_H
// Specifies a function called when a thread exits
typedef void (*thread_exit_fn_t)(void);
// Contains information about a running thread
struct thread {
s32 flags; // Probably a flags field. Usually 0x1F.
struct thread* field_0x4; // r2 parameter in ThreadStart
u32 field_0x8; // Initialized to 0
u32 field_0xC; // Initialized to 0
u32 field_0x10; // Initialized to 0
u32 field_0x14; // Initialized to 0
u32 field_0x18; // Initialized to 0
u32 field_0x1C; // Initialized to 0
u32 field_0x20; // Initialized to 0
u32 field_0x24; // Initialized to 0
u32 field_0x28; // Initialized to 0
u32 field_0x2C; // Initialized to 0
u32 field_0x30; // Initialized to 0
u32 field_0x34; // Initialized to 0
// 0x38: Points to the area of the allocated stack area that can actually be used to store data.
// This is equal to stack_pointer - 0x44, with an additional - 4 if the resulting addess is not
// aligned to 8 bytes.
void* usable_stack_pointer;
// 0x3C: Address of the function to return to once the thread exits. Usually ThreadExit.
thread_exit_fn_t exit_function;
void* function_address_plus_4; // 0x40: Pointer to the function to run + 4
void* stack_pointer_minus_4; // 0x44: Pointer to the start of the stack area - 4
u8 field_0x48;
u8 field_0x49;
u8 field_0x4A;
u8 field_0x4B;
u8 field_0x4C;
u8 field_0x4D;
u8 field_0x4E;
u8 field_0x4F;
u8 field_0x50;
u8 field_0x51;
u8 field_0x52;
u8 field_0x53;
u8 field_0x54;
u8 field_0x55;
u8 field_0x56;
u8 field_0x57;
u8 field_0x58;
u8 field_0x59;
u8 field_0x5A;
u8 field_0x5B;
u8 field_0x5C;
u8 field_0x5D;
u8 field_0x5E;
u8 field_0x5F;
u8 field_0x60;
u8 field_0x61;
u8 field_0x62;
u8 field_0x63;
u32 field_0x64; // Initialized to 0
// 0x68: Pointer to the next thread. This forms a linked list sorted in ascending order
// according to sorting_order
struct thread* next_thread;
// 0x6C: Seems to be a thread ID that gets incremented for each new thread created.
s32 thread_id;
s32 sorting_order; // 0x70: Unknown. Used to sort threads.
u32 field_0x74; // Initialized to 0
u32 field_0x78; // Initialized to 0
u32 field_0x7C; // Initialized to 0
u32 field_0x80; // Initialized to 0
u32 field_0x84; // Initialized to 0
u32 field_0x88; // Initialized to 0
u32 field_0x8C; // Initialized to 0
void* stack_end_pointer; // 0x90: Pointer to the end of the stack area (exclusive)
void* stack_pointer; // 0x94: Pointer to the start of the stack area (inclusive)
u32 field_0x98; // Initialized to 0
u32 field_0x9C; // Initialized to 0
u32 field_0xA0; // Initialized to 0
// Initialized to 0. Actually part of a separate struct alongside field_0xA8 and field_0xAC.
u32 field_0xA4;
u32 field_0xA8; // Initialized to 0
u32 field_0xAC; // Initialized to 0
u32 field_0xB0; // Initialized to 0
u32 field_0xB4; // Initialized to 0
u8 field_0xB8;
u8 field_0xB9;
u8 field_0xBA;
u8 field_0xBB;
u8 field_0xBC;
u8 field_0xBD;
u8 field_0xBE;
u8 field_0xBF;
};
#endif //PMDSKY_THREAD_H

View File

@ -80,7 +80,7 @@ Static main
Object src/main_02071A98.o
Object asm/main_02071AC0.o
Object src/main_02071BF4.o
Object asm/main_02071C3C.o
Object asm/main_02071CC8.o
Object lib/DSE/src/dc_envelope.o
Object lib/DSE/src/dc_lfo.o
Object lib/DSE/asm/dc_lfo_1.o

View File

@ -1,12 +1,16 @@
#include "main_02071BF4.h"
extern struct dse_driver_work DRIVER_WORK;
extern u32 DseChannel_SetInstrument(struct dse_channel *channel, u16 instrument_index);
extern u32 _u32_div_f(u32 dividend, u32 divisor);
extern u32 _s32_div_f(s32 dividend, s32 divisor);
u8* DseTrackEvent_Dummy1Byte(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel)
{
return ptr_next_byte + 1;
}
extern u32 DseChannel_SetInstrument(struct dse_channel *channel, u16 instrument_index);
u8* DseTrackEvent_SetInstrument(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel)
{
s32 iVar1;
@ -17,3 +21,38 @@ u8* DseTrackEvent_SetInstrument(u8 *ptr_next_byte, struct dse_sequence *sequence
}
return ptr_next_byte + 1;
}
u8* DseTrackEvent_SongVolumeFade(u8 *ptr_next_byte, struct dse_sequence *sequence, struct dse_track *track, struct dse_channel *channel)
{
s32 iVar2;
u32 uVar3;
u16 uVar4;
uVar4 = (u32)*ptr_next_byte + (u32)ptr_next_byte[1] * 0x100 & 0xffff;
if (uVar4 == 0) {
uVar4 = 0;
}
else {
uVar4 = _u32_div_f(uVar4 * 1000,DRIVER_WORK.microseconds_per_driver_tick);
if (uVar4 == 0) {
uVar4 = 1;
}
}
iVar2 = (u32)ptr_next_byte[2] * 0x10000;
(sequence->volume).target = iVar2;
if (uVar4 == 0) {
(sequence->volume).current = iVar2;
}
else {
iVar2 = iVar2 - (sequence->volume).current;
if (iVar2 == 0) {
uVar4 = 0;
}
else {
uVar3 = _s32_div_f(iVar2,uVar4);
(sequence->volume).delta = uVar3;
}
}
(sequence->volume).ticks_remaining = (short)uVar4;
return ptr_next_byte + 3;
}