mapgen: wip door generator
authorLukas Krickl <lukas@krickl.dev>
Thu, 21 Aug 2025 13:47:19 +0000 (15:47 +0200)
committerLukas Krickl <lukas@krickl.dev>
Thu, 21 Aug 2025 13:47:19 +0000 (15:47 +0200)
src/mapgen.s

index c56b0b0344092edf7636b65f951a5c72b759acac..a03a085b2e4d760373123327e7cfc7cb87c117ce 100644 (file)
@@ -142,18 +142,186 @@ mapgen:
   ret
        
        ; generates door locations for each map
+       ; starts at location 3/3 and moves one door at a time
+       ; avoids placing doors at the edge.
+       ; stops after plaving at least N  doors
 mapgen_make_doors:
-       ld a, FLOOR_MAP_COUNT
-       ld hl, map_doors_location
-       ; TODO: fnor now just place all 4 doors
+       ld b, 3
+       ld c, 3 ; bc = y/x position
+       ; start current ptr at 1/1 as well
+       ld hl, map_doors_location + 1  * FLOOR_W 
+
+       ; set map cursor
+       ld a, 1 + FLOOR_W
+       ld [player_map_cursor], a
+       
+       ; select how many doors we want
+       push bc
+       push hl
+       call rand
+       add a, FLOOR_MAP_COUNT * 2 ; at least N doors
+       and a, (FLOOR_MAP_COUNT - 1) * 4
+
+       pop hl
+       pop bc
+
 @loop:
                push af
-               ld a, DIRUP | DIRDOWN | DIRLEFT | DIRRIGHT
-               ld [hl+], a
+               push hl
+               push bc
+
+               ; select a random location
+
+               call rand
+               and a, 3 
+
+               pop bc
+               pop hl
+               
+               call make_door
+               cp a, 0xFF
+               jp z, @loop ; try again
+               call make_opp_door
+
                pop af
                dec a
                jr nz, @loop REL
        ret
+       
+       ; creates the counterpart to 
+       ; a recently created door
+       ;       inputs:
+       ;               a: 1 = UP, 2 = DOWN, 3 = LEFT, 0 = RIGHT
+       ;               [hl]: current door ptr
+       ;       returns:
+       ;               [hl]: ord new door
+make_opp_door:
+       cp a, 0
+       jp z, @right
+       cp a, 1
+       jp z, @up
+       cp a, 2
+       jp z, @down
+       cp a, 3
+       jp z, @left
+
+@right:        
+       ld a, [hl]
+       or a, DIRLEFT 
+       ld [hl], a
+       ret
+@up:   
+       ld a, [hl]
+       or a, DIRDOWN
+       ld [hl], a
+       ret
+@down:
+       ld a, [hl]
+       or a, DIRUP
+       ld [hl], a
+       ret
+@left:
+       ld a, [hl]
+       or a, DIRRIGHT
+       ld [hl], a
+       ret
+
+       ; creates a single door
+       ; based on the random selection
+       ; inputs:
+       ;               a: 1 = UP, 2 = DOWN, 3 = LEFT, 0 = RIGHT
+       ;               bc: current coordinate
+       ;               hl: current ptr
+       ;       returns:
+       ;               a: FF -> unable to place door
+       ;               a: door direction -> door placed
+       ;               [hl]: ors new door bit
+       ;               bc: if door placed moves coordinates
+       ;               hl: if door placed moves ptr
+make_door:
+       push af
+       cp a, 0 
+       jp z, @right
+
+       cp a, 1
+       jp z, @up
+
+       cp a, 2
+       jp z, @down
+
+       cp a, 3
+       jp z, @left
+
+@try_again:
+       pop af
+       ; try again...
+       ld a, 0xFF
+       ret
+@right: 
+       
+       ; can we even place it?
+       ld a, c
+       cp a, 0
+       jp z, @try_again
+
+       ; we can!
+       ld a, [hl]
+       or a, DIRRIGHT
+       ld [hl], a
+
+       dec c ; x--
+       dec hl ; hl--
+
+       pop af
+       ret
+@left:
+       ld a, c
+       cp a, MAP_W-1
+       jp z, @try_again
+
+       ld a, [hl]
+       or a, DIRLEFT
+       ld [hl], a
+       
+       inc c ; x++
+       inc hl ; hl++
+
+       pop af
+       ret
+@up:
+       
+       ld a, b
+       cp a, 0
+       jp z, @try_again
+
+       ld a, [hl]
+       or a, DIRUP
+       ld [hl], a
+
+       dec b ; y--
+
+       ld de, -FLOOR_W & 0xFFFF
+       add hl, de ; hl one row up
+
+       pop af
+       ret
+@down:
+       
+       ld a, b
+       cp a, MAP_H-1
+       jp z, @try_again
+
+       ld a, [hl]
+       or a, DIRDOWN
+       ld [hl], a
+
+       inc bc ; y++
+
+       ld de, FLOOR_W
+       add hl, de ; hl one row downa
+
+       pop af
+       ret
 
        ; loads the current player map cursor 
        ; and draws the required doors