libpokemegb/include/gen2/Gen2GameReader.h
risingPhil a44b908587 Implement gen 2 party icon decoding
Now you can also decode the party icons for the gen 2 pokémon games
2024-09-25 20:22:17 +02:00

233 lines
9.3 KiB
C++

#ifndef _GEN2GAMEREADER_H
#define _GEN2GAMEREADER_H
#include "gen2/Gen2SpriteDecoder.h"
#include "gen2/Gen2PlayerPokemonStorage.h"
#include "gen2/Gen2DistributionPokemon.h"
#include "SpriteRenderer.h"
class IRomReader;
class ISaveManager;
// Note: for GEN2 there is no difference between index and pokedex number: the indexes are in national dex order
class Gen2GameReader
{
public:
Gen2GameReader(IRomReader &romReader, ISaveManager &saveManager, Gen2GameType gameType);
~Gen2GameReader();
Gen2GameType getGameType() const;
/**
* @brief get the name of a pokémon based on an index number
* Note: you don't own the returned pointer. The data will get overwritten on the next call to this function,
* so make sure to strdup() it if you need to store it for later
*
* @return const char*
*/
const char *getPokemonName(uint8_t index) const;
/**
* Returns the specific icon type for a given pokémon
*/
Gen2PokemonIconType getPokemonIconType(uint8_t index) const;
/**
* @brief With this function, you can check if the index is valid and not referring to garbage data
*/
bool isValidIndex(uint8_t index) const;
/**
* @brief This function reads the pokemon stats at the given index
*
* @return whether or not this operation was successful
*/
bool readPokemonStatsForIndex(uint8_t index, Gen2PokeStats &outStats) const;
/**
* @brief This function reads the pointer to the front sprite of the pokémon at the given index
*/
bool readFrontSpritePointer(uint8_t index, uint8_t &outBankIndex, uint16_t &outPointer);
/**
* @brief Converts the sprite_dimensions field in Gen2PokeStats into values we can actually use
*/
void readSpriteDimensions(const Gen2PokeStats &poke, uint8_t &outWidthInTiles, uint8_t &outHeightInTiles);
/**
* @brief This function reads a color palette for the given pokemon
* @param index the index of the pokemon
* @param shiny whether or not we need to get the shiny color palette
* @param outColorPalette the output variable in which the color palette will be read. Please make sure this array has a length of 4 items
*/
bool readColorPaletteForPokemon(uint8_t index, bool shiny, uint16_t *outColorPalette);
/**
* @brief This function decodes a sprite at the given bank and pointer.
* Returns a pointer to a buffer containing the decoded gameboy sprite in gameboy sprite format.
* You need to look at the sprite dimension to see how much data there is. ()
*
* WARNING: this function returns a pointer to an internal buffer of the Gen1SpriteDecoder. It will get overwritten on the next call to this function.
* If you want to keep the content around for longer, make a copy of this data.
*/
uint8_t *decodeSprite(uint8_t bankIndex, uint16_t pointer);
/**
* @brief This function decodes the given pokemon icon and returns the internal buffer of the given SpriteRenderer instance
* The size of the returned buffer is 16x16 pixels
*/
uint8_t* decodePokemonIcon(Gen2PokemonIconType iconType, SpriteRenderer& renderer, SpriteRenderer::OutputFormat outputFormat, bool firstFrame = true);
/**
* @brief Adds a pokemon to the save. Tries to add it to the party first. If there's no more room there, it tries to add it to the
* first ingame PC box with open slots.
*
* WARNING: When you're done adding pokemon, make sure to call finishSave() !!! Not doing so will corrupt the save file!
*
* @param isEgg adds the pokemon as an egg
* @param originalTrainerID optional parameter. If not specified (=null), the original trainer id string will be set to the players'
* @param nickname optional parameter. If not specified (= null), the pokemon species name will be used instead.
*
* @return
* 0xFF - Could not add pokemon (probably no space left)
* 0xFE - Added to players' party
* 0x0 - 0xB - Added to box at index <value>
*/
uint8_t addPokemon(Gen2TrainerPokemon &poke, bool isEgg, const char *originalTrainerID = 0, const char *nickname = 0);
/**
* @brief Adds a distribution pokemon to the save. Tries to add it to the party first. If there's no more room there, it tries to add it to the
* first ingame PC box with open slots
*
* WARNING: When you're done adding pokemon, make sure to call finishSave() !!! Not doing so will corrupt the save file!
*
* @param nickname optional parameter. If not specified (= null), the pokemon species name will be used instead.
*
* @return
* 0xFF - Could not add pokemon (probably no space left)
* 0xFE - Added to players' party
* 0x0 - 0xB - Added to box at index <value>
*/
uint8_t addDistributionPokemon(const Gen2DistributionPokemon& distributionPoke, const char *nickname = 0);
/**
* @brief Get the player ID from the save file
*/
uint16_t getTrainerID() const;
/**
* @brief Get the trainer name from the save file
* Note: the resulting const char* does not need to be free'd.
* However, it needs to be either used rightaway or strdup()'d, because the data will get overwritten on the next call to this function.
*/
const char *getTrainerName() const;
/**
* @brief Get the rival name from the save file
* Note: the resulting const char* does not need to be free'd.
* However, it needs to be either used rightaway or strdup()'d, because the data will get overwritten on the next call to this function.
*/
const char *getRivalName() const;
/**
* @brief Returns the 0-based index of the currently selected PC box for pokemon
*/
uint8_t getCurrentBoxIndex();
/**
* @brief Returns a Gen2Party instance, which can be used to retrieve the information about the pokemon currently in the trainers' party
*/
Gen2Party getParty();
/**
* @brief Returns a Gen2Box instance, which can be used to retrieve information about the pokemon currently in the Trainers' PC box at the specified index
*/
Gen2Box getBox(uint8_t boxIndex);
/**
* Returns a Gen2ItemList instance, which can be used to retrieve the items currently in the players' specified inventory type
*/
Gen2ItemList getItemList(Gen2ItemListType type);
/**
* @brief This function returns whether the pokemon with the given pokedexNumber has been SEEN/OWNED.
*/
bool getPokedexFlag(PokedexFlag dexFlag, uint8_t pokedexNumber);
/**
* @brief This function sets the pokedex flag for the given pokedexNumber
*/
void setPokedexFlag(PokedexFlag dexFlag, uint8_t pokedexNumber);
/**
* @brief This function returns the counter value of the given dex flag
*/
uint8_t getPokedexCounter(PokedexFlag dexFlag);
/**
* @brief The save data is stored twice in gen 2. There's a main and a backup region.
* This function returns whether the main regions' checksum is valid.
*/
bool isMainChecksumValid();
/**
* @brief The save data is stored twice in gen 2. There's a main and a backup region.
* This function returns whether the backup regions' checksum is valid.
*/
bool isBackupChecksumValid();
/**
* @brief This function finishes the save file. Make sure to call this at the end after you're done doing changes
* This function will:
* - update the current pc box section of the save
* - update the main checksum
* - copy the main save to the backup save
*/
void finishSave();
/**
* @brief Checks whether we're currently dealing with Pokémon Crystal
*/
bool isGameCrystal() const;
/**
* @brief Unlocks the GS Ball event in Pokemon crystal
* Note: this function is made to be repeatable: it removes an existing GS Ball entry first and resets all the
* GS ball related event flags.
*
* This is for 2 reasons: I screwed up my first versions of PokeMe64: they only gave you the GS Ball item, but didn't
* change any of the event flags. Obviously this has changed now.
*
* Therefore after executing this function, the GS Ball event stats from the beginning again:
* you can get a GS Ball by leaving the Golden Rod Pokemon center, even if you had done the event before
*
* Secondly, it's just nice to be able to trigger the GS Ball/Celebi event more than once.
*
* Don't forget to call finishSave() after using this function!
*/
void unlockGsBallEvent();
/**
* @brief Retrieves the value of the given event flag
* Hint: You can find the number and meaning of various event flags here:
* https://github.com/kwsch/PKHeX/blob/master/PKHeX.Core/Resources/text/script/gen2/flags_c_en.txt
*/
bool getEventFlag(uint16_t flagNumber);
/**
* @brief Sets the value of the given event flag number
* Hint: You can find the number and meaning of different event flags here:
* https://github.com/kwsch/PKHeX/blob/master/PKHeX.Core/Resources/text/script/gen2/flags_c_en.txt
*
* Don't forget to call finishSave() after using this function!
*/
void setEventFlag(uint16_t flagNumber, bool enabled);
protected:
private:
IRomReader &romReader_;
ISaveManager &saveManager_;
Gen2SpriteDecoder spriteDecoder_;
Gen2GameType gameType_;
};
#endif