ANM animations
ANM files store Deluxe Paint animations as indexed bitmap deltas in LPF pages.
This is the LPF animation format, distinct from IFF ANIM containers.
See LBM for IFF bitmaps.
Overall Structure
[LPF header — page counts, dimensions, encoding, and frame rate]
[Color-cycle records — authored palette ranges]
[Palette — 256 BGRX entries]
[Page table — 256 page descriptors]
[Large pages — record sizes and RunSkipDump bitmap records]
All multibyte integers are little-endian.
Header and palette
The header occupies 128 bytes.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0x00 | 4 | [u8; 4] | signature | LPF |
0x04 | 2 | u16 | max_pages | Page-table capacity, 256 |
0x06 | 2 | u16 | page_count | Number of active pages |
0x08 | 4 | u32 | record_count | Total records, including the loop delta |
0x0C | 2 | u16 | max_records_per_page | Authored record capacity |
0x0E | 2 | u16 | page_table_offset | Absolute table position |
0x10 | 4 | [u8; 4] | content_type | ANIM |
0x14 | 2 | u16 | width | Pixel width |
0x16 | 2 | u16 | height | Pixel height |
0x18 | 1 | u8 | variant | Bitmap variant, zero |
0x19 | 1 | u8 | version | Format version |
0x1A | 1 | u8 | has_last_delta | Final record is a loop delta |
0x1B | 1 | u8 | last_delta_valid | Loop delta validity flag |
0x1C | 1 | u8 | pixel_type | Indexed eight-bit pixels, zero |
0x1D | 1 | u8 | compression | RunSkipDump, 1 |
0x1E | 1 | u8 | other_records_per_frame | Additional record types, zero |
0x1F | 1 | u8 | bitmap_type | Single bitmap, 1 |
0x20 | 32 | [u8; 32] | record_types | Record-type fields |
0x40 | 4 | u32 | frame_count | Authored frame-count field |
0x44 | 2 | u16 | frames_per_second | Playback rate |
0x46 | 58 | [u8; 58] | reserved | Reserved header bytes |
Sixteen eight-byte color-cycle records follow at 0x80. The palette begins at
0x100, with 256 entries in blue, green, red, unused order. Pixel index zero
is opaque.
Every installed ANM except system/gui.anm has all sixteen records zero. In
gui.anm four records are populated, each with a zero rate and zero flags and
the palette ranges 0x10-0x1f, 0x20-0x2f, 0x60-0x6f and 0x90-0x9f
(low and high bytes at record offsets 6 and 7). Because rate and flags are zero,
no installed ANM defines an active palette cycle. The first six bytes of every
gui.anm cycle record are zero, including the four populated ranges. These are the same four ranges
as the CRNG chunks of gui.lbm.
Page table and large pages
Each page descriptor is six bytes:
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
+0x00 | 2 | u16 | base_record | First record number in the page |
+0x02 | 2 | u16 | record_count | Low 14 bits contain the record count; high bits mark continuation records |
+0x04 | 2 | u16 | data_size | Total record payload bytes |
Page i begins at page_table_offset + 256 * 6 + i * 65536. Its header repeats
the descriptor, followed by a reserved word, one u16 size per record, and the
record payloads. The last physical page can end before its 64 KiB boundary.
Playback follows record numbers rather than physical page order.
Bitmap records
A bitmap record begins with byte 0x42 (B), a zero padding flag, and a
two-byte unknown_02 field. RunSkipDump operations follow. Each record starts
its output cursor at pixel zero; skipped pixels retain the preceding frame.
| Control | Operation |
|---|---|
0x01 through 0x7F | Copy that many following pixel indices |
0x00 | Read an eight-bit count and index; repeat the index |
0x81 through 0xFF | Skip the low-seven-bit count |
0x80 | Read a little-endian extended control word |
Extended words select these operations:
| Word | Operation |
|---|---|
0x0000 | End the record |
0x0001 through 0x3FFF | Skip that many pixels |
0x4001 through 0x7FFF | Skip the low-14-bit count plus 0x4000 pixels |
0x8001 through 0xBFFF | Copy the low-14-bit count of following indices |
0xC001 through 0xFFFF | Repeat the following index for the low-14-bit count |
0x4000, 0xC000 | No operation |
0x8000 is invalid. An eight-bit repeat count of zero is also a no-op, but
still consumes its index byte.
Playback and looping
The header supplies a frame rate and can identify a final loop delta. That record converts the last display frame back to the first and is excluded from the displayed image sequence. The authored frame-count field includes it.
GUI image collection
system/gui.anm uses the animation container to bundle separate GUI graphics.
Its 25 display images contain small, medium, and large parchment buttons in
different states, followed by a parchment background. Each image occupies a
320 by 200 canvas. These are selectable artwork variants, rather than a motion
sequence. The header declares 10 frames per second; this is container metadata,
not GUI interaction timing.
system/gui.lbm contains the same button designs arranged
on a 640 by 480 bitmap sheet. The files have different embedded palettes, so
matching artwork can use different palette indices.