Commander Keen EGA Header

From ModdingWiki
Jump to navigation Jump to search
Commander Keen EGA Header
There is no image of a tileset in this format — upload one!
Format typeTileset
Max tile countUnknown
Tile names?No
Minimum tile size (pixels)0×0
Maximum tile size (pixels)8,191×65,535
Plane count4-5
Plane arrangementUnknown
Transparent pixels?Yes
Hitmap pixels?No
Supports sub-tilesets?No
Compressed tiles?No
Hidden data?No

Many early (1989-1993) id Software/Softdisk games use an EGAHEAD.* file to read their graphics files. While the number and function of various graphics files vary substantially across various games, the header format itself is rather constant, with only a few minor variations. (Indeed it is possible to see a progressive development of the format over the years by tracing changes across several games.) In Commander Keen 1-3 itself two Raw EGA data files contain all the tiles, sprites and in-game images. In other games more files are usually required.

There are 'types' of graphics, 8x8 fonts, 16x16 tiles, unmasked images and masked sprites. Sprites are almost always stored separately because they usually require 5 planes of EGA data, not 4.

The EGAHEAD file may be external or internal and is divided into three parts, the first section deals with the number and location of fonts, tiles, images and sprites. The second section is a list of the names of unmasked images (Each 16 bytes long.) and the third (And usually largest.) section deals with a list of the names of sprites. (Each 128 bytes long.)

Note that the addresses of graphics are offsets from where an EGA plane starts. So with a plane size of 100, the address 40 would have us looking for data at 40, 140, 240... in the graphics file. If graphics are stored separately, then this address is usually blank (Since it will start at the file start.)

Commander Keen format

Section 1:
0   4    Latplansiz  Size of 4-plane EGA plane; should be one quarter of the size of the UNCOMPRESSED EGA
                     file size. In Keen this is for the EGALATCH file.
4   4    Sprplansiz  Size of 5-plane EGA plane; should be one fifth of the size of the UNCOMPRESSED EGA
                     file size. In Keen this is EGASPRIT. This may be blank in games that store their
                     sprites in multiple files.
8   4    Imgdatstart Where in the EGAHEAD the entries for unmasked graphics (Excluding font and tiles.)  
                     start. If there are none, this is blank.
12  4    Sprdatstart Where in the EGAHEAD the entries for masked graphics (Sprites) start; by default
                     this is right after the unmasked graphics.
16  2    Fontnum     Number of 8x8 font entries are in the font; note that many games have this for
                     drawing windows, with the actual black and white font stored in the executable.
18  4    Fontloc     Offset in memory where font data is placed. Should be zero since font is
                     first. In Keen 1-3 also the location in LATCH file where font data starts.      
22  2    Unknum      Used for the ending screen until this was removed. Number of screen graphics.       
24  4    Unkloc      Used for screen graphics until removal. Offset in memory where screen data placed.   
28  2    Tilenum     Number of 16x16 tiles                                
30  4    Tileloc     Offset in memory\LATCH where tile data placed\starts.     
34  2    Bmpnum      Number of unmasked bitmaps                           
36  4    Bmploc      Offset in memory\plane where unmasked bitmap data starts\placed.   
40  2    Spritenum   Number of sprite images                              
42  4    Spriteloc   Offset in EGASPRIT plane of start of sprite data. Is, of course, zero. Also relates
                     to memory
46  2    Compression Add 2 to this byte if EGALATCH is compressed, add 1 to it if EGASPRIT is compressed.
                     Thus uncompressed graphics have this set at 0 and fully compressed at 3. The only
                     game that compresses its graphics like this is Commander Keen 1. Attempting to set
                     any compression for the other games will result in garbage graphics.

Section 2:
    2    Size h      The width of the graphic divided by 8 
2   2    Size v      The height of the graphic in pixels; if this cannot be
                     divided into neat 16 byte pieces, the extra data,     
                     usually 8 bytes, is added to the size.                
4   4     Loc        When added to the graphic offset in the header, gives 
                     the location of the start of the graphic data in the  
                     plane. For the first graphic this is thus zero.       
8   8     Name       Name of the graphic, padded with nulls. 

Section 3:
0   2     Width      The width of the graphic divided by 8 
2   2     Height     The height of the graphic in pixels;  the same rule 
                     applies as for unmasked graphics except now we have:
4   2     Loc offset Usually 8, this is the number of bytes 'extra' that 
                     must be added to the location to reach the start of 
                     the sprite data. This appears when a sprite is so   
                     small, usually 8x8 pixels, that it doesn't fill a   
                     multiple of 16 bytes. This will affect ALL sprites  
                     after the aberration until another one occurs to fix
                     the shortfall.                                      
6   2     Location   Multiplying this by 16 bytes gives the location of  
                     the start of the sprite data in the EGA plane.      
8   4     Hitbox ul  Location of the upper-left corner of the sprite's   
                     hitbox or collision rectangle, in pixels, starting   
                     from 0,0. First two bytes are the h location and the
                     next two are the v location. In the EGAHEAD, both
                     values are multiplied by 256.               
12  4     Hitbox br  Same as above, for the bottom left corner.          
16  12    Name       The sprite name, usually includes a number and is   
                     usually only 10 bytes long. May spill into the next
                     field in games that do not use that.                        
28  4     h/v off    The horizontal and vertical offset of the sprite frame from the sprite
                     event. In early games this is blank, but in later ones such as
                     Shadow Knights it is utilized. This can be used to 'line up'
                     frames of different heights and so on.
32  3*32  Copies     Games use these entries for smooth movement; each 32 byte entry is
                     a copy of the initial sprite shifted 2 pixels left. The game will
                     automatically generate the graphics, but the preceding information
                     must be duplicated. In the copies, 1 is added to the width field.

Other games

There are several differences between other games and Commander Keen. The most notable is usually the presence of more than two graphics files. Sprites are often split into various S_* files, each of which is compressed, containing, as its first word, the decompressed file size (Including the word itself and any header the raw data may have.) It is usually not hard to calculate a plane size from this.

Addresses in the header will point to the right location in whatever file is being used at the time. Thus is sprites have been split up into several files, it is possible to see when files are 'switched' whenever the pointer for a sprite is less (usually 0) than the pointer to the previous sprite. (A new file is being opened and data read from the start of it, instead of the end of the old file.) Note however that the order sprite files are opened and how many sprites they contain is usually hard-coded.

Another effect of this is that pointers in the EGA are used for memory, NOT files. In Keen they are the same, since the EGALATCH is copied directly into memory in segments, essentially the whole file is copied as-is. In other games with more files the game is hard-coded to calculate where to read from the number of graphics entries, their size or whether or not a file has been opened so they header pointers are not a reliable guide.

Aside fro Commander Keen, no other games are LZW compressed and so don't use that feature in the header. Other forms of compression are used which may or may not be indicated in the header somehow.

As games progressed an additional modification was added to the header format; the last four bytes of a sprite's name were set aside to be h and v offsets of the sprite image (as used in Commander Keen 4-6 games.) This left a sprite with a maximum name length of 11 bytes. Since the last four bytes are seldom used (are zero), it can often be assumed that all games use this with few problems.

Finally is the issue of 'sprite blitting' The header's sprite entries are 128 bytes long, being essentially four copies of a 32 byte entry. In earlier games each was in fact a separate entry, there were in effect four times the number of sprites, each one used for when a sprite was moving 0, 2, 4, and 6 pixels left or right. Later games automated the creation of these sprites, shrinking file size. For simplicity the header format was left as-is.

Dangerous Dave in Copyright Infringement


Dangerous Dave 2

Dangerous Dave 2 stores the header and LATCH internally in the executable at 74896 and 101096 respectively (in the UNLZEXE'd executable.) Because the EGALATCH.DD2 file is stored internally there is an interesting situation with 8x8 tiles and unmasked bitmaps; the EGAHEAD points to 32 8x8 tiles, but the last tile is overwritten by the start of the unmasked bitmap data. This means that 8 bytes from each EGA plane are copied into memory twice, once as the end of 8x8 tiles and again as the first unmasked bitmap. It also means that the 'location' of the bitmaps (e.g. $100) is 8 bytes larger than the location of the EGA data in the internal file.

Otherwise the format is nearly identical. Number of unmasked bitmaps and their location are at 40\42 in the header instead of 34\36. There is no sprite plane size at 4 since the sprites are stored in several compressed files (each containing its own planesize.) Tiles are stored in a separate file EGATILES.DD2. Since each tile may or may not be loaded in a level depending on whether it's needed, the tile file is composed of 858 128-byte entries, each containing 4-EGA planes for the tile. There is a 'copy' of the EGA planesize at byte 40 and bytes 22-34 and 52-64 are blank or contain nonsense data.

Rescue Rover

Rescue Rover has two sprite files, S_PLAY.ROV and S_DEMO.ROV used in that order. Bitmaps and 8x8 font are stored in EGAPLANE.ROV, tiles are 32x32 and stored in EGABTILE.ROV (TED 16x16 tiles are stored in a file not used by the game, EGATILES.ROV. Finally a monochrome font is stored in EGAFONT0.ROV There are also several compressed screen images, *PIC.ROV

The number\location-in-file of the sprites are stored at slightly different places, at bytes 47 and 49 instead of 41 and 43. In practice the location of tile and sprite data is 0, since they do not share files with any other EGA graphics.

Shadow Knights

Shadow Knights uses the same (subtly different) EGA header as Rescue Rover, this document describes how the compression used for the sprites and the slightly odd layout of the tile data works.


Slordax uses a format exactly identical to Commander Keen.


This format has been reverse engineered several times, mostly by the Commander Keen community. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)