News:

11 March 2016 - Forum Rules

Main Menu

Dragon Warrior 1 Spanish Translation

Started by werewolfslayr925, April 09, 2018, 12:38:48 PM

Previous topic - Next topic

werewolfslayr925

#40
Quote from: Psyklax on May 23, 2018, 05:38:25 PM
The pages on nesdev give you way more info on this than I ever could:
https://wiki.nesdev.com/w/index.php/Mapper

...

Hope that gives you some insight! I must say that once you get the hang of assembly, these chips are a godsend, because expansion can sometimes be as simple as I suggested earlier.

It all does. I didn't think of going to NESdev for that kind of thing, but that totally makes sense. I've been there quite a few times for other biznass.

Regarding the state of the project:

I'm trying to insert the menus and stats into a copy of the ROM to test things out, but Atlas keeps giving me a weird error:

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.


Since you're my support team, I decided to ask you :P

Here's the code I've got in a file marked "dspmensta.txt"


// Define, load, and activate a table (replace "dw_es.tbl" with the name of your table file).
#VAR(dwSP, TABLE)
#ADDTBL("dwSP.tbl", dwSP)
#ACTIVETBL(dwSP)

// NES ROMs have a $10 byte header.
#HDR($10)

// Jump to the start of the script, set an upper bound on the available space so that you don't accidentally start overwriting other code/data if your script is too long.
#JMP($6FDD, $BCBF)

// Write a 16-bit pointer to the current address (which is $8038 because that's where we just jumped to)
#W16($6840)
Nom:<B1><80><86>Fuerza:<D8><80><87>Agilidad:<D9><80><84>VP<81>Máximo:<DC><80><84>MP<81>Máximo:<DD><80><82>Ataque<81>:<DA><80><81>Defensa<81>:<DB><80><82>Arma:<B8><87><83><B8><83>Armadura:<B9><87><83><B9><82>Escudo:<BA><87><83><BA>15o<92><88><80><80><80><80><80>5gm8x<8B>COMANDO<88><81>Hablar<84>Hechizos<81>Estado<82>Artículos<80><81>Escalera<82>Puerta<80><81>Buscar<82>Llevar<80><80>3gm8x<8B>COMANDO<88><81>LUCHAR<83>HECHIZO<81>CORRER<85>ARTICULO<80><80>bcF0x<8B>HECHIZO<88><D6><81><C0><E8><E9><A0>bcV0h<88><D4><81><BB><82><BB><E8><E9><A0>8iB0h<88><D5><81><BC><81><C8><82><BC><80><E8><E9><80>38B0x<88><81>YES<80><81>NO<80><80>38B0x<88><81>BUY<80><81>SELL<80>17o.}<88><81>A<81>B<81>C<81>D<81>E<81>F<81>G<81>H<81>I<81>J<81>K<81>L<81>M<81>N<81>O<81>P<81>Q<81>R<81>S<81>T<81>U<81>V<81>W<81>X<81>Y<81>Z<81>-<81>}<81>!<81>?<81>(<81>)<80><81>a<81>b<81>c<81>d<81>e<81>f<81>g<81>h<81>i<81>j<81>k<81>l<81>m<81>n<81>o<81>p<81>q<81>r<81>s<81>t<81>u<81>v<81>w<81>x<81>y<81>z<81>,<81>.<81>BACK<82>END<A1>7i<74>0<86><88><81>¿Qué<81>velocidad<80><80><81>de<81>mensaje<81>quieres<80><80><81>usar<81>?<81><80><80><80><86>Rápido<80><80><86>Normáal<80><80><86>Despacio<80>12k<73><88><81>Ingrese<81>tu<81>nombre!<80>13cR<8B>Nom.<88><81>********<80><81>4o<42>0x<88><81>Continuar<81>A<81>viaje<80><81>Velocidad<81>de<81>mensaje<80><81>Borrar<81>un<81>viaje<80><81>6o<42>0x<88><81>Continuar<81>un<81>viaje<80><81>Velocidad<81>de<81>mensaje<80><81>Empezar<81>un<81>viaje<81>nuevo<80><81>Copiar<81>un<81>viaje<80><81>Borrar<81>un<81>viaje<80><81>2o<42>0x<88><81>Empezar<81>un<81>viaje<81>nuevo<80><81>2k<95>0x<88><81>Viaje<81><81>1<80><81>2k<95>0x<88><81>Viaje<81><81>2<80><81>3k<95>0x<88><81>Viaje<81><81>1<80><81>Viaje<81><81>2<80><81>2k<95>0x<88><81>Viaje<81><81>3<80><81>3k<95>0x<88><81>Viaje<81><81>1<80><81>Viaje<81><81>3<80><81>3k<95>0x<88><81>Viaje<81><81>2<80><81>Viaje<81><81>3<80><81>4k<95>0x<88><81>Viaje<81><81>1<80><81>Viaje<81><81>2<80><81>Viaje<81><81>3<80><81>2o<63>0x<88><81>Viaje<81><81>1:<B5><80><81>2o<63>0x<88><81>Viaje<81><81>2:<B6><80><81>3o<63>0x<88><81>Viaje<81><81>1:<B5><80><81>Viaje<81><81>2:<B6><80><81>2o<63>0x<88><81>Viaje<81><81>3:<B7><80><81>3o<63>0x<88><81>Viaje<81><81>1:<B5><80><81>Viaje<81><81>3:<B7><80><81>3o<63>0x<88><81>Viaje<81><81>2:<B6><80><81>Viaje<81><81>3:<B7><80><81>4o<63>0x<88><81>Viaje<81><81>1:<B5><80><81>Viaje<81><81>2:<B6><80><81>Viaje<81><81>3:<B7><80>16k<73><88><81><B4><80><81>Nivel<82><A1><80><81>¿Quieres<81>borrar<81>este<81>personaje<80><81>.<81>.<80><81>.?<80><80>38W0x<88><81>Sí<80><81>No


EDIT:

This is probably a n00bish thing to notice—and I apologize if someone already explained this in some way or other—but I just discovered something about the way the items are listed: The length of the text for one item may result in another item being in the wrong place. In other words, unless I make the translated words the exact same length as the English words, and unless there's a way to edit how the pointers work, I'm going to end up with scrambled item and monster names.

I've discovered this after deciding to change gears and work on item/monster/spell lists instead of the menus for a bit. Why was the text so easy to edit while the items so difficult? Am I missing something?

EDIT 2:

After nearly a week of wrestling with hex code, Pointer Tables, and Atlas, I managed to properly insert item names that consist of two lines (e.g. "Copper Sword"/"Espada de Cobre"). Apparently the text for the items needs to begin at a particular point in the ROM in order for the pointers to read it correctly. To put it another way: the pointers for item names and enemy names (and spells? Menus? Credits?) each point to a particular byte in the ROM that begins a text string of a certain length; pushing the text of one string into the text of another results in the scrambled names.

I anticipate problems with certain items (e.g. Laura's Love) and certain enemy names (e.g. Dragonlord, Red Dragon) where they breach the end of the text string for one pointer and go into the territory of a different pointer. Is there a way to edit the location to which the pointers point to eliminate this problem and to conserve space in the ROM?
As the harbor is welcome to the sailor, so is the last line to the scribe.

abw

Quote from: werewolfslayr925 on May 23, 2018, 09:59:04 PM
I'm trying to insert the menus and stats into a copy of the ROM to test things out, but Atlas keeps giving me a weird error:

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Hmm, I get the same thing too. It looks like Atlas crashes when it tries to report an error on a script line that's too long (some light experimentation suggests that 466 characters is the limit). Try splitting that really long line into a bunch of shorter lines and see what happens. You'll at least need to change the format of the byte tokens - Atlas uses e.g. <$B1> instead of just <B1>.

Quote from: werewolfslayr925 on May 23, 2018, 09:59:04 PM
The length of the text for one item may result in another item being in the wrong place. In other words, unless I make the translated words the exact same length as the English words, and unless there's a way to edit how the pointers work, I'm going to end up with scrambled item and monster names.
[...]
Apparently the text for the items needs to begin at a particular point in the ROM in order for the pointers to read it correctly. To put it another way: the pointers for item names and enemy names (and spells? Menus? Credits?) each point to a particular byte in the ROM that begins a text string of a certain length; pushing the text of one string into the text of another results in the scrambled names.
Yeah, pointers are important :P. For the item/monster/price/spell lists, you'll need to update the pointers at 0x6842-0x6851 so that they each point to the same thing in your new text as they did in the original; 0x6842-0x6843 needs to point to the start of your new spell list, 0x6844-0x6845 needs to point to the start of your new item list, etc. For the menus, you'll need to do the same thing with all the pointers at 0x6F7C-0x6FBF; 0x6F7C-0x6F7D needs to point to the start of your new LV/HP/MP/etc. menu, 0x6F7E-0x6F7F needs to point to the start of your new NAME:/STRENGTH:/AGILITY:/etc. menu, and so on for the rest of the pointers.

werewolfslayr925

Quote from: abw on June 02, 2018, 08:41:07 PM
Hmm, I get the same thing too. It looks like Atlas crashes when it tries to report an error on a script line that's too long (some light experimentation suggests that 466 characters is the limit). Try splitting that really long line into a bunch of shorter lines and see what happens. You'll at least need to change the format of the byte tokens - Atlas uses e.g. <$B1> instead of just <B1>.

Shortening each of the lengths was actually one of the solutions that gave me a (somewhat) working item list. I recently started testing things out and found a few problems with the script (pictures below). Which brings me to...

Quote from: abw on June 02, 2018, 08:41:07 PM
Yeah, pointers are important :P. For the item/monster/price/spell lists, you'll need to update the pointers at 0x6842-0x6851 so that they each point to the same thing in your new text as they did in the original; 0x6842-0x6843 needs to point to the start of your new spell list, 0x6844-0x6845 needs to point to the start of your new item list, etc.

Great! This is exactly what I wanted to hear!

...

How do I do that? I've read through this, and it was very informative (and fun to read). However, iIrc, it only explained how to find pointers (which...I tried the main method and—maybe I did something wrong—it didn't seem to direct me to the pointers you mentioned for this particular game) and how to redirect a pointer from one text string to another. It doesn't give too much info in "Fixed Length" strings, which is what I think the lists are in DW. Is there a way to make the pointers point to any byte in the ROM and, therefore, take full advantage of the pointers to maximize use of space?

Quote from: abw on June 02, 2018, 08:41:07 PM
For the menus, you'll need to do the same thing with all the pointers at 0x6F7C-0x6FBF; 0x6F7C-0x6F7D needs to point to the start of your new LV/HP/MP/etc. menu, 0x6F7E-0x6F7F needs to point to the start of your new NAME:/STRENGTH:/AGILITY:/etc. menu, and so on for the rest of the pointers.

Thanks for the tip on the menus ;) Also, welcome back to the internet. I take it you've returned from your adventures?

Also also, here are the pics I mentioned above. Not much, but it isn't quite done yet :P
As the harbor is welcome to the sailor, so is the last line to the scribe.

abw

Quote from: werewolfslayr925 on June 03, 2018, 05:28:54 PM
It doesn't give too much info in "Fixed Length" strings, which is what I think the lists are in DW.
DW's item lists use variable length strings terminated by a $FF byte. Fixed length strings are when you have a bunch of strings one after the other that each have the same length, like this:


$8000:Fire  Ice   Bolt  PoisonDrain Fire 2Ice 2 Bolt 2Bio   Fire 3Ice 3 Bolt 3


With fixed length strings, a game usually just keeps a pointer to the very first list item and then does some math to find any other item in the list. E.g., if we wanted the spell name at index 3 in this list of 6-byte long spell names, we could take the desired index (3), multiply it by the fixed length (6), and then add that to the address of the first spell name ($8000) and get $8000 + 3 * 6 = $8012, a.k.a. the start of Poison.

Quote from: werewolfslayr925 on June 03, 2018, 05:28:54 PM
How do I do that?
In this case, we've already located some pointers to the item lists at 0x6842-0x6851. In general, it's entirely possible that there might be other pointers to the same data elsewhere in the ROM (I've seen games where a string address is hardcoded into the ASM in dozens of different places; tracking all of those down is a pain), but for now let's pretend that Dragon Warrior is going to keep being nice to us and only uses the one pointer table we know about.

If you look in the original ROM, you'll see

$6840:.. .. 56 BE B7 BA B7 BB 8F BB 4F BC 0E BE 70 BC
$6850:A2 BD

Those are your pointers. The NES hardware expects pointers to be stored in 2 byte little endian format, so that's almost always what games do. The first pointer in the list, 56 BE, corresponds to RAM address $BE56, which since we're in ROM bank 1 that will be loaded into RAM bank 0, is ROM address 0x7E66, i.e. the start of the original spell name list. If your new spell name list starts at ROM 0x7E87 instead, you'll need to take your ROM address 0x7E87, convert it to RAM address $BE87, and then change the pointer at 0x6842 to say 87 BE instead of 56 BE. Then you need to do the same for every other pointer in the list. Then you need to do the same for all the menu pointers.

The individual steps aren't difficult, but doing all those calculations and typing into a hex editor by hand is time consuming and error prone. Do it manually a couple of times until you understand what's going on, but then get your insertion utility to do all this tedious stuff for you - stick a "#W16($6842)" just before the start of your spell list, a "#W16($684C)" just before the start of your price list, etc.

Oh, there's one other thing you'll need to change in your insert script - the main dialogue was in ROM bank 2 loaded into RAM bank 0, so the difference between ROM and RAM addresses was only $10 (for the iNES header); the item lists, on the other hand, are in ROM bank 1 loaded into RAM bank 0, so the difference between ROM and RAM addresses is $-3FF0 ($-4000 for being in ROM bank 1 + $10 for the iNES header). I think the "correct" way of doing that in Atlas is to use custom pointers, but I always cheat and just use the #HDR command to change the address calculation instead. For all of the work you do in ROM bank 1 (i.e. 0x4010-0x800F), set #HDR($-3FF0); use #HDR($10) for the work you do in ROM bank 2 (i.e. 0x8010-0xC00F).

werewolfslayr925

Quote from: abw on June 04, 2018, 09:15:56 AM
DW's item lists use variable length strings terminated by a $FF byte. Fixed length strings are when you have a bunch of strings one after the other that each have the same length, like this:


$8000:Fire  Ice   Bolt  PoisonDrain Fire 2Ice 2 Bolt 2Bio   Fire 3Ice 3 Bolt 3


With fixed length strings, a game usually just keeps a pointer to the very first list item and then does some math to find any other item in the list. E.g., if we wanted the spell name at index 3 in this list of 6-byte long spell names, we could take the desired index (3), multiply it by the fixed length (6), and then add that to the address of the first spell name ($8000) and get $8000 + 3 * 6 = $8012, a.k.a. the start of Poison.

Gotcha. I didn't realize that a fixed length is always so short. The reason I thought that DW had a fixed length string is because the item/enemy lists are split into multiple sections (usually in a long-short-long-short pattern). I didn't count the bytes, but I thought that the length of each section of the text dump was one long string

Quote from: abw on June 04, 2018, 09:15:56 AM
In this case, we've already located some pointers to the item lists at 0x6842-0x6851. In general, it's entirely possible that there might be other pointers to the same data elsewhere in the ROM (I've seen games where a string address is hardcoded into the ASM in dozens of different places; tracking all of those down is a pain), but for now let's pretend that Dragon Warrior is going to keep being nice to us and only uses the one pointer table we know about.

If you look in the original ROM, you'll see

$6840:.. .. 56 BE B7 BA B7 BB 8F BB 4F BC 0E BE 70 BC
$6850:A2 BD

Those are your pointers. The NES hardware expects pointers to be stored in 2 byte little endian format, so that's almost always what games do. The first pointer in the list, 56 BE, corresponds to RAM address $BE56, which since we're in ROM bank 1 that will be loaded into RAM bank 0, is ROM address 0x7E66, i.e. the start of the original spell name list. If your new spell name list starts at ROM 0x7E87 instead, you'll need to take your ROM address 0x7E87, convert it to RAM address $BE87, and then change the pointer at 0x6842 to say 87 BE instead of 56 BE. Then you need to do the same for every other pointer in the list. Then you need to do the same for all the menu pointers.

The individual steps aren't difficult, but doing all those calculations and typing into a hex editor by hand is time consuming and error prone. Do it manually a couple of times until you understand what's going on, but then get your insertion utility to do all this tedious stuff for you - stick a "#W16($6842)" just before the start of your spell list, a "#W16($684C)" just before the start of your price list, etc.

OOOOKAY!! I think I understand this now. For some reason, I was under the impression that the values in the parentheses in the #W16 commands were the starting points for the text (instead of pointers for the text). (This was before I read The Mad Hacker's document.) I think I understand better now how to use Atlas.

There is one potential problem, though: will I still have problems with the items that, in the original ROM, go beyond the territory of one pointer and into the territory of another? Or can I just lump those items/enemies in on one side or the other once I start making pointers follow my every whim and command (mwahaha).

Quote from: abw on June 04, 2018, 09:15:56 AM
Oh, there's one other thing you'll need to change in your insert script - the main dialogue was in ROM bank 2 loaded into RAM bank 0, so the difference between ROM and RAM addresses was only $10 (for the iNES header); the item lists, on the other hand, are in ROM bank 1 loaded into RAM bank 0, so the difference between ROM and RAM addresses is $-3FF0 ($-4000 for being in ROM bank 1 + $10 for the iNES header). I think the "correct" way of doing that in Atlas is to use custom pointers, but I always cheat and just use the #HDR command to change the address calculation instead. For all of the work you do in ROM bank 1 (i.e. 0x4010-0x800F), set #HDR($-3FF0); use #HDR($10) for the work you do in ROM bank 2 (i.e. 0x8010-0xC00F).

This intrigues me. So, I can glean from this that bank 0 is the RAM and goes from 0x0000 to 0x3FFF, bank 1 is ROM and goes from 0x4000 to 0x7fff, and bank 2 is also ROM and goes from 0x8000 to the end of the ROM (0x14000)? Or is it one bank per 0x4000 bytes with the first 0x4000 bytes being RAM and everything beyond that being ROM? Also, I'm a bit unclear on the relationship between the header, the RAM, and the ROM. Does that only affect emulators, or does it also make a difference if running the game on original hardware?
As the harbor is welcome to the sailor, so is the last line to the scribe.

abw

Quote from: werewolfslayr925 on June 04, 2018, 01:01:33 PM
I didn't realize that a fixed length is always so short.
Fixed length strings can be any length, really; that example just happened to use strings with a length of 6. Elsewhere in the same game you can find fixed length strings with lengths anywhere between 6 and 14 bytes, and if you look at other games you can find other examples both longer and shorter.

Quote from: werewolfslayr925 on June 04, 2018, 01:01:33 PM
There is one potential problem, though: will I still have problems with the items that, in the original ROM, go beyond the territory of one pointer and into the territory of another?
Not if you do it right :P. As long as all the pointers are pointing to the right strings (or groups of strings in DW's case), you can move the strings pretty much anywhere you want to in RAM. Of course, if you try to move them to somewhere already occupied by other code/data, it'll be more work because you'll have to find a new home for that code/data and update any references to it, but DW has a fair bit of free space for you to make use of if you need it.

Quote from: werewolfslayr925 on June 04, 2018, 01:01:33 PM
This intrigues me. So, I can glean from this that bank 0 is the RAM and goes from 0x0000 to 0x3FFF, bank 1 is ROM and goes from 0x4000 to 0x7fff, and bank 2 is also ROM and goes from 0x8000 to the end of the ROM (0x14000)? Or is it one bank per 0x4000 bytes with the first 0x4000 bytes being RAM and everything beyond that being ROM?
Not quite - this goes back to mappers. Remember that DW has a total of 64k of PRG ROM, 32k of the NES's 64k address space gets mapped to PRG ROM, and DW configures its MMC1 mapper to use two 16k RAM banks. So, you can think of the NES's 32k RAM as being split into banks 0 ($8000-$BFFF) and 1 ($C000-$FFFF), and DW's 64k of PRG ROM as being split into banks 0 (0x0010-0x400F), 1 (0x4010-0x800F), 2 (0x8010-0xC00F), and 3 (0xC010-0x1000F). In DW's case, the last RAM bank (1) is fixed to the last ROM bank (3), and it swaps whichever of the other ROM banks it wants to read from into RAM bank 0 as needed; put another way, ROM banks 0, 1, and 2 all get mapped to RAM bank 0, and ROM bank 3 always gets mapped to RAM bank 1.

Quote from: werewolfslayr925 on June 04, 2018, 01:01:33 PM
Also, I'm a bit unclear on the relationship between the header, the RAM, and the ROM. Does that only affect emulators, or does it also make a difference if running the game on original hardware?
As for the iNES header... the actual ROM on physical hardware only contains the ROM, so for the NES, there's a $10 byte header that contains extra information about the rest of the hardware, things like whether there's any PRG RAM, whether it's battery-backed, what mapper it uses, etc. The header isn't part of the physical ROM, but is included as part of the ROM file so that emulators know what additional hardware they need to emulate besides the NES itself.

werewolfslayr925

#46
Quote from: abw on June 04, 2018, 09:19:25 PM
Not if you do it right

Okay, and how would that be? This is really starting to frustrate me, and it's getting to the point where I really don't want to finish this. No matter what I do it never reads the script how it should. When I set a pointer to a string of text, do I start with the word itself or with the [ITM] code? Should I handle text that's cut off like this:


#VAR(dwSP4, TABLE)
#ADDTBL("dwSP4.tbl", dwSP4)
#ACTIVETBL(dwSP4)

#HDR($10)

#JMP($7AC6)

#W16($7AC6)
[60]Palo[ITM]Porra[ITM]Espada[ITM]Hacha[ITM]Sable[ITM]Espada[ITM]Espada[ITM]Ropas[ITM]Armadura[ITM]Cota[ITM]Corasa[ITM]Petral[ITM]Armadura[ITM]Armadura[ITM]Rodela[ITM]Escudo[ITM]Escudo[ITM]Hierba[ITM]Hachón[ITM]Escama[ITM]Alas[ITM]Llave[ITM]Agua[ITM]Orbe de[ITM]Tableta[ITM]Flauta[ITM]Lira[ITM]Caña[ITM]Piedra del[ITM]Amor de[ITM]G


or like this:


#VAR(dwSP4, TABLE)
#ADDTBL("dwSP4.tbl", dwSP4)
#ACTIVETBL(dwSP4)

#HDR($10)

#JMP($7AC6)

#W16($7AC6)
[60]Palo[ITM]Porra[ITM]Espada[ITM]Hacha[ITM]Sable[ITM]Espada[ITM]Espada[ITM]Ropas[ITM]Armadura[ITM]Cota[ITM]Corasa[ITM]Petral[ITM]Armadura[ITM]Armadura[ITM]Rodela[ITM]Escudo[ITM]Escudo[ITM]Hierba[ITM]Hachón[ITM]Escama[ITM]Alas[ITM]Llave[ITM]Agua[ITM]Orbe de[ITM]Tableta[ITM]Flauta[ITM]Lira[ITM]Caña[ITM]Piedra del[ITM]Amor de[ITM]Gota del


EDIT:

Nevermind. I just ended up inserting and then editing the pointers by hand.

Now I've got a different problem. After inserting everything and making sure that all my pointers are in order, I keep having a problem with two enemies in particular. Screenshots can be found here: https://imgur.com/a/anAsLtw

I've been having this problem for weeks and I can't find out where that "n" is coming from. I tried deleting the entire second tier in the enemy name list and it still appears. The script is also well within its borders. Any ideas?

EDIT2:

I discovered that, for some reason, using "E" after an "[ITM]" command (FF) in the monster list results in the E being preceded by "n " (i.e. "n" and a space). This can be resolved by placing a space (" ") in between the "[ITM]" command in the script. Weird.
As the harbor is welcome to the sailor, so is the last line to the scribe.

abw

Quote from: werewolfslayr925 on June 08, 2018, 04:30:28 PM
Okay, and how would that be?
An insert script for the original text (using Psyklax's table file) looks like this:

#VAR(Table, TABLE)
#ADDTBL("dw.tbl", Table)
#ACTIVETBL(Table)

#JMP($7AC7, $7EAF)
#HDR($-3FF0)

#W16($6844)
Bamboo[ITM]Club[ITM]Copper[ITM]Hand[ITM]Broad[ITM]Flame[ITM]Erdrick}s[ITM]Clothes[ITM]Leather[ITM]Chain[ITM]Half[ITM]Full[ITM]Magic[ITM]Erdrick}s[ITM]Small[ITM]Large[ITM]Silver[ITM]Herb[ITM]Torch[ITM]Dragon}s[ITM]Wings[ITM]Magic[ITM]Fairy[ITM]Ball of[ITM]Tablet[ITM]Fairy[ITM]Silver[ITM]Staff of[ITM]Stones of[ITM]Gwaelin}s[ITM]Rainbow[ITM]

#W16($6848)
Cursed[ITM]Death[ITM]Fighter}s[ITM]Erdrick}s[ITM]Secret[ITM]

#W16($6846)
Pole[ITM][ITM]Sword[ITM]Axe[ITM]Sword[ITM]Sword[ITM]Sword[ITM][ITM]Armor[ITM]Mail[ITM]Plate[ITM]Plate[ITM]Armor[ITM]Armor[ITM]Shield[ITM]Shield[ITM]Shield[ITM][ITM][ITM]Scale[ITM][ITM]Key[ITM]Water[ITM]Light[ITM][ITM]Flute[ITM]Harp[ITM]Rain[ITM]Sunlight[ITM]Love[ITM]Drop[ITM]

#W16($684A)
Belt[ITM]Necklace[ITM]Ring[ITM]Token[ITM]Passage[ITM]

// etc.


Some points to note:

  • 0x7AC6 is actually ASM code ($60 is the opcode for RTS); as long as you're still writing $60 there, it'll work out in the end, but unless you know exactly what you're doing, it's generally better to leave code alone while you're editing data, so using #JMP($7AC7) and getting rid of the [60] is better, especially since...
  • #W16($7AC6) calculates the value of a pointer to the current address (which also happens to be 0x7AC6 since no text has been written since the previous #JMP) and then writes that value to 0x7AC6-0x7AC7, overwriting the RTS and breaking that part of the game's code
  • the original pointer at 0x6844 doesn't get changed, so it still points to ROM 0x7AC7 (RAM $BAB7), which is now the high byte of the pointer to 0x7AC6
  • with #HDR($10), a pointer to 0x7AC6 has the value $7AB6 (= $7AC6 - $10), which points to cartridge RAM, not ROM; you need the pointer to be $BAB7, so the #HDR value has to be $-3FF0 (= $7AC7 - $BAB7)
  • there is apparently a "Secret Passage" item in the game; who knew?

Quote from: werewolfslayr925 on June 08, 2018, 04:30:28 PM
I discovered that, for some reason, using "E" after an "[ITM]" command (FF) in the monster list results in the E being preceded by "n " (i.e. "n" and a space). This can be resolved by placing a space (" ") in between the "[ITM]" command in the script. Weird.
This is coming from some ASM code. In English, normal battles start with the message "A <monster name> draws near!", except that isn't proper English when <monster name> starts with a vowel (i.e. A, E, I, O, U, and sometimes Y), so in those cases* the game adds an extra "n " and uses "An <monster name> draws near!" instead. Does Spanish have any similar behaviour?

*: Actually only for A, E, I, and U - the game doesn't check for Y at all and the check for O is broken; in the original game it doesn't really matter since the only monster names that start with a vowel all start with A, so this isn't a bug that would show up without hacking the game.

werewolfslayr925

Quote from: abw on June 09, 2018, 12:30:57 AM
An insert script for the original text (using Psyklax's table file) looks like this:

#VAR(Table, TABLE)
#ADDTBL("dw.tbl", Table)
#ACTIVETBL(Table)

#JMP($7AC7, $7EAF)
#HDR($-3FF0)

#W16($6844)
Bamboo[ITM]Club[ITM]Copper[ITM]Hand[ITM]Broad[ITM]Flame[ITM]Erdrick}s[ITM]Clothes[ITM]Leather[ITM]Chain[ITM]Half[ITM]Full[ITM]Magic[ITM]Erdrick}s[ITM]Small[ITM]Large[ITM]Silver[ITM]Herb[ITM]Torch[ITM]Dragon}s[ITM]Wings[ITM]Magic[ITM]Fairy[ITM]Ball of[ITM]Tablet[ITM]Fairy[ITM]Silver[ITM]Staff of[ITM]Stones of[ITM]Gwaelin}s[ITM]Rainbow[ITM]

#W16($6848)
Cursed[ITM]Death[ITM]Fighter}s[ITM]Erdrick}s[ITM]Secret[ITM]

#W16($6846)
Pole[ITM][ITM]Sword[ITM]Axe[ITM]Sword[ITM]Sword[ITM]Sword[ITM][ITM]Armor[ITM]Mail[ITM]Plate[ITM]Plate[ITM]Armor[ITM]Armor[ITM]Shield[ITM]Shield[ITM]Shield[ITM][ITM][ITM]Scale[ITM][ITM]Key[ITM]Water[ITM]Light[ITM][ITM]Flute[ITM]Harp[ITM]Rain[ITM]Sunlight[ITM]Love[ITM]Drop[ITM]

#W16($684A)
Belt[ITM]Necklace[ITM]Ring[ITM]Token[ITM]Passage[ITM]

// etc.
    That's good to know, but the dump didn't come out this way when I used Pointer Tables. For example, "Rainbow" was cut off right after the R and it bled over next to "Cursed[ITM]". Oh well.

    Quote
    • there is apparently a "Secret Passage" item in the game; who knew?

    Yeah, that's what I said. I think maybe Erdrick's Tablet was meant to be an item at some point? I'll take a look at tcrf to see if they have any info on that.

    Quote
    This is coming from some ASM code. In English, normal battles start with the message "A <monster name> draws near!", except that isn't proper English when <monster name> starts with a vowel (i.e. A, E, I, O, U, and sometimes Y), so in those cases* the game adds an extra "n " and uses "An <monster name> draws near!" instead. Does Spanish have any similar behaviour?

    *: Actually only for A, E, I, and U - the game doesn't check for Y at all and the check for O is broken; in the original game it doesn't really matter since the only monster names that start with a vowel all start with A, so this isn't a bug that would show up without hacking the game.

    See, I didn't know this. I wish I had known this. Thanks for clearing that up and for the points about the Atlas code. I'll post here again when I have trouble with and/or have completed the menus. (That said, what's the rule here on double-posting?)
    As the harbor is welcome to the sailor, so is the last line to the scribe.

    abw

    Quote from: werewolfslayr925 on June 09, 2018, 05:54:37 PM
    That's good to know, but the dump didn't come out this way when I used Pointer Tables.
    Yeah, that's kind of what I figured from the errors you were getting, which is why I kept going on about pointers :P. As long as you've got it working somehow, though, it's all good!

    Quote from: werewolfslayr925 on June 09, 2018, 05:54:37 PM
    Yeah, that's what I said. I think maybe Erdrick's Tablet was meant to be an item at some point? I'll take a look at tcrf to see if they have any info on that.
    So, it turns out the "Secret Passage" item is actually the secret passage in Charlock castle and shows up as "[INV]" in "[ME] discovers the [INV]".

    Quote from: werewolfslayr925 on June 09, 2018, 05:54:37 PM
    See, I didn't know this. I wish I had known this.
    Yeah, I had forgotten how much English-specific stuff was in this game. Here's another example that comes from ASM code: it turns out that "[PNT]" and "[XP]" both print out " Point", but they also add "s" if the relevant number is greater than 1 (e.g. "1 Point" vs. "2 Points"). As an aside, I think the "[PNT]" code is over-used; you get text like "Thy Hit Point decreased by 1." and "Thy Hit Points decreased by 2." when really it should just be "Hit Points" all the time. Oh well.

    Anyway, for those control codes, you'll be interested in 0x7761-0x7766 (the "tnioP " - the ASM code reads the string in reverse) and 0x7756 (the "s"); once you figure out how you want to handle those control codes, I might be able to provide some suggestions. I've also jumped ahead and taken a look at the menu, title screen, and end credits, so I should be able to help with those too.

    Quote from: werewolfslayr925 on June 09, 2018, 05:54:37 PM
    (That said, what's the rule here on double-posting?)
    At one point in the past, following your own post with a separate post within a week of the first post was considered an offense (you were supposed to edit your previous post instead of making a new one), but later on the auto-merge feature was added, so now when you attempt to make a second post, automatically you end up editing your previous post instead; the net effect is that double-posting isn't really an issue anymore, though sometimes edits don't show up as new on the main board. Post away all you want (within reason, of course :P)!

    werewolfslayr925

    #50
    Quote from: abw on June 20, 2018, 05:51:05 PM
    So, it turns out the "Secret Passage" item is actually the secret passage in Charlock castle and shows up as "[INV]" in "[ME] discovers the [INV]".

    Ah! That's interesting, especially since it's categorized under the items. Clever that they did that.

    Quote from: abw on June 20, 2018, 05:51:05 PM
    Yeah, I had forgotten how much English-specific stuff was in this game. Here's another example that comes from ASM code: it turns out that "[PNT]" and "[XP]" both print out " Point", but they also add "s" if the relevant number is greater than 1 (e.g. "1 Point" vs. "2 Points"). As an aside, I think the "[PNT]" code is over-used; you get text like "Thy Hit Point decreased by 1." and "Thy Hit Points decreased by 2." when really it should just be "Hit Points" all the time. Oh well.

    I tested this out in the translation, and it shouldn't be a problem since I didn't get any extra "s" characters in the text. My HP depletion text still reads "puntos". Perhaps the control code just looks for the word "Points"?

    Quote from: abw on June 20, 2018, 05:51:05 PM
    I've also jumped ahead and taken a look at the menu, title screen, and end credits, so I should be able to help with those too.

    I'm working on this with the trace logger right now. Using your guide on the previous page of this thread, I'm trying to find out where the "T" in "TALK" comes from. (I tried it first with the "L" in "LV" but was having problems, so I switched over...). My only qualm so far is with the formatting. The logger gives me commands the formatting of which are the reverse of how you format your log for "TORCH"—i.e. they look like this:


    A:5F X:05 Y:08 S:E8 P:nvUbdIzc                        $FE4D:D0 F6     BNE $FE45
    A:5F X:05 Y:08 S:E8 P:nvUbdIzc                        $FE45:BD 00 03  LDA $0300,X @ $0305 = #$37
    A:37 X:05 Y:08 S:E8 P:nvUbdIzc                        $FE48:E8        INX


    instead of the way it looks in your comment. (For some reason, when I copy and paste it here, the formatting gets wonky).

    A small nitpick, but it makes it slightly more difficult for me to follow along. Is there a remedy for that?

    Quote from: abw on June 20, 2018, 05:51:05 PM
    At one point in the past, following your own post with a separate post within a week of the first post was considered an offense (you were supposed to edit your previous post instead of making a new one), but later on the auto-merge feature was added, so now when you attempt to make a second post, automatically you end up editing your previous post instead; the net effect is that double-posting isn't really an issue anymore, though sometimes edits don't show up as new on the main board. Post away all you want (within reason, of course :P)!

    Good to know :3 Glad they implemented the auto-merge feature.


    EDIT: Looking through the trace log file, I (think I) followed the trail to this:



    A:01 X:03 Y:10 S:F0 P:nVUbdIzc                $A2ED:B1 9F     LDA ($9F),Y @ $B064 = #$37
    A:37 X:03 Y:10 S:F0 P:nVUbdIzc                $A2EF:10 10     BPL $A301
    A:37 X:03 Y:10 S:F0 P:nVUbdIzc                $A301:8D DD 64  STA $64DD = #$5F


    A quick Google search yields that BPL means "Branch on Result Plus" (whatever the heck that means). However, looking at the code at $6311 doesn't give me a hex pair that looks like a pointer. Looking instead at 7054 (which corresponds to $B064) shows me the "L" in "SHIELD". How far back should I go? For what kind of command am I looking? I'm really lost...
    As the harbor is welcome to the sailor, so is the last line to the scribe.

    abw

    Quote from: werewolfslayr925 on June 22, 2018, 02:59:37 PM
    Ah! That's interesting, especially since it's categorized under the items. Clever that they did that.
    Yeah, it looks like the items you find by searching use the "[ME] discovers the [INV]." text, and the items you get from chests use the "Fortune smiles upon thee, [ME].&Thou hast found the [INV].%" text. The items you get from talking to people don't use any text at all :P. There's some more cleverness in store for you if/when you start editing the title screen/end credits graphics >:D.

    Quote from: werewolfslayr925 on June 22, 2018, 02:59:37 PM
    I tested this out in the translation, and it shouldn't be a problem since I didn't get any extra "s" characters in the text. My HP depletion text still reads "puntos". Perhaps the control code just looks for the word "Points"?
    No, both "[PNT]" and "[XP]" print out extra text that doesn't show up there in the text dump. As long as you're not using "[PNT]" in your text, that part should be fine, but if you're using "[XP]", you'll still see "Before reaching thy next level of experience thou must gain 1 Point" / "2 Points" when talking to the King. The easiest way around that is to use "[NUM]", but if you do want different text for 1 vs. more than 1, the game is already set up to do that for those 2 control codes, so it shouldn't be too much more work to just change that text a bit.

    Quote from: werewolfslayr925 on June 22, 2018, 02:59:37 PM
    My only qualm so far is with the formatting.
    Ah, an easy problem, the best kind to have :D. In the Trace Logger window, under Log Options, there's a "To the left from disassembly" checkbox (beside the "Log Processor status flags" checkbox it refers to) that controls that. Which one is best depends on the situation and your personal preference - try them both and choose!

    Quote from: werewolfslayr925 on June 22, 2018, 02:59:37 PM
    EDIT: Looking through the trace log file, I (think I) followed the trail to this:
    Congratulations, that is indeed the "T" in "TALK"! If you keep following the log further back, you'll eventually reach the code that starts reading that string (in this particular case, that's when Y=#$00, though the same can't be said in general):

    $A1E6:B1 9F     LDA ($9F),Y @ $B054 = #$80                   A:B0 X:00 Y:00 S:F0 P:nvUBdIZc

    And that's where things start to get interesting. Dragon Warrior's menu strings start with between 4 and 7 bytes that specify some of the menu window's properties, such as how many lines to print and how many characters wide the window is, and then continue until that many lines of text have been read. So, finding the end of each string is a little bit complicated. Fortunately, Dragon Warrior doesn't seem to waste any bytes in between strings and the final string is immediately followed by code (if you keep the Code/Data Logger open while you play through the game, it will eventually become pretty good at telling you what bytes are code and what bytes are data), so one way you can tackle the problem is to just dump the entire block from 0x6FC0-0x752C and match that up with the pointer table at 0x6F7C-0x6FBF, which I hear Pointer Tables is pretty good at. The corresponding Atlas insert script looks like this (I've kept the window setup bytes as raw hex to make it clear that they are not text and should not be treated as such during insertion):

    #JMP($6FC0, $752C)

    #W16($6F7C)
    <$01><$06><$08><$21><$89><$B0><$88>LV<$82><$A0>HP<$81><$90>MP<$81><$94>G<$98>E<$A8>

    #W16($6F7E)
    <$21><$0B><$14><$35><$88><$85>NAME:<$B1><$80><$86>STRENGTH:<$D8><$80><$87>AGILITY:<$D9><$80><$84>MAXIMUM<$81>HP:<$DC><$80><$84>MAXIMUM<$81>MP:<$DD><$80><$82>ATTACK<$81>POWER:<$DA><$80><$81>DEFENSE<$81>POWER:<$DB><$80><$82>WEAPON:<$B8><$87><$83><$B8><$83>ARMOR:<$B9><$87><$83><$B9><$82>SHIELD:<$BA><$87><$83><$BA>

    #W16($6F80)
    <$01><$05><$18><$92><$88><$80><$80><$80><$80>

    #W16($6F82)
    <$80><$05><$10><$16><$08><$21><$8B>COMMAND<$88><$81>TALK<$84>SPELL<$81>STATUS<$82>ITEM<$80><$81>STAIRS<$82>DOOR<$80><$81>SEARCH<$82>TAKE<$80>

    #W16($6F84)
    <$80><$03><$10><$16><$08><$21><$8B>COMMAND<$88><$81>FIGHT<$83>SPELL<$81>RUN<$85>ITEM<$80>

    #W16($6F86)
    #W16($6F88)
    <$80><$0B><$0C><$29><$00><$21><$8B>SPELL<$88><$D6><$81><$C0><$E8><$E9>

    #W16($6F8A)
    <$A0><$0B><$0C><$39><$00><$11><$88><$D4><$81><$BB><$82><$BB><$E8><$E9>

    #W16($6F8C)
    <$A0><$08><$12><$25><$00><$11><$88><$D5><$81><$BC><$81><$C8><$82><$BC><$80><$E8><$E9>

    #W16($6F8E)
    <$80><$03><$08><$25><$00><$21><$88><$81>YES<$80><$81>NO<$80>

    #W16($6F90)
    <$80><$03><$08><$25><$00><$21><$88><$81>BUY<$80><$81>SELL<$80>

    #W16($6F92)
    <$01><$07><$18><$52><$88><$81>A<$81>B<$81>C<$81>D<$81>E<$81>F<$81>G<$81>H<$81>I<$81>J<$81>K<$81>L<$81>M<$81>N<$81>O<$81>P<$81>Q<$81>R<$81>S<$81>T<$81>U<$81>V<$81>W<$81>X<$81>Y<$81>Z<$81>-<$81>}<$81>!<$81>?<$81>(<$81>)<$80><$81>a<$81>b<$81>c<$81>d<$81>e<$81>f<$81>g<$81>h<$81>i<$81>j<$81>k<$81>l<$81>m<$81>n<$81>o<$81>p<$81>q<$81>r<$81>s<$81>t<$81>u<$81>v<$81>w<$81>x<$81>y<$81>z<$81>,<$81>.<$81>BACK<$82>END

    #W16($6F94)
    <$A1><$07><$12><$74><$00><$86><$88><$81>Which<$81>Message<$80><$80><$81>Speed<$81>Do<$81>You<$80><$80><$81>Want<$81>To<$81>Use?<$80><$80><$80><$86>FAST<$80><$80><$86>NORMAL<$80><$80><$86>SLOW<$80>

    #W16($6F96)
    <$01><$02><$14><$73><$88><$81>INPUT<$81>YOUR<$81>NAME!<$80>

    #W16($6F98)
    <$01><$03><$0C><$35><$8B>NAME<$88><$81>********<$80>

    #W16($6F9A)
    <$81><$04><$18><$42><$00><$21><$88><$81>CONTINUE<$81>A<$81>QUEST<$80><$81>CHANGE<$81>MESSAGE<$81>SPEED<$80><$81>ERASE<$81>A<$81>QUEST<$80>

    #W16($6F9C)
    <$81><$06><$18><$42><$00><$21><$88><$81>CONTINUE<$81>A<$81>QUEST<$80><$81>CHANGE<$81>MESSAGE<$81>SPEED<$80><$81>BEGIN<$81>A<$81>NEW<$81>QUEST<$80><$81>COPY<$81>A<$81>QUEST<$80><$81>ERASE<$81>A<$81>QUEST<$80>

    #W16($6F9E)
    <$81><$02><$18><$42><$00><$21><$88><$81>BEGIN<$81>A<$81>NEW<$81>QUEST<$80>

    #W16($6FA0)
    <$81><$02><$14><$95><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>1<$80>

    #W16($6FA2)
    <$81><$02><$14><$95><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>2<$80>

    #W16($6FA4)
    <$81><$03><$14><$95><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>1<$80><$81>ADVENTURE<$81>LOG<$81>2<$80>

    #W16($6FA6)
    <$81><$02><$14><$95><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>3<$80>

    #W16($6FA8)
    <$81><$03><$14><$95><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>1<$80><$81>ADVENTURE<$81>LOG<$81>3<$80>

    #W16($6FAA)
    <$81><$03><$14><$95><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>2<$80><$81>ADVENTURE<$81>LOG<$81>3<$80>

    #W16($6FAC)
    <$81><$04><$14><$95><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>1<$80><$81>ADVENTURE<$81>LOG<$81>2<$80><$81>ADVENTURE<$81>LOG<$81>3<$80>

    #W16($6FAE)
    <$81><$02><$18><$63><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>1:<$B5><$80>

    #W16($6FB0)
    <$81><$02><$18><$63><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>2:<$B6><$80>

    #W16($6FB2)
    <$81><$03><$18><$63><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>1:<$B5><$80><$81>ADVENTURE<$81>LOG<$81>2:<$B6><$80>

    #W16($6FB4)
    <$81><$02><$18><$63><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>3:<$B7><$80>

    #W16($6FB6)
    <$81><$03><$18><$63><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>1:<$B5><$80><$81>ADVENTURE<$81>LOG<$81>3:<$B7><$80>

    #W16($6FB8)
    <$81><$03><$18><$63><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>2:<$B6><$80><$81>ADVENTURE<$81>LOG<$81>3:<$B7><$80>

    #W16($6FBA)
    <$81><$04><$18><$63><$00><$21><$88><$81>ADVENTURE<$81>LOG<$81>1:<$B5><$80><$81>ADVENTURE<$81>LOG<$81>2:<$B6><$80><$81>ADVENTURE<$81>LOG<$81>3:<$B7><$80>

    #W16($6FBC)
    <$01><$06><$14><$73><$88><$81><$B4><$80><$81>LEVEL<$82><$A1><$80><$81>Do<$81>You<$81>Want<$81>To<$80><$81>Erase<$81>This<$80><$81>Character?<$80>

    #W16($6FBE)
    <$80><$03><$08><$3A><$00><$21><$88><$81>YES<$80><$81>NO<$80>


    Quote from: werewolfslayr925 on June 22, 2018, 02:59:37 PM
    A quick Google search yields that BPL means "Branch on Result Plus" (whatever the heck that means).
    When you think of a byte as being a 2's complement integer, it's positive (Plus) when the high bit is 0 and negative (Minus) otherwise, so BPL means "go to this address if the negative processor flag is not set"; LDA updates the negative and zero flags based on the value it loads, so this boils down to "go to $A301 if the byte we just loaded is positive". The "negative" bytes with values >= #$80 get chopped up into a 4-bit index into a function jump table and a 3-bit parameter to the function that gets called; you'll be interested in at least #$80 (new line) and #$81 - #$87 (print 1 to 7 spaces).

    werewolfslayr925

    #52
    At this point I really don't care about learning anything about this anymore. I've come to hate this project and to hate programming even more than I did before starting it. If you don't mind, would you be willing to just give me any further pointer locations/info I need to know for inserting the credits and editing the title screen? I'm really sick of this and want it to be over with.
    As the harbor is welcome to the sailor, so is the last line to the scribe.

    abw

    Well, that's depressing :(. When a hobby starts to be more like work than fun (and ROM hacking can definitely be a very large amount of work), maybe it's time to take a break for a little while and come back feeling refreshed. I know that's helped me on more than one occasion! As for the title screen and credits, try this on for size:


    #JMP($3DDC, $3FD9)
    // Title Screen data starts being written to PPU $2000.
    // Control code F7 takes 2 bytes (A, B) as parameters and means "write byte B A times" so e.g. F7 04 5F results in 5F 5F 5F 5F being written to the PPU; it's a simple RLE compression.
    // Control code FC does nothing useful until we reach PPU $2400, at which point it signals the end of the title screen data; as such, only the final FC actually matters.
    // There are also some other inefficiencies in the original data that you can take advantage of if you need more space for text.

    // 4 rows of spaces
    <$F7><$80><$5F><$FC>
    // 1 row of spaces
    <$F7><$20><$5F><$FC>
    // top border
    <$F7><$20><$AD><$FC>
    // speckled background
    <$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$FC>
    <$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$FC>
    <$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$FC>
    <$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$FC>

    // speckled background with DRAGON WARRIOR graphics
    <$A9><$AA><$A9><$74><$75><$76><$77><$78><$79><$7A><$7B><$7C><$7D><$7E><$7F><$80><$81><$82><$83><$84><$85><$86><$85><$86><$87><$88><$89><$8A><$8B><$8C><$A9><$AA><$FC>
    <$AB><$AC><$AB><$8D><$8E><$8F><$90><$91><$92><$93><$94><$95><$96><$97><$98><$99><$9A><$9B><$9C><$9D><$9E><$9F><$9E><$9F><$A0><$A1><$A2><$A3><$AB><$AC><$AB><$AC><$FC>
    <$A9><$AA><$A9><$AA><$A9><$AA><$A4><$A5><$A9><$A6><$A7><$AA><$A9><$AA><$A9><$AA><$A9><$A8><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$FC>

    // speckled background
    <$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$FC>
    <$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$A9><$AA><$FC>
    <$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$AB><$AC><$FC>
    // bottom border
    <$F7><$20><$AE><$FC>
    // 1 row of spaces
    <$F7><$20><$5F><$FC>
    // 1 row of spaces
    <$F7><$20><$5F><$FC>

    // 63=-
    <$F7><$0A><$5F><$63>PUSH START<$63><$F7><$0A><$5F><$FC>
    // 1 row of spaces
    <$F7><$20><$5F><$FC>
    // 62=<copyright symbol>
    <$F7><$0B><$5F><$62>1986 ENIX<$F7><$0B><$5F><$FC>
    // 1 row of spaces
    <$F7><$20><$5F><$FC>
    <$F7><$0B><$5F><$62>1989 ENIX<$F7><$0B><$5F><$FC>
    // 1 row of spaces
    <$F7><$20><$5F><$FC>
    <$F7><$06><$5F>LICENSED TO NINTENDO<$F7><$06><$5F><$FC>
    // 1 row of spaces
    <$F7><$20><$5F><$FC>
    <$F7><$04><$5F>TM TRADEMARK OF NINTENDO<$F7><$04><$5F><$FC>
    // 1 row of spaces
    <$F7><$20><$5F><$FC>
    // 1 row of spaces
    <$F7><$20><$5F><$FC>

    // At this point we've reached PPU $23C0, so this is palette data instead of tilemap data
    <$F7><$08><$FF>
    <$F7><$08><$05>
    <$F7><$10><$00><$FC>
    <$F7><$08><$A5>
    <$F7><$08><$FF><$FC>
    <$F7><$10><$FF><$FC>


    #JMP($549D, $595E)
    // End Credits
    // As with the title screen data, control code F7 takes 2 bytes (A, B) as parameters and means "write byte B A times" so e.g. F7 04 5F results in 5F 5F 5F 5F being written to the PPU; it's a simple RLE compression.
    // Strings start with a 2 byte PPU address followed by the bytes to be written starting at that address.
    // Control code FC means end of string.
    // Control code FD means end of screen.
    // As with the title screen data, there are some inefficiencies in the original data that you can take advantage of if you need more space for text.

    // Screen #1
    // 60=!
    // 61=.
    <$E8><$20>CONGRATULATIONS<$60><$FC>
    <$47><$21>THOU HAST RESTORED<$FC>
    <$86><$21>PEACE UNTO THE WORLD<$60><$FC>
    <$E4><$21>BUT THERE ARE MANY ROADS<$FC>
    <$29><$22>YET TO TRAVEL<$61><$FC>
    <$89><$22>MAY THE LIGHT<$FC>
    <$C8><$22>SHINE UPON THEE<$61><$FD>

    // Screen #2
    <$88><$21>DRAGON WARRIOR<$FC>
    <$ED><$21>STAFF<$FC>
    // palette data
    <$C0><$23><$F7><$20><$FF><$FD>

    // Screen #3
    <$86><$21>SCENARIO WRITTEN BY<$FC>
    <$EB><$21>YUJI HORII<$FC>
    // palette data
    <$C0><$23><$F7><$20><$05><$FD>

    // Screen #4
    <$85><$21>CHARACTER DESIGNED BY<$FC>
    <$E9><$21>AKIRA TORIYAMA<$FC>
    // palette data
    <$C0><$23><$F7><$20><$0A><$FD>

    // Screen #5
    <$87><$21>MUSIC COMPOSED BY<$FC>
    <$E8><$21>KOICHI SUGIYAMA<$FC>
    // palette data
    <$C0><$23><$F7><$20><$0F><$FD>

    // Screen #6
    <$2A><$21>PROGRAMED BY<$FC>
    <$A8><$21>KOICHI NAKAMURA<$FC>
    <$0A><$22>KOJI YOSHIDA<$FC>
    <$67><$22>TAKENORI YAMAMORI<$FC>
    // palette data
    <$D0><$23><$F7><$08><$05><$F7><$10><$00><$FD>

    // Screen #7
    <$89><$21>CG DESIGNED BY<$FC>
    <$E9><$21>TAKASHI YASUNO<$FC>
    // palette data
    <$D8><$23><$F7><$08><$0A><$FD>

    // Screen #8
    <$86><$21>SCENARIO ASSISTED BY<$FC>
    <$E8><$21>HIROSHI MIYAOKA<$FC>
    // palette data
    <$C0><$23><$F7><$20><$0F><$FD>

    // Screen #9
    <$4A><$21>ASSISTED BY<$FC>
    <$CA><$21>RIKA SUZUKI<$FC>
    <$28><$22>TADASHI FUKUZAWA<$FC>
    // palette data
    <$D0><$23><$F7><$08><$50><$F7><$10><$00><$FD>

    // Screen #10
    <$87><$21>SPECIAL THANKS TO<$FC>
    <$E7><$21>KAZUHIKO TORISHIMA<$FC>
    // palette data
    <$C0><$23><$F7><$20><$05><$FD>

    // Screen #11
    <$8A><$21>TRANSLATION<$FC>
    <$ED><$21>STAFF<$FC>
    // palette data
    <$C0><$23><$F7><$20><$FF><$FD>

    // Screen #12
    <$C6><$20>TRANSLATED BY<$FC>
    <$08><$21>TOSHIKO WATSON<$FC>
    <$86><$21>REVISED TEXT BY<$FC>
    <$C8><$21>SCOTT PELLAND<$FC>
    <$46><$22>TECHNICAL SUPPORT BY<$FC>
    <$88><$22>DOUG BAKER<$FC>
    // palette data
    <$C0><$23><$F7><$10><$FF><$F7><$08><$00><$F7><$08><$0F><$F7><$10><$F0><$FD>

    // Screen #13
    <$48><$21>PROGRAMED BY<$FC>
    <$CA><$21>KENICHI MASUTA<$FC>
    <$2A><$22>MANABU YAMANA<$FC>
    // palette data
    <$D0><$23><$F7><$08><$50><$F7><$10><$00><$FD>

    // Screen #14
    <$25><$21>CG DESIGNED BY<$FC>
    <$8A><$21>SATOSHI FUDABA<$FC>
    <$05><$22>SPECIAL THANKS TO<$FC>
    <$6A><$22>HOWARD PHILLIPS<$FC>
    // palette data
    <$D0><$23><$F7><$08><$0A><$F7><$08><$00><$F7><$08><$0F><$FD>

    // Screen #15
    <$8A><$21>DIRECTED BY<$FC>
    <$E8><$21>KOICHI NAKAMURA<$FC>
    // palette data
    <$C0><$23><$F7><$20><$0A><$FD>

    // Screen #16
    <$8A><$21>PRODUCED BY<$FC>
    <$E9><$21>YUKINOBU CHIDA<$FC>
    // palette data
    <$C0><$23><$F7><$20><$0F><$FD>

    // Screen #17
    <$85><$20>BASED ON DRAGON QUEST<$FC>
    <$0B><$21>COPYRIGHT<$FC>
    <$63><$21>ARMOR PROJECT<$FC>
    <$74><$21>1986 1989<$FC>
    <$C3><$21>BIRD STUDIO<$FC>
    <$D4><$21>1986 1989<$FC>
    <$23><$22>KOICHI SUGIYAMA<$FC>
    <$34><$22>1986 1989<$FC>
    <$83><$22><$0C><$0D><$0E><$0F> SOFT<$FC>
    <$94><$22>1986 1989<$FC>
    <$09><$23>ENIX<$FC>
    <$10><$23>1986 1989<$FC>
    // palette data
    <$C8><$23><$F7><$03><$FF><$07><$F7><$06><$05><$F7><$03><$0F><$F7><$03><$AA><$F7><$05><$00><$F7><$05><$AA><$FC>
    <$E0><$23><$F7><$05><$00><$F7><$03><$AA><$04><$F7><$04><$00><$F7><$03><$AA><$F7><$04><$00><$F7><$03><$AA><$FD>

    // Screen #18
    // Enix logo
    <$8F><$21><$10><$11><$12><$FC>
    <$AE><$21><$13><$14><$15><$16><$FC>
    <$CE><$21><$17><$18><$19><$1A><$FC>
    <$EE><$21><$1B><$1C><$1D><$1E><$FC>
    <$0E><$22><$1F><$20><$21><$22><$FC>
    // palette data
    <$D8><$23><$F7><$10><$FF><$FD>

    // Screen #19
    // Gothic "The End"
    <$AA><$21><$3E><$3F><$40><$41><$42><$43><$44><$45><$46><$47><$48><$49><$FC>
    <$CA><$21><$4A><$4B><$4C><$4D><$4E><$4F><$50><$51><$52><$53><$54><$55><$FC>
    // palette data
    <$D0><$23><$F7><$20><$00><$FD>

    werewolfslayr925

    This is extremely helpful and makes my life much easier. I'll PM you if I have any problems. I think there may be some letters that I may have to work around. Either way, thank you so much for this and for the other script.
    As the harbor is welcome to the sailor, so is the last line to the scribe.

    abw

    Glad to hear it!

    Ah, yes, that's an excellent point - the title screen and end credits use a different set of graphics than the rest of the game, so if you need any Spanish tiles, you'll have to steal from the existing tiles. Most of the number tiles appear to be unused, and the staff names do not include "Q" or "V", so those are options; if you're going to redraw the "DRAGON WARRIOR" text, you might be able to free up some of those tiles, especially from the third row (the bottom of the "A"s and "G").

    werewolfslayr925

    #56
    Okay, so after translating the text block you gave me for the menus, I tired inserting it. The game started to freak out when the king's text box came up. I compared character counts and everything to make sure the Spanish was within the appropriate limitations and tried tinkering with the insertion script a bit, but to no avail.

    Here's what I've got:

    // Define, load, and activate a table (replace "dw_es.tbl" with the name of your table file).
    #VAR(dwSP2, TABLE)
    #ADDTBL("dwSP2.tbl", dwSP2)
    #ACTIVETBL(dwSP2)

    // NES ROMs have a $10 byte header.
    #HDR($10)

    // Jump to the start of the script, set an upper bound on the available space so that you don't accidentally start overwriting other code/data if your script is too long.
    #JMP($6FC0, $752C)

    #W16($6F7C)
    <$01><$06><$08><$21><$89><$B0><$88>LV<$82><$A0>HP<$81><$90>MP<$81><$94>G<$98>E<$A8>

    #W16($6F7E)
    <$21><$0B><$14><$35><$88><$85>NOM:<$B1><$80><$86>Fuerza:<$D8><$80><$87>Agilidad:<$D9><$80><$84>HP<$81>Máximo:<$DC><$80><$84>MP<$81>Máximo:<$DD><$80><$82>Ataque<$81>:<$DA><$80><$81>Defensa<$81>:<$DB><$80><$82>Arma:<$B8><$87><$83><$B8><$83>Armadura:<$B9><$87><$83><$B9><$82>Escudo:<$BA><$87><$83><$BA>

    #W16($6F80)
    <$01><$05><$18><$92><$88><$80><$80><$80><$80>

    #W16($6F82)
    <$80><$05><$10><$16><$08><$21><$8B>COMANDO<$88><$81>Hablar<$84>Hech.<$81>Estado<$82>Cosas<$80><$81>Escal.<$82>Puerta<$80><$81>Buscar<$82>Coger<$80>

    #W16($6F84)
    <$80><$03><$10><$16><$08><$21><$8B>COMANDO<$88><$81>Luchar<$83>Hech.<$81>Corre<$85>Cosas<$80>

    #W16($6F86)
    #W16($6F88)
    <$80><$0B><$0C><$29><$00><$21><$8B>Hech.<$88><$D6><$81><$C0><$E8><$E9>

    #W16($6F8A)
    <$A0><$0B><$0C><$39><$00><$11><$88><$D4><$81><$BB><$82><$BB><$E8><$E9>

    #W16($6F8C)
    <$A0><$08><$12><$25><$00><$11><$88><$D5><$81><$BC><$81><$C8><$82><$BC><$80><$E8><$E9>

    #W16($6F8E)
    <$80><$03><$08><$25><$00><$21><$88><$81>Sí<$80><$81>No<$80>

    #W16($6F90)
    <$80><$03><$08><$25><$00><$21><$88><$81>Com.<$80><$81>Ven.<$80>

    #W16($6F92)
    <$01><$07><$18><$52><$88><$81>A<$81>B<$81>C<$81>D<$81>E<$81>F<$81>G<$81>H<$81>I<$81>J<$81>K<$81>L<$81>M<$81>N<$81>O<$81>P<$81>Q<$81>R<$81>S<$81>T<$81>U<$81>V<$81>í<$81>ó<$81>Y<$81>ú<$81>-<$81>ñ<$81>!<$81>?<$81><$81><$80><$81>a<$81>b<$81>c<$81>d<$81>e<$81>f<$81>g<$81>h<$81>i<$81>j<$81>á<$81>l<$81>m<$81>n<$81>o<$81>p<$81>q<$81>r<$81>s<$81>t<$81>u<$81>v<$81>é<$81>x<$81>y<$81>z<$81>,<$81>.<$81>Bor.<$82>Fin

    #W16($6F94)
    <$A1><$07><$12><$74><$00><$86><$88><$81>Elige<$81>la<$80><$80><$81>velocidad<$81>del<$81>texto<$80><$80><$81><$81><$81><$80><$80><$80><$86>Rapido<$80><$80><$86>Normal<$80><$80><$86>Lento<$80>

    #W16($6F96)
    <$01><$02><$14><$73><$88><$81>Ingrese<$81>tu<$81>nombre<$80>

    #W16($6F98)
    <$01><$03><$0C><$35><$8B>Nom.<$88><$81>********<$80>

    #W16($6F9A)
    <$81><$04><$18><$42><$00><$21><$88><$81>Continuar<$81>una<$81>aventura<$80><$81>Velocidad<$81>del<$81>texto<$80><$81>Borrar<$81>aventura<$81><$80>

    #W16($6F9C)
    <$81><$06><$18><$42><$00><$21><$88><$81>Continuar<$81>una<$81>aventura<$80><$81>Velocidad<$81>del<$81>texto<$80><$81>Empezar<$81>una<$81>aventura<$81><$80><$81>Copiar<$81>una<$81>aventura<$80><$81>Borrar<$81>una<$81>aventura<$80>

    #W16($6F9E)
    <$81><$02><$18><$42><$00><$21><$88><$81>Empezar<$81>una<$81>aventura<$81><$80>

    #W16($6FA0)
    <$81><$02><$14><$95><$00><$21><$88><$81>Aventura<$81><$81>1<$80>

    #W16($6FA2)
    <$81><$02><$14><$95><$00><$21><$88><$81>Aventura<$81><$81>2<$80>

    #W16($6FA4)
    <$81><$03><$14><$95><$00><$21><$88><$81>Aventura<$81><$81>1<$80><$81>Aventura<$81><$81>2<$80>

    #W16($6FA6)
    <$81><$02><$14><$95><$00><$21><$88><$81>Aventura<$81><$81>3<$80>

    #W16($6FA8)
    <$81><$03><$14><$95><$00><$21><$88><$81>Aventura<$81><$81>1<$80><$81>Aventura<$81><$81>3<$80>

    #W16($6FAA)
    <$81><$03><$14><$95><$00><$21><$88><$81>Aventura<$81><$81>2<$80><$81>Aventura<$81><$81>3<$80>

    #W16($6FAC)
    <$81><$04><$14><$95><$00><$21><$88><$81>Aventura<$81>LOG<$81>1<$80><$81>Aventura<$81><$81>2<$80><$81>Aventura<$81><$81>3<$80>

    #W16($6FAE)
    <$81><$02><$18><$63><$00><$21><$88><$81>Aventura<$81><$81>1:<$B5><$80>

    #W16($6FB0)
    <$81><$02><$18><$63><$00><$21><$88><$81>Aventura<$81><$81>2:<$B6><$80>

    #W16($6FB2)
    <$81><$03><$18><$63><$00><$21><$88><$81>Aventura<$81><$81>1:<$B5><$80><$81>Aventura<$81><$81>2:<$B6><$80>

    #W16($6FB4)
    <$81><$02><$18><$63><$00><$21><$88><$81>Aventura<$81><$81>3:<$B7><$80>

    #W16($6FB6)
    <$81><$03><$18><$63><$00><$21><$88><$81>Aventura<$81><$81>1:<$B5><$80><$81>Aventura<$81><$81>3:<$B7><$80>

    #W16($6FB8)
    <$81><$03><$18><$63><$00><$21><$88><$81>Aventura<$81><$81>2:<$B6><$80><$81>Aventura<$81><$81>3:<$B7><$80>

    #W16($6FBA)
    <$81><$04><$18><$63><$00><$21><$88><$81>Aventura<$81><$81>1:<$B5><$80><$81>Aventura<$81><$81>2:<$B6><$80><$81>Aventura<$81><$81>3:<$B7><$80>

    #W16($6FBC)
    <$01><$06><$14><$73><$88><$81><$B4><$80><$81>Nivel<$82><$A1><$80><$81>¿Quieres<$81>borrar<$81>esto<$81>registro<$80><$81>de<$81>aventura?<$80><$81><$80>

    #W16($6FBE)
    <$80><$03><$08><$3A><$00><$21><$88><$81>Sí<$80><$81>No<$80>


    Apologies to the mods for the necromancy...


    Edit: After a bit more testing, the pointers in the #W16 commands seem to be incorrect. I'm probably wrong about that, but even reducing the script down to just an edition of the status window (the one that appears if you stand still for a bit) results in very buggy behavior.
    As the harbor is welcome to the sailor, so is the last line to the scribe.

    abw

    Huh, yeah, I would also describe that as freaking out :D. You were close, though - change the #HDR to #HDR($-3FF0) and try it again! Once you see it in action, you can start adjusting the line lengths and box widths until everything fits to your satisfaction.

    E.g. for the
    Quote
    <$81><$04><$18><$42><$00><$21><$88><$81>Continuar<$81>una<$81>aventura<$80><$81>Velocidad<$81>del<$81>texto<$80><$81>Borrar<$81>aventura<$81><$80>
    menu, you can increase the box width to
    Quote
    <$81><$04><$1A><$42><$00><$21><$88><$81>Continuar<$81>una<$81>aventura<$80><$81>Velocidad<$81>del<$81>texto<$80><$81>Borrar<$81>aventura<$81><$80>
    to make your text fit, or for the
    Quote
    <$80><$05><$10><$16><$08><$21><$8B>COMANDO<$88><$81>Hablar<$84>Hech.<$81>Estado<$82>Cosas<$80><$81>Escal.<$82>Puerta<$80><$81>Buscar<$82>Coger<$80>
    menu you can reduce the spacing between Hablar and Hech. to
    Quote
    <$80><$05><$10><$16><$08><$21><$8B>COMANDO<$88><$81>Hablar<$82>Hech.<$81>Estado<$82>Cosas<$80><$81>Escal.<$82>Puerta<$80><$81>Buscar<$82>Coger<$80>
    keep them both on the same line, etc., etc.

    werewolfslayr925

    #58
    Yeah, I think I've had enough of this. If I PM a patch to you, would you be willing/able to insert the credits and menu stuff? I really don't want to do this anymore. It isn't fun, it isn't rewarding, and it isn't worth my time.
    As the harbor is welcome to the sailor, so is the last line to the scribe.