From b92c029f0da03e96afb61800ad268a98db960ff5 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Mon, 24 Jul 2023 14:38:35 -0400 Subject: [PATCH] Implement & link m_start_data_init --- config/rel_slices.yml | 4 + include/m_common_data.h | 26 +- include/m_event.h | 95 +++++++ include/m_field_info.h | 2 + include/m_field_make.h | 4 + include/m_island.h | 1 + include/m_mark_room.h | 17 ++ include/m_mask_cat.h | 24 ++ include/m_melody.h | 16 ++ include/m_name_table.h | 12 +- include/m_npc.h | 2 + include/m_npc_walk.h | 61 +++++ include/m_play.h | 3 +- include/m_quest.h | 6 + include/m_room_type.h | 1 + include/m_start_data_init.h | 1 + include/m_string.h | 4 + include/m_train_control.h | 2 +- rel/m_mail_password_check.c | 2 +- rel/m_start_data_init.c | 525 ++++++++++++++++++++++++++++++++++++ rel/m_train_control.c | 2 +- 21 files changed, 793 insertions(+), 17 deletions(-) create mode 100644 include/m_mark_room.h create mode 100644 include/m_mask_cat.h create mode 100644 include/m_melody.h create mode 100644 include/m_npc_walk.h create mode 100644 rel/m_start_data_init.c diff --git a/config/rel_slices.yml b/config/rel_slices.yml index eab88d2d..00da5330 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -121,6 +121,10 @@ m_rcp.c: .bss: [0x8129F2E8, 0x8129F2F0] m_room_type/mRmTp_FtrItemNo2FtrIdx.c: .text: [0x803E7878, 0x803E78BC] +m_start_data_init.c: + .text: [0x803EDEC0, 0x803EED30] + .rodata: [0x806432E0, 0x806432F0] + .data: [0x8065DD70, 0x8065DDD0] m_string.c: .text: [0x803EED30, 0x803EF290] .bss: [0x8129F320, 0x8129F400] diff --git a/include/m_common_data.h b/include/m_common_data.h index 2d46b1d8..294fa07f 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -24,7 +24,10 @@ #include "m_field_assessment.h" #include "m_mushroom.h" #include "m_clip.h" +#include "m_event.h" #include "m_scene.h" +#include "m_npc_walk.h" +#include "m_mask_cat.h" #ifdef __cplusplus extern "C" { @@ -78,7 +81,8 @@ typedef struct Save_s { /* 0x020330 */ AnmPersonalID_c last_removed_animal_id; /* ID of last villager who left town */ /* 0x020340 */ Shop_c shop; /* Nook's shop */ /* 0x020480 */ Kabu_price_c kabu_price_schedule; /* Stalk Market info */ - /* 0x020498 */ u8 _tmp3[0x1F0]; /* saved events go here, but have a lot of structs in a union so holding off */ + /* 0x020498 */ mEv_event_save_c event_save_data; + /* 0x020554 */ u8 _20554[0x20688 - 0x20554]; /* active event data? */ /* 0x020688 */ mActor_name_t fruit; /* town fruit type */ /* 0x02068A */ u8 house_arrangement; /* 2 bits for each player for the # of house they own */ /* 0x02068B */ u8 num_statues; /* number of statues built for players who have paid off their debts */ @@ -119,7 +123,8 @@ typedef struct Save_s { /* 0x022500 */ u8 _tmp7[0x22528 - 0x22500]; /* 0x022528 */ OSTime time_delta; /* time delta against GC RTC */ /* 0x022540 */ Island_c island; /* island data */ - /* 0x023E40 */ u8 _tmp9[0x320]; + /* 0x023E40 */ u8 _23E40[0x23F20 - 0x23E40]; + /* 0x023F20 */ MaskCat_c mask_cat; /* 0x024160 */ Anmret_c return_animal; /* information about villager which moved back in to your town after moving to someone else's town */ /* 0x02416C */ u8 _tmp10[0x24174 - 0x2416C]; /* 0x024174 */ u8 insect_term; /* current insect term idx */ @@ -127,9 +132,12 @@ typedef struct Save_s { /* 0x024176 */ u8 gyoei_term; /* current fish term idx */ /* 0x024177 */ u8 gyoei_term_transition_offset; /* days offset from end of term to begin transition */ /* 0x024178 */ mFAs_GoodField_c good_field; /* field assessment last info */ - /* 0x024184 */ u8 _tmp11[0x241A0 - 0x24184]; + /* 0x024184 */ u8 bg_tex_idx; /* Grass type */ + /* 0x024185 */ u8 _24185[0x2418A - 0x24185]; + /* 0x02418A */ u8 town_day; + /* 0x02418B */ u8 _2418B[0x241A0 - 0x2418B]; /* 0x0241A0 */ lbRTC_time_c saved_auto_nwrite_time; /* save data notice time used for fishing tourney results? */ - /* 0x0241A8 */ u8 _tmp12[0x26000 - 0x241A8]; + /* 0x0241A8 */ u8 _241A8[0x26000 - 0x241A8]; } Save_t; typedef union save_u { @@ -151,7 +159,8 @@ typedef struct common_data_s { /* 0x02613C */ Private_c* now_private; /* 0x026140 */ mHm_hs_c* now_home; /* 0x026144 */ u8 map_flag; - /* 0x026145 */ u8 tmp0[0x2614D - 0x26145]; + /* 0x026145 */ u8 fish_location; + /* 0x026146 */ u8 tmp0[0x2614D - 0x26146]; /* 0x02614D */ u8 transFadeDuration; /* 0x02614E */ u8 transWipeSpeed; /* 0x02614F */ u8 wipeType; /* maybe unused? */ @@ -171,9 +180,12 @@ typedef struct common_data_s { /* 0x02666C */ s16 weather; /* 0x02666E */ s16 weather_intensity; /* 0x026670 */ lbRTC_time_c weather_time; - /* 0x026678 */ u8 _26678[0x266A4 - 0x26678]; + /* 0x026678 */ u8 _26678[0x2669C - 0x26678]; + /* 0x02669C */ mQst_not_saved_c quest; /* 0x0266A4 */ int scene_from_title_demo; /* next scene to be loaded when title demo finishes */ - /* 0x0266A8 */ u8 _266A8[0x2852C - 0x266A8]; + /* 0x0266A8 */ u8 _266A8[0x267A8 - 0x266A8]; + /* 0x0267A8 */ mNpc_walk_c npc_walk; + /* 0x026838 */ u8 _26838[0x2852C - 0x26838]; /* 0x02852C */ s16 money_power; /* 0x02852E */ s16 goods_power; /* 0x028530 */ Door_data_c door_data; /* misc door data */ diff --git a/include/m_event.h b/include/m_event.h index 44f6e462..cdedc6c6 100644 --- a/include/m_event.h +++ b/include/m_event.h @@ -3,6 +3,8 @@ #include "types.h" #include "libu64/gfxprint.h" +#include "m_personal_id.h" +#include "m_private.h" #include "m_time.h" #ifdef __cplusplus @@ -140,6 +142,95 @@ typedef struct ghost_common_s { u8 _0C[0x2C - 0x0C]; } mEv_gst_common_c; +#define mEv_DESGINER_NUM 3 + +typedef struct kabu_peddler_event_s { + PersonalID_c spoken_pids[TOTAL_PLAYER_NUM]; +} mEv_kabu_peddler_c; + +typedef struct dozaemon_event_s { + u32 flags; +} mEv_dozaemon_c; + +typedef union { + mEv_kabu_peddler_c kabu_peddler; + mEv_dozaemon_c dozaemon; +} mEv_weekly_u; + +typedef struct bargin_event_s { + lbRTC_time_c start_time; + lbRTC_time_c end_time; + mActor_name_t items[5]; + int kind; +} mEv_bargin_c; + +typedef struct designer_event_s { + PersonalID_c pids[mEv_DESGINER_NUM]; + int used; + mActor_name_t gifted_cloths[mEv_DESGINER_NUM]; +} mEv_designer_c; + +typedef struct broker_event_s { + PersonalID_c pid[2]; + lbRTC_time_c end_time; + int used; + mActor_name_t sold_items[2]; + mActor_name_t items[3]; +} mEv_broker_c; + +typedef struct artist_event_s { + PersonalID_c pids[2]; + int used; + mActor_name_t walls[2]; +} mEv_artist_c; + +typedef struct arabian_event_s { + int used; + mActor_name_t carpet; +} mEv_arabian_c; + +typedef struct gypsy_event_s { + int _00; + int block_z; + int block_x; + int ut_z; + int ut_x; +} mEv_gypsy_c; + +typedef union { + mEv_bargin_c bargin; + mEv_designer_c designer; + mEv_broker_c broker; + mEv_artist_c artist; + mEv_arabian_c arabian; + mEv_gypsy_c gypsy; +} mEv_special_u; + +typedef struct special_event_s { + lbRTC_time_c scheduled; + u32 type; + mEv_special_u; +} mEv_special_c; + +typedef struct save_event_data_s { + mEv_special_c special; + mEv_weekly_u weekly; + u32 flags; +} mEv_event_save_c; + +typedef struct event_s { + u8 day; + u8 hour; + u8 _02; + u8 state; + u8 month; + u8 year; + s16 changed_num; + int block_z; + int block_x; + int unused[5]; +} Event_c; + extern int mEv_CheckFirstJob(); extern int mEv_CheckFirstIntro(); extern int mEv_CheckArbeit(); @@ -148,10 +239,14 @@ extern int mEv_check_status(int event, s16 status); extern s8* mEv_get_common_area(int type, s8 id); extern int mEv_ArbeitPlayer(u32 player_no); extern u16 mEv_get_special_event_type(); +mEv_ClearEventSaveInfo(mEv_event_save_c* event_save_data); extern int mEv_weekday2day(lbRTC_month_t month, int week_type, lbRTC_weekday_t weekday); extern void mEv_ClearEventInfo(); +extern void mEv_init(Event_c* event); +extern void mEv_2nd_init(Event_c* event); + extern int mEv_CheckTitleDemo(); extern void mEv_SetTitleDemo(int titledemo_no); diff --git a/include/m_field_info.h b/include/m_field_info.h index a2577cbe..6a9891ab 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -151,6 +151,8 @@ extern int mFI_BkNum2WposXZ(f32* wpos_x, f32* wpos_z, int block_x, int block_z); extern void mFI_SetBearActor(GAME_PLAY* play, xyz_t wpos, int update_before_block_table); extern void mFI_FieldMove(xyz_t player_wpos); extern int mFI_search_unit_around(xyz_t* wpos, mActor_name_t item); +extern void mFI_BlockDepositOFF(u16* deposit, int ut_x, int ut_z); +extern void mFI_PullTanukiPathTrees(); 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 28997696..6f8b19d7 100644 --- a/include/m_field_make.h +++ b/include/m_field_make.h @@ -4,6 +4,7 @@ #include "types.h" #include "m_actor_type.h" #include "libforest/gbi_extensions.h" +#include "game_h.h" #ifdef __cplusplus extern "C" { @@ -89,6 +90,9 @@ typedef struct field_info_s { extern u8* g_block_type_p; extern int* g_block_kind_p; +extern void mFM_DecideBgTexIdx(u8* bg_tex_idx); +extern void mFM_InitFgCombiSaveData(GAME* game); + #ifdef __cplusplus } #endif diff --git a/include/m_island.h b/include/m_island.h index 5b7e83c7..a3afee99 100644 --- a/include/m_island.h +++ b/include/m_island.h @@ -44,6 +44,7 @@ typedef struct island_s { } Island_c; extern void mISL_ClearKeepIsland(); +extern void mISL_init(Island_c* island); #ifdef __cplusplus } diff --git a/include/m_mark_room.h b/include/m_mark_room.h new file mode 100644 index 00000000..e0da5dcd --- /dev/null +++ b/include/m_mark_room.h @@ -0,0 +1,17 @@ +#ifndef M_MARK_ROOM_H +#define M_MARK_ROOM_H + +#include "types.h" +#include "game_h.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mMkRm_MarkRoom(GAME* game); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_mask_cat.h b/include/m_mask_cat.h new file mode 100644 index 00000000..0fc4ce58 --- /dev/null +++ b/include/m_mask_cat.h @@ -0,0 +1,24 @@ +#ifndef M_MASK_CAT_H +#define M_MASK_CAT_H + +#include "types.h" +#include "m_needlework.h" +#include "m_time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct mask_cat_s { + mNW_original_design_c design; + u8 palette_no; + u8 cloth_no; + u8 talk_idx; + lbRTC_time_c time; +} MaskCat_c; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_melody.h b/include/m_melody.h new file mode 100644 index 00000000..906b9752 --- /dev/null +++ b/include/m_melody.h @@ -0,0 +1,16 @@ +#ifndef M_MELODY_H +#define M_MELODY_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mMld_SetDefaultMelody(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_name_table.h b/include/m_name_table.h index e32325b6..635b0a24 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -331,6 +331,11 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define FTR_PAPA_BEAR_NORTH 0x10EA #define FTR_PAPA_BEAR_WEST 0x10EB +#define FTR_BIRTHDAY_CAKE 0x11FC +#define FTR_BIRTHDAY_CAKE_EAST 0x11FD +#define FTR_BIRTHDAY_CAKE_NORTH 0x11FE +#define FTR_BIRTHDAY_CAKE_WEST 0x11FF + #define FTR_DRACAENA 0x13B0 #define FTR_DRACAENA_EAST 0x13B1 #define FTR_DRACAENA_NORTH 0x13B2 @@ -368,11 +373,6 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define FTR_UMBRELLA31_WEST 0x1D87 -#define FTR_BIRTHDAY_CAKE 0x11FC -#define FTR_BIRTHDAY_CAKE_EAST 0x11FD -#define FTR_BIRTHDAY_CAKE_NORTH 0x11FE -#define FTR_BIRTHDAY_CAKE_WEST 0x11FF - #define FTR_TAPEDECK 0x1E58 #define FTR_PIGGY_BANK 0x1FAC @@ -884,7 +884,7 @@ extern int mNT_check_unknown(mActor_name_t item_no); #define FTR_ORANGEBOX 0x30F8 -#define FTR_COLLEGERULE_SOUTH 0x30FC +#define FTR_COLLEGERULE 0x30FC #define FTR_CALLIGRAPHY_PAD_WEST 0x313B diff --git a/include/m_npc.h b/include/m_npc.h index 2732cc82..1418b6bf 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -208,6 +208,8 @@ extern void mMl_set_mail_name_npcinfo(Mail_nm_c* mail_name, AnmPersonalID_c* anm extern int mNpc_ReceiveHPMail(Mail_c* hp_mail); extern void mNpc_SendMailtoNpc(Mail_c* mail); extern void mNpc_SetNpcinfo(ACTOR* actor, s8 npc_info_idx); +extern void mNpc_InitNpcAllInfo(int malloc_flag); +extern void mNpc_SetRemoveAnimalNo(u8* remove_animal_no, Animal_c* animals, int remove_no); extern void mNpc_PrintRemoveInfo(gfxprint_t* gfxprint); extern void mNpc_PrintFriendship_fdebug(gfxprint_t* gfxprint); diff --git a/include/m_npc_walk.h b/include/m_npc_walk.h new file mode 100644 index 00000000..332b2264 --- /dev/null +++ b/include/m_npc_walk.h @@ -0,0 +1,61 @@ +#ifndef M_NPC_WALK_H +#define M_NPC_WALK_H + +#include "types.h" +#include "m_npc_personal_id.h" +#include "m_npc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define mNpcW_GET_WALK_NUM(x) (int)((x) / 3) +#define mNpcW_MAX mNpcW_GET_WALK_NUM(ANIMAL_NUM_MAX) + +typedef struct goal_data_s { + u8* types; + u8 count; + int end_time; +} mNpcW_GoalData_c; + +typedef struct goal_data_table_s { + mNpcW_GoalData_c* data_p; + int count; +} mNpc_GoalDataTable_c; + +enum { + mNpcW_GOAL_SHRINE, /* Shrine/Wishing Well acre */ + mNpcW_GOAL_HOME, /* Randomly selected acre with a villager house */ + mNpcW_GOAL_ALONE, /* Randomly selected acre with no other animals in it */ + mNpcW_GOAL_MY_HOME, /* Acre containing the villager's house */ + + mNpcW_GOAL_NUM +}; + +typedef struct npc_walk_appear_s { + u8 state; + u8 target_direction; +} mNpcW_appear_c; + +typedef struct npc_walk_information_s { + AnmPersonalID_c id; + int idx; + u8 state; + u8 goal_type; + u8 goal_block_x; + u8 goal_block_z; + mNpcW_appear_c appear_info; +} mNpcW_info_c; + +typedef struct npc_walk_s { + mNpcW_info_c info[mNpcW_MAX]; + u16 used_idx_bitfield; + u8 used_info_num; + u8 info_max; +} mNpc_walk_c; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_play.h b/include/m_play.h index 009ce773..efbeeddf 100644 --- a/include/m_play.h +++ b/include/m_play.h @@ -11,6 +11,7 @@ #include "m_lights.h" #include "m_pause.h" #include "m_field_info.h" +#include "m_event.h" #include "m_fbdemo_wipe.h" #include "m_collision_obj.h" #include "m_play_h.h" @@ -53,7 +54,7 @@ struct game_play_s { /* 0x20A0 */ s16* ctrl_actor_data; /* 0x20A4 */ s16* obj_bank_data; /* 0x20A8 */ int _20A8; - /* 0x20AC */ u8 _20AC[0x20D0 - 0x20AC]; + /* 0x20AC */ Event_c event; /* 0x20D0 */ u8 fb_fade_type; /* 0x20D1 */ u8 fb_wipe_type; /* 0x20D2 */ u8 fb_mode; diff --git a/include/m_quest.h b/include/m_quest.h index 551ce6af..f99cc138 100644 --- a/include/m_quest.h +++ b/include/m_quest.h @@ -113,6 +113,12 @@ typedef struct quest_errand_s { /* 0x2C */ mQst_errand_info_u info; /* errand type-specific data */ } mQst_errand_c; +/* 'Not Saved' Quest */ +typedef struct not_saved_quest_s { + int work; + u8 h; +} mQst_not_saved_c; + extern void mQst_PrintQuestInfo(gfxprint_t* gfxprint); extern void mQst_ClearGrabItemInfo(); diff --git a/include/m_room_type.h b/include/m_room_type.h index d5c7c077..abb72659 100644 --- a/include/m_room_type.h +++ b/include/m_room_type.h @@ -109,5 +109,6 @@ extern int mRmTp_GetFurnitureData(mActor_name_t ftr, int ut_x, int ut_z, mRmTp_F extern int mRmTp_FurnitureIdx2FurnitureKind(int ftr_idx); extern int mRmTp_PleaseDrawLightSwitch(); extern mActor_name_t mRmTp_Item1ItemNo2FtrItemNo_AtPlayerRoom(mActor_name_t item_no, int flag); +extern void mRmTp_SetDefaultLightSwitchData(int state); #endif \ No newline at end of file diff --git a/include/m_start_data_init.h b/include/m_start_data_init.h index e06b302a..6805ec08 100644 --- a/include/m_start_data_init.h +++ b/include/m_start_data_init.h @@ -27,6 +27,7 @@ enum { extern void mSDI_StartInitAfter(GAME* game, int renewal_reserve_flag, int malloc_flag); extern int mSDI_StartInitBefore(GAME* game, int player_no, int init_mode, int malloc_flag); +extern int mSDI_StartDataInit(GAME* game, int player_no, int init_mode); #ifdef __cplusplus } diff --git a/include/m_string.h b/include/m_string.h index 2bf48e25..5362e6de 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -16,6 +16,10 @@ extern "C" { #define mString_DAY_START 0x64E #define mString_MONTH_START 0x66D #define mString_ARTICLE_START 0x737 +#define mString_HANIWA_MSG0 0x76A +#define mString_HANIWA_MSG1 0x76B +#define mString_HANIWA_MSG2 0x76C +#define mString_HANIWA_MSG3 0x76D extern void mString_aram_init(); diff --git a/include/m_train_control.h b/include/m_train_control.h index 0b7b4b9d..c99be199 100644 --- a/include/m_train_control.h +++ b/include/m_train_control.h @@ -25,7 +25,7 @@ enum { mTRC_ACTION_NUM }; -extern void mTRC_init(); +extern void mTRC_init(GAME* game); extern void mTRC_move(GAME_PLAY* play); #ifdef __cplusplus diff --git a/rel/m_mail_password_check.c b/rel/m_mail_password_check.c index efa39d09..47ef820c 100644 --- a/rel/m_mail_password_check.c +++ b/rel/m_mail_password_check.c @@ -1047,7 +1047,7 @@ extern int mMpswd_check_present_user(mActor_name_t item) { } else if ( // TODO: furniture index values need to be declared in some header file as defines (mRmTp_FtrItemNo2FtrIdx(item) >= 0x3FC && mRmTp_FtrItemNo2FtrIdx(item) <= 0x403) || // balloons - (item >= FTR_COLLEGERULE_SOUTH && item <= FTR_CALLIGRAPHY_PAD_WEST) || // diaries + (item >= FTR_COLLEGERULE && item <= FTR_CALLIGRAPHY_PAD_WEST) || // diaries (mRmTp_FtrItemNo2FtrIdx(item) >= 0x453 && mRmTp_FtrItemNo2FtrIdx(item) <= 0x45A) || // fans (mRmTp_FtrItemNo2FtrIdx(item) >= 0x45B && mRmTp_FtrItemNo2FtrIdx(item) <= 0x462) || // pinwheels (mRmTp_FtrItemNo2FtrIdx(item) >= 0x44F && mRmTp_FtrItemNo2FtrIdx(item) <= 0x452) || // golden tools diff --git a/rel/m_start_data_init.c b/rel/m_start_data_init.c new file mode 100644 index 00000000..3ce3e60d --- /dev/null +++ b/rel/m_start_data_init.c @@ -0,0 +1,525 @@ +#include "m_start_data_init.h" + +#include "m_all_grow.h" +#include "m_name_table.h" +#include "m_house.h" +#include "m_string.h" +#include "m_font.h" +#include "m_field_info.h" +#include "m_field_make.h" +#include "m_scene.h" +#include "libultra/libultra.h" +#include "m_cockroach.h" +#include "m_melody.h" +#include "m_play.h" +#include "m_npc.h" +#include "m_room_type.h" +#include "m_huusui_room.h" +#include "m_mark_room.h" +#include "m_eappli.h" +#include "m_quest.h" +#include "m_name_table.h" +#include "m_train_control.h" +#include "m_notice.h" +#include "m_event.h" +#include "m_common_data.h" + +static void famicom_emu_initial_common_data() { + // stubbed +} + +static void decide_fruit(mActor_name_t* fruit_p) { + *fruit_p = RANDOM(mAGrw_FRUIT_NUM) | ITM_FOOD_START; +} + +static void decide_fish_location(u8* location) { + *location = RANDOM(3); +} + +static void title_game_haniwa_data_init() { + static int haniwa_msg[4] = { mString_HANIWA_MSG0, mString_HANIWA_MSG1, mString_HANIWA_MSG2, mString_HANIWA_MSG3 }; + u8 haniwa_buf[HANIWA_MESSAGE_LEN]; + + int line_len; + int haniwa_msg_len; + int i; + u8* dst; + + /* Load message line-by-line */ + dst = haniwa_buf; + haniwa_msg_len = 0; + for (i = 0; i < 4; i++) { + + mString_Load_StringFromRom(dst, HANIWA_MESSAGE_LEN - haniwa_msg_len, haniwa_msg[i]); + line_len = mMl_strlen(dst, HANIWA_MESSAGE_LEN - haniwa_msg_len, CHAR_SPACE); + + if (i < 3) { + dst[line_len] = CHAR_NEW_LINE; + haniwa_msg_len += line_len + 1; + dst += line_len + 1; + } + } + + for (i = 0; i < mHS_HOUSE_NUM; i++) { + Haniwa_c* haniwa = &Save_Get(homes + i)->haniwa; + mHm_hs_c* house = Save_Get(homes + i); + int j; + + /* Copy default message */ + mem_copy(house->haniwa.message, haniwa_buf, HANIWA_MESSAGE_LEN); + + /* Clear held items */ + for (j = 0; j < HANIWA_ITEM_HOLD_NUM; j++) { + haniwa->items[j].item = EMPTY_NO; + } + + haniwa->bells = 0; + } +} + +static void mSDI_ClearMoneyPlayerHomeStationBlock() { + static int block_num[2][2] = { + { 2, 1 }, /* Player home */ + { 2, 0 } /* Station */ + }; + + int block_z; + int block_x; + mActor_name_t* items; + u16* deposit; + int ut_x; + int ut_z; + mActor_name_t item; + int i; + + for (i = 0; i < 2; i++) { + block_z = block_num[i][1]; + block_x = block_num[i][0]; + + items = Save_Get(fg[block_z][block_x]).items[0]; + deposit = Save_Get(deposit[block_z * FG_BLOCK_X_NUM + block_x]); + + if (items != NULL) { + for (ut_z = 0; ut_z < UT_Z_NUM; ut_z++) { + for (ut_x = 0; ut_x < UT_X_NUM; ut_x++) { + item = *items; + + if (item >= ITM_MONEY_START && item <= ITM_MONEY_END) { + mPB_keep_item(item); + *items = EMPTY_NO; + + if (deposit != NULL) { + mFI_BlockDepositOFF(deposit, ut_x, ut_z); + } + } + + items++; + } + } + } + } +} + +static void mSDI_PullTreeUT(mActor_name_t* item_p) { + mActor_name_t item = *item_p; + + if ( + (item >= TREE_SAPLING && item <= TREE_30000BELLS) || + (item >= TREE_100BELLS_SAPLING && item <= TREE_PALM_FRUIT) || + (item >= CEDAR_TREE_SAPLING && item <= CEDAR_TREE) || + (item >= GOLD_TREE_SAPLING && item <= GOLD_TREE) + ) { + *item_p = EMPTY_NO; + } +} + +static void mSDI_PullTreeBlock(mActor_name_t* items_p, int ut) { + int i; + for (i = ut; i < UT_TOTAL_NUM; i += UT_X_NUM) { + mSDI_PullTreeUT(&items_p[i]); + } +} + +static void mSDI_PullTree() { + mFM_fg_c* fg_block; + int block_z; + + for (block_z = 0; block_z < FG_BLOCK_Z_NUM; block_z++) { + /* Clear trees against the cliffs on the left and right town cliff borders */ + fg_block = Save_GetPointer(fg[block_z][0]); + mSDI_PullTreeBlock(fg_block->items[0], 0); + mSDI_PullTreeBlock((fg_block + FG_BLOCK_X_NUM - 1)->items[0], UT_X_NUM - 1); + } +} + +static void mSDI_PullTreeUnderPlayerBlock() { + /** + * Cleared tree diagram + * + * -------xx------- + * -------xx------- + * ---------------- + * ... + **/ + + mActor_name_t* items = &Save_Get(fg[2][2].items[0][0]); + if (items != NULL) { + mSDI_PullTreeUT(&items[7]); + mSDI_PullTreeUT(&items[8]); + mSDI_PullTreeUT(&items[16 + 7]); + mSDI_PullTreeUT(&items[16 + 8]); + } +} + +static int mSDI_StartInitNew(GAME* game, int player_no, int malloc_flag) { + int town_day; + Private_c* priv; + int i; + Private_c* priv_p; + Animal_c* animals = Save_Get(animals); + GAME_PLAY* play = (GAME_PLAY*)game; + GAME* g = NULL; + + Common_Set(scene_from_title_demo, SCENE_START_DEMO); + lbRTC_GetTime(Common_GetPointer(time.rtc_time)); + osSyncPrintf("player no -- %d\n", player_no); + Common_Set(player_no, player_no); + + priv = Save_GetPointer(private[player_no]); + Common_Set(now_private, priv); + priv->gender = mPr_SEX_MALE; + decide_fruit(Save_GetPointer(fruit)); + mFM_DecideBgTexIdx(Save_GetPointer(bg_tex_idx)); + mFAs_ClearGoodField(); + + if (malloc_flag == FALSE) { + g = game; + } + + bzero(Save_Get(deposit), sizeof(Save_Get(deposit))); + Save_Set(dust_flag, FALSE); + bzero(Save_GetPointer(island), sizeof(Island_c)); + mFM_InitFgCombiSaveData(g); + + /* Remove trees */ + mSDI_PullTree(); + mSDI_PullTreeUnderPlayerBlock(); + + mFM_SetBlockKindLoadCombi(g); + + /* Tree -> Fruit Tree */ + mAGrw_ChangeTree2FruitTree(); + + /* Tree -> Cedar Tree */ + mAGrw_ChangeTree2Cedar(); + + priv_p = Save_Get(private); + + mMld_SetDefaultMelody(); + mLd_LandDataInit(); + mEv_ClearEventSaveInfo(Save_GetPointer(event_save_data)); + mEv_init(&play->event); + mNpc_InitNpcAllInfo(malloc_flag); + + for (i = 0; i < PLAYER_NUM; i++) { + mPr_ClearPrivateInfo(priv_p); + + Save_Get(homes[i]).outlook_pal = i; + Save_Get(homes[i]).next_outlook_pal = i; + bzero(&Save_Get(homes[i]).size_info, sizeof(mHm_rmsz_c)); + + mPr_ClearMotherMailInfo(&Save_Get(mother_mail[i])); + priv_p++; + } + + mPr_InitPrivateInfo(priv_p - PLAYER_NUM + player_no); + mNpc_SetRemoveAnimalNo(Save_GetPointer(remove_animal_idx), animals, -1); + title_game_haniwa_data_init(); + mPB_police_box_init(g); + mSN_snowman_init(); // + mHS_house_init(); + mGH_animal_return_init(); // + mMC_mask_cat_init(); // + mDE_maskcat_init(Save_GetPointer(mask_cat)); // + + lbRTC_TimeCopy(Save_GetPointer(last_grow_time), &mTM_rtcTime_clear_code); + lbRTC_TimeCopy(Save_GetPointer(treasure_buried_time), &mTM_rtcTime_clear_code); + lbRTC_TimeCopy(Save_GetPointer(treasure_checked_time), &mTM_rtcTime_clear_code); + lbRTC_TimeCopy(Save_GetPointer(saved_auto_nwrite_time), &mTM_rtcTime_clear_code); + + Save_Set(station_type, RANDOM(15)); + Save_Set(island.last_song_male, -1); + Save_Set(island.last_song_female, -1); + + mPr_SetPossessionItem(Common_Get(now_private), 0, ITM_MONEY_1000, mPr_ITEM_COND_QUEST); + + town_day = RANDOM(30) + 1; /* Initial spread is [1, 30] */ + if (town_day >= 4) { + town_day++; /* Add an extra day so that 4th of July is never chosen, so [1, 3] U [5, 31] */ + } + + Save_Set(town_day, town_day); + + mCkRh_InitGokiSaveData_AllRoom(); + + mNW_InitMyOriginal(); + mNW_InitNeedleworkData(); + + mEv_2nd_init(&play->event); + + mISL_init(Save_GetPointer(island)); + + famicom_emu_initial_common_data(); + + mRmTp_SetDefaultLightSwitchData(1); // TODO: lightswitch enum + + mFI_PullTanukiPathTrees(); + + Common_Set(_2dbe1, 0); + + return TRUE; +} + +static int mSDI_StartInitFrom(GAME* game, int player_no, int malloc_flag) { + GAME_PLAY* play = (GAME_PLAY*)game; + int res = FALSE; + GAME* g = game; + Animal_c* animals = Save_Get(animals); + + if (malloc_flag) { + g = NULL; + } + + Common_Set(scene_from_title_demo, SCENE_FG); + lbRTC_GetTime(Common_GetPointer(time.rtc_time)); + + if (mFRm_CheckSaveData() == TRUE) { + Private_c* priv = Save_Get(private + player_no); + + if (mPr_CheckPrivate(priv) == TRUE) { + + if (priv->exists == TRUE) { + Common_Set(now_private, priv); + Common_Set(player_no, player_no); + mFM_SetBlockKindLoadCombi(g); // + mEv_init_force(&play->event); // + mHsRm_GetHuusuiRoom(g, player_no); + mCkRh_DecideNowGokiFamilyCount(player_no); + mSP_ExchangeLineUp_InGame(g); // + mNpc_SetRemoveAnimalNo(Save_GetPointer(remove_animal_idx), animals, -1); + mMkRm_MarkRoom(g); + mRmTp_SetDefaultLightSwitchData(2); // TODO: enum + res = TRUE; + } + else { + /* Player loaded their player data while "out travelling" */ + Common_Set(player_decoy_flag, TRUE); // set "gyroid face" flag + priv->exists = TRUE; + Common_Set(now_private, priv); + Common_Set(player_no, player_no); + mFM_SetBlockKindLoadCombi(g); // + mEv_init_force(&play->event); // + mHsRm_GetHuusuiRoom(g, player_no); + mCkRh_DecideNowGokiFamilyCount(player_no); + mSP_ExchangeLineUp_InGame(g); // + mNpc_SetRemoveAnimalNo(Save_GetPointer(remove_animal_idx), animals, -1); + + /* Punish player by deleting their pockets and some pending items */ + bzero(&priv->inventory.pockets, sizeof(priv->inventory.pockets)); + priv->inventory.lotto_ticket_expiry_month = 0; + priv->inventory.lotto_ticket_mail_storage = 0; + priv->inventory.item_conditions = 0; + priv->inventory.wallet = 0; + mQst_ClearDelivery(priv->deliveries, mPr_DELIVERY_QUEST_NUM); // + mQst_ClearErrand(priv->errands, mPr_ERRAND_QUEST_NUM); // + + mMkRm_MarkRoom(g); + mRmTp_SetDefaultLightSwitchData(2); // TODO: enum + res = TRUE; + } + } + } + + return res; +} + +static int mSDI_StartInitNewPlayer(GAME* game, int player_no, int malloc_flag) { + GAME_PLAY* play = (GAME_PLAY*)game; + Animal_c* animals = Save_Get(animals); + int res = FALSE; + + Common_Set(scene_from_title_demo, SCENE_START_DEMO2); + lbRTC_GetTime(Common_GetPointer(time.rtc_time)); + + if (mFRm_CheckSaveData() == TRUE) { + Private_c* priv = Save_Get(private + player_no); + + if (mPr_CheckPrivate(priv) != TRUE) { + mPr_InitPrivateInfo(priv); + Common_Set(now_private, priv); + mPr_SetPossessionItem(priv, 0, ITM_MONEY_1000, mPr_ITEM_COND_QUEST); + Common_Set(player_no, player_no); + Common_Get(now_private)->gender = mPr_SEX_MALE; + mNW_InitOneMyOriginal(Common_Get(player_no)); + mCkRh_InitGokiSaveData_InitNewPlayer(); + + if (malloc_flag == FALSE) { + mFM_SetBlockKindLoadCombi(game); + mEv_init_force(&play->event); + mSP_ExchangeLineUp_InGame(game); + } + else { + mFM_SetBlockKindLoadCombi(NULL); + mEv_init_force(&play->event); + mSP_ExchangeLineUp_InGame(NULL); + } + + mNpc_SetRemoveAnimalNo(Save_GetPointer(remove_animal_idx), animals, -1); + mSDI_ClearMoneyPlayerHomeStationBlock(); + mRmTp_SetDefaultLightSwitchData(1); // TODO: enum + mFI_PullTanukiPathTrees(); + res = TRUE; + } + } + + return res; +} + +static int mSDI_StartInitPak(GAME* game, int player_no, int malloc_flag) { + GAME_PLAY* play = (GAME_PLAY*)game; + GAME* g = game; + Animal_c* animals = Save_Get(animals); + int res = FALSE; + + if (malloc_flag == TRUE) { + g = NULL; + } + + if (player_no < mPr_PLAYER_NUM) { + Common_Set(scene_from_title_demo, SCENE_FG); + } + + if (mFRm_CheckSaveData() == TRUE) { + mFM_SetBlockKindLoadCombi(g); + mEv_init_force(&play->event); + mHsRm_GetHuusuiRoom(g, player_no); + mCkRh_DecideNowGokiFamilyCount(player_no); + mSP_ExchangeLineUp_InGame(g); + mNpc_SetRemoveAnimalNo(Save_GetPointer(remove_animal_idx), animals, -1); + mNpc_SetReturnAnimal(mNpc_GetInAnimalP()); // + mNpc_SendRegisteredGoodbyMail(); // + mMkRm_MarkRoom(g); + mEv_SetGateway(); // + mRmTp_SetDefaultLightSwitchData(2); // TODO: enum + res = TRUE; + } + + return res; +} + +static int mSDI_StartInitErr(GAME* game, int player_no, int malloc_flag) { + return TRUE; +} + +extern void mSDI_StartInitAfter(GAME* game, int renew_mode, int malloc_flag) { + GAME_PLAY* play = (GAME_PLAY*)game; + Animal_c* animals = Save_Get(animals); + + Common_Set(house_owner_name, -1); + mEA_InitLetterCardE(); + Common_Set(last_field_id, -1); + mHm_SetNowHome(); + mNpc_RenewalAnimalMemory(); // + mNpc_ForceRemove(); // + mTM_renewal_renew_time(); + mEv_ClearEventInfo(); + mEnv_DecideWeather_NormalGameStart(); // + mMl_start_send_mail(); + mPO_first_work(play); + mTM_set_season(); + mAGrw_ClearAllShine_Stone(); // + mAGrw_RestoreStoneShine(Common_Get(player_no)); + mFAs_SetFieldRank(); + mEv_2nd_init(&play->event); + mNpc_Grow(); // + Kabu_manager(); + mNpc_InitNpcData(); + mNpc_InitNpcList(Common_Get(npclist), ANIMAL_NUM_MAX); // + mNpc_SetNpcList(Common_Get(npclist), animals, ANIMAL_NUM_MAX, malloc_flag); + mNpc_InitNpcList(Common_Get(island_npclist), 1); + mNpc_ClearTalkInfo(); // + + if (renew_mode == 1) { + mFM_RenewalReserve(); // + } + + mNpc_ChangePresentCloth(); // + mQst_ClearNotSaveQuest(Common_GetPointer(quest)); // + mGH_check_delete(); // + mMC_check_delete(); // + mFM_SetIslandNpcRoomData(game, malloc_flag); // + mCD_calendar_wellcome_on(); // + mPr_SetItemCollectBit(FTR_TAPEDECK); + mPr_SetItemCollectBit(FTR_COLLEGERULE); + mPr_SetItemCollectBit(FTR_ORANGEBOX); + mNPS_set_all_schedule_area(); // + mNpcW_InitNpcWalk(Common_GetPointer(npc_walk)); // + mHm_CheckRehouseOrder(); + decide_fish_location(Common_GetPointer(fish_location)); + mTRC_init(game); + Common_Set(goki_shocked_flag, FALSE); + mNtc_auto_nwrite_time_ct(); // + mPr_SendMailFromMother(); + mNpc_Remail(); // + mPr_SendForeingerAnimalMail(Common_Get(now_private)); + mPr_StartSetCompleteTalkInfo(); + mMsm_SendInformationMail(); // + mMsm_SendCompMail(); // + mFI_SetFirstSetShell(); // + mMsr_FirstClearMushroom(); + mSN_decide_msg(); // + mPr_RenewalMapInfo(Common_Get(now_private)->maps, mPr_FOREIGN_MAP_COUNT, Save_GetPointer(land_info)); + mSP_SetTanukiShopStatus(); // + mEnv_DecideTodayWindPowerRange(); // + mFI_SetClimate(mFI_CLIMATE_0); + mISL_RestoreIsland(); // + mNpc_SendHPMail(); // +} + +typedef int (*mSDI_INIT_PROC)(GAME*, int, int); + +extern int mSDI_StartInitBefore(GAME* game, int player_no, int init_mode, int malloc_flag) { + static mSDI_INIT_PROC init_proc[mSDI_INIT_MODE_NUM] = { + &mSDI_StartInitNew, + &mSDI_StartInitNewPlayer, + &mSDI_StartInitFrom, + &mSDI_StartInitPak, + &mSDI_StartInitErr + }; + + mEv_UnSetGateway(); // + return (*init_proc[init_mode])(game, player_no, malloc_flag); +} + +extern int mSDI_StartDataInit(GAME* game, int player_no, int init_mode) { + static int renew_reserve_mode_table[mSDI_INIT_MODE_NUM] = { + TRUE, + FALSE, + FALSE, + FALSE, + FALSE + }; + + int res; + + if (init_mode < mSDI_INIT_MODE_NEW || init_mode >= mSDI_INIT_MODE_NUM) { + init_mode = mSDI_INIT_MODE_NEW; + } + + res = mSDI_StartInitBefore(game, player_no, init_mode, mSDI_MALLOC_FLAG_ZELDA); + if (res == TRUE) { + mSDI_StartInitAfter(game, renew_reserve_mode_table[init_mode], mSDI_MALLOC_FLAG_ZELDA); + } + + return res; +} diff --git a/rel/m_train_control.c b/rel/m_train_control.c index 9f311dd5..7b803995 100644 --- a/rel/m_train_control.c +++ b/rel/m_train_control.c @@ -500,7 +500,7 @@ static void mTRC_trainSet(GAME_PLAY* play) { } } -extern void mTRC_init() { +extern void mTRC_init(GAME* game) { Common_Set(train_start_timer, mTRC_get_depart_time()); Common_Set(train_coming_flag, 0); Common_Set(train_exists_flag, FALSE);