The FXT format contains language specific texts of the game in a slightly encrypted manner.
This converter tool allows you to convert FXT files to TXT and vice versa.
It fully supports all languages, including Japanese, and corrects many issues
that other converters handle incorrectly.
It has been thoroughly tested with all official FXT files, and converting from
TXT back to FXT reproduces the original file exactly, bit for bit.
It also detects illegal characters such as non-implemented European accent
characters or Japanese Kanji characters which are not implemented in the game.
For this reason, this converter is as accurate and reliable as possible.
Download for Windows
Usage: Just drag'n'drop an FXT or TXT file into the EXE. It will then create
an converted FXT/TXT file in the same directory. Alternatively, use it via
command line (cmd.exe).
Download
for Linux
Usage: Call it in the shell. The arguments are a bit different than the
Windows version. To converter Japanese, make sure that KANJI.IDX is present.
Source code for Delphi (Windows) and FreePascal (Linux)
TODO for the future: Create a FXTPad clone based on this converter, including real-time view of illegal characters
The file is decrypted byte-by-byte, with this code system:
0x00 xx yy is not found in the game files. It
simply prints "!".0xC3
equivalent for unmapped Japanese characters?!0x01 becomes a new-line0x84 xx becomes xx+0xBF.
This is done by GTA London for Non-English characters, but GTA 1 can also
read it.0xC3 xx is a special case found in the original French translation,
where œ is converted to C3 9D, and printed as "!", since œ is not existing
in the game font.xx gets encoded as
C3 xx+1, making sure the game will print "!", but the editor
itself (or TXT-to-FXT converter) can display the original character that
was intended by the translator.0xC4 xx becomes xx+0x3F. This is done by GTA 1 for
Non-English characters, but GTA London can also read it.[0xE0..0xFF] xx yy encrypt Japanese characters.
Only 0xE9 and 0xEA and 0xEF are used in GTA 1. Details how
to encode/decode: See below.0xFF is NOT to be ignored! This is a
misconception by many converters that 0xFF means "ignore".The first 8 bytes in the FXT file are masked. The decoding is performed as follows:
For i = 0..7: Unmasked[i] := ((Input[i] + 256 - K[i]) mod 256) + 1
(Note: The addition of 256 ensures consistent non-negative results across programming languages where the modulo operation on negative values differs. The "+1" at the end is because we will do "-1" later.)
The sequence K[i] is generated by a linear
congruential generator (LCG):
K[0] := 100 K[i+1] := (2 * K[i] - 1) mod 256
Hence:
K = { 0x64, 0xC7, 0x8D, 0x19, 0x31, 0x61, 0xC1, 0x81 }
After unmasking, the resulting bytes are processed according to the code
system described above.
In other words, this header handlings are to be COMBINED with the code system
(Most converters don't do this!).
All operations are performed in the ring ℤ/256ℤ (8-bit arithmetic).
0 1 2 3 4 5 6 7 8 9 A B C D E F
C4 0x ! À Á Â ! Ä ! Æ Ç È É Ê Ë Ì Í Î
C4 1x Ï ! ! Ò Ó Ô ! Ö ! ! Ù Ú Û Ü ! !
C4 2x ß à á â ! ä ! æ ç è é ê ë ì í î
C4 3x ï ! ! ò ó ô ! ö ! ! ù ú û ü ! !
C4 4x ! À Á Â ! Ä ! Æ Ç È É Ê Ë Ì Í Î
C4 5x Ï ! ! Ò Ó Ô ! Ö ! ! Ù Ú Û Ü ! !
C4 6x ß à á â ! ä ! æ ç è é ê ë ì í î
C4 7x ï ! ! ò ó ô ! ö ! ! ù ú û ü ! !
C4 8x ! À Á Â ! Ä ! Æ Ç È É Ê Ë Ì Í Î (used in GTA 1)
C4 9x Ï ! ! Ò Ó Ô ! Ö ! ! Ù Ú Û Ü ! ! (used in GTA 1)
C4 Ax ß à á â ! ä ! æ ç è é ê ë ì í î (used in GTA 1)
C4 Bx ï ! ! ò ó ô ! ö ! ! ù ú û ü ! ! (used in GTA 1)
C4 Cx ! À Á Â ! Ä ! Æ Ç È É Ê Ë Ì Í Î
C4 Dx Ï ! ! Ò Ó Ô ! Ö ! ! Ù Ú Û Ü ! !
C4 Ex ß à á â ! ä ! æ ç è é ê ë ì í î
C4 Fx ï ! ! ò ó ô ! ö ! ! ù ú û ü ! !
0 1 2 3 4 5 6 7 8 9 A B C D E F
84 0x ! À Á Â ! Ä ! Æ Ç È É Ê Ë Ì Í Î (used in GTA London)
84 1x Ï ! ! Ò Ó Ô ! Ö ! ! Ù Ú Û Ü ! ! (used in GTA London)
84 2x ß à á â ! ä ! æ ç è é ê ë ì í î (used in GTA London)
84 3x ï ! ! ò ó ô ! ö ! ! ù ú û ü ! ! (used in GTA London)
84 4x ! À Á Â ! Ä ! Æ Ç È É Ê Ë Ì Í Î
84 5x Ï ! ! Ò Ó Ô ! Ö ! ! Ù Ú Û Ü ! !
84 6x ß à á â ! ä ! æ ç è é ê ë ì í î
84 7x ï ! ! ò ó ô ! ö ! ! ù ú û ü ! !
84 8x ! À Á Â ! Ä ! Æ Ç È É Ê Ë Ì Í Î
84 9x Ï ! ! Ò Ó Ô ! Ö ! ! Ù Ú Û Ü ! !
84 Ax ß à á â ! ä ! æ ç è é ê ë ì í î
84 Bx ï ! ! ò ó ô ! ö ! ! ù ú û ü ! !
84 Cx ! À Á Â ! Ä ! Æ Ç È É Ê Ë Ì Í Î
84 Dx Ï ! ! Ò Ó Ô ! Ö ! ! Ù Ú Û Ü ! !
84 Ex ß à á â ! ä ! æ ç è é ê ë ì í î
84 Fx ï ! ! ò ó ô ! ö ! ! ù ú û ü ! !
The FXT format encodes Japanese characters (originally stored as Shift-JIS) into 3-byte sequences with a prefix byte of 0xEz.
To convert from FXT to Shift-JIS, the formula is:
ShiftJIS(0xEZ B0 B1) = 0xZFFE − 0x40*(0xFF−B0) − (0xFF−B1)
The game accepts the prefix Fz which behaves exactly like Ez. For example, you could use F9 instead of E9.
Step 1 — Determine prefix from Shift-JIS value:
| Shift-JIS range | Prefix | Base | | --------------- | ------ | ------- | | 0x0000 – 0x0FFF | 0xE1 | 0x1FFE | | 0x1000 – 0x1FFF | 0xE2 | 0x2FFE | | 0x2000 – 0x2FFF | 0xE3 | 0x3FFE | | 0x3000 – 0x3FFF | 0xE4 | 0x4FFE | | 0x4000 – 0x4FFF | 0xE5 | 0x5FFE | | 0x5000 – 0x5FFF | 0xE6 | 0x6FFE | | 0x6000 – 0x6FFF | 0xE7 | 0x7FFE | | 0x7000 – 0x7FFF | 0xE8 | 0x8FFE | | 0x8000 – 0x8FFF | 0xE9 | 0x9FFE | (used in GTA1 + GTA London) | 0x9000 – 0x9FFF | 0xEA | 0xAFFE | (used in GTA1 + GTA London) | 0xA000 – 0xAFFF | 0xEB | 0xBFFE | | 0xB000 – 0xBFFF | 0xEC | 0xCFFE | | 0xC000 – 0xCFFF | 0xED | 0xDFFE | | 0xD000 – 0xDFFF | 0xEE | 0xEFFE | | 0xE000 – 0xEFFF | 0xEF | 0xFFFE | (used in GTA London, but character is unimplemented) | 0xF000 – 0xFFFF | 0xF0? | 0x000E? |
The two ranges are non-overlapping, so the prefix is determined unambiguously by the Shift-JIS value alone. No lookup table is needed.
Step 2 — Compute B0 and B1:
D := Base − ShiftJIS Y := D mod 0x40 if Y < 0x3F then Y := Y + 0x40 // correction: Y always lies in [0x3F..0x7E] X := (D − Y) div 0x40 B0 := 0xFF − X B1 := 0xFF − Y
Why the correction?
The formula D = 0x40*X + Y is not a standard positional system because Y can
exceed the factor 0x40. Analysis of all known FXT codes shows that 0xFF − B1
(i.e. Y) always falls in the range [0x3F..0x7E]. A raw D mod 0x40 yields values in
[0..0x3F], which means values in [0x40..0x7E] get incorrectly folded down. Adding
0x40 when Y < 0x3F restores the correct value.
Step 3 — Output:
Output: Prefix || B0 || B1
Example
Encode Shift-JIS 0x8345 (ウ):
Prefix = 0xE9 (since 0x8345 < 0x9000), Base = 0x9FFE D = 0x9FFE − 0x8345 = 0x1CB9 Y = 0x1CB9 mod 0x40 = 0x39 → 0x39 < 0x3F → Y = 0x39 + 0x40 = 0x79 X = (0x1CB9 − 0x79) div 0x40 = 0x1C40 div 0x40 = 0x71 B0 = 0xFF − 0x71 = 0x8E B1 = 0xFF − 0x79 = 0x86 Result: E9 8E 86 ✓
The index becomes transformed (unknown) and looked up in KANJI.IDX (which is a Int16 → Int16 Lookup Table), and then gather the graphics from KANJI.BIT which has 5040 glyphs á 16x16 pixels.
KANJI.BIT is a raw graphics file where 1 bit is 1 pixel. (See the file being converted to PNG here. Your browser might not display this 16x80640 pixels picture correct, though.)
Examples:
E9 86 9C → Shift-JIS
81 5B → IDX Offset
01 02 B6 → IDX Contents
78 00 → BIT Index
00 0F 00
→ 16x16 Glyph ー
E9 8C 8D → Shift-JIS
82 CC → IDX Offset
01 05 98 → IDX Contents
E9 01 → BIT Index
00 3D 20
→ 16x16 Glyph の
E9 8E 8F → Shift-JIS
83 4E → IDX Offset
01 06 9C → IDX Contents
6B 02 → BIT Index
00 4D 60
→ 16x16 Glyph ク
E9 8F 8D → Shift-JIS
83 8C → IDX Offset
01 07 18 → IDX Contents
A9 02 → BIT Index
00 55 20
→ 16x16 Glyph レ
E9 8F 8E → Shift-JIS
83 8D → IDX Offset 01 07 1A → IDX Contents AA 02 → BIT Index 00 55 40
→ 16x16 Glyph ロThe rendering/lookup process for the FXT code E9 8F 8E is as follows:
E9 8F 8E is converted to Shift-JIS
using the formula 0xZFFE − 0x40*(0xFF−B0) − (0xFF−B1), for example
E9 8F 8E becomes
Shift-JIS 83 8D0x838D * 2 = 0x1071A.01 07 1A you will find AA 02.AA 02 becomes 0x2AA, which means: Read glyph #
682.0x2AA * 0x20 = 0x5540See also:
The decoded contents look like this:
[1001]Answer the South Park phones to get jobs. Keep your eyes open for opportunities. Remember - you mess up, we mess you up. [1002]Crazy Jimmy's dumped a car in North East Park. Find it before the cops do - or die. [1003]Bring the car to Dulli's in West Park. Move it! We got some fresh pussy here!
The number at the beginning is the brief number that can be used in mission.ini scripts.
The FXT file must end with "5C 5E", which represents "[]" in the TXT file, otherwise the game won't read the file.
The usual footer in the published FXT files is 01 5C 5E 1B 01 5C 5E which represents "\n[]\x1A\n[]". (The meaning of the 1A character is unknown; it is probably only an artefact from the original FXT development tools).
The encrypt process is similar to the decrypt process, just vice-versa.
For the extended charset, you can decide if you want to encode it with 0x84
(GTA London style) or 0xC4 (GTA1 style), since both London and GTA1 can read each
other's encodings.
The GTA London style 0x84 is recommended, because you have more usable space in the
extended characters.