This is an old revision of the document!
Table of Contents
FRM16
*.frm16 files are images, used for many things like UI elements, icons, minimaps, textures, portraits … Also they are embedded in .SEQ16 and .MDL16 files. They use 16bits (2 bytes) per color and between 2 and 3 bits for transparency.
Allegedly they are cached form of .FRM files which in turn are created from .TGA files. To speed up loading, they do not use any JPEG-type compression like FRM files and use only RLE and 16bit colors. They reside in Cache/ subdir, which supports the theory. In some related games (Ricochet) it's possible to delete .FRM16 files and they get recreated automatically from FRM ones. Unfortunately there are not any .FRM files in Lionheart.
FRM16 file consists of a header and up to five layers. Layers are a way to encode alpha (transparency) in FRM16 files - the first layer is opaque (possibly with fully transparent pixels), the second layer is 80% opacity (: or 20% ?) and so on.
- header
- Opaque layer
- Bitmap
- Scanline LUT
- 80% opacity layer
- Bitmap
- Scanline LUT
- 60% opacity layer
- Bitmap
- Scanline LUT
- 40% opacity layer
- Bitmap
- Scanline LUT
- 20% opacity layer
- Bitmap
- Scanline LUT
Any (: even the fully opaque) layer might be missing.
There are at least two types of FRM16 files - type 64 and type 68. Type 64 uses uncompressed pixels, while type 68 uses RLE.
Header (36 bytes)
Offset | Size | Description |
---|---|---|
0x00 | 2 | Signature (0x1032) |
0x02 | 2 | Anchor X ? |
0x04 | 2 | Anchor Y ? |
0x06 | 2 | Width in pixels (portraits = 90, areas = 779) |
0x08 | 2 | Height in pixels (portraits = 111, areas = 330) |
0x0a | 2 | Flags? Either 0 (normal) or 107 (immediate) |
0x0c | 2 | Type (64 or 68) |
0x0e | 2 | Unknown, possibly padding, always 0 in standalone files |
0x10 | 4 | Data size for opaque layer |
0x14 | 4 | Data size for 80?% layer |
0x18 | 4 | Data size for 60?% layer |
0x1c | 4 | Data size for 40?% layer |
0x20 | 4 | Data size for 20?% layer |
Layers
Each layer consists of a bitmap and a scanline lookup table (LUT).
Bitmap
In type 68 files, the first 4 bytes in a bitmap is a DWORD containing bitmap's size in bytes. Since LUT's size is known (2 * height), it allows to read or skip the bitmap or whole layer without decoding it. However, the same number is already in the header, so its usefullness is unclear.
Pixel color is encoded as a 16bit word, probably with a common 5-6-5 RGB? encoding. : How are fully transparent pixels encoded?
Type 64 files do not use any compression. Each bitmap consists of width x height pixels of 2 bytes each.
Type 68 FRM16 files use Run Length Encoding, RLE. Each bitmap line consists of variable number of pixel runs. The RLE scheme uses two highest bits in the first byte of each run. If bit 7 is set, bits 0-6 contain number of pixels to skip in the resulting image. If bit 7 is clear and bit 6 is set, bits 0-5 contain number of 16bit pixels which follow. If both bits 7 and 6 are cleared, bits 0-5 contain a number of repetitions of the following 16 bit pixel.
For example:
81 42 ff fe ff fc 05 00 00
would result in
__ __ ff fe ff fc 00 00 00 00 00 00 00 00 00 00
(First one pixel (0x81 & 0x7f) is skipped, then two (0x42 & 0x3f) whitish pixels are copied, then a black pixel is copied 5 times)
Scanline Lookup Table, LUT
Array of 32bit indices into pixel data pointing to beginnings of each image scanline. The first index is 0 in type 64 files, 4 in type 68 files.
Offset | Size | Description |
---|---|---|
0x00 | 2 | Offset of the 1st scanline (0 in type 64 files, 4 in type 68 files) |
0x02 | 2 | Offset of the 2nd scanline |
… | ||
height * 2 | 2 | Offset of the last scanline |
References
[: quotes on FRM/FRM16 and JPEG-like compression] [: links to convertors by Balder, Miloch, …]