Author
|
Topic: Variable names in GBA game (Read 1012 times)
|
stev
Guest
|
|
« on: June 18, 2007, 03:04:13 am » |
|
Okay, I'm finding that the more I mess around with ROM hacking, the less I truly know! I know about how text pointers are defined in GBA, however I am apparently unclear on how to deal with variables such as when a character's name is inserted into dialogue.
As far as I can tell, this game defines these variables as <$03><$##> where <$##> is some other number depending on what variable it's for. This works find in the untranslated dialogue, but when I insert the text elsewhere the <$03> clears the previous text and <$##> prints the actual character it corresponds to. I imagine I am missing some kind of indicator that's telling the program, "hey when you see <$03> at this location, that means I'm trying to specify a variable."
Also if there's a net resource out there that may help push my general understanding beyond pointers, I would appreciate it!
|
|
|
|
Tauwasser
Guest
|
|
« Reply #1 on: June 18, 2007, 05:33:08 am » |
|
Well, what game? Tell us a bit more and give us some examples right out or your hexeditor. That way, we can understand better what you're talking about. Also, did you watch for alignment? Some games have 1 and 2 byte codes for characters but some control codes may only start at the next even offset.
cYa,
Tauwasser
|
|
|
|
stev
Guest
|
|
« Reply #2 on: June 18, 2007, 12:59:25 pm » |
|
I didn't mention the game because I'm looking for knowledge that helps me figure these things out, not just a solution to this particular problem. The game is Mother 1+2, though. I already provided an example, that's really all there is to it. I've searched for text pointers that may refer to <$03><$##>, but I haven't found anything. One other thing I found is that I can insert a new <$03><$##> into preexisting dialogue, even if that particular part did not have one before and it works. If I use it in dialogue that has been moved, it doesn't work. So maybe it's not so much a pointer but rather something that allows its usage within a certain domain of the ROM. I'm just guessing based on what happens, which I imagine is one of the things you have to do.
I did not know anything about alignment, but <$03><$##> never seemed to appear with more than one space around it so I suspect it fell on both even and odd offsets, but I can check that.
|
|
|
|
Tauwasser
Guest
|
|
« Reply #3 on: June 18, 2007, 02:59:13 pm » |
|
Well, the only other way to know for sure is either hacking ASM, or looking for some related pointers/stuff that you don't move and see if it happens to define variables. Also, you could try repointing a japanese text with $03 in it to another japanese text with $03 in it and see if it now prints other variable names, or the one it would have in the other text.
cYa,
Tauwasser
|
|
|
|
stev
Guest
|
|
« Reply #4 on: June 19, 2007, 10:08:31 pm » |
|
I can insert any variable into any item description that is still in its original location whether or not it had a variable there in the first place and it works fine. This leads me to believe there is no pointer for that specific location, but maybe some indicator for that section of the file that anything that starts with <$03> is one of these variables. It could also be a matter of whether these variables are loaded into memory, I guess.
I'm tired of this stupid guess work. What is a good starting point for getting into ASM? How do I view the code? Do I need to make another table to figure out what characters map to what hex code and if so how do I figure that out? It's not like I can do trail-and-error like with the in-game text. Of course, once that's done, I'm still left with thousands of lines of code! From what I've seen from the VisualBoy debug output, it's a bunch of commands like mov over and over again (although I'm sure it was partially the same lines being repeated), I don't know how I'm going to find anything in there. Are there even comments for the code?
Sometimes I wonder why I'm bothering with this at all, but I do appreciate your help.
|
|
|
|
Ryusui
Guest
|
|
« Reply #5 on: June 20, 2007, 12:48:43 am » |
|
Comments get compiled out of code. That said, it's still possible to divine how code works if you know what to look for.
You're going to need two things.
First is a debugger. Get VBA-SDL-H, or better still, pony up $15 for NO$GBA. Vanilla Visual Boy Advance has a debugger, but it's crap.
Second is the text in the ROM. Find a string you can get to easily and note its position.
Now, before we continue, here's a little aside. The nice thing about GBA programming is that there's no bank swapping. Other cartridge-based consoles, for the most part, can only access a little window of program ROM at a time: this generally makes expanding ROMs a pain in the ass and necessitates some tedious math every time we crack open a ROM in WindHex or whatever and want to figure out what the address we find translates to in hardware terms. For GBA games, all we have to do is add $8000000 to the ROM address. That's it. If we're looking at data at $42 in WindHex, the GBA sees that same data at $8000042. If it's at $68106, the GBA address is $8068106. If it's at $DABEEF, the GBA address is $8DABEEF. And so on.
That said, what we want to do is set a breakpoint for that location in the ROM. Basically, you tell the emulator to freeze when it loads from that position. The entire GBA memory map, ROM and all, is just one big block, so the same procedure works if we're checking for reads from anywhere else in memory. We can also check for writes, but for obvious reasons it's pointless to check for writes to the game ROM. ^_^;
In brief, you will set the debugger to catch the game in the act of reading your problem string. And what are you going to find when the trap closes? Why, an "ldr" instruction that loads the first byte of your string (you did set the breakpoint to check for reading the first byte, correct?). You'll need a GBA THUMB ASM reference to get much further, but the next step is to set an execute breakpoint for the instruction that loads the string from the game ROM. Let the game run a few cycles through the code until the instruction loads your headache-inducing name variable byte. Step through the code and watch what it does next (again, you'll need a GBA THUMB reference to make sense of what you'll find, but note that mnemonics all have logical meanings: "ldr" is short for "load register", for instance, and by paying attention to what happens after each instruction, figuring out what some opcodes do on your own is a simple matter of logic.).
Now we start all over with the modified ROM, with the string that doesn't work. Repeat the process and watch what happens when it hits the problem code: what does it do differently, and why? If you can figure that out...well, the rest is obvious. ^_^
Good luck!
|
|
|
|
Thraka
Guest
|
|
« Reply #6 on: June 20, 2007, 09:40:41 am » |
|
Wow.. sounds like GBA hacking should take the place of SNES hacking! Especially since a lot of SNES-esque games were ported to GBA. But not all the good ones
|
|
|
|
stev
Guest
|
|
« Reply #7 on: June 20, 2007, 12:02:42 pm » |
|
Thanks for all the info! I'll definitely try it out, but maybe not until the weekend. One thing I do need to learn is the basic syntax dealing with R1-R16 and the hex values in the code (do they refer to offsets, actual values being used, or does it depend on the situation?). If you know of a tutorial around here or elsewhere that starts at that basic level, I think that will help me figure out what I'm looking at.
|
|
|
|
Ryusui
Guest
|
|
« Reply #8 on: June 20, 2007, 05:50:39 pm » |
|
"Depends on the situation".
GBA is also a bit of an oddball in that unlike NES/SNES/GB(C) programming, all instructions are the same length. Most game code is done in 16-bit (two-byte) THUMB format, although the processor default is 32-bit ARM code. A side effect of this is that most immediate (or "literal") data is stored not in the instructions themselves, but in a "literal pool" sandwiched between sections of code (and branched over): what the instructions have is a relative pointer indicating the data in question. You won't really need to bother with this unless you're actually programming, though it is helpful to know where those mysterious numbers are coming from. ^_^
|
|
|
|
stev
Guest
|
|
« Reply #9 on: June 21, 2007, 02:12:46 am » |
|
I found some time to mess with it tonight. I can get VBA-SDL-H to stop at a certain address, but how do I step through? Sadly, I've never used any debugger...I have no formal programming experience, just what I've been forced to learn for work and had to learn to complete some sort of project.
Anyway, I created log files and had them stop on the first character of the <$03><$##> string in both the original and translated states. Here's the output:
08000000 ea00002e b $080000c0 080000c0 e3a00012 mov r0, #0x12 080000c4 e129f000 msr cpsr_fc, r0 080000c8 e59fd028 ldr sp, [$080000f8] (=$03007fa0) 080000cc e3a0001f mov r0, #0x1f 080000d0 e129f000 msr cpsr_fc, r0 080000d4 e59fd018 ldr sp, [$080000f4] (=$03007e00) 080000d8 e59f10cc ldr r1, [$080001ac] (=$03007ffc) 080000dc e28f0018 add r0, pc, #0x18
They were identical in both cases. Also, this seems like an incredibly small amount of code, is it only outputting code that references this specific address? The documentation made it sound like it outputs all code from the beginning to the reference to this address.
|
|
|
|
Normmatt
Guest
|
|
« Reply #10 on: June 21, 2007, 03:59:06 am » |
|
sorry to tell you but that disassembly is just the first few instructions of the rom and has nothing to do with your problem at all, maybe if you provide some offsets and a table file maybe someone will be able to help you with debugging your problem
|
|
|
|
Tauwasser
Guest
|
|
« Reply #11 on: June 21, 2007, 04:00:55 am » |
|
You must have inputted the break code in a weird/wrong way. If you looked for it accessing rom data, then it shouldn't have breaked on the first 3 already...
cYa,
Tauwasser
|
|
|
|
Kajitani-Eizan
Guest
|
|
« Reply #12 on: June 21, 2007, 07:55:51 am » |
|
yeah, that code is the startup code for the game... there's no way that's what you're looking for.
if you're really having trouble, you can use the tracer version of VBA. it will start logging all instructions executed when you press '/' and stop when you press '/' again. the catch is, it will only log any given instruction once. meaning, if the game runs the instruction at 0x1000 and dumps it to the log, even if the instruction at 0x1000 is executed later, it won't be written to the log. still, you can dump a large trace, use the SDL VBA to figure out around what address you should be looking at, and look for that address in your trace.
or, you could do it this way. what you will want to do is differentially filter out as much as possible before your code of interest:
1. run tracer VBA and load your game. load state, load your save file, or whatever. 2. hit '/' to start logging and play around with the menus, let the music play for a bit, etc., but don't trigger the code you're interested in. 3. hit '/' to stop logging. 4. now hit '/' to start logging, play the game so that the code you're interested in is executed, and then immediately hit '/' to stop logging. 5. close VBA. (this is important.) 6. now open trace.log. search for "TRACE STOPPED" and delete everything above the first occurrence of "TRACE STOPPED", which should hopefully be most of the file. 7. examine the remaining code, which will hopefully contain what you're interested in. it helps if you have some idea of what values or addresses you need to be watching out for.
|
|
|
|
stev
Guest
|
|
« Reply #13 on: June 22, 2007, 02:03:04 am » |
|
Tauwasser: I entered the break at the address when the text starts plus the 08000000 offset. I don't know how else to do it and the debugger doesn't offer very many instructions.
Kajitani-Eizan: VBA tracer worked. Now, I have the thousands of lines of code that I expected. When I run the original ROM, I find the address of the beginning of the item description, while when I run the translated version of that sentence, I find neither the old offset nor the new offset, yet translated text does show up except for the variable part. The address was in "R5", which I assume is some memory area. I looked around this site and elsewhere and I can't seem to find a guide that explains the exactly what R0-R16 is, the syntax of ARM and THUMB and an explanation of the commands. If such information exists, I think I may be able to figure it out.
Thanks for sticking with me, people. I commend you for resisting the urge to scream n00b at me!
|
|
|
|
KaioShin
Guest
|
|
« Reply #14 on: June 22, 2007, 04:50:14 am » |
|
http://www.romhacking.net/docs/217/I know this document is GBA and DS, but we seriously have to put it under GBA category. Nobody ever finds it
|
|
|
|
|