----------------------------------------------------------------------------- T H E U N O F F I C I A L *-D-*-*-O-*-*-O-*-*-M-* S P E C S Release v1.0 - January 21, 1994 Written by: roggerffff@aol.com Released by: Hank Leukart (ap641@cleveland.freenet.edu) "DOOM: Where the sanest place... is behind a trigger." "DOOM: Such mayhem the likes of which have never been witnessed in this particular dimension!" ----------------------------------------------------------------------------- ---------- DISCLAIMER ---------- These specs are to aid in informing the public about the game DOOM, by id Software. In no way should this promote your killing yourself, killing others, or killing in any other fashion. Additionally, Hank Leukart nor the author claim ANY responsibility regarding ANY illegal activity concerning this file, or indirectly related to this file. The information contained in this file only reflects id Software indirectly, and questioning id Software regarding any information in this file is not recommended. --------- COPYRIGHT --------- You may NOT distribute this work by any non-electronic media, including but not limited to books, newsletters, magazines, manuals, catalogs, and speech. You may NOT distribute this work in electronic magazines, or within computer software without prior written explicit permission. These rights are temporary and revocable upon written, oral, or other notice by Hank Leukart. This copyright notice shall be governed by the laws of the state of Ohio. If you would like additional rights beyond those granted above, write to the distributor at "ap641@cleveland.freenet.edu" on the Internet. ------------ INTRODUCTION ------------ Here are the long awaited unofficial specs for DOOM. These specs should be used for creating add-on software for the game. I would like to request that these specs be used in making utilities that ONLY work on the registered version of DOOM. You may not use these for modifing, translating, disassembling, decompiling, reverse engineering, or creating derivative works based upon DOOM. Notwithstanding the foregoing, you may create a map editor, modify maps and make your own maps (collectively referenced as the "Permitted Derivative Works") for the Software. You may not sell or distribute any Permitted Derivative Works but you may exchange the Permitted Derivative Works at no charge amongst other end-users. I do not understand much of what is contained in this file, so if you have any questions about the information, write to "roggerffff@aol.com" on the Internet. If you would like to request a copy of this file, or have any questions about its distribution, write to me, Hank Leukart, at "ap641@cleveland.freenet.edu" on the Internet. -------- CONTENTS -------- [1] Basics [2] Directory Overview [3] The Maps, The Levels [3-1] ExMy [3-2] Things [3-3] Thing Types [3-4] Linedefs [3-5] Sidedefs [3-6] Vertexes [3-7] Segs [3-8] Ssectors [3-9] Nodes [3-10] Sectors [3-11] Reject [3-12] Blockmap [4] Texture1 [5] Pnames [6] Pictures [7] Floor and Ceiling Textures ------------------- CHAPTER [1]: Basics ------------------- The first twelve bytes of a Doom *.WAD file (in the shareware version it is DOOM1.WAD, the registered version's is DOOM.WAD) are as follows: Bytes 0 to 3 - contain the ASCII letters "IWAD" or possibly "PWAD" Bytes 4 to 7 - contain a long integer which is the number of entries in the "directory" Bytes 8 to 11 - contain a pointer to the first byte of the "directory" (Bytes 12 to the start of the directory contain object data) The directory referred to is a list, located at the end of the WAD file, which contains the pointers, lengths, and names of all the "objects" in the WAD file. "Objects" means data structures such as item pictures, enemies' pictures (frames), floor and ceiling textures, wall textures, songs, sound effects, map data, and many others. For example, the first 12 bytes of the shareware DOOM1.WAD file are: 49 57 41 44 f6 04 00 00 6b e5 3f 00 This is "IWAD", then 4f6 hex (=1270 decimal) for # of directory entries, then 3fe56b (=4187500 decimal) for the first byte of the directory. Each directory entry is 16 bytes long (10 hex), arranged this way: First four bytes: pointer to start of object (a long integer) Next four bytes: length of object (another long integer) Last eight bytes: name of object, ending with 00s if not eight bytes. ------------------------------- CHAPTER [2]: Directory Overview ------------------------------- PLAYPAL is the palette used while playing Doom. COLORMAP is something to do with the palette also. ENDOOM is the text messages displayed at the end of each episode. DEMO[x] are the demos which will play if you just sit and watch. E1M1 etc (to E1M9 or E3M9), along with its 10 subsequent entries, defines the map data for a single level or "map". More on this below. TEXTURE1 is a list of wall type names, and their composition data. PNAMES is the list of wall textures that are used to make up the entries in TEXTURE1. GENMIDI has some instrument names in it, and...? DMXGUS has to do with Gravis Ultra Sound, I suppose D_xxxxxx is a song DP_xxxxx DP and DS come in pairs and are DS_xxxxx probably the sound effects HELP1 These four are the full screen HELP2 pictures displayed as help TITLEPIC screens, title screen, and CREDITS credits screen. AMMNUMx where x is 0-9, means what? STxxxxxx ? M_xxxxxx ? BRDR_xxx ? WIxxxxxx ? these objects "bracket" a collection of objects: S_START has 0 length and is right before the first "picture" S_END is immediately after the last "picture" P_START P1_START before the first wall texture P1_END after the last wall texture P_END F_START F1_START before the first floor texture F1_END after the last F_END Detailed info on specific objects follows. --------------------------------- CHAPTER [3]: The Maps, The Levels --------------------------------- Each level has eleven objects/directory entries: E[x]M[y] (where x is a single digit 1-3 for the episode # and y is 1-9 for the map/level #), THINGS, LINEDEFS, SIDEDEFS, VERTEXES, SEGS, SSECTORS, NODES, SECTORS, REJECT, BLOCKMAP. [3-1]: ExMy =========== This is just the name object for a (single) level, and has zero length. The next 10 entries in the directory after one of these must be THINGS...BLOCKMAP. [3-2]: Things ============= Each thing is ten bytes, consisting of five (integer) fields: 1. bytes 0-1 X coordinate of thing 2. bytes 2-3 Y coordinate of thing (each level has a different "range" to its coordinates. On E1M1, X ranges from (c.) -288 to +3440, and Y ranges from (c.) -4832 to -2144. On the automap within the game, with the grid on (press `G'), the lines are hex 80 (decimal 128) apart, two lines = hex 100, dec 256 3. bytes 4-5 angle the thing faces, 0 is west (according to automap). May be 0,45,90,135,180,225,270,315. Only important for enemies. 4. bytes 6-7 type of thing, see next subsection 5. bytes 8-9 skill levels it is present on, and ...? The skill level is done thus: bit 0 is set if the THING is present at skill 1 and 2 bit 1 is set if the THING is on skill 3 (hurt me plenty) bit 2 is set if the THING is on skill 4 (ultra-violence) bit 3 is for what? I don't know yet... bit 4 makes the THING only appear in the commercial version. bits 5-15 are never set in any THING in the shareware version, and have no effect as far as I can tell. The skill settings are most used with the ENEMIES, of course...the most common skill level settings are hex 07/0f (on all skills), 06/0e (on skill 3-4), and 04/0c (only on skill 4). However, you can twist the purpose and have ones like 1 so that a player at the low skill levels has to fight more guys! Then all skill levels would be "tough"! [3-3]: Thing Types ================== Bytes 6-7 of each thing are an integer which means the thing at that x,y location is one of these: (this list needs updating to include the registered version) 1 player 1 start 2 player 2 start 3 player 3 start 4 player 4 start 5 Blue keycard 6 Yellow keycard 7 error message `invalid frame 33:0', this item is not in the shareware version. 8 Backpack 9 SARGE = black dudes with shotguns 10 dead guy, bloody mess 11 ?? something that doesn't display (mystery object #1) 12 dead, bloody mess 2 13 Red keycard 14 ?? doesn't display anything (mystery object #2) 15 green dead guy (one of your pals...?) 24 pool of blood 34 candle 35 candelabra 46 flame stick 48 column 58 SPECTRE = invisible demon 2001 shotgun 2002 chaingun 2003 rocket launcher 2004 `frame 70:0' prob. the PLASMA GUN; not in shareware 2005 chainsaw 2006 `frame 66:0' prob. th BFG9000; not in shareware 2007 ammo clip 2008 shotgun shells 2010 1 rocket 2011 stimpack 2012 med kit 2013 soulsphere (blue, +100% health) 2014 potion +1% health 2015 helmet +1% armor 2018 green armor 100% 2019 blue armor 200% 2022 `frame 51:0' prob. invulnerability or beserk strength 2023 `frame 52:0' prob. the other one 2024 blur sphere 2025 radiation suit 2026 computer map 2028 floor lamp 2035 barrel 2045 lite-amp goggles 2046 rockets box 2048 ammo box 2049 shells box 3001 IMP = brown fireball chucker 3002 DEMON = pink bull 3003 BOSS GUY = throws green fireballs 3004 TROOP = regular loser 3005 `frame 30:0' probably Lost Soul or Cacodemon 3006 `frame 32:32768' probably the other One cool effect: for one-player mode, change one (or more) of the other player things (2,3,4) to 1. Then when you play, there will be a green guy standing there, your alter-ego! If you shoot him, you take damage!!! [3-4]: Linedefs =============== Each linedef represents a line from one of the VERTEXES to another, and each has 7 (integer) fields: 1. from the VERTEX with this number (the first vertex is 0) 2. to the VERTEX with this number (31 is the 32nd vertex) 3. bit 0 set means you can't go through it, others like 28,12,17 = ? 4. 1 is for a door, 48 means it is "animated" like the armor pedestal at the very start of E1M1, 11 is for the switch that ends the level, many others...sublist in the making...? 5. is a "trigger" number which ties crossing this line to the SECTOR with this same number as its last field (I think...) 6. SIDEDEF one (always present, since this line adjoins at least 1 SECTOR) 7. SIDEDEF two, if this line adjoins 2 SECTORS [3-5]: Sidedefs =============== A sidedef is a definition of what wall meta-textures to draw along the various LINEDEFS, and a group of sidedefs define a SECTOR. There will be one sidedef for a line that borders only one sector, since it is not necessary to define what the doom player would see from the "other" side of that line because the doom player can't go there. The doom player can only "go" where there is a sector (unless you use the no clipping cheat, which will cause the screen to freak out if you go "outside" to a non-sector area). Each SIDEDEF has 2 (integer) fields, then 3 (8-byte string) fields, then a final (integer) field: 1. X offset from the top-left corner to begin pasting the appropriate wall texture onto the walls "space" 2. Y offset from the top-left to begin "paste" 3. name of wall type 1 = the part "above" the juncture with a lower ceiling of an adjacent SECTOR 4. name of wall type 2 = the part "below" a juncture with a higher floored adjacent SECTOR 5. name of wall type 3 = the regular part 6. SECTOR that this sidedef "helps to surround" the wall type fields will be "-" if nothing, thus the sidedef for looking IN a "window" is "-" "-" "-". A typical sidedef is "-" "-" "STARTAN3" the wall names are from the TEXTURE1 object, which defines how to draw that wall. the names in the DIRECTORY are not directly used, they are referenced through PNAMES. [3-6]: Vertexes =============== These are the beginnings and ends for LINEDEFS, each has 2 (integer) fields: 1. x coordinate 2. y coordinate [3-7]: Segs =========== Each SEG has 6 (integer) fields 1. from vertex 2. to vertex 3. angle 0= east 16384=north -16384=south -32768=west 4. linedef that this seg goes along 5. either 0 or 1, why ??? 6. ??? (SEGS, SSECTORS, and NODES are a real bear. I haven't figured them out yet...) [3-8]: Ssectors =============== each SSECTOR has 2 (integer) fields 1. # of SEGS in this SSECTOR 2. starting with this SEG # [3-9]: Nodes ============ the NODES object is (# of SSECTORS -1) * 14 bytes long, but I don't see the connection. [3-10]: Sectors =============== A SECTOR is a horiontal (east-west and north-south) area of the map where a floor height and ceiling height is defined, so a doom player may go there. Any change in floor or ceiling "altitude" or texture requires a new SECTOR (and therefor a separating LINEDEF and SIDEDEFS). Each is 2 (integer) fields, 2 (8-byte string) fields, then 3 (integer) fields: 1. floor is at this "altitude" for this sector 2. ceiling altitude the altitudes range from -264 to 264. a difference of 28 between the floor heights of two adjacent sectors is passable (upwards), but a difference of 32 is "too high". the player may fall any amount. 3. name of floor texture, from the DIRECTORY 4. name of ceiling texture, from DIRECTORY (note: all the ones listed in the DIRECTORY work as either floors or ceilings) 5. brightness of this sector 0=total dark 255=maximum bright 6. special sector: 0 is normal 1 light level "blinks" randomly 2 light quickly pulsates 3 blink 4 pulsates AND take 20% health hit when stand here 5 -10% health 6 UNKNOWN SPECIAL SECTOR, causes program to exit to DOS 7 -5% (this is the typical NUKAGE green stuff floor) 8 pulsating light 9 SECRET (player must walk into this sector to get credit for discovering this "secret") 10 ? 11 -20% health 12 blink 13 quick pulsate 14 ? 15 UNKNOWN SPECIAL SECTOR, do not use 16 -20% 7. is a "trigger" number corresponding to a certain LINEDEF with the same "trigger" number. When that LINEDEF is crossed, something happens to this SECTOR - it goes up or down, etc... [3-11]: Reject ============== The purpose of this one eludes me so far [3-12]: Blockmap ================ This is to aid in the implementation of the automap, probably. All its fields are integers. The whole level is cut into "blocks", each hex 80 wide (the grid lines in the automap correspond to these blocks). The first two integers are XORIGIN and YORIGIN, which specify the coordinates of the bottom-left corner of the bottom-left (southwest) block. Then come XBLOCKS and YBLOCKS, which specify how many "blocks" there are in the X and Y directions. XBLOCKS is the number of COLUMNS, YBLOCKS is the number of ROWS. Then come (ROWS * COLUMNS) integers which are pointers to the offset within the BLOCKMAP object for that "block". The blocks go right (east) and up (north). The first block is at row 0, column 0; the next at row 0, column 1; if there are 34 columns like on the first level, the 35th block is row 1, column 0, etc. After all the pointers, come the block lists. Each blocklist describes the numbers of all the LINEDEFS which are partially or wholly "in" that block. An "empty" block is two integers: 0 and then -1. A non-empty block will go something like: 0 330 331 333 -1. This means that LINEDEFS 330, 331, and 333 are "in" that block. Part of each of those line segments lies within the (hex 80 by 80) boundaries of that block. What about the block that has LINEDEF 0? It goes: 0 0 ... etc ... -1. That's it. (I'm not sure how linedefs are handled when they lie entirely along a "border" between blocks) THIS CONCLUDES THE SECTION ON THE LEVELS. --------------------- CHAPTER [4]: Texture1 --------------------- This object contains a list of the wall names used in the various SIDEDEFS sections of the level data. Each wall name actually references a meta-structure, defined in this list. Each entry in this list begins with a 8-byte "name" field, but then each entry has variable length. All the remaining fields of an entry are integers. The second and third fields always 0 and 0 that I've seen so far, so the purpose is unknown. The fourth and fifth fields define the width in columns and height in rows, for this entry, thus defining a "space" (usually 32 by 128 or 64 by 72 or etc...) in which individual wall textures are "placed" to form the overall picture. This is done because there are some parts that are used in several different walls, like computer screens, etc. The sixth and seventh fields are 0 and 0, purpose unknown The eigth field is the number of 5-integer "sets" that follow. Each "set" defines a wall texture for placement, and the integers mean this: 1. x offset from top-left corner of "space" (defined in 4/5) to start placement of this "part" 2. y offset 3. number, from 0 to ____, of the entry in the PNAMES object, which contains the name from the DIRECTORY, of the wall texture to use... 4. always 1 ?? 5. always 0 ?? Some of the entries have 1 "part", one has 64 "parts"! ------------------- CHAPTER [5]: Pnames ------------------- This is a lookup table for the numbers in TEXTURE1 to reference to an actual entry in the DIRECTORY which is a wall texture (in the picture format described later). The middle integer of each 5-integer "set" of a TEXTURE1 entry is something from 0 to 125 (shareware) or ___ (registered). Number 0 means the first entry in this PNAMES list, 1 is the second, etc... Every entry in this list is eight bytes, and exactly duplicates an entry in the DIRECTORY. If a name in PNAMES is not in the DIRECTORY, an error occurs. --------------------- CHAPTER [6]: Pictures --------------------- The same format is used for the pictures for items (like medikits), the frames that make up enemies (like demons), and the wall textures. The floor/ceiling textures are different! First come four integers: 1. The number of columns of picture data 2. The number of rows this defines a rectangular "space" or limits for drawing a picture within 3. leftwards x offset from the center to begin the first column 4. upwards y offset from the bottom to begin the first row To be "centered", #3 is usually about half of the total width. If the picture had 30 columns, and #3 was 0, then it would be off-center to the right, especially when the player is standing right in front of it, looking at it. If a picture has 30 columns, and #4 is 60, it will appear to "float" like a blue soul-sphere. If #4 equals the number of rows, it will appear to rest on the ground. If #4 is more than 5 less than #2, the bottom part of the picture is invisible, cut off by the floor. With walls, #3 (columns/2)-1, and #4 is always (rows)-5. This is because the walls are drawn consistently within their own space. (There are two integers in each SIDEDEF which can offset the beginning of a wall) Finally, if #3 and #4 are NEGATIVE integers, then they are the absolute coordinates from the top-left corner of the screen, to begin drawing the picture, assuming the VIEW is FULL-SCREEN (the full 320x200). This is only done with the pictures of the weapons of the doom player - fist, chainsaw, pistol, shotgun, etc. ====== After these four integers, there are N=(# of columns) long integers (4 bytes each). These are pointers to the data for each column. The value of the pointer represents the offset from the first byte of that picture. Each column is composed of some number of BYTES (NOT integers), arranged in sets, all sets ending in 255=FF hex: The first byte is the row to begin drawing this set at. 0 means whatever height the #4 upwards-offset describes. The second byte is how many colored pixels (non-transparent) to draw, going downwards. Then follow (# of pixels)+2 bytes, which define what color each pixel is, using the game palette. The first and last bytes AREN'T drawn, and I don't know why they are there. Only the middle (# of pixels in this set) are drawn, starting at the row specified in byte 1 of the set. 255 (hex FF) ends the set, so a column that starts this way is a null column, all "transparent". Goes to the next column. Thus, transparent areas can be defined for either items or walls (but you should only use a wall with transparent parts on a SIDEDEF between two SECTORS): If the picture is 56 wide and 72 tall, and column 1 has a set of 12 pixels starting at row 13, and another set of 10 starting at row 32, and a third set of 9 starting at 55, then the pixels at column 1, rows 0-12, 25-31, 42-54, and 64-71 will all be "transparent". (The data bytes for this might look something like this, in hexadecimal - ... 0d 0c # # # # # # # # # # # # # # FF 20 0a # # # # # # # # # # # # FF 37 09 # # # # # # # # # # # ff ... next column) Note that all the item and enemy pictures names are in the DIRECTORY between the S_START and S_END entries, and all the wall textures are all between the P_START and P_END entries. --------------------------------------- CHAPTER [7]: Floor and Ceiling Textures --------------------------------------- This is temporary, speculative...I haven't checked these out much yet... Also, how is the F_SKY1 ceiling "texture" transparent? All the names for these textures are in the DIRECTORY between the F_START and F_END entries. There is no look-up or meta-structure as with the walls. Each texture is 4096 raw bytes, making a square 64 by 64 pixels, which is pasted starting in the northwesternmost corner (as determined by the x,y coordinates and the automap) of a sector.