Romhacking.net

Romhacking => Newcomer's Board => Topic started by: Gyroballer on February 20, 2019, 11:12:05 pm

Title: Understanding NES text routines
Post by: Gyroballer on February 20, 2019, 11:12:05 pm
Hey there,

I know I recently translated DBZ II for the Famicom, and while I do know some stuff about computer science, etc., I'm having trouble with rom hacking a lot of games.

If the text is stored like DBZ II, where it's mostly character for character in the rom and there are few dictionary entries, I don't have much trouble. But I don't even know where to begin or how to understand what's going on if I can't find a string of characters like the basic tutorials say.

I'm assuming that means the text is somehow compressed. Is DTE really common on the NES or are there other things for me to look out for? How do I know which one I'm dealing with and from there, how do I go about editing the in-game text?

Thanks for your help with this noob question.
Title: Re: Understanding NES text routines
Post by: Psyklax on February 21, 2019, 04:55:51 am
Having translated a bunch of Famicom games, I think I'm well placed to answer this. Some games do simply have basic uncompressed text strings, but due to the lack of storage space, any game with more than a few sentences is likely to use compression.

I've worked on Time Stranger, which uses dictionary compression. The US localisation of Dragon Warrior uses a kind of DTE. So it's quite common on the 8-bit machines, less so on the 16-bit ones.

The problem is that I feel the newbie guides have got it wrong: relative searching is just fumbling around in the dark. People ignore the much more effective option, which is learning how assembly works and properly reverse engineering the text.

See, you start with what you know - the RAM, what's on the screen. After all, RAM ain't compressed: the text on the screen is stored in VRAM and it got there somehow. Your task is to trace its path from the VRAM back to the part of the ROM where it originated. To do this, you don't need to be a programmer, you just need to know a few principles about how assembly works, and use the tools in an emulator such as FCEUX, like the debugger and memory editor. With a bit of perseverance, you can crack any game.

In some cases it's ludicrously easy: the game just reads a byte from the ROM and sends it directly to the VRAM. In many cases, though, the text is assembled in RAM first, then transferred to VRAM at an appropriate time. Often the reason for this is because it needs to be decompressed into work RAM first. If this is the case, then understanding the compression routine can sometimes be straightforward, sometimes be a headache.

It may sound daunting, yet I can't even program in BASIC let alone assembly, and I've cracked everything I've attempted. In a Game Gear translation, I even reverse engineered a graphics compression scheme, decompressed the graphics, changed them, and recompressed them with a rewritten routine, all without being a programmer. So if I can, you can. ;)
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 21, 2019, 01:32:48 pm
Thank you very much, Psyklax. I was looking for some direction/motivation and you gave both.

I'll try again on some stuff and see what I can figure out.

Detective Conan is awesome, by the way.
Title: Re: Understanding NES text routines
Post by: Pennywise on February 21, 2019, 02:39:14 pm
Basically you find the location where the text is being written on-screen, set a write breakpoint on PPU memory of that location and trace your way backwards. The process typically involves screen -> RAM -> ROM.

You can find the screen offset with the nametable viewer in FCEUX or the PPU viewer in MESEN.
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 21, 2019, 03:13:29 pm
I used this* last night and was able to get to the point where the CPU/RAM was snapping during writing text, but if I picked a specific value, it was snapping 1 tile before or after (can't remember which, sorry), and then it was hard to find an instruction like:
Code: [Select]
LDA ($40), Y @0123 = #$A0
*http://archive.rpgclassics.com/subsites/twit/docs/text/ (http://archive.rpgclassics.com/subsites/twit/docs/text/)
Title: Re: Understanding NES text routines
Post by: Psyklax on February 21, 2019, 05:24:35 pm
I used this* last night and was able to get to the point where the CPU/RAM was snapping during writing text, but if I picked a specific value, it was snapping 1 tile before or after

Not sure I understand the problem you're having. The document describes the process pretty well, it's the method I'd use. I would say that you shouldn't bother with specifying exact values: the time taken writing it is time you could spend just doing it and getting the right breakpoint. If you use save states to reach the moment before the breakpoint, you won't need to be so specific. I never use conditions.

All in all, though, the doc works for me (though I'm just reading rather than trying it myself).
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 21, 2019, 05:48:36 pm
Not sure I understand the problem you're having.

(https://imgur.com/b0No1TV.png)

Like in this photo, the PPU's snapped before the first text tile is written, since the breakpoint is any write to that particular space on the PPU (first text tile in the window, in this case). I know it's going to be A0, but I don't see that anywhere. But if I have it snap at the tile after that, I see A0 one of the times it breaks.

(https://imgur.com/GxFYQ0l.png)

Interestingly, neither character's been drawn yet, but breaking at the spot where the 2nd character would go shows me an A0 that I was anticipating.
Title: Re: Understanding NES text routines
Post by: KingMike on February 21, 2019, 06:54:53 pm
This is definitely the harder way to go about finding text.

But from what I gather of that code, stored at RAM $021C (the LDX $0200,X @ $021C part) is the string length, $21E-21F is the VRAM address data is written to, and from $220 on is the data to be written (such as the text string).
So how did that data get into the area at $220?
Set a write breakpoint for CPU $220 and find when data gets written into that point.
(the instruction that writes to $220 will probably be some kind of STA instruction. It's a LDA before that we'd probably be interested in)
(note that this if is a standard routine for copying data to VRAM, it is probably going to be called A LOT. So you will probably only want to enable the breakpoint close to your test point in the game for finding text).
Repeat until you get a hit in the ROM ($8000+) area.

(note that the @ $xxxx values in this original posted code could possibly change as different strings get loaded. I guess I would savestate right before my test point.)
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 21, 2019, 07:58:04 pm
This is the part where it's really confusing for me. I didn't realize that the 21C part is the string length, but it definitely is, after going through the text. I also didn't know the 21E-F part was the VRAM address written to.
I sort of at a basic level get what each operator does, but I'm not getting the big picture at all and I'm not sure how to reason out what you did.

Worse, I get really confused on if I break @ 220. It seems like the tile values get written to 204 and 205, maybe others, and yet 220 has something to do with this? If I break at 220 and try to continue, it will break a few more times and then go on with the entire string.

I can't figure out what to get from the parts before 220 is written to.

I did see that these instructions are stored really early in the ROM, like $1536, but I'm just seeing the assembly instructions that I see on the debugger.

(https://imgur.com/MRR6Rxh.png)


EDIT:
(https://imgur.com/4XV5odJ.png)

These two instructions will bounce back and forth (with "Run"). 204 in RAM just keeps just STX $01.
205 is always the tile value printed to screen.

LDA, $0441,Y @ $044D <- that address goes up by 1 each time

But the value doesn't match up with anything I'm familiar with in the nametable, so it must do something else?

If I "Step Into" these functions, they jump around to different subroutines and do all sorts of stuff that I have trouble comprehending, but probably necessary stuff in order to draw a character.

What's going on at 440 is the current character of the current line of the string, 0-indexed. So $00 at 440 is the first char and $17 at 440 is the last character on that line (aka before a line break character or something like that is reached).


EDIT2:
(https://imgur.com/1vfivP3.png)

This image shows that while 440 is incrementing, so is 202, although from something like 60 or 70 instead of 00
Title: Re: Understanding NES text routines
Post by: Psyklax on February 22, 2019, 06:03:39 am
Okay, I'm completely lost at this point. What exactly are you trying to do? Are you making a table file? Are you just experimenting? Clearly the $200-ish region in the internal RAM is being used as a temporary thing for the text before it's sent off to the VRAM, and the different numbers refer to different things. I just don't understand your end goal here, and why it's so confusing.

If I knew what you wanted to achieve then maybe I could help, but as it stands I haven't a clue.

Okay, let me open up Bio Senshi Dan and do it myself, ignoring the tutorial...

So the first letter of the prologue appears at $21A4, and it comes from $785. Just before $785 I see 84 21 FF 1D.... which tells me the game takes $2184 as the base address in the PPU, puts FF (black) in that position (which I assume is where the dakuten markers go), adds $20 to it and puts 1D (which is 'se'). Sure enough, I test the theory with the 'zo' at $21B5, which has 43 (the dakuten marker) at $2195. This is from experience, of course, but you can learn these things when you keep experimenting.

So looking before a write to $785, I see it comes from $167, so let's go there... aha, the text comes from around the $EEAB area. Where's that in ROM: $16EBB. So there's the text, I make a quick table file in Tabular based on what the PPU viewer shows me, and it's all laid out there. I also notice that to make the dakuten ones like 'zo' they write 'so' then the dakuten marker, and the game takes them both and figures out to put them on top of one another. If the next character doesn't match that value, it'll just put FF (black) in that space instead.

So, if I were translating the game, this is about as much as I'd need to know, so I don't know what else you need to know. Anything unclear? :)

EDIT: another five minutes of investigating $40 (the indirect address location) and $169 (where the address came from) points me to a hard-coded pointer at $EB38 ($16B48 in ROM) that loads the A and X registers with the location of the text ($EE8B). Change that to something else and the game will look elsewhere for the prologue. Nice. :)
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 22, 2019, 11:57:18 am
Sorry about that. I'm working with Dragon Ball 3 - Gokuu Den. The text seems like it must be compressed in some way because I've made accurate tables but can't find any of the strings except for the stats page.

If I try to search for any consecutive hex values in the dialogue, I don't find them.

I translated DBZ2 so I'm familiar with tables and how hex editing roms work, but I'm completely unfamiliar with what to do when the text isn't just stored normally.

I'm guessing it could be DTE or some other compression method because I can't even find dictionary entries for something like Gokuu.
Title: Re: Understanding NES text routines
Post by: nesrocks on February 22, 2019, 12:02:46 pm
You're gonna have to look in the PPU memory, find the address for one specific letter, then set a breakpoint to a write to that PPU address and work your way back from there to reverse engineer what it is doing.

https://www.youtube.com/watch?v=d2XkJQFs0OQ

This video explains some of that (the text in dr. mario isn't compressed, but you can see how to use the PPU mem view and the debugger to find it).
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 22, 2019, 12:12:23 pm
You're gonna have to look in the PPU memory, find the address for one specific letter, then set a breakpoint to a write to that PPU address and work your way back from there to reverse engineer what it is doing.

The last few words are the confusing part for me. I figured out the values using the PPU viewer and then figured out that, ignoring mirroring, the dialogue is written starting at $2084 in PPU MEM.

It seems like $204 or $205 corresponds with that in the RAM, but that's about as far as I get. I know that the value in 205 for instance gets changed all the time and thrown to the next spot around the 2085 area until the string is complete.

My problem is that if I wanna go into the ROM and change what dialogue is there, and therefore gets stored in $205 and then PPU $2085-$20XX, I have no idea how to do that.
Title: Re: Understanding NES text routines
Post by: cccmar on February 22, 2019, 01:37:12 pm
I believe that the text in DB 3 is stored in CHR-ROM, kinda like what Culture Brain tend to do with their games, so the pointers are not normal. If that's the case, even just finding and dumping it will be very difficult. Maybe DvD or some other hacker who's done that could give you some tips there.
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 22, 2019, 01:43:08 pm
I believe that the text in DB 3 is stored in CHR-ROM, kinda like what Culture Brain tend to do with their games, so the pointers are not normal. If that's the case, even just finding and dumping it will be very difficult. Maybe DvD or some other hacker who's done that could give you some tips there.

Thanks for this lead. I thought maybe it was just compressed like DTE and I didn't understand how to handle that (probably still don't, but maybe I'd figure it out eventually, whereas with this, maybe it makes sense I'm so confused).
Title: Re: Understanding NES text routines
Post by: nesrocks on February 22, 2019, 01:56:48 pm
There are four nametables on PPU memory: 0x2000-0x23ff, 0x2400-0x27ff, 0x2800-0x2bff and 0x2c00-0x2fff. If it's writing to 0x2084, it's in the first one (top left).

By reverse engineer I mean that you need to set a breakpoint to a write to that address and then read the assembly code and understand what it is doing and where the value is coming from. I admit I hadn't read the thread and Psyklax had already said basically exactly the same thing! Sorry :)

$204 and $203 are the temporary bytes to store the 16bit sized address for where to write to the nametable (since addresses are 16 bit and each byte is 8 bits it needs two bytes).
$205 is the data to write there.

That data is coming from $2007, which is the register to write PPU data to. I don't know exactly what is going on there, but this is the line that does it
07:E0F9:AD 07 20  LDA PPU_DATA = #$B7 (A becomes 02 after this read)
07:E0FC:9D 64 02  STA $0264,X @ $026D = #$93

Maybe it has to do with this, but I'm not sure http://wiki.nesdev.com/w/index.php/Reading_2007_during_rendering
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 22, 2019, 02:46:18 pm
There are four nametables on PPU memory: 0x2000-0x23ff, 0x2400-0x27ff, 0x2800-0x2bff and 0x2c00-0x2fff. If it's writing to 0x2084, it's in the first one (top left).

By reverse engineer I mean that you need to set a breakpoint to a write to that address and then read the assembly code and understand what it is doing and where the value is coming from. I admit I hadn't read the thread and Psyklax had already said basically exactly the same thing! Sorry :)

$204 and $203 are the temporary bytes to store the 16bit sized address for where to write to the nametable (since addresses are 16 bit and each byte is 8 bits it needs two bytes).
$205 is the data to write there.

That data is coming from $2007, which is the register to write PPU data to. I don't know exactly what is going on there, but this is the line that does it
07:E0F9:AD 07 20  LDA PPU_DATA = #$B7 (A becomes 02 after this read)
07:E0FC:9D 64 02  STA $0264,X @ $026D = #$93

Maybe it has to do with this, but I'm not sure http://wiki.nesdev.com/w/index.php/Reading_2007_during_rendering

Awesome, thank you! I've got a lot of stuff to look at now. I'll try this out over the next couple of days.

Everyone's been a big help.
Title: Re: Understanding NES text routines
Post by: Pennywise on February 22, 2019, 02:59:53 pm
Oh, DB3. The script for that is stored in the CHR-ROM, which is a very special case. My plan was to tackle that after I did a new translation of the first Dragon Ball game, but that project's been in limbo for so long, it kind of fell by the wayside.

Anyhow, I ripped the scripts for the game years back. As for how I would approach the hacking, I mulled this over years back.

AFAIK, the CHR-ROM is maxed out at 256kb, but the PRG-ROM can be expanded from 128kb to 256kb. My plan was to move the text to the PRG-ROM, split text between multiple banks etc and rewrite the code to support loading from the PRG-ROM. This would effectively remove any space constraints, but would require a bit of work to pull off.

Anyhow, the text isn't compressed and the pointers are your typical NES pointers, but with wacky offsets instead. From a basic standpoint, the game isn't hard to manage. It's only when you start digging in does the difficulty increase exponentially.
Title: Re: Understanding NES text routines
Post by: Psyklax on February 22, 2019, 03:32:13 pm
NOTE: I started this before Pennywise posted.

Okay, I was using the game from that tutorial because it wasn't clear that you had moved on to DB3 - the two games aren't going to do things exactly the same.

I can see why you had trouble, though, because I just had a look. The good news is that it's not compressed at all. :D To find it, I started with VRAM $2084 for the first character and saw that $203-205 is where the screen location and the character come from, and I used the trace logger to go from there. I reset the game, got to the dialogue screen and started the trace logger: I got an 11MB file until I reached my $2084 breakpoint. Trace logging is usually much quicker when you want to reverse engineer, because you can just go back and back until you find the root.

In this case, I found that the value in $205 goes through an ORA #$80 process (which changes it to the value it needs), and before that it comes from $441... and THAT comes from $264 (sigh). So then, the real revelation: $264 is loaded from a PPU register, as nesrocks suggested. That's pretty weird, but this is a later game with an advanced MMC chip so the screen drawing is a bit weird.

Anyway, I actually don't know how the hell it's getting into the PPU data at this point, but I don't care, because I have the actual bytes from the ROM. So I do a simple search in the ROM for the first four bytes (20 05 0B B7) and what do you know, they're at $4DEA2. :) So I made a simple Romaji table file and there you go. Here it is:

Code: [Select]
00=a
01=i
02=u
03=e
04=o
05=ka
06=ki
07=ku
08=ke
09=ko
0A=sa
0B=shi
0C=su
0D=se
0E=so
0F=ta
10=chi
11=tsu
12=te
13=to
14=na
15=ni
16=nu
17=ne
18=no
19=ha
1A=hi
1B=fu
1C=he
1D=ho
1E=ma
1F=mi
20=mu
21=me
22=mo
23=ya
24=yu
25=yo
26=ra
27=ri
28=ru
29=re
2A=ro
2B=wa
2C=wo
2D=nn
2E=xa
2F=xi
30=xu
31=xe
32=xo
33=tt
34=xya
35=xyu
36=xyo
37="
38=*
39=-
3A=_
3B=?
3C=!
3D=0
3E=.
40=A
41=I
42=U
43=E
44=O
45=KA
46=KI
47=KU
48=KE
49=KO
4A=SA
4B=SHI
4C=SU
4D=SE
4E=SO
4F=TA
50=CHI
51=TSU
52=TE
53=TO
54=NA
55=NI
56=NU
57=NE
58=NO
59=HA
5A=HI
5B=FU
5C=HE
5D=HO
5E=MA
5F=MI
60=MU
61=ME
62=MO
63=YA
64=YU
65=YO
66=RA
67=RI
68=RU
69=RE
6A=RO
6B=WA
6C=WO
6D=NN
6E=XA
6F=XI
70=XU
71=XE
72=XO
73=TT
74=XYA
75=XYU
76=XYO
77=1
78=2
79=3
7A=4
7B=5
7C=6
7D=7
7E=8
7F=9
85=ga
86=gi
87=gu
88=ge
89=go
8A=za
8B=ji
8C=zu
8D=ze
8E=zo
8F=da
90=di
91=du
92=de
93=do
99=ba
9A=bi
9B=bu
9C=be
9D=bo
B7=
B8=pa
B9=pi
BA=pu
BB=pe
BC=po
C5=GA
C6=GI
C7=GU
C8=GE
C9=GO
CA=ZA
CB=JI
CC=ZU
CD=ZE
CE=ZO
CF=DA
D0=DI
D1=DU
D2=DE
D3=DO
D9=BA
DA=BI
DB=BU
DC=BE
DD=BO
E8=PA
E9=PI
EA=PU
EB=PE
EC=PO
FE=[BRK]
FF=[END]

I might have missed something but I think that's everything in there. Just go to #4DEA2 in your favourite editor like WindHex32 EX and use that table file, and it should all be quite clear. :)
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 22, 2019, 04:02:06 pm
Oh my goodness, that seemed like magic, Psyklax. When I was looking at the PPU and nametables on FCEUX, it was suggesting that there were 3 main tables where one starts at 40 with another at C0, and then another starts at 80, which was what the story dialogue seemed to be referencing, but from what you said, if I understand correctly, it's that ORA #$80 that was causing my main confusion. It shows up as 80, but it comes from 00. Wow.

And to Pennywise, if you still end up doing it, I'm sure it'll end up better than mine, but I'll probably still go for it anyway if I can make something decent.

EDIT:
Is there a good doc for a "work smarter not harder" way to like dump and reinsert scripts? I'll be honest and say that I manually edited each line and pointer in DBZ II because I didn't quite understand how to use Cartographer and Atlas, but I'd be happy to learn how if there's a good tutorial for me to read or something since you guys already helped a bunch with this  :D
Title: Re: Understanding NES text routines
Post by: Pennywise on February 22, 2019, 04:21:02 pm
Who can say at this point. Best of luck to you.

AFAIK, there is no tutorial on how to use cartographer, Atlas etc. You can either learn how to use them or learn a high level language and code your own utilities to handle everything. If you're gonna be doing NES hacking, the former option will suffice as 95% of the games will work with those tools. They're designed to be generic and flexible and all you have to do is make a batch file to execute them.

For cartographer, just use the example included in the archive to rip the script for practice. Then adapt the command file to the game you're working on.
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 22, 2019, 04:47:33 pm
Who can say at this point. Best of luck to you.

AFAIK, there is no tutorial on how to use cartographer, Atlas etc. You can either learn how to use them or learn a high level language and code your own utilities to handle everything. If you're gonna be doing NES hacking, the former option will suffice as 95% of the games will work with those tools. They're designed to be generic and flexible and all you have to do is make a batch file to execute them.

For cartographer, just use the example included in the archive to rip the script for practice. Then adapt the command file to the game you're working on.

I was able to dump scripts with Cartographer, but was a bit confused with the pointer part and a bit scared to ruin things, but I think I'll just have to give it the college try. I'd probably rather use their tools than try to make something in C# for an individual game.

I definitely appreciate all the advice.
Title: Re: Understanding NES text routines
Post by: KingMike on February 22, 2019, 08:21:44 pm
Okay, I was using the game from that tutorial because it wasn't clear that you had moved on to DB3 - the two games aren't going to do things exactly the same.
I only noticed from the file name at the bottom of the screenshots. :)
Title: Re: Understanding NES text routines
Post by: Psyklax on February 23, 2019, 03:31:48 am
Now, I wouldn't necessarily recommend the way I do script dumping/insertion - it works for me, but I know it's a bit convoluted. I'll briefly explain what I do.

I use a program simply called Pointer Tables:
http://www.romhacking.net/utilities/502/ (http://www.romhacking.net/utilities/502/)

What I like about it is that it's very simple to use and completely adaptable to any system. You input where the pointer table in the ROM is, where the text is, and use a suitably formatted table file (Japanese must be in UTF8), and it does a simple dump, which you can then edit and insert. With a bit of fiddling, it can work with anything.

I use TextPad for all my text editing needs, but the one thing PT doesn't do is change the pointers in the ROM after inserting text, so you have to do that manually. You could write down the address of every string manually, but that takes time, so I use a simple Python script that my Dad wrote for me which gives the location of every particular byte (such as FF to signify the end of a string, for example). I can then take that list of addresses, use OpenOffice Calc to add 1 to each of them, and put the result back in the ROM. As I said, not everyone is going to be able to use my method, but for me, it works. :)

One bit of advice, especially when using Pointer Tables: make backups! I use Dropbox for my hacking folder, and make a new file every time I do something significant like inserting text with PT. Of course, I'm not stupid enough to share files directly from my Dropbox account with everyone - gotta keep that stuff private. ;) But given that hacking 8- and 16-bit games means tiny filesizes, there's no good reason not to use Dropbox.

Well, I hope this gives you a little inspiration, for what it's worth. Just remember: if you want to be good at hacking, you have to enjoy the process, not just the result. :D
Title: Re: Understanding NES text routines
Post by: Pennywise on February 23, 2019, 06:41:35 pm
Well, if you're concerned about the pointer part. All you're really doing is specifying the pointer table start/end locations and updating the ROM offset to match CPU offsets.

The CPU memory map for the NES reserves $8000-FFFF for loading/storing ROM banks from the PRG-ROM. Games will switch ROM banks in/out as needed. If you have text that's at $15000 in the ROM and the pointer is $9000, it's not pointing to a ROM offset per se, it's pointing to an offset in the CPU memory map. You need to add x bytes so that the offsets match up.
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 26, 2019, 05:58:16 pm
(https://imgur.com/NxR17KD.png)

I can not for the life of me locate the items in this game. I've seen some stuff in RAM that may indicate addresses for them, but then I go there and only see the "helper cards" nearby with names that I've translated so far. Which kinda makes sense since the items and help cards are really similar. But the hex values or the text-equivalents only seem to be found in the dialogue (like finding ドラゴンレーダー being said by Goku or Bulma for instance).
 
The closest I've gotten is some sort of list that seemed like the items, but I think it might be referenced when you get the items, which would explain why DragonRadar isn't present and why none of them seem translated after changing the values.

However, I feel like it's weird that I can't find even 1 value even though I've successfully located helper cards.

(https://imgur.com/r9eGwUJ.png)

I've tried tracing the text and didn't understand what was going on or where it may have been referencing.

---
EDIT: I checked the ROM, RAM, and PPU. Maybe because things are stored in CHR, it seems like the RAM and PPU's roles are reversed from what I'm used to. I see 4 copies of the latest text written in the RAM. But even with that, it's like the item text never seems to be written and I can't find where it's coming from.
I also tried variations on the hex searches (like using +-80 or +-40, so for 39, the ー ㏌ レーダー, I checked f9, 79, and b9 as well, looking for like B9 ?? B9 or like 39 ?? 39 -- ダ is CF, and I tried variations mixing CF, as well, and assuming the one without handakuten, タ at 4F but 39 CF 39 showed nothing after I translated all the dialogue references of the radar).

I've also tried blindly looking for sandwiched values (not necessarily just with x9) in locations in RAM close to where text is written and in the ROM and PPU and have had little luck. Looking up pairs of characters like レー and ダー also seemed fruitless.

EDIT2: Similar screens to these, like the stats page, etc. are just completely written like a whole screen in the ROM, interestingly:
(https://imgur.com/f1kucvG.png)

Assuming that maybe it was around the "Items" part, I tried editing things there and only crashed the game, so I was likely editing code or important pointers.
I also tried looking for sections like (B7 01 01 01 B7) because if it's written directly to the ROM like the stat page, then it also writes dakuten/handakuten characters (B8/B7), so I could use my alternate table for those sections and seek out spaced handakuten marks like my cavespeak dragon radar, but I had zero luck.

EDIT3: I should note that the Name Table can't understand tiles being written there. It just shows "03", which is the background color, or nothing written there, basically.

Code data logger from the moment I press the Item menu to the moment the item list pops up (instantly, not 1 letter at a time like the item descriptions), it's like 3-4 frames. There's a lot of stuff from CHR ROM displayed that doesn't resemble the text. It's really confusing.
---

Side note: I know I'm gonna need DTE (probably for like "Go", "nin", "ro", etc.) since most of the enemy names took like 4 characters in Japanese but are represented with double that amount in English. Only really something like Murasaki was able to be shortened (since his game name is hilariously ムラサキそうちょうじょうにん, which seems to mean something like Master Sergeant Jounin [like master ninja from Naruto] Murasaki -- 14 characters fitting means I should be able to name them whatever if it'll fit).
Title: Re: Understanding NES text routines
Post by: Pennywise on February 26, 2019, 10:49:49 pm
Probably sprites.
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 27, 2019, 03:19:06 am
It may very well be sprites, but I couldn't find them using YY-CHR, TLP, TM, etc. or with using YY-CHR's 8x16 mode or switching around where each letter landed.

It definitely loads all of the items at once, but for instance it knows what order it will be in since normally the DR is the first thing you get, but it's 4th on my list, below food, etc. even though it'd be first when you first load the game and don't have food.

Here's three frames in order:

(https://imgur.com/5BrVE4O.png)

(https://imgur.com/3PSMH5Y.png)

(https://imgur.com/L8FUpG7.png)

So on the first frame that the screen can possibly be displayed, before any text is written describing the first item, all the items are shown.



EDIT:
Example of 80 tbl that shows where similar windows are:
(https://imgur.com/LoXkrZs.png)


Example of typical 00 tbl that shows some names of helper cards and some techniques (both selected from windows like the items):
(https://imgur.com/enUMbZ7.png)
Title: Re: Understanding NES text routines
Post by: Psyklax on February 27, 2019, 08:45:50 am
I'd try to look at it myself, but I've no idea how to see these items in the game, since I've no idea how the game works. Could you give either a simple explanation of how to see that list in your screenshot, or provide a save state? Then I'll get to work. 8)
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 27, 2019, 12:37:09 pm
I'd try to look at it myself, but I've no idea how to see these items in the game, since I've no idea how the game works. Could you give either a simple explanation of how to see that list in your screenshot, or provide a save state? Then I'll get to work. 8)

Closest thing to simplest explanation is "Game Start", press Select for menu, choose Card/s -> Item Cards, and the item list pops up instantly, whereas textual descriptions of the items up top are written character by character, looking from strings in the CHR.

Zip called psyklax022719.zip and contains savestate near end-game with some items, and also contains very early translation ips with savestate that corresponds to the Japanese one:

https://mega.nz/#!hclCRAKa!0Zz-aGz-G9e9CwZUBpzjL_eInn5E2aICIhrUvZs1_7s

Thanks so much for looking into this. I really have tried to bang my head for the better part of a week on just this part. There are other annoying things that I'll need to figure out, like learning to use DTE for the first time and learning where the particles during battle come from (like Goku "の" critical hit or Enemy "は" took ## damage), but seeing abbreviations or errant characters isn't as bad as lack of item translations at the current state.

Of course, I'll need to figure out the pointers or whatever they're doing to display numbers on the screen, too, because I have to work around the numbers and leave blank spaces in my strings at present.

Edit/Sidenote: I found out that the item names I was translating are at least used when you can choose items in between Tenkaichi Budoukai matches during events, but possibly also when you earn the items.
Title: Re: Understanding NES text routines
Post by: Psyklax on February 27, 2019, 04:42:49 pm
Well, thanks for the info on how to see the items. I've found them - but their location is pretty weird. :D

It didn't take long at all, actually. I knew they weren't sprites because FCEUX showed them in the name table. I knew the one item at the start (Dragon Raider?) would have its first letter appear at $218C on PPU RAM, and I knew it would be $D3 because that's a katakana 'to'. Breakpoint, run, see it comes from $218 in RAM, set breakpoint to $218, run again... well I'll be damned.

At $9EDF in RAM ($1EEF in ROM) is an instruction to load the accumulator with $D3 and store it to $218. Then another for the next letter. Then another... so basically the list of items is HARD CODED. Lord only knows why they did this, there's really no logical reason. They could've saved time and space by doing a load relative and incrementing the address, but whatever, at least they're obvious (sort of).

So, how does it work? It's simple when you can read assembly. The ROM includes a routine which inserts the item name into temporary RAM, then puts it from that RAM into the PPU RAM.

Code: [Select]
00:9ED4:A9 B7     LDA #$B7
 00:9ED6:8D 04 02  STA $0204 = #$01
 00:9ED9:8D 06 02  STA $0206 = #$01
 00:9EDC:8D 0A 02  STA $020A = #$01
 00:9EDF:A9 D3     LDA #$D3
 00:9EE1:8D 18 02  STA $0218 = #$01
 00:9EE4:A9 E6     LDA #$E6
 00:9EE6:8D 19 02  STA $0219 = #$01
 00:9EE9:A9 C9     LDA #$C9
 00:9EEB:8D 1A 02  STA $021A = #$01
 00:9EEE:A9 ED     LDA #$ED
 00:9EF0:8D 1B 02  STA $021B = #$01
 00:9EF3:A9 E9     LDA #$E9
 00:9EF5:8D 1C 02  STA $021C = #$01
 00:9EF8:A9 B9     LDA #$B9
 00:9EFA:8D 1D 02  STA $021D = #$01
 00:9EFD:A9 CF     LDA #$CF
 00:9EFF:8D 1E 02  STA $021E = #$01
 00:9F02:A9 B9     LDA #$B9
 00:9F04:8D 1F 02  STA $021F = #$01
 00:9F07:60        RTS -----------------------------------------

So it first loads B7 and stores it in three places: this is the dakuten mark for 'do' 'go' and 'da'. It starts at $204 in RAM, as you can see. Then it loads each letter and puts it in each position in RAM: D3, E6, C9 and so on. If you want, I can do the whole list since a) it won't be very long, and b) I'll make sure that I don't mess anything up with the assembly.

EDIT: I just want to nitpick about your use of the term DTE. Technically, what you're doing isn't dual tile encoding, it's drawing two letters on spare tiles. It's a lot simpler than actual DTE, which is when you modify the game code so that those spare tile addresses refer to two letters instead of one. What you've done does save screen real estate - I did it myself in my first translation for certain combinations - but it's not the most elegant solution. But hey, Nintendo was happy for Pokémon to do that stupid 'PkMn' thing on the Game Boy, so what do I know. :D
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 27, 2019, 07:03:14 pm
Thank you for the help with this, so much!

Oh right, I'm using ligatures, but I'm gonna have to do real DTE and put in stuff like "Go" or "nin" so I can fit all these long Japanese names into the CHR space I have. I used them a lot in DBZ II since screen space was an issue, but it's more rom space in this one. Also connecting 'i' or 't' to other common pairings just looks better with this and most fonts, especially il, li, and ll. But I also think stuff like ki, hi, it, etc. look good. Some of mine are definitely just there to save space temporarily.

Edit: I ended up being able to translate temporarily as DrgnRadr and will hopefully get DTE working at some point to do something flashier. Got rid of the B7 handakuten marks, as well.

Thanks again, for real. I can probably do the rest of the list, but I appreciate the offer and have already past the point of crediting you (and Pennywise) on this, so I'll make sure that people know I didn't figure this out on my own.

I'll probably post again in the Personal Projects section if I need help after this.
Title: Re: Understanding NES text routines
Post by: Psyklax on February 28, 2019, 02:48:55 am
Well, the reason I asked if you wanted my help is because, after a few minutes writing my own assembly routine to replace the existing code, I did this:

(http://s346165667.websitehome.co.uk/psyktrans/db3-1.png)

Are you sure you don't want me to do the whole list? :)
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 28, 2019, 03:21:10 am
That's awesome, sure!

I wish I could do that. I need to figure out how to do ASM so I can improve my hacks.
Title: Re: Understanding NES text routines
Post by: Psyklax on February 28, 2019, 04:11:52 am
Well, I've just been through the section of code that deals with the items, and assuming there's no other items elsewhere (if there are, I might need a save state to check them out), this is the whole list. While I could try to translate them myself, I'd rather limit my involvement here to technical help rather than translation, so that either you or whoever is translating can take sole credit.

So, therefore, here's the list:

ねずみ
カメのこうら…きている / おもいごうぎ…きている / カメのこうら…ぬいでいる / おもいごうぎ…ぬいでいる
たべもの
ごちそう
ごくいしょ
ひこうき
キントウン
こガメラ

Regarding the second in the list, there are four different possibilities depending on game conditions, though since I don't know the game, I don't know the context.

Given the wasteful way the items are done in the original game, I will have tons of space to fit them all in, so just let me know how you'd rather translate everything and I'll do what I can.
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 28, 2019, 11:39:01 am
I think it's an exhaustive list of the items, but there are "help cards" which act like items and some of those share names with enemies/NPCs, etc., which is frustrating since names seem to repeat a lot in this game.
(Like Krillin is a helper card, but also talks a lot and is also an enemy and a playable character temporarily and he's listed by full name each time)

First item is Dragon Radar

Mouse
Turtle Shell...put on
/Weighted Gi...put on
/Turtle Shell...removed
/Weighted Gi...removed
Food
Meal
Gokuisho (I'll need to find this item, but without seeing the picture, I think it's a scroll)
Airplane
Flying Nimbus (or just Nimbus)
Baby Gamera

I've been doing everything that I haven't asked for help on. Graphics, translation, and basic hacking.

I know that the ones besides ごくいしょ are good, but I'm seriously confused by that one. I don't think it'd be "goddess", but then I'm not sure what it'd be without seeing the item picture.
There's a line in the game with that word after he beats an enemy that contextually I took to assume he was either reading a scroll, praying, or localized/contextualized to meditating.
He uses it to restore ki/energy, and I'm thinking it probably is a scroll, without seeing the picture, so it's got like secret/mystic teachings in it or something.

Thanks again, Psyklax.
Title: Re: Understanding NES text routines
Post by: Psyklax on February 28, 2019, 04:57:22 pm
Okay, I'm getting to work now, I think I'll change the system completely by having one simple routine and a list of items. That way it's easy to change if need be.

Also, I somehow missed one item, my mistake. Here it is:

せんず

I think it's cause it's next to Dragon Radar in the list, so I missed it (and yeah, Radar makes sense :D ).

I'll do what I can, so just let me know your translation of that one word. Only problem I have at the moment is the Turtle Shell since I have a screen limit of 16 characters, and they exceed it when saying if they're on or off... actually, if I just use capital letters instead of brackets or whatever, I think I can JUST fit it.
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 28, 2019, 05:06:57 pm
Okay, I'm getting to work now, I think I'll change the system completely by having one simple routine and a list of items. That way it's easy to change if need be.

Also, I somehow missed one item, my mistake. Here it is:

せんず

I think it's cause it's next to Dragon Radar in the list, so I missed it (and yeah, Radar makes sense :D ).

I'll do what I can, so just let me know your translation of that one word. Only problem I have at the moment is the Turtle Shell since I have a screen limit of 16 characters, and they exceed it when saying if they're on or off... actually, if I just use capital letters instead of brackets or whatever, I think I can JUST fit it.

Senzu can stay as "Senzu" or be "Senzu Bean" if it'll fit.
Even if I go the DTE route, I'd still be using the double-character tiles of at least li, ll, and il so if the 'll' will help Shell fit, then that would work. It's currently tile 42, although if that table for the items is 80-based, I guess that'd be C2.
Title: Re: Understanding NES text routines
Post by: KingMike on February 28, 2019, 10:16:10 pm
I personally don't like ligatures (I think that's what "squishy tiles" are officially called) due to inconsistent spacing between the same letters but I can understand they may be unavoidable.
(the official "PKMN" thing mentioned before... yeah, they probably wouldn't have fit a few menus without it, and I guess they decided being consistent with its usage was better than not)
Title: Re: Understanding NES text routines
Post by: Gyroballer on February 28, 2019, 11:01:46 pm
I personally don't like ligatures (I think that's what "squishy tiles" are officially called) due to inconsistent spacing between the same letters but I can understand they may be unavoidable.
(the official "PKMN" thing mentioned before... yeah, they probably wouldn't have fit a few menus without it, and I guess they decided being consistent with its usage was better than not)

I would love to do VWF, but I realize it's impractical/nigh impossible on NES, according to what I've heard.
But at least il, li, and ll tend to look better, regardless of their space saving capacity since taking up 1-2 pixels out of 8, compared to a typical 6 or so out of 8 looks pretty goofy:

(https://imgur.com/dXYO3xb.png)
(https://imgur.com/wICkUQ1.png)

So when I have enough screen space and rom space, I'll still use those 3 ligatures, likely.

But I'd love to do DTE or something to save rom space and stop using the other ligatures.
Title: Re: Understanding NES text routines
Post by: Psyklax on March 01, 2019, 06:27:30 am
Okay, I thought I'd have an easy time but it's not quite as easy. I thought I could just stick my own routine in there and be done with it, but it crashed the game. A trace log left me with something missing, and I had to step through the code line by line before I realised what was happening.

The game decides to do a JSR and then PULL THE RETURN LOCATION from the stack and put it in RAM to use as a reference for the pointer table that exists there. I can't stand it when games mess with the stack! :( Anyway, these difficulties are why I enjoy ROM hacking, and with a bit more work I'm sure I'll figure something out.

EDIT: I think it's done! :) Apply this patch to a ROM that's been patched with the English patch you gave me:
http://s346165667.websitehome.co.uk/psyktrans/db3-items.ips (http://s346165667.websitehome.co.uk/psyktrans/db3-items.ips)

If there's any problem, let me know. ;)
Title: Re: Understanding NES text routines
Post by: Gyroballer on March 01, 2019, 10:53:14 am
This is awesome, thank you so much! I had already made some changes to the title screen in the meantime and the patch was compatible with that, so everything is working perfectly.

I'd really like to be at your level someday, but for now, I'm just happy that people will be able to enjoy a more quality translation thanks to you.  :D
Title: Re: Understanding NES text routines
Post by: KingMike on March 01, 2019, 10:55:05 am
One reason I can see a NES game doing a "push the address to the stack and then return" is to effectively jump to anywhere in the ROM.
One other reason is to set up a table of functions to jump to.
Perhaps less space than a IF HEX=00 JUMP FUNC-A ELSE IF HEX=01 JUMP FUNC-B... thing.
Title: Re: Understanding NES text routines
Post by: Psyklax on March 01, 2019, 02:37:17 pm
One reason I can see a NES game doing a "push the address to the stack and then return" is to effectively jump to anywhere in the ROM.
One other reason is to set up a table of functions to jump to.
Perhaps less space than a IF HEX=00 JUMP FUNC-A ELSE IF HEX=01 JUMP FUNC-B... thing.

Here's what happens: there's a JSR $803A, and immediately following that command is the pointer table used for the items list. So $9DDA is now sitting on top of the stack, and the code in this "subroutine" pulls that address off the stack and sticks it in $11-12, then does LDA ($11),Y to get the address in the pointer table, which it stores in $13-14, and does JMP ($0013). Then it goes through the weirdest backwards way of putting the text in RAM as described in a previous post, before finally doing an RTS, which takes it to $DB7B instead of $9DDB. As a hacker, messing with the stack like that just drives me nuts, because it's hard to follow what's going on. On the PC-98 I noticed it was more common as there are specific instructions dealing with the stack, but on the NES it doesn't happen that much.