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

Author Topic: FFTA's Text Data: LZSS Compression assistance  (Read 3159 times)

Edea

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
FFTA's Text Data: LZSS Compression assistance
« on: October 08, 2011, 06:16:53 pm »
Code: [Select]
158 85 9E 55 Probably start of string
128 195 80 C3 T
128 209 80 D1 h
128 210 80 D2 i
128 220 80 DC s
64 115 40 73 Space
128 224 80 E0 w
128 216 80 D8 o
128 214 80 D6 m
128 206 80 CE e
128 215 80 D7 n
128 244 80 F4 '
144 15 90 0F go to compression, s + Space
64 219 40 DB r
128 23 80 17 i
64 203 40 CB b
128 1 80 01 b
66 216 42 D8 return to uncompressed text, o
128 215 80 D7 n
144 29 90 1D go to compression, Space + w
64 202 40 CA a
128 17 80 11 r
64 205 40 CD d
128 41 80 29 s
64 110 40 6E Newline
128 39 80 27 o
66 207 42 CF return to uncompressed text, f
128 207 80 CF f
128 49 80 31 Space
68 202 44 CA a
128 213 80 D5 l
128 213 80 D5 l
144 7 90 07 go to compression, Space + a
64 210 40 D2 i
128 9 80 09 l
152 59 98 3B
72 221 48 DD return to uncompressed text, t
128 228 80 E4 .
64 112 40 70 Display "next page" button and wait for button press.
64 99 40 63 Clear dialog box.
128 193 80 C1 R
192 61 C0 3D Compressed, retrieves six characters, "ibbon "
66 110 42 6E Return to uncompressed text, Newline
128 251 80 FB [
128 85 80 55
64 222 40 DE u
136 45 67 88 2D 43
128 252 80 FC ]
128 176 80 B0 A
160 53 A0 35
64 220 40 DC s
128 43 80 2B t
64 202 40 CA a
128 47 80 2F t
64 222 40 DE u
144 125 90 7D
216 67 D8 43
68 220 44 DC s
64 97 40 61 Wait for button press.
64 99 40 63 Clear dialog box.
32 128 20 80
40 24 28 18

Above is the code inside $4db1fd-$4db279 from a Final Fantasy Tactics Advance ROM (GBA, header).  It's an in-menu text description of the Ribbon item (which I've since turned into a gender-neutral accessory):

"This women's ribbon wards
off all ailment. (Page Button)
Ribbon
[null]All status ailments"

The problem here seems simple enough: the description has 'women' in it, and that's not how the item behaves anymore, so it needs to come out.  Since that part of the string is (blessedly) uncompressed, it was relatively simple to put in another 10-byte string (in this case I used the word 'saint').  However, now other parts of the description are incorrect, because the compressed portions of the data are retrieving information from the uncompressed portions (Example: the word 'ailment' is compressed, and retrieves 'men' from 'women'.  Since 'women' is now 'saint', 'ailment' becomes 'ailintt').

Now for the problem: working with these compressed bytes.  I've been trying to use the information on Data Crystal to figure out what the heck the 'commands' are, but every time I attempt to change one of these compressed bytes the whole text box goes haywire.  I'm not really sure where to go at this point; I've tried using Lunar Decompress and gbalzss to...well, decompress...but LD didn't understand LZ77 format and gbalzss requires pcs files (no idea what that is, Google says it's a PICT File Animation o_O).  So I just need some assistance from people who are used to working with that kind of compression so I can get this text edited >_<.  If more info is required to assist I'll try to provide it.

Also, I guess there's an FFTA modding community somewhere on the intarbutts?  I have no idea where they might be or how to find them, but if anyone has info on that I'd greatly appreciate knowing about it (as such a group's probably hacked the text already).  Thank you in advance for any assistance provided.  Also, the notes in the Code section at the top of the page are not 100% verified, quite the opposite.  Feel free to correct.

« Last Edit: October 09, 2011, 09:19:50 pm by DarkSol »

Darthatron

  • Newbie
  • *
  • Posts: 4
  • Massive Troll
    • View Profile
Re: FFTA's Text Data: LZSS Compression assistance
« Reply #1 on: October 09, 2011, 02:57:14 am »
After some research, it appears that strings are just using the LZSS compression that's already been documented. Item's description strings are located by the offsets located by the pointer at 0036D6CC in the ROM. This pointer is 084D276C in the default ROM. From this pointer, you can get the offset-pointer halfword by using the equation [0x0036D6CC] + ((ItemID - 1) * 2);

So, for example the offset for the Ribbon is:
Code: [Select]
[0x0036D6CC] + ((0x114 - 1) * 2) = 0x084D276C + (0x113* 2) = 0x084D276C + 0x226 = 0x084D2992
So the offset 084D2992 contains a halfword (2 bytes), which we then add to [0x0036D6CC]; so...

Code: [Select]
[0x0036D6CC] + [[0x0036D6CC] + ((0x114 - 1) * 2)] = 0x084D276C + 8A8C = [b]0x084DB1F8[/b] //This this offset for our compressed string.

Here, there is a halfword (no idea what it's for), a big-endian word (maybe the length of something) and our compressed string/data.

Code: [Select]
182A
0000009E
55          ""; 0b01XXXXXX; Next compressed byte is after X+1 (22) bytes.
80 C3       "T"
80 D1       "Th"
80 D2       "Thi"
80 DC       "This"
40 73       "This "
80 E0       "This w"
80 D8       "This wo"
80 D6       "This wom"
80 CE       "This wome"
80 D7       "This women"
80 F4       "This women'"
90 0F       "This women's "; 0b1XXXXYYY 0bYYYYYYYY; Track back Y (15) bytes and copy X+3 (5) bytes.
40          "This women's "; 0b01XXXXXX; Next compressed byte is after X+1 (1) bytes.
DB          "This women's r"; This is because the 0x80 was copied to the decompressed data already.
80 17       "This women's ri"; 0b1XXXXYYY 0bYYYYYYYY; Track back Y (23) bytes and copy X+3 (3) bytes.
40          "This women's ri"; 0b01XXXXXX; Next compressed byte is after X+1 (1) bytes.
CB          "This women's rib"; This is because the 0x80 was copied to the decompressed data already.
80 01       "This women's ribb"; 0b1XXXXYYY 0bYYYYYYYY; Track back Y (1) byte and copy X+3 (3) bytes.
42          "This women's ribb"; 0b01XXXXXX; Next compressed byte is after X+1 (3) bytes.
D8          "This women's ribbo"; This is because the 0x80 was copied to the decompressed data already.
80 D7       "This women's ribbon";
90 1D       "This women's ribbon w";
40          "This women's ribbon w"; 0b01XXXXXX; Next compressed byte is after X+1 (1) bytes.
CA          "This women's ribbon wa"
80 11       "This women's ribbon war"; 0b1XXXXYYY 0bYYYYYYYY; Track back Y (17) bytes and copy X+3 (3) bytes.
40          "This women's ribbon war"; 0b01XXXXXX; Next compressed byte is after X+1 (1) bytes.
CD          "This women's ribbon ward"
80 29       "This women's ribbon wards"; 0b1XXXXYYY 0bYYYYYYYY; Track back Y (41) bytes and copy X+3 (3) bytes.

etc...

Hope this helped.

It may be hard to comprehend since the text is just data until it's decompressed. It'd be best to have some tool to do the work for you.

Edea

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: FFTA\'s Text Data: LZSS Compression assistance
« Reply #2 on: October 09, 2011, 03:15:28 am »
It does, I'll mess with it some as the week progresses and report results here.  Thanks for the reply!

October 09, 2011, 08:35:01 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
Praise the gods.  Finally capable of editing the text (for the equipment descriptions at least).







Pointers for item descriptions start at $4d276c in the ROM (I think this is what was meant by 084d276c?).  Simply add $4d276c to the listed pointer to get the start of the address for the string it corresponds to (or subtract 4d276c from the string address to get the pointer values).  Here's the kicker (for these strings at least); all of them begin with a 2 byte operation.  If $02 00 is set, that string is marked for compression and will be succeeded by a big-endian like Darthatron indicated.  This operation looks like "$2a 18."  However, if $02 00 is NOT set, the whole string is considered free of compression (and you will be unable to use compression code in the string), and this looks like "$28 18."

So if you want to edit a compressed string (at least as far as item dialogue is concerned)?  Change $2A to $28, and get rid of any 'opcodes' that are not $80 or $40 (used to indicate characters ($80) and calls for things like spaces, dialog clear, etc. ($40)).  Then remove the big-endian (I just treated it as free space).  Voila, the string is no longer compressed.  Make sure to end any decompressed string with at least one $00 (more is fine and allows for filler); otherwise, the game will hang once you're finished scrolling through the text.

Haven't looked at other text types yet; I'm just happy I got Ribbon edited, to be honest.  Thanks again for the help, if anyone finds out more about how to effectively handle compressed text in this game please post it here.
« Last Edit: October 09, 2011, 08:35:01 pm by Edea »

Darthatron

  • Newbie
  • *
  • Posts: 4
  • Massive Troll
    • View Profile
Re: FFTA's Text Data: LZSS Compression assistance
« Reply #3 on: October 10, 2011, 06:43:30 am »
The pointer just after that pointer (0x084DDD28) is for Job Descriptions. But it's based on the halfword that is the NameID for the Job. (1C for Sage, 1D for Soldier, etc) It takes the same steps other than that. :)

I assume the other pointers around there point to other long texts. Dunno if that's any help to you?

itoikenza

  • Jr. Member
  • **
  • Posts: 32
  • https://www.irccloud.com
    • View Profile
    • My Twitter!
Re: FFTA's Text Data: LZSS Compression assistance
« Reply #4 on: October 11, 2011, 11:11:19 am »

Also, I guess there's an FFTA modding community somewhere on the intarbutts?  I have no idea where they might be or how to find them, but if anyone has info on that I'd greatly appreciate knowing about it (as such a group's probably hacked the text already).  Thank you in advance for any assistance provided.  Also, the notes in the Code section at the top of the page are not 100% verified, quite the opposite.  Feel free to correct.

Ask Darthatron for the ffta forum he frequents.. i'm a member there it's really good...
« Last Edit: October 11, 2011, 11:30:28 am by itoikenza »