From 5083c7f2baaeb7574bd5fb49534e6668d73fd430 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Mon, 25 Mar 2024 00:06:16 -0400 Subject: [PATCH 1/4] Match ac_my_room.c --- include/ac_furniture.h | 44 +- include/ac_my_room.h | 44 +- include/audio.h | 4 +- include/jaudio_NES/rhythm.h | 5 +- include/m_common_data.h | 2 +- include/m_home_h.h | 208 +-- include/m_name_table.h | 2 +- src/ac_furniture_data.c_inc | 2603 +++++++++++++++++++++++++++++++++++ src/ac_my_room.c | 2274 ++++++++++++++++++++++++++++++ src/ac_my_room_data.c_inc | 1402 +++++++++++++++++++ src/audio.c | 9 +- src/famicom_emu.c | 6 +- src/ftr/ac_ike_jny_houi01.c | 41 +- src/m_island.c | 1058 +++++++------- src/m_room_type.c | 8 +- tools/arc_tool.py | 17 +- 16 files changed, 6995 insertions(+), 732 deletions(-) create mode 100644 src/ac_furniture_data.c_inc create mode 100644 src/ac_my_room.c create mode 100644 src/ac_my_room_data.c_inc diff --git a/include/ac_furniture.h b/include/ac_furniture.h index 98f64f54..0ffbc750 100644 --- a/include/ac_furniture.h +++ b/include/ac_furniture.h @@ -12,6 +12,9 @@ extern "C" { typedef struct furniture_actor_s FTR_ACTOR; +#define aFTR_KEEP_ITEM_COUNT (mCoBG_LAYER_NUM - 1) +#define aFTR_CHECK_INTERACTION(inter, type) (((inter) >> (type)) & 1) + enum { aFTR_STATE_STOP, aFTR_STATE_WAIT_PUSH, @@ -62,7 +65,7 @@ enum { enum { aFTR_INTERACTION_STORAGE_DRAWERS = 1, // dressers - aFTR_INTERACTION_STORAGE_WARDROBE, // double doors + aFTR_INTERACTION_STORAGE_WARDROBE = 2, // double doors aFTR_INTERACTION_STORAGE_CLOSET = 4, // single door aFTR_INTERACTION_MUSIC_DISK = 8, aFTR_INTERACTION_NO_COLLISION = 0x10, @@ -78,19 +81,52 @@ enum { aFTR_INTERACTION_FAMICOM_ITEM = 0x2000, aFTR_INTERACTION_RADIO_AEROBICS = 0x4000, aFTR_INTERACTION_TOGGLE = 0x8000, - aFTR_INTERACTION_NUM = 15, }; +enum { + aFTR_INTERACTION_TYPE_DRAWERS, + aFTR_INTERACTION_TYPE_WARDROBE, + aFTR_INTERACTION_TYPE_CLOSET, + aFTR_INTERACTION_TYPE_MUSIC_DISK, + aFTR_INTERACTION_TYPE_NO_COLLISION, + aFTR_INTERACTION_TYPE_HANIWA, + aFTR_INTERACTION_TYPE_FISH, + aFTR_INTERACTION_TYPE_INSECT, + aFTR_INTERACTION_TYPE_MANNEKIN, + aFTR_INTERACTION_TYPE_UMBRELLA, + aFTR_INTERACTION_TYPE_FOSSIL, + aFTR_INTERACTION_TYPE_FAMICOM, + aFTR_INTERACTION_TYPE_START_DISABLED, + aFTR_INTERACTION_TYPE_FAMICOM_ITEM, + aFTR_INTERACTION_TYPE_RADIO_AEROBICS, + aFTR_INTERACTION_TYPE_TOGGLE, + + aFTR_INTERACTION_NUM, +}; + +#define aFTR_IS_STORAGE(profile) \ + (aFTR_CHECK_INTERACTION((profile)->interaction_type, aFTR_INTERACTION_TYPE_DRAWERS) || \ + aFTR_CHECK_INTERACTION((profile)->interaction_type, aFTR_INTERACTION_TYPE_WARDROBE) || \ + aFTR_CHECK_INTERACTION((profile)->interaction_type, aFTR_INTERACTION_TYPE_CLOSET) || \ + aFTR_CHECK_INTERACTION((profile)->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK)) enum { aFTR_CONTACT_ACTION_CHAIR_UNIDIRECTIONAL = 1, // only can sit from the front aFTR_CONTACT_ACTION_CHAIR_MULTIDIRECTIONAL = 2, // can sit from any direction aFTR_CONTACT_ACTION_CHAIR_SOFA = 4, // cam sit anywhere from the front aFTR_CONTACT_ACTION_BED_SINGLE = 8, // single bed (can't roll) - aFTR_CONTACT_ACTION_BED_DOUBLE = 0x10, // double bed (can roll) + aFTR_CONTACT_ACTION_BED_DOUBLE = 0x10, // double bed (can roll) aFTR_CONTACT_ACTION_NUM }; +enum { + aFTR_SET_TYPE_NORMAL, /* Can't be placed on top and is not a table (layer0) */ + aFTR_SET_TYPE_SURFACE, /* Is a surface (layer0) */ + aFTR_SET_TYPE_ON_SURFACE, /* Can be placed on a surface (layer0/layer1) */ + + aFTR_SET_TYPE_NUM +}; + typedef void (*aFTR_FTR_CT_PROC)(FTR_ACTOR*, u8*); typedef void (*aFTR_FTR_MOVE_PROC)(FTR_ACTOR*, ACTOR*, GAME*, u8*); typedef void (*aFTR_FTR_DRAW_PROC)(FTR_ACTOR*, ACTOR*, GAME*, u8*); @@ -186,7 +222,7 @@ struct furniture_actor_s { s16 _83E; s16 open_music_disk; /* set when a music player is interacted with */ s16 dust_timer; - mActor_name_t items[mCoBG_LAYER_NUM - 1]; /* used for holding items (music players & wardrobes) */ + mActor_name_t items[aFTR_KEEP_ITEM_COUNT]; /* used for holding items (music players & wardrobes) */ int _84C; u16* pal_p; /* used for furniture actors with dynamic palettes such as the structure model items */ int _854; diff --git a/include/ac_my_room.h b/include/ac_my_room.h index 9cfddf77..dfae0a25 100644 --- a/include/ac_my_room.h +++ b/include/ac_my_room.h @@ -10,6 +10,9 @@ extern "C" { #endif +#define aMR_MAX_UNIT 8 +#define aMR_HANIWA_ON_TABLE_NUM 14 + typedef struct my_room_actor_s MY_ROOM_ACTOR; enum { @@ -29,6 +32,23 @@ enum { aMR_CONTACT_DIR_NUM }; +enum { + aMR_FRIEND_ALL, + aMR_FRIEND_ON, + aMR_FRIEND_OFF, + + aMR_FRIEND_NUM +}; + +enum { + aMR_DIRECT_UP, + aMR_DIRECT_LEFT, + aMR_DIRECT_DOWN, + aMR_DIRECT_RIGHT, + + aMR_DIRECT_NUM +}; + typedef struct my_room_contact_s { int contact_flag; int ftr_no; @@ -48,18 +68,18 @@ typedef struct my_room_clock_info_s { int frame; /* 0-119 */ } aMR_clock_info_c; -typedef int (*aMR_JUDGE_BREED_NEW_FTR_PROC)(GAME_PLAY* play, u16 ftr_no, int* ut_x, int* ut_z, u16* rotation, +typedef int (*aMR_JUDGE_BREED_NEW_FTR_PROC)(GAME* game, u16 ftr_no, int* ut_x, int* ut_z, u16* rotation, int* square_offset, int* layer); -typedef mActor_name_t (*aMR_SEARCH_PICKUP_FURNITURE_PROC)(GAME_PLAY* play); -typedef void (*aMR_FURNITURE2ITEMBAG_PROC)(GAME_PLAY* play); +typedef mActor_name_t (*aMR_SEARCH_PICKUP_FURNITURE_PROC)(GAME* game); +typedef void (*aMR_FURNITURE2ITEMBAG_PROC)(GAME* game); typedef int (*aMR_JUDGE_PLAYER_ACTION_PROC)(xyz_t* wpos0, xyz_t* wpos1, int ftr_actor_idx); typedef void (*aMR_PLAYER_MOVE_FURNITURE_PROC)(int ftr_actor_idx, xyz_t* wpos); typedef int (*aMR_FTR_ID_2_WPOS_PROC)(xyz_t* wpos, int ftr_id); typedef int (*aMR_UNIT_NUM_2_FTR_ITEMNO_FTRID_PROC)(mActor_name_t* ftr_item_no, int* ftr_id, int ut_x, int ut_z, - s16 layer); + int layer); typedef void (*aMR_FTR_ID_2_EXTINGUISH_FURNITURE_PROC)(int ftr_id); -typedef void (*aMR_REDMA_FTR_BANK_PROC)(); -typedef int (*aMR_RESERVE_FURNITURE_PROC)(GAME_PLAY* play, u16 ftr_no, int judge_res, int ut_x, int ut_z, u16 rotation, +typedef void (*aMR_REDMA_FTR_BANK_PROC)(void); +typedef int (*aMR_RESERVE_FURNITURE_PROC)(GAME* game, u16 ftr_no, int judge_res, int ut_x, int ut_z, u16 rotation, int square_offset, int layer); typedef int (*aMR_COUNT_FRIEND_FURNITURE_PROC)(FTR_ACTOR* ftr_actor, u8 switch_on); typedef int (*aMR_JUDGE_PLACE_2ND_LAYER_PROC)(int ut_x, int ut_z); @@ -75,13 +95,13 @@ typedef int (*aMR_PICKUP_FTR_LAYER_PROC)(void); typedef void (*aMR_LEAF_PICKUPED_PROC)(void); typedef void (*aMR_FAMICOM_EMU_COMMON_MOVE_PROC)(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, int rom_no, int agb_rom_no); -typedef u32 (*aMR_FTR_NO_2_BANK_ADDRESS_PROC)(u16 ftr_no); +typedef u8* (*aMR_FTR_NO_2_BANK_ADDRESS_PROC)(u16 ftr_no); typedef void (*aMR_CALL_SIT_DOWN_ONGEN_POS_SE_PROC)(const xyz_t* pos); typedef void (*aMR_SOUND_MELODY_PROC)(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, int idx); typedef int (*aMR_CHECK_DANNA_KILL_PROC)(xyz_t* pos); typedef struct my_room_clip_s { - MY_ROOM_ACTOR* my_room_actor_p; + ACTOR* my_room_actor_p; aMR_JUDGE_BREED_NEW_FTR_PROC judge_breed_new_ftr_proc; aMR_SEARCH_PICKUP_FURNITURE_PROC search_pickup_ftr_proc; aMR_FURNITURE2ITEMBAG_PROC ftr2itemBag_proc; @@ -162,7 +182,7 @@ typedef struct emu_info_s { int _10; int card_famicom_count; int memory_game_select; - char** famicom_names_p; + char* famicom_names_p; s16 save_msg_timer; s16 external_rom; } aMR_emu_info_c; @@ -215,7 +235,7 @@ struct my_room_actor_s { s16 keep_pull_flag; xyz_t pull_target_pos0; xyz_t pull_target_pos1; - int haniwa_on_table[14]; + int haniwa_on_table[aMR_HANIWA_ON_TABLE_NUM]; aMR_bgm_info_c bgm_info; aMR_room_info_c room_info; aMR_emu_info_c emu_info; @@ -257,8 +277,8 @@ extern int aMR_GetFurnitureUnit(mActor_name_t ftr); extern mActor_name_t aMR_FurnitureFg_to_FurnitureFgWithDirect(mActor_name_t ftr, int direct); extern void aMR_SameFurnitureSwitchOFF(u16 ftr_name); extern aMR_contact_info_c* aMR_GetContactInfoLayer1(void); -extern FTR_ACTOR* aMR_GetParentFactor(); -extern s16 aMR_GetParentAngleOffset(FTR_ACTOR* ftr_actor, MY_ROOM_ACTOR* my_room_actor); +extern FTR_ACTOR* aMR_GetParentFactor(FTR_ACTOR* ftr_actor, ACTOR* my_room_actorx); +extern s16 aMR_GetParentAngleOffset(FTR_ACTOR* ftr_actor, ACTOR* my_room_actorx); extern void aMR_SetSurprise(ACTOR* my_room_actor, s16 rot); extern void aMR_RadioCommonMove(FTR_ACTOR* ftr_actor, ACTOR* my_room_actorx); diff --git a/include/audio.h b/include/audio.h index 34f49505..7236a34d 100644 --- a/include/audio.h +++ b/include/audio.h @@ -69,8 +69,8 @@ extern void sAdo_Pause(u8 mode); extern f32 sAdo_GetRhythmAnimCounter(u32 id); extern s8 sAdo_GetRhythmDelay(u32 id); -extern f32 sAdo_GetRhythmInfo(u32 id); -extern void sAdo_SetRhythmInfo(f32 p); +extern void sAdo_GetRhythmInfo(TempoBeat_c* rhythm); +extern void sAdo_SetRhythmInfo(TempoBeat_c* rhythm); extern int sAdo_InstCountGet(); diff --git a/include/jaudio_NES/rhythm.h b/include/jaudio_NES/rhythm.h index e22dec33..44becac8 100644 --- a/include/jaudio_NES/rhythm.h +++ b/include/jaudio_NES/rhythm.h @@ -2,6 +2,7 @@ #define RHYTHM_H #include "types.h" +#include "audio.h" #ifdef __cplusplus extern "C" { @@ -12,8 +13,8 @@ extern void Na_RhythmStop(u32); extern void Na_RhythmAllStop(); extern f32 Na_GetRhythmAnimCounter(u32); extern s8 Na_GetRhythmDelay(u32); -extern f32 Na_GetRhythmInfo(u32); -extern void Na_SetRhythmInfo(f32); +extern void Na_GetRhythmInfo(TempoBeat_c* rhythm); +extern void Na_SetRhythmInfo(TempoBeat_c* rhythm); #ifdef __cplusplus } diff --git a/include/m_common_data.h b/include/m_common_data.h index 589853d4..056c7562 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -310,7 +310,7 @@ typedef struct common_data_s { /* 0x02DBA4 */ s16 island_weather_intensity; /* 0x02DBA6 */ s16 _2DBA6; /* 0x02DBA8 */ u8 memcard_slot; - /* 0X02DBAC */ int famicom_2DBAC; + /* 0X02DBAC */ int my_room_message_control_flags; /* 0x02DBB0 */ s16 can_look_goki_count; /* 0x02DBB4 */ f32 rainbow_opacity; /* current opacity of rainbow (0.0f - 1.0f) */ /* 0x02DBB8 */ u32 event_flags[mEv_EVENT_TYPE_NUM]; diff --git a/include/m_home_h.h b/include/m_home_h.h index f59ef86f..4486ec0f 100644 --- a/include/m_home_h.h +++ b/include/m_home_h.h @@ -19,169 +19,171 @@ extern "C" { #define mHm_LAYER_NUM 4 enum { - mHm_ROOM_MAIN, - mHm_ROOM_UPPER, - mHm_ROOM_BASEMENT, + mHm_ROOM_MAIN, + mHm_ROOM_UPPER, + mHm_ROOM_BASEMENT, - mHm_ROOM_NUM + mHm_ROOM_NUM }; enum { - mHm_ROOMTYPE_SMALL, - mHm_ROOMTYPE_MEDIUM, - mHm_ROOMTYPE_LARGE, - mHm_ROOMTYPE_COTTAGE, + mHm_ROOMTYPE_SMALL, + mHm_ROOMTYPE_MEDIUM, + mHm_ROOMTYPE_LARGE, + mHm_ROOMTYPE_COTTAGE, - mHm_ROOMTYPE_NUM + mHm_ROOMTYPE_NUM }; enum { - mHm_HOMESIZE_SMALL, /* initial size */ - mHm_HOMESIZE_MEDIUM, /* paid off first debt */ - mHm_HOMESIZE_LARGE, /* paid off second debt (excluding basement) */ - mHm_HOMESIZE_UPPER, /* paid off third debt & basement */ - mHm_HOMESIZE_STATUE, /* paid off final debt */ + mHm_HOMESIZE_SMALL, /* initial size */ + mHm_HOMESIZE_MEDIUM, /* paid off first debt */ + mHm_HOMESIZE_LARGE, /* paid off second debt (excluding basement) */ + mHm_HOMESIZE_UPPER, /* paid off third debt & basement */ + mHm_HOMESIZE_STATUE, /* paid off final debt */ - mHm_HOMESIZE_NUM + mHm_HOMESIZE_NUM }; enum { - mHm_HANIWA_TRADE_0, - mHm_HANIWA_TRADE_1, - mHm_HANIWA_TRADE_2, - mHm_HANIWA_TRADE_3, - - mHm_HANIWA_TRADE_NUM + mHm_HANIWA_TRADE_0, + mHm_HANIWA_TRADE_1, + mHm_HANIWA_TRADE_2, + mHm_HANIWA_TRADE_3, + + mHm_HANIWA_TRADE_NUM }; enum { - mHm_OUTLOOK_PAL_0, - mHm_OUTLOOK_PAL_1, - mHm_OUTLOOK_PAL_2, - mHm_OUTLOOK_PAL_3, - mHm_OUTLOOK_PAL_4, - mHm_OUTLOOK_PAL_5, - mHm_OUTLOOK_PAL_6, - mHm_OUTLOOK_PAL_7, - mHm_OUTLOOK_PAL_8, - mHm_OUTLOOK_PAL_9, - mHm_OUTLOOK_PAL_10, - mHm_OUTLOOK_PAL_11, + mHm_OUTLOOK_PAL_0, + mHm_OUTLOOK_PAL_1, + mHm_OUTLOOK_PAL_2, + mHm_OUTLOOK_PAL_3, + mHm_OUTLOOK_PAL_4, + mHm_OUTLOOK_PAL_5, + mHm_OUTLOOK_PAL_6, + mHm_OUTLOOK_PAL_7, + mHm_OUTLOOK_PAL_8, + mHm_OUTLOOK_PAL_9, + mHm_OUTLOOK_PAL_10, + mHm_OUTLOOK_PAL_11, - mHm_OUTLOOK_PAL_NUM + mHm_OUTLOOK_PAL_NUM }; /* sizeof(mHm_rmsz_c) == 6 */ typedef struct home_size_info_s { - /* 0x00 */ struct { - /* 0x00 */ u8 day; - /* 0x01 */ u8 month; - /* 0x02 */ u16 year; - } upgrade_order_date; /* date you ordered an upgrade, seems to be a struct */ + /* 0x00 */ struct { + /* 0x00 */ u8 day; + /* 0x01 */ u8 month; + /* 0x02 */ u16 year; + } upgrade_order_date; /* date you ordered an upgrade, seems to be a struct */ - /* 0x04 */ u8 size:3; /* current house size */ - /* 0x04 */ u8 next_size:3; /* next house size when upgrade is ordered */ - /* 0x04 */ u8 statue_rank:2; /* statue ranking, 0 = gold, 1 = silver, 2 = bronze, 3 = jade */ - /* 0x05 */ u8 renew:1; /* refresh house size & 'outlook' palette */ - /* 0x05 */ u8 statue_ordered:1; /* set when statue is ordered from Nook */ - /* 0x05 */ u8 basement_ordered:1; /* set when basement has been ordered */ - /* 0x05 */ u8 pad:5; /* unused? */ + /* 0x04 */ u8 size : 3; /* current house size */ + /* 0x04 */ u8 next_size : 3; /* next house size when upgrade is ordered */ + /* 0x04 */ u8 statue_rank : 2; /* statue ranking, 0 = gold, 1 = silver, 2 = bronze, 3 = jade */ + /* 0x05 */ u8 renew : 1; /* refresh house size & 'outlook' palette */ + /* 0x05 */ u8 statue_ordered : 1; /* set when statue is ordered from Nook */ + /* 0x05 */ u8 basement_ordered : 1; /* set when basement has been ordered */ + /* 0x05 */ u8 pad : 5; /* unused? */ } mHm_rmsz_c; /* sizeof(Haniwa_Item_c) == 8 */ typedef struct home_haniwa_item_s { - /* 0x00 */ mActor_name_t item; /* held item */ - /* 0x02 */ s16 exchange_type; /* type of exchange (sale, free, trade) */ - /* 0x04 */ u32 extra_data; /* trade related data */ + /* 0x00 */ mActor_name_t item; /* held item */ + /* 0x02 */ s16 exchange_type; /* type of exchange (sale, free, trade) */ + /* 0x04 */ u32 extra_data; /* trade related data */ } Haniwa_Item_c; /* sizeof(Haniwa_c) == 0xA4 */ typedef struct home_haniwa_s { - /* 0x00 */ Haniwa_Item_c items[HANIWA_ITEM_HOLD_NUM]; /* held items */ - /* 0x20 */ u8 message[HANIWA_MESSAGE_LEN]; /* message for visitors */ - /* 0xA0 */ u32 bells; /* held bells from selling items */ + /* 0x00 */ Haniwa_Item_c items[HANIWA_ITEM_HOLD_NUM]; /* held items */ + /* 0x20 */ u8 message[HANIWA_MESSAGE_LEN]; /* message for visitors */ + /* 0xA0 */ u32 bells; /* held bells from selling items */ } Haniwa_c; /* sizeof(mHm_wf_c) == 2 */ typedef struct home_wall_floor_s { - /* 0x00 */ u8 flooring_idx; - /* 0x01 */ u8 wallpaper_idx; + /* 0x00 */ u8 flooring_idx; + /* 0x01 */ u8 wallpaper_idx; } mHm_wf_c; /* sizeof(mHm_goki_c) == 0xA */ typedef struct home_goki_s { - /* 0x00 */ lbRTC_time_c time; /* last time updated */ - /* 0x08 */ u8 num; /* number of cockroaches in the house */ - /* 0x09 */ u8 pad; /* unused outside of being initalized to 0 */ + /* 0x00 */ lbRTC_time_c time; /* last time updated */ + /* 0x08 */ u8 num; /* number of cockroaches in the house */ + /* 0x09 */ u8 pad; /* unused outside of being initalized to 0 */ } mHm_goki_c; /* sizeof(mHm_lyr_c) == 0x228 */ typedef struct home_layer_s { - /* 0x000 */ mActor_name_t items[UT_Z_NUM][UT_X_NUM]; /* Furniture item actors */ - /* 0x200 */ u64 ftr_switch; /* Bitfield for controlling which furniture items are active, max of 64 */ - /* 0x208 */ u32 unk_208[8]; /* Only referenced in mISL_gc_to_agb_layer */ + /* 0x000 */ mActor_name_t items[UT_Z_NUM][UT_X_NUM]; /* Furniture item actors */ + /* 0x200 */ u64 ftr_switch; /* Bitfield for controlling which furniture items are active, max of 64 */ + /* 0x208 */ u32 haniwa_step[8]; /* Only referenced in mISL_gc_to_agb_layer */ } mHm_lyr_c; typedef struct floor_bit_info_s { - u8 wall_original:1; /* is wallpaper a pattern (original)? */ - u8 floor_original:1; /* is flooring a pattern (original)? */ - u8 bit_2_7:6; /* unused? */ + u8 wall_original : 1; /* is wallpaper a pattern (original)? */ + u8 floor_original : 1; /* is flooring a pattern (original)? */ + u8 bit_2_7 : 6; /* unused? */ } mHm_fllot_bit_c; /* sizeof(mHm_flr_c) == 0x8A8 */ typedef struct home_floor_s { - /* 0x000 */ mHm_lyr_c layer_main; - /* 0x228 */ mHm_lyr_c layer_secondary; /* Also storage layer 0 */ - /* 0x450 */ mHm_lyr_c layer_storage1; - /* 0x678 */ mHm_lyr_c layer_storage2; - /* 0x8A0 */ mHm_wf_c wall_floor; - /* 0x8A2 */ TempoBeat_c tempo_beat; - /* 0x8A4 */ mHm_fllot_bit_c floor_bit_info; + /* 0x000 */ mHm_lyr_c layer_main; + /* 0x228 */ mHm_lyr_c layer_secondary; /* Also storage layer 0 */ + /* 0x450 */ mHm_lyr_c layer_storage1; + /* 0x678 */ mHm_lyr_c layer_storage2; + /* 0x8A0 */ mHm_wf_c wall_floor; + /* 0x8A2 */ TempoBeat_c tempo_beat; + /* 0x8A4 */ mHm_fllot_bit_c floor_bit_info; } mHm_flr_c; /* sizeof(mHm_flg_c) == 1 */ typedef struct home_flags_s { - u8 house_updated:1; /* signals HRA to re-score house */ - u8 has_saved:1; /* whether or not the player has saved at this house before */ - u8 hra_member:1; /* whether or not the house has been setup for HRA membership */ - u8 has_basement:1; /* set when the basement is built */ - u8 hra_reward0:1; /* earned 70k HRA points reward */ - u8 hra_reward1:1; /* earned 100k HRA points reward */ - u8 bit_6:1; /* unused */ - u8 bit_7:1; /* unused */ + u8 house_updated : 1; /* signals HRA to re-score house */ + u8 has_saved : 1; /* whether or not the player has saved at this house before */ + u8 hra_member : 1; /* whether or not the house has been setup for HRA membership */ + u8 has_basement : 1; /* set when the basement is built */ + u8 hra_reward0 : 1; /* earned 70k HRA points reward */ + u8 hra_reward1 : 1; /* earned 100k HRA points reward */ + u8 bit_6 : 1; /* unused */ + u8 bit_7 : 1; /* unused */ } mHm_flg_c; /* sizeof(mHm_hs_c) == 0x26B0 */ typedef struct home_s { - /* 0x0000 */ PersonalID_c ownerID; /* owner player's ID */ - /* 0x0014 */ u8 unk_14[6]; - /* 0x001A */ TempoBeat_c haniwa_tempo; /* unsure about this */ - /* 0x001C */ lbRTC_ymd_c hra_mark_time; /* last HRA judge date */ - /* 0x0020 */ u32 hra_mark_info; /* bitfield of HRA info pulled when HRA mails letter */ - /* 0x0024 */ mHm_flg_c flags; - /* 0x0026 */ mHm_rmsz_c size_info; /* home size info */ - /* 0x002C */ u8 outlook_pal; /* current house palette */ - /* 0x002D */ u8 ordered_outlook_pal; /* house palette ordered at Nook's via upgrade */ - /* 0x002E */ u8 next_outlook_pal; /* next house palette set via all other means (villager, Wisp, paint @ Nook's, ...) */ - /* 0x002F */ u8 door_original; /* player design shown on door, apparently called 'original', maybe 'original design'? */ - /* 0x0030 */ u8 unk_30[8]; /* unused? */ - /* 0x0038 */ mHm_flr_c floors[mHm_ROOM_NUM]; /* house floors, might be a union idk */ - /* 0x1A30 */ Mail_c mailbox[HOME_MAILBOX_SIZE]; /* mailbox */ - /* 0x25D4 */ Haniwa_c haniwa; /* gyroid info */ - /* 0x2678 */ mHm_goki_c goki; /* cockroach info */ - /* 0x2684 */ u32 music_box[2]; /* bitfield of inserted music */ - /* 0x268C */ u8 unk_286C[36]; /* unused? */ + /* 0x0000 */ PersonalID_c ownerID; /* owner player's ID */ + /* 0x0014 */ u8 unk_14[6]; + /* 0x001A */ TempoBeat_c haniwa_tempo; /* unsure about this */ + /* 0x001C */ lbRTC_ymd_c hra_mark_time; /* last HRA judge date */ + /* 0x0020 */ u32 hra_mark_info; /* bitfield of HRA info pulled when HRA mails letter */ + /* 0x0024 */ mHm_flg_c flags; + /* 0x0026 */ mHm_rmsz_c size_info; /* home size info */ + /* 0x002C */ u8 outlook_pal; /* current house palette */ + /* 0x002D */ u8 ordered_outlook_pal; /* house palette ordered at Nook's via upgrade */ + /* 0x002E */ u8 + next_outlook_pal; /* next house palette set via all other means (villager, Wisp, paint @ Nook's, ...) */ + /* 0x002F */ u8 + door_original; /* player design shown on door, apparently called 'original', maybe 'original design'? */ + /* 0x0030 */ u8 unk_30[8]; /* unused? */ + /* 0x0038 */ mHm_flr_c floors[mHm_ROOM_NUM]; /* house floors, might be a union idk */ + /* 0x1A30 */ Mail_c mailbox[HOME_MAILBOX_SIZE]; /* mailbox */ + /* 0x25D4 */ Haniwa_c haniwa; /* gyroid info */ + /* 0x2678 */ mHm_goki_c goki; /* cockroach info */ + /* 0x2684 */ u32 music_box[2]; /* bitfield of inserted music */ + /* 0x268C */ u8 unk_286C[36]; /* unused? */ } mHm_hs_c; /* sizeof(mHm_cottage_c) == 0x8C8 */ typedef struct home_cottage_s { - /* 0x000 */ mHm_wf_c unused_wall_floor; /* Has wallpaper & flooring bounds checks in sChk_CheckSaveData_Cattage */ - /* 0x002 */ u8 unk_2[2]; /* struct/array that is two bytes long, maybe another wall floor? */ - /* 0x004 */ u8 unk_4; /* direct copy in agb_to_gc_cottage, GBA only? */ - /* 0x005 */ u8 unk_5; /* direct copy in agb_to_gc_cottage, GBA only? */ - /* 0x008 */ mHm_flr_c room; /* Cottage room */ - /* 0x8B0 */ mHm_goki_c goki; /* Cottage cockroaches */ - /* 0x8BC */ u32 music_box[2]; /* Cottage music storage... separate from main home? */ + /* 0x000 */ mHm_wf_c unused_wall_floor; /* Has wallpaper & flooring bounds checks in sChk_CheckSaveData_Cattage */ + /* 0x002 */ u8 unk_2[2]; /* struct/array that is two bytes long, maybe another wall floor? */ + /* 0x004 */ u8 unk_4; /* direct copy in agb_to_gc_cottage, GBA only? */ + /* 0x005 */ u8 unk_5; /* direct copy in agb_to_gc_cottage, GBA only? */ + /* 0x008 */ mHm_flr_c room; /* Cottage room */ + /* 0x8B0 */ mHm_goki_c goki; /* Cottage cockroaches */ + /* 0x8BC */ u32 music_box[2]; /* Cottage music storage... separate from main home? */ } mHm_cottage_c; #ifdef __cplusplus diff --git a/include/m_name_table.h b/include/m_name_table.h index dde35fab..ff03aee2 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -1100,7 +1100,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define FTR_CLOTH_MANNIQUIN254_WEST 0x1BA7 #define FTR_CLOTH_END FTR_CLOTH_MANNIQUIN254_WEST #define FTR_CLOTH_MANNIQUIN_MY_ORIGINAL0 0x1BA8 - +#define FTR_CLOTH_MYMANNIQUIN_END 0x1BC7 #define FTR_INSECT_START 0x1BC8 #define FTR_INSECT00 FTR_INSECT_START diff --git a/src/ac_furniture_data.c_inc b/src/ac_furniture_data.c_inc new file mode 100644 index 00000000..a905e8e2 --- /dev/null +++ b/src/ac_furniture_data.c_inc @@ -0,0 +1,2603 @@ +typedef struct { + f32 x[2]; + f32 z[2]; + f32 edge[2]; +} aFTR_size_info_c; + +static aFTR_size_info_c l_size_typeA = { { 20.0f, 20.0f }, { 20.0f, 20.0f }, { 0.1f, 0.1f } }; +static aFTR_size_info_c l_size_typeB_90 = { { 60.0f, 20.0f }, { 20.0f, 20.0f }, { 0.1f, 0.05f } }; +static aFTR_size_info_c l_size_typeB_180 = { { 20.0f, 60.0f }, { 20.0f, 20.0f }, { 0.05f, 0.1f } }; +static aFTR_size_info_c l_size_typeB_270 = { { 20.0f, 20.0f }, { 60.0f, 20.0f }, { 0.1f, 0.05f } }; +static aFTR_size_info_c l_size_typeB_0 = { { 20.0f, 20.0f }, { 20.0f, 60.0f }, { 0.05f, 0.1 } }; +static aFTR_size_info_c l_size_typeC = { { 40.0f, 40.0f }, { 40.0f, 40.0f }, { 0.05f, 0.05f } }; + +static aFTR_size_info_c* aMR_furniture_size_table[] = { + &l_size_typeB_90, &l_size_typeB_180, &l_size_typeB_270, &l_size_typeB_0, &l_size_typeA, &l_size_typeC, +}; + +static aFTR_PROFILE* furniture_quality[] = { + &iam_sum_hal_chest02, + &iam_sum_clchest03, + &iam_sum_blue_bureau01, + &iam_kob_locker1, + &iam_sum_x_chest01, + &iam_sum_whi_chest02, + &iam_sum_ratan_chest02, + &iam_sum_log_chest02, + &iam_sum_liccachest, + &iam_sum_gre_chest02, + &iam_sum_fruitchest03, + &iam_sum_cont_chest02, + &iam_sum_blue_cab01, + &iam_sum_bla_chest03, + &iam_sum_asi_chest03, + &iam_sum_x_chest02, + &iam_sum_whi_chest01, + &iam_sum_ratan_chest01, + &iam_sum_log_chest01, + &iam_sum_liccalowchest, + &iam_sum_hal_chest03, + &iam_sum_gre_chest03, + &iam_sum_fruitchest01, + &iam_sum_cont_chest03, + &iam_sum_classicchest01, + &iam_sum_blue_lowchest01, + &iam_sum_bla_chest01, + &iam_sum_asi_chest02, + &iam_nog_tri_chest01, + &iam_nog_tri_chest02, + &iam_nog_tri_chest03, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_nog_fan01, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_ari_isu01, + &iam_ari_table01, + &iam_ari_reizou01, + &iam_dummy, + &iam_dummy, + &iam_sum_sofe01, + &iam_sum_sofe02, + &iam_dummy, + &iam_ari_kitchen01, + &iam_sum_sofe03, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_sum_guitar01, + &iam_sum_guitar02, + &iam_sum_guitar03, + &iam_sum_doll01, + &iam_sum_doll02, + &iam_sum_doll03, + &iam_sum_doll04, + &iam_sum_classiccabinet01, + &iam_sum_classicchair01, + &iam_sum_classicchest02, + &iam_sum_classictable01, + &iam_sum_classicwardrope01, + &iam_sum_clchair02, + &iam_sum_cupboard01, + &iam_sum_desk01, + &iam_sum_doll05, + &iam_sum_doll06, + &iam_sum_doll07, + &iam_sum_doll08, + &iam_sum_doll09, + &iam_sum_doll10, + &iam_sum_globe01, + &iam_sum_kitchair01, + &iam_sum_kittable01, + &iam_sum_tv01, + &iam_sum_totemp01, + &iam_sum_totemp02, + &iam_sum_totemp03, + &iam_sum_totemp04, + &iam_sum_taiko01, + &iam_sum_stove01, + &iam_sum_stereo01, + &iam_sum_ratan_isu01, + &iam_sum_oldsofa01, + &iam_sum_liccatable, + &iam_sum_liccasofa, + &iam_sum_liccapiano, + &iam_sum_liccalanp, + &iam_sum_liccakitchen, + &iam_sum_liccachair, + &iam_sum_liccabed, + &iam_sum_oldclk01, + &iam_sum_ratan_bed01, + &iam_sum_golfbag01, + &iam_sum_golfbag02, + &iam_sum_golfbag03, + &iam_sum_bookcht01, + &iam_sum_chair01, + &iam_sum_cont_sofa01, + &iam_sum_cont_sofa02, + &iam_sum_cont_table01, + &iam_sum_cont_cab01, + &iam_sum_cont_chest01, + &iam_sum_cont_chair01, + &iam_sum_cont_bed01, + &iam_sum_cont_table02, + &iam_sum_comp01, + &iam_kob_jimudesk, + &iam_kob_mastersword, + &iam_kob_ncube, + &iam_sum_tekin01, + &iam_sum_biwa01, + &iam_sum_conga01, + &iam_sum_shoukaki, + &iam_sum_col_chair01, + &iam_sum_col_chair02, + &iam_sum_col_chair03, + &iam_sum_conpo01, + &iam_kob_pipeisu, + &iam_sum_liccamirror, + &iam_sum_pet01, + &iam_sum_timpani01, + &iam_dummy, + &iam_sum_bdcake01, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_sum_sabo01, + &iam_sum_sabo02, + &iam_sum_clbed02, + &iam_sum_tv02, + &iam_sum_liccalowtable, + &iam_dummy, + &iam_dummy, + &iam_sum_touro01, + &iam_sum_touro02, + &iam_sum_touro03, + &iam_kob_jimuisu, + &iam_kob_getabako1, + &iam_kob_getabako2, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_kob_rika_desk, + &iam_dummy, + &iam_sum_touro04, + &iam_sum_taru01, + &iam_sum_taru02, + &iam_kob_tobibako, + &iam_kon_tukue, + &iam_sum_mezaclock, + &iam_sum_poptable01, + &iam_sum_poptable02, + &iam_sum_poptable03, + &iam_kon_tubo, + &iam_sum_popchair01, + &iam_sum_popchair02, + &iam_sum_popchair03, + &iam_sum_suberi01, + &iam_sum_wc01, + &iam_sum_wc02, + &iam_tak_table02, + &iam_tak_isu03, + &iam_kon_tubo2, + &iam_kon_tubo3, + &iam_sum_misin01, + &iam_sum_billiads, + &iam_sum_art01, + &iam_ike_art_ang, + &iam_ike_art_sya, + &iam_sum_art04, + &iam_sum_art05, + &iam_sum_art06, + &iam_ike_art_fel, + &iam_sum_art08, + &iam_sum_art09, + &iam_sum_art10, + &iam_sum_art11, + &iam_sum_art12, + &iam_sum_art13, + &iam_sum_art14, + &iam_sum_art15, + &iam_sum_fruitbed01, + &iam_sum_fruitchair01, + &iam_dummy, + &iam_sum_fruittable01, + &iam_sum_fruittv01, + &iam_sum_takkyu, + &iam_sum_harp, + &iam_sum_log_hatoclk, + &iam_sum_kisha, + &iam_sum_mizunomi, + &iam_sum_okiagari01, + &iam_dummy, + &iam_sum_slot, + &iam_sum_asi_chair01, + &iam_sum_asi_chair02, + &iam_sum_asi_chest01, + &iam_sum_asi_lanp01, + &iam_sum_pl_caladium01, + &iam_sum_pl_shuroci, + &iam_sum_asi_screen01, + &iam_sum_asi_table01, + &iam_sum_asi_taiko, + &iam_sum_bla_bed01, + &iam_dummy, + &iam_sum_bla_chest02, + &iam_sum_bla_desk01, + &iam_sum_bla_sofa02, + &iam_sum_bla_table01, + &iam_sum_blue_bed01, + &iam_sum_blue_bench01, + &iam_sum_blue_chair01, + &iam_sum_blue_chest01, + &iam_sum_blue_chest02, + &iam_sum_blue_table01, + &iam_sum_gre_bed01, + &iam_sum_gre_chair01, + &iam_sum_gre_chair02, + &iam_sum_gre_chest01, + &iam_sum_gre_counter01, + &iam_sum_gre_lanp01, + &iam_sum_gre_table01, + &iam_sum_log_bed01, + &iam_sum_log_chair01, + &iam_sum_log_chair02, + &iam_sum_log_chest03, + &iam_sum_log_table01, + &iam_sum_pl_aloe01, + &iam_sum_pl_ananas, + &iam_sum_pl_cocos, + &iam_sum_pl_compacta, + &iam_sum_pl_dracaena, + &iam_sum_pl_gomunoki, + &iam_sum_pl_pothos, + &iam_sum_pl_yamayasi, + &iam_sum_fruittable02, + &iam_sum_fruitchair02, + &iam_sum_pl_benjyami, + &iam_sum_pl_draca02, + &iam_sum_pl_kuroton, + &iam_sum_pl_pakila, + &iam_sum_pl_hirasabo, + &iam_tak_metro, + &iam_kon_sisiodosi, + &iam_sum_bon_matu01, + &iam_sum_bon_matu02, + &iam_tak_barber, + &iam_sum_bon_matu03, + &iam_sum_bon_ume, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_sum_bon_boke, + &iam_sum_bon_satuki, + &iam_sum_bon_sanshu, + &iam_kon_cracker, + &iam_tak_cone01, + &iam_dummy, + &iam_tak_cone03, + &iam_dummy, + &iam_sum_bon_momiji, + &iam_sum_bon_pira, + &iam_sum_bon_turu, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_kon_jihanki02, + &iam_tak_hole01, + &iam_kon_jihanki03, + &iam_dummy, + &iam_tak_drum02, + &iam_dummy, + &iam_dummy, + &iam_tak_tekkin, + &iam_dummy, + &iam_dummy, + &iam_sum_fruitchair03, + &iam_sum_fruitchair04, + &iam_sum_fruittable03, + &iam_dummy, + &iam_kon_gomi03, + &iam_kon_gomi04, + &iam_sum_viola01, + &iam_sum_bass01, + &iam_sum_cello01, + &iam_sum_piano01, + &iam_dummy, + &iam_tak_neko, + &iam_dummy, + &iam_sum_hal_pkin, + &iam_dummy, + &iam_tak_yaji, + &iam_kon_isi01, + &iam_kon_isi02, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_sum_hal_bed01, + &iam_sum_hal_box01, + &iam_sum_hal_chair01, + &iam_dummy, + &iam_sum_hal_chest01, + &iam_sum_hal_sofa01, + &iam_sum_hal_table01, + &iam_tak_apollo1, + &iam_tak_eisei, + &iam_kon_isi03, + &iam_kon_isi04, + &iam_kon_isi05, + &iam_tak_ufo, + &iam_kon_isi06, + &iam_kon_pound, + &iam_tak_rocket1, + &iam_tak_astro, + &iam_sum_hal_clk01, + &iam_sum_hal_lanp01, + &iam_sum_asi_bed01, + &iam_sum_asi_table02, + &iam_tak_asteroid1, + &iam_sum_ratan_lanp, + &iam_sum_ratan_table01, + &iam_dummy, + &iam_kon_taiju, + &iam_dummy, + &iam_dummy, + &iam_sum_ratan_screen, + &iam_sum_ratan_mirror, + &iam_sum_ratan_isu02, + &iam_sum_ratan_chest03, + &iam_tak_arwing, + &iam_tak_mooncar, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_sum_blue_clk, + &iam_tak_moti, + &iam_sum_hal_mirror01, + &iam_sum_gre_desk01, + &iam_dummy, + &iam_sum_bla_chair02, + &iam_sum_bla_table02, + &iam_tak_station, + &iam_dummy, + &iam_sum_log_chair03, + &iam_sum_whi_bed01, + &iam_tak_shuttle, + &iam_sum_whi_mirror, + &iam_sum_whi_sofa01, + &iam_sum_whi_lanp, + &iam_sum_log_table02, + &iam_dummy, + &iam_dummy, + &iam_sum_uwa_cup01, + &iam_sum_uwa_poto01, + &iam_sum_uwa_vase01, + &iam_sum_uwa_vase02, + &iam_sum_uwa_vase03, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_hnw_common, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_fmanekin, + &iam_myfmanekin, + &iam_myfmanekin, + &iam_myfmanekin, + &iam_myfmanekin, + &iam_myfmanekin, + &iam_myfmanekin, + &iam_myfmanekin, + &iam_myfmanekin, + &iam_sum_monshiro, + &iam_sum_monki, + &iam_sum_kiageha, + &iam_sum_ohmurasaki, + &iam_sum_minmin, + &iam_sum_tukutuku, + &iam_sum_higurashi, + &iam_sum_abura, + &iam_sum_hachi, + &iam_sum_shiokara, + &iam_sum_akiakane, + &iam_sum_ginyanma, + &iam_sum_oniyanma, + &iam_sum_syouryou, + &iam_sum_tonosama, + &iam_sum_koorogi, + &iam_sum_kirigirisu, + &iam_sum_suzumushi, + &iam_sum_matumushi, + &iam_sum_kanabun, + &iam_sum_kabuto, + &iam_sum_hirata, + &iam_sum_tamamushi, + &iam_sum_gomadara, + &iam_sum_tentou, + &iam_sum_nanahoshi, + &iam_sum_kamakiri, + &iam_sum_genji, + &iam_sum_danna, + &iam_sum_nokogiri, + &iam_sum_miyama, + &iam_sum_okuwa, + &iam_nog_maimai, + &iam_nog_kera, + &iam_nog_amenbo, + &iam_nog_mino, + &iam_nog_dango, + &iam_nog_kumo, + &iam_nog_ari, + &iam_nog_ka, + &iam_sum_funa, + &iam_sum_hera, + &iam_sum_koi, + &iam_sum_nisiki, + &iam_sum_namazu, + &iam_sum_bass, + &iam_sum_bassm, + &iam_sum_bassl, + &iam_sum_gill, + &iam_sum_oonamazu, + &iam_sum_raigyo, + &iam_sum_nigoi, + &iam_sum_ugui, + &iam_sum_oikawa, + &iam_sum_tanago, + &iam_sum_dojyo, + &iam_sum_wakasagi, + &iam_sum_ayu, + &iam_sum_yamame, + &iam_sum_iwana, + &iam_sum_niji, + &iam_sum_ito, + &iam_sum_sake, + &iam_sum_kingyo, + &iam_sum_pirania, + &iam_sum_aroana, + &iam_sum_unagi, + &iam_sum_donko, + &iam_sum_angel, + &iam_sum_gupi, + &iam_sum_demekin, + &iam_sum_kaseki, + &iam_nog_zarigani, + &iam_nog_kaeru, + &iam_nog_medaka, + &iam_nog_kurage, + &iam_nog_suzuki, + &iam_nog_tai, + &iam_nog_isidai, + &iam_nog_piraluku, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_fumbrella, + &iam_myfumbrella, + &iam_myfumbrella, + &iam_myfumbrella, + &iam_myfumbrella, + &iam_myfumbrella, + &iam_myfumbrella, + &iam_myfumbrella, + &iam_myfumbrella, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_famicom_common, + &iam_kob_disksystem8, + &iam_sum_chikuon01, + &iam_sum_chikuon02, + &iam_sum_jukebox, + &iam_sum_radio01, + &iam_sum_radio02, + &iam_sum_conpo02, + &iam_sum_stereo02, + &iam_sum_lv_stereo, + &iam_sum_x_lanp, + &iam_sum_x_chair01, + &iam_sum_x_chest03, + &iam_sum_x_sofa01, + &iam_sum_x_bed01, + &iam_sum_x_clk, + &iam_sum_x_table01, + &iam_sum_x_piano, + &iam_sum_doll11, + &iam_sum_roboconpo, + &iam_sum_saiconpo, + &iam_sum_fruitclk, + &iam_sum_roboclk, + &iam_kon_ameclock, + &iam_kon_atqclock, + &iam_sum_reco01, + &iam_sum_casse01, + &iam_sum_md01, + &iam_kon_grclock, + &iam_kon_waclock, + &iam_kon_redclock, + &iam_kon_blueclock, + &iam_kon_mimiclock, + &iam_dummy, + &iam_dummy, + &iam_kon_musya, + &iam_dummy, + &iam_dummy, + &iam_kon_xtree02, + &iam_nog_rookW, + &iam_nog_rookB, + &iam_nog_queenW, + &iam_nog_queenB, + &iam_nog_bishopW, + &iam_nog_bishopB, + &iam_nog_kingW, + &iam_nog_kingB, + &iam_nog_knightW, + &iam_nog_knightB, + &iam_nog_pawnW, + &iam_nog_pawnB, + &iam_nog_xtree, + &iam_nog_tri_clock01, + &iam_nog_tri_bed01, + &iam_nog_tri_table01, + &iam_nog_tri_sofa01, + &iam_nog_tri_audio01, + &iam_nog_tri_chair01, + &iam_nog_tri_rack01, + &iam_dummy, + &iam_dummy, + &iam_sum_kokuban, + &iam_sum_baketu, + &iam_din_trikera_head, + &iam_din_trikera_tail, + &iam_din_trikera_body, + &iam_din_trex_head, + &iam_din_trex_tail, + &iam_din_trex_body, + &iam_din_bront_head, + &iam_din_bront_tail, + &iam_din_bront_body, + &iam_din_stego_head, + &iam_din_stego_tail, + &iam_din_stego_body, + &iam_din_ptera_head, + &iam_din_ptera_Rwing, + &iam_din_ptera_Lwing, + &iam_din_hutaba_head, + &iam_din_hutaba_neck, + &iam_din_hutaba_body, + &iam_din_mammoth_head, + &iam_din_mammoth_body, + &iam_din_amber, + &iam_din_stump, + &iam_din_ammonite, + &iam_din_egg, + &iam_din_trilobite, + &iam_sum_bla_lanp, + &iam_kon_snowfreezer, + &iam_kon_snowtable, + &iam_kon_snowbed, + &iam_tak_snowisu, + &iam_tak_snowlamp, + &iam_kon_snowsofa, + &iam_kon_snowtv, + &iam_kon_snowtansu, + &iam_kon_snowbox, + &iam_kon_snowclock, + &iam_din_trikera_dummy, + &iam_din_trex_dummy, + &iam_din_bront_dummy, + &iam_din_ptera_dummy, + &iam_din_hutaba_dummy, + &iam_din_mammoth_dummy, + &iam_din_stego_dummyA, + &iam_din_stego_dummyB, + &iam_din_dummy, + &iam_tak_syogi, + &iam_ike_jny_makada01, + &iam_dummy, + &iam_ike_pst_pig01, + &iam_ike_pst_tesyu01, + &iam_ike_jny_afmen01, + &iam_ike_jny_rosia01, + &iam_hayakawa_famicom, + &iam_ike_jny_botle01, + &iam_ike_jny_hariko01, + &iam_ike_jny_moai01, + &iam_radio_test, + &iam_ike_jny_gojyu01, + &iam_ike_jny_kibori01, + &iam_ike_jny_truth01, + &iam_ike_jny_sirser01, + &iam_ike_jny_pisa01, + &iam_tak_lion, + &iam_ike_jny_syon01, + &iam_ike_jny_tower01, + &iam_nog_balloon_common, + &iam_nog_balloon_common, + &iam_nog_balloon_common, + &iam_nog_balloon_common, + &iam_nog_balloon_common, + &iam_nog_balloon_common, + &iam_nog_balloon_common, + &iam_nog_balloon_common, + &iam_tak_megami, + &iam_ike_jny_gate01, + &iam_tak_money, + &iam_ike_jny_ningyo01, + &iam_nog_yubin, + &iam_nog_myhome2, + &iam_nog_myhome4, + &iam_nog_koban, + &iam_nog_museum, + &iam_tak_yoroi, + &iam_dummy, + &iam_dummy, + &iam_dummy, + &iam_ike_k_otome01, + &iam_nog_yamishop, + &iam_nog_uranai, + &iam_ike_jny_sirser201, + &iam_ike_k_tanabata01, + &iam_dummy, + &iam_dummy, + &iam_nog_shop1, + &iam_ike_jny_houi01, + &iam_dummy, + &iam_dummy, + &iam_tak_toudai, + &iam_ike_k_sum01, + &iam_nog_s_tree, + &iam_nog_f_tree, + &iam_nog_zassou, + &iam_tak_tailor, + &iam_nog_dump, + &iam_dummy, + &iam_nog_snowman, + &iam_ike_k_iveboy01, + &iam_dummy, + &iam_tak_moon, + &iam_ike_k_kid01, + &iam_iid_ningyou, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_station, + &iam_nog_shrine, + &iam_nog_flat, + &iam_nog_rail, + &iam_nog_earth, + &iam_ike_k_kid02, + &iam_nog_mikanbox, + &iam_nog_collegenote, + &iam_nog_schoolnote, + &iam_nog_systemnote, + &iam_nog_harddiary, + &iam_nog_tudurinote, + &iam_iid_diary, + &iam_iid_funediary, + &iam_iid_mdiary, + &iam_iid_newdiary, + &iam_tak_nikki01, + &iam_ike_nikki_fan1, + &iam_ike_nikki_fan2, + &iam_ike_nikki_fan3, + &iam_ike_nikki_fan4, + &iam_ike_nikki_fan5, + &iam_ike_nikki_wafu1, + &iam_gold_item, + &iam_gold_item, + &iam_gold_item, + &iam_gold_item, + &iam_utiwa, + &iam_utiwa, + &iam_utiwa, + &iam_utiwa, + &iam_utiwa, + &iam_utiwa, + &iam_utiwa, + &iam_utiwa, + &iam_kazaguruma, + &iam_kazaguruma, + &iam_kazaguruma, + &iam_kazaguruma, + &iam_kazaguruma, + &iam_kazaguruma, + &iam_kazaguruma, + &iam_kazaguruma, + &iam_tool, + &iam_tool, + &iam_tool, + &iam_tool, + &iam_nog_nabe, + &iam_ike_kama_danro01, + &iam_nog_kamakura, + &iam_nog_w_tree, + &iam_tak_ice, + &iam_ike_island_hako01, + &iam_nog_beachbed, + &iam_nog_beachtable, + &iam_dummy, + &iam_iid_surf, + &iam_iid_snow, + &iam_tak_tetra, + &iam_ike_island_uku01, + &iam_ike_island_sensui01, + &iam_iid_yuki, + &iam_dummy, + &iam_dummy, + &iam_tak_sori01, + &iam_iid_benti, + &iam_tak_cube, + &iam_iku_denko, + &iam_yaz_rocket, + &iam_iku_slip, + &iam_iku_ukai, + &iam_iku_work, + &iam_hos_deskL, + &iam_hos_deskR, + &iam_hos_flip, + &iam_iku_flagman, + &iam_yaz_fish_trophy, + &iam_iku_jersey, + &iam_iku_reducespeed, + &iam_dummy, + &iam_hos_Tdesk, + &iam_iku_hazardous_top, + &iam_dummy, + &iam_iku_sawhousev, + &iam_dummy, + &iam_iku_bugzapper, + &iam_yaz_telescope, + &iam_iku_cocoa, + &iam_yaz_b_bath, + &iam_sugi_barbecue, + &iam_sugi_radiatorl, + &iam_sugi_alchair, + &iam_sugi_chesstable, + &iam_iku_candy, + &iam_sugi_kpool, + &iam_iku_cement, + &iam_iku_jack, + &iam_sugi_torch, + &iam_yaz_b_house, + &iam_yos_pbstove, + &iam_iku_busstop, + &iam_tak_ham1, + &iam_iku_flip_top, + &iam_yos_kflag, + &iam_tak_nes01, + &iam_yos_b_feeder, + &iam_iku_chair, + &iam_iku_roller, + &iam_yos_flamingo, + &iam_yos_mailbox, + &iam_yaz_candle, + &iam_iku_ham, + &iam_yos_gnome, + &iam_yos_flamingo2, + &iam_iku_gold_green, + &iam_iku_gold_red, + &iam_iku_tumble, + &iam_iku_cow, + &iam_iku_orange, + &iam_iku_saku_a, + &iam_iku_saku_b, + &iam_yaz_tub, + &iam_yos_luigi, + &iam_yos_mario, + &iam_iku_turkey_lamp, + &iam_yaz_wagon, + &iam_yos_terrace, + &iam_hos_piknic, + &iam_iku_turkey_table, + &iam_iku_turkey_TV, + &iam_iku_turkey_bed, + &iam_yaz_turkey_chair, + &iam_yos_turkey_watch, + &iam_hos_turkey_sofa, + &iam_iku_mario_dokan, + &iam_iku_mario_renga, + &iam_yaz_turkey_closet, + &iam_hos_mario_hata, + &iam_yaz_turkey_chest, + &iam_hos_mario_kinoko, + &iam_yos_turkey_mirror, + &iam_iku_mario_coin, + &iam_iku_mario_hatena, + &iam_iku_mario_star, + &iam_iku_mario_koura, + &iam_iku_mario_taihou, + &iam_yos_cactus, + &iam_yaz_mario_flower, + &iam_yos_wheel, + &iam_iku_ido, + &iam_ike_prores_fense01, + &iam_ike_prores_ling01, + &iam_ike_prores_ling02, + &iam_ike_prores_ling03, + &iam_ike_prores_mat01, + &iam_ike_prores_table01, + &iam_ike_prores_punch01, + &iam_ike_prores_sandbag01, + &iam_ike_prores_bench01, + &iam_ike_tent_fire01, + &iam_ike_tent_fire02, + &iam_ike_tent_kayak01, + &iam_nog_sprinkler, + &iam_tak_tent, + &iam_ike_tent_knap01, + &iam_ike_fish_tro2, + &iam_nog_flower, + &iam_nog_flower, + &iam_nog_flower, + &iam_nog_flower, + &iam_nog_flower, + &iam_nog_flower, + &iam_nog_flower, + &iam_nog_flower, + &iam_nog_flower, + &iam_tak_tent_lamp, + &iam_nog_lawnmower, + &iam_tak_tent_box, + &iam_ike_tent_bike01, + &iam_ike_tent_sleepbag01, + &iam_nog_burner, + &iam_nog_cornucopia, + &iam_nog_gong, + &iam_tak_noise, + &iam_tak_stew, + &iam_dummy, +}; + +// clang-format off +static u8 l_place_table[] = { + 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, +}; +// clang-format on + +// clang-format off +static u8 l_place_table2[] = { + 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, + 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201 +}; +// clang-format on + +static u8* aMR_place_table[] = { + l_place_table, + l_place_table2, +}; + +// clang-format off +static u8 aMR_layer_set_info[] = { + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_NORMAL, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_ON_SURFACE, + aFTR_SET_TYPE_NORMAL, +}; +// clang-format on diff --git a/src/ac_my_room.c b/src/ac_my_room.c new file mode 100644 index 00000000..36304007 --- /dev/null +++ b/src/ac_my_room.c @@ -0,0 +1,2274 @@ +#include "ac_my_room.h" + +#include "m_bgm.h" +#include "m_name_table.h" +#include "ac_furniture.h" +#include "f_furniture.h" +#include "m_common_data.h" +#include "libultra/libultra.h" +#include "m_malloc.h" +#include "m_cockroach.h" +#include "m_msg.h" +#include "dolphin/card.h" + +enum { + aMR_ICON_LEAF, + aMR_ICON_HANIWA, + aMR_ICON_CLOTH, + aMR_ICON_UMBRELLA, + aMR_ICON_BONE, + aMR_ICON_DIARY, + + aMR_ICON_NUM +}; + +/* Inclusive bounds */ +#define aMR_MIN_BOUND 1 +#define aMR_MAX_BOUND 8 + +#define aMR_FTR_BANK_NUM 100 +#define aMR_FTR_BANK_SIZE 0x800 + +#define aMR_CLIP (Common_Get(clip).my_room_clip) +#define aMR_BOUNDS_OK(x, z) \ + ((x) > (aMR_MIN_BOUND - 1) && (x) < (aMR_MAX_BOUND + 1) && (z) > (aMR_MIN_BOUND - 1) && (z) < (aMR_MAX_BOUND + 1)) + +enum { + aMR_MSG_STATE_NONE, + aMR_MSG_STATE_WAIT_MSG, + aMR_MSG_STATE_OWNER_NO_ITEM, + aMR_MSG_STATE_OWNER_EXIST_ITEM, + aMR_MSG_STATE_OWNER_EXIST_ITEM_ITEM_COUNT2, + aMR_MSG_STATE_OWNER_WHICH_PUT_OUT1, + aMR_MSG_STATE_OWNER_WHICH_PUT_OUT2, + aMR_MSG_STATE_OWNER_WHICH_PUT_OUT3, + aMR_MSG_STATE_OWNER_WAIT_WHICH_PUT_OUT, + aMR_MSG_STATE_OTHER_NO_ITEM, + aMR_MSG_STATE_OTHER_EXIST_ITEM1, + aMR_MSG_STATE_OTHER_EXIST_ITEM2, + aMR_MSG_STATE_OTHER_EXIST_ITEM3, + aMR_MSG_STATE_FULL_PLAYER_ITEM, + aMR_MSG_STATE_OPEN_SUBMENU, + aMR_MSG_STATE_ITEM_PUT_IN, + aMR_MSG_STATE_WAIT_CLOSE_FTR, + aMR_MSG_STATE_REQUEST_CLOSE_FTR, + aMR_MSG_STATE_REQUEST_FULL_BAG, + aMR_MSG_STATE_CAN_NOT_CLEAN, + aMR_MSG_STATE_CAN_NOT_CLEAN_MD, + aMR_MSG_STATE_OPEN_SET_ITEM_SUBMENU, + aMR_MSG_STATE_ITEM_SET_SUBMENU, + aMR_MSG_STATE_WAIT_MD, + aMR_MSG_STATE_OWNER_NO_MD, + aMR_MSG_STATE_OWNER_EXIST_MD, + aMR_MSG_STATE_OWNER_EXIST_MD2, + aMR_MSG_STATE_OTHER_NO_MD, + aMR_MSG_STATE_OTHER_EXIST_MD, + aMR_MSG_STATE_FULL_PLAYER_MD, + aMR_MSG_STATE_OPENMD_SUBMENU, + aMR_MSG_STATE_MD_PUT_IN, + aMR_MSG_STATE_OPEN_MUSIC_BOX, + aMR_MSG_STATE_MUSIC_BOX_MD_PUT_IN, + aMR_MSG_STATE_WAIT_CLOSE_MD, + aMR_MSG_STATE_REQUEST_CLOSE_MD, + aMR_MSG_STATE_REQUEST_FULL_BAG_MD, + aMR_MSG_STATE_CAN_NOT_MD_CLEAN, + aMR_MSG_STATE_OPEN_EXCHANGE_MD_SUBMENU, + aMR_MSG_STATE_MD_EXCHANGE_SUBMENU, + aMR_MSG_STATE_QQQ_EMULATOR, + aMR_MSG_STATE_EXPLAIN_EMULATOR, + aMR_MSG_STATE_QQQ_EMULATOR_MEMORY1, + aMR_MSG_STATE_EXPLAIN_EMULATOR_MEMORY, + aMR_MSG_STATE_QQQ_EMULATOR_MEMORY2, + aMR_MSG_STATE_QQQ_EMULATOR_MEMORY_OVER3, + aMR_MSG_STATE_QQQ_REPEAT_DISPLAY1, + aMR_MSG_STATE_QQQ_REPEAT_DISPLAY1_2, + aMR_MSG_STATE_QQQ_REPEAT_DISPLAY2, + aMR_MSG_STATE_QQQ_REPEAT_DISPLAY2_2, + aMR_MSG_STATE_NO_PACK_NO_DATA, + aMR_MSG_STATE_WARNING_CANNOT_MAKE_SAVE_FILE, + aMR_MSG_STATE_NO_PACK_NO_DATA1, + aMR_MSG_STATE_NO_PACK_NO_DATA2, + aMR_MSG_STATE_HITOKOTO, + aMR_MSG_STATE_HITOKOTO1, + aMR_MSG_STATE_HITOKOTO2, + aMR_MSG_STATE_SAVE_FAMICOM, + aMR_MSG_STATE_WAIT_FAMICOM_BATU, + aMR_MSG_STATE_PREPARE_COMMUNICATION, + aMR_MSG_STATE_NOT_CONNECT_AGB, + aMR_MSG_STATE_CHECK_AGB_PROGRAM, + aMR_MSG_STATE_DELETE_AGB_PROGRAMQ, + aMR_MSG_STATE_START_EMU_DOWN_LOAD, + aMR_MSG_STATE_RECHECK_AGB_CONNECT, + + aMR_MSG_STATE_NUM +}; + +#include "../src/ac_furniture_data.c_inc" +#include "../src/ac_my_room_data.c_inc" + +typedef struct my_room_work_s { + FTR_ACTOR* ftr_actor_list; + u8* used_list; + int list_size; +} aMR_work_c; + +static aMR_work_c l_aMR_work; +static u8 l_bank_index_table[FTR_NUM]; +static u8* l_bank_address_table[aMR_FTR_BANK_NUM]; + +const f32 aMR_angle_table[4] = { 0.0f, 90.0f, 180.0f, 270.0f }; +const u8 l_typeB0_table[4] = { aFTR_SHAPE_TYPEB_0, aFTR_SHAPE_TYPEB_90, aFTR_SHAPE_TYPEB_180, aFTR_SHAPE_TYPEB_270 }; + +static int aMR_UnitNum2FtrItemNoFtrID(mActor_name_t* item_no, int* ftr_id, int ut_x, int ut_z, int layer); +static void aMR_ReserveDefaultBgm(ACTOR* actorx, FTR_ACTOR* ftr_actor); +static void aMR_ChangeMDBgm(ACTOR* actorx, FTR_ACTOR* ftr_actor); +static void aMR_SetFurniture2FG(FTR_ACTOR* ftr_actor, xyz_t pos, int on_flag); + +static aFTR_PROFILE* aMR_GetFurnitureProfile(u16 ftr_no) { + if (ftr_no < FTR_NUM) { + if (furniture_quality[ftr_no] != NULL) { + return furniture_quality[ftr_no]; + } + } else { + return &iam_dummy; + } + + return &iam_dummy; +} + +static int aMR_GetItemCountInFurniture(FTR_ACTOR* ftr_actor) { + int count = 0; + int i; + + for (i = 0; i < aFTR_KEEP_ITEM_COUNT; i++) { + if (ftr_actor->items[i] != EMPTY_NO) { + count++; + } + } + + return count; +} + +static void aMR_TidyItemInFurniture(FTR_ACTOR* ftr_actor) { + mActor_name_t temp_items[aFTR_KEEP_ITEM_COUNT]; + mActor_name_t* dst_p; + int i; + + for (i = 0; i < aFTR_KEEP_ITEM_COUNT; i++) { + temp_items[i] = ftr_actor->items[i]; + ftr_actor->items[i] = EMPTY_NO; + } + + dst_p = ftr_actor->items; + for (i = 0; i < aFTR_KEEP_ITEM_COUNT; i++) { + if (temp_items[i] != EMPTY_NO) { + *dst_p++ = temp_items[i]; + } + } +} + +static int aMR_ItemPutInFurniture(FTR_ACTOR* ftr_actor, mActor_name_t item) { + int i; + + for (i = 0; i < aFTR_KEEP_ITEM_COUNT; i++) { + if (ftr_actor->items[i] == EMPTY_NO) { + ftr_actor->items[i] = item; + return TRUE; + } + } + + return FALSE; +} + +static int aMR_ItemNo2IconNo(mActor_name_t item_no) { + if (ITEM_IS_FTR(item_no)) { + if (item_no >= FTR_COLLEGERULE && item_no <= FTR_CALLIGRAPHY_PAD_WEST) { + return aMR_ICON_DIARY; + } + + if (item_no >= HANIWA_START && item_no <= HANIWA_END) { + return aMR_ICON_HANIWA; + } + + if ((item_no >= FTR_UMBRELLA_START && item_no <= FTR_UMBRELLA_END) || + (item_no >= FTR_UMBRELLA_START && item_no <= FTR_MYUMBRELLA_END)) { + return aMR_ICON_UMBRELLA; + } + + if ((item_no >= FTR_CLOTH_START && item_no <= FTR_CLOTH_END) || + (item_no >= FTR_CLOTH_START && item_no <= FTR_CLOTH_MYMANNIQUIN_END)) { + return aMR_ICON_CLOTH; + } + + if (item_no >= FTR_DINO_START && item_no <= FTR_DINO_END) { + return aMR_ICON_BONE; + } + + return aMR_ICON_LEAF; + } + + return aMR_ICON_LEAF; +} + +static Gfx* aMR_IconNo2Gfx1(int icon_no) { + aMR_icon_display_data_c* icon; + + if (icon_no < 0) { + icon_no = 0; + } else if (icon_no >= aMR_ICON_NUM) { + icon_no = aMR_ICON_NUM - 1; + } + + return aMR_icon_display_data[icon_no].mat_gfx; +} + +static Gfx* aMR_IconNo2Gfx2(int icon_no) { + if (icon_no < 0) { + icon_no = 0; + } else if (icon_no >= aMR_ICON_NUM) { + icon_no = aMR_ICON_NUM - 1; + } + + return aMR_icon_display_data[icon_no].vtx_gfx; +} + +static mActor_name_t* aMR_GetLayerTopFg(s16 layer) { + return mFI_BkNum2UtFGTop_layer(0, 0, layer); +} + +u64* aMR_GetBitSwitchTable(int layer, MY_ROOM_ACTOR* my_room) { + mActor_name_t field_id = mFI_GetFieldId(); + + if (my_room->scene == SCENE_COTTAGE_MY) { + return &(&Save_Get(island).cottage.room.layer_main)[layer].ftr_switch; + } + + if ((mFI_GET_TYPE(field_id) == mFI_FIELD_PLAYER0_ROOM)) { + int idx = (mFI_GetFieldId() - mFI_FIELD_PLAYER0_ROOM) & 3; + + if (aMR_CLIP != NULL && aMR_CLIP->my_room_actor_p != NULL) { + int floor_no = mFI_GetPlayerHouseFloorNo(((MY_ROOM_ACTOR*)aMR_CLIP->my_room_actor_p)->scene); + + if (floor_no != -1) { + return &(&Save_Get(homes[idx]).floors[floor_no].layer_main)[layer].ftr_switch; + } + } + } + + return NULL; +} + +u32* aMR_GetHaniwaStepSaveData(s16 layer, MY_ROOM_ACTOR* my_room) { + mActor_name_t field_id = mFI_GetFieldId(); + + if (my_room->scene == SCENE_COTTAGE_MY) { + return (&Save_Get(island).cottage.room.layer_main)[layer].haniwa_step; + } + + if ((mFI_GET_TYPE(field_id) == mFI_FIELD_PLAYER0_ROOM)) { + int idx = (mFI_GetFieldId() - mFI_FIELD_PLAYER0_ROOM) & 3; + int floor_no = mFI_GetPlayerHouseFloorNo(my_room->scene); + + if (floor_no != -1) { + return (&Save_Get(homes[idx]).floors[floor_no].layer_main)[layer].haniwa_step; + } + } + + return NULL; +} + +static void aMR_ClearBitSwitch(FTR_ACTOR* ftr_actor) { + ftr_actor->switch_bit = FALSE; + ftr_actor->haniwa_step = -1; +} + +static void aMR_GetSwitchBit(FTR_ACTOR* ftr_actor, s16 placing_flag, MY_ROOM_ACTOR* my_room) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (placing_flag == TRUE) { + ftr_actor->switch_bit = TRUE; + } else { + u64* ftr_bit_switch_table = aMR_GetBitSwitchTable(ftr_actor->layer, my_room); + xyz_t pos = ftr_actor->position; + int ut_x; + int ut_z; + + pos.x -= 1.0f; + pos.z -= 1.0f; + + if (ftr_bit_switch_table != NULL && ftr_actor->layer < mCoBG_LAYER2 && + mFI_Wpos2UtNum_inBlock(&ut_x, &ut_z, pos) && aMR_BOUNDS_OK(ut_x, ut_z)) { + if (((*ftr_bit_switch_table) >> ((ut_x - 1 + (ut_z - 1) * 8) & 0x3F) & 1)) { + ftr_actor->switch_bit = TRUE; + } else { + ftr_actor->switch_bit = FALSE; + } + } else if ((mFI_CheckShop() == TRUE || mFI_GetFieldId() == mFI_FIELD_ROOM_BROKER_SHOP) && profile != NULL && + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK)) { + ftr_actor->switch_bit = FALSE; // disable music players in shops + } else { + ftr_actor->switch_bit = TRUE; + } + } +} + +static void aMR_GetHaniwaStep(FTR_ACTOR* ftr_actor, s16 placing_flag, int* step_idx, MY_ROOM_ACTOR* my_room) { + if (placing_flag == TRUE) { + ftr_actor->haniwa_step = -1; + } else { + int layer = ftr_actor->layer; + int ut_x; + int ut_z; + + if (layer < mCoBG_LAYER2 && mFI_Wpos2UtNum_inBlock(&ut_x, &ut_z, ftr_actor->position) && + aMR_BOUNDS_OK(ut_x, ut_z)) { + u32* step_table = aMR_GetHaniwaStepSaveData(layer, my_room); + + if (step_table != NULL) { + int shift = (ut_x - 1) * 4; + int idx = ut_z - 1; + + ftr_actor->haniwa_step = (step_table[idx] >> shift) & 0xF; + } else if (*step_idx < mFM_HANIWA_STEP_NUM) { + u8* step = mFI_GetHaniwaStepBlock(0, 0); + + ftr_actor->haniwa_step = step[*step_idx]; + (*step_idx)++; + } else { + ftr_actor->haniwa_step = -1; + } + } else { + ftr_actor->haniwa_step = -1; + } + } +} + +static void aMR_OperateSwitchBit(FTR_ACTOR* ftr_actor) { + if (ftr_actor->switch_bit == FALSE) { + ftr_actor->switch_bit = TRUE; + } else { + ftr_actor->switch_bit = FALSE; + } +} + +static void aMR_SaveHaniwaStepData(MY_ROOM_ACTOR* my_room) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used == TRUE && ftr_actor->name < FTR_NUM) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL && aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_HANIWA)) { + int ut_x; + int ut_z; + + if (mFI_Wpos2UtNum_inBlock(&ut_x, &ut_z, ftr_actor->position) && aMR_BOUNDS_OK(ut_x, ut_z)) { + u32* step_data = aMR_GetHaniwaStepSaveData(ftr_actor->layer, my_room); + + if (step_data != NULL) { + int shift = (ut_x - 1) * 4; + int idx = ut_z - 1; + + step_data[idx] &= ~(0xF << shift); + step_data[idx] |= (ftr_actor->haniwa_step & 0xF) << shift; + } + } + } + } + + ftr_actor++; + used++; + } +} + +static void aMR_SaveOneFtrSwitchData(mActor_name_t ftr_name, int ut_x, int ut_z, s16 layer, u64* switch_bit_table) { + if (ITEM_IS_FTR(ftr_name)) { + mActor_name_t name; + int ftr_id; + + if (aMR_UnitNum2FtrItemNoFtrID(&name, &ftr_id, ut_x, ut_z, layer)) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftr_id]; + + if (aMR_BOUNDS_OK(ut_x, ut_z)) { + int shift = (ut_x - 1 + (ut_z - 1) * 8) & 0x3F; + + if (ftr_actor->switch_bit) { + (*switch_bit_table) |= 1ull << shift; + } + } + } + } +} + +static void aMR_SaveSwitchData(MY_ROOM_ACTOR* my_room) { + if (l_aMR_work.ftr_actor_list != NULL && l_aMR_work.used_list != NULL) { + u64* bit_switch_table; + int ut_x; + int ut_z; + int layer; + mActor_name_t* fg_p; + + for (layer = mCoBG_LAYER0; layer < mCoBG_LAYER2; layer++) { + bit_switch_table = aMR_GetBitSwitchTable(layer, my_room); + + if (bit_switch_table != NULL) { + *bit_switch_table = 0; + fg_p = aMR_GetLayerTopFg(layer); + + if (fg_p != NULL) { + for (ut_z = aMR_MIN_BOUND; ut_z <= aMR_MAX_BOUND; ut_z++) { + for (ut_x = aMR_MIN_BOUND; ut_x <= aMR_MAX_BOUND; ut_x++) { + aMR_SaveOneFtrSwitchData(fg_p[ut_x + ut_z * UT_X_NUM], ut_x, ut_z, layer, bit_switch_table); + } + } + } + } + } + } +} + +static int aMR_CountFriendFurniture(FTR_ACTOR* ftr_actor, u8 friend_type) { + u8* used = l_aMR_work.used_list; + FTR_ACTOR* check_ftr_actor = l_aMR_work.ftr_actor_list; + int count = 0; + int i = 0; + + if (check_ftr_actor != NULL && used != NULL) { + for (i; i < l_aMR_work.list_size; i++) { + if (*used == TRUE && i != ftr_actor->id) { + if (check_ftr_actor->name == ftr_actor->name) { + if (friend_type == aMR_FRIEND_ALL) { + count++; + } else if (friend_type == aMR_FRIEND_ON) { + if (check_ftr_actor->switch_bit != FALSE) { + count++; + } + } else { /* aMR_FRIEND_OFF */ + if (check_ftr_actor->switch_bit == FALSE) { + count++; + } + } + } + } + + check_ftr_actor++; + used++; + } + + return count; + } + + return 0; +} + +static int aMR_GetWeight(int type) { + return 1; +} + +static void aMR_PlussWeight(ACTOR* actorx, FTR_ACTOR* ftr_actor) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->weight += aMR_GetWeight(ftr_actor->shape_type); +} + +static void aMR_MinusWeight(ACTOR* actorx, FTR_ACTOR* ftr_actor) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->weight -= aMR_GetWeight(ftr_actor->shape_type); +} + +static int aMR_WeightPossible(ACTOR* actorx, int type) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (aMR_GetWeight(type) + my_room->weight <= l_aMR_work.list_size) { + return TRUE; + } + + return FALSE; +} + +static int aMR_CheckFurnitureBankExist(u16 idx) { + if (l_bank_index_table[idx] != 255) { + return TRUE; + } + + return FALSE; +} + +static int aMR_GetFtrBankID(u16 idx) { + if (l_bank_index_table[idx] == 255) { + return -1; + } + + return l_bank_index_table[idx]; +} + +static u8* aMR_BankNo2BankAddress(int bank_no) { + if (bank_no == -1) { + return NULL; + } + + return l_bank_address_table[bank_no]; +} + +static u8* aMR_FtrNo2BankAddress(u16 ftr_no) { + return aMR_BankNo2BankAddress(aMR_GetFtrBankID(ftr_no)); +} + +static int aMR_SearchFurnitureBankVacancy(void) { + int i; + int count = 0; + + for (i = 0; i < FTR_NUM; i++) { + if (aMR_CheckFurnitureBankExist(i)) { + count++; + } + } + + if (count < l_aMR_work.list_size) { + return TRUE; + } + + return FALSE; +} + +static int aMR_SearchFreeFurnitureBankIdx(void) { + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + int j; + int count = 0; + + for (j = 0; j < FTR_NUM; j++) { + if (l_bank_index_table[j] == i) { + count++; + } + } + + if (count == 0) { + return i; + } + } + + return -1; +} + +static int aMR_SearchFreeFurnitureActorNumber(void) { + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (l_aMR_work.used_list[i] == FALSE) { + return i; + } + } + + return -1; +} + +// Part 1 + +static int aMR_CountAppointFurniture(u16 ftr_no) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + int count = 0; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (used[i]) { + if (ftr_no == ftr_actor[i].name) { + count++; + } + } + } + + return count; +} + +static int aMR_CountFurniture(void) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + int count = 0; + + if (ftr_actor != NULL && used != NULL) { + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used) { + count++; + } + + ftr_actor++; + used++; + } + } + + return count; +} + +static void aMR_UnitNumber2Position(xyz_t* pos, u8 type, int ut_x, int ut_z) { + pos->x = (f32)ut_x * mFI_UT_WORLDSIZE_X_F + mFI_UT_WORLDSIZE_HALF_X_F; + pos->y = 0.0f; + pos->z = (f32)ut_z * mFI_UT_WORLDSIZE_Z_F + mFI_UT_WORLDSIZE_HALF_Z_F; + + if (type == aFTR_SHAPE_TYPEC) { + pos->x += mFI_UT_WORLDSIZE_HALF_X_F; + pos->z += mFI_UT_WORLDSIZE_HALF_Z_F; + } +} + +static int aMR_Wpos2PlaceNumber(int* ut_x, int* ut_z, xyz_t pos, u8 type) { + if (type == aFTR_SHAPE_TYPEC) { + pos.x -= mFI_UT_WORLDSIZE_HALF_X_F; + pos.z -= mFI_UT_WORLDSIZE_HALF_Z_F; + } + + *ut_x = (int)(pos.x / mFI_UT_WORLDSIZE_X_F); + *ut_z = (int)(pos.z / mFI_UT_WORLDSIZE_Z_F); + + if (*ut_x < UT_X_NUM && *ut_z < UT_Z_NUM) { + return TRUE; + } + + return FALSE; +} + +static u8* aMR_GetLayerPlaceTable(s16 layer) { + if (layer == mCoBG_LAYER0) { + return aMR_place_table[0]; + } + + if (layer == mCoBG_LAYER1) { + return aMR_place_table[1]; + } + + return NULL; +} + +static int aMR_Direct2PlussUnit(int* ut_x, int* ut_z, int direct) { + switch (direct) { + case aMR_DIRECT_UP: + (*ut_z)--; + return TRUE; + case aMR_DIRECT_LEFT: + (*ut_x)--; + return TRUE; + case aMR_DIRECT_DOWN: + (*ut_z)++; + return TRUE; + case aMR_DIRECT_RIGHT: + (*ut_x)++; + return TRUE; + } + + return FALSE; +} + +static int aMR_GetTypeBPlaceInfo(int* x0, int* z0, int* x1, int* z1, u8 type, xyz_t pos) { + *x0 = (int)(pos.x / mFI_UT_WORLDSIZE_X_F); + *z0 = (int)(pos.z / mFI_UT_WORLDSIZE_Z_F); + + switch (type) { + case aFTR_SHAPE_TYPEB_90: + *x1 = *x0; + *z1 = *z0 - 1; + return TRUE; + case aFTR_SHAPE_TYPEB_180: + *x1 = *x0 - 1; + *z1 = *z0; + return TRUE; + case aFTR_SHAPE_TYPEB_270: + *x1 = *x0; + *z1 = *z0 + 1; + return TRUE; + case aFTR_SHAPE_TYPEB_0: + *x1 = *x0 + 1; + *z1 = *z0; + return TRUE; + } + + return FALSE; +} + +static void aMR_SetInfoFurnitureTable(u8 type, int idx, int id, s16 layer) { + u8* place_table = aMR_GetLayerPlaceTable(layer); + + switch (type) { + case aFTR_SHAPE_TYPEA: + place_table[idx] = id; + break; + case aFTR_SHAPE_TYPEB_90: + place_table[idx] = id; + place_table[idx - UT_X_NUM] = id; + break; + case aFTR_SHAPE_TYPEB_180: + place_table[idx] = id; + place_table[idx - 1] = id; + break; + case aFTR_SHAPE_TYPEB_270: + place_table[idx] = id; + place_table[idx + UT_X_NUM] = id; + break; + case aFTR_SHAPE_TYPEB_0: + place_table[idx] = id; + place_table[idx + 1] = id; + break; + case aFTR_SHAPE_TYPEC: + place_table[idx] = id; + place_table[idx + 1] = id; + place_table[idx + UT_X_NUM] = id; + place_table[idx + UT_X_NUM + 1] = id; + break; + } +} + +static void aMR_SetFurnitureType(FTR_ACTOR* ftr_actor, int angle) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile->shape == aFTR_SHAPE_TYPEB_0) { + ftr_actor->shape_type = l_typeB0_table[angle]; + ftr_actor->original_shape_type = profile->shape; + } else { + ftr_actor->shape_type = profile->shape; + ftr_actor->original_shape_type = profile->shape; + } +} + +static void aMR_SetFirstScale(FTR_ACTOR* ftr_actor) { + static xyz_t xyz0 = { 0.0f, 0.0f, 0.0f }; + static xyz_t xyz1 = { 1.0f, 1.0f, 1.0f }; + + if (ftr_actor->state == aFTR_STATE_BIRTH || ftr_actor->state == aFTR_STATE_BIRTH_WAIT) { + ftr_actor->scale = xyz0; + } else { + ftr_actor->scale = xyz1; + } + + if (ftr_actor->shape_type >= aFTR_SHAPE_TYPEB_90 && ftr_actor->shape_type <= aFTR_SHAPE_TYPEB_0) { + ftr_actor->birth_scale_modifier = 0.5f; + ftr_actor->birth_anim_step = 6000; + } else { + ftr_actor->birth_scale_modifier = 0.5f; + ftr_actor->birth_anim_step = 6000; + } + + ftr_actor->birth_anim_counter = 0; + ftr_actor->dust_timer = 0; +} + +static void aMR_DeleteFurnitreBank(u16 ftr_no) { + if (aMR_CountAppointFurniture(ftr_no) == 0) { + l_bank_index_table[ftr_no] = 255; + } +} + +static void aMR_InitHaniwaOnTable(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int* haniwa_on_table_p = my_room->haniwa_on_table; + int i; + + for (i = 0; i < aMR_HANIWA_ON_TABLE_NUM; i++, haniwa_on_table_p++) { + *haniwa_on_table_p = -1; + } +} + +static int aMR_GetHaniwaSwitchVac(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int* haniwa_on_table_p = my_room->haniwa_on_table; + int i; + + for (i = 0; i < aMR_HANIWA_ON_TABLE_NUM; i++) { + if (*haniwa_on_table_p == -1) { + return i; + } + haniwa_on_table_p++; + } + + return -1; +} + +static int aMR_TidyHaniwaOnTable(ACTOR* actorx, int idx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int* haniwa_on_table_p = my_room->haniwa_on_table; + int i; + + if (idx >= 0 && idx < aMR_HANIWA_ON_TABLE_NUM) { + if (idx == (aMR_HANIWA_ON_TABLE_NUM - 1)) { + haniwa_on_table_p[idx] = -1; + } else { + for (i = idx; i < (aMR_HANIWA_ON_TABLE_NUM - 1); i++) { + haniwa_on_table_p[i] = haniwa_on_table_p[i + 1]; + } + + haniwa_on_table_p[aMR_HANIWA_ON_TABLE_NUM - 1] = -1; + } + + return TRUE; + } + + return FALSE; +} + +static int aMR_HaniwaOffReport(ACTOR* actorx, int ftr_idx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int* haniwa_on_table_p = my_room->haniwa_on_table; + int i; + + for (i = 0; i < aMR_HANIWA_ON_TABLE_NUM; i++) { + if (*haniwa_on_table_p == ftr_idx) { + aMR_TidyHaniwaOnTable(actorx, i); + return TRUE; + } + + haniwa_on_table_p++; + } + + return FALSE; +} + +static int aMR_ClearHaniwaSwitch(ACTOR* actorx, FTR_ACTOR* ftr_actor) { + ftr_actor->switch_changed_flag = FALSE; + ftr_actor->switch_bit = FALSE; + return aMR_HaniwaOffReport(actorx, ftr_actor->id); +} + +static void aMR_HaniwaSwitchOn(ACTOR* actorx, FTR_ACTOR* ftr_actor) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int free_idx = aMR_GetHaniwaSwitchVac(actorx); + int* haniwa_on_table_p = my_room->haniwa_on_table; + + if (free_idx == -1) { + int ftr_id = haniwa_on_table_p[0]; + + if (ftr_id >= 0) { + FTR_ACTOR* target_ftr_actor = l_aMR_work.ftr_actor_list + ftr_id; + + /* Turn off the old active gyroid */ + target_ftr_actor->switch_changed_flag = TRUE; + target_ftr_actor->switch_bit = FALSE; + aMR_HaniwaOffReport(actorx, target_ftr_actor->id); + + /* Turn on new one */ + ftr_actor->switch_changed_flag = TRUE; + ftr_actor->switch_bit = TRUE; + haniwa_on_table_p[aMR_HANIWA_ON_TABLE_NUM - 1] = ftr_actor->id; + } + } else { + ftr_actor->switch_changed_flag = TRUE; + ftr_actor->switch_bit = TRUE; + haniwa_on_table_p[free_idx] = ftr_actor->id; + } +} + +static void aMR_SetSwitchStepData(FTR_ACTOR* ftr_actor, s16 placed_flag, MY_ROOM_ACTOR* my_room) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_HANIWA)) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* l_my_room = (MY_ROOM_ACTOR*)actorx; + + if (placed_flag == TRUE) { + aMR_HaniwaSwitchOn(actorx, ftr_actor); + aMR_GetHaniwaStep(ftr_actor, placed_flag, &l_my_room->haniwa_step_idx, l_my_room); + return; + } else { + aMR_GetSwitchBit(ftr_actor, placed_flag, l_my_room); + if (ftr_actor->switch_bit) { + aMR_HaniwaSwitchOn(actorx, ftr_actor); + } + + aMR_GetHaniwaStep(ftr_actor, placed_flag, &l_my_room->haniwa_step_idx, l_my_room); + return; + } + } + } else { + if (placed_flag == TRUE) { + ftr_actor->switch_bit = TRUE; + ftr_actor->haniwa_step = -1; + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_TOGGLE) || + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_START_DISABLED)) { + ftr_actor->switch_bit = FALSE; + } + } else { + aMR_GetSwitchBit(ftr_actor, placed_flag, my_room); + ftr_actor->haniwa_step = -1; + } + + return; + } + + ftr_actor->switch_bit = FALSE; + ftr_actor->haniwa_step = 0; +} + +static int aMR_SystemAnimeCt_UniqueCt(FTR_ACTOR* ftr_actor, aFTR_PROFILE* profile) { + if (profile->rig != NULL) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + cKF_Skeleton_R_c* skeleton = profile->rig->skeleton; + cKF_Animation_R_c* animation = profile->rig->animation; + + cKF_SkeletonInfo_R_ct(keyframe, skeleton, animation, ftr_actor->joint, ftr_actor->morph); + cKF_SkeletonInfo_R_init_standard_repeat(keyframe, animation, NULL); + cKF_SkeletonInfo_R_play(keyframe); + + keyframe->frame_control.speed = 0.5f; + } + + if (profile->vtable != NULL && profile->vtable->ct_proc != NULL) { + profile->vtable->ct_proc(ftr_actor, aMR_FtrNo2BankAddress(ftr_actor->name)); + } + + return TRUE; +} + +static int aMR_RegistMoveBg(FTR_ACTOR* ftr_actor, aFTR_PROFILE* profile) { + ftr_actor->move_bg_idx = -1; + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_NO_COLLISION) == FALSE || + mFI_CheckShop() == TRUE || mFI_GetFieldId() == mFI_FIELD_ROOM_BROKER_SHOP) { + f32 height; + + if (aMR_layer_set_info[ftr_actor->name] == aFTR_SET_TYPE_SURFACE) { + height = profile->height; + } else { + height = 100.0f; + } + + ftr_actor->move_bg_idx = + mCoBG_RegistMoveBg(&ftr_actor->bg_register, &ftr_actor->position, &ftr_actor->last_position, + &ftr_actor->s_angle_y, height, NULL, &ftr_actor->collision_scale, &ftr_actor->bg_contact, + &ftr_actor->base_position, profile->move_bg_type, mCoBG_ATTRIBUTE_STONE, 81.0f); + + if (ftr_actor->move_bg_idx != -1) { + return TRUE; + } else { + return FALSE; + } + } else { + return TRUE; + } +} + +static void aMR_MiniDiskCommonCt(FTR_ACTOR* ftr_actor, s16 placed_flag) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + int count; + int i; + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK)) { + if (placed_flag == FALSE) { + if (ftr_actor->switch_bit == TRUE) { + ftr_actor->haniwa_state = 1; + ftr_actor->switch_changed_flag = FALSE; + } + } else { + int home_idx = (mFI_GetFieldId() - mFI_FIELD_PLAYER0_ROOM) & 3; + + count = 0; + for (i = 0; i < MINIDISK_NUM; i++) { + u32* music_box = Save_Get(scene_no) == SCENE_COTTAGE_MY ? Save_Get(island).cottage.music_box + : Save_Get(homes[home_idx]).music_box; + + if (((music_box[(i / 32) & 1] >> (i & 31)) & 1) != 0) { + count++; + } + } + + /* Pick a random song to play when placed */ + if (count > 0) { + int sel = RANDOM(count); + + count = 0; + for (i = 0; i < MINIDISK_NUM; i++) { + u32* music_box = Save_Get(scene_no) == SCENE_COTTAGE_MY ? Save_Get(island).cottage.music_box + : Save_Get(homes[home_idx]).music_box; + + if (((music_box[(i / 32) & 1] >> (i & 31)) & 1) != 0) { + if (sel == count) { + ftr_actor->items[0] = ITM_MINIDISK_START + i; + // @BUG - missing break; + } + + count++; + } + } + } + + ftr_actor->switch_changed_flag = FALSE; + ftr_actor->switch_bit = FALSE; + } + } +} + +static void aMR_MiniDiskCommonDt(FTR_ACTOR* ftr_actor, ACTOR* actorx) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK) && + ftr_actor->switch_bit == TRUE) { + mBGMPsComp_delete_ps_room(my_room->bgm_info.md_no, 0); + my_room->bgm_info.active_flag = FALSE; + my_room->bgm_info.active_ftr_actor = NULL; + my_room->bgm_info.last_md_no = -1; + + /* Don't delete for aerobics radio music */ + if (my_room->bgm_info.md_no != 27) { + mBGMPsComp_MDPlayerPos_delete(); + } + } +} + +static void aMR_RadioCommonCt(FTR_ACTOR* ftr_actor, s16 placed_flag) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_RADIO_AEROBICS)) { + ftr_actor->switch_changed_flag = FALSE; + ftr_actor->switch_bit = FALSE; + } +} + +static void aMR_RadioCommonDt(FTR_ACTOR* ftr_actor, ACTOR* actorx) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_RADIO_AEROBICS) && + ftr_actor->switch_bit == TRUE) { + aMR_ReserveDefaultBgm(actorx, ftr_actor); + aMR_ChangeMDBgm(actorx, ftr_actor); + } +} + +static void aMR_ChangeMDBgm(ACTOR* actorx, FTR_ACTOR* ftr_actor) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if ((int)my_room->bgm_info.reserve_flag == TRUE) { + if (my_room->bgm_info.active_flag == FALSE) { + if (my_room->bgm_info.md_no != -1) { + mBGMPsComp_make_ps_room(my_room->bgm_info.md_no, 0); + + if (my_room->bgm_info.md_no != 27) { + mBGMPsComp_MDPlayerPos_make(); + } + + my_room->bgm_info.active_flag = TRUE; + my_room->bgm_info.active_ftr_actor = ftr_actor; + my_room->bgm_info.last_md_no = my_room->bgm_info.md_no; + } + } else if (my_room->bgm_info.md_no == -1) { + mBGMPsComp_delete_ps_room(my_room->bgm_info.last_md_no, 0); + mBGMPsComp_MDPlayerPos_delete(); + my_room->bgm_info.active_flag = FALSE; + my_room->bgm_info.active_ftr_actor = NULL; + my_room->bgm_info.last_md_no = my_room->bgm_info.md_no; + } else { + mBGMPsComp_delete_ps_room(my_room->bgm_info.last_md_no, 0); + if (my_room->bgm_info.last_md_no != 27) { + mBGMPsComp_MDPlayerPos_delete(); + } + + mBGMPsComp_make_ps_room(my_room->bgm_info.md_no, 0); + if (my_room->bgm_info.md_no != 27) { + mBGMPsComp_MDPlayerPos_make(); + } + + my_room->bgm_info.active_flag = TRUE; + my_room->bgm_info.active_ftr_actor = ftr_actor; + my_room->bgm_info.last_md_no = my_room->bgm_info.md_no; + } + + my_room->bgm_info.reserve_flag = FALSE; + my_room->bgm_info.last_md_no = my_room->bgm_info.md_no; + } +} + +static void aMR_ReserveBgm(ACTOR* actorx, int bgm_no, FTR_ACTOR* ftr_actor, s16 timer) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->bgm_info.reserve_flag = TRUE; + my_room->bgm_info.timer = timer; + my_room->bgm_info.md_no = bgm_no; + my_room->bgm_info.reserved_ftr_actor = ftr_actor; +} + +static void aMR_ReserveDefaultBgm(ACTOR* actorx, FTR_ACTOR* ftr_actor) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->bgm_info.reserve_flag = TRUE; + my_room->bgm_info.timer = 0; + my_room->bgm_info.md_no = -1; + my_room->bgm_info.reserved_ftr_actor = ftr_actor; +} + +static void aMR_AllMDSwitchOff(void) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK) || + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_RADIO_AEROBICS)) { + ftr_actor->switch_bit = FALSE; + ftr_actor->switch_changed_flag = TRUE; + } + } + + used++; + ftr_actor++; + } +} + +static void aMR_OneMDSwitchOn_TheOtherSwitchOff(FTR_ACTOR* ftr_actor) { + aMR_AllMDSwitchOff(); + ftr_actor->switch_bit = TRUE; + ftr_actor->switch_changed_flag = TRUE; +} + +// Part 2 + +static void aMR_Status2MoveBgCollisionScale(FTR_ACTOR* ftr_actor, s16 status) { + if (status == aFTR_STATE_BIRTH_WAIT) { + ftr_actor->collision_scale = 0.6f; + } else { + ftr_actor->collision_scale = 1.0f; + } +} + +static void aMR_FurnitureCt(FTR_ACTOR* ftr_actor, GAME* game, int ut_x, int ut_z, mActor_name_t item, int ftr_idx, + s16 status, s16 layer, s16 placed_flag) { + int angle = FTR_GET_ROTATION(item); + static xyz_t xyz0 = { 0.0f, 0.0f, 0.0f }; + aFTR_PROFILE* profile; + xyz_t pos; + + bzero(ftr_actor, sizeof(FTR_ACTOR)); + ftr_actor->ctr_type = aFTR_CTR_TYPE_GAME_PLAY; + ftr_actor->base_position = xyz0; + ftr_actor->layer = layer; + ftr_actor->angle_y = aMR_angle_table[angle]; + ftr_actor->angle_y_target = ftr_actor->angle_y; + ftr_actor->s_angle_y = RAD2SHORT_ANGLE2(DEG2RAD(ftr_actor->angle_y)); + ftr_actor->name = mRmTp_FtrItemNo2FtrIdx(item); + + profile = aMR_GetFurnitureProfile(ftr_actor->name); + ftr_actor->state = status; + aMR_SetFurnitureType(ftr_actor, angle); + aMR_SetFirstScale(ftr_actor); + aMR_UnitNumber2Position(&pos, ftr_actor->shape_type, ut_x, ut_z); + pos.y = mCoBG_GetBgY_AngleS_FromWpos(NULL, pos, 0.0f); + ftr_actor->position = pos; + ftr_actor->last_position = pos; + ftr_actor->id = ftr_idx; + aMR_SetInfoFurnitureTable(ftr_actor->shape_type, ut_x + ut_z * UT_X_NUM, ftr_idx, ftr_actor->layer); + ftr_actor->collision_direction = 0; + + if (aMR_CLIP != NULL && aMR_CLIP->my_room_actor_p != NULL) { + aMR_SetSwitchStepData(ftr_actor, placed_flag, (MY_ROOM_ACTOR*)aMR_CLIP->my_room_actor_p); + } + + aMR_MiniDiskCommonCt(ftr_actor, placed_flag); + aMR_RadioCommonCt(ftr_actor, placed_flag); + aMR_Status2MoveBgCollisionScale(ftr_actor, status); + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_HANIWA)) { + ftr_actor->dynamic_work_s[3] = placed_flag; + } + + if (aMR_RegistMoveBg(ftr_actor, profile) && aMR_SystemAnimeCt_UniqueCt(ftr_actor, profile)) { + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, TRUE); + } +} + +static int aMR_DmaFurniture_Common(u16 ftr_id, mActor_name_t item, u8* bank_addr, int bank_idx) { + if (bank_addr != NULL) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_id); + + if (bank_idx != -1) { + l_bank_index_table[ftr_id] = bank_idx; + } + + if (profile->vtable != NULL && profile->vtable->dma_proc != NULL) { + profile->vtable->dma_proc(item, aMR_FtrNo2BankAddress(ftr_id)); + return TRUE; + } else { + return TRUE; + } + } + + return FALSE; +} + +static int aMR_GetFurnitureBank(u16 ftr_id, GAME_PLAY* play, mActor_name_t item) { + if (aMR_SearchFurnitureBankVacancy()) { + int bank_idx = aMR_SearchFreeFurnitureBankIdx(); + + if (bank_idx != -1) { + u8* bank_addr = aMR_BankNo2BankAddress(bank_idx); + + return aMR_DmaFurniture_Common(ftr_id, item, bank_addr, bank_idx); + } + } + + return FALSE; +} + +static int aMR_GetFurnitureBank2(u16 ftr_id, GAME* game, mActor_name_t item) { + GAME_PLAY* play = (GAME_PLAY*)game; + + if (aMR_CheckFurnitureBankExist(ftr_id)) { + return TRUE; + } + + if (aMR_GetFurnitureBank(ftr_id, play, item)) { + return TRUE; + } + + return FALSE; +} + +static void aMR_MakeOneFurniture(ACTOR* actorx, mActor_name_t item, GAME* game, int ut_x, int ut_z, s16 layer) { + if (ITEM_IS_FTR(item) && aMR_CountFurniture() < l_aMR_work.list_size) { + u16 ftr_idx = mRmTp_FtrItemNo2FtrIdx((mActor_name_t)item); + int id = aMR_SearchFreeFurnitureActorNumber(); + + if (id != -1) { + u8* used = l_aMR_work.used_list; + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list + id; + + if (aMR_GetFurnitureBank2(ftr_idx, game, item)) { + used[id] = TRUE; + aMR_FurnitureCt(ftr_actor, game, ut_x, ut_z, item, id, aFTR_STATE_STOP, layer, FALSE); + aMR_PlussWeight(actorx, ftr_actor); + } + } + } +} + +static void aMR_MakeFurnitureActor(ACTOR* actorx, GAME_PLAY* play, s16 layer) { + GAME* game = (GAME*)play; + mActor_name_t* fg_p = aMR_GetLayerTopFg(layer); + int ut_x; + int ut_z; + + if (fg_p != NULL) { + for (ut_z = 0; ut_z < UT_Z_NUM; ut_z++) { + for (ut_x = 0; ut_x < UT_X_NUM; ut_x++) { + aMR_MakeOneFurniture(actorx, *fg_p, game, ut_x, ut_z, layer); + fg_p++; + } + } + } +} + +static void aMR_InitFurnitureActorExistTable(void) { + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + l_aMR_work.used_list[i] = FALSE; + } +} + +static void aMR_InitFurnitureBankTable(void) { + int i; + + for (i = 0; i < FTR_NUM; i++) { + l_bank_index_table[i] = 255; + } +} + +extern cKF_Skeleton_R_c cKF_bs_r_furniture_stop; +extern cKF_Animation_R_c cKF_ba_r_furniture_stop; + +static void aMR_InitDummyKeyAnime(GAME_PLAY* play, ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + cKF_SkeletonInfo_R_ct(&my_room->keyframe, &cKF_bs_r_furniture_stop, &cKF_ba_r_furniture_stop, my_room->joint, + my_room->morph); +} + +static void aMR_GetBankSitu(int* unalloc_bank_num, int* alloc_bank_num, int* req_bank_num) { + *unalloc_bank_num = 0; + *alloc_bank_num = 0; + + if (*req_bank_num > aMR_FTR_BANK_NUM) { + *req_bank_num = aMR_FTR_BANK_NUM; + } + + *unalloc_bank_num = *req_bank_num <= aMR_FTR_BANK_NUM ? *req_bank_num : aMR_FTR_BANK_NUM; + if (*req_bank_num > *unalloc_bank_num) { + *alloc_bank_num = *req_bank_num - *unalloc_bank_num; + } +} + +static void aMR_SecureFurnitureBank(MY_ROOM_ACTOR* my_room, GAME* game) { + u8* bank_p; + size_t size; + int i; + + aMR_GetBankSitu(&my_room->bank_count0, &my_room->bank_count1, &l_aMR_work.list_size); + size = my_room->bank_count0 * aMR_FTR_BANK_SIZE; + + for (i = 0; i < aMR_FTR_BANK_NUM; i++) { + l_bank_address_table[i] = NULL; + } + + bank_p = (u8*)zelda_malloc_align(size, 32); + my_room->bank0_p = bank_p; + for (i = 0; i < my_room->bank_count0; i++) { + l_bank_address_table[i] = bank_p + i * aMR_FTR_BANK_SIZE; + } + + if (my_room->bank_count1 > 0) { + for (i = 0; i < my_room->bank_count1; i++) { + u8* bank = (u8*)zelda_malloc(aMR_FTR_BANK_SIZE); + int idx = my_room->bank_count0 + i; + + if (bank != NULL) { + l_bank_address_table[idx] = bank; + } + } + } +} + +static int aMR_GetSceneFurnitureMax(void) { + static int scene_table[] = { + SCENE_NPC_HOUSE, + SCENE_FIELD_TOOL_INSIDE, + SCENE_SHOP0, + SCENE_CONVENI, + SCENE_SUPER, + SCENE_DEPART, + SCENE_DEPART_2, + SCENE_BROKER_SHOP, + SCENE_MY_ROOM_S, + SCENE_MY_ROOM_M, + SCENE_MY_ROOM_L, + SCENE_KAMAKURA, + SCENE_MUSEUM_ROOM_PAINTING, + SCENE_MUSEUM_ROOM_FOSSIL, + SCENE_MY_ROOM_LL1, + SCENE_MY_ROOM_LL2, + SCENE_MY_ROOM_BASEMENT_S, + SCENE_MY_ROOM_BASEMENT_M, + SCENE_MY_ROOM_BASEMENT_L, + SCENE_MY_ROOM_BASEMENT_LL1, + SCENE_COTTAGE_MY, + SCENE_COTTAGE_NPC, + -1, + }; + + static int bank_count_table[] = { + 30, 30, 10, 10, 10, 10, 10, 10, 32, 48, 64, 10, 20, 25, 64, 48, 64, 64, 64, 64, 64, 30, 5, + }; + + int scene = Save_Get(scene_no); + int i; + + for (i = 0; scene_table[i] != -1; i++) { + if (scene == scene_table[i]) { + return bank_count_table[i]; + } + } + + return 3; +} + +static void aMR_SecureFurnitureRam(ACTOR* actorx) { + l_aMR_work.ftr_actor_list = (FTR_ACTOR*)zelda_malloc(l_aMR_work.list_size * sizeof(FTR_ACTOR)); + l_aMR_work.used_list = (u8*)zelda_malloc(l_aMR_work.list_size * sizeof(u8)); + + if (l_aMR_work.ftr_actor_list == NULL || l_aMR_work.used_list == NULL) { + l_aMR_work.list_size = 0; + } +} + +static void aMR_InitFurnitureTable(FTR_ACTOR* ftr_actor, int count) { + if (ftr_actor != NULL) { + int i; + + for (i = 0; i < count; i++) { + bzero(&ftr_actor[i], sizeof(FTR_ACTOR)); + } + } +} + +static int aMR_JudgeBreedNewFurniture(GAME* game, u16 ftr_no, int* ut_x, int* ut_z, u16* rotation, int* square_offset, + int* layer); +static mActor_name_t aMR_SearchPickupFurniture(GAME* game); +static void aMR_Furniture2ItemBag(GAME* game); +static int aMR_JudgePlayerAction(xyz_t* wpos0, xyz_t* wpos1, int ftr_actor_idx); +static void aMR_PlayerMoveFurniture(int ftr_actor_idx, xyz_t* wpos); +static int aMR_ftrID2Wpos(xyz_t* wpos, int ftr_id); +static int aMR_UnitNum2FtrItemNoFtrID(mActor_name_t* ftr_item_no, int* ftr_id, int ut_x, int ut_z, int layer); +static void aMR_FtrID2ExtinguishFurniture(int ftr_id); +static void aMR_RedmaFtrBank(void); +static int aMR_ReserveFurniture(GAME* game, u16 ftr_no, int judge_res, int ut_x, int ut_z, u16 rotation, + int square_offset, int layer); +static int aMR_CountFriendFurniture(FTR_ACTOR* ftr_actor, u8 switch_on); +static int aMR_JudgePlace2ndLayer(int ut_x, int ut_z); +static void aMR_OpenCloseCommonMove(FTR_ACTOR* ftr_actor, ACTOR* actor, GAME* game, f32 start_frame, f32 end_frame); +static int aMR_GetBedAction(ACTOR* actorx, int bed_move_dir); +static void aMR_MiniDiskCommonMove(FTR_ACTOR* ftr_actor, ACTOR* my_room_actorx, GAME* game, f32 start_frame, + f32 end_frame); +static void aMR_FamicomEmuCommonMove(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, int rom_no, + int agb_rom_no); +static int aMR_SetLeaf(const xyz_t* pos, f32 scale); +static int aMR_Ftr2Leaf(void); +static void aMR_LeafStartPos(xyz_t* pos); +static int aMR_PickupFtrLayer(void); +static void aMR_LeafPickuped(void); +static u8* aMR_FtrNo2BankAddress(u16 ftr_no); +static void aMR_CallSitDownOngenPosSE(const xyz_t* pos); +static void aMR_SoundMelody(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, int idx); +static int aMR_CheckDannaKill(xyz_t* pos); + +static void aMR_SetClip(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->clip.my_room_actor_p = actorx; + my_room->clip.judge_breed_new_ftr_proc = &aMR_JudgeBreedNewFurniture; + my_room->clip.search_pickup_ftr_proc = &aMR_SearchPickupFurniture; + my_room->clip.ftr2itemBag_proc = &aMR_Furniture2ItemBag; + my_room->clip.judge_player_action_proc = &aMR_JudgePlayerAction; + my_room->clip.player_move_ftr_proc = &aMR_PlayerMoveFurniture; + my_room->clip.ftrId2wpos_proc = &aMR_ftrID2Wpos; + my_room->clip.unitNum2ftrItemNoftrId_proc = &aMR_UnitNum2FtrItemNoFtrID; + my_room->clip.ftrId2extinguishFtr_proc = &aMR_FtrID2ExtinguishFurniture; + my_room->clip.redma_ftr_bank_proc = &aMR_RedmaFtrBank; + my_room->clip.reserve_ftr_proc = &aMR_ReserveFurniture; + my_room->clip.count_friend_ftr_proc = &aMR_CountFriendFurniture; + my_room->clip.judge_place_2nd_layer_proc = &aMR_JudgePlace2ndLayer; + my_room->clip.open_close_common_move_proc = &aMR_OpenCloseCommonMove; + my_room->clip.get_bed_action_proc = &aMR_GetBedAction; + my_room->clip.mini_disk_common_move_proc = &aMR_MiniDiskCommonMove; + my_room->clip.famicom_emu_common_move_proc = &aMR_FamicomEmuCommonMove; + my_room->clip.set_leaf_proc = &aMR_SetLeaf; + my_room->clip.ftr2leaf_proc = &aMR_Ftr2Leaf; + my_room->clip.leaf_start_pos_proc = &aMR_LeafStartPos; + my_room->clip.pickup_ftr_layer_proc = &aMR_PickupFtrLayer; + my_room->clip.leaf_pickuped_proc = &aMR_LeafPickuped; + my_room->clip.ftrNo2bankAddress_proc = &aMR_FtrNo2BankAddress; + my_room->clip.call_sit_down_ongen_pos_se_proc = &aMR_CallSitDownOngenPosSE; + my_room->clip.clock_info_p = &my_room->clock_info; + my_room->clip.sound_melody_proc = &aMR_SoundMelody; + my_room->clip.check_danna_kill_proc = &aMR_CheckDannaKill; + + aMR_CLIP = &my_room->clip; +} + +static void aMR_MakeItemDataInFurniture(void) { + mActor_name_t* layer_top_table[mCoBG_LAYER_NUM]; + int idx; + int j; + int ut_x; + int ut_z; + int i; + int k; + + for (k = 0; k < mCoBG_LAYER_NUM; k++) { + layer_top_table[k] = aMR_GetLayerTopFg(k); + } + + for (i = mCoBG_LAYER0; i < mCoBG_LAYER2; i++) { + if (layer_top_table[i] != NULL) { + idx = 0; + + for (j = i + 1; j < mCoBG_LAYER_NUM; j++) { + mActor_name_t* fg_top_p = layer_top_table[j]; + + if (fg_top_p != NULL) { + for (ut_z = 0; ut_z < UT_Z_NUM; ut_z++) { + for (ut_x = 0; ut_x < UT_X_NUM; ut_x++) { + if (*fg_top_p != EMPTY_NO && *fg_top_p != RSV_NO && *fg_top_p != RSV_WALL_NO) { + mActor_name_t item; + int ftr_id; + + if (aMR_UnitNum2FtrItemNoFtrID(&item, &ftr_id, ut_x, ut_z, i)) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list + ftr_id; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (aFTR_IS_STORAGE(profile)) { + ftr_actor->items[idx] = *fg_top_p; + *fg_top_p = EMPTY_NO; + } + } + } + + fg_top_p++; + } + } + } + + idx++; + } + } + } +} + +static void aMR_ClearSwitchSaveData(MY_ROOM_ACTOR* my_room) { + u64* switch_bit_table[2]; + int i; + + for (i = mCoBG_LAYER0; i < mCoBG_LAYER2; i++) { + switch_bit_table[i] = aMR_GetBitSwitchTable(i, my_room); + + if (switch_bit_table[i] != NULL) { + *switch_bit_table[i] = 0; + } + } +} + +static TempoBeat_c* aMR_NowSceneWaltzTempo(MY_ROOM_ACTOR* my_room) { + mActor_name_t field_id = mFI_GetFieldId(); + + if (my_room->scene == SCENE_COTTAGE_MY) { + return &Save_Get(island).cottage.room.tempo_beat; + } else if (mFI_GET_TYPE(field_id) == mFI_FIELD_PLAYER0_ROOM) { + int idx = (mFI_GetFieldId() - mFI_FIELD_PLAYER0_ROOM) & 3; + int floor_no = mFI_GetPlayerHouseFloorNo(my_room->scene); + + if (floor_no != -1) { + return &Save_Get(homes[idx]).floors[floor_no].tempo_beat; + } + } + + return NULL; +} + +static void aMR_GetSavedWaltzTempo(MY_ROOM_ACTOR* my_room) { + sAdo_SetRhythmInfo(aMR_NowSceneWaltzTempo(my_room)); +} + +static void aMR_SaveWaltzTempo(MY_ROOM_ACTOR* my_room) { + TempoBeat_c* rhythm = aMR_NowSceneWaltzTempo(my_room); + + if (rhythm != NULL && Common_Get(rhythym_updated) == FALSE) { + sAdo_GetRhythmInfo(rhythm); + Common_Set(rhythym_updated, TRUE); + } +} + +extern void aMR_SaveWaltzTempo2(void) { + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + aMR_SaveWaltzTempo(my_room); + aMR_SaveHaniwaStepData(my_room); + } + } +} + +static int aMR_CheckRoomOwner(u32 player_no, MY_ROOM_ACTOR* my_room) { + if (Common_Get(field_type) == mFI_FIELDTYPE2_PLAYER_ROOM || my_room->scene == SCENE_COTTAGE_MY) { + return TRUE; + } + + return FALSE; +} + +static void aMR_MakeRoomInfo(MY_ROOM_ACTOR* my_room) { + u32 player_no = Common_Get(player_no); + + my_room->room_info.shop_flag = FALSE; + my_room->room_info.owner_flag = FALSE; + + if (mFI_CheckShop() == TRUE || mFI_GetFieldId() == mFI_FIELD_ROOM_BROKER_SHOP) { + my_room->room_info.shop_flag = TRUE; + } + + if (aMR_CheckRoomOwner(player_no, my_room)) { + my_room->room_info.owner_flag = TRUE; + } +} + +static void aMR_OneMDFurnitureSwitchOn(void) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL && + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK) && + !(ftr_actor->items[0] >= ITM_MINIDISK_START && ftr_actor->items[0] < ITM_MINIDISK_END)) { + ftr_actor->switch_bit = FALSE; + ftr_actor->switch_changed_flag = FALSE; + ftr_actor->haniwa_state = 0; + } + } + + ftr_actor++; + used++; + } +} + +static void aMR_InitFurnitureWork(void) { + int i; + + for (i = mCoBG_LAYER0; i < mCoBG_LAYER2; i++) { + u8* place_p = aMR_place_table[i & 1]; + int j; + + for (j = 0; j < UT_TOTAL_NUM; j++) { + if (*place_p != 201 && *place_p != 200) { + *place_p = 200; + } + + place_p++; + } + } +} + +static void aMR_DeleteMusicWhichMusicBoxDontHave(void) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + + if (mFI_GET_TYPE(mFI_GetFieldId()) == mFI_FIELD_PLAYER0_ROOM) { + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used == TRUE) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL && + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK) && + (ftr_actor->items[0] >= ITM_MINIDISK_START && ftr_actor->items[0] < ITM_MINIDISK_END)) { + int idx = (mFI_GetFieldId() - mFI_FIELD_PLAYER0_ROOM) & 3; + int music_idx = (mActor_name_t)(ftr_actor->items[0] - ITM_MINIDISK_START); + u32* music_box = Save_Get(scene_no) == SCENE_COTTAGE_MY ? Save_Get(island).cottage.music_box + : Save_Get(homes[idx]).music_box; + + if (((music_box[(music_idx / 32) & 1] >> (music_idx & 31)) & 1) == 0) { + ftr_actor->items[0] = EMPTY_NO; + + if (ftr_actor->switch_bit == TRUE) { + ftr_actor->switch_bit = FALSE; + ftr_actor->haniwa_state = 0; + } + } + } + } + + ftr_actor++; + used++; + } + } +} + +static void aMR_SetMDIslandNPC(void) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + int md_set = FALSE; + + if (Save_Get(scene_no) == SCENE_COTTAGE_NPC) { + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL && + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK)) { + if (md_set == FALSE) { + ftr_actor->items[0] = ITM_MINIDISK_START + mNpc_GetIslandMDIdx(); + ftr_actor->switch_bit = TRUE; + ftr_actor->haniwa_state = 1; + md_set = TRUE; + } else { + ftr_actor->switch_bit = FALSE; + ftr_actor->haniwa_state = 0; + } + } + } + + ftr_actor++; + used++; + } + } +} + +static void aMR_GokiInfoCt(ACTOR* actorx, GAME* game); + +static void My_Room_Actor_ct(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + + bzero(&l_aMR_work, sizeof(l_aMR_work)); + my_room->scene = Save_Get(scene_no); + aMR_SetClip(actorx); + aMR_InitFurnitureWork(); + aMR_SetMelodyData(my_room->melody); + my_room->goki_ct_proc = &aMR_GokiInfoCt; + aMR_MakeRoomInfo(my_room); + aMR_GetSavedWaltzTempo(my_room); + l_aMR_work.list_size = aMR_GetSceneFurnitureMax(); + aMR_SecureFurnitureRam(actorx); + aMR_InitFurnitureTable(l_aMR_work.ftr_actor_list, l_aMR_work.list_size); + aMR_InitFurnitureActorExistTable(); + aMR_SecureFurnitureBank(my_room, game); + aMR_InitHaniwaOnTable(actorx); + my_room->state = 0; + aMR_InitFurnitureBankTable(); + aMR_MakeFurnitureActor(actorx, play, mCoBG_LAYER0); + aMR_MakeFurnitureActor(actorx, play, mCoBG_LAYER1); + my_room->parent_ftrID = -1; + Common_Set(make_npc2_actor, TRUE); + aMR_MakeItemDataInFurniture(); + aMR_DeleteMusicWhichMusicBoxDontHave(); + aMR_InitDummyKeyAnime(play, actorx); + my_room->allow_rotation_flag = TRUE; + my_room->sit_timer = 0; + my_room->bed_timer = 0; + my_room->msg_type = 0; + my_room->requested_msg_type = my_room->msg_type; + my_room->bgm_info.reserve_flag = FALSE; + my_room->bgm_info.md_no = -1; + my_room->bgm_info.last_md_no = -1; + aMR_ClearSwitchSaveData(my_room); + aMR_OneMDFurnitureSwitchOn(); + aMR_SetMDIslandNPC(); + my_room->emu_info.request_flag = FALSE; + my_room->emu_info.explaination_given_flag = FALSE; + mCkRh_InitCanLookGokiCount(); +} + +// Part 3 + +static void aMR_FreeMallocBank(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int i; + + if (my_room->bank_count1 != 0) { + for (i = 0; i < my_room->bank_count1; i++) { + zelda_free(l_bank_address_table[my_room->bank_count0 + i]); + } + } +} + +static void aMR_FreeHeapArea(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (l_aMR_work.ftr_actor_list != NULL) { + zelda_free(l_aMR_work.ftr_actor_list); + } + + if (l_aMR_work.used_list != NULL) { + zelda_free(l_aMR_work.used_list); + } + + aMR_FreeMallocBank(actorx); + + if (my_room->emu_info.famicom_names_p != NULL) { + zelda_free(my_room->emu_info.famicom_names_p); + } + + if (my_room->bank0_p != NULL) { + zelda_free(my_room->bank0_p); + } +} + +static void aMR_KeepItem2Fg(FTR_ACTOR* ftr_actor) { + int idx = 0; + int i; + + for (i = ftr_actor->layer + 1; i < mCoBG_LAYER_NUM; i++) { + if (ftr_actor->items[idx] != EMPTY_NO) { + mActor_name_t* fg_p = aMR_GetLayerTopFg(i); + + if (fg_p != NULL) { + int ut_x; + int ut_z; + + if (aMR_Wpos2PlaceNumber(&ut_x, &ut_z, ftr_actor->position, ftr_actor->shape_type)) { + fg_p[ut_x + ut_z * UT_X_NUM] = ftr_actor->items[idx]; + ftr_actor->items[idx] = EMPTY_NO; + } + } + } + + idx++; + } +} + +static void aMR_AllFurnitureDestruct(ACTOR* actorx, GAME* game) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + + sAdo_RhythmAllStop(); + if (ftr_actor != NULL && used != NULL) { + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + mCoBG_CrossOffMoveBg(ftr_actor->move_bg_idx); + aMR_KeepItem2Fg(ftr_actor); + aMR_MiniDiskCommonDt(ftr_actor, actorx); + aMR_RadioCommonDt(ftr_actor, actorx); + aMR_MinusWeight(actorx, ftr_actor); + + if (profile != NULL && profile->vtable != NULL && profile->vtable->dt_proc != NULL) { + profile->vtable->dt_proc(ftr_actor, aMR_FtrNo2BankAddress(ftr_actor->name)); + } + + *used = FALSE; + } + + used++; + ftr_actor++; + } + } +} + +static void aMR_LeafPickuped(void) { + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->pickup_info.pickup_flag = FALSE; + } + } +} + +static int aMR_PickupFtrLayer(void) { + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + return my_room->pickup_info.layer; + } + } + + return mCoBG_LAYER0; +} + +static void aMR_LeafStartPos(xyz_t* pos) { + static xyz_t leaf_start0 = { 0.0f, 0.0f, 0.0f }; + + *pos = leaf_start0; + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + *pos = my_room->pickup_info.leaf_pos; + } + } +} + +static int aMR_Ftr2Leaf(void) { + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + return my_room->pickup_info.picking_up_flag; + } + } + + return FALSE; +} + +static int aMR_SetLeaf(const xyz_t* pos, f32 scale) { + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (my_room->leaf_info.exist_flag == FALSE) { + my_room->leaf_info.pos = *pos; + my_room->leaf_info.scale = scale; + my_room->leaf_info.exist_flag = TRUE; + return TRUE; + } + + return FALSE; + } + } + + return FALSE; +} + +static void My_Room_Actor_dt(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + aMR_SaveSwitchData(my_room); + aMR_AllFurnitureDestruct(actorx, game); + aMR_FreeHeapArea(actorx); + aMR_GokiInfoDt(); + aMR_CLIP = NULL; + mCkRh_SetGoingOutCottageTime(my_room->scene); + + /* TODO: enums for this field */ + if ((Common_Get(my_room_message_control_flags) >> 3) & 1) { + Common_Set(my_room_message_control_flags, 0); + Common_Get(my_room_message_control_flags) &= ~2; + Common_Get(my_room_message_control_flags) &= ~1; + Common_Get(my_room_message_control_flags) |= 8; + sAdo_SubGameStart(); + } else if ((Common_Get(my_room_message_control_flags) & 0x10)) { + Common_Set(my_room_message_control_flags, 0); + Common_Get(my_room_message_control_flags) &= ~2; + Common_Get(my_room_message_control_flags) &= ~1; + Common_Get(my_room_message_control_flags) |= 0x10; + sAdo_SubGameStart(); + } else { + Common_Set(my_room_message_control_flags, 0); + Common_Get(my_room_message_control_flags) &= ~2; + Common_Get(my_room_message_control_flags) &= ~1; + } +} + +static void aMR_RedmaFtrBank(void) { + int i; + + for (i = 0; i < FTR_NUM; i++) { + if (l_bank_index_table[i] != 255) { + u8* bank_addr = aMR_BankNo2BankAddress(l_bank_index_table[i]); + mActor_name_t item = mRmTp_FtrIdx2FtrItemNo(i, mRmTp_DIRECT_SOUTH); + + aMR_DmaFurniture_Common(i, item, bank_addr, -1); + } + } +} + +static void aMR_RequestStartEmu(MY_ROOM_ACTOR* my_room, FTR_ACTOR* ftr_actor, int game_idx, int agb_game_idx) { + if (my_room->emu_info.request_flag == FALSE && mMsg_Check_MainHide(mMsg_Get_base_window_p())) { + my_room->emu_info.request_flag = TRUE; + my_room->emu_info.rom_no = game_idx; + my_room->emu_info.agb_rom_no = agb_game_idx; + my_room->emu_info.explaination_given_flag = FALSE; + my_room->emu_info._10 = 0; + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_EMULATOR; + my_room->emu_ftrID = ftr_actor->id; + } +} + +static void aMR_RequestStartEmu_MemoryC(MY_ROOM_ACTOR* my_room, FTR_ACTOR* ftr_actor, int game_idx) { + if (my_room->emu_info.request_flag == FALSE && mMsg_Check_MainHide(mMsg_Get_base_window_p())) { + int card_count = aMR_GetCardFamicomCount(); + + my_room->emu_info.card_famicom_count = card_count; + my_room->emu_info.memory_game_select = 0; + + if (card_count > 0) { + size_t namebuf_size = card_count * mIN_ITEM_NAME_LEN; + + if (my_room->emu_info.famicom_names_p != NULL) { + zelda_free(my_room->emu_info.famicom_names_p); + } + + my_room->emu_info.famicom_names_p = (char*)zelda_malloc(namebuf_size); + + if (my_room->emu_info.famicom_names_p != NULL) { + int n_games = 0; + + if (famicom_get_disksystem_titles(&n_games, my_room->emu_info.famicom_names_p, namebuf_size) == FALSE) { + my_room->requested_msg_type = aMR_MSG_STATE_NO_PACK_NO_DATA; + my_room->room_msg_flag = TRUE; + return; + } + } + + if (card_count == 1) { + my_room->emu_info.request_flag = TRUE; + my_room->emu_info.rom_no = game_idx; + my_room->emu_info.explaination_given_flag = FALSE; + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_EMULATOR_MEMORY1; + my_room->emu_ftrID = ftr_actor->id; + my_room->emu_info._10 = 0; + } else if (card_count == 2) { + my_room->emu_info.request_flag = TRUE; + my_room->emu_info.rom_no = game_idx; + my_room->emu_info.explaination_given_flag = FALSE; + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_EMULATOR_MEMORY2; + my_room->emu_ftrID = ftr_actor->id; + my_room->emu_info._10 = 0; + } else { + my_room->emu_info.request_flag = TRUE; + my_room->emu_info.rom_no = game_idx; + my_room->emu_info.explaination_given_flag = FALSE; + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_EMULATOR_MEMORY_OVER3; + my_room->emu_ftrID = ftr_actor->id; + my_room->emu_info._10 = 0; + } + } else { + my_room->requested_msg_type = aMR_MSG_STATE_NO_PACK_NO_DATA; + my_room->room_msg_flag = TRUE; + } + } +} + +static void aMR_FamicomEmuCommonMove(FTR_ACTOR* ftr_actor, ACTOR* actorx, GAME* game, int rom_no, int agb_rom_no) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (ftr_actor->switch_changed_flag) { + if (rom_no == 0) { + aMR_RequestStartEmu_MemoryC(my_room, ftr_actor, 0); + } else { + aMR_RequestStartEmu(my_room, ftr_actor, rom_no, agb_rom_no); + } + } +} + +static void aMR_CallSitDownOngenPosSE(const xyz_t* pos) { + mActor_name_t item_no; + int ftrID; + xyz_t sit_pos = *pos; + int ut_x = 0; + int ut_z = 0; + + sit_pos.y = 0.0f; + sit_pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos(sit_pos, 0.0f); + if (mFI_Wpos2UtNum(&ut_x, &ut_z, sit_pos) && + aMR_UnitNum2FtrItemNoFtrID(&item_no, &ftrID, ut_x, ut_z, mCoBG_LAYER0)) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list + ftrID; + + /* Check for massage chair */ + switch (ftr_actor->name) { + case 0x152: + sAdo_OngenPos((u32)ftr_actor, 39, &ftr_actor->position); + break; + } + } +} + +static int aMR_CheckDannaKill(xyz_t* pos) { + mActor_name_t* fg_p = mFI_GetUnitFG(*pos); + + /* @BUG - this doesn't check for newer furniture in the 0x3XXX range */ + if (fg_p != NULL && ((*fg_p >= FTR0_START && *fg_p <= ITEM1_NO_START) || *fg_p == RSV_FE1F)) { + int ut_x; + int ut_z; + + if (mFI_Wpos2UtNum(&ut_x, &ut_z, *pos) && aMR_CLIP != NULL) { + mActor_name_t item_no; + int ftrID; + + if (aMR_UnitNum2FtrItemNoFtrID(&item_no, &ftrID, ut_x & 0xF, ut_z & 0xF, mCoBG_LAYER0)) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list + ftrID; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL && + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_NO_COLLISION) == FALSE && + aMR_CheckFtrAndGoki2(ftr_actor->edge_collision, pos)) { + return TRUE; + } + } + } + } + + return FALSE; +} + +extern int aMR_GetFurnitureUnit(mActor_name_t item) { + if (ITEM_IS_FTR(item)) { + int ftr_idx = mRmTp_FtrItemNo2FtrIdx(item); + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_idx); + + if (profile != NULL) { + switch (profile->shape) { + case aFTR_SHAPE_TYPEA: + return 0; + case aFTR_SHAPE_TYPEC: + return 2; + default: + return 1; + } + } + } + + return -1; +} + +extern int aMR_CorrespondFurniture(mActor_name_t ftr0, mActor_name_t ftr1) { + if (ITEM_IS_FTR(ftr0) && ITEM_IS_FTR(ftr1)) { + int ftr_idx0 = mRmTp_FtrItemNo2FtrIdx(ftr0); + int ftr_idx1 = mRmTp_FtrItemNo2FtrIdx(ftr1); + + if (ftr_idx0 == ftr_idx1) { + return TRUE; + } + } + + return FALSE; +} + +extern mActor_name_t aMR_FurnitureFg_to_FurnitureFgWithDirect(mActor_name_t item, int direct) { + if (ITEM_IS_FTR(item)) { + return mRmTp_FtrIdx2FtrItemNo(mRmTp_FtrItemNo2FtrIdx(item), direct); + } + + return item; +} + +extern void aMR_RadioCommonMove(FTR_ACTOR* ftr_actor, ACTOR* actorx) { + if (ftr_actor->haniwa_state == 1) { + aMR_ReserveBgm(actorx, 27, ftr_actor, 0); + ftr_actor->haniwa_state = 0; + } else if (ftr_actor->switch_changed_flag) { + if (ftr_actor->switch_bit == FALSE) { + aMR_OneMDSwitchOn_TheOtherSwitchOff(ftr_actor); + aMR_ReserveDefaultBgm(actorx, ftr_actor); + aMR_ChangeMDBgm(actorx, ftr_actor); + ftr_actor->switch_bit = FALSE; + } else { + aMR_OneMDSwitchOn_TheOtherSwitchOff(ftr_actor); + aMR_ReserveBgm(actorx, 27, ftr_actor, 0); + aMR_ChangeMDBgm(actorx, ftr_actor); + ftr_actor->switch_bit = TRUE; + } + } +} + +extern int aMR_RadioBgmNow(void) { + if (mBGMPsComp_execute_bgm_num_get() == 27) { + return TRUE; + } + + return FALSE; +} + +extern aMR_contact_info_c* aMR_GetContactInfoLayer1(void) { + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + return &my_room->contact0; + } + } + + return NULL; +} + +extern FTR_ACTOR* aMR_GetParentFactor(FTR_ACTOR* ftr_actor, ACTOR* actorx) { + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (my_room->parent_ftrID != -1) { + FTR_ACTOR* parent_ftr_actor = l_aMR_work.ftr_actor_list + my_room->parent_ftrID; + + if (my_room->fit_ftr_table[0].ftr_ID == ftr_actor->id || + my_room->fit_ftr_table[1].ftr_ID == ftr_actor->id || + my_room->fit_ftr_table[2].ftr_ID == ftr_actor->id || + my_room->fit_ftr_table[3].ftr_ID == ftr_actor->id) { + return parent_ftr_actor; + } + } + } + + return NULL; +} + +extern s16 aMR_GetParentAngleOffset(FTR_ACTOR* ftr_actor, ACTOR* actorx) { + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + if (my_room->parent_ftrID != -1) { + FTR_ACTOR* parent_ftr_actor = l_aMR_work.ftr_actor_list + my_room->parent_ftrID; + + if (my_room->fit_ftr_table[0].ftr_ID == ftr_actor->id || + my_room->fit_ftr_table[1].ftr_ID == ftr_actor->id || + my_room->fit_ftr_table[2].ftr_ID == ftr_actor->id || + my_room->fit_ftr_table[3].ftr_ID == ftr_actor->id) { + return parent_ftr_actor->s_angle_y - my_room->parent_angleY; + } + } + } + + return 0; +} + +extern u8 aMR_GetAlphaEdge(u16 ftr_name) { + switch (ftr_name) { + case 0x41: // classic cabinet + case 0x120: // violin + case 0x121: // bass (instrument) + case 0x122: // cello + return 11; + case 0x393: // kitschy clock + case 0x394: // antique clock + return 250; + case 0x3FC: // red balloon + case 0x3FD: // yellow balloon + case 0x3FE: // blue balloon + case 0x3FF: // green balloon + case 0x400: // purple balloon + case 0x401: // bunny p. balloon + case 0x402: // bunny b. balloon + case 0x403: // bunny o. balloon + return 96; + case 0x415: + return 127; // tanabata palm + case 0x4CC: + return 20; // harvest bureau + default: + return 127; + } +} + +extern int aMR_DrawDolphinMode(u16 ftr_name) { + switch (ftr_name) { + case 0x406: // stone coin + case 0x49D: // hamster cage + case 0x4CF: // neutral corner + case 0x4D0: // red corner + case 0x4D1: // blue corner + return TRUE; + default: + return FALSE; + } +} + +extern void aMR_ThrowItem_FurnitureLock(void) { + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->throw_item_lock_flag = TRUE; + } + } +} + +extern void aMR_ThrowItem_FurnitureUnlock(void) { + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->throw_item_lock_flag = FALSE; + } + } +} + +extern void aMR_SameFurnitureSwitchOFF(u16 ftr_name) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used && ftr_actor->name == ftr_name) { + ftr_actor->switch_bit = FALSE; + ftr_actor->switch_changed_flag = TRUE; + } + + ftr_actor++; + used++; + } +} diff --git a/src/ac_my_room_data.c_inc b/src/ac_my_room_data.c_inc new file mode 100644 index 00000000..f1c70b22 --- /dev/null +++ b/src/ac_my_room_data.c_inc @@ -0,0 +1,1402 @@ +static xyz_t norm_table[] = { + { 0.0f, 0.0f, -1.0f }, + { -1.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 0.0f }, +}; + +typedef struct { + int left; + int right; +} aMR_rotate_data_c; + +static aMR_rotate_data_c rotateDt[] = { + { 1, 3 }, + { 2, 0 }, + { 3, 1 }, + { 0, 2 }, +}; + +typedef struct { + u8 type; + xyz_t offset; +} aMR_type_target_c; + +static aMR_type_target_c type_target_table[] = { + { 2, { 0.0f, 0.0f, -40.0f } }, { 2, { 0.0f, 0.0f, -40.0f } }, { 2, { 0.0f, 0.0f, -40.0f } }, + { 0, { 0.0f, 0.0f, 0.0f } }, { 0, { 0.0f, 0.0f, 0.0f } }, { 0, { 0.0f, 0.0f, 0.0f } }, + { 0, { 0.0f, 0.0f, 0.0f } }, { 2, { 0.0f, 0.0f, -40.0f } }, { 1, { 0.0f, 0.0f, 0.0f } }, + { 3, { -40.0f, 0.0f, 0.0f } }, { 3, { -40.0f, 0.0f, 0.0f } }, { 3, { -40.0f, 0.0f, 0.0f } }, + { 3, { -40.0f, 0.0f, 0.0f } }, { 1, { 0.0f, 0.0f, 0.0f } }, { 1, { 0.0f, 0.0f, 0.0f } }, + { 1, { 0.0f, 0.0f, 0.0f } }, { 2, { 0.0f, 0.0f, 0.0f } }, { 2, { 0.0f, 0.0f, 0.0f } }, + { 2, { 0.0f, 0.0f, 0.0f } }, { 0, { 0.0f, 0.0f, 40.0f } }, { 0, { 0.0f, 0.0f, 40.0f } }, + { 0, { 0.0f, 0.0f, 40.0f } }, { 0, { 0.0f, 0.0f, 40.0f } }, { 2, { 0.0f, 0.0f, 0.0f } }, + { 1, { 40.0f, 0.0f, 0.0f } }, { 3, { 0.0f, 0.0f, 0.0f } }, { 3, { 0.0f, 0.0f, 0.0f } }, + { 3, { 0.0f, 0.0f, 0.0f } }, { 3, { 0.0f, 0.0f, 0.0f } }, { 1, { 40.0f, 0.0f, 0.0f } }, + { 1, { 40.0f, 0.0f, 0.0f } }, { 1, { 40.0f, 0.0f, 0.0f } }, +}; + +static s16 rotate_forbid_table[][2] = { + { -1, 0 }, { -1, -1 }, { 0, 0 }, { 1, 0 }, { -1, 1 }, { 0, 0 }, { -1, 0 }, { 1, 0 }, + { 0, 1 }, { -1, 0 }, { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 }, { 0, 1 }, { -1, 0 }, + { 0, -1 }, { 0, 1 }, { 0, 0 }, { -1, 1 }, { 0, -1 }, { 0, 0 }, { 1, 1 }, { 0, 1 }, +}; + +static s16 rotate_forbid_friction_table[][2] = { + { 0x0000, 0x0000 }, { 0x0001, 0x0001 }, { 0x0000, 0x0000 }, { 0x0000, 0x0000 }, { 0x0001, 0xffff }, + { 0x0000, 0x0000 }, { 0x0001, 0x0000 }, { 0x0000, 0x0000 }, { 0x0000, 0xffff }, { 0x0001, 0x0000 }, + { 0x0000, 0x0000 }, { 0x0000, 0x0001 }, { 0x0000, 0x0000 }, { 0xffff, 0xffff }, { 0x0000, 0x0000 }, + { 0x0000, 0x0000 }, { 0xffff, 0x0001 }, { 0x0000, 0x0000 }, { 0xffff, 0x0000 }, { 0x0000, 0x0000 }, + { 0x0000, 0x0001 }, { 0xffff, 0x0000 }, { 0x0000, 0x0000 }, { 0x0000, 0xffff }, +}; + +typedef struct { + s_xyz* ofs_p; + int count; +} aMR_place_info_c; + +static s_xyz l_next_typea[] = { + { 0, 0, -1 }, + { -1, 0, 0 }, + { 0, 0, 1 }, + { 1, 0, 0 }, +}; + +static aMR_place_info_c l_next_place_typeA = { l_next_typea, ARRAY_COUNT(l_next_typea) }; + +static s_xyz l_next_typec[] = { + { 0, 0, -1 }, { -1, 0, 0 }, { -1, 0, 1 }, { 0, 0, 2 }, { 1, 0, 2 }, { 2, 0, 1 }, { 2, 0, 0 }, { 1, 0, -1 }, +}; + +static aMR_place_info_c l_next_place_typeC = { l_next_typec, ARRAY_COUNT(l_next_typec) }; + +static aMR_place_info_c* next_table[] = { + NULL, NULL, NULL, NULL, &l_next_place_typeA, &l_next_place_typeC, +}; + +static xyz_t l_typeB_90_pattern[2] = { + { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 40.0f }, +}; + +static xyz_t l_typeB_180_pattern[2] = { + { 0.0f, 0.0f, 0.0f }, + { 40.0f, 0.0f, 0.0f }, +}; + +static xyz_t l_typeB_270_pattern[2] = { + { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, -40.0f }, +}; + +static xyz_t l_typeB_0_pattern[2] = { + { 0.0f, 0.0f, 0.0f }, + { -40.0f, 0.0f, 0.0f }, +}; + +static xyz_t* pattern_table[] = { + l_typeB_90_pattern, + l_typeB_180_pattern, + l_typeB_270_pattern, + l_typeB_0_pattern, +}; + +// clang-format off + +/* List of items which are a diary (are a calendar) */ +static u8 aMR_calender_info_table[] = { + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, +}; + +// clang-format on + +typedef struct { + Gfx* mat_gfx; + Gfx* vtx_gfx; +} aMR_icon_display_data_c; + +extern Gfx leaf_DL_mode[]; +extern Gfx leaf_DL_vtx[]; +extern Gfx obj_haniwaT_mat_model[]; +extern Gfx obj_haniwaT_gfx_model[]; +extern Gfx obj_item_clothT_mat_model[]; +extern Gfx obj_item_umbrellaT_mat_model[]; +extern Gfx obj_item_umbrellaT_gfx_model[]; +extern Gfx obj_item_boneT_mat_model[]; +extern Gfx obj_item_boneT_gfx_model[]; +extern Gfx obj_item_diaryT_mat_model[]; +extern Gfx obj_item_diaryT_gfx_model[]; + +static aMR_icon_display_data_c aMR_icon_display_data[] = { + { leaf_DL_mode, leaf_DL_vtx }, + { obj_haniwaT_mat_model, obj_haniwaT_gfx_model }, + { obj_item_clothT_mat_model, obj_item_umbrellaT_gfx_model }, + { obj_item_umbrellaT_mat_model, obj_item_umbrellaT_gfx_model }, + { obj_item_boneT_mat_model, obj_item_boneT_gfx_model }, + { obj_item_diaryT_mat_model, obj_item_diaryT_gfx_model }, +}; diff --git a/src/audio.c b/src/audio.c index ac8e3679..9fe6c6d2 100644 --- a/src/audio.c +++ b/src/audio.c @@ -219,14 +219,13 @@ extern s8 sAdo_GetRhythmDelay(u32 p) { return Na_GetRhythmDelay(p); } -extern f32 sAdo_GetRhythmInfo(u32 p) { +extern void sAdo_GetRhythmInfo(TempoBeat_c* rhythm) { - return Na_GetRhythmInfo(p); + Na_GetRhythmInfo(rhythm); } -extern void sAdo_SetRhythmInfo(f32 p) { - - Na_SetRhythmInfo(p); +extern void sAdo_SetRhythmInfo(TempoBeat_c* rhythm) { + Na_SetRhythmInfo(rhythm); } extern int sAdo_InstCountGet() { diff --git a/src/famicom_emu.c b/src/famicom_emu.c index 63208c87..69a1b030 100644 --- a/src/famicom_emu.c +++ b/src/famicom_emu.c @@ -77,7 +77,7 @@ extern void famicom_emu_main(GAME* famicom) { if (famicom_done == 0) { if (famicom_rom_load_check() < 0) { - Common_Set(famicom_2DBAC, Common_Get(famicom_2DBAC) | 1); + Common_Set(my_room_message_control_flags, Common_Get(my_room_message_control_flags) | 1); famicom_done = 1; famicom_done_countdown = 0; } else { @@ -152,7 +152,7 @@ extern void famicom_emu_init(GAME* game) { my_alloc_init(game, freeXfbBase, freeXfbSize); if (famicom_init(rom_id, &my_malloc_func, player) != 0) { - Common_Set(famicom_2DBAC, Common_Get(famicom_2DBAC) | 1); + Common_Set(my_room_message_control_flags, Common_Get(my_room_message_control_flags) | 1); return_emu_game(game); } } @@ -161,7 +161,7 @@ extern void famicom_emu_cleanup(GAME* game) { JC_JFWDisplay_startFadeIn(JC_JFWDisplay_getManager(), 1); if (famicom_cleanup() != 0) { - Common_Set(famicom_2DBAC, Common_Get(famicom_2DBAC) | 2); + Common_Set(my_room_message_control_flags, Common_Get(my_room_message_control_flags) | 2); } my_alloc_cleanup(); diff --git a/src/ftr/ac_ike_jny_houi01.c b/src/ftr/ac_ike_jny_houi01.c index 634e6f26..41ced0d6 100644 --- a/src/ftr/ac_ike_jny_houi01.c +++ b/src/ftr/ac_ike_jny_houi01.c @@ -57,7 +57,7 @@ static void fIJHOUI_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u cKF_SkeletonInfo_R_c* keyf = &ftr_actor->keyframe; FTR_ACTOR* parent; - parent = aMR_GetParentFactor(); + parent = aMR_GetParentFactor(ftr_actor, my_room_actor); fIJHOUI_Status2SetMode(ftr_actor, ftr_actor); if (parent != NULL) { @@ -88,14 +88,14 @@ static void fIJHOUI_mv(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u ftr_actor->dynamic_work_s[0] = ftr_actor->state; } -static int fIJHOUI_DrawBefore(GAME* game, cKF_SkeletonInfo_R_c* keyf, int jointNum, Gfx** joint, u8* jointFlag, void* arg, - s_xyz* joint1, xyz_t* trans) { +static int fIJHOUI_DrawBefore(GAME* game, cKF_SkeletonInfo_R_c* keyf, int jointNum, Gfx** joint, u8* jointFlag, + void* arg, s_xyz* joint1, xyz_t* trans) { FTR_ACTOR* actor = (FTR_ACTOR*)arg; int offset = 10430.378f * (0.017453292f * actor->dynamic_work_f[1]); if (jointNum == 3) { - MY_ROOM_ACTOR* my_room_actor; + ACTOR* my_room_actor; int exists = FALSE; if ((Common_Get(clip).my_room_clip != NULL && Common_Get(clip).my_room_clip->my_room_actor_p != NULL)) { @@ -114,15 +114,15 @@ static int fIJHOUI_DrawBefore(GAME* game, cKF_SkeletonInfo_R_c* keyf, int jointN return 1; } -static int fIJHOUI_DrawAfter(GAME* game, cKF_SkeletonInfo_R_c* keyf, int jointNum, Gfx** joint, u8* jointFlag, void* arg, - s_xyz* joint1, xyz_t* trans) { +static int fIJHOUI_DrawAfter(GAME* game, cKF_SkeletonInfo_R_c* keyf, int jointNum, Gfx** joint, u8* jointFlag, + void* arg, s_xyz* joint1, xyz_t* trans) { return 1; } static void fIJHOUI_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u8* data) { Mtx* mtx = ftr_actor->skeleton_mtx[game->frame_counter & 1]; - - OPEN_DISP(game->graph); + + OPEN_DISP(game->graph); gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -131,29 +131,10 @@ static void fIJHOUI_dw(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor, GAME* game, u } static aFTR_vtable_c fIJHOUI_func = { - &fIJHOUI_ct, - &fIJHOUI_mv, - &fIJHOUI_dw, - NULL, - NULL, + &fIJHOUI_ct, &fIJHOUI_mv, &fIJHOUI_dw, NULL, NULL, }; aFTR_PROFILE iam_ike_jny_houi01 = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - 40.0f, - 0.01f, - aFTR_SHAPE_TYPEA, - mCoBG_FTR_TYPEA, - 0, - 2, - 0, - 0, - &fIJHOUI_func, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 40.0f, 0.01f, aFTR_SHAPE_TYPEA, mCoBG_FTR_TYPEA, + 0, 2, 0, 0, &fIJHOUI_func, }; diff --git a/src/m_island.c b/src/m_island.c index 28a67534..2f70197d 100644 --- a/src/m_island.c +++ b/src/m_island.c @@ -10,835 +10,781 @@ static Island_c l_keepIsland; static u16 l_keepIslandComb[mISL_FG_BLOCK_X_NUM * mISL_FG_BLOCK_Z_NUM]; -static u8 l_misl_count_max_table[32] = { - 10, - 4, - 1, - 10, - 1, - 5, - 3, - 10, - 5, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 -}; +static u8 l_misl_count_max_table[32] = { 10, 4, 1, 10, 1, 5, 3, 10, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; static u8 l_misl_count_table[32]; extern void mISL_ClearKeepIsland() { - bzero(&l_keepIsland, sizeof(l_keepIsland)); + bzero(&l_keepIsland, sizeof(l_keepIsland)); } extern void mISL_KeepIsland(Island_c* island) { - if (mLd_CheckThisLand(island->landinfo.name, island->landinfo.id) == TRUE) { - bcopy(island, &l_keepIsland, sizeof(l_keepIsland)); - } + if (mLd_CheckThisLand(island->landinfo.name, island->landinfo.id) == TRUE) { + bcopy(island, &l_keepIsland, sizeof(l_keepIsland)); + } } static void mISL_KeepIslandComb(u16* dst, mFM_combination_c* combi, int count) { - while (count != 0 && dst != NULL && combi != NULL) { - count--; - dst[0] = combi[0].combination_type; - dst++; - combi++; - } + while (count != 0 && dst != NULL && combi != NULL) { + count--; + dst[0] = combi[0].combination_type; + dst++; + combi++; + } } static void mISL_RestoreIslandComb_com(mFM_combination_c* combi, u16* src, int count) { - while (count != 0 && src != NULL && combi != NULL) { - count--; - combi[0].combination_type = *src; - combi++; - src++; - } + while (count != 0 && src != NULL && combi != NULL) { + count--; + combi[0].combination_type = *src; + combi++; + src++; + } } static void mISL_RestoreIslandComb() { - int island_x_blocks[mISL_FG_BLOCK_X_NUM]; + int island_x_blocks[mISL_FG_BLOCK_X_NUM]; - mFI_GetIslandBlockNumX(island_x_blocks); + mFI_GetIslandBlockNumX(island_x_blocks); - if (island_x_blocks[0] > 0 && island_x_blocks[1] < (BLOCK_X_NUM - 1)) { - mISL_RestoreIslandComb_com(Save_GetPointer(combi_table[mISL_BLOCK_Z][island_x_blocks[0]]), l_keepIslandComb, mISL_FG_BLOCK_X_NUM); - } + if (island_x_blocks[0] > 0 && island_x_blocks[1] < (BLOCK_X_NUM - 1)) { + mISL_RestoreIslandComb_com(Save_GetPointer(combi_table[mISL_BLOCK_Z][island_x_blocks[0]]), l_keepIslandComb, + mISL_FG_BLOCK_X_NUM); + } } extern void mISL_ChangeBG() { - int island_x_blocks[mISL_FG_BLOCK_X_NUM]; + int island_x_blocks[mISL_FG_BLOCK_X_NUM]; - mFI_GetIslandBlockNumX(island_x_blocks); + mFI_GetIslandBlockNumX(island_x_blocks); - if (island_x_blocks[0] > 0 && island_x_blocks[1] < (BLOCK_X_NUM - 1)) { - mISL_KeepIslandComb(l_keepIslandComb, Save_GetPointer(combi_table[mISL_BLOCK_Z][island_x_blocks[0]]), mISL_FG_BLOCK_X_NUM); - mRF_IslandBgData_To_VillageData(); - mFM_RestoreIslandBG(island_x_blocks, mISL_FG_BLOCK_X_NUM); - } + if (island_x_blocks[0] > 0 && island_x_blocks[1] < (BLOCK_X_NUM - 1)) { + mISL_KeepIslandComb(l_keepIslandComb, Save_GetPointer(combi_table[mISL_BLOCK_Z][island_x_blocks[0]]), + mISL_FG_BLOCK_X_NUM); + mRF_IslandBgData_To_VillageData(); + mFM_RestoreIslandBG(island_x_blocks, mISL_FG_BLOCK_X_NUM); + } } extern void mISL_RestoreIsland() { - Island_c* island = Save_GetPointer(island); - Island_c* keep_island = &l_keepIsland; + Island_c* island = Save_GetPointer(island); + Island_c* keep_island = &l_keepIsland; - if (mLd_CheckThisLand(island->landinfo.name, island->landinfo.id) == FALSE) { - bcopy(keep_island, island, sizeof(l_keepIsland)); - mISL_RestoreIslandComb(); - } - else { - bcopy(island, keep_island, sizeof(l_keepIsland)); - } + if (mLd_CheckThisLand(island->landinfo.name, island->landinfo.id) == FALSE) { + bcopy(keep_island, island, sizeof(l_keepIsland)); + mISL_RestoreIslandComb(); + } else { + bcopy(island, keep_island, sizeof(l_keepIsland)); + } } extern void mISL_init(Island_c* island) { - mLd_ClearLandName(island->name); - bcopy(Save_GetPointer(land_info), &island->landinfo, sizeof(mLd_land_info_c)); - mHm_InitCottage(&island->cottage); - mNpc_DecideIslandNpc(&island->animal); - Save_Get(island).grass_tex_type = Save_Get(bg_tex_idx); + mLd_ClearLandName(island->name); + bcopy(Save_GetPointer(land_info), &island->landinfo, sizeof(mLd_land_info_c)); + mHm_InitCottage(&island->cottage); + mNpc_DecideIslandNpc(&island->animal); + Save_Get(island).grass_tex_type = Save_Get(bg_tex_idx); } static u32* mISL_GetCheckP(PersonalID_c* pid) { - Anmmem_c* memory = Save_Get(island).animal.memories; - u32* check_p = NULL; + Anmmem_c* memory = Save_Get(island).animal.memories; + u32* check_p = NULL; - if (pid != NULL && mPr_NullCheckPersonalID(pid) == FALSE) { - int idx = mNpc_GetAnimalMemoryIdx(pid, memory, ANIMAL_MEMORY_NUM); + if (pid != NULL && mPr_NullCheckPersonalID(pid) == FALSE) { + int idx = mNpc_GetAnimalMemoryIdx(pid, memory, ANIMAL_MEMORY_NUM); - if (idx != -1) { - check_p = &memory[idx].memuni.island.check; + if (idx != -1) { + check_p = &memory[idx].memuni.island.check; + } } - } - return check_p; + return check_p; } extern void mISL_ClearNowPlayerAction() { - Private_c* priv = Common_Get(now_private); + Private_c* priv = Common_Get(now_private); - if (priv != NULL) { - u32* check_p = mISL_GetCheckP(&priv->player_ID); + if (priv != NULL) { + u32* check_p = mISL_GetCheckP(&priv->player_ID); - if (check_p != NULL) { - check_p[0] = 0; + if (check_p != NULL) { + check_p[0] = 0; + } + + bzero(l_misl_count_table, sizeof(l_misl_count_table)); } - - bzero(l_misl_count_table, sizeof(l_misl_count_table)); - } } extern void mISL_SetPlayerAction(PersonalID_c* pid, u32 action) { - if (pid != NULL && mFI_CheckInIsland() == TRUE) { - u32* check_p = mISL_GetCheckP(pid); + if (pid != NULL && mFI_CheckInIsland() == TRUE) { + u32* check_p = mISL_GetCheckP(pid); - if (check_p != NULL) { - int i; + if (check_p != NULL) { + int i; - for (i = 0; i < ARRAY_COUNT(l_misl_count_table); i++) { - if (((action >> i) & 1) != 0) { - l_misl_count_table[i]++; + for (i = 0; i < ARRAY_COUNT(l_misl_count_table); i++) { + if (((action >> i) & 1) != 0) { + l_misl_count_table[i]++; + } + + if (l_misl_count_max_table[i] <= l_misl_count_table[i]) { + check_p[0] |= (1 << i); + l_misl_count_table[i] = l_misl_count_max_table[i]; + } + } } - - if (l_misl_count_max_table[i] <= l_misl_count_table[i]) { - check_p[0] |= (1 << i); - l_misl_count_table[i] = l_misl_count_max_table[i]; - } - } } - } } extern void mISL_SetNowPlayerAction(u32 action) { - Private_c* priv = Common_Get(now_private); + Private_c* priv = Common_Get(now_private); - if (priv != NULL) { - mISL_SetPlayerAction(&priv->player_ID, action); - } + if (priv != NULL) { + mISL_SetPlayerAction(&priv->player_ID, action); + } } extern int mISL_CheckPlayerAction(PersonalID_c* pid, u32 action) { - int res = FALSE; + int res = FALSE; - if (pid != NULL) { - u32* check_p = mISL_GetCheckP(pid); + if (pid != NULL) { + u32* check_p = mISL_GetCheckP(pid); - if (check_p != NULL && (check_p[0] & action) != 0) { - res = TRUE; + if (check_p != NULL && (check_p[0] & action) != 0) { + res = TRUE; + } } - } - return res; + return res; } extern int mISL_CheckNowPlayerAction(u32 action) { - Private_c* priv = Common_Get(now_private); - int res = FALSE; + Private_c* priv = Common_Get(now_private); + int res = FALSE; - if (priv != NULL) { - res = mISL_CheckPlayerAction(&priv->player_ID, action); - } + if (priv != NULL) { + res = mISL_CheckPlayerAction(&priv->player_ID, action); + } - return res; + return res; } static void mISL_int(u32* dst, u32* src, int n) { - int i; + int i; - for (i = n; i != 0; i--) { - u32 v = ((src[0] & 0xFF) << 24) | ((src[0] & 0xFF00) << 8) | ((src[0] >> 8) & 0xFF00) | ((src[0] >> 24) & 0xFF); - src++; - *dst++ = v; - } + for (i = n; i != 0; i--) { + u32 v = ((src[0] & 0xFF) << 24) | ((src[0] & 0xFF00) << 8) | ((src[0] >> 8) & 0xFF00) | ((src[0] >> 24) & 0xFF); + src++; + *dst++ = v; + } } static void mISL_short(register u16* dst, register u16* src, register int n) { - int i; + int i; - for (i = n; i != 0; i--) { - u16 v = ((src[0] & 0xFF) << 8 ) | ((src[0] & 0xFF00) >> 8); - src++; - *dst++ = v; - } + for (i = n; i != 0; i--) { + u16 v = ((src[0] & 0xFF) << 8) | ((src[0] & 0xFF00) >> 8); + src++; + *dst++ = v; + } } static void mISL_u64(u64* dst, u64* src, int n) { - int i; - - for (i = n; i != 0; i--) { - u32 src_hi; - u32 src_lo; - u32 dst_lo; - u32 dst_hi; - - src_hi = (u32)((src[0] >> 32) & 0xFFFFFFFF); - src_lo = (u32)(src[0] & 0xFFFFFFFF); - - mISL_int(&dst_lo, &src_hi, 1); - mISL_int(&dst_hi, &src_lo, 1); + int i; - *dst = (((u64)dst_hi) << 32) | (u64)dst_lo; - - src++; - dst++; - } + for (i = n; i != 0; i--) { + u32 src_hi; + u32 src_lo; + u32 dst_lo; + u32 dst_hi; + + src_hi = (u32)((src[0] >> 32) & 0xFFFFFFFF); + src_lo = (u32)(src[0] & 0xFFFFFFFF); + + mISL_int(&dst_lo, &src_hi, 1); + mISL_int(&dst_hi, &src_lo, 1); + + *dst = (((u64)dst_hi) << 32) | (u64)dst_lo; + + src++; + dst++; + } } static mActor_name_t l_misl_agb_npc_table[NPC_ISLANDER_NUM] = { - NPC_BLISS, - NPC_DOBIE, - NPC_OHARE, - NPC_DRIFT, - NPC_JUNE, - NPC_FAITH, - NPC_FLOSSIE, - NPC_FLASH, - NPC_MAELLE, - NPC_ANNALISE, - NPC_BUD, - NPC_ELINA, - NPC_BOOMER, - NPC_PIGLEG, - NPC_YODEL, - NPC_PLUCKY, - NPC_ROWAN, - NPC_ANKHA + NPC_BLISS, NPC_DOBIE, NPC_OHARE, NPC_DRIFT, NPC_JUNE, NPC_FAITH, NPC_FLOSSIE, NPC_FLASH, NPC_MAELLE, + NPC_ANNALISE, NPC_BUD, NPC_ELINA, NPC_BOOMER, NPC_PIGLEG, NPC_YODEL, NPC_PLUCKY, NPC_ROWAN, NPC_ANKHA }; static int mISL_get_npc_idx(mActor_name_t npc_id) { - mActor_name_t* agb_npc_table_p = l_misl_agb_npc_table; - int res = 0; - int i; + mActor_name_t* agb_npc_table_p = l_misl_agb_npc_table; + int res = 0; + int i; - if (ITEM_NAME_GET_TYPE(npc_id) == NAME_TYPE_NPC) { - for (i = 0; i < NPC_ISLANDER_NUM; i++) { - if (*agb_npc_table_p == npc_id) { - res = i; - break; - } + if (ITEM_NAME_GET_TYPE(npc_id) == NAME_TYPE_NPC) { + for (i = 0; i < NPC_ISLANDER_NUM; i++) { + if (*agb_npc_table_p == npc_id) { + res = i; + break; + } - agb_npc_table_p++; + agb_npc_table_p++; + } } - } - return res; + return res; } static void mISL_get_npc_tex(u32* dst, u32* src, int idx) { - if (idx != -1 && dst != NULL && src != NULL) { - u32 base_addr = JW_GetAramAddress(RESOURCE_D_OBJ_NPC_STOCK_SCH); - - _JW_GetResourceAram(base_addr + idx * (1024 * sizeof(u32)), (u8*)src, 1024 * sizeof(u32)); - mISL_int(dst, src, 1024); - } + if (idx != -1 && dst != NULL && src != NULL) { + u32 base_addr = JW_GetAramAddress(RESOURCE_D_OBJ_NPC_STOCK_SCH); + + _JW_GetResourceAram(base_addr + idx * (1024 * sizeof(u32)), (u8*)src, 1024 * sizeof(u32)); + mISL_int(dst, src, 1024); + } } static void mISL_get_npc_pal(u16* dst, u16* src, int idx) { - if (idx != -1 && dst != NULL && src != NULL) { - u32 base_addr = JW_GetAramAddress(RESOURCE_D_OBJ_NPC_STOCK_SCL); - - _JW_GetResourceAram(base_addr + idx * (16 * sizeof(u16)), (u8*)src, 16 * sizeof(u16)); - mISL_short(dst, src, 16); - } + if (idx != -1 && dst != NULL && src != NULL) { + u32 base_addr = JW_GetAramAddress(RESOURCE_D_OBJ_NPC_STOCK_SCL); + + _JW_GetResourceAram(base_addr + idx * (16 * sizeof(u16)), (u8*)src, 16 * sizeof(u16)); + mISL_short(dst, src, 16); + } } static void mISL_get_earth_tex(u32* dst, u32* src, int idx) { - if (idx < mFM_BG_TEX_NUM && dst != NULL && src != NULL) { - u32 base_addr = JW_GetAramAddress(RESOURCE_D_BG_ISLAND_SCH); - - _JW_GetResourceAram(base_addr + idx * (1024 * sizeof(u32)), (u8*)src, 1024 * sizeof(u32)); - mISL_int(dst, src, 1024); - } + if (idx < mFM_BG_TEX_NUM && dst != NULL && src != NULL) { + u32 base_addr = JW_GetAramAddress(RESOURCE_D_BG_ISLAND_SCH); + + _JW_GetResourceAram(base_addr + idx * (1024 * sizeof(u32)), (u8*)src, 1024 * sizeof(u32)); + mISL_int(dst, src, 1024); + } } static void mISL_gc_to_agb_iandinfo(mISL_landinfo_agb_c* agb, mLd_land_info_c* gc) { - bcopy(gc->name, agb->name, LAND_NAME_SIZE); - agb->exists = gc->exists; - mISL_short(&agb->id, &gc->id, 1); + bcopy(gc->name, agb->name, LAND_NAME_SIZE); + agb->exists = gc->exists; + mISL_short(&agb->id, &gc->id, 1); } static void mISL_agb_to_gc_iandinfo(mLd_land_info_c* gc, mISL_landinfo_agb_c* agb) { - bcopy(agb->name, gc->name, LAND_NAME_SIZE); - gc->exists = agb->exists; - mISL_short(&gc->id, &agb->id, 1); + bcopy(agb->name, gc->name, LAND_NAME_SIZE); + gc->exists = agb->exists; + mISL_short(&gc->id, &agb->id, 1); } static void mISL_gc_to_agb_fg(mActor_name_t* agb, mActor_name_t* gc) { - mISL_short(agb, gc, UT_TOTAL_NUM); + mISL_short(agb, gc, UT_TOTAL_NUM); } static void mISL_gc_to_agb_fg2(mActor_name_t* agb, mActor_name_t* gc) { - int i; + int i; - for (i = 0; i < UT_TOTAL_NUM; i++) { - mActor_name_t item; + for (i = 0; i < UT_TOTAL_NUM; i++) { + mActor_name_t item; - if (*gc == 0xF123) { - item = COTTAGE_MY; - } - else if (*gc == 0xF124) { - item = COTTAGE_NPC; - } - else if (*gc == 0xF122) { - item = FLAG; - } - else if (*gc == 0xF128) { - item = BOAT; - } - else if (*gc >= HOLE_START && *gc <= HOLE_END) { - item = EMPTY_NO; - } - else if (*gc == 0xF11F) { - item = ACTOR_PROP_VILLAGER_SIGNBOARD; - } - else { - item = *gc; - } + if (*gc == 0xF123) { + item = COTTAGE_MY; + } else if (*gc == 0xF124) { + item = COTTAGE_NPC; + } else if (*gc == 0xF122) { + item = FLAG; + } else if (*gc == 0xF128) { + item = BOAT; + } else if (*gc >= HOLE_START && *gc <= HOLE_END) { + item = EMPTY_NO; + } else if (*gc == 0xF11F) { + item = ACTOR_PROP_VILLAGER_SIGNBOARD; + } else { + item = *gc; + } - - mISL_short(agb, &item, 1); - agb++; - gc++; - } + mISL_short(agb, &item, 1); + agb++; + gc++; + } } static void mISL_agb_to_gc_fg(mActor_name_t* gc, mActor_name_t* agb) { - mISL_short(gc, agb, UT_TOTAL_NUM); + mISL_short(gc, agb, UT_TOTAL_NUM); } static void mISL_gc_to_agb_fgblock(mFM_fg_c* agb, mFM_fg_c* gc) { - int i; + int i; - for (i = 0; i < mISL_FG_BLOCK_X_NUM; i++) { - mISL_gc_to_agb_fg2(agb->items[0], gc->items[0]); - agb++; - gc++; - } + for (i = 0; i < mISL_FG_BLOCK_X_NUM; i++) { + mISL_gc_to_agb_fg2(agb->items[0], gc->items[0]); + agb++; + gc++; + } } static void mISL_agb_to_gc_fgblock(mFM_fg_c* gc, mFM_fg_c* agb) { - int i; + int i; - for (i = 0; i < mISL_FG_BLOCK_X_NUM; i++) { - mISL_agb_to_gc_fg(gc->items[0], agb->items[0]); - agb++; - gc++; - } + for (i = 0; i < mISL_FG_BLOCK_X_NUM; i++) { + mISL_agb_to_gc_fg(gc->items[0], agb->items[0]); + agb++; + gc++; + } } static void mISL_gc_to_agb_layer(mHm_lyr_c* agb, mHm_lyr_c* gc) { - int i; + int i; - for (i = 0; i < mHm_LAYER_NUM; i++) { - mISL_gc_to_agb_fg(agb->items[0], gc->items[0]); - mISL_u64(&agb->ftr_switch, &gc->ftr_switch, 1); - mISL_int(agb->unk_208, gc->unk_208, ARRAY_COUNT(agb->unk_208)); + for (i = 0; i < mHm_LAYER_NUM; i++) { + mISL_gc_to_agb_fg(agb->items[0], gc->items[0]); + mISL_u64(&agb->ftr_switch, &gc->ftr_switch, 1); + mISL_int(agb->haniwa_step, gc->haniwa_step, ARRAY_COUNT(agb->haniwa_step)); - agb++; - gc++; - } + agb++; + gc++; + } } static void mISL_gc_to_agb_fllot_bit(u32* agb, mHm_fllot_bit_c* gc) { - mHm_fllot_bit_c tmp[4]; + mHm_fllot_bit_c tmp[4]; - bzero(tmp, sizeof(tmp)); - tmp[0].wall_original = gc->wall_original; - tmp[0].floor_original = gc->floor_original; - mISL_int(agb, (u32*)tmp, 1); + bzero(tmp, sizeof(tmp)); + tmp[0].wall_original = gc->wall_original; + tmp[0].floor_original = gc->floor_original; + mISL_int(agb, (u32*)tmp, 1); } static void mISL_agb_to_gc_fllot_bit(mHm_fllot_bit_c* gc, u32* agb) { - mHm_fllot_bit_c tmp[4]; + mHm_fllot_bit_c tmp[4]; - bzero(tmp, sizeof(tmp)); - mISL_int((u32*)tmp, agb, 1); + bzero(tmp, sizeof(tmp)); + mISL_int((u32*)tmp, agb, 1); - /* @BUG - devs made an oopsie and reused GC here */ - #ifndef BUGFIXES - gc->wall_original = (u32)gc->wall_original; - gc->floor_original = (u32)gc->floor_original; - #else - gc->wall_original = agb->wall_original; - gc->floor_original = agb->floor_original; - #endif +/* @BUG - devs made an oopsie and reused GC here */ +#ifndef BUGFIXES + gc->wall_original = (u32)gc->wall_original; + gc->floor_original = (u32)gc->floor_original; +#else + gc->wall_original = agb->wall_original; + gc->floor_original = agb->floor_original; +#endif } static void mISL_gc_to_agb_cottage_floor(mISL_flr_agb_c* agb, mHm_flr_c* gc) { - mISL_gc_to_agb_layer(agb->layers, &gc->layer_main); - bcopy(&gc->wall_floor, &agb->wall_floor, sizeof(gc->wall_floor)); - bcopy(&gc->tempo_beat, &agb->tempo_beat, sizeof(gc->tempo_beat)); - mISL_gc_to_agb_fllot_bit(&agb->floor_bit_info, &gc->floor_bit_info); + mISL_gc_to_agb_layer(agb->layers, &gc->layer_main); + bcopy(&gc->wall_floor, &agb->wall_floor, sizeof(gc->wall_floor)); + bcopy(&gc->tempo_beat, &agb->tempo_beat, sizeof(gc->tempo_beat)); + mISL_gc_to_agb_fllot_bit(&agb->floor_bit_info, &gc->floor_bit_info); } static void mISL_agb_to_gc_cottage_floor(mHm_flr_c* gc, mISL_flr_agb_c* agb) { - mISL_gc_to_agb_layer(&gc->layer_main, agb->layers); - bcopy(&agb->wall_floor, &gc->wall_floor, sizeof(gc->wall_floor)); - bcopy(&agb->tempo_beat, &gc->tempo_beat, sizeof(gc->tempo_beat)); - mISL_agb_to_gc_fllot_bit(&gc->floor_bit_info, &agb->floor_bit_info); + mISL_gc_to_agb_layer(&gc->layer_main, agb->layers); + bcopy(&agb->wall_floor, &gc->wall_floor, sizeof(gc->wall_floor)); + bcopy(&agb->tempo_beat, &gc->tempo_beat, sizeof(gc->tempo_beat)); + mISL_agb_to_gc_fllot_bit(&gc->floor_bit_info, &agb->floor_bit_info); } static void mISL_gc_to_agb_ymd(lbRTC_ymd_c* agb, lbRTC_ymd_c* gc) { - mISL_short(&agb->year, &gc->year, 1); - agb->month = gc->month; - agb->day = gc->day; + mISL_short(&agb->year, &gc->year, 1); + agb->month = gc->month; + agb->day = gc->day; } static void mISL_gc_to_agb_time(lbRTC_time_c* agb, lbRTC_time_c* gc) { - agb->sec = gc->sec; - agb->min = gc->min; - agb->hour = gc->hour; - agb->day = gc->day; - agb->weekday = gc->weekday; - agb->month = gc->month; - mISL_short(&agb->year, &gc->year, 1); + agb->sec = gc->sec; + agb->min = gc->min; + agb->hour = gc->hour; + agb->day = gc->day; + agb->weekday = gc->weekday; + agb->month = gc->month; + mISL_short(&agb->year, &gc->year, 1); } static void mISL_gc_to_agb_goki(mHm_goki_c* agb, mHm_goki_c* gc) { - mISL_gc_to_agb_time(&agb->time, &gc->time); - agb->num = gc->num; + mISL_gc_to_agb_time(&agb->time, &gc->time); + agb->num = gc->num; } static void mISL_agb_to_gc_goki(mHm_goki_c* gc, mHm_goki_c* agb) { - mISL_gc_to_agb_time(&gc->time, &agb->time); - gc->num = agb->num; + mISL_gc_to_agb_time(&gc->time, &agb->time); + gc->num = agb->num; } static void mISL_gc_to_agb_cottage(mISL_cottage_agb_c* agb, mHm_cottage_c* gc) { - bcopy(&gc->unused_wall_floor, &agb->unused_wall_floor, sizeof(gc->unused_wall_floor)); - bcopy(gc->unk_2, agb->unk_2, sizeof(gc->unk_2)); - mISL_gc_to_agb_cottage_floor(&agb->room, &gc->room); - agb->unk_8B8 = gc->unk_4; - agb->unk_8B9 = gc->unk_5; - mISL_gc_to_agb_goki(&agb->goki, &gc->goki); - mISL_int(agb->music_box, gc->music_box, 2); + bcopy(&gc->unused_wall_floor, &agb->unused_wall_floor, sizeof(gc->unused_wall_floor)); + bcopy(gc->unk_2, agb->unk_2, sizeof(gc->unk_2)); + mISL_gc_to_agb_cottage_floor(&agb->room, &gc->room); + agb->unk_8B8 = gc->unk_4; + agb->unk_8B9 = gc->unk_5; + mISL_gc_to_agb_goki(&agb->goki, &gc->goki); + mISL_int(agb->music_box, gc->music_box, 2); } static void mISL_agb_to_gc_cottage(mHm_cottage_c* gc, mISL_cottage_agb_c* agb) { - bcopy(&agb->unused_wall_floor, &gc->unused_wall_floor, sizeof(gc->unused_wall_floor)); - bcopy(agb->unk_2, gc->unk_2, sizeof(gc->unk_2)); - gc->unk_4 = agb->unk_8B8; - gc->unk_5 = agb->unk_8B9; - mISL_agb_to_gc_cottage_floor(&gc->room, &agb->room); - mISL_agb_to_gc_goki(&gc->goki, &agb->goki); - mISL_int(gc->music_box, agb->music_box, 2); + bcopy(&agb->unused_wall_floor, &gc->unused_wall_floor, sizeof(gc->unused_wall_floor)); + bcopy(agb->unk_2, gc->unk_2, sizeof(gc->unk_2)); + gc->unk_4 = agb->unk_8B8; + gc->unk_5 = agb->unk_8B9; + mISL_agb_to_gc_cottage_floor(&gc->room, &agb->room); + mISL_agb_to_gc_goki(&gc->goki, &agb->goki); + mISL_int(gc->music_box, agb->music_box, 2); } static void mISL_gc_to_agb_mail(mISL_Anmplmail_agb_c* agb, Anmplmail_c* gc) { - agb->font = gc->font; - agb->paper_type = gc->paper_type; - agb->present = gc->present; - agb->header_back_start = gc->header_back_start; - bcopy(gc->header, agb->header, MAIL_HEADER_LEN); - bcopy(gc->body, agb->body, MAIL_BODY_LEN); - bcopy(gc->footer, agb->footer, MAIL_FOOTER_LEN); - mISL_gc_to_agb_ymd(&agb->date, &gc->date); + agb->font = gc->font; + agb->paper_type = gc->paper_type; + agb->present = gc->present; + agb->header_back_start = gc->header_back_start; + bcopy(gc->header, agb->header, MAIL_HEADER_LEN); + bcopy(gc->body, agb->body, MAIL_BODY_LEN); + bcopy(gc->footer, agb->footer, MAIL_FOOTER_LEN); + mISL_gc_to_agb_ymd(&agb->date, &gc->date); } static void mISL_agb_to_gc_mail(Anmplmail_c* gc, mISL_Anmplmail_agb_c* agb) { - gc->font = agb->font; - gc->paper_type = agb->paper_type; - gc->present = agb->present; - gc->header_back_start = agb->header_back_start; - bcopy(agb->header, gc->header, MAIL_HEADER_LEN); - bcopy(agb->body, gc->body, MAIL_BODY_LEN); - bcopy(agb->footer, gc->footer, MAIL_FOOTER_LEN); - mISL_gc_to_agb_ymd(&gc->date, &agb->date); + gc->font = agb->font; + gc->paper_type = agb->paper_type; + gc->present = agb->present; + gc->header_back_start = agb->header_back_start; + bcopy(agb->header, gc->header, MAIL_HEADER_LEN); + bcopy(agb->body, gc->body, MAIL_BODY_LEN); + bcopy(agb->footer, gc->footer, MAIL_FOOTER_LEN); + mISL_gc_to_agb_ymd(&gc->date, &agb->date); } static void mIS_gc_to_agb_anmpersonal(AnmPersonalID_c* agb, AnmPersonalID_c* gc) { - mISL_short(&agb->npc_id, &gc->npc_id, 1); - mISL_short(&agb->land_id, &gc->land_id, 1); - bcopy(gc->land_name, agb->land_name, LAND_NAME_SIZE); - agb->name_id = gc->name_id; - agb->looks = gc->looks; + mISL_short(&agb->npc_id, &gc->npc_id, 1); + mISL_short(&agb->land_id, &gc->land_id, 1); + bcopy(gc->land_name, agb->land_name, LAND_NAME_SIZE); + agb->name_id = gc->name_id; + agb->looks = gc->looks; } static void mIS_agb_to_gc_anmpersonal(AnmPersonalID_c* gc, AnmPersonalID_c* agb) { - mISL_short(&gc->npc_id, &agb->npc_id, 1); - mISL_short(&gc->land_id, &agb->land_id, 1); - bcopy(agb->land_name, gc->land_name, LAND_NAME_SIZE); - gc->name_id = agb->name_id; - gc->looks = agb->looks; + mISL_short(&gc->npc_id, &agb->npc_id, 1); + mISL_short(&gc->land_id, &agb->land_id, 1); + bcopy(agb->land_name, gc->land_name, LAND_NAME_SIZE); + gc->name_id = agb->name_id; + gc->looks = agb->looks; } static void mISL_gc_to_agb_personal(PersonalID_c* agb, PersonalID_c* gc) { - bcopy(gc->player_name, agb->player_name, PLAYER_NAME_LEN); - bcopy(gc->land_name, agb->land_name, LAND_NAME_SIZE); - mISL_short(&agb->player_id, &gc->player_id, 1); - mISL_short(&agb->land_id, &gc->land_id, 1); + bcopy(gc->player_name, agb->player_name, PLAYER_NAME_LEN); + bcopy(gc->land_name, agb->land_name, LAND_NAME_SIZE); + mISL_short(&agb->player_id, &gc->player_id, 1); + mISL_short(&agb->land_id, &gc->land_id, 1); } static void mISL_gc_to_agb_memuni(memuni_u* agb, memuni_u* gc) { - mISL_int((u32*)agb, (u32*)gc, sizeof(memuni_u) / sizeof(u32)); + mISL_int((u32*)agb, (u32*)gc, sizeof(memuni_u) / sizeof(u32)); } static void mISL_agb_to_gc_memuni(memuni_u* gc, memuni_u* agb) { - mISL_int((u32*)gc, (u32*)agb, sizeof(memuni_u) / sizeof(u32)); + mISL_int((u32*)gc, (u32*)agb, sizeof(memuni_u) / sizeof(u32)); } static void mISL_gc_to_agb_memletter(u32* agb, Anmlet_c* gc) { - Anmlet_c t[4]; + Anmlet_c t[4]; - bzero(t, sizeof(t)); - t[0].exists = gc->exists; - t[0].cond = gc->cond; - t[0].send_reply = gc->send_reply; - t[0].has_present_cloth = gc->has_present_cloth; - t[0].wearing_present_cloth = gc->wearing_present_cloth; - mISL_int(agb, (u32*)t, 1); + bzero(t, sizeof(t)); + t[0].exists = gc->exists; + t[0].cond = gc->cond; + t[0].send_reply = gc->send_reply; + t[0].has_present_cloth = gc->has_present_cloth; + t[0].wearing_present_cloth = gc->wearing_present_cloth; + mISL_int(agb, (u32*)t, 1); } static void mISL_agb_to_gc_memletter(Anmlet_c* gc, u32* agb) { - Anmlet_c t[4]; + Anmlet_c t[4]; - bzero(t, sizeof(t)); - mISL_int((u32*)t, agb, 1); - gc->exists = t[0].exists; - gc->cond = t[0].cond; - gc->send_reply = t[0].send_reply; - gc->has_present_cloth = t[0].has_present_cloth; - gc->wearing_present_cloth = t[0].wearing_present_cloth; + bzero(t, sizeof(t)); + mISL_int((u32*)t, agb, 1); + gc->exists = t[0].exists; + gc->cond = t[0].cond; + gc->send_reply = t[0].send_reply; + gc->has_present_cloth = t[0].has_present_cloth; + gc->wearing_present_cloth = t[0].wearing_present_cloth; } static void mISL_gc_to_agb_memory(mISL_Anmmem_agb_c* agb, Anmmem_c* gc) { - mISL_gc_to_agb_personal(&agb->player_id, &gc->memory_player_id); - mISL_gc_to_agb_time(&agb->last_speak_time, &gc->last_speak_time); - mISL_gc_to_agb_memuni(&agb->memuni, &gc->memuni); - /* @BUG - devs forgot to save this, but remembered to restore it */ - #ifdef BUGFIXES - mISL_u64(&agb->saved_town_tune, &gc->saved_town_tune, 1); - #endif - agb->friendship = gc->friendship; - mISL_gc_to_agb_memletter(&agb->letter_info, &gc->letter_info); - mISL_gc_to_agb_mail(&agb->letter, &gc->letter); + mISL_gc_to_agb_personal(&agb->player_id, &gc->memory_player_id); + mISL_gc_to_agb_time(&agb->last_speak_time, &gc->last_speak_time); + mISL_gc_to_agb_memuni(&agb->memuni, &gc->memuni); +/* @BUG - devs forgot to save this, but remembered to restore it */ +#ifdef BUGFIXES + mISL_u64(&agb->saved_town_tune, &gc->saved_town_tune, 1); +#endif + agb->friendship = gc->friendship; + mISL_gc_to_agb_memletter(&agb->letter_info, &gc->letter_info); + mISL_gc_to_agb_mail(&agb->letter, &gc->letter); } static void mISL_agb_to_gc_memory(Anmmem_c* gc, mISL_Anmmem_agb_c* agb) { - mISL_gc_to_agb_personal(&gc->memory_player_id, &agb->player_id); - mISL_gc_to_agb_time(&gc->last_speak_time, &agb->last_speak_time); - mISL_agb_to_gc_memuni(&gc->memuni, &agb->memuni); - mISL_u64(&gc->saved_town_tune, &agb->saved_town_tune, 1); - gc->friendship = agb->friendship; - mISL_agb_to_gc_memletter(&gc->letter_info, &agb->letter_info); - mISL_agb_to_gc_mail(&gc->letter, &agb->letter); + mISL_gc_to_agb_personal(&gc->memory_player_id, &agb->player_id); + mISL_gc_to_agb_time(&gc->last_speak_time, &agb->last_speak_time); + mISL_agb_to_gc_memuni(&gc->memuni, &agb->memuni); + mISL_u64(&gc->saved_town_tune, &agb->saved_town_tune, 1); + gc->friendship = agb->friendship; + mISL_agb_to_gc_memletter(&gc->letter_info, &agb->letter_info); + mISL_agb_to_gc_mail(&gc->letter, &agb->letter); } - static void mISL_gc_to_agb_qclass(mISL_quest_base_c* agb, mQst_base_c* gc) { - mQst_base_c t; - - bzero(&t, sizeof(t)); - t.quest_type = gc->quest_type; - t.quest_kind = gc->quest_kind; - t.time_limit_enabled = gc->time_limit_enabled; - t.progress = gc->progress; - t.give_reward = gc->give_reward; - mISL_int(&agb->info, (u32*)&t, 1); - mISL_gc_to_agb_time(&agb->time_limit, &gc->time_limit); + mQst_base_c t; + + bzero(&t, sizeof(t)); + t.quest_type = gc->quest_type; + t.quest_kind = gc->quest_kind; + t.time_limit_enabled = gc->time_limit_enabled; + t.progress = gc->progress; + t.give_reward = gc->give_reward; + mISL_int(&agb->info, (u32*)&t, 1); + mISL_gc_to_agb_time(&agb->time_limit, &gc->time_limit); } static void mISL_agb_to_gc_qclass(mQst_base_c* gc, mISL_quest_base_c* agb) { - mQst_base_c t; - - bzero(&t, sizeof(t)); - mISL_int((u32*)&t, &agb->info, 1); - gc->quest_type = t.quest_type; - gc->quest_kind = t.quest_kind; - gc->time_limit_enabled = t.time_limit_enabled; - gc->progress = t.progress; - gc->give_reward = t.give_reward; - mISL_gc_to_agb_time(&gc->time_limit, &agb->time_limit); + mQst_base_c t; + + bzero(&t, sizeof(t)); + mISL_int((u32*)&t, &agb->info, 1); + gc->quest_type = t.quest_type; + gc->quest_kind = t.quest_kind; + gc->time_limit_enabled = t.time_limit_enabled; + gc->progress = t.progress; + gc->give_reward = t.give_reward; + mISL_gc_to_agb_time(&gc->time_limit, &agb->time_limit); } static void mISL_gc_to_agb_qdata(mQst_contest_info_u* agb, mQst_contest_info_u* gc) { - mISL_int((u32*)agb, (u32*)gc, sizeof(mQst_contest_info_u) / sizeof(u32)); + mISL_int((u32*)agb, (u32*)gc, sizeof(mQst_contest_info_u) / sizeof(u32)); } static void mISL_agb_to_gc_qdata(mQst_contest_info_u* gc, mQst_contest_info_u* agb) { - mISL_int((u32*)gc, (u32*)agb, sizeof(mQst_contest_info_u) / sizeof(u32)); + mISL_int((u32*)gc, (u32*)agb, sizeof(mQst_contest_info_u) / sizeof(u32)); } static void mISL_gc_to_agb_quest(mISL_quest_contest_c* agb, mQst_contest_c* gc) { - mISL_gc_to_agb_qclass(&agb->base, &gc->base); - mISL_short(&agb->requested_item, &gc->requested_item, 1); - mISL_gc_to_agb_personal(&agb->player_id, &gc->player_id); - agb->type = gc->type; - mISL_gc_to_agb_qdata(&agb->info, &gc->info); + mISL_gc_to_agb_qclass(&agb->base, &gc->base); + mISL_short(&agb->requested_item, &gc->requested_item, 1); + mISL_gc_to_agb_personal(&agb->player_id, &gc->player_id); + agb->type = gc->type; + mISL_gc_to_agb_qdata(&agb->info, &gc->info); } static void mISL_agb_to_gc_quest(mQst_contest_c* gc, mISL_quest_contest_c* agb) { - mISL_agb_to_gc_qclass(&gc->base, &agb->base); - mISL_short(&gc->requested_item, &agb->requested_item, 1); - mISL_gc_to_agb_personal(&agb->player_id, &gc->player_id); - gc->type = agb->type; - mISL_agb_to_gc_qdata(&gc->info, &agb->info); + mISL_agb_to_gc_qclass(&gc->base, &agb->base); + mISL_short(&gc->requested_item, &agb->requested_item, 1); + mISL_gc_to_agb_personal(&agb->player_id, &gc->player_id); + gc->type = agb->type; + mISL_agb_to_gc_qdata(&gc->info, &agb->info); } static void mISL_gc_to_agb_anmuni(anmuni_u* agb, anmuni_u* gc) { - mISL_int((u32*)agb, (u32*)gc, sizeof(anmuni_u) / sizeof(u32)); + mISL_int((u32*)agb, (u32*)gc, sizeof(anmuni_u) / sizeof(u32)); } static void mISL_agb_to_gc_anmuni(anmuni_u* gc, anmuni_u* agb) { - mISL_int((u32*)gc, (u32*)agb, sizeof(anmuni_u) / sizeof(u32)); + mISL_int((u32*)gc, (u32*)agb, sizeof(anmuni_u) / sizeof(u32)); } static void mISL_gc_to_agb_hp_mail(AnmHPMail_c* agb, AnmHPMail_c* gc) { - mISL_gc_to_agb_time(&agb->receive_time, &gc->receive_time); - bcopy(gc->password, agb->password, sizeof(gc->password)); + mISL_gc_to_agb_time(&agb->receive_time, &gc->receive_time); + bcopy(gc->password, agb->password, sizeof(gc->password)); } static void mISL_agb_to_gc_hp_mail(AnmHPMail_c* gc, AnmHPMail_c* agb) { - mISL_gc_to_agb_time(&gc->receive_time, &agb->receive_time); - bcopy(agb->password, gc->password, sizeof(gc->password)); + mISL_gc_to_agb_time(&gc->receive_time, &agb->receive_time); + bcopy(agb->password, gc->password, sizeof(gc->password)); } static void mISL_gc_to_agb_animal(mISL_Animal_agb_c* agb, Animal_c* gc) { - int i; + int i; - mIS_gc_to_agb_anmpersonal(&agb->id, &gc->id); - for (i = 0; i < ANIMAL_MEMORY_NUM; i++) { - mISL_gc_to_agb_memory(&agb->memories[i], &gc->memories[i]); - } + mIS_gc_to_agb_anmpersonal(&agb->id, &gc->id); + for (i = 0; i < ANIMAL_MEMORY_NUM; i++) { + mISL_gc_to_agb_memory(&agb->memories[i], &gc->memories[i]); + } - bcopy(&gc->home_info, &agb->home_info, sizeof(Anmhome_c)); - bcopy(gc->catchphrase, agb->catchphrase, ANIMAL_CATCHPHRASE_LEN); - mISL_gc_to_agb_quest(&agb->contest_quest, &gc->contest_quest); - bcopy(gc->parent_name, agb->parent_name, PLAYER_NAME_LEN); - mISL_gc_to_agb_anmuni(&agb->anmuni, &gc->anmuni); - agb->mood = gc->mood; - agb->mood_time = gc->mood_time; - mISL_short(&agb->cloth, &gc->cloth, 1); - mISL_short(&agb->remove_info, &gc->remove_info, 1); - agb->is_home = gc->is_home; - agb->moved_in = gc->moved_in; - agb->removing = gc->removing; - agb->cloth_original_id = gc->cloth_original_id; - agb->umbrella_id = gc->umbrella_id; - agb->unk_932 = gc->unk_8ED; - mISL_short(&agb->present_cloth, &gc->present_cloth, 1); - bcopy(gc->animal_relations, agb->animal_relations, ANIMAL_NUM_MAX); + bcopy(&gc->home_info, &agb->home_info, sizeof(Anmhome_c)); + bcopy(gc->catchphrase, agb->catchphrase, ANIMAL_CATCHPHRASE_LEN); + mISL_gc_to_agb_quest(&agb->contest_quest, &gc->contest_quest); + bcopy(gc->parent_name, agb->parent_name, PLAYER_NAME_LEN); + mISL_gc_to_agb_anmuni(&agb->anmuni, &gc->anmuni); + agb->mood = gc->mood; + agb->mood_time = gc->mood_time; + mISL_short(&agb->cloth, &gc->cloth, 1); + mISL_short(&agb->remove_info, &gc->remove_info, 1); + agb->is_home = gc->is_home; + agb->moved_in = gc->moved_in; + agb->removing = gc->removing; + agb->cloth_original_id = gc->cloth_original_id; + agb->umbrella_id = gc->umbrella_id; + agb->unk_932 = gc->unk_8ED; + mISL_short(&agb->present_cloth, &gc->present_cloth, 1); + bcopy(gc->animal_relations, agb->animal_relations, ANIMAL_NUM_MAX); - for (i = 0; i < ANIMAL_HP_MAIL_NUM; i++) { - mISL_gc_to_agb_hp_mail(&agb->hp_mail[i], &gc->hp_mail[i]); - } + for (i = 0; i < ANIMAL_HP_MAIL_NUM; i++) { + mISL_gc_to_agb_hp_mail(&agb->hp_mail[i], &gc->hp_mail[i]); + } } static void mISL_agb_to_gc_animal(Animal_c* gc, mISL_Animal_agb_c* agb) { - int i; + int i; - mIS_agb_to_gc_anmpersonal(&gc->id, &agb->id); - for (i = 0; i < ANIMAL_MEMORY_NUM; i++) { - mISL_agb_to_gc_memory(&gc->memories[i], &agb->memories[i]); - } + mIS_agb_to_gc_anmpersonal(&gc->id, &agb->id); + for (i = 0; i < ANIMAL_MEMORY_NUM; i++) { + mISL_agb_to_gc_memory(&gc->memories[i], &agb->memories[i]); + } - bcopy(&agb->home_info, &gc->home_info, sizeof(Anmhome_c)); - bcopy(agb->catchphrase, gc->catchphrase, ANIMAL_CATCHPHRASE_LEN); - mISL_agb_to_gc_quest(&gc->contest_quest, &agb->contest_quest); - bcopy(agb->parent_name, gc->parent_name, PLAYER_NAME_LEN); - mISL_agb_to_gc_anmuni(&gc->anmuni, &agb->anmuni); - gc->mood = agb->mood; - gc->mood_time = agb->mood_time; - mISL_short(&gc->cloth, &agb->cloth, 1); - mISL_short(&gc->remove_info, &agb->remove_info, 1); - gc->is_home = agb->is_home; - gc->moved_in = agb->moved_in; - gc->removing = agb->removing; - gc->cloth_original_id = agb->cloth_original_id; - gc->umbrella_id = agb->umbrella_id; - gc->unk_8ED = agb->unk_932; - mISL_short(&gc->present_cloth, &agb->present_cloth, 1); - bcopy(agb->animal_relations, gc->animal_relations, ANIMAL_NUM_MAX); + bcopy(&agb->home_info, &gc->home_info, sizeof(Anmhome_c)); + bcopy(agb->catchphrase, gc->catchphrase, ANIMAL_CATCHPHRASE_LEN); + mISL_agb_to_gc_quest(&gc->contest_quest, &agb->contest_quest); + bcopy(agb->parent_name, gc->parent_name, PLAYER_NAME_LEN); + mISL_agb_to_gc_anmuni(&gc->anmuni, &agb->anmuni); + gc->mood = agb->mood; + gc->mood_time = agb->mood_time; + mISL_short(&gc->cloth, &agb->cloth, 1); + mISL_short(&gc->remove_info, &agb->remove_info, 1); + gc->is_home = agb->is_home; + gc->moved_in = agb->moved_in; + gc->removing = agb->removing; + gc->cloth_original_id = agb->cloth_original_id; + gc->umbrella_id = agb->umbrella_id; + gc->unk_8ED = agb->unk_932; + mISL_short(&gc->present_cloth, &agb->present_cloth, 1); + bcopy(agb->animal_relations, gc->animal_relations, ANIMAL_NUM_MAX); - for (i = 0; i < ANIMAL_HP_MAIL_NUM; i++) { - mISL_agb_to_gc_hp_mail(&gc->hp_mail[i], &agb->hp_mail[i]); - } + for (i = 0; i < ANIMAL_HP_MAIL_NUM; i++) { + mISL_agb_to_gc_hp_mail(&gc->hp_mail[i], &agb->hp_mail[i]); + } } static int mISL_ReturnCheckSum(u8* data, int size) { - int checksum = 0; - int i; + int checksum = 0; + int i; - for (i = size; i != 0; i--) { - checksum += *data++; - } + for (i = size; i != 0; i--) { + checksum += *data++; + } - return checksum; + return checksum; } static u8 mISL_GetFlatCheckSum(u8* data, int size, u8 now_checksum, int ignored_section_checksum) { - int checksum = mISL_ReturnCheckSum(data, size); - u8 diff = (u8)(checksum - now_checksum) - ignored_section_checksum; + int checksum = mISL_ReturnCheckSum(data, size); + u8 diff = (u8)(checksum - now_checksum) - ignored_section_checksum; - diff = ~diff; - diff = diff + 1; + diff = ~diff; + diff = diff + 1; - return diff; + return diff; } extern void mISL_gc_to_agb(Island_agb_c* agb, Island_c* gc) { - int npc_idx; - u32* temp; + int npc_idx; + u32* temp; - if (agb != NULL) { - bcopy(gc->name, agb->name, mISL_ISLAND_NAME_LEN); - agb->in_use = FALSE; - mISL_gc_to_agb_iandinfo(&agb->landinfo, &gc->landinfo); - mISL_gc_to_agb_fgblock(agb->fgblock[0], gc->fgblock[0]); - mISL_gc_to_agb_cottage(&agb->cottage, &gc->cottage); - bcopy(&gc->flag_design, &agb->flag_design, sizeof(mNW_original_design_c)); - mISL_gc_to_agb_animal(&agb->animal, &gc->animal); - mISL_short(agb->deposit[0], gc->deposit[0], sizeof(gc->deposit) / sizeof(u16)); - bcopy(gc->bg_data, agb->bg_data, sizeof(gc->bg_data)); - mISL_gc_to_agb_time(&agb->renew_time, &gc->renew_time); + if (agb != NULL) { + bcopy(gc->name, agb->name, mISL_ISLAND_NAME_LEN); + agb->in_use = FALSE; + mISL_gc_to_agb_iandinfo(&agb->landinfo, &gc->landinfo); + mISL_gc_to_agb_fgblock(agb->fgblock[0], gc->fgblock[0]); + mISL_gc_to_agb_cottage(&agb->cottage, &gc->cottage); + bcopy(&gc->flag_design, &agb->flag_design, sizeof(mNW_original_design_c)); + mISL_gc_to_agb_animal(&agb->animal, &gc->animal); + mISL_short(agb->deposit[0], gc->deposit[0], sizeof(gc->deposit) / sizeof(u16)); + bcopy(gc->bg_data, agb->bg_data, sizeof(gc->bg_data)); + mISL_gc_to_agb_time(&agb->renew_time, &gc->renew_time); - if (Common_Get(island_weather) == mEnv_WEATHER_RAIN) { - agb->weather = mEnv_WEATHER_RAIN; + if (Common_Get(island_weather) == mEnv_WEATHER_RAIN) { + agb->weather = mEnv_WEATHER_RAIN; + } else { + agb->weather = mEnv_WEATHER_CLEAR; + } + + npc_idx = mISL_get_npc_idx(Save_Get(island).animal.id.npc_id); + mISL_int((u32*)&agb->npc_idx, (u32*)&npc_idx, 1); + temp = (u32*)zelda_malloc_align(0x1000, 32); + agb->grass_tex_type = gc->grass_tex_type; + + if (temp != NULL) { + bzero(temp, 0x1000); + mISL_get_npc_tex(agb->npc_tex, temp, npc_idx); + bzero(temp, 0x1000); + mISL_get_npc_pal(agb->npc_pal, (u16*)temp, npc_idx); + bzero(temp, 0x1000); + mISL_get_earth_tex(agb->earth_tex, temp, agb->grass_tex_type); + zelda_free(temp); + } + + agb->last_song_to_island = gc->last_song_to_island; + agb->last_song_from_island = gc->last_song_from_island; + // remove the land info portion from the checksum as it can change + agb->checksum = mISL_GetFlatCheckSum((u8*)agb, sizeof(Island_agb_c), agb->checksum, + mISL_ReturnCheckSum((u8*)&agb->landinfo, 16)); } - else { - agb->weather = mEnv_WEATHER_CLEAR; - } - - npc_idx = mISL_get_npc_idx(Save_Get(island).animal.id.npc_id); - mISL_int((u32*)&agb->npc_idx, (u32*)&npc_idx, 1); - temp = (u32*)zelda_malloc_align(0x1000, 32); - agb->grass_tex_type = gc->grass_tex_type; - - if (temp != NULL) { - bzero(temp, 0x1000); - mISL_get_npc_tex(agb->npc_tex, temp, npc_idx); - bzero(temp, 0x1000); - mISL_get_npc_pal(agb->npc_pal, (u16*)temp, npc_idx); - bzero(temp, 0x1000); - mISL_get_earth_tex(agb->earth_tex, temp, agb->grass_tex_type); - zelda_free(temp); - } - - agb->last_song_to_island = gc->last_song_to_island; - agb->last_song_from_island = gc->last_song_from_island; - // remove the land info portion from the checksum as it can change - agb->checksum = mISL_GetFlatCheckSum((u8*)agb, sizeof(Island_agb_c), agb->checksum, mISL_ReturnCheckSum((u8*)&agb->landinfo, 16)); - } } static void mISL_toHole(mActor_name_t* fg, u16* deposit, int bx, int bz) { - int ut_x; - int ut_z; + int ut_x; + int ut_z; - for (ut_z = 0; ut_z < UT_Z_NUM; ut_z++) { - for (ut_x = 0; ut_x < UT_X_NUM; ut_x++) { - if (*fg == ITM_PITFALL && (((*deposit) >> ut_x) & 1) != 0) { - int hole_no = mCoBG_BnumUnum2HoleNumber(bx, bz, ut_x, ut_z); + for (ut_z = 0; ut_z < UT_Z_NUM; ut_z++) { + for (ut_x = 0; ut_x < UT_X_NUM; ut_x++) { + if (*fg == ITM_PITFALL && (((*deposit) >> ut_x) & 1) != 0) { + int hole_no = mCoBG_BnumUnum2HoleNumber(bx, bz, ut_x, ut_z); - if (hole_no < 0 || hole_no >= 25) { - hole_no = 0; + if (hole_no < 0 || hole_no >= 25) { + hole_no = 0; + } + + fg[0] = BURIED_PITFALL_START + hole_no; + deposit[0] &= ~(1 << ut_x); + } + + fg++; } - fg[0] = BURIED_PITFALL_START + hole_no; - deposit[0] &= ~(1 << ut_x); - } - - fg++; + deposit++; } - - deposit++; - } } /* @nonmatching */ #ifndef MUST_MATCH extern void mISL_agb_to_gc(Island_c* gc, Island_agb_c* agb) { - int island_x_blocks[mISL_FG_BLOCK_X_NUM]; - int i; + int island_x_blocks[mISL_FG_BLOCK_X_NUM]; + int i; - if (agb != NULL) { - bcopy(agb->name, gc->name, mISL_ISLAND_NAME_LEN); - mISL_agb_to_gc_iandinfo(&gc->landinfo, &agb->landinfo); - mISL_agb_to_gc_fgblock(gc->fgblock[0], agb->fgblock[0]); - mISL_agb_to_gc_cottage(&gc->cottage, &agb->cottage); - bcopy(&agb->flag_design, &gc->flag_design, sizeof(mNW_original_design_c)); - mISL_agb_to_gc_animal(&gc->animal, &agb->animal); - mISL_short((u16*)gc->deposit, (u16*)agb->deposit, sizeof(gc->deposit) / sizeof(u16)); - bcopy(agb->bg_data, gc->bg_data, sizeof(gc->bg_data)); - mISL_gc_to_agb_time(&gc->renew_time, &agb->renew_time); - gc->last_song_to_island = agb->last_song_to_island; - gc->last_song_from_island = agb->last_song_from_island; + if (agb != NULL) { + bcopy(agb->name, gc->name, mISL_ISLAND_NAME_LEN); + mISL_agb_to_gc_iandinfo(&gc->landinfo, &agb->landinfo); + mISL_agb_to_gc_fgblock(gc->fgblock[0], agb->fgblock[0]); + mISL_agb_to_gc_cottage(&gc->cottage, &agb->cottage); + bcopy(&agb->flag_design, &gc->flag_design, sizeof(mNW_original_design_c)); + mISL_agb_to_gc_animal(&gc->animal, &agb->animal); + mISL_short((u16*)gc->deposit, (u16*)agb->deposit, sizeof(gc->deposit) / sizeof(u16)); + bcopy(agb->bg_data, gc->bg_data, sizeof(gc->bg_data)); + mISL_gc_to_agb_time(&gc->renew_time, &agb->renew_time); + gc->last_song_to_island = agb->last_song_to_island; + gc->last_song_from_island = agb->last_song_from_island; - if (mFI_CheckFieldData() == TRUE) { - bzero(island_x_blocks, sizeof(island_x_blocks)); - mFI_GetIslandBlockNumX(island_x_blocks); + if (mFI_CheckFieldData() == TRUE) { + bzero(island_x_blocks, sizeof(island_x_blocks)); + mFI_GetIslandBlockNumX(island_x_blocks); - for (i = 0; i < mISL_FG_BLOCK_X_NUM; i++) { - int idx = i + island_x_blocks[0]; - mActor_name_t* fg_p = &gc->fgblock[0][i].items[0][0]; - u16* deposit_p = (u16*)&gc->deposit[(u16)i]; // the access to deposit is strange, casting to u16 is incorrect but it makes all other instructions correct - - mISL_toHole(fg_p, deposit_p, idx, mISL_BLOCK_Z); - } + for (i = 0; i < mISL_FG_BLOCK_X_NUM; i++) { + int idx = i + island_x_blocks[0]; + mActor_name_t* fg_p = &gc->fgblock[0][i].items[0][0]; + u16* deposit_p = (u16*)&gc->deposit[(u16)i]; // the access to deposit is strange, casting to u16 is + // incorrect but it makes all other instructions correct + + mISL_toHole(fg_p, deposit_p, idx, mISL_BLOCK_Z); + } + } } - } } #else extern asm void mISL_agb_to_gc(Island_c* gc, Island_agb_c* agb) { - #include "asm/803b5948.s" +#include "asm/803b5948.s" } #endif diff --git a/src/m_room_type.c b/src/m_room_type.c index a212fe11..2559faa2 100644 --- a/src/m_room_type.c +++ b/src/m_room_type.c @@ -2019,9 +2019,9 @@ extern void mRmTp_MakeFamicom_Fdebug() { u16 ftr_idx; int res; Clip_c* clip; - GAME_PLAY* play = (GAME_PLAY*)gamePT; + GAME* game = gamePT; - if ((gamePT->pads[PAD1].on.button & BUTTON_Z) == BUTTON_Z && play != NULL) { + if ((gamePT->pads[PAD1].on.button & BUTTON_Z) == BUTTON_Z && game != NULL) { clip = Common_GetPointer(clip); if (clip->my_room_clip != NULL) { @@ -2036,10 +2036,10 @@ extern void mRmTp_MakeFamicom_Fdebug() { ftr_idx = 0x36A + mRmTp_famicom_idx; } - res = (*clip->my_room_clip->judge_breed_new_ftr_proc)(play, ftr_idx, &ut_x, &ut_z, &direct, &ofs, &layer); + res = (*clip->my_room_clip->judge_breed_new_ftr_proc)(game, ftr_idx, &ut_x, &ut_z, &direct, &ofs, &layer); if (res >= 0) { - (*clip->my_room_clip->reserve_ftr_proc)(play, ftr_idx, res, ut_x, ut_z, direct, ofs, layer); + (*clip->my_room_clip->reserve_ftr_proc)(game, ftr_idx, res, ut_x, ut_z, direct, ofs, layer); } } } diff --git a/tools/arc_tool.py b/tools/arc_tool.py index fec79ab9..3d45dba1 100644 --- a/tools/arc_tool.py +++ b/tools/arc_tool.py @@ -10,14 +10,13 @@ def unpack_dir(archive: pyjkernel.JKRArchive, dir: str, verbose=False): if verbose: print('Dumping file: ' + file.name) with open(os.path.join(dir, file.name), "wb") as f: - f.write(archive.get_file(dir + "/" + file.name).data) + f.write(archive.get_file(dir + os.sep + file.name).data) # create all subdirectories and recurse through them for subdir in archive.list_folders(dir): - if not os.path.exists(dir + "/" + subdir): - os.mkdir(dir + "/" + subdir) - unpack_dir(archive, dir + "/" + subdir, verbose) - + if not os.path.exists(dir + os.sep + subdir): + os.mkdir(dir + os.sep + subdir) + unpack_dir(archive, dir + os.sep + subdir, verbose) def unpack_archive(path: str, out_path: str, verbose=False): archive = pyjkernel.from_archive_file(path, True) @@ -38,13 +37,13 @@ def pack_dir(archive: pyjkernel.JKRArchive, path: str, verbose=False): for root, dirs, files in os.walk(local_root): files.sort(key=lambda item: (item.lower(), item)) for dir in dirs: - archive.create_folder(root + "/" + dir) + archive.create_folder(root + os.sep + dir) for file in files: if verbose: - print('Packing file: ' + root + '/' + file) - with open(root + "/" + file, "rb") as f: - archive.create_file(root + "/" + file, bytearray(f.read()), pyjkernel.JKRPreloadType.ARAM) + print('Packing file: ' + root + os.sep + file) + with open(root + os.sep + file, "rb") as f: + archive.create_file(root + os.sep + file, bytearray(f.read()), pyjkernel.JKRPreloadType.ARAM) os.chdir(orig_dir) def pack_archive(root_path: str, out_path: str, verbose=False): From 97c4e85adac1138d5011e06ca150ccd7ffb7d1ac Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Thu, 4 Apr 2024 04:34:22 -0400 Subject: [PATCH 2/4] Implement ac_my_room_msg_ctrl.c_inc --- config/dol.yml | 3 +- config/rel.yml | 3 +- include/Famicom/famicom.h | 173 ++- include/ac_furniture.h | 2 +- include/audio_defs.h | 15 +- include/famicom_emu.h | 6 +- include/libjsys/jsyswrapper.h | 16 +- include/m_choice.h | 130 ++- include/m_common_data.h | 2 + include/m_msg.h | 346 +++--- include/m_player_lib.h | 3 +- include/m_scene.h | 2 +- src/ac_airplane.c | 6 +- src/ac_my_room.c | 8 + src/ac_my_room_msg_ctrl.c_inc | 2039 +++++++++++++++++++++++++++++++++ src/famicom_emu.c | 10 +- src/m_scene.c | 3 +- 17 files changed, 2427 insertions(+), 340 deletions(-) create mode 100644 src/ac_my_room_msg_ctrl.c_inc diff --git a/config/dol.yml b/config/dol.yml index 520a2a3c..f6f55442 100644 --- a/config/dol.yml +++ b/config/dol.yml @@ -21,4 +21,5 @@ section_defs: bss: - name: .bss balign: 4 - - name: .sbss \ No newline at end of file + - name: .sbss +label_prefix: ".L" \ No newline at end of file diff --git a/config/rel.yml b/config/rel.yml index 8c9825af..4edb6246 100644 --- a/config/rel.yml +++ b/config/rel.yml @@ -1,4 +1,5 @@ path: dump/foresta.rel address: 0x803701C0 bss_address: 0x8125A7C0 -dol: config/dol.yml \ No newline at end of file +dol: config/dol.yml +label_prefix: ".L" \ No newline at end of file diff --git a/include/Famicom/famicom.h b/include/Famicom/famicom.h index 34340e29..4ce4c198 100644 --- a/include/Famicom/famicom.h +++ b/include/Famicom/famicom.h @@ -21,7 +21,7 @@ extern "C" { #define NESTAG_GID "GID" #define NESTAG_GNM "GNM" #define NESTAG_CPN "CPN" -#define NESTAG_OFS "OFS" /* Offset into the shared highscore data to read/write at */ +#define NESTAG_OFS "OFS" /* Offset into the shared highscore data to read/write at */ #define NESTAG_HSC "HSC" #define NESTAG_GNO "GNO" #define NESTAG_BBR "BBR" @@ -47,122 +47,122 @@ typedef void* (*MALLOC_ALIGN_FUNC)(size_t size, u32 align); typedef void (*MALLOC_FREE_FUNC)(void* ptr); typedef int (*MALLOC_GETMEMBLOCKSIZE_FUNC)(void* ptr); typedef int (*MALLOC_GETTOTALFREESIZE_FUNC)(); - + typedef struct malloc_s { - MALLOC_ALIGN_FUNC malloc_align; - MALLOC_FREE_FUNC free; - MALLOC_GETMEMBLOCKSIZE_FUNC getmemblocksize; - MALLOC_GETTOTALFREESIZE_FUNC gettotalfreesize; + MALLOC_ALIGN_FUNC malloc_align; + MALLOC_FREE_FUNC free; + MALLOC_GETMEMBLOCKSIZE_FUNC getmemblocksize; + MALLOC_GETTOTALFREESIZE_FUNC gettotalfreesize; } Famicom_MallocInfo; enum filer_demo_mode { - FILER_DEMO_MODE_NORMAL, - FILER_DEMO_MODE_AUTO, + FILER_DEMO_MODE_NORMAL, + FILER_DEMO_MODE_AUTO, - FILER_DEMO_MODE_NUM + FILER_DEMO_MODE_NUM }; #define FAMICOM_SAVE_DATA_NAME_LEN 8 +#define FAMICOM_MORI_NAME_LEN 16 typedef struct FamicomSaveDataHeader { - u8 name[FAMICOM_SAVE_DATA_NAME_LEN]; - u8 _08; - u8 _09; - u8 headerSize; - u8 checksum; - u16 size; - u8 no_save; - u8 _temp[FAMICOM_SAVE_HEADER_SIZE - 0x000F]; + u8 name[FAMICOM_SAVE_DATA_NAME_LEN]; + u8 _08; + u8 _09; + u8 headerSize; + u8 checksum; + u16 size; + u8 no_save; + u8 _temp[FAMICOM_SAVE_HEADER_SIZE - 0x000F]; } FamicomSaveDataHeader; enum { - MEMCARD_COMMENT_TYPE_NONE, - MEMCARD_COMMENT_TYPE_DEFAULT, - MEMCARD_COMMENT_TYPE_COPY_ROM, // converts rom's comment but converts "] ROM" to "] SAVE" - MEMCARD_COMMENT_TYPE_COPY_EMBEDDED // uses the embedded and unique 'save' comment + MEMCARD_COMMENT_TYPE_NONE, + MEMCARD_COMMENT_TYPE_DEFAULT, + MEMCARD_COMMENT_TYPE_COPY_ROM, // converts rom's comment but converts "] ROM" to "] SAVE" + MEMCARD_COMMENT_TYPE_COPY_EMBEDDED // uses the embedded and unique 'save' comment }; enum { - MEMCARD_BANNER_TYPE_NONE, - MEMCARD_BANNER_TYPE_DEFAULT, - MEMCARD_BANNER_TYPE_COPY_ROM, // copies the NES rom save's banner - MEMCARD_BANNER_TYPE_COPY_EMBEDDED // uses the embedded and unique 'save' banner + MEMCARD_BANNER_TYPE_NONE, + MEMCARD_BANNER_TYPE_DEFAULT, + MEMCARD_BANNER_TYPE_COPY_ROM, // copies the NES rom save's banner + MEMCARD_BANNER_TYPE_COPY_EMBEDDED // uses the embedded and unique 'save' banner }; enum { - MEMCARD_ICON_TYPE_NONE, - MEMCARD_ICON_TYPE_DEFAULT, - MEMCARD_ICON_TYPE_COPY_ROM, // copies the NES rom save's icon - MEMCARD_ICON_TYPE_COPY_EMBEDDED // uses the embedded and unique 'save' icon + MEMCARD_ICON_TYPE_NONE, + MEMCARD_ICON_TYPE_DEFAULT, + MEMCARD_ICON_TYPE_COPY_ROM, // copies the NES rom save's icon + MEMCARD_ICON_TYPE_COPY_EMBEDDED // uses the embedded and unique 'save' icon }; enum { - FAMICOM_RESULT_OK, - FAMICOM_RESULT_NOSPACE, - FAMICOM_RESULT_NOENTRY, - FAMICOM_RESULT_BROKEN, - FAMICOM_RESULT_WRONGDEVICE, - FAMICOM_RESULT_WRONGENCODING, - FAMICOM_RESULT_NOCARD, - FAMICOM_RESULT_NOFILE + FAMICOM_RESULT_OK, + FAMICOM_RESULT_NOSPACE, + FAMICOM_RESULT_NOENTRY, + FAMICOM_RESULT_BROKEN, + FAMICOM_RESULT_WRONGDEVICE, + FAMICOM_RESULT_WRONGENCODING, + FAMICOM_RESULT_NOCARD, + FAMICOM_RESULT_NOFILE }; typedef struct MemcardGameHeader_t { - u8 _00; - u8 _01; - u8 mori_name[16]; - u16 nesrom_size; - u16 nestags_size; - u16 icon_format; - u16 icon_flags; - u16 comment_img_size; /* Size of comment + banner + icon */ - struct { - u8 has_comment_img:1; - u8 comment_type:2; - u8 banner_type:2; - u8 icon_type:2; - u8 no_copy_flag:1; - } flags0; - struct { - u8 no_move_flag:1; - u8 banner_fmt:2; - u8 reserved:5; - } flags1; - u16 pad; + u8 _00; + u8 _01; + u8 mori_name[FAMICOM_MORI_NAME_LEN]; + u16 nesrom_size; + u16 nestags_size; + u16 icon_format; + u16 icon_flags; + u16 comment_img_size; /* Size of comment + banner + icon */ + struct { + u8 has_comment_img : 1; + u8 comment_type : 2; + u8 banner_type : 2; + u8 icon_type : 2; + u8 no_copy_flag : 1; + } flags0; + struct { + u8 no_move_flag : 1; + u8 banner_fmt : 2; + u8 reserved : 5; + } flags1; + u16 pad; } MemcardGameHeader_t; /* sizeof (FamicomCommon) == 0xB8 */ typedef struct FamicomCommon { - /* 0x00 */ ksNesCommonWorkObj* wp; - /* 0x04 */ ksNesStateObj* sp; - /* 0x08 */ u8* nesromp; - /* 0x0C */ u8* chrramp; - /* 0x10 */ u8* bbramp; - /* 0x14 */ u8* noise_bufp; - /* 0x18 */ u8* chr_to_i8_bufp; - /* 0x1C */ u8* result_bufp; - /* 0x20 */ u8* highscore_flagsp; - /* 0x24 */ u8* nesinfo_tagsp; - /* 0x28 */ int _28; - /* 0x2C */ u8 nesrom_memcard; // TRUE: rom is loaded from memcard, FALSE: rom is loaded internally - /* 0x2D */ u8 rom_no; - /* 0x2E */ s8 save_pl_no; - /* 0x2F */ u8 mura_save_name[33]; - /* 0x50 */ u8 famicom_save_name[33]; - /* 0x74 */ FamicomSaveDataHeader* save_data_header; - /* 0x78 */ u8* internal_save_datap; - /* 0x7C */ size_t save_data_total_size; - /* 0x80 */ size_t save_data_single_size; - /* 0x84 */ int _84; - /* 0x88 */ u8* save_data_name; - /* 0x8C */ u8 _8C; - /* 0x8D */ u8 low_res_mode; - /* 0x8E */ MemcardGameHeader_t memcard_game_header; - /* 0xB0 */ u8* memcard_save_comment; - /* 0xB4 */ size_t unused_save_data_start_ofs; + /* 0x00 */ ksNesCommonWorkObj* wp; + /* 0x04 */ ksNesStateObj* sp; + /* 0x08 */ u8* nesromp; + /* 0x0C */ u8* chrramp; + /* 0x10 */ u8* bbramp; + /* 0x14 */ u8* noise_bufp; + /* 0x18 */ u8* chr_to_i8_bufp; + /* 0x1C */ u8* result_bufp; + /* 0x20 */ u8* highscore_flagsp; + /* 0x24 */ u8* nesinfo_tagsp; + /* 0x28 */ int _28; + /* 0x2C */ u8 nesrom_memcard; // TRUE: rom is loaded from memcard, FALSE: rom is loaded internally + /* 0x2D */ u8 rom_no; + /* 0x2E */ s8 save_pl_no; + /* 0x2F */ u8 mura_save_name[33]; + /* 0x50 */ u8 famicom_save_name[33]; + /* 0x74 */ FamicomSaveDataHeader* save_data_header; + /* 0x78 */ u8* internal_save_datap; + /* 0x7C */ size_t save_data_total_size; + /* 0x80 */ size_t save_data_single_size; + /* 0x84 */ int _84; + /* 0x88 */ u8* save_data_name; + /* 0x8C */ u8 _8C; + /* 0x8D */ u8 low_res_mode; + /* 0x8E */ MemcardGameHeader_t memcard_game_header; + /* 0xB0 */ u8* memcard_save_comment; + /* 0xB4 */ size_t unused_save_data_start_ofs; } FamicomCommon; - extern Famicom_MallocInfo* my_malloc_current; extern u8 save_game_image; extern u8** nesrom_filename_ptrs; @@ -213,7 +213,6 @@ extern u8* nesinfo_get_moriName(); extern void nesinfo_init(); extern void highscore_setup_flags(u8* flags); - #ifdef __cplusplus } #endif diff --git a/include/ac_furniture.h b/include/ac_furniture.h index 0ffbc750..254479c8 100644 --- a/include/ac_furniture.h +++ b/include/ac_furniture.h @@ -220,7 +220,7 @@ struct furniture_actor_s { f32 dynamic_work_f[2]; /* reserved for any use by each unique furniture actor */ s16 layer; /* layer the furniture actor resides on */ s16 _83E; - s16 open_music_disk; /* set when a music player is interacted with */ + s16 demo_status; /* set when a music player is interacted with */ s16 dust_timer; mActor_name_t items[aFTR_KEEP_ITEM_COUNT]; /* used for holding items (music players & wardrobes) */ int _84C; diff --git a/include/audio_defs.h b/include/audio_defs.h index 18859c04..2ff8f2d4 100644 --- a/include/audio_defs.h +++ b/include/audio_defs.h @@ -15,12 +15,12 @@ extern "C" { #define MONO(id) (id | 0x1000) #define SE_FLAG_15(id) (id | 0x8000) -//TODO: Make the rest of Sound Effects with parameters +// TODO: Make the rest of Sound Effects with parameters #define SE_REGISTER MONO(0x50) -typedef enum audio_sound_effects{ +typedef enum audio_sound_effects { NA_SE_START, - NA_SE_CURSOL, + NA_SE_CURSOL, NA_SE_MENU_EXIT, NA_SE_ZOOMUP = 4, @@ -109,14 +109,19 @@ typedef enum audio_sound_effects{ NA_SE_KARABURI = 0x43A, NA_SE_ROD_STROKE_SMALL = 0x445, - + NA_SE_SCOOP_TREE_HIT = 0x448, NA_SE_SCOOP_ITEM_HIT, NA_SE_AXE_BALL_HIT, NA_SE_COIN_GASAGOSO = 0x465, -}AudioSE; +} AudioSE; + +typedef enum bgm_e { + BGM_MD0 = 128, + +} BGM_e; #ifdef __cplusplus } diff --git a/include/famicom_emu.h b/include/famicom_emu.h index b260dd60..c797ba43 100644 --- a/include/famicom_emu.h +++ b/include/famicom_emu.h @@ -11,7 +11,7 @@ extern "C" { /* sizeof(struct game_famicom_emu_s) == 0xE0 */ typedef struct game_famicom_emu_s { - /* 0x00 */ GAME game; + /* 0x00 */ GAME game; } GAME_FAMICOM_EMU; extern Famicom_MallocInfo my_malloc_func; @@ -19,8 +19,8 @@ extern Famicom_MallocInfo my_malloc_func; extern void famicom_emu_main(GAME* game); extern void famicom_emu_init(GAME* game); extern void famicom_emu_cleanup(GAME* game); -extern int famicom_gba_getImage(u32 rom_id, int* ptr); -extern void famicom_gba_removeImage(void* ); +extern void* famicom_gba_getImage(u32 rom_id, size_t* size); +extern void famicom_gba_removeImage(void*); #ifdef __cplusplus } diff --git a/include/libjsys/jsyswrapper.h b/include/libjsys/jsyswrapper.h index c1938f10..e93f8bdb 100644 --- a/include/libjsys/jsyswrapper.h +++ b/include/libjsys/jsyswrapper.h @@ -12,12 +12,12 @@ extern "C" { #endif typedef struct { - u16 mFileID; // _00 - u16 mHash; // _02 - u32 mFlag; // _04 - u32 mDataOffset; // _08 - u32 mSize; // _0C - void* mData; // _10 + u16 mFileID; // _00 + u16 mHash; // _02 + u32 mFlag; // _04 + u32 mDataOffset; // _08 + u32 mSize; // _0C + void* mData; // _10 } CSDIFileEntry; extern void* JC_JFWSystem_getSystemConsole(); @@ -116,8 +116,8 @@ extern void* JC_JUTFader_new(int ul_x, int ul_y, int br_x, int br_y, u32* color) extern void JC_JUTFader_delete(void* fader); extern void JC_JFWDisplay_changeToDoubleXfb(void* manager); -extern u32 JC__JKRGetResource(char* resourceName); -extern int JC__JKRGetMemBlockSize(int, u32); +extern void* JC__JKRGetResource(const char* resourceName); +extern u32 JC__JKRGetMemBlockSize(int, void*); extern void JC__JKRRemoveResource(void* res); diff --git a/include/m_choice.h b/include/m_choice.h index 3d29970c..bb496e99 100644 --- a/include/m_choice.h +++ b/include/m_choice.h @@ -15,94 +15,94 @@ typedef struct choice_s mChoice_c; typedef struct choice_data_s mChoice_Data_c; enum choice { - mChoice_CHOICE0, - mChoice_CHOICE1, - mChoice_CHOICE2, - mChoice_CHOICE3, - mChoice_CHOICE4, - mChoice_CHOICE5, + mChoice_CHOICE0, + mChoice_CHOICE1, + mChoice_CHOICE2, + mChoice_CHOICE3, + mChoice_CHOICE4, + mChoice_CHOICE5, - mChoice_CHOICE_NUM + mChoice_CHOICE_NUM }; enum { - mChoice_AUTOMOVE_STOPPED, - mChoice_AUTOMOVE_INCREMENT_WAIT, - mChoice_AUTOMOVE_INCREMENT, - mChoice_AUTOMOVE_DECREMENT_WAIT, - mChoice_AUTOMOVE_DECREMENT, + mChoice_AUTOMOVE_STOPPED, + mChoice_AUTOMOVE_INCREMENT_WAIT, + mChoice_AUTOMOVE_INCREMENT, + mChoice_AUTOMOVE_DECREMENT_WAIT, + mChoice_AUTOMOVE_DECREMENT, - mChoice_AUTOMOVE_NUM + mChoice_AUTOMOVE_NUM }; enum { - mChoice_MAIN_HIDE, - mChoice_MAIN_APPEAR, - mChoice_MAIN_NORMAL, - mChoice_MAIN_DISAPPEAR, + mChoice_MAIN_HIDE, + mChoice_MAIN_APPEAR, + mChoice_MAIN_NORMAL, + mChoice_MAIN_DISAPPEAR, - mChoice_MAIN_INDEX_NUM + mChoice_MAIN_INDEX_NUM }; struct choice_data_s { - u8 strings[mChoice_CHOICE_NUM][mChoice_CHOICE_STRING_LEN]; - int string_lens[mChoice_CHOICE_NUM]; - u8 determination_string[mChoice_CHOICE_STRING_LEN]; - int determination_len; - int choice_num; - int selected_choice_idx; + u8 strings[mChoice_CHOICE_NUM][mChoice_CHOICE_STRING_LEN]; + int string_lens[mChoice_CHOICE_NUM]; + u8 determination_string[mChoice_CHOICE_STRING_LEN]; + int determination_len; + int choice_num; + int selected_choice_idx; }; struct choice_s { - /* Current XY position (centered) */ - /* 0x00 */ f32 center_x; - /* 0x04 */ f32 center_y; + /* Current XY position (centered) */ + /* 0x00 */ f32 center_x; + /* 0x04 */ f32 center_y; - /* Initial XY position */ - /* 0x08 */ f32 center_x_begin; - /* 0x0C */ f32 center_y_begin; + /* Initial XY position */ + /* 0x08 */ f32 center_x_begin; + /* 0x0C */ f32 center_y_begin; - /* Target XY position */ - /* 0x10 */ f32 center_x_target; - /* 0x14 */ f32 center_y_target; + /* Target XY position */ + /* 0x10 */ f32 center_x_target; + /* 0x14 */ f32 center_y_target; - /* Text settings */ - /* 0x18 */ rgba_t text_color; - /* 0x1C */ f32 text_scale_x; - /* 0x20 */ f32 text_scale_y; - /* 0x24 */ f32 text_x; - /* 0x28 */ f32 text_y; + /* Text settings */ + /* 0x18 */ rgba_t text_color; + /* 0x1C */ f32 text_scale_x; + /* 0x20 */ f32 text_scale_y; + /* 0x24 */ f32 text_x; + /* 0x28 */ f32 text_y; - /* Window scaling XY */ - /* 0x2C */ f32 scale_x; - /* 0x30 */ f32 scale_y; + /* Window scaling XY */ + /* 0x2C */ f32 scale_x; + /* 0x30 */ f32 scale_y; - /* Text related data */ - /* 0x34 */ mChoice_Data_c data; + /* Text related data */ + /* 0x34 */ mChoice_Data_c data; - /* 0xC8 */ int selected_choice_idx; - /* 0xCC */ rgba_t selected_choice_text_color; - - /* 0xD0 */ rgba_t background_color; + /* 0xC8 */ int selected_choice_idx; + /* 0xCC */ rgba_t selected_choice_text_color; - /* 0xD4 */ f32 _D4; - /* 0xD8 */ f32 _D8; + /* 0xD0 */ rgba_t background_color; - /* 0xDC */ f32 scale; // total choice window scaling percentage + /* 0xD4 */ f32 _D4; + /* 0xD8 */ f32 _D8; - /* 0xE0 */ int main_index; - /* 0xE4 */ int requested_main_index; + /* 0xDC */ f32 scale; // total choice window scaling percentage - /* 0xE8 */ int window_visible_flag; - /* 0xEC */ int font_visible_flag; + /* 0xE0 */ int main_index; + /* 0xE4 */ int requested_main_index; - /* 0xF0 */ int choice_automove_type; - /* 0xF4 */ f32 choice_automove_timer; + /* 0xE8 */ int window_visible_flag; + /* 0xEC */ int font_visible_flag; - /* 0xF8 */ f32 timer; + /* 0xF0 */ int choice_automove_type; + /* 0xF4 */ f32 choice_automove_timer; - /* 0xFC */ u8 no_b_flag; // can't press B to select last option - /* 0xFD */ u8 no_close_flag; // pressing B won't auto-cancel the choice selection? + /* 0xF8 */ f32 timer; + + /* 0xFC */ u8 no_b_flag; // can't press B to select last option + /* 0xFD */ u8 no_close_flag; // pressing B won't auto-cancel the choice selection? }; extern void mChoice_Main(mChoice_c* choice, GAME* game); @@ -114,13 +114,21 @@ extern mChoice_c* mChoice_Get_base_window_p(); extern void mChoice_Change_request_main_index(mChoice_c* choice, int request_main_index); extern int mChoice_check_main_index(mChoice_c* choice); extern int mChoice_check_main_normal(mChoice_c* choice); -extern void mChoice_Set_choice_data( mChoice_c* choice, u8* str0, int str0_len, u8* str1, int str1_len, u8* str2, int str2_len, u8* str3, int str3_len, u8* str4, int str4_len, u8* str5, int str5_len); +extern void mChoice_Set_choice_data(mChoice_c* choice, u8* str0, int str0_len, u8* str1, int str1_len, u8* str2, + int str2_len, u8* str3, int str3_len, u8* str4, int str4_len, u8* str5, + int str5_len); extern int mChoice_Get_ChoseNum(mChoice_c* choice); extern void mChoice_Clear_ChoseNum(mChoice_c* choice); extern void mChoice_Load_ChoseStringFromRom(mChoice_c* choice, u8* str, int str_no, ACTOR* actor); extern void mChoice_no_b_set(mChoice_c* choice); extern void mChoice_no_b_close_set(mChoice_c* choice); +/* Macros */ +#define mChoice_GET_CHOSENUM() mChoice_Get_ChoseNum(mChoice_Get_base_window_p()) +#define mChoice_CLEAR_CHOSENUM() mChoice_Clear_ChoseNum(mChoice_Get_base_window_p()) +#define mChoice_NO_B_SET() mChoice_no_b_set(mChoice_Get_base_window_p()) +#define mChoice_NO_B_CLOSE_SET() mChoice_no_b_close_set(mChoice_Get_base_window_p()) + #ifdef __cplusplus } #endif diff --git a/include/m_common_data.h b/include/m_common_data.h index 056c7562..672eeea5 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -341,6 +341,8 @@ extern common_data_t common_data; #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 Now_Private (Common_Get(now_private)) + #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)) diff --git a/include/m_msg.h b/include/m_msg.h index 27912907..0a87615a 100644 --- a/include/m_msg.h +++ b/include/m_msg.h @@ -21,86 +21,86 @@ extern "C" { #define mMsg_BUTTON_TURN_TIME 60.0f enum { - mMsg_INDEX_HIDE, - mMsg_INDEX_APPEAR, - mMsg_INDEX_NORMAL, - mMsg_INDEX_CURSOL, - mMsg_INDEX_DISAPPEAR, - mMsg_INDEX_APPEAR_WAIT, - mMsg_INDEX_WAIT, - mMsg_INDEX_DISAPPEAR_WAIT, + mMsg_INDEX_HIDE, + mMsg_INDEX_APPEAR, + mMsg_INDEX_NORMAL, + mMsg_INDEX_CURSOL, + mMsg_INDEX_DISAPPEAR, + mMsg_INDEX_APPEAR_WAIT, + mMsg_INDEX_WAIT, + mMsg_INDEX_DISAPPEAR_WAIT, - mMsg_INDEX_NUM + mMsg_INDEX_NUM }; enum { - mMsg_FREE_STR0, - mMsg_FREE_STR1, - mMsg_FREE_STR2, - mMsg_FREE_STR3, - mMsg_FREE_STR4, - mMsg_FREE_STR5, - mMsg_FREE_STR6, - mMsg_FREE_STR7, - mMsg_FREE_STR8, - mMsg_FREE_STR9, - mMsg_FREE_STR10, - mMsg_FREE_STR11, - mMsg_FREE_STR12, - mMsg_FREE_STR13, - mMsg_FREE_STR14, - mMsg_FREE_STR15, - mMsg_FREE_STR16, - mMsg_FREE_STR17, - mMsg_FREE_STR18, - mMsg_FREE_STR19, + mMsg_FREE_STR0, + mMsg_FREE_STR1, + mMsg_FREE_STR2, + mMsg_FREE_STR3, + mMsg_FREE_STR4, + mMsg_FREE_STR5, + mMsg_FREE_STR6, + mMsg_FREE_STR7, + mMsg_FREE_STR8, + mMsg_FREE_STR9, + mMsg_FREE_STR10, + mMsg_FREE_STR11, + mMsg_FREE_STR12, + mMsg_FREE_STR13, + mMsg_FREE_STR14, + mMsg_FREE_STR15, + mMsg_FREE_STR16, + mMsg_FREE_STR17, + mMsg_FREE_STR18, + mMsg_FREE_STR19, - mMsg_FREE_STR_NUM + mMsg_FREE_STR_NUM }; enum { - mMsg_ITEM_STR0, - mMsg_ITEM_STR1, - mMsg_ITEM_STR2, - mMsg_ITEM_STR3, - mMsg_ITEM_STR4, + mMsg_ITEM_STR0, + mMsg_ITEM_STR1, + mMsg_ITEM_STR2, + mMsg_ITEM_STR3, + mMsg_ITEM_STR4, - mMsg_ITEM_STR_NUM + mMsg_ITEM_STR_NUM }; enum { - mMsg_MAIL_STR0, + mMsg_MAIL_STR0, - mMsg_MAIL_STR_NUM + mMsg_MAIL_STR_NUM }; enum { - mMsg_RESULT_VOID, - mMsg_RESULT_FALSE, - mMsg_RESULT_TRUE, + mMsg_RESULT_VOID, + mMsg_RESULT_FALSE, + mMsg_RESULT_TRUE, - mMsg_RESULT_NUM + mMsg_RESULT_NUM }; -#define mMsg_STATUS_FLAG_SOUND_CUT (1 << 0) // 0x000001 +#define mMsg_STATUS_FLAG_SOUND_CUT (1 << 0) // 0x000001 #define mMsg_STATUS_FLAG_NO_SE_PAGE_OKURI (1 << 1) // 0x000002 -#define mMsg_STATUS_FLAG_NO_ZOOMUP (1 << 2) // 0x000004 -#define mMsg_STATUS_FLAG_LAST_DELAY (1 << 3) // 0x000008 -#define mMsg_STATUS_FLAG_SPEC_VOICE (1 << 4) // 0x000010 -#define mMsg_STATUS_FLAG_VOICE_ENTRY (1 << 5) // 0x000020 -#define mMsg_STATUS_FLAG_IDLING_REQ (1 << 6) // 0x000040 -#define mMsg_STATUS_FLAG_IDLING_NOW (1 << 7) // 0x000080 -#define mMsg_STATUS_FLAG_FAST_TEXT (1 << 8) // 0x000100 -#define mMsg_STATUS_FLAG_NOT_PAUSE_FRAME (1 << 9) // 0x000200 -#define mMsg_STATUS_FLAG_UTTER (1 << 10) // 0x000400 -#define mMsg_STATUS_FLAG_NO_ZOOMDOWN (1 << 11) /* When set, mMsg_sound_ZOOMDOWN_[SHORT, LONG]() sfx will not play */ -#define mMsg_STATUS_FLAG_VOICE_CLICK (1 << 12) // 0x001000 -#define mMsg_STATUS_FLAG_VOICE_SILENT (1 << 13) // 0x002000 -#define mMsg_STATUS_FLAG_CURSOL_JUST (1 << 14) /* Sets cursor justification */ -#define mMsg_STATUS_FLAG_CUT_ARTICLE (1 << 15) // 0x008000 -#define mMsg_STATUS_FLAG_CAPITALIZE (1 << 16) // 0x010000 -#define mMsg_STATUS_FLAG_USE_AM (1 << 17) /* 'AM' when set, 'PM' when not set */ -#define mMsg_STATUS_FLAG_18 (1 << 18) // 0x040000 +#define mMsg_STATUS_FLAG_NO_ZOOMUP (1 << 2) // 0x000004 +#define mMsg_STATUS_FLAG_LAST_DELAY (1 << 3) // 0x000008 +#define mMsg_STATUS_FLAG_SPEC_VOICE (1 << 4) // 0x000010 +#define mMsg_STATUS_FLAG_VOICE_ENTRY (1 << 5) // 0x000020 +#define mMsg_STATUS_FLAG_IDLING_REQ (1 << 6) // 0x000040 +#define mMsg_STATUS_FLAG_IDLING_NOW (1 << 7) // 0x000080 +#define mMsg_STATUS_FLAG_FAST_TEXT (1 << 8) // 0x000100 +#define mMsg_STATUS_FLAG_NOT_PAUSE_FRAME (1 << 9) // 0x000200 +#define mMsg_STATUS_FLAG_UTTER (1 << 10) // 0x000400 +#define mMsg_STATUS_FLAG_NO_ZOOMDOWN (1 << 11) /* When set, mMsg_sound_ZOOMDOWN_[SHORT, LONG]() sfx will not play */ +#define mMsg_STATUS_FLAG_VOICE_CLICK (1 << 12) // 0x001000 +#define mMsg_STATUS_FLAG_VOICE_SILENT (1 << 13) // 0x002000 +#define mMsg_STATUS_FLAG_CURSOL_JUST (1 << 14) /* Sets cursor justification */ +#define mMsg_STATUS_FLAG_CUT_ARTICLE (1 << 15) // 0x008000 +#define mMsg_STATUS_FLAG_CAPITALIZE (1 << 16) // 0x010000 +#define mMsg_STATUS_FLAG_USE_AM (1 << 17) /* 'AM' when set, 'PM' when not set */ +#define mMsg_STATUS_FLAG_18 (1 << 18) // 0x040000 typedef struct message_window_s mMsg_Window_c; typedef struct message_data_s mMsg_Data_c; @@ -108,160 +108,160 @@ typedef struct message_data_s mMsg_Data_c; /* These are hinted at due to the 8-byte alignment forced onto these structs */ typedef struct { - int saved_main_index; + int saved_main_index; } mMsg_MainAppearWait_Data_c; typedef struct { - int saved_main_index; + int saved_main_index; } mMsg_MainDisappearWait_Data_c; typedef struct { - int last_main_index; + int last_main_index; } mMsg_MainWait_Data_c; typedef union { - mMsg_MainAppearWait_Data_c main_appear_wait; - mMsg_MainDisappearWait_Data_c main_disappear_wait; - mMsg_MainWait_Data_c main_wait; - u64 align; + mMsg_MainAppearWait_Data_c main_appear_wait; + mMsg_MainDisappearWait_Data_c main_disappear_wait; + mMsg_MainWait_Data_c main_wait; + u64 align; } mMsg_Main_Data_c; typedef struct { - ACTOR* speaker_actor; - int msg_no; - int name_shown_flag; - rgba_t window_color; + ACTOR* speaker_actor; + int msg_no; + int name_shown_flag; + rgba_t window_color; } mMsg_Request_MainAppear_Data_c; typedef struct { - int last_main_index; - u32 setup_flag; + int last_main_index; + u32 setup_flag; } mMsg_Request_MainAppearWait_Data_c; typedef struct { - int wait_flag; + int wait_flag; } mMsg_Request_MainCursor_Data_c; typedef struct { - int last_main_index; + int last_main_index; } mMsg_Request_MainDisappearWait_Data_c; typedef struct { - int wait_flag; + int wait_flag; } mMsg_Request_MainNormal_Data_c; typedef struct { - int last_main_index; + int last_main_index; } mMsg_Request_MainWait_Data_c; typedef union { - mMsg_Request_MainAppear_Data_c request_main_appear; - mMsg_Request_MainAppearWait_Data_c request_main_appear_wait; - mMsg_Request_MainCursor_Data_c request_main_cursor; - mMsg_Request_MainDisappearWait_Data_c request_main_disappear_wait; - mMsg_Request_MainNormal_Data_c request_main_normal; - mMsg_Request_MainWait_Data_c request_main_wait; - u64 align; + mMsg_Request_MainAppear_Data_c request_main_appear; + mMsg_Request_MainAppearWait_Data_c request_main_appear_wait; + mMsg_Request_MainCursor_Data_c request_main_cursor; + mMsg_Request_MainDisappearWait_Data_c request_main_disappear_wait; + mMsg_Request_MainNormal_Data_c request_main_normal; + mMsg_Request_MainWait_Data_c request_main_wait; + u64 align; } mMsg_Request_Data_c; typedef union { - u8 data[mMsg_MSG_BUF_SIZE] ATTRIBUTE_ALIGN(32); - u64 align; + u8 data[mMsg_MSG_BUF_SIZE] ATTRIBUTE_ALIGN(32); + u64 align; } mMsg_MsgBuf_c; struct message_data_s { - int data_loaded; - int msg_no; - int msg_len; - int cut; + int data_loaded; + int msg_no; + int msg_len; + int cut; - mMsg_MsgBuf_c text_buf; + mMsg_MsgBuf_c text_buf; }; struct message_window_s { - /* 0x000 */ int data_loaded; - /* 0x004 */ int msg_no; - /* 0x008 */ int _008; - /* 0x00C */ mMsg_Data_c* msg_data; - /* 0x010 */ f32 center_x; - /* 0x014 */ f32 center_y; - /* 0x018 */ f32 width; - /* 0x01C */ f32 height; - - /* 0x020 */ ACTOR* client_actor_p; - /* 0x024 */ int show_actor_name; - /* 0x028 */ int client_name_len; - /* 0x02C */ f32 nameplate_x; - /* 0x030 */ f32 nameplate_y; + /* 0x000 */ int data_loaded; + /* 0x004 */ int msg_no; + /* 0x008 */ int _008; + /* 0x00C */ mMsg_Data_c* msg_data; + /* 0x010 */ f32 center_x; + /* 0x014 */ f32 center_y; + /* 0x018 */ f32 width; + /* 0x01C */ f32 height; - /* 0x034 */ int show_continue_button; + /* 0x020 */ ACTOR* client_actor_p; + /* 0x024 */ int show_actor_name; + /* 0x028 */ int client_name_len; + /* 0x02C */ f32 nameplate_x; + /* 0x030 */ f32 nameplate_y; - /* 0x038 */ u8 free_str[mMsg_FREE_STR_NUM][mMsg_FREE_STRING_LEN]; - /* 0x178 */ int free_str_article[mMsg_FREE_STR_NUM]; + /* 0x034 */ int show_continue_button; - /* 0x1C8 */ u8 item_str[mMsg_ITEM_STR_NUM][mIN_ITEM_NAME_LEN]; - /* 0x218 */ int item_str_article[mMsg_ITEM_STR_NUM]; + /* 0x038 */ u8 free_str[mMsg_FREE_STR_NUM][mMsg_FREE_STRING_LEN]; + /* 0x178 */ int free_str_article[mMsg_FREE_STR_NUM]; - /* 0x22C */ u8 mail_str[mMsg_MAIL_STR_NUM][mMsg_MAIL_STRING_LEN]; + /* 0x1C8 */ u8 item_str[mMsg_ITEM_STR_NUM][mIN_ITEM_NAME_LEN]; + /* 0x218 */ int item_str_article[mMsg_ITEM_STR_NUM]; - /* 0x2B0 */ rgba_t name_text_color; - /* 0x2B4 */ rgba_t name_background_color; + /* 0x22C */ u8 mail_str[mMsg_MAIL_STR_NUM][mMsg_MAIL_STRING_LEN]; - /* 0x2B8 */ rgba_t window_background_color; - /* 0x2BC */ rgba_t font_color[mMsg_MAX_LINE]; + /* 0x2B0 */ rgba_t name_text_color; + /* 0x2B4 */ rgba_t name_background_color; - /* 0x2CC */ rgba_t continue_button_color; + /* 0x2B8 */ rgba_t window_background_color; + /* 0x2BC */ rgba_t font_color[mMsg_MAX_LINE]; - /* 0x2D0 */ f32 font_scale_x; - /* 0x2D4 */ f32 font_scale_y; + /* 0x2CC */ rgba_t continue_button_color; - /* 0x2D8 */ int _2D8; - /* 0x2DC */ int _2DC; + /* 0x2D0 */ f32 font_scale_x; + /* 0x2D4 */ f32 font_scale_y; - /* 0x2E0 */ int text_lines; - /* 0x2E4 */ int now_display_line; + /* 0x2D8 */ int _2D8; + /* 0x2DC */ int _2DC; - /* 0x2E8 */ mChoice_c choice_window; + /* 0x2E0 */ int text_lines; + /* 0x2E4 */ int now_display_line; - /* 0x3E8 */ int _3E8; + /* 0x2E8 */ mChoice_c choice_window; - /* 0x3EC */ u16 end_timer; - /* 0x3EE */ s16 animal_voice_idx; - /* 0x3F0 */ int voice_sfx_idx; - /* 0x3F4 */ u8 voice_idx; - /* 0x3F5 */ u8 voice2_idx; - /* 0x3F6 */ u8 voice3_idx; - /* 0x3F7 */ s8 hide_choice_window_timer; - /* 0x3F8 */ u8 force_voice_enable_flag; - /* 0x3FC */ int spec; - /* 0x400 */ u8 free_str_color_idx[4]; - /* 0x408 */ u8 _404[8]; // unused? - /* 0x40C */ u32 status_flags; + /* 0x3E8 */ int _3E8; - /* 0x410 */ f32 timer; - /* 0x414 */ f32 cursor_timer; - /* 0x418 */ f32 continue_button_timer; + /* 0x3EC */ u16 end_timer; + /* 0x3EE */ s16 animal_voice_idx; + /* 0x3F0 */ int voice_sfx_idx; + /* 0x3F4 */ u8 voice_idx; + /* 0x3F5 */ u8 voice2_idx; + /* 0x3F6 */ u8 voice3_idx; + /* 0x3F7 */ s8 hide_choice_window_timer; + /* 0x3F8 */ u8 force_voice_enable_flag; + /* 0x3FC */ int spec; + /* 0x400 */ u8 free_str_color_idx[4]; + /* 0x408 */ u8 _404[8]; // unused? + /* 0x40C */ u32 status_flags; - /* 0x41C */ int start_text_cursor_idx; - /* 0x420 */ int end_text_cursor_idx; - /* 0x424 */ f32 window_scale; - /* 0x428 */ f32 text_scale; + /* 0x410 */ f32 timer; + /* 0x414 */ f32 cursor_timer; + /* 0x418 */ f32 continue_button_timer; - /* 0x42C */ int requested_main_index; - /* 0x430 */ int requested_priority; + /* 0x41C */ int start_text_cursor_idx; + /* 0x420 */ int end_text_cursor_idx; + /* 0x424 */ f32 window_scale; + /* 0x428 */ f32 text_scale; - /* 0x434 */ int main_index; - /* 0x438 */ int draw_flag; - /* 0x43C */ int cancel_flag; - /* 0x440 */ int cancelable_flag; - /* 0x444 */ int continue_msg_no; - /* 0x448 */ int continue_cancel_flag; - /* 0x44C */ int force_next; - /* 0x450 */ int lock_continue; - /* 0x454 */ u8 now_utter; + /* 0x42C */ int requested_main_index; + /* 0x430 */ int requested_priority; - /* 0x458 */ mMsg_Main_Data_c main_data; - /* 0x460 */ mMsg_Request_Data_c request_data; + /* 0x434 */ int main_index; + /* 0x438 */ int draw_flag; + /* 0x43C */ int cancel_flag; + /* 0x440 */ int cancelable_flag; + /* 0x444 */ int continue_msg_no; + /* 0x448 */ int continue_cancel_flag; + /* 0x44C */ int force_next; + /* 0x450 */ int lock_continue; + /* 0x454 */ u8 now_utter; + + /* 0x458 */ mMsg_Main_Data_c main_data; + /* 0x460 */ mMsg_Request_Data_c request_data; }; extern void mMsg_aram_init(); @@ -279,7 +279,8 @@ extern int mMsg_Check_not_series_main_wait(mMsg_Window_c* msg_p); extern int mMsg_Check_main_hide(mMsg_Window_c* msg_p); extern int mMsg_request_main_forceoff(); extern int mMsg_request_main_disappear(mMsg_Window_c* msg_p); -extern int mMsg_request_main_appear(mMsg_Window_c* msg_p, ACTOR* client_actor_p, int show_name, rgba_t* window_color, int msg_no, int request_priority); +extern int mMsg_request_main_appear(mMsg_Window_c* msg_p, ACTOR* client_actor_p, int show_name, rgba_t* window_color, + int msg_no, int request_priority); extern int mMsg_request_main_disappear_wait_type1(mMsg_Window_c* msg_p); extern int mMsg_request_main_disappear_wait_type2(mMsg_Window_c* msg_p); extern int mMsg_request_main_appear_wait_type2(mMsg_Window_c* msg_p, int clear_flag); @@ -323,13 +324,15 @@ extern int mMsg_CopyDay(u8* data, int start_idx, int len); extern int mMsg_CopyHour(u8* data, int start_idx, int len); extern int mMsg_CopyMin(u8* data, int start_idx, int len); extern int mMsg_CopySec(u8* data, int start_idx, int len); -extern int mMsg_CopyFree(mMsg_Window_c* msg_p, int str_no, u8* data, int start_idx, int len, int article, u32 capitalize); +extern int mMsg_CopyFree(mMsg_Window_c* msg_p, int str_no, u8* data, int start_idx, int len, int article, + u32 capitalize); extern int mMsg_CopyDetermination(mMsg_Window_c* msg_p, u8* data, int start_idx, int len); -extern int mMsg_CopyCountryName(u8 *data, int start_idx, int len, u32 capitalize); +extern int mMsg_CopyCountryName(u8* data, int start_idx, int len, u32 capitalize); extern int mMsg_CopyIslandName(u8* data, int start_idx, int len, u32 capitalize); extern int mMsg_CopyAmPm(mMsg_Window_c* msg_p, u8* data, int start_idx, int len); extern int mMsg_CopyRamdomNumber2(u8* data, int start_idx, int len); -extern int mMsg_CopyItem(mMsg_Window_c* msg_p, int str_no, u8* data, int start_idx, int len, int article, u32 capitalize); +extern int mMsg_CopyItem(mMsg_Window_c* msg_p, int str_no, u8* data, int start_idx, int len, int article, + u32 capitalize); extern int mMsg_CopyMail(mMsg_Window_c* msg_p, int str_no, u8* data, int start_idx, int len, u32 capitalize); extern int mMsg_sound_voice_get(int code); extern int mMsg_sound_voice_get_for_editor(int code); @@ -339,6 +342,29 @@ extern void mMsg_sound_set_voice_click(mMsg_Window_c* msg_p); extern void mMsg_sound_set_voice_silent(mMsg_Window_c* msg_p, int update_mode); extern void mMsg_sound_unset_voice_silent(mMsg_Window_c* msg_p, int update_mode); +/* Macros */ + +#define mMsg_SET_CONTINUE_MSG_NUM(msg_no) mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), (msg_no)) +#define mMsg_SET_LOCKCONTINUE() mMsg_Set_LockContinue(mMsg_Get_base_window_p()) +#define mMsg_UNSET_LOCKCONTINUE() mMsg_Unset_LockContinue(mMsg_Get_base_window_p()) +#define mMsg_SET_FORCENEXT() mMsg_Set_ForceNext(mMsg_Get_base_window_p()) +#define mMsg_SET_CANCELNORMALCONTINUE() mMsg_Set_CancelNormalContinue(mMsg_Get_base_window_p()) +#define mMsg_SET_ITEM_STR_ART(str_no, str, str_len, item_no) \ + mMsg_Set_item_str_art(mMsg_Get_base_window_p(), str_no, str, str_len, mIN_get_item_article(item_no)) +#define mMsg_SET_FREE_STR(str_no, str, str_len) mMsg_Set_free_str(mMsg_Get_base_window_p(), str_no, str, str_len) +#define mMsg_SET_FREE_STR_CL(str_no, str, str_len, cl) \ + mMsg_Set_free_str_cl(mMsg_Get_base_window_p(), str_no, str, str_len, cl) +#define mMsg_SET_FREE_STR_CL_ART(str_no, str, str_len, cl, item_no) \ + mMsg_Set_free_str_cl_art(mMsg_Get_base_window_p(), str_no, str, str_len, cl, mIN_get_item_article(item_no)) + +#define mMsg_GET_MSG_NUM() mMsg_Get_msg_num(mMsg_Get_base_window_p()) + +#define mMsg_CHECK_MAINNORMALCONTINUE() mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p()) +#define mMsg_CHECK_MAINDISAPPEAR() mMsg_Check_MainDisappear(mMsg_Get_base_window_p()) +#define mMsg_CHECK_MAINHIDE() mMsg_Check_MainHide(mMsg_Get_base_window_p()) + +#define mMsg_REQUEST_MAIN_DISAPPEAR() mMsg_request_main_disappear(mMsg_Get_base_window_p()) + #ifdef __cplusplus } #endif diff --git a/include/m_player_lib.h b/include/m_player_lib.h index c2ae63ce..60d05841 100644 --- a/include/m_player_lib.h +++ b/include/m_player_lib.h @@ -17,7 +17,7 @@ extern void mPlib_Clear_controller_data_for_title_demo(); extern void mPlib_request_main_invade_type1(GAME_PLAY* play); extern mActor_name_t mPlib_Get_itemNo_forWindow(); extern int mPlib_check_able_change_camera_normal_index(); -extern void mPlib_request_main_refuse_type1(GAME_PLAY* play); +extern void mPlib_request_main_refuse_type1(GAME* game); extern void mPlib_request_main_wait_type3(GAME* game); extern void mPlib_Set_able_force_speak_label(ACTOR* actor); extern int mPlib_request_main_demo_walk_type1(GAME* game, f32 goal_x, f32 goal_z, f32 speed, int flag); @@ -63,6 +63,7 @@ extern void mPlib_Set_change_color_request(); extern int mPlib_check_player_open_umbrella(GAME_PLAY* play); extern int mPlib_Check_UKI_COMEBACK_STATUS(); extern int mPlib_check_player_actor_main_index_OutDoorMove(GAME_PLAY* play); +extern int mPlib_request_main_close_furniture_type1(GAME* game); extern mPlayer_change_data_from_submenu_c* mPlib_Get_change_data_from_submenu_p(); diff --git a/include/m_scene.h b/include/m_scene.h index 017aa6af..5d2a41c1 100644 --- a/include/m_scene.h +++ b/include/m_scene.h @@ -212,7 +212,7 @@ extern void Scene_ct(GAME_PLAY* play, Scene_Word_u* scene_data); extern void Door_info_ct(Door_info_c* door_info); extern int goto_other_scene(GAME_PLAY* play, Door_data_c* door_data, int update_player_mode); extern int goto_next_scene(GAME_PLAY* play, int next_idx, int update_player_mode); -extern int goto_emu_game(GAME_PLAY* play, u8 famicom_rom_id); +extern int goto_emu_game(GAME* game, s16 famicom_rom_id); extern void return_emu_game(GAME* game); #ifdef __cplusplus diff --git a/src/ac_airplane.c b/src/ac_airplane.c index c9d8f5e3..c58a37d9 100644 --- a/src/ac_airplane.c +++ b/src/ac_airplane.c @@ -334,15 +334,13 @@ static void aAp_CommonHandle(ACTOR* actor, AIRPLANE_ACTOR* airplane, GAME* game) } static void aAp_ZbuttonChangeStatus(AIRPLANE_ACTOR* actor, GAME* game) { - GAME_PLAY* play = (GAME_PLAY*)game; - if (chkButton(BUTTON_Z)) { if (actor->status == aAp_STATUS_PLAYER_CATCH) { - mPlib_request_main_refuse_type1(play); + mPlib_request_main_refuse_type1(game); actor->status = aAp_STATUS_START_FLY_MOVE; } } else if (actor->status == aAp_STATUS_START_FLY_MOVE) { - mPlib_request_main_wait_type3((GAME*)play); + mPlib_request_main_wait_type3(game); actor->status = aAp_STATUS_PLAYER_CATCH; } } diff --git a/src/ac_my_room.c b/src/ac_my_room.c index 36304007..681c9cf2 100644 --- a/src/ac_my_room.c +++ b/src/ac_my_room.c @@ -10,6 +10,10 @@ #include "m_cockroach.h" #include "m_msg.h" #include "dolphin/card.h" +#include "m_string.h" +#include "m_house.h" +#include "m_player_lib.h" +#include "GBA2/gba2.h" enum { aMR_ICON_LEAF, @@ -123,6 +127,10 @@ static int aMR_UnitNum2FtrItemNoFtrID(mActor_name_t* item_no, int* ftr_id, int u static void aMR_ReserveDefaultBgm(ACTOR* actorx, FTR_ACTOR* ftr_actor); static void aMR_ChangeMDBgm(ACTOR* actorx, FTR_ACTOR* ftr_actor); static void aMR_SetFurniture2FG(FTR_ACTOR* ftr_actor, xyz_t pos, int on_flag); +static int aMR_FtrIdx2ChangeFtrSwitch(ACTOR* actorx, int ftr_id); +static aFTR_PROFILE* aMR_GetFurnitureProfile(u16 ftr_no); + +#include "../src/ac_my_room_msg_ctrl.c_inc" static aFTR_PROFILE* aMR_GetFurnitureProfile(u16 ftr_no) { if (ftr_no < FTR_NUM) { diff --git a/src/ac_my_room_msg_ctrl.c_inc b/src/ac_my_room_msg_ctrl.c_inc new file mode 100644 index 00000000..cc04018f --- /dev/null +++ b/src/ac_my_room_msg_ctrl.c_inc @@ -0,0 +1,2039 @@ +static void aMR_SetSlotString(void) { + u8 str[mMsg_FREE_STRING_LEN]; + int slot = famicom_getErrorChan(); + + mString_Load_StringFromRom(str, mMsg_FREE_STRING_LEN, 0x6CD + (slot & 1)); + mMsg_Set_free_str(mMsg_Get_base_window_p(), mMsg_FREE_STR4, str, mMsg_FREE_STRING_LEN); +} + +static int aMR_GetCardFamicomCount(void) { + int count = 0; + + if (famicom_get_disksystem_titles(&count, NULL, 0) != FALSE) { + return count; + } + + return 0; +} + +static u8* aMR_GetNameString(MY_ROOM_ACTOR* my_room, int rom_no) { + static u8 dummy[FAMICOM_MORI_NAME_LEN] = { 'n', 'o', ' ', 'g', 'a', 'm', 'e', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }; + + if (my_room->emu_info.famicom_names_p != NULL && rom_no < my_room->emu_info.card_famicom_count) { + return (u8*)my_room->emu_info.famicom_names_p + rom_no * FAMICOM_MORI_NAME_LEN; + } + + return dummy; +} + +static void aMR_SetMemoryCardGameIndex(MY_ROOM_ACTOR* my_room, int sub_index) { + my_room->emu_info.rom_no = -(my_room->emu_info.memory_game_select + sub_index); +} + +static void aMR_ReportDisplayMemoryGameSelectCount(MY_ROOM_ACTOR* my_room, int add_amount) { + my_room->emu_info.memory_game_select += add_amount; + + if (my_room->emu_info.memory_game_select >= my_room->emu_info.card_famicom_count) { + my_room->emu_info.memory_game_select = 0; + } +} + +static FTR_ACTOR* aMR_GetNowDemoFtr(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + return l_aMR_work.ftr_actor_list + my_room->demo_ftrID; +} + +static void aMR_ChangeDemoFtrStatus(ACTOR* actorx, s16 status) { + FTR_ACTOR* ftr_actor = aMR_GetNowDemoFtr(actorx); + + ftr_actor->demo_status = status; +} + +static int aMR_GetMusicCountInMusicBox(void) { + int i; + int count = 0; + + for (i = 0; i < MINIDISK_NUM; i++) { + u32* music_box = Save_Get(scene_no) == SCENE_COTTAGE_MY + ? Save_Get(island).cottage.music_box + : Save_Get(homes[mHS_get_arrange_idx(Common_Get(player_no))]).music_box; + + if (((music_box[(i / 32) & 1] >> (i & 31)) & 1) == 1) { + count++; + } + } + + return count; +} + +static void aMR_MemoryMusicBoxStatus(MY_ROOM_ACTOR* my_room) { + u32* music_box = Save_Get(scene_no) == SCENE_COTTAGE_MY + ? Save_Get(island).cottage.music_box + : Save_Get(homes[mHS_get_arrange_idx(Common_Get(player_no))]).music_box; + int i; + + for (i = 0; i < 2; i++) { + my_room->music_box[i] = music_box[i]; + } +} + +static void aMR_SetEmulatorMessage_CanSave(ACTOR* actorx) { + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x17B5); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + mMsg_Set_ForceNext(mMsg_Get_base_window_p()); +} + +static void aMR_SetEmulatorStartMessage(ACTOR* actorx, int internal_rom) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int res; + + Common_Get(my_room_message_control_flags) |= (1 << 2); + + if (internal_rom == TRUE) { + res = famicom_internal_data_load(); + } else { + if (Common_Get(player_no) < PLAYER_NUM) { + aMR_SetEmulatorMessage_CanSave(actorx); + aMR_SetSlotString(); + return; + } + + res = famicom_external_data_save_check(); + } + + aMR_SetSlotString(); + + switch (res) { + case FAMICOM_RESULT_OK: + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR; + aMR_SetEmulatorMessage_CanSave(actorx); + break; + case FAMICOM_RESULT_NOSPACE: + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x3B50); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + mMsg_Set_ForceNext(mMsg_Get_base_window_p()); + break; + case FAMICOM_RESULT_NOENTRY: + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x3B51); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + mMsg_Set_ForceNext(mMsg_Get_base_window_p()); + break; + case FAMICOM_RESULT_BROKEN: + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x3B52); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + mMsg_Set_ForceNext(mMsg_Get_base_window_p()); + break; + case FAMICOM_RESULT_WRONGDEVICE: + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x3B53); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + mMsg_Set_ForceNext(mMsg_Get_base_window_p()); + break; + case FAMICOM_RESULT_WRONGENCODING: + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x3B54); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + mMsg_Set_ForceNext(mMsg_Get_base_window_p()); + break; + case FAMICOM_RESULT_NOCARD: + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR; + mMsg_Set_free_str(mMsg_Get_base_window_p(), mMsg_FREE_STR0, Save_Get(land_info).name, LAND_NAME_SIZE); + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x3B55); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + mMsg_Set_ForceNext(mMsg_Get_base_window_p()); + break; + case FAMICOM_RESULT_NOFILE: + default: + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x3071); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + mMsg_Set_ForceNext(mMsg_Get_base_window_p()); + my_room->requested_msg_type = aMR_MSG_STATE_WAIT_FAMICOM_BATU; + Common_Get(my_room_message_control_flags) &= ~4; + break; + } +} + +static void aMR_NoMsgInit(ACTOR* actorx) { + // nothing +} + +static void aMR_NoMsgControl(ACTOR* actorx, GAME* game) { + // nothing +} + +static void aMR_MsgControlOwnerNoItem(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice = mChoice_Get_ChoseNum(mChoice_Get_base_window_p()); + + if (choice != -1) { + switch (choice) { + case mChoice_CHOICE0: { + if (mSM_check_open_inventory_itemlist(mSM_IV_OPEN_PUTIN_FTR, 0) == FALSE) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x0A10); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OPEN_SUBMENU; + mMsg_Set_CancelNormalContinue(mMsg_Get_base_window_p()); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } + + break; + } + + default: { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mMsg_Set_CancelNormalContinue(mMsg_Get_base_window_p()); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + break; + } + } + } +} + +static void aMR_MsgInitOwnerWhichPutOut(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + static u8 item_name1[mIN_ITEM_NAME_LEN]; + static u8 item_name2[mIN_ITEM_NAME_LEN]; + static u8 item_name3[mIN_ITEM_NAME_LEN]; + static u8* item_name_table[] = { item_name1, item_name2, item_name3 }; + u8 cancel_str[mChoice_CHOICE_STRING_LEN]; + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list + my_room->demo_ftrID; + mChoice_c* choice_win = mChoice_Get_base_window_p(); + int count; + int i; + + aMR_TidyItemInFurniture(ftr_actor); + count = aMR_GetItemCountInFurniture(ftr_actor); + mChoice_Clear_ChoseNum(choice_win); + + for (i = 0; i < count; i++) { + if (ftr_actor->items[i] != EMPTY_NO) { + mIN_copy_name_str(item_name_table[i], ftr_actor->items[i]); + } + } + + if (my_room->msg_type == aMR_MSG_STATE_OWNER_WHICH_PUT_OUT1) { + for (i = 0; i < aFTR_KEEP_ITEM_COUNT; i++) { + if (ftr_actor->items[i] != EMPTY_NO) { + mMsg_Set_item_str_art(mMsg_Get_base_window_p(), i, item_name_table[i], mIN_ITEM_NAME_LEN, + mIN_get_item_article(ftr_actor->items[i])); + } + } + } + + mChoice_Load_ChoseStringFromRom(choice_win, cancel_str, 0x29, NULL); + if (count == 1) { + mChoice_Set_choice_data(choice_win, item_name_table[0], mIN_ITEM_NAME_LEN, cancel_str, + mChoice_CHOICE_STRING_LEN, NULL, mIN_ITEM_NAME_LEN, NULL, mIN_ITEM_NAME_LEN, NULL, + mIN_ITEM_NAME_LEN, NULL, mIN_ITEM_NAME_LEN); + } else if (count == 2) { + mChoice_Set_choice_data(choice_win, item_name_table[0], mIN_ITEM_NAME_LEN, item_name_table[1], + mIN_ITEM_NAME_LEN, cancel_str, mChoice_CHOICE_STRING_LEN, NULL, mIN_ITEM_NAME_LEN, NULL, + mIN_ITEM_NAME_LEN, NULL, mIN_ITEM_NAME_LEN); + } else if (count == 3) { + mChoice_Set_choice_data(choice_win, item_name_table[0], mIN_ITEM_NAME_LEN, item_name_table[1], + mIN_ITEM_NAME_LEN, item_name_table[2], mIN_ITEM_NAME_LEN, cancel_str, + mChoice_CHOICE_STRING_LEN, NULL, mIN_ITEM_NAME_LEN, NULL, mIN_ITEM_NAME_LEN); + } +} + +static void aMR_MsgControlOwnerWhichPutOut(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice_no = mChoice_Get_ChoseNum(mChoice_Get_base_window_p()); + + mChoice_Clear_ChoseNum(mChoice_Get_base_window_p()); + if (choice_no != -1) { + FTR_ACTOR* ftr_actor = aMR_GetNowDemoFtr(actorx); + + if (choice_no < aMR_GetItemCountInFurniture(ftr_actor)) { + int idx = mPr_GetPossessionItemIdxWithCond(Common_Get(now_private), EMPTY_NO, mPr_ITEM_COND_NORMAL); + + if (idx != -1) { + mActor_name_t item = ftr_actor->items[choice_no]; + + ftr_actor->items[choice_no] = EMPTY_NO; + aMR_TidyItemInFurniture(ftr_actor); + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mPr_SetPossessionItem(Common_Get(now_private), idx, item, mPr_ITEM_COND_NORMAL); + mMsg_Set_CancelNormalContinue(mMsg_Get_base_window_p()); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } else { + /* Full pockets */ + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x0A0E); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } + } else { + /* Cancelled */ + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mMsg_Set_CancelNormalContinue(mMsg_Get_base_window_p()); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } + } +} + +static void aMR_MsgInitOwnerWaitWhichPutOut(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_Check_MainNormalContinue(mMsg_Get_base_window_p())) { + my_room->requested_msg_type = aMR_MSG_STATE_OWNER_WHICH_PUT_OUT3; + mChoice_no_b_close_set(mChoice_Get_base_window_p()); + } +} + +static void aMR_MsgControlOwnerWaitWhichPutOut(ACTOR* actorx, GAME* game) { + aMR_MsgInitOwnerWaitWhichPutOut(actorx); +} + +static void aMR_MsgInitOwnerExistItem(ACTOR* actorx) { + u8 item_str[mIN_ITEM_NAME_LEN]; + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int demo_ftrID = my_room->demo_ftrID; + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[demo_ftrID]; + int i; + + for (i = 0; i < aFTR_KEEP_ITEM_COUNT; i++) { + if (ftr_actor->items[i] != EMPTY_NO) { + mIN_copy_name_str(item_str, ftr_actor->items[i]); + mMsg_Set_item_str_art(mMsg_Get_base_window_p(), i, item_str, mIN_ITEM_NAME_LEN, + mIN_get_item_article(ftr_actor->items[i])); + } + } +} + +static void aMR_MsgControlOwnerExistItem(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int idx = mPr_GetPossessionItemIdxWithCond(Common_Get(now_private), EMPTY_NO, mPr_ITEM_COND_NORMAL); + int choice_no = mChoice_Get_ChoseNum(mChoice_Get_base_window_p()); + + mChoice_Clear_ChoseNum(mChoice_Get_base_window_p()); + + if (choice_no != -1) { + if (choice_no == mChoice_CHOICE0) { + if (mSM_check_open_inventory_itemlist(mSM_IV_OPEN_PUTIN_FTR, 0) == FALSE) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x0A10); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OPEN_SET_ITEM_SUBMENU; + mMsg_Set_CancelNormalContinue(mMsg_Get_base_window_p()); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } + } else if (choice_no == mChoice_CHOICE1) { + FTR_ACTOR* ftr_actor = aMR_GetNowDemoFtr(actorx); + + if (idx != -1) { + mActor_name_t item = ftr_actor->items[0]; + + ftr_actor->items[0] = EMPTY_NO; + aMR_TidyItemInFurniture(ftr_actor); + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mPr_SetPossessionItem(Common_Get(now_private), idx, item, mPr_ITEM_COND_NORMAL); + mMsg_Set_CancelNormalContinue(mMsg_Get_base_window_p()); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } else { + /* Full pockets */ + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x0A0E); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } + } else { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mMsg_Set_CancelNormalContinue(mMsg_Get_base_window_p()); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } + } +} + +static void aMR_MsgControlOwnerExistItem_ItemCount2(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int idx = mPr_GetPossessionItemIdxWithCond(Common_Get(now_private), EMPTY_NO, mPr_ITEM_COND_NORMAL); + int choice_no = mChoice_Get_ChoseNum(mChoice_Get_base_window_p()); + + mChoice_Clear_ChoseNum(mChoice_Get_base_window_p()); + + if (choice_no != -1) { + if (choice_no == mChoice_CHOICE0) { + if (mSM_check_open_inventory_itemlist(mSM_IV_OPEN_PUTIN_FTR, 0) == FALSE) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x0A10); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OPEN_SET_ITEM_SUBMENU; + mMsg_Set_CancelNormalContinue(mMsg_Get_base_window_p()); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } + } else if (choice_no == mChoice_CHOICE1) { + if (idx != -1) { + my_room->requested_msg_type = aMR_MSG_STATE_OWNER_WAIT_WHICH_PUT_OUT; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x2F1E); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } else { + /* Full pockets */ + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x0A0E); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } + } else { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + mMsg_Set_CancelNormalContinue(mMsg_Get_base_window_p()); + mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); + } + } +} + +static void aMR_MsgControlOtherNoItem(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_Check_MainDisappear(mMsg_Get_base_window_p())) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + } +} + +static void aMR_MsgControlOtherExistItem(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_Check_MainDisappear(mMsg_Get_base_window_p())) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_FTR; + } +} + +static void aMR_MsgInitFullPlayerItem(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlFullPlayerItem(ACTOR* actorx, GAME* game) { + if (mDemo_Check(mDemo_TYPE_REPORT, actorx) == FALSE) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + } +} + +static void aMR_MsgControlOpenSubmenu(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + Submenu* submenu = &play->submenu; + + if (mDemo_CheckDemo() == FALSE) { + mSM_open_submenu(submenu, mSM_OVL_INVENTORY, mSM_IV_OPEN_PUTIN_FTR, 0); + mChoice_Clear_ChoseNum(mChoice_Get_base_window_p()); + my_room->requested_msg_type = aMR_MSG_STATE_ITEM_PUT_IN; + } +} + +static void aMR_MsgControlItemPutIn(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + Submenu* submenu = &play->submenu; + + if (submenu->process_status == mSM_PROCESS_WAIT) { + Submenu_Item_c* submenu_item = submenu->item_p; + + if (submenu_item != NULL && submenu_item->item != EMPTY_NO) { + FTR_ACTOR* ftr_actor = aMR_GetNowDemoFtr(actorx); + + aMR_ItemPutInFurniture(ftr_actor, submenu_item->item); + } + + if (mPlib_request_main_close_furniture_type1(game)) { + aMR_ChangeDemoFtrStatus(actorx, 5); + my_room->requested_msg_type = aMR_MSG_STATE_WAIT_CLOSE_FTR; + } + } +} + +static void aMR_MsgControlCanNotClean(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->requested_msg_type = aMR_MSG_STATE_NONE; +} + +static void aMR_MsgControlWaitCloseFtr(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (my_room->demo_flag == TRUE) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[my_room->demo_ftrID]; + + if (ftr_actor->demo_status == 0) { + my_room->demo_flag = FALSE; + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + } + } else { + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->demo_ftrID = 0; + } +} + +static void aMR_MsgInitRequestCloseFtr(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlRequestCloseFtr(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_CHECK_MAINDISAPPEAR() || mMsg_CHECK_MAINHIDE()) { + if (mPlib_request_main_close_furniture_type1(game)) { + aMR_ChangeDemoFtrStatus(actorx, 5); + my_room->requested_msg_type = aMR_MSG_STATE_WAIT_CLOSE_FTR; + } + } +} + +static void aMR_MsgControlOpenSetItemSubmenu(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + Submenu* submenu = &play->submenu; + + if (mDemo_CheckDemo() == FALSE) { + mSM_open_submenu(submenu, mSM_OVL_INVENTORY, mSM_IV_OPEN_PUTIN_FTR, 0); + mChoice_Clear_ChoseNum(mChoice_Get_base_window_p()); + my_room->requested_msg_type = aMR_MSG_STATE_ITEM_SET_SUBMENU; + } +} + +static void aMR_MsgControlItemSetSubmenu(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + Submenu* submenu = &play->submenu; + + if (submenu->process_status == mSM_PROCESS_WAIT) { + Submenu_Item_c* submenu_item = submenu->item_p; + + if (submenu_item != NULL && submenu_item->item != EMPTY_NO) { + FTR_ACTOR* ftr_actor = aMR_GetNowDemoFtr(actorx); + + aMR_ItemPutInFurniture(ftr_actor, submenu_item->item); + } + + if (mPlib_request_main_close_furniture_type1(game)) { + aMR_ChangeDemoFtrStatus(actorx, 5); + my_room->requested_msg_type = aMR_MSG_STATE_WAIT_CLOSE_FTR; + } + } +} + +static void aMR_MsgControlOwnerNoMD(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice_no = mChoice_Get_ChoseNum(mChoice_Get_base_window_p()); + + if (choice_no != -1) { + switch (choice_no) { + case mChoice_CHOICE0: { + if (mSM_check_open_inventory_itemlist(mSM_IV_OPEN_MINIDISK, 0) == FALSE) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_MD; + mMsg_SET_CONTINUE_MSG_NUM(0x10BD); + mMsg_UNSET_LOCKCONTINUE(); + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OPENMD_SUBMENU; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + } + break; + } + + case mChoice_CHOICE1: { + if (aMR_GetMusicCountInMusicBox() == 0) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_MD; + mMsg_SET_CONTINUE_MSG_NUM(0x2F28); + mMsg_UNSET_LOCKCONTINUE(); + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OPEN_MUSIC_BOX; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + } + + break; + } + + default: { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_MD; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + break; + } + } + } +} + +static void aMR_MsgInitOwnerExistMD(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int demo_ftrID = my_room->demo_ftrID; + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[demo_ftrID]; + mActor_name_t item = ftr_actor->items[0]; + u8 item_name[mIN_ITEM_NAME_LEN]; + + mIN_copy_name_str(item_name, item); + mMsg_SET_ITEM_STR_ART(mMsg_ITEM_STR0, item_name, mIN_ITEM_NAME_LEN, item); +} + +static void aMR_MsgControlOwnerExistMD(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice_no = mChoice_GET_CHOSENUM(); + + mChoice_CLEAR_CHOSENUM(); + if (choice_no != -1) { + if (choice_no == mChoice_CHOICE0) { + if (mSM_check_open_inventory_itemlist(mSM_IV_OPEN_MINIDISK, 0) == FALSE) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_MD; + mMsg_SET_CONTINUE_MSG_NUM(0x10BD); + mMsg_UNSET_LOCKCONTINUE(); + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OPENMD_SUBMENU; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + } + } else if (choice_no == mChoice_CHOICE1) { + if (aMR_GetMusicCountInMusicBox() == 0) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_MD; + mMsg_SET_CONTINUE_MSG_NUM(0x2F28); + mMsg_UNSET_LOCKCONTINUE(); + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OPEN_MUSIC_BOX; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + } + } else if (choice_no == mChoice_CHOICE2) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_MD; + aMR_FtrIdx2ChangeFtrSwitch(actorx, my_room->demo_ftrID); + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + } else { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_MD; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + } + } +} + +static void aMR_MsgControlOtherNoMD(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_Check_MainDisappear(mMsg_Get_base_window_p())) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_MD; + } +} + +static void aMR_MsgControlOtherExistMD(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_Check_MainDisappear(mMsg_Get_base_window_p())) { + my_room->requested_msg_type = aMR_MSG_STATE_REQUEST_CLOSE_MD; + aMR_FtrIdx2ChangeFtrSwitch(actorx, my_room->demo_ftrID); + } +} + +static void aMR_MsgControlFullPlayerMD(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->requested_msg_type = aMR_MSG_STATE_NONE; +} + +static void aMR_MsgControlOpenMusicBox(ACTOR* actorx, GAME* game) { + FTR_ACTOR* ftr_actor = aMR_GetNowDemoFtr(actorx); + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + Submenu* submenu = &play->submenu; + + if (mDemo_CheckDemo() == FALSE) { + int md_idx = (ftr_actor->items[0] >= ITM_MINIDISK_START && ftr_actor->items[0] < ITM_MINIDISK_END) + ? (mActor_name_t)(ftr_actor->items[0] - ITM_MINIDISK_START) + : -1; + + aMR_MemoryMusicBoxStatus(my_room); + mSM_open_submenu(submenu, mSM_OVL_MUSIC, md_idx, 0); + mChoice_CLEAR_CHOSENUM(); + my_room->requested_msg_type = aMR_MSG_STATE_MUSIC_BOX_MD_PUT_IN; + } +} + +static void aMR_DeleteDirectedMD(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK) && + (ftr_actor->items[0] >= ITM_MINIDISK_START && ftr_actor->items[0] < ITM_MINIDISK_END)) { + int md_idx = (mActor_name_t)(ftr_actor->items[0] - ITM_MINIDISK_START); + u32* music_box = Save_Get(scene_no) == SCENE_COTTAGE_MY + ? Save_Get(island).cottage.music_box + : Save_Get(homes[mHS_get_arrange_idx(Common_Get(player_no))]).music_box; + + if (((music_box[(md_idx / 32) & 1] >> (md_idx & 31)) & 1) == 0) { + if (ftr_actor->switch_bit == TRUE) { + aMR_AllMDSwitchOff(); + ftr_actor->items[0] = EMPTY_NO; + aMR_OneMDSwitchOn_TheOtherSwitchOff(ftr_actor); + aMR_ReserveDefaultBgm(actorx, ftr_actor); + aMR_ChangeMDBgm(actorx, ftr_actor); + sAdo_OngenTrgStart(0x17, &ftr_actor->position); + } else { + ftr_actor->items[0] = EMPTY_NO; + sAdo_OngenTrgStart(0x17, &ftr_actor->position); + } + + ftr_actor->switch_changed_flag = TRUE; + ftr_actor->switch_bit = FALSE; + } + } + } + + used++; + ftr_actor++; + } +} + +static void aMR_MsgControlMusicBoxMDPutIn(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + Submenu* submenu = &play->submenu; + + if (submenu->process_status == mSM_PROCESS_WAIT) { + FTR_ACTOR* ftr_actor = aMR_GetNowDemoFtr(actorx); + + if (submenu->item_p != NULL && submenu->item_p->item != EMPTY_NO) { + ftr_actor->items[0] = submenu->item_p->item; + aMR_OneMDSwitchOn_TheOtherSwitchOff(ftr_actor); + aMR_ReserveBgm(actorx, BGM_MD0 + (ftr_actor->items[0] - ITM_MINIDISK_START), ftr_actor, 0); + aMR_ChangeMDBgm(actorx, ftr_actor); + } else { + aMR_DeleteDirectedMD(actorx); + } + + aMR_ChangeDemoFtrStatus(actorx, 5); + my_room->requested_msg_type = aMR_MSG_STATE_WAIT_CLOSE_MD; + } +} + +static void aMR_MsgControlOpenMDSubmenu(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + Submenu* submenu = &play->submenu; + + if (mDemo_CheckDemo() == FALSE) { + aMR_MemoryMusicBoxStatus(my_room); + mSM_open_submenu(submenu, mSM_OVL_INVENTORY, mSM_IV_OPEN_MINIDISK, 0); + mChoice_CLEAR_CHOSENUM(); + my_room->requested_msg_type = aMR_MSG_STATE_MD_PUT_IN; + } +} + +static void aMR_MsgControlOpenExchangeMDSubmenu(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + Submenu* submenu = &play->submenu; + + if (mDemo_CheckDemo() == FALSE) { + mSM_open_submenu(submenu, mSM_OVL_INVENTORY, mSM_IV_OPEN_MINIDISK, 0); + mChoice_CLEAR_CHOSENUM(); + my_room->requested_msg_type = aMR_MSG_STATE_MD_EXCHANGE_SUBMENU; + } +} + +static void aMR_MsgControlMDPutIn(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + Submenu* submenu = &play->submenu; + + if (submenu->process_status == mSM_PROCESS_WAIT) { + FTR_ACTOR* ftr_actor = aMR_GetNowDemoFtr(actorx); + + if (submenu->item_p != NULL && submenu->item_p->item != EMPTY_NO) { + ftr_actor->items[0] = submenu->item_p->item; + aMR_OneMDSwitchOn_TheOtherSwitchOff(ftr_actor); + aMR_ReserveBgm(actorx, BGM_MD0 + (ftr_actor->items[0] - ITM_MINIDISK_START), ftr_actor, 0); + aMR_ChangeMDBgm(actorx, ftr_actor); + } + + aMR_ChangeDemoFtrStatus(actorx, 5); + my_room->requested_msg_type = aMR_MSG_STATE_WAIT_CLOSE_MD; + } +} + +static void aMR_MsgControlMDExchangeSubmenu(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + Submenu* submenu = &play->submenu; + + if (submenu->process_status == mSM_PROCESS_WAIT) { + Submenu_Item_c* submenu_item = submenu->item_p; + + if (submenu_item != NULL && submenu_item->item != EMPTY_NO) { + FTR_ACTOR* ftr_actor = aMR_GetNowDemoFtr(actorx); + + mPr_SetFreePossessionItem(Now_Private, ftr_actor->items[0], mPr_ITEM_COND_NORMAL); + ftr_actor->items[0] = submenu_item->item; + aMR_OneMDSwitchOn_TheOtherSwitchOff(ftr_actor); + aMR_ReserveBgm(actorx, BGM_MD0 + (ftr_actor->items[0] - ITM_MINIDISK_START), ftr_actor, 0); + aMR_ChangeMDBgm(actorx, ftr_actor); + } + + aMR_ChangeDemoFtrStatus(actorx, 5); + my_room->requested_msg_type = aMR_MSG_STATE_WAIT_CLOSE_MD; + } +} + +static void aMR_MsgControlWaitCloseMD(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (my_room->demo_flag == TRUE) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[my_room->demo_ftrID]; + + if (ftr_actor->demo_status == 0) { + my_room->state = 0; + my_room->demo_flag = FALSE; + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + } + } else { + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->demo_ftrID = 0; + } +} + +static void aMR_MsgInitRequestCloseMD(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlRequestCloseMD(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_CHECK_MAINDISAPPEAR() != FALSE || mMsg_CHECK_MAINHIDE() != FALSE) { + aMR_ChangeDemoFtrStatus(actorx, 5); + my_room->requested_msg_type = aMR_MSG_STATE_WAIT_CLOSE_MD; + } +} + +static void aMR_MsgControlCanNotMDClean(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->requested_msg_type = aMR_MSG_STATE_NONE; +} + +static void aMR_MsgInitPrepareCommunication(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->agb_connect_tries = 0; + mGcgba_InitVar(); +} + +static void aMR_MsgControlPrepareCommunication(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_CHECK_MAINNORMALCONTINUE()) { + /* Check that the current message is the 'send to GBA' message */ + if (mMsg_GET_MSG_NUM() == 0x3DCE) { + mMsg_SET_LOCKCONTINUE(); + + switch (mGcgba_ConnectEnabled()) { + case GBA2_GBA_STATE_SUCCESS: + mGcgba_InitVar(); + my_room->requested_msg_type = aMR_MSG_STATE_START_EMU_DOWN_LOAD; + break; + + case GBA2_GBA_STATE_TRANSMITTING: + break; + + default: + if (my_room->agb_connect_tries > 60) { + my_room->requested_msg_type = aMR_MSG_STATE_NOT_CONNECT_AGB; + mMsg_SET_CONTINUE_MSG_NUM(0x3DCF); /* GBA is not properly connected */ + mMsg_UNSET_LOCKCONTINUE(); + mGcgba_EndComm(); + } + + break; + } + + my_room->agb_connect_tries++; + } + } +} + +static void aMR_MsgInitNotConnectAgb(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlNotConnectAgb(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_CHECK_MAINDISAPPEAR() || mMsg_CHECK_MAINHIDE()) { + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->emu_info.request_flag = FALSE; + } +} + +static void aMR_MsgInitCheckAgbProgram(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlCheckAgbProgram(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + switch (mGcgba_IsEditor()) { + case GBA2_GBA_STATE_ALREADY_EXIST: + case GBA2_GBA_STATE_SUCCESS: + my_room->requested_msg_type = aMR_MSG_STATE_DELETE_AGB_PROGRAMQ; + mMsg_SET_CONTINUE_MSG_NUM(0x3DD0); /* Already has GBA program */ + mMsg_UNSET_LOCKCONTINUE(); + break; + + case GBA2_GBA_STATE_ERROR: + my_room->requested_msg_type = aMR_MSG_STATE_START_EMU_DOWN_LOAD; + break; + } +} + +static void aMR_MsgInitDeleteAgbProgramQ(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlDeleteAgbProgramQ(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice_no = mChoice_GET_CHOSENUM(); + + if (choice_no != -1) { + switch (choice_no) { + case mChoice_CHOICE0: + my_room->requested_msg_type = aMR_MSG_STATE_RECHECK_AGB_CONNECT; + mMsg_SET_CONTINUE_MSG_NUM(0x3DD2); + mMsg_UNSET_LOCKCONTINUE(); + break; + default: + my_room->requested_msg_type = aMR_MSG_STATE_NOT_CONNECT_AGB; + mMsg_SET_CONTINUE_MSG_NUM(0x3DD1); + mMsg_UNSET_LOCKCONTINUE(); + break; + } + } +} + +static void aMR_MsgInitStartEmuDownLoad(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->famicom_agb_image_p = famicom_gba_getImage(my_room->emu_info.agb_rom_no, &my_room->agb_game_size); + mGcgba_InitVar(); + mMsg_SET_LOCKCONTINUE(); + sAdo_SysLevStart(0x47); +} + +static void aMR_MsgControlStartEmuDownLoad(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + switch (mGcgba_Boot((u8*)my_room->famicom_agb_image_p, my_room->agb_game_size)) { + case GBA2_GBA_STATE_SUCCESS: + sAdo_SysLevStop(0x47); + famicom_gba_removeImage(my_room->famicom_agb_image_p); + mGcgba_InitVar(); + mGcgba_EndComm(); + my_room->requested_msg_type = aMR_MSG_STATE_NOT_CONNECT_AGB; + mMsg_SET_CONTINUE_MSG_NUM(0x3DD3); /* Data transmission complete */ + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + + case GBA2_GBA_STATE_TRANSMITTING: + break; + + default: + sAdo_SysLevStop(0x47); + famicom_gba_removeImage(my_room->famicom_agb_image_p); + mGcgba_InitVar(); + mGcgba_EndComm(); + my_room->requested_msg_type = aMR_MSG_STATE_NOT_CONNECT_AGB; + mMsg_SET_CONTINUE_MSG_NUM(0x3DD4); /* Data transmission failed */ + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + } +} + +static void aMR_MsgInitRecheckAgbConnect(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + mGcgba_EndComm(); + my_room->agb_connect_tries = 0; +} + +static void aMR_MsgControlRecheckAgbConnect(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_CHECK_MAINNORMALCONTINUE()) { + /* Check that the current message is the 'reconnect GBA' message */ + if (mMsg_GET_MSG_NUM() == 0x3DD2) { + mMsg_SET_LOCKCONTINUE(); + + switch (mGcgba_ConnectEnabled()) { + case GBA2_GBA_STATE_SUCCESS: + mGcgba_InitVar(); + my_room->requested_msg_type = aMR_MSG_STATE_START_EMU_DOWN_LOAD; + break; + + case GBA2_GBA_STATE_TRANSMITTING: + break; + + default: + if (my_room->agb_connect_tries > 60) { + my_room->requested_msg_type = aMR_MSG_STATE_NOT_CONNECT_AGB; + mMsg_SET_CONTINUE_MSG_NUM(0x3DCF); /* GBA is not properly connected */ + mMsg_UNSET_LOCKCONTINUE(); + } + + break; + } + + my_room->agb_connect_tries++; + } + } +} + +static void aMR_MsgInitQqqEmulator(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[my_room->emu_ftrID]; + + if (ftr_actor != NULL) { + static u8 ftr_name[mIN_ITEM_NAME_LEN]; + mActor_name_t emu_item = mRmTp_FtrIdx2FtrItemNo(ftr_actor->name, mRmTp_DIRECT_SOUTH); + + mIN_copy_name_str(ftr_name, emu_item); + mMsg_SET_FREE_STR_CL_ART(mMsg_FREE_STR1, ftr_name, sizeof(ftr_name), 5, emu_item); + } +} + +static void aMR_MsgControlQqqEmulator(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice_no = mChoice_GET_CHOSENUM(); + + if (choice_no != -1) { + mChoice_NO_B_CLOSE_SET(); + + switch (choice_no) { + case mChoice_CHOICE0: + aMR_SetEmulatorStartMessage(actorx, TRUE); + break; + case mChoice_CHOICE1: + if (my_room->emu_info.agb_rom_no != 255) { + my_room->requested_msg_type = aMR_MSG_STATE_PREPARE_COMMUNICATION; + mMsg_SET_CONTINUE_MSG_NUM(0x3DCE); /* GBA */ + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + } else { + my_room->requested_msg_type = aMR_MSG_STATE_NOT_CONNECT_AGB; + mMsg_SET_CONTINUE_MSG_NUM(0x3B57); /* Can't play on GBA */ + mMsg_SET_FORCENEXT(); + } + break; + default: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->emu_info.request_flag = FALSE; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + } + } +} + +static void aMR_MsgInitWarningCannotMakeSaveFile(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlWarningCannotMakeSaveFile(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + /* Check message is 'cannot create a new file' */ + if (mMsg_GET_MSG_NUM() == 0x306A) { + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR; + mMsg_SET_CONTINUE_MSG_NUM(0x17B5); /* Press L+R+Z to quit playing */ + mMsg_UNSET_LOCKCONTINUE(); + } +} + +static void aMR_MsgInitExplainEmulator(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlExplainEmulator(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + /* Check message is 'cannot create a new file' */ + if (mMsg_CHECK_MAINDISAPPEAR()) { + my_room->emu_info.explaination_given_flag = TRUE; + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + } +} + +static void aMR_MsgInitQqqEmulatorMemory1(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + mMsg_SET_FREE_STR_CL(mMsg_FREE_STR1, aMR_GetNameString(my_room, 0), mIN_ITEM_NAME_LEN, 5); +} + +static void aMR_MsgControlQqqEmulatorMemory1(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice_no = mChoice_GET_CHOSENUM(); + + mChoice_NO_B_CLOSE_SET(); + if (choice_no != -1) { + switch (choice_no) { + case mChoice_CHOICE0: + my_room->emu_info.rom_no = 0; + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR_MEMORY; + aMR_SetEmulatorStartMessage(actorx, FALSE); + break; + case mChoice_CHOICE1: + my_room->requested_msg_type = aMR_MSG_STATE_NOT_CONNECT_AGB; + mMsg_SET_CONTINUE_MSG_NUM(0x3B57); /* Can't play on GBA */ + mMsg_SET_FORCENEXT(); + break; + default: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->emu_info.request_flag = FALSE; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + } + } +} + +static void aMR_MsgInitQqqEmulatorMemory2(ACTOR* actorx) { + mChoice_c* choice_win = mChoice_Get_base_window_p(); + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + u8 cancel_string[mChoice_CHOICE_STRING_LEN]; + + mChoice_Load_ChoseStringFromRom(choice_win, cancel_string, 0x1AB, NULL); /* No thanks. */ + + // clang-format off + mChoice_Set_choice_data(choice_win, + aMR_GetNameString(my_room, 0), mChoice_CHOICE_STRING_LEN, + aMR_GetNameString(my_room, 1), mChoice_CHOICE_STRING_LEN, + cancel_string, mChoice_CHOICE_STRING_LEN, + NULL, mChoice_CHOICE_STRING_LEN, + NULL, mChoice_CHOICE_STRING_LEN, + NULL, mChoice_CHOICE_STRING_LEN); + // clang-format on +} + +static void aMR_MsgControlQqqEmulatorMemory2(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice_no = mChoice_GET_CHOSENUM(); + + mChoice_NO_B_CLOSE_SET(); + if (choice_no != -1) { + switch (choice_no) { + case mChoice_CHOICE0: + my_room->emu_info.rom_no = 0; + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR_MEMORY; + aMR_SetEmulatorStartMessage(actorx, FALSE); + break; + case mChoice_CHOICE1: + my_room->emu_info.rom_no = -1; + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR_MEMORY; + aMR_SetEmulatorStartMessage(actorx, FALSE); + break; + default: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->emu_info.request_flag = FALSE; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + } + } +} + +static void aMR_MsgInitQqqEmulatorMemoryOver3(ACTOR* actorx) { + mChoice_c* choice_win = mChoice_Get_base_window_p(); + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + static u8 cancel_string[mChoice_CHOICE_STRING_LEN]; + static u8 else_string[mChoice_CHOICE_STRING_LEN]; + + mChoice_Load_ChoseStringFromRom(choice_win, cancel_string, 0x1AB, NULL); /* No thanks. */ + mChoice_Load_ChoseStringFromRom(choice_win, else_string, 0x235, NULL); /* Something else... */ + + // clang-format off + mChoice_Set_choice_data(choice_win, + aMR_GetNameString(my_room, 0), mChoice_CHOICE_STRING_LEN, + aMR_GetNameString(my_room, 1), mChoice_CHOICE_STRING_LEN, + else_string, mChoice_CHOICE_STRING_LEN, + cancel_string, mChoice_CHOICE_STRING_LEN, + NULL, mChoice_CHOICE_STRING_LEN, + NULL, mChoice_CHOICE_STRING_LEN); + // clang-format on +} + +static void aMR_MsgControlQqqEmulatorMemoryOver3(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice_no = mChoice_GET_CHOSENUM(); + + mChoice_NO_B_CLOSE_SET(); + if (choice_no != -1) { + switch (choice_no) { + case mChoice_CHOICE0: + my_room->emu_info.rom_no = 0; + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR_MEMORY; + aMR_SetEmulatorStartMessage(actorx, FALSE); + break; + case mChoice_CHOICE1: + my_room->emu_info.rom_no = -1; + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR_MEMORY; + aMR_SetEmulatorStartMessage(actorx, FALSE); + break; + case mChoice_CHOICE2: + aMR_ReportDisplayMemoryGameSelectCount(my_room, 2); + if ((my_room->emu_info.card_famicom_count - my_room->emu_info.memory_game_select) >= 2 || + (my_room->emu_info.card_famicom_count - my_room->emu_info.memory_game_select) == 0) { + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_REPEAT_DISPLAY2; + } else { + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_REPEAT_DISPLAY1; + } + mMsg_SET_CONTINUE_MSG_NUM(0x3069); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + default: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->emu_info.request_flag = FALSE; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + } + } +} + +static void aMR_MsgInitQqqRepeatDisplay1(ACTOR* actorx) { + mChoice_c* choice_win = mChoice_Get_base_window_p(); + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + static u8 cancel_string[mChoice_CHOICE_STRING_LEN]; + static u8 else_string[mChoice_CHOICE_STRING_LEN]; + + switch (mChoice_check_main_index(choice_win)) { + case mChoice_MAIN_HIDE: + mChoice_Load_ChoseStringFromRom(choice_win, cancel_string, 0x1AB, NULL); /* No thanks. */ + mChoice_Load_ChoseStringFromRom(choice_win, else_string, 0x235, NULL); /* Something else... */ + + // clang-format off + mChoice_Set_choice_data(choice_win, + aMR_GetNameString(my_room, my_room->emu_info.memory_game_select), mChoice_CHOICE_STRING_LEN, + else_string, mChoice_CHOICE_STRING_LEN, + cancel_string, mChoice_CHOICE_STRING_LEN, + NULL, mChoice_CHOICE_STRING_LEN, + NULL, mChoice_CHOICE_STRING_LEN, + NULL, mChoice_CHOICE_STRING_LEN); + // clang-format on + break; + } +} + +static void aMR_MsgControlQqqRepeatDisplay1(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice_no; + + aMR_MsgInitQqqRepeatDisplay1(actorx); + choice_no = mChoice_GET_CHOSENUM(); + mChoice_NO_B_CLOSE_SET(); + if (choice_no != -1) { + switch (choice_no) { + case mChoice_CHOICE0: + aMR_SetMemoryCardGameIndex(my_room, 0); + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR_MEMORY; + aMR_SetEmulatorStartMessage(actorx, FALSE); + aMR_ReportDisplayMemoryGameSelectCount(my_room, 1); + break; + case mChoice_CHOICE1: + aMR_ReportDisplayMemoryGameSelectCount(my_room, 1); + if ((my_room->emu_info.card_famicom_count - my_room->emu_info.memory_game_select) >= 2 || + (my_room->emu_info.card_famicom_count - my_room->emu_info.memory_game_select) == 0) { + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_REPEAT_DISPLAY2; + } else if (my_room->msg_type == aMR_MSG_STATE_QQQ_REPEAT_DISPLAY1) { + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_REPEAT_DISPLAY1_2; + } else { + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_REPEAT_DISPLAY1; + } + mMsg_SET_CONTINUE_MSG_NUM(0x3069); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + default: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->emu_info.request_flag = FALSE; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + } + } +} + +static void aMR_MsgInitQqqRepeatDisplay2(ACTOR* actorx) { + mChoice_c* choice_win = mChoice_Get_base_window_p(); + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + static u8 cancel_string[mChoice_CHOICE_STRING_LEN]; + static u8 else_string[mChoice_CHOICE_STRING_LEN]; + + switch (mChoice_check_main_index(choice_win)) { + case mChoice_MAIN_HIDE: + mChoice_Load_ChoseStringFromRom(choice_win, cancel_string, 0x1AB, NULL); /* No thanks. */ + mChoice_Load_ChoseStringFromRom(choice_win, else_string, 0x235, NULL); /* Something else... */ + + // clang-format off + mChoice_Set_choice_data(choice_win, + aMR_GetNameString(my_room, my_room->emu_info.memory_game_select), mChoice_CHOICE_STRING_LEN, + aMR_GetNameString(my_room, my_room->emu_info.memory_game_select + 1), mChoice_CHOICE_STRING_LEN, + else_string, mChoice_CHOICE_STRING_LEN, + cancel_string, mChoice_CHOICE_STRING_LEN, + NULL, mChoice_CHOICE_STRING_LEN, + NULL, mChoice_CHOICE_STRING_LEN); + // clang-format on + break; + } +} + +static void aMR_MsgControlQqqRepeatDisplay2(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int choice_no; + + aMR_MsgInitQqqRepeatDisplay2(actorx); + choice_no = mChoice_GET_CHOSENUM(); + mChoice_NO_B_CLOSE_SET(); + if (choice_no != -1) { + switch (choice_no) { + case mChoice_CHOICE0: + aMR_SetMemoryCardGameIndex(my_room, 0); + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR_MEMORY; + aMR_SetEmulatorStartMessage(actorx, FALSE); + break; + case mChoice_CHOICE1: + aMR_SetMemoryCardGameIndex(my_room, 1); + my_room->requested_msg_type = aMR_MSG_STATE_EXPLAIN_EMULATOR_MEMORY; + aMR_SetEmulatorStartMessage(actorx, FALSE); + break; + case mChoice_CHOICE2: + aMR_ReportDisplayMemoryGameSelectCount(my_room, 2); + if ((my_room->emu_info.card_famicom_count - my_room->emu_info.memory_game_select) >= 2 || + (my_room->emu_info.card_famicom_count - my_room->emu_info.memory_game_select) == 0) { + if (my_room->msg_type == aMR_MSG_STATE_QQQ_REPEAT_DISPLAY2) { + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_REPEAT_DISPLAY2_2; + } else { + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_REPEAT_DISPLAY2; + } + } else { + my_room->requested_msg_type = aMR_MSG_STATE_QQQ_REPEAT_DISPLAY1; + } + mMsg_SET_CONTINUE_MSG_NUM(0x3069); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + default: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->emu_info.request_flag = FALSE; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + } + } +} + +static void aMR_MsgInitExplainEmulatorMemory(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlExplainEmulatorMemory(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_CHECK_MAINDISAPPEAR()) { + my_room->emu_info.explaination_given_flag = TRUE; + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + } +} + +static void aMR_MsgInitNoPackNoData(ACTOR* actorx) { + aMR_SetSlotString(); +} + +static void aMR_MsgControlNoPackNoData(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_CHECK_MAINDISAPPEAR()) { + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + mMsg_SET_CANCELNORMALCONTINUE(); + mMsg_UNSET_LOCKCONTINUE(); + my_room->room_msg_flag = FALSE; + } +} + +static void aMR_MsgInitWaitFamicomBatu(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlWaitFamicomBatu(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_CHECK_MAINDISAPPEAR() || mMsg_CHECK_MAINHIDE()) { + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->emu_info.request_flag = FALSE; + } +} + +static void aMR_MsgInitSaveFamicom(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->emu_info.save_msg_timer = 240; + my_room->emu_info.external_rom = (Common_Get(my_room_message_control_flags >> 3) & 1) ^ 1; + Common_Get(my_room_message_control_flags) &= ~(1 << 3); + Common_Get(my_room_message_control_flags) &= ~(1 << 4); + mMsg_SET_LOCKCONTINUE(); + aMR_SetSlotString(); +} + +static void aMR_MsgControlSaveFamicom(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (my_room->emu_info.save_msg_timer > 0) { + my_room->emu_info.save_msg_timer--; + } else { + my_room->emu_info.save_msg_timer = 0; + } + + if (my_room->emu_info.save_msg_timer == 0 && mMsg_CHECK_MAINNORMALCONTINUE()) { + int save_res; + + if (my_room->emu_info.external_rom == FALSE) { + save_res = famicom_internal_data_save(); + } else { + save_res = famicom_external_data_save(); + } + + aMR_SetSlotString(); + switch (save_res) { + case FAMICOM_RESULT_OK: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + mMsg_REQUEST_MAIN_DISAPPEAR(); + break; + case FAMICOM_RESULT_NOSPACE: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + mMsg_SET_CONTINUE_MSG_NUM(0x2B6C); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + case FAMICOM_RESULT_NOENTRY: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + mMsg_SET_CONTINUE_MSG_NUM(0x2B6D); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + case FAMICOM_RESULT_BROKEN: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + mMsg_SET_CONTINUE_MSG_NUM(0x2B6E); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + case FAMICOM_RESULT_WRONGDEVICE: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + mMsg_SET_CONTINUE_MSG_NUM(0x2B6F); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + case FAMICOM_RESULT_WRONGENCODING: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + mMsg_SET_CONTINUE_MSG_NUM(0x2B70); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + case FAMICOM_RESULT_NOCARD: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + mMsg_SET_FREE_STR(mMsg_FREE_STR0, Save_Get(land_info).name, LAND_NAME_SIZE); + mMsg_SET_CONTINUE_MSG_NUM(0x2B71); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + case FAMICOM_RESULT_NOFILE: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + mMsg_SET_CONTINUE_MSG_NUM(0x3B56); + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + default: + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + + if (my_room->emu_info.external_rom == TRUE) { + mMsg_SET_CONTINUE_MSG_NUM(0x3072); + } else { + mMsg_SET_CONTINUE_MSG_NUM(0x3072); + } + + mMsg_UNSET_LOCKCONTINUE(); + mMsg_SET_FORCENEXT(); + break; + } + + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->room_msg_flag = FALSE; + } +} + +static void aMR_MsgInitHitokoto(ACTOR* actorx) { + // nothing +} + +static void aMR_MsgControlHitokoto(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (mMsg_CHECK_MAINDISAPPEAR()) { + my_room->requested_msg_type = aMR_MSG_STATE_NONE; + my_room->state = 0; + } +} + +typedef void (*aMR_MSG_INIT_PROC)(ACTOR*); +typedef void (*aMR_MSG_CTRL_PROC)(ACTOR*, GAME*); + +// clang-format off +static aMR_MSG_INIT_PROC msg_init_table[aMR_MSG_STATE_NUM] = { + &aMR_NoMsgInit, + &aMR_NoMsgInit, + &aMR_NoMsgInit, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerWhichPutOut, + &aMR_MsgInitOwnerWhichPutOut, + &aMR_MsgInitOwnerWhichPutOut, + &aMR_MsgInitOwnerWaitWhichPutOut, + &aMR_NoMsgInit, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitFullPlayerItem, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_NoMsgInit, + &aMR_MsgInitRequestCloseFtr, + &aMR_NoMsgInit, + &aMR_NoMsgInit, + &aMR_NoMsgInit, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_NoMsgInit, + &aMR_NoMsgInit, + &aMR_MsgInitOwnerExistMD, + &aMR_MsgInitOwnerExistMD, + &aMR_NoMsgInit, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_NoMsgInit, + &aMR_MsgInitRequestCloseMD, + &aMR_NoMsgInit, + &aMR_NoMsgInit, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitOwnerExistItem, + &aMR_MsgInitQqqEmulator, + &aMR_MsgInitExplainEmulator, + &aMR_MsgInitQqqEmulatorMemory1, + &aMR_MsgInitExplainEmulatorMemory, + &aMR_MsgInitQqqEmulatorMemory2, + &aMR_MsgInitQqqEmulatorMemoryOver3, + &aMR_MsgInitQqqRepeatDisplay1, + &aMR_MsgInitQqqRepeatDisplay1, + &aMR_MsgInitQqqRepeatDisplay2, + &aMR_MsgInitQqqRepeatDisplay2, + &aMR_MsgInitNoPackNoData, + &aMR_MsgInitWarningCannotMakeSaveFile, + &aMR_MsgInitNoPackNoData, + &aMR_MsgInitNoPackNoData, + &aMR_MsgInitHitokoto, + &aMR_MsgInitHitokoto, + &aMR_MsgInitHitokoto, + &aMR_MsgInitSaveFamicom, + &aMR_MsgInitWaitFamicomBatu, + &aMR_MsgInitPrepareCommunication, + &aMR_MsgInitNotConnectAgb, + &aMR_MsgInitCheckAgbProgram, + &aMR_MsgInitDeleteAgbProgramQ, + &aMR_MsgInitStartEmuDownLoad, + &aMR_MsgInitRecheckAgbConnect, +}; +// clang-format on + +// clang-format off +static aMR_MSG_CTRL_PROC msg_ctrl_table[aMR_MSG_STATE_NUM] = { + &aMR_NoMsgControl, + &aMR_NoMsgControl, + &aMR_MsgControlOwnerNoItem, + &aMR_MsgControlOwnerExistItem, + &aMR_MsgControlOwnerExistItem_ItemCount2, + &aMR_MsgControlOwnerWhichPutOut, + &aMR_MsgControlOwnerWhichPutOut, + &aMR_MsgControlOwnerWhichPutOut, + &aMR_MsgControlOwnerWaitWhichPutOut, + &aMR_MsgControlOtherNoItem, + &aMR_MsgControlOtherExistItem, + &aMR_MsgControlOtherExistItem, + &aMR_MsgControlOtherExistItem, + &aMR_MsgControlFullPlayerItem, + &aMR_MsgControlOpenSubmenu, + &aMR_MsgControlItemPutIn, + &aMR_MsgControlWaitCloseFtr, + &aMR_MsgControlRequestCloseFtr, + &aMR_NoMsgControl, + &aMR_MsgControlCanNotClean, + &aMR_MsgControlCanNotClean, + &aMR_MsgControlOpenSetItemSubmenu, + &aMR_MsgControlItemSetSubmenu, + &aMR_NoMsgControl, + &aMR_MsgControlOwnerNoMD, + &aMR_MsgControlOwnerExistMD, + &aMR_MsgControlOwnerExistMD, + &aMR_MsgControlOtherNoMD, + &aMR_MsgControlOtherExistMD, + &aMR_MsgControlFullPlayerMD, + &aMR_MsgControlOpenMDSubmenu, + &aMR_MsgControlMDPutIn, + &aMR_MsgControlOpenMusicBox, + &aMR_MsgControlMusicBoxMDPutIn, + &aMR_MsgControlWaitCloseMD, + &aMR_MsgControlRequestCloseMD, + &aMR_NoMsgControl, + &aMR_MsgControlCanNotMDClean, + &aMR_MsgControlOpenExchangeMDSubmenu, + &aMR_MsgControlMDExchangeSubmenu, + &aMR_MsgControlQqqEmulator, + &aMR_MsgControlExplainEmulator, + &aMR_MsgControlQqqEmulatorMemory1, + &aMR_MsgControlExplainEmulatorMemory, + &aMR_MsgControlQqqEmulatorMemory2, + &aMR_MsgControlQqqEmulatorMemoryOver3, + &aMR_MsgControlQqqRepeatDisplay1, + &aMR_MsgControlQqqRepeatDisplay1, + &aMR_MsgControlQqqRepeatDisplay2, + &aMR_MsgControlQqqRepeatDisplay2, + &aMR_MsgControlNoPackNoData, + &aMR_MsgControlWarningCannotMakeSaveFile, + &aMR_MsgControlNoPackNoData, + &aMR_MsgControlNoPackNoData, + &aMR_MsgControlHitokoto, + &aMR_MsgControlHitokoto, + &aMR_MsgControlHitokoto, + &aMR_MsgControlSaveFamicom, + &aMR_MsgControlWaitFamicomBatu, + &aMR_MsgControlPrepareCommunication, + &aMR_MsgControlNotConnectAgb, + &aMR_MsgControlCheckAgbProgram, + &aMR_MsgControlDeleteAgbProgramQ, + &aMR_MsgControlStartEmuDownLoad, + &aMR_MsgControlRecheckAgbConnect, +}; +// clang-format on + +#define aMR_NO_MSG (-1) + +// clang-format off +static int aMR_msg_no_table[aMR_MSG_STATE_NUM] = { + aMR_NO_MSG, + aMR_NO_MSG, + 0x0A0A, + 0x0A0B, + 0x2F1A, + 0x2F1B, + 0x2F1E, + aMR_NO_MSG, + aMR_NO_MSG, + 0x0A0C, + 0x0A0D, + 0x2F1C, + 0x2F1D, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + 0x2F1F, + 0x2F1F, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + 0x10B7, + 0x10BE, + 0x10B8, + 0x10B9, + 0x10BA, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + 0x10BC, + aMR_NO_MSG, + aMR_NO_MSG, + 0x2B72, + aMR_NO_MSG, + 0x2B72, + aMR_NO_MSG, + 0x3068, + 0x3068, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + 0x2B69, + aMR_NO_MSG, + 0x306C, + 0x306B, + 0x3A8A, + 0x3AF1, + 0x3B58, + 0x2B6B, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, + aMR_NO_MSG, +}; +// clang-format on + +// clang-format off +static int aMR_none_talk_proc[aMR_MSG_STATE_NUM] = { + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + TRUE, + TRUE, + TRUE, + TRUE, + FALSE, + FALSE, + FALSE, + TRUE, + TRUE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + FALSE, + TRUE, + TRUE, + TRUE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, +}; +// clang-format on + +// clang-format off +static int aMR_force_talk_flag[aMR_MSG_STATE_NUM] = { + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + TRUE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + TRUE, + TRUE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + TRUE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + TRUE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + TRUE, + TRUE, + FALSE, + FALSE, + FALSE, + TRUE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, +}; +// clang-format on + +// clang-format off +static int aMR_window_se_flag[aMR_MSG_STATE_NUM] = { + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + FALSE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, + TRUE, +}; +// clang-format on + +static rgba_t aMR_window_color = { 255, 255, 20, 255 }; + +static int aMR_GetMessageNum(s16 msg_state, MY_ROOM_ACTOR* my_room) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[my_room->demo_ftrID]; + if (msg_state == aMR_MSG_STATE_OTHER_NO_ITEM) { + if (Save_Get(scene_no) == SCENE_NPC_HOUSE || Save_Get(scene_no) == SCENE_COTTAGE_NPC) { + return 0x2988 + ((ftr_actor->name + my_room->demo_ftrID) & 0xF); + } + } + + return aMR_msg_no_table[msg_state]; +} + +static void aMR_speak_set(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + mDemo_Set_msg_num(aMR_GetMessageNum(my_room->msg_type, my_room)); + mDemo_Set_talk_display_name(FALSE); + mDemo_Set_camera(CAMERA2_PROCESS_NORMAL); + mDemo_Set_ListenAble(); + mDemo_Set_talk_window_color(&aMR_window_color); + mMsg_SET_CONTINUE_MSG_NUM(-1); +} + +static void aMR_report_set(ACTOR* actorx) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + mDemo_Set_msg_num(aMR_GetMessageNum(my_room->msg_type, my_room)); + mDemo_Set_ListenAble(); + mDemo_Set_use_zoom_sound(aMR_window_se_flag[my_room->msg_type] & 1); + mDemo_Set_talk_window_color(&aMR_window_color); + mMsg_SET_CONTINUE_MSG_NUM(-1); +} + +static void aMR_MessageControl(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int demo_type; + + if (aMR_force_talk_flag[my_room->requested_msg_type]) { + demo_type = mDemo_TYPE_SPEAK; + } else { + demo_type = mDemo_TYPE_REPORT; + } + + if (my_room->requested_msg_type != my_room->msg_type && my_room->emu_info.explaination_given_flag == FALSE) { + if (aMR_msg_no_table[my_room->requested_msg_type] != aMR_NO_MSG) { + if (mDemo_Check(demo_type, actorx) == FALSE && + mDemo_Request(demo_type, actorx, demo_type == mDemo_TYPE_SPEAK ? &aMR_speak_set : &aMR_report_set)) { + my_room->msg_type = my_room->requested_msg_type; + mChoice_NO_B_CLOSE_SET(); + (*msg_init_table[my_room->msg_type])(actorx); + mChoice_CLEAR_CHOSENUM(); + } + } else { + my_room->msg_type = my_room->requested_msg_type; + mChoice_NO_B_CLOSE_SET(); + (*msg_init_table[my_room->msg_type])(actorx); + mChoice_CLEAR_CHOSENUM(); + } + } + + if (aMR_force_talk_flag[my_room->msg_type]) { + demo_type = mDemo_TYPE_SPEAK; + } else { + demo_type = mDemo_TYPE_REPORT; + } + + if (mDemo_Check(demo_type, actorx)) { + (*msg_ctrl_table[my_room->msg_type])(actorx, game); + } else if (aMR_none_talk_proc[my_room->msg_type] == TRUE) { + (*msg_ctrl_table[my_room->msg_type])(actorx, game); + } + + if (my_room->emu_info.request_flag == TRUE && my_room->emu_info.explaination_given_flag == TRUE && + mDemo_CheckDemo() == FALSE) { + int rom_no = my_room->emu_info.rom_no; + + if (rom_no <= 0) { + rom_no--; + } + + aMR_SaveWaltzTempo2(); + if (goto_emu_game(game, rom_no) == TRUE) { + mBGMPsComp_scene_mode(0x11); + mPlib_request_main_refuse_type1(game); + my_room->emu_info.request_flag = FALSE; + + if (rom_no < 0) { + Common_Get(my_room_message_control_flags) |= (1 << 4); + } else { + Common_Get(my_room_message_control_flags) |= (1 << 3); + } + } + } + + if ((Common_Get(my_room_message_control_flags) & (1 << 0))) { + my_room->requested_msg_type = aMR_MSG_STATE_NO_PACK_NO_DATA2; + my_room->room_msg_flag = TRUE; + Common_Get(my_room_message_control_flags) &= ~(1 << 0); + Common_Get(my_room_message_control_flags) &= ~(1 << 3); + Common_Get(my_room_message_control_flags) &= ~(1 << 4); + ; + } + + if ((Common_Get(my_room_message_control_flags) >> 3) & 1) { + my_room->requested_msg_type = aMR_MSG_STATE_SAVE_FAMICOM; + my_room->room_msg_flag = TRUE; + } else if ((Common_Get(my_room_message_control_flags) & (1 << 4))) { + my_room->requested_msg_type = aMR_MSG_STATE_SAVE_FAMICOM; + my_room->room_msg_flag = TRUE; + } +} diff --git a/src/famicom_emu.c b/src/famicom_emu.c index 69a1b030..7a184fc9 100644 --- a/src/famicom_emu.c +++ b/src/famicom_emu.c @@ -174,7 +174,7 @@ extern void famicom_emu_cleanup(GAME* game) { sAdo_SubGameEnd(); } -extern int famicom_gba_getImage(u32 rom_id, int* ptr) { +extern void* famicom_gba_getImage(u32 rom_id, size_t* size) { static char* names[] = { "cluclu", "usa_balloon", "donkey", "usa_jr_math", "pinball", "tennis", "usa_golf", NULL, "usa_baseball", NULL, "usa_donkey3", "donkeyjr", "soccer", "exbike", @@ -182,8 +182,7 @@ extern int famicom_gba_getImage(u32 rom_id, int* ptr) { }; char buf[256]; - u32 resource; - int block; + void* resource; char* rom; if (rom_id > 19) { @@ -197,9 +196,8 @@ extern int famicom_gba_getImage(u32 rom_id, int* ptr) { } else { sprintf(buf, "/FAMICOM/GBA/jb_%s.bin.szs", rom); resource = JC__JKRGetResource(buf); - if ((resource != 0) && (ptr != NULL)) { - block = JC__JKRGetMemBlockSize(0, resource); - *ptr = block; + if ((resource != NULL) && (size != NULL)) { + *size = JC__JKRGetMemBlockSize(0, resource); } } return resource; diff --git a/src/m_scene.c b/src/m_scene.c index d4e72a15..33e8ce51 100644 --- a/src/m_scene.c +++ b/src/m_scene.c @@ -529,7 +529,8 @@ extern int goto_next_scene(GAME_PLAY* play, int next_idx, int update_player_mode return res; } -extern int goto_emu_game(GAME_PLAY* play, u8 famicom_rom_id) { +extern int goto_emu_game(GAME* game, s16 famicom_rom_id) { + GAME_PLAY* play = (GAME_PLAY*)game; PLAYER_ACTOR* player = get_player_actor_withoutCheck(play); int res = FALSE; From cee5936d37d4b042521e37026656e07c44352450 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Fri, 12 Apr 2024 06:06:24 -0400 Subject: [PATCH 3/4] Match ac_my_room_move.c_inc --- include/ac_furniture.h | 5 +- include/ac_my_room.h | 26 +- include/ac_shop_goods.h | 2 +- include/ac_shop_goods_h.h | 29 + include/audio.h | 34 +- include/audio_defs.h | 12 +- include/c_keyframe.h | 7 +- include/jaudio_NES/melody.h | 6 +- include/m_clip.h | 3 +- include/m_collision_bg.h | 9 + include/m_common_data.h | 4 +- include/m_player_lib.h | 3 + include/m_scene_table.h | 149 +- src/ac_my_room.c | 73 +- src/ac_my_room_data.c_inc | 18 +- src/ac_my_room_goki.c_inc | 247 +++ src/ac_my_room_melody.c_inc | 17 + src/ac_my_room_move.c_inc | 3304 +++++++++++++++++++++++++++++++++++ src/audio.c | 40 +- src/c_keyframe.c | 5 +- 20 files changed, 3823 insertions(+), 170 deletions(-) create mode 100644 include/ac_shop_goods_h.h create mode 100644 src/ac_my_room_goki.c_inc create mode 100644 src/ac_my_room_melody.c_inc create mode 100644 src/ac_my_room_move.c_inc diff --git a/include/ac_furniture.h b/include/ac_furniture.h index 254479c8..9716da25 100644 --- a/include/ac_furniture.h +++ b/include/ac_furniture.h @@ -15,6 +15,8 @@ typedef struct furniture_actor_s FTR_ACTOR; #define aFTR_KEEP_ITEM_COUNT (mCoBG_LAYER_NUM - 1) #define aFTR_CHECK_INTERACTION(inter, type) (((inter) >> (type)) & 1) +#define aFTR_EDGE_COL_NUM 4 + enum { aFTR_STATE_STOP, aFTR_STATE_WAIT_PUSH, @@ -110,6 +112,7 @@ enum { aFTR_CHECK_INTERACTION((profile)->interaction_type, aFTR_INTERACTION_TYPE_CLOSET) || \ aFTR_CHECK_INTERACTION((profile)->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK)) enum { + aFTR_CONTACT_ACTION_NONE = 0, aFTR_CONTACT_ACTION_CHAIR_UNIDIRECTIONAL = 1, // only can sit from the front aFTR_CONTACT_ACTION_CHAIR_MULTIDIRECTIONAL = 2, // can sit from any direction aFTR_CONTACT_ACTION_CHAIR_SOFA = 4, // cam sit anywhere from the front @@ -195,7 +198,7 @@ struct furniture_actor_s { u8 shape_type; /* current size & shape (rotation) */ u8 original_shape_type; /* original size & shape (rotation) */ xyz_t base_position; - aFTR_collision_c edge_collision[4]; /* collision for each edge */ + aFTR_collision_c edge_collision[aFTR_EDGE_COL_NUM]; /* collision for each edge */ s16 collision_direction; int move_bg_idx; mCoBG_bg_regist_c bg_register; diff --git a/include/ac_my_room.h b/include/ac_my_room.h index dfae0a25..9c602d63 100644 --- a/include/ac_my_room.h +++ b/include/ac_my_room.h @@ -12,6 +12,12 @@ extern "C" { #define aMR_MAX_UNIT 8 #define aMR_HANIWA_ON_TABLE_NUM 14 +#define aMR_GOKI_MAX 3 +#define aMR_FIT_FTR_MAX 4 +#define aMR_RSV_FTR_NUM 3 + +#define aMR_NO_FTR_ID 200 +#define aMR_NO_FTR_ID2 201 typedef struct my_room_actor_s MY_ROOM_ACTOR; @@ -51,13 +57,13 @@ enum { typedef struct my_room_contact_s { int contact_flag; - int ftr_no; + int ftrID; int direction; int contact_side; f32 contact_percent; f32* normal_p; - f32 contact_edge0[2]; - f32 contact_edge1[2]; + f32 contact_edge_start[2]; + f32 contact_edge_end[2]; int contact_direction; } aMR_contact_info_c; @@ -138,11 +144,11 @@ typedef struct room_leaf_s { typedef struct room_pickup_s { int pickup_flag; - int ftr_no; + int ftrID; xyz_t leaf_pos; int picking_up_flag; s16 layer; - u16 dust_effect_timer; + s16 dust_effect_timer; u16 icon; } aMR_pickup_info_c; @@ -198,6 +204,12 @@ typedef struct room_fit_ftr_s { xyz_t ut_pos; } aMR_fit_ftr_c; +typedef struct room_parent_ftr_s { + int ftrID; + s16 angle_y; + aMR_fit_ftr_c fit_ftr_table[aMR_FIT_FTR_MAX]; +} aMR_parent_ftr_c; + struct my_room_actor_s { ACTOR actor_class; s16 state; @@ -256,9 +268,7 @@ struct my_room_actor_s { int _4F4; int room_msg_flag; int haniwa_step_idx; - int parent_ftrID; - s16 parent_angleY; - aMR_fit_ftr_c fit_ftr_table[4]; + aMR_parent_ftr_c parent_ftr; u32 music_box[2]; int scene; int _5A4; diff --git a/include/ac_shop_goods.h b/include/ac_shop_goods.h index 9d93ba40..e4694002 100644 --- a/include/ac_shop_goods.h +++ b/include/ac_shop_goods.h @@ -3,6 +3,7 @@ #include "types.h" #include "m_actor.h" +#include "ac_shop_goods_h.h" #ifdef __cplusplus extern "C" { @@ -15,4 +16,3 @@ extern ACTOR_PROFILE Shop_Goods_Profile; #endif #endif - diff --git a/include/ac_shop_goods_h.h b/include/ac_shop_goods_h.h new file mode 100644 index 00000000..702028f1 --- /dev/null +++ b/include/ac_shop_goods_h.h @@ -0,0 +1,29 @@ +#ifndef AC_SHOP_GOODS_H_H +#define AC_SHOP_GOODS_H_H + +#include "types.h" +#include "m_actor_type.h" +#include "game_h.h" +#include "m_lib.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*aSG_SINGLE_DRAW_PROC)(GAME*, mActor_name_t, xyz_t*, f32, s16, int); +typedef int (*aSG_PLAYER_DROP_ENTRY_PROC)(GAME*, mActor_name_t, int, int, int, int); +typedef s16 (*aSG_SINGLE_GET_ANGLE_Y_PROC)(int, int, int); +typedef void (*aSG_SINGLE_SET_ANGLE_Y_PROC)(int, int, int, s16); + +typedef struct shop_goods_clip_s { + aSG_SINGLE_DRAW_PROC single_draw_proc; + aSG_PLAYER_DROP_ENTRY_PROC player_drop_entry_proc; + aSG_SINGLE_GET_ANGLE_Y_PROC single_get_angle_y_proc; + aSG_SINGLE_SET_ANGLE_Y_PROC single_set_angle_y_proc; +} aSG_Clip_c; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/audio.h b/include/audio.h index 7236a34d..99b2f5bc 100644 --- a/include/audio.h +++ b/include/audio.h @@ -26,18 +26,18 @@ enum { VOICE_STATUS_NUM }; -extern void sAdo_Calc_MicPosition_forTrig(f32* fcalc, u16* scalc, xyz_t* pos); -extern void sAdo_Calc_MicPosition_forLevel(f32* fcalc, u16* scalc, xyz_t* pos); +extern void sAdo_Calc_MicPosition_forTrig(f32* fcalc, u16* scalc, const xyz_t* pos); +extern void sAdo_Calc_MicPosition_forLevel(f32* fcalc, u16* scalc, const xyz_t* pos); extern void sAdo_GameFrame(); extern void sAdo_BgmStart(u8 id); extern void sAdo_BgmStop(u16 id); extern void sAdo_SysTrgStart(u16 id); -extern void sAdo_PlyWalkSe(int walk, xyz_t* pos); -extern void sAdo_PlyWalkSeRoom(int walk, xyz_t* pos); -extern void sAdo_NpcWalkSe(int walk, xyz_t* pos); -extern void sAdo_NpcWalkSeRoom(int walk, xyz_t* pos); +extern void sAdo_PlyWalkSe(int walk, const xyz_t* pos); +extern void sAdo_PlyWalkSeRoom(int walk, const xyz_t* pos); +extern void sAdo_NpcWalkSe(int walk, const xyz_t* pos); +extern void sAdo_NpcWalkSeRoom(int walk, const xyz_t* pos); extern void sAdo_PlayerStatusLevel(f32 speed, int p); @@ -52,19 +52,19 @@ extern u8 sAdo_MessageSpeedGet(); extern void sAdo_SysLevStop(u8 id); extern void sAdo_SysLevStart(u8 id); -extern void sAdo_OngenPos(u32 p1, u8 p2, xyz_t* pos); -extern void sAdo_OngenTrgStart(u16 id, xyz_t* pos); +extern void sAdo_OngenPos(u32 p1, u8 p2, const xyz_t* pos); +extern void sAdo_OngenTrgStart(u16 id, const xyz_t* pos); extern void sAdo_SetOutMode(u8 mode); extern void sAdo_SetVoiceMode(u8 mode); -extern void sAdo_FloorTrgStart(u16 id, xyz_t* pos); +extern void sAdo_FloorTrgStart(u16 id, const xyz_t* pos); extern void sAdo_RhythmStart(u32 id, s8 type, s8 wait); extern void sAdo_RhythmStop(u32 id); extern void sAdo_RhythmAllStop(); -extern void sAdo_FurnitureInst(int track_id, s8 cb, s32 cl, xyz_t* pos); +extern void sAdo_FurnitureInst(u32 id, u8 inst, u8* melody, const xyz_t* pos); extern void sAdo_Pause(u8 mode); extern f32 sAdo_GetRhythmAnimCounter(u32 id); @@ -74,10 +74,10 @@ extern void sAdo_SetRhythmInfo(TempoBeat_c* rhythm); extern int sAdo_InstCountGet(); -extern void sAdo_RhythmPos(u32 id, u8 haniwa_id, xyz_t* pos); +extern void sAdo_RhythmPos(u32 id, u8 haniwa_id, const xyz_t* pos); extern void sAdo_SpecChange(int spec); -extern void sAdo_MDPlayerPos(xyz_t* pos, u16 s1, u16 s2, int p); +extern void sAdo_MDPlayerPos(const xyz_t* pos, u16 s1, u16 s2, int p); extern void sAdo_BGMVolume(f32 f, u16 volume); extern void sAdo_BgmCrossfadeStart(u8 b); @@ -98,7 +98,7 @@ extern void sAdos_GetStaffRollInfo(void* p); extern void sAdos_TTKK_ARM(u8 mode); -extern void sAdo_OngenTrgStartSpeed(f32 speed, u16 s1, xyz_t* pos); +extern void sAdo_OngenTrgStartSpeed(f32 speed, u16 s1, const xyz_t* pos); extern void sAdo_TrgSeEcho(u8 b); extern void sAdo_LevSeEcho(u8 b); @@ -115,16 +115,16 @@ extern u16 sAdo_Get_WalkLabel(int type); extern int sAdo_Get_KokeruLabel(int type); extern void sAdo_SceneMode(u8 mode); -extern u8 sAdo_RoomIncectPos(u32 f, u16 u, xyz_t* pos); +extern u8 sAdo_RoomIncectPos(u32 f, u16 u, const xyz_t* pos); -extern void sAdo_FurnitureInstPos(u32 f, xyz_t* pos); +extern void sAdo_FurnitureInstPos(u32 id, const xyz_t* pos); extern void sAdo_Set_ongenpos_refuse_fg(int state); extern int sAdo_GameframeEnd_Check(); extern int sAdo_GetSoundFrameCounter(); -extern int sAdo_CheckOnPlussBridge(xyz_t* pos, u32 atr); -extern void sAdo_RegistPlussBridge(xyz_t* pos); +extern int sAdo_CheckOnPlussBridge(const xyz_t* pos, u32 atr); +extern void sAdo_RegistPlussBridge(const xyz_t* pos); extern void sAdo_DeletePlussBridge(); extern void sAdo_kazagurumaLevel(f32 level); diff --git a/include/audio_defs.h b/include/audio_defs.h index 2ff8f2d4..e3553a44 100644 --- a/include/audio_defs.h +++ b/include/audio_defs.h @@ -35,6 +35,8 @@ typedef enum audio_sound_effects { NA_SE_LIGHT_ON, NA_SE_LIGHT_OFF, + NA_SE_DRAWER_SHUT = 0x3A, + NA_SE_ITEM_GET = 0x40, NA_SE_ITEM_HORIDASHI = 0x47, @@ -43,6 +45,9 @@ typedef enum audio_sound_effects { NA_SE_MONEY2, NA_SE_COIN, + NA_SE_BIRTH_FTR = 0x57, + NA_SE_CLEAN_UP_FTR = 0x58, + NA_SE_TOOL_FURI = 0x5A, // swing? NA_SE_AMI_HIT = 0x5C, NA_SE_TOOL_GET, @@ -79,6 +84,7 @@ typedef enum audio_sound_effects { NA_SE_ZASSOU_NUKU = 0x15F, NA_SE_HACHI_SASARERU, + NA_SE_166 = 0x166, NA_SE_UCHIWA = 0x167, NA_SE_SCOOP_SHIGEMI = 0x401, @@ -99,6 +105,10 @@ typedef enum audio_sound_effects { NA_SE_HARD_CHAIR_STANDUP, NA_SE_BUBU_CHAIR_STANDUP = 0x429, + NA_SE_FTR_DOOR_OPEN = 0x42C, + NA_SE_FTR_DOOR_CLOSE = 0x42D, + NA_SE_DRAWER_OPEN = 0x42E, + NA_SE_DRAWER_CLOSE = 0x42F, NA_SE_DAI_UE_KAKUNOU = 0x430, NA_SE_UMBRELLA_ROTATE = 0x432, @@ -119,8 +129,8 @@ typedef enum audio_sound_effects { } AudioSE; typedef enum bgm_e { + BGM_AEROBICS = 27, BGM_MD0 = 128, - } BGM_e; #ifdef __cplusplus diff --git a/include/c_keyframe.h b/include/c_keyframe.h index 9cfcda24..4d45b4ab 100644 --- a/include/c_keyframe.h +++ b/include/c_keyframe.h @@ -424,9 +424,8 @@ extern void cKF_SkeletonInfo_R_T_combine_play(int* arg1, int* arg2, int* arg3, c * @param angley Y angle for base model rotation. * @param anglez Z angle for base model rotation. */ -extern void cKF_SkeletonInfo_R_Animation_Set_base_shape_trs(f32 transx, f32 transy, f32 transz, - cKF_SkeletonInfo_R_c* keyframe, s16 anglex, s16 angley, - s16 anglez); +extern void cKF_SkeletonInfo_R_Animation_Set_base_shape_trs(cKF_SkeletonInfo_R_c* keyframe, f32 transx, f32 transy, + f32 transz, s16 anglex, s16 angley, s16 anglez); /** * Adjusts the base position and correction for a skeleton info structure based on animation flags. @@ -482,4 +481,4 @@ extern void cKF_SkeletonInfo_R_AnimationMove_CulcTransToWorld(f32 calcx, f32 cal } #endif -#endif \ No newline at end of file +#endif diff --git a/include/jaudio_NES/melody.h b/include/jaudio_NES/melody.h index 05b84497..34d98d1d 100644 --- a/include/jaudio_NES/melody.h +++ b/include/jaudio_NES/melody.h @@ -8,13 +8,11 @@ extern "C" { #endif extern void Na_Inst(u16, u8*); -extern void Na_FurnitureInst(int,s8,s32,u16,f32); +extern void Na_FurnitureInst(u32, u8, u8*, u16, f32); extern int Na_InstCountGet(); - - #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif diff --git a/include/m_clip.h b/include/m_clip.h index 306f493f..68bba9de 100644 --- a/include/m_clip.h +++ b/include/m_clip.h @@ -23,6 +23,7 @@ #include "ac_shop_umbrella.h" #include "ac_handOverItem.h" #include "ac_quest_manager_clip.h" +#include "ac_shop_goods_h.h" #ifdef __cplusplus extern "C" { @@ -63,7 +64,7 @@ typedef struct clip_s { /* 0x0A4 */ mDemo_Clip_c* demo_clip2; /* can be multiple clip classes */ /* 0x0A8 */ void* _0A8; /* 0x0AC */ aGYO_Clip_c* gyo_clip; - /* 0x0B0 */ void* _0B0; + /* 0x0B0 */ aSG_Clip_c* shop_goods_clip; /* 0x0B4 */ void* _0B4; /* 0x0B8 */ aShopUmbrella_Clip_c* shop_umbrella_clip; /* 0x0BC */ aAR_Clip_c* arrange_room_clip; diff --git a/include/m_collision_bg.h b/include/m_collision_bg.h index c18518f8..360dbe54 100644 --- a/include/m_collision_bg.h +++ b/include/m_collision_bg.h @@ -277,6 +277,15 @@ extern int mCoBG_GetHoleNumber_ClData(mCoBG_Collision_u* col); extern void mCoBG_GetBgNorm_FromWpos(xyz_t* norm, xyz_t wpos); extern int mCoBG_GetWaterFlow(xyz_t* water_flow, u32 attr); extern void mCoBG_SetAttribute(xyz_t pos, u32 attr); +extern int mCoBG_GetPointInfoFrontLine(f32* line, f32* check_pos, f32* norm); +extern int mCoBG_GetCrossCircleAndLine2Dvector(f32* cross0_xz, f32* cross1_xz, f32* point_xz, f32* vec_xz, + f32* center_xz, f32 radius); +extern f32 mCoBG_GetVectorProductin2D(f32* vec0_xz, f32* vec1_xz); +extern int mCoBG_GetCrossLineAndPerpendicular(f32* cross_xz, f32* start_xz, f32* end_xz, f32* point_xz); +extern int mCoBG_RangeCheckLinePoint(f32* start_xz, f32* end_xz, f32* point_xz); +extern int mCoBG_GetDistPointAndLine2D_Norm(f32* dist, f32* start_xz, f32* end_xz, f32* norm, f32* point_xz); +extern f32 mCoBG_Get2VectorAngleF(f32* v0, f32* v1, u8 type); +extern int mCoBG_CheckUtFlat(const xyz_t* pos); extern void mCoBG_InitMoveBgData(); extern void mCoBG_InitBlockBgCheckMode(); diff --git a/include/m_common_data.h b/include/m_common_data.h index 672eeea5..19d81f59 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -256,7 +256,7 @@ typedef struct common_data_s { /* 0x0287FA */ u8 _287FA[0x28838 - 0x0287FA]; /* 0x028838 */ s8 player_bee_swell_flag; /* 0x028839 */ s8 player_bee_chase_flag; - /* 0x02883A */ u8 goki_shocked_flag; + /* 0x02883A */ s8 goki_shocked_flag; /* 0x02883B */ u8 time_changed_flag; /* 0x02883C */ u8 unable_to_wade_flag; /* 0x02883D */ u8 _02883D; @@ -314,7 +314,7 @@ typedef struct common_data_s { /* 0x02DBB0 */ s16 can_look_goki_count; /* 0x02DBB4 */ f32 rainbow_opacity; /* current opacity of rainbow (0.0f - 1.0f) */ /* 0x02DBB8 */ u32 event_flags[mEv_EVENT_TYPE_NUM]; - /* 0x02DBD4 */ xyz_t* pluss_bridge_pos; /* position of extra bridge */ + /* 0x02DBD4 */ const xyz_t* pluss_bridge_pos; /* position of extra bridge */ /* 0x02DBD8 */ lbRTC_time_c auto_nwrite_time; /* cached notice time used for fishing tourney results? */ /* 0x02DBE0 */ u8 rhythym_updated; /* 0x02DBE1 */ u8 _2dbe1; diff --git a/include/m_player_lib.h b/include/m_player_lib.h index 60d05841..9052d5ad 100644 --- a/include/m_player_lib.h +++ b/include/m_player_lib.h @@ -64,6 +64,9 @@ extern int mPlib_check_player_open_umbrella(GAME_PLAY* play); extern int mPlib_Check_UKI_COMEBACK_STATUS(); extern int mPlib_check_player_actor_main_index_OutDoorMove(GAME_PLAY* play); extern int mPlib_request_main_close_furniture_type1(GAME* game); +extern int mPlib_request_main_shock_type1(GAME* game, f32 time, s16 angle_y, int axe_swing); +extern int mPlib_request_main_hold_type1(GAME* game, int ftr_no, int player_direct, const xyz_t* player_pos); +extern int mPlib_check_player_warp_forEvent(void); extern mPlayer_change_data_from_submenu_c* mPlib_Get_change_data_from_submenu_p(); diff --git a/include/m_scene_table.h b/include/m_scene_table.h index 07091587..bf86fa0f 100644 --- a/include/m_scene_table.h +++ b/include/m_scene_table.h @@ -2,24 +2,24 @@ #define M_SCENE_TABLE_H #include "types.h" -//#include "m_scene.h" +// #include "m_scene.h" #ifdef __cplusplus extern "C" { #endif enum field_draw_type { - FIELD_DRAW_TYPE_OUTDOORS, - FIELD_DRAW_TYPE_INDOORS, - FIELD_DRAW_TYPE_TRAIN, - FIELD_DRAW_TYPE_PLAYER_SELECT, + FIELD_DRAW_TYPE_OUTDOORS, + FIELD_DRAW_TYPE_INDOORS, + FIELD_DRAW_TYPE_TRAIN, + FIELD_DRAW_TYPE_PLAYER_SELECT, - FIELD_DRAW_TYPE_NUM + FIELD_DRAW_TYPE_NUM }; typedef struct scene_status_s { - u8 unk0[0x13]; - u8 unk13; + u8 unk0[0x13]; + u8 unk13; } Scene_data_status_c; /* @@ -28,76 +28,79 @@ typedef struct scene_status_s { */ enum scene_table { - SCENE_TEST1, - SCENE_TEST2, - SCENE_TEST3, - SCENE_WATER_TEST, - SCENE_FOOTPRINT_TEST, - SCENE_NPC_TEST, - SCENE_NPC_HOUSE, /* npc house interior */ - SCENE_FG, /* outdoors/FG */ - SCENE_RANDOM_NPC_TEST, - SCENE_SHOP0, /* nook's cranny */ - SCENE_BG_TEST_NO_RIVER, - SCENE_BG_TEST_RIVER, - SCENE_BROKER_SHOP, /* crazy redd's tent */ - SCENE_FIELD_TOOL_INSIDE, - SCENE_POST_OFFICE, /* post office */ - SCENE_START_DEMO, /* after player select */ - SCENE_START_DEMO2, /* */ - SCENE_POLICE_BOX, - SCENE_BUGGY, - SCENE_PLAYERSELECT, - SCENE_MY_ROOM_S, - SCENE_MY_ROOM_M, - SCENE_MY_ROOM_L, - SCENE_CONVENI, /* nook 'n' go */ - SCENE_SUPER, /* nookway */ - SCENE_DEPART, /* nookington's 1st floor */ - SCENE_TEST5, - SCENE_PLAYERSELECT_2, - SCENE_PLAYERSELECT_3, - SCENE_DEPART_2, /* nookington's 2nd floor */ - SCENE_EVENT_ANNOUNCEMENT, - SCENE_KAMAKURA, - SCENE_FIELD_TOOL, - SCENE_TITLE_DEMO, /* title screen demo */ - SCENE_PLAYERSELECT_SAVE, - SCENE_MUSEUM_ENTRANCE, - SCENE_MUSEUM_ROOM_PAINTING, - SCENE_MUSEUM_ROOM_FOSSIL, - SCENE_MUSEUM_ROOM_INSECT, - SCENE_MUSEUM_ROOM_FISH, - SCENE_MY_ROOM_LL1, - SCENE_MY_ROOM_LL2, - SCENE_MY_ROOM_BASEMENT_S, - SCENE_MY_ROOM_BASEMENT_M, - SCENE_MY_ROOM_BASEMENT_L, - SCENE_MY_ROOM_BASEMENT_LL1, - SCENE_NEEDLEWORK, /* able sister's */ - SCENE_COTTAGE_MY, - SCENE_COTTAGE_NPC, - SCENE_START_DEMO3, - SCENE_LIGHTHOUSE, - SCENE_TENT, + SCENE_TEST1, + SCENE_TEST2, + SCENE_TEST3, + SCENE_WATER_TEST, + SCENE_FOOTPRINT_TEST, + SCENE_NPC_TEST, + SCENE_NPC_HOUSE, /* npc house interior */ + SCENE_FG, /* outdoors/FG */ + SCENE_RANDOM_NPC_TEST, + SCENE_SHOP0, /* nook's cranny */ + SCENE_BG_TEST_NO_RIVER, + SCENE_BG_TEST_RIVER, + SCENE_BROKER_SHOP, /* crazy redd's tent */ + SCENE_FIELD_TOOL_INSIDE, + SCENE_POST_OFFICE, /* post office */ + SCENE_START_DEMO, /* after player select */ + SCENE_START_DEMO2, /* */ + SCENE_POLICE_BOX, + SCENE_BUGGY, + SCENE_PLAYERSELECT, + SCENE_MY_ROOM_S, + SCENE_MY_ROOM_M, + SCENE_MY_ROOM_L, + SCENE_CONVENI, /* nook 'n' go */ + SCENE_SUPER, /* nookway */ + SCENE_DEPART, /* nookington's 1st floor */ + SCENE_TEST5, + SCENE_PLAYERSELECT_2, + SCENE_PLAYERSELECT_3, + SCENE_DEPART_2, /* nookington's 2nd floor */ + SCENE_EVENT_ANNOUNCEMENT, + SCENE_KAMAKURA, + SCENE_FIELD_TOOL, + SCENE_TITLE_DEMO, /* title screen demo */ + SCENE_PLAYERSELECT_SAVE, + SCENE_MUSEUM_ENTRANCE, + SCENE_MUSEUM_ROOM_PAINTING, + SCENE_MUSEUM_ROOM_FOSSIL, + SCENE_MUSEUM_ROOM_INSECT, + SCENE_MUSEUM_ROOM_FISH, + SCENE_MY_ROOM_LL1, + SCENE_MY_ROOM_LL2, + SCENE_MY_ROOM_BASEMENT_S, + SCENE_MY_ROOM_BASEMENT_M, + SCENE_MY_ROOM_BASEMENT_L, + SCENE_MY_ROOM_BASEMENT_LL1, + SCENE_NEEDLEWORK, /* able sister's */ + SCENE_COTTAGE_MY, + SCENE_COTTAGE_NPC, + SCENE_START_DEMO3, + SCENE_LIGHTHOUSE, + SCENE_TENT, - SCENE_NUM + SCENE_NUM }; -#define mSc_IS_SCENE_PLAYER_ROOM(scene) \ - ((scene) == SCENE_MY_ROOM_S || (scene) == SCENE_MY_ROOM_M || (scene) == SCENE_MY_ROOM_L || \ - (scene) == SCENE_MY_ROOM_LL1 || (scene) == SCENE_MY_ROOM_LL2 || (scene) == SCENE_MY_ROOM_BASEMENT_S || \ - (scene) == SCENE_MY_ROOM_BASEMENT_M || (scene) == (SCENE_MY_ROOM_BASEMENT_L) || (scene) == SCENE_MY_ROOM_BASEMENT_LL1 || \ - (scene) == SCENE_COTTAGE_MY) +#define mSc_IS_SCENE_PLAYER_HOUSE_ROOM(scene) \ + ((scene) == SCENE_MY_ROOM_S || (scene) == SCENE_MY_ROOM_M || (scene) == SCENE_MY_ROOM_L || \ + (scene) == SCENE_MY_ROOM_LL1 || (scene) == SCENE_MY_ROOM_LL2 || (scene) == SCENE_MY_ROOM_BASEMENT_S || \ + (scene) == SCENE_MY_ROOM_BASEMENT_M || (scene) == (SCENE_MY_ROOM_BASEMENT_L) || \ + (scene) == SCENE_MY_ROOM_BASEMENT_LL1) -#define mSc_IS_SCENE_BASEMENT(scene) \ - ((scene) == SCENE_MY_ROOM_BASEMENT_S || \ - (scene) == SCENE_MY_ROOM_BASEMENT_M || \ - (scene) == SCENE_MY_ROOM_BASEMENT_L || \ - (scene) == SCENE_MY_ROOM_BASEMENT_LL1) +#define mSc_IS_SCENE_PLAYER_ROOM(scene) \ + ((scene) == SCENE_MY_ROOM_S || (scene) == SCENE_MY_ROOM_M || (scene) == SCENE_MY_ROOM_L || \ + (scene) == SCENE_MY_ROOM_LL1 || (scene) == SCENE_MY_ROOM_LL2 || (scene) == SCENE_MY_ROOM_BASEMENT_S || \ + (scene) == SCENE_MY_ROOM_BASEMENT_M || (scene) == (SCENE_MY_ROOM_BASEMENT_L) || \ + (scene) == SCENE_MY_ROOM_BASEMENT_LL1 || (scene) == SCENE_COTTAGE_MY) -#define mSc_IS_SCENE_MUSEUM_ROOM(scene) \ - ((scene) >= SCENE_MUSEUM_ENTRANCE && (scene) <= SCENE_MUSEUM_ROOM_FISH) +#define mSc_IS_SCENE_BASEMENT(scene) \ + ((scene) == SCENE_MY_ROOM_BASEMENT_S || (scene) == SCENE_MY_ROOM_BASEMENT_M || \ + (scene) == SCENE_MY_ROOM_BASEMENT_L || (scene) == SCENE_MY_ROOM_BASEMENT_LL1) + +#define mSc_IS_SCENE_MUSEUM_ROOM(scene) ((scene) >= SCENE_MUSEUM_ENTRANCE && (scene) <= SCENE_MUSEUM_ROOM_FISH) extern Scene_data_status_c scene_data_status[SCENE_NUM]; diff --git a/src/ac_my_room.c b/src/ac_my_room.c index 681c9cf2..4fe3a109 100644 --- a/src/ac_my_room.c +++ b/src/ac_my_room.c @@ -14,6 +14,9 @@ #include "m_house.h" #include "m_player_lib.h" #include "GBA2/gba2.h" +#include "m_debug.h" +#include "m_mark_room.h" +#include "sys_matrix.h" enum { aMR_ICON_LEAF, @@ -120,17 +123,33 @@ static aMR_work_c l_aMR_work; static u8 l_bank_index_table[FTR_NUM]; static u8* l_bank_address_table[aMR_FTR_BANK_NUM]; +// clang-format off +const aMR_contact_info_c l_cntInf_default = { + FALSE, + 100, + 0, + 0, + 0.0f, + NULL, + { 0.0f, 0.0f }, + { 0.0f, 0.0f }, + 0 +}; +// clang-format on const f32 aMR_angle_table[4] = { 0.0f, 90.0f, 180.0f, 270.0f }; const u8 l_typeB0_table[4] = { aFTR_SHAPE_TYPEB_0, aFTR_SHAPE_TYPEB_90, aFTR_SHAPE_TYPEB_180, aFTR_SHAPE_TYPEB_270 }; static int aMR_UnitNum2FtrItemNoFtrID(mActor_name_t* item_no, int* ftr_id, int ut_x, int ut_z, int layer); static void aMR_ReserveDefaultBgm(ACTOR* actorx, FTR_ACTOR* ftr_actor); static void aMR_ChangeMDBgm(ACTOR* actorx, FTR_ACTOR* ftr_actor); -static void aMR_SetFurniture2FG(FTR_ACTOR* ftr_actor, xyz_t pos, int on_flag); +static int aMR_SetFurniture2FG(FTR_ACTOR* ftr_actor, xyz_t pos, int on_flag); static int aMR_FtrIdx2ChangeFtrSwitch(ACTOR* actorx, int ftr_id); static aFTR_PROFILE* aMR_GetFurnitureProfile(u16 ftr_no); +static mActor_name_t* aMR_GetLayerTopFg(s16 layer); #include "../src/ac_my_room_msg_ctrl.c_inc" +#include "../src/ac_my_room_goki.c_inc" +#include "../src/ac_my_room_melody.c_inc" static aFTR_PROFILE* aMR_GetFurnitureProfile(u16 ftr_no) { if (ftr_no < FTR_NUM) { @@ -244,7 +263,7 @@ static mActor_name_t* aMR_GetLayerTopFg(s16 layer) { return mFI_BkNum2UtFGTop_layer(0, 0, layer); } -u64* aMR_GetBitSwitchTable(int layer, MY_ROOM_ACTOR* my_room) { +static u64* aMR_GetBitSwitchTable(int layer, MY_ROOM_ACTOR* my_room) { mActor_name_t field_id = mFI_GetFieldId(); if (my_room->scene == SCENE_COTTAGE_MY) { @@ -266,7 +285,7 @@ u64* aMR_GetBitSwitchTable(int layer, MY_ROOM_ACTOR* my_room) { return NULL; } -u32* aMR_GetHaniwaStepSaveData(s16 layer, MY_ROOM_ACTOR* my_room) { +static u32* aMR_GetHaniwaStepSaveData(s16 layer, MY_ROOM_ACTOR* my_room) { mActor_name_t field_id = mFI_GetFieldId(); if (my_room->scene == SCENE_COTTAGE_MY) { @@ -764,7 +783,7 @@ static void aMR_SetFirstScale(FTR_ACTOR* ftr_actor) { ftr_actor->dust_timer = 0; } -static void aMR_DeleteFurnitreBank(u16 ftr_no) { +static void aMR_DeleteFurnitureBank(u16 ftr_no) { if (aMR_CountAppointFurniture(ftr_no) == 0) { l_bank_index_table[ftr_no] = 255; } @@ -1022,7 +1041,7 @@ static void aMR_MiniDiskCommonDt(FTR_ACTOR* ftr_actor, ACTOR* actorx) { my_room->bgm_info.last_md_no = -1; /* Don't delete for aerobics radio music */ - if (my_room->bgm_info.md_no != 27) { + if (my_room->bgm_info.md_no != BGM_AEROBICS) { mBGMPsComp_MDPlayerPos_delete(); } } @@ -1055,7 +1074,7 @@ static void aMR_ChangeMDBgm(ACTOR* actorx, FTR_ACTOR* ftr_actor) { if (my_room->bgm_info.md_no != -1) { mBGMPsComp_make_ps_room(my_room->bgm_info.md_no, 0); - if (my_room->bgm_info.md_no != 27) { + if (my_room->bgm_info.md_no != BGM_AEROBICS) { mBGMPsComp_MDPlayerPos_make(); } @@ -1071,12 +1090,12 @@ static void aMR_ChangeMDBgm(ACTOR* actorx, FTR_ACTOR* ftr_actor) { my_room->bgm_info.last_md_no = my_room->bgm_info.md_no; } else { mBGMPsComp_delete_ps_room(my_room->bgm_info.last_md_no, 0); - if (my_room->bgm_info.last_md_no != 27) { + if (my_room->bgm_info.last_md_no != BGM_AEROBICS) { mBGMPsComp_MDPlayerPos_delete(); } mBGMPsComp_make_ps_room(my_room->bgm_info.md_no, 0); - if (my_room->bgm_info.md_no != 27) { + if (my_room->bgm_info.md_no != BGM_AEROBICS) { mBGMPsComp_MDPlayerPos_make(); } @@ -1412,7 +1431,7 @@ static int aMR_ftrID2Wpos(xyz_t* wpos, int ftr_id); static int aMR_UnitNum2FtrItemNoFtrID(mActor_name_t* ftr_item_no, int* ftr_id, int ut_x, int ut_z, int layer); static void aMR_FtrID2ExtinguishFurniture(int ftr_id); static void aMR_RedmaFtrBank(void); -static int aMR_ReserveFurniture(GAME* game, u16 ftr_no, int judge_res, int ut_x, int ut_z, u16 rotation, +static int aMR_ReserveFurniture(GAME* game, u16 ftr_no, int free_idx, int ut_x, int ut_z, u16 rotation, int square_offset, int layer); static int aMR_CountFriendFurniture(FTR_ACTOR* ftr_actor, u8 switch_on); static int aMR_JudgePlace2ndLayer(int ut_x, int ut_z); @@ -1724,7 +1743,7 @@ static void My_Room_Actor_ct(ACTOR* actorx, GAME* game) { aMR_InitFurnitureBankTable(); aMR_MakeFurnitureActor(actorx, play, mCoBG_LAYER0); aMR_MakeFurnitureActor(actorx, play, mCoBG_LAYER1); - my_room->parent_ftrID = -1; + my_room->parent_ftr.ftrID = -1; Common_Set(make_npc2_actor, TRUE); aMR_MakeItemDataInFurniture(); aMR_DeleteMusicWhichMusicBoxDontHave(); @@ -1939,6 +1958,8 @@ static void My_Room_Actor_dt(ACTOR* actorx, GAME* game) { } } +#include "../src/ac_my_room_move.c_inc" + static void aMR_RedmaFtrBank(void) { int i; @@ -2124,7 +2145,7 @@ extern mActor_name_t aMR_FurnitureFg_to_FurnitureFgWithDirect(mActor_name_t item extern void aMR_RadioCommonMove(FTR_ACTOR* ftr_actor, ACTOR* actorx) { if (ftr_actor->haniwa_state == 1) { - aMR_ReserveBgm(actorx, 27, ftr_actor, 0); + aMR_ReserveBgm(actorx, BGM_AEROBICS, ftr_actor, 0); ftr_actor->haniwa_state = 0; } else if (ftr_actor->switch_changed_flag) { if (ftr_actor->switch_bit == FALSE) { @@ -2134,7 +2155,7 @@ extern void aMR_RadioCommonMove(FTR_ACTOR* ftr_actor, ACTOR* actorx) { ftr_actor->switch_bit = FALSE; } else { aMR_OneMDSwitchOn_TheOtherSwitchOff(ftr_actor); - aMR_ReserveBgm(actorx, 27, ftr_actor, 0); + aMR_ReserveBgm(actorx, BGM_AEROBICS, ftr_actor, 0); aMR_ChangeMDBgm(actorx, ftr_actor); ftr_actor->switch_bit = TRUE; } @@ -2142,7 +2163,7 @@ extern void aMR_RadioCommonMove(FTR_ACTOR* ftr_actor, ACTOR* actorx) { } extern int aMR_RadioBgmNow(void) { - if (mBGMPsComp_execute_bgm_num_get() == 27) { + if (mBGMPsComp_execute_bgm_num_get() == BGM_AEROBICS) { return TRUE; } @@ -2167,13 +2188,13 @@ extern FTR_ACTOR* aMR_GetParentFactor(FTR_ACTOR* ftr_actor, ACTOR* actorx) { if (actorx != NULL) { MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; - if (my_room->parent_ftrID != -1) { - FTR_ACTOR* parent_ftr_actor = l_aMR_work.ftr_actor_list + my_room->parent_ftrID; + if (my_room->parent_ftr.ftrID != -1) { + FTR_ACTOR* parent_ftr_actor = l_aMR_work.ftr_actor_list + my_room->parent_ftr.ftrID; - if (my_room->fit_ftr_table[0].ftr_ID == ftr_actor->id || - my_room->fit_ftr_table[1].ftr_ID == ftr_actor->id || - my_room->fit_ftr_table[2].ftr_ID == ftr_actor->id || - my_room->fit_ftr_table[3].ftr_ID == ftr_actor->id) { + if (my_room->parent_ftr.fit_ftr_table[0].ftr_ID == ftr_actor->id || + my_room->parent_ftr.fit_ftr_table[1].ftr_ID == ftr_actor->id || + my_room->parent_ftr.fit_ftr_table[2].ftr_ID == ftr_actor->id || + my_room->parent_ftr.fit_ftr_table[3].ftr_ID == ftr_actor->id) { return parent_ftr_actor; } } @@ -2185,14 +2206,14 @@ extern FTR_ACTOR* aMR_GetParentFactor(FTR_ACTOR* ftr_actor, ACTOR* actorx) { extern s16 aMR_GetParentAngleOffset(FTR_ACTOR* ftr_actor, ACTOR* actorx) { if (actorx != NULL) { MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; - if (my_room->parent_ftrID != -1) { - FTR_ACTOR* parent_ftr_actor = l_aMR_work.ftr_actor_list + my_room->parent_ftrID; + if (my_room->parent_ftr.ftrID != -1) { + FTR_ACTOR* parent_ftr_actor = l_aMR_work.ftr_actor_list + my_room->parent_ftr.ftrID; - if (my_room->fit_ftr_table[0].ftr_ID == ftr_actor->id || - my_room->fit_ftr_table[1].ftr_ID == ftr_actor->id || - my_room->fit_ftr_table[2].ftr_ID == ftr_actor->id || - my_room->fit_ftr_table[3].ftr_ID == ftr_actor->id) { - return parent_ftr_actor->s_angle_y - my_room->parent_angleY; + if (my_room->parent_ftr.fit_ftr_table[0].ftr_ID == ftr_actor->id || + my_room->parent_ftr.fit_ftr_table[1].ftr_ID == ftr_actor->id || + my_room->parent_ftr.fit_ftr_table[2].ftr_ID == ftr_actor->id || + my_room->parent_ftr.fit_ftr_table[3].ftr_ID == ftr_actor->id) { + return parent_ftr_actor->s_angle_y - my_room->parent_ftr.angle_y; } } } diff --git a/src/ac_my_room_data.c_inc b/src/ac_my_room_data.c_inc index f1c70b22..883e56e5 100644 --- a/src/ac_my_room_data.c_inc +++ b/src/ac_my_room_data.c_inc @@ -74,31 +74,31 @@ static aMR_place_info_c* next_table[] = { NULL, NULL, NULL, NULL, &l_next_place_typeA, &l_next_place_typeC, }; -static xyz_t l_typeB_90_pattern[2] = { +static xyz_t l_typeB_90_pattarn[2] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 40.0f }, }; -static xyz_t l_typeB_180_pattern[2] = { +static xyz_t l_typeB_180_pattarn[2] = { { 0.0f, 0.0f, 0.0f }, { 40.0f, 0.0f, 0.0f }, }; -static xyz_t l_typeB_270_pattern[2] = { +static xyz_t l_typeB_270_pattarn[2] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, -40.0f }, }; -static xyz_t l_typeB_0_pattern[2] = { +static xyz_t l_typeB_0_pattarn[2] = { { 0.0f, 0.0f, 0.0f }, { -40.0f, 0.0f, 0.0f }, }; -static xyz_t* pattern_table[] = { - l_typeB_90_pattern, - l_typeB_180_pattern, - l_typeB_270_pattern, - l_typeB_0_pattern, +static xyz_t* pattarn_table[] = { + l_typeB_90_pattarn, + l_typeB_180_pattarn, + l_typeB_270_pattarn, + l_typeB_0_pattarn, }; // clang-format off diff --git a/src/ac_my_room_goki.c_inc b/src/ac_my_room_goki.c_inc new file mode 100644 index 00000000..da3bcb78 --- /dev/null +++ b/src/ac_my_room_goki.c_inc @@ -0,0 +1,247 @@ +extern void aMR_SetSurprise(ACTOR* actorx, s16 angle_y) { + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + my_room->request_player_surprise = TRUE; + my_room->player_surprise_angle_y = angle_y; + } +} + +static int aMR_MakeIndoorGoki(xyz_t* pos, s16 arg, s16 angle_y, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + ACTOR* actor = Actor_info_make_actor(&play->actor_info, game, mAc_PROFILE_HOUSE_GOKI, pos->x, pos->y, pos->z, 0, + angle_y, 0, -1, -1, -1, EMPTY_NO, arg, -1, -1); + + if (actor) { + return TRUE; + } + + return FALSE; +} + +typedef struct goki_info_s { + int scene; + int size; +} aMR_goki_info_c; + +static int aMR_RandomMakeIndoorGoki(s16 arg, GAME* game) { + // clang-format off + static aMR_goki_info_c goki_random_make_data[] = { + { SCENE_MY_ROOM_S, 4 }, + { SCENE_MY_ROOM_M, 6 }, + { SCENE_MY_ROOM_LL2, 6 }, + { SCENE_MY_ROOM_L, 8 }, + { SCENE_MY_ROOM_LL1, 8 }, + { SCENE_MY_ROOM_BASEMENT_S, 6 }, + { SCENE_MY_ROOM_BASEMENT_M, 6 }, + { SCENE_MY_ROOM_BASEMENT_L, 6 }, + { SCENE_MY_ROOM_BASEMENT_LL1, 6 }, + }; + // clang-format on + + int scene = Save_Get(scene_no); + int free_count0 = 0; + int free_count1 = 0; + mActor_name_t* fg_p = aMR_GetLayerTopFg(mCoBG_LAYER0); + + int i; + int sel_no; + int ut_x; + int ut_z; + + if (fg_p != NULL) { + for (i = 0; i < ARRAY_COUNT(goki_random_make_data); i++) { + if (scene == goki_random_make_data[i].scene) { + for (ut_z = 1; ut_z <= goki_random_make_data[i].size; ut_z++) { + for (ut_x = 1; ut_x <= goki_random_make_data[i].size; ut_x++) { + mActor_name_t item = fg_p[ut_x + ut_z * UT_X_NUM]; + + if (!ITEM_IS_FTR(item) && item != RSV_FE1F && item != RSV_NO && item != RSV_WALL_NO && + item != RSV_DOOR) { + free_count0++; + } + } + } + + if (free_count0 <= 0) { + return FALSE; + } + + sel_no = RANDOM(free_count0); + for (ut_z = 1; ut_z <= goki_random_make_data[i].size; ut_z++) { + for (ut_x = 1; ut_x <= goki_random_make_data[i].size; ut_x++) { + mActor_name_t item = fg_p[ut_x + ut_z * UT_X_NUM]; + + if (!ITEM_IS_FTR(item) && item != RSV_FE1F && item != RSV_NO && item != RSV_WALL_NO && + item != RSV_DOOR) { + if (sel_no == free_count1) { + xyz_t pos; + + if (mFI_UtNum2CenterWpos(&pos, ut_x, ut_z)) { + pos.y = 0.0f; + pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos(pos, 0.0f); + return aMR_MakeIndoorGoki(&pos, arg, 0, game); + } + } + + free_count1++; + } + } + } + } + } + } + + return FALSE; +} + +static void aMR_RequestPlayerBikkuri(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (my_room->request_player_surprise) { + if (mPlib_get_player_actor_main_index(gamePT) != mPlayer_INDEX_SHOCK) { + mPlib_request_main_shock_type1(gamePT, 20.0f, my_room->player_surprise_angle_y, FALSE); + } else { + my_room->request_player_surprise = FALSE; + } + } +} + +static void aMR_GokiInfoCt_Dummy(ACTOR* actorx, GAME* game) { + // nothing +} + +static void aMR_GokiInfoCt(ACTOR* actorx, GAME* game) { + int field_type = Common_Get(field_type); + GAME_PLAY* play = (GAME_PLAY*)game; + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int goki_count = mCkRh_NowSceneGokiFamilyCount(); + + mCkRh_InitCanLookGokiCount(); + if (goki_count != 0) { + int max; + int i; + + if (goki_count < aMR_GOKI_MAX) { + max = goki_count; + } else { + max = aMR_GOKI_MAX; + } + + for (i = 0; i < max; i++) { + if (i == 0) { + if (Save_Get(scene_no) == SCENE_MY_ROOM_S || Save_Get(scene_no) == SCENE_MY_ROOM_M || + Save_Get(scene_no) == SCENE_MY_ROOM_L || Save_Get(scene_no) == SCENE_MY_ROOM_LL1 || + Save_Get(scene_no) == SCENE_MY_ROOM_BASEMENT_S || Save_Get(scene_no) == SCENE_MY_ROOM_BASEMENT_M || + Save_Get(scene_no) == SCENE_MY_ROOM_BASEMENT_L || + Save_Get(scene_no) == SCENE_MY_ROOM_BASEMENT_LL1) { + static f32 off_x[] = { 10.0f, -10.0f, 15.0f, -15.0f }; + xyz_t pos = player->actor_class.world.position; + mActor_name_t* fg_p; + + pos.x += off_x[play->game_frame % ARRAY_COUNT(off_x)]; + pos.y = 0.0f; + pos.z += -10.0f; + pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(pos, 0.0f); + fg_p = mFI_GetUnitFG(pos); + + if (fg_p != NULL && !ITEM_IS_FTR(*fg_p) && *fg_p != RSV_FE1F && *fg_p != RSV_NO && + *fg_p != RSV_WALL_NO && *fg_p != RSV_DOOR) { + int spawned = aMR_MakeIndoorGoki(&pos, 0, DEG2SHORT_ANGLE(0.0f), game); + + if (spawned) { + mCkRh_CalcCanLookGokiCount(1); + mCkRh_MinusGokiN_NowRoom(1, my_room->scene); + if (Common_Get(goki_shocked_flag) == FALSE && field_type == mFI_FIELDTYPE2_PLAYER_ROOM) { + aMR_SetSurprise(actorx, DEG2SHORT_ANGLE(-180.0f)); + Common_Set(goki_shocked_flag, TRUE); + } + } + } + } + } else { + int spawned = aMR_RandomMakeIndoorGoki(0, game); + + if (spawned) { + mCkRh_CalcCanLookGokiCount(1); + mCkRh_MinusGokiN_NowRoom(1, my_room->scene); + if (Common_Get(goki_shocked_flag) == FALSE && field_type == mFI_FIELDTYPE2_PLAYER_ROOM) { + aMR_SetSurprise(actorx, DEG2SHORT_ANGLE(-180.0f)); + Common_Set(goki_shocked_flag, TRUE); + } + } + } + } + } + + my_room->goki_ct_proc = &aMR_GokiInfoCt_Dummy; +} + +static void aMR_MakeGokiburi(xyz_t* pos, GAME* game, s16 arg) { + if (mCkRh_NowSceneGokiFamilyCount() > 0 && mCkRh_GetCanLookGokiCount() < aMR_GOKI_MAX && + aMR_MakeIndoorGoki(pos, arg, DEG2SHORT_ANGLE(0.0f), game)) { + mCkRh_CalcCanLookGokiCount(1); + + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + mCkRh_MinusGokiN_NowRoom(1, my_room->scene); + } + } + } +} + +static void aMR_GokiInfoDt(void) { + if (aMR_CLIP != NULL) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + mCkRh_PlussGokiN_NowRoom(mCkRh_GetCanLookGokiCount(), my_room->scene); + } + } +} + +static int aMR_CheckFtrAndGoki2(aFTR_collision_c* ftr_col, const xyz_t* goki_pos) { + f32 check_pos[2]; + int i; + + check_pos[0] = goki_pos->x; + check_pos[1] = goki_pos->z; + + for (i = 0; i < aFTR_EDGE_COL_NUM; i++) { + aFTR_collision_c* col_p = &ftr_col[i]; + + if (mCoBG_GetPointInfoFrontLine(col_p->start, check_pos, col_p->normal)) { + return FALSE; + } + } + + return TRUE; +} + +static void aMR_CheckFtrAndGoki(ACTOR* actorx, FTR_ACTOR* ftr_actor, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + ACTOR* actor_p = play->actor_info.list[ACTOR_PART_BG].actor; + int count = 0; + + while (actor_p != NULL) { + if (actor_p->id == mAc_PROFILE_HOUSE_GOKI) { + if (aMR_CheckFtrAndGoki2(ftr_actor->edge_collision, &actor_p->world.position)) { + actor_p->actor_specific = 2; + } + + count++; + if (count >= aMR_GOKI_MAX) { + break; + } + } + + actor_p = actor_p->next_actor; + } +} diff --git a/src/ac_my_room_melody.c_inc b/src/ac_my_room_melody.c_inc new file mode 100644 index 00000000..d04fff3c --- /dev/null +++ b/src/ac_my_room_melody.c_inc @@ -0,0 +1,17 @@ +static void aMR_SetMelodyData(u8* melody_data) { + mRmTp_MakeMelodyData(); +} + +static u8* aMR_GetMelodyData(ACTOR* actorx) { + return mRmTp_GetMelodyData(); +} + +static void aMR_SoundMelody(FTR_ACTOR* ftr_actor, ACTOR* actorx, int idx) { + if (ftr_actor->switch_changed_flag) { + u8* melody_data = aMR_GetMelodyData(actorx); + + sAdo_FurnitureInst((u32)ftr_actor, idx, melody_data, &ftr_actor->position); + } + + sAdo_FurnitureInstPos((u32)ftr_actor, &ftr_actor->position); +} diff --git a/src/ac_my_room_move.c_inc b/src/ac_my_room_move.c_inc new file mode 100644 index 00000000..925e47e0 --- /dev/null +++ b/src/ac_my_room_move.c_inc @@ -0,0 +1,3304 @@ +#define aMR_IS_SHOP() (mFI_CheckShop() == TRUE || mFI_GetFieldId() == mFI_FIELD_ROOM_BROKER_SHOP) + +typedef struct process_info_s { + int unit_count; + s16 unit_ofs[4]; +} aMR_process_info_c; + +static aMR_process_info_c aMR_process_typeB90 = { 2, { 0, -UT_X_NUM, 0, 0 } }; +static aMR_process_info_c aMR_process_typeB180 = { 2, { 0, -1, 0, 0 } }; +static aMR_process_info_c aMR_process_typeB270 = { 2, { 0, UT_X_NUM, 0, 0 } }; +static aMR_process_info_c aMR_process_typeB0 = { 2, { 0, 1, 0, 0 } }; +static aMR_process_info_c aMR_process_typeA = { 1, { 0, 0, 0, 0 } }; +static aMR_process_info_c aMR_process_typeC = { 4, { 0, 1, UT_X_NUM, UT_X_NUM + 1 } }; + +static aMR_process_info_c* aMR_process_table[aFTR_SHAPE_TYPE_NUM] = { + &aMR_process_typeB90, &aMR_process_typeB180, &aMR_process_typeB270, + &aMR_process_typeB0, &aMR_process_typeA, &aMR_process_typeC, +}; + +static int aMR_GetFurniturePoccessUnitNo(int* ut_info, int ut_x, int ut_z, u8 type) { + if (ut_x < UT_X_NUM && ut_z < UT_Z_NUM) { + int ut = ut_x + ut_z * UT_X_NUM; + + if (type < aFTR_SHAPE_TYPE_NUM) { + aMR_process_info_c* process_info = aMR_process_table[type]; + int count = process_info->unit_count; + int i; + + if (ut_info != NULL) { + for (i = 0; i < 4; i++) { + ut_info[i] = ut + (int)process_info->unit_ofs[i]; + } + } + + return count; + } + } + + return 0; +} + +static int aMR_PosType2FurniturePoccessUnitNo(int* ut_info, const xyz_t* pos, u8 type) { + int x; + int z; + + if (type == aFTR_SHAPE_TYPEC) { + xyz_t t_pos = *pos; + + t_pos.x -= mFI_UT_WORLDSIZE_X_F; + t_pos.z -= mFI_UT_WORLDSIZE_Z_F; + + x = t_pos.x / mFI_UT_WORLDSIZE_X_F; + z = t_pos.z / mFI_UT_WORLDSIZE_Z_F; + } else { + x = pos->x / mFI_UT_WORLDSIZE_X_F; + z = pos->z / mFI_UT_WORLDSIZE_Z_F; + } + + return aMR_GetFurniturePoccessUnitNo(ut_info, x, z, type); +} + +static void aMR_RegistItemToFitFurniture(ACTOR* actorx, const xyz_t* base_pos, int ftrID, mActor_name_t* item_p, + s16 angle_y) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + aMR_fit_ftr_c* fit_ftr_p; + int i; + + /* Check that this furniture isn't already 'fitted' to the base furniture? */ + for (i = 0; i < aMR_FIT_FTR_MAX; i++) { + /* @BUG - isn't this supposed to be 'my_room->fit_ftr_table[i].ftr_ID' ? */ + if (my_room->parent_ftr.fit_ftr_table[0].ftr_ID != -1 && my_room->parent_ftr.fit_ftr_table[0].ftr_ID == ftrID) { + return; + } + } + + /* Search for a free index to fit this item */ + fit_ftr_p = my_room->parent_ftr.fit_ftr_table; + for (i = 0; i < aMR_FIT_FTR_MAX; i++, fit_ftr_p++) { + if (fit_ftr_p->exist_flag == FALSE) { + fit_ftr_p->exist_flag = TRUE; + fit_ftr_p->pos.x = base_pos->x; + fit_ftr_p->pos.y = base_pos->y; + fit_ftr_p->pos.z = base_pos->z; + fit_ftr_p->ftr_ID = ftrID; + fit_ftr_p->angle_y = angle_y; + + if (item_p != NULL) { + fit_ftr_p->item_no = *item_p; + *item_p = EMPTY_NO; + } else { + fit_ftr_p->item_no = EMPTY_NO; + } + + break; + } + } +} +static int aMR_RequestItemToFitFurniture(ACTOR* actorx, FTR_ACTOR* ftr_actor) { + // clang-format off + static aMR_fit_ftr_c init_data = { + FALSE, + { 0.0f, 0.0f, 0.0f }, + -1, + EMPTY_NO, + DEG2SHORT_ANGLE(0.0f), + { 0.0f, 0.0f, 0.0f } + }; + // clang-format on + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + aMR_parent_ftr_c* parent_ftr_p = &my_room->parent_ftr; + int i; + + if (parent_ftr_p->ftrID == -1) { + int ut_info[4]; + int ut_count; + xyz_t pos; + + /* Initialize fit furniture table */ + for (i = 0; i < aMR_FIT_FTR_MAX; i++) { + parent_ftr_p->fit_ftr_table[i] = init_data; + } + + /* Set the temporary parent furniture info */ + parent_ftr_p->ftrID = ftr_actor->id; + parent_ftr_p->angle_y = ftr_actor->s_angle_y; + + ut_count = aMR_PosType2FurniturePoccessUnitNo(ut_info, &ftr_actor->position, ftr_actor->shape_type); + if (ut_count != 0) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + f32 bg_y = mCoBG_GetBgY_OnlyCenter_FromWpos2(ftr_actor->position, 0.0f); + f32 height = profile->height; + f32 pos_y = height + bg_y; + mActor_name_t* fg_layer1_p = aMR_GetLayerTopFg(mCoBG_LAYER1); + + if (fg_layer1_p != NULL) { + for (i = 0; i < ut_count; i++) { + int ut_pos = ut_info[i]; /* absolute unit position */ + int ut_x = (ut_pos & 15); + int ut_z = (ut_pos >> 4) & 15; + mActor_name_t cur_item = fg_layer1_p[ut_pos]; + + if (cur_item != EMPTY_NO) { + if (ITEM_IS_FTR(cur_item)) { + mActor_name_t item; + int on_top_ftrID; + + if (aMR_UnitNum2FtrItemNoFtrID(&item, &on_top_ftrID, ut_x, ut_z, mCoBG_LAYER1)) { + FTR_ACTOR* on_top_ftr_actor = &l_aMR_work.ftr_actor_list[on_top_ftrID]; + + pos.x = + on_top_ftr_actor->position.x - (ftr_actor->position.x + ftr_actor->base_position.x); + pos.y = + on_top_ftr_actor->position.y - (ftr_actor->position.y + ftr_actor->base_position.y); + pos.z = + on_top_ftr_actor->position.z - (ftr_actor->position.z + ftr_actor->base_position.z); + Common_Get(clip).shop_goods_clip->single_set_angle_y_proc(ut_z, ut_x, mCoBG_LAYER1, + DEG2SHORT_ANGLE(0.0f)); + aMR_RegistItemToFitFurniture(actorx, &pos, on_top_ftrID, NULL, 0); + aMR_SetFurniture2FG(on_top_ftr_actor, on_top_ftr_actor->position, FALSE); + aMR_SetInfoFurnitureTable(aFTR_SHAPE_TYPEA, ut_x + ut_z * UT_X_NUM, aMR_NO_FTR_ID, + mCoBG_LAYER1); + } + } else { + s16 angle_y = DEG2SHORT_ANGLE(0.0f); + + if (Common_Get(clip).shop_goods_clip != NULL) { + angle_y = + Common_Get(clip).shop_goods_clip->single_get_angle_y_proc(ut_z, ut_x, mCoBG_LAYER1); + } + + pos.x = (ut_x * mFI_UT_WORLDSIZE_X_F + mFI_UT_WORLDSIZE_HALF_X_F) - + (ftr_actor->position.x + ftr_actor->base_position.x); + pos.y = pos_y - (ftr_actor->position.y + ftr_actor->base_position.y); + pos.z = (ut_z * mFI_UT_WORLDSIZE_Z_F + mFI_UT_WORLDSIZE_HALF_Z_F) - + (ftr_actor->position.z + ftr_actor->base_position.z); + + if (Common_Get(clip).shop_goods_clip != NULL) { + Common_Get(clip).shop_goods_clip->single_set_angle_y_proc(ut_z, ut_x, mCoBG_LAYER1, 0); + } + + aMR_RegistItemToFitFurniture(actorx, &pos, -1, &fg_layer1_p[ut_pos], angle_y); + } + } + } + + return TRUE; + } + } + } + + return FALSE; +} + +static void aMR_RequestItemToUnFitFurniture(MY_ROOM_ACTOR* my_room, FTR_ACTOR* ftr_actor) { + int ut; + int ut_x; + int ut_z; + int i; + aMR_fit_ftr_c* fit_ftr_p; + mActor_name_t* fg_layer1_p = aMR_GetLayerTopFg(mCoBG_LAYER1); + + if (my_room->parent_ftr.ftrID != -1 && fg_layer1_p != NULL) { + fit_ftr_p = my_room->parent_ftr.fit_ftr_table; + + for (i = 0; i < aMR_FIT_FTR_MAX; i++, fit_ftr_p++) { + if (fit_ftr_p->exist_flag == TRUE) { + + fit_ftr_p->exist_flag = FALSE; + ut_x = (int)(fit_ftr_p->ut_pos.x / mFI_UT_WORLDSIZE_X_F); + ut_z = (int)(fit_ftr_p->ut_pos.z / mFI_UT_WORLDSIZE_Z_F); + ut = ut_x + ut_z * UT_X_NUM; + + if (fit_ftr_p->ftr_ID != -1) { + FTR_ACTOR* on_top_ftr_actor = &l_aMR_work.ftr_actor_list[fit_ftr_p->ftr_ID]; + xyz_t center_pos; + s16 angle; + + fit_ftr_p->ftr_ID = -1; + mFI_Wpos2UtCenterWpos(¢er_pos, fit_ftr_p->ut_pos); + angle = ftr_actor->s_angle_y - my_room->parent_ftr.angle_y; + on_top_ftr_actor->s_angle_y += angle; + on_top_ftr_actor->angle_y = RAD2DEG(SHORT2RAD_ANGLE2(on_top_ftr_actor->s_angle_y)); + on_top_ftr_actor->angle_y_target = on_top_ftr_actor->angle_y; + on_top_ftr_actor->position = center_pos; + aMR_SetFurniture2FG(on_top_ftr_actor, on_top_ftr_actor->position, TRUE); + aMR_SetInfoFurnitureTable(aFTR_SHAPE_TYPEA, ut, on_top_ftr_actor->id, mCoBG_LAYER1); + } + + if (fit_ftr_p->item_no != EMPTY_NO) { + s16 ftr_angle = fit_ftr_p->angle_y + (ftr_actor->s_angle_y - my_room->parent_ftr.angle_y); + + fg_layer1_p[ut] = fit_ftr_p->item_no; + Common_Get(clip).shop_goods_clip->single_set_angle_y_proc(ut_z, ut_x, mCoBG_LAYER1, ftr_angle); + } + } + } + } + + my_room->parent_ftr.ftrID = -1; +} + +static void aMR_GetPlayerLookAtUnit(int* ut_x, int* ut_z, s16 angleY, int high_ofs) { + // clang-format off + static s16 unit_offset[16][2] = { + { 0, 1 }, + { 1, 1 }, + { 1, 1 }, + { 1, 0 }, + { 1, 0 }, + { 1, -1 }, + { 1, -1 }, + { 0, -1 }, + { 0, -1 }, + { -1, -1 }, + { -1, -1 }, + { -1, 0 }, + { -1, 0 }, + { -1, 1 }, + { -1, 1 }, + { 0, 1 } + }; + // clang-format on + int angle_idx = (angleY >> 12) & 0xF; // r8 + static int high_offset[8] = { 0, 2, -2, 4, -4, 6, -6, 8 }; + + if (high_ofs >= 0 && high_ofs < ARRAY_COUNT(high_offset)) { + high_ofs = angle_idx + high_offset[high_ofs]; + + (*ut_x) = (int)unit_offset[high_ofs & 0xF][0] + *ut_x; + (*ut_z) = (int)unit_offset[high_ofs & 0xF][1] + *ut_z; + } +} + +static void aMR_GetFtrShape4Position(xyz_t* p0, xyz_t* p1, xyz_t* p2, xyz_t* p3, FTR_ACTOR* ftr_actor) { + p0->x = ftr_actor->edge_collision[0].start[0]; + p0->y = ftr_actor->position.y; + p0->z = ftr_actor->edge_collision[0].start[1]; + + p1->x = ftr_actor->edge_collision[1].start[0]; + p1->y = ftr_actor->position.y; + p1->z = ftr_actor->edge_collision[1].start[1]; + + p2->x = ftr_actor->edge_collision[2].start[0]; + p2->y = ftr_actor->position.y; + p2->z = ftr_actor->edge_collision[2].start[1]; + + p3->x = ftr_actor->edge_collision[3].start[0]; + p3->y = ftr_actor->position.y; + p3->z = ftr_actor->edge_collision[3].start[1]; +} + +static void aMR_GetFtrShapeCenter(xyz_t* center, FTR_ACTOR* ftr_actor) { + static xyz_t center0 = { 0.0f, 0.0f, 0.0f }; + xyz_t p[4]; + + *center = center0; + aMR_GetFtrShape4Position(&p[0], &p[1], &p[2], &p[3], ftr_actor); + + center->x = (p[0].x + p[2].x) * 0.5f; + center->y = ftr_actor->position.y; + center->z = (p[0].z + p[2].z) * 0.5f; +} + +static void aMR_GetDust4Position(xyz_t* p0, xyz_t* p1, xyz_t* p2, xyz_t* p3, xyz_t* center, FTR_ACTOR* ftr_actor) { + xyz_t shape0; + xyz_t shape1; + xyz_t shape2; + xyz_t shape3; + + aMR_GetFtrShapeCenter(center, ftr_actor); + aMR_GetFtrShape4Position(&shape0, &shape1, &shape2, &shape3, ftr_actor); + + p0->x = center->x + (shape0.x - center->x) * 0.6f; + p0->y = shape0.y; + p0->z = center->z + (shape0.z - center->z) + 3.5f; + + p1->x = center->x + (shape1.x - center->x) * 0.6f; + p1->y = shape1.y; + p1->z = center->z + (shape1.z - center->z) + 3.5f; + + p2->x = center->x + (shape2.x - center->x) * 0.6f; + p2->y = shape2.y; + p2->z = center->z + (shape2.z - center->z) + 3.5f; + + p3->x = center->x + (shape3.x - center->x) * 0.6f; + p3->y = shape3.y; + p3->z = center->z + (shape3.z - center->z) + 3.5f; +} + +static s16 aMR_GetDustAngle(xyz_t* vec) { + if (vec->x > 0.0f) { + if (vec->z > 0.0f) { + return DEG2SHORT_ANGLE(45.0f); + } else { + return DEG2SHORT_ANGLE(135.0f); + } + } else { + if (vec->z > 0.0f) { + return DEG2SHORT_ANGLE(-90.0f); + } else { + return DEG2SHORT_ANGLE(-135.0f); + } + } +} + +static int aMR_CheckReserveFlag(MY_ROOM_ACTOR* my_room, int flag) { + int i; + + for (i = 0; i < aMR_RSV_FTR_NUM; i++) { + if (my_room->rsv_ftr[i].exist_flag == flag) { + return TRUE; + } + } + + return FALSE; +} + +static void aMR_SetCleanUpFtrSE(xyz_t pos) { + sAdo_OngenTrgStart(NA_SE_CLEAN_UP_FTR, &pos); +} + +static int aMR_GetPlayerDirect(const f32* normal_xz) { + if (normal_xz[0] > (F_PI / 4.0f)) { + return aMR_DIRECT_LEFT; + } + + if (normal_xz[0] < -(F_PI / 4.0f)) { + return aMR_DIRECT_RIGHT; + } + + if (normal_xz[1] > (F_PI / 4.0f)) { + return aMR_DIRECT_UP; + } + + if (normal_xz[1] < -(F_PI / 4.0f)) { + return aMR_DIRECT_DOWN; + } + + // default case + return aMR_DIRECT_UP; +} + +static void aMR_MoveShapeCenter(FTR_ACTOR* ftr_actor) { + xyz_t* pattern = pattarn_table[ftr_actor->original_shape_type]; + xyz_t* base = &ftr_actor->base_position; + int i; + + for (i = 0; i < 2; i++) { + if (base->x == pattern[i].x && base->z == pattern[i].z) { + int idx = (i ^ 1) & 1; + + base->x = pattern[idx].x; + base->z = pattern[idx].z; + break; + } + } +} + +static int aMR_Norm2DirectName(f32* normal_xz) { + if (normal_xz[0] > (F_PI / 4.0f)) { + return aMR_DIRECT_RIGHT; + } + + if (normal_xz[0] <= -(F_PI / 4.0f)) { + return aMR_DIRECT_LEFT; + } + + if (normal_xz[1] > (F_PI / 4.0f)) { + return aMR_DIRECT_DOWN; + } + + if (normal_xz[1] <= -(F_PI / 4.0f)) { + return aMR_DIRECT_UP; + } + + // default case + return aMR_DIRECT_UP; +} + +static void aMR_RotateY(f32* xz, f32 amount) { + f32 cos = cosf_table(amount); + f32 sin = sinf_table(amount); + f32 x = xz[0]; + f32 z = xz[1]; + + xz[0] = x * cos + z * sin; + xz[1] = -x * sin + z * cos; +} + +static int aMR_Get3dDirectStatus(int direct) { + static f32 direct_vector[aMR_DIRECT_NUM][2] = { + { 0.0f, 1.0f }, /* aMR_DIRECT_UP */ + { -1.0f, 0.0f }, /* aMR_DIRECT_LEFT */ + { 0.0f, -1.0f }, /* aMR_DIRECT_DOWN */ + { 1.0f, 0.0f } /* aMR_DIRECT_RIGHT */ + }; + + f32 point_xz[2]; + f32 vec_xz[2]; + f32 cross0_xz[2]; + f32 cross1_xz[2]; + f32 center_xz[2] = { 0.0f, 0.0f }; + + if (direct >= 0 && direct < aMR_DIRECT_NUM) { + point_xz[0] = direct_vector[direct][0] * 0.8f; + point_xz[1] = direct_vector[direct][1] * 0.8f; + vec_xz[0] = -direct_vector[direct][1]; + vec_xz[1] = direct_vector[direct][0]; + + if (mCoBG_GetCrossCircleAndLine2Dvector(cross0_xz, cross1_xz, point_xz, vec_xz, center_xz, 1.0f)) { + f32 vec0[2]; + f32 vec1[2]; + f32 vec2[2]; + + f32 pX = gamePT->mcon.move_pX; + f32 pZ = gamePT->mcon.move_pY; + + f32 m0; + f32 m1; + + vec0[0] = center_xz[0] - pX; + vec0[1] = center_xz[1] - pZ; + + vec1[0] = 2.0f * cross1_xz[0] - pX; + vec1[1] = 2.0f * cross1_xz[1] - pZ; + + vec2[0] = 2.0f * cross0_xz[0] - pX; + vec2[1] = 2.0f * cross0_xz[1] - pZ; + + m0 = mCoBG_GetVectorProductin2D(vec0, vec1) * mCoBG_GetVectorProductin2D(vec0, vec2); + m1 = mCoBG_GetVectorProductin2D(vec1, vec2) * mCoBG_GetVectorProductin2D(vec1, vec0); + + if (m0 <= 0.0f && m1 <= 0.0f) { + if (gamePT->mcon.move_pR >= 0.8f) { + return 1; + } else { + return 0; + } + } + + if (gamePT->mcon.move_pR <= 0.1f) { + return 0; + } + } + } + + return 2; +} + +static int aMR_3DStickNuetral(void) { + if (gamePT->mcon.move_pR < 0.1f) { + return TRUE; + } + + return FALSE; +} + +static u8 aMR_JudgeStickFull(int direct, GAME* game) { + if (gamePT->mcon.move_pR >= 0.8f) { + f32 mX = gamePT->mcon.move_pX; + f32 mZ = gamePT->mcon.move_pY; + + switch (direct) { + case aMR_DIRECT_UP: + if (mZ > 0.8f) { + return TRUE; + } + break; + case aMR_DIRECT_LEFT: + if (mX < -0.8f) { + return TRUE; + } + break; + case aMR_DIRECT_DOWN: + if (mZ < -0.8f) { + return TRUE; + } + break; + case aMR_DIRECT_RIGHT: + if (mX > 0.8f) { + return TRUE; + } + break; + default: + return FALSE; + } + } + + return FALSE; +} + +static int aMR_JudgeFurnitureMove(u8 type, int ut) { + mActor_name_t* fg_p = aMR_GetLayerTopFg(mCoBG_LAYER0); + u8* place_table = aMR_place_table[mCoBG_LAYER0]; + int ut_info[4]; + int count = aMR_GetFurniturePoccessUnitNo(ut_info, (ut & 0xF), ((ut >> 4) & 0xF), type); + + if (count > 0) { + int i; + + for (i = 0; i < count; i++) { + if (place_table[ut_info[i]] != 200) { + return FALSE; + } + + if (fg_p[ut_info[i]] != EMPTY_NO) { + return FALSE; + } + } + + return TRUE; + } + + return TRUE; +} + +static void aMR_ContactRange(aMR_contact_info_c* contact_info, f32* start_xz, f32* end_xz, f32 percent, f32* point) { + f32 diffX = end_xz[0] - start_xz[0]; + f32 diffZ = end_xz[1] - start_xz[1]; + f32 contact_percent = 0.0f; + f32 cross_xz[2]; + + if (mCoBG_GetCrossLineAndPerpendicular(cross_xz, start_xz, end_xz, point)) { + if (diffX != 0.0f) { + contact_percent = (cross_xz[0] - start_xz[0]) / diffX; + } else if (diffZ != 0.0f) { + contact_percent = (cross_xz[1] - start_xz[1]) / diffZ; + } + + contact_info->contact_percent = contact_percent; + if (contact_percent < percent) { + contact_info->contact_side = aMR_CONTACT_RIGHT; + } else if (contact_percent > (1.0f - percent)) { + contact_info->contact_side = aMR_CONTACT_LEFT; + } else { + contact_info->contact_side = aMR_CONTACT_CENTER; + } + } +} + +static int aMR_SearchContactPartName(FTR_ACTOR* ftr_actor, aMR_contact_info_c* contact_info) { + static s16 direct_table[aMR_DIRECT_NUM] = { + DEG2SHORT_ANGLE(-180.0f), + DEG2SHORT_ANGLE(-90.0f), + DEG2SHORT_ANGLE(0.0f), + DEG2SHORT_ANGLE(90.0f), + }; + + s16 ftr_angle_y = RAD2SHORT_ANGLE2(DEG2RAD(ftr_actor->angle_y)); + s16 direct_angle = direct_table[contact_info->direction & 3]; + s16 angle = direct_angle - ftr_angle_y; + int i; + + for (i = 0; i < aMR_DIRECT_NUM; i++) { + if (ABS(direct_table[i] - angle) < 5) { + return i; + } + } + + return aMR_DIRECT_UP; +} + +static int aMR_ContactCheck(int ftrID, FTR_ACTOR* ftr_actor, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + f32* point_xz) { + aFTR_collision_c* ftr_col = ftr_actor->edge_collision; + + if (ftr_actor->bg_contact.side_count != 0) { + int i; + + for (i = 0; i < aFTR_EDGE_COL_NUM; i++) { + f32* start_xz = ftr_col[i].start; + f32* end_xz = ftr_col[i].end; + f32* norm = ftr_col[i].normal; + f32 edge_contact_ratio = ftr_col[i].edge_contact_ratio; + f32 dist; + + if (ftr_actor->player_distance <= 100.0f && mCoBG_RangeCheckLinePoint(start_xz, end_xz, point_xz)) { + mCoBG_GetDistPointAndLine2D_Norm(&dist, start_xz, end_xz, norm, point_xz); + + if (dist < 20.5f) { + f32 vec[2] = { 0.0f, -1.0f }; + f32 player_angle = SHORT2RAD_ANGLE2(player->actor_class.shape_info.rotation.y); + f32 angle; + + aMR_RotateY(vec, player_angle); + angle = ABS(mCoBG_Get2VectorAngleF(norm, vec, 1)); + + if (angle < 60.0f) { + aMR_ContactRange(contact_info, start_xz, end_xz, edge_contact_ratio, point_xz); + contact_info->contact_flag = TRUE; + contact_info->ftrID = ftrID; + contact_info->normal_p = norm; + contact_info->direction = aMR_Norm2DirectName(norm); + contact_info->contact_edge_start[0] = start_xz[0]; + contact_info->contact_edge_start[1] = start_xz[1]; + contact_info->contact_edge_end[0] = end_xz[0]; + contact_info->contact_edge_end[1] = end_xz[1]; + contact_info->contact_direction = aMR_SearchContactPartName(ftr_actor, contact_info); + return TRUE; + } + } + } + } + } + + return FALSE; +} + +static void aMR_MakeContactData(aMR_contact_info_c* contact_info, s16 layer, u8 action, f32* point_xz, + PLAYER_ACTOR* player) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL && ftr_actor->layer == layer) { + if (action == 0) { + if (profile->contact_action == 0) { + aMR_ContactCheck(i, ftr_actor, contact_info, player, point_xz); + } + } else if ((profile->contact_action & action) != 0) { + aMR_ContactCheck(i, ftr_actor, contact_info, player, point_xz); + } + } + } + + ftr_actor++; + used++; + } +} + +static int aMR_GroundFlat(xyz_t* pos) { + mCoBG_Collision_u* col = mFI_GetUnitCol(*pos); + + if (col->data.center == col->data.top_left && col->data.center == col->data.bot_left && + col->data.center == col->data.top_right && col->data.center == col->data.bot_right) { + return TRUE; + } + + return FALSE; +} + +static void aMR_AllContactCheck(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info0, + aMR_contact_info_c* contact_info1, PLAYER_ACTOR* player) { + f32 point[2]; + + contact_info0->ftrID = 0; + contact_info0->contact_flag = FALSE; + point[0] = player->actor_class.world.position.x; + point[1] = player->actor_class.world.position.z; + contact_info1->ftrID = 0; + contact_info1->contact_flag = FALSE; + + if (aMR_GroundFlat(&player->actor_class.world.position)) { + /* Process standard collision first */ + aMR_MakeContactData(contact_info0, mCoBG_LAYER0, aFTR_CONTACT_ACTION_NONE, point, player); + + /* Process seat collision next */ + aMR_MakeContactData(contact_info0, mCoBG_LAYER0, + aFTR_CONTACT_ACTION_CHAIR_UNIDIRECTIONAL | aFTR_CONTACT_ACTION_CHAIR_MULTIDIRECTIONAL | + aFTR_CONTACT_ACTION_CHAIR_SOFA, + point, player); + /* Finally, process bed collision */ + aMR_MakeContactData(contact_info0, mCoBG_LAYER0, + aFTR_CONTACT_ACTION_BED_SINGLE | aFTR_CONTACT_ACTION_BED_DOUBLE, point, player); + + /* We collided with something, so process collisions for the secondary layer */ + if (contact_info0->contact_flag == TRUE) { + /* Process standard collision first */ + aMR_MakeContactData(contact_info1, mCoBG_LAYER1, aFTR_CONTACT_ACTION_NONE, point, player); + + /* Process seat collision next */ + aMR_MakeContactData(contact_info1, mCoBG_LAYER1, + aFTR_CONTACT_ACTION_CHAIR_UNIDIRECTIONAL | aFTR_CONTACT_ACTION_CHAIR_MULTIDIRECTIONAL | + aFTR_CONTACT_ACTION_CHAIR_SOFA, + point, player); + /* Finally, process bed collision */ + aMR_MakeContactData(contact_info1, mCoBG_LAYER1, + aFTR_CONTACT_ACTION_BED_SINGLE | aFTR_CONTACT_ACTION_BED_DOUBLE, point, player); + } + } +} + +extern cKF_Animation_R_c cKF_ba_r_furniture_pull; + +static void aMR_SetPullMoveAnime(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room, + aMR_contact_info_c* contact_info) { + cKF_SkeletonInfo_R_c* keyframe = &my_room->keyframe; + xyz_t* pos = &ftr_actor->position; + static s16 move_angle_table[aMR_DIRECT_NUM] = { + DEG2SHORT_ANGLE(-180.0f), + DEG2SHORT_ANGLE(-90.0f), + DEG2SHORT_ANGLE(0.0f), + DEG2SHORT_ANGLE(90.0f), + }; + + my_room->move_angle = move_angle_table[aMR_GetPlayerDirect(contact_info->normal_p)]; + cKF_SkeletonInfo_R_init_standard_stop(keyframe, &cKF_ba_r_furniture_stop, NULL); + cKF_SkeletonInfo_R_play(keyframe); + cKF_SkeletonInfo_R_Animation_Set_base_shape_trs(keyframe, 0.0f, 0.0f, 0.0f, 0, 0, 0); + cKF_SkeletonInfo_R_AnimationMove_ct_base(0.0f, pos, pos, 0, 0, keyframe, TRUE); + cKF_SkeletonInfo_R_init_standard_stop_morph(keyframe, &cKF_ba_r_furniture_pull, NULL, -3.0f); + cKF_SkeletonInfo_R_play(keyframe); +} + +extern cKF_Animation_R_c cKF_ba_r_furniture_push; + +static void aMR_SetPushMoveAnime(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room, + aMR_contact_info_c* contact_info) { + cKF_SkeletonInfo_R_c* keyframe = &my_room->keyframe; + xyz_t* pos = &ftr_actor->position; + static s16 move_angle_table[aMR_DIRECT_NUM] = { + DEG2SHORT_ANGLE(-180.0f), + DEG2SHORT_ANGLE(-90.0f), + DEG2SHORT_ANGLE(0.0f), + DEG2SHORT_ANGLE(90.0f), + }; + + my_room->move_angle = move_angle_table[aMR_GetPlayerDirect(contact_info->normal_p)]; + cKF_SkeletonInfo_R_init_standard_stop(keyframe, &cKF_ba_r_furniture_stop, NULL); + cKF_SkeletonInfo_R_play(keyframe); + cKF_SkeletonInfo_R_Animation_Set_base_shape_trs(keyframe, 0.0f, 0.0f, 0.0f, 0, 0, 0); + cKF_SkeletonInfo_R_AnimationMove_ct_base(0.0f, pos, pos, 0, 0, keyframe, TRUE); + cKF_SkeletonInfo_R_init_standard_stop(keyframe, &cKF_ba_r_furniture_push, NULL); + cKF_SkeletonInfo_R_play(keyframe); +} + +/* @TODO - likely fakematch */ +static int aMR_SelectNicePoint(f32* nice_point, xyz_t player_pos, f32* start_xz, f32* end_xz, + aMR_contact_info_c* contact_info) { + f32 diff_x; + f32 diff_z; + f32 contact_percent; + + diff_x = end_xz[0] - start_xz[0]; + diff_z = end_xz[1] - start_xz[1]; + contact_percent = contact_info->contact_percent; + + if (contact_percent > 0.75f) { + diff_x = end_xz[0] - start_xz[0]; + diff_z = end_xz[1] - start_xz[1]; + nice_point[0] = start_xz[0] + diff_x * 0.75f; + nice_point[1] = start_xz[1] + diff_z * 0.75f; + return TRUE; + } + + if (contact_percent < 0.25f) { + nice_point[0] = start_xz[0] + diff_x * 0.25f; + nice_point[1] = start_xz[1] + diff_z * 0.25f; + return TRUE; + } + + return FALSE; +} + +static void aMR_SetNicePos(xyz_t* nice_pos, xyz_t player_pos, f32* col_start_xz, f32* col_end_xz, + aMR_contact_info_c* contact_info, int type) { + f32 nice_point[2]; + f32* norm; + + norm = contact_info->normal_p; + *nice_pos = player_pos; + + switch (type) { + case 1: + case 2: { + if (col_start_xz[0] == col_end_xz[0]) { + f32 len_z = ABS(col_start_xz[1] - col_end_xz[1]); + + if (len_z > mFI_UT_WORLDSIZE_Z_F) { + if (aMR_SelectNicePoint(nice_point, player_pos, col_start_xz, col_end_xz, contact_info)) { + nice_pos->z = nice_point[1]; + } + } else { + nice_pos->z = (col_start_xz[1] + col_end_xz[1]) * 0.5f; + } + } else if (col_start_xz[1] == col_end_xz[1]) { + f32 len_x = ABS(col_start_xz[0] - col_end_xz[0]); + + if (len_x > mFI_UT_WORLDSIZE_X_F) { + if (aMR_SelectNicePoint(nice_point, player_pos, col_start_xz, col_end_xz, contact_info)) { + nice_pos->x = nice_point[0]; + } + } else { + nice_pos->x = (col_start_xz[0] + col_end_xz[0]) * 0.5f; + } + } + break; + } + + case 0: { + if (col_start_xz[0] == col_end_xz[0]) { + nice_pos->z = (col_start_xz[1] + col_end_xz[1]) * 0.5f; + + if (norm[0] > 0.0f) { + nice_pos->x = col_start_xz[0] + mFI_UT_WORLDSIZE_HALF_X_F; + } else { + nice_pos->x = col_start_xz[0] - mFI_UT_WORLDSIZE_HALF_X_F; + } + } else if (col_start_xz[1] == col_end_xz[1]) { + nice_pos->x = (col_start_xz[0] + col_end_xz[0]) * 0.5f; + + if (norm[1] > 0.0f) { + nice_pos->z = col_start_xz[1] + mFI_UT_WORLDSIZE_HALF_Z_F; + } else { + nice_pos->z = col_start_xz[1] - mFI_UT_WORLDSIZE_HALF_Z_F; + } + } + + break; + } + } +} + +static int aMR_FtrIdx2ChangeFtrSwitch(ACTOR* actorx, int ftrID) { + if (l_aMR_work.ftr_actor_list != NULL && l_aMR_work.used_list != NULL) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_HANIWA)) { + if (ftr_actor->switch_bit == FALSE) { + aMR_HaniwaSwitchOn(actorx, ftr_actor); + return TRUE; + } else { + ftr_actor->switch_changed_flag = TRUE; + aMR_OperateSwitchBit(ftr_actor); + aMR_HaniwaOffReport(actorx, ftr_actor->id); + return TRUE; + } + } else if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK)) { + if (ftr_actor->items[0] != EMPTY_NO && + (ftr_actor->items[0] >= ITM_MINIDISK_START && ftr_actor->items[0] <= ITM_MINIDISK_END)) { + if (ftr_actor->switch_bit == FALSE) { + ftr_actor->switch_changed_flag = TRUE; + ftr_actor->switch_bit = TRUE; + aMR_OneMDSwitchOn_TheOtherSwitchOff(ftr_actor); + aMR_ReserveBgm(actorx, BGM_MD0 + (ftr_actor->items[0] - ITM_MINIDISK_START), ftr_actor, 30); + sAdo_OngenTrgStart(NA_SE_LIGHT_ON, &ftr_actor->position); + return TRUE; + } else { + ftr_actor->switch_changed_flag = TRUE; + ftr_actor->switch_bit = FALSE; + aMR_AllMDSwitchOff(); + aMR_ReserveDefaultBgm(actorx, ftr_actor); + aMR_ChangeMDBgm(actorx, ftr_actor); + sAdo_OngenTrgStart(NA_SE_LIGHT_OFF, &ftr_actor->position); + return TRUE; + } + } + } else if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_RADIO_AEROBICS)) { + ftr_actor->switch_changed_flag = TRUE; + aMR_OperateSwitchBit(ftr_actor); + + if (ftr_actor->switch_bit == TRUE) { + sAdo_OngenTrgStart(NA_SE_LIGHT_ON, &ftr_actor->position); + } else { + sAdo_OngenTrgStart(NA_SE_LIGHT_OFF, &ftr_actor->position); + } + + return TRUE; + } else { + ftr_actor->switch_changed_flag = TRUE; + aMR_OperateSwitchBit(ftr_actor); + return TRUE; + } + } + + return FALSE; +} + +static void aMR_RequestForceOpenDemo(MY_ROOM_ACTOR* my_room) { + my_room->state = 8; + my_room->force_open_demo_flag = TRUE; +} + +static int aMR_GetPlayerRoomIdx(void) { + mActor_name_t field_id = mFI_GetFieldId(); + + if (mFI_GET_TYPE(field_id) == mFI_FIELD_PLAYER0_ROOM) { + return mFI_GET_PLAYER_ROOM_NO(field_id); + } + + return 0; +} + +static int aMR_CheckDiaryOnMe(FTR_ACTOR* ftr_actor, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + mActor_name_t* fg_layer1_p = aMR_GetLayerTopFg(mCoBG_LAYER1); + + if (ftr_actor->layer == mCoBG_LAYER0 && aMR_layer_set_info[ftr_actor->name] == aFTR_SET_TYPE_SURFACE && + fg_layer1_p != NULL) { + int ut_info[4]; + int ut_count = aMR_PosType2FurniturePoccessUnitNo(ut_info, &ftr_actor->position, ftr_actor->shape_type); + + if (ut_count != 0) { + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + xyz_t pos = { 0.0f, 0.0f, 0.0f }; + int i; + + for (i = 0; i < ut_count; i++) { + int ut = ut_info[i]; + + if (fg_layer1_p[ut] >= ITM_DIARY_START && fg_layer1_p[ut] <= ITM_DIARY15) { + int ut_x = ut & 0xF; + int ut_z = (ut >> 4) & 0xF; + f32 x = ut_x * mFI_UT_WORLDSIZE_X_F + mFI_UT_WORLDSIZE_HALF_X_F; + f32 z = ut_z * mFI_UT_WORLDSIZE_Z_F + mFI_UT_WORLDSIZE_HALF_Z_F; + + pos.x = x; + pos.z = z; + + if (ABS(pos.x - player->actor_class.world.position.x) < 12.0f || + ABS(pos.z - player->actor_class.world.position.z) < 12.0f) { + return TRUE; + } + } + } + } + } + + return FALSE; +} + +static int aMR_ManageMoveBottun(MY_ROOM_ACTOR* my_room, GAME* game, aMR_contact_info_c* contact_info0, + aMR_contact_info_c* contact_info1) { + aMR_contact_info_c* contact; + u8* field_type; + ACTOR* actorx = (ACTOR*)my_room; + GAME_PLAY* play = (GAME_PLAY*)game; + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + xyz_t nice_pos = player->actor_class.world.position; + int i; + FTR_ACTOR* ftr_actor; + aFTR_PROFILE* profile; + FTR_ACTOR* md_ftr_actor; + FTR_ACTOR* ftr_actor2; + int state; + u16 ftr_idx; + int player_no; + Submenu* submenu; + + if (my_room->room_msg_flag == TRUE) { + return FALSE; + } + + if (my_room->force_open_demo_flag == TRUE) { + my_room->state = 8; + return FALSE; + } + + if (chkTrigger(BUTTON_A) && !chkTrigger(BUTTON_B) && !chkTrigger(BUTTON_B) && my_room->demo_flag == FALSE && + my_room->msg_type == aMR_MSG_STATE_NONE) { + if (contact_info0->contact_flag == TRUE && contact_info0->contact_side == aMR_CONTACT_CENTER && + my_room->state == 0) { + ftr_actor2 = &l_aMR_work.ftr_actor_list[contact_info0->ftrID]; + state = ftr_actor2->state; + if (state == aFTR_STATE_BYE || state == aFTR_STATE_BIRTH_WAIT || ftr_actor2->state == aFTR_STATE_BIRTH || + ftr_actor2->state == aFTR_STATE_DEATH) { + return FALSE; + } + + aMR_SetNicePos(&nice_pos, player->actor_class.world.position, contact_info0->contact_edge_start, + contact_info0->contact_edge_end, contact_info0, 1); + my_room->nice_pos = nice_pos; + + if (mPlib_request_main_hold_type1(game, contact_info0->ftrID, aMR_GetPlayerDirect(contact_info0->normal_p), + &nice_pos)) { + my_room->state = 1; + my_room->switch_timer = 0; + } + } + } else if (chkButton(BUTTON_A) && !chkTrigger(BUTTON_B) && !chkTrigger(BUTTON_B) && my_room->demo_flag == FALSE && + my_room->msg_type == aMR_MSG_STATE_NONE) { + if (my_room->state == 1 || my_room->state == 6) { + if (my_room->switch_timer < 14) { + my_room->switch_timer++; + } + } + } else if (!chkButton(BUTTON_A) && my_room->demo_flag == FALSE && my_room->msg_type == aMR_MSG_STATE_NONE) { + if (my_room->state == 1 || my_room->state == 6) { + if (my_room->switch_timer < 14) { + field_type = Common_GetPointer(field_type); + for (i = 1; i >= 0; i--) { + if (i == 1) { + contact = contact_info1; + } else { + contact = contact_info0; + } + + ftr_actor = &l_aMR_work.ftr_actor_list[contact->ftrID]; + profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (contact->contact_flag == TRUE && profile != NULL) { + ftr_idx = ftr_actor->name; + + if (aMR_CheckDiaryOnMe(ftr_actor, game)) { + if (mSc_IS_SCENE_PLAYER_HOUSE_ROOM(Save_Get(scene_no))) { + player_no = mHS_get_pl_no_detail(aMR_GetPlayerRoomIdx()); + + if (player_no != -1) { + submenu = &play->submenu; + my_room->state = 0; + mSM_open_submenu(submenu, mSM_OVL_CALENDAR, 0, player_no); + return TRUE; + } + } + } else if (ftr_idx == 0x4A0) { /* Super Tortimer */ + if (aMR_FtrIdx2ChangeFtrSwitch(actorx, contact->ftrID)) { + my_room->requested_msg_type = aMR_MSG_STATE_HITOKOTO2; + return TRUE; + } + } else if (ftr_idx == 0x411) { /* lovely phone */ + if (aMR_FtrIdx2ChangeFtrSwitch(actorx, contact->ftrID)) { + my_room->requested_msg_type = aMR_MSG_STATE_HITOKOTO; + sAdo_OngenTrgStart(NA_SE_166, &ftr_actor->position); + return TRUE; + } + } else if (ftr_idx == 0x415) { /* tanabata palm */ + if (aMR_FtrIdx2ChangeFtrSwitch(actorx, contact->ftrID)) { + my_room->requested_msg_type = aMR_MSG_STATE_HITOKOTO1; + return TRUE; + } + } else if (aFTR_CHECK_INTERACTION(profile->interaction_type, + aFTR_INTERACTION_TYPE_RADIO_AEROBICS)) { + /* Only active the aerobics radio if interacted with from its 'down' (front) side */ + if (contact->contact_direction == aMR_CONTACT_DIR_FRONT && + aMR_FtrIdx2ChangeFtrSwitch(actorx, contact->ftrID)) { + my_room->state = 0; + return TRUE; + } + } else if (aFTR_CHECK_INTERACTION(profile->interaction_type, + aFTR_INTERACTION_TYPE_MUSIC_DISK)) { + if (*field_type == mFI_FIELDTYPE2_PLAYER_ROOM) { + /* Only active the music player if interacted with from its 'down' (front) side */ + if (contact->contact_direction == aMR_CONTACT_DIR_FRONT && + ftr_actor->demo_status == 0) { + aMR_SetMDFtrDemoData(my_room, ftr_actor, contact); + my_room->switch_timer = 14; + return TRUE; + } + } else if (!aMR_IS_SHOP()) { + if (ftr_actor->demo_status == 0 && + contact->contact_direction == aMR_CONTACT_DIR_FRONT) { + md_ftr_actor = &l_aMR_work.ftr_actor_list[contact->ftrID]; + + if (md_ftr_actor->switch_bit == TRUE) { + aMR_SetMDFtrDemoData(my_room, md_ftr_actor, contact); + my_room->switch_timer = 14; + return TRUE; + } else if (md_ftr_actor->items[0] == EMPTY_NO) { + aMR_SetMDFtrDemoData(my_room, md_ftr_actor, contact); + my_room->switch_timer = 14; + return TRUE; + + } else { + aMR_FtrIdx2ChangeFtrSwitch(actorx, contact->ftrID); + my_room->state = 0; + return TRUE; + } + } + } + } else if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_FAMICOM) || + aFTR_CHECK_INTERACTION(profile->interaction_type, + aFTR_INTERACTION_TYPE_FAMICOM_ITEM)) { + aMR_FtrIdx2ChangeFtrSwitch(actorx, contact->ftrID); + my_room->switch_timer = 14; + return TRUE; + } else if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_WARDROBE) || + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_CLOSET)) { + if (contact->contact_direction == aMR_CONTACT_DIR_FRONT && ftr_actor->demo_status == 0) { + aMR_RequestForceOpenDemo(my_room); + return TRUE; + } + } else if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_DRAWERS)) { + if (contact->contact_direction == aMR_CONTACT_DIR_FRONT && ftr_actor->demo_status == 0) { + if (profile->shape == aFTR_SHAPE_TYPEA) { + aMR_RequestForceOpenDemo(my_room); + return TRUE; + } else if (aMR_CheckHikidashi(ftr_actor, player, contact)) { + aMR_RequestForceOpenDemo(my_room); + return TRUE; + } + } + } else if (ftr_actor->name == 0x3F6) { /* Mouth of Truth */ + if (contact->contact_direction == aMR_CONTACT_DIR_FRONT && + aMR_FtrIdx2ChangeFtrSwitch(actorx, contact->ftrID)) { + my_room->state = 0; + return TRUE; + } + } else if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_TOGGLE)) { + if (aMR_FtrIdx2ChangeFtrSwitch(actorx, contact->ftrID)) { + my_room->state = 0; + + if (ftr_actor->switch_bit == TRUE) { + sAdo_OngenTrgStart(NA_SE_LIGHT_ON, &ftr_actor->position); + } else { + sAdo_OngenTrgStart(NA_SE_LIGHT_OFF, &ftr_actor->position); + } + + return TRUE; + } + } else { + if (aMR_FtrIdx2ChangeFtrSwitch(actorx, contact->ftrID)) { + my_room->state = 0; + return TRUE; + } + } + } + } + } + } else { + my_room->switch_timer = 14; + } + + if (my_room->state == 1 || my_room->state == 6 || my_room->state == 7 || my_room->state == 8) { + my_room->state = 0; + } + + if (my_room->pull_bubu == TRUE) { + my_room->state = 6; + my_room->pull_bubu = FALSE; + } + + if (my_room->push_bubu == TRUE) { + my_room->state = 6; + my_room->push_bubu = FALSE; + } + } + + if (my_room->state == 0) { + my_room->push_timer = 0; + my_room->pull_timer = 0; + my_room->keep_push_flag = FALSE; + my_room->keep_pull_flag = FALSE; + } + + return FALSE; +} + +static int aMR_PullDirect2PushDirect(int pull_direct) { + static int push_target_d_table[] = { + aMR_DIRECT_DOWN, /* aMR_DIRECT_UP */ + aMR_DIRECT_RIGHT, /* aMR_DIRECT_LEFT */ + aMR_DIRECT_UP, /* aMR_DIRECT_DOWN */ + aMR_DIRECT_LEFT, /* aMR_DIRECT_RIGHT */ + }; + + return push_target_d_table[pull_direct & 3]; +} + +static void aMR_MngPullDirectTimer(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + GAME* game) { + if (my_room->pull_timer > 20000) { + my_room->pull_timer = 20000; + } + + if (my_room->pull_bubu == TRUE) { + if (aMR_Get3dDirectStatus(contact_info->direction) != 1) { + my_room->pull_timer = 0; + my_room->state = 6; + my_room->pull_bubu = FALSE; + return; + } else { + my_room->state = 8; + } + } else if (contact_info->ftrID >= 0 && contact_info->ftrID < l_aMR_work.list_size && + contact_info->contact_flag == TRUE && contact_info->contact_side == aMR_CONTACT_CENTER && + l_aMR_work.used_list[contact_info->ftrID]) { + if (aMR_Get3dDirectStatus(contact_info->direction) == 1) { + if (my_room->state == 6 && my_room->keep_pull_flag == TRUE) { + my_room->pull_timer = 0; + my_room->keep_pull_flag = FALSE; + my_room->state = 8; + } + + if (my_room->pull_timer == 0 && my_room->state == 6) { + my_room->state = 8; + my_room->pull_timer++; + } + + if (my_room->state == 8) { + my_room->pull_timer++; + } + } else if (my_room->state == 6) { + my_room->keep_pull_flag = FALSE; + } else if (my_room->state == 8) { + my_room->keep_pull_flag = FALSE; + my_room->state = 6; + my_room->pull_timer = 0; + } + } + + if (my_room->state == 3 || my_room->state == 2 || my_room->state == 4 || my_room->state == 1) { + my_room->pull_timer = 0; + } +} + +static void aMR_MngPushDirectTimer(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + GAME* game) { + if (my_room->push_timer > 20000) { + my_room->push_timer = 20000; + } + + if (my_room->push_bubu == TRUE) { + if (aMR_JudgeStickFull(aMR_PullDirect2PushDirect(contact_info->direction), game) == FALSE) { + my_room->push_timer = 0; + my_room->state = 6; + my_room->push_bubu = FALSE; + return; + } else { + my_room->state = 7; + } + } else if (contact_info->ftrID >= 0 && contact_info->ftrID < l_aMR_work.list_size && + contact_info->contact_flag == TRUE && contact_info->contact_side == aMR_CONTACT_CENTER && + l_aMR_work.used_list[contact_info->ftrID]) { + if (aMR_JudgeStickFull(aMR_PullDirect2PushDirect(contact_info->direction), game)) { + if (my_room->state == 6 && my_room->keep_push_flag == TRUE) { + my_room->push_timer = 0; + my_room->keep_push_flag = FALSE; + my_room->state = 7; + } + + if (my_room->push_timer == 0 && my_room->state == 6) { + my_room->state = 7; + my_room->push_timer++; + } + + if (my_room->state == 7) { + my_room->push_timer++; + } + } else if (my_room->state == 6) { + my_room->keep_push_flag = FALSE; + } else if (my_room->state == 7) { + my_room->keep_push_flag = FALSE; + my_room->state = 6; + my_room->push_timer = 0; + } + } + + if (my_room->state == 2 || my_room->state == 3 || my_room->state == 4 || my_room->state == 1) { + my_room->push_timer = 0; + } +} + +#define aMR_IS_MUSEUM_ROOM(scene) \ + ((scene) == SCENE_MUSEUM_ENTRANCE || (scene) == SCENE_MUSEUM_ROOM_PAINTING || \ + (scene) == SCENE_MUSEUM_ROOM_FOSSIL || (scene) == SCENE_MUSEUM_ROOM_INSECT || (scene) == SCENE_MUSEUM_ROOM_FISH) + +static void aMR_MngFtrContactAction(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + f32 point[2]; + aMR_contact_info_c* contact_info0; + aMR_contact_info_c* contact_info1; + u32 player_no; + + point[0] = player->actor_class.world.position.x; + point[1] = player->actor_class.world.position.z; + contact_info0 = &my_room->contact0; + contact_info1 = &my_room->contact1; + player_no = Common_Get(player_no); + + aMR_AllContactCheck(my_room, contact_info0, contact_info1, player); + if (my_room->demo_flag == FALSE && !aMR_IS_MUSEUM_ROOM(Save_Get(scene_no)) && aMR_IS_SHOP() == FALSE && + my_room->emu_info.request_flag == FALSE && my_room->msg_type == aMR_MSG_STATE_NONE) { + aMR_ManageMoveBottun(my_room, game, contact_info0, contact_info1); + + /* Process furniture movement timers if not in a storage item demo sequence */ + if (my_room->force_open_demo_flag == FALSE) { + aMR_MngPullDirectTimer(my_room, contact_info0, player, game); + aMR_MngPushDirectTimer(my_room, contact_info0, player, game); + } + + if (aMR_JudgeDemoStart(my_room, contact_info0, game, player) == FALSE) { + if (aMR_CheckRoomOwner(player_no, my_room) && my_room->throw_item_lock_flag == FALSE) { + /* We own the room so actually process modifying furniture */ + aMR_PlacePushFurniture(my_room, contact_info0, point, player, game); + aMR_PlacePullFurniture(my_room, contact_info0, player, game); + aMR_PlaceKurukuruFurniture(my_room, contact_info0, player, game); + aMR_SitDownFurniture(my_room, contact_info0, player, game); + aMR_JudgeGoToBed(my_room, contact_info0, player, game); + } else { + /* We don't own this room so only process sit & lay actions */ + aMR_SitDownFurniture(my_room, contact_info0, player, game); + aMR_JudgeGoToBed(my_room, contact_info0, player, game); + } + } + } +} + +static f32 aMR_GetDistXZ(const xyz_t* pos0, const xyz_t* pos1) { + f32 diff_x = pos0->x - pos1->x; + f32 diff_z = pos0->z - pos1->z; + + return sqrtf((diff_x * diff_x) + (diff_z * diff_z)); +} + +static void aMR_SetFurnitureBaseNorm(aFTR_collision_c* ftr_col) { + int i; + + for (i = 0; i < aFTR_EDGE_COL_NUM; i++) { + ftr_col[i].normal[0] = norm_table[i].x; + ftr_col[i].normal[1] = norm_table[i].z; + } +} + +static void aMR_MakeBaseFurnitureCollisionData(aFTR_collision_c* ftr_col, u16 ftr_no, xyz_t scale) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_no); + s16 shape = profile->shape; + aFTR_size_info_c* size_info = aMR_furniture_size_table[shape]; + f32 up; + f32 right; + f32 left; + f32 down; + f32 edge_x; + f32 edge_z; + f32 height; + + right = size_info->x[1]; + up = size_info->z[1]; + left = size_info->x[0]; + down = size_info->z[0]; + edge_x = size_info->edge[0]; + edge_z = size_info->edge[1]; + height = profile->height; + + ftr_col[0].start[0] = -(right * scale.x); + ftr_col[0].start[1] = -(left * scale.z); + ftr_col[0].end[0] = (up * scale.x); + ftr_col[0].end[1] = -(left * scale.z); + ftr_col[0].height = (height * scale.y); + ftr_col[0].edge_contact_ratio = edge_x; + + ftr_col[1].end[0] = -(right * scale.x); + ftr_col[1].end[1] = -(left * scale.z); + ftr_col[1].start[0] = -(right * scale.x); + ftr_col[1].start[1] = (down * scale.z); + ftr_col[1].height = (height * scale.y); + ftr_col[1].edge_contact_ratio = edge_z; + + ftr_col[2].end[0] = -(right * scale.x); + ftr_col[2].end[1] = (down * scale.z); + ftr_col[2].start[0] = (up * scale.x); + ftr_col[2].start[1] = (down * scale.z); + ftr_col[2].height = (height * scale.y); + ftr_col[2].edge_contact_ratio = edge_x; + + ftr_col[3].start[0] = (up * scale.x); + ftr_col[3].start[1] = -(left * scale.z); + ftr_col[3].end[0] = (up * scale.x); + ftr_col[3].end[1] = (down * scale.z); + ftr_col[3].height = (height * scale.y); + ftr_col[3].edge_contact_ratio = edge_z; +} + +static void aMR_PlussPosition(aFTR_collision_c* ftr_col, const xyz_t* plus_amount) { + int i; + + for (i = 0; i < aFTR_EDGE_COL_NUM; i++) { + ftr_col[i].start[0] += plus_amount->x; + ftr_col[i].start[1] += plus_amount->z; + ftr_col[i].end[0] += plus_amount->x; + ftr_col[i].end[1] += plus_amount->z; + } +} + +static void aMR_RotateFurnitureCollisionData(aFTR_collision_c* ftr_col, f32 amount) { + int i; + + for (i = 0; i < aFTR_EDGE_COL_NUM; i++) { + aMR_RotateY(ftr_col[i].start, amount); + aMR_RotateY(ftr_col[i].end, amount); + aMR_RotateY(ftr_col[i].normal, amount); + } +} + +static void aMR_MakeFurnitureCollisionData(aFTR_collision_c* ftr_col, FTR_ACTOR* ftr_actor) { + u16 name; + xyz_t scale; + xyz_t pos; + xyz_t base_pos; + f32 angle; + + name = ftr_actor->name; + scale = ftr_actor->scale; + pos = ftr_actor->position; + base_pos = ftr_actor->base_position; + angle = DEG2RAD(ftr_actor->angle_y); + + aMR_SetFurnitureBaseNorm(ftr_col); + + scale.x = 1.0f; + scale.y = 1.0f; + scale.z = 1.0f; + aMR_MakeBaseFurnitureCollisionData(ftr_col, name, scale); + aMR_PlussPosition(ftr_col, &base_pos); + aMR_RotateFurnitureCollisionData(ftr_col, angle); + aMR_PlussPosition(ftr_col, &pos); +} + +static void aMR_RewriteFactorInfo(GAME* game) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + GAME_PLAY* play = (GAME_PLAY*)game; + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used) { + aMR_MakeFurnitureCollisionData(ftr_actor->edge_collision, ftr_actor); + ftr_actor->player_distance = aMR_GetDistXZ(&player->actor_class.world.position, &ftr_actor->position); + } + + ftr_actor++; + used++; + } +} + +static mActor_name_t aMR_GetBirthFurniture(u16 ftr_no, int angle_idx) { + if (ftr_no < FTR_NUM) { + return mRmTp_FtrIdx2FtrItemNo(ftr_no, angle_idx & 3); + } + + return FTR_FAN; +} + +static int aMR_CheckPlaceSituation(int ut, int target_ut, u16 ftr_no, u16 angle_idx) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_no); + + if (profile != NULL) { + u32 shape = profile->shape; + + if (shape == aFTR_SHAPE_TYPEB_0) { + static u8 rotate_angle_types[] = { + aFTR_SHAPE_TYPEB_90, + aFTR_SHAPE_TYPEB_180, + aFTR_SHAPE_TYPEB_270, + aFTR_SHAPE_TYPEB_0, + }; + + shape = rotate_angle_types[angle_idx & 3]; + } + + if (aMR_JudgeFurnitureMove(shape, target_ut)) { + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_NO_COLLISION)) { + return TRUE; + } else { + int ut_info[4]; + int ut_count = aMR_GetFurniturePoccessUnitNo(ut_info, target_ut & 0xF, (target_ut >> 4) & 0xF, shape); + + if (ut_count > 0) { + int i; + + for (i = 0; i < ut_count; i++) { + if (ut == ut_info[i]) { + return FALSE; + } + } + } + + return TRUE; + } + } + } + + return FALSE; +} + +static int aMR_ReserveFurniture(GAME* game, u16 ftr_no, int free_idx, int ut_x, int ut_z, u16 rotation, + int square_offset, int layer) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int i; + + for (i = 0; i < aMR_RSV_FTR_NUM; i++) { + if (my_room->rsv_ftr[i].exist_flag == FALSE) { + PLAYER_ACTOR* player = GET_PLAYER_ACTOR((GAME_PLAY*)game); + + my_room->rsv_ftr[i].exist_flag = TRUE; + my_room->rsv_ftr[i].ftr_name = ftr_no; + my_room->rsv_ftr[i].ofs = square_offset; + my_room->rsv_ftr[i].angle_idx = rotation; + my_room->rsv_ftr[i].free_no = free_idx; + my_room->rsv_ftr[i].layer = layer; + my_room->rsv_ftr[i].frames = 46; + my_room->rsv_ftr[i].initial_frames_num = 46; + my_room->rsv_ftr[i].ut_x = ut_x; + my_room->rsv_ftr[i].ut_z = ut_z; + + if (player != NULL) { + mCoBG_BgCheckControll(NULL, (ACTOR*)player, 18.0f, 0.0f, FALSE, FALSE, 1); + } + + return TRUE; + } + } + } + + return FALSE; +} + +static void aMR_PreparePickingUpFurniture(int ftrID, MY_ROOM_ACTOR* my_room) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + + my_room->pickup_info.ftrID = ftrID; + my_room->pickup_info.layer = ftr_actor->layer; + my_room->pickup_info.dust_effect_timer = 2; + aMR_GetFtrShapeCenter(&my_room->pickup_info.leaf_pos, ftr_actor); + my_room->pickup_info.icon = aMR_ItemNo2IconNo(mRmTp_FtrIdx2FtrItemNo(ftr_actor->name, mRmTp_DIRECT_SOUTH)); +} + +static int aMR_JudgePickUpCommon(mActor_name_t* pickup_item_p, ACTOR* actorx, int ftrID, mActor_name_t item) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + int item_count = aMR_GetItemCountInFurniture(ftr_actor); + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (item_count == 0 && my_room->demo_flag == FALSE && my_room->msg_type == aMR_MSG_STATE_NONE) { + int unused_free_space = mPr_GetPossessionItemSumWithCond(Now_Private, EMPTY_NO, mPr_ITEM_COND_NORMAL); + + aMR_PreparePickingUpFurniture(ftrID, my_room); + *pickup_item_p = item; + return TRUE; + } + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK) && + my_room->demo_flag == FALSE && my_room->msg_type == aMR_MSG_STATE_NONE) { + int free_space = mPr_GetPossessionItemSumWithCond(Now_Private, EMPTY_NO, mPr_ITEM_COND_NORMAL); + + if (free_space > 0) { + *pickup_item_p = item; + aMR_PreparePickingUpFurniture(ftrID, my_room); + return TRUE; + } else { + *pickup_item_p = item; + return TRUE; + } + } + + if (my_room->demo_flag == FALSE && my_room->msg_type == aMR_MSG_STATE_NONE) { + int free_space = mPr_GetPossessionItemSumWithCond(Now_Private, EMPTY_NO, mPr_ITEM_COND_NORMAL); + int need_space = item_count + 1; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + s16 msg_type = aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK) + ? aMR_MSG_STATE_CAN_NOT_CLEAN_MD + : aMR_MSG_STATE_CAN_NOT_CLEAN; + + if (free_space < need_space) { + int current_msg_state = my_room->msg_type; + int demo_type; + + if (aMR_force_talk_flag[msg_type]) { + demo_type = mDemo_TYPE_SPEAK; + } else { + demo_type = mDemo_TYPE_REPORT; + } + + *pickup_item_p = EMPTY_NO; + my_room->requested_msg_type = msg_type; + + if (mDemo_CheckDemo() == FALSE && + mDemo_Request(demo_type, actorx, demo_type == mDemo_TYPE_SPEAK ? &aMR_speak_set : &aMR_report_set)) { + my_room->msg_type = my_room->requested_msg_type; + } else { + my_room->requested_msg_type = current_msg_state; + } + + return FALSE; + } else { + aMR_PreparePickingUpFurniture(ftrID, my_room); + *pickup_item_p = item; + return TRUE; + } + } + + return FALSE; +} + +static int square_offset_data[] = { 0, -1, -UT_X_NUM, -(UT_X_NUM + 1) }; + +static mActor_name_t aMR_SearchPickupFurniture(GAME* game) { + mActor_name_t layer1_item; + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + u32 player_no = Common_Get(player_no); + mActor_name_t* fg_layer1_p = aMR_GetLayerTopFg(mCoBG_LAYER1); + mActor_name_t* fg_layer0_p = aMR_GetLayerTopFg(mCoBG_LAYER0); + GAME_PLAY* play = (GAME_PLAY*)game; + + if (mCoBG_CheckUtFlat(&GET_PLAYER_ACTOR(play)->actor_class.world.position) == FALSE) { + return EMPTY_NO; + } + + if (my_room->pickup_info.pickup_flag == TRUE || aMR_CheckReserveFlag(my_room, 1) == TRUE || + my_room->emu_info.request_flag == TRUE || (int)my_room->bgm_info.reserve_flag == TRUE) { + return EMPTY_NO; + } + + my_room->pickup_info.ftrID = -1; + if (aMR_CheckRoomOwner(player_no, my_room)) { + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + s16 player_angle = player->actor_class.shape_info.rotation.y; + int ut_x; + int ut_z; + int target_ut_x; + int target_ut_z; + int target_ut; + mActor_name_t item; + int ftrID; + mActor_name_t item2; + int ftrID2; + int ut; + int i; + xyz_t ut_pos; + f32 dX; + f32 dZ; + f32 dist_sq; + u8 exists; + FTR_ACTOR* ftr_actor; + u8 exists2; + FTR_ACTOR* ftr_actor2; + + aMR_Wpos2PlaceNumber(&ut_x, &ut_z, player->actor_class.world.position, 0); + ut = ut_x + ut_z * UT_X_NUM; + + /* Search the three closest 'in front of' units relative to the player's look direction */ + for (i = 0; i < 3; i++) { + target_ut_x = ut_x; + target_ut_z = ut_z; + aMR_GetPlayerLookAtUnit(&target_ut_x, &target_ut_z, player_angle, i); + target_ut = target_ut_x + target_ut_z * UT_X_NUM; + mFI_UtNum2CenterWpos(&ut_pos, target_ut_x, target_ut_z); + + dX = player->actor_class.world.position.x - ut_pos.x; + dZ = player->actor_class.world.position.z - ut_pos.z; + dist_sq = SQ(dX) + SQ(dZ); + + if (aMR_UnitNum2FtrItemNoFtrID(&item, &ftrID, target_ut_x, target_ut_z, mCoBG_LAYER1) && + dist_sq <= SQ(56.0f)) { + exists = l_aMR_work.used_list[ftrID]; + ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + + if (exists == TRUE) { + mActor_name_t pickup_item; + if (ftr_actor->state != aFTR_STATE_BYE && ftr_actor->state != aFTR_STATE_BIRTH_WAIT && + ftr_actor->state != aFTR_STATE_BIRTH && ftr_actor->state != aFTR_STATE_DEATH && + aMR_JudgePickUpCommon(&pickup_item, actorx, ftrID, item)) { + return pickup_item; + } else { + return EMPTY_NO; + } + } + } + + layer1_item = fg_layer1_p[target_ut]; + if (ITEM_NAME_GET_TYPE((int)fg_layer1_p[target_ut]) == NAME_TYPE_ITEM1 && dist_sq <= SQ(56.0f)) { + my_room->pickup_info.leaf_pos.x = (f32)target_ut_x * mFI_UT_WORLDSIZE_X_F + mFI_UT_WORLDSIZE_HALF_X_F; + my_room->pickup_info.leaf_pos.y = 0.0f; + my_room->pickup_info.leaf_pos.z = (f32)target_ut_z * mFI_UT_WORLDSIZE_Z_F + mFI_UT_WORLDSIZE_HALF_Z_F; + + my_room->pickup_info.leaf_pos.y = + mCoBG_GetBgY_AngleS_FromWpos(NULL, my_room->pickup_info.leaf_pos, 0.0f); + my_room->pickup_info.layer = mCoBG_LAYER1; + return (mActor_name_t)layer1_item; + } + + if (aMR_UnitNum2FtrItemNoFtrID(&item2, &ftrID2, target_ut_x, target_ut_z, mCoBG_LAYER0) && + dist_sq <= SQ(50.0f)) { + exists2 = l_aMR_work.used_list[ftrID2]; + ftr_actor2 = &l_aMR_work.ftr_actor_list[ftrID2]; + + if (exists2 == TRUE) { + mActor_name_t pickup_item; + if (ftr_actor2->state != aFTR_STATE_BYE && ftr_actor2->state != aFTR_STATE_BIRTH_WAIT && + ftr_actor2->state != aFTR_STATE_BIRTH && ftr_actor2->state != aFTR_STATE_DEATH) { + u8* place_table = aMR_GetLayerPlaceTable(mCoBG_LAYER0); + int unused_count = aMR_GetItemCountInFurniture(ftr_actor2); + int x; + int z; + + for (z = 1; z < (UT_Z_NUM - 1); z++) { + for (x = 1; x < (UT_X_NUM - 1); x++) { + /* Check that there are no items on top of this piece of furniture */ + int idx = x + z * UT_X_NUM; + + if (ftrID2 == place_table[idx] && fg_layer1_p[idx] != EMPTY_NO) { + return EMPTY_NO; /* There's something on top of this furniture actor */ + } + } + } + + if (aMR_JudgePickUpCommon(&pickup_item, actorx, ftrID2, item2)) { + return pickup_item; + } else { + return EMPTY_NO; + } + } + } + } + + if (i == 0) { + if (ITEM_NAME_GET_TYPE(fg_layer0_p[ut]) == NAME_TYPE_ITEM1) { + return EMPTY_NO; + } + + if (aMR_UnitNum2FtrItemNoFtrID(&item2, &ftrID2, ut_x, ut_z, mCoBG_LAYER0)) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID2]; + u8 exists = l_aMR_work.used_list[ftrID2]; + + if (exists == TRUE) { + mActor_name_t pickup_item; + if (ftr_actor->state != aFTR_STATE_BYE && ftr_actor->state != aFTR_STATE_BIRTH_WAIT && + ftr_actor->state != aFTR_STATE_BIRTH && ftr_actor->state != aFTR_STATE_DEATH) { + aMR_GetFtrShapeCenter(&my_room->pickup_info.leaf_pos, ftr_actor); + aMR_PreparePickingUpFurniture(ftrID2, my_room); + return item2; + } + } + } + } + + if (ITEM_NAME_GET_TYPE(fg_layer0_p[target_ut]) == NAME_TYPE_ITEM1) { + return EMPTY_NO; + } + } + } + + return EMPTY_NO; +} + +static void aMR_Furniture2ItemBag(GAME* game) { + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int ftrID = my_room->pickup_info.ftrID; + u32 player_no = Common_Get(player_no); + + if (aMR_CheckRoomOwner(player_no, my_room) && ftrID >= 0 && ftrID < l_aMR_work.list_size) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + u8 exists = l_aMR_work.used_list[ftrID]; + + if (exists) { + int shape = ftr_actor->shape_type; + int ut_x; + int ut_z; + + if (aMR_Wpos2PlaceNumber(&ut_x, &ut_z, ftr_actor->position, shape)) { + int ut = ut_x + ut_z * UT_X_NUM; + int item_count = aMR_GetItemCountInFurniture(ftr_actor); + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + Private_c* priv = Now_Private; + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK)) { + int unused_sum = mPr_GetPossessionItemSumWithCond(Now_Private, EMPTY_NO, mPr_ITEM_COND_NORMAL); + ftr_actor->items[0] = EMPTY_NO; + } else if (my_room->demo_flag == FALSE && my_room->msg_type == aMR_MSG_STATE_NONE) { + int free_sum = mPr_GetPossessionItemSumWithCond(priv, EMPTY_NO, mPr_ITEM_COND_NORMAL); + aFTR_PROFILE* unused_profile = aMR_GetFurnitureProfile(ftr_actor->name); + int i; + + if (free_sum < item_count) { + return; + } + + aMR_TidyItemInFurniture(ftr_actor); + for (i = 0; i < item_count; i++) { + mPr_SetFreePossessionItem(priv, ftr_actor->items[i], mPr_ITEM_COND_NORMAL); + ftr_actor->items[i] = EMPTY_NO; + } + } + + my_room->pickup_info.pickup_flag = TRUE; + my_room->pickup_info.picking_up_flag = FALSE; + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, FALSE); + ftr_actor->state = aFTR_STATE_BYE; + aMR_MiniDiskCommonDt(ftr_actor, actorx); + aMR_RadioCommonDt(ftr_actor, actorx); + aMR_SetCleanUpFtrSE(ftr_actor->position); + aMR_SetInfoFurnitureTable(shape, ut, aMR_NO_FTR_ID, ftr_actor->layer); + aMR_ClearHaniwaSwitch(actorx, ftr_actor); + if (ftr_actor->move_bg_idx != -1) { + mCoBG_CrossOffMoveBg(ftr_actor->move_bg_idx); + } + } + } + } +} + +static int aMR_SearchReserveRam(u16 ftr_no) { + return TRUE; +} + +static int aMR_JudgeBreedNewFurniture(GAME* game, u16 ftr_no, int* ut_x, int* ut_z, u16* rotation, int* square_offset, + int* layer) { + u32 player_no = Common_Get(player_no); + + if (aMR_CLIP != NULL && aMR_CheckRoomOwner(player_no, (MY_ROOM_ACTOR*)aMR_CLIP->my_room_actor_p)) { + GAME_PLAY* play = (GAME_PLAY*)game; + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + xyz_t player_pos = player->actor_class.world.position; + mActor_name_t* unused_player_fg_item = mFI_GetUnitFG(player_pos); + s16 player_angle = player->actor_class.shape_info.rotation.y; + int cur_ut_x; + int cur_ut_z; + int cur_ut; + int free_ftrID; + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)aMR_CLIP->my_room_actor_p; + u8 shape; + aFTR_PROFILE* profile; + int target_ut_x; + int target_ut_z; + int target_ut; + int i; + int j; + int angle_idx; + u16 angle; + + if (mCoBG_CheckUtFlat(&player_pos) == FALSE) { + return -2; + } + + if (aMR_CLIP != NULL && my_room != NULL && aMR_CheckReserveFlag(my_room, 0) == FALSE) { + *rotation = 0; + *square_offset = 0; + *layer = 0; + return -2; + } + + aMR_Wpos2PlaceNumber(&cur_ut_x, &cur_ut_z, player_pos, 0); + cur_ut = cur_ut_x + cur_ut_z * UT_X_NUM; + + if (aMR_SearchReserveRam(ftr_no) && aMR_CountFurniture() < l_aMR_work.list_size) { + free_ftrID = aMR_SearchFreeFurnitureActorNumber(); + + if (free_ftrID != -1) { + angle_idx = mRmTp_DIRECT_SOUTH; + angle = player->actor_class.shape_info.rotation.y + DEG2SHORT_ANGLE(180.0f); + + if (angle >= DEG2SHORT_ANGLE2(45.0f) && angle <= DEG2SHORT_ANGLE2(135.0f)) { + angle_idx = mRmTp_DIRECT_EAST; + } else if (angle >= DEG2SHORT_ANGLE2(135.0f) && angle <= DEG2SHORT_ANGLE2(225.0f)) { + angle_idx = mRmTp_DIRECT_NORTH; + } else if (angle >= DEG2SHORT_ANGLE2(225.0f) && angle <= DEG2SHORT_ANGLE2(315.0f)) { + angle_idx = mRmTp_DIRECT_WEST; + } + + if (ftr_no == 0x3C4 || (ftr_no >= 0x3FC && ftr_no <= 0x403)) { + /* Add a rotation for stego skull & the balloon furniture items */ + angle_idx++; + } else if (ftr_no == 0x33B) { + /* Add two rotations for the frog furniture */ + angle_idx += 2; + } + + profile = aMR_GetFurnitureProfile(ftr_no); + shape = profile->shape; + + /* Handle 2x1 furniture */ + if (shape <= aFTR_SHAPE_TYPEB_0) { + + for (i = 0; i < 5; i++) { + if (aMR_WeightPossible((ACTOR*)my_room, profile->shape) == FALSE) { + return -1; + } + + target_ut_x = cur_ut_x; + target_ut_z = cur_ut_z; + aMR_GetPlayerLookAtUnit(&target_ut_x, &target_ut_z, player_angle, i); + target_ut = target_ut_x + target_ut_z * UT_X_NUM; + + if (aMR_CheckPlaceSituation(cur_ut, target_ut, ftr_no, angle_idx & 3)) { + *ut_x = target_ut_x; + *ut_z = target_ut_z; + *square_offset = 0; + *rotation = angle_idx & 3; + *layer = mCoBG_LAYER0; + return free_ftrID; + } + + /* Check if it's a collision-less furniture and if we can place it beneath the player */ + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_NO_COLLISION) && + aMR_CheckPlaceSituation(cur_ut, cur_ut, ftr_no, angle_idx & 3)) { + *ut_x = cur_ut_x; + *ut_z = cur_ut_z; + *square_offset = 0; + *rotation = angle_idx & 3; + *layer = mCoBG_LAYER0; + return free_ftrID; + } + } + + /* Try again but check all the possible rotations for each spot */ + for (j = 0; j < mRmTp_DIRECT_NUM; j++) { + for (i = 0; i < 5; i++) { +/* @BUG - they forgot aMR_GetPlayerLookAtUnit? + Otherwise why does this inner loop exist? */ +#ifdef BUGFIXES + target_ut_x = cur_ut_x; + target_ut_z = cur_ut_z; + aMR_GetPlayerLookAtUnit(&target_ut_x, &target_ut_z, player_angle, i); + target_ut = target_ut_x + target_ut_z * UT_X_NUM; +#endif + + if (aMR_CheckPlaceSituation(cur_ut, target_ut, ftr_no, j)) { + *ut_x = target_ut_x; + *ut_z = target_ut_z; + *square_offset = 0; + *rotation = j; + *layer = mCoBG_LAYER0; + return free_ftrID; + } + + /* Check if it's a collision-less furniture and if we can place it beneath the player */ + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_NO_COLLISION) && + aMR_CheckPlaceSituation(cur_ut, cur_ut, ftr_no, j)) { + *ut_x = cur_ut_x; + *ut_z = cur_ut_z; + *square_offset = 0; + *rotation = j; + *layer = mCoBG_LAYER0; + return free_ftrID; + } + } + } + } else { /* Process 1x1 and 2x2 furniture */ + u8* layer_set_info = aMR_layer_set_info; + + for (i = 0; i < 5; i++) { + angle_idx = (int)angle_idx; + if (aMR_WeightPossible((ACTOR*)my_room, profile->shape) == FALSE) { + return -1; + } + + target_ut_x = cur_ut_x; + target_ut_z = cur_ut_z; + aMR_GetPlayerLookAtUnit(&target_ut_x, &target_ut_z, player_angle, i); + target_ut = target_ut_x + target_ut_z * UT_X_NUM; + + /* Check that the item we're setting down is placeable on the surface and it's 1x1 */ + if (layer_set_info[ftr_no] == aFTR_SET_TYPE_ON_SURFACE && profile->shape == aFTR_SHAPE_TYPEA) { + mActor_name_t* fg_layer1_p = aMR_GetLayerTopFg(mCoBG_LAYER1); + mActor_name_t item; + int ftrID; + + /* Check that the item below is a surface and it has no item on the desired spot */ + if (fg_layer1_p[target_ut] == EMPTY_NO && + aMR_UnitNum2FtrItemNoFtrID(&item, &ftrID, target_ut_x, target_ut_z, mCoBG_LAYER0)) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + + if (aMR_layer_set_info[ftr_actor->name] == aFTR_SET_TYPE_SURFACE) { + *ut_x = target_ut_x; + *ut_z = target_ut_z; + *rotation = angle_idx & 3; + *square_offset = 0; + *layer = mCoBG_LAYER1; + return free_ftrID; + } + } + } + + /* Process 1x1 */ + if (shape != aFTR_SHAPE_TYPEC) { + if (aMR_CheckPlaceSituation(cur_ut, target_ut, ftr_no, angle_idx & 3)) { + *ut_x = target_ut_x; + *ut_z = target_ut_z; + *square_offset = 0; + *rotation = angle_idx & 3; + *layer = mCoBG_LAYER0; + return free_ftrID; + } + + /* Check if it's a collision-less furniture and if we can place it beneath the player */ + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_NO_COLLISION) && + aMR_CheckPlaceSituation(cur_ut, cur_ut, ftr_no, angle_idx & 3)) { + *ut_x = cur_ut_x; + *ut_z = cur_ut_z; + *square_offset = 0; + *rotation = angle_idx & 3; + *layer = mCoBG_LAYER0; + return free_ftrID; + } + + /* Try again but check all the possible rotations for each spot */ + for (j = 0; j < mRmTp_DIRECT_NUM; j++) { + if (aMR_CheckPlaceSituation(cur_ut, target_ut, ftr_no, j)) { + *ut_x = target_ut_x; + *ut_z = target_ut_z; + *square_offset = 0; + *rotation = j; + *layer = mCoBG_LAYER0; + return free_ftrID; + } + + /* Check if it's a collision-less furniture and if we can place it beneath the + * player */ + if (aFTR_CHECK_INTERACTION(profile->interaction_type, + aFTR_INTERACTION_TYPE_NO_COLLISION) && + aMR_CheckPlaceSituation(cur_ut, cur_ut, ftr_no, j)) { + *ut_x = cur_ut_x; + *ut_z = cur_ut_z; + *square_offset = 0; + *rotation = j; + *layer = mCoBG_LAYER0; + return free_ftrID; + } + } + } else { /* Process 2x2 */ + int j; + + for (j = 0; j < 4; j++) { + int target_ut2 = target_ut + square_offset_data[j]; + int target_ut_x2 = (target_ut2 & 0xF); + int target_ut_z2 = (target_ut2 / 16); + + if (aMR_CheckPlaceSituation(cur_ut, target_ut2, ftr_no, angle_idx & 3)) { + *ut_x = target_ut_x2; + *ut_z = target_ut_z2; + *square_offset = j; + *rotation = angle_idx & 3; + *layer = mCoBG_LAYER0; + return free_ftrID; + } + + /* Check if it's a collision-less furniture and if we can place it beneath the player */ + if (aFTR_CHECK_INTERACTION(profile->interaction_type, + aFTR_INTERACTION_TYPE_NO_COLLISION) && + aMR_CheckPlaceSituation(cur_ut, cur_ut, ftr_no, angle_idx & 3)) { + *ut_x = cur_ut_x; + *ut_z = cur_ut_z; + *square_offset = 0; + *rotation = angle_idx & 3; + *layer = mCoBG_LAYER0; + return free_ftrID; + } + } + } + } + } + + return -2; + } + } + + return -1; + } else { + *rotation = 0; + *square_offset = 0; + *layer = 0; + return -3; + } +} + +static void aMR_InitFactorCollisionDirect(void) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used) { + ftr_actor->collision_direction = 0; + } + + ftr_actor++; + used++; + } +} + +static mActor_name_t aMR_GetSaveAngle(f32 angle, mActor_name_t item) { + f32 sin = sinf_table(DEG2RAD(angle)); + f32 cos = cosf_table(DEG2RAD(angle)); + + if (sin > 0.8f) { + item |= mRmTp_DIRECT_EAST; + } else if (sin < -0.8f) { + item |= mRmTp_DIRECT_WEST; + } + + if (cos > 0.8f) { + item |= mRmTp_DIRECT_SOUTH; + } else if (cos < -0.8f) { + item |= mRmTp_DIRECT_NORTH; + } + + return item; +} + +static int aMR_SetFurniture2FG(FTR_ACTOR* ftr_actor, xyz_t pos, int on_flag) { + int layer = ftr_actor->layer; + mActor_name_t* fg_layer_p = aMR_GetLayerTopFg(layer); + + if (fg_layer_p != NULL && ftr_actor->state != aFTR_STATE_BYE) { + f32 target_angle = ftr_actor->angle_y_target; + f32 target_angle_rad = DEG2RAD(target_angle); + mActor_name_t item = mRmTp_FtrIdx2FtrItemNo(ftr_actor->name, mRmTp_DIRECT_SOUTH); + xyz_t base_pos = { 0.0f, 0.0f, 0.0f }; + xyz_t tmp_pos = { mFI_UT_WORLDSIZE_X_F, 0.0f, 0.0f }; + int shape; + + item = aMR_GetSaveAngle(target_angle, item); + switch (ftr_actor->shape_type) { + case aFTR_SHAPE_TYPEA: + case aFTR_SHAPE_TYPEC: { + int set_item; + int ut_info[4]; + int ut_count = aMR_PosType2FurniturePoccessUnitNo(ut_info, &pos, ftr_actor->shape_type); + int i; + + if (ut_count > 0) { + if (on_flag == TRUE) { + set_item = item; + } else { + set_item = EMPTY_NO; + } + + fg_layer_p[ut_info[0]] = set_item; + + if (ut_count > 1) { + for (i = 1; i < ut_count; i++) { + if (on_flag == TRUE) { + set_item = RSV_FE1F; + } else { + set_item = EMPTY_NO; + } + + fg_layer_p[ut_info[i]] = set_item; + } + } + + return TRUE; + } + + return FALSE; + } + + default: { + int ut; + int tmp_ut; + + base_pos.x += ftr_actor->base_position.x; + base_pos.z += ftr_actor->base_position.z; + base_pos.y = ftr_actor->base_position.y; + + tmp_pos.x += ftr_actor->base_position.x; + tmp_pos.z += ftr_actor->base_position.z; + tmp_pos.y = ftr_actor->base_position.y; + + sMath_RotateY(&base_pos, target_angle_rad); + sMath_RotateY(&tmp_pos, target_angle_rad); + + base_pos.x += pos.x; + base_pos.z += pos.z; + + tmp_pos.x += pos.x; + tmp_pos.z += pos.z; + + ut = (int)(base_pos.x / mFI_UT_WORLDSIZE_X_F) + (int)(base_pos.z / mFI_UT_WORLDSIZE_Z_F) * UT_X_NUM; + tmp_ut = (int)(tmp_pos.x / mFI_UT_WORLDSIZE_X_F) + (int)(tmp_pos.z / mFI_UT_WORLDSIZE_Z_F) * UT_X_NUM; + + if (on_flag == TRUE) { + fg_layer_p[ut] = item; + fg_layer_p[tmp_ut] = RSV_FE1F; + } else { + fg_layer_p[ut] = EMPTY_NO; + fg_layer_p[tmp_ut] = EMPTY_NO; + } + + return TRUE; + } + } + } + + return FALSE; +} + +static void aMR_CheckControllerNeutral(MY_ROOM_ACTOR* my_room) { + f32 x = ABS(gamePT->mcon.move_pX); + f32 z = ABS(gamePT->mcon.move_pY); + + if (my_room->allow_rotation_flag == FALSE && x <= 0.086f && z <= 0.086f) { + my_room->allow_rotation_flag = TRUE; + } +} + +static void aMR_FtrPull(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + cKF_SkeletonInfo_R_c* keyframe = &my_room->keyframe; + xyz_t scale = { 0.01f, 0.01f, 0.01f }; + f32 speed = keyframe->frame_control.speed; + int state = cKF_SkeletonInfo_R_play(keyframe); + + cKF_SkeletonInfo_R_AnimationMove_base(&ftr_actor->position, NULL, &scale, my_room->move_angle, keyframe); + if (state == cKF_STATE_STOPPED) { + if (speed == 0.0f) { + my_room->state = 6; + ftr_actor->state = aFTR_STATE_STOP; + ftr_actor->position = ftr_actor->target_position; + keyframe->frame_control.speed = 0.5f; + cKF_SkeletonInfo_R_AnimationMove_dt(keyframe); + aMR_RequestItemToUnFitFurniture(my_room, ftr_actor); + } else { + keyframe->frame_control.speed = 0.0f; + } + } +} + +static void aMR_FtrPush(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + cKF_SkeletonInfo_R_c* keyframe = &my_room->keyframe; + xyz_t scale = { 0.01f, 0.01f, 0.01f }; + f32 speed = keyframe->frame_control.speed; + int state = cKF_SkeletonInfo_R_play(keyframe); + + cKF_SkeletonInfo_R_AnimationMove_base(&ftr_actor->position, NULL, &scale, my_room->move_angle, keyframe); + if (state == cKF_STATE_STOPPED) { + if (speed == 0.0f) { + my_room->state = 6; + ftr_actor->position = ftr_actor->target_position; + ftr_actor->state = aFTR_STATE_STOP; + keyframe->frame_control.speed = 0.5f; + cKF_SkeletonInfo_R_AnimationMove_dt(keyframe); + aMR_RequestItemToUnFitFurniture(my_room, ftr_actor); + } else { + keyframe->frame_control.speed = 0.0f; + } + } + + aMR_CheckFtrAndGoki((ACTOR*)my_room, ftr_actor, game); +} + +static void aMR_FtrStop(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + // nothing +} + +static void aMR_FtrWaitPush(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + ftr_actor->state = aFTR_STATE_WAIT_PUSH2; +} + +static void aMR_FtrWaitPush2(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + ftr_actor->state = aFTR_STATE_WAIT_PUSH3; +} + +static void aMR_FtrWaitPush3(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + ftr_actor->state = aFTR_STATE_PUSH; +} + +static void aMR_FtrWaitPull(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + ftr_actor->state = aFTR_STATE_WAIT_PULL2; +} + +static void aMR_FtrWaitPull2(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + ftr_actor->state = aFTR_STATE_PULL; +} + +static f32 aMR_GetEllipseSpeed(f32 start, f32 target, f32 speed, f32 max) { + f32 delta_angle = ABS(start - target); + f32 delta_max = delta_angle - max; + + if (!F32_IS_ZERO(max)) { + f32 sq_speed = SQ(speed); + f32 res = sq_speed * (1.0f - SQ(delta_max) / SQ(max)); + + if (F32_IS_ZERO(res)) { + return 0.0f; + } + + return sqrtf(res); + } + + return 0.0f; +} + +static void aMR_FtrRotate(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + f32 rotate_amount = aMR_GetEllipseSpeed(ftr_actor->angle_y, ftr_actor->angle_y_target, 5.6f, 90.0f); + f32 delta_angle = ABS(ftr_actor->angle_y - ftr_actor->angle_y_target); + + if (delta_angle <= rotate_amount + 1.0f) { + ftr_actor->angle_y = ftr_actor->angle_y_target; + ftr_actor->state = aFTR_STATE_STOP; + if (my_room->state == 4) { + my_room->state = 6; + } + + ftr_actor->s_angle_y = RAD2SHORT_ANGLE2(DEG2RAD(ftr_actor->angle_y)); + aMR_RequestItemToUnFitFurniture(my_room, ftr_actor); + } else { + if (ftr_actor->state == aFTR_STATE_LROTATE) { + ftr_actor->angle_y += rotate_amount; + } else if (ftr_actor->state == aFTR_STATE_RROTATE) { + ftr_actor->angle_y -= rotate_amount; + } + } + + aMR_CheckFtrAndGoki((ACTOR*)my_room, ftr_actor, game); +} + +static void aMR_BirthWait(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + f32 scale = ftr_actor->collision_scale; + int i; + + if (ftr_actor->collision_scale < 1.0f) { + ftr_actor->collision_scale = scale + ((f32)GETREG(MYKREG, 89) * 0.01f + 0.05f); + } else if (ftr_actor->collision_scale > 1.0f) { + ftr_actor->collision_scale = 1.0f; + } else { + ftr_actor->collision_scale = scale; + } + + for (i = 0; i < aMR_RSV_FTR_NUM; i++) { + if (ftr_actor->id == my_room->rsv_ftr[i].free_no) { + if (my_room->rsv_ftr[i].frames <= 0) { + ftr_actor->state = aFTR_STATE_BIRTH; + sAdo_OngenTrgStart(NA_SE_BIRTH_FTR, &ftr_actor->position); + } + + break; + } + } +} + +static void aMR_FtrBirth(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + static xyz_t scale1 = { 1.0f, 1.0f, 1.0f }; + f32 scale_y; + f32 scale_xz; + s16 now_counter; + s16 prev_counter = ftr_actor->birth_anim_counter; + xyz_t center; + xyz_t pos0; + xyz_t pos1; + xyz_t pos2; + xyz_t pos3; + + if (ftr_actor->collision_scale < 1.0f) { + ftr_actor->collision_scale = ftr_actor->collision_scale + ((f32)GETREG(MYKREG, 89) * 0.01f + 0.05f); + } else if (ftr_actor->collision_scale > 1.0f) { + ftr_actor->collision_scale = 1.0f; + } else { + ftr_actor->collision_scale = ftr_actor->collision_scale; + } + + ftr_actor->birth_anim_counter += ftr_actor->birth_anim_step; + now_counter = ftr_actor->birth_anim_counter; + scale_y = sinf_table(SHORT2RAD_ANGLE2(now_counter)) * ftr_actor->birth_scale_modifier; + scale_xz = 1.0f - scale_y; + scale_y += 1.0f; + + ftr_actor->scale.x = scale_xz; + ftr_actor->scale.y = scale_y; + ftr_actor->scale.z = scale_xz; + + if (ftr_actor->dust_timer == 2) { + aMR_GetDust4Position(&pos0, &pos1, &pos2, &pos3, ¢er, ftr_actor); + + if (eEC_CLIP != NULL) { + xyz_t vec; + + vec.x = pos0.x - center.x; + vec.y = pos0.y - center.y; + vec.z = pos0.z - center.z; + eEC_CLIP->effect_make_proc(eEC_EFFECT_DUST, pos0, 2, aMR_GetDustAngle(&vec), game, RSV_NO, 0, 4); + + vec.x = pos2.x - center.x; + vec.y = pos2.y - center.y; + vec.z = pos2.z - center.z; + eEC_CLIP->effect_make_proc(eEC_EFFECT_DUST, pos2, 2, aMR_GetDustAngle(&vec), game, RSV_NO, 0, 4); + } + } else if (ftr_actor->dust_timer == 6) { + aMR_GetDust4Position(&pos0, &pos1, &pos2, &pos3, ¢er, ftr_actor); + + if (eEC_CLIP != NULL) { + xyz_t vec; + + vec.x = pos1.x - center.x; + vec.y = pos1.y - center.y; + vec.z = pos1.z - center.z; + eEC_CLIP->effect_make_proc(eEC_EFFECT_DUST, pos1, 2, aMR_GetDustAngle(&vec), game, RSV_NO, 0, 4); + + vec.x = pos3.x - center.x; + vec.y = pos3.y - center.y; + vec.z = pos3.z - center.z; + eEC_CLIP->effect_make_proc(eEC_EFFECT_DUST, pos3, 2, aMR_GetDustAngle(&vec), game, RSV_NO, 0, 4); + } + } + + ftr_actor->dust_timer++; + if ((prev_counter < 0 && now_counter >= 0) || (prev_counter < -0x8000 && now_counter >= -0x8000)) { + ftr_actor->birth_scale_modifier *= 0.4f; + ftr_actor->birth_anim_step += 1500; + } + + if (ABS(ftr_actor->birth_scale_modifier) < 0.02f) { + ftr_actor->state = aFTR_STATE_STOP; + ftr_actor->scale = scale1; + ftr_actor->collision_scale = 1.0f; + } +} + +static void aMR_FtrBye(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + ACTOR* actorx = (ACTOR*)my_room; + s16 dust; + f32 scale; + aFTR_PROFILE* profile; + int ftrID; + u8* used; + + ftr_actor->scale.x -= 0.08333333333f; + scale = ftr_actor->scale.x; + if (scale < 0.25f) { + scale = 0.0f; + } + + ftr_actor->scale.x = scale; + ftr_actor->scale.y = ftr_actor->scale.x; + ftr_actor->scale.z = ftr_actor->scale.x; + + dust = my_room->pickup_info.dust_effect_timer; + my_room->pickup_info.dust_effect_timer = dust - 1; + + if (dust == 0) { + Clip_c* clip = Common_GetPointer(clip); /* Not a fan of doing this */ + + if (clip->effect_clip) { + aMR_GetFtrShapeCenter(&my_room->pickup_info.leaf_pos, ftr_actor); + clip->effect_clip->effect_make_proc(eEC_EFFECT_DUST, my_room->pickup_info.leaf_pos, 2, 0, game, RSV_NO, 0, + 4); + } + } + + if (ftr_actor->scale.x == 0.0f) { + ftrID = ftr_actor->id; + used = l_aMR_work.used_list; + profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (ftr_actor->layer == mCoBG_LAYER0) { + aMR_MakeGokiburi(&ftr_actor->position, game, 1); + } + + if (my_room->pickup_info.pickup_flag) { + aMR_GetFtrShapeCenter(&my_room->pickup_info.leaf_pos, ftr_actor); + my_room->pickup_info.picking_up_flag = TRUE; + } + + if (profile != NULL) { + aMR_KeepItem2Fg(ftr_actor); + aMR_MiniDiskCommonDt(ftr_actor, actorx); + aMR_RadioCommonDt(ftr_actor, actorx); + aMR_MinusWeight(actorx, ftr_actor); + + if (profile->vtable != NULL && profile->vtable->dt_proc != NULL) { + u8* bank = aMR_FtrNo2BankAddress(ftr_actor->name); + + profile->vtable->dt_proc(ftr_actor, bank); + } + + mMkRm_ReportChangePlayerRoom(); + } + + used[ftrID] = FALSE; + aMR_DeleteFurnitureBank(ftr_actor->name); + aMR_ClearBitSwitch(ftr_actor); + } +} + +static void aMR_FtrDeath(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + int ftrID = ftr_actor->id; + ACTOR* actorx = (ACTOR*)my_room; + + if (l_aMR_work.ftr_actor_list != NULL && l_aMR_work.used_list != NULL) { + u16 ftr_no = ftr_actor->name; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_no); + + if (l_aMR_work.used_list[ftrID]) { + if (profile != NULL) { + aMR_KeepItem2Fg(ftr_actor); + aMR_MiniDiskCommonDt(ftr_actor, actorx); + aMR_RadioCommonDt(ftr_actor, actorx); + + if (profile->vtable != NULL && profile->vtable->dt_proc != NULL) { + u8* bank = aMR_FtrNo2BankAddress(ftr_no); + + profile->vtable->dt_proc(ftr_actor, bank); + } + } + + l_aMR_work.used_list[ftrID] = FALSE; + aMR_DeleteFurnitureBank(ftr_no); + aMR_ClearBitSwitch(ftr_actor); + } + } +} + +static void aMR_FtrWaitRrotate(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + if (ftr_actor->rotation_delay_timer <= 0) { + ftr_actor->state = aFTR_STATE_RROTATE; + } + + ftr_actor->rotation_delay_timer--; +} + +static void aMR_FtrWaitLrotate(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room) { + if (ftr_actor->rotation_delay_timer <= 0) { + ftr_actor->state = aFTR_STATE_LROTATE; + } + + ftr_actor->rotation_delay_timer--; +} + +static void aMR_GetItemPosOnMovingFurniture(MY_ROOM_ACTOR* my_room, FTR_ACTOR* ftr_actor) { + aMR_parent_ftr_c* parent_ftr = &my_room->parent_ftr; + + if (parent_ftr->ftrID == ftr_actor->id) { + s16 angle = ftr_actor->s_angle_y; + int i; + + Matrix_translate(ftr_actor->position.x, ftr_actor->position.y, ftr_actor->position.z, 0); + Matrix_RotateY(angle - parent_ftr->angle_y, 1); + Matrix_translate(ftr_actor->base_position.x, ftr_actor->base_position.y, ftr_actor->base_position.z, 1); + + for (i = 0; i < aMR_FIT_FTR_MAX; i++) { + if (parent_ftr->fit_ftr_table[i].exist_flag == TRUE) { + xyz_t pos; + + Matrix_Position(&parent_ftr->fit_ftr_table[i].pos, &pos); + parent_ftr->fit_ftr_table[i].ut_pos = pos; + if (parent_ftr->fit_ftr_table[i].ftr_ID != -1) { + l_aMR_work.ftr_actor_list[parent_ftr->fit_ftr_table[i].ftr_ID].position = pos; + } + } + } + } +} + +typedef void (*aMR_FPROC)(FTR_ACTOR*, GAME*, MY_ROOM_ACTOR*); + +static void aMR_FurnitureMoveFunction(ACTOR* actorx, GAME* game) { + int i; + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + + static aMR_FPROC fproc[aFTR_STATE_NUM] = { + &aMR_FtrStop, &aMR_FtrWaitPush, &aMR_FtrWaitPush2, &aMR_FtrWaitPush3, + &aMR_FtrPush, &aMR_FtrWaitPull, &aMR_FtrWaitPull2, &aMR_FtrPull, + &aMR_FtrWaitLrotate, &aMR_FtrRotate, &aMR_FtrWaitRrotate, &aMR_FtrRotate, + &aMR_BirthWait, &aMR_FtrBirth, &aMR_FtrBye, &aMR_FtrDeath, + }; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL) { + (*fproc[ftr_actor->state])(ftr_actor, game, my_room); + ftr_actor->s_angle_y = RAD2SHORT_ANGLE2(DEG2RAD(ftr_actor->angle_y)); + + if (profile->rig != NULL) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + + cKF_SkeletonInfo_R_play(keyframe); + keyframe->frame_control.speed = 0.5f; + } + + if (profile->tex_anim != NULL) { + int count = profile->tex_anim->animation_count; + + ftr_actor->tex_animation.frame++; + if (ftr_actor->tex_animation.frame >= count || ftr_actor->tex_animation.frame < 0) { + ftr_actor->tex_animation.frame = 0; + } + } + + if (ftr_actor->state != aFTR_STATE_BYE && ftr_actor->state != aFTR_STATE_DEATH) { + if (profile->vtable != NULL && profile->vtable->move_proc != NULL) { + u8* bank = aMR_FtrNo2BankAddress(ftr_actor->name); + + profile->vtable->move_proc(ftr_actor, actorx, game, bank); + } + } + + ftr_actor->last_position = ftr_actor->position; + } + + aMR_GetItemPosOnMovingFurniture(my_room, ftr_actor); + } + + used++; + ftr_actor++; + } +} + +static void aMR_ClearChangeSwitchFlag(void) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + + if (l_aMR_work.ftr_actor_list != NULL && l_aMR_work.used_list != NULL) { + int i; + + for (i = 0; i < l_aMR_work.list_size; i++) { + ftr_actor[i].switch_changed_flag = FALSE; + } + } +} + +static void aMR_SetReserveFurniture(MY_ROOM_ACTOR* my_room, GAME* game) { + ACTOR* actorx = (ACTOR*)my_room; + GAME_PLAY* play = (GAME_PLAY*)game; + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + int i; + + if (play->submenu.process_status == mSM_PROCESS_WAIT) { + for (i = 0; i < aMR_RSV_FTR_NUM; i++) { + if (my_room->rsv_ftr[i].exist_flag) { + if (my_room->rsv_ftr[i].frames == my_room->rsv_ftr[i].initial_frames_num) { + u16 ftr_no = my_room->rsv_ftr[i].ftr_name; + mActor_name_t item = aMR_GetBirthFurniture(ftr_no, my_room->rsv_ftr[i].angle_idx); + + if (aMR_GetFurnitureBank2(ftr_no, game, item)) { + if (my_room->rsv_ftr[i].free_no != -1) { + used[my_room->rsv_ftr[i].free_no] = TRUE; + aMR_FurnitureCt(ftr_actor + my_room->rsv_ftr[i].free_no, game, my_room->rsv_ftr[i].ut_x, + my_room->rsv_ftr[i].ut_z, item, my_room->rsv_ftr[i].free_no, + aFTR_STATE_BIRTH_WAIT, my_room->rsv_ftr[i].layer, TRUE); + aMR_PlussWeight(actorx, &ftr_actor[my_room->rsv_ftr[i].free_no]); + mMkRm_ReportChangePlayerRoom(); + } else { + my_room->rsv_ftr[i].exist_flag = FALSE; + } + } else { + my_room->rsv_ftr[i].exist_flag = FALSE; + } + } else if (my_room->rsv_ftr[i].frames <= 0) { + my_room->rsv_ftr[i].exist_flag = FALSE; + } else if (my_room->rsv_ftr[i].frames + 1 == my_room->rsv_ftr[i].initial_frames_num) { + int ftrID = my_room->rsv_ftr[i].free_no; + mActor_name_t item = mRmTp_FtrIdx2FtrItemNo(my_room->rsv_ftr[i].ftr_name, mRmTp_DIRECT_SOUTH); + s16 icon_no = aMR_ItemNo2IconNo(item); + + if (ftrID != -1) { + xyz_t effect_pos; + + aMR_GetFtrShapeCenter(&effect_pos, &l_aMR_work.ftr_actor_list[ftrID]); + if (eEC_CLIP != NULL) { + eEC_CLIP->effect_make_proc(eEC_EFFECT_KAGU_HAPPA, effect_pos, 2, 0, game, RSV_NO, icon_no, + 0); + } + } + } + + my_room->rsv_ftr[i].frames--; + } + } + } +} + +static void aMR_PreparePlayerAction(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + + if (my_room->state == 1) { + PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play); + + if (player->actor_class.world.position.x == my_room->nice_pos.x && + player->actor_class.world.position.z == my_room->nice_pos.z) { + my_room->state = 6; + } + } +} + +static void aMR_SetFtrDemoMsg(MY_ROOM_ACTOR* my_room) { + if (my_room->msg_type == aMR_MSG_STATE_WAIT_MSG || my_room->msg_type == aMR_MSG_STATE_WAIT_MD) { + my_room->msg_timer++; + } + + if (my_room->demo_flag == TRUE) { + if (my_room->msg_type == aMR_MSG_STATE_WAIT_MSG) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[my_room->demo_ftrID]; + u32 player_no = Common_Get(player_no); + + if (my_room->msg_timer > 0) { + if (aMR_GetItemCountInFurniture(ftr_actor) <= 0) { + if (aMR_CheckRoomOwner(player_no, my_room)) { + my_room->requested_msg_type = aMR_MSG_STATE_OWNER_NO_ITEM; + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OTHER_NO_ITEM; + } + } else { + int count = aMR_GetItemCountInFurniture(ftr_actor); + + if (Save_Get(scene_no) == SCENE_NPC_HOUSE || Save_Get(scene_no) == SCENE_COTTAGE_NPC) { + my_room->requested_msg_type = aMR_MSG_STATE_OTHER_NO_ITEM; + } else { + if (aMR_CheckRoomOwner(player_no, my_room)) { + switch (count) { + case 0: + break; + case 1: + my_room->requested_msg_type = aMR_MSG_STATE_OWNER_EXIST_ITEM; + break; + case 2: + my_room->requested_msg_type = aMR_MSG_STATE_OWNER_EXIST_ITEM_ITEM_COUNT2; + break; + default: + my_room->requested_msg_type = aMR_MSG_STATE_OWNER_WHICH_PUT_OUT1; + break; + } + } else { + switch (count) { + case 0: + break; + case 1: + my_room->requested_msg_type = aMR_MSG_STATE_OTHER_EXIST_ITEM1; + break; + case 2: + my_room->requested_msg_type = aMR_MSG_STATE_OTHER_EXIST_ITEM2; + break; + default: + my_room->requested_msg_type = aMR_MSG_STATE_OTHER_EXIST_ITEM3; + break; + } + } + } + } + } + } else if (my_room->msg_type == aMR_MSG_STATE_WAIT_MD) { + int demo_ftrID = my_room->demo_ftrID; + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[demo_ftrID]; + u32 player_no = Common_Get(player_no); + + if (my_room->msg_timer > 0) { + if (ftr_actor->items[0] == EMPTY_NO) { + if (aMR_CheckRoomOwner(player_no, my_room)) { + my_room->requested_msg_type = aMR_MSG_STATE_OWNER_NO_MD; + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OTHER_NO_MD; + } + } else { + if (aMR_CheckRoomOwner(player_no, my_room)) { + if (ftr_actor->switch_bit) { + my_room->requested_msg_type = aMR_MSG_STATE_OWNER_EXIST_MD; + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OWNER_EXIST_MD2; + } + } else { + my_room->requested_msg_type = aMR_MSG_STATE_OTHER_EXIST_MD; + } + } + } + } + } +} + +static void aMR_HouseOwnerMove(u32 player_no, ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + aMR_FurnitureMoveFunction(actorx, game); + aMR_PreparePlayerAction(actorx, game); + aMR_CheckControllerNeutral(my_room); +} + +static void aMR_HouseOtherMove(u32 player_no, ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + aMR_FurnitureMoveFunction(actorx, game); + aMR_PreparePlayerAction(actorx, game); + aMR_CheckControllerNeutral(my_room); +} + +static void aMR_MakeClockInfo(MY_ROOM_ACTOR* my_room, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + + my_room->clock_info.frame = play->game_frame % 120; + my_room->clock_info.tick0 = FALSE; + my_room->clock_info.tick1 = FALSE; + my_room->clock_info.tick_stop = FALSE; + + switch (my_room->clock_info.frame) { + case 0: + my_room->clock_info.tick_stop = TRUE; + break; + case 15: + my_room->clock_info.tick0 = TRUE; + break; + case 45: + my_room->clock_info.tick1 = TRUE; + break; + } +} + +static u16 aMR_Fname2ConpoIndex(u16 fname) { + switch (fname) { + case 0x055: /* retro stereo */ + return 1; + case 0x37E: /* phonograph */ + return 2; + case 0x37F: /* turntable */ + return 3; + case 0x380: /* jukebox */ + return 4; + case 0x385: /* lovely stereo */ + return 5; + case 0x381: /* red boom box */ + return 6; + case 0x382: /* white boom box */ + return 7; + case 0x396: /* tape deck */ + return 8; + case 0x395: /* reel-to-reel */ + return 9; + case 0x079: /* gold stereo */ + return 10; + case 0x383: /* high-end stereo */ + return 11; + case 0x384: /* hi-fi stereo */ + return 12; + case 0x38F: /* robo-stereo */ + return 13; + case 0x390: /* dice stereo */ + return 14; + case 0x397: /* CD player */ + return 15; + case 0x3B4: /* kiddie stereo */ + return 16; + default: + return 1; + } +} + +static void My_Room_Actor_move(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + u32 player_no = Common_Get(player_no); + int i; + + my_room->goki_ct_proc(actorx, game); + if (my_room->state == 0) { + aMR_RequestPlayerBikkuri(actorx, game); + } + + if (!aMR_IS_SHOP() && my_room->bgm_info.active_flag) { + FTR_ACTOR* md_ftr_actor = my_room->bgm_info.active_ftr_actor; + + if (md_ftr_actor != NULL) { + u16 md_angle = md_ftr_actor->s_angle_y; + + if (my_room->bgm_info.md_no != BGM_AEROBICS) { + mBGMPsComp_MDPlayerPos_param_set(&md_ftr_actor->position, md_angle, + aMR_Fname2ConpoIndex(md_ftr_actor->name), (u32)md_ftr_actor); + } + } + } + + aMR_SetReserveFurniture(my_room, game); + if (my_room->bgm_info.timer > 0) { + my_room->bgm_info.timer--; + } else { + my_room->bgm_info.timer = 0; + } + + if (!aMR_IS_SHOP() && my_room->bgm_info.timer == 0 && (int)my_room->bgm_info.reserve_flag == TRUE) { + if (mMsg_CHECK_MAINHIDE()) { + aMR_ChangeMDBgm(actorx, my_room->bgm_info.reserved_ftr_actor); + } + } + + aMR_MakeClockInfo(my_room, game); + my_room->contact0 = l_cntInf_default; + aMR_InitFactorCollisionDirect(); + aMR_RewriteFactorInfo(game); + aMR_MngFtrContactAction(actorx, game); + + if (aMR_CheckRoomOwner(player_no, my_room)) { + aMR_HouseOwnerMove(player_no, actorx, game); + } else { + aMR_HouseOtherMove(player_no, actorx, game); + } + + aMR_SetFtrDemoMsg(my_room); + aMR_MessageControl(actorx, game); + aMR_ClearChangeSwitchFlag(); +} + +static void aMR_SetNowPosition(xyz_t* now_pos, xyz_t pos) { + if (now_pos != NULL) { + *now_pos = pos; + } +} + +static int aMR_JudgePlayerAction(xyz_t* out_pos0, xyz_t* out_pos1, int ftrID) { + static xyz_t pos0 = { 0.0f, 0.0f, 0.0f }; + ACTOR* actorx = aMR_CLIP->my_room_actor_p; + + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + if (l_aMR_work.ftr_actor_list != NULL && l_aMR_work.used_list != NULL) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list + ftrID; + s16 ftr_state = ftr_actor->state; + + if (my_room->demo_flag == TRUE) { + if (my_room->state == 8) { + FTR_ACTOR* demo_ftr_actor = &l_aMR_work.ftr_actor_list[my_room->demo_ftrID]; + aFTR_PROFILE* demo_profile = aMR_GetFurnitureProfile(demo_ftr_actor->name); + + if (demo_profile != NULL) { + if (aFTR_CHECK_INTERACTION(demo_profile->interaction_type, aFTR_INTERACTION_TYPE_DRAWERS)) { + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 8; + } else if (aFTR_CHECK_INTERACTION(demo_profile->interaction_type, + aFTR_INTERACTION_TYPE_WARDROBE)) { + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 6; + } else if (aFTR_CHECK_INTERACTION(demo_profile->interaction_type, + aFTR_INTERACTION_TYPE_CLOSET)) { + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 7; + } else if (aFTR_CHECK_INTERACTION(demo_profile->interaction_type, + aFTR_INTERACTION_TYPE_MUSIC_DISK)) { + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 1; + } + } + } + } else { + switch (my_room->state) { + case 7: + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 9; + case 8: + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 10; + case 2: + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 2; + case 3: + aMR_SetNowPosition(out_pos0, my_room->pull_target_pos0); + aMR_SetNowPosition(out_pos1, my_room->pull_target_pos1); + return 3; + case 4: + if (ftr_state == aFTR_STATE_LROTATE || ftr_state == aFTR_STATE_WAIT_LROTATE) { + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 5; + } + + if (ftr_state == aFTR_STATE_RROTATE || ftr_state == aFTR_STATE_WAIT_RROTATE) { + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 4; + } + /* Fallthrough 4 -> 0 */ + case 0: + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 0; + case 6: + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 1; + default: + break; + } + } + + aMR_SetNowPosition(out_pos0, my_room->nice_pos); + aMR_SetNowPosition(out_pos1, my_room->nice_pos); + return 1; + } + } + + aMR_SetNowPosition(out_pos0, pos0); + aMR_SetNowPosition(out_pos1, pos0); + return 1; +} + +static void aMR_PlayerMoveFurniture(int ftrID, xyz_t* pos) { + if (l_aMR_work.ftr_actor_list != NULL && l_aMR_work.used_list != NULL) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + xyz_t* ftr_pos = &ftr_actor->position; + + ftr_pos->x = pos->x; + ftr_pos->z = pos->z; + } +} + +static int aMR_ftrID2Wpos(xyz_t* pos, int ftrID) { + if (ftrID >= 0 && ftrID < l_aMR_work.list_size && l_aMR_work.ftr_actor_list != NULL && + l_aMR_work.used_list != NULL) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + u8 used = l_aMR_work.used_list[ftrID]; + + if (used) { + xyz_t* ftr_pos = &ftr_actor->position; + + *pos = *ftr_pos; + return TRUE; + } + } + + return FALSE; +} + +static int aMR_UnitNum2FtrItemNoFtrID(mActor_name_t* item_no, int* ftrID, int ut_x, int ut_z, int layer) { + /* ut_x & ut_z are in world coordinates so they go above the standard 0-15 */ + int local_ut_x = ut_x & 0xF; + int local_ut_z = ut_z & 0xF; + mActor_name_t* fg_p = aMR_GetLayerTopFg(layer); + u8* place_table = aMR_GetLayerPlaceTable(layer); + + if (fg_p != NULL) { + int ut = local_ut_x + local_ut_z * UT_X_NUM; + int targetFtrID = place_table[ut]; + + if (targetFtrID != aMR_NO_FTR_ID && targetFtrID != aMR_NO_FTR_ID2 && l_aMR_work.ftr_actor_list != NULL && + l_aMR_work.used_list != NULL) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[targetFtrID]; + mActor_name_t item = mRmTp_FtrIdx2FtrItemNo(ftr_actor->name, mRmTp_DIRECT_SOUTH); + + if (item_no != NULL) { + *item_no = item; + } + + if (ftrID != NULL) { + *ftrID = targetFtrID; + } + + if (ITEM_IS_FTR(item) || item == RSV_FE1F) { + if (targetFtrID >= 0 && targetFtrID < l_aMR_work.list_size) { + return TRUE; + } + } + + return FALSE; + } + } + + if (item_no != NULL) { + *item_no = RSV_NO; + } + + if (ftrID != NULL) { + *ftrID = 0; + } + + return FALSE; +} + +static void aMR_FtrID2ExtinguishFurniture(int ftrID) { + if (ftrID >= 0 && ftrID < l_aMR_work.list_size && l_aMR_work.ftr_actor_list != NULL && + l_aMR_work.used_list != NULL) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + u8 used = l_aMR_work.used_list[ftrID]; + + if (used == TRUE) { + int ut_x; + int ut_z; + u8 shape = ftr_actor->shape_type; + int ut; + + if (aMR_Wpos2PlaceNumber(&ut_x, &ut_z, ftr_actor->position, ftr_actor->shape_type)) { + ut = ut_x + ut_z * UT_X_NUM; + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, FALSE); + ftr_actor->state = aFTR_STATE_BYE; + aMR_SetCleanUpFtrSE(ftr_actor->position); + aMR_SetInfoFurnitureTable(shape, ut, aMR_NO_FTR_ID, ftr_actor->layer); + mCoBG_CrossOffMoveBg(ftr_actor->move_bg_idx); + } + } + } +} + +static int aMR_JudgePlace2ndLayer(int ut_x, int ut_z) { + u32 player_no = Common_Get(player_no); + + if (aMR_CLIP != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)aMR_CLIP->my_room_actor_p; + + if (aMR_CheckRoomOwner(player_no, my_room)) { + mActor_name_t* fg_layer0_p = aMR_GetLayerTopFg(mCoBG_LAYER0); + mActor_name_t* fg_layer1_p = aMR_GetLayerTopFg(mCoBG_LAYER1); + int local_ut_x = ut_x & 0xF; + int local_ut_z = ut_z & 0xF; + + if (local_ut_x < UT_X_NUM && local_ut_z < UT_Z_NUM && fg_layer0_p != NULL && fg_layer1_p != NULL) { + int ut = local_ut_x + local_ut_z * UT_X_NUM; + mActor_name_t item; + int ftrID; + + if (fg_layer0_p[ut] == EMPTY_NO) { + return FALSE; + } + + if (aMR_UnitNum2FtrItemNoFtrID(&item, &ftrID, local_ut_x, local_ut_z, mCoBG_LAYER0)) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + u8 used = l_aMR_work.used_list[ftrID]; + + if (used && aMR_layer_set_info[ftr_actor->name] == aFTR_SET_TYPE_SURFACE && + fg_layer1_p[ut] == EMPTY_NO) { + return TRUE; + } + } + } + } + } + + return FALSE; +} + +static void aMR_OpenCloseCommonMove(FTR_ACTOR* ftr_actor, ACTOR* actorx, GAME* game, f32 start, f32 end) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + switch (ftr_actor->demo_status) { + case 1: + keyframe->frame_control.start_frame = start; + keyframe->frame_control.end_frame = end; + keyframe->frame_control.speed = 0.5f; + + if (mPlib_check_player_warp_forEvent() == FALSE && + mPlib_get_player_actor_main_index(game) == mPlayer_INDEX_OPEN_FURNITURE) { + ftr_actor->demo_status = 2; + } + break; + case 2: + cKF_SkeletonInfo_R_play(keyframe); + ftr_actor->demo_status = 3; + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_DRAWERS)) { + sAdo_OngenTrgStart(NA_SE_DRAWER_OPEN, &ftr_actor->position); + } else if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_WARDROBE)) { + sAdo_OngenTrgStart(NA_SE_FTR_DOOR_OPEN, &ftr_actor->position); + } else { + sAdo_OngenTrgStart(NA_SE_FTR_DOOR_OPEN, &ftr_actor->position); + } + break; + case 3: + if (keyframe->frame_control.speed == 0.0f && cKF_SkeletonInfo_R_play(keyframe) == cKF_STATE_STOPPED) { + ftr_actor->demo_status = 4; + } + + if (cKF_SkeletonInfo_R_play(keyframe) == cKF_STATE_STOPPED) { + keyframe->frame_control.speed = 0.0f; + } + break; + case 5: + keyframe->frame_control.start_frame = end; + keyframe->frame_control.end_frame = start; + keyframe->frame_control.speed = 0.5f; + + if (mPlib_check_player_warp_forEvent() == FALSE && + mPlib_get_player_actor_main_index(game) == mPlayer_INDEX_CLOSE_FURNITURE) { + cKF_SkeletonInfo_R_play(keyframe); + ftr_actor->demo_status = 7; + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_DRAWERS)) { + sAdo_OngenTrgStart(NA_SE_DRAWER_CLOSE, &ftr_actor->position); + } + } + break; + case 7: + if (keyframe->frame_control.speed == 0.0f && cKF_SkeletonInfo_R_play(keyframe) == cKF_STATE_STOPPED) { + my_room->state = 0; + ftr_actor->demo_status = 0; + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_DRAWERS)) { + sAdo_OngenTrgStart(NA_SE_DRAWER_SHUT, &ftr_actor->position); + } else if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_WARDROBE)) { + sAdo_OngenTrgStart(NA_SE_FTR_DOOR_CLOSE, &ftr_actor->position); + } else { + sAdo_OngenTrgStart(NA_SE_FTR_DOOR_CLOSE, &ftr_actor->position); + } + } + + if (cKF_SkeletonInfo_R_play(keyframe) == cKF_STATE_STOPPED) { + keyframe->frame_control.speed = 0.0f; + } + break; + default: + break; + } +} + +static void aMR_MiniDiskCommonMove(FTR_ACTOR* ftr_actor, ACTOR* actorx, GAME* game, f32 start, f32 end) { + + if (ftr_actor->haniwa_state == 1) { + aMR_ReserveBgm(actorx, BGM_MD0 + (ftr_actor->items[0] - ITM_MINIDISK_START), ftr_actor, 0); + ftr_actor->haniwa_state = 0; + } + + if (start == 0.0f && end == 0.0f) { + switch (ftr_actor->demo_status) { + case 0: + break; + case 1: + ftr_actor->demo_status = 4; + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + ftr_actor->demo_status = 0; + break; + case 6: + break; + case 7: + break; + } + } else { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + + switch (ftr_actor->demo_status) { + case 1: + + if (mPlib_check_player_warp_forEvent() == FALSE) { + keyframe->frame_control.start_frame = start; + keyframe->frame_control.end_frame = end; + keyframe->frame_control.speed = 0.5f; + ftr_actor->demo_status = 2; + } + break; + case 2: + cKF_SkeletonInfo_R_play(keyframe); + ftr_actor->demo_status = 3; + break; + case 3: + if (keyframe->frame_control.speed == 0.0f && cKF_SkeletonInfo_R_play(keyframe) == cKF_STATE_STOPPED) { + ftr_actor->demo_status = 4; + } + + if (cKF_SkeletonInfo_R_play(keyframe) == cKF_STATE_STOPPED) { + keyframe->frame_control.speed = 0.0f; + } + break; + case 5: + if (mPlib_check_player_warp_forEvent() == FALSE) { + keyframe->frame_control.start_frame = end; + keyframe->frame_control.end_frame = start; + keyframe->frame_control.speed = 0.5f; + } + break; + case 7: + if (keyframe->frame_control.speed == 0.0f && cKF_SkeletonInfo_R_play(keyframe) == cKF_STATE_STOPPED) { + my_room->state = 0; + ftr_actor->demo_status = 0; + } + + if (cKF_SkeletonInfo_R_play(keyframe) == cKF_STATE_STOPPED) { + keyframe->frame_control.speed = 0.0f; + } + break; + default: + break; + } + } +} diff --git a/src/audio.c b/src/audio.c index 9fe6c6d2..057d63f4 100644 --- a/src/audio.c +++ b/src/audio.c @@ -13,7 +13,7 @@ int S_ongenpos_refuse_fg; -static void sAdo_Calc_MicPosition_common(f32* fcalc, u16* scalc, xyz_t* pos) { +static void sAdo_Calc_MicPosition_common(f32* fcalc, u16* scalc, const xyz_t* pos) { f32 diff; xyz_t posd; @@ -35,12 +35,12 @@ static void sAdo_Calc_MicPosition_common(f32* fcalc, u16* scalc, xyz_t* pos) { } } -extern void sAdo_Calc_MicPosition_forTrig(f32* fcalc, u16* scalc, xyz_t* pos) { +extern void sAdo_Calc_MicPosition_forTrig(f32* fcalc, u16* scalc, const xyz_t* pos) { sAdo_Calc_MicPosition_common(fcalc, scalc, pos); } -extern void sAdo_Calc_MicPosition_forLevel(f32* fcalc, u16* scalc, xyz_t* pos) { +extern void sAdo_Calc_MicPosition_forLevel(f32* fcalc, u16* scalc, const xyz_t* pos) { sAdo_Calc_MicPosition_common(fcalc, scalc, pos); } @@ -60,7 +60,7 @@ extern void sAdo_SysTrgStart(u16 id) { Na_SysTrgStart(id); } -extern void sAdo_PlyWalkSe(int walk, xyz_t* pos) { +extern void sAdo_PlyWalkSe(int walk, const xyz_t* pos) { f32 fcalc; u16 scalc; @@ -69,7 +69,7 @@ extern void sAdo_PlyWalkSe(int walk, xyz_t* pos) { Na_PlyWalkSe(walk, scalc, fcalc); } -extern void sAdo_PlyWalkSeRoom(int walk, xyz_t* pos) { +extern void sAdo_PlyWalkSeRoom(int walk, const xyz_t* pos) { f32 fcalc; u16 scalc; @@ -78,7 +78,7 @@ extern void sAdo_PlyWalkSeRoom(int walk, xyz_t* pos) { Na_PlyWalkSeRoom(walk, scalc, fcalc); } -extern void sAdo_NpcWalkSe(int walk, xyz_t* pos) { +extern void sAdo_NpcWalkSe(int walk, const xyz_t* pos) { f32 fcalc; u16 scalc; @@ -87,7 +87,7 @@ extern void sAdo_NpcWalkSe(int walk, xyz_t* pos) { Na_NpcWalkSe(walk, scalc, fcalc); } -extern void sAdo_NpcWalkSeRoom(int walk, xyz_t* pos) { +extern void sAdo_NpcWalkSeRoom(int walk, const xyz_t* pos) { f32 fcalc; u16 scalc; @@ -135,7 +135,7 @@ extern void sAdo_SysLevStop(u8 id) { Na_SysLevStop(id); } -extern void sAdo_OngenPos(u32 p1, u8 p2, xyz_t* pos) { +extern void sAdo_OngenPos(u32 p1, u8 p2, const xyz_t* pos) { u16 scalc; f32 fcalc; @@ -146,7 +146,7 @@ extern void sAdo_OngenPos(u32 p1, u8 p2, xyz_t* pos) { } } -extern void sAdo_OngenTrgStart(u16 id, xyz_t* pos) { +extern void sAdo_OngenTrgStart(u16 id, const xyz_t* pos) { u16 scalc; f32 fcalc; @@ -171,7 +171,7 @@ extern void sAdo_SetVoiceMode(u8 mode) { Na_SetVoiceMode(mode); } -extern void sAdo_FloorTrgStart(u16 id, xyz_t* pos) { +extern void sAdo_FloorTrgStart(u16 id, const xyz_t* pos) { u16 scalc; f32 fcalc; @@ -195,13 +195,13 @@ extern void sAdo_RhythmAllStop() { Na_RhythmAllStop(); } -extern void sAdo_FurnitureInst(int track_id, s8 cb, s32 cl, xyz_t* pos) { +extern void sAdo_FurnitureInst(u32 id, u8 inst, u8* melody, const xyz_t* pos) { u16 scalc; f32 fcalc; sAdo_Calc_MicPosition_common(&fcalc, &scalc, pos); - Na_FurnitureInst(track_id, cb, cl, scalc, fcalc); + Na_FurnitureInst(id, inst, melody, scalc, fcalc); } extern void sAdo_Pause(u8 mode) { @@ -233,7 +233,7 @@ extern int sAdo_InstCountGet() { return Na_InstCountGet(); } -extern void sAdo_RhythmPos(u32 p, u8 haniwa_id, xyz_t* pos) { +extern void sAdo_RhythmPos(u32 p, u8 haniwa_id, const xyz_t* pos) { u16 scalc; f32 fcalc; @@ -247,7 +247,7 @@ extern void sAdo_SpecChange(int spec) { Na_SpecChange(spec); } -extern void sAdo_MDPlayerPos(xyz_t* pos, u16 s1, u16 s2, int p) { +extern void sAdo_MDPlayerPos(const xyz_t* pos, u16 s1, u16 s2, int p) { u16 scalc; f32 fcalc; @@ -316,7 +316,7 @@ extern void sAdos_TTKK_ARM(u8 mode) { Na_TTKK_ARM(mode); } -extern void sAdo_OngenTrgStartSpeed(f32 speed, u16 s1, xyz_t* pos) { +extern void sAdo_OngenTrgStartSpeed(f32 speed, u16 s1, const xyz_t* pos) { f32 fcalc; u16 scalc; @@ -443,7 +443,7 @@ extern void sAdo_SceneMode(u8 mode) { Na_SceneMode(mode); } -extern u8 sAdo_RoomIncectPos(u32 f, u16 u, xyz_t* pos) { +extern u8 sAdo_RoomIncectPos(u32 f, u16 u, const xyz_t* pos) { u16 scalc; f32 fcalc; @@ -452,13 +452,13 @@ extern u8 sAdo_RoomIncectPos(u32 f, u16 u, xyz_t* pos) { return Na_RoomIncectPos(f, u, scalc, fcalc); } -extern void sAdo_FurnitureInstPos(u32 f, xyz_t* pos) { +extern void sAdo_FurnitureInstPos(u32 id, const xyz_t* pos) { u16 scalc; f32 fcalc; sAdo_Calc_MicPosition_forLevel(&fcalc, &scalc, pos); - Na_FurnitureInstPos(f, scalc, fcalc); + Na_FurnitureInstPos(id, scalc, fcalc); } extern void sAdo_Set_ongenpos_refuse_fg(int state) { @@ -476,7 +476,7 @@ extern int sAdo_GetSoundFrameCounter() { return Na_GetSoundFrameCounter(); } -extern int sAdo_CheckOnPlussBridge(xyz_t* pos, u32 atr) { +extern int sAdo_CheckOnPlussBridge(const xyz_t* pos, u32 atr) { f32 x; f32 z; @@ -490,7 +490,7 @@ extern int sAdo_CheckOnPlussBridge(xyz_t* pos, u32 atr) { return 0; } -extern void sAdo_RegistPlussBridge(xyz_t* pos) { +extern void sAdo_RegistPlussBridge(const xyz_t* pos) { Common_Set(pluss_bridge_pos, pos); } diff --git a/src/c_keyframe.c b/src/c_keyframe.c index f894f228..a65391f5 100644 --- a/src/c_keyframe.c +++ b/src/c_keyframe.c @@ -1014,9 +1014,8 @@ extern void cKF_SkeletonInfo_R_T_combine_play(int* arg1, int* arg2, int* arg3, c *arg3 = cKF_FrameControl_play(&info3->frame_control); } -extern void cKF_SkeletonInfo_R_Animation_Set_base_shape_trs(f32 transx, f32 transy, f32 transz, - cKF_SkeletonInfo_R_c* keyframe, s16 anglex, s16 angley, - s16 anglez) { +extern void cKF_SkeletonInfo_R_Animation_Set_base_shape_trs(cKF_SkeletonInfo_R_c* keyframe, f32 transx, f32 transy, + f32 transz, s16 anglex, s16 angley, s16 anglez) { keyframe->base_model_translation.x = transx; keyframe->base_model_translation.y = transy; keyframe->base_model_translation.z = transz; From 39fe30e0d746ec910c417cb1f2fa49dc58ef0b9c Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sun, 14 Apr 2024 15:34:40 -0400 Subject: [PATCH 4/4] Finish & link ac_my_room --- config/rel_slices.yml | 5 + include/MSL_C/math.h | 1 + include/ac_furniture.h | 32 +- include/ac_my_room.h | 7 +- include/audio.h | 2 +- include/audio_defs.h | 6 + include/jaudio_NES/game64.h | 2 +- include/m_actor.h | 7 - include/m_field_info.h | 215 +++-- include/m_name_table.h | 1 + include/m_player.h | 556 ++++++------- include/m_player_lib.h | 3 + src/ac_my_room.c | 80 +- src/ac_my_room_action.c_inc | 1379 +++++++++++++++++++++++++++++++++ src/ac_my_room_data.c_inc | 182 ++++- src/ac_my_room_draw.c_inc | 378 +++++++++ src/ac_my_room_move.c_inc | 42 +- src/ac_my_room_msg_ctrl.c_inc | 1 - src/audio.c | 2 +- src/m_actor.c | 37 +- 20 files changed, 2472 insertions(+), 466 deletions(-) create mode 100644 src/ac_my_room_action.c_inc create mode 100644 src/ac_my_room_draw.c_inc diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 43837485..6f9ec3c1 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -459,6 +459,11 @@ ac_my_indoor.c: .text: [0x8046EE38, 0x80470288] .rodata: [0x80644A88, 0x80644A98] .data: [0x806870F0, 0x806873E8] +ac_my_room.c: + .text: [0x80470288, 0x80482D9C] + .rodata: [0x80644A98, 0x80644C28] + .data: [0x806873E8, 0x8068A378] + .bss: [0x812FBEB0, 0x812FC5E0] ac_psnowman.c: .text: [0x80484098, 0x80484694] .rodata: [0x80644C30, 0x80644C60] diff --git a/include/MSL_C/math.h b/include/MSL_C/math.h index 01e4da80..3fc61d26 100644 --- a/include/MSL_C/math.h +++ b/include/MSL_C/math.h @@ -13,6 +13,7 @@ extern "C" { #define SQRT2 (1.4142135623730950488016887242097) #define F_SQRT2 ((f32)SQRT2) +#define F_SQRT2_DIV2 (0.707106f) #define SQRTF(f) (__frsqrte(f)) diff --git a/include/ac_furniture.h b/include/ac_furniture.h index 9716da25..3e27ccaa 100644 --- a/include/ac_furniture.h +++ b/include/ac_furniture.h @@ -66,6 +66,7 @@ enum { }; enum { + aFTR_INTERACTION_NONE = 0, aFTR_INTERACTION_STORAGE_DRAWERS = 1, // dressers aFTR_INTERACTION_STORAGE_WARDROBE = 2, // double doors aFTR_INTERACTION_STORAGE_CLOSET = 4, // single door @@ -122,6 +123,21 @@ enum { aFTR_CONTACT_ACTION_NUM }; +enum { + aFTR_CONTACT_ACTION_TYPE_CHAIR1, + aFTR_CONTACT_ACTION_TYPE_CHAIR4, + aFTR_CONTACT_ACTION_TYPE_SOFA, + aFTR_CONTACT_ACTION_TYPE_BED_SINGLE, + aFTR_CONTACT_ACTION_TYPE_BED_DOUBLE, + + aFTR_CONTACT_ACTION_TYPE_NUM +}; + +#define aFTR_CHK_CONTACT_ACTION(cnt, action) (((cnt) >> (aFTR_CONTACT_ACTION_TYPE_##action)) & 1) +#define aFTR_CHK_CHAIR(cnt) \ + (aFTR_CHK_CONTACT_ACTION(cnt, CHAIR1) || aFTR_CHK_CONTACT_ACTION(cnt, CHAIR4) || aFTR_CHK_CONTACT_ACTION(cnt, SOFA)) +#define aFTR_CHK_BED(cnt) (aFTR_CHK_CONTACT_ACTION(cnt, BED_SINGLE) || aFTR_CHK_CONTACT_ACTION(cnt, BED_DOUBLE)) + enum { aFTR_SET_TYPE_NORMAL, /* Can't be placed on top and is not a table (layer0) */ aFTR_SET_TYPE_SURFACE, /* Is a surface (layer0) */ @@ -130,6 +146,14 @@ enum { aFTR_SET_TYPE_NUM }; +enum { + aFTR_KANKYO_MAP_NONE, + aFTR_KANKYO_MAP_OPA, + aFTR_KANKYO_MAP_XLU, + + aFTR_KANKYO_MAP_NUM +}; + typedef void (*aFTR_FTR_CT_PROC)(FTR_ACTOR*, u8*); typedef void (*aFTR_FTR_MOVE_PROC)(FTR_ACTOR*, ACTOR*, GAME*, u8*); typedef void (*aFTR_FTR_DRAW_PROC)(FTR_ACTOR*, ACTOR*, GAME*, u8*); @@ -190,10 +214,10 @@ struct furniture_actor_s { xyz_t position; xyz_t last_position; xyz_t target_position; - int target_distance; /* distance to target position */ - f32 player_distance; /* distance to the player */ - f32 angle_y; /* current Y angle */ - f32 angle_y_target; /* goal Y angle */ + int target_direction; /* direction to target position */ + f32 player_distance; /* distance to the player */ + f32 angle_y; /* current Y angle */ + f32 angle_y_target; /* goal Y angle */ s16 state; u8 shape_type; /* current size & shape (rotation) */ u8 original_shape_type; /* original size & shape (rotation) */ diff --git a/include/ac_my_room.h b/include/ac_my_room.h index 9c602d63..95de307d 100644 --- a/include/ac_my_room.h +++ b/include/ac_my_room.h @@ -149,7 +149,7 @@ typedef struct room_pickup_s { int picking_up_flag; s16 layer; s16 dust_effect_timer; - u16 icon; + s16 icon; } aMR_pickup_info_c; typedef struct room_rsv_ftr_s { @@ -291,6 +291,11 @@ extern FTR_ACTOR* aMR_GetParentFactor(FTR_ACTOR* ftr_actor, ACTOR* my_room_actor extern s16 aMR_GetParentAngleOffset(FTR_ACTOR* ftr_actor, ACTOR* my_room_actorx); extern void aMR_SetSurprise(ACTOR* my_room_actor, s16 rot); extern void aMR_RadioCommonMove(FTR_ACTOR* ftr_actor, ACTOR* my_room_actorx); +extern void aMR_SaveWaltzTempo2(void); +extern u8 aMR_GetAlphaEdge(u16 ftr_name); +extern int aMR_DrawDolphinMode(u16 ftr_name); +extern Gfx* aMR_IconNo2Gfx1(int icon_no); +extern Gfx* aMR_IconNo2Gfx2(int icon_no); #ifdef __cplusplus } diff --git a/include/audio.h b/include/audio.h index 99b2f5bc..f71359ae 100644 --- a/include/audio.h +++ b/include/audio.h @@ -58,7 +58,7 @@ extern void sAdo_OngenTrgStart(u16 id, const xyz_t* pos); extern void sAdo_SetOutMode(u8 mode); extern void sAdo_SetVoiceMode(u8 mode); -extern void sAdo_FloorTrgStart(u16 id, const xyz_t* pos); +extern void sAdo_FloorTrgStart(u8 id, const xyz_t* pos); extern void sAdo_RhythmStart(u32 id, s8 type, s8 wait); extern void sAdo_RhythmStop(u32 id); diff --git a/include/audio_defs.h b/include/audio_defs.h index e3553a44..b912a55c 100644 --- a/include/audio_defs.h +++ b/include/audio_defs.h @@ -60,6 +60,9 @@ typedef enum audio_sound_effects { NA_SE_TOOL_BROKEN2, NA_SE_TOOL_BROKEN3, + NA_SE_STONECOIN_ROLL = 0x7D, + NA_SE_STONECOIN_DRAG = 0x7E, + NA_SE_ROD_STROKE = 0x109, NA_SE_ROD_BACK, @@ -86,6 +89,7 @@ typedef enum audio_sound_effects { NA_SE_166 = 0x166, NA_SE_UCHIWA = 0x167, + NA_SE_LAWNMOWER = 0x177, NA_SE_SCOOP_SHIGEMI = 0x401, @@ -98,6 +102,8 @@ typedef enum audio_sound_effects { NA_SE_BED_NEGAERI, NA_SE_BED_OUT, + NA_SE_ROTATE = 0x41A, + NA_SE_SOFT_CHAIR_SIT = 0x41F, NA_SE_HARD_CHAIR_SIT, NA_SE_BUBU_CHAIR_SIT, diff --git a/include/jaudio_NES/game64.h b/include/jaudio_NES/game64.h index e75e8474..ed32bfef 100644 --- a/include/jaudio_NES/game64.h +++ b/include/jaudio_NES/game64.h @@ -29,7 +29,7 @@ extern void Na_OngenPos(u32, u8, u16, f32); extern void Na_OngenTrgStart(u16, u16, f32); extern void Na_SetOutMode(u8); extern void Na_SetVoiceMode(u8); -extern void Na_FloorTrgStart(u16, u16, f32); +extern void Na_FloorTrgStart(u8, u16, f32); extern void Na_Pause(u8); extern void Na_RhythmPos(u32, u8, u16, f32); extern void Na_SpecChange(int); diff --git a/include/m_actor.h b/include/m_actor.h index 8a4d1bd2..c7a193de 100644 --- a/include/m_actor.h +++ b/include/m_actor.h @@ -1187,16 +1187,9 @@ extern void Actor_get_overlay_area(ACTOR_DLFTBL* dlftbl, int unused, size_t allo extern void Actor_init_actor_class(ACTOR* actor, ACTOR_PROFILE* profile, ACTOR_DLFTBL* dlftbl, GAME_PLAY* play, int bank_idx, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg); -#ifndef MUST_MATCH extern ACTOR* Actor_info_make_actor(Actor_info* actor_info, GAME* game, s16 profile_no, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, s8 npc_info_idx, int data_bank_idx); -#else -extern asm ACTOR* Actor_info_make_actor(Actor_info* actor_info, GAME* game, s16 profile_no, f32 x, f32 y, f32 z, - s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, - s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, s8 npc_info_idx, - int data_bank_idx); -#endif extern ACTOR* Actor_info_make_child_actor(Actor_info* actor_info, ACTOR* parent_actor, GAME* game, s16 profile, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, int data_bank_idx); diff --git a/include/m_field_info.h b/include/m_field_info.h index e5455788..9b646568 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -15,8 +15,8 @@ extern "C" { #define mFI_UNIT_BASE_SIZE 40 #define mFI_UNIT_BASE_SIZE_F ((f32)mFI_UNIT_BASE_SIZE) -#define mFI_UT_WORLDSIZE_X 40 -#define mFI_UT_WORLDSIZE_Z 40 +#define mFI_UT_WORLDSIZE_X mFI_UNIT_BASE_SIZE +#define mFI_UT_WORLDSIZE_Z mFI_UNIT_BASE_SIZE #define mFI_UT_WORLDSIZE_X_F ((f32)mFI_UT_WORLDSIZE_X) #define mFI_UT_WORLDSIZE_Z_F ((f32)mFI_UT_WORLDSIZE_Z) @@ -30,6 +30,8 @@ extern "C" { #define mFI_BK_WORLDSIZE_X_F (mFI_UT_WORLDSIZE_X_F * UT_X_NUM) #define mFI_BK_WORLDSIZE_Z_F (mFI_UT_WORLDSIZE_Z_F * UT_Z_NUM) +#define mFI_POS2UT(pos) ((int)((pos) / mFI_UNIT_BASE_SIZE_F)) + #define mFI_ROW_TO_CHARSTR(row) ((row) + 'A') #define mFI_COL_TO_CHARSTR(col) ((col) + '0') @@ -39,24 +41,24 @@ extern "C" { #define mFI_MAX_SHELLS_PER_BLOCK 4 enum field_type { - mFI_FIELDTYPE_FG, - mFI_FIELDTYPE_1, - mFI_FIELDTYPE_2, - mFI_FIELDTYPE_ROOM, - mFI_FIELDTYPE_NPC_ROOM, - mFI_FIELDTYPE_DEMO, - mFI_FIELDTYPE_PLAYER_ROOM, + mFI_FIELDTYPE_FG, + mFI_FIELDTYPE_1, + mFI_FIELDTYPE_2, + mFI_FIELDTYPE_ROOM, + mFI_FIELDTYPE_NPC_ROOM, + mFI_FIELDTYPE_DEMO, + mFI_FIELDTYPE_PLAYER_ROOM, - mFI_FIELDTYPE_NUM + mFI_FIELDTYPE_NUM }; enum field_type2 { - mFI_FIELDTYPE2_FG, - mFI_FIELDTYPE2_PLAYER_ROOM, - mFI_FIELDTYPE2_NPC_ROOM, - mFI_FIELDTYPE2_ROOM, + mFI_FIELDTYPE2_FG, + mFI_FIELDTYPE2_PLAYER_ROOM, + mFI_FIELDTYPE2_NPC_ROOM, + mFI_FIELDTYPE2_ROOM, - mFI_FIELDTYPE2_NUM + mFI_FIELDTYPE2_NUM }; #define mFI_TO_FIELD_ID(type, index) (((type) << 12) | (index)) @@ -64,134 +66,126 @@ enum field_type2 { #define mFI_TYPE(type) ((type) << 12) enum field_room { - /* TODO: others */ - mFI_FIELD_FG = mFI_TO_FIELD_ID(mFI_FIELDTYPE_FG, 0), + /* TODO: others */ + mFI_FIELD_FG = mFI_TO_FIELD_ID(mFI_FIELDTYPE_FG, 0), - mFI_FIELD_ROOM0 = mFI_TO_FIELD_ID(mFI_FIELDTYPE_ROOM, 0), - mFI_FIELD_ROOM_SHOP0, /* 0x3001 */ - mFI_FIELD_ROOM_BROKER_SHOP, /* 0x3002 */ - mFI_FIELD_ROOM_POST_OFFICE, /* 0x3003 */ - mFI_FIELD_ROOM_POLICE_BOX, /* 0x3004 */ - mFI_FIELD_ROOM_BUGGY, /* 0x3005 */ - mFI_FIELD_ROOM_SHOP1, /* 0x3006 */ - mFI_FIELD_ROOM_SHOP2, /* 0x3007 */ - mFI_FIELD_ROOM_SHOP3_1, /* 0x3008 */ - mFI_FIELD_ROOM_SHOP3_2, /* 0x3009 */ - mFI_FIELD_ROOM_KAMAKURA, /* 0x300A */ - mFI_FIELD_ROOM_MUSEUM_ENTRANCE, /* 0x300B */ - mFI_FIELD_ROOM_MUSEUM_PAINTING, /* 0x300C */ - mFI_FIELD_ROOM_MUSEUM_FOSSIL, /* 0x300D */ - mFI_FIELD_ROOM_MUSEUM_INSECT, /* 0x300E */ - mFI_FIELD_ROOM_MUSEUM_FISH, /* 0x300F */ - mFI_FIELD_ROOM_NEEDLEWORK, /* 0x3010 */ - mFI_FIELD_ROOM_LIGHTHOUSE, /* 0x3011 */ - mFI_FIELD_ROOM_TENT, /* 0x3012 */ + mFI_FIELD_ROOM0 = mFI_TO_FIELD_ID(mFI_FIELDTYPE_ROOM, 0), + mFI_FIELD_ROOM_SHOP0, /* 0x3001 */ + mFI_FIELD_ROOM_BROKER_SHOP, /* 0x3002 */ + mFI_FIELD_ROOM_POST_OFFICE, /* 0x3003 */ + mFI_FIELD_ROOM_POLICE_BOX, /* 0x3004 */ + mFI_FIELD_ROOM_BUGGY, /* 0x3005 */ + mFI_FIELD_ROOM_SHOP1, /* 0x3006 */ + mFI_FIELD_ROOM_SHOP2, /* 0x3007 */ + mFI_FIELD_ROOM_SHOP3_1, /* 0x3008 */ + mFI_FIELD_ROOM_SHOP3_2, /* 0x3009 */ + mFI_FIELD_ROOM_KAMAKURA, /* 0x300A */ + mFI_FIELD_ROOM_MUSEUM_ENTRANCE, /* 0x300B */ + mFI_FIELD_ROOM_MUSEUM_PAINTING, /* 0x300C */ + mFI_FIELD_ROOM_MUSEUM_FOSSIL, /* 0x300D */ + mFI_FIELD_ROOM_MUSEUM_INSECT, /* 0x300E */ + mFI_FIELD_ROOM_MUSEUM_FISH, /* 0x300F */ + mFI_FIELD_ROOM_NEEDLEWORK, /* 0x3010 */ + mFI_FIELD_ROOM_LIGHTHOUSE, /* 0x3011 */ + mFI_FIELD_ROOM_TENT, /* 0x3012 */ - mFI_FIELD_NPCROOM0 = mFI_TO_FIELD_ID(mFI_FIELDTYPE_NPC_ROOM, 0), - mFI_FIELD_NPCROOM_FIELD_TOOL_INSIDE, + mFI_FIELD_NPCROOM0 = mFI_TO_FIELD_ID(mFI_FIELDTYPE_NPC_ROOM, 0), + mFI_FIELD_NPCROOM_FIELD_TOOL_INSIDE, - mFI_FIELD_DEMO_STARTDEMO = mFI_TO_FIELD_ID(mFI_FIELDTYPE_DEMO, 0), - mFI_FIELD_DEMO_STARTDEMO2, - mFI_FIELD_DEMO_PLAYERSELECT, - mFI_FIELD_DEMO_STARTDEMO3, + mFI_FIELD_DEMO_STARTDEMO = mFI_TO_FIELD_ID(mFI_FIELDTYPE_DEMO, 0), + mFI_FIELD_DEMO_STARTDEMO2, + mFI_FIELD_DEMO_PLAYERSELECT, + mFI_FIELD_DEMO_STARTDEMO3, - mFI_FIELD_PLAYER0_ROOM = mFI_TO_FIELD_ID(mFI_FIELDTYPE_PLAYER_ROOM, 0), - mFI_FIELD_PLAYER1_ROOM, - mFI_FIELD_PLAYER2_ROOM, - mFI_FIELD_PLAYER3_ROOM, + mFI_FIELD_PLAYER0_ROOM = mFI_TO_FIELD_ID(mFI_FIELDTYPE_PLAYER_ROOM, 0), + mFI_FIELD_PLAYER1_ROOM, + mFI_FIELD_PLAYER2_ROOM, + mFI_FIELD_PLAYER3_ROOM, - /* TODO: others */ + /* TODO: others */ }; -#define mFI_GET_PLAYER_ROOM_NO(field_id) (((field_id)-mFI_FIELD_PLAYER0_ROOM) & 3) -#define mFI_IS_PLAYER_ROOM(field_id) \ - ((field_id) == mFI_FIELD_PLAYER0_ROOM || (field_id) == mFI_FIELD_PLAYER1_ROOM || \ - (field_id) == mFI_FIELD_PLAYER2_ROOM || (field_id) == mFI_FIELD_PLAYER3_ROOM) +#define mFI_GET_PLAYER_ROOM_NO(field_id) (((field_id) - mFI_FIELD_PLAYER0_ROOM) & 3) +#define mFI_IS_PLAYER_ROOM(field_id) \ + ((field_id) == mFI_FIELD_PLAYER0_ROOM || (field_id) == mFI_FIELD_PLAYER1_ROOM || \ + (field_id) == mFI_FIELD_PLAYER2_ROOM || (field_id) == mFI_FIELD_PLAYER3_ROOM) /* "wade" between acres (acre transition) */ enum player_wade_state { - mFI_WADE_NONE, - mFI_WADE_START, - mFI_WADE_INPROGRESS, - mFI_WADE_END, - mFI_WADE_ERROR, + mFI_WADE_NONE, + mFI_WADE_START, + mFI_WADE_INPROGRESS, + mFI_WADE_END, + mFI_WADE_ERROR, - mFI_WADE_NUM + mFI_WADE_NUM }; enum { - mFI_DEPOSIT_ON, - mFI_DEPOSIT_OFF, - mFI_DEPOSIT_GET, + mFI_DEPOSIT_ON, + mFI_DEPOSIT_OFF, + mFI_DEPOSIT_GET, - mFI_DEPOSIT_NUM + mFI_DEPOSIT_NUM }; enum { - mFI_MOVEDIR_NONE, - mFI_MOVEDIR_RIGHT, - mFI_MOVEDIR_LEFT, - mFI_MOVEDIR_UP, - mFI_MOVEDIR_DOWN, + mFI_MOVEDIR_NONE, + mFI_MOVEDIR_RIGHT, + mFI_MOVEDIR_LEFT, + mFI_MOVEDIR_UP, + mFI_MOVEDIR_DOWN, - mFI_MOVEDIR_NUM + mFI_MOVEDIR_NUM }; /* Not sure about these other than the island one */ +enum { mFI_CLIMATE_0, mFI_CLIMATE_ISLAND, mFI_CLIMATE_2, mFI_CLIMATE_3, mFI_CLIMATE_4, mFI_CLIMATE_5, mFI_CLIMATE_NUM }; + enum { - mFI_CLIMATE_0, - mFI_CLIMATE_ISLAND, - mFI_CLIMATE_2, - mFI_CLIMATE_3, - mFI_CLIMATE_4, - mFI_CLIMATE_5, - mFI_CLIMATE_NUM + mFI_DIGSTATUS_MISS, + mFI_DIGSTATUS_CANCEL, + mFI_DIGSTATUS_FILLIN, + mFI_DIGSTATUS_DIG, + mFI_DIGSTATUS_PUT_ITEM, + mFI_DIGSTATUS_GET_ITEM, + + mFI_DIGSTATUS_NUM }; enum { - mFI_DIGSTATUS_MISS, - mFI_DIGSTATUS_CANCEL, - mFI_DIGSTATUS_FILLIN, - mFI_DIGSTATUS_DIG, - mFI_DIGSTATUS_PUT_ITEM, - mFI_DIGSTATUS_GET_ITEM, - - mFI_DIGSTATUS_NUM -}; + mFI_SET_STRUCTURE_SET, + mFI_SET_STRUCTURE_REMOVE, -enum { - mFI_SET_STRUCTURE_SET, - mFI_SET_STRUCTURE_REMOVE, - - mFI_SET_STRUCTURE_NUM + mFI_SET_STRUCTURE_NUM }; /* sizeof(mFI_unit_c) == 0x14 */ typedef struct location_info_s { - /* 0x00 */ int block_x; - /* 0x04 */ int block_z; - /* 0x08 */ int unit_x; - /* 0x0C */ int unit_z; - /* 0x10 */ mActor_name_t* block_data; + /* 0x00 */ int block_x; + /* 0x04 */ int block_z; + /* 0x08 */ int unit_x; + /* 0x0C */ int unit_z; + /* 0x10 */ mActor_name_t* block_data; } mFI_unit_c; typedef struct block_table_s { - s8 block_x; - s8 block_z; + s8 block_x; + s8 block_z; - f32 pos_x; - f32 pos_z; + f32 pos_x; + f32 pos_z; - mActor_name_t* items; + mActor_name_t* items; } mFI_block_tbl_c; typedef struct visible_block_item_info_s { - int count; - mFI_block_tbl_c block_info_tbl[mFM_VISIBLE_BLOCK_NUM]; + int count; + mFI_block_tbl_c block_info_tbl[mFM_VISIBLE_BLOCK_NUM]; } mFI_item_table_c; enum { - mFI_SOUND_SOURCE_POND = 3, // TODO: might not be correct name + mFI_SOUND_SOURCE_POND = 3, // TODO: might not be correct name }; extern void mFI_ClearFieldData(); @@ -269,7 +263,7 @@ extern int mFI_GetItemTable(mFI_item_table_c* item_table, xyz_t wpos, char* file extern int mFI_FGisUpDate(); extern void mFI_SetFGUpData(); extern void mFI_BornItemON(); -//extern MATCH_FORCESTRIP void mFI_BornItemOFF(); +// extern MATCH_FORCESTRIP void mFI_BornItemOFF(); extern int mFI_ItemisBorn(); extern int mFI_ActorisBorn(); extern void mFI_SetBearActor(GAME_PLAY* play, xyz_t wpos, int set_flag); @@ -288,9 +282,10 @@ extern void mFI_SetMoveActorBitData(int bx, int bz, u16 move_actor_bit_data); extern void mFI_SetMoveActorBitData_ON(s16 move_actor_idx, int bx, int bz); extern void mFI_SetMoveActorBitData_OFF(s16 move_actor_idx, int bx, int bz); extern void mFI_MyMoveActorBitData_ON(ACTOR* actor); -//extern MATCH_FORCESTRIP void mFI_MyMoveActorBitData_OFF(ACTOR* actor); +// extern MATCH_FORCESTRIP void mFI_MyMoveActorBitData_OFF(ACTOR* actor); extern int mFI_GetMoveActorListIdx(mFM_move_actor_c* move_actor_list, int list_size, mActor_name_t actor_name); -extern int mFI_RegistMoveActorList(mActor_name_t actor_name, int bx, int bz, int ut_x, int ut_z, int npc_info_idx, s16 arg); +extern int mFI_RegistMoveActorList(mActor_name_t actor_name, int bx, int bz, int ut_x, int ut_z, int npc_info_idx, + s16 arg); extern int mFI_UnregistMoveActorList(mActor_name_t actor_name, int bx, int bz); extern int mFI_AddMoveActorList(mActor_name_t actor_name, int bx, int bz, int ut_x, int ut_z, s16 arg); extern mFM_move_actor_c* mFI_MoveActorListDma(int bx, int bz); @@ -302,12 +297,12 @@ extern int mFI_GetNextBlockNum(int* bx, int* bz); extern u16* mFI_GetDepositP(int bx, int bz); extern void mFI_ClearDeposit(int bx, int bz); extern int mFI_GetLineDeposit(u16* deposit, int ut_x); -//extern MATCH_FORCESTRIP void mFI_BlockDepositON(u16* deposit_p, int ut_x, int ut_z); +// extern MATCH_FORCESTRIP void mFI_BlockDepositON(u16* deposit_p, int ut_x, int ut_z); extern void mFI_BlockDepositOFF(u16* deposit_p, int ut_x, int ut_z); extern int mFI_GetBlockDeposit(u16* deposit_p, int ut_x, int ut_z); -//extern MATCH_FORCESTRIP void mFI_BkUtNum2DepositON(int bx, int bz, int ut_x, int ut_z); +// extern MATCH_FORCESTRIP void mFI_BkUtNum2DepositON(int bx, int bz, int ut_x, int ut_z); extern void mFI_BkUtNum2DepositOFF(int bx, int bz, int ut_x, int ut_z); -//extern MATCH_FORCESTRIP int mFI_BkUtNum2DepositGet(int bx, int bz, int ut_x, int ut_z); +// extern MATCH_FORCESTRIP int mFI_BkUtNum2DepositGet(int bx, int bz, int ut_x, int ut_z); extern void mFI_UtNum2DepositON(int ut_x, int ut_z); extern void mFI_UtNum2DepositOFF(int ut_x, int ut_z); extern int mFI_UtNum2DepositGet(int ut_x, int ut_z); @@ -320,12 +315,14 @@ extern int mFI_GetDigStatus(mActor_name_t* item, xyz_t wpos, int golden_shovel); extern void mFI_ClearHoleBlock(int bx, int bz); extern void mFI_ClearBeecomb(int bx, int bz); extern int mFI_SetFGStructure_common(mActor_name_t structure_name, int bx, int bz, int ut_x, int ut_z, int set_type); -extern int mFI_CheckStructureArea(int ut_x, int ut_z, mActor_name_t structure_name, int structure_ut_x, int structure_ut_z); +extern int mFI_CheckStructureArea(int ut_x, int ut_z, mActor_name_t structure_name, int structure_ut_x, + int structure_ut_z); extern mActor_name_t mFI_GetOtherFruit(); extern int mFI_CheckFGNpcOn(mActor_name_t item); extern int mFI_CheckLapPolice(int bx, int bz, int ut_x, int ut_z); extern int mFI_GetWaveUtinBlock(int* ut_x, int* ut_z, int bx, int bz); -extern int mFI_ClearBlockItemRandom_common(mActor_name_t item, int clear_num, mActor_name_t* fg_p, u16* deposit_p, int delete_buried); +extern int mFI_ClearBlockItemRandom_common(mActor_name_t item, int clear_num, mActor_name_t* fg_p, u16* deposit_p, + int delete_buried); extern void mFI_SetFirstSetShell(); extern void mFI_FieldMove(xyz_t player_pos); extern void mFI_PrintNowBGNum(gfxprint_t* gfxprint); diff --git a/include/m_name_table.h b/include/m_name_table.h index ff03aee2..7fa61d47 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -2253,6 +2253,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define ETC_START 0x8000 #define ETC_AIRPLANE ETC_START #define ETC_BALL (ETC_START + 1) +#define ETC_MY_ROOM (ETC_START + 2) #define ETC_MBG (ETC_START + 3) #define ETC_BOXTRICK (ETC_START + 4) #define ETC_BOXMANAGER (ETC_START + 5) diff --git a/include/m_player.h b/include/m_player.h index 978144e5..21d4ee79 100644 --- a/include/m_player.h +++ b/include/m_player.h @@ -5,6 +5,7 @@ #include "m_actor.h" #include "m_lib.h" #include "c_keyframe.h" +#include "libultra/ultratypes.h" #ifdef __cplusplus extern "C" { @@ -22,314 +23,331 @@ typedef struct player_actor_s PLAYER_ACTOR; #define mPlayer_FORCE_POSITION_ANGLE_ROTZ (1 << 6) enum { - mPlayer_ADDRESSABLE_TRUE, - mPlayer_ADDRESSABLE_FALSE_MOVEMENT, - mPlayer_ADDRESSABLE_FALSE_TALKING, - mPlayer_ADDRESSABLE_FALSE_USING_TOOL, + mPlayer_ADDRESSABLE_TRUE, + mPlayer_ADDRESSABLE_FALSE_MOVEMENT, + mPlayer_ADDRESSABLE_FALSE_TALKING, + mPlayer_ADDRESSABLE_FALSE_USING_TOOL, - mPlayer_ADDRESSABLE_NUM + mPlayer_ADDRESSABLE_NUM }; enum { - mPlayer_INDEX_DMA, - mPlayer_INDEX_INTRO, - mPlayer_INDEX_REFUSE, - mPlayer_INDEX_REFUSE_PICKUP, - mPlayer_INDEX_RETURN_DEMO, - mPlayer_INDEX_RETURN_OUTDOOR, - mPlayer_INDEX_RETURN_OUTDOOR2, - mPlayer_INDEX_WAIT, - mPlayer_INDEX_WALK, - mPlayer_INDEX_RUN, - mPlayer_INDEX_DASH, - mPlayer_INDEX_TUMBLE, - mPlayer_INDEX_TUMBLE_GETUP, - mPlayer_INDEX_TURN_DASH, - mPlayer_INDEX_FALL, - mPlayer_INDEX_WADE, - mPlayer_INDEX_DOOR, - mPlayer_INDEX_OUTDOOR, - mPlayer_INDEX_INVADE, - mPlayer_INDEX_HOLD, - mPlayer_INDEX_PUSH, - mPlayer_INDEX_PULL, - mPlayer_INDEX_ROTATE_FURNITURE, - mPlayer_INDEX_OPEN_FURNITURE, - mPlayer_INDEX_WAIT_OPEN_FURNITURE, - mPlayer_INDEX_CLOSE_FURNITURE, - mPlayer_INDEX_LIE_BED, - mPlayer_INDEX_WAIT_BED, - mPlayer_INDEX_ROLL_BED, - mPlayer_INDEX_STANDUP_BED, - mPlayer_INDEX_PICKUP, - mPlayer_INDEX_PICKUP_JUMP, - mPlayer_INDEX_PICKUP_FURNITURE, - mPlayer_INDEX_PICKUP_EXCHANGE, - mPlayer_INDEX_SITDOWN, - mPlayer_INDEX_SITDOWN_WAIT, - mPlayer_INDEX_STANDUP, - mPlayer_INDEX_SWING_AXE, - mPlayer_INDEX_AIR_AXE, - mPlayer_INDEX_REFLECT_AXE, - mPlayer_INDEX_BROKEN_AXE, - mPlayer_INDEX_SLIP_NET, - mPlayer_INDEX_READY_NET, - mPlayer_INDEX_READY_WALK_NET, - mPlayer_INDEX_SWING_NET, - mPlayer_INDEX_PULL_NET, - mPlayer_INDEX_STOP_NET, - mPlayer_INDEX_NOTICE_NET, - mPlayer_INDEX_PUTAWAY_NET, - mPlayer_INDEX_READY_ROD, - mPlayer_INDEX_CAST_ROD, - mPlayer_INDEX_AIR_ROD, - mPlayer_INDEX_RELAX_ROD, - mPlayer_INDEX_COLLECT_ROD, - mPlayer_INDEX_VIB_ROD, - mPlayer_INDEX_FLY_ROD, - mPlayer_INDEX_NOTICE_ROD, - mPlayer_INDEX_PUTAWAY_ROD, - mPlayer_INDEX_DIG_SCOOP, - mPlayer_INDEX_FILL_SCOOP, - mPlayer_INDEX_REFLECT_SCOOP, - mPlayer_INDEX_AIR_SCOOP, - mPlayer_INDEX_GET_SCOOP, - mPlayer_INDEX_PUTAWAY_SCOOP, - mPlayer_INDEX_PUTIN_SCOOP, - mPlayer_INDEX_TALK, - mPlayer_INDEX_RECIEVE_WAIT, - mPlayer_INDEX_RECIEVE_STRETCH, - mPlayer_INDEX_RECIEVE, - mPlayer_INDEX_RECIEVE_PUTAWAY, - mPlayer_INDEX_GIVE, - mPlayer_INDEX_GIVE_WAIT, - mPlayer_INDEX_TAKEOUT_ITEM, - mPlayer_INDEX_PUTIN_ITEM, - mPlayer_INDEX_DEMO_WAIT, - mPlayer_INDEX_DEMO_WALK, - mPlayer_INDEX_DEMO_GETON_TRAIN, - mPlayer_INDEX_DEMO_GETON_TRAIN_WAIT, - mPlayer_INDEX_DEMO_GETOFF_TRAIN, - mPlayer_INDEX_DEMO_STANDING_TRAIN, - mPlayer_INDEX_DEMO_WADE, - mPlayer_INDEX_HIDE, - mPlayer_INDEX_GROUNDHOG, - mPlayer_INDEX_RELEASE_CREATURE, - mPlayer_INDEX_WASH_CAR, - mPlayer_INDEX_TIRED, - mPlayer_INDEX_ROTATE_OCTAGON, - mPlayer_INDEX_THROW_MONEY, - mPlayer_INDEX_PRAY, - mPlayer_INDEX_SHAKE_TREE, - mPlayer_INDEX_MAIL_JUMP, - mPlayer_INDEX_MAIL_LAND, - mPlayer_INDEX_READY_PITFALL, - mPlayer_INDEX_FALL_PITFALL, - mPlayer_INDEX_STRUGGLE_PITFALL, - mPlayer_INDEX_CLIMBUP_PITFALL, - mPlayer_INDEX_STUNG_BEE, - mPlayer_INDEX_NOTICE_BEE, - mPlayer_INDEX_REMOVE_GRASS, - mPlayer_INDEX_SHOCK, - mPlayer_INDEX_KNOCK_DOOR, - mPlayer_INDEX_CHANGE_CLOTH, - mPlayer_INDEX_PUSH_SNOWBALL, - mPlayer_INDEX_ROTATE_UMBRELLA, - mPlayer_INDEX_WADE_SNOWBALL, - mPlayer_INDEX_COMPLETE_PAYMENT, - mPlayer_INDEX_FAIL_EMU, - mPlayer_INDEX_STUNG_MOSQUITO, - mPlayer_INDEX_NOTICE_MOSQUITO, - mPlayer_INDEX_SWING_FAN, - mPlayer_INDEX_SWITCH_ON_LIGHTHOUSE, - mPlayer_INDEX_RADIO_EXERCISE, - mPlayer_INDEX_DEMO_GETON_BOAT, - mPlayer_INDEX_DEMO_GETON_BOAT_SITDOWN, - mPlayer_INDEX_DEMO_GETON_BOAT_WAIT, - mPlayer_INDEX_DEMO_GETON_BOAT_WADE, - mPlayer_INDEX_DEMO_GETOFF_BOAT_STANDUP, - mPlayer_INDEX_DEMO_GETOFF_BOAT, - mPlayer_INDEX_DEMO_GET_GOLDEN_ITEM, - mPlayer_INDEX_DEMO_GET_GOLDEN_ITEM2, - mPlayer_INDEX_DEMO_GET_GOLDEN_AXE_WAIT + mPlayer_INDEX_DMA, + mPlayer_INDEX_INTRO, + mPlayer_INDEX_REFUSE, + mPlayer_INDEX_REFUSE_PICKUP, + mPlayer_INDEX_RETURN_DEMO, + mPlayer_INDEX_RETURN_OUTDOOR, + mPlayer_INDEX_RETURN_OUTDOOR2, + mPlayer_INDEX_WAIT, + mPlayer_INDEX_WALK, + mPlayer_INDEX_RUN, + mPlayer_INDEX_DASH, + mPlayer_INDEX_TUMBLE, + mPlayer_INDEX_TUMBLE_GETUP, + mPlayer_INDEX_TURN_DASH, + mPlayer_INDEX_FALL, + mPlayer_INDEX_WADE, + mPlayer_INDEX_DOOR, + mPlayer_INDEX_OUTDOOR, + mPlayer_INDEX_INVADE, + mPlayer_INDEX_HOLD, + mPlayer_INDEX_PUSH, + mPlayer_INDEX_PULL, + mPlayer_INDEX_ROTATE_FURNITURE, + mPlayer_INDEX_OPEN_FURNITURE, + mPlayer_INDEX_WAIT_OPEN_FURNITURE, + mPlayer_INDEX_CLOSE_FURNITURE, + mPlayer_INDEX_LIE_BED, + mPlayer_INDEX_WAIT_BED, + mPlayer_INDEX_ROLL_BED, + mPlayer_INDEX_STANDUP_BED, + mPlayer_INDEX_PICKUP, + mPlayer_INDEX_PICKUP_JUMP, + mPlayer_INDEX_PICKUP_FURNITURE, + mPlayer_INDEX_PICKUP_EXCHANGE, + mPlayer_INDEX_SITDOWN, + mPlayer_INDEX_SITDOWN_WAIT, + mPlayer_INDEX_STANDUP, + mPlayer_INDEX_SWING_AXE, + mPlayer_INDEX_AIR_AXE, + mPlayer_INDEX_REFLECT_AXE, + mPlayer_INDEX_BROKEN_AXE, + mPlayer_INDEX_SLIP_NET, + mPlayer_INDEX_READY_NET, + mPlayer_INDEX_READY_WALK_NET, + mPlayer_INDEX_SWING_NET, + mPlayer_INDEX_PULL_NET, + mPlayer_INDEX_STOP_NET, + mPlayer_INDEX_NOTICE_NET, + mPlayer_INDEX_PUTAWAY_NET, + mPlayer_INDEX_READY_ROD, + mPlayer_INDEX_CAST_ROD, + mPlayer_INDEX_AIR_ROD, + mPlayer_INDEX_RELAX_ROD, + mPlayer_INDEX_COLLECT_ROD, + mPlayer_INDEX_VIB_ROD, + mPlayer_INDEX_FLY_ROD, + mPlayer_INDEX_NOTICE_ROD, + mPlayer_INDEX_PUTAWAY_ROD, + mPlayer_INDEX_DIG_SCOOP, + mPlayer_INDEX_FILL_SCOOP, + mPlayer_INDEX_REFLECT_SCOOP, + mPlayer_INDEX_AIR_SCOOP, + mPlayer_INDEX_GET_SCOOP, + mPlayer_INDEX_PUTAWAY_SCOOP, + mPlayer_INDEX_PUTIN_SCOOP, + mPlayer_INDEX_TALK, + mPlayer_INDEX_RECIEVE_WAIT, + mPlayer_INDEX_RECIEVE_STRETCH, + mPlayer_INDEX_RECIEVE, + mPlayer_INDEX_RECIEVE_PUTAWAY, + mPlayer_INDEX_GIVE, + mPlayer_INDEX_GIVE_WAIT, + mPlayer_INDEX_TAKEOUT_ITEM, + mPlayer_INDEX_PUTIN_ITEM, + mPlayer_INDEX_DEMO_WAIT, + mPlayer_INDEX_DEMO_WALK, + mPlayer_INDEX_DEMO_GETON_TRAIN, + mPlayer_INDEX_DEMO_GETON_TRAIN_WAIT, + mPlayer_INDEX_DEMO_GETOFF_TRAIN, + mPlayer_INDEX_DEMO_STANDING_TRAIN, + mPlayer_INDEX_DEMO_WADE, + mPlayer_INDEX_HIDE, + mPlayer_INDEX_GROUNDHOG, + mPlayer_INDEX_RELEASE_CREATURE, + mPlayer_INDEX_WASH_CAR, + mPlayer_INDEX_TIRED, + mPlayer_INDEX_ROTATE_OCTAGON, + mPlayer_INDEX_THROW_MONEY, + mPlayer_INDEX_PRAY, + mPlayer_INDEX_SHAKE_TREE, + mPlayer_INDEX_MAIL_JUMP, + mPlayer_INDEX_MAIL_LAND, + mPlayer_INDEX_READY_PITFALL, + mPlayer_INDEX_FALL_PITFALL, + mPlayer_INDEX_STRUGGLE_PITFALL, + mPlayer_INDEX_CLIMBUP_PITFALL, + mPlayer_INDEX_STUNG_BEE, + mPlayer_INDEX_NOTICE_BEE, + mPlayer_INDEX_REMOVE_GRASS, + mPlayer_INDEX_SHOCK, + mPlayer_INDEX_KNOCK_DOOR, + mPlayer_INDEX_CHANGE_CLOTH, + mPlayer_INDEX_PUSH_SNOWBALL, + mPlayer_INDEX_ROTATE_UMBRELLA, + mPlayer_INDEX_WADE_SNOWBALL, + mPlayer_INDEX_COMPLETE_PAYMENT, + mPlayer_INDEX_FAIL_EMU, + mPlayer_INDEX_STUNG_MOSQUITO, + mPlayer_INDEX_NOTICE_MOSQUITO, + mPlayer_INDEX_SWING_FAN, + mPlayer_INDEX_SWITCH_ON_LIGHTHOUSE, + mPlayer_INDEX_RADIO_EXERCISE, + mPlayer_INDEX_DEMO_GETON_BOAT, + mPlayer_INDEX_DEMO_GETON_BOAT_SITDOWN, + mPlayer_INDEX_DEMO_GETON_BOAT_WAIT, + mPlayer_INDEX_DEMO_GETON_BOAT_WADE, + mPlayer_INDEX_DEMO_GETOFF_BOAT_STANDUP, + mPlayer_INDEX_DEMO_GETOFF_BOAT, + mPlayer_INDEX_DEMO_GET_GOLDEN_ITEM, + mPlayer_INDEX_DEMO_GET_GOLDEN_ITEM2, + mPlayer_INDEX_DEMO_GET_GOLDEN_AXE_WAIT }; enum { - mPlayer_CREATURE_INSECT, - mPlayer_CREATURE_GYOEI, - mPlayer_CREATURE_BALLOON, + mPlayer_CREATURE_INSECT, + mPlayer_CREATURE_GYOEI, + mPlayer_CREATURE_BALLOON, - mPlayer_CREATURE_NUM + mPlayer_CREATURE_NUM +}; + +enum { + mPlayer_BED_ACTION_NONE, + mPlayer_BED_ACTION_ROLL, + mPlayer_BED_ACTION_OUT, + + mPlayer_BED_ACTION_NUM }; typedef struct player_request_give_from_submenu_s { - xyz_t unused; // assumed based on size - mActor_name_t item; - int mode_after; // player mode after the action finishes - int present_flag; // set if the item is wrapped as presnet - int counter_flag; // set when the item slides across a counter + xyz_t unused; // assumed based on size + mActor_name_t item; + int mode_after; // player mode after the action finishes + int present_flag; // set if the item is wrapped as presnet + int counter_flag; // set when the item slides across a counter } mPlayer_request_give_from_submenu_c; typedef struct player_request_putin_scoop_from_submenu_s { - xyz_t wpos; - mActor_name_t item; - int got_gold_scoop; + xyz_t wpos; + mActor_name_t item; + int got_gold_scoop; } mPlayer_request_putin_scoop_from_submenu_data_c; typedef struct { - int type; - int got_gold_scoop; - s16 angle_y; - s16 item; + int type; + int got_gold_scoop; + s16 angle_y; + s16 item; } mPlayer_request_release_creature_gyoei_from_submenu_c; typedef struct { - int type; - int got_gold_scoop; - xyz_t wpos; - int insect_type; + int type; + int got_gold_scoop; + xyz_t wpos; + int insect_type; } mPlayer_request_release_creature_insect_from_submenu_c; typedef struct { - int type; - int got_gold_scoop; - int balloon_shape_type; + int type; + int got_gold_scoop; + int balloon_shape_type; } mPlayer_request_release_creature_balloon_from_submenu_c; typedef struct { - int _0; - ACTOR* speak_actor; + int _0; + ACTOR* speak_actor; } mPlayer_request_demo_wait_from_submenu_c; typedef struct { - int direct; - s16 angle; - xyz_t wpos; - int ftr_name; + int direct; + s16 angle; + xyz_t wpos; + int ftr_name; } mPlayer_request_lie_bed_c; typedef union { - mPlayer_request_give_from_submenu_c give_from_submenu; - mPlayer_request_putin_scoop_from_submenu_data_c putin_scoop_from_submenu; - mPlayer_request_release_creature_gyoei_from_submenu_c release_creature_gyoei_from_submenu; - mPlayer_request_release_creature_insect_from_submenu_c release_creature_insect_from_submenu; - mPlayer_request_release_creature_balloon_from_submenu_c release_creature_balloon_from_submenu; - mPlayer_request_demo_wait_from_submenu_c demo_wait_from_submenu; - mPlayer_request_lie_bed_c lie_bed; - /* TODO: others */ - u8 force_size[72]; // TEMP + mPlayer_request_give_from_submenu_c give_from_submenu; + mPlayer_request_putin_scoop_from_submenu_data_c putin_scoop_from_submenu; + mPlayer_request_release_creature_gyoei_from_submenu_c release_creature_gyoei_from_submenu; + mPlayer_request_release_creature_insect_from_submenu_c release_creature_insect_from_submenu; + mPlayer_request_release_creature_balloon_from_submenu_c release_creature_balloon_from_submenu; + mPlayer_request_demo_wait_from_submenu_c demo_wait_from_submenu; + mPlayer_request_lie_bed_c lie_bed; + /* TODO: others */ + u8 force_size[72]; // TEMP } mPlayer_request_main_data; typedef struct { - int requested_main_index; - int requested_index_pending; - mPlayer_request_main_data request_main_data; + int requested_main_index; + int requested_index_pending; + mPlayer_request_main_data request_main_data; } mPlayer_change_data_from_submenu_c; /* sizeof(struct player_actor_s) == 0x13A8 */ struct player_actor_s { - /* 0x0000 */ ACTOR actor_class; - /* 0x0174 */ cKF_SkeletonInfo_R_c keyframe0; - /* 0x01E4 */ cKF_SkeletonInfo_R_c keyframe1; - /* 0x0252 */ s_xyz joint_data[27]; - /* 0x02F4 */ s_xyz morph_data[27]; - /* 0x0398 */ Mtx work_mtx[2][13]; /* swapped between frames */ - /* 0x0A18 */ cKF_SkeletonInfo_R_c item_keyframe; /* for item animations */ - /* 0x0A88 */ s_xyz item_joint_data[8]; - /* 0x0AB8 */ s_xyz item_morph_data[8]; - /* 0x0AE8 */ Mtx item_work_mtx[2][4]; /* swapped between frames */ - /* 0x0CE8 */ s16 eye_pattern_normal; - /* 0x0CEA */ s16 eye_pattern_normal_timer; - /* 0x0CEC */ int blink_count; - /* 0x0CF0 */ int eye_tex_idx; - /* 0x0CF4 */ int mouth_tex_idx; - /* 0x0CF8 */ int now_main_index; - /* 0x0CFC */ int prev_main_index; - /* 0x0D00 */ int changed_main_index; - /* 0x0D04 */ int item_main_index; - /* 0x0D08 */ int requested_main_index; - /* 0x0D0C */ int requested_main_index_priority; - /* 0x0D10 */ int requested_main_index_changed; - /* 0x0D14 */ int settled_requested_main_index_priority; - /* 0x0D18 */ u8 main_index_data[72]; // TODO: Union of many types... - /* 0x0D60 */ u8 requested_main_index_data[72]; // TODO: Union of many types... - /* 0x0DA8 */ u8 _0DA8[0x1270 - 0x0DA8]; /* TODO: finish */ - /* 0x1270 */ int (*request_main_invade_all_proc)(GAME*, int); - /* 0x1274 */ int (*request_main_refuse_all_proc)(GAME*, int); - /* 0x1278 */ int (*request_main_return_demo_all_proc)(GAME*, int, f32, int); - /* 0x127C */ int (*request_main_wait_all_proc)(GAME*, f32, int, int); - /* 0x1280 */ int (*request_main_talk_all_proc)(GAME*, ACTOR*, int, f32, int, int); - /* 0x1284 */ int (*request_main_hold_all_proc)(GAME*, int, int, const xyz_t*, f32, int, int); - /* 0x1288 */ int (*request_main_recieve_wait_all_proc)(GAME*, ACTOR*, int, int, mActor_name_t, int, int); - /* 0x128C */ int (*request_main_give_all_proc)(GAME*, ACTOR*, int, int, mActor_name_t, int, int, int, int); - /* 0x1290 */ int (*request_main_sitdown_all_proc)(GAME*, int, const xyz_t*, int, int); - /* 0x1294 */ int (*request_main_close_furniture_all_proc)(GAME*, int); - /* 0x1298 */ int (*request_main_lie_bed_all_proc)(GAME*, int, const xyz_t*, int, int, int); - /* 0x129C */ int (*request_main_hide_all_proc)(GAME*, int); - /* 0x12A0 */ int (*request_main_groundhog_proc)(GAME*, int); - /* 0x12A4 */ int (*request_main_door_all_proc)(GAME*, const xyz_t*, s16, int, void*, int); - /* 0x12A8 */ int (*request_main_outdoor_all_proc)(GAME*, int, int, int); - /* 0x12AC */ int (*request_main_wash_car_all_proc)(GAME*, const xyz_t*, const xyz_t*, s16, ACTOR*, int); - /* 0x12B0 */ int (*request_main_rotate_octagon_all_proc)(GAME*, ACTOR*, int, int, const xyz_t*, s16, int); - /* 0x12B4 */ int (*request_main_throw_money_all_proc)(GAME*, const xyz_t*, s16, int); - /* 0x12B8 */ int (*request_main_pray_all_proc)(GAME*, const xyz_t*, s16, int); - /* 0x12BC */ int (*request_main_mail_jump_all_proc)(GAME*, const xyz_t*, s16, int); - /* 0x12C0 */ int (*request_main_demo_wait_all_proc)(GAME*, int, void*, int); - /* 0x12C4 */ int (*request_main_demo_walk_all_proc)(GAME*, f32, f32, f32, int, int); - /* 0x12C8 */ int (*request_main_demo_geton_train_all_proc)(GAME*, const xyz_t*, s16, int); - /* 0x12CC */ int (*request_main_demo_getoff_train_all_proc)(GAME*, const xyz_t*, s16, int); - /* 0x12D0 */ int (*request_main_demo_standing_train_all_proc)(GAME*, int); - /* 0x12D4 */ int (*request_main_stung_bee_all_proc)(GAME*, int); - /* 0x12D8 */ int (*request_main_shock_all_proc)(GAME*, f32, s16, s8, int, int); - /* 0x12DC */ int (*request_main_change_cloth_forNPC_proc)(GAME*, mActor_name_t, int); - /* 0x12E0 */ int (*request_main_push_snowball_all_proc)(GAME*, void*, int, int); - /* 0x12E4 */ int (*request_main_stung_mosquito_all_proc)(GAME*, int, int); - /* 0x12E8 */ int (*request_main_switch_on_lighthouse_all_proc)(GAME*, const xyz_t*, int, int); - /* 0x12EC */ int (*request_main_demo_geton_boat_all_proc)(GAME*, const xyz_t*, s16, int); - /* 0x12F0 */ int (*request_main_demo_getoff_boat_standup_all_proc)(GAME*, const xyz_t*, s16, int); - /* 0x12F4 */ int (*request_main_demo_get_golden_item2_all_proc)(GAME*, int, int); - /* 0x12F8 */ int (*request_main_demo_get_golden_axe_wait_all_proc)(GAME*, int); - /* 0x12FC */ int (*check_request_main_priority_proc)(GAME*, int); - /* 0x1300 */ void* (*get_door_label_proc)(GAME*); - /* 0x1304 */ int (*Set_Item_net_catch_request_table_proc)(ACTOR*, GAME*, u32, s8, const xyz_t*, f32); - /* 0x1308 */ f32 (*Get_Item_net_catch_swing_timer_proc)(ACTOR*, GAME*); - /* 0x130C */ u8 (*Set_Item_net_catch_request_force_proc)(ACTOR*, GAME*, u32, s8); - /* 0x1310 */ void (*Set_force_position_angle_proc)(GAME*, const xyz_t*, const s_xyz*, u8); - /* 0x1314 */ u8 (*Get_force_position_angle_proc)(GAME*, xyz_t*, s_xyz*); - /* 0x1318 */ int (*Get_WadeEndPos_proc)(GAME*, xyz_t*); - /* 0x131C */ int (*Check_Label_main_push_snowball_proc)(GAME*, void*); - /* 0x1320 */ int (*SetParam_for_push_snowball_proc)(GAME*, const xyz_t*, s16, f32); - /* 0x1324 */ int (*able_submenu_request_main_index_proc)(GAME*); - /* 0x1328 */ int (*check_able_change_camera_normal_index_proc)(ACTOR*); - /* 0x132C */ int (*Check_able_force_speak_label_proc)(GAME*, ACTOR*); - /* 0x1330 */ int (*check_cancel_request_change_proc_index_proc)(int); - /* 0x1334 */ u32 (*Get_item_net_catch_label_proc)(ACTOR*); - /* 0x1338 */ int (*Change_item_net_catch_label_proc)(ACTOR*, u32, s8); - /* 0x133C */ int (*Check_StopNet_proc)(ACTOR*, xyz_t*); - /* 0x1340 */ int (*Check_HitAxe_proc)(ACTOR*, xyz_t*); - /* 0x1344 */ int (*Check_VibUnit_OneFrame_proc)(ACTOR*, const xyz_t*); - /* 0x1348 */ int (*Check_HitScoop_proc)(ACTOR*, xyz_t*); - /* 0x134C */ int (*Check_DigScoop_proc)(ACTOR*, xyz_t*); - /* 0x1350 */ int (*check_request_change_item_proc)(GAME*); - /* 0x1354 */ int (*Check_RotateOctagon_proc)(GAME*); - /* 0x1358 */ int (*Check_end_stung_bee_proc)(ACTOR*); - /* 0x135C */ int (*Get_status_for_bee_proc)(ACTOR*); - /* 0x1360 */ int (*Set_ScrollDemo_forWade_snowball_proc)(ACTOR*, int, const xyz_t*); - /* 0x1364 */ int (*Check_tree_shaken_proc)(ACTOR*, const xyz_t*); - /* 0x1368 */ int (*Check_tree_shaken_little_proc)(ACTOR*, const xyz_t*); - /* 0x136C */ int (*Check_tree_shaken_big_proc)(ACTOR*, const xyz_t*); - /* 0x1370 */ int (*Check_Label_main_wade_snowball_proc)(GAME*, void*); - /* 0x1374 */ int (*GetSnowballPos_forWadeSnowball_proc)(ACTOR*, xyz_t*); - /* 0x1378 */ int (*CheckCondition_forWadeSnowball_proc)(GAME*, const xyz_t*, s16); - /* 0x137C */ mActor_name_t (*Get_itemNo_forWindow_proc)(ACTOR*); - /* 0x1380 */ int (*check_cancel_event_without_priority_proc)(GAME*); - /* 0x1384 */ int (*CheckScene_AbleSubmenu_proc)(); - /* 0x1388 */ int (*Check_stung_mosquito_proc)(GAME*, ACTOR*); - /* 0x138C */ int a_btn_pressed; - /* 0x1390 */ int a_btn_triggers_submenu; - /* 0x1394 */ mActor_name_t item_in_front; /* item directly in front of the player */ - /* 0x1398 */ xyz_t foward_ut_pos; /* wpos of unit in front of player */ - /* 0x13A4 */ s8 update_scene_bg_mode; + /* 0x0000 */ ACTOR actor_class; + /* 0x0174 */ cKF_SkeletonInfo_R_c keyframe0; + /* 0x01E4 */ cKF_SkeletonInfo_R_c keyframe1; + /* 0x0252 */ s_xyz joint_data[27]; + /* 0x02F4 */ s_xyz morph_data[27]; + /* 0x0398 */ Mtx work_mtx[2][13]; /* swapped between frames */ + /* 0x0A18 */ cKF_SkeletonInfo_R_c item_keyframe; /* for item animations */ + /* 0x0A88 */ s_xyz item_joint_data[8]; + /* 0x0AB8 */ s_xyz item_morph_data[8]; + /* 0x0AE8 */ Mtx item_work_mtx[2][4]; /* swapped between frames */ + /* 0x0CE8 */ s16 eye_pattern_normal; + /* 0x0CEA */ s16 eye_pattern_normal_timer; + /* 0x0CEC */ int blink_count; + /* 0x0CF0 */ int eye_tex_idx; + /* 0x0CF4 */ int mouth_tex_idx; + /* 0x0CF8 */ int now_main_index; + /* 0x0CFC */ int prev_main_index; + /* 0x0D00 */ int changed_main_index; + /* 0x0D04 */ int item_main_index; + /* 0x0D08 */ int requested_main_index; + /* 0x0D0C */ int requested_main_index_priority; + /* 0x0D10 */ int requested_main_index_changed; + /* 0x0D14 */ int settled_requested_main_index_priority; + /* 0x0D18 */ u8 main_index_data[72]; // TODO: Union of many types... + /* 0x0D60 */ u8 requested_main_index_data[72]; // TODO: Union of many types... + /* 0x0DA8 */ u8 _0DA8[0x1010 - 0x0DA8]; /* TODO: finish */ + /* 0x1010 */ ClObjPipe_c col_pipe; + /* 0x102C */ xyz_t head_pos; + /* 0x1038 */ xyz_t feel_pos; + /* 0x1044 */ xyz_t right_hand_pos; + /* 0x1050 */ xyz_t right_hand_move; + /* 0x105C */ xyz_t left_hand_pos; + /* 0x1068 */ MtxF right_hand_mtx; + /* 0x10A8 */ MtxF left_hand_mtx; + /* 0x10E8 */ u8 _10E8[0x1270 - 0x10E8]; + /* 0x1270 */ int (*request_main_invade_all_proc)(GAME*, int); + /* 0x1274 */ int (*request_main_refuse_all_proc)(GAME*, int); + /* 0x1278 */ int (*request_main_return_demo_all_proc)(GAME*, int, f32, int); + /* 0x127C */ int (*request_main_wait_all_proc)(GAME*, f32, int, int); + /* 0x1280 */ int (*request_main_talk_all_proc)(GAME*, ACTOR*, int, f32, int, int); + /* 0x1284 */ int (*request_main_hold_all_proc)(GAME*, int, int, const xyz_t*, f32, int, int); + /* 0x1288 */ int (*request_main_recieve_wait_all_proc)(GAME*, ACTOR*, int, int, mActor_name_t, int, int); + /* 0x128C */ int (*request_main_give_all_proc)(GAME*, ACTOR*, int, int, mActor_name_t, int, int, int, int); + /* 0x1290 */ int (*request_main_sitdown_all_proc)(GAME*, int, const xyz_t*, int, int); + /* 0x1294 */ int (*request_main_close_furniture_all_proc)(GAME*, int); + /* 0x1298 */ int (*request_main_lie_bed_all_proc)(GAME*, int, const xyz_t*, int, int, int); + /* 0x129C */ int (*request_main_hide_all_proc)(GAME*, int); + /* 0x12A0 */ int (*request_main_groundhog_proc)(GAME*, int); + /* 0x12A4 */ int (*request_main_door_all_proc)(GAME*, const xyz_t*, s16, int, void*, int); + /* 0x12A8 */ int (*request_main_outdoor_all_proc)(GAME*, int, int, int); + /* 0x12AC */ int (*request_main_wash_car_all_proc)(GAME*, const xyz_t*, const xyz_t*, s16, ACTOR*, int); + /* 0x12B0 */ int (*request_main_rotate_octagon_all_proc)(GAME*, ACTOR*, int, int, const xyz_t*, s16, int); + /* 0x12B4 */ int (*request_main_throw_money_all_proc)(GAME*, const xyz_t*, s16, int); + /* 0x12B8 */ int (*request_main_pray_all_proc)(GAME*, const xyz_t*, s16, int); + /* 0x12BC */ int (*request_main_mail_jump_all_proc)(GAME*, const xyz_t*, s16, int); + /* 0x12C0 */ int (*request_main_demo_wait_all_proc)(GAME*, int, void*, int); + /* 0x12C4 */ int (*request_main_demo_walk_all_proc)(GAME*, f32, f32, f32, int, int); + /* 0x12C8 */ int (*request_main_demo_geton_train_all_proc)(GAME*, const xyz_t*, s16, int); + /* 0x12CC */ int (*request_main_demo_getoff_train_all_proc)(GAME*, const xyz_t*, s16, int); + /* 0x12D0 */ int (*request_main_demo_standing_train_all_proc)(GAME*, int); + /* 0x12D4 */ int (*request_main_stung_bee_all_proc)(GAME*, int); + /* 0x12D8 */ int (*request_main_shock_all_proc)(GAME*, f32, s16, s8, int, int); + /* 0x12DC */ int (*request_main_change_cloth_forNPC_proc)(GAME*, mActor_name_t, int); + /* 0x12E0 */ int (*request_main_push_snowball_all_proc)(GAME*, void*, int, int); + /* 0x12E4 */ int (*request_main_stung_mosquito_all_proc)(GAME*, int, int); + /* 0x12E8 */ int (*request_main_switch_on_lighthouse_all_proc)(GAME*, const xyz_t*, int, int); + /* 0x12EC */ int (*request_main_demo_geton_boat_all_proc)(GAME*, const xyz_t*, s16, int); + /* 0x12F0 */ int (*request_main_demo_getoff_boat_standup_all_proc)(GAME*, const xyz_t*, s16, int); + /* 0x12F4 */ int (*request_main_demo_get_golden_item2_all_proc)(GAME*, int, int); + /* 0x12F8 */ int (*request_main_demo_get_golden_axe_wait_all_proc)(GAME*, int); + /* 0x12FC */ int (*check_request_main_priority_proc)(GAME*, int); + /* 0x1300 */ void* (*get_door_label_proc)(GAME*); + /* 0x1304 */ int (*Set_Item_net_catch_request_table_proc)(ACTOR*, GAME*, u32, s8, const xyz_t*, f32); + /* 0x1308 */ f32 (*Get_Item_net_catch_swing_timer_proc)(ACTOR*, GAME*); + /* 0x130C */ u8 (*Set_Item_net_catch_request_force_proc)(ACTOR*, GAME*, u32, s8); + /* 0x1310 */ void (*Set_force_position_angle_proc)(GAME*, const xyz_t*, const s_xyz*, u8); + /* 0x1314 */ u8 (*Get_force_position_angle_proc)(GAME*, xyz_t*, s_xyz*); + /* 0x1318 */ int (*Get_WadeEndPos_proc)(GAME*, xyz_t*); + /* 0x131C */ int (*Check_Label_main_push_snowball_proc)(GAME*, void*); + /* 0x1320 */ int (*SetParam_for_push_snowball_proc)(GAME*, const xyz_t*, s16, f32); + /* 0x1324 */ int (*able_submenu_request_main_index_proc)(GAME*); + /* 0x1328 */ int (*check_able_change_camera_normal_index_proc)(ACTOR*); + /* 0x132C */ int (*Check_able_force_speak_label_proc)(GAME*, ACTOR*); + /* 0x1330 */ int (*check_cancel_request_change_proc_index_proc)(int); + /* 0x1334 */ u32 (*Get_item_net_catch_label_proc)(ACTOR*); + /* 0x1338 */ int (*Change_item_net_catch_label_proc)(ACTOR*, u32, s8); + /* 0x133C */ int (*Check_StopNet_proc)(ACTOR*, xyz_t*); + /* 0x1340 */ int (*Check_HitAxe_proc)(ACTOR*, xyz_t*); + /* 0x1344 */ int (*Check_VibUnit_OneFrame_proc)(ACTOR*, const xyz_t*); + /* 0x1348 */ int (*Check_HitScoop_proc)(ACTOR*, xyz_t*); + /* 0x134C */ int (*Check_DigScoop_proc)(ACTOR*, xyz_t*); + /* 0x1350 */ int (*check_request_change_item_proc)(GAME*); + /* 0x1354 */ int (*Check_RotateOctagon_proc)(GAME*); + /* 0x1358 */ int (*Check_end_stung_bee_proc)(ACTOR*); + /* 0x135C */ int (*Get_status_for_bee_proc)(ACTOR*); + /* 0x1360 */ int (*Set_ScrollDemo_forWade_snowball_proc)(ACTOR*, int, const xyz_t*); + /* 0x1364 */ int (*Check_tree_shaken_proc)(ACTOR*, const xyz_t*); + /* 0x1368 */ int (*Check_tree_shaken_little_proc)(ACTOR*, const xyz_t*); + /* 0x136C */ int (*Check_tree_shaken_big_proc)(ACTOR*, const xyz_t*); + /* 0x1370 */ int (*Check_Label_main_wade_snowball_proc)(GAME*, void*); + /* 0x1374 */ int (*GetSnowballPos_forWadeSnowball_proc)(ACTOR*, xyz_t*); + /* 0x1378 */ int (*CheckCondition_forWadeSnowball_proc)(GAME*, const xyz_t*, s16); + /* 0x137C */ mActor_name_t (*Get_itemNo_forWindow_proc)(ACTOR*); + /* 0x1380 */ int (*check_cancel_event_without_priority_proc)(GAME*); + /* 0x1384 */ int (*CheckScene_AbleSubmenu_proc)(); + /* 0x1388 */ int (*Check_stung_mosquito_proc)(GAME*, ACTOR*); + /* 0x138C */ int a_btn_pressed; + /* 0x1390 */ int a_btn_triggers_submenu; + /* 0x1394 */ mActor_name_t item_in_front; /* item directly in front of the player */ + /* 0x1398 */ xyz_t foward_ut_pos; /* wpos of unit in front of player */ + /* 0x13A4 */ s8 update_scene_bg_mode; }; void Player_actor_ct(ACTOR*, GAME*); diff --git a/include/m_player_lib.h b/include/m_player_lib.h index 9052d5ad..55b7fda8 100644 --- a/include/m_player_lib.h +++ b/include/m_player_lib.h @@ -67,6 +67,9 @@ extern int mPlib_request_main_close_furniture_type1(GAME* game); extern int mPlib_request_main_shock_type1(GAME* game, f32 time, s16 angle_y, int axe_swing); extern int mPlib_request_main_hold_type1(GAME* game, int ftr_no, int player_direct, const xyz_t* player_pos); extern int mPlib_check_player_warp_forEvent(void); +extern int mPlib_check_player_actor_main_index_Furniture_Move(GAME* game); +extern int mPlib_request_main_sitdown_type1(GAME* game, int direct, const xyz_t* pos, int ftr_no); +extern int mPlib_request_main_lie_bed_type1(GAME* game, int direct, const xyz_t* pos, int head_direct, int ftr_no); extern mPlayer_change_data_from_submenu_c* mPlib_Get_change_data_from_submenu_p(); diff --git a/src/ac_my_room.c b/src/ac_my_room.c index 4fe3a109..b9e98172 100644 --- a/src/ac_my_room.c +++ b/src/ac_my_room.c @@ -17,6 +17,7 @@ #include "m_debug.h" #include "m_mark_room.h" #include "sys_matrix.h" +#include "m_rcp.h" enum { aMR_ICON_LEAF, @@ -110,6 +111,27 @@ enum { aMR_MSG_STATE_NUM }; +static void My_Room_Actor_ct(ACTOR*, GAME*); +static void My_Room_Actor_dt(ACTOR*, GAME*); +static void My_Room_Actor_move(ACTOR*, GAME*); +static void My_Room_Actor_draw(ACTOR*, GAME*); + +// clang-format off +ACTOR_PROFILE My_Room_Profile = { + mAc_PROFILE_MY_ROOM, + ACTOR_PART_BG, + ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED, + ETC_MY_ROOM, + ACTOR_OBJ_BANK_KEEP, + sizeof(MY_ROOM_ACTOR), + &My_Room_Actor_ct, + &My_Room_Actor_dt, + &My_Room_Actor_move, + &My_Room_Actor_draw, + NULL +}; +// clang-format on + #include "../src/ac_furniture_data.c_inc" #include "../src/ac_my_room_data.c_inc" @@ -146,10 +168,48 @@ static int aMR_SetFurniture2FG(FTR_ACTOR* ftr_actor, xyz_t pos, int on_flag); static int aMR_FtrIdx2ChangeFtrSwitch(ACTOR* actorx, int ftr_id); static aFTR_PROFILE* aMR_GetFurnitureProfile(u16 ftr_no); static mActor_name_t* aMR_GetLayerTopFg(s16 layer); - -#include "../src/ac_my_room_msg_ctrl.c_inc" -#include "../src/ac_my_room_goki.c_inc" -#include "../src/ac_my_room_melody.c_inc" +static void aMR_TidyItemInFurniture(FTR_ACTOR* ftr_actor); +static int aMR_GetItemCountInFurniture(FTR_ACTOR* ftr_actor); +static int aMR_ItemPutInFurniture(FTR_ACTOR* ftr_actor, mActor_name_t item); +static void aMR_AllMDSwitchOff(void); +static void aMR_OneMDSwitchOn_TheOtherSwitchOff(FTR_ACTOR* ftr_actor); +static void aMR_ReserveBgm(ACTOR* actorx, int bgm_no, FTR_ACTOR* ftr_actor, s16 timer); +static void aMR_SetMDFtrDemoData(MY_ROOM_ACTOR* my_room, FTR_ACTOR* ftr_actor, aMR_contact_info_c* contact_info); +static int aMR_CheckHikidashi(FTR_ACTOR* ftr_actor, PLAYER_ACTOR* player, aMR_contact_info_c* contact_info); +static int aMR_JudgeDemoStart(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, GAME* game, + PLAYER_ACTOR* player); +static void aMR_PlacePushFurniture(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, f32* point, + PLAYER_ACTOR* player, GAME* game); +static void aMR_PlacePullFurniture(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + GAME* game); +static void aMR_PlaceKurukuruFurniture(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + GAME* game); +static void aMR_SitDownFurniture(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + GAME* game); +static void aMR_JudgeGoToBed(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + GAME* game); +static void aMR_SetMelodyData(u8* melody_data); +static void aMR_GokiInfoCt(ACTOR* actorx, GAME* game); +static void aMR_GokiInfoDt(void); +static void aMR_CheckFtrAndGoki(ACTOR* actorx, FTR_ACTOR* ftr_actor, GAME* game); +static void aMR_MakeGokiburi(xyz_t* pos, GAME* game, s16 arg); +static void aMR_RequestPlayerBikkuri(ACTOR* actorx, GAME* game); +static void aMR_GetFtrShape4Position(xyz_t* p0, xyz_t* p1, xyz_t* p2, xyz_t* p3, FTR_ACTOR* ftr_actor); +static u8 aMR_JudgeStickFull(int direct, GAME* game); +static int aMR_JudgeFurnitureMove(u8 type, int ut); +static int aMR_RequestItemToFitFurniture(ACTOR* actorx, FTR_ACTOR* ftr_actor); +static void aMR_SetPullMoveAnime(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room, + aMR_contact_info_c* contact_info); +static int aMR_PullDirect2PushDirect(int pull_direct); +static void aMR_SetPushMoveAnime(FTR_ACTOR* ftr_actor, GAME* game, MY_ROOM_ACTOR* my_room, + aMR_contact_info_c* contact_info); +static void aMR_MoveShapeCenter(FTR_ACTOR* ftr_actor); +static void aMR_RotateY(f32* xz, f32 amount); +static int aMR_3DStickNuetral(void); +static void aMR_SetNicePos(xyz_t* nice_pos, xyz_t player_pos, f32* col_start_xz, f32* col_end_xz, + aMR_contact_info_c* contact_info, int type); +static int aMR_GetPlayerDirect(const f32* normal_xz); +static int aMR_Get3dDirectStatus(int direct); static aFTR_PROFILE* aMR_GetFurnitureProfile(u16 ftr_no) { if (ftr_no < FTR_NUM) { @@ -237,7 +297,7 @@ static int aMR_ItemNo2IconNo(mActor_name_t item_no) { return aMR_ICON_LEAF; } -static Gfx* aMR_IconNo2Gfx1(int icon_no) { +extern Gfx* aMR_IconNo2Gfx1(int icon_no) { aMR_icon_display_data_c* icon; if (icon_no < 0) { @@ -249,7 +309,7 @@ static Gfx* aMR_IconNo2Gfx1(int icon_no) { return aMR_icon_display_data[icon_no].mat_gfx; } -static Gfx* aMR_IconNo2Gfx2(int icon_no) { +extern Gfx* aMR_IconNo2Gfx2(int icon_no) { if (icon_no < 0) { icon_no = 0; } else if (icon_no >= aMR_ICON_NUM) { @@ -1402,6 +1462,8 @@ static int aMR_GetSceneFurnitureMax(void) { return 3; } +#include "../src/ac_my_room_msg_ctrl.c_inc" + static void aMR_SecureFurnitureRam(ACTOR* actorx) { l_aMR_work.ftr_actor_list = (FTR_ACTOR*)zelda_malloc(l_aMR_work.list_size * sizeof(FTR_ACTOR)); l_aMR_work.used_list = (u8*)zelda_malloc(l_aMR_work.list_size * sizeof(u8)); @@ -1719,8 +1781,6 @@ static void aMR_SetMDIslandNPC(void) { } } -static void aMR_GokiInfoCt(ACTOR* actorx, GAME* game); - static void My_Room_Actor_ct(ACTOR* actorx, GAME* game) { MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; GAME_PLAY* play = (GAME_PLAY*)game; @@ -1878,6 +1938,8 @@ static int aMR_PickupFtrLayer(void) { return mCoBG_LAYER0; } +#include "../src/ac_my_room_goki.c_inc" + static void aMR_LeafStartPos(xyz_t* pos) { static xyz_t leaf_start0 = { 0.0f, 0.0f, 0.0f }; @@ -1958,7 +2020,9 @@ static void My_Room_Actor_dt(ACTOR* actorx, GAME* game) { } } +#include "../src/ac_my_room_melody.c_inc" #include "../src/ac_my_room_move.c_inc" +#include "../src/ac_my_room_draw.c_inc" static void aMR_RedmaFtrBank(void) { int i; diff --git a/src/ac_my_room_action.c_inc b/src/ac_my_room_action.c_inc new file mode 100644 index 00000000..74bd687f --- /dev/null +++ b/src/ac_my_room_action.c_inc @@ -0,0 +1,1379 @@ +static f32 aMR_PointDist2(xyz_t* pos0, xyz_t* pos1) { + f32 dX = pos0->x - pos1->x; + f32 dZ = pos0->z - pos1->z; + + return dX * dX + dZ * dZ; +} + +static int aMR_GokiburiPos_Common(xyz_t* pos, FTR_ACTOR* ftr_actor, PLAYER_ACTOR* player, int flag) { + static xyz_t init_pos = { 0.0f, 0.0f, 0.0f }; + f32 dist_tbl[4]; + int idx_tbl[4] = { -1, -1, -1, -1 }; + int sorted_tbl[4]; + int idx_tbl_idx = 0; + + if (ftr_actor->original_shape_type == aFTR_SHAPE_TYPEA) { + *pos = ftr_actor->position; + return TRUE; + } else { + xyz_t shape_pos_tbl[4]; + int i; + int j; + f32 x; + f32 y; + f32 z; + int sel; + int chk; + + *pos = init_pos; + aMR_GetFtrShape4Position(&shape_pos_tbl[0], &shape_pos_tbl[1], &shape_pos_tbl[2], &shape_pos_tbl[3], ftr_actor); + for (i = 0; i < 4; i++) { + dist_tbl[i] = aMR_PointDist2(&shape_pos_tbl[i], &player->actor_class.world.position); + } + + for (j = 0; j < 4; j++) { + f32 dist = 1000000.0f; + + for (i = 0; i < 4; i++) { + if (dist_tbl[i] < dist && idx_tbl[i] == -1) { + dist = dist_tbl[i]; + idx_tbl_idx = i; + } + } + + idx_tbl[idx_tbl_idx] = j; + } + + for (j = 0; j < 4; j++) { + for (i = 0; i < 4; i++) { + if (j == idx_tbl[i]) { + sorted_tbl[j] = i; + break; + } + } + } + + sel = (sorted_tbl[0] + 1) & 3; + chk = sorted_tbl[1]; + if (sel != chk) { + x = (shape_pos_tbl[sorted_tbl[0]].x + shape_pos_tbl[sel].x) * 0.5f; + y = shape_pos_tbl[sorted_tbl[0]].y; + z = (shape_pos_tbl[sorted_tbl[0]].z + shape_pos_tbl[sel].z) * 0.5f; + } else { + sel = (sorted_tbl[0] - 1) & 3; + if (sel != chk) { + x = (shape_pos_tbl[sorted_tbl[0]].x + shape_pos_tbl[sel].x) * 0.5f; + y = shape_pos_tbl[sorted_tbl[0]].y; + z = (shape_pos_tbl[sorted_tbl[0]].z + shape_pos_tbl[sel].z) * 0.5f; + } else { + return FALSE; + } + } + + if (flag == 1) { + sel = (sorted_tbl[0] + 2) & 3; + pos->x = (x + shape_pos_tbl[sel].x) * 0.5f; + pos->y = y; + pos->z = (z + shape_pos_tbl[sel].z) * 0.5f; + } else { + pos->x = (x + shape_pos_tbl[chk].x) * 0.5f; + pos->y = y; + pos->z = (z + shape_pos_tbl[chk].z) * 0.5f; + } + } + + return TRUE; +} + +static int aMR_GokiburiPos_Rotate(xyz_t* pos, FTR_ACTOR* ftr_actor, PLAYER_ACTOR* player) { + /* 1x1 and 2x2 furniture don't expose newly empty spots when rotating, so ignore them */ + if (ftr_actor->original_shape_type == aFTR_SHAPE_TYPEA || ftr_actor->original_shape_type == aFTR_SHAPE_TYPEC) { + return FALSE; + } + + return aMR_GokiburiPos_Common(pos, ftr_actor, player, TRUE); +} + +static int aMR_GokiburiPos_Pull(xyz_t* pos, FTR_ACTOR* ftr_actor, PLAYER_ACTOR* player) { + return aMR_GokiburiPos_Common(pos, ftr_actor, player, TRUE); +} + +static int aMR_GokiburiPos_Push(xyz_t* pos, FTR_ACTOR* ftr_actor, PLAYER_ACTOR* player) { + return aMR_GokiburiPos_Common(pos, ftr_actor, player, FALSE); +} + +static int aMR_FtrColCheck(xyz_t pos, f32 radius) { + mActor_name_t* fg_p = aMR_GetLayerTopFg(mCoBG_LAYER0); + + if (fg_p != NULL) { + int i; + + for (i = 0; i < aMR_CONTACT_DIR_NUM; i++) { + xyz_t chk_pos; + int ut_x; + int ut_z; + int ut; + + switch (i) { + case aMR_CONTACT_DIR_BACK: + chk_pos.x = pos.x; + chk_pos.z = pos.z - radius; + break; + case aMR_CONTACT_DIR_RIGHT: + chk_pos.x = pos.x - radius; + chk_pos.z = pos.z; + break; + case aMR_CONTACT_DIR_FRONT: + chk_pos.x = pos.x; + chk_pos.z = pos.z + radius; + break; + case aMR_CONTACT_DIR_LEFT: + chk_pos.x = pos.x + radius; + chk_pos.z = pos.z; + break; + } + + ut_x = (int)(chk_pos.x / mFI_UT_WORLDSIZE_X_F); + ut_z = (int)(chk_pos.z / mFI_UT_WORLDSIZE_Z_F); + ut = ut_x + ut_z * UT_X_NUM; + + if (ITEM_IS_FTR(fg_p[ut]) || fg_p[ut] == RSV_FE1F) { + mActor_name_t item_no; + int ftrID; + + if (aMR_UnitNum2FtrItemNoFtrID(&item_no, &ftrID, ut_x, ut_z, mCoBG_LAYER0)) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL && aFTR_CHECK_INTERACTION(profile->interaction_type, + aFTR_INTERACTION_TYPE_NO_COLLISION) == FALSE) { + return TRUE; + } + } + } else if (fg_p[ut] == RSV_WALL_NO) { + return TRUE; /* House walls always have collision */ + } + } + + return FALSE; + } + + /* If we don't have any fg info then always collide */ + return TRUE; +} + +static void aMR_SetBubu(PLAYER_ACTOR* player, MY_ROOM_ACTOR* my_room, GAME* game, s16* bubu_p) { + if (eEC_CLIP != NULL) { + eEC_CLIP->effect_make_proc(eEC_EFFECT_BUBU, player->actor_class.world.position, 2, 0, game, RSV_NO, 0, 0); + } + + my_room->pull_timer = 0; + my_room->push_timer = 0; + + if (bubu_p != NULL) { + *bubu_p = TRUE; + } +} + +static int aMR_ConvertDirectLevel(int direct) { + static s16 direct_conv_data[] = { + mFI_MOVEDIR_UP, /* aMR_DIRECT_UP */ + mFI_MOVEDIR_LEFT, /* aMR_DIRECT_LEFT */ + mFI_MOVEDIR_DOWN, /* aMR_DIRECT_DOWN */ + mFI_MOVEDIR_RIGHT /* aMR_DIRECT_RIGHT */ + }; + + if (direct >= 0 && direct <= aMR_DIRECT_RIGHT) { + return direct_conv_data[direct]; + } + + return -1; +} + +static void aMR_SetMoveSE(FTR_ACTOR* ftr_actor) { + aMR_contact_info_c* contact_layer; + int floor_idx; + + switch (ftr_actor->name) { + case 0x406: /* stone coin */ + contact_layer = aMR_GetContactInfoLayer1(); + + if (ftr_actor->state == aFTR_STATE_WAIT_PUSH || ftr_actor->state == aFTR_STATE_WAIT_PUSH2 || + ftr_actor->state == aFTR_STATE_WAIT_PUSH3 || ftr_actor->state == aFTR_STATE_PUSH || + ftr_actor->state == aFTR_STATE_WAIT_PULL || ftr_actor->state == aFTR_STATE_WAIT_PULL2 || + ftr_actor->state == aFTR_STATE_PULL) { + if (contact_layer != NULL) { + switch (contact_layer->contact_direction) { + case aMR_CONTACT_DIR_RIGHT: + case aMR_CONTACT_DIR_LEFT: + sAdo_OngenTrgStart(NA_SE_STONECOIN_ROLL, &ftr_actor->position); + break; + default: + sAdo_OngenTrgStart(NA_SE_STONECOIN_DRAG, &ftr_actor->position); + break; + } + } + } + break; + case 0x4E8: /* lawn mower */ + floor_idx = Common_Get(floor_idx); + + if (floor_idx == FLOOR_NPC026 || floor_idx == FLOOR_NPC048) { + contact_layer = aMR_GetContactInfoLayer1(); + + if (ftr_actor->state == aFTR_STATE_WAIT_PUSH || ftr_actor->state == aFTR_STATE_WAIT_PUSH2 || + ftr_actor->state == aFTR_STATE_WAIT_PUSH3 || ftr_actor->state == aFTR_STATE_PUSH) { + if (contact_layer != NULL) { + switch (contact_layer->contact_direction) { + case aMR_CONTACT_DIR_BACK: + sAdo_OngenTrgStart(NA_SE_LAWNMOWER, &ftr_actor->position); + break; + } + } + } + } else { + sAdo_FloorTrgStart(Common_Get(floor_idx), &ftr_actor->position); + } + break; + default: + sAdo_FloorTrgStart(Common_Get(floor_idx), &ftr_actor->position); + break; + } +} + +static void aMR_SetRotateSE(FTR_ACTOR* ftr_actor) { + if (mFI_GET_TYPE(mFI_GetFieldId()) == mFI_FIELD_PLAYER0_ROOM) { + sAdo_OngenTrgStart(NA_SE_ROTATE, &ftr_actor->position); + } +} + +static void aMR_GetPullSlip(xyz_t* pos, xyz_t target_pos, int ut_x, int ut_z, int direct) { + *pos = target_pos; + + switch (direct) { + case aMR_DIRECT_UP: + case aMR_DIRECT_DOWN: + pos->x = (f32)ut_x * mFI_UT_WORLDSIZE_X_F + mFI_UT_WORLDSIZE_HALF_X_F; + break; + default: + pos->z = (f32)ut_z * mFI_UT_WORLDSIZE_Z_F + mFI_UT_WORLDSIZE_HALF_Z_F; + break; + } +} + +enum { + aMR_SLIDE_PULL_JUDGE_TYPE0, + aMR_SLIDE_PULL_JUDGE_TYPE1, + aMR_SLIDE_PULL_JUDGE_NUM, +}; + +static int aMR_CheckSlidePullJudgeType(aMR_contact_info_c* contact_info, aFTR_PROFILE* profile) { + if (profile->shape == aFTR_SHAPE_TYPEC) { + return aMR_SLIDE_PULL_JUDGE_TYPE1; + } + + if (profile->shape <= aFTR_SHAPE_TYPEB_0) { + if (contact_info->contact_direction == aMR_CONTACT_DIR_FRONT || + contact_info->contact_direction == aMR_CONTACT_DIR_BACK) { + return aMR_SLIDE_PULL_JUDGE_TYPE1; + } + } + + return aMR_SLIDE_PULL_JUDGE_TYPE0; +} + +static int aMR_CheckPullPlayerObstacle2(xyz_t* pull0, xyz_t* pull1, aMR_contact_info_c* contact_info, + PLAYER_ACTOR* player, xyz_t move_ofs) { + if (contact_info->contact_flag && contact_info->contact_side == aMR_DIRECT_DOWN && + l_aMR_work.used_list[contact_info->ftrID] == TRUE) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(l_aMR_work.ftr_actor_list[contact_info->ftrID].name); + + if (profile != NULL) { + mActor_name_t* fg_p = aMR_GetLayerTopFg(mCoBG_LAYER0); + xyz_t player_pos = player->actor_class.world.position; + int direct = contact_info->direction; + xyz_t target_player_pos; + int ut_x; + int ut_z; + + target_player_pos.x = player_pos.x + move_ofs.x; + target_player_pos.y = player_pos.y + move_ofs.y; + target_player_pos.z = player_pos.z + move_ofs.z; + + ut_x = (int)(target_player_pos.x / mFI_UT_WORLDSIZE_X_F); + ut_z = (int)(target_player_pos.z / mFI_UT_WORLDSIZE_Z_F); + + *pull0 = target_player_pos; + *pull1 = target_player_pos; + + if (aMR_CheckSlidePullJudgeType(contact_info, profile) && fg_p != NULL) { + if (aMR_FtrColCheck(target_player_pos, 18.0f)) { + if (!aMR_FtrColCheck(target_player_pos, 0.5f)) { + aMR_GetPullSlip(pull1, target_player_pos, ut_x, ut_z, direct); + return FALSE; + } else { + return TRUE; + } + } else { + return FALSE; + } + } else { + return FALSE; + } + } else { + return TRUE; + } + } + + return TRUE; +} + +static int aMR_CheckPullPlayerObstacle(xyz_t* pull0, xyz_t* pull1, PLAYER_ACTOR* player, xyz_t move_ofs, int direct) { + mActor_name_t* fg_p = aMR_GetLayerTopFg(mCoBG_LAYER0); + + if (fg_p != NULL) { + int ut_x = (int)(player->actor_class.world.position.x / mFI_UT_WORLDSIZE_X_F); + int ut_z = (int)(player->actor_class.world.position.z / mFI_UT_WORLDSIZE_Z_F); + + if (aMR_Direct2PlussUnit(&ut_x, &ut_z, direct)) { + int ut = ut_x + ut_z * UT_X_NUM; + mActor_name_t item_no; + int ftrID; + + if (fg_p[ut] == RSV_WALL_NO || fg_p[ut] == RSV_FE1C || ITEM_NAME_GET_TYPE(fg_p[ut]) == NAME_TYPE_WARP) { + return TRUE; + } + + aMR_UnitNum2FtrItemNoFtrID(&item_no, &ftrID, ut_x, ut_z, mCoBG_LAYER0); + if ((ITEM_IS_FTR(item_no) || item_no == RSV_FE1F) && ftrID >= 0 && ftrID < l_aMR_work.list_size) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL && + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_NO_COLLISION) == FALSE) { + return TRUE; + } + } + } + + pull0->x = player->actor_class.world.position.x + move_ofs.x; + pull0->y = player->actor_class.world.position.y + move_ofs.y; + pull0->z = player->actor_class.world.position.z + move_ofs.z; + + pull1->x = pull0->x; + pull1->y = pull0->y; + pull1->z = pull0->z; + + return FALSE; + } + + return TRUE; +} + +static void aMR_PlacePullFurniture(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + GAME* game) { + static s_xyz move_table[4] = { + { 0, 0, -1 }, /* aMR_DIRECT_UP */ + { -1, 0, 0 }, /* aMR_DIRECT_LEFT */ + { 0, 0, 1 }, /* aMR_DIRECT_DOWN */ + { 1, 0, 0 }, /* aMR_DIRECT_RIGHT */ + }; + + static xyz_t target_table[4] = { + { 0.0f, 0.0f, -mFI_UT_WORLDSIZE_Z_F }, /* aMR_DIRECT_UP */ + { -mFI_UT_WORLDSIZE_X_F, 0.0f, 0.0f }, /* aMR_DIRECT_LEFT */ + { 0.0f, 0.0f, mFI_UT_WORLDSIZE_Z_F }, /* aMR_DIRECT_DOWN */ + { mFI_UT_WORLDSIZE_X_F, 0.0f, 0.0f }, /* aMR_DIRECT_RIGHT */ + }; + + if (contact_info->ftrID >= 0 && contact_info->ftrID < l_aMR_work.list_size && contact_info->contact_flag == TRUE && + contact_info->contact_side == aMR_DIRECT_DOWN && l_aMR_work.used_list[contact_info->ftrID] == TRUE && + my_room->state == 8 && my_room->pull_timer > 16 && + mPlib_check_player_actor_main_index_Furniture_Move(game) == FALSE) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[contact_info->ftrID]; + + if (ftr_actor->state == aFTR_STATE_STOP) { + int direct = contact_info->direction; + int ut_x; + int ut_z; + int ut; + int target_ut_x; + int target_ut_z; + int target_ut; + + aMR_Wpos2PlaceNumber(&ut_x, &ut_z, ftr_actor->position, ftr_actor->shape_type); + ut = ut_x + ut_z * UT_X_NUM; + + target_ut_x = ut_x + move_table[direct].x; + target_ut_z = ut_z + move_table[direct].z; + target_ut = target_ut_x + target_ut_z * UT_X_NUM; + + if (aMR_JudgeStickFull(direct, game) == TRUE) { + xyz_t* target_pos = &target_table[direct]; + + if (aMR_CheckPullPlayerObstacle(&my_room->pull_target_pos0, &my_room->pull_target_pos1, player, + *target_pos, direct) == FALSE) { + if (aMR_CheckPullPlayerObstacle2(&my_room->pull_target_pos0, &my_room->pull_target_pos1, + contact_info, player, *target_pos) == FALSE) { + aMR_SetInfoFurnitureTable(ftr_actor->shape_type, ut, aMR_NO_FTR_ID, ftr_actor->layer); + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, FALSE); + + if (aMR_JudgeFurnitureMove(ftr_actor->shape_type, target_ut) && + aMR_RequestItemToFitFurniture((ACTOR*)my_room, ftr_actor)) { + xyz_t goki_pos; + + my_room->state = 3; + ftr_actor->state = aFTR_STATE_WAIT_PULL; + ftr_actor->target_direction = direct; + ftr_actor->target_position.x = ftr_actor->position.x + target_table[direct].x; + ftr_actor->target_position.y = ftr_actor->position.y + target_table[direct].y; + ftr_actor->target_position.z = ftr_actor->position.z + target_table[direct].z; + + aMR_SetInfoFurnitureTable(ftr_actor->shape_type, target_ut, ftr_actor->id, + ftr_actor->layer); + aMR_SetFurniture2FG(ftr_actor, ftr_actor->target_position, TRUE); + aMR_SetPullMoveAnime(ftr_actor, game, my_room, contact_info); + aMR_SetMoveSE(ftr_actor); + my_room->pull_timer = 0; + mMkRm_ReportChangePlayerRoom(); + my_room->keep_pull_flag = TRUE; + + if (aMR_GokiburiPos_Pull(&goki_pos, ftr_actor, player)) { + aMR_MakeGokiburi(&goki_pos, game, 1); + } + } else { + /* Can't move the furniture */ + aMR_SetInfoFurnitureTable(ftr_actor->shape_type, ut, ftr_actor->id, ftr_actor->layer); + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, TRUE); + aMR_SetBubu(player, my_room, game, &my_room->pull_bubu); + } + } else { + aMR_SetBubu(player, my_room, game, &my_room->pull_bubu); + } + } else { + aMR_SetBubu(player, my_room, game, &my_room->pull_bubu); + } + } + } + } +} + +static void aMR_PlacePushFurniture(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, f32* point, + PLAYER_ACTOR* player, GAME* game) { + static s_xyz push_move_table[4] = { + { 0, 0, 1 }, /* aMR_DIRECT_UP */ + { 1, 0, 0 }, /* aMR_DIRECT_LEFT */ + { 0, 0, -1 }, /* aMR_DIRECT_DOWN */ + { -1, 0, 0 }, /* aMR_DIRECT_RIGHT */ + }; + + static xyz_t push_target_table[4] = { + { 0.0f, 0.0f, mFI_UT_WORLDSIZE_Z_F }, /* aMR_DIRECT_UP */ + { mFI_UT_WORLDSIZE_X_F, 0.0f, 0.0f }, /* aMR_DIRECT_LEFT */ + { 0.0f, 0.0f, -mFI_UT_WORLDSIZE_Z_F }, /* aMR_DIRECT_DOWN */ + { -mFI_UT_WORLDSIZE_X_F, 0.0f, 0.0f }, /* aMR_DIRECT_RIGHT */ + }; + + if (my_room->state == 7 && contact_info->contact_flag == TRUE && contact_info->contact_side == aMR_DIRECT_DOWN && + l_aMR_work.used_list[contact_info->ftrID] == TRUE && my_room->push_timer > 16 && + mPlib_check_player_actor_main_index_Furniture_Move(game) == FALSE) { + int direct = contact_info->direction; + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[contact_info->ftrID]; + + if (ftr_actor->state == aFTR_STATE_STOP) { + int ut_x; + int ut_z; + int ut; + int target_ut_x; + int target_ut_z; + int target_ut; + + aMR_Wpos2PlaceNumber(&ut_x, &ut_z, ftr_actor->position, ftr_actor->shape_type); + ut = ut_x + ut_z * UT_X_NUM; + + target_ut_x = ut_x + push_move_table[direct].x; + target_ut_z = ut_z + push_move_table[direct].z; + target_ut = target_ut_x + target_ut_z * UT_X_NUM; + + if (aMR_JudgeStickFull(aMR_PullDirect2PushDirect(direct), game)) { + xyz_t* target_pos = &push_target_table[direct]; + + aMR_SetInfoFurnitureTable(ftr_actor->shape_type, ut, aMR_NO_FTR_ID, ftr_actor->layer); + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, FALSE); + + if (aMR_JudgeFurnitureMove(ftr_actor->shape_type, target_ut) && + aMR_RequestItemToFitFurniture((ACTOR*)my_room, ftr_actor)) { + xyz_t goki_pos; + + my_room->state = 2; + ftr_actor->state = aFTR_STATE_WAIT_PUSH; + ftr_actor->target_direction = aMR_PullDirect2PushDirect(direct); + ftr_actor->target_position.x = ftr_actor->position.x + push_target_table[direct].x; + ftr_actor->target_position.y = ftr_actor->position.y + push_target_table[direct].y; + ftr_actor->target_position.z = ftr_actor->position.z + push_target_table[direct].z; + + aMR_SetInfoFurnitureTable(ftr_actor->shape_type, target_ut, ftr_actor->id, ftr_actor->layer); + aMR_SetFurniture2FG(ftr_actor, ftr_actor->target_position, TRUE); + aMR_SetPushMoveAnime(ftr_actor, game, my_room, contact_info); + aMR_SetMoveSE(ftr_actor); + mMkRm_ReportChangePlayerRoom(); + my_room->keep_push_flag = TRUE; + + if (aMR_GokiburiPos_Push(&goki_pos, ftr_actor, player)) { + aMR_MakeGokiburi(&goki_pos, game, 1); + } + } else { + /* Can't move the furniture */ + aMR_SetInfoFurnitureTable(ftr_actor->shape_type, ut, ftr_actor->id, ftr_actor->layer); + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, TRUE); + aMR_SetBubu(player, my_room, game, &my_room->push_bubu); + } + } + } + } +} + +static int aMR_DecideKurukuruDirect(MY_ROOM_ACTOR* my_room, s16* state, aMR_contact_info_c* contact_info, + FTR_ACTOR* ftr_actor, GAME* game) { + int direct = contact_info->direction; + int left = rotateDt[direct].left; + int right = rotateDt[direct].right; + + if (my_room->allow_rotation_flag) { + if (aMR_JudgeStickFull(left, game)) { + *state = aFTR_STATE_WAIT_LROTATE; + ftr_actor->rotation_delay_timer = 3; + return TRUE; + } + + if (aMR_JudgeStickFull(right, game)) { + *state = aFTR_STATE_WAIT_RROTATE; + ftr_actor->rotation_delay_timer = 3; + return TRUE; + } + } + + return FALSE; +} + +static void aMR_SetTargetAngle(FTR_ACTOR* ftr_actor) { + if (ftr_actor->state == aFTR_STATE_WAIT_RROTATE) { + ftr_actor->angle_y_target = ftr_actor->angle_y - 90.0f; + } else { + ftr_actor->angle_y_target = ftr_actor->angle_y + 90.0f; + } +} + +static s_xyz* aMR_GetRotateForbidData(s16 rotation_state, u8 shape) { + int idx = (int)shape; + + if (rotation_state == aFTR_STATE_WAIT_RROTATE) { + return rotate_forbid_table[idx].right; + } else { + return rotate_forbid_table[idx].left; + } +} + +static int aMR_SearchCompleteObstacle(FTR_ACTOR* ftr_actor, s16 rotation_state, int player_ut, int ftr_ut) { + u8 shape = ftr_actor->shape_type; + mActor_name_t* fg_p = mFI_BkNumtoUtFGTop(0, 0); + s_xyz* rotate_forbid_data = aMR_GetRotateForbidData(rotation_state, shape); + int i; + + for (i = 0; i < 2; i++) { + int ut = ftr_ut + rotate_forbid_data[i].z * UT_X_NUM + rotate_forbid_data[i].x; + + if (l_place_table[ut] != aMR_NO_FTR_ID) { + return FALSE; + } + + if (fg_p[ut] != EMPTY_NO) { + return FALSE; + } + + if (ut == player_ut) { + return FALSE; + } + } + + return TRUE; +} + +static int aMR_SearchFrictionObstacle(FTR_ACTOR* ftr_actor, s16 rotation_state, int ftr_ut) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + int shape = ftr_actor->shape_type; + + if (profile->check_rotation && shape <= aFTR_SHAPE_TYPEB_0) { + int i; + s_xyz* rotate_forbid_data; + + if (rotation_state == aFTR_STATE_WAIT_RROTATE) { + rotate_forbid_data = rotate_forbid_friction_table[shape].right; + } else { + rotate_forbid_data = rotate_forbid_friction_table[shape].left; + } + + for (i = 0; i < 2; i++) { + int ut = ftr_ut + rotate_forbid_data[i].z * UT_X_NUM + rotate_forbid_data[i].x; + + if (l_place_table[ut] != aMR_NO_FTR_ID) { + FTR_ACTOR* other_ftr_actor = &l_aMR_work.ftr_actor_list[l_place_table[ut]]; + aFTR_PROFILE* other_profile = aMR_GetFurnitureProfile(other_ftr_actor->name); + + if (other_profile->check_rotation) { + return FALSE; + } + } + } + } + + return TRUE; +} + +static int aMR_RotatePermission(FTR_ACTOR* ftr_actor, PLAYER_ACTOR* player, s16 rotation_state) { + int player_ut_x; + int player_ut_z; + int player_ut; + int ftr_ut_x; + int ftr_ut_z; + int ftr_ut; + + aMR_Wpos2PlaceNumber(&player_ut_x, &player_ut_z, player->actor_class.world.position, 0); + player_ut = player_ut_z * UT_X_NUM + player_ut_x; + + aMR_Wpos2PlaceNumber(&ftr_ut_x, &ftr_ut_z, ftr_actor->position, ftr_actor->shape_type); + ftr_ut = ftr_ut_z * UT_X_NUM + ftr_ut_x; + + if (aMR_SearchCompleteObstacle(ftr_actor, rotation_state, player_ut, ftr_ut)) { + if (aMR_SearchFrictionObstacle(ftr_actor, rotation_state, ftr_ut)) { + return TRUE; + } else { + return FALSE; + } + } else { + return FALSE; + } +} + +static int aMR_ResetFurnitureType(FTR_ACTOR* ftr_actor, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + s16 rotation_state) { + int sub_idx; + u8 shape; + int direct; + f32 contact_ratio; + aMR_type_target_c type_target; + + contact_ratio = contact_info->contact_percent; + direct = contact_info->direction; + + if (contact_ratio >= 0.5f) { + sub_idx = 0; + } else { + sub_idx = 1; + } + + shape = ftr_actor->shape_type; + type_target = type_target_table[shape][direct][sub_idx]; + + if (type_target.type != shape) { + ftr_actor->shape_type = type_target.type; + ftr_actor->position.x += type_target.offset.x; + ftr_actor->position.y += type_target.offset.y; + ftr_actor->position.z += type_target.offset.z; + aMR_MoveShapeCenter(ftr_actor); + } + + return aMR_RotatePermission(ftr_actor, player, rotation_state); +} + +static void aMR_TypeChangeByRotate(FTR_ACTOR* ftr_actor) { + static u8 rt_place_tbl[] = { aFTR_SHAPE_TYPEB_0, aFTR_SHAPE_TYPEB_90, aFTR_SHAPE_TYPEB_180, aFTR_SHAPE_TYPEB_270 }; + static u8 lt_place_tbl[] = { aFTR_SHAPE_TYPEB_180, aFTR_SHAPE_TYPEB_270, aFTR_SHAPE_TYPEB_0, aFTR_SHAPE_TYPEB_90 }; + + if (ftr_actor->state == aFTR_STATE_WAIT_LROTATE) { + ftr_actor->shape_type = lt_place_tbl[ftr_actor->shape_type]; + } else { + ftr_actor->shape_type = rt_place_tbl[ftr_actor->shape_type]; + } +} + +static int aMR_SearchNextSituation(FTR_ACTOR* ftr_actor) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + int shape = ftr_actor->shape_type; + int ut_x; + int ut_z; + int ut; + + aMR_Wpos2PlaceNumber(&ut_x, &ut_z, ftr_actor->position, shape); + ut = ut_z * UT_X_NUM + ut_x; + + if (shape > aFTR_SHAPE_TYPEB_0 && profile->check_rotation) { + aMR_place_info_c* place_info = next_table[shape]; + + if (place_info != NULL) { + int count = place_info->count; + s_xyz* ofs_p = place_info->ofs_p; + int i; + + for (i = 0; i < count; i++) { + int check_ut = ut + ofs_p[i].z * UT_Z_NUM + ofs_p[i].x; + + if (l_place_table[check_ut] != aMR_NO_FTR_ID) { + FTR_ACTOR* other_ftr_actor = &l_aMR_work.ftr_actor_list[l_place_table[check_ut]]; + aFTR_PROFILE* other_profile = aMR_GetFurnitureProfile(other_ftr_actor->name); + + if (other_profile->check_rotation) { + return FALSE; + } + } + } + } + } + + return TRUE; +} + +typedef struct sit_data_s { + u8* direction_p; + int direction_count; +} aMR_sit_data_c; + +static u8 aMR_sit_small_chair1[] = { aMR_CONTACT_DIR_FRONT }; +static aMR_sit_data_c aMR_sit_small_chair1_data = { aMR_sit_small_chair1, ARRAY_COUNT(aMR_sit_small_chair1) }; + +static u8 aMR_sit_small_chair4[] = { aMR_CONTACT_DIR_BACK, aMR_CONTACT_DIR_RIGHT, aMR_CONTACT_DIR_FRONT, + aMR_CONTACT_DIR_LEFT }; +static aMR_sit_data_c aMR_sit_small_chair4_data = { aMR_sit_small_chair4, ARRAY_COUNT(aMR_sit_small_chair4) }; + +static u8 aMR_sit_middle_sofa[] = { aMR_CONTACT_DIR_FRONT }; +static aMR_sit_data_c aMR_sit_middle_sofa_data = { aMR_sit_middle_sofa, ARRAY_COUNT(aMR_sit_middle_sofa) }; + +static aMR_sit_data_c* aME_sit_data[] = { + &aMR_sit_small_chair1_data, + &aMR_sit_small_chair4_data, + &aMR_sit_middle_sofa_data, +}; + +static void aMR_SitDownFurniture(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + int angle = (u16)((s16)(DEG2SHORT_ANGLE2(270.0f) + gamePT->mcon.move_angle + (s16)getCamera2AngleY(play)) - + player->actor_class.shape_info.rotation.y); + + if (contact_info->contact_flag) { + f32 point[] = { 0.0f, -1.0f }; + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[contact_info->ftrID]; + f32 angle_f; + + aMR_RotateY(point, SHORT2RAD_ANGLE2(player->actor_class.shape_info.rotation.y)); + angle_f = ABS(mCoBG_Get2VectorAngleF(contact_info->normal_p, point, 1)); // This gets called 3 times due to ABS + + if (ftr_actor->state != aFTR_STATE_BYE && ftr_actor->state != aFTR_STATE_BIRTH_WAIT && + ftr_actor->state != aFTR_STATE_BIRTH && ftr_actor->state != aFTR_STATE_DEATH && + contact_info->contact_side == aMR_CONTACT_DIR_FRONT && my_room->state == 0 && + aMR_3DStickNuetral() == FALSE && angle < DEG2SHORT_ANGLE2(15.0f) && angle_f < 15.0f && + gamePT->mcon.move_pR > 0.6f) { + my_room->sit_timer++; + } else { + my_room->sit_timer = 0; + } + } else { + my_room->sit_timer = 0; + } + + if (my_room->sit_timer > 14 && my_room->state == 0 && contact_info->contact_flag == TRUE && + contact_info->contact_side == aMR_CONTACT_DIR_FRONT) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[contact_info->ftrID]; + u8 used = l_aMR_work.used_list[contact_info->ftrID]; + int ftr_no = ftr_actor->name; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_no); + + if (profile != NULL && used) { + u8 contact_action = profile->contact_action; + int i; + + for (i = 0; i < 3; i++) { + if (((contact_action >> i) & 1) != 0) { + aMR_sit_data_c* sit_data = aME_sit_data[i]; + int j; + + for (j = 0; j < sit_data->direction_count; j++) { + if (contact_info->contact_direction == sit_data->direction_p[j]) { + xyz_t nice_pos = { 0.0f, 0.0f, 0.0f }; + + aMR_SetNicePos(&nice_pos, player->actor_class.world.position, + contact_info->contact_edge_start, contact_info->contact_edge_end, + contact_info, 2); + my_room->nice_pos = nice_pos; + mPlib_request_main_sitdown_type1(game, aMR_GetPlayerDirect(contact_info->normal_p), + &nice_pos, ftr_no); + return; + } + } + } + } + } + } +} + +static int aMR_GetBedHeadDirect(FTR_ACTOR* ftr_actor) { + u16 angle = ftr_actor->s_angle_y; + + if (angle >= (DEG2SHORT_ANGLE2(90.0f) - 2) && angle <= (DEG2SHORT_ANGLE2(90.0f) + 2)) { + return aMR_DIRECT_DOWN; + } else if (angle >= (DEG2SHORT_ANGLE2(180.0f) - 2) && angle <= (DEG2SHORT_ANGLE2(180.0f) + 2)) { + return aMR_DIRECT_RIGHT; + } else if (angle >= (DEG2SHORT_ANGLE2(270.0f) - 2) && angle <= (DEG2SHORT_ANGLE2(270.0f) + 2)) { + return aMR_DIRECT_UP; + } else { + return aMR_DIRECT_LEFT; + } +} + +static FTR_ACTOR* aMR_Wpos2FtrInfo(xyz_t pos, u8* action, u16* inter, s16 layer) { + int ut_x; + int ut_z; + + *action = aFTR_CONTACT_ACTION_NONE; + *inter = aFTR_INTERACTION_NONE; + + if (mFI_Wpos2UtNum(&ut_x, &ut_z, pos)) { + mActor_name_t item_no; + int ftrID; + + aMR_UnitNum2FtrItemNoFtrID(&item_no, &ftrID, ut_x, ut_z, layer); + if ((ITEM_IS_FTR(item_no) || item_no == RSV_FE1F) && ftrID >= 0 && ftrID < l_aMR_work.list_size) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL) { + *action = profile->contact_action; + *inter = profile->interaction_type; + return ftr_actor; + } + } + } + + return NULL; +} + +static int aMR_GetUnderfootSidePos(xyz_t* left, xyz_t* right, FTR_ACTOR* ftr_actor, u8 exist) { + static xyz_t pos0 = { 0.0f, 0.0f, 0.0f }; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + *left = pos0; + *right = pos0; + + if (profile != NULL && exist) { + if ((profile->contact_action >> aFTR_CONTACT_ACTION_TYPE_BED_SINGLE) & 1) { + xyz_t pos = ftr_actor->base_position; + f32 angle = SHORT2RAD_ANGLE2(ftr_actor->s_angle_y); + + left->x = pos.x + mFI_UT_WORLDSIZE_X_F; + left->y = pos.y; + left->z = pos.z - mFI_UT_WORLDSIZE_Z_F; + + sMath_RotateY(left, angle); + left->x += ftr_actor->position.x; + left->y += ftr_actor->position.y; + left->z += ftr_actor->position.z; + + right->x = pos.x + mFI_UT_WORLDSIZE_X_F; + right->y = pos.y; + right->z = pos.z + mFI_UT_WORLDSIZE_Z_F; + sMath_RotateY(right, angle); + right->x += ftr_actor->position.x; + right->y += ftr_actor->position.y; + right->z += ftr_actor->position.z; + + return TRUE; + } + + if ((profile->contact_action >> aFTR_CONTACT_ACTION_TYPE_BED_DOUBLE) & 1) { + xyz_t pos = ftr_actor->base_position; + f32 angle = SHORT2RAD_ANGLE2(ftr_actor->s_angle_y); + + left->x = pos.x + mFI_UT_WORLDSIZE_HALF_X_F; + left->y = pos.y; + left->z = pos.z - (mFI_UT_WORLDSIZE_Z_F + mFI_UT_WORLDSIZE_HALF_Z_F); + + sMath_RotateY(left, angle); + left->x += ftr_actor->position.x; + left->y += ftr_actor->position.y; + left->z += ftr_actor->position.z; + + right->x = pos.x + mFI_UT_WORLDSIZE_HALF_X_F; + right->y = pos.y; + right->z = pos.z + (mFI_UT_WORLDSIZE_Z_F + mFI_UT_WORLDSIZE_HALF_Z_F); + sMath_RotateY(right, angle); + right->x += ftr_actor->position.x; + right->y += ftr_actor->position.y; + right->z += ftr_actor->position.z; + + return TRUE; + } + } + + return FALSE; +} + +static int aMR_GetPillowSidePos(xyz_t* left, xyz_t* right, FTR_ACTOR* ftr_actor, u8 exist) { + static xyz_t pos0 = { 0.0f, 0.0f, 0.0f }; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + *left = pos0; + *right = pos0; + + if (profile != NULL && exist) { + if ((profile->contact_action >> aFTR_CONTACT_ACTION_TYPE_BED_SINGLE) & 1) { + xyz_t pos = ftr_actor->base_position; + f32 angle = SHORT2RAD_ANGLE2(ftr_actor->s_angle_y); + + left->x = pos.x; + left->y = pos.y; + left->z = pos.z - mFI_UT_WORLDSIZE_Z_F; + + sMath_RotateY(left, angle); + left->x += ftr_actor->position.x; + left->y += ftr_actor->position.y; + left->z += ftr_actor->position.z; + + right->x = pos.x; + right->y = pos.y; + right->z = pos.z + mFI_UT_WORLDSIZE_Z_F; + sMath_RotateY(right, angle); + right->x += ftr_actor->position.x; + right->y += ftr_actor->position.y; + right->z += ftr_actor->position.z; + + return TRUE; + } + + if ((profile->contact_action >> aFTR_CONTACT_ACTION_TYPE_BED_DOUBLE) & 1) { + xyz_t pos = ftr_actor->base_position; + f32 angle = SHORT2RAD_ANGLE2(ftr_actor->s_angle_y); + + left->x = pos.x - mFI_UT_WORLDSIZE_HALF_X_F; + left->y = pos.y; + left->z = pos.z - (mFI_UT_WORLDSIZE_Z_F + mFI_UT_WORLDSIZE_HALF_Z_F); + + sMath_RotateY(left, angle); + left->x += ftr_actor->position.x; + left->y += ftr_actor->position.y; + left->z += ftr_actor->position.z; + + right->x = pos.x - mFI_UT_WORLDSIZE_HALF_X_F; + right->y = pos.y; + right->z = pos.z + (mFI_UT_WORLDSIZE_Z_F + mFI_UT_WORLDSIZE_HALF_Z_F); + sMath_RotateY(right, angle); + right->x += ftr_actor->position.x; + right->y += ftr_actor->position.y; + right->z += ftr_actor->position.z; + + return TRUE; + } + } + + return FALSE; +} + +static int aMR_CheckBedUnderfoot(aMR_contact_info_c* contact_info, PLAYER_ACTOR* player) { + if (contact_info->contact_flag == TRUE) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[contact_info->ftrID]; + u8 used = l_aMR_work.used_list[contact_info->ftrID]; + mActor_name_t* fg_p = aMR_GetLayerTopFg(mCoBG_LAYER0); + xyz_t pillow_left; + xyz_t pillow_right; + + if (aMR_GetPillowSidePos(&pillow_left, &pillow_right, ftr_actor, used)) { + int player_ut_x = (int)(player->actor_class.world.position.x / mFI_UT_WORLDSIZE_X_F); + int player_ut_z = (int)(player->actor_class.world.position.z / mFI_UT_WORLDSIZE_Z_F); + int pillow_left_ut_x = (int)(pillow_left.x / mFI_UT_WORLDSIZE_X_F); + int pillow_left_ut_z = (int)(pillow_left.z / mFI_UT_WORLDSIZE_Z_F); + int pillow_right_ut_x = (int)(pillow_right.x / mFI_UT_WORLDSIZE_X_F); + int pillow_right_ut_z = (int)(pillow_right.z / mFI_UT_WORLDSIZE_Z_F); + xyz_t underfoot_left; + xyz_t underfoot_right; + u8 contact_action_type; + u16 inter_type; + + /* Check left first */ + if (player_ut_x == pillow_left_ut_x && player_ut_z == pillow_left_ut_z) { + if (aMR_GetUnderfootSidePos(&underfoot_left, &underfoot_right, ftr_actor, used)) { + if (aMR_Wpos2FtrInfo(underfoot_left, &contact_action_type, &inter_type, mCoBG_LAYER0) != NULL) { + if (aFTR_CHECK_INTERACTION(inter_type, aFTR_INTERACTION_TYPE_NO_COLLISION) == FALSE) { + return TRUE; + } + } else { + int underfoot_left_ut_x = (int)(underfoot_left.x / mFI_UT_WORLDSIZE_X_F); + int underfoot_left_ut_z = (int)(underfoot_left.z / mFI_UT_WORLDSIZE_Z_F); + int underfoot_left_ut = underfoot_left_ut_z * UT_X_NUM + underfoot_left_ut_x; + + if (fg_p[underfoot_left_ut] == RSV_WALL_NO || fg_p[underfoot_left_ut] == RSV_FE1C || + ITEM_NAME_GET_TYPE(fg_p[underfoot_left_ut]) == NAME_TYPE_WARP) { + return TRUE; + } + } + } + } + + /* Check right */ + if (player_ut_x == pillow_right_ut_x && player_ut_z == pillow_right_ut_z) { + if (aMR_GetUnderfootSidePos(&underfoot_left, &underfoot_right, ftr_actor, used)) { + if (aMR_Wpos2FtrInfo(underfoot_right, &contact_action_type, &inter_type, mCoBG_LAYER0) != NULL) { + if (aFTR_CHECK_INTERACTION(inter_type, aFTR_INTERACTION_TYPE_NO_COLLISION) == FALSE) { + return TRUE; + } + } else { + int underfoot_right_ut_x = (int)(underfoot_right.x / mFI_UT_WORLDSIZE_X_F); + int underfoot_right_ut_z = (int)(underfoot_right.z / mFI_UT_WORLDSIZE_Z_F); + int underfoot_right_ut = underfoot_right_ut_z * UT_X_NUM + underfoot_right_ut_x; + + if (fg_p[underfoot_right_ut] == RSV_WALL_NO || fg_p[underfoot_right_ut] == RSV_FE1C || + ITEM_NAME_GET_TYPE(fg_p[underfoot_right_ut]) == NAME_TYPE_WARP) { + return TRUE; + } + } + } + } + } + } + + return FALSE; +} + +static void aMR_JudgeGoToBed(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + u16 angle = (s16)(DEG2SHORT_ANGLE2(270.0f) + gamePT->mcon.move_angle + (s16)getCamera2AngleY(play)) - + player->actor_class.shape_info.rotation.y; + + if (contact_info->contact_flag == TRUE) { + f32 point[] = { 0.0f, -1.0f }; + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[contact_info->ftrID]; + f32 angle_f; + + aMR_RotateY(point, SHORT2RAD_ANGLE2(player->actor_class.shape_info.rotation.y)); + angle_f = ABS(mCoBG_Get2VectorAngleF(contact_info->normal_p, point, 1)); // This gets called 3 times due to ABS + + if (ftr_actor->state != aFTR_STATE_BYE && ftr_actor->state != aFTR_STATE_BIRTH_WAIT && + ftr_actor->state != aFTR_STATE_BIRTH && ftr_actor->state != aFTR_STATE_DEATH && my_room->state == 0 && + aMR_3DStickNuetral() == FALSE && angle < DEG2SHORT_ANGLE(35.0f) && angle_f < 35.0f && + gamePT->mcon.move_pR > 0.6f) { + if (aMR_CheckBedUnderfoot(contact_info, player) == FALSE) { + my_room->bed_timer++; + } else { + my_room->bed_timer = 0; + } + } else { + my_room->bed_timer = 0; + } + } else { + my_room->bed_timer = 0; + } + + if (my_room->bed_timer > 14 && my_room->state == 0 && contact_info->contact_flag == TRUE && + contact_info->contact_side == aMR_CONTACT_DIR_FRONT) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[contact_info->ftrID]; + u8 used = l_aMR_work.used_list[contact_info->ftrID]; + int ftr_no = ftr_actor->name; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_no); + + if (profile != NULL && used) { + if (aFTR_CHK_BED(profile->contact_action)) { + if (contact_info->contact_direction == aMR_CONTACT_DIR_FRONT || + contact_info->contact_direction == aMR_CONTACT_DIR_BACK) { + xyz_t nice_pos = { 0.0f, 0.0f, 0.0f }; + int player_direct; + int head_direct; + + aMR_SetNicePos(&nice_pos, player->actor_class.world.position, contact_info->contact_edge_start, + contact_info->contact_edge_end, contact_info, 0); + my_room->nice_pos = nice_pos; + player_direct = aMR_ConvertDirectLevel(aMR_GetPlayerDirect(contact_info->normal_p)); + my_room->head_direction = aMR_GetBedHeadDirect(ftr_actor); + my_room->bed_ftr_actor_idx = contact_info->ftrID; + head_direct = aMR_ConvertDirectLevel(my_room->head_direction); + + if (player_direct != -1 && head_direct != -1) { + mPlib_request_main_lie_bed_type1(game, player_direct, &nice_pos, head_direct, ftr_no); + } + } + } + } + } +} + +static int aMR_CheckHikidashi(FTR_ACTOR* ftr_actor, PLAYER_ACTOR* player, aMR_contact_info_c* contact_info) { + int direct = contact_info->direction; + int x0; + int z0; + int x1; + int z1; + + if (aMR_GetTypeBPlaceInfo(&x0, &z0, &x1, &z1, ftr_actor->shape_type, ftr_actor->position)) { + mActor_name_t* fg_p = aMR_GetLayerTopFg(mCoBG_LAYER0); + + if (fg_p != NULL && aMR_Direct2PlussUnit(&x0, &z0, direct) && aMR_Direct2PlussUnit(&x1, &z1, direct)) { + int ut0 = z0 * UT_X_NUM + x0; + int ut1 = z1 * UT_X_NUM + x1; + mActor_name_t fg0 = fg_p[ut0]; + mActor_name_t fg1 = fg_p[ut1]; + + if (!(ITEM_IS_FTR(fg0) || fg0 == RSV_FE1F) && !(ITEM_IS_FTR(fg1) || fg1 == RSV_FE1F)) { + return TRUE; + } + } + } + + return FALSE; +} + +static void aMR_SetOpenFtrDemoData(MY_ROOM_ACTOR* my_room, FTR_ACTOR* ftr_actor, aMR_contact_info_c* contact_info) { + ftr_actor->demo_status = 1; + my_room->msg_timer = 0; + my_room->requested_msg_type = aMR_MSG_STATE_WAIT_MSG; + my_room->demo_flag = TRUE; + my_room->demo_ftrID = contact_info->ftrID; + my_room->pull_timer = 0; +} + +static void aMR_SetMDFtrDemoData(MY_ROOM_ACTOR* my_room, FTR_ACTOR* ftr_actor, aMR_contact_info_c* contact_info) { + ftr_actor->demo_status = 1; + my_room->msg_timer = 0; + my_room->requested_msg_type = aMR_MSG_STATE_WAIT_MD; + my_room->demo_flag = TRUE; + my_room->demo_ftrID = contact_info->ftrID; + my_room->pull_timer = 0; +} + +static int aMR_JudgeDemoStart(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, GAME* game, + PLAYER_ACTOR* player) { + if (my_room->force_open_demo_flag == TRUE && my_room->state == 8 && my_room->demo_flag == FALSE && + contact_info->contact_flag == TRUE && contact_info->contact_side == aMR_CONTACT_DIR_FRONT && + mPlib_check_player_warp_forEvent() == FALSE) { + int stick_direct = aMR_Get3dDirectStatus(contact_info->direction); + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[contact_info->ftrID]; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL) { + if (contact_info->contact_direction == aMR_CONTACT_DIR_FRONT && + (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_WARDROBE) || + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_CLOSET))) { + if (ftr_actor->demo_status == FALSE) { + /* Open closet/wardrobe */ + aMR_SetOpenFtrDemoData(my_room, ftr_actor, contact_info); + my_room->force_open_demo_flag = FALSE; + return TRUE; + } + } else if (contact_info->contact_direction == aMR_CONTACT_DIR_FRONT && + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_DRAWERS)) { + /* Open drawers if nothing is blocking them */ + if (ftr_actor->demo_status == FALSE) { + if (profile->shape == aFTR_SHAPE_TYPEA) { + aMR_SetOpenFtrDemoData(my_room, ftr_actor, contact_info); + my_room->force_open_demo_flag = FALSE; + return TRUE; + } + + if (aMR_CheckHikidashi(ftr_actor, player, contact_info)) { + aMR_SetOpenFtrDemoData(my_room, ftr_actor, contact_info); + my_room->force_open_demo_flag = FALSE; + return TRUE; + } else { + /* Something is blocking the 2x1 drawers on one side */ + aMR_SetBubu(player, my_room, game, &my_room->pull_bubu); + my_room->force_open_demo_flag = FALSE; + return FALSE; + } + } + } else { + my_room->state = 6; + my_room->pull_timer = 0; + } + } + } + + if (my_room->demo_flag == TRUE) { + return TRUE; + } + + return FALSE; +} + +static void aMR_PlaceKurukuruFurniture(MY_ROOM_ACTOR* my_room, aMR_contact_info_c* contact_info, PLAYER_ACTOR* player, + GAME* game) { + if (my_room->state == 6 && my_room->allow_rotation_flag == TRUE && contact_info->contact_flag == TRUE && + contact_info->contact_side == aMR_CONTACT_DIR_FRONT) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[contact_info->ftrID]; + u8 used = l_aMR_work.used_list[contact_info->ftrID]; + + if (used && ftr_actor->state == aFTR_STATE_STOP) { + s16 rotation_state; + + if (aMR_DecideKurukuruDirect(my_room, &rotation_state, contact_info, ftr_actor, game)) { + u8 shape = ftr_actor->shape_type; + int ftr_ut_x; + int ftr_ut_z; + int ftr_ut; + + aMR_Wpos2PlaceNumber(&ftr_ut_x, &ftr_ut_z, ftr_actor->position, ftr_actor->shape_type); + ftr_ut = ftr_ut_z * UT_X_NUM + ftr_ut_x; + + if (ftr_actor->shape_type <= aFTR_SHAPE_TYPEB_0) { + aMR_SetInfoFurnitureTable(shape, ftr_ut, aMR_NO_FTR_ID, ftr_actor->layer); + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, FALSE); + + if (aMR_ResetFurnitureType(ftr_actor, contact_info, player, rotation_state) && + aMR_RequestItemToFitFurniture((ACTOR*)my_room, ftr_actor)) { + int next_ut_x; + int next_ut_z; + int next_ut; + xyz_t goki_pos; + + ftr_actor->state = rotation_state; + my_room->state = 4; + aMR_SetTargetAngle(ftr_actor); + my_room->allow_rotation_flag = FALSE; + aMR_TypeChangeByRotate(ftr_actor); + aMR_Wpos2PlaceNumber(&next_ut_x, &next_ut_z, ftr_actor->position, ftr_actor->shape_type); + next_ut = next_ut_z * UT_X_NUM + next_ut_x; + aMR_SetInfoFurnitureTable(ftr_actor->shape_type, next_ut, ftr_actor->id, ftr_actor->layer); + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, TRUE); + aMR_SetRotateSE(ftr_actor); + mMkRm_ReportChangePlayerRoom(); + + if (aMR_GokiburiPos_Rotate(&goki_pos, ftr_actor, player)) { + aMR_MakeGokiburi(&goki_pos, game, 1); + } + return; + } else { + /* Failed to rotate */ + aMR_SetInfoFurnitureTable(shape, ftr_ut, ftr_actor->id, ftr_actor->layer); + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, TRUE); + aMR_SetBubu(player, my_room, game, NULL); + } + } else { + if (aMR_SearchNextSituation(ftr_actor) && + aMR_RequestItemToFitFurniture((ACTOR*)my_room, ftr_actor)) { + ftr_actor->state = rotation_state; + my_room->state = 4; + aMR_SetTargetAngle(ftr_actor); + my_room->allow_rotation_flag = FALSE; + aMR_SetRotateSE(ftr_actor); + aMR_SetInfoFurnitureTable(ftr_actor->shape_type, ftr_ut, ftr_actor->id, ftr_actor->layer); + aMR_SetFurniture2FG(ftr_actor, ftr_actor->position, TRUE); + mMkRm_ReportChangePlayerRoom(); + return; + } else { + aMR_SetBubu(player, my_room, game, NULL); + } + } + + my_room->allow_rotation_flag = FALSE; + } + } + } +} + +static void aMR_GetBedTurnPos(xyz_t* player_pos, int direct) { + static xyz_t offset_data[mFI_MOVEDIR_NUM] = { + { 0.0f, 0.0f, 0.0f }, // mFI_MOVEDIR_NONE + { mFI_UT_WORLDSIZE_X_F, 0.0f, 0.0f }, // mFI_MOVEDIR_RIGHT + { -mFI_UT_WORLDSIZE_X_F, 0.0f, 0.0f }, // mFI_MOVEDIR_LEFT + { 0.0f, 0.0f, -mFI_UT_WORLDSIZE_Z_F }, // mFI_MOVEDIR_UP + { 0.0f, 0.0f, mFI_UT_WORLDSIZE_Z_F }, // mFI_MOVEDIR_DOWN + }; + + player_pos->x += offset_data[direct].x; + player_pos->y += offset_data[direct].y; + player_pos->z += offset_data[direct].z; +} + +static int aMR_GetBedAction(ACTOR* player_actorx, int direct) { + xyz_t player_pos; + ACTOR* actorx; + xyz_t head_pos; + xyz_t next_player_pos; + xyz_t next_head_pos; + mActor_name_t* fg_p; + + player_pos = player_actorx->world.position; + actorx = aMR_CLIP->my_room_actor_p; + head_pos = ((PLAYER_ACTOR*)player_actorx)->head_pos; + next_player_pos = player_pos; + next_head_pos = head_pos; + fg_p = aMR_GetLayerTopFg(mCoBG_LAYER0); + + aMR_GetBedTurnPos(&next_player_pos, direct); + aMR_GetBedTurnPos(&next_head_pos, direct); + if (actorx != NULL) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + int ut_x; + int ut_z; + + if (mFI_Wpos2UtNum(&ut_x, &ut_z, next_player_pos)) { + mActor_name_t item_no; + int ftrID; + + aMR_UnitNum2FtrItemNoFtrID(&item_no, &ftrID, ut_x, ut_z, mCoBG_LAYER0); + if ((ITEM_IS_FTR(item_no) || item_no == RSV_FE1F) && ftrID >= 0 && ftrID < l_aMR_work.list_size) { + FTR_ACTOR* ftr_actor = &l_aMR_work.ftr_actor_list[ftrID]; + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + if (profile != NULL) { + if (ftrID == my_room->bed_ftr_actor_idx) { + return mPlayer_BED_ACTION_ROLL; + } + + if (aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_NO_COLLISION)) { + return mPlayer_BED_ACTION_OUT; + } + + if (aFTR_CHK_BED(profile->contact_action)) { + int cur_ut_x = (int)(player_pos.x / mFI_UT_WORLDSIZE_X_F); + int cur_ut_z = (int)(player_pos.z / mFI_UT_WORLDSIZE_Z_F); + mActor_name_t item_no2 = EMPTY_NO; + int ftrID2 = 0; + + aMR_UnitNum2FtrItemNoFtrID(&item_no2, &ftrID2, cur_ut_x, cur_ut_z, mCoBG_LAYER0); + if ((ITEM_IS_FTR(item_no2) || item_no2 == RSV_FE1F) && ftrID2 >= 0 && + ftrID2 < l_aMR_work.list_size) { + FTR_ACTOR* ftr_actor2 = &l_aMR_work.ftr_actor_list[ftrID2]; + + /* Check if the beds are aligned so that you can roll across them */ + if (ftr_actor->s_angle_y == ftr_actor2->s_angle_y) { + xyz_t bed0_uf_left; + xyz_t bed0_uf_right; + xyz_t bed1_uf_left; + xyz_t bed1_uf_right; + + if (aMR_GetUnderfootSidePos(&bed0_uf_left, &bed0_uf_right, ftr_actor, + l_aMR_work.used_list[ftrID]) && + aMR_GetUnderfootSidePos(&bed1_uf_left, &bed1_uf_right, ftr_actor2, + l_aMR_work.used_list[ftrID2])) { + if (mFI_POS2UT(bed0_uf_left.x) == mFI_POS2UT(bed1_uf_left.x) || + mFI_POS2UT(bed0_uf_left.z) == mFI_POS2UT(bed1_uf_left.z)) { + return mPlayer_BED_ACTION_ROLL; + } + } + } + } + } + + return mPlayer_BED_ACTION_NONE; + } + } else { + int ut = ut_z * UT_X_NUM + ut_x; + + if (fg_p[ut] == RSV_WALL_NO || fg_p[ut] == RSV_FE1C || ITEM_NAME_GET_TYPE(fg_p[ut]) == NAME_TYPE_WARP) { + return mPlayer_BED_ACTION_NONE; + } + } + + return mPlayer_BED_ACTION_OUT; + } + } + + return mPlayer_BED_ACTION_NONE; +} diff --git a/src/ac_my_room_data.c_inc b/src/ac_my_room_data.c_inc index 883e56e5..ea000ba6 100644 --- a/src/ac_my_room_data.c_inc +++ b/src/ac_my_room_data.c_inc @@ -22,32 +22,170 @@ typedef struct { xyz_t offset; } aMR_type_target_c; -static aMR_type_target_c type_target_table[] = { - { 2, { 0.0f, 0.0f, -40.0f } }, { 2, { 0.0f, 0.0f, -40.0f } }, { 2, { 0.0f, 0.0f, -40.0f } }, - { 0, { 0.0f, 0.0f, 0.0f } }, { 0, { 0.0f, 0.0f, 0.0f } }, { 0, { 0.0f, 0.0f, 0.0f } }, - { 0, { 0.0f, 0.0f, 0.0f } }, { 2, { 0.0f, 0.0f, -40.0f } }, { 1, { 0.0f, 0.0f, 0.0f } }, - { 3, { -40.0f, 0.0f, 0.0f } }, { 3, { -40.0f, 0.0f, 0.0f } }, { 3, { -40.0f, 0.0f, 0.0f } }, - { 3, { -40.0f, 0.0f, 0.0f } }, { 1, { 0.0f, 0.0f, 0.0f } }, { 1, { 0.0f, 0.0f, 0.0f } }, - { 1, { 0.0f, 0.0f, 0.0f } }, { 2, { 0.0f, 0.0f, 0.0f } }, { 2, { 0.0f, 0.0f, 0.0f } }, - { 2, { 0.0f, 0.0f, 0.0f } }, { 0, { 0.0f, 0.0f, 40.0f } }, { 0, { 0.0f, 0.0f, 40.0f } }, - { 0, { 0.0f, 0.0f, 40.0f } }, { 0, { 0.0f, 0.0f, 40.0f } }, { 2, { 0.0f, 0.0f, 0.0f } }, - { 1, { 40.0f, 0.0f, 0.0f } }, { 3, { 0.0f, 0.0f, 0.0f } }, { 3, { 0.0f, 0.0f, 0.0f } }, - { 3, { 0.0f, 0.0f, 0.0f } }, { 3, { 0.0f, 0.0f, 0.0f } }, { 1, { 40.0f, 0.0f, 0.0f } }, - { 1, { 40.0f, 0.0f, 0.0f } }, { 1, { 40.0f, 0.0f, 0.0f } }, +static aMR_type_target_c type_target_table[4][4][2] = { + { + { + { aFTR_SHAPE_TYPEB_270, { 0.0f, 0.0f, -40.0f } }, + { aFTR_SHAPE_TYPEB_270, { 0.0f, 0.0f, -40.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_270, { 0.0f, 0.0f, -40.0f } }, + { aFTR_SHAPE_TYPEB_90, { 0.0f, 0.0f, 0.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_90, { 0.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_90, { 0.0f, 0.0f, 0.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_90, { 0.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_270, { 0.0f, 0.0f, -40.0f } }, + }, + }, + { + { + { aFTR_SHAPE_TYPEB_180, { 0.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_0, { -40.0f, 0.0f, 0.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_0, { -40.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_0, { -40.0f, 0.0f, 0.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_0, { -40.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_180, { 0.0f, 0.0f, 0.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_180, { 0.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_180, { 0.0f, 0.0f, 0.0f } }, + }, + }, + { + { + { aFTR_SHAPE_TYPEB_270, { 0.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_270, { 0.0f, 0.0f, 0.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_270, { 0.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_90, { 0.0f, 0.0f, 40.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_90, { 0.0f, 0.0f, 40.0f } }, + { aFTR_SHAPE_TYPEB_90, { 0.0f, 0.0f, 40.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_90, { 0.0f, 0.0f, 40.0f } }, + { aFTR_SHAPE_TYPEB_270, { 0.0f, 0.0f, 0.0f } }, + }, + }, + { + { + { aFTR_SHAPE_TYPEB_180, { 40.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_0, { 0.0f, 0.0f, 0.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_0, { 0.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_0, { 0.0f, 0.0f, 0.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_0, { 0.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_180, { 40.0f, 0.0f, 0.0f } }, + }, + { + { aFTR_SHAPE_TYPEB_180, { 40.0f, 0.0f, 0.0f } }, + { aFTR_SHAPE_TYPEB_180, { 40.0f, 0.0f, 0.0f } }, + }, + }, }; -static s16 rotate_forbid_table[][2] = { - { -1, 0 }, { -1, -1 }, { 0, 0 }, { 1, 0 }, { -1, 1 }, { 0, 0 }, { -1, 0 }, { 1, 0 }, - { 0, 1 }, { -1, 0 }, { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 }, { 0, 1 }, { -1, 0 }, - { 0, -1 }, { 0, 1 }, { 0, 0 }, { -1, 1 }, { 0, -1 }, { 0, 0 }, { 1, 1 }, { 0, 1 }, +typedef struct rotate_forbid_data_s { + s_xyz left[2]; + s_xyz right[2]; +} aMR_rotate_forbid_data_c; + +static aMR_rotate_forbid_data_c rotate_forbid_table[4] = { + { + { + { -1, 0, -1 }, + { -1, 0, 0 }, + }, + { + { 1, 0, -1 }, + { 1, 0, 0 }, + }, + }, + { + { + { -1, 0, 1 }, + { 0, 0, 1 }, + }, + { + { -1, 0, -1 }, + { 0, 0, -1 }, + }, + }, + { + { + { 1, 0, 0 }, + { 1, 0, 1 }, + }, + { + { -1, 0, 0 }, + { -1, 0, 1 }, + }, + }, + { + { + { 0, 0, -1 }, + { 1, 0, -1 }, + }, + { + { 0, 0, 1 }, + { 1, 0, 1 }, + }, + }, }; -static s16 rotate_forbid_friction_table[][2] = { - { 0x0000, 0x0000 }, { 0x0001, 0x0001 }, { 0x0000, 0x0000 }, { 0x0000, 0x0000 }, { 0x0001, 0xffff }, - { 0x0000, 0x0000 }, { 0x0001, 0x0000 }, { 0x0000, 0x0000 }, { 0x0000, 0xffff }, { 0x0001, 0x0000 }, - { 0x0000, 0x0000 }, { 0x0000, 0x0001 }, { 0x0000, 0x0000 }, { 0xffff, 0xffff }, { 0x0000, 0x0000 }, - { 0x0000, 0x0000 }, { 0xffff, 0x0001 }, { 0x0000, 0x0000 }, { 0xffff, 0x0000 }, { 0x0000, 0x0000 }, - { 0x0000, 0x0001 }, { 0xffff, 0x0000 }, { 0x0000, 0x0000 }, { 0x0000, 0xffff }, +static aMR_rotate_forbid_data_c rotate_forbid_friction_table[4] = { + { + { + { 0, 0, 1 }, + { 1, 0, 0 }, + }, + { + { 0, 0, 1 }, + { -1, 0, 0 }, + }, + }, + { + { + { 1, 0, 0 }, + { 0, 0, -1 }, + }, + { + { 1, 0, 0 }, + { 0, 0, 1 }, + }, + }, + { + { + { 0, 0, -1 }, + { -1, 0, 0 }, + }, + { + { 0, 0, -1 }, + { 1, 0, 0 }, + }, + }, + { + { + { -1, 0, 0 }, + { 0, 0, 1 }, + }, + { + { -1, 0, 0 }, + { 0, 0, -1 }, + }, + }, }; typedef struct { diff --git a/src/ac_my_room_draw.c_inc b/src/ac_my_room_draw.c_inc new file mode 100644 index 00000000..c20f2cdb --- /dev/null +++ b/src/ac_my_room_draw.c_inc @@ -0,0 +1,378 @@ +static void aMR_SetKankyoMapping(FTR_ACTOR* ftr_actor, GAME_PLAY* play) { + aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_actor->name); + + switch (profile->kankyo_map) { + case aFTR_KANKYO_MAP_OPA: + Setpos_HiliteReflect_init(&ftr_actor->position, play); + break; + case aFTR_KANKYO_MAP_XLU: + Setpos_HiliteReflect_xlu_init(&ftr_actor->position, play); + break; + } +} + +static void aMR_LoadPallet(aFTR_PROFILE* profile, GAME* game) { + if (profile->palette != NULL) { + if (profile->opaque0 != NULL || profile->opaque1 != NULL || profile->rig != NULL) { + OPEN_DISP(game->graph); + + gDPPipeSync(NEXT_POLY_OPA_DISP); + gDPLoadTLUT_pal16(NEXT_POLY_OPA_DISP, 15, profile->palette); + + CLOSE_DISP(game->graph); + } + + if (profile->translucent0 != NULL || profile->translucent1 != NULL || profile->rig != NULL) { + OPEN_DISP(game->graph); + + gDPPipeSync(NEXT_POLY_XLU_DISP); + gDPLoadTLUT_pal16(NEXT_POLY_XLU_DISP, 15, profile->palette); + + CLOSE_DISP(game->graph); + } + } +} + +static void aMR_LoadTexture(aFTR_PROFILE* profile, GAME* game) { + if (profile->texture != NULL) { + if (profile->opaque0 != NULL || profile->opaque1 != NULL || profile->rig != NULL) { + OPEN_DISP(game->graph); + + gDPPipeSync(NEXT_POLY_OPA_DISP); + gDPLoadTextureBlockS(NEXT_POLY_OPA_DISP, profile->texture, G_IM_FMT_I, G_IM_SIZ_8b, 64, 64, 0, + G_TX_MIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, 7, 7, G_TX_NOLOD, G_TX_NOLOD); + + CLOSE_DISP(game->graph); + } + + if (profile->translucent0 != NULL || profile->translucent1 != NULL || profile->rig != NULL) { + OPEN_DISP(game->graph); + + gDPPipeSync(NEXT_POLY_XLU_DISP); + gDPLoadTextureBlockS(NEXT_POLY_XLU_DISP, profile->texture, G_IM_FMT_I, G_IM_SIZ_8b, 64, 64, 0, + G_TX_MIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, 7, 7, G_TX_NOLOD, G_TX_NOLOD); + + CLOSE_DISP(game->graph); + } + } +} + +static void aMR_SetLoopTextureAnime(FTR_ACTOR* ftr_actor, aFTR_PROFILE* profile, GAME* game) { + aFTR_tex_anim_c* tex_anime = profile->tex_anim; + + if (tex_anime != NULL) { + u8* tex_p = tex_anime->animation[ftr_actor->tex_animation.frame]; + + OPEN_DISP(game->graph); + + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_8, tex_p); + gSPSegment(NEXT_POLY_XLU_DISP, G_MWO_SEGMENT_8, tex_p); + + CLOSE_DISP(game->graph); + } +} + +static void aMR_DrawRegistModel(aFTR_PROFILE* profile, GAME* game) { + OPEN_DISP(game->graph); + + if (profile->opaque0 != NULL || profile->opaque1 != NULL) { + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + + if (profile->opaque0 != NULL) { + gSPDisplayList(NEXT_POLY_OPA_DISP, profile->opaque0); + } + + if (profile->opaque1 != NULL) { + gSPDisplayList(NEXT_POLY_OPA_DISP, profile->opaque1); + } + + if (profile->translucent0 != NULL || profile->translucent1 != NULL) { + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + + if (profile->translucent0 != NULL) { + gSPDisplayList(NEXT_POLY_XLU_DISP, profile->translucent0); + } + + if (profile->translucent1 != NULL) { + gSPDisplayList(NEXT_POLY_XLU_DISP, profile->translucent1); + } + + CLOSE_DISP(game->graph); +} + +static void aMR_DrawSkelShape(FTR_ACTOR* ftr_actor, aFTR_PROFILE* profile, GAME* game) { + if (profile->rig != NULL) { + cKF_SkeletonInfo_R_c* keyframe = &ftr_actor->keyframe; + int mtx_idx = game->frame_counter & 1; + Mtx* mtx = ftr_actor->skeleton_mtx[mtx_idx]; + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + CLOSE_DISP(game->graph); + + cKF_Si3_draw_R_SV(game, keyframe, mtx, NULL, NULL, NULL); + } +} + +static void aMR_DrawUniqueShape(FTR_ACTOR* ftr_actor, ACTOR* actorx, aFTR_PROFILE* profile, GAME* game) { + if (profile->vtable != NULL && profile->vtable->draw_proc != NULL) { + u8* bank = aMR_FtrNo2BankAddress(ftr_actor->name); + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + CLOSE_DISP(game->graph); + + profile->vtable->draw_proc(ftr_actor, actorx, game, bank); + } +} + +static void aMR_DrawItemOnMovingFurniture(ACTOR* actorx, FTR_ACTOR* ftr_actor, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + aMR_parent_ftr_c* parent_ftr = &my_room->parent_ftr; + + if (parent_ftr->ftrID == ftr_actor->id) { + int i; + + OPEN_DISP(game->graph); + + gDPSetTexEdgeAlpha(NEXT_POLY_OPA_DISP, 144); + gDPSetTexEdgeAlpha(NEXT_POLY_XLU_DISP, 144); + + for (i = 0; i < aMR_FIT_FTR_MAX; i++) { + if (parent_ftr->fit_ftr_table[i].exist_flag == TRUE) { + mActor_name_t item_no = parent_ftr->fit_ftr_table[i].item_no; + xyz_t* pos = &parent_ftr->fit_ftr_table[i].ut_pos; + + if (Common_Get(clip).shop_goods_clip != NULL && + Common_Get(clip).shop_goods_clip->single_draw_proc != NULL) { + Common_Get(clip).shop_goods_clip->single_draw_proc(game, item_no, pos, 0.01f, + parent_ftr->fit_ftr_table[i].angle_y + + (ftr_actor->s_angle_y - parent_ftr->angle_y), + mCoBG_LAYER1); + } + } + } + + CLOSE_DISP(game->graph); + } +} + +static int aMR_GetFitNo(ACTOR* actorx, FTR_ACTOR* ftr_actor) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + aMR_parent_ftr_c* parent_ftr = &my_room->parent_ftr; + int i; + + for (i = 0; i < aMR_FIT_FTR_MAX; i++) { + if (parent_ftr->fit_ftr_table[i].ftr_ID == ftr_actor->id) { + return i; + } + } + + return -1; +} + +static void aMR_FurnitureLightSet(FTR_ACTOR* ftr_actor, GAME_PLAY* play) { + LightsN* lights; + xyz_t center; + + aMR_GetFtrShapeCenter(¢er, ftr_actor); + lights = Global_light_read(&play->global_light, play->game.graph); + LightsN_list_check(lights, play->global_light.list, ¢er); + LightsN_disp(lights, play->game.graph); +} + +static void aMR_DrawOneFurniture(FTR_ACTOR* ftr_actor, ACTOR* actorx, GAME* game, int fit_flag) { + xyz_t ftr_scale = ftr_actor->scale; + GAME_PLAY* play = (GAME_PLAY*)game; + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + aFTR_PROFILE* profile; + + profile = aMR_GetFurnitureProfile(ftr_actor->name); + if (profile != NULL) { + f32 scale = profile->scale; + + _texture_z_light_fog_prim_xlu(game->graph); + _texture_z_light_fog_prim(game->graph); + aMR_FurnitureLightSet(ftr_actor, play); + aMR_LoadTexture(profile, game); + aMR_LoadPallet(profile, game); + aMR_SetKankyoMapping(ftr_actor, play); + + if (fit_flag == TRUE) { + aMR_parent_ftr_c* parent_ftr = &my_room->parent_ftr; + FTR_ACTOR* fit_ftr_p = &l_aMR_work.ftr_actor_list[parent_ftr->ftrID]; + int fit_no = aMR_GetFitNo(actorx, ftr_actor); + s16 angle = fit_ftr_p->s_angle_y - parent_ftr->angle_y; + aMR_fit_ftr_c* fit_ftr_info_p = &parent_ftr->fit_ftr_table[fit_no & 3]; + xyz_t* pos = &fit_ftr_info_p->pos; + + Matrix_translate(fit_ftr_p->position.x, fit_ftr_p->position.y, fit_ftr_p->position.z, 0); + Matrix_RotateY(angle, 1); + Matrix_translate(fit_ftr_p->base_position.x, fit_ftr_p->base_position.y, fit_ftr_p->base_position.z, 1); + + if (ftr_actor->name == 0x9A) { /* lower alarm clock ftr's height */ + Matrix_translate(pos->x, pos->y - 4.0f, pos->z, 1); + } else { + Matrix_translate(pos->x, pos->y, pos->z, 1); + } + + Matrix_RotateY(ftr_actor->s_angle_y, 1); + Matrix_translate(ftr_actor->base_position.x, ftr_actor->base_position.y, ftr_actor->base_position.z, 1); + + if (ftr_actor->state == aFTR_STATE_BIRTH && ftr_actor->shape_type <= aFTR_SHAPE_TYPEB_0) { + Matrix_translate(mFI_UT_WORLDSIZE_HALF_X_F, 0.0f, 0.0f, 1); + } + Matrix_scale(ftr_scale.x, ftr_scale.y, ftr_scale.z, 1); + + if (ftr_actor->state == aFTR_STATE_BIRTH && ftr_actor->shape_type <= aFTR_SHAPE_TYPEB_0) { + Matrix_translate(-mFI_UT_WORLDSIZE_HALF_X_F, 0.0f, 0.0f, 1); + } + Matrix_scale(scale, scale, scale, 1); + } else { + if (ftr_actor->name == 0x9A) { /* lower alarm clock ftr's height */ + Matrix_translate(ftr_actor->position.x, ftr_actor->position.y - 4.0f, ftr_actor->position.z, 0); + } else { + Matrix_translate(ftr_actor->position.x, ftr_actor->position.y, ftr_actor->position.z, 0); + } + + Matrix_RotateY(ftr_actor->s_angle_y, 1); + + if (Save_Get(scene_no) == SCENE_MUSEUM_ROOM_FOSSIL && + aFTR_CHECK_INTERACTION(profile->interaction_type, aFTR_INTERACTION_TYPE_FOSSIL) && + profile->shape <= aFTR_SHAPE_TYPEB_0) { + Matrix_translate(ftr_actor->base_position.x + 2.5f, ftr_actor->base_position.y, + ftr_actor->base_position.z, 1); + } else { + Matrix_translate(ftr_actor->base_position.x, ftr_actor->base_position.y, ftr_actor->base_position.z, 1); + } + + if (ftr_actor->state == aFTR_STATE_BIRTH && ftr_actor->shape_type <= aFTR_SHAPE_TYPEB_0) { + Matrix_translate(mFI_UT_WORLDSIZE_HALF_X_F, 0.0f, 0.0f, 1); + } + Matrix_scale(ftr_scale.x, ftr_scale.y, ftr_scale.z, 1); + + if (ftr_actor->state == aFTR_STATE_BIRTH && ftr_actor->shape_type <= aFTR_SHAPE_TYPEB_0) { + Matrix_translate(-mFI_UT_WORLDSIZE_HALF_X_F, 0.0f, 0.0f, 1); + } + Matrix_scale(scale, scale, scale, 1); + } + + aMR_SetLoopTextureAnime(ftr_actor, profile, game); + aMR_DrawRegistModel(profile, game); + aMR_DrawSkelShape(ftr_actor, profile, game); + aMR_DrawUniqueShape(ftr_actor, actorx, profile, game); + aMR_DrawItemOnMovingFurniture(actorx, ftr_actor, game); + } +} + +static void aMR_DrawFurniture(MY_ROOM_ACTOR* my_room, GAME_PLAY* play, int ftr_flag, u16 ftr_no) { + ACTOR* actorx = (ACTOR*)my_room; + GAME* game = (GAME*)play; + int i; + int z; + + OPEN_DISP(game->graph); + + gDPSetTexEdgeAlpha(NEXT_POLY_OPA_DISP, 127); + gDPSetTexEdgeAlpha(NEXT_POLY_XLU_DISP, 127); + + CLOSE_DISP(game->graph); + + for (z = UT_Z_NUM - 1; z >= 0; z--) { + FTR_ACTOR* ftr_actor = l_aMR_work.ftr_actor_list; + u8* used = l_aMR_work.used_list; + + for (i = 0; i < l_aMR_work.list_size; i++) { + if (*used == TRUE && mFI_POS2UT(ftr_actor->position.z) == z) { + if ((ftr_flag == FALSE && ftr_actor->name != ftr_no) || + (ftr_flag == TRUE && ftr_actor->name == ftr_no)) { + int alpha_edge; + int fit_flag = (ftr_actor->layer == mCoBG_LAYER0 || my_room->parent_ftr.ftrID == -1 || + (my_room->parent_ftr.ftrID != -1 && + my_room->parent_ftr.fit_ftr_table[0].ftr_ID != ftr_actor->id && + my_room->parent_ftr.fit_ftr_table[1].ftr_ID != ftr_actor->id && + my_room->parent_ftr.fit_ftr_table[2].ftr_ID != ftr_actor->id && + my_room->parent_ftr.fit_ftr_table[3].ftr_ID != ftr_actor->id)) == FALSE; + + alpha_edge = aMR_GetAlphaEdge(ftr_actor->name); + + OPEN_DISP(game->graph); + + gDPSetTexEdgeAlpha(NEXT_POLY_OPA_DISP, alpha_edge); + gDPSetTexEdgeAlpha(NEXT_POLY_XLU_DISP, alpha_edge); + + CLOSE_DISP(game->graph); + + if (aMR_DrawDolphinMode(ftr_actor->name)) { + OPEN_DISP(game->graph); + + gDPSetTextureAdjustMode(NEXT_POLY_OPA_DISP, G_TA_DOLPHIN); + gDPSetTextureAdjustMode(NEXT_POLY_XLU_DISP, G_TA_DOLPHIN); + + CLOSE_DISP(game->graph); + } + + aMR_DrawOneFurniture(ftr_actor, actorx, game, fit_flag); + + if (aMR_DrawDolphinMode(ftr_actor->name)) { + OPEN_DISP(game->graph); + + gDPSetTextureAdjustMode(NEXT_POLY_OPA_DISP, G_TA_N64); + gDPSetTextureAdjustMode(NEXT_POLY_XLU_DISP, G_TA_N64); + + CLOSE_DISP(game->graph); + } + } + } + + ftr_actor++; + used++; + } + } + + OPEN_DISP(game->graph); + + gDPSetTexEdgeAlpha(NEXT_POLY_OPA_DISP, 144); + gDPSetTexEdgeAlpha(NEXT_POLY_XLU_DISP, 144); + + CLOSE_DISP(game->graph); +} + +static void aMR_DrawLeaf(MY_ROOM_ACTOR* my_room, GAME_PLAY* play) { + GAME* game = (GAME*)play; + + if (my_room->leaf_info.exist_flag) { + f32 scale = my_room->leaf_info.scale; + + OPEN_DISP(game->graph); + + _texture_z_light_fog_prim(game->graph); + Matrix_translate(my_room->leaf_info.pos.x, my_room->leaf_info.pos.y, my_room->leaf_info.pos.z, 0); + Matrix_scale(scale, scale, scale, 1); + + gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(NEXT_POLY_OPA_DISP, aMR_IconNo2Gfx1(my_room->pickup_info.icon)); + gSPDisplayList(NEXT_POLY_OPA_DISP, aMR_IconNo2Gfx2(my_room->pickup_info.icon)); + + CLOSE_DISP(game->graph); + + my_room->leaf_info.exist_flag = FALSE; + } +} + +static void My_Room_Actor_draw(ACTOR* actorx, GAME* game) { + MY_ROOM_ACTOR* my_room = (MY_ROOM_ACTOR*)actorx; + GAME_PLAY* play = (GAME_PLAY*)game; + + aMR_DrawFurniture(my_room, play, FALSE, 0x41C); /* lighthouse model */ + aMR_DrawFurniture(my_room, play, TRUE, 0x41C); /* lighthouse model */ + aMR_DrawLeaf(my_room, play); +} diff --git a/src/ac_my_room_move.c_inc b/src/ac_my_room_move.c_inc index 925e47e0..5e552eda 100644 --- a/src/ac_my_room_move.c_inc +++ b/src/ac_my_room_move.c_inc @@ -5,16 +5,16 @@ typedef struct process_info_s { s16 unit_ofs[4]; } aMR_process_info_c; -static aMR_process_info_c aMR_process_typeB90 = { 2, { 0, -UT_X_NUM, 0, 0 } }; -static aMR_process_info_c aMR_process_typeB180 = { 2, { 0, -1, 0, 0 } }; -static aMR_process_info_c aMR_process_typeB270 = { 2, { 0, UT_X_NUM, 0, 0 } }; -static aMR_process_info_c aMR_process_typeB0 = { 2, { 0, 1, 0, 0 } }; -static aMR_process_info_c aMR_process_typeA = { 1, { 0, 0, 0, 0 } }; -static aMR_process_info_c aMR_process_typeC = { 4, { 0, 1, UT_X_NUM, UT_X_NUM + 1 } }; +static aMR_process_info_c aMR_poccess_typeB90 = { 2, { 0, -UT_X_NUM, 0, 0 } }; +static aMR_process_info_c aMR_poccess_typeB180 = { 2, { 0, -1, 0, 0 } }; +static aMR_process_info_c aMR_poccess_typeB270 = { 2, { 0, UT_X_NUM, 0, 0 } }; +static aMR_process_info_c aMR_poccess_typeB0 = { 2, { 0, 1, 0, 0 } }; +static aMR_process_info_c aMR_poccess_typeA = { 1, { 0, 0, 0, 0 } }; +static aMR_process_info_c aMR_poccess_typeC = { 4, { 0, 1, UT_X_NUM, UT_X_NUM + 1 } }; -static aMR_process_info_c* aMR_process_table[aFTR_SHAPE_TYPE_NUM] = { - &aMR_process_typeB90, &aMR_process_typeB180, &aMR_process_typeB270, - &aMR_process_typeB0, &aMR_process_typeA, &aMR_process_typeC, +static aMR_process_info_c* aMR_poccess_table[aFTR_SHAPE_TYPE_NUM] = { + &aMR_poccess_typeB90, &aMR_poccess_typeB180, &aMR_poccess_typeB270, + &aMR_poccess_typeB0, &aMR_poccess_typeA, &aMR_poccess_typeC, }; static int aMR_GetFurniturePoccessUnitNo(int* ut_info, int ut_x, int ut_z, u8 type) { @@ -22,7 +22,7 @@ static int aMR_GetFurniturePoccessUnitNo(int* ut_info, int ut_x, int ut_z, u8 ty int ut = ut_x + ut_z * UT_X_NUM; if (type < aFTR_SHAPE_TYPE_NUM) { - aMR_process_info_c* process_info = aMR_process_table[type]; + aMR_process_info_c* process_info = aMR_poccess_table[type]; int count = process_info->unit_count; int i; @@ -360,19 +360,19 @@ static void aMR_SetCleanUpFtrSE(xyz_t pos) { } static int aMR_GetPlayerDirect(const f32* normal_xz) { - if (normal_xz[0] > (F_PI / 4.0f)) { + if (normal_xz[0] > F_SQRT2_DIV2) { return aMR_DIRECT_LEFT; } - if (normal_xz[0] < -(F_PI / 4.0f)) { + if (normal_xz[0] < -F_SQRT2_DIV2) { return aMR_DIRECT_RIGHT; } - if (normal_xz[1] > (F_PI / 4.0f)) { + if (normal_xz[1] > F_SQRT2_DIV2) { return aMR_DIRECT_UP; } - if (normal_xz[1] < -(F_PI / 4.0f)) { + if (normal_xz[1] < -F_SQRT2_DIV2) { return aMR_DIRECT_DOWN; } @@ -397,19 +397,19 @@ static void aMR_MoveShapeCenter(FTR_ACTOR* ftr_actor) { } static int aMR_Norm2DirectName(f32* normal_xz) { - if (normal_xz[0] > (F_PI / 4.0f)) { + if (normal_xz[0] > F_SQRT2_DIV2) { return aMR_DIRECT_RIGHT; } - if (normal_xz[0] <= -(F_PI / 4.0f)) { + if (normal_xz[0] <= -F_SQRT2_DIV2) { return aMR_DIRECT_LEFT; } - if (normal_xz[1] > (F_PI / 4.0f)) { + if (normal_xz[1] > F_SQRT2_DIV2) { return aMR_DIRECT_DOWN; } - if (normal_xz[1] <= -(F_PI / 4.0f)) { + if (normal_xz[1] <= -F_SQRT2_DIV2) { return aMR_DIRECT_UP; } @@ -1332,6 +1332,8 @@ static void aMR_MngFtrContactAction(ACTOR* actorx, GAME* game) { } } +#include "../src/ac_my_room_action.c_inc" + static f32 aMR_GetDistXZ(const xyz_t* pos0, const xyz_t* pos1) { f32 diff_x = pos0->x - pos1->x; f32 diff_z = pos0->z - pos1->z; @@ -1472,14 +1474,14 @@ static int aMR_CheckPlaceSituation(int ut, int target_ut, u16 ftr_no, u16 angle_ aFTR_PROFILE* profile = aMR_GetFurnitureProfile(ftr_no); if (profile != NULL) { - u32 shape = profile->shape; + u8 shape = profile->shape; if (shape == aFTR_SHAPE_TYPEB_0) { static u8 rotate_angle_types[] = { + aFTR_SHAPE_TYPEB_0, aFTR_SHAPE_TYPEB_90, aFTR_SHAPE_TYPEB_180, aFTR_SHAPE_TYPEB_270, - aFTR_SHAPE_TYPEB_0, }; shape = rotate_angle_types[angle_idx & 3]; diff --git a/src/ac_my_room_msg_ctrl.c_inc b/src/ac_my_room_msg_ctrl.c_inc index cc04018f..9ba626d5 100644 --- a/src/ac_my_room_msg_ctrl.c_inc +++ b/src/ac_my_room_msg_ctrl.c_inc @@ -147,7 +147,6 @@ static void aMR_SetEmulatorStartMessage(ACTOR* actorx, int internal_rom) { mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); mMsg_Set_ForceNext(mMsg_Get_base_window_p()); break; - case FAMICOM_RESULT_NOFILE: default: mMsg_Set_continue_msg_num(mMsg_Get_base_window_p(), 0x3071); mMsg_Unset_LockContinue(mMsg_Get_base_window_p()); diff --git a/src/audio.c b/src/audio.c index 057d63f4..3540a8ce 100644 --- a/src/audio.c +++ b/src/audio.c @@ -171,7 +171,7 @@ extern void sAdo_SetVoiceMode(u8 mode) { Na_SetVoiceMode(mode); } -extern void sAdo_FloorTrgStart(u16 id, const xyz_t* pos) { +extern void sAdo_FloorTrgStart(u8 id, const xyz_t* pos) { u16 scalc; f32 fcalc; diff --git a/src/m_actor.c b/src/m_actor.c index 5aec1060..7841654d 100644 --- a/src/m_actor.c +++ b/src/m_actor.c @@ -608,18 +608,18 @@ extern void Actor_get_overlay_area(ACTOR_DLFTBL* dlftbl, int unused, size_t allo } } -static int Actor_data_bank_regist_check_npc(int* bank_id, ACTOR_PROFILE* profile, ACTOR_DLFTBL* dlftbl, GAME* game, +static int Actor_data_bank_regist_check_npc(int* bank_id, ACTOR_PROFILE* profile, ACTOR_DLFTBL* dlftbl, GAME_PLAY* play, mActor_name_t name_id) { return TRUE; } -static int Actor_data_bank_regist_check(int* bank_id, ACTOR_PROFILE* profile, ACTOR_DLFTBL* dlftbl, GAME* game, +static int Actor_data_bank_regist_check(int* bank_id, ACTOR_PROFILE* profile, ACTOR_DLFTBL* dlftbl, GAME_PLAY* play, mActor_name_t name_id) { int res = TRUE; if (*bank_id == -1) { if (profile->part == ACTOR_PART_NPC) { - res = Actor_data_bank_regist_check_npc(bank_id, profile, dlftbl, game, name_id); + res = Actor_data_bank_regist_check_npc(bank_id, profile, dlftbl, play, name_id); } else { // in DnM, this was another func call res = TRUE; @@ -687,31 +687,32 @@ extern void Actor_init_actor_class(ACTOR* actor, ACTOR_PROFILE* profile, ACTOR_D actor->npc_id = name_id; } -#ifndef MUST_MATCH -/* @nonmatching */ +typedef struct overlay_struct { + const char* actor_name; +} mAc_overlay_info_c; + extern ACTOR* Actor_info_make_actor(Actor_info* actor_info, GAME* game, s16 profile_no, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, s8 npc_info_idx, int data_bank_idx) { - const char* test = ""; - GAME_PLAY* play = (GAME_PLAY*)game; + GAME_PLAY* play; ACTOR* actor; ACTOR_PROFILE* profile; ACTOR_DLFTBL* dlftbl; + mAc_overlay_info_c overlay_info; /* Required to be a struct, stubbed in GC */ - test = ""; // removing this line helps a bit... - - dlftbl = &actor_dlftbls[profile_no]; - + play = (GAME_PLAY*)game; + dlftbl = actor_dlftbls + profile_no; + overlay_info.actor_name = ""; if (actor_info->total_num > mAc_MAX_ACTORS) { return NULL; } profile = dlftbl->profile; - if (Actor_data_bank_regist_check(&data_bank_idx, profile, dlftbl, game, name_id) == FALSE) { + if (Actor_data_bank_regist_check(&data_bank_idx, profile, dlftbl, play, name_id) == FALSE) { return NULL; } - if (Actor_malloc_actor_class(&actor, profile, dlftbl, test, name_id) == FALSE) { + if (Actor_malloc_actor_class(&actor, profile, dlftbl, overlay_info.actor_name, name_id) == FALSE) { return NULL; } @@ -720,18 +721,10 @@ extern ACTOR* Actor_info_make_actor(Actor_info* actor_info, GAME* game, s16 prof move_actor_list_idx, name_id, arg); Actor_info_part_new(actor_info, actor, profile->part); mNpc_SetNpcinfo(actor, npc_info_idx); - Actor_ct(actor, (GAME*)play); + Actor_ct(actor, game); return actor; } -#else -extern asm ACTOR* Actor_info_make_actor(Actor_info* actor_info, GAME* game, s16 profile_no, f32 x, f32 y, f32 z, - s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, - s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, s8 npc_info_idx, - int data_bank_idx) { -#include "asm/80375830.s" -} -#endif extern ACTOR* Actor_info_make_child_actor(Actor_info* actor_info, ACTOR* parent_actor, GAME* game, s16 profile, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s16 move_actor_list_idx,