Implement clock advancing when the battery is fine

This commit is contained in:
Lorenzooone 2023-12-29 03:35:41 +01:00
parent 1970dad8a8
commit 2a5efee9ec
7 changed files with 120 additions and 58 deletions

View File

@ -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*);

View File

@ -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*);

View File

@ -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() {

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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("<Day>\n\n");
else
PRINT_FUNCTION("<Night>\n\n");
PRINT_FUNCTION(" Shoal Cave Tide: ");
set_text_x(19);
if(is_high_tide(clock_events, time_change))
PRINT_FUNCTION("<High>\n\n");
PRINT_FUNCTION("<High>");
else
PRINT_FUNCTION("<Low>\n\n");
PRINT_FUNCTION("<Low>");
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) {