Hi,
I'm currently developing a software which reads Pokémon save file data. Also, I have a few questions :Tux.
- How does work the small/big blocks mechanics in a 256-kilobytes file ?
- How does work the save file data in Generation III ?
- Is the block footer structure the same beetween D/P/Pl/HG/SS/B/W ?
- Where are located the ID, sID, 'Number of Party Pokémon', the Party Pokémon data, the PC Pokémon data in B/W? Same question for Generation III save file data.
- Is something new about these save file informations beetween B/W and HG/SS ?
- Is it the same blocks mechanics between B/W and HG/SS ? What are the blocks limits offsets in B/W ?
- For a 256 KB save file, I imagine there would be no backup blocks. But the game was not meant to save files of this size, so I never bothered with them personally.
- The Gen III save structure is sort of complicated... I am looking for the documentation I used to figure it out so I don't have to try to explain it (since I'm sure I'd only befuddle you if I tried).
EDIT: Ah, look what a quick Google search yields: http://furlocks-forest.net/wiki/?pag...BA_Save_Format
- The block footers are very similar between all Gen IV games... I think there are minor differences in HGSS, but nothing too complicated IIRC.
- Your best bet for locating the PKM data in B/W is to just use a save file containing a few PKM you know the PID of, and opening the save file in HxD or some other hex program and doing a search for those PIDs.
- Um, yes?
- I don't think B/W switch the blocks around like Gen IV did, making it much more straightforward to find the "current" information. I dunno anything specific about the B/W save data though.
Also, don't forget that the Gen III PKM data looks different:
http://bulbapedia.bulbagarden.net/wi...Generation_III
http://bulbapedia.bulbagarden.net/wi...Generation_III
My Pokémon stuff on Google Drive!
Spoiler
To use (some of) my software you need the .Net Framework!
codemonkey85 on
Pokémon Black 2: 1507-3503-1914
Thanks a lot ^^ !
Also, I'm unable to recalculate the save file checksums --' . I have readen your PKMDS vb.net library (by the way, this is a excellent and useful library) source code, and have transcripted the checksums algorithm in C++, but I get wrong checksums ...
For example, with 0 for begining block offset, and (0xC0EC + 20) for ending offset (inclusive) and 20 for the footer size, I get 0x5663 (or 0x6356) instead of 0x2306 (EDIT: 0x7A0A or 0x0A7A, offset 0xC0FE to 0xC0FF, sorry)
Here is a part my source code :
Code:int Savefile::getSeeds(int * seeds) //Output is the 'seeds' parameter array { int v0 = 0; //Signed 32-bit Integer int v1; int v2; int result; do { v1 = v0 << 8; v2 = 0; do { if ((unsigned char)(v1 >> 8 & 0x80) != 0) //unsigned char : unsigned 8-bit integer = Byte v1 = (2 * v1) ^ 0x1021; else v1 *= 2; v2 += 1; } while(v2 < 8); result = (unsigned short) v1; //Unsigned 16-bit integer seeds[v0] = result; v0 ++; } while(v0 <= 0xFF); return result; } unsigned short calculateChecksum(FILE * savefile, unsigned int begin, unsigned int end, unsigned int footerSize) { int seeds[0xFF]; getSeeds(seeds); unsigned char * data = new unsigned char[end-begin-footerSize]; fseek(savefile, begin, SEEK_SET); //Set the cursor at the beginning of the savefile + begin fread(data, 1, (end-begin) - footerSize, savefile); //Read end-begin-footerSize bytes of data into the array 'data' int checksum = 0xFFFF; long long unsigned int i; //64-bit unsigned integer int v4 = end - footerSize; unsigned char v6; i = 0; while (v4 > 0) { v4 -= 1; v6 = (unsigned char)(data[i] ^ (unsigned char)(checksum >> 8)); checksum = (checksum << 8) ^ seeds[v6]; i++; } unsigned short retour = (unsigned short) checksum; delete[] data; // retour ^= 0; return retour; }
Last edited by Tux; Jun 11th, 2011 at 03:24 AM.
Just out of curiosity, which game's save file are you trying to calculate a checksum for?
Also, I'm no help when it comes to C++.![]()
My Pokémon stuff on Google Drive!
Spoiler
To use (some of) my software you need the .Net Framework!
codemonkey85 on
Pokémon Black 2: 1507-3503-1914
I use my Pokémon Pearl's savefile.
I don't understand what I got wrong ... Is The temporary variable(initializated at 0xFFFF), which is used to calculate the checksum , a signed 32-bit integer ?
Which pairs of offsets (inclusive) should I use to calculate the checksum ?
Hmm. It's been quite some time since I've looked at this part of my library. I have a tight schedule this week but I'll try to look it over when I can.
Issue fixed ! (my program's generated checksum and Pokegen's are the same)
The equivalent of the changes made in C++ are the following in VB .Net :
Also, thanks a lot for your help and for your libraryCode:seeds = New Integer(&H100) {} 'instead of : seeds = New Integer(&H100 - 1) {}, line 13304 in PKMDSLIB.vb of your library If (CType((v1 >> 8) And &H80, [Byte]) And &H80) <> 0 Then ' Instead of : If (CType(v1 >> 8, [Byte]) And &H80) <> 0 Then, l. 13315, supposing CType() returns the 8 firts bits starting from right.
PS : How is the checksum calculated in Gen III save files ?



There are save file editors for gen 3, namely Pokemon Enciclopedia (spanish, translated on forums) and PokeStock (japanese).
PSavFix (by loadingNOW iirc) corrects the Chksum, here's the code:
Spoiler
That's great, thanks! Is it the same algorithm/"Map" for Pokémon Emerald?



I'm not sure, probably.
Bookmarks