Menu images (MIMG/*.IMG)
Pictures for the menus: track maps, car previews, title and loading screens, and the localised menu screens in MIMG/<LANGUAGE>/. Plain files, not in the block container.
Reader: decoders/img.py. State: decoded completely on all 146 files (measured, 2026-10-23, GameFrame validate.py; all bytes read). Pictures checked by eye in the viewer. The game's reader is FUN_0047a454 (load_menu_images).
Writer: crates/pod-formats/src/image.rs (write, Images::put). Round-trip on all 146 files (measured, tests/writers.rs): the entries' two unread words, the palettes as stored and the whole pixel area are kept. put draws a picture into an entry with the nearest colour of its palette. Modded: a changed BELTANE.IMG shows on the track screen (docs/modding.md).
Layout
Observed in FUN_0047a454: four ReadFile calls, 12 bytes, count × 16, palettes × 512, data_size.
| Read | Size | Content |
|---|---|---|
| header | 12 | u32 count, u32 data_size, u32 palettes |
| entries | count × 16 | One per picture, below |
| palettes | palettes × 512 | 256 colours of 16 bits each |
| data | data_size | Pixels of all pictures |
Entry (16 bytes)
| Offset | Type | Meaning |
|---|---|---|
+0 | u16 | Width |
+2 | u16 | Height |
+4 | u16 | Slot: where the game stores the picture (observed: index into the table at 0x502f1c) |
+6 | u16 | Not read by FUN_0047a454 |
+8 | u32 | Offset of the pixels in the data |
+0xc | u16 | Palette number, or 0xFFFF for 16-bit pixels |
+0xe | u16 | Not read |
A picture with a palette has one byte per pixel. Without one it has two.
Bytes after the pixel area are never read. POD's load_menu_images (0x474f88) makes four ReadFile calls (header, entries, palettes, pixel area) and closes the file (observed). The fan track ECocoon's picture has 277 such bytes (measured). The reader keeps them so that the file writes back the same.
Colours
16-bit colours (palettes and pixels) are RGB555 (measured: drawn as RGB565 the pictures have green noise, as RGB555 they are clean). The game passes every colour through a 65,536-entry table at 0x57925c unless the video mode DAT_0060b314 is 3 (observed): probably a conversion to the screen's format (inferred).
The loading screens
PRGS.IMG (640 × 480) and PRGS512.IMG (512 × 384) have a different header: u32 1, u32 size, u16 width, u16 height, 8 zero bytes, then 16-bit pixels. FUN_0047a454 is not their reader (inferred: its header read would fail on them); which function reads them is open.