Contents

Technical Documentation - Dungeon Master II Graphics.dat: How to read and decompress images from the PC version

Author of this documentation: Kentaro.k-21
This is a binary dump of DM2 PC specific image to be described.

ADDRESS 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF
------------------------------------------------------------------------
0000000 0C 00 07 7C 00 00 03 00 BD 0A 22 00 27 2A 2A 27 ...|......".'**'
0000010 44 01 27 EF 2A 2D 2D 2A 44 01 2A 3B 3F CF 3F 3B D.'.*--*D.*;?.?;
0000020 2A 27 41 01 C0 02 2D 3B 9F 3F 2D 27 00 00 01 03 *'A...-;.?-'....
0000030 A0 01 2D 10 41 06 C3 01 A5 07 81 03 27 00 09 ..-.A.......'..

It is 1620th binary (0 based index) in DM2 PC GRAPHICS.DAT, and is the compressed image of Blue gem.

The DM2 PC specific compressed image has 8 bytes for prefix and sequent bytes for body of compressed image. It has no suffix.

Part Heading hexa binary
Prefix 0C 00 07 7C 00 00 03 00
Body BD 0A 22 00 27 2A 2A 27 44 01 27 EF 2A 2D 2D 2A 44...

The 4th byte in Prefix is highlighted. It may be used to know that this image is formatted in DM2 PC specific image.

Majority images has 4th byte fixed in 0x7C.

Body binary format

There are command control byte and sequent 8 primitives in a set.

Command control byte
If 1st bit is set in command control byte, here is a pixel(1 byte), otherwise here is repetition command(2 bytes)
If 2st bit is set in command control byte, here is a pixel(1 byte), otherwise here is repetition command(2 bytes)
If 3st bit is set in command control byte, here is a pixel(1 byte), otherwise here is repetition command(2 bytes)
If 4st bit is set in command control byte, here is a pixel(1 byte), otherwise here is repetition command(2 bytes)
If 5st bit is set in command control byte, here is a pixel(1 byte), otherwise here is repetition command(2 bytes)
If 6st bit is set in command control byte, here is a pixel(1 byte), otherwise here is repetition command(2 bytes)
If 7st bit is set in command control byte, here is a pixel(1 byte), otherwise here is repetition command(2 bytes)
If 8st bit is set in command control byte, here is a pixel(1 byte), otherwise here is repetition command(2 bytes)
Command control byte
...

* 1st bit means LSB in a byte. 8th bit means MSB in a byte.

Format of Pixel

A pixel is represented in 1 byte and is a 8-bit indexed palette in DM2.

It renders only 1 pixel per pixel command.

Format of Repetition Command

This command is to copy pixels from previous rendered pixels. It has 2 following scalar factors

- How far do you go back to fetch pixels (As negative-offset)
- How length do you copy (As length)

It is always consisted with 2 bytes.

First byte is variant against each image prefix. They will be grouped in 'Type'.

Type Format of 1st byte (from MSB to LSB)
Type 2 XXXXyyyy (leading 4 bits for X, sequent 4 bits for Y)
Type 3 XXXyyyyy (leading 3 bits for X, sequent 5 bits for Y)

X and Y are defined for expression.

Second byte is a unsigned byte value and defined as B for expression.

negative_offset and copy_length are figured out as next table shows.

Type Expression
Type 2 negative_offset = X + (16 * B)
copy_length = Y + 3
Type 3 negative_offset = X + (8 * B)
copy_length = Y + 3

* It is possible that source pixel range and destination pixel range between a repetition command are overlapped. It says (negative_offset < copy_length) is actually possible.

Decision of Type

This is prefix part of the image: 0C 00 07 7C 00 00 03 00

The 7th byte, the highlighted part shows the Type of decompression factor.

If it is 02, it is Type2 factor applied compressed image.
If it is 03, it is Type3 factor applied compressed image.

Decompression Example

Here is reading sample for the 1620th compressed image.

Decompression Example

This is Type3 factor applied compressed image.

Index in c.c.b. Binary Reading
BD Command control byte.bit array is 1011 1101
1st 0A Pixel 0A
2nd 22 00 Repetition command.
negative_offset is (1 + 8 * 0) = 1
copy_length is (3 + 2) = 5
Pixels are 0A 0A 0A 0A 0A
3rd 27 Pixel 27
4th 2A Pixel 2A
5th 2A Pixel 2A
6th 27 Pixel 27
7th 44 01 Repetition command.
negative_offset is (2 + 8 * 1) = 10
copy_length is (3 + 4) = 7
Pixels are 0A 0A 0A 0A 0A 0A 27
8th 27 Pixel 27
EF Command control byte.bit array is 1110 1111
1st 2A Pixel 2A
2nd 2D Pixel 2D
3rd 2D Pixel 2D
4th 2A Pixel 2A
5th 44 01 Repetition command.
negative_offset is (2 + 8 * 1) = 10
copy_length is (3 + 4) = 7
Pixels are 0A 0A 0A 0A 27 27 2A
6th 2A Pixel 2A
7th 3B Pixel 3B
8th 3F Pixel 3F
CF Command control byte.bit array is 1100 1111
1st 3F Pixel 3F
2nd 3B Pixel 3B
3rd 2A Pixel 2A
4th 27 Pixel 27
5th 41 01 Repetition command.
negative_offset is (2 + 8 * 1) = 10
copy_length is (3 + 1) = 4
Pixels are 27 27 2A 2A
6th C0 02 Repetition command.
negative_offset is (6 + 8 * 2) = 22
copy_length is (3 + 0) = 3
Pixels are 2A 2D 2D
7th 2D Pixel 2D
8th 3B Pixel 3B
9F Command control byte.bit array is 1001 1111
1st 3F Pixel 3F
2nd 2D Pixel 2D
3rd 27 Pixel 27
4th 00 Pixel 00
5th 00 Pixel 00
6th 01 03 Repetition command.
negative_offset is (0 + 8 * 3) = 24
copy_length is (3 + 1) = 4
Pixels are 27 27 2A 2A
7th A0 01 Repetition command.
negative_offset is (5 + 8 * 1) = 13
copy_length is (3 + 0) = 3
Pixels are 2D 2D 2D
8th 2D Pixel 2D
10 Command control byte.bit array is 0001 0000
1st 41 06 Repetition command.
negative_offset is (2 + 8 * 6) = 50
copy_length is (3 + 1) = 4
Pixels are 2A 27 0A 0A
2nd C3 01 Repetition command.
negative_offset is (6 + 8 * 1) = 14
copy_length is (3 + 3) = 6
Pixels are 00 00 27 27 2A 2A
3rd A5 07 Repetition command.
negative_offset is (5 + 8 * 7) = 61
copy_length is (3 + 5) = 8
Pixels are 2A 2A 27 0A 0A 0A 0A 0A
4th 81 03 Repetition command.
negative_offset is (4 + 8 * 3) = 28
copy_length is (3 + 1) = 4
Pixels are 00 00 27 27
5th 27 Pixel 27
6th 00 09 Repetition command.
negative_offset is (0 + 8 * 9) = 72
copy_length is (3 + 0) = 3
Pixels are 27 0A 0A