From 78daef64839b9f9be032ad99bf74ecc09dc34f99 Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Wed, 31 Dec 2025 17:19:27 +0100 Subject: [PATCH] map: wip rewriting renderer 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 | 1 + maps/far_center_wall.inc | 4 + src/main.s | 2 +- src/map.s | 477 +++++++++++++-------------------------- src/player.s | 10 +- src/tiles.s | 4 + src/update.s | 23 +- src/wram.s | 27 +-- 8 files changed, 193 insertions(+), 355 deletions(-) create mode 100644 maps/far_center_wall.inc diff --git a/makefile b/makefile index bce0463..07c59ef 100644 --- 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 index 0000000..a781530 --- /dev/null +++ b/maps/far_center_wall.inc @@ -0,0 +1,4 @@ +; this map was generated by tmx2map.py + +.db 0x15, 0x21, 0x21, 0x16, 0x10, 0x12, 0x12, 0x20, 0x25, 0x22, 0x22, 0x26 + diff --git a/src/main.s b/src/main.s index 3884c34..699401d 100644 --- a/src/main.s +++ b/src/main.s @@ -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" diff --git a/src/map.s b/src/map.s index 2ad48d4..29827a4 100644 --- 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 diff --git a/src/player.s b/src/player.s index 074beec..6972297 100644 --- a/src/player.s +++ b/src/player.s @@ -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 diff --git a/src/tiles.s b/src/tiles.s index cddf138..fd39a37 100644 --- a/src/tiles.s +++ b/src/tiles.s @@ -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 diff --git a/src/update.s b/src/update.s index 619a100..3dc92ec 100644 --- a/src/update.s +++ b/src/update.s @@ -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 diff --git a/src/wram.s b/src/wram.s index 7b714ce..36131b2 100644 --- a/src/wram.s +++ b/src/wram.s @@ -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 -- 2.30.2