Skip to content

Save Functions

Chris Feger edited this page Jun 17, 2020 · 3 revisions

## Value Access

int sav_get_value(enum SAV_Field field, ...);

enum SAV_Field
{
    SAV_OT_NAME,
    SAV_TID,
    SAV_SID,
    SAV_GENDER,
    SAV_COUNTRY,
    SAV_SUBREGION,
    SAV_REGION,
    SAV_LANGUAGE,
    SAV_MONEY,
    SAV_BP,
    SAV_HOURS,
    SAV_MINUTES,
    SAV_SECONDS,
    SAV_ITEM
};

// example usage
char *otName = (char *)sav_get_value(SAV_OT_NAME);
int tid = sav_get_value(SAV_OT_TID);
int firstMedicine = sav_get_value(SAV_ITEM, Medicine, 0);
Used to get values out of the currently loaded save. Most fields will not require even a second argument. See below for what fields are available. Notable caveats and arguments are:
  • `SAV_OT_NAME`: Returns a UTF-8 formatted string that must be manually freed. Cast to `char*` to use it properly
  • `SAV_TID` and `SAV_SID`: Both return the 5-digit format
  • `SAV_ITEM`: Requires an `enum Pouch` (see [General Enums and Structs: Pouch](PicoC-Basics#pouch)) and a slot number. Returns the item ID of the specified slot

## Wonder Cards

int sav_wcx_free_slot();
Gets the first empty Wonder Card slot, or, if all are filled, the maximum index.
void sav_inject_wcx(char* data, enum Generation type, int slot, int alternateFormat);
Injects a wonder card.
  • `data` should be a pointer to the Wonder Card data in the correct format for the generation. If the Wonder Card data passed in is not in the correct format, issues will occur.
  • `slot` refers to which Wonder Card slot it should be injected to, though GEN_LGPE does not store Wonder Cards, and, as such, this argument does not affect it.
  • `alternateFormat` is a boolean that refers to the format of the data passed in, based on the value of `enum Generation type` as follows:
    • `GEN_FOUR`: if true, `data` is interpreted as a WC4 (meaning that the internal Pokémon data is decrypted). Otherwise, `data` will be interpreted as a PGT.
    • `GEN_FIVE`: ignored
    • `GEN_SIX`: if true, `data` is interpreted as a WC6FULL. Otherwise, `data` will be interpreted as a WC6
    • `GEN_SEVEN`: if true, `data` is interpreted as a WC7FULL. Otherwise, `data` will be interpreted as a WC7
    • `GEN_LGPE`: if true, `data` is interpreted as a WB7FULL. Otherwise, `data` will be interpreted as a WB7

## Values

void sav_get_data(char* dataOut, unsigned int size, int off1, int off2);
void sav_set_data(char* data, unsigned int size, int off1, int off2);
int sav_get_bit(int off1, int off2, int bitNum);
void sav_set_byte(int bitVal, int off1, int off2, int bitNum);
char sav_get_byte(int off1, int off2);
void sav_set_byte(char data, int off1, int off2);
short sav_get_short(int off1, int off2);
void sav_set_short(short data, int off1, int off2);
int sav_get_int(int off1, int off2);
void sav_set_int(int data, int off1, int off2);
char* sav_get_string(int off1, int off2, unsigned int codepoints);
void sav_set_string(char* string, int off1, int off2, unsigned int codepoints);
These functions are used to read data from and write data to the save. All functions with `get` will retrieve data, and all with `set` will write it. `off1` and `off2` work as follows:
  • In Generations 4-7 and LGPE, `off1` and `off2` are added together to get the final offset.
  • In Generation 3 and 8, `off1` indicates the block used.
    • In Generation 3, values -1-13 are allowed for `off1`: 0-13 indicate the block index to use, and -1 indicates that the offset is absolute.
    • In Generation 8, any value that is a block key is allowed for `off1`. There is no indication that an offset is absolute, as there are no absolute offsets in G8 saves.
  • In Generations 3 and 8, `off2` is the offset from the start of the block indicated by `off1`.
  • `sav_get_bit` will return 0 for unset and 1 for set, and `sav_set_bit`’s bitVal argument should be 0 for unset and 1 for set.
  • `bitNum` is zero-indexed from the least-significant bit. An example:

Byte value: 0x7B

`bitNum` 7 6 5 4 3 2 1 0
Value returned 0 1 1 1 1 0 1 1

## Box Data Encryption

void sav_box_decrypt();
void sav_box_encrypt();
**IMPORTANT**: These should always be used as a pair and always in this order. Mixing them or not using them in pairs will produce unpredictable results.

Any edits you aim to make should be done after calling `sav_box_decrypt` and before calling `sav_box_encrypt`.