From 2a5efee9ec024f2d7512873f8ce7aa997dff7bb3 Mon Sep 17 00:00:00 2001 From: Lorenzooone Date: Fri, 29 Dec 2023 03:35:41 +0100 Subject: [PATCH] Implement clock advancing when the battery is fine --- include/gen3_clock_events.h | 2 + include/menu_text_handler.h | 1 + source/config_settings.c | 2 +- source/gen3_clock_events.c | 112 ++++++++++++++++++++++-------------- source/input_handler.c | 7 ++- source/main.c | 8 ++- source/menu_text_handler.c | 46 +++++++++++---- 7 files changed, 120 insertions(+), 58 deletions(-) diff --git a/include/gen3_clock_events.h b/include/gen3_clock_events.h index ee02771..f86575c 100644 --- a/include/gen3_clock_events.h +++ b/include/gen3_clock_events.h @@ -11,6 +11,8 @@ void enable_rtc_reset(struct clock_events_t*); void disable_rtc_reset(struct clock_events_t*); u8 is_rtc_reset_enabled(struct clock_events_t*); u8 is_daily_update_safe(struct game_data_t*, struct clock_events_t*, struct saved_time_t*); +u8 has_init_succeded(void); +u8 update_base_time(void); void init_rtc_time(void); void run_daily_update(struct game_data_t*, struct clock_events_t*, struct saved_time_t*, u8); u8 is_daytime(struct clock_events_t*, struct saved_time_t*); diff --git a/include/menu_text_handler.h b/include/menu_text_handler.h index 329fc6d..f40cca8 100644 --- a/include/menu_text_handler.h +++ b/include/menu_text_handler.h @@ -41,6 +41,7 @@ void print_colour_settings_menu(u8); void print_evolution_menu(struct gen3_mon_data_unenc*, u16, u8, u8); void print_evolution_window(struct gen3_mon_data_unenc*); void print_cheats_menu(u8); +void print_clock_variable_menu(struct clock_events_t*, struct saved_time_t*, u8); void print_clock_menu(struct clock_events_t*, struct saved_time_t*, u8); void print_warning_when_clock_changed(void); void print_load_warnings(struct game_data_t*, struct game_data_priv_t*); diff --git a/source/config_settings.c b/source/config_settings.c index 8b9ca08..23c0f8c 100644 --- a/source/config_settings.c +++ b/source/config_settings.c @@ -41,7 +41,7 @@ static u16 applied_ball; static u8 egg_met_location; static u8 first_set_egg_met_location; -const struct version_t version = { .main_version = 1, .sub_version = 1, .revision_version = 11, .revision_letter = CONSOLE_LETTER}; +const struct version_t version = { .main_version = 1, .sub_version = 1, .revision_version = 12, .revision_letter = CONSOLE_LETTER}; const u8* egg_valid_met_locations[NUMBER_OF_GAMES+FIRST_VERSION_ID] = {valid_egg_locations_rs_bin, valid_egg_locations_rs_bin, valid_egg_locations_rs_bin, valid_egg_locations_e_bin, valid_egg_locations_frlg_bin, valid_egg_locations_frlg_bin}; void set_default_settings() { diff --git a/source/gen3_clock_events.c b/source/gen3_clock_events.c index f6ce83a..086fb3b 100644 --- a/source/gen3_clock_events.c +++ b/source/gen3_clock_events.c @@ -144,6 +144,7 @@ const u16 berry_trees_pos[NUM_MAIN_GAME_ID] = {0x688, 0, 0x71C}; const u16 daily_show_thresholds[TOTAL_DAILY_SHOW_VARS] = {100, 50, 100, 20, 20, 20, 30}; static u32 time_events_rng_seed; #endif +static u8 init_successful; u8 has_rtc_events(struct game_identity* game_id) { if(game_id->game_main_version == RS_MAIN_GAME_CODE) @@ -196,51 +197,76 @@ void change_tide(struct clock_events_t* clock_events, struct saved_time_t* extra increase_clock(extra_time, 0xFFFF, 0, 0, 0, 0); } +u8 has_init_succeded() { + return init_successful; +} + +u8 update_base_time() { + #if ACTIVE_RTC_FUNCTIONS + __agbabi_datetime_t datetime = __agbabi_rtc_datetime(); + u16 year = bcd_decode(datetime[0], 1); + u8 month = bcd_decode(datetime[0] >> 8, 1); + u8 day = bcd_decode(datetime[0] >> 16, 1); + u8 hour = bcd_decode(datetime[1], 1); + u8 minute = bcd_decode(datetime[1] >> 8, 1); + u8 second = bcd_decode(datetime[1] >> 16, 1); + u8 error_out = 0; + if(year == ((u16)ERROR_OUT_BCD)) + error_out = 1; + if((month == ((u8)ERROR_OUT_BCD)) || (month == 0) || (month > NUM_MONTHS)) + error_out = 1; + // There is no checking for overflows here, normally... :/ + u8 checking_month = 0; + if((month > 0) && (month <= NUM_MONTHS)) + checking_month = month - 1; + u8 max_day = num_days_per_month[checking_month]; + if((month == LEAP_YEAR_EXTRA_DAY_MONTH) && is_leap_year(year)) + max_day++; + // What if the day is 0? And if it's the max_day?! :/ + if((day == ((u8)ERROR_OUT_BCD)) || (day > max_day)) + error_out = 1; + // What if the hour is 0? And if it's MAX_HOURS?! :/ + if((hour == ((u8)ERROR_OUT_BCD)) || (hour > MAX_HOURS)) + error_out = 1; + // What if the minute is 0? And if it's MAX_MINUTES?! :/ + if((minute == ((u8)ERROR_OUT_BCD)) || (minute > MAX_MINUTES)) + error_out = 1; + // What if the second is 0? And if it's MAX_SECONDS?! :/ + if((second == ((u8)ERROR_OUT_BCD)) || (second > MAX_SECONDS)) + error_out = 1; + if(!error_out) { + u16 final_days = get_num_days(year, month, day); + u8 final_hours = hour; + u8 final_minutes = minute; + u8 final_seconds = second; + u8 updated = 0; + if(base_rtc_time.d != final_days) + updated = 1; + if(base_rtc_time.h != final_hours) + updated = 1; + if(base_rtc_time.m != final_minutes) + updated = 1; + if(base_rtc_time.s != final_seconds) + updated = 1; + base_rtc_time.d = final_days; + base_rtc_time.h = final_hours; + base_rtc_time.m = final_minutes; + base_rtc_time.s = final_seconds; + return 1 + updated; + } + #endif + return 0; +} + void init_rtc_time() { base_rtc_time.d = 1; base_rtc_time.h = 0; base_rtc_time.m = 0; base_rtc_time.s = 0; + init_successful = 0; #if ACTIVE_RTC_FUNCTIONS - if(!__agbabi_rtc_init()) { - __agbabi_datetime_t datetime = __agbabi_rtc_datetime(); - u16 year = bcd_decode(datetime[0], 1); - u8 month = bcd_decode(datetime[0] >> 8, 1); - u8 day = bcd_decode(datetime[0] >> 16, 1); - u8 hour = bcd_decode(datetime[1], 1); - u8 minute = bcd_decode(datetime[1] >> 8, 1); - u8 second = bcd_decode(datetime[1] >> 16, 1); - u8 error_out = 0; - if(year == ((u16)ERROR_OUT_BCD)) - error_out = 1; - if((month == ((u8)ERROR_OUT_BCD)) || (month == 0) || (month > NUM_MONTHS)) - error_out = 1; - // There is no checking for overflows here, normally... :/ - u8 checking_month = 0; - if((month > 0) && (month <= NUM_MONTHS)) - checking_month = month - 1; - u8 max_day = num_days_per_month[checking_month]; - if((month == LEAP_YEAR_EXTRA_DAY_MONTH) && is_leap_year(year)) - max_day++; - // What if the day is 0? And if it's the max_day?! :/ - if((day == ((u8)ERROR_OUT_BCD)) || (day > max_day)) - error_out = 1; - // What if the hour is 0? And if it's MAX_HOURS?! :/ - if((hour == ((u8)ERROR_OUT_BCD)) || (hour > MAX_HOURS)) - error_out = 1; - // What if the minute is 0? And if it's MAX_MINUTES?! :/ - if((minute == ((u8)ERROR_OUT_BCD)) || (minute > MAX_MINUTES)) - error_out = 1; - // What if the second is 0? And if it's MAX_SECONDS?! :/ - if((second == ((u8)ERROR_OUT_BCD)) || (second > MAX_SECONDS)) - error_out = 1; - if(!error_out) { - base_rtc_time.d = get_num_days(year, month, day); - base_rtc_time.h = hour; - base_rtc_time.m = minute; - base_rtc_time.s = second; - } - } + if((!__agbabi_rtc_init()) && update_base_time()) + init_successful = 1; #endif } @@ -426,8 +452,8 @@ void run_daily_update(struct game_data_t* game_data, struct clock_events_t* cloc #else void run_daily_update(struct game_data_t* game_data, struct clock_events_t* clock_events, struct saved_time_t* extra_time, u8 UNUSED(is_game_cleared)) { #endif - if(has_rtc_events(&game_data->game_identifier)) - init_rtc_time(); + if(has_rtc_events(&game_data->game_identifier) && has_init_succeded()) + update_base_time(); swap_time(&clock_events->saved_time); u16 d = clock_events->saved_time.d; add_time(&clock_events->saved_time, extra_time, &clock_events->saved_time); @@ -488,8 +514,8 @@ void wipe_clock(struct clock_events_t* clock_events) { } u8 is_daily_update_safe(struct game_data_t* game_data, struct clock_events_t* clock_events, struct saved_time_t* extra_time) { - if(has_rtc_events(&game_data->game_identifier)) - init_rtc_time(); + if(has_rtc_events(&game_data->game_identifier) && has_init_succeded()) + update_base_time(); swap_time(&clock_events->saved_time); struct saved_time_t tmp; u16 days_increase = clock_events->saved_time.d; diff --git a/source/input_handler.c b/source/input_handler.c index 9d0a40b..641705e 100644 --- a/source/input_handler.c +++ b/source/input_handler.c @@ -882,8 +882,11 @@ u8 handle_input_clock_menu(u16 keys, struct clock_events_t* clock_events, struct } break; case BOTTOM_Y_CURSOR_CLOCK_SETTINGS_MENU_VALUE: - if(keys & KEY_A) - return 1; + if(keys & KEY_A) { + if((time_change->d != 0) || (time_change->h != 0) || (time_change->m != 0) || (time_change->s != 0)) + return 1; + return EXIT_CLOCK_SETTINGS; + } else if(keys & KEY_UP) *cursor_y_pos = 9; else if(keys & KEY_DOWN) diff --git a/source/main.c b/source/main.c index 7c50416..8910ef9 100644 --- a/source/main.c +++ b/source/main.c @@ -646,10 +646,13 @@ void clock_settings_menu_init(struct game_data_priv_t* game_data_priv, struct sa set_screen(BASE_SCREEN); disable_all_screens_but_current(); disable_all_cursors(); - if(reset_time) + if(reset_time) { wipe_time(time_change); + init_rtc_time(); + } print_clock_menu(&game_data_priv->clock_events, time_change, 1); enable_screen(BASE_SCREEN); + enable_screen(BASE_SCREEN + 1); *cursor_y_pos = 0; update_cursor_base_x(BASE_X_CURSOR_CLOCK_SETTINGS_MENU); cursor_update_clock_settings_menu(*cursor_y_pos); @@ -999,6 +1002,9 @@ int main(void) } } break; + case CLOCK_SETTINGS_MENU: + print_clock_variable_menu(&game_data_priv.clock_events, &time_change, 0); + break; default: break; } diff --git a/source/menu_text_handler.c b/source/menu_text_handler.c index 9bc96cb..18d5233 100644 --- a/source/menu_text_handler.c +++ b/source/menu_text_handler.c @@ -517,29 +517,52 @@ void print_base_settings_menu(struct game_identity* game_identifier, u8 is_loade PRINT_FUNCTION("V.\x03.\x03.\x03\x02", version->main_version, version->sub_version, version->revision_version, version->revision_letter); } -void print_clock_menu(struct clock_events_t* clock_events, struct saved_time_t* time_change, u8 update) { - if(!update) +void print_clock_variable_menu(struct clock_events_t* clock_events, struct saved_time_t* time_change, u8 force_print) { + u8 update_value = 0; + if(has_init_succeded()) + update_value = update_base_time(); + + if((update_value != 2) && (!force_print)) return; - init_rtc_time(); struct saved_time_t base_time; struct saved_time_t new_time; get_clean_time(&clock_events->saved_time, &base_time); get_increased_time(&clock_events->saved_time, time_change, &new_time); - default_reset_screen(); + u8 old_screen = get_screen_num(); + set_screen(old_screen + 1); + reset_screen(BLANK_FILL); + + set_text_y(1); + set_text_x(8); - PRINT_FUNCTION("\n Time: "); if(is_daytime(clock_events, time_change)) PRINT_FUNCTION("\n\n"); else PRINT_FUNCTION("\n\n"); - PRINT_FUNCTION(" Shoal Cave Tide: "); + set_text_x(19); if(is_high_tide(clock_events, time_change)) - PRINT_FUNCTION("\n\n"); + PRINT_FUNCTION(""); else - PRINT_FUNCTION("\n\n"); + PRINT_FUNCTION(""); + set_text_y(Y_LIMIT-6); + set_text_x(11); + PRINT_FUNCTION("\x0B-\x0B:\x0B:\x0B\n", base_time.d, 5, base_time.h, 2, base_time.m, 2, base_time.s, 2); + set_text_x(11); + PRINT_FUNCTION("\x0B-\x0B:\x0B:\x0B\n", new_time.d, 5, new_time.h, 2, new_time.m, 2, new_time.s, 2); + set_screen(old_screen); +} + +void print_clock_menu(struct clock_events_t* clock_events, struct saved_time_t* time_change, u8 update) { + if(!update) + return; + + default_reset_screen(); + + PRINT_FUNCTION("\n Time: \n\n"); + PRINT_FUNCTION(" Shoal Cave Tide: \n\n"); u8 curr_y = get_text_y(); PRINT_FUNCTION(" Clock Reset Menu: "); if(is_rtc_reset_enabled(clock_events)) @@ -555,14 +578,15 @@ void print_clock_menu(struct clock_events_t* clock_events, struct saved_time_t* set_text_y(Y_LIMIT-8); PRINT_FUNCTION(" Save and Exit\n\n"); - PRINT_FUNCTION("Base Time: \x0B-\x0B:\x0B:\x0B\n", base_time.d, 5, base_time.h, 2, base_time.m, 2, base_time.s, 2); - PRINT_FUNCTION("New Time: \x0B-\x0B:\x0B:\x0B\n", new_time.d, 5, new_time.h, 2, new_time.m, 2, new_time.s, 2); - set_text_y(Y_LIMIT-4); + PRINT_FUNCTION("Base Time:\n"); + PRINT_FUNCTION("New Time:\n"); PRINT_FUNCTION("Issues may arise when changing"); set_text_y(Y_LIMIT-3); PRINT_FUNCTION("the time of a Working Battery."); set_text_y(Y_LIMIT-1); PRINT_FUNCTION("B: Exit Without Saving"); + + print_clock_variable_menu(clock_events, time_change, 1); } void print_cheats_menu(u8 update) {