RISC OS Build EnvironmentROBE

Appendix44Appendix J: Sprite File Format

Overview

Sprite files are a common interchange and resource format in RISC OS projects. They appear in application resources, DrawFiles, icon sets, and generated assets. This appendix summarises the on-disc structure that inspection tools such as riscos-dumpsprites and sprite-aware code need to understand.

The PRM describes a sprite file as the same format as a sprite area in memory, except that the first word of the in-memory sprite area is omitted when the file is saved. In practice, the file therefore begins with the remaining sprite area header fields and is followed by one or more sprite records.

Sprite file structure

Overall file structure

At the highest level, a sprite file contains:

  1. a shortened sprite-area header;
  2. zero or more sprite records, chained by offsets;
  3. any palette, mask, or image data that belongs to those sprites.

The saved file layout is:

OffsetSizeContents
04Number of sprites in the file.
44Offset to the first sprite record, relative to the start of the file.
84Offset to the first free word, relative to the start of the file.
12variableSprite records and their associated data.

When the same data is held in memory as a full sprite area, an additional word precedes these fields and gives the total size of the sprite area. Local header definitions in the build environment also name the full in-memory fields saEnd, saNumber, saFirst, and saFree.

Saved header fields

The saved header fields have the following meanings:

FieldMeaning
Number of spritesHow many sprite records are present in the file.
First sprite offsetByte offset of the first sprite record from the start of the file.
Free offsetByte offset of the first unused word after the used sprite data.

Inspection code commonly expects the sprite offsets to be word-aligned. The local sprite-area validation code also checks that the first sprite offset lies within the used part of the area, and that the free offset lies within the area as a whole.

Sprite record layout

Each sprite record begins with a fixed-size header. That header identifies the sprite, records its geometry and mode information, and gives offsets to its image and mask data within the sprite record.

OffsetSizeContents
04Offset to the next sprite record, relative to the start of this sprite.
412Sprite name, stored in a fixed 12-byte field. Names shorter than 12 bytes are padded with zero bytes, not spaces.
164Width information in words minus one (so a width of one word, the minimum, is stored as 0).
204Height information in scan lines minus one (so a height of one row, the minimum, is stored as 0).
244First bit used: the number of unused bits wasted at the left-hand end of each row (0-31).
284Last bit used: the number of unused bits wasted at the right-hand end of each row (0-31).
324Offset to the sprite image data, relative to the start of this sprite.
364Offset to the transparency mask data, or the same as the image offset if there is no separate mask.
404Mode word or mode number describing pixel format.
44variableOptional palette data, then image data, then optional mask data.

The minimum valid header size is 44 bytes, even for a sprite that uses neither a palette nor a separate mask.

The exact interpretation of the mode field depends on whether the sprite uses the older sprite format or one of the newer mode-word encodings. The local tooling recognises old-format sprites, newer RGB sprites, alpha-bearing sprite types, and CMYK-related type information.

The left-hand wastage field (offset 24) is interpreted differently depending on the sprite's format. For a sprite using one of the newer mode-word types (any mode value with bits 27-31 set), the left-hand wastage must always be 0; image rows for newer sprite types are required to start exactly on a word boundary, with no bits wasted before the first pixel. Only an old-format sprite (mode value with bits 27-31 clear, identified by a mode number rather than a mode word) may have a non-zero left-hand wastage, in the range 0-31. The right-hand wastage field (offset 28) is always in the range 0-31 for either format.

Converting the stored width to pixels needs the row's bit depth (2^log2bpp, from the mode field) as well as the wastage fields:

bit_width = ((width_words + 1) × 32) - first_bit - (31 - last_bit)
pixels = bit_width >> log2bpp

For example, a sprite with width_words of 0 (one word, 32 bits), no wastage (first_bit 0 and last_bit 31, meaning the row uses every bit of the word right up to its last bit), and 8 bits per pixel (log2bpp 3) gives bit_width = 32 - 0 - (31 - 31) = 32, so the row is 32 / 8 = 4 pixels wide. The height in pixels is simply height_rows + 1, with no bit-depth conversion needed since wastage only ever applies along a row.

Mode and type values

The local sprite headers define these primary type values for newer mode-word sprites:

ValueMeaning
0Old-format sprite.
11 bpp sprite.
22 bpp sprite.
34 bpp sprite.
48 bpp sprite.
516 bpp sprite.
632 bpp sprite.
7CMYK sprite type.
8Packed 24 bpp sprite type.
9JPEG sprite type.

Some of these types are not handled directly by the base operating system, but inspection tools may still recognise and report them.

Using inspection tools

The quickest way to inspect a sprite file is usually riscos-dumpsprites. It can:

  • summarise all sprites in a file;
  • describe one named sprite field by field;
  • validate structure and offsets with --check;
  • emit JSON for other tools with --json.

Inspection workflow

Summarising and validating a sprite file

These examples show the common inspection workflow for a sprite file.

riscos-dumpsprites Resources/Sprites,ff9
riscos-dumpsprites --check Resources/Sprites,ff9