Skip to content

Frame Format Documentation

Francis Dominic Fajardo edited this page Jul 9, 2024 · 11 revisions

New Frame format [outdated]

  • Not to be confused with the initial FRAME format used only in the first version of Swarm.
  • Refer to code for up to date parsing logic.

Header

Offset Size Description Value
0x00 4 Hot spot X
0x04 4 Hot spot Y
0x08 1 Embedded image is compressed 0 or 1
0x09 1 or 4 File size *0x01
0x0A 4 Deflated file size *
0x0E 4 Inflated file size *
0x12 2 ZLIB header *0x78DA

* If compressed.

Embedded image (not compressed)

  • JPEG file.

Alpha mask header (RLE, not compressed)

Offset Size Description Value
0x00 1 ? Padding 0x00
0x01 4 Inflated file size
0x05 2 ZLIB header 0x78DA

Alpha mask image (not compressed)

  • There is only 1 layer representing the alpha channel for the embedded image.

  • Follow the same algorithm below for obtaining the alpha value of each pixel.

Embedded image (compressed)

  • There are 4 “layers” representing each channel of RGBA.

  • Each layer is a width * height matrix.

  • To get the color component of each pixel:

    • The value at column 1, row 1 is used as the “base component”.

    • For the succeeding cells, add the value of the previous cell to the current cell and apply integer wrap-around.

      • Example:
R: AD 19 00 00 00 00 00 E7 CE 19 6C 00
M: AD C6 C6 C6 C6 C6 C6 AD 7B 94 00 00
  • Special case: If we’re on column 1 and the value of the current cell is 0x00, copy the value of the cell on column 1, row n-1 given that n > 1.

    • Example:
R:

29 00 00 00 73

00 00 00 73 63

00 00 73 63 00

00 73 63 00 00

M:

29 29 29 29 9C

29 29 29 9C FF

29 29 9C FF FF

29 9C FF FF FF

Image dimensions (compressed)

Offset Size Description
0x00 4 Width
0x04 4 Height

Frame frm/frm16/frm24/frm32 format

  • Preliminary analysis, still subject to change.
byte count | = | description

TN: Swarm Demo (1998/07/14) uses a different frame format.
    Swarm Gold uses the newer frame format.
    01 Ivy - point of comparison for Zax frm vs frm16

1  = magic byte
    * 0x2E - Star Trek Away Team
    * 0x31 - Ricochet Xtreme, Zax
    * 0x32 - Swarm 1.4, Lionheart
    * 0x35 - Ricochet Lost Worlds, Wik
1  = frame type
    * 0x08 - frm
    * 0x10 - frm16
    * 0x18 - frm24
    * 0x20 - frm32
        [TN: Wik incorrectly assigns the file extension for this]
2  = hot spot x
2  = hot spot y
2  = width
2  = height
2  = engine revision [TN: scan this]
    * 4115 (0x1310) - Reflexive Arcade DRM
    * 4108 (0x100C) - Ricochet Lost Worlds: Recharged
                        1.1 Build 29 RA, 2004/10/27
    * 4107 (0x100B) - Ricochet Lost Worlds
                        1.1 Build 33 STM, 2007/03/29 17:39:50 [released April 20, 2007]
    * 2497 (0x09C1) - Ricochet Lost Worlds
    * 2847 (0x0B1F) - Ricochet Lost Worlds
    * 2846 (0x0B1E) - Ricochet Lost Worlds
    * varies        - Ricochet Lost Worlds
                        1.0 Build 20, 2004/05/03 16:42:51
                        1.0 Build 20, 2004/05/04 12:55:15 (No DRM/mjrtl aka MumboJumbo Retail)
    * 1092 (0x0444) - Star Trek Away Team (Demo)
    * 904  (0x0388) - Star Trek Away Team (Demo)
    * 379  (0x017B) - Star Trek Away Team (Demo)
                        1.0 Demo, 2001/03/14 19:38:29
    * 207  (0x00CF) - Swarm
    * 192  (0x00C0) - Swarm (some frm16's)
    * 190  (0x00BE) - Swarm (File Icon.frm16)
    * 189  (0x00BD) - Swarm (some frm16's, all fonts.frm32)
                        1.4 Build 262, 2003/04/21
    * 0    (0x0000) - Lionheart
    * 107  (0x006B) - Lionheart
                        1.0 Build 3005, 2003/07/29 13:58:58
    * 25   (0x0019) - Ricochet Xtreme
                        1.4 Build 75, 2006/12/28
    * 18   (0x0012) - Ricochet Xtreme
                        1.01 Build 50 2001/10/04
    * 18   (0x0012) - Zax
                        1.0 Build 1308, 2001/08/06
    [frm24 special case]
    * 0    (0x0000) - Wik and the Fable of Souls
                        040927 (2004/09/27)
    * 74   (0x004A) - Wik and the Fable of Souls
                        070502 (2007/05/02) [released May 10, 2007]

4  = flags (0b00000000_00000000_00F0000G_ABC00DE0)
          n layers
    [frm]
    C   - 5 layers      (0x00000020)
    CE  - 5 layers, RLE (0x00002022)
    [frm16]
    B   - 5 layers      (0x00000040)
    BD  - 5 layers, RLE (0x00000044)
    BDF - 5 layers, RLE (0x00002044)
    C   - 3 layers      (0x00000020)
    CDF - 3 layers, RLE (0x00002024)
    [frm24]
    A   - 5 layers      (0x00000080)
    [frm32]
    G   - 5 laters      (0x00000100)

4  = layer 1 size (little endian, actual field size varies from 1-4 bytes)

4  = layer 2 size

4  = layer 3 size

4  = layer 4 size (flag optional)

4  = layer 5 size (flag optional)

layer n size = embedded image
    [frm]
    * RGB332
    [frm 16]
    * RGB565:
        * RGB565 = (((red & 0xf8)<<8) + ((green & 0xfc)<<3) + (blue>>3))
        * RGB565 = (((RGB888&0xf80000)>>8) + ((RGB888&0xfc00)>>5) + ((RGB888&0xf8)>>3))
    * If RLE encoded, the first 4 bytes is a duplicate of the file size.
    [frm24]
    * RGB888
    [frm32]
    * ARGB8888

(image height * 4) = list of 4-byte indices of the leftmost and center pixel of each row until the middle row

---

if layers 1, 4, and 5 are in use...

- layer 1: count of transparent pixels
- layer 4: alpha value of semi-transparent pixels
- layer 5: image data in RLE

Sequence seq/seq16/seq24/seq32 format

  • Preliminary analysis, still subject to change.
TN: Font sequences have a slightly different format.

2  = padding [tn: scan]
1  = flags (0b1101A000)
    A - [UK2] Unknown 4-byte field is present.
        0xD8 present, 0xD0 absent
1  = magic byte (0x41)
4  = unknown value that varies per game
    * 0x44128000 - Star Trek Away Team
    * 0x43760000 - Ricochet Lost Worlds
    * 0x43600000 - Swarm 1.4
    * 0x43600000 - Ricochet Xtreme 1.3b60 - 1.4b75
    * 0x435F0000 - Ricochet Xtreme 1.01b50
    * 0x43520000 - Lionheart
    * 0x434F0000 - Zax

[UK2]
    4  = unknown (usually 0x00000000)
4  = Number of embedded frames
4  = Frames Per Second (IEEE 754 float)

[STAT/ZAX]
    1  = Center Hot Spot? (0x01)
4  = strlen of blit type text
na = blit type (text)

[RLW]
    4  = X offset
    4  = Y offset
    4  = Use Every
    1  = Always Include Last Frame
    1  = Center Hot Spot
    1  = Blended With Black
    1  = Crop Color 0
    1  = Use 8 Bit Alpha
    1  = Run Length Encode
    1  = Do Dither
    1  = Loss Less
    4  = Quality

[LION]
    4  = X offset
    4  = Y offset
    1  = Center Hot Spot?
    1  = Blended With Black?
    1  = Crop Color 0?
    1  = Use 8 Bit Alpha?
    1  = Do Dither?

[SWARM 1.4/RX]
    4  = X offset
    4  = Y offset
    1  = Center Hot Spot?
    1  = Blended With Black?
    1  = Crop Color 0?
    1  = Use 8 Bit Alpha?
    1  = Do Dither?
    1  = Loss Less?
    4  = Quality? [detect garbage values]

[STAT/ZAX]
    1  = Blended With Black?
    1  = Crop Color 0?
    1  = Use 8 Bit Alpha?
    1  = Dither?
    4  = X offset
    4  = Y offset

[FONT-RLW/RX/STAT]
    4 = Height Without Descenders
    4 = First ASCII
    4 = Last ASCII
    1 = Fixed Width

4  = Hotspot X
4  = Hotspot Y
4  = Center X (after cropping)
4  = Center Y (after cropping)

1  = Frame separator (0x01) or Empty sequence indicator (0x00)
nb = Frame data
     [TN: engine revision/unknown 1 seems to be missing]