home *** CD-ROM | disk | FTP | other *** search
- Wolfenstein 3D Map Formats
- --------------------------
-
- This document contains the formats of the MAPHEAD and GAMEMAPS file, which
- together define the maps for Wolfenstein 3D. The file format is valid for
- versions of PC Wolfenstein 3D greater than V1.4 and for V1.0 of the RISC OS
- version.
-
- MAPHEAD:
-
- +0 - &CD
- +1 - &AB
- +2 - file pointer (in GAMEMAPS) of map descriptor for level 1
- +6 - file pointer of map descriptor for level 2
- +2 + 4*(n-1) - file pointer of map descriptor for level 3
-
- So you extract the word from 2 + 4n where n is from 0 to 59 and that is an
- offset into the GAMEMAPS file from which you must load 18 bytes. (Note that
- if the value is 0 this means that the level is not available.) These 18
- bytes (the map descriptor) are:
-
- +0 - File pointer to map plane 1 (in GAMEMAPS)
- +4 - File pointer to map plane 2
- +8 - File pointer to map plane 3
- +12 - Length of map plane 1 data
- +14 - Length of map plane 2 data
- +16 - Length of map plane 3 data
-
- This requires a little explanation - each map plane contains 64x64 cells (the
- size of the map). Map plane 1 contains the walls, floors and doors. Map
- plane 2 contains the objects, actors, and various markers. Map plane 3 is
- always filled with 0s. Each cell is two bytes, so each map plane is 8K long
- when uncompressed. Sadly, they are compressed, so you'll need to decompress
- them. In Appendix I is an assembler-language code fragment to decompress a
- lump.
-
- Now you have 3 decompressed lumps you can look at and edit them. As mentioned
- earlier, the first plane contains the walls, doors and floors. Each value is
- two bytes, but for walls these are limited to:
-
- 0 = nothingness - should never occur
- 1 to 49 = wall type n
- &5A/&5B = vertical/horizontal door
- &5C/&5D = vertical/horizontal door needing yellow key
- &5E/&5F = vertical/horizontal door needing blue key
- &64/&65 = elevator door
- &6A = floor type 0
- &6B onwards = floor type n - &6A
-
- Wall types each have 2 bitmaps in the ASWAP file. The first two graphics in
- the ASWAP file are for wall #1. The first frame is brighter than the second
- frame; this is used to express a little subtle lighting by plotting one frame
- on N/S wall faces and the other one on E/W faces.
-
- Floor types go from 1 to 40 for normal floors and 0 for a 'silent' floor. If
- a soldier starts on a 'silent' floor tile then he will not hear anything, and
- will only 'wake up' when he actually sees the player. Experiment!
-
- The object types use 9 bits of the value. The other 7 bits must be 0. (While
- I'm on, the top 8 bits of each wall value must be 0).
-
- The mapping goes as follows:
-
- &00 : no object
- &01 - &12 : undefined, DO NOT USE
- &13 : player start, facing N
- &14 : player start, facing E
- &15 : player start, facing S
- &16 : player start, facing W
- &17 : Object #2
- &18 : Object #3
- &19 - &46 : Object #(n-&15)
- &47 - &59 : undefined, DO NOT USE
- &5A - &61 : Turn tiles 0 to 7
- &62 : Secret Door
- &63 : End of game
- &64 - &6B : undefined, DO NOT USE
-
- &6C onwards are actors, which I will explain in a minute. Firstly, though,
- objects #2 to #49 are the static objects. Some you can walk through and some
- you can't. The graphics are in the ASWAP file. Object #0 is actually the
- "DEMO" sign and object #1 is the "DEATHCAM" sign - these are not true objects.
- The first object which can appear on a map is Object #2 - the pool of water.
-
- The turn tiles affect actors when they are in wander mode. Each tile forces
- a turn in one of the eight directions. Again, experiment to find out which!
- The secret door tile is placed on the map plane in the same position as the
- wall in the wall plane, and makes that door secret. The computer
- automagically
- works out in which direction the wall can be pushed.
- The end of game tile is only used at the end of levels 9 and 49. These are
- the
- levels where the camera follows BJ's running jump instead of getting a
- DeathCam
- when you win. Once the player hits the tile, he runs NORTH. Look at levels 9
- and 49 to get the idea.
-
- Actor concepts:
-
- Actors begin either standing or walking (some are always walking). An actor
- will detect your presence if you shoot when he is in earshot or if he sees
- you.
- Once he detects you it's you or him. The standing actors just stand there,
- and
- if they are standing on a 'silent' tile then they won't hear your gun. The
- walking actors walk forwards until they hit a wall or a turn tile. Look at
- the
- maps to see how this allows you to plan complex patrols for the guards to
- follow. Walking or chasing actors will open doors (including locked doors)
- whenever they need to.
-
- Each actor has an initial direction (N,S,E or W) which he is facing and (if
- appropriate) walking. They also have a difficulty level of 1,3 or 4. 1 means
- the actor appears at all difficulty levels. 3 means only on level 3 or
- higher,
- and 4 means only on 'I am death incarnate'. The actor values on the map are
- grouped in 4s. If the list below has a * to the left of the value, then
-
- value + 0 is the item facing North
- value + 1 is the item facing East
- value + 2 is the item facing South
- value + 3 is the item facing West
-
- * &6C - soldier, standing, level 1
- * &70 - soldier, walking, level 1
- * &74 - 'spion', standing, level 1
- * &78 - 'spion', walking, level 1
- * &7E - SS, standing, level 1
- * &82 - SS, walking, level 1
- * &86 - dog, standing, level 1 (this shouldn't be used)
- * &8A - dog, walking, level 1
-
- Add &24 for the level 3 actors and &48 for the level 4 actors.
-
- * &D8 - zombie, standing, level 1
- * &DC - zombie, walking, level 1
-
- Add &12 for the level 3 actors and &24 for the level 4 actors.
-
- The rest are bosses and special monsters, like the Pac-men. These don't
- 'face'
- any direction.
-
- &7C - the dead guard at the start of level 1
- &A0 - Ghost Hitler (episode 3)
- &B2 - Mecha-Hitler (episode 3)
- &B3 - Fat bastard at the end of episode 4
- &C4 - Dr Schabbs (the guy with the needles in episode 2)
- &C5 - Gretel Giftmacher, the blonde non-temptress in episode 5
- &D6 - Mr "Guten Tag" himself, official name Hans (episode 1)
- &D7 - Giftmacher, the ultimate challenge (episode 6)
- &E0,&E1,&E2,&E3 - Inky, Blinky, Pinky and Clyde
-
- I've been pretty vague in some places. I want to encourage you to experiment,
- all the nitty gritty is here and you need broad outlines. The Wolfenstein 3D
- FAQ should help - it has tons and tons of stuff about screen designing in it.
-
- Appendix I
- ----------
-
- The following code is pretty raw, and is actually pulled straight from Arc
- Wolfenstein. Exciting, huh? The three words at the top of the program should
- be set up before the routine is called. I'm afraid that recompression is left
- as an exercise to the reader.
-
- .source
- EQUD 0 ; This is the address of the compressed data
- .buffer
- EQUD 0 ; This must point to a 8K buffer
- .target
- EQUD 0 ; And this must point to the 8K output buffer
-
- .decompress_lump
- STMFD R13!,{PC}
- LDR R0,source ; set the source address
- LDR R1,buffer ; set the address of an 8K buffer
- BL a7a8 ; uncompress - first stage
- LDR R0,buffer ; source = first-stage uncompressed data
- LDR R1,target ; target address
- BL mexpand ; uncompress - second stage
- LDMFD R13!,{PC} ; done !
- .a7a8
- MOV R2,R1 ; dest start
- LDRB R8,[R0],#1
- LDRB R9,[R0],#1
- ORR R8,R8,R9,ASL #8 ; target data length (first half-word)
- ADD R8,R8,R2 ; end of destination buffer
-
- .looprep1
- LDRB R4,[R0],#1 ; lo
- LDRB R5,[R0],#1 ; hi
- CMP R5,#&A7
- BNE nota7
- MOVS R4,R4,ASL #1 ; length of run
- BEQ special
- LDRB R6,[R0],#1 ; goback1
- MOV R6,R6,ASL #1
- .loopa7
- LDRB R7,[R1,-R6]
- STRB R7,[R1],#1
- SUBS R4,R4,#1
- BNE loopa7
- B endif
- .nota7
- CMP R5,#&A8
- BNE nota8
- MOVS R4,R4,ASL #1 ; length of run
- BEQ special
- LDRB R6,[R0],#1
- LDRB R7,[R0],#1
- ORR R6,R6,R7,ASL #8 ; goback2
- ADD R6,R2,R6,ASL #1
- .loopa8
- LDRB R7,[R6],#1
- STRB R7,[R1],#1
- SUBS R4,R4,#1
- BNE loopa8
- B endif
- .nota8
- STRB R4,[R1],#1
- STRB R5,[R1],#1
- .endif
- CMP R1,R8
- BLO looprep1
- MOV PC,R14
- .special
- STRB R5,[R1],#1
- LDRB R4,[R0],#1
- STRB R4,[R1],#1
- B endif
-
- .specialword EQUD &ABCD
- .mexpand
- LDRB R10,specialword
- LDRB R11,specialword+1
-
- LDRB R4,[R0],#1
- LDRB R5,[R0],#1
- ORR R4,R4,R5,ASL #8
- ADD R8,R4,R1 ; end of data target
-
- .loopexp
-
- LDRB R4,[R0],#1
- LDRB R5,[R0],#1
- CMP R5,R11:CMPEQ R4,R10:BNE notabcd
- LDRB R6,[R0],#1
- LDRB R7,[R0],#1
- ORR R6,R6,R7,ASL #8 ; count
- LDRB R4,[R0],#1
- LDRB R5,[R0],#1
- .loopabcd
- STRB R4,[R1],#1
- STRB R5,[R1],#1
- SUBS R6,R6,#1
- BNE loopabcd
- B endifexp
- .notabcd
- STRB R4,[R1],#1
- STRB R5,[R1],#1
- .endifexp
- CMP R1,R8
- BLO loopexp
- MOV PC,R14
-
-
-
-
-
-
-