Poke_Transporter_GB/source/rom_data.cpp
2026-03-18 22:55:38 -04:00

193 lines
6.4 KiB
C++

#include "rom_data.h"
#include "mystery_gift_builder.h"
#include "pokemon_party.h"
#include "pokemon_data.h"
#include "text_engine.h"
#include "ptgb_save_data_manager.h"
#include "gba_rom_values/gba_rom_values.h"
#include "libraries/nanoprintf/nanoprintf.h"
#include "gba_rom_values_eng_lz10_bin.h"
#include "gba_rom_values_fre_lz10_bin.h"
#include "gba_rom_values_ger_lz10_bin.h"
#include "gba_rom_values_ita_lz10_bin.h"
#include "gba_rom_values_jpn_lz10_bin.h"
#include "gba_rom_values_spa_lz10_bin.h"
extern rom_data curr_GBA_rom;
rom_data::rom_data() {}
bool rom_data::load_rom(bool debug)
{
u8 rom_list_buffer[2048];
u32 rom_list_size;
const u8 *compressed_rom_list;
const u8 *cur;
if (debug)
{
gamecode = DEBUG_GAME;
version = DEBUG_VERS;
language = DEBUG_LANG;
}
else
{
gamecode = (*(vu8 *)(0x80000AC)) << 0x10 |
(*(vu8 *)(0x80000AD)) << 0x08 |
(*(vu8 *)(0x80000AE)) << 0x00;
language = (*(vu8 *)(0x80000AF));
version = (*(vu8 *)(0x80000BC));
}
switch (language)
{
case LANG_JPN:
compressed_rom_list = gba_rom_values_jpn_lz10_bin;
break;
case LANG_ENG:
compressed_rom_list = gba_rom_values_eng_lz10_bin;
break;
case LANG_FRE:
compressed_rom_list = gba_rom_values_fre_lz10_bin;
break;
case LANG_GER:
compressed_rom_list = gba_rom_values_ger_lz10_bin;
break;
case LANG_ITA:
compressed_rom_list = gba_rom_values_ita_lz10_bin;
break;
case LANG_SPA:
compressed_rom_list = gba_rom_values_spa_lz10_bin;
break;
default:
return false; // Unsupported language
}
// Game looks good, let's make sure it can save.
/*if (!check_can_save())
{
return false;
}*/
// byte 2-4 of the compressed data store the decompressed size
rom_list_size = compressed_rom_list[1] | (compressed_rom_list[2] << 8) | (compressed_rom_list[3] << 16);
LZ77UnCompWram(compressed_rom_list, rom_list_buffer);
cur = rom_list_buffer;
while (cur < rom_list_buffer + rom_list_size)
{
const ROM_DATA *rom_values = reinterpret_cast<const ROM_DATA *>(cur);
if (rom_values->is_valid && rom_values->gamecode == gamecode &&
rom_values->version == version)
{
fill_values(rom_values);
rom_loaded = true;
return true;
}
cur += sizeof(ROM_DATA);
}
// If we reach here, no matching ROM_DATA was found
return false;
}
void rom_data::fill_values(const ROM_DATA *rom_values)
{
loc_sendMonToPC = rom_values->loc_copyMonToPC;
loc_gSpecialVar_0x8000 = rom_values->loc_gSpecialVar_0x8000;
loc_gSaveBlock1 = rom_values->loc_gSaveBlock1;
loc_setPokedexFlag = rom_values->loc_getSetPokedexFlag;
loc_gSaveDataBuffer = rom_values->loc_gSaveDataBuffer;
loc_readFlashSector = rom_values->loc_readFlashSector;
loc_loadSaveSection30 = rom_values->loc_loadSaveSection30;
loc_m4aMPlayStop = rom_values->loc_m4aMPlayStop;
loc_gMPlayInfo_BGM = rom_values->loc_gMPlayInfo_BGM;
loc_gMPlayInfo_SE2 = rom_values->loc_gMPlayInfo_SE2;
loc_MPlayStart = rom_values->loc_MPlayStart;
loc_CreateFanfareTask = rom_values->loc_CreateFanfareTask;
loc_sFanfareCounter = rom_values->loc_sFanfareCounter;
loc_gPlttBufferFaded = rom_values->loc_gPlttBufferFaded;
loc_gSprites = rom_values->loc_gSprites;
loc_voicegroup = rom_values->loc_voicegroup;
loc_sPicTable_NPC = rom_values->loc_sPicTable_NPC;
loc_gMonFrontPicTable = rom_values->loc_gMonFrontPicTable;
loc_gMonPaletteTable = rom_values->loc_gMonPaletteTable;
loc_gMonShinyPaletteTable = rom_values->loc_gMonShinyPaletteTable;
loc_gMonIconTable = rom_values->loc_gMonIconTable;
loc_gMonIconPaletteIndices = rom_values->loc_gMonIconPaletteIndices;
loc_gMonIconPalettes = rom_values->loc_gMonIconPalettes;
offset_ramscript = rom_values->offset_ramscript;
offset_flags = rom_values->offset_flags;
offset_wondercard = rom_values->offset_wondercard;
offset_script = rom_values->offset_script;
text_region = rom_values->text_region;
special_DrawWholeMapView = rom_values->special_DrawWholeMapView;
e4_flag = rom_values->e4_flag; // The flag that is set when you become champion. Often listed as "GAME_CLEAR"
mg_flag = rom_values->mg_flag; // The flag that is set when you enable Mystery Gift. Known as "EXDATA_ENABLE" in RS
unused_flag_start = rom_values->unused_flag_start; // The start of the unused flags and must have 31 open flags in a row
all_collected_flag = rom_values->unused_flag_start; // The flag for if everything has been collected
pkmn_collected_flag_start = rom_values->unused_flag_start + 1; // The beginning of the flags for each of the Pokemon
map_bank = rom_values->map_bank;
map_id = rom_values->map_id;
npc_id = rom_values->npc_id;
npc_palette = rom_values->npc_palette;
def_map_bank = rom_values->def_map_bank;
def_map_id = rom_values->def_map_id;
def_npc_id = rom_values->def_npc_id;
loc_gSaveBlock1PTR = rom_values->loc_gSaveBlock1PTR; // TODO: Only used for old script, can be removed later
}
bool rom_data::is_hoenn()
{
return (gamecode == RUBY_ID || gamecode == SAPPHIRE_ID || gamecode == EMERALD_ID);
}
bool rom_data::is_ruby_sapphire()
{
return (gamecode == RUBY_ID || gamecode == SAPPHIRE_ID);
}
void rom_data::print_rom_info()
{
char buffer[64];
char gameTypeChar;
switch (gamecode)
{
case (RUBY_ID):
gameTypeChar = 'R';
break;
case (SAPPHIRE_ID):
gameTypeChar = 'S';
break;
case (FIRERED_ID):
gameTypeChar = 'F';
break;
case (LEAFGREEN_ID):
gameTypeChar = 'L';
break;
case (EMERALD_ID):
gameTypeChar = 'E';
break;
default:
gameTypeChar = '0';
break;
}
npf_snprintf(buffer, sizeof(buffer), "%c-%d-%c", gameTypeChar, version, language);
ptgb_write_simple(reinterpret_cast<const byte *>(buffer), true);
}
bool rom_data::verify_rom()
{
return !rom_loaded ||
g_debug_options.ignore_game_pak ||
((gamecode == ((*(vu8 *)(0x80000AC)) << 0x10 | (*(vu8 *)(0x80000AD)) << 0x08 | (*(vu8 *)(0x80000AE)) << 0x00)) &&
(language == (*(vu8 *)(0x80000AF))) &&
(version == (*(vu8 *)(0x80000BC))));
}