After some discoveries, I asked Darthatron if I could finish his old tutorial on Advanced OW Sprite Editing and he said yes. I recently fully discovered how the routine works which controls how many OWs you can have and I plan on sharing with you how to increase this limit.

However, first, here is the original tutorial who's thread was closed a while back with a little updated commentary from me. I will also include the offsets for the main english roms Ruby and Emerald. If you need more offsets and you can't find them on your own, just let me know.

Quote:

Originally Posted by Darthatron

Okay, in this tutorial I will teach you how to repoint, resize and increase the amount of OWS (Over World Sprites) in Pokemon FireRed. Sounds fun, right? :p

I haven't tested this in the other Advance Gen Games, but I'm sure it will work just the same. :)

Quote:

karatekid552- Confirmed. It does work for all Advance Gen games.

For this Tutorial you will need...

An English FireRed ROM

A Hex Editor

The latest version of VBA

A Free Space Finder

A Brain

Lesson 01: Understanding the Data.

Ok, let's take a quick look at the Layout of the Sprite Data, before we go any further. Here is what the first Sprites Data will look like in FireRed:

That's about it for this lesson, next we will learn how to resize the OW Sprite! YAY! *Cheers*

Lesson 02: Resizing an Over World Sprite.

Right, so if you remember correctly, before we looked at the Sprite Data, and it had the "Height" and "Width" Bytes stored there, so... Let's just change them, and see what happens. Why don't we make it a 32 x 32 Sprite now?

...And put it back into our Hex Editor. Next we will open up the OWS in our OWE.

Oh dear! Frame 0 and 1 seemed to have melded together! This means we have to repoint the Frames, YAY!
Ok, so all you have to do is follow the "Sprite Pointer", which is "A0003A08", or "0x003A00A0" when it's flipped. SO now, goto the offset "0x003A00A0" in your Hex Editor and look at the data. It should look something like this:

Code:

68BB350800010000

Now, we need to work out how many frames the OWS has. The Hero Sprite has 20 Frames, so open up your Free Space Finder and search for the Value of this Sum:

Ok, I found the Space I need at the offset: "0x00720A00" Lucky me. Now, I'm going to start Repointing all the Pointers.

Back to the Offset "0x003A00A0" in your Hex Editor and it's time to start the fun!

Alright, so replace the First Pointer with "000A7208", which now lead to the Free Space we found earlier.

Now, view that Frame and Sprite in your OWE. And see how it turns out.

Great! We now have a clear Sprite! Next we are going to want to do the same for every frame, so back at the Offset "0x003A00A0" we are going to move 8 more Bytes into the File and Repoint this Frame aswell!

So with the Free Space we found earlier, which was "0x00720A00", we want to add 128 Bytes, because that is the Value of the Sum we did before:

Code:

Value = (Height x Width) / 2
So, the new Offset will be: "0x00720A80"
And the new Pointer will be: "800A7208"

So, what we want to do it replace the Pointer at the Offset "0x003A00A0" with our new pointer, in my case: "800A7208".

Quote:

karatekid552- Some people find pointers confusing so here is a way to remember it: take the 6 figure long offset, and swap the first and the last bytes (the first pair of two numbers and the last pair of two numbers) then put 08 on the end. Also, here is a visual representation:

AX BY CZ -> CZ BY AX 08

Great! The second Frame is now clear as well! Do that for the other 18 Frames, and then you can start painting your new OWS! YAY!

Lesson 03: Adding for OWS to the game.

Finally, we can learn how to repoint the OWS and add more into out game! YAY! *Cheers*

Ok, what we are going to do it open our ROM in our Hex Editor...

*Opens ROM*

Right, now Goto the offset: "0x0039FDB0" And you will see a whole bunch of Pointers, right? They should look something... like... this:

Yes, that's right. Following one of those points will take you to the "Sprite Data", we looked at that data before (Lesson 01 & 02), cool huh? This is the location where AMap reads from, however, this isn't as far back as we can go...

Now, in your Hex Editor we are going to goto the location that points to this Table, and change it. So, goto this location: "0x0005F2F4", this should have a pointer to the table we just looked at, correct?

Ok, now open up your ROM in your FSF and search for this number of bytes:

Code:

Value = Number x 4

"Number" is how many Sprites you want to have in your game. For this example we will use 151, Which is 1 extra Sprite to the average 151 FireRed has.

Quote:

karatekid552- After a lot of experimentation with overworlds, I have found that this is not the case. FireRed actually has 152 total OWs (I will prove this later), Ruby has 218, and Emerald has 246. This is due to some people forgetting about OW number 00 and, in FR's case, 151, the S.S. Anne, which doesn't show up in A-map. So, keep in mind these new totals as you continue on.:) Darthatron will continue to use the A-map number of 151 for FireRed but it is 152. (Unless you don't like the S.S. Anne:p)

So.... In my FSF I will search for....

Code:

Value = Number x 4
Value = 152 x 4
Value = 608

...608 Bytes. However, due to my vast amount of laziness, and my really slow computer, I will just use the offset "0x00801000", write that offset down somewhere, alright so... Asuming we are still at the offset "0x0005F2F4", I will set the Pointer there to... "00108008".

Now, we have copy/paste the Table at the Location "0x0039FDB0", ONLY THE FIRST 151 POINTERS (604 Bytes), to the Location we just found, in my case "0x00801000". Now, if you did everything correctly, there should be at least 4 Free Bytes after the table has been pasted. With this free space we are going to add a new pointer to some free space where we will put our new Sprite Data...

Once again, open up FSF and search for some free space, this time search for 36 Bytes. Once again, due my huge amount of laziness, I will be using the offset "0x00802000". Back at the 4 Bytes that we have free after pasting the Pointer Table, we are going to add out new pointer. In my case: "00208008".

Now, in your Hex Editor we are going to look at the Hero's Sprite Data, located at "0x003A3BB0", and we are going to copy it all (36 Bytes). Then we will go back to our new free space, in my case "0x00802000", and we are going to paste the data we just stole from the Hero's Sprite Data.

Open your ROM up in a Map Editor and make a Sprite with the Picture Number of "151" and you will notice that the Map Editor doesn't appear to show any Sprite. However, opening the ROM in your emulator and looking at the Sprite it will look like the Hero.

Alright, now you just have to follow Lesson 02, using this Sprite Data instead of the First, and all should be fine. I think... I kind of lost track of where I was up to. If for whatever reason it doesn't work, post and I'll see if I missed anything... xD

Here is my table of equivalent offsets between games. I can expand this table fairly easily if needed:
[I would like to apologize for this being an image. I wanted code it as a table, but it appears the table system for PC has a few bugs, so I couldn't.]

I would also like to note that to use the increased OWs with an OW editor, I would suggest using NSE Classic since it reads from the table we just repointed, and not the secondary sprite table that OWERE uses. To use your new sprites, create an .ini file (instructions for this are in the NSE readme file) and point it to your new table. Then, open NSE and under options choose "Advanced Mode". From there, go back under options and turn the boundaries off. This was a major feature lacking from OWERE. Instead of this, it just gave the "subscript out of range" error.

Part 2.

Now that you know how to increase the amount of overworlds by repointing that nice big table, we need to take a look at what I like to call "OW limiters". In all Advance Gen games, there is a special routine that is carried out when an overworld is loaded onto the screen. This routine checks to make sure that the OW is a part of the table. If not, instead of letting the game crash, it just reroutes the loading routine to use OWs from earlier on in the table.

For those of you ASM enthusiasts, here is the routine that runs said checks in Ruby and FireRed. they are almost identical but Emerald is a little different, so we will discuss it later on:
Ruby

In Ruby, there is a total of 218 OWs (counting #00). If you notice, the second cmp command checks if the number in r1 (which is the OW number currently being loading loaded onto the screen using the hex equivalents for the numbers in NSE) is less than or equal to 0xD9 or decimal 217. In FireRed, this cmp is to 0x97 or decimal 151 and will branch only if less than or equal. This proves what I commented earlier being that there are 152 OWs because it is comparing to the numbers in NSE, in which the S.S. Anne is #151.

So, as you can see, that check was pretty basic. It was just the maximum number of OWs. But what about those other two? They both cmp for 0xEF (240) in both Ruby and FireRed, but what could they possibly do? After a lot of research, I finally understand how these are used. They allow for Dynamic OWs; OWs that can be placed on the map and then later modified to be something different. These checks make it so that OWs #240+ are dynamic in nature. Some main examples of how these are used would be the sprites in the Union Room in FR and how secret bases are done in RSE. I will discuss how we can use these to our advantage in Part 2.5.

So, what if you don't know all of this fancy ASM stuff? What do you do? It is actually pretty simple.

Open up our trusty Hex editor and change the following three offsets to the hex value of the number of OWs you want to have up to 239. If you want anything higher, you will have to deal with Part 2.5.

Ruby(AXVE)
•0x5BC28

FireRed(BPRE)
•0x5F2E0

*If you need offsets for different versions, just let me know. I will get them.

Now you have done it! You've successfully increased the amount of OWs in Ruby and FireRed. Yay!

But what if you have Emerald? I never want to leave any hackers in the cold, which is why I try to write my tutorials to support as many games as possible. In Emerald, the routine is fairly the same. However there is an extra ripple I want to make you aware of.

As you have probably noticed by now, this routine has four checks. I can tell you that the 1st, 3rd, and 4th checks match up in the same order that they do in Ruby and FireRed.

But what about that second check? After some guessing and playing, I figured it out. It checks specifically for this guy's sprite:

In all of the other games in which he appears, his sprites were kept together. However in Emerald, there is only one usable sprite: #69.

The other ones are at the end of the table, above the old limits, and auto default to other sprites when used in game. When you use sprite number 69, it activates a section of the OW loading routine that allows the sprite shown on screen to be changed (to one of his other colors at the end of the table) depending on certain conditions such as his location in the game (bank and map number) and the data of your save file.

In theory, this check could be used to create OWs that could be randomized, and ideally, unique, per game save. I don't know if it can be done, but it definitely would be a cool feature.

So, when you are expanding your OWs in Emerald, keep this guy in mind and try to leave his sprites in order and when you change one, change them all. He is the only NPC sprite to vary like he does, so it is kind of cool.:)

As I said before, the other three checks work exactly as they do in Ruby and FireRed so here are the offsets that need to be changed in Emerald to the number of OWs you want to have. Since Emerald has 246 OWs already, your best bet is to just go straight for 255 and change the main limit locations to 0xFF, but remember, since this goes over 239, you will have to deal with Part 2.5:

Emerald(BPEE):
•0x8E6C4

Now you know how to get the most OWs possible without having problems with the dynamic ones in the major Advance Gen games.:D Have fun!

Part 2.5: Dealing with Dynamic Over Worlds

Above you learned that in RSE, OWs 240+ are used for secret bases. If we change their checks, then it prevents your dolls and cusions from being used in your secret bases. So, Darthatron and I worked out a way to fix this. I suggested just checking if you were in a secret base and then running the original routine if that was true. He found where the secret base byte was and I tried writing a nice routine. I failed miserably after 2 hours of hard work, lol. Then, Darth wrote up a routine in 10 minutes to fix it. (I guess I need some more practice, haha) What his routine does is it just skips the checks used for secret bases when you are not in them. After we worked out the bugs in Ruby, I ported it over to Emerald. Simple, but effective. There are only 3 problems (2 of which I provide a fix for):

1) Outside of S.B.s, sprite 240 is the always the opposite gender of the player making it the rival sprite. I don't have a fix for this yet. You can still do it the old fashion way by having two different sprites on the map and only showing the relevant one.

2) A-map loads the OWs by searching for the routine that comes just before the pointer. This fix changes that routine, which means A-map won't be able to load the OWs without a change to the .ini file. I will provide this change attached at the end of this post. My best suggestion is to make a second copy of A-map that will use this .ini so that you won'thave to keep switching them out.

3) This one is really simple; your player's rooms are not secret bases, so the decorations won't be diplayed correctly. Just change the map type in A-map to "Secret Base" for those 2 rooms and you should be fine.

With the above mentioned, let's move on to how to apply this hack. If you are decent with ASM, then feel free to do it yourself. Here is the source code:

Remember to change your A-map .ini (best to just create a second copy of A-map to use it), that the rival sprite won't work (Maybe I'll find a fix:D), and to change your rooms' map type to Secret Base.

Dealing with FireRed

In FireRed, I mistakenly assumed (you know what they say about assuming:p) that we wouldn't have any problems because we don't have secret bases. I was very wrong. The Union Room definitely uses dynamic OWs and it is most likely also the case when it comes to the trainer tower. So, I have created another port of the Ruby routine for FR. This routine, like the others will only allow the dynamic OWs to be dynamic on maps whose type is 09 (secret base). On any other map, these OWs will act like regular OWs, just showing up like you see them in NSE.

-Just as a side note, when I was porting this routine, I noticed that, besides offsets, both routines are exactly the same. Just a little bit more proof for the argument that FR is a heavily modified version of Ruby.:p-

Once again, I know you probably don't understand much of that fix, so I will dumb it down a lot:

~FireRed Fix (BPRE)~

-Just as a fair warning, I did not test this routine since it was all just offset changes from Ruby. I have double-checked all of the offsets, so it should work. If you have a single problem, be sure to let me know.

1) Paste both of these lines of code somewhere in the free space of the rom using a hex editor:

Also, if you notice any other areas where the sprites do not appear correctly, try changing that map type to 09 (secret base) in A-map. Places like the Battle Tower/Frontier most likely use dynamic OWs. If you find a location not listed here, feel free to comment with it. I will try and make a list of all of the locations.

--On a final note, Advance Map was never designed to support expanded OWs, therefore, it is highly likely that your sprites will not show up properly in A-map.--

Well, that should be it,

Good Luck!

~Credits:~

Darthatron- For putting up with my many, many questions and providing the original main OW limiter in FR. Also for his original Advanced OW tutorial which was the main reason I downloaded a hex editor!

Shinyquagsire- For also putting up with my many questions and his ASM tutorial.:)

Jambo51- Once again, answering my many questions, and helping me with my grammar.:D

Bela, ShinyDragonHunter, and MrAPT1- For listening to me for hours on IRC and constantly throwing out suggestions on what each check could mean and how they relate. Bela especially for forcing me to take a closer look at the S.S. Anne and SDH for making me look into Emerald.

HackMew- For his ASM tutorial which got me started on learning ASM. It took me three tries to finally work up the courage to read the whole thing:p.

Locations that need to be changed to map type Secret Base:

Quote:

Ruby:
-Your Room
-Your Rival's Room
-Battle Tower
-Pokemon Contests
-Southern Island
-Locations which show Team Aqua and Team Magma (they do it this way to save space between Ruby and Saphire)