Creating 3-D Dungeon Crawls

         by Todd S. Elliott (telliott@ubmail.ubalt.edu)
         http://ubmail.ubalt.edu/~telliott/commodore.html
 

Introduction

What? Another article in C=Hacking that deals with the subject of 3-D? Well, not in the same vein as Mr. Judd's study in 3 Dimensions for rendering shaded 3-D polygons in real time. (See Polygonomy in C=Hacking 12) No, this article only deals with the aspect of the 3-D look and feel in those dungeon crawls you see for the c64. Some titles spring to mind, like the gold box series by SSI in collaboration with TSR, i.e., Pool of Radiance, Curse of the Azure Bonds, or other popular titles such as the Bard's Tale Trilogy.

With the techniques described, the aspiring Dungeon Master (DM) can create a rich world to torture his players at the local terminal of the beloved c64! That, and some generous helpings from the local pizza delivery company. "Hey! Look out for the grease! Arrrgh! Now the `A' key is stained!" ;)

Nuts and Bolts

Let's begin with the 3-D screen. It is comprised of a 12x12 square of custom characters, which never change position. The 12x12 square looks like this:

characters 01,02,24,25,48,49,..,96,97,120,121
           03,04,26,27,50,51,..,98,99,122,123
           ..
           ..
           22,23,46,47,70,71,..,118,119,142,143
The 144 characters are positioned in an unusual way: they flow in two character columns, run down for 24 characters, then go back up for the next two-character columns. Think of these two-character columns as SEAMS in the 3-D window. Right now, there are six such SEAMS in the 3-D window for the dungeon. Of course, these are not the actual characters (screen codes), (I forget what they are right now), but they are in a continuous sequence, i.e., no broken or interrupted series of screen codes. (If memory serves me correctly, they are the last 144 screen codes in the 256 screen code table.) The corresponding color codes never change, for the sake of speed.

Next, we deal with the concept of CELLS in the 3-D window. There are a total of 13 CELLS which we can utilize individually to show an object, which in turn, is displayed in the 3-D window in the correct perspective. By objects, I mean walls or doors. The perspective is from the user's standpoint. This creates the illusion of the 3-D look and feel, but does not simulate true 3-D rendering on the fly such as Polygonamy by Mr. Judd. (See Polygonomy, C=Hacking 12.) Let's take a look at all 13 cells, to give us an idea of what each one does:

Cell 01 - Farthest left side object.
Cell 02 - Middle left side object.
Cell 03 - Immediate left side object.
Cell 04 - Farthest right side object.
Cell 05 - Middle right side object.
Cell 06 - Immediate right side object.
Cell 07 - Farthest front object.
Cell 08 - Middle front object.
Cell 09 - Immediate front object . (Currently used for backdrop only; 
          fills the entire 12x12 screen.)
Cell 10 - Farthest left side object situated in front.
Cell 11 - Middle left side object situated in front.
Cell 12 - Farthest right side object situated in front.
Cell 13 - Middle right side object situated in front.
The 3-D engine, before it starts to redraw the 12x12 screen, checks the user's (you!) orientation. If you are facing north, the engine will know this and configure the 3-D window accordingly. Let's assume that the user is facing north, and the 3-D engine now looks in the dungeon map for relevant objects to place on the screen. The 3-D engine will look for doors or walls only. In future revisions, this is expected to change. Currently, the map value for a wall is 128 and for a door is 7.

First of all, the 3-D engine looks in Cell 3. If it finds an object there, it will paint a wall or door and will skip the search in Cell 11. The reason why Cell 11 was skipped is because an object was found in Cell 3, which would overwrite Cell 11. We don't want the 3-D engine accidentally overwriting Cell 3 with Cell 11 on top. Next, it searches for an object in Cell 6, and if it finds an object there, it will skip Cell 13. Last, it will search in Cell 8, and if an object is found, it will skip all remaining cells except for Cells 10 & 12. This is to ensure that there are no overlapping cells which result in a less-than harmonious 3-D look and feel. This hunt and eliminate approach employed by the 3-D engine can be referred to as a first-last approach. There are three layers of information for the 3-D engine to process, and it starts from the 1st layer to the 3rd layer, minimizing conflicts and results in a natural 3-D look.

Here's the sample code for the direction of north:

;paint the north surroundings ; Note: the .Y register refers to the location in the map for the 3-D ; engine to search. ; position the paint location npaint =* lda #101 sta subtract+1 sta addition+1 jsr minus ;first block module ldy #100:jsr cell3 ;second block module bne +:ldy #74:jsr cell11 + ldy #102:jsr cell6 bne +:ldy #78:jsr cell13 ;third block module + ldy #76:jsr cell8:bne + ;fourth block module ldy #50:jsr cell2 ;fifth block module ldy #52:jsr cell5 ;sixth block module ldy #26:jsr cell7:bne + ;seventh block module ldy #0:jsr cell1 ;eighth block module ldy #2:jsr cell4 + ldy #24:jsr cell10 ldy #28:jsr cell12 ;position the party jmp plus

Drawing the Screen

Now, on to the actual drawing of the 12x12 3-D screen! First, the 3-D engine immediately draws a backdrop to Cell 9. This is the floor and the sky you see in the 3-D world. (This step may be unnecessary in the future.) Then, the 3-D engine takes the object found in a particular cell and draws the object on the SEAM in the 12x12 window. Remember the SEAM's, eh? Depending on the size of the object, the 3-D engine may encompass two or more SEAM's in one sitting. First, it takes the pointer values from the graphic tables, extracts the raw graphics data, and stashes the same raw data on to the character dot data area. Please note that the 3-D engine does not stash the data to the screen; only to the character dot data area. Remember that the 12x12 had a character grid- the VIC-II chip continuously updates the characters with its corresponding dot data. Hence the reason why the characters never change in the 12x12 3-D window. This is needed for two reasons: One, the 12x12 grid uses only 144 of the 256 available characters, leaving some left over for regular character. Two, it allows the 3-D engine to `unroll' the graphics updating loop using self-modifying code , resulting in speed increases.

Here's a sample code for the grunt screen updating routine:

;to paint the 3d surroundings paint =* lda #59:ldy #128; This is the lo-hi byte representation of ; the character sta dummy+2:sty dummy+1; dot data area. lda <milleu:ldy >milleu; the pointer to where the backdrop ; can be found. sta dumb+1:sty dumb+2 ldx #$03 - lda #$00 sta disflag,x; this flag is used for hidden objects. tay dumb lda $ffff,y dummy sta $ffff,y; This is the self-modifying code to draw the ; backdrop. dey bne dumb inc dummy+2 inc dumb+2 dex bpl - ldy #127 - lda 22016,y sta 16256,y; The remaining part of the backdrop is drawn. dey bpl - jmp direction ; routine for printing two char wide column on the dungeon window table =* lda cassette,y; retrieves the pointer values from a table. sta twain+1; The table is stored in the cassette buffer at ; 820. iny lda cassette,y sta twain+2 lda chartable,x sta seam+1; This retrieves the pointer values from a table ; for inx ; the character dot data area. lda chartable,x sta seam+2 ldy #192; to output enough bytes to fill 24 characters. twain lda $ffff,y; Self-modifying code used here to draw the ; 3-D screen. seam sta $ffff,y dey bne twain dey rts

Conclusions

Whew! The 3-D engine has finally done its work and waits for the user to press a key for a new facing. The 3-D engine by itself is quite small and flexible enough to handle as much as the programmer wants to throw at it! The power is in the tables and the 3-D hunt/eliminate routines.

The 3-D Dungeon Demo can be found in this issue of Commodore Hacking (Reference: code, SubRef: gfxcode), on the Commodore Hacking MAILSERV http://www.msen.com/~brain/pub/dungeon.sda [mirrored here at http://www.canberra.edu.au/~scott/C=Hacking/C-Hacking13/dungeon.sda] or in the file DUNGEON.SDA available at my site. There may be a c128 version in the offing, but in 40 col. mode. Of course, there are no planned versions for the c65. ;) Please note that it does not contain the source code. However, upon request, I will be happy to send you the source code in Buddy format. (Right now, I'm trying to make the source code assembler neutral to work in either ACEsembler or the Buddy assembler.

Right now, I have already done work in producing a Dungeon Master's environment- with a 12x12 screen grabber routine and a Retouch Studio. The 3-D engine will be overhauled completely to create a 3-D environment in the hi-res multi-color screen, as opposed to using custom characters. In the future, I hope to have a complete environment, where the user can design dungeons, comment them, add a bestiary, add custom doors and walls, and map editors for the purpose of playing pen & paper dungeon games. This way, the program only shows the visual aspects of the pen & paper genre; it will not have combat or character interaction. I expect a version to be ready by the end of summer '96. I'm not sure how I will release the software, but I will choose an appropriate medium for mass distribution that is accessible to C= users.

That's it! Feel free to drop me a line regarding this article. I'd be happy and will try my best to answer any questions or comments about this article. Until then, Happy 8-Bit computing!

C= Hacking Home | Issue 13 Contents


Copyright © 1992 - 1997 Commodore Hacking

Commodore, CBM, its respective computer system names, and the CBM logo are either registered trademarks or trademarks of ESCOM GmbH or VISCorp in the United States and/or other countries. Neither ESCOM nor VISCorp endorse or are affiliated with Commodore Hacking.

Commodore Hacking is published by:

Brain Innovations, Inc.
10710 Bruhn Avenue
Bennington, NE 68007

Last Updated: 1997-03-11 by Jim Brain