SFFv2

From M.U.G.E.N Wiki

Jump to: navigation, search

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.

Personal tools