From 272a0546e0f7ac2a3a20ed888ac6fe006e5f0ce8 Mon Sep 17 00:00:00 2001 From: Hexalotl <15166449+Hexalotl@users.noreply.github.com> Date: Sat, 27 Jan 2024 20:04:52 -0800 Subject: [PATCH] Implement and link ac_t_umbrella --- config/rel_slices.yml | 4 + include/ac_t_umbrella.h | 27 ++- include/m_actor.h | 2 +- include/m_common_data.h | 10 ++ src/ac_t_umbrella.c | 386 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 427 insertions(+), 2 deletions(-) create mode 100644 src/ac_t_umbrella.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 2409a444..ad671b5d 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -522,6 +522,10 @@ ac_t_tama.c: .text: [0x804A9B00, 0x804A9CC4] .data: [0x8068EF78, 0x8068EFE0] .rodata: [0x80645F00, 0x80645F10] +ac_t_umbrella.c: + .text: [0x804A9F24, 0x804AA4C8] + .data: [0x8068F040, 0x8068F310] + .rodata: [0x80645F18, 0x80645F30] ac_t_utiwa.c: .text: [0x804AA4C8, 0x804AA72C] .data: [0x8068F310, 0x8068F370] diff --git a/include/ac_t_umbrella.h b/include/ac_t_umbrella.h index 9a86be6d..f15f38b6 100644 --- a/include/ac_t_umbrella.h +++ b/include/ac_t_umbrella.h @@ -2,7 +2,8 @@ #define AC_T_UMBRELLA_H #include "types.h" -#include "m_actor.h" +#include "ac_tools.h" +#include "c_keyframe.h" #ifdef __cplusplus extern "C" { @@ -10,6 +11,30 @@ extern "C" { extern ACTOR_PROFILE T_Umbrella_Profile; +typedef void (*UMBRELLA_PROC)(ACTOR*); + +// Size == 0x1F4 (500) +typedef struct t_umbrella_s { + TOOLS_ACTOR tools_class; + UMBRELLA_PROC action_proc; + int action; + f32 frame; + xyz_t scale_e; + xyz_t scale_kasa; + BOOL opened_fully; +} UMBRELLA_ACTOR; + +typedef struct t_umbrella_data_table_s { + int table_length; + f32* sect_table; + f32* scale_table; +} UMBRELLA_DATA_TABLE; + +typedef struct t_umbrella_model_s { + Gfx* model_e; + Gfx* model_kasa; +} UMBRELLA_MODEL; + #ifdef __cplusplus } #endif diff --git a/include/m_actor.h b/include/m_actor.h index 9fbbabaf..9106d592 100644 --- a/include/m_actor.h +++ b/include/m_actor.h @@ -67,7 +67,7 @@ typedef enum bank_id { ACTOR_OBJ_BANK_25, ACTOR_OBJ_BANK_26, ACTOR_OBJ_BANK_27, - ACTOR_OBJ_BANK_28, + ACTOR_OBJ_BANK_UMBRELLA, ACTOR_OBJ_BANK_29, ACTOR_OBJ_BANK_30, ACTOR_OBJ_BANK_31, diff --git a/include/m_common_data.h b/include/m_common_data.h index 9ef3b760..ba7edd38 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -329,6 +329,16 @@ extern common_data_t common_data; /* Useful for returning fg item data as a pointer to mActor_name_t */ #define Save_GetFG() Save_Get(fg[0][0].items[0]) +#define Player_Palette_Get(idx) (Common_Get(now_private->my_org[idx].palette)) +#define Player_Design_Get(idx) (Common_GetPointer(now_private->my_org[idx].design)) + +#define Able_Sisters_Palette_Get(idx) (Save_Get(needlework.original_design[idx].palette)) +#define Able_Sisters_Design_Get(idx) (Save_GetPointer(needlework.original_design[idx].design)) +#define Able_Sisters_Cloth_Palette_Get(idx) (Able_Sisters_Palette_Get(idx)) +#define Able_Sisters_Cloth_Design_Get(idx) (Able_Sisters_Design_Get(idx)) +#define Able_Sisters_Umbrella_Palette_Get(idx) (Able_Sisters_Palette_Get(idx + mNW_CLOTH_DESIGN_NUM)) +#define Able_Sisters_Umbrella_Design_Get(idx) (Able_Sisters_Design_Get(idx + mNW_CLOTH_DESIGN_NUM)) + extern void common_data_reinit(); extern void common_data_init(); extern void common_data_clear(); diff --git a/src/ac_t_umbrella.c b/src/ac_t_umbrella.c new file mode 100644 index 00000000..6f520a89 --- /dev/null +++ b/src/ac_t_umbrella.c @@ -0,0 +1,386 @@ +#include "ac_t_umbrella.h" + +#include "m_name_table.h" +#include "sys_matrix.h" +#include "m_lib.h" +#include "m_rcp.h" +#include "m_common_data.h" + +enum { + aTUMB_ACTION_TAKEOUT_BEFORE, + aTUMB_ACTION_OPENING, // Placeholder. Unknown use. + aTUMB_ACTION_DELETED2, // Placeholder. Unknown use. + aTUMB_ACTION_DESTRUCT, + aTUMB_ACTION_DELETED3, // Placeholder. Unknown use. + aTUMB_ACTION_DELETED4 // Placeholder. Unknown use. +}; + +static void aTUMB_actor_ct(ACTOR* actor, GAME* game); +static void aTUMB_actor_move(ACTOR* actor, GAME* game); +static void aTUMB_actor_draw(ACTOR* actor, GAME* game); + +ACTOR_PROFILE T_Umbrella_Profile = { + mAc_PROFILE_T_UMBRELLA, + ACTOR_PART_BG, + ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED, + EMPTY_NO, + ACTOR_OBJ_BANK_UMBRELLA, + sizeof(UMBRELLA_ACTOR), + &aTUMB_actor_ct, + NONE_ACTOR_PROC, + &aTUMB_actor_move, + &aTUMB_actor_draw, + NULL +}; + +extern Gfx e_umb01_model[]; +extern Gfx kasa_umb01_model[]; +extern Gfx e_umb02_model[]; +extern Gfx kasa_umb02_model[]; +extern Gfx e_umb03_model[]; +extern Gfx kasa_umb03_model[]; +extern Gfx e_umb04_model[]; +extern Gfx kasa_umb04_model[]; +extern Gfx e_umb05_model[]; +extern Gfx kasa_umb05_model[]; +extern Gfx e_umb06_model[]; +extern Gfx kasa_umb06_model[]; +extern Gfx e_umb07_model[]; +extern Gfx kasa_umb07_model[]; +extern Gfx e_umb08_model[]; +extern Gfx kasa_umb08_model[]; +extern Gfx e_umb09_model[]; +extern Gfx kasa_umb09_model[]; +extern Gfx e_umb10_model[]; +extern Gfx kasa_umb10_model[]; +extern Gfx e_umb11_model[]; +extern Gfx kasa_umb11_model[]; +extern Gfx e_umb12_model[]; +extern Gfx kasa_umb12_model[]; +extern Gfx e_umb13_model[]; +extern Gfx kasa_umb13_model[]; +extern Gfx e_umb14_model[]; +extern Gfx kasa_umb14_model[]; +extern Gfx e_umb15_model[]; +extern Gfx kasa_umb15_model[]; +extern Gfx e_umb16_model[]; +extern Gfx kasa_umb16_model[]; +extern Gfx e_umb17_model[]; +extern Gfx kasa_umb17_model[]; +extern Gfx e_umb18_model[]; +extern Gfx kasa_umb18_model[]; +extern Gfx e_umb19_model[]; +extern Gfx kasa_umb19_model[]; +extern Gfx e_umb20_model[]; +extern Gfx kasa_umb20_model[]; +extern Gfx e_umb21_model[]; +extern Gfx kasa_umb21_model[]; +extern Gfx e_umb22_model[]; +extern Gfx kasa_umb22_model[]; +extern Gfx e_umb23_model[]; +extern Gfx kasa_umb23_model[]; +extern Gfx e_umb24_model[]; +extern Gfx kasa_umb24_model[]; +extern Gfx e_umb25_model[]; +extern Gfx kasa_umb25_model[]; +extern Gfx e_umb26_model[]; +extern Gfx kasa_umb26_model[]; +extern Gfx e_umb27_model[]; +extern Gfx kasa_umb27_model[]; +extern Gfx e_umb28_model[]; +extern Gfx kasa_umb28_model[]; +extern Gfx e_umb29_model[]; +extern Gfx kasa_umb29_model[]; +extern Gfx e_umb30_model[]; +extern Gfx kasa_umb30_model[]; +extern Gfx e_umb31_model[]; +extern Gfx kasa_umb31_model[]; +extern Gfx e_umb32_model[]; +extern Gfx kasa_umb32_model[]; +extern Gfx e_umb_w_model[]; +extern Gfx kasa_umb_w_model[]; + +static void aTUMB_setupAction(UMBRELLA_ACTOR* umbrella, int action); + +static void aTUMB_actor_ct(ACTOR* actor, GAME* game) { + UMBRELLA_ACTOR* umbrella = (UMBRELLA_ACTOR*)actor; + aTUMB_setupAction(umbrella, umbrella->tools_class.work0); +} + +static void aTUMB_OngenTrgStart_sub(ACTOR* actor, u16 id) { + sAdo_OngenTrgStart(id, &actor->world.position); +} + +static void aTUMB_OngenTrgStart(ACTOR* actor, int idx) { + switch(idx) { + case 1: + aTUMB_OngenTrgStart_sub(actor, 0x139); + break; + case 2: + aTUMB_OngenTrgStart_sub(actor, 0x10E); + break; + } +} + +static void aTUMB_calc_model_scale_sub(xyz_t* scale, UMBRELLA_ACTOR* umbrella, int idx) { + static f32 e_open_sect_table[6] = { 0.0f, 7.0f, 11.0f, 18.0f, 22.0f, 26.0f }; + static f32 e_open_scale_table[12] = { + 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f,0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f + }; + + static f32 kasa_open_sect_table[4] = { 0.0f, 15.0f, 22.0f, 26.0f }; + static f32 kasa_open_scale_table[8] = { + 3.0f, 0.15f, 3.0f, 0.15f, 1.0f, 1.0f, 0.9, 1.0f + }; + + static UMBRELLA_DATA_TABLE open_data_table[2] = { + { 6, e_open_sect_table, e_open_scale_table }, + { 4, kasa_open_sect_table, kasa_open_scale_table } + }; + + static f32 e_close_sect_table[6] = { 0.0f, 4.0f, 12.0f, 15.0f, 22.0f, 30.0f }; + static f32 e_close_scale_table[12] = { + 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f + }; + + static f32 kasa_close_sect_table[4] = { 0.0f, 4.0f, 12.0f, 30.0f }; + static f32 kasa_close_scale_table[8] = { + 1.0f, 1.0f, 1.2f, 1.0f, 3.0f, 0.15f, 3.0f, 0.15f + }; + + static UMBRELLA_DATA_TABLE close_data_table[2] = { + { 6, e_close_sect_table, e_close_scale_table }, + { 4, kasa_close_sect_table, kasa_close_scale_table } + }; + + static UMBRELLA_DATA_TABLE* data_table[6] = { + open_data_table, open_data_table, close_data_table, close_data_table, open_data_table, NULL + }; + + f32 modifier_percentage; + f32 base_scale_x; + f32 base_scale_y; + f32 max_scale_y; + f32 max_scale_x; + + int scale_idx_offset; + f32* scale_table; + int sector_idx; + int frame; + int corresponding_sector; + UMBRELLA_DATA_TABLE *table; + f32* sect_table; + + corresponding_sector = 0; + table = data_table[umbrella->action] + idx; + sector_idx = table->table_length - 1; + frame = (int)umbrella->frame; + sect_table = table->sect_table + 1; + + for(sector_idx; sector_idx > 0; sector_idx--) { + if (frame <= (int)sect_table[0]) { + frame -= (int)sect_table[-1]; + break; + } + + sect_table++; + corresponding_sector++; + } + + scale_idx_offset = corresponding_sector * 2; + scale_table = table->scale_table; + base_scale_x = scale_table[scale_idx_offset]; + modifier_percentage = (f32) frame / (sect_table[0] - sect_table[-1]); + base_scale_y = scale_table[scale_idx_offset + 1]; + max_scale_y = scale_table[scale_idx_offset + 3]; + max_scale_x = scale_table[scale_idx_offset + 2]; + + scale->x = base_scale_x + modifier_percentage * (max_scale_x - base_scale_x); + scale->y = base_scale_y + modifier_percentage * (max_scale_y - base_scale_y); + scale->z = scale->y; +} + +static void aTUMB_calc_model_scale(UMBRELLA_ACTOR* umbrella) { + aTUMB_calc_model_scale_sub(&umbrella->scale_e, umbrella, 0); + aTUMB_calc_model_scale_sub(&umbrella->scale_kasa, umbrella, 1); +} + +static void aTUMB_anime_proc(UMBRELLA_ACTOR* umbrella) { + static f32 max_anm[6] = { 0.0f, 26.0f, 30.0f, 30.0f, 26.0f, 0.0f }; + + f32 max_anm_for_action; + f32 next_frame; + int action; + + action = umbrella->action; + max_anm_for_action = max_anm[action]; + next_frame = umbrella->frame; + next_frame += 0.5f; + + if (next_frame >= max_anm_for_action) { + next_frame = max_anm_for_action; + } + + if (action == aTUMB_ACTION_OPENING) { + umbrella->opened_fully = next_frame == max_anm_for_action; + } + + umbrella->frame = next_frame; + aTUMB_calc_model_scale(umbrella); +} + +static void aTUMB_takeout_before(ACTOR* actor) { + UMBRELLA_ACTOR* umbrella = (UMBRELLA_ACTOR*)actor; + if (umbrella->tools_class.unk1BC == TRUE) { + aTUMB_setupAction(umbrella, aTUMB_ACTION_OPENING); + } +} + +static void aTUMB_destruct(ACTOR* actor) { + Actor_delete(actor); +} + +void aTUMB_setupAction(UMBRELLA_ACTOR* umbrella, int action) { + static UMBRELLA_PROC process[] = { + aTUMB_takeout_before, (UMBRELLA_PROC)none_proc1, (UMBRELLA_PROC)none_proc1, aTUMB_destruct, (UMBRELLA_PROC)none_proc1, NULL + }; + + f32 frame; + + umbrella->action_proc = process[action]; + umbrella->action = action; + umbrella->tools_class.work0 = action; + + aTUMB_OngenTrgStart(&umbrella->tools_class.actor_class, action); + + if (action == aTUMB_ACTION_DELETED3) { + umbrella->opened_fully = TRUE; + frame = 26.0f; + } else { + frame = 0.0f; + } + + umbrella->frame = frame; +} + +static void aTUMB_actor_move(ACTOR* actor, GAME* game) { + UMBRELLA_ACTOR* umbrella; + int action; + + umbrella = (UMBRELLA_ACTOR*)actor; + action = umbrella->tools_class.work0; + + if (action != umbrella->action) { + aTUMB_setupAction(umbrella, action); + } + + if (umbrella->action != aTUMB_ACTION_DESTRUCT) { + aTUMB_anime_proc(umbrella); + } + + umbrella->action_proc(actor); +} + +static void aTUMB_actor_draw(ACTOR* actor, GAME* game) { + static UMBRELLA_MODEL draw_dt[40] = { + { e_umb01_model, kasa_umb01_model }, + { e_umb02_model, kasa_umb02_model }, + { e_umb03_model, kasa_umb03_model }, + { e_umb04_model, kasa_umb04_model }, + { e_umb05_model, kasa_umb05_model }, + { e_umb06_model, kasa_umb06_model }, + { e_umb07_model, kasa_umb07_model }, + { e_umb08_model, kasa_umb08_model }, + { e_umb09_model, kasa_umb09_model }, + { e_umb10_model, kasa_umb10_model }, + { e_umb11_model, kasa_umb11_model }, + { e_umb12_model, kasa_umb12_model }, + { e_umb13_model, kasa_umb13_model }, + { e_umb14_model, kasa_umb14_model }, + { e_umb15_model, kasa_umb15_model }, + { e_umb16_model, kasa_umb16_model }, + { e_umb17_model, kasa_umb17_model }, + { e_umb18_model, kasa_umb18_model }, + { e_umb19_model, kasa_umb19_model }, + { e_umb20_model, kasa_umb20_model }, + { e_umb21_model, kasa_umb21_model }, + { e_umb22_model, kasa_umb22_model }, + { e_umb23_model, kasa_umb23_model }, + { e_umb24_model, kasa_umb24_model }, + { e_umb25_model, kasa_umb25_model }, + { e_umb26_model, kasa_umb26_model }, + { e_umb27_model, kasa_umb27_model }, + { e_umb28_model, kasa_umb28_model }, + { e_umb29_model, kasa_umb29_model }, + { e_umb30_model, kasa_umb30_model }, + { e_umb31_model, kasa_umb31_model }, + { e_umb32_model, kasa_umb32_model }, + { e_umb_w_model, kasa_umb_w_model }, + { e_umb_w_model, kasa_umb_w_model }, + { e_umb_w_model, kasa_umb_w_model }, + { e_umb_w_model, kasa_umb_w_model }, + { e_umb_w_model, kasa_umb_w_model }, + { e_umb_w_model, kasa_umb_w_model }, + { e_umb_w_model, kasa_umb_w_model }, + { e_umb_w_model, kasa_umb_w_model } + }; + + UMBRELLA_ACTOR* umbrella; + GRAPH* graph; + int umbrella_design_index; + int umbrella_name; + int tool_name; + UMBRELLA_MODEL* umbrella_model; + ACTOR* parent; + Gfx* gfx; + + umbrella = (UMBRELLA_ACTOR*)actor; + parent = actor->parent_actor; + tool_name = umbrella->tools_class.tool_name; + graph = game->graph; + umbrella_model = &draw_dt[tool_name]; + + if (parent->drawn == FALSE || umbrella->tools_class.init_matrix == FALSE) { + return; + } + + Matrix_put(&umbrella->tools_class.matrix_work); + Matrix_Position_Zero(&umbrella->tools_class.actor_class.world.position); + + umbrella->tools_class.init_matrix = FALSE; + umbrella->tools_class.unk1BC = TRUE; + + _texture_z_light_fog_prim_npc(graph); + + OPEN_DISP(graph); + gfx = NOW_POLY_OPA_DISP; + + Matrix_rotateXYZ(0, -0x4000, 0, TRUE); + Matrix_scale(umbrella->scale_e.x, umbrella->scale_e.y, umbrella->scale_e.z, TRUE); + + gSPMatrix(gfx++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, umbrella_model->model_e); + + Matrix_translate(4500.0f, 0.0f, 0.0f, TRUE); + Matrix_scale(umbrella->scale_kasa.x, umbrella->scale_kasa.y, umbrella->scale_kasa.z, TRUE); + + gSPMatrix(gfx++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (tool_name >= TOOL_UMBRELLA32) { + umbrella_name = tool_name - TOOL_UMBRELLA32; + if (parent->part == ACTOR_PART_PLAYER) { + umbrella_name = (umbrella_name & 7); + gSPSegment(gfx++, G_MWO_SEGMENT_8, mNW_PaletteIdx2Palette(Player_Palette_Get(umbrella_name))); + gSPSegment(gfx++, G_MWO_SEGMENT_9, Player_Design_Get(umbrella_name)); + } + else { + umbrella_name = umbrella_name & 3; + gSPSegment(gfx++, G_MWO_SEGMENT_8, mNW_PaletteIdx2Palette(Able_Sisters_Umbrella_Palette_Get(umbrella_name))); + gSPSegment(gfx++, G_MWO_SEGMENT_9, Able_Sisters_Umbrella_Design_Get(umbrella_name)); + } + } + + gSPDisplayList(gfx++, umbrella_model->model_kasa); + SET_POLY_OPA_DISP(gfx); + CLOSE_DISP(graph); +}