Difference between revisions of "Image Formats (Apocalypse)"

From UFOpaedia
Jump to navigation Jump to search
(Created page with "{{tocright}}Image file formats used by X-COM: Apocalypse. <br clear=all> =PCK= An advancement on the version used by the previous games, whi...")
 
m (categorizing)
Line 163: Line 163:
  
 
[[Category:Game Files]]
 
[[Category:Game Files]]
 +
[[Category:Apocalypse]]

Revision as of 12:49, 23 July 2013

Image file formats used by X-COM: Apocalypse.


PCK

An advancement on the version used by the previous games, which can now use a variety of different compression methods on different sprites within the same image archive.

Most images are about 48x64 (the bounds of a single tile), but the format leaves itself open to much larger dimensions (for example, the giant Megaspawns aren't split up into multiple "tiles" like the large units in the previous games (such as the Cyberdiscs) - they nearly double the average sprite dimensions as a result).

As before, the image data indexes into an palette consisting of 256 colours. There is a unique palette stored for every terrain, but they're mostly similar (after all, your units need to look the same regardless of where you send them).

Each PCK file is again accompanied by a TAB file. Every image gets a four-byte record in the TAB which indicates where the image data for that sprite starts in the PCK; the image data ends where the next image begins (or EOF, whichever comes first).

When loading the following PCK archives (which contain terrain data), you must multiply the values of each TAB record by four:

  • Ground (contains, um, ground tiles)
  • Left (contains west walls)
  • Right (contains north walls)
  • Feature (contains "object" tiles)
  • Animate (doors opening, etc)

The first twelve bytes of each record in the PCK are a header:

Offset
(Decimal)
Offset
(Hex)
Usage
0 0x00 Compression mode. If 0, stop reading, there's no image to load and even the header won't be complete.
1-3 0x01-0x03 Unknown, usually blank (unless the compression mode is 128).
4-5 0x04-0x05 Left-most pixel within the sprite. No data should be rendered further left of this point.
6-7 0x08-0x09 Right-most pixel within the sprite. No data should be rendered at this point or further.
8-9 0x08-0x09 Top-most pixel within the sprite. No data should be rendered higher above this point.
10-11 0x0A-0x0B Bottom-most pixel within the sprite. No data should be rendered at this point or lower.

It seems you can ignore the dimensions in the header, though you should probably expect them to be accurate.

The image data then proceeds according to the compression mode used by the sprite.


Compression mode: 0

No image, don't render anything.


Compression mode: 1

RLE compression, but opaque pixels aren't compressed at all. The concept is fairly similar to that of the old PCK format (though it's been expanded out a bit). Keep reading & rendering records according to this pattern:

Offset
(Decimal)
Offset
(Hex)
Usage
0-3 0x00-0x03 Amount of pixels to skip, relative to where the tile is supposed to be rendered (ignore what the header has to say about the image dimensions and assume co-ord 0x0). Divide this by 640 and round down to get the row to start rendering at. Take the modulo of this and 640 to get the column to start rendering at.

(If this sounds needlessly confusing, at run time the game doesn't need to think in terms of rows and columns and so doesn't bother with the math - it just jumps to the exact address in the display memory to start dumping the sprite at and offloads it. This value is a shortcut).

If this is 0xFF FF FF FF, then stop rendering, you've hit the end of the sprite.

4 0x04 The column to start rendering at (again).
5 0x05 The amount of pixels this record contains.
6 0x06 Always 0 (probably part of the previous index).
7 0x07 Add one to this value then multiply by four to get the amount of pixels this record contains (... again).
8 ... 0x08 ... From this point, read the amount of pixels specified by index 5 and render then left to right on the display. Skip any values of 0 encountered.


Compression mode: 2

Uncommon, not entirely certain it's used at all...


Compression mode: 3

I guess you could describe this as LZ77 compression. Start out by loading the contents of TacData\XCOM.BLK into RAM - this contains all the actual pixel data used by sprites via this mode. Keep reading & rendering records according to the below pattern.

If a given record starts with 0xFF FF FF FF, then stop rendering, you've hit the end of the sprite.

Offset
(Decimal)
Offset
(Hex)
Usage
0 0x00 The amount of sub-records to render on this row.
1 0x01 Usually, this is 128 minus the amount of pixels drawn by the first sub-record rendered on the previous row. I'm not strictly sure what this means or why it's there.
2 0x02 Unknown
3 0x03 The row this record is to be rendered on.
4 0x04 Sub-records. Read & render however many index 0 specified, on the current row:
Offset
(Decimal)
Offset
(Hex)
Usage
0 0x00 Column to start rendering, relative to where the last sub-record finished (or relative to column 0, if this is the first sub-record on the row).
1 0x01 Amount of pixels to render.
2-4 0x02-0x04 A three byte value that indexes into TacData\XCOM.BLK. Starting from this location, read however many bytes index 1 specified and render them left-to-right on the display.


Compression mode: 128

I haven't looked into this one as of yet, but the context this mode is used in suggests it's mainly used for smoke clouds (which'd use lots of transparent pixels).