From 27622ecf6293768acc9d836a0e6d666b1c1554d8 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Sat, 16 Sep 2023 10:15:49 -0400 Subject: [PATCH] Implement remainder of m_flashrom TU, link --- config/rel_slices.yml | 4 + include/lb_reki.h | 6 +- include/lb_rtc.h | 6 +- include/m_calendar.h | 1 + include/m_common_data.h | 33 +- include/m_config.h | 18 ++ include/m_fishrecord.h | 12 +- include/m_flashrom.h | 3 +- include/m_home_h.h | 28 +- include/m_island.h | 2 + include/m_kabu_manager.h | 3 + include/m_kankyo.h | 3 + include/m_mail.h | 7 +- include/m_mask_cat.h | 2 + include/m_museum_display.h | 2 + include/m_mushroom.h | 4 +- include/m_name_table.h | 1 + include/m_needlework.h | 21 ++ include/m_npc.h | 18 +- include/m_npc_personal_id.h | 3 +- include/m_post_office.h | 2 + include/m_private.h | 30 +- include/m_shop.h | 8 + include/m_snowman.h | 2 +- include/m_time.h | 6 +- rel/lb_reki.c | 12 +- rel/lb_rtc.c | 12 +- rel/m_calendar.c | 4 +- rel/m_flashrom.c | 60 ++-- rel/m_mail.c | 4 +- rel/m_map_ovl.c | 6 +- rel/m_mushroom.c | 16 +- rel/m_notice.c | 22 +- rel/m_private.c | 2 +- rel/m_select.c | 8 +- rel/m_time.c | 14 +- rel/save_check.c_inc | 582 ++++++++++++++++++++++++++++++++++++ rel/save_check_MYK.c_inc | 281 +++++++++++++++++ rel/save_check_NSW.c_inc | 244 +++++++++++++++ rel/save_check_YSD.c_inc | 105 +++++++ rel/save_check_gen.c_inc | 3 + rel/save_check_komatu.c_inc | 75 +++++ rel/save_check_take.c_inc | 89 ++++++ 43 files changed, 1652 insertions(+), 112 deletions(-) diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 3cf3185f..030e696e 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -78,6 +78,10 @@ m_fbdemo_fade.c: .text: [0x803A12F8, 0x803A1508] .rodata: [0x80641FC0, 0x80641FD8] .data: [0x80653558, 0x806535A0] +m_flashrom.c: + .text: [0x803AC5C8, 0x803AF48C] + .data: [0x80654188, 0x80654298] + .bss: [0x81295BD8, 0x81295C30] m_fuusen.c: .text: [0x803B15E0, 0x803B1908] .rodata: [0x80642258, 0x80642288] diff --git a/include/lb_reki.h b/include/lb_reki.h index 4b980f19..49b951ad 100644 --- a/include/lb_reki.h +++ b/include/lb_reki.h @@ -22,11 +22,11 @@ extern "C" { #define lbRk_KYUU_DAY_START 1 -extern int lbRk_ToSeiyouReki(lbRTC_ymd_t* seiyo_ymd, const lbRTC_ymd_t* kyuu_ymd); -extern int lbRk_ToKyuuReki(lbRTC_ymd_t* kyuu_ymd, const lbRTC_ymd_t* seiyo_ymd); +extern int lbRk_ToSeiyouReki(lbRTC_ymd_c* seiyo_ymd, const lbRTC_ymd_c* kyuu_ymd); +extern int lbRk_ToKyuuReki(lbRTC_ymd_c* kyuu_ymd, const lbRTC_ymd_c* seiyo_ymd); extern int lbRk_VernalEquinoxDay(int year); extern int lbRk_AutumnalEquinoxDay(int year); -extern void lbRk_HarvestMoonDay(lbRTC_ymd_t* harvest_moon_day, int year); +extern void lbRk_HarvestMoonDay(lbRTC_ymd_c* harvest_moon_day, int year); #ifdef __cplusplus } diff --git a/include/lb_rtc.h b/include/lb_rtc.h index 45a6a18e..89c1987b 100644 --- a/include/lb_rtc.h +++ b/include/lb_rtc.h @@ -33,11 +33,13 @@ typedef struct lbRTC_datetime_s { lbRTC_year_t year; } lbRTC_time_c; /* Name leaked in lbRTC_time_c_save_data_check */ +typedef lbRTC_time_c OSRTCTime; + typedef struct lbRTC_ymd_s { lbRTC_year_t year; lbRTC_month_t month; lbRTC_day_t day; -} lbRTC_ymd_t; /* Name leaked in mTM_ymd_2_time */ +} lbRTC_ymd_c; /* Name leaked in mTM_ymd_2_time */ enum WEEKDAYS { lbRTC_WEEKDAYS_BEGIN = 0, @@ -112,7 +114,7 @@ extern int lbRTC_IsOverTime(const lbRTC_time_c* t0, const lbRTC_time_c* t1); extern int lbRTC_IsOverRTC(const lbRTC_time_c* time); extern int lbRTC_IntervalTime(const lbRTC_time_c* time0, const lbRTC_time_c* time1); extern int lbRTC_GetIntervalDays(const lbRTC_time_c* t0, const lbRTC_time_c* t1); -extern int lbRTC_GetIntervalDays2(lbRTC_ymd_t* ymd0, lbRTC_ymd_t* ymd1); +extern int lbRTC_GetIntervalDays2(lbRTC_ymd_c* ymd0, lbRTC_ymd_c* ymd1); extern void lbRTC_Add_YY(lbRTC_time_c* time, int year); extern void lbRTC_Add_MM(lbRTC_time_c* time, int month); extern void lbRTC_Add_DD(lbRTC_time_c* time, int day); diff --git a/include/m_calendar.h b/include/m_calendar.h index bff5bf93..45b6fddd 100644 --- a/include/m_calendar.h +++ b/include/m_calendar.h @@ -22,6 +22,7 @@ typedef struct calendar_player_info_s { /* 0x30 */ u32 event_days[lbRTC_MONTHS_MAX]; /* bitfield of events where 1 bit represents an event was on that day */ /* 0x60 */ u16 event_flags; /* flags for specific event days the player played on */ /* 0x62 */ u8 edit; /* unsure, might have something to do with saving an edit */ + /* 0x63 */ u8 pad_63; /* only checked in save data validation? */ /* 0x64 */ lbRTC_year_t year; /* year calendar was last updated */ /* 0x66 */ lbRTC_month_t month; /* month calendar was last updated */ } mCD_player_calendar_c; diff --git a/include/m_common_data.h b/include/m_common_data.h index 7af759ee..27f97650 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -30,6 +30,7 @@ #include "m_mask_cat.h" #include "m_npc_schedule_h.h" #include "m_all_grow.h" +#include "m_fishrecord.h" #ifdef __cplusplus extern "C" { @@ -56,7 +57,7 @@ typedef struct time_s { } Time_c; /* sizeof(PlusBridge_c) == 8 */ -typedef struct plus_bridge_s { +typedef struct bridge_s { /* 0x00 */ u8 block_x; /* 0x01 */ u8 block_z; /* 0x02 */ struct { @@ -64,9 +65,16 @@ typedef struct plus_bridge_s { u8 pending:1; u8 pad:6; }; - /* 0x04 */ lbRTC_ymd_t build_date; + /* 0x04 */ lbRTC_ymd_c build_date; } PlusBridge_c; +typedef struct lighthouse_s { + lbRTC_ymd_c renew_time; + u8 players_switch_on; + u8 players_quest_started; + u8 players_completed; +} LightHouse_c; + typedef struct Save_s { /* 0x000000 */ mFRm_chk_t save_check; /* save information */ /* 0x000014 */ int scene_no; /* current 'scene' id */ @@ -96,7 +104,7 @@ typedef struct Save_s { /* 0x020EF8 */ mSN_snowman_save_c snowmen; /* saved snowmen data */ /* 0x020F08 */ u64 melody; /* town tune, each nibble is a note (16 notes) */ /* 0x020F10 */ Config_c config; /* saved config for sound mode, voice mode, and vibration */ - /* 0x020F14 */ lbRTC_ymd_t renew_time; /* next renew date */ + /* 0x020F14 */ lbRTC_ymd_c renew_time; /* next renew date */ /* 0x020F18 */ u8 station_type; /* train station type */ /* 0x020F19 */ u8 weather; /* upper nibble is intensity, lower nibble is type */ /* 0x020F1A */ u8 save_exist; /* unsure, set in mCD_SaveHome_bg_set_data (1) & mCD_SaveHome_bg (bss) */ @@ -104,8 +112,13 @@ typedef struct Save_s { /* 0x020F1C */ u16 deposit[FG_BLOCK_X_NUM * FG_BLOCK_Z_NUM][UT_Z_NUM]; /* flags for which items are buried around town */ /* 0x0212DC */ lbRTC_time_c last_grow_time; /* last time that a new villager moved into town */ /* 0x0212E4 */ mPr_mother_mail_info_c mother_mail[PLAYER_NUM]; /* info on when mom sent player letters and what event was sent */ - /* 0x02131C */ mMsr_MushTime_c mushroom_time; /* last time mushroom season info was updated */ - /* 0x021322 */ u8 _tmp21322[0x02137E - 0x021322]; + /* 0x02131C */ mMsr_time_c mushroom_time; /* last time mushroom season info was updated */ + /* 0x021322 */ lbRTC_ymd_c _021322; + /* 0x021326 */ u16 _021326[20]; + /* 0x02134E */ u8 npc_used_tbl[32]; + /* 0x02136E */ lbRTC_time_c _02136E; + /* 0x021376 */ u8 cheated_flag; + /* 0x021377 */ u8 _021377[7]; /* 0x02137E */ lbRTC_time_c treasure_buried_time; /* last time treasure was actually buried */ /* 0x021386 */ lbRTC_time_c treasure_checked_time; /* last time check to bury treasure was executed */ /* 0x02138E */ u8 saved_rom_debug; /* flag to set save to 'debug rom' mode */ @@ -116,22 +129,22 @@ typedef struct Save_s { /* 0x021393 */ u8 haniwa_scheduled; /* when set, gyroids will be spwaned */ /* 0x021394 */ u8 dust_flag; /* set by field assessment for too much 'dust' (garbage) around town, causes immediate fail of town ranking */ /* 0x021395 */ u8 clear_grass; /* set by Wisp, removes all weeds */ - /* 0x021396 */ lbRTC_ymd_t event_year_ymd; /* might not exist and just be lbRTC_year_t */ + /* 0x021396 */ lbRTC_ymd_c event_year_ymd; /* might not exist and just be lbRTC_year_t */ /* 0x02139A */ u8 unused_2139A[6]; /* 0x0213A0 */ u8 keep_house_size[PLAYER_NUM]; /* saved flags for house sizes */ - /* 0x0213A4 */ lbRTC_ymd_t force_remove_date; /* last time the NPC force remove timer was updated */ + /* 0x0213A4 */ lbRTC_ymd_c force_remove_date; /* last time the NPC force remove timer was updated */ /* 0x0213A8 */ mMmd_info_c museum_display; /* museum display bits */ /* 0x0213E7 */ u8 _tmp6[0x213F0 - 0x213E7]; - /* 0x0213F0 */ PlusBridge_c plus_bridge; /* additional bridge info */ + /* 0x0213F0 */ PlusBridge_c bridge; /* additional bridge info */ /* 0x021400 */ mNW_needlework_c needlework; /* Able Sisters' designs */ /* 0x022500 */ u8 _tmp7[0x22528 - 0x22500]; /* 0x022528 */ OSTime time_delta; /* time delta against GC RTC */ /* 0x022540 */ Island_c island; /* island data */ /* 0x023E40 */ mAGrw_AllGrow_c allgrow_ss_pos_info; - /* 0x023E68 */ u8 _23E68[0x23F20 - 0x23E68]; + /* 0x023E68 */ mFR_record_c fishRecord[mFR_RECORD_NUM]; /* 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]; + /* 0x02416C */ LightHouse_c LightHouse; /* info for tracking the light house quest */ /* 0x024174 */ u8 insect_term; /* current insect term idx */ /* 0x024175 */ u8 insect_term_transition_offset; /* days offset from end of term to begin transition */ /* 0x024176 */ u8 gyoei_term; /* current fish term idx */ diff --git a/include/m_config.h b/include/m_config.h index 6efa7364..22b29e17 100644 --- a/include/m_config.h +++ b/include/m_config.h @@ -7,6 +7,24 @@ extern "C" { #endif +enum { + Config_SOUND_MODE_0, + Config_SOUND_MODE_1, + Config_SOUND_MODE_2, + Config_SOUND_MODE_3, + + Config_SOUND_MODE_NUM +}; + +enum { + Config_VOICE_MODE_0, + Config_VOICE_MODE_1, + Config_VOICE_MODE_2, + Config_VOICE_MODE_3, + + Config_VOICE_MODE_NUM +}; + /* sizeof(Config_c) == 4 */ typedef struct config_s { /* 0x00 */ u8 sound_mode; /* mono, stereo, ... */ diff --git a/include/m_fishrecord.h b/include/m_fishrecord.h index 4a6749c2..92bc55c2 100644 --- a/include/m_fishrecord.h +++ b/include/m_fishrecord.h @@ -9,8 +9,16 @@ extern "C" { #endif -extern void mEv_fishRecord_holder(PersonalID_c* winner_pid, u32* winning_size, lbRTC_ymd_t* contest_date); -extern int mEv_fishday(lbRTC_ymd_t* dates, lbRTC_time_c* now_time); +#define mFR_RECORD_NUM 5 + +typedef struct fishrecord_s { + PersonalID_c pid; + lbRTC_time_c time; + int size; +} mFR_record_c; + +extern void mEv_fishRecord_holder(PersonalID_c* winner_pid, u32* winning_size, lbRTC_ymd_c* contest_date); +extern int mEv_fishday(lbRTC_ymd_c* dates, lbRTC_time_c* now_time); extern void mFR_fishmail(); #ifdef __cplusplus diff --git a/include/m_flashrom.h b/include/m_flashrom.h index 6f3b3688..bdc4c444 100644 --- a/include/m_flashrom.h +++ b/include/m_flashrom.h @@ -3,6 +3,7 @@ #include "types.h" #include "libu64/gfxprint.h" +#include "m_time.h" #ifdef __cplusplus extern "C" { @@ -55,7 +56,7 @@ extern void mFRm_SetSaveCheckData(mFRm_chk_t* save_check); extern void mFRm_PrintSavedDebug(gfxprint_t* gfxprint); extern void mFRm_clear_err_info(); extern void mFRm_save_data_check(); -extern void mFRm_display_errInfo(gfxprint_t* gfxprint); +extern void mFRm_display_errInfo(gfxprint_t* gfxprint); #ifdef __cplusplus } diff --git a/include/m_home_h.h b/include/m_home_h.h index aa01123d..3127133a 100644 --- a/include/m_home_h.h +++ b/include/m_home_h.h @@ -45,6 +45,32 @@ enum { mHm_HOMESIZE_NUM }; +enum { + mHm_HANIWA_TRADE_0, + mHm_HANIWA_TRADE_1, + mHm_HANIWA_TRADE_2, + mHm_HANIWA_TRADE_3, + + mHm_HANIWA_TRADE_NUM +}; + +enum { + mHm_OUTLOOK_PAL_0, + mHm_OUTLOOK_PAL_1, + mHm_OUTLOOK_PAL_2, + mHm_OUTLOOK_PAL_3, + mHm_OUTLOOK_PAL_4, + mHm_OUTLOOK_PAL_5, + mHm_OUTLOOK_PAL_6, + mHm_OUTLOOK_PAL_7, + mHm_OUTLOOK_PAL_8, + mHm_OUTLOOK_PAL_9, + mHm_OUTLOOK_PAL_10, + mHm_OUTLOOK_PAL_11, + + mHm_OUTLOOK_PAL_NUM +}; + /* sizeof(mHm_rmsz_c) == 6 */ typedef struct home_size_info_s { /* 0x00 */ struct { @@ -128,7 +154,7 @@ typedef struct home_s { /* 0x0000 */ PersonalID_c ownerID; /* owner player's ID */ /* 0x0014 */ u8 unk_14[6]; /* 0x001A */ TempoBeat_c haniwa_tempo; /* unsure about this */ - /* 0x001C */ lbRTC_ymd_t hra_mark_time; /* last HRA judge date */ + /* 0x001C */ lbRTC_ymd_c hra_mark_time; /* last HRA judge date */ /* 0x0020 */ u32 hra_mark_info; /* bitfield of HRA info pulled when HRA mails letter */ /* 0x0024 */ mHm_flg_c flags; /* 0x0026 */ mHm_rmsz_c size_info; /* home size info */ diff --git a/include/m_island.h b/include/m_island.h index 0429b2ac..54cc5a75 100644 --- a/include/m_island.h +++ b/include/m_island.h @@ -20,6 +20,8 @@ extern "C" { #define mISL_FG_BLOCK_X_NUM 2 #define mISL_FG_BLOCK_Z_NUM 1 +#define mISL_BLOCK_X0 4 +#define mISL_BLOCK_X1 5 #define mISL_BLOCK_Z 8 enum { diff --git a/include/m_kabu_manager.h b/include/m_kabu_manager.h index 1516d462..66a5496a 100644 --- a/include/m_kabu_manager.h +++ b/include/m_kabu_manager.h @@ -18,6 +18,9 @@ enum { Kabu_TRADE_MARKET_TYPE_NUM }; +#define Kabu_PRICE_MIN 10 +#define Kabu_PRICE_MAX 2000 + /* sizeof(Kabu_price_c) == 0x18 */ typedef struct kabu_price_s { /* 0x00 */ u16 daily_price[lbRTC_WEEKDAYS_MAX]; diff --git a/include/m_kankyo.h b/include/m_kankyo.h index edc17e16..76b8bf70 100644 --- a/include/m_kankyo.h +++ b/include/m_kankyo.h @@ -28,6 +28,9 @@ enum weather_intensity { mEnv_WEATHER_INTENSITY_NUM, }; +#define mEnv_SAVE_GET_WEATHER_TYPE(w) (((w) & 0xF0) >> 4) +#define mEnv_SAVE_GET_WEATHER_INTENSITY(w) ((w) & 0xF) + typedef void (*NATURE_PROC)(ACTOR*); typedef struct nature_s { diff --git a/include/m_mail.h b/include/m_mail.h index 4e5d9de1..d631b452 100644 --- a/include/m_mail.h +++ b/include/m_mail.h @@ -26,7 +26,8 @@ enum { mMl_NAME_TYPE_NPC, mMl_NAME_TYPE_MUSEUM, - mMl_TYPE_CLEAR = 0xFF + mMl_NAME_TYPE_NUM, + mMl_NAME_TYPE_CLEAR = 0xFF }; enum { @@ -50,7 +51,9 @@ enum { mMl_TYPE_MUSEUM = 0, mMl_TYPE_1 = 1, mMl_TYPE_SHOP_SALE_LEAFLET = 2, - mMl_TYPE_BROKER_SALE_LEAFLET = 3 + mMl_TYPE_BROKER_SALE_LEAFLET = 3, + + mMl_TYPE_12 = 12 }; /* sizeof(Mail_nm_c) == 0x16 */ diff --git a/include/m_mask_cat.h b/include/m_mask_cat.h index 0fc4ce58..2361380a 100644 --- a/include/m_mask_cat.h +++ b/include/m_mask_cat.h @@ -9,6 +9,8 @@ extern "C" { #endif +#define mMC_TALK_IDX_MAX 10 + typedef struct mask_cat_s { mNW_original_design_c design; u8 palette_no; diff --git a/include/m_museum_display.h b/include/m_museum_display.h index 80f4e3d1..8e46250a 100644 --- a/include/m_museum_display.h +++ b/include/m_museum_display.h @@ -51,6 +51,8 @@ enum { /* 4 bits per donatable item */ #define mMmd_BIT_INFO(info, category, index) \ (((info).category##_bit[(index) >> 1] >> (((index) & 1) << 2)) & 0x0F) +#define mMmd_BIT_INFO2(bitfield, index) \ + (((bitfield)[(index) >> 1] >> (((index) & 1) << 2)) & 0x0F) #define mMmd_ART_BIT(info, index) mMmd_BIT_INFO(info, art, index) #define mMmd_INSECT_BIT(info, index) mMmd_BIT_INFO(info, insect, index) diff --git a/include/m_mushroom.h b/include/m_mushroom.h index 7e0553ec..22e417a4 100644 --- a/include/m_mushroom.h +++ b/include/m_mushroom.h @@ -11,7 +11,7 @@ extern "C" { #define mMsr_ACTIVE_HOUR 8 #define mMsr_NUM_MUSHROOMS 5 -/* sizeof(mMsr_Mushtime_c) == 6 */ +/* sizeof(mMsr_time_c) == 6 */ typedef struct mushroom_time_s { /* 0x00 */ u16 year:12; /* 0x01 */ u16 month:4; @@ -22,7 +22,7 @@ typedef struct mushroom_time_s { /* 0x04 */ u8 hour_quarter:4; /* 0x04 */ u8 active:1; /* probably a better name for this */ /* 0x04 */ u8 pad2:3; -} mMsr_MushTime_c; +} mMsr_time_c; extern void mMsr_FirstClearMushroom(); extern void mMsr_SetMushroom(xyz_t player_pos); diff --git a/include/m_name_table.h b/include/m_name_table.h index ef5bd0bb..279e6049 100644 --- a/include/m_name_table.h +++ b/include/m_name_table.h @@ -1302,6 +1302,7 @@ extern mActor_name_t bg_item_fg_sub_tree_grow(mActor_name_t tree, int past_days, #define DUMMY_DOUZOU 0xF11D #define RSV_DOOR 0xFE1B +#define RSV_CLOTH 0xFE20 #define RSV_WALL_NO 0xFFFE /* interior wall item, no collision */ #define RSV_NO 0xFFFF /* reserved space, can't interact but no collision */ diff --git a/include/m_needlework.h b/include/m_needlework.h index 4c8350c6..80b590bd 100644 --- a/include/m_needlework.h +++ b/include/m_needlework.h @@ -20,6 +20,27 @@ extern "C" { #define mNW_DESIGN_TEX_SIZE (mNW_ORIGINAL_DESIGN_HEIGHT * (mNW_ORIGINAL_DESIGN_WIDTH / 2)) /* total texture data size */ #define mNW_PALETTE_COUNT 16 /* number of design palettes */ +enum { + mNW_PALETTE0, + mNW_PALETTE1, + mNW_PALETTE2, + mNW_PALETTE3, + mNW_PALETTE4, + mNW_PALETTE5, + mNW_PALETTE6, + mNW_PALETTE7, + mNW_PALETTE8, + mNW_PALETTE9, + mNW_PALETTE10, + mNW_PALETTE11, + mNW_PALETTE12, + mNW_PALETTE13, + mNW_PALETTE14, + mNW_PALETTE15, + + mNW_PALETTE_NUM +}; + /* sizeof(mNW_original_design_c) == 0x220 */ typedef struct original_data_s { /* 0x000 */ u8 name[mNW_ORIGINAL_DESIGN_NAME_LEN]; diff --git a/include/m_npc.h b/include/m_npc.h index dbd87f64..8db855ad 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -31,9 +31,23 @@ extern "C" { #define mNpc_ISLAND_FTR_SAVE_NUM 4 +enum { + mNpc_MOOD_0, + mNpc_MOOD_1, + mNpc_MOOD_2, + mNpc_MOOD_3, + mNpc_MOOD_4, + mNpc_MOOD_5, + mNpc_MOOD_6, + mNpc_MOOD_7, + mNpc_MOOD_8, + + mNpc_MOOD_NUM +}; + /* sizeof(Anmremail_c) == 0x16 */ typedef struct animal_remail_s { - lbRTC_ymd_t date; /* date sent */ + lbRTC_ymd_c date; /* date sent */ u8 name[ANIMAL_NAME_LEN]; /* villager name */ u8 land_name[LAND_NAME_SIZE]; /* town name */ struct { @@ -52,7 +66,7 @@ typedef struct animal_player_maiL_s { /* 0x01D */ u8 body[MAIL_BODY_LEN]; /* 0x0DD */ u8 footer[MAIL_FOOTER_LEN]; /* 0x0FD */ u8 pad0; /* likely pad */ - /* 0x0FE */ lbRTC_ymd_t date; /* sent date */ + /* 0x0FE */ lbRTC_ymd_c date; /* sent date */ } Anmplmail_c; /* sizeof(Anmhome_c) == 5 */ diff --git a/include/m_npc_personal_id.h b/include/m_npc_personal_id.h index 31908b17..df7cd1dc 100644 --- a/include/m_npc_personal_id.h +++ b/include/m_npc_personal_id.h @@ -16,8 +16,9 @@ enum { mNpc_LOOKS_SPORT_MAN, mNpc_LOOKS_GRIM_MAN, mNpc_LOOKS_NANIWA_LADY, + mNpc_LOOKS_UNSET, - mNpc_LOOKS_NUM + mNpc_LOOKS_NUM = mNpc_LOOKS_UNSET }; /* sizeof(AnmPersonalID_c) == 0xE */ diff --git a/include/m_post_office.h b/include/m_post_office.h index 3466ea32..df721685 100644 --- a/include/m_post_office.h +++ b/include/m_post_office.h @@ -13,6 +13,8 @@ extern "C" { #define mPO_MAIL_STORAGE_SIZE 5 #define mPO_DELIVER_ALL_HOUSES -1 +#define mPO_KEEP_MAIL_PLAYERS_MAX 10 + enum { mPO_SENDTYPE_MAIL, mPO_SENDTYPE_LEAFLET, diff --git a/include/m_private.h b/include/m_private.h index afcc72e1..19cf8c7c 100644 --- a/include/m_private.h +++ b/include/m_private.h @@ -20,6 +20,7 @@ extern "C" { #define TOTAL_PLAYER_NUM (PLAYER_NUM + FOREIGNER_NUM) #define mPr_WALLET_MAX 99999 +#define mPr_DEPOSIT_MAX 999999999 #define mPr_FLAG_POSTOFFICE_GIFT0 (1 << 2) // 1,000,000 Bells #define mPr_FLAG_POSTOFFICE_GIFT1 (1 << 3) // 10,000,000 Bells @@ -81,6 +82,7 @@ enum { #define mPr_CATALOG_ORDER_NUM 5 #define mPr_FOREIGN_MAP_COUNT 8 #define mPr_ORIGINAL_DESIGN_COUNT 8 +#define mPr_RADIOCARD_MAX_DAYS 13 #define mPr_GET_ITEM_COND(all_cond, slot_no) (((all_cond) >> (((u32)(slot_no)) << 1)) & mPr_ITEM_COND_NUM) #define mPr_SET_ITEM_COND(all_cond, slot_no, cond) (((all_cond) & ~((u32)mPr_ITEM_COND_NUM << ((u32)(slot_no) << 1))) | ((u32)(cond) << ((u32)(i) << 1))) @@ -109,7 +111,9 @@ enum { mPr_DESTINY_UNPOPULAR, /* bad luck with villagers */ mPr_DESTINY_BAD_LUCK, /* bad luck in general */ mPr_DESTINY_MONEY_LUCK, /* good money luck */ - mPr_DESTINY_GOODS_LUCK /* good goods/item luck */ + mPr_DESTINY_GOODS_LUCK, /* good goods/item luck */ + + mPr_DESTINY_NUM }; /* sizeof(mPr_destiny_c) == 0xA */ @@ -145,20 +149,20 @@ typedef struct player_map_s { /* sizeof(mPr_day_day_c) == 6 */ typedef struct player_day_day_s { - /* 0x00 */ lbRTC_ymd_t last_date; /* last date modified */ + /* 0x00 */ lbRTC_ymd_c last_date; /* last date modified */ /* 0x04 */ u8 days; /* number of unique days */ } mPr_day_day_c; /* sizeof(mPr_sunburn_c) == 6 */ typedef struct player_sunburn_s { - /* 0x00 */ lbRTC_ymd_t last_changed_date; /* last date that the sunburn rank changed */ + /* 0x00 */ lbRTC_ymd_c last_changed_date; /* last date that the sunburn rank changed */ /* 0x04 */ s8 rank; /* level of sunburn, 0-8 */ /* 0x05 */ s8 rankdown_days; /* days until sunburn rank decreases */ } mPr_sunburn_c; /* sizeof(mPr_carde_data_c) == 0x32 */ typedef struct player_ecard_data_s { - /* 0x00 */ lbRTC_ymd_t letter_send_date; /* date the latest eCard letter was sent */ + /* 0x00 */ lbRTC_ymd_c letter_send_date; /* date the latest eCard letter was sent */ /* 0x04 */ u8 card_letters_sent[mPr_ECARD_LETTER_NUM]; /* bitfield keeping track of which eCard letters have been sent to the player [0, 366] */ } mPr_carde_data_c; @@ -172,10 +176,15 @@ typedef struct private_mother_mail_data_s { } mPr_mother_mail_data_c; typedef struct private_mother_mail_info_s { - lbRTC_ymd_t date; + lbRTC_ymd_c date; mPr_mother_mail_data_c data; } mPr_mother_mail_info_c; +typedef struct private_cloth_s { + u16 idx; + mActor_name_t item; +} mPr_cloth_c; + struct private_s { /* 0x0000 */ PersonalID_c player_ID; /* player's id info */ /* 0x0014 */ s8 gender; /* gender/sex of player */ @@ -204,8 +213,9 @@ struct private_s { /* 0x1086 */ u8 exists; /* 0/1 if player exists or not */ /* 0x1087 */ u8 hint_count; /* total hints heard from villagers (initial dialog) */ - /* 0x1088 */ u16 cloth_idx; /* index value for texture? */ - /* 0x108A */ mActor_name_t cloth; /* shirt item */ + /* 0x1088 */ mPr_cloth_c cloth; + /* 0x1088 */ //u16 cloth_idx; /* index value for texture? */ + /* 0x108A */ //mActor_name_t cloth; /* shirt item */ /* 0x108C */ AnmPersonalID_c stored_anm_id; /* foriegn animal personal ID leftover from N64? */ @@ -235,12 +245,12 @@ struct private_s { /* 0x2348 */ u32 state_flags; /* TODO: this might be a bitfield/struct, also document bits */ /* 0x234C */ mCD_player_calendar_c calendar; /* player calendar data */ /* 0x23B4 */ u32 soncho_trophy_field0; /* first 28 tortimer event flags */ - /* 0x23B8 */ mPr_day_day_c needlework_day; /* info for how many unique days the player has talked to Sable */ - /* 0x23BE */ mPr_day_day_c radio_day; /* radio stamp days */ + /* 0x23B8 */ mPr_day_day_c nw_visitor; /* info for how many unique days the player has talked to Sable */ + /* 0x23BE */ mPr_day_day_c radiocard; /* radio stamp days */ /* 0x23C4 */ mPr_sunburn_c sunburn; /* sunburn state */ /* 0x23CA */ u8 unused_23CA[14]; /* seemingly unused data */ /* 0x23D8 */ mActor_name_t birthday_present_npc; /* npc id of the 'best friend' villger who will gift the player a present on their birthday (at the door) */ - /* 0x23DA */ u16 golden_items_collected; /* bitfield tracking which golden items the player has received */ + /* 0x23DA */ u8 golden_items_collected; /* bitfield tracking which golden items the player has received */ /* 0x23DC */ u32 soncho_trophy_field1; /* remaining tortimer event flags */ /* 0x23E0 */ mPr_carde_data_c ecard_letter_data; /* info relating to scanned e-Card letters */ /* 0x2412 */ u8 unused_2412[46]; diff --git a/include/m_shop.h b/include/m_shop.h index f3095b7a..ed137d36 100644 --- a/include/m_shop.h +++ b/include/m_shop.h @@ -93,6 +93,14 @@ enum { mSP_KIND_MAX }; +enum { + mSP_PRIORITY_COMMON, + mSP_PRIORITY_UNCOMMON, + mSP_PRIORITY_RARE, + + mSP_PRIORITY_NUM +}; + /* sizeof(mSP_goods_priority_list_c) == 1 */ typedef struct shop_goods_priority_list_s { u8 a:2; /* list A rarity */ diff --git a/include/m_snowman.h b/include/m_snowman.h index 2b4c877e..82150c85 100644 --- a/include/m_snowman.h +++ b/include/m_snowman.h @@ -28,7 +28,7 @@ typedef struct snowman_save_data_s { typedef struct snowman_info_s{ /* 0x00 */ int scale; /* 0x04 */ xyz_t pos; -}mSN_snowman_info_c; +} mSN_snowman_info_c; extern int mSN_check_life(mActor_name_t* ac, int idx); extern int mSN_ClearSnowmanData(mActor_name_t* ac, int idx); diff --git a/include/m_time.h b/include/m_time.h index f3d9bc4e..986767c6 100644 --- a/include/m_time.h +++ b/include/m_time.h @@ -76,8 +76,8 @@ extern void mTM_set_season(); extern int mTM_check_renew_time(u8 renew_flag); extern void mTM_off_renew_time(u8 renew_flag); extern void mTM_set_renew_is(); -extern void mTM_set_renew_time(lbRTC_ymd_t* renew_time, const lbRTC_time_c* time); -extern void mTM_ymd_2_time(lbRTC_time_c* time, lbRTC_ymd_t* ymd); +extern void mTM_set_renew_time(lbRTC_ymd_c* renew_time, const lbRTC_time_c* time); +extern void mTM_ymd_2_time(lbRTC_time_c* time, lbRTC_ymd_c* ymd); extern void mTM_renewal_renew_time(); extern void mTM_clear_renew_is(); extern void mTM_rtcTime_limit_check(); @@ -85,7 +85,7 @@ extern void mTM_time(); extern void mTM_time_init(); extern const lbRTC_time_c mTM_rtcTime_clear_code; -extern const lbRTC_ymd_t mTM_rtcTime_ymd_clear_code; +extern const lbRTC_ymd_c mTM_rtcTime_ymd_clear_code; extern const lbRTC_time_c mTM_rtcTime_default_code; #define mTM_IsTimeCleared(time) (lbRTC_IsEqualTime((time), &mTM_rtcTime_clear_code, lbRTC_CHECK_ALL) == TRUE) diff --git a/rel/lb_reki.c b/rel/lb_reki.c index c99f2e57..4d25f7b1 100644 --- a/rel/lb_reki.c +++ b/rel/lb_reki.c @@ -218,7 +218,7 @@ static int lbRk_KyuurekiDays(int year, int month) { * @param kyuu_ymd The input date in the kyuureki calendar. * @return TRUE if the conversion is successful, FALSE if the input date is invalid. */ -extern int lbRk_ToSeiyouReki(lbRTC_ymd_t* seiyo_ymd, const lbRTC_ymd_t* kyuu_ymd) { +extern int lbRk_ToSeiyouReki(lbRTC_ymd_c* seiyo_ymd, const lbRTC_ymd_c* kyuu_ymd) { int seireki_days; int year; int month; @@ -275,9 +275,9 @@ extern int lbRk_ToSeiyouReki(lbRTC_ymd_t* seiyo_ymd, const lbRTC_ymd_t* kyuu_ymd * @param seiyo_ymd The input date in the Gregorian calendar. * @return TRUE if the conversion is successful, FALSE if the input date is invalid. */ -extern int lbRk_ToKyuuReki(lbRTC_ymd_t* kyuu_ymd, const lbRTC_ymd_t* seiyo_ymd) { - lbRTC_ymd_t kyuu_date = (lbRTC_ymd_t){lbRk_YEAR_MIN, lbRk_KYUU_MONTH_START, lbRk_KYUU_DAY_START}; - lbRTC_ymd_t seyio_date; +extern int lbRk_ToKyuuReki(lbRTC_ymd_c* kyuu_ymd, const lbRTC_ymd_c* seiyo_ymd) { + lbRTC_ymd_c kyuu_date = (lbRTC_ymd_c){lbRk_YEAR_MIN, lbRk_KYUU_MONTH_START, lbRk_KYUU_DAY_START}; + lbRTC_ymd_c seyio_date; while (TRUE) { // Attempt to convert the current kyuureki date to Gregorian date @@ -355,7 +355,7 @@ extern int lbRk_AutumnalEquinoxDay(int year) { * @param harvest_moon_day The output Harvest Moon Day in the Gregorian calendar. * @param year The input year. */ -extern void lbRk_HarvestMoonDay(lbRTC_ymd_t* harvest_moon_day, int year) { +extern void lbRk_HarvestMoonDay(lbRTC_ymd_c* harvest_moon_day, int year) { /* Array of precomputed Seiyo Reki (Gregorian calendar) Havest Moon Day dates. */ static lbRk_date_t ev_day[lbRk_HARVEST_MOON_YEAR_NUM] = { @@ -390,7 +390,7 @@ extern void lbRk_HarvestMoonDay(lbRTC_ymd_t* harvest_moon_day, int year) { /* 2030 */ {9, 11} }; - lbRTC_ymd_t kyuu_ymd; + lbRTC_ymd_c kyuu_ymd; // If the year is within the pre-calculated range, use the stored values if ((year >= lbRk_HARVEST_MOON_YEAR_MIN) && (year < lbRk_HARVEST_MOON_YEAR_MAX + 1)) { diff --git a/rel/lb_rtc.c b/rel/lb_rtc.c index 8bff6cc0..11bb9704 100644 --- a/rel/lb_rtc.c +++ b/rel/lb_rtc.c @@ -300,7 +300,7 @@ extern lbRTC_day_t lbRTC_GetDaysByMonth(lbRTC_year_t year, lbRTC_month_t month) typedef union { int raw; - lbRTC_ymd_t ymd; + lbRTC_ymd_c ymd; } ymd_u; /** @@ -608,17 +608,17 @@ extern int lbRTC_GetIntervalDays(const lbRTC_time_c* t0, const lbRTC_time_c* t1) } /** - * @brief Calculate the number of days between two dates using lbRTC_ymd_t structures. + * @brief Calculate the number of days between two dates using lbRTC_ymd_c structures. * - * This function calculates the number of days between two given lbRTC_ymd_t + * This function calculates the number of days between two given lbRTC_ymd_c * structures. It returns the interval in days as an integer. If ymd0 is greater than * ymd1, the interval will be negative. * - * @param ymd0 Pointer to the first lbRTC_ymd_t structure. - * @param ymd1 Pointer to the second lbRTC_ymd_t structure. + * @param ymd0 Pointer to the first lbRTC_ymd_c structure. + * @param ymd1 Pointer to the second lbRTC_ymd_c structure. * @return Number of days between the two given dates, negative if ymd0 is greater than ymd1. */ -extern int lbRTC_GetIntervalDays2(lbRTC_ymd_t* ymd0, lbRTC_ymd_t* ymd1) { +extern int lbRTC_GetIntervalDays2(lbRTC_ymd_c* ymd0, lbRTC_ymd_c* ymd1) { lbRTC_time_c t0, t1; int equality; diff --git a/rel/m_calendar.c b/rel/m_calendar.c index 640a3546..460eba3a 100644 --- a/rel/m_calendar.c +++ b/rel/m_calendar.c @@ -101,7 +101,7 @@ static void mCD_calendar_clear_day(mCD_player_calendar_c* calendar, lbRTC_year_t case lbRTC_SEPTEMBER: { - lbRTC_ymd_t harvest_moon_day; + lbRTC_ymd_c harvest_moon_day; lbRk_HarvestMoonDay(&harvest_moon_day, year); @@ -114,7 +114,7 @@ static void mCD_calendar_clear_day(mCD_player_calendar_c* calendar, lbRTC_year_t case lbRTC_OCTOBER: { - lbRTC_ymd_t harvest_moon_day; + lbRTC_ymd_c harvest_moon_day; lbRk_HarvestMoonDay(&harvest_moon_day, year); diff --git a/rel/m_flashrom.c b/rel/m_flashrom.c index 914981b5..6ea03d89 100644 --- a/rel/m_flashrom.c +++ b/rel/m_flashrom.c @@ -36,6 +36,7 @@ #include "m_common_data.h" #include "m_time.h" #include "m_land.h" +#include "m_name_table.h" #include "zurumode.h" static int l_mfrm_msg_idx; @@ -43,14 +44,11 @@ static int l_mfrm_now_color; static mFRm_err_info_c l_mfrm_err_info[mFRm_ERROR_INFO_NUM]; static int l_mfrm_err_debug[] = {0, 0, 0, 0, 0, 0}; -/* Predeclaration for save check functions */ -static int sChk_check_save_data(); -static int sChk_check_save_gen(); -static int sChk_CheckSaveData_MYK(); -static int sChk_CheckSaveData_NSW(); -static int sChk_check_save_take(); -static int sChk_CheckSaveData_YSD(); -static int sChk_CheckSaveData_komatu(); +BSS_ORDER_GROUP_START + BSS_ORDER_ITEM(l_mfrm_msg_idx); + BSS_ORDER_ITEM(l_mfrm_now_color); + BSS_ORDER_ITEM(l_mfrm_err_info); +BSS_ORDER_GROUP_END /** * @brief Set the current message index value. @@ -74,6 +72,16 @@ extern int mFRm_get_msg_idx() { return l_mfrm_msg_idx; } +/* @fabricated - necessary for including some strings in .data */ +extern MATCH_FORCESTRIP void mFRm_PrintErrInfo(gfxprint_t* gfxprint) { + gfxprint_printf(gfxprint, "N"); + gfxprint_printf(gfxprint, "A"); + gfxprint_printf(gfxprint, "W"); + gfxprint_printf(gfxprint, "R"); + gfxprint_printf(gfxprint, "C"); + gfxprint_printf(gfxprint, "O"); +} + /** * @brief Calculate the checksum of the given data. * @@ -225,6 +233,17 @@ extern void mFRm_PrintSavedDebug(gfxprint_t* gfxprint) { } } +/* Color table for displaying error information */ +static u32 l_mfrm_color_table[7][3] = { + { 0, 0, 0}, /* Black */ + {255, 0, 0}, /* Red */ + {255, 255, 255}, /* White */ + { 0, 190, 0}, /* Green */ + {100, 100, 100}, /* Gray */ + { 0, 0, 255}, /* Blue */ + {255, 0, 255} /* Magenta */ +}; + /** * @brief Clear the error information. * @@ -312,6 +331,17 @@ static int mFRm_get_errInfoNum(mFRm_err_info_c* err_info, int count) { return ret; } +#define mFRm_ERRORLINE(line) mFRm_set_errInfo(l_mfrm_err_info, (line), l_mfrm_now_color) +#define mFRm_ERROR() mFRm_ERRORLINE(__LINE__) + +#include "../rel/save_check.c_inc" +#include "../rel/save_check_gen.c_inc" +#include "../rel/save_check_MYK.c_inc" +#include "../rel/save_check_NSW.c_inc" +#include "../rel/save_check_take.c_inc" +#include "../rel/save_check_YSD.c_inc" +#include "../rel/save_check_komatu.c_inc" + /** * @brief Perform save data checks. * @@ -343,19 +373,6 @@ extern void mFRm_save_data_check() { } } -/* Color table for displaying error information */ -static u32 l_mfrm_color_table[7][3] = { - { 0, 0, 0}, /* Black */ - {255, 0, 0}, /* Red */ - {255, 255, 255}, /* White */ - { 0, 190, 0}, /* Green */ - {100, 100, 100}, /* Gray */ - { 0, 0, 255}, /* Blue */ - {255, 0, 255} /* Magenta */ -}; - -/* This needs pool_data on */ -#pragma pool_data on /** * @brief Display error information on the screen. * @@ -406,4 +423,3 @@ extern void mFRm_display_errInfo(gfxprint_t* gfxprint) { } } } -#pragma pool_data reset diff --git a/rel/m_mail.c b/rel/m_mail.c index d3734f10..bd7ecac2 100644 --- a/rel/m_mail.c +++ b/rel/m_mail.c @@ -56,10 +56,10 @@ extern int mMl_strlen2(int* found, u8* str, int size, u8 end_char) { extern void mMl_clear_mail_header(Mail_hdr_c* header) { mPr_ClearPersonalID(&header->recipient.personalID); - header->recipient.type = mMl_TYPE_CLEAR; + header->recipient.type = mMl_NAME_TYPE_CLEAR; mPr_ClearPersonalID(&header->sender.personalID); - header->sender.type = mMl_TYPE_CLEAR; + header->sender.type = mMl_NAME_TYPE_CLEAR; } extern void mMl_clear_mail(Mail_c* mail) { diff --git a/rel/m_map_ovl.c b/rel/m_map_ovl.c index 2f935ff3..624c2924 100644 --- a/rel/m_map_ovl.c +++ b/rel/m_map_ovl.c @@ -561,9 +561,9 @@ static void mMP_make_max_no_table(int* max_no_table, int count) { if (mMP_check_bg_kind(type) == TRUE) { max_no_table[0] = type; - if (Save_Get(plus_bridge.exists) && - Save_Get(plus_bridge.block_x) == bx && - Save_Get(plus_bridge.block_z) == bz && + if (Save_Get(bridge.exists) && + Save_Get(bridge.block_x) == bx && + Save_Get(bridge.block_z) == bz && pluss_bridge[type] != 0xFF ) { max_no_table[0] = pluss_bridge[type]; diff --git a/rel/m_mushroom.c b/rel/m_mushroom.c index 2157cf16..20e85785 100644 --- a/rel/m_mushroom.c +++ b/rel/m_mushroom.c @@ -15,12 +15,12 @@ static lbRTC_time_c l_mmsr_zeto_time = { 0, 0, 0, 0, 0, 0, 0 }; /** - * @brief Converts a saved time in mMsr_MushTime_c format into its lbRTC_time_c representation. + * @brief Converts a saved time in mMsr_time_c format into its lbRTC_time_c representation. * * @param dst The destination lbRTC_time_c - * @param src The source mMsr_MushTime_c + * @param src The source mMsr_time_c **/ -static void mMsr_Mushtime2Rtc(lbRTC_time_c* dst, const mMsr_MushTime_c* src) { +static void mMsr_Mushtime2Rtc(lbRTC_time_c* dst, const mMsr_time_c* src) { dst->year = src->year; dst->month = src->month; dst->day = src->day; @@ -31,12 +31,12 @@ static void mMsr_Mushtime2Rtc(lbRTC_time_c* dst, const mMsr_MushTime_c* src) { } /** - * @brief Converts time in lbRTC_time_c format into its mMsr_MushTime_c representation. + * @brief Converts time in lbRTC_time_c format into its mMsr_time_c representation. * - * @param dst The destination mMsr_MushTime_c + * @param dst The destination mMsr_time_c * @param src The source lbRTC_time_c **/ -static void mMsr_Rtc2MushTime(mMsr_MushTime_c* dst, const lbRTC_time_c* src) { +static void mMsr_Rtc2MushTime(mMsr_time_c* dst, const lbRTC_time_c* src) { dst->year = src->year; dst->month = src->month; dst->day = src->day; @@ -332,7 +332,7 @@ static void mMsr_ClearMushrooms(int clear_num, int block_x, int block_z) { extern void mMsr_FirstClearMushroom() { int first_clear_num; lbRTC_time_c mush_rtc_time; - mMsr_MushTime_c* mush_time = Save_GetPointer(mushroom_time); + mMsr_time_c* mush_time = Save_GetPointer(mushroom_time); const lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); mMsr_Mushtime2Rtc(&mush_rtc_time, mush_time); @@ -668,7 +668,7 @@ static void mMsr_SetMushroomNum(int mushroom_num, int player_bx, int player_bz) extern void mMsr_SetMushroom(xyz_t player_pos) { int player_bx, player_bz; lbRTC_time_c mush_rtc; - mMsr_MushTime_c* mush_time = Save_GetPointer(mushroom_time); + mMsr_time_c* mush_time = Save_GetPointer(mushroom_time); const lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); mMsr_Mushtime2Rtc(&mush_rtc, mush_time); diff --git a/rel/m_notice.c b/rel/m_notice.c index dbe101c7..1e3a57bf 100644 --- a/rel/m_notice.c +++ b/rel/m_notice.c @@ -438,13 +438,13 @@ static void mNtc_set_auto_nwrite_common_string() { mHandbill_Set_free_str(1, shop_name, 16); } -static void mNtc_set_auto_nwrite_fishing_string(const lbRTC_ymd_t* date) { +static void mNtc_set_auto_nwrite_fishing_string(const lbRTC_ymd_c* date) { u8 month_str[] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }; u8 day_str[] = { ' ', ' ', ' ', ' ' }; u8 size_str[] = { ' ', ' ' }; PersonalID_c winner_pid; u32 size; - lbRTC_ymd_t win_date = *date; + lbRTC_ymd_c win_date = *date; mEv_fishRecord_holder(&winner_pid, &size, &win_date); mFont_UnintToString(size_str, 2, size, 2, 0, 0, TRUE); @@ -457,7 +457,7 @@ static void mNtc_set_auto_nwrite_fishing_string(const lbRTC_ymd_t* date) { } static void mNtc_set_auto_nwrite_string(lbRTC_year_t year) { - lbRTC_ymd_t harvest_moon_date; + lbRTC_ymd_c harvest_moon_date; int autumnal_equi_day; int len; u8 buf[28]; @@ -483,11 +483,11 @@ extern void mNtc_auto_nwrite_time_ct() { } /* TODO: better understand this function & refactor */ -static int mNtc_get_fishing_day(lbRTC_ymd_t* ymds, u16* dates, lbRTC_time_c* time, u16* fishing_term_date) { +static int mNtc_get_fishing_day(lbRTC_ymd_c* ymds, u16* dates, lbRTC_time_c* time, u16* fishing_term_date) { int notice_year; int notice_hour; lbRTC_time_c time_temp; - lbRTC_ymd_t ymd_buf[5]; + lbRTC_ymd_c ymd_buf[5]; int valid_count = 0; int i; @@ -517,7 +517,7 @@ static int mNtc_get_fishing_day(lbRTC_ymd_t* ymds, u16* dates, lbRTC_time_c* tim } for (i = 0; i < 5; i++) { - lbRTC_ymd_t* ymd = ymd_buf + i; + lbRTC_ymd_c* ymd = ymd_buf + i; u16 month_day = (ymd_buf[i].month << 8) + ymd_buf[i].day; if (ymd->year > notice_year || @@ -563,7 +563,7 @@ static void mNtc_decide_nwrite_data( int* fishing_day, u16 fishing_term_date, lbRTC_year_t fishing_term_year, - lbRTC_ymd_t* ymds, + lbRTC_ymd_c* ymds, u16* month_days ) { @@ -609,7 +609,7 @@ static void mNtc_decide_nwrite_data( // @nonmatching /* TODO: match */ -static void mNtc_set_auto_nwrite(int write_count, u8* nwrite_nums, lbRTC_year_t* nwrite_years, int fishing_day, lbRTC_ymd_t* ymds, u16* month_days) { +static void mNtc_set_auto_nwrite(int write_count, u8* nwrite_nums, lbRTC_year_t* nwrite_years, int fishing_day, lbRTC_ymd_c* ymds, u16* month_days) { mNtc_board_post_c post; lbRTC_year_t now_year; int header_back_pos; @@ -628,8 +628,8 @@ static void mNtc_set_auto_nwrite(int write_count, u8* nwrite_nums, lbRTC_year_t* for (write_count; write_count < 5; write_count++) { /* write 'fishing day' info */ if (nwrite_nums[write_count] == mNtc_FISHING_DAY_NUM && nwrite_years[write_count] == mNtc_FISHING_DAY_YEAR) { - lbRTC_ymd_t* post_date = ymds + fishing_day; - lbRTC_ymd_t temp; + lbRTC_ymd_c* post_date = ymds + fishing_day; + lbRTC_ymd_c temp; int id; post.post_time.year = post_date->year; post.post_time.month = mNtc_GET_MONTH(month_days[fishing_day]); @@ -674,7 +674,7 @@ extern void mNtc_set_auto_nwrite_data() { u8 now_nwrite_num; lbRTC_time_c rtc_time; u8 set_nwrite_nums[5]; - lbRTC_ymd_t nwrite_ymds[mNtc_NWRITE_NUM]; + lbRTC_ymd_c nwrite_ymds[mNtc_NWRITE_NUM]; u16 nwrite_dates[mNtc_NWRITE_NUM]; lbRTC_year_t set_nwrite_years[mNtc_NWRITE_NUM]; int write_count; diff --git a/rel/m_private.c b/rel/m_private.c index a1bbb37e..fda89258 100644 --- a/rel/m_private.c +++ b/rel/m_private.c @@ -1204,7 +1204,7 @@ extern void mPr_SendMailFromMother() { if (mLd_PlayerManKindCheckNo(player_no) == FALSE && priv != NULL && mPr_NullCheckPersonalID(&priv->player_ID) == FALSE) { mPr_mother_mail_info_c* mother_mail = Save_GetPointer(mother_mail[player_no]); - lbRTC_ymd_t* mail_date = &mother_mail->date; + lbRTC_ymd_c* mail_date = &mother_mail->date; if (mail_date->year != mTM_rtcTime_ymd_clear_code.year && mail_date->month != mTM_rtcTime_ymd_clear_code.month && mail_date->day != mTM_rtcTime_ymd_clear_code.day) { if (mail_date->year != rtc_time->year || mail_date->month != rtc_time->month || mail_date->day != rtc_time->day) { diff --git a/rel/m_select.c b/rel/m_select.c index 43ca8c45..0e090309 100644 --- a/rel/m_select.c +++ b/rel/m_select.c @@ -437,7 +437,7 @@ static int select_check_A_button_swell(GAME_SELECT* select) { } static int select_check_A_button_sunburn(GAME_SELECT* select) { - lbRTC_ymd_t renew_time; + lbRTC_ymd_c renew_time; mPr_sunburn_c sunburn = Common_Get(now_private)->sunburn; mTM_set_renew_time(&renew_time, Common_GetPointer(time.rtc_time)); @@ -819,7 +819,7 @@ static void select_move_cloth_sel(GAME_SELECT* select) { select->status = 1; } else { - int cloth = Common_Get(now_private)->cloth - ITM_CLOTH001; // shouldn't this be CLOTH000? + int cloth = Common_Get(now_private)->cloth.item - ITM_CLOTH001; // shouldn't this be CLOTH000? int adjust = (chkButton(BUTTON_B)) ? 10 : 1; if (chkButton(BUTTON_DDOWN)) { @@ -856,7 +856,7 @@ static void select_move_cloth_sel(GAME_SELECT* select) { cloth -= CLOTH_NUM; } - Common_Get(now_private)->cloth = ITM_CLOTH001 + cloth; + Common_Get(now_private)->cloth.item = ITM_CLOTH001 + cloth; } } @@ -1082,7 +1082,7 @@ static void select_print_cloth(gfxprint_t* gfxprint, GAME_SELECT* select) { gfxprint_color(gfxprint, 255, 180, 180, 255); } - gfxprint_printf(gfxprint, "フク :%03d", Common_Get(now_private)->cloth - ITM_CLOTH_START); + gfxprint_printf(gfxprint, "フク :%03d", Common_Get(now_private)->cloth.item - ITM_CLOTH_START); } static void select_print_swell(gfxprint_t* gfxprint, GAME_SELECT* select) { diff --git a/rel/m_time.c b/rel/m_time.c index dd434a71..49636102 100644 --- a/rel/m_time.c +++ b/rel/m_time.c @@ -56,7 +56,7 @@ const lbRTC_time_c mTM_rtcTime_clear_code = { 0xFFFF }; -const lbRTC_ymd_t mTM_rtcTime_ymd_clear_code = { +const lbRTC_ymd_c mTM_rtcTime_ymd_clear_code = { 0xFFFF, 0xFF, 0xFF }; @@ -249,22 +249,22 @@ extern void mTM_set_renew_is() { /** * Set the renewal time based on the given lbRTC_time_c struct. * - * @param renew_time Pointer to the lbRTC_ymd_t struct where the renewal time will be stored. + * @param renew_time Pointer to the lbRTC_ymd_c struct where the renewal time will be stored. * @param time Pointer to the lbRTC_time_c struct from which the renewal time will be taken. */ -extern void mTM_set_renew_time(lbRTC_ymd_t* renew_time, const lbRTC_time_c* time) { +extern void mTM_set_renew_time(lbRTC_ymd_c* renew_time, const lbRTC_time_c* time) { renew_time->year = time->year; renew_time->month = time->month; renew_time->day = time->day; } /** - * Convert lbRTC_ymd_t to lbRTC_time_c, setting time to midnight and calculating the weekday. + * Convert lbRTC_ymd_c to lbRTC_time_c, setting time to midnight and calculating the weekday. * * @param time Pointer to the lbRTC_time_c struct where the converted time will be stored. - * @param ymd Pointer to the lbRTC_ymd_t struct containing the date to be converted. + * @param ymd Pointer to the lbRTC_ymd_c struct containing the date to be converted. */ -extern void mTM_ymd_2_time(lbRTC_time_c* time, lbRTC_ymd_t* ymd) { +extern void mTM_ymd_2_time(lbRTC_time_c* time, lbRTC_ymd_c* ymd) { time->year = ymd->year; time->month = ymd->month; time->day = ymd->day; @@ -278,7 +278,7 @@ extern void mTM_ymd_2_time(lbRTC_time_c* time, lbRTC_ymd_t* ymd) { * Check if the renewal time has changed, and if so, update the renewal time and set renewal flags. */ extern void mTM_renewal_renew_time() { - lbRTC_ymd_t* renew_time = Save_GetPointer(renew_time); + lbRTC_ymd_c* renew_time = Save_GetPointer(renew_time); const lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); // Check if the renewal time has changed diff --git a/rel/save_check.c_inc b/rel/save_check.c_inc index e69de29b..5f341dda 100644 --- a/rel/save_check.c_inc +++ b/rel/save_check.c_inc @@ -0,0 +1,582 @@ +#include "m_mushroom.h" +#include "m_house.h" + +static int sChk_block_num_sub(u32 block_x, u32 block_z) { + int res = FALSE; + + if (block_x > FG_BLOCK_X_NUM && block_x != 0xFF) { + mFRm_ERRORLINE(79); + res = TRUE; + } + + if (block_z > FG_BLOCK_Z_NUM && block_z != 0xFF) { + mFRm_ERRORLINE(90); + res = TRUE; + } + + if (block_z == mISL_BLOCK_Z && (block_x == mISL_BLOCK_X0 || block_x == mISL_BLOCK_X1)) { + res = FALSE; + } + + return res; +} + +static int sChk_ut_num_sub(u32 ut_x, u32 ut_z) { + int res = FALSE; + + if (ut_x >= UT_X_NUM && ut_x != 0xFF) { + mFRm_ERRORLINE(140); + res = TRUE; + } + + if (ut_z >= UT_Z_NUM && ut_z != 0xFF) { + mFRm_ERRORLINE(151); + res = TRUE; + } + + return res; +} + +static int sChk_ItemFG_sub(mActor_name_t item) { + int res = FALSE; + + if (item != EMPTY_NO && (ITEM_NAME_GET_TYPE(item) >= NAME_TYPE_WARP || ITEM_NAME_GET_TYPE(item) < NAME_TYPE_FTR0)) { + mFRm_ERRORLINE(201); + res = TRUE; + } + + return res; +} + +static int sChk_cloth_sub(mActor_name_t item) { + int valid_cloth; + int res = FALSE; + + valid_cloth = item == RSV_CLOTH || (item >= ITM_CLOTH_START && item < ITM_CLOTH_END); + + if (valid_cloth == FALSE && item != EMPTY_NO) { + mFRm_ERRORLINE(247); + res = TRUE; + } + + return res; +} + +static int sChk_fruit_sub(mActor_name_t item) { + int res = FALSE; + + if (item < ITM_FOOD_APPLE || item > ITM_FOOD_ORANGE) { + mFRm_ERRORLINE(288); + res = TRUE; + } + + return res; +} + +static int sChk_OSRTCTime_sub(OSRTCTime* time) { + int res = FALSE; + + if (time->year < GAME_YEAR_MIN || time->year > GAME_YEAR_MAX) { + res = TRUE; + } + + if (time->month == 0 || time->month > lbRTC_MONTHS_MAX) { + res = TRUE; + } + + if (time->day == 0 || time->day > 31) { + res = TRUE; + } + + if (time->weekday > lbRTC_SATURDAY) { + res = TRUE; + } + + if (time->hour > 23) { + res = TRUE; + } + + if (time->min > 59) { + res = TRUE; + } + + if (time->sec > 59) { + res = TRUE; + } + + if (res == TRUE) { + if (time->year == 0 && time->month == 0 && time->day == 0 && time->weekday == 0 && time->hour == 0 && time->min == 0 && time->sec == 0) { + res = FALSE; + } + else if (mTM_AreTimesEqual(time, &mTM_rtcTime_clear_code) == TRUE) { + res = FALSE; + } + else { + mFRm_ERRORLINE(379); + } + } + + return res; +} + +static int sChk_lbRTC_ymd_c_sub(lbRTC_ymd_c* ymd) { + int res = FALSE; + + if (ymd->year < GAME_YEAR_MIN || ymd->year > GAME_YEAR_MAX) { + res = TRUE; + } + + if (ymd->month == 0 || ymd->month > lbRTC_MONTHS_MAX) { + res = TRUE; + } + + if (ymd->day == 0 || ymd->day > 31) { + res = TRUE; + } + + if (res == TRUE) { + if (ymd->year == 0 && ymd->month == 0 && ymd->day == 0) { + res = FALSE; + } + else if (ymd->year == mTM_rtcTime_ymd_clear_code.year && ymd->month == mTM_rtcTime_ymd_clear_code.month && ymd->day == mTM_rtcTime_ymd_clear_code.day) { + res = FALSE; + } + else { + mFRm_ERRORLINE(464); + } + } + + return res; +} + +static int sChk_Mail_nm_c_sub(Mail_nm_c* mail_name, int depth) { + int res = FALSE; + + if (mail_name->type >= mMl_NAME_TYPE_NUM && mail_name->type != mMl_NAME_TYPE_CLEAR) { + mFRm_ERRORLINE(519); + res = TRUE; + } + + return res; +} + +static int sChk_Mail_hdr_c_sub(Mail_hdr_c* mail_header, int depth) { + int res = FALSE; + + res |= sChk_Mail_nm_c_sub(&mail_header->recipient, depth + 1); + res |= sChk_Mail_nm_c_sub(&mail_header->sender, depth + 1); + + return res; +} + +static int sChk_font_sub(u8* font_p) { + int font = *font_p; + int res = FALSE; + + /* This check seems wrong lol */ + if (font != 0xFF && (font >= 0xFF || font >= mMl_FONT_NUM || font < mMl_FONT_0)) { + mFRm_ERRORLINE(612); + res = TRUE; + } + + return res; +} + +static int sChk_header_back_start_sub(u8* header_back_start_p) { + int res = FALSE; + + if (*header_back_start_p > MAIL_HEADER_LEN) { + mFRm_ERRORLINE(657); + res = TRUE; + } + + return res; +} + +static int sChk_paper_type_sub(u8* paper_type) { + int res = FALSE; + + if (*paper_type > (ITM_PAPER63 - ITM_PAPER00)) { + mFRm_ERRORLINE(701); + res = TRUE; + } + + return res; +} + +static int sChk_Mail_ct_c_sub(Mail_ct_c* contents, int depth) { + int res = sChk_font_sub(&contents->font); + + res |= sChk_header_back_start_sub(&contents->header_back_start); + + if (contents->mail_type > mMl_TYPE_12) { + mFRm_ERRORLINE(766); + res = TRUE; + } + + res |= sChk_paper_type_sub(&contents->paper_type); + + return res; +} + +static int sChk_Mail_c_sub(Mail_c* mail, int depth) { + int res = FALSE; + + res |= sChk_Mail_hdr_c_sub(&mail->header, depth + 1); + res |= sChk_ItemFG_sub(mail->present); + res |= sChk_Mail_ct_c_sub(&mail->content, depth + 1); + + return res; +} + +static int sChk_mHm_rmsz_c_sub(mHm_rmsz_c* room_size, int depth) { + lbRTC_ymd_c order_date_copy; + int res; + + order_date_copy.day = room_size->upgrade_order_date.day; + order_date_copy.month = room_size->upgrade_order_date.month; + order_date_copy.year = room_size->upgrade_order_date.year; + + res = sChk_lbRTC_ymd_c_sub(&order_date_copy); + + if (room_size->size >= mHm_HOMESIZE_NUM) { + mFRm_ERRORLINE(880); + res = TRUE; + } + + if (room_size->next_size >= mHm_HOMESIZE_NUM) { + mFRm_ERRORLINE(894); + res = TRUE; + } + + return res; +} + +static int sChk_Haniwa_Item_c_sub(Haniwa_Item_c* haniwa_item, int depth) { + int res = sChk_ItemFG_sub(haniwa_item->item); + + if (haniwa_item->exchange_type > mHm_HANIWA_TRADE_3) { + mFRm_ERRORLINE(947); + res = TRUE; + } + + return res; +} + +static int sChk_Haniwa_c_sub(Haniwa_c* haniwa, int depth) { + int i; + int res = FALSE; + + for (i = 0; i < HANIWA_ITEM_HOLD_NUM; i++) { + res |= sChk_Haniwa_Item_c_sub(haniwa->items + i, depth + 1); + } + + return res; +} + +static int sChk_outlook_pal_sub(u8 outlook_pal) { + int res = FALSE; + + if (outlook_pal >= mHm_OUTLOOK_PAL_NUM) { + mFRm_ERRORLINE(1035); + res = TRUE; + } + + return res; +} + +static int sChk_mHm_goki_c_sub(mHm_goki_c* goki, int depth) { + return sChk_OSRTCTime_sub(&goki->time); +} + +static int sChk_mHm_hs_c_sub(mHm_hs_c* house, int depth) { + int i; + int res = FALSE; + + res |= sChk_lbRTC_ymd_c_sub(&house->hra_mark_time); + res |= sChk_mHm_rmsz_c_sub(&house->size_info, depth + 1); + res |= sChk_outlook_pal_sub(house->outlook_pal); + res |= sChk_outlook_pal_sub(house->ordered_outlook_pal); + res |= sChk_outlook_pal_sub(house->next_outlook_pal); + + for (i = 0; i < HOME_MAILBOX_SIZE; i++) { + res |= sChk_Mail_c_sub(house->mailbox + i, depth + 1); + } + + res |= sChk_Haniwa_c_sub(&house->haniwa, depth + 1); + res |= sChk_mHm_goki_c_sub(&house->goki, depth + 1); + + return res; +} + +static int sChk_AnmPersonalID_c_sub(AnmPersonalID_c* pid, int depth) { + int res = FALSE; + + if (ITEM_NAME_GET_TYPE(pid->npc_id) != NAME_TYPE_NPC && pid->npc_id != EMPTY_NO) { + mFRm_ERRORLINE(1200); + res = TRUE; + } + + if (pid->looks > mNpc_LOOKS_NUM) { + mFRm_ERRORLINE(1214); + res = TRUE; + } + + return res; +} + +static int sChk_Anmplmail_c_sub(Anmplmail_c* animal_player_mail, int depth) { + int res = FALSE; + + res |= sChk_font_sub(&animal_player_mail->font); + res |= sChk_paper_type_sub(&animal_player_mail->paper_type); + res |= sChk_ItemFG_sub(animal_player_mail->present); + res |= sChk_header_back_start_sub(&animal_player_mail->header_back_start); + res |= sChk_lbRTC_ymd_c_sub(&animal_player_mail->date); + + return res; +} + +static int sChk_Anmmem_c_sub(Anmmem_c* animal_memory, int depth) { + int res = FALSE; + + res |= sChk_OSRTCTime_sub(&animal_memory->last_speak_time); + res |= sChk_Anmplmail_c_sub(&animal_memory->letter, depth + 1); + + return res; +} + +static int sChk_Anmhome_c_sub(Anmhome_c* animal_home, int depth) { + int res = FALSE; + + if (animal_home->type_unused > 5) { + mFRm_ERRORLINE(1365); + res = TRUE; + } + + res |= sChk_block_num_sub(animal_home->block_x, animal_home->block_z); + res |= sChk_ut_num_sub(animal_home->ut_x, animal_home->ut_z); + + return res; +} + +static int sChk_Animal_c_sub(Animal_c* animal, int depth) { + int i; + int res = FALSE; + + res |= sChk_AnmPersonalID_c_sub(&animal->id, depth + 1); + + for (i = 0; i < ANIMAL_MEMORY_NUM; i++) { + res |= sChk_Anmmem_c_sub(animal->memories + i, depth + 1); + } + + res |= sChk_Anmhome_c_sub(&animal->home_info, depth + 1); + + if (animal->mood >= mNpc_MOOD_NUM) { + mFRm_ERRORLINE(1458); + res = TRUE; + } + + res |= sChk_cloth_sub(animal->cloth); + + if ((animal->is_home & ~1)) { + mFRm_ERRORLINE(1474); + res = TRUE; + } + + res |= sChk_cloth_sub(animal->present_cloth); + + return res; +} + +static int sChk_Kabu_price_c_sub(Kabu_price_c* kabu_price, int depth) { + int res = FALSE; + int i; + + for (i = 0; i < lbRTC_WEEK; i++) { + if (kabu_price->daily_price[i] < Kabu_PRICE_MIN || kabu_price->daily_price[i] > Kabu_PRICE_MAX) { + mFRm_ERRORLINE(1531); + res = TRUE; + + break; + } + } + + if (kabu_price->trade_market >= Kabu_TRADE_MARKET_TYPE_NUM) { + mFRm_ERRORLINE(1554); + res = TRUE; + } + + res |= sChk_OSRTCTime_sub(&kabu_price->update_time); + + return res; +} + +static int sChk_PostOffice_c_sub(PostOffice_c* post_office, int depth) { + int i; + int res = FALSE; + + if (post_office->keep_mail_sum_players < 0 || post_office->keep_mail_sum_players > mPO_KEEP_MAIL_PLAYERS_MAX) { + mFRm_ERRORLINE(1617); + res = TRUE; + } + + if (post_office->keep_mail_sum_npcs < 0) { + mFRm_ERRORLINE(1632); + res = TRUE; + } + + if (post_office->mail_recipient_flags & (u16)(~0b1111)) { + mFRm_ERRORLINE(1647); + res = TRUE; + } + + for (i = 0; i < mPO_MAIL_STORAGE_SIZE; i++) { + res |= sChk_Mail_c_sub(post_office->mail + i, depth + 1); + } + + res |= sChk_Mail_c_sub(&post_office->leaflet, depth + 1); + res |= sChk_Mail_c_sub(&post_office->event_leaflet, depth + 1); + + if (post_office->leaflet_recipient_flags.leaflet_flags & (u16)(~0b1111)) { + mFRm_ERRORLINE(1668); + res = TRUE; + } + + if (post_office->leaflet_recipient_flags.event_flags & (u16)(~0b1111)) { + mFRm_ERRORLINE(1682); + res = TRUE; + } + + res |= sChk_OSRTCTime_sub(&post_office->delivery_time); + + return res; +} + +static int sChk_PoliceBox_c_sub(PoliceBox_c* police_box, int depth) { + int i; + int res = FALSE; + + for (i = 0; i < mPB_POLICE_BOX_ITEM_STORAGE_COUNT; i++) { + res |= sChk_ItemFG_sub(police_box->keep_items[i]); + } + + return res; +} + +static int sChk_Config_c_sub(Config_c* config, int depth) { + int res = FALSE; + + if (config->sound_mode > Config_SOUND_MODE_3) { + mFRm_ERRORLINE(1775); + res = TRUE; + } + + if (config->voice_mode > Config_VOICE_MODE_3) { + mFRm_ERRORLINE(1789); + res = TRUE; + } + + if (config->vibration_enabled & (~1)) { + mFRm_ERRORLINE(1803); + res = TRUE; + } + + return res; +} + +static int sChk_mMsr_time_c_sub(mMsr_time_c* mushroom_time, int depth) { + int res = FALSE; + + if (mushroom_time->year < GAME_YEAR_MIN && mushroom_time->year > GAME_YEAR_MAX) { + res = TRUE; + } + + if (mushroom_time->month == 0 || mushroom_time->month > lbRTC_DECEMBER) { + res = TRUE; + } + + if (mushroom_time->day == 0 || mushroom_time->day > 31) { + res = TRUE; + } + + if (mushroom_time->hour > 23) { + res = TRUE; + } + + if (res == TRUE) { + if ( + mushroom_time->year == 0 && + mushroom_time->month == 0 && + mushroom_time->day == 0 && + mushroom_time->hour == 0 && + mushroom_time->hour_quarter == 0 + ) { + res = FALSE; + } + else { + mFRm_ERRORLINE(1876); + } + } + + return res; +} + +static int sChk_MaskCat_c_sub(MaskCat_c* mask_cat, int depth) { + int valid_cloth; + int res = FALSE; + + if (mask_cat->palette_no >= mNW_PALETTE_NUM) { + mFRm_ERRORLINE(1935); + res = TRUE; + } + + /* This is definitely a macro */ + valid_cloth = (mActor_name_t)(mask_cat->cloth_no + ITM_CLOTH_START) >= ITM_CLOTH_START && (mActor_name_t)(mask_cat->cloth_no + ITM_CLOTH_START) < ITM_CLOTH_END; + if (valid_cloth == FALSE) { + mFRm_ERRORLINE(1949); + res = TRUE; + } + + if (mask_cat->talk_idx > mMC_TALK_IDX_MAX) { + mFRm_ERRORLINE(1963); + res = TRUE; + } + + res |= sChk_OSRTCTime_sub(&mask_cat->time); + + return res; +} + +static int sChk_check_save_data() { + int res = FALSE; + Save_t* save = Common_GetPointer(save.save); + int i; + + for (i = 0; i < mHS_HOUSE_NUM; i++) { + res |= sChk_mHm_hs_c_sub(save->homes + i, 1); + } + + for (i = 0; i < ANIMAL_NUM_MAX; i++) { + res |= sChk_Animal_c_sub(save->animals + i, 1); + } + + res |= sChk_AnmPersonalID_c_sub(&save->last_removed_animal_id, 1); + res |= sChk_Kabu_price_c_sub(&save->kabu_price_schedule, 1); + res |= sChk_fruit_sub(save->fruit); + res |= sChk_OSRTCTime_sub(&save->all_grow_renew_time); + res |= sChk_PostOffice_c_sub(&save->post_office, 1); + res |= sChk_PoliceBox_c_sub(&save->police_box, 1); + res |= sChk_Config_c_sub(&save->config, 1); + res |= sChk_lbRTC_ymd_c_sub(&save->renew_time); + res |= sChk_OSRTCTime_sub(&save->last_grow_time); + res |= sChk_mMsr_time_c_sub(&save->mushroom_time, 1); + res |= sChk_lbRTC_ymd_c_sub(&save->_021322); + res |= sChk_OSRTCTime_sub(&save->_02136E); + res |= sChk_OSRTCTime_sub(&save->treasure_buried_time); + res |= sChk_OSRTCTime_sub(&save->treasure_checked_time); + res |= sChk_lbRTC_ymd_c_sub(&save->force_remove_date); + res |= sChk_MaskCat_c_sub(&save->mask_cat, 1); + + return res; +} diff --git a/rel/save_check_MYK.c_inc b/rel/save_check_MYK.c_inc index e69de29b..327b472f 100644 --- a/rel/save_check_MYK.c_inc +++ b/rel/save_check_MYK.c_inc @@ -0,0 +1,281 @@ +#include "m_random_field.h" + +#define sSC_MYK_OK (0) +#define sSC_MYK_ERR_WEATHER (1 << 0) +#define sSC_MYK_ERR_SHOP (1 << 1) +#define sSC_MYK_ERR_HOUSE (1 << 2) +#define sSC_MYK_ERR_CATTAGE (1 << 3) +#define sSC_MYK_ERR_MUSEUMDISPLAY (1 << 4) +#define sSC_MYK_ERR_NEEDLEWORK (1 << 5) +#define sSC_MYK_ERR_MAP (1 << 7) + +static int sSC_CheckSaveData_Weather() { + int weather = mEnv_SAVE_GET_WEATHER_TYPE(Save_Get(weather)); + int intensity = mEnv_SAVE_GET_WEATHER_INTENSITY(Save_Get(weather)); + + if (weather >= mEnv_WEATHER_LEAVES) { + mFRm_ERRORLINE(78); + return sSC_MYK_ERR_WEATHER; + } + else if (intensity >= mEnv_WEATHER_INTENSITY_NUM) { + mFRm_ERRORLINE(82); + return sSC_MYK_ERR_WEATHER; + } + else { + return sSC_MYK_OK; + } +} + +static int sSC_CheckSaveData_Shop() { + Shop_c* shop = Save_GetPointer(shop); + mSP_goods_priority_list_c* prio_list = Save_GetPointer(shop)->priority_lists; + int i; + + for (i = 0; i < mSP_KIND_MAX; i++) { + if (prio_list->a >= mSP_PRIORITY_NUM) { + mFRm_ERRORLINE(101); + return sSC_MYK_ERR_SHOP; + } + + if (prio_list->b >= mSP_PRIORITY_NUM) { + mFRm_ERRORLINE(105); + return sSC_MYK_ERR_SHOP; + } + + if (prio_list->c >= mSP_PRIORITY_NUM) { + mFRm_ERRORLINE(109); + return sSC_MYK_ERR_SHOP; + } + + if (prio_list->pad != 0) { + mFRm_ERRORLINE(113); + return sSC_MYK_ERR_SHOP; + } + + prio_list++; + } + + return sSC_MYK_OK; +} + +static int sSC_CheckHouseSize(mHm_hs_c* house) { + return house->size_info.size < mHm_HOMESIZE_NUM; +} + +static int sSC_CheckHappyRoom(mHm_hs_c* house) { + return TRUE; +} + +static int sSC_CheckDoorOriginal(mHm_hs_c* house) { + if (house->door_original < mPr_ORIGINAL_DESIGN_COUNT || house->door_original == 0xFF) { + return TRUE; + } + + return FALSE; +} + +static int sSCCheckOneFloorData(mHm_flr_c* floor) { + return TRUE; +} + +static int sSC_CheckHouseInterior(mHm_hs_c* house) { + int i; + + for (i = 0; i < mHm_ROOM_NUM; i++) { + if (sSCCheckOneFloorData(house->floors + i) == 0) { + return FALSE; + } + } + + return TRUE; +} + +static int sSC_CheckSaveData_House() { + mHm_hs_c* house; + int i; + + for (i = 0; i < mHS_HOUSE_NUM; i++) { + house = Save_Get(homes) + i; + + if (sSC_CheckHouseSize(house) == 0) { + mFRm_ERRORLINE(220); + return sSC_MYK_ERR_HOUSE; + } + + if (sSC_CheckHappyRoom(house) == 0) { + mFRm_ERRORLINE(227); + return sSC_MYK_ERR_HOUSE; + } + + if (sSC_CheckDoorOriginal(house) == 0) { + mFRm_ERRORLINE(234); + return sSC_MYK_ERR_HOUSE; + } + + if (sSC_CheckHouseInterior(house) == 0) { + mFRm_ERRORLINE(241); + return sSC_MYK_ERR_HOUSE; + } + } + + return sSC_MYK_OK; +} + +static int sSC_CheckSaveData_Cattage() { + u8 floor = Save_Get(island).cottage.unused_wall_floor.flooring_idx; + u8 wall = Save_Get(island).cottage.unused_wall_floor.wallpaper_idx; + + if (sSCCheckOneFloorData(&Save_Get(island).cottage.room) == 0) { + return sSC_MYK_ERR_CATTAGE; + } + else if (floor >= CARPET_NUM && (floor < 87 || floor > 94)) { + return sSC_MYK_ERR_CATTAGE; + } + else if (wall >= WALL_NUM && (wall < 72 || wall > 79)) { + return sSC_MYK_ERR_CATTAGE; + } + else { + return sSC_MYK_OK; + } +} + +static int sSC_CheckMuseumBitData(u8* bits, int max) { + int i; + + for (i = 0; i < max; i++) { + int donator = mMmd_BIT_INFO2(bits, i); + + if (donator < 0 || donator >= 6) { + mFRm_ERRORLINE(289); + return FALSE; + } + } + + return TRUE; +} + +static int sSC_CheckSaveData_MuseumDisplay() { + if (sSC_CheckMuseumBitData(Save_Get(museum_display).fossil_bit, mMmd_FOSSIL_NUM) == FALSE) { + mFRm_ERRORLINE(300); + return sSC_MYK_ERR_MUSEUMDISPLAY; + } + else if (sSC_CheckMuseumBitData(Save_Get(museum_display).art_bit, mMmd_ART_NUM) == FALSE) { + mFRm_ERRORLINE(305); + return sSC_MYK_ERR_MUSEUMDISPLAY; + } + else if (sSC_CheckMuseumBitData(Save_Get(museum_display).fish_bit, mMmd_INSECT_NUM) == FALSE) { + mFRm_ERRORLINE(310); + return sSC_MYK_ERR_MUSEUMDISPLAY; + } + else if (sSC_CheckMuseumBitData(Save_Get(museum_display).insect_bit, mMmd_FISH_NUM) == FALSE) { + mFRm_ERRORLINE(315); + return sSC_MYK_ERR_MUSEUMDISPLAY; + } + else { + return sSC_MYK_OK; + } +} + +static int sSC_CheckOneOriginalData(mNW_original_design_c* original) { + if (original->palette >= mNW_PALETTE_NUM) { + mFRm_ERRORLINE(333); + return FALSE; + } + + return TRUE; +} + +static int sSC_CheckSaveData_Needlework() { + int j; + int i; + + for (i = 0; i < PLAYER_NUM; i++) { + for (j = 0; j < mPr_ORIGINAL_DESIGN_COUNT; j++) { + if (sSC_CheckOneOriginalData(Save_Get(private + i)->my_org + j) == FALSE) { + mFRm_ERRORLINE(348); + return sSC_MYK_ERR_NEEDLEWORK; + } + } + } + + for (i = 0; i < mNW_TOTAL_DESIGN_NUM; i++) { + if (sSC_CheckOneOriginalData(Save_Get(needlework).original_design + i) == FALSE) { + mFRm_ERRORLINE(356); + return sSC_MYK_ERR_NEEDLEWORK; + } + } + + return sSC_MYK_OK; +} + +static int sSC_BlockInfo2Count(u32 block_kind) { + mFM_combo_info_c* combi_table = data_combi_table; + int bx; + int bz; + int count = 0; + + for (bz = 0; bz < BLOCK_Z_NUM; bz++) { + for (bx = 0; bx < BLOCK_X_NUM; bx++) { + int block_no = Save_Get(combi_table)[bz][bx].combination_type; + + if (block_no < data_combi_table_number) { + u32 info = mRF_Type2BlockInfo(combi_table[block_no].type); + + if (info & block_kind) { + count++; + } + } + else { + return -1; + } + } + } + + return count; +} + +static u32 sSC_map_perfect_table[16] = { + mRF_BLOCKKIND_PLAYER, + mRF_BLOCKKIND_SHOP, + mRF_BLOCKKIND_SHRINE, + mRF_BLOCKKIND_POLICE, + mRF_BLOCKKIND_POSTOFFICE, + mRF_BLOCKKIND_STATION, + mRF_BLOCKKIND_BRIDGE, + mRF_BLOCKKIND_SLOPE, + mRF_BLOCKKIND_POOL, + mRF_BLOCKKIND_DUMP, + mRF_BLOCKKIND_MUSEUM, + mRF_BLOCKKIND_TAILORS, + mRF_BLOCKKIND_OCEAN, + mRF_BLOCKKIND_ISLAND, + mRF_BLOCKKIND_DOCK, + mRF_BLOCKKIND_ISLAND_LEFT +}; + +static int sSC_CheckSaveData_Map() { + int i; + + for (i = 0; i < 16; i++) { + if (sSC_BlockInfo2Count(sSC_map_perfect_table[i]) <= 0) { + mFRm_ERRORLINE(434); + return sSC_MYK_ERR_MAP; + } + } + + return sSC_MYK_OK; +} + +static int sChk_CheckSaveData_MYK() { + int res; + + res = sSC_CheckSaveData_Weather(); + res |= sSC_CheckSaveData_Shop(); + res |= sSC_CheckSaveData_House(); + res |= sSC_CheckSaveData_Cattage(); + res |= sSC_CheckSaveData_MuseumDisplay(); + res |= sSC_CheckSaveData_Needlework(); + res |= sSC_CheckSaveData_Map(); + + return res; +} diff --git a/rel/save_check_NSW.c_inc b/rel/save_check_NSW.c_inc index e69de29b..f159b398 100644 --- a/rel/save_check_NSW.c_inc +++ b/rel/save_check_NSW.c_inc @@ -0,0 +1,244 @@ +static int sChk_lbRTC_ymd_c_NSW(lbRTC_ymd_c* ymd) { + int res = FALSE; + + if (ymd->year < GAME_YEAR_MIN + 1 || ymd->year > GAME_YEAR_MAX - 1) { + res = TRUE; + } + + if (ymd->month == 0 || ymd->month > lbRTC_MONTHS_MAX) { + res = TRUE; + } + + if (ymd->day == 0 || ymd->day > 31) { + res = TRUE; + } + + if (res == TRUE) { + if (ymd->year == 0 && ymd->month == 0 && ymd->day == 0) { + res = FALSE; + } + else if (ymd->year == mTM_rtcTime_ymd_clear_code.year && ymd->month == mTM_rtcTime_ymd_clear_code.month && ymd->day == mTM_rtcTime_ymd_clear_code.day) { + res = FALSE; + } + + if (res == TRUE) { + mFRm_set_errInfo(l_mfrm_err_info, 91, l_mfrm_now_color); + } + } + + return res; +} + +static int sCck_CheckSaveData_radiocard_NSW(Private_c* priv) { + mPr_day_day_c* radiocard_p = &priv->radiocard; + int res; + + if (sChk_lbRTC_ymd_c_NSW(&radiocard_p->last_date)) { + mFRm_ERRORLINE(112); + res = TRUE; + } + else if (radiocard_p->days > mPr_RADIOCARD_MAX_DAYS) { + mFRm_ERRORLINE(121); + res = TRUE; + } + else { + res = FALSE; + } + + return res; +} + +static int sCck_CheckSaveData_calendar_NSW(Private_c* priv) { + int res; + + if (priv->calendar.edit > 1) { + mFRm_ERRORLINE(143); + res = TRUE; + } + else if (priv->calendar.pad_63 != 0) { + mFRm_ERRORLINE(151); + res = TRUE; + } + else if ( + ( + priv->calendar.year < GAME_YEAR_MIN + 1 || priv->calendar.year > GAME_YEAR_MAX - 1 || + priv->calendar.month == 0 || priv->calendar.month > lbRTC_DECEMBER + ) && + (priv->calendar.year != 0 || priv->calendar.month != 0) + ) { + mFRm_ERRORLINE(164); + res = TRUE; + } + else { + res = FALSE; + } + + return res; +} + +static int sCck_CheckSaveData_deposit_NSW(Private_c* priv) { + int res; + int deposit = priv->bank_account; + + if (deposit < 0 || deposit > mPr_DEPOSIT_MAX) { + mFRm_ERRORLINE(184); + res = TRUE; + } + else { + res = FALSE; + } + + return res; +} + +static int sCck_CheckSaveData_nw_visitor_NSW(Private_c* priv) { + mPr_day_day_c* nw_visitor_p = &priv->nw_visitor; + int res; + + if (sChk_lbRTC_ymd_c_NSW(&nw_visitor_p->last_date) != FALSE && nw_visitor_p->last_date.year != 0) { + mFRm_ERRORLINE(204); + res = TRUE; + } + else { + res = FALSE; + } + + return res; +} + +static int sCck_CheckSaveData_my_org_no_table_NSW(Private_c* priv) { + u8 my_org_no; + int field = 0; + int total = 0; + u8* my_org_no_table = priv->my_org_no_table; + int i; + int res; + + for (i = 0; i < mPr_ORIGINAL_DESIGN_COUNT; i++) { + my_org_no = my_org_no_table[i]; + + if (my_org_no >= mPr_ORIGINAL_DESIGN_COUNT) { + return TRUE; + } + + total += my_org_no; + field |= (u16)(1 << my_org_no); + } + + if ((u16)field != (u16)((1 << mPr_ORIGINAL_DESIGN_COUNT) - 1) && total != 0) { + mFRm_ERRORLINE(239); + res = TRUE; + } + else { + res = FALSE; + } + + return res; +} + +static int sCck_CheckSaveData_bridge_NSW() { + PlusBridge_c* bridge = Save_GetPointer(bridge); + + if (sChk_lbRTC_ymd_c_NSW(&bridge->build_date)) { + mFRm_ERRORLINE(259); + return TRUE; + } + else if (bridge->exists || bridge->pending) { + if ( + bridge->block_x == 0 || bridge->block_x > FG_BLOCK_X_NUM || + bridge->block_z == 0 || bridge->block_z > FG_BLOCK_Z_NUM + ) { + mFRm_ERRORLINE(271); + return TRUE; + } + } + else if (bridge->block_x != 0 || bridge->block_z != 0) { + mFRm_ERRORLINE(280); + return TRUE; + } + + return FALSE; +} + +static int sCck_CheckSaveData_fishRecord_NSW() { + mFR_record_c* record; + lbRTC_ymd_c ymd; + int i; + + for (i = 0; i < mFR_RECORD_NUM; i++) { + record = Save_Get(fishRecord + i); + mTM_set_renew_time(&ymd, &record->time); + + if (record->size < 0) { + mFRm_ERRORLINE(307); + return TRUE; + } + + if (record->size != 0 && sChk_lbRTC_ymd_c_NSW(&ymd) == TRUE) { + mFRm_ERRORLINE(316); + return TRUE; + } + } + + return FALSE; +} + +static int sCck_CheckSaveData_Anmret_NSW() { + Anmret_c* anmret = Save_GetPointer(return_animal); + int res; + lbRTC_ymd_c ymd; + + if (anmret->npc_id != EMPTY_NO && ITEM_NAME_GET_TYPE(anmret->npc_id) != NAME_TYPE_NPC) { + mFRm_ERRORLINE(339); + res = TRUE; + } + else { + mTM_set_renew_time(&ymd, &anmret->renew_time); + + if (sChk_lbRTC_ymd_c_NSW(&ymd) == TRUE) { + mFRm_ERRORLINE(349); + res = TRUE; + } + else { + res = FALSE; + } + } + + return res; +} + +static int sCck_CheckSaveData_LightHouse_NSW() { + int res; + + if (sChk_lbRTC_ymd_c_NSW(&Save_Get(LightHouse).renew_time) == TRUE) { + mFRm_ERRORLINE(368); + res = TRUE; + } + else { + res = FALSE; + } + + return res; +} + +static int sChk_CheckSaveData_NSW() { + int res = FALSE; + int i; + + for (i = 0; i < PLAYER_NUM; i++) { + Private_c* priv = Save_Get(private) + i; + + res |= sCck_CheckSaveData_radiocard_NSW(priv); + res |= sCck_CheckSaveData_calendar_NSW(priv); + res |= sCck_CheckSaveData_deposit_NSW(priv); + res |= sCck_CheckSaveData_nw_visitor_NSW(priv); + res |= sCck_CheckSaveData_my_org_no_table_NSW(priv); + } + + res |= sCck_CheckSaveData_bridge_NSW(); + res |= sCck_CheckSaveData_fishRecord_NSW(); + res |= sCck_CheckSaveData_Anmret_NSW(); + res |= sCck_CheckSaveData_LightHouse_NSW(); + + return res; +} diff --git a/rel/save_check_YSD.c_inc b/rel/save_check_YSD.c_inc index e69de29b..ebd91eec 100644 --- a/rel/save_check_YSD.c_inc +++ b/rel/save_check_YSD.c_inc @@ -0,0 +1,105 @@ +static int sCck_CheckSaveData_diary_body_YSD(Private_c* priv) { + return FALSE; +} + +static int sCCk_Check_ItemName(mActor_name_t item) { + /* TODO: do not hardcode this */ + static s16 item1_kinds[ITEM1_CAT_NUM] = { + 255, + 3, + 91, + 39, + 254, + 48, + 66, + 66, + 7, + 10, + 54, + 15, + 95, + 44, + 1, + 3 + }; + + mActor_name_t item_name = (mActor_name_t)item; + int item_type = ITEM_NAME_GET_TYPE(item_name); + int res = FALSE; + + if (item_type == NAME_TYPE_ITEM1) { + int index = ITEM_NAME_GET_INDEX(item_name); + int category = ITEM_NAME_GET_CAT(item_name); + + if ( + index < 0 || + index > item1_kinds[category] || + item_name == ITM_SICKLE /* ??? why is this explicitly invalid... lol */ + ) { + res = TRUE; + } + } + else if (item_name != EMPTY_NO && item_type != NAME_TYPE_FTR0 && item_type != NAME_TYPE_FTR1) { + mFRm_ERRORLINE(110); + res = TRUE; + } + + return res; +} + +static int sCCk_Check_ItemName_Possession(mActor_name_t item) { + int res = FALSE; + + if ( + sCCk_Check_ItemName(item) || + (item >= ITM_MY_ORG_UMBRELLA0 && item <= ITM_MY_ORG_UMBRELLA7) || + (item >= ITM_RED_PAINT && item <= ITM_BROWN_PAINT) || + item == ITM_PRESENT || + item == ITM_TOWN_MAP || + item == ITM_GOLDEN_NET_PRESENT || + item == ITM_GOLDEN_AXE_PRESENT || + item == ITM_GOLDEN_SHOVEL_PRESENT || + item == ITM_GOLDEN_ROD_PRESENT + ) { + mFRm_ERRORLINE(141); + res = TRUE; + } + + return res; +} + +static int sCck_CheckSaveData_Item_YSD(Private_c* priv) { + int i; + + for (i = 0; i < mPr_POCKETS_SLOT_COUNT; i++) { + sCCk_Check_ItemName_Possession(priv->inventory.pockets[i]); + } + + return FALSE; +} + +static int sCck_CheckSaveData_Mail_YSD(Private_c* priv) { + int res = FALSE; + int i; + + for (i = 0; i < mPr_INVENTORY_MAIL_COUNT; i++) { + res |= sChk_Mail_c_sub(priv->mail + i, 0); + } + + return FALSE; +} + +static int sChk_CheckSaveData_YSD() { + int res = FALSE; + int i; + + for (i = 0; i < PLAYER_NUM; i++) { + Private_c* priv = Save_Get(private) + i; + + res |= sCck_CheckSaveData_Item_YSD(priv); + res |= sCck_CheckSaveData_Mail_YSD(priv); + res |= sCck_CheckSaveData_diary_body_YSD(priv); + } + + return res; +} diff --git a/rel/save_check_gen.c_inc b/rel/save_check_gen.c_inc index e69de29b..aa2b00b2 100644 --- a/rel/save_check_gen.c_inc +++ b/rel/save_check_gen.c_inc @@ -0,0 +1,3 @@ +static int sChk_check_save_gen() { + return FALSE; +} diff --git a/rel/save_check_komatu.c_inc b/rel/save_check_komatu.c_inc index e69de29b..049f502f 100644 --- a/rel/save_check_komatu.c_inc +++ b/rel/save_check_komatu.c_inc @@ -0,0 +1,75 @@ +static int sChk_CheckSaveData_komatu() { + int i; + int j; + + for (i = 0; i < PLAYER_NUM; i++) { + Private_c* priv = Save_Get(private) + i; + + { + const u8 gender = priv->gender; + if (gender > mPr_SEX_FEMALE) { + return TRUE; + } + } + + { + s8 face = priv->face; + if (face < 0 || face >= mPr_FACE_TYPE_NUM) { + return TRUE; + } + } + + { + mPr_cloth_c* cloth = &priv->cloth; + u16 idx = cloth->idx; + mActor_name_t item; + + if (idx >= (256 + 8) || idx == 255) { + return TRUE; + } + + item = cloth->item; + if (item != EMPTY_NO) { + int valid_cloth = item == RSV_CLOTH || (item >= ITM_CLOTH000 && item < ITM_CLOTH_END); + + if (valid_cloth == FALSE) { + return TRUE; + } + } + } + + { + mPr_destiny_c* destiny = &priv->destiny; + + if (destiny->type >= mPr_DESTINY_NUM) { + return TRUE; + } + } + + { + mPr_sunburn_c* sunburn = &priv->sunburn; + s8 t = sunburn->rank; + s8 t2; + + if (t < 0 || t >= mPr_SUNBURN_RANK_NUM) { + return TRUE; + } + + t2 = sunburn->rankdown_days; + if (t2 < 0 || t2 > 2) { + return TRUE; + } + } + + { + u8 golden_items_collected = priv->golden_items_collected; + for (j = 4; j < 8; j++) { + if (golden_items_collected & ((u8)(1 << j))) { + return TRUE; + } + } + } + } + + return FALSE; +} diff --git a/rel/save_check_take.c_inc b/rel/save_check_take.c_inc index e69de29b..7539ded3 100644 --- a/rel/save_check_take.c_inc +++ b/rel/save_check_take.c_inc @@ -0,0 +1,89 @@ +#include "m_notice.h" +#include "m_font.h" + +static int sChk_board_save_check() { + mNtc_board_post_c* board = Save_Get(noticeboard); + int max = mNtc_notice_write_num(); + int i; + int j; + + for (i = 0; i < max; i++) { + u8* msg = board->message; + if (lbRTC_time_c_save_data_check(&board->post_time)) { + mFRm_ERRORLINE(65); + return TRUE; + } + + for (j = 0; j < MAIL_BODY_LEN; j++) { + if (mFont_char_save_data_check(msg[0])) { + mFRm_ERRORLINE(73); + return TRUE; + } + + msg++; + } + + board++; + } + + return FALSE; +} + +static int sChk_weather_save_check() { + u32 weather = mEnv_SAVE_GET_WEATHER_TYPE(Save_Get(weather)); + u32 intensity = mEnv_SAVE_GET_WEATHER_INTENSITY(Save_Get(weather)); + + if (intensity >= mEnv_WEATHER_INTENSITY_NUM || weather >= mEnv_WEATHER_LEAVES) { + mFRm_ERRORLINE(141); + return TRUE; + } + else { + return FALSE; + } +} + +static int sChk_snowman_save_check() { + u8 year; + u8 month; + u8 day; + u8 hour; + mSN_snowman_save_c* data = Save_GetPointer(snowmen); + + year = Save_Get(snowman_year); + month = Save_Get(snowman_month); + day = Save_Get(snowman_day); + hour = Save_Get(snowman_hour); + + if ( + year > GAME_YEAR_MAX - 1 || + month > lbRTC_DECEMBER || + day > 31 || + hour >= 24 + ) { + mFRm_ERRORLINE(168); + return TRUE; + } + else { + int i; + + for (i = 0; i < mSN_SAVE_COUNT; i++) { + mSN_snowman_data_c* data2 = data->snowmen_data + i; + + if (data2->score >= 4 || data2->exists > 1) { + mFRm_ERRORLINE(179); + return TRUE; + } + } + } + + return FALSE; +} + +static int sChk_check_save_take() { + if (sChk_snowman_save_check() || sChk_board_save_check() || sChk_weather_save_check()) { + return TRUE; + } + else { + return FALSE; + } +}