PAK Format (The Learning Company)

From ModdingWiki
Jump to navigation Jump to search
PAK Format (The Learning Company)
PAK Format (The Learning Company).png
Format typeTileset
HardwareEGA
Max tile count232-1
PaletteExternal
Tile names?No
Minimum tile size (pixels)2×1
Maximum tile size (pixels)126×65535
Plane count1
Plane arrangementLinear
Transparent pixels?Palette-based
Hitmap pixels?No
Metadata?X and Y offsets, some other unidentified data.
Supports sub-tilesets?No
Compressed tiles?Yes
Hidden data?Yes
Games

The PAK Format is the sprite format used in Treasure Mountain. It contains multiple 16-color sprites, along with some metadata used by the game.

File format

The file begins with the following structure:

Offset Data type Name Description
0x00 UINT32LE ImageCount Number of images in the file
0x04 UINT16LE Unknown1 Always 0x3E. Might be a fixed identifying value.
0x06 UINT16LE Unknown2 Always 0x3A. Might be a fixed identifying value.
0x08 UINT16LE[imageCount] offsets Array containing the offsets of all images.

The offsets array is an index of UINT16LE values, each one pointing to the next image, so it contains imageCount items. The values in the array must be multiplied by 16 to get the actual image offset. The offsets are relative to the start of the file. With this format, the file can address image offsets up to index 0xFFFF0, or 1048560 decimal. Roughly speaking, this means these files can be up to about a megabyte in size.

Since all offsets are multiples of 16, there is generally open space between the header and the actual image offsets, and between the data of the different images. This space is filled with 0xFF values as padding.

The image data starts after this header, at the next multiple of 16 bytes.

Since this format has an index, extra space could be left between the images to store hidden data.

Image chunk

The data at the given offset starts with a header of in the following format:

Offset Data type Name Description
0x00 UINT16LE Unknown0 Always 0x0000
0x02 UINT16LE Width Image width, in bytes
0x04 UINT16LE Height Image height in bytes
0x06 INT16LE X-origin X origin of image, in bytes.
0x08 INT16LE Y-origin Y origin of image
0x0A UINT16LE Unknown1 Seems to be bit flags; usually 0, 1, 4 or 8, but 5 is also used.
0x0C UINT16LE Unknown2 Possibly related to grouping animations together; clearing this caused animations to go out of sequence and use unrelated frames. Generally values around 120-150
0x0E UINT16LE Unknown3 Almost always identical to Unknown2.

This header is followed by the image data.

The exact usage of the X and Y origin seems to vary. On some sprites it is not used at all, and the values are just left as zero. On scenes like the game's title screen and the end-animation in the castle, it is used to position the sprite in the full screen frame. In a lot of cases, however, one or both of the values are negative, meaning they move the frame up and to the left from the position at which the game is told to draw it. This seems to indicate that the game keeps track of objects by their center position, and these offsets in the sprite data handle the correct positioning relative to that point.

Image data

This image data behind the image header is saved per line. Each line starts with a byte that contains the information on how to read the line. If the byte has its upper bit enabled (meaning, it is larger than 0x80), the data that follows are simply bytes of image data to copy straight into the image. If the upper bit is disabled, the following data are length/value pairs to perform an RLE decompression operation.

The remainder of the first byte, with the highest bit cut off (or, 0x80 subtracted from it), indicates how many bytes long the data for that one line is. Both types should always result in a completely filled line.

For example, a byte 0x08 indicates that the following data are 8 bytes of length/value pairs, meaning, four pairs, before the next line's data starts. A byte 0xA2 would indicate a line that is copied without repeat commands, and the length of the line is 0x22, or decimal 34.

The resulting image data is in 4bpp linear format, big endian packed, meaning values 0x12 0x34 would represent four pixels, left to right, of colour values 1, 2, 3 and 4. The colour value 0 is treated as transparent pixels by the game.

Format notes and quirks

  • The width and height of the image can't be 0. Either of these will result in immediate graphical corruption in-game.
  • There are some easy checks that can be done to see whether the lines are in the correct format: if a repeat is not used, the line length should always match the width value in the image header, and if repeats are used, the following values are always pairs of bytes, so the line length should always be an even number.
  • Normally, lines of data always exactly fill an entire line. If the line overflows, the game seems to only paint the correct amount, but this is no guarantee that the overflow does not cause any corruption in memory. If the line is not completely filled, the remainder is filled up with random junk, as is typical for an uncleared buffer.
  • As a side effect of the fact the line length is saved in a single byte without the highest bit, the maximum width of the images is technically 0x7F, or 127 bytes, meaning, 254 pixels long. Anything more than that can not be stored in a copy-command, so the only way it could exist is as a compressed line, if that would take 126 bytes or less.
  • In the original game files, the compression is only used if the line data is at least two bytes smaller when compressed.

Image Colour Palette

The image colour palette is the following

Colour Name RGB
0 blue #0000AA
1 bright blue #5555FF
2 brown #AA5500
3 bright red #FF5555
4 red #AA0000
5 magenta #AA00AA
6 bright magenta #FF55FF
7 cyan #00AAAA
8 green #00AA00
9 bright green #55FF55
10 bright cyan #55FFFF
11 yellow #FFFF55
12 white #FFFFFF
13 light gray #AAAAAA
14 dark gray #555555
15 black #000000

Tools

The following tools are able to work with files in this format.

Name PlatformView images in this format? Convert/export to another file/format? Import from another file/format? Access hidden data? Edit metadata? Notes
Engie File Converter WindowsYesYesYesN/AN/A Opening a .pak file and bringing up its save menu allows getting the metadata needed to re-save edited frames to the format.

Credits

This file format was reverse engineered by Malvineous, with research into the compression done by Trogdor and Nyerguds. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)