I wanted to write an as-simple-as-possible tutorial on inserting new sprites into the Fire Red rom because, well, I was having trouble with it and finally got it to work. :)
Special thanks to JPAN for helping me understand how to set up everything properly with his hacked engine, which is needed for this tutorial.
Thanks to the following threads:
http://www.pokecommunity.com/showthread.php?t=152021 - by *Poliwag*
http://www.pokecommunity.com/showthread.php?t=142067 - by Darthatron
http://www.pokecommunity.com/showthread.php?t=194695 - by mozzer0734
For which I wouldn't have been able to learn how to do this without.
Also thanks to JPAN's Fire Red Hacked Engine.
Hopefully this will help people who are not yet adept in Hex Editing. You will need:
Fire Red Hacked Engine
Hex Workshop (or any Hex Editor)
Free Space Finder
Overworld Editor - Rebirth Edition
Firstly - back up your rom! Do not start this without having a backup of your Rom available.
Step 1 - Applying the Fire Red Hacked Engine
Once downloaded open it up, enter the Hack Applier Folder, and open the "Hacked Fire Red Engine V 1.1.ips" file. Patch it to your rom - don't worry about it replacing anything important that you've already hacked. Everything should be fine (unless you used any original scripts from Fire Red in your hack - those will be erased and you'll have to replace them). :)
Just a little information about how the Fire Red hacked engine works (might be somewhat difficult to comprehend :P):
The first table we're dealing with (offset at 0x1A2000) is a table with pointers to other tables. The first pointer of this table is the original table for the OW pointers in the original game. We'll be adding pointers to our own table from here. We can add pointers to 256 of our own tables. Each of our own tables can hold 256 pointers (except the first one, which holds only 240). Each of these pointers points to one of our new OW's data.
Our new OW's data has a pointer in it which points to frame data pointers. Each of these has about (usually) nine which point to the data for the frames (9 frames for each OW usually). And each of the data for our frames has a pointer to where the actual image is found. That's a lot of pointing! But that's what has to be done and that's what we'll be doing - inserting a pointer in a table that points to a table that has a pointer that points to data containing a pointer that points to more data containing many pointers that point to one frame of our OW image.
So that's that.
Great, now we have what we need to insert new sprites into our game. We can now move onto Step 2.
Step 2 - Finding the Free Space Needed
A block of data that directs the game to another area of data.
Each pointer contains 4 bytes of data.
A byte is just a bit of information. It's two numbers (or letters) side by side. So one byte = two numbers/letters.
Now the location of our OW table pointers is already determined. We'll putting them at offset 0X1A2004.
So next we need to find where we're going to put our First New OW Table.
So in order to figure out where we should put our first OW table, we should calculate the number of bytes we need. Since we'll need space for 256 sprites, and each pointer for one sprite is 4 bytes, we'll need 256 * 4 = 1024. So we'll need 1024 bytes of free space for our first table.
A block of data unused by the game. This is represented by FF, which is basically blank data. If you see a bunch of FFs, you can be pretty certain that the game is not using this for anything and it's safe to replace.
For me, I like to just play it safe, because I'm going to want to add more OWs later, but I just want to start with one, so for the new location of my OW's data, I'm going to use 0x900000 which has plenty of space. However, if you'd like, you can use Free Space Finder to find the amount of space you need somewhere in the Rom (700000 and up I think is the most safe areas to use). Open up Free Space Finder.
Load your rom - File > Open Rom = select the Rom you want to edit.
Click "Search from Offset" - you can change this to 700000, or leave it at 800000 - for me, I'm using 900000, just because I'd like to leave any free space in 800000 for scripting. There's no need for it, but I want to do it that way so it's more organized.
So 1024 is the number of "Needed Bytes" we need to put into Free Space Finder. Write that in, and click "Search". I come up with 900000 in my search, since I started searching from 900000. So that's my "First New OW Table" offset. Please write that down somewhere.
First New OW Table - 900000
So the next space we need to find is for the location of our new OW data.
Now how much free space do we need? Well, that depends on how many OWs you want to insert. The data for each new OW contains 36 bytes of information.
Now, you will need 36 bytes of data for each OW you want to insert. So let's assume you want to add about the maximum # of OWs for the first table - 256. Multiply the number of OWs you want by 36. In this case - 256 * 36 = 9216. We need 9216 bytes of free space.
9216 is the number of "Needed Bytes" we need to put into Free Space Finder. But you will want to start at a new "search from offset" point in Free Space Finder. Because each pointer in your New OW Table is 4 bytes long, you'll need to start searching from that offset at least 4 * the number of sprites you want to insert for this table away. We're making space for 256 sprites (the maximum), so 256 * 4 = 1024 bytes. You'll want to search for free space exactly 1024 bytes away from your New OW table offset (900000). But first you have to convert the bytes to hex - you can use a hex calculator which is included in Hex Workshop, or just know that the 1024 converted to hex is 400. So add 400 to your new OW table offset (900000) and you have 900400. Start your search there. Because I like to keep things simple though, I will use 910000 as the offset for the First New OW Offset. So write down that number.
First New OW Offset - 910000
This is the name for where any bit of data is located. For instance, if the data for Bulbasaur were at 0000001 (it's not), that would be Bulbasaur's data offset. With hex, you have the information and you have the location where the information is stored - they use numbers and letters (1-9 and A-F) to identify themselves. Think of it like an X-Y chart. X (horizontal) is all the data. Y (vertical) is where the data is being stored (the offset).
Now, you might be aware that each overworld has multiple frames.
A picture. In order to make something look like it's moving, you need two or more frames. To make the typical OW look like it's moving, the game has at least 9 frames - Frame 1 = Looking forward; Frame 2 = Looking away; Frame 3 = Looking to one side; Frame 4 = Stepping Forward 1; Frame 5 = Stepping Forward 2; Frame 6 = Stepping away 1; Frame 7 = Stepping away 2; Frame 8 = Stepping to side 1; Frame 9 = Stepping to side 2
First let's find some free space for the location of our Frame Data pointer. Then we'll find free space for the Frame Data itself. The Frame Data pointer, as you may have guessed, points to the Frame Data. For the Frame Data pointer, we need 72 bytes for one OW, or however many frames that OW has * 8. We will be using the standard 9 frames, so 9 * 8 = 72.
Now, take that number (72) and multiply it by the number of OWs you'll want to add. I'll want room to add 256 OWs, so 72 * 256 = 18432. This next bit of data will need 18432 bytes.
You will want to start at a new "search from offset" point in Free Space Finder. Because each OW is 36 bytes, you will need to search at least 36 bytes away from the location of you new OW - but I recommend searching 36 bytes * the number of OWs you want to insert, so you can use all that free space in-between solely for your OW data. So 36 * 256 (# of new OWs) = 9216. Convert that to hex (2400) - Add that to our New OW offset (910000) and we get 912400. Start your search there. Because I like to keep things simple though, I will use 920000 as the offset for the Frame Data pointer. So write down that number.
Frame Data Pointer Offset - 920000
Lastly, let's find free space for the frame data itself. I'll be using 930000 because it's simple. :)
If you'd like, you can search for free space. Since each offset for the Frame Data Pointer of one OW is 72 bytes, you will need to multiply 72 * the number of OWs you will be inserting (256) = 18432. Converted to hex = 4800. Add that to the offset for your frame data pointer (920000) = 924800. Search from that offset for about 1000 bytes of free space. Now write that offset down.
Frame Data Offset - 930000
Now we have all our offsets figured out:
Pointer to First New OW Pointer Table - 1A2004
First New OW Pointer Table Offset - 900000
First New OW Offset - 910000
Frame Data Pointer Offset - 920000
Frame Data Offset - 930000
Step 3 - Adding a New Table Pointer to the Existing OW Pointer Table
So click Edit > Goto (or control G; or this button toward the top: ) and write in 1A2000 - making sure the Hex button is clicked. You'll see this data:
B0 FD 39 08 B0 FF 39 08 B0 FE 39 08
with a bunch of FFs before it and a bunch of 00s after it. The first four bytes are a pointer to the original OW table in the game. We don't want to touch that. The next 8 bytes aren't necessary and can just be replaced according to JPAN, so I recommend replacing them with FF or 00 right from the start so they're out of the way. So now we might see something like
B0 FD 39 08
with some FFs or 00s around it. As I said, the "B0 FD 39 08" data is a pointer to the original OW Table.
Now, let me just explain something. When the game "points" to another offset, the way it writes out the pointer is a little funky. Take our pointer to the original OW Table. It is "B0FD3908". So you would put that in to search for (Edit > goto) if you wanted to find that data in Hex Workshop, right? Uhm, no. The bytes are reversed. So while B0 is at the beginning in the pointer, in the actual offset it's at the end. So it's really: 08 39 FD B0 and not B0 FD 39 08. We can also just ignore the "08" at the beginning - it's important, but not for finding the offset. So the offset for original OW Table is actually 0x0039FDB0 (the 08 becomes 00 when searching for the offset, you see). Understand? :)
Now that that's explained, let's go ahead and input the data for the pointer to our First OW Pointer Table Offset. Mine was 900000.
So now let's reverse that to 00 00 90 and don't forget to add the 08 - 00 00 90 08. Now we want to write that number into the offset following the one for the pointer to the original OW table. So it would look like this:
B0 FD 39 08 00 00 90 08
Go to File > Save and you've inserted the pointer to your first OW Pointer Table.
Step 4 - Adding New OW Pointer to the New OW Pointer Table
Edit > goto and type in 900000. You should see a sea of FFs. This offset is where we're going to be putting the pointers to the data for our new sprites. We've already determined the offset for our first new OW offset.
So that's the pointer we want to put at this offset. So reverse it and add 08 - 00 00 91 08. That's what we want to type in at this offset.
File > Save.
Step 5 - Adding New OW Data
So I go to Edit > goto and type in 910000. Lots of FFs, right? So what kind of data do we want there? Well, me, I want a nice roomy OW. So I want one that's similar to the hero riding his bike, because it's nice and square, with lots of room on each side. However, you can pick any OW you want to use as a basis. All you have to do is find its data. How?
Well, the data for all the OWs is located at offset 3A3BB0. Edit > goto and type 3A3BB0. Each bit of data is made up of 36 bytes. After 36 bytes, we see data for the next OW. So how do you find the OW you want? Well, let's take the second OW in the game, which is the hero riding his bike. Because it's the second OW, it's exactly 36 bytes away from 3A3BB0. The second overworld is actually OW #1, since the first OW starts at 0.
So the formula for calculating how many bytes away from the offset it is would be [OW #] * 36. You can find the OW # by opening up Overworld Editor. So if you wanted to replicate the tree sprite with its animation, you would find it in Overworld Editor. It's Index number is 61. So to find how many bytes away from 3A3BB0 the tree's data is, it would be 61 * 36 = 2196. Now simply navigate to 3A3BB0 in Hex Workshop and go Edit > Select Block and put in 2196. Scroll down to where the selection ends. This should be where the tree data begins - you can find the tree offset # by looking over to the right. It's under Data Inspector. Click right after the selected data and look at "Data at offset" number under Data Inspector all the way to the right. The Tree data is at offset 0x003A4444. Now to copy this data, you would just go to edit > select block and copy 36 bytes of data (make sure Dec button is clicked).
Okay, but I'll be using the hero bicycle OW, which is located at offset 3A3BD4. Go to Edit > Select Block. Make sure the "Dec" button and "Size of Block" button is clicked. Now type in 36. Select OK. The 36 bytes which make up the the data for the OW of the player riding his bike has been selected.
Then go to edit and copy and you have copied the info for the main hero riding his bike.
So now we have our basic structure for our new OW. Let's navigate back to the offset of our new OW.
This is where we want to place the data for our first new OW. Edit > goto - 910000. Once there, go to Edit > Select Block and once again select 36 bytes. This is important because you don't want to add any bytes, you want to replace the free space that's there. You will have selected a bunch of FFs, I presume. Good! FF is a byte that has no info in it, so that's free space. :)
Now that you've selected 36 bytes of free space at the offset you designated for the First New OW Offset in Step 2, go to Edit > Paste. Now the data for the hero riding his bite sprite has been successfully inserted at the offset for our new OW.
File > Save
But we don't want to use the data for the hero riding his bike - that's just a template. We want to make our own OW. To do that, we need data for our own OW's frames.
Now the OW data for the main hero looks like this:
FFFF = Starter Byte
00 = Palette Number
11 02 11 = Sprite validation.
0200 = This is equal to the second 4 numbers in the Frame Data Pointer; this is the size of each frame
0010 = Width
0020 = Height
0110 and 0000 = oam data. Do not modify!
1@ 10373A08 = Points to @3.
2@ 9C373A08 = Void pointer\ unsure.
3@ 70343A08 = A pointer to @5 lol.
4@ A0003A08 = Sprite Pointer
5@ FC1C2308 = Pointer to pointers which point to code that loads the sprite through the ewram into the sprite block of the vram and its data into the oam.
Okay, with that said, what we really need to change is the data for the Sprite Pointer. So scroll to the end of the data for our new OW, right before all the FFs appear. You want to navigate 8 bytes to the left of this, so just hit the left arrow on your keypad 8 times. The four bytes in front of you are the pointer to the Frame Data Pointer. For me, that data is 40 01 3A 08, or reversed it would be offset 3A0140. I want to change this to the free space I designated for Frame Data Pointer Offset.
Reverse that number to - 00 00 92 08 and then type it in.
File > save. Now our new OW is pointing to some free space for the animation frames of our OW.
All the data for our OW is complete - now to add the data for the OW's frames.
Step 6 - Adding New OW's Frame Data
Edit > goto type in 920000. Lots of FFs, right? What goes in this area is a little complicated. First thing's first - the data for each frame of your OW is 8 bytes long. The data consists of a pointer to the actual OW frame, and another bit of info that relates to the size of the OW.
Okay, so we want to fill in 8 bytes of data here, right? So that would be:
FF FF FF FF FF FF FF FF
that we need to replace.
The first four bytes are replaced with the offset for our Frame Data that we determined in Step 2.
Don't forget to reverse it and add 08. So the first four bytes for the first frame of our OW would become:
00 00 93 08
So then what about the second four bytes? This is a little more complicated. According to *Poliwag* in his tutorial, this data can be found through some calculation - Multiply the height by the width after converting it to hex and divide it by 100. Well, that's all somewhat complicated, and didn't work well for me anyway. So ... I recommend using the game's data as a template.
Since I used the hero on a bike as my template, I'm going to go to that offset: 3A3BD4. Edit, select block = 36.
Go back 4 bytes and select the 4 preceding bytes, which are 40 01 3A 08, or offset 3A0140.
Let me navigate to that - edit > goto 3A0140. Now I see the template they used. The first 8 bytes I see are A8 1F 36 08 00 02 00 00. So what does this mean? Well, the first four bytes are the pointer to the bike-riding hero's first frame. Disregard that. The next 4 bytes - 00 02 00 00, are the bytes I need to use when making my OW.
So do the same for whichever template you're using, or if you're using my template, know that for the second four bytes we will be using 00 02 00 00. Okay? Now go back to your Frame Data Pointer Offset.
Edit > goto = 920000
Okay, so the first four bytes we type in here are the offset of our Frame Data.
Reversed it's 00 00 93 08, so type that in. Now the next four bytes are the bytes we discovered a moment ago, in the case of using the bike-riding hero OW as a template, it is 00 02 00 00. There you are, you've just created data for the first frame of your OW. But we want to have 9 frames all together, right? Okay, now it gets a little tricky.
You're going to need to use Hex Workshop's Hex Calculator. You should see a dropdown menu that says ASCII. Next to it is a picture of a calculator, this picture:
Type in the Frame Data Offset - mine is 930000. You want to add the number, reversed, of the second four bytes that we found a bit ago. For mine it was 00 02 00 00, which reversed is 00 00 02 00 - ignore any zeros in front and it becomes 200! So I'll be adding 200 to my offset.
930000 + 200 in my Hex Calculator = 920200. Reverse it and add 08 = 00 02 93 08. Type that in for your pointer to the second frame. Type 00 00 02 00 once more. And continue on until you have an equal number for each of your frames. I'm doing 9, so I'll have 9 sets of 8 bytes of data.
When finished, you should have 72 bytes of data. You can check to make sure everything's been input correctly by clicking at your offset and going to edit > select block and selecting 72 bytes. If all #s are selected, and only FFs surround your block, you've probably done it right. Mine looks like this:
00009308 00020000 00002398 00020000 00049308 00020000 00069308 00020000 00089308 00020000 000A9308 00020000 000C9308 00020000 000E9308 00020000 00109308 00020000
And now you've added the pointers to each of the frames of your new OW.
Step 7 - Editing your new OW in Overworld Editor
Name = Pokémon Fire Red (English)
SpriteBank = &H3A3BB0
SpritePaletteHeaders = &H3A5158
SpriteCount = 153
the 3A3BB0 in SpriteBank becomes the location of your first new OW Offset.
The SpriteCount becomes the number of new sprites you've added. I've only added one, so mine will be changed to:
Name = Pokémon Fire Red (English)
SpriteBank = &H910000
SpritePaletteHeaders = &H3A5158
SpriteCount = 1
Now open up Overworld Editor. What you should see is a bunch of black frames. Now you can draw or insert any OWs you want into them! Congratz! You can change the Palette here, so don't worry about doing that in Hex. And that's how you add a new OW to your game.
Step 8 - Adding the Sprite in A-Map
Okay, so for our first sprite we put 00 as the picture number.
Now we have to get the game to know we're using a different table. We do that by using the unknown variable directly below the picture number.
The sprite we're inserting is located in our first new table, but remember that the original table comes before this. So it's actually the second OW table in the game. So the first original table is 00, while the second table (the new table we inserted) is 01. So for the unknown data below this, we would write 00 01. If it were the ninth table we'd put 00 09 - the tenth table would be 00 0A.
The sprite will not show up in A-Map. It will show up in game, however. Like so:
Just make certain you set the right numbers up, or you'll end up seeing invisible sprites and the hero OW itself will vanish when you near the OWs.
Once you've done all this correctly, you will be able to input and view as many OWs as you can imagine in your game!
Lastly, about adding new additional OWs after you've added the first. Just make sure you search from your new offsets when looking for free space so you make sure you don't copy over any of your previous work. The sprite table is done, you just keep adding offsets after it, no biggie. Just do the same for everything else. When adding the data for your next OW, make sure it goes directly after the previous one's data and make sure you write down and remember that offset.
I hope this tutorial has simplified this a bit. Criticism or suggestions for how to make it simpler and easier to understand are welcome. :)