View Single Post
Old 09-11-2016, 05:38 PM
LewisH LewisH is offline
Senior Member
Join Date: Mar 2012
Location: Earth
Posts: 215

I wrote a small tool to read and write these files a couple of months ago (not quite 'usable' enough that I'd release it, re-writing it for release has been on my to-do list for a while now.)

Here's my documentation of the format:

Each `pack` file is a texture atlas containing a texture (sometimes multiple
textures, but only for large images), and one or more sprites.

The file starts with a list of sprites.

First is a little endian (later referred to as 'LE') 32bit integer giving the
number of sprites the pack contains.

For each sprite, the following is then read:

   - It's file name
      + a UTF-8 string which starts with a 16bit LE integer giving the
         length of the string in bytes.
   - X-offset (The horizontal offset in pixels from the left of the image)
      + a 32bit LE integer.
   - Y-offset (The vertical offset in pixels from the bottom of the image)
      + a 32bit LE integer.
   - Width in pixels
      + a 32bit LE integer
   - Height in pixels
      + a 32bit LE integer

After the list of sprites is the metadata for the textures:

   - A 32bit big endian (BE) integer:
     - If the value is less than 10000, the image is uncompressed, and this
       value gives the pixel format:
        - 0 => ALPHA8
        - 1 => RGB5
        - 2 => RGBA4
        - 3 => RGBA8
        - 4 => DXT1
        - 5 => DXT1A
        - 6 => DXT3
        - 7 => DXT5
     - If the value is 10000 or higher, it gives the compression type, and
       _another_ 32bit integer is read for the pixel format.
        - 10000 => Uncompressed
        - 10001 => DXT
        - 10002 => JPEG
          - Altitude extends the JPEG format to add transparency, by way
            of an optional LZMA compressed bit-mask.
        - 10003 => LZMA
   - Another 32bit BE integer giving the repeat type:
     - 0 => Clamped
     - 1 => Repeat (a draw area larger than the texture will repeat the texture)
   - Another 32bit BE integer giving the filter type:
     - 0 => Nearest neighbour
     - 1 => Linear

Finally, the textures:

   - A 32 bit BE integer giving the number of textures.
   - For each texture:
     - It's width (32bit BE)
     - It's height (32bit BE)
     - The RAW pixel data, with the compression and pixel format given above.

The default maximum texture size is 256x256.

For large images there can be multiple textures which are tiled together
to make the full image. As far as I can tell, these packs only ever contain
a single sprite (presumably whatever bin-packing algorithm they use
starts with the largest, and ends when a single texture is full).
P.S. That glyph packing on the second texture in the OP... Gotta save the bits I guess ^^

Last edited by LewisH; 09-14-2016 at 04:40 PM.
Reply With Quote