mirror of
https://github.com/risingPhil/libpokemegb.git
synced 2026-03-21 17:44:24 -05:00
Fix bug: Japanese saves were not detected correctly for gen I
This commit is contained in:
parent
3d86aa80f5
commit
99b2e41f42
|
|
@ -22,7 +22,7 @@
|
|||
* Yes, I'm aware this is a bit unclean, but once the relevant rom offsets are found once, you don't typically need this tool anymore.
|
||||
* Still, I'm leaving this application in the codebase in case I need more rom offsets later (or in case Korean localization support would get implemented at some point)
|
||||
*/
|
||||
static const Gen1LocalizationLanguage g1_localization = Gen1LocalizationLanguage::ENGLISH;
|
||||
static const Gen1LocalizationLanguage g1_localization = Gen1LocalizationLanguage::JAPANESE;
|
||||
static const Gen2LocalizationLanguage g2_localization = Gen2LocalizationLanguage::ENGLISH;
|
||||
|
||||
static uint32_t findBinaryPattern(uint8_t* buffer, size_t bufferSize, uint8_t* pattern, size_t patternSize)
|
||||
|
|
@ -138,7 +138,7 @@ static void processGen1(Gen1GameType gameType, uint8_t* romBuffer, uint8_t* loca
|
|||
findBinaryPattern(localizedRomBuffer, localizedRomBufferSize, romBuffer + eng.numbers, 11);
|
||||
|
||||
// WARNING: Modify this variable with the localized name of the pokémon we're trying to look up. (RHYDON, because it's index 1)
|
||||
const char* pokeNames[] = {"RHYDON"};
|
||||
const char* pokeNames[] = {"サイドン"};
|
||||
printf("Names: 0x%08x\n", findNames(localizedRomBuffer, localizedRomBufferSize, pokeNames, 1, 1));
|
||||
printf("IconTypes:\n");
|
||||
findBinaryPattern(localizedRomBuffer, localizedRomBufferSize, romBuffer + eng.iconTypes, 11);
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@
|
|||
/**
|
||||
* @brief This function calculates the main data checksum
|
||||
*/
|
||||
uint8_t calculateMainDataChecksum(ISaveManager& saveManager)
|
||||
uint8_t calculateMainDataChecksum(ISaveManager& saveManager, uint8_t localization)
|
||||
{
|
||||
Gen1Checksum checksum;
|
||||
const uint16_t checksummedDataStart = 0x598;
|
||||
const uint16_t checksummedDataEnd = 0x1523;
|
||||
const uint16_t checksummedDataEnd = (localization != (uint8_t)Gen1LocalizationLanguage::JAPANESE) ? 0x1523: 0x1594;
|
||||
const uint16_t numBytes = checksummedDataEnd - checksummedDataStart;
|
||||
uint16_t i;
|
||||
uint8_t byte;
|
||||
|
|
@ -322,7 +322,9 @@ const char *Gen1GameReader::getRivalName() const
|
|||
{
|
||||
static char result[20];
|
||||
uint8_t encodedRivalName[0xB];
|
||||
saveManager_.seek(0x25F6);
|
||||
const uint16_t savOffset = (localization_ != (uint8_t)Gen1LocalizationLanguage::JAPANESE) ? 0x25F6 : 0x25F1;
|
||||
|
||||
saveManager_.seek(savOffset);
|
||||
|
||||
saveManager_.readUntil(encodedRivalName, 0x50, sizeof(encodedRivalName));
|
||||
gen1_decodePokeText(encodedRivalName, sizeof(encodedRivalName), result, sizeof(result), (Gen1LocalizationLanguage)localization_);
|
||||
|
|
@ -332,8 +334,8 @@ const char *Gen1GameReader::getRivalName() const
|
|||
uint16_t Gen1GameReader::getTrainerID() const
|
||||
{
|
||||
uint16_t result;
|
||||
|
||||
saveManager_.seek(0x2605);
|
||||
const uint16_t savOffset = (localization_ != (uint8_t)Gen1LocalizationLanguage::JAPANESE) ? 0x2605 : 0x25FB;
|
||||
saveManager_.seek(savOffset);
|
||||
saveManager_.readUint16(result);
|
||||
|
||||
return result;
|
||||
|
|
@ -352,8 +354,9 @@ Gen1Box Gen1GameReader::getBox(uint8_t boxIndex)
|
|||
uint8_t Gen1GameReader::getCurrentBoxIndex()
|
||||
{
|
||||
uint8_t byte;
|
||||
const uint16_t savOffset = (localization_ != (uint8_t)Gen1LocalizationLanguage::JAPANESE) ? 0x284C : 0x2842;
|
||||
|
||||
saveManager_.seek(0x284C);
|
||||
saveManager_.seek(savOffset);
|
||||
saveManager_.readByte(byte);
|
||||
|
||||
return byte & 0x3F;
|
||||
|
|
@ -361,8 +364,18 @@ uint8_t Gen1GameReader::getCurrentBoxIndex()
|
|||
|
||||
bool Gen1GameReader::getPokedexFlag(PokedexFlag dexFlag, uint8_t pokedexNumber) const
|
||||
{
|
||||
const uint16_t saveOffset = (dexFlag == POKEDEX_SEEN) ? 0x25B6 : 0x25A3;
|
||||
uint16_t saveOffset;
|
||||
uint8_t byte;
|
||||
|
||||
if(localization_ != (uint8_t)Gen1LocalizationLanguage::JAPANESE)
|
||||
{
|
||||
saveOffset = (dexFlag == POKEDEX_SEEN) ? 0x25B6 : 0x25A3;
|
||||
}
|
||||
else
|
||||
{
|
||||
saveOffset = (dexFlag == POKEDEX_SEEN) ? 0x25B1 : 0x259E;
|
||||
}
|
||||
|
||||
if(pokedexNumber < 1 || pokedexNumber > 151)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -380,8 +393,18 @@ bool Gen1GameReader::getPokedexFlag(PokedexFlag dexFlag, uint8_t pokedexNumber)
|
|||
|
||||
void Gen1GameReader::setPokedexFlag(PokedexFlag dexFlag, uint8_t pokedexNumber) const
|
||||
{
|
||||
const uint16_t saveOffset = (dexFlag == POKEDEX_SEEN) ? 0x25B6 : 0x25A3;
|
||||
uint16_t saveOffset;
|
||||
uint8_t byte;
|
||||
|
||||
if(localization_ != (uint8_t)Gen1LocalizationLanguage::JAPANESE)
|
||||
{
|
||||
saveOffset = (dexFlag == POKEDEX_SEEN) ? 0x25B6 : 0x25A3;
|
||||
}
|
||||
else
|
||||
{
|
||||
saveOffset = (dexFlag == POKEDEX_SEEN) ? 0x25B1 : 0x259E;
|
||||
}
|
||||
|
||||
if(pokedexNumber < 1 || pokedexNumber > 151)
|
||||
{
|
||||
return;
|
||||
|
|
@ -400,10 +423,19 @@ void Gen1GameReader::setPokedexFlag(PokedexFlag dexFlag, uint8_t pokedexNumber)
|
|||
|
||||
uint8_t Gen1GameReader::getPokedexCounter(PokedexFlag dexFlag) const
|
||||
{
|
||||
const uint16_t saveOffset = (dexFlag == POKEDEX_SEEN) ? 0x25B6 : 0x25A3;
|
||||
uint16_t saveOffset;
|
||||
uint8_t bytes[19];
|
||||
uint8_t result = 0;
|
||||
|
||||
if(localization_ != (uint8_t)Gen1LocalizationLanguage::JAPANESE)
|
||||
{
|
||||
saveOffset = (dexFlag == POKEDEX_SEEN) ? 0x25B6 : 0x25A3;
|
||||
}
|
||||
else
|
||||
{
|
||||
saveOffset = (dexFlag == POKEDEX_SEEN) ? 0x25B1 : 0x259E;
|
||||
}
|
||||
|
||||
saveManager_.seek(saveOffset);
|
||||
saveManager_.read(bytes, sizeof(bytes));
|
||||
|
||||
|
|
@ -500,22 +532,22 @@ uint8_t Gen1GameReader::addDistributionPokemon(const Gen1DistributionPokemon& di
|
|||
|
||||
bool Gen1GameReader::isMainChecksumValid()
|
||||
{
|
||||
const uint16_t mainDataChecksumOffset = 0x3523;
|
||||
const uint16_t mainDataChecksumOffset = (localization_ != (uint8_t)Gen1LocalizationLanguage::JAPANESE) ? 0x3523 : 0x3594;
|
||||
uint8_t storedChecksum;
|
||||
uint8_t calculatedChecksum;
|
||||
|
||||
saveManager_.seek(mainDataChecksumOffset);
|
||||
saveManager_.readByte(storedChecksum);
|
||||
|
||||
calculatedChecksum = calculateMainDataChecksum(saveManager_);
|
||||
calculatedChecksum = calculateMainDataChecksum(saveManager_, localization_);
|
||||
|
||||
return (storedChecksum == calculatedChecksum);
|
||||
}
|
||||
|
||||
void Gen1GameReader::updateMainChecksum()
|
||||
{
|
||||
const uint16_t mainDataChecksumOffset = 0x3523;
|
||||
const uint8_t calculatedChecksum = calculateMainDataChecksum(saveManager_);
|
||||
const uint16_t mainDataChecksumOffset = (localization_ != (uint8_t)Gen1LocalizationLanguage::JAPANESE) ? 0x3523 : 0x3594;
|
||||
const uint8_t calculatedChecksum = calculateMainDataChecksum(saveManager_, localization_);
|
||||
|
||||
saveManager_.seek(mainDataChecksumOffset);
|
||||
saveManager_.writeByte(calculatedChecksum);
|
||||
|
|
|
|||
|
|
@ -58,14 +58,14 @@ static const Gen1LocalizationRomOffsets g1_localizationOffsetsRB[] = {
|
|||
},
|
||||
// Japanese
|
||||
{
|
||||
.stats = 0x383DE,
|
||||
.statsMew = 0x425B,
|
||||
.numbers = 0x42784,
|
||||
.names = 0x39446,
|
||||
.iconTypes = 0x71DC1,
|
||||
.icons = 0x71C74,
|
||||
.paletteIndices = 0x72A0E,
|
||||
.palettes = 0x72AA5
|
||||
.stats = 0x38000,
|
||||
.statsMew = 0x4200,
|
||||
.numbers = 0x4279A,
|
||||
.names = 0x39068,
|
||||
.iconTypes = 0x71DD1,
|
||||
.icons = 0x71C84,
|
||||
.paletteIndices = 0x72A1F,
|
||||
.palettes = 0x72AB6
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,18 +25,20 @@ static const uint8_t OT_NAME_SIZE = 0xB;
|
|||
* @brief This function will load the metadata of the trainer party into the specified outPartyMeta variable.
|
||||
* Note that it won't contain the detailed data about the pokemon in the party.
|
||||
*/
|
||||
static bool getPartyMetadata(ISaveManager& saveManager, Gen1TrainerPartyMeta &outPartyMeta)
|
||||
static bool getPartyMetadata(ISaveManager& saveManager, Gen1TrainerPartyMeta &outPartyMeta, Gen1LocalizationLanguage localization)
|
||||
{
|
||||
saveManager.seek(0x2F2C);
|
||||
const uint16_t savOffset = (localization != Gen1LocalizationLanguage::JAPANESE) ? 0x2F2C : 0x2ED5;
|
||||
saveManager.seek(savOffset);
|
||||
saveManager.readByte(outPartyMeta.number_of_pokemon);
|
||||
saveManager.read(outPartyMeta.species_index_list, 6);
|
||||
outPartyMeta.species_index_list[6] = 0xFF;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void writePartyMetadata(ISaveManager& saveManager, Gen1TrainerPartyMeta& partyMeta)
|
||||
static void writePartyMetadata(ISaveManager& saveManager, Gen1TrainerPartyMeta& partyMeta, Gen1LocalizationLanguage localization)
|
||||
{
|
||||
saveManager.seek(0x2F2C);
|
||||
const uint16_t savOffset = (localization != Gen1LocalizationLanguage::JAPANESE) ? 0x2F2C : 0x2ED5;
|
||||
saveManager.seek(savOffset);
|
||||
saveManager.writeByte(partyMeta.number_of_pokemon);
|
||||
saveManager.write(partyMeta.species_index_list, 6);
|
||||
saveManager.writeByte(0xFF);
|
||||
|
|
@ -202,7 +204,7 @@ Gen1Party::~Gen1Party()
|
|||
uint8_t Gen1Party::getSpeciesAtIndex(uint8_t partyIndex)
|
||||
{
|
||||
Gen1TrainerPartyMeta partyMeta;
|
||||
getPartyMetadata(saveManager_, partyMeta);
|
||||
getPartyMetadata(saveManager_, partyMeta, localization_);
|
||||
|
||||
if(partyIndex >= partyMeta.number_of_pokemon)
|
||||
{
|
||||
|
|
@ -247,7 +249,7 @@ bool Gen1Party::setPokemon(uint8_t partyIndex, Gen1TrainerPokemon& poke)
|
|||
const uint8_t PARTY_POKEMON_NUM_BYTES = 44;
|
||||
const uint8_t FIRST_POKE_STRUCT_OFFSET = 8;
|
||||
Gen1TrainerPartyMeta partyMeta;
|
||||
getPartyMetadata(saveManager_, partyMeta);
|
||||
getPartyMetadata(saveManager_, partyMeta, localization_);
|
||||
|
||||
if(partyIndex >= partyMeta.number_of_pokemon)
|
||||
{
|
||||
|
|
@ -263,7 +265,7 @@ bool Gen1Party::setPokemon(uint8_t partyIndex, Gen1TrainerPokemon& poke)
|
|||
partyMeta.species_index_list[partyMeta.number_of_pokemon] = 0xFF;
|
||||
}
|
||||
|
||||
writePartyMetadata(saveManager_, partyMeta);
|
||||
writePartyMetadata(saveManager_, partyMeta, localization_);
|
||||
|
||||
// make sure the stat fields are filled in by recalculating them.
|
||||
// this is the same as what happens when withdrawing them from an ingame PC box
|
||||
|
|
@ -289,7 +291,7 @@ bool Gen1Party::setPokemon(uint8_t partyIndex, Gen1TrainerPokemon& poke)
|
|||
uint8_t Gen1Party::getNumberOfPokemon()
|
||||
{
|
||||
Gen1TrainerPartyMeta partyMeta;
|
||||
if(!getPartyMetadata(saveManager_, partyMeta))
|
||||
if(!getPartyMetadata(saveManager_, partyMeta, localization_))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -360,7 +362,7 @@ void Gen1Party::setOriginalTrainerOfPokemon(uint8_t partyIndex, const char* orig
|
|||
bool Gen1Party::add(Gen1TrainerPokemon& poke, const char* originalTrainerID, const char* nickname)
|
||||
{
|
||||
Gen1TrainerPartyMeta partyMeta;
|
||||
getPartyMetadata(saveManager_, partyMeta);
|
||||
getPartyMetadata(saveManager_, partyMeta, localization_);
|
||||
const uint8_t partyIndex = partyMeta.number_of_pokemon;
|
||||
|
||||
if(partyIndex >= getMaxNumberOfPokemon())
|
||||
|
|
@ -376,7 +378,7 @@ bool Gen1Party::add(Gen1TrainerPokemon& poke, const char* originalTrainerID, con
|
|||
partyMeta.species_index_list[partyMeta.number_of_pokemon] = 0xFF;
|
||||
}
|
||||
|
||||
writePartyMetadata(saveManager_, partyMeta);
|
||||
writePartyMetadata(saveManager_, partyMeta, localization_);
|
||||
if(!setPokemon(partyIndex, poke))
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user