diff --git a/include/gen3_clock_events.h b/include/gen3_clock_events.h index 775ca15..7cfcaa9 100644 --- a/include/gen3_clock_events.h +++ b/include/gen3_clock_events.h @@ -11,13 +11,13 @@ 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*, u16); -void run_daily_update(struct game_data_t*, u16); -u8 is_daytime(struct game_data_t*); -void change_time_of_day(struct game_data_t* game_data); -u8 is_high_tide(struct game_data_t* game_data); -void change_tide(struct game_data_t* game_data); -void load_time_data(struct game_data_t*, u16, int, int, u8); -void store_time_data(struct game_data_t*, u16, u8*, u8); +void run_daily_update(struct game_data_t*, struct clock_events_t*, u16, u8); +u8 is_daytime(struct clock_events_t*); +void change_time_of_day(struct clock_events_t* game_data); +u8 is_high_tide(struct clock_events_t* game_data); +void change_tide(struct clock_events_t* game_data); +void load_time_data(struct clock_events_t*, u16, int, int, u8, u8, u32); +void store_time_data(struct clock_events_t*, u16, u8*, u8, u8, u32); u8 can_clock_run(struct clock_events_t*); void wipe_clock(struct clock_events_t*); diff --git a/include/gen3_save.h b/include/gen3_save.h index e49e8d6..8c13c9f 100644 --- a/include/gen3_save.h +++ b/include/gen3_save.h @@ -14,15 +14,11 @@ #define SECTION_VARS_ID 2 #define SECTION_GAME_STATS_ID 2 -struct game_data_t { +struct game_data_priv_t { u32 seen_unown_pid; u32 seen_spinda_pid; u8 pokedex_owned[DEX_BYTES]; u8 pokedex_seen[DEX_BYTES]; - struct game_identity game_identifier; - u8 giftRibbons[GIFT_RIBBONS]; - u8 trainer_name[OT_NAME_GEN3_SIZE+1]; - u8 trainer_gender; u16 nat_dex_var; u8 nat_dex_flag : 1; u8 full_link_flag : 1; @@ -34,13 +30,20 @@ struct game_data_t { u32 stat_enc_key; u32 num_saves_stat; u32 num_trades_stat; + struct gen2_party party_2; + struct gen1_party party_1; + struct clock_events_t clock_events; +}; + +struct game_data_t { + struct game_identity game_identifier; + u8 giftRibbons[GIFT_RIBBONS]; + u8 trainer_name[OT_NAME_GEN3_SIZE+1]; + u8 trainer_gender; u32 trainer_id; struct mail_gen3 mails_3[PARTY_SIZE]; struct gen3_party party_3; struct gen3_mon_data_unenc party_3_undec[PARTY_SIZE]; - struct gen2_party party_2; - struct gen1_party party_1; - struct clock_events_t clock_events; }; enum TRADE_POSSIBILITY {FULL_TRADE_POSSIBLE, PARTIAL_TRADE_POSSIBLE, TRADE_IMPOSSIBLE}; @@ -49,16 +52,16 @@ void init_game_data(struct game_data_t*); void init_save_data(void); u8 has_cartridge_been_removed(void); u8 get_is_cartridge_loaded(void); -enum TRADE_POSSIBILITY can_trade(struct game_data_t*); -u8 is_in_pokemon_center(struct game_data_t*); -u8 read_gen_3_data(struct game_data_t*); -void process_party_data(struct game_data_t* game_data); +enum TRADE_POSSIBILITY can_trade(struct game_data_priv_t*, u8); +u8 is_in_pokemon_center(struct game_data_priv_t*, u8); +u8 read_gen_3_data(struct game_data_t*, struct game_data_priv_t*); +void process_party_data(struct game_data_t* game_data, struct gen2_party*, struct gen1_party*); struct game_data_t* get_own_game_data(void); void set_default_gift_ribbons(struct game_data_t*); -u8 trade_mons(struct game_data_t*, u8, u8, u8); +u8 trade_mons(struct game_data_t*, struct game_data_priv_t*, u8, u8, u8); u8 is_invalid_offer(struct game_data_t*, u8, u8, u8, u16); -u8 pre_write_gen_3_data(struct game_data_t*, u8); -u8 pre_write_updated_moves_gen_3_data(struct game_data_t*); +u8 pre_write_gen_3_data(struct game_data_t*, struct game_data_priv_t*, u8); +u8 pre_write_updated_moves_gen_3_data(struct game_data_t*, struct game_data_priv_t*); u8 complete_write_gen_3_data(struct game_data_t*); u8 get_sys_flag_save(u8, int, u8, u16); void set_sys_flag_save(u8*, u8, u16, u8); diff --git a/include/input_handler.h b/include/input_handler.h index cfce901..942066f 100644 --- a/include/input_handler.h +++ b/include/input_handler.h @@ -37,7 +37,7 @@ u8 handle_input_main_menu(u8*, u16, u8*, u8*, u8*, u8*); u8 handle_input_trade_options(u16, u8*); u8 handle_input_nature_menu(u16); u8 handle_input_iv_fix_menu(u16); -u8 handle_input_base_settings_menu(u16, u8*, struct game_data_t*, u8); +u8 handle_input_base_settings_menu(u16, u8*, struct game_data_priv_t*, u8); u8 handle_input_offer_options(u16, u8*, u8*); u8 handle_input_swap_cartridge_menu(u16); u8 handle_input_trade_setup(u16, u8); diff --git a/include/menu_text_handler.h b/include/menu_text_handler.h index bfa64f9..dac9441 100644 --- a/include/menu_text_handler.h +++ b/include/menu_text_handler.h @@ -31,7 +31,7 @@ void print_evolution_animation(struct gen3_mon_data_unenc*); void print_invalid(u8); void print_rejected(u8); void print_offer_screen(struct game_data_t*, u8, u8); -void print_base_settings_menu(struct game_data_t*, u8); +void print_base_settings_menu(struct game_data_priv_t*, u8); void print_offer_options_screen(struct game_data_t*, u8, u8); void print_trade_options(u8, u8); diff --git a/include/options_handler.h b/include/options_handler.h index 3537629..9f8dc1d 100644 --- a/include/options_handler.h +++ b/include/options_handler.h @@ -14,11 +14,11 @@ u8 get_number_of_higher_ordered_options(u8*, u8, u8); u8 get_number_of_lower_ordered_options(u8*, u8, u8); -u8 is_valid_for_gen(struct game_data_t*, u8); +u8 is_valid_for_gen(struct game_data_t*, struct game_data_priv_t*, u8); u8* get_options_main(void); u8 get_valid_options_main(void); -void prepare_main_options(struct game_data_t*); +void prepare_main_options(struct game_data_t*, struct game_data_priv_t*); u8* get_options_trade(int); u8 get_options_num_trade(int); diff --git a/include/sio_buffers.h b/include/sio_buffers.h index e1ce7f0..84aced8 100644 --- a/include/sio_buffers.h +++ b/include/sio_buffers.h @@ -146,7 +146,7 @@ struct gen3_trade_data { u32 final_checksum; } PACKED ALIGNED(4); -void load_comm_buffer(struct game_data_t*, int, u8); +void load_comm_buffer(struct game_data_t*, struct gen2_party*, struct gen1_party*, int, u8); void read_comm_buffer(struct game_data_t*, int, u8); u8 are_checksum_same_gen3(struct gen3_trade_data*); diff --git a/source/gen3_clock_events.c b/source/gen3_clock_events.c index 7bfc586..fdc1434 100644 --- a/source/gen3_clock_events.c +++ b/source/gen3_clock_events.c @@ -80,7 +80,7 @@ void schedule_number_one_show(struct tv_show_t*, u16*, u16, u8*, u8); void update_news(struct news_t*, u8, u16); void update_outbreak_tv(struct tv_show_t*, struct outbreak_t*, u16); void update_outbreak(struct outbreak_t*, u16); -void update_tv_shows(struct game_data_t*, u16); +void update_tv_shows(struct game_data_t*, struct clock_events_t*, u16, u8); void update_dewford_trends(struct dewford_trend_t*, u16); void update_weather(struct clock_events_t*, u16); void update_pokerus_daily(struct game_data_t*, u16); @@ -124,26 +124,26 @@ u8 has_rtc_events(struct game_identity* game_id) { return 0; } -u8 is_daytime(struct game_data_t* game_data) { - swap_time(&game_data->clock_events.saved_time); - u8 retval = game_data->clock_events.saved_time.h >= DAY_START; - swap_time(&game_data->clock_events.saved_time); +u8 is_daytime(struct clock_events_t* clock_events) { + swap_time(&clock_events->saved_time); + u8 retval = clock_events->saved_time.h >= DAY_START; + swap_time(&clock_events->saved_time); return retval; } -void change_time_of_day(struct game_data_t* game_data) { - u16 curr_d = game_data->clock_events.saved_time.d; - increase_clock(&game_data->clock_events.saved_time, 0, MAX_HOURS>>1, 0, 0, 1); - if(game_data->clock_events.saved_time.d != curr_d) - increase_clock(&game_data->clock_events.saved_time, 0xFFFF, 0, 0, 0, 1); +void change_time_of_day(struct clock_events_t* clock_events) { + u16 curr_d = clock_events->saved_time.d; + increase_clock(&clock_events->saved_time, 0, MAX_HOURS>>1, 0, 0, 1); + if(clock_events->saved_time.d != curr_d) + increase_clock(&clock_events->saved_time, 0xFFFF, 0, 0, 0, 1); } -u8 is_high_tide(struct game_data_t* game_data) { - swap_time(&game_data->clock_events.saved_time); - u8 tidal_hours = game_data->clock_events.saved_time.h - TIDE_OFFSET; - if(game_data->clock_events.saved_time.h < TIDE_OFFSET) - tidal_hours = game_data->clock_events.saved_time.h + MAX_HOURS - TIDE_OFFSET; - swap_time(&game_data->clock_events.saved_time); +u8 is_high_tide(struct clock_events_t* clock_events) { + swap_time(&clock_events->saved_time); + u8 tidal_hours = clock_events->saved_time.h - TIDE_OFFSET; + if(clock_events->saved_time.h < TIDE_OFFSET) + tidal_hours = clock_events->saved_time.h + MAX_HOURS - TIDE_OFFSET; + swap_time(&clock_events->saved_time); if(tidal_hours >= (MAX_HOURS>>1)) tidal_hours -= MAX_HOURS>>1; if(tidal_hours >= (MAX_HOURS>>2)) @@ -151,14 +151,14 @@ u8 is_high_tide(struct game_data_t* game_data) { return 0; } -void change_tide(struct game_data_t* game_data) { - u16 curr_d = game_data->clock_events.saved_time.d; - u8 curr_daytime = is_daytime(game_data); - increase_clock(&game_data->clock_events.saved_time, 0, MAX_HOURS>>2, 0, 0, 1); - if(is_daytime(game_data) != curr_daytime) - change_time_of_day(game_data); - if(game_data->clock_events.saved_time.d != curr_d) - increase_clock(&game_data->clock_events.saved_time, 0xFFFF, 0, 0, 0, 1); +void change_tide(struct clock_events_t* clock_events) { + u16 curr_d = clock_events->saved_time.d; + u8 curr_daytime = is_daytime(clock_events); + increase_clock(&clock_events->saved_time, 0, MAX_HOURS>>2, 0, 0, 1); + if(is_daytime(clock_events) != curr_daytime) + change_time_of_day(clock_events); + if(clock_events->saved_time.d != curr_d) + increase_clock(&clock_events->saved_time, 0xFFFF, 0, 0, 0, 1); } void subtract_time(struct saved_time_t* base, struct saved_time_t* sub, struct saved_time_t* target) { @@ -251,28 +251,32 @@ void normalize_time(struct saved_time_t* saved_time) { saved_time->s = SWI_DivMod(saved_time->s, MAX_SECONDS); } -void run_daily_update(struct game_data_t* game_data, u16 days_increase) { - increase_clock(&game_data->clock_events.saved_time, days_increase, 0, 0, 0, 1); +#if ACTUALLY_RUN_EVENTS +void run_daily_update(struct game_data_t* game_data, struct clock_events_t* clock_events, u16 days_increase, u8 is_game_cleared) { +#else +void run_daily_update(struct game_data_t* UNUSED(game_data), struct clock_events_t* clock_events, u16 days_increase, u8 UNUSED(is_game_cleared)) { +#endif + increase_clock(&clock_events->saved_time, days_increase, 0, 0, 0, 1); #if ACTUALLY_RUN_EVENTS // To be 100% faithful, events should be stopped inside of a Pokémon Center... // But doing that would defeat the purpose of this if(has_rtc_events(&game_data->game_identifier)) { if(days_increase) { - reset_daily_flags(&game_data->clock_events); - update_dewford_trends(game_data->clock_events.dewford_trends, days_increase); - update_tv_shows(game_data, days_increase); - update_weather(&game_data->clock_events, days_increase); + reset_daily_flags(clock_events); + update_dewford_trends(clock_events->dewford_trends, days_increase); + update_tv_shows(game_data, clock_events, days_increase, is_game_cleared); + update_weather(clock_events, days_increase); update_pokerus_daily(game_data, days_increase); - update_mirage_island(&game_data->clock_events, days_increase); - update_birch_state(&game_data->clock_events, days_increase); + update_mirage_island(clock_events, days_increase); + update_birch_state(clock_events, days_increase); if(game_data->game_identifier.game_main_version == E_MAIN_GAME_CODE) { - update_frontier_maniac(&game_data->clock_events, days_increase); - update_frontier_gambler(&game_data->clock_events, days_increase); + update_frontier_maniac(clock_events, days_increase); + update_frontier_gambler(clock_events, days_increase); } - reset_shoal_cave_items(&game_data->clock_events); - reset_lottery(&game_data->clock_events); - game_data->clock_events.days_var += days_increase; + reset_shoal_cave_items(clock_events); + reset_lottery(clock_events); + clock_events->days_var += days_increase; } } #endif @@ -302,41 +306,45 @@ void wipe_clock(struct clock_events_t* clock_events) { wipe_time(&clock_events->saved_berry_time); } -void load_time_data(struct game_data_t* game_data, u16 section_id, int slot, int index, u8 game_id) { +#if ACTUALLY_RUN_EVENTS +void load_time_data(struct clock_events_t* clock_events, u16 section_id, int slot, int index, u8 game_id, u8 can_run_rtc_events, u32 stat_enc_key) { +#else +void load_time_data(struct clock_events_t* clock_events, u16 section_id, int slot, int index, u8 game_id, u8 can_run_rtc_events, u32 UNUSED(stat_enc_key)) { +#endif if(section_id == SECTION_SAVED_TIME_ID) { - copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + SAVED_TIME_POS, (u8*)&game_data->clock_events.saved_time, sizeof(struct saved_time_t)); - normalize_time(&game_data->clock_events.saved_time); - copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + SAVED_BERRY_TIME_POS, (u8*)&game_data->clock_events.saved_berry_time, sizeof(struct saved_time_t)); - normalize_time(&game_data->clock_events.saved_berry_time); + copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + SAVED_TIME_POS, (u8*)&clock_events->saved_time, sizeof(struct saved_time_t)); + normalize_time(&clock_events->saved_time); + copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + SAVED_BERRY_TIME_POS, (u8*)&clock_events->saved_berry_time, sizeof(struct saved_time_t)); + normalize_time(&clock_events->saved_berry_time); } if(section_id == SECTION_SYS_FLAGS_ID) { - game_data->clock_events.enable_rtc_reset_flag = get_sys_flag_save(slot, index, game_id, enable_rtc_flag_num[game_id]); + clock_events->enable_rtc_reset_flag = get_sys_flag_save(slot, index, game_id, enable_rtc_flag_num[game_id]); #if ACTUALLY_RUN_EVENTS - if(has_rtc_events(&game_data->game_identifier)) { - game_data->clock_events.shoal_cave_items_reset_flag = get_sys_flag_save(slot, index, game_id, shoal_items_flag_num[game_id]); + if(can_run_rtc_events) { + clock_events->shoal_cave_items_reset_flag = get_sys_flag_save(slot, index, game_id, shoal_items_flag_num[game_id]); for(size_t j = 0; j < (DAILY_FLAGS_TOTAL>>3); j++) - game_data->clock_events.daily_flags[j] = get_sys_flag_byte_save(slot, index, game_id, daily_flags_start_num[game_id] + (j<<3)); + clock_events->daily_flags[j] = get_sys_flag_byte_save(slot, index, game_id, daily_flags_start_num[game_id] + (j<<3)); } #endif } if(section_id == SECTION_VARS_ID) { - game_data->clock_events.enable_rtc_reset_var = get_var_save(slot, index, game_id, enable_rtc_var_num[game_id]); - if(has_rtc_events(&game_data->game_identifier)) { - game_data->clock_events.days_var = get_var_save(slot, index, game_id, days_var_num[game_id]); + clock_events->enable_rtc_reset_var = get_var_save(slot, index, game_id, enable_rtc_var_num[game_id]); + if(can_run_rtc_events) { + clock_events->days_var = get_var_save(slot, index, game_id, days_var_num[game_id]); #if ACTUALLY_RUN_EVENTS - game_data->clock_events.lottery_low_var = get_var_save(slot, index, game_id, lottery_low_var_num[game_id]); - game_data->clock_events.lottery_high_var = get_var_save(slot, index, game_id, lottery_low_var_num[game_id]+1); - game_data->clock_events.mirage_high_var = get_var_save(slot, index, game_id, mirage_high_var_num[game_id]); - game_data->clock_events.mirage_low_var = get_var_save(slot, index, game_id, mirage_high_var_num[game_id]+1); - game_data->clock_events.birch_state_var = get_var_save(slot, index, game_id, birch_state_var_num[game_id]); - game_data->clock_events.lottery_consumed_var = get_var_save(slot, index, game_id, lottery_consumed_var_num[game_id]); + clock_events->lottery_low_var = get_var_save(slot, index, game_id, lottery_low_var_num[game_id]); + clock_events->lottery_high_var = get_var_save(slot, index, game_id, lottery_low_var_num[game_id]+1); + clock_events->mirage_high_var = get_var_save(slot, index, game_id, mirage_high_var_num[game_id]); + clock_events->mirage_low_var = get_var_save(slot, index, game_id, mirage_high_var_num[game_id]+1); + clock_events->birch_state_var = get_var_save(slot, index, game_id, birch_state_var_num[game_id]); + clock_events->lottery_consumed_var = get_var_save(slot, index, game_id, lottery_consumed_var_num[game_id]); if(game_id == E_MAIN_GAME_CODE) { - game_data->clock_events.frontier_maniac_var = get_var_save(slot, index, game_id, frontier_maniac_var_num[game_id]); - game_data->clock_events.frontier_gambler_var = get_var_save(slot, index, game_id, frontier_gambler_var_num[game_id]); + clock_events->frontier_maniac_var = get_var_save(slot, index, game_id, frontier_maniac_var_num[game_id]); + clock_events->frontier_gambler_var = get_var_save(slot, index, game_id, frontier_gambler_var_num[game_id]); for(int j = 0; j < TOTAL_DAILY_SHOW_VARS; j++) - game_data->clock_events.daily_show_vars[j] = get_var_save(slot, index, game_id, daily_vars_num[j]); + clock_events->daily_show_vars[j] = get_var_save(slot, index, game_id, daily_vars_num[j]); } #endif } @@ -344,61 +352,61 @@ void load_time_data(struct game_data_t* game_data, u16 section_id, int slot, int #if ACTUALLY_RUN_EVENTS if(section_id == SECTION_GAME_STATS_ID) - game_data->clock_events.steps_stat = get_stat_save(slot, index, game_id, STEPS_STAT_NUM) ^ game_data->stat_enc_key; + clock_events->steps_stat = get_stat_save(slot, index, game_id, STEPS_STAT_NUM) ^ stat_enc_key; if(section_id == SECTION_WEATHER_ID) - game_data->clock_events.weather_stage = read_byte_save((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + WEATHER_POS); + clock_events->weather_stage = read_byte_save((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + WEATHER_POS); - if(has_rtc_events(&game_data->game_identifier)) { + if(can_run_rtc_events) { if(section_id == section_dewford_chunk_1[game_id]) - copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + dewford_chunk_1_pos[game_id], (u8*)game_data->clock_events.dewford_trends, DEWFORD_CHUNK_1_SIZE); + copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + dewford_chunk_1_pos[game_id], (u8*)clock_events->dewford_trends, DEWFORD_CHUNK_1_SIZE); if(section_id == section_dewford_chunk_2[game_id]) - copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + dewford_chunk_2_pos[game_id], ((u8*)game_data->clock_events.dewford_trends) + DEWFORD_CHUNK_1_SIZE, sizeof(game_data->clock_events.dewford_trends)-DEWFORD_CHUNK_1_SIZE); + copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + dewford_chunk_2_pos[game_id], ((u8*)clock_events->dewford_trends) + DEWFORD_CHUNK_1_SIZE, sizeof(clock_events->dewford_trends)-DEWFORD_CHUNK_1_SIZE); if(section_id == SECTION_TV_ID) - copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + tv_shows_pos[game_id], (u8*)game_data->clock_events.tv_shows, sizeof(game_data->clock_events.tv_shows)); + copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + tv_shows_pos[game_id], (u8*)clock_events->tv_shows, sizeof(clock_events->tv_shows)); if(section_id == SECTION_NEWS_ID) - copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + news_pos[game_id], (u8*)game_data->clock_events.news, sizeof(game_data->clock_events.news)); + copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + news_pos[game_id], (u8*)clock_events->news, sizeof(clock_events->news)); if(section_id == SECTION_OUTBREAK_ID) - copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + outbreak_pos[game_id], (u8*)&game_data->clock_events.outbreak, sizeof(game_data->clock_events.outbreak)); + copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (index * SECTION_SIZE) + outbreak_pos[game_id], (u8*)&clock_events->outbreak, sizeof(clock_events->outbreak)); } #endif } -void store_time_data(struct game_data_t* game_data, u16 section_id, u8* buffer_8, u8 game_id) { +void store_time_data(struct clock_events_t* clock_events, u16 section_id, u8* buffer_8, u8 game_id, u8 can_run_rtc_events, u32 UNUSED(stat_enc_key)) { if(section_id == SECTION_SAVED_TIME_ID) { for(size_t j = 0; j < sizeof(struct saved_time_t); j++) - buffer_8[SAVED_TIME_POS+j] = ((u8*)&game_data->clock_events.saved_time)[j]; + buffer_8[SAVED_TIME_POS+j] = ((u8*)&clock_events->saved_time)[j]; for(size_t j = 0; j < sizeof(struct saved_time_t); j++) - buffer_8[SAVED_BERRY_TIME_POS+j] = ((u8*)&game_data->clock_events.saved_berry_time)[j]; + buffer_8[SAVED_BERRY_TIME_POS+j] = ((u8*)&clock_events->saved_berry_time)[j]; } if(section_id == SECTION_SYS_FLAGS_ID) { - set_sys_flag_save(buffer_8, game_id, enable_rtc_flag_num[game_id], game_data->clock_events.enable_rtc_reset_flag); + set_sys_flag_save(buffer_8, game_id, enable_rtc_flag_num[game_id], clock_events->enable_rtc_reset_flag); #if ACTUALLY_RUN_EVENTS - if(has_rtc_events(&game_data->game_identifier)) { - set_sys_flag_save(buffer_8, game_id, shoal_items_flag_num[game_id], game_data->clock_events.shoal_cave_items_reset_flag); + if(can_run_rtc_events) { + set_sys_flag_save(buffer_8, game_id, shoal_items_flag_num[game_id], clock_events->shoal_cave_items_reset_flag); for(size_t j = 0; j < (DAILY_FLAGS_TOTAL>>3); j++) - set_sys_flag_byte_save(buffer_8, game_id, daily_flags_start_num[game_id] + (j<<3), game_data->clock_events.daily_flags[j]); + set_sys_flag_byte_save(buffer_8, game_id, daily_flags_start_num[game_id] + (j<<3), clock_events->daily_flags[j]); } #endif } if(section_id == SECTION_VARS_ID) { - set_var_save(buffer_8, game_id, enable_rtc_var_num[game_id], game_data->clock_events.enable_rtc_reset_var); - if(has_rtc_events(&game_data->game_identifier)) { - set_var_save(buffer_8, game_id, days_var_num[game_id], game_data->clock_events.days_var); + set_var_save(buffer_8, game_id, enable_rtc_var_num[game_id], clock_events->enable_rtc_reset_var); + if(can_run_rtc_events) { + set_var_save(buffer_8, game_id, days_var_num[game_id], clock_events->days_var); #if ACTUALLY_RUN_EVENTS - set_var_save(buffer_8, game_id, lottery_low_var_num[game_id], game_data->clock_events.lottery_low_var); - set_var_save(buffer_8, game_id, lottery_low_var_num[game_id]+1, game_data->clock_events.lottery_high_var); - set_var_save(buffer_8, game_id, mirage_high_var_num[game_id], game_data->clock_events.mirage_high_var); - set_var_save(buffer_8, game_id, mirage_high_var_num[game_id]+1, game_data->clock_events.mirage_low_var); - set_var_save(buffer_8, game_id, birch_state_var_num[game_id], game_data->clock_events.birch_state_var); - set_var_save(buffer_8, game_id, lottery_consumed_var_num[game_id], game_data->clock_events.lottery_consumed_var); + set_var_save(buffer_8, game_id, lottery_low_var_num[game_id], clock_events->lottery_low_var); + set_var_save(buffer_8, game_id, lottery_low_var_num[game_id]+1, clock_events->lottery_high_var); + set_var_save(buffer_8, game_id, mirage_high_var_num[game_id], clock_events->mirage_high_var); + set_var_save(buffer_8, game_id, mirage_high_var_num[game_id]+1, clock_events->mirage_low_var); + set_var_save(buffer_8, game_id, birch_state_var_num[game_id], clock_events->birch_state_var); + set_var_save(buffer_8, game_id, lottery_consumed_var_num[game_id], clock_events->lottery_consumed_var); if(game_id == E_MAIN_GAME_CODE) { - set_var_save(buffer_8, game_id, frontier_maniac_var_num[game_id], game_data->clock_events.frontier_maniac_var); - set_var_save(buffer_8, game_id, frontier_gambler_var_num[game_id], game_data->clock_events.frontier_gambler_var); + set_var_save(buffer_8, game_id, frontier_maniac_var_num[game_id], clock_events->frontier_maniac_var); + set_var_save(buffer_8, game_id, frontier_gambler_var_num[game_id], clock_events->frontier_gambler_var); for(int j = 0; j < TOTAL_DAILY_SHOW_VARS; j++) - set_var_save(buffer_8, game_id, daily_vars_num[j], game_data->clock_events.daily_show_vars[j]); + set_var_save(buffer_8, game_id, daily_vars_num[j], clock_events->daily_show_vars[j]); } #endif } @@ -406,24 +414,24 @@ void store_time_data(struct game_data_t* game_data, u16 section_id, u8* buffer_8 #if ACTUALLY_RUN_EVENTS if(section_id == SECTION_WEATHER_ID) - buffer_8[WEATHER_POS] = game_data->clock_events.weather_stage; + buffer_8[WEATHER_POS] = clock_events->weather_stage; - if(has_rtc_events(&game_data->game_identifier)) { + if(can_run_rtc_events) { if(section_id == section_dewford_chunk_1[game_id]) for(size_t j = 0; j < DEWFORD_CHUNK_1_SIZE; j++) - buffer_8[dewford_chunk_1_pos[game_id]+j] = ((u8*)game_data->clock_events.dewford_trends)[j]; + buffer_8[dewford_chunk_1_pos[game_id]+j] = ((u8*)clock_events->dewford_trends)[j]; if(section_id == section_dewford_chunk_2[game_id]) - for(size_t j = 0; j < (sizeof(game_data->clock_events.dewford_trends)-DEWFORD_CHUNK_1_SIZE); j++) - buffer_8[dewford_chunk_2_pos[game_id]+j] = ((u8*)game_data->clock_events.dewford_trends)[DEWFORD_CHUNK_1_SIZE+j]; + for(size_t j = 0; j < (sizeof(clock_events->dewford_trends)-DEWFORD_CHUNK_1_SIZE); j++) + buffer_8[dewford_chunk_2_pos[game_id]+j] = ((u8*)clock_events->dewford_trends)[DEWFORD_CHUNK_1_SIZE+j]; if(section_id == SECTION_TV_ID) - for(size_t j = 0; j < sizeof(game_data->clock_events.tv_shows); j++) - buffer_8[tv_shows_pos[game_id]+j] = ((u8*)game_data->clock_events.tv_shows)[j]; + for(size_t j = 0; j < sizeof(clock_events->tv_shows); j++) + buffer_8[tv_shows_pos[game_id]+j] = ((u8*)clock_events->tv_shows)[j]; if(section_id == SECTION_NEWS_ID) - for(size_t j = 0; j < sizeof(game_data->clock_events.news); j++) - buffer_8[news_pos[game_id]+j] = ((u8*)game_data->clock_events.news)[j]; + for(size_t j = 0; j < sizeof(clock_events->news); j++) + buffer_8[news_pos[game_id]+j] = ((u8*)clock_events->news)[j]; if(section_id == SECTION_OUTBREAK_ID) - for(size_t j = 0; j < sizeof(game_data->clock_events.outbreak); j++) - buffer_8[outbreak_pos[game_id]+j] = ((u8*)&game_data->clock_events.outbreak)[j]; + for(size_t j = 0; j < sizeof(clock_events->outbreak); j++) + buffer_8[outbreak_pos[game_id]+j] = ((u8*)&clock_events->outbreak)[j]; } #endif } @@ -618,13 +626,13 @@ void update_outbreak(struct outbreak_t* outbreak, u16 days_increase) { outbreak->days -= days_increase; } -void update_tv_shows(struct game_data_t* game_data, u16 days_increase) { - update_outbreak_tv(game_data->clock_events.tv_shows, &game_data->clock_events.outbreak, days_increase); - update_outbreak(&game_data->clock_events.outbreak, days_increase); - update_news(game_data->clock_events.news, game_data->game_cleared_flag, days_increase); - schedule_world_of_masters_show(game_data->clock_events.tv_shows, game_data->clock_events.steps_stat, game_data->trainer_id & 0xFFFF, game_data->trainer_name, game_data->game_identifier.game_is_jp); +void update_tv_shows(struct game_data_t* game_data, struct clock_events_t* clock_events, u16 days_increase, u8 is_game_cleared) { + update_outbreak_tv(clock_events->tv_shows, &clock_events->outbreak, days_increase); + update_outbreak(&clock_events->outbreak, days_increase); + update_news(clock_events->news, is_game_cleared, days_increase); + schedule_world_of_masters_show(clock_events->tv_shows, clock_events->steps_stat, game_data->trainer_id & 0xFFFF, game_data->trainer_name, game_data->game_identifier.game_is_jp); if(game_data->game_identifier.game_main_version == E_MAIN_GAME_CODE) - schedule_number_one_show(game_data->clock_events.tv_shows, game_data->clock_events.daily_show_vars, game_data->trainer_id & 0xFFFF, game_data->trainer_name, game_data->game_identifier.game_is_jp); + schedule_number_one_show(clock_events->tv_shows, clock_events->daily_show_vars, game_data->trainer_id & 0xFFFF, game_data->trainer_name, game_data->game_identifier.game_is_jp); } void update_weather(struct clock_events_t* clock_events, u16 days_increase) { diff --git a/source/gen3_save.c b/source/gen3_save.c index 64eea7f..a1c6deb 100644 --- a/source/gen3_save.c +++ b/source/gen3_save.c @@ -53,16 +53,16 @@ enum SAVING_KIND {FULL_SAVE, NON_PARTY_SAVE, PARTY_ONLY_SAVE}; u16 read_section_id(int, int); u32 read_slot_index(int); -void read_game_data_trainer_info(int, struct game_data_t*); -void register_dex_entry(struct game_data_t*, struct gen3_mon_data_unenc*); +void read_game_data_trainer_info(int, struct game_data_t*, struct game_data_priv_t*); +void register_dex_entry(struct game_data_priv_t*, struct gen3_mon_data_unenc*); void handle_mail_trade(struct game_data_t*, u8, u8); -void read_party(int, struct game_data_t*); +void read_party(int, struct game_data_t*, struct game_data_priv_t*); void update_gift_ribbons(struct game_data_t*, const u8*); u8 validate_slot(int, struct game_identity*); u8 get_slot(struct game_identity*); void unload_cartridge(void); void load_cartridge(void); -u8 pre_update_save(struct game_data_t*, u8, enum SAVING_KIND); +u8 pre_update_save(struct game_data_t*, struct game_data_priv_t*, u8, enum SAVING_KIND); u8 complete_save(u8, struct game_data_t*); static u8 get_next_slot(u8); u32 calc_checksum_save_buffer(u32*, u16); @@ -105,45 +105,40 @@ struct game_data_t* get_own_game_data() { void init_game_data(struct game_data_t* game_data) { init_game_identifier(&game_data->game_identifier); - - game_data->party_1.total = 0; - game_data->party_2.total = 0; + game_data->party_3.total = 0; - + for(size_t i = 0; i < (OT_NAME_GEN3_SIZE+1); i++) game_data->trainer_name[i] = GEN3_EOL; - + for(gen3_party_total_t i = 0; i < PARTY_SIZE; i++) { for(size_t j = 0; j < sizeof(struct mail_gen3); j++) ((u8*)(&game_data->mails_3[i]))[j] = 0; for(size_t j = 0; j < sizeof(struct gen3_mon_data_unenc); j++) ((u8*)(&game_data->party_3_undec[i]))[j] = 0; } - + for(size_t i = 0; i < sizeof(struct gen3_party); i++) ((u8*)(&game_data->party_3))[i] = 0; - + for(gen3_party_total_t i = 0; i < PARTY_SIZE; i++) game_data->party_3_undec[i].is_valid_gen3 = 0; } -enum TRADE_POSSIBILITY can_trade(struct game_data_t* game_data) { - u8 game_id = game_data->game_identifier.game_main_version; - if(!game_data->dex_obtained_flag) +enum TRADE_POSSIBILITY can_trade(struct game_data_priv_t* game_data_priv, u8 game_id) { + if(!game_data_priv->dex_obtained_flag) return TRADE_IMPOSSIBLE; - if((game_data->nat_dex_var == nat_dex_var_value[game_id]) && game_data->nat_dex_flag && (game_data->nat_dex_magic == nat_dex_magic_value[game_id]) && game_data->game_cleared_flag && game_data->full_link_flag) + if((game_data_priv->nat_dex_var == nat_dex_var_value[game_id]) && game_data_priv->nat_dex_flag && (game_data_priv->nat_dex_magic == nat_dex_magic_value[game_id]) && game_data_priv->game_cleared_flag && game_data_priv->full_link_flag) return FULL_TRADE_POSSIBLE; return PARTIAL_TRADE_POSSIBLE; } -u8 is_in_pokemon_center(struct game_data_t* game_data) { - u8 game_id = game_data->game_identifier.game_main_version; - +u8 is_in_pokemon_center(struct game_data_priv_t* game_data_priv, u8 game_id) { if(game_id != RS_MAIN_GAME_CODE) - return game_data->save_warp_flags & IN_POKEMON_CENTER_FLAG; + return game_data_priv->save_warp_flags & IN_POKEMON_CENTER_FLAG; for(size_t i = 0; i < VALID_MAPS; i++) - if(rs_valid_maps[i] == game_data->curr_map) + if(rs_valid_maps[i] == game_data_priv->curr_map) return 1; return 0; } @@ -166,7 +161,7 @@ u32 read_slot_index(int slot) { return read_int_save((slot * SAVE_SLOT_SIZE) + SAVE_SLOT_INDEX_POS); } -void read_game_data_trainer_info(int slot, struct game_data_t* game_data) { +void read_game_data_trainer_info(int slot, struct game_data_t* game_data, struct game_data_priv_t* game_data_priv) { if(slot) slot = 1; @@ -177,26 +172,25 @@ void read_game_data_trainer_info(int slot, struct game_data_t* game_data) { game_data->trainer_id = read_int_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + TRAINER_ID_POS); determine_game_with_save(&game_data->game_identifier, slot, i, summable_bytes[SECTION_TRAINER_INFO_ID]); if(has_stat_enc_key[game_data->game_identifier.game_main_version]) - game_data->stat_enc_key = read_int_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + stat_enc_key_pos[game_data->game_identifier.game_main_version]); + game_data_priv->stat_enc_key = read_int_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + stat_enc_key_pos[game_data->game_identifier.game_main_version]); else - game_data->stat_enc_key = 0; - + game_data_priv->stat_enc_key = 0; break; } } -void register_dex_entry(struct game_data_t* game_data, struct gen3_mon_data_unenc* data_src) { +void register_dex_entry(struct game_data_priv_t* game_data_priv, struct gen3_mon_data_unenc* data_src) { u16 dex_index = get_dex_index_raw(data_src); if(dex_index != NO_DEX_INDEX) { u8 base_index = dex_index >> 3; u8 rest_index = dex_index & 7; - u8 prev_seen = game_data->pokedex_seen[base_index] & (1 << rest_index); - game_data->pokedex_seen[base_index] |= (1 << rest_index); - game_data->pokedex_owned[base_index] |= (1 << rest_index); + u8 prev_seen = game_data_priv->pokedex_seen[base_index] & (1 << rest_index); + game_data_priv->pokedex_seen[base_index] |= (1 << rest_index); + game_data_priv->pokedex_owned[base_index] |= (1 << rest_index); if((!prev_seen) && (data_src->growth.species == UNOWN_SPECIES)) - game_data->seen_unown_pid = data_src->src->pid; + game_data_priv->seen_unown_pid = data_src->src->pid; if((!prev_seen) && (data_src->growth.species == SPINDA_SPECIES)) - game_data->seen_spinda_pid = data_src->src->pid; + game_data_priv->seen_spinda_pid = data_src->src->pid; } } @@ -240,7 +234,7 @@ void set_default_gift_ribbons(struct game_data_t* game_data) { update_gift_ribbons(game_data, default_gift_ribbons_bin); } -u8 trade_mons(struct game_data_t* game_data, u8 own_mon, u8 other_mon, u8 curr_gen) { +u8 trade_mons(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 own_mon, u8 other_mon, u8 curr_gen) { handle_mail_trade(game_data, own_mon, other_mon); u8* dst = (u8*)&game_data[0].party_3.mons[own_mon]; @@ -253,10 +247,10 @@ u8 trade_mons(struct game_data_t* game_data, u8 own_mon, u8 other_mon, u8 curr_g dst[i] = src[i]; game_data[0].party_3_undec[own_mon].src = &game_data[0].party_3.mons[own_mon]; update_gift_ribbons(&game_data[0], game_data[1].giftRibbons); - register_dex_entry(&game_data[0], &game_data[0].party_3_undec[own_mon]); + register_dex_entry(game_data_priv, &game_data[0].party_3_undec[own_mon]); u8 ret_val = trade_evolve(&game_data[0].party_3.mons[own_mon], &game_data[0].party_3_undec[own_mon], curr_gen); if(ret_val) - register_dex_entry(&game_data[0], &game_data[0].party_3_undec[own_mon]); + register_dex_entry(game_data_priv, &game_data[0].party_3_undec[own_mon]); return ret_val; } @@ -320,7 +314,7 @@ void set_stat_save(u8* buffer_8, u8 game_id, u16 stat_num, u32 value) { buffer_8[game_stats_pos[game_id] + (stat_num<<2) + j] = (value >> (8*j)) & 0xFF; } -void process_party_data(struct game_data_t* game_data) { +void process_party_data(struct game_data_t* game_data, struct gen2_party* party_2, struct gen1_party* party_1) { if(game_data->party_3.total > PARTY_SIZE) game_data->party_3.total = PARTY_SIZE; u8 curr_slot = 0; @@ -337,29 +331,29 @@ void process_party_data(struct game_data_t* game_data) { if (!found) game_data->party_3.total = 0; for(gen3_party_total_t i = 0; i < game_data->party_3.total; i++) - if(gen3_to_gen2(&game_data->party_2.mons[curr_slot], &game_data->party_3_undec[i], game_data->trainer_id)) { + if(gen3_to_gen2(&party_2->mons[curr_slot], &game_data->party_3_undec[i], game_data->trainer_id)) { curr_slot++; game_data->party_3_undec[i].is_valid_gen2 = 1; } else game_data->party_3_undec[i].is_valid_gen2 = 0; - game_data->party_2.total = curr_slot; + party_2->total = curr_slot; curr_slot = 0; for(gen3_party_total_t i = 0; i < game_data->party_3.total; i++) - if(gen3_to_gen1(&game_data->party_1.mons[curr_slot], &game_data->party_3_undec[i], game_data->trainer_id)) { + if(gen3_to_gen1(&party_1->mons[curr_slot], &game_data->party_3_undec[i], game_data->trainer_id)) { curr_slot++; game_data->party_3_undec[i].is_valid_gen1 = 1; } else game_data->party_3_undec[i].is_valid_gen1 = 0; - game_data->party_1.total = curr_slot; + party_1->total = curr_slot; } -void read_party(int slot, struct game_data_t* game_data) { +void read_party(int slot, struct game_data_t* game_data, struct game_data_priv_t* game_data_priv) { if(slot) slot = 1; - read_game_data_trainer_info(slot, game_data); + read_game_data_trainer_info(slot, game_data, game_data_priv); if(game_data->game_identifier.game_is_jp == UNDETERMINED) game_data->game_identifier.game_is_jp = is_trainer_name_japanese(game_data->trainer_name); @@ -378,47 +372,47 @@ void read_party(int slot, struct game_data_t* game_data) { copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + ribbon_pos[game_id], (u8*)game_data->giftRibbons, sizeof(game_data->giftRibbons)); if(section_id == SECTION_SYS_FLAGS_ID) { - game_data->game_cleared_flag = get_sys_flag_save(slot, i, game_id, game_clear_flag_num[game_id]); - game_data->nat_dex_flag = get_sys_flag_save(slot, i, game_id, nat_dex_flag_num[game_id]); + game_data_priv->game_cleared_flag = get_sys_flag_save(slot, i, game_id, game_clear_flag_num[game_id]); + game_data_priv->nat_dex_flag = get_sys_flag_save(slot, i, game_id, nat_dex_flag_num[game_id]); if(game_id == RS_MAIN_GAME_CODE) { - game_data->full_link_flag = 1; - game_data->nat_dex_flag = 1; + game_data_priv->full_link_flag = 1; + game_data_priv->nat_dex_flag = 1; } else - game_data->full_link_flag = get_sys_flag_save(slot, i, game_id, full_link_flag_num[game_id]); - game_data->dex_obtained_flag = get_sys_flag_save(slot, i, game_id, dex_obtained_flag_num[game_id]); + game_data_priv->full_link_flag = get_sys_flag_save(slot, i, game_id, full_link_flag_num[game_id]); + game_data_priv->dex_obtained_flag = get_sys_flag_save(slot, i, game_id, dex_obtained_flag_num[game_id]); } if(section_id == SECTION_VARS_ID) { - game_data->nat_dex_var = get_var_save(slot, i, game_id, nat_dex_var_num[game_id]); + game_data_priv->nat_dex_var = get_var_save(slot, i, game_id, nat_dex_var_num[game_id]); if(game_id == RS_MAIN_GAME_CODE) - game_data->nat_dex_var = nat_dex_var_value[game_id]; + game_data_priv->nat_dex_var = nat_dex_var_value[game_id]; } if(section_id == SECTION_GAME_STATS_ID) { - game_data->num_saves_stat = get_stat_save(slot, i, game_id, SAVED_GAME_STAT_NUM) ^ game_data->stat_enc_key; - game_data->num_trades_stat = get_stat_save(slot, i, game_id, NUM_TRADES_STAT_NUM) ^ game_data->stat_enc_key; + game_data_priv->num_saves_stat = get_stat_save(slot, i, game_id, SAVED_GAME_STAT_NUM) ^ game_data_priv->stat_enc_key; + game_data_priv->num_trades_stat = get_stat_save(slot, i, game_id, NUM_TRADES_STAT_NUM) ^ game_data_priv->stat_enc_key; } if(section_id == SECTION_SAVE_LOCATION_FLAGS_ID) - game_data->save_warp_flags = read_byte_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + SAVE_LOCATION_FLAGS_POS); + game_data_priv->save_warp_flags = read_byte_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + SAVE_LOCATION_FLAGS_POS); if(section_id == SECTION_LOCATION_ID) - game_data->curr_map = read_short_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + LOCATION_POS); + game_data_priv->curr_map = read_short_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + LOCATION_POS); if(section_id == SECTION_BASE_DEX_ID) { - game_data->nat_dex_magic = read_byte_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + nat_dex_magic_pos[game_id]); + game_data_priv->nat_dex_magic = read_byte_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + nat_dex_magic_pos[game_id]); if(game_id == RS_MAIN_GAME_CODE) - game_data->nat_dex_magic = nat_dex_magic_value[game_id]; - game_data->seen_unown_pid = read_int_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + DEX_UNOWN_PID_POS); - game_data->seen_spinda_pid = read_int_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + DEX_SPINDA_PID_POS); - copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + DEX_POS_OWNED, game_data->pokedex_owned, sizeof(game_data->pokedex_owned)); - copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + DEX_POS_SEEN_0, game_data->pokedex_seen, sizeof(game_data->pokedex_seen)); + game_data_priv->nat_dex_magic = nat_dex_magic_value[game_id]; + game_data_priv->seen_unown_pid = read_int_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + DEX_UNOWN_PID_POS); + game_data_priv->seen_spinda_pid = read_int_save((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + DEX_SPINDA_PID_POS); + copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + DEX_POS_OWNED, game_data_priv->pokedex_owned, sizeof(game_data_priv->pokedex_owned)); + copy_save_to_ram((slot * SAVE_SLOT_SIZE) + (i * SECTION_SIZE) + DEX_POS_SEEN_0, game_data_priv->pokedex_seen, sizeof(game_data_priv->pokedex_seen)); } - load_time_data(game_data, section_id, slot, i, game_id); + load_time_data(&game_data_priv->clock_events, section_id, slot, i, game_id, has_rtc_events(&game_data->game_identifier), game_data_priv->stat_enc_key); } - process_party_data(game_data); + process_party_data(game_data, &game_data_priv->party_2, &game_data_priv->party_1); } u32 calc_checksum_save_buffer(u32* buffer, u16 sum_size) { @@ -503,7 +497,7 @@ ALWAYS_INLINE u8 get_next_slot(u8 base_slot) { return (base_slot + 1) % NUM_SLOTS; } -u8 pre_update_save(struct game_data_t* game_data, u8 base_slot, enum SAVING_KIND saving_kind) { +u8 pre_update_save(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 base_slot, enum SAVING_KIND saving_kind) { u8 target_slot = get_next_slot(base_slot); u32 target_slot_save_index = read_slot_index(base_slot) - 1; @@ -542,37 +536,37 @@ u8 pre_update_save(struct game_data_t* game_data, u8 base_slot, enum SAVING_KIND buffer_8[ribbon_pos[game_id]+j] = ((u8*)game_data->giftRibbons)[j]; if(section_id == SECTION_BASE_DEX_ID) { - buffer_8[nat_dex_magic_pos[game_id]] = game_data->nat_dex_magic; - for(size_t j = 0; j < sizeof(game_data->seen_unown_pid); j++) - buffer_8[DEX_UNOWN_PID_POS+j] = ((u8*)&game_data->seen_unown_pid)[j]; - for(size_t j = 0; j < sizeof(game_data->seen_spinda_pid); j++) - buffer_8[DEX_SPINDA_PID_POS+j] = ((u8*)&game_data->seen_spinda_pid)[j]; - for(size_t j = 0; j < sizeof(game_data->pokedex_owned); j++) - buffer_8[DEX_POS_OWNED+j] = ((u8*)game_data->pokedex_owned)[j]; - for(size_t j = 0; j < sizeof(game_data->pokedex_seen); j++) - buffer_8[DEX_POS_SEEN_0+j] = ((u8*)game_data->pokedex_seen)[j]; + buffer_8[nat_dex_magic_pos[game_id]] = game_data_priv->nat_dex_magic; + for(size_t j = 0; j < sizeof(game_data_priv->seen_unown_pid); j++) + buffer_8[DEX_UNOWN_PID_POS+j] = ((u8*)&game_data_priv->seen_unown_pid)[j]; + for(size_t j = 0; j < sizeof(game_data_priv->seen_spinda_pid); j++) + buffer_8[DEX_SPINDA_PID_POS+j] = ((u8*)&game_data_priv->seen_spinda_pid)[j]; + for(size_t j = 0; j < sizeof(game_data_priv->pokedex_owned); j++) + buffer_8[DEX_POS_OWNED+j] = ((u8*)game_data_priv->pokedex_owned)[j]; + for(size_t j = 0; j < sizeof(game_data_priv->pokedex_seen); j++) + buffer_8[DEX_POS_SEEN_0+j] = ((u8*)game_data_priv->pokedex_seen)[j]; } if(section_id == SECTION_SYS_FLAGS_ID) - set_sys_flag_save(buffer_8, game_id, nat_dex_flag_num[game_id], game_data->nat_dex_flag); + set_sys_flag_save(buffer_8, game_id, nat_dex_flag_num[game_id], game_data_priv->nat_dex_flag); if(section_id == SECTION_VARS_ID) - set_var_save(buffer_8, game_id, nat_dex_var_num[game_id], game_data->nat_dex_var); + set_var_save(buffer_8, game_id, nat_dex_var_num[game_id], game_data_priv->nat_dex_var); if(section_id == SECTION_GAME_STATS_ID) { - set_stat_save(buffer_8, game_id, SAVED_GAME_STAT_NUM, game_data->num_saves_stat ^ game_data->stat_enc_key); - set_stat_save(buffer_8, game_id, NUM_TRADES_STAT_NUM, game_data->num_trades_stat ^ game_data->stat_enc_key); + set_stat_save(buffer_8, game_id, SAVED_GAME_STAT_NUM, game_data_priv->num_saves_stat ^ game_data_priv->stat_enc_key); + set_stat_save(buffer_8, game_id, NUM_TRADES_STAT_NUM, game_data_priv->num_trades_stat ^ game_data_priv->stat_enc_key); } if(section_id == SECTION_DEX_SEEN_1_ID) - for(size_t j = 0; j < sizeof(game_data->pokedex_seen); j++) - buffer_8[pokedex_extra_pos_1[game_id]+j] = ((u8*)game_data->pokedex_seen)[j]; + for(size_t j = 0; j < sizeof(game_data_priv->pokedex_seen); j++) + buffer_8[pokedex_extra_pos_1[game_id]+j] = ((u8*)game_data_priv->pokedex_seen)[j]; if(section_id == SECTION_DEX_SEEN_2_ID) - for(size_t j = 0; j < sizeof(game_data->pokedex_seen); j++) - buffer_8[pokedex_extra_pos_2[game_id]+j] = ((u8*)game_data->pokedex_seen)[j]; + for(size_t j = 0; j < sizeof(game_data_priv->pokedex_seen); j++) + buffer_8[pokedex_extra_pos_2[game_id]+j] = ((u8*)game_data_priv->pokedex_seen)[j]; - store_time_data(game_data, section_id, buffer_8, game_id); + store_time_data(&game_data_priv->clock_events, section_id, buffer_8, game_id, has_rtc_events(&game_data->game_identifier), game_data_priv->stat_enc_key); // Checksum calcs u16 sum_size = summable_bytes[section_id] >> 2; @@ -664,7 +658,7 @@ u8 has_cartridge_been_removed(){ return retval; } -u8 read_gen_3_data(struct game_data_t* game_data){ +u8 read_gen_3_data(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv){ unload_cartridge(); init_bank(); @@ -673,7 +667,7 @@ u8 read_gen_3_data(struct game_data_t* game_data){ if(slot == INVALID_SLOT) return 0; - read_party(slot, game_data); + read_party(slot, game_data, game_data_priv); own_game_data_ptr = game_data; load_cartridge(); @@ -681,7 +675,7 @@ u8 read_gen_3_data(struct game_data_t* game_data){ return 1; } -u8 pre_write_gen_3_data(struct game_data_t* game_data, u8 is_full){ +u8 pre_write_gen_3_data(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 is_full){ unload_cartridge(); init_bank(); @@ -690,14 +684,14 @@ u8 pre_write_gen_3_data(struct game_data_t* game_data, u8 is_full){ return 0; if(is_full) { - if(!pre_update_save(game_data, base_slot, FULL_SAVE)) + if(!pre_update_save(game_data, game_data_priv, base_slot, FULL_SAVE)) return 0; if(!validate_slot(get_next_slot(base_slot), &game_data->game_identifier)) return 0; } else { - if(!pre_update_save(game_data, base_slot, NON_PARTY_SAVE)) + if(!pre_update_save(game_data, game_data_priv, base_slot, NON_PARTY_SAVE)) return 0; } @@ -706,7 +700,7 @@ u8 pre_write_gen_3_data(struct game_data_t* game_data, u8 is_full){ return 1; } -u8 pre_write_updated_moves_gen_3_data(struct game_data_t* game_data){ +u8 pre_write_updated_moves_gen_3_data(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv){ unload_cartridge(); init_bank(); @@ -714,7 +708,7 @@ u8 pre_write_updated_moves_gen_3_data(struct game_data_t* game_data){ if(base_slot == INVALID_SLOT) return 0; - if(!pre_update_save(game_data, base_slot, PARTY_ONLY_SAVE)) + if(!pre_update_save(game_data, game_data_priv, base_slot, PARTY_ONLY_SAVE)) return 0; if(!validate_slot(get_next_slot(base_slot), &game_data->game_identifier)) diff --git a/source/input_handler.c b/source/input_handler.c index 04b12d9..5e0df3b 100644 --- a/source/input_handler.c +++ b/source/input_handler.c @@ -432,7 +432,7 @@ u8 handle_input_learnable_moves_menu(u16 keys, u8* cursor_y_pos) { return 0; } -u8 handle_input_base_settings_menu(u16 keys, u8* cursor_y_pos, struct game_data_t* game_data, u8 is_loaded) { +u8 handle_input_base_settings_menu(u16 keys, u8* cursor_y_pos, struct game_data_priv_t* game_data_priv, u8 is_loaded) { if(keys & KEY_B) return EXIT_BASE_SETTINGS; diff --git a/source/main.c b/source/main.c index 3b846da..64f1ed0 100644 --- a/source/main.c +++ b/source/main.c @@ -56,7 +56,7 @@ void cursor_update_trade_options(u8); void cursor_update_offer_options(u8, u8); void handle_learnable_moves_message(struct game_data_t*, u8, u8*, u32*, enum MOVES_PRINTING_TYPE); void change_nature(struct game_data_t*, u8, u8, u8*, u8); -void check_bad_trade_received(struct game_data_t*, u8, u8, u8, u8, u8, u8*); +void check_bad_trade_received(struct game_data_t*, struct game_data_priv_t*, u8, u8, u8, u8, u8, u8*); void trade_cancel_print_screen(u8); void saving_print_screen(void); void loading_print_screen(void); @@ -70,16 +70,16 @@ void waiting_offer_init(u8, u8); void waiting_accept_init(u8); void waiting_success_init(void); void trade_options_init(u8, u8*, u8); -void trade_menu_init(struct game_data_t*, u8, u8, u8, u8, u8, u8*, u8*); -void start_trade_init(struct game_data_t*, u8, u8, u8, u8, u8*); -void main_menu_init(struct game_data_t*, u8, u8, u8, u8*); +void trade_menu_init(struct game_data_t*, struct game_data_priv_t*, u8, u8, u8, u8, u8, u8*, u8*); +void start_trade_init(struct game_data_t*, struct game_data_priv_t*, u8, u8, u8, u8, u8*); +void main_menu_init(struct game_data_t*, struct game_data_priv_t*, u8, u8, u8, u8*); void info_menu_init(struct game_data_t*, u8, u8, u8*, u8); void nature_menu_init(struct game_data_t*, u8, u8, u8*); void iv_fix_menu_init(struct game_data_t*, u8, u8); void learnable_moves_message_init(struct game_data_t*, u8); void learnable_move_menu_init(struct game_data_t*, u8, u8, u8*); -void conclude_trade(struct game_data_t*, u8, u8, u8, u8*); -void return_to_trade_menu(struct game_data_t*, u8, u8, u8, u8, u8, u8*, u8*); +void conclude_trade(struct game_data_t*, struct game_data_priv_t*, u8, u8, u8, u8*); +void return_to_trade_menu(struct game_data_t*, struct game_data_priv_t*, u8, u8, u8, u8, u8, u8*, u8*); void prepare_crash_screen(enum CRASH_REASONS); void crash_on_cartridge_removed(void); void crash_on_bad_save(u8, u8); @@ -257,12 +257,12 @@ void change_nature(struct game_data_t* game_data, u8 cursor_x_pos, u8 curr_mon, *wanted_nature = get_nature(game_data[cursor_x_pos].party_3_undec[curr_mon].alter_nature.pid); } -void check_bad_trade_received(struct game_data_t* game_data, u8 target, u8 region, u8 master, u8 curr_gen, u8 own_menu, u8* cursor_y_pos) { +void check_bad_trade_received(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 target, u8 region, u8 master, u8 curr_gen, u8 own_menu, u8* cursor_y_pos) { u8 useless = 0; // Handle bad received / No valid mons if(handle_input_trading_menu(&useless, &useless, 0, curr_gen, own_menu) == CANCEL_TRADING) { if(own_menu) - main_menu_init(&game_data[0], target, region, master, cursor_y_pos); + main_menu_init(&game_data[0], game_data_priv, target, region, master, cursor_y_pos); else waiting_offer_init(1, 0); } @@ -397,7 +397,7 @@ void trade_options_init(u8 cursor_x_pos, u8* submenu_cursor_x_pos, u8 own_menu) prepare_flush(); } -void trade_menu_init(struct game_data_t* game_data, u8 target, u8 region, u8 master, u8 curr_gen, u8 own_menu, u8* cursor_y_pos, u8* cursor_x_pos) { +void trade_menu_init(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 target, u8 region, u8 master, u8 curr_gen, u8 own_menu, u8* cursor_y_pos, u8* cursor_x_pos) { set_bg_pos(BASE_SCREEN, X_OFFSET_TRADE_MENU, Y_OFFSET_TRADE_MENU); curr_state = TRADING_MENU; *cursor_y_pos = 0; @@ -407,14 +407,14 @@ void trade_menu_init(struct game_data_t* game_data, u8 target, u8 region, u8 mas trade_cancel_print_screen(1); set_party_sprite_counter(); cursor_update_trading_menu(*cursor_y_pos, *cursor_x_pos); - check_bad_trade_received(game_data, target, region, master, curr_gen, own_menu, cursor_y_pos); + check_bad_trade_received(game_data, game_data_priv, target, region, master, curr_gen, own_menu, cursor_y_pos); prepare_flush(); } -void start_trade_init(struct game_data_t* game_data, u8 target, u8 region, u8 master, u8 curr_gen, u8* cursor_y_pos) { - if(is_valid_for_gen(game_data, curr_gen)) { +void start_trade_init(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 target, u8 region, u8 master, u8 curr_gen, u8* cursor_y_pos) { + if(is_valid_for_gen(game_data, game_data_priv, curr_gen)) { curr_state = START_TRADE; - load_comm_buffer(game_data, curr_gen, region); + load_comm_buffer(game_data, &game_data_priv->party_2, &game_data_priv->party_1, curr_gen, region); init_start_state(); set_screen(BASE_SCREEN); set_bg_pos(BASE_SCREEN, 0, 0); @@ -426,12 +426,12 @@ void start_trade_init(struct game_data_t* game_data, u8 target, u8 region, u8 ma start_transfer(master, curr_gen); } else - conclude_trade(game_data, target, region, master, cursor_y_pos); + conclude_trade(game_data, game_data_priv, target, region, master, cursor_y_pos); } -void main_menu_init(struct game_data_t* game_data, u8 target, u8 region, u8 master, u8* cursor_y_pos) { +void main_menu_init(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 target, u8 region, u8 master, u8* cursor_y_pos) { curr_state = MAIN_MENU; - prepare_main_options(game_data); + prepare_main_options(game_data, game_data_priv); set_screen(BASE_SCREEN); set_bg_pos(BASE_SCREEN, 0, 0); print_main_menu(1, target, region, master); @@ -503,12 +503,12 @@ void learnable_moves_message_init(struct game_data_t* game_data, u8 curr_mon) { prepare_flush(); } -void conclude_trade(struct game_data_t* game_data, u8 target, u8 region, u8 master, u8* cursor_y_pos) { +void conclude_trade(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 target, u8 region, u8 master, u8* cursor_y_pos) { stop_transfer(master); - main_menu_init(game_data, target, region, master, cursor_y_pos); + main_menu_init(game_data, game_data_priv, target, region, master, cursor_y_pos); } -void return_to_trade_menu(struct game_data_t* game_data, u8 target, u8 region, u8 master, u8 curr_gen, u8 own_menu, u8* cursor_y_pos, u8* cursor_x_pos) { +void return_to_trade_menu(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 target, u8 region, u8 master, u8 curr_gen, u8 own_menu, u8* cursor_y_pos, u8* cursor_x_pos) { curr_state = TRADING_MENU; set_screen(BASE_SCREEN); reset_sprites_to_party(); @@ -517,7 +517,7 @@ void return_to_trade_menu(struct game_data_t* game_data, u8 target, u8 region, u enable_all_sprites(); trade_cancel_print_screen(1); cursor_update_trading_menu(*cursor_y_pos, *cursor_x_pos); - check_bad_trade_received(game_data, target, region, master, curr_gen, own_menu, cursor_y_pos); + check_bad_trade_received(game_data, game_data_priv, target, region, master, curr_gen, own_menu, cursor_y_pos); prepare_flush(); } @@ -580,6 +580,7 @@ int main(void) init_save_data(); u16 keys; struct game_data_t game_data[2]; + struct game_data_priv_t game_data_priv; init_game_data(&game_data[0]); get_game_id(&game_data[0].game_identifier); @@ -597,7 +598,7 @@ int main(void) irqEnable(IRQ_VBLANK); irqDisable(IRQ_SERIAL); - read_gen_3_data(&game_data[0]); + read_gen_3_data(&game_data[0], &game_data_priv); init_item_icon(); init_cursor(); @@ -625,7 +626,7 @@ int main(void) u8 curr_page = 0; const u8* party_selected_mons[2] = {&curr_mon, &other_mon}; - main_menu_init(&game_data[0], target, region, master, &cursor_y_pos); + main_menu_init(&game_data[0], &game_data_priv, target, region, master, &cursor_y_pos); //load_pokemon_sprite_raw(&game_data[1].party_3_undec[0], 1, 0, 0); //worst_case_conversion_tester(&counter); @@ -646,7 +647,7 @@ int main(void) keys = 0; read_comm_buffer(&game_data[1], curr_gen, region); own_menu = 0; - trade_menu_init(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + trade_menu_init(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); } else print_start_trade(); @@ -657,11 +658,11 @@ int main(void) keys = 0; result = get_received_trade_offer(); if(result == TRADE_CANCELLED) - conclude_trade(&game_data[0], target, region, master, &cursor_y_pos); + conclude_trade(&game_data[0], &game_data_priv, target, region, master, &cursor_y_pos); else if(result == WANTS_TO_CANCEL) { rejected_print_screen(1); wait_frames(WAITING_TIME_REJECTED); - return_to_trade_menu(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + return_to_trade_menu(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); } else { u8 is_invalid = is_invalid_offer(game_data, curr_mon, result, curr_gen, get_gen3_offer()); @@ -671,7 +672,7 @@ int main(void) } else { is_invalid -= 1; - return_to_trade_menu(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + return_to_trade_menu(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); invalid_init(is_invalid); waiting_accept_init(1); } @@ -682,26 +683,26 @@ int main(void) if(has_accepted_offer()) { trading_animation_init(game_data, curr_mon, other_mon); prepare_gen3_success(&game_data[0].party_3_undec[curr_mon], &game_data[1].party_3_undec[other_mon]); - evolved = trade_mons(game_data, curr_mon, other_mon, curr_gen); + evolved = trade_mons(game_data, &game_data_priv, curr_mon, other_mon, curr_gen); if(evolved) evolution_animation_init(game_data, curr_mon); - game_data[0].num_trades_stat++; - if(game_data[0].num_trades_stat > 0xFFFFFF) - game_data[0].num_trades_stat = 0xFFFFFF; - if(game_data[0].num_saves_stat < 0xFFFFFF) - game_data[0].num_saves_stat--; - if(game_data[0].num_saves_stat > 0xFFFFFF) - game_data[0].num_saves_stat = 0xFFFFFF; + game_data_priv.num_trades_stat++; + if(game_data_priv.num_trades_stat > 0xFFFFFF) + game_data_priv.num_trades_stat = 0xFFFFFF; + if(game_data_priv.num_saves_stat < 0xFFFFFF) + game_data_priv.num_saves_stat--; + if(game_data_priv.num_saves_stat > 0xFFFFFF) + game_data_priv.num_saves_stat = 0xFFFFFF; curr_state = TRADING_ANIMATION; learnable_moves = game_data[0].party_3_undec[curr_mon].learnable_moves != NULL; - success = pre_write_gen_3_data(&game_data[0], !learnable_moves); + success = pre_write_gen_3_data(&game_data[0], &game_data_priv, !learnable_moves); if(!success) crash_on_bad_save(1, master); } else { rejected_print_screen(0); wait_frames(WAITING_TIME_REJECTED); - return_to_trade_menu(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + return_to_trade_menu(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); } break; case FAILED_SUCCESS: @@ -715,9 +716,9 @@ int main(void) crash_on_bad_save(1, master); if(curr_gen == 3) wait_frames(SWI_DivMod(get_rng() & 0x7FFFFFFF, MAX_RANDOM_WAIT_TIME)); - process_party_data(&game_data[0]); + process_party_data(&game_data[0], &game_data_priv.party_2, &game_data_priv.party_1); stop_transfer(master); - start_trade_init(&game_data[0], target, region, master, curr_gen, &cursor_y_pos); + start_trade_init(&game_data[0], &game_data_priv, target, region, master, curr_gen, &cursor_y_pos); break; default: break; @@ -752,7 +753,7 @@ int main(void) handle_learnable_moves_message(game_data, curr_mon, &cursor_x_pos, &curr_move, LEARNABLE_P); break; case COMPLETED: - success = pre_write_updated_moves_gen_3_data(&game_data[0]); + success = pre_write_updated_moves_gen_3_data(&game_data[0], &game_data_priv); if(!success) crash_on_bad_save(1, master); disable_screen(LEARN_MOVE_MESSAGE_WINDOW_SCREEN); @@ -793,16 +794,16 @@ int main(void) else if(returned_val == START_SETTINGS_MENU) { curr_state = BASE_SETTINGS_MENU; disable_cursor(); - print_base_settings_menu(&game_data[0], get_is_cartridge_loaded()); + print_base_settings_menu(&game_data_priv, get_is_cartridge_loaded()); } else if(returned_val > VIEW_OWN_PARTY && returned_val <= VIEW_OWN_PARTY + TOTAL_GENS) { curr_gen = returned_val - VIEW_OWN_PARTY; own_menu = 1; - trade_menu_init(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + trade_menu_init(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); } else if(returned_val > 0 && returned_val <= TOTAL_GENS) { curr_gen = returned_val; - start_trade_init(&game_data[0], target, region, master, curr_gen, &cursor_y_pos); + start_trade_init(&game_data[0], &game_data_priv, target, region, master, curr_gen, &cursor_y_pos); } break; case TRADING_MENU: @@ -814,7 +815,7 @@ int main(void) if(own_menu) { if(returned_val == CANCEL_TRADING) - main_menu_init(&game_data[0], target, region, master, &cursor_y_pos); + main_menu_init(&game_data[0], &game_data_priv, target, region, master, &cursor_y_pos); else if(returned_val) { // TODO: Handle Eevee into Umbreon/Espeon if(game_data[cursor_x_pos].party_3_undec[curr_mon].is_valid_gen3 && (!game_data[cursor_x_pos].party_3_undec[curr_mon].is_egg) && game_data[cursor_x_pos].party_3_undec[curr_mon].can_roamer_fix) @@ -838,7 +839,7 @@ int main(void) prev_val = curr_mon; returned_val = handle_input_info_menu(game_data, &cursor_y_pos, cursor_x_pos, keys, &curr_mon, curr_gen, &curr_page); if(returned_val == CANCEL_INFO) - return_to_trade_menu(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + return_to_trade_menu(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); else print_pokemon_pages(returned_val, curr_mon != prev_val, &game_data[cursor_x_pos].party_3_undec[curr_mon], curr_page); break; @@ -852,17 +853,17 @@ int main(void) break; case MULTIBOOT: if(handle_input_multiboot_menu(keys)) - main_menu_init(&game_data[0], target, region, master, &cursor_y_pos); + main_menu_init(&game_data[0], &game_data_priv, target, region, master, &cursor_y_pos); break; case START_TRADE: if(handle_input_trade_setup(keys, curr_gen)) - conclude_trade(&game_data[0], target, region, master, &cursor_y_pos); + conclude_trade(&game_data[0], &game_data_priv, target, region, master, &cursor_y_pos); break; case TRADE_OPTIONS: returned_val = handle_input_trade_options(keys, &submenu_cursor_x_pos); if(returned_val) { if(returned_val == CANCEL_TRADE_OPTIONS) - return_to_trade_menu(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + return_to_trade_menu(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); else { if(!submenu_cursor_x_pos) info_menu_init(game_data, cursor_x_pos, curr_mon, &curr_page, 0); @@ -887,11 +888,11 @@ int main(void) returned_val = handle_input_nature_menu(keys); if(returned_val) { if(returned_val == CANCEL_NATURE) - return_to_trade_menu(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + return_to_trade_menu(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); else if(returned_val == CONFIRM_NATURE) { if(game_data[cursor_x_pos].party_3_undec[curr_mon].is_valid_gen3 && (!game_data[cursor_x_pos].party_3_undec[curr_mon].is_egg)) set_alter_data(&game_data[cursor_x_pos].party_3_undec[curr_mon], &game_data[cursor_x_pos].party_3_undec[curr_mon].alter_nature); - return_to_trade_menu(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + return_to_trade_menu(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); } else { change_nature(game_data, cursor_x_pos, curr_mon, &submenu_cursor_y_pos, returned_val == INC_NATURE); @@ -903,7 +904,7 @@ int main(void) returned_val = handle_input_iv_fix_menu(keys); if(returned_val) { if(returned_val == CANCEL_IV_FIX) - return_to_trade_menu(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + return_to_trade_menu(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); else { if(game_data[cursor_x_pos].party_3_undec[curr_mon].is_valid_gen3 && (!game_data[cursor_x_pos].party_3_undec[curr_mon].is_egg) && game_data[cursor_x_pos].party_3_undec[curr_mon].can_roamer_fix) { set_alter_data(&game_data[cursor_x_pos].party_3_undec[curr_mon], &game_data[cursor_x_pos].party_3_undec[curr_mon].fixed_ivs); @@ -912,23 +913,24 @@ int main(void) set_default_gift_ribbons(&game_data[cursor_x_pos]); if(!cursor_x_pos) { saving_print_screen(); - success = pre_write_gen_3_data(&game_data[0], 1); + success = pre_write_gen_3_data(&game_data[0], &game_data_priv, 1); if(success) success = complete_write_gen_3_data(&game_data[0]); if(!success) crash_on_bad_save(0, master); + process_party_data(&game_data[0], &game_data_priv.party_2, &game_data_priv.party_1); } } - return_to_trade_menu(game_data, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); + return_to_trade_menu(game_data, &game_data_priv, target, region, master, curr_gen, own_menu, &cursor_y_pos, &cursor_x_pos); } } break; case BASE_SETTINGS_MENU: // TODO: Handle the Settings menu - returned_val = handle_input_base_settings_menu(keys, &cursor_y_pos, &game_data[0], get_is_cartridge_loaded()); + returned_val = handle_input_base_settings_menu(keys, &cursor_y_pos, &game_data_priv, get_is_cartridge_loaded()); if(returned_val) { if(returned_val == EXIT_BASE_SETTINGS) - main_menu_init(&game_data[0], target, region, master, &cursor_y_pos); + main_menu_init(&game_data[0], &game_data_priv, target, region, master, &cursor_y_pos); } else { @@ -940,9 +942,9 @@ int main(void) loading_print_screen(); init_game_data(&game_data[0]); get_game_id(&game_data[0].game_identifier); - read_gen_3_data(&game_data[0]); + read_gen_3_data(&game_data[0], &game_data_priv); // TODO: Print warnings for bad location/no nat dex/other - main_menu_init(&game_data[0], target, region, master, &cursor_y_pos); + main_menu_init(&game_data[0], &game_data_priv, target, region, master, &cursor_y_pos); } break; case OFFER_MENU: @@ -993,7 +995,7 @@ int main(void) cursor_update_learnable_move_menu(cursor_y_pos); break; default: - main_menu_init(&game_data[0], target, region, master, &cursor_y_pos); + main_menu_init(&game_data[0], &game_data_priv, target, region, master, &cursor_y_pos); break; } update = 0; diff --git a/source/menu_text_handler.c b/source/menu_text_handler.c index ebd6724..b6c1f3d 100644 --- a/source/menu_text_handler.c +++ b/source/menu_text_handler.c @@ -325,21 +325,21 @@ void print_offer_options_screen(struct game_data_t* game_data, u8 own_mon, u8 ot PRINT_FUNCTION("Summary: Receiving"); } -void print_base_settings_menu(struct game_data_t* game_data, u8 is_loaded) { +void print_base_settings_menu(struct game_data_priv_t* game_data_priv, u8 is_loaded) { default_reset_screen(); PRINT_FUNCTION("AAAA\n\n"); if(is_loaded) { //change_time_of_day(game_data); //enable_rtc_reset(&game_data->clock_events); - if(is_daytime(game_data)) + if(is_daytime(&game_data_priv->clock_events)) PRINT_FUNCTION("Time: Day\n\n"); else PRINT_FUNCTION("Time: Night\n\n"); - if(is_high_tide(game_data)) + if(is_high_tide(&game_data_priv->clock_events)) PRINT_FUNCTION("Tide: High\n\n"); else PRINT_FUNCTION("Tide: Low\n\n"); - PRINT_FUNCTION("\x03 \x03", game_data->clock_events.enable_rtc_reset_flag, game_data->clock_events.enable_rtc_reset_var); + PRINT_FUNCTION("\x03 \x03", game_data_priv->clock_events.enable_rtc_reset_flag, game_data_priv->clock_events.enable_rtc_reset_var); } set_text_y(Y_LIMIT-1); diff --git a/source/options_handler.c b/source/options_handler.c index 073d013..f8a220a 100644 --- a/source/options_handler.c +++ b/source/options_handler.c @@ -2,8 +2,8 @@ #include "party_handler.h" #include "options_handler.h" -void set_valid_options_main(struct game_data_t*); -void fill_options_main_array(struct game_data_t*); +void set_valid_options_main(struct game_data_t*, struct game_data_priv_t*); +void fill_options_main_array(struct game_data_t*, struct game_data_priv_t*); gen3_party_total_t prepare_trade_options_num(u8*); void fill_trade_options(u8*, struct game_data_t*, u8); @@ -12,11 +12,11 @@ u8 valid_options_main; u8 options_trade[2][PARTY_SIZE]; u8 num_options_trade[2]; -u8 is_valid_for_gen(struct game_data_t* game_data, u8 gen) { +u8 is_valid_for_gen(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv, u8 gen) { if(gen == 1) - return (game_data->party_1.total > 0); + return (game_data_priv->party_1.total > 0); if(gen == 2) - return (game_data->party_2.total > 0); + return (game_data_priv->party_2.total > 0); u8 found = 0; for(gen3_party_total_t i = 0; i < game_data->party_3.total; i++) if(game_data->party_3_undec[i].is_valid_gen3) { @@ -26,34 +26,34 @@ u8 is_valid_for_gen(struct game_data_t* game_data, u8 gen) { return found; } -void set_valid_options_main(struct game_data_t* game_data) { - valid_options_main = (is_valid_for_gen(game_data, 1) ? 1: 0) | (is_valid_for_gen(game_data, 2) ? 2: 0) | (is_valid_for_gen(game_data, 3) ? 4: 0); +void set_valid_options_main(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv) { + valid_options_main = (is_valid_for_gen(game_data, game_data_priv, 1) ? 1: 0) | (is_valid_for_gen(game_data, game_data_priv, 2) ? 2: 0) | (is_valid_for_gen(game_data, game_data_priv, 3) ? 4: 0); } -void fill_options_main_array(struct game_data_t* game_data) { +void fill_options_main_array(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv) { u8 curr_slot = MAIN_OPTIONS_NO_OPTION; for(int i = 0; i < MAIN_OPTIONS_NUM; i++) options_main[i] = 0; - if(is_valid_for_gen(game_data, 1)) { + if(is_valid_for_gen(game_data, game_data_priv, 1)) { options_main[curr_slot++] = 1; for(int i = curr_slot; i < MAIN_OPTIONS_NUM; i++) options_main[i] = 1; } - if(is_valid_for_gen(game_data, 2)) { + if(is_valid_for_gen(game_data, game_data_priv, 2)) { options_main[curr_slot++] = 2; for(int i = curr_slot; i < MAIN_OPTIONS_NUM; i++) options_main[i] = 2; } - if(is_valid_for_gen(game_data, 3)) { + if(is_valid_for_gen(game_data, game_data_priv, 3)) { options_main[curr_slot++] = 3; for(int i = curr_slot; i < MAIN_OPTIONS_NUM; i++) options_main[i] = 3; } } -void prepare_main_options(struct game_data_t* game_data) { - fill_options_main_array(game_data); - set_valid_options_main(game_data); +void prepare_main_options(struct game_data_t* game_data, struct game_data_priv_t* game_data_priv) { + fill_options_main_array(game_data, game_data_priv); + set_valid_options_main(game_data, game_data_priv); } u8 get_valid_options_main() { diff --git a/source/sio_buffers.c b/source/sio_buffers.c index c52b52a..5909743 100644 --- a/source/sio_buffers.c +++ b/source/sio_buffers.c @@ -16,11 +16,11 @@ void prepare_random_data_gen12(struct random_data_t*); void prepare_patch_set(u8*, u8*, size_t, size_t, size_t, size_t); void apply_patch_set(u8*, u8*, size_t, size_t, size_t, size_t); void prepare_mail_gen2(u8*, size_t, u8*, size_t, size_t); -void load_names_gen12(struct game_data_t*, u8*, u8*, u8*, u8, u8); -void load_party_info_gen2(struct game_data_t*, struct gen2_party_info*); -void load_party_info_gen1(struct game_data_t*, struct gen1_party_info*); -void prepare_gen2_trade_data(struct game_data_t*, u32*, u8, size_t*); -void prepare_gen1_trade_data(struct game_data_t*, u32*, u8, size_t*); +void load_names_gen12(struct game_data_t*, struct gen2_party*, struct gen1_party*, u8*, u8*, u8*, u8); +void load_party_info_gen2(struct gen2_party*, struct gen2_party_info*); +void load_party_info_gen1(struct gen1_party*, struct gen1_party_info*); +void prepare_gen2_trade_data(struct game_data_t*, struct gen2_party*, u32*, u8, size_t*); +void prepare_gen1_trade_data(struct game_data_t*, struct gen1_party*, u32*, u8, size_t*); void prepare_gen3_trade_data(struct game_data_t*, u32*, size_t*); void read_gen12_trade_data(struct game_data_t*, u32*, u8, u8); void read_gen3_trade_data(struct game_data_t* game_data, u32*); @@ -124,10 +124,16 @@ void prepare_mail_gen2(u8* buffer, size_t size, u8* patch_set_buffer, size_t pat prepare_patch_set(buffer, patch_set_buffer, size, start_pos, patch_set_buffer_size, 0); } -void load_names_gen12(struct game_data_t* game_data, u8* trainer_name, u8* ot_names, u8* nicknames, u8 is_jp, u8 curr_gen){ +void load_names_gen12(struct game_data_t* game_data, struct gen2_party* party_2, struct gen1_party* party_1, u8* trainer_name, u8* ot_names, u8* nicknames, u8 is_jp){ size_t size = STRING_GEN2_INT_SIZE; if(is_jp) size = STRING_GEN2_JP_SIZE; + + u8 curr_gen = 0; + if(party_2 != NULL) + curr_gen = 2; + if(party_1 != NULL) + curr_gen = 1; text_gen3_to_gen12(game_data->trainer_name, trainer_name, OT_NAME_GEN3_SIZE+1, size, game_data->game_identifier.game_is_jp, is_jp); for(size_t i = 0; i < size; i++) @@ -135,24 +141,27 @@ void load_names_gen12(struct game_data_t* game_data, u8* trainer_name, u8* ot_na trainer_name[i] = NO_ACTION_BYTE-2; trainer_name[size-1] = GEN2_EOL; + if(!curr_gen) + return; + for(gen3_party_total_t i = 0; i < PARTY_SIZE; i++) { u8* src_ot_name; u8* src_nickname; if(is_jp && curr_gen == 2) { - src_ot_name = (u8*)&game_data->party_2.mons[i].ot_name_jp; - src_nickname = (u8*)&game_data->party_2.mons[i].nickname_jp; + src_ot_name = party_2->mons[i].ot_name_jp; + src_nickname = party_2->mons[i].nickname_jp; } else if(curr_gen == 2) { - src_ot_name = (u8*)&game_data->party_2.mons[i].ot_name; - src_nickname = (u8*)&game_data->party_2.mons[i].nickname; + src_ot_name = party_2->mons[i].ot_name; + src_nickname = party_2->mons[i].nickname; } else if(is_jp) { - src_ot_name = (u8*)&game_data->party_1.mons[i].ot_name_jp; - src_nickname = (u8*)&game_data->party_1.mons[i].nickname_jp; + src_ot_name = party_1->mons[i].ot_name_jp; + src_nickname = party_1->mons[i].nickname_jp; } else { - src_ot_name = (u8*)&game_data->party_1.mons[i].ot_name; - src_nickname = (u8*)&game_data->party_1.mons[i].nickname; + src_ot_name = party_1->mons[i].ot_name; + src_nickname = party_1->mons[i].nickname; } copy_bytes(src_ot_name, ot_names, size, 0, i*size); ot_names[(i*size)+size-1] = GEN2_EOL; @@ -161,41 +170,39 @@ void load_names_gen12(struct game_data_t* game_data, u8* trainer_name, u8* ot_na } } -void load_party_info_gen2(struct game_data_t* game_data, struct gen2_party_info* party_info){ - u8 num_options = game_data->party_2.total; +void load_party_info_gen2(struct gen2_party* party_2, struct gen2_party_info* party_info){ + u8 num_options = party_2->total; if(num_options > PARTY_SIZE) num_options = PARTY_SIZE; party_info->num_mons = num_options; for(int i = 0; i < num_options; i++) { - copy_bytes(&game_data->party_2.mons[i].data, &(party_info->mons_data[i]), sizeof(struct gen2_mon_data), 0, 0); - party_info->mons_index[i] = game_data->party_2.mons[i].data.species; - if(game_data->party_2.mons[i].is_egg) + copy_bytes(&party_2->mons[i].data, &(party_info->mons_data[i]), sizeof(struct gen2_mon_data), 0, 0); + party_info->mons_index[i] = party_2->mons[i].data.species; + if(party_2->mons[i].is_egg) party_info->mons_index[i] = GEN2_EGG; } for(int i = num_options; i < MON_INDEX_SIZE; i++) party_info->mons_index[i] = GEN2_NO_MON; - - party_info->trainer_id = (game_data->trainer_id&0xFFFF); } -void load_party_info_gen1(struct game_data_t* game_data, struct gen1_party_info* party_info){ - u8 num_options = game_data->party_1.total; +void load_party_info_gen1(struct gen1_party* party_1, struct gen1_party_info* party_info){ + u8 num_options = party_1->total; if(num_options > PARTY_SIZE) num_options = PARTY_SIZE; party_info->num_mons = num_options; for(int i = 0; i < num_options; i++) { - copy_bytes(&game_data->party_1.mons[i].data, &(party_info->mons_data[i]), sizeof(struct gen1_mon_data), 0, 0); - party_info->mons_index[i] = game_data->party_1.mons[i].data.species; + copy_bytes(&party_1->mons[i].data, &(party_info->mons_data[i]), sizeof(struct gen1_mon_data), 0, 0); + party_info->mons_index[i] = party_1->mons[i].data.species; } for(int i = num_options; i < MON_INDEX_SIZE; i++) party_info->mons_index[i] = GEN2_NO_MON; } -void prepare_gen2_trade_data(struct game_data_t* game_data, u32* buffer, u8 is_jp, size_t* sizes) { +void prepare_gen2_trade_data(struct game_data_t* game_data, struct gen2_party* party_2, u32* buffer, u8 is_jp, size_t* sizes) { struct gen2_trade_data_int* td_int = (struct gen2_trade_data_int*)buffer; struct gen2_trade_data_jp* td_jp = (struct gen2_trade_data_jp*)buffer; @@ -213,13 +220,15 @@ void prepare_gen2_trade_data(struct game_data_t* game_data, u32* buffer, u8 is_j if(is_jp) nicknames = (u8*)td_jp->trainer_info.nicknames; - load_names_gen12(game_data, trainer_name, ot_names, nicknames, is_jp, 2); + load_names_gen12(game_data, party_2, NULL, trainer_name, ot_names, nicknames, is_jp); struct gen2_party_info* party_info = (struct gen2_party_info*)&td_int->trainer_info.party_info; if(is_jp) party_info = (struct gen2_party_info*)&td_jp->trainer_info.party_info; - load_party_info_gen2(game_data, party_info); + load_party_info_gen2(party_2, party_info); + + party_info->trainer_id = (game_data->trainer_id&0xFFFF); u8* safety_bytes = (u8*)td_int->trainer_info.safety_bytes; if(is_jp) @@ -255,7 +264,7 @@ void prepare_gen2_trade_data(struct game_data_t* game_data, u32* buffer, u8 is_j sizes[2] += USELESS_SYNC_BYTES + sizeof(struct party_mail_data_gen2_jp); } -void prepare_gen1_trade_data(struct game_data_t* game_data, u32* buffer, u8 is_jp, size_t* sizes) { +void prepare_gen1_trade_data(struct game_data_t* game_data, struct gen1_party* party_1, u32* buffer, u8 is_jp, size_t* sizes) { struct gen1_trade_data_int* td_int = (struct gen1_trade_data_int*)buffer; struct gen1_trade_data_jp* td_jp = (struct gen1_trade_data_jp*)buffer; @@ -273,13 +282,13 @@ void prepare_gen1_trade_data(struct game_data_t* game_data, u32* buffer, u8 is_j if(is_jp) nicknames = (u8*)td_jp->trainer_info.nicknames; - load_names_gen12(game_data, trainer_name, ot_names, nicknames, is_jp, 1); + load_names_gen12(game_data, NULL, party_1, trainer_name, ot_names, nicknames, is_jp); struct gen1_party_info* party_info = (struct gen1_party_info*)&td_int->trainer_info.party_info; if(is_jp) party_info = (struct gen1_party_info*)&td_jp->trainer_info.party_info; - load_party_info_gen1(game_data, party_info); + load_party_info_gen1(party_1, party_info); u8* safety_bytes = (u8*)td_int->trainer_info.safety_bytes; if(is_jp) @@ -505,17 +514,17 @@ void read_gen3_trade_data(struct game_data_t* game_data, u32* buffer) { game_data->party_3.total = 0; } -void load_comm_buffer(struct game_data_t* game_data, int curr_gen, u8 is_jp) { +void load_comm_buffer(struct game_data_t* game_data, struct gen2_party* party_2, struct gen1_party* party_1, int curr_gen, u8 is_jp) { for(int i = 0; i < NUM_SIZES; i++) buffer_sizes[i] = SIZE_STOP; switch(curr_gen) { case 1: - prepare_gen1_trade_data(game_data, communication_buffers[OWN_BUFFER], is_jp, buffer_sizes); + prepare_gen1_trade_data(game_data, party_1, communication_buffers[OWN_BUFFER], is_jp, buffer_sizes); break; case 2: - prepare_gen2_trade_data(game_data, communication_buffers[OWN_BUFFER], is_jp, buffer_sizes); + prepare_gen2_trade_data(game_data, party_2, communication_buffers[OWN_BUFFER], is_jp, buffer_sizes); break; default: prepare_gen3_trade_data(game_data, communication_buffers[OWN_BUFFER], buffer_sizes);