LucasArts .FNT Font File The FNT File defines the in-flight text seen in the cockpit, map interface, etc. For XWA, this applies to Software Mode only, the fonts seen in Hardware Mode are defined elsewhere. There are two variations of the FNT file, the only external clues being the filename and the filesize. 8-bit files tend to stay under 2KB in size, and have letter-only filenames. 32-bit files are much larger, around 10-30KB. 32-bit files have numerals in their filename, such as TINY64.FNT. ===== FNT Structure The following values are used through this and all of my file definitions unless otherwise specified: NAME LENGTH DESC ---- ------ ---- BYTE 1 unsigned 8-bit INT 4 signed Int32 -- Glyph[] -- struct Glyph { 0x0 BYTE Width 0x1 BYTE Height #if (8-bit) 0x2 Row8[Height] #elseif (32-bit) 0x2 Row32[Height] #endif } struct Row8 (size 0x2) { 0x0 BYTE BitData 0x1 BYTE InvertedBitData } struct Row32 (size 0x8) { 0x0 INT BitData 0x4 INT InvertedBitData } ===== FNT Detail All FNT files start with CHAR_32, or 'space'. That's a good thing, since the space is fairly important, there's no other header information in the file, it just starts with glyphs right off the bat. 8-bit files tend to have 90-95 glyphs, while the 32-bt files will have a couple hundred. I don't know if the lengths are defined elsewhere if at all. The glyphs themselves are monochrome. The BitData values are read left to right, highest bit first. Below is the 8-bit definition of the number 1 in SMALL.FNT. 00 F0 C0 30 40 B0 40 B0 40 B0 E0 10 00 F0 00 F0 ........XXXX.... 00 F0 = b00000000 11110000 XX........XX.... C0 30 = b11000000 00110000 .X......X.XX.... 40 B0 = b01000000 10110000 .X......X.XX.... 40 B0 .X......X.XX.... 40 B0 XXX........X.... E0 10 = b11100000 00010000 ........XXXX.... 00 F0 ........XXXX.... 00 F0 The width defined for this glyph is 4, which contains an extra space seen best on the inverted side. All characters within the FNT files have this space built in. The width is also why the inverted glyph cuts off. 32-bit glyphs are stored as 32-bit integers (how about that!) so when reading the hex output one must remember the byte order is reversed. Below is the 32-bit definition of an Aurekbesh J in MICRO64.FNT (writing this in the middle of another project, deal with it). 00 00 00 00 00 00 80 ff 00 00 00 01 00 00 80 fe 00 00 00 03 00 00 80 fc 00 00 00 0d 00 00 80 f2 00 00 00 f2 00 00 80 0d 00 00 00 02 00 00 80 fd 00 00 00 04 00 00 80 fb 00 00 00 04 00 00 80 fb 00 00 00 f8 00 00 80 07 00 00 00 00 00 00 80 ff ................................XXXXXXXXX....................... .......X........................XXXXXXX.X....................... ......XX........................XXXXXX..X....................... ....XX.X........................XXXX..X.X....................... XXXX..X.............................XX.XX....................... ......X.........................XXXXXX.XX....................... .....X..........................XXXXX.XXX....................... XXXXX................................XXXX....................... ................................XXXXXXXXX....................... The width is defined as 9, which is why I picked this glyph to point out the reverse byte storage. Each row has the 80 value to be used as the extra space on the inverted glyph. That is displayed 2nd, but stored third. This is only a problem when reading individual bytes, as it creates some fancy loop iterators. Treating as INT32 works best. Because the height is defined with each glyph individually, it is theoretically possible to have differing heights within a single FNT file, but the outcome is unknown and there's no real reason to with the number of FNT files to choose from.