Fixed memory bug
|
Before Width: | Height: | Size: 979 B After Width: | Height: | Size: 975 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
graphics/unused graphics/progress.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef DEBUG_MODE_H
|
||||
#define DEBUG_MODE_H
|
||||
|
||||
#define DEBUG_MODE true
|
||||
#define DEBUG_MODE false
|
||||
#define IGNORE_LINK_CABLE true
|
||||
#define DEBUG_GAME LEAFGREEN_ID
|
||||
#define DEBUG_GAME SAPPHIRE_ID
|
||||
#define DEBUG_VERS VERS_1_1
|
||||
#define DEBUG_LANG LANG_ENG
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@
|
|||
#include "pokemon.h"
|
||||
#include "rom_data.h"
|
||||
|
||||
|
||||
#define MEM_CRAM 0x0E000000 // Cart RAM
|
||||
|
||||
#define SAVE_A_OFFSET 0x00000000 // Offset of Game Save A
|
||||
#define SAVE_B_OFFSET 0x0000E000 // Offset of Game Save B
|
||||
|
||||
|
|
@ -20,6 +17,7 @@ extern u8 global_memory_buffer[0x1000];
|
|||
extern rom_data curr_rom;
|
||||
|
||||
void initalize_memory_locations();
|
||||
void print_mem_section();
|
||||
//bool insert_pokemon(Pokemon party_array[], int num);
|
||||
void reverse_endian(u8 *data, size_t size);
|
||||
void update_memory_buffer_checksum();
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public:
|
|||
bool load_rom();
|
||||
bool is_hoenn();
|
||||
bool is_ruby_sapphire();
|
||||
|
||||
int loc_sendMonToPC;
|
||||
int loc_gSpecialVar_0x8000;
|
||||
int loc_gSaveBlock1; // Only used in R/S
|
||||
|
|
@ -38,6 +39,10 @@ public:
|
|||
int offset_script;
|
||||
int text_region;
|
||||
|
||||
// PKHeX's list of flags is useful for making sure the detection is accurate: https://github.com/kwsch/PKHeX/blob/78a557c3cdaa6f48b42cc96df8ccb4d20b897937/PKHeX.Core/Resources/text/other/flags_rs.txt
|
||||
int e4_flag; // The flag that is set when you become champion. Often listed as "GAME_CLEAR"
|
||||
int mg_flag; // The flag that is set when you enable Mystery Gift. Known as "EXDATA_ENABLE" in RS
|
||||
|
||||
u8 map_bank;
|
||||
u8 map_id;
|
||||
u8 npc_id;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <tonc.h>
|
||||
#include <string>
|
||||
#include "flash_mem.h"
|
||||
#include "gba_flash.h"
|
||||
#include "pokemon.h"
|
||||
|
|
@ -8,31 +9,32 @@
|
|||
#define READ_SAVE_SECTIONS 5
|
||||
#define TOTAL_SAVE_SECTIONS 14
|
||||
|
||||
vu32 newest_save_offset = MEM_CRAM + SAVE_A_OFFSET;
|
||||
vu32 newest_save_offset = SAVE_A_OFFSET;
|
||||
|
||||
vu32 memory_section_array[READ_SAVE_SECTIONS] = {};
|
||||
u8 global_memory_buffer[0x1000];
|
||||
char mem_name = 'A';
|
||||
u8 mem_id;
|
||||
|
||||
// Fills the variables with the current offset information
|
||||
void initalize_memory_locations()
|
||||
{
|
||||
u8 save_A_index[4];
|
||||
u8 save_B_index[4];
|
||||
flash_read(MEM_CRAM + SAVE_A_OFFSET + SAVE_INDEX_OFFSET, &save_A_index[0], 0x04);
|
||||
flash_read(MEM_CRAM + SAVE_B_OFFSET + SAVE_INDEX_OFFSET, &save_B_index[0], 0x04);
|
||||
flash_read(SAVE_A_OFFSET + SAVE_INDEX_OFFSET, &save_A_index[0], 0x04);
|
||||
flash_read(SAVE_B_OFFSET + SAVE_INDEX_OFFSET, &save_B_index[0], 0x04);
|
||||
reverse_endian(&save_A_index[0], 0x04);
|
||||
reverse_endian(&save_B_index[0], 0x04);
|
||||
|
||||
// Determines if save A or B is more recent
|
||||
if (*(vu32 *)save_B_index > *(vu32 *)save_A_index)
|
||||
{
|
||||
newest_save_offset = MEM_CRAM + SAVE_B_OFFSET;
|
||||
newest_save_offset = SAVE_B_OFFSET;
|
||||
mem_name = 'B';
|
||||
}
|
||||
|
||||
// Populates the memory_section_array with the correct pointer locations
|
||||
vu8 mem_id = *(vu8 *)(newest_save_offset + SECTION_ID_OFFSET);
|
||||
flash_read(newest_save_offset + SECTION_ID_OFFSET, &mem_id, 1);
|
||||
for (int i = 0; i < TOTAL_SAVE_SECTIONS; i++)
|
||||
{
|
||||
if (mem_id < READ_SAVE_SECTIONS)
|
||||
|
|
@ -41,6 +43,58 @@ void initalize_memory_locations()
|
|||
}
|
||||
mem_id = (mem_id + 1) % TOTAL_SAVE_SECTIONS;
|
||||
}
|
||||
|
||||
if (false) // This will print out a section of the FLASH mem for debugging purposes
|
||||
{
|
||||
int mem_start = 0xF80;
|
||||
int mem_section = 1;
|
||||
flash_read(memory_section_array[mem_section], &global_memory_buffer[0], 0x1000);
|
||||
tte_set_pos(8, 0);
|
||||
tte_write("loc: ");
|
||||
tte_write(std::to_string(memory_section_array[mem_section] + mem_start).c_str());
|
||||
tte_write("\n");
|
||||
for (int i = mem_start; i < (128 + mem_start); i++)
|
||||
{
|
||||
if (i % 2 == 0){
|
||||
tte_write("#{cx:0xE000}");
|
||||
} else {
|
||||
tte_write("#{cx:0xD000}");
|
||||
}
|
||||
tte_write(std::to_string(global_memory_buffer[i]).c_str());
|
||||
if (i % 8 == 7)
|
||||
{
|
||||
tte_write("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (global_memory_buffer[i] < 10)
|
||||
{
|
||||
tte_write(" ");
|
||||
}
|
||||
else if (global_memory_buffer[i] < 100)
|
||||
{
|
||||
tte_write(" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
tte_write("");
|
||||
}
|
||||
}
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void print_mem_section()
|
||||
{
|
||||
std::string out;
|
||||
out.append(1, mem_name);
|
||||
out += "-";
|
||||
out += std::to_string(mem_id);
|
||||
tte_set_pos(0, 0);
|
||||
tte_write(out.c_str());
|
||||
}
|
||||
|
||||
// Reverses the endian of the given array
|
||||
|
|
@ -138,6 +192,24 @@ void update_memory_buffer_checksum()
|
|||
|
||||
bool read_flag(u16 flag_id)
|
||||
{
|
||||
if (false)
|
||||
{
|
||||
tte_set_pos(0, 0);
|
||||
tte_write("#{cx:0xD000}Attempting to read byte ");
|
||||
tte_write(std::to_string((curr_rom.offset_flags + (flag_id / 8)) % 0xF80).c_str());
|
||||
tte_write(" of memory section ");
|
||||
tte_write(std::to_string(1 + ((curr_rom.offset_flags + (flag_id / 8)) / 0xF80)).c_str());
|
||||
tte_write(" for flag ");
|
||||
tte_write(std::to_string(flag_id).c_str());
|
||||
tte_write(". Flag is ");
|
||||
flash_read(memory_section_array[1 + ((curr_rom.offset_flags + (flag_id / 8)) / 0xF80)], &global_memory_buffer[0], 0x1000);
|
||||
u8 flags = global_memory_buffer[(curr_rom.offset_flags + (flag_id / 8)) % 0xF80];
|
||||
tte_write(std::to_string((flags >> (flag_id % 8)) & 0b1).c_str());
|
||||
while (true)
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
flash_read(memory_section_array[1 + ((curr_rom.offset_flags + (flag_id / 8)) / 0xF80)], &global_memory_buffer[0], 0x1000);
|
||||
u8 flags = global_memory_buffer[(curr_rom.offset_flags + (flag_id / 8)) % 0xF80];
|
||||
return (flags >> (flag_id % 8)) & 0b1;
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ void initalization_script(void)
|
|||
main_menu_btn_init(Button(btn_lang_spa, 608), BTN_SPA);
|
||||
main_menu_btn_init(Button(btn_lang_kor, 640), BTN_KOR);
|
||||
main_menu_btn_init(Button(lang_arrow, 672), LANG_ARROW);
|
||||
|
||||
|
||||
// Prepare dialouge
|
||||
populate_dialogue();
|
||||
populate_script();
|
||||
|
|
@ -166,7 +166,7 @@ void game_load_error(void)
|
|||
REG_BG2VOFS = 0;
|
||||
tte_set_pos(40, 24);
|
||||
tte_set_margins(40, 24, 206, 104);
|
||||
tte_write("The Pok@mon save\nfile was not loaded successfully.\n\nPlease remove and\nreinsert the Game\nPak, and then press the A button.");
|
||||
tte_write("#{cx:0xF000}The Pok@mon save\nfile was not loaded successfully.\n\nPlease remove and\nreinsert the Game\nPak, and then press the A button.");
|
||||
// tte_write(std::to_string(get_gamecode() >> 8).c_str());
|
||||
key_poll();
|
||||
while (!key_hit(KEY_A))
|
||||
|
|
@ -186,9 +186,10 @@ void game_load_error(void)
|
|||
|
||||
void first_load_message(void)
|
||||
{
|
||||
while (key_hit(KEY_A)){}; // Wait until A is no longer being held
|
||||
tte_set_pos(8, 0);
|
||||
tte_set_ink(10);
|
||||
tte_write("#{cx:0x2000}Hello! Thank you for using\nPok@mon Mirror!\n\nJust as a word of caution- \nPok@mon Mirror WILL modify\nyour generation 3 save file.\nThe program is designed to\nnot corrupt anything, but if\nyou do not wish to modify\nyour save file, please turn\noff your Game Boy Advance.\n\nPlease note that Pok@mon\nMirror is still in beta, so\nsave file backups are HIGHLY\nrecommended before using.\nWith that all out of the\nway, please enjoy!\n\n -The Gears of Progress");
|
||||
tte_write("#{cx:0xE000}Hello! Thank you for using\nPok@mon Mirror!\n\nJust as a word of caution- \nPok@mon Mirror WILL modify\nyour generation 3 save file.\nThe program is designed to\nnot corrupt anything, but if\nyou do not wish to modify\nyour save file, please turn\noff your Game Boy Advance.\n\nPlease note that Pok@mon\nMirror is still in beta, so\nsave file backups are HIGHLY\nrecommended before using.\nWith that all out of the\nway, please enjoy!\n\n -The Gears of Progress");
|
||||
while (!key_hit(KEY_A))
|
||||
{
|
||||
key_poll();
|
||||
|
|
@ -222,14 +223,14 @@ int main(void)
|
|||
tte_set_pos(8, 0);
|
||||
tte_write("#{cx:0xE000}\n\nPokemon Mirror was created\nout of love and appreciation\nfor the Pokemon franchise\nwith no profit in mind.\nIt will ALWAYS be free.\n\nPlease support the original developers-\nNintendo and GAME FREAK.\n\nAll Pokemon names, sprites, and music are owned by \nNintendo, Creatures Inc, and\nGAME FREAK Inc.");
|
||||
tte_write("#{cx:0xF000}"); // Set the color to grey
|
||||
while (delay_counter < 2500000)
|
||||
while (delay_counter < (15 * 60))
|
||||
{
|
||||
delay_counter++;
|
||||
rand_next_frame();
|
||||
key_poll();
|
||||
if (key_hit(KEY_A))
|
||||
{
|
||||
delay_counter = 2500000;
|
||||
delay_counter = (15 * 60);
|
||||
}
|
||||
VBlankIntrWait();
|
||||
}
|
||||
|
|
@ -239,14 +240,14 @@ int main(void)
|
|||
tte_erase_rect(0, 0, 240, 160);
|
||||
REG_BG1VOFS = 0;
|
||||
delay_counter = 0;
|
||||
while (delay_counter < 2500000)
|
||||
while (delay_counter < (15 * 60))
|
||||
{
|
||||
delay_counter++;
|
||||
rand_next_frame();
|
||||
key_poll();
|
||||
if (key_hit(KEY_A))
|
||||
{
|
||||
delay_counter = 2500000;
|
||||
delay_counter = (15 * 60);
|
||||
}
|
||||
VBlankIntrWait();
|
||||
}
|
||||
|
|
@ -264,6 +265,9 @@ int main(void)
|
|||
// MAIN LOOP
|
||||
while (1)
|
||||
{
|
||||
if (DEBUG_MODE){
|
||||
print_mem_section();
|
||||
}
|
||||
switch (main_menu_loop())
|
||||
{
|
||||
case (BTN_TRANSFER):
|
||||
|
|
|
|||
|
|
@ -111,6 +111,6 @@ bool Pokemon_Party::get_has_new_pkmn()
|
|||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -36,8 +36,8 @@ bool rom_data::load_rom()
|
|||
case (RUBY_ID):
|
||||
case (SAPPHIRE_ID):
|
||||
|
||||
map_bank = 0;
|
||||
map_id = 10;
|
||||
map_bank = 20;
|
||||
map_id = 2;
|
||||
npc_id = 1;
|
||||
|
||||
def_map_bank = 8;
|
||||
|
|
@ -47,8 +47,11 @@ bool rom_data::load_rom()
|
|||
text_region = TEXT_HOENN;
|
||||
offset_wondercard = 0;
|
||||
offset_script = 0x0810;
|
||||
switch (version)
|
||||
|
||||
e4_flag = 0x800 + 0x04;
|
||||
mg_flag = 0x800 + 0x4C;
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case (VERS_1_0):
|
||||
loc_sendMonToPC = 0x0803D998;
|
||||
|
|
@ -57,7 +60,7 @@ bool rom_data::load_rom()
|
|||
loc_setPokedexFlag = 0x08090D90;
|
||||
offset_ramscript = 0x3690;
|
||||
offset_flags = 0x1220;
|
||||
break;
|
||||
return true;
|
||||
case (VERS_1_1):
|
||||
loc_sendMonToPC = 0x0803D998;
|
||||
loc_gSpecialVar_0x8000 = 0x0202E8C4;
|
||||
|
|
@ -65,7 +68,7 @@ bool rom_data::load_rom()
|
|||
loc_setPokedexFlag = 0x08090DB0;
|
||||
offset_ramscript = 0x3690;
|
||||
offset_flags = 0x1220;
|
||||
break;
|
||||
return true;
|
||||
case (VERS_1_2):
|
||||
loc_sendMonToPC = 0x0803D998;
|
||||
loc_gSpecialVar_0x8000 = 0x0202E8C4;
|
||||
|
|
@ -73,10 +76,9 @@ bool rom_data::load_rom()
|
|||
loc_setPokedexFlag = 0x08090DB0;
|
||||
offset_ramscript = 0x3690;
|
||||
offset_flags = 0x1220;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
||||
break;
|
||||
case (FIRERED_ID):
|
||||
case (LEAFGREEN_ID):
|
||||
|
||||
|
|
@ -91,6 +93,10 @@ bool rom_data::load_rom()
|
|||
text_region = TEXT_KANTO;
|
||||
offset_wondercard = 0x0460;
|
||||
offset_script = 0x079C;
|
||||
|
||||
e4_flag = 0x800 + 0x2C;
|
||||
mg_flag = 0x800 + 0x39;
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case (VERS_1_0):
|
||||
|
|
@ -100,7 +106,7 @@ bool rom_data::load_rom()
|
|||
loc_setPokedexFlag = 0x08088E74;
|
||||
offset_ramscript = 0x361C;
|
||||
offset_flags = 0x0EE0;
|
||||
break;
|
||||
return true;
|
||||
case (VERS_1_1):
|
||||
loc_sendMonToPC = 0x08040BA4;
|
||||
loc_gSpecialVar_0x8000 = 0x020370B8;
|
||||
|
|
@ -108,10 +114,9 @@ bool rom_data::load_rom()
|
|||
loc_setPokedexFlag = 0x08088E5C;
|
||||
offset_ramscript = 0x361C;
|
||||
offset_flags = 0x0EE0;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
||||
break;
|
||||
case (EMERALD_ID):
|
||||
|
||||
map_bank = 20;
|
||||
|
|
@ -126,6 +131,9 @@ bool rom_data::load_rom()
|
|||
offset_wondercard = 0x056C;
|
||||
offset_script = 0x08A8;
|
||||
|
||||
e4_flag = 0x860 + 0x04;
|
||||
mg_flag = 0x860 + 0x7B;
|
||||
|
||||
loc_sendMonToPC = 0x0806B490;
|
||||
loc_gSpecialVar_0x8000 = 0x020375D8;
|
||||
loc_gSaveBlock1PTR = 0x03005D8C;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ void populate_dialogue()
|
|||
dialogue[DIA_NEW_DEX] = "It looks like there's at\nleast one new Pokemon here\nthat isn't in the Dream Dex!|I'll give them something\nextra sweet as a reward for you both.";
|
||||
dialogue[DIA_NO_NEW_DEX] = "It doesn't look like there's\nanything new for your Dream\nDex, but that's okay!|It's important to confirm\nresearch results with\nmultiple tests!";
|
||||
dialogue[DIA_SEND_FRIEND_KANTO] = "I'm going to send these\nPokemon to my friend BILL so\nthat you can pick them up.\nThey live on Route 25!|Did you know they developed the Storage System for the\nKanto region?|My younger sister developed a version of the Storage\nSystem too, so BILL is a\ngood friend of ours!";
|
||||
dialogue[DIA_SEND_FRIEND_HOENN] = "I'm going to send these\nPokemon to my friend LANNETE so\nthat you can pick them up.\nThey live on route 114!|Did you know they developed the Storage System for the\nHoenn region?|My younger sister developed a version of the Storage\nSystem too, so LANNETE is a\ngood friend of ours!";
|
||||
dialogue[DIA_SEND_FRIEND_HOENN] = "I'm going to send these\nPokemon to my friend LANNETE\nso that you can pick them\nup. They live on route 114!|Did you know they developed the Storage System for the\nHoenn region?|My younger sister developed a version of the Storage\nSystem too, so LANNETE is a\ngood friend of ours!";
|
||||
dialogue[DIA_THANK] = "Thank you so much for your\nhelp! Whenever you want to\ntransfer more Pokemon, just\nlet me know!|See you around!";
|
||||
dialogue[DIA_GET_MON] = "Let's get started! Please connect Load the Game Boy Pok@mon game you want to transfer from, and put the Pok@mon you want to transfer into your party. ";
|
||||
dialogue[DIA_MG_OTHER_EVENT] = "Hi Trainer! It looks like\nyou have a different event\ncurrently loaded.|That's no problem, but it\nwill be overwritten if you\ncontinue.|Turn off the system now if\nyou want to experience your\ncurrent event,\nbut otherwise-";
|
||||
|
|
@ -116,12 +116,10 @@ bool run_conditional(int index)
|
|||
return party_data.get_last_error() != COND_ERROR_COLOSSEUM;
|
||||
|
||||
case COND_BEAT_E4:
|
||||
return read_flag(0x800 + 0x39);
|
||||
// Emerald Flag ID 0x860 + 0x1F
|
||||
return read_flag(curr_rom.e4_flag);
|
||||
|
||||
case COND_MG_ENABLED:
|
||||
return read_flag(0x800 + 0x39);
|
||||
// Emerald flag ID (0x860 + 0x7B)
|
||||
return read_flag(curr_rom.mg_flag);
|
||||
|
||||
case COND_TUTORIAL_COMPLETE:
|
||||
return get_tutorial_flag();
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@ void init_text_engine()
|
|||
tte_set_margins(LEFT, TOP, RIGHT, BOTTOM);
|
||||
tte_set_pos(LEFT, TOP);
|
||||
|
||||
pal_bg_bank[14][15]= 0b0000001001111111;
|
||||
pal_bg_bank[15][15]= 0b0001100011100110;
|
||||
pal_bg_bank[13][15] = CLR_WHITE;
|
||||
pal_bg_bank[14][15] = 0b0000001001111111;
|
||||
pal_bg_bank[15][15] = 0b0001100011100110;
|
||||
|
||||
|
||||
// Set default variables
|
||||
|
|
|
|||