• Welcome to Final Fantasy Hacktics. Please login or sign up.
 

FFT Text Compression

Started by Phoenix, June 26, 2008, 04:39:03 pm

Phoenix

June 26, 2008, 04:39:03 pm Last Edit: December 31, 1969, 07:00:00 pm by Phoenix
Hi all.
My nickname is Phoenix and i'm a romhacker from the italian scene (see ClomaxDominion), and i'm a SadNES cITy member.

We are working on the Final Fantasy Tactics translation project and we've reached 75% of the work.

I've read the source code of the TextCompression dll and compared it with my decompressor and i saw they compute jumps in different ways.

I reverse engineered the routine of decompression of the game via debugger and it seems like the game coputes jumps in a different way than the dll.

here is a portion of my decompressor used to copute jumps:

/* decompression code */
offset=((((byte2&0xF)<<7)-(byte2&0xF))<<1)+byte3;

/* compression code */
unsigned int pointer = 0xF00000|(((length-4)<<13)|(((offset/0xFE)<<8)|(offset%0xFE)));

where byte2 and byte3 are the second and the third byte of the three bytes pointer (F0XXXX F1XXXX etc.);

length is the number of bytes to load during decompression;
offset is the jump from the pointer position;
pointer is the computed three bytes pointer;

Max jump is also different, i think it's FE1 whereas yours is ED1, and not only FE and FF are illegal bytes for compression, there are other to exclude from compression.

Maybe i'm wrong but im working on it since december and i would like to find the truth about this algorithm  :)

Thank you in advance.

melonhead

June 26, 2008, 05:34:24 pm #1 Last Edit: December 31, 1969, 07:00:00 pm by melonhead
Quote from: "Phoenix"Hi all.
My nickname is Phoenix and i'm a romhacker from the italian scene (see ClomaxDominion), and i'm a SadNES cITy member.

We are working on the Final Fantasy Tactics translation project and we've reached 75% of the work.
Welcome. I've been anxiously watching SadNES cITy's FFT translation progress since I first saq Brisma's posting on romhacking.it.

QuoteI reverse engineered the routine of decompression of the game via debugger and it seems like the game coputes jumps in a different way than the dll.
Can you say which executable/location contains the decompression subroutine? Futhermore, does your team have a way to compress text that wasn't originally compressed (e.g. WORLD.LZW)?

Quotehere is a portion of my decompressor used to copute jumps:
/* decompression code */
offset=((((byte2&0xF)<<7)-(byte2&0xF))<<1)+byte3;

/* compression code */
unsigned int pointer = 0xF00000|(((length-4)<<13)|(((offset/0xFE)<<8)|(offset%0xFE)));
This is the reverse engineered offset calculation for decompression?

QuoteMax jump is also different, i think it's FE1 whereas yours is ED1, and not only FE and FF are illegal bytes for compression, there are other to exclude from compression.
My compression algorithm was derived from gomtuu's description, code in fftunzip.c, and trying to replicate the original output.
That is to say, I decompressed one of the files (WLDHELP.LZW, etc), then recompressed it using my algorithm.
I considered the algorithm "correct" once my compression and the game's compression matched byte-for-byte.
I think that is where I got the 0xED0 jump limit from. This is the largest jump used in the in-game text files. I never actually tried to use a jump larger than this... but if the disassembled code says it will work then I might modify my code. We'd certainly get better compression this way...

Can you say which other bytes than 0xFE and 0xFF are illegal? I noticed problems when I compressed menus (world menu, battle menu, etc), which is probably due to the appearance of 0xFF in those strings. The current version of FFTacText just simply skips those menu sections when compressing.

QuoteMaybe i'm wrong but im working on it since december and i would like to find the truth about this algorithm
I think the "truth" is whatever the game code expects... whatever we feed into the decompression algorithm should come out the way it came in.

Phoenix

June 26, 2008, 05:49:02 pm #2 Last Edit: December 31, 1969, 07:00:00 pm by Phoenix
This is the code of the routine:



"inizio pointer" = pointer start
"si ricorda da dove continuare (il pointer occupa 3 byte)" = remeber where to continue after decompression (pointer occupies 3 bytes)
"Decompressione" = decompression

I don't know where the code is, i always traced the code on the fly.

the source i've posted are respectively the code to take jump from a pointer and the code to make the pointer from jump and length.

The other illegal bytes are:

E0
E1
EB
FB
FC
E2XX
E3XX
E6XX (maybe)
ECXX
EEXX
D1XX
D9XX
DAXX

i don't know if there are other illegal bytes, my compressor  allows only characters byte in this range:
[0x00,0x55]  0x5F,0x8D,0x8E,0x91,0x93,0x95,0xFA,0xF8