From e679690b1273667f942e7e627afdea40eeec1325 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 11:23:54 +0000 Subject: [PATCH 001/251] decomp: improve project_graphics_bounds --- src/assembly/textbin/fun_00237a78.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/assembly/textbin/fun_00237a78.c b/src/assembly/textbin/fun_00237a78.c index fbf2c1040..6a7af96d8 100644 --- a/src/assembly/textbin/fun_00237a78.c +++ b/src/assembly/textbin/fun_00237a78.c @@ -42,14 +42,16 @@ void project_graphics_bounds(f32 *first, f32 *opposite, s32 *width, s32 *height, *(volatile f32 *)&opposite_pointer[1] *= 1.0f / opposite_pointer[3]; scale_y = view_context[101]; scale_x = view_context[100]; - projected_coordinate = first_projected[0] * scale_x; + projected_coordinate = first_projected[0]; + projected_coordinate *= scale_x; first_projected[0] = projected_coordinate; first_projected[1] *= scale_y; opposite_pointer[0] *= scale_x; projected_coordinate = opposite_pointer[1] * scale_y; opposite_pointer[1] = projected_coordinate; projected_coordinate = (f32)screen_extent.half_width; - *x = convert_float_to_integer(first_projected[0] * 0.25f + projected_coordinate); + scale_y = first_projected[0]; + *x = convert_float_to_integer(scale_y * 0.25f + projected_coordinate); *y = convert_float_to_integer(first_projected[1] * 0.25f + (f32)screen_extent.half_height); *(volatile s32 *)width = convert_float_to_integer((opposite_pointer[0] - first_projected[0]) * 0.25f); From a0eeb6211ee2489eb0f85f4235ab9dee4fa417e6 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 11:26:39 +0000 Subject: [PATCH 002/251] decomp: improve sceSifInitCmd --- src/assembly/sdk/rpc/sce_sif_init_cmd.c | 36 +++++++++++-------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/assembly/sdk/rpc/sce_sif_init_cmd.c b/src/assembly/sdk/rpc/sce_sif_init_cmd.c index ddbdb723f..dc38e5fab 100644 --- a/src/assembly/sdk/rpc/sce_sif_init_cmd.c +++ b/src/assembly/sdk/rpc/sce_sif_init_cmd.c @@ -50,7 +50,6 @@ extern void _sceSifCmdIntrHdlr(); /* Initializes the fixed command state once, then submits a warm or cold SIF * handshake. The cold path polls register 4 until bit 0x20000 is set. */ void sceSifInitCmd(void) { - s32 ipval; struct M2c_var_3_42 *var_3_42; struct M2c_var_3_42 *handlers; s32 *var_2_61; @@ -59,8 +58,7 @@ void sceSifInitCmd(void) { s32 poll_value; s32 temp_5_29; s32 temp_6_30; - s32 var_16_46; - s32 var_16_59; + s32 ipval; DIntr(); if (*(s32 *)D_0012FC04 == 0) { @@ -70,40 +68,38 @@ void sceSifInitCmd(void) { return; block_3: *(s32 *)D_0012FC04 = 1; - ipval = 0x20; - temp_6_30 = (s32)D_00154D80 | 0x20000000; temp_5_29 = (s32)D_00154E00 | 0x20000000; + temp_6_30 = (s32)D_00154D80 | 0x20000000; D_00154E58.unk0 = (u8 *)temp_6_30; - D_00154E58.unk4 = (u8 *)temp_5_29; D_00154E58.unk1C = D_00154F80; - handlers = D_00154E80; - var_3_42 = handlers; + D_00154E58.unk4 = (u8 *)temp_5_29; + D_00154E58.unk10 = 0x20; D_00154E58.unk8 = 0; - - var_16_46 = 0x1F; + ipval = 0x1F; D_00154E58.unkC = D_00154E80; D_00154E58.unk14 = 0; D_00154E58.unk18 = 0; - D_00154E58.unk10 = ipval; + var_3_42 = D_00154E80; do { var_3_42->unk0 = 0; - var_16_46 -= 1; + ipval -= 1; var_3_42->unk4 = 0; var_3_42 += 1; - } while (var_16_46 >= 0); - var_16_59 = 0x1F; + } while (ipval >= 0); + ipval = 0x1F; var_2_61 = D_00154F80 + 0x1F; loop_6: *var_2_61 = 0; - var_16_59 -= 1; + ipval -= 1; var_2_61 -= 1; - if (var_16_59 >= 0) { + if (ipval >= 0) { goto loop_6; } - handlers[0].unk0 = FUN_0011a448; - handlers[1].unk0 = FUN_0011a428; - handlers[0].unk4 = &D_00154E58; - handlers[1].unk4 = &D_00154E58; + D_00154E80[0].unk0 = FUN_0011a448; + D_00154E80[1].unk0 = FUN_0011a428; + D_00154E80[0].unk4 = &D_00154E58; + D_00154E80[1].unk4 = &D_00154E58; + ipval = 0x20; EnableInterrupts(); FlushCache(0); { From 2814df8e90b903d9a9dbb10224af04acb27b8f4b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 11:36:48 +0000 Subject: [PATCH 003/251] decomp: improve build_resident_indexed_texture_warp_meshes --- src/assembly/textbin/fun_0022e420.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/assembly/textbin/fun_0022e420.c b/src/assembly/textbin/fun_0022e420.c index 15ee9d9d0..e91836736 100644 --- a/src/assembly/textbin/fun_0022e420.c +++ b/src/assembly/textbin/fun_0022e420.c @@ -88,10 +88,10 @@ void build_resident_indexed_texture_warp_meshes(void) { subtract_vectors(&cross_strip_differences[1], primary_current, secondary_current); subtract_vectors(&cross_strip_differences[2], secondary_next, primary_next); subtract_vectors(&cross_strip_differences[3], primary_next, secondary_next); - subtract_vectors(&edge_normals[1], primary_next + strip_offset, - primary_current + strip_offset); - subtract_vectors(&edge_normals[3], primary_after_next + strip_offset, - primary_next + strip_offset); + subtract_vectors(&edge_normals[1], (Vec4 *)(strip_offset * sizeof(Vec4) + (u32)primary_next), + (Vec4 *)(strip_offset * sizeof(Vec4) + (u32)primary_current)); + subtract_vectors(&edge_normals[3], (Vec4 *)(strip_offset * sizeof(Vec4) + (u32)primary_after_next), + (Vec4 *)(strip_offset * sizeof(Vec4) + (u32)primary_next)); if (page == 0) { qcopy(&edge_normals[3], &edge_normals[1]); } @@ -110,8 +110,8 @@ void build_resident_indexed_texture_warp_meshes(void) { progress * (&D_001604D0)[level_render_state.content_variant]); add_vectors(&quad.positions[vertex], &quad.positions[vertex], - get_primary_history_position((history_index + history_step) & 0x1F) + - strip_offset); + (Vec4 *)(strip_offset * sizeof(Vec4) + + (u32)get_primary_history_position((history_index + history_step) & 0x1F))); } draw_geometry_quad(&quad, 0, 0); for (side_vertex = 0; side_vertex < 4; side_vertex++) { @@ -123,8 +123,8 @@ void build_resident_indexed_texture_warp_meshes(void) { (&D_001604D0)[level_render_state.content_variant]); add_vectors( &quad.positions[side_vertex], &quad.positions[side_vertex], - get_primary_history_position((history_index + side_history_step) & 0x1F) + - strip_offset); + (Vec4 *)(strip_offset * sizeof(Vec4) + + (u32)get_primary_history_position((history_index + side_history_step) & 0x1F))); } draw_geometry_quad(&quad, 0, 0); } From 7f51de26cc768679524ba8504e54ce0dac18c124 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 11:47:08 +0000 Subject: [PATCH 004/251] decomp: improve cmd_sem_init --- config/us/rnc1.us.yaml | 2 +- src/{assembly => }/sdk/library/cmd_sem_init.c | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) rename src/{assembly => }/sdk/library/cmd_sem_init.c (63%) diff --git a/config/us/rnc1.us.yaml b/config/us/rnc1.us.yaml index 514c9751d..75b6168d7 100644 --- a/config/us/rnc1.us.yaml +++ b/config/us/rnc1.us.yaml @@ -456,7 +456,7 @@ segments: - [0x21658, c, storage/cd/handle_cd_read_callback] - [0x216f8, textbin, text_gap_00120778_after_fun_001206d8_prefix_00120778] - [0x21708, c, sdk/callbacks/process_native_cd_read_completion] - - [0x217a8, c, assembly/sdk/library/cmd_sem_init] + - [0x217a8, c, sdk/library/cmd_sem_init] - [0x2183c, textbin, text_gap_00120828_post_sdk_worker] - [0x21840, c, sdk/library/cdvd_exit] - [0x218d4, textbin, text_gap_001208c0_post_sdk_worker_prefix_00120954] diff --git a/src/assembly/sdk/library/cmd_sem_init.c b/src/sdk/library/cmd_sem_init.c similarity index 63% rename from src/assembly/sdk/library/cmd_sem_init.c rename to src/sdk/library/cmd_sem_init.c index 9d75100c7..026f936b5 100644 --- a/src/assembly/sdk/library/cmd_sem_init.c +++ b/src/sdk/library/cmd_sem_init.c @@ -1,13 +1,9 @@ #include "asm.h" -#ifndef NON_MATCHING -INCLUDE_ASM("config/us/expected/asm/assembly/sdk/library/cmd_sem_init/cmd_sem_init.s", - cmd_sem_init); -#else #include "types.h" #include "kernel.h" extern volatile s32 D_001312E0[]; -extern volatile s32 D_001312E8[]; +extern s32 D_001312E8[]; extern s32 D_001312EC[]; extern volatile s32 D_001312F0[]; extern s32 CreateSema(struct SemaParam *); @@ -20,11 +16,10 @@ void cmd_sem_init(void) { sema.option = 0; sema.initCount = 1; sema.maxCount = 1; - D_001312E8[0] = CreateSema(&sema); - D_001312EC[0] = CreateSema(&sema); + /* Both results use the same record; store the first ID before the second call. */ + D_001312EC[0] = CreateSema( + (D_001312E8[0] = CreateSema(&sema)) ? &sema : &sema); sema.initCount = 0; D_001312E0[0] = CreateSema(&sema); D_001312F0[0] = 0; } - -#endif /* NON_MATCHING */ From 3e7f27b9690ca0936a870dd61944c5f0660fb863 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 11:52:17 +0000 Subject: [PATCH 005/251] decomp: improve music_transition --- src/assembly/textbin/audio/music/music_transition.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/assembly/textbin/audio/music/music_transition.c b/src/assembly/textbin/audio/music/music_transition.c index 7b8e55abc..426cac1e0 100644 --- a/src/assembly/textbin/audio/music/music_transition.c +++ b/src/assembly/textbin/audio/music/music_transition.c @@ -9,7 +9,7 @@ INCLUDE_ASM("config/us/expected/asm/assembly/textbin/audio/music/music_transitio #include "rnc/audio/music/music_stream_state.h" #include "rnc/storage/disc_table.h" extern void music_transition_start_callback() __asm__("FUN_00216a80"); -extern void snd_play_vag_stream_by_loc_ex_cb(s32, s32, s32, s32, s16, s32, s32, s32, s32, +extern s32 snd_play_vag_stream_by_loc_ex_cb(s32, s32, s32, s32, s16, s32, s32, s32, s32, void (*)(), u64) __asm__("func_0012EC08"); s32 music_transition(s32 target_track, s32 transition_track, s32 flags, s32 volume) __asm__("FUN_00215e00"); @@ -17,6 +17,7 @@ s32 music_transition(s32 target_track, s32 transition_track, s32 flags, s32 volu volatile s32 *location_entry; s64 stream_location; u64 callback_context; + s16 stream_volume; void (*callback)(); u8 *track_table; s32 track_table_offset; @@ -34,8 +35,8 @@ s32 music_transition(s32 target_track, s32 transition_track, s32 flags, s32 volu return 0; } *(u32 *)&music_stream_state.transition.handle = 0xFFFFFFFF; - sample_rate = 48000; poll_interval = 10; + sample_rate = 48000; music_stream_state.transition.poll_interval = poll_interval; music_stream_state.transition.remaining_time = sample_rate; music_stream_state.transition.track = target_track; @@ -43,10 +44,11 @@ s32 music_transition(s32 target_track, s32 transition_track, s32 flags, s32 volu music_stream_state.transition.volume = volume; music_stream_state.transition.crossfade_enabled = 1; music_stream_state.transition.flags = flags; + stream_volume = volume; stream_location = *location_entry; callback_context = (u32)&music_stream_state.transition.handle; callback = music_transition_start_callback; - snd_play_vag_stream_by_loc_ex_cb(stream_location, 0, 0, 0, volume, 0, 1, 0, 0x20, callback, + snd_play_vag_stream_by_loc_ex_cb(stream_location, 0, 0, 0, stream_volume, 0, 1, 0, 0x20, callback, callback_context); return 1; } From 7d968d5424128bb4e02cf194e92aa6d58c998f64 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 11:50:44 +0000 Subject: [PATCH 006/251] decomp: improve sceSifInitCmd --- src/assembly/sdk/rpc/sce_sif_init_cmd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/assembly/sdk/rpc/sce_sif_init_cmd.c b/src/assembly/sdk/rpc/sce_sif_init_cmd.c index dc38e5fab..f7296ac51 100644 --- a/src/assembly/sdk/rpc/sce_sif_init_cmd.c +++ b/src/assembly/sdk/rpc/sce_sif_init_cmd.c @@ -68,18 +68,19 @@ void sceSifInitCmd(void) { return; block_3: *(s32 *)D_0012FC04 = 1; - temp_5_29 = (s32)D_00154E00 | 0x20000000; temp_6_30 = (s32)D_00154D80 | 0x20000000; - D_00154E58.unk0 = (u8 *)temp_6_30; + temp_5_29 = (s32)D_00154E00 | 0x20000000; + handlers = D_00154E80; D_00154E58.unk1C = D_00154F80; + D_00154E58.unk0 = (u8 *)temp_6_30; D_00154E58.unk4 = (u8 *)temp_5_29; D_00154E58.unk10 = 0x20; D_00154E58.unk8 = 0; ipval = 0x1F; - D_00154E58.unkC = D_00154E80; + D_00154E58.unkC = handlers; D_00154E58.unk14 = 0; D_00154E58.unk18 = 0; - var_3_42 = D_00154E80; + var_3_42 = handlers; do { var_3_42->unk0 = 0; ipval -= 1; From 892ab445fb948344bf180f55d2d2c1da8598e1be Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 12:13:00 +0000 Subject: [PATCH 007/251] decomp: improve sceSifInitCmd --- src/assembly/sdk/rpc/sce_sif_init_cmd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/assembly/sdk/rpc/sce_sif_init_cmd.c b/src/assembly/sdk/rpc/sce_sif_init_cmd.c index f7296ac51..245272ab8 100644 --- a/src/assembly/sdk/rpc/sce_sif_init_cmd.c +++ b/src/assembly/sdk/rpc/sce_sif_init_cmd.c @@ -72,14 +72,14 @@ void sceSifInitCmd(void) { temp_5_29 = (s32)D_00154E00 | 0x20000000; handlers = D_00154E80; D_00154E58.unk1C = D_00154F80; + D_00154E58.unk10 = 0x20; + D_00154E58.unk14 = 0; D_00154E58.unk0 = (u8 *)temp_6_30; D_00154E58.unk4 = (u8 *)temp_5_29; - D_00154E58.unk10 = 0x20; + D_00154E58.unk18 = 0; D_00154E58.unk8 = 0; - ipval = 0x1F; D_00154E58.unkC = handlers; - D_00154E58.unk14 = 0; - D_00154E58.unk18 = 0; + ipval = 0x1F; var_3_42 = handlers; do { var_3_42->unk0 = 0; From 5a4122c19af1d78d56feeab84f783dcee1c40bdd Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 12:14:27 +0000 Subject: [PATCH 008/251] decomp: improve FUN_L00_002bcf98 --- src/overlays/shared/gameplay/entities/002b94d0.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b94d0.c b/src/overlays/shared/gameplay/entities/002b94d0.c index 00a718fc7..f9feaf8d5 100644 --- a/src/overlays/shared/gameplay/entities/002b94d0.c +++ b/src/overlays/shared/gameplay/entities/002b94d0.c @@ -1216,7 +1216,7 @@ void FUN_L00_002bc7e8(Moby *moby) { INCLUDE_ASM("config/us/overlays/asm/FUN_L00_002bcf98.s", FUN_L00_002bcf98); #else extern s32 D_L00_001617BC __attribute__((sda)); -#define D_L00_001617BC_abs (*(volatile s32 *)0x001617BC) +extern s32 D_L00_001617BC_abs __asm__("D_L00_001617BC") __attribute__((section(".data"))); extern f32 D_L00_001616DC __attribute__((sda)); extern f32 D_L00_001617CC __attribute__((sda)); extern volatile s32 D_L00_00161718_i __asm__("D_L00_00161718") __attribute__((sda)); @@ -1226,6 +1226,7 @@ extern s32 D_L00_001617D0 __attribute__((section(".data"))); extern s32 D_L00_00161824 __attribute__((section(".data"))); extern s32 D_L00_00161818 __attribute__((section(".data"))); extern s32 D_L00_001DBF50 __attribute__((section(".data"))); +extern u128 D_L00_001DBF60_2bcf98 __asm__("D_L00_001DBF60") __attribute__((section(".data"))); extern s32 D_L00_001DD0D0 __attribute__((section(".data"))); extern void scale_vector_2bcf98(float, void *, void *) __asm__("FUN_001f9a68"); extern void FUN_001f9a10(void *, void *, void *); @@ -1243,9 +1244,9 @@ void FUN_L00_002bcf98(u8 *m) { scale = D_L00_001616DC / convert_integer_to_float(12); D_L00_001617CC = scale; scale_vector_2bcf98(-scale, &vec, m + 0xD0); - qcopy((u128 *)&D_L00_001DBF50 + 1, (void *)source); + qcopy(&D_L00_001DBF60_2bcf98, (void *)source); for (i = 10; i >= 0; i--) { - FUN_001f9a10(&((u128 *)&D_L00_001DBF50)[12 - i], &((u128 *)&D_L00_001DBF50)[11 - i], &vec); + FUN_001f9a10((&D_L00_001DBF60_2bcf98 + (11 - i)), &((u128 *)&D_L00_001DBF50)[11 - i], &vec); } D_L00_00161718_i = 0; D_L00_00161720_i = 0; From 52031553964955fd9b7740536e26ca14ceaea9e4 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 12:17:08 +0000 Subject: [PATCH 009/251] decomp: improve FUN_L14_00301de8 --- src/overlays/shared/gameplay/vendor/003015d0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/vendor/003015d0.c b/src/overlays/shared/gameplay/vendor/003015d0.c index 27e915e56..95a58722d 100644 --- a/src/overlays/shared/gameplay/vendor/003015d0.c +++ b/src/overlays/shared/gameplay/vendor/003015d0.c @@ -310,7 +310,7 @@ void FUN_L14_00301de8(char *m) { src += 0x40; } i = next_i; - } while ((float)i < 4.0f); + } while ((double)i < 4.0); src = (char *)indices; copy_i = 0; do { From 7fc27941453303fcd71887e54b3d58880f750f0e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 12:55:00 +0000 Subject: [PATCH 010/251] decomp: improve FUN_L04_002ca420 --- src/overlays/l04/gameplay/entities/002ca420.c | 381 ++++++++++++++++++ 1 file changed, 381 insertions(+) diff --git a/src/overlays/l04/gameplay/entities/002ca420.c b/src/overlays/l04/gameplay/entities/002ca420.c index 19d9840c9..244779424 100644 --- a/src/overlays/l04/gameplay/entities/002ca420.c +++ b/src/overlays/l04/gameplay/entities/002ca420.c @@ -35,7 +35,388 @@ void FUN_L04_002d3580(char *m) { m[0x20] = 1; } } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L04_002ca420.s", FUN_L04_002ca420); +#else +extern int D_L04_0015FFD8; +extern int *D_L04_001B0630[]; +extern char *D_L04_001600EC; +extern char D_L04_001DBE10[]; +extern char D_L04_00166F40[]; +extern float D_L04_0015F580[] __attribute__((section(".sdata"))); +extern int D_L04_0015EDF8 __attribute__((sda)); +extern unsigned char D_0013D40E; +extern void FUN_001e93b0(); +extern int truncate_float_to_s32(float) __asm__("FUN_001fa6d0"); +extern int FUN_001f96f8(int); +extern int FUN_001f9740(int *); +extern void FUN_001f9770(void *); +extern float FUN_001f9b48(void *, void *); +extern float FUN_001f9b80(void *, void *); +extern float FUN_001f9af0(void *); +extern float FUN_001f9e90(float, float); +extern float fast_difference_between_rotations(float, float) __asm__("FUN_001fa688"); +extern float fast_add_rotations(float, float) __asm__("FUN_001fa580"); +extern void normalize_vector_xyz(void *, void *, float) __asm__("FUN_001f9bf8"); +extern void add_vector_xyz(void *, void *, void *) __asm__("FUN_001f9a10"); +extern void scale_vector_xyz(void *, void *, float) __asm__("FUN_001f9a68"); +extern void FUN_001f9cf8(void *, void *, void *); +extern void clear_vector(void *) __asm__("FUN_001f99f8"); +extern int is_point_inside_clip_volume(void *, int) __asm__("FUN_00214720"); +extern void FUN_L01_002f5168(void *); +extern void FUN_L00_00258278(void *, float, void *, float, float, float); +extern void attach_manipulator(char *, int, void *) __asm__("FUN_0020cb10"); +extern void FUN_L00_001fff28(void *, int, float); +extern void FUN_0020d580(void *); +extern void FUN_L00_00250df8(void *); +extern void FUN_0020e098(void *); +extern char *find_moby_hit(void *, int, int) __asm__("FUN_L00_0025a420"); +extern void FUN_0022db10(int, int, int); +extern void queue_dialogue_message(int, int) __asm__("FUN_L00_00263d40"); +extern void collect_mobies_in_sphere(void *, float, int, void *, void *) __asm__("FUN_L00_001f2868"); +extern void func_L00_0025F4A8_alt(void *, void *, void *, float, float, int, int, int, float, float, + float, float, int, float, int, int, int, int) __asm__("FUN_L00_0025e450"); +extern int FUN_0022da68(int, int, struct Moby *); +extern void moby_point_position(void *, int, void *) __asm__("FUN_L00_0024f7c8"); +extern void FUN_L00_0025f090(void *, void *, int, float, float); +extern void FUN_L00_00263fd8(void *, int, void *, void *, int, int, float, void *, void *, void *); + +/* Class-dependent movement, manipulator rotation, hit effects and visibility. */ +void FUN_L04_002ca420(struct Moby *moby) { + Vec4 old; + Vec4 delta; + struct { + Vec4 vector; + struct Moby *moby; + int flags; + int unused; + float scale; + int zero; + } sphere, sphere2; + char *data = (char *)moby->pvars; + unsigned char state = moby->state; + int i, *p, *target; + struct Moby *other; + float amount, length; + int timer; + qcopy(&old, &moby->pos); + if (!data) return; + if (!state) { + if (*(int *)((int)(data + 0x60) + 0x14) != -1) { + int *p; + p = D_L04_001B0630[*(int *)((int)(data + 0x60) + 0x14)]; + if (FUN_001f9b48(p + 4, p + *p * 4) < 0.5f) --*p; + } else { + char *message = D_L04_001DBE10; + int oclass = moby->oclass; + timer = truncate_float_to_s32((float)(((int)moby - D_L04_0015FFD8) >> 8)); + FUN_001e93b0(message, oclass, timer); + } + moby->draw_dist = 0x7f; + moby->update_dist = 0xff; + *(float *)(data + 0x138) = *(float *)(data + 0xfc); + *(int *)(data + 0x178) = moby->draw_dist; + } + FUN_L01_002f5168(moby); + if (moby->oclass != 0x1e4) { + FUN_001f9770(data + 0x14a); + switch (*(unsigned char *)(data + 0x149)) { + case 0: + amount = *(float *)(data + 0x138); + if (*(float *)(data + 0xfc) < amount) { + *(float *)(data + 0xfc) += frame_time_sq * 20.0f; + if (amount < *(float *)(data + 0xfc)) *(float *)(data + 0xfc) = amount; + } + target = (int *)(data + 0x150); + p = target; + i = 0; + do { + if (*(short *)(data + 0x14a) == 0 && *p != -1 && + is_point_inside_clip_volume(&moby->pos, *p)) { + qcopy(data + 0x160, &moby->pos); + *(unsigned char *)(data + 0x149) = 1; + *(unsigned char *)(data + 0x148) = *(unsigned char *)target; + *(int *)(data + 0x7c) = 0; + *(float *)(data + 0x14c) = moby->rot.z; + moby->state = 3; + *(int *)(data + 0x11c) = FUN_001f96f8(36000); + break; + } + ++i; ++p; ++target; + } while (i < 4); + break; + case 1: + FUN_L00_00258278(moby, *(float *)(D_L04_001600EC + *(unsigned char *)(data + 0x148) * 0x80 + 0x78), + data + 0x7c, frame_time_sq * 1.0471976f, frame_time_sq * 3.1415927f, frame_time * 3.1415927f); + if (FUN_001f9b80(&moby->pos, D_L04_001600EC + *(unsigned char *)(data + 0x148) * 0x80 + 0x30) < 1.0f && + fast_difference_between_rotations(moby->rot.z, *(float *)(D_L04_001600EC + *(unsigned char *)(data + 0x148) * 0x80 + 0x78)) < 0.17453292f) { + *(unsigned char *)(data + 0x149) = 2; + *(short *)(data + 0x14a) = FUN_001f96f8(300); + } + FUN_001f9a28(&delta, D_L04_001600EC + *(unsigned char *)(data + 0x148) * 0x80 + 0x30, &moby->pos); + normalize_vector_xyz(&delta, &delta, frame_time * 3.0f); + add_vector_xyz(&moby->pos, &moby->pos, &delta); + break; + case 2: + if (*(short *)(data + 0x14a) == 0) { + *(float *)(data + 0x7c) = 0.0f; + *(unsigned char *)(data + 0x149) = 3; + } + break; + case 3: + FUN_L00_00258278(moby, *(float *)(data + 0x14c), data + 0x7c, + frame_time_sq * 1.0471976f, frame_time_sq * 3.1415927f, frame_time * 3.1415927f); + if (FUN_001f9b80(&moby->pos, data + 0x160) < 1.0f && + fast_difference_between_rotations(moby->rot.z, *(float *)(data + 0x14c)) < 0.034906585f) { + *(unsigned char *)(data + 0x149) = 0; + *(short *)(data + 0x14a) = FUN_001f96f8(600); + *(float *)(data + 0x7c) = 0.0f; + *(float *)(data + 0xfc) = 0.0f; + *(int *)(data + 0x11c) = 0; + } + FUN_001f9a28(&delta, data + 0x160, &moby->pos); + length = FUN_001f9af0(&delta); + amount = frame_time * 3.0f; + if (!(length < amount)) length = amount; + normalize_vector_xyz(&delta, &delta, length); + add_vector_xyz(&moby->pos, &moby->pos, &delta); + break; + } + } + if (!state) { + switch ((short)(moby->oclass - 0x1d2)) { + case 0: case 0xe: case 0x13: case 0x14: case 0x1c: case 0x1d: case 0x20: case 0x59: + attach_manipulator((char *)moby, 0, data + 0x180); + *(int *)(data + 0x140) = 0; + break; + case 0x16: case 0x1b: + attach_manipulator((char *)moby, 0, data + 0x180); + *(int *)(data + 0x140) = 0; + attach_manipulator((char *)moby, 1, data + 0x1c0); + *(int *)(data + 0x144) = 0; + break; + } + } else { + switch ((short)(moby->oclass - 0x1d2)) { + case 0: case 0xe: + *(float *)(data + 0x140) = fast_add_rotations(*(float *)(data + 0x140), frame_time * 12.566371f); + FUN_L00_001fff28(data + 0x190, 0, *(float *)(data + 0x140)); + break; + case 0x13: case 0x14: case 0x1c: case 0x1d: case 0x20: case 0x59: + *(float *)(data + 0x140) = fast_add_rotations(*(float *)(data + 0x140), frame_time * 12.566371f); + FUN_L00_001fff28(data + 0x190, 2, *(float *)(data + 0x140)); + break; + case 0x16: case 0x1b: + *(float *)(data + 0x140) = fast_add_rotations(*(float *)(data + 0x140), frame_time * 12.566371f); + FUN_L00_001fff28(data + 0x190, 2, *(float *)(data + 0x140)); + *(float *)(data + 0x144) = fast_add_rotations(*(float *)(data + 0x144), frame_time * 12.566371f); + FUN_L00_001fff28(data + 0x1d0, 2, *(float *)(data + 0x144)); + break; + } + } + if (*(int *)(data + 0x17c) != -1) { + other = (struct Moby *)(D_L04_0015FFD8 + (*(int *)(data + 0x17c) << 8)); + other->draw_dist = 0x7f; + if (moby->oclass == 0x1e0) { + delta.q = 0; + delta.f[0] = 0.5f; + delta.f[2] = -5.0f; + FUN_001f9cf8(&delta, &delta, &moby->rot_row0); + add_vector_xyz(&other->pos, &moby->pos, &delta); + qcopy(&other->rot, &moby->rot); + other->rot.y = fast_add_rotations(other->rot.y, 1.5707964f); + } else if (moby->oclass == 0x1ee) { + delta.q = 0; + delta.f[2] = -2.0f; + FUN_001f9cf8(&delta, &delta, &moby->rot_row0); + add_vector_xyz(&other->pos, &moby->pos, &delta); + qcopy(&other->rot, &moby->rot); + } else goto hit; + FUN_0020d580(other); + FUN_L00_00250df8(other); + FUN_0020e098(other); + other->flags |= 6; + } +hit: + if (find_moby_hit(moby, 0x210000, 0)) { + if (++D_L04_0015EDF8 >= 10 && !D_0013D40E) { + D_0013D40E = 1; + FUN_0022db10(1, 0, 0); + queue_dialogue_message(0x53d6, -1); + } + switch ((short)(moby->oclass - 0x1d2)) { + case 0x13: case 0x14: + sphere.flags = 0x810000; + sphere.scale = 1.0f; + sphere.moby = moby; + clear_vector(&sphere.vector); + sphere.zero = 0; + collect_mobies_in_sphere(&moby->pos, 4.0f, 0x10, moby, &sphere); + case 0: case 0xe: case 0x16: case 0x18: case 0x1c: case 0x1d: case 0x20: case 0x59: + delta.q = 0; + delta.f[2] = 0.75f; + clear_vector(&sphere.vector); + add_vector_xyz(&delta, &delta, &moby->pos); + func_L00_0025F4A8_alt(moby, &sphere.vector, &delta, 0.0f, 0.0f, 10, 3, 4, 2.0f, 1.0f, + 100000.0f, 3.0f, -1, 15.0f, 1, 1, -1, 0); + if (moby->oclass == 0x1f2 || moby->oclass == 0x22b) FUN_0022da68(0, 0, moby); + else if (moby->oclass != 0x1e6) FUN_0022da68(1, 0, moby); + *(int *)(data + 0x170) = FUN_001f96f8(600); + *(int *)(data + 0x174) = 1; + break; + case 0x1b: + sphere.vector.q = 0; + sphere.vector.f[2] = 0.75f; + clear_vector(&sphere.moby); + moby_point_position(moby, 0, &delta); + add_vector_xyz(&delta, &delta, &sphere.vector); + FUN_L00_0025f090(moby, &delta, -1, 1.0f, 13.0f); + moby_point_position(moby, 1, &delta); + add_vector_xyz(&delta, &delta, &sphere.vector); + FUN_L00_0025f090(moby, &delta, -1, 1.0f, 13.0f); + add_vector_xyz(&delta, &sphere.vector, &moby->pos); + func_L00_0025F4A8_alt(moby, &sphere.moby, &delta, 0.0f, 0.0f, 20, 5, 4, 2.0f, 1.0f, + 100000.0f, 3.0f, -1, 15.0f, 1, 1, -1, 0); + FUN_0022da68(1, 0, moby); + sphere2.flags = 0x810000; + sphere2.scale = 2.0f; + sphere2.moby = moby; + clear_vector(&sphere2.vector); + sphere2.zero = 0; + collect_mobies_in_sphere(&moby->pos, 6.0f, 0x10, moby, &sphere2); + *(int *)(data + 0x170) = FUN_001f96f8(600); + *(int *)(data + 0x174) = 1; + break; + } + scale_vector_xyz(&delta, &moby->rot_row0, frame_scale * 0.075f); + delta.f[2] += frame_scale * 0.08f; + if (moby->oclass == 0x1d2) { + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x63f, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x641, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x642, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + } + else if (moby->oclass == 0x1e0) { + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x642, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x643, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x644, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + } + else if (moby->oclass == 0x1e6) { + int i; + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x645, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + i = 5; + do { + --i; + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x646, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + } while (i >= 0); + } + else if (moby->oclass == 0x1ea) { + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x647, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x648, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x649, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + } + else if (moby->oclass == 0x1ee) { + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x64d, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x64e, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + } + else if (moby->oclass == 0x1ef) { + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x64f, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x650, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x651, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x658, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + } + else if (moby->oclass == 0x1f2) { + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x652, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x653, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x654, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + } + else if (moby->oclass == 0x1ed) { + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x793, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x794, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + i = 2; + do { + --i; + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x795, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + } while (i >= 0); + i = 2; + do { + --i; + timer = FUN_001f96f8(90); + FUN_L00_00263fd8(moby, 0x796, &moby->pos, &moby->rot, timer, 0, + frame_time_sq * 12.0f, &delta, D_L04_0015F580, D_L04_0015F580); + } while (i >= 0); + } + } + moby->hit_slot = 0xff; + if (*(int *)(data + 0x174) == 0) return; + if (FUN_001f9740((int *)(data + 0x170))) { + amount = FUN_001f9e90(moby->pos.x - *(float *)(D_L04_00166F40), moby->pos.y - *(float *)(D_L04_00166F40 + 4)); + if (1.5707964f < fast_difference_between_rotations(*(float *)(D_L04_00166F40 + 0x18), amount)) { + moby->collision = moby->pclass->collision; + moby->flags &= 0xffbe; + *(int *)(data + 0x174) = 0; + if (*(int *)(data + 0x17c) != -1) { + other = (struct Moby *)(D_L04_0015FFD8 + (*(int *)(data + 0x17c) << 8)); + other->flags &= 0xffbe; + } + moby->flags |= 0x1000; + return; + } + } + moby->collision = 0; + moby->flags |= 0x41; + if (*(int *)(data + 0x17c) != -1) { + other = (struct Moby *)(D_L04_0015FFD8 + (*(int *)(data + 0x17c) << 8)); + other->flags |= 0x41; + } + moby->flags &= 0xefff; +} +#endif #include "qcopy.h" From 5788867640e38806723b80ee789136499fba6e47 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 12:56:34 +0000 Subject: [PATCH 011/251] decomp: improve FUN_L00_002c26c8 --- .../shared/gameplay/entities/002bffa8.c | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+) diff --git a/src/overlays/shared/gameplay/entities/002bffa8.c b/src/overlays/shared/gameplay/entities/002bffa8.c index 69f9b15e6..906d6d687 100644 --- a/src/overlays/shared/gameplay/entities/002bffa8.c +++ b/src/overlays/shared/gameplay/entities/002bffa8.c @@ -1060,7 +1060,242 @@ void aim_throw_arc(V2c2488 *pos, V2c2488 *tgt, f32 *out, f32 speed, f32 unused, out[2] = v; } } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L00_002c26c8.s", FUN_L00_002c26c8); +#else +typedef struct { + u8 pad0[0x40]; + OvlVec4 grip; + struct Moby *held; + s32 timer; + s32 delay; +} CarrierVars_2c26c8; +typedef struct { + u8 pad0[0x50]; + u16 deliveries; /* D_001416D0: saturates at 0xFFFF */ + u16 unkA2; + u32 levels; +} DeliveryStats_2c26c8; +extern DeliveryStats_2c26c8 D_00141680_2c26c8 __asm__("D_00141680"); +extern struct Moby *D_L00_001ABA00_2c26c8[] __asm__("D_L00_001ABA00") __attribute__((section(".data"))); +extern u8 *FUN_002141f8_2c26c8(struct Moby *) __asm__("FUN_002141f8"); +#include "rnc/input/pad_state.h" +extern struct Moby *FUN_L00_002ace70(struct Moby *, void *); +extern void FUN_L00_002acfd8(void *, struct Moby *, void *); +extern u8 D_0013E531; +extern f32 D_0015ED68; +extern f32 D_0015ED6C __attribute__((section(".sdata"))); +extern f32 D_0015ED70 __attribute__((section(".sdata"))); +extern s32 D_0015EEA4; +extern u32 D_0013CAE4 __attribute__((section(".data"))); +extern CollisionHit coll_hit __asm__("D_L00_00173E40") __attribute__((section(".data"))); +extern OvlVec4 D_L00_00166DC0_2c1ad0 __asm__("D_L00_00166DC0") __attribute__((section(".data"))); +extern OvlVec4 D_L00_00166C80_2c1ad0[3] __asm__("D_L00_00166C80") __attribute__((section(".data"))); +extern char D_L00_001B07B0[] __attribute__((section(".data"))); +extern void FUN_L00_002aa008(void *, void *, void *); +extern struct Moby *FUN_L00_002a9ed0(void *, void *, void *); +extern void FUN_L00_0025f780(void *, void *, int); +extern void FUN_0020c828(void *); +extern void FUN_0020cca8(void *, int, void *); +extern f32 FUN_001f9988(f32); +extern f32 fast_add_rotations(f32, f32) __asm__("FUN_001fa580"); +extern f32 atan2_f(f32, f32) __asm__("FUN_001f9e90"); +extern f32 FUN_001f9dc8(f32); +extern f32 FUN_001f9de0(f32); +extern void add_vector_xyz(void *, void *, void *) __asm__("FUN_001f9a10"); +extern void scale_vector_xyz(void *, void *, f32) __asm__("FUN_001f9a68"); +extern s32 scale_game_frames(s32) __asm__("FUN_001f96f8"); +extern s32 tick_countdown(s32 *) __asm__("FUN_001f9740"); +extern s32 collision_line(void *, void *, s32, void *, s32) __asm__("FUN_001efa68"); +extern void setup_matrix_2c1ad0(void *, void *) __asm__("FUN_001fa2b8"); +extern void matrix_from_basis_rows_2c1ad0(void *, void *) __asm__("FUN_001fa2d8"); +extern void rotate_vector_2c1ad0(void *, void *, void *) __asm__("FUN_001f9d20"); +extern void adjust_direction_2c1ad0(void *, void *, void *) __asm__("FUN_001f9cf8"); +extern f32 vector_length_xy_2c1ad0(void *) __asm__("FUN_001f9b20"); +extern f32 fast_subtract_rotations_2c1ad0(f32, f32) __asm__("FUN_001fa5c8"); +extern void build_spherical_offset_2c1ad0(void *, f32, f32, f32) __asm__("FUN_00214db0"); +extern int hero_set_state_2c1ad0(int, int) __asm__("FUN_L00_002223f8"); +extern int FUN_L00_00216de8_2c1ad0(int, int) __asm__("FUN_L00_00216de8"); +extern int FUN_L00_00233db8_2c1ad0(int, int) __asm__("FUN_L00_00233db8"); +extern int FUN_L00_00233e98_2c1ad0(int) __asm__("FUN_L00_00233e98"); +/* Updates the grip, chooses a throw target, and handles the held moby states. */ +void FUN_L00_002c26c8(struct Moby *moby) { + CarrierVars_2c26c8 *vars; + OvlVec4 local[4], saved, offset, rotatedOffset, pos, target, basis[3], matrix[4]; + OvlVec4 launch; + union { OvlVec4 arc; } temporary; + OvlVec4 direction; + OvlVec4 probe; + f32 angle, slope, distance, horizontal, vertical, radius, speed; + f32 gravity, root; + s32 hit = 0; + + if (moby == 0) + return; + vars = (CarrierVars_2c26c8 *)moby->pvars; + offset.q = 0; + offset.f[1] = -0.09f; + offset.f[2] = -0.02f; + setup_matrix_2c1ad0(basis, D_L00_00166C80_2c1ad0); + matrix_from_basis_rows_2c1ad0(matrix, basis); + if (vars == 0) + return; + if (vars->delay < 3) { + ++vars->delay; + return; + } + FUN_L00_0024f7c8((u8 *)moby, 0, &saved); + FUN_0020cca8(moby, 0, local); + rotate_vector_2c1ad0(&rotatedOffset, &offset, local); + add_vector_xyz(&vars->grip, &saved, &rotatedOffset); + if (vars->held != 0) + vars->held->collision_disable = 1; + if (vars->held == 0 || vars->held->state == 0xFE || vars->held->state == 0xFD) + vars->held = 0; + if (hero.state.current == 1) + hero_set_state_2c1ad0(0x1E, 1); + if (tick_countdown(&vars->timer) && !hero.unk20AC) { + if ((hero.unk20A8 && hero.unk1BC == scale_game_frames(0x11)) || + ((D_0013CAE4 & hero.items[0].button_mask) && + hero.state.current == 0x1E && FUN_L00_00233e98_2c1ad0(-1)) || + (hero.state.current == 0x23 && hero.state_timer == scale_game_frames(0x10))) { + FUN_L00_00216de8_2c1ad0(0x1A, 0); + FUN_L00_00233db8_2c1ad0(-1, 1); + moby->state = 3; + } + } + if (vars->held != 0) { + f32 best = 15.0f; + f32 *out = (f32 *)vars->held->pvars; + launch.q = 0; + launch.f[0] = 1.0f; + adjust_direction_2c1ad0(&launch, &launch, hero.basis); + pos.f[0] = FUN_001f9dc8(fast_add_rotations(-0.361968011f, atan2_f(hero.unk670, hero.unk674))) * 0.859039009f; + pos.f[1] = FUN_001f9de0(fast_add_rotations(-0.361968011f, atan2_f(hero.unk670, hero.unk674))) * 0.859039009f; + pos.f[2] = 0.0f; + add_vector_xyz(&pos, &pos, &hero.motion.pos); + pos.f[2] += 0.490819991f; + angle = atan2_f(launch.f[0], launch.f[1]); + { + f32 speed = (controller_state.held & 5) ? scale_ticks(D_0013E52A[0]) * 2.5f + 8.5f : 8.5f; + scale_vector_xyz(&target, &launch, speed); + } + add_vector_xyz(&target, &target, &pos); + if ((controller_state.held & 5) && !hero.unk20AC) { + temporary.arc.q = 0; + temporary.arc.f[2] = 1.0f; + rotate_vector_2c1ad0(&temporary.arc, &temporary.arc, matrix); + hit = 0; + fast_subtract_rotations_2c1ad0(hero.moby->rot.z, atan2_f(temporary.arc.f[0], temporary.arc.f[1])); + angle = atan2_f(temporary.arc.f[0], temporary.arc.f[1]); + slope = atan2_f(vector_length_xy_2c1ad0(&temporary.arc), temporary.arc.f[2]); + if (0.593411922f < slope) slope = 0.593411922f; + if (slope < -1.39626336f) slope = -1.39626336f; + { + f32 speed = (controller_state.held & 5) ? scale_ticks(D_0013E52A[0]) * 2.5f + 8.5f : 8.5f; + build_spherical_offset_2c1ad0(&temporary.arc, speed, angle, slope); + } + qcopy(&direction, &D_L00_00166DC0_2c1ad0); + { + f32 distance = vector_length_xy_2c1ad0(&temporary.arc); + f32 z = temporary.arc.f[2]; + if (distance != 0.0f) horizontal = z / distance; + else horizontal = z / 0.01f; + } + gravity = D_0015ED70 * 11.0f; + root = FUN_001f9988(gravity * ((controller_state.held & 5) ? scale_ticks(D_0013E52A[0]) * 2.5f + 8.5f : 8.5f) * 0.5f); + radius = (root + root) * root * (1.0f - horizontal) / (D_0015ED70 * 11.0f); + vertical = horizontal * radius; + if (0.0f < radius) { + temporary.arc.f[0] = FUN_001f9dc8(angle) * radius; + temporary.arc.f[1] = FUN_001f9de0(angle) * radius; + temporary.arc.f[2] = vertical; + add_vector_xyz(&probe, &D_L00_00166DC0_2c1ad0, &temporary.arc); + if (collision_line(&D_L00_00166DC0_2c1ad0, &probe, 2, moby, 0) && coll_hit.moby != (s32)hero.moby) { + qcopy(&target, &coll_hit.point); + hit = 1; + angle = atan2_f(target.f[0] - pos.f[0], target.f[1] - pos.f[1]); + } + if (!hit) { + target.f[0] = FUN_001f9dc8(angle) * radius * 5.0f; + target.f[1] = FUN_001f9de0(angle) * radius * 5.0f; + target.f[2] = vertical * 5.0f; + add_vector_xyz(&target, &target, &D_L00_00166DC0_2c1ad0); + } + } + } else { + struct Moby **entry = D_L00_001ABA00_2c26c8; + struct Moby *candidate; + hero.unkA50 = 0; + while ((candidate = *entry) != 0) { + u8 *data = FUN_002141f8_2c26c8(candidate); + if ((s8)candidate->state >= 0 && data && (candidate->flags & 0x1000)) { + f32 candidateAngle, elevation, difference; + qcopy(&temporary.arc, &candidate->pos); + temporary.arc.f[2] += *(f32 *)(data + 0x10); + distance = dist2(&pos, &temporary.arc); + candidateAngle = atan2_f(temporary.arc.f[0] - pos.f[0], temporary.arc.f[1] - pos.f[1]); + elevation = atan2_f(dist2(&pos, &temporary.arc), temporary.arc.f[2] - pos.f[2]); + difference = adiff(angle, candidateAngle); + if ((difference < 0.785398185f || (distance < 4.0f && difference < 1.57079637f)) && distance < best && elevation < 0.959931076f && temporary.arc.f[2] - pos.f[2] < 2.0f && !collision_line(&D_L00_00166DC0_2c1ad0, &temporary.arc, 6, moby, 0)) { + best = distance; + hero.unkA50 = (u8 *)candidate; + angle = candidateAngle; + qcopy(&target, &temporary.arc); + } + } + ++entry; + } + } + gravity = D_0015ED70 * 11.0f; + speed = (controller_state.held & 5) ? scale_ticks(D_0013E52A[0]) * 2.5f + 8.5f : 8.5f; + aim_throw_arc((V2c2488 *)&pos, (V2c2488 *)&target, out, gravity, 0.00000999999975f, speed); + } + switch (moby->state) { + case 0: + vars->held = 0; + moby->state = !(moby->anim_flags & 2) ? 1 : 2; + case 1: + if (moby->anim_flags & 2) + moby->state = 2; + break; + case 3: + if (vars->held == 0) { + vars->held = FUN_L00_002ace70(moby, &vars->grip); + } else { + FUN_L00_002acfd8(&pos, vars->held, vars->held->pvars); + if (D_00141680_2c26c8.deliveries <= 0xfffe) + ++D_00141680_2c26c8.deliveries; + { + s32 frames = scale_game_frames(D_0015EEA4); + if (D_00141680_2c26c8.unkA2 < frames / 600) + D_00141680_2c26c8.unkA2 = scale_game_frames(D_0015EEA4) / 600; + } + D_00141680_2c26c8.levels = (D_00141680_2c26c8.levels | (1u << (current_level_index & 31))) | 0x80000000; + vars->held = 0; + moby->state = 4; + vars->timer = scale_game_frames(0x14); + } + break; + case 4: + if (hero.state.current != 0x23 && !hero.unk20A8) + moby->state = 2; + break; + case 5: + moby->state = 6; + break; + case 6: + /* Retail reloads held after destruction before the common tail. */ + if (vars->held != 0) + FUN_0020c828(vars->held); + break; + } + if (vars->held != 0) + qcopy(&vars->held->pos, &vars->grip); + else if (FUN_L00_00233e98_2c1ad0(-1) || hero.unk20A8) + vars->held = FUN_L00_002ace70(moby, &vars->grip); +} +#endif extern u8 D_0013E539; extern s32 D_L00_0015FFD8_2c35c0 __asm__("D_L00_0015FFD8"); extern s16 D_L00_001B0830[] __attribute__((section(".data"))); From a47d08326d77085241e78e98a1e9e57df093bee3 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 12:57:09 +0000 Subject: [PATCH 012/251] decomp: improve FUN_L01_0030df40 --- .../shared/gameplay/vendor/0030b618.c | 311 ++++++++++++++++++ 1 file changed, 311 insertions(+) diff --git a/src/overlays/shared/gameplay/vendor/0030b618.c b/src/overlays/shared/gameplay/vendor/0030b618.c index e3f956fbb..867e56fbc 100644 --- a/src/overlays/shared/gameplay/vendor/0030b618.c +++ b/src/overlays/shared/gameplay/vendor/0030b618.c @@ -726,7 +726,318 @@ void FUN_L01_0030ded0(char *moby) { } enqueue_callback_list_1_alt(FUN_L01_0030de68, moby); } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L01_0030df40.s", FUN_L01_0030df40); +#else +extern u8 D_0013D4C5; +extern u8 D_0015EDB0; +extern char D_0013E550[]; +extern char D_L01_001BB6B0[]; +extern s32 D_0014C190[][64]; +extern s32 D_L01_001742D8; +extern char *D_L01_00167280_df40 __asm__("D_L01_00167280"); +extern char D_L01_0020BA10[], D_L01_0020BA30[]; +extern s32 D_L01_00162098 __attribute__((sda)); +extern s32 D_L01_0016209C __attribute__((sda)); +extern s32 D_L01_001620A4 __attribute__((sda)); +extern s32 D_L01_001620A8 __attribute__((sda)); +extern s32 D_L01_001620AC __attribute__((sda)); +extern f32 D_L01_001620B0 __attribute__((sda)); +extern f32 D_L01_001620B4 __attribute__((sda)); +extern f32 D_L01_001620B8 __attribute__((sda)); +extern s32 D_L01_001620BC __attribute__((sda)); +extern f32 D_L01_001620C0 __attribute__((sda)); +extern void FUN_001e93b0(void *); +extern void FUN_0020cb10(void *, s32, void *); +extern void FUN_0020cb88(void *, void *); +extern void FUN_00212f90(void *, s32, s32, s32); +extern void FUN_L01_0026d930(void *); +extern void FUN_L01_002e30b8(void *, void *) __asm__("FUN_L01_0030d208"); +extern void FUN_L01_0023cf98(s32, s32); +extern void FUN_L00_002323b8(f32, s32, s32); + +extern void FUN_0022d798(s32); +extern s32 FUN_L00_00259028(void *, void *, void *, void *); +extern void FUN_L00_00259fe8(void *, f32); +extern void FUN_L00_0025f8e0(void *, f32); +extern s32 FUN_001160d8(void); +extern void FUN_L01_0030dda0_with_vars(char *, char *) __asm__("FUN_L01_0030dda0"); +extern s32 FUN_0022da68_sound(s32, s32, void *) __asm__("FUN_0022da68"); +extern void FUN_L00_00272060(void *, s32, u32, s32, s32, void *, f32, f32, f32); +extern f32 FUN_001fa580(f32, f32); +extern s32 FUN_001efa68(void *, void *, s32, void *, s32); + +#define HOVER_I(off) (*(s32 *)(p + (off))) +#define HOVER_S(off) (*(s16 *)(p + (off))) +#define HOVER_F(off) (*(f32 *)(p + (off))) +#define HOVER_SOUND_VALID ( *(struct Moby **)(D_0013E550 + HOVER_I(0x64) * 0x70 + 0x88) == m && *(u8 *)(D_0013E550 + HOVER_I(0x64) * 0x70 + 0x74) != 0 ) +void FUN_L01_0030df40(struct Moby *m) { + char *p; + struct Moby *e; + OvlVec4 v, q; + struct HoverTuning *t; + s64 hit; + s32 n, r, duration; + u32 color; + f32 angle; + char *g; + if (m == 0) return; + p = (char *)m->pvars; + if (p == 0) return; + if (HOVER_I(0x48) != -1) { + if (m->state < 5) { + e = (struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100); + angle = FUN_001f9e90(hero.motion.pos.f[0] - e->pos.x, hero.motion.pos.f[1] - e->pos.y); + } else { + e = (struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100); + angle = FUN_001f9e90(m->pos.x - e->pos.x, m->pos.y - e->pos.y); + } + *(f32 *)((struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100))->pvars = angle; + if (HOVER_I(0x48) != -1) + ((struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100))->collision = 0; + } + if (m->state >= 3) { + if (D_0015EDB0 != 0) { + if (*(u8 *)(p + 0x91) == 0) FUN_0020cb10(m, 5, p + 0x90); + HOVER_F(0xb8) = 2.1f; + HOVER_F(0xb0) = 2.1f; + HOVER_F(0xb4) = 2.1f; + } else if (*(u8 *)(p + 0x91) != 0) FUN_0020cb88(m, p + 0x90); + FUN_L01_0030ded0((char *)m); + } + switch (m->state) { + case 0: + qzero(p); + qzero(p + 0x10); + HOVER_S(0x50) = 0; + HOVER_S(0x52) = 0; + if (m->prev_seq != 0) FUN_00212f90(m, 0, 0, FUN_001f96f8(10)); + m->update_dist = 0xff; + m->draw_dist = 0xff; + if (HOVER_I(0x48) == -1) { + FUN_001e93b0(D_L01_0020BA30); + mark_moby_for_removal_b618(m); + return; + } + qcopy(&m->pos, D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100 + 0x10); + m->pos.z += 0.02f; + n = (s16)m->save_id; + if (*(u8 *)(D_L01_001BB6B0 + n + 0x454) != 0 || ((D_0014C190[current_level_index][n >> 5] >> (m->save_id & 31)) & 1)) { + FUN_001e93b0(D_L01_0020BA10); + mark_moby_for_removal_b618(m); + return; + } + qcopy(p + 0x20, &m->pos); + qcopy(p + 0x30, &m->pos); + t = &D_L01_001DEB38; + FUN_L01_0026d930(t); + { + f32 scale = frame_scale; + f32 time = frame_time; + f32 time_sq = frame_time_sq; + f32 turn = time_sq * 3.1415927f; + f32 speed = scale * 0.4f; + f32 limit = time * 2.7f; + f32 rate = scale * 0.01f; + f32 turn_speed = time_sq * 6.2831855f; + f32 turn_limit = time * 11.519173f; + s32 flags = *(s32 *)((char *)t + 0x38) | 8; + t->unk0 = 500; + *(f32 *)((char *)t + 0xc) = 0.15f; + t->yaw_speed = speed; + *(f32 *)((char *)t + 0x24) = limit; + *(f32 *)((char *)t + 0x1c) = rate; + *(f32 *)((char *)t + 4) = 0.3f; + t->unk30 = 0.005f; + *(s32 *)((char *)t + 0x38) = flags; + *(f32 *)((char *)t + 0x3c) = turn_speed; + *(f32 *)((char *)t + 0x40) = turn; + *(f32 *)((char *)t + 0x44) = turn_limit; + *(f32 *)((char *)t + 8) = 0.15f; + *(f32 *)((char *)t + 0x10) = rate; + } + *(s32 *)((char *)t + 0x48) = FUN_001f96f8(4); + *(f32 *)((char *)t + 0x28) = 3.1415927f; + m->state = 1; + m->draw_dist = 0; + break; + case 1: + g = (char *)&hero; + if (D_0013D4C5 == 0) break; + if (*(s32 *)(g + 0x1158) != 5) break; + HOVER_I(0x5c) = 0; + HOVER_I(0x58) = FUN_001f96f8(D_L01_00162098); + if (m->visible != 0 && (m->anim_flags & 2) && m->prev_seq != 2) + FUN_00212f90(m, 2, 0, FUN_001f96f8(10)); + if (HOVER_I(0x48) != -1) { + n = is_point_inside_clip_volume_b618(&hero.motion.pos, HOVER_I(0x40)) ? 3 : 1; + ((struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100))->command = n; + } + if (*(s32 *)(g + 0x1130) == 0 || *(s32 *)(g + 0x1158) != 5) break; + angle = FUN_001f9e90(hero.motion.pos.f[0] - m->pos.x, hero.motion.pos.f[1] - m->pos.y); + FUN_L00_00258278(m, &D_L01_001DEB4C, angle, frame_time_sq * 6.2831855f, frame_time_sq * 3.1415927f, frame_time * 11.519173f); + qcopy(&v, D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100 + 0x10); + v.f[2] += 0.5f; + qcopy(&q, &hero.motion.pos); + q.f[2] += 0.2f; + if (!is_point_inside_clip_volume_b618(&hero.motion.pos, HOVER_I(0x40))) break; + if (FUN_001efa68(&v, &q, 0, m, 0) && D_L01_001742D8 != (s32)hero.moby) break; + FUN_L01_002e30b8(m, p); + e = *(struct Moby **)(g + 0x1130); + if (e != 0 && e->oclass == 0x1b1 && e->state != 0xfe && e->state != 0xfd) e->state = 1; + *(struct Moby **)((char *)&D_L01_001DEB38 + 0x50) = m; + FUN_L01_0023cf98(0x1f, 0); + FUN_L00_002323b8((f32)FUN_001f96f8(6), 0, 0); + if (HOVER_I(0x48) == -1) { + m->draw_dist = 0xff; + if (m->prev_seq != 0) FUN_00212f90(m, 0, 0, FUN_001f96f8(10)); + m->state = 3; + } else { + ((struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100))->command = 5; + m->state = 2; + } + break; + case 2: + if (HOVER_I(0x48) == -1) { + HOVER_S(0x52) = 0; + m->draw_dist = 0xff; + if (m->prev_seq != 0) FUN_00212f90(m, 0, 0, FUN_001f96f8(20)); + if (HOVER_I(0x64) == -1) HOVER_I(0x64) = FUN_0022da68_sound(1, 4, m); + m->state = 3; + } else { + if (((struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100))->state != 5) break; + if (m->prev_seq != 0) FUN_00212f90(m, 0, 0, FUN_001f96f8(10)); + m->state = 3; + HOVER_S(0x52) = 0; + m->draw_dist = 0xff; + } + break; + case 3: + if (!HOVER_SOUND_VALID) { + HOVER_I(0x64) = -1; + HOVER_I(0x64) = FUN_0022da68_sound(1, 4, m); + } + if (FUN_001f9b80(&m->pos, p + 0x30) > 0.6f && HOVER_S(0x52) == 0) { + *(f32 *)((char *)&D_L01_001DEB38 + 4) = 0.7f; + FUN_L01_0030d260(m, (f32 *)p); + FUN_L01_0030d880(m, (struct HoverVars *)p); + hit = HOVER_S(0x50) < 21 ? 0 : 2; + } else { + FUN_L01_002e30b8(m, p); + angle = FUN_001f9e90(HOVER_F(0) - m->pos.x, HOVER_F(4) - m->pos.y); + FUN_L00_00258278(m, &D_L01_001DEB4C, angle, frame_time_sq * 6.2831855f, frame_time_sq * 3.1415927f, frame_time * 11.519173f); + HOVER_F(0x18) = 0.0f; + hit = FUN_L00_00259028(m, &D_L01_001DEB38, p, p + 0x10); + } + if ((hit & 6) != 0 || distance_xyz_30d308(&m->pos, p) < 0.25f) { + if (m->prev_seq != 2) FUN_00212f90(m, 2, 0, FUN_001f96f8(10)); + qzero(p + 0x10); + m->state = 4; + HOVER_S(0x52) = FUN_001f96f8(120); + } + if (m->anim_flags & 2) { + if (m->prev_seq != 1) FUN_00212f90(m, 1, 0, FUN_001f96f8(random_integer_between_b618(7, 12))); + m->anim_speed = random_float_between_alt(0.95f, 1.05f); + } + break; + case 4: + if (!HOVER_SOUND_VALID) { + HOVER_I(0x64) = -1; + HOVER_I(0x64) = FUN_0022da68_sound(1, 4, m); + } + FUN_L01_0023cf98(0, 1); + m->flags &= 0xffbe; + if (HOVER_I(0x48) != -1) ((struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100))->flags &= 0xffbe; + m->state = 5; + break; + case 5: + g = (char *)&hero; + if (!HOVER_SOUND_VALID) { + HOVER_I(0x64) = -1; + HOVER_I(0x64) = FUN_0022da68_sound(1, 4, m); + } + n = HOVER_S(0x52); + if (n == FUN_001f96f8(20) || D_L01_0016209C - 5 < HOVER_I(0x5c)) { + if (m->prev_seq != 2) FUN_00212f90(m, 2, 0, FUN_001f96f8(5)); + } else { + n = HOVER_S(0x52); + if (FUN_001f96f8(20) < n && (m->anim_flags & 2)) { + if (m->prev_seq != 1) FUN_00212f90(m, 1, 0, FUN_001f96f8(random_integer_between_b618(7, 12))); + m->anim_speed = random_float_between_alt(0.95f, 1.05f); + } + } + if (*(s32 *)(g + 0x1130) == 0 || *(s32 *)(g + 0x1158) != 5 || hero.state.control_mode == 22 || hero.state.control_mode == 20 || hero.vehicle_mode != 0 || *(s16 *)(D_L01_00167280_df40 + 0x86) == 20 || FUN_001f9740(p + 0x58) || D_L01_0016209C <= HOVER_I(0x5c)) { + qzero(p + 0x10); + HOVER_S(0x52) = D_L01_001620A4; + if (HOVER_I(0x64) != -1 && HOVER_SOUND_VALID) FUN_0022d798(HOVER_I(0x64)); + HOVER_I(0x64) = -1; + FUN_0022da68_sound(2, 0, m); + m->state = 6; + if (HOVER_I(0x48) != -1) ((struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100))->command = 5; + } else { + FUN_L01_0030d260(m, (f32 *)p); + FUN_L01_0030d880(m, (struct HoverVars *)p); + } + FUN_L01_0030d5f0((char *)m, p); + break; + case 6: + if (HOVER_I(0x64) != -1 && HOVER_SOUND_VALID) FUN_0022d798(HOVER_I(0x64)); + HOVER_I(0x64) = -1; + if (FUN_001f9770(p + 0x52)) { + m->alpha = 0x80; + qcopy(&m->pos, p + 0x30); + qcopy(p, p + 0x30); + qzero(p + 0x10); + m->state = 7; + m->flags &= 0xfdff; + } else { + q.q = 0; + qcopy(&v, &m->pos); + FUN_L00_0025f8e0(&v, D_L01_001620B0); + color = (FUN_001160d8() + 0x30u) & 0x3f; + color |= ((FUN_001160d8() + 0x20u) & 0x3f) << 8; + color |= (FUN_001160d8() & 0x2fu) << 16; + color |= D_L01_001620BC << 24; + r = FUN_001160d8() % 2; + if (*(u16 *)(p + 0x52) & 1) r = -r; + n = random_integer_between_b618(D_L01_001620A8, D_L01_001620AC); + angle = random_float_between_alt(D_L01_001620B4, D_L01_001620B8); + FUN_L00_00272060(&v, n, color, 2, r, &q, angle, 0.001f, D_L01_001620C0 * frame_time_sq); + m->flags |= 0x200; + m->alpha -= 0x80 / D_L01_001620A4; + m->rot.z = FUN_001fa580(m->rot.z, frame_time * 25.132742f); + } + break; + case 7: + if (HOVER_I(0x64) != -1 && HOVER_SOUND_VALID) FUN_0022d798(HOVER_I(0x64)); + HOVER_I(0x64) = -1; + qzero(p + 0x10); + qcopy(p, D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100 + 0x10); + *(s32 *)((char *)&D_L01_001DEB38 + 0x50) = 0; + angle = FUN_001f9e90(HOVER_F(0) - m->pos.x, HOVER_F(4) - m->pos.y); + FUN_L00_00258278(m, &D_L01_001DEB4C, angle, frame_time_sq * 6.2831855f, frame_time_sq * 3.1415927f, frame_time * 11.519173f); + if (m->prev_seq != 0) FUN_00212f90(m, 0, 0, FUN_001f96f8(6)); + ((struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100))->command = 1; + m->state = 1; + m->draw_dist = 0; + break; + case 8: + break; + } + if (m->state >= 2) { + FUN_L00_00259fe8(m, 0.3f); + FUN_L01_0030dda0_with_vars((char *)m, p); + } + if (HOVER_I(0x48) != -1) { + e = (struct Moby *)(D_L01_0015FFD8_b618 + HOVER_I(0x48) * 0x100); + e->collision = e->pclass->collision; + } +} +#undef HOVER_I +#undef HOVER_S +#undef HOVER_F +#undef HOVER_SOUND_VALID +#endif /* Camera blocks FUN_L01_00314e98 resets (camera + 0x70 and its preset row in D_L01_0015EF50) */ typedef struct { Vec4 pos; /* 0x00 */ From 321ffc7d6af21e1facfb6363fca6ad40f0f94eb4 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:07:50 +0000 Subject: [PATCH 013/251] decomp: improve FUN_L05_00301f48 --- src/overlays/l05/gameplay/entities/002d1688.c | 392 ++++++++++++++++++ 1 file changed, 392 insertions(+) diff --git a/src/overlays/l05/gameplay/entities/002d1688.c b/src/overlays/l05/gameplay/entities/002d1688.c index 819a8c8f8..5f2522fdf 100644 --- a/src/overlays/l05/gameplay/entities/002d1688.c +++ b/src/overlays/l05/gameplay/entities/002d1688.c @@ -1021,7 +1021,399 @@ void FUN_L05_002db238(void *moby, void *dir) { } } } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L05_00301f48.s", FUN_L05_00301f48); +#else +extern void spawn_particle_305178(void *, int, void *, void *, int, int, float, void *, void *, void *) __asm__("FUN_L00_00263fd8"); +extern int D_L05_0015F5C4; +extern char *D_L05_0015FFD8_7920 __asm__("D_L05_0015FFD8"); +extern int D_L05_00161A84 __attribute__((sda)); +extern float D_L05_00161A98 __attribute__((sda)); +extern int D_L05_00161A9C __attribute__((sda)); +extern int D_L05_00161AA0 __attribute__((sda)); +extern int D_L05_00161AA4 __attribute__((sda)); +extern int D_L05_00161AA8 __attribute__((sda)); +extern float D_L05_00161AAC __attribute__((sda)); +extern float D_L05_00161AB0 __attribute__((sda)); +extern float D_L05_00161AB4 __attribute__((sda)); +extern float D_L05_00161AB8 __attribute__((sda)); +extern float D_L05_00161ABC __attribute__((sda)); +extern float D_L05_00161AC0 __attribute__((sda)); +extern float D_L05_00161AC4 __attribute__((sda)); +extern int D_L05_00161AC8 __attribute__((sda)); +extern int D_001404A8; +extern float distance_2d1688(void *, void *) __asm__("FUN_001f9b48"); +extern float distance_to_2d1688(void *, void *) __asm__("FUN_001f9b80"); +extern float absolute_2d1688(float) __asm__("FUN_001f99c0"); +extern void fast_vec_add(void *, void *, void *) __asm__("FUN_001f9a10"); +extern void mark_moby_2d1688(char *) __asm__("FUN_0020c828"); +extern char D_L05_001671C0[]; +extern float D_0013F3D0[4]; +extern void FUN_L01_0026d930(char *); +extern int FUN_L00_00258b50(void *, void *, void *, void *, float); +extern void FUN_L05_0028be78(void *, int, int); +extern void FUN_L05_00303390(struct Moby *); +extern void FUN_L05_00303b08(struct Moby *, int, float); +extern void FUN_L00_00263b38(void *, float); +extern void FUN_L00_0025a120(void *); +extern int follow_path(void *, int, int, void *, int, void *, float) __asm__("FUN_L01_00276fe8"); +extern float angle_diff(float, float) __asm__("FUN_001fa688"); +extern float approach_value(float *, float, float) __asm__("FUN_00213ed8"); +extern float approach_angle(float *, float, float *, float, float, float) __asm__("FUN_L00_0025be00"); +extern int FUN_L00_00261d78(int, void *, void *, float); +extern int FUN_L00_00261b48(int, void *, void *, void *); +extern int FUN_L00_0025c698(void *, void *); +extern int is_point_inside_clip_volume(void *, int) __asm__("FUN_00214720"); +extern void moby_point_position(void *, int, void *) __asm__("FUN_L00_0024f7c8"); +extern float FUN_0020c9e0(struct Moby *); +extern int FUN_001f9770(void *); +extern void FUN_L00_00259bc8(void *, int, int, void *, void *, float); +extern void FUN_L00_0025f090(void *, void *, int, float, float); +#define F301(p,o) (*(float *)((char *)(p)+(o))) +#define I301(p,o) (*(int *)((char *)(p)+(o))) +#define H301(p,o) (*(unsigned short *)((char *)(p)+(o))) +#define S301(p,o) (*(short *)((char *)(p)+(o))) +#define B301(p,o) (*(unsigned char *)((char *)(p)+(o))) +void FUN_L05_00301f48(struct Moby *moby) { + char *data = (char *)moby->pvars; + struct Moby *target; + float v[4] __attribute__((aligned(16))); + float w[4] __attribute__((aligned(16))); + float point[4] __attribute__((aligned(16))); + float pos[4] __attribute__((aligned(16))); + float distance, angle; + float *rotation; + float height_limit; + float height; + int timer, i, n1, n2, n3; + int blocked; + FUN_L00_00263b38(data + 0x170, 2.5f); + if (D_L05_0015F5C4 == 2) { + if (((moby->flags ^ 1) & 1) == 0) goto check_freeze; + I301(data,0x2dc) = 1; + moby->flags |= 0x41; + goto freeze_done; + } +check_freeze: + if (I301(data,0x2dc) != 0 && D_L05_0015F5C4 == 0) { + I301(data,0x2dc) = 0; + moby->flags &= 0xffbe; + } +freeze_done: + if (moby->visible && distance_2d1688((char *)moby + 0x10, D_L05_001671C0) < 28.0f) { + FUN_L00_0025a120(moby); + moby->shadow_range = 0x16; + } + FUN_L05_00303390(moby); + target = *(struct Moby **)(data + 0x160); + moby->scale = moby->pclass->scale * D_L05_00161A98; + switch (moby->state) { + case 0: + moby->flags |= 0x1000; + qcopy(data + 0x270, (char *)moby + 0x10); + F301(data,0x20) = 2.0f; + B301(data,0x29) = 0; + I301(data,0x2b0) = 0; + B301(data,0x28) = 1; + F301(data,0x30) = 1.0f; + S301(data,0x24) = 2; + B301(data,0x58) = func_001FA898_r(14.0f); + B301(data,0x5a) = func_001FA898_r(11.2f); + FUN_L01_0026d930(data + 0xd0); + distance = D_L05_00161A98 * 409.6f; + F301(data,0xdc) = 2.0f; + F301(data,0xd8) = 2.0f; + timer = func_001FA898_r(distance); + { + float speed = frame_time * 6.0f; + I301(data,0xd0) = timer; + F301(data,0xf4) = speed; + } + F301(data,0x2d8) = random_angle_radians(); + if (random_integer_below(2)) moby->flags |= 0x8000; + else moby->flags &= 0x7fff; + if (I301(data,0x2b4)) { + moby->state = 12; + moby->collision = 0; + moby->flags &= 0xefff; + moby->pos.z -= 20.0f; + moby->visible = 0; + moby->draw_dist = 0; + } else { + if (*(long *)(data + 0x2b8) != -1) { + moby->state = 15; + moby->flags &= 0xefff; + if (moby->prev_seq) blend_moby_animation(moby,0,0,0); + } else { + moby->state = 1; + if (moby->prev_seq) blend_moby_animation(moby,0,0,0); + } + } + FUN_L05_0028be78(data + 0x2c0,1,I301(data,0x2c4)); + break; + case 1: + if (I301(data,0x164) != 2) { + if (random_integer_below(9) == 0) { + if (follow_path(data+0x2c0,1,I301(data,0x2c4),(char *)moby+0x10,(int)((char *)target+0x10),v,D_L05_00161A98*0.4f) != 0) { + if (random_integer_below(0x100)&1) F301(data,0x298) = -F301(data,0x298); + F301(data,0x294) = F301(data,0x298)*0.017453292f; + I301(data,0x2ac) = FUN_001f96f8((int)random_float_between(30.0f,90.0f)); + moby->state = 4; + if (moby->prev_seq != 1) blend_moby_animation(moby,1,0,FUN_001f96f8(10)); + } else { + I301(data,0x164) = 2; + } + } + } +check_mode: + if (I301(data,0x164) == 2 && I301(data,0x2b0)) { + moby->state = 6; + if (moby->prev_seq != 1) blend_moby_animation(moby,1,0,FUN_001f96f8(10)); + goto done; + } + if (!(moby->anim_flags&2)) break; + if (moby->visible && (random_integer_below(255)&1)) { + random_vector((float *)(data+0x280),0.0f,4.0f); + F301(data,0x288) = 0.0f; + fast_vec_add(data+0x280,data+0x280,data+0x270); + H301(data,0x2d2) = 0; + moby->command = moby->state; + moby->state = 2; + if (moby->prev_seq != 1) blend_moby_animation(moby,1,0,FUN_001f96f8(10)); + goto done; + } + if (moby->prev_seq != 0) blend_moby_animation(moby,0,0,FUN_001f96f8(10)); + goto done; + case 2: + rotation=&moby->rot.z; + angle = FUN_001f9e90(F301(data,0x280)-moby->pos.x,F301(data,0x284)-moby->pos.y); + approach_angle(rotation,angle,(float *)(data+0x290),frame_time_sq*6.2831855f,frame_time_sq*6.2831855f,frame_time*6.2831855f); + if (angle_diff(moby->rot.z,FUN_001f9e90(F301(data,0x280)-moby->pos.x,F301(data,0x284)-moby->pos.y)) < 1.5707964f) { + v[0] = FUN_001f9dc8(moby->rot.z); v[0] += v[0]; + v[1] = FUN_001f9de0(moby->rot.z); v[1] += v[1]; + v[2] = 0.0f; + FUN_L00_00258b50(moby,data+0xd0,v,w,1.0f); + FUN_L00_00261d78(I301(data,0x2c0),(char *)moby+0x10,(char *)moby+0x10,D_L05_00161A98*0.4f); + } + H301(data,0x2d2) += 1; + distance=distance_to_2d1688((char *)moby+0x10,data+0x280); + timer=S301(data,0x2d2); + if (distance < 1.0f) { + if (timer > FUN_001f96f8(60)) goto finish_wander; + timer=S301(data,0x2d2); + } + if (timer <= FUN_001f96f8(180)) break; +finish_wander: + moby->state = moby->command; + if (moby->prev_seq != 0) blend_moby_animation(moby,0,0,FUN_001f96f8(20)); + goto done; + case 6: + rotation=&moby->rot.z; + approach_value((float *)(data+0xf4),frame_time*6.0f,frame_time_sq*6.0f); + angle=FUN_001f9e90(target->pos.x-moby->pos.x,target->pos.y-moby->pos.y); + approach_angle(rotation,angle,(float *)(data+0x290),frame_time_sq*6.2831855f,frame_time_sq*6.2831855f,frame_time*6.2831855f); + if (angle_diff(moby->rot.z,FUN_001f9e90(target->pos.x-moby->pos.x,target->pos.y-moby->pos.y)) < 1.5707964f) { + v[0]=FUN_001f9dc8(moby->rot.z); v[0]+=v[0]; + v[1]=FUN_001f9de0(moby->rot.z); v[1]+=v[1]; + v[2]=0.0f; + FUN_L00_00258b50(moby,data+0xd0,v,w,1.0f); + FUN_L00_00261d78(I301(data,0x2c0),(char *)moby+0x10,(char *)moby+0x10,D_L05_00161A98*0.4f); + } + blocked = 0; + if (FUN_L00_00261b48(I301(data,0x2c0),(char *)moby+0x10,(char *)target+0x10,point) && distance_2d1688((char *)moby+0x10,point)<1.5f) blocked = 1; + if (blocked) { + moby->state=5; + if (moby->prev_seq != 4) blend_moby_animation(moby,4,0,FUN_001f96f8(20)); + goto done; + } + if (I301(data,0x2b0)==0) { moby->state=10; break; } + if (distance_to_2d1688((char *)moby+0x10,(char *)target+0x10)<3.0f) { + moby->state=7; + H301(data,0x2d0)=FUN_001f96f8(D_L05_00161AC8); + if (moby->prev_seq != 2) blend_moby_animation(moby,2,0,FUN_001f96f8(10)); + goto done; + } + break; + case 5: + if (I301(data,0x2b0)==0) { + F301(data,0xf4)=0.0f; + moby->state=10; + if (moby->prev_seq != 1) blend_moby_animation(moby,1,0,FUN_001f96f8(20)); + goto done; + } + if (distance_to_2d1688((char *)moby+0x10,(char *)target+0x10) < 3.0f) { + moby->state=7; + H301(data,0x2d0)=FUN_001f96f8(D_L05_00161AC8); + if (moby->prev_seq != 2) blend_moby_animation(moby,2,0,FUN_001f96f8(10)); + } + break; + case 15: + if ((I301(data,0x2b8)!=-1 && B301(D_L05_0015FFD8_7920+I301(data,0x2b8)*256,0xbc)) || (I301(data,0x2bc)!=-1 && is_point_inside_clip_volume(D_0013F3D0,I301(data,0x2bc)))) { + moby->draw_dist=0x40; moby->state=1; moby->flags|=0x1000; + break; + } + if (!(moby->anim_flags&2)) break; + if (random_integer_below(255)&1) { + random_vector((float *)(data+0x280),0.0f,4.0f); + F301(data,0x288)=0.0f; + fast_vec_add(data+0x280,data+0x280,data+0x270); + H301(data,0x2d2)=FUN_001f96f8(90); + moby->command=moby->state; moby->state=2; + if (moby->prev_seq != 1) blend_moby_animation(moby,1,0,FUN_001f96f8(10)); + goto done; + } + if (moby->prev_seq != 0) blend_moby_animation(moby,0,0,FUN_001f96f8(10)); + goto done; + case 4: + distance=distance_to_2d1688((char *)moby+0x10,(char *)target+0x10); + FUN_L05_00303b08(moby,(int)((char *)target+0x10),F301(data,0x294)); + if (distance < 3.0f && angle_diff(moby->rot.z,FUN_001f9e90(target->pos.x-moby->pos.x,target->pos.y-moby->pos.y)) < 0.7853982f) { + moby->state=7; + H301(data,0x2d0)=FUN_001f96f8(D_L05_00161AC8); + if (moby->prev_seq!=2) blend_moby_animation(moby,2,0,FUN_001f96f8(10)); + } + if (I301(data,0x164)==2) moby->state=10; + break; + case 7: { + float angle; + float zero; + rotation=&moby->rot.z; + angle=FUN_001f9e90(target->pos.x-moby->pos.x,target->pos.y-moby->pos.y); + approach_angle(rotation,angle,(float *)(data+0x290),frame_time_sq*12.566371f,frame_time_sq*12.566371f,frame_time*25.132742f); + if ((moby->anim_flags&2) && moby->prev_seq==2) blend_moby_animation(moby,7,0,FUN_001f96f8(5)); + if (!FUN_001f9770(data+0x2d0)) break; + moby->state=8; + H301(data,0x2d0)=0; + if (moby->prev_seq!=3) blend_moby_animation(moby,3,0,FUN_001f96f8(1)); + zero=0.0f; + angle=FUN_001fa580(moby->rot.z,zero); + v[0]=FUN_001f9dc8(angle)*(D_L05_00161AB8*frame_time); + v[1]=FUN_001f9de0(angle)*(D_L05_00161AB8*frame_time); + v[2]=zero; v[3]=D_L05_00161AC0; + w[2]=zero; w[3]=D_L05_00161AC4; + moby_point_position(moby,0,point); + i = 29; + do { + qcopy(pos,point); + distance=random_float_between(-0.065f,0.065f); + i--; + pos[0]+=distance; + pos[1]+=random_float_between(-0.065f,0.065f); + pos[2]+=random_float_between(-0.065f,0.065f); + w[0]=random_float_between(-frame_time,frame_time); + w[1]=random_float_between(-frame_time,frame_time); + w[2]=random_float_between(-(D_L05_00161ABC*frame_time),D_L05_00161ABC*frame_time); + n1=func_001FA898_r(FUN_001f96b0(random_float_between(D_L05_00161AAC,D_L05_00161AAC+D_L05_00161AAC))); + n2=func_001FA898_r(FUN_001f96b0(random_float_between(D_L05_00161AB0,D_L05_00161AB0*1.2f))); + n3=func_001FA898_r(FUN_001f96b0(random_float_between(D_L05_00161AB4,D_L05_00161AB4*1.2f))); + FUN_00218888(pos,v,w,D_L05_00161A9C,D_L05_00161AA0,n1,n2,n3,-1); + } while (i >= 0); + v[3]=D_L05_00161AC0*0.1f; w[3]=D_L05_00161AC4*0.1f; + { + int i = 29; + do { + qcopy(pos,point); + distance=random_float_between(-0.065f,0.065f); + i--; + pos[0]+=distance; + pos[1]+=random_float_between(-0.065f,0.065f); + pos[2]+=random_float_between(-0.065f,0.065f); + w[0]=random_float_between(-frame_time,frame_time); + w[1]=random_float_between(-frame_time,frame_time); + w[2]=random_float_between(-(D_L05_00161ABC*frame_time),D_L05_00161ABC*frame_time); + n1=func_001FA898_r(FUN_001f96b0(random_float_between(D_L05_00161AAC,D_L05_00161AAC+D_L05_00161AAC))); + n2=func_001FA898_r(FUN_001f96b0(random_float_between(D_L05_00161AB0,D_L05_00161AB0*1.2f))); + n3=func_001FA898_r(FUN_001f96b0(random_float_between(D_L05_00161AB4,D_L05_00161AB4*1.2f))); + FUN_00218888(pos,v,w,D_L05_00161AA4,D_L05_00161AA8,n1,n2,n3,-1); + } while (i >= 0); + } + break; + } + case 8: { + int flags; + angle=FUN_001fa580(moby->rot.z,0.0f); + if (FUN_0020c9e0(moby)<1.5f && angle_diff(angle,FUN_001f9e90(target->pos.x-moby->pos.x,target->pos.y-moby->pos.y))<0.2617994f && distance_to_2d1688((char *)moby+0x10,(char *)target+0x10)<3.0f && absolute_2d1688(target->pos.z-moby->pos.z)<2.0f) { + v[0]=FUN_001f9dc8(moby->rot.z); + v[1]=FUN_001f9de0(moby->rot.z); + v[2]=0.0f; v[3]=5627.925f; + qcopy(w,(char *)target+0x10); + flags=0x10001; + if (D_001404A8==6) flags=0x10000; + w[2]+=0.75f; + FUN_L00_00259bc8(target,(int)moby,flags,w,v,1.0f); + } + if (moby->anim_flags&2) { moby->state=9; if (moby->prev_seq != 4) blend_moby_animation(moby,4,0,FUN_001f96f8(10)); + goto done; } + break; + } + case 9: + if (!(moby->anim_flags&2)) break; + if (distance_to_2d1688((char *)moby+0x10,(char *)target+0x10)<3.0f && angle_diff(moby->rot.z,FUN_001f9e90(target->pos.x-moby->pos.x,target->pos.y-moby->pos.y))<0.2617994f) { + moby->state=7; H301(data,0x2d0)=FUN_001f96f8(D_L05_00161AC8); + if (moby->prev_seq != 7) blend_moby_animation(moby,7,0,FUN_001f96f8(5)); + goto done; + } + F301(data,0xf4)=0.0f; moby->state=4; + if (moby->prev_seq != 1) blend_moby_animation(moby,1,0,FUN_001f96f8(10)); + goto done; + case 10: + FUN_L05_00303b08(moby,(int)(data+0x270),0.0f); + if (distance_to_2d1688((char *)moby+0x10,data+0x270)<1.0f) { + moby->state=1; if (moby->prev_seq != 0) blend_moby_animation(moby,0,0,FUN_001f96f8(3)); + goto done; + } + if (I301(data,0x164)!=2) { + moby->state=4; if (moby->prev_seq != 1) blend_moby_animation(moby,1,0,FUN_001f96f8(3)); + goto done; + } else { + if (I301(data,0x2b0)) moby->state=6; + } + break; + case 11: + if (FUN_L00_0025c698(moby,data+0x70)&0x60) { + if (follow_path(data+0x2c0,1,I301(data,0x2c4),(char *)moby+0x10,(int)(data+0x270),v,D_L05_00161A98*0.4f)!=0) { + moby->state=4; + if (moby->prev_seq != 1) blend_moby_animation(moby,1,0,FUN_001f96f8(10)); + goto done; + } + FUN_L00_0025f090(moby,(char *)moby+0x10,-1,0.5f,13.0f); + goto remove; + } + height_limit=2.0f; + height=moby->pos.z; + goto check_height; + case 13: + if (moby->anim_flags&2) { moby->state=1; if (moby->prev_seq != 0) blend_moby_animation(moby,0,0,FUN_001f96f8(10)); + goto done; } + break; + case 14: + if (FUN_L00_0025c698(moby,data+0x70)&0x60) { + FUN_L00_0025f090(moby,(char *)moby+0x10,-1,0.5f,13.0f); + spawn_particle_305178((char *)moby,0x6da,(float *)((char *)moby+0x10),(char *)moby+0x40,0,0,0.0f,(float *)D_L05_0015F580,(float *)D_L05_0015F580,(float *)D_L05_0015F580); + spawn_particle_305178((char *)moby,0x6db,(float *)((char *)moby+0x10),(char *)moby+0x40,0,0,0.0f,(float *)D_L05_0015F580,(float *)D_L05_0015F580,(float *)D_L05_0015F580); + spawn_particle_305178((char *)moby,0x6dc,(float *)((char *)moby+0x10),(char *)moby+0x40,0,0,0.0f,(float *)D_L05_0015F580,(float *)D_L05_0015F580,(float *)D_L05_0015F580); + goto remove; + } + height=moby->pos.z; + height_limit=0.0f; + goto check_height; + } + goto done; +check_height: + if (height_limit>height) goto remove; + goto done; +remove: + mark_moby_2d1688((char *)moby); + return; +done: + D_L05_00161A84=*(volatile int *)0x10000000; +} +#undef F301 +#undef I301 +#undef H301 +#undef S301 +#undef B301 +#endif #include "rnc/math/vector.h" /* Level 5 moby update (a flying enemy): takes hits through func_L00_0025B4D0 and reacts per hit kind, then From 493cbaa1e41bd6e60e57622101819998d36b602c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:30:32 +0000 Subject: [PATCH 014/251] decomp: improve FUN_L00_002bffa8 --- .../shared/gameplay/entities/002bffa8.c | 367 ++++++++++++++++++ 1 file changed, 367 insertions(+) diff --git a/src/overlays/shared/gameplay/entities/002bffa8.c b/src/overlays/shared/gameplay/entities/002bffa8.c index 906d6d687..b11fc13a2 100644 --- a/src/overlays/shared/gameplay/entities/002bffa8.c +++ b/src/overlays/shared/gameplay/entities/002bffa8.c @@ -675,7 +675,374 @@ void FUN_L00_002c82f0(Vec4_2c82f0 *a, u8 *m, void *c) { m[0x20] = 2; } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L00_002bffa8.s", FUN_L00_002bffa8); +#else +#include "rnc/math/fast_math.h" +typedef struct { + OvlVec4 target_pos, velocity, previous_pos; + s32 timer, age; + struct Moby *target, *previous_target; + float turn_velocity, speed; + u8 pad48[0x14]; + float move_speed; + struct Moby *owner; + float angle; +} Vars_2bffa8; +extern CollisionHit collision_hit_2bffa8 __asm__("D_L00_00173E40") __attribute__((section(".data"))); +extern int FUN_L00_0025a420(void *, int, int); +extern void FUN_L00_00260400(void *, int, void *, void *, void *, void *); +extern float FUN_00213508_2bffa8(void *, int, float) __asm__("FUN_00213508"); +extern int FUN_001fa6d0_2c53c0(float) __asm__("FUN_001fa6d0"); +extern void FUN_00257880_2c4380(void *, int, int, int) __asm__("FUN_00212f90"); +extern int tick_countdown(s32 *) __asm__("FUN_001f9740"); +extern int FUN_L00_002beab0(void *, int, int); +extern void FUN_L00_002beb90(void *); +extern void FUN_L00_002bebc8(void *); +extern void FUN_L00_002bec00(void *); +extern void FUN_L00_002bec48(void *); +extern struct Moby *FUN_L00_002bed90(void *, void *, void *, void *, int); +extern float FUN_L00_002bf050(void *, void *, void *, void *, float, float, float, float, float, float); +extern int FUN_L00_002bf8b0(void *, void *, void *); +extern int FUN_L00_002bf9f0(void *, void *, void *, int); +extern u8 FUN_L00_002bfec8(void *); +extern void FUN_L00_00258278_2bffa8(void *, void *, float, float, float, float) __asm__("FUN_L00_00258278"); +extern u32 FUN_L00_00258ad0_2bffa8(void *, void *, int, int, float, float) __asm__("FUN_L00_00258ad0"); +extern u32 FUN_L00_00259028(void *, void *, void *, void *); +extern int FUN_L00_0025b440(void *, void *); +extern void FUN_L00_0025e450_2bffa8(void *, void *, void *, int, int, int, int, int, int, int, int, float, float, float, float, float, float, float) __asm__("FUN_L00_0025e450"); +extern void collect_mobies_in_sphere(float, void *, int, void *, void *) __asm__("FUN_L00_001f2868"); +extern void FUN_L00_0025a9f8_2bffa8(void *, void *, void *, int, int, int, int, int, float, float, float) __asm__("FUN_L00_0025a9f8"); +extern void FUN_0028dbe8_2c4380(int, int, void *) __asm__("FUN_0022da68"); +extern void FUN_L00_0024eb68_2c4380(void *) __asm__("FUN_0020c828"); +extern int coll_sphere(float, void *, int, void *) __asm__("FUN_L00_001f0d60"); +extern int FUN_00213260_2bffa8(int) __asm__("FUN_00213260"); +extern float FUN_001f9b48_2c1928(void *, void *) __asm__("FUN_001f9b48"); +extern float FUN_001f9b80_2c1928(void *, void *) __asm__("FUN_001f9b80"); +extern u8 *FUN_002141f8_2c26c8(struct Moby *) __asm__("FUN_002141f8"); +extern int FUN_001efa68_002c82f0(void *, void *, int, void *, int) __asm__("FUN_001efa68"); +extern void FUN_001f9c90_2bffa8(void *, void *, float) __asm__("FUN_001f9c90"); +extern void FUN_L00_001ff600_2bffa8(void *, void *, float) __asm__("FUN_L00_001ff600"); +extern void FUN_001e93b0_2bffa8(void *) __asm__("FUN_001e93b0"); +extern char D_L00_001E9B48[], D_L00_001E9B70[]; +extern s32 D_L00_00177F00[]; +extern void *memset(void *, int, unsigned int); +extern f32 atan2_f(f32, f32) __asm__("FUN_001f9e90"); +extern int collect_mobies_in_sphere_2bffa8(float, void *, int, void *, void *) __asm__("FUN_L00_001f2868"); +#define HF_2bffa8(o) (*(float *)((u8 *)&hero + (o))) +#define HI_2bffa8(o) (*(int *)((u8 *)&hero + (o))) +#define HB_2bffa8(o) (*((u8 *)&hero + (o))) +#define ANIM_2bffa8(a,t) FUN_00257880_2c4380(moby,(a),0,scale_game_frames(t)) +#define OUTSIDE_2bffa8 (moby->pos.x < 2.0f || 1021.0f < moby->pos.x || moby->pos.y < 2.0f || 1021.0f < moby->pos.y || moby->pos.z < 2.0f || 1021.0f < moby->pos.z) +void FUN_L00_002bffa8(struct Moby *moby) { + extern int level_game_mode __asm__("D_L00_0015F5C4") __attribute__((sda)); + Vars_2bffa8 *vars; + OvlVec4 probe, start, end, delta, result; + void *pos; + float size, speed, distance, height, limit, angle, rate, old_z; + u8 state; + u8 *data; + int hit; + u32 flags; + struct Moby *target; + if (!moby) return; + vars = (Vars_2bffa8 *)moby->pvars; + if (!vars) return; + if (level_game_mode == 2) { moby->flags |= 0x41; return; } + moby->flags &= 0xffbe; + if (OUTSIDE_2bffa8) goto destroy; + if (FUN_L00_0025a420(moby,0x800001,0)) moby->state = 11; + size = convert_integer_to_float(item_text_variant[20]) + 1.0f; + moby->scale += (moby->pclass->scale * size - moby->scale) * 0.05f; + speed = convert_integer_to_float(item_text_variant[20]) * 0.5f + 1.0f; + if (moby->seq == 0 || moby->seq == 6 || moby->seq == 7) moby->anim_speed = speed / size; + else moby->anim_speed = 1.0f; + if (moby->state != 11) { + HI_2bffa8(0x1ec0) = FUN_001fa6d0_2c53c0(size * 183.296f) + 1; + HI_2bffa8(0x1ef0) = 0; + HF_2bffa8(0x1ec4) = size * 0.198f + 0.02f; + if (moby->state == 0) { + memset((u8 *)&hero + 0x1f10,0,0x40); + { + float scale_01 = frame_scale * 0.01f; + float scale_02 = frame_scale * 0.02f; + float scale_045 = frame_scale * 0.045f; + float scale_066 = frame_scale * 0.066f; + float scale_2 = frame_scale * 0.2f; + float size_25 = size * 0.25f; + float size_01 = size * 0.01f * frame_scale; + float time_297 = frame_time_sq * 29.7f; + float size_1 = size * 0.1f; + HF_2bffa8(0x1ecc) = size_25; + HF_2bffa8(0x1ec8) = size_25; + vars->speed = scale_2; + vars->turn_velocity = size_01; + HF_2bffa8(0x1ee0) = 0.3f; + HF_2bffa8(0x1ee4) = 2.7f; + HF_2bffa8(0x1edc) = size_01; + HI_2bffa8(0x1ed8) = 0; + vars->move_speed = scale_066 * speed; + HB_2bffa8(0x1f3e) = 4; + HB_2bffa8(0x1f3c) = 2; + HB_2bffa8(0x1f3d) = 3; + HF_2bffa8(0x1f4c) = scale_045; + HF_2bffa8(0x1ee8) = 3.1415927f; + HF_2bffa8(0x1f2c) = time_297; + HF_2bffa8(0x1f30) = size_1; + HF_2bffa8(0x1f34) = 7.5f; + HF_2bffa8(0x1f38) = 11.5f; + HF_2bffa8(0x1f44) = scale_02; + HF_2bffa8(0x1f48) = scale_01; + HF_2bffa8(0x1f00) = scale_01; + HF_2bffa8(0x1efc) = scale_02; + HF_2bffa8(0x1f04) = scale_045; + } + vars->target = 0; moby->state = 14; vars->timer = 0; + vars->move_speed = frame_scale * 0.1f * speed; + FUN_L00_002beb90(vars); FUN_L00_002bec00(vars); + if (moby->prev_seq != 5) ANIM_2bffa8(5,5); + } + if (moby->state == 13) { + if (!vars->owner || vars->owner->state == 254 || vars->owner->state == 253 || OUTSIDE_2bffa8) goto destroy; + return; + } + vars->age = (s32)((u32)vars->age + 1); + if (scale_game_frames(3600) < vars->age) moby->state = 11; + tick_countdown(&vars->timer); + qcopy(&vars->previous_pos,&moby->pos); + if (FUN_L00_002beab0(moby,5,0)) { + target = (struct Moby *)collision_hit_2bffa8.moby; + if (!target) goto land; + if (collision_hit_2bffa8.unk1C < 0 && (target->flags & 0x1000) && target->pclass && target->pclass->type == 5) { moby->state = 11; goto collision_done; } + if (!collision_hit_2bffa8.moby || collision_hit_2bffa8.unk1C < 0) { +land: + old_z = moby->pos.z; + qcopy(&moby->pos,(u8 *)&collision_hit_2bffa8 + 0x30); + /* Retail subtracts the saved height from itself. */ + if (0.6f < absolute_float(old_z - old_z)) moby->pos.z = old_z + 0.01f; + qcopy(&vars->velocity,(u8 *)&collision_hit_2bffa8 + 0x40); + FUN_001f9c90_2bffa8(&vars->velocity,&vars->velocity,frame_scale * 0.05f); + FUN_L00_001ff600_2bffa8(&vars->velocity,&vars->velocity,frame_scale * 0.05f); + moby->state = 8; + if (vars->target) { vars->previous_target = vars->target; vars->timer = (s32)((u32)vars->timer + 500); } + if (moby->prev_seq != 5) ANIM_2bffa8(5,5); + } + } +collision_done: + if (moby->pos.z < 0.1f) goto destroy; + if (vars->timer > 4000) moby->state = 11; + } + pos = &moby->pos; + if (FUN_00213508_2bffa8(pos,0,0.5f) != 0.0f && collision_hit_2bffa8.moby) + FUN_L00_00260400(moby,collision_hit_2bffa8.moby,pos,&moby->rot,pos,&moby->rot); + switch (moby->state) { + case 15: goto reset; + case 0: + FUN_001e93b0_2bffa8(D_L00_001E9B48); moby->state = 1; goto finish; + case 8: + fast_vec_add(&probe,pos,&vars->velocity); + vars->velocity.f[2] -= frame_time_sq * 9.0f; + FUN_L00_002beb90(vars); + flags = FUN_L00_00258ad0_2bffa8(moby,&vars->velocity,HI_2bffa8(0x1ec0),0,size*0.7f,HF_2bffa8(0x1ef0)); + if (flags & 2) { vars->velocity.f[2] = 0.0f; fast_vec_scale(&vars->velocity,&vars->velocity,0.5f); } + FUN_L00_001ff600_2bffa8(&vars->velocity,&vars->velocity,frame_scale*0.05f); + if (moby->anim_flags & 2) { if (flags & 2) moby->state = 2; else goto falling_anim; } + goto turn; + case 1: case 9: case 10: + if (moby->anim_flags & 2) moby->state = 2; + break; + case 2: case 3: case 4: case 5: + target = vars->target; + if (target && target->state != 254 && target->state != 253) { + height = target->pos.z; + data = FUN_002141f8_2c26c8(target); + limit = speed; + if (data) { distance = convert_integer_to_float(data[10]); height += *(float *)(data+0x10); limit = speed + distance * 0.125f; } + if (FUN_001f9b48_2c1928(pos,&vars->target->pos) < limit && coll_sphere(speed,pos,1,moby)) { moby->state = 11; goto finish; } + distance = FUN_001f9b80_2c1928(pos,&vars->target->pos); + limit *= 0.5f; + if (distance < limit && absolute_float(height - (moby->pos.z + speed * 0.1f)) < limit) { + FUN_L00_002bec00(vars); + FUN_L00_002bf8b0(moby,(u8 *)&hero+0x1f10,&vars->target->pos); + FUN_L00_002bec48(vars); + qcopy(&vars->target_pos,&vars->target->pos); + vars->move_speed = frame_scale * 0.066f * speed; + if (moby->prev_seq != 0) ANIM_2bffa8(0,2); + moby->state = 6; + } + } + qcopy(&probe,pos); probe.f[2] += size * 0.3f; + hit = FUN_00213260_2bffa8(4); + rate = frame_scale; + if (!hit) { vars->target = FUN_L00_002bed90(moby,&probe,&moby->rot,vars->previous_target,1); rate = frame_scale; } + vars->move_speed = rate * 0.1f * speed; moby->state = 4; + if (!vars->target) { + angle = random_float_between(-3.1415927f,3.1415927f); + if (!FUN_00213260_2bffa8(4)) vars->angle = FUN_L00_002bf050(moby,pos,0,&result,angle,1.847995638847351f,4.0f,size*0.35f,4.0f,convert_integer_to_float(HI_2bffa8(0x1ec0))*0.0009765625f); + else result.f[0] = 5.0f; + } + target = vars->target; + if (target && target != hero.moby) { + if (!target || target->state == 254 || target->state == 253 || !target->pclass || target->pclass->type != 5 || !(target->flags & 0x1000)) { + vars->target = 0; moby->state = 2; + vars->move_speed = frame_scale * 0.0273f * speed; goto finish; + } + } + state = moby->state; + if (!target) { + moby->state = 5; + if (moby->prev_seq != 6) ANIM_2bffa8(6,10); + vars->move_speed = frame_scale * 0.0273f * speed; + } else { + if (!FUN_00213260_2bffa8(4) && FUN_L00_002bf9f0(moby,vars,&vars->target->pos,1)) { + qcopy(&vars->target_pos,&vars->target->pos); + vars->move_speed = frame_scale * 0.066f * speed; + if (moby->prev_seq != 0) ANIM_2bffa8(0,2); + moby->state = 6; goto finish; + } + distance = FUN_001f9b80_2c1928(pos,&vars->target->pos); + if (vars->target == hero.moby) { + moby->state = 5; + rate = frame_scale; + if (moby->anim_flags & 2) { + rate = frame_scale; + if (moby->prev_seq != 6) { ANIM_2bffa8(6,0); rate = frame_scale; } + } + vars->move_speed = rate * 0.0273f * speed; + } + if (distance < 8.0f || !(20.0f < distance)) { + moby->state = 4; if (moby->prev_seq != 7) ANIM_2bffa8(7,10); + limit = 0.1f; rate = frame_scale; + } else { + moby->state = 5; if (moby->prev_seq != 0) ANIM_2bffa8(0,10); + limit = 0.0273f; rate = frame_scale; + } + vars->move_speed = rate * limit * speed; + if (!FUN_00213260_2bffa8(4)) vars->angle = FUN_L00_002bf050(moby,pos,&vars->target->pos,&result,moby->rot.z,1.847995638847351f,4.0f,0.35f,4.0f,convert_integer_to_float(HI_2bffa8(0x1ec0))*0.0009765625f); + else result.f[0] = 5.0f; + } + if (moby->state == 4 && state == 5) { + moby->state = 12; if (moby->prev_seq != 1) ANIM_2bffa8(1,10); break; + } + vars->target_pos.f[1] = moby->pos.y + fast_sin(vars->angle) * 5.0f; + vars->target_pos.f[0] = moby->pos.x + fast_cos(vars->angle) * 5.0f; + vars->target_pos.f[2] = moby->pos.z + 1.0f; + FUN_L00_002beb90(vars); + FUN_L00_00258278_2bffa8(moby,&vars->speed,vars->angle,HF_2bffa8(0x1efc),HF_2bffa8(0x1f00),HF_2bffa8(0x1f04)); + fast_vec_scale(&delta,&vars->velocity,5.0f); delta.i[2] = 0; + qcopy(&start,pos); start.f[2] += size * 0.15f; + fast_vec_add(&end,&start,&delta); + hit = FUN_001efa68_002c82f0(&start,&end,6,moby,0); + target = (struct Moby *)collision_hit_2bffa8.moby; + if (!hit || target == vars->target || (target && target->pclass && target->pclass->type == 5)) { + old_z = moby->pos.z; + flags = FUN_L00_00259028(moby,(u8 *)&hero+0x1ec0,vars,&vars->velocity); + if (1.0f < absolute_float(moby->pos.z-old_z)) { + moby->pos.z = old_z; + if (FUN_L00_002beab0(moby,5,0)) { + qcopy(pos,(u8 *)&collision_hit_2bffa8+0x30); + if (1.0f < absolute_float(moby->pos.z-old_z)) moby->pos.z = old_z; + } + } + } else { + result.f[0] = 0.0f; flags = 2; + vars->velocity.f[0] = moby->pos.x-vars->target_pos.f[0]; + vars->velocity.f[2] = 0.01f; + vars->velocity.f[1] = moby->pos.y-vars->target_pos.f[1]; + fast_vec_normalize(&vars->velocity,&vars->velocity,0.1f); + } + FUN_L00_002bebc8(vars); + if ((flags & 2) || result.f[0] < 4.0f) { + if (!FUN_L00_002bf9f0(moby,vars,vars,0)) { + if (vars->target) { vars->previous_target = vars->target; vars->timer = (s32)((u32)vars->timer + 500); } + vars->velocity.f[0] = moby->pos.x-vars->target_pos.f[0]; + vars->velocity.f[2] = 0.01f; + vars->velocity.f[1] = moby->pos.y-vars->target_pos.f[1]; + fast_vec_normalize(&vars->velocity,&vars->velocity,0.1f); + moby->state = 8; if (moby->prev_seq != 5) ANIM_2bffa8(5,5); goto finish; + } + vars->move_speed = frame_scale * 0.066f * speed; + if (moby->prev_seq != 0) ANIM_2bffa8(0,2); + moby->state = 6; + } + break; + case 6: + angle = atan2_f(vars->target_pos.f[0]-moby->pos.x,vars->target_pos.f[1]-moby->pos.y); + FUN_L00_002beb90(vars); + FUN_L00_00258278_2bffa8(moby,(u8 *)&hero+0x1ec0+0x14,angle,HF_2bffa8(0x1efc)+HF_2bffa8(0x1efc),HF_2bffa8(0x1f00)*0.5f,HF_2bffa8(0x1f04)+HF_2bffa8(0x1f04)); + FUN_L00_002bebc8(vars); + if (fast_difference_between_rotations(moby->rot.z,angle) < 0.08726646f) { state = HB_2bffa8(0x1f3c); ANIM_2bffa8(state,3); moby->state = 7; } + break; + case 7: + old_z = moby->pos.z; FUN_L00_002bec00(vars); + if (FUN_L00_0025b440(moby,(u8 *)&hero+0x1f10) == 4) { + moby->state = 4; if (moby->prev_seq != 7) ANIM_2bffa8(7,3); + vars->move_speed = frame_scale * 0.1f * speed; + } + FUN_L00_002bec48(vars); absolute_float(moby->pos.z-old_z); break; + case 11: + if (!OUTSIDE_2bffa8) { + qcopy(&start,pos); end.q = 0; end.f[2] = end.f[3] = 1.0f; + FUN_L00_0025e450_2bffa8(moby,&end,pos,5,2,4,-1,1,5,-1,item_text_variant[20],0.0f,0.0f,speed+speed,speed,9.0f,1.0f,15.0f); + start.f[2] += size * 0.5f; + /* The unused prepared start vector is present in retail. */ + hit = collect_mobies_in_sphere_2bffa8(speed,pos,21,moby,0); + /* The query returns its integer result in v0. */ + qcopy(&delta,pos); + FUN_L00_0025a9f8_2bffa8(moby,&delta,D_L00_00177F00,hit,0,0x10000,2,3,3.0f,1.0f,1.0f); + FUN_0028dbe8_2c4380(item_text_variant[20] ? 4 : 0,0,moby); + } +destroy: + FUN_L00_0024eb68_2c4380(moby); + return; + case 12: + if (moby->anim_flags & 2) { + moby->state = 4; if (moby->prev_seq != 7) ANIM_2bffa8(7,10); + vars->move_speed = frame_scale * 0.1f * speed; + } + goto finish; + case 13: + FUN_001e93b0_2bffa8(D_L00_001E9B70); goto finish; + case 14: + fast_vec_add(&start,pos,&vars->velocity); + if (coll_sphere(size*0.5f,pos,1,moby)) { + target = (struct Moby *)collision_hit_2bffa8.moby; + if (target && target->oclass == 0xba) { + fast_vec_sub(&start,(u8 *)&collision_hit_2bffa8+0x30,pos); + distance = fast_vec_length(&start); start.i[2] = 0; + fast_vec_normalize(&start,&start,distance*1.1f); + fast_vec_add(pos,pos,&start); rate = frame_time_sq; + } + } + rate = frame_time_sq; + vars->velocity.f[2] -= rate * 9.0f; + FUN_L00_002beb90(vars); + flags = FUN_L00_00258ad0_2bffa8(moby,&vars->velocity,HI_2bffa8(0x1ec0),0,size*0.7f,HF_2bffa8(0x1ef0)); + if (flags & 2) { vars->velocity.f[2] = 0.0f; fast_vec_scale(&vars->velocity,&vars->velocity,0.5f); } + FUN_001f9c90_2bffa8(&vars->velocity,&vars->velocity,frame_scale*0.05f); + if (flags & 2) moby->state = 2; + else { +falling_anim: + if (moby->prev_seq != 5) ANIM_2bffa8(5,5); + } +turn: + angle = atan2_f(vars->velocity.f[0],vars->velocity.f[1]); + FUN_L00_00258278_2bffa8(moby,&vars->turn_velocity,angle,HF_2bffa8(0x1edc),HF_2bffa8(0x1ee0),HF_2bffa8(0x1ee4)); + FUN_L00_002bebc8(vars); break; + default: +reset: moby->state = 0; goto finish; + } + moby->state = FUN_L00_002bfec8(moby); +finish: + if (OUTSIDE_2bffa8) FUN_L00_0024eb68_2c4380(moby); + return; +} +#undef HF_2bffa8 +#undef HI_2bffa8 +#undef HB_2bffa8 +#undef ANIM_2bffa8 +#undef OUTSIDE_2bffa8 +#endif extern const float D_L00_00161828_2c1778 __asm__("D_L00_00161828") __attribute__((sda)); extern float D_L00_00161830_2c1778 __asm__("D_L00_00161830") __attribute__((sda)); extern float D_L00_00173E68_2c1778 __asm__("D_L00_00173E68") __attribute__((section(".data"))); From f45e14e8ff50fe1816243cf852d1ff69d87b7b20 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:31:14 +0000 Subject: [PATCH 015/251] decomp: improve FUN_L00_002c89e8 --- .../shared/gameplay/entities/002c8440.c | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/src/overlays/shared/gameplay/entities/002c8440.c b/src/overlays/shared/gameplay/entities/002c8440.c index 1f2a2b764..4a149ac13 100644 --- a/src/overlays/shared/gameplay/entities/002c8440.c +++ b/src/overlays/shared/gameplay/entities/002c8440.c @@ -155,7 +155,189 @@ s32 FUN_L00_002c8440(ThrowVars_2c8440 *v, struct Moby *m, s32 mode) /* a second return 0 block, as in retail */ return 0; } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L00_002c89e8.s", FUN_L00_002c89e8); +#else +extern u8 D_0013E534 __attribute__((section(".data"))); +extern int D_L00_0015FFE4; +extern f32 vector_length_xyz_2cb418(void *) __asm__("FUN_001f9af0"); +extern f32 FUN_001fa6c0(int); +extern void mark_moby_for_removal(void *) __asm__("FUN_0020c828"); +extern s32 tick_timer_2cb418(void *) __asm__("FUN_001f9770"); +extern void reflect_vector_2cb418(void *, void *, void *) __asm__("FUN_L00_001ff660"); +extern void FUN_L00_001ff290_2c89e8(void *, void *, void *) __asm__("FUN_L00_001ff290"); +extern s32 FUN_001f0d60_2c89e8(f32, void *, s32, void *) __asm__("FUN_L00_001f0d60"); +extern void FUN_L00_0026ed28(struct Moby *); +extern void FUN_L00_002c8078(struct Moby *); +extern void FUN_L00_002bfe08(struct Moby *, void *, void *); +extern void FUN_L00_00260400(struct Moby *, s32, void *, void *, void *, void *); +extern f32 probe_ground_height(void *, int, f32) __asm__("FUN_00213508"); + +/* Six checked switch entries: state 5 shares the default state reset. */ +void FUN_L00_002c89e8(struct Moby *m) +{ + Vec4 d, e, a, q; + ThrowVars_2c8440 *v; + struct Moby *p; + s32 count; + s32 timer; + + if (!m) return; + v = (ThrowVars_2c8440 *)m->pvars; + if (!v) return; + if (m->pos.x < 2.0f || 1021.0f < m->pos.x || + m->pos.y < 2.0f || 1021.0f < m->pos.y || + m->pos.z < 2.0f || 1021.0f < m->pos.z) goto remove; + if (hero.unk20A5 && m->state < 2) + m->flags |= 0x41; + else + m->flags &= 0xffbe; + if (v->holder->oclass == 0xe5 && v->unk46 == 0 && vector_length_xyz_2cb418(v) > 0.0f) { + if (!hero.ground_moby || !FUN_L00_002603d0_2c8440((int)hero.ground_moby)) + FUN_L00_002c8440(v, m, 1); + else if (!FUN_L00_002c8440(v, m, 0)) + FUN_L00_002c8440(v, m, 2); + } + switch (m->state) { + case 0: + m->state = 1; + *(s32 *)v->pad_34 = scale_game_frames_2c8440(4); + *(s32 *)((u8 *)v + 0x3c) = 0; + v->timer = 0; + break; + case 1: { + v->timer = 0; + { + f32 f = m->pclass->scale; + if (m->scale < f * 0.25f) + m->scale = m->scale + f * (frame_scale * 0.05f); + } + if (tick_countdown_2c8440((s32 *)v->pad_34)) { + *(s32 *)v->pad_34 = scale_game_frames_2c8440(4); + if (!hero.unk20A5) FUN_L00_0026ed28(m); + } + if (!hero.vehicle_mode && v->holder && (v->holder->state & 0xf0) != 0xf0 && + hero.items[0].moby && hero.items[0].moby->oclass == 0xe5) return; + goto remove; + } + case 2: { + f32 f, g, h; + f32 half = 0.5f; + f = FUN_001fa6c0(D_0013E534) + 1.0f; + { + f32 g = m->pclass->scale; + if (m->scale < g * half * f) + m->scale = m->scale + g * (frame_scale * 0.05f) * f; + } + if (tick_countdown_2c8440((s32 *)v->pad_34)) { + *(s32 *)v->pad_34 = scale_game_frames_2c8440(4); + FUN_L00_0026ed28(m); + g = D_0015ED70_2c8440; + } else { + g = D_0015ED70_2c8440; + } + v->vel.f[2] -= g * 9.0f; + add_vector_xyz_2c8440(&d, &m->pos, v); + FUN_L00_001ff290_2c89e8(&q, &m->pos, &hero.motion.platform_carry); + qcopy_nc(&e, &m->pos); + h = frame_scale * 0.15f * m->scale; + e.f[2] -= h / m->pclass->scale; + qcopy_nc(&a, &d); + a.f[2] -= h / m->pclass->scale; + qcopy_nc(&q, &d); + q.f[2] += f * 0.2f; + if (FUN_001f0d60_2c89e8(f * 0.3f, &q, 4, hero.moby)) { + qcopy_nc(&m->pos, (u8 *)&coll_hit_2c8440 + 0x30); + m->pos.z -= f * 0.2f; + } else { + if (!collision_line_2c8440(&e, &a, 0, hero.moby, 0)) { + qcopy_nc(&m->pos, &d); + return; + } + qcopy_nc(&m->pos, &coll_hit_2c8440.point); + m->pos.z += (frame_scale * 0.15f * m->scale) / m->pclass->scale; + } + h = 0.01f; + reflect_vector_2cb418(v, v, &coll_hit_normal_2c8440); + scale_vector_xyz_2c8440(v, v, half); + g = vector_length_xyz_2cb418(v); + if (g < frame_scale * h) goto settle; + if (hero.ground_moby) { + if (FUN_L00_002603d0_2c8440((int)hero.ground_moby)) { + g = vector_length_xyz_2cb418(v); + f = vector_length_xyz_2cb418(&hero.motion.displacement); + if (g < frame_scale * h + f) { +settle: + timer = (u16)v->timer + 1; + v->timer = timer; + if (!coll_hit_2c8440.moby || coll_hit_2c8440.unk1C > 0 || + scale_game_frames_2c8440(240) < (s16)timer) { + m->state = 3; + v->timer = 0; + } + } + } + if (hero.ground_moby && FUN_L00_002603d0_2c8440((int)hero.ground_moby)) + add_vector_xyz_2c8440(v, v, &hero.motion.displacement); + } + add_vector_xyz_2c8440(&m->pos, &m->pos, v); + FUN_L00_002c8078(m); + break; + } + case 3: { + f32 f; + f = probe_ground_height(&m->pos, 0, 0.5f); + if (f != 0.0f && coll_hit_2c8440.moby) + FUN_L00_00260400(m, coll_hit_2c8440.moby, &m->pos, &m->rot, &m->pos, &m->rot); + if (tick_timer_2cb418(&v->timer)) { + count = 0; + for (p = (struct Moby *)D_L00_0015FFE4; p; p = p->next) + if (p->oclass == 0xba && (p->state & 0xf0) != 0xf0) count++; + if (count >= 8) { + v->timer = scale_game_frames_2c8440(15); + goto spawn_done; + } + { + e.f[0] = FUN_001f9dc8_2c8440((f32)*(s32 *)((u8 *)v + 0x3c) * 6.2831855f * 0.25f); + e.f[0] = frame_scale * 0.05f * e.f[0]; + e.f[1] = FUN_001f9de0_2c8440((f32)*(s32 *)((u8 *)v + 0x3c) * 6.2831855f * 0.25f); + e.f[2] = frame_scale * 0.02f; + e.f[1] = frame_scale * 0.05f * e.f[1]; + if (hero.ground_moby && FUN_L00_002603d0_2c8440((int)hero.ground_moby)) + add_vector_xyz_2c8440(&e, &e, &hero.motion.displacement); + add_vector_xyz_2c8440(&d, &e, &m->pos); + FUN_L00_002bfe08(v->holder, &d, &e); + v->timer = scale_game_frames_2c8440(8); + count = *(s32 *)((u8 *)v + 0x3c) + 1; + *(s32 *)((u8 *)v + 0x3c) = count; + if (count > 3) m->state = 4; + } + } +spawn_done: + if (*(s32 *)((u8 *)v + 0x3c) < 2 && tick_countdown_2c8440((s32 *)v->pad_34)) { + *(s32 *)v->pad_34 = scale_game_frames_2c8440(4); + FUN_L00_0026ed28(m); + } + break; + } + case 4: { + f32 f; + m->alpha -= 4; + m->scale *= 0.92f; + f = probe_ground_height(&m->pos, 0, 0.5f); + if (f != 0.0f && coll_hit_2c8440.moby) + FUN_L00_00260400(m, coll_hit_2c8440.moby, &m->pos, &m->rot, &m->pos, &m->rot); + if (m->alpha) return; +remove: + mark_moby_for_removal(m); + break; + } + case 5: + default: + m->state = 0; + } +} +#endif /* 0x002c92d8, 112 bytes. * Ported from rac1-decomp, where it is exact; names translated to * the US level program (data still reached through the MACRO_ADDR form). */ From 0989c391221a30a966f534fcef5a58ea4031835e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:30:50 +0000 Subject: [PATCH 016/251] decomp: improve FUN_L12_00303370 --- src/overlays/l12/gameplay/vendor/003028c8.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/overlays/l12/gameplay/vendor/003028c8.c b/src/overlays/l12/gameplay/vendor/003028c8.c index 8ec18f7f6..878e90ce7 100644 --- a/src/overlays/l12/gameplay/vendor/003028c8.c +++ b/src/overlays/l12/gameplay/vendor/003028c8.c @@ -409,6 +409,8 @@ void FUN_L12_00303370(void *moby) { float yaw_limit; float pitch_limit; float yaw; + float x; + float y; float distance; float pitch; @@ -423,8 +425,9 @@ void FUN_L12_00303370(void *moby) { pitch_limit = 0.05235988f; position[2] += 1.5f; } - yaw = FUN_001f9e90(position[0] - L12_VENDOR_REFERENCE->position[0], - position[1] - L12_VENDOR_REFERENCE->position[1]); + y = position[1] - L12_VENDOR_REFERENCE->position[1]; + x = position[0] - L12_VENDOR_REFERENCE->position[0]; + yaw = FUN_001f9e90(x, y); distance = FUN_001f9b80(L12_VENDOR_REFERENCE->position, position); pitch = FUN_001f9e90(distance, position[2] - L12_VENDOR_REFERENCE->position[2]); if (fast_difference_between_rotations(yaw, L12_VENDOR_REFERENCE->yaw) < yaw_limit && From 093179772ff2ba4fdb0148d2e598c389e39e2a42 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:36:41 +0000 Subject: [PATCH 017/251] decomp: improve FUN_L00_00261b48 --- src/overlays/shared/gameplay/state/00261968.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/gameplay/state/00261968.c b/src/overlays/shared/gameplay/state/00261968.c index ddea60bca..442e7d429 100644 --- a/src/overlays/shared/gameplay/state/00261968.c +++ b/src/overlays/shared/gameplay/state/00261968.c @@ -91,6 +91,7 @@ s32 FUN_L00_00261b48(s32 path_index, OvlVec4 *start, OvlVec4 *end, OvlVec4 *out) OvlVec4 origin; OvlVec4 first; OvlVec4 next; + OvlVec4 *previous; OvlVec4 *current; SegmentPath_261b48 **entry; s32 i; @@ -110,15 +111,17 @@ s32 FUN_L00_00261b48(s32 path_index, OvlVec4 *start, OvlVec4 *end, OvlVec4 *out) entry = &D_L00_001B04B0_261b48[path_index]; found = 0; i = 1; - FUN_001ff2a8_261b48(&first, &(*entry)->points[0], start); origin.f[2] = 1.0f; - FUN_001ff6d0_261b48(&first, &first, &direction); + current = &first; + FUN_001ff2a8_261b48(current, &(*entry)->points[0], start); + FUN_001ff6d0_261b48(current, current, &direction); + previous = current; current = &next; if (i < (*entry)->count) { offset = 0x20; do { FUN_001ff2a8_261b48(current, (OvlVec4 *)((u8 *)*entry + offset), start); - FUN_001ff6d0_261b48(current, &next, &direction); + FUN_001ff6d0_261b48(current, current, &direction); if (first.f[3] != 0.0f || current->f[3] != 0.0f) { if (current->f[1] * first.f[1] < 0.0f) { crossing = (first.f[0] - current->f[0]) / (first.f[1] - current->f[1]) * -current->f[1] + current->f[0]; @@ -128,7 +131,7 @@ s32 FUN_L00_00261b48(s32 path_index, OvlVec4 *start, OvlVec4 *end, OvlVec4 *out) } } } - first.q = ((volatile OvlVec4 *)current)->q; + previous->q = ((volatile OvlVec4 *)current)->q; i++; offset += 0x10; } while (i < (*entry)->count); From 9493201418afb85e66c230171fff99c5af383aec Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:37:30 +0000 Subject: [PATCH 018/251] decomp: improve FUN_L12_002e72c0 --- src/overlays/l12/gameplay/entities/002bf140.c | 317 ++++++++++++++++++ 1 file changed, 317 insertions(+) diff --git a/src/overlays/l12/gameplay/entities/002bf140.c b/src/overlays/l12/gameplay/entities/002bf140.c index 2a14f07db..0e1838c70 100644 --- a/src/overlays/l12/gameplay/entities/002bf140.c +++ b/src/overlays/l12/gameplay/entities/002bf140.c @@ -1724,7 +1724,324 @@ extern void FUN_L00_0025f3e8(void *, void *, int, float, float); void FUN_L12_002e7290(void *a, void *b) { FUN_L00_0025f3e8(a, b, -1, 1.0f, 10.0f); } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L12_002e72c0.s", FUN_L12_002e72c0); +#else +extern void FUN_L12_002e81e0(struct Moby *); +extern void FUN_L12_002e8608(struct Moby *, float *); +extern void FUN_L12_002e86d0(struct Moby *); +extern void FUN_L12_002e8720(struct Moby *); +extern void FUN_L12_002e87b0(char *); +extern void FUN_L12_002e8808(struct Moby *, float *, float, float); +extern s32 D_001413D0_e81e0 __asm__("D_001413D0") __attribute__((section(".data"))); +extern s32 scale_game_frames_e81e0(s32) __asm__("FUN_001f96f8"); +extern f32 fast_cos_e81e0(f32) __asm__("FUN_001f9dc8"); +extern f32 fast_sin_e81e0(f32) __asm__("FUN_001f9de0"); +extern void call_for_help_e81e0(struct Moby *, s32, s32, Vec4f *, f32 *, f32) __asm__("FUN_L00_00259bc8"); +extern void mark_moby_for_removal(void *) __asm__("FUN_0020c828"); +extern void moby_point_position(void *, int, void *) __asm__("FUN_L00_0024f7c8"); +extern int random_integer_below_e81e0(s32) __asm__("FUN_00213260"); +extern float angle_difference_8808(float, float) __asm__("FUN_001fa688"); +extern float fast_add_rotations_e81e0(float, float) __asm__("FUN_001fa580"); +extern float probe_ground_height(void *, int, float) __asm__("FUN_00213508"); +extern void subtract_8808(void *, void *, void *) __asm__("FUN_001f9a28"); +extern void allocate_voice_for_target_entry(int, int, int) __asm__("FUN_0022da68"); +extern void FUN_L00_00257470(struct Moby *, int, int); +extern Vec4 D_L12_0015F580; +extern struct Moby *D_L12_00178380[]; +extern int coll_line_fix_72(void *, void *, int, void *, int) __asm__("FUN_001efa68"); +extern int query_mobys_72(void *, int, void *, int, float) __asm__("FUN_L00_001f2868"); +extern int FUN_L00_0025e3b8(void *); +extern float FUN_L00_00257c48(float, float); +extern void blend_moby_animation_ex(void *, int, int, int, int) __asm__("FUN_002130d8"); +extern int FUN_L01_0028b510(void *, void *, float); +extern int FUN_L12_0027b8e0(void *, void *, float, float, float); +extern float vector_project_72(void *, float) __asm__("FUN_001f9b20"); +extern void FUN_L04_002aee30(void *, void *, void *, int); + +#define OGRE_I(offset) (*(int *)(data + (offset))) +#define OGRE_F(offset) (*(float *)(data + (offset))) +#define OGRE_B(offset) (*(u8 *)(data + (offset))) +#define OGRE_H(offset) (*(u16 *)(data + (offset))) +#define OGRE_CHILD (*(struct Moby **)(data + 0x248)) + +/* Ogre update: initialization, path following, aiming, attack and removal. + The retail unsigned group sentinel is 0xff; unordered angle comparisons + keep the original branch outcomes. Quad copies include the fourth word. */ +void FUN_L12_002e72c0(struct Moby *moby) { + TargetReport54_2E2EF0 work; + Vec4 v; + Vec4 delta; + char *data = (char *)moby->pvars; + struct Moby *target; + + func_L00_00264BB0_2E2EF0(data + 0x120, 3.0f); + if (D_L12_0015F5C4_c == 2) goto hide; + if (moby->state >= 3) { + moby->flags &= 0xffbe; + if (OGRE_CHILD) OGRE_CHILD->flags &= 0xffbe; + } + if (OGRE_B(0x269) && hero.state.current == 0 && hero.state.prev == 0x67) { + if (FUN_001f9b80(&moby->pos, &hero.motion.pos) < 30.0f) goto leave; + } + if (OGRE_I(0x270) != -1) { + if (!is_point_inside_clip_volume(D_L12_00167240, OGRE_I(0x270))) { +hide: + moby->flags |= 0x41; + if (OGRE_CHILD) OGRE_CHILD->flags |= 0x41; + return; + } + moby->flags &= 0xffbe; + if (OGRE_CHILD) OGRE_CHILD->flags &= 0xffbe; + } + if (OGRE_B(0x2e) == 2) goto leave; + FUN_L12_002e81e0(moby); + select54((char *)moby, (char *)&work, OGRE_F(0x230)); + target = (struct Moby *)work.moby; + if (!target) { + target = hero.moby; + qcopy(work.v20, hero.motion.unkD0.f); + } + switch (moby->state) { + case 0: { + float value; + float other = OGRE_F(0x230); + OGRE_F(0x20) = 2.0f; + OGRE_H(0x24) = 2; + OGRE_B(0x29) = 1; + OGRE_B(0x2e) = 1; + OGRE_B(0x58) = 8; + OGRE_B(0x5a) = 8; + OGRE_F(0x28c) = other; + OGRE_I(0x90) = 0x200; + OGRE_F(0x98) = 0.5f; + func_L01_0026E8E0_2E2EF0(data + 0xd0); + value = D_0015ED6C * 5.5f; + OGRE_I(0xd0) = 0x38d; + *(volatile float *)(data + 0xd8) = 1.0f; + OGRE_I(0x108) = 0x18; + *(volatile float *)(data + 0xf4) = value; + *(volatile float *)(data + 0xdc) = 1.0f; + qcopy(data + 0x220, &moby->pos); + if (moby->group != 0xff) { + if (**(int **)(data + 0x24c) == 1) moby->flags |= 0x8000; + **(int **)(data + 0x24c) = (**(int **)(data + 0x24c) == 0); + } else if (func_001160D8_2E2EF0() & 1) { + moby->flags |= 0x8000; + } + if (OGRE_I(0x274)) OGRE_I(0x288) = scale_game_frames_e81e0(FUN_L00_00257b90(0, 300)); + moby->rot.x = 0.0f; + moby->rot.y = 0.0f; + if (OGRE_F(0x244) == moby->rot.x) { + if (moby->group != 0xff) { + int *path = *(int **)(data + 0x250); + int count; + OGRE_F(0x244) = (float)*path; + count = *path; + if (count > 0) *path = -count; + else *path = count + 20; + } else OGRE_F(0x244) = FUN_L00_00257c48(15.0f, 35.0f); + } + OGRE_F(0x244) *= 0.017453292f; + moby->pos.z = probe_ground_height(&moby->pos, 0, 0.5f); + if (OGRE_B(0x268)) { + moby->flags |= 0x41; + if (OGRE_CHILD) OGRE_CHILD->flags |= 0x41; + } + moby->state = 2; + break; + } + case 2: { + if (distance_xyz(&moby->pos, &hero.motion.pos) > 64.0f) return; + if (moby->prev_seq != 0 && moby->seq == moby->prev_seq) + blend_moby_animation_ex(moby, 0, 0, scale_game_frames_e81e0(8), 5); + if (!FUN_L12_0027b8e0(moby, &target->pos, OGRE_F(0x230), 3.0f, 0.0f)) { + if ((OGRE_I(0x25c) == -1 || !is_point_inside_clip_volume(&target->pos, OGRE_I(0x25c))) && moby->command == 0) break; + } + if (moby->flags & 1) { + qcopy(v.f, &moby->pos); + v.f[2] += 0.5f; + if (coll_line_fix_72(&v, D_L12_00167240, 2, moby, 0)) { + moby->flags &= 0xffbe; + if (OGRE_CHILD) OGRE_CHILD->flags &= 0xffbe; + } else { + if (OGRE_CHILD) mark_moby_for_removal(OGRE_CHILD); + mark_moby_for_removal(moby); + return; + } + } + if (moby->group != 0xff) FUN_L01_0026e090(moby->group, 1); + if (OGRE_I(0x254) == -1) goto state3; + else { + OGRE_I(0x260) = FUN_L01_0028b510(&moby->pos, D_L12_001B0930_w[OGRE_I(0x254)], 0.0f); + moby->state = 1; + } + break; + } + case 1: { + int *path; + if (!tick_countdown_32_alt_c2((int *)(data + 0x258))) break; + if (moby->prev_seq != 8 && moby->seq == moby->prev_seq) + blend_moby_animation_ex(moby, 8, 0, scale_game_frames_e81e0(11), 5); + path = (int *)D_L12_001B0930_w[OGRE_I(0x254)]; + if (FUN_001f9b80(&moby->pos, path + (OGRE_I(0x260) * 4 + 4)) < 3.0f) ++OGRE_I(0x260); + if (*path - 1 < OGRE_I(0x260)) OGRE_I(0x260) = *path - 1; + FUN_L12_002e8808(moby, (float *)(path + (OGRE_I(0x260) * 4 + 4)), 0.0f, D_0015ED6C * 8.0f); + if (OGRE_I(0x260) == *path - 1) goto state3; + else if (FUN_001f9b80(&moby->pos, &target->pos) < OGRE_F(0x264)) moby->state = 3; + break; + } + case 3: { + float angle; + if (OGRE_B(0x268) == 1) { + int hit; + qcopy(v.f, &moby->pos); + v.f[0] += fast_cos_e81e0(moby->rot.z); + v.f[1] += fast_sin_e81e0(moby->rot.z); + hit = query_mobys_72(&v, 0, moby, 0, 1.5f); + if (hit) { + qcopy(delta.f, D_L12_0015F580.f); + if (hit > 0) { + struct Moby **iterator = D_L12_00178380; + int count = hit; + do { + if (FUN_L00_0025e3b8(*iterator) && func_001F9B88_2E2EF0(moby->pos.z - (*iterator)->pos.z) < 0.7f) + call_for_help_e81e0(*iterator, (int)hero.moby, 0x10000, &moby->pos, delta.f, 1.0f); + --count; + ++iterator; + } while (count != 0); + } + } + } + angle = func_001FA790_2E2EF0(FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y), moby->rot.z); + if (angle > 0.9599311f) angle = 0.9599311f; + else if (angle < -0.9599311f) angle = -0.9599311f; + OGRE_F(0x188) = angle * 0.5f; + OGRE_F(0x208) = angle * 0.5f; + FUN_L12_002e8808(moby, (float *)&target->pos, OGRE_F(0x244), 0.0f); + if (FUN_001f9b80(&moby->pos, &target->pos) < 5.5f || OGRE_B(0x242)) { + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + if (angle_difference_8808(moby->rot.z, angle) < 0.08726646f) goto state5; + } + if (moby->prev_seq != 8 && moby->seq == moby->prev_seq) + blend_moby_animation_ex(moby, 8, 0, scale_game_frames_e81e0(11), 5); + break; + } + case 5: { + if (OGRE_F(0x28c) < 8.0f) OGRE_F(0x28c) = 8.0f; + FUN_L12_002e8608(moby, (float *)&target->pos); + FUN_L12_002e87b0((char *)moby); + if (moby->prev_seq != 2 && moby->seq == moby->prev_seq) + blend_moby_animation_ex(moby, 2, 0, scale_game_frames_e81e0(8), 5); + if (moby->anim_flags & 2) { + if (moby->prev_seq != 10 && moby->seq == moby->prev_seq) + blend_moby_animation_ex(moby, 10, 0, scale_game_frames_e81e0(5), 5); + moby->state = 6; + } + break; + } + case 6: { + int count; float angle; float other; float value; + FUN_L12_002e8608(moby, (float *)&target->pos); + FUN_L12_002e87b0((char *)moby); + if (OGRE_CHILD && is_value_within_interpolated_window(moby, 0.0f)) { + moby_point_position(OGRE_CHILD, 0, &v); + subtract_8808(&delta, work.v20, &v); + angle = FUN_001f9e90(delta.f[0], delta.f[1]); + other = fast_add_rotations_e81e0(moby->rot.z, OGRE_F(0x208)); + angle = 0.2268928f < angle_difference_8808(angle, other) ? other : angle; + value = vector_project_72(&delta, angle); + value = FUN_001f9e90(value, delta.f[2]); + build_spherical_offset(&delta, D_0015ED6C * 15.0f, angle, value); + allocate_voice_for_target_entry(0, 0, (int)moby); + count = truncate_float_to_s32(18.0f / (D_0015ED6C * 15.0f)); + FUN_L04_002aee30(moby, &v, &delta, count); + } + if (moby->anim_flags & 2) { + if (moby->prev_seq != 5 && moby->seq == moby->prev_seq) + blend_moby_animation_ex(moby, 5, 0, scale_game_frames_e81e0(8), 5); + moby->state = 7; + } + break; + } + case 7: { + float angle; + FUN_L12_002e8608(moby, (float *)&target->pos); + FUN_L12_002e87b0((char *)moby); + if ((moby->prev_seq != 5 || (moby->anim_flags & 2)) && moby->prev_seq != 0 && moby->seq == moby->prev_seq) + blend_moby_animation_ex(moby, 0, 0, scale_game_frames_e81e0(8), 5); + if (!random_integer_below_e81e0(9)) goto state5; + if (FUN_001f9b80(&moby->pos, &target->pos) > 10.5f && !OGRE_B(0x242)) goto state3; + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + if (angle_difference_8808(moby->rot.z, angle) > 0.4886922f) moby->state = 3; + break; + } + case 8: { + float angle; + FUN_L12_002e8808(moby, (float *)(data + 0x220), 0.0f, 0.0f); + angle = OGRE_F(0x23c) * 30.0f; + if (angle > 0.7853982f) angle = 0.7853982f; + else if (angle < -0.7853982f) angle = -0.7853982f; + OGRE_F(0x188) = angle * 0.7f; + OGRE_F(0x208) = angle * 0.4f; + if (FUN_001f9b80(&moby->pos, data + 0x220) < 1.0f) moby->state = 2; + break; + } + case 4: { + float angle; + moby->flags &= 0xffbe; + if (FUN_L00_0025c698(moby, data + 0x70) & 0x60) { + if (FUN_001f9b80(&moby->pos, &target->pos) < 6.0f || OGRE_B(0x242)) { + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + if (angle_difference_8808(moby->rot.z, angle) < 0.12217305f) { +state5: + moby->state = 5; + break; + } + } +state3: + moby->state = 3; + break; + } + if (!(moby->pos.z < 2.0f)) goto finish; + goto leave; + } + case 9: { + if (FUN_L00_0025c698(moby, data + 0x70) & 0x60) { + FUN_L00_00257470(moby, 0, -1); + FUN_L12_002e7290(moby, &moby->pos); + goto leave; + } + if (moby->pos.z < 2.0f) { + FUN_L00_00257470(moby, 0, -1); +leave: + FUN_L12_002e86d0(moby); + return; + } + break; + } + } +finish: + if (moby->visible || (OGRE_CHILD && OGRE_CHILD->visible)) { + float value; + FUN_L12_002e8720(moby); + value = frame_scale_sq; + if (moby->flags & 0x8000) { + OGRE_F(0x188) = -OGRE_F(0x188); + OGRE_F(0x208) = -OGRE_F(0x208); + value = D_0015ED64; + } + FUN_L00_002628d8(value * 0.018f, value * 0.3f, moby, data + 0x120, 5); + FUN_L00_002628d8(D_0015ED64 * 0.024f, D_0015ED64 * 0.3f, moby, data + 0x1a0, 6); + } + return; +} +#undef OGRE_I +#undef OGRE_F +#undef OGRE_B +#undef OGRE_H +#undef OGRE_CHILD +#endif /* Variables of the l12 ogre moby (moby->pvars): FUN_L00_002e1678's TrollVars layout, with the alert and call-for-help state at 0x230.. */ typedef struct { From 584b83109f0c3c8301cf72702ca035a6fd715a36 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:35:59 +0000 Subject: [PATCH 019/251] decomp: improve FUN_L07_0030f5f0 --- src/overlays/l07/gameplay/entities/002cd2b0.c | 325 ++++++++++++++++++ 1 file changed, 325 insertions(+) diff --git a/src/overlays/l07/gameplay/entities/002cd2b0.c b/src/overlays/l07/gameplay/entities/002cd2b0.c index a7f0c846f..0f8393342 100644 --- a/src/overlays/l07/gameplay/entities/002cd2b0.c +++ b/src/overlays/l07/gameplay/entities/002cd2b0.c @@ -2463,7 +2463,332 @@ int FUN_L07_0030f540(unsigned char *moby, int lower, int upper) { found: return 1; } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L07_0030f5f0.s", FUN_L07_0030f5f0); +#else +extern void FUN_L00_0025e450_l07(f32, f32, f32, f32, f32, f32, f32, struct Moby *, void *, s32, s32, s32, s32, s32, s32, s32, s32, s32) __asm__("FUN_L00_0025e450"); +extern void FUN_L00_00263ac8(void *, int, void *, float); +extern int FUN_L07_002886d8(void *, void *, float); +extern int FUN_001f0b58(void); +extern int FUN_00213260(int); +extern float FUN_002135f0(void *, int); +extern void FUN_L00_002715e8(void *, int, int, float, float); +extern void FUN_L00_00258278(void *, void *, float, float, float, float); +extern float FUN_L00_00258110(void *, float, float, float, float, float); +extern void FUN_001e93e8(void *, void *); +extern int FUN_L00_0025c698(void *, void *); +extern unsigned char D_L07_00161B40[] __attribute__((section(".sdata"))); +extern unsigned char D_L07_00161B50[] __attribute__((section(".sdata"))); +extern char D_L07_002117F8[]; +extern char D_L07_00211838[]; +extern char D_0013F3D0[]; +extern int D_001413D0 __attribute__((section(".data"))); +extern short D_0013F65C __attribute__((section(".data"))); +extern int D_001415F8 __attribute__((section(".data"))); +extern unsigned char D_001413F5 __attribute__((section(".data"))); +extern int D_L07_001612D8; +extern char D_L07_00173EE0_30f5f0[] __asm__("D_L07_00173EE0"); + +void FUN_L07_0030f5f0(unsigned char *moby) { + char *data; + float target[18] __attribute__((aligned(16))); + float point[4] __attribute__((aligned(16))); + float offset[4] __attribute__((aligned(16))); + float goal[4] __attribute__((aligned(16))); + float delta[4] __attribute__((aligned(16))); + float previous[4] __attribute__((aligned(16))); + char *path; + int wander, inside, id, old_command, command; + unsigned char next_state, next_sequence; + float height, distance, angle, scale; + if (!moby) return; + data = *(char **)(moby + 0x78); + if (!data) return; + FUN_L00_00263ac8(moby, 0, data + 0x150, 2.2f); + if (moby[0x20] == 0) { + if (FUN_L07_0030ed30(moby, data)) { + stub_printf(D_L07_002117F8, ((char *)moby - D_L07_0015FFD8_30ed30) >> 8); + goto remove; + } + goto bounds; + } + FUN_L07_002886d8(moby, target, 30.0f); + FUN_L07_0030e998(moby, data, (float *)(data + 0x20)); + FUN_L00_0025d538(moby, data + 0x60); + wander = FUN_001f9740((int *)(data + 0x134)) != 0; + path = *(char **)(data + 0x148); + if (*(int *)(data + 0x110) == 0 || moby[0x20] < 7) { + inside = point_in_path_xy(D_0013F3D0, path + 0x10, *(int *)path) != 0; + if (FUN_001f9b80(moby + 0x10, D_0013F3D0) < 30.0f) { + *(int *)(target + 16) = D_001413D0; + qcopy(target, D_0013F3D0); + qcopy(target + 4, D_0013F3D0 + 0x10); + qcopy(target + 8, D_0013F3D0 + 0x40); + qcopy(target + 12, D_0013F3D0 + 0x50); + *(int *)(target + 17) = 0; + } else { + *(int *)(target + 16) = 0; + *(u128 *)target = 0; + *(u128 *)(target + 4) = 0; + *(u128 *)(target + 12) = 0; + *(u128 *)(target + 8) = 0; + *(int *)(target + 17) = 2; + } + } else inside = point_in_path_xy(target, path + 0x10, *(int *)path) != 0; + if (*(int *)(data + 0x110)) { + path = *(char **)(data + 0x128); + point_in_path_xy(moby + 0x10, path + 0x10, *(int *)path); + } + next_state = 0xff; + old_command = moby[0xbc]; + command = (unsigned char)FUN_L07_0030ebc8(moby, data); + next_sequence = 0xff; + moby[0xbc] = command; + if (old_command != command) { + id = command + old_command * 3; + next_sequence = D_L07_00161B50[id]; + next_state = D_L07_00161B40[id]; + } + moby_point_position(moby, 0, point); + if (FUN_L00_001f0d60(0.8f, point, 1, moby) && !FUN_001f0b58()) { + height = (**(float **)(data + 0x12c) - F(data, 0x130)) * 0.5f; + if (height < FUN_001f99c0(F(moby, 0x18) - point[2])) + height = (**(float **)(data + 0x12c) - F(data, 0x130)) * 0.5f; + else height = FUN_001f99c0(F(moby, 0x18) - point[2]); + if (F(data, 0xd8) < 0.0f) height = -height; + if (moby[0x20] == 14 || moby[0x20] == 12) height += height; + if (0.5f < FUN_001f9b80(moby + 0x10, D_L07_00173EE0_30f5f0)) { + distance = FUN_001f9b80(moby + 0x10, D_L07_00173EE0_30f5f0); + distance += distance; + } else distance = 1.0f; + if (D_L07_0015F5CC % 45 == *(short *)(moby + 0xb2) && !FUN_00213260(2)) + func_L00_002A5158_30D8E8(D_L07_001612D0, D_L07_001612D8, 1, F(moby, 0x10), F(moby, 0x14), distance, height); + id = (rand_e50() & 7) + 20; + if (D_L07_0015F5CC % id == 0) { + scale = random_float_between(1.5f, 2.4f); + point[0] += random_float_between(-0.15f, 0.15f); + point[1] += random_float_between(-0.15f, 0.15f); + point[2] = FUN_002135f0(D_L07_00173EE0_30f5f0, 0); + FUN_L00_002715e8(point, 0, -1, scale, 5250.0f); + } + } + if (1.0f <= F(data, 0x14c)) *(u128 *)D_0013F3D0 = *(u128 *)(moby + 0x10); + switch (moby[0x20]) { + case 0: + stub_printf(D_L07_00211838, 0); + goto bounds; + case 1: + if ((moby[0x70] & 2) && moby[0x53] != 0) blend_moby_animation(moby, 0, 0, 10); + if (inside && *(int *)(target + 16)) { + if (*(int *)(target + 16) == D_001413D0 && !FUN_L07_0030f540(moby, 4, 6)) { + if (moby[0x53] != 1) blend_moby_animation(moby, 1, 0, 10); + moby[0x20] = 4; + } + } else if (inside) goto wander_one; + if (*(int *)(target + 16) && *(int *)(target + 16) == D_001413D0 && FUN_L07_0030f4d0(moby, *(int *)(target + 16), 1.5f)) { + if (moby[0x53] != 2) blend_moby_animation(moby, 2, 0, 2); + moby[0x20] = 5; + } else { + wander_one: + if (wander) { + if (moby[0x53] != 1) blend_moby_animation(moby, 1, 0, 10); + *(int *)(data + 0x134) = rand_e50() % 200 + 300; + F(data, 0x13c) = random_angle_radians(); + moby[0x20] = 2; + } + } + FUN_001f9a68(data + 0xd0, data + 0xd0, frame_scale * -0.050000012f + 1.0f); + FUN_L07_0030f0f8(moby, data, frame_time_sq * 15.0f, frame_time_sq * 50.0f, frame_time * 8.0f); + break; + case 2: + if ((moby[0x70] & 2) && moby[0x53] != 1) blend_moby_animation(moby, 1, 0, 10); + if (inside && *(int *)(target + 16) && *(int *)(target + 16) == D_001413D0) { + if (!FUN_L07_0030f540(moby, 4, 6)) { + if (moby[0x53] != 1) blend_moby_animation(moby, 1, 0, 10); + moby[0x20] = 4; + } + } else { + FUN_L00_00258278(moby, data + 0x120, F(data, 0x13c), frame_time_sq * 1.7453293f, frame_time_sq * 4.537856f, frame_time * 1.7453293f); + F(moby, 0x44) = FUN_L00_00258110(data + 0x124, F(moby, 0x44), 0.0f, frame_time_sq * 1.7453293f, frame_time_sq * 4.537856f, frame_time * 1.7453293f); + if (wander && is_point_inside_clip_volume(moby + 0x10, *(int *)(data + 0x114))) { + if (moby[0x53] != 0) blend_moby_animation(moby, 0, 0, 10); + *(int *)(data + 0x134) = rand_e50() % 120 + 60; + moby[0x20] = 1; + } + } + FUN_L07_0030eee8(moby, data); + if (FUN_L07_0030f1e0(moby, data, F(data, 0x13c), 0.20943952f, frame_time_sq * 6.0f, 0.5235988f, frame_time_sq * 4.0f, frame_time * 7.0f, frame_time * 3.0f) && wander) { + if (moby[0x53] != 0) blend_moby_animation(moby, 0, 0, 10); + *(int *)(data + 0x134) = rand_e50() % 120 + 60; + moby[0x20] = 1; + } + if (*(int *)(target + 16) && *(int *)(target + 16) == D_001413D0 && FUN_L07_0030f4d0(moby, *(int *)(target + 16), 1.5f)) { + if (moby[0x53] != 2) blend_moby_animation(moby, 2, 0, 2); + moby[0x20] = 5; + } + FUN_L07_0030f0f8(moby, data, frame_time_sq * 15.0f, frame_time_sq * 50.0f, frame_time * 8.0f); + break; + case 4: + angle = FUN_001f9e90(target[0] - F(moby, 0x10), target[1] - F(moby, 0x14)); + FUN_L00_00258278(moby, data + 0x120, angle, frame_time_sq * 12.566371f, frame_time_sq * 0.0f, frame_time * 12.566371f); + distance = FUN_001f9b80(moby + 0x10, target); + height = FUN_001f9e90(distance, target[2] - F(moby, 0x18)); + F(moby, 0x44) = FUN_L00_00258110(data + 0x124, F(moby, 0x44), -height, frame_time_sq * 12.566371f, frame_time_sq * 0.0f, frame_time * 12.566371f); + wander = FUN_001f9b80(moby + 0x10, D_0013F3D0) < 3.0f; + if (wander) FUN_001f9a68(data + 0xd0, data + 0xd0, frame_scale * -0.100000024f + 1.0f); + if (FUN_L07_0030f1e0(moby, data, angle, 0.20943952f, frame_time_sq * 20.0f, 0.5235988f, frame_time_sq * 3.0f, frame_time * 20.0f, frame_time * 5.0f) && wander) { + if (moby[0x53] != 2) blend_moby_animation(moby, 2, 4, 2); + *(int *)(moby + 0x94) = 0; + moby[0x20] = 5; + F(data, 0x14c) = 0.0f; + qcopy(data + 0x100, moby + 0x10); + } + F(data, 0x138) = target[2] - 0.25f; + FUN_L07_0030f0f8(moby, data, frame_time_sq * 38.0f, frame_time_sq * 0.0f, frame_time * 38.0f); + if (!inside || D_0013F65C == 0) { + if (moby[0x53] != 1) blend_moby_animation(moby, 1, 0, 10); + moby[0x20] = 2; + } + break; + case 5: + moby_point_position(moby, 0, point); + subtract_vector_xyz(offset, point, moby + 0x10); + angle = FUN_001f9e90(target[0] - point[0], target[1] - point[1]); + FUN_L00_00258278(moby, data + 0x120, angle, frame_time_sq * 12.566371f, frame_time_sq * 0.0f, frame_time * 12.566371f); + F(moby, 0x44) *= frame_scale * 0.7f; + F(data, 0x14c) += 0.028f; + qcopy(previous, moby + 0x10); + subtract_vector_xyz(goal, target, offset); + subtract_vector_xyz(delta, goal, data + 0x100); + scale = 1.0f; + if (F(data, 0x14c) < scale) scale = F(data, 0x14c); + FUN_001f9a68(delta, delta, scale); + add_vector_xyz(moby + 0x10, delta, data + 0x100); + FUN_001e93e8(previous, moby + 0x10); + FUN_001e93e8(data + 0x100, moby + 0x10); + subtract_vector_xyz(data + 0xd0, moby + 0x10, previous); + if (1.0f <= F(data, 0x14c)) { + D_001415F8 = 0; + hero_set_state(0x3d, 1); + *(int *)(D_001413D0 + 0x98) = -1; + D_001413F5 = 1; + moby[0x20] = 6; + } else F(data, 0x13c) = angle; + if (!inside && D_0013F65C == 0) { + F(data, 0x14c) = 0.0f; + if (moby[0x53] != 1) blend_moby_animation(moby, 1, 0, 10); + moby[0x20] = 2; + } + goto bounds; + case 6: + FUN_L07_0030eee8(moby, data); + FUN_L07_0030f1e0(moby, data, F(data, 0x13c), 0.20943952f, frame_time_sq * 6.0f, 0.5235988f, frame_time_sq * 4.0f, frame_time * 7.0f, frame_time * 3.0f); + FUN_L07_0030f0f8(moby, data, frame_time_sq * 12.0f, frame_time_sq * 50.0f, frame_time * 7.0f); + FUN_L00_00258278(moby, data + 0x120, F(data, 0x13c), frame_time_sq * 1.5707964f, frame_time_sq * 3.1415927f, frame_time * 3.1415927f); + F(moby, 0x44) = FUN_L00_00258110(data + 0x124, F(moby, 0x44), 0.0f, frame_time_sq * 1.5707964f, frame_time_sq * 3.1415927f, frame_time * 3.1415927f); + if ((moby[0x70] & 2) && moby[0x53] != 1) blend_moby_animation(moby, 1, 0, 10); + break; + case 7: + if (inside) { + if (moby[0x53] != 4) blend_moby_animation(moby, 4, 0, 10); + moby[0x20] = 9; + } else if (wander) { + if (moby[0x53] != 4) blend_moby_animation(moby, 4, 0, 10); + *(int *)(data + 0x134) = rand_e50() % 200 + 300; + F(data, 0x13c) = random_angle_radians(); + moby[0x20] = 8; + } + FUN_001f9a68(data + 0xd0, data + 0xd0, frame_scale * -0.050000012f + 1.0f); + F(data, 0xd8) -= frame_time * 9.8f; + if (FUN_L00_00258ad0((int)moby, (int)(data + 0xd0), 0x400, 0x10, 1.0f, 0.0f)) FUN_001f9a68(data + 0xd0, data + 0xd0, 0.5f); + break; + case 8: + if (inside) { + if (moby[0x53] != 4) blend_moby_animation(moby, 4, 0, 10); + moby[0x20] = 9; + } else { + FUN_L00_00258278(moby, data + 0x120, F(data, 0x13c), frame_time_sq * 0.7853982f, frame_time_sq * 1.5707964f, frame_time * 0.7853982f); + F(moby, 0x44) = FUN_L00_00258110(data + 0x124, F(moby, 0x44), 0.0f, frame_time_sq * 0.7853982f, frame_time_sq * 1.5707964f, frame_time * 0.7853982f); + if (wander && is_point_inside_clip_volume(moby + 0x10, *(int *)(data + 0x114))) { + if (moby[0x53] != 3) blend_moby_animation(moby, 3, 0, 10); + *(int *)(data + 0x134) = rand_e50() % 120 + 60; + moby[0x20] = 7; + } + } + FUN_L07_0030eee8(moby, data); + if (FUN_L07_0030f1e0(moby, data, F(data, 0x13c), 0.34906584f, frame_time_sq * 3.0f, 1.0471976f, frame_time_sq * 9.0f, frame_time, frame_time) && wander) { + if (moby[0x53] != 3) blend_moby_animation(moby, 3, 0, 10); + *(int *)(data + 0x134) = rand_e50() % 120 + 60; + moby[0x20] = 7; + } + F(data, 0xd8) -= frame_time * 9.8f; + if (FUN_L00_00258ad0((int)moby, (int)(data + 0xd0), 0x400, 0x10, 1.0f, 0.0f)) FUN_001f9a68(data + 0xd0, data + 0xd0, 0.5f); + break; + case 9: case 10: + angle = FUN_001f9e90(target[0] - F(moby, 0x10), target[1] - F(moby, 0x14)); + FUN_L00_00258278(moby, data + 0x120, angle, frame_time_sq * 0.7853982f, frame_time_sq * 1.5707964f, frame_time * 0.7853982f); + if (FUN_L07_0030f1e0(moby, data, angle, 0.5235988f, frame_time_sq * 4.0f, 1.5707964f, frame_time_sq * 9.0f, frame_time * 1.5f, frame_time) && FUN_001f9b80(moby + 0x10, target) < 1.9f && moby[0x20] != 10) { + if (moby[0x53] != 5) blend_moby_animation(moby, 5, 0, 2); + moby[0x20] = 10; + } + F(data, 0xd8) -= frame_time * 9.8f; + if (FUN_L00_00258ad0((int)moby, (int)(data + 0xd0), 0x400, 0x10, 1.0f, 0.0f)) FUN_001f9a68(data + 0xd0, data + 0xd0, 0.5f); + data[0x58] = truncate_float_to_s32(8.0f); + data[0x5a] = truncate_float_to_s32(9.6f); + if (!inside) { + if (moby[0x53] != 4) blend_moby_animation(moby, 4, 0, 10); + moby[0x20] = 8; + } + FUN_L07_0030f308(moby, data, 10, 5, 4, 4, 11, *(int *)(target + 16), 17.0f, 20.0f, 1.0f, 1.0f, 1.0f); + if (moby[0x70] & 2) { + if (moby[0x53] != 4) blend_moby_animation(moby, 4, 0, 10); + *(int *)(data + 0x134) = rand_e50() % 200 + 300; + moby[0x20] = 8; + } + break; + case 11: + if (moby[0x70] & 2) moby[0x20] = 7; + goto bounds; + case 12: + if (FUN_L00_0025c698(moby, data + 0x70) & 1) FUN_L07_0030ec58(moby); + goto bounds; + case 13: + if (moby[0x70] & 2) FUN_L07_0030ec58(moby); + goto bounds; + case 14: + if (FUN_L00_0025c698(moby, data + 0x70) & moby[0x70] & 2) { + FUN_L00_0025e450_l07(0.0f, 0.0f, 2.0f, 1.0f, 4.0f, 1.0f, 7.0f, (struct Moby *)moby, data + 0xd0, 0, 3, 3, 5, -1, 0, 1, -1, 0); + goto remove; + } + goto bounds; + case 15: + FUN_001f9a68(data + 0xd0, data + 0xd0, frame_scale * -0.050000012f + 1.0f); + F(data, 0xd8) -= frame_time * 9.8f; + FUN_L00_00258ad0((int)moby, (int)(data + 0xd0), 0x400, 0x10, 1.0f, 0.0f); + break; + case 16: + FUN_001f9a68(data + 0xd0, data + 0xd0, frame_scale * -0.050000012f + 1.0f); + F(data, 0xd8) -= frame_time * 9.8f; + FUN_L00_00258ad0((int)moby, (int)(data + 0xd0), 0x400, 0x10, 1.0f, 0.0f); + if (moby[0x70] & 2) FUN_L07_0030ec58(moby); + goto bounds; + case 17: + FUN_001f9a68(data + 0xd0, data + 0xd0, frame_scale * -0.050000012f + 1.0f); + if (moby[0x70] & 2) FUN_L07_0030ec58(moby); + goto bounds; + default: goto bounds; + } + if (next_state != 0xff) { + if (moby[0x53] != next_sequence) blend_moby_animation(moby, next_sequence, 0, 6); + moby[0x20] = next_state; + } +bounds: + if (F(moby, 0x10) < 2.0f || 1021.0f < F(moby, 0x10) || F(moby, 0x14) < 2.0f || 1021.0f < F(moby, 0x14) || F(moby, 0x18) < 2.0f || 1021.0f < F(moby, 0x18)) { + remove: + mark_moby_for_removal(moby); + } +} +#endif extern int FUN_001160d8(void); extern int FUN_001f96f8(int); extern int FUN_001f9740(int *); From 7355c8c2169687b022dad88f6da94c81f996652c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:40:10 +0000 Subject: [PATCH 020/251] decomp: improve FUN_L08_002e3870 --- src/overlays/l08/gameplay/entities/002deee0.c | 492 ++++++++++++++++++ 1 file changed, 492 insertions(+) diff --git a/src/overlays/l08/gameplay/entities/002deee0.c b/src/overlays/l08/gameplay/entities/002deee0.c index a4efcaf79..ef632ba0b 100644 --- a/src/overlays/l08/gameplay/entities/002deee0.c +++ b/src/overlays/l08/gameplay/entities/002deee0.c @@ -1909,7 +1909,499 @@ void FUN_L08_002e2df0(struct Moby *moby) { } FUN_L00_0025d538(moby, data->x60); } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L08_002e3870.s", FUN_L08_002e3870); +#else +extern float D_L08_00161C88 __attribute__((sda)); +extern float D_L08_00161C8C __attribute__((sda)); +extern float D_L08_00161C94 __attribute__((sda)); +extern float D_L08_00161C98 __attribute__((sda)); +extern float D_L08_00161C9C __attribute__((sda)); +extern float D_L08_00161CA0 __attribute__((sda)); +extern float D_L08_00161CA4 __attribute__((sda)); +extern float D_L08_00161CA8 __attribute__((sda)); +extern float D_L08_00161CAC __attribute__((sda)); +extern float D_L08_00161CB0 __attribute__((sda)); +extern short D_L08_00161CB4 __attribute__((sda)); +extern short D_L08_00161CB8 __attribute__((sda)); +extern short D_L08_00161CBC __attribute__((sda)); +extern int D_L08_00161CC0 __attribute__((sda)); +extern int D_L08_00161CC4 __attribute__((sda)); +extern int D_L08_00161CC8 __attribute__((sda)); +extern int D_L08_00161CCC __attribute__((sda)); +extern float scale_game_frames_float(float) __asm__("FUN_L08_00211a20"); +extern float D_L08_00161CD0 __attribute__((sda)); +extern int D_L08_00161CD4 __attribute__((sda)); +extern char D_0013F370[]; +extern char D_0013F390[]; +extern char D_0013F490[]; +extern char D_0013F5F0[]; +extern unsigned char *D_L08_0015FFDC; +extern int D_L08_0015F5CC_sda __asm__("D_L08_0015F5CC") __attribute__((sda)); +extern int current_level_index_sda __asm__("D_0015ED84") __attribute__((sda)); +extern unsigned char D_0014BEC0[]; +extern unsigned char D_0014D590[]; +extern int level_bolts[] __asm__("D_0013DF38"); +extern unsigned char mission_state[] __asm__("D_L08_0015FC88"); +extern unsigned char D_L08_001BB224[]; +extern unsigned char D_L08_001BBE84[]; +extern struct Moby *D_L08_00174658 __attribute__((section(".data"))); +extern Vec4 D_L08_00174660; +extern Vec4 D_L08_00174680; +extern void FUN_L08_002e4e90(struct Moby *, float *, float *); +extern void FUN_L08_0026a0f8(void *, void *, float); +extern int FUN_001efa68(void *, void *, int, int, int); +extern int FUN_L00_001f0d60(void *, int, void *, float); +extern void FUN_L00_001ff660(void *, void *, void *); +extern void *FUN_L00_002603d0(void *); +extern void FUN_L00_002604f0(void *, void *, void *, void *, void *, void *); +extern void FUN_L00_00260668(void *, void *, void *, void *, void *, void *); +extern void FUN_L00_0025bc00(float *, int, float, float); +extern void FUN_L00_0025f730(void *, float); +extern void FUN_L00_00257d78(void *, float, float); +extern void FUN_00213ed8(void *, float, float); +extern float FUN_001f99c0(float); +extern float FUN_001f9b80(void *, void *); +extern float FUN_001f9b20(void *); +extern void FUN_001f9d20(void *, void *, void *); +extern void FUN_001fa328(void *, void *, void *); +extern void FUN_L00_0025f730(void *, float); +extern void FUN_L00_00272060(void *, int, float, float, int, int, int, void *, float); +extern void queue_animation_update(int, int, void *, void *, void *, void *, int) __asm__("FUN_001ff308"); +extern void FUN_L08_002444a8(void); +extern void FUN_L08_002444e0(void); +extern void FUN_L08_002445d8(void); +extern void FUN_L08_002e5188(struct Moby *); +extern void FUN_L00_00257d78(void *, float, float); +extern void FUN_001f4600(void *, void *); +extern void scale_vector_xyz(void *, void *, float) __asm__("FUN_001f9a68"); + +#define DATA_F(off) (*(float *)(data + (off))) +#define DATA_I(off) (*(int *)(data + (off))) +#define DATA_S(off) (*(short *)(data + (off))) +#define DATA_P(off) (*(struct Moby **)(data + (off))) + +/* Six-state collectible update. The in-place rotation in state 3 deliberately + * uses the new X value when calculating Y, as the retail instructions do. */ +void FUN_L08_002e3870(struct Moby *moby) { + Vec4 normal, point, offset; + float matrix[16]; + + switch (moby->state) { + case 0: { + struct Moby *ground; + int timer; + float scale; + char *data; + unsigned char *position; + data = (char *)moby->pvars; + { + int timer; + struct MobyClass *pclass; + float scale; + switch (moby->oclass) { + case 0x279: + pclass = moby->pclass; + scale = *(float *)&D_L08_00161CB4; + goto initial_scale; + case 0x3dc: + pclass = moby->pclass; + scale = *(float *)&D_L08_00161CB8; + goto initial_scale; + case 0x3dd: + pclass = moby->pclass; + scale = *(float *)&D_L08_00161CBC; +initial_scale: + moby->scale = pclass->scale * scale; + timer = D_L08_0015F5CC_d; + break; + default: + timer = D_L08_0015F5CC_sda; + break; + } + if (timer < D_L08_00161CD4) D_L08_00161CD4 = timer; + } + ground = 0; + moby->flags &= 0xfeff; + position = (unsigned char *)&moby->pos; + qcopy(data, position); + /* Retail leaves normal untouched when this flag is nonzero. */ + if (DATA_S(0x6e) == 0) { + normalize_vector_xyz(&point, &moby->rot_row2, 0.1f); + add_vector_xyz(&point, &point, position); + scale_vector_xyz(&offset, &moby->rot_row2, -2.0f); + add_vector_xyz(&offset, &offset, position); + if (FUN_001efa68(&point, &offset, 2, 0, 0)) { + qcopy(data, &D_L08_00174660); + ground = D_L08_00174658; + normalize_vector_xyz(&normal, &D_L08_00174680, 1.0f); + } else { + qcopy(data, position); + clear_u64_value(&normal); + normal.f[2] = 1.0f; + } + } + FUN_L08_002e4db8(moby, normal.f); + DATA_F(0x60) = random_angle_radians(); + DATA_F(0x64) = moby->rot.x; + FUN_L08_002e4e90(moby, (float *)position, &moby->rot.x); + if (ground && FUN_L00_002603d0(ground)) { + DATA_P(0x7c) = ground; + FUN_L00_00260668(moby, ground, data, data + 0x10, data + 0x20, data + 0x30); + } + moby->state = 1; + DATA_S(0x6c) = 0; + timer = scale_game_frames_alt(600); + DATA_I(0x70) = truncate_float_to_s32(random_float_between(0.0f, (float)timer)); + DATA_I(0x78) = D_L08_00161CCC; + break; + } + case 1: { + int timer; + float angle, turn, scale; + char *data; + unsigned char *position; + position = (unsigned char *)&moby->pos; + data = (char *)moby->pvars; + if (DATA_P(0x7c)) { + FUN_L00_002604f0(moby, DATA_P(0x7c), data + 0x20, data + 0x30, data, data + 0x10); + if ((signed char)DATA_P(0x7c)->state < 0) { + data = (char *)moby->pvars; + clear_u64_value(data + 0x40); + FUN_L08_0026a0f8(data, &moby->rot_row1, + D_L08_00161C98 * 0.017453292f * frame_time); + moby->state = 4; + return; + } + } + if (FUN_001f99c0(moby->pos.z - hero.motion.pos.f[2]) < hero.reach_distance && + FUN_001f9b80(position, &hero.motion.pos) < hero.reach_height) { + DATA_I(0x68) = scale_game_frames_alt(1); + moby->state = 2; + } + if (moby->visible) { + if (moby->oclass == 0x3dc) { + angle = fast_add_rotations(DATA_F(0x60), D_L08_00161CA4 * 0.017453292f * frame_time); + turn = D_L08_00161CA8; + } else if (moby->oclass == 0x3dd) { + angle = fast_add_rotations(DATA_F(0x60), D_L08_00161CAC * 0.017453292f * frame_time); + turn = D_L08_00161CB0; + } else { + angle = fast_add_rotations(DATA_F(0x60), D_L08_00161C9C * 0.017453292f * frame_time); + turn = D_L08_00161CA0; + } + DATA_F(0x60) = angle; + DATA_F(0x64) = fast_add_rotations(DATA_F(0x64), turn * 0.017453292f * frame_time); + FUN_L08_002e4e90(moby, (float *)position, &moby->rot.x); + if (DATA_S(0x6c) == 0) { + if (!tick_countdown_32_alt((int *)(data + 0x70))) return; + DATA_I(0x70) = 0x18; + DATA_F(0x74) = random_angle_radians(); + DATA_S(0x6c) = 1; + return; + } + DATA_F(0x74) = fast_add_rotations(DATA_F(0x74), frame_time * 5.2359877f); + if (DATA_I(0x70) < 13) DATA_I(0x78) += -0x5000000; + else DATA_I(0x78) += 0x5000000; + if (tick_countdown_32_alt((int *)(data + 0x70))) { + DATA_S(0x6c) = 0; + scale = (float)scale_game_frames_alt(300); + timer = scale_game_frames_alt(600); + DATA_I(0x70) = truncate_float_to_s32(random_float_between(scale, (float)timer)); + return; + } + if (!moby->visible || !D_L08_00161CC8) return; + FUN_001f4600(FUN_L08_002e5188, moby); + return; + } + if ((unsigned int)moby <= (unsigned int)D_L08_0015FFDC) return; + if (!(24.0f < FUN_001f9b80(position, &hero.motion.pos))) return; + goto remove; + } + case 2: { + int timer; + float angle, turn, sine; + char *data; + unsigned char *position; + position = (unsigned char *)&moby->pos; + data = (char *)moby->pvars; + FUN_001fa050(matrix, (float *)(data + 0x10)); + qcopy(&normal, matrix + 8); + if (!tick_countdown_32_alt((int *)(data + 0x68))) { + if (scale_game_frames_alt(10) < DATA_I(0x68)) { + sine = fast_sin((float)(DATA_I(0x68) % 8 - 4) * 0.7854f); + angle = fast_add_rotations(DATA_F(0x60), sine * 0.17453292f); + FUN_L00_0025bc00((float *)(data + 0x60), 0, angle, 0.5235988f); + } else { + turn = 0.08726646f; + angle = FUN_001f9e90(hero.motion.pos.f[0] - moby->pos.x, hero.motion.pos.f[1] - moby->pos.y); + angle = fast_add_rotations(angle, 1.5707964f); + FUN_L00_0025bc00((float *)(data + 0x60), 0, angle, turn); + if (func_001FA850_2E16A0(DATA_F(0x60), angle) < turn) DATA_I(0x68) = 0; + } + FUN_L08_002e4e90(moby, (float *)position, &moby->rot.x); + } else { + data = (char *)moby->pvars; + subtract_vector_xyz(&point, position, &hero.motion.pos); + normalize_vector_xyz(&point, &point, 1.0f); + fast_vec_cross(&point, &normal, &point); + FUN_L08_0026a0f8(data, &point, D_L08_00161C94 * 0.017453292f * frame_time); + moby->flags |= 0x100; + normalize_vector_xyz(data + 0x40, &normal, frame_time * 8.0f); + DATA_F(0x74) = 0.0f; + DATA_F(0x70) = frame_time * 8.0f; + DATA_F(0x7c) = 0.5f; + DATA_P(0x78) = *(struct Moby **)D_001413D0; + timer = scale_game_frames_alt(3); + if (D_L08_00161CD4 + timer < D_L08_0015F5CC_d) { + D_L08_00161CD4 = D_L08_0015F5CC_d; + allocate_voice_for_target_entry(0, 0x20, moby); + DATA_F(0x64) = 0.0f; + } else DATA_F(0x64) = random_float_between(-30.0f, 30.0f) * 0.017453292f; + moby->state = 3; + } + break; + } + case 3: { + int timer, value, spin, i, j, count, level; + float distance, reach, size, sine, cosine; + unsigned char *source; + char *data; + unsigned char *position; + position = (unsigned char *)&moby->pos; + data = (char *)moby->pvars; + if (!DATA_P(0x78)) return; + normalize_vector_xyz(&point, &DATA_P(0x78)->rot_row2, DATA_F(0x7c)); + add_vector_xyz(&point, &point, &DATA_P(0x78)->pos); + subtract_vector_xyz(&normal, &point, position); + if (DATA_F(0x64) != 0.0f) { + sine = fast_sin(DATA_F(0x64)); + cosine = fast_cos(DATA_F(0x64)); + normal.f[0] = cosine * normal.f[0] + sine * normal.f[1]; + normal.f[1] = cosine * normal.f[1] - sine * normal.f[0]; + } + distance = FUN_001f9b48(&point, position); + normalize_vector_xyz(data + 0x40, data + 0x40, DATA_F(0x70)); + add_vector_xyz(position, position, data + 0x40); + normalize_vector_xyz(&normal, &normal, DATA_F(0x74)); + add_vector_xyz(position, position, &normal); + add_vector_xyz(position, position, D_0013F490); + subtract_vector_xyz(&offset, position, D_0013F5F0); + FUN_001f9d20(&offset, &offset, D_0013F390); + if (DATA_P(0x78)->oclass != 0 || 0.0f < offset.f[2]) { + FUN_00213ed8(data + 0x70, 0.0f, D_L08_00161C8C * frame_time_sq); + FUN_00213ed8(data + 0x74, D_L08_00161C88 * frame_time, D_L08_00161C8C * frame_time_sq); + } else { + normalize_vector_xyz(matrix, D_0013F370, DATA_F(0x70)); + subtract_vector_xyz(matrix + 4, matrix, data + 0x40); + FUN_L00_0025f730(matrix + 4, D_L08_00161C8C * frame_time_sq); + add_vector_xyz(data + 0x40, data + 0x40, matrix + 4); + } + if (distance < DATA_F(0x74)) DATA_F(0x74) = distance; + timer = scale_game_frames_alt(20); + reach = DATA_F(0x74) * (float)timer; + if (distance < reach) { + if (!(0.52f < FUN_001f9b48(&point, position))) { + if (moby->oclass == 0x3dc) value = 5; + else if (moby->oclass < 0x3dd) { + if (moby->oclass == 0x305) { + D_0014BEC0[moby->command + current_level_index * 4] = 1; + count = 0; + i = 0; + do { + source = D_0014BEC0 + i * 4; + j = 3; + do { + if (*source++ != 0) count++; + j--; + } while (j >= 0); + i++; + } while (i < 20); + value = count * 100; + } else value = 1; + } else if (moby->oclass == 0x3dd) value = 10; + else value = 1; + FUN_L00_00257d78(matrix, frame_time * 0.7f, frame_time); + scale_vector_xyz(matrix + 4, matrix, 10.0f); + add_vector_xyz(matrix + 4, matrix + 4, position); + spin = random_integer_below(2); + if (!spin) spin--; + size = random_float_between(0.4f, 0.5f); + timer = scale_game_frames_alt(25); + FUN_L00_00272060(matrix + 4, timer, size * 0.2f, size, 0x7f207f7f, 0, spin, matrix, 0.0f); + timer = scale_game_frames_alt(25); + FUN_L00_00272060(matrix + 4, timer, size * 0.14f, size * 0.7f, 0x7f7f7f7f, 1, -spin, matrix, 0.0f); + source = (unsigned char *)moby->parent; + level = current_level_index_sda; + if (source && !(source[0xb1] & 0x80)) { + *(short *)(D_0014D590 + source[0xb1] * 4 + current_level_index * 256 + 2) += value; + level = current_level_index; + } + current_bolt_count += value; + level_bolts[level] += value; + queue_animation_update(2, 0x754e, FUN_L08_002444a8, FUN_L08_002444e0, FUN_L08_002445d8, ¤t_bolt_count, 9999999); + if ((unsigned char *)moby < D_L08_0015FFDC) { + D_L08_001BB224[(short)moby->save_id] = moby->mission + 2; + if (moby->mission == 255 || (mission_state[moby->mission] != 255 && D_0014C050[moby->mission + current_level_index_sda * 16] == 255)) + D_L08_001BBE84[(short)moby->save_id] = moby->mission + 2; + } +remove: + mark_moby_for_removal(moby); + return; + } + if (D_L08_00161CC0) { + distance = FUN_001f9b48(&point, position); + moby->alpha = (int)(((distance + reach) * 128.0f) / (reach + reach)); + } + if (D_L08_00161CC4) { + distance = FUN_001f9b48(&point, position); + moby->scale = (moby->pclass->scale * *(float *)&D_L08_00161CB4 * (distance + reach)) / (reach + reach); + } + } + FUN_001fa328(&moby->rot_row0, data, &moby->rot_row0); + break; + } + case 4: { + int timer, value, level; + float angle, scale; + char *platform; + unsigned char *source; + char *data; + unsigned char *position; + position = (unsigned char *)&moby->pos; + data = (char *)moby->pvars; + add_vector_xyz(position, position, data + 0x40); + DATA_F(0x48) -= frame_time_sq * 10.8f; + FUN_001fa328(&moby->rot_row0, data, &moby->rot_row0); + if (moby->pos.z < 2.0f || 510.0f < moby->pos.x || moby->pos.x < 2.0f || + 510.0f < moby->pos.y || moby->pos.y < 2.0f) { + if (moby->oclass == 0x3dc) value = 5; + else if (moby->oclass == 0x3dd) value = 10; + else value = 1; + source = (unsigned char *)moby->parent; + level = current_level_index_sda; + if (source && !(source[0xb1] & 0x80)) { + *(short *)(D_0014D590 + source[0xb1] * 4 + current_level_index * 256 + 2) += value; + level = current_level_index; + } + current_bolt_count += value; + level_bolts[level] += value; + mark_moby_for_removal(moby); + break; + } + if (moby->pos.z < DATA_F(0x60) - 4.0f && moby->pos.z < hero.motion.pos.f[2] - 4.0f) { + data = (char *)moby->pvars; + qcopy(data + 0x10, &hero.motion.rot); + DATA_I(0x68) = scale_game_frames_alt(1); + moby->state = 2; + return; + } + if (!FUN_L00_001f0d60(position, 0x22, moby, 0.25f)) return; + subtract_vector_xyz(&normal, position, &D_L08_00174660); + FUN_L00_001ff660(data + 0x40, data + 0x40, &normal); + angle = FUN_001f9e90(normal.f[2], FUN_001f9b20(&normal)); + if (!(angle < 0.7853982f)) return; + angle = FUN_001f9e90(D_L08_00174680.f[2], FUN_001f9b20(&D_L08_00174680)); + if (!(angle < 0.7853982f)) return; + moby->flags &= 0xfeff; + data = (char *)moby->pvars; + timer = truncate_float_to_s32(scale_game_frames_float(D_L08_00161CD0 + random_float_between(-10.0f, 10.0f))); + scale = 1.0f / convert_integer_to_float(timer); + qcopy(data, &D_L08_00174660); + FUN_00214598(&moby->rot_row0, &moby->rot.x); + normalize_vector_xyz(&normal, &D_L08_00174680, 1.0f); + FUN_L08_002e4db8(moby, normal.f); + DATA_F(0x60) = random_angle_radians(); + DATA_F(0x64) = random_angle_radians(); + FUN_L08_002e4e90(moby, (float *)(data + 0x20), (float *)(data + 0x30)); + subtract_vector_xyz(data + 0x40, data + 0x20, position); + scale_vector_xyz(data + 0x40, data + 0x40, scale); + if (D_L08_00174658) { + platform = FUN_L00_002603d0(D_L08_00174658); + if (platform) { + platform += 0x10; + add_vector_xyz(data + 0x40, data + 0x40, platform); + scale_vector_xyz(&point, platform, convert_integer_to_float(timer)); + add_vector_xyz(data + 0x20, data + 0x20, &point); + add_vector_xyz(data, data, &point); + } + } + DATA_F(0x48) += frame_time_sq * 10.8f * (float)(timer >> 1); + DATA_F(0x50) = fast_subtract_rotations(DATA_F(0x30), moby->rot.x) * scale; + DATA_F(0x54) = fast_subtract_rotations(DATA_F(0x34), moby->rot.y) * scale; + DATA_F(0x58) = fast_subtract_rotations(DATA_F(0x38), moby->rot.z) * scale; + moby->state = 5; + DATA_I(0x68) = timer; + DATA_P(0x7c) = D_L08_00174658; + if (!(FUN_001f99c0(moby->pos.z - hero.motion.pos.f[2]) < hero.reach_distance)) return; + if (!(FUN_001f9b80(position, &hero.motion.pos) < hero.reach_height)) return; + data = (char *)moby->pvars; + DATA_I(0x68) = scale_game_frames_alt(1); + moby->state = 2; + return; + } + case 5: { + int timer; + float scale; + char *platform; + char *data; + unsigned char *position; + position = (unsigned char *)&moby->pos; + data = (char *)moby->pvars; + moby->rot.x = fast_add_rotations(moby->rot.x, DATA_F(0x50)); + moby->rot.y = fast_add_rotations(moby->rot.y, DATA_F(0x54)); + moby->rot.z = fast_add_rotations(moby->rot.z, DATA_F(0x58)); + add_vector_xyz(position, position, data + 0x40); + DATA_F(0x48) -= frame_time_sq * 10.8f; + if (!tick_countdown_32_alt((int *)(data + 0x68))) return; + if (FUN_001f99c0(moby->pos.z - hero.motion.pos.f[2]) < hero.reach_distance && + FUN_001f9b80(position, &hero.motion.pos) < hero.reach_height) { + DATA_I(0x68) = scale_game_frames_alt(1); +chase: + moby->state = 2; + return; + } + if (!moby->command) { + timer = truncate_float_to_s32((float)scale_game_frames_alt(20)); + scale = 1.0f / convert_integer_to_float(timer); + moby->command++; + DATA_F(0x50) = fast_subtract_rotations(DATA_F(0x30), moby->rot.x) * scale; + DATA_F(0x54) = fast_subtract_rotations(DATA_F(0x34), moby->rot.y) * scale; + DATA_F(0x58) = fast_subtract_rotations(DATA_F(0x38), moby->rot.z) * scale; + subtract_vector_xyz(data + 0x40, data + 0x20, position); + scale_vector_xyz(data + 0x40, data + 0x40, scale); + DATA_I(0x68) = timer; + if (DATA_P(0x7c)) { + platform = FUN_L00_002603d0(DATA_P(0x7c)); + if (platform) { + platform += 0x10; + add_vector_xyz(data + 0x40, data + 0x40, platform); + scale_vector_xyz(&normal, platform, convert_integer_to_float(timer)); + add_vector_xyz(data + 0x20, data + 0x20, &normal); + add_vector_xyz(data, data, &normal); + } + } + DATA_F(0x48) += frame_time_sq * 10.8f * (float)(timer >> 1); + } else { + moby->state = 1; + if (!DATA_P(0x7c)) { + qcopy(position, data + 0x20); + qcopy(&moby->rot.x, data + 0x30); + } else { + data = (char *)moby->pvars; + FUN_L00_00260668(moby, DATA_P(0x7c), data, data + 0x10, data + 0x20, data + 0x30); + } + } + break; + } + } + return; +} +#undef DATA_F +#undef DATA_I +#undef DATA_S +#undef DATA_P +#endif #include "qcopy.h" From fa0923fa6d6b2e3f1b5386d19b64b5531bc47d87 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:44:56 +0000 Subject: [PATCH 021/251] decomp: improve draw_debug_text --- src/overlays/shared/rendering/debug/001f36f8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/rendering/debug/001f36f8.c b/src/overlays/shared/rendering/debug/001f36f8.c index c3bc04a0e..da8f94fd0 100644 --- a/src/overlays/shared/rendering/debug/001f36f8.c +++ b/src/overlays/shared/rendering/debug/001f36f8.c @@ -64,8 +64,8 @@ void FUN_L00_001f3770(s32 x, s32 y, s32 color, s32 text_address) { packet[2] = 0x10AB400000000001ULL; tags = packet + 2; tags[1] = 0xE; - tags[2] = 1; tags[3] = 0x14; + tags[2] = 1; tags[4] = 0x2400000000000001ULL; tags[5] = 0x61; ((u64 *)tags)[6] = color & 0xFFFFFFFFULL; @@ -100,8 +100,8 @@ void FUN_L00_001f3770(s32 x, s32 y, s32 color, s32 text_address) { } x += *(s32 *)((u8 *)D_L00_00169B00 + glyph); } - ((u32 *)packet)[3] = quadwords | 0x50000000; ((u32 *)packet)[0] = quadwords | 0x10000000; + ((u32 *)packet)[3] = quadwords | 0x50000000; ((u32 *)packet)[1] = 0; ((u32 *)packet)[2] = 0; *glyph_tag = (s64)(glyph_count | 0x8000) | 0x4400000000000000ULL; From 4d4a2c8b54734159dda15d0cead22faa75af60eb Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:46:13 +0000 Subject: [PATCH 022/251] decomp: improve FUN_L00_002995d0 --- src/overlays/shared/gameplay/entities/00295100.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/00295100.c b/src/overlays/shared/gameplay/entities/00295100.c index 8e1f43365..fee4076fe 100644 --- a/src/overlays/shared/gameplay/entities/00295100.c +++ b/src/overlays/shared/gameplay/entities/00295100.c @@ -857,6 +857,8 @@ extern void FUN_00120558(s32, s32); extern void FUN_L00_001eb078(s32, s32); extern void FUN_L00_001ff008(void); +extern char D_L00_001E9480[]; + void FUN_L00_002995d0(s32 sector, s32 size, s32 language) { u8 buffer[0x60] __attribute__((aligned(16))); s32 source, destination, count, second_count, pal, initial_count; @@ -907,7 +909,7 @@ void FUN_L00_002995d0(s32 sector, s32 size, s32 language) { } while (count != 0); } if (source > 0x400000) { - FUN_L00_001eb078(0x1e9480, source - 0x400000); + FUN_L00_001eb078((s32)D_L00_001E9480, source - 0x400000); FUN_L00_001ff008(); } } From 79e5181d38beccd2a28c2c35604e4d4d5cb476de Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:47:21 +0000 Subject: [PATCH 023/251] decomp: improve FUN_L00_002648e0 --- src/overlays/shared/gameplay/entities/002648e0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002648e0.c b/src/overlays/shared/gameplay/entities/002648e0.c index 871fadffc..b211fbe19 100644 --- a/src/overlays/shared/gameplay/entities/002648e0.c +++ b/src/overlays/shared/gameplay/entities/002648e0.c @@ -12,7 +12,7 @@ typedef struct { s32 ticks; } MobyProfile; -extern u64 D_0013CAE0; +extern u64 D_0013CAE0[]; extern s32 D_L00_0015F3F8; extern struct Moby *D_L00_0015FFE4; extern s16 D_L00_00197A00[]; @@ -42,7 +42,7 @@ void FUN_L00_002648e0(void) { s32 *entry; s16 profile_label; - if ((D_0013CAE0 & 0x800000007LL) != 0x800000007LL) { + if ((D_0013CAE0[0] & 0x800000007LL) != 0x800000007LL) { FUN_L00_00264848(); return; } From da5032b0c29574fb277b359900db3c4d2ebaf285 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:49:07 +0000 Subject: [PATCH 024/251] decomp: improve nanotech_upgrade_vendor --- src/overlays/l10/gameplay/vendor/002df270.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/overlays/l10/gameplay/vendor/002df270.c b/src/overlays/l10/gameplay/vendor/002df270.c index bce1ad0aa..50f2f64e7 100644 --- a/src/overlays/l10/gameplay/vendor/002df270.c +++ b/src/overlays/l10/gameplay/vendor/002df270.c @@ -1963,7 +1963,6 @@ extern int D_L10_0013F640 __asm__("D_L10_0013F640") __attribute__((section(".sda void FUN_L10_002e8358(struct Moby *moby) { int *timer; - int accepted; float angle; int purchase; int upgrade_level; @@ -1983,7 +1982,7 @@ void FUN_L10_002e8358(struct Moby *moby) { FUN_L00_00266858_vendor(moby, 1); if (alternate_item_available[4] == 0) { if (current_bolt_count >= 4001) { - accepted = try_set_help_message_vendor(1, 0x271e) != 0; + int accepted = try_set_help_message_vendor(1, 0x271e) != 0; if (!(D_0013CAE4 & 0x10)) return; if (accepted == 0) return; alternate_item_available[4] = 1; @@ -2000,7 +1999,7 @@ void FUN_L10_002e8358(struct Moby *moby) { } else { if (alternate_item_available[5] != 0 || timer[1] != 0) return; if (current_bolt_count >= 30001) { - accepted = try_set_help_message_vendor(1, 0x271f) != 0; + int accepted = try_set_help_message_vendor(1, 0x271f) != 0; if (!(D_0013CAE4 & 0x10)) return; if (accepted == 0) return; alternate_item_available[5] = 1; @@ -2023,8 +2022,9 @@ void FUN_L10_002e8358(struct Moby *moby) { if (D_L10_0015F5C4_vendor != 2) { memcard_save_data_vendor(0, -1); switch (alternate_item_available[5]) { - case 0: purchase = 0x271c; break; default: purchase = 0x271d; break; + case 1: purchase = 0x271d; break; + case 0: purchase = 0x271c; break; } FUN_L00_00263d40_vendor(purchase, -1); D_L10_0013F640 = 0xb4; From a3ccfb96671ea4daa16a1a38d090b70b0403412c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:45:30 +0000 Subject: [PATCH 025/251] decomp: improve FUN_L07_00314150 --- src/overlays/l07/gameplay/entities/00312948.c | 1079 +++++++++++++++++ 1 file changed, 1079 insertions(+) diff --git a/src/overlays/l07/gameplay/entities/00312948.c b/src/overlays/l07/gameplay/entities/00312948.c index 59a274371..bb3163060 100644 --- a/src/overlays/l07/gameplay/entities/00312948.c +++ b/src/overlays/l07/gameplay/entities/00312948.c @@ -537,7 +537,1086 @@ void FUN_L07_00314058(char *moby) { } } } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L07_00314150.s", FUN_L07_00314150); +#else +/* Target sensing, fade timers, and state transitions. Adapted from + * OpenRAC/rac1-decomp func_L07_00315528 and checked against US level-07 + * instructions; only navigation result 4 takes the stop transition. */ +typedef struct { + Vec4 pos; + Vec4 rotation; + Vec4 position20; /* copied from hero +0xC0 or the selected position */ + Vec4 position30; /* copied from hero +0xD0 or the selected position */ + void *moby; + int kind; +} ChaserSight; +typedef struct { int count; int pad[3]; RopeVec points[1]; } ChaserPath; +typedef struct { char pad[0x1D4]; unsigned char path_points[4]; int linked_mobys[6]; } ChaserPathPoints; +typedef struct { char pad[0x3C]; short count; char pad2[0xE]; } ChaserSpawnRecord; +extern char *D_L07_0015FFD8; +extern Vec4 D_L07_00166E40; +extern int D_L07_00161B64 __attribute__((sda)); +extern ChaserSpawnRecord D_L07_00179B40[]; +extern int D_L07_0020C600[][4]; +extern int spawn_counts[] __asm__("D_0013D428"); +extern void FUN_L00_00263ac8(float, int, int, void *); +extern void FUN_L00_0025e450(void *, void *, void *, float, float, int, int, int, float, float, float, float, int, float, int, int, int, int); +extern int FUN_00214720(void *, int); +extern float FUN_001f9b48(void *, void *); +extern float FUN_001f9b80(void *, void *); +extern void FUN_L00_0025a120(struct Moby *); +extern int get_target_sight(void *, void *, float) __asm__("FUN_L07_002886d8"); +extern int FUN_L00_001fefc8(void *); +extern int FUN_001f9770(void *); +extern float FUN_001f99c0(float); +extern void FUN_L00_002defe0(int); +extern void FUN_001f4600(void (*)(), void *); +extern int FUN_001ff308(int, int, int, int, int, int, int); +extern void FUN_L00_00235d80(void); +extern void FUN_L00_00235ea0(void); +extern void FUN_L06_00249738(void); +extern void FUN_L05_0028be78(int *, int, int); +extern void FUN_L00_002ddca0(void *); +extern int FUN_001160d8(void); +extern int tick_countdown_32_alt(s32 *) __asm__("FUN_001f9740"); +extern int FUN_00213260(int); +extern void FUN_L07_0029b8d8(char *, int, float, float); +extern int FUN_L07_003122b0(void *, char *, float *); +extern int FUN_00214cc8(void *, float); +extern void *FUN_L07_0030dbb0(int, void *, int, float, float, float, float, float); +extern void FUN_L00_0024f7c8(void *, int, void *); +extern void FUN_L07_00311eb8(void *, void *, int, void *, short, unsigned int, int, float); +extern void FUN_00214db0(void *, float, float, float); +extern void FUN_L07_0029c4e8(void *, void *); +extern void FUN_L07_003120d8(char *); +extern float FUN_00213508(void *, int, float); +extern float FUN_001f9ab0(void *, void *); +extern float FUN_001f9af0(void *); +extern void FUN_L07_00312420(void); +extern float FUN_0020c9e0(void *); +extern void *FUN_L00_002715e8(void *, int, int, float, float); +extern void FUN_00210850(void *, int, void *, void *); +extern void FUN_00214598(void *, void *); +extern float FUN_001fa580(float, float); +extern float FUN_L07_00317e60(void *, void *); +extern void FUN_L07_00318e98(int); +extern void FUN_L00_00257d78(void *, float, float); +extern int FUN_L00_0025d808(void *, void *, int *, float *, float, int); +extern float FUN_L00_0025abf0(void *, void *, void *, float, float); +extern char *FUN_L00_002c52a8(void *, int, int, int); +extern void FUN_001ff570(int, int); +extern void FUN_L06_002e6148(char *); +extern void FUN_L00_0023e838(int); +extern void mark_moby_for_removal(void *); +extern void FUN_L00_00259fe8(struct Moby *, float); +extern void FUN_L07_00312150(char *); +void FUN_L07_00314150(unsigned char *moby) { + Vec4 oldpos; + ChaserSight sight; + Vec4 position; + Vec4 velocity; + Vec4 direction; + Vec4 start; + Vec4 offset; + Vec4 step; + Vec4 projection; + unsigned char *data = *(unsigned char **)(moby + 0x78); + int follow_target; + int timer194; + int timer19a; + int sight_ready; + int target_close; + int path_point_ready; + int target_above; + float target_distance; + float target_angle; + float hero_distance; + float hero_angle; + int i; + float *health; + + FUN_L00_00263ac8(2.5f, (int)moby, 0xB, data + 0x2A0); + FUN_L07_00314058((char *)moby); + if (D_L07_0015F5C4 == 2) return; + if (*(int *)(data + 0x1A4) != -1 && !FUN_00214720(((char *)&hero) + 0x80, *(int *)(data + 0x1A4))) return; + if (moby[0x31] != 0) { + if (FUN_001f9b48(moby + 0x10, &D_L07_00166E40) < 35.0f) { + FUN_L00_0025a120((struct Moby *)moby); + moby[0x7F] = 0x1C; + } + } + qcopy(&oldpos, moby + 0x10); + health = (float *)(data + 0x20); + FUN_L07_00313420((char *)moby, (char *)data, health); + follow_target = 0; + get_target_sight((struct Moby *)moby, &sight, 30.0f); + target_distance = FUN_001f9b80(&sight, moby + 0x10); + target_angle = FUN_001f9e90(sight.pos.f[0] - *(float *)(moby + 0x10), sight.pos.f[1] - *(float *)(moby + 0x14)); + hero_distance = FUN_001f9b80(moby + 0x10, ((char *)&hero) + 0x80); + { + char *g = ((char *)&hero); + hero_angle = FUN_001f9e90(*(float *)(g + 0x80) - *(float *)(moby + 0x10), *(float *)(g + 0x84) - *(float *)(moby + 0x14)); + } + if (FUN_L00_001fefc8(data + 0x1F7)) { + if ((FUN_001f9b80(moby + 0x10, ((char *)&hero) + 0x80) > 8.0f && moby[0x20] != 5) + || (FUN_001f9b80(moby + 0x10, ((char *)&hero) + 0x80) > 6.0f && (moby[0x20] == 5 || moby[0xBC] % 3U == 1))) { + follow_target = 1; + } + } + timer19a = 0; + timer194 = FUN_001f9770(data + 0x194) != 0; + if (FUN_001f9770(data + 0x19A) && target_distance > 9.0f) timer19a = 1; + sight_ready = 0; + if (data[0x1C7] != 0) { + char *g = ((char *)&hero); + if (sight.moby == *(void **)(g + 0x2080) && target_distance < 30.0f + && FUN_001f99c0(fast_subtract_rotations(target_angle, *(float *)(moby + 0x48))) < 1.3962634f) { + sight_ready = 1; + } + } + target_close = 0; + if (FUN_001f9770(data + 0x198)) { + if (((moby[0x20] == 5 || moby[0xBC] % 3U == 1) && target_distance < 14.0f) || (moby[0x20] != 5 && target_distance < 10.0f)) target_close = 1; + } + { + char *g = ((char *)&hero); + path_point_ready = 0; + target_above = 0; + if (*(float *)(moby + 0x18) + 1.0f < *(float *)(g + 0x2D8)) { + if (*(char **)(g + 0x2FC) != 0 && *(short *)(*(char **)(g + 0x2FC) + 0xA6) >= 0x459 + && *(short *)(*(char **)(g + 0x2FC) + 0xA6) < 0x45D) { + target_above = 1; + } + } + } + switch (moby[0xBC]) { + case 0: + follow_target = 0; + sight_ready = 0; + break; + case 3: + if (*(int *)(data + 0x1A8) != -1) { + follow_target = 1; + path_point_ready = 1; + timer194 = 0; + target_close = 0; + } else { + follow_target = 0; + } + sight_ready = 0; + break; + case 6: + if (*(int *)(data + 0x1A8) != -1) { + follow_target = 1; + path_point_ready = 1; + timer194 = 0; + target_close = 0; + } else { + follow_target = 0; + } + break; + case 1: + case 4: + case 7: + timer194 = 0; + sight_ready = 0; + if (moby[0x20] != 1) timer19a = 0; + break; + case 2: + case 5: + case 8: + target_close = 0; + timer194 = 0; + sight_ready = 0; + timer19a = 0; + break; + } + *(int *)(data + 0x1B4) = truncate_float_to_s32(*(float *)(data + 0x20) * 16.0f) & 0xFFF0; + if (*(int *)(data + 0x1B4) >= truncate_float_to_s32(((float)*(short *)(data + 0x24) - 0.5f) * 16.0f)) { + *(int *)(data + 0x1B4) |= 0xF; + } + if (moby[0xBC] % 3U == 0) { + if (*(float *)(data + 0x20) > 0.5f) { + int r = ((truncate_float_to_s32(*(float *)(data + 0x20)) % (*(short *)(data + 0x24) / 6)) * 16) / (*(short *)(data + 0x24) / 6); + if (r < 0) r = 0; + *(int *)(data + 0x1B4) += r & 0xF; + } else { + *(int *)(data + 0x1B4) = 0; + } + } + if (moby[0xBC] % 3U == 2) *(int *)(data + 0x1B4) += 0xF; + if (moby[0x20] != 8 && moby[0x20] != 0) FUN_L00_002defe0((int)moby); + if (data[0x1C5] == 1) { + if (*(int *)(data + 0x1F8) == -1) *(int *)(data + 0x1F8) = FUN_0022da68(0xF, 4, (int)moby); + *(float *)(data + 0x1C8) += frame_scale * 0.01f; + if (*(float *)(data + 0x1C8) >= 1.0f) data[0x1C5] = 0; + if (*(float *)(data + 0x1C8) > 1.0f) *(float *)(data + 0x1C8) = 1.0f; + } + if (data[0x1C5] == 2) { + if (*(int *)(data + 0x1F8) == -1) *(int *)(data + 0x1F8) = FUN_0022da68(0xF, 4, (int)moby); + *(float *)(data + 0x1C8) -= frame_scale * 0.01f; + if (*(float *)(data + 0x1C8) <= 0.0f) { + if (*(int *)(data + 0x1F8) != -1) { + char *sl = (D_0013E5C4 - 0x74) + *(int *)(data + 0x1F8) * 0x70; + if (*(void **)(sl + 0x88) == moby && *(unsigned char *)(sl + 0x74) != 0) { + FUN_0022d798(*(int *)(data + 0x1F8)); + } + } + data[0x1C5] = 0; + *(int *)(data + 0x1F8) = -1; + } + if (*(float *)(data + 0x1C8) < 0.0f) *(float *)(data + 0x1C8) = 0.0f; + } + if (*(float *)(data + 0x1C8) > 0.0f) FUN_001f4600(FUN_L07_00312dc8, moby); + FUN_L07_00313f60((char *)moby, (char *)data, (float *)(((char *)&hero) + 0x80)); + if (moby[0x20] != 0 && moby[0x20] != 0xA && moby[0x20] != 0x10) { + *(int *)(data + 0x1B0) = FUN_001ff308(0x16, 0xFFFF, (int)FUN_L00_00235d80, (int)FUN_L00_00235ea0, + (int)FUN_L06_00249738, (int)(data + 0x1B4), + (*(short *)(data + 0x24) << 4) | 0xF); + } + switch (moby[0x20]) { + case 0: + *(int *)&D_L07_00161B64 = 0; + moby[0x20] = 1; + moby[0xBC] = 0; + *(short *)(data + 0x280) = -1; + *(float *)(data + 0x190) = 0.0f; + if (*(int *)(data + 0x18C) != -1) { + int i; + for (i = 0; i < *(int *)D_L07_001B0530[*(int *)(data + 0x18C)]; i++) { + ((ChaserPath *)D_L07_001B0530[*(int *)(data + 0x18C)])->points[i][3] = + FUN_001f9b48(D_L07_001B0530[*(int *)(data + 0x18C)] + (i * 16 + 0x10), + D_L07_001B0530[*(int *)(data + 0x18C)] + (((i + 1) % *(int *)D_L07_001B0530[*(int *)(data + 0x18C)]) * 16 + 0x10)); + *(float *)(data + 0x190) += ((ChaserPath *)D_L07_001B0530[*(int *)(data + 0x18C)])->points[i][3]; + } + } + if (*(int *)(data + 0x290) != -1) { + char *tbl = D_L07_001B0530[*(int *)(data + 0x290)]; + int i; + for (i = 0; i < *(int *)tbl; i++) { + ((ChaserPath *)tbl)->points[i][3] = FUN_001f9b48(tbl + (i * 16 + 0x10), tbl + (((i + 1) % *(int *)tbl) * 16 + 0x10)); + } + } + if (*(int *)(data + 0x188) != -1) { + int i; + for (i = 0; i < *(int *)D_L07_001B0530[*(int *)(data + 0x188)]; i++) { + int k = truncate_float_to_s32(((ChaserPath *)D_L07_001B0530[*(int *)(data + 0x188)])->points[i][3]); + if ((unsigned int)k < 4) ((ChaserPathPoints *)data)->path_points[k] = i; + } + } + *(int *)(data + 0xA8) &= ~8; + *(unsigned short *)(moby + 0x34) |= 0x1000; + FUN_L05_0028be78((int *)(data + 0x170), 3, *(int *)(data + 0x188)); + data[0x19C] = 7; + moby[0x30] = 0xFF; + *(short *)(moby + 0x32) = 0xFF; + *(int *)(data + 0x1A8) = -1; + *(int *)(data + 0x1B0) = -1; + *(int *)(data + 0x1C0) = FUN_L01_0028b510(moby + 0x10, D_L07_001B0530[*(int *)(data + 0x188)], 0.0f); + FUN_L00_002ddca0(moby); + *(float *)(moby + 0x2C) *= 1.75f; + data[0x1C7] = 0; + *(float *)(data + 0x98) = 1.7453293f; + data[0x29] = 1; + data[0x58] = truncate_float_to_s32(30.0f); + data[0x5A] = truncate_float_to_s32(40.0f); + break; + case 1: + if (moby[0x70] & 2) { + if (moby[0x53] != (FUN_001160d8() & 1)) { + int r1 = FUN_001160d8() & 1; + int r2 = random_int_between(0, 0xF); + FUN_00212f90(moby, r1, r2, random_int_between(0x1E, 0x2A)); + } + } + if (tick_countdown_32_alt((int *)(data + 0x160))) { + if (timer19a) { + *(int *)(data + 0x164) = 0; + *(int *)(data + 0x160) = 0; + if (moby[0x53] != 5) { + int r = random_int_between(0, 2); + FUN_00212f90(moby, 5, r, random_int_between(0x12, 0x14)); + } + moby[0x20] = 4; + } + if (timer194) { + if (moby[0x20] != 5 || FUN_00213260(4) == 0) { + *(int *)(data + 0x164) = 0; + if (moby[0x53] != 4) { + int r = random_int_between(0, 9); + FUN_00212f90(moby, 4, r, random_int_between(0x14, 0x28)); + } + moby[0x20] = 3; + *(float *)(moby + 0x58) = 1.0f; + } + } + if (sight_ready) { + if (moby[0x53] != 6) { + int r = random_int_between(0, 2); + FUN_00212f90(moby, 6, r, random_int_between(0xF, 0x19)); + } + *(int *)(data + 0x164) = 0; + *(float *)(data + 0x16C) = 0.0f; + data[0x1C4] = 0; + moby[0x20] = 8; + *(int *)(data + 0x294) = 0; + *(int *)(data + 0x1F8) = FUN_0022da68(9, 4, (int)moby); + } + if (target_close) { + if (moby[0x53] != 9) { + int r = random_int_between(0, 2); + FUN_00212f90(moby, 9, r, random_int_between(0x11, 0x19)); + } + moby[0x20] = 2; + } + } + if (follow_target && moby[0x20] != 8) { + if (moby[0x53] != 0xA) { + int r = random_int_between(0, 4); + FUN_00212f90(moby, 0xA, r, random_int_between(0x14, 0x1E)); + } + *(float *)(moby + 0x58) = 1.5f; + *(int *)(data + 0x298) = 0; + moby[0x20] = 5; + } + break; + case 2: { + float rot; + rot = *(float *)(moby + 0x48); + if (frame_count_l07 % 6 == 0) FUN_L07_0029b8d8((char *)moby, 0, 600000.0f, 5.0f); + if ((frame_count_l07 - 2) % 6 == 0) FUN_L07_0029b8d8((char *)moby, 1, 600000.0f, 5.0f); + if (FUN_L07_00313de8(moby, data, (float *)(((char *)&hero) + 0x80), 9, 0)) break; + FUN_L00_00258278((struct Moby *)moby, target_angle, (float *)(data + 0x168), frame_time_sq * 2.0943952f, frame_time_sq * 0.6981317f, frame_time * 2.0943952f); + if (fast_difference_between_rotations(*(float *)(moby + 0x48), rot) > frame_time * 0.17453292f) { + if (moby[0x53] != 0xD) { + int r = random_int_between(0, 1); + FUN_00212f90(moby, 0xD, r, random_int_between(0xF, 0x16)); + } + } else { + if (moby[0x53] != 9) { + int r = random_int_between(0, 1); + FUN_00212f90(moby, 9, r, random_int_between(0xF, 0x16)); + } + } + if (moby[0x52] == 9 || moby[0x52] == 0xD) moby[0x20] = FUN_L07_003122b0(moby, (char *)data, (float *)&sight); + if ((moby[0xBC] % 3U == 0 && FUN_001f9b80(&sight, moby + 0x10) > 13.0f) + || (moby[0xBC] % 3U == 1 && FUN_001f9b80(&sight, moby + 0x10) > 20.0f)) { + *(short *)(data + 0x198) = scale_ticks(0x23); + *(int *)(data + 0x160) = scale_ticks(0x1E); + moby[0x20] = 1; + } + break; + } + case 3: + FUN_L00_00258278((struct Moby *)moby, target_angle, (float *)(data + 0x168), frame_time_sq * 1.5707964f, frame_time_sq * 0.6981317f, frame_time * 1.0471976f); + if (FUN_00214cc8(moby, 31.0f) || FUN_00214cc8(moby, 67.0f) || FUN_00214cc8(moby, 101.0f)) { + float speed; + *(int *)(data + 0x164) += 1; + qcopy(&position, moby + 0x10); + speed = frame_time * 8.0f; + *(int *)(data + 0x168) = 0; + FUN_L07_0030dbb0((int)moby, &position, 0x3A, 1.0f, 25.0f, 2.0f, speed, 1.0f); + FUN_L00_0024f7c8(moby, (*(int *)(data + 0x164) & 1) + 5, &position); + FUN_L07_00311eb8(moby, data, 1, &position, scale_ticks(0x1E), 0x800060FF, 0, 10.0f); + position.f[2] = *(float *)(moby + 0x18); + for (i = 0; i < 55; i++) { + float r1 = random_angle_radians(); + float r2 = random_float_between(0.3926991f, 0.78539819f); + FUN_00214db0(&velocity, frame_time * 5.0f, r1, r2); + normalize_vector_xyz(&direction, &velocity, 0.75f); + direction.f[2] += 0.1f; + add_vector_xyz(&direction, &direction, &position); + *(int *)&velocity.f[3] = 0; + FUN_L07_0029c4e8(&direction, &velocity); + } + FUN_L07_003120d8((char *)moby); + } + if (*(int *)(data + 0x164) >= 3 && FUN_00214cc8(moby, 51.0f)) { + if (timer19a) { + *(short *)(data + 0x194) = 0xC0; + *(int *)(data + 0x160) = 0xAA; + } else { + *(short *)(data + 0x194) = scale_ticks(0x3C); + *(int *)(data + 0x160) = scale_ticks(0x37); + if (*(short *)(data + 0x19A) <= scale_ticks(0x37)) *(short *)(data + 0x19A) += scale_ticks(0x3C); + } + *(float *)(moby + 0x58) = 1.0f; + if (moby[0x53] != (FUN_001160d8() & 1)) { + int r1 = FUN_001160d8() & 1; + int r2 = random_int_between(0, 0xF); + FUN_00212f90(moby, r1, r2, random_int_between(0x1E, 0x2A)); + } + moby[0x20] = 1; + } + break; + case 4: + if (FUN_L07_00313de8(moby, data, (float *)(((char *)&hero) + 0x80), 5, 0)) break; + if (*(int *)(data + 0x160) < scale_ticks(0x3C) / 2) { + FUN_L00_0024f7c8(moby, 2, &position); + FUN_L07_00311eb8(moby, data, 2, &position, scale_ticks(0x1E), 0x800060FF, 0, 10.0f); + if ((frame_count_l07 & 7) == 0) FUN_L07_0029b8d8((char *)moby, 2, 0.0f, 0.2f); + if (((frame_count_l07 - 4) & 7) == 0) FUN_L07_0029b8d8((char *)moby, 3, 0.0f, 0.2f); + } + if (moby[0x52] == 5) { + qcopy(&position, &sight); + position.f[2] = FUN_00213508(&position, 0, 0.5f); + *(int *)(data + 0x160) += 1; + if (*(int *)(data + 0x164) == 0) { + subtract_vector_xyz(&velocity, moby + 0x10, &position); + velocity.f[2] = 0.0f; + normalize_vector_xyz(&velocity, &velocity, 1.0f); + normalize_vector_xyz(&step, &velocity, 0.075f); + direction.f[0] = fast_cos(sight.rotation.f[2]); + direction.f[1] = fast_sin(sight.rotation.f[2]); + direction.f[2] = 0.0f; + { + float s = FUN_001f9ab0(&direction, &velocity); + normalize_vector_xyz(&projection, &velocity, s); + } + subtract_vector_xyz(&direction, &direction, &projection); + direction.f[2] = 0.0f; + normalize_vector_xyz(&start, &velocity, 8.0f); + normalize_vector_xyz(&direction, &direction, 4.0f); + add_vector_xyz(&start, &start, &position); + subtract_vector_xyz(&start, &start, &direction); + normalize_vector_xyz(&direction, &direction, 8.0f); + add_vector_xyz(&direction, &direction, &position); + normalize_vector_xyz(&velocity, &velocity, 2.0f); + subtract_vector_xyz(&direction, &direction, &velocity); + qcopy(&projection, ((char *)&hero) + 0x100); + projection.f[2] = 0.0f; + scale_vector_xyz(&offset, &projection, (float)scale_ticks(0x28)); + subtract_vector_xyz(&velocity, &direction, &start); + scale_vector_xyz(&velocity, &velocity, 0.5f); + add_vector_xyz(&velocity, &velocity, &start); + subtract_vector_xyz(&velocity, &velocity, &position); + subtract_vector_xyz(&velocity, &velocity, &step); + subtract_vector_xyz(&velocity, &offset, &velocity); + add_vector_xyz(&start, &start, &velocity); + add_vector_xyz(&direction, &direction, &velocity); + qcopy(data + 0x110, &start); + qcopy(data + 0x120, &direction); + qcopy(data + 0x140, &start); + subtract_vector_xyz(data + 0x130, &direction, &start); + scale_vector_xyz(data + 0x130, data + 0x130, 1.0f / (float)scale_ticks(0x3C)); + qcopy(data + 0x150, data + 0x140); + *(int *)(data + 0x15C) = 0; + *(int *)(data + 0x164) = 1; + } else { + if (*(int *)(data + 0x160) < scale_ticks(0x3C)) { + add_vector_xyz(data + 0x140, data + 0x140, data + 0x130); + FUN_001f4600(FUN_L07_00312420, moby); + *(int *)(data + 0x164) = 2; + } else { + *(int *)(data + 0x164) = 0; + *(short *)(data + 0x19A) = scale_ticks(0xF0); + *(int *)(data + 0x160) = scale_ticks(0xC8); + moby[0x20] = 1; + } + } + } + break; + case 5: + case 6: { + float thr = 2.0f; + float rot = *(float *)(moby + 0x48); + float dd; + FUN_L07_00313350(moby, data, &direction); + if (!path_point_ready) { + thr = 6.0f; + if (*(int *)(data + 0x29C) != -1 && (data[0x19C] & 3) == 0 && FUN_00214720(&sight, *(int *)(data + 0x29C))) { + qcopy(&velocity, D_L07_001B0530[*(int *)(data + 0x1A0)] + FUN_L01_0028b510(&sight, D_L07_001B0530[*(int *)(data + 0x1A0)], 0.0f) * 16 + 0x10); + dd = FUN_001f9b80(moby + 0x10, &velocity); + } else { + qcopy(&velocity, &sight); + qcopy(&velocity, D_L07_001B0530[*(int *)(data + 0x290)] + FUN_L01_0028b510(&velocity, D_L07_001B0530[*(int *)(data + 0x290)], 0.0f) * 16 + 0x10); + dd = FUN_001f9b80(moby + 0x10, &velocity); + if (dd < *(float *)(data + 0x9C) + 1.0f) qcopy(&velocity, &sight); + } + } else { + qcopy(&velocity, D_L07_001B0530[*(int *)(data + 0x188)] + *(int *)(data + 0x1A8) * 16 + 0x10); + dd = FUN_001f9b80(moby + 0x10, &velocity); + } + FUN_L07_00313d30((struct ChaserAnim *)moby, (struct ChaserSpeed *)data, dd, thr, 1.5f); + if ((*(int *)(data + 0x298) & 3) == 0) FUN_L07_00313988((char *)moby, (char *)data, &velocity, data + 0x140); + qcopy(&position, data + 0x140); + *(int *)(data + 0x298) += 1; + if (*(float *)(data + 0x98) < fast_difference_between_rotations(*(float *)(moby + 0x48), FUN_001f9e90(position.f[0] - *(float *)(moby + 0x10), position.f[1] - *(float *)(moby + 0x14)))) { + *(float *)(moby + 0x58) = 1.0f; + data[0x1F4] = moby[0x20]; + data[0x1F6] = 0xA; + data[0x1F5] = 1; + qcopy(data + 0xC0, &position); + if (moby[0x53] != 3) { + int r = random_int_between(0, 1); + FUN_00212f90(moby, 3, r, random_int_between(0xF, 0x16)); + } + moby[0x20] = 7; + } else { + int hit = FUN_L07_00313af0((struct Moby *)moby, (struct ChaserVars *)data, &velocity, (int)&position, thr); + float spd; + int near; + int moving; + fast_difference_between_rotations(*(float *)(moby + 0x48), rot); + spd = FUN_001f9af0(data + 0x100); + near = 0; + if (!path_point_ready && target_distance < 20.0f) near = 1; + moving = frame_time * 0.01f < spd; + if (hit != 4) hit = 2; + if ((hit == 4) || !moving) { + data[0x1F7] = scale_ticks(0x5A); + if (moby[0x53] != (FUN_001160d8() & 1)) { + int r1 = FUN_001160d8() & 1; + int r2 = random_int_between(0, 9); + FUN_00212f90(moby, r1, r2, random_int_between(0x14, 0x28)); + } + *(int *)(data + 0x1A8) = -1; + moby[0x20] = 1; + break; + } + if (moby[0x53] != 0xA) { + if (!near && (moby[0x70] & 2)) FUN_00212f90(moby, 0xA, 5, random_int_between(0xA, 0xD)); + } else { + if (near && (moby[0x70] & 2)) FUN_00212f90(moby, 0xC, 5, random_int_between(0xA, 0xD)); + } + if (tick_countdown_32_alt((int *)(data + 0x160))) { + if (timer19a) { + *(int *)(data + 0x164) = 0; + *(int *)(data + 0x160) = 0; + *(float *)(moby + 0x58) = 1.0f; + if (moby[0x53] != 5) { + int r = random_int_between(0, 2); + FUN_00212f90(moby, 5, r, random_int_between(0x14, 0x19)); + } + moby[0x20] = 4; + } + if (timer194) { + *(int *)(data + 0x164) = 0; + if (moby[0x53] != 4) { + int r = random_int_between(0, 5); + FUN_00212f90(moby, 4, r, random_int_between(0x14, 0x28)); + } + moby[0x20] = 3; + *(float *)(moby + 0x58) = 1.0f; + } + if (target_above) { + *(int *)(data + 0x164) = 0; + { char *g = ((char *)&hero); qcopy(data + 0x150, *(char **)(g + 0x2FC) + 0x10); } + *(float *)(data + 0x158) += 3.0f; + moby[0x20] = 9; + } + if (sight_ready) { + *(float *)(moby + 0x58) = 1.0f; + if (moby[0x53] != 6) { + int r = random_int_between(0, 2); + FUN_00212f90(moby, 6, r, random_int_between(0x14, 0x19)); + } + *(int *)(data + 0x164) = 0; + *(float *)(data + 0x16C) = 0.0f; + data[0x1C4] = 0; + *(int *)(data + 0x294) = 0; + moby[0x20] = 8; + *(int *)(data + 0x1F8) = FUN_0022da68(9, 4, (int)moby); + } + } + if (!follow_target) { + *(float *)(moby + 0x58) = 1.0f; + if (moby[0x53] != (FUN_001160d8() & 1)) { + int r1 = FUN_001160d8() & 1; + int r2 = random_int_between(0, 2); + FUN_00212f90(moby, r1, r2, random_int_between(0x1C, 0x28)); + } + moby[0x20] = 1; + } + if (moby[0x52] == 0xC) FUN_L07_003122b0(moby, (char *)data, (float *)&sight); + } + if (moby[0x52] == 0xA || moby[0x52] == 0xC) { + if (FUN_00214cc8(moby, 27.5f)) FUN_L07_003120d8((char *)moby); + if (FUN_00214cc8(moby, 73.0f)) FUN_L07_003120d8((char *)moby); + } + break; + } + case 7: { + float diff; + if (data[0x1F5] == 0) qcopy(data + 0xC0, ((char *)&hero) + 0x80); + diff = fast_subtract_rotations(FUN_001f9e90(*(float *)(data + 0xC0) - *(float *)(moby + 0x10), *(float *)(data + 0xC4) - *(float *)(moby + 0x14)), *(float *)(moby + 0x48)); + if (!target_close && (moby[0x70] & 2)) { + if (diff < 0.0001f) { + if (moby[0x53] != 3) FUN_00212f90(moby, 3, 5, random_int_between(0xA, 0xD)); + } else { + if (moby[0x53] != 0xE) FUN_00212f90(moby, 0xE, 5, random_int_between(0xA, 0xD)); + } + } + if (moby[0x52] == 3 || moby[0x52] == 0xE || moby[0x52] == 0xD) { + float dz = FUN_0020c9e0(moby); + if (dz < 14.5f || (dz > 19.0f && dz < 35.5f) || dz > 40.5f) { + FUN_L00_00258278((struct Moby *)moby, FUN_001f9e90(*(float *)(data + 0xC0) - *(float *)(moby + 0x10), *(float *)(data + 0xC4) - *(float *)(moby + 0x14)), + (float *)(data + 0x168), frame_time_sq * 2.0943952f, frame_time_sq * 0.6981317f, frame_time * 2.0943952f); + } + if (diff > 0.001f && moby[0x53] == 3) { + FUN_00212f90(moby, 0xE, 5, random_int_between(0xA, 0xD)); + } else if (diff < 0.001f && moby[0x53] == 0xE) { + FUN_00212f90(moby, 3, 5, random_int_between(0xA, 0xD)); + } + } else { + *(int *)(data + 0x84) = 0; + } + if (fast_difference_between_rotations(*(float *)(moby + 0x48), FUN_001f9e90(*(float *)(data + 0xC0) - *(float *)(moby + 0x10), *(float *)(data + 0xC4) - *(float *)(moby + 0x14))) < *(float *)(data + 0x98) * 0.25f) { + qzero(data + 0x100); + if (moby[0x53] != data[0x1F6]) { + int anim = data[0x1F6]; + int r = random_int_between(0, 2); + FUN_00212f90(moby, anim, r, random_int_between(0xF, 0x1B)); + } + moby[0x20] = data[0x1F4]; + } + if (moby[0x52] == 3 || moby[0x52] == 0xE) { + if (FUN_00214cc8(moby, 16.0f)) FUN_L07_003120d8((char *)moby); + if (FUN_00214cc8(moby, 37.0f)) FUN_L07_003120d8((char *)moby); + } else if (moby[0x52] == 0xD) { + if (FUN_00214cc8(moby, 13.0f)) FUN_L07_003120d8((char *)moby); + if (FUN_00214cc8(moby, 34.0f)) FUN_L07_003120d8((char *)moby); + } + break; + } + case 12: { + int k; + if (*(float *)(data + 0x20) <= convert_integer_to_float(*(short *)(data + 0x24) / 6)) { + if (moby[0x53] != 8) FUN_00212f90(moby, 8, 0x35, random_int_between(0xA, 0xD)); + } else { + if (moby[0x53] != 0xB) FUN_00212f90(moby, 0xB, 0x3D, 1); + } + moby[0x20] = 0xD; + *(float *)(data + 0x108) = 0.0f; + if (moby[0xBC] % 3U < 2) moby[0xBC] += 1; + if (moby[0xBC] % 3U < 2) moby[0xBC] += 1; + if (moby[0xBC] >= 8) moby[0xBC] = 8; + if (((ChaserPathPoints *)data)->linked_mobys[data[0x19D]] != -1) { + int k2; + k = data[0x19D]; + k2 = k + 3; + if (((ChaserPathPoints *)data)->linked_mobys[k2] != -1) { + char *o1 = *(char **)(D_L07_0015FFD8 + (((ChaserPathPoints *)data)->linked_mobys[k] << 8) + 0x78); + char *o2 = *(char **)(D_L07_0015FFD8 + (((ChaserPathPoints *)data)->linked_mobys[k2] << 8) + 0x78); + if (*(int *)(o1 + 0x28) != -1 && *(int *)(o2 + 0x28) != -1) { + float d1 = FUN_001f9b80(((char *)&hero) + 0x80, D_L07_001600EC + (*(int *)(o1 + 0x28) << 7) + 0x30); + int sel; + if (FUN_001f9b80(((char *)&hero) + 0x80, D_L07_001600EC + (*(int *)(o2 + 0x28) << 7) + 0x30) < d1) { + sel = *(int *)(o2 + 0x28); + k = k2; + } else { + sel = *(int *)(o1 + 0x28); + } + *(float *)(moby + 0x48) = FUN_001f9e90(*(float *)(D_L07_001600EC + sel * 0x80 + 0x30) - *(float *)(moby + 0x10), + *(float *)(D_L07_001600EC + sel * 0x80 + 0x34) - *(float *)(moby + 0x14)); + } + } + *(unsigned char *)(D_L07_0015FFD8 + ((ChaserPathPoints *)data)->linked_mobys[k] * 0x100 + 0xBC) = 1; + } + break; + } + case 13: { + int done = 0; + if (FUN_0020c9e0(moby) > 10.0f) { + FUN_L00_0024f7c8(moby, 0xA, &position); + position.f[2] = 34.6f; + if (FUN_00213260(0x1A) == 0) FUN_L00_002715e8(&position, 0, 0x40103080, 1.6f, 14700.0f); + } + if (moby[0xBC] == 8) { + float z = *(float *)(data + 0x108); + scale_vector_xyz(data + 0x100, data + 0x100, 0.7f); + *(float *)(data + 0x108) = z; + *(float *)(data + 0x108) -= frame_time * 9.8f; + add_vector_xyz(moby + 0x10, moby + 0x10, data + 0x100); + if (*(float *)(moby + 0x18) < *(float *)(data + 0x1B8)) done = 1; + } else { + if (FUN_0020c9e0(moby) > 79.0f) done = 1; + } + if (done) { + *(int *)(data + 0x160) = scale_ticks(0xA); + data[0x1C5] = 2; + moby[0x20] = 0xE; + *(int *)(data + 0x164) = *(short *)(data + 0x24) / 6; + } + break; + } + case 14: + scale_vector_xyz(data + 0x100, data + 0x100, 0.4f); + add_vector_xyz(moby + 0x10, moby + 0x10, data + 0x100); + if (FUN_0020c9e0(moby) < 168.0f) { + FUN_L00_0024f7c8(moby, 0xA, &position); + position.f[2] = 34.6f; + if (FUN_00213260(0x1A) == 0) FUN_L00_002715e8(&position, 0, 0x40103080, 1.6f, 14700.0f); + } + if (FUN_00214cc8(moby, 168.0f)) { + FUN_L00_0024f7c8(moby, 5, &position); + FUN_L07_0030dbb0((int)moby, &position, 0x3A, 1.0f, 25.0f, 2.0f, frame_time * 8.0f, 1.0f); + } + if (FUN_00214cc8(moby, 168.5f)) { + FUN_L00_0024f7c8(moby, 6, &position); + FUN_L07_0030dbb0((int)moby, &position, 0x3A, 1.0f, 25.0f, 2.0f, frame_time * 8.0f, 1.0f); + FUN_L07_003120d8((char *)moby); + } + if (*(int *)(data + 0x164) > 0) { + if (tick_countdown_32_alt((int *)(data + 0x160))) { + *(int *)(data + 0x164) -= 1; + *health -= 1.0f; + data[0x67] = 0xFA; + FUN_L00_0025d458(moby, (short *)(data + 0x60)); + if (*health <= 0.0f) { + *health = 0.0f; + if (moby[0x53] != 8) FUN_00212f90(moby, 8, 0, random_int_between(0xA, 0xD)); + if (*(int *)(data + 0x1F0) != -1) { + FUN_L00_00266858(moby, 1); + FUN_L00_00257470(moby, 0, -1); + FUN_L00_002502a0(moby[0xB0]); + FUN_L00_00284e50(D_L07_001600EC + (*(int *)(data + 0x1F0) << 7) + 0x30, D_L07_001600EC + (*(int *)(data + 0x1F0) << 7) + 0x70); + } + moby[0x20] = 0xA; + } else { + if (*(int *)(data + 0x164) > 0) { + *(int *)(data + 0x160) = scale_ticks(0xA); + } else { + *(int *)(data + 0x160) = scale_ticks(0x14); + } + } + } + } else { + if (tick_countdown_32_alt((int *)(data + 0x160))) { + switch (data[0x19D]) { + case 0: + qcopy(data + 0x120, D_L07_001B0530[*(int *)(data + 0x1A0)] + 0x10); + data[0x19C] &= 0xFE; + break; + case 1: + qcopy(data + 0x120, D_L07_001B0530[*(int *)(data + 0x1A0)] + 0x20); + data[0x19C] &= 0xFD; + break; + case 2: { + float d1 = FUN_001f9b80(((char *)&hero) + 0x80, D_L07_001B0530[*(int *)(data + 0x1A0)] + 0x30); + if (FUN_001f9b80(((char *)&hero) + 0x80, D_L07_001B0530[*(int *)(data + 0x1A0)] + 0x40) < d1) { + qcopy(data + 0x120, D_L07_001B0530[*(int *)(data + 0x1A0)] + 0x30); + } else { + qcopy(data + 0x120, D_L07_001B0530[*(int *)(data + 0x1A0)] + 0x40); + } + data[0x19C] &= 0xFB; + break; + } + } + *(int *)(data + 0x1A8) = ((ChaserPathPoints *)data)->path_points[data[0x19D]]; + FUN_L05_0028be78((int *)&position, (int)FUN_L07_00313350(moby, data, &position), *(int *)(data + 0x188)); + moby[0x20] = 0xF; + } + } + break; + case 15: { + int iF0; + if (FUN_0020c9e0(moby) > 198.0f) { + if (moby[0x53] != 0xA) FUN_00212f90(moby, 0xA, 0, 0); + FUN_L00_0024f7c8(moby, 0xA, &position); + qcopy(data + 0xC0, &position); + *(float *)(data + 0xC8) = *(float *)(data + 0x128); + iF0 = 0xA; + FUN_00210850(moby, 1, &iF0, &velocity); + FUN_00214598(&velocity, &step); + *(float *)(data + 0xCC) = FUN_001fa580(*(float *)(moby + 0x48), step.f[2]); + } + if (moby[0x52] == 0xA) { + qcopy(moby + 0x10, data + 0xC0); + *(float *)(moby + 0x48) = *(float *)(data + 0xCC); + if (((ChaserPathPoints *)data)->linked_mobys[data[0x19D]] != -1) { + *(unsigned char *)(D_L07_0015FFD8 + ((ChaserPathPoints *)data)->linked_mobys[data[0x19D]] * 0x100 + 0xBC) = 0; + } + *(float *)(moby + 0x58) = 1.5f; + moby[0xBC] += 1; + *(int *)(data + 0x298) = 0; + moby[0x20] = 6; + *(int *)(data + 0x160) = scale_ticks(0x37); + } + break; + } + case 8: { + float fr; + float rotation_time = frame_time_sq; + if (*(int *)(data + 0x294) <= 0) { + if (FUN_L07_00313de8(moby, data, (float *)(((char *)&hero) + 0x80), 6, 0)) break; + rotation_time = frame_time_sq; + } + *(int *)(data + 0x294) = 1; + FUN_L00_00258278((struct Moby *)moby, hero_angle, (float *)(data + 0x168), rotation_time * 2.0943952f, rotation_time * 0.6981317f, frame_time * 2.0943952f); + FUN_L00_0024f7c8(moby, 4, &position); + fr = FUN_L07_00317e60(moby, &position); + if (moby[0x52] != 6) break; + qcopy(data + 0x140, ((char *)&hero) + 0x80); + *(float *)(data + 0x148) += 0.6f; + if (*(float *)(data + 0x16C) < hero_distance) { + *(int *)(data + 0x160) = 0; + *(float *)(data + 0x16C) += frame_time * 15.0f; + } else { + if (data[0x1C4] != 0 || (tick_countdown_32_alt((int *)(data + 0x160)) && fr < 0.6f)) { + int slot; + char *g = ((char *)&hero); + data[0x1C4] = 1; + if (*(int *)(g + 0x2084) != 0x78) { + qcopy(data + 0x110, ((char *)&hero) + 0x80); + qcopy(data + 0x120, ((char *)&hero) + 0x80); + if (*(float *)(moby + 0x18) < *(float *)(g + 0x88)) { + *(float *)(data + 0x128) = *(float *)(g + 0x88) + 2.0f; + } else { + *(float *)(data + 0x128) = *(float *)(moby + 0x18) + 2.0f; + } + FUN_L00_002223f8(0x78, 1); + *(int *)(data + 0x164) = 0; + *(float *)(data + 0x1AC) = 20.0f; + *(short *)(data + 0x19E) = 0; + } + subtract_vector_xyz(&velocity, data + 0x120, data + 0x110); + scale_vector_xyz(&velocity, &velocity, frame_scale * 0.1f); + add_vector_xyz(data + 0x110, data + 0x110, &velocity); + qcopy(((char *)&hero) + 0x1D30, data + 0x110); + qcopy(((char *)&hero) + 0x80, data + 0x110); + { + char *g2 = ((char *)&hero); + *(float *)(g2 + 0x1D48) = FUN_001fa580(*(float *)(g2 + 0x1D48), frame_time * 25.132742f); + *(float *)(g2 + 0x98) = FUN_001fa580(*(float *)(g2 + 0x1D48), frame_time * 25.132742f); + } + *(float *)(data + 0x16C) = hero_distance; + slot = D_L07_0020C600[*(int *)(data + 0x164)][0]; + if (slot == -1) { + *(int *)(data + 0x164) = 0; + *(short *)(data + 0x196) = scale_ticks(0x320); + *(int *)(data + 0x160) = scale_ticks(0xF0); + FUN_L07_00318e98((int)moby); + { char *g3 = ((char *)&hero); if (*(int *)(g3 + 0x2084) == 0x78) FUN_L00_002223f8(0, 1); } + data[0x1C7] = 0; + if (*(int *)(data + 0x1F8) != -1) { + char *sl = (D_0013E5C4 - 0x74) + *(int *)(data + 0x1F8) * 0x70; + if (*(void **)(sl + 0x88) == moby && *(unsigned char *)(sl + 0x74) != 0) { + FUN_0022d798(*(int *)(data + 0x1F8)); + } + } + *(int *)(data + 0x1F8) = -1; + moby[0x20] = 1; + } else { + int cnt = (D_L07_00179B40 + slot)->count; + int rem; + int pos; + if (*(short *)(data + 0x19E) == 0) { + *(short *)(data + 0x19E) = spawn_counts[slot] / 8; + if (*(short *)(data + 0x19E) < cnt) *(short *)(data + 0x19E) = cnt; + *(float *)(data + 0x1AC) = random_float_between(*(float *)(data + 0x1AC) + 20.0f, *(float *)(data + 0x1AC) + 100.0f); + } + cnt = *(short *)(data + 0x19E); + if (spawn_counts[slot] < cnt) { + cnt = spawn_counts[slot]; + *(short *)(data + 0x19E) = 0; + *(int *)(data + 0x164) += 1; + } + rem = spawn_counts[slot] - cnt * 8; + pos = rem > 0; + cnt = cnt + pos * rem; + if (cnt > 0) { + float zv = 0.0f; + if (*(int *)(data + 0x18C) == -1) { + FUN_L00_00257d78((float *)&velocity, frame_time * 4.0f, frame_time * 10.0f); + if (velocity.f[2] < frame_time * 2.0f) velocity.f[2] = random_float_between(frame_time * 3.0f, frame_time * 6.0f); + normalize_vector_xyz(&direction, &velocity, 0.9f); + add_vector_xyz(&direction, &direction, ((char *)&hero) + 0x80); + } else { + char *path = D_L07_001B0530[*(int *)(data + 0x18C)]; + int pidx = 0; + float pfrac = 0.0f; + float d1; + float d2; + pidx = FUN_L01_0028b510(((char *)&hero) + 0x80, path, 0.0f); + do { + *(float *)(data + 0x1AC) += 10.0f; + FUN_L00_0025d808(path, &start, &pidx, &pfrac, *(float *)(data + 0x1AC), 1); + d1 = FUN_001f9b80(((char *)&hero) + 0x80, &start); + d2 = FUN_001f9b80(moby + 0x10, &start); + } while (d1 < 8.0f || d2 < 12.0f); + FUN_L07_00313920((float *)&start, 0.5f); + subtract_vector_xyz(&direction, &start, ((char *)&hero) + 0x80); + zv = start.f[2]; + normalize_vector_xyz(&direction, &direction, 0.9f); + qcopy(&velocity, &direction); + velocity.f[2] = 0.0f; + normalize_vector_xyz(&velocity, &velocity, frame_time * 15.0f); + add_vector_xyz(&direction, &direction, ((char *)&hero) + 0x80); + velocity.f[2] = FUN_L00_0025abf0(&direction, &start, 0, frame_time * 15.0f, frame_time_sq * -9.8f); + *(float *)(data + 0x1AC) += random_float_between(0.7f, 2.0f); + } + FUN_0022da68(0xB, 0, (int)moby); + { + char *obj = FUN_L00_002c52a8(&direction, slot, cnt, 0); + if (obj != 0) { + qcopy_nc(*(char **)(obj + 0x78) + 0x10, &velocity); + *(float *)(*(char **)(obj + 0x78) + 0x28) = zv; + spawn_counts[slot] -= cnt; + *(int *)(data + 0x160) = scale_ticks(0); + } + } + } + } + } + } + if (!sight_ready) { + *(int *)(data + 0x164) = 0; + *(short *)(data + 0x196) = scale_ticks(0xF); + FUN_L07_00318e98((int)moby); + { char *g3 = ((char *)&hero); if (*(int *)(g3 + 0x2084) == 0x78) FUN_L00_002223f8(0, 1); } + *(int *)(data + 0x160) = scale_ticks(0x46); + data[0x1C7] = 0; + if (*(int *)(data + 0x1F8) != -1) { + char *sl = (D_0013E5C4 - 0x74) + *(int *)(data + 0x1F8) * 0x70; + if (*(void **)(sl + 0x88) == moby && *(unsigned char *)(sl + 0x74) != 0) { + FUN_0022d798(*(int *)(data + 0x1F8)); + } + } + *(int *)(data + 0x1F8) = -1; + moby[0x20] = 1; + } + if (target_close) { + *(short *)(data + 0x196) = scale_ticks(0x1E); + if (moby[0x53] != 9) { + int r = random_int_between(0, 2); + FUN_00212f90(moby, 9, r, random_int_between(0x10, 0x19)); + } + FUN_L07_00318e98((int)moby); + { char *g3 = ((char *)&hero); if (*(int *)(g3 + 0x2084) == 0x78) FUN_L00_002223f8(0, 1); } + if (*(int *)(data + 0x1F8) != -1) { + char *sl = (D_0013E5C4 - 0x74) + *(int *)(data + 0x1F8) * 0x70; + if (*(void **)(sl + 0x88) == moby && *(unsigned char *)(sl + 0x74) != 0) { + FUN_0022d798(*(int *)(data + 0x1F8)); + } + } + *(int *)(data + 0x1F8) = -1; + moby[0x20] = 2; + } + break; + } + case 9: + if (*(int *)(data + 0x164) <= 0) { + if (FUN_L07_00313de8(moby, data, (float *)(data + 0x150), 7, 1)) break; + } + FUN_L00_00258278((struct Moby *)moby, FUN_001f9e90(*(float *)(data + 0x150) - *(float *)(moby + 0x10), *(float *)(data + 0x154) - *(float *)(moby + 0x14)), + (float *)(data + 0x168), frame_time_sq * 2.0943952f, frame_time_sq * 0.6981317f, frame_time * 2.0943952f); + switch (*(int *)(data + 0x164)) { + case 0: + if (moby[0x53] != 7) FUN_00212f90(moby, 7, 0, random_int_between(0xA, 0xD)); + *(int *)(data + 0x160) = 0; + *(int *)(data + 0x164) = 1; + break; + case 1: + if ((*(u64 *)(moby + 0x50) & 0xFFFF0000) != 0x07070000 && moby[0x53] != 7) { + FUN_00212f90(moby, 7, 0, random_int_between(0xA, 0xD)); + } + if (moby[0x52] == 7) { + if (FUN_0020c9e0(moby) >= 9.5f) { + FUN_L00_0024f7c8(moby, 0, &velocity); + FUN_L00_0024f7c8(moby, 1, &direction); + add_vector_xyz(&position, &velocity, &direction); + scale_vector_xyz(&position, &position, 0.5f); + qcopy(data + 0x110, &position); + subtract_vector_xyz(data + 0x130, data + 0x150, data + 0x110); + normalize_vector_xyz(data + 0x130, data + 0x130, frame_scale); + *(int *)(data + 0x164) = 2; + } + } + break; + case 2: + if ((*(u64 *)(moby + 0x50) & 0xFFFF0000) != 0x07070000 && moby[0x53] != 7) { + FUN_00212f90(moby, 7, 0, random_int_between(7, 0xA)); + } + if (tick_countdown_32_alt((int *)(data + 0x160))) { + *(int *)(data + 0x160) = scale_ticks(0xA); + FUN_L07_0029b8d8((char *)moby, 0, 800000.0f, 5.0f); + FUN_L07_0029b8d8((char *)moby, 1, 800000.0f, 5.0f); + } + if (FUN_0020c9e0(moby) >= 31.5f) { + *(float *)(data + 0x16C) = 0.0f; + *(int *)(data + 0x164) = 3; + *(int *)(data + 0x11C) = 0; + } + break; + case 3: { + float r = FUN_001f9b80(moby + 0x10, &sight.position30); + *(float *)(data + 0x16C) += frame_scale; + if (r <= *(float *)(data + 0x16C)) *(int *)(data + 0x164) = 4; + if (tick_countdown_32_alt((int *)(data + 0x160))) *(int *)(data + 0x160) = scale_ticks(0x14); + FUN_001f4600(FUN_L07_003131b0, moby); + break; + } + case 4: + subtract_vector_xyz(&position, data + 0x120, data + 0x110); + normalize_vector_xyz(&position, &position, frame_scale); + add_vector_xyz(data + 0x110, data + 0x110, &position); + FUN_L07_00311eb8(moby, data, 3, data + 0x110, scale_ticks(0x1E), 0x800060FF, 0, 10.0f); + if (*(int *)(data + 0x164) != 0) { + if (tick_countdown_32_alt((int *)(data + 0x160))) *(int *)(data + 0x164) = 5; + } + FUN_001f4600(FUN_L07_003131b0, moby); + break; + case 5: + *(float *)(moby + 0x58) = 1.0f; + *(int *)(data + 0x164) = 0; + *(int *)(data + 0x160) = 0; + if (moby[0x53] != (FUN_001160d8() & 1)) { + int r1 = FUN_001160d8() & 1; + int r2 = random_int_between(0, 7); + FUN_00212f90(moby, r1, r2, random_int_between(0x1B, 0x2D)); + } + moby[0x20] = 1; + break; + } + break; + case 10: + if (*(int *)(data + 0x1B0) != -1) { + FUN_001ff570(*(int *)(data + 0x1B0), 0); + *(int *)(data + 0x1B0) = -1; + } + if (moby[0x70] & 2) { + normalize_vector_xyz(data + 0x100, data + 0x100, 1.0f); + *(float *)(data + 0x108) = 1.0f; + qcopy(&position, moby + 0x10); + position.f[2] = *(float *)(data + 0x1B8) + 1.0f; + FUN_L00_0025e450(moby, data + 0x100, &position, 0.0f, 0.0f, 0x14, 0xC, 0x40, 7.0f, 5.0f, 10.0f, 1.0f, -1, 50.0f, 1, 1, -1, 0); + *(unsigned short *)(moby + 0x34) |= 0x41; + if (*(int *)(data + 0x1CC) != -1) FUN_L06_002e6148(D_L07_0015FFD8 + (*(int *)(data + 0x1CC) << 8)); + moby[0x20] = 0x10; + *(float *)(moby + 0x18) = 20.0f; + } + break; + case 11: + if (moby[0x70] & 2) { + if (target_above) { + *(int *)(data + 0x164) = 0; + { char *g = ((char *)&hero); qcopy(data + 0x150, *(char **)(g + 0x2FC) + 0x10); } + *(float *)(data + 0x158) += 3.0f; + moby[0x20] = 9; + } else { + moby[0x20] = 1; + } + } + break; + case 16: + if (*(short *)(data + 0x280) != -1) FUN_L00_0023e838(*(short *)(data + 0x280)); + if (*(int *)(data + 0x1D0) == -1 || !(*(float *)(D_L07_0015FFD8 + (*(int *)(data + 0x1D0) << 8) + 0x18) < 34.5f)) { + mark_moby_for_removal(moby); + return; + } + *(float *)(D_L07_0015FFD8 + (*(int *)(data + 0x1D0) << 8) + 0x18) += + (34.6f - *(float *)(D_L07_0015FFD8 + (*(int *)(data + 0x1D0) << 8) + 0x18)) * 0.1f; + break; + case 17: + break; + } + subtract_vector_xyz(data + 0x100, moby + 0x10, &oldpos); + if (moby[0x20] < 0xA) FUN_L00_00259fe8((struct Moby *)moby, 2.5f); + FUN_L07_00312150((char *)data); +} +#endif #ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L07_00317910.s", FUN_L07_00317910); #else From 77cf12a18b2c4f9ea64597f9fdb7b70a2b71035c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:51:52 +0000 Subject: [PATCH 026/251] decomp: improve FUN_L00_002c97e0 --- .../shared/gameplay/entities/002c8440.c | 337 ++++++++++++++++++ 1 file changed, 337 insertions(+) diff --git a/src/overlays/shared/gameplay/entities/002c8440.c b/src/overlays/shared/gameplay/entities/002c8440.c index 4a149ac13..9b6862444 100644 --- a/src/overlays/shared/gameplay/entities/002c8440.c +++ b/src/overlays/shared/gameplay/entities/002c8440.c @@ -559,7 +559,344 @@ struct Moby *FUN_L00_002c9348(State *a) { } return n; } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L00_002c97e0.s", FUN_L00_002c97e0); +#else +extern f32 D_L00_0015F5D4_sda_2c97e0 __asm__("D_L00_0015F5D4") __attribute__((sda)); +extern f32 D_L00_0015F5D0_2c97e0 __asm__("D_L00_0015F5D0") __attribute__((section(".sdata"))); +extern f32 D_L00_0015F5D4_2c97e0 __asm__("D_L00_0015F5D4") __attribute__((section(".sdata"))); + +extern s32 D_L00_00161850_2c97e0 __asm__("D_L00_00161850") __attribute__((sda)); +extern f32 D_L00_00161858_2c97e0 __asm__("D_L00_00161858") __attribute__((sda)); +extern f32 D_L00_0016185C_2c97e0 __asm__("D_L00_0016185C") __attribute__((sda)); +extern f32 D_L00_00161860_2c97e0 __asm__("D_L00_00161860") __attribute__((sda)); +extern f32 D_L00_00161864_2c97e0 __asm__("D_L00_00161864") __attribute__((sda)); +extern f32 D_L00_00161868_2c97e0 __asm__("D_L00_00161868") __attribute__((sda)); +extern f32 D_L00_0016186C_2c97e0 __asm__("D_L00_0016186C") __attribute__((sda)); +extern s32 FUN_L00_00257b50_2c97e0(s32) __asm__("FUN_00213260"); +extern f32 FUN_L00_00257cb0_2c97e0(void) __asm__("FUN_00213308"); +extern void FUN_L00_00263ac8_2c97e0(struct Moby *, s32, void *, f32) __asm__("FUN_L00_00263ac8"); +extern void *FUN_L00_0025a420_2c97e0(void *, s32, s32) __asm__("FUN_L00_0025a420"); +extern s32 FUN_L00_00258490_2c97e0(void *, void *, void *, s32, f32, f32, f32, f32) __asm__("FUN_L00_00258490"); +extern void FUN_L00_00258278_2c97e0(void *, void *, f32, f32, f32, f32) __asm__("FUN_L00_00258278"); +extern s32 tick_timer_2cb418(void *) __asm__("FUN_001f9770"); +extern f32 vector_length_xyz_2cb418(void *) __asm__("FUN_001f9af0"); +extern f32 FUN_001fa688_2c97e0(void) __asm__("FUN_001fa688"); +extern s32 FUN_001fa6d0_2c97e0(f32) __asm__("FUN_001fa6d0"); +extern f32 distance_xy_2c97e0(void *, void *) __asm__("FUN_001f9b80"); +extern f32 distance_xyz_2c97e0(void *, void *) __asm__("FUN_001f9b48"); +extern f32 rotation_distance_2c97e0(f32, f32) __asm__("FUN_001fa688"); +extern f32 rotation_delta_2c97e0(f32, f32) __asm__("FUN_001fa5c8"); +extern void build_spherical_offset_2c97e0(void *, f32, f32, f32) __asm__("FUN_00214db0"); +extern void FUN_L00_0026ced0_2c97e0(void *, void *, u32, u32, s32, f32) __asm__("FUN_L00_0026ced0"); +extern s32 FUN_L00_001f2868_2c97e0(void *, s32, void *, s32, f32) __asm__("FUN_L00_001f2868"); +extern void FUN_L00_0025a9f8_2c97e0(void *, void *, s32, s32, s32, s32, s32, s32, f32, f32, f32) __asm__("FUN_L00_0025a9f8"); +extern void FUN_L00_0025e450_2c97e0(void *, void *, s32, s32, s32, s32, s32, s32, s32, s32, s32, f32, f32, f32, f32, f32, f32, f32) __asm__("FUN_L00_0025e450"); +extern void FUN_L00_002cbf68_2c97e0(void *, void *, void *) __asm__("FUN_L00_002cbf68"); +extern s32 FUN_L00_002dc9f0_2c97e0(void *, void *) __asm__("FUN_L00_002dc9f0"); +extern void FUN_L00_00257880_2c97e0(void *, s32, s32, s32) __asm__("FUN_00212f90"); +extern f32 FUN_L00_00259710_2c97e0(void *) __asm__("FUN_L00_00259710"); +extern f32 fabs_2c97e0(f32) __asm__("FUN_001f99c0"); +extern void normalize_2c97e0(void *, void *, f32) __asm__("FUN_001f9bf8"); + +/* Update for class 0x10e. State-specific inequalities and scale omissions + * follow the level-00 instructions, including the close state-3 step. */ +void FUN_L00_002c97e0(struct Moby *m) +{ + V4 old_pos, next_pos, velocity, offset; + Sub *s2 = (Sub *)m->pvars; + s32 result = 0; + s32 i, count, a, b, mode; + void *hit; + f32 angle, scale, speed, f, g, h, rotation; + f32 anim_speed = m->anim_speed; + angle = atan2_f_2c8440(m->pos.x - hero.motion.pos.f[0], m->pos.y - hero.motion.pos.f[1]); + if (m->state == 0) { + m->state = 1; + s2->unk66 = 0; + s2->unk70 = -1; + a = scale_game_frames(120); + b = scale_game_frames(300); + s2->unk64 = FUN_L00_00257b90(a, b); + s2->unk78 = 1.0f; + } + if (m->state == 6) return; + if (D_0013E520[0x15]) + FUN_L00_00263ac8_2c97e0(m, D_L00_00161850_2c97e0, (u8 *)s2 + 0x20, 5.0f); + else + FUN_L00_00263ac8_2c97e0(m, D_L00_00161850_2c97e0, (u8 *)s2 + 0x20, 7.7f); + qcopy(&old_pos, &m->pos); + if (s2->unk70 >= 0) { + if (tick_countdown_2c8440(&s2->unk70) && !m->visible) goto remove; + if (s2->unk70 >= 0) { + f = D_L00_0015F5D4_sda_2c97e0; + if ((f > 0.9f || D_L00_0015F5D0_2c97e0 > 0.9f) && !m->visible && s2->unk70 != -1) { + if (!FUN_L00_00257b50_2c97e0(199)) goto remove; + s2->unk70 = FUN_L00_00257b90(20, 30); + f = D_L00_0015F5D4_2c97e0; + } + if (f > 1.0f || D_L00_0015F5D0_2c97e0 > 1.0f) { + if (!m->visible) { + if (!FUN_L00_00257b50_2c97e0(24)) goto remove; + } else if (!FUN_L00_00257b50_2c97e0(99)) s2->unk78 = 0.0f; + else s2->unk70 = FUN_L00_00257b90(20, 30); + } + } + } + if ((s32)s2->unk74 > 0) { + f = FUN_001fa6c0(s2->unk74); + m->scale += ((f * 3.0f + 1.0f) * m->pclass->scale - m->scale) * 0.1f; + } + scale = m->scale / m->pclass->scale; + if (tick_countdown_2c8440((s32 *)((u8 *)s2 + 0x7c))) { + hit = FUN_L00_0025a420_2c97e0(m, -1, 0); + if (hit) { + FUN_0022da68_c(1, 0, m); + s2->unk78 -= *(f32 *)((u8 *)hit + 0x2c); + *(s32 *)((u8 *)s2 + 0x7c) = scale_game_frames(25); + } + } + m->hit_slot = 255; + if (s2->unk78 < 1.0f) { + if (s2->unk74 == 0) { + for (i = 0; i < (s32)FUN_001fa6d0_2c97e0(scale) * 20; i++) { + f = random_float_between(0.0f, 0.37f) * scale; + g = FUN_L00_00257cb0_2c97e0(); h = FUN_L00_00257cb0_2c97e0(); + build_spherical_offset_2c97e0(&offset, f, g, h); + offset.f[2] += random_float_between(0.25f, 0.5f) * scale; + add_vector_xyz_2c8440(&offset, &offset, &old_pos); + f = random_float_between(D_0015ED6C_2c8440 * 0.1f, D_0015ED6C_2c8440) * scale; + g = FUN_L00_00257cb0_2c97e0(); h = FUN_L00_00257cb0_2c97e0(); + build_spherical_offset_2c97e0(&velocity, f, g, h); + f = scale * 150000.0f; + a = scale_game_frames(30); b = scale_game_frames(57); + a = FUN_L00_00257b90(a, b); + FUN_L00_0026ced0_2c97e0(&offset, &velocity, 0x3f7f7f7f, 0x2f2f2f, a, f); + } + } else { + offset.q = 0; + offset.f[0] = frame_scale * 0.5f; + offset.f[1] = offset.f[0]; offset.f[2] = frame_scale * 0.7f; + velocity.q = offset.q; + FUN_L00_0025e450_2c97e0(m, &velocity, 0, 0, 0, 0, -1, 1, 1, -1, *(u8 *)&s2->unk74, 0.0f, 2.0f, 4.0f, 3.0f, 9.0f, 1.0f, 12.0f); + a = FUN_L00_001f2868_2c97e0(&m->pos, 16, m, 0, 3.0f); + offset.q = ((V4 *)&m->pos)->q; + FUN_L00_0025a9f8_2c97e0(m, &offset, 0x177f00, a, 0, 0x830000, 2, 1, 1.0f, 1.0f, 1.0f); + } + count = FUN_L00_00257b90(5, 8); + if (D_L00_0015F5D0_2c97e0 > 0.85f || D_L00_0015F5D4_2c97e0 > 0.85f) { + if (D_L00_0015F5D0_2c97e0 > 1.0f || D_L00_0015F5D4_2c97e0 > 1.0f) count = 1; + else count /= 2; + } + if (count > 0) { + rotation = 0.017453292f; + do { + count--; + f = random_float_between(D_L00_00161868_2c97e0, D_L00_0016186C_2c97e0) * scale; + g = FUN_L00_00257cb0_2c97e0(); h = FUN_L00_00257cb0_2c97e0(); + build_spherical_offset_2c97e0(&offset, f, g, h); + offset.f[2] += D_L00_00161864_2c97e0 * scale; + add_vector_xyz_2c8440(&offset, &offset, &old_pos); + f = random_float_between(D_L00_0016185C_2c97e0 * D_0015ED6C_2c8440, D_L00_00161860_2c97e0 * D_0015ED6C_2c8440); + g = FUN_L00_00257cb0_2c97e0(); + build_spherical_offset_2c97e0(&velocity, f, g, D_L00_00161858_2c97e0 * rotation); + velocity.f[2] = random_float_between(3.5f, 5.5f) * D_0015ED6C_2c8440; + FUN_L00_002cbf68_2c97e0(m, &offset, &velocity); + } while (count != 0); + } + FUN_0022da68_c(1, 0, m); + if (s2->unk70 >= 0) goto remove; + m->collision = 0; + m->flags = (m->flags & 0xefff) | 0x41; + s2->unk74 = 0; m->state = 6; m->command = 0; + return; + } + if (tick_timer_2cb418(&s2->unk64)) { + a = FUN_L00_00257b50_2c97e0(100); + FUN_0022da68_c(a > 74, 0, m); + a = scale_game_frames(120); b = scale_game_frames(300); + s2->unk64 = FUN_L00_00257b90(a, b); + } + if (s2->unk70 < 0) speed = 0.333f; + else speed = (D_0015ED6C_2c8440 + D_0015ED6C_2c8440) * scale; + switch (m->state) { + case 1: + if (m->anim_flags & 2) { + a = FUN_L00_00257b50_2c97e0(2); + b = scale_game_frames(5); + FUN_L00_00257880_2c97e0(m, a == 0, 0, b); + } + if (tick_timer_2cb418(&s2->unk66) && distance_xy_2c97e0(&m->pos, &hero.motion.pos) < scale * 5.0f) { + next_pos.f[0] = FUN_001f9dc8(m->rot.z) * D_0015ED6C_2c8440 * scale; + next_pos.f[1] = FUN_001f9de0(m->rot.z) * D_0015ED6C_2c8440 * scale; + next_pos.f[2] = 0.0f; + add_vector_xyz_2c8440(&next_pos, &next_pos, &old_pos); + result = FUN_L00_00258490_2c97e0(m, &old_pos, &next_pos, 0, scale * 0.2f, scale * 0.5f, speed, 0.2617994f); + if (!result) { + angle = atan2_f_2c8440(old_pos.f[0] - m->pos.x, old_pos.f[1] - m->pos.y); + f = rotation_distance_2c97e0(m->rot.z, angle); + if (!(f < 1.5707964f) || !(scale * 0.01f < distance_xyz_2c97e0(&m->pos, &old_pos))) goto reset_timer_only; + } + m->state = 3; a = scale_game_frames(10); FUN_L00_00257880_2c97e0(m, 3, 0, a); break; + } + if (distance_xy_2c97e0(&m->pos, &hero.motion.pos) < scale * 5.0f && rotation_distance_2c97e0(angle, m->rot.z) > 0.5235988f) { + FUN_L00_00258490_2c97e0(m, &old_pos, &old_pos, 0, scale * 0.2f, scale * 0.5f, speed, 0.2617994f); + m->state = 2; a = scale_game_frames(10); FUN_L00_00257880_2c97e0(m, 3, 0, a); break; + } +idle_move: + FUN_L00_00258490_2c97e0(m, &old_pos, &old_pos, 0, scale * 0.2f, scale * 0.5f, speed, 0.2617994f); + break; + case 2: + rotation = 0.5f; + FUN_L00_00258278_2c97e0(m, (u8 *)s2 + 0x68, angle, D_0015ED70_2c8440 * 0.7853982f, D_0015ED70_2c8440 * 1.5707964f, D_0015ED6C_2c8440 * 0.7853982f); + FUN_L00_00258490_2c97e0(m, &old_pos, &old_pos, 0, scale * 0.2f, scale * rotation, speed, 0.2617994f); + if (tick_timer_2cb418(&s2->unk66) && distance_xy_2c97e0(&m->pos, &hero.motion.pos) < scale * 5.0f) { + next_pos.f[0] = FUN_001f9dc8(m->rot.z) * D_0015ED6C_2c8440 * scale; + next_pos.f[1] = FUN_001f9de0(m->rot.z) * D_0015ED6C_2c8440 * scale; + next_pos.f[2] = 0.0f; + add_vector_xyz_2c8440(&next_pos, &next_pos, &old_pos); + f = probe_ground_height(&next_pos, 0, rotation); + f = fabs_2c97e0(f - next_pos.f[2]); + if (f <= (D_0015ED6C_2c8440 + D_0015ED6C_2c8440) * scale) { + m->state = 3; a = scale_game_frames(10); FUN_L00_00257880_2c97e0(m, 3, 0, a); break; + } + break; + } + if (rotation_distance_2c97e0(angle, m->rot.z) < 0.08726646f) goto reset_state; + if (scale * 6.0f < distance_xy_2c97e0(&m->pos, &hero.motion.pos)) goto reset_state; + break; + case 3: + if (scale * 6.0f < distance_xy_2c97e0(&m->pos, &hero.motion.pos)) { + m->state = 1; + a = scale_game_frames(60); b = scale_game_frames(180); + s2->unk66 = FUN_L00_00257b90(a, b); + a = FUN_L00_00257b50_2c97e0(2); b = scale_game_frames(5); + FUN_L00_00257880_2c97e0(m, a == 0, 0, b); + goto idle_move; + } + if (!(distance_xy_2c97e0(&m->pos, &hero.motion.pos) < scale * 3.0f)) { + FUN_L00_00258278_2c97e0(m, (u8 *)s2 + 0x68, angle, D_0015ED70_2c8440 * 0.7853982f, D_0015ED70_2c8440 * 1.5707964f, D_0015ED6C_2c8440 * 0.7853982f); + rotation = 1.5707964f; + next_pos.f[0] = FUN_001f9dc8(m->rot.z) * D_0015ED6C_2c8440 * scale; + next_pos.f[1] = FUN_001f9de0(m->rot.z) * D_0015ED6C_2c8440; + goto move_scaled; + } + FUN_L00_00258278_2c97e0(m, (u8 *)s2 + 0x68, angle, D_0015ED70_2c8440 * 0.7853982f, D_0015ED70_2c8440 * 1.5707964f, D_0015ED6C_2c8440 * 0.7853982f); + rotation = 1.5707964f; + next_pos.f[0] = FUN_001f9dc8(m->rot.z) * (D_0015ED6C_2c8440 + D_0015ED6C_2c8440); + next_pos.f[1] = FUN_001f9de0(m->rot.z) * (D_0015ED6C_2c8440 + D_0015ED6C_2c8440); + next_pos.f[2] = 0.0f; + add_vector_xyz_2c8440(&next_pos, &next_pos, &old_pos); + result = FUN_L00_00258490_2c97e0(m, &old_pos, &next_pos, 0, scale * 0.2f, scale * 0.5f, speed, 0.2617994f); + if (!result) { + angle = atan2_f_2c8440(old_pos.f[0] - m->pos.x, old_pos.f[1] - m->pos.y); + f = rotation_distance_2c97e0(m->rot.z, angle); + if (rotation < f || distance_xyz_2c97e0(&m->pos, &old_pos) < scale * 0.01f) goto reset_state; + } + m->state = 4; a = scale_game_frames(10); FUN_L00_00257880_2c97e0(m, 2, 0, a); break; + case 4: + result = tick_timer_2cb418(&s2->unk66); + if (result && scale * 4.0f < distance_xy_2c97e0(&m->pos, &hero.motion.pos)) { + FUN_L00_00258278_2c97e0(m, (u8 *)s2 + 0x68, angle, D_0015ED70_2c8440 * 0.7853982f, D_0015ED70_2c8440 * 1.5707964f, D_0015ED6C_2c8440 * 0.7853982f); + rotation = 1.5707964f; + next_pos.f[0] = FUN_001f9dc8(m->rot.z) * D_0015ED6C_2c8440 * scale; + next_pos.f[1] = FUN_001f9de0(m->rot.z) * D_0015ED6C_2c8440 * scale; + next_pos.f[2] = 0.0f; + add_vector_xyz_2c8440(&next_pos, &next_pos, &old_pos); + result = FUN_L00_00258490_2c97e0(m, &old_pos, &next_pos, 0, scale * 0.2f, scale * 0.5f, speed, 0.2617994f); + if (!result) { + angle = atan2_f_2c8440(old_pos.f[0] - m->pos.x, old_pos.f[1] - m->pos.y); + f = rotation_distance_2c97e0(m->rot.z, angle); + if (rotation < f || distance_xyz_2c97e0(&m->pos, &old_pos) < scale * 0.01f) goto reset_state; + } + m->state = 3; a = scale_game_frames(10); FUN_L00_00257880_2c97e0(m, 3, 0, a); break; + } + FUN_L00_00258278_2c97e0(m, (u8 *)s2 + 0x68, angle, D_0015ED70_2c8440 * 0.7853982f, D_0015ED70_2c8440 * 1.5707964f, D_0015ED6C_2c8440 * 0.7853982f); + rotation = 1.5707964f; + next_pos.f[0] = FUN_001f9dc8(m->rot.z) * (D_0015ED6C_2c8440 + D_0015ED6C_2c8440) * scale; + next_pos.f[1] = FUN_001f9de0(m->rot.z) * (D_0015ED6C_2c8440 + D_0015ED6C_2c8440); +move_scaled: + next_pos.f[1] *= scale; + next_pos.f[2] = 0.0f; + add_vector_xyz_2c8440(&next_pos, &next_pos, &old_pos); + result = FUN_L00_00258490_2c97e0(m, &old_pos, &next_pos, 0, scale * 0.2f, scale * 0.5f, speed, 0.2617994f); + if (!result) { + angle = atan2_f_2c8440(old_pos.f[0] - m->pos.x, old_pos.f[1] - m->pos.y); + f = rotation_distance_2c97e0(m->rot.z, angle); + if (rotation < f || distance_xyz_2c97e0(&m->pos, &old_pos) < scale * 0.01f) goto reset_state; + } + break; +reset_state: + m->state = 1; + a = scale_game_frames(60); b = scale_game_frames(180); + s2->unk66 = FUN_L00_00257b90(a, b); + a = FUN_L00_00257b50_2c97e0(2); mode = a == 0; a = scale_game_frames(5); + goto animate; +reset_timer_only: + a = scale_game_frames(60); b = scale_game_frames(180); + s2->unk66 = FUN_L00_00257b90(a, b); + break; +animate: + FUN_L00_00257880_2c97e0(m, mode, 0, a); + break; + case 5: + result = FUN_L00_002dc9f0_2c97e0(m, s2->unk10); + if (result) { m->state = 0; *(u16 *)((u8 *)s2->unk14 + 0x68) = 0; } + if (FUN_L00_00257b50_2c97e0(4)) return; + rotation = 0.017453292f; + f = random_float_between(D_L00_00161868_2c97e0, D_L00_0016186C_2c97e0) * scale; + g = FUN_L00_00257cb0_2c97e0(); h = FUN_L00_00257cb0_2c97e0(); + build_spherical_offset_2c97e0(&offset, f, g, h); + offset.f[2] += D_L00_00161864_2c97e0 * scale; + add_vector_xyz_2c8440(&offset, &offset, &old_pos); + f = random_float_between(D_L00_0016185C_2c97e0 * D_0015ED6C_2c8440, D_L00_00161860_2c97e0 * D_0015ED6C_2c8440); + g = FUN_L00_00257cb0_2c97e0(); + build_spherical_offset_2c97e0(&velocity, f, g, D_L00_00161858_2c97e0 * rotation); + velocity.f[2] = random_float_between(3.5f, 5.5f) * D_0015ED6C_2c8440; + FUN_L00_002cbf68_2c97e0(m, &offset, &velocity); + return; + } + if (!result) { + subtract_vector_xyz_2c8440(&velocity, &old_pos, &m->pos); + f = vector_length_xyz_2cb418(&velocity); + if (D_0015ED6C_2c8440 * scale < f) + normalize_2c97e0(&velocity, &velocity, D_0015ED6C_2c8440 * scale); + add_vector_xyz_2c8440(&old_pos, &m->pos, &velocity); + f = FUN_L00_00259710_2c97e0(&old_pos); + g = fabs_2c97e0(f - m->pos.z); + f = D_0015ED70_2c8440; + if (!(g <= D_0015ED6C_2c8440 * scale)) goto gravity; + } + qcopy(&m->pos, &old_pos); + f = D_0015ED70_2c8440; +gravity: + *(f32 *)((u8 *)s2 + 0x6c) += f * 9.8f; + m->pos.z -= *(f32 *)((u8 *)s2 + 0x6c); + f = probe_ground_height(&m->pos, 0, 0.5f); + if (m->pos.z < f && f < m->pos.z + scale * 0.25f) { + *(f32 *)((u8 *)s2 + 0x6c) = 0.0f; m->pos.z = f; + } + if (!FUN_001f0b58_2c8440()) s2->unk78 = 0.0f; + if (m->state != 5) { + m->pos.z = D_L00_00173E40.f28; + qcopy(&velocity, &D_L00_00173E40.v40); + f = FUN_001f9dc8(m->rot.z); g = FUN_001f9de0(m->rot.z); + offset.f[0] = velocity.f[0] * f + velocity.f[1] * g; + f = FUN_001f9dc8(m->rot.z); g = FUN_001f9de0(m->rot.z); + offset.f[1] = velocity.f[1] * f - velocity.f[0] * g; + offset.f[2] = velocity.f[2]; + f = -atan2_f_2c8440(FUN_001f9988(offset.f[0] * offset.f[0] + offset.f[2] * offset.f[2]), offset.f[1]); + angle = atan2_f_2c8440(offset.f[2], offset.f[0]); + f = rotation_delta_2c97e0(f, m->rot.x); + m->rot.x = fast_add_rotations_2c8440(m->rot.x, f * (D_0015ED6C_2c8440 * 6.2831855f)); + f = rotation_delta_2c97e0(angle, m->rot.y); + m->rot.y = fast_add_rotations_2c8440(m->rot.y, f * (D_0015ED6C_2c8440 * 6.2831855f)); + } + if (!(m->pos.z < 0.0f)) { m->anim_speed = anim_speed; return; } +remove: + mark_moby_for_removal(m); +} +#endif #define NOT_SDA #define MACRO_ADDR From 2bb51d32fbfe4a35c7f5f97e2d6bbca79f2cdbb1 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:55:51 +0000 Subject: [PATCH 027/251] decomp: improve FUN_L01_00234358 --- src/overlays/shared/ui/help/00226f10.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/ui/help/00226f10.c b/src/overlays/shared/ui/help/00226f10.c index 8610bf1ef..6da558436 100644 --- a/src/overlays/shared/ui/help/00226f10.c +++ b/src/overlays/shared/ui/help/00226f10.c @@ -1300,8 +1300,7 @@ extern void add_vector_xyz_34358(void *, void *, void *) __asm__("FUN_001f9a10") extern void FUN_001f9c48_34358(void *, void *, f32) __asm__("FUN_001f9c48"); extern f32 vector_length_xy_34358(void *) __asm__("FUN_001f9b20"); -void air_accel(float amount) __asm__("FUN_L01_00234358"); -void air_accel(float amount) { +void FUN_L01_00234358(float amount) { f32 delta[4]; Vec4 *velocity; Vec4 saved; @@ -1362,10 +1361,12 @@ void air_accel(float amount) { } else if (factor > 3.0f) { factor = 3.0f; } + /* Keep the lower clamp in the single-precision amount multiplication. */ if (factor < min_factor) - factor = min_factor; + amount *= min_factor; + else + amount *= factor; velocity = &hero.motion.velocity; - amount *= factor; subtract_vector_xyz_34358(delta, delta, velocity); length = vector_length_xy_34358(delta); if (amount < length) @@ -1373,7 +1374,7 @@ void air_accel(float amount) { add_vector_xyz_34358(velocity, velocity, delta); /* velocity is at hero + 0xE0; retail keeps this base for the copy. */ saved.q = ((struct Hero *)((char *)velocity - 0xE0))->move_impulse.q; - ((struct Hero *)((char *)velocity - 0xE0))->ground_speed = ((struct Hero *)((char *)velocity - 0xE0))->motion.unk168 - FUN_L00_00213350_34358(&saved); + hero.ground_speed = hero.motion.unk168 - FUN_L00_00213350_34358(&saved); return; nonzero_mode: velocity = &hero.motion.velocity; From eea7bfdb77aef29c2861455f671934df6bfe6daf Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:58:10 +0000 Subject: [PATCH 028/251] decomp: improve FUN_L00_0020a9e8 --- src/overlays/shared/ui/help/00203b18.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/ui/help/00203b18.c b/src/overlays/shared/ui/help/00203b18.c index ec3bdc2d7..4f1dfb05c 100644 --- a/src/overlays/shared/ui/help/00203b18.c +++ b/src/overlays/shared/ui/help/00203b18.c @@ -2798,7 +2798,7 @@ extern s32 FUN_001fef20_a9e8(s32) __asm__("FUN_L00_001fef20"); extern f32 FUN_L00_00257be8_a9e8(f32, f32) __asm__("FUN_L00_00257be8"); void FUN_L00_0020a9e8(void) { - G_a540 *g = &D_0013F350_a540; + struct Hero *g = &hero; char *base = (char *)g; s32 *timers; s32 *check_timer; @@ -2807,13 +2807,13 @@ void FUN_L00_0020a9e8(void) { struct HeroEase *output; s32 i; - if (g->i2084 != 0 || *(u8 *)((char *)g->p2080 + 0x53) != 0) + if (g->state.current != 0 || *(u8 *)((char *)g->moby + 0x53) != 0) return; timers = (s32 *)(base + 0x1060); - check_timer = timers; output = D_L00_0017A680_002054e8; i = 0; + check_timer = timers; record = base; store_timer = check_timer; do { @@ -2868,6 +2868,7 @@ void FUN_L00_0020a9e8(void) { i++; } while (i < 4); } + #endif /* Ported from rac1-decomp (src/overlays/shared/help_00203E98.c: func_L00_0020B310), where it is exact; names translated to the US level program. */ From 64d99facb45b84755330cc6338fd14cefa66883e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:58:17 +0000 Subject: [PATCH 029/251] decomp: improve FUN_L00_00276908 --- src/overlays/shared/audio/voices/00276368.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index 85e29fb5c..9fc1c55b9 100644 --- a/src/overlays/shared/audio/voices/00276368.c +++ b/src/overlays/shared/audio/voices/00276368.c @@ -280,12 +280,15 @@ void FUN_L00_00276908(void) { } D_L00_001B9CF0.owner = 0; } - for (i = 0; i < 4; i++) { - if (D_00141660[i] != ((s32 *)((u8 *)&D_L00_001B9CF0 + 0x30))[i]) { - hero.pending_item[i] = - ((s32 *)((u8 *)&D_L00_001B9CF0 + 0x30))[i] != 0 - ? ((s32 *)((u8 *)&D_L00_001B9CF0 + 0x30))[i] - : 0x26; + { + s32 i; + for (i = 0; i < 4; i++) { + if (D_00141660[i] != ((s32 *)((u8 *)&D_L00_001B9CF0 + 0x30))[i]) { + hero.pending_item[i] = + ((s32 *)((u8 *)&D_L00_001B9CF0 + 0x30))[i] != 0 + ? ((s32 *)((u8 *)&D_L00_001B9CF0 + 0x30))[i] + : 0x26; + } } } { From b517c82a6916ff5eeb03c048836523f5852ad29b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:04:35 +0000 Subject: [PATCH 030/251] decomp: improve FUN_L05_00254358 --- src/overlays/shared/ui/help/00237488.c | 39 +++++++++++++++----------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/overlays/shared/ui/help/00237488.c b/src/overlays/shared/ui/help/00237488.c index 6fbaa101a..c70273748 100644 --- a/src/overlays/shared/ui/help/00237488.c +++ b/src/overlays/shared/ui/help/00237488.c @@ -1358,7 +1358,7 @@ typedef struct { } HelpPath; void FUN_L05_00254358(f32 *position, f32 *direction) { - struct Hero *g = &hero; + struct Hero *g; HelpPath *path; f32 height_limit; f32 best; @@ -1367,40 +1367,47 @@ void FUN_L05_00254358(f32 *position, f32 *direction) { HelpPathPoint point; HelpPathPoint *p; HelpPath *cursor; - char *origin = (char *)g + 0x80; - if (g->unk86C == 0) { - *(HelpPathPoint *)position = *(HelpPathPoint *)origin; - *(HelpPathPoint *)direction = *(HelpPathPoint *)(origin + 0x10); + + if (hero.unk86C == 0) { + qcopy(position, (char *)&hero + 0x80); + qcopy(direction, (char *)&hero + 0x90); return; } - path = (HelpPath *)D_L05_001B0930[*(s32 *)(*(char **)(g->unk86C + 0x78) + 0x24)]; + path = (HelpPath *)D_L05_001B0930[*(s32 *)(*(char **)(hero.unk86C + 0x78) + 0x24)]; best = 9999999.0f; index = 0; selected = 0; - p = path->points; + if (path->count > 0) { height_limit = 4.0f; + p = path->points; + g = &hero; cursor = path; do { f32 a; s32 next; + s32 count; f32 b; - a = FUN_001f9e90(cursor->points[0].x - *(f32 *)origin, cursor->points[0].y - *(f32 *)(origin + 4)); - next = (s32)((u32)index + ((u32)path->count + 2U)) % path->count; + a = FUN_001f9e90(cursor->points[0].x - g->motion.pos.f[0], cursor->points[0].y - g->motion.pos.f[1]); + count = path->count; + next = (s32)((u32)count + 2U); + next = (s32)((u32)index + (u32)next) % count; b = FUN_001f9e90(path->points[next].x - cursor->points[0].x, path->points[next].y - cursor->points[0].y); if (!(fast_difference_between_rotations(a, b) > 1.5707964f)) goto next_point; { if (current_level_index == 0x10 && g->unk8B4 != 0) { - f32 a = *(f32 *)((char *)g->unk8B4 + *(s16 *)((char *)g + 0x8C8) * 16 + 0x18); - f32 b = *(f32 *)((char *)g->unk8B4 + g->unk898 * 16 + 0x18); - f32 high = (a < b ? b : a) - cursor->points[0].z; + f32 a = ((HelpPath *)g->unk8B4)->points[*(s16 *)((char *)g + 0x8C8)].z; + f32 b = ((HelpPath *)g->unk8B4)->points[g->unk898].z; + f32 high = cursor->points[0].z; + if (a < b) high = b - high; + else high = a - high; if (absolute_float(high) > height_limit) { goto next_point; } } { - f32 distance = FUN_001f9b80(origin, p); + f32 distance = FUN_001f9b80((char *)&hero + 0x80, p); if (distance < best) { best = distance; selected = index; @@ -1408,14 +1415,14 @@ void FUN_L05_00254358(f32 *position, f32 *direction) { } } next_point: - index = (s32)((u32)((char *)cursor - (char *)path) / 16U) + 2; + index += 2; p += 2; cursor = (HelpPath *)((char *)cursor + 0x20); } while (index < path->count); } p = &path->points[selected]; - *(HelpPathPoint *)position = *p; - point = *(HelpPathPoint *)position; + qcopy(position, p); + qcopy(&point, position); point.z += 2.0f; position[2] = find_ground_height(0.5f, &point, 0); clear_u64_value(direction); From 54f7d0d4d5dbc10722391cfad94b6c87257b56d7 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:05:51 +0000 Subject: [PATCH 031/251] decomp: improve FUN_L00_001fcca0 --- .../shared/rendering/texture/001fcb28.c | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/overlays/shared/rendering/texture/001fcb28.c b/src/overlays/shared/rendering/texture/001fcb28.c index 7ac0bf7a4..588e68c40 100644 --- a/src/overlays/shared/rendering/texture/001fcb28.c +++ b/src/overlays/shared/rendering/texture/001fcb28.c @@ -90,33 +90,35 @@ void FUN_L00_001fcca0(LevelTextEntry *entry, s32 frame) { source = get_help_message_text(entry->text_id); if (entry->separator_mode == 1) { out = buffer; - next = out; - ch = (u8)*source; - while (ch != 0) { - out = next; - if (ch == 1) { - *out++ = ' '; - *out++ = '-'; - *out++ = ' '; - ch = *source; - while ((u8)ch == 1) { - source++; + ch = *source; +joined_text: + if (ch != 0) { + do { + if ((u8)ch == 1) { + *out++ = ' '; + *out++ = '-'; + *out++ = ' '; + while (*source == 1) + source++; ch = *source; + if (ch != 0) + goto joined_text; + out -= 3; + break; + } else { + *out = ch; + source++; + out++; } - next = out; - if (ch == 0) - next -= 3; - } else { - *out = ch; - source++; - out++; - next = out; - ch = *source; - } + } while ((ch = *source) != 0); + } + { + s32 mode = entry->mode; + s32 x = entry->x; + y = entry->y; + *out = 0; + FUN_L00_001fcb28(x, y, mode, buffer, scale, alpha); } - out = next; - *out = 0; - FUN_L00_001fcb28(entry->x, entry->y, entry->mode, buffer, scale, alpha); } else { y = entry->y; out = buffer; From 536319d628bf0c98085e479932d4b0f234002834 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:04:46 +0000 Subject: [PATCH 032/251] decomp: improve FUN_L04_002923b8 --- src/overlays/l04/runtime/dma/002922d0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/l04/runtime/dma/002922d0.c b/src/overlays/l04/runtime/dma/002922d0.c index 05eefea94..447d067c4 100644 --- a/src/overlays/l04/runtime/dma/002922d0.c +++ b/src/overlays/l04/runtime/dma/002922d0.c @@ -87,14 +87,14 @@ void FUN_L04_002923b8(char *arg0, char *arg1) { LegRigAnim *item = *slot; float start = item->phase[1].from[j]; float end = item->phase[1].to[j]; - current = &item->phase[1].span[j]; + current = (float *)((char *)item + 0x38 + offset); if (start <= end) difference = end - start; else difference = (end + item->len) - start; *current = difference; item = *slot; - current = &item->phase[0].span[j]; + current = (float *)((char *)item + 0x20 + offset); start = item->phase[0].from[j]; end = item->phase[0].to[j]; if (start <= end) From b44dec75b33623d9c3c8e47a2685765ef7a5a79c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:10:55 +0000 Subject: [PATCH 033/251] decomp: improve update_hero_held_items_and_orientation --- src/overlays/shared/ui/help/0020c758.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index 4a728be1f..a44688a31 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -1012,32 +1012,35 @@ void FUN_L00_0020e728(void) { u8 **slot; int i; u128 *basis; + struct Hero *hero_state; if (hero.unk20A8 && hero.unk20AA && get_ammo(-1) == 0) FUN_L00_0020e698(); i = 0; slot = hero.unkD08; + hero_state = (struct Hero *)((u8 *)slot - 0xD08); do { if (*slot != 0) { int id = FUN_L00_0020d498_c(0); - if (id == hero.unk2298) { + if (id == hero_state->unk2298) { s32 anim; ID_20e4c8 *definition = &D_L00_00179AC0_c[id]; - if (hero.state.control_mode == 12) + if (hero_state->state.control_mode == 12) anim = definition->f2C; else anim = definition->f28; if (anim != -1 && (*slot)[0x23] != anim) { - hero.unk2294 = anim; - FUN_L00_0024f3e0((u8 *)hero.moby, *slot, hero.unk2294, 0, + hero_state->unk2294 = anim; + FUN_L00_0024f3e0((u8 *)hero_state->moby, *slot, hero_state->unk2294, 0, FUN_001f96f8_e728(8), 1); } } FUN_L00_0024f190((u8 *)hero.moby, *slot); if (hero.unkD14 != 0) { + f32 scale = frame_scale; if (hero.unkD14 == 2) - FUN_00213ed8_e728((f32 *)(*slot + 8), 0.0f, frame_scale * 0.25f); + FUN_00213ed8_e728((f32 *)(*slot + 8), 0.0f, scale * 0.25f); else - FUN_00213ed8_e728((f32 *)(*slot + 8), 0.0f, frame_scale * 0.07f); + FUN_00213ed8_e728((f32 *)(*slot + 8), 0.0f, scale * 0.07f); if (*(f32 *)(*slot + 8) == 0.0f) { FUN_L00_0024f0e8((u8 *)hero.moby, slot); return; From ab99b0d7db72ef5e9b3ee6a17badc8df76f6708e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:11:19 +0000 Subject: [PATCH 034/251] decomp: improve FUN_L12_00308350 --- src/overlays/l12/gameplay/vendor/003028c8.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/overlays/l12/gameplay/vendor/003028c8.c b/src/overlays/l12/gameplay/vendor/003028c8.c index 878e90ce7..de7ab7914 100644 --- a/src/overlays/l12/gameplay/vendor/003028c8.c +++ b/src/overlays/l12/gameplay/vendor/003028c8.c @@ -1545,18 +1545,23 @@ void FUN_L12_00308350(struct Moby *m) { qcopy(&matrix[3], &m->pos); matrix[3][3] = 1.0f; first.texture = get_effect_texture_l12(0xe); - flags = (long)D_L12_00161FBC | (long)D_L12_00161FC0 << 2 | - (long)D_L12_00161FC4 << 4 | (long)D_L12_00161FC8 << 6 | - 0x8000000000L; - second_flags = (long)D_L12_00161FCC | (long)D_L12_00161FD0 << 2 | - (long)D_L12_00161FD4 << 4 | (long)D_L12_00161FD8 << 6 | - 0x8000000000L; + flags = (long)D_L12_00161FBC; + second_flags = (long)D_L12_00161FCC; + flags |= (long)D_L12_00161FC0 << 2; + flags |= (long)D_L12_00161FC4 << 4; + flags |= (long)D_L12_00161FC8 << 6; + second_flags |= (long)D_L12_00161FD0 << 2; + second_flags |= (long)D_L12_00161FD4 << 4; + second_flags |= (long)D_L12_00161FD8 << 6; + flags |= 0x8000000000L; + second_flags |= 0x8000000000L; first.gs_state = flags; second.gs_state = second_flags; first.texture_state = 0xFF9000000260L; second.texture_state = 0xFF9000000260L; + first.tag = 0; + second.tag = 0; second.texture = first.texture; - first.tag = second.tag = 0; first.color[0] = first.color[1] = first.color[2] = first.color[3] = D_L12_00161F90; second.color[0] = second.color[1] = second.color[2] = second.color[3] = D_L12_00161F94; j = 0; From f8f4daad80ad78e008d22b154025cccd8513222b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:14:26 +0000 Subject: [PATCH 035/251] decomp: improve FUN_L11_00310cf8 --- src/overlays/shared/gameplay/vendor/0030e690.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/0030e690.c b/src/overlays/shared/gameplay/vendor/0030e690.c index 8cff4de8d..8141753e3 100644 --- a/src/overlays/shared/gameplay/vendor/0030e690.c +++ b/src/overlays/shared/gameplay/vendor/0030e690.c @@ -214,7 +214,8 @@ void FUN_L11_00310cf8(float x, float y, float width, float height, float angle, vertical[0] = height * fast_sin(angle); vertical[1] = height * fast_cos(angle); horizontal[0] = width * fast_cos(angle); - horizontal[1] = -width * fast_sin(angle); + width = -width; + horizontal[1] = width * fast_sin(angle); add_vector_xyz(top_left, center, vertical); subtract_vector_xyz(top_left, top_left, horizontal); add_vector_xyz(bottom_left, center, vertical); @@ -225,6 +226,7 @@ void FUN_L11_00310cf8(float x, float y, float width, float height, float angle, ((int *)(*(volatile int *)&D_L11_001611C0_g))[0] = 0x10000007; ((int *)(*(volatile int *)&D_L11_001611C0_g))[1] = 0; ((int *)(*(volatile int *)&D_L11_001611C0_g))[2] = 0; + packed_depth = (unsigned long long)saved_depth[0] << 32; ((int *)(*(volatile int *)&D_L11_001611C0_g))[3] = 0x50000007; tag = (int *)(*(volatile int *)&D_L11_001611C0_g); q = (unsigned long long *)(tag + 4); @@ -236,7 +238,6 @@ void FUN_L11_00310cf8(float x, float y, float width, float height, float angle, q[4] = (unsigned long long)(red & 0xff) | ((unsigned long long)(green & 0xff) << 8) | ((unsigned long long)(blue & 0xff) << 16) | ((unsigned long long)(alpha & 0xff) << 24); q[5] = 0x100010; - packed_depth = (unsigned long long)saved_depth[0] << 32; texture_width <<= 4; texture_height <<= 20; sx = ftoi_g(top_left[0] * 16.0f); From 11b6e4e9f01fcdbbcdad5498ac79817d0965b356 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:14:41 +0000 Subject: [PATCH 036/251] decomp: improve scan_hero_input_sequences --- src/overlays/shared/ui/help/00203b18.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/ui/help/00203b18.c b/src/overlays/shared/ui/help/00203b18.c index 4f1dfb05c..57e09d429 100644 --- a/src/overlays/shared/ui/help/00203b18.c +++ b/src/overlays/shared/ui/help/00203b18.c @@ -1000,6 +1000,7 @@ void FUN_L00_00206e00(void) { s32 input; s32 level; s32 i, j, length, position; + u8 *end; u8 *sequence; u8 *history; volatile s32 *history_count; @@ -1075,7 +1076,9 @@ void FUN_L00_00206e00(void) { for (i = 0; i < 12; i++, sequence += 16) { length = 0; if (*sequence != 0) { - for (length = 1; sequence[length] != 0; length++) { } + end = sequence + 1; + length = 1; + while (*end != 0) { end++; length++; } } if (length != 0) { position = *history_count - length; From 231a29f621a64d29a04f456fdfa4cd213e8a0903 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:18:14 +0000 Subject: [PATCH 037/251] decomp: improve FUN_L00_00262030 --- src/overlays/shared/gameplay/state/00261968.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/overlays/shared/gameplay/state/00261968.c b/src/overlays/shared/gameplay/state/00261968.c index 442e7d429..5de0b6beb 100644 --- a/src/overlays/shared/gameplay/state/00261968.c +++ b/src/overlays/shared/gameplay/state/00261968.c @@ -243,20 +243,21 @@ s32 FUN_L00_00262030(f32 distance, s32 path_index, OvlVec4 *point, OvlVec4 *out) s32 next; s32 i; s32 offset; - OvlVec4 *volatile saved_out; - volatile s32 found; + OvlVec4 *saved_out; + s32 found; f32 original_height; f32 segment_length; f32 projection; + found = 0; saved_out = out; qcopy(&working, point); - found = 0; entry = D_L00_001B04B0_262030[path_index]; - original_height = FUN_001ff398_262030(&working, &D_0013F5E0_262030); + offset = (s32)&D_0013F5E0_262030; + original_height = FUN_001ff398_262030(&working, (OvlVec4 *)offset); + i = 0; if (entry->count - 1 > found) { - i = 0; - height_axis = &D_0013F5E0_262030; + height_axis = (OvlVec4 *)offset; do { offset = i << 4; next = i + 1; From fd6ac020dca06ca3f07e24bc4caeffe35a4c3e92 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:20:30 +0000 Subject: [PATCH 038/251] decomp: improve FUN_L00_0029ff58 --- .../shared/gameplay/entities/0029f990.c | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/0029f990.c b/src/overlays/shared/gameplay/entities/0029f990.c index 90a6cd9cd..e8ad2d7f8 100644 --- a/src/overlays/shared/gameplay/entities/0029f990.c +++ b/src/overlays/shared/gameplay/entities/0029f990.c @@ -172,7 +172,11 @@ extern int D_L00_001CA480[4][4]; extern float D_L00_001CA380[16][4]; extern float D_L00_001CA410[8][2]; extern int D_L00_001CA458[]; -extern char D_L00_001CA4C0_29ff58[] __asm__("D_L00_001CA4C0"); +typedef struct { + char pad[0x1c]; + char *f1C; +} L00ObjectState29ff58; +extern L00ObjectState29ff58 D_L00_001CA4C0_29ff58 __asm__("D_L00_001CA4C0"); extern long FUN_001f44b8_29ff58(int) __asm__("FUN_001f44b8"); extern void FUN_001f9cf8_29ff58(void *, void *, void *) __asm__("FUN_001f9cf8"); extern void FUN_001f7d30_29ff58(void *, int, int) __asm__("FUN_001f7d30"); @@ -183,7 +187,7 @@ void FUN_L00_0029ff58(void) { float *position; int offset; - volatile int i; + int i; int index0, index1, index2, index3; int *indices, *second, *third; D_L00_00161184 = D_L00_00161184 + 0.01f; @@ -199,13 +203,14 @@ void FUN_L00_0029ff58(void) { while (1) { offset = i * 16; i++; - FUN_001f9cf8_29ff58(transformed[0], D_L00_001CA380[indices[0]], *(char **)(D_L00_001CA4C0_29ff58 + 0x1c) + 0xc0); - second = (int *)((int)D_L00_001CA480 + offset + 4); - FUN_001f9cf8_29ff58(transformed[1], D_L00_001CA380[*second], *(char **)(D_L00_001CA4C0_29ff58 + 0x1c) + 0xc0); - third = (int *)((int)D_L00_001CA480 + offset + 8); - FUN_001f9cf8_29ff58(transformed[2], D_L00_001CA380[*third], *(char **)(D_L00_001CA4C0_29ff58 + 0x1c) + 0xc0); - FUN_001f9cf8_29ff58(transformed[3], D_L00_001CA380[indices[3]], *(char **)(D_L00_001CA4C0_29ff58 + 0x1c) + 0xc0); - position = (float *)(*(char **)(D_L00_001CA4C0_29ff58 + 0x1c)); + FUN_001f9cf8_29ff58(transformed[0], D_L00_001CA380[indices[0]], D_L00_001CA4C0_29ff58.f1C + 0xc0); + /* Each row is 16 bytes, so the low offset bits select its fields. */ + second = (int *)((int)D_L00_001CA480 + (offset | 4)); + FUN_001f9cf8_29ff58(transformed[1], D_L00_001CA380[*second], D_L00_001CA4C0_29ff58.f1C + 0xc0); + third = (int *)((int)D_L00_001CA480 + (offset | 8)); + FUN_001f9cf8_29ff58(transformed[2], D_L00_001CA380[*third], D_L00_001CA4C0_29ff58.f1C + 0xc0); + FUN_001f9cf8_29ff58(transformed[3], D_L00_001CA380[indices[3]], D_L00_001CA4C0_29ff58.f1C + 0xc0); + position = (float *)(D_L00_001CA4C0_29ff58.f1C); #define SET_POSITION(n) \ q.position[n][0] = position[4] + transformed[n][0]; \ q.position[n][1] = position[5] + transformed[n][1]; \ From a61c6f1533dbbdda057d8014843ae527271260ea Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:27:44 +0000 Subject: [PATCH 039/251] decomp: improve FUN_L11_003192c8 --- src/overlays/shared/gameplay/vendor/0030e690.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/vendor/0030e690.c b/src/overlays/shared/gameplay/vendor/0030e690.c index 8141753e3..1c53a61a3 100644 --- a/src/overlays/shared/gameplay/vendor/0030e690.c +++ b/src/overlays/shared/gameplay/vendor/0030e690.c @@ -431,7 +431,7 @@ int FUN_L11_003192c8(char *moby) { char stack_data[0x900] __attribute__((aligned(16))); float offset[8] __attribute__((aligned(16))); short *list; - int i, j; + int i; float phase; float *position_base; float *position_y_base; @@ -456,6 +456,7 @@ int FUN_L11_003192c8(char *moby) { float *position_y; int *colors; float span; + int j; j = 0; texture = trail_effect_texture(0x13); *(long long *)(packet + 0x38) = texture; @@ -495,6 +496,7 @@ int FUN_L11_003192c8(char *moby) { int a = next + 15; int b = next + 30; int start; + int j; if (limit < a) b = a; start = a - ((b >> 4) << 4); for (j = 0; j < 2; j++) { From 97e4db9c4fa151efde4b4670b69b865fca089b41 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:31:50 +0000 Subject: [PATCH 040/251] decomp: improve FUN_L00_002dd8e8 --- .../shared/gameplay/entities/002d7f88.c | 71 ++++++++++--------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002d7f88.c b/src/overlays/shared/gameplay/entities/002d7f88.c index 5b22ff076..028154272 100644 --- a/src/overlays/shared/gameplay/entities/002d7f88.c +++ b/src/overlays/shared/gameplay/entities/002d7f88.c @@ -2612,7 +2612,7 @@ typedef struct { float texcoords[8]; u64 texture[4]; } __attribute__((aligned(16))) Quad_002dd8e8; -extern float D_L00_00161B48_002dd8e8 __asm__("D_L00_00161B48") __attribute__((sda)); +extern float D_L00_00161B48_002dd8e8 __asm__("D_L00_00161B48") __attribute__((section(".data"))); extern char D_L00_001E6020_002dd8e8[] __asm__("D_L00_001E6020") __attribute__((section(".data"))); extern char D_L00_001E5EE0_002dd8e8[] __asm__("D_L00_001E5EE0") __attribute__((section(".data"))); u64 FUN_001f9298_002dd8e8(int) __asm__("FUN_L00_001f9298"); @@ -2627,7 +2627,8 @@ void FUN_L00_002dd8e8(void) { u128 following, edge, outward, normal; float phase, next_phase, offset, step, dot; int row, segment, next_segment, value, previous_value; - char *current, *prior; + int current; + char *prior; quad.texture[1] = FUN_001f9298_002dd8e8(0x15); quad.texture[2] = 0xff9000000260ULL; @@ -2640,49 +2641,51 @@ void FUN_L00_002dd8e8(void) { step = 0.05f; for (row = 1; row < 10; row++) { offset = ((float *)&D_L00_00161B48_002dd8e8)[-1]; - next_phase = phase + 0.3f; - phase = next_phase; - next_phase = phase + 0.3f; + phase += 0.3f; ((float *)&D_L00_00161B48_002dd8e8)[-1] += D_L00_00161B48_002dd8e8; if (((float *)&D_L00_00161B48_002dd8e8)[-1] > 7.0f) ((float *)&D_L00_00161B48_002dd8e8)[-1] -= 7.0f; - current = D_L00_001E6020_002dd8e8 + row * 0x140; - prior = D_L00_001E5EE0_002dd8e8 + row * 0x140; + next_phase = phase + 0.3f; + current = row * 0x140; + prior = D_L00_001E5EE0_002dd8e8; for (segment = 0; segment < 20; segment++) { + qcopy(&quad.points[0], D_L00_001E6020_002dd8e8 + current + segment * 16); next_segment = (segment + 1) % 20; - qcopy(&quad.points[0], current + segment * 16); - qcopy(&quad.points[1], current + next_segment * 16); - qcopy(&quad.points[2], prior + segment * 16); - qcopy(&quad.points[3], prior + next_segment * 16); + qcopy(&quad.points[1], D_L00_001E6020_002dd8e8 + current + next_segment * 16); + qcopy(&quad.points[2], prior + current + segment * 16); + qcopy(&quad.points[3], prior + current + next_segment * 16); FUN_001ff2a8_002dd8e8(&edge, &quad.points[0], &quad.points[1]); FUN_001ff2a8_002dd8e8(&outward, &quad.points[2], &quad.points[1]); FUN_001ff3c0_002dd8e8(&normal, &outward, &edge); FUN_001ff2a8_002dd8e8(&following, &quad.points[1], g_debug_camera); dot = FUN_001ff398_002dd8e8(&normal, &following); - if (!(0.0f <= dot)) { - value = ((short *)(D_L00_001E6020_002dd8e8 - 0x18))[row]; - previous_value = ((short *)(D_L00_001E6020_002dd8e8 - 0x18))[row - 1]; - if (value < 0) value = 0; - if (value > 0x40) value = 0x40; - if (previous_value < 0) previous_value = 0; - if (previous_value > 0x40) previous_value = 0x40; - quad.colors[0] = quad.colors[1] = (value << 24) | 0x404040; - quad.colors[2] = quad.colors[3] = (previous_value << 24) | 0x404040; - if (row == 1) - quad.colors[2] = quad.colors[3] = 0x20404040; - else if (row == 9) - quad.colors[0] = quad.colors[1] = 0x00404040; - quad.texcoords[0] = phase; - quad.texcoords[1] = offset; - quad.texcoords[2] = phase; - quad.texcoords[3] = offset + step; - quad.texcoords[4] = phase - 0.3f; - quad.texcoords[5] = offset; - quad.texcoords[6] = phase - 0.3f; - quad.texcoords[7] = offset + step; - FUN_001fd228_002dd8e8(&quad, 0, 0); + if (0.0f <= dot) { + offset += step; + continue; } - offset += step; + value = ((short *)(D_L00_001E6020_002dd8e8 - 0x18))[row]; + previous_value = ((short *)(D_L00_001E6020_002dd8e8 - 0x18))[row - 1]; + if (value < 0) value = 0; + if (value > 0x40) value = 0x40; + if (previous_value < 0) previous_value = 0; + if (previous_value > 0x40) previous_value = 0x40; + quad.colors[0] = quad.colors[1] = (value << 24) | 0x404040; + quad.colors[2] = quad.colors[3] = (previous_value << 24) | 0x404040; + if (row == 1) + quad.colors[2] = quad.colors[3] = 0x20404040; + else if (row == 9) + quad.colors[0] = quad.colors[1] = 0x00404040; + dot = offset + step; + quad.texcoords[0] = phase; + quad.texcoords[1] = offset; + quad.texcoords[2] = phase; + quad.texcoords[3] = dot; + quad.texcoords[4] = phase - 0.3f; + quad.texcoords[5] = offset; + quad.texcoords[6] = phase - 0.3f; + quad.texcoords[7] = dot; + offset = dot; + FUN_001fd228_002dd8e8(&quad, 0, 0); } phase = next_phase; } From 9915bc4daea3b52ffe8387dfcf58a34da0c7906b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:34:03 +0000 Subject: [PATCH 041/251] decomp: improve FUN_L07_0030dcf0 --- src/overlays/l07/gameplay/entities/002cd2b0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/l07/gameplay/entities/002cd2b0.c b/src/overlays/l07/gameplay/entities/002cd2b0.c index 0f8393342..0a8547428 100644 --- a/src/overlays/l07/gameplay/entities/002cd2b0.c +++ b/src/overlays/l07/gameplay/entities/002cd2b0.c @@ -2009,10 +2009,10 @@ void FUN_L07_0030dcf0(unsigned char *moby) { width = convert_integer_to_float_l07((int)(index + 1) > 5 ? 5 : index + 1); green = green - green_step; center = *(float *)(moby + 0x10); - *(float *)(packet + 0x34) = *(float *)(packet + 0x14) = *(float *)(moby + 0x14); *(float *)(packet + 0x38) = *(float *)(packet + 0x28) = *(float *)(moby + 0x18); *(float *)(packet + 0x30) = center - radius; *(float *)(packet + 0x68) = *(float *)(packet + 0x58) = *(float *)(packet + 0x50) + width; + *(float *)(packet + 0x34) = *(float *)(packet + 0x14) = *(float *)(moby + 0x14); *(float *)(packet + 0x6c) = *(float *)(packet + 0x64) = 1.0f; *(float *)(packet + 0x5c) = 0.0f; *(float *)(packet + 0x08) = *(float *)(packet + 0x18) = side + *(float *)(moby + 0x18); From ac1ad289e020fe6fdcb43ab28e830b9d1c4b74e6 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:34:35 +0000 Subject: [PATCH 042/251] decomp: improve FUN_L10_002f5b58 --- src/overlays/shared/gameplay/vendor/002e3de8.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index 2bed92efd..5b0db1875 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -324,14 +324,15 @@ void FUN_L10_002f5b58(char *moby) { angle_cursor++; index_cursor++; } - next = (i + 1) % *(int *)path; + count = i + 1; + next = count % *(int *)path; distance = FUN_001f9b48( (char *)((unsigned int)path + (offset + 0x10)), (char *)((unsigned int)path + ((unsigned int)next * 0x10 + 0x10))); *(float *)((unsigned int)path + offset + 0x1c) = distance; if (i < *(int *)path - 1) *(float *)(acc + 0x08) += distance; - i++; + i = count; } while (i < *(int *)path); } } From 8df4a4d9f069655d6f4cace5faf7b1d8095d6531 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:37:02 +0000 Subject: [PATCH 043/251] decomp: improve FUN_L05_00262b58 --- src/overlays/shared/ui/text/00262ae8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/ui/text/00262ae8.c b/src/overlays/shared/ui/text/00262ae8.c index fb51e5a35..9eec2298e 100644 --- a/src/overlays/shared/ui/text/00262ae8.c +++ b/src/overlays/shared/ui/text/00262ae8.c @@ -85,7 +85,7 @@ typedef struct { /* Retail accesses these names through the shared Hero base at 0x0013f350. */ #define D_001413D4 hero.state.current #define D_0013F65E hero.air_frames.s -#define D_0013F650 hero.unk300 +#define D_0013F650 hero.grounded_frames #define D_0013FA40 hero.unk6E0[4] #define D_0013FA5C (*(s32 *)&hero.pad_6FC[0x10]) #define D_0013FBB4 hero.unk864 From 15412cd3ba3f88644872ebff0e36fc5abb433448 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:39:12 +0000 Subject: [PATCH 044/251] decomp: improve FUN_L00_002464a8 --- src/overlays/shared/rendering/00245c28.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/rendering/00245c28.c b/src/overlays/shared/rendering/00245c28.c index e2551bf95..fe9c129e4 100644 --- a/src/overlays/shared/rendering/00245c28.c +++ b/src/overlays/shared/rendering/00245c28.c @@ -538,7 +538,8 @@ void FUN_L00_002464a8(void) { for (x = 0; x < 32; x++) { if ((15.5f - (f32)x) * (15.5f - (f32)x) + (15.5f - (f32)y) * (15.5f - (f32)y) > 256.0f) { - mask[x / 8 + y * 4] |= 1 << (x % 8); + i = x / 8; + mask[i + y * 4] |= 1 << (x - i * 8); } } } @@ -547,7 +548,7 @@ void FUN_L00_002464a8(void) { *(s32 *)0x184218 = 0; state->scratch_data = 0; state->mask_data = 0; - state->second_data = 0; + D_L00_001841F0_load.second_data = 0; } } #endif From 058ce48c9fa40cf05433e07fa9234d892b37fa70 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:41:19 +0000 Subject: [PATCH 045/251] decomp: improve FUN_L00_0020f160 --- src/overlays/shared/ui/help/0020c758.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index a44688a31..b610c542d 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -1337,7 +1337,7 @@ void FUN_L00_0020f160(void *moby, void *matrix) s32 i, j, n, chosen, ring, limit; volatile s32 count; f32 maximum; - s64 negative_one; + s64 negative_one = -1; u8 *record; f32 *score_ptr; void * volatile output; @@ -1382,8 +1382,8 @@ void FUN_L00_0020f160(void *moby, void *matrix) score_ptr = scores; for (i = 0; i < n; i++) { s32 a = (*(volatile s32 *)(hero.pad_21B8)) - (i - 15); - a -= ((a < 0 ? a + 15 : a) >> 4) * 16; - negative_one = -1; + a -= ((negative_one < a ? a : a + 15) >> 4) * 16; + for (j = 0; j < n; j++) { if (i != j) { s32 b = (*(volatile s32 *)(hero.pad_21B8)) - (j - 15); @@ -1412,7 +1412,7 @@ void FUN_L00_0020f160(void *moby, void *matrix) for (i = 0; i < n; i++) { if (!(maximum * 0.2f < scores[i]) || count < 1 || !limit) { s32 a = (*(volatile s32 *)(hero.pad_21B8)) - (i - 15); - a -= ((a < 0 ? a + 15 : a) >> 4) * 16; + a -= ((negative_one < a ? a : a + 15) >> 4) * 16; record = (hero.pad_12EF + 1) + a * 0x30; chosen++; for (j = 0; j < 3; j++) From 4aec1eada4297e60d555fb310ec9e38d855e6e51 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:43:40 +0000 Subject: [PATCH 046/251] decomp: improve FUN_L05_002f87a8 --- .../shared/gameplay/entities/002b3840.c | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b3840.c b/src/overlays/shared/gameplay/entities/002b3840.c index f2994ccac..1e5640a1e 100644 --- a/src/overlays/shared/gameplay/entities/002b3840.c +++ b/src/overlays/shared/gameplay/entities/002b3840.c @@ -279,17 +279,17 @@ extern int D_00151910_87a8 __asm__("D_00151910") __attribute__((sda)); void FUN_L05_002f87a8(unsigned char *moby) { char *data = *(char **)(moby + 0x78); - float position[4], delta[4], effect_position[4], offset[4], second_position[4]; - float *delta_ptr = delta; + float delta[4], position[4], effect_position[4], offset[4], second_position[4]; float angle, distance_scale, delta_length; int state = (u8)moby[0x20]; + struct Hero *g = &hero; - if (state != 1) { - if (state < 2 && state == 0) { - if (distance_xyz_87a8(&hero.motion.pos, moby + 0x10) < 5.5f && - D_0014F5CC_87a8 > 3 && *(int *)0x1413dc != 0x15 && - *(int *)0x1413dc != 0x16) { - *(char **)0x13fbbc = moby; + switch (state) { + case 0: + if (distance_xyz_87a8(&g->motion.pos, moby + 0x10) < 5.5f && + D_0014F5CC_87a8 > 3 && g->state.control_mode != 0x15 && + g->state.control_mode != 0x16) { + g->unk86C = moby; FUN_L05_0024cee8_87a8(0x6b, 1); if (*(int *)(data + 0x50) == 0) { qcopy(data + 0x10, moby + 0x10); @@ -297,37 +297,40 @@ void FUN_L05_002f87a8(unsigned char *moby) { moby[0x20] = 1; *(unsigned char *)(moby + 0x30) = 0xff; } - } - } else { + break; + case 1: if (*(int *)(data + 0x50) == 0 && *(unsigned char *)0x13d388 != 0 && *(unsigned short *)0x141938 == 0 && *(int *)0x15f6a8 != 0 && - scale_game_frames_87a8(0x4b0) < *(int *)0x13f4ec && + scale_game_frames_87a8(0x4b0) < g->unk19C && *(unsigned short *)0x141c60 == 0) { play_sound_87a8(0x138f, 0x5f); } - if (*(int *)0x1413dc != 0x16) { + if (g->state.control_mode != 0x16) { moby[0x30] = 0x10; if (*(int *)(data + 0x50) == 0) { qcopy(moby + 0x10, data + 0x10); } moby[0x20] = 0; } + break; + case 2: + break; } { unsigned char *position_ptr = moby + 0x10; - subtract_vector_xyz_87a8(delta_ptr, position_ptr, data); + subtract_vector_xyz_87a8(delta, position_ptr, data); qcopy(data, position_ptr); } - delta_length = vector_length_xyz_87a8(delta_ptr); + delta_length = vector_length_xyz_87a8(delta); if ((unsigned char)moby[0xbc] != 2 && delta_length < 2.0f) { get_moby_position_87a8(moby, D_0014F5CC_87a8 & 1, position); angle = random_angle_radians_87a8(); distance_scale = frame_time * 0.25f; normalize_vector_xyz_87a8(effect_position, moby + 0xe0, distance_scale * fast_cos_87a8(angle)); normalize_vector_xyz_87a8(offset, moby + 0xd0, distance_scale * fast_sin_87a8(angle)); - add_vector_xyz_87a8(effect_position, effect_position, delta_ptr); + add_vector_xyz_87a8(effect_position, effect_position, delta); add_vector_xyz_87a8(effect_position, effect_position, offset); - qcopy(effect_position, delta_ptr); + qcopy(effect_position, delta); effect_position[3] = (float)D_00151928_87a8; if ((unsigned char)moby[0xbc] == 0) { int size = random_int_between_87a8(scale_game_frames_87a8(10), scale_game_frames_87a8(13)); @@ -335,7 +338,7 @@ void FUN_L05_002f87a8(unsigned char *moby) { moby[0xbc] = 0; return; } - scale_vector_xyz_87a8(0.920f, second_position, delta_ptr); + scale_vector_xyz_87a8(0.920f, second_position, delta); { int size = random_int_between_87a8(scale_game_frames_87a8(15), scale_game_frames_87a8(18)); spawn_effect_87a8(position, second_position, 0x5032f0d2, D_00151910_87a8, size, 30, 20, 1); From 0399a3a0025e3d2c60a74f5226aadc068076bf69 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:45:41 +0000 Subject: [PATCH 047/251] decomp: improve register_part_types --- .../shared/rendering/effects/00268900.c | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/overlays/shared/rendering/effects/00268900.c b/src/overlays/shared/rendering/effects/00268900.c index f1c749686..3b50bb8ae 100644 --- a/src/overlays/shared/rendering/effects/00268900.c +++ b/src/overlays/shared/rendering/effects/00268900.c @@ -93,67 +93,66 @@ extern void FUN_L00_00275eb0(void); extern u32 effect_handlers[] __asm__("D_L00_001B1E80"); -void register_part_types(void) __asm__("FUN_L00_00268900"); -void register_part_types(void) +void FUN_L00_00268900(void) { u32 *handlers = effect_handlers; handlers[0] = (u32)FUN_L00_00268d48; - handlers[7] = (u32)FUN_L00_0026a418; + handlers[6] = (u32)FUN_L00_00269d20; handlers[8] = (u32)FUN_L00_0026a5b8; handlers[9] = (u32)FUN_L00_0026a6f0; handlers[10] = (u32)FUN_L00_0026a880; handlers[11] = (u32)FUN_L00_0026ac78; handlers[12] = (u32)FUN_L00_0026b500; - handlers[13] = (u32)FUN_L00_0026b910; - handlers[14] = (u32)FUN_L00_0026ba68; - handlers[15] = (u32)FUN_L00_0026bca8; - handlers[16] = (u32)FUN_L00_0026c088; - handlers[17] = (u32)FUN_L00_0026c3c8; - handlers[18] = (u32)FUN_L00_0026c558; - handlers[19] = (u32)FUN_L00_0026c7f0; - handlers[20] = (u32)FUN_L00_0026c860; + handlers[7] = (u32)FUN_L00_0026a418; handlers[21] = (u32)FUN_L00_0026ccb0; - handlers[22] = (u32)FUN_L00_00267b10; + handlers[23] = (u32)FUN_L00_0026d1b0; handlers[1] = (u32)FUN_L00_00268fe8; handlers[2] = (u32)FUN_L00_00269290; + handlers[28] = (u32)FUN_L00_0026e150; handlers[3] = (u32)FUN_L00_002694f8; handlers[4] = (u32)FUN_L00_00269a70; handlers[5] = (u32)FUN_L00_00269c70; - handlers[6] = (u32)FUN_L00_00269d20; - handlers[23] = (u32)FUN_L00_0026d1b0; + handlers[20] = (u32)FUN_L00_0026c860; + handlers[13] = (u32)FUN_L00_0026b910; + handlers[14] = (u32)FUN_L00_0026ba68; + handlers[15] = (u32)FUN_L00_0026bca8; + handlers[16] = (u32)FUN_L00_0026c088; handlers[24] = (u32)FUN_L00_0026d470; - handlers[25] = (u32)FUN_L00_0026d700; + handlers[17] = (u32)FUN_L00_0026c3c8; + handlers[18] = (u32)FUN_L00_0026c558; handlers[26] = (u32)FUN_L00_0026dbe0; + handlers[19] = (u32)FUN_L00_0026c7f0; + handlers[22] = (u32)FUN_L00_00267b10; handlers[27] = (u32)FUN_L00_0026de00; - handlers[28] = (u32)FUN_L00_0026e150; + handlers[33] = (u32)FUN_L00_0026f048; handlers[29] = (u32)FUN_L00_0026e3a8; handlers[30] = (u32)FUN_L00_0026e670; handlers[31] = (u32)FUN_L00_0026eb88; handlers[32] = (u32)FUN_L00_0026ee48; - handlers[33] = (u32)FUN_L00_0026f048; - handlers[34] = (u32)FUN_L00_0026f280; - handlers[35] = (u32)FUN_L00_0026f660; + handlers[25] = (u32)FUN_L00_0026d700; + handlers[56] = (u32)FUN_L00_00272838; + handlers[52] = (u32)FUN_L00_00271fc0; handlers[36] = (u32)FUN_L00_0026f898; handlers[37] = (u32)FUN_L00_0026fa00; handlers[38] = (u32)FUN_L00_0026fb00; handlers[39] = (u32)FUN_L00_0026fc38; handlers[40] = (u32)FUN_L00_0026ff10; handlers[41] = (u32)FUN_L00_00270710; - handlers[42] = (u32)FUN_L00_00270948; + handlers[55] = (u32)FUN_L00_002726d8; handlers[43] = (u32)FUN_L00_002710a0; - handlers[44] = (u32)FUN_L00_00271450; - handlers[45] = (u32)FUN_L00_00271748; + handlers[35] = (u32)FUN_L00_0026f660; + handlers[34] = (u32)FUN_L00_0026f280; handlers[46] = (u32)FUN_L00_002719f0; + handlers[44] = (u32)FUN_L00_00271450; handlers[47] = (u32)FUN_L00_00271be8; - handlers[48] = (u32)FUN_L00_00271c88; + handlers[45] = (u32)FUN_L00_00271748; handlers[49] = (u32)FUN_L00_00271d20; - handlers[50] = (u32)FUN_L00_00271df8; + handlers[48] = (u32)FUN_L00_00271c88; handlers[51] = (u32)FUN_L00_00271ec8; - handlers[52] = (u32)FUN_L00_00271fc0; + handlers[50] = (u32)FUN_L00_00271df8; handlers[53] = (u32)FUN_L00_002721f0; handlers[54] = (u32)FUN_L00_00272438; - handlers[55] = (u32)FUN_L00_002726d8; - handlers[56] = (u32)FUN_L00_00272838; + handlers[42] = (u32)FUN_L00_00270948; handlers[57] = (u32)FUN_L00_002728e8; handlers[58] = (u32)FUN_L00_00272bc0; handlers[59] = (u32)FUN_L00_00273088; From 9614c46eeca5c0d1550bb7f1afde0dc9c8db91e7 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:45:47 +0000 Subject: [PATCH 048/251] decomp: improve FUN_L15_001ff938 --- src/overlays/shared/ui/help/001ff938.c | 47 ++++++++++++++------------ 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/overlays/shared/ui/help/001ff938.c b/src/overlays/shared/ui/help/001ff938.c index 885c1471f..9f695280d 100644 --- a/src/overlays/shared/ui/help/001ff938.c +++ b/src/overlays/shared/ui/help/001ff938.c @@ -7,6 +7,7 @@ #ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L15_001ff938.s", FUN_L15_001ff938); #else +#include "qcopy.h" extern void FUN_L00_00232670(void); extern void hero_update(void) __asm__("FUN_L00_00211670"); extern void FUN_L15_002044c8(void); @@ -30,14 +31,17 @@ extern u32 FUN_001fa6e0(f32, u32, u32); extern void FUN_L00_00216de8(int, int); extern void FUN_L00_00208b60(void); extern void FUN_L00_00257024(void *); +extern float D_L15_0017ACC0_d __asm__("D_L15_0017ACC0") __attribute__((section(".data"))); +extern unsigned char D_0013E533[]; extern u8 D_0015EDB3; -extern u8 D_0015EDB1; +extern u8 D_0015EDB1 __attribute__((section(".data"))); extern float D_0015EE18_001ff938 __asm__("D_0015EE18_gp") __attribute__((sda)); extern int D_L15_0015F5CC; extern u8 D_0013D4DC[]; void FUN_L15_001ff938(void) { u8 *moby; + struct Hero *base; u32 copy[4] __attribute__((aligned(16))); int period, red, green, blue, alpha, i; u32 color; @@ -61,58 +65,57 @@ void FUN_L15_001ff938(void) { if (hero.vehicle_mode == 2) { if (D_0015EDB3 != 0) - *(float *)(0x0017C06C + (((u32)&FUN_L15_001ff938 == 0x0020EFA8) ? 0x400 : 0)) = D_0015EE18_001ff938 * 1.4f; + *(float *)((u8 *)&D_L15_0017ACC0_d + 0x13AC) = D_0015EE18_001ff938 * 1.4f; FUN_L00_002059d8(); FUN_L00_002061f0(); - moby = (u8 *)hero.moby; - if (((*(u16 *)(moby + 0x34) ^ 1) & 1) != 0) { - moby_point_position(moby, 6, copy); - *(u128 *)((u8 *)&hero + 0x1D80) = *(u128 *)copy; + if (((*(u16 *)((u8 *)hero.moby + 0x34) ^ 1) & 1) != 0) { + moby_point_position(hero.moby, 6, copy); + qcopy((u8 *)&hero + 0x1D80, copy); FUN_L00_00207d00(); } } if (hero.vehicle_mode == 3) { + base = (struct Hero *)(D_0013E533 + 0xE1D); if (D_0015EDB1 != 0) - *(u32 *)(0x0017C1CC + (((u32)&FUN_L15_001ff938 == 0x0020EFA8) ? 0x400 : 0)) = 0x3ff33333; + *(float *)((u8 *)&D_L15_0017ACC0_d + 0x150C) = 1.9f; alpha = 0x80; period = FUN_001f96f8(0xAA); - if (hero.unk22E0 == 2) + if (base->unk22E0 == 2) period = FUN_001f96f8(0x32); - else if (hero.unk22E0 == 1) + else if (base->unk22E0 == 1) period = FUN_001f96f8(0x5A); pulse = FUN_001f9de0((((float)(D_L15_0015F5CC % period) / FUN_001fa6c0(period)) * 2.0f) * 3.1415927f + -3.1415927f); red = FUN_001fa6d0(pulse * 20.0f) + 0x32; green = FUN_001fa6d0(pulse * 70.0f) + 0xB4; blue = FUN_001fa6d0(pulse * 10.0f) + 0x14; - moby = (u8 *)hero.moby; if (red > 0xFF) red = 0xFF; if (green > 0xFF) green = 0xFF; - *(u16 *)(moby + 0x34) |= 0x10; + *(u16 *)((u8 *)hero.moby + 0x34) |= 0x10; if (hero.unk22E0 == 2) color = (alpha << 24) | (blue << 16) | ((red / 2) << 8) | green; else color = (alpha << 24) | (blue << 16) | (green << 8) | red; - *(u32 *)(moby + 0x90) = FUN_001fa6e0(0.1f, *(u32 *)(moby + 0x90), color); + *(u32 *)((u8 *)hero.moby + 0x90) = FUN_001fa6e0(0.1f, *(u32 *)((u8 *)hero.moby + 0x90), color); for (i = 0; i < 3; i++) moby_point_position(hero.moby, i, (u8 *)&hero + 0x1D50 + i * 16); alpha = 0x30; - moby = (u8 *)hero.moby; + moby = (u8 *)base->moby; red_byte = moby[0x90]; green_byte = moby[0x91]; blue_byte = moby[0x92]; - if (hero.unk22DE != 0) - alpha = FUN_001fa6d0((FUN_001fa6c0(hero.unk22DE) / FUN_001fa6c0(0x12)) * (float)alpha); - *(u32 *)((u8 *)&hero + 0x22E4) = (alpha << 24) | (blue_byte << 16) | (green_byte << 8) | red_byte; + if (base->unk22DE != 0) + alpha = FUN_001fa6d0((FUN_001fa6c0(base->unk22DE) / FUN_001fa6c0(0x12)) * (float)alpha); + *(u32 *)((u8 *)base + 0x22E4) = (alpha << 24) | (blue_byte << 16) | (green_byte << 8) | red_byte; FUN_L00_00207d00(); - hero.unk22E0 = 0; - if (hero.vehicle_mode == 3) { - int pending = hero.pending_item[0]; + base->unk22E0 = 0; + if (base->vehicle_mode == 3) { + int pending = base->pending_item[0]; if (pending != 0 && pending != 0x1F) { - if (hero.unk22DE == 0) { + if (base->unk22DE == 0) { FUN_L00_00216de8(0x19, 0); - hero.unk22DC = 1; - hero.unk22DE = 0x12; + base->unk22DC = 1; + base->unk22DE = 0x12; } } else { hero.pending_item[0] = 0; From a96c0c2135dd6db5a2f64e4a0dce5658c9d1b9aa Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:49:59 +0000 Subject: [PATCH 049/251] decomp: improve FUN_L00_0029ead8 --- src/overlays/shared/gameplay/vendor/0029ead8.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/0029ead8.c b/src/overlays/shared/gameplay/vendor/0029ead8.c index e08719dd9..b8dcd921d 100644 --- a/src/overlays/shared/gameplay/vendor/0029ead8.c +++ b/src/overlays/shared/gameplay/vendor/0029ead8.c @@ -49,6 +49,8 @@ void FUN_L00_0029ead8(void *m, s32 x, s32 y) { char text[256]; VendorItemInfo *price_table; s32 cost; + s32 message_id; + s32 text_x; VendorDisplayItem *row; u16 ammo_cost; @@ -65,7 +67,7 @@ void FUN_L00_0029ead8(void *m, s32 x, s32 y) { row = &vendor_menu.rows[vendor_menu.f58]; if (row->fD4 == 1 && weapon_ammo_counts[row->fD0] >= D_L00_001C40B0[row->fD0].hE) { - cost = 0x5236; + message_id = 0x5236; goto message; } if (vendor_menu.rows[vendor_menu.f58].fD4 != 1) @@ -75,7 +77,7 @@ void FUN_L00_0029ead8(void *m, s32 x, s32 y) { else ammo_cost = D_L00_001C40B0[vendor_menu.rows[vendor_menu.f58].fD0].h8; if (current_bolt_count < ammo_cost) { - cost = 0x5238; + message_id = 0x5238; goto message; } FUN_0024ff08(vendor_menu.f20 + 0x500, 1); @@ -86,13 +88,13 @@ void FUN_L00_0029ead8(void *m, s32 x, s32 y) { FUN_001fc4a8((void *)&box, 0x80f0f0f0ULL, FUN_00203ad8(0x5237), -1); FUN_00116248(text, D_L00_00161160, D_L00_00161E34); if (D_L00_00161E34 >= 100) - cost = 0x17; + text_x = 0x17; else { if (D_L00_00161E34 < 10) goto quantity_small; - cost = 0x1e; + text_x = 0x1e; } - FUN_001fb3f0(cost, 0x32, 0x80f0f0f0ULL, text, -1); + FUN_001fb3f0(text_x, 0x32, 0x80f0f0f0ULL, text, -1); goto quantity_done; quantity_small: FUN_001fb3f0(0x25, 0x32, 0x80f0f0f0ULL, text, -1); @@ -107,7 +109,7 @@ void FUN_L00_0029ead8(void *m, s32 x, s32 y) { FUN_001fb888(0x40, 0x4c, 0x80f0f0f0ULL, text, -1); return; message: - FUN_001fc4a8((void *)&box, 0x80f0f0f0ULL, FUN_00203ad8(cost), -1); + FUN_001fc4a8((void *)&box, 0x80f0f0f0ULL, FUN_00203ad8(message_id), -1); return; purchase: cost = discount_purchase_pricing[0] ? D_L00_001C40B0[vendor_menu.rows[vendor_menu.f58].fD0].f4 : D_L00_001C40B0[vendor_menu.rows[vendor_menu.f58].fD0].f0; From 33887e23d0ec84fea749de1d8af9219e9c7f9a3e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:50:00 +0000 Subject: [PATCH 050/251] decomp: improve FUN_L10_002e91b8 --- src/overlays/shared/gameplay/vendor/002e3de8.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index 5b0db1875..2e193c0c6 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -120,7 +120,8 @@ void FUN_L10_002e91b8(unsigned char *m) { float *second_source = (float *)0x001da310; float *first_vectors = (float *)first; float *second_vectors = (float *)second; - int i, j, k; + int i, k; + unsigned int j; copy_matrix(matrix, m + 0xc0); *(aligned_vector *)position = *(aligned_vector *)(m + 0x10); @@ -179,10 +180,10 @@ void FUN_L10_002e91b8(unsigned char *m) { int limit = float_to_integer(((float *)0x001da270)[index] * 360.0f); float angle = integer_to_float(*(int *)0x0015f3f8 % limit) / ((float *)0x001da270)[index] - 180.0f; float wave; - if (((int *)0x001da2b0)[index] == 0) - wave = FUN_001f9de0(angle * 0.017453292f); - else + if (((int *)0x001da2b0)[index] != 0) wave = FUN_001f9dc8(angle * 0.017453292f); + else + wave = FUN_001f9de0(angle * 0.017453292f); ((float *)(first + 0x50))[j * 2 + k] = ((float *)0x001da2f0)[j * 2 + k] + wave * 0.125f; } } @@ -195,7 +196,7 @@ void FUN_L10_002e91b8(unsigned char *m) { } transform_vectors((float *)first, matrix, 0); transform_vectors((float *)second, matrix, 0); - for (j = 3; j >= 0; j--) { + for (j = 0; j < 4; j++) { ((float *)(first + j * 16))[1] += 0.1f; ((float *)(second + j * 16))[1] += 0.1f; } From 6146b791d6219e101625c66be37327c4f2bb29c5 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:52:24 +0000 Subject: [PATCH 051/251] decomp: improve FUN_L15_002a3138 --- .../shared/gameplay/entities/00278fd8.c | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/00278fd8.c b/src/overlays/shared/gameplay/entities/00278fd8.c index 007246d09..ad66e9d7f 100644 --- a/src/overlays/shared/gameplay/entities/00278fd8.c +++ b/src/overlays/shared/gameplay/entities/00278fd8.c @@ -2298,6 +2298,9 @@ int FUN_L15_002a3138(unsigned char *moby) { float position[4]; int *data = *(int **)(moby + 0x78); int pass, corner, axis, component; + float (*secondVertices)[4]; + float (*firstUv)[2]; + float *firstUv1, *firstUv3, *secondUv1, *secondUv2, *secondUv3; copy_rotation_2a3138(transform, moby + 0xc0); qcopy(position, moby + 0x10); @@ -2306,13 +2309,20 @@ int FUN_L15_002a3138(unsigned char *moby) { first.r80 = 0xff9000000260ULL; first.r70 = 0; second.texture = get_effect_texture(0x2c); + secondVertices = second.v; + firstUv = first.uv; + firstUv1 = first.uv[1]; + firstUv3 = first.uv[3]; + secondUv1 = second.uv[1]; + secondUv2 = second.uv[2]; + secondUv3 = second.uv[3]; second.r70 = 0; second.r80 = 0xff9000000260ULL; second.col[3] = 0; second.col[1] = 0; for (corner = 0; corner < 4; corner++) { qcopy(first.v[corner], D_L15_001CE330[corner]); - qcopy(second.v[corner], D_L15_001CE2F0[corner]); + qcopy(secondVertices[corner], D_L15_001CE2F0[corner]); } for (pass = 0; pass < 6; pass++) { int parity = pass & 1; @@ -2320,14 +2330,14 @@ int FUN_L15_002a3138(unsigned char *moby) { int level; first.alpha = (unsigned long long)pairs[4 + parity] | - ((unsigned long long)pairs[6 + parity] << 2) | - ((unsigned long long)pairs[8 + parity] << 4) | + (((unsigned long long)pairs[6 + parity] << 2) | + ((unsigned long long)pairs[8 + parity] << 4)) | ((unsigned long long)pairs[10 + parity] << 6) | 0x8000000000ULL; second.alpha = (unsigned long long)pairs[4 + parity] | - ((unsigned long long)pairs[6 + parity] << 2) | - ((unsigned long long)pairs[8 + parity] << 4) | + (((unsigned long long)pairs[6 + parity] << 2) | + ((unsigned long long)pairs[8 + parity] << 4)) | ((unsigned long long)pairs[10 + parity] << 6) | 0x8000000000ULL; if (data[5] == 0) { @@ -2347,7 +2357,7 @@ int FUN_L15_002a3138(unsigned char *moby) { for (corner = 0; corner < 4; corner++) { float *frequency = D_L15_001CE250[pass]; int waveform = pass * 8; - float *uv = first.uv[corner]; + float *uv = firstUv[corner]; int base = corner * 8; axis = 1; do { @@ -2372,17 +2382,17 @@ int FUN_L15_002a3138(unsigned char *moby) { } for (component = 0; component < 2; component++) { float step = (float)component * 0.125f; - second.uv[1][component] = first.uv[0][component]; - second.uv[2][component] = first.uv[0][component] + step; - second.uv[3][component] = first.uv[1][component]; - first.uv[3][component] = first.uv[1][component] + step; + secondUv1[component] = firstUv[0][component]; + secondUv2[component] = firstUv[0][component] + step; + secondUv3[component] = firstUv1[component]; + firstUv3[component] = firstUv1[component] + step; } draw_geometry_quad(&first, transform, 0); - draw_geometry_quad(&second, transform, 0); + draw_geometry_quad(secondVertices, transform, 0); corner = 3; do { first.v[3 - corner][0] += 0.1f; - second.v[3 - corner][0] += 0.1f; + secondVertices[3 - corner][0] += 0.1f; } while (--corner >= 0); } } From 56c766a33b745392e3afa3c87226ea264f05ba7f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:55:16 +0000 Subject: [PATCH 052/251] decomp: improve FUN_L00_002caf70 --- src/overlays/shared/gameplay/entities/002c8440.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/002c8440.c b/src/overlays/shared/gameplay/entities/002c8440.c index 9b6862444..a2ed9db4b 100644 --- a/src/overlays/shared/gameplay/entities/002c8440.c +++ b/src/overlays/shared/gameplay/entities/002c8440.c @@ -1100,7 +1100,8 @@ struct Moby *FUN_L00_002caf70(struct Moby *source, OvlVec4 *position, struct Mob FUN_00200240_2caf70(i) / FUN_00200240_2caf70(16)); initial_value = *(f32 *)(effect + 0xc); target = D_L00_00161878_2caf70; - *(f32 *)(effect + 0xc) = initial_value + (target - initial_value) * blend; + target = (target - initial_value) * blend; + *(f32 *)(effect + 0xc) = initial_value + target; *(u32 *)(effect + 4) = (FUN_00200250_2caf70(128.0f + blend * -64.0f) << 24) | 0xffffff; *handle = effect; } else { From 3f9125ba56aa0fb1e62dad1c9ef1f9edd8a2929f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:56:26 +0000 Subject: [PATCH 053/251] decomp: improve update_help_effect --- src/overlays/shared/ui/help/00203b18.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/ui/help/00203b18.c b/src/overlays/shared/ui/help/00203b18.c index 57e09d429..df0ea2589 100644 --- a/src/overlays/shared/ui/help/00203b18.c +++ b/src/overlays/shared/ui/help/00203b18.c @@ -450,9 +450,9 @@ void FUN_L00_002059d8(void) { Quad_59d8 *src_b = (Quad_59d8 *)D_L00_0017C220_2059d8; Quad_59d8 *src_c = (Quad_59d8 *)D_L00_0017C260_2059d8; s32 *kind = (s32 *)0x140AF8; - for (i = 0; i < 4; i++, slot += 0x40, active += 0x40, - dst_a += 0x40, dst_b += 0x40, dst_c += 0x40, - src_a++, src_b++, src_c++, kind++) { + for (i = 0; i < 4; i++, dst_c += 0x40, src_c++, + src_a++, src_b++, dst_a += 0x40, kind++, + slot += 0x40, active += 0x40, dst_b += 0x40) { if (*active == 0) { attach_manipulator_2059d8((s32)moby, *kind, slot); active[2] = 1; From 4cdfa1c7c2804ee2c24e314020906562835d9823 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:58:12 +0000 Subject: [PATCH 054/251] decomp: improve FUN_L10_002e8ab0 --- src/overlays/l10/gameplay/vendor/002df270.c | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/overlays/l10/gameplay/vendor/002df270.c b/src/overlays/l10/gameplay/vendor/002df270.c index 50f2f64e7..54cec1213 100644 --- a/src/overlays/l10/gameplay/vendor/002df270.c +++ b/src/overlays/l10/gameplay/vendor/002df270.c @@ -2197,9 +2197,6 @@ void FUN_L10_002e85b8(Moby *moby) break; } } -#ifndef NON_MATCHING -INCLUDE_ASM("config/us/overlays/asm/FUN_L10_002e8ab0.s", FUN_L10_002e8ab0); -#else typedef struct { int linked; int targets[3]; @@ -2280,19 +2277,23 @@ void FUN_L10_002e8ab0(struct Moby *moby) { { struct Moby *candidate; candidate = 0; + if (vars->targets[0] != -1) { + struct Moby *target; + target = (struct Moby *)((char *)D_L10_0015FFD0_e[2] + (vars->targets[0] << 8)); + candidate = (target != 0 && target->state != 0xfe && target->state != 0xfd) ? target : 0; + } { struct Moby *target; - if (vars->targets[0] != -1) { - target = (struct Moby *)((char *)D_L10_0015FFD0_e[2] + (vars->targets[0] << 8)); - candidate = (target != 0 && target->state != 0xfe && target->state != 0xfd) ? target : 0; - } + target = candidate; if (candidate == 0) { if (vars->targets[1] != -1) { - target = (struct Moby *)((char *)D_L10_0015FFD8_8ab0 + (vars->targets[1] << 8)); - if (target != 0 && target->state != 0xfe && target->state != 0xfd) - candidate = target; + struct Moby *candidate; + candidate = (struct Moby *)((char *)D_L10_0015FFD8_8ab0 + (vars->targets[1] << 8)); + if (candidate != 0 && candidate->state != 0xfe && candidate->state != 0xfd) + target = candidate; } } + candidate = target; } target = candidate; } @@ -2375,7 +2376,6 @@ void FUN_L10_002e8ab0(struct Moby *moby) { return; } } -#endif typedef struct { int unk0; float home_yaw; From ec5e9583e3f5b33e24f17807fc8065be6231aca3 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:58:13 +0000 Subject: [PATCH 055/251] decomp: improve FUN_L15_002e5958 --- src/overlays/shared/gameplay/vendor/002e5958.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e5958.c b/src/overlays/shared/gameplay/vendor/002e5958.c index 326c7a425..bc95da514 100644 --- a/src/overlays/shared/gameplay/vendor/002e5958.c +++ b/src/overlays/shared/gameplay/vendor/002e5958.c @@ -101,8 +101,7 @@ void FUN_L15_002e5958(struct Moby *moby) { ((((s32)*(u32 *)(((((s16)save_id >> 5) << 2) + (current_level_index << 8)) + (u8 *)D_0014C190)) >> (save_id & 31)) & 1) != 0) { if (vars->enabled != 0) { FUN_L01_0026e0e0(moby->group, 4); - save_id = vars->restart_timer; - vars->timer = save_id; + vars->timer = vars->restart_timer; moby->state = 4; break; } @@ -124,7 +123,8 @@ void FUN_L15_002e5958(struct Moby *moby) { if (vars->child_count >= vars->notified_count) { FUN_L01_0026e0e0(moby->group, 4); allocate_voice_for_target_entry(1, 0x31, moby); - vars->timer = vars->restart_timer; + near_parent = (u16)vars->restart_timer; + vars->timer = near_parent; moby->state = 4; break; } else { From cc26f3a70288432522f41c91b2f07200a27bd51e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:57:24 +0000 Subject: [PATCH 056/251] decomp: improve FUN_L01_002b91c8 --- src/overlays/shared/gameplay/entities/002b8c08.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b8c08.c b/src/overlays/shared/gameplay/entities/002b8c08.c index c5a392816..b26c53df4 100644 --- a/src/overlays/shared/gameplay/entities/002b8c08.c +++ b/src/overlays/shared/gameplay/entities/002b8c08.c @@ -2847,11 +2847,7 @@ void FUN_L01_002f5168(char *moby) { INCLUDE_ASM("config/us/overlays/asm/FUN_L01_002b91c8.s", FUN_L01_002b91c8); #else #include "rnc/rendering/dma_tag.h" -#define D_0015F620 (*(s32 *)0x0015F620) -#define D_0015F628 (*(u32 *)0x0015F628) -#define D_0015F62C (*(u32 *)0x0015F62C) -#define D_0015F630 (*(u32 *)0x0015F630) -#define D_0015F634 (*(u32 *)0x0015F634) +extern s32 D_0015F620 __asm__("D_L01_00161220") __attribute__((sda)); extern union PacketCursor l01_packet __asm__("D_L01_001611C0") __attribute__((section(".sdata"))); extern void FUN_L01_00261c10(void *, void *) __asm__("FUN_L01_00261c10"); extern void FUN_L01_00261df8(f32 *) __asm__("FUN_L01_00261df8"); @@ -2913,7 +2909,7 @@ void FUN_L01_002b91c8(f32 *pos, s32 count) { if ((near_bits & 0x08080808) == 0x08080808) goto next_entity; if ((near_bits & 0x20202020) == 0x20202020) goto next_entity; - FUN_L01_00261c10((void *)0x70000000, pos + D_0015F620 * 0x170 + 0x14); + FUN_L01_00261c10((void *)0x70000000, (u8 *)pos + (D_0015F620 * 0x5c0 + 0x50)); FUN_L01_00261df8(pos); FUN_L01_002b8c08(pos); FUN_L01_002b80d0(pos); @@ -2955,8 +2951,12 @@ void FUN_L01_002b91c8(f32 *pos, s32 count) { data[8] = get_effect_texture(*(s32 *)(pos + 5)); data[9] = 7; l01_packet.words = packet + 0x18; - D_0015F628 = *(u32 *)(pos + 5); - D_0015F62C = *(u32 *)(pos + 6); + { + u32 texture_id = *(u32 *)(pos + 5); + u32 second_texture_id = *(u32 *)(pos + 6); + D_0015F628 = texture_id; + D_0015F62C = second_texture_id; + } D_0015F630 = *(u8 *)(pos + 7); D_0015F634 = *(u8 *)((u8 *)pos + 0x1d); } From 315c01c4e86106f2f429a7f963babe53164dc6f9 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:01:18 +0000 Subject: [PATCH 057/251] decomp: improve FUN_L00_00237200 --- .../shared/gameplay/animation/00235878.c | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/overlays/shared/gameplay/animation/00235878.c b/src/overlays/shared/gameplay/animation/00235878.c index 3d4688172..edf3e3cbd 100644 --- a/src/overlays/shared/gameplay/animation/00235878.c +++ b/src/overlays/shared/gameplay/animation/00235878.c @@ -542,6 +542,7 @@ extern unsigned char D_L00_0017E530[]; extern int freeze_stats_time_ref_a[] __asm__("D_0015EE58"); extern int freeze_stats_score_ref_a[] __asm__("D_0015EE68"); extern float D_0013F3D0[]; +extern void *memcpy(void *, const void *, unsigned int); extern float FUN_00200240(unsigned int) __asm__("FUN_001fa6c0"); extern float FUN_001fef10(float) __asm__("FUN_001f96b0"); @@ -592,10 +593,10 @@ int FUN_L00_00237200(HudElem *e) { left = 0xe0 - (width >> 1); other_width = FUN_001fb090((const char *)&D_L00_0017E530[1] + i, -1); other_left = 0xe0 - (other_width >> 1); - if (left < other_left) { - other_left = left; - } else { + if (left >= other_left) { width = other_width; + } else { + other_left = left; } left = other_left; FUN_0023b4d8(FUN_0023b208(0x7580, 0), left + 0x20, y, width, 0x36, alpha); @@ -623,21 +624,17 @@ int FUN_L00_00237200(HudElem *e) { points[1].x = 115.7f; points[1].y = 287.0f; points[1].z = 119.5f; - if (level == 5) { - point = points[0]; - } else { - point = points[1]; - } - if (FUN_001ff450(D_0013F3D0, &point.x) < 5.0f) { + if (FUN_001ff450(D_0013F3D0, + level == 5 ? memcpy(&point, &points[0], sizeof(point)) + : memcpy(&point, &points[1], sizeof(point))) < 5.0f) { *(int *)0x15f648 = y + 100; - extra = 4; - if (current_level_index_sda != 0x10) extra = 0; - elapsed = *(int *)((char *)freeze_stats_time_ref_a + extra); - extra = *(int *)((char *)freeze_stats_score_ref_a + extra); + extra = current_level_index_sda == 0x10 ? 1 : 0; + elapsed = freeze_stats_time_ref_a[extra]; + extra = freeze_stats_score_ref_a[extra]; if (elapsed != 0) { interval = pal_mode != 0 ? 3000 : 3600; - minute_scale = interval / 60; seconds = elapsed / interval; + minute_scale = interval / 60; remainder = elapsed - seconds * interval; width = remainder / minute_scale; remainder = (remainder - width * minute_scale) * 100 / minute_scale; From c764dc42ff8582b0595a551c8789d9ff3d149c42 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:02:26 +0000 Subject: [PATCH 058/251] decomp: improve draw_quad_grid_with_dynamic_uvs --- src/overlays/shared/gameplay/entities/002cfcb8.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002cfcb8.c b/src/overlays/shared/gameplay/entities/002cfcb8.c index dbf5bd40b..280a08949 100644 --- a/src/overlays/shared/gameplay/entities/002cfcb8.c +++ b/src/overlays/shared/gameplay/entities/002cfcb8.c @@ -791,11 +791,8 @@ void FUN_L00_002d19b0(u8 *m) { quad.texture[3] = (u64)(s64)D_L00_001618DC | ((u64)(s64)D_L00_001618E0 << 2) | ((u64)(s64)D_L00_001618E4 << 4) | ((u64)(s64)D_L00_001618E8 << 6) | ((u64)(s64)D_L00_001618EC << 32); - quad.colors[0] = D_L00_001618F4; quad.texture[0] = 0; - quad.colors[1] = D_L00_001618F4; - quad.colors[2] = D_L00_001618F4; - quad.colors[3] = D_L00_001618F4; + quad.colors[3] = quad.colors[2] = quad.colors[1] = quad.colors[0] = D_L00_001618F4; if (absolute_float_2d19b0(D_L00_00166C80_2d19b0[80] - *(f32 *)(m + 0x10)) < 16.0f && absolute_float_2d19b0(D_L00_00166C80_2d19b0[81] - *(f32 *)(m + 0x14)) < 16.0f) active = 1; @@ -820,18 +817,16 @@ void FUN_L00_002d19b0(u8 *m) { len = fast_sqrt_2d19b0(c.z + c.z); len += len; if (m[0x20] == 1 || *(s32 *)(vars + 0x40) == 0) { - x = c.x / len + 0.5f; - y = c.y / len + 0.5f; - uv[0][0] = x; + uv[0][0] = c.x / len + 0.5f; + uv[0][1] = c.y / len + 0.5f; } else { x = c.x / len; y = c.y / len; x += 0.5f; uv[0][0] = x + (old_uv[0][0] - x) * blend; x = y + 0.5f; - y = x + (old_uv[0][1] - x) * blend; + uv[0][1] = x + (old_uv[0][1] - x) * blend; } - uv[0][1] = y; uv++; old_uv++; } From ba022d70a7fedbb2604dc2e24c5655e0f1020669 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:05:01 +0000 Subject: [PATCH 059/251] decomp: improve FUN_L08_002f44c0 --- src/overlays/l08/gameplay/entities/002e9b70.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/l08/gameplay/entities/002e9b70.c b/src/overlays/l08/gameplay/entities/002e9b70.c index ef182e9c4..072c51ff8 100644 --- a/src/overlays/l08/gameplay/entities/002e9b70.c +++ b/src/overlays/l08/gameplay/entities/002e9b70.c @@ -515,8 +515,9 @@ state_one: { distance = FUN_001f9b80_44c0(&moby->pos, D_0013F3D0); if ((distance < 2.0f && *(s32 *)(D_0013F3D0 + 0x2004) == 0x42) || *(struct Moby **)(D_0013F3D0 + 0x1bc) == moby) { allocate_voice_for_target_entry_44c0(0, 0, moby); + waypoint = 1; FUN_L00_0025e450_44c0(moby, D_L08_0015F580, &moby->pos, 3.0f, 1.0f, 10, 20, 60, - 3.0f, 5.0f, 9.0f, 1.0f, -1, 15.0f, 1, 1, -1, 0); + 3.0f, 5.0f, 9.0f, 1.0f, -1, 15.0f, waypoint, 1, -1, 0); } else { if (active == 0) return; allocate_voice_for_target_entry_44c0(0, 0, moby); From 2c53fce708d3392df5c853756133721bdd2de675 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:05:04 +0000 Subject: [PATCH 060/251] decomp: improve FUN_L10_002da690 --- src/overlays/l10/gameplay/entities/00295a38.c | 84 +++++++++++++------ 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/src/overlays/l10/gameplay/entities/00295a38.c b/src/overlays/l10/gameplay/entities/00295a38.c index 8be4c6409..6b2882a25 100644 --- a/src/overlays/l10/gameplay/entities/00295a38.c +++ b/src/overlays/l10/gameplay/entities/00295a38.c @@ -1967,12 +1967,19 @@ extern unsigned int fast_tween_color_da690(float, int, int) __asm__("FUN_001fa6e extern float scale_time_da690(float) __asm__("FUN_L10_001f2578"); extern void add_vector_xyz_da690(void *, void *, void *) __asm__("FUN_001f9a10"); extern void draw_geometry_quad_da690(void *, void *, int) __asm__("FUN_001f7d30"); +/* Retail loads these words relative to gp (0x00166c00). */ +extern int D_L10_00161C70 __attribute__((sda)); +extern int D_L10_00161C74 __attribute__((sda)); +extern int D_L10_00161C78 __attribute__((sda)); +extern int D_L10_00161C7C __attribute__((sda)); +extern int D_L10_00161C90 __attribute__((sda)); +extern int D_L10_00161C94 __attribute__((sda)); extern float D_L10_00161D60; extern int D_L10_00161D64; extern int D_L10_00161D68; -void FUN_L10_002da690(struct Moby *moby) { - char *data = (char *)moby->pvars; +void FUN_L10_002da690(void *moby) { + char *data = (char *)((struct Moby *)moby)->pvars; char *base = *(char **)((char *)D_L10_0015FFD8 + *(int *)(data + 0xc) * 0x100 + 0x78); char scratch[(unsigned int)*(int *)(data + 4) * 0x40]; /* The draw helper reads UVs at quad + 0x50 and packet words at quad + 0x70. */ @@ -1988,25 +1995,54 @@ void FUN_L10_002da690(struct Moby *moby) { int i, group, row, vertex; float fade, phase; char *transform; + float *matrix1, *matrix2, *uv1, *uv2; - fade = vector_distance_da690(&moby->pos, &D_L10_00167240); - if (fade > 48.0f) fade = (80.0f - fade) * 0.03125f; - else fade = 1.0f; + { + float distance = vector_distance_da690(&((struct Moby *)moby)->pos, &D_L10_00167240); + if (distance > 48.0f) fade = (80.0f - distance) * 0.03125f; + else fade = 1.0f; + } rotation_matrix_y_da690(buffers.rotation, *(float *)data * 0.5f); - for (i = 0, transform = scratch; i < *(int *)(data + 4); i++, transform += 0x40) { - rotation_matrix_da690(transform, &moby->rot); - multiply_matrix_da690(transform, transform, buffers.rotation); - *(OvlQuad *)(transform + 0x30) = *(OvlQuad *)&moby->pos; - *(float *)(transform + 0x38) += convert_integer_to_float_da690(i + 1) * *(float *)(data + 8); - } - ((u64 *)buffers.matrix1)[5] = ((u64 *)buffers.packet.fields.matrix2)[5] = get_effect_texture_da690(14); - ((u64 *)buffers.matrix1)[6] = ((u64 *)buffers.packet.fields.matrix2)[6] = 0xff9000000260ULL; - ((u64 *)buffers.matrix1)[7] = ((u64 *)buffers.packet.fields.matrix2)[7] = ((u64)*(int *)0x0015b070) | ((u64)*(int *)0x0015b074 << 2) | - ((u64)*(int *)0x0015b078 << 4) | ((u64)*(int *)0x0015b07c << 6) | 0x8000000000ULL; - ((u64 *)buffers.matrix1)[4] = 0; - ((u64 *)buffers.packet.fields.matrix2)[4] = 0; - for (i = 0; i < 4; i++) { - buffers.matrix1[i * 2 + 1] = buffers.packet.fields.matrix2[i * 2 + 1] = ((float *)0x001d9ff4)[i * 2]; + matrix1 = buffers.matrix1; + matrix2 = buffers.packet.fields.matrix2; + uv1 = matrix1 + 1; + uv2 = matrix2 + 1; + i = 0; + if (*(int *)(data + 4) > 0) { + transform = scratch; + do { + i++; + rotation_matrix_da690(transform, &((struct Moby *)moby)->rot); + multiply_matrix_da690(transform, transform, buffers.rotation); + *(OvlQuad *)(transform + 0x30) = *(OvlQuad *)&((struct Moby *)moby)->pos; + *(float *)(transform + 0x38) += convert_integer_to_float_da690(i) * *(float *)(data + 8); + transform += 0x40; + } while (i < *(int *)(data + 4)); + } + { + u64 texture = get_effect_texture_da690(14); + u64 packet_flags = ((u64)D_L10_00161C70) | ((u64)D_L10_00161C74 << 2) | + ((u64)D_L10_00161C78 << 4) | ((u64)D_L10_00161C7C << 6) | 0x8000000000ULL; + ((u64 *)matrix1)[5] = texture; + ((u64 *)matrix2)[5] = texture; + ((u64 *)matrix1)[6] = 0xff9000000260ULL; + ((u64 *)matrix1)[7] = packet_flags; + ((u64 *)matrix2)[6] = 0xff9000000260ULL; + ((u64 *)matrix2)[4] = 0; + ((u64 *)matrix1)[4] = 0; + ((u64 *)matrix2)[7] = packet_flags; + } + { + float *source = (float *)0x001d9ff4; + i = 3; + do { + float value = *source; + source += 2; + *uv2 = value; + *uv1 = value; + uv2 += 2; + uv1 += 2; + } while (--i >= 0); } for (group = 0; group < 4; group++) { phase = 0.0f; @@ -2015,8 +2051,8 @@ void FUN_L10_002da690(struct Moby *moby) { if (phase > 1.0f) phase -= 1.0f; for (i = 0; i < 4; i++) { float value = ((float *)0x001d9ff0)[i * 2] + phase + *(float *)(base + 0x12de0); - buffers.matrix1[i * 2] = value; - buffers.packet.fields.matrix2[i * 2] = value; + matrix1[i * 2] = value; + matrix2[i * 2] = value; } for (i = 0; i < *(int *)(data + 4); i++) { unsigned char *order = (unsigned char *)(data + 0x10); @@ -2030,13 +2066,13 @@ void FUN_L10_002da690(struct Moby *moby) { progress = 1.0f - convert_integer_to_float_da690(age) / convert_integer_to_float_da690(D_L10_00161D68); } - color = fast_tween_color_da690(progress, *(int *)0x0015b090, *(int *)0x0015b094); + color = fast_tween_color_da690(progress, D_L10_00161C90, D_L10_00161C94); color = (color & 0xffffff) + (truncate_float_to_s32_da690(fade * fade * convert_integer_to_float_da690((int)color >> 24)) << 24); - if (moby->state == 2) { + if (((struct Moby *)moby)->state == 2) { float alpha = convert_integer_to_float_da690(*(int *)(data + 0x34)); - float duration = scale_time_da690(*(float *)0x0015b098 * 60.0f); + float duration = scale_time_da690(D_L10_00161C98 * 60.0f); color = (truncate_float_to_s32_da690(alpha * 255.0f / duration) << 24) | 0xffffff; } From cae29ed1dfc3f6412abab0451759593bad993212 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:08:43 +0000 Subject: [PATCH 061/251] decomp: improve FUN_L00_002d9810 --- src/overlays/shared/gameplay/entities/002d7f88.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002d7f88.c b/src/overlays/shared/gameplay/entities/002d7f88.c index 028154272..13b68d7ba 100644 --- a/src/overlays/shared/gameplay/entities/002d7f88.c +++ b/src/overlays/shared/gameplay/entities/002d7f88.c @@ -857,13 +857,13 @@ void FUN_L00_002d9810(u8 *m) { float *data = *(float **)(m + 0x78); char *shape; float ratio = data[0] / D_L00_00161A10_002d9810; - int i, j = 0x121, color; + int i, j, color; short *indices; char *source; char *destination = D_L00_001E3DA0_002d9810; - char *pointA, *pointB; + char *pointB, *pointA; float *u, *v; - float *shiftedVector; + float *shiftedVector = shifted; quad.texture[1] = FUN_001f44b8_002d9810(D_L00_00161AD4_002d9810); quad.texture[2] = 0xff9000000260ULL; @@ -874,7 +874,6 @@ void FUN_L00_002d9810(u8 *m) { ((u64)D_L00_00161AD0_002d9810 << 32); quad.texture[0] = 0; FUN_00233980_002d9810(0x47, 0x53001); - shiftedVector = shifted; ((float *)&position)[0] = *(float *)(m + 0x10); ((float *)&position)[1] = *(float *)(m + 0x14); ((float *)&position)[2] = *(float *)(m + 0x18) + 0.5f; @@ -897,6 +896,7 @@ void FUN_L00_002d9810(u8 *m) { FUN_00233980_002d9810(0x14, 0xff9000000260ULL); FUN_00233980_002d9810(0x4a, 0); FUN_001f76a0_002d9810(); + j = 0x121; source = D_L00_001E14C0_002d9810; do { FUN_001f9d20_002d9810(&transformed, source, shiftedVector); @@ -921,7 +921,7 @@ void FUN_L00_002d9810(u8 *m) { quad.texture[1] = FUN_001f44b8_002d9810(0xb); quad.texture[3] = 0x8000000048ULL; color = FUN_001fa6d0_002d9810(ratio * 64.0f + 128.0f); - color = ((u32)(color + D_L00_00161B10_002d9810) << 24) | D_L00_00161AE0_002d9810; + color = ((u32)(D_L00_00161B10_002d9810 + color) << 24) | D_L00_00161AE0_002d9810; quad.colors[3] = 0; quad.colors[2] = 0; quad.colors[0] = color; @@ -938,8 +938,8 @@ void FUN_L00_002d9810(u8 *m) { else FUN_001f9a68_002d9810(D_L00_00161ADC_002d9810, pointA, D_L00_001E3480_002d9810 + index * 16); - pointA += 16; pointB += 16; + pointA += 16; indices++; } quad.texcoords[0] = 0.5f; From dd04f43313f8773f4b805eaba29610d3f6ac3755 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:09:23 +0000 Subject: [PATCH 062/251] decomp: improve FUN_L02_002ea210 --- src/overlays/shared/gameplay/entities/002a4038.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/002a4038.c b/src/overlays/shared/gameplay/entities/002a4038.c index 11b6c2862..ff8830078 100644 --- a/src/overlays/shared/gameplay/entities/002a4038.c +++ b/src/overlays/shared/gameplay/entities/002a4038.c @@ -1472,7 +1472,7 @@ extern float ea210_clamp(float, float) __asm__("FUN_001fa580"); extern void ea210_draw(void *, void *, int, int, int) __asm__("FUN_L00_002eaaa0"); extern void ea210_drawend(void *) __asm__("FUN_L00_002ea9d8"); extern void ea210_drawflush(void *) __asm__("FUN_L00_002eaa30"); -extern void ea210_fade(float, float, void *) __asm__("FUN_00213ed8"); +extern float ea210_fade(float, float, void *) __asm__("FUN_00213ed8"); extern void ea210_hide(int) __asm__("FUN_L00_002eac18"); extern void ea210_audio(int, int) __asm__("FUN_0020b178"); extern void ea210_destroy(char *) __asm__("FUN_0020c828"); From 2e2932862a7229180dc732a3e75c97134521e07b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:10:05 +0000 Subject: [PATCH 063/251] decomp: improve FUN_L14_00301fa8 --- .../shared/gameplay/vendor/003015d0.c | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/003015d0.c b/src/overlays/shared/gameplay/vendor/003015d0.c index 95a58722d..3a1e6e02c 100644 --- a/src/overlays/shared/gameplay/vendor/003015d0.c +++ b/src/overlays/shared/gameplay/vendor/003015d0.c @@ -356,6 +356,12 @@ extern u64 get_effect_texture(int) __asm__("FUN_001f44b8"); extern float convert_integer_to_float(int) __asm__("FUN_001fa6c0"); extern void draw_geometry_quad(void *, void *, int) __asm__("FUN_001f7d30"); +extern int D_L14_001620DC __attribute__((sda)); +extern int D_L14_001620E0 __attribute__((sda)); +extern int D_L14_001620E4 __attribute__((sda)); +extern int D_L14_001620E8 __attribute__((sda)); +extern int D_L14_001620EC __attribute__((sda)); + void FUN_L14_00301fa8(char *m) { char *d = *(char **)(m + 0x78); VendorBeamFrame *frame = &D_L14_001600EC[*(int *)d]; @@ -367,20 +373,23 @@ void FUN_L14_00301fa8(char *m) { float start[4] __attribute__((aligned(16))); float work[4] __attribute__((aligned(16))); float side[4] __attribute__((aligned(16))); - int i, j, k, strip, point, rounded; + int i, j, k, strip, point; + int rounded; int color; + u8 *indices; void *src; FUN_001fa050(base, &frame->pad40[0x30]); FUN_001fa2d8(matrix, base); - *(u128 *)(base + 12) = *(u128 *)&frame->origin; + frame = &D_L14_001600EC[*(int *)d]; + qcopy(base + 12, &frame->origin); subtract_vector_xyz(direction, (void *)0x1674c0, &frame->origin); transform_vector_xyz(direction, direction, matrix); { - u64 texture = get_effect_texture(*(int *)0x001fb4dc); - u64 gs_state = (u64)*(int *)0x001fb4e0 | (u64)*(int *)0x001fb4e4 << 2 | - (u64)*(int *)0x001fb4e8 << 4 | (u64)*(int *)0x001fb4ec << 6 | 0x8000000000ULL; + u64 texture = get_effect_texture(D_L14_001620DC); + u64 gs_state = (u64)D_L14_001620E0 | (u64)D_L14_001620E4 << 2 | + (u64)D_L14_001620E8 << 4 | (u64)D_L14_001620EC << 6 | 0x8000000000ULL; packet[0].texture_state = packet[1].texture_state = packet[2].texture_state = 0xff9000000260ULL; packet[0].texture = packet[1].texture = packet[2].texture = texture; packet[0].gs_state = packet[1].gs_state = packet[2].gs_state = gs_state; @@ -398,6 +407,7 @@ void FUN_L14_00301fa8(char *m) { } clear_u64_value(start); + indices = (u8 *)(d + 0x18); for (point = 0; point < 31; point++) { qcopy(end, start); if (point < 30) { @@ -409,9 +419,9 @@ void FUN_L14_00301fa8(char *m) { clear_u64_value(start); } rounded = point + 3; - if (point > -1) rounded = point; + if (-1 < point) rounded = point; rounded = (rounded >> 2) << 2; - for (i = 0; i < 4; i++) { + for (i = 0; i < 4;) { if (i < 2) { packet[0].vertices[i] = *(u128 *)(d + 0x20 + (point << 4)); if (!(i & 1)) subtract_vector_xyz(&packet[0].vertices[i], &packet[0].vertices[i], end); @@ -428,14 +438,15 @@ void FUN_L14_00301fa8(char *m) { add_vector_xyz(&packet[0].vertices[i], &packet[0].vertices[i], src); } } - packet[0].uv[i][0] = ((float *)0x001e5fd0)[i * 2] + + j = i++; + packet[0].uv[j][0] = ((float *)0x001e5fd0)[j * 2] + convert_integer_to_float(point - rounded) * 0.25f; } draw_geometry_quad(&packet[0], base, 0); } for (strip = 0; strip < 4; strip++) { clear_u64_value(start); - if ((u8)d[0x18 + strip] < 31) { + if (indices[strip] < 31) { for (point = 0; point < 3; point++) { qcopy(end, start); if (point < 2) { @@ -450,9 +461,9 @@ void FUN_L14_00301fa8(char *m) { } if (point == 0) qcopy(end, start); rounded = point + 3; - if (point > -1) rounded = point; + if (-1 < point) rounded = point; rounded = (rounded >> 2) << 2; - for (k = 0; k < 4; k++) { + for (k = 0; k < 4;) { if (k < 2) { packet[0].vertices[k] = *(u128 *)(d + (point << 6) + 0x420 + (strip << 4)); if (!(k & 1)) subtract_vector_xyz(&packet[0].vertices[k], &packet[0].vertices[k], end); @@ -469,7 +480,8 @@ void FUN_L14_00301fa8(char *m) { add_vector_xyz(&packet[0].vertices[k], &packet[0].vertices[k], src); } } - packet[0].uv[k][0] = ((float *)0x001e5fd0)[k * 2] + + j = k++; + packet[0].uv[j][0] = ((float *)0x001e5fd0)[j * 2] + convert_integer_to_float(point - rounded) * 0.25f; } draw_geometry_quad(&packet[0], base, 0); From 3462a30a9eaff0868fa0050085dca3104c23d8d0 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:11:11 +0000 Subject: [PATCH 064/251] decomp: improve FUN_L06_002feb40 --- src/overlays/shared/gameplay/entities/002fdbd0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002fdbd0.c b/src/overlays/shared/gameplay/entities/002fdbd0.c index c0fe19e43..1788d4883 100644 --- a/src/overlays/shared/gameplay/entities/002fdbd0.c +++ b/src/overlays/shared/gameplay/entities/002fdbd0.c @@ -445,7 +445,7 @@ void FUN_L06_002feb40(struct Moby *moby) { struct Moby *other; struct Moby *fragment; s32 collision; - s32 fragment_count; + struct { f32 position[4]; f32 velocity[4]; @@ -530,7 +530,7 @@ void FUN_L06_002feb40(struct Moby *moby) { angle = FUN_001f9e90(other->pos.x, other->pos.y); FUN_0026b368(angle, moby, vel, 9, 1, 0); vel = scratch.velocity; - for (fragment_count = 9; fragment_count >= 0; fragment_count--) { + for (collision = 9; collision >= 0; collision--) { qcopy(scratch.position, &moby->pos); scratch.position[2] += 2.5f; scratch.position[0] += FUN_00266908(0.0f, 0.2f); From 5ab362cb41e8a28b0318342fdd3f51d495892262 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:12:59 +0000 Subject: [PATCH 065/251] decomp: improve FUN_L08_003024d8 --- src/overlays/shared/gameplay/entities/002937a0.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002937a0.c b/src/overlays/shared/gameplay/entities/002937a0.c index 1714d5ee8..656a4a6ce 100644 --- a/src/overlays/shared/gameplay/entities/002937a0.c +++ b/src/overlays/shared/gameplay/entities/002937a0.c @@ -1683,11 +1683,11 @@ void FUN_L08_003024d8(char *m) { pose_scale = D_00162184_3024d8 * frame_time_sq; *(unsigned short *)(m + 0x34) &= 0xefff; *(int *)(d + 0x90) = 0x200; - *(float *)(d + 0x80) = pose_scale; - *(float *)(d + 0x88) = timer_scale; - *(float *)(d + 0xc0) = 11.0f; *(float *)(d + 0xc4) = 16.0f; + *(float *)(d + 0xc0) = 11.0f; *(float *)(d + 0x98) = 0.25f; + *(float *)(d + 0x80) = pose_scale; + *(float *)(d + 0x88) = timer_scale; *(float *)(d + 0x8c) = angle; angle = angle_atan2_3024d8(*(float *)(m + 0x10) - *(float *)(*(char **)(h + 0x20) + 0x10), *(float *)(m + 0x14) - *(float *)(*(char **)(h + 0x20) + 0x14)); From 7ac23386dfca0b04f8b597a359d76bbd89e78a63 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:09:06 +0000 Subject: [PATCH 066/251] decomp: improve FUN_L12_002bf140 --- src/overlays/l12/gameplay/entities/002bf140.c | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/overlays/l12/gameplay/entities/002bf140.c b/src/overlays/l12/gameplay/entities/002bf140.c index 0e1838c70..52c0618bc 100644 --- a/src/overlays/l12/gameplay/entities/002bf140.c +++ b/src/overlays/l12/gameplay/entities/002bf140.c @@ -71,30 +71,28 @@ void FUN_L12_002bf140(struct Moby *moby) { moby->flags |= 1; slot = data[3]; if (slot == 0) { - short *p = (short *)(D_L12_001CBF40_c + 16 * 0x1190 + 0x1e); i = 16; do { - *p = 0; - p -= 0x1190 / 2; + ((L12Slot *)D_L12_001CBF40_c)[i].visibility = 0; } while (--i >= 0); initialize_slots_c(D_L12_001CBF40_c, 17); initialize_slot_data_c(1.0f); - *(volatile float *)(D_L12_001CAD00_c + 0x00) = 16.0f; - *(volatile float *)(D_L12_001CAD00_c + 0x0c) = -8.0f; - *(volatile float *)(D_L12_001CAD00_c + 0x18) = 0.9f; - *(volatile float *)(D_L12_001CAD00_c + 0x08) = -8.0f; - *(volatile float *)(D_L12_001CAD00_c + 0x20) = 0.1f; - *(volatile float *)(D_L12_001CAD00_c + 0x14) = 1.0f; - *(volatile float *)(D_L12_001CAD00_c + 0x10) = 1.0f; - *(volatile float *)(D_L12_001CAD00_c + 0x04) = 16.0f; + *(float *)(D_L12_001CAD00_c + 0x00) = 16.0f; + *(float *)(D_L12_001CAD00_c + 0x0c) = -8.0f; + *(float *)(D_L12_001CAD00_c + 0x18) = 0.9f; + *(float *)(D_L12_001CAD00_c + 0x08) = -8.0f; + *(float *)(D_L12_001CAD00_c + 0x20) = 0.1f; + *(float *)(D_L12_001CAD00_c + 0x14) = 1.0f; + *(float *)(D_L12_001CAD00_c + 0x10) = 1.0f; + *(float *)(D_L12_001CAD00_c + 0x04) = 16.0f; value = angle_c(*(float *)0x00180350, *(float *)0x00180354); - *(volatile float *)(D_L12_001CAD00_c + 0x30) = sine_c(value) * 0.57735f; - *(volatile float *)(D_L12_001CAD00_c + 0x34) = cosine_c(value) * 0.57735f; - *(volatile float *)(D_L12_001CAD00_c + 0x38) = -0.57735f; - *(volatile int *)(D_L12_001CAD00_c + 0x28) = data[0] + 0x28; - *(volatile u8 *)(D_L12_001CAD00_c + 0x3d) = 0x40; - *(volatile int *)(D_L12_001CAD00_c + 0x2c) = data[1] + 0x28; - *(volatile u8 *)(D_L12_001CAD00_c + 0x3c) = 0x1c; + *(float *)(D_L12_001CAD00_c + 0x30) = sine_c(value) * 0.57735f; + *(float *)(D_L12_001CAD00_c + 0x34) = cosine_c(value) * 0.57735f; + *(float *)(D_L12_001CAD00_c + 0x38) = -0.57735f; + *(int *)(D_L12_001CAD00_c + 0x28) = data[0] + 0x28; + *(u8 *)(D_L12_001CAD00_c + 0x3d) = 0x40; + *(int *)(D_L12_001CAD00_c + 0x2c) = data[1] + 0x28; + *(u8 *)(D_L12_001CAD00_c + 0x3c) = 0x1c; *(char **)0x001612d0 = D_L12_001CBF40_c; *(void **)0x001612d4 = D_L12_001CBE00_c; *(int *)0x001612d8 = 17; From f1a9fb0409bd108b555e91420bb7794d1e2045a3 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:18:37 +0000 Subject: [PATCH 067/251] decomp: improve FUN_L13_00306300 --- src/overlays/l13/gameplay/vendor/003058a8.c | 22 ++++++++++----------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/overlays/l13/gameplay/vendor/003058a8.c b/src/overlays/l13/gameplay/vendor/003058a8.c index d64d6e7d7..c210ba03b 100644 --- a/src/overlays/l13/gameplay/vendor/003058a8.c +++ b/src/overlays/l13/gameplay/vendor/003058a8.c @@ -320,8 +320,8 @@ extern int random_int_between(int, int) __asm__("FUN_L00_00257b90"); extern int scale_game_frames(int) __asm__("FUN_001f96f8"); extern void FUN_L00_001ff660(void *, void *, void *); extern void FUN_L00_0026dd20(void *, void *, int, int, float); -extern void FUN_0022da68(void *, void *) __asm__("FUN_L07_0029a2a0"); -extern void FUN_L07_0029a2a0(int, int, void *) __asm__("FUN_0022da68"); +extern void FUN_0022da68(int, int, void *); +extern void FUN_L07_0029a2a0(void *, void *); extern unsigned char D_00141346; extern char D_0013F3D0[]; extern float D_0015ED6C; @@ -414,11 +414,10 @@ void FUN_L13_00306300(struct Moby *moby) { FUN_001f9740((int *)(data + 0x2c)) == 0) goto collision; if (moby->visible != 0) { - int i = 2; - do { + int i; + for (i = 0; i < 3; i++) { *(OvlQuad *)&work.random_direction = 0; work.random_direction.x = random_float_between(-1.0f, 1.0f); - i--; work.random_direction.y = random_float_between(-1.0f, 1.0f); work.random_direction.z = random_float_between(-1.0f, 1.0f); work.velocity = work.random_direction; @@ -427,8 +426,8 @@ void FUN_L13_00306300(struct Moby *moby) { add_vector_xyz(&work.velocity, &work.random_direction, &work.velocity); scale_vector_xyz_6300(&work.velocity, &work.velocity, random_float_between(D_0015ED6C + D_0015ED6C, D_0015ED6C * 4.0f)); - FUN_0022da68(&moby->pos, &work.velocity); - } while (i >= 0); + FUN_L07_0029a2a0(&moby->pos, &work.velocity); + } } mark_moby_for_removal(moby); return; @@ -438,11 +437,10 @@ void FUN_L13_00306300(struct Moby *moby) { goto bounds; qcopy(&moby->pos, &D_L13_00174140.pos); if (moby->visible != 0) { - int i = 4; - do { + int i; + for (i = 0; i < 5; i++) { *(OvlQuad *)&work.random_direction = 0; work.random_direction.x = random_float_between(-1.0f, 1.0f); - i--; work.random_direction.y = random_float_between(-1.0f, 1.0f); work.random_direction.z = random_float_between(-1.0f, 1.0f); work.velocity = work.random_direction; @@ -454,11 +452,11 @@ void FUN_L13_00306300(struct Moby *moby) { random_float_between(D_0015ED6C * 3.0f, D_0015ED6C * 6.0f)); FUN_L00_0026dd20(&moby->pos, &work.velocity, 0x7f2f4f6f, random_int_between(scale_game_frames(10), scale_game_frames(15)), 30000.0f); - } while (i >= 0); + } } if (D_L13_00174140.moby != 0 && (D_L13_00174140.moby)->oclass == 0) - FUN_L07_0029a2a0(0, 0, moby); + FUN_0022da68(0, 0, moby); mark_moby_for_removal(moby); return; bounds: From 365725ed69c01f87e8077756d5952d020c01c3d8 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:20:42 +0000 Subject: [PATCH 068/251] decomp: improve FUN_L06_00303160 --- src/overlays/l06/gameplay/entities/002fd1a0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/l06/gameplay/entities/002fd1a0.c b/src/overlays/l06/gameplay/entities/002fd1a0.c index 011367752..60cb3a8a5 100644 --- a/src/overlays/l06/gameplay/entities/002fd1a0.c +++ b/src/overlays/l06/gameplay/entities/002fd1a0.c @@ -1827,7 +1827,7 @@ extern void clear_vector_303160(float *) __asm__("FUN_001f99f8"); extern void approach_angle_303160(float *, float *, float, float, float, float) __asm__("FUN_L00_0025be00"); extern void event_303160(int, int, char *) __asm__("FUN_0022dba0"); extern void FUN_L06_00303748(float, char *, char *, char *, int); -extern void FUN_L06_00303b68(char *); +extern void FUN_L06_00303b68(struct Moby *); int FUN_L06_00303160(char *moby, int path) { char *data = *(char **)(moby + 0x78); @@ -1912,7 +1912,7 @@ int FUN_L06_00303160(char *moby, int path) { D_L06_001600EC_303160 + next_index * 0x80, 6); } else if (event == 10 || previous_event == 10) { event_303160(1, 0, moby); - FUN_L06_00303b68(moby); + FUN_L06_00303b68((struct Moby *)moby); } } return *(float *)(data + 0xf4) == 1.0f; From 3877ef96b8d8598e2b7338d9741627a3c8368eae Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:21:53 +0000 Subject: [PATCH 069/251] decomp: improve FUN_L08_002dc9a8 --- src/overlays/l08/gameplay/entities/002b8228.c | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/overlays/l08/gameplay/entities/002b8228.c b/src/overlays/l08/gameplay/entities/002b8228.c index d5d408d26..19f77bfe5 100644 --- a/src/overlays/l08/gameplay/entities/002b8228.c +++ b/src/overlays/l08/gameplay/entities/002b8228.c @@ -1452,7 +1452,15 @@ extern void FUN_L08_002dc9a8_start(int, int, void *) __asm__("FUN_0022da68"); extern void FUN_L08_002dc9a8_finish(void *) __asm__("FUN_0020c828"); extern float D_0015ED6C_2DC9A8 __asm__("D_0015ED6C"); extern float D_0015ED70_2DC9A8 __asm__("D_0015ED70"); -extern char D_L08_00174640_2DC9A8[] __asm__("D_L08_00174640"); +typedef struct CollisionRecord_2DC9A8 { + char pad[0x18]; + int owner; + int unknown; + float position[4]; + char pad30[0x10]; + float vector[4]; +} CollisionRecord_2DC9A8; +extern CollisionRecord_2DC9A8 D_L08_00174640_2DC9A8 __asm__("D_L08_00174640"); extern int D_L08_00174658_2DC9A8 __asm__("D_L08_00174658") __attribute__((section(".data"))); typedef struct __attribute__((packed)) EffectVectorCopy_2DC9A8 { @@ -1490,23 +1498,25 @@ void FUN_L08_002dc9a8(struct Moby *moby) { switch ((unsigned char)m[0x20]) { case 1: { position = (float *)(m + 0x10); - *(volatile u128 *)original = *(volatile u128 *)position; + qcopy(original, position); FUN_L08_002dc9a8_transform(position, position, data); *(float *)(data + 8) -= D_0015ED70_2DC9A8 * 10.8f; - *(volatile u128 *)record.pos = *(volatile u128 *)position; + qcopy(record.pos, position); record.owner = m; record.flags = 0x810000; - record.scale = 1.0f; record.state = 1; - *(volatile u128 *)record.velocity = *(volatile u128 *)data; - if (FUN_L08_002dc9a8_trace(original, &record, 0, m, 0) == 0) { + record.scale = 1.0f; + qcopy(record.velocity, data); + if (FUN_L08_002dc9a8_trace(original, &record, 0, m, 0) != 0) { + if (*(int *)(data + 0x20) != 0 && + D_L08_00174640_2DC9A8.owner != *(int *)(data + 0x20)) { + m[0x20] = 99; + qcopy(position, D_L08_00174640_2DC9A8.position); + FUN_L08_002dc9a8_add(data, data, D_L08_00174640_2DC9A8.vector); + FUN_L08_002dc9a8_scale(D_0015ED6C_2DC9A8 + D_0015ED6C_2DC9A8, data, data); + } + } else { if (FUN_L08_002dc9a8_test(data + 0x10) != 0) m[0x20] = 99; - } else if (*(int *)(data + 0x20) != 0 && - *(int *)(data + 0x20) != D_L08_00174658_2DC9A8) { - m[0x20] = 99; - *(volatile u128 *)position = *(volatile u128 *)(D_L08_00174640_2DC9A8 + 0x20); - FUN_L08_002dc9a8_add(data, data, D_L08_00174640_2DC9A8 + 0x40); - FUN_L08_002dc9a8_scale(D_0015ED6C_2DC9A8 + D_0015ED6C_2DC9A8, data, data); } } break; case 99: { From b31482d7a8bb7be4154d7993e9b2a2941abd9b53 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:22:57 +0000 Subject: [PATCH 070/251] decomp: improve FUN_L00_002ebe70 --- src/overlays/shared/gameplay/vendor/002e9010.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e9010.c b/src/overlays/shared/gameplay/vendor/002e9010.c index c1ad89be4..2bd8b4199 100644 --- a/src/overlays/shared/gameplay/vendor/002e9010.c +++ b/src/overlays/shared/gameplay/vendor/002e9010.c @@ -1493,10 +1493,10 @@ void FUN_L00_002ebe70(char *o) { ((float *)&aim)[2] = 0.0f; score = FUN_001ff398_2ebe70(&scaled, &aim); if (score > 0.0f) { - score = FUN_001ff3d8_2ebe70(&diff) - score * 10.0f; - if (score < best) { - best = score; + target = FUN_001ff3d8_2ebe70(&diff) - score * 10.0f; + if (target < best) { chosen = candidate; + best = target; } } } From e17f185fda8121bad635c8680ff4e04f2906e55d Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:25:25 +0000 Subject: [PATCH 071/251] decomp: improve FUN_L05_00262f50 --- src/overlays/shared/ui/text/00262ae8.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/ui/text/00262ae8.c b/src/overlays/shared/ui/text/00262ae8.c index 9eec2298e..2866a945c 100644 --- a/src/overlays/shared/ui/text/00262ae8.c +++ b/src/overlays/shared/ui/text/00262ae8.c @@ -280,8 +280,7 @@ s32 FUN_L05_00262f50(char *e) { } } else if (D_L05_0015FAD8 == 4) value = 4; if (value >= 0) { - if (D_L05_0015FAD4 >= 4) i = 2; - else i = (D_L05_0015FAD4 < 2) ^ 1; + i = D_L05_0015FAD4 >= 4 ? 2 : (D_L05_0015FAD4 < 2) ^ 1; group = value + i * 5; D_L05_0015FAF0 = group; D_L05_0015FB00 = D_L05_0017E918[group]; @@ -333,7 +332,7 @@ s32 FUN_L05_00262f50(char *e) { group = get_icon_frame(0x7558, 1); FUN_L00_0023b6c0(group, x, y, value, 0x40, 0x80); draw_hud_sprite(get_icon_frame(0x7558, 0), x, y, 0x100, 0x40, 0x80); - value = hero.pad_8AE[0]; + value = hero.unk8AE; if (scale_game_frames(0x78) < value) { period = scale_game_frames(0x3c); pulse = fast_sin(convert_integer_to_float(D_L05_0015F5CC % period) / (f32)period * From 5649a36939b639cc5f7b88795af246c0e03fdeff Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:29:03 +0000 Subject: [PATCH 072/251] decomp: improve update_leg_rig_motion --- src/overlays/l04/runtime/dma/002922d0.c | 66 +++++++++++-------------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/src/overlays/l04/runtime/dma/002922d0.c b/src/overlays/l04/runtime/dma/002922d0.c index 447d067c4..f38539468 100644 --- a/src/overlays/l04/runtime/dma/002922d0.c +++ b/src/overlays/l04/runtime/dma/002922d0.c @@ -410,7 +410,8 @@ extern float FUN_001f99c0(float); extern float D_L04_0015ED60 __asm__("D_L04_0015ED60"); extern float D_L04_0015ED68 __asm__("D_L04_0015ED68"); extern float D_L04_0015ED6C __asm__("D_L04_0015ED6C"); -extern float D_L04_0015816C __asm__("D_L04_0015816C"); +/* Retail -0x7e94($gp), with $gp = 0x166c00, addresses 0x0015ed6c. */ +extern float D_L04_0015816C __asm__("D_L04_0015ED6C") __attribute__((sda)); extern float D_L04_00173FF8 __asm__("D_L04_00173FF8"); extern int D_L04_00173FF0[] __asm__("D_L04_00173FF0"); @@ -496,40 +497,25 @@ int FUN_L04_00295778(struct Moby *m, LegRig *rig, float amount, float target, fl rig_step(m, rig, amount, target, step, changed); if ((rig->unkEE & 4) == 0) { rig_probe_setup(m, 0, &result, local.joints, &probe_start, &probe_end); - if (m->prev_seq == rig->anims[3]->id) - goto double_height; - if (m->prev_seq == rig->anims[1]->id) - goto double_height; - if (m->prev_seq == rig->anims[2]->id) { -double_height: - height = rig->unkE0; - height += height; - goto store_height; + if (m->prev_seq == rig->anims[3]->id || + m->prev_seq == rig->anims[1]->id || + m->prev_seq == rig->anims[2]->id) { + *(float *)&rig->unkE8 = rig->unkE0 + rig->unkE0; + } else if (m->prev_seq == rig->anims[7]->id && (rig->mode & 15)) { + *(float *)&rig->unkE8 = rig->unkE0 + rig->unkE0; + } else if (m->prev_seq == m->seq) { + *(float *)&rig->unkE8 *= 0.9f; } - if (m->prev_seq == rig->anims[7]->id) { - if ((rig->mode & 15) == 0) - goto decay_height; - height = rig->unkE0 + rig->unkE0; - goto store_height; - } -decay_height: - if (m->prev_seq == m->seq) - *(float *)&rig->unkE8 = *(float *)&rig->unkE8 * 0.9f; - height = *(float *)&rig->unkE8; - goto have_height; -store_height: - *(float *)&rig->unkE8 = height; height = *(float *)&rig->unkE8; -have_height: *(float *)&local.joints[2] += height; probe_end -= height; rig_sub_vector(local.v.offset, (float *)&m->pos, (float *)local.joints); - for (i = 0; i < 8 && rig_probe((float *)local.joints, probe_start, probe_end, 4, m); i++) { - ((int *)local.joints)[0] = D_L04_00173FF0[0]; - ((int *)local.joints)[1] = D_L04_00173FF0[1]; - ((int *)local.joints)[2] = D_L04_00173FF0[2]; - ((int *)local.joints)[3] = D_L04_00173FF0[3]; - flags |= 1; + { + int i; + for (i = 0; i < 8 && rig_probe((float *)local.joints, probe_start, probe_end, 4, m); i++) { + *(u128 *)local.joints = *(u128 *)D_L04_00173FF0; + flags |= 1; + } } rig_sub_vector((float *)transformed, (float *)local.joints, (float *)&m->pos); add_vector_xyz((float *)&m->pos, (float *)local.joints, local.v.offset); @@ -547,16 +533,24 @@ int FUN_L04_00295778(struct Moby *m, LegRig *rig, float amount, float target, fl m->anim_speed = 1.0f; first = rig->anims; if (rig->unkB7 != 0) { + i = 0; entry = first; - for (i = 0; i < 13; i++, entry++, first++) { + for (; i < 13; i++, entry++, first++) { if ((*entry)->id == m->seq) { - if (rig->speed < D_L04_0015ED6C * 0.19f) { + if (rig->speed < *(float *)0x0015ed6c * 0.19f) { height = rig_angle_difference(m->rot.z, target); - if (0.09239978f < height && amount < D_L04_0015816C * 0.19f) - entry = first; + if (0.09239978f < height) { + /* Retail retains this threshold as the rate numerator. */ + time = D_L04_0015816C * 0.19f; + if (amount < time) { + m->anim_speed = D_L04_0015ED68 * FUN_001f99c0(time / (*first)->rate); + break; + } + } } - m->anim_speed = D_L04_0015ED68 * FUN_001f99c0(rig->speed / (*entry)->rate); - return flags; + time = rig->speed; + m->anim_speed = D_L04_0015ED68 * FUN_001f99c0(time / (*entry)->rate); + break; } } } From e32685315c2fb06f396a15e2bffbe2bb1707aadf Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:30:42 +0000 Subject: [PATCH 073/251] decomp: improve update_motion_and_emit_effects --- src/overlays/l13/gameplay/vendor/003058a8.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/overlays/l13/gameplay/vendor/003058a8.c b/src/overlays/l13/gameplay/vendor/003058a8.c index c210ba03b..ab327dd42 100644 --- a/src/overlays/l13/gameplay/vendor/003058a8.c +++ b/src/overlays/l13/gameplay/vendor/003058a8.c @@ -1917,6 +1917,8 @@ typedef union { float f[4]; } L13EffectVector; +#include "qzero.h" + void FUN_L13_0030c3b8(struct Moby *moby) { char *data = (char *)moby->pvars; L13EffectVector old_pos, position, velocity, acceleration, second_pos; @@ -1929,11 +1931,11 @@ void FUN_L13_0030c3b8(struct Moby *moby) { acceleration.f[3] = D_L13_00161F60; i = 1; do { - position.quad = *(OvlQuad *)&moby->pos; + qcopy(&position, &moby->pos); position.f[0] += random_float_between_alt(-0.065f, 0.065f); position.f[1] += random_float_between_alt(-0.065f, 0.065f); position.f[2] += random_float_between_alt(-0.065f, 0.065f); - *(volatile OvlQuad *)&velocity = 0; + qzero(&velocity); i--; velocity.f[2] = random_float_between_alt(D_L13_00161F30 * frame_time * 0.9f, D_L13_00161F30 * frame_time * 1.1f); @@ -1958,12 +1960,12 @@ void FUN_L13_0030c3b8(struct Moby *moby) { acceleration.f[3] = D_L13_00161F68; i = 1; do { - second_pos.quad = *(OvlQuad *)&moby->pos; + qcopy(&second_pos, &moby->pos); second_pos.f[0] += random_float_between_alt(-0.1f, 0.1f); second_pos.f[1] += random_float_between_alt(-0.1f, 0.1f); second_pos.f[2] += random_float_between_alt(-0.1f, 0.1f); random_float_between_alt(-D_L13_00161F58, D_L13_00161F58); - *(volatile OvlQuad *)&velocity = 0; + qzero(&velocity); i--; velocity.f[2] = random_float_between_alt(D_L13_00161F44 * frame_time * 0.7f, D_L13_00161F44 * frame_time * 1.5f); From 7411c404bd130bcb5025e31f75f13f2586968349 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:31:12 +0000 Subject: [PATCH 074/251] decomp: improve FUN_L00_0020dd20 --- src/overlays/shared/ui/help/0020c758.c | 77 ++++++++++++++------------ 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index b610c542d..bda41b5b4 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -703,12 +703,14 @@ void FUN_L00_0020dd20(void) { active = 0; if (hero_ptr->unk20AB && (i == 0 || hero_ptr->unk20AB == 2)) active = 1; - if (hero_ptr->unk20AF) { + if (hero.unk20AF) { active = 0; + slot = (u8 **)&hero.unkD00 + i; if (*slot) *(s32 *)(*slot + 0x34) = 1; } if (active) { + slot = (u8 **)&hero.unkD00 + i; next = i + 1; if (*slot == 0) { *slot = FUN_L00_0024f028_20dd20((u8 *)hero_ptr->moby, D_L00_0015F6A0_20dd20[i]); @@ -716,6 +718,7 @@ void FUN_L00_0020dd20(void) { *(s32 *)(*slot + 0x18) = D_L00_00197300_20dd20[D_L00_00197BC0_20dd20[next]]; } } else { + slot = (u8 **)&hero.unkD00 + i; next = i + 1; if (*slot == 0) goto next_slot; @@ -726,14 +729,14 @@ void FUN_L00_0020dd20(void) { obj = *((u8 **)&hero.unkD00 + i); if (obj) { moby = (u8 *)hero_ptr->moby; - same = moby[0x52] == ((u8 *)hero_ptr->moby)[0x53]; - if (hero_ptr->unkD08[0] && !hero_ptr->unkD14) { + same = moby[0x52] != ((u8 *)hero_ptr->moby)[0x53]; + if (hero.unkD08[0] && !hero.unkD14) { FUN_00213ed8_20dd20((f32 *)(obj + 8), zero, frame_scale * tenth); } else if (*(s32 *)(obj + 0x34) == 0) { FUN_00213ed8_20dd20((f32 *)(obj + 8), 1.0f, frame_scale * tenth); } change = 0; - if (!same && hero_ptr->unkA9C) { + if (same && hero.unkA9C) { if (FUN_L00_002050b8_20dd20(obj[0x23]) != FUN_L00_002050b8_20dd20(((u8 *)hero_ptr->moby)[0x53])) change = obj[0x22] != obj[0x23]; } @@ -752,7 +755,9 @@ void FUN_L00_0020dd20(void) { ANGLE_FIELD_20DD20(0x6d4) = angle_scale_small; ANGLE_FIELD_20DD20(0x6d8) = angle_scale_large; } - if (handled) { + if (handled == 0) + goto unhandled_update; + { if (obj[0x32] == 0 || obj[0x23] != 0) { if (obj[0x22] == obj[0x23] || 0.5f < *(f32 *)(obj + 0x24)) { obj[0x22] = obj[0x23]; @@ -769,8 +774,13 @@ void FUN_L00_0020dd20(void) { obj[0x33] = 0; *(f32 *)(obj + 0x2c) = one / (f32)j; } + } + if (handled != 0) { *(f32 *)(obj + 0x28) = one; - } else { + goto special_textures; + } +unhandled_update: + { if (obj[0x33] == 0) { obj[0x23] = FUN_L00_0020d5b8_20dd20((u8 *)hero_ptr->moby, ((u8 *)hero_ptr->moby)[0x53]); obj[0x21] = 0; @@ -786,24 +796,24 @@ void FUN_L00_0020dd20(void) { obj[0x32] = 0; } } +special_textures: { u8 *enabled = obj + 6; u8 *symbol = obj + 0x22; u8 **texture = (u8 **)(obj + 0x38); u8 *texture_base = D_L00_0017CA80_20dd20 + i * 0x800; - j = 0; - do { - if (symbol[j] < 0x17) { - *enabled = 1; - *texture = texture_base; - } else { - *enabled = 0; - } - enabled++; - texture++; - texture_base += 0x400; - j++; - } while (j < 2); + if (symbol[0] < 0x17) { + enabled[0] = 1; + texture[0] = texture_base; + } else { + enabled[0] = 0; + } + if (symbol[1] < 0x17) { + enabled[1] = 1; + texture[1] = texture_base + 0x400; + } else { + enabled[1] = 0; + } } FUN_L00_0024f190_20dd20((u8 *)hero_ptr->moby, obj); } @@ -813,7 +823,7 @@ void FUN_L00_0020dd20(void) { if (*(s16 *)(obj + 0x30) == 0) { j = 0; do { - if (same || j == 1) + if (!same || j == 1) obj[0x22 + j] = FUN_L00_0020d5b8_20dd20((u8 *)hero_ptr->moby, ((u8 *)hero_ptr->moby)[0x52 + j]); j++; } while (j < 2); @@ -827,7 +837,7 @@ void FUN_L00_0020dd20(void) { *(u16 *)(obj + 0x30) = 0; } } else { - if (same) + if (!same) obj[0x20] = ((u8 *)hero_ptr->moby)[0x50]; obj[0x21] = ((u8 *)hero_ptr->moby)[0x51]; *(f32 *)(obj + 0x24) = *(f32 *)((u8 *)hero_ptr->moby + 0x54); @@ -837,19 +847,18 @@ void FUN_L00_0020dd20(void) { u8 *enabled = obj + 6; u8 **texture = (u8 **)(obj + 0x38); u8 *texture_base = D_L00_0017CA80_20dd20 + i * 0x800; - j = 0; - do { - if (symbol[j] < 0x17) { - *enabled = 1; - *texture = texture_base; - } else { - *enabled = 0; - } - enabled++; - texture++; - texture_base += 0x400; - j++; - } while (j < 2); + if (symbol[0] < 0x17) { + enabled[0] = 1; + texture[0] = texture_base; + } else { + enabled[0] = 0; + } + if (symbol[1] < 0x17) { + enabled[1] = 1; + texture[1] = texture_base + 0x400; + } else { + enabled[1] = 0; + } } FUN_L00_0024f190_20dd20((u8 *)hero_ptr->moby, obj); } From a5feaee16435c0ef09a0890c538b5b5a766b491c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:31:38 +0000 Subject: [PATCH 075/251] decomp: improve FUN_L15_002aa280 --- src/overlays/l15/gameplay/entities/0029aff0.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/overlays/l15/gameplay/entities/0029aff0.c b/src/overlays/l15/gameplay/entities/0029aff0.c index ffa1373b5..5c7525bf1 100644 --- a/src/overlays/l15/gameplay/entities/0029aff0.c +++ b/src/overlays/l15/gameplay/entities/0029aff0.c @@ -743,8 +743,8 @@ void FUN_L15_002aa280(struct Moby *moby) { float radius, angle; - int i = 0x18; - do { + int i = 0x19; + while (--i >= 0) { int duration; angle = random_float_between_7880(moby->rot.z, 1.5707963267948966f); radius = fast_cos_7880(angle); @@ -771,8 +771,7 @@ void FUN_L15_002aa280(struct Moby *moby) size = random_float_between_7880(3.0f, 7.0f); FUN_L01_002f8530_7880(&offset, &velocity, *palette_entry, radius, duration, size, 0.15f, 2.0f, 1); - i--; - } while (i >= 0); + } } clear_u64_value_7880(&velocity); FUN_L00_0025e450_7880(moby, &velocity, &base, 0.0f, 0.0f, 20, From 06c76826c3caeaaf757c314af426e67977e54d8a Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:29:07 +0000 Subject: [PATCH 076/251] decomp: improve FUN_L12_00304e00 --- src/overlays/l12/gameplay/vendor/003028c8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/l12/gameplay/vendor/003028c8.c b/src/overlays/l12/gameplay/vendor/003028c8.c index de7ab7914..da955e16b 100644 --- a/src/overlays/l12/gameplay/vendor/003028c8.c +++ b/src/overlays/l12/gameplay/vendor/003028c8.c @@ -1168,12 +1168,12 @@ void FUN_L12_00304e00(struct Moby *moby) { direction[2] = 1.2f; func_L00_0025A8C0_304310(hit_info, moby, 0x10001, 1.0f, direction); *(volatile u128 *)position = *(volatile u128 *)position_source; - ((volatile float *)position)[2] += 0.4f; + position[2] = position_source[2] + 0.4f; if (!collect_mobies_in_sphere(position, 0x10, moby, hit_info, 0.4f) || !*(int *)0x001742d8 || *(short *)(*(int *)0x001742d8 + 0xa6) == 0x4f5 || *(int *)0x001742d8 == *(int *)((char *)moby + 0xb8)) { *(volatile u128 *)position = *(volatile u128 *)position_source; - ((volatile float *)position)[2] += 0.35f; + position[2] = position_source[2] + 0.35f; if (coll_sphere(position, 0, moby, 0.35f)) moby->state = 2; } else moby->state = 2; } From 3a5f4e8a844ac00a492aef93affd8549525bd5d7 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:36:59 +0000 Subject: [PATCH 077/251] decomp: improve FUN_L06_003049f8 --- src/overlays/l06/gameplay/entities/002fd1a0.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/overlays/l06/gameplay/entities/002fd1a0.c b/src/overlays/l06/gameplay/entities/002fd1a0.c index 60cb3a8a5..5c1e47001 100644 --- a/src/overlays/l06/gameplay/entities/002fd1a0.c +++ b/src/overlays/l06/gameplay/entities/002fd1a0.c @@ -2406,7 +2406,8 @@ void FUN_L06_003049f8(char *m) { float *p = points; float *q = scratch; int j; - for (j = 29; j >= 0; j--) { + int index; + for (index = 29; index >= 0; index--) { float scale; FUN_L06_00217300(p); p += 4; @@ -2421,7 +2422,7 @@ void FUN_L06_003049f8(char *m) { /* The completed countdown is -1: these cursors start at * the second and third scratch vectors. */ float *second, *third; - j += 2; + j = index + 2; second = scratch + j * 4; third = scratch + (j + 1) * 4; q = scratch; From 7bcefe8622190f6656807f6a525e842738f36b84 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:37:09 +0000 Subject: [PATCH 078/251] decomp: improve FUN_L06_002fbfb0 --- src/overlays/l06/gameplay/entities/002b4770.c | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/overlays/l06/gameplay/entities/002b4770.c b/src/overlays/l06/gameplay/entities/002b4770.c index dcd8a5038..d84d1e8e1 100644 --- a/src/overlays/l06/gameplay/entities/002b4770.c +++ b/src/overlays/l06/gameplay/entities/002b4770.c @@ -2212,6 +2212,7 @@ void FUN_L06_002fbfb0(char *moby) { float acceleration, max_speed, damping, rotation_acceleration, rotation_speed, rotation_damping; int next_timer; unsigned char next_phase; + int phase; switch ((unsigned char)moby[0x20]) { case 0: @@ -2254,8 +2255,10 @@ void FUN_L06_002fbfb0(char *moby) { allocate_voice_for_target_entry(0, 0, (int)*(char **)(data + 0x40)); return; case 3: - a = FUN_001f9b48(moby + 0x10, data + 0x10); - b = FUN_001f9b48(*(char **)(data + 0x40) + 0x10, data + 0x10); + target_delta = FUN_001f9b48(moby + 0x10, data + 0x10); + child = *(char **)(data + 0x40); + a = target_delta; + b = FUN_001f9b48(child + 0x10, data + 0x10); FUN_00213f38(&a, &((float *)data)[2], D_L06_00161F1C, frame_time_sq * 10.0f, frame_time_sq * 20.0f, frame_time * 5.0f); FUN_00213f38(&b, &((float *)data)[0x11], D_L06_00161F20, frame_time_sq * 10.0f, frame_time_sq * 20.0f, frame_time * 5.0f); FUN_001f9bf8(v, data + 0x30, a); @@ -2266,16 +2269,19 @@ void FUN_L06_002fbfb0(char *moby) { if (absolute_float(a - D_L06_00161F1C) < 0.01f && absolute_float(b - D_L06_00161F20) < 0.01f) moby[0x20] = 5; return; case 4: - phase_a = FUN_001f9b48(moby + 0x10, data + 0x10); - phase_b = FUN_001f9b48(*(char **)(data + 0x40) + 0x10, data + 0x10); - if ((unsigned char)moby[0xbc] == 1) goto phase_one; - if ((int)(unsigned char)moby[0xbc] < 2) goto phase_default; - if ((unsigned char)moby[0xbc] == 2) goto phase_two; + target_delta = FUN_001f9b48(moby + 0x10, data + 0x10); + child = *(char **)(data + 0x40); + phase_a = target_delta; + phase_b = FUN_001f9b48(child + 0x10, data + 0x10); + phase = (unsigned char)moby[0xbc]; + if (phase == 1) goto phase_one; + if (phase < 2) goto phase_default; + if (phase == 2) goto phase_two; phase_default: + target_a = D_L06_00161F24; target_rot_a = *(float *)(moby + 0x44); target_rot_b = target_rot_a; - target_a = D_L06_00161F24; target_b = D_L06_00161F28; acceleration = 10.0f; max_speed = 20.0f; @@ -2301,10 +2307,10 @@ void FUN_L06_002fbfb0(char *moby) { next_timer = func_001FA898_r(random_float_between_alt((float)D_L06_00161F54, (float)D_L06_00161F58)); goto phase_join; phase_two: - target_rot_a = D_L06_00161F2C; - target_rot_b = D_L06_00161F30; target_a = D_L06_00161F24; + target_rot_a = D_L06_00161F2C; target_b = D_L06_00161F28; + target_rot_b = D_L06_00161F30; acceleration = D_L06_00161F34; max_speed = D_L06_00161F38; damping = D_L06_00161F3C; @@ -2314,10 +2320,11 @@ void FUN_L06_002fbfb0(char *moby) { next_phase = 1; next_timer = func_001FA898_r(random_float_between_alt((float)D_L06_00161F4C, (float)D_L06_00161F50)); phase_join: + target_delta = target_rot_b; FUN_00213f38(&phase_a, &((float *)data)[2], target_a, acceleration * frame_time_sq, max_speed * frame_time_sq, damping * frame_time); FUN_00213f38(&phase_b, &((float *)data)[0x11], target_b, acceleration * frame_time_sq, max_speed * frame_time_sq, damping * frame_time); FUN_00213f38((float *)(moby + 0x44), &((float *)data)[3], target_rot_a, rotation_acceleration * DEG_TO_RAD * frame_time_sq, rotation_speed * DEG_TO_RAD * frame_time_sq, rotation_damping * DEG_TO_RAD * frame_time); - FUN_00213f38((float *)(*(char **)(data + 0x40) + 0x44), &((float *)data)[0x12], target_rot_b, rotation_acceleration * DEG_TO_RAD * frame_time_sq, rotation_speed * DEG_TO_RAD * frame_time_sq, rotation_damping * DEG_TO_RAD * frame_time); + FUN_00213f38((float *)(*(char **)(data + 0x40) + 0x44), &((float *)data)[0x12], target_delta, rotation_acceleration * DEG_TO_RAD * frame_time_sq, rotation_speed * DEG_TO_RAD * frame_time_sq, rotation_damping * DEG_TO_RAD * frame_time); FUN_001f9bf8(v, data + 0x30, phase_a); FUN_001f9a10(moby + 0x10, data + 0x10, v); FUN_001f9bf8(v, data + 0x30, -phase_b); From f10988fe01c1af18c67e295e503d8d7c8acd0331 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:38:17 +0000 Subject: [PATCH 079/251] decomp: improve FUN_L18_002e9768 --- src/overlays/l18/gameplay/entities/002a7220.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/l18/gameplay/entities/002a7220.c b/src/overlays/l18/gameplay/entities/002a7220.c index bec02d48e..76327f93e 100644 --- a/src/overlays/l18/gameplay/entities/002a7220.c +++ b/src/overlays/l18/gameplay/entities/002a7220.c @@ -2363,7 +2363,7 @@ void FUN_L18_002e9768(struct Moby *moby) { return; case 2: if (moby->oclass == 0x37c) { - float *pos = &moby->pos.x; + float *pos; { int i; int *first, *second; @@ -2371,6 +2371,7 @@ void FUN_L18_002e9768(struct Moby *moby) { float colors2[6]; float position[4]; i = 0; + pos = &moby->pos.x; do { magnitude = random_float_between_9768(8.0f, 10.0f) * frame_time; __builtin_memcpy(colors, D_L18_001F29A0_9768, 24); From 95ec85a4bb2f3bc1677fe4f6d9dd6434a393cf0f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:36:00 +0000 Subject: [PATCH 080/251] decomp: improve FUN_L07_0030d4d8 --- src/overlays/l07/gameplay/entities/002cd2b0.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/overlays/l07/gameplay/entities/002cd2b0.c b/src/overlays/l07/gameplay/entities/002cd2b0.c index 0a8547428..b614646bd 100644 --- a/src/overlays/l07/gameplay/entities/002cd2b0.c +++ b/src/overlays/l07/gameplay/entities/002cd2b0.c @@ -1833,12 +1833,14 @@ void FUN_L07_0030d4d8(struct Moby *moby) { if (src && *(char **)(src + 0x20) && *(short *)(*(char **)(src + 0x20) + 0xa6) == 0x372) goto animate; /* Retail still reads damage at address 0x2c when src is null. */ if (*health <= *(float *)(src + 0x2c)) { + void *effect_rotation = &moby->rot; + void *effect_position = &moby->pos; FUN_L00_00257470(moby, 0, -1); *(float *)(data + 0x20) = 0.0f; FUN_001f99f8(&offset); FUN_L00_0025e450_l07(0.0f, 0.0f, 4.0f, 2.0f, 9.0f, 1.0f, 15.0f, moby, &offset, 0, 10, 3, 16, 1, 1, 1, -1, 0); - FUN_L00_00263fd8(moby, 0x621, &moby->pos, &moby->rot, 0, 0, 0.0f, D_L07_0015F580, D_L07_0015F580, D_L07_0015F580); - FUN_L00_00263fd8(moby, 0x622, &moby->pos, &moby->rot, 0, 0, 0.0f, D_L07_0015F580, D_L07_0015F580, D_L07_0015F580); + FUN_L00_00263fd8(moby, 0x621, effect_position, effect_rotation, 0, 0, 0.0f, D_L07_0015F580, D_L07_0015F580, D_L07_0015F580); + FUN_L00_00263fd8(moby, 0x622, effect_position, effect_rotation, 0, 0, 0.0f, D_L07_0015F580, D_L07_0015F580, D_L07_0015F580); mark_moby_for_removal(moby); return; } From 77fa7a6f160c3c71085591401227023a6c7a5d30 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:44:17 +0000 Subject: [PATCH 081/251] decomp: improve update_path_camera --- .../shared/gameplay/vendor/002e3de8.c | 140 ++++++++++-------- 1 file changed, 79 insertions(+), 61 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index 2e193c0c6..4d63a3026 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -392,7 +392,7 @@ extern float D_L10_0015F3FC_sda __asm__("D_L10_0015F3FC") __attribute__((sda)); extern int D_L10_0015F404; extern float D_0015ED6C; extern char *D_L10_0015FFD8 __attribute__((sda)); -extern char *D_L10_0015FFD8_far __asm__("D_L10_0015FFD8"); +extern char *D_L10_0015FFD8_far __asm__("D_L10_0015FFD8") __attribute__((section(".data"))); extern float D_L10_00167358; extern float D_L10_0016CF70; extern void subtract_vector_xyz(void *, void *, void *) __asm__("FUN_001f9a28"); @@ -416,59 +416,67 @@ extern void FUN_001e93e8_part(void *, void *) __asm__("FUN_001e93e8"); extern float D_L10_00167450[]; extern float D_0013F5E0[]; +extern char D_L10_0016CEC0[]; +extern float D_L10_0016CF70_far __asm__("D_L10_0016CF70") __attribute__((section(".data"))); + void FUN_L10_002f5f18(char *moby) { char *work = *(char **)(moby + 0x70); - char *acc = work + 0x40; + short *indices = (short *)(work + 0x58); + char *acc = (char *)indices - 0x18; int slot = *(short *)(moby + 0x84); - char *data = *(char **)(D_L10_0015EF50 + slot * 0x20 + 0x1c); + unsigned char *data = *(unsigned char **)(D_L10_0015EF50 + slot * 0x20 + 0x1c); char *path; float old_pos[4] __attribute__((aligned(16))); - float target[4] __attribute__((aligned(16))); + union { float target[4]; float direction[4]; } vectors __attribute__((aligned(16))); float transformed[4] __attribute__((aligned(16))); - float direction[4] __attribute__((aligned(16))); float point[4] __attribute__((aligned(16))); - float *scale = (float *)(moby + 0x30); - int i, segment, count, next, index; - int reached; + float *scale; + int i, count, next, index; + long long segment; + long long reached; float angle, first, total, distance, fade; - short *indices = (short *)(acc + 0x18); + float *distance_cursor; if (*(short *)(acc + 0x14) == 0) { - fade = D_L10_0015F3FC + 0.05f; - D_L10_0015F3FC_sda = fade; - if (!(1.0f <= fade)) return; + char *other; + D_L10_0015F3FC_sda = D_L10_0015F3FC + 0.05f; + if (!(1.0f <= D_L10_0015F3FC_sda)) return; path = D_L10_001B0930_5a78[*(int *)(data + 0x20)]; + other = D_L10_001B0930_5a78[*(int *)(data + 0x24)]; + scale = (float *)(moby + 0x30); D_L10_0015F3FC = 1.0f; D_L10_0015F404 = 1; *(short *)(acc + 0x14) = 1; - *(u128 *)scale = *(u128 *)(path + 0x10); - if (*(int *)(data + 0x28) < 0) { - subtract_vector_xyz(old_pos, D_L10_001B0930_5a78[*(int *)(data + 0x24)] + 0x10, scale); - } else { - target[0] = *(float *)(data + 0x2c); - target[1] = *(float *)(data + 0x30); - target[2] = *(float *)(data + 0x34); - target[3] = 0.0f; - transform_vector_by_basis(target, target, D_L10_00167450); + path += 0x10; + *(u128 *)scale = *(u128 *)path; + if (*(int *)(data + 0x28) >= 0) { path = D_L10_0015FFD8 + *(int *)(data + 0x28) * 0x100; - add_vector_xyz(transformed, path + 0x10, target); + vectors.target[0] = *(float *)(data + 0x2c); + vectors.target[1] = *(float *)(data + 0x30); + vectors.target[2] = *(float *)(data + 0x34); + vectors.target[3] = 0.0f; + transform_vector_by_basis(vectors.target, vectors.target, D_L10_00167450); + add_vector_xyz(transformed, path + 0x10, vectors.target); subtract_vector_xyz(old_pos, transformed, scale); + } else { + subtract_vector_xyz(old_pos, other + 0x10, scale); } - FUN_001f9a68(-1.0f, target, D_0013F5E0); + FUN_001f9a68(-1.0f, vectors.target, D_0013F5E0); scale_vector_xyz(1.0f, moby, old_pos); - cross_vectors_xyz(moby + 0x10, moby, target); + cross_vectors_xyz(moby + 0x10, moby, vectors.target); scale_vector_xyz(1.0f, moby + 0x10, moby + 0x10); cross_vectors_xyz(moby + 0x20, moby + 0x10, moby); return; } if (*(short *)(acc + 0x14) == 2) { - fade = D_L10_0015F3FC + 0.05f; - D_L10_0015F3FC_sda = fade; - if (fade >= 1.0f) { + D_L10_0015F3FC_sda = D_L10_0015F3FC + 0.05f; + if (D_L10_0015F3FC_sda >= 1.0f) { *(short *)(acc + 0x14) = 3; D_L10_0015F3FC = 1.0f; - angle = *(float *)(work + 0x88) * 0.5f; - D_L10_0016CF70 = FUN_001f9de0(angle) / FUN_001f9dc8(angle); + angle = *(float *)((char *)indices + 0x30) * 0.5f; + distance = FUN_001f9de0(angle); + fade = FUN_001f9dc8(angle); + D_L10_0016CF70_far = distance / fade; update_view_context(); data[0x39] = 1; D_L10_00167358 = 0.05f; @@ -479,11 +487,11 @@ void FUN_L10_002f5f18(char *moby) { if (*(int *)(data + 0x40) == 0) return; } else { if (*(short *)(acc + 0x14) == 3) return; - fade = D_L10_0015F3FC_sda - 0.05f; - D_L10_0015F3FC_sda = fade; - if (fade < 0.0f) D_L10_0015F3FC = 0.0f; + D_L10_0015F3FC_sda -= 0.05f; + if (D_L10_0015F3FC_sda < 0.0f) D_L10_0015F3FC = 0.0f; } path = D_L10_001B0930_5a78[*(int *)(data + 0x20)]; + scale = (float *)(moby + 0x30); *(u128 *)old_pos = *(u128 *)scale; reached = FUN_L00_0025d808(path, scale, (int *)(acc + 0x00), (float *)(acc + 0x04), *(float *)(data + 0x3c) * D_0015ED6C, 0); @@ -495,64 +503,74 @@ void FUN_L10_002f5f18(char *moby) { reached = 1; } } - if (data[0x39] != 0) reached = 1; + if ((unsigned char)data[0x39] != 0) reached = 1; if (reached) { *(short *)(acc + 0x14) = 2; if (*(int *)(data + 0x40) == 0) return; } if (indices[0] >= 0 && indices[1] >= 0) { - for (i = 0; i < 7 && indices[i] >= 0 && indices[i + 1] >= 0; i++) { + i = 0; + do { + next = i + 1; segment = *(int *)(acc + 0x00); - if (indices[i] <= segment && segment < indices[i + 1]) { - total = 0.0f; - if (indices[i] < segment) { - count = segment - indices[i]; - index = indices[i]; + index = indices[i]; + if (index <= segment && segment < indices[next]) { + first = 0.0f; + if (index < segment) { + count = segment - index; + distance_cursor = (float *)(path + (index * 0x10 + 0x1c)); do { - total += *(float *)(path + index * 0x10 + 0x1c); - index++; + first += *distance_cursor; + distance_cursor += 4; count--; } while (count != 0); } - first = total + *(float *)(acc + 0x04); - if (segment < indices[i + 1]) { - count = indices[i + 1] - segment; + total = first; + first = first + *(float *)(acc + 0x04); + if (segment < indices[next]) { + count = indices[next] - segment; index = segment; + distance_cursor = (float *)(path + (index * 0x10 + 0x1c)); do { - total += *(float *)(path + index * 0x10 + 0x1c); - index++; + total += *distance_cursor; + distance_cursor += 4; count--; } while (count != 0); } - angle = cosine_interpolate(((float *)(acc + 0x28))[i], - ((float *)(acc + 0x28))[i + 1], first / total); + angle = cosine_interpolate(((float *)((char *)indices + 0x10))[i], + ((float *)((char *)indices + 0x10))[next], first / total); angle = angle * 0.017453292f * 0.5f; - D_L10_0016CF70 = FUN_001f9de0(angle) / FUN_001f9dc8(angle); + distance = FUN_001f9de0(angle); + fade = FUN_001f9dc8(angle); + *(float *)(D_L10_0016CEC0 + 0xb0) = distance / fade; update_view_context(); } - } + if (next >= 7) break; + i = next; + } while (indices[i] >= 0 && indices[i + 1] >= 0); } distance = FUN_001f9b48(old_pos, scale); *(float *)(acc + 0x10) += distance; - if (*(int *)(data + 0x28) < 0) { + if (*(int *)(data + 0x28) >= 0) { + path = D_L10_0015FFD8_far + *(int *)(data + 0x28) * 0x100; + transformed[0] = *(float *)(data + 0x2c); + transformed[1] = *(float *)(data + 0x30); + transformed[2] = *(float *)(data + 0x34); + transformed[3] = 0.0f; + transform_vector_by_basis(transformed, transformed, D_L10_00167450); + add_vector_xyz(point, path + 0x10, transformed); + subtract_vector_xyz(vectors.direction, point, scale); + } else { float zero_a = 0.0f, zero_b = 0.0f; char *other = D_L10_001B0930_5a78[*(int *)(data + 0x24)]; FUN_L00_0025d808(other, transformed, (int *)&zero_a, &zero_b, (*(float *)(acc + 0x10) / *(float *)(acc + 0x08)) * *(float *)(acc + 0x0c), 0); FUN_001e93e8(0.2f, transformed); FUN_001e93e8_part(other + 0x10, other + *(int *)other * 0x10); - subtract_vector_xyz(direction, transformed, scale); - } else { - transformed[0] = *(float *)(data + 0x2c); - transformed[1] = *(float *)(data + 0x30); - transformed[2] = *(float *)(data + 0x34); - transformed[3] = 0.0f; - transform_vector_by_basis(transformed, transformed, D_L10_00167450); - add_vector_xyz(point, D_L10_0015FFD8_far + *(int *)(data + 0x28) * 0x100 + 0x10, transformed); - subtract_vector_xyz(direction, point, scale); + subtract_vector_xyz(vectors.direction, transformed, scale); } FUN_001f9a68(-1.0f, transformed, D_0013F5E0); - scale_vector_xyz(1.0f, moby, direction); + scale_vector_xyz(1.0f, moby, vectors.direction); cross_vectors_xyz(moby + 0x10, moby, transformed); scale_vector_xyz(1.0f, moby + 0x10, moby + 0x10); cross_vectors_xyz(moby + 0x20, moby + 0x10, moby); From 40ff3130bdf914dc94d657c21d05a6ee92159c8d Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:01:52 +0000 Subject: [PATCH 082/251] decomp: improve FUN_L08_002d23f0 --- src/overlays/l08/gameplay/entities/002b8228.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/l08/gameplay/entities/002b8228.c b/src/overlays/l08/gameplay/entities/002b8228.c index 19f77bfe5..b92aa260e 100644 --- a/src/overlays/l08/gameplay/entities/002b8228.c +++ b/src/overlays/l08/gameplay/entities/002b8228.c @@ -358,7 +358,7 @@ void FUN_L08_002d23f0(char *moby) { qcopy(record.motion.from, position); record.motion.from[2] -= 0.16f; add_vector_xyz(position, position, velocity); - ((float *)velocity)[2] -= D_L08_00161860 * D_0015ED70; + *(float *)(data + 0x18) -= D_L08_00161860 * D_0015ED70; qcopy(record.motion.collision.position, position); record.motion.collision.position[2] -= 0.16f; record.motion.collision.flags = 0x810000; @@ -381,7 +381,7 @@ void FUN_L08_002d23f0(char *moby) { if (*(unsigned char *)(moby + 0xbc) & 1) { allocate_voice_for_target_entry(1, 0, moby); qcopy(position, collision_result + 0x20); - ((float *)position)[2] += 0.16f; + *(float *)(moby + 0x18) += 0.16f; rotate_vector_2d23f0(velocity, velocity, collision_result + 0x40); fast_vec_cross(impulse, velocity, collision_result + 0x40); normalize_vector_xyz(impulse, impulse, random_float_between(-(D_0015ED6C * 1.5f), D_0015ED6C * 1.5f)); From 60610713e71abbfc3806d962e9584bb80983ea2c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:09:09 +0000 Subject: [PATCH 083/251] decomp: improve FUN_L00_002a5040 --- .../shared/gameplay/entities/002a4830.c | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002a4830.c b/src/overlays/shared/gameplay/entities/002a4830.c index 8c9099e5a..73a0f906f 100644 --- a/src/overlays/shared/gameplay/entities/002a4830.c +++ b/src/overlays/shared/gameplay/entities/002a4830.c @@ -296,14 +296,15 @@ void FUN_L00_002a5040(u8 *moby) { Point_2a5040 basis[4]; f32 rotation[3]; f32 matrix[12]; + Point_2a5040 *basis0, *basis1, *basis2, *basis3; Point_2a5040 orbit_copy[4]; Point_2a5040 orbit[4]; Vars_2a5040 *vars = *(Vars_2a5040 **)(moby + 0x78); - s32 *indices = (s32 *)0x1d7460; + s32 *indices; extern f32 points[] __asm__("D_L00_001D7360"); - f32 *uvs = (f32 *)0x1d73f0; - f32 *uvs_y = (f32 *)0x1d73f4; - u32 *colors = (u32 *)0x1d7438; + f32 *uvs; + f32 *uvs_y; + u32 *colors; f32 x, y, z, phase, angle; f32 uv0, uv1, uv2, uv3; f32 u0, u1, u2, u3; @@ -324,31 +325,39 @@ void FUN_L00_002a5040(u8 *moby) { quad.kind = 1; quad.flags = 0x4000000044LL; quad.draw = 0; - quad.texture = get_effect_texture(0x18); i = 0; + indices = (s32 *)0x1d7460; + quad.texture = get_effect_texture(0x18); + basis0 = &basis[0]; + basis1 = &basis[1]; + basis2 = &basis[2]; + basis3 = &basis[3]; + uvs = (f32 *)0x1d73f0; + uvs_y = (f32 *)0x1d73f4; + colors = (u32 *)0x1d7438; do { index = i++ * 4; - transform_point_2a5040(&basis[0], points + indices[0] * 4, matrix); + transform_point_2a5040(basis0, points + indices[0] * 4, matrix); indices1 = (s32 *)0x1d7464 + index; - transform_point_2a5040(&basis[1], points + *indices1 * 4, matrix); + transform_point_2a5040(basis1, points + *indices1 * 4, matrix); indices2 = (s32 *)0x1d7468 + index; - transform_point_2a5040(&basis[2], points + *indices2 * 4, matrix); - transform_point_2a5040(&basis[3], points + indices[3] * 4, matrix); + transform_point_2a5040(basis2, points + *indices2 * 4, matrix); + transform_point_2a5040(basis3, points + indices[3] * 4, matrix); x = *(f32 *)(moby + 0x10); y = *(f32 *)(moby + 0x14); z = *(f32 *)(moby + 0x18); quad.corners[0].x = x + basis[0].x * vars->scale; - quad.corners[0].y = y + basis[0].y * vars->scale; quad.corners[0].z = z + basis[0].z; + quad.corners[1].z = z + basis[1].z; + quad.corners[0].y = y + basis[0].y * vars->scale; + quad.corners[2].z = z + basis[2].z; + quad.corners[3].z = z + basis[3].z; quad.corners[1].x = x + basis[1].x * vars->scale; quad.corners[1].y = y + basis[1].y * vars->scale; - quad.corners[1].z = z + basis[1].z; quad.corners[2].x = x + basis[2].x * vars->scale; quad.corners[2].y = y + basis[2].y * vars->scale; - quad.corners[2].z = z + basis[2].z; quad.corners[3].x = x + basis[3].x * vars->scale; quad.corners[3].y = y + basis[3].y * vars->scale; - quad.corners[3].z = z + basis[3].z; index1 = *indices1; index2 = *indices2; index = indices[0]; @@ -413,10 +422,10 @@ void FUN_L00_002a5040(u8 *moby) { rotation[1] = 0.0f; rotation[2] = D_L00_00166C80_2a5040.f158; vu_euler_rotation_basis(matrix, rotation); - transform_point_2a5040(&basis[0], &orbit_copy[0], matrix); - transform_point_2a5040(&basis[1], &orbit_copy[1], matrix); - transform_point_2a5040(&basis[2], &orbit_copy[2], matrix); - transform_point_2a5040(&basis[3], &orbit_copy[3], matrix); + transform_point_2a5040(basis0, &orbit_copy[0], matrix); + transform_point_2a5040(basis1, &orbit_copy[1], matrix); + transform_point_2a5040(basis2, &orbit_copy[2], matrix); + transform_point_2a5040(basis3, &orbit_copy[3], matrix); x = *(f32 *)(moby + 0x10); y = *(f32 *)(moby + 0x14); z = *(f32 *)(moby + 0x18); From e78f0dfd1c91f52159cc34cfaa5bc664a71df9ad Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:05:01 +0000 Subject: [PATCH 084/251] decomp: improve FUN_L00_002484e0 --- src/overlays/shared/ui/map/002484e0.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/ui/map/002484e0.c b/src/overlays/shared/ui/map/002484e0.c index 9561d7fa8..23bda0eab 100644 --- a/src/overlays/shared/ui/map/002484e0.c +++ b/src/overlays/shared/ui/map/002484e0.c @@ -57,6 +57,7 @@ void FUN_L00_002484e0(f32 *position) { s32 mode15; s32 mode16; s32 i; + s32 *filter = filters; if (D_L00_00184218 == 0) return; if (*(s32 *)0x0015fdf8 != 0) { @@ -76,16 +77,16 @@ void FUN_L00_002484e0(f32 *position) { mode15 = hero.state.control_mode == 15; mode16 = hero.state.control_mode == 16; - for (i = 0; i < 16; i++) { + for (i = 0; i < 16; i++, filter++) { u32 flags; f32 value; MapFilterCallback callback; - filters[i] = 1; + *filter = 1; if (i <= 0) continue; if (D_L00_00182BA0[level][i].lower != D_L00_00182BA0[level][i].upper) { value = *(f32 *)((u8 *)hero.moby + 0x18); if (D_L00_00182BA0[level][i].lower > value || value > D_L00_00182BA0[level][i].upper) { - filters[i] = 0; + *filter = 0; continue; } } @@ -115,7 +116,7 @@ void FUN_L00_002484e0(f32 *position) { #undef CHECK_CALLBACK continue; reject: - filters[i] = 0; + *filter = 0; } x_min = x - 16; @@ -143,7 +144,7 @@ void FUN_L00_002484e0(f32 *position) { s64 column = column_start; s32 test_column = test_start + column_offset; s32 byte_column = byte_start + column_offset; - for (; column < column_end; column = (s32)column + 1, byte_column++, test_column++) { + for (; column < column_end; column++, byte_column++, test_column++) { s32 bitmap_column = (s32)column; volatile u8 *pixel; if (bitmap_column < 0) bitmap_column += 7; From bb743be7dd415808018b1e5a7224265ac1b21d30 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:25:18 +0000 Subject: [PATCH 085/251] decomp: improve set_pal_mode --- src/assembly/textbin/video/display/set_pal_mode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/assembly/textbin/video/display/set_pal_mode.c b/src/assembly/textbin/video/display/set_pal_mode.c index c503af897..c6931d7f8 100644 --- a/src/assembly/textbin/video/display/set_pal_mode.c +++ b/src/assembly/textbin/video/display/set_pal_mode.c @@ -61,9 +61,8 @@ void set_pal_mode(void) { display_width = fs_aa_buffer.display_width; screen_extent.width = display_width; screen_extent.half_width = display_width >> 1; - screen_extent.half_height = fs_aa_buffer.display_height >> 1; + screen_extent.half_height = (screen_extent.height = fs_aa_buffer.display_height) >> 1; screen_extent.bottom = (screen_extent.half_height + 0x800) << 4; - screen_extent.height = fs_aa_buffer.display_height; screen_extent.left = (0x800 - screen_extent.half_width) << 4; screen_extent.right = (screen_extent.half_width + 0x800) << 4; screen_extent.top = (0x800 - screen_extent.half_height) << 4; From dc8f46c415167f82c6d808c026bba82de4fe5f43 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:26:45 +0000 Subject: [PATCH 086/251] decomp: improve sceGsSetDefDispEnv --- .../sdk/dma/sce_gs_set_def_disp_env.c | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c index 58bfbf4be..ed2ffb64e 100644 --- a/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c +++ b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c @@ -30,6 +30,7 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s s64 scaled_horizontal; u16 interlace; u64 value; + u64 display_vertical; state = GetCoreDataTable(); if (!((u32)(state->wMode - 2) < 2) && checkModelVersion() != 0) { @@ -56,19 +57,17 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s if ((s16)mode == 2) { if ((s16)interlace == 1) { - scale = width + 0x9ff; - scale /= width; + scale = (width + 0x9ff) / width; + display_vertical = (u64)((vertical_offset + kernel_vertical + 0x32) & 0xfff) << 12; scaled_horizontal = horizontal_offset * scale; - value = ((u64)((vertical_offset + kernel_vertical + 0x32) & 0xfff) << 12) | - ((u64)((s64)(width * scale) - 1) << 32) | - ((u64)(((s64)scaled_horizontal + ((s64)kernel_horizontal + 0x27c)) & 0xfff)) | - ((u64)(s64)(scale - 1) << 23); - if (state->nSFrame_mode == 0) { - scale = height - 1; - } else { + scaled_horizontal = (scaled_horizontal + ((s64)kernel_horizontal + 0x27c)) & 0xfff; + value = ((u64)(s64)(scale - 1) << 23) | ((u64)((s64)(scale * width) - 1) << 32); + if (state->nSFrame_mode != 0) { scale = height * 2 - 1; + } else { + scale = height - 1; } - value |= (u64)(s64)scale << 44; + value = (value | display_vertical) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44)); } else { scale = width + 0x9ff; scale /= width; @@ -76,25 +75,23 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s value = ((u64)(s64)(height - 1) << 44) | ((u64)(s64)(scale - 1) << 23) | ((u64)(((s64)scaled_horizontal + (s64)(((u32)kernel_horizontal + 0x27cU) & 0xfffU)) & 0xfff)) | - ((u64)((s64)(width * scale) - 1) << 32) | + ((u64)((s64)(scale * width) - 1) << 32) | ((u64)((vertical_offset + kernel_vertical + 0x19) & 0xfff) << 12); } output->display = value; } else if ((s16)mode == 3) { if ((s16)interlace == 1) { - scale = width + 0x9ff; - scale /= width; + scale = (width + 0x9ff) / width; + display_vertical = (u64)((vertical_offset + kernel_vertical + 0x48) & 0xfff) << 12; scaled_horizontal = horizontal_offset * scale; - value = ((u64)((vertical_offset + kernel_vertical + 0x48) & 0xfff) << 12) | - ((u64)((s64)(width * scale) - 1) << 32) | - ((u64)(((s64)scaled_horizontal + ((s64)kernel_horizontal + 0x290)) & 0xfff)) | - ((u64)(s64)(scale - 1) << 23); + scaled_horizontal = (scaled_horizontal + ((s64)kernel_horizontal + 0x290)) & 0xfff; + value = ((u64)(s64)(scale - 1) << 23) | ((u64)((s64)(scale * width) - 1) << 32); if (state->nSFrame_mode != 0) { scale = height * 2 - 1; } else { scale = height - 1; } - value |= (u64)(s64)scale << 44; + value = (value | display_vertical) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44)); } else { scale = width + 0x9ff; scale /= width; @@ -102,7 +99,7 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s value = ((u64)(s64)(height - 1) << 44) | ((u64)(s64)(scale - 1) << 23) | ((u64)(((s64)scaled_horizontal + (s64)(((u32)kernel_horizontal + 0x290U) & 0xfffU)) & 0xfff)) | - ((u64)((s64)(width * scale) - 1) << 32) | + ((u64)((s64)(scale * width) - 1) << 32) | ((u64)((vertical_offset + kernel_vertical + 0x24) & 0xfff) << 12); } output->display = value; From 4f961ec3ca929e9e0860d940a59bced57033e486 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:32:00 +0000 Subject: [PATCH 087/251] decomp: improve build_resident_indexed_texture_warp_meshes --- src/assembly/textbin/fun_0022e420.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/assembly/textbin/fun_0022e420.c b/src/assembly/textbin/fun_0022e420.c index e91836736..d2cd8c269 100644 --- a/src/assembly/textbin/fun_0022e420.c +++ b/src/assembly/textbin/fun_0022e420.c @@ -73,11 +73,10 @@ void build_resident_indexed_texture_warp_meshes(void) { s32 page; for (page = 0; page < level_render_state.history_count - 1; page++) { history_index = (level_render_state.history_index - page + 0x1F) & 0x1F; - primary_next = get_primary_history_position((history_index + 1) & 0x1F); - secondary_next = - &level_render_state.secondary_history[(history_index + 1) & 0x1F]; - primary_current = get_primary_history_position(history_index); secondary_current = &level_render_state.secondary_history[history_index]; + primary_current = get_primary_history_position(history_index); + secondary_next = &level_render_state.secondary_history[(history_index + 1) & 0x1F]; + primary_next = get_primary_history_position((history_index + 1) & 0x1F); primary_after_next = get_primary_history_position((history_index + 2) & 0x1F); { s32 strip; From ee7267b9883439eee8ee97f92087720f32d6d70f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:34:47 +0000 Subject: [PATCH 088/251] decomp: improve set_pal_mode --- src/assembly/textbin/video/display/set_pal_mode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assembly/textbin/video/display/set_pal_mode.c b/src/assembly/textbin/video/display/set_pal_mode.c index c6931d7f8..3e75ce441 100644 --- a/src/assembly/textbin/video/display/set_pal_mode.c +++ b/src/assembly/textbin/video/display/set_pal_mode.c @@ -62,10 +62,10 @@ void set_pal_mode(void) { screen_extent.width = display_width; screen_extent.half_width = display_width >> 1; screen_extent.half_height = (screen_extent.height = fs_aa_buffer.display_height) >> 1; - screen_extent.bottom = (screen_extent.half_height + 0x800) << 4; screen_extent.left = (0x800 - screen_extent.half_width) << 4; - screen_extent.right = (screen_extent.half_width + 0x800) << 4; screen_extent.top = (0x800 - screen_extent.half_height) << 4; + screen_extent.right = (screen_extent.half_width + 0x800) << 4; + screen_extent.bottom = (screen_extent.half_height + 0x800) << 4; FlushCache(0); func_00120558(0, 0); zbuf = (depth_buffer_address >> 13) | 0x1000000; From 78c67a422549f6a7edd0a0a6ca4c25a2ddd02169 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:35:33 +0000 Subject: [PATCH 089/251] decomp: improve update_level_gameplay_frame --- src/assembly/textbin/fun_0022eaa8.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/assembly/textbin/fun_0022eaa8.c b/src/assembly/textbin/fun_0022eaa8.c index 9290b1330..07ec3bbcc 100644 --- a/src/assembly/textbin/fun_0022eaa8.c +++ b/src/assembly/textbin/fun_0022eaa8.c @@ -165,7 +165,10 @@ extern s32 rand(void); void update_level_gameplay_frame(void) __asm__("FUN_0022eaa8"); void update_level_gameplay_frame(void) { - Vector4 first_position; + union { + Vector4 position; + volatile s32 sound_bank; + } first_position; Vector4 second_position; Matrix4x4 first_transform; Matrix4x4 second_transform; @@ -175,7 +178,7 @@ void update_level_gameplay_frame(void) { LevelRenderObject *object; LevelRenderObject *expired_object; s32 mode_advance; - volatile s32 sound_bank; + s32 sound_bank; RenderModel *model; RenderArchiveTable *archive_table; u8 *archive_data; @@ -212,7 +215,9 @@ void update_level_gameplay_frame(void) { if (render_sequence.time == 1 && current_level_index != 0 && (current_level_index != 1 || level_available[3] != 0)) { read_global_table_entry(); - sound_bank = sound_bank_handle; + /* The bank scratch is dead before scale_vector overwrites the position. */ + first_position.sound_bank = sound_bank_handle; + sound_bank = first_position.sound_bank; mode_advance = level_render_state.mode; snd_play_sound_vol_pan_pmpb(sound_bank, mode_advance, 0x400, 0, 0, 0, 0, D_0013E5C0); snd_reset_state_and_flush_commands(); From 9cf2ea5e0019ccc5577d33ca15d94b29ae47f3d4 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:37:25 +0000 Subject: [PATCH 090/251] decomp: improve render_configured_text_label --- src/assembly/textbin/fun_0021a328.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/assembly/textbin/fun_0021a328.c b/src/assembly/textbin/fun_0021a328.c index efba39130..0b32c700a 100644 --- a/src/assembly/textbin/fun_0021a328.c +++ b/src/assembly/textbin/fun_0021a328.c @@ -67,7 +67,6 @@ int render_configured_text_label(struct MenuScreen *label) { int remaining_frames; int visible_height; int text_extent; - struct MenuScreen *page; struct MenuGridCell *entry; u8 *availability_table; int item_id; @@ -102,24 +101,25 @@ int render_configured_text_label(struct MenuScreen *label) { label->data.label.cached_value = 0; label->data.label.value_variant = 0; } else if (selector_flags & 0x80) { - page = menu_system.current->focus; + struct MenuScreen *page = menu_system.current->focus; value_index = page->data.list.selected; if (selector_flags & 0x8000) { value_variant = pal_mode != 0; } } else if (selector_flags & 0x100) { - page = menu_system.current->focus; + struct MenuScreen *page = menu_system.current->focus; value_index = page->data.grid.selected_cell; entry = &page->data.grid.cells[value_index]; item_id = entry->id; availability_table = entry->kind == 0 ? item_available : alternate_item_available; - if (availability_table[item_id] != 0) { + flags = availability_table[item_id]; + if (flags != 0) { value_index = page->data.grid.selected_cell; } else { value_index = -1; } } else if (selector_flags & 0x1000) { - page = menu_system.current->focus; + struct MenuScreen *page = menu_system.current->focus; value_index = page->data.list.selected; { short sid = page->data.list.items[value_index].text; @@ -127,7 +127,7 @@ int render_configured_text_label(struct MenuScreen *label) { find_help_entry(sid, 1, (u16 *)&label->data.label.text_id); } } else { - page = menu_system.current->focus; + struct MenuScreen *page = menu_system.current->focus; item_id = page->data.grid.cells[page->data.grid.selected_cell].id; value_variant = item_text_variant[item_id] != 0; value_index = item_id; @@ -182,7 +182,7 @@ int render_configured_text_label(struct MenuScreen *label) { text = unavailable_label_text; } if (label->data.label.flags & 0x200) { - item_id = *((int *)label->data.label.text_id + + int item_id = *((int *)label->data.label.text_id + value_index * label->data.label.text_stride / sizeof(int)); if (item_id != 0x4ED2 && item_id != 0x4ED9 && item_id != 0x4EDD) { sprintf(formatted_text, label_format, get_help_message_text(0x4ECC), text); From c84b46265b9a0bcbc08c1519f3686dfe8ac41557 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:36:49 +0000 Subject: [PATCH 091/251] decomp: improve sceGsSetDefDispEnv --- src/assembly/sdk/dma/sce_gs_set_def_disp_env.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c index ed2ffb64e..b788a471a 100644 --- a/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c +++ b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c @@ -28,6 +28,7 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s s32 kernel_horizontal, kernel_vertical, kernel_width, kernel_height; s32 mode, scale; s64 scaled_horizontal; + u64 display_width; u16 interlace; u64 value; u64 display_vertical; @@ -61,13 +62,14 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s display_vertical = (u64)((vertical_offset + kernel_vertical + 0x32) & 0xfff) << 12; scaled_horizontal = horizontal_offset * scale; scaled_horizontal = (scaled_horizontal + ((s64)kernel_horizontal + 0x27c)) & 0xfff; - value = ((u64)(s64)(scale - 1) << 23) | ((u64)((s64)(scale * width) - 1) << 32); + value = (u64)(s64)(scale - 1) << 23; + display_width = (u64)((s64)(scale * width) - 1) << 32; if (state->nSFrame_mode != 0) { scale = height * 2 - 1; } else { scale = height - 1; } - value = (value | display_vertical) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44)); + value = ((value | display_width) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44))) | display_vertical; } else { scale = width + 0x9ff; scale /= width; @@ -85,13 +87,14 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s display_vertical = (u64)((vertical_offset + kernel_vertical + 0x48) & 0xfff) << 12; scaled_horizontal = horizontal_offset * scale; scaled_horizontal = (scaled_horizontal + ((s64)kernel_horizontal + 0x290)) & 0xfff; - value = ((u64)(s64)(scale - 1) << 23) | ((u64)((s64)(scale * width) - 1) << 32); + value = (u64)(s64)(scale - 1) << 23; + display_width = (u64)((s64)(scale * width) - 1) << 32; if (state->nSFrame_mode != 0) { scale = height * 2 - 1; } else { scale = height - 1; } - value = (value | display_vertical) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44)); + value = ((value | display_width) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44))) | display_vertical; } else { scale = width + 0x9ff; scale /= width; From 5bbef10dadec902f55b146ce628cd01f038b483a Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:41:32 +0000 Subject: [PATCH 092/251] decomp: improve FUN_L00_0020f580 --- src/overlays/shared/ui/help/0020c758.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index bda41b5b4..930941d7a 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -1606,11 +1606,10 @@ void FUN_L00_0020f580(void) angle = FUN_001ff800_f580(((f32)(D_L00_0015F5CC_f580 % random_range) / FUN_00200240_f580(random_range) * 2.0f) * 3.1415927f + -3.1415927f); color_red = FUN_00200250_f580(angle * 90.0f); color_green = FUN_00200250_f580(angle * 50.0f); - color_blue = FUN_00200250_f580(angle * 10.0f) + 0x14; + color_blue = FUN_00200250_f580(angle * 10.0f); color_red += 0xd7; - color_green += 0x32; if (color_red > 0xff) color_red = 0xff; - *(u32 *)(effect + 0x90) = (color_blue << 16) | 0x80000000 | (color_green << 8) | color_red; + *(u32 *)(effect + 0x90) = ((color_blue + 0x14) << 16) | 0x80000000 | ((color_green + 0x32) << 8) | color_red; *(u16 *)(effect + 0x34) |= 0x10; } } From 87b4edc3953b81fd03505f04c2d815871961a306 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:41:37 +0000 Subject: [PATCH 093/251] decomp: improve FUN_L06_002f5d78 --- src/overlays/l06/gameplay/entities/002b4770.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/overlays/l06/gameplay/entities/002b4770.c b/src/overlays/l06/gameplay/entities/002b4770.c index d84d1e8e1..6f77b9ff6 100644 --- a/src/overlays/l06/gameplay/entities/002b4770.c +++ b/src/overlays/l06/gameplay/entities/002b4770.c @@ -1215,7 +1215,7 @@ void FUN_L06_002f5d78(char *moby) { float angle, other, upper, lower, base, threshold; char **left, **right; - for (i = 0, offset = 0; i < 20; i++, offset += 4) { + for (i = 0, offset = 0; offset < 80;) { float angle; float length = D_L06_00161D78 - (float)i; if (length < 0.0f) length = 0.0f; @@ -1233,6 +1233,8 @@ void FUN_L06_002f5d78(char *moby) { else if (angle < 0.0f) angle = 0.0f; left = (char **)(data + 0x70 + offset); right = (char **)(data + 0xc0 + offset); + i++; + offset += 4; *(float *)(*left + 0x40) = -angle; *(float *)(*right + 0x40) = angle; FUN_L00_00250df8(*left); @@ -1282,15 +1284,15 @@ void FUN_L06_002f5d78(char *moby) { if (1.5707964f < other) other = 1.5707964f; else if (other < 0.0f) other = 0.0f; if (angle != 0.0f && other == 0.0f) allocate_voice_for_target_entry(2, 0, (int)*left); - lower = (D_L06_00161D80 * DEG_TO_RAD - (float)(i + i) * 0.7853982f) - 0.7853982f; + upper = (D_L06_00161D80 * DEG_TO_RAD - (float)(i + i) * 0.7853982f) - 0.7853982f; other = angle - (*(float *)&D_L06_00161DA4) * DEG_TO_RAD; - if (1.5707964f < lower) lower = 1.5707964f; - else if (lower < 0.0f) lower = 0.0f; + if (1.5707964f < upper) upper = 1.5707964f; + else if (upper < 0.0f) upper = 0.0f; if (1.5707964f < other) other = 1.5707964f; else if (other < 0.0f) other = 0.0f; - if (lower != 0.0f && other == 0.0f) allocate_voice_for_target_entry(2, 0, (int)*right); + if (upper != 0.0f && other == 0.0f) allocate_voice_for_target_entry(2, 0, (int)*right); *(float *)(*left + 0x44) = -angle; - *(float *)(*right + 0x44) = -lower; + *(float *)(*right + 0x44) = -upper; FUN_L00_00250df8(*left); FUN_L00_00250df8(*right); } From d5b12972bbb341e84fda984db91089b61f36d237 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:45:21 +0000 Subject: [PATCH 094/251] decomp: improve FUN_L05_002d1688 --- src/overlays/l05/gameplay/entities/002d1688.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/overlays/l05/gameplay/entities/002d1688.c b/src/overlays/l05/gameplay/entities/002d1688.c index 5f2522fdf..2d81ea855 100644 --- a/src/overlays/l05/gameplay/entities/002d1688.c +++ b/src/overlays/l05/gameplay/entities/002d1688.c @@ -258,8 +258,8 @@ void FUN_L05_002d1688(char *moby) { *(unsigned short *)(moby + 0x34) |= 1; *(unsigned char *)(moby + 0x30) = 0xff; *(float *)(data + 0x74) = *(float *)(moby + 0x18); - duration = 30; - goto set_timer; + *(int *)(data + 0x7c) = timer_2d1688(30); + return; } index = *(int *)(data + 0x60); if (index == -1) { @@ -333,9 +333,10 @@ void FUN_L05_002d1688(char *moby) { } if (hero.state.current == 0x12) return; path = D_L05_001B0930[*(int *)(data + 0x60)]; - duration = 180; - if (check_path_2d1688(&hero.motion.pos, path + 0x10, *(int *)path) == 0) goto set_timer; - duration = 600; + if (check_path_2d1688(&hero.motion.pos, path + 0x10, *(int *)path) != 0) + duration = 600; + else + duration = 180; set_timer: *(int *)(data + 0x7c) = timer_2d1688(duration); return; @@ -355,7 +356,9 @@ void FUN_L05_002d1688(char *moby) { hero.unk20A5 = one; hero.motion.pos.f[2] += 20.0f; } - *(float *)(moby + 0x18) += *(float *)(data + 0x78); + speed = *(float *)(data + 0x78); + height = *(float *)(moby + 0x18); + *(float *)(moby + 0x18) = height + speed; speed = *(float *)(data + 0x78) - frame_time_sq * 10.0f; *(float *)(data + 0x78) = speed; if (speed < frame_time + frame_time) { @@ -370,7 +373,7 @@ void FUN_L05_002d1688(char *moby) { } if (*(float *)(data + 0x78) < 0.0f) { if (*(float *)(moby + 0x18) < hero.water_surface_z && *(unsigned char *)(moby + 0xbc) == 0) { - *(unsigned char *)(moby + 0xbc) = 1; + *(unsigned char *)(moby + 0xbc) = one; effect_2d1688(0, 0, moby); fast_vec_normalize((*(float *)&D_L05_00161388), v, moby + 0xe0); fast_vec_add(v, v, moby + 0x10); From 34453bcba32efae93bd1052f945559dc923e3298 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:50:03 +0000 Subject: [PATCH 095/251] decomp: improve render_configured_text_label --- src/assembly/textbin/fun_0021a328.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/assembly/textbin/fun_0021a328.c b/src/assembly/textbin/fun_0021a328.c index 0b32c700a..029a5cf2d 100644 --- a/src/assembly/textbin/fun_0021a328.c +++ b/src/assembly/textbin/fun_0021a328.c @@ -192,8 +192,8 @@ int render_configured_text_label(struct MenuScreen *label) { render_flags = label->data.label.flags; draw_flags = render_flags; + x = 4; y = 4; - text_style = 8; if ((draw_flags & 0x4004) == 0x4004 && label->data.label.text_id == 0x523E) { draw_flags |= 1; y = 12; @@ -205,7 +205,7 @@ int render_configured_text_label(struct MenuScreen *label) { if (text == 0) { text = fallback_label_text; } - x = 4; + text_style = 8; if (draw_flags & 1) { text_style = 9; x = label->width / 2; @@ -237,12 +237,12 @@ int render_configured_text_label(struct MenuScreen *label) { c.flags |= 4; font_print_window(&c, color, text, -1, texture_tex0, font); window->flags = c.flags ^ 4; - flags = label->data.label.flags; + draw_flags = label->data.label.flags; text_extent = c.rendered_height + 4; visible_height = c.bottom - c.top; - if (!(flags & 0x2000) && text_extent >= visible_height) { - if (!(flags & 0x400)) { - label->data.label.flags = flags | 0x400; + if (!(draw_flags & 0x2000) && text_extent >= visible_height) { + if (!(draw_flags & 0x400)) { + label->data.label.flags = draw_flags | 0x400; label->data.label.scroll_offset = -(label->height * 8); } } else if (label->data.label.flags & 0x400) { From b09fa9a710984f4313255ac677e96d04ca07b371 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:51:41 +0000 Subject: [PATCH 096/251] decomp: improve FUN_L00_002382a0 --- src/overlays/shared/ui/text/002377b8.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/overlays/shared/ui/text/002377b8.c b/src/overlays/shared/ui/text/002377b8.c index 9362a2841..37220a948 100644 --- a/src/overlays/shared/ui/text/002377b8.c +++ b/src/overlays/shared/ui/text/002377b8.c @@ -420,12 +420,11 @@ s32 FUN_L00_002382a0(char *rec) { (s32)(D_L00_0015F78C * fast_cos(angle) * D_L00_0015F7C4); icon_y = y + D_L00_0015F724 + (s32)(D_L00_0015F78C * fast_sin(angle)); - entry = D_L00_0015FAC0_c[D_L00_0015F72C]; - if (*(s32 *)(rec + 0x74) == i && ((Ent *)(marker_offset + (char *)entry))->f0 != 0) + if (*(s32 *)(rec + 0x74) == i && + ((Ent *)(marker_offset + (char *)D_L00_0015FAC0_c[D_L00_0015F72C]))->f0 != 0) draw_hud_sprite(get_icon_frame(0xe99c, 0), icon_x - 0x13, icon_y - 0x13, 0x26, 0x26, marker_alpha); - entry = D_L00_0015FAC0_c[D_L00_0015F72C]; - if (((Ent *)(normal_offset + (char *)entry))->f0 != 0) { + if (((Ent *)(normal_offset + (char *)D_L00_0015FAC0_c[D_L00_0015F72C]))->f0 != 0) { s32 icon_alpha; if (i != *(s32 *)(rec + 0x74)) icon_alpha = truncate_float_to_s32((f32)alpha * D_L00_0015F7C0); @@ -479,7 +478,8 @@ s32 FUN_L00_002382a0(char *rec) { suffix = text + 2; prefix_length = 2; } else { - while (++j < text_length) { + while (j + 1 < text_length) { + j++; suffix++; if (*(const u8 *)suffix == '-') { prefix_length = j + 2; @@ -498,7 +498,8 @@ s32 FUN_L00_002382a0(char *rec) { suffix = text + 2; prefix_length = 1; } else { - while (++j < text_length) { + while (j + 1 < text_length) { + j++; suffix++; if (*(const u8 *)suffix == ' ') { prefix_length = j + 1; From c7d5e10fc551a8976dbb2164c2c43228f9a59085 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:52:39 +0000 Subject: [PATCH 097/251] decomp: improve update_moby_sequence --- src/overlays/l15/gameplay/vendor/002e73c0.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/overlays/l15/gameplay/vendor/002e73c0.c b/src/overlays/l15/gameplay/vendor/002e73c0.c index 0875438a4..2a99e81b0 100644 --- a/src/overlays/l15/gameplay/vendor/002e73c0.c +++ b/src/overlays/l15/gameplay/vendor/002e73c0.c @@ -1169,11 +1169,12 @@ void FUN_L15_002ec760(struct Moby *moby) { } { struct { OvlQuad target, pos, diff; } vecs; + char *pos = (char *)&moby->pos; fast = 0.02f; slow = 0.3f; - near_distance = FUN_001f8c00((char *)moby + 0x10, (void *)0x13f3d0); + near_distance = FUN_001f8c00(pos, (void *)0x13f3d0); if (near_distance < 8.0f) { - yaw = FUN_001f9028(D_0013F420 - *(float *)((char *)moby + 0x10), D_0013F424 - *(float *)((char *)moby + 0x14)); + yaw = FUN_001f9028(D_0013F420 - *(float *)(pos), D_0013F424 - *(float *)((char *)moby + 0x14)); if (FUN_001f9968(moby->rot.z, yaw) < 1.5707964f) { if (FUN_001f8b50((void *)0x13f450) > 0.01f) *(int *)(data + 0x274) = FUN_001f8658(0x78); @@ -1188,10 +1189,10 @@ void FUN_L15_002ec760(struct Moby *moby) { ready: if (FUN_001f86a0(data + 0x278)) { float angle = 0.017453292f; - *(int *)(data + 0x278) = FUN_001f99c8(D_0015ED68 * random_float_between(180.0f, 300.0f)); + *(int *)(data + 0x278) = FUN_001f99c8(random_float_between(180.0f, 300.0f) * D_0015ED68); turn = FUN_001f9860(moby->rot.z, random_float_between(-90.0f, 90.0f) * angle); FUN_00252348(6.0f, turn, random_float_between(0.0f, 30.0f) * angle, data + 0x260); - FUN_001f89f0(data + 0x260, data + 0x260, (char *)moby + 0x10); + FUN_001f89f0(data + 0x260, data + 0x260, pos); } if (*(int *)(data + 0x274) == 0) { vecs.target = *(OvlQuad *)(data + 0x260); @@ -1199,7 +1200,7 @@ void FUN_L15_002ec760(struct Moby *moby) { vecs.target = *(OvlQuad *)0x13f420; fast = 0.04f; } - vecs.pos = *(OvlQuad *)((char *)moby + 0x10); + vecs.pos = *(OvlQuad *)(pos); ((float *)&vecs.pos)[2] += 1.0f; FUN_001f8a20(&vecs.diff, &vecs.target, &vecs.pos); yaw = FUN_001f98a8(FUN_001f9028(((float *)&vecs.diff)[0], ((float *)&vecs.diff)[1]), moby->rot.z); From 3e600ac81fe5dd3364955c6ea2d552a5f1afd05d Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:52:52 +0000 Subject: [PATCH 098/251] decomp: improve sceGsSetDefDispEnv --- src/assembly/sdk/dma/sce_gs_set_def_disp_env.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c index b788a471a..3dca0ee59 100644 --- a/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c +++ b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c @@ -60,8 +60,8 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s if ((s16)interlace == 1) { scale = (width + 0x9ff) / width; display_vertical = (u64)((vertical_offset + kernel_vertical + 0x32) & 0xfff) << 12; - scaled_horizontal = horizontal_offset * scale; - scaled_horizontal = (scaled_horizontal + ((s64)kernel_horizontal + 0x27c)) & 0xfff; + scaled_horizontal = (s64)kernel_horizontal + 0x27c; + scaled_horizontal = (scaled_horizontal + horizontal_offset * scale) & 0xfff; value = (u64)(s64)(scale - 1) << 23; display_width = (u64)((s64)(scale * width) - 1) << 32; if (state->nSFrame_mode != 0) { @@ -69,7 +69,7 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s } else { scale = height - 1; } - value = ((value | display_width) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44))) | display_vertical; + value = ((display_width | value) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44))) | display_vertical; } else { scale = width + 0x9ff; scale /= width; @@ -85,8 +85,8 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s if ((s16)interlace == 1) { scale = (width + 0x9ff) / width; display_vertical = (u64)((vertical_offset + kernel_vertical + 0x48) & 0xfff) << 12; - scaled_horizontal = horizontal_offset * scale; - scaled_horizontal = (scaled_horizontal + ((s64)kernel_horizontal + 0x290)) & 0xfff; + scaled_horizontal = (s64)kernel_horizontal + 0x290; + scaled_horizontal = (scaled_horizontal + horizontal_offset * scale) & 0xfff; value = (u64)(s64)(scale - 1) << 23; display_width = (u64)((s64)(scale * width) - 1) << 32; if (state->nSFrame_mode != 0) { @@ -94,7 +94,7 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s } else { scale = height - 1; } - value = ((value | display_width) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44))) | display_vertical; + value = ((display_width | value) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44))) | display_vertical; } else { scale = width + 0x9ff; scale /= width; From 379a79035cc63dda088291eb4c7ac2baa764c9cf Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:54:44 +0000 Subject: [PATCH 099/251] decomp: improve update_camera_record --- src/overlays/shared/gameplay/vendor/002ec308.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/vendor/002ec308.c b/src/overlays/shared/gameplay/vendor/002ec308.c index f3c17c320..eb119aa9f 100644 --- a/src/overlays/shared/gameplay/vendor/002ec308.c +++ b/src/overlays/shared/gameplay/vendor/002ec308.c @@ -1033,8 +1033,8 @@ int FUN_L02_002fb9c8(char *moby) { fast_add_rotations(heading, 3.1415927f); } if (*(short *)(data + 0x3c) == 4) { - heading = *(float *)(D_L02_0015EF50 + *(short *)(moby + 0x84) * 32 + 0x18); angle = FUN_001f9e90(*(float *)D_L02_00167400, *(float *)(D_L02_00167400 + 4)); + heading = *(float *)(D_L02_0015EF50 + *(short *)(moby + 0x84) * 32 + 0x18); if (fast_difference_between_rotations(heading, angle) > 1.5707964f) heading = fast_add_rotations(heading, 3.1415927f); *(float *)(data + 0x40) = heading; From df056275959e5bb6a3d5383ab2ef4f822fbf5b4e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:58:58 +0000 Subject: [PATCH 100/251] decomp: improve render_configured_text_label --- src/assembly/textbin/fun_0021a328.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assembly/textbin/fun_0021a328.c b/src/assembly/textbin/fun_0021a328.c index 029a5cf2d..d81f7fec1 100644 --- a/src/assembly/textbin/fun_0021a328.c +++ b/src/assembly/textbin/fun_0021a328.c @@ -110,9 +110,9 @@ int render_configured_text_label(struct MenuScreen *label) { struct MenuScreen *page = menu_system.current->focus; value_index = page->data.grid.selected_cell; entry = &page->data.grid.cells[value_index]; - item_id = entry->id; + flags = entry->id; availability_table = entry->kind == 0 ? item_available : alternate_item_available; - flags = availability_table[item_id]; + flags = availability_table[flags]; if (flags != 0) { value_index = page->data.grid.selected_cell; } else { From 85bc787c6cf144bb8bf148ec235105b2e9efff95 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:56:55 +0000 Subject: [PATCH 101/251] decomp: improve FUN_L00_002cfcb8 --- src/overlays/shared/gameplay/entities/002cfcb8.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002cfcb8.c b/src/overlays/shared/gameplay/entities/002cfcb8.c index 280a08949..5cfc788c1 100644 --- a/src/overlays/shared/gameplay/entities/002cfcb8.c +++ b/src/overlays/shared/gameplay/entities/002cfcb8.c @@ -144,8 +144,8 @@ void FUN_L00_002cfcb8(u8 *moby) { if (FUN_L00_0025e3b8_2cfcb8(second) && !*(u8 **)(vars + 0xA4)) { qcopy_nc(&second_probe, second + 0x10); qcopy(&second_start, second + 0x10); - second_probe.z += *(f32 *)(vars + 0xB0) * 0.5f; second_start.z = 0.1f; + second_probe.z += *(f32 *)(vars + 0xB0) * 0.5f; if (FUN_L00_001efc70_2cfcb8(&second_probe, &second_start, 2, first, 0) && D_L00_00173E58_2cfcb8 && FUN_L00_002603d0_2cfcb8(D_L00_00173E58_2cfcb8)) { if (first) *(u16 *)(first + 0x36) = 0x7F80; @@ -175,8 +175,7 @@ void FUN_L00_002cfcb8(u8 *moby) { *(u8 **)(vars + 0xA0)) { if (*(s32 *)(vars + 0xC0) != -1) { row = D_L00_001B04B0_2cfcb8[*(s32 *)(vars + 0xC0)]; - state = *(s32 *)(row + 0x1C); - if (*(s32 *)row == 0 || state == 1 || state == 3) { + if (*(s32 *)row == 0 || (state = *(s32 *)(row + 0x1C)) == 1 || state == 3) { *(s32 *)(vars + 0xC0) = -1; } else if (state != 0x111 && (u32)(state - 0x11) <= 0xFF) { if (state - 0x10 >= *(s32 *)row) *(s32 *)(vars + 0xC0) = -1; From 466d33bf554fef6e7128e2b567a2071bc11afd88 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 16:51:52 +0000 Subject: [PATCH 102/251] decomp: improve FUN_L00_00260a88 --- src/overlays/shared/rendering/view/0025fcb8.c | 66 ++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/src/overlays/shared/rendering/view/0025fcb8.c b/src/overlays/shared/rendering/view/0025fcb8.c index 0ce936b4d..b5a0e5238 100644 --- a/src/overlays/shared/rendering/view/0025fcb8.c +++ b/src/overlays/shared/rendering/view/0025fcb8.c @@ -504,8 +504,9 @@ void FUN_L00_00260a88(char *moby, int lower, int upper, unsigned int flags, int if (count < 1) count = 1; } } - remaining = count; - if (count >= 300) { + single = count; + remaining = single; + if (remaining >= 300) { do { remaining -= 50; large++; @@ -520,31 +521,33 @@ void FUN_L00_00260a88(char *moby, int lower, int upper, unsigned int flags, int int b_large = 0, b_medium = 0, b_small = 0, b_single = 3; near_value = 150; far_value = 3; - if (count < 150) { - int value_large = 150, value_medium = 0, value_small = 0, value_single = 0; - do { - if (a_large) { - value_large -= 50; a_large--; value_medium += 20; a_medium++; - } else if (a_medium) { - value_medium -= 20; a_medium--; value_small += 5; a_small++; - } else if (a_small) { - value_small -= 5; a_small--; a_single++; - } - near_value = value_large + value_medium + value_small + a_single; - } while (count < near_value && near_value > 3); - } - if (count > 3) { - int value_large = 0, value_medium = 0, value_small = 0; - do { - if (b_single) { - b_single--; value_small += 5; b_small++; - } else if (b_small) { - value_small -= 5; b_small--; value_medium += 20; b_medium++; - } else if (b_medium) { - value_medium -= 20; b_medium--; value_large += 50; b_large++; - } - far_value = value_large + value_medium + value_small + b_single; - } while (far_value < count && far_value < 150); + if (single + small + medium + large > 3) { + if (count < 150) { + int value_large = 150, value_medium = 0, value_small = 0, value_single = 0; + do { + if (a_large) { + value_large -= 50; a_large--; value_medium += 20; a_medium++; + } else if (a_medium) { + value_medium -= 20; a_medium--; value_small += 5; a_small++; + } else if (a_small) { + value_small -= 5; a_small--; a_single++; + } + near_value = value_large + value_medium + value_small + a_single; + } while (count < near_value && near_value > 3); + } + if (count > 3) { + int value_large = 0, value_medium = 0, value_small = 0; + do { + if (b_single) { + b_single--; value_small += 5; b_small++; + } else if (b_small) { + value_small -= 5; b_small--; value_medium += 20; b_medium++; + } else if (b_medium) { + value_medium -= 20; b_medium--; value_large += 50; b_large++; + } + far_value = value_large + value_medium + value_small + b_single; + } while (far_value < count && far_value < 150); + } } if (near_value - count < count - far_value) { large = a_large; medium = a_medium; small = a_small; single = a_single; @@ -586,17 +589,18 @@ void FUN_L00_00260a88(char *moby, int lower, int upper, unsigned int flags, int FUN_001ff278_260a88(&velocity, &velocity, &base); if (large) { large--; - FUN_002a7438_260a88(moby, &position, &velocity, flags, 50, gated); + remaining = 50; } else if (medium) { medium--; - FUN_002a7438_260a88(moby, &position, &velocity, flags, 20, gated); + remaining = 20; } else if (small) { small--; - FUN_002a7438_260a88(moby, &position, &velocity, flags, 5, gated); + remaining = 5; } else { single--; - FUN_002a7438_260a88(moby, &position, &velocity, flags, 1, gated); + remaining = 1; } + FUN_002a7438_260a88(moby, &position, &velocity, flags, remaining, gated); } } #endif From 25f7fbd3501b0e46bc05c3e6a8ff7a293cc5c6a0 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:02:14 +0000 Subject: [PATCH 103/251] decomp: improve FUN_L00_002dbf28 --- src/overlays/shared/gameplay/entities/002d7f88.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002d7f88.c b/src/overlays/shared/gameplay/entities/002d7f88.c index 13b68d7ba..0ba41ef18 100644 --- a/src/overlays/shared/gameplay/entities/002d7f88.c +++ b/src/overlays/shared/gameplay/entities/002d7f88.c @@ -2013,6 +2013,13 @@ extern void FUN_L00_002d3838_002dbf28(void *, void *, int, int) __asm__("FUN_L00 extern int FUN_L00_001f2868_002dbf28(float, void *, int, void *, int) __asm__("FUN_L00_001f2868"); extern void FUN_L00_0025a9f8_002dbf28(float, float, float, void *, void *, void *, int, int, int, int, int) __asm__("FUN_L00_0025a9f8"); +typedef struct { + char pad[0x160]; + float f160; + int i164, i168; +} G_002dbf28; +extern G_002dbf28 D_L00_00166C80_002dbf28 __asm__("D_L00_00166C80"); + void FUN_L00_002dbf28(char *moby) { u128 matrix[5]; Q_WORDDATA origin, position, axis, temporary, scaled, displacement; @@ -2036,6 +2043,7 @@ void FUN_L00_002dbf28(char *moby) { range = fast_vec_length(&origin); for (i = 0; i < 10 / multiplier; i++) { + int a, b; displacement.ul128 = 0; displacement.fl32[0] = FUN_002132a8_002dbf28(-1.0f, 1.0f); displacement.fl32[1] = FUN_002132a8_002dbf28(-1.0f, 1.0f); @@ -2053,6 +2061,7 @@ void FUN_L00_002dbf28(char *moby) { FUN_L00_002af450_002dbf28(center, &scaled, FUN_L00_00257b90_002dbf28(a, b), 0, item_text_variant.b9); } for (i = 0; i < 4 / multiplier; i++) { + int a, b; displacement.ul128 = 0; displacement.fl32[0] = FUN_002132a8_002dbf28(-1.0f, 1.0f); displacement.fl32[1] = FUN_002132a8_002dbf28(-1.0f, 1.0f); @@ -2088,6 +2097,7 @@ void FUN_L00_002dbf28(char *moby) { deficit = 0.0f; if (range < 7.0f) deficit = 7.0f - range; for (i = 0; i < count; i++) { + int a, b; int red, green, blue; float effect_magnitude; speed = FUN_002132a8_002dbf28(8.0f, 10.0f); @@ -2132,9 +2142,9 @@ void FUN_L00_002dbf28(char *moby) { speed = magnitude * 3.0f; a = FUN_001f96f8_002dbf28(29); FUN_L00_002df808_002dbf28(speed, moby, center, &position, a, (u8)red, (u8)green, (u8)blue, 32); - if (range < 20.0f) *(float *)(D_L00_00166DC0_002dbf28 + 0x120) = 0.4f - range * 0.0175f; - else *(float *)(D_L00_00166DC0_002dbf28 + 0x120) = 0.050000012f; - *(int *)(D_L00_00166DC0_002dbf28 + 0x128) = FUN_001f96f8_002dbf28(25); + if (range < 20.0f) D_L00_00166C80_002dbf28.f160 = 0.4f - range * 0.0175f; + else D_L00_00166C80_002dbf28.f160 = 0.050000012f; + D_L00_00166C80_002dbf28.i168 = FUN_001f96f8_002dbf28(25); FUN_L00_002d3838_002dbf28(matrix, center, 0, 0); if (item_text_variant.b9) { a = FUN_L00_001f2868_002dbf28(3.0f, center, 16, moby, 0); From 58c82026baba93de69237cf40a8fcf515d338e40 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:03:27 +0000 Subject: [PATCH 104/251] decomp: improve FUN_L01_002f5168 --- .../shared/gameplay/entities/002b8c08.c | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b8c08.c b/src/overlays/shared/gameplay/entities/002b8c08.c index b26c53df4..134802df0 100644 --- a/src/overlays/shared/gameplay/entities/002b8c08.c +++ b/src/overlays/shared/gameplay/entities/002b8c08.c @@ -2689,24 +2689,27 @@ void FUN_L01_002f5168(char *moby) { FUN_L01_0028bb90(path_state, B2(data, 0x120) & 0x20, moby, F2(data, 0xf4), F2(data, 0xf8)); if ((B2(data, 0x120) & 0x1e) && !(B2(data, 0x120) & 1)) { link = (int *)(data + 0x140); - for (i = 0; i < 4; ++i) { - if ((B2(data, 0x120) & (2 << i)) && link[i] != -1) { - child = D_L01_0015FFD8 + (link[i] << 8); + node = (char *)point; + for (i = 0; i < 4; ++i, node += 0x10, ++link) { + if ((B2(data, 0x120) & (2 << i)) && *link != -1) { + child = D_L01_0015FFD8 + (*link << 8); if (child && (child_data = *(char **)(child + 0x78)) != 0) { I2(child_data, 0x70) |= 0x1000; - FUN_002645a8_2f5168(moby, i, point + i * 4); - FUN_002211b8_2f5168(work_init, point + i * 4, moby + 0x10); + FUN_002645a8_2f5168(moby, i, node); + FUN_002211b8_2f5168(work_init, node, moby + 0x10); FUN_00221410_2f5168(work_init, work_init, 1.0f); - Q2(child, 0x10) = *(OvlQuad *)(point + i * 4); + Q2(child, 0x10) = *(OvlQuad *)node; Q2(child_data, 0x80) = *(OvlQuad *)work_init; } } } } - if (H2(data, 0x11c) <= 0) { - if (D_L01_0015ED84 == 3 || D_L01_0015ED84 == 9) H2(data, 0x13a) = 0; - B2(moby, 0x20) = 1; - } else B2(moby, 0x20) = 3; + if (H2(data, 0x11c) > 0) { + B2(moby, 0x20) = 3; + return; + } + if (D_L01_0015ED84 == 3 || D_L01_0015ED84 == 9) H2(data, 0x13a) = 0; + B2(moby, 0x20) = 1; return; case 2: if (path_state->path_id == -1) return; From f1258e3058b1dbbcc9258472d0b661267b0b5a7f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:03:55 +0000 Subject: [PATCH 105/251] decomp: improve FUN_L00_002cd1f0 --- .../shared/gameplay/entities/002c8440.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002c8440.c b/src/overlays/shared/gameplay/entities/002c8440.c index a2ed9db4b..9c24aa77d 100644 --- a/src/overlays/shared/gameplay/entities/002c8440.c +++ b/src/overlays/shared/gameplay/entities/002c8440.c @@ -2065,21 +2065,26 @@ void FUN_L00_002cd1f0(struct Moby *m) if (v->strength > 0.9f) v->strength = 0.9f; hit = 0; - for (;;) { + goto move; +retry: + if (!(v->strength > 0.1f)) + goto moved; +move: + { collision_scratch.tracking.rotation.f[1] = v->strength * FUN_001ff800_2cd1f0(v->yaw) * FUN_001ff7e8_2cd1f0(v->pitch); collision_scratch.tracking.rotation.f[2] = v->strength * FUN_001ff7e8_2cd1f0(v->yaw) * FUN_001ff7e8_2cd1f0(v->pitch); collision_scratch.tracking.rotation.f[0] = 0.0f; - collision_scratch.tracking.rotation.f[3] = 0.0f; + collision_scratch.tracking.rotation.f[3] = collision_scratch.tracking.rotation.f[0]; FUN_001ffa70_2cd1f0(matrix, &m->rot); FUN_001ff6f8_2cd1f0(&collision_scratch.tracking.rotation, &collision_scratch.tracking.rotation, matrix); add_vector_xyz_2c8440(&m->pos, &v->offset, &collision_scratch.tracking.rotation); if (!collision_line_2c8440(&start, &m->pos, 6, m, 0)) - break; + goto moved; hit = 1; v->strength *= 0.7f; - if (!(*(volatile f32 *)&v->strength > 0.1f)) - break; + goto retry; } +moved: if (hit) { m->rot.z = FUN_001ff8b0_2cd1f0(m->pos.x - start.f[0], m->pos.y - start.f[1]); m->rot.y = -FUN_001ff8b0_2cd1f0(FUN_001ff488_2cd1f0(&start, &m->pos), m->pos.z - start.f[2]); @@ -2109,7 +2114,7 @@ void FUN_L00_002cd1f0(struct Moby *m) goto bounce_only; m->command = 2; qcopy(&m->pos, &coll_hit_2c8440.point); - FUN_001ff660_2cd1f0(&vector_scratch.bounce, &query, &coll_hit_normal_2c8440); + FUN_001ff660_2cd1f0(&vector_scratch.bounce, &query, &coll_hit_2c8440.normal_x); FUN_001ff500_2cd1f0(&vector_scratch.bounce, &vector_scratch.bounce, frame_time + frame_time); FUN_0025e450_2cd1f0(m, &vector_scratch.bounce, 0, 0.0f, 0.0f, 10, 3, 9, 4.0f, 2.0f, 9.0f, 1.0f, 0, 15.0f, 1, 1, -1, 0); } else { @@ -2117,7 +2122,7 @@ void FUN_L00_002cd1f0(struct Moby *m) goto bounce_only; m->command = 1; qcopy(&m->pos, &coll_hit_2c8440.point); - FUN_001ff660_2cd1f0(&vector_scratch.bounce, &query, &coll_hit_normal_2c8440); + FUN_001ff660_2cd1f0(&vector_scratch.bounce, &query, &coll_hit_2c8440.normal_x); FUN_001ff500_2cd1f0(&vector_scratch.bounce, &vector_scratch.bounce, frame_time + frame_time); FUN_0025e450_2cd1f0(m, &vector_scratch.bounce, 0, 0.0f, 1.0f, 10, 3, 9, 4.0f, 2.0f, 9.0f, 1.0f, 0, 15.0f, 1, 1, -1, 0); } From 9b1661d1e7074d6232bdbcb1e4e43c03795ab5ca Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:04:23 +0000 Subject: [PATCH 106/251] decomp: improve FUN_L00_002b77f0 --- src/overlays/shared/gameplay/entities/002b2100.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b2100.c b/src/overlays/shared/gameplay/entities/002b2100.c index da06e0dd7..913d4ced3 100644 --- a/src/overlays/shared/gameplay/entities/002b2100.c +++ b/src/overlays/shared/gameplay/entities/002b2100.c @@ -2376,7 +2376,7 @@ void FUN_L00_002b77f0(unsigned char *m) { f32 speed, length, strength, response_scale; struct { f32 response[2]; s32 gate, initial_count, count; } counts; s32 i; - s32 state; + u8 state; s16 h; s32 divisor; void *effect; @@ -2528,10 +2528,10 @@ void FUN_L00_002b77f0(unsigned char *m) { divisor = FUN_001f96f8_2b77f0(D_L00_00161530_2b77f0); if (D_L00_0015F5CC % divisor == 0) FUN_L00_00233db8_2b77f0(-1, 1); - state = FUN_L00_00233e98_2b77f0(-1); + divisor = FUN_L00_00233e98_2b77f0(-1); if (FUN_001f9740_2b77f0(v + 0x4C)) { if ((D_0013CAE0[0] & g->items[0].button_mask) && - !g->unk20AC && state) + !g->unk20AC && divisor) goto tail; m[0x20] = 2; FUN_L00_0020e698_2b77f0(); @@ -2542,7 +2542,7 @@ void FUN_L00_002b77f0(unsigned char *m) { FUN_L00_0028d918_2b77f0(h); } *(s16 *)(v + 0x4A) = -1; - if (!state) + if (!divisor) FUN_L00_0028dbe8_2b77f0(0, 0, m); } break; From f45775b78bb952d86347d7539515a7092ac57e6e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:04:23 +0000 Subject: [PATCH 107/251] decomp: improve FUN_L08_002f5e58 --- src/overlays/l08/gameplay/entities/002e9b70.c | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/src/overlays/l08/gameplay/entities/002e9b70.c b/src/overlays/l08/gameplay/entities/002e9b70.c index 072c51ff8..65178b3c4 100644 --- a/src/overlays/l08/gameplay/entities/002e9b70.c +++ b/src/overlays/l08/gameplay/entities/002e9b70.c @@ -705,15 +705,15 @@ void FUN_L08_002f5e58(struct Moby *m) { b = (u8 *)d; f = (f32 *)d; stride = (b[8] + 1) * 16; - grid = __builtin_alloca(((u32)(b[8] + 1) * 128 * (b[9] + 1)) >> 3); + grid = __builtin_alloca((((u32)(b[8] + 1) << 7) * (b[9] + 1)) >> 3); inv_x = 1.0f / convert_integer_to_float(b[8]); inv_y = 1.0f / convert_integer_to_float(b[9]); u = __builtin_alloca((b[8] * 4 + 0x13) & 0x7f0); v = __builtin_alloca((b[9] * 4 + 0x13) & 0x7f0); time = convert_integer_to_float(D_L08_0015F3F8); { - f32 *current = d->levels_a; f32 *target = d->levels_b; + f32 *current = d->levels_a; i = 7; do { f32 value = *current; @@ -827,31 +827,41 @@ void FUN_L08_002f5e58(struct Moby *m) { } a = FUN_001f9de0(FUN_L00_0025e310(time * f[0x12])); a = FUN_L00_00200228(time*f[0x10] + f[0x11]*a, &temp); - for (i=0; i<=b[8]; i++) { u[i] = a; a = a + inv_x / d->period_a; } + { s32 count = 0; f32 *weight = u; do { *weight++ = a; count++; a = a + inv_x / d->period_a; } while (count <= b[8]); } a = FUN_001f9de0(FUN_L00_0025e310(time * f[0x15])); a = FUN_L00_00200228(time*f[0x13] + f[0x14]*a, &temp); - for (i=0; i<=b[9]; i++) { v[i] = a; a = a + inv_y / d->period_b; } + { s32 count = 0; f32 *weight = v; do { *weight++ = a; count++; a = a + inv_y / d->period_b; } while (count <= b[9]); } for (i=0; ipos); - add_vector_xyz(&packet.points[1], (char *)grid+((j+1)*16+k), &m->pos); - add_vector_xyz(&packet.points[2], (char *)grid+(j*16+count), &m->pos); - add_vector_xyz(&packet.points[3], (char *)grid+((j+1)*16+count), &m->pos); - temp = truncate_float_to_s32_u(((Vec4 *)((char *)grid+(j*16+k)))->f[3]); - packet.color[0] = (u32)(alpha/temp) << 24 | (u32)b[0x11] << 16 | (u32)b[0x12] << 8 | b[0x10]; - temp = truncate_float_to_s32_u(((Vec4 *)((char *)grid+((j+1)*16+k)))->f[3]); - packet.color[1] = (u32)(alpha/temp) << 24 | (u32)b[0x11] << 16 | (u32)b[0x12] << 8 | b[0x10]; - temp = truncate_float_to_s32_u(((Vec4 *)((char *)grid+(j*16+count)))->f[3]); - packet.color[2] = (u32)(alpha/temp) << 24 | (u32)b[0x11] << 16 | (u32)b[0x12] << 8 | b[0x10]; - temp = truncate_float_to_s32_u(((Vec4 *)((char *)grid+((j+1)*16+count)))->f[3]); - packet.color[3] = (u32)(alpha/temp) << 24 | (u32)b[0x11] << 16 | (u32)b[0x12] << 8 | b[0x10]; - FUN_001f7d30(&packet, NULL, 0); + { + Vec4 *current; + Vec4 *target; + f32 *current_v = v + i; + f32 *target_v = v + i + 1; + if (b[8]) { + k = i * stride; + count = (i + 1) * stride; + current = (Vec4 *)((char *)grid + k); + target = (Vec4 *)((char *)grid + count); + for (j=0; jpos); + add_vector_xyz(&packet.points[1], ¤t[j+1], &m->pos); + add_vector_xyz(&packet.points[2], &target[j], &m->pos); + add_vector_xyz(&packet.points[3], &target[j+1], &m->pos); + temp = truncate_float_to_s32_u((¤t[j])->f[3]); + packet.color[0] = (u32)(alpha/temp) << 24 | (u32)b[0x11] << 16 | (u32)b[0x12] << 8 | b[0x10]; + temp = truncate_float_to_s32_u((¤t[j+1])->f[3]); + packet.color[1] = (u32)(alpha/temp) << 24 | (u32)b[0x11] << 16 | (u32)b[0x12] << 8 | b[0x10]; + temp = truncate_float_to_s32_u((&target[j])->f[3]); + packet.color[2] = (u32)(alpha/temp) << 24 | (u32)b[0x11] << 16 | (u32)b[0x12] << 8 | b[0x10]; + temp = truncate_float_to_s32_u((&target[j+1])->f[3]); + packet.color[3] = (u32)(alpha/temp) << 24 | (u32)b[0x11] << 16 | (u32)b[0x12] << 8 | b[0x10]; + FUN_001f7d30(&packet, NULL, 0); + } + } } } if (!(d->flags & 2)) return; From 51a5ff1fca79d18ff84ac72cee69c059110bab17 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:07:21 +0000 Subject: [PATCH 108/251] decomp: improve update_debug_menu --- src/overlays/shared/rendering/debug/001f36f8.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/rendering/debug/001f36f8.c b/src/overlays/shared/rendering/debug/001f36f8.c index da8f94fd0..faaa10129 100644 --- a/src/overlays/shared/rendering/debug/001f36f8.c +++ b/src/overlays/shared/rendering/debug/001f36f8.c @@ -899,9 +899,10 @@ void FUN_L00_001f4598(void) { if ((g_debug_menu.selected_row == 1) && ((D_0013C940.buttons.w.pressed & 0x50) != 0)) { g_debug_menu.actuator_enabled = (u32)(g_debug_menu.actuator_enabled == 0); } - if ((g_debug_menu.selected_row == 2) && (index = 0, (D_0013C940.buttons.w.pressed & 0xf0) != 0)) { + if ((g_debug_menu.selected_row == 2) && ((D_0013C940.buttons.w.pressed & 0xf0) != 0)) { + b32 enabled = FALSE; + s32 index = 0; f64 formatted_x, formatted_y, formatted_z; - enabled = FALSE; if (0 < D_L00_0015F614) { f32 *capture_positions = D_L00_00173E20; do { From 448024222ce6cdf0f16ee3a3309d3a9179f38375 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:01:42 +0000 Subject: [PATCH 109/251] decomp: improve FUN_L13_002ba178 --- src/overlays/l13/gameplay/entities/002b0e80.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/l13/gameplay/entities/002b0e80.c b/src/overlays/l13/gameplay/entities/002b0e80.c index ad93a9b9a..9e6a05374 100644 --- a/src/overlays/l13/gameplay/entities/002b0e80.c +++ b/src/overlays/l13/gameplay/entities/002b0e80.c @@ -3007,7 +3007,7 @@ void FUN_L13_002ba178(void *moby, void *obj) { distance = frame_time*30.0f-frame_time*24.0f; if (height < 0.0f) speed_fraction = 0.0f/distance; else speed_fraction = height/distance; - *(u128 *)camera_position = 0; + camera_position[3] = 0.0f; *(u128 *)camera_rotation = 0; camera_position[0] = ((-15.0f-F(d,0x70))-speed_fraction*4.0f)*0.25f; camera_position[1] = F(d,0x6C)*-3.0f*0.25f; From 5b75bb97cf92511ba9969691ac8204323582a9c4 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:29:11 +0000 Subject: [PATCH 110/251] decomp: improve sceGsSetDefDispEnv --- src/assembly/sdk/dma/sce_gs_set_def_disp_env.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c index 3dca0ee59..b3581f6a3 100644 --- a/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c +++ b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c @@ -60,10 +60,10 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s if ((s16)interlace == 1) { scale = (width + 0x9ff) / width; display_vertical = (u64)((vertical_offset + kernel_vertical + 0x32) & 0xfff) << 12; + display_width = (u64)(s64)(scale * width - 1) << 32; scaled_horizontal = (s64)kernel_horizontal + 0x27c; scaled_horizontal = (scaled_horizontal + horizontal_offset * scale) & 0xfff; value = (u64)(s64)(scale - 1) << 23; - display_width = (u64)((s64)(scale * width) - 1) << 32; if (state->nSFrame_mode != 0) { scale = height * 2 - 1; } else { @@ -85,10 +85,10 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s if ((s16)interlace == 1) { scale = (width + 0x9ff) / width; display_vertical = (u64)((vertical_offset + kernel_vertical + 0x48) & 0xfff) << 12; + display_width = (u64)(s64)(scale * width - 1) << 32; scaled_horizontal = (s64)kernel_horizontal + 0x290; scaled_horizontal = (scaled_horizontal + horizontal_offset * scale) & 0xfff; value = (u64)(s64)(scale - 1) << 23; - display_width = (u64)((s64)(scale * width) - 1) << 32; if (state->nSFrame_mode != 0) { scale = height * 2 - 1; } else { From 9d3dd55f2c00ae0b8a920bc731fd3b33ab6453a5 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:30:05 +0000 Subject: [PATCH 111/251] decomp: improve FUN_L00_002b49a8 --- src/overlays/shared/gameplay/entities/002b2100.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/002b2100.c b/src/overlays/shared/gameplay/entities/002b2100.c index 913d4ced3..0168d39a8 100644 --- a/src/overlays/shared/gameplay/entities/002b2100.c +++ b/src/overlays/shared/gameplay/entities/002b2100.c @@ -1153,7 +1153,8 @@ void FUN_L00_002b49a8(u8 *m) { r[0x3C]++; n = D_0015EEA4_2b49a8; } - if (r[0x3D] < FUN_001f96f8_2b49a8(n) / 600) { + n = FUN_001f96f8_2b49a8(n) / 600; + if (r[0x3D] < n) { r[0x3D] = FUN_001f96f8_2b49a8(D_0015EEA4_2b49a8) / 600; index = D_0015ED84_2b49a8; } else index = D_0015ED84_2b49a8; From f49fa1b4e18c55e3f6594dd43e9ee1967f585858 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:30:07 +0000 Subject: [PATCH 112/251] decomp: improve FUN_L00_002ce358 --- .../shared/gameplay/entities/002c8440.c | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002c8440.c b/src/overlays/shared/gameplay/entities/002c8440.c index 9c24aa77d..913218803 100644 --- a/src/overlays/shared/gameplay/entities/002c8440.c +++ b/src/overlays/shared/gameplay/entities/002c8440.c @@ -2447,30 +2447,28 @@ void FUN_L00_002ce358(struct Moby *m) { struct Moby **slots, **exclusions; s32 i; - slots = (struct Moby **)hero.unk2020; exclusions = (struct Moby **)((u8 *)&hero + 0x1ffc); + slots = (struct Moby **)hero.unk2020; for (i = 0; i < 6; i++, slots++) { other = *slots; - if (!other) - continue; - if (other->oclass != 0x1df) { - *slots = 0; - continue; - } - if (other->state == 0xfe) { - *slots = 0; - continue; - } - if (other->state == 0xfd) { - *slots = 0; - continue; + if (other != 0) { + if (other->oclass == 0x1df) { + if (other->state == 0xfe) { + *slots = 0; + } else if (other->state == 0xfd) { + *slots = 0; + } else { + count++; + *exclusions++ = *(struct Moby **)(other->pvars + 0x30); + if (other->state < 4) + (*(u8 *)((u8 *)&hero + 0x1ff7))++; + if (count > 8) + break; + } + } else { + *slots = 0; + } } - count++; - *exclusions++ = *(struct Moby **)(other->pvars + 0x30); - if (other->state < 4) - (*(u8 *)((u8 *)&hero + 0x1ff7))++; - if (count > 8) - break; } if (count < 9) { exclusions = (struct Moby **)((u8 *)&hero + 0x1ffc) + count; @@ -2677,7 +2675,9 @@ void FUN_L00_002ce358(struct Moby *m) state4: { target = v->target; - if (target == 0 || target->oclass != v->target_oclass || target->state == 0xfe || target->state == 0xfd) { + if (target == 0 || target->oclass != v->target_oclass) { + v->target = 0; + } else if (target->state == 0xfe || target->state == 0xfd) { v->target = 0; } else { char *h = (char *)FUN_002141f8_c((char *)target); From d5c3645b103fed4ef44ac30b58811eb993614ccf Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:31:54 +0000 Subject: [PATCH 113/251] decomp: improve FUN_L00_002ddf60 --- src/overlays/shared/gameplay/entities/002d7f88.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002d7f88.c b/src/overlays/shared/gameplay/entities/002d7f88.c index 0ba41ef18..82a663db4 100644 --- a/src/overlays/shared/gameplay/entities/002d7f88.c +++ b/src/overlays/shared/gameplay/entities/002d7f88.c @@ -2866,6 +2866,7 @@ void FUN_L00_002ddf60(void *frame_context, void *initial_vector) { short *halfword; int i, j, row, segment, count, small_count, index, next_segment; float fraction, sampled, angle, delta, length, row_float, spread, phase, value; + int next_row; FUN_L00_002ddcb8(frame_context, initial_vector); global = (char *)&D_0013F350_c; @@ -2992,7 +2993,7 @@ void FUN_L00_002ddf60(void *frame_context, void *initial_vector) { phase = row_float * 0.7f; current = D_L00_001E6020_002ddf60 + (int)((unsigned int)(row * 5) << 6); prior = D_L00_001E4B40; - ++row; + next_row = row + 1; j = 0; do { value = spread + 0.1f; @@ -3006,6 +3007,7 @@ void FUN_L00_002ddf60(void *frame_context, void *initial_vector) { prior += 16; } while (j < 20); FUN_001ff500_002ddcb8(&scaled_first, &offset, D_L00_00161B84); + row = next_row; } while (row < 10); FUN_001f9598_002ddf60(FUN_L00_002dd8e8, frame_context); count = 0; @@ -3099,12 +3101,12 @@ void FUN_L00_002ddf60(void *frame_context, void *initial_vector) { row = *(volatile short *)record; FUN_001ff278_002ddcb8(*(char **)(record + 20) + 16, D_L00_001E5F40_002ddcb8 + row * 16, &temp1); segment = *(volatile short *)(record + 2); - FUN_001ff2a8_002ddf60(&temp2, D_L00_001E6020_002ddf60 + (int)((unsigned int)(row * 5) << 6) + segment * 16, D_L00_001E5F40_002ddcb8 + row * 16); - FUN_001ff2a8_002ddf60(&edge, D_L00_001E6020_002ddf60 + (int)((unsigned int)(row * 5) << 6) + segment * 16 - 0x140, D_L00_001E5F30_002ddcb8 + row * 16); + FUN_001ff2a8_002ddf60(&temp2, D_L00_001E6020_002ddf60 + row * 320 + segment * 16, D_L00_001E5F40_002ddcb8 + row * 16); + FUN_001ff2a8_002ddf60(&edge, D_L00_001E6020_002ddf60 + row * 320 + segment * 16 - 0x140, D_L00_001E5F30_002ddcb8 + row * 16); interpolate_vector4_linear_002ddf60(&offset, &temp2, &edge, fraction); next_segment = (segment + 19) % 20; - FUN_001ff2a8_002ddf60(&direction, D_L00_001E6020_002ddf60 + (int)((unsigned int)(row * 5) << 6) + next_segment * 16, D_L00_001E5F40_002ddcb8 + row * 16); - FUN_001ff2a8_002ddf60(&tangent, D_L00_001E6020_002ddf60 + (int)((unsigned int)(row * 5) << 6) + next_segment * 16 - 0x140, D_L00_001E5F30_002ddcb8 + row * 16); + FUN_001ff2a8_002ddf60(&direction, D_L00_001E6020_002ddf60 + row * 320 + next_segment * 16, D_L00_001E5F40_002ddcb8 + row * 16); + FUN_001ff2a8_002ddf60(&tangent, D_L00_001E6020_002ddf60 + row * 320 + next_segment * 16 - 0x140, D_L00_001E5F30_002ddcb8 + row * 16); interpolate_vector4_linear_002ddf60(&following, &direction, &tangent, fraction); interpolate_vector4_linear_002ddf60(&offset, &offset, &following, *(volatile float *)(record + 8)); value = *(volatile float *)(record + 8) + *(volatile float *)(record + 12); From fda468eaed1d715ddf31023cda8a6866cdc00e24 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:34:57 +0000 Subject: [PATCH 114/251] decomp: improve update_linked_moby_path_transition --- src/overlays/l12/gameplay/vendor/003028c8.c | 274 ++++++++++++++++++++ 1 file changed, 274 insertions(+) diff --git a/src/overlays/l12/gameplay/vendor/003028c8.c b/src/overlays/l12/gameplay/vendor/003028c8.c index da955e16b..424443c39 100644 --- a/src/overlays/l12/gameplay/vendor/003028c8.c +++ b/src/overlays/l12/gameplay/vendor/003028c8.c @@ -1282,7 +1282,281 @@ void FUN_L12_00306828(struct Moby *moby) { } } #endif /* NON_MATCHING */ +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L12_003069d0.s", FUN_L12_003069d0); +#else +extern float FUN_L00_0025b8c0(float *, float *, float, float, float, float); +extern float fast_difference_between_rotations(float, float) __asm__("FUN_001fa688"); +extern int D_L12_001619B4; +extern int D_L12_001FB6CC; +extern float D_L12_00161F40; +extern float D_L12_00161F60[4], D_L12_00161F70[4]; +extern float D_L12_00161F28 __attribute__((sda)); +extern float D_L12_00161F2C __attribute__((sda)); +extern float D_L12_00161F30 __attribute__((sda)); +extern int D_L12_00161F34 __attribute__((sda)); +extern int D_L12_0015F404 __attribute__((sda)); +extern char *D_L12_001600EC; +extern unsigned char D_0014C050[]; +extern void FUN_L12_0027b268(void *, void *, int); +extern void FUN_L12_0027b370(void *, void *, int); +extern void FUN_L00_00262b00(void *, void *, void *, float, float); +extern void FUN_L00_00262b80(void *, void *, void *, float, float, float); +extern float FUN_L00_00258278(void *, void *, float, float, float, float); +extern float FUN_L00_0025bc98(void *, void *, int, float, float, float, float); +extern float advance_accelerated_scalar_l12(void *, void *, float, float, float, float) __asm__("FUN_00213f38"); +extern void FUN_001f9a28(void *, void *, void *); +extern void FUN_001f9bf8(void *, void *, float); +extern void FUN_001f9a40(void *, void *, void *, float); +extern void FUN_L00_002eac18(int); +extern int FUN_00214720(void *, int); +extern void FUN_L12_003054b0(void *); +extern void FUN_L12_003064e8(void *); +extern int FUN_0022da68(int, int, void *); +extern void release_voice_slot(int) __asm__("FUN_0022d798"); + +void FUN_L12_003069d0(struct Moby *moby) { + float direction[4] __attribute__((aligned(16))); + float rotation[4] __attribute__((aligned(16))); + char *data = (char *)moby->pvars; + int i, next; + int *slot; + int *saved; + struct Moby *other; + float height, angle, distance; + int triggered; + + if (moby->state && D_L12_001FB6CC) { + qcopy(&moby->pos, D_L12_00161F60); + qcopy(&moby->rot, D_L12_00161F70); + } + switch (moby->state) { + case 0: { + char *row; + D_L12_001619B4 = 0; + if (D_0014C050[moby->mission + current_level_index * 16] == 0xff) { + slot = (int *)(data + 0x20); + i = 16; + do { + if (*slot != -1) mark_moby_for_removal(D_L12_0015FFD8_p + *slot * 0x100); + i--; + slot += 12; + } while (i >= 0); + goto remove_moby; + } + D_L12_00161F24 = 0; + FUN_L12_0027b268(moby, data, 17); + row = ((char **)&D_L12_001B0930)[*(int *)(data + 0x5c0)]; + qcopy(&moby->pos, row + 0x10); + *(float *)(data + 0x618) = moby->pos.z; + moby->rot.z = FUN_001f9e90(*(float *)(row + 0x20) - *(float *)(row + 0x10), + *(float *)(row + 0x24) - *(float *)(row + 0x14)); + if (((float *)&D_0013F3D0)[2] < 52.0f) moby->pos.z += 3.0f; + slot = (int *)(data + 0x5d0); + i = 4; + do { + int index = *slot++; + other = (struct Moby *)(D_L12_0015FFD8_p + *(int *)(data + index * 0x30 + 0x20) * 0x100); + *(float *)(other->pvars + 0x80) = 10.0f; + i--; + } while (i >= 0); + D_L12_00161F40 = -1.0f; + saved = D_L12_001FB688; + saved += 17; + i = 17; + do { *saved-- = 0; i--; } while (i >= 0); + *(int *)(data + 0x604) = -1; + *(short *)(data + 0x5fc) = 100; + moby->state = 1; + break; + } + case 1: + triggered = FUN_00214720(D_L12_00167240, *(int *)(data + 0x624)); + if (triggered) { + moby->flags |= 0x41; + slot = (int *)(data + 0x20); + i = 16; + do { + if (*slot != -1) { + other = (struct Moby *)(D_L12_0015FFD8_p + *slot * 0x100); + other->flags |= 0x41; + } + i--; slot += 12; + } while (i >= 0); + } else { + moby->flags &= 0xffbe; + slot = (int *)(data + 0x20); + i = 16; + do { + if (*slot != -1) { + other = (struct Moby *)(D_L12_0015FFD8_p + *slot * 0x100); + other->flags &= 0xffbe; + } + i--; slot += 12; + } while (i >= 0); + } + triggered = FUN_00214720(&D_0013F3D0, *(int *)(data + 0x628)); + if (!(52.0f < ((float *)&D_0013F3D0)[2]) || triggered) { + height = 3.0f; + if (triggered) height = 10.0f; + if (FUN_00214720(&D_0013F3D0, *(int *)(data + 0x61c))) + *(int *)(data + 0x620) = scale_ticks(90); + if (!tick_countdown_32_alt((int *)(data + 0x620))) height = 19.0f; + FUN_L00_0025b8c0(&moby->pos.z, data + 0x62c, *(float *)(data + 0x618) + height, + frame_scale_sq * 0.03f, frame_scale_sq * 0.3f, frame_time * 2.7f); + height = frame_time; + } else { + approach_value(&moby->pos.z, *(float *)(data + 0x618), frame_time + frame_time); + height = frame_time; + } + FUN_L00_00262b00(moby, data + 0x5cc, data + 0x5c8, 0.7f, height * 1.2217305f); + FUN_L00_00262b80(moby, data + 0x5e4, data + 0x5e8, D_L12_00161F30, + D_L12_00161F28 * 0.017453292f * frame_time, D_L12_00161F2C * 0.017453292f * frame_time); + FUN_L12_0027b370(moby, data, 17); + if (FUN_00214720(&D_0013F3D0, *(int *)(data + 0x5ec)) || D_L12_00161F00) { + D_L12_001619B4 = 1; + slot = (int *)(data + 0x5d0); i = 4; + do { + int index = *slot++; + other = (struct Moby *)(D_L12_0015FFD8_p + *(int *)(data + index * 0x30 + 0x20) * 0x100); + other->hit_slot = 0xff; + i--; + } while (i >= 0); + moby->state = 2; + } + break; + case 2: { + char *row; + FUN_L00_00262b00(moby, data + 0x5cc, data + 0x5c8, 0.7f, frame_time * 1.2217305f); + FUN_L00_00262b80(moby, data + 0x5e4, data + 0x5e8, D_L12_00161F30, + D_L12_00161F28 * 0.017453292f * frame_time, D_L12_00161F2C * 0.017453292f * frame_time); + row = ((char **)&D_L12_001B0930)[*(int *)(data + 0x5c0)]; + if (*(short *)(data + 0x5f8) < *(int *)row - 11) { + approach_value((float *)(data + 0x5f0), frame_time * 8.0f, frame_time_sq * 10.0f); + } else { + approach_value((float *)(data + 0x5f0), 0.0f, frame_time_sq * 8.0f); + if (*(float *)(data + 0x5f0) == 0.0f) { moby->state = 3; break; } + } + next = (*(short *)(data + 0x5f8) + 1) % *(int *)row; + FUN_001f9a28(direction, row + next * 16 + 16, row + *(short *)(data + 0x5f8) * 16 + 16); + FUN_001f9bf8(direction, direction, *(float *)(data + 0x5f0)); + FUN_001f9a10(&moby->pos, &moby->pos, direction); + angle = FUN_001f9e90(*(float *)(row + next * 16 + 16) - *(float *)(row + *(short *)(data + 0x5f8) * 16 + 16), + *(float *)(row + next * 16 + 20) - *(float *)(row + *(short *)(data + 0x5f8) * 16 + 20)); + if (*(int *)row - 20 < *(short *)(data + 0x5f8)) angle = 3.054326f; + FUN_L00_00258278(moby, data + 0x5f4, angle, frame_scale_sq * 0.0015f, frame_scale_sq * 0.3f, frame_time * 0.17453292f); + distance = FUN_001f9b80(&moby->pos, row + *(short *)(data + 0x5f8) * 16 + 16); + if (!(distance < 5.0f)) { + angle = FUN_001f9e90(*(float *)(row + *(short *)(data + 0x5f8) * 16 + 16) - moby->pos.x, + *(float *)(row + *(short *)(data + 0x5f8) * 16 + 20) - moby->pos.y); + if (!(1.5707964f < fast_difference_between_rotations(moby->rot.z, angle))) goto update_linked; + } + *(short *)(data + 0x5f8) = (*(short *)(data + 0x5f8) + 1) % *(int *)row; + goto update_linked; + } + case 3: + D_L12_00161F34++; + FUN_L00_0025bc98(&moby->rot.z, data + 0x5f4, -1, 3.054326f, + frame_scale_sq * 0.0015f, frame_scale_sq * 0.3f, frame_time * 0.17453292f); + FUN_L00_00262b00(moby, data + 0x5cc, data + 0x5c8, 0.7f, frame_time * 1.2217305f); + FUN_L00_00262b80(moby, data + 0x5e4, data + 0x5e8, D_L12_00161F30, + D_L12_00161F28 * 0.017453292f * frame_time, D_L12_00161F2C * 0.017453292f * frame_time); +update_linked: + FUN_L12_0027b370(moby, data, 17); + FUN_L12_003054b0(moby); + break; + case 4: + if (*(int *)(data + 0x608) != -1 && *(int *)(data + 0x60c) != -1) { + if (moby->command == 1) { + if (*(float *)(data + 0x610) < 1.0f) { + advance_accelerated_scalar_l12(data + 0x610, data + 0x614, 1.0f, + frame_time_sq * 0.666f, frame_time_sq * 0.666f, frame_time * 0.4f); + FUN_001f9a40(direction, + D_L12_001600EC + *(int *)(data + 0x608) * 128 + 0x30, + D_L12_001600EC + *(int *)(data + 0x60c) * 128 + 0x30, + *(float *)(data + 0x610)); + clear_u64_value(rotation); + angle = fast_subtract_rotations(*(float *)(D_L12_001600EC + *(int *)(data + 0x60c) * 128 + 0x70), + *(float *)(D_L12_001600EC + *(int *)(data + 0x608) * 128 + 0x70)); + rotation[0] = angle * *(float *)(data + 0x610); + /* Retail uses the zero second component here, discarding the first delta. */ + rotation[0] = fast_add_rotations(*(float *)(D_L12_001600EC + *(int *)(data + 0x608) * 128 + 0x70), rotation[1]); + angle = fast_subtract_rotations(*(float *)(D_L12_001600EC + *(int *)(data + 0x60c) * 128 + 0x74), + *(float *)(D_L12_001600EC + *(int *)(data + 0x608) * 128 + 0x74)); + rotation[1] = angle * *(float *)(data + 0x610); + rotation[1] = fast_add_rotations(*(float *)(D_L12_001600EC + *(int *)(data + 0x608) * 128 + 0x74), rotation[1]); + angle = fast_subtract_rotations(*(float *)(D_L12_001600EC + *(int *)(data + 0x60c) * 128 + 0x78), + *(float *)(D_L12_001600EC + *(int *)(data + 0x608) * 128 + 0x78)); + rotation[2] = angle * *(float *)(data + 0x610); + rotation[2] = fast_add_rotations(*(float *)(D_L12_001600EC + *(int *)(data + 0x608) * 128 + 0x78), rotation[2]); + FUN_L00_002ea9d8(direction); + FUN_L00_002eaa30(rotation); + } else { + moby->command = 2; + D_L12_0015F404 = 0; + FUN_L00_002eac18(3); + } + } else if (moby->command < 2) { + if (moby->command == 0) { + moby->command = 1; + FUN_L00_002ea9d8(D_L12_001600EC + *(int *)(data + 0x608) * 128 + 0x30); + FUN_L00_002eaa30(D_L12_001600EC + *(int *)(data + 0x608) * 128 + 0x70); + D_L12_001619A0 = 1; + D_L12_0015F404 = 1; + } + } else if (moby->command == 2) { + char *slot_data = data; + int index; + saved = D_L12_001FB688; + i = 16; + do { + index = *(int *)(slot_data + 0x20); + if (index != -1) { + other = (struct Moby *)(D_L12_0015FFD8_p + index * 256); + if ((signed char)other->state >= 0) mark_moby_for_removal(other); + *(int *)(slot_data + 0x20) = -1; + } else if (*saved > 0) { + other = (struct Moby *)(D_L12_0015FFD8_p + *saved * 256); + if ((signed char)other->state >= 0) mark_moby_for_removal(other); + } + saved++; i--; slot_data += 0x30; + } while (i >= 0); + D_L12_001619B4 = 0; + FUN_L00_00298840(7); +remove_moby: + mark_moby_for_removal(moby); + return; + } + } + if (*(short *)(data + 0x5fa) == 0) { + slot = (int *)(data + 0x20); saved = D_L12_001FB688; i = 16; + do { + if (*saved == 0) *saved = *slot; + *slot = -1; + saved++; i--; slot += 12; + } while (i >= 0); + saved = D_L12_001FB688; + saved[17] = 1; + for (i = 0; i < 18; i++) FUN_L12_00306350(moby, i); + } + *(short *)(data + 0x5fa) += 1; + FUN_L12_003064e8(moby); + break; + } + FUN_L12_00306828(moby); + if ((unsigned int)(moby->state - 1) < 3) { + if (*(int *)(data + 0x604) == -1) *(int *)(data + 0x604) = FUN_0022da68(0, 4, moby); + } else { + int index = *(int *)(data + 0x604); + if (index != -1) { + char *entry = voice_pool + index * 0x70; + if (*(struct Moby **)(entry + 0x88) == moby && *(unsigned char *)(entry + 0x74)) + release_voice_slot(index); + } + *(int *)(data + 0x604) = -1; + } +} +#endif #include "qcopy.h" /* Spawns the next linked moby at this one's spot, sets it up and gives it a random spin. */ From 978d9d2d3e13e339f3d0251b23100139b18d180c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:33:58 +0000 Subject: [PATCH 115/251] decomp: improve FUN_L00_002d09b8 --- .../shared/gameplay/entities/002cfcb8.c | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002cfcb8.c b/src/overlays/shared/gameplay/entities/002cfcb8.c index 5cfc788c1..3bbfda41b 100644 --- a/src/overlays/shared/gameplay/entities/002cfcb8.c +++ b/src/overlays/shared/gameplay/entities/002cfcb8.c @@ -449,6 +449,7 @@ extern f32 D_0015ED6C_2d09b8 __asm__("D_0015ED6C"); extern f32 D_L00_0015F5D0_2d09b8 __asm__("D_L00_0015F5D0"); extern s32 D_001413DC_2d09b8 __asm__("D_001413DC") __attribute__((section(".data"))); extern u8 *D_001413D0_2d09b8 __asm__("D_001413D0") __attribute__((section(".data"))); +extern f32 D_L00_00166C80_2d19b0[] __asm__("D_L00_00166C80"); extern V2d09b8 D_L00_00166DC0_2d09b8 __asm__("D_L00_00166DC0"); extern V2d09b8 D_L00_001DE6F0_2d09b8[] __asm__("D_L00_001DE6F0"); extern V2d09b8 D_L00_001DE750_2d09b8[] __asm__("D_L00_001DE750"); @@ -473,15 +474,15 @@ extern f32 FUN_002000e8_2d09b8(f32, f32) __asm__("FUN_001fa580"); extern f32 FUN_00257be8_2d09b8(f32, f32) __asm__("FUN_002132a8"); extern void FUN_001ff500_2d09b8(f32, void *, void *) __asm__("FUN_001f9bf8"); extern s32 FUN_00257b50_2d09b8(s32) __asm__("FUN_00213260"); -extern void *FUN_002af8b0_2d09b8(f32, f32, void *, void *, void *, void *, s32, s32) __asm__("FUN_L00_002af8b0"); +extern void *FUN_002af8b0_2d09b8(void *, void *, void *, void *, s32, s32, f32, f32) __asm__("FUN_L00_002af8b0"); extern void FUN_00250df8_2d09b8(void *) __asm__("FUN_L00_00250df8"); extern void FUN_00257d78_2d09b8(f32, f32, void *) __asm__("FUN_L00_00257d78"); extern f32 FUN_00257cb0_2d09b8(void) __asm__("FUN_00213308"); extern u8 FUN_001fef20_2d09b8(s32) __asm__("FUN_001f96f8"); extern f32 FUN_001ff3d8_2d09b8(void *) __asm__("FUN_001f9af0"); extern s32 FUN_00257b90_2d09b8(s32, s32) __asm__("FUN_L00_00257b90"); -extern void FUN_0026a9f0_2d09b8(f32, f32, void *, void *, s32, s32, s32, s32, s32, s32) __asm__("FUN_L00_0026a9f0"); -extern void FUN_002ac910_2d09b8(f32, void *, void *, void *, s32, s32, s32, s32, s32) __asm__("FUN_L00_002ac910"); +extern void FUN_0026a9f0_2d09b8(void *, void *, s32, s32, s32, s32, s32, s32, f32, f32) __asm__("FUN_L00_0026a9f0"); +extern void FUN_002ac910_2d09b8(void *, void *, void *, s32, f32, s32, s32, s32, s32) __asm__("FUN_L00_002ac910"); void FUN_L00_002d09b8(M2d1428 *m, s32 hit, s32 source) { u8 *vars = (u8 *)m->vars; @@ -525,11 +526,10 @@ void FUN_L00_002d09b8(M2d1428 *m, s32 hit, s32 source) { else FUN_001ff2a8_2d09b8(&b, &m->pos, D_001413D0_2d09b8 + 0x10); switch ((s16)((u16)m->oclass - 500)) { - case 0: kind = 0x165; break; - case 11: kind = 0x165; break; case 1: kind = 0x15C; break; - case 2: kind = 0x162; break; case 3: kind = 0x15F; break; + case 2: kind = 0x162; break; + case 0: case 11: kind = 0x165; break; case 4: kind = 0x168; break; case 5: kind = 0x16B; break; case 6: kind = 0x16E; break; @@ -539,9 +539,10 @@ void FUN_L00_002d09b8(M2d1428 *m, s32 hit, s32 source) { if (D_L00_0015FFBC_2d09b8 >= 201) { count = 4; trail_count = 4; } else if (D_L00_0015FFBC_2d09b8 >= 151) { count = 2; trail_count = 2; } else if (D_L00_0015FFBC_2d09b8 >= 101) { count = 2; trail_count = 1; } - else { trail_count = 0; if (D_L00_0015FFBC_2d09b8 >= 51) count = 1; else count = 1; } - speed = D_L00_00166DC0_2d09b8.f[1] - m->pos.y; - angle = D_L00_00166DC0_2d09b8.f[0] - m->pos.x; + else if (D_L00_0015FFBC_2d09b8 >= 51) { count = 1; trail_count = 0; } + else { count = 1; trail_count = 0; } + angle = D_L00_00166C80_2d19b0[80] - m->pos.x; + speed = D_L00_00166C80_2d19b0[81] - m->pos.y; angle = FUN_001ff8b0_2d09b8(angle, speed); angle = FUN_00200130_2d09b8(angle, m->v40.z); angle += 3.1415925f; @@ -550,10 +551,10 @@ void FUN_L00_002d09b8(M2d1428 *m, s32 hit, s32 source) { FUN_001ff260_2d09b8(&rotation); rotation.f[2] = angle; FUN_001ffa50_2d09b8(&c, &rotation); - for (i = count; i != 0; --i) { - FUN_001ff6d0_2d09b8(&d, &D_L00_001DE6F0_2d09b8[count - i], &c); + for (i = 0; i < count; ++i) { + FUN_001ff6d0_2d09b8(&d, &D_L00_001DE6F0_2d09b8[i], &c); FUN_001ff278_2d09b8(&d, &d, &m->pos); - qcopy(&e, &D_L00_001DE750_2d09b8[count - i]); + qcopy(&e, &D_L00_001DE750_2d09b8[i]); e.f[2] = FUN_002000e8_2d09b8(e.f[2], rotation.f[2]); FUN_001ff2a8_2d09b8(&a, &d, &m->pos); a.f[2] = 0.0f; @@ -561,9 +562,9 @@ void FUN_L00_002d09b8(M2d1428 *m, s32 hit, s32 source) { FUN_001ff500_2d09b8(speed * D_0015ED6C_2d09b8, &a, &a); a.f[2] = FUN_00257be8_2d09b8(4.0f, 9.0f) * D_0015ED6C_2d09b8; particle = FUN_00257b50_2d09b8(2); - spawned = FUN_002af8b0_2d09b8(1.0f, 1.0f, m, &a, &d, &e, kind, particle); + spawned = FUN_002af8b0_2d09b8(m, &a, &d, &e, kind, particle, 1.0f, 1.0f); if (spawned) { - qcopy((u8 *)spawned + 0x40, &D_L00_001DE750_2d09b8[count - i]); + qcopy((u8 *)spawned + 0x40, &D_L00_001DE750_2d09b8[i]); *(f32 *)((u8 *)spawned + 0x48) = FUN_002000e8_2d09b8(*(f32 *)((u8 *)spawned + 0x48), rotation.f[2]); FUN_00250df8_2d09b8(spawned); } @@ -581,7 +582,7 @@ void FUN_L00_002d09b8(M2d1428 *m, s32 hit, s32 source) { particle = 1; if (FUN_00257b50_2d09b8(6) == 0) particle = FUN_00200250_2d09b8(FUN_00257be8_2d09b8(3.0f, 6.0f)); - FUN_002af8b0_2d09b8(0.25f, 0.5f, m, &a, &d, &e, kind + 1, particle); + FUN_002af8b0_2d09b8(m, &a, &d, &e, kind + 1, particle, 0.25f, 0.5f); } *(u32 *)((u8 *)m + 0x94) = 0; m->state = 3; @@ -615,15 +616,15 @@ void FUN_L00_002d09b8(M2d1428 *m, s32 hit, s32 source) { first = FUN_001fef20_2d09b8(25); second = FUN_001fef20_2d09b8(30); second_color = FUN_00257b90_2d09b8(first, second); - FUN_0026a9f0_2d09b8(400000.0f, rise, &a, &e, *effect, *velocity, first_color, second_color, 0, 0); + FUN_0026a9f0_2d09b8(&a, &e, *effect, *velocity, first_color, second_color, 0, 0, 400000.0f, rise); } if (D_L00_0015F5D0_2d09b8 < 0.95f && distance > 9.0f && !close) { - FUN_002ac910_2d09b8(4.0f, m, &a, &e, FUN_001fef20_2d09b8(15), 127, 127, 127, 32); - FUN_002ac910_2d09b8(4.0f, m, &a, &e, FUN_001fef20_2d09b8(24), 127, 32, 0, 32); - FUN_002ac910_2d09b8(4.0f, m, &a, &e, FUN_001fef20_2d09b8(20), 127, 64, 0, 48); + FUN_002ac910_2d09b8(m, &a, &e, FUN_001fef20_2d09b8(15), 4.0f, 127, 127, 127, 32); + FUN_002ac910_2d09b8(m, &a, &e, FUN_001fef20_2d09b8(24), 4.0f, 127, 32, 0, 32); + FUN_002ac910_2d09b8(m, &a, &e, FUN_001fef20_2d09b8(20), 4.0f, 127, 64, 0, 48); } - FUN_002ac910_2d09b8(3.5f, m, &a, &e, FUN_001fef20_2d09b8(27), 96, 16, 0, 64); - FUN_002ac910_2d09b8(3.0f, m, &a, &e, FUN_001fef20_2d09b8(29), 32, 0, 0, 32); + FUN_002ac910_2d09b8(m, &a, &e, FUN_001fef20_2d09b8(27), 3.5f, 96, 16, 0, 64); + FUN_002ac910_2d09b8(m, &a, &e, FUN_001fef20_2d09b8(29), 3.0f, 32, 0, 0, 32); } } #endif From da2186e2278d7319dd73a08aacecaf0a5ebe9331 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:40:23 +0000 Subject: [PATCH 116/251] decomp: improve FUN_L12_002e9f68 --- src/overlays/l12/gameplay/entities/002bf140.c | 306 ++++++++++++++++++ 1 file changed, 306 insertions(+) diff --git a/src/overlays/l12/gameplay/entities/002bf140.c b/src/overlays/l12/gameplay/entities/002bf140.c index 52c0618bc..daaac2ce2 100644 --- a/src/overlays/l12/gameplay/entities/002bf140.c +++ b/src/overlays/l12/gameplay/entities/002bf140.c @@ -2344,7 +2344,313 @@ void FUN_L12_002e8808(struct Moby *moby, float *target, float max_angle, float a } } } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L12_002e9f68.s", FUN_L12_002e9f68); +#else +extern float spring_turn(float *, float, float, float, float, float) __asm__("FUN_L00_00258110"); +extern float FUN_L00_00257c48(float, float); +extern void FUN_L01_00274b78(void *, void *, float); +extern void FUN_L00_00263ac8(void *, int, void *, float); +extern void FUN_L12_002eb220(struct Moby *); +extern void FUN_L12_002eae00(struct Moby *); +extern int FUN_L12_002eaf68(struct Moby *, int); +extern void FUN_L12_0027ba70(int); +extern struct Moby *FUN_L12_00308670(struct Moby *); +extern void FUN_L12_00308708(struct Moby *); +extern int allocate_voice_for_target_entry_e9f68(int, int, int) __asm__("FUN_0022da68"); +extern void release_voice(int) __asm__("FUN_0022d798"); +extern void help_request(int, int) __asm__("FUN_L00_00203908"); +extern void advance_moby_animation(void *) __asm__("FUN_0020d580"); +extern void FUN_L00_00269958(void *, void *, int, int, int, int, int, int); +extern char *FUN_L12_002ecce8(void *, void *, int, int, float, float, float); +extern void FUN_L00_0025e450(void *, void *, void *, float, float, int, int, int, float, float, float, int, float, float, int, int, int, int); +extern unsigned char D_001413F4 __attribute__((section(".data"))); +extern int D_L12_00161F00 __attribute__((section(".data"))); +extern int D_L12_00161F20 __attribute__((section(".data"))); +extern int D_L12_001619A0 __attribute__((sda)); +typedef struct { char pad[0x25c]; struct Moby *moby; int count; } Tracking_e9f68; +extern Tracking_e9f68 D_L12_00167100; +extern unsigned char D_0014C050[]; +typedef struct { char pad[0x74]; unsigned char active; char pad75[0x13]; struct Moby *moby; char rest[0x70 - 0x1c]; } Voice_e9f68; +extern unsigned char D_0013E550[]; +extern unsigned char D_0013D4CB; +extern unsigned short D_00141C50; +extern char D_L12_0015F580[]; + +void FUN_L12_002e9f68(struct Moby *moby) { + char *data = (char *)moby->pvars; + struct Moby *child; + float target[20] __attribute__((aligned(16))); + OvlVec4 position, delta, aim, velocity; + int index, count, limit, a, b, color, life, size, triggered; + float distance, angle, value, spread; + if (D_L12_0015F5C4_c == 2) return; + FUN_L01_00274b78(moby, target, 70.0f); + child = *(struct Moby **)(data + 0xac); + if (child != 0 && (signed char)child->state >= 0) + FUN_L00_00263ac8(child, 0, data + 0xd0, 2.7f); + FUN_L12_002eb220(moby); + if (D_001413F4 == 2) { + moby->scale = moby->pclass->scale * 0.5f; + child = *(struct Moby **)(data + 0xac); + if (child != 0) child->scale = child->pclass->scale * 0.5f; + } else { + moby->scale = moby->pclass->scale; + child = *(struct Moby **)(data + 0xac); + if (child != 0) child->scale = child->pclass->scale; + } + if ((unsigned int)(moby->state - 2) < 4) { + if (*(int *)(data + 0xb0) == -1) + *(int *)(data + 0xb0) = allocate_voice_for_target_entry_e9f68(3, 4, (int)moby); + } else { + index = *(int *)(data + 0xb0); + if (index != -1 && ((Voice_e9f68 *)(D_0013E550 + index * 0x70))->moby == moby && ((Voice_e9f68 *)(D_0013E550 + index * 0x70))->active) + release_voice(index); + *(int *)(data + 0xb0) = -1; + } + index = *(int *)(data + 0xc0); + if (current_level_index == 12 && D_L12_00161F00 != 0) { + if (index == 0) { + if (D_L12_00167100.moby == moby) D_L12_00167100.moby = 0; + if (!moby->visible) { + if (*(struct Moby **)(data + 0xac)) { + mark_moby_for_removal(*(struct Moby **)(data + 0xac)); + *(struct Moby **)(data + 0xac) = 0; + } + goto remove; + } + index = *(int *)(data + 0xc0); + goto check_mode; + } + } else { +check_mode: + if (index == 0) goto update_state; + } + if (D_0014C050[current_level_index * 16 + moby->mission] == 255) { + if (*(struct Moby **)(data + 0xac)) { + mark_moby_for_removal(*(struct Moby **)(data + 0xac)); + *(struct Moby **)(data + 0xac) = 0; + } + goto remove; + } + if (index == 0) goto update_state; + if (D_L12_001619A0 != 0) { + if (*(struct Moby **)(data + 0xac)) { + FUN_L12_00308708(moby); + *(struct Moby **)(data + 0xac) = 0; + } + goto remove; + } +update_state: + switch (moby->state) { + case 0: + data[0x28] = 2; + *(float *)(data + 0x20) = 6.0f; + *(short *)(data + 0x24) = 6; + data[0x29] = 0; + *(float *)(data + 0x94) = 0.0f; + *(float *)(data + 0x98) = 0.0f; + *(float *)(data + 0x9c) = 0.0f; + moby->collision = 0; + moby->flags = (moby->flags | 0x41) & 0xefff; + FUN_L12_0027ba70(*(int *)(data + 0xa0)); + FUN_L12_0027ba70(*(int *)(data + 0xa0)); + FUN_L12_0027ba70(*(int *)(data + 0xa4)); + if (moby->draw_dist < 128) moby->draw_dist = 128; + if (*(struct Moby **)(data + 0xac) == 0) { + child = FUN_L12_00308670(moby); + *(struct Moby **)(data + 0xac) = child; + child->update_dist = 0; + (*(struct Moby **)(data + 0xac))->flags |= 0x41; + } + *(OvlQuad *)&moby->pos = *(OvlQuad *)(D_L12_001B0930[*(int *)(data + 0xa0)] + 0x10); + if (*(int *)(data + 0xc0) != 0 && *(int *)(data + 0xc4) == 0) { + a = scale_game_frames_alt(240); + b = scale_game_frames_alt(400); + *(int *)(data + 0xc4) = FUN_L00_00257b90(a, b); + limit = D_L12_00161F20 - 1; + if (limit > 10) limit = 10; + if (limit < 0) limit = 0; + *(int *)(data + 0xc4) += limit * scale_game_frames_alt(35); + } + *(int *)(data + 0xb4) = 0; + moby->state = 1; + break; + case 1: + triggered = 0; + if (*(int *)(data + 0xc0) && D_L12_00161F00) + triggered = tick_countdown_32_alt_c2((int *)(data + 0xc4)) != 0; + if ((*(int *)(data + 0x80) != -1 && is_point_inside_clip_volume(&hero.motion.pos, *(int *)(data + 0x80))) || triggered) { + data[0x58] = 22; data[0x59] = 1; data[0x5a] = 7; + moby->hit_slot = 255; + moby->flags &= 0xffbe; + child = *(struct Moby **)(data + 0xac); + if (child) child->flags &= 0xffbe; + moby->flags |= 0x1000; + moby->state = 2; + moby->collision = moby->pclass->collision; + } + break; + case 2: + if (*(int *)(data + 0xc0) == 0 && D_L12_00167100.moby == 0) { + D_L12_00167100.count = 0; + D_L12_00167100.moby = moby; + } + if (*(int *)(data + 0xc0)) { + count = *(short *)(data + 0x8c); + limit = D_L12_00161F20 - 3; + if (limit > 5) limit = 5; + if (limit < 0) limit = 0; + if (count < limit * scale_game_frames_alt(15)) + *(short *)(data + 0x8c) = limit * scale_game_frames_alt(15); + } + if (FUN_L12_002eaf68(moby, *(int *)(data + 0xa0))) moby->state = 3; + break; + case 3: + if (current_level_index == 12 && !D_0013D4CB && !D_00141C50) help_request(0x2ee2, 0x5d); + distance = FUN_001f9b80(&moby->pos, &hero.motion.pos); + if (*(int *)(data + 0xc0) == 0) { + if (!(distance < 21.0f) || !(moby->pos.z - hero.motion.pos.f[2] > 1.0f)) { + if (D_L12_00167100.moby == moby) D_L12_00167100.moby = 0; + } else if (D_L12_00167100.moby == 0) { + D_L12_00167100.count = 0; D_L12_00167100.moby = moby; + } + } + distance = FUN_001f9b80(&moby->pos, target); + if ((distance < 40.0f && moby->pos.z - target[2] > -2.0f) || *(int *)(data + 0xc0)) { + angle = FUN_001f9e90(target[0] - moby->pos.x, target[1] - moby->pos.y); + moby->rot.z = spring_turn((float *)(data + 0x88), moby->rot.z, angle, 0.004f, 0.3f, frame_time * 0.7853982f); + value = FUN_001f9b80(target, &moby->pos); + angle = FUN_001f9e90(value, moby->pos.z - target[2]); + moby->rot.y = spring_turn((float *)(data + 0x9c), moby->rot.y, angle, 0.004f, 0.3f, frame_time * 0.7853982f); + clear_u64_value(data + 0x70); + FUN_L12_002eae00(moby); + if (FUN_001f9770(data + 0x8c)) { + ++*(short *)(data + 0xbc); + moby_point_position(moby, *(int *)(data + 0xb8), &position); + *(int *)(data + 0xb8) = *(int *)(data + 0xb8) == 0; + aim.q = *(OvlQuad *)(target + 8); + if (*(int *)(data + 0xc0)) { + aim.q = *(OvlQuad *)D_L12_00167240; + aim.f[2] += random_float_between(-0.5f, 0.1f); + aim.f[0] += FUN_L00_00257c48(0.0f, 0.4f); + } + subtract_vector_xyz_c3(&delta, &aim, &position); + if (*(int *)(data + 0xc0)) fast_vec_normalize(&delta, &delta, frame_time * 22.0f); + else fast_vec_normalize(&delta, &delta, frame_time * 15.0f); + count = 24; + angle = FUN_001f9e90(delta.f[0], delta.f[1]); + spread = 1.3f; + a = scale_game_frames_alt(130); + FUN_L12_002ecce8(&delta, &position, (int)moby, a, angle, frame_time * 15.0f, 0.0f); + allocate_voice_for_target_entry_e9f68(0, 0, (int)moby); + fast_vec_normalize(&delta, &delta, 0.5f); + fast_vec_add(&position, &position, &delta); + value = frame_time; + do { + --count; + velocity.f[0] = FUN_L00_00257c48(0.0f, value * spread); + velocity.f[1] = FUN_L00_00257c48(0.0f, frame_time * spread); + velocity.f[2] = FUN_L00_00257c48(0.0f, frame_time * spread); + color = FUN_L00_00257b90(170, 240); + b = FUN_L00_00257b90(110, 180); + color = (b << 8) | color | 0x7f000000; + a = FUN_L00_00257b90(30, 70); + life = scale_game_frames_alt(a); + size = FUN_L00_00257b90(120, 170); + FUN_L00_00269958(&position, &velocity, color, 255, life, 30, size, 1); + value = frame_time; + } while (count >= 0); + limit = 4; + if (*(int *)(data + 0xc0)) { + if (D_L12_00161F20 > 10) limit = 2; + if (D_L12_00161F20 > 6) limit = 3; + } + if (*(short *)(data + 0xbc) < limit || *(int *)(data + 0xa4) == -1) + *(short *)(data + 0x8c) = scale_game_frames_alt(40); + else { *(short *)(data + 0xbc) = 0; moby->state = 4; } + } + } + break; + case 4: + angle = FUN_001f9e90(target[0] - moby->pos.x, target[1] - moby->pos.y); + moby->rot.z = spring_turn((float *)(data + 0x88), moby->rot.z, angle, 0.004f, 0.3f, frame_time * 0.7853982f); + { + char *path = D_L12_001B0930[*(int *)(data + 0xa4)]; + if (*(short *)(data + 0xbe) != 0) subtract_vector_xyz_c3(&position, path + 16, &moby->pos); + else subtract_vector_xyz_c3(&position, path + *(int *)path * 16, &moby->pos); + } + distance = vector_length_xyz_c3(&position); + if (!(distance > 5.5f)) { + approach_value(data + 0x94, 0.0f, frame_time_sq * 9.0f); + if (*(float *)(data + 0x94) == 0.0f) { + *(short *)(data + 0x8c) = scale_game_frames_alt(50); + *(short *)(data + 0xbe) = *(short *)(data + 0xbe) == 0; + moby->state = 3; + break; + } + } else approach_value(data + 0x94, frame_time * 10.0f, frame_time_sq * 7.0f); + fast_vec_normalize(data + 0x70, &position, *(float *)(data + 0x94)); + fast_vec_add(&moby->pos, &moby->pos, data + 0x70); + FUN_L12_002eae00(moby); + break; + case 5: + if (!FUN_001f9770(data + 0x8e)) { + value = *(float *)(data + 0x94) - frame_time_sq * 4.0f; + *(float *)(data + 0x94) = value; + if (value < 0.0f) *(float *)(data + 0x94) = 0.0f; + position.f[0] = fast_cos_c(moby->rot.z); + position.f[0] *= -*(float *)(data + 0x94); + position.f[1] = fast_sin_c2(moby->rot.z); + position.f[2] = 0.0f; + position.f[1] *= -*(float *)(data + 0x94); + fast_vec_add(&moby->pos, &moby->pos, &position); + } else moby->state = moby->command; + break; + case 6: + if (D_L12_00167100.moby == moby) D_L12_00167100.moby = 0; + if (*(struct Moby **)(data + 0xac)) { + FUN_L12_00308708(moby); + *(struct Moby **)(data + 0xac) = 0; + } + FUN_L00_0025e450(moby, D_L12_0015F580, &moby->pos, 0.0f, 0.0f, 20, 3, 4, 4.0f, 2.0f, 100000.0f, 2, 3.0f, 15.0f, 1, 1, -1, 0); + if (*(int *)(data + 0xc0) == 0) FUN_L00_00257470(moby, 0, -1); + index = *(int *)(data + 0xb0); + if (index != -1 && ((Voice_e9f68 *)(D_0013E550 + index * 0x70))->moby == moby && ((Voice_e9f68 *)(D_0013E550 + index * 0x70))->active) release_voice(index); + *(int *)(data + 0xb0) = -1; + if (*(int *)(data + 0xc0) == 0) { +remove: + mark_moby_for_removal(moby); + return; + } + a = scale_game_frames_alt(240); + b = scale_game_frames_alt(400); + *(int *)(data + 0xc4) = FUN_L00_00257b90(a, b); + moby->collision = 0; + moby->state = 0; + moby->flags = (moby->flags | 0x41) & 0xefff; + break; + } + moby->pos.z -= fast_cos_c(*(float *)(data + 0x90)) * 0.17f; + a = scale_game_frames_alt(120); + angle = fast_add_rotations_c3(*(float *)(data + 0x90), 6.2831855f / (float)a); + *(float *)(data + 0x90) = angle; + moby->pos.z += fast_cos_c(angle) * 0.17f; + child = *(struct Moby **)(data + 0xac); + if (child) { + *(OvlQuad *)&child->pos = *(OvlQuad *)&moby->pos; + child = *(struct Moby **)(data + 0xac); + *(OvlQuad *)&child->rot = *(OvlQuad *)&moby->rot; + advance_moby_animation(*(struct Moby **)(data + 0xac)); + FUN_L00_00250df8_x(*(struct Moby **)(data + 0xac)); + (*(struct Moby **)(data + 0xac))->flags |= 6; + } + if (*(int *)(data + 0xc0) == 0 && moby->state > 1 && moby->visible && distance_xyz(&moby->pos, D_L12_00167240) < 30.0f) { + FUN_L00_0025a120((char *)moby); + moby->shadow_range = 24; + } +} +#endif /* Springs the moby's two rotation angles toward a heading taken from its data's direction vector. */ /* Ported from rac1-decomp (src/overlays/l12_hoven/vendor_002C0310.c: func_L12_002EC180), where it is exact; names translated to the US level program. */ From 1aa8f1188a21047bec16b75df814a2438e71cec1 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:41:42 +0000 Subject: [PATCH 117/251] decomp: improve sceGsSetDefDispEnv --- .../sdk/dma/sce_gs_set_def_disp_env.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c index b3581f6a3..28af3929a 100644 --- a/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c +++ b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c @@ -73,12 +73,12 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s } else { scale = width + 0x9ff; scale /= width; - scaled_horizontal = horizontal_offset * scale; - value = ((u64)(s64)(height - 1) << 44) | - ((u64)(s64)(scale - 1) << 23) | - ((u64)(((s64)scaled_horizontal + (s64)(((u32)kernel_horizontal + 0x27cU) & 0xfffU)) & 0xfff)) | + scaled_horizontal = scale * horizontal_offset; + value = ((u64)(s64)(scale - 1) << 23) | ((u64)((s64)(scale * width) - 1) << 32) | - ((u64)((vertical_offset + kernel_vertical + 0x19) & 0xfff) << 12); + ((u64)(((s64)scaled_horizontal + (s64)(((u32)kernel_horizontal + 0x27cU) & 0xfffU)) & 0xfff)) | + ((u64)((vertical_offset + kernel_vertical + 0x19) & 0xfff) << 12) | + ((u64)(s64)(height - 1) << 44); } output->display = value; } else if ((s16)mode == 3) { @@ -98,12 +98,12 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s } else { scale = width + 0x9ff; scale /= width; - scaled_horizontal = horizontal_offset * scale; - value = ((u64)(s64)(height - 1) << 44) | - ((u64)(s64)(scale - 1) << 23) | - ((u64)(((s64)scaled_horizontal + (s64)(((u32)kernel_horizontal + 0x290U) & 0xfffU)) & 0xfff)) | + scaled_horizontal = scale * horizontal_offset; + value = ((u64)(s64)(scale - 1) << 23) | ((u64)((s64)(scale * width) - 1) << 32) | - ((u64)((vertical_offset + kernel_vertical + 0x24) & 0xfff) << 12); + ((u64)(((s64)scaled_horizontal + (s64)(((u32)kernel_horizontal + 0x290U) & 0xfffU)) & 0xfff)) | + ((u64)((vertical_offset + kernel_vertical + 0x24) & 0xfff) << 12) | + ((u64)(s64)(height - 1) << 44); } output->display = value; } else if ((s16)mode == 0x50) { From bb6a7299758cc58c3506775c62d1d131eacd19c1 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:42:27 +0000 Subject: [PATCH 118/251] decomp: improve FUN_L06_002f9a28 --- src/overlays/l06/gameplay/entities/002b4770.c | 241 ++++++++++++++++++ 1 file changed, 241 insertions(+) diff --git a/src/overlays/l06/gameplay/entities/002b4770.c b/src/overlays/l06/gameplay/entities/002b4770.c index 6f77b9ff6..b395a936b 100644 --- a/src/overlays/l06/gameplay/entities/002b4770.c +++ b/src/overlays/l06/gameplay/entities/002b4770.c @@ -1904,7 +1904,248 @@ void FUN_L06_002f91e8(Moby *moby) data->f160 = D_001413D0[0]; } } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L06_002f9a28.s", FUN_L06_002f9a28); +#else +extern void FUN_L06_002fa9c0(char *); +extern void FUN_L06_002fbc88(struct Moby *); +extern void FUN_L00_00263ac8(float, void *, int, void *); +extern void FUN_L00_0025a120(void *); +extern int queue_animation_update(int, int, void *, void *, void *, void *, int) __asm__("FUN_001ff308"); +extern void FUN_L00_00235d80(void); +extern void FUN_L00_00235ea0(void); +extern void FUN_L06_00249738(void); +extern int FUN_001fa6d0(float); +extern float absolute_float(float) __asm__("FUN_001f99c0"); +extern void FUN_L06_002fb4b0_high(char *) __asm__("FUN_L06_002fb870"); +extern void FUN_L06_002fb4b0_low(char *) __asm__("FUN_L06_002fbc30"); +extern int FUN_L06_002fb668_low(char *) __asm__("FUN_L06_002fba28"); +extern void FUN_00212f90(void *, int, int, int); +extern float FUN_00213308(void); +extern void mark_moby_for_removal(struct Moby *); +extern float FUN_0020c9e0(void *); +extern void FUN_L00_0024f7c8(void *, int, void *); +extern void FUN_L00_001f2868(float, void *, int, void *, void *); +extern float approach_value_c(float, float, float *); +extern float approach_angle(float *, float, float *, float, float, float) __asm__("FUN_L00_0025be00"); +extern void FUN_L00_00261d78(float, int, void *, void *); +extern int FUN_L01_0026e008(int, int); +extern int FUN_L06_002e9ea0(int); +extern void FUN_L00_0025f3e8(void *, void *, int, float, float); +extern void FUN_L00_00263e30(void *, int, int, int, int, int, int); +extern void FUN_L00_00263d40(int, int); +extern void allocate_voice_for_bank_entry(int, int, int) __asm__("FUN_0022db10"); +extern void FUN_L06_00316330(void *); +extern int *D_L06_001B0C30[]; +extern int D_L06_00161EF0 __attribute__((sda)); +extern float D_L06_00161EF4 __attribute__((sda)); +extern float D_L06_00161EFC __attribute__((sda)); +extern float D_L06_00161F00 __attribute__((sda)); +extern float D_L06_00161F04 __attribute__((sda)); +extern float D_L06_00161F08 __attribute__((sda)); +extern unsigned char D_0013D3AB; +extern unsigned char D_0013D505 __attribute__((section(".data"))); +extern unsigned char D_0013D412 __attribute__((section(".data"))); +extern char D_L06_001678D0[]; +extern int D_L06_0016A010[]; +extern int D_L06_0015F5C4; +typedef unsigned int CirclerQuad __attribute__((mode(TI))); + +/* Sixteen-state update; copies retain the fourth position component. */ +void FUN_L06_002f9a28(unsigned char *moby) { + float v[4] __attribute__((aligned(16))); + struct { float direction[4]; char *owner; int flags; int pad; float scale; int enabled; } hit; + float pos[4] __attribute__((aligned(16))); + char *data = *(char **)(moby + 0x78); + char *focus; + char *target; + float distance, angle, acceleration; + int *path; + int i, out; + FUN_L06_002fa9c0(moby); + focus = *(char **)(data + 0xb0); + FUN_L00_00263ac8(1.9f, moby, D_L06_00161EF0, data + 0x130); + if ((unsigned char)moby[0x31] != 0) { + if (FUN_001f9b48(moby + 0x10, D_L06_00167540) < 45.0f) { + FUN_L00_0025a120(moby); + moby[0x7f] = 0x24; + } + } + if ((unsigned int)((unsigned char)moby[0x20] - 3) < 11) + *(int *)(data + 0x10c) = queue_animation_update(22, 65535, FUN_L00_00235d80, FUN_L00_00235ea0, FUN_L06_00249738, data + 0x110, 495); + switch ((unsigned char)moby[0x20]) { + case 0: + *(float *)(data + 0x20) = 30.0f; + data[0x28] = 3; data[0x2e] = 1; data[0x29] = 1; + *(short *)(data + 0x24) = 30; + data[0x58] = FUN_001fa6d0(14.0f); + data[0x5a] = FUN_001fa6d0(18.4f); + *(int *)(data + 0x120) = scale_game_frames_alt(1200); + *(int *)(data + 0x178) = 0; + *(CirclerQuad *)(data + 0xc0) = *(CirclerQuad *)(moby + 0x10); + *(int *)(data + 0x10c) = -1; + path = D_L06_001B0C30[*(int *)(data + 0xec)]; + *(int *)(data + 0x114) = *path; + path = D_L06_001B0C30[*(int *)(data + 0xec)]; + FUN_001f9a40(data + 0xd0, path + 4, path + (*path / 2) * 4 + 4, 0.5f); + *(float *)(data + 0xdc) = FUN_001f9b80(data + 0xc0, data + 0xd0); + *(float *)(data + 0x128) = FUN_00213308(); + *(int *)(data + 0x12c) = scale_game_frames_alt(30); + *(int *)(moby + 0x94) = 0; + *(unsigned short *)(moby + 0x34) = (*(unsigned short *)(moby + 0x34) | 0x4001) & 0xefff; + *(float *)(moby + 0x18) += 17.5f; + FUN_L06_002f9948(*(int *)(data + 0xf4)); + if (D_0013D3AB == 0 || D_0013D505 != 0) moby[0x20] = 1; + else mark_moby_for_removal((struct Moby *)moby); + return; + case 1: + if (*(int *)(data + 0xb4) == 2 || *(short *)(focus + 0xa6) != 0) return; + if (*(int *)(data + 0x170) == 0) { + *(int *)(data + 0x170) = 1; + *(int *)(data + 0x12c) = scale_game_frames_alt(10); + } else if (*(int *)(data + 0x12c) == 0) { + FUN_L06_002f53e8(D_L06_0015FFD8 + (*(int *)(data + 0xfc) << 8)); + FUN_L06_002f53e8(D_L06_0015FFD8 + (*(int *)(data + 0x100) << 8)); + FUN_L06_002d9e08(*(int *)(data + 0x104)); + *(int *)(data + 0x170) = 0; moby[0x20] = 2; + out = *(int *)(*(char **)(moby + 0x24) + 0x10); + *(unsigned short *)(moby + 0x34) = (*(unsigned short *)(moby + 0x34) | 0x1000) & 0xfffe; + *(int *)(moby + 0x94) = out; + if ((unsigned char)moby[0x53] != 8) FUN_00212f90(moby, 8, 0, scale_game_frames_alt(1)); + FUN_L06_002fb148(moby); + } + return; + case 2: + acceleration = frame_time_sq * 30.0f; + *(float *)(moby + 0x18) += *(float *)(data + 0x48); + *(float *)(data + 0x48) -= acceleration; + if ((unsigned char)moby[0x53] == 8) { + if (absolute_float((*(float *)(moby + 0x18) - *(float *)(data + 0xc8)) / *(float *)(data + 0x48)) <= 6.0f && (unsigned char)moby[0x53] != 9) + FUN_00212f90(moby, 9, 0, scale_game_frames_alt(5)); + } else { + if (*(float *)(moby + 0x18) < *(float *)(data + 0xc8)) *(float *)(moby + 0x18) = *(float *)(data + 0xc8); + if (*(float *)(moby + 0x54) == 0.0f && ((unsigned char)moby[0x70] & 2)) { + if ((unsigned char)moby[0x53] == 9) FUN_00212f90(moby, 6, 0, scale_game_frames_alt(30)); + else if ((unsigned char)moby[0x53] != 1) FUN_00212f90(moby, 1, 0, scale_game_frames_alt(30)); + } + } + if (FUN_L06_002fb2a8(moby)) { moby[0x20] = 7; FUN_L06_002fb4b0(moby); } + return; + case 3: + if ((unsigned char)moby[0x53] == 6 && *(float *)(moby + 0x54) == 0.0f && ((unsigned char)moby[0x70] & 2)) { + FUN_00212f90(moby, 1, 0, scale_game_frames_alt(20)); FUN_L06_002fb090(moby); + } + if (FUN_L06_002fb668(moby)) { moby[0x20] = 4; FUN_L06_002fb4b0_high(moby); } + return; + case 5: + if ((unsigned char)moby[0x53] == 6 && *(float *)(moby + 0x54) == 0.0f && ((unsigned char)moby[0x70] & 2)) { + FUN_00212f90(moby, 1, 0, scale_game_frames_alt(20)); FUN_L06_002f99b0(*(int *)(data + 0xf4)); + } + if (FUN_L06_002fb668_low(moby)) { moby[0x20] = 6; FUN_L06_002fb4b0_low(moby); } + return; + case 4: FUN_L06_002fb090(moby); + case 6: + FUN_L06_002fbc88((struct Moby *)moby); + if ((unsigned char)moby[0x20] != 4 || !FUN_L06_002e9ea0(*(int *)(data + 0xf0))) { + if ((unsigned char)moby[0x20] != 6 || FUN_L01_0026e008(*(int *)(data + 0xf4), -1)) return; + } + moby[0x20] = 8; *(int *)(data + 0x120) = scale_game_frames_alt(1200); + if ((unsigned char)moby[0x53] != 3) FUN_00212f90(moby, 3, 0, scale_game_frames_alt(20)); return; + case 7: + if (*(int *)(data + 0xb4) == 2) return; + moby[0x20] = 8; if ((unsigned char)moby[0x53] != 3) FUN_00212f90(moby, 3, 0, scale_game_frames_alt(20)); return; + case 8: + target = moby + 0x10; + distance = FUN_001f9b80(target, focus + 0x10); + angle = fast_difference_between_rotations(*(float *)(moby + 0x48), FUN_001f9e90(*(float *)(focus + 0x10) - *(float *)(moby + 0x10), *(float *)(focus + 0x14) - *(float *)(moby + 0x14))); + approach_angle((float *)(moby + 0x48), FUN_001f9e90(*(float *)(focus + 0x10) - *(float *)(moby + 0x10), *(float *)(focus + 0x14) - *(float *)(moby + 0x14)), (float *)(data + 0xe0), frame_time_sq * 6.2831855f, frame_time_sq * 6.2831855f, frame_time * 3.1415927f); + if (angle < 0.7853982f && D_L06_00161F00 < distance) approach_value_c(D_L06_00161EF4 * frame_time, D_L06_00161EFC * frame_time_sq, (float *)(data + 0xe8)); + else if (distance < D_L06_00161F04) approach_value_c(-(D_L06_00161EF4 * frame_time), D_L06_00161EFC * frame_time_sq, (float *)(data + 0xe8)); + else approach_value_c(0.0f, frame_time_sq * 8.0f, (float *)(data + 0xe8)); + FUN_001f9a28(v, focus + 0x10, target); v[2] = 0.0f; + FUN_001f9bf8(v, v, *(float *)(data + 0xe8)); FUN_001f9a10(target, target, v); + FUN_L00_00261d78(1.0f, *(int *)(data + 0xec), target, target); + if (*(int *)(data + 0xb4) == 2) { moby[0x20] = 13; return; } + if (fast_dec_timer(data + 0x120)) { *(int *)(data + 0x120) = scale_game_frames_alt(360); moby[0x20] = 12; return; } + if (!(distance < D_L06_00161F00) || !(angle < D_L06_00161F08 * 0.017453292f)) return; + moby[0x20] = 9; moby[0xbc] = 7; if ((unsigned char)moby[0x53] != 4) FUN_00212f90(moby, 4, 0, scale_game_frames_alt(20)); return; + case 12: + FUN_L06_002fbc88((struct Moby *)moby); + if (!fast_dec_timer(data + 0x120)) return; + *(int *)(data + 0x120) = scale_game_frames_alt(1200); + moby[0xbc] = 7; moby[0x20] = 11; if ((unsigned char)moby[0x53] != 6) FUN_00212f90(moby, 6, 0, scale_game_frames_alt(20)); return; + case 9: + fast_dec_timer(data + 0x120); + approach_angle((float *)(moby + 0x48), *(float *)(moby + 0x48), (float *)(data + 0xe0), frame_time_sq * 6.2831855f, frame_time_sq * 6.2831855f, frame_time * 3.1415927f); + if (!((unsigned char)moby[0x70] & 2)) return; + moby[0x20] = 10; if ((unsigned char)moby[0x53] != 5) FUN_00212f90(moby, 5, 0, scale_game_frames_alt(20)); return; + case 10: + fast_dec_timer(data + 0x120); + if (1.0f < FUN_0020c9e0(moby) && FUN_0020c9e0(moby) < 8.0f) { + v[0] = FUN_001f9dc8(*(float *)(moby + 0x48)) * 0.45f; + v[1] = FUN_001f9de0(*(float *)(moby + 0x48)) * 0.45f; + v[2] = 0.0f; + hit.owner = moby; hit.flags = 1; hit.scale = 1.0f; hit.enabled = 1; + hit.direction[0] = FUN_001f9dc8(*(float *)(moby + 0x48)); + hit.direction[1] = FUN_001f9de0(*(float *)(moby + 0x48)); hit.direction[2] = 0.0f; + FUN_L00_0024f7c8(moby, 0, pos); FUN_L00_001f2868(0.5f, pos, 0, moby, &hit); + FUN_L00_0024f7c8(moby, 1, pos); FUN_L00_001f2868(0.5f, pos, 0, moby, &hit); + FUN_L00_0024f7c8(moby, 2, pos); FUN_L00_001f2868(0.5f, pos, 0, moby, &hit); + FUN_L00_0024f7c8(moby, 3, pos); FUN_L00_001f2868(0.5f, pos, 0, moby, &hit); + FUN_L00_0024f7c8(moby, 4, pos); FUN_L00_001f2868(0.5f, pos, 0, moby, &hit); + FUN_L00_0024f7c8(moby, 5, pos); FUN_L00_001f2868(1.1f, pos, 0, moby, &hit); + FUN_L00_0024f7c8(moby, 6, pos); FUN_L00_001f2868(1.1f, pos, 0, moby, &hit); + + return; + } + case 11: + if (!((unsigned char)moby[0x70] & 2)) return; + moby[0x20] = moby[0xbc]; if ((unsigned char)moby[0x53] != 1) FUN_00212f90(moby, 1, 0, scale_game_frames_alt(20)); return; + case 13: + target = moby + 0x10; + distance = FUN_001f9b80(target, data + 0xc0); + angle = fast_difference_between_rotations(*(float *)(moby + 0x48), FUN_001f9e90(*(float *)(data + 0xc0) - *(float *)(moby + 0x10), *(float *)(data + 0xc4) - *(float *)(moby + 0x14))); + approach_angle((float *)(moby + 0x48), FUN_001f9e90(*(float *)(data + 0xc0) - *(float *)(moby + 0x10), *(float *)(data + 0xc4) - *(float *)(moby + 0x14)), (float *)(data + 0xe0), frame_time_sq * 6.2831855f, frame_time_sq * 6.2831855f, frame_time * 3.1415927f); + if (angle < 0.7853982f) { + FUN_001f9a28(v, data + 0xc0, target); v[2] = 0.0f; + FUN_001f9bf8(v, v, D_L06_00161EF4 * frame_time); FUN_001f9a10(target, target, v); + FUN_L00_00261d78(1.0f, *(int *)(data + 0xec), target, target); + } + if (*(int *)(data + 0xb4) != 2) { moby[0x20] = 7; return; } + if (!(distance < 1.0f)) return; + moby[0x20] = 7; if ((unsigned char)moby[0x53] != 1) FUN_00212f90(moby, 1, 0, scale_game_frames_alt(20)); return; + case 14: + D_0013D3AB = 1; *(int *)(data + 0x110) = 0; moby[0x30] = 0xff; + if ((unsigned char)data[0x2e] == 2) { + FUN_L06_002f5360(D_L06_0015FFD8 + (*(int *)(data + 0x100) << 8)); + FUN_L06_002d9e78(*(int *)(data + 0x104)); + moby[0x20] = 15; *(unsigned short *)(moby + 0x34) |= 1; + moby[0x31] = 0; *(int *)(moby + 0x94) = 0; if ((unsigned char)moby[0x53] != 1) FUN_00212f90(moby, 1, 0, scale_game_frames_alt(20)); return; + } + if (!((unsigned char)moby[0x70] & 2)) return; + *(CirclerQuad *)v = *(CirclerQuad *)(moby + 0x10); v[2] += 1.0f; + FUN_L00_0025f3e8(moby, v, -1, 2.0f, 20.0f); + FUN_L00_00263e30(moby, 0x6a2, 1, 0x6a3, 3, 6, 2); + FUN_L06_002f5360(D_L06_0015FFD8 + (*(int *)(data + 0x100) << 8)); + FUN_L06_002d9e78(*(int *)(data + 0x104)); moby[0x20] = 15; + if ((unsigned char)moby[0x53] != 1) FUN_00212f90(moby, 1, 0, scale_game_frames_alt(20)); + *(int *)(moby + 0x94) = 0; moby[0x31] = 0; *(unsigned short *)(moby + 0x34) |= 1; + if (*(int *)(data + 0x178) != 0 || D_0013D412 != 0) return; + D_0013D412 = 1; allocate_voice_for_bank_entry(1, 0, 0); FUN_L00_00263d40(0x53d6, -1); return; + case 15: + target = D_L06_001678D0; path = D_L06_0016A010; + for (i = 0; i < 48; i++) { + if (*path != 0 && *(short *)(target + 0x86) == 18) { FUN_L06_00316330(target); break; } + target += 0xa0; path++; + } + if (D_L06_0015F5C4 == 2) { + FUN_L06_002f5360(D_L06_0015FFD8 + (*(int *)(data + 0xfc) << 8)); mark_moby_for_removal((struct Moby *)moby); + } + return; + } + return; +} +#endif extern int FUN_001fa6d0(float); extern char *FUN_L00_0025a420(void *, int, int); extern int FUN_00213928(void *, void *, void *, int, int *, float *, int, int); From 12a8640ebe49085781038e555b701087dca67e38 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:42:09 +0000 Subject: [PATCH 119/251] decomp: improve FUN_L01_002edca0 --- .../shared/gameplay/entities/002b8c08.c | 57 +++++++++++-------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b8c08.c b/src/overlays/shared/gameplay/entities/002b8c08.c index 134802df0..0b7c34299 100644 --- a/src/overlays/shared/gameplay/entities/002b8c08.c +++ b/src/overlays/shared/gameplay/entities/002b8c08.c @@ -1419,8 +1419,8 @@ extern float D_0015ED70 __attribute__((section(".sdata"))); extern float D_0013F420[4]; extern float D_L01_0015F580[] __attribute__((section(".sdata"))); -extern char D_L01_00161A40[16] __attribute__((section(".sdata"))); -extern char D_L01_00161A50[16] __attribute__((section(".sdata"))); +extern char D_L01_00161A40 __attribute__((sda)); +extern char D_L01_00161A50 __attribute__((sda)); extern float D_L01_001619AC __attribute__((sda)); void FUN_L01_002edca0(unsigned char *moby) { @@ -1469,15 +1469,15 @@ void FUN_L01_002edca0(unsigned char *moby) { *(float *)(data + 0x30) = *(float *)(data + 0x250); *(float *)(data + 0x254) = FUN_00213308(); if (*(short *)(moby + 0xa6) == 0x362) - *(void **)(data + 0x130) = D_L01_00161A50; + *(void **)(data + 0x130) = &D_L01_00161A50; else - *(void **)(data + 0x130) = D_L01_00161A40; + *(void **)(data + 0x130) = &D_L01_00161A40; data[0x29] = 1; - if (*(int *)(data + 0x258) == 0) { - *(float *)(data + 0x20) = 3.0f; - } else { + if (*(int *)(data + 0x258) != 0) { *(float *)(data + 0x20) = 1.0f; *(int *)(data + 0x230) = 1; + } else { + *(float *)(data + 0x20) = 3.0f; } if (*(float *)(data + 0x224) == 0.0f) *(float *)(data + 0x224) = 15.0f; @@ -1485,19 +1485,21 @@ void FUN_L01_002edca0(unsigned char *moby) { *(float *)(data + 0x17c) = 2.0f; *(float *)(data + 0x178) = 2.0f; result = FUN_001fa6d0(*(float *)(data + 0x250) * 0.8f * 1024.0f); - distance = *(float *)(data + 0x23c) * D_0015ED6C; + angle = *(float *)(data + 0x23c) * D_0015ED6C; *(int *)(data + 0x170) = result; - *(float *)(data + 0x194) = distance; + *(float *)(data + 0x194) = angle; if (*(int *)(data + 0x230) != 0) { moby[0x20] = 1; *(u16 *)(moby + 0x34) |= 0x1000; } else { - moby[0x20] = *(int *)(data + 0x25c) == -1 ? 12 : 13; + if (*(int *)(data + 0x25c) == -1) moby[0x20] = 12; + else moby[0x20] = 13; *(int *)(moby + 0x94) = 0; *(int *)(moby + 0x58) = 0; moby[0x31] = 0; - *(float *)(moby + 0x18) -= 20.0f; + distance = *(float *)(moby + 0x18) - 20.0f; *(u16 *)(moby + 0x34) = (*(u16 *)(moby + 0x34) & 0xefff) | 1; + *(float *)(moby + 0x18) = distance; } break; case 1: @@ -1547,8 +1549,10 @@ void FUN_L01_002edca0(unsigned char *moby) { if (moby[0x53] != 0) FUN_00212f90(moby, 0, 0, FUN_001f96f8(10)); FUN_001f99f8(data + 0x40); - *(float *)(data + 0x234) = FUN_002132a8(-0.34906584f, 0.34906584f); - *(float *)(data + 0x194) = *(float *)(data + 0x23c) * D_0015ED6C; + angle = FUN_002132a8(-0.34906584f, 0.34906584f); + distance = *(float *)(data + 0x23c) * D_0015ED6C; + *(float *)(data + 0x234) = angle; + *(float *)(data + 0x194) = distance; } else { *(int *)(data + 0x204) = 2; } @@ -1592,7 +1596,8 @@ void FUN_L01_002edca0(unsigned char *moby) { if (moby[0x53] != 1) FUN_00212f90(moby, 1, 0, FUN_001f96f8(20)); return; - case 4: + case 4: { + unsigned char path_hit; target_position = target + 0x10; distance = FUN_001f9b80(moby + 0x10, target_position); if (distance < D_L01_001619AC) { @@ -1627,6 +1632,7 @@ void FUN_L01_002edca0(unsigned char *moby) { FUN_L01_002ef560(moby); return; } + } case 6: { float *rotation = (float *)(moby + 0x48); angle = FUN_001f9e90(*(float *)(target + 0x10) - *(float *)(moby + 0x10), @@ -1670,21 +1676,21 @@ void FUN_L01_002edca0(unsigned char *moby) { if (moby[0x53] != 1) FUN_00212f90(moby, 1, 0, FUN_001f96f8(10)); return; - case 5: + case 5: { target_position = data + 0x210; distance = FUN_001f9b80(moby + 0x10, target_position); - path_hit = 0; + blocked = 0; if (distance < 1.0f) { moby[0x20] = 1; } else { if (FUN_L01_00276fe8((int *)(data + 0x240), 1, *(int *)(data + 0x244), *(float *)(data + 0x250) * 0.8f, moby + 0x10, target_position, hit) != 0) - path_hit = 1; + blocked = 1; else - path_hit = FUN_L01_00276fe8((int *)(data + 0x240), 1, *(int *)(data + 0x244), + blocked = FUN_L01_00276fe8((int *)(data + 0x240), 1, *(int *)(data + 0x244), 0.0f, target_position, target_position, hit) != 0; } - if (path_hit != 0) { + if (blocked != 0) { angle = FUN_001f9e90(hit[0] - *(float *)(moby + 0x10), hit[1] - *(float *)(moby + 0x14)); angle = FUN_001fa580(angle, *(float *)(data + 0x234)); FUN_L00_0025be00((float *)(moby + 0x48), (float *)(data + 0x220), angle, @@ -1701,12 +1707,13 @@ void FUN_L01_002edca0(unsigned char *moby) { FUN_00212f90(moby, 1, 0, FUN_001f96f8(3)); FUN_L01_002ef560(moby); return; + } case 8: result = FUN_L00_0025c698(moby, data + 0x60); if (result & 1) { path_hit = FUN_L01_00276fe8((int *)(data + 0x240), 1, *(int *)(data + 0x244), *(float *)(data + 0x250) * 0.8f, - moby + 0x10, data + 0x210, hit); + moby + 0x10, data + 0x210, move); if (path_hit != 0) { FUN_0022da68(4, 0, (char *)moby); *(float *)(data + 0x194) = *(float *)(data + 0x23c) * D_0015ED6C; @@ -1729,21 +1736,23 @@ void FUN_L01_002edca0(unsigned char *moby) { if (moby[0x53] != 1) FUN_00212f90(moby, 1, 0, FUN_001f96f8(10)); FUN_001f99f8(data + 0x40); - *(float *)(data + 0x234) = FUN_002132a8(-0.34906584f, 0.34906584f); - *(float *)(data + 0x194) = *(float *)(data + 0x23c) * D_0015ED6C; + angle = FUN_002132a8(-0.34906584f, 0.34906584f); + distance = *(float *)(data + 0x23c) * D_0015ED6C; + *(float *)(data + 0x234) = angle; + *(float *)(data + 0x194) = distance; } break; case 13: *(u16 *)(moby + 0x34) |= 1; if (FUN_00214720(D_0013F420, *(int *)(data + 0x25c)) != 0) { - u16 flags = *(u16 *)(moby + 0x34); + u16 flags = *(u16 *)(moby + 0x34) | 0x1000; moby[0x20] = 1; *(u16 *)(moby + 0x34) = flags | 0x1000; *(float *)(moby + 0x58) = 1.0f; *(float *)(moby + 0x18) += 20.0f; moby[0x31] = 1; *(int *)(moby + 0x94) = *(int *)(*(char **)(moby + 0x24) + 0x10); - *(u16 *)(moby + 0x34) = (flags & 0xfffe) | 0x1000; + *(u16 *)(moby + 0x34) = flags & 0xfffe; } return; case 14: From e150dcf54bb4dfa656e2196d7f74923f51ed1d36 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:56:40 +0000 Subject: [PATCH 120/251] decomp: improve FUN_L00_002be650 --- .../shared/gameplay/entities/002b94d0.c | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b94d0.c b/src/overlays/shared/gameplay/entities/002b94d0.c index f9feaf8d5..3284c99e8 100644 --- a/src/overlays/shared/gameplay/entities/002b94d0.c +++ b/src/overlays/shared/gameplay/entities/002b94d0.c @@ -1913,10 +1913,12 @@ void FUN_L00_002be650(void *o) { OvlVec4 axis; OvlVec4 negativeUp; OvlVec4 vertex[2]; - volatile int color; - OvlVec4 * volatile vertexTarget; + struct { + volatile int color; + OvlVec4 * volatile vertexTarget; + int nextIndex; + } state; int i, j; - int nextIndex; (void)o; quad.tex = tex_2be650(8); @@ -1938,19 +1940,19 @@ void FUN_L00_002be650(void *o) { else c = D_L00_00161760; i = 0; - color = c & 0xFFFFFF; + state.color = c & 0xFFFFFF; } - vertexTarget = &vertex[0]; + state.vertexTarget = &vertex[0]; do { - nextIndex = i + 1; + state.nextIndex = i + 1; if (((int *)&D_L00_00161818)[i] != 0) { unsigned int c = color_alpha_2be650(((float *)&D_L00_001617E8)[i]); - c = (c << 24) | color; + c = (c << 24) | state.color; quad.color[3] = c; quad.color[2] = c; quad.color[1] = c; quad.color[0] = c; - qcopy(vertexTarget, &((u128 *)&D_L00_001DD0A0)[i]); + qcopy(state.vertexTarget, &((u128 *)&D_L00_001DD0A0)[i]); qcopy(&scaled, &((u128 *)&D_L00_001DD0D0)[i]); vmul_2be650(-1.0f, &negativeUp, &D_0013F5E0_2be650); cross_2be650(&axis, &scaled, &negativeUp); @@ -1962,7 +1964,7 @@ void FUN_L00_002be650(void *o) { } draw_2be650(&quad, 0, 0); } - i = nextIndex; + i = state.nextIndex; } while (i < 3); } #endif From e52d0c73c28b8b7b24f6978e03110fbd8002ef1f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:59:01 +0000 Subject: [PATCH 121/251] decomp: improve FUN_L00_00257218 --- src/overlays/shared/rendering/00250df8.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/rendering/00250df8.c b/src/overlays/shared/rendering/00250df8.c index 5b3f37d5f..affc3e2dd 100644 --- a/src/overlays/shared/rendering/00250df8.c +++ b/src/overlays/shared/rendering/00250df8.c @@ -73,7 +73,7 @@ int FUN_L00_00257218(u8 *m, s32 *item) { if (scan_index < 0) break; } } - selected_item = D_0015EDD0_257218[i] & 0x3F; + selected_item = *(D_0015EDD0_257218 + i); } else { selected_item = 10; if (available != 0) { @@ -93,10 +93,10 @@ int FUN_L00_00257218(u8 *m, s32 *item) { selected_item = D_0015EDD0_257218[i] & 0x3F; } } - *item = selected_item; + *item = selected_item & 0x3F; } - choice = 2; - if (random_integer_below(5) != 0) choice = 1; + choice = random_integer_below(5); + choice = 1 + (choice == 0); return choice; } #endif From c9e7b9c56e5ca02bb2c2fafc7234c653571934a0 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:43:21 +0000 Subject: [PATCH 122/251] decomp: improve FUN_L06_002e8678 --- .../shared/gameplay/entities/00297d10.c | 347 ++++++++++++++++++ 1 file changed, 347 insertions(+) diff --git a/src/overlays/shared/gameplay/entities/00297d10.c b/src/overlays/shared/gameplay/entities/00297d10.c index 31e800440..8c85a7942 100644 --- a/src/overlays/shared/gameplay/entities/00297d10.c +++ b/src/overlays/shared/gameplay/entities/00297d10.c @@ -346,7 +346,354 @@ void FUN_L06_002e6148(char *moby) { *(unsigned short *)(moby + 0x34) &= 0xFFBE; FUN_L00_002d6bf0(moby); } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L06_002e8678.s", FUN_L06_002e8678); +#else +#include "rnc/gameplay/entities/moby.h" +extern int *D_L06_001B0C30[]; +extern void FUN_L06_002e9f30(struct Moby *); +extern float fast_add_rotations_e94f0(float, float) __asm__("FUN_001fa580"); +extern float FUN_001f9e90(float, float); +extern char D_L06_00167540[]; +extern int D_L06_00161C10 __attribute__((sda)); +extern int D_L06_00161C14 __attribute__((sda)); +extern int D_L06_0015FDF8 __attribute__((sda)); +extern int D_L06_0015F5C4; +extern char D_L06_00161BF0 __attribute__((sda)); +extern float D_0015ED70; +extern int D_001413D4 __attribute__((section(".data"))); +extern char D_0013F3D0[]; +extern float D_L06_00174600[]; +extern float FUN_001f9b48(void *, void *); +extern float FUN_001f9b80(void *, void *); +extern float vector_length_xy(void *) __asm__("FUN_001f9b20"); +extern void FUN_001f9a00(void *); +extern void add_vector_xyz(void *, void *, void *) __asm__("FUN_001f9a10"); +extern void FUN_001f9cf8(void *, void *, void *); +extern void FUN_001f9bf8(void *, void *, float); +extern int truncate_float_to_s32(float) __asm__("FUN_001fa6d0"); +extern int tick_countdown_32(int *) __asm__("FUN_001f9740"); +extern int random_integer_below(int) __asm__("FUN_00213260"); +extern void blend_moby_animation(void *, int, int, int) __asm__("FUN_00212f90"); +extern struct Moby *create_moby(int) __asm__("FUN_0020c4f8"); +extern float compute_interpolated_record_value(void *) __asm__("FUN_0020c9e0"); +extern float probe_ground_height(void *, int, float) __asm__("FUN_00213508"); +extern void FUN_L00_00257470(void *, int, int); +extern void FUN_L00_0025a120(void *); +extern void FUN_L00_002599e8(void *, int, int, float, float, float, int, int, int); +extern float FUN_L00_0025abf0(void *, void *, void *, float, float); +extern void FUN_L00_0025c558(void *, void *, int, int, int, float); +extern int FUN_L00_0025c698(void *, void *); +extern int FUN_L00_00261b48(int, void *, void *, void *); +extern void FUN_L00_00263ac8(void *, int, void *, float); +extern int FUN_L00_002dc9f0(void *, void *); +extern void FUN_L06_002e94f0(struct Moby *); +extern void FUN_L06_002e9998(char *, float *, float *); +extern void FUN_L06_002e9aa8(char *); +extern void FUN_L06_002e9b60(float, float, char *, float *, int); + +#define E8678_SHORT(off) (*(short *)(vars + (off))) +#define E8678_INT(off) (*(int *)(vars + (off))) +#define E8678_FLOAT(off) (*(float *)(vars + (off))) + +/* The checked level-06 state machine; the catalogue name is shared with level 10. */ +void FUN_L06_002e8678(struct Moby *moby) { + unsigned char *vars = moby->pvars; + struct Moby *target; + struct Moby *carried; + float direction[4] __attribute__((aligned(16))); + float pos[4] __attribute__((aligned(16))); + float displacement[4] __attribute__((aligned(16))); + float intersection[4] __attribute__((aligned(16))); + float f, angle, speed; + int *path; + int divisor; + int flags, blocked, animation, frames, state; + + if (D_L06_00161C10 != 0) return; + if (D_L06_0015F5C4 == 2 && ((moby->flags ^ 1) & 1)) { + E8678_SHORT(0x1ea) = 1; + moby->flags |= 0x41; + } else if (D_L06_0015F5C4 == 0 && E8678_SHORT(0x1ea) != 0) { + E8678_SHORT(0x1ea) = 0; + moby->flags &= 0xffbe; + } + if (moby->state != 16) { + if (D_L06_0015FDF8 != 0) { + if (E8678_SHORT(0x242) == 0) return; + } else if (E8678_SHORT(0x242) != 0) return; + } + FUN_L00_00263ac8(moby, 1, vars + 0x250, 2.1f); + FUN_L06_002e94f0(moby); + if (moby->visible != 0 && FUN_001f9b48(&moby->pos, D_L06_00167540) < 14.0f) { + FUN_L00_0025a120(moby); + moby->shadow_range = 11; + } + target = (*(struct Moby **)(vars + 0x1c0)); + switch (moby->state) { + case 0: { + float frame_scale; + divisor = E8678_SHORT(0x240); + flags = D_L06_00161C14; + E8678_SHORT(0x20a) = flags % 8; + D_L06_00161C14 = flags + 1; + if (divisor != 0) moby->unkB4 /= divisor; + moby->flags |= 0x100; + vars[0x58] = truncate_float_to_s32(8.0f); + vars[0x5a] = truncate_float_to_s32(3.2f); + qcopy((vars + 0x210), &moby->pos); + qcopy((vars + 0x230), &moby->pos); + qcopy((vars + 0x220), &moby->rot); + E8678_SHORT(0x208) = 0; + f = random_float_between(0.5f, 3.0f); + frame_scale = D_0015ED70; + E8678_INT(0x148) = 0; + E8678_INT(0x134) = 0; + E8678_INT(0x140) = 0x200; + E8678_FLOAT(0x244) = f; + E8678_FLOAT(0x130) = frame_scale * 20.0f; + E8678_FLOAT(0x248) = random_angle_radians(); + *(void **)(vars + 0xd0) = &D_L06_00161BF0; + vars[0x29] = 1; + if (E8678_SHORT(0x200) != 0) { + moby->state = 1; + (*(struct Moby **)(vars + 0x20c)) = create_moby(500); + carried = (*(struct Moby **)(vars + 0x20c)); + if (carried == 0) goto remove; + carried->spawn_frame = moby->spawn_frame; + (*(struct Moby **)(vars + 0x20c))->flags |= 0x4002; + carried = (*(struct Moby **)(vars + 0x20c)); + qcopy(&carried->pos, &moby->pos); + qcopy(&carried->rot, &moby->rot); + carried->draw_dist = 0x40; + (*(struct Moby **)(vars + 0x20c))->visible = 1; + FUN_L00_00250df8((*(struct Moby **)(vars + 0x20c))); + moby->flags |= 0x41; + return; + } + if (E8678_SHORT(0x202) != 0) { + moby->state = 15; + moby->collision = 0; + moby->flags = (moby->flags | 0x41) & 0xefff; + return; + } + if (E8678_INT(0x1f8) >= 0) { + moby->state = 3; + if (moby->prev_seq != 0) blend_moby_animation(moby, 0, 0, 0); + return; + } + moby->state = 8; + if (moby->prev_seq == 4) return; + flags = random_integer_below(*((unsigned char *)moby->pclass->seqs[4] + 0x10)); + blend_moby_animation(moby, 4, flags, 0); + return; + } + case 1: + if (!(FUN_001f9b80(&moby->pos, &target->pos) < 4.0f)) return; + moby->flags &= 0xffbe; + FUN_L06_002e9f30(moby); + moby->state = 8; + if (moby->prev_seq == 4) return; + frames = 5; + break; + case 3: + subtract_vector_xyz(direction, &target->pos, &moby->pos); + FUN_L06_002e9aa8((char *)moby); + FUN_L06_002e9998((char *)moby, D_L06_00174600, direction); + if (!(FUN_001f9b80(D_0013F3D0, &moby->pos) < E8678_FLOAT(0x24c))) return; + moby->state = 4; + if (moby->prev_seq == 4) return; + frames = 5; + break; + case 4: + path = D_L06_001B0C30[E8678_INT(0x1f8)]; + qcopy(pos, (path + E8678_SHORT(0x208) * 4 + 4)); + subtract_vector_xyz(direction, pos, &moby->pos); + FUN_L06_002e9aa8((char *)moby); + FUN_L06_002e9998((char *)moby, D_L06_00174600, direction); + FUN_001f9bf8(displacement, &moby->rot_row0, E8678_FLOAT(0x1e4) * D_0015ED6C); + FUN_L06_002e9b60(0.3f, 0.3f, (char *)moby, displacement, 0); + FUN_001f9cf8(direction, direction, &moby->rot_row0); + if (!(vector_length_xy(direction) < 0.5f)) return; + path = D_L06_001B0C30[E8678_INT(0x1f8)]; + if (E8678_SHORT(0x208) < *path - 2) { + E8678_SHORT(0x208)++; + return; + } + qcopy((vars + 0x210), (path + *path * 4)); + qcopy((vars + 0x230), (vars + 0x210)); + f = FUN_001f9b80(&moby->pos, vars + 0x210); + f /= (float)FUN_001f96f8(30); + E8678_FLOAT(0x138) = f; + E8678_FLOAT(0x13c) = FUN_L00_0025abf0(&moby->pos, vars + 0x210, 0, f, -E8678_FLOAT(0x130)); + vars[0x15d] = 3; + E8678_INT(0x144) = 5; + angle = FUN_001f9e90(E8678_FLOAT(0x210) - moby->pos.x, E8678_FLOAT(0x214) - moby->pos.y); + FUN_L00_0025c558(moby, vars + 0x120, 2, 1, 0, angle); + moby->state = 5; + return; + case 5: + FUN_001f9a00(direction); + FUN_L06_002e9998((char *)moby, direction, (float *)(vars + 0x120)); + flags = FUN_L00_0025c698(moby, vars + 0x120); + if (!(flags & 1)) return; + goto landed; + case 6: + flags = FUN_L00_0025c698(moby, vars + 0x120); + if (flags & 1) { +landed: + moby->state = 7; + if (moby->prev_seq != 3) blend_moby_animation(moby, 3, 0, 1); + moby->anim_time = 1.0f; + moby->pos.z = probe_ground_height(&moby->pos, 0, 0.5f); + return; + } + if (!(flags & 0x120)) return; + FUN_L00_00257470(moby, 0, -1); +remove: + mark_moby_for_removal(moby); + return; + case 7: + if (!(moby->anim_flags & 2)) return; + moby->state = 8; + if (moby->prev_seq == 4) return; + frames = 5; + break; + case 8: + if (moby->visible != 0) { + if (FUN_001f9b48(&moby->pos, vars + 0x230) < 0.05f || tick_countdown_32((int *)(vars + 0x1fc))) { + angle = random_angle_radians(); + speed = random_float_between(0.5f, 2.0f); + direction[0] = fast_cos(angle) * speed; + direction[1] = fast_sin(angle) * speed; + direction[2] = 0; + add_vector_xyz(vars + 0x230, vars + 0x210, direction); + E8678_INT(0x1fc) = FUN_001f96f8(truncate_float_to_s32(random_float_between(45.0f, 75.0f))); + } + subtract_vector_xyz(displacement, vars + 0x230, &moby->pos); + FUN_L06_002e9aa8((char *)moby); + FUN_L06_002e9998((char *)moby, D_L06_00174600, displacement); + FUN_001f9bf8(pos, &moby->rot_row0, E8678_FLOAT(0x1e4) * D_0015ED6C); + FUN_L06_002e9b60(0.3f, 0.3f, (char *)moby, pos, 1); + } + if (E8678_INT(0x1c4) == 2 || random_integer_below(9) != 0) { + if (E8678_SHORT(0x1e8) == 0) return; + f = random_float_between(-E8678_FLOAT(0x1d8), E8678_FLOAT(0x1d8)); + state = 10; + } else { + f = random_float_between(-E8678_FLOAT(0x1d8), E8678_FLOAT(0x1d8)); + state = 9; + } + E8678_FLOAT(0x1d4) = f * 0.017453292f; + moby->state = state; + if (moby->prev_seq != 4) blend_moby_animation(moby, 4, 0, 0); + return; + case 9: + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + angle = fast_add_rotations_e94f0(angle, E8678_FLOAT(0x1d4)); + pos[0] = fast_cos(angle); + pos[1] = fast_sin(angle); + pos[2] = 0; + FUN_L06_002e9aa8((char *)moby); + FUN_L06_002e9998((char *)moby, D_L06_00174600, pos); + FUN_001f9bf8(direction, &moby->rot_row0, E8678_FLOAT(0x1e4) * D_0015ED6C); + FUN_L06_002e9b60(0.3f, 0.3f, (char *)moby, direction, 1); + if (FUN_001f9b80(&moby->pos, &target->pos) < 2.0f) { + moby->state = 12; + if (moby->prev_seq != 5) blend_moby_animation(moby, 5, 4, FUN_001f96f8(10)); + return; + } + if (E8678_INT(0x1c4) == 2) moby->state = 13; + return; + case 10: + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + angle = fast_add_rotations_e94f0(angle, E8678_FLOAT(0x1d4)); + qcopy(displacement, &moby->pos); + pos[0] = fast_cos(angle); + pos[1] = fast_sin(angle); + pos[2] = 0; + blocked = 0; + FUN_L06_002e9aa8((char *)moby); + FUN_L06_002e9998((char *)moby, D_L06_00174600, pos); + FUN_001f9bf8(direction, &moby->rot_row0, E8678_FLOAT(0x1e4) * D_0015ED6C); + FUN_L06_002e9b60(0.3f, 0.3f, (char *)moby, direction, 1); + if (FUN_L00_00261b48(E8678_INT(0x1ec), &moby->pos, &target->pos, intersection) != 0 && + FUN_001f9b48(&moby->pos, intersection) < E8678_FLOAT(0x244)) blocked = 1; + if (E8678_SHORT(0x1e8) == 0) { + moby->state = 13; + return; + } + if (blocked) { + moby->state = 11; + if (moby->prev_seq == 6) return; + animation = 6; + frames = FUN_001f96f8(10); + } else { + if (!(FUN_001f9b80(&moby->pos, &target->pos) < 2.0f)) return; + moby->state = 12; + if (moby->prev_seq == 5) return; + animation = 5; + frames = FUN_001f96f8(10); + } + blend_moby_animation(moby, animation, 0, frames); + return; + case 11: + if (!(moby->anim_flags & 2)) return; + moby->state = 10; + if (moby->prev_seq == 4) return; + frames = 20; + break; + case 12: { + float f; + pos[0] = fast_cos(FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y)); + pos[1] = fast_sin(FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y)); + pos[2] = 0; + FUN_L06_002e9998((char *)moby, (float *)&moby->rot_row2, pos); + f = compute_interpolated_record_value(moby); + if (moby->seq == moby->prev_seq && 10.0f <= f && f <= 15.0f && D_001413D4 != 0x51) { + FUN_001f9bf8(direction, &moby->rot_row0, (E8678_FLOAT(0x1e4) + E8678_FLOAT(0x1e4)) * D_0015ED6C); + FUN_L06_002e9b60(0.3f, 0.3f, (char *)moby, direction, 1); + FUN_L00_002599e8(moby, 0, 1, 0.333f, 1.0f, 1.0f, 0, 1, 0); + return; + } + if (!(moby->anim_flags & 2)) return; + if (!(2.0f < FUN_001f9b80(&moby->pos, &target->pos))) return; + moby->state = 9; + if (moby->prev_seq == 4) return; + frames = 10; + break; + } + case 13: + subtract_vector_xyz(pos, vars + 0x210, &moby->pos); + FUN_L06_002e9aa8((char *)moby); + FUN_L06_002e9998((char *)moby, D_L06_00174600, pos); + FUN_001f9bf8(direction, &moby->rot_row0, E8678_FLOAT(0x1e4) * D_0015ED6C); + FUN_L06_002e9b60(0.3f, 0.3f, (char *)moby, direction, 1); + if (!(FUN_001f9b80(&moby->pos, vars + 0x210) < 2.0f)) { + if (E8678_INT(0x1c4) != 2) moby->state = 9; + else if (E8678_SHORT(0x1e8) != 0) moby->state = 10; + return; + } + moby->state = 8; + if (moby->prev_seq == 4) return; + frames = 10; + break; + case 16: + if (FUN_L00_002dc9f0(moby, vars + 0x120) != 0) { + moby->state = 8; + if (moby->prev_seq != 0) blend_moby_animation(moby, 0, 0, FUN_001f96f8(10)); + E8678_SHORT(0xc8) = 0; + } + return; + default: + return; + } + blend_moby_animation(moby, 4, 0, FUN_001f96f8(frames)); +} +#undef E8678_SHORT +#undef E8678_INT +#undef E8678_FLOAT +#endif #include "rnc/gameplay/entities/moby.h" struct MobyHit { From 03a44229990af753e8890189d26158603ffed493 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:44:03 +0000 Subject: [PATCH 123/251] decomp: improve FUN_L13_00307e98 --- src/overlays/l13/gameplay/vendor/003058a8.c | 287 ++++++++++++++++++++ 1 file changed, 287 insertions(+) diff --git a/src/overlays/l13/gameplay/vendor/003058a8.c b/src/overlays/l13/gameplay/vendor/003058a8.c index ab327dd42..1f240a581 100644 --- a/src/overlays/l13/gameplay/vendor/003058a8.c +++ b/src/overlays/l13/gameplay/vendor/003058a8.c @@ -589,7 +589,294 @@ void FUN_L13_00307b10(struct Moby *moby) { break; } } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L13_00307e98.s", FUN_L13_00307e98); +#else +extern void FUN_L13_00308d10(struct Moby *); +extern void FUN_L13_00309370(struct Moby *); +extern void FUN_L00_00263ac8(void *, int, void *, float); +extern void FUN_L00_0025a120(struct Moby *); +extern void FUN_L01_0026d930(void *); +extern float FUN_L00_0025be00(float *, float *, float, float, float, float); +extern void FUN_L00_00258278(struct Moby *, float *, float, float, float, float); +extern int FUN_L00_00258b50(void *, void *, void *, void *, float); +extern void FUN_L00_00259d08(void *, void *, void *, void *, void *, void *, int); +extern int FUN_L00_00261b48(int, void *, void *, void *); +extern void FUN_L00_00261d78(int, void *, void *, float); +extern int FUN_L00_0025c698(struct Moby *, void *); +extern void FUN_00212f90(struct Moby *, int, int, int); +extern float FUN_0020c9e0(struct Moby *); +extern float fast_vec_dist(void *, void *) __asm__("FUN_001f9b48"); +extern float FUN_001f9e90(float, float); +extern float FUN_001fa688(float, float); +extern float fast_add_rotations(float, float) __asm__("FUN_001fa580"); +extern float fast_cos(float) __asm__("func_001F9DC8"); +extern float fast_sin(float) __asm__("func_001F9DE0"); +extern float FUN_001fa6c0(int); +extern int FUN_001fa6d0(float); +extern int FUN_001f9740(int *); +extern int scale_game_frames(int) __asm__("func_001F96F8"); +extern float random_float_between(float, float) __asm__("FUN_002132a8"); +extern void FUN_001160d8(void); +extern float D_0015ED70; +extern float D_L13_00161E58 __attribute__((sda)); +extern int D_L13_00161E70 __attribute__((sda)); +extern float D_L13_00161E74 __attribute__((sda)); +extern float D_L13_00161E78 __attribute__((sda)); +extern char D_L13_001670C0[]; + +/* State update; raw offsets retain the retail interpretations of shared pvars. */ +void FUN_L13_00307e98(struct Moby *moby) { + char *data = (char *)moby->pvars; + struct Moby *target; + OvlVec4 next, pos, direction; + struct { + OvlVec4 vector; + float unk10, unk14; + unsigned char active, valid; + unsigned short oclass; + char pad1C[0x14]; + } __attribute__((aligned(16))) hit; + float angle, distance; + float *rotation; + void *anim; + int flags, value; + + FUN_L13_00308d10(moby); + target = *(struct Moby **)(data + 0x160); + FUN_L00_00263ac8(moby, 1, data + 0x400, 2.5f); + if (moby->visible && fast_vec_dist(&moby->pos, D_L13_001670C0) < 28.0f) { + FUN_L00_0025a120(moby); + moby->shadow_range = 0x16; + } + switch (moby->state) { + case 0: + *(float *)(data + 0x20) = 2.0f; + data[0x28] = 1; + data[0x58] = 12; + data[0x5a] = 8; + *(short *)(data + 0x24) = 2; + *(float *)(data + 0x30) = 1.5f; + FUN_L01_0026d930(data + 0xc0); + angle = D_L13_00161E58 * 716.8f; + *(float *)(data + 0xc8) = 2.0f; + *(float *)(data + 0xcc) = 0.5f; + value = FUN_001fa6d0(angle); + *(float *)(data + 0xc4) = D_L13_00161E58 * 0.7f; + *(int *)(data + 0xc0) = value; + distance = random_float_between(0.95f, 1.05f); + *(float *)(data + 0xe4) = D_L13_00161E78 * D_0015ED6C * distance; + qcopy(data + 0x170, &moby->pos); + moby_point_position(moby, 0, data + 0x1e0); + moby->state = 1; + break; + case 1: + rotation = &moby->rot.z; + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + FUN_L00_0025be00(rotation, (float *)(data + 0x188), angle, + D_0015ED70 * 6.2831855f, D_0015ED70 * 6.2831855f, D_0015ED6C * 3.1415927f); + if (*(int *)(data + 0x164) != 2) { + distance = FUN_001f9b80(&moby->pos, &target->pos); + if (D_L13_00161E74 < distance) { + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + if (FUN_001fa688(moby->rot.z, angle) < 0.2617994f) { + moby->state = 2; if (moby->prev_seq != 3) FUN_00212f90(moby, 3, 0, scale_game_frames(10)); + } else { + moby->state = 7; if (moby->prev_seq != 1) FUN_00212f90(moby, 1, 0, scale_game_frames(20)); + } + } else { + moby->state = 5; if (moby->prev_seq != 6) FUN_00212f90(moby, 6, 0, scale_game_frames(10)); + } + return; + } else { + if (*(int *)(data + 0x184)) { + moby->state = 11; + if (moby->prev_seq != 1) FUN_00212f90(moby, 1, 0, scale_game_frames(20)); + return; + } + } + break; + case 2: + if (!(moby->anim_flags & 2)) return; + moby->state = 3; + FUN_L13_00309370(moby); + if (moby->prev_seq != 5) FUN_00212f90(moby, 5, 0, scale_game_frames(10)); + return; + case 3: + if (!(moby->anim_flags & 2)) return; + distance = FUN_001f9b80(&moby->pos, &target->pos); + if (*(int *)(data + 0x164) != 2 && distance < 15.0f) { + moby->state = 4; + if (moby->prev_seq != 4) + FUN_00212f90(moby, 4, 0, scale_game_frames(20)); + *(int *)(data + 0x194) = scale_game_frames(D_L13_00161E70); + return; + } + moby->state = 1; if (moby->prev_seq != 0) FUN_00212f90(moby, 0, 0, scale_game_frames(20)); + return; + case 4: + rotation = &moby->rot.z; + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + FUN_L00_0025be00(rotation, (float *)(data + 0x188), angle, + D_0015ED70 * 6.2831855f, D_0015ED70 * 6.2831855f, D_0015ED6C * 3.1415927f); + if (FUN_001f9740((int *)(data + 0x194))) { + moby->state = 3; + FUN_L13_00309370(moby); + if (moby->prev_seq != 5) FUN_00212f90(moby, 5, 0, scale_game_frames(5)); + return; + } + distance = FUN_001f9b80(&moby->pos, &target->pos); + if (distance < D_L13_00161E74) { + moby_point_position(moby, 0, data + 0x1e0); + moby->state = 5; if (moby->prev_seq != 6) FUN_00212f90(moby, 6, 0, scale_game_frames(10)); + return; + } else if (*(int *)(data + 0x184)) { + moby->state = 11; if (moby->prev_seq != 1) FUN_00212f90(moby, 1, 0, scale_game_frames(20)); + return; + } + break; + case 5: + rotation = &moby->rot.z; + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + FUN_L00_0025be00(rotation, (float *)(data + 0x188), angle, + D_0015ED70 * 6.2831855f, D_0015ED70 * 6.2831855f, D_0015ED6C * 3.1415927f); + moby_point_position(moby, 0, &next); + qcopy(&pos, &moby->pos); + pos.f[2] += 0.3f; + distance = FUN_0020c9e0(moby); + if (distance <= 15.0f && 9.0f <= distance) { + direction.f[0] = fast_cos(moby->rot.z); + direction.f[1] = fast_sin(moby->rot.z); + direction.f[3] = 5627.925f; + direction.f[2] = 1.0f; + FUN_L00_00259888(&hit, moby, 1, &direction, 1.0f); + hit.oclass = moby->oclass; hit.valid = 1; hit.active = 0; + FUN_L00_00259d08(&next, &pos, data + 0x1e0, &pos, moby, &hit, 5); + } + qcopy(data + 0x1e0, &next); + if (moby->anim_flags & 2) { + moby->state = 6; moby->command = 1; + if (moby->prev_seq != 2) FUN_00212f90(moby, 2, 0, scale_game_frames(10)); + return; + } + break; + case 6: + if (!(moby->anim_flags & 2)) return; + moby->state = moby->command; + if (moby->prev_seq != 0) FUN_00212f90(moby, 0, 0, scale_game_frames(20)); + return; + case 7: { + int blocked; + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + angle = fast_add_rotations(angle, *(float *)(data + 0x1a8)); + FUN_L00_00258278(moby, (float *)(data + 0x188), angle, 0.05f, 0.3f, D_0015ED6C * 6.2831855f); + next.f[0] = fast_cos(moby->rot.z); next.f[0] += next.f[0]; + next.f[1] = fast_sin(moby->rot.z); next.f[1] += next.f[1]; + next.i[2] = 0; + flags = FUN_L00_00258b50(moby, data + 0xc0, &next, &pos, 1.0f); + if (!(flags & 2)) *(float *)(data + 0x1a8) = 0.0f; + else { + FUN_001160d8(); + *(float *)(data + 0x1a8) = FUN_001fa6c0(-1) * 1.0995574f; + } + FUN_L00_00261d78(*(int *)(data + 0x198), &moby->pos, &moby->pos, 0.75f); + blocked = 0; + if (FUN_L00_00261b48(*(int *)(data + 0x198), &moby->pos, &target->pos, &direction) && + fast_vec_dist(&moby->pos, &direction) < 0.8f) blocked = 1; + distance = FUN_001f9b80(&moby->pos, &target->pos); + if (distance < 15.0f) { + moby->state = 2; if (moby->prev_seq != 3) FUN_00212f90(moby, 3, 0, scale_game_frames(10)); + return; + } else if (blocked) { + moby->state = 2; if (moby->prev_seq != 3) FUN_00212f90(moby, 3, 0, scale_game_frames(10)); + return; + } else if (distance < D_L13_00161E74) { + moby->state = 5; if (moby->prev_seq != 6) FUN_00212f90(moby, 6, 0, scale_game_frames(10)); + return; + } + break; + } + case 11: { + int blocked; + blocked = 0; + angle = FUN_001f9e90(target->pos.x - moby->pos.x, target->pos.y - moby->pos.y); + FUN_L00_00258278(moby, (float *)(data + 0x188), angle, 0.05f, 0.3f, D_0015ED6C * 6.2831855f); + next.f[0] = fast_cos(moby->rot.z); next.f[0] += next.f[0]; + next.f[1] = fast_sin(moby->rot.z); next.f[1] += next.f[1]; + next.i[2] = 0; + FUN_L00_00258b50(moby, data + 0xc0, &next, &pos, 1.0f); + FUN_L00_00261d78(*(int *)(data + 0x198), &moby->pos, &moby->pos, 0.75f); + if (FUN_L00_00261b48(*(int *)(data + 0x198), &moby->pos, &target->pos, &direction) && + fast_vec_dist(&moby->pos, &direction) < 0.8f) blocked = 1; + if (!*(int *)(data + 0x184)) moby->state = 13; + else if (blocked) { + moby->state = 12; if (moby->prev_seq != 6) FUN_00212f90(moby, 6, 0, scale_game_frames(10)); + return; + } else { + distance = FUN_001f9b80(&moby->pos, &target->pos); + if (distance < D_L13_00161E74) { + moby_point_position(moby, 0, data + 0x1e0); + moby->state = 12; if (moby->prev_seq != 6) FUN_00212f90(moby, 6, 0, scale_game_frames(10)); + return; + } + } + break; + } + case 12: + moby_point_position(moby, 0, &next); + qcopy(&pos, &moby->pos); + pos.f[2] += 1.5f; + distance = FUN_0020c9e0(moby); + if (distance <= 15.0f && 9.0f <= distance) { + direction.f[0] = fast_cos(moby->rot.z); + direction.f[1] = fast_sin(moby->rot.z); + direction.f[3] = 5627.925f; + direction.f[2] = 1.0f; + FUN_L00_00259888(&hit, moby, 1, &direction, 1.0f); + hit.oclass = moby->oclass; hit.valid = 1; hit.active = 0; + FUN_L00_00259d08(&next, &pos, data + 0x1e0, &pos, moby, &hit, 5); + } + qcopy(data + 0x1e0, &next); + if (moby->anim_flags & 2) { + moby->state = 11; if (moby->prev_seq != 1) FUN_00212f90(moby, 1, 0, scale_game_frames(20)); + return; + } + break; + case 13: + angle = FUN_001f9e90(*(float *)(data + 0x170) - moby->pos.x, *(float *)(data + 0x174) - moby->pos.y); + FUN_L00_00258278(moby, (float *)(data + 0x188), angle, 0.05f, 0.3f, D_0015ED6C * 6.2831855f); + next.f[0] = fast_cos(moby->rot.z); next.f[0] += next.f[0]; + next.f[1] = fast_sin(moby->rot.z); next.i[2] = 0; next.f[1] += next.f[1]; + angle = FUN_001f9e90(*(float *)(data + 0x170) - moby->pos.x, *(float *)(data + 0x174) - moby->pos.y); + if (FUN_001fa688(moby->rot.z, angle) < 0.7853982f) { + FUN_L00_00258b50(moby, data + 0xc0, &next, &pos, 1.0f); + FUN_L00_00261d78(*(int *)(data + 0x198), &moby->pos, &moby->pos, 0.75f); + } + if (!(fast_vec_dist(data + 0x170, &moby->pos) < 1.0f)) return; + moby->state = 1; if (moby->prev_seq != 0) FUN_00212f90(moby, 0, 0, scale_game_frames(20)); + return; + case 15: + anim = data + 0x60; + flags = FUN_L00_0025c698(moby, anim); + if (flags & 0x40) { + ((u64 *)anim)[0] = 0; + ((u64 *)anim)[1] = 0; + moby->state = 1; if (moby->prev_seq != 0) FUN_00212f90(moby, 0, 0, scale_game_frames(10)); + return; + } + if (flags & 0x120) mark_moby_for_removal(moby); + return; + case 16: + flags = FUN_L00_0025c698(moby, data + 0x60); + if (flags & 0x160) { + FUN_L00_0025e450(moby, data + 0x60, 0, 0.0f, 0.0f, 10, 3, 16, + 4.0f, 2.0f, 9.0f, 1.0f, -1, 15.0f, 1, 1, -1, 0); + mark_moby_for_removal(moby); + } + } + return; +} +#endif #include "rnc/overlay/collision.h" /* Vars of the level 13 walker FUN_L13_00308d10 drives. */ From 33932b1bf6f6c5725ce428dc7bb15bcc844ac484 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 17:59:05 +0000 Subject: [PATCH 124/251] decomp: improve FUN_L00_00261b48 --- src/overlays/shared/gameplay/state/00261968.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/gameplay/state/00261968.c b/src/overlays/shared/gameplay/state/00261968.c index 5de0b6beb..bdb660617 100644 --- a/src/overlays/shared/gameplay/state/00261968.c +++ b/src/overlays/shared/gameplay/state/00261968.c @@ -103,7 +103,6 @@ s32 FUN_L00_00261b48(s32 path_index, OvlVec4 *start, OvlVec4 *end, OvlVec4 *out) FUN_001ff2a8_261b48(&direction, end, start); direction.i[2] = 0; FUN_001ff500_261b48(&direction, &direction, 1.0f / FUN_001ff3d8_261b48(&direction)); - nearest = 1.0f; FUN_001ff260_261b48(&axis); axis.f[0] = direction.f[1]; axis.f[1] = -direction.f[0]; @@ -112,10 +111,11 @@ s32 FUN_L00_00261b48(s32 path_index, OvlVec4 *start, OvlVec4 *end, OvlVec4 *out) found = 0; i = 1; origin.f[2] = 1.0f; + nearest = origin.f[2]; current = &first; FUN_001ff2a8_261b48(current, &(*entry)->points[0], start); - FUN_001ff6d0_261b48(current, current, &direction); previous = current; + FUN_001ff6d0_261b48(current, current, &direction); current = &next; if (i < (*entry)->count) { offset = 0x20; @@ -124,14 +124,14 @@ s32 FUN_L00_00261b48(s32 path_index, OvlVec4 *start, OvlVec4 *end, OvlVec4 *out) FUN_001ff6d0_261b48(current, current, &direction); if (first.f[3] != 0.0f || current->f[3] != 0.0f) { if (current->f[1] * first.f[1] < 0.0f) { - crossing = (first.f[0] - current->f[0]) / (first.f[1] - current->f[1]) * -current->f[1] + current->f[0]; + crossing = (first.f[0] - next.f[0]) / (first.f[1] - current->f[1]) * -current->f[1] + next.f[0]; if (crossing > 0.0f && crossing < nearest) { nearest = crossing; found = 1; } } } - previous->q = ((volatile OvlVec4 *)current)->q; + qcopy(previous, current); i++; offset += 0x10; } while (i < (*entry)->count); From 0f7e57100cbc5d6a81df99cb991a680441ec424d Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:04:35 +0000 Subject: [PATCH 125/251] decomp: improve FUN_L01_00234358 --- src/overlays/shared/ui/help/00226f10.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/ui/help/00226f10.c b/src/overlays/shared/ui/help/00226f10.c index 6da558436..9c2704d40 100644 --- a/src/overlays/shared/ui/help/00226f10.c +++ b/src/overlays/shared/ui/help/00226f10.c @@ -1361,13 +1361,11 @@ void FUN_L01_00234358(float amount) { } else if (factor > 3.0f) { factor = 3.0f; } - /* Keep the lower clamp in the single-precision amount multiplication. */ - if (factor < min_factor) - amount *= min_factor; - else - amount *= factor; + if (!(factor < min_factor)) + min_factor = factor; velocity = &hero.motion.velocity; subtract_vector_xyz_34358(delta, delta, velocity); + amount *= min_factor; length = vector_length_xy_34358(delta); if (amount < length) FUN_001f9c48_34358(delta, delta, amount); From 3dc1693d4459e5c9864f15e7b9475a043e9c358b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:06:10 +0000 Subject: [PATCH 126/251] decomp: improve FUN_L00_002d5de8 --- .../shared/gameplay/entities/002cfcb8.c | 273 ++++++++++++++++++ 1 file changed, 273 insertions(+) diff --git a/src/overlays/shared/gameplay/entities/002cfcb8.c b/src/overlays/shared/gameplay/entities/002cfcb8.c index 3bbfda41b..7c91edeef 100644 --- a/src/overlays/shared/gameplay/entities/002cfcb8.c +++ b/src/overlays/shared/gameplay/entities/002cfcb8.c @@ -2576,7 +2576,280 @@ void FUN_L00_002d5988(Obj_2d5988 *o, Path_2d5988 *path, s32 p) { } } } +#ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L00_002d5de8.s", FUN_L00_002d5de8); +#else +extern u8 level_available[] __asm__("D_0013DD40"); +extern u8 *D_0015FFD8_2d3a10 __asm__("D_L00_0015FFD8") __attribute__((sda)); +extern u8 *D_L00_001600EC_2d5de8 __asm__("D_L00_001600EC") __attribute__((sda)); +extern s32 D_15F5C4_2d6cd0 __asm__("D_L00_0015F5C4"); +void mark_moby_for_removal() __asm__("FUN_0020c828"); +void FUN_L00_002d6bf0(); +void FUN_L00_002d6cd0(char *); +void FUN_L00_00266858(void *, s32); +void FUN_L00_002607d0(s32); +void FUN_L00_002502a0(s32); +void FUN_L00_00284e50(void *, void *); +void FUN_L00_00262d38(s32); +void FUN_L00_00298840_2d5de8(s32) __asm__("FUN_L00_00298840"); +void FUN_L00_00299460_2d5de8(s32) __asm__("FUN_L00_00299460"); +void FUN_0024d430_2d5de8(s32, s32) __asm__("FUN_0020b178"); +#define IV5(p, o) (*(s32 *)((u8 *)(p) + (o))) +#define FV5(p, o) (*(f32 *)((u8 *)(p) + (o))) + +/* Retail treats vars+0x5C/0x60/0xA4 and path segment lengths as floats. + * State 1 and out-of-range states still run the common attachment update. */ +void FUN_L00_002d5de8(struct Moby *m) { + Vec4_2d5988 offset, delta, point; + struct { s32 idx; f32 t[3]; } sample; + u8 *v; + u8 *path, *first, *second, *length, *other; + s32 i, j; + s32 *paths; + f32 radius, angle, d, speed, step, progress, x, y, timing; + offset.q = 0; + v = *(u8 **)((u8 *)m + 0x78); + switch (m->state) { + case 0: + ((u8 *)m)[0x30] = 0xff; + FV5(v, 0xac) = FV5(m, 0x48); + *(u128_2d5988 *)(v + 0xc0) = *(u128_2d5988 *)((u8 *)m + 0x10); + if (IV5(v, 0) != 0) { + m->state = 2; + FUN_L00_002d6bf0(m); + } else { + m->state = IV5(v, 0xb0) == 0 ? 1 : 2; + *(u16 *)((u8 *)m + 0x34) |= 0x41; + } + if (IV5(v, 0x50) != -1) { + m->state = 5; + FUN_L00_002d6bf0(m); + break; + } + i = 0; + if (IV5(v, 0x70) != -1) { + paths = (s32 *)(v + 0x70); + do { + if (paths[i] != -1) { + path = D_L00_001B04B0_2d0538[paths[i]]; + j = 0; + if (0 < IV5(path, 0) - 2) { + length = path + 0x1c; + second = path + 0x20; + first = path + 0x10; + do { + FV5(length, 0) = distance_xyz(first, second); + j++; + second += 16; length += 16; first += 16; + } while (j < IV5(path, 0) - 2); + } + } + i++; + } while (i < 8); + path = D_L00_001B04B0_2d0538[IV5(v, 0x70)]; + *(u128_2d5988 *)((u8 *)m + 0x10) = *(u128_2d5988 *)(path + 0x10); + IV5(v, 0xa8) = 0; + m->state = 3; + } + break; + case 2: + radius = 1.0f; + if (IV5(v, 0xb0) != 0 && (*(u16 *)((u8 *)m + 0x34) & 1)) radius = 3.0f; + if (IV5(v, 4) == 12) radius = 3.0f; + d = turn_f((f32 *)(v + 0x6c), FV5(m, 0x48), FV5(v, 0xac), 0.01f, 0.3f, 0.1f); + step = frame_time_sq; + speed = frame_time; + x = step * 1.0471976f; + y = step * 0.5235988f; + progress = speed * 0.7853982f; + FV5(m, 0x48) = d; + d = turn_f((f32 *)(v + 0x68), FV5(m, 0x44), 0.0f, y, x, progress); + step = frame_time_sq; + speed = frame_time; + x = step * 1.0471976f; + y = step * 2.0943952f; + progress = speed * 1.5707964f; + FV5(m, 0x44) = d; + FV5(m, 0x40) = turn_f((f32 *)(v + 0x64), FV5(m, 0x40), 0.0f, x, y, progress); + FUN_L00_002d6cd0((char *)m); + if (level_available[IV5(v, 4)]) goto remove; + if (distance_xyz(&hero.motion.pos, (u8 *)m + 0x10) < radius && hero.health.hp) m->state = 8; + break; + case 3: + FUN_L00_002d6cd0((char *)m); + if (level_available[IV5(v, 4)]) goto remove; + if (IV5(v, 0x70 + IV5(v, 0xa8) * 4) == -1) { + m->state = 2; + } else { + angle = angle_atan2(hero.motion.pos.f[0] - FV5(m, 0x10), hero.motion.pos.f[1] - FV5(m, 0x14)); + d = turn_f((f32 *)(v + 0x6c), FV5(m, 0x48), angle, 0.01f, 0.3f, 0.1f); + step = frame_time_sq; + speed = frame_time; + x = step * 1.0471976f; + y = step * 0.5235988f; + progress = speed * 0.7853982f; + FV5(m, 0x48) = d; + d = turn_f((f32 *)(v + 0x68), FV5(m, 0x44), 0.0f, y, x, progress); + step = frame_time_sq; + speed = frame_time; + x = step * 1.0471976f; + y = step * 2.0943952f; + progress = speed * 1.5707964f; + FV5(m, 0x44) = d; + FV5(m, 0x40) = turn_f((f32 *)(v + 0x64), FV5(m, 0x40), 0.0f, x, y, progress); + if (distance_xyz(&hero.motion.pos, (u8 *)m + 0x10) < 8.0f) { + m->state = 4; + FUN_L00_00266858(m, 1); + } + } + break; + case 4: + FUN_L00_002d5988((Obj_2d5988 *)m, (Path_2d5988 *)D_L00_001B04B0_2d0538[IV5(v, 0x70 + IV5(v, 0xa8) * 4)], 3); + FUN_L00_002d6cd0((char *)m); + if (m->state != 4) IV5(v, 0xa8)++; + break; + case 5: + FUN_L00_002d6cd0((char *)m); + if (level_available[IV5(v, 4)]) goto remove; + FV5(v, 0x5c) = FUN_001fa580_2d54c8(FV5(v, 0x5c), frame_time * 3.1415927f); + offset.f[0] = fast_cos(FV5(v, 0x5c)); + offset.f[1] = fast_sin(FV5(v, 0x5c)); + offset.f[2] = 3.0f; + FV5(m, 0x48) = FUN_001fa580_2d54c8(FV5(v, 0x5c), 1.5707964f); + if (IV5(v, 0x54) == -1) break; + other = D_0015FFD8_2d3a10 + IV5(v, 0x54) * 256; + if (*(s16 *)(other + 0xa6) != 0x336 || other[0xbc] != 6 || IV5(v, 0x58) == -1) break; + m->state = 6; + IV5(v, 0x50) = -1; + path = D_L00_001B04B0_2d0538[IV5(v, 0x58)]; + *(u128_2d5988 *)((u8 *)m + 0x10) = *(u128_2d5988 *)(path + 0x10); + path = D_L00_001B04B0_2d0538[IV5(v, 0x58)]; + FV5(m, 0x48) = angle_atan2(FV5(path, 0x20) - FV5(path, 0x10), FV5(path, 0x24) - FV5(path, 0x14)); + path = D_L00_001B04B0_2d0538[IV5(v, 0x58)]; + j = 0; + length = path + 0x1c; + if (0 < IV5(path, 0) - 2) { + second = path + 0x20; first = path + 0x10; + do { + FV5(length, 0) = distance_xyz(first, second); + j++; + second += 16; length += 16; first += 16; + } while (j < IV5(path, 0) - 2); + } + break; + case 6: { + u8 *path; + path = D_L00_001B04B0_2d0538[IV5(v, 0x58)]; + FUN_L00_002d6cd0((char *)m); + FUN_L00_0025df68_2d5988(path, (u8 *)m + 0x10, &point, &sample.idx, sample.t, 0, 999.0f, 5.0f, 0.0f); + progress = convert_integer_to_float(sample.idx) * FV5(path, 0x1c) + sample.t[0] + 2.0f; + d = distance_xyz((u8 *)m + 0x10, path + IV5(path, 0) * 16); + speed = FV5(v, 0x60); + step = frame_time_sq * 16.0f; + if (d <= (speed * speed) / (step + step)) { + FV5(v, 0x60) = speed - step; + if (speed - step < 0.0f) FV5(v, 0x60) = 0.0f; + } else { + FV5(v, 0x60) = speed + step; + if (frame_time * 16.0f < speed + step) FV5(v, 0x60) = frame_time * 16.0f; + } + sample.idx = truncate_float_to_s32(progress / FV5(path, 0x1c)); + sample.t[0] = (progress - convert_integer_to_float(sample.idx) * FV5(path, 0x1c)) / FV5(path, 0x1c); + if (sample.idx >= IV5(path, 0) - 1) { + if (FV5(v, 0x60) <= frame_time_sq * 16.0f) { + m->state = 7; + *(u128_2d5988 *)((u8 *)m + 0x10) = *(u128_2d5988 *)(path + IV5(path, 0) * 16); + break; + } + sample.idx = IV5(path, 0) - 2; + sample.t[0] = 1.0f; + } + subtract_vector_xyz(&point, path + sample.idx * 16 + 0x20, path + sample.idx * 16 + 0x10); + scale_vector_xyz(&point, &point, sample.t[0]); + add_vector_xyz(&point, &point, path + sample.idx * 16 + 0x10); + angle = angle_atan2(FV5(path, (sample.idx + 1) * 16 + 0x10) - FV5(path, sample.idx * 16 + 0x10), FV5(path, (sample.idx + 1) * 16 + 0x14) - FV5(path, sample.idx * 16 + 0x14)); + FV5(m, 0x48) = turn_f((f32 *)(v + 0x6c), FV5(m, 0x48), angle, 0.01f, 0.3f, 0.1f); + subtract_vector_xyz(&delta, &point, (u8 *)m + 0x10); + d = vector_length_xyz(&delta); + if (FV5(v, 0x60) < d) d = FV5(v, 0x60); + normalize_vector_xyz(&delta, &delta, d); + add_vector_xyz((u8 *)m + 0x10, (u8 *)m + 0x10, &delta); + angle = FUN_001fa5c8_2d5988(angle_atan2(delta.f[0], delta.f[1]), FV5(m, 0x48)); + x = (FV5(v, 0x60) * 0.34906584f * fast_cos(angle)) / (frame_time * 16.0f); + y = (FV5(v, 0x60) * -0.34906584f * fast_sin(angle)) / (frame_time * 16.0f); + FV5(m, 0x44) = turn_f((f32 *)(v + 0x68), FV5(m, 0x44), x, frame_time_sq * 0.5235988f, frame_time_sq * 1.0471976f, frame_time * 0.7853982f); + FV5(m, 0x40) = turn_f((f32 *)(v + 0x64), FV5(m, 0x40), y, frame_time_sq * 1.0471976f, frame_time_sq * 2.0943952f, frame_time * 1.5707964f); + break; + } + case 7: { + u8 *path; + path = D_L00_001B04B0_2d0538[IV5(v, 0x58)]; + FUN_L00_002d6cd0((char *)m); + FV5(v, 0xa4) += frame_time; + if (1.0f < FV5(v, 0xa4)) FV5(v, 0xa4) = 1.0f; + FV5(v, 0x5c) = FUN_001fa580_2d54c8(FV5(v, 0x5c), frame_time * 3.1415927f); + offset.f[0] = fast_cos(FV5(v, 0x5c)) * FV5(v, 0xa4); + offset.f[1] = fast_sin(FV5(v, 0x5c)) * FV5(v, 0xa4); + offset.f[2] = 0.0f; + angle = FUN_001fa580_2d54c8(FV5(v, 0x5c), 1.5707964f); + FV5(m, 0x48) = turn_f((f32 *)(v + 0x6c), FV5(m, 0x48), angle, frame_time * 25.132742f, frame_time * 25.132742f, frame_time * 12.566371f); + add_vector_xyz(&delta, &offset, path + IV5(path, 0) * 16); + *(u128_2d5988 *)((u8 *)m + 0x10) = delta.q; + d = distance_xyz(&hero.motion.pos, path + IV5(path, 0) * 16); + timing = frame_time_sq; + if (d < 2.0f && hero.health.hp) { + m->state = 8; + timing = frame_time_sq; + } + FV5(m, 0x44) = turn_f((f32 *)(v + 0x68), FV5(m, 0x44), 0.0f, timing * 0.5235988f, timing * 1.0471976f, frame_time * 0.7853982f); + FV5(m, 0x40) = turn_f((f32 *)(v + 0x64), FV5(m, 0x40), 0.0f, frame_time_sq * 1.0471976f, frame_time_sq * 2.0943952f, frame_time * 1.5707964f); + break; + } + case 8: + *(u16 *)((u8 *)m + 0x34) |= 0x41; + FUN_L00_002607d0(IV5(v, 4)); + FUN_L00_002502a0(((u8 *)m)[0xb0]); + if (IV5(v, 8) != -1) { + other = D_L00_001600EC_2d5de8 + IV5(v, 8) * 128; + FUN_L00_00284e50(other + 0x30, other + 0x70); + } + m->state = 9; + if ((s8)v[0xc] != -1) FUN_L00_00298840_2d5de8((s8)v[0xc]); + break; + case 9: + if (D_15F5C4_2d6cd0 != 2) { + m->state = 10; + if ((s8)v[0xd] != -1) FUN_L00_00299460_2d5de8((s8)v[0xd]); + } + break; + case 10: + if (D_15F5C4_2d6cd0 != 2) { + if ((s8)v[0xe] != -1) FUN_L00_00298840_2d5de8((s8)v[0xe]); + m->state = 11; + } + break; + case 11: + if (D_15F5C4_2d6cd0 == 2) return; + FUN_0024d430_2d5de8(0, -1); + FUN_L00_00262d38(IV5(v, 4)); +remove: + mark_moby_for_removal(m); + return; + } + if (IV5(v, 0x50) != -1 && IV5(v, 0x54) != -1) { + other = D_0015FFD8_2d3a10 + IV5(v, 0x54) * 256; + if (*(s16 *)(other + 0xa6) == 0x336) { + delta.q = 0; + first = D_L00_001600EC_2d5de8 + IV5(v, 0x50) * 128 + 0x30; + FUN_L00_00260400_2d0538(m, (s32)other, first, &delta, first, &delta); + add_vector_xyz(&point, &offset, D_L00_001600EC_2d5de8 + IV5(v, 0x50) * 128 + 0x30); + *(u128_2d5988 *)((u8 *)m + 0x10) = point.q; + } + } +} +#undef IV5 +#undef FV5 +#endif typedef struct { u8 p0[0x10]; f32 r[4]; From 3dfddfdac70a0b086889b3f289a027e1df797f98 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:07:48 +0000 Subject: [PATCH 127/251] decomp: improve FUN_L08_002e2250 --- src/overlays/l08/gameplay/entities/002deee0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/l08/gameplay/entities/002deee0.c b/src/overlays/l08/gameplay/entities/002deee0.c index ef632ba0b..ed01f21c1 100644 --- a/src/overlays/l08/gameplay/entities/002deee0.c +++ b/src/overlays/l08/gameplay/entities/002deee0.c @@ -1353,7 +1353,7 @@ void FUN_L08_002e2250(struct Moby *moby) { slot = &slots[selected]; vector = slot->moby->pvars; FUN_L00_0025f090(moby, &slot->moby->pos, -1, 2.0f, 13.0f); - FUN_001f9a28(vector, &slot->moby->pos, &(*(struct Moby **)((char *)vars + 0x64 + selected * 16))->pos); + FUN_001f9a28(vector, &slot->moby->pos, &vars->slots[selected].anchor->pos); normalize_vector_xyz(vector, vector, D_0015ED6C * 10.0f); slot->moby->state = 1; slot->moby = 0; @@ -1369,7 +1369,7 @@ void FUN_L08_002e2250(struct Moby *moby) { if (slot->moby != 0) { u8 *vector = slot->moby->pvars; FUN_L00_0025f090(moby, &slot->moby->pos, -1, 2.0f, 13.0f); - FUN_001f9a28(vector, &slot->moby->pos, &(*(struct Moby **)((char *)vars + 0x64 + index * 16))->pos); + FUN_001f9a28(vector, &slot->moby->pos, &vars->slots[index].anchor->pos); normalize_vector_xyz(vector, vector, D_0015ED6C * 10.0f); slot->moby->state = 1; slot->moby = 0; From 59756c7311343a3d15e58eefb8b9a822e036d97c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:08:14 +0000 Subject: [PATCH 128/251] decomp: improve FUN_L00_002bcf98 --- src/overlays/shared/gameplay/entities/002b94d0.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b94d0.c b/src/overlays/shared/gameplay/entities/002b94d0.c index 3284c99e8..76a90f751 100644 --- a/src/overlays/shared/gameplay/entities/002b94d0.c +++ b/src/overlays/shared/gameplay/entities/002b94d0.c @@ -1219,12 +1219,12 @@ extern s32 D_L00_001617BC __attribute__((sda)); extern s32 D_L00_001617BC_abs __asm__("D_L00_001617BC") __attribute__((section(".data"))); extern f32 D_L00_001616DC __attribute__((sda)); extern f32 D_L00_001617CC __attribute__((sda)); -extern volatile s32 D_L00_00161718_i __asm__("D_L00_00161718") __attribute__((sda)); -extern volatile s32 D_L00_00161720_i __asm__("D_L00_00161720") __attribute__((sda)); -extern volatile s32 D_L00_00161724_i __asm__("D_L00_00161724") __attribute__((sda)); -extern s32 D_L00_001617D0 __attribute__((section(".data"))); -extern s32 D_L00_00161824 __attribute__((section(".data"))); -extern s32 D_L00_00161818 __attribute__((section(".data"))); +extern s32 D_L00_00161718_i __asm__("D_L00_00161718") __attribute__((sda)); +extern s32 D_L00_00161720_i __asm__("D_L00_00161720") __attribute__((sda)); +extern s32 D_L00_00161724_i __asm__("D_L00_00161724") __attribute__((sda)); +extern s32 D_L00_001617D0; +extern s32 D_L00_00161824; +extern s32 D_L00_00161818; extern s32 D_L00_001DBF50 __attribute__((section(".data"))); extern u128 D_L00_001DBF60_2bcf98 __asm__("D_L00_001DBF60") __attribute__((section(".data"))); extern s32 D_L00_001DD0D0 __attribute__((section(".data"))); From 4f59b57172c5a0d78ba13c7782c5484cc6f30203 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:11:17 +0000 Subject: [PATCH 129/251] decomp: improve FUN_L00_00257218 --- src/overlays/shared/rendering/00250df8.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/rendering/00250df8.c b/src/overlays/shared/rendering/00250df8.c index affc3e2dd..9f65caebc 100644 --- a/src/overlays/shared/rendering/00250df8.c +++ b/src/overlays/shared/rendering/00250df8.c @@ -96,7 +96,8 @@ int FUN_L00_00257218(u8 *m, s32 *item) { *item = selected_item & 0x3F; } choice = random_integer_below(5); - choice = 1 + (choice == 0); + if (choice) choice = 1; + else choice = 2; return choice; } #endif From f06e71e5f518dc62f8281ee9c1a21b0fad196628 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:14:18 +0000 Subject: [PATCH 130/251] decomp: improve FUN_L05_00254358 --- src/overlays/shared/ui/help/00237488.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/overlays/shared/ui/help/00237488.c b/src/overlays/shared/ui/help/00237488.c index c70273748..263844dca 100644 --- a/src/overlays/shared/ui/help/00237488.c +++ b/src/overlays/shared/ui/help/00237488.c @@ -1420,8 +1420,7 @@ void FUN_L05_00254358(f32 *position, f32 *direction) { cursor = (HelpPath *)((char *)cursor + 0x20); } while (index < path->count); } - p = &path->points[selected]; - qcopy(position, p); + qcopy(position, &path->points[selected]); qcopy(&point, position); point.z += 2.0f; position[2] = find_ground_height(0.5f, &point, 0); From 8c9504ea10ca1d2bd2048df5812409e9c1f9ca20 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:16:39 +0000 Subject: [PATCH 131/251] decomp: improve FUN_L00_002cbcc0 --- .../shared/gameplay/entities/002c8440.c | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002c8440.c b/src/overlays/shared/gameplay/entities/002c8440.c index 913218803..f0e891608 100644 --- a/src/overlays/shared/gameplay/entities/002c8440.c +++ b/src/overlays/shared/gameplay/entities/002c8440.c @@ -1374,7 +1374,7 @@ void FUN_L00_002cbcc0(u8 *m, s32 enabled) s32 color; s32 sign; u8 *effect; - u8 alpha = 0x44; + s32 alpha; handle = (void **)(*(u8 **)(m + 0x78) + 0x2c); for (i = 16; i >= 0; i--) { @@ -1398,23 +1398,30 @@ void FUN_L00_002cbcc0(u8 *m, s32 enabled) } } - for (j = 2; j >= 0; j--) { - color = ((u32)FUN_L00_00257b90_2cbcc0(0x20, 0x80) << 24) | 0x606060; - sign = FUN_L00_00257b50_2cbcc0(2) ? -1 : 1; - vectors[0].q = 0; - vectors[0].f[2] = 1.0f; - vectors[0].f[3] = 1.0f; - vectors[0].f[2] = FUN_L00_00257be8_2cbcc0(0.01f, 0.025f) * D_0015ED60_2cbcc0; - effect = FUN_0026d000_2cbcc0(pos, sign, &vectors[0], color, - 0.2f, 1.0f, 1.02f, 140000.0f); - if (effect != 0) { - *(s16 *)(effect + 0xa) = FUN_001fef20_2cbcc0(FUN_L00_00257b90_2cbcc0(50, 80)); - effect += 0x20; - *(s32 *)(effect + 4) = 2; - effect[0xa] = color >> 24; - effect[0xb] = effect[-0x16]; - if (FUN_L00_00257b50_2cbcc0(2)) - effect[-0x1d] = alpha; + { + s32 j; + for (j = 2; j >= 0; j--) { + color = ((u32)FUN_L00_00257b90_2cbcc0(0x20, 0x80) << 24) | 0x606060; + sign = FUN_L00_00257b50_2cbcc0(2) ? -1 : 1; + vectors[0].q = 0; + vectors[0].f[2] = 1.0f; + vectors[0].f[3] = 1.0f; + vectors[0].f[2] = FUN_L00_00257be8_2cbcc0(0.01f, 0.025f) * D_0015ED60_2cbcc0; + effect = FUN_0026d000_2cbcc0(pos, sign, &vectors[0], color, + 0.2f, 1.0f, 1.02f, 140000.0f); + if (effect != 0) { + *(s16 *)(effect + 0xa) = FUN_001fef20_2cbcc0(FUN_L00_00257b90_2cbcc0(50, 80)); + /* The direction is no longer needed; retain the effect field address. */ + sign = (s32)(effect + 0x20); + *(s32 *)(sign + 4) = 2; + ((u8 *)sign)[0xa] = color >> 24; + ((u8 *)sign)[0xb] = effect[0xa]; + if (FUN_L00_00257b50_2cbcc0(2)) { + /* The fixed low color byte is 0x60, so the alpha byte is 0x44. */ + alpha = color ^ 0x24; + effect[3] = alpha; + } + } } } } From 780ccb766a24a3f07054c3002b55a915aecbb353 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:19:32 +0000 Subject: [PATCH 132/251] decomp: improve FUN_L00_00276908 --- src/overlays/shared/audio/voices/00276368.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index 9fc1c55b9..b780ae0a9 100644 --- a/src/overlays/shared/audio/voices/00276368.c +++ b/src/overlays/shared/audio/voices/00276368.c @@ -282,11 +282,11 @@ void FUN_L00_00276908(void) { } { s32 i; - for (i = 0; i < 4; i++) { - if (D_00141660[i] != ((s32 *)((u8 *)&D_L00_001B9CF0 + 0x30))[i]) { - hero.pending_item[i] = - ((s32 *)((u8 *)&D_L00_001B9CF0 + 0x30))[i] != 0 - ? ((s32 *)((u8 *)&D_L00_001B9CF0 + 0x30))[i] + for (i = 3; i >= 0; i--) { + if (D_00141660[3 - i] != ((s32 *)&D_L00_001B9CF0)[15 - i]) { + hero.pending_item[3 - i] = + ((s32 *)&D_L00_001B9CF0)[15 - i] != 0 + ? ((s32 *)&D_L00_001B9CF0)[15 - i] : 0x26; } } From c2a5b7f9ba41e6072860d007cdb8e2a5ee1407b8 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:20:08 +0000 Subject: [PATCH 133/251] decomp: improve FUN_L00_00275aa0 --- src/overlays/shared/rendering/002712b8.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/overlays/shared/rendering/002712b8.c b/src/overlays/shared/rendering/002712b8.c index 590135a7d..a9d4b70f0 100644 --- a/src/overlays/shared/rendering/002712b8.c +++ b/src/overlays/shared/rendering/002712b8.c @@ -2009,9 +2009,8 @@ void FUN_L00_00275aa0(unsigned char *m) { m[8] += q[0xa]; h = *(short *)(q + 8); - h -= *(short *)(m + 0xa); - if (h < 6) { - f = (float)h / 5.0f; + if (h - *(short *)(m + 0xa) < 6) { + f = (float)(h - *(short *)(m + 0xa)) / 5.0f; *(float *)(m + 0xc) = *(float *)(q + 4) + ((*(float *)q + *(float *)(q + 4)) * 0.5f - *(float *)(q + 4)) * f; originalAlpha = q[0xb]; @@ -2021,7 +2020,7 @@ void FUN_L00_00275aa0(unsigned char *m) { alpha *= f; alpha = (float)originalAlpha + alpha; } else { - f = (float)*(short *)(m + 0xa) / FUN_001fa6c0_275aa0(*(short *)(q + 8) - 6); + f = (float)*(short *)(m + 0xa) / FUN_001fa6c0_275aa0(h - 6); *(float *)(m + 0xc) = *(float *)q + ((*(float *)q + *(float *)(q + 4)) * 0.5f - *(float *)q) * f; alpha = (float)(q[0xb] >> 1); @@ -2030,10 +2029,10 @@ void FUN_L00_00275aa0(unsigned char *m) { } *(int *)(m + 4) = (FUN_001fa6d0_275aa0(alpha) << 24) | (*(int *)(m + 4) & 0xffffff); velocity = (float *)(q + 0xc); - v[0] = *(float *)(q + 0xc); - v[1] = *(float *)(q + 0x10); + *(volatile float *)&v[0] = *(volatile float *)(q + 0xc); + *(volatile float *)&v[1] = *(volatile float *)(q + 0x10); v[2] = *(float *)(q + 0x14); - *(int *)&v[3] = 0; + *(volatile int *)&v[3] = 0; FUN_001f9a10_275aa0(m + 0x10, m + 0x10, v); if (*(int *)(q + 0x18)) { subtract_vector_xyz(d, (char *)*(int *)(q + 0x18) + 0x10, m + 0x10); From 6335bd71a7065b8e84e1bafe0a5cd28f7646d397 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:21:50 +0000 Subject: [PATCH 134/251] decomp: improve FUN_L10_002e5be0 --- src/overlays/l10/gameplay/vendor/002df270.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/overlays/l10/gameplay/vendor/002df270.c b/src/overlays/l10/gameplay/vendor/002df270.c index 54cec1213..23afb52d9 100644 --- a/src/overlays/l10/gameplay/vendor/002df270.c +++ b/src/overlays/l10/gameplay/vendor/002df270.c @@ -1881,12 +1881,12 @@ extern f32 multiply_global_factor_ed64(f32) __asm__("FUN_001f96b0"); extern void scale_vector_xyz(f32 *, f32 *, f32) __asm__("FUN_001f9a68"); extern void build_spherical_offset(f32 *, f32, f32, f32) __asm__("FUN_00214db0"); extern s32 fast_tween_color(f32, s32, s32) __asm__("FUN_001fa6e0"); -extern unsigned char *FUN_L00_002738e8(f32, f32, f32, void *, void *, s32, s32, s32, s32); +extern unsigned char *FUN_L00_002738e8(void *, void *, s32, f32, f32, f32, s32, s32, s32); void FUN_L10_002e5be0(struct Moby *moby) { f32 *pvars = (f32 *)moby->pvars; Vec4 *moby_position = (Vec4 *)&moby->pos.x; - s32 i; + s64 i; moby->update_dist = 0x80; if (((s32 *)pvars)[3] > 0) { @@ -1941,8 +1941,8 @@ void FUN_L10_002e5be0(struct Moby *moby) { x = random_float_between(0.25f, 0.5f); fade_color = fast_tween_color(x, D_L10_00161EF4, first_color); life = truncate_float_to_s32(multiply_global_factor_ed64(pvars[2] * 60.0f)); - FUN_L00_002738e8(amount, pvars[0], D_L10_00161F00 * frame_time_sq, - &position, &velocity, life, color, fade_color, variant); + FUN_L00_002738e8(&position, &velocity, life, amount, pvars[0], + D_L10_00161F00 * frame_time_sq, color, fade_color, variant); } } } From 412306993ccde05e49dc97379b8621c35e079a60 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:22:36 +0000 Subject: [PATCH 135/251] decomp: improve FUN_L08_002e2250 --- src/overlays/l08/gameplay/entities/002deee0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/l08/gameplay/entities/002deee0.c b/src/overlays/l08/gameplay/entities/002deee0.c index ed01f21c1..7c0ad1d5c 100644 --- a/src/overlays/l08/gameplay/entities/002deee0.c +++ b/src/overlays/l08/gameplay/entities/002deee0.c @@ -1360,10 +1360,10 @@ void FUN_L08_002e2250(struct Moby *moby) { return; } { - int start = truncate_float_to_s32(random_float_between(0.0f, 23.0f)); + long start = truncate_float_to_s32(random_float_between(0.0f, 23.0f)); i = 0; do { - int index = (i + start) % 24 + 10; + int index = (int)(i + start) % 24 + 10; slot = &slots[index]; i++; if (slot->moby != 0) { From dd0aef547459f829cd160d9eaf35fafe62158bce Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:07:02 +0000 Subject: [PATCH 136/251] decomp: improve draw_debug_text --- src/overlays/shared/rendering/debug/001f36f8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/rendering/debug/001f36f8.c b/src/overlays/shared/rendering/debug/001f36f8.c index faaa10129..733f61813 100644 --- a/src/overlays/shared/rendering/debug/001f36f8.c +++ b/src/overlays/shared/rendering/debug/001f36f8.c @@ -102,8 +102,8 @@ void FUN_L00_001f3770(s32 x, s32 y, s32 color, s32 text_address) { } ((u32 *)packet)[0] = quadwords | 0x10000000; ((u32 *)packet)[3] = quadwords | 0x50000000; - ((u32 *)packet)[1] = 0; ((u32 *)packet)[2] = 0; + ((u32 *)packet)[1] = 0; *glyph_tag = (s64)(glyph_count | 0x8000) | 0x4400000000000000ULL; } #endif /* NON_MATCHING */ From 48b6508eea6227d9d34ada20959d4b920332b0bf Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:13:00 +0000 Subject: [PATCH 137/251] decomp: improve FUN_L00_00261b48 --- src/overlays/shared/gameplay/state/00261968.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/state/00261968.c b/src/overlays/shared/gameplay/state/00261968.c index bdb660617..e3f3a21cf 100644 --- a/src/overlays/shared/gameplay/state/00261968.c +++ b/src/overlays/shared/gameplay/state/00261968.c @@ -99,6 +99,7 @@ s32 FUN_L00_00261b48(s32 path_index, OvlVec4 *start, OvlVec4 *end, OvlVec4 *out) s32 found; f32 nearest; f32 crossing; + f32 zero; FUN_001ff2a8_261b48(&direction, end, start); direction.i[2] = 0; @@ -119,10 +120,11 @@ s32 FUN_L00_00261b48(s32 path_index, OvlVec4 *start, OvlVec4 *end, OvlVec4 *out) current = &next; if (i < (*entry)->count) { offset = 0x20; + zero = 0.0f; do { FUN_001ff2a8_261b48(current, (OvlVec4 *)((u8 *)*entry + offset), start); FUN_001ff6d0_261b48(current, current, &direction); - if (first.f[3] != 0.0f || current->f[3] != 0.0f) { + if (first.f[3] != zero || next.f[3] != zero) { if (current->f[1] * first.f[1] < 0.0f) { crossing = (first.f[0] - next.f[0]) / (first.f[1] - current->f[1]) * -current->f[1] + next.f[0]; if (crossing > 0.0f && crossing < nearest) { From dbc507e84e2e953929f5858c8167ae161efb26ae Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:27:39 +0000 Subject: [PATCH 138/251] decomp: improve FUN_L00_002cbcc0 --- .../shared/gameplay/entities/002c8440.c | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002c8440.c b/src/overlays/shared/gameplay/entities/002c8440.c index f0e891608..3a84a7fd4 100644 --- a/src/overlays/shared/gameplay/entities/002c8440.c +++ b/src/overlays/shared/gameplay/entities/002c8440.c @@ -1349,9 +1349,6 @@ void FUN_L00_002cb418(Moby *m) { scale_vector_xyz_2cb418(&c, &b, random_float_between_2cb418(D_0015ED6C_2cb418 * 0.5f, D_0015ED6C_2cb418 + D_0015ED6C_2cb418) / len); spawn_spark_2cb418((Vec4A *)&m->pos, &c, 0x7F2F4F6F, random_int_between_2cb418(scale_game_frames_2cb418(10), scale_game_frames_2cb418(15)), 30000.0f); } -#ifndef NON_MATCHING -INCLUDE_ASM("config/us/overlays/asm/FUN_L00_002cbcc0.s", FUN_L00_002cbcc0); -#else extern void FUN_00267a08_2cbcc0(void *) __asm__("FUN_L00_00267a08"); extern f32 FUN_L00_00257be8_2cbcc0(f32, f32) __asm__("FUN_L00_00257be8"); extern s32 FUN_L00_00257b90_2cbcc0(s32, s32) __asm__("FUN_L00_00257b90"); @@ -1359,7 +1356,7 @@ extern s32 FUN_L00_00257b50_2cbcc0(s32) __asm__("FUN_L00_00257b50"); extern s32 FUN_001fef20_2cbcc0(s32) __asm__("FUN_L00_001fef20"); extern void FUN_001ff500_2cbcc0(void *, void *, f32) __asm__("FUN_L00_001ff500"); extern void *FUN_0026dd20_2cbcc0(void *, void *, u32, s32, f32) __asm__("FUN_L00_0026dd20"); -extern u8 *FUN_0026d000_2cbcc0(void *, s32, void *, u32, f32, f32, f32, f32) __asm__("FUN_L00_0026d000"); +extern u8 *FUN_0026d000_2cbcc0(f32, f32, f32, f32, void *, s32, void *, u32) __asm__("FUN_L00_0026d000"); extern f32 D_0015ED6C_2cbcc0 __asm__("D_0015ED6C"); extern f32 D_0015ED60_2cbcc0 __asm__("D_0015ED60"); @@ -1385,16 +1382,17 @@ void FUN_L00_002cbcc0(u8 *m, s32 enabled) pos = m + 0x10; if (enabled != 0) { + V4 *vector = &vectors[1]; for (j = 4; j >= 0; j--) { vectors[1].q = 0; vectors[1].f[0] = FUN_L00_00257be8_2cbcc0(-1.0f, 1.0f); vectors[1].f[1] = FUN_L00_00257be8_2cbcc0(-1.0f, 1.0f); vectors[1].f[2] = FUN_L00_00257be8_2cbcc0(-1.0f, 1.0f); vectors[0].q = vectors[1].q; - FUN_001ff500_2cbcc0(&vectors[1], &vectors[0], + FUN_001ff500_2cbcc0(vector, &vectors[0], FUN_L00_00257be8_2cbcc0(D_0015ED6C_2cbcc0 * 3.0f, D_0015ED6C_2cbcc0 * 6.0f)); lifetime = FUN_L00_00257b90_2cbcc0(FUN_001fef20_2cbcc0(10), FUN_001fef20_2cbcc0(15)); - FUN_0026dd20_2cbcc0(pos, &vectors[1], 0x7f2f4f6f, lifetime, 35000.0f); + FUN_0026dd20_2cbcc0(pos, vector, 0x7f2f4f6f, lifetime, 35000.0f); } } @@ -1407,25 +1405,25 @@ void FUN_L00_002cbcc0(u8 *m, s32 enabled) vectors[0].f[2] = 1.0f; vectors[0].f[3] = 1.0f; vectors[0].f[2] = FUN_L00_00257be8_2cbcc0(0.01f, 0.025f) * D_0015ED60_2cbcc0; - effect = FUN_0026d000_2cbcc0(pos, sign, &vectors[0], color, - 0.2f, 1.0f, 1.02f, 140000.0f); + effect = FUN_0026d000_2cbcc0(0.2f, 1.0f, 1.02f, 140000.0f, + pos, sign, &vectors[0], color); if (effect != 0) { *(s16 *)(effect + 0xa) = FUN_001fef20_2cbcc0(FUN_L00_00257b90_2cbcc0(50, 80)); /* The direction is no longer needed; retain the effect field address. */ - sign = (s32)(effect + 0x20); - *(s32 *)(sign + 4) = 2; - ((u8 *)sign)[0xa] = color >> 24; - ((u8 *)sign)[0xb] = effect[0xa]; - if (FUN_L00_00257b50_2cbcc0(2)) { + i = (s32)(effect + 0x20); + *(s32 *)(i + 4) = 2; + ((u8 *)i)[0xa] = color >> 24; + ((u8 *)i)[0xb] = effect[0xa]; + alpha = FUN_L00_00257b50_2cbcc0(2); + if (alpha) { /* The fixed low color byte is 0x60, so the alpha byte is 0x44. */ - alpha = color ^ 0x24; + alpha = 0x44; effect[3] = alpha; } } } } } -#endif #include "qcopy.h" #include "rnc/overlay/quad.h" extern float D_0015ED6C_2cbf68 __asm__("D_0015ED6C"); From b0b9f208d013b72a3bc3363f70489f7d2953087e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:30:18 +0000 Subject: [PATCH 139/251] decomp: improve scan_hero_input_sequences --- src/overlays/shared/ui/help/00203b18.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/overlays/shared/ui/help/00203b18.c b/src/overlays/shared/ui/help/00203b18.c index df0ea2589..9330d7214 100644 --- a/src/overlays/shared/ui/help/00203b18.c +++ b/src/overlays/shared/ui/help/00203b18.c @@ -998,6 +998,7 @@ void FUN_L00_00206e00(void) { struct Hero *g; u8 *hero_base; s32 input; + u32 state; s32 level; s32 i, j, length, position; u8 *end; @@ -1025,9 +1026,9 @@ void FUN_L00_00206e00(void) { input = 1; goto append; } + state = g->unk450 ^ 3; input = 3; - if (g->unk450 != 3) - input = 0; + goto reject; } else if (g->state.current == 0x11) { input = 9; goto append; @@ -1035,7 +1036,9 @@ void FUN_L00_00206e00(void) { input = 10; goto append; } else { - input = (g->state.current == 0xE) ? 5 : 0; + state = g->state.current ^ 0xE; + input = 5; + goto reject; } } else if (g->state.control_mode == 6) { if (g->state.current == HERO_STATE_WRENCH_SLAM) { @@ -1046,12 +1049,13 @@ void FUN_L00_00206e00(void) { input = g->attack_record + 12; goto append; } + state = g->state.current ^ HERO_STATE_CROUCH_SWING; input = 4; - if (g->state.current != HERO_STATE_CROUCH_SWING) input = 0; + goto reject; } else { + state = g->state.current ^ 0x22; input = 11; - if (g->state.current != 0x22) - input = 0; + goto reject; } } else { level = FUN_001f96f8(0x3C); @@ -1060,11 +1064,14 @@ void FUN_L00_00206e00(void) { input = 7; goto append; } + state = g->state.current ^ HERO_STATE_LAND; input = 8; - if (g->state.current != HERO_STATE_LAND) - input = 0; + goto reject; } } + goto append; +reject: + if (state != 0) input = 0; append: if (input == 0) return; From f59ccd74ed6d6011a47ca89bfab2aeff8e2160ad Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:30:30 +0000 Subject: [PATCH 140/251] decomp: improve FUN_L00_002bcf98 --- src/overlays/shared/gameplay/entities/002b94d0.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/002b94d0.c b/src/overlays/shared/gameplay/entities/002b94d0.c index 76a90f751..71f65c133 100644 --- a/src/overlays/shared/gameplay/entities/002b94d0.c +++ b/src/overlays/shared/gameplay/entities/002b94d0.c @@ -1238,6 +1238,7 @@ void FUN_L00_002bcf98(u8 *m) { f32 scale; u128 *copies; s32 *clears; + u128 *scaled_vector; if (D_L00_001617BC_abs != 0) { D_L00_001617BC = 0; @@ -1251,6 +1252,7 @@ void FUN_L00_002bcf98(u8 *m) { D_L00_00161718_i = 0; D_L00_00161720_i = 0; D_L00_00161724_i = 0; + scaled_vector = &vec; D_L00_001617D0 = 0; D_L00_00161824 = 0; copies = (u128 *)&D_L00_001DD0D0; @@ -1259,7 +1261,7 @@ void FUN_L00_002bcf98(u8 *m) { s32 j; for (j = 2; j >= 0; j--) { *clears = 0; - qcopy(copies, &vec); + qcopy(copies, scaled_vector); copies++; clears++; } From 719cb4e17054872ec3ee757352bfd5d23c1dcbf4 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:27:48 +0000 Subject: [PATCH 141/251] decomp: improve FUN_L05_00254358 --- src/overlays/shared/ui/help/00237488.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/ui/help/00237488.c b/src/overlays/shared/ui/help/00237488.c index 263844dca..0413ad444 100644 --- a/src/overlays/shared/ui/help/00237488.c +++ b/src/overlays/shared/ui/help/00237488.c @@ -1382,13 +1382,13 @@ void FUN_L05_00254358(f32 *position, f32 *direction) { if (path->count > 0) { height_limit = 4.0f; p = path->points; - g = &hero; cursor = path; do { f32 a; s32 next; s32 count; f32 b; + g = &hero; a = FUN_001f9e90(cursor->points[0].x - g->motion.pos.f[0], cursor->points[0].y - g->motion.pos.f[1]); count = path->count; next = (s32)((u32)count + 2U); From 1da7702348e9aaa38f16a811c5ff63fef374f2b9 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:35:19 +0000 Subject: [PATCH 142/251] decomp: improve FUN_L00_002721f0 --- src/overlays/shared/rendering/002712b8.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/rendering/002712b8.c b/src/overlays/shared/rendering/002712b8.c index a9d4b70f0..2b0cbb33f 100644 --- a/src/overlays/shared/rendering/002712b8.c +++ b/src/overlays/shared/rendering/002712b8.c @@ -457,7 +457,8 @@ void FUN_L00_002721f0(unsigned char *p) { alpha = (unsigned int)alpha >> 1; a = (float)(alpha - originalAlpha); a *= t; - a += (float)originalAlpha; + t = (float)originalAlpha + a; + a = t; } else { t = (float)*(short *)(p + 0xA) / FUN_001fa6c0_2721f0(*(short *)(q + 8) - 6); *(float *)(p + 0xC) = *(float *)q + From 987e81345db7ff9c7fce8266244a9440353edd85 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:36:10 +0000 Subject: [PATCH 143/251] decomp: improve FUN_L00_00276908 --- src/overlays/shared/audio/voices/00276368.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index b780ae0a9..6e80574bc 100644 --- a/src/overlays/shared/audio/voices/00276368.c +++ b/src/overlays/shared/audio/voices/00276368.c @@ -282,12 +282,13 @@ void FUN_L00_00276908(void) { } { s32 i; + s32 value = 0x26; for (i = 3; i >= 0; i--) { if (D_00141660[3 - i] != ((s32 *)&D_L00_001B9CF0)[15 - i]) { hero.pending_item[3 - i] = ((s32 *)&D_L00_001B9CF0)[15 - i] != 0 ? ((s32 *)&D_L00_001B9CF0)[15 - i] - : 0x26; + : value; } } } From 449380a96475b1dce3ae2d45009a9094e91f43a4 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:33:50 +0000 Subject: [PATCH 144/251] decomp: improve FUN_L12_00308350 --- src/overlays/l12/gameplay/vendor/003028c8.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/overlays/l12/gameplay/vendor/003028c8.c b/src/overlays/l12/gameplay/vendor/003028c8.c index 424443c39..9750a7430 100644 --- a/src/overlays/l12/gameplay/vendor/003028c8.c +++ b/src/overlays/l12/gameplay/vendor/003028c8.c @@ -1818,7 +1818,7 @@ void FUN_L12_00308350(struct Moby *m) { copy_moby_matrix(matrix, &m->rot_row0); qcopy(&matrix[3], &m->pos); matrix[3][3] = 1.0f; - first.texture = get_effect_texture_l12(0xe); + first.texture = second.texture = get_effect_texture_l12(0xe); flags = (long)D_L12_00161FBC; second_flags = (long)D_L12_00161FCC; flags |= (long)D_L12_00161FC0 << 2; @@ -1831,11 +1831,9 @@ void FUN_L12_00308350(struct Moby *m) { second_flags |= 0x8000000000L; first.gs_state = flags; second.gs_state = second_flags; - first.texture_state = 0xFF9000000260L; - second.texture_state = 0xFF9000000260L; - first.tag = 0; + first.texture_state = second.texture_state = 0xFF9000000260L; second.tag = 0; - second.texture = first.texture; + first.tag = 0; first.color[0] = first.color[1] = first.color[2] = first.color[3] = D_L12_00161F90; second.color[0] = second.color[1] = second.color[2] = second.color[3] = D_L12_00161F94; j = 0; From dda60d69e84606d51aa5a54e06d2dac06c665652 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:43:29 +0000 Subject: [PATCH 145/251] decomp: improve FUN_L02_00264e70 --- src/overlays/shared/gameplay/entities/00264e40.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/00264e40.c b/src/overlays/shared/gameplay/entities/00264e40.c index 7e201bba2..637d3f75f 100644 --- a/src/overlays/shared/gameplay/entities/00264e40.c +++ b/src/overlays/shared/gameplay/entities/00264e40.c @@ -51,8 +51,8 @@ void FUN_L02_00264e70(char *slots, float *position, float *direction, float dist float adjusted[4] __attribute__((aligned(16))); float velocity[4] __attribute__((aligned(16))); float offset[4] __attribute__((aligned(16))); - float travel_step = 0.0f; float speed = 0.0f; + float travel_step = 0.0f; float travel; float acceleration; int count; From adfc792aa2cf531839b06dcdc4be555245bd18c4 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:45:11 +0000 Subject: [PATCH 146/251] decomp: improve FUN_L00_0029ff58 --- src/overlays/shared/gameplay/entities/0029f990.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/0029f990.c b/src/overlays/shared/gameplay/entities/0029f990.c index e8ad2d7f8..dd8585c27 100644 --- a/src/overlays/shared/gameplay/entities/0029f990.c +++ b/src/overlays/shared/gameplay/entities/0029f990.c @@ -195,11 +195,11 @@ void FUN_L00_0029ff58(void) { D_L00_00161184 = D_L00_00161184 - 1.0f; } q.extra[0] = 0; - q.extra[2] = 1; q.extra[3] = 0x4000000044L; + indices = D_L00_001CA480[0]; + q.extra[2] = 1; q.extra[1] = FUN_001f44b8_29ff58(0x18); i = 0; - indices = D_L00_001CA480[0]; while (1) { offset = i * 16; i++; From b3c8a03d18e98454b0d3671ea18d2470ffb1e9b9 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:47:31 +0000 Subject: [PATCH 147/251] decomp: improve spawn_troll_alert_particles --- src/overlays/l12/gameplay/entities/002bf140.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/overlays/l12/gameplay/entities/002bf140.c b/src/overlays/l12/gameplay/entities/002bf140.c index daaac2ce2..4b06c8620 100644 --- a/src/overlays/l12/gameplay/entities/002bf140.c +++ b/src/overlays/l12/gameplay/entities/002bf140.c @@ -867,8 +867,9 @@ void FUN_L12_002e3098(struct Moby *moby) { float angle, horizontal, vertical, radius; int i, j, count, a, b, c, d, life; float *position; + float *direction_ptr; - void *vars = moby->pvars; + void *vars = *(void *volatile *)&moby->pvars; count = D_L12_0016183C; if (moby->state == 15) @@ -876,6 +877,7 @@ void FUN_L12_002e3098(struct Moby *moby) { i = 0; if (count > 0) { position = pos; + direction_ptr = direction; do { qcopy(pos, &moby->pos); @@ -892,9 +894,9 @@ void FUN_L12_002e3098(struct Moby *moby) { velocity[0] = fast_cos_e3098(angle) * (horizontal * frame_time); velocity[1] = fast_sin_e3098(angle) * (horizontal * frame_time); velocity[2] = vertical * frame_time + 0.0f; - set_direction(0.5f, direction, (char *)vars + 0x120); + set_direction(0.5f, direction_ptr, (char *)vars + 0x120); direction[2] = 0.0f; - rotate_vector(velocity, velocity, direction); + rotate_vector(velocity, velocity, direction_ptr); qcopy(accel, velocity); accel[2] -= D_L12_00161860 * frame_time_sq * (float)scale_game_frames_e3098(D_L12_00161880); From 7f0338b65ce45465571c39761b646e24628aeea1 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:48:55 +0000 Subject: [PATCH 148/251] decomp: improve FUN_L00_002721f0 --- src/overlays/shared/rendering/002712b8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/rendering/002712b8.c b/src/overlays/shared/rendering/002712b8.c index 2b0cbb33f..b74dfee59 100644 --- a/src/overlays/shared/rendering/002712b8.c +++ b/src/overlays/shared/rendering/002712b8.c @@ -473,8 +473,8 @@ void FUN_L00_002721f0(unsigned char *p) { r = (float *)(q + 0xC); *(volatile float *)&v[0] = *(float *)(q + 0xC); *(volatile float *)&v[1] = r[1]; - v[2] = r[2]; - *(volatile int *)&v[3] = 0; + *(volatile float *)&v[2] = *(volatile float *)&r[2]; + *(int *)&v[3] = 0; FUN_001f9a10_2721f0(p + 0x10, p + 0x10, &v); *(float *)(q + 0x14) -= *(float *)(q + 0x18); if (*(float *)(p + 0x10) < 2.0f || 1021.0f < *(float *)(p + 0x10) || From 0f0081c55b45188052e473187350a47d7f3ea43e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:50:31 +0000 Subject: [PATCH 149/251] decomp: improve FUN_L00_00262030 --- src/overlays/shared/gameplay/state/00261968.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/overlays/shared/gameplay/state/00261968.c b/src/overlays/shared/gameplay/state/00261968.c index e3f3a21cf..2334aef4d 100644 --- a/src/overlays/shared/gameplay/state/00261968.c +++ b/src/overlays/shared/gameplay/state/00261968.c @@ -210,9 +210,6 @@ s32 FUN_L00_00261d78(f32 distance, s32 path_index, OvlVec4 *point, OvlVec4 *out) qcopy(out, &working); return found; } -#ifndef NON_MATCHING -INCLUDE_ASM("config/us/overlays/asm/FUN_L00_00262030.s", FUN_L00_00262030); -#else #include "rnc/overlay/quad.h" typedef struct { @@ -284,9 +281,9 @@ s32 FUN_L00_00262030(f32 distance, s32 path_index, OvlVec4 *point, OvlVec4 *out) segment_length = FUN_001ff3d8_262030(&difference); if (!(segment_length < distance)) goto next_segment_262030; - found = 1; FUN_001ff500_262030(distance, &scaled_difference, &difference); FUN_001ff278_262030(&working, &scaled_difference, current); + found = 1; } else { found = 1; FUN_001ff500_262030(projection, &scaled_cross, &scaled_segment); @@ -307,7 +304,6 @@ s32 FUN_L00_00262030(f32 distance, s32 path_index, OvlVec4 *point, OvlVec4 *out) } return found; } -#endif /* NON_MATCHING */ #include "rnc/math/vector.h" /* A polyline of evenly spaced points. */ From 81715da1657e15a817f402a5f585aeb7684910a3 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:51:30 +0000 Subject: [PATCH 150/251] decomp: improve FUN_L00_00276908 --- src/overlays/shared/audio/voices/00276368.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index 6e80574bc..294e99364 100644 --- a/src/overlays/shared/audio/voices/00276368.c +++ b/src/overlays/shared/audio/voices/00276368.c @@ -294,9 +294,11 @@ void FUN_L00_00276908(void) { } { struct GameState *state = &D_L00_001B9CF0; + s32 value; table = D_L00_0017E4D8; + value = *(s32 *)((u8 *)*(void **)(table + 0x18) + 0x74); D_0015EE78_gp = *(s32 *)state->pad18; - hud_send_resident_bank(0, *(s32 *)((u8 *)*(void **)(table + 0x18) + 0x74), 0); + hud_send_resident_bank(0, value, 0); } FUN_L00_00235310(2); if (*(s32 *)((u8 *)*(void **)(table + 0x18) + 0x80) != 0) { From f821f329bc312e305b696cfe32f04b70d84eee11 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:53:02 +0000 Subject: [PATCH 151/251] decomp: improve FUN_L05_00254058 --- src/overlays/shared/ui/help/00237488.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/ui/help/00237488.c b/src/overlays/shared/ui/help/00237488.c index 0413ad444..66f0909a6 100644 --- a/src/overlays/shared/ui/help/00237488.c +++ b/src/overlays/shared/ui/help/00237488.c @@ -1326,7 +1326,7 @@ void FUN_L05_00254058(void) { } { struct Hero *g = &hero; - table = *(struct ScoreTable *)D_L05_002169F8; + for (i = 0; i < 5; i++) table.values[i] = D_L05_002169F8[i]; *(f32 *)((char *)g + 0x6F4) = table.values[*(s32 *)((char *)g + 0x6F0)]; frames = FUN_001f96b0(1.0f); *(s32 *)((char *)g + 0x6FC) = truncate_float_to_s32((f32)((*(s32 *)((char *)g + 0x6F8) * 100) / (s32)(frames * 60.0f))); From 2c08ae61a8d9395c8c420e0813a5715de0891116 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:57:36 +0000 Subject: [PATCH 152/251] decomp: improve FUN_L02_00264e70 --- src/overlays/shared/gameplay/entities/00264e40.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/00264e40.c b/src/overlays/shared/gameplay/entities/00264e40.c index 637d3f75f..043b38dd4 100644 --- a/src/overlays/shared/gameplay/entities/00264e40.c +++ b/src/overlays/shared/gameplay/entities/00264e40.c @@ -87,9 +87,10 @@ void FUN_L02_00264e70(char *slots, float *position, float *direction, float dist shot = FUN_L00_0026b230(velocity, offset, i < first_count ? 1ULL : 0ULL, travel); if (i == 2 && *(volatile int *)&save_shot) { int j; - for (j = 0; j < 7; j++) { - if (((char **)slots)[j] == 0) { - ((char **)slots)[j] = shot; + char **slot = (char **)slots; + for (j = 0; j < 7; j++, slot++) { + if (*slot == 0) { + *slot = shot; break; } } From 7de26a03052b8be07681f71ef78f095e0b350e5b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:59:12 +0000 Subject: [PATCH 153/251] decomp: improve FUN_L00_002721f0 --- src/overlays/shared/rendering/002712b8.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/rendering/002712b8.c b/src/overlays/shared/rendering/002712b8.c index b74dfee59..c6d30cfc9 100644 --- a/src/overlays/shared/rendering/002712b8.c +++ b/src/overlays/shared/rendering/002712b8.c @@ -472,7 +472,8 @@ void FUN_L00_002721f0(unsigned char *p) { (*(unsigned int *)(p + 4) & 0xFFFFFF); r = (float *)(q + 0xC); *(volatile float *)&v[0] = *(float *)(q + 0xC); - *(volatile float *)&v[1] = r[1]; + t = *(volatile float *)&r[1]; + *(volatile float *)&v[1] = t; *(volatile float *)&v[2] = *(volatile float *)&r[2]; *(int *)&v[3] = 0; FUN_001f9a10_2721f0(p + 0x10, p + 0x10, &v); From 807a251e11749d7027d07cacd8a1c289fbfa3f9e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 18:58:01 +0000 Subject: [PATCH 154/251] decomp: improve draw_rope_strips --- src/overlays/l07/gameplay/entities/00312948.c | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/overlays/l07/gameplay/entities/00312948.c b/src/overlays/l07/gameplay/entities/00312948.c index bb3163060..ad254261c 100644 --- a/src/overlays/l07/gameplay/entities/00312948.c +++ b/src/overlays/l07/gameplay/entities/00312948.c @@ -1670,25 +1670,25 @@ void FUN_L07_00317910(void) { if (D_L07_00161B78 > 7.0f) D_L07_00161B78 -= 7.0f; row_offset = row * 0x140; for (column = 0; column < 20; column++) { - float end_phase = row_phase + column_step; - qcopy(packet.pos[0], (char *)&D_L07_0020DB00_c[14] + row_offset + (column << 4)); + float end_phase; + qcopy(packet.pos[0], (char *)&D_L07_0020DB00_c[14] + (row_offset + (column << 4))); next_column = (column + 1) % 20; - qcopy(packet.pos[1], (char *)&D_L07_0020DB00_c[14] + row_offset + (next_column << 4)); - qcopy(packet.pos[2], (char *)&D_L07_0020DAF0_c[-5] + row_offset + (column << 4)); - qcopy(packet.pos[3], (char *)&D_L07_0020DAF0_c[-5] + row_offset + (next_column << 4)); + qcopy(packet.pos[1], (char *)&D_L07_0020DB00_c[14] + (row_offset + (next_column << 4))); + qcopy(packet.pos[2], ((char *)&D_L07_0020DB00_c[14] - 0x140) + (row_offset + (column << 4))); + qcopy(packet.pos[3], ((char *)&D_L07_0020DB00_c[14] - 0x140) + (row_offset + (((column + 1) % 20) << 4))); + end_phase = row_phase + column_step; { - u32 previous = (u32)(u16)D_L07_0020DBC8[row - 1] << 16; - s32 current = D_L07_0020DBC8[row]; + u16 previous = D_L07_0020DBC8[row - 1]; + s64 current = D_L07_0020DBC8[row]; s32 j; u32 *color_out = packet.color; for (j = 1; j >= 0; j--) { - alpha = current; - if (alpha < 0) alpha = 0; - if (alpha > 64) alpha = 64; - color = ((u32)alpha << 24) | 0x404040; + if (current < 0) current = 0; + if (current > 64) current = 64; + color = ((u32)current << 24) | 0x404040; color_out[0] = color; color_out[1] = color; - current = (s32)previous >> 16; + current = (s16)previous; color_out += 2; } } From a085b9ceed2fb02503d30dc77a56ad1d880b53bf Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:01:53 +0000 Subject: [PATCH 155/251] decomp: improve FUN_L18_002f9eb8 --- src/overlays/l18/gameplay/vendor/002f88e8.c | 48 ++++++++------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/src/overlays/l18/gameplay/vendor/002f88e8.c b/src/overlays/l18/gameplay/vendor/002f88e8.c index 308cab9be..c7d3f36c3 100644 --- a/src/overlays/l18/gameplay/vendor/002f88e8.c +++ b/src/overlays/l18/gameplay/vendor/002f88e8.c @@ -588,9 +588,6 @@ void FUN_L18_002f9c20(struct Moby *m) { } draw_9c20(&pk, 0, 0); } -#ifndef NON_MATCHING -INCLUDE_ASM("config/us/overlays/asm/FUN_L18_002f9eb8.s", FUN_L18_002f9eb8); -#else extern float D_L18_0016252C_9eb8 __asm__("D_L18_0016252C"); extern float D_L18_00162514_9eb8 __asm__("D_L18_00162514") __attribute__((sda)); extern float D_L18_00162518_9eb8 __asm__("D_L18_00162518") __attribute__((sda)); @@ -604,8 +601,6 @@ void FUN_L18_002f9eb8(struct Moby *m) { float mat[4][4]; float up[4]; Vec4 vertices[4]; - float scale_z; - float scale_x; int i = 0; int color; @@ -626,8 +621,6 @@ void FUN_L18_002f9eb8(struct Moby *m) { norm_9c20(mat[2], mat[2], 1.0f); cross_9c20(mat[1], mat[0], mat[2]); - scale_z = D_L18_00162514_9eb8; - scale_x = D_L18_0016252C_9eb8; color = D_L18_00162504_9eb8 | 0xFF000000; pk.uv[0] = 1.0f; pk.uv[1] = 1.0f; @@ -644,10 +637,10 @@ void FUN_L18_002f9eb8(struct Moby *m) { pk.col[0] = color; i = 0; do { - qcopy(&vertices[i], D_L18_001DFBD0_9eb8[i]); + qcopy_nc(&vertices[i], D_L18_001DFBD0_9eb8[i]); { - vertices[i].f[2] *= scale_z; - vertices[i].f[0] *= scale_x; + vertices[i].f[2] *= D_L18_00162514_9eb8; + vertices[i].f[0] *= D_L18_0016252C_9eb8; } i++; } while (i < 4); @@ -656,19 +649,16 @@ void FUN_L18_002f9eb8(struct Moby *m) { } draw_9c20(&pk, 0, 0); - scale_z = D_L18_00162518_9eb8; - scale_x = D_L18_0016252C_9eb8; - color = D_L18_00162510_9eb8 | 0x7F000000; - pk.col[3] = color; - pk.col[2] = color; - pk.col[1] = color; - pk.col[0] = color; + pk.col[3] = D_L18_00162510_9eb8 | 0x7F000000; + pk.col[2] = pk.col[3]; + pk.col[1] = pk.col[3]; + pk.col[0] = pk.col[3]; i = 0; do { - qcopy(&vertices[i], D_L18_001DFBD0_9eb8[i]); + qcopy_nc(&vertices[i], D_L18_001DFBD0_9eb8[i]); { - vertices[i].f[2] *= scale_z; - vertices[i].f[0] *= scale_x; + vertices[i].f[2] *= D_L18_00162518_9eb8; + vertices[i].f[0] *= D_L18_0016252C_9eb8; } i++; } while (i < 4); @@ -677,19 +667,16 @@ void FUN_L18_002f9eb8(struct Moby *m) { } draw_9c20(&pk, 0, 0); - scale_z = D_L18_0016251C_9eb8; - scale_x = D_L18_0016252C_9eb8; - color = D_L18_00162510_9eb8 | 0x7F000000; - pk.col[3] = color; - pk.col[2] = color; - pk.col[1] = color; - pk.col[0] = color; + pk.col[3] = D_L18_00162510_9eb8 | 0x7F000000; + pk.col[2] = pk.col[3]; + pk.col[1] = pk.col[3]; + pk.col[0] = pk.col[3]; i = 0; do { - qcopy(&vertices[i], D_L18_001DFBD0_9eb8[i]); + qcopy_nc(&vertices[i], D_L18_001DFBD0_9eb8[i]); { - vertices[i].f[2] *= scale_z; - vertices[i].f[0] *= scale_x; + vertices[i].f[2] *= D_L18_0016251C_9eb8; + vertices[i].f[0] *= D_L18_0016252C_9eb8; } i++; } while (i < 4); @@ -698,7 +685,6 @@ void FUN_L18_002f9eb8(struct Moby *m) { } draw_9c20(&pk, 0, 0); } -#endif #define NOT_SDA #define MACRO_ADDR From 295e72b8aa0dfb995a64fee696628f9f60e81ae5 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:02:58 +0000 Subject: [PATCH 156/251] decomp: improve FUN_L06_00249738 --- src/overlays/shared/ui/text/00249738.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/ui/text/00249738.c b/src/overlays/shared/ui/text/00249738.c index 24e755ec0..e4ea792d8 100644 --- a/src/overlays/shared/ui/text/00249738.c +++ b/src/overlays/shared/ui/text/00249738.c @@ -26,11 +26,13 @@ s32 FUN_L06_00249738(u8 *p) { s32 center_x = D_L06_0015F8E8; f32 alpha, scaled_alpha, fill, step, limit; - if (pal_mode == 0) y = screen_y - 50; - if (current_level_index == 7 || current_level_index == 13) segments = 6; - if (current_level_index == 18) segments = 7; - if (p[0x70] != 0) { - if (current_level_index == 13) { + y = pal_mode ? screen_y - 42 : screen_y - 50; + screen_y = current_level_index; + if (screen_y == 7 || screen_y == 13) segments = 6; + if (screen_y == 18) segments = 7; + if (p[0x70] == 0) return *(s32 *)(p + 0x58); + { + if (screen_y == 13) { y = 18; if (pal_mode != 0) y = 10; } From 4088a842fedee46f68c3587531be3fcdb69ab4d6 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:06:00 +0000 Subject: [PATCH 157/251] decomp: improve FUN_L00_00276908 --- src/overlays/shared/audio/voices/00276368.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index 294e99364..220095166 100644 --- a/src/overlays/shared/audio/voices/00276368.c +++ b/src/overlays/shared/audio/voices/00276368.c @@ -342,8 +342,8 @@ void FUN_L00_00276908(void) { } D_L00_0015F5D8 = 1; { - u8 *table = D_L00_00173E40; - *(s32 *)(table + 0x10) &= 0x7fffffff; + s32 *table = (s32 *)D_L00_00173E40; + table[4] &= 0x7fffffff; } FUN_L00_002a08c8(); FUN_L00_002a09d8(1); From 4f9c5bbf2feb72c1ea57a7b7ad65ca2f59c15888 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:08:11 +0000 Subject: [PATCH 158/251] decomp: improve FUN_L11_003192c8 --- src/overlays/shared/gameplay/vendor/0030e690.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/0030e690.c b/src/overlays/shared/gameplay/vendor/0030e690.c index 1c53a61a3..736ec0b5c 100644 --- a/src/overlays/shared/gameplay/vendor/0030e690.c +++ b/src/overlays/shared/gameplay/vendor/0030e690.c @@ -450,7 +450,7 @@ int FUN_L11_003192c8(char *moby) { colors_base = (int *)(stack_data + 0x40); for (i = 0; i < 16; i++) { long long texture; - char *packet = stack_data + 0x40 + i * 0x90; + long long *packet = (long long *)(stack_data + 0x70); float *source; float *position; float *position_y; @@ -459,10 +459,10 @@ int FUN_L11_003192c8(char *moby) { int j; j = 0; texture = trail_effect_texture(0x13); - *(long long *)(packet + 0x38) = texture; - *(long long *)(packet + 0x48) = 0x8000000048LL; - *(long long *)(packet + 0x40) = 0xff9000000260LL; - *(long long *)(packet + 0x30) = 0; + packet[i * 18 + 1] = texture; + packet[i * 18 + 3] = 0x8000000048LL; + packet[i * 18 + 2] = 0xff9000000260LL; + packet[i * 18] = 0; span = *(float *)&D_L11_001623F0_d * 4.0f; phase = integer_to_float((D_L11_0015F5CC + 3) & 3) / span; source = D_L11_001F1490; From 61f65a2981ddc9d808bb621e226fc56fdb380e18 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:08:14 +0000 Subject: [PATCH 159/251] decomp: improve FUN_L10_002dcc58 --- src/overlays/l10/gameplay/entities/00295a38.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/l10/gameplay/entities/00295a38.c b/src/overlays/l10/gameplay/entities/00295a38.c index 6b2882a25..331e1fe98 100644 --- a/src/overlays/l10/gameplay/entities/00295a38.c +++ b/src/overlays/l10/gameplay/entities/00295a38.c @@ -2108,7 +2108,8 @@ extern void FUN_L10_0024a7f0(float, float, void *) __asm__("FUN_L00_00257d78"); void FUN_L10_002dcc58(struct Moby *moby) { char *data = (char *)moby->pvars; float scratch[0xC80 / 4]; - int group, item; + int group; + long item; float phase; switch (moby->state) { From 097f47defab4a59b6d72630c8916645eae03d8fe Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:12:12 +0000 Subject: [PATCH 160/251] decomp: improve FUN_L00_002dd8e8 --- src/overlays/shared/gameplay/entities/002d7f88.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002d7f88.c b/src/overlays/shared/gameplay/entities/002d7f88.c index 82a663db4..279617b1e 100644 --- a/src/overlays/shared/gameplay/entities/002d7f88.c +++ b/src/overlays/shared/gameplay/entities/002d7f88.c @@ -2659,11 +2659,11 @@ void FUN_L00_002dd8e8(void) { current = row * 0x140; prior = D_L00_001E5EE0_002dd8e8; for (segment = 0; segment < 20; segment++) { - qcopy(&quad.points[0], D_L00_001E6020_002dd8e8 + current + segment * 16); + qcopy(&quad.points[0], D_L00_001E6020_002dd8e8 + (current + segment * 16)); next_segment = (segment + 1) % 20; - qcopy(&quad.points[1], D_L00_001E6020_002dd8e8 + current + next_segment * 16); - qcopy(&quad.points[2], prior + current + segment * 16); - qcopy(&quad.points[3], prior + current + next_segment * 16); + qcopy(&quad.points[1], D_L00_001E6020_002dd8e8 + (current + next_segment * 16)); + qcopy(&quad.points[2], prior + (current + segment * 16)); + qcopy(&quad.points[3], prior + (current + next_segment * 16)); FUN_001ff2a8_002dd8e8(&edge, &quad.points[0], &quad.points[1]); FUN_001ff2a8_002dd8e8(&outward, &quad.points[2], &quad.points[1]); FUN_001ff3c0_002dd8e8(&normal, &outward, &edge); From a9713a98f9e62fbdd199386d27d0f6df4af96efe Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:14:33 +0000 Subject: [PATCH 161/251] decomp: improve FUN_L05_002f87a8 --- src/overlays/shared/gameplay/entities/002b3840.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b3840.c b/src/overlays/shared/gameplay/entities/002b3840.c index 1e5640a1e..5a12b993c 100644 --- a/src/overlays/shared/gameplay/entities/002b3840.c +++ b/src/overlays/shared/gameplay/entities/002b3840.c @@ -256,6 +256,7 @@ void FUN_L05_002f81b8(void *mv) { #ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L05_002f87a8.s", FUN_L05_002f87a8); #else +#include "rnc/gameplay/state/item_state.h" extern int scale_game_frames_87a8(int) __asm__("FUN_001f96f8"); extern void add_vector_xyz_87a8(void *, void *, void *) __asm__("FUN_001f9a10"); extern void subtract_vector_xyz_87a8(void *, void *, void *) __asm__("FUN_001f9a28"); @@ -270,7 +271,7 @@ extern void get_moby_position_87a8(void *, int, void *) __asm__("FUN_L00_0024f7c extern int random_int_between_87a8(int, int) __asm__("FUN_L00_00257b90"); extern float random_angle_radians_87a8(void) __asm__("FUN_00213308"); extern void spawn_effect_87a8(void *, void *, int, int, int, int, int, int) __asm__("FUN_L00_00269958"); -extern void spawn_second_effect_87a8(float, void *, void *, int, int, int, int) __asm__("FUN_L00_0026cbb0"); +extern void spawn_second_effect_87a8(void *, void *, int, int, int, int, float) __asm__("FUN_L00_0026cbb0"); extern void FUN_L05_0024cee8_87a8(int, int) __asm__("FUN_L05_0024cee8"); extern int D_0014F5CC_87a8 __asm__("D_0014F5CC") __attribute__((sda)); extern int D_00151928_87a8 __asm__("D_00151928") __attribute__((sda)); @@ -282,29 +283,31 @@ void FUN_L05_002f87a8(unsigned char *moby) { float delta[4], position[4], effect_position[4], offset[4], second_position[4]; float angle, distance_scale, delta_length; int state = (u8)moby[0x20]; - struct Hero *g = &hero; + struct Hero *g; switch (state) { case 0: + g = &hero; if (distance_xyz_87a8(&g->motion.pos, moby + 0x10) < 5.5f && D_0014F5CC_87a8 > 3 && g->state.control_mode != 0x15 && g->state.control_mode != 0x16) { g->unk86C = moby; FUN_L05_0024cee8_87a8(0x6b, 1); if (*(int *)(data + 0x50) == 0) { - qcopy(data + 0x10, moby + 0x10); + *(u128 *)(data + 0x10) = *(u128 *)(moby + 0x10); } moby[0x20] = 1; *(unsigned char *)(moby + 0x30) = 0xff; } break; case 1: - if (*(int *)(data + 0x50) == 0 && *(unsigned char *)0x13d388 != 0 && + if (*(int *)(data + 0x50) == 0 && alternate_item_available[0] != 0 && *(unsigned short *)0x141938 == 0 && *(int *)0x15f6a8 != 0 && - scale_game_frames_87a8(0x4b0) < g->unk19C && + scale_game_frames_87a8(0x4b0) < (g = &hero)->unk19C && *(unsigned short *)0x141c60 == 0) { play_sound_87a8(0x138f, 0x5f); } + g = &hero; if (g->state.control_mode != 0x16) { moby[0x30] = 0x10; if (*(int *)(data + 0x50) == 0) { @@ -345,7 +348,7 @@ void FUN_L05_002f87a8(unsigned char *moby) { } { int size = random_int_between_87a8(scale_game_frames_87a8(8), scale_game_frames_87a8(17)); - spawn_second_effect_87a8(15000.0f, position, effect_position, D_0015190C_87a8, D_00151910_87a8, size, 1); + spawn_second_effect_87a8(position, effect_position, D_0015190C_87a8, D_00151910_87a8, size, 1, 15000.0f); } } moby[0xbc] = 0; From af9bf02e0903f5ef098fd4c820f9d6fc2ed1a775 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:15:45 +0000 Subject: [PATCH 162/251] decomp: improve FUN_L05_00254058 --- src/overlays/shared/ui/help/00237488.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/ui/help/00237488.c b/src/overlays/shared/ui/help/00237488.c index 66f0909a6..ea17546d5 100644 --- a/src/overlays/shared/ui/help/00237488.c +++ b/src/overlays/shared/ui/help/00237488.c @@ -1274,7 +1274,8 @@ void FUN_L05_00254058(void) { stats->stat[30].level_mask |= 0x80000000; } { - counter = (s32 *)((char *)&hero + 0x700); + counter = (s32 *)((char *)&hero + 0x6D0); + counter += 12; for (i = 2; i >= 0; i--, counter++) { if (absolute_float(*(f32 *)(counter - 12)) > 3.3161256f) { f32 rotation = *(f32 *)(counter - 12); @@ -1290,7 +1291,7 @@ void FUN_L05_00254058(void) { struct Hero *g = &hero; *(s32 *)((char *)g + 0x70C) = 0; { - counter = (s32 *)((char *)g + 0x700); + s32 *counter = (s32 *)((char *)g + 0x700); i = 2; do { if (*(s32 *)((char *)g + 0x70C) < *counter) @@ -1326,7 +1327,7 @@ void FUN_L05_00254058(void) { } { struct Hero *g = &hero; - for (i = 0; i < 5; i++) table.values[i] = D_L05_002169F8[i]; + table = *(struct ScoreTable *)D_L05_002169F8; *(f32 *)((char *)g + 0x6F4) = table.values[*(s32 *)((char *)g + 0x6F0)]; frames = FUN_001f96b0(1.0f); *(s32 *)((char *)g + 0x6FC) = truncate_float_to_s32((f32)((*(s32 *)((char *)g + 0x6F8) * 100) / (s32)(frames * 60.0f))); From b604d7b4b01a77651b18ddc6f9d877bad69f7911 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:16:16 +0000 Subject: [PATCH 163/251] decomp: improve FUN_L10_002f5b58 --- src/overlays/shared/gameplay/vendor/002e3de8.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index 4d63a3026..998118539 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -255,6 +255,7 @@ extern int hero_set_state(int, int) __asm__("FUN_L00_002223f8"); extern float D_L10_0016CF70; extern char D_L10_00167100[]; +extern char D_L10_0016CEC0[]; void FUN_L10_002f5b58(char *moby) { char *data = *(char **)(D_L10_0015EF50 + *(short *)(moby + 0x84) * 0x20 + 0x1c); char *work; @@ -298,7 +299,7 @@ void FUN_L10_002f5b58(char *moby) { moby_scale = moby + 0x30; moby_pos = moby + 0x10; moby_rot = moby + 0x20; - angle = angle_atan2(1.0f, D_L10_0016CF70); + angle = angle_atan2(1.0f, *(float *)(D_L10_0016CEC0 + 0xb0)); *(float *)((char *)indices + 0x30) = angle + angle; if (*(int *)(data + 0x20) >= 0) { From debbc48eaa3e3b13a496209cbecfffd4b6c9bb0c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:20:53 +0000 Subject: [PATCH 164/251] decomp: improve FUN_L07_0030dcf0 --- src/overlays/l07/gameplay/entities/002cd2b0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/l07/gameplay/entities/002cd2b0.c b/src/overlays/l07/gameplay/entities/002cd2b0.c index b614646bd..15a6dccf5 100644 --- a/src/overlays/l07/gameplay/entities/002cd2b0.c +++ b/src/overlays/l07/gameplay/entities/002cd2b0.c @@ -2011,7 +2011,7 @@ void FUN_L07_0030dcf0(unsigned char *moby) { width = convert_integer_to_float_l07((int)(index + 1) > 5 ? 5 : index + 1); green = green - green_step; center = *(float *)(moby + 0x10); - *(float *)(packet + 0x38) = *(float *)(packet + 0x28) = *(float *)(moby + 0x18); + *(float *)(packet + 0x28) = *(float *)(packet + 0x38) = *(float *)(moby + 0x18); *(float *)(packet + 0x30) = center - radius; *(float *)(packet + 0x68) = *(float *)(packet + 0x58) = *(float *)(packet + 0x50) + width; *(float *)(packet + 0x34) = *(float *)(packet + 0x14) = *(float *)(moby + 0x14); From 49beb17873057c1fda71a7f162b8c2095a7a5244 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:21:13 +0000 Subject: [PATCH 165/251] decomp: improve FUN_L00_00275aa0 --- src/overlays/shared/rendering/002712b8.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/rendering/002712b8.c b/src/overlays/shared/rendering/002712b8.c index c6d30cfc9..a93fd6e88 100644 --- a/src/overlays/shared/rendering/002712b8.c +++ b/src/overlays/shared/rendering/002712b8.c @@ -2018,7 +2018,8 @@ void FUN_L00_00275aa0(unsigned char *m) { originalAlpha = q[0xb]; h = originalAlpha; h = (unsigned int)h >> 1; - alpha = (float)(h - originalAlpha); + h -= originalAlpha; + alpha = (float)h; alpha *= f; alpha = (float)originalAlpha + alpha; } else { From eb8a255c3ebb61f0505bef706dfe3b63e786f097 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:27:24 +0000 Subject: [PATCH 166/251] decomp: improve FUN_L00_0020f160 --- src/overlays/shared/ui/help/0020c758.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index 930941d7a..d51d775c1 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -1360,7 +1360,7 @@ void FUN_L00_0020f160(void *moby, void *matrix) record = records + (*(volatile s32 *)hero_ptr->pad_21B8) * 0x30; normalize_vector_triplet(record); ring = (*(volatile s32 *)hero_ptr->pad_21B8) + 1; - (*(volatile s32 *)hero_ptr->pad_21B8) = ring % 16; + (*(s32 *)hero_ptr->pad_21B8) = ring % 16; (*(s32 *)(hero_ptr->pad_21B8 + 4))++; if ((*(s32 *)(hero_ptr->pad_21B8 + 4)) > 16) (*(s32 *)(hero_ptr->pad_21B8 + 4)) = 16; From 2e83dbdd83c2c35094cf81aced09dd6918b753bd Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:29:04 +0000 Subject: [PATCH 167/251] decomp: improve FUN_L14_002de670 --- src/overlays/shared/gameplay/entities/002b17d8.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b17d8.c b/src/overlays/shared/gameplay/entities/002b17d8.c index f4cd1dd49..0e83bdf0f 100644 --- a/src/overlays/shared/gameplay/entities/002b17d8.c +++ b/src/overlays/shared/gameplay/entities/002b17d8.c @@ -943,6 +943,8 @@ void FUN_L14_002de670(struct Moby *moby) { s32 n; s32 alpha; s32 color; + s32 particle_type; + s32 fade_mode; f32 size; f32 absolute_velocity; u8 *particle; @@ -988,6 +990,8 @@ void FUN_L14_002de670(struct Moby *moby) { return; particles: alpha = 0x60000000; + particle_type = 0x44; + fade_mode = 2; FUN_L00_0026cbb0_de670(position, D_L14_0015F580, 0x4F007FFF, 0x1FFFFFFF, FUN_L00_00257b90(FUN_001f96f8(10), FUN_001f96f8(20)), 1, 60000.0f); for (i = 1; i >= 0; --i) { @@ -999,10 +1003,10 @@ void FUN_L14_002de670(struct Moby *moby) { D_L14_0015F580, size, color | ((color << 16) | ((color << 8) | alpha))); if (particle != 0) { - particle[3] = 0x44; + particle[3] = particle_type; fade = particle + 0x20; *(s16 *)(particle + 0xA) = FUN_001f96f8(0x3C); - *(s32 *)(fade + 4) = 2; + *(s32 *)(fade + 4) = fade_mode; fade[0xA] = 0x60; fade[0xB] = particle[0xA]; } From 41873a84a77882d02d76d50215399828383d9e79 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:29:21 +0000 Subject: [PATCH 168/251] decomp: improve FUN_L00_002dd8e8 --- src/overlays/shared/gameplay/entities/002d7f88.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002d7f88.c b/src/overlays/shared/gameplay/entities/002d7f88.c index 279617b1e..9f99346a6 100644 --- a/src/overlays/shared/gameplay/entities/002d7f88.c +++ b/src/overlays/shared/gameplay/entities/002d7f88.c @@ -2636,6 +2636,7 @@ void FUN_L00_002dd8e8(void) { Quad_002dd8e8 quad; u128 following, edge, outward, normal; float phase, next_phase, offset, step, dot; + float previous_phase; int row, segment, next_segment, value, previous_value; int current; char *prior; @@ -2673,6 +2674,8 @@ void FUN_L00_002dd8e8(void) { offset += step; continue; } + previous_phase = phase - 0.3f; + dot = offset + step; value = ((short *)(D_L00_001E6020_002dd8e8 - 0x18))[row]; previous_value = ((short *)(D_L00_001E6020_002dd8e8 - 0x18))[row - 1]; if (value < 0) value = 0; @@ -2685,14 +2688,13 @@ void FUN_L00_002dd8e8(void) { quad.colors[2] = quad.colors[3] = 0x20404040; else if (row == 9) quad.colors[0] = quad.colors[1] = 0x00404040; - dot = offset + step; quad.texcoords[0] = phase; quad.texcoords[1] = offset; quad.texcoords[2] = phase; quad.texcoords[3] = dot; - quad.texcoords[4] = phase - 0.3f; + quad.texcoords[4] = previous_phase; quad.texcoords[5] = offset; - quad.texcoords[6] = phase - 0.3f; + quad.texcoords[6] = previous_phase; quad.texcoords[7] = dot; offset = dot; FUN_001fd228_002dd8e8(&quad, 0, 0); From a1eb545475ab3de987c216c1317e01aa738fb12a Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:31:05 +0000 Subject: [PATCH 169/251] decomp: improve FUN_L11_003192c8 --- src/overlays/shared/gameplay/vendor/0030e690.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/0030e690.c b/src/overlays/shared/gameplay/vendor/0030e690.c index 736ec0b5c..64eecd193 100644 --- a/src/overlays/shared/gameplay/vendor/0030e690.c +++ b/src/overlays/shared/gameplay/vendor/0030e690.c @@ -432,6 +432,7 @@ int FUN_L11_003192c8(char *moby) { float offset[8] __attribute__((aligned(16))); short *list; int i; + short *next_list; float phase; float *position_base; float *position_y_base; @@ -445,8 +446,8 @@ int FUN_L11_003192c8(char *moby) { } else { *(float *)&D_L11_001623F0_d = 5.0f; } - position_base = (float *)(stack_data + 0x50); position_y_base = (float *)(stack_data + 0x54); + position_base = (float *)(stack_data + 0x50); colors_base = (int *)(stack_data + 0x40); for (i = 0; i < 16; i++) { long long texture; @@ -488,6 +489,7 @@ int FUN_L11_003192c8(char *moby) { char *linked = (char *)(D_L11_0015FFD8 + ((entry & 0x7fff) << 8)); int skip = *(short *)(linked + 0xa6) != *(short *)(moby + 0xa6); if (*(unsigned char *)(linked + 0x31) == 0) skip = 1; + next_list = list + 1; if (skip == 0) { char *trail = *(char **)(linked + 0x78); long limit = -1; @@ -515,7 +517,8 @@ int FUN_L11_003192c8(char *moby) { } } } - if (*list++ < 0) break; + if (*list < 0) break; + list = next_list; } while (1); } #endif From 4dd58ad75e10277c7b687b8d6885d44c2639f971 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:32:53 +0000 Subject: [PATCH 170/251] decomp: improve FUN_L07_0030dcf0 --- src/overlays/l07/gameplay/entities/002cd2b0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/l07/gameplay/entities/002cd2b0.c b/src/overlays/l07/gameplay/entities/002cd2b0.c index 15a6dccf5..64b305992 100644 --- a/src/overlays/l07/gameplay/entities/002cd2b0.c +++ b/src/overlays/l07/gameplay/entities/002cd2b0.c @@ -2012,7 +2012,6 @@ void FUN_L07_0030dcf0(unsigned char *moby) { green = green - green_step; center = *(float *)(moby + 0x10); *(float *)(packet + 0x28) = *(float *)(packet + 0x38) = *(float *)(moby + 0x18); - *(float *)(packet + 0x30) = center - radius; *(float *)(packet + 0x68) = *(float *)(packet + 0x58) = *(float *)(packet + 0x50) + width; *(float *)(packet + 0x34) = *(float *)(packet + 0x14) = *(float *)(moby + 0x14); *(float *)(packet + 0x6c) = *(float *)(packet + 0x64) = 1.0f; @@ -2020,6 +2019,7 @@ void FUN_L07_0030dcf0(unsigned char *moby) { *(float *)(packet + 0x08) = *(float *)(packet + 0x18) = side + *(float *)(moby + 0x18); *(float *)(packet + 0x10) = center - radius * (inner_scale - band * 0.03f); *(float *)(packet + 0x54) = 0.0f; + *(float *)(packet + 0x30) = center - radius; __builtin_memcpy(second, packet, 0x90); *(float *)(second + 8) = *(float *)(second + 0x18) = *(float *)(moby + 0x18) - 5.0f; angle = -2.8274336f; From 9bdc365ea4f6e055403888e8664fb326e172eaa8 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:36:18 +0000 Subject: [PATCH 171/251] decomp: improve FUN_L06_002d8738 --- src/overlays/shared/gameplay/entities/00297d10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/00297d10.c b/src/overlays/shared/gameplay/entities/00297d10.c index 8c85a7942..66f64cbe7 100644 --- a/src/overlays/shared/gameplay/entities/00297d10.c +++ b/src/overlays/shared/gameplay/entities/00297d10.c @@ -276,7 +276,7 @@ void FUN_L06_002d8738(char *moby) { float (*corner)[4] = quad.corner; float *uvOut = &quad.uv[0][0]; float *uvOutSecond = &quad.uv[0][1]; - for (j = 3; j >= 0; corner++, uvOutSecond += 2, uvOut += 2, j--, indices += 2) { + for (; corner != quad.corner + 4; uvOutSecond += 2, uvOut += 2, corner++, indices += 2) { short vertex = indices[0]; qcopy(corner, D_L06_001D4530[vertex]); if (near) { From 1355144954db63920c07a1db8d36bcfc43fc3587 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:43:36 +0000 Subject: [PATCH 172/251] decomp: improve FUN_L10_002e91b8 --- .../shared/gameplay/vendor/002e3de8.c | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index 998118539..9361c45fe 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -110,34 +110,48 @@ extern int D_L10_00161F50[2] __attribute__((sda)); extern int D_L10_00161F58[2] __attribute__((sda)); extern int D_L10_00161F60[2] __attribute__((sda)); +#include "qcopy.h" +extern float D_L10_001DA350[]; +extern float D_L10_001DA310[]; +extern int D_L10_001DA250[]; +extern float D_L10_001DA270[]; +extern int D_L10_001DA2B0[]; +extern float D_L10_001DA2F0[]; void FUN_L10_002e91b8(unsigned char *m) { unsigned char first[0x90] __attribute__((aligned(16))); unsigned char second[0x90] __attribute__((aligned(16))); float matrix[12] __attribute__((aligned(16))); float position[4] __attribute__((aligned(16))); float *scale = *(float **)(m + 0x78); - float *first_source = (float *)0x001da350; - float *second_source = (float *)0x001da310; - float *first_vectors = (float *)first; - float *second_vectors = (float *)second; + float *first_source; + float *second_source; + float *first_vectors; + float *second_vectors; + float *second_angles; int i, k; unsigned int j; copy_matrix(matrix, m + 0xc0); - *(aligned_vector *)position = *(aligned_vector *)(m + 0x10); + qcopy(position, m + 0x10); position[3] = 1.0f; - *(long long *)(first + 0x70) = 0; *(long long *)(first + 0x78) = trail_effect_texture(0x2c); *(long long *)(first + 0x80) = 0xff9000000260LL; - *(long long *)(second + 0x70) = 0; + *(long long *)(first + 0x70) = 0; *(long long *)(second + 0x78) = trail_effect_texture(0x2c); *(long long *)(second + 0x80) = 0xff9000000260LL; - *(int *)(second + 0x44) = 0; + *(long long *)(second + 0x70) = 0; *(int *)(second + 0x4c) = 0; + *(int *)(second + 0x44) = 0; + first_source = D_L10_001DA350; + second_source = D_L10_001DA310; + first_vectors = (float *)first; + second_vectors = (float *)second; + second_angles = (float *)second; i = 3; do { - *(aligned_vector *)first_vectors = *(aligned_vector *)first_source; - *(aligned_vector *)second_vectors = *(aligned_vector *)second_source; + qcopy(first_vectors, first_source); + qcopy(second_angles, second_source); + second_angles += 4; first_source += 4; second_source += 4; first_vectors[0] *= scale[0]; @@ -156,7 +170,7 @@ void FUN_L10_002e91b8(unsigned char *m) { ((long long)D_L10_00161F50[parity] << 2) | ((long long)D_L10_00161F58[parity] << 4) | ((long long)D_L10_00161F60[parity] << 6) | 0x8000000000ULL; - int shade = ((int *)0x001da250)[i]; + int shade = (D_L10_001DA250)[i]; float *angles = (float *)(first + 0x58); float *offsets = (float *)(first + 0x68); float *first_angles = (float *)(second + 0x50); @@ -175,16 +189,18 @@ void FUN_L10_002e91b8(unsigned char *m) { ((int *)(first + 0x40))[2] = shade; ((int *)(first + 0x40))[1] = shade; for (j = 0; j < 4; j++) { + float *first_vectors = (float *)(first + 0x50) + j * 2; + float *first_source = D_L10_001DA2F0 + j * 2; for (k = 0; k != 2; k++) { int index = i * 2 + k; - int limit = float_to_integer(((float *)0x001da270)[index] * 360.0f); - float angle = integer_to_float(*(int *)0x0015f3f8 % limit) / ((float *)0x001da270)[index] - 180.0f; + int limit = float_to_integer((D_L10_001DA270)[index] * 360.0f); + float angle = integer_to_float(*(int *)0x0015f3f8 % limit) / (D_L10_001DA270)[index] - 180.0f; float wave; - if (((int *)0x001da2b0)[index] != 0) + if ((D_L10_001DA2B0)[index] != 0) wave = FUN_001f9dc8(angle * 0.017453292f); else wave = FUN_001f9de0(angle * 0.017453292f); - ((float *)(first + 0x50))[j * 2 + k] = ((float *)0x001da2f0)[j * 2 + k] + wave * 0.125f; + *first_vectors++ = *first_source++ + wave * 0.125f; } } for (j = 0; j < 2; j++) { From aadfd2851a9b5f9f4181c54a67fd6ccc32ad7baa Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:44:44 +0000 Subject: [PATCH 173/251] decomp: improve FUN_L00_002dd8e8 --- src/overlays/shared/gameplay/entities/002d7f88.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002d7f88.c b/src/overlays/shared/gameplay/entities/002d7f88.c index 9f99346a6..ef12f9ebb 100644 --- a/src/overlays/shared/gameplay/entities/002d7f88.c +++ b/src/overlays/shared/gameplay/entities/002d7f88.c @@ -2638,7 +2638,7 @@ void FUN_L00_002dd8e8(void) { float phase, next_phase, offset, step, dot; float previous_phase; int row, segment, next_segment, value, previous_value; - int current; + int current, segment_offset; char *prior; quad.texture[1] = FUN_001f9298_002dd8e8(0x15); @@ -2660,10 +2660,11 @@ void FUN_L00_002dd8e8(void) { current = row * 0x140; prior = D_L00_001E5EE0_002dd8e8; for (segment = 0; segment < 20; segment++) { - qcopy(&quad.points[0], D_L00_001E6020_002dd8e8 + (current + segment * 16)); + segment_offset = segment * 16; + qcopy(&quad.points[0], D_L00_001E6020_002dd8e8 + (current + segment_offset)); next_segment = (segment + 1) % 20; qcopy(&quad.points[1], D_L00_001E6020_002dd8e8 + (current + next_segment * 16)); - qcopy(&quad.points[2], prior + (current + segment * 16)); + qcopy(&quad.points[2], prior + (current + segment_offset)); qcopy(&quad.points[3], prior + (current + next_segment * 16)); FUN_001ff2a8_002dd8e8(&edge, &quad.points[0], &quad.points[1]); FUN_001ff2a8_002dd8e8(&outward, &quad.points[2], &quad.points[1]); From 71935daba4ee4640d581673bf217c6a7b5bc021b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:46:28 +0000 Subject: [PATCH 174/251] decomp: improve FUN_L05_002f87a8 --- src/overlays/shared/gameplay/entities/002b3840.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b3840.c b/src/overlays/shared/gameplay/entities/002b3840.c index 5a12b993c..6fb51b65a 100644 --- a/src/overlays/shared/gameplay/entities/002b3840.c +++ b/src/overlays/shared/gameplay/entities/002b3840.c @@ -307,8 +307,7 @@ void FUN_L05_002f87a8(unsigned char *moby) { *(unsigned short *)0x141c60 == 0) { play_sound_87a8(0x138f, 0x5f); } - g = &hero; - if (g->state.control_mode != 0x16) { + if (hero.state.control_mode != 0x16) { moby[0x30] = 0x10; if (*(int *)(data + 0x50) == 0) { qcopy(moby + 0x10, data + 0x10); From 7d3b21d7edd2a3bfdf184f5d01edecfc61732e44 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:47:30 +0000 Subject: [PATCH 175/251] decomp: improve FUN_L07_0031d2e0 --- src/overlays/l07/gameplay/vendor/0031d2e0.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/overlays/l07/gameplay/vendor/0031d2e0.c b/src/overlays/l07/gameplay/vendor/0031d2e0.c index 8beeaa2d4..6efd575d2 100644 --- a/src/overlays/l07/gameplay/vendor/0031d2e0.c +++ b/src/overlays/l07/gameplay/vendor/0031d2e0.c @@ -59,8 +59,7 @@ void FUN_L07_0031d2e0(char *moby) { data[8] = 0; path = D_L07_001B0530[path_index]; count = *(int *)path; - i = 0; - if (count > 0) do { + for (i = 0; i < count; i++) { char *current_path = D_L07_001B0530[path_index]; int next = (i + 1) % *(int *)current_path; float length = fast_vec_dist(current_path + 0x10 + i * 0x10, @@ -69,8 +68,7 @@ void FUN_L07_0031d2e0(char *moby) { *(float *)(data + 8) += *(float *)(D_L07_001B0530[data[1]] + 0x1c + i * 0x10); path_index = data[1]; count = *(int *)D_L07_001B0530[path_index]; - i++; - } while (i < count); + } moby[0x20] = 1; } From 96ff4aee98a2637d40647b8d831f2f5a81c488d8 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:50:48 +0000 Subject: [PATCH 176/251] decomp: improve FUN_L08_002d3878 --- src/overlays/shared/gameplay/entities/002937a0.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002937a0.c b/src/overlays/shared/gameplay/entities/002937a0.c index 656a4a6ce..9b5e45c1f 100644 --- a/src/overlays/shared/gameplay/entities/002937a0.c +++ b/src/overlays/shared/gameplay/entities/002937a0.c @@ -389,7 +389,7 @@ extern float vector_length_xy_002d3878(void *) __asm__("FUN_001f9b20"); extern float angle_atan2_002d3878(float, float) __asm__("FUN_001f9e90"); extern void make_matrix_002d3878(void *, void *) __asm__("FUN_001fa050"); extern void FUN_001f7d30_002d3878(void *, void *, int) __asm__("FUN_001f7d30"); -extern float D_L08_00161894_002d3878 __asm__("D_L08_00161894"); +extern float D_L08_00161894_002d3878 __asm__("D_L08_00161894") __attribute__((section(".data"))); extern u32 D_00151878_002d3878 __asm__("D_00151878") __attribute__((sda)); extern u32 D_0015187C_002d3878 __asm__("D_0015187C") __attribute__((sda)); extern u32 D_00151880_002d3878 __asm__("D_00151880") __attribute__((sda)); @@ -445,10 +445,9 @@ void FUN_L08_002d3878(char *m) { pk.vertices[3].v[2] += 0.25f; pk.vertices[3].v[3] = 1.0f; FUN_001f7d30_002d3878(pk.vertices, matrix, 1); { - float *v = pk.vertices[1].v; - for (i = 1; i < 4; i += 2, v += 8) { - if (i < 2) { v[1] += -0.25f; v[2] += 0.25f; } - else { v[1] += 0.25f; v[2] += -0.25f; } + for (i = 1; i < 4; i += 2) { + if (i < 2) { pk.vertices[i].v[1] += -0.25f; pk.vertices[i].v[2] += 0.25f; } + else { pk.vertices[i].v[1] += 0.25f; pk.vertices[i].v[2] += -0.25f; } } } FUN_001f7d30_002d3878(pk.vertices, matrix, 1); @@ -489,8 +488,8 @@ void FUN_L08_002d3878(char *m) { pk.vertices[3].v[2] = 0.0f; pk.vertices[3].v[3] = 1.0f; FUN_001f7d30_002d3878(pk.vertices, matrix, 1); { - float *v = pk.vertices[0].v; - for (i = 0; i < 4; i += 2, v += 8) { + float *v; + for (i = 0, v = pk.vertices[0].v; i < 4; i += 2, v += 8) { if (i < 2) { v[1] += -0.25f; v[2] += 0.25f; } else { v[1] += 0.25f; v[2] += -0.25f; } } From 4bc5c55df56d626afc3bc27e8a51c9e19be85ffc Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:50:51 +0000 Subject: [PATCH 177/251] decomp: improve update_help_effect --- src/overlays/shared/ui/help/00203b18.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/ui/help/00203b18.c b/src/overlays/shared/ui/help/00203b18.c index 9330d7214..d5ab2d13d 100644 --- a/src/overlays/shared/ui/help/00203b18.c +++ b/src/overlays/shared/ui/help/00203b18.c @@ -446,9 +446,9 @@ void FUN_L00_002059d8(void) { u8 *dst_a = g + 0xF00; u8 *dst_b = g + 0xF10; u8 *dst_c = g + 0xF20; + Quad_59d8 *src_c = (Quad_59d8 *)D_L00_0017C260_2059d8; Quad_59d8 *src_a = (Quad_59d8 *)D_L00_0017C1E0_2059d8; Quad_59d8 *src_b = (Quad_59d8 *)D_L00_0017C220_2059d8; - Quad_59d8 *src_c = (Quad_59d8 *)D_L00_0017C260_2059d8; s32 *kind = (s32 *)0x140AF8; for (i = 0; i < 4; i++, dst_c += 0x40, src_c++, src_a++, src_b++, dst_a += 0x40, kind++, From 02f6020c77b6ef834b8c54016b79990997253da7 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:51:12 +0000 Subject: [PATCH 178/251] decomp: improve FUN_L14_002dfd10 --- src/overlays/shared/gameplay/entities/002b17d8.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b17d8.c b/src/overlays/shared/gameplay/entities/002b17d8.c index 0e83bdf0f..4adba4fe0 100644 --- a/src/overlays/shared/gameplay/entities/002b17d8.c +++ b/src/overlays/shared/gameplay/entities/002b17d8.c @@ -1094,6 +1094,7 @@ void FUN_L14_002dfd10(struct Moby *moby) { float absolute_velocity; void *path; float one; + int one_bits; float zero; if (moby->state == 0) { @@ -1111,7 +1112,8 @@ void FUN_L14_002dfd10(struct Moby *moby) { normalize_vector_xyz(vec, vec, zero); qcopy(path_position, position); pos[2] += 0.25f; - *(int *)&one = 0x3f800000; + one_bits = 0x3f800000; + one = *(float *)&one_bits; zero = 0.0f; FUN_L00_0028dc90(1, 0, moby, *(short *)(*(char **)data + 0xa6)); FUN_L00_0025e450(moby, vec, path_position, zero, zero, 5, 2, 4, @@ -1147,7 +1149,8 @@ void FUN_L14_002dfd10(struct Moby *moby) { goto random_check; } } - *(int *)&one = 0x3f800000; + one_bits = 0x3f800000; + one = *(float *)&one_bits; FUN_L00_0028dc90(0, 0, moby, *(short *)(*(char **)data + 0xa6)); FUN_L00_0025e450(moby, velocity, position, zero, zero, 5, 2, 4, one, 0.5f, 9.0f, one, -1, 15.0f, 0, 3, -1, 0); From c2a9b4fa56ae16fc781bf2ff27b91e24e4275baf Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:53:25 +0000 Subject: [PATCH 179/251] decomp: improve FUN_L01_002b91c8 --- .../shared/gameplay/entities/002b8c08.c | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b8c08.c b/src/overlays/shared/gameplay/entities/002b8c08.c index 0b7c34299..176f78dfb 100644 --- a/src/overlays/shared/gameplay/entities/002b8c08.c +++ b/src/overlays/shared/gameplay/entities/002b8c08.c @@ -2855,9 +2855,6 @@ void FUN_L01_002f5168(char *moby) { #undef Q2 #endif -#ifndef NON_MATCHING -INCLUDE_ASM("config/us/overlays/asm/FUN_L01_002b91c8.s", FUN_L01_002b91c8); -#else #include "rnc/rendering/dma_tag.h" extern s32 D_0015F620 __asm__("D_L01_00161220") __attribute__((sda)); extern union PacketCursor l01_packet __asm__("D_L01_001611C0") __attribute__((section(".sdata"))); @@ -2870,9 +2867,9 @@ void FUN_L01_002b91c8(f32 *pos, s32 count) { f32 corners[4][4]; f32 near_clip[4]; f32 far_clip[4]; - f32 x_offset, y_offset, x_end, y_end; + f32 x_offset, y_offset, x_end, y_end, z; u32 near_bits, far_bits; - u16 mask; + s32 mask; s32 i, j, mode; s32 height_index, index; f32 *height; @@ -2882,6 +2879,7 @@ void FUN_L01_002b91c8(f32 *pos, s32 count) { FUN_L01_002b8f98(); i = 0; if (count > 0) do { + f32 *next_pos = pos + 0x464; u16 active = *(u16 *)((u8 *)pos + 0x1e); if (active == 0) goto next_entity; x_offset = pos[0] + D_L01_001CAD00[2]; @@ -2890,19 +2888,20 @@ void FUN_L01_002b91c8(f32 *pos, s32 count) { y_offset = pos[1] + D_L01_001CAD00[3]; y_end = pos[1] - D_L01_001CAD00[3]; corners[0][1] = y_offset; - corners[0][2] = pos[2]; + z = pos[2]; + corners[0][2] = z; corners[0][3] = 1.0f; corners[1][0] = x_end; corners[1][1] = y_offset; - corners[1][2] = pos[2]; + corners[1][2] = z; corners[1][3] = 1.0f; corners[2][0] = x_offset; corners[2][1] = y_end; - corners[2][2] = pos[2]; + corners[2][2] = z; corners[2][3] = 1.0f; corners[3][0] = x_end; corners[3][1] = y_end; - corners[3][2] = pos[2]; + corners[3][2] = z; corners[3][3] = 1.0f; near_bits = 0; far_bits = 0; @@ -2941,10 +2940,14 @@ void FUN_L01_002b91c8(f32 *pos, s32 count) { height = (f32 *)0x70002008; for (height_index = 0x10; height_index >= 0; height_index--, height += 0x33) *height = pos[2]; } - mode = (far_bits & 0x2f2f2f2f) ? 1 : ((near_bits & 0x2f2f2f2f) ? 2 : 0); + mode = (far_bits & 0x2f2f2f2f) != 0; + if (!mode) { + mode = 2; + if (!(near_bits & 0x2f2f2f2f)) mode = 0; + } mask = *(u16 *)((u8 *)pos + 0x1e); - if (*(u32 *)(pos + 5) != D_0015F628 || *(u32 *)(pos + 6) != D_0015F62C || - *(u8 *)(pos + 7) != D_0015F630 || *(u8 *)((u8 *)pos + 0x1d) != D_0015F634) { + if (*(u32 *)(pos + 5) != D_L01_00161228 || *(u32 *)(pos + 6) != D_L01_0016122C || + *(u8 *)(pos + 7) != D_L01_00161230 || *(u8 *)((u8 *)pos + 0x1d) != D_L01_00161234) { l01_packet.words[0] = 0x10000005; l01_packet.words[1] = 0; l01_packet.words[2] = 0x11000000; @@ -2966,18 +2969,18 @@ void FUN_L01_002b91c8(f32 *pos, s32 count) { { u32 texture_id = *(u32 *)(pos + 5); u32 second_texture_id = *(u32 *)(pos + 6); - D_0015F628 = texture_id; - D_0015F62C = second_texture_id; + D_L01_00161228 = texture_id; + D_L01_0016122C = second_texture_id; } - D_0015F630 = *(u8 *)(pos + 7); - D_0015F634 = *(u8 *)((u8 *)pos + 0x1d); + D_L01_00161230 = *(u8 *)(pos + 7); + D_L01_00161234 = *(u8 *)((u8 *)pos + 0x1d); } for (index = 0; index < 16; index++, mask = (s32)mask >> 1) { if (mask & 1) FUN_L01_002b8cb0(pos, index, mode); } next_entity: i++; - pos += 0x464; + pos = next_pos; } while (i < count); l01_packet.words[0] = 0x10000000; l01_packet.words[1] = 0; @@ -2985,4 +2988,3 @@ void FUN_L01_002b91c8(f32 *pos, s32 count) { l01_packet.words[3] = 0; l01_packet.words += 4; } -#endif From a03ca51b3e4f60d2337e53e4c6d1fdb1a6260063 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:58:22 +0000 Subject: [PATCH 180/251] decomp: improve FUN_L07_0030cf90 --- src/overlays/l07/gameplay/entities/002cd2b0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/l07/gameplay/entities/002cd2b0.c b/src/overlays/l07/gameplay/entities/002cd2b0.c index 64b305992..dd47dfacd 100644 --- a/src/overlays/l07/gameplay/entities/002cd2b0.c +++ b/src/overlays/l07/gameplay/entities/002cd2b0.c @@ -1742,8 +1742,8 @@ void FUN_L07_0030cf90(struct Moby *moby) { case 4: target = (struct Moby *)((u32)D_L07_0015FFD8 + (u32)vars->target_index * 0x100); if (vars->target_index == -1 || target == 0 || - target->state == 0xfe || target->state == 0xfd || - target->state == vars->target_state) { + (voice = target->state) == 0xfe || voice == 0xfd || + voice == vars->target_state) { play_moby_sound(vars->trigger_sound, 0, moby); moby->state = 2; return; From d78769e7707796fae44f10bb0b410edbcc6f4a39 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:59:17 +0000 Subject: [PATCH 181/251] decomp: improve FUN_L10_002f5b58 --- src/overlays/shared/gameplay/vendor/002e3de8.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index 9361c45fe..f530d3f0d 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -392,10 +392,14 @@ void FUN_L10_002f5b58(char *moby) { FUN_001f99f8(work + 0x30); { char *source = *(char **)(D_L10_00167100 + 0x184); - *(u128 *)moby_scale = *(u128 *)(source + 0x30); - *(u128 *)(moby + 0x00) = *(u128 *)(source + 0x00); - *(u128 *)moby_pos = *(u128 *)(source + 0x10); - *(u128 *)moby_rot = *(u128 *)(source + 0x20); + source += 0x30; + *(u128 *)moby_scale = *(u128 *)source; + source -= 0x30; + *(u128 *)moby = *(u128 *)source; + source += 0x10; + *(u128 *)moby_pos = *(u128 *)source; + source += 0x10; + *(u128 *)moby_rot = *(volatile u128 *)source; } if (*(int *)(data + 0x4c) == 0) hero_set_state(0x72, 1); From bb6b285109af9965c76c6d391fbc3c5b719fcc77 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:59:38 +0000 Subject: [PATCH 182/251] decomp: improve FUN_L00_00237200 --- .../shared/gameplay/animation/00235878.c | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/overlays/shared/gameplay/animation/00235878.c b/src/overlays/shared/gameplay/animation/00235878.c index edf3e3cbd..7a5bd343a 100644 --- a/src/overlays/shared/gameplay/animation/00235878.c +++ b/src/overlays/shared/gameplay/animation/00235878.c @@ -553,6 +553,7 @@ extern void FUN_0023b4d8(void *, int, int, int, int, int) __asm__("FUN_001ffc30" extern void FUN_0023b860(void *, int, int, int, int, int) __asm__("FUN_001ffe18"); extern void FUN_001fb9a8(int, int, int, const char *, int) __asm__("FUN_001f6af0"); extern float FUN_001ff450(float *, float *) __asm__("FUN_001f9b48"); +extern const char freeze_stats_time_format[] __asm__("D_L00_001E84C0"); extern char *FUN_00203ad8(int) __asm__("FUN_001fdd10"); extern int FUN_00116248(char *, const char *, ...); extern void FUN_0023cf80(int, int, int, char *) __asm__("FUN_00201200"); @@ -599,9 +600,11 @@ int FUN_L00_00237200(HudElem *e) { other_left = left; } left = other_left; - FUN_0023b4d8(FUN_0023b208(0x7580, 0), left + 0x20, y, width, 0x36, alpha); + other_left = left + 0x20; + FUN_0023b4d8(FUN_0023b208(0x7580, 0), other_left, y, width, 0x36, alpha); FUN_0023b4d8(FUN_0023b208(0x7580, 1), left, y, 0x20, 0x36, alpha); - FUN_0023b860(FUN_0023b208(0x7580, 1), left + (width + 0x20), y, 0x20, 0x36, alpha); + width += 0x20; + FUN_0023b860(FUN_0023b208(0x7580, 1), left + width, y, 0x20, 0x36, alpha); FUN_001fb9a8(0x100, text_y, color, (const char *)D_L00_0017E530, -1); FUN_001fb9a8(0x100, y + 0x1b, color, (const char *)&D_L00_0017E530[1] + i, -1); level = current_level_index_sda; @@ -624,26 +627,32 @@ int FUN_L00_00237200(HudElem *e) { points[1].x = 115.7f; points[1].y = 287.0f; points[1].z = 119.5f; - if (FUN_001ff450(D_0013F3D0, - level == 5 ? memcpy(&point, &points[0], sizeof(point)) - : memcpy(&point, &points[1], sizeof(point))) < 5.0f) { - *(int *)0x15f648 = y + 100; - extra = current_level_index_sda == 0x10 ? 1 : 0; - elapsed = freeze_stats_time_ref_a[extra]; - extra = freeze_stats_score_ref_a[extra]; - if (elapsed != 0) { - interval = pal_mode != 0 ? 3000 : 3600; - seconds = elapsed / interval; - minute_scale = interval / 60; - remainder = elapsed - seconds * interval; - width = remainder / minute_scale; - remainder = (remainder - width * minute_scale) * 100 / minute_scale; - line = (const char *)0x1e84c0; - FUN_00116248(text, line, FUN_00203ad8(0x531b), seconds, width, remainder); - FUN_0023cf80(0x100, y + 0x28, color, text); - if (extra != 0) { - FUN_00116248(text, (const char *)0x15f778, FUN_00203ad8(0x531c), extra); - FUN_0023cf80(0x100, y + 0x48, color, text); + { + float *point_data; + if (level == 5) { + point_data = memcpy(&point, &points[0], sizeof(point)); + } else { + point_data = memcpy(&point, &points[1], sizeof(point)); + } + if (FUN_001ff450(D_0013F3D0, point_data) < 5.0f) { + *(int *)0x15f648 = y + 100; + extra = current_level_index_sda == 0x10 ? 1 : 0; + elapsed = freeze_stats_time_ref_a[extra]; + extra = freeze_stats_score_ref_a[extra]; + if (elapsed != 0) { + interval = pal_mode != 0 ? 3000 : 3600; + seconds = elapsed / interval; + minute_scale = interval / 60; + remainder = elapsed - seconds * interval; + width = remainder / minute_scale; + remainder = (remainder - width * minute_scale) * 100 / minute_scale; + line = freeze_stats_time_format; + FUN_00116248(text, line, FUN_00203ad8(0x531b), seconds, width, remainder); + FUN_0023cf80(0x100, y + 0x28, color, text); + if (extra != 0) { + FUN_00116248(text, (const char *)0x15f778, FUN_00203ad8(0x531c), extra); + FUN_0023cf80(0x100, y + 0x48, color, text); + } } } } From a7a063045e5ac916504eb3506df8620e4af977cf Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:01:57 +0000 Subject: [PATCH 183/251] decomp: improve FUN_L10_002da690 --- src/overlays/l10/gameplay/entities/00295a38.c | 120 ++++++++++-------- 1 file changed, 69 insertions(+), 51 deletions(-) diff --git a/src/overlays/l10/gameplay/entities/00295a38.c b/src/overlays/l10/gameplay/entities/00295a38.c index 331e1fe98..a44680590 100644 --- a/src/overlays/l10/gameplay/entities/00295a38.c +++ b/src/overlays/l10/gameplay/entities/00295a38.c @@ -2011,11 +2011,12 @@ void FUN_L10_002da690(void *moby) { if (*(int *)(data + 4) > 0) { transform = scratch; do { - i++; + int next = i + 1; + i = next; rotation_matrix_da690(transform, &((struct Moby *)moby)->rot); multiply_matrix_da690(transform, transform, buffers.rotation); *(OvlQuad *)(transform + 0x30) = *(OvlQuad *)&((struct Moby *)moby)->pos; - *(float *)(transform + 0x38) += convert_integer_to_float_da690(i) * *(float *)(data + 8); + *(float *)(transform + 0x38) += convert_integer_to_float_da690(next) * *(float *)(data + 8); transform += 0x40; } while (i < *(int *)(data + 4)); } @@ -2023,17 +2024,18 @@ void FUN_L10_002da690(void *moby) { u64 texture = get_effect_texture_da690(14); u64 packet_flags = ((u64)D_L10_00161C70) | ((u64)D_L10_00161C74 << 2) | ((u64)D_L10_00161C78 << 4) | ((u64)D_L10_00161C7C << 6) | 0x8000000000ULL; - ((u64 *)matrix1)[5] = texture; - ((u64 *)matrix2)[5] = texture; - ((u64 *)matrix1)[6] = 0xff9000000260ULL; - ((u64 *)matrix1)[7] = packet_flags; - ((u64 *)matrix2)[6] = 0xff9000000260ULL; - ((u64 *)matrix2)[4] = 0; - ((u64 *)matrix1)[4] = 0; - ((u64 *)matrix2)[7] = packet_flags; + ((u64 *)buffers.matrix1)[5] = texture; + ((u64 *)buffers.packet.fields.matrix2)[5] = texture; + ((u64 *)buffers.matrix1)[6] = 0xff9000000260ULL; + ((u64 *)buffers.matrix1)[7] = packet_flags; + ((u64 *)buffers.packet.fields.matrix2)[6] = 0xff9000000260ULL; + ((u64 *)buffers.packet.fields.matrix2)[4] = 0; + ((u64 *)buffers.matrix1)[4] = 0; + ((u64 *)buffers.packet.fields.matrix2)[7] = packet_flags; } { - float *source = (float *)0x001d9ff4; + float *source = (float *)0x001d9ff0; + source++; i = 3; do { float value = *source; @@ -2044,49 +2046,65 @@ void FUN_L10_002da690(void *moby) { uv1 += 2; } while (--i >= 0); } - for (group = 0; group < 4; group++) { - phase = 0.0f; - for (row = 0; row < 19; row++) { - phase += D_L10_00161D60; - if (phase > 1.0f) phase -= 1.0f; - for (i = 0; i < 4; i++) { - float value = ((float *)0x001d9ff0)[i * 2] + phase + *(float *)(base + 0x12de0); - matrix1[i * 2] = value; - matrix2[i * 2] = value; - } - for (i = 0; i < *(int *)(data + 4); i++) { - unsigned char *order = (unsigned char *)(data + 0x10); - int age = *(int *)(base + 0x10000 + 0x2c00 + group * 0x78 + order[i] * 4); - float progress; - unsigned int color; - if (age > D_L10_00161D68) { - progress = convert_integer_to_float_da690(age - D_L10_00161D68) / - convert_integer_to_float_da690(D_L10_00161D64 - D_L10_00161D68); - } else { - progress = 1.0f - convert_integer_to_float_da690(age) / - convert_integer_to_float_da690(D_L10_00161D68); - } - color = fast_tween_color_da690(progress, D_L10_00161C90, D_L10_00161C94); - color = (color & 0xffffff) + - (truncate_float_to_s32_da690(fade * fade * - convert_integer_to_float_da690((int)color >> 24)) << 24); - if (((struct Moby *)moby)->state == 2) { - float alpha = convert_integer_to_float_da690(*(int *)(data + 0x34)); - float duration = scale_time_da690(D_L10_00161C98 * 60.0f); - color = (truncate_float_to_s32_da690(alpha * 255.0f / duration) << 24) | 0xffffff; + { + char *age_base = base + 0x10000; + group = 0; + do { + int next_group = group + 1; + phase = 0.0f; + row = 0; + do { + int next_row = row + 1; + phase += D_L10_00161D60; + if (phase > 1.0f) phase -= 1.0f; + for (i = 0; i < 4; i++) { + float value = ((float *)0x001d9ff0)[i * 2] + phase + *(float *)(base + 0x12de0); + matrix2[i * 2] = value; + matrix1[i * 2] = value; } + i = 0; + if (*(int *)(data + 4) > 0) { + do { + unsigned char *order = (unsigned char *)(data + 0x10); + int group_age = group * 0x78; + int group_vertices = (int)((long long)group * 0x2580); + char *ages = age_base + 0x2c00; + int age = *(int *)(ages + (order[i] * 4 + group_age)); + float progress; + unsigned int color; + if (age > D_L10_00161D68) { + progress = convert_integer_to_float_da690(age - D_L10_00161D68) / + convert_integer_to_float_da690(D_L10_00161D64 - D_L10_00161D68); + } else { + progress = 1.0f - convert_integer_to_float_da690(age) / + convert_integer_to_float_da690(D_L10_00161D68); + } + color = fast_tween_color_da690(progress, D_L10_00161C90, D_L10_00161C94); + color = (color & 0xffffff) + + (truncate_float_to_s32_da690(fade * fade * + convert_integer_to_float_da690((int)color >> 24)) << 24); + if (((struct Moby *)moby)->state == 2) { + float alpha = convert_integer_to_float_da690(*(int *)(data + 0x34)); + float duration = scale_time_da690(D_L10_00161C98 * 60.0f); + color = (truncate_float_to_s32_da690(alpha * 255.0f / duration) << 24) | 0xffffff; + } - *(unsigned int *)(buffers.packet.quad + 0x40) = color; - *(unsigned int *)(buffers.packet.quad + 0x4c) = color; - *(unsigned int *)(buffers.packet.quad + 0x48) = color; - *(unsigned int *)(buffers.packet.quad + 0x44) = color; - for (vertex = 0; vertex < 4; vertex++) { - add_vector_xyz_da690(buffers.packet.quad + vertex * 0x10, (char *)0x001da010 + vertex * 0x10, - base + group * 0x2580 + (row + (vertex >> 1)) * 0x140 + order[i] * 0x10); + *(unsigned int *)(buffers.packet.quad + 0x40) = color; + *(unsigned int *)(buffers.packet.quad + 0x4c) = color; + *(unsigned int *)(buffers.packet.quad + 0x48) = color; + *(unsigned int *)(buffers.packet.quad + 0x44) = color; + for (vertex = 0; vertex < 4; vertex++) { + add_vector_xyz_da690(buffers.packet.quad + vertex * 0x10, (char *)0x001da010 + vertex * 0x10, + base + group_vertices + (row + (vertex >> 1)) * 0x140 + order[i] * 0x10); + } + draw_geometry_quad_da690(buffers.packet.quad, scratch + i * 0x40, 0); + i++; + } while (i < *(int *)(data + 4)); } - draw_geometry_quad_da690(buffers.packet.quad, scratch + i * 0x40, 0); - } - } + row = next_row; + } while (row < 19); + group = next_group; + } while (group < 4); } } #endif From 6f7d4e24188aad5d3d61edbe8f6dfc14b0c69f0d Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:02:27 +0000 Subject: [PATCH 184/251] decomp: improve FUN_L08_002f44c0 --- src/overlays/l08/gameplay/entities/002e9b70.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/overlays/l08/gameplay/entities/002e9b70.c b/src/overlays/l08/gameplay/entities/002e9b70.c index 65178b3c4..830658b26 100644 --- a/src/overlays/l08/gameplay/entities/002e9b70.c +++ b/src/overlays/l08/gameplay/entities/002e9b70.c @@ -511,18 +511,21 @@ state_zero: { return; } state_one: { + s32 tint; s32 active = find_moby_hit_44c0(moby, 0x330000, 0); distance = FUN_001f9b80_44c0(&moby->pos, D_0013F3D0); if ((distance < 2.0f && *(s32 *)(D_0013F3D0 + 0x2004) == 0x42) || *(struct Moby **)(D_0013F3D0 + 0x1bc) == moby) { allocate_voice_for_target_entry_44c0(0, 0, moby); waypoint = 1; + tint = -1; FUN_L00_0025e450_44c0(moby, D_L08_0015F580, &moby->pos, 3.0f, 1.0f, 10, 20, 60, - 3.0f, 5.0f, 9.0f, 1.0f, -1, 15.0f, waypoint, 1, -1, 0); + 3.0f, 5.0f, 9.0f, 1.0f, -1, 15.0f, waypoint, 1, tint, 0); } else { if (active == 0) return; allocate_voice_for_target_entry_44c0(0, 0, moby); + tint = -1; FUN_L00_0025e450_44c0(moby, D_L08_0015F580, &moby->pos, 0.0f, 0.0f, 10, 20, 60, - 1.0f, 3.0f, 9.0f, 1.0f, -1, 15.0f, 1, 1, -1, 0); + 1.0f, 3.0f, 9.0f, 1.0f, -1, 15.0f, 1, 1, tint, 0); } mark_moby_for_removal_44c0(moby); return; From 52195723a77fbdfc8d09398509e6710ae921e39b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:05:08 +0000 Subject: [PATCH 185/251] decomp: improve FUN_L00_002dd8e8 --- src/overlays/shared/gameplay/entities/002d7f88.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002d7f88.c b/src/overlays/shared/gameplay/entities/002d7f88.c index ef12f9ebb..05f87bd74 100644 --- a/src/overlays/shared/gameplay/entities/002d7f88.c +++ b/src/overlays/shared/gameplay/entities/002d7f88.c @@ -2662,10 +2662,10 @@ void FUN_L00_002dd8e8(void) { for (segment = 0; segment < 20; segment++) { segment_offset = segment * 16; qcopy(&quad.points[0], D_L00_001E6020_002dd8e8 + (current + segment_offset)); - next_segment = (segment + 1) % 20; - qcopy(&quad.points[1], D_L00_001E6020_002dd8e8 + (current + next_segment * 16)); + next_segment = ((segment + 1) % 20) * 16; + qcopy(&quad.points[1], D_L00_001E6020_002dd8e8 + (current + next_segment)); qcopy(&quad.points[2], prior + (current + segment_offset)); - qcopy(&quad.points[3], prior + (current + next_segment * 16)); + qcopy(&quad.points[3], prior + (current + next_segment)); FUN_001ff2a8_002dd8e8(&edge, &quad.points[0], &quad.points[1]); FUN_001ff2a8_002dd8e8(&outward, &quad.points[2], &quad.points[1]); FUN_001ff3c0_002dd8e8(&normal, &outward, &edge); From a7af1653eed82b3f0546fa8e08706e045be3c1a5 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:05:14 +0000 Subject: [PATCH 186/251] decomp: improve FUN_L12_002bf140 --- src/overlays/l12/gameplay/entities/002bf140.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/overlays/l12/gameplay/entities/002bf140.c b/src/overlays/l12/gameplay/entities/002bf140.c index 4b06c8620..270329ff7 100644 --- a/src/overlays/l12/gameplay/entities/002bf140.c +++ b/src/overlays/l12/gameplay/entities/002bf140.c @@ -78,21 +78,21 @@ void FUN_L12_002bf140(struct Moby *moby) { initialize_slots_c(D_L12_001CBF40_c, 17); initialize_slot_data_c(1.0f); *(float *)(D_L12_001CAD00_c + 0x00) = 16.0f; + *(float *)(D_L12_001CAD00_c + 0x04) = 16.0f; + *(float *)(D_L12_001CAD00_c + 0x08) = -8.0f; *(float *)(D_L12_001CAD00_c + 0x0c) = -8.0f; + *(float *)(D_L12_001CAD00_c + 0x10) = 1.0f; + *(float *)(D_L12_001CAD00_c + 0x14) = 1.0f; *(float *)(D_L12_001CAD00_c + 0x18) = 0.9f; - *(float *)(D_L12_001CAD00_c + 0x08) = -8.0f; *(float *)(D_L12_001CAD00_c + 0x20) = 0.1f; - *(float *)(D_L12_001CAD00_c + 0x14) = 1.0f; - *(float *)(D_L12_001CAD00_c + 0x10) = 1.0f; - *(float *)(D_L12_001CAD00_c + 0x04) = 16.0f; value = angle_c(*(float *)0x00180350, *(float *)0x00180354); *(float *)(D_L12_001CAD00_c + 0x30) = sine_c(value) * 0.57735f; *(float *)(D_L12_001CAD00_c + 0x34) = cosine_c(value) * 0.57735f; *(float *)(D_L12_001CAD00_c + 0x38) = -0.57735f; *(int *)(D_L12_001CAD00_c + 0x28) = data[0] + 0x28; - *(u8 *)(D_L12_001CAD00_c + 0x3d) = 0x40; *(int *)(D_L12_001CAD00_c + 0x2c) = data[1] + 0x28; *(u8 *)(D_L12_001CAD00_c + 0x3c) = 0x1c; + *(u8 *)(D_L12_001CAD00_c + 0x3d) = 0x40; *(char **)0x001612d0 = D_L12_001CBF40_c; *(void **)0x001612d4 = D_L12_001CBE00_c; *(int *)0x001612d8 = 17; From 0e9f98bfc5f8f73eb7dd35c7486f247b205666fc Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:51:27 +0000 Subject: [PATCH 187/251] decomp: improve draw_quad_grid_with_dynamic_uvs --- src/overlays/shared/gameplay/entities/002cfcb8.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002cfcb8.c b/src/overlays/shared/gameplay/entities/002cfcb8.c index 7c91edeef..ad8958bf3 100644 --- a/src/overlays/shared/gameplay/entities/002cfcb8.c +++ b/src/overlays/shared/gameplay/entities/002cfcb8.c @@ -781,8 +781,9 @@ void FUN_L00_002d19b0(u8 *m) { Vec_2d19b0 a, c, b; u8 *vars = *(u8 **)(m + 0x78); s16 *indices = D_L00_001DEE10_2d19b0; - f32 (*uv)[2], (*old_uv)[2]; + f32 (*uv)[2]; f32 *uv_y, *texcoords; + f32 (*old_uv)[2]; s32 i, j, index, active = 0; f32 blend, len, x, y; @@ -792,7 +793,7 @@ void FUN_L00_002d19b0(u8 *m) { ((u64)(s64)D_L00_001618E4 << 4) | ((u64)(s64)D_L00_001618E8 << 6) | ((u64)(s64)D_L00_001618EC << 32); quad.texture[0] = 0; - quad.colors[3] = quad.colors[2] = quad.colors[1] = quad.colors[0] = D_L00_001618F4; + quad.colors[0] = quad.colors[1] = quad.colors[2] = quad.colors[3] = D_L00_001618F4; if (absolute_float_2d19b0(D_L00_00166C80_2d19b0[80] - *(f32 *)(m + 0x10)) < 16.0f && absolute_float_2d19b0(D_L00_00166C80_2d19b0[81] - *(f32 *)(m + 0x14)) < 16.0f) active = 1; @@ -802,6 +803,8 @@ void FUN_L00_002d19b0(u8 *m) { blend = convert_integer_to_float_2d19b0(*(s32 *)(vars + 0x40)); blend /= convert_integer_to_float_2d19b0(scale_game_frames_2d19b0(0x3c)); uv = D_L00_001E0B00_2d19b0; + texcoords = quad.texcoords; + uv_y = quad.texcoords + 1; old_uv = D_L00_001E0E30_2d19b0; for (i = 0; i < 0x66; i++) { transform_vector_2d19b0(&D_L00_001E04A0_2d19b0[i], &D_L00_001DE7B0_2d19b0[i], vars); @@ -835,19 +838,21 @@ void FUN_L00_002d19b0(u8 *m) { } else { if (m[0xbc] == 1) { m[0xbc] = 0; + texcoords = quad.texcoords; + uv_y = quad.texcoords + 1; for (i = 0; i < 0x66; i++) { D_L00_001E0E30_2d19b0[i][0] = D_L00_001E0B00_2d19b0[i][0]; D_L00_001E0E30_2d19b0[i][1] = D_L00_001E0B00_2d19b0[i][1]; transform_vector_2d19b0(&D_L00_001E04A0_2d19b0[i], &D_L00_001DE7B0_2d19b0[i], vars); } } else { + texcoords = quad.texcoords; + uv_y = quad.texcoords + 1; for (i = 0; i < 0x66; i++) transform_vector_2d19b0(&D_L00_001E04A0_2d19b0[i], &D_L00_001DE7B0_2d19b0[i], vars); } *(s32 *)(vars + 0x40) = scale_game_frames_2d19b0(0x3c); } - texcoords = quad.texcoords; - uv_y = quad.texcoords + 1; for (i = 0; i < 0x4a; i++) { f32 *uv_x = texcoords; f32 *uv_second = uv_y; From df64e2ebce7f616ea47920f10bdb4f923bc2f7bb Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 19:44:25 +0000 Subject: [PATCH 188/251] decomp: improve FUN_L11_00310cf8 --- .../shared/gameplay/vendor/0030e690.c | 106 ++++++++++-------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/0030e690.c b/src/overlays/shared/gameplay/vendor/0030e690.c index 64eecd193..671ccfbba 100644 --- a/src/overlays/shared/gameplay/vendor/0030e690.c +++ b/src/overlays/shared/gameplay/vendor/0030e690.c @@ -203,8 +203,6 @@ void FUN_L11_00310cf8(float x, float y, float width, float height, float angle, float bottom_right[4]; int *tag; unsigned long long *q; - int sx, sy; - unsigned long long packed_position; volatile int saved_depth[2]; unsigned long long packed_depth; @@ -240,50 +238,66 @@ void FUN_L11_00310cf8(float x, float y, float width, float height, float angle, q[5] = 0x100010; texture_width <<= 4; texture_height <<= 20; - sx = ftoi_g(top_left[0] * 16.0f); - sy = ftoi_g(top_left[1] * 16.0f); - sy += screen_extent[5]; - sx += screen_extent[4]; - sy -= 8; - sx -= 8; - q[7] = texture_width; - packed_position = (unsigned long long)sx; - packed_position |= (unsigned long long)sy << 16; - packed_position |= packed_depth; - q[6] = packed_position; - sx = ftoi_g(bottom_left[0] * 16.0f); - sy = ftoi_g(bottom_left[1] * 16.0f); - sy += screen_extent[5]; - sx += screen_extent[4]; - sy -= 8; - sx -= 8; - q[9] = texture_height; - packed_position = (unsigned long long)sx; - packed_position |= (unsigned long long)sy << 16; - packed_position |= packed_depth; - q[8] = packed_position; - sx = ftoi_g(top_right[0] * 16.0f); - sy = ftoi_g(top_right[1] * 16.0f); - sy += screen_extent[5]; - sx += screen_extent[4]; - sy -= 8; - sx -= 8; - q[11] = (texture_height) + (texture_width); - packed_position = (unsigned long long)sx; - packed_position |= (unsigned long long)sy << 16; - packed_position |= packed_depth; - q[10] = packed_position; - sx = ftoi_g(bottom_right[0] * 16.0f); - sy = ftoi_g(bottom_right[1] * 16.0f); - sy += screen_extent[5]; - sx += screen_extent[4]; - sy -= 8; - sx -= 8; - q[13] = 0; - packed_position = (unsigned long long)sx; - packed_position |= (unsigned long long)sy << 16; - packed_position |= packed_depth; - q[12] = packed_position; + { + int sx, sy; + unsigned long long packed_position; + sx = ftoi_g(top_left[0] * 16.0f); + sy = ftoi_g(top_left[1] * 16.0f); + sy += screen_extent[5]; + sx += screen_extent[4]; + sy -= 8; + sx -= 8; + q[7] = texture_width; + packed_position = (unsigned long long)sx; + packed_position |= (unsigned long long)sy << 16; + packed_position |= packed_depth; + q[6] = packed_position; + } + { + int sx, sy; + unsigned long long packed_position; + sx = ftoi_g(bottom_left[0] * 16.0f); + sy = ftoi_g(bottom_left[1] * 16.0f); + sy += screen_extent[5]; + sx += screen_extent[4]; + sy -= 8; + sx -= 8; + q[9] = texture_height; + packed_position = (unsigned long long)sx; + packed_position |= (unsigned long long)sy << 16; + packed_position |= packed_depth; + q[8] = packed_position; + } + { + int sx, sy; + unsigned long long packed_position; + sx = ftoi_g(top_right[0] * 16.0f); + sy = ftoi_g(top_right[1] * 16.0f); + sy += screen_extent[5]; + sx += screen_extent[4]; + sy -= 8; + sx -= 8; + q[11] = (texture_height) + (texture_width); + packed_position = (unsigned long long)sx; + packed_position |= (unsigned long long)sy << 16; + packed_position |= packed_depth; + q[10] = packed_position; + } + { + int sx, sy; + unsigned long long packed_position; + sx = ftoi_g(bottom_right[0] * 16.0f); + sy = ftoi_g(bottom_right[1] * 16.0f); + sy += screen_extent[5]; + sx += screen_extent[4]; + sy -= 8; + sx -= 8; + q[13] = 0; + packed_position = (unsigned long long)sx; + packed_position |= (unsigned long long)sy << 16; + packed_position |= packed_depth; + q[12] = packed_position; + } D_L11_001611C0_g = (*(volatile int *)&D_L11_001611C0_g) + 0x70; } #undef FUN_L11_00310cf8 From 7751ff3634404abc3e60dcad9ed810a7b9bfd7f1 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:09:53 +0000 Subject: [PATCH 189/251] decomp: improve FUN_L00_00276368 --- src/overlays/shared/audio/voices/00276368.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index 220095166..e5c87c0f9 100644 --- a/src/overlays/shared/audio/voices/00276368.c +++ b/src/overlays/shared/audio/voices/00276368.c @@ -47,6 +47,8 @@ extern u8 D_L00_001B6B38[]; extern u8 D_L00_001B86C8[]; extern u8 D_L00_001B2588[]; extern u8 D_L00_00180250[]; +extern u8 D_L00_00160280_init[] __asm__("D_L00_00160280") __attribute__((sda)); +extern u8 D_L00_00160290_init[] __asm__("D_L00_00160290") __attribute__((sda)); extern f32 D_L00_00166DC0_init[] __asm__("D_L00_00166DC0"); extern u8 D_L00_001841F0_init[] __asm__("D_L00_001841F0"); @@ -118,8 +120,8 @@ void FUN_L00_00276368(void) { D_L00_001B9DE4 = 0; D_L00_001B9DE0 = 0; } - FUN_L00_001ff300(D_L00_00180250, (u8 *)0x00160280, 1.0f); - qcopy((void *)D_L00_00180240, (u8 *)0x00160290); + FUN_L00_001ff300(D_L00_00180250, D_L00_00160280_init, 1.0f); + qcopy((void *)D_L00_00180240, D_L00_00160290_init); *(volatile u128_init *)D_L00_00180260 = 0; *(volatile u128_init *)(D_L00_00180260 + 4) = 0; qcopy((void *)D_L00_001B9D30, (void *)D_L00_00166DC0_init); From 13c7b2da3b09679d5190c36adbc4ea4ded6ca44a Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:04:42 +0000 Subject: [PATCH 190/251] decomp: improve FUN_L14_00301fa8 --- src/overlays/shared/gameplay/vendor/003015d0.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/003015d0.c b/src/overlays/shared/gameplay/vendor/003015d0.c index 3a1e6e02c..c664a711c 100644 --- a/src/overlays/shared/gameplay/vendor/003015d0.c +++ b/src/overlays/shared/gameplay/vendor/003015d0.c @@ -397,13 +397,13 @@ void FUN_L14_00301fa8(char *m) { packet[0].tag = packet[1].tag = packet[2].tag = 0; for (i = 0; i < 4; i++) { float v = ((float *)0x001e5fd0)[i * 2 + 1]; - color = *(int *)(d + 0x14); - packet[0].uv[i][1] = v; - packet[1].uv[i][1] = v; packet[2].uv[i][1] = v; - packet[0].colors[i] = color; - packet[1].colors[i] = color; + packet[1].uv[i][1] = v; + packet[0].uv[i][1] = v; + color = *(int *)(d + 0x14); packet[2].colors[i] = color; + packet[1].colors[i] = color; + packet[0].colors[i] = color; } clear_u64_value(start); From ce2dbf2cef481b4c16a625e6644b5db7d1e4cbc5 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:13:14 +0000 Subject: [PATCH 191/251] decomp: improve FUN_L08_003024d8 --- src/overlays/shared/gameplay/entities/002937a0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/002937a0.c b/src/overlays/shared/gameplay/entities/002937a0.c index 9b5e45c1f..9a950fcf7 100644 --- a/src/overlays/shared/gameplay/entities/002937a0.c +++ b/src/overlays/shared/gameplay/entities/002937a0.c @@ -1683,8 +1683,8 @@ void FUN_L08_003024d8(char *m) { *(unsigned short *)(m + 0x34) &= 0xefff; *(int *)(d + 0x90) = 0x200; *(float *)(d + 0xc4) = 16.0f; - *(float *)(d + 0xc0) = 11.0f; *(float *)(d + 0x98) = 0.25f; + *(float *)(d + 0xc0) = 11.0f; *(float *)(d + 0x80) = pose_scale; *(float *)(d + 0x88) = timer_scale; *(float *)(d + 0x8c) = angle; From cb3ae8dbcd385f4bb622e7331a7c1fc0a9944e7e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:15:46 +0000 Subject: [PATCH 192/251] decomp: improve FUN_L06_002feb40 --- src/overlays/shared/gameplay/entities/002fdbd0.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/002fdbd0.c b/src/overlays/shared/gameplay/entities/002fdbd0.c index 1788d4883..8a4f15a98 100644 --- a/src/overlays/shared/gameplay/entities/002fdbd0.c +++ b/src/overlays/shared/gameplay/entities/002fdbd0.c @@ -516,7 +516,6 @@ void FUN_L06_002feb40(struct Moby *moby) { case 2: { f32 speed; - f32 remaining; moby->state = 16; vel = vars->vel.f; speed = D_L06_00161FB8 * D_0015ED6C; From cddf6a2a85c1a125c7d516791be65de3db10724c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:09:20 +0000 Subject: [PATCH 193/251] decomp: improve FUN_L01_002ef350 --- src/overlays/shared/gameplay/entities/002b8c08.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b8c08.c b/src/overlays/shared/gameplay/entities/002b8c08.c index 176f78dfb..0f45f345b 100644 --- a/src/overlays/shared/gameplay/entities/002b8c08.c +++ b/src/overlays/shared/gameplay/entities/002b8c08.c @@ -2004,8 +2004,9 @@ char *FUN_L01_002ef350(char *self) { } else if (*(short *)(self + 0xA6) == 0x361) { type = 0x362; } - list = (short *)(lists_2ef478 + (unsigned char)self[0x21]); - list = *(short **)list; + entry = (unsigned char)self[0x21]; + entities = (char *)(lists_2ef478 + entry); + list = *(short **)entities; entities = ents_2ef478; if (list == 0) return 0; goto scan; From 8f4cb16cbd5c47b7ac7bea411f98b9703df4316c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:21:29 +0000 Subject: [PATCH 194/251] decomp: improve FUN_L00_00237200 --- .../shared/gameplay/animation/00235878.c | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/overlays/shared/gameplay/animation/00235878.c b/src/overlays/shared/gameplay/animation/00235878.c index 7a5bd343a..57dfe04ed 100644 --- a/src/overlays/shared/gameplay/animation/00235878.c +++ b/src/overlays/shared/gameplay/animation/00235878.c @@ -553,6 +553,7 @@ extern void FUN_0023b4d8(void *, int, int, int, int, int) __asm__("FUN_001ffc30" extern void FUN_0023b860(void *, int, int, int, int, int) __asm__("FUN_001ffe18"); extern void FUN_001fb9a8(int, int, int, const char *, int) __asm__("FUN_001f6af0"); extern float FUN_001ff450(float *, float *) __asm__("FUN_001f9b48"); +extern const char freeze_stats_score_format[] __asm__("D_L00_0015F778"); extern const char freeze_stats_time_format[] __asm__("D_L00_001E84C0"); extern char *FUN_00203ad8(int) __asm__("FUN_001fdd10"); extern int FUN_00116248(char *, const char *, ...); @@ -602,18 +603,21 @@ int FUN_L00_00237200(HudElem *e) { left = other_left; other_left = left + 0x20; FUN_0023b4d8(FUN_0023b208(0x7580, 0), other_left, y, width, 0x36, alpha); + other_left = color; FUN_0023b4d8(FUN_0023b208(0x7580, 1), left, y, 0x20, 0x36, alpha); - width += 0x20; - FUN_0023b860(FUN_0023b208(0x7580, 1), left + width, y, 0x20, 0x36, alpha); - FUN_001fb9a8(0x100, text_y, color, (const char *)D_L00_0017E530, -1); - FUN_001fb9a8(0x100, y + 0x1b, color, (const char *)&D_L00_0017E530[1] + i, -1); + FUN_0023b860(FUN_0023b208(0x7580, 1), left + (width + 0x20), y, 0x20, 0x36, alpha); + FUN_001fb9a8(0x100, text_y, other_left, (const char *)D_L00_0017E530, -1); + FUN_001fb9a8(0x100, y + 0x1b, other_left, (const char *)&D_L00_0017E530[1] + i, -1); level = current_level_index_sda; } else { + int width, left; width = FUN_001fb090((const char *)D_L00_0017E530, -1); left = 0xe0 - (width >> 1); FUN_0023b4d8(FUN_0023b208(0x7580, 1), left, y, 0x20, 0x20, alpha); FUN_0023b4d8(FUN_0023b208(0x7580, 0), left + 0x20, y, width, 0x20, alpha); - FUN_0023b860(FUN_0023b208(0x7580, 1), left + (width + 0x20), y, 0x20, 0x20, alpha); + line = FUN_0023b208(0x7580, 1); + width += 0x20; + FUN_0023b860((void *)line, left + width, y, 0x20, 0x20, alpha); FUN_001fb9a8(0x100, text_y, color, (const char *)D_L00_0017E530, -1); level = *(int *)0x15ed84; } @@ -630,9 +634,11 @@ int FUN_L00_00237200(HudElem *e) { { float *point_data; if (level == 5) { - point_data = memcpy(&point, &points[0], sizeof(point)); + *(quadword *)&point = *(quadword *)&points[0]; + point_data = (float *)&point; } else { - point_data = memcpy(&point, &points[1], sizeof(point)); + *(quadword *)&point = *(quadword *)&points[1]; + point_data = (float *)&point; } if (FUN_001ff450(D_0013F3D0, point_data) < 5.0f) { *(int *)0x15f648 = y + 100; @@ -641,8 +647,8 @@ int FUN_L00_00237200(HudElem *e) { extra = freeze_stats_score_ref_a[extra]; if (elapsed != 0) { interval = pal_mode != 0 ? 3000 : 3600; - seconds = elapsed / interval; minute_scale = interval / 60; + seconds = elapsed / interval; remainder = elapsed - seconds * interval; width = remainder / minute_scale; remainder = (remainder - width * minute_scale) * 100 / minute_scale; @@ -650,7 +656,7 @@ int FUN_L00_00237200(HudElem *e) { FUN_00116248(text, line, FUN_00203ad8(0x531b), seconds, width, remainder); FUN_0023cf80(0x100, y + 0x28, color, text); if (extra != 0) { - FUN_00116248(text, (const char *)0x15f778, FUN_00203ad8(0x531c), extra); + FUN_00116248(text, freeze_stats_score_format, FUN_00203ad8(0x531c), extra); FUN_0023cf80(0x100, y + 0x48, color, text); } } From f9afeb8c1cd1edd95801e05769c31a6749dd4171 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:23:55 +0000 Subject: [PATCH 195/251] decomp: improve FUN_L10_002da690 --- src/overlays/l10/gameplay/entities/00295a38.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/overlays/l10/gameplay/entities/00295a38.c b/src/overlays/l10/gameplay/entities/00295a38.c index a44680590..e5fe8d8dc 100644 --- a/src/overlays/l10/gameplay/entities/00295a38.c +++ b/src/overlays/l10/gameplay/entities/00295a38.c @@ -2024,8 +2024,8 @@ void FUN_L10_002da690(void *moby) { u64 texture = get_effect_texture_da690(14); u64 packet_flags = ((u64)D_L10_00161C70) | ((u64)D_L10_00161C74 << 2) | ((u64)D_L10_00161C78 << 4) | ((u64)D_L10_00161C7C << 6) | 0x8000000000ULL; - ((u64 *)buffers.matrix1)[5] = texture; ((u64 *)buffers.packet.fields.matrix2)[5] = texture; + ((u64 *)buffers.matrix1)[5] = texture; ((u64 *)buffers.matrix1)[6] = 0xff9000000260ULL; ((u64 *)buffers.matrix1)[7] = packet_flags; ((u64 *)buffers.packet.fields.matrix2)[6] = 0xff9000000260ULL; @@ -2034,6 +2034,7 @@ void FUN_L10_002da690(void *moby) { ((u64 *)buffers.packet.fields.matrix2)[7] = packet_flags; } { + int i; float *source = (float *)0x001d9ff0; source++; i = 3; @@ -2054,9 +2055,10 @@ void FUN_L10_002da690(void *moby) { phase = 0.0f; row = 0; do { - int next_row = row + 1; + int next_row; phase += D_L10_00161D60; if (phase > 1.0f) phase -= 1.0f; + next_row = row + 1; for (i = 0; i < 4; i++) { float value = ((float *)0x001d9ff0)[i * 2] + phase + *(float *)(base + 0x12de0); matrix2[i * 2] = value; From 1ae57518dc2afd500929c9b65dcb0ba2a4c28b7c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:23:14 +0000 Subject: [PATCH 196/251] decomp: improve FUN_L00_002d5160 --- src/overlays/shared/gameplay/entities/002cfcb8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002cfcb8.c b/src/overlays/shared/gameplay/entities/002cfcb8.c index ad8958bf3..6581b8ecf 100644 --- a/src/overlays/shared/gameplay/entities/002cfcb8.c +++ b/src/overlays/shared/gameplay/entities/002cfcb8.c @@ -2246,7 +2246,7 @@ extern unsigned char *D_L00_001B04B0_2d5160[] __asm__("D_L00_001B04B0"); extern void *FUN_L00_0025a420_2d5160(void *, s32, s32) __asm__("FUN_L00_0025a420"); extern void FUN_L00_0025a478_2d5160(void *, void *, void *, s32, s32 *, f32 *, s32, s32) __asm__("FUN_L00_0025a478"); extern void FUN_L00_0025ab48_2d5160(void *, f32 *, void *, void *) __asm__("FUN_L00_0025ab48"); -extern void FUN_L00_0025c558_2d5160(f32, void *, void *, s32, s32, s32) __asm__("FUN_L00_0025c558"); +extern void FUN_L00_0025c558_2d5160(void *, void *, f32, s32, s32, s32) __asm__("FUN_L00_0025c558"); extern void FUN_L00_0025d458_2d5160(void *, void *) __asm__("FUN_L00_0025d458"); extern void FUN_L00_0025d538_2d5160(void *, void *) __asm__("FUN_L00_0025d538"); extern void FUN_L00_0025ff38_2d5160(f32, void *, void *, s32, s32, void *, s32) __asm__("FUN_L00_0025ff38"); @@ -2303,7 +2303,7 @@ void FUN_L00_002d5160(unsigned char *m) { *(u16 *)(m + 0x34) &= ~0x1000; *(OvlQuad *)vec = *(OvlQuad *)(hit + 0x10); FUN_L00_0025ab48_2d5160(vec, &angle, v + 0x88, v + 0x8C); - FUN_L00_0025c558_2d5160(angle, m, v + 0x70, FUN_L00_00257b50_2d5160(2) + 6, 1, 0); + FUN_L00_0025c558_2d5160(m, v + 0x70, angle, FUN_L00_00257b50_2d5160(2) + 6, 1, 0); reactionC0 = D_L00_0016198C_2d5160; reactionC4 = D_L00_00161988_2d5160; *(f32 *)(v + 0xC0) = reactionC0; From cd4a6051ec9113c1a59693a1613815ce086821c3 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:31:00 +0000 Subject: [PATCH 197/251] decomp: improve FUN_L10_002e91b8 --- .../shared/gameplay/vendor/002e3de8.c | 116 ++++++++++-------- 1 file changed, 67 insertions(+), 49 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index f530d3f0d..1b91f4a0d 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -129,7 +129,7 @@ void FUN_L10_002e91b8(unsigned char *m) { float *second_vectors; float *second_angles; int i, k; - unsigned int j; + int j; copy_matrix(matrix, m + 0xc0); qcopy(position, m + 0x10); @@ -163,58 +163,76 @@ void FUN_L10_002e91b8(unsigned char *m) { i--; } while (i >= 0); - for (i = 0; i < D_L10_0015B340; i++) { - int parity = i & 1; - int *colors = D_L10_0015B348; - unsigned long long color = (long long)colors[parity] | - ((long long)D_L10_00161F50[parity] << 2) | - ((long long)D_L10_00161F58[parity] << 4) | - ((long long)D_L10_00161F60[parity] << 6) | 0x8000000000ULL; - int shade = (D_L10_001DA250)[i]; - float *angles = (float *)(first + 0x58); - float *offsets = (float *)(first + 0x68); + if (D_L10_0015B340 > 0) { + float *angle_vectors = (float *)(first + 0x50); float *first_angles = (float *)(second + 0x50); - float *second_angles = (float *)(second + 0x60); + float *angles = (float *)(first + 0x58); float *first_offsets = (float *)(second + 0x58); + float *second_angles = (float *)(second + 0x60); + float *offsets = (float *)(first + 0x68); float *second_offsets = (float *)(second + 0x68); - *(unsigned long long *)(first + 0x88) = color; - *(unsigned long long *)(second + 0x88) = - (long long)colors[parity] | ((long long)D_L10_00161F50[parity] << 2) | - ((long long)D_L10_00161F58[parity] << 4) | ((long long)D_L10_00161F60[parity] << 6) | - 0x8000000000ULL; - ((int *)(first + 0x40))[0] = shade; - ((int *)(second + 0x40))[2] = shade; - ((int *)(second + 0x40))[0] = shade; - ((int *)(first + 0x40))[3] = shade; - ((int *)(first + 0x40))[2] = shade; - ((int *)(first + 0x40))[1] = shade; - for (j = 0; j < 4; j++) { - float *first_vectors = (float *)(first + 0x50) + j * 2; - float *first_source = D_L10_001DA2F0 + j * 2; - for (k = 0; k != 2; k++) { - int index = i * 2 + k; - int limit = float_to_integer((D_L10_001DA270)[index] * 360.0f); - float angle = integer_to_float(*(int *)0x0015f3f8 % limit) / (D_L10_001DA270)[index] - 180.0f; - float wave; - if ((D_L10_001DA2B0)[index] != 0) - wave = FUN_001f9dc8(angle * 0.017453292f); - else - wave = FUN_001f9de0(angle * 0.017453292f); - *first_vectors++ = *first_source++ + wave * 0.125f; + for (i = 0; i < D_L10_0015B340; i++) { + int parity = i & 1; + int *colors = D_L10_0015B348; + unsigned long long color = (long long)colors[parity] | + ((long long)D_L10_00161F50[parity] << 2) | + ((long long)D_L10_00161F58[parity] << 4) | + ((long long)D_L10_00161F60[parity] << 6) | 0x8000000000ULL; + int shade = (D_L10_001DA250)[i]; + *(unsigned long long *)(first + 0x88) = color; + *(unsigned long long *)(second + 0x88) = + (long long)colors[parity] | ((long long)D_L10_00161F50[parity] << 2) | + ((long long)D_L10_00161F58[parity] << 4) | ((long long)D_L10_00161F60[parity] << 6) | + 0x8000000000ULL; + ((int *)(first + 0x40))[0] = shade; + ((int *)(second + 0x40))[2] = shade; + ((int *)(second + 0x40))[0] = shade; + ((int *)(first + 0x40))[3] = shade; + ((int *)(first + 0x40))[2] = shade; + ((int *)(first + 0x40))[1] = shade; + j = 0; + do { + int index = i * 8; + int offset = j * 8; + int next_vector = j + 1; + float *first_vectors = (float *)((unsigned char *)angle_vectors + offset); + float *first_source = D_L10_001DA270 + i * 2; + k = 1; + do { + int limit = float_to_integer(*first_source * 360.0f); + float angle = integer_to_float(*(int *)0x0015f3f8 % limit) / *first_source - 180.0f; + float wave; + if (*(int *)((unsigned char *)D_L10_001DA2B0 + index) != 0) + wave = FUN_001f9dc8(angle * 0.017453292f); + else + wave = FUN_001f9de0(angle * 0.017453292f); + first_source++; + index += 4; + *first_vectors++ = *(float *)((unsigned char *)D_L10_001DA2F0 + offset) + wave * 0.125f; + offset += 4; + k--; + } while (k >= 0); + j = next_vector; + } while (j < 4); + for (k = 0; k < 2; k++) { + float step = (float)k * 0.125f; + first_angles[k] = angles[k]; + first_offsets[k] = angles[k] + step; + second_angles[k] = offsets[k]; + second_offsets[k] = offsets[k] + step; } - } - for (j = 0; j < 2; j++) { - float step = (float)j * 0.125f; - first_angles[j] = angles[j]; - first_offsets[j] = angles[j] + step; - second_angles[j] = offsets[j]; - second_offsets[j] = offsets[j] + step; - } - transform_vectors((float *)first, matrix, 0); - transform_vectors((float *)second, matrix, 0); - for (j = 0; j < 4; j++) { - ((float *)(first + j * 16))[1] += 0.1f; - ((float *)(second + j * 16))[1] += 0.1f; + transform_vectors((float *)first, matrix, 0); + transform_vectors((float *)second, matrix, 0); + first_vectors = (float *)first; + second_vectors = (float *)second; + j = 3; + do { + first_vectors[1] += 0.1f; + first_vectors += 4; + second_vectors[1] += 0.1f; + second_vectors += 4; + j--; + } while (j >= 0); } } } From 24c2d9947820a737342d8ee3a8e887a1c68fc02e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:31:28 +0000 Subject: [PATCH 198/251] decomp: improve FUN_L14_00301fa8 --- src/overlays/shared/gameplay/vendor/003015d0.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/003015d0.c b/src/overlays/shared/gameplay/vendor/003015d0.c index c664a711c..93fab9c1a 100644 --- a/src/overlays/shared/gameplay/vendor/003015d0.c +++ b/src/overlays/shared/gameplay/vendor/003015d0.c @@ -418,9 +418,7 @@ void FUN_L14_00301fa8(char *m) { } else { clear_u64_value(start); } - rounded = point + 3; - if (-1 < point) rounded = point; - rounded = (rounded >> 2) << 2; + rounded = (point / 4) * 4; for (i = 0; i < 4;) { if (i < 2) { packet[0].vertices[i] = *(u128 *)(d + 0x20 + (point << 4)); @@ -460,9 +458,7 @@ void FUN_L14_00301fa8(char *m) { clear_u64_value(start); } if (point == 0) qcopy(end, start); - rounded = point + 3; - if (-1 < point) rounded = point; - rounded = (rounded >> 2) << 2; + rounded = (point / 4) * 4; for (k = 0; k < 4;) { if (k < 2) { packet[0].vertices[k] = *(u128 *)(d + (point << 6) + 0x420 + (strip << 4)); From 7dca9fca0cf3613be3912c1731a7d7462814a70f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:36:44 +0000 Subject: [PATCH 199/251] decomp: improve FUN_L10_002dcc58 --- src/overlays/l10/gameplay/entities/00295a38.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/l10/gameplay/entities/00295a38.c b/src/overlays/l10/gameplay/entities/00295a38.c index e5fe8d8dc..8ca5c57d9 100644 --- a/src/overlays/l10/gameplay/entities/00295a38.c +++ b/src/overlays/l10/gameplay/entities/00295a38.c @@ -2163,7 +2163,7 @@ void FUN_L10_002dcc58(struct Moby *moby) { int group_offset = group * 0x2580; int timer_offset = group * 0x78; for (item = 0; item < 10; item++) { - char *entry = data + (timer_offset + group_table) + item * 4; + char *entry = (data + group_table) + timer_offset + item * 4; char *base = data + group_offset; char *other = data + (group_offset + 0x9600); char *buffer = (char *)scratch + item * 0x10; From 8771e9ca1590aba6f6726bc0f24bbdf340440062 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:33:46 +0000 Subject: [PATCH 200/251] decomp: improve FUN_L06_002ff2c8 --- src/overlays/shared/gameplay/entities/002fdbd0.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002fdbd0.c b/src/overlays/shared/gameplay/entities/002fdbd0.c index 8a4f15a98..8ad7d5077 100644 --- a/src/overlays/shared/gameplay/entities/002fdbd0.c +++ b/src/overlays/shared/gameplay/entities/002fdbd0.c @@ -657,14 +657,15 @@ void FUN_L06_002ff2c8(char *moby) { weight += 4; } while (remaining >= 0); } - i = 0; offset = 0; { + s32 i = 0; f32 *entry = (f32 *)(data + 0x230); f32 *relative_ptr = relative; do { if (hero.vehicle_mode == 1) { - step = D_L06_00161FD0 * frame_time * 0.5f; + step = D_L06_00161FD0 * frame_time; + step *= 0.5f; } else { step = D_L06_00161FD0 * frame_time; } @@ -695,14 +696,14 @@ void FUN_L06_002ff2c8(char *moby) { f32 *next_entry; offset = i * 16; next = i + 1; - if (entry[3] >= 0.6f && + if (*(f32 *)(data + i * 16 + 0x23C) >= 0.6f && (next_entry = (f32 *)(data + 0x230 + next * 16), next_entry[3] >= 0.6f)) { point[0] = fast_cos(*(f32 *)(moby + 0x48)); point[1] = fast_sin_c(*(f32 *)(moby + 0x48)); point[2] = 1.0f; point[3] = 5627.925f; make_hit_descriptor(&shot, (struct Moby *)moby, - entry[3] >= 1.0f && next_entry[3] >= 1.0f ? 0x10001 : 0x10000, point, 1.0f); + *(f32 *)(data + i * 16 + 0x23C) >= 1.0f && next_entry[3] >= 1.0f ? 0x10001 : 0x10000, point, 1.0f); shot.unk18 = 0; shot.unk19 = 1; shot.oclass = *(s16 *)(moby + 0xA6); From 787662fc1faf8f0e934985ad11edfcfd2855aa89 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:41:47 +0000 Subject: [PATCH 201/251] decomp: improve FUN_L00_00237200 --- src/overlays/shared/gameplay/animation/00235878.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/overlays/shared/gameplay/animation/00235878.c b/src/overlays/shared/gameplay/animation/00235878.c index 57dfe04ed..819187a7e 100644 --- a/src/overlays/shared/gameplay/animation/00235878.c +++ b/src/overlays/shared/gameplay/animation/00235878.c @@ -633,18 +633,13 @@ int FUN_L00_00237200(HudElem *e) { points[1].z = 119.5f; { float *point_data; - if (level == 5) { - *(quadword *)&point = *(quadword *)&points[0]; - point_data = (float *)&point; - } else { - *(quadword *)&point = *(quadword *)&points[1]; - point_data = (float *)&point; - } + line = level == 5 ? memcpy(&point, &points[0], 16) : memcpy(&point, &points[1], 16); + point_data = (float *)line; if (FUN_001ff450(D_0013F3D0, point_data) < 5.0f) { *(int *)0x15f648 = y + 100; - extra = current_level_index_sda == 0x10 ? 1 : 0; - elapsed = freeze_stats_time_ref_a[extra]; - extra = freeze_stats_score_ref_a[extra]; + extra = current_level_index_sda == 0x10 ? 4 : 0; + elapsed = *(int *)((char *)freeze_stats_time_ref_a + extra); + extra = *(int *)((char *)freeze_stats_score_ref_a + extra); if (elapsed != 0) { interval = pal_mode != 0 ? 3000 : 3600; minute_scale = interval / 60; From f6974a7b351c09705d078b099ee309bf94d6682c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:42:58 +0000 Subject: [PATCH 202/251] decomp: improve FUN_L00_002d9810 --- src/overlays/shared/gameplay/entities/002d7f88.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002d7f88.c b/src/overlays/shared/gameplay/entities/002d7f88.c index 05f87bd74..fbf68a62a 100644 --- a/src/overlays/shared/gameplay/entities/002d7f88.c +++ b/src/overlays/shared/gameplay/entities/002d7f88.c @@ -924,13 +924,14 @@ void FUN_L00_002d9810(u8 *m) { color = ((u32)(D_L00_00161B10_002d9810 + color) << 24) | D_L00_00161AE0_002d9810; quad.colors[3] = 0; quad.colors[2] = 0; - quad.colors[0] = color; quad.colors[1] = color; + quad.colors[0] = color; for (i = 0; i < 32; i++) { indices = (short *)(D_L00_001E3A80_002d9810 + i * 8); + j = 0; pointB = (char *)quad.points; pointA = (char *)quad.points; - for (j = 0; j < 4; j++) { + for (; j < 4; j++) { short index = *indices; if (j >= 2) FUN_001f9a68_002d9810(D_L00_00161ADC_002d9810 * D_L00_00161AEC_002d9810, From 8d8f18bab5c6adac9d1de7aa4281afd6df1de9dd Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:45:05 +0000 Subject: [PATCH 203/251] decomp: improve FUN_L00_002d5160 --- src/overlays/shared/gameplay/entities/002cfcb8.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002cfcb8.c b/src/overlays/shared/gameplay/entities/002cfcb8.c index 6581b8ecf..a575feafb 100644 --- a/src/overlays/shared/gameplay/entities/002cfcb8.c +++ b/src/overlays/shared/gameplay/entities/002cfcb8.c @@ -2269,6 +2269,7 @@ void FUN_L00_002d5160(unsigned char *m) { f32 forceX, forceY, forceZ, forceW, health, duration; f32 reactionC0, reactionC4; unsigned char *row; + s32 index; unsigned char *effect; if (m[0x20] == 0) @@ -2316,20 +2317,21 @@ void FUN_L00_002d5160(unsigned char *m) { m[0xA4] = 0xFF; FUN_L00_0025d538_2d5160(m, v + 0x60); if (m[0x20] == 3) { - row = D_L00_001B04B0_2d5160[*(s32 *)(v + 0x1E4)]; + index = *(s32 *)(v + 0x1E4); effect = v + 0x180; - FUN_L00_0025ff38_2d5160(64.0f, m, effect, 0, 0, row + 0x10, *(s32 *)row); + FUN_L00_0025ff38_2d5160(64.0f, m, effect, 0, 0, D_L00_001B04B0_2d5160[index] + 0x10, *(s32 *)D_L00_001B04B0_2d5160[index]); } else { - row = D_L00_001B04B0_2d5160[*(s32 *)(v + 0x1E0)]; + index = *(s32 *)(v + 0x1E0); effect = v + 0x180; - FUN_L00_0025ff38_2d5160(24.0f, m, effect, 0, 0, row + 0x10, *(s32 *)row); + FUN_L00_0025ff38_2d5160(24.0f, m, effect, 0, 0, D_L00_001B04B0_2d5160[index] + 0x10, *(s32 *)D_L00_001B04B0_2d5160[index]); } if (*(s32 *)(v + 0x1C0) == 0) { *(s32 *)(v + 0x1C0) = (s32)hero.moby; qcopy(effect, &hero.motion.pos); } FUN_001fef98_2d5160(v + 0x276); - if (*(s32 *)(v + 0x38) != 0) { + index = *(s32 *)(v + 0x38); + if (index != 0) { *(s16 *)(v + 0x276) = FUN_00200250_2d5160(FUN_001fef10_2d5160(FUN_L00_00257be8_2d5160(180.0f, 240.0f))); } *(s32 *)(v + 0x38) = 0; From 2eda04f3ba80ffb5d078b5a16166332a8349beb6 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:49:39 +0000 Subject: [PATCH 204/251] decomp: improve FUN_L06_00303160 --- src/overlays/l06/gameplay/entities/002fd1a0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/overlays/l06/gameplay/entities/002fd1a0.c b/src/overlays/l06/gameplay/entities/002fd1a0.c index 5c1e47001..857151d34 100644 --- a/src/overlays/l06/gameplay/entities/002fd1a0.c +++ b/src/overlays/l06/gameplay/entities/002fd1a0.c @@ -1831,7 +1831,7 @@ extern void FUN_L06_00303b68(struct Moby *); int FUN_L06_00303160(char *moby, int path) { char *data = *(char **)(moby + 0x78); - volatile int *ids = (volatile int *)(data + path * 4); + int *ids = (int *)(data + path * 4); float *first = D_L06_001B0C30_303160[ids[0x60 / 4]]; float *middle = D_L06_001B0C30_303160[ids[0x74 / 4]]; float *third = D_L06_001B0C30_303160[ids[0x88 / 4]]; @@ -1847,11 +1847,11 @@ int FUN_L06_00303160(char *moby, int path) { first_time = *(float *)(data + 0xf4) * (float)(*(int *)first - 1); first_index = truncate_float_303160(first_time); first_index_float = (float)(int)first_index; - first_fraction = first_time - first_index_float; middle_index = truncate_float_303160(*(float *)(data + 0xf4) * (float)(*(int *)middle - 1)); third_time = *(float *)(data + 0xf4) * (float)(*(int *)third - 1); third_fraction = third_time - first_index_float; third_index = truncate_float_303160(third_time); + first_fraction = first_time - first_index_float; lerp_vector_303160(from, first + ((int)first_index * 4 + 4), first + ((int)first_index * 4 + 8), first_fraction); lerp_vector_303160((float *)(moby + 0x10), third + (int)third_index * 4 + 4, third + (int)third_index * 4 + 8, third_fraction); From 689878c7c438227bc6dea63f8f36c1091503853f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:42:29 +0000 Subject: [PATCH 205/251] decomp: improve FUN_L14_002b2928 --- .../shared/gameplay/entities/002b17d8.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002b17d8.c b/src/overlays/shared/gameplay/entities/002b17d8.c index 4adba4fe0..043b4ecd7 100644 --- a/src/overlays/shared/gameplay/entities/002b17d8.c +++ b/src/overlays/shared/gameplay/entities/002b17d8.c @@ -348,7 +348,7 @@ void FUN_L14_002b2928(struct Moby *m) Vec4 *template; Vec4 *beam_start; Vec4 *beam_end; - u32 color; + u64 color; s32 i; { @@ -380,12 +380,11 @@ void FUN_L14_002b2928(struct Moby *m) quad.texture_coordinates[3][0] = 1.0f; quad.texture_coordinates[3][1] = 1.0f; corner = &quad.positions[0]; - template = &D_L14_001D8850[0]; do { + template = &D_L14_001D8850[3 - i]; FUN_001f9a68(corner, template, 0.4f); transform_vector_l14(corner, corner, &basis[0]); corner++; - template++; i--; } while (i >= 0); draw_geometry_quad_l14(&quad, 0, 0); @@ -405,12 +404,11 @@ void FUN_L14_002b2928(struct Moby *m) quad.colors[0] = 0x202020FF; i = 3; corner = &quad.positions[0]; - template = &D_L14_001D8850[0]; do { + template = &D_L14_001D8850[3 - i]; FUN_001f9a68(corner, template, 0.2f); transform_vector_l14(corner, corner, &basis[0]); corner++; - template++; i--; } while (i >= 0); draw_geometry_quad_l14(&quad, 0, 0); @@ -429,12 +427,11 @@ void FUN_L14_002b2928(struct Moby *m) quad.colors[0] = 0x4020FF20; i = 3; corner = &quad.positions[0]; - template = &D_L14_001D8850[0]; do { + template = &D_L14_001D8850[3 - i]; FUN_001f9a68(corner, template, 0.2f); transform_vector_l14(corner, corner, &basis[0]); corner++; - template++; i--; } while (i >= 0); draw_geometry_quad_l14(&quad, 0, 0); @@ -455,12 +452,11 @@ void FUN_L14_002b2928(struct Moby *m) quad.colors[0] = color | 0xFF2020; i = 3; corner = &quad.positions[0]; - template = &D_L14_001D8850[0]; do { + template = &D_L14_001D8850[3 - i]; FUN_001f9a68(corner, template, D_L14_001614C0); transform_vector_l14(corner, corner, &basis[0]); corner++; - template++; i--; } while (i >= 0); draw_geometry_quad_l14(&quad, 0, 0); @@ -479,12 +475,11 @@ void FUN_L14_002b2928(struct Moby *m) quad.colors[0] = color | 0xFF2020; i = 3; corner = &quad.positions[0]; - template = &D_L14_001D8850[0]; do { + template = &D_L14_001D8850[3 - i]; FUN_001f9a68(corner, template, D_L14_001614C0); transform_vector_l14(corner, corner, &basis[0]); corner++; - template++; i--; } while (i >= 0); draw_geometry_quad_l14(&quad, 0, 0); From 55d6d81c587c5a3de33f15c75bd45b9fb3585808 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:53:57 +0000 Subject: [PATCH 206/251] decomp: improve update_motion_and_emit_effects --- src/overlays/l13/gameplay/vendor/003058a8.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/overlays/l13/gameplay/vendor/003058a8.c b/src/overlays/l13/gameplay/vendor/003058a8.c index 1f240a581..4e4a010c2 100644 --- a/src/overlays/l13/gameplay/vendor/003058a8.c +++ b/src/overlays/l13/gameplay/vendor/003058a8.c @@ -2243,6 +2243,7 @@ void FUN_L13_0030c3b8(struct Moby *moby) { FUN_00218888(&position, &velocity, &acceleration, D_L13_00161F08, D_L13_00161F0C, a, b, c, -1); } while (i >= 0); + amount = 0.017453292f; velocity.f[3] = D_L13_00161F64; acceleration.f[3] = D_L13_00161F68; i = 1; @@ -2256,12 +2257,12 @@ void FUN_L13_0030c3b8(struct Moby *moby) { i--; velocity.f[2] = random_float_between_alt(D_L13_00161F44 * frame_time * 0.7f, D_L13_00161F44 * frame_time * 1.5f); - angle = random_float_between_alt(-D_L13_00161F54, D_L13_00161F54); + angle = random_float_between_alt(-D_L13_00161F54, D_L13_00161F54) * amount; direction = FUN_001fa580(FUN_001f9e90(*(float *)data, *(float *)(data + 4)), - angle * 0.017453292f); + angle); acceleration.f[0] = FUN_001f9dc8(direction) * (D_L13_00161F48 * frame_time); direction = FUN_001fa580(FUN_001f9e90(*(float *)data, *(float *)(data + 4)), - angle * 0.017453292f); + angle); acceleration.f[1] = FUN_001f9de0(direction) * (D_L13_00161F48 * frame_time); acceleration.f[2] = 0.0f; acceleration.f[2] = random_float_between_alt(D_L13_00161F4C * frame_time * 0.7f, @@ -2287,14 +2288,14 @@ void FUN_L13_0030c3b8(struct Moby *moby) { *(float *)((char *)moby + 0x2c) = *(float *)(data + 0x1c) * FUN_001fa6c0(life) / FUN_001fa6c0(*(short *)(data + 0x1a) / 4); } - if (FUN_001f9770(data + 0x18) == 0) { - if (moby->command != 1) return; - if (FUN_001efa68(&old_pos, &moby->pos, 2, (void *)D_001413D0, 0) == 0) return; - FUN_L13_0030c2b0(moby); - goto remove; - } + if (FUN_001f9770(data + 0x18) == 0) goto collision; } -remove: + FUN_0020c828(moby); + return; +collision: + if (moby->command != 1) return; + if (FUN_001efa68(&old_pos, &moby->pos, 2, (void *)D_001413D0, 0) == 0) return; + FUN_L13_0030c2b0(moby); FUN_0020c828(moby); } #endif From 57022148d81f65d6b5ea04f7730a74f348ef60e1 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:51:05 +0000 Subject: [PATCH 207/251] decomp: improve FUN_L08_002dc9a8 --- src/overlays/l08/gameplay/entities/002b8228.c | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/overlays/l08/gameplay/entities/002b8228.c b/src/overlays/l08/gameplay/entities/002b8228.c index b92aa260e..c5fcbe5aa 100644 --- a/src/overlays/l08/gameplay/entities/002b8228.c +++ b/src/overlays/l08/gameplay/entities/002b8228.c @@ -1428,10 +1428,7 @@ char *FUN_L08_002dc8a0(char *src, char *pos, char *vec) { } return moby; } -#ifndef NON_MATCHING -INCLUDE_ASM("config/us/overlays/asm/FUN_L08_002dc9a8.s", FUN_L08_002dc9a8); -#else -extern int FUN_L08_002dc9a8_collision(float, void *, int, void *, void *) __asm__("FUN_L00_001f2868"); +extern int FUN_L08_002dc9a8_collision(void *, float, int, void *, void *) __asm__("FUN_L00_001f2868"); extern int FUN_L08_002dc9a8_trace(void *, void *, int, void *, int) __asm__("FUN_001efa68"); extern void FUN_L08_002dc9a8_transform(void *, void *, void *) __asm__("FUN_001f9a10"); extern void FUN_L08_002dc9a8_setup(void *) __asm__("FUN_001f99f8"); @@ -1446,7 +1443,7 @@ extern int FUN_L08_002dc9a8_random_below(int) __asm__("FUN_00213260"); extern int FUN_L08_002dc9a8_random_color(int) __asm__("FUN_001f96f8"); extern int FUN_L08_002dc9a8_blend(int, int) __asm__("FUN_L00_00257b90"); extern int FUN_L08_002dc9a8_color(float, int, int) __asm__("FUN_L08_00264930"); -extern void FUN_L08_002dc9a8_emit(float, void *, void *, int, int, int, int) __asm__("FUN_L00_0026bed0"); +extern void FUN_L08_002dc9a8_emit(void *, void *, int, int, float, int, int) __asm__("FUN_L00_0026bed0"); extern void FUN_L08_002dc9a8_special(void *, float, float, float) __asm__("FUN_00214db0"); extern void FUN_L08_002dc9a8_start(int, int, void *) __asm__("FUN_0022da68"); extern void FUN_L08_002dc9a8_finish(void *) __asm__("FUN_0020c828"); @@ -1490,7 +1487,7 @@ void FUN_L08_002dc9a8(struct Moby *moby) { int i, axis; float angle; - if (FUN_L08_002dc9a8_collision(0.5f, m + 0x10, 0, m, 0) != 0 && + if (FUN_L08_002dc9a8_collision(m + 0x10, 0.5f, 0, m, 0) != 0 && D_L08_00174658_2DC9A8 != 0 && (D_L08_00174658_2DC9A8 != *(int *)(data + 0x20) || *(int *)(data + 0x14) != 0)) { m[0x20] = 99; @@ -1530,7 +1527,7 @@ void FUN_L08_002dc9a8(struct Moby *moby) { record.scale = 1.0f; FUN_L08_002dc9a8_setup(record.velocity); record.state = 0; - FUN_L08_002dc9a8_collision(1.0f, m + 0x10, 9, m, record.velocity); + FUN_L08_002dc9a8_collision(m + 0x10, 1.0f, 9, m, record.velocity); FUN_L08_002dc9a8_start(0, 0, m); for (i = 0; i < 50; i++) { axis = i % 4; @@ -1552,6 +1549,7 @@ void FUN_L08_002dc9a8(struct Moby *moby) { radius *= 0.717f; record.pos[2] -= radius; effect[2] -= frame_time * 8.0f; + position = effect; switch (axis) { case 0: { int color, color2, alpha; @@ -1559,14 +1557,14 @@ void FUN_L08_002dc9a8(struct Moby *moby) { color = FUN_L08_002dc9a8_random_color(60); color2 = FUN_L08_002dc9a8_random_color(120); alpha = FUN_L08_002dc9a8_blend(color, color2); - FUN_L08_002dc9a8_emit(size, record.pos, effect, 0x1f101820, 0x101010, alpha, 0); + FUN_L08_002dc9a8_emit(record.pos, position, 0x1f101820, 0x101010, size, alpha, 0); } break; case 2: { int color, color2, alpha; color = FUN_L08_002dc9a8_random_below(100) < 40 ? 0x5ff8f8f8 : 0x2f486078; color2 = FUN_L08_002dc9a8_random_color(30); alpha = FUN_L08_002dc9a8_random_color(45); - FUN_L08_002dc9a8_emit(150000.0f, record.pos, effect, color, 0x0f000020, + FUN_L08_002dc9a8_emit(record.pos, position, color, 0x0f000020, 150000.0f, FUN_L08_002dc9a8_blend(color2, alpha), 2); } break; case 3: { @@ -1576,12 +1574,12 @@ void FUN_L08_002dc9a8(struct Moby *moby) { color2 = FUN_L08_002dc9a8_color(FUN_L08_002dc9a8_random(0.5f, 1.0f), 0, 0x5f5f5f); radius = FUN_L08_002dc9a8_random(0.0f, 1.0f) * D_0015ED6C_2DC9A8; - FUN_L08_002dc9a8_special(effect, radius, angle, + FUN_L08_002dc9a8_special(position, radius, angle, FUN_L08_002dc9a8_random_word()); radius = FUN_L08_002dc9a8_random(150000.0f, 200000.0f); alpha = FUN_L08_002dc9a8_random_color(60); alpha = FUN_L08_002dc9a8_blend(alpha, FUN_L08_002dc9a8_random_color(120)); - FUN_L08_002dc9a8_emit(radius, record.pos, effect, color, color2, + FUN_L08_002dc9a8_emit(record.pos, position, color, color2, radius, alpha, 3); } break; case 1: break; @@ -1591,7 +1589,6 @@ void FUN_L08_002dc9a8(struct Moby *moby) { } break; } } -#endif #include "sda.h" /* Rocket guidance, route traversal, launch effects, and destruction. */ From bebaf133093593e0e2c526841d8390f73fbf8e7b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:02:15 +0000 Subject: [PATCH 208/251] decomp: improve FUN_L00_00237200 --- src/overlays/shared/gameplay/animation/00235878.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/gameplay/animation/00235878.c b/src/overlays/shared/gameplay/animation/00235878.c index 819187a7e..30239c180 100644 --- a/src/overlays/shared/gameplay/animation/00235878.c +++ b/src/overlays/shared/gameplay/animation/00235878.c @@ -641,14 +641,16 @@ int FUN_L00_00237200(HudElem *e) { elapsed = *(int *)((char *)freeze_stats_time_ref_a + extra); extra = *(int *)((char *)freeze_stats_score_ref_a + extra); if (elapsed != 0) { + const char *message; interval = pal_mode != 0 ? 3000 : 3600; - minute_scale = interval / 60; seconds = elapsed / interval; + minute_scale = interval / 60; remainder = elapsed - seconds * interval; - width = remainder / minute_scale; - remainder = (remainder - width * minute_scale) * 100 / minute_scale; + other_left = remainder / minute_scale; + remainder = (remainder - other_left * minute_scale) * 100 / minute_scale; line = freeze_stats_time_format; - FUN_00116248(text, line, FUN_00203ad8(0x531b), seconds, width, remainder); + message = FUN_00203ad8(0x531b); + FUN_00116248(text, line, message, seconds, other_left, remainder); FUN_0023cf80(0x100, y + 0x28, color, text); if (extra != 0) { FUN_00116248(text, freeze_stats_score_format, FUN_00203ad8(0x531c), extra); From 9a55928dae8c01bd97d93758573bff0325da062a Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:04:43 +0000 Subject: [PATCH 209/251] decomp: improve FUN_L07_00319040 --- src/overlays/l07/gameplay/entities/00312948.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/overlays/l07/gameplay/entities/00312948.c b/src/overlays/l07/gameplay/entities/00312948.c index ad254261c..b1472b26b 100644 --- a/src/overlays/l07/gameplay/entities/00312948.c +++ b/src/overlays/l07/gameplay/entities/00312948.c @@ -1884,6 +1884,7 @@ void FUN_L07_00319040(struct Moby *moby) { f32 speed; union { s32 bits; f32 value; } one; f32 stable_one; + f32 effect_scale; f32 turn; f32 new_speed; f32 max_speed; @@ -1968,10 +1969,14 @@ void FUN_L07_00319040(struct Moby *moby) { make_hit_descriptor_19040(contact, moby, 0x10001, stable_one, &dir); qcopy(&probe, &moby->pos); probe.f[2] += 0.75f; - if (!probe_world_sphere(0.75f, &probe, 0x10, moby, contact) || + if (!(!probe_world_sphere(0.75f, &probe, 0x10, moby, contact) || D_L07_00173ED8 == NULL || D_L07_00173ED8->oclass == 0x363 || D_L07_00173ED8->oclass == 0x456 || D_L07_00173ED8->oclass == 0x458 || - D_L07_00173ED8->oclass == 0x365 || D_L07_00173ED8->oclass == 0x367) { + D_L07_00173ED8->oclass == 0x365 || D_L07_00173ED8->oclass == 0x367)) { + /* The saved descriptor scale is exactly 1.0f; its difference is +0.0f. */ + effect_scale = stable_one; + turn = stable_one - stable_one; + } else { qcopy(&probe, &moby->pos); probe.f[2] += 0.55f; if (coll_sphere(0.55f, &probe, 0, moby)) { @@ -1979,10 +1984,11 @@ void FUN_L07_00319040(struct Moby *moby) { add_vector_xyz(&moby->pos, &moby->pos, &push); } if (!tick_countdown_32_alt((s32 *)(vars + 0x78))) break; - /* The timeout path reloads the effect scale in retail. */ - stable_one = 1.0f; + /* Reload the IEEE-754 effect scale on timeout. */ + *(s32 *)&effect_scale = 0x3f800000; + turn = 0.0f; } - FUN_L00_0025e450(moby, &dir, NULL, 0.0f, 0.0f, 3, 3, 5, 2.0f, 1.0f, 4.0f, stable_one, 2, 7.0f, 0, 1, -1, 0); + FUN_L00_0025e450(moby, &dir, NULL, turn, turn, 3, 3, 5, 2.0f, effect_scale, 4.0f, effect_scale, 2, 7.0f, 0, 1, -1, 0); } mark_moby_for_removal(moby); return; From a4a6c8a3068d4a8a6f7afc0125e685da94484dbc Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:06:06 +0000 Subject: [PATCH 210/251] decomp: improve FUN_L10_002da690 --- src/overlays/l10/gameplay/entities/00295a38.c | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/overlays/l10/gameplay/entities/00295a38.c b/src/overlays/l10/gameplay/entities/00295a38.c index 8ca5c57d9..1e3f1101d 100644 --- a/src/overlays/l10/gameplay/entities/00295a38.c +++ b/src/overlays/l10/gameplay/entities/00295a38.c @@ -1995,7 +1995,14 @@ void FUN_L10_002da690(void *moby) { int i, group, row, vertex; float fade, phase; char *transform; - float *matrix1, *matrix2, *uv1, *uv2; + unsigned char *order; + int group_age; + char *age_base; + char *ages; + int group_vertices; + float *matrix1; + int next_group, next_row; + float *matrix2, *uv1, *uv2; { float distance = vector_distance_da690(&((struct Moby *)moby)->pos, &D_L10_00167240); @@ -2024,11 +2031,11 @@ void FUN_L10_002da690(void *moby) { u64 texture = get_effect_texture_da690(14); u64 packet_flags = ((u64)D_L10_00161C70) | ((u64)D_L10_00161C74 << 2) | ((u64)D_L10_00161C78 << 4) | ((u64)D_L10_00161C7C << 6) | 0x8000000000ULL; - ((u64 *)buffers.packet.fields.matrix2)[5] = texture; ((u64 *)buffers.matrix1)[5] = texture; + ((u64 *)buffers.packet.fields.matrix2)[5] = texture; ((u64 *)buffers.matrix1)[6] = 0xff9000000260ULL; - ((u64 *)buffers.matrix1)[7] = packet_flags; ((u64 *)buffers.packet.fields.matrix2)[6] = 0xff9000000260ULL; + ((u64 *)buffers.matrix1)[7] = packet_flags; ((u64 *)buffers.packet.fields.matrix2)[4] = 0; ((u64 *)buffers.matrix1)[4] = 0; ((u64 *)buffers.packet.fields.matrix2)[7] = packet_flags; @@ -2048,16 +2055,16 @@ void FUN_L10_002da690(void *moby) { } while (--i >= 0); } { - char *age_base = base + 0x10000; + age_base = base + 0x10000; group = 0; do { - int next_group = group + 1; + next_group = group + 1; phase = 0.0f; row = 0; do { - int next_row; phase += D_L10_00161D60; if (phase > 1.0f) phase -= 1.0f; + group_vertices = (int)((long long)group * 0x2580); next_row = row + 1; for (i = 0; i < 4; i++) { float value = ((float *)0x001d9ff0)[i * 2] + phase + *(float *)(base + 0x12de0); @@ -2067,13 +2074,13 @@ void FUN_L10_002da690(void *moby) { i = 0; if (*(int *)(data + 4) > 0) { do { - unsigned char *order = (unsigned char *)(data + 0x10); - int group_age = group * 0x78; - int group_vertices = (int)((long long)group * 0x2580); - char *ages = age_base + 0x2c00; - int age = *(int *)(ages + (order[i] * 4 + group_age)); + int age; float progress; unsigned int color; + order = (unsigned char *)(data + 0x10); + group_age = group * 0x78; + ages = age_base + 0x2c00; + age = *(int *)(ages + (order[i] * 4 + group_age)); if (age > D_L10_00161D68) { progress = convert_integer_to_float_da690(age - D_L10_00161D68) / convert_integer_to_float_da690(D_L10_00161D64 - D_L10_00161D68); From 4e797b40c9bb8b705ddb02c16b49053e2d5e0b73 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:06:23 +0000 Subject: [PATCH 211/251] decomp: improve FUN_L14_003017f8 --- .../shared/gameplay/vendor/003015d0.c | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/003015d0.c b/src/overlays/shared/gameplay/vendor/003015d0.c index 93fab9c1a..9a2543b4c 100644 --- a/src/overlays/shared/gameplay/vendor/003015d0.c +++ b/src/overlays/shared/gameplay/vendor/003015d0.c @@ -186,17 +186,24 @@ void FUN_L14_003017f8(char *m) { { int i; for (i = 0; i < 32; i++) { - t = (0.5f - convert_integer_to_float(i) / convert_integer_to_float(31)) * length; - if ((unsigned)(i - 3) < 26) { - set_vector_xyz(path_a[i], 0.0f, D_L14_001620FC); - set_vector_xyz(path_b[i], 0.0f, D_L14_00162100 * D_0015ED6C); - } else { + t = convert_integer_to_float(i) / convert_integer_to_float(31); + { + float y = 0.5f - t; + t = y * length; + } + if ((unsigned)(i - 3) >= 26) { clear_u64_value(path_a[i]); clear_u64_value(path_b[i]); + } else { + set_vector_xyz(path_a[i], 0.0f, D_L14_001620FC); + set_vector_xyz(path_b[i], 0.0f, D_L14_00162100 * D_0015ED6C); + } + { + float *point = path_a[i]; + y = point[1]; + point[3] = 1.0f; + point[1] = y + t; } - y = path_a[i][1]; - path_a[i][3] = 1.0f; - path_a[i][1] = y + t; } } { @@ -225,8 +232,8 @@ void FUN_L14_003017f8(char *m) { index += 4; d[0x18 + i] = index; offset = (i << 4) + (int)d; - *(u128 *)((char *)offset + 0x420) = *(u128 *)(d + 0x20 + (index << 4)); - *(u128 *)((char *)offset + 0x520) = *(u128 *)(d + 0x220 + (index << 4)); + qcopy((char *)offset + 0x420, d + 0x20 + (index << 4)); + qcopy((char *)offset + 0x520, d + 0x220 + (index << 4)); for (j = 2; j >= 0; j--) { set_vector_xyz(delta_a, 0.1f, 0.1f); set_vector_xyz(d + 0x560 + (i << 4) + ((2 - j) << 6), 0.0f, From d88e321266d4a41938d97f72f442e6f6bfed769c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:07:25 +0000 Subject: [PATCH 212/251] decomp: improve FUN_L10_002e91b8 --- .../shared/gameplay/vendor/002e3de8.c | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index 1b91f4a0d..6fe423454 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -142,34 +142,34 @@ void FUN_L10_002e91b8(unsigned char *m) { *(long long *)(second + 0x70) = 0; *(int *)(second + 0x4c) = 0; *(int *)(second + 0x44) = 0; - first_source = D_L10_001DA350; second_source = D_L10_001DA310; - first_vectors = (float *)first; + first_source = D_L10_001DA350; second_vectors = (float *)second; second_angles = (float *)second; + first_vectors = (float *)first; i = 3; do { qcopy(first_vectors, first_source); qcopy(second_angles, second_source); + second_source += 4; second_angles += 4; first_source += 4; - second_source += 4; + i--; first_vectors[0] *= scale[0]; second_vectors[0] *= scale[0]; first_vectors[2] *= scale[1]; second_vectors[2] *= scale[1]; first_vectors += 4; second_vectors += 4; - i--; } while (i >= 0); if (D_L10_0015B340 > 0) { float *angle_vectors = (float *)(first + 0x50); - float *first_angles = (float *)(second + 0x50); float *angles = (float *)(first + 0x58); + float *first_angles = (float *)(second + 0x50); float *first_offsets = (float *)(second + 0x58); - float *second_angles = (float *)(second + 0x60); float *offsets = (float *)(first + 0x68); + float *second_angles = (float *)(second + 0x60); float *second_offsets = (float *)(second + 0x68); for (i = 0; i < D_L10_0015B340; i++) { int parity = i & 1; @@ -192,11 +192,11 @@ void FUN_L10_002e91b8(unsigned char *m) { ((int *)(first + 0x40))[1] = shade; j = 0; do { - int index = i * 8; int offset = j * 8; + int index = i * 8; int next_vector = j + 1; - float *first_vectors = (float *)((unsigned char *)angle_vectors + offset); float *first_source = D_L10_001DA270 + i * 2; + float *first_vectors = (float *)((unsigned char *)angle_vectors + offset); k = 1; do { int limit = float_to_integer(*first_source * 360.0f); @@ -214,25 +214,30 @@ void FUN_L10_002e91b8(unsigned char *m) { } while (k >= 0); j = next_vector; } while (j < 4); - for (k = 0; k < 2; k++) { - float step = (float)k * 0.125f; - first_angles[k] = angles[k]; - first_offsets[k] = angles[k] + step; - second_angles[k] = offsets[k]; - second_offsets[k] = offsets[k] + step; + { + int k; + for (k = 0; k < 2; k++) { + float step = (float)k * 0.125f; + first_angles[k] = angles[k]; + first_offsets[k] = angles[k] + step; + second_angles[k] = offsets[k]; + second_offsets[k] = offsets[k] + step; + } } transform_vectors((float *)first, matrix, 0); transform_vectors((float *)second, matrix, 0); - first_vectors = (float *)first; - second_vectors = (float *)second; - j = 3; - do { - first_vectors[1] += 0.1f; - first_vectors += 4; - second_vectors[1] += 0.1f; - second_vectors += 4; - j--; - } while (j >= 0); + { + float *first_vectors = (float *)first; + float *second_vectors = (float *)second; + int j = 3; + do { + first_vectors[1] += 0.1f; + first_vectors += 4; + second_vectors[1] += 0.1f; + second_vectors += 4; + j--; + } while (j >= 0); + } } } } From 07cce4da23c7a1e0781c112bb837d316d9c1c30c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:03:06 +0000 Subject: [PATCH 213/251] decomp: improve FUN_L00_0020dd20 --- src/overlays/shared/ui/help/0020c758.c | 31 +++++++++++++------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index d51d775c1..f595e8547 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -691,17 +691,16 @@ void FUN_L00_0020dd20(void) { f32 tenth = 0.1f; f32 one = 1.0f; - struct Hero *hero_ptr = &hero; i = 0; do { slot = (u8 **)&hero.unkD00 + i; if (*slot && *(s32 *)(*slot + 0x34)) { next = i + 1; if (FUN_00213ed8_20dd20((f32 *)(*slot + 8), zero, frame_scale * tenth) == zero) - FUN_L00_0024f0e8_20dd20((u8 *)hero_ptr->moby, slot); + FUN_L00_0024f0e8_20dd20((u8 *)hero.moby, slot); } else { active = 0; - if (hero_ptr->unk20AB && (i == 0 || hero_ptr->unk20AB == 2)) + if (hero.unk20AB && (i == 0 || hero.unk20AB == 2)) active = 1; if (hero.unk20AF) { active = 0; @@ -713,7 +712,7 @@ void FUN_L00_0020dd20(void) { slot = (u8 **)&hero.unkD00 + i; next = i + 1; if (*slot == 0) { - *slot = FUN_L00_0024f028_20dd20((u8 *)hero_ptr->moby, D_L00_0015F6A0_20dd20[i]); + *slot = FUN_L00_0024f028_20dd20((u8 *)hero.moby, D_L00_0015F6A0_20dd20[i]); *(s32 *)(*slot + 8) = 0; *(s32 *)(*slot + 0x18) = D_L00_00197300_20dd20[D_L00_00197BC0_20dd20[next]]; } @@ -723,13 +722,13 @@ void FUN_L00_0020dd20(void) { if (*slot == 0) goto next_slot; if (FUN_00213ed8_20dd20((f32 *)(*slot + 8), zero, frame_scale * tenth) == zero) - FUN_L00_0024f0e8_20dd20((u8 *)hero_ptr->moby, slot); + FUN_L00_0024f0e8_20dd20((u8 *)hero.moby, slot); } } obj = *((u8 **)&hero.unkD00 + i); if (obj) { - moby = (u8 *)hero_ptr->moby; - same = moby[0x52] != ((u8 *)hero_ptr->moby)[0x53]; + moby = (u8 *)hero.moby; + same = moby[0x52] != ((u8 *)hero.moby)[0x53]; if (hero.unkD08[0] && !hero.unkD14) { FUN_00213ed8_20dd20((f32 *)(obj + 8), zero, frame_scale * tenth); } else if (*(s32 *)(obj + 0x34) == 0) { @@ -737,11 +736,11 @@ void FUN_L00_0020dd20(void) { } change = 0; if (same && hero.unkA9C) { - if (FUN_L00_002050b8_20dd20(obj[0x23]) != FUN_L00_002050b8_20dd20(((u8 *)hero_ptr->moby)[0x53])) + if (FUN_L00_002050b8_20dd20(obj[0x23]) != FUN_L00_002050b8_20dd20(((u8 *)hero.moby)[0x53])) change = obj[0x22] != obj[0x23]; } *(u16 *)(obj + 0x30) = change; - handled = FUN_L00_0020d5d0_20dd20(((u8 *)hero_ptr->moby)[0x53], &angle); + handled = FUN_L00_0020d5d0_20dd20(((u8 *)hero.moby)[0x53], &angle); if (handled == 0 && obj[0x32] == 0) goto ordinary_update; { @@ -782,7 +781,7 @@ void FUN_L00_0020dd20(void) { unhandled_update: { if (obj[0x33] == 0) { - obj[0x23] = FUN_L00_0020d5b8_20dd20((u8 *)hero_ptr->moby, ((u8 *)hero_ptr->moby)[0x53]); + obj[0x23] = FUN_L00_0020d5b8_20dd20((u8 *)hero.moby, ((u8 *)hero.moby)[0x53]); obj[0x21] = 0; obj[0x33] = 1; *(s32 *)(obj + 0x24) = 0; @@ -815,7 +814,7 @@ void FUN_L00_0020dd20(void) { enabled[1] = 0; } } - FUN_L00_0024f190_20dd20((u8 *)hero_ptr->moby, obj); + FUN_L00_0024f190_20dd20((u8 *)hero.moby, obj); } goto next_slot; ordinary_update: @@ -824,7 +823,7 @@ void FUN_L00_0020dd20(void) { j = 0; do { if (!same || j == 1) - obj[0x22 + j] = FUN_L00_0020d5b8_20dd20((u8 *)hero_ptr->moby, ((u8 *)hero_ptr->moby)[0x52 + j]); + obj[0x22 + j] = FUN_L00_0020d5b8_20dd20((u8 *)hero.moby, ((u8 *)hero.moby)[0x52 + j]); j++; } while (j < 2); } @@ -838,9 +837,9 @@ void FUN_L00_0020dd20(void) { } } else { if (!same) - obj[0x20] = ((u8 *)hero_ptr->moby)[0x50]; - obj[0x21] = ((u8 *)hero_ptr->moby)[0x51]; - *(f32 *)(obj + 0x24) = *(f32 *)((u8 *)hero_ptr->moby + 0x54); + obj[0x20] = ((u8 *)hero.moby)[0x50]; + obj[0x21] = ((u8 *)hero.moby)[0x51]; + *(f32 *)(obj + 0x24) = *(f32 *)((u8 *)hero.moby + 0x54); } { u8 *symbol = obj + 0x22; @@ -860,7 +859,7 @@ void FUN_L00_0020dd20(void) { enabled[1] = 0; } } - FUN_L00_0024f190_20dd20((u8 *)hero_ptr->moby, obj); + FUN_L00_0024f190_20dd20((u8 *)hero.moby, obj); } } next_slot: From 37128ce088a1a555e1e1197353dfe0887f240c7d Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:32:49 +0000 Subject: [PATCH 214/251] decomp: improve update_hero_held_items_and_orientation --- src/overlays/shared/ui/help/0020c758.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index f595e8547..0fcb11fff 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -1032,10 +1032,7 @@ void FUN_L00_0020e728(void) { if (id == hero_state->unk2298) { s32 anim; ID_20e4c8 *definition = &D_L00_00179AC0_c[id]; - if (hero_state->state.control_mode == 12) - anim = definition->f2C; - else - anim = definition->f28; + anim = *(hero_state->state.control_mode == 12 ? &definition->f2C : &definition->f28); if (anim != -1 && (*slot)[0x23] != anim) { hero_state->unk2294 = anim; FUN_L00_0024f3e0((u8 *)hero_state->moby, *slot, hero_state->unk2294, 0, From efae16062be062b4c7c0a6edbfcdd101789b8688 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:33:45 +0000 Subject: [PATCH 215/251] decomp: improve FUN_L00_00237200 --- src/overlays/shared/gameplay/animation/00235878.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/overlays/shared/gameplay/animation/00235878.c b/src/overlays/shared/gameplay/animation/00235878.c index 30239c180..a20d99c2e 100644 --- a/src/overlays/shared/gameplay/animation/00235878.c +++ b/src/overlays/shared/gameplay/animation/00235878.c @@ -637,17 +637,17 @@ int FUN_L00_00237200(HudElem *e) { point_data = (float *)line; if (FUN_001ff450(D_0013F3D0, point_data) < 5.0f) { *(int *)0x15f648 = y + 100; - extra = current_level_index_sda == 0x10 ? 4 : 0; - elapsed = *(int *)((char *)freeze_stats_time_ref_a + extra); - extra = *(int *)((char *)freeze_stats_score_ref_a + extra); + extra = current_level_index_sda == 0x10 ? 1 : 0; + elapsed = freeze_stats_time_ref_a[extra]; + extra = freeze_stats_score_ref_a[extra]; if (elapsed != 0) { const char *message; interval = pal_mode != 0 ? 3000 : 3600; seconds = elapsed / interval; - minute_scale = interval / 60; + other_width = interval / 60; remainder = elapsed - seconds * interval; - other_left = remainder / minute_scale; - remainder = (remainder - other_left * minute_scale) * 100 / minute_scale; + other_left = remainder / other_width; + remainder = (remainder - other_left * other_width) * 100 / other_width; line = freeze_stats_time_format; message = FUN_00203ad8(0x531b); FUN_00116248(text, line, message, seconds, other_left, remainder); From 0d6f5e0b1e727591f7335e7817455569d6b0cafb Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:41:32 +0000 Subject: [PATCH 216/251] decomp: improve FUN_L14_00301fa8 --- src/overlays/shared/gameplay/vendor/003015d0.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/003015d0.c b/src/overlays/shared/gameplay/vendor/003015d0.c index 9a2543b4c..bef172f69 100644 --- a/src/overlays/shared/gameplay/vendor/003015d0.c +++ b/src/overlays/shared/gameplay/vendor/003015d0.c @@ -369,6 +369,8 @@ extern int D_L14_001620E4 __attribute__((sda)); extern int D_L14_001620E8 __attribute__((sda)); extern int D_L14_001620EC __attribute__((sda)); +extern char D_L14_001674C0[]; + void FUN_L14_00301fa8(char *m) { char *d = *(char **)(m + 0x78); VendorBeamFrame *frame = &D_L14_001600EC[*(int *)d]; @@ -385,12 +387,13 @@ void FUN_L14_00301fa8(char *m) { int color; u8 *indices; void *src; + float t; FUN_001fa050(base, &frame->pad40[0x30]); FUN_001fa2d8(matrix, base); frame = &D_L14_001600EC[*(int *)d]; qcopy(base + 12, &frame->origin); - subtract_vector_xyz(direction, (void *)0x1674c0, &frame->origin); + subtract_vector_xyz(direction, D_L14_001674C0, &frame->origin); transform_vector_xyz(direction, direction, matrix); { @@ -443,9 +446,10 @@ void FUN_L14_00301fa8(char *m) { add_vector_xyz(&packet[0].vertices[i], &packet[0].vertices[i], src); } } + t = convert_integer_to_float(point - rounded) * 0.25f; j = i++; packet[0].uv[j][0] = ((float *)0x001e5fd0)[j * 2] + - convert_integer_to_float(point - rounded) * 0.25f; + t; } draw_geometry_quad(&packet[0], base, 0); } @@ -483,9 +487,10 @@ void FUN_L14_00301fa8(char *m) { add_vector_xyz(&packet[0].vertices[k], &packet[0].vertices[k], src); } } + t = convert_integer_to_float(point - rounded) * 0.25f; j = k++; packet[0].uv[j][0] = ((float *)0x001e5fd0)[j * 2] + - convert_integer_to_float(point - rounded) * 0.25f; + t; } draw_geometry_quad(&packet[0], base, 0); } From a38406f29400006cfed8063756fbc3e96d0079a9 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:46:20 +0000 Subject: [PATCH 217/251] decomp: improve update_leg_rig_motion --- src/overlays/l04/runtime/dma/002922d0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/l04/runtime/dma/002922d0.c b/src/overlays/l04/runtime/dma/002922d0.c index f38539468..c614a1fe8 100644 --- a/src/overlays/l04/runtime/dma/002922d0.c +++ b/src/overlays/l04/runtime/dma/002922d0.c @@ -513,7 +513,7 @@ int FUN_L04_00295778(struct Moby *m, LegRig *rig, float amount, float target, fl { int i; for (i = 0; i < 8 && rig_probe((float *)local.joints, probe_start, probe_end, 4, m); i++) { - *(u128 *)local.joints = *(u128 *)D_L04_00173FF0; + qcopy(local.joints, D_L04_00173FF0); flags |= 1; } } From 7944784922eeeaf8e5290a8ce04dad519643c0ba Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:48:07 +0000 Subject: [PATCH 218/251] decomp: improve FUN_L13_00306300 --- src/overlays/l13/gameplay/vendor/003058a8.c | 54 ++++++++++++--------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/overlays/l13/gameplay/vendor/003058a8.c b/src/overlays/l13/gameplay/vendor/003058a8.c index 4e4a010c2..d6b879220 100644 --- a/src/overlays/l13/gameplay/vendor/003058a8.c +++ b/src/overlays/l13/gameplay/vendor/003058a8.c @@ -360,6 +360,7 @@ void FUN_L13_00306300(struct Moby *moby) { } work; extern L13TargetRow_6300 D_L13_00178400[]; int stationary; + int flags; float length; extern struct { char pad[0x18]; struct Moby *moby; int pad1; L13Vector_6300 pos; L13Vector_6300 pad2; L13Vector_6300 matrix; } D_L13_00174140; @@ -369,46 +370,53 @@ void FUN_L13_00306300(struct Moby *moby) { work.direction.z = 0.0f; normalize_vector_xyz_6300(&work.direction, &work.direction, 1.0f); work.direction.z = 1.0f; - if (hero.ammo_used != 0 && *(float *)(data + 0xc) != 31337.602f && - fast_vec_dist(&moby->pos, &hero.motion.pos) < 2.0f) { + flags = 0x10001; + /* Existing symbols for hero.ammo_used and hero.motion.pos at their retail addresses. */ + if (D_00141346 != 0 && *(float *)(data + 0xc) != 31337.602f && + fast_vec_dist(&moby->pos, D_0013F3D0) < 2.0f) { int i; scale_vector_xyz_6300(data, data, 0.5f); subtract_vector_xyz(&moby->pos, &moby->pos, data); *(OvlQuad *)data = 0; *(int *)(data + 0x2c) = 5; - *(float *)(data + 0xc) = 31337.602f; + /* Preserve the sentinel bits without keeping the comparison constant live. */ + *(unsigned int *)(data + 0xc) = 0x46f4d334; for (i = 0; i < 6; i++) { struct Moby *target = (struct Moby *)hero.unk2020[i]; if (target != 0) { - FUN_L00_00259888(&work.hit, moby, 0x10001, &work.direction, 1.0f); + FUN_L00_00259888(&work.hit, moby, flags, &work.direction, 1.0f); work.hit.oclass = moby->oclass; work.hit.active = 1; work.hit.valid = 1; - if (target->hit_slot == 0xff) + { + L13TargetRow_6300 *previous; + if (target->hit_slot == 0xff) + goto attach_hit; + previous = &D_L13_00178400[target->hit_slot]; + if (previous->moby == target) + goto update_hit; +attach_hit: FUN_L00_00259a88(target, &work.hit); - else { - L13TargetRow_6300 *previous = (L13TargetRow_6300 *)((char *)D_L13_00178400 + target->hit_slot * 0x40); - if (previous->moby == target) { - previous->value += 1.0f; - previous = (L13TargetRow_6300 *)((char *)D_L13_00178400 + target->hit_slot * 0x40); - previous->active = 1; - previous = (L13TargetRow_6300 *)((char *)D_L13_00178400 + target->hit_slot * 0x40); - previous->valid = 1; - previous = (L13TargetRow_6300 *)((char *)D_L13_00178400 + target->hit_slot * 0x40); - previous->oclass = moby->oclass; - previous = (L13TargetRow_6300 *)((char *)D_L13_00178400 + target->hit_slot * 0x40); - previous->flags = 0x10001; - } else - FUN_L00_00259a88(target, &work.hit); + break; +update_hit: + previous->value += 1.0f; + previous = &D_L13_00178400[target->hit_slot]; + previous->active = 1; + previous = &D_L13_00178400[target->hit_slot]; + previous->valid = 1; + previous = &D_L13_00178400[target->hit_slot]; + previous->oclass = moby->oclass; + previous = &D_L13_00178400[target->hit_slot]; + previous->flags = flags; } break; } } } - FUN_L00_00259888(&work.hit, moby, 0x10001, &work.direction, 1.0f); + FUN_L00_00259888(&work.hit, moby, flags, &work.direction, 1.0f); work.hit.oclass = moby->oclass; - work.hit.valid = 1; work.hit.active = 1; + work.hit.valid = 1; stationary = *(int *)(data + 0x24) == 0; if (!(*(float *)(data + 0x28) < vector_distance(&moby->pos, data + 0x10)) && FUN_001f9740((int *)(data + 0x2c)) == 0) @@ -420,7 +428,7 @@ void FUN_L13_00306300(struct Moby *moby) { work.random_direction.x = random_float_between(-1.0f, 1.0f); work.random_direction.y = random_float_between(-1.0f, 1.0f); work.random_direction.z = random_float_between(-1.0f, 1.0f); - work.velocity = work.random_direction; + *(OvlQuad *)&work.velocity = *(OvlQuad *)&work.random_direction; length = vector_length_xyz(&work.random_direction); scale_vector_xyz_6300(&work.velocity, &work.velocity, length * 0.1f); add_vector_xyz(&work.velocity, &work.random_direction, &work.velocity); @@ -443,7 +451,7 @@ void FUN_L13_00306300(struct Moby *moby) { work.random_direction.x = random_float_between(-1.0f, 1.0f); work.random_direction.y = random_float_between(-1.0f, 1.0f); work.random_direction.z = random_float_between(-1.0f, 1.0f); - work.velocity = work.random_direction; + *(OvlQuad *)&work.velocity = *(OvlQuad *)&work.random_direction; FUN_L00_001ff660(&work.random_direction, data, &D_L13_00174140.matrix); length = vector_length_xyz(&work.random_direction); scale_vector_xyz_6300(&work.velocity, &work.velocity, length * 0.5f); From bd686fc79e8f79bffdecc655081fa9f90179248f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:54:35 +0000 Subject: [PATCH 219/251] decomp: improve FUN_L10_002e91b8 --- src/overlays/shared/gameplay/vendor/002e3de8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index 6fe423454..ec2e878b7 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -227,8 +227,8 @@ void FUN_L10_002e91b8(unsigned char *m) { transform_vectors((float *)first, matrix, 0); transform_vectors((float *)second, matrix, 0); { - float *first_vectors = (float *)first; float *second_vectors = (float *)second; + float *first_vectors = (float *)first; int j = 3; do { first_vectors[1] += 0.1f; From 3b42e74ce5b6db1c6b5520b0b627b5f4324e25ef Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:56:49 +0000 Subject: [PATCH 220/251] decomp: improve FUN_L00_00237200 --- src/overlays/shared/gameplay/animation/00235878.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/animation/00235878.c b/src/overlays/shared/gameplay/animation/00235878.c index a20d99c2e..c230ad39f 100644 --- a/src/overlays/shared/gameplay/animation/00235878.c +++ b/src/overlays/shared/gameplay/animation/00235878.c @@ -605,7 +605,7 @@ int FUN_L00_00237200(HudElem *e) { FUN_0023b4d8(FUN_0023b208(0x7580, 0), other_left, y, width, 0x36, alpha); other_left = color; FUN_0023b4d8(FUN_0023b208(0x7580, 1), left, y, 0x20, 0x36, alpha); - FUN_0023b860(FUN_0023b208(0x7580, 1), left + (width + 0x20), y, 0x20, 0x36, alpha); + FUN_0023b860(FUN_0023b208(0x7580, 1), (width + 0x20) + left, y, 0x20, 0x36, alpha); FUN_001fb9a8(0x100, text_y, other_left, (const char *)D_L00_0017E530, -1); FUN_001fb9a8(0x100, y + 0x1b, other_left, (const char *)&D_L00_0017E530[1] + i, -1); level = current_level_index_sda; From ffda5f7dac35314e9f225d4ac9475abca878f517 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:58:32 +0000 Subject: [PATCH 221/251] decomp: improve FUN_L06_002f2250 --- src/overlays/shared/gameplay/entities/00297d10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/00297d10.c b/src/overlays/shared/gameplay/entities/00297d10.c index 66f64cbe7..152d31288 100644 --- a/src/overlays/shared/gameplay/entities/00297d10.c +++ b/src/overlays/shared/gameplay/entities/00297d10.c @@ -2188,7 +2188,7 @@ void FUN_L06_002f2250(void) { } } if (moby_count > 0) { - int j, k, last; + int i, j, k, last; GbMoby *moby, *target; GbVars *vars; GbClass *cls; From 522156f5ce349a71cb9fb3f1f96c005c8d80136c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:00:44 +0000 Subject: [PATCH 222/251] decomp: improve FUN_L14_00301fa8 --- src/overlays/shared/gameplay/vendor/003015d0.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/003015d0.c b/src/overlays/shared/gameplay/vendor/003015d0.c index bef172f69..dfb95acf5 100644 --- a/src/overlays/shared/gameplay/vendor/003015d0.c +++ b/src/overlays/shared/gameplay/vendor/003015d0.c @@ -388,6 +388,8 @@ void FUN_L14_00301fa8(char *m) { u8 *indices; void *src; float t; + float *uv, *uv_base; + int next; FUN_001fa050(base, &frame->pad40[0x30]); FUN_001fa2d8(matrix, base); @@ -418,7 +420,7 @@ void FUN_L14_00301fa8(char *m) { clear_u64_value(start); indices = (u8 *)(d + 0x18); - for (point = 0; point < 31; point++) { + for (point = 0; point < 31; point = next) { qcopy(end, start); if (point < 30) { subtract_vector_xyz(side, d + 0x20 + (point << 4), d + 0x40 + (point << 4)); @@ -428,6 +430,7 @@ void FUN_L14_00301fa8(char *m) { } else { clear_u64_value(start); } + next = point + 1; rounded = (point / 4) * 4; for (i = 0; i < 4;) { if (i < 2) { @@ -456,7 +459,7 @@ void FUN_L14_00301fa8(char *m) { for (strip = 0; strip < 4; strip++) { clear_u64_value(start); if (indices[strip] < 31) { - for (point = 0; point < 3; point++) { + for (point = 0; point < 3; point = next) { qcopy(end, start); if (point < 2) { subtract_vector_xyz(side, d + (point << 6) + 0x420 + (strip << 4), @@ -469,7 +472,10 @@ void FUN_L14_00301fa8(char *m) { clear_u64_value(start); } if (point == 0) qcopy(end, start); + next = point + 1; rounded = (point / 4) * 4; + uv = &packet[0].uv[0][0]; + uv_base = (float *)0x001e5fd0; for (k = 0; k < 4;) { if (k < 2) { packet[0].vertices[k] = *(u128 *)(d + (point << 6) + 0x420 + (strip << 4)); @@ -489,8 +495,10 @@ void FUN_L14_00301fa8(char *m) { } t = convert_integer_to_float(point - rounded) * 0.25f; j = k++; - packet[0].uv[j][0] = ((float *)0x001e5fd0)[j * 2] + - t; + t = *uv_base + t; + uv_base += 2; + *uv = t; + uv += 2; } draw_geometry_quad(&packet[0], base, 0); } From 81e64d36ad069a27abfb56287e9617d4a52d7fc5 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:05:02 +0000 Subject: [PATCH 223/251] decomp: improve FUN_L04_002923b8 --- src/overlays/l04/runtime/dma/002922d0.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/overlays/l04/runtime/dma/002922d0.c b/src/overlays/l04/runtime/dma/002922d0.c index c614a1fe8..f94f9c895 100644 --- a/src/overlays/l04/runtime/dma/002922d0.c +++ b/src/overlays/l04/runtime/dma/002922d0.c @@ -60,8 +60,8 @@ void FUN_L04_002923b8(char *arg0, char *arg1) { float transformed[16]; LegRigAnim **entry = (LegRigAnim **)(arg1 + 0x70); int *current; - int i; - int j; + unsigned char i; + unsigned short j; int offset; char *record; char *upper; @@ -87,16 +87,16 @@ void FUN_L04_002923b8(char *arg0, char *arg1) { LegRigAnim *item = *slot; float start = item->phase[1].from[j]; float end = item->phase[1].to[j]; - current = (float *)((char *)item + 0x38 + offset); + current = &item->phase[1].span[j]; if (start <= end) difference = end - start; else difference = (end + item->len) - start; *current = difference; item = *slot; - current = (float *)((char *)item + 0x20 + offset); start = item->phase[0].from[j]; end = item->phase[0].to[j]; + current = &item->phase[0].span[j]; if (start <= end) difference = end - start; else From ac08a029fc00d4f96058ffab2aa07a791f64cef9 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:05:56 +0000 Subject: [PATCH 224/251] decomp: improve FUN_L13_00306300 --- src/overlays/l13/gameplay/vendor/003058a8.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/overlays/l13/gameplay/vendor/003058a8.c b/src/overlays/l13/gameplay/vendor/003058a8.c index d6b879220..a3fd8121a 100644 --- a/src/overlays/l13/gameplay/vendor/003058a8.c +++ b/src/overlays/l13/gameplay/vendor/003058a8.c @@ -360,7 +360,7 @@ void FUN_L13_00306300(struct Moby *moby) { } work; extern L13TargetRow_6300 D_L13_00178400[]; int stationary; - int flags; + short flags; float length; extern struct { char pad[0x18]; struct Moby *moby; int pad1; L13Vector_6300 pos; L13Vector_6300 pad2; L13Vector_6300 matrix; } D_L13_00174140; @@ -370,7 +370,7 @@ void FUN_L13_00306300(struct Moby *moby) { work.direction.z = 0.0f; normalize_vector_xyz_6300(&work.direction, &work.direction, 1.0f); work.direction.z = 1.0f; - flags = 0x10001; + flags = 1; /* Existing symbols for hero.ammo_used and hero.motion.pos at their retail addresses. */ if (D_00141346 != 0 && *(float *)(data + 0xc) != 31337.602f && fast_vec_dist(&moby->pos, D_0013F3D0) < 2.0f) { @@ -384,7 +384,7 @@ void FUN_L13_00306300(struct Moby *moby) { for (i = 0; i < 6; i++) { struct Moby *target = (struct Moby *)hero.unk2020[i]; if (target != 0) { - FUN_L00_00259888(&work.hit, moby, flags, &work.direction, 1.0f); + FUN_L00_00259888(&work.hit, moby, (unsigned short)flags | 0x10000, &work.direction, 1.0f); work.hit.oclass = moby->oclass; work.hit.active = 1; work.hit.valid = 1; @@ -407,13 +407,13 @@ void FUN_L13_00306300(struct Moby *moby) { previous = &D_L13_00178400[target->hit_slot]; previous->oclass = moby->oclass; previous = &D_L13_00178400[target->hit_slot]; - previous->flags = flags; + previous->flags = (unsigned short)flags | 0x10000; } break; } } } - FUN_L00_00259888(&work.hit, moby, flags, &work.direction, 1.0f); + FUN_L00_00259888(&work.hit, moby, (unsigned short)flags | 0x10000, &work.direction, 1.0f); work.hit.oclass = moby->oclass; work.hit.active = 1; work.hit.valid = 1; From c5f40c1f3ebcad19670b93189e229625d5b07dc9 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:03:13 +0000 Subject: [PATCH 225/251] decomp: improve FUN_L00_0020f160 --- src/overlays/shared/ui/help/0020c758.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index 0fcb11fff..1bffc2d85 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -1344,7 +1344,7 @@ void FUN_L00_0020f160(void *moby, void *matrix) f32 maximum; s64 negative_one = -1; u8 *record; - f32 *score_ptr; + f32 * volatile score_ptr; void * volatile output; { @@ -1387,12 +1387,12 @@ void FUN_L00_0020f160(void *moby, void *matrix) score_ptr = scores; for (i = 0; i < n; i++) { s32 a = (*(volatile s32 *)(hero.pad_21B8)) - (i - 15); - a -= ((negative_one < a ? a : a + 15) >> 4) * 16; + a %= 16; for (j = 0; j < n; j++) { if (i != j) { s32 b = (*(volatile s32 *)(hero.pad_21B8)) - (j - 15); - b -= ((negative_one < b ? b : b + 15) >> 4) * 16; + b %= 16; score_ptr[i] += FUN_L00_0020f0b8((f32 *)((hero.pad_12EF + 1) + a * 0x30), (f32 *)((hero.pad_12EF + 1) + b * 0x30)); } @@ -1417,7 +1417,7 @@ void FUN_L00_0020f160(void *moby, void *matrix) for (i = 0; i < n; i++) { if (!(maximum * 0.2f < scores[i]) || count < 1 || !limit) { s32 a = (*(volatile s32 *)(hero.pad_21B8)) - (i - 15); - a -= ((negative_one < a ? a : a + 15) >> 4) * 16; + a %= 16; record = (hero.pad_12EF + 1) + a * 0x30; chosen++; for (j = 0; j < 3; j++) From df1fa217896fca29f73de1092fe2bd047a6e4f6f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 21:55:46 +0000 Subject: [PATCH 226/251] decomp: improve FUN_L06_002fbfb0 --- src/overlays/l06/gameplay/entities/002b4770.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/overlays/l06/gameplay/entities/002b4770.c b/src/overlays/l06/gameplay/entities/002b4770.c index b395a936b..5f15791d2 100644 --- a/src/overlays/l06/gameplay/entities/002b4770.c +++ b/src/overlays/l06/gameplay/entities/002b4770.c @@ -2413,9 +2413,6 @@ void FUN_L06_002fbc88(struct Moby *m) { add_vector_xyz(&m->pos, &m->pos, &step); FUN_L00_00261d78(1.0f, v->ground, &m->pos, &m->pos); } -#ifndef NON_MATCHING -INCLUDE_ASM("config/us/overlays/asm/FUN_L06_002fbfb0.s", FUN_L06_002fbfb0); -#else extern struct Moby *create_moby(s32) __asm__("FUN_0020c4f8"); extern int is_point_inside_clip_volume(void *, int) __asm__("FUN_00214720"); extern void FUN_L01_0026e0e0(int, int); @@ -2551,8 +2548,8 @@ void FUN_L06_002fbfb0(char *moby) { goto phase_join; phase_two: target_a = D_L06_00161F24; - target_rot_a = D_L06_00161F2C; target_b = D_L06_00161F28; + target_rot_a = D_L06_00161F2C; target_rot_b = D_L06_00161F30; acceleration = D_L06_00161F34; max_speed = D_L06_00161F38; @@ -2563,11 +2560,10 @@ void FUN_L06_002fbfb0(char *moby) { next_phase = 1; next_timer = func_001FA898_r(random_float_between_alt((float)D_L06_00161F4C, (float)D_L06_00161F50)); phase_join: - target_delta = target_rot_b; FUN_00213f38(&phase_a, &((float *)data)[2], target_a, acceleration * frame_time_sq, max_speed * frame_time_sq, damping * frame_time); FUN_00213f38(&phase_b, &((float *)data)[0x11], target_b, acceleration * frame_time_sq, max_speed * frame_time_sq, damping * frame_time); FUN_00213f38((float *)(moby + 0x44), &((float *)data)[3], target_rot_a, rotation_acceleration * DEG_TO_RAD * frame_time_sq, rotation_speed * DEG_TO_RAD * frame_time_sq, rotation_damping * DEG_TO_RAD * frame_time); - FUN_00213f38((float *)(*(char **)(data + 0x40) + 0x44), &((float *)data)[0x12], target_delta, rotation_acceleration * DEG_TO_RAD * frame_time_sq, rotation_speed * DEG_TO_RAD * frame_time_sq, rotation_damping * DEG_TO_RAD * frame_time); + FUN_00213f38((float *)(*(char **)(data + 0x40) + 0x44), &((float *)data)[0x12], target_rot_b, rotation_acceleration * DEG_TO_RAD * frame_time_sq, rotation_speed * DEG_TO_RAD * frame_time_sq, rotation_damping * DEG_TO_RAD * frame_time); FUN_001f9bf8(v, data + 0x30, phase_a); FUN_001f9a10(moby + 0x10, data + 0x10, v); FUN_001f9bf8(v, data + 0x30, -phase_b); @@ -2597,7 +2593,6 @@ void FUN_L06_002fbfb0(char *moby) { return; } } -#endif /* NON_MATCHING */ /* Ported from rac1-decomp (src/overlays/l06_blarg/vendor_002B5990.c: func_L06_002FDA70), where it is exact; names translated to the US level program. */ typedef struct { float x, y, z, w; } __attribute__((aligned(16))) Vec_2FDA70; From 6ed60a228db0f03d24f049c227c7f486b16f77b1 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:12:09 +0000 Subject: [PATCH 227/251] decomp: improve FUN_L00_00269d20 --- src/overlays/shared/rendering/00269290.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/rendering/00269290.c b/src/overlays/shared/rendering/00269290.c index 3ef5856c5..9997e75e3 100644 --- a/src/overlays/shared/rendering/00269290.c +++ b/src/overlays/shared/rendering/00269290.c @@ -400,9 +400,10 @@ void FUN_L00_00269d20(unsigned char *m) { blue = limit; if (*(unsigned int *)(e + 0x70) & 0x40) p[0x1b] ^= 0x40; } - p[0x18] = particle_color_int_269d20(red * 65535.0f); - p[0x19] = particle_color_int_269d20(green * 65535.0f); - p[0x1a] = particle_color_int_269d20(blue * 65535.0f); + step = 65535.0f; + p[0x18] = particle_color_int_269d20(red * step); + p[0x19] = particle_color_int_269d20(green * step); + p[0x1a] = particle_color_int_269d20(blue * step); color = (particle_color_int_269d20(red * 255.0f) & 0xff) | ((particle_color_int_269d20(green * 255.0f) & 0xff) << 8) | ((particle_color_int_269d20(blue * 255.0f) & 0xff) << 16) | From ddc05abbc2a017f799927431ea037da9af1cbe6d Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:15:50 +0000 Subject: [PATCH 228/251] decomp: improve FUN_L14_00301fa8 --- src/overlays/shared/gameplay/vendor/003015d0.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/003015d0.c b/src/overlays/shared/gameplay/vendor/003015d0.c index dfb95acf5..317f987c0 100644 --- a/src/overlays/shared/gameplay/vendor/003015d0.c +++ b/src/overlays/shared/gameplay/vendor/003015d0.c @@ -390,6 +390,7 @@ void FUN_L14_00301fa8(char *m) { float t; float *uv, *uv_base; int next; + int branch_next; FUN_001fa050(base, &frame->pad40[0x30]); FUN_001fa2d8(matrix, base); @@ -459,7 +460,7 @@ void FUN_L14_00301fa8(char *m) { for (strip = 0; strip < 4; strip++) { clear_u64_value(start); if (indices[strip] < 31) { - for (point = 0; point < 3; point = next) { + for (point = 0; point < 3; point = branch_next) { qcopy(end, start); if (point < 2) { subtract_vector_xyz(side, d + (point << 6) + 0x420 + (strip << 4), @@ -472,7 +473,7 @@ void FUN_L14_00301fa8(char *m) { clear_u64_value(start); } if (point == 0) qcopy(end, start); - next = point + 1; + branch_next = point + 1; rounded = (point / 4) * 4; uv = &packet[0].uv[0][0]; uv_base = (float *)0x001e5fd0; From 1d16a74d93affdc67feab74cfa3dc915fff93f67 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:16:55 +0000 Subject: [PATCH 229/251] decomp: improve FUN_L00_002a5040 --- src/overlays/shared/gameplay/entities/002a4830.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002a4830.c b/src/overlays/shared/gameplay/entities/002a4830.c index 73a0f906f..0d8cf41c9 100644 --- a/src/overlays/shared/gameplay/entities/002a4830.c +++ b/src/overlays/shared/gameplay/entities/002a4830.c @@ -296,6 +296,7 @@ void FUN_L00_002a5040(u8 *moby) { Point_2a5040 basis[4]; f32 rotation[3]; f32 matrix[12]; + s32 i; Point_2a5040 *basis0, *basis1, *basis2, *basis3; Point_2a5040 orbit_copy[4]; Point_2a5040 orbit[4]; @@ -308,7 +309,7 @@ void FUN_L00_002a5040(u8 *moby) { f32 x, y, z, phase, angle; f32 uv0, uv1, uv2, uv3; f32 u0, u1, u2, u3; - s32 i, index; + s32 index; f32 zero; s32 *indices1, *indices2; s32 index1, index2, index3; @@ -351,13 +352,16 @@ void FUN_L00_002a5040(u8 *moby) { quad.corners[1].z = z + basis[1].z; quad.corners[0].y = y + basis[0].y * vars->scale; quad.corners[2].z = z + basis[2].z; - quad.corners[3].z = z + basis[3].z; + z = z + basis[3].z; + quad.corners[3].z = z; quad.corners[1].x = x + basis[1].x * vars->scale; quad.corners[1].y = y + basis[1].y * vars->scale; quad.corners[2].x = x + basis[2].x * vars->scale; quad.corners[2].y = y + basis[2].y * vars->scale; - quad.corners[3].x = x + basis[3].x * vars->scale; - quad.corners[3].y = y + basis[3].y * vars->scale; + x = x + basis[3].x * vars->scale; + quad.corners[3].x = x; + y = y + basis[3].y * vars->scale; + quad.corners[3].y = y; index1 = *indices1; index2 = *indices2; index = indices[0]; From 245270068e5aac0c773659cc2bcff92c6acc421c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:11:51 +0000 Subject: [PATCH 230/251] decomp: improve FUN_L00_002772c0 --- src/overlays/shared/audio/voices/00276368.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index e5c87c0f9..1e8cea763 100644 --- a/src/overlays/shared/audio/voices/00276368.c +++ b/src/overlays/shared/audio/voices/00276368.c @@ -678,7 +678,7 @@ extern void FUN_L00_00299f40(void *, void *, s32 *, s32 *, s32 *, s32 *) __asm__ extern void FUN_L00_0023caa8_772c0(s32, s32, s32, s32, u64, s32) __asm__("FUN_00200e08"); extern void FUN_L00_001fc928(f32, s32, s32, s32) __asm__("FUN_001f7888"); extern void FUN_L00_0023cc30(s32, s32, s32, s32, u64, s32, s32) __asm__("FUN_00200f90"); -extern void FUN_L00_001fca18(void) __asm__("FUN_001f7978"); +extern void FUN_L00_001fca18(void) __asm__("FUN_L00_001fca18"); extern void FUN_L00_001fa290(s32, s32, s32, s32, s32, s32, s32, s32, u64, u64) __asm__("FUN_001f5450"); extern void FUN_L00_0024fe20(void) __asm__("FUN_L00_0024fe20"); extern void FUN_L00_0024ff88(void) __asm__("FUN_L00_0024ff88"); From 4757a3fd36deb20d8dd635676bad45cda8ac67c5 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:19:48 +0000 Subject: [PATCH 231/251] decomp: improve FUN_L13_00306300 --- src/overlays/l13/gameplay/vendor/003058a8.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/overlays/l13/gameplay/vendor/003058a8.c b/src/overlays/l13/gameplay/vendor/003058a8.c index a3fd8121a..f4aec3a62 100644 --- a/src/overlays/l13/gameplay/vendor/003058a8.c +++ b/src/overlays/l13/gameplay/vendor/003058a8.c @@ -423,6 +423,7 @@ void FUN_L13_00306300(struct Moby *moby) { goto collision; if (moby->visible != 0) { int i; + L13Vector_6300 *velocity = &work.velocity; for (i = 0; i < 3; i++) { *(OvlQuad *)&work.random_direction = 0; work.random_direction.x = random_float_between(-1.0f, 1.0f); @@ -430,11 +431,11 @@ void FUN_L13_00306300(struct Moby *moby) { work.random_direction.z = random_float_between(-1.0f, 1.0f); *(OvlQuad *)&work.velocity = *(OvlQuad *)&work.random_direction; length = vector_length_xyz(&work.random_direction); - scale_vector_xyz_6300(&work.velocity, &work.velocity, length * 0.1f); - add_vector_xyz(&work.velocity, &work.random_direction, &work.velocity); - scale_vector_xyz_6300(&work.velocity, &work.velocity, + scale_vector_xyz_6300(velocity, velocity, length * 0.1f); + add_vector_xyz(velocity, &work.random_direction, velocity); + scale_vector_xyz_6300(velocity, velocity, random_float_between(D_0015ED6C + D_0015ED6C, D_0015ED6C * 4.0f)); - FUN_L07_0029a2a0(&moby->pos, &work.velocity); + FUN_L07_0029a2a0(&moby->pos, velocity); } } mark_moby_for_removal(moby); From 1459a67c88c38baac94b1313bb583b03d3bbbcc1 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:23:05 +0000 Subject: [PATCH 232/251] decomp: improve FUN_L00_002382a0 --- src/overlays/shared/ui/text/002377b8.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/ui/text/002377b8.c b/src/overlays/shared/ui/text/002377b8.c index 37220a948..77f42e371 100644 --- a/src/overlays/shared/ui/text/002377b8.c +++ b/src/overlays/shared/ui/text/002377b8.c @@ -442,7 +442,9 @@ s32 FUN_L00_002382a0(char *rec) { } selected = *(s32 *)(rec + 0x74); if (selected >= 0 && D_L00_0015FAC0_c[D_L00_0015F72C][selected].f0 != 0) { - f32 opacity = open * fade; + f32 opacity; + open *= fade; + opacity = open; color = fast_tween_color_alpha_first(opacity, D_L00_0015F798, D_L00_0015F79C); id = pause_iop_sprite_lists[selected]; if (D_L00_001C40B0[id].h8 != 0) { @@ -498,8 +500,7 @@ s32 FUN_L00_002382a0(char *rec) { suffix = text + 2; prefix_length = 1; } else { - while (j + 1 < text_length) { - j++; + while (++j < text_length) { suffix++; if (*(const u8 *)suffix == ' ') { prefix_length = j + 1; From 93499f398b267af5174d21db075bd939240478c5 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:23:30 +0000 Subject: [PATCH 233/251] decomp: improve update_hero_held_items_and_orientation --- src/overlays/shared/ui/help/0020c758.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index 1bffc2d85..0ac247fd4 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -1041,11 +1041,13 @@ void FUN_L00_0020e728(void) { } FUN_L00_0024f190((u8 *)hero.moby, *slot); if (hero.unkD14 != 0) { - f32 scale = frame_scale; - if (hero.unkD14 == 2) - FUN_00213ed8_e728((f32 *)(*slot + 8), 0.0f, scale * 0.25f); - else - FUN_00213ed8_e728((f32 *)(*slot + 8), 0.0f, scale * 0.07f); + if (hero.unkD14 == 2) { + f32 scale = frame_scale * 0.25f; + FUN_00213ed8_e728((f32 *)(*slot + 8), 0.0f, scale); + } else { + f32 scale = frame_scale * 0.07f; + FUN_00213ed8_e728((f32 *)(*slot + 8), 0.0f, scale); + } if (*(f32 *)(*slot + 8) == 0.0f) { FUN_L00_0024f0e8((u8 *)hero.moby, slot); return; From 76321db1ca466e195a2e05b498850c882c66d481 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:23:54 +0000 Subject: [PATCH 234/251] decomp: improve update_path_camera --- src/overlays/shared/gameplay/vendor/002e3de8.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index ec2e878b7..74b64d2f5 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -431,6 +431,7 @@ void FUN_L10_002f5b58(char *moby) { #ifndef NON_MATCHING INCLUDE_ASM("config/us/overlays/asm/FUN_L10_002f5f18.s", FUN_L10_002f5f18); #else +#include "qcopy.h" extern float D_L10_0015F3FC __attribute__((section(".data"))); extern float D_L10_0015F3FC_sda __asm__("D_L10_0015F3FC") __attribute__((sda)); extern int D_L10_0015F404; @@ -465,8 +466,8 @@ extern float D_L10_0016CF70_far __asm__("D_L10_0016CF70") __attribute__((section void FUN_L10_002f5f18(char *moby) { char *work = *(char **)(moby + 0x70); - short *indices = (short *)(work + 0x58); - char *acc = (char *)indices - 0x18; + char *acc = work + 0x40; + short *indices = (short *)(acc + 0x18); int slot = *(short *)(moby + 0x84); unsigned char *data = *(unsigned char **)(D_L10_0015EF50 + slot * 0x20 + 0x1c); char *path; @@ -474,7 +475,7 @@ void FUN_L10_002f5f18(char *moby) { union { float target[4]; float direction[4]; } vectors __attribute__((aligned(16))); float transformed[4] __attribute__((aligned(16))); float point[4] __attribute__((aligned(16))); - float *scale; + float * volatile scale; int i, count, next, index; long long segment; long long reached; @@ -492,7 +493,7 @@ void FUN_L10_002f5f18(char *moby) { D_L10_0015F404 = 1; *(short *)(acc + 0x14) = 1; path += 0x10; - *(u128 *)scale = *(u128 *)path; + qcopy(scale, path); if (*(int *)(data + 0x28) >= 0) { path = D_L10_0015FFD8 + *(int *)(data + 0x28) * 0x100; vectors.target[0] = *(float *)(data + 0x2c); @@ -536,7 +537,7 @@ void FUN_L10_002f5f18(char *moby) { } path = D_L10_001B0930_5a78[*(int *)(data + 0x20)]; scale = (float *)(moby + 0x30); - *(u128 *)old_pos = *(u128 *)scale; + qcopy(old_pos, scale); reached = FUN_L00_0025d808(path, scale, (int *)(acc + 0x00), (float *)(acc + 0x04), *(float *)(data + 0x3c) * D_0015ED6C, 0); if (*(short *)(acc + 0x16) != 0) { From 4d9a4160fac0053f20bb5a1b670adae2db002674 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:18:18 +0000 Subject: [PATCH 235/251] decomp: improve FUN_L10_002be858 --- src/overlays/l10/gameplay/entities/00295a38.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/l10/gameplay/entities/00295a38.c b/src/overlays/l10/gameplay/entities/00295a38.c index 1e3f1101d..ab1d12d26 100644 --- a/src/overlays/l10/gameplay/entities/00295a38.c +++ b/src/overlays/l10/gameplay/entities/00295a38.c @@ -481,7 +481,8 @@ void FUN_L10_002be858(unsigned char *moby) { normalize_vector_xyz(position, position, random_float_between_alt(0.0f, D_0015ED6C)); position[2] = random_float_between_alt(D_0015ED6C * 2.5f, D_0015ED6C * 5.0f); life = FUN_001f96f8(random_int_between(15, 30)); - color = (blue << 16) | ((green << 8) | 0x7f000000) | red; + /* Channels are 64..255, so alpha and shifted green have disjoint bits. */ + color = (blue << 16) | ((green << 8) + 0x7f000000) | red; size_scaled = size * 0.07f; size *= 0.7f; spin = random_integer_below(2) ? 1 : -1; From c09c5f8ca0fdabaf652e9dd61ec3cbde36cf3fcc Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:25:38 +0000 Subject: [PATCH 236/251] decomp: improve FUN_L00_00260a88 --- src/overlays/shared/rendering/view/0025fcb8.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/rendering/view/0025fcb8.c b/src/overlays/shared/rendering/view/0025fcb8.c index b5a0e5238..e68d95f21 100644 --- a/src/overlays/shared/rendering/view/0025fcb8.c +++ b/src/overlays/shared/rendering/view/0025fcb8.c @@ -448,6 +448,7 @@ void FUN_L00_00260a88(char *moby, int lower, int upper, unsigned int flags, int Vec_260a88 base, position, velocity, offset, adjusted, difference, quarter; float crossings[2]; float time; + float scale; int large = 0, medium = 0, small = 0, single; int count, remaining, multiplier, near_count, far_count; int near_large, near_medium, near_small, near_single; @@ -536,7 +537,7 @@ void FUN_L00_00260a88(char *moby, int lower, int upper, unsigned int flags, int } while (count < near_value && near_value > 3); } if (count > 3) { - int value_large = 0, value_medium = 0, value_small = 0; + int value_large = b_large * 50, value_medium = b_medium * 20, value_small = b_small * 5; do { if (b_single) { b_single--; value_small += 5; b_small++; @@ -559,8 +560,10 @@ void FUN_L00_00260a88(char *moby, int lower, int upper, unsigned int flags, int qcopy(&position, moby + 0x10); position.f[2] += 0.5f; time = FUN_00257cb0_260a88(); - velocity.f[0] = FUN_001ff7e8_260a88(time) * (FUN_00257be8_260a88(0.0f, 3.0f) * D_L00_0015ED6C_260a88); - velocity.f[1] = FUN_001ff800_260a88(time) * (FUN_00257be8_260a88(0.0f, 3.0f) * D_L00_0015ED6C_260a88); + scale = FUN_001ff7e8_260a88(time); + velocity.f[0] = scale * (FUN_00257be8_260a88(0.0f, 3.0f) * D_L00_0015ED6C_260a88); + scale = FUN_001ff800_260a88(time); + velocity.f[1] = scale * (FUN_00257be8_260a88(0.0f, 3.0f) * D_L00_0015ED6C_260a88); velocity.f[2] = 0.0f; velocity.f[2] = FUN_00257be8_260a88(3.7f, 6.0f) * D_L00_0015ED6C_260a88; offset.f[0] = velocity.f[0]; From efec65e7efba767c493d37df39b037cb0633c7f2 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:18:11 +0000 Subject: [PATCH 237/251] decomp: improve FUN_L00_002d73e8 --- src/overlays/shared/gameplay/entities/002cfcb8.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002cfcb8.c b/src/overlays/shared/gameplay/entities/002cfcb8.c index a575feafb..6d4aac10e 100644 --- a/src/overlays/shared/gameplay/entities/002cfcb8.c +++ b/src/overlays/shared/gameplay/entities/002cfcb8.c @@ -3154,9 +3154,10 @@ float FUN_00200240_2d73e8(s32) __asm__("FUN_001fa6c0"); s32 FUN_00200250_2d73e8(float) __asm__("FUN_001fa6d0"); s32 FUN_00257b50_2d73e8(s32) __asm__("FUN_00213260"); +extern T *D_L00_001600EC_2d73e8 __asm__("D_L00_001600EC") __attribute__((section(".data"))); void FUN_L00_002d73e8(P *p) { Q *q = p->q; - T *t = &D_L00_001600EC[q->idx]; + T *t = &D_L00_001600EC_2d73e8[q->idx]; V position, zero_vector; V positive_transform[4], negative_transform[4]; Quad_2d73e8 quad; @@ -3216,9 +3217,11 @@ void FUN_L00_002d73e8(P *p) { index = D_L00_001E1380_2d73e8[row][point]; source = &D_L00_001E12C0_2d73e8[index]; points->x = source->x; - points->y = source->y * x; + f = source->y * x; + points->y = f; points->w = 1.0f; - points->z = source->z * y; + f = source->z * y; + points->z = f; FUN_001ff6f8_2d73e8(points, points, transform); *texcoords = D_L00_001E1440_2d73e8[index][1] + *phase; *texcoords_second = D_L00_001E1440_2d73e8[index][0]; @@ -3255,9 +3258,11 @@ void FUN_L00_002d73e8(P *p) { for (point = 0, points = quad.points, texcoords = quad.texcoords, texcoords_second = quad.texcoords + 1, colors = quad.colors; point < 4; point++, points++, texcoords += 2, texcoords_second += 2, colors++) { source = (V *)(D_L00_001E11A0_2d73e8 + point * 16); points->x = source->x; - points->y = source->y * x; + f = source->y * x; + points->y = f; points->w = 1.0f; - points->z = source->z * y; + f = source->z * y; + points->z = f; f = source_texcoords[0] - *phase; *texcoords_second = source_texcoords[1]; source_texcoords += 2; From 403628751cad92ef725f09c6f7ffb9ea78c0b01f Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:23:54 +0000 Subject: [PATCH 238/251] decomp: improve FUN_L06_002f5d78 --- src/overlays/l06/gameplay/entities/002b4770.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/l06/gameplay/entities/002b4770.c b/src/overlays/l06/gameplay/entities/002b4770.c index 5f15791d2..675e65dd0 100644 --- a/src/overlays/l06/gameplay/entities/002b4770.c +++ b/src/overlays/l06/gameplay/entities/002b4770.c @@ -1242,8 +1242,8 @@ void FUN_L06_002f5d78(char *moby) { } { int i, offset; - left = (char **)(data + 0x110); right = (char **)(data + 0x138); + left = (char **)(data + 0x110); for (i = 0, offset = 0; i < 10; i++, offset += 2, left++, right++) { float length = D_L06_00161D78 - ((float)i + (float)i); threshold = D_L06_00161D70 + (float)(4 - i) * D_L06_00161D74; From 9f53e88eee5a871d897297348f91cc54e9937da2 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:24:25 +0000 Subject: [PATCH 239/251] decomp: improve FUN_L06_002f2250 --- src/overlays/shared/gameplay/entities/00297d10.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/entities/00297d10.c b/src/overlays/shared/gameplay/entities/00297d10.c index 152d31288..4265d9f87 100644 --- a/src/overlays/shared/gameplay/entities/00297d10.c +++ b/src/overlays/shared/gameplay/entities/00297d10.c @@ -2351,11 +2351,12 @@ void FUN_L06_002f2250(void) { { GbMoby **moby_list = mobys; if (moby_count > 0) for (i = moby_count; i != 0; i--) { - GbVars *vars = (*moby_list++)->vars; + GbVars *vars = (*moby_list)->vars; vars->f18C = GB_FRAME; vars->target = *(GbMoby **)((char *)vars + 0x178); vars->target_searched = 1; if (*(int *)((char *)vars + 0x178) != 0) vars->f198 = 1; + moby_list++; } } } From ab01501b0b4d9dd8d4be02ce8a6fa6ef56cf1069 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:45:34 +0000 Subject: [PATCH 240/251] decomp: improve FUN_L00_002c89e8 --- src/overlays/shared/gameplay/entities/002c8440.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/overlays/shared/gameplay/entities/002c8440.c b/src/overlays/shared/gameplay/entities/002c8440.c index 3a84a7fd4..e9614eb05 100644 --- a/src/overlays/shared/gameplay/entities/002c8440.c +++ b/src/overlays/shared/gameplay/entities/002c8440.c @@ -223,6 +223,7 @@ void FUN_L00_002c89e8(struct Moby *m) case 2: { f32 f, g, h; f32 half = 0.5f; + u8 *collision_point; f = FUN_001fa6c0(D_0013E534) + 1.0f; { f32 g = m->pclass->scale; @@ -232,11 +233,8 @@ void FUN_L00_002c89e8(struct Moby *m) if (tick_countdown_2c8440((s32 *)v->pad_34)) { *(s32 *)v->pad_34 = scale_game_frames_2c8440(4); FUN_L00_0026ed28(m); - g = D_0015ED70_2c8440; - } else { - g = D_0015ED70_2c8440; } - v->vel.f[2] -= g * 9.0f; + v->vel.f[2] -= D_0015ED70_2c8440 * 9.0f; add_vector_xyz_2c8440(&d, &m->pos, v); FUN_L00_001ff290_2c89e8(&q, &m->pos, &hero.motion.platform_carry); qcopy_nc(&e, &m->pos); @@ -247,18 +245,22 @@ void FUN_L00_002c89e8(struct Moby *m) qcopy_nc(&q, &d); q.f[2] += f * 0.2f; if (FUN_001f0d60_2c89e8(f * 0.3f, &q, 4, hero.moby)) { - qcopy_nc(&m->pos, (u8 *)&coll_hit_2c8440 + 0x30); + collision_point = (u8 *)&coll_hit_2c8440 + 0x30; + qcopy_nc(&m->pos, collision_point); m->pos.z -= f * 0.2f; + collision_point += 0x10; } else { if (!collision_line_2c8440(&e, &a, 0, hero.moby, 0)) { qcopy_nc(&m->pos, &d); return; } - qcopy_nc(&m->pos, &coll_hit_2c8440.point); + collision_point = (u8 *)&coll_hit_2c8440 + 0x20; + qcopy_nc(&m->pos, collision_point); m->pos.z += (frame_scale * 0.15f * m->scale) / m->pclass->scale; + collision_point += 0x20; } h = 0.01f; - reflect_vector_2cb418(v, v, &coll_hit_normal_2c8440); + reflect_vector_2cb418(v, v, collision_point); scale_vector_xyz_2c8440(v, v, half); g = vector_length_xyz_2cb418(v); if (g < frame_scale * h) goto settle; From 0fcbde0d87ee8f615e11d8620503ac512e49f6c2 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:48:30 +0000 Subject: [PATCH 241/251] decomp: improve FUN_L00_00276368 --- src/overlays/shared/audio/voices/00276368.c | 25 ++++++++++++--------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index 1e8cea763..42f4b43d6 100644 --- a/src/overlays/shared/audio/voices/00276368.c +++ b/src/overlays/shared/audio/voices/00276368.c @@ -12,7 +12,7 @@ typedef unsigned int u128_init __attribute__((mode(TI), aligned(16))); extern struct Own D_L00_001B71F0; extern s32 D_L00_00173E04; extern s32 D_L00_00173E08; -extern u8 D_L00_00173E40[]; +extern u8 D_L00_00173E40[] __attribute__((section(".data"))); extern void *D_L00_00197300[]; extern s32 D_L00_0015F3F8_gp __asm__("D_L00_0015F3F8") __attribute__((sda)); extern s32 frame_size __asm__("D_0013E504"); @@ -77,36 +77,39 @@ extern u8 D_L00_001841F0_init[] __asm__("D_L00_001841F0"); void FUN_L00_00276368(void) { s32 i; s32 special = 0; + f32 *source = D_L00_00166DC0_init; s32 *handle; void *obj; u8 *table; s32 id; + struct Own *owner; - *(s32 *)(D_L00_00173E40 + 0x10) |= 0x80000000; + { s32 *table = (s32 *)D_L00_00173E40; table[4] |= 0x80000000; } D_L00_001B9CF0.unk124 = 0; D_L00_001B9CF0.unkD0 = 0; if (D_L00_001B9CF0.state == 10) { D_L00_001B9CF0.state = 11; - D_L00_001B9CF0.unk8 = (struct Own *)D_L00_001B3518; + owner = (struct Own *)D_L00_001B3518; special = 1; } else if (D_L00_001B9CF0.state == 14) { D_L00_001B9CF0.state = 15; - D_L00_001B9CF0.unk8 = (struct Own *)D_L00_001B6088; + owner = (struct Own *)D_L00_001B6088; special = 1; } else if (D_L00_001B9CF0.state == 0x21) { D_L00_001B9CF0.unk124 = 1; - D_L00_001B9CF0.unk8 = &D_L00_001B71F0; + owner = &D_L00_001B71F0; D_L00_001B9CF0.state = 0x22; } else if (D_L00_001B9CF0.state == 0x23) { - D_L00_001B9CF0.unk8 = (struct Own *)D_L00_001B6B38; + owner = (struct Own *)D_L00_001B6B38; } else { if (D_L00_001B9CF0.state == 0x2d) { - D_L00_001B9CF0.unk8 = (struct Own *)D_L00_001B86C8; + owner = (struct Own *)D_L00_001B86C8; } else { - D_L00_001B9CF0.unk8 = (struct Own *)D_L00_001B2588; + owner = (struct Own *)D_L00_001B2588; } D_L00_001B9CF0.state = 2; } + D_L00_001B9CF0.unk8 = owner; D_L00_001B9CF0.owner = D_L00_001B9CF0.unk8; if (D_L00_001B9DE0 != 0) { D_L00_0015EED8 = D_L00_001B9E20; @@ -217,9 +220,9 @@ void FUN_L00_00276368(void) { if (obj != 0) { *(u16 *)((u8 *)obj + 0x34) &= 0xfffd; *(void **)((u8 *)*handle + 0x74) = (void *)0x002df638; - *(f32 *)((u8 *)*handle + 0x10) = D_L00_00166DC0_init[0]; - *(f32 *)((u8 *)*handle + 0x14) = D_L00_00166DC0_init[1]; - *(f32 *)((u8 *)*handle + 0x18) = D_L00_00166DC0_init[2]; + *(f32 *)((u8 *)*handle + 0x10) = source[0]; + *(f32 *)((u8 *)*handle + 0x14) = source[1]; + *(f32 *)((u8 *)*handle + 0x18) = source[2]; *(s32 *)((u8 *)*handle + 0x40) = 0; *(s32 *)((u8 *)*handle + 0x44) = 0; *(s32 *)((u8 *)*handle + 0x48) = 0; From bb8b4ba08ac42fe0b4ac74f762c3ccfcebdbf6bb Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:51:45 +0000 Subject: [PATCH 242/251] decomp: improve FUN_L14_003017f8 --- src/overlays/shared/gameplay/vendor/003015d0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/shared/gameplay/vendor/003015d0.c b/src/overlays/shared/gameplay/vendor/003015d0.c index 317f987c0..37fdd8822 100644 --- a/src/overlays/shared/gameplay/vendor/003015d0.c +++ b/src/overlays/shared/gameplay/vendor/003015d0.c @@ -231,7 +231,7 @@ void FUN_L14_003017f8(char *m) { (float)next * 6.0f)); index += 4; d[0x18 + i] = index; - offset = (i << 4) + (int)d; + offset = (unsigned int)((i << 4) + (int)d); qcopy((char *)offset + 0x420, d + 0x20 + (index << 4)); qcopy((char *)offset + 0x520, d + 0x220 + (index << 4)); for (j = 2; j >= 0; j--) { From 033f69baf3112a6e5368592455b9d09bc4f4c3f4 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:54:11 +0000 Subject: [PATCH 243/251] decomp: improve FUN_L00_00269d20 --- src/overlays/shared/rendering/00269290.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/overlays/shared/rendering/00269290.c b/src/overlays/shared/rendering/00269290.c index 9997e75e3..4c7d2520a 100644 --- a/src/overlays/shared/rendering/00269290.c +++ b/src/overlays/shared/rendering/00269290.c @@ -359,17 +359,21 @@ void FUN_L00_00269d20(unsigned char *m) { red = particle_color_float_269d20((m[4] << 8) | p[0x18]) / 65535.0f; green = (float)particle_color_int_269d20((int)((*(unsigned int *)(m + 4) & 0xff00) | p[0x19])) / 65535.0f; blue = (float)particle_color_int_269d20((int)(((*(unsigned int *)(m + 4) >> 8) & 0xff00) | p[0x1a])) / 65535.0f; - if (p[0x1b] & 0x10) { - red -= *(float *)(e + 0x4c) * D_0015ED60_269d20; - step = D_0015ED60_269d20; - } else { - red += *(float *)(e + 0x4c) * D_0015ED60_269d20; - step = D_0015ED60_269d20; + { + float step; + if (p[0x1b] & 0x10) { + red -= *(float *)(e + 0x4c) * D_0015ED60_269d20; + step = D_0015ED60_269d20; + } else { + red += *(float *)(e + 0x4c) * D_0015ED60_269d20; + step = D_0015ED60_269d20; + } + if (p[0x1b] & 0x20) green -= *(float *)(e + 0x50) * step; + else green += *(float *)(e + 0x50) * step; } - if (p[0x1b] & 0x20) green -= *(float *)(e + 0x50) * step; - else green += *(float *)(e + 0x50) * step; - if (p[0x1b] & 0x40) blue -= *(float *)(e + 0x54) * frame_scale; - else blue += *(float *)(e + 0x54) * frame_scale; + step = frame_scale; + if (p[0x1b] & 0x40) blue -= *(float *)(e + 0x54) * step; + else blue += *(float *)(e + 0x54) * step; limit = *(float *)(e + 0x64); if (limit < red) { red = limit; From a39c7a3f706e282f01a123e53f631a48d39ec2a4 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:55:45 +0000 Subject: [PATCH 244/251] decomp: improve FUN_L10_002e91b8 --- .../shared/gameplay/vendor/002e3de8.c | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index 74b64d2f5..0924d3860 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -128,6 +128,8 @@ void FUN_L10_002e91b8(unsigned char *m) { float *first_vectors; float *second_vectors; float *second_angles; + float *second_packet; + float *angle_vectors; int i, k; int j; @@ -138,39 +140,41 @@ void FUN_L10_002e91b8(unsigned char *m) { *(long long *)(first + 0x80) = 0xff9000000260LL; *(long long *)(first + 0x70) = 0; *(long long *)(second + 0x78) = trail_effect_texture(0x2c); + second_packet = (float *)second; *(long long *)(second + 0x80) = 0xff9000000260LL; *(long long *)(second + 0x70) = 0; *(int *)(second + 0x4c) = 0; *(int *)(second + 0x44) = 0; second_source = D_L10_001DA310; first_source = D_L10_001DA350; - second_vectors = (float *)second; - second_angles = (float *)second; + second_vectors = second_packet; + second_angles = second_packet; first_vectors = (float *)first; - i = 3; + j = 3; do { qcopy(first_vectors, first_source); qcopy(second_angles, second_source); second_source += 4; second_angles += 4; first_source += 4; - i--; + j--; first_vectors[0] *= scale[0]; second_vectors[0] *= scale[0]; first_vectors[2] *= scale[1]; second_vectors[2] *= scale[1]; first_vectors += 4; second_vectors += 4; - } while (i >= 0); + } while (j >= 0); if (D_L10_0015B340 > 0) { - float *angle_vectors = (float *)(first + 0x50); + float *angles = (float *)(first + 0x58); float *first_angles = (float *)(second + 0x50); float *first_offsets = (float *)(second + 0x58); float *offsets = (float *)(first + 0x68); float *second_angles = (float *)(second + 0x60); float *second_offsets = (float *)(second + 0x68); + angle_vectors = (float *)(first + 0x50); for (i = 0; i < D_L10_0015B340; i++) { int parity = i & 1; int *colors = D_L10_0015B348; @@ -225,11 +229,11 @@ void FUN_L10_002e91b8(unsigned char *m) { } } transform_vectors((float *)first, matrix, 0); - transform_vectors((float *)second, matrix, 0); + transform_vectors(second_packet, matrix, 0); { - float *second_vectors = (float *)second; + float *second_vectors = second_packet; float *first_vectors = (float *)first; - int j = 3; + j = 3; do { first_vectors[1] += 0.1f; first_vectors += 4; From 965d6956cd8cba2359db8e42c06e316121c22df2 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:49:00 +0000 Subject: [PATCH 245/251] decomp: improve update_hero_held_items_and_orientation --- src/overlays/shared/ui/help/0020c758.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index 0ac247fd4..a69e16de0 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -1066,15 +1066,12 @@ void FUN_L00_0020e728(void) { slot++; } while (i < 2); if (hero.state.control_mode == 15) { - if (hero.unk5D8 != 0) { - *(u128 *)((u8 *)&hero + 0x680) = hero.motion.rot.q; - hero.unk688 = FUN_001ff8b0_e728( - *(f32 *)((u8 *)hero.unk5D8 + 0x10) - hero.motion.pos.f[0], - *(f32 *)((u8 *)hero.unk5D8 + 0x14) - hero.motion.pos.f[1]); - } else { - *(u128 *)((u8 *)&hero + 0x680) = hero.motion.rot.q; - hero.unk688 = FUN_002000e8_e728(hero.unk57C, hero.unk5D0); - } + hero.unk688 = hero.unk5D8 != 0 ? + (*(u128 *)((u8 *)&hero + 0x680) = hero.motion.rot.q, + FUN_001ff8b0_e728(*(f32 *)((u8 *)hero.unk5D8 + 0x10) - hero.motion.pos.f[0], + *(f32 *)((u8 *)hero.unk5D8 + 0x14) - hero.motion.pos.f[1])) : + (*(u128 *)((u8 *)&hero + 0x680) = hero.motion.rot.q, + FUN_002000e8_e728(hero.unk57C, hero.unk5D0)); hero.unk684 = -hero.unk580; vu_euler_rotation_basis(hero.basis, (u8 *)&hero + 0x680); FUN_001ff260_e728((u8 *)&hero + 0x670); From e4fcdc1cec4ba3ab1558f2c0b5d8697e6b137a91 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:10:56 +0000 Subject: [PATCH 246/251] decomp: improve FUN_L00_0020f160 --- src/overlays/shared/ui/help/0020c758.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index a69e16de0..869eb7fa7 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -1339,7 +1339,7 @@ void FUN_L00_0020f160(void *moby, void *matrix) /* Retail adds distances to these stack values without initializing them. */ f32 scores[16]; s32 i, j, n, chosen, ring, limit; - volatile s32 count; + s32 count; f32 maximum; s64 negative_one = -1; u8 *record; @@ -1360,8 +1360,15 @@ void FUN_L00_0020f160(void *moby, void *matrix) if ((*(s32 *)(hero_ptr->pad_21B8 + 4)) > 16) (*(s32 *)(hero_ptr->pad_21B8 + 4)) = 16; } - for (i = 0; i < 3; i++) - FUN_001ff260_f160(sum + i * 16); + { + u8 *record = sum; + i = 2; + do { + FUN_001ff260_f160(record); + i--; + record += 16; + } while (i >= 0); + } if (hero.state.control_mode == 22) D_0013F694 = 14; From 52bf91e2c2edf16bc18dcfe5909c2719aaed089c Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:12:09 +0000 Subject: [PATCH 247/251] decomp: improve FUN_L00_00276368 --- src/overlays/shared/audio/voices/00276368.c | 38 +++++++++++---------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index 42f4b43d6..dc86e04cd 100644 --- a/src/overlays/shared/audio/voices/00276368.c +++ b/src/overlays/shared/audio/voices/00276368.c @@ -68,16 +68,18 @@ extern u8 D_L00_001841F0_init[] __asm__("D_L00_001841F0"); #define D_L00_00184434 (*(s32 *)(D_L00_001841F0_init + 580)) #define D_L00_00184430 (*(s32 *)(D_L00_001841F0_init + 576)) #define D_L00_00184438 ((s32 *)(D_L00_001841F0_init + 584)) -#define D_L00_0016CC5C (*(f32 *)(D_L00_0016CAF0_raw + 364)) -#define D_L00_0016CC68 (*(f32 *)(D_L00_0016CAF0_raw + 376)) -#define D_L00_0016CC58 (*(s32 *)(D_L00_0016CAF0_raw + 360)) -#define D_L00_0016CC6C (*(s32 *)(D_L00_0016CAF0_raw + 380)) +#define D_L00_0016CC5C (*(f32 *)(D_L00_0016CA40 + 0x21c)) +#define D_L00_0016CC68 (*(f32 *)(D_L00_0016CA40 + 0x228)) +#define D_L00_0016CC58 (*(s32 *)(D_L00_0016CA40 + 0x218)) +#define D_L00_0016CC6C (*(s32 *)(D_L00_0016CA40 + 0x22c)) #define D_L00_00180240 ((s32 *)(D_L00_00180250 + -16)) +extern u8 D_L00_0016CA40[]; +extern u8 D_L00_00166C80[]; void FUN_L00_00276368(void) { s32 i; s32 special = 0; - f32 *source = D_L00_00166DC0_init; + f32 *source; s32 *handle; void *obj; u8 *table; @@ -89,27 +91,26 @@ void FUN_L00_00276368(void) { D_L00_001B9CF0.unkD0 = 0; if (D_L00_001B9CF0.state == 10) { D_L00_001B9CF0.state = 11; - owner = (struct Own *)D_L00_001B3518; + D_L00_001B9CF0.unk8 = (struct Own *)D_L00_001B3518; special = 1; } else if (D_L00_001B9CF0.state == 14) { D_L00_001B9CF0.state = 15; - owner = (struct Own *)D_L00_001B6088; + D_L00_001B9CF0.unk8 = (struct Own *)D_L00_001B6088; special = 1; } else if (D_L00_001B9CF0.state == 0x21) { D_L00_001B9CF0.unk124 = 1; - owner = &D_L00_001B71F0; + D_L00_001B9CF0.unk8 = &D_L00_001B71F0; D_L00_001B9CF0.state = 0x22; } else if (D_L00_001B9CF0.state == 0x23) { - owner = (struct Own *)D_L00_001B6B38; + D_L00_001B9CF0.unk8 = (struct Own *)D_L00_001B6B38; } else { if (D_L00_001B9CF0.state == 0x2d) { - owner = (struct Own *)D_L00_001B86C8; + D_L00_001B9CF0.unk8 = (struct Own *)D_L00_001B86C8; } else { - owner = (struct Own *)D_L00_001B2588; + D_L00_001B9CF0.unk8 = (struct Own *)D_L00_001B2588; } D_L00_001B9CF0.state = 2; } - D_L00_001B9CF0.unk8 = owner; D_L00_001B9CF0.owner = D_L00_001B9CF0.unk8; if (D_L00_001B9DE0 != 0) { D_L00_0015EED8 = D_L00_001B9E20; @@ -129,8 +130,8 @@ void FUN_L00_00276368(void) { *(volatile u128_init *)(D_L00_00180260 + 4) = 0; qcopy((void *)D_L00_001B9D30, (void *)D_L00_00166DC0_init); qcopy((void *)(D_L00_001B9D30 + 4), (void *)(D_L00_00166DC0_init + 4)); - D_L00_001B9DD8 = *(s32 *)D_L00_0016CAF0_raw; - *(f32 *)D_L00_0016CAF0_raw = 0.63f; + *(f32 *)((u8 *)&D_L00_001B9CF0 + 0xe8) = *(f32 *)(D_L00_0016CA40 + 0xb0); + *(f32 *)(D_L00_0016CA40 + 0xb0) = 0.63f; D_L00_0016CC5C = 524288.0f; D_L00_0016CC68 = 255.0f; D_L00_0016CC58 = 0; @@ -178,7 +179,7 @@ void FUN_L00_00276368(void) { s32 *handle; D_L00_00184434 = D_L00_0015EE78 + 0x40000; D_L00_00184430 = D_L00_0015EE78; - D_L00_0015EE78 += 0x40400; + D_L00_0015EE78 = D_L00_00184434 + 0x400; handle = D_L00_00184438; i = 3; do { @@ -213,6 +214,7 @@ void FUN_L00_00276368(void) { } while (i >= 0); } if (D_L00_001B9CF0.owner != 0) { + source = (f32 *)D_L00_00166C80; handle = D_L00_001B9E90_init; for (i = 0; i < 14; i++, handle++) { obj = FUN_L00_002830d8(0x472); @@ -220,9 +222,9 @@ void FUN_L00_00276368(void) { if (obj != 0) { *(u16 *)((u8 *)obj + 0x34) &= 0xfffd; *(void **)((u8 *)*handle + 0x74) = (void *)0x002df638; - *(f32 *)((u8 *)*handle + 0x10) = source[0]; - *(f32 *)((u8 *)*handle + 0x14) = source[1]; - *(f32 *)((u8 *)*handle + 0x18) = source[2]; + *(f32 *)((u8 *)*handle + 0x10) = source[80]; + *(f32 *)((u8 *)*handle + 0x14) = source[81]; + *(f32 *)((u8 *)*handle + 0x18) = source[82]; *(s32 *)((u8 *)*handle + 0x40) = 0; *(s32 *)((u8 *)*handle + 0x44) = 0; *(s32 *)((u8 *)*handle + 0x48) = 0; From 75b889590f3c84e8021158c98dc1f01eae6b37c7 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:13:50 +0000 Subject: [PATCH 248/251] decomp: improve FUN_L00_002382a0 --- src/overlays/shared/ui/text/002377b8.c | 32 ++++++++++---------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/overlays/shared/ui/text/002377b8.c b/src/overlays/shared/ui/text/002377b8.c index 77f42e371..689d3278b 100644 --- a/src/overlays/shared/ui/text/002377b8.c +++ b/src/overlays/shared/ui/text/002377b8.c @@ -421,17 +421,17 @@ s32 FUN_L00_002382a0(char *rec) { icon_y = y + D_L00_0015F724 + (s32)(D_L00_0015F78C * fast_sin(angle)); if (*(s32 *)(rec + 0x74) == i && - ((Ent *)(marker_offset + (char *)D_L00_0015FAC0_c[D_L00_0015F72C]))->f0 != 0) + ((Ent *)(marker_offset + (s32)D_L00_0015FAC0_c[D_L00_0015F72C]))->f0 != 0) draw_hud_sprite(get_icon_frame(0xe99c, 0), icon_x - 0x13, icon_y - 0x13, 0x26, 0x26, marker_alpha); - if (((Ent *)(normal_offset + (char *)D_L00_0015FAC0_c[D_L00_0015F72C]))->f0 != 0) { + if (((Ent *)(normal_offset + (s32)D_L00_0015FAC0_c[D_L00_0015F72C]))->f0 != 0) { s32 icon_alpha; if (i != *(s32 *)(rec + 0x74)) icon_alpha = truncate_float_to_s32((f32)alpha * D_L00_0015F7C0); else icon_alpha = alpha; entry = D_L00_0015FAC0_c[D_L00_0015F72C]; - entry = (Ent *)(entry_offset + (char *)entry); + entry = (Ent *)(entry_offset + (s32)entry); draw_hud_icon(rec, get_icon_frame(entry->f0, D_0013E520[entry->f18] ? 4 : 0), icon_x, icon_y, 1, icon_alpha); } @@ -469,8 +469,8 @@ s32 FUN_L00_002382a0(char *rec) { id = ((TitleItem_2382a0 *)D_L00_00179AC0)[item].h46; text = get_text(id); } - if (text == 0) return *(s32 *)(rec + 0x58); - if (strlen_alt(text) == 0) return *(s32 *)(rec + 0x58); + if (text == 0) goto out; + if (strlen_alt(text) == 0) goto out; text_length = strlen_alt(text); suffix = text; j = 0; @@ -493,21 +493,12 @@ s32 FUN_L00_002382a0(char *rec) { } if (prefix_length == 0) { suffix = text; - j = 0; - if (prefix_length < text_length) { - suffix = text + 1; - if ((u8)text[1] == ' ') { - suffix = text + 2; - prefix_length = 1; - } else { - while (++j < text_length) { - suffix++; - if (*(const u8 *)suffix == ' ') { - prefix_length = j + 1; - suffix++; - break; - } - } + for (j = 0; j < text_length; j++) { + suffix++; + if (*(const u8 *)suffix == ' ') { + suffix++; + prefix_length = j + 1; + break; } } } @@ -529,6 +520,7 @@ s32 FUN_L00_002382a0(char *rec) { font_print_right_2382a0(x + D_L00_0015F720, text_y, shadow, text, -1); } } +out: return *(s32 *)(rec + 0x58); } #endif From f4f813197a4eef2de57ed896c055a7b97d7cad44 Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:15:03 +0000 Subject: [PATCH 249/251] decomp: improve update_motion_and_emit_effects --- src/overlays/l13/gameplay/vendor/003058a8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/l13/gameplay/vendor/003058a8.c b/src/overlays/l13/gameplay/vendor/003058a8.c index f4aec3a62..f5d1100c3 100644 --- a/src/overlays/l13/gameplay/vendor/003058a8.c +++ b/src/overlays/l13/gameplay/vendor/003058a8.c @@ -2181,7 +2181,7 @@ extern void FUN_0020c828(void *); extern void FUN_L13_0030c2b0(void *); extern void FUN_00218888(void *, void *, void *, int, int, int, int, int, int); extern float D_0015ED70; -extern int D_001413D0; +extern int D_001413D0 __attribute__((section(".data"))); extern float D_L13_00161F18 __attribute__((sda)); extern float D_L13_00161F1C __attribute__((sda)); extern float D_L13_00161F20 __attribute__((sda)); From 966c3b75046b3266526779fd5c74f71d11a9fa1e Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:11:35 +0000 Subject: [PATCH 250/251] decomp: improve FUN_L06_002f5d78 --- src/overlays/l06/gameplay/entities/002b4770.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlays/l06/gameplay/entities/002b4770.c b/src/overlays/l06/gameplay/entities/002b4770.c index 675e65dd0..356e1b8a0 100644 --- a/src/overlays/l06/gameplay/entities/002b4770.c +++ b/src/overlays/l06/gameplay/entities/002b4770.c @@ -1246,7 +1246,7 @@ void FUN_L06_002f5d78(char *moby) { left = (char **)(data + 0x110); for (i = 0, offset = 0; i < 10; i++, offset += 2, left++, right++) { float length = D_L06_00161D78 - ((float)i + (float)i); - threshold = D_L06_00161D70 + (float)(4 - i) * D_L06_00161D74; + threshold = (float)(4 - i) * D_L06_00161D74 + D_L06_00161D70; upper = length; lower = length - 1.0f; if (length < threshold) upper = threshold; From 453f2a1a8a7c23985f7398e552aaf7457959821b Mon Sep 17 00:00:00 2001 From: Ben Perry <7693062+ben-perry@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:48:04 +0000 Subject: [PATCH 251/251] overlay: reuse shared layouts and preserve canonical function names --- src/overlays/l07/gameplay/entities/00312948.c | 10 +++++----- src/overlays/l08/gameplay/entities/002b8228.c | 17 +++++------------ src/overlays/l12/gameplay/entities/002bf140.c | 6 +++--- src/overlays/shared/audio/voices/00276368.c | 2 +- .../shared/rendering/effects/00268900.c | 3 ++- src/overlays/shared/ui/help/00226f10.c | 3 ++- 6 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/overlays/l07/gameplay/entities/00312948.c b/src/overlays/l07/gameplay/entities/00312948.c index b1472b26b..6bf471de5 100644 --- a/src/overlays/l07/gameplay/entities/00312948.c +++ b/src/overlays/l07/gameplay/entities/00312948.c @@ -551,7 +551,7 @@ typedef struct { void *moby; int kind; } ChaserSight; -typedef struct { int count; int pad[3]; RopeVec points[1]; } ChaserPath; +#include "rnc/overlay/swarm_path.h" typedef struct { char pad[0x1D4]; unsigned char path_points[4]; int linked_mobys[6]; } ChaserPathPoints; typedef struct { char pad[0x3C]; short count; char pad2[0xE]; } ChaserSpawnRecord; extern char *D_L07_0015FFD8; @@ -785,23 +785,23 @@ void FUN_L07_00314150(unsigned char *moby) { if (*(int *)(data + 0x18C) != -1) { int i; for (i = 0; i < *(int *)D_L07_001B0530[*(int *)(data + 0x18C)]; i++) { - ((ChaserPath *)D_L07_001B0530[*(int *)(data + 0x18C)])->points[i][3] = + ((SwarmPath *)D_L07_001B0530[*(int *)(data + 0x18C)])->points[i].f[3] = FUN_001f9b48(D_L07_001B0530[*(int *)(data + 0x18C)] + (i * 16 + 0x10), D_L07_001B0530[*(int *)(data + 0x18C)] + (((i + 1) % *(int *)D_L07_001B0530[*(int *)(data + 0x18C)]) * 16 + 0x10)); - *(float *)(data + 0x190) += ((ChaserPath *)D_L07_001B0530[*(int *)(data + 0x18C)])->points[i][3]; + *(float *)(data + 0x190) += ((SwarmPath *)D_L07_001B0530[*(int *)(data + 0x18C)])->points[i].f[3]; } } if (*(int *)(data + 0x290) != -1) { char *tbl = D_L07_001B0530[*(int *)(data + 0x290)]; int i; for (i = 0; i < *(int *)tbl; i++) { - ((ChaserPath *)tbl)->points[i][3] = FUN_001f9b48(tbl + (i * 16 + 0x10), tbl + (((i + 1) % *(int *)tbl) * 16 + 0x10)); + ((SwarmPath *)tbl)->points[i].f[3] = FUN_001f9b48(tbl + (i * 16 + 0x10), tbl + (((i + 1) % *(int *)tbl) * 16 + 0x10)); } } if (*(int *)(data + 0x188) != -1) { int i; for (i = 0; i < *(int *)D_L07_001B0530[*(int *)(data + 0x188)]; i++) { - int k = truncate_float_to_s32(((ChaserPath *)D_L07_001B0530[*(int *)(data + 0x188)])->points[i][3]); + int k = truncate_float_to_s32(((SwarmPath *)D_L07_001B0530[*(int *)(data + 0x188)])->points[i].f[3]); if ((unsigned int)k < 4) ((ChaserPathPoints *)data)->path_points[k] = i; } } diff --git a/src/overlays/l08/gameplay/entities/002b8228.c b/src/overlays/l08/gameplay/entities/002b8228.c index c5fcbe5aa..3aef0175d 100644 --- a/src/overlays/l08/gameplay/entities/002b8228.c +++ b/src/overlays/l08/gameplay/entities/002b8228.c @@ -1449,15 +1449,8 @@ extern void FUN_L08_002dc9a8_start(int, int, void *) __asm__("FUN_0022da68"); extern void FUN_L08_002dc9a8_finish(void *) __asm__("FUN_0020c828"); extern float D_0015ED6C_2DC9A8 __asm__("D_0015ED6C"); extern float D_0015ED70_2DC9A8 __asm__("D_0015ED70"); -typedef struct CollisionRecord_2DC9A8 { - char pad[0x18]; - int owner; - int unknown; - float position[4]; - char pad30[0x10]; - float vector[4]; -} CollisionRecord_2DC9A8; -extern CollisionRecord_2DC9A8 D_L08_00174640_2DC9A8 __asm__("D_L08_00174640"); +#include "rnc/overlay/collision.h" +extern CollisionHit D_L08_00174640_2DC9A8 __asm__("D_L08_00174640"); extern int D_L08_00174658_2DC9A8 __asm__("D_L08_00174658") __attribute__((section(".data"))); typedef struct __attribute__((packed)) EffectVectorCopy_2DC9A8 { @@ -1506,10 +1499,10 @@ void FUN_L08_002dc9a8(struct Moby *moby) { qcopy(record.velocity, data); if (FUN_L08_002dc9a8_trace(original, &record, 0, m, 0) != 0) { if (*(int *)(data + 0x20) != 0 && - D_L08_00174640_2DC9A8.owner != *(int *)(data + 0x20)) { + D_L08_00174640_2DC9A8.moby != *(int *)(data + 0x20)) { m[0x20] = 99; - qcopy(position, D_L08_00174640_2DC9A8.position); - FUN_L08_002dc9a8_add(data, data, D_L08_00174640_2DC9A8.vector); + qcopy(position, D_L08_00174640_2DC9A8.point.f); + FUN_L08_002dc9a8_add(data, data, &D_L08_00174640_2DC9A8.normal_x); FUN_L08_002dc9a8_scale(D_0015ED6C_2DC9A8 + D_0015ED6C_2DC9A8, data, data); } } else { diff --git a/src/overlays/l12/gameplay/entities/002bf140.c b/src/overlays/l12/gameplay/entities/002bf140.c index 270329ff7..a531e1848 100644 --- a/src/overlays/l12/gameplay/entities/002bf140.c +++ b/src/overlays/l12/gameplay/entities/002bf140.c @@ -2373,7 +2373,7 @@ extern int D_L12_001619A0 __attribute__((sda)); typedef struct { char pad[0x25c]; struct Moby *moby; int count; } Tracking_e9f68; extern Tracking_e9f68 D_L12_00167100; extern unsigned char D_0014C050[]; -typedef struct { char pad[0x74]; unsigned char active; char pad75[0x13]; struct Moby *moby; char rest[0x70 - 0x1c]; } Voice_e9f68; +#include "rnc/audio/voice_pool.h" extern unsigned char D_0013E550[]; extern unsigned char D_0013D4CB; extern unsigned short D_00141C50; @@ -2406,7 +2406,7 @@ void FUN_L12_002e9f68(struct Moby *moby) { *(int *)(data + 0xb0) = allocate_voice_for_target_entry_e9f68(3, 4, (int)moby); } else { index = *(int *)(data + 0xb0); - if (index != -1 && ((Voice_e9f68 *)(D_0013E550 + index * 0x70))->moby == moby && ((Voice_e9f68 *)(D_0013E550 + index * 0x70))->active) + if (index != -1 && (void *)((VoicePoolWindow *)(D_0013E550 + index * 0x70))->voice.owner == (void *)moby && ((VoicePoolWindow *)(D_0013E550 + index * 0x70))->voice.state) release_voice(index); *(int *)(data + 0xb0) = -1; } @@ -2618,7 +2618,7 @@ void FUN_L12_002e9f68(struct Moby *moby) { FUN_L00_0025e450(moby, D_L12_0015F580, &moby->pos, 0.0f, 0.0f, 20, 3, 4, 4.0f, 2.0f, 100000.0f, 2, 3.0f, 15.0f, 1, 1, -1, 0); if (*(int *)(data + 0xc0) == 0) FUN_L00_00257470(moby, 0, -1); index = *(int *)(data + 0xb0); - if (index != -1 && ((Voice_e9f68 *)(D_0013E550 + index * 0x70))->moby == moby && ((Voice_e9f68 *)(D_0013E550 + index * 0x70))->active) release_voice(index); + if (index != -1 && (void *)((VoicePoolWindow *)(D_0013E550 + index * 0x70))->voice.owner == (void *)moby && ((VoicePoolWindow *)(D_0013E550 + index * 0x70))->voice.state) release_voice(index); *(int *)(data + 0xb0) = -1; if (*(int *)(data + 0xc0) == 0) { remove: diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index dc86e04cd..7fbdf5ec8 100644 --- a/src/overlays/shared/audio/voices/00276368.c +++ b/src/overlays/shared/audio/voices/00276368.c @@ -683,7 +683,7 @@ extern void FUN_L00_00299f40(void *, void *, s32 *, s32 *, s32 *, s32 *) __asm__ extern void FUN_L00_0023caa8_772c0(s32, s32, s32, s32, u64, s32) __asm__("FUN_00200e08"); extern void FUN_L00_001fc928(f32, s32, s32, s32) __asm__("FUN_001f7888"); extern void FUN_L00_0023cc30(s32, s32, s32, s32, u64, s32, s32) __asm__("FUN_00200f90"); -extern void FUN_L00_001fca18(void) __asm__("FUN_L00_001fca18"); +extern void FUN_L00_001fca18(void) __asm__("FUN_001f7978"); extern void FUN_L00_001fa290(s32, s32, s32, s32, s32, s32, s32, s32, u64, u64) __asm__("FUN_001f5450"); extern void FUN_L00_0024fe20(void) __asm__("FUN_L00_0024fe20"); extern void FUN_L00_0024ff88(void) __asm__("FUN_L00_0024ff88"); diff --git a/src/overlays/shared/rendering/effects/00268900.c b/src/overlays/shared/rendering/effects/00268900.c index 3b50bb8ae..5c146ad6a 100644 --- a/src/overlays/shared/rendering/effects/00268900.c +++ b/src/overlays/shared/rendering/effects/00268900.c @@ -93,7 +93,8 @@ extern void FUN_L00_00275eb0(void); extern u32 effect_handlers[] __asm__("D_L00_001B1E80"); -void FUN_L00_00268900(void) +void register_part_types(void) __asm__("FUN_L00_00268900"); +void register_part_types(void) { u32 *handlers = effect_handlers; handlers[0] = (u32)FUN_L00_00268d48; diff --git a/src/overlays/shared/ui/help/00226f10.c b/src/overlays/shared/ui/help/00226f10.c index 9c2704d40..4210b0f8e 100644 --- a/src/overlays/shared/ui/help/00226f10.c +++ b/src/overlays/shared/ui/help/00226f10.c @@ -1300,7 +1300,8 @@ extern void add_vector_xyz_34358(void *, void *, void *) __asm__("FUN_001f9a10") extern void FUN_001f9c48_34358(void *, void *, f32) __asm__("FUN_001f9c48"); extern f32 vector_length_xy_34358(void *) __asm__("FUN_001f9b20"); -void FUN_L01_00234358(float amount) { +void air_accel(float amount) __asm__("FUN_L01_00234358"); +void air_accel(float amount) { f32 delta[4]; Vec4 *velocity; Vec4 saved;