+  RHDN Forum Archive
|-+  Romhacking
| |-+  ROM Hacking Discussion
| | |-+  Gameboy, debugger, and weird pointers
Pages: [1] 2
Author Topic: Gameboy, debugger, and weird pointers  (Read 2 times)
Cless
Guest
« on: October 29, 2006, 12:29:25 am »

I've tried every last damn little thing I can think of to find the dialogue pointers for Tales of Phantasia Narikiri Dungeon for GBC. I don't know what's up with it, but it's pretty bloody clear that it doesn't use anything even remotely standard.

I've moved onto trying a debugger with breakpoints. I'm no ASM guru by any stretch but I do understand some opcodes. I've run write breakpoints on where the beginning strings are loaded into RAM, and also read breakpoints on where the string is loaded from the ROM bank. Neither of which produced any useful results that I could see.

I'm using the BGB debugger. There doesn't seem to be any detailed documentation about it so I'm not entirely sure what everything does, anyway. It might be helpful if I could backtrack from the breakpoint, once I hit a RET opcode, I have no idea where the heck it jumped from...
Ryusui
Guest
« Reply #1 on: October 29, 2006, 12:49:05 am »

I had that problem too.

Look at the stack. Assuming there have been no intervening push/pull instructions, the value at the current stack pointer will always be the address a RET will jump back to, i.e. the instruction immediately after the original CALL. Even if there have been push/pull instructions, the return address will usually be close to the stack pointer.

Access breakpoints are exceedingly useful for this kind of stuff. Make one for the ROM location where text is loaded and follow the routine backwards from where it breaks.

BGB is good stuff. Learn to use it well.
Cless
Guest
« Reply #2 on: October 29, 2006, 02:02:38 am »

...blah. I must not be doing something right. I check the stack, and go back to the original CALL, only to find a RET behind it too, making things horribly confusing for me.

Man, I'd really like to get a tracelog that shows all the values being passed through the registers...
RedComet
Guest
« Reply #3 on: October 29, 2006, 10:08:23 am »

BGB can do trace logs. Run -> Trace. Or you can use F7. Smiley
Cless
Guest
« Reply #4 on: October 29, 2006, 10:34:58 am »

Yeah, I saw that. It doesn't seem to be dumging a tracelog file though...?

I've been starting a trace from the debugger, going back to the game and getting through the parts that matter, and back to the debugger where it seems to stop ('tracing' disappears from the title bar).

Maybe I'm doing something wrong...
Tauwasser
Guest
« Reply #5 on: October 29, 2006, 10:39:27 am »

It is horribly confusing. I took a peek.

I found how it handles dialog, for one.

First off, the font is at 2A:590B (that's 0xA990B). I hope you know enough ASM to hack this.
It works like this:

The routine that interprets the scripts gets a code that says "text starts". Then the textoffset is calculated. It is basically text_start_offset + word following code.
The text_start_offset is set per map and @ CCCF in Ram. (that's [low byte][high byte][rom bank]. On a sidenote: all rombanks contain their own number at [4000], so don't overwrite that no matter what or it will bug out.
So, now. The semantics are a bit unclear, since I didn't get a good enough grasp in that half an hour I spent.
Basically, there are scripttables in use.

C706 till C707 contain the actual text-offset for every character (meaning it's incremented after read). They start with several codes. One of these strings it at 27:508A with the text of the bookshelf 3 in middle row in the narikiri house (where you start off). It begins with 03D9, 03 is the code, D9 is a specific setup, I think it is what kind of textbox and so on. After that, there is the actual text starting with A2 being a 「. It can be terminated multiple ways it seems. However, this particular string is terminated with code 00. The script that interprets these codes is at 5:4094. text start offset for Narikiri house is 27:4001.

What it does is, it writes each and every tile in a ram-array (resp. info for it) until it finds a termination code. Then it stops. This table is at C74A. The pointer to the actual index is in [C748/9] (BE order). It will write:

[03][Destination in VRAM (word)][Source for gfx inrombank 2A (word)][Destination on BG (word)][tile number]

It will put other values than 03 for line breaks, stops, etc...
The routine interpreting it is called during vblank but should not be hard to find with the info provided.

The game's main loop is 0x2488 (interpreter for scripts it seems) or rather 0D:4844 looping and calling 0x2488. In case you're having trouble finding a spot in the loop that is not executed every 5 ms, put a break at 0x24B7, that's the place when you press any button. For a button, you can even break at 0x2658.

In case you wondered what these random bytes in the loop are. It goes like this:

---code---
call $04F7
db low byte
db high byte
db rombank
---code---

Beware, don't put breaks on these bytes (except for the call), as it will break the call and the game will crash because it reads improper values.

So, basically, what you wanna do to dump all the data is as follows:

- get a good understanding of the script routine. Find out what code does what and write that down.
- research text engine some more to find out what textcode (00 to 06) does what and how many bytes it requires after it before text starts etc...)
- find out from where scripts are called when you talk to a person etc.
- find the master table(s) for maps and see if it's linked to the scripts and event data
- make a program that reads the master table, deciphers the events, reads in the text_start_offset for the map, goes thru every event and computes the text offsets for every text
- dump the texts with proper notation. Like, MapX.YPZ.a being: Map Y of mapbank X (if such exist) P for person, S for sign or whatever else there might be, Z is the number of the person/sign/event  . is a seperator and a being the number of the text the person talks (in case it says more than one text)

I got some offsets for you as well:

Text Start Offsets (/ignore this: to begin with random capitalization lol)

27:4001 for Narikiri House left, middle (start of game), right
26:6C1F upper Narikiri House
21:4001 Dune city on island closest to house
1E:6A1C Heart-Tower thingy (pink)

Look for these in the rom and find some map table or something like that so you can build a program and dump all strings.

RAM-Offset:

[C700] - current tile number used
[C704] - current text line in the textbox. 00 = first line, 01 second, not sure about the rest.
[C705] - current x offset for text, it is needed to compute bg offsets for characters to write
[C706] - rombank of current text
[C707/8] - pointer to current byte of text

[C741/2] - position of upper left corner of current text box YX relative to ram bg map, not screen!
[C748/9] - pointer to latest unused index in table following this pointer
[C74A+] - table with entries to display once drawing starts

Text engine:

A1 and A4 can both be the 17th character on the current line (these two being 。 and 、)
All other characters automatically put on new line, once 16th character is outputtet (?).


Other than that option, I don't see a chance for you to dump all strings :-/ It's like Pokémon, just a little more evil :-(

cYa,

Tauwasser
DaMarsMan
Guest
« Reply #6 on: October 29, 2006, 11:36:29 am »

This is why I stopped my Furai no Shiren translation for gameboy.
Cless
Guest
« Reply #7 on: October 29, 2006, 02:08:49 pm »

Quote from: Tauwasser on October 29, 2006, 10:39:27 am
stuff

Man. All that in just half an hour. Guess I've got a lot to learn. I spent almost all day yesterday not getting very far!

Anyway, yeah, I was able to figure out C706-C708 was. I did run some write breakpoints there but I don't think those helped me much either. I was also trying to figure out what the the table at C74A was since that address got referenced, but I couldn't.

I did find a part in the ROM with a bunch of "Text Start Offsets" in rombank 7. They seem to include some other data with them.

Well, thanks. I'm having evo implement a variable width font and DTE into the game, I might have to ask him for help on this too. I figured I'd try to get some experience by at least figure out this myself, but it turned out to be a lot more complicated than I thought it would.
Tauwasser
Guest
« Reply #8 on: October 29, 2006, 03:07:16 pm »

Hmm, implementing a vwf in this mess ... would... suck! Totally rewrite every aspect of how text is handled. Suxxage with Sauerkraut...

cYa,

Tauwasser
Cless
Guest
« Reply #9 on: October 29, 2006, 03:14:23 pm »

Sounds like evo's gonna need a lot more coffee. D:
Ryusui
Guest
« Reply #10 on: October 29, 2006, 07:25:48 pm »

Whoever wrote Bistro Recipe was a real headcase. The way it's set up, I have two options: either gut the entire print routine and rewrite it from scratch, or settle on a fixed-width font of some denomination (a 3x8 like Pokémon TCG would be next to mandatory).

At least I hacked the naming system. ^_^
Tauwasser
Guest
« Reply #11 on: October 30, 2006, 02:22:48 am »

Actually, I thought about it. It might be possible do perform all the needed tasks during vblank to have a vwf in there. I don't know if the time will allow it though... That's the only second-thought... Everything else might work. However, you'd need to check first whether the table is just used for text, or if it is used for printing some gfx, too :|

cYa,

Tauwasser
evo
Guest
« Reply #12 on: October 30, 2006, 05:57:31 am »

it's impossible that you render an entire vwf during the vblank...
you need *always* to replace the existing routine, you can use part of it though Smiley
Tauwasser
Guest
« Reply #13 on: October 30, 2006, 08:21:02 am »

I'm not saying it should render an entire vwf during vblank, however, the routine in vblank get's where the tile data comes from, what dile number to put on bg and bg offset itself. There might not be a problem just parsing one letter per vblank (as the routine now in the rom does). The only thing needed therefore would be a vwf, the exact routine during vblank, checking if it only handles text and to adjust the routine that writes the tilenumbers to be used into the ram to be adjusted so it precalculates which tile to use (width table e.g.)

EDIT: @ 1:4D0A it copies the Tiles. It seems to only take rombank 2A into account, so it only can handle font and all the other things in there. It should be possible to enhance that routine to handle a very basic vwf.

cYa,

Tauwasser
« Last Edit: October 30, 2006, 11:33:36 am by Tauwasser »
Neil
Guest
« Reply #14 on: January 02, 2009, 09:19:11 am »

-necrobump to save a thread from the great board prune of 2009-
Pages: [1] 2  


Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC