Each DGN file fully describes a level of the dungeon.
The entrance of the dungeon shown during the title sequence is stored in LEV00.DGN (not playable). The automap for this level (SMAP00.BIN) is in fact an unused duplicate of the automap for LEV02.
The other DGN files (LEV01.DGN to LEV15.DGN) are the actual dungeon levels. LEV1.DGN is the hall of champions where the game starts.
The files are structured in 800h = 2048 bytes blocks.
There is one block for the header followed by 3 structures of variable size.
In the header, the offsets and sizes of the 3 structures are not specified in bytes but in numbers of blocks.
At the end of each structure, 00h bytes are padded until the next 2048 bytes block boundary. A DGN file looks like:
Offset Description 0000 byte 01 0001 byte Level number 0002 01 24 01 01 01 00 00 00 00 00 000C word Offset of Structure1 (in number of 800h blocks) 000E word Size of Structure1 (in number of 800h blocks) 0010 dword Size of Structure1 useful data in bytes (without the padding bytes) 0014 word Offset of Structure2 (in number of 800h blocks) 0016 word Size of Structure2 (in number of 800h blocks) 0018 dword Size of Structure2 useful data in bytes (without the padding bytes) 001C word Offset of Structure3 (in number of 800h blocks) 001E word Size of Structure3 (in number of 800h blocks) 0020 dword Size of Structure3 useful data in bytes (without the padding bytes) 0024 Padding until end of 2048 bytes block
Offset Description 0000 00 50 40 40 00 00 00 00 0008 dword Unknown 000C dword Number of entries in Structure1A 0010 dword Offset of Structure1A 00000038h 0014 dword Offset of Structure1B. Structure 1B is always 8000h bytes. 0018 dword Offset of Structure1C (= Offset of Structure1B + 8000h) 001C dword Offset of Structure1G May be 00000000h in which case there is no Structure1G 0020 dword 00000000h 0024 dword Offset of Structure1D 0028 dword 00000000h 002C dword 00000000h 0030 dword Offset of Structure1E 0034 dword Offset of Structure1F 0038 Structure1A 24 bytes entries. The number of entries is specified in the Structure1 header xxxx Structure1B Size is always 8000h = 32768 bytes This represents the level map as a grid of 64x64 cells with 8 bytes per cell. Note: The current version of the script decodes this data as an image to visualize the data. Resize the produced images from 512x64 pixels to 64x64 pixels with any image editor. The result for LEV1.DGN clearly looks like the map of the hall of champions (remember there are 2 hidden areas that do not appear on the automap). xxxx Structure1C 0000 byte Number of dwords + 1. For example, 15h = 21 means there are 20 dwords. 0001 00 00 00 0004 dwords. The number of dwords is specified above. xxxx Structure1D 0000 128 bytes with value 00h xxxx Structure1E 16 bytes entries First byte of last entry is FFh xxxx Structure1F 0000 word Unknown1 0004 word Unknown2 0008 word Number of entries in Structure1Fa 000C word Number of entries in Structure1Fb 0010 word Number of entries in Structure1Fc 0014 word Number of entries in Structure1Fd 0018 word Number of entries in Structure1Fe 001C word Number of entries in Structure1Ff 0020 Structure1Fa. 8 bytes per entry These entries define items present in the dungeon. 0000 byte Always 10h 0001 byte X Coordinate in 64x64 grid 0002 byte Y Coordinate in 64x64 grid 0003 byte Location on tile 0: North West 1: North East 2: South East 3: South West 4: Center 0004 byte Item number (see ITEM.IBS for item descriptors) 0005 byte Item attribute1. Set for some magic items. 0006 byte Always 00h 0007 byte Item attribute2. Charges. In LEV1.DGN, Item 42h (Torch) has Byte7=0F (charges) and item 9Eh (Waterskin) has Byte7 = 03 (full). xxxx Structure1Fb. 12 bytes per entry xxxx Structure1Fc. 16 bytes per entry May be creatures present in the dungeon. In LEV1.DGN, there are 4 Rock piles and 4 entries here. xxxx Structure1Fd. 12 bytes per entry xxxx Structure1Fe. 12 bytes per entry xxxx Structure1Ff. 16 bytes per entry xxxx Structure1G Note: some DGN files do not have any data in this section. In that case, the offset of Structure1G is set to 0 in the Structure1 header. Structure1G has the same format as the last part of ITEM.IBS. This is animation data declaring sequences of textures. For example, in LEV01.DGN there is only one animation declared which is probably used for the flame over the face of the character talking at the entrance of the dungeon. Sample from LEV15.DGN 00 09 Number of entries in first part, including last entry marker. 9 entries of 8 bytes each. Last entry starts with FFh 00 4C Offset of second part = Number of entries in part 1 * 8 + 4 (this header) = 76 First part - Entries declarations, 8 bytes each word2: ID (also found in second part as first word of each entry data) word3: index of first dword of the record in the second part 00 00 00 01 01 56 00 00 01 00 00 01 01 53 00 04 02 00 00 01 01 58 00 08 08 00 00 01 01 5B 00 0C 09 00 00 01 01 5D 00 10 0A 00 00 01 01 62 00 14 0B 00 00 01 01 65 00 19 0C 00 00 01 01 66 00 1E FF 00 00 00 00 00 00 00 Second part - Entries data 01 56 80 06 01 57 80 06 FF FE FF FE FF FF 00 00 8 other sets of bytes (Nb entries - 1) 01 53 80 04 01 58 80 04 FF FE FF FE FF FF 00 00 01 58 80 04 01 53 80 04 FF FE FF FE FF FF 00 00 01 5B C0 06 01 5C C0 06 FF FE FF FE FF FF 40 00 01 5D 80 06 01 5E 80 06 FF FE FF FE FF FF 00 00 01 62 C0 08 01 61 C0 08 01 60 C0 08 FF FE FF FD FF FF 40 00 01 65 C0 08 01 64 C0 08 01 63 C0 08 FF FE FF FD FF FF 40 00 01 66 C0 06 01 67 C0 06 01 68 C0 06 FF FE FF FD FF FF 40 00
Structure2 contains a list of texture descriptors. 20 bytes per texture descriptor. These descriptors use the same format as the ones used in ITEM.IBS to declare item on floor images.
The last descriptor in the list starts with FFFFh and does not declare a texture itself.
After the texture descriptors is raw data containing color palettes and images. The offsets of each palette and image are defined in the descriptors. These offsets are relative to the start of Structure2.
A texture descriptor has the following format:
Offset Description 0000 word Image ID 0002 word Color Mode. Values 0008h and 0028h are found. 0008h for 4 bits. 0028h for 16 bits (1BBBBBGG GGGRRRRR). 0004 word Palette ID. The meaning of this value depends on the value of the last dword in the texture descriptor which is the Palette offset: If Palette offset <> 0, associates this ID with the palette at speficied offset If Palette offset = 0, refers to a previously associated Palette ID 0006 word Image width 0008 word Image height 000A word Unknown. 000C dword Image offset 0010 dword Palette offset
In the raw data following the descriptors, color palettes have 16 colors (32 bytes per palette).
Images are stored in 4 bits per pixel. The first pixel is stored in the 4 most significant bits. Pixels are stored from left to right and then top to bottom.
Offset Description 0000 dword Number of entries 0004 Offsets (based on offset of Structure3). One offset (a dword) for each entry xxxx Entry data one after the other
Format of a Structure3 entry:
Each entry has a header of 40 bytes following by three structures
Offset Description 0000 dword Unknown. Flags ? Often 00000100h 0004 word Number of 12 bytes entries in Structure3a 0006 word Number of 12 bytes entries in Structure3b & Structure3c 0008 dword offset of structure 3a based on offset of Structure3 000C dword Always 0 0010 dword offset of structure 3b based on offset of Structure3 0014 dword offset of structure 3c based on offset of Structure3 0018 dword Often 0 but not always 001C dword Always 0 0020 dword Always 0 0024 dword Always 0 xxxx Structure3a. List of vertices. 12 bytes per vertex. A vertex: 0000 dword X coordinate (signed int32) 0004 dword Y coordinate (signed int32) 0008 dword Z coordinate (signed int32) xxxx Structure3b. List of faces. 12 bytes per face. A face: 0000 word Index of 1st Vertex (in associated Structure3a) 0002 word Index of 2nd Vertex 0004 word Index of 3rd Vertex 0006 word Index of 4th Vertex (If 3rd=4th face is a Triangle, otherwise face is a Quad) 0008 word Unknown 000A word Misc: 0x8000=Texture-flip-y, 0x4000=flip-x, LOBYTE=TextureIndex xxxx Structure3c. List of face normal vectors? 12 bytes per face One entry per face. Unknown content.