+adamantyr Posted August 29, 2012 Share Posted August 29, 2012 (edited) Okay, after abandoning my binary tree efforts, I moved on to something simpler. The maze algorithm first plots corridors, up to 512 squares, only hitting unvisited blocks. I store them in a stack area for easy retrieval later, and it also comes in handle for tracking where the corridors are as opposed to the rooms. Direction changes are set to only occur 1/16 of the time, so it makes very long straight corridors. It also picks up and starts a new corridor if it gets "trapped" anywhere. Room placement is more tricky. I wanted to use a "weighted" algorithm like Jaime Buck's to determine placement. Just randomly placing rooms anywhere on the map creates a lot of processing time, so instead I take a random corridor and try four set points around it for potential room spots. The weight measurement wants the following: Only blocks under the room itself and the immediate ring of squares around it A corridor somwhere within 2 squares of the room's edge Rooms are set to a hard-coded count of 16. Eventually I'll add door/archway/secret passage placement code to connect rooms to other rooms and corridors, which is why I want rooms to only be one square away from corridors. Issues include: Corridors that can double around and create double-wides... I suppose I could live with that if it happens, but it would look kinda messy. The corridor "start-over" method can create unconnected dungeon areas... which can be seen on the map Here is the maze generated by the code... the random function uses a set seed so it generates the same content all the time: DEF START REF VMBW,VSBW,VWTR,KSCAN RSTACK BSS 32 WS EQU >8300 WS2 EQU >8320 SCRADR EQU >0000 COLTAB EQU >0380 PATADR EQU >0800 STATUS EQU >837C KEYADR EQU >8374 KEYVAL EQU >8375 VDPTMR EQU >8378 DIRX BYTE 0,1,0,-1 DIRY BYTE -1,0,1,0 KEYS BYTE 'E','X','S','D',0 ANYKEY BYTE >20 B1 BYTE 1 B2 BYTE 2 B4 BYTE 4 B8 BYTE 8 B48 BYTE 48 B63 BYTE 63 B97 BYTE 97 B128 BYTE 128 B129 BYTE 129 EVEN ZERO DATA 0 W1 DATA 1 W4 DATA 4 W64 DATA 64 MCOUNT DATA 512 RCOUNT DATA 16 SEED DATA >26D5 MAXVAL DATA >FFFF KSUB DATA MOVEUP,MOVEDN,MOVELF,MOVERT RVALUE DATA 0,1,-4 CSTACK BSS 1024 MAZE BSS 4096 ROW BSS 2 COL BSS 2 TROW BSS 2 TCOL BSS 2 DIRECT BSS 2 TCOUNT BSS 2 POSY BSS 2 POSX BSS 2 RMDATA BSS 6 CHARS DATA >FFFF,>FFFF,>FFFF,>FFFF DATA >0000,>0000,>0000,>0000 BSS 16 * Main routine START LWPI WS LI R10,RSTACK LI R0,COLTAB+16 LI R1,>1F1F BLWP @VSBW LI R0,PATADR+1024 LI R1,CHARS LI R2,16 BLWP @VMBW BL @CLRSCR * Create maze BL @MKMAZE CLR @POSY CLR @POSX * Maze look routine MLOOP BL @MZDRAW KSC1 CLR @KEYADR KSC2 CLR @STATUS LIMI 2 LIMI 0 KSC3 BLWP @KSCAN CB @ANYKEY,@STATUS JNE KSC2 CB @KEYVAL,@B97 JLT KSC4 SB @ANYKEY,@KEYVAL KSC4 LI R2,KEYS KSC5 CB *R2,@KEYVAL JEQ KSC6 MOVB *R2,*R2+ JEQ KSC2 JMP KSC5 KSC6 LI R3,KEYS LI R0,KSUB S R3,R2 SLA R2,1 A R2,R0 MOV *R0,R1 BL *R1 JMP MLOOP MOVEUP MOV @POSY,@POSY JEQ MU1 DEC @POSY MU1 RT MOVEDN MOV @POSY,R0 CI R0,40 JEQ MD1 INC @POSY MD1 RT MOVELF MOV @POSX,@POSX JEQ ML1 DEC @POSX ML1 RT MOVERT MOV @POSX,R0 CI R0,32 JEQ MR1 INC @POSX MR1 RT MZDRAW MOV @POSY,R2 SLA R2,6 A @POSX,R2 LI R0,SCRADR LI R1,MAZE A R2,R1 LI R2,32 LI R3,24 MZD1 BLWP @VMBW AI R0,32 AI R1,64 DEC R3 JNE MZD1 RT * Make Maze MKMAZE MOV R11,*R10+ * Fill maze buffer with blocks LI R0,MAZE LI R1,>8080 LI R2,2048 MKM1 MOV R1,*R0+ DEC R2 JNE MKM1 CLR @DIRECT * Choose a random start point (CSTACK contains all corridor locations) MKM2 LI R8,CSTACK CLR @ROW CLR @COL LI R3,62 BLWP @RNDNUM INC R4 MOVB @WS+9,@ROW BLWP @RNDNUM INC R4 MOVB @WS+9,@COL MOVB @ROW,*R8+ MOVB @COL,*R8+ * Choose a random direction or keep same? (1/16 chance) MKM3 LI R9,4 BLWP @RANDOM ANDI R4,>000F JNE MKM5 MKM4 BLWP @RANDOM ANDI R4,>0003 MOV R4,@DIRECT MKM5 MOV @DIRECT,R4 BL @GODIR MOV R0,R0 JNE MKM6 DEC R9 JNE MKM4 JMP MKM2 * Plot in that direction MKM6 MOVB @TROW,@ROW MOVB @TCOL,@COL MOVB @TROW,*R8+ MOVB @TCOL,*R8+ BL @GRDIDX LI R0,MAZE A R1,R0 MOVB @B129,*R0 DEC @MCOUNT JNE MKM3 * Draw rooms * Determine random size (3-12) on each side MKM7 LI R3,10 BLWP @RNDNUM AI R4,3 MOV R4,@RMDATA+2 BLWP @RNDNUM AI R4,3 MOV R4,@RMDATA+4 * Find a corridor on the map, put into @ROW,@COL MKM8 BLWP @RANDOM ANDI R4,>01FF SLA R4,1 MOVB @CSTACK(R4),@ROW MOVB @CSTACK+1(R4),@COL * Determine 4 random positions of room around corridor LI R8,CHARS CLR R9 MKM9 MOV @ROW,@TROW MOV @COL,@TCOL SB @RMDATA+3,@TROW SB @RMDATA+5,@TCOL SB @B1,@TROW SB @B1,@TCOL BL @EDGCHK MOV R0,R0 JEQ MKM9A MOVB @TROW,*R8+ MOVB @TCOL,*R8+ INC R9 MKM9A MOV @ROW,@TROW MOV @COL,@TCOL AB @B2,@TROW AB @B2,@TCOL BL @EDGCHK MOV R0,R0 JEQ MKM9B MOVB @TROW,*R8+ MOVB @TCOL,*R8+ INC R9 MKM9B MOV @ROW,@TROW MOV @COL,@TCOL SB @RMDATA+3,@TROW SB @B1,@TROW AB @B2,@TCOL BL @EDGCHK MOV R0,R0 JEQ MKM9C MOVB @TROW,*R8+ MOVB @TCOL,*R8+ INC R9 MKM9C MOV @ROW,@TROW MOV @COL,@TCOL SB @RMDATA+5,@TCOL SB @B1,@TCOL AB @B2,@TROW BL @EDGCHK MOV R0,R0 JEQ MKM9D MOVB @TROW,*R8+ MOVB @TCOL,*R8+ INC R9 * Determine "value" of each random room MKM9D MOV R9,@TCOUNT JEQ MKM8 CLR R3 MKM10 MOVB @CHARS(R3),@ROW MOVB @CHARS+1(R3),@COL BLWP @ROOMCK MOV R0,@CHARS+16(R3) INCT R3 DEC R9 JNE MKM10 * Pick best value room and draw it CLR R3 MOV @TCOUNT,R9 CLR R0 SETO R1 MKM11 C R0,@CHARS+16(R3) JGT MKM12 MOV @CHARS+16(R3),R0 MOV R3,R1 MKM12 INCT R3 DEC R9 JNE MKM11 C R1,@MAXVAL JNE MKM13 B @MKM7 * Draw room, and decrement max room count MKM13 MOV @CHARS(R1),@RMDATA BL @DRAWRM DEC @RCOUNT JEQ MKM14 B @MKM7 MKM14 B @SUBRET * Room check - Delivers value of room * @ROW,@COL - Position * @RMDATA,@RMDATA+2 - Vertical and horizontal width * Result returned in R0 ROOMCK DATA WS2,RMCK1 RMCK1 CLR R8 MOV @RMDATA+2,R2 MOV @RMDATA+4,R3 MOV @ROW,@TROW MOV @COL,@TCOL SB @B1,@TROW SB @B1,@TCOL INCT R2 INCT R3 * First pass - Check underneath room footprint and outer edge; open space is "bad" RMCK2 BL @RGETVL SLA R4,2 S R4,R8 AB @B1,@TCOL DEC R3 JNE RMCK2 AB @B1,@TROW MOV @RMDATA+4,R3 INCT R3 MOV @COL,@TCOL SB @B1,@TCOL DEC R2 JNE RMCK2 * Second pass - Check 2 squares away in cardinal areas; open space is "good" * Top row MOV @RMDATA+2,R2 MOV @ROW,@TROW MOV @COL,@TCOL SB @B2,@TROW RMCK2A BL @EDGCHK MOV R0,R0 JEQ RMCK3 BL @RGETVL A R4,R8 AB @B1,@TCOL DEC R2 JNE RMCK2A * Bottom row RMCK3 MOV @RMDATA+2,R2 MOV @ROW,@TROW MOV @COL,@TCOL AB @B2,@TROW RMCK3A BL @EDGCHK MOV R0,R0 JEQ RMCK4 BL @RGETVL A R4,R8 AB @B1,@TCOL DEC R2 JNE RMCK3A * Left column RMCK4 MOV @RMDATA+4,R2 MOV @ROW,@TROW MOV @COL,@TCOL SB @B2,@TCOL RMCK4A BL @EDGCHK MOV R0,R0 JEQ RMCK5 BL @RGETVL A R4,R8 AB @B1,@TROW DEC R2 JNE RMCK4A * Right column RMCK5 MOV @RMDATA+4,R2 MOV @ROW,@TROW MOV @COL,@TCOL AB @B2,@TCOL RMCK5A BL @EDGCHK MOV R0,R0 JEQ RMCKE BL @RGETVL A R4,R8 AB @B1,@TROW DEC R2 JNE RMCK5A * Return value RMCKE MOV R8,@>0000(R13) RTWP * Calculate value of square RGETVL CLR R1 MOVB @TROW,@WS2+3 SLA R1,6 AB @TCOL,@WS2+3 CLR R4 MOVB @MAZE(R1),@WS2+9 ANDI R4,>007F RT * Draw room * @RMDATA - Row * @RMDATA+1 - Column * @RMDATA+2 - vertical width * @RMDATA+4 - horizontal width DRAWRM CLR R1 MOVB @RMDATA,@WS+3 SLA R1,6 AB @RMDATA+1,@WS+3 LI R0,MAZE A R1,R0 MOV @RMDATA+2,R2 MOV @RMDATA+4,R3 DRWRM1 MOVB @B129,*R0+ DEC R3 JNE DRWRM1 AI R0,64 MOV @RMDATA+4,R3 S R3,R0 DEC R2 JNE DRWRM1 RT * Check a given direction is valid edge-wise * R0 must not be zero GODIR MOVB @ROW,@TROW MOVB @COL,@TCOL AB @DIRY(R4),@TROW AB @DIRX(R4),@TCOL EDGCHK CLR R0 * Check if over edge CB @TROW,@B63 JHE EC1 CB @TCOL,@B63 JHE EC1 MOVB @TROW,@TROW JLE EC1 MOVB @TCOL,@TCOL JLE EC1 SETO R0 EC1 RT * Get grid index from @ROW,@COL * Returns in R1 GRDIDX CLR R1 MOVB @ROW,@WS+3 SLA R1,6 AB @COL,@WS+3 RT * Clear screen CLRSCR LI R0,SCRADR LI R1,>2000 LI R4,768 CSLOOP BLWP @VSBW INC R0 DEC R4 JNE CSLOOP RT * Random number generator (Range in R3, Result in R4) * Returns 0 to R3-1 RNDNUM DATA WS2,RAND2 RAND2 BL @RNDGEN MOV @>0006(R13),R3 CLR R4 DIV R3,R4 MOV R5,@>0008(R13) RTWP * Random number generator 16-bit (Result in R4) * returns 0-65535 RANDOM DATA WS2,RAND1 RAND1 BL @RNDGEN MOV R5,@>0008(R13) RTWP * Random number generation RNDGEN LI R4,23729 MPY @SEED,R4 AI R5,31871 SRC R5,5 MOV R5,@SEED RT * Nested return from subroutine SUBRET DECT R10 MOV *R10,R11 RT * Program end END START Edited August 30, 2012 by adamantyr Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted August 29, 2012 Author Share Posted August 29, 2012 Okay, I fixed one issue; instead of choosing a random point to restart when drawing corridors, it selects a previously visited square and traverses from there. That way you don't ever have unconnected corridors. The resulting maze looks MUCH better too: Adamantyr Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted August 29, 2012 Author Share Posted August 29, 2012 (edited) Okay, some more revisions and I got a pretty good dungeon generator going! After messing around with several different corridor implementations to try and stop it from creating double-wides, I finally found the answer: Check the parallel blocks when moving a particular direction. This allows it to avoid creating corridors next to each other, and it fills up rather nicely. Room placement had some bugs before; I was checking the upper-left room corner was in boundary but not the lower right, which caused some spillover rooms in the maze array. I also altered placement a bit, and the result is much more drop down pleasing. I don't have time to do screen captures of the results, but you can see them as ASCII code below. Guess I should start thinking about door algorithms next... ################################################################ ################################################################ #........................................####################### #........................................####################### #.###########.##########################.####################### #.###########.##########################.#............########## #.............##########################.####################### #.............##########################.#............########## #.######################################.####################### #.######################################.#............########## #.######################################.####################### #.########...........###################.#............########## #.#################################......####################### #.########...........##############......####################### #.#################################.####.####################### #.########...........##############.####.#.......############### #.#################################.####.####################### #.########...........##############.####.#.......############### #.#################################.####.####################### #.#################################.####.#.......############### #......................................#.####################### #......................................#.#.......############### ########.#########.####.#.############.#.####################### ########.#########.####.#.############.#.####################### ########.#########.####.#.############.#.####################### ########.##....###.####.#.####...#####.#.####################### #####....#########.####.#.############.#.####################### #####....##....###.####.#.####...#####.#.####################### #####.##.#########.####.#.############.#.####################### #####.##.##....###.####.#.####...#####.#.####################### #####.##.#########.####.#.############.#.####################### #####.##.##....###.####.#.####...#####.#.#.........############# #####....#########.####.#.############.#.####################### #####....##....###.####.#.####...#####.#.#.........############# ########.#########.####.#.##############.####################### ########.##....###.####.#.####...#######.#.........############# ########.#########.####.#.##############.####################### ########.##....###.####.#.####...#######.#.........############# ########.#########.####.#.##############.####################### ########.#########.####.#.####...#######.#.........############# ########.#########.####.#.##############.#####################.# ########.#......##.####.#.##############.#.........###########.# ########.#########.####.#.##############.#####################.# ########.#......##.####.#.##############.#.........###########.# ########.#########.####..................#####################.# ########.#......##.####..................#.........###########.# ########.#########.#############.##.##########################.# ########.#......##.#############.##.######.........###########.# ########.#########.#############.##.##########################.# ########.#......##.###....######.##.######.........###########.# ########.#########.#############.##.##########################.# ########.#......##.###....######.##.######.........###########.# ########.#########.#############.##.##########################.# ##.....#.#......##.###....######.##.######.........###########.# ########.#########.#############.##.##########################.# ##.....#.#......##.###....######.##.##########################.# ########.#########.#############.##.##########################.# ##.....#.#......##.###....######.##.##########################.# ########.#########.#############.##.##########################.# ##.....#.#......##.###....######.##.##########################.# ########.#########.#############.##.##########################.# ##.....#.#########.###....######.##.##########################.# ########.#########.#############.##.##########################.# ##.....#.#...#####.###....######.##.#.........################.# ########.#########.#############.##.##########################.# ##.....#.#...#####.###....######.##.#.........################.# ########.#########.#############.##.##########################.# ##.....#.#...#####.###....######.##.#.........################.# ########.#########.#############.##.##########################.# ##.....#.#...#####.###....######.##.##########################.# ########.#########.#############.##.##########################.# ##.....#.#...#####.###....######.##.##########################.# ########.#########.#############.##.##########################.# ##.....#.#...#####.#############.##.#.......##################.# ########.#########.#############.##.##########################.# ########.#...#####.#############.##.#.......##################.# ########.#########.#############.##.##########################.# ########.#...#####.#############.##.#.......##################.# ########.#########.#############.##.##########################.# ########.#...#####.#############.##.#.......##################.# ########.#########.#############.##.##########################.# ########.#...#####.#############.##.##########################.# ########.#########.#############.##.##########################.# ########.#########.#############.##.#####............#########.# ########.#########.#############.##.##########################.# ########.#########.#.....#######.##.#####............#########.# ########.#########.#############.##.##########################.# ########.#########.#.....#######.##.#####............#########.# ########.#########.#############.##.##########################.# ########.#########.#.....#######.##.#####............#########.# ########.#########.#############.##.##########################.# ########.#########.#############.##.#####............#########.# ########.#########.#############.##.##########################.# ########.#########.#############.##.#####............#########.# ########.#########.#############.##.##########################.# ########.#########.#############.##.##########################.# ########.#########.#############.##............................# ########.#########.#############.##............................# ########.#########.#############.#############.################# ########.#########.#############.#############.################# ########.#########.#############.#############.################# ########.#########.#############.#############.######......##### ########.#########.#############.#############.################# ########.#########.#############.#############.######......##### ########.#########.#############.#############.################# ########.#########.#############.#############.######......##### ########.#########.#############.#############.################# ########.#########.#############.#############.######......##### #........#########.#############.#############.################# #........#########.#############.#############.######......##### #.###.##.#########.#############.##########.##.################# #.###.##.#########.#############.#......###.##.################# #.....##.#########.#############.##########.##.################# #.....##.#########.#############.#......###.##.################# #.######.####......#############.##########.##.################# #.######.####......#############.#......###.##.################# #.######.####.##################.##########.##.................# #.######.####.##################.#......###.##.................# #........####.##################.##########.##.#.######.######.# #........####.##################.#......###.##.#.######.######.# #############.##################.##########.##.#.######.######.# #############.##################.#......###.##.#.######.######.# #############.##################.##########.##.#.######.######.# #############.##################.##########.##.#.######.######.# #############........###########............##.................# #############........###########............##.................# ################################################################ ################################################################ Edited August 29, 2012 by adamantyr Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted August 30, 2012 Author Share Posted August 30, 2012 Some more revisions... I added door and stair placement. Stairs are placed at dead-ends, I traverse the stack of corridors to find these by looking for ones that are cardinally surrounded by only a single corridor. I'll eventually add some code in to place them in rooms if no dead-ends are available. Doors are trickier. Checking and storing coordinates for potential doors for each room creates a lot of options. At first I tried random door amounts per room but this was way too messy. I ended up making it a single door, with a distinct possibility (1/16 chance) of a second door. I may need to revisit this to make it smarter and only place a single door on a side of a room, which would make multiple doors more logical. Here's a screenshot: Adamantyr Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted August 30, 2012 Share Posted August 30, 2012 The screenshot reminded me of Tunnels of Doom. Is the algorithm used to generate the ToD dungeons documented anywhere? I'm not ashamed to say I spent an entire summer 'trudging' up and down those 10-level dungeons with my brothers long ago Quote Link to comment Share on other sites More sharing options...
+retroclouds Posted August 30, 2012 Share Posted August 30, 2012 The screenshot reminded me of Tunnels of Doom. Is the algorithm used to generate the ToD dungeons documented anywhere? I'm not ashamed to say I spent an entire summer 'trudging' up and down those 10-level dungeons with my brothers long ago There you go: http://www.atariage.com/forums/topic/187918-tunnels-of-doom-map-generation-algorithm/#entry2373742 Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted August 30, 2012 Author Share Posted August 30, 2012 The screenshot reminded me of Tunnels of Doom. Is the algorithm used to generate the ToD dungeons documented anywhere? I'm not ashamed to say I spent an entire summer 'trudging' up and down those 10-level dungeons with my brothers long ago There you go: http://www.atariage....m/#entry2373742 Thanks, Retro! I knew I had read about the ToD algorithm somewhere, but I couldn't remember where exactly. Currently my dungeon generator takes the most time doing room placement, several real-time seconds. Still, I think I could generate 10 levels of dungeon pretty quick. I'm definitely leaning towards storing it all on disk rather than trying to make it up as you go along. Adamantyr Quote Link to comment Share on other sites More sharing options...
+adamantyr Posted August 30, 2012 Author Share Posted August 30, 2012 (edited) Oh, and here is the listing for the current code (hidden in spoiler so as to not make the thread super-huge): DEF START REF VMBW,VSBW,VWTR,KSCAN RSTACK BSS 32 WS EQU >8300 WS2 EQU >8320 SCRADR EQU >0000 COLTAB EQU >0380 PATADR EQU >0800 STATUS EQU >837C KEYADR EQU >8374 KEYVAL EQU >8375 VDPTMR EQU >8378 DIRX BYTE 0,1,0,-1 DIRY BYTE -1,0,1,0 KEYS BYTE 'E','X','S','D',0 ANYKEY BYTE >20 B1 BYTE 1 B2 BYTE 2 B4 BYTE 4 B8 BYTE 8 B48 BYTE 48 B63 BYTE 63 B97 BYTE 97 B128 BYTE 128 B129 BYTE 129 B130 BYTE 130 BYTE 131 BYTE 132 MSG TEXT 'Digging corridors...' TEXT 'Building rooms...' TEXT 'Adding doors...' TEXT 'Adding stairs...' EVEN ZERO DATA 0 W1 DATA 1 W4 DATA 4 W64 DATA 64 MCOUNT DATA 512 RCOUNT DATA 16 SEED DATA >26D5 MAXVAL DATA >FFFF KSUB DATA MOVEUP,MOVEDN,MOVELF,MOVERT ROW BSS 2 COL BSS 2 TROW BSS 2 TCOL BSS 2 DIRECT BSS 2 TCOUNT BSS 2 POSY BSS 2 POSX BSS 2 RMDATA BSS 6 CHARS DATA >FFFF,>FFFF,>FFFF,>FFFF DATA >0000,>0000,>0000,>0000 DATA >FF81,>BDBD,>BDBD,>BDBD DATA >0010,>387C,>1010,>1000 DATA >0010,>1010,>7C38,>1000 ROOMS BSS 128 DOORS BSS 128 HALLS BSS 1024 MAZE BSS 4096 * Main routine START LWPI WS LI R10,RSTACK LI R0,COLTAB+16 LI R1,>1F1F BLWP @VSBW LI R0,PATADR+1024 LI R1,CHARS LI R2,40 BLWP @VMBW * Create halls BL @CLRSCR LI R0,SCRADR+130 LI R1,MSG LI R2,20 BLWP @VMBW BL @MKHALL * Create rooms BL @CLRSCR LI R0,SCRADR+130 LI R1,MSG+20 LI R2,17 BLWP @VMBW BL @MKROOM * Create doors BL @CLRSCR LI R0,SCRADR+130 LI R1,MSG+37 LI R2,15 BLWP @VMBW BL @MKDOOR * Create stairs BL @CLRSCR LI R0,SCRADR+130 LI R1,MSG+52 LI R2,16 BLWP @VMBW BL @MKSTRS * Maze look routine CLR @POSY CLR @POSX MLOOP BL @MZDRAW KSC1 CLR @KEYADR KSC2 CLR @STATUS LIMI 2 LIMI 0 KSC3 BLWP @KSCAN CB @ANYKEY,@STATUS JNE KSC2 CB @KEYVAL,@B97 JLT KSC4 SB @ANYKEY,@KEYVAL KSC4 LI R2,KEYS KSC5 CB *R2,@KEYVAL JEQ KSC6 MOVB *R2,*R2+ JEQ KSC2 JMP KSC5 KSC6 LI R3,KEYS LI R0,KSUB S R3,R2 SLA R2,1 A R2,R0 MOV *R0,R1 BL *R1 JMP MLOOP MOVEUP MOV @POSY,@POSY JEQ MU1 DEC @POSY MU1 RT MOVEDN MOV @POSY,R0 CI R0,40 JEQ MD1 INC @POSY MD1 RT MOVELF MOV @POSX,@POSX JEQ ML1 DEC @POSX ML1 RT MOVERT MOV @POSX,R0 CI R0,32 JEQ MR1 INC @POSX MR1 RT MZDRAW MOV @POSY,R2 SLA R2,6 A @POSX,R2 LI R0,SCRADR LI R1,MAZE A R2,R1 LI R2,32 LI R3,24 MZD1 BLWP @VMBW AI R0,32 AI R1,64 DEC R3 JNE MZD1 RT * Make Corridors MKHALL MOV R11,*R10+ * Fill maze buffer with blocks LI R0,MAZE LI R1,>8080 LI R2,2048 MKH1 MOV R1,*R0+ DEC R2 JNE MKH1 CLR @DIRECT * Choose a random start point (HALLS contains all corridor locations) MKH2 LI R8,HALLS CLR @ROW CLR @COL LI R3,62 BLWP @RNDNUM INC R4 MOVB @WS+9,@ROW BLWP @RNDNUM INC R4 MOVB @WS+9,@COL MOVB @ROW,*R8+ MOVB @COL,*R8+ DEC @MCOUNT * Choose a random direction or keep same? (1/16 chance) MKH3 LI R9,4 BLWP @RANDOM ANDI R4,>000F JNE MKH5 MKH4 BLWP @RANDOM ANDI R4,>0003 MOV R4,@DIRECT MKH5 MOV @DIRECT,R4 BL @GODIR MOV R0,R0 JEQ MKH5A BL @VALCOR MOV R0,R0 JNE MKH6 MKH5A DEC R9 JNE MKH4 * If no valid direction can be found after 4 tries, retreat to previous corridor point LI R3,512 S @MCOUNT,R3 BLWP @RNDNUM SLA R4,1 MOVB @HALLS(R4),@ROW MOVB @HALLS+1(R4),@COL JMP MKH3 * Plot in that direction MKH6 MOVB @TROW,@ROW MOVB @TCOL,@COL MOVB @TROW,*R8+ MOVB @TCOL,*R8+ BL @GRDIDX MOVB @B129,@MAZE(R1) DEC @MCOUNT JNE MKH3 B @SUBRET * Make Rooms MKROOM MOV R11,*R10+ LI R6,ROOMS * Determine random size (3-12) on each side MKR1 LI R3,10 BLWP @RNDNUM AI R4,3 MOV R4,@RMDATA+2 BLWP @RNDNUM AI R4,3 MOV R4,@RMDATA+4 * Find a corridor on the map, put into @ROW,@COL MKR2 BLWP @RANDOM ANDI R4,>01FF SLA R4,1 MOVB @HALLS(R4),@ROW MOVB @HALLS+1(R4),@COL * Determine 4 random positions of room around corridor LI R8,CHARS CLR R9 LI R7,6 MKR3 MOV @ROW,@TROW MOV @COL,@TCOL BL @ROOMPL * Check upper left corner BL @EDGCHK MOV R0,R0 JEQ MKR3A MOVB @TROW,R1 MOVB @TCOL,@WS+3 AB @RMDATA+3,@TROW AB @RMDATA+5,@TCOL * Check lower right corner BL @EDGCHK MOV R0,R0 JEQ MKR3A MOV R1,*R8+ INC R9 MKR3A DECT R7 JGT MKR3 JEQ MKR3 * Determine "value" of each random room MOV R9,@TCOUNT JEQ MKR2 CLR R3 MKR4 MOVB @CHARS(R3),@ROW MOVB @CHARS+1(R3),@COL BLWP @ROOMCK MOV R0,@CHARS+16(R3) INCT R3 DEC R9 JNE MKR4 * Pick best value room and draw it CLR R3 MOV @TCOUNT,R9 CLR R0 SETO R1 MKR5 C R0,@CHARS+16(R3) JGT MKR6 MOV @CHARS+16(R3),R0 MOV R3,R1 MKR6 INCT R3 DEC R9 JNE MKR5 C R0,@W4 JLT MKR1 C R1,@MAXVAL JEQ MKR1 * Draw room, and decrement max room count MKR7 MOV @CHARS(R1),@RMDATA BL @DRAWRM MOV @RMDATA,*R6+ MOVB @RMDATA+3,*R6+ MOVB @RMDATA+5,*R6+ DEC @RCOUNT JNE MKR1 B @SUBRET * Make doors MKDOOR MOV R11,*R10+ LI R9,ROOMS LI R8,16 * Determine door count per room (1-4) MKDR1 MOVB *R9+,@ROW MOVB *R9+,@COL MOVB *R9+,@RMDATA+3 MOVB *R9+,@RMDATA+5 MOV @W1,R5 BLWP @RANDOM ANDI R4,>0007 JNE MKDR2 INC R5 MKDR2 BLWP @DOORCK MKDR3 BLWP @RNDNUM SLA R4,1 MOV @DOORS(R4),R0 CLR R1 MOVB R0,@WS+3 SLA R1,6 AB @WS+1,@WS+3 CB @B130,@MAZE(R1) JEQ MKDR2 MOVB @B130,@MAZE(R1) DEC R5 JNE MKDR3 DEC R8 JNE MKDR1 B @SUBRET * Make stairs MKSTRS MOV R11,*R10+ LI R9,HALLS LI R8,DOORS LI R7,512 CLR R5 * Locate all dead-ends in dungeon corridors MKS2 MOVB *R9+,@ROW MOVB *R9+,@COL CLR R4 LI R1,3 MKS3 CLR R2 MOVB @ROW,@TROW MOVB @COL,@TCOL AB @DIRY(R1),@TROW AB @DIRX(R1),@TCOL MOVB @TROW,@WS+5 SLA R2,6 AB @TCOL,@WS+5 MOVB @MAZE(R2),R0 ANDI R0,>7F00 AB R0,R4 DEC R1 JGT MKS3 JEQ MKS3 CB @B1,R4 JEQ MKS5 MKS4 DEC R7 JNE MKS2 JMP MKS5A MKS5 MOVB @ROW,*R8+ MOVB @COL,*R8+ INC R5 JMP MKS4 * All dead-ends found, now place stairs * Are there at least two dead-ends? MKS5A CI R5,2 JHE MKS6 * If not, skip JMP MKS8 MKS6 LI R2,2 MKS7 MOV R5,R3 BLWP @RNDNUM SLA R4,1 MOVB @DOORS(R4),@WS+3 SLA R1,6 AB @DOORS+1(R4),@WS+3 CB @MAZE(R1),@B129 JNE MKS7 MOVB @B130(R2),@MAZE(R1) DEC R2 JNE MKS7 MKS8 B @SUBRET * Door check - Finds valid door positions around room * @ROW,@COL - Position of room * @RMDATA+2,@RMDATA+4 - Vertical and horizontal width * Result returned in DOORS array and R3 DOORCK DATA WS2,DOCK1 DOCK1 LI R8,DOORS CLR R9 CLR @DIRECT * Bottom row MOV @RMDATA+4,R2 MOV @ROW,@TROW MOV @COL,@TCOL AB @B1,@TROW AB @RMDATA+3,@TROW DOCK2 BL @EDGCHK MOV R0,R0 JEQ DOCK3 BL @DFIND AB @B1,@TCOL DEC R2 JNE DOCK2 * Left column DOCK3 INC @DIRECT MOV @RMDATA+2,R2 MOV @ROW,@TROW MOV @COL,@TCOL SB @B2,@TCOL DOCK4 BL @EDGCHK MOV R0,R0 JEQ DOCK5 BL @DFIND AB @B1,@TROW DEC R2 JNE DOCK4 * Top row DOCK5 INC @DIRECT MOV @RMDATA+4,R2 MOV @ROW,@TROW MOV @COL,@TCOL SB @B2,@TROW DOCK6 BL @EDGCHK MOV R0,R0 JEQ DOCK7 BL @DFIND AB @B1,@TCOL DEC R2 JNE DOCK6 * Right column DOCK7 INC @DIRECT MOV @RMDATA+2,R2 MOV @ROW,@TROW MOV @COL,@TCOL AB @B1,@TCOL AB @RMDATA+5,@TCOL DOCK8 BL @EDGCHK MOV R0,R0 JEQ DOCKE BL @DFIND AB @B1,@TROW DEC R2 JNE DOCK8 * Return value DOCKE MOV R9,@>0006(R13) RTWP * Find potential door spot DFIND CLR R1 MOVB @TROW,@WS2+3 SLA R1,6 AB @TCOL,@WS2+3 CB @MAZE(R1),@B129 JNE DFIND1 MOV @DIRECT,R4 MOVB @TROW,*R8 AB @DIRY(R4),*R8+ MOVB @TCOL,*R8 AB @DIRX(R4),*R8+ INC R9 DFIND1 RT * Validate corridor - check block and parallel blocks for other corridors VALCOR CLR R0 CLR R3 MOVB @TROW,@WS+7 SLA R3,6 AB @TCOL,@WS+7 CB @MAZE(R3),@B129 JEQ VALCR1 MOV @DIRECT,R2 INC R2 ANDI R2,>0003 CLR R3 MOVB @TROW,@WS+7 AB @DIRY(R2),@WS+7 SLA R3,6 AB @TCOL,@WS+7 AB @DIRX(R2),@WS+7 CB @MAZE(R3),@B129 JEQ VALCR1 INCT R2 ANDI R2,>0003 CLR R3 MOVB @TROW,@WS+7 AB @DIRY(R2),@WS+7 SLA R3,6 AB @TCOL,@WS+7 AB @DIRX(R2),@WS+7 CB @MAZE(R3),@B129 JEQ VALCR1 SETO R0 VALCR1 RT * Room placement RMPSEL DATA RMUP,RMDOWN,RMLEFT,RMRGHT ROOMPL MOV @RMPSEL(R7),R0 B *R0 * Up RMUP SB @RMDATA+3,@TROW SB @B1,@TROW MOVB @RMDATA+5,R0 SRL R0,1 SB R0,@TCOL JMP RMPEND * Down RMDOWN AB @B2,@TROW MOVB @RMDATA+5,R0 SRL R0,1 SB R0,@TCOL JMP RMPEND * Left RMLEFT MOVB @RMDATA+3,R0 SRL R0,1 SB R0,@TROW SB @RMDATA+5,@TCOL SB @B1,@TCOL JMP RMPEND * Right RMRGHT MOVB @RMDATA+3,R0 SRL R0,1 SB R0,@TROW AB @B2,@TCOL JMP RMPEND RMPEND RT * Room check - Delivers value of room * @ROW,@COL - Position * @RMDATA,@RMDATA+2 - Vertical and horizontal width * Result returned in R0 ROOMCK DATA WS2,RMCK1 RMCK1 CLR R8 MOV @RMDATA+2,R2 MOV @RMDATA+4,R3 MOV @ROW,@TROW MOV @COL,@TCOL SB @B1,@TROW SB @B1,@TCOL INCT R2 INCT R3 * First pass - Check underneath room footprint and outer edge; open space is "bad" RMCK2 BL @RGETVL SLA R4,2 S R4,R8 AB @B1,@TCOL DEC R3 JNE RMCK2 AB @B1,@TROW MOV @RMDATA+4,R3 INCT R3 MOV @COL,@TCOL SB @B1,@TCOL DEC R2 JNE RMCK2 * Second pass - Check 2 squares away in cardinal areas; open space is "good" * Top row MOV @RMDATA+4,R2 MOV @ROW,@TROW MOV @COL,@TCOL SB @B2,@TROW RMCK2A BL @EDGCHK MOV R0,R0 JEQ RMCK3 BL @RGETVL A R4,R8 AB @B1,@TCOL DEC R2 JNE RMCK2A * Bottom row RMCK3 MOV @RMDATA+4,R2 MOV @ROW,@TROW MOV @COL,@TCOL AB @B1,@TROW AB @RMDATA+3,@TROW RMCK3A BL @EDGCHK MOV R0,R0 JEQ RMCK4 BL @RGETVL A R4,R8 AB @B1,@TCOL DEC R2 JNE RMCK3A * Left column RMCK4 MOV @RMDATA+2,R2 MOV @ROW,@TROW MOV @COL,@TCOL SB @B2,@TCOL RMCK4A BL @EDGCHK MOV R0,R0 JEQ RMCK5 BL @RGETVL A R4,R8 AB @B1,@TROW DEC R2 JNE RMCK4A * Right column RMCK5 MOV @RMDATA+2,R2 MOV @ROW,@TROW MOV @COL,@TCOL AB @B1,@TCOL AB @RMDATA+5,@TCOL RMCK5A BL @EDGCHK MOV R0,R0 JEQ RMCKE BL @RGETVL A R4,R8 AB @B1,@TROW DEC R2 JNE RMCK5A * Return value RMCKE MOV R8,@>0000(R13) RTWP * Calculate value of square RGETVL CLR R1 MOVB @TROW,@WS2+3 SLA R1,6 AB @TCOL,@WS2+3 CLR R4 MOVB @MAZE(R1),@WS2+9 ANDI R4,>007F RT * Draw room * @RMDATA - Row * @RMDATA+1 - Column * @RMDATA+2 - vertical width * @RMDATA+4 - horizontal width DRAWRM CLR R1 MOVB @RMDATA,@WS+3 SLA R1,6 AB @RMDATA+1,@WS+3 LI R0,MAZE A R1,R0 MOV @RMDATA+2,R2 MOV @RMDATA+4,R3 DRWRM1 MOVB @B129,*R0+ DEC R3 JNE DRWRM1 AI R0,64 MOV @RMDATA+4,R3 S R3,R0 DEC R2 JNE DRWRM1 RT * Check a given direction is valid edge-wise * R0 must not be zero GODIR MOVB @ROW,@TROW MOVB @COL,@TCOL AB @DIRY(R4),@TROW AB @DIRX(R4),@TCOL EDGCHK CLR R0 * Check if over edge CB @TROW,@B63 JHE EC1 CB @TCOL,@B63 JHE EC1 MOVB @TROW,@TROW JLE EC1 MOVB @TCOL,@TCOL JLE EC1 SETO R0 EC1 RT * Get grid index from @ROW,@COL * Returns in R1 GRDIDX CLR R1 MOVB @ROW,@WS+3 SLA R1,6 AB @COL,@WS+3 RT * Clear screen CLRSCR LI R0,SCRADR LI R1,>2000 LI R4,768 CSLOOP BLWP @VSBW INC R0 DEC R4 JNE CSLOOP RT * Random number generator (Range in R3, Result in R4) * Returns 0 to R3-1 RNDNUM DATA WS2,RAND2 RAND2 BL @RNDGEN MOV @>0006(R13),R3 CLR R4 DIV R3,R4 MOV R5,@>0008(R13) RTWP * Random number generator 16-bit (Result in R4) * returns 0-65535 RANDOM DATA WS2,RAND1 RAND1 BL @RNDGEN MOV R5,@>0008(R13) RTWP * Random number generation RNDGEN LI R4,23729 MPY @SEED,R4 AI R5,31871 SRC R5,5 MOV R5,@SEED RT * Nested return from subroutine SUBRET DECT R10 MOV *R10,R11 RT * Program end END START Edited August 30, 2012 by adamantyr Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.