<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://moddingwiki.shikadi.net/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=VKokielov</id>
	<title>ModdingWiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://moddingwiki.shikadi.net/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=VKokielov"/>
	<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/wiki/Special:Contributions/VKokielov"/>
	<updated>2026-09-21T00:37:17Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.11</generator>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=GameMaps_Format&amp;diff=12037</id>
		<title>GameMaps Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=GameMaps_Format&amp;diff=12037"/>
		<updated>2024-10-22T00:14:25Z</updated>

		<summary type="html">&lt;p&gt;VKokielov: removed misinformation -- I forgot to add pragma pack() to my struct declarations&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 3&lt;br /&gt;
 | Viewport = &#039;&#039;Varies by game&#039;&#039;&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Bio Menace}}&lt;br /&gt;
   {{Game|Blake Stone}}&lt;br /&gt;
   {{Game|Catacomb 3-D}}&lt;br /&gt;
   {{Game|Catacomb Abyss}}&lt;br /&gt;
   {{Game|Commander Keen Dreams}}&lt;br /&gt;
   {{Game|Commander Keen 4-6}}&lt;br /&gt;
   {{Game|Corridor 7 Alien Invasion}}&lt;br /&gt;
   {{Game|Dangerous Dave 3}}&lt;br /&gt;
   {{Game|Dangerous Dave 4}}&lt;br /&gt;
   {{Game|Super 3-D Noah&#039;s Ark}}&lt;br /&gt;
   {{Game|Operation Body Count}}&lt;br /&gt;
   {{Game|Rescue Rover 2}}&lt;br /&gt;
   {{Game|Spear of Destiny}}&lt;br /&gt;
   {{Game|Wolfenstein 3-D}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;GameMaps Format&#039;&#039;&#039; stores levels in a number of [[:Category:id Software|id Software]] games. The filenames and compression varies somewhat across different games but all files stored in this format were produced by the [[TED5]] level editor.&lt;br /&gt;
&lt;br /&gt;
There are three main varieties of the file format. The most basic version is just [[RLEW compression|RLEW compressed]], the other two are either [[Carmack compression|carmackized]] or [[Huffman Compression|Huffman compressed]] on top of the RLEW compression. Each variation has its own file naming scheme and pattern of external/internal files.&lt;br /&gt;
&lt;br /&gt;
There are two main components to the format.  The game maps proper, which contain the actual level data, and the map headers, which contain both the location of each level&#039;s data within the game maps file, and the tile info for the game.&lt;br /&gt;
&lt;br /&gt;
== Variants ==&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Game !! RLEW !! Carmackization !! Huffman !! Head || Gamemaps || Notes&lt;br /&gt;
|-&lt;br /&gt;
| Bio Menace || Yes || No || No || maphead.bm[123] || maptemp.bm[123] || gamemaps.bm[123] and mapthead.bm[123] are present but not used&lt;br /&gt;
|-&lt;br /&gt;
| Blake Stone: Aliens of Gold || Yes || No || No || maphead.bs[16] || maptemp.bs[16] ||&lt;br /&gt;
|-&lt;br /&gt;
| Blake Stone: Planet Strike || Yes || No || No || maphead.vsi || maptemp.vsi ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb 3-D || Yes || Yes || No || Inside .exe || gamemaps.c3d ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb Abyss || Yes || Yes || No || Inside .exe || gamemaps.abs ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb Apocalypse || Yes || Yes || No || Inside .exe || gamemaps.apc ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb Armageddon || Yes || Yes || No || Inside .exe || gamemaps.arm ||&lt;br /&gt;
|-&lt;br /&gt;
| Commander Keen Dreams || Yes || No || Yes || Inside .exe || gamemaps.kdr (v1.00),&amp;lt;br&amp;gt;kdreams.map (v1.01+) ||&lt;br /&gt;
|-&lt;br /&gt;
| Commander Keen 4-6 || Yes || Yes || No || Inside .exe || gamemaps.ck[456] ||&lt;br /&gt;
|-&lt;br /&gt;
| Corridor 7 Alien Invasion || Yes || No || No || Inside .exe (cd, disk),&amp;lt;br&amp;gt;maphead.dmo (demo) || maptemp.co7 (cd, disk),&amp;lt;br&amp;gt;maptemp.dmo (demo) || Uses MAPTEMP.xxx (only RLEW compression)&lt;br /&gt;
|-&lt;br /&gt;
| Dangerous Dave 3 || Yes || No || Yes || Inside .exe || gamemaps.dav ||&lt;br /&gt;
|-&lt;br /&gt;
| Dangerous Dave 4 || Yes || No || Yes || Inside .exe || gamemaps.dav ||&lt;br /&gt;
|-&lt;br /&gt;
| Super 3-D Noah&#039;s Ark || Yes || Yes || No || maphead.n3d || gamemaps.n3d ||&lt;br /&gt;
|-&lt;br /&gt;
| Operation Body Count || Yes || No || No || maphead.bc (cd, disk, demo 2),&amp;lt;br&amp;gt;maphead.co7 (demo 1) || maptemp.bc (cd, disk, demo 2),&amp;lt;br&amp;gt;maptemp.co7 (demo 1) || Uses MAPTEMP.xxx (only RLEW compression)&lt;br /&gt;
|-&lt;br /&gt;
| Rescue Rover 2 || Yes || Yes || No || Inside .exe || gamemaps.rr2 ||&lt;br /&gt;
|-&lt;br /&gt;
| Spear of Destiny || Yes || Yes || No || maphead.sod || gamemaps.sod ||&lt;br /&gt;
|-&lt;br /&gt;
| Wolfenstein 3-D (v1.0) || Yes || No || No || maphead.wl1 || maptemp.wl1 ||&lt;br /&gt;
|-&lt;br /&gt;
| Wolfenstein 3-D (v1.1 and above)|| Yes || Yes || No || maphead.wl[16] || gamemaps.wl[16] ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The games that use Huffman compression will have a MAPDICT (embedded in the game&#039;s main executable).  Those missing the map dictionary are not Huffman encoded.&lt;br /&gt;
&lt;br /&gt;
To work out whether Carmackization is used, read the first UINT16LE in a map plane (the field storing the decompressed size).  If the value matches the expected size of the plane (i.e. width * height * 2), then only RLEW compression is used.  If it doesn&#039;t match, check the second UINT16LE in the file (which will become the first UINT16LE once Carmackization has been removed).  If this matches the expected plane size then the plane must first have Carmackization removed followed by removal of RLEW. The exception to this rule are plane sizes that have either 0xA7 or 0xA8 as the high byte (i.e. any value from 0xA700 to 0xA8FF), as those values would have been encoded differently by the [[Carmack compression]] algorithm.&lt;br /&gt;
&lt;br /&gt;
== Data structures==&lt;br /&gt;
&lt;br /&gt;
The map data is split into two files: The map header (&amp;lt;tt&amp;gt;MAPHEAD.xxx&amp;lt;/tt&amp;gt;) and the main map file (usually &amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt;). The map header may be embedded in the game&#039;s main executable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; is the working format saved by [[TED5]] when maps are being edited and can be directly accessed and edited by this utility, allowing changes to be made to the game. Note that if the MAPHEAD file exists as an external file, the game always reads it from a file named named &amp;lt;tt&amp;gt;MAPHEAD.xxx&amp;lt;/tt&amp;gt; for both the &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; variation. TED5 also saves a &amp;lt;tt&amp;gt;MAPTHEAD.xx&amp;lt;/tt&amp;gt; file when editing maps, but that file is only used by TED5 and usually omitted from any game release.&lt;br /&gt;
&lt;br /&gt;
The maps were often compressed even further for the public release versions of the games. This more compressed version of the map file was saved as &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt; by TED5. Later releases would omit the additional compression layer and ship with the &amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; file instead. One possible reason for this could be that the size of the games grew to the point where they would no longer fit onto and be playable from a single floppy disk, and therefore the additional compression was no longer worth the amount of time it took to compress the maps and re-compile the code.&lt;br /&gt;
&lt;br /&gt;
=== Map headers (MAPHEAD) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || [[UINT16LE]] || magic || Magic word signalling [[RLEW compression]]&lt;br /&gt;
|-&lt;br /&gt;
| 2 || [[INT32LE]][100] || ptr || 100 pointers to start of level 0-99 data in the game maps file&lt;br /&gt;
|-&lt;br /&gt;
| 402 || {{TODO|Unknown}} || tileinfo || Optional tileinfo data&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The map header file (MAPHEAD) is of varying length and contains three main types of data.&lt;br /&gt;
&lt;br /&gt;
* The first is the magic word or flag used for RLEW compression, which is almost always $ABCD in the original files. It could be changed to any other value if necessary.&lt;br /&gt;
&lt;br /&gt;
* The second is 100 level pointers which give the location of the start of level data in the GAMEMAPS file, relative to the start of that file.  A value less than 1 indicates no level (generally 0, but occasionally -1 (0xFFFFFFFF) is used). Using -1 should be preferred over 0, as the pre-Wolf3D version of the engine will treat any negative value as &amp;quot;a non existant map&amp;quot; [sic!] and quit with an appropriate error message, while 0 will cause it to try reading a level header at offset 0 (where the &amp;quot;TED5v1.0&amp;quot; string is usually stored), which will cause all kinds of errors as there is clearly no valid level header at that offset.&lt;br /&gt;
&lt;br /&gt;
* The third is the tileinfo data, which contains tile properties for each tile used in level creation. (These are masked and unmasked and either 8x8, 16x16 or 32x32.)&lt;br /&gt;
&lt;br /&gt;
Many programs treat the tileinfo as a separate file from the MAPHEAD and it is possible to modify a game in this manner.  Indeed, some games such as Wolfenstein 3-D do not have any tileinfo data at all in the map header file (giving a total file length of 402 bytes.) However TED5 works with any tileinfo data in the MAPHEAD.&lt;br /&gt;
&lt;br /&gt;
=== Map data (GAMEMAPS) ===&lt;br /&gt;
&lt;br /&gt;
The GAMEMAPS file consists of the string &amp;quot;TED5v1.0&amp;quot; and a number of compressed chunks of varying length.  Each level in the file will have from two to four chunks (usually four) depending on the game, with all levels in a given game having the same number of chunks.  These are the level header and 1-3 planes (foreground, background and sprite/info.)  The chunks are in no particular order and it is possible to read through the entire file decompressing chunks as they&#039;re found.&lt;br /&gt;
&lt;br /&gt;
Chunks are ordered by the MAPHEAD file, which will point to the GAMEMAPS level header chunks which in turn contain pointers to the other GAMEMAPS chunks used by that level.&lt;br /&gt;
&lt;br /&gt;
All level data is in the form of [[UINT16LE]] values (or in the case of pointers, [[UINT32LE]].)&lt;br /&gt;
&lt;br /&gt;
==== Level headers ====&lt;br /&gt;
&lt;br /&gt;
The header for each level inside the GAMEMAPS file (which is pointed to by MAPHEAD) is 38 bytes long and &#039;&#039;never&#039;&#039; RLEW compressed.  If the GAMEMAPS file is using Huffman compression, the level header itself is Huffman-compressed.  In that case, the size of the compressed level header can be found in the MAPHEAD file.  Since the uncompressed level header always has a size of 38 bytes, that size is not stored at the beginning of the compressed data.  The header is sometimes followed by a signature &amp;quot;!ID!&amp;quot; string, which would give the header a total size of 42 bytes, but that string is not part of the actual level header.&lt;br /&gt;
&lt;br /&gt;
The expanded size of each map plane is the size of a word ([[UINT16LE]]) times the width times the height.  This is the final, expected size and can be precomputed even if there are two layers of compression.&lt;br /&gt;
&lt;br /&gt;
Plane 0 is background using unmasked tiles, plane 1 is foreground and uses masked tiles, and plane 2 is sprite/info.  Levels must contain a background plane and usually an infoplane.&lt;br /&gt;
&lt;br /&gt;
For the compressed size of each level plane, a value of 0 indicates the plane does not exist. The offset value for unused planes appears to be set to a random number with the most significant byte set to 0xFF, making it either a negative number or an offset close to the 4 gigabyte range. The games only check the compressed size and ignore the offset if the size is 0.&lt;br /&gt;
&lt;br /&gt;
Note that Wolf3D is hard-coded to always load the first two planes, even if the compressed size of a plane is 0. Wolf3D also ignores the width and height stored in the level header and just assumes the level is 64x64 tiles. This also applies to Blake Stone and probably any other game based on the Wolf3D code.&lt;br /&gt;
&lt;br /&gt;
All versions of the &amp;quot;Id Software Caching Manager&amp;quot; ignore the expanded size value at the beginning of the RLEW data and just assume that the size is the same as the size of the plane (width * height * 2).&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || [[INT32LE]] || offPlane0 || Offset in GAMEMAPS to beginning of compressed plane 0 data (or &amp;lt;= 0 if plane is not present)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || INT32LE || offPlane1 || Offset in GAMEMAPS to beginning of compressed plane 1 data (or &amp;lt;= 0 if plane is not present)&lt;br /&gt;
|-&lt;br /&gt;
| 8 || INT32LE || offPlane2 || Offset in GAMEMAPS to beginning of compressed plane 2 data (or &amp;lt;= 0 if plane is not present)&lt;br /&gt;
|-&lt;br /&gt;
| 12 || UINT16LE || lenPlane0 || Length of compressed plane 0 data (in bytes)&lt;br /&gt;
|-&lt;br /&gt;
| 14 || UINT16LE || lenPlane1 || Length of compressed plane 1 data (in bytes)&lt;br /&gt;
|-&lt;br /&gt;
| 16 || UINT16LE || lenPlane2 || Length of compressed plane 2 data (in bytes)&lt;br /&gt;
|-&lt;br /&gt;
| 18 || UINT16LE || width || Width of level (in tiles)&lt;br /&gt;
|-&lt;br /&gt;
| 20 || UINT16LE || height || Height of level (in tiles)&lt;br /&gt;
|-&lt;br /&gt;
| 22 || char[16] || name || Internal name for level (used only by editor, not displayed in-game. null-terminated)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that for Wolfenstein 3D, a 4-byte signature string (&amp;quot;!ID!&amp;quot;) will normally be present directly after the level name. The signature does not appear to be used anywhere, but is useful for distinguishing between v1.0 files (the signature string is missing), and files for v1.1 and later (includes the signature string).&lt;br /&gt;
&lt;br /&gt;
== Carmack compression ==&lt;br /&gt;
&lt;br /&gt;
[[Carmack compression]] is the method used to compress later &#039;&#039;id Software&#039;&#039; games, when file size was still a concern.  It is the most efficient and complex compression method and was created specifically to work with the 16-bit word structure of the GameMaps file.  The compression is detailed on its [[Carmack compression|own page.]]&lt;br /&gt;
&lt;br /&gt;
Carmackized game maps files are external &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt; files and the map header is usually (but not always) stored internally in the executable.  The map header must be extracted and the game maps decompressed before TED5 can access them.  TED5 itself can produce carmackized files and external &amp;lt;tt&amp;gt;MAPHEAD.xxx&amp;lt;/tt&amp;gt; files. Carmackization does not replace the RLEW compression used in uncompressed data, but compresses this data, that is, the data is doubly compressed.&lt;br /&gt;
&lt;br /&gt;
Note that for Wolfenstein 3D v1.0, map files are not carmackized, only RLEW compression is applied.&lt;br /&gt;
&lt;br /&gt;
== Huffman compression ==&lt;br /&gt;
&lt;br /&gt;
[[Huffman Compression]] was probably used by earlier versions of TED5 (but possibly not TED5 at all) before carmackization was introduced.  It uses the same method to compress its data as is used by &#039;&#039;id Software&#039;&#039; games to compress their graphics and sounds.  Again this compression method works with RLEW compressed data and has its [[Huffman Compression|own page.]]&lt;br /&gt;
&lt;br /&gt;
Huffman compression is easily detected since it works on the bit level and thus disrupts the word structure of the game data.  This is easily seen in a hex editor.  Compressed data will not contain the string $00 $00 or indeed even $00 very often. (In contrast, even carmackized data contains both strings hundreds of times.)&lt;br /&gt;
&lt;br /&gt;
There will be two internal files for this format: the map header and the Huffman dictionary (which is always the first dictionary in the executable.)  The map header format is also slightly different, being 502 bytes long, the extra 100 bytes being the length of the compressed level headers in the game maps data, which occur immediately after the normal level header offsets and before the tileinfo. Each entry is one octet indicating the decompressed header length in bytes or zero if the level does not exist. (These can be ignored when decompressing since Huffman data can be read until the decompressed level header&#039;s fixed size is reached, but if they are omitted when writing the MAPHEAD, the game may experience a buffer overflow when reading the maps.)&lt;br /&gt;
&lt;br /&gt;
== Location of internal files ==&lt;br /&gt;
&lt;br /&gt;
The GAMEMAPS file itself is always external, but in the case of compression, the MAPHEAD is stored internally in the main .exe file.  Executables are themselves compressed with either with LZEXE or PKLite.  Once the .exe has been decompressed it is a trivial task to find the MAPHEAD as it will start with the UINT16LE value $ABCD (i.e. the byte $CD followed by the byte $AB.)  For level editing purposes only the first 402 (or 502) bytes of the file need to be extracted, though it is possible to read the MAPHEAD file to calculate its length.&lt;br /&gt;
&lt;br /&gt;
The following table lists the offsets of the MAPHEAD file for various games, relative to the start of the decompressed game .exe file.&lt;br /&gt;
&lt;br /&gt;
{{TODO|TODO: Add all known versions of all games}}&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Game !! Version !! Location !! Filename !! Offset !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| [[Bio Menace]] || Freeware || External || &amp;lt;tt&amp;gt;MAPHEAD.BM[123]&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=2| [[Blake Stone]]: Aliens of Gold || Shareware || External || &amp;lt;tt&amp;gt;MAPHEAD.BS1&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| Registered|| External || &amp;lt;tt&amp;gt;MAPHEAD.BS6&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Blake Stone]] 2: Planet Strike || All || External || &amp;lt;tt&amp;gt;MAPHEAD.VSI&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb 3-D]] (3) || 1.00 || Internal || &amp;lt;tt&amp;gt;CAT3D.EXE&amp;lt;/tt&amp;gt; || $1C570 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb Abyss]] (4) || 1.13 || Internal || &amp;lt;tt&amp;gt;CATABYSS.EXE&amp;lt;/tt&amp;gt; || $1C510 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb Armageddon]] (5) || 1.01a || Internal || &amp;lt;tt&amp;gt;CATARMA.EXE&amp;lt;/tt&amp;gt; || $1D900 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb Apocalypse]] (6) || 1.00b || Internal || &amp;lt;tt&amp;gt;CATAPOC.EXE&amp;lt;/tt&amp;gt; || $1DD50 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=3| [[Corridor 7 Alien Invasion]] || Demo || External || &amp;lt;tt&amp;gt;MAPHEAD.DMO&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
|| CD || Internal || &amp;lt;tt&amp;gt;CORR7CD.EXE&amp;lt;/tt&amp;gt; || $30D50 || File is not compressed&lt;br /&gt;
|-&lt;br /&gt;
| Floppy || Internal || &amp;lt;tt&amp;gt;C7.EXE&amp;lt;/tt&amp;gt; || $24BF0 || File is not compressed&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=2| [[Commander Keen 4-6|Keen 4]] || Special Demo || ? || ? || ? || File is PKLite compressed&lt;br /&gt;
|-&lt;br /&gt;
| 1.4 EGA || Internal || &amp;lt;tt&amp;gt;KEEN4E.EXE&amp;lt;/tt&amp;gt; || $24830 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Commander Keen 4-6|Keen 5]] || 1.4 EGA || Internal || &amp;lt;tt&amp;gt;KEEN5E.EXE&amp;lt;/tt&amp;gt; || $25990 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Commander Keen 4-6|Keen 6]] || 1.4 EGA || Internal || &amp;lt;tt&amp;gt;KEEN6.EXE&amp;lt;/tt&amp;gt; || $25080 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Commander Keen Dreams]] || 1.13 || Internal || ? || $1FA50 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Super 3-D Noah&#039;s Ark]] || All || External || &amp;lt;tt&amp;gt;maphead.n3d&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Operation Body Count]] || All || External || &amp;lt;tt&amp;gt;MAPHEAD.BC&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Spear of Destiny]] || All || External || &amp;lt;tt&amp;gt;MAPHEAD.SOD&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=2| [[Wolfenstein 3-D]] || Shareware || External || &amp;lt;tt&amp;gt;MAPHEAD.WL1&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| Registered || External || &amp;lt;tt&amp;gt;MAPHEAD.WL6&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Utilities ==&lt;br /&gt;
&lt;br /&gt;
* [[TED5]] can edit the &amp;lt;tt&amp;gt;GAMEMAPS&amp;lt;/tt&amp;gt; format of any games that use it.  It is the original editor used to create these files.&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
This file format was reverse engineered by Andrew Durdin (adurdin).  If you find this information helpful in a project you&#039;re working on, please give credit where credit is due.  (A link back to this wiki would be nice too!)&lt;/div&gt;</summary>
		<author><name>VKokielov</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=GameMaps_Format&amp;diff=12036</id>
		<title>GameMaps Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=GameMaps_Format&amp;diff=12036"/>
		<updated>2024-10-21T23:43:25Z</updated>

		<summary type="html">&lt;p&gt;VKokielov: important clarifying point for Wolf3d&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 3&lt;br /&gt;
 | Viewport = &#039;&#039;Varies by game&#039;&#039;&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Bio Menace}}&lt;br /&gt;
   {{Game|Blake Stone}}&lt;br /&gt;
   {{Game|Catacomb 3-D}}&lt;br /&gt;
   {{Game|Catacomb Abyss}}&lt;br /&gt;
   {{Game|Commander Keen Dreams}}&lt;br /&gt;
   {{Game|Commander Keen 4-6}}&lt;br /&gt;
   {{Game|Corridor 7 Alien Invasion}}&lt;br /&gt;
   {{Game|Dangerous Dave 3}}&lt;br /&gt;
   {{Game|Dangerous Dave 4}}&lt;br /&gt;
   {{Game|Super 3-D Noah&#039;s Ark}}&lt;br /&gt;
   {{Game|Operation Body Count}}&lt;br /&gt;
   {{Game|Rescue Rover 2}}&lt;br /&gt;
   {{Game|Spear of Destiny}}&lt;br /&gt;
   {{Game|Wolfenstein 3-D}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;GameMaps Format&#039;&#039;&#039; stores levels in a number of [[:Category:id Software|id Software]] games. The filenames and compression varies somewhat across different games but all files stored in this format were produced by the [[TED5]] level editor.&lt;br /&gt;
&lt;br /&gt;
There are three main varieties of the file format. The most basic version is just [[RLEW compression|RLEW compressed]], the other two are either [[Carmack compression|carmackized]] or [[Huffman Compression|Huffman compressed]] on top of the RLEW compression. Each variation has its own file naming scheme and pattern of external/internal files.&lt;br /&gt;
&lt;br /&gt;
There are two main components to the format.  The game maps proper, which contain the actual level data, and the map headers, which contain both the location of each level&#039;s data within the game maps file, and the tile info for the game.&lt;br /&gt;
&lt;br /&gt;
== Variants ==&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Game !! RLEW !! Carmackization !! Huffman !! Head || Gamemaps || Notes&lt;br /&gt;
|-&lt;br /&gt;
| Bio Menace || Yes || No || No || maphead.bm[123] || maptemp.bm[123] || gamemaps.bm[123] and mapthead.bm[123] are present but not used&lt;br /&gt;
|-&lt;br /&gt;
| Blake Stone: Aliens of Gold || Yes || No || No || maphead.bs[16] || maptemp.bs[16] ||&lt;br /&gt;
|-&lt;br /&gt;
| Blake Stone: Planet Strike || Yes || No || No || maphead.vsi || maptemp.vsi ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb 3-D || Yes || Yes || No || Inside .exe || gamemaps.c3d ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb Abyss || Yes || Yes || No || Inside .exe || gamemaps.abs ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb Apocalypse || Yes || Yes || No || Inside .exe || gamemaps.apc ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb Armageddon || Yes || Yes || No || Inside .exe || gamemaps.arm ||&lt;br /&gt;
|-&lt;br /&gt;
| Commander Keen Dreams || Yes || No || Yes || Inside .exe || gamemaps.kdr (v1.00),&amp;lt;br&amp;gt;kdreams.map (v1.01+) ||&lt;br /&gt;
|-&lt;br /&gt;
| Commander Keen 4-6 || Yes || Yes || No || Inside .exe || gamemaps.ck[456] ||&lt;br /&gt;
|-&lt;br /&gt;
| Corridor 7 Alien Invasion || Yes || No || No || Inside .exe (cd, disk),&amp;lt;br&amp;gt;maphead.dmo (demo) || maptemp.co7 (cd, disk),&amp;lt;br&amp;gt;maptemp.dmo (demo) || Uses MAPTEMP.xxx (only RLEW compression)&lt;br /&gt;
|-&lt;br /&gt;
| Dangerous Dave 3 || Yes || No || Yes || Inside .exe || gamemaps.dav ||&lt;br /&gt;
|-&lt;br /&gt;
| Dangerous Dave 4 || Yes || No || Yes || Inside .exe || gamemaps.dav ||&lt;br /&gt;
|-&lt;br /&gt;
| Super 3-D Noah&#039;s Ark || Yes || Yes || No || maphead.n3d || gamemaps.n3d ||&lt;br /&gt;
|-&lt;br /&gt;
| Operation Body Count || Yes || No || No || maphead.bc (cd, disk, demo 2),&amp;lt;br&amp;gt;maphead.co7 (demo 1) || maptemp.bc (cd, disk, demo 2),&amp;lt;br&amp;gt;maptemp.co7 (demo 1) || Uses MAPTEMP.xxx (only RLEW compression)&lt;br /&gt;
|-&lt;br /&gt;
| Rescue Rover 2 || Yes || Yes || No || Inside .exe || gamemaps.rr2 ||&lt;br /&gt;
|-&lt;br /&gt;
| Spear of Destiny || Yes || Yes || No || maphead.sod || gamemaps.sod ||&lt;br /&gt;
|-&lt;br /&gt;
| Wolfenstein 3-D (v1.0) || Yes || No || No || maphead.wl1 || maptemp.wl1 ||&lt;br /&gt;
|-&lt;br /&gt;
| Wolfenstein 3-D (v1.1 and above)|| Yes || Yes || No || maphead.wl[16] || gamemaps.wl[16] ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The games that use Huffman compression will have a MAPDICT (embedded in the game&#039;s main executable).  Those missing the map dictionary are not Huffman encoded.&lt;br /&gt;
&lt;br /&gt;
To work out whether Carmackization is used, read the first UINT16LE in a map plane (the field storing the decompressed size).  If the value matches the expected size of the plane (i.e. width * height * 2), then only RLEW compression is used.  If it doesn&#039;t match, check the second UINT16LE in the file (which will become the first UINT16LE once Carmackization has been removed).  If this matches the expected plane size then the plane must first have Carmackization removed followed by removal of RLEW. The exception to this rule are plane sizes that have either 0xA7 or 0xA8 as the high byte (i.e. any value from 0xA700 to 0xA8FF), as those values would have been encoded differently by the [[Carmack compression]] algorithm.&lt;br /&gt;
&lt;br /&gt;
== Data structures==&lt;br /&gt;
&lt;br /&gt;
The map data is split into two files: The map header (&amp;lt;tt&amp;gt;MAPHEAD.xxx&amp;lt;/tt&amp;gt;) and the main map file (usually &amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt;). The map header may be embedded in the game&#039;s main executable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; is the working format saved by [[TED5]] when maps are being edited and can be directly accessed and edited by this utility, allowing changes to be made to the game. Note that if the MAPHEAD file exists as an external file, the game always reads it from a file named named &amp;lt;tt&amp;gt;MAPHEAD.xxx&amp;lt;/tt&amp;gt; for both the &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; variation. TED5 also saves a &amp;lt;tt&amp;gt;MAPTHEAD.xx&amp;lt;/tt&amp;gt; file when editing maps, but that file is only used by TED5 and usually omitted from any game release.&lt;br /&gt;
&lt;br /&gt;
The maps were often compressed even further for the public release versions of the games. This more compressed version of the map file was saved as &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt; by TED5. Later releases would omit the additional compression layer and ship with the &amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; file instead. One possible reason for this could be that the size of the games grew to the point where they would no longer fit onto and be playable from a single floppy disk, and therefore the additional compression was no longer worth the amount of time it took to compress the maps and re-compile the code.&lt;br /&gt;
&lt;br /&gt;
=== Map headers (MAPHEAD) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || [[UINT16LE]] || magic || Magic word signalling [[RLEW compression]]&lt;br /&gt;
|-&lt;br /&gt;
| 2 || [[INT32LE]][100] || ptr || 100 pointers to start of level 0-99 data in the game maps file&lt;br /&gt;
|-&lt;br /&gt;
| 402 || {{TODO|Unknown}} || tileinfo || Optional tileinfo data&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The map header file (MAPHEAD) is of varying length and contains three main types of data.&lt;br /&gt;
&lt;br /&gt;
* The first is the magic word or flag used for RLEW compression, which is almost always $ABCD in the original files. It could be changed to any other value if necessary.&lt;br /&gt;
&lt;br /&gt;
* The second is 100 level pointers which give the location of the start of level data in the GAMEMAPS file, relative to the start of that file.  A value less than 1 indicates no level (generally 0, but occasionally -1 (0xFFFFFFFF) is used). Using -1 should be preferred over 0, as the pre-Wolf3D version of the engine will treat any negative value as &amp;quot;a non existant map&amp;quot; [sic!] and quit with an appropriate error message, while 0 will cause it to try reading a level header at offset 0 (where the &amp;quot;TED5v1.0&amp;quot; string is usually stored), which will cause all kinds of errors as there is clearly no valid level header at that offset.&lt;br /&gt;
** For Wolf3D, take only the 16 high-order bits of the resulting 32-bit value (0x12340000 means a map at offset 0x1234)&lt;br /&gt;
&lt;br /&gt;
* The third is the tileinfo data, which contains tile properties for each tile used in level creation. (These are masked and unmasked and either 8x8, 16x16 or 32x32.)&lt;br /&gt;
&lt;br /&gt;
Many programs treat the tileinfo as a separate file from the MAPHEAD and it is possible to modify a game in this manner.  Indeed, some games such as Wolfenstein 3-D do not have any tileinfo data at all in the map header file (giving a total file length of 402 bytes.) However TED5 works with any tileinfo data in the MAPHEAD.&lt;br /&gt;
&lt;br /&gt;
=== Map data (GAMEMAPS) ===&lt;br /&gt;
&lt;br /&gt;
The GAMEMAPS file consists of the string &amp;quot;TED5v1.0&amp;quot; and a number of compressed chunks of varying length.  Each level in the file will have from two to four chunks (usually four) depending on the game, with all levels in a given game having the same number of chunks.  These are the level header and 1-3 planes (foreground, background and sprite/info.)  The chunks are in no particular order and it is possible to read through the entire file decompressing chunks as they&#039;re found.&lt;br /&gt;
&lt;br /&gt;
Chunks are ordered by the MAPHEAD file, which will point to the GAMEMAPS level header chunks which in turn contain pointers to the other GAMEMAPS chunks used by that level.&lt;br /&gt;
&lt;br /&gt;
All level data is in the form of [[UINT16LE]] values (or in the case of pointers, [[UINT32LE]].)&lt;br /&gt;
&lt;br /&gt;
==== Level headers ====&lt;br /&gt;
&lt;br /&gt;
The header for each level inside the GAMEMAPS file (which is pointed to by MAPHEAD) is 38 bytes long and &#039;&#039;never&#039;&#039; RLEW compressed.  If the GAMEMAPS file is using Huffman compression, the level header itself is Huffman-compressed.  In that case, the size of the compressed level header can be found in the MAPHEAD file.  Since the uncompressed level header always has a size of 38 bytes, that size is not stored at the beginning of the compressed data.  The header is sometimes followed by a signature &amp;quot;!ID!&amp;quot; string, which would give the header a total size of 42 bytes, but that string is not part of the actual level header.&lt;br /&gt;
&lt;br /&gt;
The expanded size of each map plane is the size of a word ([[UINT16LE]]) times the width times the height.  This is the final, expected size and can be precomputed even if there are two layers of compression.&lt;br /&gt;
&lt;br /&gt;
Plane 0 is background using unmasked tiles, plane 1 is foreground and uses masked tiles, and plane 2 is sprite/info.  Levels must contain a background plane and usually an infoplane.&lt;br /&gt;
&lt;br /&gt;
For the compressed size of each level plane, a value of 0 indicates the plane does not exist. The offset value for unused planes appears to be set to a random number with the most significant byte set to 0xFF, making it either a negative number or an offset close to the 4 gigabyte range. The games only check the compressed size and ignore the offset if the size is 0.&lt;br /&gt;
&lt;br /&gt;
Note that Wolf3D is hard-coded to always load the first two planes, even if the compressed size of a plane is 0. Wolf3D also ignores the width and height stored in the level header and just assumes the level is 64x64 tiles. This also applies to Blake Stone and probably any other game based on the Wolf3D code.&lt;br /&gt;
&lt;br /&gt;
All versions of the &amp;quot;Id Software Caching Manager&amp;quot; ignore the expanded size value at the beginning of the RLEW data and just assume that the size is the same as the size of the plane (width * height * 2).&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || [[INT32LE]] || offPlane0 || Offset in GAMEMAPS to beginning of compressed plane 0 data (or &amp;lt;= 0 if plane is not present)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || INT32LE || offPlane1 || Offset in GAMEMAPS to beginning of compressed plane 1 data (or &amp;lt;= 0 if plane is not present)&lt;br /&gt;
|-&lt;br /&gt;
| 8 || INT32LE || offPlane2 || Offset in GAMEMAPS to beginning of compressed plane 2 data (or &amp;lt;= 0 if plane is not present)&lt;br /&gt;
|-&lt;br /&gt;
| 12 || UINT16LE || lenPlane0 || Length of compressed plane 0 data (in bytes)&lt;br /&gt;
|-&lt;br /&gt;
| 14 || UINT16LE || lenPlane1 || Length of compressed plane 1 data (in bytes)&lt;br /&gt;
|-&lt;br /&gt;
| 16 || UINT16LE || lenPlane2 || Length of compressed plane 2 data (in bytes)&lt;br /&gt;
|-&lt;br /&gt;
| 18 || UINT16LE || width || Width of level (in tiles)&lt;br /&gt;
|-&lt;br /&gt;
| 20 || UINT16LE || height || Height of level (in tiles)&lt;br /&gt;
|-&lt;br /&gt;
| 22 || char[16] || name || Internal name for level (used only by editor, not displayed in-game. null-terminated)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that for Wolfenstein 3D, a 4-byte signature string (&amp;quot;!ID!&amp;quot;) will normally be present directly after the level name. The signature does not appear to be used anywhere, but is useful for distinguishing between v1.0 files (the signature string is missing), and files for v1.1 and later (includes the signature string).&lt;br /&gt;
&lt;br /&gt;
== Carmack compression ==&lt;br /&gt;
&lt;br /&gt;
[[Carmack compression]] is the method used to compress later &#039;&#039;id Software&#039;&#039; games, when file size was still a concern.  It is the most efficient and complex compression method and was created specifically to work with the 16-bit word structure of the GameMaps file.  The compression is detailed on its [[Carmack compression|own page.]]&lt;br /&gt;
&lt;br /&gt;
Carmackized game maps files are external &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt; files and the map header is usually (but not always) stored internally in the executable.  The map header must be extracted and the game maps decompressed before TED5 can access them.  TED5 itself can produce carmackized files and external &amp;lt;tt&amp;gt;MAPHEAD.xxx&amp;lt;/tt&amp;gt; files. Carmackization does not replace the RLEW compression used in uncompressed data, but compresses this data, that is, the data is doubly compressed.&lt;br /&gt;
&lt;br /&gt;
Note that for Wolfenstein 3D v1.0, map files are not carmackized, only RLEW compression is applied.&lt;br /&gt;
&lt;br /&gt;
== Huffman compression ==&lt;br /&gt;
&lt;br /&gt;
[[Huffman Compression]] was probably used by earlier versions of TED5 (but possibly not TED5 at all) before carmackization was introduced.  It uses the same method to compress its data as is used by &#039;&#039;id Software&#039;&#039; games to compress their graphics and sounds.  Again this compression method works with RLEW compressed data and has its [[Huffman Compression|own page.]]&lt;br /&gt;
&lt;br /&gt;
Huffman compression is easily detected since it works on the bit level and thus disrupts the word structure of the game data.  This is easily seen in a hex editor.  Compressed data will not contain the string $00 $00 or indeed even $00 very often. (In contrast, even carmackized data contains both strings hundreds of times.)&lt;br /&gt;
&lt;br /&gt;
There will be two internal files for this format: the map header and the Huffman dictionary (which is always the first dictionary in the executable.)  The map header format is also slightly different, being 502 bytes long, the extra 100 bytes being the length of the compressed level headers in the game maps data, which occur immediately after the normal level header offsets and before the tileinfo. Each entry is one octet indicating the decompressed header length in bytes or zero if the level does not exist. (These can be ignored when decompressing since Huffman data can be read until the decompressed level header&#039;s fixed size is reached, but if they are omitted when writing the MAPHEAD, the game may experience a buffer overflow when reading the maps.)&lt;br /&gt;
&lt;br /&gt;
== Location of internal files ==&lt;br /&gt;
&lt;br /&gt;
The GAMEMAPS file itself is always external, but in the case of compression, the MAPHEAD is stored internally in the main .exe file.  Executables are themselves compressed with either with LZEXE or PKLite.  Once the .exe has been decompressed it is a trivial task to find the MAPHEAD as it will start with the UINT16LE value $ABCD (i.e. the byte $CD followed by the byte $AB.)  For level editing purposes only the first 402 (or 502) bytes of the file need to be extracted, though it is possible to read the MAPHEAD file to calculate its length.&lt;br /&gt;
&lt;br /&gt;
The following table lists the offsets of the MAPHEAD file for various games, relative to the start of the decompressed game .exe file.&lt;br /&gt;
&lt;br /&gt;
{{TODO|TODO: Add all known versions of all games}}&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Game !! Version !! Location !! Filename !! Offset !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| [[Bio Menace]] || Freeware || External || &amp;lt;tt&amp;gt;MAPHEAD.BM[123]&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=2| [[Blake Stone]]: Aliens of Gold || Shareware || External || &amp;lt;tt&amp;gt;MAPHEAD.BS1&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| Registered|| External || &amp;lt;tt&amp;gt;MAPHEAD.BS6&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Blake Stone]] 2: Planet Strike || All || External || &amp;lt;tt&amp;gt;MAPHEAD.VSI&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb 3-D]] (3) || 1.00 || Internal || &amp;lt;tt&amp;gt;CAT3D.EXE&amp;lt;/tt&amp;gt; || $1C570 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb Abyss]] (4) || 1.13 || Internal || &amp;lt;tt&amp;gt;CATABYSS.EXE&amp;lt;/tt&amp;gt; || $1C510 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb Armageddon]] (5) || 1.01a || Internal || &amp;lt;tt&amp;gt;CATARMA.EXE&amp;lt;/tt&amp;gt; || $1D900 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb Apocalypse]] (6) || 1.00b || Internal || &amp;lt;tt&amp;gt;CATAPOC.EXE&amp;lt;/tt&amp;gt; || $1DD50 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=3| [[Corridor 7 Alien Invasion]] || Demo || External || &amp;lt;tt&amp;gt;MAPHEAD.DMO&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
|| CD || Internal || &amp;lt;tt&amp;gt;CORR7CD.EXE&amp;lt;/tt&amp;gt; || $30D50 || File is not compressed&lt;br /&gt;
|-&lt;br /&gt;
| Floppy || Internal || &amp;lt;tt&amp;gt;C7.EXE&amp;lt;/tt&amp;gt; || $24BF0 || File is not compressed&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=2| [[Commander Keen 4-6|Keen 4]] || Special Demo || ? || ? || ? || File is PKLite compressed&lt;br /&gt;
|-&lt;br /&gt;
| 1.4 EGA || Internal || &amp;lt;tt&amp;gt;KEEN4E.EXE&amp;lt;/tt&amp;gt; || $24830 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Commander Keen 4-6|Keen 5]] || 1.4 EGA || Internal || &amp;lt;tt&amp;gt;KEEN5E.EXE&amp;lt;/tt&amp;gt; || $25990 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Commander Keen 4-6|Keen 6]] || 1.4 EGA || Internal || &amp;lt;tt&amp;gt;KEEN6.EXE&amp;lt;/tt&amp;gt; || $25080 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Commander Keen Dreams]] || 1.13 || Internal || ? || $1FA50 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Super 3-D Noah&#039;s Ark]] || All || External || &amp;lt;tt&amp;gt;maphead.n3d&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Operation Body Count]] || All || External || &amp;lt;tt&amp;gt;MAPHEAD.BC&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Spear of Destiny]] || All || External || &amp;lt;tt&amp;gt;MAPHEAD.SOD&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=2| [[Wolfenstein 3-D]] || Shareware || External || &amp;lt;tt&amp;gt;MAPHEAD.WL1&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| Registered || External || &amp;lt;tt&amp;gt;MAPHEAD.WL6&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Utilities ==&lt;br /&gt;
&lt;br /&gt;
* [[TED5]] can edit the &amp;lt;tt&amp;gt;GAMEMAPS&amp;lt;/tt&amp;gt; format of any games that use it.  It is the original editor used to create these files.&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
This file format was reverse engineered by Andrew Durdin (adurdin).  If you find this information helpful in a project you&#039;re working on, please give credit where credit is due.  (A link back to this wiki would be nice too!)&lt;/div&gt;</summary>
		<author><name>VKokielov</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=EGA_Font_format&amp;diff=10875</id>
		<title>EGA Font format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=EGA_Font_format&amp;diff=10875"/>
		<updated>2023-01-27T16:44:09Z</updated>

		<summary type="html">&lt;p&gt;VKokielov: A more clear explanation -- I hope -- based on my investigations&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;EGA Font format&#039; is used to store a monochrome font used in many [[Softdisk]] and [[ID Software]] games. While the font is functionally monochrome is is related to [[Raw EGA data|EGA]] and used solely by EGA games. There are two versions of the font, differing slightly in format. This is because the first format was dropped due to limitations in what it could display (256 characters of one color) however after some experimentation using 8x8 unmasked tiles for font (Notable in [[Commander Keen 1-3]].), a new way to use the font for more varied purposes was discovered.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
 0	[[UINT16LE]]	Line height	Height of lines (And thus all characters)	&lt;br /&gt;
 2	256*[[UINT16LE]]	Char offset	Array of 16-bit offsets to characters from the start of the data chunk&lt;br /&gt;
 514	256*[[UINT8]]	Char width	Width of the character on-screen (but see below)&lt;br /&gt;
 770	bytes to the end of the chunk	Character image data (see below)&lt;br /&gt;
&lt;br /&gt;
Each file starts with a 770 byte header. This can be used to search for the font if it is stored internally. This is because characters 0-31 are used by the game to write 8x8 window tiles inside which text is written. Therefore a font file will start with a word of varying value followed by 64 nulls and the word $302, pointing to the end of the header.&lt;br /&gt;
&lt;br /&gt;
The offsets in the header refer to 1-plane (one bit per pixel, monochrome) image data.  The size of the stored image is line height*rounded with, where rounded width is &amp;quot;char width,&amp;quot; but rounded &#039;&#039;&#039;up&#039;&#039;&#039; to the next multiple of 8.  &lt;br /&gt;
&lt;br /&gt;
For example, in a font with height 10, a character where &amp;quot;width&amp;quot; == 7 is stored in a 10x8 monochrome image.  A character where &amp;quot;width&amp;quot; == 11 is stored in a 10x16 monochrome image.  &lt;br /&gt;
&lt;br /&gt;
The additional pixels to the right of the width line are not meant to be rendered and are consequently always set to 0 in the mask; the rounding is simply to prevent the rows of the planar image from having an odd (non-byte-aligned) number of bits.&lt;br /&gt;
&lt;br /&gt;
=== Version 1 and Version 2 ===&lt;br /&gt;
&lt;br /&gt;
There is one difference between the two versions of fonts; version 1 has twice as much character data, as each character&#039;s data is preceded by a mask. It is not known if or how the game uses this, but it may have something to do with character overlap mentioned above. The difference between versions can be detected by comparing the size of a character&#039;s data with its height\width. The 4x10 character above would have 20 bytes of data in version 1.&lt;br /&gt;
&lt;br /&gt;
Version 1 is found either internally in executables or externally as a single file in earlier Softdisk\ID Software games such as [[Shadow Knights]] or [[Rescue Rover]]. Version 2 is found inside [[EGAGraph Format|EGAGraph]] files as a font chunk.&lt;br /&gt;
&lt;br /&gt;
== Implementation ==&lt;br /&gt;
&lt;br /&gt;
In its earliest implementation characters are treated as another plane of EGA data overlaid on the screen. The game performs a NOT check meaning in essence that the nonzero part of the character inverts the color it is displayed on. In a text window this turns the white background black, but characters can be displayed over images outside of text windows, where this effect can be seen more clearly.&lt;br /&gt;
&lt;br /&gt;
Later games allow the font to be warped in various ways, as well as having custom colors instead of simple inversion. This can be seen in the [[Commander Keen 4-6]] help screens for example.&lt;/div&gt;</summary>
		<author><name>VKokielov</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Carmack_compression&amp;diff=10860</id>
		<title>Carmack compression</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Carmack_compression&amp;diff=10860"/>
		<updated>2023-01-20T17:26:27Z</updated>

		<summary type="html">&lt;p&gt;VKokielov: clearer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Compression Infobox&lt;br /&gt;
 | Type = Stream&lt;br /&gt;
 | UnitSize = 1-byte&lt;br /&gt;
 | Games =&lt;br /&gt;
   {{Game|Catacomb 3-D}}&lt;br /&gt;
   {{Game|Commander Keen 4-6}}&lt;br /&gt;
   {{Game|Super 3-D Noah&#039;s Ark}}&lt;br /&gt;
   {{Game|Wolfenstein 3-D}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Carmack compression]] is used in the [[GameMaps Format|GAMEMAPS file]] in a number of games to further shrink the levels down beyond what [[RLEW compression]] can achieve. Its basic idea is somewhat like LZ (Lempel-Ziv) compression in that it contains pointers back to previous data.&lt;br /&gt;
&lt;br /&gt;
As in RLEW compression, the first word in the Carmack compressed data is the number of bytes (not words) in the decompressed data. This is typically the number of bytes in the compressed RLEW data, as Carmack compression is performed after RLEW compression.&lt;br /&gt;
&lt;br /&gt;
The format specifies some values in &#039;&#039;&#039;words&#039;&#039;&#039; - these are 16-bits in length ([[UINT16LE]]).&lt;br /&gt;
&lt;br /&gt;
Carmack compression contains two types of references to previous data: near pointers and far pointers.&lt;br /&gt;
&lt;br /&gt;
=== Near Pointers ===&lt;br /&gt;
&lt;br /&gt;
Near pointers occupy three bytes in the compressed data. The first is the number of words in the referenced sequence, the second is the signal byte of 0xA7, and the third is the number of words to the start of the reference (counting backwards from the current location). As a concrete example, the three bytes 0x05 0xA7 0x0A mean &#039;repeat the 5 words starting 10 words ago&#039;.&lt;br /&gt;
&lt;br /&gt;
Notice that near pointers only let one refer to the last 255 words. To refer to sequences further back, one must use far pointers.&lt;br /&gt;
&lt;br /&gt;
=== Far Pointers ===&lt;br /&gt;
&lt;br /&gt;
Far pointers occupy four bytes in the compressed data:&lt;br /&gt;
* The first byte is the number of &#039;&#039;words&#039;&#039; in the sequence to copy from the previously generated output;&lt;br /&gt;
* The second byte is the tag &#039;0xa8&#039;&lt;br /&gt;
* The fourth and fifth bytes are an UINT16LE specifying &#039;&#039;&#039;the number of words from the beginning of output to the start of the sequence to copy&#039;&#039;&#039;.  This is different from the near pointers, which are offsets from the &amp;quot;current&amp;quot; output position!&lt;br /&gt;
&lt;br /&gt;
As a concrete example, the four bytes 0x10 0xA8 0x01 0x02 mean &#039;copy to the current output position the 16 words (or 32 bytes) starting 513 words (or 1026 bytes) from the start of the output&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Words with a high byte of 0xA7 or 0xA8 ===&lt;br /&gt;
&lt;br /&gt;
Words whose high (second) byte is 0xA7 or 0xA8 would appear to be issue, as they would be confused with near or far pointers. These are handled by representing them as the three bytes: &amp;lt;tt&amp;gt;00 Ax yy&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;yy&amp;lt;/tt&amp;gt; is the lower 8 bits of the word being escaped.  This sequence is recognized as an exception, as repeating zero words would make no sense.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
    00 A7 12 EE FF 00 A8 34 CC DD&lt;br /&gt;
&lt;br /&gt;
Decodes to:&lt;br /&gt;
&lt;br /&gt;
    12 A7 EE FF 34 A8 CC DD&lt;br /&gt;
&lt;br /&gt;
=== Example code ===&lt;br /&gt;
&lt;br /&gt;
* Javascript: the [https://github.com/Malvineous/gamecompjs/blob/master/formats/cmp-carmackize.js cmp-carmackize] algorithm in gamecomp.js&lt;/div&gt;</summary>
		<author><name>VKokielov</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Carmack_compression&amp;diff=10859</id>
		<title>Carmack compression</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Carmack_compression&amp;diff=10859"/>
		<updated>2023-01-20T17:22:42Z</updated>

		<summary type="html">&lt;p&gt;VKokielov: this is rather misleading here.  I implemented the wrong algorithm.  Correcting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Compression Infobox&lt;br /&gt;
 | Type = Stream&lt;br /&gt;
 | UnitSize = 1-byte&lt;br /&gt;
 | Games =&lt;br /&gt;
   {{Game|Catacomb 3-D}}&lt;br /&gt;
   {{Game|Commander Keen 4-6}}&lt;br /&gt;
   {{Game|Super 3-D Noah&#039;s Ark}}&lt;br /&gt;
   {{Game|Wolfenstein 3-D}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Carmack compression]] is used in the [[GameMaps Format|GAMEMAPS file]] in a number of games to further shrink the levels down beyond what [[RLEW compression]] can achieve. Its basic idea is somewhat like LZ (Lempel-Ziv) compression in that it contains pointers back to previous data.&lt;br /&gt;
&lt;br /&gt;
As in RLEW compression, the first word in the Carmack compressed data is the number of bytes (not words) in the decompressed data. This is typically the number of bytes in the compressed RLEW data, as Carmack compression is performed after RLEW compression.&lt;br /&gt;
&lt;br /&gt;
The format specifies some values in &#039;&#039;&#039;words&#039;&#039;&#039; - these are 16-bits in length ([[UINT16LE]]).&lt;br /&gt;
&lt;br /&gt;
Carmack compression contains two types of references to previous data: near pointers and far pointers.&lt;br /&gt;
&lt;br /&gt;
=== Near Pointers ===&lt;br /&gt;
&lt;br /&gt;
Near pointers occupy three bytes in the compressed data. The first is the number of words in the referenced sequence, the second is the signal byte of 0xA7, and the third is the number of words to the start of the reference (counting backwards from the current location). As a concrete example, the three bytes 0x05 0xA7 0x0A mean &#039;repeat the 5 words starting 10 words ago&#039;.&lt;br /&gt;
&lt;br /&gt;
Notice that near pointers only let one refer to the last 255 words. To refer to sequences further back, one must use far pointers.&lt;br /&gt;
&lt;br /&gt;
=== Far Pointers ===&lt;br /&gt;
&lt;br /&gt;
Far pointers occupy four bytes in the compressed data:&lt;br /&gt;
* The first byte is the number of bytes to repeat;&lt;br /&gt;
* The second byte is the tag &#039;0xa8&#039;&lt;br /&gt;
* The fourth and fifth bytes are an UINT16LE specifying &#039;&#039;&#039;the number of words from the beginning of output to the start of the sequence to copy&#039;&#039;&#039;.  This is different from the near pointers, which are offsets from the &amp;quot;current&amp;quot; output position!&lt;br /&gt;
&lt;br /&gt;
As a concrete example, the four bytes 0x10 0xA8 0x01 0x02 mean &#039;repeat the 16 words starting 513 words from the start of the output &#039;.&lt;br /&gt;
&lt;br /&gt;
=== Words with a high byte of 0xA7 or 0xA8 ===&lt;br /&gt;
&lt;br /&gt;
Words whose high (second) byte is 0xA7 or 0xA8 would appear to be issue, as they would be confused with near or far pointers. These are handled by representing them as the three bytes: &amp;lt;tt&amp;gt;00 Ax yy&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;yy&amp;lt;/tt&amp;gt; is the lower 8 bits of the word being escaped.  This sequence is recognized as an exception, as repeating zero words would make no sense.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
    00 A7 12 EE FF 00 A8 34 CC DD&lt;br /&gt;
&lt;br /&gt;
Decodes to:&lt;br /&gt;
&lt;br /&gt;
    12 A7 EE FF 34 A8 CC DD&lt;br /&gt;
&lt;br /&gt;
=== Example code ===&lt;br /&gt;
&lt;br /&gt;
* Javascript: the [https://github.com/Malvineous/gamecompjs/blob/master/formats/cmp-carmackize.js cmp-carmackize] algorithm in gamecomp.js&lt;/div&gt;</summary>
		<author><name>VKokielov</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=GameMaps_Format&amp;diff=10858</id>
		<title>GameMaps Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=GameMaps_Format&amp;diff=10858"/>
		<updated>2023-01-18T19:09:52Z</updated>

		<summary type="html">&lt;p&gt;VKokielov: /* Level headers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Map Infobox&lt;br /&gt;
 | Type = 2D tile-based&lt;br /&gt;
 | Layers = 3&lt;br /&gt;
 | Viewport = &#039;&#039;Varies by game&#039;&#039;&lt;br /&gt;
 | Games = &lt;br /&gt;
   {{Game|Bio Menace}}&lt;br /&gt;
   {{Game|Blake Stone}}&lt;br /&gt;
   {{Game|Catacomb 3-D}}&lt;br /&gt;
   {{Game|Catacomb Abyss}}&lt;br /&gt;
   {{Game|Commander Keen Dreams}}&lt;br /&gt;
   {{Game|Commander Keen 4-6}}&lt;br /&gt;
   {{Game|Corridor 7 Alien Invasion}}&lt;br /&gt;
   {{Game|Dangerous Dave 3}}&lt;br /&gt;
   {{Game|Dangerous Dave 4}}&lt;br /&gt;
   {{Game|Super 3-D Noah&#039;s Ark}}&lt;br /&gt;
   {{Game|Operation Body Count}}&lt;br /&gt;
   {{Game|Rescue Rover 2}}&lt;br /&gt;
   {{Game|Spear of Destiny}}&lt;br /&gt;
   {{Game|Wolfenstein 3-D}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;GameMaps Format&#039;&#039;&#039; stores levels in a number of [[:Category:id Software]] games. The filenames and compression varies somewhat across different games but all files stored in this format were produced by the [[TED5]] level editor.&lt;br /&gt;
&lt;br /&gt;
There are three main varieties of the file format. The most basic version is just [[RLEW compression|RLEW compressed]], the other two are either [[Carmack compression|carmackized]] or [[Huffman Compression|Huffman compressed]] on top of the RLEW compression. Each variation has its own file naming scheme and pattern of external/internal files.&lt;br /&gt;
&lt;br /&gt;
There are two main components to the format.  The game maps proper, which contain the actual level data, and the map headers, which contain both the location of each level&#039;s data within the game maps file, and the tile info for the game.&lt;br /&gt;
&lt;br /&gt;
== Variants ==&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Game !! RLEW !! Carmackization !! Huffman !! Head || Gamemaps || Notes&lt;br /&gt;
|-&lt;br /&gt;
| Bio Menace || Yes || No || No || maphead.bm[123] || maptemp.bm[123] || gamemaps.bm[123] and mapthead.bm[123] are present but not used&lt;br /&gt;
|-&lt;br /&gt;
| Blake Stone: Aliens of Gold || Yes || No || No || maphead.bs[16] || maptemp.bs[16] ||&lt;br /&gt;
|-&lt;br /&gt;
| Blake Stone: Planet Strike || Yes || No || No || maphead.vsi || maptemp.vsi ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb 3-D || Yes || Yes || No || Inside .exe || gamemaps.c3d ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb Abyss || Yes || Yes || No || Inside .exe || gamemaps.abs ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb Apocalypse || Yes || Yes || No || Inside .exe || gamemaps.apc ||&lt;br /&gt;
|-&lt;br /&gt;
| Catacomb Armageddon || Yes || Yes || No || Inside .exe || gamemaps.arm ||&lt;br /&gt;
|-&lt;br /&gt;
| Commander Keen Dreams || Yes || No || Yes || Inside .exe || gamemaps.kdr (v1.00), kdreams.map (v1.01+) ||&lt;br /&gt;
|-&lt;br /&gt;
| Commander Keen 4-6 || Yes || Yes || No || Inside .exe || gamemaps.ck[456] ||&lt;br /&gt;
|-&lt;br /&gt;
| Corridor 7 Alien Invasion || Yes || No || No || ? || ? || Uses MAPTEMP.xxx (only RLEW compression)&lt;br /&gt;
|-&lt;br /&gt;
| Dangerous Dave 3 || Yes || No || Yes || Inside .exe || gamemaps.dav ||&lt;br /&gt;
|-&lt;br /&gt;
| Dangerous Dave 4 || Yes || No || Yes || Inside .exe || gamemaps.dav ||&lt;br /&gt;
|-&lt;br /&gt;
| Super 3-D Noah&#039;s Ark || Yes || Yes || No || maphead.n3d || gamemaps.n3d ||&lt;br /&gt;
|-&lt;br /&gt;
| Operation Body Count || Yes || No || No || ? || ? || Uses MAPTEMP.xxx (only RLEW compression)&lt;br /&gt;
|-&lt;br /&gt;
| Rescue Rover 2 || Yes || Yes || No || Inside .exe || gamemaps.rr2 ||&lt;br /&gt;
|-&lt;br /&gt;
| Spear of Destiny || Yes || Yes || No || maphead.sod || gamemaps.sod ||&lt;br /&gt;
|-&lt;br /&gt;
| Wolfenstein 3-D (v1.0) || Yes || No || No || maphead.wl1 || maptemp.wl1 ||&lt;br /&gt;
|-&lt;br /&gt;
| Wolfenstein 3-D (v1.1 and above)|| Yes || Yes || No || maphead.wl[16] || gamemaps.wl[16] ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The games that use Huffman compression will have a MAPDICT (embedded in the game&#039;s main executable).  Those missing the map dictionary are not Huffman encoded.&lt;br /&gt;
&lt;br /&gt;
To work out whether Carmackization is used, read the first UINT16LE in a map plane (the field storing the decompressed size).  If the value matches the expected size of the plane (i.e. width * height * 2), then only RLEW compression is used.  If it doesn&#039;t match, check the second UINT16LE in the file (which will become the first UINT16LE once Carmackization has been removed).  If this matches the expected plane size then the plane must first have Carmackization removed followed by removal of RLEW. The exception to this rule are plane sizes that have either 0xA7 or 0xA8 as the high byte (i.e. any value from 0xA700 to 0xA8FF), as those values would have been encoded differently by the [[Carmack compression]] algorithm.&lt;br /&gt;
&lt;br /&gt;
== Data structures==&lt;br /&gt;
&lt;br /&gt;
The map data is split into two files: The map header (&amp;lt;tt&amp;gt;MAPHEAD.xxx&amp;lt;/tt&amp;gt;) and the main map file (usually &amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt;). The map header may be embedded in the game&#039;s main executable.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; is the working format saved by [[TED5]] when maps are being edited and can be directly accessed and edited by this utility, allowing changes to be made to the game. Note that if the MAPHEAD file exists as an external file, the game always reads it from a file named named &amp;lt;tt&amp;gt;MAPHEAD.xxx&amp;lt;/tt&amp;gt; for both the &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt; and the &amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; variation. TED5 also saves a &amp;lt;tt&amp;gt;MAPTHEAD.xx&amp;lt;/tt&amp;gt; file when editing maps, but that file is only used by TED5 and usually omitted from any game release.&lt;br /&gt;
&lt;br /&gt;
The maps were often compressed even further for the public release versions of the games. This more compressed version of the map file was saved as &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt; by TED5. Later releases would omit the additional compression layer and ship with the &amp;lt;tt&amp;gt;MAPTEMP.xxx&amp;lt;/tt&amp;gt; file instead. One possible reason for this could be that the size of the games grew to the point where they would no longer fit onto and be playable from a single floppy disk, and therefore the additional compression was no longer worth the amount of time it took to compress the maps and re-compile the code.&lt;br /&gt;
&lt;br /&gt;
=== Map headers (MAPHEAD) ===&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || [[UINT16LE]] || magic || Magic word signalling [[RLEW compression]]&lt;br /&gt;
|-&lt;br /&gt;
| 2 || [[INT32LE]][100] || ptr || 100 pointers to start of level 0-99 data in the game maps file&lt;br /&gt;
|-&lt;br /&gt;
| 402 || {{TODO|Unknown}} || tileinfo || Optional tileinfo data&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The map header file (MAPHEAD) is of varying length and contains three main types of data.&lt;br /&gt;
&lt;br /&gt;
* The first is the magic word or flag used for RLEW compression, which is almost always $ABCD in the original files. It could be changed to any other value if necessary.&lt;br /&gt;
&lt;br /&gt;
* The second is 100 level pointers which give the location of the start of level data in the GAMEMAPS file, relative to the start of that file.  A value less than 1 indicates no level (generally 0, but occasionally -1 (0xFFFFFFFF) is used). Using -1 should be preferred over 0, as the pre-Wolf3D version of the engine will treat any negative value as &amp;quot;a non existant map&amp;quot; [sic!] and quit with an appropriate error message, while 0 will cause it to try reading a level header at offset 0 (where the &amp;quot;TED5v1.0&amp;quot; string is usually stored), which will cause all kinds of errors as there is clearly no valid level header at that offset.&lt;br /&gt;
&lt;br /&gt;
* The third is the tileinfo data, which contains tile properties for each tile used in level creation. (These are masked and unmasked and either 8x8, 16x16 or 32x32.)&lt;br /&gt;
&lt;br /&gt;
Many programs treat the tileinfo as a separate file from the MAPHEAD and it is possible to modify a game in this manner.  Indeed, some games such as Wolfenstein 3-D do not have any tileinfo data at all in the map header file (giving a total file length of 402 bytes.) However TED5 works with any tileinfo data in the MAPHEAD.&lt;br /&gt;
&lt;br /&gt;
=== Map data (GAMEMAPS) ===&lt;br /&gt;
&lt;br /&gt;
The GAMEMAPS file consists of the string &amp;quot;TED5v1.0&amp;quot; and a number of compressed chunks of varying length.  Each level in the file will have from two to four chunks (usually four) depending on the game, with all levels in a given game having the same number of chunks.  These are the level header and 1-3 planes (foreground, background and sprite/info.)  The chunks are in no particular order and it is possible to read through the entire file decompressing chunks as they&#039;re found.&lt;br /&gt;
&lt;br /&gt;
Chunks are ordered by the MAPHEAD file, which will point to the GAMEMAPS level header chunks which in turn contain pointers to the other GAMEMAPS chunks used by that level.&lt;br /&gt;
&lt;br /&gt;
All level data is in the form of [[UINT16LE]] values (or in the case of pointers, [[UINT32LE]].)&lt;br /&gt;
&lt;br /&gt;
==== Level headers ====&lt;br /&gt;
&lt;br /&gt;
The header for each level inside the GAMEMAPS file (which is pointed to by MAPHEAD) is 38 bytes long and &#039;&#039;never&#039;&#039; RLEW compressed.  If the GAMEMAPS file is using Huffman compression, the level header itself is Huffman-compressed.  In that case, the size of the compressed level header can be found in the MAPHEAD file.  Since the uncompressed level header always has a size of 38 bytes, that size is not stored at the beginning of the compressed data.  The header is sometimes followed by a signature &amp;quot;!ID!&amp;quot; string, which would give the header a total size of 42 bytes, but that string is not part of the actual level header.&lt;br /&gt;
&lt;br /&gt;
The expanded size of each map plane is the size of a word ([[UINT16LE]]) times the width times the height.  This is the final, expected size and can be precomputed even if there are two layers of compression.&lt;br /&gt;
&lt;br /&gt;
Plane 0 is background using unmasked tiles, plane 1 is foreground and uses masked tiles, and plane 2 is sprite/info.  Levels must contain a background plane and usually an infoplane.&lt;br /&gt;
&lt;br /&gt;
For the compressed size of each level plane, a value of 0 indicates the plane does not exist. The offset value for unused planes appears to be set to a random number with the most significant byte set to 0xFF, making it either a negative number or an offset close to the 4 gigabyte range. The games only check the compressed size and ignore the offset if the size is 0.&lt;br /&gt;
&lt;br /&gt;
Note that Wolf3D is hard-coded to always load the first two planes, even if the compressed size of a plane is 0. Wolf3D also ignores the width and height stored in the level header and just assumes the level is 64x64 tiles. This also applies to Blake Stone and probably any other game based on the Wolf3D code.&lt;br /&gt;
&lt;br /&gt;
All versions of the &amp;quot;Id Software Caching Manager&amp;quot; ignore the expanded size value at the beginning of the RLEW data and just assume that the size is the same as the size of the plane (width * height * 2).&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Type !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || [[INT32LE]] || offPlane0 || Offset in GAMEMAPS to beginning of compressed plane 0 data (or &amp;lt;= 0 if plane is not present)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || INT32LE || offPlane1 || Offset in GAMEMAPS to beginning of compressed plane 1 data (or &amp;lt;= 0 if plane is not present)&lt;br /&gt;
|-&lt;br /&gt;
| 8 || INT32LE || offPlane2 || Offset in GAMEMAPS to beginning of compressed plane 2 data (or &amp;lt;= 0 if plane is not present)&lt;br /&gt;
|-&lt;br /&gt;
| 12 || UINT16LE || lenPlane0 || Length of compressed plane 0 data (in bytes)&lt;br /&gt;
|-&lt;br /&gt;
| 14 || UINT16LE || lenPlane1 || Length of compressed plane 1 data (in bytes)&lt;br /&gt;
|-&lt;br /&gt;
| 16 || UINT16LE || lenPlane2 || Length of compressed plane 2 data (in bytes)&lt;br /&gt;
|-&lt;br /&gt;
| 18 || UINT16LE || width || Width of level (in tiles)&lt;br /&gt;
|-&lt;br /&gt;
| 20 || UINT16LE || height || Height of level (in tiles)&lt;br /&gt;
|-&lt;br /&gt;
| 22 || char[16] || name || Internal name for level (used only by editor, not displayed in-game. null-terminated)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that for Wolfenstein 3D, a 4-byte signature string (&amp;quot;!ID!&amp;quot;) will normally be present directly after the level name. The signature does not appear to be used anywhere, but is useful for distinguishing between v1.0 files (the signature string is missing), and files for v1.1 and later (includes the signature string).&lt;br /&gt;
&lt;br /&gt;
== Carmack compression ==&lt;br /&gt;
&lt;br /&gt;
[[Carmack compression]] is the method used to compress later &#039;&#039;id Software&#039;&#039; games, when file size was still a concern.  It is the most efficient and complex compression method and was created specifically to work with the 16-bit word structure of the GameMaps file.  The compression is detailed on its [[Carmack compression|own page.]]&lt;br /&gt;
&lt;br /&gt;
Carmackized game maps files are external &amp;lt;tt&amp;gt;GAMEMAPS.xxx&amp;lt;/tt&amp;gt; files and the map header is usually (but not always) stored internally in the executable.  The map header must be extracted and the game maps decompressed before TED5 can access them.  TED5 itself can produce carmackized files and external &amp;lt;tt&amp;gt;MAPHEAD.xxx&amp;lt;/tt&amp;gt; files. Carmackization does not replace the RLEW compression used in uncompressed data, but compresses this data, that is, the data is doubly compressed.&lt;br /&gt;
&lt;br /&gt;
Note that for Wolfenstein 3D v1.0, map files are not carmackized, only RLEW compression is applied.&lt;br /&gt;
&lt;br /&gt;
== Huffman compression ==&lt;br /&gt;
&lt;br /&gt;
[[Huffman Compression]] was probably used by earlier versions of TED5 (but possibly not TED5 at all) before carmackization was introduced.  It uses the same method to compress its data as is used by &#039;&#039;id Software&#039;&#039; games to compress their graphics and sounds.  Again this compression method works with RLEW compressed data and has its [[Huffman Compression|own page.]]&lt;br /&gt;
&lt;br /&gt;
Huffman compression is easily detected since it works on the bit level and thus disrupts the word structure of the game data.  This is easily seen in a hex editor.  Compressed data will not contain the string $00 $00 or indeed even $00 very often. (In contrast, even carmackized data contains both strings hundreds of times.)&lt;br /&gt;
&lt;br /&gt;
There will be two internal files for this format: the map header and the Huffman dictionary (which is always the first dictionary in the executable.)  The map header format is also slightly different, being 502 bytes long, the extra 100 bytes being the length of the compressed level headers in the game maps data, which occur immediately after the normal level header offsets and before the tileinfo. Each entry is one octet indicating the decompressed header length in bytes or zero if the level does not exist. (These can be ignored when decompressing since Huffman data can be read until the decompressed level header&#039;s fixed size is reached, but if they are omitted when writing the MAPHEAD, the game may experience a buffer overflow when reading the maps.)&lt;br /&gt;
&lt;br /&gt;
== Location of internal files ==&lt;br /&gt;
&lt;br /&gt;
The GAMEMAPS file itself is always external, but in the case of compression, the MAPHEAD is stored internally in the main .exe file.  Executables are themselves compressed with either with LZEXE or PKLite.  Once the .exe has been decompressed it is a trivial task to find the MAPHEAD as it will start with the UINT16LE value $ABCD (i.e. the byte $CD followed by the byte $AB.)  For level editing purposes only the first 402 (or 502) bytes of the file need to be extracted, though it is possible to read the MAPHEAD file to calculate its length.&lt;br /&gt;
&lt;br /&gt;
The following table lists the offsets of the MAPHEAD file for various games, relative to the start of the decompressed game .exe file.&lt;br /&gt;
&lt;br /&gt;
{{TODO|TODO: Add all known versions of all games}}&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Game !! Version !! Location !! Filename !! Offset !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| [[Bio Menace]] || Freeware || External || &amp;lt;tt&amp;gt;MAPHEAD.BM[123]&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=2| [[Blake Stone]]: Aliens of Gold || Shareware || External || &amp;lt;tt&amp;gt;MAPHEAD.BS1&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| Registered|| External || &amp;lt;tt&amp;gt;MAPHEAD.BS6&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Blake Stone]] 2: Planet Strike || All || External || &amp;lt;tt&amp;gt;MAPHEAD.VSI&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb 3-D]] (3) || 1.00 || Internal || &amp;lt;tt&amp;gt;CAT3D.EXE&amp;lt;/tt&amp;gt; || $1C570 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb Abyss]] (4) || 1.13 || Internal || &amp;lt;tt&amp;gt;CATABYSS.EXE&amp;lt;/tt&amp;gt; || $1C510 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb Armageddon]] (5) || 1.01a || Internal || &amp;lt;tt&amp;gt;CATARMA.EXE&amp;lt;/tt&amp;gt; || $1D900 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Catacomb Apocalypse]] (6) || 1.00b || Internal || &amp;lt;tt&amp;gt;CATAPOC.EXE&amp;lt;/tt&amp;gt; || $1DD50 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=3| [[Corridor 7 Alien Invasion]] || Demo || External || &amp;lt;tt&amp;gt;MAPHEAD.DMO&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
|| CD || Internal || &amp;lt;tt&amp;gt;CORR7CD.EXE&amp;lt;/tt&amp;gt; || $30D50 || File is not compressed&lt;br /&gt;
|-&lt;br /&gt;
| Floppy || Internal || &amp;lt;tt&amp;gt;C7.EXE&amp;lt;/tt&amp;gt; || $24BF0 || File is not compressed&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=2| [[Commander Keen 4-6|Keen 4]] || Special Demo || ? || ? || ? || File is PKLite compressed&lt;br /&gt;
|-&lt;br /&gt;
| 1.4 EGA || Internal || &amp;lt;tt&amp;gt;KEEN4E.EXE&amp;lt;/tt&amp;gt; || $24830 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Commander Keen 4-6|Keen 5]] || 1.4 EGA || Internal || &amp;lt;tt&amp;gt;KEEN5E.EXE&amp;lt;/tt&amp;gt; || $25990 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Commander Keen 4-6|Keen 6]] || 1.4 EGA || Internal || &amp;lt;tt&amp;gt;KEEN6.EXE&amp;lt;/tt&amp;gt; || $25080 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Commander Keen Dreams]] || 1.13 || Internal || ? || $1FA50 || After UNLZEXE&lt;br /&gt;
|-&lt;br /&gt;
| [[Noah&#039;s Ark 3D]] || All || External || ? || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Operation Body Count]] || All || External || &amp;lt;tt&amp;gt;MAPHEAD.BC&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| [[Spear of Destiny]] || All || External || &amp;lt;tt&amp;gt;MAPHEAD.SOD&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=2| [[Wolfenstein 3-D]] || Shareware || External || &amp;lt;tt&amp;gt;MAPHEAD.WL1&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|-&lt;br /&gt;
| Registered || External || &amp;lt;tt&amp;gt;MAPHEAD.WL6&amp;lt;/tt&amp;gt; || - ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Utilities ==&lt;br /&gt;
&lt;br /&gt;
* [[TED5]] can edit the &amp;lt;tt&amp;gt;GAMEMAPS&amp;lt;/tt&amp;gt; format of any games that use it.  It is the original editor used to create these files.&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
This file format was reverse engineered by Andrew Durdin (adurdin).  If you find this information helpful in a project you&#039;re working on, please give credit where credit is due.  (A link back to this wiki would be nice too!)&lt;/div&gt;</summary>
		<author><name>VKokielov</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=EGAGraph_Format&amp;diff=10857</id>
		<title>EGAGraph Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=EGAGraph_Format&amp;diff=10857"/>
		<updated>2023-01-17T17:59:40Z</updated>

		<summary type="html">&lt;p&gt;VKokielov: sprites missing from list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Tileset Infobox&lt;br /&gt;
 | ImageNativeWidth = Y&lt;br /&gt;
 | Hardware1 = VGA&lt;br /&gt;
 | Palette = External&lt;br /&gt;
 | Names = N&lt;br /&gt;
 | HasTransparency = Y&lt;br /&gt;
 | Metadata = None&lt;br /&gt;
 | Subtilesets = N&lt;br /&gt;
 | Compressed = Y&lt;br /&gt;
 | Hidden = N&lt;br /&gt;
 | Games =&lt;br /&gt;
   {{Game|Catacomb 3-D}}&lt;br /&gt;
   {{Game|Catacomb Abyss}}&lt;br /&gt;
   {{Game|Commander Keen 4-6}}&lt;br /&gt;
   {{Game|Commander Keen Dreams}}&lt;br /&gt;
   {{Game|Dangerous Dave 3}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EGAGraph&#039;&#039;&#039;, short for &#039;EGA graphics library&#039; is the format used to store graphics, demos, fonts, game texts and more in many early [[:Category:Id Software|id Software]] games.&lt;br /&gt;
&lt;br /&gt;
The basic format is that of a number of [[Huffman Compression]] compressed sub-files (Chunks) stored in a similar manner to the [[AudioT Format]]. Like this format it has three main files, &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;EGAHEAD&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EGADICT&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is notable that while the &amp;lt;tt&amp;gt;EGAHEAD&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;EGADICT&amp;lt;/tt&amp;gt; are stored in the game executable, they need to be extracted for [[TED5]] to edit levels.&lt;br /&gt;
&lt;br /&gt;
This article may contain errors as some formats have not been worked out completely.&lt;br /&gt;
&lt;br /&gt;
== EGA Head (EGAHEAD.xxx) ==&lt;br /&gt;
&lt;br /&gt;
There are two versions of this format. The first version, used in [[Commander Keen Dreams]], [[Dangerous Dave 3]] and [[Dangerous Dave 4]], is an array of 4-byte little-endian values. The second version, used in all later EGA games, is an array of 3-byte unsigned little-endian values.&lt;br /&gt;
&lt;br /&gt;
This header file may be present as an external file (eg. [[Bio Menace]]), or it may be included in the EXE file (eg. [[Catacomb 3-D]]). The last entry in the header is always the size of the EGAGRAPH.xxx file, and the first entry in the header is always 00 00 00. To find the end, you can search for filesize(EGAGRAPH.xxx) as a 3-byte (little-endian) value in the EXE. Then to find the start, go back 3 bytes at a time until you get to 00 000 00. Or use the fact that entries always get smaller as you go back, unless the entry is $FFFFFF. &lt;br /&gt;
&lt;br /&gt;
In [[Catacomb 3-D]] v1.00 &amp;lt;tt&amp;gt;EGAHEAD.C3D&amp;lt;/tt&amp;gt; is at $1BFD0 from the start of the decompressed ([[unlzexe]]) EXE file, and is 1437 bytes long, or 479 3-byte entries (for 478 chunks). It is then followed by 3 zero bytes (padding to multiple of 16?) 00 00 00, then the &amp;lt;tt&amp;gt;MAPHEAD.C3D&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
In [[Catacomb Abyss]] v1.13 &amp;lt;tt&amp;gt;EGAHEAD.ABS&amp;lt;/tt&amp;gt; is at $1BDB0 from the start of the decompressed ([[unlzexe]]) EXE file, and 1881 bytes long and has 626 chunks.&lt;br /&gt;
&lt;br /&gt;
In [[Catacomb Apocalypse]] v1.00b &amp;lt;tt&amp;gt;EGAHEAD.APC&amp;lt;/tt&amp;gt; is at $1E270 from the start of the decompressed ([[unlzexe]]) EXE file, and 2049 bytes long and has 682 chunks.&lt;br /&gt;
&lt;br /&gt;
This header file stores the offsets (relative to the start of the &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt; file) for each sub file.  The format is trivial, in that the header file is simply an array of 3 or 4 byte variables.  (Each variable is a &amp;quot;slot&amp;quot;, as the game refers to files by index.) Most games use the more compact 3-byte variables, since the &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt; file is never larger than $FFFFFF. However games based on older engines, notably [[Commander Keen Dreams]], [[Dangerous Dave 3]] and [[Dangerous Dave 4]], use 4-byte vales as these are easier to deal with.&lt;br /&gt;
&lt;br /&gt;
It is important to note that not every &#039;slot&#039; will be in use. Tiles especially if blank (All black) will be considered &#039;empty&#039; and not worth adding to the file. (A blank 16x16 tile takes up 12 bytes of space if compressed, and there can be hundreds.) There are two ways of dealing with this; by default the games set all empty slot headers to -1, but many programs compress the graphics anyway and use a normal header value for them.&lt;br /&gt;
&lt;br /&gt;
The last offset in the file will be an offset to the end of the main &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt; file.  (So this should be ignored when reading the file to prevent a zero-byte file appearing last.) The total size of the &amp;lt;tt&amp;gt;EGAHEAD&amp;lt;/tt&amp;gt; divided by 3 (Or 4) will also give the number of &#039;slots&#039; the game uses. This varies, but is usually about 10,000.&lt;br /&gt;
&lt;br /&gt;
Unlike [[AudioT Format]] files, &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt; is always compressed. However the header and dictionary may be external (E.g [[Bio Menace]])&lt;br /&gt;
&lt;br /&gt;
== Dictionary (EGADICT.xxx) ==&lt;br /&gt;
&lt;br /&gt;
The same [[Huffman Compression]] scheme used elsewhere in the [[Commander Keen]] series is used.  When reading compressed chunks out of the &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt; file, the first four bytes located at the &amp;lt;tt&amp;gt;EGAHEAD&amp;lt;/tt&amp;gt; offset are a UINT32LE specifying the file&#039;s decompressed size (which is required for the decompression algorithm.)  The compressed data then follows, EXCEPT for 16x16 masked and unmasked tiles. Since these all have a similar decompressed size (128 bytes for unmasked, 256 bytes for masked) it is a waste of space to include these (Since tiles make up the bulk of graphics slots.) The decompressed size is hard coded, as are the start and finish of the unmasked and masked tile slots.&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;lt;tt&amp;gt;EGADICT&amp;lt;/tt&amp;gt; file is not often obvious, usually being embedded in the main exe file. It is possible to locate it by looking for the string &amp;lt;tt&amp;gt;$FD $01 $00 $00 $00 $00&amp;lt;/tt&amp;gt;, which appears at the end of nearly all Huffman dictionaries. They are the last 6 bytes out of 1024 (256*2*2), so add 6 and subtract 1024 to get the start (pointer to the head node).&lt;br /&gt;
&lt;br /&gt;
Executables usually contain two or more dictionaries, but the &amp;lt;tt&amp;gt;EGADICT&amp;lt;/tt&amp;gt; is usually &#039;&#039;&#039;the second one&#039;&#039;&#039;, except in the case of early games like Keen Dreams, where it is the first of THREE. (A simple check of whether it decompresses the data sensibly works.)&lt;br /&gt;
&lt;br /&gt;
In [[Catacomb 3-D]] &amp;lt;tt&amp;gt;EGADICT.C3D&amp;lt;/tt&amp;gt; is at offset $24464 from the start of the decompressed CAT3D.EXE, which is the second Huffman dictionary and comes immediately after the first Huffman Dictionary.&lt;br /&gt;
&lt;br /&gt;
In [[Catacomb Abyss]] v1.13 &amp;lt;tt&amp;gt;EGADICT.ABS&amp;lt;/tt&amp;gt; is at offset $2734C from the start of the decompressed CATABYSS.EXE, which is the second Huffman dictionary.&lt;br /&gt;
&lt;br /&gt;
In [[Catacomb Apocalypse]] v1.00b &amp;lt;tt&amp;gt;EGADICT.APC&amp;lt;/tt&amp;gt; is at offset $26B24 from the start of the decompressed CATAPOC.EXE, which is the second Huffman dictionary.&lt;br /&gt;
&lt;br /&gt;
== Main file (EGAGRAPH.xxx) ==&lt;br /&gt;
&lt;br /&gt;
This file is simply an array of data files.  Each file starts at the offset specified in the &amp;lt;tt&amp;gt;EGAHEAD&amp;lt;/tt&amp;gt; file, and as there are no filenames each file is referred to by its index/slot number.  Slots containing dummy values in the header are treated as if they don&#039;t exist in the &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt; file. Each file within the &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt; file is individually compressed.  A file can be read by opening the &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt; file, seeking to the offset specified in the &amp;lt;tt&amp;gt;EGAHEAD&amp;lt;/tt&amp;gt; file, reading a UINT32LE for the decompressed file size, and then decompressing the data from that point onwards using standard Huffman decompression techniques.&lt;br /&gt;
&lt;br /&gt;
Note that in early games such as Keen Dreams, the &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt; file may have another name. (Such as &amp;lt;tt&amp;gt;KDREAMS.EGA&amp;lt;/tt&amp;gt; in that case.) in which case it is always the largest non-executable file.&lt;br /&gt;
&lt;br /&gt;
=== Chunks ===&lt;br /&gt;
&lt;br /&gt;
Each sub file or chunk is a separate graphic, ordered in the &amp;lt;tt&amp;gt;EGAGRAPH&amp;lt;/tt&amp;gt; file in a specific way, much again like the [[AudioT Format]].  Chunks are labeled starting at 0. The game executable is hard coded for the start and finish of various chunk types. For example, Keen 4 has chunks 124-520 as sprites and will treat any chunk between these two numbers as a sprite. (Note that the game refers to chunk number, not sprite number.) The usual order of chunks is:&lt;br /&gt;
&lt;br /&gt;
 Picture table&lt;br /&gt;
 Masked picture table&lt;br /&gt;
 Sprite table&lt;br /&gt;
 Fonts&lt;br /&gt;
 Pictures (Unmasked bitmaps)&lt;br /&gt;
 Masked pictures&lt;br /&gt;
 Sprites&lt;br /&gt;
 8x8 unmasked tiles (Single chunk)&lt;br /&gt;
 8x8 masked tiles (Single chunk)&lt;br /&gt;
 16x16 unmasked tiles&lt;br /&gt;
 16x16 masked tiles&lt;br /&gt;
 32x32 unmasked tiles (Optional)&lt;br /&gt;
 32x32 masked tiles (Optional)&lt;br /&gt;
 Misc graphics (Optional)&lt;br /&gt;
 Game texts&lt;br /&gt;
 Demo files (Optional)&lt;br /&gt;
 Misc data (Optional)&lt;br /&gt;
&lt;br /&gt;
== Chunk formats ==&lt;br /&gt;
&lt;br /&gt;
When compressed each chunk consists of a dword giving the decompressed size followed by the compressed data.&lt;br /&gt;
&lt;br /&gt;
=== Picture table ===&lt;br /&gt;
&lt;br /&gt;
Always present and always the first chunk, the picture table is 4 * numpics bytes long, consisting of two words for each picture (Width\8, Height) used when displaying picture chunks.&lt;br /&gt;
&lt;br /&gt;
Divide the decompressed size by 4 to get numpics.&lt;br /&gt;
&lt;br /&gt;
=== Masked picture table ===&lt;br /&gt;
&lt;br /&gt;
Always present and always the second chunk, the picture table is 4 * numpics bytes long, consisting of two words for each picture (Width\8, Height) used when displaying masked picture chunks. This table is often quite small.&lt;br /&gt;
&lt;br /&gt;
=== Sprite table ===&lt;br /&gt;
&lt;br /&gt;
Always present and always the third chunk, the sprite table is 18 * numspr bytes long, consisting of nine words for each sprite image (width\8, height, x offset, y offset, clipping rectangle left, top, right and bottom, and shifts; all in that order.) used when displaying sprite chunks. This is what Modkeen exports as its notoriously hard to use xSPRITES.txt file.&lt;br /&gt;
&lt;br /&gt;
=== Fonts ===&lt;br /&gt;
&lt;br /&gt;
Always present and always starting at the fourth chunk. (Chunk 3!) Each chunk is a single monochrome font, containing all the entries from 0-255 for that font. Each &#039;letter&#039; is stored separately and consecutively. A game will have at least one, and usually 3 fonts. The format is version two of [[EGA Font format]]&lt;br /&gt;
&lt;br /&gt;
Fonts are used in the game for game texts. They can be stretched or colored and are always transparent, meaning they look strange when not over a single-color background.&lt;br /&gt;
&lt;br /&gt;
=== Pictures (Bitmaps) ===&lt;br /&gt;
&lt;br /&gt;
These follow game fonts. You need to know how many fonts there are before it to know how what chunk number the first picture is (3+NumFonts).&lt;br /&gt;
&lt;br /&gt;
Bitmaps are stored as standard [[Raw EGA data]], the size of each plane being the decompressed chunk size \ 4. In order to be displayed properly these need information from chunk 0, the picture table. Note that unlike fonts, data does not wrap, so a 4x4 sprite will consist of four planes of four bytes in size, the same as an 8x4 sprite.&lt;br /&gt;
&lt;br /&gt;
Pictures are used for things such as title screens or pictures in game texts. Most of the main menu will consist of pictures. They are also used for the wall textures and sprites in EGA FPS games like [[Catacomb 3-D]], in which case the wall textures usually come near the end of the picture list.&lt;br /&gt;
&lt;br /&gt;
The number of picture chunks is given in chunk 0, the picture table.&lt;br /&gt;
&lt;br /&gt;
=== Masked pictures (Masked bitmaps) ===&lt;br /&gt;
&lt;br /&gt;
These follow Pictures. You need to know how many fonts there are, to know how what chunk number the first Masked picture is (3+NumFonts+numpics).&lt;br /&gt;
&lt;br /&gt;
These are identical to the picture chunks in every respect, except being masked, they consist of five EGA planes, not four. Most games have only one or two of them. They need information from chunk 1, the masked picture table, to be displayed correctly.&lt;br /&gt;
&lt;br /&gt;
The number of Masked pictures is given in Chunk 1.&lt;br /&gt;
&lt;br /&gt;
=== Sprites ===&lt;br /&gt;
&lt;br /&gt;
The first Sprite chunk is at 3+numfonts+numpics+numMaskedPics.&lt;br /&gt;
&lt;br /&gt;
Sprites are exactly identical to masked pictures in format except the game cannot stretch or warp them. Most games use these for enemy, player or item graphics during gameplay. They need information from chunk 2, the sprite table, both to display correctly and to interact correctly, something more complex than masked pictures.&lt;br /&gt;
&lt;br /&gt;
There are usually several hundred sprite chunks, although that&#039;s not always the case, as [[Catacomb 3-D]] only has 3 sprite chunks (used for the PaddleWar game), and [[Catacomb Abyss]] has only one (used for the in-game radar). The number of sprite chunks is given in chunk 2.&lt;br /&gt;
&lt;br /&gt;
=== 8x8 tiles ===&lt;br /&gt;
&lt;br /&gt;
8x8 tiles are used by most games in status windows or foe the borders of message windows in-game. (And occasionally by TED5 to display levels.) There are thus not many of them. ALL the masked or unmasked tiles are one single chunk stored as four and five plane [[Raw EGA data]] respectively. The number of 8x8 unmasked and masked tiles is hard-coded into the executable, but can be worked out by dividing the decompressed chunk size by 32 and 40 (The size of one tile&#039;s data) respectively.&lt;br /&gt;
&lt;br /&gt;
=== 16x16 and 32x32 tiles ===&lt;br /&gt;
&lt;br /&gt;
32x32 tiles are optional and rarely used. 16x16 tiles are only occasionally absent and for most games make up the bulk of graphics. There are usually several thousand entries. Both come in masked and unmasked kinds, just like 8x8 tiles.&lt;br /&gt;
&lt;br /&gt;
These chunks have notable differences. Each tile is an individual chunk and stored as four or five plane [[Raw EGA data]] with a plane size of 128 (16x16) or 512 (32x32). These chunks do NOT have a dword specifying their decompressed size as this is hard-coded into the executable as a space saving measure. (As is the start and finish of unmasked and masked tile chunks.) This can cause problems for editing programs.&lt;br /&gt;
&lt;br /&gt;
Tiles make up the bulk of 2D game levels but are seldom seen elsewhere.&lt;br /&gt;
&lt;br /&gt;
=== Misc graphics ===&lt;br /&gt;
&lt;br /&gt;
Sometimes following tile graphics are miscellaneous graphics, that cannot be handled by the other chunk types. For example, Keen 4-6 has two misc graphics files used for the &#039;COMMANDER KEEN terminator text&#039; intro. These graphics usually have unique formats that fit their function and few have been investigated.&lt;br /&gt;
&lt;br /&gt;
==== Keen 4-6 Intro Bitmaps ====&lt;br /&gt;
&lt;br /&gt;
This is the text that displays after the &#039;Ready, press any key&#039; screen at Keen startup. It is composed of a monochrome bitmap that is scrolled across the screen and distorted for special effects. When displayed it is transparent, with a special palette so it is not black-and-white. It consists of a header followed by RLE compressed monochrome data.&lt;br /&gt;
&lt;br /&gt;
 HEADER:&lt;br /&gt;
 0   2    Img height  Height of the image in pixels&lt;br /&gt;
 2   2    Img width   Width of the image in pixels&lt;br /&gt;
 4   2x   Line point  Pointers to line 1,2,3..etc of data. There will be [Img height] of&lt;br /&gt;
                      these, each 2 bytes long. The first pointer will  have the value&lt;br /&gt;
                      (2 * [Img height] + 4)&lt;br /&gt;
 +2  ?    RLE data    RLE-WM compressed data&lt;br /&gt;
&lt;br /&gt;
 DATA:&lt;br /&gt;
 0   2    Black run   Number of black pixels to write&lt;br /&gt;
 2   2    Not-blk run Number of not-black pixels to write&lt;br /&gt;
 4   2    Black run....&lt;br /&gt;
 ...&lt;br /&gt;
 ..&lt;br /&gt;
 .&lt;br /&gt;
 ?  2     End         $FFFF; end of row.&lt;br /&gt;
&lt;br /&gt;
=== Game texts ===&lt;br /&gt;
&lt;br /&gt;
Also known as ANSII chunks, these are used by the game for things like help screens, and have their own format. In the main they are simply text documents, interspersed with various commands to make things happen. Each file is divided up into a number of &#039;pages&#039; which are moved between by pressing the up/down arrows. Pages can also have action sequences (Repeated each time the page is moved to, you cannot leave a page until the sequence finishes.)&lt;br /&gt;
&lt;br /&gt;
 ^P		First command in every file. Defines a page start&lt;br /&gt;
 ^E		Ends the file&lt;br /&gt;
 ^Cx		Change font color to $x until next page or ^C command&lt;br /&gt;
 ^Gx,y,z	Display (unmasked) picture chunk z at location x,y (in pixels)&lt;br /&gt;
 ^Tx,y,z,t	Display picture chunk z at x,y for z clicks of time&lt;br /&gt;
 ^Bx,y,z,t,b	Fill a width-by-height-pixel rectangle at pixel location x,y (for z clicks of time?) with color $x&lt;br /&gt;
 ^Lx,y		Start text alignment at pixel location x,y.&lt;br /&gt;
&lt;br /&gt;
=== Demo files ===&lt;br /&gt;
&lt;br /&gt;
These files, which can be recorded in several games using the &#039;demo cheat&#039; consist of a series of commands that are played back when a demo is run ingame. (The game is also &#039;derandomized&#039; during recording so all demo playbacks will be predictable.)&lt;br /&gt;
&lt;br /&gt;
The format is quite simple; consisting of two words and a number of byte pairs. The first two bytes store the number of the level to load for the demo, the next two store the length of data to load\play (After this limit is reached the demo will end, whether or not there is any more data to read.) The remaining byte pairs each encode a time and a keypress. The following values are known:&lt;br /&gt;
&lt;br /&gt;
 01	Left&lt;br /&gt;
 04	Up&lt;br /&gt;
 05	Nothing&lt;br /&gt;
 06	Down&lt;br /&gt;
 09	Right&lt;br /&gt;
 15	Ctrl&lt;br /&gt;
 25	Alt&lt;br /&gt;
&lt;br /&gt;
=== Misc files ===&lt;br /&gt;
&lt;br /&gt;
The last few chunks are demo files and occasionally miscellaneous data. Demo file formats are currently unknown but can be recorded using the demo cheat. They contain the level number and difficulty followed by a series of key commands.&lt;br /&gt;
&lt;br /&gt;
== Utilities ==&lt;br /&gt;
&lt;br /&gt;
* [[KeenWiki:ModKeen|ModKeen]] (DOS) and [[KeenWiki:LModKeen|LModKeen]] (Linux/Windows) can be used to modify graphics and text stored in EGAGRAPH.CKx for the Commander Keen [[KeenWiki:Goodbye Galaxy|Goodbye Galaxy]] trilogy.&lt;br /&gt;
* WDC (Windows) can be used to view or modify the graphics in most EGAGRAPH games, including [[Catacomb 3-D]], [[Catacomb Abyss]] and [[Commander Keen 4-6]].&lt;/div&gt;</summary>
		<author><name>VKokielov</name></author>
	</entry>
</feed>