Dangerous Dave Tileset Format
Apart from the interface graphics (menu, font, etc.) Dangerous Dave stores its graphics in three files in this format. The EGA graphics are stored externally in EGADAVE.DAV, while the CGA and VGA graphics are stored internally in DAVE.EXE.
These graphics in this format are the tiles and sprites, and most images used in-level. As Dangerous Dave is an early game, it does not always employ compression and uses a primitive method of storing the Raw EGA data in the file.
Both the CGA and VGA data (stored in the .exe) is compressed with a form of RLE. (This is not counting the LZEXE compression applied to the final .exe as a whole.) The compression applies to the entire file, headers and all. The EGA data (stored in EGADAVE.DAV) is not compressed.
The data is compressed using Keen 1-3 RLE compression.
It is important to note that no RLE compression code must run across a 65,280 (0xFF00) byte boundary, otherwise the game will not load the graphics correctly. For example the code 0B 00 ("repeat 0x00 14 times") might have to be changed to 02 00 06 00 ("repeat 0x00 five times, then repeat 0x00 nine times") if the 65,280 byte boundary occurs in the middle of the code. (In this case the boundary would be between the 02 00 code and the 06 00 code.)
It is unknown precisely why the boundary is at 65,280 bytes and not 65,536 bytes, considering that this split happens at the RLE level so it should not matter whether encoding is in the middle of a tile or not.
The file starts with the number of chunks (graphics) in the file, followed by a number of values giving the offset of each chunk.
|UINT32LE count||Number of images in the file|
|UINT32LE offsets[count]||Offset of image data|
|BYTE data||Image data|
There are two types of chunks, those that are 128 bytes in size are taken to be 16x16 tiles (by default the first 53 chunks are these) and consist entirely of raw graphics data. Other chunks start with two UINT16LE values giving the width and height of the graphic in pixels followed by the image data.
Due to a bug in the way the game loads and saves tilesets, be aware that there is an extra byte inserted every 65536 bytes. This extra byte is not counted in any file offsets. Failure to take this into account will cause the last 10 images in the VGA tileset to appear as though they are 2048 pixels wide instead of 8 pixels wide.
Image data is Linear CGA (like VGA but 2bpp instead of 8bpp.) In other words, it's not split up into planes like the EGA data is. The pixels are broken up in big-endian order within the byte, so this value:
Would translate as four pixels of the following values:
11 00 10 01 (3, 0, 2, 1)
The actual colours for each pixel depend on the active CGA palette, of which there are three basic ones. See wp:Color Graphics Adapter for details.
All EGA data is stored in the Row-planar EGA arrangement, meaning each graphic is split into rows which are then split into EGA planes.
All graphics have four planes, stored in the order I, R, G, B. Tiles are first, followed by player sprites, enemy sprites, in-level images and in-level font.
This is a very basic implementation of EGA data. The only masked sprite is the player sprite (the only sprite that needs to appear over colored tiles and other sprites - enemy sprites are drawn using XOR to avoid the mask, at the expense of causing colour changes should they ever overlap map tiles.) Masking is accomplished by storing the mask as a second, black and white image - that is, black and white EGA. The mask graphic is the same size, in pixels and bytes, as the sprite image it masks - a very wasteful way of doing things.
Dave is also interesting in that it contains graphics whose width does not divide evenly by eight pixels. As EGA data these are stored as if they divided by the next highest multiple of 8 pixels (a 26x8 image is stored like a 32x8 image, with the 'extra' space being blank.) This is standard for storing images padded to a certain byte width (e.g. .BMP images) however it is not often done in games due to the 'wasted' space.
The VGA data is standard 8bpp single-plane data. The palette is stored in the main EXE file (see Dangerous Dave for its location.)
This file format and the EGA + VGA graphics were reverse engineered by Levellass, and the RLE algorithm and CGA graphics were reverse engineered by Malvineous. 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!)