Pokémon byte exporting tool for 1st and 2nd generation save files
Java Perl
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
Android
PokeExport
README
perl.pl

README

Pokemon Exporting Tool
    - this tool is designed to read the raw bytes from a pokemon save
      file and export/import the specific pokemon.
    - functions fully for first and second generation as of right now.
    
Terminology:

Position:
    All Pokemon in the game are assigned a position from 0 to 249,
    representing their location in the six party slots and fourteen
    boxes. It's a little tricky to think about them in order, so you
    can use getPosition() to return a Position value with a given box
    and slot. See below.
    
byte[] Pokemon:
    There are no Pokemon objects at this time in the API. Instead, a
    byte array represents a Pokemon. In this program, if you see a 
    byte array being passed around, it probably means that it's passing
    an entire Pokemon around to either export it or read data. You'd also
    pass a pokemon around to write it to a specific Position in the data.
    
data array:
    The data array reperesenting every byte in the cartridge. This is 
    stored in memory, and then written back to the file with writeFile().
    
    
Common methods:

initVars()      
    - load a pokemon.sav file. Hardcode the path or launch a browser.
    - must be called first in order to do anything with data.
                

getPosition(int box, int slot)
    - returns an integer representing a pokemon's Position in the given
      box and slot. For example, getPosition(2,1) gives you the first 
      pokemon in the second box, which is represented by 25.
      
readPokemonFromData(int pos)
    - returns a byte array representing a Pokemon given a Position.
    - this byte array can then be passed around, exported or parsed.
    
exportPokemon(byte[] pokemon)
    - exports a pokemon to a filename. It is stored by default in 
      Pokemon directory, with a filename including it's nickname,
      species, and a checksum representing its information.
      
listAllPokemonFiles()
    - returns an array of File objects representing Pokemon that
      have been exported. These can be passed to importPokemon
      
*importPokemon(File f)
    - imports a given .2pkm file to a byte array (returns).
    
writePokemonToData(byte[] b, int pos)
    - writes a Pokemon to the data array that is stored in memory.
    - writes to the given position, as well as OtherSpecies byte.

writeFile()
    - writes the data array to the file, and generates the checksum.
    - should be called after a file operation is done (eg. moving data)
      to ensure that everything is insync in memory and data.
      
parsePkm(byte[] pokemon)
    - returns a string detailing all information that is represented in
      the pokemon byte array in human readable format.
      
printAllPokemonDetails()
    - Does what it says! Prints information on all Pokemon in party and box.
    
    
Pokemon Data Structure

The file structure of a .2pkm file is 54 bytes:
    
        11 for the nickname of the Pokemon
        8 for the Original Trainer name
        3 unused bytes
        32 for the actual PKM data
        
Unused bytes may be used to pass around file information between future
versions of the program.

Here is an example of some raw data using printBytes(byte[] pokemon):
    91 8E 82 8A 98 50 50 50 50 50 50 8A 98 8B 84 50 50 50 50 00 00 00 5F 00 21 67 14 58 BF 1E 00 2A E2 09 03 09 06 08 A8 0A 17 08 2F 96 66 23 28 14 0F B2 00 00 7E 16 
    
To break this down as it is broken down above:
    
    Nickname bytes: 
    
    91 8E 82 8A 98 50 50 50 50 50 50
     R  O  C  K  Y 
    
    8A 98 8B 84 50 50 50 50 
     K  Y  L  E
    
    00 00 00 
    three unused as of right now bytes
    
    5F 00 21 67 14 58 BF 1E 00 2A E2 09 03 09 06 08 A8 0A 17 08 2F 96 66 23 28 14 0F B2 00 00 7E 16 
    32 PKM bytes, 5F is Onix, which you can read by calling:
    parseSpecies(byte[] pokemon) on the whole pokemon byte array. The rest
    is this information, generated with parsePkm(byte[] poke):
        Level: 22
        Gender: Male
        Hold Item: None
        Moveset: Tackle / Screech / Bind / Rock Throw
        Experience: 10978
        EVs: 2307 HP / 2310 ATK / 2216 DEF / 2583 SPEED / 2095 SPECIAL
        IVs: 9 ATK / 6 DEF / 6 SPEED / 6 SPECIAL
        Happiness: 178
        PokeRus: false
        Met at Level: 0
        Time of Day: No Data
        Location: Can't tell
        Trainer ID: 48926
        Trainer Gender: Male
        
Examples:

    initVars()
        - load up the game with one save file.

    System.out.println(parsePkm(readPokemonFromData(getPosition(3,1))));
        - prints out information on pokemon in box 3 slot 1.
        
    byte[] poke1 = readPokemonFromData(getPosition(2,4));
        - stores pokemon in box 2 slot 4 to the poke1 object
        
    writePokemonToData(poke1, getPosition(2,5)):
        - would make a copy of the pokemon in box 2 in slot 5 as well
        
    exportPokemon(poke1);
        - exports the poke1 object to a file
        
    ** restart the program **
        
    initVars() 
        - load up the game with a different save file
        
    File file = listAllPokemonFiles()[0];
        - loads a pokemon file, this assumes that the Pokemon directory is 
          empty.
    
    byte[] newp = importPokemon(file);
        - imports the Pokemon to newp object.
        
    writePokemonToData(newp, getPosition(1,1));
        - writes the exported pokemon data from the first game, to box 1
          slot 1 in the other game. Traded pokemon!
          

Things to fix:

    Adjust box count, (right now, pokemon can't be added in slots that don't
                       already have pokemon in them)
                       
    Read box names,  (for ease of use)
    
    Properly write party data,      (will work 1/2 the time right now, due to
                                     the mirror copy of the party data)
    
    importFile(),   (to actually import data to bytes)
    
    loadFile(),     (instead of calling initVars() all the time)
    
    and other things!