From 43f0321c66d0001bbd8919d3e5d812cfb2c80cba Mon Sep 17 00:00:00 2001 From: Lukas Krickl Date: Tue, 24 Jun 2025 19:09:54 +0200 Subject: [PATCH] unit: wip sub-tile movement --- src/actortables.s | 2 +- src/macros.inc | 2 +- src/map.s | 5 +++- src/stats.s | 10 +++++++ src/unit.s | 76 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 3 deletions(-) diff --git a/src/actortables.s b/src/actortables.s index 511da3d..e92921d 100644 --- a/src/actortables.s +++ b/src/actortables.s @@ -1,7 +1,7 @@ #include "unit_demo.s" default_map_actor_table: -.db 19 ; size +.db 0 ; 19 ; size dw unit_demo_2 dw unit_demo_3 dw unit_demo_3 diff --git a/src/macros.inc b/src/macros.inc index 503f889..5cde6d1 100644 --- a/src/macros.inc +++ b/src/macros.inc @@ -72,7 +72,7 @@ ; divides a regiser by 16 ; inputs: ; $1: the register -#macro div8 +#macro div16 srl $1 ; / 2 srl $1 ; / 4 srl $1 ; / 8 diff --git a/src/map.s b/src/map.s index d629f6b..975d758 100644 --- a/src/map.s +++ b/src/map.s @@ -187,7 +187,9 @@ map_actors_load: ; de = actor table ; load actor count - ld a, [de] + ld a, [de] + cp a, 0 + jp z, @skip ; do not load if ptr is 0 inc de ; de = first actor ptr ; load starting at slot 1 @@ -232,6 +234,7 @@ map_actors_load: dec a jr nz, @loop REL +@skip: ; hand over control to a unit ld de, player_unit call unit_wake_up diff --git a/src/stats.s b/src/stats.s index 4dd2f9b..8f59cd6 100644 --- a/src/stats.s +++ b/src/stats.s @@ -7,3 +7,13 @@ stat_calc_str: ret + ; calculates the real speed state + ; inputs: + ; de: actor + ; returns: + ; a: speed stat +stat_calc_speed: + ld hl, act_speed + add hl, de ; hl = speed stat + ld a, [hl] + ret diff --git a/src/unit.s b/src/unit.s index c9618ef..407ce3f 100644 --- a/src/unit.s +++ b/src/unit.s @@ -306,6 +306,73 @@ unit_collides_with_any_other: ret #undefine scratch_loop_i +#define TMP_MOVEMENT_SPEED scratch + ; calculates movement speed based un the current unit + ; inputs: + ; de: unit + ; returns: + ; movement speed in sub-tiles in TMP_UNIT_MOVEMENT_SPEED +unit_calc_movement_speed: + call stat_calc_speed + ; movement speed is simply speed / 16 + div16 a + cp a, 0 + jr nz, @not_zero_speed REL + inc a +@not_zero_speed: + ld [TMP_MOVEMENT_SPEED], a + ret + + ; performs a sub tile move + ; inputs: + ; de: actor + ; $1: swap a/nop + ; $2: add/sub + ; $3: mask to apply to move speed (0xF0 or 0x0F) + ; returns if sub-tile movement does not + ; cause an over/underflow + ; preserves: + ; hl +#macro unit_sub_tile_move + push hl + + push de + call unit_calc_movement_speed + pop de + + ld hl, act_rt_subtile_pos + add hl, de ; hl = subtile pos + + ld a, [TMP_MOVEMENT_SPEED] + ld b, a ; b = movement speed + + ld a, [hl] + $1 ; swap + and a, 0x0F ; mask bits we don't need + $2 a, b ; sub/add + ; test if overflow + ld c, a ; need value again in a bit + and a, 0xF0 + ; z flag is set if no overflow + push af ; push flag on to stack for now + + ld a, c ; now cut off value + and a, 0x0F ; mask it out in case of overflow + + $1 ; swap back + ld b, a ; b = new position + ld a, [hl] ; load value again + and a, $3 ; mask off + or a, b + ld [hl], a ; store new value + + ; if we did not over/underflow + ; exit now + pop af ; get back flag result + pop hl + ret nz +#endmacro + ; moves a unit up ; moves are aborted ; if no more initiative is left @@ -320,16 +387,23 @@ unit_try_move_up: ; y - 1 unit_test_collision dec b, CF_COLLISION + push de ld hl, act_pos_y add hl, de ; hl = actor y ld a, [hl] cp a, 0 ; upper bound + + pop de ret z + unit_sub_tile_move swap a, sub, 0xF0 + + ld a, [hl] dec a ld [hl], a + ret unit_try_move_down: @@ -378,6 +452,8 @@ unit_try_move_right: ld [hl], a ret +#undefine TMP_MOVEMENT_SPEED + ; centers the current scroll on the selected unit ; snaps to corners of the map ; inputs: -- 2.30.2