suloku Posted February 19, 2017 Posted February 19, 2017 (edited) I've looked into the Stadium 2 savefile to locate registered teams and also coded a dumper that exports the registered pokémon as pk2 files ready to use with pkhex. This may help some people get their original pokémon back, if they ever registered them on Stadium 2. As a bonus, this can be used to dump the rental pokémon if you register them. Note about the dumps: registered pokémon lose the extra 0x50 terminators in the nickname (when a pokémon is never nicknamed, all extra bytes are set as 0x50, when nicknamed they are set to 0x00). This has no real impact, but it's a pitty they aren't 1:1 copies. (The status condition is also lost, but that isn't important either so...). UPDATE 11/04/2021: Pkhex supports all pokémon stadium savegames as of now, but since it seems I missed many registered teams in the initial release, I've updated the dumper so it dumps all teams in pk2 and sk2 format, optionally it will put RENT as OT name for rental pokémon in case someone wants to use them in a gen 2 game withouth manually inserting an OT. I've also included ED64-Saveswap in the file for convenience. UPDATE 14/03/2020: It seems Stadium 2 never actually stores the "full" name of the pokémon. The name is stored only until a 0x50 terminator is found. This makes depositing the pokémon in stadium 2 become "nicknamed". This doesn't make any actual different, but on the GBC games this wouldn't happen as the game seems to keep copying the bytes 0x50 bytes. Because pokémon data in boxes in the GB games isn't actually erased but rather the box slot is marked as "empty" when you withdraw/release/move pokémon, there is a chance that when you return the pokémon to GB the pokémon will become unnicknamed again, depending on the pokémon that was stored in that slot before. If one would like to return the pokémon to the "unnicknamed status", the easiest would be to have an unnicknamed evolved or wild muk stored in the box (because it's the shortest pokémon name and all chars besides the first 3 will be 0x50). Then put a pokémon from stadium 2 into that box in the same slot muk was. This is easiest done in a box with 19 pokemon, deposit muk in GB, withdraw, then deposit pokémon from stadium 2 into that box. This doesn't happen with OT name, it is fully copied. I suspect this is done so only full OT name + ID can nicnkame a pokémon (the pokémon being marked as nicknamed or not is irrelevant). Thus, this finding makes any registered pokémon recovered with the dumper be actually the same one you had back in your day. Registered teams start at 0x4000 in the savefile, here's the structure: Registered parties are 0x180 each: 0x10 header + six 0x3C pokemon structures + 2 bytes padding, 4 byte footer and 2 byte checksum 0x00 Header: 0x0 1 True if team is present (0x00 if no team) 0x1 1 Padding 0x00 0x2 2 trainer ID (default 0x0000) 0x4 12 Trainer name (GB encoding, 0x50 terminated + 1 byte padding 0x00) (default 0x5000) 0x10 Start of party pkmn, 0x3C each; uses a similar GB storage format: 0x00 1 species 0x01 1 held item 0x02 1 move 1 0x03 1 move 2 0x04 1 move 3 0x05 1 move 4 0x06 2 OT ID *0x08 4 EXP (1 byte extra padding) 0x0C 2 HP exp 0x0E 2 Atk exp 0x10 2 Def exp 0x12 2 Spd exp 0x14 2 Spc exp 0x16 2 DVs 0x18 1 PP 1 0x19 1 PP 2 0x1A 1 PP 3 0x1B 1 PP 4 0x1C 1 friendship 0x1D 1 level 0x1E 1 status condition? (status is set to 0 when the pokémon is registered) (might be padding) 0x20 2 Caught data 0x22 1 Padding? (might be status condition) *0x24 12 nickname (GB encoding, 0x50 terminated) (1 extra padding byte) *0x30 12 OT name? (GB encoding, 0x50 terminated; 0 if rental) (1 extra padding byte) 0x178 2 Padding? always 0x0000 0x17A 4 Footer 'P3v0' (0x50337630) 0x17E 2 Checksum (UByte 8 bit) Computes Header + party data + footer Download (source code included):stadium2dumper.zip Stadium2Dumper_0.2.zip Edited April 11, 2021 by suloku 2 1
Aquaaquaaqua Posted March 6, 2017 Posted March 6, 2017 So, I thought I should tell everyone that at first the program worked for me after using a Neo N64 Myth Cart to backup my cartridge save and then using ED64-SaveSwap on the save, however that was once and now any new backups I make from the cartridge don't work with the program, even after using SaveSwap. Personally, I don't care since I have a fully-compatible backup of the save already, but I just thought I'd mention this oddity.
suloku Posted March 7, 2017 Author Posted March 7, 2017 11 hours ago, Aquaaquaaqua said: So, I thought I should tell everyone that at first the program worked for me after using a Neo N64 Myth Cart to backup my cartridge save and then using ED64-SaveSwap on the save, however that was once and now any new backups I make from the cartridge don't work with the program, even after using SaveSwap. Personally, I don't care since I have a fully-compatible backup of the save already, but I just thought I'd mention this oddity. Send me the saves via PM and I'll check them and see what's wrong.
vgmoose Posted April 28, 2017 Posted April 28, 2017 Thank you very much for this program and documenting the format! I may try to use it in conjunction with a save dumped from this cartreader device.
Aquaaquaaqua Posted September 12, 2017 Posted September 12, 2017 Just for the record, as I told suloku via pm, the reason I felt the need to redump my save after I had a save dump that was converted to successful compatibility with the Pokemon dumper, was mainly because of OCD. And oh yeah I did in the end send suloku a fresh save dump, (that wasn't saveswapped,) but, whatever.
Metropolis Posted July 18, 2019 Posted July 18, 2019 Apologies to the moderators if bumping a two year thread violates any rules, but I’m interested in any work being done in this area and may be able to contribute. Thanks suloku for this excellent research. Could anyone who has edited N64 save files provide some additional info on: Endianness of bytes (big/little) Other checksums across the data sections that would need to be updated when the regions detailed above are modified. Any other relevant research or implementations of dumping or editing the registered Pokemon (or other Pokemon stadium save data) including different formats and lengths of save files. It would cool to see a fully fledged Pokemon Stadium 2 editor, and this provides a great starting point for any developers. Thanks. 2
suloku Posted March 14, 2020 Author Posted March 14, 2020 (edited) I've been running some tests and I did find out stadium 2 does not store the full pokémon name, either when boxing or when registering. I've updated the first post with this information. It seems Stadium 2 never actually stores the "full" name of the pokémon. The name is stored only until a 0x50 terminator is found. This makes depositing the pokémon in stadium 2 become "nicknamed". This doesn't make any actual different, but on the GBC games this wouldn't happen as the game seems to keep copying the bytes 0x50 bytes. Because pokémon data in boxes in the GB games isn't actually erased but rather the box slot is marked as "empty" when you withdraw/release/move pokémon, there is a chance that when you return the pokémon to GB the pokémon will become unnicknamed again, depending on the pokémon that was stored in that slot before. If one would like to return the pokémon to the "unnicknamed status", the easiest would be to have an unnicknamed evolved or wild muk stored in the box (because it's the shortest pokémon name and all chars besides the first 3 will be 0x50). Then put a pokémon from stadium 2 into that box in the same slot muk was. This is easiest done in a box with 19 pokemon, deposit muk in GB, withdraw, then deposit pokémon from stadium 2 into that box. This doesn't happen with OT name, it is fully copied. I suspect this is done so only full OT name + ID can nicnkame a pokémon (the pokémon being marked as nicknamed or not is irrelevant). Thus, this finding makes any registered pokémon recovered with the dumper be actually the same one you had back in your day. Also, friendship is reset, as if the pokémon was traded. Edited March 14, 2020 by suloku
ShadowMario3 Posted October 3, 2020 Posted October 3, 2020 (edited) Posting my finding on the offset locations for the Registered Teams. It seem that the Japanese version (G&S) only has 10 registered teams per mode, which puts it in line with the English version. Also will be clarifying the Pokemon data structure. First the is a registered team is made using OP's post as a base: Registered parties are 0x180 each: 0x10 header + six 0x3C pokemon structures + 2 bytes padding, 4 byte footer and 2 byte checksum 0x00 Header: 0x0 1 True if team is present (0x00 if no team) 0x1 1 Padding 0x00 0x2 2 trainer ID (default 0x0000) *0x4 12 Trainer name (GB encoding, 0x50 terminated + remaining byte padding 0x00) (default 0x5000) 0x10 Start of party pkmn, 0x3C each; uses a similar GB storage format: 0x00 Index number of the Species 1 byte 0x01 Held Item 1 byte 0x02 Move 1 1 byte 0x03 Move 2 1 byte 0x04 Move 3 1 byte 0x05 Move 4 1 byte 0x06 OT ID 2 bytes *0x08 Experience points (1 byte 4 bytes extra padding at beginning) 0x0C HP EV Data 2 bytes 0x0E Atk EV Data 2 bytes 0x10 Def EV Data 2 bytes 0x12 Spd EV Data 2 bytes 0x14 Spc EV Data 2 bytes 0x16 DV Data 2 bytes 0x18 Move 1's PP values 1 byte 0x19 Move 2's PP values 1 byte 0x1A Move 3's PP values 1 byte 0x1B Move 4's PP values 1 byte 0x1C Friendship or Hatch Counter 1 byte 0x1D Level 1 byte 0x1E Status** 2 bytes 0x20 Pokérus Status 1 byte 0x21 Caught data 2 bytes 0x23 1 Padding? *0x24 Nickname (GB encoding, 0x50 12 bytes terminated) (1 extra padding byte) *0x30 OT name (GB encoding, 0x50 12 bytes terminated; 0 if rental) (4 extra padding bytes) 0x17A Footer 'P3v0' (0x50337630) 4 bytes 0x17E Checksum (UByte 8 bit) 2 bytes Computes Header + party data + footer *If OT Name is short, 0x50 is used to fill in rest (7 characters total in English, 5 in Japanese). *Japanese version is mostly the same except for one difference in Nickname and OT Name. Nicknames can only be 5 bytes, has 0x50 terminator, and 6 bytes of padding. Same with OT names. Both will have 0x00 padding to fill 12 bytes each. **Status is set to 0 when the pokémon is registered or in box. Set to 1 if Egg in box. Set to 4 if it is a rental Pokemon in a registered team. There is one byte padding afterwards. Thanks to @Kaphotics for figuring out which byte Pokérus is. For example, D1 = strain 13 and 1 day left. Use this chart for English Nickname and OT: https://bulbapedia.bulbagarden.net/wiki/Character_encoding_in_Generation_II#English For Japanese Nickname and OT: https://bulbapedia.bulbagarden.net/wiki/Character_encoding_in_Generation_II#Japanese Here are the locations for the Registered Teams (same in English and Japanese versions): Anything Goes Little Cup Poké Cup Prime Cup Gym Leader Castle Vs. Rival 01 0x0 0xF00 0x1E00 0x2D00 0x4000 0x4F00 02 0x180 0x1080 0x1F80 0x2E80 0x4180 0x5080 03 0x300 0x1200 0x2100 0x3000 0x4300 0x5200 04 0x480 0x1380 0x2280 0x3180 0x4480 0x5380 05 0x600 0x1500 0x2400 0x3300 0x4600 0x5500 06 0x780 0x1680 0x2580 0x3480 0x4780 0x5680 07 0x900 0x1800 0x2700 0x3600 0x4900 0x5800 08 0xA80 0x1980 0x2880 0x3780 0x4A80 0x5980 09 0xC00 0x1B00 0x2A00 0x3900 0x4C00 0x5B00 10 0xD80 0x1C80 0x2B80 0x3A80 0x4D80 0x5C80 Offsets for Boxes in Professor Oak's Lab: English boxes are 0x4D8 each: Japanese boxes are 0x750 each: Box 1 0x5E00 Box 1 0x5E00 Box 2 0x8000 Box 2 0x8000 Box 3 0x84D8 Box 3 0x8750 Box 4 0x89B0 Box 4 0x8E60 Box 5 0x8E88 Box 5 0x9590 Box 6 0x9360 Box 6 0x9CC0 Box 7 0x9838 Box 7 0xA3F0 Box 8 0x9D10 Box 8 0xAB20 Box 9 0xA1E8 Box 9 0xB250 Box 10 0xA6C0 Box 11 0xAB98 Box 12 0xB070 Box 13 0xB548 Box 14 0xBA20 Edited October 7, 2020 by ShadowMario3 More info about status. 1
suloku Posted April 11, 2021 Author Posted April 11, 2021 (edited) Seems my program only dumped "Gym Leader Castle" registered teams. For some reason I did find the correct Pokérus byte and caught data bytes, but didn't update the file structure (neither here or in the main.c file), but pk2 dumps should be correct. Thanks @ShadowMario3 for the detailed teams structure. Pkhex now supports all stadium savefiles, including registered teams, but I tested it earlier and seems to have some bugs (I tested registering a celebi, then dumping and the dumped file became japanese somehow). I'll post an issue in pkhex's github, for now I've updated the dumper code to dump all registered teams, both in sk2 (direct dump pkhex compatible) and pk2 file format. EDIT: seems the bug in pkhex was related to importing sk2 files when it couldn't decide if the file was jap or international (OT and Name both being lesd than 5 characters). Seems it is already fixed at github. Edited April 12, 2021 by suloku 1
Grimakis Posted June 1, 2022 Posted June 1, 2022 Hi all, I just wanted to thank you for the work here. Secondly, I don’t have a cart reader, but I found another way to get the data. if you have a Gameshark Pro, you can use the Memory Editor. Basically, go into whatever gamemode you have your team, choose that team, and get to the point where you pick your three pokemon. press the GS button, and choose memory editor. Then do a text search on your Pokemon’s name. You will find the data structure from the earlier post fully loaded into memory. Then I just copied the relevant values and used PkHex to reconstitute the team
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now