mirror of
https://github.com/GearsProgress/Poke_Transporter_GB.git
synced 2026-03-21 17:34:42 -05:00
Do a little bit of documentation and optimization for some of the current save-related routines.
Some of the logic wasn't very clear from just looking at the code and some of it also wasn't very optimal. So I added some comments and optimized some stuff to make it better.
This commit is contained in:
parent
23292afc0c
commit
547d2c81c0
|
|
@ -15,10 +15,25 @@ extern char mem_name;
|
||||||
extern u8 global_memory_buffer[0x1000];
|
extern u8 global_memory_buffer[0x1000];
|
||||||
extern rom_data curr_GBA_rom;
|
extern rom_data curr_GBA_rom;
|
||||||
|
|
||||||
void initalize_memory_locations();
|
/**
|
||||||
|
* @brief Given that the save sections within a save slot are not saved in a fixed order,
|
||||||
|
* This function will walk through the save slot to fill the memory_section_array map.
|
||||||
|
*
|
||||||
|
* After calling this, memory_section_array will point to the save offset by each section ID.
|
||||||
|
* So memory_section_array[0] will point to the save offset of section 0, etc.
|
||||||
|
*/
|
||||||
|
void initialize_memory_locations();
|
||||||
|
|
||||||
void print_mem_section();
|
void print_mem_section();
|
||||||
//bool insert_pokemon(Pokemon party_array[], int num);
|
//bool insert_pokemon(Pokemon party_array[], int num);
|
||||||
void reverse_endian(u8 *data, size_t size);
|
void reverse_endian(u8 *data, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function will update the checksum in global_memory_buffer.
|
||||||
|
* It assumes that global_memory_buffer contains one of the save data sections.
|
||||||
|
*
|
||||||
|
* @param hall_of_fame This is needed to indicate if you're trying to save the hall of fame section. The checksum offset is slightly different there.
|
||||||
|
*/
|
||||||
void update_memory_buffer_checksum(bool hall_of_fame);
|
void update_memory_buffer_checksum(bool hall_of_fame);
|
||||||
bool read_flag(u16 flag_id);
|
bool read_flag(u16 flag_id);
|
||||||
bool compare_map_and_npc_data(int map_bank, int map_id, int npc_id);
|
bool compare_map_and_npc_data(int map_bank, int map_id, int npc_id);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include <tonc.h>
|
#include <tonc.h>
|
||||||
#include "pokemon_party.h"
|
#include "pokemon_party.h"
|
||||||
#include "debug_mode.h"
|
#include "debug_mode.h"
|
||||||
#include "save_data_manager.h"
|
#include "ptgb_save_data_manager.h"
|
||||||
#include "script_var.h"
|
#include "script_var.h"
|
||||||
#include "pokemon_data.h"
|
#include "pokemon_data.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
#ifndef SAVE_DATA_MANAGER_H
|
#ifndef PTGB_SAVE_DATA_MANAGER_H
|
||||||
#define SAVE_DATA_MANAGER_H
|
#define PTGB_SAVE_DATA_MANAGER_H
|
||||||
|
|
||||||
#include <tonc.h>
|
|
||||||
#include "rom_data.h"
|
#include "rom_data.h"
|
||||||
|
|
||||||
#define HALL_OF_FAME 0x01C000
|
#define HALL_OF_FAME 0x01C000
|
||||||
#define HOF_SECTION 2032
|
#define HOF_SECTION 2032
|
||||||
|
|
||||||
|
// NOTE: This module doesn't manage the _game_ save. It manages Poke_Transporter's specific save data.
|
||||||
|
// This save data is stored at an unused section (HOF_SECTION) of the HALL OF FAME save section.
|
||||||
|
|
||||||
// Data map:
|
// Data map:
|
||||||
// There are 1936 (0x790) unused bytes starting at 0x1D7F0
|
// There are 1936 (0x790) unused bytes starting at 0x1D7F0
|
||||||
|
|
||||||
|
|
@ -27,7 +29,7 @@ void set_def_lang(int nLang);
|
||||||
int get_def_lang_num();
|
int get_def_lang_num();
|
||||||
bool get_tutorial_flag();
|
bool get_tutorial_flag();
|
||||||
void set_tutorial_flag(bool value);
|
void set_tutorial_flag(bool value);
|
||||||
void initalize_save_data();
|
void initialize_save_data();
|
||||||
int get_dex_completion(int gen, bool include_mythicals);
|
int get_dex_completion(int gen, bool include_mythicals);
|
||||||
bool check_can_save();
|
bool check_can_save();
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#include "typeDefs.h"
|
#include "typeDefs.h"
|
||||||
#include "button_menu.h"
|
#include "button_menu.h"
|
||||||
#include "button_handler.h"
|
#include "button_handler.h"
|
||||||
#include "save_data_manager.h"
|
#include "ptgb_save_data_manager.h"
|
||||||
#include "global_frame_controller.h"
|
#include "global_frame_controller.h"
|
||||||
#include "string"
|
#include "string"
|
||||||
#include "sprite_data.h"
|
#include "sprite_data.h"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include <tonc.h>
|
#include <tonc.h>
|
||||||
#include "button_menu.h"
|
#include "button_menu.h"
|
||||||
#include "button_handler.h"
|
#include "button_handler.h"
|
||||||
#include "save_data_manager.h"
|
#include "ptgb_save_data_manager.h"
|
||||||
#include "global_frame_controller.h"
|
#include "global_frame_controller.h"
|
||||||
#include "string"
|
#include "string"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,17 @@
|
||||||
#include "libraries/Pokemon-Gen3-to-Gen-X/include/save.h"
|
#include "libraries/Pokemon-Gen3-to-Gen-X/include/save.h"
|
||||||
#include "text_engine.h"
|
#include "text_engine.h"
|
||||||
|
|
||||||
#define pkmn_length 80
|
#define READ_SAVE_SECTIONS 14
|
||||||
#define READ_SAVE_SECTIONS 5
|
|
||||||
#define TOTAL_SAVE_SECTIONS 14
|
#define TOTAL_SAVE_SECTIONS 14
|
||||||
|
|
||||||
vu32 newest_save_offset = SAVE_A_OFFSET;
|
vu32 newest_save_offset = SAVE_A_OFFSET;
|
||||||
|
|
||||||
vu32 memory_section_array[READ_SAVE_SECTIONS] = {};
|
vu32 memory_section_array[READ_SAVE_SECTIONS];
|
||||||
u8 global_memory_buffer[0x1000];
|
u8 global_memory_buffer[0x1000];
|
||||||
char mem_name = 'A';
|
|
||||||
u8 mem_id;
|
u8 mem_id;
|
||||||
|
|
||||||
// Fills the variables with the current offset information
|
// Fills the variables with the current offset information
|
||||||
void initalize_memory_locations()
|
void initialize_memory_locations()
|
||||||
{
|
{
|
||||||
u8 save_A_index[4];
|
u8 save_A_index[4];
|
||||||
u8 save_B_index[4];
|
u8 save_B_index[4];
|
||||||
|
|
@ -31,10 +29,12 @@ void initalize_memory_locations()
|
||||||
if (*(vu32 *)save_B_index > *(vu32 *)save_A_index)
|
if (*(vu32 *)save_B_index > *(vu32 *)save_A_index)
|
||||||
{
|
{
|
||||||
newest_save_offset = SAVE_B_OFFSET;
|
newest_save_offset = SAVE_B_OFFSET;
|
||||||
mem_name = 'B';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populates the memory_section_array with the correct pointer locations
|
// Populates the memory_section_array with the correct pointer locations
|
||||||
|
// The sections within the save slot are rotated on every save. So it doesn't
|
||||||
|
// start at the first section. However, the next sections follow sequentially.
|
||||||
|
// https://bulbapedia.bulbagarden.net/wiki/Save_data_structure_(Generation_III)#Section_ID
|
||||||
copy_save_to_ram(newest_save_offset + SECTION_ID_OFFSET, &mem_id, 1);
|
copy_save_to_ram(newest_save_offset + SECTION_ID_OFFSET, &mem_id, 1);
|
||||||
for (int i = 0; i < TOTAL_SAVE_SECTIONS; i++)
|
for (int i = 0; i < TOTAL_SAVE_SECTIONS; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -99,6 +99,7 @@ void print_mem_section()
|
||||||
/*
|
/*
|
||||||
uint16_t charset[256];
|
uint16_t charset[256];
|
||||||
byte out[4] = {0, 0, 0, 0xFF};
|
byte out[4] = {0, 0, 0, 0xFF};
|
||||||
|
const char mem_name = (newest_save_offset == SAVE_A_OFFSET) ? 'A' : 'B';
|
||||||
|
|
||||||
load_localized_charset(charset, 3, ENGLISH);
|
load_localized_charset(charset, 3, ENGLISH);
|
||||||
|
|
||||||
|
|
@ -124,33 +125,28 @@ void reverse_endian(u8 *data, size_t size)
|
||||||
|
|
||||||
void update_memory_buffer_checksum(bool hall_of_fame)
|
void update_memory_buffer_checksum(bool hall_of_fame)
|
||||||
{
|
{
|
||||||
vu32 checksum = 0x00;
|
u32 checksum = 0x00;
|
||||||
|
|
||||||
vu32 num_of_bytes = 3968;
|
// Section 13 is the last PC buffer (I) and that one only has 2000 bytes of data.
|
||||||
if (global_memory_buffer[0x0FF4] == 13)
|
// source: https://bulbapedia.bulbagarden.net/wiki/Save_data_structure_(Generation_III)#Section_ID
|
||||||
|
const u32 num_of_bytes = (global_memory_buffer[SECTION_ID_OFFSET] != 13) ? 3968 : 2000;
|
||||||
|
|
||||||
|
// the cpu is little endian and the data is read as little endian too.
|
||||||
|
// therefore, we can do a straightforward sum of the data as u32's.
|
||||||
|
const u32 *cur = (const u32 *)global_memory_buffer;
|
||||||
|
const u32 * const end = (const u32 *)(global_memory_buffer + num_of_bytes);
|
||||||
|
while (cur < end)
|
||||||
{
|
{
|
||||||
num_of_bytes = 2000;
|
checksum += *cur;
|
||||||
|
++cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < num_of_bytes / 4; i++)
|
const u16 small_checksum = ((checksum & 0xFFFF0000) >> 16) + (checksum & 0x0000FFFF);
|
||||||
{
|
const u32 checksum_offset = hall_of_fame ? 0x0FF4 : 0x0FF6;
|
||||||
checksum += (global_memory_buffer[(4 * i) + 3] << 24) |
|
|
||||||
(global_memory_buffer[(4 * i) + 2] << 16) |
|
global_memory_buffer[checksum_offset] = small_checksum & 0x00FF;
|
||||||
(global_memory_buffer[(4 * i) + 1] << 8) |
|
global_memory_buffer[checksum_offset + 1] = (small_checksum & 0xFF00) >> 8;
|
||||||
(global_memory_buffer[(4 * i) + 0] << 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vu16 small_checksum = ((checksum & 0xFFFF0000) >> 16) + (checksum & 0x0000FFFF);
|
|
||||||
if (hall_of_fame)
|
|
||||||
{
|
|
||||||
global_memory_buffer[0x0FF4] = small_checksum & 0x00FF;
|
|
||||||
global_memory_buffer[0x0FF5] = (small_checksum & 0xFF00) >> 8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
global_memory_buffer[0x0FF6] = small_checksum & 0x00FF;
|
|
||||||
global_memory_buffer[0x0FF7] = (small_checksum & 0xFF00) >> 8;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_flag(u16 flag_id)
|
bool read_flag(u16 flag_id)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#include "pokedex.h"
|
#include "pokedex.h"
|
||||||
#include "global_frame_controller.h"
|
#include "global_frame_controller.h"
|
||||||
#include "pkmn_font.h"
|
#include "pkmn_font.h"
|
||||||
#include "save_data_manager.h"
|
#include "ptgb_save_data_manager.h"
|
||||||
#include "mystery_gift_injector.h"
|
#include "mystery_gift_injector.h"
|
||||||
#include "mystery_gift_builder.h"
|
#include "mystery_gift_builder.h"
|
||||||
#include "multiboot_upload.h"
|
#include "multiboot_upload.h"
|
||||||
|
|
@ -72,9 +72,9 @@ void load_graphics()
|
||||||
yes_no_menu.add_button(Button(button_no), false);
|
yes_no_menu.add_button(Button(button_no), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initalization_script(void)
|
void initialization_script(void)
|
||||||
{
|
{
|
||||||
// Initalizations
|
// Initializations
|
||||||
REG_DISPCNT = DCNT_BLANK | DCNT_MODE0 | DCNT_BG0 | DCNT_BG1 | DCNT_BG2 | DCNT_BG3 | DCNT_OBJ | DCNT_OBJ_1D;
|
REG_DISPCNT = DCNT_BLANK | DCNT_MODE0 | DCNT_BG0 | DCNT_BG1 | DCNT_BG2 | DCNT_BG3 | DCNT_OBJ | DCNT_OBJ_1D;
|
||||||
|
|
||||||
// Disable for save data read/write
|
// Disable for save data read/write
|
||||||
|
|
@ -452,7 +452,7 @@ static void __attribute__((noinline)) show_intro()
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
malloc_init_default_pool();
|
malloc_init_default_pool();
|
||||||
initalization_script();
|
initialization_script();
|
||||||
|
|
||||||
// Set colors based on current ROM
|
// Set colors based on current ROM
|
||||||
set_background_pal(0, false, false);
|
set_background_pal(0, false, false);
|
||||||
|
|
@ -482,15 +482,15 @@ int main(void)
|
||||||
obj_hide_multi(ptgb_logo_l, 2);
|
obj_hide_multi(ptgb_logo_l, 2);
|
||||||
global_next_frame();
|
global_next_frame();
|
||||||
game_load_error();
|
game_load_error();
|
||||||
// initalization_script();
|
// initialization_script();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initalize memory and save data after loading the game
|
// Initialize memory and save data after loading the game
|
||||||
reset_textbox();
|
reset_textbox();
|
||||||
REG_BG2CNT = REG_BG2CNT | BG_PRIO(3);
|
REG_BG2CNT = REG_BG2CNT | BG_PRIO(3);
|
||||||
init_bank();
|
init_bank();
|
||||||
initalize_memory_locations();
|
initialize_memory_locations();
|
||||||
load_custom_save_data();
|
load_custom_save_data();
|
||||||
|
|
||||||
set_background_pal(curr_GBA_rom.gamecode, false, true);
|
set_background_pal(curr_GBA_rom.gamecode, false, true);
|
||||||
|
|
@ -499,7 +499,7 @@ int main(void)
|
||||||
{
|
{
|
||||||
obj_hide_multi(ptgb_logo_l, 2);
|
obj_hide_multi(ptgb_logo_l, 2);
|
||||||
text_loop(BTN_TRANSFER);
|
text_loop(BTN_TRANSFER);
|
||||||
initalize_save_data();
|
initialize_save_data();
|
||||||
// TODO: We should be able to test for a Bootleg rom in here- if the save data isn't written, then it is bootleg.
|
// TODO: We should be able to test for a Bootleg rom in here- if the save data isn't written, then it is bootleg.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include "sprite_data.h"
|
#include "sprite_data.h"
|
||||||
#include "pokemon_data.h"
|
#include "pokemon_data.h"
|
||||||
#include "global_frame_controller.h"
|
#include "global_frame_controller.h"
|
||||||
#include "save_data_manager.h"
|
#include "ptgb_save_data_manager.h"
|
||||||
#include "button_handler.h"
|
#include "button_handler.h"
|
||||||
#include "translated_text.h"
|
#include "translated_text.h"
|
||||||
#include "text_engine.h"
|
#include "text_engine.h"
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
#include "gb_gen1_payloads_RB_lz10_bin.h"
|
#include "gb_gen1_payloads_RB_lz10_bin.h"
|
||||||
#include "gb_gen1_payloads_Y_lz10_bin.h"
|
#include "gb_gen1_payloads_Y_lz10_bin.h"
|
||||||
#include "gb_gen2_payloads_lz10_bin.h"
|
#include "gb_gen2_payloads_lz10_bin.h"
|
||||||
#include "save_data_manager.h"
|
#include "ptgb_save_data_manager.h"
|
||||||
#include "libraries/Pokemon-Gen3-to-Gen-X/include/save.h"
|
#include "libraries/Pokemon-Gen3-to-Gen-X/include/save.h"
|
||||||
|
|
||||||
static byte gen1_rb_debug_box_data[0x462] = {
|
static byte gen1_rb_debug_box_data[0x462] = {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include <tonc.h>
|
#include <tonc.h>
|
||||||
#include "save_data_manager.h"
|
#include "ptgb_save_data_manager.h"
|
||||||
#include "flash_mem.h"
|
#include "flash_mem.h"
|
||||||
#include "debug_mode.h"
|
#include "debug_mode.h"
|
||||||
#include "button_menu.h"
|
#include "button_menu.h"
|
||||||
|
|
@ -11,19 +11,14 @@ byte save_data_array[SAVE_DATA_SIZE];
|
||||||
void load_custom_save_data()
|
void load_custom_save_data()
|
||||||
{
|
{
|
||||||
copy_save_to_ram(HALL_OF_FAME + 0x1000, &global_memory_buffer[0], 0x1000);
|
copy_save_to_ram(HALL_OF_FAME + 0x1000, &global_memory_buffer[0], 0x1000);
|
||||||
for (int i = 0; i < SAVE_DATA_SIZE; i++)
|
memcpy(save_data_array, global_memory_buffer + HOF_SECTION, SAVE_DATA_SIZE);
|
||||||
{
|
|
||||||
save_data_array[i] = global_memory_buffer[HOF_SECTION + i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_custom_save_data()
|
void write_custom_save_data()
|
||||||
{
|
{
|
||||||
copy_save_to_ram(HALL_OF_FAME + 0x1000, &global_memory_buffer[0], 0x1000);
|
copy_save_to_ram(HALL_OF_FAME + 0x1000, &global_memory_buffer[0], 0x1000);
|
||||||
for (int i = 0; i < SAVE_DATA_SIZE; i++)
|
memcpy(global_memory_buffer + HOF_SECTION, save_data_array, SAVE_DATA_SIZE);
|
||||||
{
|
|
||||||
global_memory_buffer[HOF_SECTION + i] = save_data_array[i];
|
|
||||||
}
|
|
||||||
update_memory_buffer_checksum(true);
|
update_memory_buffer_checksum(true);
|
||||||
erase_sector(HALL_OF_FAME + 0x1000);
|
erase_sector(HALL_OF_FAME + 0x1000);
|
||||||
copy_ram_to_save(&global_memory_buffer[0], HALL_OF_FAME + 0x1000, 0x1000);
|
copy_ram_to_save(&global_memory_buffer[0], HALL_OF_FAME + 0x1000, 0x1000);
|
||||||
|
|
@ -59,12 +54,9 @@ bool get_tutorial_flag()
|
||||||
return save_data_array[TUTORIAL_FLAG];
|
return save_data_array[TUTORIAL_FLAG];
|
||||||
}
|
}
|
||||||
|
|
||||||
void initalize_save_data()
|
void initialize_save_data()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < SAVE_DATA_SIZE; i++)
|
memset(save_data_array, 0, SAVE_DATA_SIZE);
|
||||||
{
|
|
||||||
save_data_array[i] = 0;
|
|
||||||
}
|
|
||||||
set_tutorial_flag(true);
|
set_tutorial_flag(true);
|
||||||
write_custom_save_data();
|
write_custom_save_data();
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#include "pokemon_party.h"
|
#include "pokemon_party.h"
|
||||||
#include "pokemon_data.h"
|
#include "pokemon_data.h"
|
||||||
#include "text_engine.h"
|
#include "text_engine.h"
|
||||||
#include "save_data_manager.h"
|
#include "ptgb_save_data_manager.h"
|
||||||
#include "gba_rom_values/gba_rom_values.h"
|
#include "gba_rom_values/gba_rom_values.h"
|
||||||
#include "libraries/nanoprintf/nanoprintf.h"
|
#include "libraries/nanoprintf/nanoprintf.h"
|
||||||
#include "gba_rom_values_eng_lz10_bin.h"
|
#include "gba_rom_values_eng_lz10_bin.h"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user