Jazz Jackrabbit Font Format

From ModdingWiki
Jump to navigation Jump to search
Jazz Jackrabbit Font Format
Jazz Jackrabbit Font Format.png
Format typeFont
Max glyph count127
Minimum glyph size (pixels)1×1
Maximum glyph size (pixels)65,535×65,535
Access modeSequential
Metadata?None
Bitmap glyphs?Yes
Vector glyphs?No
Compressed glyphs?Yes
Hidden data?Yes
Games

The fonts in Jazz Jackrabbit are 8-bit sequential fonts with variable widths and heights per symbol. They are stored in two different ways; the normal fonts, with .0FN extension, are compressed, but one font file, FONTS.000, is in a different format, which does not use compression. Some font symbols are stored in non-font files; for example, the bonus font is stored in BONUS.000, together with the bonus sprites.

Normal fonts

The standard .0FN files (FONT2, FONTBIG, FONTINY, FONTMN1 and FONTMN2) are compressed 8-bit fonts. They use palette index 0 as transparent colour.

Header

The files start with a 23 byte header:

Offset Data type Name Description
0x00 Char[12] Identifier1 Literal string "Digital Dimensions".
0x12 BYTE Identifier2 Always byte 0x1A.
0x13 BYTE SpaceWidth Space width.
0x14 BYTE LineHeight Line height. This is not a restriction on how high the symbols can be, but a value used to determine how many pixels to go down to paint a next line of this font.
0x15 UINT16LE Unknown3 Always two 00-bytes.

Note that in situations where text is drawn on arbitrary positions on the screen, the line height setting will not be used. Also, in several places in the game, the space width will either be overridden by a fixed value, or expanded or reduced by a specific set amount. A good place to see both values at work as intended is in the full-text pages of the "Instructions" section of the game.

The fonts do not contain any information concerning the space between symbols. Some scenes, like the score screen and start-of-level "GET READY" text, have all symbol widths padded up to the next multiple of four pixels. This may be a side effect of the fact a lot of sprites, including the ones in FONTS.000, are stored in a way that forces their width to a multiple of 4 pixels. Note that when symbols get padded, this padding does not seem to apply to the space character.

Symbol data

Compressed

The remainder of the font is filled up with the symbols. Each symbol consists of a little-endian word indicating the uncompressed size of the symbol data, followed by the compressed block. This block is in the Jazz Jackrabbit RLE compression format, which means it starts with an indicator of how long the compressed data is.

Offset Data type Name Description
0x00 UINT16LE UncompressedLength Length of the uncompressed data.
0x02 UINT16LE CompressedLength Length of the compressed data that follows. This can be used to know how much to skip to get to the next symbol block.
0x04 BYTE[CompressedLength] CompressedData Actual compressed data. Note that the Jazz Jackrabbit RLE data format normally includes the preceding length block.

An UncompressedLength of 0 indicates that the symbol is not present at all. In that case, no compressed block (length + data) will be present behind it. These dummy entries are not treated as 0×0 symbols, but are substituted by the space width from the header, even if an explicit symbol for the space is set (see "Symbol order").

Decompressed

Once uncompressed, the data has the following format:

Offset Data type Name Description
0x00 UINT16LE Width Width of the symbol data
0x02 UINT16LE Height Height of the symbol data
0x04 BYTE[Width*Height] ImageData The actual image data, in 8 bit per pixel format.

The font can not handle images that have 0 as one or both dimensions; they will cause corruptions in the game. Since empty dummy symbols are substituted by the space width, adding completely empty symbols is not possible, except by setting the space width in the header to 0, and writing the space symbol as explicit image (see "Symbol order").

Hidden data

Since the Jazz Jackrabbit RLE compression contains both an explicit data length for the compressed content, and an explicit command to stop the decompression, it is trivial to write a value in the CompressedLength field that is larger than the actual compressed length, and fill up the extra space with other data. The game will only use the CompressedLength value to find the next block of data, and will never check if that is actually where the decompression ended.

Symbol order

Unlike most fonts, the order of the symbols in the Jazz Jackrabbit fonts doesn't match any classic text encoding, meaning they act more like sprite files, in that regard. The usage of the exact symbols varies per font, but the game uses an exact mapping to translate bytes to font indices. This is what the font indices map to:

  • 00-25: Upper case characters A-Z.
  • 26-51: Lower case characters a-z.
  • 52-61: Numbers 0-9.
  • 62-65: []<> - Open square bracket, close square bracket, less-than sign, greater-than sign.
  • 66-99: These symbols map to bytes beyond ASCII range. The exact byte order for this range is: 0x81, 0x80, 0x82-0x96, 0x9A, 0x97-0x99, 0x9B, 0xA0-0xA5.
  • 100-115: ,.?-+=!#%&();:'" - Comma, period, question mark, minus, plus, equals, exclamation mark, number sign, percentage, ampersand, open bracket, close bracket, semicolon, colon, single quote, double quote.
  • 116-125: Never used.
  • 126: If present, and not an empty dummy entry, this overrides the space symbol.

Adding more symbols to the font is possible, but has no use, and will crash the game if too many are present, so for all practical purpose, the maximum amount of symbols in these font files is 127.

The following bytes don't have a place mapped in the Jazz fonts:

  • 0x00-0x1F: All byte values below the space
  • 0x24: Dollar $
  • 0x2A: Asterisk *
  • 0x2F: Forward slash /
  • 0x40: At sign @
  • 0x5C: Backslash \
  • 0x5E: Circumflex accent ^
  • 0x5F: Underscore _
  • 0x60: Grave accent `
  • 0x7B: Left curly bracket {
  • 0x7C: Vertical line |
  • 0x7D: Right curly bracket }
  • 0x7E: Tilde ~
  • 0x7F: Delete symbol (sometimes shown as in DOS ASCII)
  • 0x9C-0x9F: Extended ASCII symbols
  • 0xA6-0xFF: All further extended ASCII symbols

If any of these values are encountered, they are mapped to the space symbol, and will be shown accordingly.

Mapping table

To easily interpret the data and see for each font symbol position which byte it corresponds to, this table can be used. The 00 entries in the 0x75-0x7D range should be ignored, since these indices in the font don't seem to map to anything.

41, 42, 43, 44, 45, 46, 47, 48, 49, 4A, 4B, 4C, 4D, 4E, 4F, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 5A, 61, 62, 63, 64, 65, 66,
67, 68, 69, 6A, 6B, 6C, 6D, 6E, 6F, 70, 71, 72, 73, 74, 75, 76,
77, 78, 79, 7A, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 5B, 5D,
3C, 3E, 81, 80, 82, 83, 84, 85, 86, 87, 88, 89, 8A, 8B, 8C, 8D,
8E, 8F, 90, 91, 92, 93, 94, 95, 96, 9A, 97, 98, 99, 9B, A0, A1,
A2, A3, A4, A5, 2C, 2E, 3F, 2D, 2B, 3D, 21, 23, 25, 26, 28, 29,
3B, 3A, 27, 22, 7E, 00, 00, 00, 00, 00, 00, 00, 00, 00, 20

FONTS.000

Like the 0FN fonts, this font is an 8-bit sequential font with variable dimensions per symbol. However, the way it is stored is completely different. It has no identifying text at the start, it contains the number of symbols, and it is uncompressed. The actual image data is also interpreted completely differently, working with four slices of graphics that alternate pixel columns to build up the full image.

This font seems to use palette index 254 as transparent colour.

Header

The file starts with a UINT16LE indicating the amount of symbols in the font (which should be 37). This is followed directly by the symbol data blocks.

Symbol data

The symbol data is built up in a peculiar way: the data contains four images that each have the data for 1/4th of the image, as alternating columns. This means the first image 'slice' will fill up columns 0, 4, 8, etc, the second will fill 1, 5, 9, etc, the third fill 2, 6, 10, etc and the fourth completes the image with columns 3, 7, 11, etc. This means all symbols in this font type will have a width that is divisible by four.

The symbol data has the following structure:

Offset Data type Name Description
0x00 UINT16LE SliceWidth Width of one slice of the symbol graphics. This matches the full symbol width divided by 4.
0x02 UINT16LE Height Height of the symbol graphics.
0x04 UINT16LE SliceSize Size of one slice. Matches SliceWidth * Height
0x06 BYTE[SliceSize][4] Slices The graphics slices. Four blocks of SliceSize

Symbol order

Like the 0FN type, the font is built more like a sprite file than like a real font, containing a set of frames in an order that doesn't match any real text encoding. The order of the symbols is the following:

  • 00-25: Upper case characters A-Z.
  • 26-35: Numbers 0-9.
  • 36: Dollar sign.

Bonus.000

This contains the bonus level font and sprites. It is not a font file per se but a graphics file.


Tools

The following tools are able to work with files in this format.

Name PlatformView images in this format? Convert/export to another file/format? Import from another file/format? Access hidden data? Edit metadata? Notes
Westwood Font Editor WindowsYesYesYesN/AN/A Can handle both the compressed fonts and FONTS.000. Rearranges the symbols as necessary and generates the space entry as needed. Allows setting the line height in compressed fonts when saving.
Engie File Converter WindowsYesYesYesN/AN/A Can handle both the compressed fonts and FONTS.000, as tileset. Allows setting the space width and line height in compressed fonts when saving.