Howdy everyone, hope you’re having a hackful day. I accidentally posted this when I wasn’t finished, but here’s the finished product:
It seems everyone who uses buildfiles knows how to repoint tables except me lol. So, I decided to understand how to do it more, and then write a guide on it. Fair warning, I’m rather dumb, and I don’t know a lot of terminology that probably exists, and I may not be as articulate as a lot of the other people here who’ve helped me figure this out. I’m here to do my best and go over something I think should have a clear guide, given how important it is and how much we take it for granted since you’re able to just hit “expand list” in FEBuilder (no hate, I love FEBuilder dearly).
However, I’m going to assume you have enough knowledge on buildfiles to the point in which you are now asking yourself “I think it’s time I start adding more _____ into my hack, how can I expand the current _____ table to do so?” Since we have a lot of space to work with, it’s often easier to just add new entries into a table, rather than replace existing entries. Let’s get started!
Repointing using CSV Inline Expansion
First, I’m going to go over inline expansion in the CSV’s. This is actually pretty easy, and doesn’t take too many steps. All of the CSV’s I have were generated with n2c on all of the FE8 Nightmare Modules. If you don’t know what that means, here is a good place to start.
Let’s repoint the class data table. This works only when Expanded Modular Save (EMS) is installed in your hack (it comes default in SkillSystems, make sure you uncomment #define USE_SAVE_EXPANSION
in your Config.event
file). Most other tables can be repointed no problem, but the class table specifically is very weird.
First, open up the class data table CSV, and look in the upper left corner. You should have the value 0x807110
in that cell. That’s the address where the class data table is located. Write down that number, and change that cell to INLINE NewClassTable
. What did we just do? Well, instead of going to 0x807110
and writing all of this class data into the ROM at that offset, we instead are creating a label called NewClassTable
in freespace, and writing all of our entries there instead.
However, we still need to tell the game to reference the class table at the new offset, rather than the old offset. To do this, write this somewhere in your defintions event file:
#define ClassTable NewClassTable
I do it this way since a lot of other things use ClassTable
to reference the class table, and since NewClassTable
is a label for an address in freespace, any time ClassTable
is referenced, it will point to NewClassTable
.
Next, we are going to find all of the pointers to the old class table, and change them to point to NewClassTable
. Open up a clean FE8 ROM in your hex editor of choice (I’m going to use HxD) and search for the address of the vanilla class table using Ctrl + F
(remember Little Endian).
If you typed the address in correctly, it should now show up somewhere in the ROM. Like so:
If you look in the bottom left corner, you can see the current Offset in hex. This is the address of the pointer to the class table. So, let’s make an .event file full of repointers for everything we’re going to repoint. In this file, add your PUSH
and POP
, ORG
to the address that is given in the bottom left, and then below that just type ClassTable
(or NewClassTable
, but since we defined ClassTable
to be NewClassTable
it shouldn’t matter). It should look like this:
Before I move on, @Snakey1 has a big repointers.event file you can use if you don’t feel like doing this manually. I’m basing this process on this so if you are curious on how to do this in general, keep on reading!
Let’s cycle through the results using F3
(if you want to go backwards, use Shift + F3
). Replace the rest of the pointers using the same method, and you should have something that looks like this:
Congratulations! You’ve finished repointing the class table. Note: when you compile everything and you’re getting a warning along the lines of Redefining ClassTable
, that means the label has already been defined, and you’re redefining it to be something new. If you don’t want that warning, just find out where it’s being defined and then change it to our new definition.
Now in many cases, this is all you need to repoint these csv tables. INLINE LabelName, find and replace the pointers, done. However, if you try to add a class to the class table, and you try to move, hover over it, check stats, etc, the game will crash. Why? Because the class table is really weird. Also why: because there is no associated moving map animation. Open up your moving map animation CSV and do exactly everything we just did.
-
Write down the top left entry (should be
0x9A2E00
), and change it toINLINE MovingMapAnimTable
. -
Find all the pointers to it, and replace them like so:
Note: If you enter in an address, and when you compile you get a bad alignment
error (or something of the like), you might have just coincidentally found a string of bytes that match the address of the table you’re looking for. If you get that error at an offset, just remove the repointer for it. If you look in the hex editor, you will notice that it is not 4-aligned like all of the other addresses that are valid.
Now to test that we actually have a working extended class list, let’s test it out! You can test it any way, I’m just going to copy and paste the Cavalier class (class 0x6) at the bottom, and then change the class number to 0x80. After that, I’m going to copy and paste the cavalier’s moving map animation and AP to the bottom of the moving map animation table. Now insert a unit with that class somewhere in your chapter, run your MakeHackFull and it should work!
There you go! Now you can basically repoint and extend any list with a corresponding CSV. It’s pretty easy once you get the hang of it.
Manually Repointing Tables
The next method of repointing does not include CSV’s, however it’s the same basic concept. We are changing an existing table’s location to freespace so we can extend the data freely. Our exercise for this part is going to be expanding the battle animation table. So, let’s get into it!
First we want to find out where the battle animation table is, but we also need to find out the size of the table is as well. I use FEBuilder to get this info because there’s a lot of great documentation in FEB. Open up FEBuilder and open a clean FE8 ROM. Go to Image Editors
-> Battle Animations
and look at this address here:
We can see that the table address starts at offset 0xC00008
, each entry has a size of 32 bytes, and that there are 201 entries. Now open up your clean FE8 ROM in HxD and go to offset 0xC00008
. From there, press Ctrl + E
to select a block of data. Calculate 201 * 32 (6432) and enter it in like so:
Note: I entered the length values to decimal since that’s what FEB gives the table sizes in, but HxD changed all of those entries to be in decimal (despite initially entering start offset in hex). Once you select OK, a big block of data should be highlighted. Now go to File
-> Save Selection
and save this as ClassAnimTable.dmp
Now that we have the vanilla class animation table data, let’s move it to freespace. I always keep things organized by text, tables, graphics, etc, so I’m going to write this in my Master Table Installer event file, but you can write it anywhere in freespace.
If you’re like me, and need to know everything before you can even do it, I understand your skepticism. Let me tell you what I did to the best of my abilities:
-
ALIGN
andORG
Configured our address for our actual label,NewClassAnimTable
-
ORG CURRENTOFFSET + 0x20 * 0x200
This is where we actually expand the table. I’m allocating 0x200 entries (512 in decimal) for battle animations. This is completely overkill and unnecessary, but this is here to show you that you can, indeed, expand this bad boy into space. -
PUSH
andPOP
are self explanatory. -
ORG NewClassAnimTable
andincbin "ClassAnimTable.dmp"
will bring us back to the start of the table where our new label is, and then fill up some of the space we allocated with the vanilla entries that already exist in the table. There are 201 entries in vanilla, so with this set up, we will have 311 remaining battle animation slots to insert.
While a bit more complicated here, I hope you at least understand what we are doing here, we need to save all of the vanilla animation data for all of the vanilla classes. We can still reference each animation with the same offset, but now the entire table is stored in freespace so we can safely increase the amount of battle animation data in our hack if we want to (which you probably will want to).
Now the next step is to change all of the pointers to the vanilla class table to instead point to our newly repointed battle animation table! Use the repointers.event file if you want, but if you want to do it by hand, here you go:
Once again, open up HxD and search for the vanilla animation table address, 0xC00008
. Use F3
to cycle through each instance of the pointer and, in our repointers file, ORG
to each offset and replace it with NewClassAnimTable
. The final product should look like this:
Remember, if you find any instances where the result is not 4-aligned, that is NOT an actual pointer to the address, and you will get an error when you compile. When searching for these pointers, I got a lot more results than what I wrote down above, but these are the correct addresses.
Now, I’m not going to go over battle animation insertion entirely in this guide, but I am going to have you do one more thing with how I set this up. If you’re using animation assembler, you should have the AnimTableEntry
macro defined. I want you to redefine that to be this in your definitions file:
#define AnimTableEntry(index) "ORG NewClassAnimTable - 0x20 + (index * 0x20)
Remember when I said I don’t quite understand how the “first entry is essentially nothing” thing? Well this also is part of that. The battle animation table specifically is very weird. The fact that we write - 0x20 + (index * 0x20)
just has to do with how the battle animation table is indexed when we repoint it this way. Once you have changed the AnimTableEntry
to be this, inserting battle animations should work just fine. Again, though, as much as I would love to, I will not be going over that in this guide.
If there’s documentation on how to insert something into some table, and you want to extend it like we just did, well, now you know how to do it! In this case, you can now insert more battle animations into your hack! If things break. I apologize. I’m very dumb and make many mistakes myself, but I hope this guide was still helpful in some way to you!
Credits
Special thanks to the #hacking_help channel on the FEU discord for helping me understand tables, ORG, and many other tools and tricks. More specifially I’d like to thank @Snakey1 for having his Legends of Avenir project public for us all to look at, as well as proofreading and helping me edit this guide. I’d like to also thank @Sme for her patience and help she’s given me overall and @Pikmin1211 for answering and helping me with many of the stupid questions and issues I’ve had with this stuff as well.