SFFv2
From M.U.G.E.N Wiki
Contents |
Introduction
This document is a specification for the SFF 2.0 format, also known as SFFv2.
SFFv2 file format is designed for fast loading, fast decompression and low runtime memory consumption.
In 2.00, only 5 and 8-bit paletted sprites are supported.
SFFv2 is an open file format. Elecbyte grants permission to implement the spec freely in any application.
Terminology
ldata
literal data. Must be loaded verbatim. In M.U.G.E.N, sprite data in the ldata block is loaded verbatim into memory, and decompressed as necessary on-the-fly.
tdata
translate data. Must be translated (e.g. decompressed) during load.
SFF 2.00
SFF header 2.00
All values are little-endian.
512 bytes
dec hex size meaning 0 0 12 "ElecbyteSpr\0" signature 12 C 1 verlo3; 0 13 D 1 verlo2; 0 14 E 1 verlo1; 0 15 F 1 verhi; 2 16 10 4 reserved; 0 20 14 4 reserved; 0 24 18 1 compatverlo3; 0 25 19 1 compatverlo1; 0 26 1A 1 compatverlo2; 0 27 1B 1 compatverhi; 2 28 1C 4 reserved; 0 32 20 4 reserved; 0 36 24 4 offset where first sprite node header data is located 40 28 4 Total number of sprites 44 2C 4 offset where first palette node header data is located 48 30 4 Total number of palettes 52 34 4 ldata offset 56 38 4 ldata length 60 3C 4 tdata offset 64 40 4 tdata length 68 44 4 reserved; 0 72 48 4 reserved; 0 76 4C 436 unused
compatver
Minimum version of loader needed to read this SFF: 2.00
Sprite node header 2.00
28 bytes
dec hex size meaning 0 0 2 groupno 2 2 2 itemno 4 4 2 width 6 6 2 height 8 8 2 axisx 10 A 2 axisy 12 C 2 Index number of the linked sprite (if linked) 14 E 1 fmt 15 F 1 coldepth 16 10 4 offset into ldata or tdata 20 14 4 Sprite data length (0: linked) 24 18 2 palette index 26 1A 2 flags
fmt
0 raw 1 invalid (no use) 2 RLE8 3 RLE5 4 LZ5
flags
0 unset: literal (use ldata); set: translate (use tdata; decompress on load) 1-15 unused
Pal node header 2.00
16 bytes
dec hex size meaning 0 0 2 groupno 2 2 2 itemno 4 4 2 numcols 6 6 2 Index number of the linked palette (if linked) 8 8 4 Offset into ldata 12 C 4 Palette data length (0: linked)
Palette data is stored in 4 byte chunks per color. The first 3 bytes correspond to 8-bit values for RGB color, and the last byte is unused (set to 0).
Compression Formats
Compression formats are consistent across SFF versions.
RLE8
Simple run-length encoding for 8-bit-per-pixel bitmaps.
Any byte with bits 6 and 7 set to 1 and 0 respectively is an RLE control packet. All other bytes represent the value of the pixel.
RLE packet (1 byte)
bits 0-5: run length bits 6-7: run marker (01)
Pseudocode to decode an RLE8 chunk:
one_byte = read(1 byte) if (one_byte & 0xC0) == 0x40, then color = read(1 byte) for run_count from 0 to (val & 0x3F) - 1, do output(color) else output(one_byte)
RLE5
RLE5 is a run-length encoding used for the compression of 5-bit-per-pixel bitmaps. RLE5 is a hybrid of two run-length encoding algorithms. The first allows encoding of long runs of color 0 pixels, the second is a 3-bit-RL/5-bit-color run-length algorithm.
RLE5 packet (2 bytes)
byte 0 : run length byte 1 bit 7 : color bit; .2-.7 byte 1 bits 0-6: data length
Pseudocode to decode an RLE5 chunk:
RLE5packet = read(2 bytes) if RLE5packet.color_bit is 1, then color = read(1 byte) else color = 0 for run_count from 0 to RLE5packet.run_length, do output(color) // Decode 3RL/5VAL for bytes_processed from 0 to RLE5packet.data_length - 1, do one_byte = read(1 byte) color = one_byte & 0x1F run_length = one_byte >> 5 for run_count from 0 to run_length, do output(color)
LZ5
LZ5 is a run-length encoding used for the compression of 5-bit-per-pixel bitmaps. It is more efficient than RLE5 but is more complex to encode.
See LZ5 for details.