diff --git a/config/assets.yml b/config/assets.yml index 948fbc6c..dae47196 100644 --- a/config/assets.yml +++ b/config/assets.yml @@ -355,3 +355,11 @@ config/rel.yml: mFM_rail_pal_12: addrs: [0x80F8C448, 0x80F8C468] type: pal16 + # ac_koinobori + aKOI_obj_e_koinobori_a_pal: + addrs: [0x806C5900, 0x806C5920] + type: pal16 + obj_e_koinobori_b_pal: + addrs: [0x806C5920, 0x806C5940] + type: pal16 + \ No newline at end of file diff --git a/config/rel_slices.yml b/config/rel_slices.yml index ad671b5d..d052842b 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -430,6 +430,10 @@ ac_haniwa.c: .text: [0x80427624, 0x80428F64] .rodata: [0x806440B8, 0x806440F8] .data: [0x80683D08, 0x80683E98] +ac_koinobori.c: + .text: [0x805B27B8, 0x805B2AE0] + .data: [0x806C58A0, 0x806C5940] + .rodata: [0x8064A978, 0x8064A990] ac_rope.c: .text: [0x804967A4, 0x80496AB8] .rodata: [0x80644DB0,0x80644DB8] diff --git a/include/ac_koinobori.h b/include/ac_koinobori.h index b232f942..afc6ea3d 100644 --- a/include/ac_koinobori.h +++ b/include/ac_koinobori.h @@ -3,6 +3,7 @@ #include "types.h" #include "m_actor.h" +#include "c_keyframe.h" #ifdef __cplusplus extern "C" { @@ -10,6 +11,22 @@ extern "C" { extern ACTOR_PROFILE Koinobori_Profile; +typedef void (*KOINOBORI_PROC)(ACTOR*, GAME*); + +/* sizeof(KOINOBORI_ACTOR) == 0x2DC */ +typedef struct actor_koinobori_s{ + /* 0x000 */ ACTOR actor_class; + /* 0x174 */ int _174; // Unused + /* 0x178 */ cKF_SkeletonInfo_R_c keyframe; + /* 0x1E8 */ int _1E8; // Unused + /* 0x1EC */ s_xyz work[15]; + /* 0x246 */ s_xyz morph[15]; + /* 0x2A0 */ KOINOBORI_PROC action_proc; + /* 0x2A4 */ u8 _2A4[0x2B4 - 0x2A4]; // Unused + /* 0x2B4 */ int action; + /* 0x2B8 */ u8 _2B8[0x2DC - 0x2B8]; // Unused +} KOINOBORI_ACTOR; + #ifdef __cplusplus } #endif diff --git a/include/m_name_table.h b/include/m_name_table.h index b0e01b95..fb13b49f 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -2699,6 +2699,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define DUMMY_RADIO 0xF109 #define DUMMY_MIKUJI 0xF10D #define DUMMY_TAMA 0xF110 +#define DUMMY_KOINOBORI 0xF114 #define DUMMY_DOUZOU 0xF11D #define DUMMY_NAMEPLATE 0xF11F #define DUMMY_BOAT 0xF128 diff --git a/src/ac_koinobori.c b/src/ac_koinobori.c new file mode 100644 index 00000000..5a965ae6 --- /dev/null +++ b/src/ac_koinobori.c @@ -0,0 +1,71 @@ +#include "ac_koinobori.h" + +#include "m_name_table.h" +#include "sys_matrix.h" +#include "m_lib.h" +#include "m_rcp.h" +#include "m_common_data.h" +#include "m_player_lib.h" + +enum { + aKOI_ACTION_WAIT, +}; + +static void aKOI_actor_ct(ACTOR* actor, GAME* game); +static void aKOI_actor_dt(ACTOR* actor, GAME* game); +static void aKOI_actor_init(ACTOR* actor, GAME* game); +static void aKOI_actor_draw(ACTOR* actor, GAME* game); + +ACTOR_PROFILE Koinobori_Profile = { + mAc_PROFILE_KOINOBORI, + ACTOR_PART_ITEM, + ACTOR_STATE_TA_SET, + KOINOBORI_WINDSOCK, + ACTOR_OBJ_BANK_KEEP, + sizeof(KOINOBORI_ACTOR), + &aKOI_actor_ct, + &aKOI_actor_dt, + &aKOI_actor_init, + &aKOI_actor_draw, + NULL +}; + +extern cKF_Skeleton_R_c cKF_bs_r_obj_e_koinobori; +extern Vtx obj_e_koinobori_shadow_v[]; +extern Gfx obj_e_koinobori_shadowT_model[]; +extern cKF_Animation_R_c cKF_ba_r_obj_e_koinobori; + +u8 aKOI_shadow_vtx_fix_flg_table[8] = { + 1, 0, 0, 1, + 1, 0, 0, 1 +}; + +bIT_ShadowData_c aKOI_shadow_data = { + 8, + aKOI_shadow_vtx_fix_flg_table, + 60.0f, + obj_e_koinobori_shadow_v, + obj_e_koinobori_shadowT_model, +}; + +static void aKOI_setup_action(KOINOBORI_ACTOR* actor, int action); + +static void aKOI_actor_ct(ACTOR* actor, GAME* game) { + KOINOBORI_ACTOR* koinobori = (KOINOBORI_ACTOR*)actor; + + actor->cull_height = 830.0f; + actor->cull_radius = 480.0f; + + cKF_SkeletonInfo_R_ct(&koinobori->keyframe, &cKF_bs_r_obj_e_koinobori, NULL, koinobori->work, koinobori->morph); + aKOI_setup_action(koinobori, aKOI_ACTION_WAIT); + cKF_SkeletonInfo_R_play(&koinobori->keyframe); +} + +static void aKOI_actor_dt(ACTOR* actor, GAME* game) { + KOINOBORI_ACTOR* koinobori = (KOINOBORI_ACTOR*)actor; + cKF_SkeletonInfo_R_dt(&koinobori->keyframe); +} + +#include "../src/ac_koinobori_move.c_inc" + +#include "../src/ac_koinobori_draw.c_inc" diff --git a/src/ac_koinobori_draw.c_inc b/src/ac_koinobori_draw.c_inc new file mode 100644 index 00000000..eb9fed33 --- /dev/null +++ b/src/ac_koinobori_draw.c_inc @@ -0,0 +1,41 @@ +u16 aKOI_obj_e_koinobori_a_pal[] = { + #include "assets/aKOI_obj_e_koinobori_a_pal.inc" +}; + +u16 obj_e_koinobori_b_pal[] = { + #include "assets/obj_e_koinobori_b_pal.inc" +}; + +static void aKOI_actor_draw(ACTOR* actor, GAME* game) { + KOINOBORI_ACTOR* koinobori; + GRAPH* graph; + cKF_SkeletonInfo_R_c* keyframe; + Mtx* mtx; + u16* pal; + Gfx* gfx; + + + koinobori = (KOINOBORI_ACTOR*)actor; + graph = game->graph; + keyframe = &koinobori->keyframe; + mtx = GRAPH_ALLOC_TYPE(graph, Mtx, keyframe->skeleton->num_shown_joints); + + if (mtx != NULL) { + pal = Common_Get(clip.structure_clip)->get_pal_segment_proc(aSTR_PAL_KOINOBORI_A); + + _texture_z_light_fog_prim_npc(graph); + + OPEN_DISP(graph); + gfx = NOW_POLY_OPA_DISP; + + gSPSegment(gfx++, G_MWO_SEGMENT_8, pal); + gSPSegment(gfx++, G_MWO_SEGMENT_9, &obj_e_koinobori_b_pal); + gSPSegment(gfx++, G_MWO_SEGMENT_A, &aKOI_obj_e_koinobori_a_pal); + + SET_POLY_OPA_DISP(gfx); + CLOSE_DISP(graph); + + cKF_Si3_draw_R_SV(game, keyframe, mtx, NULL, NULL, actor); + (*Common_Get(clip).bg_item_clip->draw_shadow_proc)(game, &aKOI_shadow_data, FALSE); + } +} diff --git a/src/ac_koinobori_move.c_inc b/src/ac_koinobori_move.c_inc new file mode 100644 index 00000000..3844398c --- /dev/null +++ b/src/ac_koinobori_move.c_inc @@ -0,0 +1,29 @@ +static void aKOI_wait(ACTOR* actor, GAME* game) { +} + +static void aKOI_setup_action(KOINOBORI_ACTOR* koinobori, int action) { + static KOINOBORI_PROC process[8] = { &aKOI_wait, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + + cKF_SkeletonInfo_R_init(&koinobori->keyframe, koinobori->keyframe.skeleton, &cKF_ba_r_obj_e_koinobori, 1.0f, 1.0f, 1.0f, 0.5f, 0.0f, TRUE, NULL); + koinobori->action_proc = process[action]; + koinobori->action = action; +} + +static void aKOI_actor_move(ACTOR* actor, GAME* game) { + GAME_PLAY* game_play = (GAME_PLAY*)game; + KOINOBORI_ACTOR* koinobori = (KOINOBORI_ACTOR*)actor; + + GET_PLAYER_ACTOR(game_play); + cKF_SkeletonInfo_R_play(&koinobori->keyframe); + koinobori->action_proc(actor, game); + + sAdo_OngenPos((u32)actor, 0x35, &actor->world.position); +} + +static void aKOI_actor_init(ACTOR* actor, GAME* game) { + xyz_t pos = actor->home.position; + + mFI_SetFG_common(DUMMY_KOINOBORI, pos, FALSE); + aKOI_actor_move(actor, game); + actor->mv_proc = aKOI_actor_move; +}