<?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=Lemm</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=Lemm"/>
	<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/wiki/Special:Contributions/Lemm"/>
	<updated>2026-05-14T05:47:48Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.11</generator>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=EGAGraph_Format&amp;diff=5151</id>
		<title>EGAGraph Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=EGAGraph_Format&amp;diff=5151"/>
		<updated>2014-03-02T01:35:11Z</updated>

		<summary type="html">&lt;p&gt;Lemm: /* Misc graphics */  typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Stub}}&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;
&lt;br /&gt;
= File formats =&lt;br /&gt;
&lt;br /&gt;
== EGA Head (EGAHEAD.xxx) ==&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 3D]]). 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 3D]] 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 3D]] &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;KDREAM.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;
 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;
&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;
&lt;br /&gt;
=== Sprite table ===&lt;br /&gt;
&lt;br /&gt;
Always present and always the third chunk, the picture table is 16 * numspr bytes long, consisting of eight words for each sprite image (Width\8, Height, x offset, y offset and clipping rectangle left, top, right and bottom; 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;
&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;
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). In [[Catacomb 3D]] there are 2 fonts.&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 in EGA FPS games like [[Catacomb 3D]], in which case the wall textures come near the end of the picture list (starting from chunk 137 in [[Catacomb 3D]]).&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. Some games (E.g [[Catacomb 3D]] make great use of masked pictures, but most games have only one or two. 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, but [[Catacomb 3D]] only has 3 sprite chunks and they are used for the PaddleWar game (Skulls and Bones). 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;
&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	?&lt;br /&gt;
 ^Lx,y		?&lt;br /&gt;
&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;
&lt;br /&gt;
= Utilities =&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 and text stored in EGAGRAPH for [[Catacomb 3D]] and [[Catacomb Abyss]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Catacomb 3D]]&lt;br /&gt;
[[Category:Catacomb Abyss]]&lt;br /&gt;
[[Category:Commander Keen 4-6]]&lt;br /&gt;
[[Category:Commander Keen Dreams]]&lt;br /&gt;
[[Category:Dangerous Dave 3]]&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Graphics Files]]&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Monster_Bash_Sprite_Format&amp;diff=5007</id>
		<title>Talk:Monster Bash Sprite Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Monster_Bash_Sprite_Format&amp;diff=5007"/>
		<updated>2013-11-01T14:47:38Z</updated>

		<summary type="html">&lt;p&gt;Lemm: Arg, typos and unfinished sentences!  Sorry; I&amp;#039;m tired.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Image Format Flags Field ==&lt;br /&gt;
&lt;br /&gt;
After doing some more analysis of the .exe, I can find two functions responsible for drawing sprites.  The first draws the &amp;quot;white flashed&amp;quot; sprites by copying the transparency mask to all four graphics planes.  The second function, which draws the normal sprites, first applies the mask, and then sets the map mask register based upon the value in the planebit field.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The lower four bytes of the UInt8 &amp;quot;iFlags&amp;quot; field in the image header appear to control the number of shifts.  The high-four bytes (particularly bit 6, 0x40) appear to radically alter the manner in which the sprite is drawn.  I haven&#039;t finished analyzing it yet, but it looks like the &amp;quot;big&amp;quot; sprites have bit 6 set, because the width-optimized drawing code doesn&#039;t handle cases larger than 64 pixels wide (8 bytes wide).&lt;br /&gt;
&lt;br /&gt;
For sprites that don&#039;t have 0x40 set (which appears to be the majority of them in Monster Bash), then the low bit indicates whether or not the sprite has multiple &amp;quot;shifted&amp;quot; source copies or if the sprite is shifted as it is drawn.  If the low bit is not set, then the flags value is either 2, 4, or 8, and this is the number of shifted copies found in memory.  In Monster Bash, this only appears to apply to the &amp;quot;rock,&amp;quot; which has an iFlags of 0x8, indicating 8 shifts. If the low bit is set, then the flags value is 1, meaning that there is only one copy of the sprite in memory, and it is shifted as it is drawn, allowing big sprites, which would take up too much memory if they were pre-shifted, to be drawn smoothly.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;At least for the transparency plane, the function of the planeBits only seems to be to indicate the width of the sprite.&#039;&#039;&#039;  This is evident in the following line of code:&lt;br /&gt;
&lt;br /&gt;
http://pastebin.com/guLjzx5K&lt;br /&gt;
&lt;br /&gt;
We are looking at the start of the function that draws the white-flashed-sprites.  You can see that, at E8DF, where we deal with non-0x40-masked sprites, the planebit is loaded into al and then exchanged into bl in the subsequent instruction.  At E90A and E911, the game jumps to width-optimized drawing instructions based upon the value of bx.  (One jump table is for sprites that are drawn starting at byte-boundaries, which includes pre-shifted sprites and non-shifted sprites that are lucky 1/8th of the time, while the other jump table is for sprites that are drawn off byte-boundaries).&lt;br /&gt;
&lt;br /&gt;
Now looking at how Camoto messes up sprite import:&lt;br /&gt;
&lt;br /&gt;
Here are the first 16 bytes of main_r as analyzed by Wombat.  I&#039;m comparing an unmodified DAT file, and one that has been modified by exporting and then importing main_r as a .PNG.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
Unmodified: . FF6A 0201 2818 00F7 FFFF FF0C 0027 0003&amp;lt;br /&amp;gt;&lt;br /&gt;
Modified: ... FF6A 0201 2818 00F7 FFFF FF0C 0027 0001&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can see that byte 0xF, which is the &amp;quot;plane-bits&amp;quot; of the transparency plane belonging to the frame with Johnny standing to the right, equals 3, meaning that the sprite is three bytes wide.  Camoto changes this to 1, for whatever reason.  The game draws the sprite as an 8-pixel wide strip of garble, because it thinks that the sprite is 8 pixels wide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now in addition to all of that, take a look at E8D9.  For sprites that have multiple shifts, there must be an array of word-length offsets that follows the standard 12-byte header, because SI is set based upon which shift is to be drawn.  (In this case, the shift number is stored in BX and ES:SI points to the graphics source in conventional memory when drawing commences.)  This means that any sprite frame with a flags value of 0x2,0x4,0x8, or 0x42, 0x44, or 0x48 should have an array of words, equal in size to the number of shifts, that slips in between the 12-byte header and the start of the graphics plane.&lt;br /&gt;
[[User:Lemm|Lemm]] ([[User talk:Lemm|talk]]) 14:32, 1 November 2013 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Monster_Bash_Sprite_Format&amp;diff=5006</id>
		<title>Talk:Monster Bash Sprite Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Monster_Bash_Sprite_Format&amp;diff=5006"/>
		<updated>2013-11-01T14:36:34Z</updated>

		<summary type="html">&lt;p&gt;Lemm: /* Image Format Flags Field */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Image Format Flags Field ==&lt;br /&gt;
&lt;br /&gt;
After doing some more analysis of the .exe, I can find two functions responsible for drawing sprites.  The first draws the &amp;quot;white flashed&amp;quot; sprites by copying the transparency mask to all four graphics planes.  The second function, which draws the normal sprites, first applies the mask, and then &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The lower four bytes of the UInt8 &amp;quot;iFlags&amp;quot; field in the image header appear to control the number of shifts.  The high-four bytes (particularly bit 6, 0x40) appear to radically alter the manner in which the sprite is drawn.  I haven&#039;t finished analyzing it yet, but it looks like the &amp;quot;big&amp;quot; sprites have bit 6 set, because the width-optimized drawing code doesn&#039;t handle cases larger than 64 pixels wide (8 bytes wide).&lt;br /&gt;
&lt;br /&gt;
For sprites that don&#039;t have 0x40 set (which appears to be the majority of them in Monster Bash), then the low bit indicates whether or not the sprite has multiple &amp;quot;shifted&amp;quot; source copies or if the sprite is shifted as it is drawn.  If the low bit is not set, then the flags value is either 2, 4, or 8, and this is the number of shifted copies found in memory.  In Monster Bash, this only appears to apply to the &amp;quot;rock,&amp;quot; which has an iFlags of 0x8, indicating 8 shifts. If the low bit is set, then the flags value is 1, meaning that there is only one copy of the sprite in memory, and it is shifted as it is drawn, allowing big sprites, which would take up too much memory if they were pre-shifted, to be drawn smoothly.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;At least for the transparency plane, the function of the planeBits only seems to be to indicate the width of the sprite.&#039;&#039;&#039;  This is evident in the following line of code:&lt;br /&gt;
&lt;br /&gt;
http://pastebin.com/guLjzx5K&lt;br /&gt;
&lt;br /&gt;
We are looking at the start of the function that draws the white-flashed-sprites.  You can see that, at E8DF, where we deal with non-0x40-masked sprites, the planebit is loaded into al and then exchanged into bl in the subsequent instruction.  At E90A and E911, the game jumps to width-optimized drawing instructions based upon the value of bx.  (One jump table is for sprites that are drawn starting at byte-boundaries, which includes pre-shifted sprites and non-shifted sprites that are lucky 1/8th of the time, while the other jump table is for sprites that are drawn off byte-boundaries).&lt;br /&gt;
&lt;br /&gt;
Now looking at how Camoto messes up sprite import:&lt;br /&gt;
&lt;br /&gt;
Here are the first 16 bytes of main_r as analyzed by Wombat.  I&#039;m comparing an unmodified DAT file, and one that has been modified by exporting and then importing main_r as a .PNG.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
Unmodified: . FF6A 0201 2818 00F7 FFFF FF0C 0027 0003&amp;lt;br /&amp;gt;&lt;br /&gt;
Modified: ... FF6A 0201 2818 00F7 FFFF FF0C 0027 0001&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can see that byte 0xF, which is the &amp;quot;plane-bits&amp;quot; of the frame with Johnny standing to the right, equals 3, meaning that the sprite is three bytes wide.  Camoto changes this to 1, for whatever reason.  The game draws the sprite as an 8-pixel wide strip of garble, because it thinks that the sprite is 8 pixels wide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now in addition to all of that, take a look at E8D9.  For sprites that have multiple shifts, there must be an array of word-length offsets that follows the standard 12-byte header, because SI is set based upon which shift is to be drawn.  (In this case, the shift number is stored in BX and ES:SI points to the graphics source in conventional memory when drawing commences.)  This means that any sprite frame with a flags value of 0x2,0x4,0x8, or 0x42, 0x44, or 0x48 should have an array of words, equal in size to the number of shifts, that slips in between the 12-byte header and the start of the graphics plane.&lt;br /&gt;
[[User:Lemm|Lemm]] ([[User talk:Lemm|talk]]) 14:32, 1 November 2013 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Monster_Bash_Sprite_Format&amp;diff=5005</id>
		<title>Talk:Monster Bash Sprite Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Monster_Bash_Sprite_Format&amp;diff=5005"/>
		<updated>2013-11-01T14:32:16Z</updated>

		<summary type="html">&lt;p&gt;Lemm: Sprite Planebits and why Camoto might be messing up.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Image Format Flags Field ==&lt;br /&gt;
&lt;br /&gt;
After doing some more analysis of the .exe, I can find two functions responsible for drawing sprites.  The first draws the &amp;quot;white flashed&amp;quot; sprites by copying the transparency mask to all four graphics planes.  The second function, which draws the normal sprites, first applies the mask, and then &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The lower four bytes of the UInt8 &amp;quot;iFlags&amp;quot; field in the image header appear to control the number of shifts.  The high-four bytes (particularly bit 6, 0x40) appear to radically alter the manner in which the sprite is drawn.  I haven&#039;t finished analyzing it yet, but it looks like the &amp;quot;big&amp;quot; sprites have bit 6 set, because the width-optimized drawing code doesn&#039;t handle cases larger than 64 pixels wide (8 bytes wide).&lt;br /&gt;
&lt;br /&gt;
For sprites that don&#039;t have 0x40 set (which appears to be the majority of them in Monster Bash), then the low bit indicates whether or not the sprite has multiple &amp;quot;shifted&amp;quot; source copies or if the sprite is shifted as it is drawn.  If the low bit is not set, then the flags value is either 2, 4, or 8, and this is the number of shifted copies found in memory.  In Monster Bash, this only appears to apply to the &amp;quot;rock,&amp;quot; which has an iFlags of 0x8, indicating 8 shifts. If the low bit is set, then the flags value is 1, meaning that there is only one copy of the sprite in memory, and it is shifted as it is drawn, allowing big sprites, which would take up too much memory if they were pre-shifted, to be drawn smoothly.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;At least for the transparency plane, the function of the planeBits only seems to be to indicate the width of the sprite.&#039;&#039;&#039;  This is evident in the following line of code:&lt;br /&gt;
&lt;br /&gt;
http://pastebin.com/guLjzx5K&lt;br /&gt;
&lt;br /&gt;
We are looking at the start of the function that draws the white-flashed-sprites.  You can see that, at E8DF, where we deal with non-0x40-masked sprites, the planebit is loaded into al and then exchanged into bl in the subsequent instruction.  At E90A and E911, the game jumps to width-optimized drawing instructions based upon the value of bx.  (One jump table is for sprites that are drawn starting at byte-boundaries, which includes pre-shifted sprites and non-shifted sprites that are lucky 1/8th of the time, while the other jump table is for sprites that are drawn off byte-boundaries).&lt;br /&gt;
&lt;br /&gt;
Now looking at how Camoto messes up sprite import:&lt;br /&gt;
&lt;br /&gt;
Here are the first 16 bytes of main_r as analyzed by Wombat.  I&#039;m comparing an unmodified DAT file, and one that has been modified by exporting and then importing main_r as a .PNG.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
Unmodified: . FF6A 0201 2818 00F7 FFFF FF0C 0027 0003&amp;lt;br /&amp;gt;&lt;br /&gt;
Modified: ... FF6A 0201 2818 00F7 FFFF FF0C 0027 0001&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can see that byte 0xF, which is the &amp;quot;plane-bits&amp;quot; of the frame with Johnny standing to the right, equals 3, meaning that the sprite is three bytes wide.  Camoto changes this to 1, for whatever reason.  The game draws the sprite as an 8-pixel wide strip of garble, because it thinks that the sprite is 8 pixels wide.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now in addition to all of that, take a look at E8D9.  For sprites that have multiple shifts, there must be an array of word-length offsets that follows the standard 12-byte header, because SI is set based upon which shift is to be drawn.  (In this case, the shift number is stored in BX and ES:SI points to the graphics source in conventional memory when drawing commences.)  This means that any sprite frame with a mask-plane planebits value of 0x2,0x4,0x8, or 0x42, 0x44, or 0x48 should have an array of words, equal in size to the number of shifts, that slips in between the 12-byte header and the start of the graphics plane.&lt;br /&gt;
[[User:Lemm|Lemm]] ([[User talk:Lemm|talk]]) 14:32, 1 November 2013 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:DAT_Format_(Monster_Bash)&amp;diff=5004</id>
		<title>Talk:DAT Format (Monster Bash)</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:DAT_Format_(Monster_Bash)&amp;diff=5004"/>
		<updated>2013-11-01T03:34:34Z</updated>

		<summary type="html">&lt;p&gt;Lemm: /* Unused enemy in MB1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== LZW compression ==&lt;br /&gt;
&lt;br /&gt;
Does anyone have another implementation of the deLZW code? I tried porting the code from Gerald Lindsly&#039;s homepage to another programming language and I encountered some problems. I think they are related to those awful word-pointer to byte-pointer to word-pointer casts, but I&#039;m not 100% sure. --[[User:K1n9 Duk3|K1n9 Duk3]] 08:24, 10 March 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
:You could take a look at the [https://github.com/Malvineous/libgamecommon/blob/master/src/lzw.cpp version I used for Camoto] (decompress only) which is extended from [http://warp.povusers.org/EfficientLZW/ EfficientLZW] to work with a couple of games including Monster Bash.  This code doesn&#039;t use pointers but is less efficient as it uses what are effectively resizable arrays.  The Lindsly deLZW code includes the RLE expansion so if you use standard LZW code you&#039;ll need to perform the RLE decoding separately.  LZW is pretty common so you can probably find an existing implementation in your language of choice. -- [[User:Malvineous|Malvineous]] 11:35, 10 March 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
::I got my ported code to work (used the wrong operator precedence somewhere), but thanks anyway. --[[User:K1n9 Duk3|K1n9 Duk3]] 15:55, 10 March 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
== Unused enemy in MB1 ==&lt;br /&gt;
&lt;br /&gt;
It seems that there is code in the Episode 1 .exe for the electrical spark enemy from Episode 2.  The six frames that exist between the spear plat and the snake can be used for this enemy.  Both the horizontal and vertical versions exist.  SparkV occupies the first three frames, while Spark occupies the second triplet.  They have enemy type codes of 0x3F and 0x3E, respectively.&lt;br /&gt;
[[User:Lemm|Lemm]] ([[User talk:Lemm|talk]]) 08:49, 30 October 2013 (GMT)&lt;br /&gt;
&lt;br /&gt;
: What do you mean &amp;quot;the frames between the spear plat and the snake&amp;quot;?  And where are the enemy type codes used?  In a level you can place a spear_plat sprite and/or a snake sprite, but they are referenced by name only, as far as I can tell. -- [[User:Malvineous|Malvineous]] ([[User talk:Malvineous|talk]]) 10:02, 31 October 2013 (GMT)&lt;br /&gt;
&lt;br /&gt;
:: I mean that there are two sprites, named &amp;quot;spark&amp;quot; and &amp;quot;sparkv&amp;quot;, each of which contains three frames.  Based upon the disassembly, the data for these sprites *should* have been entered, in the DAT file, after the spear_plat and before the snake, but no spark data was included.  However, you should be able to place a 3-frame &amp;quot;spark&amp;quot; and a &amp;quot;sparkv&amp;quot; sprite in a level, just as you would any other sprite. [[User:Lemm|Lemm]] ([[User talk:Lemm|talk]]) 03:34, 1 November 2013 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:DAT_Format_(Monster_Bash)&amp;diff=5002</id>
		<title>Talk:DAT Format (Monster Bash)</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:DAT_Format_(Monster_Bash)&amp;diff=5002"/>
		<updated>2013-10-30T08:49:27Z</updated>

		<summary type="html">&lt;p&gt;Lemm: Unused Enemy in MB1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== LZW compression ==&lt;br /&gt;
&lt;br /&gt;
Does anyone have another implementation of the deLZW code? I tried porting the code from Gerald Lindsly&#039;s homepage to another programming language and I encountered some problems. I think they are related to those awful word-pointer to byte-pointer to word-pointer casts, but I&#039;m not 100% sure. --[[User:K1n9 Duk3|K1n9 Duk3]] 08:24, 10 March 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
:You could take a look at the [https://github.com/Malvineous/libgamecommon/blob/master/src/lzw.cpp version I used for Camoto] (decompress only) which is extended from [http://warp.povusers.org/EfficientLZW/ EfficientLZW] to work with a couple of games including Monster Bash.  This code doesn&#039;t use pointers but is less efficient as it uses what are effectively resizable arrays.  The Lindsly deLZW code includes the RLE expansion so if you use standard LZW code you&#039;ll need to perform the RLE decoding separately.  LZW is pretty common so you can probably find an existing implementation in your language of choice. -- [[User:Malvineous|Malvineous]] 11:35, 10 March 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
::I got my ported code to work (used the wrong operator precedence somewhere), but thanks anyway. --[[User:K1n9 Duk3|K1n9 Duk3]] 15:55, 10 March 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
== Unused enemy in MB1 ==&lt;br /&gt;
&lt;br /&gt;
It seems that there is code in the Episode 1 .exe for the electrical spark enemy from Episode 2.  The six frames that exist between the spear plat and the snake can be used for this enemy.  Both the horizontal and vertical versions exist.  SparkV occupies the first three frames, while Spark occupies the second triplet.  They have enemy type codes of 0x3F and 0x3E, respectively.&lt;br /&gt;
[[User:Lemm|Lemm]] ([[User talk:Lemm|talk]]) 08:49, 30 October 2013 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Monster_Bash&amp;diff=4995</id>
		<title>Talk:Monster Bash</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Monster_Bash&amp;diff=4995"/>
		<updated>2013-10-25T06:46:35Z</updated>

		<summary type="html">&lt;p&gt;Lemm: Formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Patching Actor and Sprite Structures in the Executable ==&lt;br /&gt;
&lt;br /&gt;
Animation and actor behaviours in Monster Bash are governed by 10-byte action structures, similar to those found in Commander keen Galaxy, but much simpler.  &lt;br /&gt;
&lt;br /&gt;
 typedef struct action {&lt;br /&gt;
 	void _seg ***left_sprite, _seg ***right_sprite; &lt;br /&gt;
 	uint16_t time;&lt;br /&gt;
 	int (*think)(actor *);&lt;br /&gt;
 	struct action *next;&lt;br /&gt;
 } action_t;&lt;br /&gt;
&lt;br /&gt;
Actions exist in the data segment, and all pointers are 16 bits. In the data segment, Monster bash stores sprite information in linked list of variable-sized nodes.  Each node has the sprite name, a null-terminated list of segment pointers that store the value of the segment where the raw EGA graphics data is for that sprite, an ASCII string with the name of the graphic, and two 16-bit signed integers of unknown function (possibly the sprite &amp;quot;hotspot&amp;quot; x and y coordinates).  There is a second array of near pointers in the data segment, with one entry for each sprite that points to the segment pointer in the linked list.  If the sprite is cached, then this value is set, otherwise it is null.  Finally, the 16-bit left_sprite and right_sprite pointers point to their respective entry in this second array.  Thus, the value in the action structure is a near pointer to a near pointer to a segment pointer!&lt;br /&gt;
&lt;br /&gt;
The other fields are much simpler to understand.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;time&amp;lt;/code&amp;gt; is the length of animation in x&#039;ths of a second.&lt;br /&gt;
* &amp;lt;code&amp;gt;think&amp;lt;/code&amp;gt; is the actor behaviour function that is in use for this animation frame&lt;br /&gt;
* &amp;lt;code&amp;gt;next&amp;lt;/code&amp;gt; is the action structure that the sprite uses when the action timer expires&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is a second array of 6-byte structs that hold animation information for each &amp;quot;group&amp;quot; of frames.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 typedef struct {&lt;br /&gt;
 	void _seg ***first_sprite; // same as the action_t field, references first sprite in spritegroup&lt;br /&gt;
 	char *groupname;&lt;br /&gt;
 	int num_frames;&lt;br /&gt;
 } spritegroup_t;&lt;br /&gt;
&lt;br /&gt;
For whatever reason, the .exe has the names of the spritegroups stored in the data segment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Diving into the .exe to figure out which action belongs to which sprite ===&lt;br /&gt;
&lt;br /&gt;
As an example, I am using the Registered version 2.1 of the first episode.  Say we want to find the actions for the green hand.  I am using IDA Free v 5.0 to disassemble the .exe (which has been unpacked by UNP.EXE v 4.11.  At dseg:3FBC, we find the array of spritegroups.  We scroll down until we find the spritegroup that corresponds to the hand.&lt;br /&gt;
&lt;br /&gt;
 dseg:4250                 spritegroup &amp;lt;offset off_244C2, offset aHand_l, 6&amp;gt; ; &amp;quot;hand_l&amp;quot;&lt;br /&gt;
 dseg:4256                 spritegroup &amp;lt;offset off_244B6, offset aHand_r, 6&amp;gt; ; &amp;quot;hand_r&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually, there are two spritegroups for the hand, one for each direction. We see that that left hand sprites start at off_244C2 in the .exe image.  Therefore, we want to look for action structures that have off_244C2 in their left_sprite field.  One such struct exists at dseg:2DAE.   Because all of the hand actions are located next to each other, and all of the right handed values must be between off_244B6 and off_244C0, we can identify which actions belong to the hand. &lt;br /&gt;
&lt;br /&gt;
We know that the first four hand frames are for the walking loop, which would be actions with off_244C2 through off_244C8. The remaining actions likely have to do with the jump sequence, and we can make guesses as to what each action is for based upon the frame field content.&lt;br /&gt;
&lt;br /&gt;
 dseg:2DAE ac_hand_walk_0  action &amp;lt;offset off_244C2, offset off_244B6, 50, offset think, \&lt;br /&gt;
 dseg:2DAE                                         ; DATA XREF: dseg:ac_hand_walk_3�o&lt;br /&gt;
 dseg:2DAE                         offset ac_hand_walk_1&amp;gt;&lt;br /&gt;
 dseg:2DB8 ac_hand_walk_1  action &amp;lt;offset off_244C4, offset off_244B8, 50, offset think, \&lt;br /&gt;
 dseg:2DB8                                         ; DATA XREF: dseg:ac_hand_walk_0�o&lt;br /&gt;
 dseg:2DB8                         offset ac_hand_walk_2&amp;gt;&lt;br /&gt;
 dseg:2DC2 ac_hand_walk_2  action &amp;lt;offset off_244C6, offset off_244BA, 50, offset think, \&lt;br /&gt;
 dseg:2DC2                                         ; DATA XREF: dseg:ac_hand_walk_1�o&lt;br /&gt;
 dseg:2DC2                         offset ac_hand_walk_3&amp;gt;&lt;br /&gt;
 dseg:2DCC ac_hand_walk_3  action &amp;lt;offset off_244C8, offset off_244BC, 50, offset think, \&lt;br /&gt;
 dseg:2DCC                                         ; DATA XREF: dseg:ac_hand_walk_2�o&lt;br /&gt;
 dseg:2DCC                         offset ac_hand_walk_0&amp;gt;&lt;br /&gt;
 dseg:2DD6 ac_hand_curl_0  action &amp;lt;offset off_244CC, offset off_244C0, 350, offset think_21, \&lt;br /&gt;
 dseg:2DD6                                         ; DATA XREF: sub_3931+E2�o&lt;br /&gt;
 dseg:2DD6                         offset ac_hand_curl_1&amp;gt;&lt;br /&gt;
 dseg:2DE0 ac_hand_curl_1  action &amp;lt;offset off_244CC, offset off_244C0, 0, offset think_83, \&lt;br /&gt;
 dseg:2DE0                                         ; DATA XREF: dseg:ac_hand_curl_0�o&lt;br /&gt;
 dseg:2DE0                         offset ac_hand_fly_0&amp;gt;&lt;br /&gt;
 dseg:2DEA ac_hand_fly_0   action &amp;lt;offset off_244CA, offset off_244BE, 50, offset think_31, \&lt;br /&gt;
 dseg:2DEA                                         ; DATA XREF: dseg:ac_hand_curl_1�o&lt;br /&gt;
 dseg:2DEA                                         ; dseg:ac_hand_fly_0�o&lt;br /&gt;
 dseg:2DEA                         offset ac_hand_fly_0&amp;gt;&lt;br /&gt;
 dseg:2DF4 ac_hand_fly_1   action &amp;lt;offset off_244CA, offset off_244BE, 50, offset think_32, \&lt;br /&gt;
 dseg:2DF4                                         ; DATA XREF: sub_3931+E7�o&lt;br /&gt;
 dseg:2DF4                                         ; dseg:ac_hand_fly_1�o&lt;br /&gt;
 dseg:2DF4                         offset ac_hand_fly_1&amp;gt;&lt;br /&gt;
 dseg:2DFE ac_hand_fly_2   action &amp;lt;offset off_244C2, offset off_244B6, 300, offset think_31, \&lt;br /&gt;
 dseg:2DFE                                         ; DATA XREF: dseg:ac_hand_fly_2�o&lt;br /&gt;
 dseg:2DFE                         offset ac_hand_fly_2&amp;gt;&lt;br /&gt;
 dseg:2E08 ac_hand_land_0  action &amp;lt;offset off_244CC, offset off_244C0, 50, offset think_32, \&lt;br /&gt;
 dseg:2E08                                         ; DATA XREF: dseg:ac_hand_land_0�o&lt;br /&gt;
 dseg:2E08                         offset ac_hand_land_0&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, it is of use to look at the think functions.   These thinks may be used by multiple actors, but some may be specific to one actor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How would this be used for modding? ===&lt;br /&gt;
&lt;br /&gt;
First of all, a modding program would have to output a patch file to update the spritegroup array.  MBPATCH can use the %patchfile command to patch a binary file generated by the modding program at the appropriate offset (e.g., dseg:2DAE in Monster Bash 1).  As for the modder himself, he would be interested in modifying the action structures.  Sprites, animation timing and loops, and behaviours can all be changed.&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Monster_Bash&amp;diff=4994</id>
		<title>Talk:Monster Bash</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Monster_Bash&amp;diff=4994"/>
		<updated>2013-10-25T06:44:54Z</updated>

		<summary type="html">&lt;p&gt;Lemm: Graphics Disassembly Info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Animation and actor behaviours in Monster Bash are governed by 10-byte action structures, similar to those found in Commander keen Galaxy, but much simpler.  &lt;br /&gt;
&lt;br /&gt;
 typedef struct action {&lt;br /&gt;
 	void _seg ***left_sprite, _seg ***right_sprite; &lt;br /&gt;
 	uint16_t time;&lt;br /&gt;
 	int (*think)(actor *);&lt;br /&gt;
 	struct action *next;&lt;br /&gt;
 } action_t;&lt;br /&gt;
&lt;br /&gt;
Actions exist in the data segment, and all pointers are 16 bits. In the data segment, Monster bash stores sprite information in linked list of variable-sized nodes.  Each node has the sprite name, a null-terminated list of segment pointers that store the value of the segment where the raw EGA graphics data is for that sprite, an ASCII string with the name of the graphic, and two 16-bit signed integers of unknown function (possibly the sprite &amp;quot;hotspot&amp;quot; x and y coordinates).  There is a second array of near pointers in the data segment, with one entry for each sprite that points to the segment pointer in the linked list.  If the sprite is cached, then this value is set, otherwise it is null.  Finally, the 16-bit left_sprite and right_sprite pointers point to their respective entry in this second array.  Thus, the value in the action structure is a near pointer to a near pointer to a segment pointer!&lt;br /&gt;
&lt;br /&gt;
The other fields are much simpler to understand.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;time&amp;lt;/code&amp;gt; is the length of animation in x&#039;ths of a second.&lt;br /&gt;
* &amp;lt;code&amp;gt;think&amp;lt;/code&amp;gt; is the actor behaviour function that is in use for this animation frame&lt;br /&gt;
* &amp;lt;code&amp;gt;next&amp;lt;/code&amp;gt; is the action structure that the sprite uses when the action timer expires&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is a second array of 6-byte structs that hold animation information for each &amp;quot;group&amp;quot; of frames.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 typedef struct {&lt;br /&gt;
 	void _seg ***first_sprite; // same as the action_t field, references first sprite in spritegroup&lt;br /&gt;
 	char *groupname;&lt;br /&gt;
 	int num_frames;&lt;br /&gt;
 } spritegroup_t;&lt;br /&gt;
&lt;br /&gt;
For whatever reason, the .exe has the names of the spritegroups stored in the data segment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*** Diving into the .exe to figure out which action belongs to which sprite ***&lt;br /&gt;
&lt;br /&gt;
As an example, I am using the Registered version 2.1 of the first episode.  Say we want to find the actions for the green hand.  I am using IDA Free v 5.0 to disassemble the .exe (which has been unpacked by UNP.EXE v 4.11.  At dseg:3FBC, we find the array of spritegroups.  We scroll down until we find the spritegroup that corresponds to the hand.&lt;br /&gt;
&lt;br /&gt;
 dseg:4250                 spritegroup &amp;lt;offset off_244C2, offset aHand_l, 6&amp;gt; ; &amp;quot;hand_l&amp;quot;&lt;br /&gt;
 dseg:4256                 spritegroup &amp;lt;offset off_244B6, offset aHand_r, 6&amp;gt; ; &amp;quot;hand_r&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually, there are two spritegroups for the hand, one for each direction. We see that that left hand sprites start at off_244C2 in the .exe image.  Therefore, we want to look for action structures that have off_244C2 in their left_sprite field.  One such struct exists at dseg:2DAE.   Because all of the hand actions are located next to each other, and all of the right handed values must be between off_244B6 and off_244C0, we can identify which actions belong to the hand. &lt;br /&gt;
&lt;br /&gt;
We know that the first four hand frames are for the walking loop, which would be actions with off_244C2 through off_244C8. The remaining actions likely have to do with the jump sequence, and we can make guesses as to what each action is for based upon the frame field content.&lt;br /&gt;
&lt;br /&gt;
 dseg:2DAE ac_hand_walk_0  action &amp;lt;offset off_244C2, offset off_244B6, 50, offset think, \&lt;br /&gt;
 dseg:2DAE                                         ; DATA XREF: dseg:ac_hand_walk_3�o&lt;br /&gt;
 dseg:2DAE                         offset ac_hand_walk_1&amp;gt;&lt;br /&gt;
 dseg:2DB8 ac_hand_walk_1  action &amp;lt;offset off_244C4, offset off_244B8, 50, offset think, \&lt;br /&gt;
 dseg:2DB8                                         ; DATA XREF: dseg:ac_hand_walk_0�o&lt;br /&gt;
 dseg:2DB8                         offset ac_hand_walk_2&amp;gt;&lt;br /&gt;
 dseg:2DC2 ac_hand_walk_2  action &amp;lt;offset off_244C6, offset off_244BA, 50, offset think, \&lt;br /&gt;
 dseg:2DC2                                         ; DATA XREF: dseg:ac_hand_walk_1�o&lt;br /&gt;
 dseg:2DC2                         offset ac_hand_walk_3&amp;gt;&lt;br /&gt;
 dseg:2DCC ac_hand_walk_3  action &amp;lt;offset off_244C8, offset off_244BC, 50, offset think, \&lt;br /&gt;
 dseg:2DCC                                         ; DATA XREF: dseg:ac_hand_walk_2�o&lt;br /&gt;
 dseg:2DCC                         offset ac_hand_walk_0&amp;gt;&lt;br /&gt;
 dseg:2DD6 ac_hand_curl_0  action &amp;lt;offset off_244CC, offset off_244C0, 350, offset think_21, \&lt;br /&gt;
 dseg:2DD6                                         ; DATA XREF: sub_3931+E2�o&lt;br /&gt;
 dseg:2DD6                         offset ac_hand_curl_1&amp;gt;&lt;br /&gt;
 dseg:2DE0 ac_hand_curl_1  action &amp;lt;offset off_244CC, offset off_244C0, 0, offset think_83, \&lt;br /&gt;
 dseg:2DE0                                         ; DATA XREF: dseg:ac_hand_curl_0�o&lt;br /&gt;
 dseg:2DE0                         offset ac_hand_fly_0&amp;gt;&lt;br /&gt;
 dseg:2DEA ac_hand_fly_0   action &amp;lt;offset off_244CA, offset off_244BE, 50, offset think_31, \&lt;br /&gt;
 dseg:2DEA                                         ; DATA XREF: dseg:ac_hand_curl_1�o&lt;br /&gt;
 dseg:2DEA                                         ; dseg:ac_hand_fly_0�o&lt;br /&gt;
 dseg:2DEA                         offset ac_hand_fly_0&amp;gt;&lt;br /&gt;
 dseg:2DF4 ac_hand_fly_1   action &amp;lt;offset off_244CA, offset off_244BE, 50, offset think_32, \&lt;br /&gt;
 dseg:2DF4                                         ; DATA XREF: sub_3931+E7�o&lt;br /&gt;
 dseg:2DF4                                         ; dseg:ac_hand_fly_1�o&lt;br /&gt;
 dseg:2DF4                         offset ac_hand_fly_1&amp;gt;&lt;br /&gt;
 dseg:2DFE ac_hand_fly_2   action &amp;lt;offset off_244C2, offset off_244B6, 300, offset think_31, \&lt;br /&gt;
 dseg:2DFE                                         ; DATA XREF: dseg:ac_hand_fly_2�o&lt;br /&gt;
 dseg:2DFE                         offset ac_hand_fly_2&amp;gt;&lt;br /&gt;
 dseg:2E08 ac_hand_land_0  action &amp;lt;offset off_244CC, offset off_244C0, 50, offset think_32, \&lt;br /&gt;
 dseg:2E08                                         ; DATA XREF: dseg:ac_hand_land_0�o&lt;br /&gt;
 dseg:2E08                         offset ac_hand_land_0&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, it is of use to look at the think functions.   These thinks may be used by multiple actors, but some may be specific to one actor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== How would this be used for modding? ===&lt;br /&gt;
&lt;br /&gt;
First of all, a modding program would have to output a patch file to update the spritegroup array.  MBPATCH can use the %patchfile command to patch a binary file generated by the modding program at the appropriate offset (e.g., dseg:2DAE in Monster Bash 1).  As for the modder himself, he would be interested in modifying the action structures.  Sprites, animation timing and loops, and behaviours can all be changed.&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=B800_Text&amp;diff=4471</id>
		<title>B800 Text</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=B800_Text&amp;diff=4471"/>
		<updated>2013-01-05T19:13:09Z</updated>

		<summary type="html">&lt;p&gt;Lemm: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;B800 Text&#039;&#039;&#039; is a text-mode screen dump, and under x86 real mode (such as used by DOS) can be copied byte for byte into memory starting at &amp;lt;tt&amp;gt;B800:0000&amp;lt;/tt&amp;gt;, causing the data to appear on the screen.  It is most often used to display the final text screen after quitting a game, with the DOS prompt appearing on the last line once the game has terminated.&lt;br /&gt;
&lt;br /&gt;
== File format ==&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;border-style: none; float: right; clear: right; margin-left: 1.5em; text-align:center; hspace=10px&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | &amp;lt;nowiki&amp;gt;Full CGA 16-color palette&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color: white; background-color: #000000&amp;quot; | 0 — black&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#000000&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| style=&amp;quot;color: white; background-color: #555555&amp;quot; | 8 — (dark) gray&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#555555&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color: white; background-color: #0000AA&amp;quot; | 1 — blue&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#0000AA&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| style=&amp;quot;color: white; background-color: #5555FF&amp;quot; | 9 — bright blue&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#5555FF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color: white; background-color: #00AA00&amp;quot; | 2 — green&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#00AA00&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| style=&amp;quot;color: black; background-color: #55FF55&amp;quot; | 10 — bright green&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#55FF55&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color: white; background-color: #00AAAA&amp;quot; | 3 — cyan&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#00AAAA&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| style=&amp;quot;color: black; background-color: #55FFFF&amp;quot; | 11 — bright cyan&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#55FFFF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color: white; background-color: #AA0000&amp;quot; | 4 — red&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#AA0000&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| style=&amp;quot;color: black; background-color: #FF5555&amp;quot; | 12 — bright red&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#FF5555&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color: white; background-color: #AA00AA&amp;quot; | 5 — magenta&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#AA00AA&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| style=&amp;quot;color: black; background-color: #FF55FF&amp;quot; | 13 — bright magenta&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#FF55FF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color: white; background-color: #AA5500&amp;quot; | 6 — brown&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#AA5500&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| style=&amp;quot;color: black; background-color: #FFFF55&amp;quot; | 14 — yellow&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#FFFF55&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;color: black; background-color: #AAAAAA&amp;quot; | 7 — white (light gray)&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#AAAAAA&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| style=&amp;quot;color: black; background-color: #FFFFFF&amp;quot; | 15 — bright white&amp;lt;br /&amp;gt;&amp;lt;nowiki&amp;gt;#FFFFFF&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Since the file format is just a direct dump of video memory, this would more accurately be termed the &amp;quot;CGA text mode format.&amp;quot;  The file is almost always 4000 bytes long, as this is the exact amount of space required to store a standard 80x25 text screen (80 columns * 25 rows * two bytes per cell == 4000 bytes.)&lt;br /&gt;
&lt;br /&gt;
The data is arranged in cells, with each cell being two bytes long (one byte for the ASCII character to display, followed by an attribute byte indicating the colour of the character.)  The data appears starting at the top-left of the screen (1,1) and works its way across to the right (80,1) and then wraps down to the next line (1,2).&lt;br /&gt;
&lt;br /&gt;
The attribute byte contains two nybbles of data.  The most significant four bits are the background colour, and the least significant bits are the foreground colour.  This means the background and foreground colours can each be assigned a colour value between zero (black) and 15 (white) - see the table on the right for the full list of colours.&lt;br /&gt;
&lt;br /&gt;
The background colour is slightly different however.  Since the original CGA hardware was not designed to produce high intensity background colours the intensity bit is used to cause the text to flash instead.  This means setting the background colour to 14 won&#039;t produce a bright-yellow background, but instead will produce a normal yellow background (colour #6) with blinking text.  The VGA standard includes a toggle bit that allows this flashing to be switched off, thus allowing the full 16 background colours to be used (without any flashing of course.)&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
As a demonstration, these bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
48 1E  65 2E  6C 3E  6C 4E  6F 5E        H.e.l.l.o.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Would appear like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background-color: black; padding: 4px; font-size: 14pt; width: 20em;&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;&amp;lt;b&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;lt;span style=&amp;quot;background-color: #0000AA; color: #FFFF55&amp;quot;&amp;gt;H&amp;lt;span style=&amp;quot;background-color: #00AA00;&amp;quot;&amp;gt;e&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;background-color: #00AAAA;&amp;quot;&amp;gt;l&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;background-color: #AA0000;&amp;quot;&amp;gt;l&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;background-color: #AA00AA;&amp;quot;&amp;gt;o&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/b&amp;gt;&amp;lt;/tt&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The following tools are known to work with this format:&lt;br /&gt;
&lt;br /&gt;
* [http://en.wikipedia.org/wiki/TheDraw TheDraw] - DOS-based text animation/screen editor, which does support B800 text and many other DOS formats.  TheDraw also runs under DOSBox.&lt;br /&gt;
* [http://www.theabsolute.net/sware/oldfav.html TextPaint] - DOS-based text screen editor, which unfortunately doesn&#039;t support B800 text but is still very powerful, and useful enough to warrant a mention.&lt;br /&gt;
* [http://dlc.softwareload.de/SHMANSi/5597 Shmansi] - Another DOS-based text screen editor, which can import and export B800 text.&lt;br /&gt;
* [http://www.doomworld.com/idgames/index.php?id=3692 ENDOOMER]- Yet another DOS-based text screen editor, which can import and export B800 text, and can be used with the mouse as well.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Wikipedia:Color Graphics Adapter]] - lots of interesting information about the CGA hardware&lt;br /&gt;
* [[Wikipedia:ANSI art]] - An article about ANSI art&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Graphics Files]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- All the games that use this file format --&amp;gt;&lt;br /&gt;
[[Category:Blake Stone]]&lt;br /&gt;
[[Category:Boppin&#039;]]&lt;br /&gt;
[[Category:Commander Keen 1-3]]&lt;br /&gt;
[[Category:Commander Keen Dreams]]&lt;br /&gt;
[[Category:Commander Keen 4-6]]&lt;br /&gt;
[[Category:Cosmo&#039;s Cosmic Adventures]]&lt;br /&gt;
[[Category:Crystal Caves]]&lt;br /&gt;
[[Category:Descent]]&lt;br /&gt;
[[Category:Duke Nukem II]]&lt;br /&gt;
[[Category:Duke Nukem 3D]]&lt;br /&gt;
[[Category:Halloween Harry]]&lt;br /&gt;
[[Category:Hocus Pocus]]&lt;br /&gt;
[[Category:Jill of the Jungle]]&lt;br /&gt;
[[Category:Kiloblaster]]&lt;br /&gt;
[[Category:Major Stryker]]&lt;br /&gt;
[[Category:Monster Bash]]&lt;br /&gt;
[[Category:Raptor]]&lt;br /&gt;
[[Category:Rise of the Triad]]&lt;br /&gt;
[[Category:Secret Agent]]&lt;br /&gt;
[[Category:Terminal Velocity]]&lt;br /&gt;
[[Category:Vinyl Goddess From Mars]]&lt;br /&gt;
[[Category:Wacky Wheels]]&lt;br /&gt;
[[Category:Wolfenstein 3-D]]&lt;br /&gt;
[[Category:Xargon]]&lt;br /&gt;
[[Category:Zone 66]]&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Crystal_Caves_Map_Format&amp;diff=3458</id>
		<title>Crystal Caves Map Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Crystal_Caves_Map_Format&amp;diff=3458"/>
		<updated>2011-06-19T03:05:31Z</updated>

		<summary type="html">&lt;p&gt;Lemm: map height&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{NeedMoreInfo}}&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Crystal Caves Map Format&#039;&#039; describes a particular section of data within the main [[Crystal Caves]] executable file, where the game levels are stored.  Each level is 40 tiles wide and a varying number of tiles high.&lt;br /&gt;
&lt;br /&gt;
== Location ==&lt;br /&gt;
&lt;br /&gt;
The levels are stored inside the executable. To view them, the executable must be decompressed (UNP&#039;d; UNLZEXE works fine for this.) After decompression, the levels for episodes 1 and 2 are stored at offset 0x8C30 (seg000:7332) or 0x8CE0 (depending on the decompression utility) and take up just under 17kB of space. The levels for episode 3 are stored at offset 0x8F24 in the UNLZEXE&#039;d executable.&lt;br /&gt;
&lt;br /&gt;
There are 19 levels, including the main map and two story levels (used at the start and end of the game.)  Each level is stored in order, beginning with the introduction/story, finale/story, main map, then level 1, 2, 3, etc.&lt;br /&gt;
&lt;br /&gt;
The number of rows for each map is hard-coded into the executable as machine instructions, not as an array of heights for each level.  Practically, this makes it very hard to increase a level&#039;s height.  It is believed that all levels are 24 rows high, with the following exceptions:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Level !! Height&lt;br /&gt;
|-&lt;br /&gt;
| Intro || 5&lt;br /&gt;
|-&lt;br /&gt;
| Finale || 6&lt;br /&gt;
|-&lt;br /&gt;
| Main map || 25&lt;br /&gt;
|-&lt;br /&gt;
| Level 7 || 23&lt;br /&gt;
|-&lt;br /&gt;
| Level 8 || 23&lt;br /&gt;
|-&lt;br /&gt;
| Level 14 || 23&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
Each map is made up of a variable number of Pascal-style strings, one for each row.  This string format contains no terminating 0x00, but rather stores the string length in the first byte.  Thus each row of each level begins with the byte 0x28 (decimal 40, the map width.)  Each subsequent byte in the string represents a single 16x16 tile.&lt;br /&gt;
&lt;br /&gt;
=== Map codes ===&lt;br /&gt;
&lt;br /&gt;
There is currently no known formula to convert map codes into tileset indices.  Maps use byte 0x20 for &#039;no tile&#039; (drawn with some background image), which maps to different images depending on the area within the level, so there must be some other data controlling which background tiles to use in which areas.&lt;br /&gt;
&lt;br /&gt;
==== BlitzMax Code ====&lt;br /&gt;
&lt;br /&gt;
This is the code of a very simple map viewer for Crystal Caves. You need to convert the tile graphics from &amp;lt;tt&amp;gt;CC1.GFX&amp;lt;/tt&amp;gt; to PNG with Wombat and UNLZEXE the executable to use this code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&#039;Crystal Caves Map Viewer&lt;br /&gt;
&#039;by K1n9_Duk3&lt;br /&gt;
&lt;br /&gt;
SuperStrict&lt;br /&gt;
&lt;br /&gt;
Local TileImg:TImage = LoadAnimImage(&amp;quot;cc1.gfx.png&amp;quot;, 16, 16, 0, 1150)&lt;br /&gt;
Local in:TStream = ReadFile(&amp;quot;CC1-UNLZ.EXE&amp;quot;)&lt;br /&gt;
Local Maps:Byte[800, 40]&lt;br /&gt;
&lt;br /&gt;
Local MaxY:Int&lt;br /&gt;
&lt;br /&gt;
If in&lt;br /&gt;
	SeekStream(in, $8ce0)	&#039;CC1 &amp;amp; CC2&lt;br /&gt;
&#039;	SeekStream(in, $8f24)	&#039;CC3&lt;br /&gt;
	Local y:Int&lt;br /&gt;
	Repeat&lt;br /&gt;
		If ReadByte(in) &amp;lt;&amp;gt; 40 Then Exit&lt;br /&gt;
		&lt;br /&gt;
		Local s$ = &amp;quot;&amp;quot;&lt;br /&gt;
		For Local x:Int = 0 Until 40&lt;br /&gt;
			Local b:Byte = ReadByte(in)&lt;br /&gt;
			Maps[y, x] = b&lt;br /&gt;
		Next&lt;br /&gt;
		y :+ 1&lt;br /&gt;
		&lt;br /&gt;
		MaxY = y&lt;br /&gt;
	Forever&lt;br /&gt;
	CloseFile(in)&lt;br /&gt;
Else&lt;br /&gt;
	End&lt;br /&gt;
EndIf&lt;br /&gt;
&lt;br /&gt;
AppTitle = &amp;quot;Crystal Caves Map Viewer&amp;quot;&lt;br /&gt;
Graphics 640, 480&lt;br /&gt;
	&lt;br /&gt;
SetClsColor(128, 128, 128)&lt;br /&gt;
&lt;br /&gt;
Local CamY:Int&lt;br /&gt;
Local Textmode:Byte&lt;br /&gt;
	&lt;br /&gt;
Repeat&lt;br /&gt;
	Cls&lt;br /&gt;
	For Local y:Int = 0 Until 30&lt;br /&gt;
		For Local x:Int = 0 Until 40&lt;br /&gt;
			Local MapTile:Byte = Maps[y+CamY, x]&lt;br /&gt;
			Local TileIndex:Int = -1&lt;br /&gt;
			&lt;br /&gt;
			Select MapTile&lt;br /&gt;
&lt;br /&gt;
			&#039;Crystals (indices for CC1):&lt;br /&gt;
			Case $52	TileIndex =  600&lt;br /&gt;
			Case $2B	TileIndex =  601&lt;br /&gt;
			Case $62	TileIndex =  602&lt;br /&gt;
			Case $63	TileIndex =  603&lt;br /&gt;
				&lt;br /&gt;
			&#039;Walls (indices for magenta walls):&lt;br /&gt;
			Case $72	TileIndex = 1100&lt;br /&gt;
			Case $74	TileIndex = 1101&lt;br /&gt;
			Case $79	TileIndex = 1102&lt;br /&gt;
			Case $66	TileIndex = 1104&lt;br /&gt;
			Case $67	TileIndex = 1105&lt;br /&gt;
			Case $68	TileIndex = 1106&lt;br /&gt;
			Case $34	TileIndex = 1108&lt;br /&gt;
			Case $35	TileIndex = 1109&lt;br /&gt;
			Case $36	TileIndex = 1110&lt;br /&gt;
			&lt;br /&gt;
			&#039;Metal beams (indices for blue beams):&lt;br /&gt;
			Case $44	TileIndex =  953&lt;br /&gt;
			Case $64	TileIndex =  954&lt;br /&gt;
			Case $98	TileIndex =  953	&#039;with hidden crystal&lt;br /&gt;
			Case $99	TileIndex =  954	&#039;with hidden crystal&lt;br /&gt;
			Case $9A	TileIndex =  955	&#039;with hidden crystal&lt;br /&gt;
			&lt;br /&gt;
			&#039;Small platform (blue index):&lt;br /&gt;
			Case $5F	TileIndex =  950&lt;br /&gt;
			&lt;br /&gt;
			&#039;Other Stuff:&lt;br /&gt;
			Case $21	TileIndex =  650&lt;br /&gt;
			Case $22	TileIndex =  630&lt;br /&gt;
			Case $23	TileIndex =  124&lt;br /&gt;
			Case $24	TileIndex =  860&lt;br /&gt;
			Case $25	TileIndex =  539&lt;br /&gt;
			Case $26	TileIndex =  662&lt;br /&gt;
			Case $28	TileIndex =  184&lt;br /&gt;
			Case $29	TileIndex =  185&lt;br /&gt;
			Case $2A	TileIndex =  105&lt;br /&gt;
			Case $2C	TileIndex =  537&lt;br /&gt;
			Case $2D	TileIndex =  536&lt;br /&gt;
			Case $2E	TileIndex =  538&lt;br /&gt;
			Case $2F	TileIndex =  480&lt;br /&gt;
			Case $30	TileIndex =   43&lt;br /&gt;
			Case $38	TileIndex =   34&lt;br /&gt;
			Case $39	TileIndex =   96&lt;br /&gt;
			Case $3A	TileIndex =  629&lt;br /&gt;
			Case $3D	TileIndex =  689&lt;br /&gt;
			Case $3F	TileIndex =   50&lt;br /&gt;
			Case $41	TileIndex =  882&lt;br /&gt;
			Case $42	TileIndex =    6&lt;br /&gt;
			Case $45	TileIndex =  680&lt;br /&gt;
			Case $46	TileIndex =  470&lt;br /&gt;
			Case $47	TileIndex =  298&lt;br /&gt;
			Case $48	TileIndex =  590&lt;br /&gt;
			Case $49	TileIndex =  233&lt;br /&gt;
			Case $4A	TileIndex =  453&lt;br /&gt;
			Case $4B	TileIndex = 1050&lt;br /&gt;
			Case $4C	TileIndex = 1051&lt;br /&gt;
			Case $4D	TileIndex =  300&lt;br /&gt;
			Case $53	TileIndex =  154&lt;br /&gt;
			Case $56, $D7, $D6	TileIndex =  594&lt;br /&gt;
			Case $57	TileIndex =  150&lt;br /&gt;
			Case $58	TileIndex =  562&lt;br /&gt;
			Case $59	TileIndex =  250&lt;br /&gt;
			Case $5D	TileIndex =  299&lt;br /&gt;
			Case $5E	TileIndex =  201&lt;br /&gt;
			Case $61, $71, $82	TileIndex =  560&lt;br /&gt;
			Case $69	TileIndex =  674&lt;br /&gt;
			Case $6A	TileIndex =  605&lt;br /&gt;
			Case $6B	TileIndex = 1052&lt;br /&gt;
			Case $6C	TileIndex = 1053&lt;br /&gt;
			Case $6F	TileIndex =  100&lt;br /&gt;
			Case $70	TileIndex =  604&lt;br /&gt;
			Case $73, $77, $84	TileIndex =  559				&lt;br /&gt;
			Case $76	TileIndex =  580&lt;br /&gt;
			Case $78	TileIndex =   12&lt;br /&gt;
			Case $7C	TileIndex =  184&lt;br /&gt;
			Case $7E	TileIndex =  212&lt;br /&gt;
			Case $85&lt;br /&gt;
				TileIndex =    427&lt;br /&gt;
				If Maps[y+CamY+1, x] &amp;lt;&amp;gt; $85 Then TileIndex = 431&lt;br /&gt;
			Case $86&lt;br /&gt;
				TileIndex =    422&lt;br /&gt;
				If Maps[y+CamY+1, x] &amp;lt;&amp;gt; $86 Then TileIndex = 423&lt;br /&gt;
			Case $87&lt;br /&gt;
				TileIndex =    0&lt;br /&gt;
				If Maps[y+CamY+1, x] &amp;lt;&amp;gt; $87 Then TileIndex = 4&lt;br /&gt;
			Case $88&lt;br /&gt;
				TileIndex =    1&lt;br /&gt;
				If Maps[y+CamY+1, x] &amp;lt;&amp;gt; $88 Then TileIndex = 5&lt;br /&gt;
			Case $89	TileIndex =  558&lt;br /&gt;
			Case $8A	TileIndex =  554&lt;br /&gt;
			Case $8B	TileIndex =    3&lt;br /&gt;
			Case $8C	TileIndex =  587&lt;br /&gt;
			Case $90	TileIndex =  386&lt;br /&gt;
			Case $91	TileIndex =  499&lt;br /&gt;
			Case $92	TileIndex =  476&lt;br /&gt;
			Case $93	TileIndex =  477&lt;br /&gt;
			Case $94	TileIndex =  378&lt;br /&gt;
			Case $95	TileIndex =  379&lt;br /&gt;
			Case $A0	TileIndex =  416&lt;br /&gt;
			Case $A1	TileIndex =  420&lt;br /&gt;
			Case $A2	TileIndex =  418&lt;br /&gt;
			Case $A3	TileIndex =  424&lt;br /&gt;
			Case $A4	TileIndex =  426&lt;br /&gt;
			Case $A5	TileIndex =  425&lt;br /&gt;
			Case $A6	TileIndex =  414&lt;br /&gt;
			Case $A7	TileIndex =  649&lt;br /&gt;
			Case $A8	TileIndex =  643&lt;br /&gt;
			Case $A9	TileIndex =  646&lt;br /&gt;
			Case $AA	TileIndex =  648&lt;br /&gt;
			Case $AB	TileIndex =  644&lt;br /&gt;
			Case $AC	TileIndex =  645&lt;br /&gt;
			Case $B0	TileIndex =    2&lt;br /&gt;
			Case $B1	TileIndex =  598&lt;br /&gt;
			Case $B2	TileIndex =  586&lt;br /&gt;
			Case $B3	TileIndex =  856&lt;br /&gt;
			Case $BA	TileIndex =  583&lt;br /&gt;
			Case $BB	TileIndex =  588&lt;br /&gt;
			Case $BC	TileIndex =  589&lt;br /&gt;
			Case $BD	TileIndex =  579&lt;br /&gt;
			Case $BE	TileIndex =  578&lt;br /&gt;
			Case $BF	TileIndex =  540&lt;br /&gt;
			Case $C0	TileIndex =  544&lt;br /&gt;
			Case $C1	TileIndex =  546&lt;br /&gt;
			Case $C2	TileIndex =  547&lt;br /&gt;
			Case $C3	TileIndex = 1057&lt;br /&gt;
			Case $C4	TileIndex = 1061&lt;br /&gt;
			Case $C6	TileIndex =  442&lt;br /&gt;
			Case $CA	TileIndex =  584&lt;br /&gt;
			Case $CB	TileIndex =  582&lt;br /&gt;
			Case $C7	TileIndex =  443&lt;br /&gt;
			Case $CD	TileIndex =  590&lt;br /&gt;
			Case $CE	TileIndex = 1056&lt;br /&gt;
			Case $CF	TileIndex =  543&lt;br /&gt;
			Case $D0	TileIndex =  557&lt;br /&gt;
			Case $D1	TileIndex =  542&lt;br /&gt;
			Case $D5	TileIndex =  639&lt;br /&gt;
			Case $D8	TileIndex =  581&lt;br /&gt;
			Case $D9	TileIndex =  545&lt;br /&gt;
			Case $DA	TileIndex =  541&lt;br /&gt;
			Case $E7	TileIndex =  548&lt;br /&gt;
			Case $E8	TileIndex =  394&lt;br /&gt;
			Case $E9	TileIndex =  395&lt;br /&gt;
			Case $EA	TileIndex =  396&lt;br /&gt;
			Case $EB	TileIndex =  397&lt;br /&gt;
			Case $EC	TileIndex =  398&lt;br /&gt;
			Case $ED	TileIndex =  399&lt;br /&gt;
			Case $F0	TileIndex =  852&lt;br /&gt;
			Case $F3	TileIndex = 1044&lt;br /&gt;
			Case $F4	TileIndex =    8&lt;br /&gt;
			Case $F5	TileIndex =   10&lt;br /&gt;
			Case $F6	TileIndex =  182&lt;br /&gt;
			Case $F7	TileIndex =  183&lt;br /&gt;
			Case $F9	TileIndex =  553&lt;br /&gt;
			Case $FA	TileIndex =  561&lt;br /&gt;
			Case $FB	TileIndex =  585&lt;br /&gt;
			Case $FC	TileIndex =  498&lt;br /&gt;
			Case $FD	TileIndex =  499&lt;br /&gt;
			Case $FE	TileIndex =  476&lt;br /&gt;
			EndSelect&lt;br /&gt;
			&lt;br /&gt;
			&#039;Don&#039;t draw after a $5B value:&lt;br /&gt;
			If Maps[y+CamY, x-1] = $5B Then TileIndex = -1&lt;br /&gt;
			&lt;br /&gt;
			If TileImg And Not Textmode And MapTile = $C5&lt;br /&gt;
				DrawImage(TileImg, x*16, y*16, 536)&lt;br /&gt;
				DrawImage(TileImg, x*16, y*16, 539)&lt;br /&gt;
			ElseIf TileImg And Not Textmode And  TileIndex &amp;gt;= 0&lt;br /&gt;
				DrawImage(TileImg, x*16, y*16, TileIndex)&lt;br /&gt;
			ElseIf MapTile &amp;lt;&amp;gt; $20&lt;br /&gt;
				DrawText(Hex(MapTile)[6..], x*16, y*16+3)&lt;br /&gt;
			EndIf&lt;br /&gt;
		Next&lt;br /&gt;
	Next&lt;br /&gt;
	Flip&lt;br /&gt;
	&lt;br /&gt;
	If KeyDown(KEY_DOWN)&lt;br /&gt;
		CamY :+ 1&lt;br /&gt;
		If CamY &amp;gt; MaxY-30 Then CamY = MaxY-30&lt;br /&gt;
	EndIf&lt;br /&gt;
		&lt;br /&gt;
	If KeyDown(KEY_UP)&lt;br /&gt;
		CamY :- 1&lt;br /&gt;
		If CamY &amp;lt; 0 Then CamY = 0&lt;br /&gt;
	EndIf&lt;br /&gt;
		&lt;br /&gt;
	If KeyHit(KEY_TAB)&lt;br /&gt;
		Textmode = Not Textmode&lt;br /&gt;
	EndIf&lt;br /&gt;
Until KeyHit(KEY_ESCAPE) Or AppTerminate()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
The location of the map data was discovered by [[User:Lemm|Lemm]].  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;br /&gt;
&lt;br /&gt;
[[Category:Crystal Caves]]&lt;br /&gt;
[[Category:Map Files]]&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=3457</id>
		<title>Talk:Crystal Caves</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=3457"/>
		<updated>2011-06-18T12:23:56Z</updated>

		<summary type="html">&lt;p&gt;Lemm: there i go again, forgetting to sign things&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;No modding tools exist for Crystal Caves, correct?&lt;br /&gt;
&lt;br /&gt;
Also, it appears that the levels are located in the UNP&#039;d executable starting at seg000:7332 (or $8C30 in the UNP&#039;d exe).  I believe tiles are stored as byte values, in pascal strings.  Each row of tiles is 40 long, so there is an array of strings of length 41.  Also, just looking at the ASCII representation of the hex values, you can clearly see the outline of the main level.  Therefore, this should be easily patchable using a CKPATCH like utility.&lt;br /&gt;
&lt;br /&gt;
 (2222222222222222222222222222222222222222&lt;br /&gt;
 (                                        &lt;br /&gt;
 (     Y                     ÛÜ           &lt;br /&gt;
 (                               [A       &lt;br /&gt;
 (                               nn       &lt;br /&gt;
 (Dddddddddddddddddddddddddddddddddddddddn &lt;br /&gt;
 (                           ÛÜ           &lt;br /&gt;
 (                               Y        &lt;br /&gt;
 (        [5                              &lt;br /&gt;
 (        [B                              &lt;br /&gt;
 (        nn                              &lt;br /&gt;
 (z   mN                                 z&lt;br /&gt;
 (z                                      z&lt;br /&gt;
 (z                            un        z&lt;br /&gt;
 (z Y                          Žn        z&lt;br /&gt;
 (zZZZZZZZ[mZZZZZZZZZZZZZZZZZZnnnZZZZZZZz&lt;br /&gt;
 (lklklklklklklklklkKlkLKlkLKlkLKlkLKk kLk&lt;br /&gt;
 (k        Õ     Õ         Õ    [d       L&lt;br /&gt;
 (l    x              x            ±±±±± l&lt;br /&gt;
 (LÕ  ±±±  H  ±±±±±±±±±±±±±±±±±     ðn ² k&lt;br /&gt;
 (K    ²       ðn   x       ðn    ú ³nx²Æk&lt;br /&gt;
 (kù  ±±± [d   ³n  ±±±±  Õ  ³n   ±±±±±±± L&lt;br /&gt;
 (lú   ²     Õ ³n   ðn      ³n      ðn ² l&lt;br /&gt;
 (Lùù x²x      ³n   ³n ù    ³n  ú   ³nx² k&lt;br /&gt;
 (k±±±±±±±±±±±±±±±±±±±±±±   ³n ùùú  ³n±±VK&lt;br /&gt;
 (l  ðnÕ   Õðn  ²Õ          ±±±±±±±±±±±± k&lt;br /&gt;
 (kx ³n     ³n x²      x    ²   ðn  ðn   l&lt;br /&gt;
 (K±±±±±   ±±±±±±±  ±±±±±±±±²x  ³n  ³n   K&lt;br /&gt;
 (k  ðnÕ   Õðn  ²      ðn Õ ±±±±±±±±±±±± k&lt;br /&gt;
 (Lx ³n     ³n x²x ù   ³n             x² K&lt;br /&gt;
 (l±±±±± V ±±±±±±±±±±±±±±±±±±±±±±±±±±±±± k&lt;br /&gt;
 (k  ðn          [4n       ðn      ðn    L&lt;br /&gt;
 (Kx ³n      Õ         Õ   ³n  Õ   ³n Õ  L&lt;br /&gt;
 (kK ³n                    ³n      ³n    k&lt;br /&gt;
 (lKkLkKklKLklKLKkKlkLKlkLKlkLKlkLKlkLKlkl&lt;br /&gt;
 (1111111111111111111111111111111111111111&lt;br /&gt;
&lt;br /&gt;
[[User:Lemm|Lemm]] 13:31, 9 December 2009 (GMT)&lt;br /&gt;
&lt;br /&gt;
Nifty. There are a handful of graphics editors for it, but nothing else. This should help with level editing muchly. -- [[User:Draik|Draik]] 05:33, 10 December 2009 (GMT)&lt;br /&gt;
&lt;br /&gt;
:How many versions of Crystal Caves are there?  In my unlzexe&#039;d version the level data starts at 0x8CE0 instead.  The levels seem to be of varying height though - the map is 36 rows high, most of the levels are 24 rows high but either e1l6 or e1l7 seems to be only 23 rows high.  Maybe there&#039;s an array somewhere with all the level heights? -- [[User:Malvineous|Malvineous]] 13:25, 9 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
:: Here are my guesstimations based on the look of each level.  Map is 36 tiles high, levels 7, 8 and 14 are 23 tiles high, and the rest are 24 tiles high. -- [[User:Malvineous|Malvineous]] 13:43, 9 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
:::Be aware that UNP and Unlzexe don&#039;t create the same output on the same input! [[User:Calvero|Calvero]] 11:48, 10 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
:::: Yes that&#039;s true, but I&#039;m not sure if there&#039;s a way around that either.  I believe it&#039;s the segment offsets that are different, so perhaps there&#039;s a list of these segment offsets in the .exe header that could be used?  I wonder whether it&#039;s possible to take advantage of this to manually relocate or resize a segment, in order to fit more data in it?  Because at the moment the levels could only be edited in-place, there&#039;s no way to adjust the level size. -- [[User:Malvineous|Malvineous]] 12:01, 10 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
:: Hehe.  There appears to be a setup_level function in the executable (CC1: seg000:B1A9) that takes the level number as an argument.  A large switch/case statement loads each row of tiles individually as a string, with each case representing a different level.  There appears to be level -2, -1, 0, and 1 to 16 (these are the acceptable cases).  The strings are loaded by calling load_map_row (row_number, string*) for EACH string, meaning that the map height is actually encoded in the .exe based on however many calls to the load_map_row function are made.  [[User:Lemm|Lemm]] 12:23, 18 June 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Map rendering ==&lt;br /&gt;
&lt;br /&gt;
If anyone has any ideas how to figure out which tile to draw at which map location, do share.  I can&#039;t see any sort of pattern between map values and an index into the tileset, and randomly changing values in the map yields some very strange results for some values! -- [[User:Malvineous|Malvineous]] 12:17, 19 May 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
: I think I&#039;ve found the MacDaddy function that responds to every tile value.  The load_map_row function  (seg000:25F0) that I mentioned above contains what appears to be a monster switch case statement for all the possible tile values, and possible other tile combinations.  The function itself is 0x48F0 (18.6 kB) of mnemonics.  Have fun with that one.  [[User:Lemm|Lemm]] 12:23, 18 June 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
== Graphics editors ==&lt;br /&gt;
&lt;br /&gt;
They can be found over at http://spikenexus.toxicsheep.com/pccw/pages/index.php?page=downloads&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=3456</id>
		<title>Talk:Crystal Caves</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=3456"/>
		<updated>2011-06-18T12:18:12Z</updated>

		<summary type="html">&lt;p&gt;Lemm: .exe functions (should move this entire discussion to CC map format)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;No modding tools exist for Crystal Caves, correct?&lt;br /&gt;
&lt;br /&gt;
Also, it appears that the levels are located in the UNP&#039;d executable starting at seg000:7332 (or $8C30 in the UNP&#039;d exe).  I believe tiles are stored as byte values, in pascal strings.  Each row of tiles is 40 long, so there is an array of strings of length 41.  Also, just looking at the ASCII representation of the hex values, you can clearly see the outline of the main level.  Therefore, this should be easily patchable using a CKPATCH like utility.&lt;br /&gt;
&lt;br /&gt;
 (2222222222222222222222222222222222222222&lt;br /&gt;
 (                                        &lt;br /&gt;
 (     Y                     ÛÜ           &lt;br /&gt;
 (                               [A       &lt;br /&gt;
 (                               nn       &lt;br /&gt;
 (Dddddddddddddddddddddddddddddddddddddddn &lt;br /&gt;
 (                           ÛÜ           &lt;br /&gt;
 (                               Y        &lt;br /&gt;
 (        [5                              &lt;br /&gt;
 (        [B                              &lt;br /&gt;
 (        nn                              &lt;br /&gt;
 (z   mN                                 z&lt;br /&gt;
 (z                                      z&lt;br /&gt;
 (z                            un        z&lt;br /&gt;
 (z Y                          Žn        z&lt;br /&gt;
 (zZZZZZZZ[mZZZZZZZZZZZZZZZZZZnnnZZZZZZZz&lt;br /&gt;
 (lklklklklklklklklkKlkLKlkLKlkLKlkLKk kLk&lt;br /&gt;
 (k        Õ     Õ         Õ    [d       L&lt;br /&gt;
 (l    x              x            ±±±±± l&lt;br /&gt;
 (LÕ  ±±±  H  ±±±±±±±±±±±±±±±±±     ðn ² k&lt;br /&gt;
 (K    ²       ðn   x       ðn    ú ³nx²Æk&lt;br /&gt;
 (kù  ±±± [d   ³n  ±±±±  Õ  ³n   ±±±±±±± L&lt;br /&gt;
 (lú   ²     Õ ³n   ðn      ³n      ðn ² l&lt;br /&gt;
 (Lùù x²x      ³n   ³n ù    ³n  ú   ³nx² k&lt;br /&gt;
 (k±±±±±±±±±±±±±±±±±±±±±±   ³n ùùú  ³n±±VK&lt;br /&gt;
 (l  ðnÕ   Õðn  ²Õ          ±±±±±±±±±±±± k&lt;br /&gt;
 (kx ³n     ³n x²      x    ²   ðn  ðn   l&lt;br /&gt;
 (K±±±±±   ±±±±±±±  ±±±±±±±±²x  ³n  ³n   K&lt;br /&gt;
 (k  ðnÕ   Õðn  ²      ðn Õ ±±±±±±±±±±±± k&lt;br /&gt;
 (Lx ³n     ³n x²x ù   ³n             x² K&lt;br /&gt;
 (l±±±±± V ±±±±±±±±±±±±±±±±±±±±±±±±±±±±± k&lt;br /&gt;
 (k  ðn          [4n       ðn      ðn    L&lt;br /&gt;
 (Kx ³n      Õ         Õ   ³n  Õ   ³n Õ  L&lt;br /&gt;
 (kK ³n                    ³n      ³n    k&lt;br /&gt;
 (lKkLkKklKLklKLKkKlkLKlkLKlkLKlkLKlkLKlkl&lt;br /&gt;
 (1111111111111111111111111111111111111111&lt;br /&gt;
&lt;br /&gt;
[[User:Lemm|Lemm]] 13:31, 9 December 2009 (GMT)&lt;br /&gt;
&lt;br /&gt;
Nifty. There are a handful of graphics editors for it, but nothing else. This should help with level editing muchly. -- [[User:Draik|Draik]] 05:33, 10 December 2009 (GMT)&lt;br /&gt;
&lt;br /&gt;
:How many versions of Crystal Caves are there?  In my unlzexe&#039;d version the level data starts at 0x8CE0 instead.  The levels seem to be of varying height though - the map is 36 rows high, most of the levels are 24 rows high but either e1l6 or e1l7 seems to be only 23 rows high.  Maybe there&#039;s an array somewhere with all the level heights? -- [[User:Malvineous|Malvineous]] 13:25, 9 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
:: Here are my guesstimations based on the look of each level.  Map is 36 tiles high, levels 7, 8 and 14 are 23 tiles high, and the rest are 24 tiles high. -- [[User:Malvineous|Malvineous]] 13:43, 9 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
:::Be aware that UNP and Unlzexe don&#039;t create the same output on the same input! [[User:Calvero|Calvero]] 11:48, 10 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
:::: Yes that&#039;s true, but I&#039;m not sure if there&#039;s a way around that either.  I believe it&#039;s the segment offsets that are different, so perhaps there&#039;s a list of these segment offsets in the .exe header that could be used?  I wonder whether it&#039;s possible to take advantage of this to manually relocate or resize a segment, in order to fit more data in it?  Because at the moment the levels could only be edited in-place, there&#039;s no way to adjust the level size. -- [[User:Malvineous|Malvineous]] 12:01, 10 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
:: Hehe.  There appears to be a setup_level function in the executable (CC1: seg000:B1A9) that takes the level number as an argument.  A large switch/case statement loads each row of tiles individually as a string, with each case representing a different level.  There appears to be level -2, -1, 0, and 1 to 16 (these are the acceptable cases).  The strings are loaded by calling load_map_row (row_number, string*) for EACH string, meaning that the map height is actually encoded in the .exe based on however many calls to the load_map_row function are made.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Map rendering ==&lt;br /&gt;
&lt;br /&gt;
If anyone has any ideas how to figure out which tile to draw at which map location, do share.  I can&#039;t see any sort of pattern between map values and an index into the tileset, and randomly changing values in the map yields some very strange results for some values! -- [[User:Malvineous|Malvineous]] 12:17, 19 May 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
: I think I&#039;ve found the MacDaddy function that responds to every tile value.  The load_map_row function  (seg000:25F0) that I mentioned above contains what appears to be a monster switch case statement for all the possible tile values, and possible other tile combinations.  The function itself is 0x48F0 (18.6 kB) of mnemonics.  Have fun with that one.&lt;br /&gt;
&lt;br /&gt;
== Graphics editors ==&lt;br /&gt;
&lt;br /&gt;
They can be found over at http://spikenexus.toxicsheep.com/pccw/pages/index.php?page=downloads&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Duke_Nukem_II&amp;diff=3296</id>
		<title>Talk:Duke Nukem II</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Duke_Nukem_II&amp;diff=3296"/>
		<updated>2011-03-07T20:56:52Z</updated>

		<summary type="html">&lt;p&gt;Lemm: double slash strings&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;How many versions of the registered game exist?  3D Realms only offers V1.0 for shareware download, and the purchase page for the registered version gives no indication as to the version.&lt;br /&gt;
[[User:Lemm|Lemm]] 06:24, 4 March 2011 (GMT)&lt;br /&gt;
: The [http://www.rinkworks.com/apogee/s/4.1.1.shtml Apogee FAQ] only lists the one version - I guess you could ask Joe Siegler on the 3D Realms forums if you expect there to be others. -- [[User:Malvineous|Malvineous]] 11:43, 4 March 2011 (GMT)&lt;br /&gt;
: I think you should ask [[User:Litude|Litude]]. He usually knows these kind of things. [[User:Frenkel|Frenkel]] 19:58, 4 March 2011 (GMT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are a bunch of text strings in the .exe that start with two slashes (e.g. //APAGE, //FADEIN, etc.).  What do these do? [[User:Lemm|Lemm]] 20:56, 7 March 2011 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Duke_Nukem_II&amp;diff=3293</id>
		<title>Talk:Duke Nukem II</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Duke_Nukem_II&amp;diff=3293"/>
		<updated>2011-03-04T06:24:30Z</updated>

		<summary type="html">&lt;p&gt;Lemm: versions?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;How many versions of the registered game exist?  3D Realms only offers V1.0 for shareware download, and the purchase page for the registered version gives no indication as to the version.&lt;br /&gt;
[[User:Lemm|Lemm]] 06:24, 4 March 2011 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Commander_Keen_4-6&amp;diff=3060</id>
		<title>Talk:Commander Keen 4-6</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Commander_Keen_4-6&amp;diff=3060"/>
		<updated>2010-10-21T08:09:02Z</updated>

		<summary type="html">&lt;p&gt;Lemm: save game format&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Can we get the save game format up here?&lt;br /&gt;
[[User:Lemm|Lemm]] 08:09, 21 October 2010 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:EGAGraph_Format&amp;diff=3008</id>
		<title>Talk:EGAGraph Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:EGAGraph_Format&amp;diff=3008"/>
		<updated>2010-09-03T20:16:28Z</updated>

		<summary type="html">&lt;p&gt;Lemm: xSPRITES&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== xSPRITES.TXT ==&lt;br /&gt;
&lt;br /&gt;
What is the actual content of the sprite table?  The following is from the modkeen document, which does not agree with what is posted on the main page of this artice.  It would suggest that the &amp;quot;shifts&amp;quot; are stored in here as well?  Are they stored somewhere else?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Episodes 4, 5, and 6 only: This file contains extra information about each sprite. Each line in the file has the sprite number, followed by the four clipping rectangle co-ordinates in square brackets [top, left, bottom, right], followed by the sprite origin in square brackets [top, left], followed by the number of shifts the sprite uses. The origin of the sprite image is the point from which its location is calculated. For example, the hand sprite in Keen 5 (5SPR0291.BMP) has several images. The origin for each of these images is in the centre of the &amp;quot;eye&amp;quot;, so that as the hand rotates, the different sprite images all appear to rotate about the eye. The origin coordinates are given in pixels from the top-left corner of the sprite image. The shifts is the number of different copies of the sprite image that are stored in memory, and can be 1, 2, or 4. As a general rule, the more shifts a sprite has, the smoother it moves, but the more memory it takes up. If you are making a very large sprite, you can reduce the number of shifts to save memory. But if you have a small sprite and want it to move more smoothly, increase the number of shifts.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Also from modkeen source:&lt;br /&gt;
&lt;br /&gt;
typedef struct&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
	unsigned short Width;&lt;br /&gt;
&lt;br /&gt;
	unsigned short Height;&lt;br /&gt;
&lt;br /&gt;
	signed short OrgX;&lt;br /&gt;
&lt;br /&gt;
	signed short OrgY;&lt;br /&gt;
&lt;br /&gt;
	signed short Rx1, Ry1;&lt;br /&gt;
&lt;br /&gt;
	signed short Rx2, Ry2;&lt;br /&gt;
&lt;br /&gt;
	unsigned short Shifts;&lt;br /&gt;
&lt;br /&gt;
} SpriteHeadStruct;&lt;br /&gt;
&lt;br /&gt;
Which would make a 9-word structure.&lt;br /&gt;
&lt;br /&gt;
20:16, 3 September 2010 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:IMF_Format&amp;diff=2963</id>
		<title>Talk:IMF Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:IMF_Format&amp;diff=2963"/>
		<updated>2010-07-17T22:34:42Z</updated>

		<summary type="html">&lt;p&gt;Lemm: another question about delay&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As a note, IMFCreator, as far as I have been able to tell, DOES treat the #0 channel correctly, at least in that I have as yet failed to be able to create an IMF file that uses the #0 channel.&lt;br /&gt;
&lt;br /&gt;
It also creates WOLF3D and Duke 2 files (Come on! It&#039;s from the Wolf3D site!) IF the speed is specified in the options menu. (It has seperate options for 280 and 560 Hz, with 700 being the default. You can also set the speed to a custom value.) ~Levellass 20/03/2010&lt;br /&gt;
&lt;br /&gt;
:Oh ok, well as I haven&#039;t used IMFCreator I&#039;m only going by what I&#039;ve heard of other people&#039;s experiences.  I&#039;ll update the table now but please feel free to just make corrections directly in the future if you notice anything like this.  Also do you mean it creates Keen and Duke 2 files?  Because I already listed it as creating Wolf3D files... -- [[User:Malvineous|Malvineous]] 03:39, 21 March 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::I ran some tests on some &amp;quot;complicated&amp;quot; MIDIs and IMFCreator does indeed appear to leave channel #0 free, so I&#039;ve removed the question mark on that, thanks for prodding me into checking :-) -- [[User:Malvineous|Malvineous]] 04:04, 21 March 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is the the [[http://files.commanderkeen.org/users/omp/tsrmusic-july-16.zip music TSR]] for Commander Keen Vorticons with source included.  I don&#039;t know why it lags when playing certain songs like &amp;quot;Make it Tighter.&amp;quot;  It seems to do this in faster songs where the pitch bend is being used.&lt;br /&gt;
[[User:Lemm|Lemm]] 16:41, 17 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delay ==&lt;br /&gt;
&lt;br /&gt;
For the delay, what is meant by the number of cycles?  If the delay is 2, does this mean that next two times the interrupt to play the adlib data is called, you don&#039;t send any data to the adlib port? (Does that even make sense :p) [[User:Lemm|Lemm]] 08:10, 5 June 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
: It depends on what your interrupt rate is.  For Commander Keen the IMF clock rate is 560Hz, so you will have 560 cycles per second.  A delay of two will mean no data is sent for two of these cyles.  A delay of 560 would result in one second of silence. -- [[User:Malvineous|Malvineous]] 09:52, 6 June 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
:: Another question about delays: If a data chunk has a delay of zero, do you wait until the next cycle to play it, or do you keep sending data until you reach a chunk with a delay?  Because that is what the music TSR is doing rigth now and perhaps that could be the reason it lags?&lt;br /&gt;
&lt;br /&gt;
== Types ==&lt;br /&gt;
&lt;br /&gt;
I&#039;ve checked all the IMFs of all the games I have, that is to say every IMF using game except Corridor 7 and Operation Body Count. The type 0s I&#039;ve seen always skip the first two bytes, and games don&#039;t like it when you don&#039;t include them. I&#039;ve been trying to poke around game code to see how it treats the first two bytes, but I&#039;ve only managed to explore Cosmo and Keen 4-6, for Keen at least as near as I can tell it can&#039;t take type 0s at all, simply reading the first two bytes as the length of data to play. (Someone could check this with a Keen engine game like Biomenace or Catacomb 3D)&lt;br /&gt;
&lt;br /&gt;
Also I notice that the Biomenace IMFs have strings in them that seem to give the location of the file, for example xCity.imf has &#039;c:\bhazard\XCITY.IMF&#039; in its tags. -- [[User:Levellass|Levellass]] 05:55, 6 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
: That&#039;s interesting, please post back if you figure out what the two initial zero bytes are for!  I always thought that they replaced the length bytes with 00 00 when it was not required, but it seems that chronologically the type-0 format came first, so this wouldn&#039;t be the case.  It would be interesting to see what happens if you replaced 00 00 with a number that is half the file size - would it be used as the length?  (In which case the song should only play to the middle before it loops and starts again.)&lt;br /&gt;
&lt;br /&gt;
: It seems that most type-1 files have extra data at the end, Wolf 3D is another (that&#039;s one reason why the IMFs floating around from these games have proper filenames, based on those hints.)  As yet nobody knows why the data is there or what it is used for, or even what format it is in.  But apparently it was important enough that they wrote the length bytes at the front so the data could be kept in the file... -- [[User:Malvineous|Malvineous]] 06:08, 6 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::Ok, first up, I don&#039;t have a type-0 playing program, so I can&#039;t tell what it would do with the first two bytes of a type-0 file. Do you know of a type-0 playing program?&lt;br /&gt;
&lt;br /&gt;
::Second, I&#039;ve poked Tom Hall about this, apparently there are exactly four tag strings in the &#039;standard&#039; IMF format ID worked with in this order, a word of unknown use, a 16-byte name string, a 64-byte filename string, and 6 bytes of compiler data. The strings are padded with nuls. (Total 88 bytes) These were put in by the program they used to add IMFs to the sound archive. (Actually copied not from the IMF itself, but taken from some sort of list file and just pasted on to the end of the IMF, some games, especially early ones apparently didn&#039;t use this method and so don&#039;t have this tag data.)&lt;br /&gt;
&lt;br /&gt;
::He doesn&#039;t know where you got the composer thing or the $1A signature, I too am curious as to where that information came from. I&#039;ve checked all the game files I have and I can see no game that uses it, though I was able to confirm Mr Hall&#039;s comments. In theory &#039;your&#039; format could be used harmlessly in files, since games don&#039;t read the tag data at all.&lt;br /&gt;
&lt;br /&gt;
::Oh, and IMf files of duration 0 (All their timer words are 0) crash games or don&#039;t play apparently. Can you confirm this? --[[User:Levellass|Endian? What are you on about?]] 13:14, 15 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::: [[Cosmo&#039;s Cosmic Adventures|Cosmo]] is one game that uses type-0 files and is fairly easy to mod for this sort of test.  Interesting response from Tom Hall, I&#039;ll have to have another look at it.  I think perhaps the fields weren&#039;t always padded with NULLs (rather random junk data) which is why both myself and Simon Peter (AdPlug author) couldn&#039;t figure it out.  The composer tag and $1A signature were purely my own invention as I wanted to tag the files I had with their real names (e.g. for Major Stryker which gives the song titles in-game.)  I haven&#039;t any files with no durations in them, but I am not surprised that it causes problems.  I imagine at each &amp;quot;music tick&amp;quot; in the game code it reads everything up to the next delay, so if there are no delays it could get stuck in an endless loop or reach the end of the file on the first read attempt.  Not sure what your endian comment is in reference to, but there&#039;s an explanation of why it&#039;s important on [[File format data types#Big endian vs little endian]]. -- [[User:Malvineous|Malvineous]] 23:08, 15 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::::Ok then, who&#039;s stupid? I&#039;m stupid. After a lot of confusing and checking and some more talk, I have realized I made a few mistakes. This, as near as I understand it is the difference between the two types:&lt;br /&gt;
&lt;br /&gt;
::::Type 0 came first. It consists of nothing but song data, thus filesize is always divisible by 4. The first 4 bytes are often (Though not necessarily) $00 $00 $00 $00 (A minor exception is Cosmo 1&#039;s MBANJO.IMF) Mr Hall thinks the game just starts reading from byte 0, not skipping anything, but he can&#039;t remember, maybe the first word IS skipped.&lt;br /&gt;
&lt;br /&gt;
::::Type 1 came next, files can be any length because of tags. The first word of the file has a value that divides by 4. Programs that use this type always check the first two bytes THEN go on to play file data. Standard tags added by the compiler add 88 bytes to the file end.&lt;br /&gt;
&lt;br /&gt;
::::This has put a theoretical kink in one of my programs, since it assumes that type-0\type-1 can always be told apart by the first two bytes, but someone would need to deliberately set up a type-0 to be confusing. *Sigh* --[[User:Levellass|Endian? What are you on about?]] 05:26, 16 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::::: As far as I&#039;m aware, checking the first two bytes is enough to tell the format - all the utilities I&#039;ve written as well as AdPlug use this method and I&#039;m not aware of any files that don&#039;t fit.  MBANJO.IMF is fine because the first two bytes are still 0x00 0x00.  I don&#039;t believe the first word is ever skipped, as some of the software synths print errors about register 0x00 being invalid (so AdPlug and others play it.)  I have just tested this by setting the first four bytes in MZZTOP.MNI to 0xB0 0xFF 0x00 0x03 which sets the frequency on channel 0 very high when the first note is played, and inserts a ~2 second delay before the song starts.  I can hear this as a click (after a short delay) on the Cosmo 1 main menu.  This proves that the game does in fact play the first two bytes and treats the following two as a delay.  I guess it is just luck that the first two bytes are always writing 0x00 into the non-existent OPL register 0x00! -- [[User:Malvineous|Malvineous]] 13:32, 16 July 2010 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:IMF_Format&amp;diff=2962</id>
		<title>Talk:IMF Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:IMF_Format&amp;diff=2962"/>
		<updated>2010-07-17T16:41:54Z</updated>

		<summary type="html">&lt;p&gt;Lemm: --&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As a note, IMFCreator, as far as I have been able to tell, DOES treat the #0 channel correctly, at least in that I have as yet failed to be able to create an IMF file that uses the #0 channel.&lt;br /&gt;
&lt;br /&gt;
It also creates WOLF3D and Duke 2 files (Come on! It&#039;s from the Wolf3D site!) IF the speed is specified in the options menu. (It has seperate options for 280 and 560 Hz, with 700 being the default. You can also set the speed to a custom value.) ~Levellass 20/03/2010&lt;br /&gt;
&lt;br /&gt;
:Oh ok, well as I haven&#039;t used IMFCreator I&#039;m only going by what I&#039;ve heard of other people&#039;s experiences.  I&#039;ll update the table now but please feel free to just make corrections directly in the future if you notice anything like this.  Also do you mean it creates Keen and Duke 2 files?  Because I already listed it as creating Wolf3D files... -- [[User:Malvineous|Malvineous]] 03:39, 21 March 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::I ran some tests on some &amp;quot;complicated&amp;quot; MIDIs and IMFCreator does indeed appear to leave channel #0 free, so I&#039;ve removed the question mark on that, thanks for prodding me into checking :-) -- [[User:Malvineous|Malvineous]] 04:04, 21 March 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is the the [[http://files.commanderkeen.org/users/omp/tsrmusic-july-16.zip music TSR]] for Commander Keen Vorticons with source included.  I don&#039;t know why it lags when playing certain songs like &amp;quot;Make it Tighter.&amp;quot;  It seems to do this in faster songs where the pitch bend is being used.&lt;br /&gt;
[[User:Lemm|Lemm]] 16:41, 17 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delay ==&lt;br /&gt;
&lt;br /&gt;
For the delay, what is meant by the number of cycles?  If the delay is 2, does this mean that next two times the interrupt to play the adlib data is called, you don&#039;t send any data to the adlib port? (Does that even make sense :p) [[User:Lemm|Lemm]] 08:10, 5 June 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
: It depends on what your interrupt rate is.  For Commander Keen the IMF clock rate is 560Hz, so you will have 560 cycles per second.  A delay of two will mean no data is sent for two of these cyles.  A delay of 560 would result in one second of silence. -- [[User:Malvineous|Malvineous]] 09:52, 6 June 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
== Types ==&lt;br /&gt;
&lt;br /&gt;
I&#039;ve checked all the IMFs of all the games I have, that is to say every IMF using game except Corridor 7 and Operation Body Count. The type 0s I&#039;ve seen always skip the first two bytes, and games don&#039;t like it when you don&#039;t include them. I&#039;ve been trying to poke around game code to see how it treats the first two bytes, but I&#039;ve only managed to explore Cosmo and Keen 4-6, for Keen at least as near as I can tell it can&#039;t take type 0s at all, simply reading the first two bytes as the length of data to play. (Someone could check this with a Keen engine game like Biomenace or Catacomb 3D)&lt;br /&gt;
&lt;br /&gt;
Also I notice that the Biomenace IMFs have strings in them that seem to give the location of the file, for example xCity.imf has &#039;c:\bhazard\XCITY.IMF&#039; in its tags. -- [[User:Levellass|Levellass]] 05:55, 6 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
: That&#039;s interesting, please post back if you figure out what the two initial zero bytes are for!  I always thought that they replaced the length bytes with 00 00 when it was not required, but it seems that chronologically the type-0 format came first, so this wouldn&#039;t be the case.  It would be interesting to see what happens if you replaced 00 00 with a number that is half the file size - would it be used as the length?  (In which case the song should only play to the middle before it loops and starts again.)&lt;br /&gt;
&lt;br /&gt;
: It seems that most type-1 files have extra data at the end, Wolf 3D is another (that&#039;s one reason why the IMFs floating around from these games have proper filenames, based on those hints.)  As yet nobody knows why the data is there or what it is used for, or even what format it is in.  But apparently it was important enough that they wrote the length bytes at the front so the data could be kept in the file... -- [[User:Malvineous|Malvineous]] 06:08, 6 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::Ok, first up, I don&#039;t have a type-0 playing program, so I can&#039;t tell what it would do with the first two bytes of a type-0 file. Do you know of a type-0 playing program?&lt;br /&gt;
&lt;br /&gt;
::Second, I&#039;ve poked Tom Hall about this, apparently there are exactly four tag strings in the &#039;standard&#039; IMF format ID worked with in this order, a word of unknown use, a 16-byte name string, a 64-byte filename string, and 6 bytes of compiler data. The strings are padded with nuls. (Total 88 bytes) These were put in by the program they used to add IMFs to the sound archive. (Actually copied not from the IMF itself, but taken from some sort of list file and just pasted on to the end of the IMF, some games, especially early ones apparently didn&#039;t use this method and so don&#039;t have this tag data.)&lt;br /&gt;
&lt;br /&gt;
::He doesn&#039;t know where you got the composer thing or the $1A signature, I too am curious as to where that information came from. I&#039;ve checked all the game files I have and I can see no game that uses it, though I was able to confirm Mr Hall&#039;s comments. In theory &#039;your&#039; format could be used harmlessly in files, since games don&#039;t read the tag data at all.&lt;br /&gt;
&lt;br /&gt;
::Oh, and IMf files of duration 0 (All their timer words are 0) crash games or don&#039;t play apparently. Can you confirm this? --[[User:Levellass|Endian? What are you on about?]] 13:14, 15 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::: [[Cosmo&#039;s Cosmic Adventures|Cosmo]] is one game that uses type-0 files and is fairly easy to mod for this sort of test.  Interesting response from Tom Hall, I&#039;ll have to have another look at it.  I think perhaps the fields weren&#039;t always padded with NULLs (rather random junk data) which is why both myself and Simon Peter (AdPlug author) couldn&#039;t figure it out.  The composer tag and $1A signature were purely my own invention as I wanted to tag the files I had with their real names (e.g. for Major Stryker which gives the song titles in-game.)  I haven&#039;t any files with no durations in them, but I am not surprised that it causes problems.  I imagine at each &amp;quot;music tick&amp;quot; in the game code it reads everything up to the next delay, so if there are no delays it could get stuck in an endless loop or reach the end of the file on the first read attempt.  Not sure what your endian comment is in reference to, but there&#039;s an explanation of why it&#039;s important on [[File format data types#Big endian vs little endian]]. -- [[User:Malvineous|Malvineous]] 23:08, 15 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::::Ok then, who&#039;s stupid? I&#039;m stupid. After a lot of confusing and checking and some more talk, I have realized I made a few mistakes. This, as near as I understand it is the difference between the two types:&lt;br /&gt;
&lt;br /&gt;
::::Type 0 came first. It consists of nothing but song data, thus filesize is always divisible by 4. The first 4 bytes are often (Though not necessarily) $00 $00 $00 $00 (A minor exception is Cosmo 1&#039;s MBANJO.IMF) Mr Hall thinks the game just starts reading from byte 0, not skipping anything, but he can&#039;t remember, maybe the first word IS skipped.&lt;br /&gt;
&lt;br /&gt;
::::Type 1 came next, files can be any length because of tags. The first word of the file has a value that divides by 4. Programs that use this type always check the first two bytes THEN go on to play file data. Standard tags added by the compiler add 88 bytes to the file end.&lt;br /&gt;
&lt;br /&gt;
::::This has put a theoretical kink in one of my programs, since it assumes that type-0\type-1 can always be told apart by the first two bytes, but someone would need to deliberately set up a type-0 to be confusing. *Sigh* --[[User:Levellass|Endian? What are you on about?]] 05:26, 16 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::::: As far as I&#039;m aware, checking the first two bytes is enough to tell the format - all the utilities I&#039;ve written as well as AdPlug use this method and I&#039;m not aware of any files that don&#039;t fit.  MBANJO.IMF is fine because the first two bytes are still 0x00 0x00.  I don&#039;t believe the first word is ever skipped, as some of the software synths print errors about register 0x00 being invalid (so AdPlug and others play it.)  I have just tested this by setting the first four bytes in MZZTOP.MNI to 0xB0 0xFF 0x00 0x03 which sets the frequency on channel 0 very high when the first note is played, and inserts a ~2 second delay before the song starts.  I can hear this as a click (after a short delay) on the Cosmo 1 main menu.  This proves that the game does in fact play the first two bytes and treats the following two as a delay.  I guess it is just luck that the first two bytes are always writing 0x00 into the non-existent OPL register 0x00! -- [[User:Malvineous|Malvineous]] 13:32, 16 July 2010 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:IMF_Format&amp;diff=2961</id>
		<title>Talk:IMF Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:IMF_Format&amp;diff=2961"/>
		<updated>2010-07-17T15:21:23Z</updated>

		<summary type="html">&lt;p&gt;Lemm: tsr music HELP&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As a note, IMFCreator, as far as I have been able to tell, DOES treat the #0 channel correctly, at least in that I have as yet failed to be able to create an IMF file that uses the #0 channel.&lt;br /&gt;
&lt;br /&gt;
It also creates WOLF3D and Duke 2 files (Come on! It&#039;s from the Wolf3D site!) IF the speed is specified in the options menu. (It has seperate options for 280 and 560 Hz, with 700 being the default. You can also set the speed to a custom value.) ~Levellass 20/03/2010&lt;br /&gt;
&lt;br /&gt;
:Oh ok, well as I haven&#039;t used IMFCreator I&#039;m only going by what I&#039;ve heard of other people&#039;s experiences.  I&#039;ll update the table now but please feel free to just make corrections directly in the future if you notice anything like this.  Also do you mean it creates Keen and Duke 2 files?  Because I already listed it as creating Wolf3D files... -- [[User:Malvineous|Malvineous]] 03:39, 21 March 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::I ran some tests on some &amp;quot;complicated&amp;quot; MIDIs and IMFCreator does indeed appear to leave channel #0 free, so I&#039;ve removed the question mark on that, thanks for prodding me into checking :-) -- [[User:Malvineous|Malvineous]] 04:04, 21 March 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is the the [[http://files.commanderkeen.org/users/omp/tsrmusic-july-16.zip music TSR]] for Commander Keen Vorticons with source included.  I don&#039;t know why it lags when playing certain songs like &amp;quot;Make it Tighter.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delay ==&lt;br /&gt;
&lt;br /&gt;
For the delay, what is meant by the number of cycles?  If the delay is 2, does this mean that next two times the interrupt to play the adlib data is called, you don&#039;t send any data to the adlib port? (Does that even make sense :p) [[User:Lemm|Lemm]] 08:10, 5 June 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
: It depends on what your interrupt rate is.  For Commander Keen the IMF clock rate is 560Hz, so you will have 560 cycles per second.  A delay of two will mean no data is sent for two of these cyles.  A delay of 560 would result in one second of silence. -- [[User:Malvineous|Malvineous]] 09:52, 6 June 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
== Types ==&lt;br /&gt;
&lt;br /&gt;
I&#039;ve checked all the IMFs of all the games I have, that is to say every IMF using game except Corridor 7 and Operation Body Count. The type 0s I&#039;ve seen always skip the first two bytes, and games don&#039;t like it when you don&#039;t include them. I&#039;ve been trying to poke around game code to see how it treats the first two bytes, but I&#039;ve only managed to explore Cosmo and Keen 4-6, for Keen at least as near as I can tell it can&#039;t take type 0s at all, simply reading the first two bytes as the length of data to play. (Someone could check this with a Keen engine game like Biomenace or Catacomb 3D)&lt;br /&gt;
&lt;br /&gt;
Also I notice that the Biomenace IMFs have strings in them that seem to give the location of the file, for example xCity.imf has &#039;c:\bhazard\XCITY.IMF&#039; in its tags. -- [[User:Levellass|Levellass]] 05:55, 6 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
: That&#039;s interesting, please post back if you figure out what the two initial zero bytes are for!  I always thought that they replaced the length bytes with 00 00 when it was not required, but it seems that chronologically the type-0 format came first, so this wouldn&#039;t be the case.  It would be interesting to see what happens if you replaced 00 00 with a number that is half the file size - would it be used as the length?  (In which case the song should only play to the middle before it loops and starts again.)&lt;br /&gt;
&lt;br /&gt;
: It seems that most type-1 files have extra data at the end, Wolf 3D is another (that&#039;s one reason why the IMFs floating around from these games have proper filenames, based on those hints.)  As yet nobody knows why the data is there or what it is used for, or even what format it is in.  But apparently it was important enough that they wrote the length bytes at the front so the data could be kept in the file... -- [[User:Malvineous|Malvineous]] 06:08, 6 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::Ok, first up, I don&#039;t have a type-0 playing program, so I can&#039;t tell what it would do with the first two bytes of a type-0 file. Do you know of a type-0 playing program?&lt;br /&gt;
&lt;br /&gt;
::Second, I&#039;ve poked Tom Hall about this, apparently there are exactly four tag strings in the &#039;standard&#039; IMF format ID worked with in this order, a word of unknown use, a 16-byte name string, a 64-byte filename string, and 6 bytes of compiler data. The strings are padded with nuls. (Total 88 bytes) These were put in by the program they used to add IMFs to the sound archive. (Actually copied not from the IMF itself, but taken from some sort of list file and just pasted on to the end of the IMF, some games, especially early ones apparently didn&#039;t use this method and so don&#039;t have this tag data.)&lt;br /&gt;
&lt;br /&gt;
::He doesn&#039;t know where you got the composer thing or the $1A signature, I too am curious as to where that information came from. I&#039;ve checked all the game files I have and I can see no game that uses it, though I was able to confirm Mr Hall&#039;s comments. In theory &#039;your&#039; format could be used harmlessly in files, since games don&#039;t read the tag data at all.&lt;br /&gt;
&lt;br /&gt;
::Oh, and IMf files of duration 0 (All their timer words are 0) crash games or don&#039;t play apparently. Can you confirm this? --[[User:Levellass|Endian? What are you on about?]] 13:14, 15 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::: [[Cosmo&#039;s Cosmic Adventures|Cosmo]] is one game that uses type-0 files and is fairly easy to mod for this sort of test.  Interesting response from Tom Hall, I&#039;ll have to have another look at it.  I think perhaps the fields weren&#039;t always padded with NULLs (rather random junk data) which is why both myself and Simon Peter (AdPlug author) couldn&#039;t figure it out.  The composer tag and $1A signature were purely my own invention as I wanted to tag the files I had with their real names (e.g. for Major Stryker which gives the song titles in-game.)  I haven&#039;t any files with no durations in them, but I am not surprised that it causes problems.  I imagine at each &amp;quot;music tick&amp;quot; in the game code it reads everything up to the next delay, so if there are no delays it could get stuck in an endless loop or reach the end of the file on the first read attempt.  Not sure what your endian comment is in reference to, but there&#039;s an explanation of why it&#039;s important on [[File format data types#Big endian vs little endian]]. -- [[User:Malvineous|Malvineous]] 23:08, 15 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::::Ok then, who&#039;s stupid? I&#039;m stupid. After a lot of confusing and checking and some more talk, I have realized I made a few mistakes. This, as near as I understand it is the difference between the two types:&lt;br /&gt;
&lt;br /&gt;
::::Type 0 came first. It consists of nothing but song data, thus filesize is always divisible by 4. The first 4 bytes are often (Though not necessarily) $00 $00 $00 $00 (A minor exception is Cosmo 1&#039;s MBANJO.IMF) Mr Hall thinks the game just starts reading from byte 0, not skipping anything, but he can&#039;t remember, maybe the first word IS skipped.&lt;br /&gt;
&lt;br /&gt;
::::Type 1 came next, files can be any length because of tags. The first word of the file has a value that divides by 4. Programs that use this type always check the first two bytes THEN go on to play file data. Standard tags added by the compiler add 88 bytes to the file end.&lt;br /&gt;
&lt;br /&gt;
::::This has put a theoretical kink in one of my programs, since it assumes that type-0\type-1 can always be told apart by the first two bytes, but someone would need to deliberately set up a type-0 to be confusing. *Sigh* --[[User:Levellass|Endian? What are you on about?]] 05:26, 16 July 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::::: As far as I&#039;m aware, checking the first two bytes is enough to tell the format - all the utilities I&#039;ve written as well as AdPlug use this method and I&#039;m not aware of any files that don&#039;t fit.  MBANJO.IMF is fine because the first two bytes are still 0x00 0x00.  I don&#039;t believe the first word is ever skipped, as some of the software synths print errors about register 0x00 being invalid (so AdPlug and others play it.)  I have just tested this by setting the first four bytes in MZZTOP.MNI to 0xB0 0xFF 0x00 0x03 which sets the frequency on channel 0 very high when the first note is played, and inserts a ~2 second delay before the song starts.  I can hear this as a click (after a short delay) on the Cosmo 1 main menu.  This proves that the game does in fact play the first two bytes and treats the following two as a delay.  I guess it is just luck that the first two bytes are always writing 0x00 into the non-existent OPL register 0x00! -- [[User:Malvineous|Malvineous]] 13:32, 16 July 2010 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=2863</id>
		<title>Talk:Crystal Caves</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=2863"/>
		<updated>2010-06-16T21:42:46Z</updated>

		<summary type="html">&lt;p&gt;Lemm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;No modding tools exist for Crystal Caves, correct?&lt;br /&gt;
&lt;br /&gt;
Also, it appears that the levels are located in the UNP&#039;d executable starting at seg000:7332 (or $8C30 in the UNP&#039;d exe).  I believe tiles are stored as byte values, in pascal strings.  Each row of tiles is 40 long, so there is an array of strings of length 41.  Also, just looking at the ASCII representation of the hex values, you can clearly see the outline of the main level.  Therefore, this should be easily patchable using a CKPATCH like utility.&lt;br /&gt;
&lt;br /&gt;
 (2222222222222222222222222222222222222222&lt;br /&gt;
 (                                        &lt;br /&gt;
 (     Y                     ÛÜ           &lt;br /&gt;
 (                               [A       &lt;br /&gt;
 (                               nn       &lt;br /&gt;
 (Dddddddddddddddddddddddddddddddddddddddn &lt;br /&gt;
 (                           ÛÜ           &lt;br /&gt;
 (                               Y        &lt;br /&gt;
 (        [5                              &lt;br /&gt;
 (        [B                              &lt;br /&gt;
 (        nn                              &lt;br /&gt;
 (z   mN                                 z&lt;br /&gt;
 (z                                      z&lt;br /&gt;
 (z                            un        z&lt;br /&gt;
 (z Y                          Žn        z&lt;br /&gt;
 (zZZZZZZZ[mZZZZZZZZZZZZZZZZZZnnnZZZZZZZz&lt;br /&gt;
 (lklklklklklklklklkKlkLKlkLKlkLKlkLKk kLk&lt;br /&gt;
 (k        Õ     Õ         Õ    [d       L&lt;br /&gt;
 (l    x              x            ±±±±± l&lt;br /&gt;
 (LÕ  ±±±  H  ±±±±±±±±±±±±±±±±±     ðn ² k&lt;br /&gt;
 (K    ²       ðn   x       ðn    ú ³nx²Æk&lt;br /&gt;
 (kù  ±±± [d   ³n  ±±±±  Õ  ³n   ±±±±±±± L&lt;br /&gt;
 (lú   ²     Õ ³n   ðn      ³n      ðn ² l&lt;br /&gt;
 (Lùù x²x      ³n   ³n ù    ³n  ú   ³nx² k&lt;br /&gt;
 (k±±±±±±±±±±±±±±±±±±±±±±   ³n ùùú  ³n±±VK&lt;br /&gt;
 (l  ðnÕ   Õðn  ²Õ          ±±±±±±±±±±±± k&lt;br /&gt;
 (kx ³n     ³n x²      x    ²   ðn  ðn   l&lt;br /&gt;
 (K±±±±±   ±±±±±±±  ±±±±±±±±²x  ³n  ³n   K&lt;br /&gt;
 (k  ðnÕ   Õðn  ²      ðn Õ ±±±±±±±±±±±± k&lt;br /&gt;
 (Lx ³n     ³n x²x ù   ³n             x² K&lt;br /&gt;
 (l±±±±± V ±±±±±±±±±±±±±±±±±±±±±±±±±±±±± k&lt;br /&gt;
 (k  ðn          [4n       ðn      ðn    L&lt;br /&gt;
 (Kx ³n      Õ         Õ   ³n  Õ   ³n Õ  L&lt;br /&gt;
 (kK ³n                    ³n      ³n    k&lt;br /&gt;
 (lKkLkKklKLklKLKkKlkLKlkLKlkLKlkLKlkLKlkl&lt;br /&gt;
 (1111111111111111111111111111111111111111&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[User:Lemm|Lemm]] 13:31, 9 December 2009 (GMT)&lt;br /&gt;
&lt;br /&gt;
Nifty. There are a handful of graphics editors for it, but nothing else. This should help with level editing muchly. -- [[User:Draik|Draik]] 05:33, 10 December 2009 (GMT)&lt;br /&gt;
&lt;br /&gt;
== Graphics editors ==&lt;br /&gt;
&lt;br /&gt;
They can be found over at http://spikenexus.toxicsheep.com/pccw/pages/index.php?page=downloads&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:IMF_Format&amp;diff=2851</id>
		<title>Talk:IMF Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:IMF_Format&amp;diff=2851"/>
		<updated>2010-06-05T08:10:37Z</updated>

		<summary type="html">&lt;p&gt;Lemm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;As a note, IMFCreator, as far as I have been able to tell, DOES treat the #0 channel correctly, at least in that I have as yet failed to be able to create an IMF file that uses the #0 channel.&lt;br /&gt;
&lt;br /&gt;
It also creates WOLF3D and Duke 2 files (Come on! It&#039;s from the Wolf3D site!) IF the speed is specified in the options menu. (It has seperate options for 280 and 560 Hz, with 700 being the default. You can also set the speed to a custom value.) ~Levellass 20/03/2010&lt;br /&gt;
&lt;br /&gt;
:Oh ok, well as I haven&#039;t used IMFCreator I&#039;m only going by what I&#039;ve heard of other people&#039;s experiences.  I&#039;ll update the table now but please feel free to just make corrections directly in the future if you notice anything like this.  Also do you mean it creates Keen and Duke 2 files?  Because I already listed it as creating Wolf3D files... -- [[User:Malvineous|Malvineous]] 03:39, 21 March 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
::I ran some tests on some &amp;quot;complicated&amp;quot; MIDIs and IMFCreator does indeed appear to leave channel #0 free, so I&#039;ve removed the question mark on that, thanks for prodding me into checking :-) -- [[User:Malvineous|Malvineous]] 04:04, 21 March 2010 (GMT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the delay, what is meant by the number of cycles?  If the delay is 2, does this mean that next two times the interrupt to play the adlib data is called, you don&#039;t send any data to the adlib port? (Does that even make sense :p) [[User:Lemm|Lemm]] 08:10, 5 June 2010 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=2648</id>
		<title>Talk:Crystal Caves</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=2648"/>
		<updated>2009-12-09T14:28:22Z</updated>

		<summary type="html">&lt;p&gt;Lemm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;No modding tools exist for Crystal Caves, correct?&lt;br /&gt;
&lt;br /&gt;
Also, it appears that the levels are located in the UNP&#039;d executable starting at seg000:7332 (or $8C30 in the UNP&#039;d exe).  I believe tiles are stored as ASCII values, in pascal strings.  Each row of tiles is 40 long, so there is an array of strings of length 41.  Also, just looking at the ASCII representation of the hex values, you can clearly see the outline of the main level.  Therefore, this should be easily patchable using a CKPATCH like utility.&lt;br /&gt;
&lt;br /&gt;
 (2222222222222222222222222222222222222222&lt;br /&gt;
 (                                        &lt;br /&gt;
 (     Y                     ÛÜ           &lt;br /&gt;
 (                               [A       &lt;br /&gt;
 (                               nn       &lt;br /&gt;
 (Dddddddddddddddddddddddddddddddddddddddn &lt;br /&gt;
 (                           ÛÜ           &lt;br /&gt;
 (                               Y        &lt;br /&gt;
 (        [5                              &lt;br /&gt;
 (        [B                              &lt;br /&gt;
 (        nn                              &lt;br /&gt;
 (z   mN                                 z&lt;br /&gt;
 (z                                      z&lt;br /&gt;
 (z                            un        z&lt;br /&gt;
 (z Y                          Žn        z&lt;br /&gt;
 (zZZZZZZZ[mZZZZZZZZZZZZZZZZZZnnnZZZZZZZz&lt;br /&gt;
 (lklklklklklklklklkKlkLKlkLKlkLKlkLKk kLk&lt;br /&gt;
 (k        Õ     Õ         Õ    [d       L&lt;br /&gt;
 (l    x              x            ±±±±± l&lt;br /&gt;
 (LÕ  ±±±  H  ±±±±±±±±±±±±±±±±±     ðn ² k&lt;br /&gt;
 (K    ²       ðn   x       ðn    ú ³nx²Æk&lt;br /&gt;
 (kù  ±±± [d   ³n  ±±±±  Õ  ³n   ±±±±±±± L&lt;br /&gt;
 (lú   ²     Õ ³n   ðn      ³n      ðn ² l&lt;br /&gt;
 (Lùù x²x      ³n   ³n ù    ³n  ú   ³nx² k&lt;br /&gt;
 (k±±±±±±±±±±±±±±±±±±±±±±   ³n ùùú  ³n±±VK&lt;br /&gt;
 (l  ðnÕ   Õðn  ²Õ          ±±±±±±±±±±±± k&lt;br /&gt;
 (kx ³n     ³n x²      x    ²   ðn  ðn   l&lt;br /&gt;
 (K±±±±±   ±±±±±±±  ±±±±±±±±²x  ³n  ³n   K&lt;br /&gt;
 (k  ðnÕ   Õðn  ²      ðn Õ ±±±±±±±±±±±± k&lt;br /&gt;
 (Lx ³n     ³n x²x ù   ³n             x² K&lt;br /&gt;
 (l±±±±± V ±±±±±±±±±±±±±±±±±±±±±±±±±±±±± k&lt;br /&gt;
 (k  ðn          [4n       ðn      ðn    L&lt;br /&gt;
 (Kx ³n      Õ         Õ   ³n  Õ   ³n Õ  L&lt;br /&gt;
 (kK ³n                    ³n      ³n    k&lt;br /&gt;
 (lKkLkKklKLklKLKkKlkLKlkLKlkLKlkLKlkLKlkl&lt;br /&gt;
 (1111111111111111111111111111111111111111&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[User:Lemm|Lemm]] 13:31, 9 December 2009 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=2647</id>
		<title>Talk:Crystal Caves</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=2647"/>
		<updated>2009-12-09T14:13:08Z</updated>

		<summary type="html">&lt;p&gt;Lemm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;No modding tools exist for Crystal Caves, correct?&lt;br /&gt;
&lt;br /&gt;
Also, it appears that the levels are located in the UNP&#039;d executable starting at seg000:7332.  I believe tiles are stored as ASCII values, in pascal strings.  Each row of tiles is 40 long, so there is an array of strings of length 41.  Also, just looking at the ASCII representation of the hex values, you can clearly see the outline of the main level.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[User:Lemm|Lemm]] 13:31, 9 December 2009 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=2646</id>
		<title>Talk:Crystal Caves</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=2646"/>
		<updated>2009-12-09T13:41:56Z</updated>

		<summary type="html">&lt;p&gt;Lemm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;No modding tools exist for Crystal Caves, correct?&lt;br /&gt;
Also, it appears that the levels are located in the UNP&#039;d executable starting at 7332h&lt;br /&gt;
[[User:Lemm|Lemm]] 13:31, 9 December 2009 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=2645</id>
		<title>Talk:Crystal Caves</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Crystal_Caves&amp;diff=2645"/>
		<updated>2009-12-09T13:31:30Z</updated>

		<summary type="html">&lt;p&gt;Lemm: Created page with &amp;#039;No modding tools exist for Crystal Caves, correct? ~~~~&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;No modding tools exist for Crystal Caves, correct?&lt;br /&gt;
[[User:Lemm|Lemm]] 13:31, 9 December 2009 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=User:Lemm&amp;diff=2603</id>
		<title>User:Lemm</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=User:Lemm&amp;diff=2603"/>
		<updated>2009-10-31T14:06:13Z</updated>

		<summary type="html">&lt;p&gt;Lemm: Created page with &amp;#039;wat&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;wat&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:Id_Software_RLEW_compression&amp;diff=2602</id>
		<title>Talk:Id Software RLEW compression</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:Id_Software_RLEW_compression&amp;diff=2602"/>
		<updated>2009-10-31T14:04:42Z</updated>

		<summary type="html">&lt;p&gt;Lemm: Created page with &amp;#039;In Keen Dreams, it seems that Word2 is copied, Word 1 number of times. --~~~~&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In Keen Dreams, it seems that Word2 is copied, Word 1 number of times.&lt;br /&gt;
--[[User:Lemm|Lemm]] 14:04, 31 October 2009 (GMT)&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=Talk:GameMaps_Format&amp;diff=2601</id>
		<title>Talk:GameMaps Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=Talk:GameMaps_Format&amp;diff=2601"/>
		<updated>2009-10-31T12:42:54Z</updated>

		<summary type="html">&lt;p&gt;Lemm: Created page with &amp;#039;The values in that table are also good for Keen Dreams, except for the !ID! tag.&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The values in that table are also good for Keen Dreams, except for the !ID! tag.&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=GameMaps_Format&amp;diff=2600</id>
		<title>GameMaps Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=GameMaps_Format&amp;diff=2600"/>
		<updated>2009-10-31T12:38:31Z</updated>

		<summary type="html">&lt;p&gt;Lemm: /* Compression in GAMEMAPS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The map data for [[Commander Keen 4-6]] is mainly stored in the &amp;lt;tt&amp;gt;GAMEMAPS.CKx&amp;lt;/tt&amp;gt; file. This stores all the maps of the levels used in the game. The GAMEMAPS file is read and decompressed using data stored in the &amp;lt;tt&amp;gt;MAPHEAD.CKx&amp;lt;/tt&amp;gt; file. The file&#039;s start is easily located as it always begins with the word $ABCD followed by several dwords and a lot of blank space. In the 1.4 versions of Keen 4-6 (Dumped executable) the file starts at the following:&lt;br /&gt;
&lt;br /&gt;
  Keen 4: $24830&lt;br /&gt;
  Keen 5: $25990&lt;br /&gt;
  Keen 6: $25080&lt;br /&gt;
 (Keen D: $1FA50)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Map headers ==&lt;br /&gt;
&lt;br /&gt;
In Keen, as in most games, the &amp;lt;tt&amp;gt;MAPHEAD&amp;lt;/tt&amp;gt; file is 402 bytes long, consisting of a word and 100 level dwords.&lt;br /&gt;
&lt;br /&gt;
The first word is the flag for [[RLEW compression]], used to compress the &amp;lt;tt&amp;gt;GAMEMAPS&amp;lt;/tt&amp;gt; file. By default this is $ABCD (This can be changed.). The remaining dwords point to the headers of each level in the &amp;lt;tt&amp;gt;GAMEMAPS&amp;lt;/tt&amp;gt; file. (Nonexistent levels have a dword, value of -1 so this fills most of the file.) The file thus has space for 256 levels.&lt;br /&gt;
&lt;br /&gt;
== GAMEMAPS Format ==&lt;br /&gt;
&lt;br /&gt;
The structure of the &amp;lt;tt&amp;gt;GAMEMAPS&amp;lt;/tt&amp;gt; file is disordered due to the fact that the level headers and level data can be located in any place in any order. The usual structure consists of a variable string of TED settings (&#039;TEDv1.0...&#039;) followed by the levels in no particular order. Each level usually consists of the level header followed by three planes of data, though not always.&lt;br /&gt;
&lt;br /&gt;
The TED settings are unimportant and can usually be ignored. (Though in some cases TED may use them.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Levels in GAMEMAPS ===&lt;br /&gt;
&lt;br /&gt;
The header for each level that is pointed to by MAPHEAD is 42 bytes long:&lt;br /&gt;
&lt;br /&gt;
 0   4    Offset in GAMEMAPS to beginning of compressed plane 0 data&lt;br /&gt;
 4   4    Offset in GAMEMAPS to beginning of compressed plane 1 data&lt;br /&gt;
 8   4    Offset in GAMEMAPS to beginning of compressed plane 2 data&lt;br /&gt;
 12  2    Length of compressed plane 0 data (in bytes)&lt;br /&gt;
 14  2    Length of compressed plane 1 data (in bytes)&lt;br /&gt;
 16  2    Length of compressed plane 2 data (ib bytes)&lt;br /&gt;
 18  2    Width of level (in tiles)&lt;br /&gt;
 20  2    Height of level (in tiles)&lt;br /&gt;
 22  16   Internal name for level (used only by editor, not displayed in-game. null-terminated)&lt;br /&gt;
 38  4    Signature &amp;quot;!ID!&amp;quot;&lt;br /&gt;
 42  x    Level data, three planes RLEW and Carmack compressed&lt;br /&gt;
&lt;br /&gt;
The presence of the level name and the signature are not required by the Keen engine to play the level. Plane 0 is the &#039;background&#039; plane, plane 1 is the &#039;foreground&#039; plane, and plane 2 is the &#039;info&#039; plane. Each is compressed separately, as described below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Compression in GAMEMAPS ===&lt;br /&gt;
&lt;br /&gt;
Each plane is compressed with two successive compression algorithms. The first is [[RLEW compression]], identical to that used in [[Commander Keen 1-3]], except that the magic word (Flag.) is different. (It is specified in the MAPHEAD file, rather than always being xFEFE.) The second is [[Carmack compression]].&lt;br /&gt;
&lt;br /&gt;
The order of compression is RLEW followed by Carmack. One must also keep in mind that each compression algorithm outputs as its first word the length of the uncompressed data. So in the GAMEMAPS file for a particular plane of a particular level, the first word is the number of bytes in the RLEW-compressed data, and the first word of the RLEW-compressed data is the number of bytes in the uncompressed data.&lt;br /&gt;
&lt;br /&gt;
(Note: In Keen Dreams, Huffman Compression is used in place of Carmack Compression.  An array of bytes at $1FBE2 in the executable contains the lengths of the compressed level headers.)&lt;br /&gt;
&lt;br /&gt;
== Utilities ==&lt;br /&gt;
&lt;br /&gt;
[[TED5]] This program 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 crate these files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
This format was reverse engineered by Andrew Durdin (adurdin).&lt;br /&gt;
&lt;br /&gt;
The format is used by other games as well, including [[Bio Menace]], [[Catacomb 3D]], [[Dangerous Dave 3]], [[Dave Goes Nutz]], and [[Wolfenstein 3D]]&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
	<entry>
		<id>https://moddingwiki.shikadi.net/w/index.php?title=GameMaps_Format&amp;diff=2599</id>
		<title>GameMaps Format</title>
		<link rel="alternate" type="text/html" href="https://moddingwiki.shikadi.net/w/index.php?title=GameMaps_Format&amp;diff=2599"/>
		<updated>2009-10-31T12:36:36Z</updated>

		<summary type="html">&lt;p&gt;Lemm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The map data for [[Commander Keen 4-6]] is mainly stored in the &amp;lt;tt&amp;gt;GAMEMAPS.CKx&amp;lt;/tt&amp;gt; file. This stores all the maps of the levels used in the game. The GAMEMAPS file is read and decompressed using data stored in the &amp;lt;tt&amp;gt;MAPHEAD.CKx&amp;lt;/tt&amp;gt; file. The file&#039;s start is easily located as it always begins with the word $ABCD followed by several dwords and a lot of blank space. In the 1.4 versions of Keen 4-6 (Dumped executable) the file starts at the following:&lt;br /&gt;
&lt;br /&gt;
  Keen 4: $24830&lt;br /&gt;
  Keen 5: $25990&lt;br /&gt;
  Keen 6: $25080&lt;br /&gt;
 (Keen D: $1FA50)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Map headers ==&lt;br /&gt;
&lt;br /&gt;
In Keen, as in most games, the &amp;lt;tt&amp;gt;MAPHEAD&amp;lt;/tt&amp;gt; file is 402 bytes long, consisting of a word and 100 level dwords.&lt;br /&gt;
&lt;br /&gt;
The first word is the flag for [[RLEW compression]], used to compress the &amp;lt;tt&amp;gt;GAMEMAPS&amp;lt;/tt&amp;gt; file. By default this is $ABCD (This can be changed.). The remaining dwords point to the headers of each level in the &amp;lt;tt&amp;gt;GAMEMAPS&amp;lt;/tt&amp;gt; file. (Nonexistent levels have a dword, value of -1 so this fills most of the file.) The file thus has space for 256 levels.&lt;br /&gt;
&lt;br /&gt;
== GAMEMAPS Format ==&lt;br /&gt;
&lt;br /&gt;
The structure of the &amp;lt;tt&amp;gt;GAMEMAPS&amp;lt;/tt&amp;gt; file is disordered due to the fact that the level headers and level data can be located in any place in any order. The usual structure consists of a variable string of TED settings (&#039;TEDv1.0...&#039;) followed by the levels in no particular order. Each level usually consists of the level header followed by three planes of data, though not always.&lt;br /&gt;
&lt;br /&gt;
The TED settings are unimportant and can usually be ignored. (Though in some cases TED may use them.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Levels in GAMEMAPS ===&lt;br /&gt;
&lt;br /&gt;
The header for each level that is pointed to by MAPHEAD is 42 bytes long:&lt;br /&gt;
&lt;br /&gt;
 0   4    Offset in GAMEMAPS to beginning of compressed plane 0 data&lt;br /&gt;
 4   4    Offset in GAMEMAPS to beginning of compressed plane 1 data&lt;br /&gt;
 8   4    Offset in GAMEMAPS to beginning of compressed plane 2 data&lt;br /&gt;
 12  2    Length of compressed plane 0 data (in bytes)&lt;br /&gt;
 14  2    Length of compressed plane 1 data (in bytes)&lt;br /&gt;
 16  2    Length of compressed plane 2 data (ib bytes)&lt;br /&gt;
 18  2    Width of level (in tiles)&lt;br /&gt;
 20  2    Height of level (in tiles)&lt;br /&gt;
 22  16   Internal name for level (used only by editor, not displayed in-game. null-terminated)&lt;br /&gt;
 38  4    Signature &amp;quot;!ID!&amp;quot;&lt;br /&gt;
 42  x    Level data, three planes RLEW and Carmack compressed&lt;br /&gt;
&lt;br /&gt;
The presence of the level name and the signature are not required by the Keen engine to play the level. Plane 0 is the &#039;background&#039; plane, plane 1 is the &#039;foreground&#039; plane, and plane 2 is the &#039;info&#039; plane. Each is compressed separately, as described below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Compression in GAMEMAPS ===&lt;br /&gt;
&lt;br /&gt;
Each plane is compressed with two successive compression algorithms. The first is [[RLEW compression]], identical to that used in [[Commander Keen 1-3]], except that the magic word (Flag.) is different. (It is specified in the MAPHEAD file, rather than always being xFEFE.) The second is [[Carmack compression]].&lt;br /&gt;
&lt;br /&gt;
The order of compression is RLEW followed by Carmack. One must also keep in mind that each compression algorithm outputs as its first word the length of the uncompressed data. So in the GAMEMAPS file for a particular plane of a particular level, the first word is the number of bytes in the RLEW-compressed data, and the first word of the RLEW-compressed data is the number of bytes in the uncompressed data.&lt;br /&gt;
&lt;br /&gt;
(Note: In Keen Dreams, Huffman Compression is used in place of Carmack Compression.  An array of bytes at $1FBE2 in the executable contains the lengths of the compressed data.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Utilities ==&lt;br /&gt;
&lt;br /&gt;
[[TED5]] This program 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 crate these files.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
This format was reverse engineered by Andrew Durdin (adurdin).&lt;br /&gt;
&lt;br /&gt;
The format is used by other games as well, including [[Bio Menace]], [[Catacomb 3D]], [[Dangerous Dave 3]], [[Dave Goes Nutz]], and [[Wolfenstein 3D]]&lt;/div&gt;</summary>
		<author><name>Lemm</name></author>
	</entry>
</feed>