This is a tutorial to change some of the sprites in Red/Blue/Yellow roms. What you need:
A hex Editor (duh?) (I used Hexeccute because of it's Copy/paste functionality)
A debugger (I used Virtual Gameboy Color)
An emulator to test the result (Either VBA or just use the debugger mentioned above.)
First you have to choose which sprite you want to replace of course. I want to use the Nidorino sprite from Pokemon Yellow, and insert it into a Pokemon Red rom. Now that we've chosen the sprite we need to edit the Yellow rom slightly. To find where the sprite is in Yellow we need to go to the base stat data of Nidorino. So in your hex editor goto &H383DE. You're at Bulbasaur's data. Now go to &H383DE + &H1C * (Pokemon's Pokedex Number - 1) or &h383DE + &h1C * (33-1). So we're going to now look at &H383DE + &H39C or &H3875E.
We're now at Nidorino's Stat Data. The Pokemon's image data starts at the 11th byte of the base stats, so add 10 to where you are. You should now be at &H38768. And you should be seeing &H66. This just means that the image is 6 * 6. That's important if the image in Pokemon red is a 5 * 5, or 7 * 7. After this byte we have the pointers to the image data. 7F53 and DC54. The first pointer points to the front sprite and the second points to the backsprite. We're going to change the front sprite, but we still need to find the bank for both.
Now that we have that, find your preferred Debugger. I used Virtual Game Boy Color. So this explanation applys to that program. But before we open your rom in a debugger, we need to change a certain byte in the Pokemon Yellow rom. We need to view the the Nidorino image in the Pokemon Yellow rom to fin the bank for the offset. So in your Yellow rom, goto the address, &H5EDB. This is the byte for the Pokemon in the Oak Introduction. Change this to A7, which is the byte for Nidorino. Save.
Now open your Yellow rom in a debugger. Press F11 to enter the debugger mode. Set a breakpoint at &H251A, which is the beginning of the decompression routine, and then press F5, to continue the emulation.
As soon as you hit 'A' on 'New Game', the game will break. This isn't the image we want. This is breaking because of the Oak image. Just keep pressing F5 until the emulation begins again. You may have to press it 5-6 times. The next break is the one we want.
AS you can see the bank is 0D. (For more info on Pointers, go to bottom of post)
We now have our offsets, 0D:7F53, and 0D:DC54. Now turn these into a hex address.
0D 7F 53 = &h3537F
0D DC 54 = &h354DC
Now we need to find the size of the image. &h354DC - &h3537F = &h15D bytes. Pretty big image. Now we need to do the same process for the Nidorino sprite in Pokemon Red. (NOTE: Base Stat data begins at the same spot in both Red/Blue/Yellow. So the info will be in the same spot in each of those roms.)
Here, I'll even save you some time. The pointers in a Red rom, the Nidorino front and back sprites are at 35282, and 353F0 respectively. So that's a difference of &h16E bytes.
That means we don't need to repoint anything. Now in your Yellow Rom, go to the hex address 3537F, and highlight &h15D bytes or, every byte between the front and back sprites, then 'copy' it.
Now go to your red rom and go to 35282, and click 'paste'. Save. But I bet your asking about those extra 17 bytes left over from the paste. Don't worry about them. They won't effect your sprite in any way. The rom knows when the decompression of the image ends. All that's left is to look at the finished product.
Open your Red rom in your emulator. And you should have this.
Basic Pointer Information Hex Address to pointer Note: All values are hex.
3537F / 4000 = 0D ' This is the first byte.
Since Bank 0D is 34000 - 37FFF
For the last two bytes 3537F - 34000 = 13 7F.
Now we flip those and we get: 0D : 7F 13
That last byte needs to between 40 and 7F.
So if the byte is from:
0 - 3F 'Add 40 to it
40 - 7F 'Leave it as it is
80 - DF 'Subtract 40 from it
E0 - FF 'Subtract 80 from it.
My example lies in that first category so we add 40 to it.
Finished pointer is 0D: 7F53
Pointer to Hex Address Note: All values are hex.
xx * 4000 = 0D * 4000 = 34000
Flip yy and zz.
34000 + 54DC = 394DC
394DC / 4000 = 0E. WRONG BANK.
So subtract 4000 from 54DC = 14DC
34000 + 14DC = 354DC
Thanks to the unkown author of an older document
And Coolboyman for the guide on GB pointers.
For tools, search for them on google.
Any more clarification needed, please post your problem.
Just to add to this document, here is somthing Dammedmoose wrote a few years ago:
In a Pokémon's stat data (starting at 383DEh, 1Ch bytes for each pokemon, in pokedex order) there will be a byte,either 55h, 66h, or 77h followed by the pointers to the graphics..
I don't know how to tell the bank that the graphic is in apart from this way;
In NO$GMB, put a breakpoint at the start of the graphic decompression routine (251Ah), and then make the game display the Pokémon's picture - the game will break just before the graphic is decompressed, and the ROM bank will be shown in the bottom right on the statusbar. Simply multiply this by 4000h to get the bank's address.
The two pointers that you have are for the front and back picture respectively, and they are placed one after another in most circumstances (well, all circumstances I've looked at anywho).
Here's how I did Pikachu... First I went to Pokémon Yellow, and looked up Pikachu's stat bytes, 383DEh + (25 * 1Ch), because Pikachu is number 25.
1923 371E 5A32 1717 BE52 5555 4D49 4E54 2D00 0000 B183 8DC1 C318 4200
The highlighted bytes are the ones we're interested in. The 55h means the picture is 5x5 tiles (66h and 77h mean 6x6 and 7x7), and then the 554D and the 494E are the pointers to the graphic.
Using standard knowledge, we convert these to 0D55 and 0E49 respectively. The distance between these addresses is F4h, henceforth is the size of the compressed graphic.
By using the method mentioned above, we can determine that the bank Pikachu's picture is in, is bank 0Bh (address 2C000h)
so, apply the pointer to get 2CD55 as the address for Pikachu's graphic. Grab the F4h bytes from there.
Simple. Now do the same with Pokémon Red to find Pikachu's graphic at 2CD7D (note you should also check the stat bytes just to make sure that there is enough room to copy the graphic, in this case we have 10Eh bytes to use, when the graphic we are copying is only F4h so it's all good) and all you need to do is overwrite the F4h bytes from Yellow, to that address! No need to worry about padding with 00's or anything, as the compression scheme works in such a way that it stops decompressing when it has the required amount of bytes (ie it can tell when the picture is complete).
Ah! For a minute I thought I had read thethethethe's before, but it was really DamnedMoose's that I had read some time ago. Thanks, thethethethe and Cartmic.
FYI, Virtual Game Boy Color is a bad debugger to use. Very old (hasn't been updated since 2000), and inaccurate -- try opening Pokemon Crystal to see what I mean. A better choice would be BGB or no$gmb. (though the free version of no$gmb can't debug games in color)
well i think some yellow ones are bigger than rb ones, i think that a picture is generally smaller when there's more of the white colour because of RLE or something
if you know about gameboy rom banks then you can just repoint the picture to the free space near the end of the bank you found the original picture in, provided it's not used up
for the front pics, from giegue's guide:
# : Effect on pokemon
1st: pokemon number
2nd: HP rating 0-255 higher is better
3rd: ATK rating 0-255
4th: DEF " "
7th: Type ##1
8th: Type ##2
9th: Rarity factor 0-255, higher is rarer
10th: EXP factor, 0-255, higher is more points
1th: Picture size? (not completely sure how this affects the picture)
12, 13: Pointer value for picture facing you (enemy)
14, 15: pointer value for picture facing enemy (your pokemon)
16-19: attacks known at level 1
20-27: Which HM's and TM's the pokemon learns. (probably 64 binary switches in order)
i wrote locations for pokemon in rby further up this page, when you go to them in your hex editor you'll land at the pokemon number you should be able to find the pointers from there