Snake's Pit of ASM (and Other Stuff)

Today I’m proud to release something I’ve been teasing unreleased for far too long out of fear of it being buggy, but today I’m confident enough for a casual release.

TableManager

TableManager.exe is a new CSV assembler for EA buildfiles. Although similar in functionality to c2ea, TableManager is more versatile and friendlier. Download the exe and source code from my link in the OP!

Features and details

The primary feature of TableManager over c2ea is being able to combine multiple “ROM tables” that are indexed together into a single CSV file. Distinguishing where everything needs to be written to is accomplished by linking Nightmare modules to CSVs similarly to c2ea.

While c2ea assumes that you want to write the data in your table into the ROM just as it appears to you, TableManager allows you to organize rows and columns as you see fit in your CSV without necessarily affecting what you write to the ROM.

  • Sort columns in any way you like! TableManager compares the string found in the top cell of a column to a field found in a Nightmare module linked to the table in order to figure out where it needs to be written to. This means that column order is completely arbitrary, and you can even mix columns from multiple “ROM tables” together in a single CSV! I think the best example of this is the magic tables with the FE8 str/mag split. Isn’t it annoying having to have separate CSVs for those? Now you can have magic data right alongside other character/class data as if it was a vanilla stat, and TableManager sorts out where you want it all to be written! You may also leave empty columns.
  • Sort rows in any way you like! Or not if you want that! TableManager allows for writing each ow sequentially to ROM just like c2ea does, but it also offers a feature that treats the far left cell of any row to act as an index that you want that row to represent. This can be a value or an EA definition. With this option turned on, you would expect each row to be written with an ORG TableLabel + (FarLeftCellOfRow)*(EntrySize) format. The ultimate implications of this are that you don’t need to know the values of custom indices to work with them in CSVs, and you can reorder rows in any way you like! You may also leave empty rows.

Run the .exe with the -h flag for more info on command line parameters.
To use, you must pass in a table options file and an intended output file like so:

echo: | (TableManager.exe TableOptions.s TableInstaller.event --error_on_missing)

This is the command I use in my batch to assemble my CSVs. (The extra flag is something I like to use. Again use -h in the command line for more flags.)

So what is this table options file I refer to?

This file is a file that TableManager reads in order to understand how you want each CSV to behave. Here’s how it works.

  • Each CSV that you want to be assembled needs to be referenced by a CSV (FilepathToCSV) header.
  • Within each CSV header, you may link an arbitrary number of Nightmare modules with TABLE (LabelForThisROMTable) (FilepathToNMM) (OptionalAddingOffset) (Optional INLINE or FIXED to override the CSV INLINE setting for this TABLE only). The optional adding offset is to allow tables that are indexed together but with an offset to be combined into a single CSV file. This is most specifically included for the item usability/effect/target switch case tables. For example, I use TABLE ItemUsabilityTable Items/ItemUsabilityTable.nmm -0x4B for the item usability table because each index in the ItemUsabilityTable is 0x4B behind the ItemTable.
  • State whether you want this table to be written to freespace or not with INLINE (True or False) If False, the assembler will try to write to the vanilla offset in the Nightmare module.
  • For behavior in writing all rows sequentially ignoring the far left column, use WRITE_SEQUENTIALLY (True or False). If not writing sequentially, 0-space will be allocated using FILL in EA for the entire table, and entries will be filled in as the CSV describes them.
  • MAX_ENTRIES (MaxNumEntries) declares how much space you want to allocate for a table if you’re not writing sequentially. This is ignored if sequential writing is enabled.

Check the .py source code for a more detailed explanation on what each code does.

A few other notes:

  • TableManager supports negative numbers!
  • TableManager also supports data sizes that are not 1 byte, 2 bytes, or 4 bytes. Simply put the size of your data as you like in the NMM field, and TableManager will handle it. Note that this data is still little-endianed!
  • If TableManager doesn’t think you’re trying to write data to some offset (say you never reference ItemTable+0x35 in your NMM. This is unknown data off the top of my head I think), 0 will be written. The previous feature was included in order for easier writing of unknown data of irregular length.
  • TableManager has no automatic repointing feature. I recommend using my Repointers helper file here.
  • A cell left blank is assumed to be 0. TableManager will attempt to not write data and allow FILL to 0 out data if it thinks that 0 will be written for an entire row if it exists. This is done for the item usability/effect/target/etc tables being weird and any other tables with an adding offset.
  • Any table with an adding offset has an innate ASSERT when writing each row to ensure that every index that’s being written to exists. For example, if you try to give an iron sword (item ID 0 or 1 or something?) an item usability pointer, EA will give you an error because this assertion will fail because that entry in that switch table doesn’t exist. You probably don’t need to worry about this, and it should never cause problems for you. It’s just a failsafe.
  • For each cell in the far left column, only the first “chunk” of data when separating by whitespace is read. This means if I have 0x0A Manakete in the left cell of my row, TableManager reads this as 0x0A. This can be used to have sorts of comments on what a row is if you’d like to use hex indices.
  • In the table options file, make comments with @.

Rather than have BORING examples here, I invite you to check out working examples of TableManager in my Avenir Github: https://github.com/Snakey11/Legends-of-Avenir/tree/master/CSV/Tables

I don’t pretend to be a good Python programmer, so I probably made plenty of mistakes. I thiiiink I handled most errors I would expect, but please please let me know if you encounter weird traceback errors, if you see unintended behavior, if you have suggestions, or if something was confusing!

Have a happy Halloween! :skull:

11 Likes