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/dma/sce_gs_set_def_disp_env.c b/src/assembly/sdk/dma/sce_gs_set_def_disp_env.c index 58bfbf4be..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 @@ -28,8 +28,10 @@ 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; state = GetCoreDataTable(); if (!((u32)(state->wMode - 2) < 2) && checkModelVersion() != 0) { @@ -56,54 +58,52 @@ void sceGsSetDefDispEnv(struct sceGsDispEnv *output, s16 pixel_storage_format, s if ((s16)mode == 2) { if ((s16)interlace == 1) { - scale = width + 0x9ff; - scale /= width; - 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 { + 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; + if (state->nSFrame_mode != 0) { scale = height * 2 - 1; + } else { + scale = height - 1; } - value |= (u64)(s64)scale << 44; + value = ((display_width | value) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44))) | display_vertical; } else { scale = width + 0x9ff; scale /= width; - scaled_horizontal = horizontal_offset * scale; - value = ((u64)(s64)(height - 1) << 44) | - ((u64)(s64)(scale - 1) << 23) | + scaled_horizontal = scale * horizontal_offset; + value = ((u64)(s64)(scale - 1) << 23) | + ((u64)((s64)(scale * width) - 1) << 32) | ((u64)(((s64)scaled_horizontal + (s64)(((u32)kernel_horizontal + 0x27cU) & 0xfffU)) & 0xfff)) | - ((u64)((s64)(width * scale) - 1) << 32) | - ((u64)((vertical_offset + kernel_vertical + 0x19) & 0xfff) << 12); + ((u64)((vertical_offset + kernel_vertical + 0x19) & 0xfff) << 12) | + ((u64)(s64)(height - 1) << 44); } output->display = value; } else if ((s16)mode == 3) { if ((s16)interlace == 1) { - scale = width + 0x9ff; - scale /= width; - 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); + 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; if (state->nSFrame_mode != 0) { scale = height * 2 - 1; } else { scale = height - 1; } - value |= (u64)(s64)scale << 44; + value = ((display_width | value) | ((u64)scaled_horizontal | ((u64)(s64)scale << 44))) | display_vertical; } else { scale = width + 0x9ff; scale /= width; - scaled_horizontal = horizontal_offset * scale; - value = ((u64)(s64)(height - 1) << 44) | - ((u64)(s64)(scale - 1) << 23) | + scaled_horizontal = scale * horizontal_offset; + value = ((u64)(s64)(scale - 1) << 23) | + ((u64)((s64)(scale * width) - 1) << 32) | ((u64)(((s64)scaled_horizontal + (s64)(((u32)kernel_horizontal + 0x290U) & 0xfffU)) & 0xfff)) | - ((u64)((s64)(width * scale) - 1) << 32) | - ((u64)((vertical_offset + kernel_vertical + 0x24) & 0xfff) << 12); + ((u64)((vertical_offset + kernel_vertical + 0x24) & 0xfff) << 12) | + ((u64)(s64)(height - 1) << 44); } output->display = value; } else if ((s16)mode == 0x50) { diff --git a/src/assembly/sdk/rpc/sce_sif_init_cmd.c b/src/assembly/sdk/rpc/sce_sif_init_cmd.c index ddbdb723f..245272ab8 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,39 @@ 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; - 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.unk8 = 0; - - var_16_46 = 0x1F; - D_00154E58.unkC = 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.unk18 = 0; - D_00154E58.unk10 = ipval; + D_00154E58.unk8 = 0; + D_00154E58.unkC = handlers; + ipval = 0x1F; + var_3_42 = handlers; 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); { 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; } diff --git a/src/assembly/textbin/fun_0021a328.c b/src/assembly/textbin/fun_0021a328.c index efba39130..d81f7fec1 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; + flags = entry->id; availability_table = entry->kind == 0 ? item_available : alternate_item_available; - if (availability_table[item_id] != 0) { + flags = availability_table[flags]; + 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); @@ -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) { diff --git a/src/assembly/textbin/fun_0022e420.c b/src/assembly/textbin/fun_0022e420.c index 15ee9d9d0..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; @@ -88,10 +87,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 +109,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 +122,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); } 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(); 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); diff --git a/src/assembly/textbin/video/display/set_pal_mode.c b/src/assembly/textbin/video/display/set_pal_mode.c index c503af897..3e75ce441 100644 --- a/src/assembly/textbin/video/display/set_pal_mode.c +++ b/src/assembly/textbin/video/display/set_pal_mode.c @@ -61,12 +61,11 @@ 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.bottom = (screen_extent.half_height + 0x800) << 4; - screen_extent.height = fs_aa_buffer.display_height; + screen_extent.half_height = (screen_extent.height = fs_aa_buffer.display_height) >> 1; 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; 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" diff --git a/src/overlays/l04/runtime/dma/002922d0.c b/src/overlays/l04/runtime/dma/002922d0.c index 05eefea94..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; @@ -94,9 +94,9 @@ void FUN_L04_002923b8(char *arg0, char *arg1) { difference = (end + item->len) - start; *current = difference; item = *slot; - current = &item->phase[0].span[j]; 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 @@ -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++) { + qcopy(local.joints, 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; } } } diff --git a/src/overlays/l05/gameplay/entities/002d1688.c b/src/overlays/l05/gameplay/entities/002d1688.c index 819a8c8f8..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); @@ -1021,7 +1024,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 diff --git a/src/overlays/l06/gameplay/entities/002b4770.c b/src/overlays/l06/gameplay/entities/002b4770.c index dcd8a5038..356e1b8a0 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); @@ -1240,11 +1242,11 @@ 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; + threshold = (float)(4 - i) * D_L06_00161D74 + D_L06_00161D70; upper = length; lower = length - 1.0f; if (length < threshold) upper = threshold; @@ -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); } @@ -1902,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); @@ -2170,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); @@ -2212,6 +2452,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 +2495,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 +2509,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 +2547,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_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; damping = D_L06_00161F3C; @@ -2347,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; diff --git a/src/overlays/l06/gameplay/entities/002fd1a0.c b/src/overlays/l06/gameplay/entities/002fd1a0.c index 011367752..857151d34 100644 --- a/src/overlays/l06/gameplay/entities/002fd1a0.c +++ b/src/overlays/l06/gameplay/entities/002fd1a0.c @@ -1827,11 +1827,11 @@ 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); - 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); @@ -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; @@ -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; diff --git a/src/overlays/l07/gameplay/entities/002cd2b0.c b/src/overlays/l07/gameplay/entities/002cd2b0.c index a7f0c846f..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; @@ -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; } @@ -2009,15 +2011,15 @@ 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 + 0x28) = *(float *)(packet + 0x38) = *(float *)(moby + 0x18); *(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); *(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; @@ -2463,7 +2465,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 *); diff --git a/src/overlays/l07/gameplay/entities/00312948.c b/src/overlays/l07/gameplay/entities/00312948.c index 59a274371..6bf471de5 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; +#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; +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++) { + ((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) += ((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++) { + ((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(((SwarmPath *)D_L07_001B0530[*(int *)(data + 0x188)])->points[i].f[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 @@ -591,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; } } @@ -805,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; @@ -889,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)) { @@ -900,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; 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; } diff --git a/src/overlays/l08/gameplay/entities/002b8228.c b/src/overlays/l08/gameplay/entities/002b8228.c index d5d408d26..3aef0175d 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)); @@ -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,13 +1443,14 @@ 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"); 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"); +#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 { @@ -1482,7 +1480,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; @@ -1490,23 +1488,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.moby != *(int *)(data + 0x20)) { + m[0x20] = 99; + 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 { 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: { @@ -1520,7 +1520,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; @@ -1542,6 +1542,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; @@ -1549,14 +1550,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: { @@ -1566,12 +1567,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; @@ -1581,7 +1582,6 @@ void FUN_L08_002dc9a8(struct Moby *moby) { } break; } } -#endif #include "sda.h" /* Rocket guidance, route traversal, launch effects, and destruction. */ diff --git a/src/overlays/l08/gameplay/entities/002deee0.c b/src/overlays/l08/gameplay/entities/002deee0.c index a4efcaf79..7c0ad1d5c 100644 --- a/src/overlays/l08/gameplay/entities/002deee0.c +++ b/src/overlays/l08/gameplay/entities/002deee0.c @@ -1353,23 +1353,23 @@ 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; 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) { 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; @@ -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" diff --git a/src/overlays/l08/gameplay/entities/002e9b70.c b/src/overlays/l08/gameplay/entities/002e9b70.c index ef182e9c4..830658b26 100644 --- a/src/overlays/l08/gameplay/entities/002e9b70.c +++ b/src/overlays/l08/gameplay/entities/002e9b70.c @@ -511,17 +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, 1, 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; @@ -704,15 +708,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; @@ -826,31 +830,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; diff --git a/src/overlays/l10/gameplay/entities/00295a38.c b/src/overlays/l10/gameplay/entities/00295a38.c index 8be4c6409..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; @@ -1967,12 +1968,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,69 +1996,125 @@ void FUN_L10_002da690(struct Moby *moby) { int i, group, row, vertex; float fade, phase; char *transform; + 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; - 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]; - } - 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); - buffers.matrix1[i * 2] = value; - buffers.packet.fields.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, *(int *)0x0015b090, *(int *)0x0015b094); - color = (color & 0xffffff) + - (truncate_float_to_s32_da690(fade * fade * - convert_integer_to_float_da690((int)color >> 24)) << 24); - if (moby->state == 2) { - float alpha = convert_integer_to_float_da690(*(int *)(data + 0x34)); - float duration = scale_time_da690(*(float *)0x0015b098 * 60.0f); - color = (truncate_float_to_s32_da690(alpha * 255.0f / duration) << 24) | 0xffffff; + matrix1 = buffers.matrix1; + matrix2 = buffers.packet.fields.matrix2; + uv1 = matrix1 + 1; + uv2 = matrix2 + 1; + i = 0; + if (*(int *)(data + 4) > 0) { + transform = scratch; + do { + 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(next) * *(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 *)buffers.matrix1)[5] = texture; + ((u64 *)buffers.packet.fields.matrix2)[5] = texture; + ((u64 *)buffers.matrix1)[6] = 0xff9000000260ULL; + ((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; + } + { + int i; + float *source = (float *)0x001d9ff0; + source++; + i = 3; + do { + float value = *source; + source += 2; + *uv2 = value; + *uv1 = value; + uv2 += 2; + uv1 += 2; + } while (--i >= 0); + } + { + age_base = base + 0x10000; + group = 0; + do { + next_group = group + 1; + phase = 0.0f; + row = 0; + do { + 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); + matrix2[i * 2] = value; + matrix1[i * 2] = value; } + i = 0; + if (*(int *)(data + 4) > 0) { + do { + 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); + } 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 @@ -2072,7 +2136,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) { @@ -2106,7 +2171,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; diff --git a/src/overlays/l10/gameplay/vendor/002df270.c b/src/overlays/l10/gameplay/vendor/002df270.c index bce1ad0aa..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); } } } @@ -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; @@ -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; diff --git a/src/overlays/l12/gameplay/entities/002bf140.c b/src/overlays/l12/gameplay/entities/002bf140.c index 2a14f07db..a531e1848 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 + 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 + 0x20) = 0.1f; 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; + *(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; @@ -869,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) @@ -878,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); @@ -894,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); @@ -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 { @@ -2029,7 +2346,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[]; +#include "rnc/audio/voice_pool.h" +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 && (void *)((VoicePoolWindow *)(D_0013E550 + index * 0x70))->voice.owner == (void *)moby && ((VoicePoolWindow *)(D_0013E550 + index * 0x70))->voice.state) + 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 && (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: + 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. */ diff --git a/src/overlays/l12/gameplay/vendor/003028c8.c b/src/overlays/l12/gameplay/vendor/003028c8.c index 8ec18f7f6..9750a7430 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 && @@ -1165,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; } @@ -1279,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. */ @@ -1541,19 +1818,22 @@ 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); - 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; + 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; + 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; - second.texture = first.texture; - first.tag = second.tag = 0; + first.texture_state = second.texture_state = 0xFF9000000260L; + second.tag = 0; + 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; 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; diff --git a/src/overlays/l13/gameplay/vendor/003058a8.c b/src/overlays/l13/gameplay/vendor/003058a8.c index d64d6e7d7..f5d1100c3 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; @@ -360,6 +360,7 @@ void FUN_L13_00306300(struct Moby *moby) { } work; extern L13TargetRow_6300 D_L13_00178400[]; int stationary; + 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; @@ -369,66 +370,73 @@ 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 = 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) { 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, (unsigned short)flags | 0x10000, &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 = (unsigned short)flags | 0x10000; } break; } } } - FUN_L00_00259888(&work.hit, moby, 0x10001, &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.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) goto collision; if (moby->visible != 0) { - int i = 2; - do { + 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); - 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; + *(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_0022da68(&moby->pos, &work.velocity); - } while (i >= 0); + FUN_L07_0029a2a0(&moby->pos, velocity); + } } mark_moby_for_removal(moby); return; @@ -438,14 +446,13 @@ 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; + *(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); @@ -454,11 +461,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: @@ -591,7 +598,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. */ @@ -1887,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)); @@ -1919,6 +2213,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; @@ -1931,11 +2227,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); @@ -1956,25 +2252,26 @@ 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; 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); - 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, @@ -2000,14 +2297,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 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, 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); 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); 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 diff --git a/src/overlays/shared/audio/voices/00276368.c b/src/overlays/shared/audio/voices/00276368.c index 85e29fb5c..7fbdf5ec8 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"); @@ -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"); @@ -66,21 +68,25 @@ 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; 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) { @@ -118,14 +124,14 @@ 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); 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; @@ -173,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 { @@ -208,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); @@ -215,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) = 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[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; @@ -280,19 +287,25 @@ 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; + 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] + : value; + } } } { 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) { @@ -336,8 +349,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); diff --git a/src/overlays/shared/gameplay/animation/00235878.c b/src/overlays/shared/gameplay/animation/00235878.c index 3d4688172..c230ad39f 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"); @@ -552,6 +553,8 @@ 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 *, ...); extern void FUN_0023cf80(int, int, int, char *) __asm__("FUN_00201200"); @@ -592,24 +595,29 @@ 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); + 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); - FUN_0023b860(FUN_0023b208(0x7580, 1), left + (width + 0x20), 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), (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; } 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; } @@ -623,30 +631,31 @@ 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) { - *(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); - if (elapsed != 0) { - interval = pal_mode != 0 ? 3000 : 3600; - minute_scale = interval / 60; - seconds = elapsed / interval; - 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; + 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]; + if (elapsed != 0) { + const char *message; + interval = pal_mode != 0 ? 3000 : 3600; + seconds = elapsed / interval; + other_width = interval / 60; + remainder = elapsed - seconds * interval; + 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); + FUN_0023cf80(0x100, y + 0x28, color, text); + if (extra != 0) { + FUN_00116248(text, freeze_stats_score_format, FUN_00203ad8(0x531c), extra); + FUN_0023cf80(0x100, y + 0x48, color, text); + } } } } 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; } diff --git a/src/overlays/shared/gameplay/entities/00264e40.c b/src/overlays/shared/gameplay/entities/00264e40.c index 7e201bba2..043b38dd4 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; @@ -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; } } 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); } } diff --git a/src/overlays/shared/gameplay/entities/002937a0.c b/src/overlays/shared/gameplay/entities/002937a0.c index 1714d5ee8..9a950fcf7 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; } } @@ -1683,11 +1682,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 + 0x98) = 0.25f; + *(float *)(d + 0xc0) = 11.0f; + *(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)); 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(); } } diff --git a/src/overlays/shared/gameplay/entities/00297d10.c b/src/overlays/shared/gameplay/entities/00297d10.c index 31e800440..4265d9f87 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) { @@ -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 { @@ -1841,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; @@ -2004,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++; } } } diff --git a/src/overlays/shared/gameplay/entities/0029f990.c b/src/overlays/shared/gameplay/entities/0029f990.c index 90a6cd9cd..dd8585c27 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; @@ -191,21 +195,22 @@ 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++; - 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]; \ 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"); diff --git a/src/overlays/shared/gameplay/entities/002a4830.c b/src/overlays/shared/gameplay/entities/002a4830.c index 8c9099e5a..0d8cf41c9 100644 --- a/src/overlays/shared/gameplay/entities/002a4830.c +++ b/src/overlays/shared/gameplay/entities/002a4830.c @@ -296,18 +296,20 @@ 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]; 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; - s32 i, index; + s32 index; f32 zero; s32 *indices1, *indices2; s32 index1, index2, index3; @@ -324,31 +326,42 @@ 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; + 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[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; + 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]; @@ -413,10 +426,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); diff --git a/src/overlays/shared/gameplay/entities/002b17d8.c b/src/overlays/shared/gameplay/entities/002b17d8.c index f4cd1dd49..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); @@ -943,6 +938,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 +985,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 +998,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]; } @@ -1090,6 +1089,7 @@ void FUN_L14_002dfd10(struct Moby *moby) { float absolute_velocity; void *path; float one; + int one_bits; float zero; if (moby->state == 0) { @@ -1107,7 +1107,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, @@ -1143,7 +1144,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); diff --git a/src/overlays/shared/gameplay/entities/002b2100.c b/src/overlays/shared/gameplay/entities/002b2100.c index da06e0dd7..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; @@ -2376,7 +2377,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 +2529,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 +2543,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; diff --git a/src/overlays/shared/gameplay/entities/002b3840.c b/src/overlays/shared/gameplay/entities/002b3840.c index f2994ccac..6fb51b65a 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)); @@ -279,55 +280,59 @@ 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; - 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: + 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; } - } - } else { - if (*(int *)(data + 0x50) == 0 && *(unsigned char *)0x13d388 != 0 && + break; + case 1: + if (*(int *)(data + 0x50) == 0 && alternate_item_available[0] != 0 && *(unsigned short *)0x141938 == 0 && *(int *)0x15f6a8 != 0 && - scale_game_frames_87a8(0x4b0) < *(int *)0x13f4ec && + scale_game_frames_87a8(0x4b0) < (g = &hero)->unk19C && *(unsigned short *)0x141c60 == 0) { play_sound_87a8(0x138f, 0x5f); } - if (*(int *)0x1413dc != 0x16) { + if (hero.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,14 +340,14 @@ 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); } { 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; diff --git a/src/overlays/shared/gameplay/entities/002b8c08.c b/src/overlays/shared/gameplay/entities/002b8c08.c index c5a392816..0f45f345b 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: @@ -1995,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; @@ -2689,24 +2699,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; @@ -2843,15 +2856,8 @@ 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" -#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"); @@ -2862,9 +2868,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; @@ -2874,6 +2880,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]; @@ -2882,19 +2889,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; @@ -2913,7 +2921,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); @@ -2933,10 +2941,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; @@ -2955,17 +2967,21 @@ 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); - D_0015F630 = *(u8 *)(pos + 7); - D_0015F634 = *(u8 *)((u8 *)pos + 0x1d); + { + u32 texture_id = *(u32 *)(pos + 5); + u32 second_texture_id = *(u32 *)(pos + 6); + D_L01_00161228 = texture_id; + D_L01_0016122C = second_texture_id; + } + 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; @@ -2973,4 +2989,3 @@ void FUN_L01_002b91c8(f32 *pos, s32 count) { l01_packet.words[3] = 0; l01_packet.words += 4; } -#endif diff --git a/src/overlays/shared/gameplay/entities/002b94d0.c b/src/overlays/shared/gameplay/entities/002b94d0.c index 00a718fc7..71f65c133 100644 --- a/src/overlays/shared/gameplay/entities/002b94d0.c +++ b/src/overlays/shared/gameplay/entities/002b94d0.c @@ -1216,16 +1216,17 @@ 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)); -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"))); extern void scale_vector_2bcf98(float, void *, void *) __asm__("FUN_001f9a68"); extern void FUN_001f9a10(void *, void *, void *); @@ -1237,19 +1238,21 @@ 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; 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; D_L00_00161724_i = 0; + scaled_vector = &vec; D_L00_001617D0 = 0; D_L00_00161824 = 0; copies = (u128 *)&D_L00_001DD0D0; @@ -1258,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++; } @@ -1912,10 +1915,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); @@ -1937,19 +1942,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); @@ -1961,7 +1966,7 @@ void FUN_L00_002be650(void *o) { } draw_2be650(&quad, 0, 0); } - i = nextIndex; + i = state.nextIndex; } while (i < 3); } #endif diff --git a/src/overlays/shared/gameplay/entities/002bffa8.c b/src/overlays/shared/gameplay/entities/002bffa8.c index 69f9b15e6..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"))); @@ -1060,7 +1427,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"))); diff --git a/src/overlays/shared/gameplay/entities/002c8440.c b/src/overlays/shared/gameplay/entities/002c8440.c index 1f2a2b764..e9614eb05 100644 --- a/src/overlays/shared/gameplay/entities/002c8440.c +++ b/src/overlays/shared/gameplay/entities/002c8440.c @@ -155,7 +155,191 @@ 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; + u8 *collision_point; + 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); + } + 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); + 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)) { + 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; + } + 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, collision_point); + 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). */ @@ -377,7 +561,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 @@ -581,7 +1102,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 { @@ -829,9 +1351,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"); @@ -839,7 +1358,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"); @@ -854,7 +1373,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--) { @@ -865,40 +1384,48 @@ 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); } } - 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(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. */ + 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 = 0x44; + effect[3] = alpha; + } + } } } } -#endif #include "qcopy.h" #include "rnc/overlay/quad.h" extern float D_0015ED6C_2cbf68 __asm__("D_0015ED6C"); @@ -1545,21 +2072,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]); @@ -1589,7 +2121,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 { @@ -1597,7 +2129,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); } @@ -1922,30 +2454,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; @@ -2152,7 +2682,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); diff --git a/src/overlays/shared/gameplay/entities/002cfcb8.c b/src/overlays/shared/gameplay/entities/002cfcb8.c index dbf5bd40b..6d4aac10e 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; @@ -450,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"); @@ -474,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; @@ -526,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; @@ -540,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; @@ -551,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; @@ -562,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); } @@ -582,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; @@ -616,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 @@ -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; @@ -791,11 +792,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[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; @@ -805,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); @@ -820,18 +820,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++; } @@ -840,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; @@ -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"); @@ -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) @@ -2303,7 +2304,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; @@ -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; @@ -2581,7 +2583,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]; @@ -2879,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; @@ -2941,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]; @@ -2980,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; diff --git a/src/overlays/shared/gameplay/entities/002d7f88.c b/src/overlays/shared/gameplay/entities/002d7f88.c index 5b22ff076..fbf68a62a 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,16 +921,17 @@ 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; 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, @@ -938,8 +939,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; @@ -2013,6 +2014,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 +2044,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 +2062,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 +2098,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 +2143,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); @@ -2612,7 +2623,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"); @@ -2626,8 +2637,10 @@ 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; - char *current, *prior; + int current, segment_offset; + char *prior; quad.texture[1] = FUN_001f9298_002dd8e8(0x15); quad.texture[2] = 0xff9000000260ULL; @@ -2640,49 +2653,53 @@ 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++) { - 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); + segment_offset = segment * 16; + qcopy(&quad.points[0], D_L00_001E6020_002dd8e8 + (current + segment_offset)); + 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)); 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; + 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; + 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] = dot; + quad.texcoords[4] = previous_phase; + quad.texcoords[5] = offset; + quad.texcoords[6] = previous_phase; + quad.texcoords[7] = dot; + offset = dot; + FUN_001fd228_002dd8e8(&quad, 0, 0); } phase = next_phase; } @@ -2853,6 +2870,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; @@ -2979,7 +2997,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; @@ -2993,6 +3011,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; @@ -3086,12 +3105,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); diff --git a/src/overlays/shared/gameplay/entities/002fdbd0.c b/src/overlays/shared/gameplay/entities/002fdbd0.c index c0fe19e43..8ad7d5077 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]; @@ -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; @@ -530,7 +529,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); @@ -658,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; } @@ -696,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); diff --git a/src/overlays/shared/gameplay/state/00261968.c b/src/overlays/shared/gameplay/state/00261968.c index ddea60bca..2334aef4d 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; @@ -98,11 +99,11 @@ 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; 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]; @@ -110,25 +111,29 @@ 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); + nearest = origin.f[2]; + current = &first; + FUN_001ff2a8_261b48(current, &(*entry)->points[0], start); + previous = current; + FUN_001ff6d0_261b48(current, current, &direction); 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, &next, &direction); - if (first.f[3] != 0.0f || current->f[3] != 0.0f) { + FUN_001ff6d0_261b48(current, current, &direction); + if (first.f[3] != zero || next.f[3] != zero) { 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; } } } - first.q = ((volatile OvlVec4 *)current)->q; + qcopy(previous, current); i++; offset += 0x10; } while (i < (*entry)->count); @@ -205,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 { @@ -240,20 +242,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; @@ -278,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); @@ -301,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. */ 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; diff --git a/src/overlays/shared/gameplay/vendor/002e3de8.c b/src/overlays/shared/gameplay/vendor/002e3de8.c index 2bed92efd..0924d3860 100644 --- a/src/overlays/shared/gameplay/vendor/002e3de8.c +++ b/src/overlays/shared/gameplay/vendor/002e3de8.c @@ -110,94 +110,138 @@ 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; - int i, j, k; + float *first_source; + float *second_source; + float *first_vectors; + float *second_vectors; + float *second_angles; + float *second_packet; + float *angle_vectors; + int i, k; + 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); + second_packet = (float *)second; *(long long *)(second + 0x80) = 0xff9000000260LL; - *(int *)(second + 0x44) = 0; + *(long long *)(second + 0x70) = 0; *(int *)(second + 0x4c) = 0; - i = 3; + *(int *)(second + 0x44) = 0; + second_source = D_L10_001DA310; + first_source = D_L10_001DA350; + second_vectors = second_packet; + second_angles = second_packet; + first_vectors = (float *)first; + j = 3; do { - *(aligned_vector *)first_vectors = *(aligned_vector *)first_source; - *(aligned_vector *)second_vectors = *(aligned_vector *)second_source; - first_source += 4; + qcopy(first_vectors, first_source); + qcopy(second_angles, second_source); second_source += 4; + second_angles += 4; + first_source += 4; + 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; - i--; - } while (i >= 0); + } while (j >= 0); + + if (D_L10_0015B340 > 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 = ((int *)0x001da250)[i]; float *angles = (float *)(first + 0x58); - float *offsets = (float *)(first + 0x68); float *first_angles = (float *)(second + 0x50); - float *second_angles = (float *)(second + 0x60); float *first_offsets = (float *)(second + 0x58); + float *offsets = (float *)(first + 0x68); + float *second_angles = (float *)(second + 0x60); 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++) { - 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; - float wave; - if (((int *)0x001da2b0)[index] == 0) - wave = FUN_001f9de0(angle * 0.017453292f); - else - wave = FUN_001f9dc8(angle * 0.017453292f); - ((float *)(first + 0x50))[j * 2 + k] = ((float *)0x001da2f0)[j * 2 + k] + wave * 0.125f; + angle_vectors = (float *)(first + 0x50); + 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 offset = j * 8; + int index = i * 8; + int next_vector = j + 1; + 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); + 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); + { + 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(second_packet, matrix, 0); + { + float *second_vectors = second_packet; + float *first_vectors = (float *)first; + j = 3; + do { + first_vectors[1] += 0.1f; + first_vectors += 4; + second_vectors[1] += 0.1f; + second_vectors += 4; + j--; + } while (j >= 0); } - } - 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 = 3; j >= 0; j--) { - ((float *)(first + j * 16))[1] += 0.1f; - ((float *)(second + j * 16))[1] += 0.1f; } } } @@ -254,6 +298,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; @@ -297,7 +342,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) { @@ -324,14 +369,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); } } @@ -373,10 +419,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); @@ -385,12 +435,13 @@ 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; 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"); @@ -414,59 +465,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 *)(acc + 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 * volatile 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; + qcopy(scale, 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; @@ -477,12 +536,12 @@ 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)]; - *(u128 *)old_pos = *(u128 *)scale; + scale = (float *)(moby + 0x30); + 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) { @@ -493,64 +552,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); 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 { 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; } } } 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; diff --git a/src/overlays/shared/gameplay/vendor/003015d0.c b/src/overlays/shared/gameplay/vendor/003015d0.c index 27e915e56..37fdd8822 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; } } { @@ -224,9 +231,9 @@ void FUN_L14_003017f8(char *m) { (float)next * 6.0f)); 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)); + 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--) { set_vector_xyz(delta_a, 0.1f, 0.1f); set_vector_xyz(d + 0x560 + (i << 4) + ((2 - j) << 6), 0.0f, @@ -310,7 +317,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 { @@ -356,6 +363,14 @@ 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)); + +extern char D_L14_001674C0[]; + void FUN_L14_00301fa8(char *m) { char *d = *(char **)(m + 0x78); VendorBeamFrame *frame = &D_L14_001600EC[*(int *)d]; @@ -367,20 +382,27 @@ 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; + float t; + float *uv, *uv_base; + int next; + int branch_next; FUN_001fa050(base, &frame->pad40[0x30]); FUN_001fa2d8(matrix, base); - *(u128 *)(base + 12) = *(u128 *)&frame->origin; - subtract_vector_xyz(direction, (void *)0x1674c0, &frame->origin); + frame = &D_L14_001600EC[*(int *)d]; + qcopy(base + 12, &frame->origin); + subtract_vector_xyz(direction, D_L14_001674C0, &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; @@ -388,17 +410,18 @@ 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); - for (point = 0; point < 31; point++) { + indices = (u8 *)(d + 0x18); + 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)); @@ -408,10 +431,9 @@ void FUN_L14_00301fa8(char *m) { } else { clear_u64_value(start); } - rounded = point + 3; - if (point > -1) rounded = point; - rounded = (rounded >> 2) << 2; - for (i = 0; i < 4; i++) { + next = point + 1; + rounded = (point / 4) * 4; + 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,15 +450,17 @@ 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] + - convert_integer_to_float(point - rounded) * 0.25f; + t = convert_integer_to_float(point - rounded) * 0.25f; + j = i++; + packet[0].uv[j][0] = ((float *)0x001e5fd0)[j * 2] + + t; } draw_geometry_quad(&packet[0], base, 0); } for (strip = 0; strip < 4; strip++) { clear_u64_value(start); - if ((u8)d[0x18 + strip] < 31) { - for (point = 0; point < 3; point++) { + if (indices[strip] < 31) { + for (point = 0; point < 3; point = branch_next) { qcopy(end, start); if (point < 2) { subtract_vector_xyz(side, d + (point << 6) + 0x420 + (strip << 4), @@ -449,10 +473,11 @@ void FUN_L14_00301fa8(char *m) { clear_u64_value(start); } if (point == 0) qcopy(end, start); - rounded = point + 3; - if (point > -1) rounded = point; - rounded = (rounded >> 2) << 2; - for (k = 0; k < 4; k++) { + branch_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)); if (!(k & 1)) subtract_vector_xyz(&packet[0].vertices[k], &packet[0].vertices[k], end); @@ -469,8 +494,12 @@ 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] + - convert_integer_to_float(point - rounded) * 0.25f; + t = convert_integer_to_float(point - rounded) * 0.25f; + j = k++; + t = *uv_base + t; + uv_base += 2; + *uv = t; + uv += 2; } draw_geometry_quad(&packet[0], base, 0); } 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 */ diff --git a/src/overlays/shared/gameplay/vendor/0030e690.c b/src/overlays/shared/gameplay/vendor/0030e690.c index 8cff4de8d..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; @@ -214,7 +212,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 +224,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,53 +236,68 @@ 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); - 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 @@ -430,7 +445,8 @@ 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; + short *next_list; float phase; float *position_base; float *position_y_base; @@ -444,23 +460,24 @@ 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; - char *packet = stack_data + 0x40 + i * 0x90; + long long *packet = (long long *)(stack_data + 0x70); float *source; float *position; float *position_y; int *colors; float span; + 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; @@ -486,6 +503,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; @@ -494,6 +512,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++) { @@ -512,7 +531,8 @@ int FUN_L11_003192c8(char *moby) { } } } - if (*list++ < 0) break; + if (*list < 0) break; + list = next_list; } while (1); } #endif 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 diff --git a/src/overlays/shared/rendering/00250df8.c b/src/overlays/shared/rendering/00250df8.c index 5b3f37d5f..9f65caebc 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,11 @@ 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); + if (choice) choice = 1; + else choice = 2; return choice; } #endif diff --git a/src/overlays/shared/rendering/00269290.c b/src/overlays/shared/rendering/00269290.c index 3ef5856c5..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; @@ -400,9 +404,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) | diff --git a/src/overlays/shared/rendering/002712b8.c b/src/overlays/shared/rendering/002712b8.c index 590135a7d..a93fd6e88 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 + @@ -471,9 +472,10 @@ 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]; - v[2] = r[2]; - *(volatile int *)&v[3] = 0; + 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); *(float *)(q + 0x14) -= *(float *)(q + 0x18); if (*(float *)(p + 0x10) < 2.0f || 1021.0f < *(float *)(p + 0x10) || @@ -2009,19 +2011,19 @@ 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]; h = originalAlpha; h = (unsigned int)h >> 1; - alpha = (float)(h - originalAlpha); + h -= originalAlpha; + alpha = (float)h; 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 +2032,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); diff --git a/src/overlays/shared/rendering/debug/001f36f8.c b/src/overlays/shared/rendering/debug/001f36f8.c index c3bc04a0e..733f61813 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,10 +100,10 @@ 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)[1] = 0; + ((u32 *)packet)[3] = quadwords | 0x50000000; ((u32 *)packet)[2] = 0; + ((u32 *)packet)[1] = 0; *glyph_tag = (s64)(glyph_count | 0x8000) | 0x4400000000000000ULL; } #endif /* NON_MATCHING */ @@ -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 { diff --git a/src/overlays/shared/rendering/effects/00268900.c b/src/overlays/shared/rendering/effects/00268900.c index f1c749686..5c146ad6a 100644 --- a/src/overlays/shared/rendering/effects/00268900.c +++ b/src/overlays/shared/rendering/effects/00268900.c @@ -98,62 +98,62 @@ void register_part_types(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; 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; diff --git a/src/overlays/shared/rendering/view/0025fcb8.c b/src/overlays/shared/rendering/view/0025fcb8.c index 0ce936b4d..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; @@ -504,8 +505,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 +522,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 = b_large * 50, value_medium = b_medium * 20, value_small = b_small * 5; + 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; @@ -556,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]; @@ -586,17 +592,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 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; diff --git a/src/overlays/shared/ui/help/00203b18.c b/src/overlays/shared/ui/help/00203b18.c index ec3bdc2d7..d5ab2d13d 100644 --- a/src/overlays/shared/ui/help/00203b18.c +++ b/src/overlays/shared/ui/help/00203b18.c @@ -446,13 +446,13 @@ 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++, 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; @@ -998,8 +998,10 @@ void FUN_L00_00206e00(void) { struct Hero *g; u8 *hero_base; s32 input; + u32 state; s32 level; s32 i, j, length, position; + u8 *end; u8 *sequence; u8 *history; volatile s32 *history_count; @@ -1024,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; @@ -1034,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) { @@ -1045,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); @@ -1059,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; @@ -1075,7 +1083,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; @@ -2798,7 +2808,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 +2817,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 +2878,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. */ diff --git a/src/overlays/shared/ui/help/0020c758.c b/src/overlays/shared/ui/help/0020c758.c index 4a728be1f..869eb7fa7 100644 --- a/src/overlays/shared/ui/help/0020c758.c +++ b/src/overlays/shared/ui/help/0020c758.c @@ -691,54 +691,56 @@ 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_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]); + *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]]; } } else { + slot = (u8 **)&hero.unkD00 + i; next = i + 1; 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]; - if (hero_ptr->unkD08[0] && !hero_ptr->unkD14) { + 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) { FUN_00213ed8_20dd20((f32 *)(obj + 8), 1.0f, frame_scale * tenth); } change = 0; - if (!same && hero_ptr->unkA9C) { - if (FUN_L00_002050b8_20dd20(obj[0x23]) != FUN_L00_002050b8_20dd20(((u8 *)hero_ptr->moby)[0x53])) + if (same && hero.unkA9C) { + 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; { @@ -752,7 +754,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,10 +773,15 @@ 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[0x23] = FUN_L00_0020d5b8_20dd20((u8 *)hero.moby, ((u8 *)hero.moby)[0x53]); obj[0x21] = 0; obj[0x33] = 1; *(s32 *)(obj + 0x24) = 0; @@ -786,26 +795,26 @@ 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); + FUN_L00_0024f190_20dd20((u8 *)hero.moby, obj); } goto next_slot; ordinary_update: @@ -813,8 +822,8 @@ void FUN_L00_0020dd20(void) { if (*(s16 *)(obj + 0x30) == 0) { j = 0; do { - if (same || j == 1) - obj[0x22 + j] = FUN_L00_0020d5b8_20dd20((u8 *)hero_ptr->moby, ((u8 *)hero_ptr->moby)[0x52 + j]); + if (!same || j == 1) + obj[0x22 + j] = FUN_L00_0020d5b8_20dd20((u8 *)hero.moby, ((u8 *)hero.moby)[0x52 + j]); j++; } while (j < 2); } @@ -827,31 +836,30 @@ void FUN_L00_0020dd20(void) { *(u16 *)(obj + 0x30) = 0; } } 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); + if (!same) + obj[0x20] = ((u8 *)hero.moby)[0x50]; + obj[0x21] = ((u8 *)hero.moby)[0x51]; + *(f32 *)(obj + 0x24) = *(f32 *)((u8 *)hero.moby + 0x54); } { u8 *symbol = obj + 0x22; 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); + FUN_L00_0024f190_20dd20((u8 *)hero.moby, obj); } } next_slot: @@ -1012,32 +1020,34 @@ 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) - 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.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) { - if (hero.unkD14 == 2) - FUN_00213ed8_e728((f32 *)(*slot + 8), 0.0f, frame_scale * 0.25f); - else - FUN_00213ed8_e728((f32 *)(*slot + 8), 0.0f, frame_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; @@ -1056,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); @@ -1332,11 +1339,11 @@ 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; + s64 negative_one = -1; u8 *record; - f32 *score_ptr; + f32 * volatile score_ptr; void * volatile output; { @@ -1348,13 +1355,20 @@ 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; } - 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; @@ -1379,12 +1393,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 -= ((a < 0 ? a + 15 : a) >> 4) * 16; - negative_one = -1; + 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)); } @@ -1409,7 +1423,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 %= 16; record = (hero.pad_12EF + 1) + a * 0x30; chosen++; for (j = 0; j < 3; j++) @@ -1594,11 +1608,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; } } diff --git a/src/overlays/shared/ui/help/00226f10.c b/src/overlays/shared/ui/help/00226f10.c index 8610bf1ef..4210b0f8e 100644 --- a/src/overlays/shared/ui/help/00226f10.c +++ b/src/overlays/shared/ui/help/00226f10.c @@ -1362,18 +1362,18 @@ void air_accel(float amount) { } else if (factor > 3.0f) { factor = 3.0f; } - if (factor < min_factor) - factor = min_factor; + if (!(factor < min_factor)) + min_factor = factor; velocity = &hero.motion.velocity; - amount *= factor; 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); 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; diff --git a/src/overlays/shared/ui/help/00237488.c b/src/overlays/shared/ui/help/00237488.c index 6fbaa101a..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) @@ -1358,7 +1359,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 +1368,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; 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; + 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); + 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 +1416,13 @@ 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, &path->points[selected]); + qcopy(&point, position); point.z += 2.0f; position[2] = find_ground_height(0.5f, &point, 0); clear_u64_value(direction); 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; diff --git a/src/overlays/shared/ui/text/002377b8.c b/src/overlays/shared/ui/text/002377b8.c index 9362a2841..689d3278b 100644 --- a/src/overlays/shared/ui/text/002377b8.c +++ b/src/overlays/shared/ui/text/002377b8.c @@ -420,19 +420,18 @@ 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 + (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); - entry = D_L00_0015FAC0_c[D_L00_0015F72C]; - if (((Ent *)(normal_offset + (char *)entry))->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); } @@ -443,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) { @@ -468,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; @@ -479,7 +480,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; @@ -491,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; } } } @@ -527,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 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; } diff --git a/src/overlays/shared/ui/text/00262ae8.c b/src/overlays/shared/ui/text/00262ae8.c index fb51e5a35..2866a945c 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 @@ -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 * 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 */