Good endings pointer table discovered


I have found the pointer table location for the good endings. This is really good news. It means my greatest fear, of the pointers being embedded in the code, aren't reality. I can work with this. But, I haven't been able to decode the pointer table yet. It's storing pointers for more than just text, and I'm not sure how the values are calculated. Some of the values are even repeated for some reason. I'm really not sure how to work with it yet, but at least I have a place to start now. I've messed around with it a little bit and have been successful just repeating different values in different places to kind of change the order the ending visuals and audio play out, but I'm still not sure how to calculate a new pointer value for newly inserted text. 

There are actually two tables. There is a very small one right before the text, and a larger (although still pretty small compared to the ones I've been working with) at the very end of the file. I'm not sure what the difference is between the two either. Definitely need to do some more monkeying around and reverse engineering to figure it out. The table near the end of the file actually contains the references to the ending text and such though. I have figured that much out.

So, from what I've discovered with my latest testing, the pointer table only points to the start of the dialog when the picture changes. The dialog itself has the encodings for the audio files to play and line breaks and clearing the screen. The Kyosuke ending only has 4 pictures, so 4 pointers.

The pointer table near the end of the file appears at 0x1E0C. There are definitely more than 4 entries in this table, and I've found the pointers that appear to point to the text for each picture segment (except the first one, but it really isn't important as it can always start in the same place). Each line of dialog begins with a 2 byte code telling it which audio files to play. Each audio file is only 1 byte, so you can play 2 audio clips per dialog line. This is exactly how the bad endings work too. After the 2 byte audio command, there is always a 0x1E byte. I don't know what this is for. Changing it does not appear to affect anything. At the end of the dialog line, there is always a 0x0002 to end the dialog. I assume 0x00 ends the string and 0x02 clears the screen? I'm not sure. But not having the 0x02 breaks stuff. Some lines end with 0x04 or 0x07 instead, but there doesn't seem to be any difference between any of them.

I need to figure out how these pointers are calculated and what the meaning of the other pointers are.

For my own documentation purposes here are the details I know about the pointers.

the pointer table appears to start at 0x1E0C. The pointers I've found to be important are

0xECC7 = points to the first scene / picture
0xE8C8 = points to the second scene picture / text
0x14CA = points to the third scene picture / text
0x90CB = points to the fourth / final scene picture / text. 

All the opcode stuff from before is still the same, as far as playing the audio clips and such.

Until I can figure out the pointer math (and maybe it's not even possible,) I've proceeded with doing it the old fashioned, pointer-less way. It's not as flexible, but I've checked with 13 of the19 endings so far and haven't run into any issues. It is limiting in the translation, since my text length has to match the original size (or close to it. There are some unused empty bytes in there sometimes that can add just enough flexibility). But I've already written an inserter for the good things using this method and it's working quite well. I need to finish creating the input files for the inserter, but it's progress at least.

ProcessProgress
Translation 20%
Proof reading 0%
Insertion 10%
Testing 0%

So important pointers to know:
ecc7: 1st picture
e8c8: 2nd picture
14ca: 3rd picture
90cb: 4th picture

The rest don't seem to be important, but I probably need to figure out what they point to to prevent overwriting important data somehow.

I tried putting in some Indonesian in place of the english, to figure out what opcodes are necessary to move to the next picture. It looks like the current picture string needs to end with a 0x0002 to actually end. There is one case where a 0x0004 is used. I don't know what the difference is either. They appear to behave the same.

If a string ends with 0x01, it doesn't actually end the string. I think it is just a signal to clear the screen, and then it is followed with audio commands. I can do all kinds of things here by messing with this.

Audio commands basically just work by passing in a byte value for the index of the audio file. So 0x010202 will play the first audio file and the second audio file while the next string is displayed. It can end with 0x02, 0x3C, 0x1E. I replaced all of them with 0x02 and couldn't really tell any difference. Everything worked fine.

The problem is, these pointers don't point to just the text... the picture is also referenced... if I overwrite these pointers with one another, the picture, text.... everything is duplicated. So there is something else going on here. There must be another way to reference the text and only the text, I think.

So, I'm going to duplicate the beginning of the file up to address 0x14f and repeat it immediately starting at 0x150. 0x14f contains the start of the first text. So, I'm going to change the duplicated value here, and then see if I can modify the ECC7 pointer value by manipulating it with 0x150 mathematically, and see if I can get this new value to show up as the pointed to data for the first text. I'm still fairly certain that the math needs to be performed on the reversed pointer, so I'll start by manipulating C7EC first.

First, I tried running it without adjusting the pointer, and the results are exactly as I expected. The text cuts off where the data is overwritten and things break.

0xC7EC + 0x0150 = C93C => 3CC9 - exceptions.
0xECC7 + 0x0150 = EE17 - exceptions again.
0xC7EC + 0x5001 = 117ED
0xECC7 + 0x5001 = 13CC8

Comments