FONT (File Format)

From Retro Modding Wiki
Revision as of 18:41, 27 March 2015 by >Aruki (→‎Kerning Table)
Jump to navigation Jump to search

The FONT format defines fonts that can be used to display text in-game.


This file format needs more research
There's some unknowns in the header. Also, some version 4/5 fonts have outlines on their textures - how do these work?


Format

Header

The header has a couple minor differences depending on the version. Version 1 (MP1 Kiosk Demo) is missing the value at 0x18, and starting in Version 5 (MP3/DKCR), the texture ID is 64 bits. Those are the only changes, though (and for that matter, those are the only differences in version 1/5).

Offset Type Size Description
0x0 char[4] 4 "FONT" magic fourCC
0x4 u32 4 Version; see below
0x8 u32 4 Unknown
0xC s32 4 Line height
0x10 u32 4 Vertical offset
0x14 s32 4 Line margin
0x18 u32 4 Unknown (note: not present in version 1)
0x1C u16 2 Unknown
0x1E u32 4 Font size (in points)
0x22 string N Font name; zero-terminated string
- TXTR 4/8 Texture ID
- u32 4 Unknown
- u32 4 Glyph count
- Glyph[] - Glyph table (Version 2, Version 4)

Version

Version Game
1 Metroid Prime Kiosk Demo
2 Metroid Prime NTSC
4 Metroid Prime PAL and Metroid Prime 2
5 Metroid Prime 3, DKCR

Glyphs

This section of the file details each glyph making up the font. One glyph corresponds to one character. To map the character with the part of the font texture that contains that character, each glyph contains a set of texture coordinates. Since the UV map is always rectangular, the file only stores the min/max X/Y coordinates; they should be mixed and matched to get the absolute values.

In addition, glyphs contain a vertical offset. This offset is necessary because the textures are usually so tightly packed that there's no extra space for vertical spacing. After applying the offset, the vertical offset from the FONT header is applied. This aligns the glyphs at their intended position.

The kerning index value is the index of the first kerning table entry for the given character. Since the table is sorted in alphabetical order, this can be used to speed up lookup time.

This section of the file changes somewhat from version 2 to 4. Starting in version 4, glyphs are able to be encoded to only one particular RGBA channel, which allows multiple glyphs to be encoded in the same space on the texture. A "channel index" value was introduced to track which channel the glyph is on. Additionally, a lot of 32-bit values were reduced to 8- or 16-bit. Aside from that, though, the actual layout is still the same, with the same values in the same places.

Version 2 (Metroid Prime NTSC)

Offset Type Size Description
0x0 u16 2 UTF-16 character
0x2 float 4 Left UV coordinate
0x6 float 4 Top UV coordinate
0xA float 4 Right UV coordinate
0xE float 4 Bottom UV coordinate
0x12 u32 4 Left padding
0x16 u32 4 Print head advance
0x1A u32 4 Right padding
0x1E u32 4 Width
0x22 u32 4 Height
0x26 u32 4 Vertical offset
0x2A u32 4 Kerning index
0x2E End of glyph definition

Version 4 (Metroid Prime PAL)

Offset Type Size Description
0x0 u16 2 UTF-16 character
0x2 float 4 Left UV coordinate
0x6 float 4 Top UV coordinate
0xA float 4 Right UV coordinate
0xE float 4 Bottom UV coordinate
0x12 u8 1 RGBA channel index
0x13 u8 1 Glyph left padding
0x14 u8 1 Print head advance
0x15 u8 1 Glyph right padding
0x16 u8 1 Glyph width
0x17 u8 1 Glyph height
0x18 u16 2 Kerning index
0x1A End of glyph definition

Kerning Table

This table is at the end of the file, and defines kerning pairs. Kerning pairs horizontally adjust the second character of the pair whenever that particular sequence of characters is encountered. The table is case-sensitively sorted in alphabetical order, which allows for fast lookup times using the glyph kerning indices. After a 32-bit count value, each pair follows this simple structure:

Offset Size Description
0x0 2 Character 1
0x2 2 Character 2
0x4 4 Kerning adjust
0x8 End of entry

Textures

Starting with version 4, textures used by FONT files are encoded in a bit of an unorthodox manner. The textures are ostensibly C4, but it appears that the game probably replaces the palette colors with different ones at runtime, which means trying to decode them as-is will turn out junk. Fortunately, the correct colors are fairly intuitive to guess at, so the textures can be decoded as such: For each 4-bit palette index, each bit determines whether a given color channel should be set to 0 or 255. Bit 3 (the MSB) refers to the red channel, bit 2 refers to the green channel, bit 1 refers to the blue channel, and bit 0 (the LSB) refers to the alpha channel. This would correspond to the following RGB5A3 color palettes:

0 (0000) - 0x8000 (none)
1 (0001) - 0x7000 (alpha)
2 (0010) - 0xFC00 (blue)
3 (0011) - 0x7F00 (blue/alpha)
4 (0100) - 0x83E0 (green)
5 (0101) - 0x70F0 (green/alpha)
6 (0110) - 0xFFE0 (green/blue)
7 (0111) - 0x7FF0 (green/blue/alpha)
8 (1000) - 0x801F (red)
9 (1001) - 0x700F (red/alpha)
10 (1010) - 0xFC1F (red/blue)
11 (1011) - 0x7F0F (red/blue/alpha)
12 (1100) - 0x83FF (red/green)
13 (1101) - 0x70FF (red/green/alpha)
14 (1110) - 0xFFFF (red/green/blue)
15 (1111) - 0x7FFF (red/green/blue/alpha)

Note: Donkey Kong Country Returns features some font textures that use C8 instead of C4, but the palette indices still only range from 0 to 15, so the same method still applies.