diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 18d1380c..b1491a39 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -577,6 +577,10 @@ m_editor_ovl.c: .rodata: [0x8064B300, 0x8064B368] .data: [0x806CC9D8, 0x806CD068] .bss: [0x8133F5C8, 0x8133F600] +m_haniwaPortrait_ovl.c: + .text: [0x805DFA00, 0x805DFE48] + .rodata: [0x8064B418, 0x8064B448] + .bss: [0x8133F980, 0x8133FAA0] m_map_ovl.c: .text: [0x805E5EFC, 0x805E7A54] .rodata: [0x8064B628, 0x8064B6B0] diff --git a/include/m_haniwaPortrait_ovl.h b/include/m_haniwaPortrait_ovl.h new file mode 100644 index 00000000..bba8dd3d --- /dev/null +++ b/include/m_haniwaPortrait_ovl.h @@ -0,0 +1,29 @@ +#ifndef M_HANIWAPORTRAIT_OVL_H +#define M_HANIWAPORTRAIT_OVL_H + +#include "types.h" +#include "m_haniwaPortrait_ovl_h.h" +#include "m_submenu_ovl.h" +#include "c_keyframe.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*mHP_SET_HANIWAPORTRAIT_PROC)(Submenu*, mSM_MenuInfo_c*, GRAPH*, GAME*, f32, f32); +typedef void (*mHP_HANIWAPORTRAIT_SHAPE_MOVE_PROC)(Submenu*); + +struct haniwaPortrait_ovl_s { + cKF_SkeletonInfo_R_c keyframe; + s_xyz keyframe_work[8]; + s_xyz keyframe_morph[8]; + u8 _0D0[72]; + mHP_SET_HANIWAPORTRAIT_PROC set_haniwaPortrait_proc; + mHP_HANIWAPORTRAIT_SHAPE_MOVE_PROC haniwaPortrait_shape_move_proc; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_haniwaPortrait_ovl_h.h b/include/m_haniwaPortrait_ovl_h.h new file mode 100644 index 00000000..c1f12e55 --- /dev/null +++ b/include/m_haniwaPortrait_ovl_h.h @@ -0,0 +1,16 @@ +#ifndef M_HANIWAPORTRAIT_OVL_H_H +#define M_HANIWAPORTRAIT_OVL_H_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct haniwaPortrait_ovl_s mHP_Ovl_c; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_submenu_ovl.h b/include/m_submenu_ovl.h index 018d7bc4..5f212419 100644 --- a/include/m_submenu_ovl.h +++ b/include/m_submenu_ovl.h @@ -19,6 +19,7 @@ #include "m_diary_ovl_h.h" #include "m_address_ovl_h.h" #include "m_editEndChk_h.h" +#include "m_haniwaPortrait_ovl_h.h" #ifdef __cplusplus extern "C" { @@ -94,7 +95,7 @@ typedef void (*mSM_SET_DRAWMODE_PROC)(GRAPH*, PreRender*, f32, f32, s16); typedef void (*mSM_DRAW_ITEM_PROC)(GRAPH*, f32, f32, f32, mActor_name_t, int, int, int); typedef void (*mSM_DRAW_MAIL_PROC)(GRAPH*, f32, f32, f32, Mail_c*, int, int); typedef void (*mSM_SETUP_VIEW_PROC)(Submenu*, GRAPH*, int); -typedef void (*mSM_CHANGE_VIEW_PROC)(GRAPH*, f32, f32, f32, s16, int, int); +typedef void (*mSM_CHANGE_VIEW_PROC)(GRAPH*, f32, f32, f32, f32, s16, int, int); typedef void (*mSM_MOVE_PROC)(Submenu*, mSM_MenuInfo_c*); @@ -116,7 +117,13 @@ struct submenu_overlay_s { /* 0x964 */ mSM_SETUP_VIEW_PROC setup_view_proc; /* 0x968 */ void* unused_func_968; /* 0x96C */ mSM_CHANGE_VIEW_PROC change_view_proc; - /* 0x970 */ u8 _970[0x98C - 0x970]; + /* 0x970 */ void* _970; + /* 0x974 */ void* _974; + /* 0x978 */ void* _978; + /* 0x97C */ void* _97C; + /* 0x980 */ void* _980; + /* 0x984 */ mHP_Ovl_c* hanwiaPortrait_ovl; + /* 0x988 */ void* inventory_ovl; /* 0x98C */ mED_Ovl_c* editor_ovl; /* 0x990 */ mBD_Ovl_c* board_ovl; /* 0x994 */ mAD_Ovl_c* address_ovl; diff --git a/rel/ac_haniwa.c b/rel/ac_haniwa.c index 3f680c4b..ea448620 100644 --- a/rel/ac_haniwa.c +++ b/rel/ac_haniwa.c @@ -24,7 +24,7 @@ extern cKF_Skeleton_R_c cKF_bs_r_hnw; extern cKF_Animation_R_c cKF_ba_r_hnw_move; extern u8 hnw_tmem_txt[]; -extern u8 hnw_face[]; +extern u16 hnw_face[]; static void aHNW_actor_ct(ACTOR* actor, GAME* game); static void aHNW_actor_dt(ACTOR* actor, GAME* game); diff --git a/rel/m_haniwaPortrait_ovl.c b/rel/m_haniwaPortrait_ovl.c new file mode 100644 index 00000000..cc846fcf --- /dev/null +++ b/rel/m_haniwaPortrait_ovl.c @@ -0,0 +1,92 @@ +#include "m_haniwaPortrait_ovl.h" + +#include "m_rcp.h" +#include "sys_matrix.h" + +extern cKF_Skeleton_R_c cKF_bs_r_hnw; +extern cKF_Animation_R_c cKF_ba_r_hnw_move; + +static mHP_Ovl_c hp_ovl_data; + +static void mHP_haniwaPortrait_shape_init(Submenu* submenu) { + mHP_Ovl_c* haniwaPortrait_ovl = submenu->overlay->hanwiaPortrait_ovl; + + cKF_SkeletonInfo_R_ct(&haniwaPortrait_ovl->keyframe, &cKF_bs_r_hnw, NULL, haniwaPortrait_ovl->keyframe_work, haniwaPortrait_ovl->keyframe_morph); + cKF_SkeletonInfo_R_init(&haniwaPortrait_ovl->keyframe, haniwaPortrait_ovl->keyframe.skeleton, &cKF_ba_r_hnw_move, 1.0f, 9.0f, 1.0f, 0.3f, 0.0f, cKF_FRAMECONTROL_REPEAT, NULL); +} + +static void mHP_haniwaPortrait_shape_move(Submenu* submenu) { + cKF_SkeletonInfo_R_play(&submenu->overlay->hanwiaPortrait_ovl->keyframe); +} + +extern u8 hnw_tmem_txt[]; +extern u16 hnw_face[]; + +static void mHP_haniwaPortrait_shape_draw(Submenu* submenu, mSM_MenuInfo_c* menu_info, GAME* game) { + GRAPH* graph = game->graph; + Mtx* mtx = GRAPH_ALLOC_TYPE(graph, Mtx, submenu->overlay->hanwiaPortrait_ovl->keyframe.skeleton->num_shown_joints); + + if (mtx != NULL) { + _texture_z_light_fog_prim(game->graph); + Matrix_scale(0.01f, 0.01f, 0.01f, 0); + + OPEN_DISP(graph); + + gDPPipeSync(NOW_POLY_OPA_DISP++); + gSPMatrix(NOW_POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(NOW_POLY_OPA_DISP++, G_MWO_SEGMENT_B, hnw_tmem_txt); + gDPLoadTLUT_Dolphin(NOW_POLY_OPA_DISP++, 15, 16, 1, hnw_face); + + if (menu_info->data0 == 0) { + gDPSetPrimColor(NOW_POLY_OPA_DISP++, 0, 128, 255, 255, 255, 255); + } + else { + gDPSetPrimColor(NOW_POLY_OPA_DISP++, 0, 128, 255, 255, 255, 255); + } + + CLOSE_DISP(graph); + + cKF_Si3_draw_R_SV(game, &submenu->overlay->hanwiaPortrait_ovl->keyframe, mtx, NULL, NULL, NULL); + } +} + +static void mHP_set_haniwaPortrait(Submenu* submenu, mSM_MenuInfo_c* menu_info, GRAPH* graph, GAME* game, f32 x, f32 y) { + if (x < -128.0f || x > 448.0f || y < -128.0f || y > 368.0f) { + return; + } + + Matrix_push(); + + OPEN_DISP(graph); + + gDPPipeSync(NOW_POLY_OPA_DISP++); + + CLOSE_DISP(graph); + + (*submenu->overlay->change_view_proc)(graph, 105.0f, 25.0f, x * 4.0f, y * 4.0f, 0x0900, 128, 128); + mHP_haniwaPortrait_shape_draw(submenu, menu_info, game); + (*submenu->overlay->setup_view_proc)(submenu, graph, FALSE); + + Matrix_pull(); +} + +extern void mHP_haniwaPortrait_ovl_construct(Submenu* submenu) { + Submenu_Overlay_c* overlay = submenu->overlay; + + if (overlay->hanwiaPortrait_ovl == NULL) { + mem_clear((u8*)&hp_ovl_data, sizeof(mHP_Ovl_c), 0); + overlay->hanwiaPortrait_ovl = &hp_ovl_data; + + submenu->overlay->hanwiaPortrait_ovl->set_haniwaPortrait_proc = &mHP_set_haniwaPortrait; + submenu->overlay->hanwiaPortrait_ovl->haniwaPortrait_shape_move_proc = &mHP_haniwaPortrait_shape_move; + mHP_haniwaPortrait_shape_init(submenu); + mHP_haniwaPortrait_shape_move(submenu); + } +} + +extern void mHP_haniwaPortrait_ovl_destruct(Submenu* submenu) { + Submenu_Overlay_c* overlay = submenu->overlay; + + cKF_SkeletonInfo_R_dt(&overlay->hanwiaPortrait_ovl->keyframe); + submenu->overlay->hanwiaPortrait_ovl = NULL; +}