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