Westwood Font Format v4
The fourth type of bitmap font created by Westwood Studios is not used in any DOS games, but its format is virtually identical to v3, so it is included for completeness' sake. It is an 8-bit-per-pixel font, though the games that use it never use it beyond 16 colors, making it functionally identical to the 4-bpp v3 font. Like its predecessor, it has a variable amount of characters, and allows the separate symbols to specify their width, height and Y-offset.
Unlike the v3 fonts, v4 fonts usually seem to correspond to the Windows-1252 encoding, and not to classic DOS code page 437.
The font format starts with the following header.
|0x02||BYTE||DataFormat||Data format. 0x00 for v3, 0x02 for v4. The internal logics in Tiberian Sun actually allow both values, with 0x00 and 0x02 indicating respectively a 4-bit and an 8-bit font, but the 4-bit variety is never actually used in the game, and is not supported in the Westwood Font Editor.|
|0x03||BYTE||SigByte1||Signature byte. Always 0x00 for v4.|
|0x04||BYTE||SigByte2||Signature byte. Always 0x0E.|
|0x05||BYTE||SigByte3||Signature byte. Always 0x00.|
|0x06||UINT16LE||OffsetsListOffset||Offset of the array of data offsets.|
|0x08||UINT16LE||WidthsListOffset||Offset of the array of symbol widths|
|0x0A||UINT16LE||FontOffsetStart||Offsets are relative to this value. While this is unused in v3, v4 fills this in with the start of its font data block, making the values at the address in |
|0x0C||UINT16LE||HeightsListOffset||Offset of the array containing the symbol heights and Y-offsets.|
|0x0E||UINT16LE||Unknown||Unknown. Always 0x0000 for v4.|
|0x10||BYTE||Unknown||Unknown. Always 0x00.|
|0x11||BYTE||NrOfChars||Number of characters. Unused in v4, and always just left on 0x00. The only way to determine the amount of characters is through reading the index arrays and seeing where they need to end to avoid overlapping with other addressed data.|
|0x12||BYTE||Height||Overall font symbols maximum height, in pixels.|
|0x13||BYTE||Width||Overall font symbols maximum width, in pixels.|
Following this header are the referenced arrays and the font data, normally in this order:
- Array of UINT16LE values indicating the offset of the data for each symbol, relative to
FontOffsetStart. The start offset of this list is specified by
- Array of byte values indicating the symbol widths, in pixels. The start offset of this list is specified by
- Actual symbol data referenced in the offsets list.
- Array containing two bytes per entry; the first being the Y-offset, the second the height in pixels. The start offset of this array is specified by
Unlike in v3, v4 fonts seem to put the height and Y data behind the actual character data, splitting the data into a header and a footer around the actual image data. However, since the games just follow the offsets as they read them, the order probably doesn't matter at all.
As with version 3, the font data is uncompressed, but it is optimised by making the offsets for any identical symbols in the font refer to the same data.
The actual font data is very simply straightforward 8 bit per pixel, always using the minimum stride per line, so the exact amount of bytes of the width. However, the games themselves never seems to use colour indices higher than 16 on the fonts; there are simply no colours supplied for these indices, and if they are used on the font they seem to use random memory junk as colours. Because of this, the v4 format doesn't really offer any advantage over its 4-bit predecessor, except in unutilized potential.
The following tools are able to work with files in this format.
|Name||Platform||View images in this format?||Convert/export to another file/format?||Import from another file/format?||Access hidden data?||Edit metadata?||Notes|
|Westwood Font Editor||Windows||Yes||Yes||Yes||No||N/A||Created by Nyerguds|
|Engie File Converter||Windows||Yes||Yes||Yes||No||N/A||Automatically trims off the top of the characters on save, and saves the trimmed amount as Y-offset. Was added to Engie to allow creation of font sheets.|