From 10222a62c3669629d56ce95db7f345807d7a58c9 Mon Sep 17 00:00:00 2001 From: Hexalotl <15166449+Hexalotl@users.noreply.github.com> Date: Sun, 21 Jan 2024 20:24:10 -0800 Subject: [PATCH] Implement and link ac_t_keitai --- config/rel_slices.yml | 4 + include/ac_t_keitai.h | 21 ++++- include/m_actor.h | 2 +- src/ac_t_keitai.c | 181 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 src/ac_t_keitai.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 8837575a..78e98b50 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -496,6 +496,10 @@ ac_t_hat2.c: ac_t_hat3.c: .text: [0x804A8E98, 0x804A8FEC] .data: [0x8068ED70, 0x8068EDB0] +ac_t_keitai.c: + .text: [0x804A8FEC, 0x804A9348] + .data: [0x8068EDB0, 0x8068EE58] + .rodata: [0x80645ED0, 0x80645EE0] ac_t_npc_sao.c: .text: [0x804A9348, 0x804A95F4] .rodata: [0x80645EE0, 0x80645EF8] diff --git a/include/ac_t_keitai.h b/include/ac_t_keitai.h index f48036fa..e4d0af20 100644 --- a/include/ac_t_keitai.h +++ b/include/ac_t_keitai.h @@ -2,7 +2,8 @@ #define AC_T_KEITAI_H #include "types.h" -#include "m_actor.h" +#include "ac_tools.h" +#include "c_keyframe.h" #ifdef __cplusplus extern "C" { @@ -10,6 +11,24 @@ extern "C" { extern ACTOR_PROFILE T_Keitai_Profile; +typedef void (*KEITAI_PROC)(ACTOR*); + +typedef struct t_keitai_s{ + TOOLS_ACTOR tools_class; + KEITAI_PROC action_proc; + int action; + cKF_SkeletonInfo_R_c keyframe; + s_xyz work[4]; + s_xyz morph[4]; + char* bank_ram_start; +} KEITAI_ACTOR; + +typedef struct t_keitai_action_anim_s { + cKF_Animation_R_c* animation; + f32 start_frame; + f32 end_frame; +} KEITAI_ACTION_ANIM; + #ifdef __cplusplus } #endif diff --git a/include/m_actor.h b/include/m_actor.h index afea886d..5aa587ac 100644 --- a/include/m_actor.h +++ b/include/m_actor.h @@ -84,7 +84,7 @@ typedef enum bank_id { ACTOR_OBJ_BANK_42, ACTOR_OBJ_BANK_POSTHOUSE, ACTOR_OBJ_BANK_EF_POLICE, - ACTOR_OBJ_BANK_45, + ACTOR_OBJ_BANK_KEITAI, ACTOR_OBJ_BANK_46, ACTOR_OBJ_BANK_47, ACTOR_OBJ_BANK_48, diff --git a/src/ac_t_keitai.c b/src/ac_t_keitai.c new file mode 100644 index 00000000..ed084420 --- /dev/null +++ b/src/ac_t_keitai.c @@ -0,0 +1,181 @@ +#include "ac_t_keitai.h" + +#include "m_name_table.h" +#include "sys_matrix.h" +#include "m_lib.h" +#include "m_rcp.h" +#include "m_common_data.h" + +enum { + aTKT_ACTION_WAIT, + aTKT_ACTION_TAKEOUT, + aTKT_ACTION_PUTAWAY, + aTKT_ACTION_DESTRUCT, + aTKT_ACTION_TAKEOUT2, + aTKT_ACTION_DELETED // Placeholder. Unknown use. +}; + +extern cKF_Animation_R_c cKF_ba_r_tol_keitai_1_keitai_on1; +extern cKF_Animation_R_c cKF_ba_r_tol_keitai_1_keitai_off1; +extern cKF_Skeleton_R_c cKF_bs_r_tol_keitai_1; + +KEITAI_ACTION_ANIM aTKT_anm_dt[6] = { + { &cKF_ba_r_tol_keitai_1_keitai_on1, 1.0f, 1.0f }, + { &cKF_ba_r_tol_keitai_1_keitai_on1, 1.0f, 68.0f }, + { &cKF_ba_r_tol_keitai_1_keitai_off1, 1.0f, 61.0f}, + { &cKF_ba_r_tol_keitai_1_keitai_off1, 1.0f, 61.0f}, + { &cKF_ba_r_tol_keitai_1_keitai_on1, 1.0f, 68.0f}, + { NULL, 0.0f, 0.0f} +}; + +static void aTKT_actor_ct(ACTOR* actor, GAME* game); +static void aTKT_actor_move(ACTOR* actor, GAME* game); +static void aTKT_actor_draw(ACTOR* actor, GAME* game); + +ACTOR_PROFILE T_Keitai_Profile = { + mAc_PROFILE_T_KEITAI, + ACTOR_PART_BG, + ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED, + EMPTY_NO, + ACTOR_OBJ_BANK_KEITAI, + sizeof(KEITAI_ACTOR), + &aTKT_actor_ct, + NONE_ACTOR_PROC, + &aTKT_actor_move, + &aTKT_actor_draw, + NULL +}; + +static void aTKT_setupAction(KEITAI_ACTOR* actor, int action); + +static void aTKT_actor_ct(ACTOR* actor, GAME* game) { + KEITAI_ACTOR* keitai = (KEITAI_ACTOR*)actor; + cKF_SkeletonInfo_R_ct(&keitai->keyframe, &cKF_bs_r_tol_keitai_1, NULL, keitai->work, keitai->morph); + keitai->bank_ram_start = ((GAME_PLAY*)game)->object_exchange.banks[actor->data_bank_id].ram_start; + aTKT_setupAction(keitai, aTKT_ACTION_TAKEOUT); +} + +static void aTKT_calc_scale(ACTOR* actor, int idx) { + static f32 start_scale[2] = { 0.0f, 1.0f }; + static f32 end_scale[2] = { 1.0f, 0.0f }; + static f32 start_chno[2] = { 10.0f, 33.0f }; + static f32 end_chno[2] = { 20.0f, 41.0f }; + + f32 current_frame; + f32 starting_chno; + f32 ending_chno; + f32 starting_scale; + f32 ending_scale; + f32 scale; + KEITAI_ACTOR* keitai; + + keitai = (KEITAI_ACTOR*)actor; + current_frame = keitai->keyframe.frame_control.current_frame; + starting_chno = start_chno[idx]; + ending_chno = end_chno[idx]; + starting_scale = start_scale[idx]; + ending_scale = end_scale[idx]; + + if (current_frame < starting_chno) { + scale = starting_scale; + } else if (current_frame > ending_chno) { + scale = ending_scale; + } else { + scale = starting_scale + ((ending_scale - starting_scale) * ((current_frame - starting_chno) / (ending_chno - starting_chno))); + } + + actor->scale.x = scale; + actor->scale.y = scale; + actor->scale.z = scale; +} + +static void aTKT_takeout(ACTOR* actor) { + aTKT_calc_scale(actor, 0); +} + +static void aTKT_putaway(ACTOR* actor) { + aTKT_calc_scale(actor, 1); +} + +static void aTKT_destruct(ACTOR* actor) { + Actor_delete(actor); +} + +static void aTKT_s_takeout(ACTOR* actor) { + KEITAI_ACTOR* keitai = (KEITAI_ACTOR*)actor; + + actor->scale.x = 1.0f; + actor->scale.y = 1.0f; + actor->scale.z = 1.0f; + + keitai->keyframe.frame_control.current_frame = keitai->keyframe.frame_control.end_frame; +} + +static void aTKT_setupAction(KEITAI_ACTOR* keitai, int action) { + static KEITAI_PROC action_process[] = {(KEITAI_PROC)none_proc1, aTKT_takeout, aTKT_putaway, aTKT_destruct, aTKT_s_takeout, NULL}; + + KEITAI_ACTION_ANIM *action_anim; + f32 starting_frame; + f32 ending_frame; + + keitai->action_proc = action_process[action]; + keitai->action = action; + keitai->tools_class.work0 = action; + + action_anim = &aTKT_anm_dt[action]; + starting_frame = action_anim->start_frame; + + cKF_SkeletonInfo_R_init( + &keitai->keyframe, keitai->keyframe.skeleton, + action_anim->animation, starting_frame, action_anim->end_frame, starting_frame, + 0.5f, 0.0f, cKF_FRAMECONTROL_STOP, NULL + ); +} + +static void aTKT_actor_move(ACTOR* actor, GAME* game) { + KEITAI_ACTOR* keitai = (KEITAI_ACTOR*)actor; + int action = keitai->tools_class.work0; + if (action != keitai->action) { + aTKT_setupAction(keitai, action); + } + + cKF_SkeletonInfo_R_play(&keitai->keyframe); + keitai->action_proc(actor); +} + +static void aTKT_actor_draw(ACTOR* actor, GAME* game) { + cKF_SkeletonInfo_R_c* keyf; + GRAPH* graph; + Mtx* mtx; + Gfx* gfx; + KEITAI_ACTOR* keitai; + + keitai = (KEITAI_ACTOR*)actor; + keyf = &keitai->keyframe; + graph = game->graph; + mtx = GRAPH_ALLOC_TYPE(graph, Mtx, keyf->skeleton->num_shown_joints); + + if (mtx != NULL) { + if (keitai->tools_class.init_matrix == TRUE) { + Matrix_put(&keitai->tools_class.matrix_work); + Matrix_Position_Zero(&actor->world.position); + keitai->tools_class.init_matrix = FALSE; + } + else { + Matrix_translate(actor->world.position.x, actor->world.position.y, actor->world.position.z, FALSE); + Matrix_scale(0.01f, 0.01f, 0.01f, TRUE); + } + + _texture_z_light_fog_prim_npc(graph); + + OPEN_DISP(graph); + + gfx = NOW_POLY_OPA_DISP; + Matrix_scale(actor->scale.x, actor->scale.y, actor->scale.z, TRUE); + gSPMatrix(gfx++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + SET_POLY_OPA_DISP(gfx); + + cKF_Si3_draw_R_SV(game, keyf, mtx, NULL, NULL, NULL); + CLOSE_DISP(graph); + } +}