Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ==================================================
- Editing the Tutor Moves in Pokemon Platinum (US)
- -- by Maple, help from TurtleIsaac and Solace --
- ==================================================
- -- 2021, updated December 16th --
- [ Setup ]
- 1.) First, use Tinke to extract overlay9_5 from a Pokemon Platinum (US) ROM
- 2.) Use a Hex Editor such as HxD to open overlay9_5
- ---------------------------------------------------------------------------------------------------------------------------------------
- [ Editing the Available Moves, Cost, and Tutor Location ]
- 1.) Go to offset 0x2FF64.
- 2.) [Optional] Use Ctrl-X to cut out the bytes occuring before this offset, then set your bytes per row to 12. This makes it easier to edit and make sure you stay consistent to the byte layout. After editing, paste back what you cut and save.
- 3.) There are 38 tutorable moves in Pokemon Platinum. Each move is contained in a 12-byte grouping, which carries data in this format:
- XX XX RR BB GG YY 00 00 LL 00 00 00
- XX XX : Move ID in Hex (little endian, ie Move 1C3 would be C3 01)
- RR / BB / YY / GG : Number of shards required to tutor this move
- LL : Tutor location. 00 is Route 212, 01 is Survival Area, and 02 is Snowpoint.
- 4.) Edit what you want, save, then import overlay9_5 back into Tinke. You've now changed the available moves, costs, and locations.
- ---------------------------------------------------------------------------------------------------------------------------------------
- [ Editing the Compatibility Chart ]
- 1.) Go to offset 0x30127.
- 2.) [Optional] Similar to above, use Ctrl-X and 5 bytes per row to create a consistently sized table.
- 3.) There are 508 entries for each Pokemon and form within the game, each associated with 5 bytes. These 5 bytes form a 40 bit bitfield, with each bit in it representing whether an associated move is learnable by tutor, with the last 2 bits being 0's to form a clean 5 bytes.
- For an example, Squirtle in base Platinum would be [1B 25 40 10 00], which maps to this in binary:
- 00011011 00100101 01000000 00010000 00000000
- Based on the tutor move chart for Squirtle, this is how the bytes "should" look, which clues us into the ordering of the bits:
- 11011000 10100100 00000010 00001000 000000 <- last 2 bits are the 00 buffer
- This means, to get the proper bitfield, you need to read each byte backwards. Once you have your desired bitfield in chart order (move 0 to 38, with the buffer at the end), reverse each byte one at a time, then convert each byte to hex separately, then write it into the desired index. Beware of the buffer! It can get tricky because it is read backwards too. For example, Mew's hex is [FF FF FF FF 3F], because it can learn all tutor moves, but the buffer is written in the first two bits of the binary bitmap, so it looks like this:
- 11111111 11111111 11111111 11111111 00111111
- This can get a bit tedious, so I might end up writing a really simple code you can put into an online IDE and it outputs the Hex bytes associated with the bitmap.
- 4.) After editing, save, then import overlay9_5 back into Tinke. You've now changed the compatibility table.
- ---------------------------------------------------------------------------------------------------------------------------------------
- !!!! C code for generating Hex (ignore how messy it is) !!!!
- 0.) This only works if you have access to the compilation and manual execution of C code.
- 1.) Paste the code below into a file, save it as anything with the extension .c, for example tutor.c
- 2.) Go into the command line, navigate the folder you saved tutor.c in, and run the command-line command [gcc tutor.c] to get the executable
- 3.) Now that you can run the program, you need to generate the table of 1's and 0's from the PokEditor compatibility table
- 4.) To do so, copy the sheet into a separate google sheet. Delete the Egg and Bad Egg rows as they are unused in the tutor table. Delete the index and species column, as well as the move row. After doing so, save the table of checkboxes as a .csv file.
- 5.) Open up the .csv file in a text editor. From here, use Find and Replace to replace things in this order:
- 1. Find = FALSE, -> Replace = 0
- 2. Find = TRUE, -> Replace = 1
- 3. Find = FALSE -> Replace = 000
- 4. Find = TRUE -> Replace = 100
- After doing so, you should be left with the 5 byte bitfields needed for the program below to generate the proper hex. Save the .csv file as a text file within the same folder as tutor.c (example: tutor.txt)
- 6.) Run the command-line command [./a.out] which will run tutor.c. It will ask for a text file, inputting tutor.t. Afterwards, should produce a list of Hex values to be copy-pasted back into that text file. These hex values should also be ready to insert into the compatibility table in a hex editor like HxD.
- 7.) To insert, highlight from the start of the table (0x30127) to the end of the table (0x30B09) and delete. Then, paste from the same starting offset, which replaces the previous table (can also use a Paste-Write option if your hex editor offers it).
- 8.) From here, simply save and insert using Tinke.
- #include<stdio.h>
- #include<stdlib.h>
- int main()
- {
- char cmd[100];
- printf("Enter text file: ");
- scanf("%s", cmd);
- FILE *f = fopen(cmd, "r");
- unsigned char og_bitfield[40];
- char *endpointer;
- unsigned long decimal;
- unsigned char byte1;
- unsigned char byte2;
- unsigned char byte3;
- unsigned char byte4;
- unsigned char byte5;
- unsigned char temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
- while(1){
- if(fscanf(f, "%s", og_bitfield)!=EOF){
- decimal = (unsigned long) strtol(og_bitfield, &endpointer, 2);
- byte1 = decimal >> 32;
- byte2 = decimal >> 24;
- byte3 = decimal >> 16;
- byte4 = decimal >> 8;
- byte5 = decimal;
- temp1 = byte1>>7;
- temp2 = (byte1&0b01000000)>>5;
- temp3 = (byte1&0b00100000)>>3;
- temp4 = (byte1&0b00010000)>>1;
- temp5 = (byte1&0b00001000)<<1;
- temp6 = (byte1&0b00000100)<<3;
- temp7 = (byte1&0b00000010)<<5;
- temp8 = ((byte1<<7));
- byte1 = temp1^temp2^temp3^temp4^temp5^temp6^temp7^temp8;
- temp1 = byte2>>7;
- temp2 = (byte2&0b01000000)>>5;
- temp3 = (byte2&0b00100000)>>3;
- temp4 = (byte2&0b00010000)>>1;
- temp5 = (byte2&0b00001000)<<1;
- temp6 = (byte2&0b00000100)<<3;
- temp7 = (byte2&0b00000010)<<5;
- temp8 = ((byte2<<7));
- byte2 = temp1^temp2^temp3^temp4^temp5^temp6^temp7^temp8;
- temp1 = byte3>>7;
- temp2 = (byte3&0b01000000)>>5;
- temp3 = (byte3&0b00100000)>>3;
- temp4 = (byte3&0b00010000)>>1;
- temp5 = (byte3&0b00001000)<<1;
- temp6 = (byte3&0b00000100)<<3;
- temp7 = (byte3&0b00000010)<<5;
- temp8 = ((byte3<<7));
- byte3 = temp1^temp2^temp3^temp4^temp5^temp6^temp7^temp8;
- temp1 = byte4>>7;
- temp2 = (byte4&0b01000000)>>5;
- temp3 = (byte4&0b00100000)>>3;
- temp4 = (byte4&0b00010000)>>1;
- temp5 = (byte4&0b00001000)<<1;
- temp6 = (byte4&0b00000100)<<3;
- temp7 = (byte4&0b00000010)<<5;
- temp8 = ((byte4<<7));
- byte4 = temp1^temp2^temp3^temp4^temp5^temp6^temp7^temp8;
- temp1 = byte5>>7;
- temp2 = (byte5&0b01000000)>>5;
- temp3 = (byte5&0b00100000)>>3;
- temp4 = (byte5&0b00010000)>>1;
- temp5 = (byte5&0b00001000)<<1;
- temp6 = (byte5&0b00000100)<<3;
- temp7 = (byte5&0b00000010)<<5;
- temp8 = ((byte5<<7));
- byte5 = temp1^temp2^temp3^temp4^temp5^temp6^temp7^temp8;
- printf("%02x %02x %02x %02x %02x\n", byte1, byte2, byte3, byte4, byte5);
- }
- else
- break;
- }
- fclose(f);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment