AdmiralCurtiss / HyoutaTools

A collection of tools for extracting and/or reinserting data from/into video games.
Other
68 stars 21 forks source link

More extensive Tales of 'TSS' script support. #24

Open macrosscape opened 1 year ago

macrosscape commented 1 year ago

Hi there, I'm helping a friend look into patching Tales of Hearts DS, which will require the use of .TSS files. I was wondering if it's possible to add a configuration to make that feasible. Specifically looking to dismantle files for the scenarios and skits.

Alternatively, if it's possible to already make functional .tss's with an existing configuration, I'd like to know which one and how best to run that on the command line.

Thanks!

errantSquam commented 1 year ago

Adding onto this issue, I've tried tinkering with the existing code to suit Hearts' format, and to integrate it into the CLI. The furthest I got was successfully reading all the entries.

I'll leave what I've figured out here, in case it helps. Disclaimer that I'm not as familiar with C# or Tales' encryption as the repo owner, so I may be wrong on some points.

Before looks something like this (file used is Heart's LOCT00.SCP, decompressed):

5j: loct00

(empty space)

29j: isld07_3
29e: isld07_2

(empty space)

36j: isld08_3
36e: isld08_2
(...)

By splitting the instruction list into not just 0xFFFFFFFF, but also 0x3FCCCCCD, as well as deleting the code for the English pointers, nets me this:

5j: loct00
30j: isld07_3
31j: isld07_2
32j: isld07_1
40j: isld08_3
41j: isld08_2
42j: isld08_1
59j: kagd04_2
60j: kagd04_1
61j: ↵_Change_kagd04_NaviMapFile_Disposial Exception Case Select!! ↵↵
62j: kagd04_1
65j: kagd08_4
66j: kagd08_3
68j: kagd08_2
69j: kagd08_1
(...)

Which corresponds to every entry in the .TSS file for Hearts DS. Problem is, it's just these entries; the tool is unable to retrieve the text.

An example of some debug output I printed (via LoadFile in TSSFile.cs):

OneEntry[JPNIndex]: 0x1C6
JPNPointer: 0x1FE76
Position (pos): 0x0
pos + JPNPointer: 0x1FE76

From what I can glean, the relevant text is retrieved via pos + JPNPointer:

string jpn = JPNPointer == -1 ? null : File.ReadNulltermStringFromLocationAndReset( pos + JPNPointer, encoding );

Position being at 0x0 means 'pos + JPNPointer' stays at where the JPNPointer is pointing. So we get the entry name (such as isld07_3), and not the corresponding text it should be pointing at. Pos also never gets altered past the initial declaration of long pos = File.Position;...which...seems like it should always be zero? Especially since the header is read afterwards? Which feels odd to me, and I'm not sure how I'm supposed to approach this.

It feels like instead of "pos", there should be an additional value for the offset between the entry's header/name/whatever, and the text it's pointing to, but there just...isn't. Maybe it's some black magic that works for Vesperia, but not for Hearts. No clue.

I've poked around the codebase, especially the skits data section, but I can't seem to figure out what should be done regarding the .TSS files still. Any help would be appreciated.

AdmiralCurtiss commented 1 year ago

TSS files are (or appear to be, anyway) compiled bytecode in some custom scripting language. The stuff in this codebase works exactly for Vesperia and how the compiler ended up generating code for textboxes, and that's about it -- I never bothered digging more into it since it was enough for what we were doing with the translation. So I'm afraid you're on your own if you want to do anything else.