From 5914ad66983a84711835a0488aefecd43cfe029b Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sun, 19 May 2024 13:17:52 -0400 Subject: [PATCH] Finish & link m_inventory_ovl --- config/rel_slices.yml | 5 + include/audio_defs.h | 5 + include/libc/math.h | 5 +- include/m_bgm.h | 11 + include/m_inventory_ovl.h | 29 +- include/m_player.h | 24 +- include/m_player_lib.h | 18 + include/m_submenu.h | 9 +- include/m_submenu_ovl.h | 16 +- src/m_bgm.c | 2 +- src/m_catalog_ovl.c | 4 +- src/m_hand_ovl.c | 10 +- src/m_inventory_ovl.c | 2145 +++++++++++++++++++++++++++++++++---- src/m_submenu_ovl.c | 4 +- 14 files changed, 2069 insertions(+), 218 deletions(-) diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 15fd1b0f..1445f1fe 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -970,6 +970,11 @@ m_hboard_ovl.c: .text: [0x805E0AC8, 0x805E1398] .rodata: [0x8064B480, 0x8064B4B8] .data: [0x806CD3B0, 0x806CD3C8] +m_inventory_ovl.c: + .text: [0x805E1398, 0x805E4DFC] + .rodata: [0x8064B4B8, 0x8064B5C8] + .data: [0x806CD3C8, 0x806CD7B8] + .bss: [0x8133FAE0, 0x813400D0] m_map_ovl.c: .text: [0x805E5EFC, 0x805E7A54] .rodata: [0x8064B628, 0x8064B6B0] diff --git a/include/audio_defs.h b/include/audio_defs.h index 332b6aa8..7872a54e 100644 --- a/include/audio_defs.h +++ b/include/audio_defs.h @@ -38,6 +38,9 @@ typedef enum audio_sound_effects { NA_SE_25 = 0x25, NA_SE_26 = 0x26, + NA_SE_MENU_PAUSE = 0x30, + NA_SE_31 = 0x31, + NA_SE_DRAWER_SHUT = 0x3A, NA_SE_ITEM_GET = 0x40, @@ -78,6 +81,8 @@ typedef enum audio_sound_effects { NA_SE_ROD_STROKE = 0x109, NA_SE_ROD_BACK, + NA_SE_EAT = 0x113, + NA_SE_WEAR = 0x11C, NA_SE_SCOOP1 = 0x11E, diff --git a/include/libc/math.h b/include/libc/math.h index a0427698..6cda6927 100644 --- a/include/libc/math.h +++ b/include/libc/math.h @@ -4,6 +4,9 @@ #include "types.h" #define SQRT_OF_2_F 1.41421356237309504880f +#define SQRT_OF_3_F 1.73205080756887729353f + +#define SQRT_3_OVER_3_F (SQRT_OF_3_F / 3.0f) #define M_PI 3.14159265358979323846f @@ -15,4 +18,4 @@ f32 fatan2(f32, f32); f64 fsqrt(f32); f32 facos(f32); -#endif \ No newline at end of file +#endif diff --git a/include/m_bgm.h b/include/m_bgm.h index bad34b58..bac71a79 100644 --- a/include/m_bgm.h +++ b/include/m_bgm.h @@ -9,6 +9,17 @@ extern "C" { #endif +enum { + mBGM_PAUSE_0, + mBGM_PAUSE_1, + mBGM_PAUSE_2, + mBGM_PAUSE_NOTICE, + mBGM_PAUSE_4, + mBGM_PAUSE_STOP, + + mBGM_PAUSE_NUM +}; + extern void mBGMPsComp_make_ps_fanfare(u8 bgm_num, u16 stop_type); extern void mBGMPsComp_make_ps_lost_fanfare(u8 bgm_num, u16 stop_type); extern void mBGMPsComp_make_ps_wipe(u16 stop_type); diff --git a/include/m_inventory_ovl.h b/include/m_inventory_ovl.h index 856a7c8c..757d3a0d 100644 --- a/include/m_inventory_ovl.h +++ b/include/m_inventory_ovl.h @@ -11,9 +11,10 @@ extern "C" { #endif -#define mIV_PLAYER_JOINT_NUM 27 +#define mIV_PLAYER_JOINT_NUM (mPlayer_JOINT_NUM + 1) #define mIV_ITEM_JOINT_NUM 8 #define mIV_PLAYER_EFFECT_NUM 20 +#define mIV_COLLECT_NUM 40 enum { mIV_ITEM_SCALE_TYPE_NONE, @@ -30,11 +31,26 @@ enum { mIV_PAGE_FISH_COLLECTION, mIV_PAGE_INVENTORY, mIV_PAGE_INSECT_COLLECTION, - mIV_PAGE_ORIGINAL_DESIGNS, mIV_PAGE_NUM }; +enum { + mIV_ANIM_WALK, + mIV_ANIM_CATCH, + mIV_ANIM_CHANGE, + mIV_ANIM_EAT, + + mIV_ANIM_NUM +}; + +enum { + mIV_STRING_LAND_NAME, + mIV_STRING_PLAYER_NAME, + + mIV_STRING_NUM +}; + typedef struct inventory_effect_s { int timer; xyz_t pos; @@ -46,8 +62,8 @@ typedef mActor_name_t (*mIV_SET_COLLECT_ITEMNO_PROC)(int, int); /* sizeof (struct inventory_ovl_s) == 0x5EC */ struct inventory_ovl_s { - cKF_SkeletonInfo_R_c player_keyframe0; - cKF_SkeletonInfo_R_c player_keyframe1; + cKF_SkeletonInfo_R_c player_main_keyframe; + cKF_SkeletonInfo_R_c player_com_keyframe; s_xyz player_work[mIV_PLAYER_JOINT_NUM]; s_xyz player_morph[mIV_PLAYER_JOINT_NUM]; @@ -60,8 +76,8 @@ struct inventory_ovl_s { u8 _374[0x3BC - 0x374]; - u16 selected_item_bitfield; - u16 selected_mail_bitfield; + u16 selectable_item_bitfield; + u16 selectable_mail_bitfield; u32 disp_money; int disp_money_change_frames; @@ -74,6 +90,7 @@ struct inventory_ovl_s { u8 food_idx; u8 item_scale_type[mPr_POCKETS_SLOT_COUNT]; u8 page_order[mIV_PAGE_NUM]; + u8 next_page_id; s16 page_move_timer; s16 remove_timer; mIV_pl_eff_c pl_eff[mIV_PLAYER_EFFECT_NUM]; diff --git a/include/m_player.h b/include/m_player.h index f492dbab..d8d2c40c 100644 --- a/include/m_player.h +++ b/include/m_player.h @@ -22,6 +22,8 @@ typedef struct player_actor_s PLAYER_ACTOR; #define mPlayer_FORCE_POSITION_ANGLE_ROTY (1 << 5) #define mPlayer_FORCE_POSITION_ANGLE_ROTZ (1 << 6) +#define mPlayer_JOINT_NUM 26 + enum { mPlayer_ADDRESSABLE_TRUE, mPlayer_ADDRESSABLE_FALSE_MOVEMENT, @@ -364,6 +366,7 @@ enum { mPlayer_ITEM_KIND_UMBRELLA30, mPlayer_ITEM_KIND_UMBRELLA31, + mPlayer_ITEM_KIND_ORG_UMBRELLA00, mPlayer_ITEM_KIND_ORG_UMBRELLA01, mPlayer_ITEM_KIND_ORG_UMBRELLA02, mPlayer_ITEM_KIND_ORG_UMBRELLA03, @@ -371,7 +374,6 @@ enum { mPlayer_ITEM_KIND_ORG_UMBRELLA05, mPlayer_ITEM_KIND_ORG_UMBRELLA06, mPlayer_ITEM_KIND_ORG_UMBRELLA07, - mPlayer_ITEM_KIND_ORG_UMBRELLA08, mPlayer_ITEM_KIND_ROD, mPlayer_ITEM_KIND_GOLD_ROD, @@ -470,6 +472,26 @@ enum { mPlayer_ITEM_DATA_NUM }; +enum { + mPlayer_ITEM_DATA_TYPE_GFX, + mPlayer_ITEM_DATA_TYPE_SKELETON, + mPlayer_ITEM_DATA_TYPE_NET_ANIMATION, + mPlayer_ITEM_DATA_TYPE_ROD_ANIMATION, + mPlayer_ITEM_DATA_TYPE_BALLOON_ANIMATION, + mPlayer_ITEM_DATA_TYPE_PINWHEEL_ANIMATION, + + mPlayer_ITEM_DATA_TYPE_NUM +}; + +enum { + mPlayer_PART_TABLE_NORMAL, + mPlayer_PART_TABLE_AXE, + mPlayer_PART_TABLE_PICK_UP, + mPlayer_PART_TABLE_NET, + + mPlayer_PART_TABLE_NUM +}; + enum { mPlayer_CREATURE_INSECT, mPlayer_CREATURE_GYOEI, diff --git a/include/m_player_lib.h b/include/m_player_lib.h index 8953d623..c5ad6a6d 100644 --- a/include/m_player_lib.h +++ b/include/m_player_lib.h @@ -4,6 +4,7 @@ #include "types.h" #include "m_player.h" #include "m_private_h.h" +#include "c_keyframe.h" #ifdef __cplusplus extern "C" { @@ -79,6 +80,23 @@ extern int mPlib_Check_StopNet(xyz_t* net_pos); extern int mPlib_Check_DigScoop(xyz_t* scoop_pos); extern int mPlib_Check_tree_shaken(const xyz_t* pos); extern int mPlib_Check_VibUnit_OneFrame(const xyz_t* pos); +extern int mPlib_Get_BasicItemShapeIndex_fromItemKind(int item_kind); +extern u8 mPlib_Get_Item_DataPointerType(int idx); +extern void* mPlib_Get_Item_DataPointer(int idx); +extern int mPlib_Get_BasicPlayerAnimeIndex_fromItemKind(int item_kind); +extern cKF_Animation_R_c* mPlib_Get_Pointer_Animation(int anim_idx); +extern int mPlib_Get_BasicPartTableIndex_fromAnimeIndex(int anim_idx); +extern int mPlib_Get_BasicItemAnimeIndex_fromItemKind(int item_kind); +extern void mPlib_DMA_player_Part_Table(s8* part_table_p, int idx); +extern cKF_Skeleton_R_c* mPlib_get_player_mdl_p(void); +extern u8* mPlib_Get_PlayerEyeTexAnimation_p(int anim_idx); +extern u8* mPlib_Get_PlayerMouthTexAnimation_p(int anim_idx); +extern u8* mPlib_Get_eye_tex_p(int idx); +extern u8* mPlib_Get_mouth_tex_p(int idx); +extern u8* mPlib_get_player_tex_p(GAME* game); +extern u16* mPlib_get_player_pallet_p(GAME* game); +extern u16* mPlib_get_player_face_pallet_p(GAME* game); +extern int mPlib_Check_scoop_after(GAME* game, xyz_t* pos, mActor_name_t* item, ACTOR** hit_actor, int gold_shovel); extern mPlayer_change_data_from_submenu_c* mPlib_Get_change_data_from_submenu_p(); diff --git a/include/m_submenu.h b/include/m_submenu.h index caa3fbe6..d67f0c88 100644 --- a/include/m_submenu.h +++ b/include/m_submenu.h @@ -103,7 +103,7 @@ enum { mSM_IV_OPEN_SHRINE, mSM_IV_OPEN_12, mSM_IV_OPEN_EXCHANGE, - mSM_IV_OPEN_14, + mSM_IV_OPEN_CPMAIL, mSM_IV_OPEN_CURATOR, mSM_IV_OPEN_16, @@ -118,6 +118,13 @@ enum { mSM_IV_ITEM_NUM }; +enum { + mSM_HANIWA_OPEN_ENTRUST, + mSM_HANIWA_OPEN_TAKE, + + mSM_HANIWA_OPEN_NUM +}; + enum { mSM_BD_OPEN_WRITE, mSM_BD_OPEN_READ, diff --git a/include/m_submenu_ovl.h b/include/m_submenu_ovl.h index abee6321..d53e7006 100644 --- a/include/m_submenu_ovl.h +++ b/include/m_submenu_ovl.h @@ -28,6 +28,7 @@ #include "m_catalog_ovl_h.h" #include "m_hand_ovl_h.h" #include "m_inventory_ovl_h.h" +#include "m_player.h" #ifdef __cplusplus extern "C" { @@ -65,14 +66,15 @@ typedef struct submenu_ovl_dlftbl_s { int in_ram_flag; } mSM_Ovl_dlftbl_c; -// TODO: fill this out typedef struct submenu_segment_s { int _00; - s16 _04; - s16 _06; - s16 _08; - s16 _0A; - u8 _0C[0x30 - 0x0C]; + s16 player_main_anime_idx; + s16 player_item_anime_idx; + s16 change_player_main_anime_idx; + s16 player_anime_timer; + s16 player_umbrella_bank_idx; + s16 umbrella_ids[2]; + s8 player_part_table[mPlayer_JOINT_NUM + 1]; int dlftbl_loaded_num; mSM_Ovl_dlftbl_c* dlftbl_loaded_tbl[8]; } mSM_Segment_c; @@ -91,7 +93,7 @@ typedef struct submenu_menu_info_s { f32 speed[2]; char* _28; - int _2C; + int open_flag; int next_proc_status; s16 move_drt; diff --git a/src/m_bgm.c b/src/m_bgm.c index daeee328..fd87f8cd 100644 --- a/src/m_bgm.c +++ b/src/m_bgm.c @@ -2653,7 +2653,7 @@ extern void mBGM_reset() { } if (ps_comp->pause_state != 0) { - mBGMPsComp_pause(5); + mBGMPsComp_pause(mBGM_PAUSE_STOP); } mBGMDemo_ct(&bgm->demo); diff --git a/src/m_catalog_ovl.c b/src/m_catalog_ovl.c index faa1e315..0896ca75 100644 --- a/src/m_catalog_ovl.c +++ b/src/m_catalog_ovl.c @@ -527,8 +527,8 @@ static void mCL_move_Move(Submenu* submenu, mSM_MenuInfo_c* menu_info) { static void mCL_move_Play(Submenu* submenu, mSM_MenuInfo_c* menu_info) { mCL_Ovl_c* catalog_ovl = submenu->overlay->catalog_ovl; - if (menu_info->_2C == FALSE) { - menu_info->_2C = TRUE; + if (menu_info->open_flag == FALSE) { + menu_info->open_flag = TRUE; submenu->overlay->tag_ovl->chg_tag_func_proc(submenu, 14, 0, 0, 0.0f, 0.0f); } else if (catalog_ovl->page_timer != 0) { catalog_ovl->page_timer--; diff --git a/src/m_hand_ovl.c b/src/m_hand_ovl.c index 290dab93..8ad9a644 100644 --- a/src/m_hand_ovl.c +++ b/src/m_hand_ovl.c @@ -310,8 +310,8 @@ static void mHD_drop_item(Submenu* submenu, mTG_tag_c* tag, mActor_name_t* item, submenu->overlay->tag_ovl->init_tag_data_item_win_proc(submenu); - if (overlay->segment._04 == 1) { - overlay->segment._08 = 0; + if (overlay->segment.player_main_anime_idx == mIV_ANIM_CATCH) { + overlay->segment.change_player_main_anime_idx = mIV_ANIM_WALK; } } @@ -515,7 +515,8 @@ static void mHD_open_end_proc_item_type3(Submenu* submenu, int idx, int table) { int category = ITEM_NAME_GET_CAT(item); if (item == RSV_CLOTH || ITEM_IS_CLOTH(item)) { - if (cKF_FrameControl_passCheck_now(&submenu->overlay->inventory_ovl->player_keyframe0.frame_control, 36.0f)) { + if (cKF_FrameControl_passCheck_now(&submenu->overlay->inventory_ovl->player_main_keyframe.frame_control, + 36.0f)) { cloth_p = &Now_Private->cloth; mHD_drop_item(submenu, tag, &cloth_p->item, NULL); @@ -768,7 +769,8 @@ static void mHD_sasu2_move(Submenu* submenu) { int category = ITEM_NAME_GET_CAT(hand_ovl->info.item); if (hand_ovl->info.item == RSV_CLOTH || ITEM_IS_CLOTH(hand_ovl->info.item)) { - if (cKF_FrameControl_passCheck_now(&submenu->overlay->inventory_ovl->player_keyframe0.frame_control, 36.0f)) { + if (cKF_FrameControl_passCheck_now(&submenu->overlay->inventory_ovl->player_main_keyframe.frame_control, + 36.0f)) { mPr_cloth_c* cloth_p = &Now_Private->cloth; u16 cloth_idx; diff --git a/src/m_inventory_ovl.c b/src/m_inventory_ovl.c index b7f71880..59ef3b92 100644 --- a/src/m_inventory_ovl.c +++ b/src/m_inventory_ovl.c @@ -5,15 +5,15 @@ #include "ac_set_ovl_insect.h" #include "m_room_type.h" #include "m_common_data.h" - -enum { - mIV_ANIM_WALK, - mIV_ANIM_CATCH, - mIV_ANIM_CHANGE, - mIV_ANIM_EAT, - - mIV_ANIM_NUM -}; +#include "m_rcp.h" +#include "sys_matrix.h" +#include "m_tag_ovl.h" +#include "m_hand_ovl.h" +#include "m_bgm.h" +#include "zurumode.h" +#include "padmgr.h" +#include "m_play.h" +#include "m_font.h" enum { mIV_ITEM_KIND_AXE, @@ -65,20 +65,7 @@ enum { mIV_ITEM_KIND_NUM }; -static int mIV_Get_pl_main_anime_index(int type) { - static u16 player_main_animation_index_table[mIV_ANIM_NUM] = { - mPlayer_ANIM_WALK1, - mPlayer_ANIM_MENU_CATCH1, - mPlayer_ANIM_MENU_CHANGE1, - mPlayer_ANIM_EAT1, - }; - - if (type >= mIV_ANIM_WALK && type < mIV_ANIM_NUM) { - return player_main_animation_index_table[type]; - } - - return -1; -} +static mIV_Ovl_c inv_ovl_data; // clang-format off #define F(n) aSOG_FISH_TYPE_##n @@ -108,21 +95,36 @@ static u8 mIV_insect_collect_list[] = { #undef I // clang-format on +static int mIV_Get_pl_main_anime_index(int type) { + static u16 player_main_animation_index_table[mIV_ANIM_NUM] = { + mPlayer_ANIM_WALK1, + mPlayer_ANIM_MENU_CATCH1, + mPlayer_ANIM_MENU_CHANGE1, + mPlayer_ANIM_EAT1, + }; + + if (type >= mIV_ANIM_WALK && type < mIV_ANIM_NUM) { + return player_main_animation_index_table[type]; + } + + return -1; +} + static mActor_name_t mIV_set_collect_itemNo(int type, int page) { - if (type == mIV_PAGE_INSECT_COLLECTION) { + if (page == mIV_PAGE_INSECT_COLLECTION) { int insect_no = mIV_insect_collect_list[type]; int bit = mRmTp_FtrItemNo2FtrIdx(FTR_INSECT_START + FTR_NO_2_IDX(insect_no)); - if (Now_Private->furniture_collected_bitfield[bit >> 5] & (1 << (bit & 31)) != 0) { + if (Now_Private->furniture_collected_bitfield[bit >> 5] & (1 << (bit & 31))) { return ITM_INSECT_START + insect_no; } else { return EMPTY_NO; } } else { int fish_no = mIV_fish_collect_list[type]; - int bit = FTR_IDX_2_NO(FTR_NO_2_IDX(0x31A) + FTR_NO_2_IDX(fish_no)); + int bit = FTR_IDX_2_NO(FTR_NO_2_IDX(0x31A) + (u32)FTR_NO_2_IDX(fish_no)); - if (Now_Private->furniture_collected_bitfield[bit >> 5] & (1 << (bit & 31)) != 0) { + if (Now_Private->furniture_collected_bitfield[bit >> 5] & (1 << (bit & 31))) { return mNT_FishIdx2FishItemNo(fish_no); } else { return EMPTY_NO; @@ -130,179 +132,101 @@ static mActor_name_t mIV_set_collect_itemNo(int type, int page) { } } -static int mIV_get_player_item_anime_id(void) { +static s16 mIV_get_player_item_anime_id(void) { mActor_name_t item = Now_Private->equipment; + s16 res; if (item >= ITM_NET && item <= ITM_NET) { - return mIV_ITEM_KIND_NET; + res = mIV_ITEM_KIND_NET; + } else if (item == ITM_AXE) { + res = mIV_ITEM_KIND_AXE; + } else if (item == ITM_GOLDEN_AXE) { + res = mIV_ITEM_KIND_GOLD_AXE; + } else if (item == ITM_AXE_USE_1) { + res = mIV_ITEM_KIND_AXE_USE_1; + } else if (item == ITM_AXE_USE_2) { + res = mIV_ITEM_KIND_AXE_USE_2; + } else if (item == ITM_AXE_USE_3) { + res = mIV_ITEM_KIND_AXE_USE_3; + } else if (item == ITM_AXE_USE_4) { + res = mIV_ITEM_KIND_AXE_USE_4; + } else if (item == ITM_AXE_USE_5) { + res = mIV_ITEM_KIND_AXE_USE_5; + } else if (item == ITM_AXE_USE_6) { + res = mIV_ITEM_KIND_AXE_USE_6; + } else if (item == ITM_AXE_USE_7) { + res = mIV_ITEM_KIND_AXE_USE_7; + } else if (item >= ITM_ROD && item <= ITM_ROD) { + res = mIV_ITEM_KIND_ROD; + } else if (item >= ITM_UMBRELLA_START && item <= ITM_MY_ORG_UMBRELLA7) { + res = mIV_ITEM_KIND_UMBRELLA; + } else if (item >= ITM_SHOVEL && item <= ITM_SHOVEL) { + res = mIV_ITEM_KIND_SHOVEL; + } else if (item >= ITM_GOLDEN_AXE && item <= ITM_GOLDEN_AXE) { /* duplicate golden axe check */ + res = mIV_ITEM_KIND_GOLD_AXE; + } else if (item >= ITM_GOLDEN_NET && item <= ITM_GOLDEN_NET) { + res = mIV_ITEM_KIND_GOLD_NET; + } else if (item >= ITM_GOLDEN_ROD && item <= ITM_GOLDEN_ROD) { + res = mIV_ITEM_KIND_GOLD_ROD; + } else if (item >= ITM_GOLDEN_SHOVEL && item <= ITM_GOLDEN_SHOVEL) { + res = mIV_ITEM_KIND_GOLD_SHOVEL; + } else if (item == ITM_RED_BALLOON) { + res = mIV_ITEM_KIND_RED_BALLOON; + } else if (item == ITM_YELLOW_BALLOON) { + res = mIV_ITEM_KIND_YELLOW_BALLOON; + } else if (item == ITM_BLUE_BALLOON) { + res = mIV_ITEM_KIND_BLUE_BALLOON; + } else if (item == ITM_GREEN_BALLOON) { + res = mIV_ITEM_KIND_GREEN_BALLOON; + } else if (item == ITM_PURPLE_BALLOON) { + res = mIV_ITEM_KIND_PURPLE_BALLOON; + } else if (item == ITM_BUNNY_P_BALLOON) { + res = mIV_ITEM_KIND_BUNNY_P_BALLOON; + } else if (item == ITM_BUNNY_B_BALLOON) { + res = mIV_ITEM_KIND_BUNNY_B_BALLOON; + } else if (item == ITM_BUNNY_O_BALLOON) { + res = mIV_ITEM_KIND_BUNNY_O_BALLOON; + } else if (item == ITM_YELLOW_PINWHEEL) { + res = mIV_ITEM_KIND_YELLOW_PINWHEEL; + } else if (item == ITM_RED_PINWHEEL) { + res = mIV_ITEM_KIND_RED_PINWHEEL; + } else if (item == ITM_TIGER_PINWHEEL) { + res = mIV_ITEM_KIND_TIGER_PINWHEEL; + } else if (item == ITM_GREEN_PINWHEEL) { + res = mIV_ITEM_KIND_GREEN_PINWHEEL; + } else if (item == ITM_PINK_PINWHEEL) { + res = mIV_ITEM_KIND_PINK_PINWHEEL; + } else if (item == ITM_STRIPED_PINWHEEL) { + res = mIV_ITEM_KIND_STRIPED_PINWHEEL; + } else if (item == ITM_FLOWER_PINWHEEL) { + res = mIV_ITEM_KIND_FLOWER_PINWHEEL; + } else if (item == ITM_FANCY_PINWHEEL) { + res = mIV_ITEM_KIND_FANCY_PINWHEEL; + } else if (item == ITM_BLUEBELL_FAN) { + res = mIV_ITEM_KIND_BLUEBELL_FAN; + } else if (item == ITM_PLUM_FAN) { + res = mIV_ITEM_KIND_PLUM_FAN; + } else if (item == ITM_BAMBOO_FAN) { + res = mIV_ITEM_KIND_BAMBOO_FAN; + } else if (item == ITM_CLOUD_FAN) { + res = mIV_ITEM_KIND_CLOUD_FAN; + } else if (item == ITM_MAPLE_FAN) { + res = mIV_ITEM_KIND_MAPLE_FAN; + } else if (item == ITM_FAN_FAN) { + res = mIV_ITEM_KIND_FAN_FAN; + } else if (item == ITM_FLOWER_FAN) { + res = mIV_ITEM_KIND_FLOWER_FAN; + } else if (item == ITM_LEAF_FAN) { + res = mIV_ITEM_KIND_LEAF_FAN; + } else { + res = mIV_ITEM_KIND_NUM; /* No animation */ } - if (item == ITM_AXE) { - return mIV_ITEM_KIND_AXE; - } - - if (item == ITM_GOLDEN_AXE) { - return mIV_ITEM_KIND_GOLD_AXE; - } - - if (item == ITM_AXE_USE_1) { - return mIV_ITEM_KIND_AXE_USE_1; - } - - if (item == ITM_AXE_USE_2) { - return mIV_ITEM_KIND_AXE_USE_2; - } - - if (item == ITM_AXE_USE_3) { - return mIV_ITEM_KIND_AXE_USE_3; - } - - if (item == ITM_AXE_USE_4) { - return mIV_ITEM_KIND_AXE_USE_4; - } - - if (item == ITM_AXE_USE_5) { - return mIV_ITEM_KIND_AXE_USE_5; - } - - if (item == ITM_AXE_USE_6) { - return mIV_ITEM_KIND_AXE_USE_6; - } - - if (item == ITM_AXE_USE_7) { - return mIV_ITEM_KIND_AXE_USE_7; - } - - if (item >= ITM_ROD && item <= ITM_ROD) { - return mIV_ITEM_KIND_ROD; - } - - if (item >= ITM_UMBRELLA_START && item <= ITM_MY_ORG_UMBRELLA7) { - return mIV_ITEM_KIND_UMBRELLA; - } - - if (item >= ITM_SHOVEL && item <= ITM_SHOVEL) { - return mIV_ITEM_KIND_SHOVEL; - } - - /* duplicate golden axe check */ - if (item >= ITM_GOLDEN_AXE && item <= ITM_GOLDEN_AXE) { - return mIV_ITEM_KIND_GOLD_AXE; - } - - if (item >= ITM_GOLDEN_NET && item <= ITM_GOLDEN_NET) { - return mIV_ITEM_KIND_GOLD_NET; - } - - if (item >= ITM_GOLDEN_ROD && item <= ITM_GOLDEN_ROD) { - return mIV_ITEM_KIND_GOLD_ROD; - } - - if (item >= ITM_GOLDEN_SHOVEL && item <= ITM_GOLDEN_SHOVEL) { - return mIV_ITEM_KIND_GOLD_SHOVEL; - } - - if (item == ITM_RED_BALLOON) { - return mIV_ITEM_KIND_RED_BALLOON; - } - - if (item == ITM_YELLOW_BALLOON) { - return mIV_ITEM_KIND_YELLOW_BALLOON; - } - - if (item == ITM_BLUE_BALLOON) { - return mIV_ITEM_KIND_BLUE_BALLOON; - } - - if (item == ITM_GREEN_BALLOON) { - return mIV_ITEM_KIND_GREEN_BALLOON; - } - - if (item == ITM_PURPLE_BALLOON) { - return mIV_ITEM_KIND_PURPLE_BALLOON; - } - - if (item == ITM_BUNNY_P_BALLOON) { - return mIV_ITEM_KIND_BUNNY_P_BALLOON; - } - - if (item == ITM_BUNNY_B_BALLOON) { - return mIV_ITEM_KIND_BUNNY_B_BALLOON; - } - - if (item == ITM_BUNNY_O_BALLOON) { - return mIV_ITEM_KIND_BUNNY_O_BALLOON; - } - - if (item == ITM_YELLOW_PINWHEEL) { - return mIV_ITEM_KIND_YELLOW_PINWHEEL; - } - - if (item == ITM_RED_PINWHEEL) { - return mIV_ITEM_KIND_RED_PINWHEEL; - } - - if (item == ITM_TIGER_PINWHEEL) { - return mIV_ITEM_KIND_TIGER_PINWHEEL; - } - - if (item == ITM_GREEN_PINWHEEL) { - return mIV_ITEM_KIND_GREEN_PINWHEEL; - } - - if (item == ITM_PINK_PINWHEEL) { - return mIV_ITEM_KIND_PINK_PINWHEEL; - } - - if (item == ITM_STRIPED_PINWHEEL) { - return mIV_ITEM_KIND_STRIPED_PINWHEEL; - } - - if (item == ITM_FLOWER_PINWHEEL) { - return mIV_ITEM_KIND_FLOWER_PINWHEEL; - } - - if (item == ITM_FANCY_PINWHEEL) { - return mIV_ITEM_KIND_FANCY_PINWHEEL; - } - - if (item == ITM_BLUEBELL_FAN) { - return mIV_ITEM_KIND_BLUEBELL_FAN; - } - - if (item == ITM_PLUM_FAN) { - return mIV_ITEM_KIND_PLUM_FAN; - } - - if (item == ITM_BAMBOO_FAN) { - return mIV_ITEM_KIND_BAMBOO_FAN; - } - - if (item == ITM_CLOUD_FAN) { - return mIV_ITEM_KIND_CLOUD_FAN; - } - - if (item == ITM_MAPLE_FAN) { - return mIV_ITEM_KIND_MAPLE_FAN; - } - - if (item == ITM_FAN_FAN) { - return mIV_ITEM_KIND_FAN_FAN; - } - - if (item == ITM_FLOWER_FAN) { - return mIV_ITEM_KIND_FLOWER_FAN; - } - - if (item == ITM_LEAF_FAN) { - return mIV_ITEM_KIND_LEAF_FAN; - } - - return mIV_ITEM_KIND_NUM; /* No animation */ + return res; } static int mIV_ChangeIndex_mIV_to_mPlib(s16 idx) { - static s8 data[] = { + static const s8 data[] = { mPlayer_ITEM_KIND_AXE, mPlayer_ITEM_KIND_NET, mPlayer_ITEM_KIND_UMBRELLA00, @@ -358,5 +282,1840 @@ static int mIV_ChangeIndex_mIV_to_mPlib(s16 idx) { } static int mIV_Get_player_item_shape_index(int idx) { - if (idx >= 0 && idx < mIV_ITEM_KIND_NUM) {} + if (idx >= 0 && idx < mIV_ITEM_KIND_NUM) { + int plib_idx = mIV_ChangeIndex_mIV_to_mPlib(idx); + int shape_idx = mPlib_Get_BasicItemShapeIndex_fromItemKind(plib_idx); + + if (shape_idx >= 0 && shape_idx < mPlayer_ITEM_DATA_NUM) { + return shape_idx; + } + + return mPlayer_ITEM_DATA_NUM; + } + + return -1; +} + +static cKF_Skeleton_R_c* mIV_Get_pl_item_skeleton(int idx) { + if (idx >= 0 && idx < mIV_ITEM_KIND_NUM) { + int shape_idx = mIV_Get_player_item_shape_index(idx); + + if (shape_idx >= 0 && shape_idx < mPlayer_ITEM_DATA_NUM) { + u8 data_type = mPlib_Get_Item_DataPointerType(shape_idx); + + if (data_type == mPlayer_ITEM_DATA_TYPE_SKELETON) { + return (cKF_Skeleton_R_c*)mPlib_Get_Item_DataPointer(shape_idx); + } + } + } + + return NULL; +} + +static int mIV_Get_player_com_animation_index(s16 idx) { + return mPlib_Get_BasicPlayerAnimeIndex_fromItemKind(mIV_ChangeIndex_mIV_to_mPlib(idx)); +} + +static cKF_Animation_R_c* mIV_Get_pl_com_anime(s16 idx) { + return mPlib_Get_Pointer_Animation(mIV_Get_player_com_animation_index(idx)); +} + +static int mIV_Get_player_com_part_table_index(s16 idx) { + int plib_idx = mIV_ChangeIndex_mIV_to_mPlib(idx); + int anime_idx = mPlib_Get_BasicPlayerAnimeIndex_fromItemKind(plib_idx); + + return mPlib_Get_BasicPartTableIndex_fromAnimeIndex(anime_idx); +} + +static int mIV_Get_player_item_anime_index(s16 idx) { + int anime_idx = mPlib_Get_BasicItemAnimeIndex_fromItemKind(mIV_ChangeIndex_mIV_to_mPlib(idx)); + + if (anime_idx >= 0 && anime_idx < mPlayer_ITEM_DATA_NUM) { + return anime_idx == mPlayer_ITEM_DATA_BALLOON_GYAZA ? mPlayer_ITEM_DATA_BALLOON_WAIT : anime_idx; + } + + return mPlayer_ITEM_DATA_NUM; +} + +static cKF_Animation_R_c* mIV_Get_pl_item_anime(s16 idx) { + int anime_idx = mIV_Get_player_item_anime_index(idx); + + if (anime_idx >= 0 && anime_idx < mPlayer_ITEM_DATA_NUM) { + return (cKF_Animation_R_c*)mPlib_Get_Item_DataPointer(anime_idx); + } + + return NULL; +} + +static cKF_Animation_R_c* mIV_Get_pl_main_anime(int idx) { + if (idx >= 0 && idx < mIV_ANIM_NUM) { + return mPlib_Get_Pointer_Animation(mIV_Get_pl_main_anime_index(idx)); + } + + return NULL; +} + +static void mIV_pl_load_player_anime(Submenu* submenu, f32 morph_frame) { + mSM_Segment_c* seg = &submenu->overlay->segment; + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + int main_anim_idx = seg->player_main_anime_idx; + int item_anim_idx = seg->player_item_anime_idx; + int com_type = mIV_ITEM_KIND_NUM; + int unused_idx0 = mIV_Get_pl_main_anime_index(main_anim_idx); + cKF_Animation_R_c* anime = mIV_Get_pl_main_anime(main_anim_idx); + int mode; + int bank_idx; + + if (item_anim_idx != mIV_ITEM_KIND_NUM) { + if (main_anim_idx == mIV_ANIM_EAT) { + com_type = mIV_ITEM_KIND_NET; // ? + } else if (main_anim_idx == mIV_ANIM_WALK) { + com_type = item_anim_idx; + } + } + + if (com_type != mIV_ITEM_KIND_NUM) { + mPlib_DMA_player_Part_Table(seg->player_part_table, mIV_Get_player_com_part_table_index(com_type)); + } else { + mPlib_DMA_player_Part_Table(seg->player_part_table, mPlayer_PART_TABLE_NORMAL); + } + + /* Select animation mode */ + if (main_anim_idx == mIV_ANIM_WALK) { + mode = cKF_FRAMECONTROL_REPEAT; + } else { + mode = cKF_FRAMECONTROL_STOP; + } + + /* Load main animation */ + if (main_anim_idx == mIV_ANIM_CHANGE) { + cKF_SkeletonInfo_R_init_standard_setframeandspeedandmorphandmode(&inv_ovl->player_main_keyframe, anime, NULL, + 1.0f, 1.0f, morph_frame, mode); + } else { + cKF_SkeletonInfo_R_init_standard_setframeandspeedandmorphandmode(&inv_ovl->player_main_keyframe, anime, NULL, + 1.0f, 0.5f, morph_frame, mode); + } + + if (com_type != mIV_ITEM_KIND_NUM) { + int unused_anim1 = mIV_Get_player_com_animation_index(com_type); + + anime = mIV_Get_pl_com_anime(com_type); + } + + /* Load com animation */ + if (main_anim_idx == mIV_ANIM_CHANGE) { + cKF_SkeletonInfo_R_init_standard_setframeandspeedandmorphandmode(&inv_ovl->player_com_keyframe, anime, NULL, + 1.0f, 1.0f, morph_frame, mode); + } else { + cKF_SkeletonInfo_R_init_standard_setframeandspeedandmorphandmode(&inv_ovl->player_com_keyframe, anime, NULL, + 1.0f, 0.5f, morph_frame, mode); + } + + /* Play animations */ + cKF_SkeletonInfo_R_combine_play(&inv_ovl->player_main_keyframe, &inv_ovl->player_com_keyframe, + seg->player_part_table); + + seg->player_umbrella_bank_idx ^= 1; + bank_idx = seg->player_umbrella_bank_idx; + if (item_anim_idx == mIV_ITEM_KIND_UMBRELLA) { + mActor_name_t item = Now_Private->equipment; + + seg->umbrella_ids[bank_idx] = + (item >= ITM_UMBRELLA00 && item <= ITM_MY_ORG_UMBRELLA7) ? (item - ITM_UMBRELLA_START) : EMPTY_NO; + } else if (item_anim_idx != mIV_ITEM_KIND_NUM) { + int unused_shape_idx = mIV_Get_player_item_shape_index(item_anim_idx); + cKF_Skeleton_R_c* item_skel = mIV_Get_pl_item_skeleton(item_anim_idx); + int unused_anim_idx; + cKF_Animation_R_c* item_anim; + + if (item_skel != NULL) { + cKF_SkeletonInfo_R_ct(&inv_ovl->item_keyframe, item_skel, NULL, inv_ovl->item_work, inv_ovl->item_morph); + unused_anim_idx = mIV_Get_player_item_anime_index(item_anim_idx); + item_anim = mIV_Get_pl_item_anime(item_anim_idx); + + if (item_anim_idx >= mIV_ITEM_KIND_YELLOW_PINWHEEL && item_anim_idx <= mIV_ITEM_KIND_FANCY_PINWHEEL) { + cKF_SkeletonInfo_R_init(&inv_ovl->item_keyframe, inv_ovl->item_keyframe.skeleton, item_anim, 1.0f, + (f32)item_anim->frames, 1.0f, 7.5f, 0.0f, cKF_FRAMECONTROL_REPEAT, NULL); + } else { + cKF_SkeletonInfo_R_init(&inv_ovl->item_keyframe, inv_ovl->item_keyframe.skeleton, item_anim, 1.0f, + (f32)item_anim->frames, 1.0f, 0.5f, 0.0f, cKF_FRAMECONTROL_REPEAT, NULL); + } + + cKF_SkeletonInfo_R_play(&inv_ovl->item_keyframe); + } + } +} + +static void mIV_pl_shape_init(Submenu* submenu) { + mSM_Segment_c* seg = &submenu->overlay->segment; + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + + cKF_SkeletonInfo_R_ct(&inv_ovl->player_main_keyframe, mPlib_get_player_mdl_p(), NULL, inv_ovl->player_work, + inv_ovl->player_morph); + cKF_SkeletonInfo_R_ct(&inv_ovl->player_com_keyframe, mPlib_get_player_mdl_p(), NULL, inv_ovl->player_work, + inv_ovl->player_morph); + seg->player_umbrella_bank_idx = 0; + seg->player_main_anime_idx = mIV_ANIM_WALK; + seg->player_item_anime_idx = mIV_get_player_item_anime_id(); + seg->change_player_main_anime_idx = mIV_ANIM_WALK; + mIV_pl_load_player_anime(submenu, 0.0f); +} + +static void mIV_pl_eff_move(Submenu* submenu) { + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + mIV_pl_eff_c* effect_p = inv_ovl->pl_eff; + int i; + + for (i = 0; i < mIV_PLAYER_EFFECT_NUM; i++) { + if (effect_p->timer != 0) { + effect_p->timer--; + + if (effect_p->timer > 20) { + chase_f(&effect_p->scale, 0.009f, 0.0009f); + } else { + chase_f(&effect_p->scale, 0.0f, 0.00045f); + } + + effect_p->speed += -0.05f; + effect_p->pos.y += effect_p->speed; + } + + effect_p++; + } + + if (submenu->overlay->segment.player_main_anime_idx == mIV_ANIM_CHANGE) { + f32 cur_frame = inv_ovl->player_main_keyframe.frame_control.current_frame; + int effect_no = (int)cur_frame % mIV_PLAYER_EFFECT_NUM; + s16 angle = (int)cur_frame * DEG2SHORT_ANGLE2(-36.0f); + mIV_pl_eff_c* effect_p = &inv_ovl->pl_eff[effect_no]; + + effect_p->timer = 30; + effect_p->speed = 0.0f; + effect_p->scale = 0.0f; + effect_p->pos.x = 22.0f * sin_s(angle) + RANDOM2_F(5.0f); + effect_p->pos.z = 22.0f * cos_s(angle) + RANDOM2_F(5.0f); + effect_p->pos.y = (35.0f / inv_ovl->player_main_keyframe.frame_control.end_frame) * cur_frame + RANDOM2_F(5.0f); + } +} + +static void mIV_pl_check_anm_change(Submenu* submenu) { + mSM_Segment_c* seg = &submenu->overlay->segment; + f32 morph_frame; + + if (seg->change_player_main_anime_idx != seg->player_main_anime_idx) { + if (seg->change_player_main_anime_idx == mIV_ANIM_EAT) { + morph_frame = 6.0f; + } else if (seg->change_player_main_anime_idx == mIV_ANIM_CHANGE) { + morph_frame = -5.0f; + } else if (seg->change_player_main_anime_idx == mIV_ANIM_CATCH) { + morph_frame = -7.0f; + } else if (seg->player_main_anime_idx == mIV_ANIM_CHANGE) { + morph_frame = -5.0f; + } else if (seg->player_main_anime_idx == mIV_ANIM_EAT) { + morph_frame = -5.0f; + } else { + seg->player_item_anime_idx = mIV_get_player_item_anime_id(); + morph_frame = -8.0f; + } + + seg->player_main_anime_idx = seg->change_player_main_anime_idx; + mIV_pl_load_player_anime(submenu, morph_frame); + } +} + +static void mIV_pl_shape_move(Submenu* submenu) { + mSM_Segment_c* seg = &submenu->overlay->segment; + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + int anim_state = cKF_SkeletonInfo_R_combine_play(&inv_ovl->player_main_keyframe, &inv_ovl->player_com_keyframe, + seg->player_part_table); + + if (seg->player_item_anime_idx != mIV_ITEM_KIND_NUM && + mIV_Get_pl_item_skeleton(seg->player_item_anime_idx) != NULL) { + cKF_SkeletonInfo_R_play(&inv_ovl->item_keyframe); + } + + if (seg->player_anime_timer > 0) { + seg->player_anime_timer--; + } + + mIV_pl_eff_move(submenu); + if (seg->player_main_anime_idx == mIV_ANIM_CATCH) { + seg->player_anime_timer = 8; + } else if (seg->player_main_anime_idx == mIV_ANIM_CHANGE) { + seg->player_anime_timer = 5; + + if (anim_state == cKF_STATE_STOPPED) { + seg->change_player_main_anime_idx = mIV_ANIM_WALK; + } + } else if (seg->player_main_anime_idx == mIV_ANIM_EAT) { + seg->player_anime_timer = 5; + + if (anim_state == cKF_STATE_STOPPED) { + seg->change_player_main_anime_idx = mIV_ANIM_WALK; + } else if (cKF_FrameControl_passCheck_now(&inv_ovl->player_main_keyframe.frame_control, 17.0f)) { + sAdo_SysTrgStart(NA_SE_EAT); + } + } + + mIV_pl_check_anm_change(submenu); +} + +static void mIV_pl_shape_item_draw_net(Submenu* submenu, GAME* game) { + cKF_SkeletonInfo_R_c* item_kf = &submenu->overlay->inventory_ovl->item_keyframe; + Mtx* mtx = (Mtx*)GRAPH_ALLOC_TYPE(game->graph, Mtx, item_kf->skeleton->num_shown_joints); + + if (mtx != NULL) { + cKF_Si3_draw_R_SV(game, item_kf, mtx, NULL, NULL, NULL); + } +} + +static void mIV_pl_shape_item_draw_axe(Submenu* submenu, GAME* game) { + int shape_idx = mIV_Get_player_item_shape_index(submenu->overlay->segment.player_item_anime_idx); + Gfx* axe_gfx = (Gfx*)mPlib_Get_Item_DataPointer(shape_idx); + + if (axe_gfx != NULL) { + OPEN_DISP(game->graph); + + gSPDisplayList(NEXT_POLY_OPA_DISP, axe_gfx); + + CLOSE_DISP(game->graph); + } +} + +typedef struct umbrella_data_s { + Gfx* e_model; + Gfx* kasa_model; +} mIV_umbrella_data_c; + +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 mIV_pl_shape_item_draw_umbrella(Submenu* submenu, GAME* game) { + // clang-format off + static mIV_umbrella_data_c umb_data[] = { + { 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 }, + }; + // clang-format on + GRAPH* graph = game->graph; + int umbrella_idx = submenu->overlay->segment.umbrella_ids[submenu->overlay->segment.player_umbrella_bank_idx]; + mIV_umbrella_data_c* umb_data_p = &umb_data[umbrella_idx]; + int umbrella_item_kind = mPlayer_ITEM_KIND_UMBRELLA00 + umbrella_idx; + + _texture_z_light_fog_prim_npc(graph); + + OPEN_POLY_OPA_DISP(graph); + + gSPLoadGeometryMode(POLY_OPA_DISP++, G_ZBUFFER | G_SHADE | G_FOG | G_LIGHTING | G_SHADING_SMOOTH); + + Matrix_RotateY(DEG2SHORT_ANGLE2(-90.0f), 1); + Matrix_translate(800.0f, 0.0f, 0.0f, 1); + + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, umb_data_p->e_model); + Matrix_translate(4000.0f, 0.0f, 0.0f, 1); + + /* Handle custom designs */ + if (umbrella_item_kind >= mPlayer_ITEM_KIND_ORG_UMBRELLA00) { + int org_idx = (umbrella_item_kind - mPlayer_ITEM_KIND_ORG_UMBRELLA00) & 7; + + gSPSegment(POLY_OPA_DISP++, G_MWO_SEGMENT_8, mNW_PaletteIdx2Palette(Now_Private->my_org[org_idx].palette)); + gSPSegment(POLY_OPA_DISP++, G_MWO_SEGMENT_9, Now_Private->my_org[org_idx].design.data); + } + + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, umb_data_p->kasa_model); + + CLOSE_POLY_OPA_DISP(graph); +} + +extern Gfx inv_uki_model[]; // rod +extern Gfx inv_uki2_model[]; // golden rod + +static void mIV_pl_shape_item_draw_rod(Submenu* submenu, GAME* game) { + mSM_Segment_c* seg = &submenu->overlay->segment; + cKF_SkeletonInfo_R_c* item_kf = &submenu->overlay->inventory_ovl->item_keyframe; + Mtx* mtx = (Mtx*)GRAPH_ALLOC_TYPE(game->graph, Mtx, item_kf->skeleton->num_shown_joints); + + if (mtx != NULL) { + xyz_t pos; + + Matrix_Position_VecZ(&pos, 1500.0f); + cKF_Si3_draw_R_SV(game, item_kf, mtx, NULL, NULL, NULL); + Matrix_put(&submenu->overlay->inventory_ovl->item_mtx); + Matrix_translate(0.0f, 0.0f, 1500.0f, 1); + Matrix_RotateZ(DEG2SHORT_ANGLE2(24.219360f), 1); // 0x1139 + Matrix_RotateX(DEG2SHORT_ANGLE2(65.494995f), 1); // 0x2E93 + Matrix_RotateY(DEG2SHORT_ANGLE2(79.634399f), 1); // 0x38A1 + Matrix_translate(0.0f, -500.0f, 0.0f, 1); + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (seg->player_item_anime_idx == mIV_ITEM_KIND_GOLD_ROD) { + gSPDisplayList(NEXT_POLY_OPA_DISP, inv_uki2_model); + } else { + gSPDisplayList(NEXT_POLY_OPA_DISP, inv_uki_model); + } + + CLOSE_DISP(game->graph); + } +} + +static void mIV_pl_shape_item_draw_scoop(Submenu* submenu, GAME* game) { + int shape_idx = mIV_Get_player_item_shape_index(submenu->overlay->segment.player_item_anime_idx); + Gfx* scoop_gfx = (Gfx*)mPlib_Get_Item_DataPointer(shape_idx); + + if (scoop_gfx != NULL) { + OPEN_DISP(game->graph); + + gSPDisplayList(NEXT_POLY_OPA_DISP, scoop_gfx); + + CLOSE_DISP(game->graph); + } +} + +static int mIV_pl_shape_item_draw_balloon_Before(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, + Gfx** joint_shape, u8* joint_flags, void* arg, s_xyz* joint_rot, + xyz_t* joint_pos) { + switch (joint_idx) { + case 1: + case 2: + case 3: { + OPEN_DISP(game->graph); + + gDPPipeSync(NEXT_POLY_OPA_DISP); + gDPSetTexEdgeAlpha(NEXT_POLY_OPA_DISP, 80); + + CLOSE_DISP(game->graph); + break; + } + } + + return TRUE; +} + +static int mIV_pl_shape_item_draw_balloon_After(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, + Gfx** joint_shape, u8* joint_flags, void* arg, s_xyz* joint_rot, + xyz_t* joint_pos) { + switch (joint_idx) { + case 1: + case 2: + case 3: { + OPEN_DISP(game->graph); + + gDPPipeSync(NEXT_POLY_OPA_DISP); + gDPSetTexEdgeAlpha(NEXT_POLY_OPA_DISP, 144); + + CLOSE_DISP(game->graph); + break; + } + } + + return TRUE; +} + +static void mIV_pl_shape_item_draw_balloon(Submenu* submenu, GAME* game) { + cKF_SkeletonInfo_R_c* item_kf = &submenu->overlay->inventory_ovl->item_keyframe; + Mtx* mtx = (Mtx*)GRAPH_ALLOC_TYPE(game->graph, Mtx, item_kf->skeleton->num_shown_joints); + + if (mtx != NULL) { + static xyz_t dummy_eye = { 0.0f, 0.0f, 1.0f }; + static xyz_t dummy_light_direction = { -SQRT_3_OVER_3_F, SQRT_3_OVER_3_F, SQRT_3_OVER_3_F }; + GRAPH* graph = game->graph; + Hilite* hilite; + + OPEN_DISP(graph); + + SET_POLY_OPA_DISP( + HiliteReflect_new(&ZeroVec, &dummy_eye, &dummy_light_direction, graph, NOW_POLY_OPA_DISP, &hilite)); + + CLOSE_DISP(graph); + + cKF_Si3_draw_R_SV(game, item_kf, mtx, &mIV_pl_shape_item_draw_balloon_Before, + &mIV_pl_shape_item_draw_balloon_After, NULL); + } +} + +static void mIV_pl_shape_item_draw_windmill(Submenu* submenu, GAME* game) { + cKF_SkeletonInfo_R_c* item_kf = &submenu->overlay->inventory_ovl->item_keyframe; + Mtx* mtx = (Mtx*)GRAPH_ALLOC_TYPE(game->graph, Mtx, item_kf->skeleton->num_shown_joints); + + if (mtx != NULL) { + cKF_Si3_draw_R_SV(game, item_kf, mtx, NULL, NULL, NULL); + } +} + +static void mIV_pl_shape_item_draw_fan(Submenu* submenu, GAME* game) { + int shape_idx = mIV_Get_player_item_shape_index(submenu->overlay->segment.player_item_anime_idx); + Gfx* fan_gfx = (Gfx*)mPlib_Get_Item_DataPointer(shape_idx); + + if (fan_gfx != NULL) { + OPEN_DISP(game->graph); + + gSPDisplayList(NEXT_POLY_OPA_DISP, fan_gfx); + + CLOSE_DISP(game->graph); + } +} + +static int mIV_pl_shape_after_draw(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape, + u8* joint_flags, void* arg, s_xyz* joint_rot, xyz_t* joint_pos) { + switch (joint_idx) { + case 20: { + Submenu* submenu = (Submenu*)arg; + + if (submenu->overlay->segment.player_item_anime_idx != mIV_ITEM_KIND_NUM) { + Matrix_get(&submenu->overlay->inventory_ovl->item_mtx); + } + + break; + } + + case 16: { + Submenu* submenu = (Submenu*)arg; + + if (submenu->overlay->segment.player_main_anime_idx == mIV_ANIM_EAT) { + Matrix_get(&submenu->overlay->inventory_ovl->food_mtx); + } + + break; + } + } + + return TRUE; +} + +typedef void (*mIV_PL_EQUIP_ITEM_DRAW_PROC)(Submenu*, GAME*); + +static void mIV_pl_equip_item_draw(Submenu* submenu, GAME* game) { + // clang-format off + static mIV_PL_EQUIP_ITEM_DRAW_PROC proc[mIV_ITEM_KIND_NUM] = { + &mIV_pl_shape_item_draw_axe, + &mIV_pl_shape_item_draw_net, + &mIV_pl_shape_item_draw_umbrella, + &mIV_pl_shape_item_draw_rod, + &mIV_pl_shape_item_draw_scoop, + &mIV_pl_shape_item_draw_axe, + &mIV_pl_shape_item_draw_net, + &mIV_pl_shape_item_draw_rod, + &mIV_pl_shape_item_draw_scoop, + &mIV_pl_shape_item_draw_balloon, + &mIV_pl_shape_item_draw_balloon, + &mIV_pl_shape_item_draw_balloon, + &mIV_pl_shape_item_draw_balloon, + &mIV_pl_shape_item_draw_balloon, + &mIV_pl_shape_item_draw_balloon, + &mIV_pl_shape_item_draw_balloon, + &mIV_pl_shape_item_draw_balloon, + &mIV_pl_shape_item_draw_windmill, + &mIV_pl_shape_item_draw_windmill, + &mIV_pl_shape_item_draw_windmill, + &mIV_pl_shape_item_draw_windmill, + &mIV_pl_shape_item_draw_windmill, + &mIV_pl_shape_item_draw_windmill, + &mIV_pl_shape_item_draw_windmill, + &mIV_pl_shape_item_draw_windmill, + &mIV_pl_shape_item_draw_fan, + &mIV_pl_shape_item_draw_fan, + &mIV_pl_shape_item_draw_fan, + &mIV_pl_shape_item_draw_fan, + &mIV_pl_shape_item_draw_fan, + &mIV_pl_shape_item_draw_fan, + &mIV_pl_shape_item_draw_fan, + &mIV_pl_shape_item_draw_fan, + &mIV_pl_shape_item_draw_axe, + &mIV_pl_shape_item_draw_axe, + &mIV_pl_shape_item_draw_axe, + &mIV_pl_shape_item_draw_axe, + &mIV_pl_shape_item_draw_axe, + &mIV_pl_shape_item_draw_axe, + &mIV_pl_shape_item_draw_axe, + }; + // clang-format on + + mSM_Segment_c* seg = &submenu->overlay->segment; + + if (seg->player_item_anime_idx != mIV_ITEM_KIND_NUM) { + GRAPH* graph = game->graph; + + Matrix_put(&submenu->overlay->inventory_ovl->item_mtx); + + OPEN_DISP(graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + CLOSE_DISP(graph); + + (*proc[seg->player_item_anime_idx])(submenu, game); + } +} + +extern Gfx apple_DL_mode[]; +extern Gfx nuts_DL_mode[]; +extern Gfx pear_DL_mode[]; +extern Gfx peach_DL_mode[]; +extern Gfx orange_DL_mode[]; +extern Gfx matutake_DL_mode[]; +extern Gfx obj_item_cocoT_mat_model[]; +extern Gfx kabu_DL_mode[]; + +extern Gfx apple_DL_vtx[]; +extern Gfx nuts_DL_vtx[]; +extern Gfx pear_DL_vtx[]; +extern Gfx peach_DL_vtx[]; +extern Gfx orange_DL_vtx[]; +extern Gfx matutake_DL_vtx[]; +extern Gfx obj_shop_candy_modelT[]; +extern Gfx obj_item_cocoT_gfx_model[]; +extern Gfx kabu_DL_vtx[]; + +static void mIV_pl_food_item_draw(Submenu* submenu, GAME* game) { + // clang-format off + static Gfx* food_mode[] = { + apple_DL_mode, + nuts_DL_mode, + pear_DL_mode, + peach_DL_mode, + orange_DL_mode, + matutake_DL_mode, + NULL, + obj_item_cocoT_mat_model, + kabu_DL_mode, + }; + // clang-format on + + // clang-format off + static Gfx* food_model[] = { + apple_DL_vtx, + nuts_DL_vtx, + pear_DL_vtx, + peach_DL_vtx, + orange_DL_vtx, + matutake_DL_vtx, + obj_shop_candy_modelT, + obj_item_cocoT_gfx_model, + kabu_DL_vtx, + }; + // clang-format on + + if (submenu->overlay->segment.player_main_anime_idx == mIV_ANIM_EAT) { + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + f32 cur_frame = inv_ovl->player_main_keyframe.frame_control.current_frame; + f32 rate; + GRAPH* graph = game->graph; + int food_idx = inv_ovl->food_idx; + MtxF* mtxf; + f32 scale; + f32 tmp; + xyz_t l_ofs; + xyz_t w_ofs; + + if (cur_frame < 3.0f || cur_frame >= 46.0f) { + return; + } + + if (cur_frame < 12.0f) { + tmp = (cur_frame - 3.0f) * (1.0f / 9.0f); + l_ofs.x = (tmp * 1.5f + 12.5f) * 100.0f; + l_ofs.y = (tmp * 3.0f + 5.0f) * 100.0f; + l_ofs.z = (tmp * -7.0f) * 100.0f; + } else { + tmp = (cur_frame - 12.0f) * (1.0f / 34.0f); + l_ofs.x = (tmp * -5.0f + 14.0f) * 100.0f; + l_ofs.y = (tmp * -11.75f + 8.0f) * 100.0f; + l_ofs.z = (tmp * 6.0f + -7.0f) * 100.0f; + } + + if (cur_frame < 27.0f) { + scale = 1.0f; + } else { + scale = 1.0f - (cur_frame - 27.0f) * (1.0f / 19.0f); + } + + scale *= 0.01f; + + _texture_z_light_fog_prim(graph); + Matrix_put(&submenu->overlay->inventory_ovl->food_mtx); + Matrix_Position(&l_ofs, &w_ofs); + + /* Update draw matrix */ + mtxf = get_Matrix_now(); + + /* Scale */ + mtxf->xx = scale; + mtxf->yy = scale; + mtxf->zz = scale; + + mtxf->yx = 0.0f; + mtxf->zx = 0.0f; + mtxf->xy = 0.0f; + mtxf->zy = 0.0f; + mtxf->xz = 0.0f; + mtxf->yz = 0.0f; + + /* Position */ + mtxf->xw = w_ofs.x; + mtxf->yw = w_ofs.y - scale * 884.0f; + mtxf->zw = w_ofs.z; + + OPEN_DISP(graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (food_mode[food_idx] != NULL) { + gSPDisplayList(NEXT_POLY_OPA_DISP, food_mode[food_idx]); + } + + gSPDisplayList(NEXT_POLY_OPA_DISP, food_model[food_idx]); + + CLOSE_DISP(graph); + } +} + +static void mIV_pl_shape_draw(Submenu* submenu, GAME* game) { + mSM_Segment_c* seg = &submenu->overlay->segment; + cKF_SkeletonInfo_R_c* main_kf = &submenu->overlay->inventory_ovl->player_main_keyframe; + GRAPH* graph = game->graph; + Mtx* mtx = (Mtx*)GRAPH_ALLOC_TYPE(graph, Mtx, main_kf->skeleton->num_shown_joints); + u8* eye_tex_p = NULL; + u8* mouth_tex_p = NULL; + int anim_idx = mIV_Get_pl_main_anime_index(seg->player_main_anime_idx); + u8* eye_tex_anim_p = mPlib_Get_PlayerEyeTexAnimation_p(anim_idx); + u8* mouth_tex_anim_p = mPlib_Get_PlayerMouthTexAnimation_p(anim_idx); + + if (mtx != NULL) { + OPEN_DISP(graph); + + if (eye_tex_anim_p != NULL || mouth_tex_anim_p != NULL) { + cKF_FrameControl_c* frame_ctrl = &main_kf->frame_control; + f32 cur_frame = frame_ctrl->current_frame; + f32 max_frame = frame_ctrl->max_frames; + + if (1.0f <= cur_frame && cur_frame <= max_frame) { + int tex_anim_idx = (int)(cur_frame - 1.0f); + + if (eye_tex_anim_p != NULL) { + eye_tex_p = mPlib_Get_eye_tex_p(eye_tex_anim_p[tex_anim_idx]); + } + + if (mouth_tex_anim_p != NULL) { + mouth_tex_p = mPlib_Get_mouth_tex_p(mouth_tex_anim_p[tex_anim_idx]); + } + } + } + + /* Load default textures if no animation */ + if (eye_tex_p == NULL) { + eye_tex_p = mPlib_Get_eye_tex_p(0); + } + + if (mouth_tex_p == NULL) { + mouth_tex_p = mPlib_Get_mouth_tex_p(0); + } + + Matrix_scale(0.01f, 0.01f, 0.01f, 0); + + gDPPipeSync(NEXT_POLY_OPA_DISP); + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + _texture_z_light_fog_prim(graph); + + /* Set dynamic player data */ + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_8, eye_tex_p); + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_9, mouth_tex_p); + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_A, mPlib_get_player_tex_p(game)); + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_B, mPlib_get_player_pallet_p(game)); + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_C, mPlib_get_player_face_pallet_p(game)); + + CLOSE_DISP(graph); + + /* Draw skeleton */ + cKF_Si3_draw_R_SV(game, main_kf, mtx, NULL, &mIV_pl_shape_after_draw, submenu); + mIV_pl_equip_item_draw(submenu, game); + mIV_pl_food_item_draw(submenu, game); + } +} + +extern Gfx ef_takurami01_menu_render_mode[]; +extern Gfx ef_takurami01_kira_modelT[]; + +static void mIV_pl_eff_draw(GRAPH* graph, Submenu* submenu) { + int i; + mIV_pl_eff_c* pl_eff; + + _texture_z_light_fog_prim(graph); + OPEN_DISP(graph); + + pl_eff = submenu->overlay->inventory_ovl->pl_eff; + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_8, ef_takurami01_menu_render_mode); + for (i = 0; i < mIV_PLAYER_EFFECT_NUM; i++) { + if (pl_eff->timer != 0) { + Matrix_translate(pl_eff->pos.x, pl_eff->pos.y, pl_eff->pos.z, 0); + Matrix_scale(pl_eff->scale, pl_eff->scale, pl_eff->scale, 1); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(NEXT_POLY_OPA_DISP, ef_takurami01_kira_modelT); + } + + pl_eff++; + } + + CLOSE_DISP(graph); +} + +extern Gfx ef_shadow_in_modelT[]; + +static void mIV_pl_shadow_draw(GAME_PLAY* play, ACTOR* actorx) { + if (actorx != NULL) { + GRAPH* graph = play->game.graph; + + Matrix_scale(actorx->shape_info.shadow_size_x * 0.001f, 1.0f, actorx->shape_info.shadow_size_z * 0.001f, 0); + _texture_z_light_fog_prim(graph); + + OPEN_DISP(graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(NEXT_POLY_OPA_DISP, 0, 255, 10, 0, 40, 150); + gSPDisplayList(NEXT_POLY_OPA_DISP, ef_shadow_in_modelT); + + CLOSE_DISP(graph); + } +} + +static void mIV_set_player(Submenu* submenu, GRAPH* graph, GAME_PLAY* play, f32 pos_x, f32 pos_y) { + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + + if (player != NULL) { + int x = (int)pos_x + 20; + int y = (int)-pos_y + 9; + /* NOTE: 128.0 and 0.0 are doubles here */ + int draw_flag = (128.0 + x >= 0.0) && (x < 320); + + OPEN_DISP(graph); + + gDPPipeSync(NEXT_POLY_OPA_DISP); + + CLOSE_DISP(graph); + + if (draw_flag) { + submenu->overlay->change_view_proc(graph, 330.0f, 25.0f, x * 4.0f, y * 4.0f, 0x900, 256, 256); + } + + mIV_pl_check_anm_change(submenu); + if (draw_flag) { + mIV_pl_shadow_draw(play, (ACTOR*)player); + mIV_pl_shape_draw(submenu, (GAME*)play); + mIV_pl_eff_draw(graph, submenu); + } + + submenu->overlay->setup_view_proc(submenu, graph, FALSE); + } +} + +static void mIV_move_Move(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + submenu->overlay->move_Move_proc(submenu, menu_info); +} + +static void mIV_move_Play(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mSM_Control_c* ctrl = &submenu->overlay->menu_control; + mTG_Ovl_c* tag_ovl; + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + + if (menu_info->open_flag == FALSE) { + int unselected_num; + + tag_ovl = submenu->overlay->tag_ovl; + if (menu_info->data0 == mSM_IV_OPEN_SEND_MAIL) { + for (unselected_num = 0; unselected_num < mPr_INVENTORY_MAIL_COUNT; unselected_num++) { + if (inv_ovl->selectable_mail_bitfield & (1 << unselected_num)) { + break; + } + } + + if (unselected_num == mPr_INVENTORY_MAIL_COUNT) { + unselected_num = 0; + } + } else { + for (unselected_num = 0; unselected_num < mPr_POCKETS_SLOT_COUNT; unselected_num++) { + if (inv_ovl->selectable_item_bitfield & (1 << unselected_num)) { + break; + } + } + + if (unselected_num == mPr_POCKETS_SLOT_COUNT) { + unselected_num = 0; + } + } + + switch (menu_info->data0) { + case mSM_IV_OPEN_NORMAL: + case mSM_IV_OPEN_SELL: + case mSM_IV_OPEN_GIVE: + case mSM_IV_OPEN_TAKE: + case mSM_IV_OPEN_PUTIN_FTR: + case mSM_IV_OPEN_MINIDISK: + case mSM_IV_OPEN_SHRINE: + case mSM_IV_OPEN_CURATOR: + case mSM_IV_OPEN_16: + submenu->overlay->tag_ovl->chg_tag_func_proc(submenu, mTG_TABLE_ITEM, mTG_TYPE_NONE, unselected_num, + 0.0f, 0.0f); + break; + case mSM_IV_OPEN_EXCHANGE: + submenu->overlay->tag_ovl->chg_tag_func_proc(submenu, mTG_TABLE_ITEM, mTG_TYPE_NONE, unselected_num, + 0.0f, 0.0f); + submenu->overlay->hand_ovl->info.pos[0] += -5.0f; + submenu->overlay->hand_ovl->info.pos[1] += 12.0f; + break; + case mSM_IV_OPEN_QUEST: + submenu->overlay->tag_ovl->chg_tag_func_proc(submenu, mTG_TABLE_ITEM, mTG_TYPE_NONE, unselected_num, + 0.0f, 0.0f); + tag_ovl->item_name_wait_time = 0; + submenu->overlay->tag_ovl->chg_tag_func_proc(submenu, mTG_TABLE_ITEM, mTG_TYPE_QUEST_ITEM, 0, + tag_ovl->tags[0].pos[0], tag_ovl->tags[0].pos[1]); + break; + case mSM_IV_OPEN_SEND_MAIL: + submenu->overlay->tag_ovl->chg_tag_func_proc(submenu, mTG_TABLE_MAIL, mTG_TYPE_NONE, unselected_num, + 0.0f, 0.0f); + break; + } + + menu_info->open_flag = TRUE; + } else if (inv_ovl->page_move_timer != 0) { + int y; + + inv_ovl->page_move_timer--; + y = 100.0f * sinf_table((f32)inv_ovl->page_move_timer * 0.078539819f); + menu_info->position[1] = (f32)y; + + if (inv_ovl->page_move_timer == 20) { + if (inv_ovl->page_order[2] == inv_ovl->next_page_id) { + inv_ovl->page_order[2] = inv_ovl->page_order[1]; + } + + inv_ovl->page_order[1] = inv_ovl->page_order[0]; + inv_ovl->page_order[0] = inv_ovl->next_page_id; + } else if (inv_ovl->page_move_timer == 0) { + menu_info->position[1] = 0.0f; + submenu->overlay->hand_ovl->set_hand_func(submenu); + } + } else { + ctrl->tag_move_func(submenu, menu_info); + } +} + +static void mIV_move_Wait(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mSM_Control_c* ctrl = &submenu->overlay->menu_control; + mSM_MenuInfo_c* next_menu_info = &submenu->overlay->menu_info[menu_info->next_menu_type]; + + if (next_menu_info->menu_type == mSM_OVL_NEEDLEWORK) { + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + + mIV_pl_shape_move(submenu); + ctrl->animation_flag = TRUE; + if (inv_ovl->original_flag) { + if (next_menu_info->proc_status == mSM_OVL_PROC_MOVE && + next_menu_info->next_proc_status == mSM_OVL_PROC_END) { + submenu->overlay->move_chg_base_proc(menu_info, mSM_MOVE_OUT_RIGHT); + } + } else if (next_menu_info->proc_status == mSM_OVL_PROC_END) { + mTG_Ovl_c* tag_ovl; + mTG_tag_c* tag; + int i; + + menu_info->proc_status = mSM_OVL_PROC_PLAY; + tag_ovl = submenu->overlay->tag_ovl; + tag = tag_ovl->tags; + + for (i = 0; i < mTG_TAG_NUM; i++) { + tag->type = mTG_TYPE_NONE; + tag++; + } + + tag_ovl->sel_tag_idx = -1; + tag_ovl->ret_tag_idx = -1; + inv_ovl->wc_flag = FALSE; + + submenu->overlay->tag_ovl->chg_tag_func_proc(submenu, mTG_TABLE_INVENTORY_WC_ORG, mTG_TYPE_NONE, 0, 0.0f, + 0.0f); + submenu->overlay->tag_ovl->init_tag_data_item_win_proc(submenu); + } + } else if (next_menu_info->proc_status == mSM_OVL_PROC_MOVE && + next_menu_info->next_proc_status == mSM_OVL_PROC_END) { + submenu->overlay->move_chg_base_proc(menu_info, mSM_MOVE_IN_LEFT); + submenu->overlay->tag_ovl->init_tag_data_item_win_proc(submenu); + } +} + +static void mIV_move_Obey(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mSM_MenuInfo_c* next_menu_info = &submenu->overlay->menu_info[menu_info->next_menu_type]; + + if (next_menu_info->proc_status == mSM_OVL_PROC_MOVE) { + if (next_menu_info->next_proc_status == mSM_OVL_PROC_END) { + int move_dir; + + if (menu_info->data0 == mSM_IV_OPEN_CPMAIL) { + move_dir = mSM_MOVE_OUT_LEFT; + sAdo_SysTrgStart(NA_SE_31); + } else { + move_dir = mSM_MOVE_OUT_RIGHT; + } + + submenu->overlay->move_chg_base_proc(menu_info, move_dir); + } else { + menu_info->position[0] = next_menu_info->position[0]; + menu_info->position[1] = next_menu_info->position[1]; + } + } +} + +static void mIV_move_End(Submenu* submenu, mSM_MenuInfo_c* menu_info) { + mBGMPsComp_pause(mBGM_PAUSE_STOP); + submenu->overlay->move_End_proc(submenu, menu_info); +} + +typedef void (*mIV_OVL_MOVE_PROC)(Submenu*, mSM_MenuInfo_c*); + +static void mIV_inventory_ovl_move(Submenu* submenu) { + // clang-format off + static mIV_OVL_MOVE_PROC ovl_move_proc[] = { + &mIV_move_Move, + &mIV_move_Play, + &mIV_move_Wait, + &mIV_move_Obey, + &mIV_move_End, + }; + // clang-format on + + mSM_Control_c* ctrl = &submenu->overlay->menu_control; + mSM_MenuInfo_c* menu_info = &submenu->overlay->menu_info[mSM_OVL_INVENTORY]; + + menu_info->pre_move_func(submenu); + (*ovl_move_proc[menu_info->proc_status])(submenu, menu_info); + + switch (menu_info->proc_status) { + case mSM_OVL_PROC_PLAY: { + mIV_pl_shape_move(submenu); + ctrl->animation_flag = TRUE; + + /** + * Debug controls on controller #2 + * - C stick left: +1,000 added to wallet + * - C stick right: fill all free inventory spaces with 30,000 bell bags + * - C stick down: fill first 4 free inventory slots with all tools + */ + if (menu_info->data0 == mSM_IV_OPEN_NORMAL && ZURUMODE2_ENABLED() && zurumode_flag != 0) { + if ((gamePT->pads[PAD1].on.button & BUTTON_CLEFT) == BUTTON_CLEFT) { + u32 wallet = Now_Private->inventory.wallet + 1000; + + if (wallet > mPr_WALLET_MAX) { + wallet = mPr_WALLET_MAX; + } + + Now_Private->inventory.wallet = wallet; + submenu->overlay->inventory_ovl->disp_money = wallet; + } + + if ((gamePT->pads[PAD1].on.button & BUTTON_CDOWN) == BUTTON_CDOWN) { + int i; + + for (i = 0; i < MONEY_NUM; i++) { + int idx = mPr_GetPossessionItemIdxWithCond(Now_Private, EMPTY_NO, mPr_ITEM_COND_NORMAL); + + if (idx == -1) { + break; + } + + mPr_SetPossessionItem(Now_Private, idx, ITM_TOOL_START + i, mPr_ITEM_COND_NORMAL); + } + } + + if ((gamePT->pads[PAD1].on.button & BUTTON_CRIGHT) == BUTTON_CRIGHT) { + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + int idx = mPr_GetPossessionItemIdxWithCond(Now_Private, EMPTY_NO, mPr_ITEM_COND_NORMAL); + + if (idx == -1) { + break; + } + + mPr_SetPossessionItem(Now_Private, idx, ITM_MONEY_30000, mPr_ITEM_COND_NORMAL); + } + } + } + break; + } + + case mSM_OVL_PROC_MOVE: { + ctrl->animation_flag = FALSE; + break; + } + } +} + +extern Gfx inv_mwin_mode[]; +extern Gfx inv_sakana_model[]; +extern Gfx inv_mwin_model[]; +extern Gfx inv_mushi_model[]; +extern Gfx inv_sakana_part_model[]; +extern Gfx inv_mushi_part_model[]; +extern Gfx inv_sakana_scroll_mode[]; +extern Gfx inv_mushi_scroll_mode[]; + +static void mIV_set_base_frame_dl(Submenu* submenu, GAME_PLAY* play, GRAPH* graph, int page, int scroll_flag, f32 pos_x, + f32 pos_y) { + static Gfx* base_frame[] = { inv_sakana_model, inv_mwin_model, inv_mushi_model }; + static Gfx* part_frame[] = { inv_sakana_part_model, inv_mwin_model, inv_mushi_part_model }; + static Gfx* scroll_set[] = { inv_sakana_scroll_mode, NULL, inv_mushi_scroll_mode }; + + Matrix_scale(16.0f, 16.0f, 1.0f, 0); + Matrix_translate(pos_x, pos_y, 140.0f, 1); + + OPEN_POLY_OPA_DISP(graph); + + gSPDisplayList(POLY_OPA_DISP++, inv_mwin_mode); + gSPMatrix(POLY_OPA_DISP++, _Matrix_to_Mtx_new(graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (scroll_flag) { + int tex_x; + int tex_y; + + if (page == mIV_PAGE_INVENTORY) { + gDPLoadTLUT_Dolphin(POLY_OPA_DISP++, 14, 16, 1, mSM_Get_ground_pallet_p(play)); + gDPSetTextureImage_Dolphin(POLY_OPA_DISP++, G_IM_FMT_CI, G_IM_SIZ_4b, 32, 32, mSM_Get_ground_tex_p(play)); + gDPSetTile_Dolphin(POLY_OPA_DISP++, G_DOLPHIN_TLUT_DEFAULT_MODE, G_TX_RENDERTILE, 14, GX_REPEAT, GX_REPEAT, + GX_CLAMP, GX_CLAMP); + } else { + gSPDisplayList(POLY_OPA_DISP++, scroll_set[page]); + } + + gDPTileSync(POLY_OPA_DISP++); + tex_x = (int)-submenu->overlay->menu_control.texture_pos[0] & 0x7F; + tex_y = (int)-submenu->overlay->menu_control.texture_pos[1] & 0x7F; + gDPSetTileSize(POLY_OPA_DISP++, G_TX_RENDERTILE, tex_x, tex_y, tex_x + (31 << 2), tex_y + (31 << 2)); + gSPDisplayList(POLY_OPA_DISP++, base_frame[page]); + } else { + gSPDisplayList(POLY_OPA_DISP++, part_frame[page]); + } + + CLOSE_POLY_OPA_DISP(graph); +} + +/* letter slots */ +extern Gfx inv_mwin_1aT_model[]; +extern Gfx inv_mwin_2aT_model[]; +extern Gfx inv_mwin_3aT_model[]; +extern Gfx inv_mwin_4aT_model[]; +extern Gfx inv_mwin_5aT_model[]; +extern Gfx inv_mwin_6aT_model[]; +extern Gfx inv_mwin_7aT_model[]; +extern Gfx inv_mwin_8aT_model[]; +extern Gfx inv_mwin_9aT_model[]; +extern Gfx inv_mwin_10aT_model[]; + +/* item slots */ +extern Gfx inv_mwin_1bT_model[]; +extern Gfx inv_mwin_2bT_model[]; +extern Gfx inv_mwin_3bT_model[]; +extern Gfx inv_mwin_4bT_model[]; +extern Gfx inv_mwin_5bT_model[]; +extern Gfx inv_mwin_6bT_model[]; +extern Gfx inv_mwin_7bT_model[]; +extern Gfx inv_mwin_8bT_model[]; +extern Gfx inv_mwin_9bT_model[]; +extern Gfx inv_mwin_10bT_model[]; +extern Gfx inv_mwin_11bT_model[]; +extern Gfx inv_mwin_12bT_model[]; +extern Gfx inv_mwin_13bT_model[]; +extern Gfx inv_mwin_14bT_model[]; +extern Gfx inv_mwin_15bT_model[]; + +extern Gfx inv_mwin_item_frame_mode[]; +extern Gfx inv_mwin_kuni_model[]; +extern Gfx inv_mwin_kuni2_model[]; + +static void mIV_set_normal_frame_dl(Submenu* submenu, GAME_PLAY* play, GRAPH* graph, f32 pos_x, f32 pos_y) { + static Gfx* item_frame_disp[] = { + inv_mwin_1bT_model, inv_mwin_2bT_model, inv_mwin_3bT_model, inv_mwin_4bT_model, inv_mwin_5bT_model, + inv_mwin_6bT_model, inv_mwin_7bT_model, inv_mwin_8bT_model, inv_mwin_9bT_model, inv_mwin_10bT_model, + inv_mwin_11bT_model, inv_mwin_12bT_model, inv_mwin_13bT_model, inv_mwin_14bT_model, inv_mwin_15bT_model, + }; + + static Gfx* letter_frame_disp[] = { + inv_mwin_1aT_model, inv_mwin_2aT_model, inv_mwin_3aT_model, inv_mwin_4aT_model, inv_mwin_5aT_model, + inv_mwin_6aT_model, inv_mwin_7aT_model, inv_mwin_8aT_model, inv_mwin_9aT_model, inv_mwin_10aT_model, + }; + + Gfx** frame_p; + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + int i; + + mIV_set_base_frame_dl(submenu, play, graph, mIV_PAGE_INVENTORY, TRUE, pos_x, pos_y); + + OPEN_POLY_OPA_DISP(graph); + + gSPDisplayList(POLY_OPA_DISP++, inv_mwin_item_frame_mode); + + frame_p = item_frame_disp; + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + gDPPipeSync(POLY_OPA_DISP++); + + if ((inv_ovl->selectable_item_bitfield & (1 << i)) != 0) { + gDPSetEnvColor(POLY_OPA_DISP++, 100, 100, 255, 255); + } else { + gDPSetEnvColor(POLY_OPA_DISP++, 120, 140, 255, 255); + } + + gSPDisplayList(POLY_OPA_DISP++, *frame_p); + frame_p++; + } + + frame_p = letter_frame_disp; + for (i = 0; i < mPr_INVENTORY_MAIL_COUNT; i++) { + gDPPipeSync(POLY_OPA_DISP++); + + if ((inv_ovl->selectable_mail_bitfield & (1 << i)) != 0) { + gDPSetEnvColor(POLY_OPA_DISP++, 255, 60, 60, 255); + } else { + gDPSetEnvColor(POLY_OPA_DISP++, 255, 90, 90, 255); + } + + gSPDisplayList(POLY_OPA_DISP++, *frame_p); + frame_p++; + } + + gSPDisplayList(POLY_OPA_DISP++, inv_mwin_kuni_model); + gSPDisplayList(POLY_OPA_DISP++, inv_mwin_kuni2_model); + + CLOSE_POLY_OPA_DISP(graph); +} + +static int mIV_is_mark_check(mIV_Ovl_c* inv_ovl, int idx) { + if ((inv_ovl->item_mark_bitfield & (1 << idx)) != 0) { + return TRUE; + } + + return FALSE; +} + +extern Gfx inv_item_mode[]; + +static void mIV_set_item(Submenu* submenu, mSM_MenuInfo_c* menu_info, GRAPH* graph, f32 pos_x, f32 pos_y) { + mTG_Ovl_c* tag_ovl; + mTG_tag_c* tag; + mIV_Ovl_c* inv_ovl; + mActor_name_t* item; + u8* scale_type; + int i; + int anim_frame; + f32 hand_pos[2]; + f32 scale; + int no_wc_flag; + + tag = &submenu->overlay->tag_ovl->tags[0]; + inv_ovl = submenu->overlay->inventory_ovl; + item = Now_Private->inventory.pockets; + scale_type = inv_ovl->item_scale_type; + + OPEN_POLY_OPA_DISP(graph); + + gSPDisplayList(POLY_OPA_DISP++, inv_item_mode); + + CLOSE_POLY_OPA_DISP(graph); + + no_wc_flag = inv_ovl->wc_flag; + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++, item++, scale_type++) { + if (*item != EMPTY_NO) { + submenu->overlay->tag_ovl->set_hand_pos_proc(submenu, hand_pos, mTG_TABLE_ITEM, i); + if (tag->table == mTG_TABLE_ITEM) { + switch (*scale_type) { + case mIV_ITEM_SCALE_TYPE_PRESENT: { + scale = 1.0f; + + /* @fakematch -- why do I have to set this twice? */ + if (inv_ovl->remove_timer != 0) { + anim_frame = 48 - inv_ovl->remove_timer; + } else { + anim_frame = 0; + } + + anim_frame = (inv_ovl->remove_timer != 0 ? 48 - inv_ovl->remove_timer : 0); + break; + } + + case mIV_ITEM_SCALE_TYPE_NONE: { + scale = 1.0f; + anim_frame = 0; + break; + } + + case mIV_ITEM_SCALE_TYPE_SHRINK: { + anim_frame = 70 - inv_ovl->remove_timer; + scale = (f32)inv_ovl->remove_timer * (1.0f / 12.0f); + + if (anim_frame >= 6) { + anim_frame = 5; + } + break; + } + + default: { + anim_frame = 0; + scale = + 1.0f - (f32)(inv_ovl->remove_timer - 14 - (*scale_type - mIV_ITEM_SCALE_TYPE_GROW) * 14) * + (1.0f / 12.0f); + break; + } + } + + if (scale > 1.0f) { + scale = 1.0f; + } else if (scale < 0.0f) { + scale = 0.0f; + } + } else { + anim_frame = 0; + scale = 1.0f; + } + + /* @BUG - they compare int (anim_frame) to float (0.0f) here instead of just 0 */ + if (*scale_type == mIV_ITEM_SCALE_TYPE_PRESENT && anim_frame != 0.0f) { + submenu->overlay->draw_item_proc(graph, pos_x + hand_pos[0], pos_y + hand_pos[1], scale, *item, FALSE, + (inv_ovl->selectable_item_bitfield & (1 << i)), 0, FALSE, FALSE); + } + + submenu->overlay->draw_item_proc( + graph, pos_x + hand_pos[0], pos_y + hand_pos[1], scale, *item, + ((Now_Private->inventory.item_conditions >> (i * 2)) & mPr_ITEM_COND_PRESENT) != 0, + !no_wc_flag && (inv_ovl->selectable_item_bitfield & (1 << i)), anim_frame, FALSE, + mIV_is_mark_check(inv_ovl, i)); + } + } +} + +static void mIV_set_mail(Submenu* submenu, mSM_MenuInfo_c* menu_info, GRAPH* graph, f32 pos_x, f32 pos_y) { + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + mTG_Ovl_c* tag_ovl = submenu->overlay->tag_ovl; + Mail_c* mail = Now_Private->mail; + mTG_tag_c* tag = &tag_ovl->tags[0]; + u16 select_mask = 0; + f32 scale; + f32 pos[2]; + int i; + int menu_flag; + int mark_flag; + + if (inv_ovl->remove_timer > 0 && (tag->table == mTG_TABLE_MAIL || inv_ovl->_5E4 == 1)) { + if (inv_ovl->_5E4 == 1) { + select_mask = inv_ovl->_5E2; + } else if (inv_ovl->_5E4 == 0) { + select_mask = 1 << tag_ovl->get_table_idx_proc(tag); + } + } + + OPEN_POLY_OPA_DISP(graph); + + gSPDisplayList(POLY_OPA_DISP++, inv_item_mode); + + CLOSE_POLY_OPA_DISP(graph); + + if (menu_info->data0 == mSM_IV_OPEN_CPMAIL) { + pos_x -= -155.0f; + } + + menu_flag = TRUE; + if (menu_info->next_menu_type == mSM_OVL_NEEDLEWORK) { + menu_flag = FALSE; + } + + for (i = 0; i < mPr_INVENTORY_MAIL_COUNT; i++, mail++) { + if ((inv_ovl->mail_mark_bitfield & (1 << i)) == 0 && mMl_check_not_used_mail(mail) != TRUE) { + if ((select_mask & (1 << i)) != 0) { + scale = (f32)inv_ovl->remove_timer * (1.0f / 24.0f); + } else { + scale = 1.0f; + } + + if ((inv_ovl->_5E2 & (1 << i)) != 0 && inv_ovl->_5E4 == 0) { + mark_flag = TRUE; + } else { + mark_flag = FALSE; + } + + submenu->overlay->tag_ovl->set_hand_pos_proc(submenu, pos, mTG_TABLE_MAIL, i); + + submenu->overlay->draw_mail_proc(graph, pos_x + pos[0], pos_y + pos[1], scale, mail, + menu_flag && (inv_ovl->selectable_mail_bitfield & (1 << i)), FALSE, + mark_flag); + } + } +} + +static void mIV_set_money(Submenu* submenu, GAME* game, f32 pos_x, f32 pos_y) { + u8 money_str[6]; + f32 width; + + mFont_UnintToString(money_str, sizeof(money_str), submenu->overlay->inventory_ovl->disp_money, + sizeof(money_str) - 1, FALSE, FALSE, TRUE); + + width = (f32)mFont_GetStringWidth(money_str, sizeof(money_str), TRUE) * 0.875f; + pos_x = (160.0f + pos_x + -22.0f + 38.5f) - width; + pos_y = 120.0f - (pos_y + 18.0f); + + // clang-format off + mFont_SetLineStrings( + game, + money_str, sizeof(money_str), + pos_x, pos_y, + 255, 60, 0, 255, + FALSE, + TRUE, + 0.875f, 0.875f, + mFont_MODE_POLY + ); + // clang-format on +} + +typedef struct inventory_line_data_s { + int max_str_len; + f32 pos_x; + f32 pos_y; + f32 scale; + rgba_t color; + f32 max_width; +} mIV_line_data_c; + +static void mIV_SetLineStrings_centering(GAME* game, u8* string, int type, f32 x, f32 y) { + // clang-format off + static mIV_line_data_c line_data[] = { + { + 8, + 105.0f, 52.0f, + 0.875f, + { 60, 80, 110, 255 }, + 90.0f + }, + + { + 8, + 111.0f, 64.0f, + 0.9375f, + { 70, 70, 100, 255 }, + 90.0f + }, + }; + // clang format on + + mIV_line_data_c* line_data_p = &line_data[type]; + f32 scale = line_data_p->scale; + int len = mMl_strlen(string, line_data_p->max_str_len, CHAR_SPACE); + f32 width = (f32)mFont_GetStringWidth(string, len, TRUE) * scale; + f32 max_width = line_data_p->max_width; + + if (width > max_width) { + width = max_width; + } + + x += (max_width - width) * 0.5f; + + // clang-format off + mFont_SetLineStrings( + game, + string, line_data_p->max_str_len, + x + line_data_p->pos_x, -y + line_data_p->pos_y, + line_data_p->color.r, line_data_p->color.g, line_data_p->color.b, line_data_p->color.a, + FALSE, + TRUE, + scale, scale, + mFont_MODE_POLY + ); + // clang-format on +} + +static f32 mIV_get_win_posY(Submenu* submenu, mSM_MenuInfo_c* menu_info, int page) { + if (page == submenu->overlay->inventory_ovl->next_page_id) { + return menu_info->position[1]; + } else { + return -menu_info->position[1]; + } +} + +static int mIV_up_page_draw_check(Submenu* submenu, int page) { + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + + if (inv_ovl->page_move_timer > 20) { + if (inv_ovl->next_page_id == page || inv_ovl->page_order[0] == page) { + return TRUE; + } + } else if (inv_ovl->page_move_timer != 0) { + if (inv_ovl->page_order[2] != page) { + return TRUE; + } + } else if (inv_ovl->page_order[0] == page) { + return TRUE; + } + + return FALSE; +} + +static void mIV_set_collect_dl(Submenu* submenu, mSM_MenuInfo_c* menu_info, GAME* game, int page) { + GRAPH* graph = game->graph; + mActor_name_t item; + int i; + f32 pos_x; + f32 pos_y; + int flag; + f32 pos[2]; + + if (menu_info->data0 == mSM_IV_OPEN_CPMAIL) { + pos_x = menu_info->position[0] + -155.0f; + } else { + pos_x = menu_info->position[0]; + } + + pos_y = mIV_get_win_posY(submenu, menu_info, page); + + if (menu_info->data0 == mSM_IV_OPEN_NORMAL && mIV_up_page_draw_check(submenu, page)) { + flag = TRUE; + } else { + flag = FALSE; + } + + mIV_set_base_frame_dl(submenu, (GAME_PLAY*)game, graph, page, flag, pos_x, pos_y); + if (flag) { + OPEN_POLY_OPA_DISP(graph); + + gSPDisplayList(POLY_OPA_DISP++, inv_item_mode); + + CLOSE_POLY_OPA_DISP(graph); + + for (i = 0; i < mIV_COLLECT_NUM; i++) { + item = mIV_set_collect_itemNo(i, page); + + if (item != EMPTY_NO) { + submenu->overlay->tag_ovl->set_hand_pos_proc(submenu, pos, mTG_TABLE_COLLECT, i); + submenu->overlay->draw_item_proc(graph, pos_x + pos[0], pos_y + pos[1], 1.0f, item, FALSE, TRUE, 1, + FALSE, FALSE); + } + } + } +} + +static void mIV_set_normal_dl(Submenu* submenu, mSM_MenuInfo_c* menu_info, GAME* game) { + GRAPH* graph = game->graph; + f32 pos_x; + f32 pos_y; + + if (menu_info->data0 == mSM_IV_OPEN_CPMAIL) { + pos_x = menu_info->position[0] + -155.0f; + } else { + pos_x = menu_info->position[0]; + } + + pos_y = mIV_get_win_posY(submenu, menu_info, mIV_PAGE_INVENTORY); + mIV_set_normal_frame_dl(submenu, (GAME_PLAY*)game, graph, pos_x, pos_y); + + if (mIV_up_page_draw_check(submenu, mIV_PAGE_INVENTORY)) { + mIV_set_item(submenu, menu_info, graph, pos_x, pos_y); + mIV_set_mail(submenu, menu_info, graph, pos_x, pos_y); + + Matrix_push(); + mIV_set_player(submenu, graph, (GAME_PLAY*)game, pos_x, pos_y); + Matrix_pull(); + + submenu->overlay->set_char_matrix_proc(graph); + mIV_SetLineStrings_centering(game, Now_Private->player_ID.land_name, mIV_STRING_LAND_NAME, pos_x, pos_y); + mIV_SetLineStrings_centering(game, Now_Private->player_ID.player_name, mIV_STRING_PLAYER_NAME, pos_x, pos_y); + mIV_set_money(submenu, game, pos_x, pos_y); + } +} + +static void mIV_set_dl(Submenu* submenu, mSM_MenuInfo_c* menu_info, GAME* game) { + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + u8* page_order = inv_ovl->page_order; + int i; + + for (i = mIV_PAGE_INSECT_COLLECTION; i >= 0; i--) { + if (page_order[i] == mIV_PAGE_INVENTORY) { + mIV_set_normal_dl(submenu, menu_info, game); + } else { + mIV_set_collect_dl(submenu, menu_info, game, page_order[i]); + } + } + + submenu->overlay->menu_control.tag_draw_func(submenu, game, mSM_OVL_INVENTORY); +} + +static void mIV_inventory_ovl_draw(Submenu* submenu, GAME* game) { + mSM_MenuInfo_c* menu_info = &submenu->overlay->menu_info[mSM_OVL_INVENTORY]; + + menu_info->pre_draw_func(submenu, game); + mIV_set_dl(submenu, menu_info, game); +} + +extern void mIV_inventory_ovl_set_proc(Submenu* submenu) { + Submenu_Overlay_c* overlay = submenu->overlay; + mSM_MenuInfo_c* menu_info = &submenu->overlay->menu_info[mSM_OVL_INVENTORY]; + + overlay->menu_control.menu_move_func = &mIV_inventory_ovl_move; + overlay->menu_control.menu_draw_func = &mIV_inventory_ovl_draw; + + if (overlay->hand_ovl != NULL && menu_info->next_proc_status != mSM_OVL_PROC_END) { + submenu->overlay->hand_ovl->set_hand_func(submenu); + } +} + +static void mIV_inventory_ovl_init(Submenu* submenu, mSM_MenuInfo_c* menu_info, GAME_PLAY* play) { + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + mActor_name_t dig_item = EMPTY_NO; + int i; + Mail_c* mail = Now_Private->mail; + + menu_info->proc_status = mSM_OVL_PROC_MOVE; + menu_info->move_drt = mSM_MOVE_IN_RIGHT; + i = 0; + + switch (menu_info->data0) { + case mSM_IV_OPEN_HANIWA_TAKE: { + inv_ovl->selectable_item_bitfield = 0; + inv_ovl->selectable_mail_bitfield = 0; + break; + } + + case mSM_IV_OPEN_QUEST: { + inv_ovl->selectable_item_bitfield |= 1 << menu_info->data1; + inv_ovl->selectable_mail_bitfield = 0; + break; + } + + case mSM_IV_OPEN_16: { + inv_ovl->selectable_item_bitfield = menu_info->data1; + inv_ovl->selectable_mail_bitfield = 0; + break; + } + + case mSM_IV_OPEN_SEND_MAIL: { + inv_ovl->selectable_item_bitfield = 0; + inv_ovl->selectable_mail_bitfield = 0; + for (i = 0; i < mPr_INVENTORY_MAIL_COUNT; i++) { + if (mMl_check_not_used_mail(mail) == FALSE && mMl_check_send_mail(mail)) { + inv_ovl->selectable_mail_bitfield |= 1 << i; + } + + mail++; + } + break; + } + + case mSM_IV_OPEN_MAILBOX: { + inv_ovl->selectable_mail_bitfield = 0xFFFF; + inv_ovl->selectable_item_bitfield = 0; + break; + } + + case mSM_IV_OPEN_CPMAIL: { + inv_ovl->selectable_item_bitfield = 0; + inv_ovl->selectable_mail_bitfield = 0; + for (i; i < mPr_INVENTORY_MAIL_COUNT; i++) { + if (mMl_check_not_used_mail(mail) || mMl_check_send_mail(mail) == FALSE) { + inv_ovl->selectable_mail_bitfield |= 1 << i; + } + + mail++; + } + + menu_info->move_drt = mSM_MOVE_IN_LEFT; + break; + } + + default: { + inv_ovl->selectable_item_bitfield = mSM_check_open_inventory_itemlist(menu_info->data0, menu_info->data1); + + if (menu_info->data0 == mSM_IV_OPEN_NORMAL || menu_info->data0 == mSM_IV_OPEN_EXCHANGE) { + inv_ovl->selectable_mail_bitfield = 0xFFFF; + } else { + inv_ovl->selectable_mail_bitfield = 0; + } + break; + } + } + + menu_info->next_proc_status = mSM_OVL_PROC_OBEY; + + if (menu_info->data0 == mSM_IV_OPEN_CPMAIL) { + mSM_open_submenu(submenu, mSM_OVL_CPMAIL, 0, 0); + } else if (menu_info->data0 == mSM_IV_OPEN_MAILBOX) { + mSM_open_submenu(submenu, mSM_OVL_MAILBOX, 0, 0); + } else if (menu_info->data0 == mSM_IV_OPEN_HANIWA_ENTRUST) { + mSM_open_submenu(submenu, mSM_OVL_HANIWA, mSM_HANIWA_OPEN_ENTRUST, menu_info->data1); + } else if (menu_info->data0 == mSM_IV_OPEN_HANIWA_TAKE) { + mSM_open_submenu(submenu, mSM_OVL_HANIWA, mSM_HANIWA_OPEN_TAKE, menu_info->data1); + } else { + menu_info->next_proc_status = mSM_OVL_PROC_PLAY; + } + + inv_ovl->disp_money = Now_Private->inventory.wallet; + + if (menu_info->data0 == mSM_IV_OPEN_EXCHANGE && ITEM_NAME_GET_TYPE(menu_info->data1) == NAME_TYPE_ITEM1 && + ITEM_NAME_GET_CAT(menu_info->data1) == ITEM1_CAT_FISH) { + inv_ovl->release_flag = TRUE; + } else { + inv_ovl->release_flag = mCoBG_SearchWaterLimitDistN(&inv_ovl->release_pos, player->actor_class.world.position, + player->actor_class.shape_info.rotation.y, 120.0f, 12); + } + + if (mPlib_Check_scoop_after((GAME*)play, &inv_ovl->shovel_pos, &dig_item, NULL, FALSE) == + mPlayer_INDEX_FILL_SCOOP) { + inv_ovl->shovel_flag = TRUE; + } else { + inv_ovl->shovel_flag = FALSE; + } + + inv_ovl->page_order[0] = mIV_PAGE_INVENTORY; + inv_ovl->page_order[1] = mIV_PAGE_FISH_COLLECTION; + inv_ovl->page_order[2] = mIV_PAGE_INSECT_COLLECTION; + inv_ovl->page_move_timer = 0; + inv_ovl->_5E4 = 0; + inv_ovl->item_mark_bitfield = 0; + inv_ovl->_5E2 = 0; + inv_ovl->wc_flag = FALSE; + + if (menu_info->data0 == mSM_IV_OPEN_MAILBOX) { + sAdo_SysTrgStart(SE_FLAG_15(NA_SE_ZOOMUP)); + } else { + sAdo_SysTrgStart(NA_SE_MENU_PAUSE); + } + + mBGMPsComp_pause(mBGM_PAUSE_1); +} + +extern void mIV_inventory_ovl_construct(Submenu* submenu) { + mSM_MenuInfo_c* menu_info = &submenu->overlay->menu_info[mSM_OVL_INVENTORY]; + GAME_PLAY* play = (GAME_PLAY*)gamePT; + mIV_Ovl_c** inv_ovl_p = &submenu->overlay->inventory_ovl; + + if (*inv_ovl_p == NULL) { + mem_clear((u8*)&inv_ovl_data, sizeof(mIV_Ovl_c), 0); + *inv_ovl_p = &inv_ovl_data; + mIV_pl_shape_init(submenu); + mIV_pl_shape_move(submenu); + mQst_ClearGrabItemInfo(); + } + + mIV_inventory_ovl_init(submenu, menu_info, play); + mIV_inventory_ovl_set_proc(submenu); + submenu->overlay->inventory_ovl->set_collect_itemNo_proc = &mIV_set_collect_itemNo; +} + +extern void mIV_inventory_ovl_destruct(Submenu* submenu) { + mIV_Ovl_c* inv_ovl = submenu->overlay->inventory_ovl; + + cKF_SkeletonInfo_R_dt(&inv_ovl->player_main_keyframe); + cKF_SkeletonInfo_R_dt(&inv_ovl->player_com_keyframe); + cKF_SkeletonInfo_R_dt(&inv_ovl->item_keyframe); + submenu->overlay->inventory_ovl = NULL; } diff --git a/src/m_submenu_ovl.c b/src/m_submenu_ovl.c index 5bcd82a2..55321ea1 100644 --- a/src/m_submenu_ovl.c +++ b/src/m_submenu_ovl.c @@ -2099,7 +2099,7 @@ static void mSM_set_new_start_data(Submenu* submenu) { menu->data3 = submenu->param3; menu->move_flag = FALSE; - if (type == mSM_OVL_INVENTORY && submenu->param0 == mSM_IV_OPEN_14) { + if (type == mSM_OVL_INVENTORY && submenu->param0 == mSM_IV_OPEN_CPMAIL) { menu->position[0] = -300.0f; } @@ -2209,7 +2209,7 @@ static void mSM_return_func(Submenu* submenu, mSM_MenuInfo_c* menu_info) { } } - menu_info->_2C = FALSE; + menu_info->open_flag = FALSE; menu_info->pre_menu_type = mSM_OVL_NONE; menu_info->next_menu_type = mSM_OVL_NONE; menu_info->proc_status = mSM_OVL_PROC_MOVE;