News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Legend of Dragoon script rewrite (and pointer questions)  (Read 6966 times)

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Legend of Dragoon script rewrite (and pointer questions)
« on: April 05, 2016, 10:25:35 pm »
Note: There's a lot of lead-up, but this is mainly about how to deal with text and pointers.

This is something I've wanted to do for years, as I have enormous nostalgia for this game. Anyone who's familiar with it knows that the translation is atrocious, and every time I'd replay it I'd think about how I'd write a particular line. I tried several times over the years, but could never locate the text in the iso I had. I have yet to read about anyone else doing so either, though I've seen several people try.

Anyway, I decided to give it one more go, and this time I found the encoding table they used in the game files! So I have that, and now I can search and read all the dialogue. As a test, I even changed a letter in the .iso, and this worked fine. What I want to do though is be able to shorten and lengthen lines of text as need when rewriting. So a full translation hack, translating from LoD English to real English.  :P

To start, I have .iso images that I downloaded, not BIN/CUE files from the original discs. I'd use my own rips, but the final movie on the last disc is corrupted on my copy.If I convert the iso to bin/cue, the cue just has a single track instead of the file architecture. I don't know if this is a problem. I was able to save all the files from the iso using jPSXdec though, so hopefully I'm okay. The structure looks like this http://i.imgur.com/beyF8IE.png, if that helps.

Next, the hex structure, in case it's helpful:

So DRGN21.BIN contains all of the background texture assets, plus the dialogue, all mashed together in a confusing jumble. The text is mostly consecutive within a "scene", but the scenes are jumbled weirdly (and occasionally there is duplicate dialogue for some reason). Text is preceded by one of several headers: two for initiating text boxes (two different types), one for new line, one to close out a text box, and some other less major stuff. After the full text for a text box closes, there's a short block that sets the width and height of the text box itself. This is followed by the header for the next text box. The text itself uses two bytes, where the second is always 00, so there is a space between all the characters. Like so: http://i.imgur.com/NRYikHh.png

I considered the idea that it used sequential text, but I don't think that's possible. The game occasionally has choices, so it needs conditionals. Not to mention some things are out of order even within a scene. In fact, in that screenshot I think there's an unused line. So somewhere there are pointers. But I don't know which file they're in, how to find them, how to calculate knew ones, or anything like that. Any suggestions on how I go about doing that? I've read about pointers, but I still find myself completely lost here.

A couple of side question:
1) If I add or remove bytes of text, doesn't that change the offset of everything downstream from that point? So would I have to calculate new pointers for every single thing in there every time I change length? Because since it's a huge file that contains images as well as text, I don't think that's feasible.
2) Why is it bad to edit the iso instead of the component files on the disc image?

Any help would be greatly appreciated. Including assistance on this project, if anyone's interested.
« Last Edit: April 05, 2016, 10:36:09 pm by theflyingzamboni »
ROM wasn't hacked in a day.

VicVergil

  • Hero Member
  • *****
  • Posts: 726
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #1 on: April 05, 2016, 10:51:23 pm »
About 1), that's correct (and feasible, as you already guessed by taking care of not overwriting other data).

PS1 can't read game data from the disc (other than the movies and music) so it copies everything to RAM.
Most pointers in PS1 games are in fact pointing to RAM locations.
They're generally 32-bit (4 bytes) and in Little Endian (order of bytes is inverted) though lots of exceptions exist.

So you play up to a certain point where the text is already loaded and do a RAM dump. It should be a small and much more manageable file with the text and the pointers. Those pointers appear the exact same way in the ISO data, but you'd need to add/substract a constant offset to find out the address in the file from any pointer in your file.

After this, you use Cartographer and Atlas to dump and reinsert your data updating the pointers in the process. You can define limits to avoid overwriting other (graphical) data, and even set the pointer manually to point elsewhere in the file where there's data.

I guess this answers your second question a bit.
Besides a file being much more practical for pointer calculations, in some cases you might want to make that file bigger (if you can get away with it) so doing this by hex editing the whole iso (rather than reinserting the modded file with a tool rebuilding the ISO's TOC) is not feasible. Same goes for most systems with file trees (DS for example).

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #2 on: April 05, 2016, 11:55:38 pm »
Thanks for the quick reply!

Okay, I dumped the memory, opened it up, and found the text. I do not know how or where to find the pointers in it though. In the dump file, I found the header character A5 at 0x001BDA55. I tried searching 55DA1B in the DRGN21.BIN game file, and I came up with nothing. The closest I could find was DA55, and 1BDA55 vastly separated from the text, but I'm sure that's coincidence. I even made a copy of the full iso and changed every instance of 1BDA55 and 55DA1B to the offset from the next line of text in the memory dump (1BDAAD). Didn't even break that part of the game, never mind point it to a different line of text. Am I fundamentally misunderstanding how pointers work? I just want to find the bytes that say "go to this line of text", but it seems to elude me.


Also, I'm unclear on what you mean by feasible. Do you mean it's possible for me to add/remove data from the file (i.e. make a line of text longer), and get corrected pointers/offsets for the rest of the data in the file?
« Last Edit: April 06, 2016, 04:08:40 am by theflyingzamboni »
ROM wasn't hacked in a day.

BlackDog61

  • Hero Member
  • *****
  • Posts: 784
    • View Profile
    • Super Robot Wars A Portable translation thread
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #3 on: April 06, 2016, 02:53:06 pm »
I found the header character A5 at 0x001BDA55. I tried searching 55DA1B in the DRGN21.BIN game file, and I came up with nothing.

Most of the time, pointers are relative to a base address.
In other words, while the memory pointed is 0x001BDA55, if there is an implicit convention that all pointers are relative to, say, 0x001A1000, then the value of the pointer would be  0x0001CA55.
In general, when I look for pointers, I look for a series of increasing numbers closely before or closely after the text itself. Then I assume these are pointers, the first one pointing to the first text. I deduce the "base" from there. And check if the following few values correctly calculate into the startof the next texts.
Is there anything like that there?

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #4 on: April 06, 2016, 08:03:26 pm »
Most of the time, pointers are relative to a base address.
In other words, while the memory pointed is 0x001BDA55, if there is an implicit convention that all pointers are relative to, say, 0x001A1000, then the value of the pointer would be  0x0001CA55.
In general, when I look for pointers, I look for a series of increasing numbers closely before or closely after the text itself. Then I assume these are pointers, the first one pointing to the first text. I deduce the "base" from there. And check if the following few values correctly calculate into the startof the next texts.
Is there anything like that there?

I searched forwards and backwards until my eyes hurt, and it all looked like a jumbled mess to me. Almost everything in those areas alternates some byte  with 00, 01, 02, or 09 to the right most commonly, with occasionally another 0x, and sometimes a short sequence of 3-5 Fx's, mostly FF. My eyes can see no pattern anywhere in there, and I looked for scores of lines in either direction. I know that two of the text lines should have an 0x56 difference in value, but that hasn't helped me either. I'm not sure if it's in there and I'm missing it, or if it's somewhere else entirely.
ROM wasn't hacked in a day.

DackR

  • Full Member
  • ***
  • Posts: 130
  • Mo~
    • View Profile
    • Hackaday.io Page
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #5 on: April 07, 2016, 01:15:57 am »
I think you're headed in the right direction. It should be noted that pointers are not always going to be close to the data that is being referenced by the pointers.

You are most likely going to be looking for a two-byte (word value, little-endian) pointer for the text.

Here is a good example of determining pointers for psx games:
http://www.romhacking.net/documents/372/

Here is another basic guide that may be of assistance:
http://www.romhacking.net/documents/63/

Hope this helps a little bit.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #6 on: April 07, 2016, 03:21:42 am »
I think you're headed in the right direction. It should be noted that pointers are not always going to be close to the data that is being referenced by the pointers.

You are most likely going to be looking for a two-byte (word value, little-endian) pointer for the text.

Here is a good example of determining pointers for psx games:
http://www.romhacking.net/documents/372/

Here is another basic guide that may be of assistance:
http://www.romhacking.net/documents/63/

Hope this helps a little bit.

I actually read both of those multiple times before I posted here. I wanted to make sure to do my homework first. Unfortunately, the method in MadEdit's guide doesn't really help me, because the pointer is not simply a 2-byte little-endian reference to the text's location in the PSX memory. To make sure, I used the hammer-smash method of ROM hacking and replaced every instance of 0xACDA, 0xADDA, and 0xAEDA in a copy of the iso with 0x54DA, 0x55DA, and 0x56DA, just in case I was wrong about what byte the pointer should be pointing at (the 00 or A5 of the 00A5 text header, or the first letter). Not only did the text not change after about 6000 byte pair replacements (using replace all in HxD, don't worry, I'm not insane), the iso and save state for the level still loaded and functioned. So it's definitely not that.

I suspect it's likely that there is a base address that I need to subtract to get my pointer. Without being able to find and recognize a pointer though, is there some way to figure this out? Right now it seems like a circular problem: I need the base address to find the pointers, but I need a pointer to figure out the base address. :|
ROM wasn't hacked in a day.

STARWIN

  • Sr. Member
  • ****
  • Posts: 449
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #7 on: April 07, 2016, 07:41:57 am »
Speaking with some uncertainty..

1. Even if you find-replace all found in the image, some of them may technically be split between sectors (there is cd format stuff entered for each sector and this can break the sequence)

2. If you happened to only check by loading the save state, it could very well load that memory area from the save state and never load it from the modified image.

3. In general the all-purpose tool is a debugger emulator.. if you don't mind reading asm a bit. The code of course knows what it does with any numbers you have found.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #8 on: April 07, 2016, 04:02:36 pm »
Speaking with some uncertainty..

1. Even if you find-replace all found in the image, some of them may technically be split between sectors (there is cd format stuff entered for each sector and this can break the sequence)

2. If you happened to only check by loading the save state, it could very well load that memory area from the save state and never load it from the modified image.

3. In general the all-purpose tool is a debugger emulator.. if you don't mind reading asm a bit. The code of course knows what it does with any numbers you have found.
1. That's unfortunate, and I don't know what I'd do if that were the case.
2. The save state is prior to the area with the dialogue I'm looking at. I've modified the text within existing space constraints successfully, so I know that the changes take in the save state.
3. I've looked through the disassembler in psxfin, but asm means nothing to me. I found a list of the codes, but I still don't really know what they're doing. I think I've figured out that 0xXXXX0009 denotes an instruction to jump to 0xXXXX. And I think that 0xXXXXXX0F is jump and link to an offset >0x04000000 or something near that, and 0xXXXXXX0E is JAL to one less than that. So by looking at these jump instructions, could I figure out the base address?

So for example, at 0x001BDA34, I have 0x7BFC0009. This is in little-endian, so the instruction is 0x0900FC7B, and in assembly that's jump to 0x0403F1EC. Is their some way to use this info to get the base address?

Also, I'm not sure how it goes from pointer to address. There are a couple jump commands above this one. One is 0x0900FCAC, or jump to 0x0403F2B0. But these don't have the same additive relationship. FCAC - FC7B = 31, while F2B0 - F1EC = C4. So is there some other method being used to get from a pointer to an address?

I was thinking one of these sets of jump commands were the right ones, because there are two closely grouped sets of 3 just a short ways above the text, but they're not quite in ascending or descending order, and none of the differences match up with the offset difference between the lines of text themselves. But if it's not simply adding or subtracting, maybe they still are?

EDIT: Scratch the second half of bullet 3, the 0x0090 just means the first two bytes of the target are 0x0403. I have no idea how it know it's a jump command. That still leaves the inconsistent translation issue.

EDIT 2: If it's helpful to figure out the sort of operation it's doing, I found this. It clearly has some sort of byte-by-byte pattern, but I'm not really sure what it means:

0f0a003c: jal 0x042800f0
0f0a003d: jal 0x042800f4
0f07003e: jal 0x041c00f8
0f07003f: jal 0x041c00fc
0f070040: jal 0x041c0100
0f000000: jal 0x04000000
0f0e0042: jal 0x04380108
0f110043: jal 0x0444010c

Seems like an increment of one in the second byte on the left is an increment of 4 in the second byte on the right. Same sort of situation for the last byte. Also, both 0x00 and 0x40 equate to 0x00, and looking at the first entries in the list, 0x30 should equate to 0xc0. I think both the second and last byte follow this pattern. The second to last byte is 0x00 if the counting for the last byte started at 0x00, and 0x01 if it started at 0x40. Presumably it would be 0x02 if the counting on the last byte started at 0x80. I also found later that for the first byte, 0x0c equates to 0x00, so the first byte is a 1:1 increment starting at 0c I think.

Is this some kind of compression algorithm? And if so, does anyone recognize it/know a good way to go between the compressed and decompressed bytes? And also which one is compressed? And will any of this help me find those pointers?

EDIT 3: Looking at more examples, the pattern actually seems to be more complicated than this, and follow different rules in other situations, where, say, the first byte on the right column is 0x00, meaning it's 0x0c on the left. It's a little confusing because 0x04 = 0x10, which is normal, but I saw 0x00 = 0x02, 0x01, or 0x03 when the first byte was 0x0c, which does not fit the pattern.

EDIT 4: I think the basic j jump command may be more straightforward, where everything on the right is 4 times the corresponding byte on the left, with the first byte starting at 0x08 = 0x00, which I might note is 4 less than the 0x0c = 0x00 starting point of the jal command.

It should also be noted that both these patterns break down utterly in a different section of the memory, so I have no idea about anything at all anymore.  :-\ Maybe you use the pattern to make the conversion, and then have to add an offset?
« Last Edit: April 07, 2016, 05:30:11 pm by theflyingzamboni »
ROM wasn't hacked in a day.

BlackDog61

  • Hero Member
  • *****
  • Posts: 784
    • View Profile
    • Super Robot Wars A Portable translation thread
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #9 on: April 07, 2016, 05:39:53 pm »
A PSX instruction in ASM is 4 bytes, so what you've written doesn't make senseto me (the addresses are separated by 1 byte, in the first column).

Get a debugger. Find the text you want in RAM BEFORE it is displayed. Put a memory read breakpoint on it. You will thus see how it is used.
If you cannot find the text before it appears then save state before it appears. Findit in memoryafter it appears. Put a memory write breakpoint on the address where the text will appear. load the save back & replay.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #10 on: April 07, 2016, 06:43:48 pm »
A PSX instruction in ASM is 4 bytes, so what you've written doesn't make senseto me (the addresses are separated by 1 byte, in the first column).

Get a debugger. Find the text you want in RAM BEFORE it is displayed. Put a memory read breakpoint on it. You will thus see how it is used.
If you cannot find the text before it appears then save state before it appears. Findit in memoryafter it appears. Put a memory write breakpoint on the address where the text will appear. load the save back & replay.

Maybe I didn't explain it well, or maybe it really doesn't make sense. All I know was that was what the disassembler said. If it clarifies, the left column is not the offset of those commands, I just didn't include that. They were all sequential, separated by 4 bytes, like they're supposed to be. Anyway, forget that for now I guess.

Apologies, but I'm not sure what I'm supposed to be looking for in the debugger? I set two breakpoints, one for each sequential piece of text, and they triggered just fine. For both of them, the disassembler skipped to a NOP line a couple lines below a addu r2, r2, r21 command (so I guess adding r2 to r21 and storing it in r2). Sure enough, looking at the registers in each case, the offset of the text I broke at was in both r2 and r21 at the breakpoint. I'm not sure what this tells me though, because I don't know what put them there. Do I need to try to work backwards through the disassembler commands to find out what command put the address in r21 to begin with?


EDIT: I figured out one more thing: the command after the addu is lhu r4, 0x0000(r2), so it loads the half word at 0x001bda54, which is 0x00a5, or the text header code. Sure enough r4 contains 0x0000a500. Unfortunately, that still leaves me not being able to figure out what told it to go to 0x001bda54 in the first place. Or 0x801bda54 as it says. Is there a debugger that will allow me to step backwards? I'm using the PSX 1.13 debugger, and it seems to only allow me to step forward through the code.

April 08, 2016, 03:57:24 am - (Auto Merged - Double Posts are not allowed before 7 days.)
Okay, I got PCSXTrace working, so I can look at the tracebacks. I'm a bit confused though. Looking at the traceback for the first line of text, I see a line that loads the word offset 0x0030 from 0x800be148, which seems to serve as some kind of base address for this portion of code. That word is 0x001bda54, the address that I mentioned in my last post that contains the start of that first line. I look in the dump file at the offset from the base address, and it's 0x54da1b80. Fantastic.

But the second line of text starts at address 0x001bdaac. So using the traceback, I found where it loads that word from offset 0x0034 from the new offset, which seems to be the new base address. So it loads 0x801bdaac into memory, which should be great. Except when I open the memory dump and go to that offset from 0x800bdf38, instead of 0xacda1b80, I find 0xc4cd1b80. I thought maybe an offset, but e148 - bdf8 =/= daac - cdc4. So it's reading the right thing into memory, but I seem to have the wrong thing in the dump, which could make it rather hard to find anything.
« Last Edit: April 08, 2016, 03:57:24 am by theflyingzamboni »
ROM wasn't hacked in a day.

STARWIN

  • Sr. Member
  • ****
  • Posts: 449
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #11 on: April 08, 2016, 09:02:15 am »
Sounds like a good start to me. There is usually some confusion to new things, so it can take a while before you know what the right question is.

VS a trace, setting breakpoints allows you to see the entire routine in question and the memory shown in the emulator is accurate at that point. If you take a RAM dump it can of course get more and more inaccurate as the game writes new stuff to RAM according to the routines it executes.

If you manage to break at an interesting enough routine, I suppose you could show a screenshot of that around the break. Anyway just remember that your goal is to find something in the ROM (iso image or more preferably a file extracted from it) that defines where a given text starts and how long it is.

Single numbers are never little-endian. Only their representation in memory as a sequence of bytes is. For clarity when you write 0xaabbccdd it is ok to always write it normally. As byte sequence dd cc bb aa though.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #12 on: April 09, 2016, 01:31:59 am »
I've tried looking around the break point, but there are a lot of jumps, including one a few lines before the break. As far as I can tell, this means it had to have jumped in from somewhere else to a line after that jump. I have no idea where from though. Looking at the traceback, I found a little more, referring to this area of the hex: http://i.imgur.com/NTYbz6D.png

So the text starts at the yellow address. To get that address, it pulls the red address from somewhere in the RAM where it already loaded it at some indeterminate previous point. It loads the word at that address (0x001BDA3C), which is 0x00000006. It then shifts this value left by the immediate 0x0002 to get 0x00000018. It then adds that value to its address, which according to math points it at the yellow address, 0x001BDA54.

Is this some kind of relative pointer system? And is there some way to use this to focus my search?

EDIT: I answered my own question. The answer is yes, it is a relative pointer system. That red address is the start of the table. The next two 32-words correspond to the offsets of the 2nd and 3rd blocks of text, respectively, relative to that first offset. So it calculates a pointer by taking the base address of the table and shifting it left 0x02 to get the relative offset. The 4th-6th words refer to the offset of the vertical size of the text box, which is the second 32-bit word following an 0xFFA0 end text block command. I think it must read it backwards until it hits that 0xFFA0 or something to get the horizontal dimension as well. Somehow it already knows what kind of text box it's creating, though. The first line has the name "Dart" in a header followed by a newline character, followed by the main text, whereas the second block has no header. So if I change the second pointer to the first text block, everything, including the name, just shows up in the main text body. Vice versa, the second line of text goes into the header, and then it just reads garbage forever because it never finds a newline character. Since I won't ever change the type of text box, this should never be an issue.

I tested this theory out on another section of text, and it worked out fine. Turns out the pointers were immediately above the text all along. I had thought at one point that that must be a pointer table, but I half-dismissed it because I couldn't figure out how they were doing the pointing. So now they should all be easy to find.

Thanks for all the help! I couldn't have done it without your advice. I just had some difficulty turning that advice into results thanks to my newness at this. :P

So is my next step trying to use Cartographer and Atlas? Will those let me pull that script and those pointer tables out of the file in the ISO, and insert or delete bytes of text as needed, while updating the pointers appropriately? Or will I totally screw up everything else in the code if i start adding and deleting bytes? I can see how the pointer table could be updated, because I can tell those programs where to find it, but I guess there are plenty of pointers to other things that I don't know about that would be messed up if the offsets got changed by byte insertions. So am I limited to the space I have within each text block, plus whatever random empty space I can find in the file to point to? And would sections that just repeat "dummy co12" (code, I guess) be alright to co-opt for additional text?

Also, any good resources/tutorials/examples on how to use Cartographer and Atlas? I've read their documentation, but more help is always... helpful.

Also, sorry for these massive text walls describing every detail of my progress, failures, and findings. You're all wonderful for reading through all this and still offering help.
« Last Edit: April 09, 2016, 01:53:36 am by theflyingzamboni »
ROM wasn't hacked in a day.

BlackDog61

  • Hero Member
  • *****
  • Posts: 784
    • View Profile
    • Super Robot Wars A Portable translation thread
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #13 on: April 09, 2016, 12:56:35 pm »
I tested this theory out on another section of text, and it worked out fine.
[...]
So is my next step trying to use Cartographer and Atlas?

First, I'd check if there are a lot of sections of text, and if yes, if there is a "table for the tables".
Also, you want to verify that you've got the whole story by changing text ends and running the gameto verify it goes as planned. Step by step, up to increasing the text sizes.

Once that is cleared, then you'll know if carthographer+atlas cancut the deal. ;D

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #14 on: April 09, 2016, 02:36:03 pm »
First, I'd check if there are a lot of sections of text, and if yes, if there is a "table for the tables".
Also, you want to verify that you've got the whole story by changing text ends and running the gameto verify it goes as planned. Step by step, up to increasing the text sizes.

Once that is cleared, then you'll know if carthographer+atlas cancut the deal. ;D
Oh yeah, it's the first disc of a huge RPG. There's a whole lot of sections of text. Any suggestions on what to look for when looking for a table of tables? are they more likely to be absolute pointers? Or any general trends on where games have them located? That would certainly make things more difficult for the moment.

What do you mean by changing text ends? Do you mean removing 0xFFA0 end text block commands?


EDIT: I discovered I miscounted a bit for the text box dimension pointers, they actually start on the first/horizontal dimension word, and read left to right. Presumably these get read first. I also forgot to mention that they have their own separate relative pointer table, so they're not part of the text pointer table, but a new one immediately following it.

EDIT 2: I don't know if this is what you meant, but I was able to extend the first block by overwriting into the second text block, and then changing the pointers for the first text box dimensions and the start of the second text block. The text in game changed how I expected it to based on that. So I think I do have the full story with the text pointers, meaning it's just that possible table of pointer tables issue left. I don't even know if they're there. I mean, probably, but I'm not sure. So yeah, any suggestions you could offer on finding that would be greatly appreciated.

EDIT 3: If I use an ASCII table, the file containing the dialogue is segmented into parts headed by a code that says "MRG" with some padding code before it. The dialogue for a particular level is contained within one of these subsections. Is it more likely that there is a single table of pointer tables for the entire file, maybe somewhere near the top, or is it more likely that there's a separate one for each level, containing only references to pointer tables within that subsection?
« Last Edit: April 09, 2016, 09:36:45 pm by theflyingzamboni »
ROM wasn't hacked in a day.

BlackDog61

  • Hero Member
  • *****
  • Posts: 784
    • View Profile
    • Super Robot Wars A Portable translation thread
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #15 on: April 10, 2016, 04:15:10 pm »
EDIT 2: I don't know if this is what you meant, but I was able to extend the first block by overwriting into the second text block, and then changing the pointers for the first text box dimensions and the start of the second text block. The text in game changed how I expected it to based on that. So I think I do have the full story with the text pointers, meaning it's just that possible table of pointer tables issue left. I don't even know if they're there. I mean, probably, but I'm not sure. So yeah, any suggestions you could offer on finding that would be greatly appreciated.
Yes, that's pretty much steps 1 & 2 of what I had in mind. The next question is: can you make the text section bigger than it currently is? (I mean - not just text 1 eating up some bytes from text 2 to grow, but all of the texts keeping their sizes and yet increasing size for 1 of the texts.)That will tell you more than me trying to make assumptions on a game I haven't spent time understanding.

EDIT 3: If I use an ASCII table, the file containing the dialogue is segmented into parts headed by a code that says "MRG" with some padding code before it. The dialogue for a particular level is contained within one of these subsections. Is it more likely that there is a single table of pointer tables for the entire file, maybe somewhere near the top, or is it more likely that there's a separate one for each level, containing only references to pointer tables within that subsection?
Sorry, I don't have a clue about that. Both are possible. Try increasing the size of 1 section "not at the start" to see if it impacts before or not, maybe?

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #16 on: April 10, 2016, 05:28:54 pm »
Yes, that's pretty much steps 1 & 2 of what I had in mind. The next question is: can you make the text section bigger than it currently is? (I mean - not just text 1 eating up some bytes from text 2 to grow, but all of the texts keeping their sizes and yet increasing size for 1 of the texts.)That will tell you more than me trying to make assumptions on a game I haven't spent time understanding.
So I tried that quickly, just with regular hex editing. A couple of things happen, depending on what was done:

1: If I try to let the iso load normally and get to the start menu, it stops when it gets to the Sony Computer Entertainment America screen. The debug shows that it's still moving things around in memory, so it's not completely frozen, but it can't proceed past that point.

2: If I load a save state to a level prior to the one I'm editing the text for, the game runs normally until it tries to load that area. Then the screen goes black, while the sound effects from the previous area continue to loop. Nothing happens after that.

I tested again on the level after, and got the same result. Everything up to the altered area works, but the altered area will not load.

However, I realized that the preceding area of course occurred up-code from the alteration. So I edited a different level, then loaded a save state from a level after it, both in the game and in the code. As soon as I tried to leave the area that was already loaded into memory from the save state, black screen, looping sound.

So apparently altering the size of the code impacts anything after that point, but does not affect anything above it. Does this narrow down the issue any? I'm not really sure what the implication is, other than that somewhere, stuff is no longer pointing at the right location. It doesn't seem to even say whether the table of tables is relative or absolute, since either would be screwed up by such a change. I think this at least indicates that I have one, though? Possibly more than one? Like, maybe one within each level's section of code that points to pointer tables for that level's assets, and another near the top of the file that tells it where each level sub-section starts?
« Last Edit: April 10, 2016, 05:36:00 pm by theflyingzamboni »
ROM wasn't hacked in a day.

BlackDog61

  • Hero Member
  • *****
  • Posts: 784
    • View Profile
    • Super Robot Wars A Portable translation thread
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #17 on: April 11, 2016, 03:00:51 pm »
I think this just proves there are other pointers / references somewhere else in the game, which need updating. ;D
You may be able to find this by browsing the file, looking for pointers to the start of text sections. Or size info in the text sections? Otherwise the debugger can be your friend (you'd have to walk back in time again to find where the "base" address for the text comes from.)

Have fun!

STARWIN

  • Sr. Member
  • ****
  • Posts: 449
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #18 on: April 11, 2016, 04:03:47 pm »
I'm not sure how you exactly added stuff there.. if you just insert new data to the iso image (shifting everything after that offset forwards), it shouldn't even be a valid image after that. If you insert new data to an extracted file, you cannot insert it back without changing the filesystem, because it doesn't fit into its place anymore. If the game respects the filesystem, then that toc stuff that GHANMI mentioned is relevant (so basically, make the filesystem point to the right places as far as files are concerned). If you do that, then it will probably still break until you fix all local pointers within the file and such. Though if the file contains anything related to any other system, it would be a pain to understand all that in order to repoint it.

Even if everything is in order and you can expand the file to fit more letters, at least theoretically there might not be free space in the RAM for the bigger file to fit there without overwriting something. But I don't know how realistic this is or if there is more to PS1 memory management than that. I guess it varies from game to game so no one easily says anything certain here on the forums.

I never felt comfortable with free space issues, they feel so uncertain to me.

But I'm not a translation hacker, so those folks would have much more experience in repointing stuff. I don't know how much you can do without basic asm knowledge though, as what you say leaves it a bit uncertain how much you'd like to avoid that level of technicality.

theflyingzamboni

  • Jr. Member
  • **
  • Posts: 91
    • View Profile
Re: Legend of Dragoon script rewrite (and pointer questions)
« Reply #19 on: April 11, 2016, 04:44:53 pm »
I'm not sure how you exactly added stuff there.. if you just insert new data to the iso image (shifting everything after that offset forwards), it shouldn't even be a valid image after that. If you insert new data to an extracted file, you cannot insert it back without changing the filesystem, because it doesn't fit into its place anymore. If the game respects the filesystem, then that toc stuff that GHANMI mentioned is relevant (so basically, make the filesystem point to the right places as far as files are concerned). If you do that, then it will probably still break until you fix all local pointers within the file and such. Though if the file contains anything related to any other system, it would be a pain to understand all that in order to repoint it.

Even if everything is in order and you can expand the file to fit more letters, at least theoretically there might not be free space in the RAM for the bigger file to fit there without overwriting something. But I don't know how realistic this is or if there is more to PS1 memory management than that. I guess it varies from game to game so no one easily says anything certain here on the forums.

I never felt comfortable with free space issues, they feel so uncertain to me.

But I'm not a translation hacker, so those folks would have much more experience in repointing stuff. I don't know how much you can do without basic asm knowledge though, as what you say leaves it a bit uncertain how much you'd like to avoid that level of technicalities.
To you first question, I just added 4 extra bytes to the iso. It wouldn't recognize it at first, so I created a .cue file for it and it loaded. Maybe it wasn't actually doing what I thought it was doing, but that's what I did.

As to the other stuff, that sounds terribly complicated, and like it would probably take more time than I have to learn it all. The RAM part especially I was giving some thought. I have no idea how the game decides where to put level sub-files in memory, which means I also don't know how to change what it puts into memory and where.

Learning asm might be a bit much at the moment. I know some very minimal basics that I've picked up in the last few days. I understand some of the basic operations, but basically nothing about the when and why they happen. It's just a bunch of semi-random byte shuffling to me. I'd like to avoid it if at all possible, just because I don't really feel like I have the time to learn this stuff that deep down.

I'm starting to think that if I'm going to do this, I'll just have to content myself to getting creative with the writing so that I can keep it within space limitations. That, or find someone who understands more about how the PS1 handles these things and has the time to help out on a random project. Speaking of, if anyone knows someone with the appropriate knowledge willing to join in on a project, please point me their way. I'm not necessarily looking for someone to do this for me. It's just that, as much as I dislike admitting my own limitations, I don't know that I can figure this all out on my own without someone else's assistance learning the ins and outs of this particular game.
ROM wasn't hacked in a day.