diff --git a/common.py b/common.py index 5470c01c..1803ac9c 100644 --- a/common.py +++ b/common.py @@ -222,6 +222,7 @@ CPP = os.path.join(DEVKITPPC, "bin", "powerpc-eabi-cpp") # Asset Converters VTXDIS = f"{PYTHON} {TOOLS}/converters/vtxdis.py" +PAL16DIS = f"{PYTHON} {TOOLS}/converters/pal16dis.py" ICONV = f"{PYTHON} tools/sjis.py" # TODO: get actual iconv working(?) diff --git a/config/assets.yml b/config/assets.yml index eac3e74e..bee9e0d9 100644 --- a/config/assets.yml +++ b/config/assets.yml @@ -145,3 +145,186 @@ config/rel.yml: type: vtx g_wipe1_txt: addrs: [0x80652C60, 0x80653460] + mFM_beach_pal_0: + addrs: [0x80C59CA8, 0x80C59CC8] + type: pal16 + mFM_beach_pal_1: + addrs: [0x80C59CC8, 0x80C59CE8] + type: pal16 + mFM_beach_pal_2: + addrs: [0x80C59CE8, 0x80C59D08] + type: pal16 + mFM_beach_pal_3: + addrs: [0x80C59D08, 0x80C59D28] + type: pal16 + mFM_beach_pal_4: + addrs: [0x80C59D28, 0x80C59D48] + type: pal16 + mFM_beach_pal_5: + addrs: [0x80C59D48, 0x80C59D68] + type: pal16 + mFM_beach_pal_6: + addrs: [0x80C59D68, 0x80C59D88] + type: pal16 + mFM_beach_pal_7: + addrs: [0x80C59D88, 0x80C59DA8] + type: pal16 + mFM_beach_pal_8: + addrs: [0x80C59DA8, 0x80C59DC8] + type: pal16 + mFM_beach_pal_9: + addrs: [0x80C59DC8, 0x80C59DE8] + type: pal16 + mFM_beach_pal_10: + addrs: [0x80C59DE8, 0x80C59E08] + type: pal16 + mFM_beach_pal_11: + addrs: [0x80C59E08, 0x80C59E28] + type: pal16 + mFM_bush_pal_0: + addrs: [0x80C78680, 0x80C786A0] + type: pal16 + mFM_bush_pal_1: + addrs: [0x80C786A0, 0x80C786C0] + type: pal16 + mFM_bush_pal_2: + addrs: [0x80C786C0, 0x80C786E0] + type: pal16 + mFM_bush_pal_3: + addrs: [0x80C786E0, 0x80C78700] + type: pal16 + mFM_bush_pal_4: + addrs: [0x80C78700, 0x80C78720] + type: pal16 + mFM_bush_pal_5: + addrs: [0x80C78720, 0x80C78740] + type: pal16 + mFM_bush_pal_6: + addrs: [0x80C78740, 0x80C78760] + type: pal16 + mFM_bush_pal_7: + addrs: [0x80C78760, 0x80C78780] + type: pal16 + mFM_bush_pal_8: + addrs: [0x80C78780, 0x80C787A0] + type: pal16 + mFM_bush_pal_9: + addrs: [0x80C787A0, 0x80C787C0] + type: pal16 + mFM_bush_pal_10: + addrs: [0x80C787C0, 0x80C787E0] + type: pal16 + mFM_bush_pal_11: + addrs: [0x80C787E0, 0x80C78800] + type: pal16 + mFM_cliff_pal_0: + addrs: [0x80C78988, 0x80C789A8] + type: pal16 + mFM_cliff_pal_1: + addrs: [0x80C789A8, 0x80C789C8] + type: pal16 + mFM_cliff_pal_2: + addrs: [0x80C789C8, 0x80C789E8] + type: pal16 + mFM_cliff_pal_3: + addrs: [0x80C789E8, 0x80C78A08] + type: pal16 + mFM_cliff_pal_4: + addrs: [0x80C78A08, 0x80C78A28] + type: pal16 + mFM_cliff_pal_5: + addrs: [0x80C78A28, 0x80C78A48] + type: pal16 + mFM_cliff_pal_6: + addrs: [0x80C78A48, 0x80C78A68] + type: pal16 + mFM_cliff_pal_7: + addrs: [0x80C78A68, 0x80C78A88] + type: pal16 + mFM_cliff_pal_8: + addrs: [0x80C78A88, 0x80C78AA8] + type: pal16 + mFM_cliff_pal_9: + addrs: [0x80C78AA8, 0x80C78AC8] + type: pal16 + mFM_cliff_pal_10: + addrs: [0x80C78AC8, 0x80C78AE8] + type: pal16 + mFM_cliff_pal_11: + addrs: [0x80C78AE8, 0x80C78B08] + type: pal16 + mFM_earth_pal_0: + addrs: [0x80C90100, 0x80C90120] + type: pal16 + mFM_earth_pal_1: + addrs: [0x80C90120, 0x80C90140] + type: pal16 + mFM_earth_pal_2: + addrs: [0x80C90140, 0x80C90160] + type: pal16 + mFM_earth_pal_3: + addrs: [0x80C90160, 0x80C90180] + type: pal16 + mFM_earth_pal_4: + addrs: [0x80C90180, 0x80C901A0] + type: pal16 + mFM_earth_pal_5: + addrs: [0x80C901A0, 0x80C901C0] + type: pal16 + mFM_earth_pal_6: + addrs: [0x80C901C0, 0x80C901E0] + type: pal16 + mFM_earth_pal_7: + addrs: [0x80C901E0, 0x80C90200] + type: pal16 + mFM_earth_pal_8: + addrs: [0x80C90200, 0x80C90220] + type: pal16 + mFM_earth_pal_9: + addrs: [0x80C90220, 0x80C90240] + type: pal16 + mFM_earth_pal_10: + addrs: [0x80C90240, 0x80C90260] + type: pal16 + mFM_earth_pal_11: + addrs: [0x80C90260, 0x80C90280] + type: pal16 + mFM_rail_pal_0: + addrs: [0x80F8C2C8, 0x80F8C2E8] + type: pal16 + mFM_rail_pal_1: + addrs: [0x80F8C2E8, 0x80F8C308] + type: pal16 + mFM_rail_pal_2: + addrs: [0x80F8C308, 0x80F8C328] + type: pal16 + mFM_rail_pal_3: + addrs: [0x80F8C328, 0x80F8C348] + type: pal16 + mFM_rail_pal_4: + addrs: [0x80F8C348, 0x80F8C368] + type: pal16 + mFM_rail_pal_5: + addrs: [0x80F8C368, 0x80F8C388] + type: pal16 + mFM_rail_pal_6: + addrs: [0x80F8C388, 0x80F8C3A8] + type: pal16 + mFM_rail_pal_7: + addrs: [0x80F8C3A8, 0x80F8C3C8] + type: pal16 + mFM_rail_pal_8: + addrs: [0x80F8C3C8, 0x80F8C3E8] + type: pal16 + mFM_rail_pal_9: + addrs: [0x80F8C3E8, 0x80F8C408] + type: pal16 + mFM_rail_pal_10: + addrs: [0x80F8C408, 0x80F8C428] + type: pal16 + mFM_rail_pal_11: + addrs: [0x80F8C428, 0x80F8C448] + type: pal16 + mFM_rail_pal_12: + addrs: [0x80F8C448, 0x80F8C468] + type: pal16 diff --git a/config/rel_disasm_overrides.yml b/config/rel_disasm_overrides.yml index 400efdc4..c4f9e8af 100644 --- a/config/rel_disasm_overrides.yml +++ b/config/rel_disasm_overrides.yml @@ -7,3 +7,5 @@ symbol_aligns: 0x81361820 : 0x20 # S_back_title_timer 0x806D4D40: 32 # align fFTR_myhome_off_pal_table to 32 bytes 0x8064F860: 32 # data right after m_camera2 TU + 0x80C78B20: 32 # mFM_grd_s_cliff_tex + 0x80F8C460: 32 # mFM_grd_s_rail_tex \ No newline at end of file diff --git a/config/rel_slices.yml b/config/rel_slices.yml index bfe92bd4..3222240e 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -34,6 +34,8 @@ m_banti.c: .rodata: [0x80641388, 0x806413E0] .data: [0x8064F548, 0x8064F658] .bss: [0x8125A830, 0x8125AC80] +m_bg_tex.c: + .bss: [0x8125AC80, 0x81263080] m_bg_item.c: .text: [0x80378858, 0x803789F8] .rodata: [0x806413E0, 0x806413F0] @@ -78,6 +80,11 @@ m_fbdemo_fade.c: .text: [0x803A12F8, 0x803A1508] .rodata: [0x80641FC0, 0x80641FD8] .data: [0x80653558, 0x806535A0] +m_field_make.c: + .text: [0x803A22C4, 0x803A4D68] + .rodata: [0x80641FE0, 0x80642008] + .data: [0x80653620, 0x80653E28] + .bss: [0x812957A0, 0x81295A88] m_fishrecord.c: .text: [0x803AB698, 0x803AC5C8] .rodata: [0x80642068, 0x80642080] @@ -449,3 +456,13 @@ data/titledemo/pact3.c: .data: [0x80C43D18, 0x80C44B98] data/titledemo/pact4.c: .data: [0x80C44B98, 0x80C45A08] +data/field/bg/beach_pal.c: + .data: [0x80C59CA8, 0x80C59E28] +data/field/bg/bush_pal.c: + .data: [0x80C78680, 0x80C78800] +data/field/bg/cliff_pal.c: + .data: [0x80C78988, 0x80C78B20] +data/field/bg/earth_pal.c: + .data: [0x80C90100, 0x80C90280] +data/field/bg/rail_pal.c: + .data: [0x80F8C2C8, 0x80F8C460] \ No newline at end of file diff --git a/configure.py b/configure.py index 6e80bda9..96be5022 100644 --- a/configure.py +++ b/configure.py @@ -90,6 +90,7 @@ n.variable("cpp", c.CPP) n.variable("iconv", c.ICONV) n.variable("forcefilesgen", c.FORCEFILESGEN) n.variable("vtxdis", c.VTXDIS) +n.variable("pal16dis", c.PAL16DIS) n.newline() ############## @@ -243,6 +244,12 @@ n.rule( description = "vtxdis.py $in $out" ) +n.rule( + "pal16dis", + command = "$pal16dis $in $out", + description = "pal16dis.py $in $out" +) + ########## # Assets # ########## @@ -490,6 +497,12 @@ class AssetInclude(GeneratedInclude): rule="vtxdis", inputs=inc.asset_path ) + elif inc.asset.convtype == "pal16": + n.build( + inc.path, + rule="pal16dis", + inputs=inc.asset_path + ) else: n.build( inc.path, diff --git a/include/m_bg_tex.h b/include/m_bg_tex.h new file mode 100644 index 00000000..77044443 --- /dev/null +++ b/include/m_bg_tex.h @@ -0,0 +1,52 @@ +#ifndef M_BG_TEX_H +#define M_BG_TEX_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct bg_tex_obj_s { + void* data; + size_t size; +} mBGTex_obj_c; + +extern u8 sprashC_tex_dummy[]; +extern u8 sprashA_tex_dummy[]; +extern u8 wave3_tex_dummy[]; +extern u8 wave2_tex_dummy[]; +extern u8 wave1_tex_dummy[]; +extern u8 sand_tex_dummy[]; +extern u8 beach_pal_dummy2[]; +extern u8 beach2_tex_dummy2[]; +extern u8 beach1_tex_dummy2[]; +extern u8 beach_tex_dummy[]; +extern u8 tunnel_tex_dummy[]; +extern u8 rail_pal_dummy[]; +extern u8 bush_pal_dummy[]; +extern u8 cliff_pal_dummy[]; +extern u8 earth_pal_dummy[]; +extern u8 station_pal_dummy[]; +extern u8 bridge_2_pal_dummy[]; +extern u8 bridge_1_pal_dummy[]; +extern u8 tekkyo_tex_dummy[]; +extern u8 bridge_2_tex_dummy[]; +extern u8 bridge_1_tex_dummy[]; +extern u8 water_2_tex_dummy[]; +extern u8 water_1_tex_dummy[]; +extern u8 river_tex_dummy[]; +extern u8 stone_tex_dummy[]; +extern u8 station_tex_dummy[]; +extern u8 rail_tex_dummy[]; +extern u8 grass_tex_dummy[]; +extern u8 bush_b_tex_dummy[]; +extern u8 bush_a_tex_dummy[]; +extern u8 cliff_tex_dummy[]; +extern u8 earth_tex_dummy[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_bgm.h b/include/m_bgm.h index bb33f220..53cd6590 100644 --- a/include/m_bgm.h +++ b/include/m_bgm.h @@ -14,6 +14,7 @@ extern void mBGMPsComp_scene_mode(int scene_mode); extern void mBGMPsComp_make_ps_wipe(u16 ps_wipe); extern void mBGMPsComp_delete_ps_demo(u8 bgm_num, u16 stop_type); extern void mBGMPsComp_make_ps_demo(u8 bgm_no, u16 stop_type); +extern void mBGMPsComp_museum_status(int museum_status); #ifdef __cplusplus } diff --git a/include/m_collision_bg.h b/include/m_collision_bg.h index 50cd14df..0a8689b4 100644 --- a/include/m_collision_bg.h +++ b/include/m_collision_bg.h @@ -119,6 +119,7 @@ extern int mCoBG_BnumUnum2HoleNumber(int block_x, int block_z, int ut_x, int ut_ extern u32 mCoBG_UtNum2BgAttr(int ut_x, int ut_z); extern f32 mCoBG_UtNum2UtCenterY(int ut_x, int ut_z); extern int mCoBG_CheckCliffAttr(u32 attribute); +extern int mCoBG_Change2PoorAttr(mCoBG_Collision_u* col); extern void mCoBG_InitMoveBgData(); extern void mCoBG_InitBlockBgCheckMode(); diff --git a/include/m_common_data.h b/include/m_common_data.h index 27f97650..4dfabb11 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -209,13 +209,16 @@ typedef struct common_data_s { /* 0x02852E */ s16 goods_power; /* 0x028530 */ Door_data_c door_data; /* misc door data */ /* 0x028544 */ Door_data_c structure_exit_door_data; /* door data for when exiting a building */ - /* 0x028558 */ u8 tmp1[0x028592 - 0x028558]; + /* 0x028558 */ u8 tmp1[0x028591 - 0x028558]; + /* 0x028591 */ u8 floor_idx; /* 0x028592 */ s16 demo_profiles[mDemo_CLIP_TYPE_NUM - 1]; /* 0x028596 */ u8 _28596[0x285C0 - 0x28596]; /* 0x0285C0 */ s8 player_decoy_flag; - /* 0x0285C1 */ u8 _285C1[0x0285C6 - 0x0285C1]; + /* 0x0285C1 */ u8 _285C1; + /* 0x0285C2 */ u8 make_npc2_actor; + /* 0x0285C3 */ u8 _285C3[0x0285C6 - 0x0285C3]; /* 0x0285C6 */ u8 event_id; - /* 0x0285C7 */ u8 _285C3[0x0287F8 - 0x0285C7]; + /* 0x0285C7 */ u8 _285C7[0x0287F8 - 0x0285C7]; /* 0x0287F8 */ s8 current_famicom_rom; /* 0x0287F9 */ s8 famicom_287F9; /* 0x0287FA */ u8 _287FA[0x28838 - 0x0287FA]; diff --git a/include/m_event.h b/include/m_event.h index 07768482..200e0763 100644 --- a/include/m_event.h +++ b/include/m_event.h @@ -244,6 +244,7 @@ extern int mEv_ArbeitPlayer(u32 player_no); extern u16 mEv_get_special_event_type(); extern int mEv_ClearEventSaveInfo(mEv_event_save_c* event_save_data); extern void mEv_EventON(u32 event_kind); +extern int mEv_CheckGateway(); extern int mEv_weekday2day(lbRTC_month_t month, int week_type, lbRTC_weekday_t weekday); extern void mEv_ClearEventInfo(); diff --git a/include/m_field_info.h b/include/m_field_info.h index 704edc87..0ba78962 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -5,7 +5,7 @@ #include "libu64/gfxprint.h" #include "m_lib.h" #include "m_collision_bg.h" - +#include "m_field_make.h" #ifdef __cplusplus extern "C" { @@ -18,6 +18,12 @@ extern "C" { #define mFI_UT_WORLDSIZE_X_F ((f32)mFI_UT_WORLDSIZE_X) #define mFI_UT_WORLDSIZE_Z_F ((f32)mFI_UT_WORLDSIZE_Z) +#define mFI_UT_WORLDSIZE_HALF_X_F (mFI_UT_WORLDSIZE_X_F / 2.0f) +#define mFI_UT_WORLDSIZE_HALF_Z_F (mFI_UT_WORLDSIZE_X_F / 2.0f) + +#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_ROW_TO_CHARSTR(row) ((row) + 'A') #define mFI_COL_TO_CHARSTR(col) ((col) + '0') @@ -164,6 +170,16 @@ extern f32 mFI_GetBlockWidth(); extern f32 mFI_GetBlockHeight(); extern int mFI_Wpos2BkandUtNuminBlock(int* block_x, int* block_z, int* ut_x, int* ut_z, xyz_t wpos); extern int mFI_GetItemNumOnBlockInField(int block_x, int block_z, mActor_name_t start_item, mActor_name_t end_item); +extern int mFI_CheckShopFieldName(mActor_name_t field_name); +extern int mFI_GetMoveActorListIdx(mFM_move_actor_c* move_actor_list, int list_size, mActor_name_t name); +extern int mFI_GetNowPlayerHouseFloorNo(); +extern int mFI_BlockUtNumtoFGSet(mActor_name_t item, int bx, int bz, int ut_x, int ut_z); +extern void mFI_InitMoveActorBitData(); +extern void mFI_ClearColKeep(); +extern void mFI_InitAreaInfo(); +extern void mFI_InitRegisterBgInfo(); +extern mFM_block_info_c* mFI_GetBlockTopP(); +extern int mFI_GetBlockNum(int block_x, int block_z); extern void mFI_PrintNowBGNum(gfxprint_t* gfxprint); extern void mFI_PrintFgAttr(gfxprint_t* gfxprint); diff --git a/include/m_field_make.h b/include/m_field_make.h index 5e696b79..2e1fd4b0 100644 --- a/include/m_field_make.h +++ b/include/m_field_make.h @@ -5,7 +5,9 @@ #include "m_actor_type.h" #include "libforest/gbi_extensions.h" #include "game_h.h" -#include "m_play.h" +#include "m_play_h.h" +#include "evw_anime.h" +#include "m_collision_bg.h" #ifdef __cplusplus extern "C" { @@ -34,6 +36,21 @@ extern "C" { #define BLOCKXZ_2_BLOCKIDX(x, z) ((z) * BLOCK_X_NUM + (x)) #define mFM_VISIBLE_BLOCK_NUM 4 /* number of visible blocks (nearest to the Player) */ +#define mFM_SOUND_SOURCE_NUM 6 +#define mFM_MOVE_ACTOR_NUM 16 +#define mFM_HANIWA_STEP_NUM 4 + +#define mFM_BG_ID_MAX 293 + +#define mFM_FG_START 0 +#define mFM_FG_NUM 416 +#define mFM_FG_NPC_START mFM_FG_NUM +#define mFM_FG_NPC_NUM 536 +#define mFM_FG_ID_MAX (mFM_FG_NUM + mFM_FG_NPC_NUM) +#define mFM_FG2_ID_MAX 743 + +#define mFM_FIELD_PAL_NUM 12 +#define mFM_FIELD_TEX_NUM 27 /* sizeof(mFM_combination_c) == 2 */ typedef struct block_combination_s { @@ -73,30 +90,144 @@ typedef struct field_pal_s { u16* golden_tree_pal; } mFM_field_pal_c; +typedef struct field_bg_sound_source_s { + s16 kind; + xyz_t pos; +} mFM_bg_sound_source_c; + typedef struct field_bg_info_s { mFM_combination_c bg_id; - Gfx* oapque_gfx; + Gfx* opaque_gfx; Gfx* translucent_gfx; - + EVW_ANIME_DATA* animation; + s8 animation_count; + u8 block_type; + u32 block_kind; + int _18; + int _1C; + mCoBG_Collision_u collision[UT_Z_NUM][UT_X_NUM]; + u8 keep_h[UT_Z_NUM][UT_X_NUM]; // base height? + mFM_bg_sound_source_c sound_source[mFM_SOUND_SOURCE_NUM]; } mFM_bg_info_c; +typedef struct field_fg_move_actor_s { + mActor_name_t name_id; + s8 ut_x; + s8 ut_z; + s8 npc_info_idx; + s16 arg; +} mFM_move_actor_c; + +typedef struct field_fg_move_actor_data_s { + mActor_name_t name_id; + int block_x; + int block_z; + u8 ut_x; + u8 ut_z; + s8 npc_info_idx; + s16 arg; + u32 desired_block_kind; +} mFM_move_actor_data_c; + +typedef struct field_fg_info_s { + mActor_name_t fg_id; + mActor_name_t* items_p; + u16* deposit_p; + mFM_move_actor_c move_actors[mFM_MOVE_ACTOR_NUM]; + u16 move_actor_bit_data; + u8 haniwa_step[mFM_HANIWA_STEP_NUM]; +} mFM_fg_info_c; + +typedef struct field_block_info_s { + mFM_bg_info_c bg_info; + mFM_fg_info_c fg_info; +} mFM_block_info_c; + +typedef struct field_bg_sound_source_data_s { + s16 kind; + u8 ut_x; + u8 ut_z; +} mFM_bg_sound_source_data_c; + +typedef struct field_bg_data_s { + mActor_name_t bg_id; + Gfx* opaque_gfx; + Gfx* translucent_gfx; + EVW_ANIME_DATA* animation; + s8 animation_count; + u32 _14; + u32 _18; + mCoBG_Collision_u collision[UT_Z_NUM][UT_X_NUM]; + mFM_bg_sound_source_data_c sound_source[mFM_SOUND_SOURCE_NUM]; +} mFM_bg_data_c; + +typedef struct field_fg_data_s { + mActor_name_t fg_id; + mActor_name_t items[UT_Z_NUM][UT_X_NUM]; + u8 haniwa_step[mFM_HANIWA_STEP_NUM]; +} mFM_fg_data_c; + +typedef struct field_data_s { + mActor_name_t field_name; + u8 block_x_max; + u8 block_z_max; + mFM_combination_c combi[BLOCK_TOTAL_NUM]; + mFM_move_actor_data_c* move_actor_data; + u32 _94; + u32 _98; + u32 _9C; + u32 _A0; +} mFM_field_data_c; + typedef struct field_info_s { mActor_name_t field_id; u32 _04; // only set, never read? mFM_field_draw_info_c bg_draw_info[mFM_VISIBLE_BLOCK_NUM]; u8* bg_display_list_p[mFM_VISIBLE_BLOCK_NUM]; mFM_field_pal_c field_palette; - + mFM_block_info_c* block_info; + mActor_name_t** fg2_p; + int last_bg_idx[mFM_VISIBLE_BLOCK_NUM]; + u16 bg_max; + u8 bg_num; + u8 update_fg; + u8 born_item; + u8 born_actor; + u8 block_x_max; + u8 block_z_max; } mFM_fdinfo_c; +enum { + mFM_BG_TEX_TRIANGLE, + mFM_BG_TEX_SQUARE, + mFM_BG_TEX_CIRCLE, + + mFM_BG_TEX_NUM +}; + extern u8* g_block_type_p; extern int* g_block_kind_p; -extern void mFM_FieldInit(GAME_PLAY*); -extern void mFM_Field_dt(); +extern mFM_fdinfo_c* g_fdinfo; +extern int l_bg_disp_num; +extern int l_bg_disp_size; + +extern mFM_bg_data_c data_bgd[]; +extern int data_bgd_number; + +extern void mFM_GetPolicePos(int* bx, int* bz, int* ut_x, int* ut_z); extern void mFM_DecideBgTexIdx(u8* bg_tex_idx); +extern void mFM_SetFieldInitData(int bg_disp_num, int bg_disp_size); +extern void mFM_FieldInit(GAME_PLAY* play); +extern void mFM_Field_dt(); +extern void mFM_SetBlockKindLoadCombi(); extern void mFM_InitFgCombiSaveData(GAME* game); -extern mActor_name_t mFM_GetReserveName(int block_x, int block_z); +extern void mFM_RenewalReserve(); +extern mActor_name_t mFM_GetReseveName(int bx, int bz); +extern void mFM_toSummer(); +extern void mFM_returnSeason(); +extern void mFM_RestoreIslandBG(int* island_x_blocks, int bx_num); +extern void mFM_SetIslandNpcRoomData(GAME* game, int malloc_flag); #ifdef __cplusplus } diff --git a/include/m_name_table.h b/include/m_name_table.h index 279e6049..3766a25b 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -1306,6 +1306,8 @@ extern mActor_name_t bg_item_fg_sub_tree_grow(mActor_name_t tree, int past_days, #define RSV_WALL_NO 0xFFFE /* interior wall item, no collision */ #define RSV_NO 0xFFFF /* reserved space, can't interact but no collision */ +#define mNT_IS_RESERVE(n) ((n) >= SIGN00 && (n) <= SIGN20) + #ifdef __cplusplus } #endif diff --git a/include/m_npc.h b/include/m_npc.h index 0dd5f101..892ae82e 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -12,6 +12,7 @@ #include "m_quest.h" #include "m_lib.h" #include "m_private_h.h" +#include "m_field_make.h" #ifdef __cplusplus extern "C" { @@ -232,6 +233,13 @@ extern u8 mNpc_CheckNormalMail_length(int* len, u8* body); extern mActor_name_t mNpc_GetNpcFurniture(AnmPersonalID_c* pid); extern void mNpc_GetNpcWorldNameTableNo(u8* buf, mActor_name_t name_id); extern void mNpc_GetRandomAnimalName(u8* buf); +extern int mNpc_GetIslandRoomFtrNum(); +extern mActor_name_t* mNpc_GetIslandRoomP(mActor_name_t npc_name); +extern void mNpc_ChangeIslandRoom(mActor_name_t* items); +extern void mNpc_SetNpcFurnitureRandom(mFM_fg_data_c** fg_data_list, int fg_name_start); +extern void mNpc_SetNpcHomeYpos(); +extern void mNpc_SendRegisteredGoodbyMail(); +extern void mNpc_IslandNpcRoomDataSet(mFM_fg_data_c** sorted_fg_data_list, int fg_name_start); extern void mNpc_PrintRemoveInfo(gfxprint_t* gfxprint); extern void mNpc_PrintFriendship_fdebug(gfxprint_t* gfxprint); diff --git a/include/m_random_field.h b/include/m_random_field.h index 6ac1fd66..16fc7d0f 100644 --- a/include/m_random_field.h +++ b/include/m_random_field.h @@ -4,6 +4,7 @@ #include "types.h" #include "m_random_field_h.h" #include "m_field_make.h" +#include "game_h.h" #ifdef __cplusplus extern "C" { @@ -58,6 +59,7 @@ typedef struct gate_s { int ut1; } mRF_gate_c; +extern void mRF_MakeRandomField(mFM_combination_c* combi_table, mFM_combo_info_c* combo_info, int combo_count, GAME* game); extern u32 mRF_Type2BlockInfo(u8 type); extern int mRF_SearchPond(int* ut_x, int* ut_z, int block_x, int block_z); extern mRF_gate_c* mRF_BlockTypeDirect2GateData(int* gate_count, u8 block_type, int direct); diff --git a/include/m_room_type.h b/include/m_room_type.h index fb59c9e4..86d81b25 100644 --- a/include/m_room_type.h +++ b/include/m_room_type.h @@ -123,5 +123,7 @@ extern int mRmTp_PleaseDrawLightSwitch(); extern mActor_name_t mRmTp_Item1ItemNo2FtrItemNo_AtPlayerRoom(mActor_name_t item_no, int flag); extern void mRmTp_SetDefaultLightSwitchData(int state); extern int mRmTp_GetEntranceBasePosition(xyz_t* pos); +extern mActor_name_t mRmTp_GetPlayerRoomCollisionIdx(mActor_name_t field_name, mActor_name_t bg_name); +extern u8 mRmTp_GetFloorIdx(); #endif \ No newline at end of file diff --git a/include/m_scene_table.h b/include/m_scene_table.h index 0d696412..b6136b11 100644 --- a/include/m_scene_table.h +++ b/include/m_scene_table.h @@ -79,6 +79,14 @@ enum scene_table { 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_MUSEUM_ROOM(scene) \ + ((scene) >= SCENE_MUSEUM_ENTRANCE && (scene) <= SCENE_MUSEUM_ROOM_FISH) extern Scene_status_c scene_data_status[SCENE_NUM]; diff --git a/include/m_shop.h b/include/m_shop.h index 98423cea..baefb514 100644 --- a/include/m_shop.h +++ b/include/m_shop.h @@ -140,6 +140,8 @@ extern int mSP_SearchItemCategoryPriority(mActor_name_t item_no, int category, i extern mActor_name_t mSP_RandomOneFossilSelect(int multi_fossil); extern mActor_name_t mSP_RandomHaniwaSelect(mActor_name_t* item_buf, int num); extern mActor_name_t mSP_SelectFishginPresent(int player_no); +extern mActor_name_t mSP_GetNowShopFgNum(); +extern mActor_name_t mSP_GetNowShopBgNum(); extern void mItemDebug_ItemDebugMain(); extern void mItemDebug_ItemDebugDraw(gfxprint_t* gfxprint); diff --git a/include/m_soncho.h b/include/m_soncho.h new file mode 100644 index 00000000..92e039d9 --- /dev/null +++ b/include/m_soncho.h @@ -0,0 +1,17 @@ +#ifndef M_SONCHO_H +#define M_SONCHO_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern u32 mSC_check_ArbeitPlayer(); +extern int mSC_LightHouse_travel_check(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rel/data/field/bg/beach_pal.c b/rel/data/field/bg/beach_pal.c new file mode 100644 index 00000000..8fecd60a --- /dev/null +++ b/rel/data/field/bg/beach_pal.c @@ -0,0 +1,40 @@ +#include "m_field_make.h" + +extern u16 mFM_beach_pal[mFM_FIELD_PAL_NUM][16] = { + { + #include "assets/mFM_beach_pal_0.inc" + }, + { + #include "assets/mFM_beach_pal_1.inc" + }, + { + #include "assets/mFM_beach_pal_2.inc" + }, + { + #include "assets/mFM_beach_pal_3.inc" + }, + { + #include "assets/mFM_beach_pal_4.inc" + }, + { + #include "assets/mFM_beach_pal_5.inc" + }, + { + #include "assets/mFM_beach_pal_6.inc" + }, + { + #include "assets/mFM_beach_pal_7.inc" + }, + { + #include "assets/mFM_beach_pal_8.inc" + }, + { + #include "assets/mFM_beach_pal_9.inc" + }, + { + #include "assets/mFM_beach_pal_10.inc" + }, + { + #include "assets/mFM_beach_pal_11.inc" + } +}; diff --git a/rel/data/field/bg/bush_pal.c b/rel/data/field/bg/bush_pal.c new file mode 100644 index 00000000..ffc0dcc5 --- /dev/null +++ b/rel/data/field/bg/bush_pal.c @@ -0,0 +1,40 @@ +#include "m_field_make.h" + +extern u16 mFM_bush_pal[mFM_FIELD_PAL_NUM][16] = { + { + #include "assets/mFM_bush_pal_0.inc" + }, + { + #include "assets/mFM_bush_pal_1.inc" + }, + { + #include "assets/mFM_bush_pal_2.inc" + }, + { + #include "assets/mFM_bush_pal_3.inc" + }, + { + #include "assets/mFM_bush_pal_4.inc" + }, + { + #include "assets/mFM_bush_pal_5.inc" + }, + { + #include "assets/mFM_bush_pal_6.inc" + }, + { + #include "assets/mFM_bush_pal_7.inc" + }, + { + #include "assets/mFM_bush_pal_8.inc" + }, + { + #include "assets/mFM_bush_pal_9.inc" + }, + { + #include "assets/mFM_bush_pal_10.inc" + }, + { + #include "assets/mFM_bush_pal_11.inc" + } +}; diff --git a/rel/data/field/bg/cliff_pal.c b/rel/data/field/bg/cliff_pal.c new file mode 100644 index 00000000..6cc7da93 --- /dev/null +++ b/rel/data/field/bg/cliff_pal.c @@ -0,0 +1,40 @@ +#include "m_field_make.h" + +extern u16 mFM_cliff_pal[mFM_FIELD_PAL_NUM][16] = { + { + #include "assets/mFM_cliff_pal_0.inc" + }, + { + #include "assets/mFM_cliff_pal_1.inc" + }, + { + #include "assets/mFM_cliff_pal_2.inc" + }, + { + #include "assets/mFM_cliff_pal_3.inc" + }, + { + #include "assets/mFM_cliff_pal_4.inc" + }, + { + #include "assets/mFM_cliff_pal_5.inc" + }, + { + #include "assets/mFM_cliff_pal_6.inc" + }, + { + #include "assets/mFM_cliff_pal_7.inc" + }, + { + #include "assets/mFM_cliff_pal_8.inc" + }, + { + #include "assets/mFM_cliff_pal_9.inc" + }, + { + #include "assets/mFM_cliff_pal_10.inc" + }, + { + #include "assets/mFM_cliff_pal_11.inc" + } +}; diff --git a/rel/data/field/bg/earth_pal.c b/rel/data/field/bg/earth_pal.c new file mode 100644 index 00000000..5851bfea --- /dev/null +++ b/rel/data/field/bg/earth_pal.c @@ -0,0 +1,40 @@ +#include "m_field_make.h" + +extern u16 mFM_earth_pal[mFM_FIELD_PAL_NUM][16] = { + { + #include "assets/mFM_earth_pal_0.inc" + }, + { + #include "assets/mFM_earth_pal_1.inc" + }, + { + #include "assets/mFM_earth_pal_2.inc" + }, + { + #include "assets/mFM_earth_pal_3.inc" + }, + { + #include "assets/mFM_earth_pal_4.inc" + }, + { + #include "assets/mFM_earth_pal_5.inc" + }, + { + #include "assets/mFM_earth_pal_6.inc" + }, + { + #include "assets/mFM_earth_pal_7.inc" + }, + { + #include "assets/mFM_earth_pal_8.inc" + }, + { + #include "assets/mFM_earth_pal_9.inc" + }, + { + #include "assets/mFM_earth_pal_10.inc" + }, + { + #include "assets/mFM_earth_pal_11.inc" + } +}; diff --git a/rel/data/field/bg/rail_pal.c b/rel/data/field/bg/rail_pal.c new file mode 100644 index 00000000..7224a04b --- /dev/null +++ b/rel/data/field/bg/rail_pal.c @@ -0,0 +1,40 @@ +#include "m_field_make.h" + +extern u16 mFM_rail_pal[mFM_FIELD_PAL_NUM][16] = { + { + #include "assets/mFM_rail_pal_0.inc" + }, + { + #include "assets/mFM_rail_pal_1.inc" + }, + { + #include "assets/mFM_rail_pal_2.inc" + }, + { + #include "assets/mFM_rail_pal_3.inc" + }, + { + #include "assets/mFM_rail_pal_4.inc" + }, + { + #include "assets/mFM_rail_pal_5.inc" + }, + { + #include "assets/mFM_rail_pal_6.inc" + }, + { + #include "assets/mFM_rail_pal_7.inc" + }, + { + #include "assets/mFM_rail_pal_8.inc" + }, + { + #include "assets/mFM_rail_pal_9.inc" + }, + { + #include "assets/mFM_rail_pal_10.inc" + }, + { + #include "assets/mFM_rail_pal_11.inc" + } +}; diff --git a/rel/m_bg_tex.c b/rel/m_bg_tex.c new file mode 100644 index 00000000..356b28a9 --- /dev/null +++ b/rel/m_bg_tex.c @@ -0,0 +1,69 @@ +#include "m_bg_tex.h" + +u8 sprashC_tex_dummy[512]; +u8 sprashA_tex_dummy[512]; +u8 wave3_tex_dummy[1024]; +u8 wave2_tex_dummy[2048]; +u8 wave1_tex_dummy[1024]; +u8 sand_tex_dummy[1024]; +u8 beach_pal_dummy2[16 * sizeof(u16)]; +u8 beach2_tex_dummy2[256]; +u8 beach1_tex_dummy2[1024]; +u8 beach_tex_dummy[2048]; +u8 tunnel_tex_dummy[2048]; +u8 rail_pal_dummy[16 * sizeof(u16)]; +u8 bush_pal_dummy[16 * sizeof(u16)]; +u8 cliff_pal_dummy[16 * sizeof(u16)]; +u8 earth_pal_dummy[16 * sizeof(u16)]; +u8 station_pal_dummy[16 * sizeof(u16)]; +u8 bridge_2_pal_dummy[16 * sizeof(u16)]; +u8 bridge_1_pal_dummy[16 * sizeof(u16)]; +u8 tekkyo_tex_dummy[2048]; +u8 bridge_2_tex_dummy[2048]; +u8 bridge_1_tex_dummy[2048]; +u8 water_2_tex_dummy[512]; +u8 water_1_tex_dummy[512]; +u8 river_tex_dummy[1024]; +u8 stone_tex_dummy[2048]; +u8 station_tex_dummy[2048]; +u8 rail_tex_dummy[2048]; +u8 grass_tex_dummy[512]; +u8 bush_b_tex_dummy[1024]; +u8 bush_a_tex_dummy[2048]; +u8 cliff_tex_dummy[2048]; +u8 earth_tex_dummy[2048]; + +BSS_ORDER_GROUP_START + BSS_ORDER_ITEM(sprashC_tex_dummy); + BSS_ORDER_ITEM(sprashA_tex_dummy); + BSS_ORDER_ITEM(wave3_tex_dummy); + BSS_ORDER_ITEM(wave2_tex_dummy); + BSS_ORDER_ITEM(wave1_tex_dummy); + BSS_ORDER_ITEM(sand_tex_dummy); + BSS_ORDER_ITEM(beach_pal_dummy2); + BSS_ORDER_ITEM(beach2_tex_dummy2); + BSS_ORDER_ITEM(beach1_tex_dummy2); + BSS_ORDER_ITEM(beach_tex_dummy); + BSS_ORDER_ITEM(tunnel_tex_dummy); + BSS_ORDER_ITEM(rail_pal_dummy); + BSS_ORDER_ITEM(bush_pal_dummy); + BSS_ORDER_ITEM(cliff_pal_dummy); + BSS_ORDER_ITEM(earth_pal_dummy); + BSS_ORDER_ITEM(station_pal_dummy); + BSS_ORDER_ITEM(bridge_2_pal_dummy); + BSS_ORDER_ITEM(bridge_1_pal_dummy); + BSS_ORDER_ITEM(tekkyo_tex_dummy); + BSS_ORDER_ITEM(bridge_2_tex_dummy); + BSS_ORDER_ITEM(bridge_1_tex_dummy); + BSS_ORDER_ITEM(water_2_tex_dummy); + BSS_ORDER_ITEM(water_1_tex_dummy); + BSS_ORDER_ITEM(river_tex_dummy); + BSS_ORDER_ITEM(stone_tex_dummy); + BSS_ORDER_ITEM(station_tex_dummy); + BSS_ORDER_ITEM(rail_tex_dummy); + BSS_ORDER_ITEM(grass_tex_dummy); + BSS_ORDER_ITEM(bush_b_tex_dummy); + BSS_ORDER_ITEM(bush_a_tex_dummy); + BSS_ORDER_ITEM(cliff_tex_dummy); + BSS_ORDER_ITEM(earth_tex_dummy); +BSS_ORDER_GROUP_END diff --git a/rel/m_field_make.c b/rel/m_field_make.c new file mode 100644 index 00000000..de99a6fd --- /dev/null +++ b/rel/m_field_make.c @@ -0,0 +1,1988 @@ +#include "m_field_make.h" + +#include "m_island.h" +#include "m_name_table.h" +#include "m_common_data.h" +#include "m_room_type.h" +#include "m_scene_table.h" +#include "m_random_field.h" +#include "m_soncho.h" +#include "libjsys/jsyswrapper.h" +#include "m_malloc.h" +#include "libultra/libultra.h" +#include "m_bg_tex.h" +#include "m_house.h" +#include "m_bgm.h" + +static mActor_name_t l_fg_outer_fill[UT_Z_NUM * UT_X_NUM] = { + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, + RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO, RSV_NO +}; + +static mActor_name_t l_title_demo_fg[(BLOCK_Z_NUM - 2) * BLOCK_X_NUM] = { + 0x00CB, 0x00CB, 0x00CB, 0x00CB, 0x00CB, 0x00CB, 0x00CB, + 0x00CB, 0x00DD, 0x00AB, 0x00CC, 0x00E5, 0x002E, 0x00CB, + 0x00CB, 0x0174, 0x0030, 0x0069, 0x0088, 0x017C, 0x00CB, + 0x00CB, 0x0055, 0x0176, 0x0046, 0x0179, 0x0045, 0x00CB, + 0x00CB, 0x0175, 0x003F, 0x0029, 0x017A, 0x017D, 0x00CB, + 0x00CB, 0x006A, 0x00AC, 0x0178, 0x0068, 0x017E, 0x00CB, + 0x00CB, 0x0061, 0x0177, 0x0062, 0x017B, 0x0064, 0x00CB, + 0x00CB, 0x00CB, 0x00CB, 0x00CB, 0x00CB, 0x00CB, 0x00CB +}; + +typedef struct police_pos_s { + int bx; + int bz; + int ut_x; + int ut_z; +} mFM_police_pos_c; + +static mFM_police_pos_c l_mfm_police_pos = { 0, 0, 0, 0 }; + +int l_bg_disp_num; +int l_bg_disp_size; +static u16 mFM_pal_area[11][16] ATTRIBUTE_ALIGN(32); +mFM_fdinfo_c* g_fdinfo; +static int l_block_kind[BLOCK_TOTAL_NUM]; +static u8 l_block_type[BLOCK_TOTAL_NUM]; + +BSS_ORDER_GROUP_START + BSS_ORDER_ITEM(l_bg_disp_num); + BSS_ORDER_ITEM(l_bg_disp_size); + BSS_ORDER_ITEM(mFM_pal_area); + BSS_ORDER_ITEM(g_fdinfo); + BSS_ORDER_ITEM(l_block_kind); + BSS_ORDER_ITEM(l_block_type); +BSS_ORDER_GROUP_END + +static void mFM_SortBGData(mFM_bg_data_c** sorted_data_p, mFM_bg_data_c* data, int count) { + mFM_bg_data_c** sorted_data_p_copy = sorted_data_p; + int i; + + for (i = 0; i < mFM_BG_ID_MAX; i++) { + sorted_data_p_copy[0] = NULL; + sorted_data_p_copy++; + } + + for (i = 0; i < count; i++) { + if (data->bg_id <= mFM_BG_ID_MAX) { + sorted_data_p[data->bg_id] = data; + } + data++; + } +} + +static void mFM_SortFGData(mFM_fg_data_c** sorted_data_p, mFM_fg_data_c* data, int count, int list_size, int name_start) { + mFM_fg_data_c** sorted_data_p_copy = sorted_data_p; + int i; + + for (i = 0; i < count; i++) { + sorted_data_p_copy[0] = NULL; + sorted_data_p_copy++; + } + + for (i = 0; i < list_size; i++) { + int fg_idx = data->fg_id - name_start; + + if (fg_idx < 0) { + fg_idx = 0; + } + + sorted_data_p[fg_idx] = data; + data++; + } +} + +static void mFM_BgUtDataSet(mCoBG_Collision_u* collision, u8* keep, mCoBG_Collision_u* data) { + 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++) { + collision[0] = data[0]; + keep[0] = data[0].data.center; + + collision++; + data++; + keep++; + } + } +} + +static void mFM_FgUtDataSet(mActor_name_t* fg, mActor_name_t* data) { + 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++) { + fg[0] = data[0]; + fg++; + data++; + } + } +} + +static void mFM_SetFgUtPtoSaveData(mFM_block_info_c* block_info, u8 bx_max, u8 bz_max, int* island_block_x) { + int bz; + int bx; + + for (bz = 0; bz < bz_max; bz++) { + for (bx = 0; bx < bx_max; bx++) { + if (bz > 0 && bz < (bz_max - 1) && bx > 0 && bx < (bx_max - 1)) { + if (bx == island_block_x[0] && bz == mISL_BLOCK_Z) { + block_info->fg_info.items_p = Save_Get(island.fgblock[0][0]).items[0]; + } + else if (bx == island_block_x[1] && bz == mISL_BLOCK_Z) { + block_info->fg_info.items_p = Save_Get(island.fgblock[0][1]).items[0]; + } + else if (bz >= (bz_max - 3)) { + block_info->fg_info.items_p = l_fg_outer_fill; + } + else { + block_info->fg_info.items_p = Save_Get(fg[bz - 1][bx - 1]).items[0]; + } + } + else { + block_info->fg_info.items_p = l_fg_outer_fill; + } + + block_info++; + } + } +} + +static void mFM_SetFgUtPtoHomeInfo(mFM_block_info_c* block_info, u8 bx_max, u8 bz_max, mActor_name_t house_no, int floor) { + int bx; + int bz; + + for (bz = 0; bz < bz_max; bz++) { + for (bx = 0; bx < bx_max; bx++) { + block_info->fg_info.items_p = Save_Get(homes[house_no]).floors[floor].layer_main.items[0]; + block_info++; + } + } +} + +static void mFM_SetFgUtPtoCottageInfo(mFM_block_info_c* block_info, u8 bx_max, u8 bz_max) { + int bx; + int bz; + + for (bz = 0; bz < bz_max; bz++) { + for (bx = 0; bx < bx_max; bx++) { + block_info->fg_info.items_p = Save_Get(island).cottage.room.layer_main.items[0]; + block_info++; + } + } +} + +static void mFM_ChangeFGName(mActor_name_t* fg_name_p, mActor_name_t fg_name, mActor_name_t field_name, int block) { + mActor_name_t house_owner_name = Common_Get(house_owner_name); + + if (Save_Get(scene_no) == SCENE_COTTAGE_NPC) { + fg_name_p[0] = Common_Get(island_npclist[0]).house_data.main_layer_id; + } + else if (field_name == mFI_FIELD_NPCROOM0 && ITEM_NAME_GET_TYPE(house_owner_name) == NAME_TYPE_NPC) { + int npc_idx = mNpc_SearchAnimalinfo(Save_Get(animals), house_owner_name, ANIMAL_NUM_MAX); + mNpc_NpcList_c* list = Common_GetPointer(npclist[npc_idx]); + + fg_name_p[0] = list->house_data.main_layer_id; + } + else if (mFI_CheckShopFieldName(field_name)) { + fg_name_p[0] = mSP_GetNowShopFgNum(); + } + else if (Save_Get(scene_no) == SCENE_FIELD_TOOL || Save_Get(scene_no) == SCENE_TITLE_DEMO) { + fg_name_p[0] = l_title_demo_fg[block]; + } + else { + fg_name_p[0] = fg_name; + } +} + +static void mFM_ChangeBGName(mActor_name_t* bg_name_p, mActor_name_t bg_name, mActor_name_t field_name) { + if (mFI_CheckShopFieldName(field_name)) { + bg_name_p[0] = mSP_GetNowShopBgNum(); + } + else if (mFI_GET_TYPE(field_name) == mFI_FIELD_PLAYER0_ROOM) { + bg_name_p[0] = mRmTp_GetPlayerRoomCollisionIdx(field_name, bg_name); + } + else { + bg_name_p[0] = bg_name; + } +} + +static void mFM_SetSoundSource(mFM_bg_sound_source_c* sound_source, mFM_bg_sound_source_data_c* data, int count, int bx, int bz) { + int i; + + for (i = 0; i != count; i++) { + sound_source->kind = data->kind; + sound_source->pos.x = data->ut_x * mFI_UT_WORLDSIZE_X_F; + sound_source->pos.x += bx * mFI_BK_WORLDSIZE_X_F + mFI_UT_WORLDSIZE_HALF_X_F; + sound_source->pos.y = 0.0f; + sound_source->pos.z = data->ut_z * mFI_UT_WORLDSIZE_Z_F; + sound_source->pos.z += bz * mFI_BK_WORLDSIZE_Z_F + mFI_UT_WORLDSIZE_HALF_Z_F; + + data++; + sound_source++; + } +} + +static void mFM_SetBG(mFM_bg_info_c* bg_info, mFM_bg_data_c* bg_data, u16 height, u8 type, mActor_name_t bg_name, int block_x, int block_z) { + bg_info->bg_id.height = height; + bg_info->bg_id.combination_type = bg_name; + bg_info->opaque_gfx = bg_data->opaque_gfx; + bg_info->translucent_gfx = bg_data->translucent_gfx; + bg_info->animation = bg_data->animation; + bg_info->animation_count = bg_data->animation_count; + bg_info->_18 = bg_data->_14; + bg_info->_1C = bg_data->_18 - bg_data->_14; // size + bg_info->block_type = type; + bg_info->block_kind = mRF_Type2BlockInfo(type); + + mFM_SetSoundSource(bg_info->sound_source, bg_data->sound_source, mFM_SOUND_SOURCE_NUM, block_x, block_z); + mFM_BgUtDataSet(bg_info->collision[0], bg_info->keep_h[0], bg_data->collision[0]); +} + +static void mFM_SetFG(mFM_fg_info_c* fg_info, mFM_fg_data_c* data, mActor_name_t fg_name) { + int scene; + int i; + + fg_info->fg_id = fg_name; + fg_info->move_actor_bit_data = 0; + + scene = Save_Get(scene_no); + + if ( + scene != SCENE_FG && + 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 + ) { + if (scene == SCENE_COTTAGE_NPC) { + if (mNpc_GetIslandRoomFtrNum() > 0) { + mFM_FgUtDataSet(fg_info->items_p, mNpc_GetIslandRoomP(Save_Get(island).animal.id.npc_id)); + mNpc_ChangeIslandRoom(fg_info->items_p); + } + else { + mFM_FgUtDataSet(fg_info->items_p, data->items[0]); + } + + if (fg_info != NULL && fg_info->items_p != NULL) { + mActor_name_t* items_p = fg_info->items_p; + + items_p[(8 << 4) | 3] = EXIT_DOOR; + items_p[(8 << 4) | 4] = EXIT_DOOR; + } + } + else { + mFM_FgUtDataSet(fg_info->items_p, data->items[0]); + } + } + + for (i = 0; i < mFM_HANIWA_STEP_NUM; i++) { + fg_info->haniwa_step[i] = data->haniwa_step[i]; + } +} + +static void mFM_SetFG2(mActor_name_t* items_p, mFM_fg_data_c** data, mActor_name_t field_name, int name_start) { + mActor_name_t house_owner_name = Common_Get(house_owner_name); + + if (items_p != NULL && Save_Get(scene_no) == SCENE_COTTAGE_NPC) { + int idx = mFM_FG2_ID_MAX; + + idx -= name_start; + if (idx < 0) { + idx = 0; + } + + if (data[idx] != NULL) { + mFM_FgUtDataSet(items_p, data[idx]->items[0]); + } + } + else { + if (items_p != NULL && field_name == mFI_FIELD_NPCROOM0 && ITEM_NAME_GET_TYPE(house_owner_name) == NAME_TYPE_NPC) { + int anm_idx = mNpc_SearchAnimalinfo(Save_Get(animals), house_owner_name, ANIMAL_NUM_MAX); + mNpc_NpcList_c* npc_list = Common_GetPointer(npclist[anm_idx]); + int secondary_idx = npc_list->house_data.secondary_layer_id - name_start; + + if (secondary_idx < 0) { + secondary_idx = 0; + } + + if (data[secondary_idx] != NULL) { + mFM_FgUtDataSet(items_p, data[secondary_idx]->items[0]); + } + } + } +} + +static void mFM_BlockDataSet( + mActor_name_t field_name, + mFM_block_info_c* block_info, + mFM_combination_c* save_combi_table, + mFM_bg_data_c** bg_data_list, + mFM_fg_data_c** fg_data_list, + mFM_combo_info_c* data_combi_table, + int bx_max, + int bz_max, + int name_start +) { + mFM_combo_info_c* combi; + mActor_name_t bg_name; + mActor_name_t fg_name; + int fg_idx; + int i; + int bx = 0; + int bz = 0; + int max = bz_max * bx_max; + + for (i = 0; i < max; i++) { + combi = &data_combi_table[save_combi_table[0].combination_type]; + + mFM_ChangeFGName(&fg_name, combi->fg_id, field_name, i); + mFM_ChangeBGName(&bg_name, combi->bg_id, field_name); + + if (bg_name > mFM_BG_ID_MAX) { + bg_name = 0; + } + + if (fg_name > mFM_FG_ID_MAX) { + fg_name = 0; + } + + fg_idx = fg_name - name_start; + if (fg_idx < 0) { + fg_idx = 0; + } + + if (bg_data_list[bg_name] != NULL && fg_data_list[fg_idx]) { + mFM_SetBG(&block_info->bg_info, bg_data_list[bg_name], save_combi_table[0].height, combi->type, bg_name, bx, bz); + mFM_SetFG(&block_info->fg_info, fg_data_list[fg_idx], fg_name); + } + + bx++; + + if (bx >= bx_max) { + bx = 0; + bz++; + } + + block_info++; + save_combi_table++; + } +} + +static void mFM_KeepPolicePos(int bx, int bz, int ut_x, int ut_z) { + l_mfm_police_pos.bx = bx; + l_mfm_police_pos.bz = bz; + l_mfm_police_pos.ut_x = ut_x; + l_mfm_police_pos.ut_z = ut_z; +} + +extern void mFM_GetPolicePos(int* bx, int* bz, int* ut_x, int* ut_z) { + *bx = l_mfm_police_pos.bx; + *bz = l_mfm_police_pos.bz; + *ut_x = l_mfm_police_pos.ut_x; + *ut_z = l_mfm_police_pos.ut_z; +} + +static void mFM_SetMoveActorInfo(mFM_block_info_c* block_info, int bx_max, int bz_max, mFM_move_actor_data_c* move_actor_data, u32 param_5, u32 param_6) { + mFM_move_actor_data_c* move_ac_data_p = move_actor_data; + + if (block_info != NULL) { + for (move_ac_data_p; move_ac_data_p != NULL && move_ac_data_p->name_id != RSV_NO; move_ac_data_p++) { + int block = -1; + int ut_x; + int ut_z; + + ut_x = move_ac_data_p->ut_x; + ut_z = move_ac_data_p->ut_z; + + if (move_ac_data_p->desired_block_kind == mRF_BLOCKKIND_NONE) { + block = move_ac_data_p->block_x + move_ac_data_p->block_z * bx_max; + } + else { + int bx; + int bz; + + if (mFI_BlockKind2BkNum(&bx, &bz, move_ac_data_p->desired_block_kind) == TRUE) { + block = bx + bz * bx_max; + + switch (move_ac_data_p->name_id) { + case SP_NPC_POLICE: + { + mActor_name_t* items = block_info[block].fg_info.items_p; + int i; + + for (i = 0; i < UT_TOTAL_NUM; i++) { + if (items[0] == POLICE_STATION) { + ut_x = i % UT_X_NUM; + ut_z = i / UT_Z_NUM; + ut_x += 2; + mFM_KeepPolicePos(bx, bz, ut_x, ut_z); + + break; + } + + items++; + } + + break; + } + + case SP_NPC_SONCHO: + { + if (mEv_CheckFirstJob() == FALSE || (mSC_check_ArbeitPlayer() && mSC_LightHouse_travel_check())) { + block = -1; + } + + break; + } + } + } + } + + if (block != -1) { + mFM_move_actor_c* move_actor = block_info[block].fg_info.move_actors; + int free_idx = mFI_GetMoveActorListIdx(move_actor, mFM_MOVE_ACTOR_NUM, EMPTY_NO); + + if (free_idx != -1) { + move_actor[free_idx].name_id = move_ac_data_p->name_id; + move_actor[free_idx].ut_x = ut_x; + move_actor[free_idx].ut_z = ut_z; + move_actor[free_idx].npc_info_idx = move_ac_data_p->npc_info_idx; + move_actor[free_idx].arg = move_ac_data_p->arg; + } + } + } + } +} + +static void mFM_SetCombiTable(mFM_combination_c* combi_table, mFM_combination_c* combi_id, u8 bx_max, u8 bz_max) { + u8 bz; + u8 bx; + + for (bz = 0; bz < bz_max; bz++) { + for (bx = 0; bx < bx_max; bx++) { + combi_table->combination_type = combi_id->combination_type; + combi_table->height = combi_id->height; + + combi_table++; + combi_id++; + } + } +} + +static int mFM_SetBlockInfo(mFM_fdinfo_c* field_info, mFM_combination_c* combi_table) { + mFM_bg_data_c** sorted_bg_data; + mFM_fg_data_c** sorted_fg_data; + mFM_combo_info_c* combi_info_p; + mFM_bg_data_c* bg_data_p = data_bgd; + mFM_fg_data_c* fg_data; + size_t malloc_size; + u32 aram_addr; + int fg_count; + int name_start; + int fg_data_entries; + int file_id; + u32 size; + u32 align_size; + + if (mFI_GET_TYPE(field_info->field_id) == mFI_FIELD_NPCROOM0) { + malloc_size = mFM_FG_NPC_NUM * sizeof(mFM_fg_data_c*); + fg_count = mFM_FG_NPC_NUM; + name_start = mFM_FG_NPC_START; + file_id = RESOURCE_FGNPCDATA; + } + else { + malloc_size = mFM_FG_NUM * sizeof(mFM_fg_data_c*); + fg_count = mFM_FG_NUM; + name_start = mFM_FG_START; + file_id = RESOURCE_FGDATA; + } + + { + size = JW_GetResSizeFileNo(file_id); + align_size = ALIGN_NEXT(size, 32); + fg_data = (mFM_fg_data_c*)zelda_malloc_align(align_size, 32); + fg_data_entries = size / sizeof(mFM_fg_data_c); + + _JW_GetResourceAram(JW_GetAramAddress(file_id), (u8*)fg_data, align_size); + combi_info_p = data_combi_table; + sorted_bg_data = (mFM_bg_data_c**)zelda_malloc(mFM_BG_ID_MAX * sizeof(mFM_bg_data_c**)); + + if (sorted_bg_data == NULL) { + return FALSE; + } + + mFM_SortBGData(sorted_bg_data, bg_data_p, data_bgd_number); + sorted_fg_data = (mFM_fg_data_c**)zelda_malloc(malloc_size); + + if (sorted_fg_data == NULL) { + return FALSE; /* @BUG - possible memory leak from the sorted_bg_data malloc */ + } + + mFM_SortFGData(sorted_fg_data, fg_data, fg_count, fg_data_entries, name_start); + + mFM_BlockDataSet( + field_info->field_id, + field_info->block_info, + combi_table, + sorted_bg_data, + sorted_fg_data, + combi_info_p, + field_info->block_x_max, + field_info->block_z_max, + name_start + ); + + mFM_SetFG2(field_info->fg2_p[0], sorted_fg_data, field_info->field_id, name_start); + + if (mFI_GET_TYPE(field_info->field_id) == mFI_FIELD_NPCROOM0) { + mNpc_SetNpcFurnitureRandom(sorted_fg_data, name_start); // select a random furniture item from NPC base furniture layer + } + + zelda_free(sorted_bg_data); + zelda_free(sorted_fg_data); + zelda_free(fg_data); + } + + return 0; +} + +static void mFM_set_pal_p(mFM_field_pal_c* pal) { + if (pal != NULL) { + bzero(mFM_pal_area, sizeof(mFM_pal_area)); + + pal->earth_pal = mFM_pal_area[0]; + pal->cliff_pal = mFM_pal_area[1]; + pal->bush_pal = mFM_pal_area[2]; + pal->flower0_pal = mFM_pal_area[3]; + pal->flower1_pal = mFM_pal_area[4]; + pal->flower2_pal = mFM_pal_area[5]; + pal->grass_pal = mFM_pal_area[6]; + pal->tree_pal = mFM_pal_area[7]; + pal->cedar_tree_pal = mFM_pal_area[8]; + pal->palm_tree_pal = mFM_pal_area[9]; + pal->golden_tree_pal = mFM_pal_area[10]; + } +} + +extern u16 mFM_obj_a_01_flower_pal[3 * 9][16]; +extern u16 mFM_obj_01_zassou_pal[9][16]; +extern u16 mFM_obj_tree_01_pal[14][16]; +extern u16 mFM_obj_tree_01_pal_dol[14][16]; +extern u16 mFM_obj_palm_01_pal[14][16]; +extern u16 mFM_obj_gold_01_pal_dol[14][16]; + +static void mFM_SetFGPal(mFM_field_pal_c* pal, int term) { + static int tree_pal_idx_table[mTM_TERM_NUM] = { + 10, 12, 13, 0, + 1, 2, 2, 3, + 3, 4, 5, 6, + 7, 8, 9, 10, + 11, 10 + }; + + static int flower_pal_idx_table[mTM_TERM_NUM] = { + 8, 8, 8, 0, + 1, 1, 1, 2, + 2, 3, 4, 5, + 6, 7, 8, 8, + 8, 8 + }; + + int idx = flower_pal_idx_table[term]; + + bcopy(mFM_obj_a_01_flower_pal[0 * 9 + idx], pal->flower0_pal, 16 * sizeof(u16)); + bcopy(mFM_obj_a_01_flower_pal[1 * 9 + idx], pal->flower1_pal, 16 * sizeof(u16)); + bcopy(mFM_obj_a_01_flower_pal[2 * 9 + idx], pal->flower2_pal, 16 * sizeof(u16)); + bcopy(mFM_obj_01_zassou_pal[idx], pal->grass_pal, 16 * sizeof(u16)); + bcopy(mFM_obj_tree_01_pal[tree_pal_idx_table[term]], pal->tree_pal, 16 * sizeof(u16)); + bcopy(mFM_obj_tree_01_pal_dol[tree_pal_idx_table[term]], pal->cedar_tree_pal, 16 * sizeof(u16)); + bcopy(mFM_obj_palm_01_pal[tree_pal_idx_table[term]], pal->palm_tree_pal, 16 * sizeof(u16)); + bcopy(mFM_obj_gold_01_pal_dol[tree_pal_idx_table[term]], pal->golden_tree_pal, 16 * sizeof(u16)); +} + +extern u16 mFM_earth_pal[mFM_FIELD_PAL_NUM][16]; +extern u16 mFM_cliff_pal[mFM_FIELD_PAL_NUM][16]; +extern u16 mFM_bush_pal[mFM_FIELD_PAL_NUM][16]; +extern u16 mFM_rail_pal[mFM_FIELD_PAL_NUM][16]; +extern u16 mFM_beach_pal[mFM_FIELD_PAL_NUM][16]; + +static void mFM_SetFieldPal(mFM_field_pal_c* pal) { + static int field_pal_idx_table[mTM_TERM_NUM] = { + 9, 10, 11, 0, + 1, 1, 1, 2, + 2, 3, 4, 5, + 6, 7, 8, 9, + 9, 9 + }; + + u32 term = Common_Get(time.term_idx); + int field_pal_idx; + int i; + u16* pal_src; + + if (term >= mTM_TERM_NUM) { + term = mTM_TERM_0; + } + + if (Save_Get(scene_no) == SCENE_MUSEUM_ROOM_INSECT) { + term = mTM_TERM_4; + } + + field_pal_idx = field_pal_idx_table[term]; + + pal_src = mFM_earth_pal[field_pal_idx]; + for (i = 0; i < 16; i++) { + pal->earth_pal[i] = pal_src[i]; + } + + pal_src = mFM_cliff_pal[field_pal_idx]; + for (i = 0; i < 16; i++) { + pal->cliff_pal[i] = pal_src[i]; + } + + pal_src = mFM_bush_pal[field_pal_idx]; + for (i = 0; i < 16; i++) { + pal->bush_pal[i] = pal_src[i]; + } + + mFM_SetFGPal(pal, term); +} + +static void mFM_SetFgDepositP(mFM_block_info_c* block_info, mActor_name_t field_id, int bx_max, int bz_max, int* island_x_blocks) { + mFM_block_info_c* block_info_p; + int total_block; + int scene; + u16* deposit_p; + int bz; + int bx; + int fg_blocks; + + scene = Save_Get(scene_no); + total_block = bx_max * bz_max; + block_info_p = block_info; + + for (bz = 0; bz < total_block; bz++) { + block_info[bz].fg_info.deposit_p = NULL; + } + + if ((mFI_GET_TYPE(field_id) == mFI_FIELD_FG)) { + fg_blocks = 0; + + if (scene == SCENE_FG) { + for (bz = 0; bz < bz_max; bz++) { + for (bx = 0; bx < bx_max; bx++) { + if (fg_blocks >= FG_BLOCK_TOTAL_NUM) { + break; + } + + if (bx > 0 && bx < bx_max - 1 && bz > 0 && bz < bz_max - 3) { + block_info->fg_info.deposit_p = Save_GetPointer(deposit[fg_blocks++][0]); + } + + block_info++; + } + } + + block_info = block_info_p + island_x_blocks[0] + bx_max * mISL_BLOCK_Z; + + /* @BUG - they used the island Z acre location define here on accident lol */ + #ifndef BUGFIXES + for (bz = 0; bz < mISL_BLOCK_Z; bz++) { + #else + for (bz = 0; bz < mISL_FG_BLOCK_X_NUM; bz++) { + #endif + block_info->fg_info.deposit_p = Save_Get(island).deposit[bz]; + block_info++; + } + } + else { + for (bz = 0; bz < bz_max; bz++) { + for (bx = 0; bx < bx_max; bx++) { + if (fg_blocks >= FG_BLOCK_TOTAL_NUM) { + break; + } + + block_info->fg_info.deposit_p = Save_GetPointer(deposit[fg_blocks++][0]); + block_info++; + } + } + } + } +} + +extern mFM_field_data_c data_fdd[SCENE_NUM]; + +static mFM_fdinfo_c* mFM_MakeField(u16 scene, u16 bg_max, u8 bg_num) { + mFM_field_data_c* field_data; + int island_x_blocks[2]; + int total_block; + mFM_block_info_c* block_info; + mFM_combination_c* combi; + mFM_fdinfo_c* field_info = (mFM_fdinfo_c*)zelda_malloc(sizeof(mFM_fdinfo_c)); + int i; + int j; + mActor_name_t house_owner_id; + int floor_no; + + if (field_info == NULL) { + return NULL; + } + + bzero(field_info, sizeof(mFM_fdinfo_c)); + field_data = &data_fdd[scene]; + field_info->block_x_max = field_data->block_x_max; + field_info->block_z_max = field_data->block_z_max; + field_info->bg_num = bg_num; + field_info->bg_max = bg_max; + field_info->fg2_p = (mActor_name_t**)zelda_malloc((mHm_LAYER_NUM - 1) * sizeof(mActor_name_t*)); + + for (i = 0; i < 3; i++) { + field_info->fg2_p[i] = NULL; + } + + i = sizeof(mFM_block_info_c) * field_data->block_x_max * field_data->block_z_max; + block_info = (mFM_block_info_c*)zelda_malloc(i); + + if (block_info == NULL) { + /* @BUG - field_info was not freed */ + #ifdef BUGFIXES + zelda_free(field_info); + #endif + return NULL; + } + + bzero(block_info, i); + field_info->block_info = block_info; + field_info->field_id = field_data->field_name; + field_info->_04 = field_data->_94; + field_info->update_fg = FALSE; + field_info->born_item = FALSE; + field_info->born_actor = FALSE; + + for (j = 0; j < mFM_VISIBLE_BLOCK_NUM; j++) { + field_info->bg_draw_info[j].block_x = 0xFF; + field_info->bg_draw_info[j].block_z = 0xFF; + field_info->bg_draw_info[j].display_list = NULL; + field_info->last_bg_idx[j] = -1; + } + + if (Save_Get(scene_no) == SCENE_FG) { + mFI_GetIslandBlockNumX(island_x_blocks); + } + + if (Save_Get(scene_no) == SCENE_FG) { + combi = Save_Get(combi_table[0]); + mFM_SetFgUtPtoSaveData(field_info->block_info, field_info->block_x_max, field_info->block_z_max, island_x_blocks); + } + else if (mSc_IS_SCENE_PLAYER_ROOM(Save_Get(scene_no))) { + house_owner_id = Common_Get(house_owner_name); + floor_no = mFI_GetNowPlayerHouseFloorNo(); + + if (floor_no == -1) { + floor_no = 0; + } + + if (house_owner_id == RSV_NO) { + house_owner_id = EMPTY_NO; + Common_Set(house_owner_name, house_owner_id); + } + + combi = field_data->combi; + field_info->field_id = mFI_FIELD_PLAYER0_ROOM + house_owner_id; + + if (Save_Get(scene_no) == SCENE_COTTAGE_MY) { + mFM_SetFgUtPtoCottageInfo(field_info->block_info, field_info->block_x_max, field_info->block_z_max); + } + else { + mFM_SetFgUtPtoHomeInfo(field_info->block_info, field_info->block_x_max, field_info->block_z_max, house_owner_id, floor_no); + } + } + else { + mFM_block_info_c* block_info = field_info->block_info; + int total_block = field_info->block_x_max * field_info->block_z_max; + int k; + combi = field_data->combi; + + for (k = total_block; k != 0; k--) { + mActor_name_t* fg_p = (mActor_name_t*)zelda_malloc(UT_TOTAL_NUM * sizeof(mActor_name_t)); + + // There could be a memory leak here due to previous allocated blocks, perhaps investigate later + if (fg_p == NULL) { + break; + } + + bzero(fg_p, UT_TOTAL_NUM * sizeof(mActor_name_t)); + block_info->fg_info.items_p = fg_p; + block_info++; + } + } + + if (mSc_IS_SCENE_PLAYER_ROOM(Save_Get(scene_no))) { + mHm_lyr_c* layer; + + if (Save_Get(scene_no) == SCENE_COTTAGE_MY) { + layer = &Save_Get(island).cottage.room.layer_main; + } + else { + mActor_name_t house_owner_id = Common_Get(house_owner_name); + floor_no = mFI_GetNowPlayerHouseFloorNo(); + + if (floor_no == -1) { + floor_no = 0; + } + + layer = &Save_Get(homes[house_owner_id]).floors[floor_no].layer_main; + } + + for (i = 1; i < mHm_LAYER_NUM; i++) { + field_info->fg2_p[i - 1] = layer[i].items[0]; + } + } + else if (Save_Get(scene_no) == SCENE_NPC_HOUSE || Save_Get(scene_no) == SCENE_FIELD_TOOL_INSIDE) { + field_info->fg2_p[0] = (mActor_name_t*)zelda_malloc(UT_TOTAL_NUM * sizeof(mActor_name_t)); + + if (field_info->fg2_p[0] != NULL) { + bzero(field_info->fg2_p[0], UT_TOTAL_NUM * sizeof(mActor_name_t)); + } + } + + mFM_SetBlockInfo(field_info, combi); + mFM_SetMoveActorInfo(field_info->block_info, field_info->block_x_max, field_info->block_z_max, field_data->move_actor_data, field_data->_94, field_data->_98); + + for (i = 0; i < mFM_VISIBLE_BLOCK_NUM; i++) { + field_info->bg_display_list_p[i] = NULL; + } + + for (i = 0; i < field_info->bg_num; i++) { + field_info->bg_display_list_p[i] = (u8*)zelda_malloc(field_info->bg_max); + field_info->bg_display_list_p[i] = (u8*)((u32)(field_info->bg_display_list_p[i]) + (16-1)); + field_info->bg_display_list_p[i] = (u8*)((u32)(field_info->bg_display_list_p[i]) & (~(16-1))); + } + + mFM_set_pal_p(&field_info->field_palette); + mFM_SetFieldPal(&field_info->field_palette); + mFM_SetFgDepositP(field_info->block_info, field_info->field_id, field_info->block_x_max, field_info->block_z_max, island_x_blocks); + + return field_info; +} + +static mBGTex_obj_c l_bg_tex_common_dummy[27] = { + { earth_tex_dummy, 0x800 }, + { cliff_tex_dummy, 0x800 }, + { bush_a_tex_dummy, 0x800 }, + { bush_b_tex_dummy, 0x400 }, + { grass_tex_dummy, 0x200 }, + { rail_tex_dummy, 0x800 }, + { station_tex_dummy, 0x800 }, + { stone_tex_dummy, 0x800 }, + { river_tex_dummy, 0x400 }, + { water_1_tex_dummy, 0x200 }, + { water_2_tex_dummy, 0x200 }, + { bridge_1_tex_dummy, 0x800 }, + { bridge_2_tex_dummy, 0x800 }, + { tekkyo_tex_dummy, 0x800 }, + { tunnel_tex_dummy, 0x800 }, + { beach_tex_dummy, 0x800 }, + { bridge_1_pal_dummy, 0x20 }, + { bridge_2_pal_dummy, 0x20 }, + { station_pal_dummy, 0x20 }, + { beach1_tex_dummy2, 0x400 }, + { beach2_tex_dummy2, 0x100 }, + { sand_tex_dummy, 0x400 }, + { wave1_tex_dummy, 0x400 }, + { wave2_tex_dummy, 0x800 }, + { wave3_tex_dummy, 0x400 }, + { sprashA_tex_dummy, 0x200 }, + { sprashC_tex_dummy, 0x200 }, +}; + +static mBGTex_obj_c l_bg_pal_common_dummy[5] = { + { earth_pal_dummy, 16 * sizeof(u16) }, + { cliff_pal_dummy, 16 * sizeof(u16) }, + { bush_pal_dummy, 16 * sizeof(u16) }, + { rail_pal_dummy, 16 * sizeof(u16) }, + { beach_pal_dummy2, 16 * sizeof(u16) } +}; + +extern u8 mFM_grd_s_earth_tex[]; +extern u8 mFM_grd_s_cliff_tex[]; +extern u8 mFM_grd_s_bushA_tex[]; +extern u8 mFM_grd_s_bushB_tex[]; +extern u8 mFM_grd_s_grass_tex[]; +extern u8 mFM_grd_s_rail_tex[]; +extern u8 mFM_grd_s_station_tex[]; +extern u8 mFM_grd_s_stone_tex[]; +extern u8 mFM_grd_s_river_tex[]; +extern u8 mFM_grd_water1_tex[]; +extern u8 mFM_grd_water2_tex[]; +extern u8 mFM_grd_s_bridge1_tex[]; +extern u8 mFM_grd_s_bridge2_tex[]; +extern u8 mFM_grd_s_tekkyo_tex[]; +extern u8 mFM_grd_s_tunnel_tex[]; +extern u8 mFM_grd_s_beach_tex[]; +extern u16 mFM_grd_s_bridge1_pal[]; +extern u16 mFM_grd_s_bridge2_pal[]; +extern u16 mFM_grd_s_station1_pal[]; +extern u8 mFM_grd_beachA_tex[]; +extern u8 mFM_grd_beachB_tex[]; +extern u8 mFM_grd_s_sand_tex[]; +extern u8 mFM_grd_wave1_tex[]; +extern u8 mFM_grd_wave2_tex[]; +extern u8 mFM_grd_wave3_tex[]; +extern u8 mFM_grd_sprashA_tex[]; +extern u8 mFM_grd_sprashC_tex[]; + +static void* l_bg_tex_segment_rom_start_s_0[mFM_FIELD_TEX_NUM] = { + mFM_grd_s_earth_tex, + mFM_grd_s_cliff_tex, + mFM_grd_s_bushA_tex, + mFM_grd_s_bushB_tex, + mFM_grd_s_grass_tex, + mFM_grd_s_rail_tex, + mFM_grd_s_station_tex, + mFM_grd_s_stone_tex, + mFM_grd_s_river_tex, + mFM_grd_water1_tex, + mFM_grd_water2_tex, + mFM_grd_s_bridge1_tex, + mFM_grd_s_bridge2_tex, + mFM_grd_s_tekkyo_tex, + mFM_grd_s_tunnel_tex, + mFM_grd_s_beach_tex, + mFM_grd_s_bridge1_pal, + mFM_grd_s_bridge2_pal, + mFM_grd_s_station1_pal, + mFM_grd_beachA_tex, + mFM_grd_beachB_tex, + mFM_grd_s_sand_tex, + mFM_grd_wave1_tex, + mFM_grd_wave2_tex, + mFM_grd_wave3_tex, + mFM_grd_sprashA_tex, + mFM_grd_sprashC_tex +}; + +extern u8 mFM_grd_s_earth_2_tex[]; +extern u8 mFM_grd_s_cliff_2_tex[]; +extern u8 mFM_grd_s_bushA_2_tex[]; +extern u8 mFM_grd_s_bushB_2_tex[]; +extern u8 mFM_grd_s_grass_2_tex[]; +extern u8 mFM_grd_s_rail_2_tex[]; +extern u8 mFM_grd_s_station_2_tex[]; +extern u8 mFM_grd_s_stone_2_tex[]; +extern u8 mFM_grd_s_river_2_tex[]; +extern u8 mFM_grd_s_bridge1_2_tex[]; +extern u8 mFM_grd_s_bridge2_2_tex[]; +extern u8 mFM_grd_s_tekkyo_2_tex[]; +extern u8 mFM_grd_s_tunnel_2_tex[]; +extern u8 mFM_grd_s_sand_2_tex[]; + +static void* l_bg_tex_segment_rom_start_s_1[mFM_FIELD_TEX_NUM] = { + mFM_grd_s_earth_2_tex, + mFM_grd_s_cliff_2_tex, + mFM_grd_s_bushA_2_tex, + mFM_grd_s_bushB_2_tex, + mFM_grd_s_grass_2_tex, + mFM_grd_s_rail_2_tex, + mFM_grd_s_station_2_tex, + mFM_grd_s_stone_2_tex, + mFM_grd_s_river_2_tex, + mFM_grd_water1_tex, + mFM_grd_water2_tex, + mFM_grd_s_bridge1_2_tex, + mFM_grd_s_bridge2_2_tex, + mFM_grd_s_tekkyo_2_tex, + mFM_grd_s_tunnel_2_tex, + mFM_grd_s_beach_tex, + mFM_grd_s_bridge1_pal, + mFM_grd_s_bridge2_pal, + mFM_grd_s_station1_pal, + mFM_grd_beachA_tex, + mFM_grd_beachB_tex, + mFM_grd_s_sand_2_tex, + mFM_grd_wave1_tex, + mFM_grd_wave2_tex, + mFM_grd_wave3_tex, + mFM_grd_sprashA_tex, + mFM_grd_sprashC_tex +}; + +extern u8 mFM_grd_s_earth_3_tex[]; +extern u8 mFM_grd_s_cliff_3_tex[]; +extern u8 mFM_grd_s_bushA_3_tex[]; +extern u8 mFM_grd_s_bushB_3_tex[]; +extern u8 mFM_grd_s_grass_3_tex[]; +extern u8 mFM_grd_s_rail_3_tex[]; +extern u8 mFM_grd_s_station_3_tex[]; +extern u8 mFM_grd_s_stone_3_tex[]; +extern u8 mFM_grd_s_river_3_tex[]; +extern u8 mFM_grd_s_bridge1_3_tex[]; +extern u8 mFM_grd_s_bridge2_3_tex[]; +extern u8 mFM_grd_s_tekkyo_3_tex[]; +extern u8 mFM_grd_s_tunnel_3_tex[]; +extern u8 mFM_grd_s_sand_3_tex[]; + +static void* l_bg_tex_segment_rom_start_s_2[mFM_FIELD_TEX_NUM] = { + mFM_grd_s_earth_3_tex, + mFM_grd_s_cliff_3_tex, + mFM_grd_s_bushA_3_tex, + mFM_grd_s_bushB_3_tex, + mFM_grd_s_grass_3_tex, + mFM_grd_s_rail_3_tex, + mFM_grd_s_station_3_tex, + mFM_grd_s_stone_3_tex, + mFM_grd_s_river_3_tex, + mFM_grd_water1_tex, + mFM_grd_water2_tex, + mFM_grd_s_bridge1_3_tex, + mFM_grd_s_bridge2_3_tex, + mFM_grd_s_tekkyo_3_tex, + mFM_grd_s_tunnel_3_tex, + mFM_grd_s_beach_tex, + mFM_grd_s_bridge1_pal, + mFM_grd_s_bridge2_pal, + mFM_grd_s_station1_pal, + mFM_grd_beachA_tex, + mFM_grd_beachB_tex, + mFM_grd_s_sand_3_tex, + mFM_grd_wave1_tex, + mFM_grd_wave2_tex, + mFM_grd_wave3_tex, + mFM_grd_sprashA_tex, + mFM_grd_sprashC_tex +}; + +static void** l_bg_tex_segment_table[mFM_BG_TEX_NUM] = { + l_bg_tex_segment_rom_start_s_0, + l_bg_tex_segment_rom_start_s_1, + l_bg_tex_segment_rom_start_s_2 +}; + +extern u8 mFM_grd_w_earth_tex[]; +extern u8 mFM_grd_w_cliff_tex[]; +extern u8 mFM_grd_w_bushA_tex[]; +extern u8 mFM_grd_w_bushB_tex[]; +extern u8 mFM_grd_w_grass_tex[]; +extern u8 mFM_grd_w_rail_tex[]; +extern u8 mFM_grd_w_station_tex[]; +extern u8 mFM_grd_w_stone_tex[]; +extern u8 mFM_grd_w_river_tex[]; +extern u8 mFM_grd_w_bridge1_tex[]; +extern u8 mFM_grd_w_bridge2_tex[]; +extern u8 mFM_grd_w_tekkyo_tex[]; +extern u8 mFM_grd_w_sand_tex[]; + +static void* l_bg_tex_segment_rom_start_w_0[mFM_FIELD_TEX_NUM] = { + mFM_grd_w_earth_tex, + mFM_grd_w_cliff_tex, + mFM_grd_w_bushA_tex, + mFM_grd_w_bushB_tex, + mFM_grd_w_grass_tex, + mFM_grd_w_rail_tex, + mFM_grd_w_station_tex, + mFM_grd_w_stone_tex, + mFM_grd_w_river_tex, + mFM_grd_water1_tex, + mFM_grd_water2_tex, + mFM_grd_w_bridge1_tex, + mFM_grd_w_bridge2_tex, + mFM_grd_w_tekkyo_tex, + mFM_grd_s_tunnel_tex, + mFM_grd_s_beach_tex, + mFM_grd_s_bridge1_pal, + mFM_grd_s_bridge2_pal, + mFM_grd_s_station1_pal, + mFM_grd_beachA_tex, + mFM_grd_beachB_tex, + mFM_grd_w_sand_tex, + mFM_grd_wave1_tex, + mFM_grd_wave2_tex, + mFM_grd_wave3_tex, + mFM_grd_sprashA_tex, + mFM_grd_sprashC_tex +}; + +extern u8 mFM_grd_w_earth_2_tex[]; +extern u8 mFM_grd_w_cliff_2_tex[]; +extern u8 mFM_grd_w_bushA_2_tex[]; +extern u8 mFM_grd_w_bushB_2_tex[]; +extern u8 mFM_grd_w_grass_2_tex[]; +extern u8 mFM_grd_w_rail_2_tex[]; +extern u8 mFM_grd_w_station_2_tex[]; +extern u8 mFM_grd_w_stone_2_tex[]; +extern u8 mFM_grd_w_river_2_tex[]; +extern u8 mFM_grd_w_bridge1_2_tex[]; +extern u8 mFM_grd_w_bridge2_2_tex[]; +extern u8 mFM_grd_w_tekkyo_2_tex[]; +extern u8 mFM_grd_w_tunnel_2_tex[]; +extern u8 mFM_grd_w_sand_2_tex[]; + +static void* l_bg_tex_segment_rom_start_w_1[mFM_FIELD_TEX_NUM] = { + mFM_grd_w_earth_2_tex, + mFM_grd_w_cliff_2_tex, + mFM_grd_w_bushA_2_tex, + mFM_grd_w_bushB_2_tex, + mFM_grd_w_grass_2_tex, + mFM_grd_w_rail_2_tex, + mFM_grd_w_station_2_tex, + mFM_grd_w_stone_2_tex, + mFM_grd_w_river_2_tex, + mFM_grd_water1_tex, + mFM_grd_water2_tex, + mFM_grd_w_bridge1_2_tex, + mFM_grd_w_bridge2_2_tex, + mFM_grd_w_tekkyo_2_tex, + mFM_grd_w_tunnel_2_tex, + mFM_grd_s_beach_tex, + mFM_grd_s_bridge1_pal, + mFM_grd_s_bridge2_pal, + mFM_grd_s_station1_pal, + mFM_grd_beachA_tex, + mFM_grd_beachB_tex, + mFM_grd_w_sand_2_tex, + mFM_grd_wave1_tex, + mFM_grd_wave2_tex, + mFM_grd_wave3_tex, + mFM_grd_sprashA_tex, + mFM_grd_sprashC_tex +}; + +extern u8 mFM_grd_w_earth_3_tex[]; +extern u8 mFM_grd_w_cliff_3_tex[]; +extern u8 mFM_grd_w_bushA_3_tex[]; +extern u8 mFM_grd_w_bushB_3_tex[]; +extern u8 mFM_grd_w_grass_3_tex[]; +extern u8 mFM_grd_w_rail_3_tex[]; +extern u8 mFM_grd_w_station_3_tex[]; +extern u8 mFM_grd_w_stone_3_tex[]; +extern u8 mFM_grd_w_river_3_tex[]; +extern u8 mFM_grd_w_bridge1_3_tex[]; +extern u8 mFM_grd_w_bridge2_3_tex[]; +extern u8 mFM_grd_w_tekkyo_3_tex[]; +extern u8 mFM_grd_w_tunnel_3_tex[]; +extern u8 mFM_grd_w_sand_3_tex[]; + +static void* l_bg_tex_segment_rom_start_w_2[mFM_FIELD_TEX_NUM] = { + mFM_grd_w_earth_3_tex, + mFM_grd_w_cliff_3_tex, + mFM_grd_w_bushA_3_tex, + mFM_grd_w_bushB_3_tex, + mFM_grd_w_grass_3_tex, + mFM_grd_w_rail_3_tex, + mFM_grd_w_station_3_tex, + mFM_grd_w_stone_3_tex, + mFM_grd_w_river_3_tex, + mFM_grd_water1_tex, + mFM_grd_water2_tex, + mFM_grd_w_bridge1_3_tex, + mFM_grd_w_bridge2_3_tex, + mFM_grd_w_tekkyo_3_tex, + mFM_grd_w_tunnel_3_tex, + mFM_grd_s_beach_tex, + mFM_grd_s_bridge1_pal, + mFM_grd_s_bridge2_pal, + mFM_grd_s_station1_pal, + mFM_grd_beachA_tex, + mFM_grd_beachB_tex, + mFM_grd_w_sand_3_tex, + mFM_grd_wave1_tex, + mFM_grd_wave2_tex, + mFM_grd_wave3_tex, + mFM_grd_sprashA_tex, + mFM_grd_sprashC_tex +}; + +static void** l_bg_w_tex_segment_table[mFM_BG_TEX_NUM] = { + l_bg_tex_segment_rom_start_w_0, + l_bg_tex_segment_rom_start_w_1, + l_bg_tex_segment_rom_start_w_2 +}; + +static u8* l_bg_pal_segment_rom_start[5] = { + (u8*)mFM_earth_pal, + (u8*)mFM_cliff_pal, + (u8*)mFM_bush_pal, + (u8*)mFM_rail_pal, + (u8*)mFM_beach_pal +}; + +static u8 l_water_permission[mFM_FIELD_TEX_NUM] = { + TRUE, TRUE, TRUE, TRUE, + TRUE, TRUE, TRUE, TRUE, + FALSE, FALSE, FALSE, TRUE, + TRUE, TRUE, TRUE, TRUE, + TRUE, TRUE, TRUE, TRUE, + TRUE, TRUE, FALSE, FALSE, + FALSE, TRUE, TRUE +}; + +static void mFM_LoadBGCommonMonthlyPal() { + static int field_pal_idx_table[mTM_TERM_NUM] = { + 9, 10, 11, 0, + 1, 1, 1, 2, + 2, 3, 4, 5, + 6, 7, 8, 9, + 9, 9 + }; + + u32 term = Common_Get(time.term_idx); + int idx; + int i; + + if (term >= mTM_TERM_NUM) { + term = mTM_TERM_0; + } + + if (Save_Get(scene_no) == SCENE_MUSEUM_ROOM_INSECT) { + term = mTM_TERM_4; + } + + idx = field_pal_idx_table[term]; + + for (i = 0; i < 5; i++) { + bcopy(l_bg_pal_segment_rom_start[i] + ((l_bg_pal_common_dummy[i].size * idx) & ~1), l_bg_pal_common_dummy[i].data, l_bg_pal_common_dummy[i].size); + } +} + +extern void mFM_DecideBgTexIdx(u8* bg_tex_idx) { + *bg_tex_idx = RANDOM(mFM_BG_TEX_NUM); +} + +static void mFM_LoadBGCommonTex(int update_tex, u8 tex_idx) { + void** bg_tex_tbl; + u32 season = Common_Get(time.season); + int i; + + if (season >= mTM_SEASON_NUM) { + season = mTM_SEASON_SPRING; + } + + if (Save_Get(scene_no) == SCENE_TITLE_DEMO) { + mFM_DecideBgTexIdx(&tex_idx); + } + + if (tex_idx >= mFM_BG_TEX_NUM) { + tex_idx = mFM_BG_TEX_TRIANGLE; + } + + if (Save_Get(scene_no) == SCENE_MUSEUM_ROOM_INSECT) { + bg_tex_tbl = l_bg_tex_segment_table[tex_idx]; + } + else if (season == mTM_SEASON_WINTER) { + bg_tex_tbl = l_bg_w_tex_segment_table[tex_idx]; + } + else { + bg_tex_tbl = l_bg_tex_segment_table[tex_idx]; + } + + for (i = 0; i < mFM_FIELD_TEX_NUM; i++) { + if (update_tex == TRUE || l_water_permission[i] == TRUE) { + bcopy(bg_tex_tbl[i], l_bg_tex_common_dummy[i].data, l_bg_tex_common_dummy[i].size); + } + } + + mFM_LoadBGCommonMonthlyPal(); +} + +static void set_field_type() { + int field_id = mFI_GetFieldId(); + int house_owner_id; + u8 field_type; + + if (mLd_PlayerManKindCheck() == FALSE) { + house_owner_id = mFI_FIELD_PLAYER0_ROOM + mHS_get_arrange_idx(Common_Get(player_no)); + } + else { + house_owner_id = RSV_NO; + } + + if (field_id == mFI_FIELD_FG) { + field_type = mFI_FIELDTYPE2_FG; + } + else if ((field_id == house_owner_id && mEv_CheckFirstIntro() == FALSE) || Save_Get(scene_no) == SCENE_COTTAGE_MY) { + field_type = mFI_FIELDTYPE2_PLAYER_ROOM; + } + else if (field_id == mFI_FIELD_NPCROOM0) { + field_type = mFI_FIELDTYPE2_NPC_ROOM; + } + else { + field_type = mFI_FIELDTYPE2_ROOM; + } + + Common_Set(field_type, field_type); +} + +static void mFM_PoorTreeBlock(mFM_block_info_c* block, int ut) { + mCoBG_Collision_u* col = (mCoBG_Collision_u*)block->bg_info.collision; + int i; + + for (i = ut; i < UT_TOTAL_NUM; i += UT_X_NUM) { + mCoBG_Change2PoorAttr(col + i); + } +} + +static void mFM_PoorTree() { + mFM_fdinfo_c* field_info = g_fdinfo; + mFM_block_info_c* first_block = field_info->block_info; + mFM_block_info_c* last_block = field_info->block_info; + int block_total; + u8 bx_max; + int i; + + bx_max = field_info->block_x_max; + block_total = field_info->block_x_max * (field_info->block_z_max - 3); + + if (mFI_GET_TYPE(field_info->field_id) == mFI_FIELD_FG && Save_Get(scene_no) == SCENE_FG) { + for (i = field_info->block_x_max; i < block_total; i += bx_max) { + mFM_PoorTreeBlock(first_block + (i + 1), 0); + mFM_PoorTreeBlock(last_block + (i + (bx_max - 2)), UT_X_NUM - 1); + } + } +} + +static void mFM_PoorTreeUnderPlayerBlock() { + mFM_fdinfo_c* field_info = g_fdinfo; + mFM_block_info_c* block_info = field_info->block_info; + int bx_max = field_info->block_x_max; + + if (field_info != NULL && mFI_GET_TYPE(field_info->field_id) == mFI_FIELD_FG && Save_Get(scene_no) == SCENE_FG) { + mCoBG_Collision_u* col = &block_info[bx_max * 3 + 3].bg_info.collision[0][0]; + + if (col != NULL) { + mCoBG_Change2PoorAttr(col + 7); + mCoBG_Change2PoorAttr(col + 8); + mCoBG_Change2PoorAttr(col + (UT_X_NUM + 7)); + mCoBG_Change2PoorAttr(col + (UT_X_NUM + 8)); + } + } +} + +static void mFM_SetFruit_title_demo(int scene) { + if (scene == SCENE_FIELD_TOOL || scene == SCENE_TITLE_DEMO) { + mFI_BlockUtNumtoFGSet(TREE_APPLE_FRUIT, 5, 5, 14, 8); + } +} + +extern void mFM_SetFieldInitData(int bg_disp_num, int bg_disp_size) { + l_bg_disp_num = bg_disp_num; + l_bg_disp_size = bg_disp_size; +} + +extern void mFM_FieldInit(GAME_PLAY* play) { + int bg_disp_num = l_bg_disp_num; + int bg_disp_size = l_bg_disp_size; + int scene = Save_Get(scene_no); + + mFM_LoadBGCommonTex(TRUE, Save_Get(bg_tex_idx)); + if (bg_disp_num > mFM_VISIBLE_BLOCK_NUM) { + bg_disp_num = mFM_VISIBLE_BLOCK_NUM; + } + + g_fdinfo = mFM_MakeField(scene, bg_disp_size, bg_disp_num); + mFI_InitMoveActorBitData(); + mFI_ClearColKeep(); + mFI_InitAreaInfo(); + mFI_InitRegisterBgInfo(); + set_field_type(); + mFM_PoorTree(); + + if (Common_Get(field_type) == mFI_FIELDTYPE2_FG) { + mRF_CheckBeastRoad(); + } + + mFM_PoorTreeUnderPlayerBlock(); + mAGrw_ChangeCedar2Tree(); + mAGrw_RenewalFgItem(Common_GetPointer(time.rtc_time)); + mAGrw_SetXmasTree(); + mFM_SetFruit_title_demo(Save_Get(scene_no)); + + if (scene == SCENE_FG) { + mNpc_SetNpcHomeYpos(); + } + + mNpc_SendRegisteredGoodbyMail(); + Common_Set(floor_idx, mRmTp_GetFloorIdx()); + Common_Set(make_npc2_actor, FALSE); + + if (play->fb_wipe_type == 6) { + if (scene == SCENE_MUSEUM_ENTRANCE) { + mBGMPsComp_museum_status(1); + } + else if (scene == SCENE_MUSEUM_ROOM_PAINTING) { + mBGMPsComp_museum_status(2); + } + else if (scene == SCENE_MUSEUM_ROOM_FISH) { + mBGMPsComp_museum_status(3); + } + else if (scene == SCENE_MUSEUM_ROOM_INSECT) { + mBGMPsComp_museum_status(4); + } + else if (scene == SCENE_MUSEUM_ROOM_FOSSIL) { + mBGMPsComp_museum_status(5); + } + } + else if ( + mFI_GET_TYPE(g_fdinfo->field_id) == mFI_FIELD_PLAYER0_ROOM || + mFI_GET_TYPE(g_fdinfo->field_id) == mFI_FIELD_ROOM0 || + mFI_GET_TYPE(g_fdinfo->field_id) == mFI_FIELD_NPCROOM0 + ) { + if (scene == SCENE_MUSEUM_ENTRANCE) { + mBGMPsComp_scene_mode(15); + mBGMPsComp_museum_status(1); + } + else if (scene == SCENE_MUSEUM_ROOM_PAINTING) { + mBGMPsComp_scene_mode(15); + mBGMPsComp_museum_status(2); + } + else if (scene == SCENE_MUSEUM_ROOM_FISH) { + mBGMPsComp_scene_mode(15); + mBGMPsComp_museum_status(3); + } + else if (scene == SCENE_MUSEUM_ROOM_INSECT) { + mBGMPsComp_scene_mode(15); + mBGMPsComp_museum_status(4); + } + else if (scene == SCENE_MUSEUM_ROOM_FOSSIL) { + mBGMPsComp_scene_mode(15); + mBGMPsComp_museum_status(5); + } + else if (scene == SCENE_LIGHTHOUSE) { + mBGMPsComp_scene_mode(16); + } + else { + if (mEv_CheckFirstIntro() == TRUE) { + mBGMPsComp_scene_mode(10); + } + else { + mBGMPsComp_scene_mode(2); + } + } + } + else if (mFI_GET_TYPE(g_fdinfo->field_id) == mFI_FIELD_FG) { + if (scene != SCENE_TITLE_DEMO) { + if (mEv_CheckFirstIntro() == TRUE) { + mBGMPsComp_scene_mode(9); + } + else if (mEv_CheckGateway() == TRUE) { + mBGMPsComp_scene_mode(8); + } + else { + mBGMPsComp_scene_mode(1); + } + } + } + else if (scene == SCENE_PLAYERSELECT || scene == SCENE_PLAYERSELECT_2 || scene == SCENE_PLAYERSELECT_3 || scene == SCENE_PLAYERSELECT_SAVE) { + mBGMPsComp_scene_mode(3); + } + else if (scene == SCENE_START_DEMO || scene == SCENE_START_DEMO2 || scene == SCENE_START_DEMO3) { + mBGMPsComp_scene_mode(4); + } + else { + mBGMPsComp_scene_mode(0); + } +} + +extern void mFM_Field_dt() { + mFM_fdinfo_c* field_info = g_fdinfo; + mFM_block_info_c* block_info; + int max; + int i; + + Common_Set(last_field_id, field_info->field_id); + + if (mFI_GET_TYPE(field_info->field_id) == mFI_FIELD_ROOM0 && mSc_IS_SCENE_MUSEUM_ROOM(Common_Get(last_scene_no)) && !mSc_IS_SCENE_MUSEUM_ROOM(Save_Get(scene_no))) { + mBGMPsComp_museum_status(0); + } + + if (field_info->field_id != mFI_FIELD_FG && mFI_GET_TYPE(field_info->field_id) != mFI_FIELD_PLAYER0_ROOM) { + if (mFI_GET_TYPE(field_info->field_id) == mFI_FIELD_NPCROOM0) { + if (field_info->fg2_p[0] != NULL) { + zelda_free(field_info->fg2_p[0]); + } + } + else { + block_info = field_info->block_info; + max = field_info->block_x_max * field_info->block_z_max; + + for (i = max; i != 0; i--) { + zelda_free(block_info->fg_info.items_p); + block_info++; + } + } + } + + zelda_free(field_info->fg2_p); + zelda_free(field_info->block_info); + + for (i = 0; i < mFM_VISIBLE_BLOCK_NUM; i++) { + zelda_free(field_info->bg_display_list_p[i]); + } + + zelda_free(field_info); + g_fdinfo = NULL; + mFI_InitRegisterBgInfo(); +} + +static void mFM_SetBlockKind(u8* type_p, int* kind_p, mFM_combination_c* combi_p, mFM_combo_info_c* combi_info_p, int count) { + for (count; count != 0; count--) { + int combi_type = combi_p[0].combination_type; + + type_p[0] = combi_info_p[combi_type].type; + kind_p[0] = mRF_Type2BlockInfo(combi_info_p[combi_type].type); + + type_p++; + kind_p++; + combi_p++; + } +} + +extern void mFM_SetBlockKindLoadCombi() { + mFM_SetBlockKind(g_block_type_p, g_block_kind_p, Save_Get(combi_table[0]), data_combi_table, BLOCK_TOTAL_NUM); +} + +static void mFM_SetIslandFg(mFM_combo_info_c* combi_info_p, mFM_fg_data_c** sorted_fg_data, int* island_x_blocks) { + int i; + + for (i = 0; i < mISL_FG_BLOCK_X_NUM; i++) { + int fg_id = combi_info_p[Save_Get(combi_table[mISL_BLOCK_Z][island_x_blocks[0]]).combination_type].fg_id; + if (sorted_fg_data[fg_id] == NULL) { + break; + } + + if (fg_id >= 0 && fg_id < mFM_FG_NUM) { + mFM_FgUtDataSet(Save_Get(island).fgblock[0][i].items[0], sorted_fg_data[fg_id]->items[0]); + } + + island_x_blocks++; + } +} + +static mFM_combination_c l_combiID[BLOCK_TOTAL_NUM] = { + { 209, 1 }, { 201, 1 }, { 201, 1 }, { 201, 1 }, { 202, 1 }, { 201, 1 }, { 210, 1 }, + { 205, 1 }, { 172, 1 }, { 222, 1 }, { 189, 1 }, { 176, 1 }, { 225, 1 }, { 208, 1 }, + { 203, 1 }, { 159, 1 }, { 5, 1 }, { 215, 1 }, { 93, 1 }, { 37, 1 }, { 206, 1 }, + { 203, 1 }, { 45, 0 }, { 101, 0 }, { 96, 1 }, { 152, 1 }, { 108, 0 }, { 207, 0 }, + { 204, 0 }, { 42, 0 }, { 163, 0 }, { 64, 0 }, { 164, 0 }, { 213, 0 }, { 206, 0 }, + { 203, 0 }, { 157, 0 }, { 217, 0 }, { 127, 0 }, { 38, 0 }, { 160, 0 }, { 206, 0 }, + { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, + { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, + { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, + { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 }, { 196, 0 } +}; + +u8* g_block_type_p = l_block_type; +int* g_block_kind_p = l_block_kind; + +extern void mFM_InitFgCombiSaveData(GAME* game) { + GameAlloc* game_alloc_p = NULL; + void* gamealloc_data_p; + mFM_fg_data_c* fg_data_p; + mFM_combo_info_c* combo_info_p; + mFM_combination_c* combi_table; + mFM_fg_data_c** sorted_fg_data_list; + size_t fg_datasize; + size_t fg_datasize_align; + mFM_fg_c* fg_block; + int fg_id; + mFM_fg_c* fg_block_p; + int fg_data_num; + mFM_fg_data_c* src_data; + int bz; + int bx; + int total_fg_block; + + combi_table = Save_Get(combi_table[0]); + fg_block = Save_Get(fg[0]); + total_fg_block = 0; + + if (game != NULL) { + game_alloc_p = &game->gamealloc; + } + + combo_info_p = data_combi_table; + mRF_MakeRandomField(l_combiID, combo_info_p, data_combi_table_number, game); + mFM_SetBlockKind(g_block_type_p, g_block_kind_p, l_combiID, combo_info_p, BLOCK_TOTAL_NUM); + mFM_SetCombiTable(combi_table, l_combiID, BLOCK_X_NUM, BLOCK_Z_NUM); + fg_datasize = JW_GetResSizeFileNo(RESOURCE_FGDATA); + fg_datasize_align = ALIGN_NEXT(fg_datasize, 32); + + if (game != NULL) { + gamealloc_data_p = gamealloc_malloc(game_alloc_p, fg_datasize_align + 32); + fg_data_p = (mFM_fg_data_c*)(ALIGN_NEXT((u32)gamealloc_data_p, 32)); + } + else { + fg_data_p = (mFM_fg_data_c*)zelda_malloc_align(fg_datasize_align, 32); + } + + fg_data_num = fg_datasize / sizeof(mFM_fg_data_c); + _JW_GetResourceAram(JW_GetAramAddress(RESOURCE_FGDATA), (u8*)fg_data_p, fg_datasize_align); + + if (game != NULL) { + sorted_fg_data_list = (mFM_fg_data_c**)gamealloc_malloc(game_alloc_p, mFM_FG_NUM * sizeof(mFM_fg_data_c*)); + } + else { + sorted_fg_data_list = (mFM_fg_data_c**)zelda_malloc(mFM_FG_NUM * sizeof(mFM_fg_data_c*)); + } + + mFM_SortFGData(sorted_fg_data_list, fg_data_p, mFM_FG_NUM, fg_data_num, 0); + + fg_block_p = fg_block; + for (bz = 0; bz < mISL_BLOCK_Z; bz++) { + for (bx = 0; bx < BLOCK_X_NUM; bx++, combi_table++) { + if (bz > 0 && bz < (BLOCK_Z_NUM - 3) && bx > 0 && bx < (BLOCK_X_NUM - 1)) { + if (total_fg_block >= FG_BLOCK_TOTAL_NUM) { + break; + } + + fg_id = combo_info_p[combi_table[0].combination_type].fg_id; + if (fg_block_p == NULL) { + break; + } + + src_data = sorted_fg_data_list[fg_id]; + if (src_data == NULL) { + break; + } + + if (fg_id >= 0 && fg_id < mFM_FG_NUM) { + mFM_FgUtDataSet(fg_block_p->items[0], src_data->items[0]); + } + + total_fg_block++; + fg_block_p++; + + if (total_fg_block >= FG_BLOCK_TOTAL_NUM) { + break; + } + } + } + } + + { + int island_x_blocks[2]; + + mFI_GetIslandBlockNumX(island_x_blocks); + mFM_SetIslandFg(combo_info_p, sorted_fg_data_list, island_x_blocks); + } + + if (game != NULL) { + gamealloc_free(game_alloc_p, sorted_fg_data_list); + gamealloc_free(game_alloc_p, gamealloc_data_p); + } + else { + zelda_free(sorted_fg_data_list); + zelda_free(fg_data_p); + } +} + +static int mFM_AddIdx(int* idx, int min, int max) { + int res = FALSE; + + (*idx)++; + + if (*idx >= max) { + *idx = min; + res = TRUE; + } + + return res; +} + +static mActor_name_t mFM_GetNextReseve(int set, int set_idx, int river_idx, u32 block_kind, int force) { + mActor_name_t reserve; + + if (force == FALSE && ((block_kind & mRF_BLOCKKIND_RIVER) == mRF_BLOCKKIND_RIVER)) { + set = 0; + set_idx = river_idx; + } + + reserve = set * 3 + set_idx; + reserve += SIGN00; + return reserve; +} + +static void mFM_RenewalReserveBlock(mActor_name_t* items, int* set, int* set_idx, int* river_idx, u32 block_kind) { + int force = FALSE; + int i; + + for (i = 0; i < UT_TOTAL_NUM; i++) { + if (items[0] == SIGN00) { + items[0] = mFM_GetNextReseve(*set, *set_idx, *river_idx, block_kind, force); + + if (force == FALSE && (block_kind & mRF_BLOCKKIND_RIVER) == mRF_BLOCKKIND_RIVER) { + mFM_AddIdx(river_idx, 0, 3); + force = TRUE; + } + else { + if (mFM_AddIdx(set, 1, 7) == TRUE) { + mFM_AddIdx(set_idx, 0, 3); + } + } + } + + items++; + } +} + +extern void mFM_RenewalReserve() { + int set = 1; + int set_idx = 0; + int river_idx = 0; + mFM_fg_c* fg_block = Save_Get(fg[1]); + + int bx; + int bz; + + for (bz = 1; bz < FG_BLOCK_Z_NUM; bz++) { + for (bx = 0; bx < FG_BLOCK_X_NUM; bx++) { + mFM_RenewalReserveBlock(fg_block->items[0], &set, &set_idx, &river_idx, g_block_kind_p[(bz + 1) * BLOCK_X_NUM + (bx + 1)]); + fg_block++; + } + } +} + +extern mActor_name_t mFM_GetReseveName(int bx, int bz) { + mActor_name_t reserve_name = SIGN03; + int reserve_bit_field = 0; + u8 reserve_complete_sets_bit_field = 0; + int free_signs; + int set = 0; + int reserve_noncomplete_sets = 0; + int set_idx = 0; + int i; + + if (bx > 0 && bx < (BLOCK_X_NUM - 1) && bz > 0 && bz < (BLOCK_Z_NUM - 3)) { + u32 block_kind = g_block_kind_p[(bz * BLOCK_X_NUM) + bx]; + mActor_name_t* items = Save_Get(fg[bz - 1][bx - 1]).items[0]; + + for (i = 0; i < UT_TOTAL_NUM; i++) { + if (mNT_IS_RESERVE(items[0])) { + reserve_bit_field |= (1 << (items[0] - SIGN00)); + } + + items++; + } + + for (i = 0; i < 7; i++) { + u32 shift = i * 3; + if (((reserve_bit_field >> shift) & 0b111) == 0b111) { + reserve_complete_sets_bit_field |= (1 << i); + } + + if (((reserve_bit_field >> (i * 3)) & 0b111) != 0b111) { + reserve_noncomplete_sets++; + } + } + + /* Mark river set as unavailable */ + if ( + (block_kind & mRF_BLOCKKIND_RIVER) != mRF_BLOCKKIND_RIVER && + ((reserve_complete_sets_bit_field & 1) == 0) + ) { + reserve_complete_sets_bit_field |= 1; + reserve_noncomplete_sets--; + } + + /* Select one of the 7 sets of signs */ + { + int selected_set = RANDOM(reserve_noncomplete_sets); + + for (i = 0; i < 7; i++) { + if (((reserve_complete_sets_bit_field >> i) & 1) == 0) { + if (selected_set <= 0) { + set = i; + break; + } + else { + selected_set--; + } + } + } + } + + /* Count used signs in selected set */ + { + int subset_start = set * 3; + int idx; + int j; + int selected_idx; + free_signs = 0; + + for (i = subset_start; i < subset_start + 3; i++) { + if (((reserve_bit_field >> i) & 1) == 0) { + free_signs++; + } + } + + /* Select random free sign in set */ + selected_idx = RANDOM(free_signs); + idx = 0; + + for (j = subset_start; j < subset_start + 3; j++) { + if (((reserve_bit_field >> j) & 1) == 0) { + if (selected_idx <= 0) { + idx = j; + break; + } + else { + selected_idx--; + } + } + } + + reserve_name = SIGN00 + idx; + } + } + + return reserve_name; +} + +extern void mFM_toSummer() { + mTM_set_season_com(7); + + if (g_fdinfo != NULL) { + mFM_LoadBGCommonTex(FALSE, Save_Get(island).grass_tex_type); + mFM_SetFieldPal(&g_fdinfo->field_palette); + } +} + +extern void mFM_returnSeason() { + mTM_set_season(); + + if (g_fdinfo != NULL) { + mFM_LoadBGCommonTex(FALSE, Save_Get(bg_tex_idx)); + mFM_SetFieldPal(&g_fdinfo->field_palette); + } +} + +extern void mFM_RestoreIslandBG(int* island_x_blocks, int bx_num) { + mFM_combination_c* combi_p; + + mFM_block_info_c* block_info; + mFM_bg_data_c** sorted_bg_data; + mFM_bg_data_c* bg_data_p = data_bgd; + mFM_combo_info_c* combo_info_p = data_combi_table; + + if (mFI_CheckFieldData() && Save_Get(scene_no) == SCENE_FG) { + block_info = mFI_GetBlockTopP(); + + if (block_info != NULL) { + int i; + sorted_bg_data = (mFM_bg_data_c**)zelda_malloc(mFM_BG_ID_MAX * sizeof(mFM_bg_data_c*)); + + if (sorted_bg_data != NULL) { + mFM_SortBGData(sorted_bg_data, bg_data_p, data_bgd_number); + combi_p = Save_Get(combi_table[mISL_BLOCK_Z] + island_x_blocks[0]); + block_info += mFI_GetBlockNum(island_x_blocks[0], mISL_BLOCK_Z); + + for (i = 0; i < bx_num; i++) { + int bg_id = combo_info_p[combi_p[0].combination_type].bg_id; + + if (bg_id <= mFM_BG_ID_MAX && sorted_bg_data[bg_id] != NULL) { + mFM_SetBG(&block_info->bg_info, sorted_bg_data[bg_id], combi_p->height, block_info->bg_info.block_type, bg_id, island_x_blocks[i], mISL_BLOCK_Z); + } + + block_info++; + combi_p++; + } + + if (sorted_bg_data != NULL) { + zelda_free(sorted_bg_data); + } + } + } + } +} + +extern void mFM_SetIslandNpcRoomData(GAME* game, int malloc_flag) { + GameAlloc* gamealloc = NULL; + mFM_fg_data_c** sorted_fgnpc_data_list; + void* gamealloc_data_p; + mFM_fg_data_c* fgnpc_data_p; + size_t fgnpc_size = JW_GetResSizeFileNo(RESOURCE_FGNPCDATA); + size_t fgnpc_size_align = ALIGN_NEXT(fgnpc_size, 32); + int fgnpc_data_num; + + if (game != NULL) { + gamealloc = &game->gamealloc; + } + + if (malloc_flag == TRUE) { + fgnpc_data_p = (mFM_fg_data_c*)zelda_malloc_align(fgnpc_size_align, 32); + } + else if (game != NULL) { + gamealloc_data_p = gamealloc_malloc(gamealloc, fgnpc_size_align + 32); + fgnpc_data_p = (mFM_fg_data_c*)(ALIGN_NEXT((u32)gamealloc_data_p, 32)); + } + else { + fgnpc_data_p = (mFM_fg_data_c*)zelda_malloc_align(fgnpc_size_align, 32); + } + + + if (fgnpc_data_p != NULL) { + fgnpc_data_num = fgnpc_size / sizeof(mFM_fg_data_c); + _JW_GetResourceAram(JW_GetAramAddress(RESOURCE_FGNPCDATA), (u8*)fgnpc_data_p, fgnpc_size_align); + + if (malloc_flag == TRUE) { + sorted_fgnpc_data_list = (mFM_fg_data_c**)zelda_malloc(mFM_FG_NPC_NUM * sizeof(mFM_fg_data_c*)); + } + else if (game != NULL) { + sorted_fgnpc_data_list = (mFM_fg_data_c**)gamealloc_malloc(gamealloc, mFM_FG_NPC_NUM * sizeof(mFM_fg_data_c*)); + } + else { + sorted_fgnpc_data_list = (mFM_fg_data_c**)zelda_malloc(mFM_FG_NPC_NUM * sizeof(mFM_fg_data_c*)); + } + + if (sorted_fgnpc_data_list != NULL) { + mFM_SortFGData(sorted_fgnpc_data_list, fgnpc_data_p, mFM_FG_NPC_NUM, fgnpc_data_num, mFM_FG_NPC_START); + mNpc_IslandNpcRoomDataSet(sorted_fgnpc_data_list, mFM_FG_NPC_START); + + if (sorted_fgnpc_data_list != NULL) { + if (malloc_flag == TRUE) { + zelda_free(sorted_fgnpc_data_list); + } + else if (game != NULL) { + gamealloc_free(gamealloc, sorted_fgnpc_data_list); + } + else { + zelda_free(sorted_fgnpc_data_list); + } + } + } + + /* @BUG - memory leak if gamealloc malloc path is not taken above */ + #ifndef BUGFIXES + if (gamealloc_data_p != NULL) { + #else + if (fgnpc_data_p != NULL) { // this is guaranteed to exist in all malloc paths + #endif + if (malloc_flag == TRUE) { + zelda_free(fgnpc_data_p); + } + else if (game != NULL) { + gamealloc_free(gamealloc, gamealloc_data_p); + } + else { + zelda_free(fgnpc_data_p); + } + } + } +} diff --git a/tools/converters/pal16dis.py b/tools/converters/pal16dis.py new file mode 100644 index 00000000..65d92313 --- /dev/null +++ b/tools/converters/pal16dis.py @@ -0,0 +1,26 @@ +from argparse import ArgumentParser +import struct + +def convert_binary_to_vtx_c_source(src_path, dest_path): + # Load data + with open(src_path, "rb") as binary_file, open(dest_path, "w") as c_file: + while True: + chunk = binary_file.read(2) # 2 bytes for each 16-bit palette entry + + if len(chunk) < 2: + break + + pal = struct.unpack(">H", chunk[0:2]) # 2 bytes + + c_file.write(f"{hex(pal[0])}, ") + +def main(): + parser = ArgumentParser(description="Converts a binary file to an array of u16 type") + parser.add_argument("src_path", type=str, help="Binary source file path") + parser.add_argument("dest_path", type=str, help="Destination C include file path") + + args = parser.parse_args() + convert_binary_to_vtx_c_source(args.src_path, args.dest_path) + +if __name__ == '__main__': + main() \ No newline at end of file