Panic in the Park - The Interactive Game
Technical Analysis and Fan Page

Content for everyone

Technical stuff

Links

YouTube Videos

(German or English)

Analysis of the ART files of Panic in the Park and Waldo at the Circus

Please see my command line PACKER and UNPACKER written in C!

These tools can also pack/unpack ART files for Blown Away, Eraser Turnabout, Virtual K'Nex and Waldo Exploring Geography!

General structure

File structure

Possible values of PictureEntryHeader.paletteType

PictureEntryHeader.paletteType = 'X' (0x58)

The pictures contain a palette of the size 3x256 = 0x300 after PictureHeader.data

PictureEntryHeader.paletteType = 'C' (0x43)

The picture does not contain a palette.

These pictures are usually included into another picture, e.g. the glasses are included in the menu background; the glasses use the palette of the background.

Possible values of PictureHeader.compressionType

PictureHeader.compressionType = 'Q' (upper case, 0x51)

PictureHeader.data is compressed with exactly the same LZW variant which is used by the GIF standard, but the stream of LZW data is not partitioned into blocks, instead the stream is continuous. Please see the GIF specification for the difference between the GIF-LZW and the original LZW, since they are incompatible.

The adaptive palette is in the format RGB like in the GIF standard.

The decompressed stream is a top-down 8 bit bitmap. Each byte represents 1 pixel. The value is the zero based index in the colortable.

PictureHeader.compressionType = 'q' (lower case, 0x71)

PictureHeader.data is an uncompressed top-down 8bit bitmap.

Each byte represents 1 pixel. The value is the zero based index in the colortable.

In comparison to a Windows Bitmap, the lines and palette are not padded to 4 bytes.

The adaptive palette is RGB (24 bits) instead of BGR0 (32 bits) which is used by Microsoft Bitmap.

Transparency

The pictures do not have transparency information. However, 'Q' and 'q' pictures have transparency in the game. It seems as if the first color in the color table is used as transparent color (of course only if the game itself handles the picture as transparent)

Example: artfile_1_1.h

#define ART_COMPRESSIONTYPE_LZW 'Q'
#define ART_COMPRESSIONTYPE_NONE 'q'

#define ART_PALETTETYPE_ATTACHED 'X'

// Pictures with the type 'C' do not have a palette.
// They use the palette of their parent picture where they are embedded in
#define ART_PALETTETYPE_PARENT 'C'

#define ART_NAME_SIZE 23

#define ART_MAGIC_SEQ "Art"
#define ART_MAGIC_DUMMY '?'

#pragma pack(push, 1)

typedef struct tagFileHeader {
	char       magic[ART_NAME_SIZE]; // always "Art\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" (ignored by the game)
	char       dummy;                // always '?' (ignored by the game)
	uint32_t   numHeaderEntries;     // number of headers including this file header (number of follow-up PictureEntryHeader entries plus one)
	uint32_t   totalFileSize;        // total file size including this header (ignored by the game)
} FileHeader;

typedef struct tagPictureEntryHeader {
	char       name[ART_NAME_SIZE];  // zero terminated string. case sensitive
	char       paletteType;          // 'X' (0x58) = RGB palette attached
	                                 // 'C' (0x43) = no palette attached (for embedded picture, use palette of parent picture)
	uint32_t   offset;               // offset to the picture (PictureHeader)
	uint32_t   size;                 // size of the picture (PictureHeader + picture data + optional palette)
} PictureEntryHeader;

typedef struct tagPictureHeader {
	char     compressionType;        // Compression type of the follow-up data (top down pixel data; the palette won't be compressed)
	                                 // 'Q' (0x51, upper case) = LZW compression, more precisely:
	                                 //                          The LZW variant of the GIF specification,
	                                 //                          but without splitting the output data into chunks
	                                 // 'q' (0x71, lower case) = No compression
	uint16_t offsetX;                // Additional offsets for 'fine-tuning'
	uint16_t offsetY;
	uint16_t width;                  // width of the picture
	uint16_t height;                 // height of the picture
} PictureHeader;

typedef struct tagColorTableEntry {
	uint8_t r;
	uint8_t g;
	uint8_t b;
} ColorTableEntry;

typedef struct tagColorTable {
	ColorTableEntry colors[256];
} ColorTable;

#pragma pack(pop)

© 2024 Daniel Marschall - - www.daniel-marschall.de

Please also see my pages for other Imagination Pilots games:
Blown Away | Panic in the Park | Waldo at the Circus | Waldo Exploring Geography | Eraser Turnabout | Virtual K'Nex