map: wip rewriting renderer
authorLukas Krickl <lukas@krickl.dev>
Wed, 31 Dec 2025 16:19:27 +0000 (17:19 +0100)
committerLukas Krickl <lukas@krickl.dev>
Wed, 31 Dec 2025 16:19:27 +0000 (17:19 +0100)
Removed all references to old system of storing near and far tiles.
Replaced it with direction vectors.
Added map get tile n steps in a direction.
Added macro to easily load directions and actor locations.

makefile
maps/far_center_wall.inc [new file with mode: 0644]
src/main.s
src/map.s
src/player.s
src/tiles.s
src/update.s
src/wram.s

index bce0463b5afeb6f349d976b7fada85a2a37eb098..07c59ef934f354917983d5c6fb6ebcb4e69b832b 100644 (file)
--- a/makefile
+++ b/makefile
@@ -29,3 +29,4 @@ maps:
        ./tools/tmx2map.py assets/maps/far_left_door.tmx 1 > maps/far_left_door.inc 
        ./tools/tmx2map.py assets/maps/far_right_door.tmx 1 > maps/far_right_door.inc 
        ./tools/tmx2map.py assets/maps/far_center_door.tmx 1 > maps/far_center_door.inc 
+       ./tools/tmx2map.py assets/maps/far_center_wall.tmx 1 > maps/far_center_wall.inc 
diff --git a/maps/far_center_wall.inc b/maps/far_center_wall.inc
new file mode 100644 (file)
index 0000000..a781530
--- /dev/null
@@ -0,0 +1,4 @@
+; this map was generated by tmx2map.py
+
+.db 0x15, 0x21, 0x21, 0x16, 0x10, 0x12, 0x12, 0x20, 0x25, 0x22, 0x22, 0x26
+
index 3884c34ff7394da74b98dd051f68d6b3f4b257a3..699401dc2b03b10537ec24379df05449f2b2eb8e 100644 (file)
@@ -56,12 +56,12 @@ main:
 #include "mem.s"
 #include "sys.s"
 #include "input.s"
+#include "map.s"
 #include "player.s"
 #include "enemy.s"
 #include "update.s"
 #include "ui.s"
 #include "audio.s"
-#include "map.s"
 #include "math.s"
 #include "game.s"
 #include "actor.s"
index 2ad48d42ef98f291785f4ce86e03dc37c77ad262..29827a4069af73ab6a755a6752bdb5117b8bed52 100644 (file)
--- a/src/map.s
+++ b/src/map.s
@@ -245,256 +245,7 @@ map_get_tile:
        ld hl, tile_null
        ret
        
-       ; gets south facing props 
-       ; inputs:
-       ;               hl: current tile
-       ;                $1: forward direction
-       ;                $2: left direction
-       ;                $3: right direction
-       ; returns:
-       ;               d/e: left/right door state (MAP_NO_DOOR or MAP_NEAR_DOOR)
-       ;     a: forward door state
-#macro map_full_draw_door_state
-.beginscope
-       ld d, MAP_NO_DOOR
-       ld e, MAP_NO_DOOR
-
-       inc hl ; flags
-       ld a, [hl]
-       and a, $2
-       jp z, @no_left
-               ld d, MAP_NEAR_DOOR
-@no_left:
-
-       ld a, [hl]
-       and a, $3
-       jp z, @no_right
-               ld e, MAP_NEAR_DOOR
-@no_right:
-
-       ld a, [hl]
-       and a, $1
-       jp z, @no_forward
-               ld a, MAP_NEAR_DOOR
-@no_forward:
-
-       dec hl ; back to tile
-.endscope
-#endmacro
-       
-       ; writes door state
-       ; inputs:
-       ;               de: left/right state
-       ;                a: forward state
-       ;               $1: offset from tmp_map_forward (e.g. +2 to write to far left/right door)
-       ;               $2: forward value to set
-       ;               $3: instruction to run if forward is 1 (e.g. ret, nop)
-       ;       returns:
-       ;               writes MAP_NO_DOOR, MAP_NEAR_DOOR, MAP_FAR_DOOR, MAP_FURTHEST_DOOR to tmp map door table        
-#macro map_full_draw_write_door_state
-.beginscope
-       push af
-
-       ; write left door
-       ld a, d
-       ld [tmp_map_forward+$1], a
-
-       ; write right door
-       ld a, e
-       ld [tmp_map_forward+1+$1], a
-       
-       ; check if forward is available
-       pop af
-       cp a, 0
-       jr z, @no_forward REL
-               ld a, $2
-               ld [tmp_map_forward], a
-               jp @done
-@no_forward:
-       $3
-@done:
-.endscope
-#endmacro
-       
-       
-       ; writes the nearby tile information
-       ; for tile_near, tile_far etc
-       ; inputs:
-       ;               bc: y/x coordinate
-       ;    $1: offset (0 for tile_near, 2 for tile far)
-#macro _map_write_nearby_tile
-       push af
-       ld a, b
-       ld [tile_near+$1], a
-       ld a, c
-       ld [tile_near+1+$1], a
-       pop af
-#endmacro
-
-       ; counts the tiles the player can move forward
-       ;       inputs:
-       ;               player facing direction y/x
-       ; retunrs:
-       ;               tmp_map_forward: 0/1 can move forward or not
-       ;               tmp_map_forward: 2 more than 1 tile can be moved forward
-       ;         tmp_map_near_left_door: 0/1 door present or not
-       ;               tmp_map_near_right_door: 0/1 door present or not
-       ;   tmp_map_far_left_door: 0/1 door present or not
-       ;       tmp_map_far_right_door 0/1 door present or not
-       ;   tmp_map_furthest_left_door: 0/1 door present or not
-       ;               tmp_map_furthest_right_door: 0/1 door present or not
-       ;   tile_near: near tile coordinates
-       ;               tile_far: far tile coordinates
-       ;               tile_furthest: furthest tile coordinates
-map_full_draw_count_forward_attributes:
-       xor a, a
-       ld [tmp_map_forward], a
-       ld [tmp_map_near_left_door], a
-       ld [tmp_map_near_right_door], a
-       ld [tmp_map_far_left_door], a
-       ld [tmp_map_far_right_door], a
-       ld [tmp_map_furthest_left_door], a
-       ld [tmp_map_furthest_right_door], a
-
-
-       ; clear tile_near and tile_far
-       ld a, 0xFF 
-       ld [tile_near], a
-       ld [tile_near+1], a
-       ld [tile_far], a
-       ld [tile_far+1], a
-       ld [tile_furthest], a
-       ld [tile_furthest+1], a
-
-       ld a, [player+act_pos_y]
-       ld b, a
-       ld a, [player+act_pos_x]
-       ld c, a ; bc = y/x
-       push bc
-       call map_get_tile
-       pop bc ; bc = y/x
-       ; hl = tile
-
-       ld a, [player+act_dir]
-       and a, ACT_DIR_MASK
-
-       _map_write_nearby_tile 0
-
-       ; which routine to run to find values?
-       cp a, SOUTH
-       jp z, @south
-       cp a, WEST
-       jp z, @west
-       cp a, EAST
-       jp z, @east
-
 
-@north:
-       ; write near tile
-       map_full_draw_door_state TF_NE, TF_WE, TF_EE
-       map_full_draw_write_door_state 1, MAP_NEAR_DOOR, ret
-
-       dec b ; move one tile back
-       _map_write_nearby_tile 2
-       push bc
-       call map_get_tile
-       pop bc
-
-       ; write far tile
-       map_full_draw_door_state TF_NE, TF_WE, TF_EE
-       map_full_draw_write_door_state 3, MAP_FAR_DOOR, ret
-
-       dec b ; move one tile back
-       _map_write_nearby_tile 4
-
-       ; write furthest tile
-       map_full_draw_door_state TF_NE, TF_WE, TF_EE
-       map_full_draw_write_door_state 5, MAP_FURTHEST_DOOR, ret
-       ret
-@south:
-       map_full_draw_door_state TF_SE, TF_WE, TF_EE
-       map_full_draw_write_door_state 1, MAP_NEAR_DOOR, ret
-       
-       inc b ; move one tile forward
-       _map_write_nearby_tile 2
-       push bc
-       call map_get_tile
-       pop bc
-
-       map_full_draw_door_state TF_SE, TF_WE, TF_EE
-       map_full_draw_write_door_state 3, MAP_FAR_DOOR, ret
-
-       inc b ; move one tile forward
-       _map_write_nearby_tile 4
-       call map_get_tile
-
-       map_full_draw_door_state TF_SE, TF_WE, TF_EE
-       map_full_draw_write_door_state 5, MAP_FURTHEST_DOOR, ret
-       ret
-@east:
-       map_full_draw_door_state TF_EE, TF_NE, TF_SE
-       map_full_draw_write_door_state 1, MAP_NEAR_DOOR, ret
-
-       inc c ; move one tile east
-       _map_write_nearby_tile 2
-       push bc
-       call map_get_tile
-       pop bc
-
-       map_full_draw_door_state TF_EE, TF_NE, TF_SE
-       map_full_draw_write_door_state 3, MAP_FAR_DOOR, ret
-
-       inc c ; move one tile east
-       _map_write_nearby_tile 4
-       call map_get_tile
-
-       map_full_draw_door_state TF_EE, TF_NE, TF_SE
-       map_full_draw_write_door_state 5, MAP_FURTHEST_DOOR, ret
-       ret
-@west:
-       map_full_draw_door_state TF_WE, TF_SE, TF_NE
-       map_full_draw_write_door_state 1, MAP_NEAR_DOOR, ret
-
-       dec c ; move one tile west
-       _map_write_nearby_tile 2
-       push bc
-       call map_get_tile
-       pop bc
-
-       map_full_draw_door_state TF_WE, TF_SE, TF_NE
-       map_full_draw_write_door_state 3, MAP_FAR_DOOR, ret
-
-       dec c ; move one tile west
-       _map_write_nearby_tile 4
-       call map_get_tile
-       
-       map_full_draw_door_state TF_WE, TF_SE, TF_NE
-       map_full_draw_write_door_state 5, MAP_FURTHEST_DOOR, ret
-       ret
-       
-       ; draws near doors
-_map_full_draw_near_doors:
-       ld a, [tmp_map_near_left_door]
-       cp a, MAP_NEAR_DOOR
-       jr nz, @no_near_left REL
-               ld hl, render_buffer + RENDER_BUF_W * 3
-               ld de, near_left_door
-               ld bc, RENDER_BUF_W-4
-               ld a, 7
-               call tiles_block_copy
-@no_near_left:
-
-       ld a, [tmp_map_near_right_door]
-       cp a, MAP_NEAR_DOOR
-       jr nz, @no_near_right REL
-               ld hl, render_buffer + RENDER_BUF_W * 3 + 16
-               ld de, near_right_door
-               ld bc, RENDER_BUF_W-4
-               ld a, 7
-               call tiles_block_copy
-@no_near_right:
-       ret
-       
        ; optional: 
        ; clear oam and redraw only UI
        ; should be run when the actor turns
@@ -533,9 +284,9 @@ _dir_vectors_west:
 
 _dir_vectors_north:
        ; forward
-       .db 1, 0
-       ; back
        .db -1, 0
+       ; back
+       .db 1, 0
        ; left
        .db 0, 1
        ; right
@@ -543,15 +294,53 @@ _dir_vectors_north:
 
 _dir_vectors_south:
        ; forward
-       .db -1, 0
-       ; back
        .db 1, 0
+       ; back
+       .db -1, 0
        ; left
        .db 0, -1
        ; right
        .db 0, 1
 
-       
+_dir_tf_south:
+       ; forward
+.db TF_SE
+       ; back
+.db TF_NE
+       ; left
+.db TF_EE
+       ; right
+.db TF_WE
+
+_dir_tf_north:
+       ; forward
+.db TF_NE
+       ; back
+.db TF_SE
+       ; left
+.db TF_WE
+       ; right
+.db TF_EE
+
+_dir_tf_west:
+       ; forward
+.db TF_WE
+       ; back
+.db TF_EE
+       ; left
+.db TF_NE
+       ; right
+.db TF_SE
+
+_dir_tf_east:
+       ; forward
+.db TF_EE
+       ; back
+.db TF_WE
+       ; left
+.db TF_SE
+       ; right
+.db TF_NE
 
        ; gets the direction vector
        ; for the current direction
@@ -560,6 +349,7 @@ _dir_vectors_south:
        ;               a: direction
        ;       returns:
        ;               dir_vector: set for all directions
+       ;               dir_tf: sets direction flags
 map_get_dir_vectors:
        cp a, SOUTH
        jp z, @south
@@ -575,43 +365,139 @@ map_get_dir_vectors:
        ld de, _dir_vectors_east
        ld hl, dir_vectors
        ld bc, dv_size
-       jp memcpy 
+       call memcpy 
+
+       ld de, _dir_tf_east
+       ld hl, dir_tfs
+       ld bc, dir_tfs_end - dir_tfs
+       jp memcpy
 
 @south:
        ld de, _dir_vectors_south
        ld hl, dir_vectors
        ld bc, dv_size
-       jp memcpy 
+       call memcpy 
+
+       ld de, _dir_tf_south
+       ld hl, dir_tfs
+       ld bc, dir_tfs_end - dir_tfs
+       jp memcpy
+
 @north:
        ld de, _dir_vectors_north
        ld hl, dir_vectors
        ld bc, dv_size
-       jp memcpy 
+       call memcpy 
+
+       ld de, _dir_tf_north
+       ld hl, dir_tfs
+       ld bc, dir_tfs_end - dir_tfs
+       jp memcpy
 @west: 
        ld de, _dir_vectors_west
        ld hl, dir_vectors
        ld bc, dv_size
-       jp memcpy 
+       call memcpy
+
+       ld de, _dir_tf_west
+       ld hl, dir_tfs
+       ld bc, dir_tfs_end - dir_tfs
+       jp memcpy
+
+       ; draws a static ceiling from the map buffer
+map_full_draw_ceiling:
+       ld hl, render_buffer
+       ld bc, RENDER_BUF_W * 4
+       ld d, 0x12
+       ; set ceiling tile for 4 rows
+       jp memset
+       
+       ; gets a tile based on a positon
+       ; and a marching vector
+       ; inputs:
+       ;               b/c: y/x origin
+       ;               d/e: marching vector
+       ;                 a: amount of steps to take
+       ;       returns:
+       ;               tile at b/c + a * d/e
+map_get_tile_march:
+@loop:
+               push af
+               ld a, b
+               add a, d
+               ld b, a ; add vec to b
+               
+               ld a, c
+               add a, e
+               ld c, a ; add vec to c
+
+               pop af
+               dec a
+               jr nz, @loop REL
+       jp map_get_tile
+       
+       ; loads the marching vector
+       ; as well as player positin
+       ; inputs:
+       ;               de: actor ptr
+       ;               $1: vector to load
+       ;       returns:
+       ;               b/c: player y/x
+       ;               d/e: chosen vector
+#macro map_load_march_vec
+       ld hl, act_pos_y
+       add hl, de
+       ld a, [hl+]
+       ld b, a
+       ld a, [hl]
+       ld c, a
 
+       ld a, [$1]
+       ld d, a
+       ld a, [$1+1]
+       ld e, a
+#endmacro
 
+       ; draws the far center wall
+       ; either draws a wall or an open space 
+       ; depending on the door state
+map_full_draw_far_center:
+       map_load_march_vec dir_vector_forward
+       ld a, 1 
+       ld de, player
+       call map_get_tile_march
+       ; hl = tile ahead
+       ld de, t_flags0
+       add hl, de
+       ld b, [hl]
+       ld a, [dir_tf_forward]
+       and a, b ; mask out forward door bit
+
+       jr z, @no_door REL
+@door:
+       ld hl, render_buffer + RENDER_BUF_W * 5 + 8
+       ld de, far_center_door
+       ld bc, RENDER_BUF_W - 4
+       ld a, 3
+       jp tiles_block_copy
+@no_door:
+       
+       ld hl, render_buffer  + RENDER_BUF_W * 5 + 8
+       ld de, far_center_wall
+       ld bc, RENDER_BUF_W - 4
+       ld a, 3
+       jp tiles_block_copy
        
        ; draws a full map copy into the current map view buffer
-       ; bsed on the current location the player is facing
+       ; based on the current location the player is facing
        ; the map render buffer is then written to the screen
-       ; 1) load near or far wall into render_buffer (near if forward wall is on next tile)
-       ; 2) determine exits on all other walls forward
-       ; 3) draw exits in pre-determined locations
-       ; 4) set render state
+       ;       draws rooms ahead of the player back to front
        ; inputs:
        ;               [map]
        ; returns:
        ;               render_buffer: new map data to be drawn
        ; transferts to redraw state
 map_full_draw:
-       ; TODO: remove this call once all references to the 
-       ;                         wram values are removed
-       ;  now we can draw the map
-       call map_full_draw_count_forward_attributes
        
        ; 1) get player direction vecors
        ld a, [player+act_dir]
@@ -619,60 +505,11 @@ map_full_draw:
        call map_get_dir_vectors
 
        ; 2) draw back to front
+       call map_full_draw_ceiling
+       
+       ; either draw a wall or a door ahead
+       call map_full_draw_far_center
 
-       ld a, [tmp_map_forward]
-       cp a, MAP_NO_DOOR
-       jp z, @short_wall
-
-@far_wall:
-       ; draw far wall template
-       ld de, far_wall
-       ld hl, render_buffer
-       ld bc, RENDER_BUF_TILES
-       call memcpy
-
-       ; clear far back door if _forward is > 1
-       ld a, [tmp_map_forward]
-       cp a, MAP_FAR_DOOR
-       jr c, @no_far_forward_door REL
-               ld hl, render_buffer + RENDER_BUF_W * 5 + 8
-               ld de, far_center_door
-               ld bc, RENDER_BUF_W-4
-               ld a, 3
-               call tiles_block_copy
-@no_far_forward_door:
-
-       ld a, [tmp_map_far_left_door]
-       cp a, MAP_NEAR_DOOR
-       jr nz, @no_far_left_door REL
-               ld hl, render_buffer + RENDER_BUF_W * 4 + 4
-               ld de, far_left_door
-               ld bc, RENDER_BUF_W-4
-               ld a, 5
-               call tiles_block_copy
-@no_far_left_door:
-
-       ld a, [tmp_map_far_right_door]
-       cp a, MAP_NEAR_DOOR
-       jr nz, @no_far_right_door REL
-               ld hl, render_buffer + RENDER_BUF_W * 4 + 12
-               ld de, far_right_door
-               ld bc, RENDER_BUF_W-4
-               ld a, 5
-               call tiles_block_copy
-@no_far_right_door:
-       
-       call _map_full_draw_near_doors
-
-       jp @done
-@short_wall:
-       ; draw short wall template
-       ld de, near_wall
-       ld hl, render_buffer
-       ld bc, RENDER_BUF_TILES
-       call memcpy 
-
-       call _map_full_draw_near_doors
 
 @done:
        call minimap_full_draw
index 074beecbad39c136c0564b9b3ce33300eef66fc1..697229706c52c175a82d9d9bc1bdb4b3b00035be 100644 (file)
@@ -84,11 +84,11 @@ player_attack:
        ; TODO: implement correctly
        ; for now just remove an actor if
        ; they are near
-       ld a, [tile_far]
-       ld b, a
-       ld a, [tile_far+1]
-       ld c, a
-       call map_get_tile
+       
+       ld de, player
+       map_load_march_vec dir_vector_forward
+       ld a, 1 ; one forward
+       call map_get_tile_march
        ld de, t_act
        add hl, de
 
index cddf1384bed6dd1bbea005bfc9b07f4c762b0481..fd39a37dc6c449e839c3121297f0820144591b2e 100644 (file)
@@ -31,6 +31,10 @@ far_left_door:
 far_center_door:
 #include "far_center_door.inc"
 
+;      4x3 tiles
+far_center_wall:
+#include "far_center_wall.inc"
+
        ; copies a row of tiles
        ; from a linear buffer into a new block
        ; blocks must be 4 tiles wide
index 619a100296d17b3988337db207798447c562d925..3dc92ec62945a80a6716bc5548e14d79c1928471 100644 (file)
@@ -2,17 +2,18 @@ update_game_over:
   ret
        
        ; draws an actor
+       ; forward direction only
        ; inputs:
-       ;               $1: near, far, furthest
+       ;               $1: steps
+       ;               $2: near/far/furthest actor draw routine
 #macro _update_game_draw_act
        ; draw actors and props
        ; on nearby tiles
        ; if the ptr is not NULL
-       ld a, [tile_$1]
-       ld b, a
-       ld a, [tile_$1+1]
-       ld c, a
-       call map_get_tile
+       ld de, player
+       map_load_march_vec dir_vector_forward
+       ld a, $1
+       call map_get_tile_march
        ; hl = tile far
        push hl
        
@@ -23,7 +24,7 @@ update_game_over:
        ld e, [hl]
        ld d, a
        or a, e ; check if it is null
-       call nz, act_draw_$1
+       call nz, act_draw_$2
        pop hl
        
        ; load t_prop
@@ -33,7 +34,7 @@ update_game_over:
        ld e, [hl]
        ld d, a
        or a, e ; check if it is null
-       call nz, act_draw_$1
+       call nz, act_draw_$2
 #endmacro
 
 update_game:
@@ -55,9 +56,9 @@ update_game:
        ; for the current frame
 update_game_draw_act_and_prop:
        ; TODO: update map routine
-       _update_game_draw_act near
-       _update_game_draw_act far
-       _update_game_draw_act furthest
+       _update_game_draw_act 0, near
+       _update_game_draw_act 1, far
+       _update_game_draw_act 2, furthest
 
   ret
 
index 7b714ce43aa1632b66f8a7460a725f36e946eab7..36131b2b17d1dedf01a11524a2cb2afb959cbb1d 100644 (file)
@@ -108,27 +108,9 @@ update_tile_ptr: .adv 2
 render_buffer: .adv RENDER_BUF_TILES
 minimap_buffer: .adv 9
 
-       ; TODO: refactor map draw to not use 
-       ; these tmps or tile_near far etc
-       ; it should just use tile_direction_vector
-       ; to read tiles ahead
-tmp_map_forward: .adv 1
-tmp_map_near_left_door: .adv 1
-tmp_map_near_right_door: .adv 1
-tmp_map_far_left_door: .adv 1
-tmp_map_far_right_door: .adv 1
-tmp_map_furthest_left_door: .adv 1
-tmp_map_furthest_right_door: .adv 1
-
        ; tmeporary actor position backup
 tmp_act_y: .adv 1
 tmp_act_x: .adv 1
-
-       ; coordinates for up to 3 tiles
-       ; set to 0xFF if no tile is present
-tile_near: .adv 2
-tile_far: .adv 2
-tile_furthest: .adv 2
        
        ; current tile direction vector
        ; y and x direction 
@@ -142,6 +124,15 @@ dir_vector_back: .adv 2
 dir_vector_left: .adv 2
 dir_vector_right: .adv 2
 dir_vectors_end:
+
+       ; direction tile flags 
+       ; for rendering
+dir_tfs:
+dir_tf_forward: .adv 1
+dir_tf_back: .adv 1
+dir_tf_left: .adv 1
+dir_tf_right: .adv 1
+dir_tfs_end:
        
        ; combat data
 combat: .adv combat_size