Let's take back the word grasp. Far too strong of a word at this point.
Well, let's see if I can help with that a little bit...
Basically #VAR just declares a new variable, giving it a name and a type, so that you can initialize it later on, sort of like saying "hey, this here word 'foo', it's going to be a TABLE variable". #VAR is probably kind of useless (we can infer the variable's type by its initialization method), but it was part of Atlas so you'll have to take that one up with Klarth
#ADDTBL reads your table file from disk and checks it for e.g. syntax errors etc., and the #ACTIVETBL makes it the table to start from when translating text to binary. You only need to use #VAR and #ADDTBL once per table file, but you can switch back and forth between which table to use as many times as you want. E.g. for DW2, if you wanted to insert the item list, then the main script, then the monster list, you could do both #VARs and #ADDTBLs right at the start and then do #ACTIVETBL(nonScriptTBL) + item list, #ACTIVETBL(Table) + main script, and #ACTIVETBL(nonScriptTBL) + monster list. It gives you some flexibility in how you you organize your insert script.
* EDIT Going back over previous posts, I see that you provided some explanation how to compute this number (i.e. 0x1D050 / $07:9040) to 0x1D038 / $07:$9028). I still don't understand what's going on with those numbers but I see that we are using the HDR to change rom banks. I think I need to better understand how to verify where rom banks start and end and what's all going into this HDR number
#JMP says where to start writing data in the ROM, with an optional upper bound to prevent overwriting stuff you don't want to clobber if you aren't sure your new data will fit within the original space. Having an upper bound is almost always a good idea, but sometimes I'm lazy and don't bother specifying one.
The various pointer writing commands (there's a bunch of them, but #W16 is pretty useful for NES games) all take whatever ROM file address the insertion process is currently at, do some math on it to convert it from a ROM address to a RAM address, then write that RAM address to the ROM address you tell it to. For some systems that math is really easy (e.g. RAM address = ROM address), but for NES games, that math gets complicated by the cartridge's memory mapper. If you look at Atlas' documentation, I think the "correct" way to handle that is to set #HDR to the real size of the ROM file's header, create different custom pointers with #CREATEPTR based on which ROM bank you're inserting into and which RAM bank that ROM bank gets loaded into when the game is running, and then use those custom pointers to write the pointer values, but again, I'm lazy. With the default setting of linear addressing, pointer values are calculated as RAM address = ROM address - header size, or flipping it aroung, header size = ROM address - RAM address. So, by tweaking the #HDR value appropriately, you can get the right RAM addresses. As an example, when we insert the monster list starting at ROM 0x1D050, that's going to appear in RAM as $9040 (we know this because DW2 uses a $4000 RAM bank size [and we know that because FCEUX tells us the mapper number in its Message Log and we can look up mapper #1 on nesdev
] and everything except the fixed PRG ROM bank gets loaded into RAM at $8000 - $BFFF, so the RAM address is $8000 + (ROM address - $10 iNes header) modulo $4000 RAM bank size), so $1D050 - $9040 = $14010. On the other hand, the main script gets inserted starting at ROM 0x14010, but it appears in RAM starting at $8000, so the difference between ROM and RAM addresses is $14010 - $8000 = $C010, and that's the fake header value we use to make the math work.
Or in other words, the real iNes header is still $10 bytes long, but we can cheat with the math and pretend there's a different header size instead so that we get the right pointer values.
// update monster list bank/address pointers
That was to update the pointers to the pointers to the monster list to have the game load the new bank instead of the old bank. Pointers don't necessarily have to live in the same bank as the data they point to, but in this case the game code assumes the pointers and the data are in the same bank, so it was less work to let the game keep assuming that than to add new code to swap in a different bank after reading the pointers.
Is this stuff essentially rewritten code instructions telling the game where to access the new pointers you created above? You are suggesting I do this all on my own but dealing with this aspect of it seems far beyond my grasp at this point.
Yes to the first part. For larger chunks of code, you'll want to use an assembler rather than a text insertion utility, but for a small section like this where I was really only changing one byte, inserting the code as a sequence of text bytes is only a slightly horrible abuse of semantics
. For the second part, I didn't want to muddy the waters with a tutorial on ASM, but you can definitely work your way up to that later as and when you find you need or want to make changes that can't be made by changing text; one thing at a time!
I just realized I don't need to create new code, new pointers, etc. I can just have abcde update the existing pointers based on the existing list locations since I have room to expand. I think I might be able to figure that out!
That's right - you'll need to know where the existing pointers are (e.g. the spell list pointer is at 0x18036) and then stick a #W16 statement with that pointer address just before the data you want the pointer to point to. You'll also need to make sure you've got the right #HDR value in effect before the #W16 statement happens.
Out of mostly curiosity, I pulled up the rom data in a hex editor and I saw a ton of miscellaneous code appearing immediately after my new monster list that ends at appx 0x01D3E6.
Are you starting every insert with a clean ROM, or are you inserting new stuff on top of old stuff? Remember that time when you inserted the entire main script after the monster list and filled the whole ROM bank
? If you're inserting new stuff on top of old stuff, all that main script data will still be there instead of empty space.
This really isn't easy for me. I'd never say no to you wanting to be my project partner rather than my professor, but the problem is you also love translation and I thus have nothing to contribute to the partnership... Alas, your terrible student shall soldier onward!
If it was easy, everybody would do it
. Like many things in life, this will get easier with practice
This is a great idea and I thought about how helpful this would be, [...]
Oh, I should have remembered to check the wiki
before reverse-engineering the encoding myself. If/when you want to dump the Japanese text, you should check the wiki too. "Do as I say, not as I do"