<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://temp.ufopaedia.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=JonnyH</id>
	<title>UFOpaedia - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://temp.ufopaedia.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=JonnyH"/>
	<link rel="alternate" type="text/html" href="https://temp.ufopaedia.org/Special:Contributions/JonnyH"/>
	<updated>2026-05-01T05:56:06Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=65391</id>
		<title>Image Formats (Apocalypse)</title>
		<link rel="alternate" type="text/html" href="https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=65391"/>
		<updated>2015-06-07T20:20:20Z</updated>

		<summary type="html">&lt;p&gt;JonnyH: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}Image file formats used by [[Apocalypse|X-COM: Apocalypse]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
=PCK=&lt;br /&gt;
An advancement on the version used by [[Image_Formats#PCK|the previous games]], which can now use a variety of different compression methods on different sprites within the same image archive.&lt;br /&gt;
&lt;br /&gt;
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 [[Megaspawn]]s aren&#039;t split up into multiple &amp;quot;tiles&amp;quot; like the large units in the previous games (such as the [[Cyberdisc]]s) - they nearly double the average sprite dimensions as a result).&lt;br /&gt;
&lt;br /&gt;
As before, the image data indexes into an palette consisting of 256 colours. There is a unique palette stored for every terrain, but they&#039;re mostly similar (after all, your units need to look the same regardless of where you send them).&lt;br /&gt;
&lt;br /&gt;
==TAB==&lt;br /&gt;
Each PCK file is again accompanied by a TAB file. The TAB file contains a 32bit integer (4 bytes, little endian) per image. This value needs to be multipled by 4 to get the file offset in the PCK of the image header.&lt;br /&gt;
&lt;br /&gt;
==Image Header==&lt;br /&gt;
The first twelve bytes of each image in the PCK are a header:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression mode. If 0, stop reading, there&#039;s no image to load and even the header won&#039;t be complete.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1-3&lt;br /&gt;
!0x01-0x03&lt;br /&gt;
|Unknown, usually blank (unless the compression mode is 128).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Left-most pixel within the sprite. No data should be rendered further left of this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Right-most pixel within the sprite. No data should be rendered at this point or further.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8-9&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Top-most pixel within the sprite. No data should be rendered higher above this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!10-11&lt;br /&gt;
!0x0A-0x0B&lt;br /&gt;
|Bottom-most pixel within the sprite. No data should be rendered at this point or lower.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Width = Right-Most pixel - Left-ost pixel&lt;br /&gt;
Height = Bottom-Most pixel - Top-Most pixel&lt;br /&gt;
&lt;br /&gt;
The image data then proceeds according to the compression mode used by the sprite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 0==&lt;br /&gt;
No image, don&#039;t render anything.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 1==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Run-length_encoding RLE compression], but opaque pixels aren&#039;t compressed at all. The concept is fairly similar to that of the old PCK format (though it&#039;s been expanded out a bit). Keep reading &amp;amp; rendering records according to this pattern:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0-3&lt;br /&gt;
!0x00-0x03&lt;br /&gt;
|Amount of pixels to skip from co-ordinate (0, 0). If this is 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
You can calculate the Y co-ordinate for your row by taking the integer value of this divided by 640 (rounding down).&lt;br /&gt;
To make the Y co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Top-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Quick access to the X co-ordinate (so you don&#039;t have to calculate the modulus of the pixels to skip).&lt;br /&gt;
To make the X co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Left-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
!0x05&lt;br /&gt;
|The amount of pixels this record contains.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
!0x06&lt;br /&gt;
|Always 0 (Assuming &amp;quot;Left Padding&amp;quot;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!7&lt;br /&gt;
!0x07&lt;br /&gt;
|Right Padding. This is the number of pixels in the row you don&#039;t need to draw.&lt;br /&gt;
Pixels To Draw = (Amount Of Pixels) - (Right Padding)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8 ...&lt;br /&gt;
!0x08 ...&lt;br /&gt;
|From this point, read the amount of pixels specified by index 5 and render then left to right on the display. Palette Index 0 is transparent&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 2==&lt;br /&gt;
Uncommon, not entirely certain it&#039;s used at all...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 3==&lt;br /&gt;
I guess you could describe this as [http://en.wikipedia.org/wiki/LZ77_and_LZ78 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 &amp;amp; rendering records according to the below pattern.&lt;br /&gt;
&lt;br /&gt;
If a given record starts with 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|The amount of sub-records to render on this row.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Usually, this is 128 minus the amount of pixels drawn by the &#039;&#039;first&#039;&#039; sub-record rendered on the &#039;&#039;previous&#039;&#039; row. I&#039;m not strictly sure what this means or why it&#039;s there.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
!0x02&lt;br /&gt;
|&#039;&#039;Unknown&#039;&#039;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
!0x03&lt;br /&gt;
|The row this record is to be rendered on.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Sub-records. Read &amp;amp; render however many index 0 specified, on the current row:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|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).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Amount of pixels to render.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-4&lt;br /&gt;
!0x02-0x04&lt;br /&gt;
|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.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Shadow sprites==&lt;br /&gt;
These files contain a transparent &#039;dither&#039; mask to render shadows etc.&lt;br /&gt;
NOTE - These files do not seem to have the same first two bytes so that cannot be used solely to decide which &#039;compression format&#039; each file is encoded with - for example &#039;tacdata/aliens/alien/poppers.pck (popper shadows) is this format with the first two bytes as &#039;0x00 0x6e&#039;. Which files are in this format may be &#039;baked in&#039; to the executable, or it&#039;s a &#039;none of the above&#039; clause.&lt;br /&gt;
&lt;br /&gt;
It starts with an 8 byte header&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression format header (Always seems to be either &#039;0x0&#039; or &#039;0x80&#039;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Unknown - multiple different values seen&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-3&lt;br /&gt;
!0x02-0x03&lt;br /&gt;
|Unknown - always seems to be zero?&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Width of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x06-0x07&lt;br /&gt;
|Height of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Following this are a number of 2-byte pairs implementing a RLE-like encoding, encoding pixels as a lookup into a 4 pixel wide lookup table of if each pixel is occluded or not&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Repeat count - the number of repeated 4-pixel units - if 0xFF (255) stop as you&#039;ve reached the end of the image.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Index into a 7-entry lookup table for 4-pixel values&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The stride of these images always seems to be 640 pixels (140 4-pixel units) - IE each row contains 640 total pixel values, but only the width specified in the header are actually drawn.&lt;br /&gt;
&lt;br /&gt;
The lookup table looks like this:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Index&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Pixel value (0 = transparent, 1 = opaque)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
|0 0 0 0 (All transparent)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
|1 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
|0 1 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
|1 0 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
| 0 1 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
|0 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
|0 0 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
I do not know where the colour for the pixel is selected, maybe always black?&lt;br /&gt;
&lt;br /&gt;
=PCX=&lt;br /&gt;
There are a number of images in PCX format, these are standard and most graphic packages can read them&lt;br /&gt;
&lt;br /&gt;
=MOUSE.DAT=&lt;br /&gt;
This file contains 9 images with a resolution of 24 x 24 pixels, using 8bpp with a palette index&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Files]]&lt;br /&gt;
[[Category:Apocalypse]]&lt;/div&gt;</summary>
		<author><name>JonnyH</name></author>
	</entry>
	<entry>
		<id>https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=65390</id>
		<title>Image Formats (Apocalypse)</title>
		<link rel="alternate" type="text/html" href="https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=65390"/>
		<updated>2015-06-07T20:17:15Z</updated>

		<summary type="html">&lt;p&gt;JonnyH: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}Image file formats used by [[Apocalypse|X-COM: Apocalypse]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
=PCK=&lt;br /&gt;
An advancement on the version used by [[Image_Formats#PCK|the previous games]], which can now use a variety of different compression methods on different sprites within the same image archive.&lt;br /&gt;
&lt;br /&gt;
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 [[Megaspawn]]s aren&#039;t split up into multiple &amp;quot;tiles&amp;quot; like the large units in the previous games (such as the [[Cyberdisc]]s) - they nearly double the average sprite dimensions as a result).&lt;br /&gt;
&lt;br /&gt;
As before, the image data indexes into an palette consisting of 256 colours. There is a unique palette stored for every terrain, but they&#039;re mostly similar (after all, your units need to look the same regardless of where you send them).&lt;br /&gt;
&lt;br /&gt;
==TAB==&lt;br /&gt;
Each PCK file is again accompanied by a TAB file. The TAB file contains a 32bit integer (4 bytes, little endian) per image. This value needs to be multipled by 4 to get the file offset in the PCK of the image header.&lt;br /&gt;
&lt;br /&gt;
==Image Header==&lt;br /&gt;
The first twelve bytes of each image in the PCK are a header:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression mode. If 0, stop reading, there&#039;s no image to load and even the header won&#039;t be complete.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1-3&lt;br /&gt;
!0x01-0x03&lt;br /&gt;
|Unknown, usually blank (unless the compression mode is 128).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Left-most pixel within the sprite. No data should be rendered further left of this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Right-most pixel within the sprite. No data should be rendered at this point or further.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8-9&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Top-most pixel within the sprite. No data should be rendered higher above this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!10-11&lt;br /&gt;
!0x0A-0x0B&lt;br /&gt;
|Bottom-most pixel within the sprite. No data should be rendered at this point or lower.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Width = Right-Most pixel - Left-ost pixel&lt;br /&gt;
Height = Bottom-Most pixel - Top-Most pixel&lt;br /&gt;
&lt;br /&gt;
The image data then proceeds according to the compression mode used by the sprite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 0==&lt;br /&gt;
No image, don&#039;t render anything.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 1==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Run-length_encoding RLE compression], but opaque pixels aren&#039;t compressed at all. The concept is fairly similar to that of the old PCK format (though it&#039;s been expanded out a bit). Keep reading &amp;amp; rendering records according to this pattern:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0-3&lt;br /&gt;
!0x00-0x03&lt;br /&gt;
|Amount of pixels to skip from co-ordinate (0, 0). If this is 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
You can calculate the Y co-ordinate for your row by taking the integer value of this divided by 640 (rounding down).&lt;br /&gt;
To make the Y co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Top-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Quick access to the X co-ordinate (so you don&#039;t have to calculate the modulus of the pixels to skip).&lt;br /&gt;
To make the X co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Left-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
!0x05&lt;br /&gt;
|The amount of pixels this record contains.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
!0x06&lt;br /&gt;
|Always 0 (Assuming &amp;quot;Left Padding&amp;quot;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!7&lt;br /&gt;
!0x07&lt;br /&gt;
|Right Padding. This is the number of pixels in the row you don&#039;t need to draw.&lt;br /&gt;
Pixels To Draw = (Amount Of Pixels) - (Right Padding)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8 ...&lt;br /&gt;
!0x08 ...&lt;br /&gt;
|From this point, read the amount of pixels specified by index 5 and render then left to right on the display. Palette Index 0 is transparent&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 2==&lt;br /&gt;
Uncommon, not entirely certain it&#039;s used at all...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 3==&lt;br /&gt;
I guess you could describe this as [http://en.wikipedia.org/wiki/LZ77_and_LZ78 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 &amp;amp; rendering records according to the below pattern.&lt;br /&gt;
&lt;br /&gt;
If a given record starts with 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|The amount of sub-records to render on this row.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Usually, this is 128 minus the amount of pixels drawn by the &#039;&#039;first&#039;&#039; sub-record rendered on the &#039;&#039;previous&#039;&#039; row. I&#039;m not strictly sure what this means or why it&#039;s there.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
!0x02&lt;br /&gt;
|&#039;&#039;Unknown&#039;&#039;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
!0x03&lt;br /&gt;
|The row this record is to be rendered on.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Sub-records. Read &amp;amp; render however many index 0 specified, on the current row:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|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).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Amount of pixels to render.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-4&lt;br /&gt;
!0x02-0x04&lt;br /&gt;
|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.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Shadow sprites==&lt;br /&gt;
These files contain a transparent &#039;dither&#039; mask to render shadows etc.&lt;br /&gt;
NOTE - These files do not seem to have the same first two bytes so that cannot be used solely to decide which &#039;compression format&#039; each file is encoded with - for example &#039;tacdata/aliens/alien/poppers.pck (popper shadows) is this format with the first two bytes as &#039;0x00 0x6e&#039;. Which files are in this format may be &#039;baked in&#039; to the executable, or it&#039;s a &#039;none of the above&#039; clause.&lt;br /&gt;
&lt;br /&gt;
It starts with an 8 byte header&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression format header (Always seems to be either &#039;0x0&#039; or &#039;0x80&#039;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Unknown - multiple different values seen&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-3&lt;br /&gt;
!0x02-0x03&lt;br /&gt;
|Unknown - always seems to be zero?&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Width of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x06-0x07&lt;br /&gt;
|Height of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Following this are a number of 2-byte pairs implementing a RLE-like encoding, encoding pixels as a lookup into a 4 pixel wide lookup table of if each pixel is occluded or not&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Repeat count - the number of repeated 4-pixel units - if 0xFF (255) stop as you&#039;ve reached the end of the image. Ignore the highest bit (Possibly a flag to say &#039;next line?&#039;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Index into a 7-entry lookup table for 4-pixel values&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The stride of these images always seems to be 640 pixels (140 4-pixel units) - IE each row contains 640 total pixel values, but only the width specified in the header are actually drawn.&lt;br /&gt;
&lt;br /&gt;
The lookup table looks like this:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Index&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Pixel value (0 = transparent, 1 = opaque)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
|0 0 0 0 (All transparent)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
|1 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
|0 1 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
|1 0 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
| 0 1 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
|0 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
|0 0 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
I do not know where the colour for the pixel is selected, maybe always black?&lt;br /&gt;
&lt;br /&gt;
=PCX=&lt;br /&gt;
There are a number of images in PCX format, these are standard and most graphic packages can read them&lt;br /&gt;
&lt;br /&gt;
=MOUSE.DAT=&lt;br /&gt;
This file contains 9 images with a resolution of 24 x 24 pixels, using 8bpp with a palette index&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Files]]&lt;br /&gt;
[[Category:Apocalypse]]&lt;/div&gt;</summary>
		<author><name>JonnyH</name></author>
	</entry>
	<entry>
		<id>https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=64125</id>
		<title>Image Formats (Apocalypse)</title>
		<link rel="alternate" type="text/html" href="https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=64125"/>
		<updated>2015-04-23T20:49:59Z</updated>

		<summary type="html">&lt;p&gt;JonnyH: Add comment of how shadow sprites may not follow the same &amp;#039;compression mode&amp;#039; format&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}Image file formats used by [[Apocalypse|X-COM: Apocalypse]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
=PCK=&lt;br /&gt;
An advancement on the version used by [[Image_Formats#PCK|the previous games]], which can now use a variety of different compression methods on different sprites within the same image archive.&lt;br /&gt;
&lt;br /&gt;
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 [[Megaspawn]]s aren&#039;t split up into multiple &amp;quot;tiles&amp;quot; like the large units in the previous games (such as the [[Cyberdisc]]s) - they nearly double the average sprite dimensions as a result).&lt;br /&gt;
&lt;br /&gt;
As before, the image data indexes into an palette consisting of 256 colours. There is a unique palette stored for every terrain, but they&#039;re mostly similar (after all, your units need to look the same regardless of where you send them).&lt;br /&gt;
&lt;br /&gt;
==TAB==&lt;br /&gt;
Each PCK file is again accompanied by a TAB file. The TAB file contains a 32bit integer (4 bytes, little endian) per image. This value needs to be multipled by 4 to get the file offset in the PCK of the image header.&lt;br /&gt;
&lt;br /&gt;
==Image Header==&lt;br /&gt;
The first twelve bytes of each image in the PCK are a header:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression mode. If 0, stop reading, there&#039;s no image to load and even the header won&#039;t be complete.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1-3&lt;br /&gt;
!0x01-0x03&lt;br /&gt;
|Unknown, usually blank (unless the compression mode is 128).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Left-most pixel within the sprite. No data should be rendered further left of this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Right-most pixel within the sprite. No data should be rendered at this point or further.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8-9&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Top-most pixel within the sprite. No data should be rendered higher above this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!10-11&lt;br /&gt;
!0x0A-0x0B&lt;br /&gt;
|Bottom-most pixel within the sprite. No data should be rendered at this point or lower.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Width = Right-Most pixel - Left-ost pixel&lt;br /&gt;
Height = Bottom-Most pixel - Top-Most pixel&lt;br /&gt;
&lt;br /&gt;
The image data then proceeds according to the compression mode used by the sprite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 0==&lt;br /&gt;
No image, don&#039;t render anything.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 1==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Run-length_encoding RLE compression], but opaque pixels aren&#039;t compressed at all. The concept is fairly similar to that of the old PCK format (though it&#039;s been expanded out a bit). Keep reading &amp;amp; rendering records according to this pattern:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0-3&lt;br /&gt;
!0x00-0x03&lt;br /&gt;
|Amount of pixels to skip from co-ordinate (0, 0). If this is 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
You can calculate the Y co-ordinate for your row by taking the integer value of this divided by 640 (rounding down).&lt;br /&gt;
To make the Y co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Top-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Quick access to the X co-ordinate (so you don&#039;t have to calculate the modulus of the pixels to skip).&lt;br /&gt;
To make the X co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Left-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
!0x05&lt;br /&gt;
|The amount of pixels this record contains.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
!0x06&lt;br /&gt;
|Always 0 (Assuming &amp;quot;Left Padding&amp;quot;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!7&lt;br /&gt;
!0x07&lt;br /&gt;
|Right Padding. This is the number of pixels in the row you don&#039;t need to draw.&lt;br /&gt;
Pixels To Draw = (Amount Of Pixels) - (Right Padding)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8 ...&lt;br /&gt;
!0x08 ...&lt;br /&gt;
|From this point, read the amount of pixels specified by index 5 and render then left to right on the display. Palette Index 0 is transparent&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 2==&lt;br /&gt;
Uncommon, not entirely certain it&#039;s used at all...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 3==&lt;br /&gt;
I guess you could describe this as [http://en.wikipedia.org/wiki/LZ77_and_LZ78 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 &amp;amp; rendering records according to the below pattern.&lt;br /&gt;
&lt;br /&gt;
If a given record starts with 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|The amount of sub-records to render on this row.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Usually, this is 128 minus the amount of pixels drawn by the &#039;&#039;first&#039;&#039; sub-record rendered on the &#039;&#039;previous&#039;&#039; row. I&#039;m not strictly sure what this means or why it&#039;s there.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
!0x02&lt;br /&gt;
|&#039;&#039;Unknown&#039;&#039;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
!0x03&lt;br /&gt;
|The row this record is to be rendered on.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Sub-records. Read &amp;amp; render however many index 0 specified, on the current row:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|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).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Amount of pixels to render.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-4&lt;br /&gt;
!0x02-0x04&lt;br /&gt;
|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.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Shadow sprites==&lt;br /&gt;
These files contain a transparent &#039;dither&#039; mask to render shadows etc.&lt;br /&gt;
NOTE - These files do not seem to have the same first two bytes so that cannot be used solely to decide which &#039;compression format&#039; each file is encoded with - for example &#039;tacdata/aliens/alien/poppers.pck (popper shadows) is this format with the first two bytes as &#039;0x00 0x6e&#039;. Which files are in this format may be &#039;baked in&#039; to the executable, or it&#039;s a &#039;none of the above&#039; clause.&lt;br /&gt;
&lt;br /&gt;
It starts with an 8 byte header&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression format header (Always seems to be either &#039;0x0&#039; or &#039;0x80&#039;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Unknown - multiple different values seen&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-3&lt;br /&gt;
!0x02-0x03&lt;br /&gt;
|Unknown - always seems to be zero?&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Width of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x06-0x07&lt;br /&gt;
|Height of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Following this are a number of 2-byte pairs implementing a RLE-like encoding, encoding pixels as a lookup into a 4 pixel wide lookup table of if each pixel is occluded or not&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Repeat count - the number of repeated 4-pixel units - if 0xFF (255) stop as you&#039;ve reached the end of the image. Ignore the highest bit (Possibly a flag to say &#039;next line?&#039;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Index into a 7-entry lookup table for 4-pixel values&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
NOTE: The stride of the images always seems to be 128 - IE each row contains 128 total pixel values (or 32 table indices), but only the width specified in the header are actually drawn.&lt;br /&gt;
&lt;br /&gt;
The lookup table looks like this:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Index&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Pixel value (0 = transparent, 1 = opaque)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
|0 0 0 0 (All transparent)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
|1 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
|0 1 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
|1 0 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
| 0 1 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
|0 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
|0 0 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
I do not know where the colour for the pixel is selected, maybe always black?&lt;br /&gt;
&lt;br /&gt;
=PCX=&lt;br /&gt;
There are a number of images in PCX format, these are standard and most graphic packages can read them&lt;br /&gt;
&lt;br /&gt;
=MOUSE.DAT=&lt;br /&gt;
This file contains 9 images with a resolution of 24 x 24 pixels, using 8bpp with a palette index&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Files]]&lt;br /&gt;
[[Category:Apocalypse]]&lt;/div&gt;</summary>
		<author><name>JonnyH</name></author>
	</entry>
	<entry>
		<id>https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=64116</id>
		<title>Image Formats (Apocalypse)</title>
		<link rel="alternate" type="text/html" href="https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=64116"/>
		<updated>2015-04-21T17:11:31Z</updated>

		<summary type="html">&lt;p&gt;JonnyH: format128: stride is 128, not 256, mask off top bit of count&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}Image file formats used by [[Apocalypse|X-COM: Apocalypse]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
=PCK=&lt;br /&gt;
An advancement on the version used by [[Image_Formats#PCK|the previous games]], which can now use a variety of different compression methods on different sprites within the same image archive.&lt;br /&gt;
&lt;br /&gt;
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 [[Megaspawn]]s aren&#039;t split up into multiple &amp;quot;tiles&amp;quot; like the large units in the previous games (such as the [[Cyberdisc]]s) - they nearly double the average sprite dimensions as a result).&lt;br /&gt;
&lt;br /&gt;
As before, the image data indexes into an palette consisting of 256 colours. There is a unique palette stored for every terrain, but they&#039;re mostly similar (after all, your units need to look the same regardless of where you send them).&lt;br /&gt;
&lt;br /&gt;
==TAB==&lt;br /&gt;
Each PCK file is again accompanied by a TAB file. The TAB file contains a 32bit integer (4 bytes, little endian) per image. This value needs to be multipled by 4 to get the file offset in the PCK of the image header.&lt;br /&gt;
&lt;br /&gt;
==Image Header==&lt;br /&gt;
The first twelve bytes of each image in the PCK are a header:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression mode. If 0, stop reading, there&#039;s no image to load and even the header won&#039;t be complete.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1-3&lt;br /&gt;
!0x01-0x03&lt;br /&gt;
|Unknown, usually blank (unless the compression mode is 128).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Left-most pixel within the sprite. No data should be rendered further left of this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Right-most pixel within the sprite. No data should be rendered at this point or further.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8-9&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Top-most pixel within the sprite. No data should be rendered higher above this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!10-11&lt;br /&gt;
!0x0A-0x0B&lt;br /&gt;
|Bottom-most pixel within the sprite. No data should be rendered at this point or lower.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Width = Right-Most pixel - Left-ost pixel&lt;br /&gt;
Height = Bottom-Most pixel - Top-Most pixel&lt;br /&gt;
&lt;br /&gt;
The image data then proceeds according to the compression mode used by the sprite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 0==&lt;br /&gt;
No image, don&#039;t render anything.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 1==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Run-length_encoding RLE compression], but opaque pixels aren&#039;t compressed at all. The concept is fairly similar to that of the old PCK format (though it&#039;s been expanded out a bit). Keep reading &amp;amp; rendering records according to this pattern:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0-3&lt;br /&gt;
!0x00-0x03&lt;br /&gt;
|Amount of pixels to skip from co-ordinate (0, 0). If this is 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
You can calculate the Y co-ordinate for your row by taking the integer value of this divided by 640 (rounding down).&lt;br /&gt;
To make the Y co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Top-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Quick access to the X co-ordinate (so you don&#039;t have to calculate the modulus of the pixels to skip).&lt;br /&gt;
To make the X co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Left-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
!0x05&lt;br /&gt;
|The amount of pixels this record contains.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
!0x06&lt;br /&gt;
|Always 0 (Assuming &amp;quot;Left Padding&amp;quot;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!7&lt;br /&gt;
!0x07&lt;br /&gt;
|Right Padding. This is the number of pixels in the row you don&#039;t need to draw.&lt;br /&gt;
Pixels To Draw = (Amount Of Pixels) - (Right Padding)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8 ...&lt;br /&gt;
!0x08 ...&lt;br /&gt;
|From this point, read the amount of pixels specified by index 5 and render then left to right on the display. Palette Index 0 is transparent&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 2==&lt;br /&gt;
Uncommon, not entirely certain it&#039;s used at all...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 3==&lt;br /&gt;
I guess you could describe this as [http://en.wikipedia.org/wiki/LZ77_and_LZ78 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 &amp;amp; rendering records according to the below pattern.&lt;br /&gt;
&lt;br /&gt;
If a given record starts with 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|The amount of sub-records to render on this row.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Usually, this is 128 minus the amount of pixels drawn by the &#039;&#039;first&#039;&#039; sub-record rendered on the &#039;&#039;previous&#039;&#039; row. I&#039;m not strictly sure what this means or why it&#039;s there.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
!0x02&lt;br /&gt;
|&#039;&#039;Unknown&#039;&#039;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
!0x03&lt;br /&gt;
|The row this record is to be rendered on.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Sub-records. Read &amp;amp; render however many index 0 specified, on the current row:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|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).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Amount of pixels to render.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-4&lt;br /&gt;
!0x02-0x04&lt;br /&gt;
|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.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 128==&lt;br /&gt;
These files contain a transparent &#039;dither&#039; mask to render shadows etc.&lt;br /&gt;
NOTE - not all these files have the first byte as &#039;128&#039; - for example &#039;tacdata/aliens/alien/poppers.pck (popper shadows) is this format with the first two bytes as &#039;0x00 0x6e&#039;. Which files are in this format may be &#039;baked in&#039; to the executable, or it&#039;s a &#039;none of the above&#039; clause&lt;br /&gt;
&lt;br /&gt;
It starts with an 8 byte header&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression format header (Always seems to be either &#039;0x0&#039; or &#039;0x80&#039;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Unknown - multiple different values seen&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-3&lt;br /&gt;
!0x02-0x03&lt;br /&gt;
|Unknown - always seems to be zero?&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Width of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x06-0x07&lt;br /&gt;
|Height of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Following this are a number of 2-byte pairs implementing a RLE-like encoding, encoding pixels as a lookup into a 4 pixel wide lookup table of if each pixel is occluded or not&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Repeat count - the number of repeated 4-pixel units - if 0xFF (255) stop as you&#039;ve reached the end of the image. Ignore the highest bit (Possibly a flag to say &#039;next line?&#039;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Index into a 7-entry lookup table for 4-pixel values&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
NOTE: The stride of the images always seems to be 128 - IE each row contains 128 total pixel values (or 32 table indices), but only the width specified in the header are actually drawn.&lt;br /&gt;
&lt;br /&gt;
The lookup table looks like this:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Index&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Pixel value (0 = transparent, 1 = opaque)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
|0 0 0 0 (All transparent)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
|1 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
|0 1 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
|1 0 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
| 0 1 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
|0 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
|0 0 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
I do not know where the colour for the pixel is selected, maybe always black?&lt;br /&gt;
&lt;br /&gt;
=PCX=&lt;br /&gt;
There are a number of images in PCX format, these are standard and most graphic packages can read them&lt;br /&gt;
&lt;br /&gt;
=MOUSE.DAT=&lt;br /&gt;
This file contains 9 images with a resolution of 24 x 24 pixels, using 8bpp with a palette index&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Files]]&lt;br /&gt;
[[Category:Apocalypse]]&lt;/div&gt;</summary>
		<author><name>JonnyH</name></author>
	</entry>
	<entry>
		<id>https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=64095</id>
		<title>Image Formats (Apocalypse)</title>
		<link rel="alternate" type="text/html" href="https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=64095"/>
		<updated>2015-04-21T00:20:30Z</updated>

		<summary type="html">&lt;p&gt;JonnyH: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}Image file formats used by [[Apocalypse|X-COM: Apocalypse]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
=PCK=&lt;br /&gt;
An advancement on the version used by [[Image_Formats#PCK|the previous games]], which can now use a variety of different compression methods on different sprites within the same image archive.&lt;br /&gt;
&lt;br /&gt;
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 [[Megaspawn]]s aren&#039;t split up into multiple &amp;quot;tiles&amp;quot; like the large units in the previous games (such as the [[Cyberdisc]]s) - they nearly double the average sprite dimensions as a result).&lt;br /&gt;
&lt;br /&gt;
As before, the image data indexes into an palette consisting of 256 colours. There is a unique palette stored for every terrain, but they&#039;re mostly similar (after all, your units need to look the same regardless of where you send them).&lt;br /&gt;
&lt;br /&gt;
==TAB==&lt;br /&gt;
Each PCK file is again accompanied by a TAB file. The TAB file contains a 32bit integer (4 bytes, little endian) per image. This value needs to be multipled by 4 to get the file offset in the PCK of the image header.&lt;br /&gt;
&lt;br /&gt;
==Image Header==&lt;br /&gt;
The first twelve bytes of each image in the PCK are a header:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression mode. If 0, stop reading, there&#039;s no image to load and even the header won&#039;t be complete.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1-3&lt;br /&gt;
!0x01-0x03&lt;br /&gt;
|Unknown, usually blank (unless the compression mode is 128).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Left-most pixel within the sprite. No data should be rendered further left of this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Right-most pixel within the sprite. No data should be rendered at this point or further.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8-9&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Top-most pixel within the sprite. No data should be rendered higher above this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!10-11&lt;br /&gt;
!0x0A-0x0B&lt;br /&gt;
|Bottom-most pixel within the sprite. No data should be rendered at this point or lower.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Width = Right-Most pixel - Left-ost pixel&lt;br /&gt;
Height = Bottom-Most pixel - Top-Most pixel&lt;br /&gt;
&lt;br /&gt;
The image data then proceeds according to the compression mode used by the sprite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 0==&lt;br /&gt;
No image, don&#039;t render anything.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 1==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Run-length_encoding RLE compression], but opaque pixels aren&#039;t compressed at all. The concept is fairly similar to that of the old PCK format (though it&#039;s been expanded out a bit). Keep reading &amp;amp; rendering records according to this pattern:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0-3&lt;br /&gt;
!0x00-0x03&lt;br /&gt;
|Amount of pixels to skip from co-ordinate (0, 0). If this is 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
You can calculate the Y co-ordinate for your row by taking the integer value of this divided by 640 (rounding down).&lt;br /&gt;
To make the Y co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Top-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Quick access to the X co-ordinate (so you don&#039;t have to calculate the modulus of the pixels to skip).&lt;br /&gt;
To make the X co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Left-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
!0x05&lt;br /&gt;
|The amount of pixels this record contains.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
!0x06&lt;br /&gt;
|Always 0 (Assuming &amp;quot;Left Padding&amp;quot;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!7&lt;br /&gt;
!0x07&lt;br /&gt;
|Right Padding. This is the number of pixels in the row you don&#039;t need to draw.&lt;br /&gt;
Pixels To Draw = (Amount Of Pixels) - (Right Padding)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8 ...&lt;br /&gt;
!0x08 ...&lt;br /&gt;
|From this point, read the amount of pixels specified by index 5 and render then left to right on the display. Palette Index 0 is transparent&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 2==&lt;br /&gt;
Uncommon, not entirely certain it&#039;s used at all...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 3==&lt;br /&gt;
I guess you could describe this as [http://en.wikipedia.org/wiki/LZ77_and_LZ78 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 &amp;amp; rendering records according to the below pattern.&lt;br /&gt;
&lt;br /&gt;
If a given record starts with 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|The amount of sub-records to render on this row.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Usually, this is 128 minus the amount of pixels drawn by the &#039;&#039;first&#039;&#039; sub-record rendered on the &#039;&#039;previous&#039;&#039; row. I&#039;m not strictly sure what this means or why it&#039;s there.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
!0x02&lt;br /&gt;
|&#039;&#039;Unknown&#039;&#039;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
!0x03&lt;br /&gt;
|The row this record is to be rendered on.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Sub-records. Read &amp;amp; render however many index 0 specified, on the current row:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|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).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Amount of pixels to render.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-4&lt;br /&gt;
!0x02-0x04&lt;br /&gt;
|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.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 128==&lt;br /&gt;
These files contain a transparent &#039;dither&#039; mask to render shadows etc.&lt;br /&gt;
NOTE - not all these files have the first byte as &#039;128&#039; - for example &#039;tacdata/aliens/alien/poppers.pck (popper shadows) is this format with the first two bytes as &#039;0x00 0x6e&#039;. Which files are in this format may be &#039;baked in&#039; to the executable, or it&#039;s a &#039;none of the above&#039; clause&lt;br /&gt;
&lt;br /&gt;
It starts with an 8 byte header&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression format header (Always seems to be either &#039;0x0&#039; or &#039;0x80&#039;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Unknown - multiple different values seen&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-3&lt;br /&gt;
!0x02-0x03&lt;br /&gt;
|Unknown - always seems to be zero?&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Width of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x06-0x07&lt;br /&gt;
|Height of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Following this are a number of 2-byte pairs implementing a RLE-like encoding, encoding pixels as a lookup into a 4 pixel wide lookup table of if each pixel is occluded or not&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Repeat count - the number of repeated 4-pixel units - if 0xFF (255) stop as you&#039;ve reached the end of the image&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Index into a 7-entry lookup table for 4-pixel values&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
NOTE: The stride of the images always seems to be 256 - IE each row contains 256 total pixel values (or 64 table indices), but only the width specified in the header are actually drawn.&lt;br /&gt;
&lt;br /&gt;
The lookup table looks like this:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Index&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Pixel value (0 = transparent, 1 = opaque)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
|0 0 0 0 (All transparent)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
|1 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
|0 1 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
|1 0 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
| 0 1 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
|0 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
|0 0 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
I do not know where the colour for the pixel is selected, maybe always black?&lt;br /&gt;
&lt;br /&gt;
=PCX=&lt;br /&gt;
There are a number of images in PCX format, these are standard and most graphic packages can read them&lt;br /&gt;
&lt;br /&gt;
=MOUSE.DAT=&lt;br /&gt;
This file contains 9 images with a resolution of 24 x 24 pixels, using 8bpp with a palette index&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Files]]&lt;br /&gt;
[[Category:Apocalypse]]&lt;/div&gt;</summary>
		<author><name>JonnyH</name></author>
	</entry>
	<entry>
		<id>https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=64094</id>
		<title>Image Formats (Apocalypse)</title>
		<link rel="alternate" type="text/html" href="https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=64094"/>
		<updated>2015-04-21T00:19:20Z</updated>

		<summary type="html">&lt;p&gt;JonnyH: format-128 header table typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}Image file formats used by [[Apocalypse|X-COM: Apocalypse]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
=PCK=&lt;br /&gt;
An advancement on the version used by [[Image_Formats#PCK|the previous games]], which can now use a variety of different compression methods on different sprites within the same image archive.&lt;br /&gt;
&lt;br /&gt;
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 [[Megaspawn]]s aren&#039;t split up into multiple &amp;quot;tiles&amp;quot; like the large units in the previous games (such as the [[Cyberdisc]]s) - they nearly double the average sprite dimensions as a result).&lt;br /&gt;
&lt;br /&gt;
As before, the image data indexes into an palette consisting of 256 colours. There is a unique palette stored for every terrain, but they&#039;re mostly similar (after all, your units need to look the same regardless of where you send them).&lt;br /&gt;
&lt;br /&gt;
==TAB==&lt;br /&gt;
Each PCK file is again accompanied by a TAB file. The TAB file contains a 32bit integer (4 bytes, little endian) per image. This value needs to be multipled by 4 to get the file offset in the PCK of the image header.&lt;br /&gt;
&lt;br /&gt;
==Image Header==&lt;br /&gt;
The first twelve bytes of each image in the PCK are a header:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression mode. If 0, stop reading, there&#039;s no image to load and even the header won&#039;t be complete.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1-3&lt;br /&gt;
!0x01-0x03&lt;br /&gt;
|Unknown, usually blank (unless the compression mode is 128).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Left-most pixel within the sprite. No data should be rendered further left of this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Right-most pixel within the sprite. No data should be rendered at this point or further.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8-9&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Top-most pixel within the sprite. No data should be rendered higher above this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!10-11&lt;br /&gt;
!0x0A-0x0B&lt;br /&gt;
|Bottom-most pixel within the sprite. No data should be rendered at this point or lower.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Width = Right-Most pixel - Left-ost pixel&lt;br /&gt;
Height = Bottom-Most pixel - Top-Most pixel&lt;br /&gt;
&lt;br /&gt;
The image data then proceeds according to the compression mode used by the sprite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 0==&lt;br /&gt;
No image, don&#039;t render anything.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 1==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Run-length_encoding RLE compression], but opaque pixels aren&#039;t compressed at all. The concept is fairly similar to that of the old PCK format (though it&#039;s been expanded out a bit). Keep reading &amp;amp; rendering records according to this pattern:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0-3&lt;br /&gt;
!0x00-0x03&lt;br /&gt;
|Amount of pixels to skip from co-ordinate (0, 0). If this is 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
You can calculate the Y co-ordinate for your row by taking the integer value of this divided by 640 (rounding down).&lt;br /&gt;
To make the Y co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Top-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Quick access to the X co-ordinate (so you don&#039;t have to calculate the modulus of the pixels to skip).&lt;br /&gt;
To make the X co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Left-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
!0x05&lt;br /&gt;
|The amount of pixels this record contains.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
!0x06&lt;br /&gt;
|Always 0 (Assuming &amp;quot;Left Padding&amp;quot;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!7&lt;br /&gt;
!0x07&lt;br /&gt;
|Right Padding. This is the number of pixels in the row you don&#039;t need to draw.&lt;br /&gt;
Pixels To Draw = (Amount Of Pixels) - (Right Padding)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8 ...&lt;br /&gt;
!0x08 ...&lt;br /&gt;
|From this point, read the amount of pixels specified by index 5 and render then left to right on the display. Palette Index 0 is transparent&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 2==&lt;br /&gt;
Uncommon, not entirely certain it&#039;s used at all...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 3==&lt;br /&gt;
I guess you could describe this as [http://en.wikipedia.org/wiki/LZ77_and_LZ78 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 &amp;amp; rendering records according to the below pattern.&lt;br /&gt;
&lt;br /&gt;
If a given record starts with 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|The amount of sub-records to render on this row.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Usually, this is 128 minus the amount of pixels drawn by the &#039;&#039;first&#039;&#039; sub-record rendered on the &#039;&#039;previous&#039;&#039; row. I&#039;m not strictly sure what this means or why it&#039;s there.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
!0x02&lt;br /&gt;
|&#039;&#039;Unknown&#039;&#039;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
!0x03&lt;br /&gt;
|The row this record is to be rendered on.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Sub-records. Read &amp;amp; render however many index 0 specified, on the current row:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|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).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Amount of pixels to render.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-4&lt;br /&gt;
!0x02-0x04&lt;br /&gt;
|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.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 128==&lt;br /&gt;
These files contain a transparent &#039;dither&#039; mask to render shadows etc.&lt;br /&gt;
NOTE - not all these files have the first byte as &#039;128&#039; - for example &#039;tacdata/aliens/alien/poppers.pck (popper shadows) is this format with the first two bytes as &#039;0x00 0x6e&#039;. Which files are in this format may be &#039;baked in&#039; to the executable, or it&#039;s a &#039;none of the above&#039; clause&lt;br /&gt;
&lt;br /&gt;
It starts with an 8 byte header&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression format header (Always seems to be either &#039;0x0&#039; or &#039;0x80&#039;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Unknown - multiple different values seen&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-3&lt;br /&gt;
!0x02-0x03&lt;br /&gt;
|Unknown - always seems to be zero?&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Width of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x06-0x07&lt;br /&gt;
|Height of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Following this are a number of 2-byte pairs implementing a RLE-like encoding, encoding pixels as a lookup into a 4 pixel wide lookup table of if each pixel is occluded or not&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Repeat count - the number of repeated 4-pixel units - if 0xFF (255) stop as you&#039;ve reached the end of the image&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Index into a 7-entry lookup table for 4-pixel values&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
NOTE: The stride of the images always seems to be 256 - IE each row contains 256 total pixel values (or 64 table indices), but only the width specified in the header are actually drawn.&lt;br /&gt;
&lt;br /&gt;
The lookup table looks like this:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Index&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Pixer value (0 = transparent, 1 = opaque)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
|0 0 0 0 (All transparent)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
|1 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
|0 1 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
|1 0 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
| 0 1 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
|0 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
|0 0 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=PCX=&lt;br /&gt;
There are a number of images in PCX format, these are standard and most graphic packages can read them&lt;br /&gt;
&lt;br /&gt;
=MOUSE.DAT=&lt;br /&gt;
This file contains 9 images with a resolution of 24 x 24 pixels, using 8bpp with a palette index&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Files]]&lt;br /&gt;
[[Category:Apocalypse]]&lt;/div&gt;</summary>
		<author><name>JonnyH</name></author>
	</entry>
	<entry>
		<id>https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=64093</id>
		<title>Image Formats (Apocalypse)</title>
		<link rel="alternate" type="text/html" href="https://temp.ufopaedia.org/index.php?title=Image_Formats_(Apocalypse)&amp;diff=64093"/>
		<updated>2015-04-21T00:11:19Z</updated>

		<summary type="html">&lt;p&gt;JonnyH: Add my analysis of &amp;#039;compression mode 128&amp;#039; images&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}Image file formats used by [[Apocalypse|X-COM: Apocalypse]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
=PCK=&lt;br /&gt;
An advancement on the version used by [[Image_Formats#PCK|the previous games]], which can now use a variety of different compression methods on different sprites within the same image archive.&lt;br /&gt;
&lt;br /&gt;
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 [[Megaspawn]]s aren&#039;t split up into multiple &amp;quot;tiles&amp;quot; like the large units in the previous games (such as the [[Cyberdisc]]s) - they nearly double the average sprite dimensions as a result).&lt;br /&gt;
&lt;br /&gt;
As before, the image data indexes into an palette consisting of 256 colours. There is a unique palette stored for every terrain, but they&#039;re mostly similar (after all, your units need to look the same regardless of where you send them).&lt;br /&gt;
&lt;br /&gt;
==TAB==&lt;br /&gt;
Each PCK file is again accompanied by a TAB file. The TAB file contains a 32bit integer (4 bytes, little endian) per image. This value needs to be multipled by 4 to get the file offset in the PCK of the image header.&lt;br /&gt;
&lt;br /&gt;
==Image Header==&lt;br /&gt;
The first twelve bytes of each image in the PCK are a header:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression mode. If 0, stop reading, there&#039;s no image to load and even the header won&#039;t be complete.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1-3&lt;br /&gt;
!0x01-0x03&lt;br /&gt;
|Unknown, usually blank (unless the compression mode is 128).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Left-most pixel within the sprite. No data should be rendered further left of this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Right-most pixel within the sprite. No data should be rendered at this point or further.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8-9&lt;br /&gt;
!0x08-0x09&lt;br /&gt;
|Top-most pixel within the sprite. No data should be rendered higher above this point.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!10-11&lt;br /&gt;
!0x0A-0x0B&lt;br /&gt;
|Bottom-most pixel within the sprite. No data should be rendered at this point or lower.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Width = Right-Most pixel - Left-ost pixel&lt;br /&gt;
Height = Bottom-Most pixel - Top-Most pixel&lt;br /&gt;
&lt;br /&gt;
The image data then proceeds according to the compression mode used by the sprite.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 0==&lt;br /&gt;
No image, don&#039;t render anything.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 1==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Run-length_encoding RLE compression], but opaque pixels aren&#039;t compressed at all. The concept is fairly similar to that of the old PCK format (though it&#039;s been expanded out a bit). Keep reading &amp;amp; rendering records according to this pattern:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0-3&lt;br /&gt;
!0x00-0x03&lt;br /&gt;
|Amount of pixels to skip from co-ordinate (0, 0). If this is 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
You can calculate the Y co-ordinate for your row by taking the integer value of this divided by 640 (rounding down).&lt;br /&gt;
To make the Y co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Top-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Quick access to the X co-ordinate (so you don&#039;t have to calculate the modulus of the pixels to skip).&lt;br /&gt;
To make the X co-ordinate relative to the individual sprite, you can subtract the &amp;quot;Left-Most pixel&amp;quot; from the header.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
!0x05&lt;br /&gt;
|The amount of pixels this record contains.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
!0x06&lt;br /&gt;
|Always 0 (Assuming &amp;quot;Left Padding&amp;quot;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!7&lt;br /&gt;
!0x07&lt;br /&gt;
|Right Padding. This is the number of pixels in the row you don&#039;t need to draw.&lt;br /&gt;
Pixels To Draw = (Amount Of Pixels) - (Right Padding)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!8 ...&lt;br /&gt;
!0x08 ...&lt;br /&gt;
|From this point, read the amount of pixels specified by index 5 and render then left to right on the display. Palette Index 0 is transparent&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 2==&lt;br /&gt;
Uncommon, not entirely certain it&#039;s used at all...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 3==&lt;br /&gt;
I guess you could describe this as [http://en.wikipedia.org/wiki/LZ77_and_LZ78 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 &amp;amp; rendering records according to the below pattern.&lt;br /&gt;
&lt;br /&gt;
If a given record starts with 0xFF FF FF FF, then stop rendering, you&#039;ve hit the end of the sprite.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|The amount of sub-records to render on this row.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Usually, this is 128 minus the amount of pixels drawn by the &#039;&#039;first&#039;&#039; sub-record rendered on the &#039;&#039;previous&#039;&#039; row. I&#039;m not strictly sure what this means or why it&#039;s there.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
!0x02&lt;br /&gt;
|&#039;&#039;Unknown&#039;&#039;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
!0x03&lt;br /&gt;
|The row this record is to be rendered on.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
!0x04&lt;br /&gt;
|Sub-records. Read &amp;amp; render however many index 0 specified, on the current row:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|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).&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Amount of pixels to render.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-4&lt;br /&gt;
!0x02-0x04&lt;br /&gt;
|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.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Compression mode: 128==&lt;br /&gt;
These files contain a transparent &#039;dither&#039; mask to render shadows etc.&lt;br /&gt;
NOTE - not all these files have the first byte as &#039;128&#039; - for example &#039;tacdata/aliens/alien/poppers.pck (popper shadows) is this format with the first two bytes as &#039;0x00 0x6e&#039;. Which files are in this format may be &#039;baked in&#039; to the executable, or it&#039;s a &#039;none of the above&#039; clause&lt;br /&gt;
&lt;br /&gt;
It starts with an 8 byte header&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Compression format header (Always seems to be either &#039;0x0&#039; or &#039;0x80&#039;)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Unknown - multiple different values seen&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2-3&lt;br /&gt;
!0x02 - 0x03&lt;br /&gt;
|Unknown - always seems to be zero?&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4-5&lt;br /&gt;
!0x04-0x05&lt;br /&gt;
|Width of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6-7&lt;br /&gt;
!0x06-0x08&lt;br /&gt;
|Height of the sprite&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Following this are a number of 2-byte pairs implementing a RLE-like encoding, encoding pixels as a lookup into a 4 pixel wide lookup table of if each pixel is occluded or not&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Offset&amp;lt;br&amp;gt;(Hex)&lt;br /&gt;
!Usage&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
!0x00&lt;br /&gt;
|Repeat count - the number of repeated 4-pixel units - if 0xFF (255) stop as you&#039;ve reached the end of the image&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
!0x01&lt;br /&gt;
|Index into a 7-entry lookup table for 4-pixel values&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
NOTE: The stride of the images always seems to be 256 - IE each row contains 256 total pixel values (or 64 table indices), but only the width specified in the header are actually drawn.&lt;br /&gt;
&lt;br /&gt;
The lookup table looks like this:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Index&amp;lt;br&amp;gt;(Decimal)&lt;br /&gt;
!Pixer value (0 = transparent, 1 = opaque)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!0&lt;br /&gt;
|0 0 0 0 (All transparent)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!1&lt;br /&gt;
|1 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!2&lt;br /&gt;
|0 1 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!3&lt;br /&gt;
|1 0 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!4&lt;br /&gt;
| 0 1 0 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!5&lt;br /&gt;
|0 0 1 0&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
!6&lt;br /&gt;
|0 0 0 1&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=PCX=&lt;br /&gt;
There are a number of images in PCX format, these are standard and most graphic packages can read them&lt;br /&gt;
&lt;br /&gt;
=MOUSE.DAT=&lt;br /&gt;
This file contains 9 images with a resolution of 24 x 24 pixels, using 8bpp with a palette index&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Files]]&lt;br /&gt;
[[Category:Apocalypse]]&lt;/div&gt;</summary>
		<author><name>JonnyH</name></author>
	</entry>
</feed>