From 3c0e4536cc5ea1512dbe5b1d1f6aaee5af930464 Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Tue, 13 Jan 2026 05:45:37 +0100 Subject: [PATCH] map: wip map uncovering 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 | 2 +- maps/l1.inc | 4 +- src/actor.s | 6 +++ src/jmp.inc | 1 - src/map.s | 112 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/player.s | 29 ++++++++++++- src/update.s | 31 ++++++++++++-- src/wram.s | 2 + 8 files changed, 173 insertions(+), 14 deletions(-) diff --git a/assets b/assets index 87ee9f8..29e2314 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 87ee9f8f6668bdb1501830d872bff920b6c06299 +Subproject commit 29e2314c3eb913a6fd39600662306cdf1ebca3f5 diff --git a/maps/l1.inc b/maps/l1.inc index 7fba4d6..6411427 100644 --- a/maps/l1.inc +++ b/maps/l1.inc @@ -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 diff --git a/src/actor.s b/src/actor.s index c4261e6..6b4bb17 100644 --- a/src/actor.s +++ b/src/actor.s @@ -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 diff --git a/src/jmp.inc b/src/jmp.inc index 7d6cc71..e5eafac 100644 --- a/src/jmp.inc +++ b/src/jmp.inc @@ -41,7 +41,6 @@ vec_vblank: ; STA 0x48 ;============= vec_stat: - reti ; disable objects push af ld a, [RLCD] diff --git a/src/map.s b/src/map.s index 095decf..fe6da99 100644 --- 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 diff --git a/src/player.s b/src/player.s index 11f93d3..7855fc8 100644 --- a/src/player.s +++ b/src/player.s @@ -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 diff --git a/src/update.s b/src/update.s index 450a7aa..45a9b43 100644 --- a/src/update.s +++ b/src/update.s @@ -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 diff --git a/src/wram.s b/src/wram.s index ce954b5..4cf50f2 100644 --- a/src/wram.s +++ b/src/wram.s @@ -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 -- 2.30.2