map: wip map uncovering
authorLukas Krickl <lukas@krickl.dev>
Tue, 13 Jan 2026 04:45:37 +0000 (05:45 +0100)
committerLukas Krickl <lukas@krickl.dev>
Tue, 13 Jan 2026 04:45:37 +0000 (05:45 +0100)
The map uncover code will attempt to flood fill a room with uncovered
flags.
It does not work in all cases yet, but is good enough for a first test.

assets
maps/l1.inc
src/actor.s
src/jmp.inc
src/map.s
src/player.s
src/update.s
src/wram.s

diff --git a/assets b/assets
index 87ee9f8f6668bdb1501830d872bff920b6c06299..29e2314c3eb913a6fd39600662306cdf1ebca3f5 160000 (submodule)
--- a/assets
+++ b/assets
@@ -1 +1 @@
-Subproject commit 87ee9f8f6668bdb1501830d872bff920b6c06299
+Subproject commit 29e2314c3eb913a6fd39600662306cdf1ebca3f5
index 7fba4d60bb9f751c73d08559087ec36dc8cc64d5..6411427d307bd1d15f237a6bd50984974def49b2 100644 (file)
@@ -1,11 +1,11 @@
 ; this map was generated by tmx2map.py
 
 .db 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0
-.db 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x3, 0x0, 0x3
+.db 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x3, 0x3, 0x3
 .db 0x1, 0x1, 0x1, 0x1, 0x3, 0x3, 0x3, 0x1, 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
 .db 0x0, 0x0, 0x0, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1
 .db 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x1, 0x1, 0x1
-.db 0x1, 0x3, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1, 0x3, 0x3, 0x3, 0x1, 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+.db 0x1, 0x3, 0x3, 0x3, 0x1, 0x1, 0x1, 0x1, 0x3, 0x3, 0x3, 0x1, 0x1, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
 .db 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x3, 0x1, 0x1, 0x1, 0x1
 .db 0x3, 0x0, 0x3, 0x3, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
 .db 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x3, 0x3, 0x2, 0x3, 0x3, 0x0, 0x0, 0x3, 0x1, 0x3, 0x0, 0x0
index c4261e604ace04dcd2edf76172c58aea77f7fc9a..6b4bb17cecce758fa9b44ab2b2af42f316ecd455 100644 (file)
@@ -371,7 +371,13 @@ act_load_attr_table:
        ;               a: 0 -> moved
        ;               a: 1 -> not moved 
        ;               col_tile: ptr to new tile
+       ;               col_y/x: coordinates of the tile (input b/c)
 act_move_to:
+       ld a, b
+       ld [col_y], a
+       ld a, c
+       ld [col_x], a
+
        ld hl, act_pos_y
        add hl, de
 
index 7d6cc713157c9697e3ae1c4ae124fbf241f9a984..e5eafaca1444a6075137b75703e6e8178dc53005 100644 (file)
@@ -41,7 +41,6 @@ vec_vblank:
 ; STA 0x48
 ;=============
 vec_stat:
-       reti
   ; disable objects
   push af
   ld a, [RLCD]
index 095decfd1f7cf2c7cf336ecb0b080f7cf3860092..fe6da9951dc625c0fd9fe1d5878d6ddf37484e10 100644 (file)
--- a/src/map.s
+++ b/src/map.s
@@ -32,8 +32,6 @@ map_load:
        call lcd_on
        call vblank_wait
        call enableinterrupts
-       
-       call map_uncover
 
        call map_full_draw
        call update_render
@@ -283,9 +281,7 @@ map_set_visible_row:
                
                ; hl = tile
                ld a, [hl]
-               ; TODO: do not set uncovered flag here
-               ; once room uncovering is implemented
-               or a, TF0_VISIBLE | TF0_UNCOVERED 
+               or a, TF0_VISIBLE
                ld [hl], a
 
 @skip:
@@ -482,10 +478,116 @@ map_full_draw:
        ; 4) go to render state
        call update_render
        ret
+
+       ; marks a single tile
+       ; inputs:
+       ;               b/c: y/x
+       ; returns:
+       ;               a: 1 -> is wall
+       ;               a: 0 -> is not wall
+_map_uncover_mark:
+       push bc
+       call map_get_tile
+       pop bc
+
+       ld a, [hl+] ; check type
+       ; hl = flags
+       cp a, TT_INNER_WALL
+       jr z, @mark REL
+
+       cp a, TT_DOOR
+       jr z, @mark_but_exit REL
+
+       ld a, [hl]
+       and a, TF0_WALL
+       jr z, @mark REL
+       
+       ; wall
+       ld a, 1
+       ret
+@mark:
+       ld a, [hl]
+       or a, TF0_UNCOVERED
+       ld [hl], a
+       
+       ; not wall
+       ld a, 0
+       ret
+@mark_but_exit:
+       ld a, [hl]
+       or a, TF0_UNCOVERED
+       ld [hl], a
+       
+       ; wall
+       ld a, 1
+       ret
+       
+       ; same as map uncover 
+       ; but starts at player position
+map_uncover_player:
+       ld a, [player+act_pos_y]
+       ld b, a
+       ld a, [player+act_pos_x]
+       ld c, a
+       ; b/c = player y/x
        
        ; uncovers tiles starting at player position
        ; and moving in all non-uncovered tiles until walls are hit
+       ; inputs: 
+       ;               b/c: y/x coordinate to start at
 map_uncover:
+
+       ; 1) go up until we hit a wall that is not an internal wall type
+@find_top:
+               push bc
+               call map_get_tile
+               ld a, [hl+] ; get type
+
+               cp a, TT_INNER_WALL
+               jr z, @next_find_top REL
+               
+               cp a, TT_DOOR
+               jr z, @next_find_top REL
+
+               ; hl = flags0
+               ld a, [hl]
+               and a, TF0_WALL 
+               jr nz, @done_find_top REL
+@next_find_top:
+               pop bc
+               dec b ; y--
+               jr @find_top REL
+@done_find_top:
+       pop bc
+       inc b ; go one down again to get the last non-wall tile
+
+       ; now bc == top y / x
+@mark_all:
+               push bc
+@mark_left:
+                       ; now go as far left as possible (until wall is hit)
+                       call _map_uncover_mark
+                       dec c ; x--
+                       cp a, 0
+                       jr z, @mark_left REL
+               pop bc
+
+               ; then as far right as possible (until wall is hit)
+               push bc
+@mark_right:
+                       ; now go as far left as possible (until wall is hit)
+                       call _map_uncover_mark
+                       inc c ; x++
+                       cp a, 0
+                       jr z, @mark_right REL
+               pop bc
+
+               ; then y++
+               inc b
+               call _map_uncover_mark
+               cp a, 0 ; is it a wall?
+               jr z, @mark_all REL ; again!
+
        ret
        
        ; nop map rotuine
index 11f93d349127c4b206c87deb96024a534c621911..7855fc8019e369cfd39fedb122f3858fb100eaf7 100644 (file)
@@ -47,7 +47,7 @@ player_init:
        call memset
 
        ; set default view
-       ld a, 10
+       ld a, 3
        ld [player_viewradius], a
        
        ret
@@ -59,8 +59,22 @@ player_update:
 
        call player_handle_move
        
+       ; check if player is currently in uncovered tile
+       ld a, [player+act_pos_y]
+       ld b, a
+       ld a, [player+act_pos_x]
+       ld c, a
+       call map_get_tile
+       inc hl ; hl = flags
+       ld a, [hl]
+       and a, TF0_UNCOVERED
+       jp z, @need_to_uncover
 
        ret
+@need_to_uncover:
+       call map_uncover_player
+       call map_full_draw 
+       ret
 
        ; draws player
 player_draw:
@@ -198,12 +212,23 @@ player_collided:
        ; clear all flags
        xor a, a
        ld [hl], a
-
+       
+       ld a, [col_y]
+       ld b, a
+       ld a, [col_x]
+       ld c, a
        call map_uncover
        call map_full_draw
+       call player_end_turn
        ret
 
        ; code to run when player has moved
 player_moved:
        call map_full_draw
+       call player_end_turn
        ret
+       
+       ; ends the current turn
+player_end_turn:
+       ld a, 1
+       ld [turn_flag], a
index 450a7aafc94d4ade959ada62c064486642dad9ea..45a9b43f62a25ec5fcc6300d2013eb4a00da9e5e 100644 (file)
@@ -41,8 +41,8 @@ update_game:
 
 update_render:
        call disableinterrupts
-       ; TODO: this should be smooth...
-       ld b, RENDER_BUF_H ; loop counter
+
+       ld b, RENDER_BUF_H/2 ; loop counter
        ld de, render_buffer
        
        ld a, [scrn_select]
@@ -78,7 +78,6 @@ update_render:
        call next_vblank_wait
 
        ; copy buffer into SCRN0
-       ; TODO: we should do this off-screen in SCRN1 and then switch
 @render_loop:
        update_render_draw
        update_render_draw
@@ -101,6 +100,32 @@ update_render:
        update_render_draw
        update_render_draw
 
+       push de
+       ld de, 12
+       add hl, de ; next row
+       pop de
+
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+       update_render_draw
+
        call next_vblank_wait
 
        push de
index ce954b5a89c5cf614d7ea4b6dfa4bd091a6c1a69..4cf50f2a6496ce1a6dded4a5f39e05ca26d20bec 100644 (file)
@@ -125,6 +125,8 @@ render_buffer: .adv RENDER_BUF_TILES
 
 col_actor: .adv 2
 col_tile: .adv 2
+col_y: .adv 1
+col_x: .adv 1
 
 #ifdef DEBUG_CANARY
 render_canary: .adv 4