state: Removed old player input handling - replaced with new state
authorLukas Krickl <lukas@krickl.dev>
Sun, 2 Feb 2025 05:30:32 +0000 (06:30 +0100)
committerLukas Krickl <lukas@krickl.dev>
Sun, 2 Feb 2025 05:30:32 +0000 (06:30 +0100)
machine

The new implmenetation is a more modular approach to handling actor
states.
It works by swapping a simple state parameter out and calling
functions from a table.
The table to call is still left up to the actors.

src/animation.s
src/defs.s
src/macros.inc
src/player.s
src/state.s

index f432c89420f2ae095f914c7762dbb84d7c5a2b1c..76b49f29c7f6a359a881dfd1dc2fe9f1834cc244 100644 (file)
@@ -2,15 +2,60 @@
 ; each frame the latest animation is 
 ; updated
 
+  ; anim_walk_<direction> inputs
+  ; sm_param[0]: frames to walk for
 anim_walk_north:
-  ret
+  inc bc ; bc = actor y
+  ld d, 0xFF ; walk back 
+  jp anim_walk_generic 
 
 anim_walk_south:
-  ret
+  inc bc ; bc = actor y
+  ld d, 1 ; walk forward 
+  jp anim_walk_generic 
 
 anim_walk_east:
-  ret
+  inc bc
+  inc bc ; bc = actor x
+  ld d, 1 ; walk forward
+  jp anim_walk_generic
 
 anim_walk_west:
+  inc bc
+  inc bc ; bc = actor x
+  ld d, 0xFF ; walk back 
+  jp anim_walk_generic
+
+  ; generic version of anim walk
+  ; inputs:
+  ;   bc: position to walk in
+  ;    d: offset per frame 
+anim_walk_generic:
+  sm_load_ptr hl
+  inc hl ; hl = param 
+  ld a, [hl]
+  cp a, 0
+  jp z, anim_walk_end
+
+  dec a 
+  ld [hl], a ; p0--
+
+  ld a, [bc]
+  add a, d
+  ld [bc], a ; y++
   ret
 
+  ; aborts walk
+  ; inputs:
+  ;   none
+anim_abort_walk:
+  sm_load_ptr hl
+  inc hl
+
+  ; inputs:
+  ;   hl: sm_param[0] 
+anim_walk_end:
+  dec hl ; hl = sm_state 
+  ld a ,smt_end_turn 
+  ld [hl], a
+  ret
index 19791ac7d8400f14abc842092d96cc5d30de5a67..bf16bbfa0ecada76e33671c1c7452512b6dd0034 100644 (file)
@@ -55,6 +55,8 @@
 #define ANIM_STEP_UP 0xFF
 #define ANIM_STEP_RIGHT 1
 
+#define ANIM_PLAYER_WALK_FRAMES 16
+
 ; actor type enum
 .se 0
   ; null actor type = nop
 .se 1
 .de smt_end_turn, 1
 .de smt_player_poll_inputs, 1
+.de smt_player_go_north, 1
+.de smt_player_go_south, 1
+.de smt_player_go_east, 1
+.de smt_player_go_west, 1
index ec9a6535119f5edc2ab6864f5c4932dfdda780c4..26826894d94172222c958d2fbfc82907c6e229be 100644 (file)
 @noassert
 #endmacro
 
+  ; loads the state machine ptr 
+  ; into $1
+  ; inptuts:
+  ;   $1: register (hl, de, bc)
+#macro sm_load_ptr
+  ld $1, state_machine
+#endmacro 
index 1c6afd11adcb27c5115819f589db0bb9f07eadfa..44b18da518984fe0a0e9f7fc61780c69e4ed63e1 100644 (file)
@@ -80,162 +80,6 @@ player_update:
   ; restore hl 
   pop hl
 
-  ; play move animation 
-  ; and skip inputs if it is still 
-  ; ongoing
-  ld a, [end_turn]
-  cp a, 0
-  jr z, @no_anim REL ; do not play anim if turn is not ended
-
-  call anim_move
-  cp a, 0
-  jp nz, @skip_input
-  call who_next ; next actor's turn
-  call anim_clear
-  jp nz, @skip_input
-@no_anim:
-
-  ; set collision mask
-  ld a, RF_WALL | RF_DOOR | RF_ACTOR
-  ld [ct_mask], a
-  
-  ; anim_target_y = y movement target 
-  ; anim_target_x = x movement target
-  ; load tmp and +1 with the current position by 
-  ; default
-  ld a, [hl+]
-  ld [anim_target_y], a
-  ld a, [hl]
-  dec hl
-  ld [anim_target_x], a
-
-  ; input handling
-  input_held BTNDOWN
-  jr z, @notdown REL
-  
-  ; set animation params 
-    ld a, ANIM_MOVE_TILE_SIZE
-    ld [anim_move_y], a
-    ld a, ANIM_STEP_DOWN
-    ld [anim_step_y], a
-  
-    ; set expected offset 
-    ld a, ANIM_MOVE_TILE_SIZE
-    add a, [hl]
-    ld [anim_target_y], a
-    
-    call play_noise
-    turn_finish
-@notdown:
-  
-  input_held BTNUP
-  jr z, @notup REL
-
-  ; set animation params 
-    ld a, ANIM_MOVE_TILE_SIZE
-    ld [anim_move_y], a
-    ld a, ANIM_STEP_UP
-    ld [anim_step_y], a
-
-    ; set expected offset 
-    ld a, ANIM_MOVE_TILE_SIZE_N
-    add a, [hl]
-    ld [anim_target_y], a
-
-    call play_noise
-    turn_finish
-@notup:
-  
-
-  input_held BTNLEFT
-  jr z, @notleft REL
-
-  ; set animation params 
-    ld a, ANIM_MOVE_TILE_SIZE
-    ld [anim_move_x], a
-    ld a, ANIM_STEP_LEFT
-    ld [anim_step_x], a
-
-    ; set expected offset 
-    ld a, ANIM_MOVE_TILE_SIZE_N
-    inc hl
-    add a, [hl]
-    dec hl
-    ld [anim_target_x], a
-    
-    call play_noise
-    turn_finish
-@notleft:
-
-  input_held BTNRIGHT
-  jr z, @notright REL
-
-  ; set animation params 
-    ld a, ANIM_MOVE_TILE_SIZE
-    ld [anim_move_x], a
-    ld a, ANIM_STEP_RIGHT
-    ld [anim_step_x], a
-
-    ; set expected offset 
-    ld a, ANIM_MOVE_TILE_SIZE
-    inc hl
-    add a, [hl]
-    dec hl
-    ld [anim_target_x], a
-
-    call play_noise
-    turn_finish
-@notright:
-
-@action_buttons:
-
-  input_just BTNA 
-  jr z, @nota REL
-
-  ; reduce hp by 1
-  ld a, 1
-  ; make sure we do not mess with hl
-  push hl
-  ; hl = player_y right now 
-  push de ; de will get used in take damage
-  call player_take_damage
-  ; call for UI redraw 
-  ld a, UI_REDRAW_HP 
-  ld [ui_flags], a
-  pop de
-  pop hl
-@nota:
-
-  input_just BTNB
-  jr z, @notb REL
-
-  ; gain 1 hp
-  ld a, 1
-  ; make sure we do not mess with hl
-  push hl
-  ; hl = player_y right now
-  inc hl
-  inc hl 
-  inc hl ; hl = player_hp
-  call player_gain_resource 
-  ; call for UI redraw
-  ld a, UI_REDRAW_HP 
-  ld [ui_flags], a
-  pop hl
-
-@notb:
-  ; sotre x in e
-  ld a, [hl]
-  ld e, a
-  
-  ld a, [anim_target_y] 
-  add a, 8
-  ld d, a ; d = target y + 8 to center on tile 
-  ld a, [anim_target_x]
-  add a, 8
-  ld e, a ; e = target x + 8 to center on tile 
-  call player_collision_check
-
 @update_end:
 @skip_input:
   ; hl should be player_y here 
@@ -336,12 +180,27 @@ player_update:
 
   ; performs player collision checks
   ; inputs:
-  ;   hl: player ptr
-  ;   de: y/x position used for check
+  ;   bc: actor ptr
+  ;   de: y/x position offset 
 player_collision_check:
+
+  ; set collision mask
+  ld a, RF_WALL | RF_DOOR | RF_ACTOR
+  ld [ct_mask], a
+
+  ; load actor y/x into de
+  inc bc ; bc = actor y
+  ld a, [bc]
+  add a, d ; y + offset 
+
+  ld d, a ; d = target y
+  inc bc ; bc = actor x
+  ld a, [bc]
+  add a, e ; x + offset 
+  ld e, a ; e = target x
+
   ; if any collision happens now 
   ; we stop the animation
-  push hl ; need to save hl 
   call collision_tile 
   ld h, a ; store original a in h for now 
 
@@ -366,11 +225,10 @@ player_collision_check:
 
   ld a, h ; restore original a for next check  
   and a, RF_WALL | RF_ACTOR
-  pop hl
   
   jr z, @no_collision REL
-    ; clear anim memory
-    call anim_clear
+    ; abort walk state 
+    call anim_abort_walk
     jr @skip REL
 @no_collision:
   ; call z, player_tile_update_rf_flags 
index f330d11f6eee46c7c5dde03176b960bf1acfd659..bb62b892cd596c4bee76d31a931437a4402b8b30 100644 (file)
 ; to store their current state and call small re-usable routines 
 ; at the end of a chain the state should always be 0
 
+
   ; table of all states 
   ; expected inputs:
   ; bc: actor_ptr
-  ; de: state machine ptr
 state_table:
   dw sm_nop
   dw sm_end_turn
   dw sm_player_poll_inputs
+  dw anim_walk_north
+  dw anim_walk_south
+  dw anim_walk_east
+  dw anim_walk_west
 
 sm_nop:
   ret
 
 sm_end_turn:
   call sm_clear
+  turn_finish
+  call who_next
   ret
 
   ; clears the state machine 
 sm_clear:
   xor a, a
-  ld hl, state_machine 
-  ld a, [hl+]
-  ld a, [hl+]
-  ld a, [hl+]
+  sm_load_ptr hl
+  ld [hl+], a
+  ld [hl+], a
+  ld [hl], a
   ret
 
 sm_player_poll_inputs:
+  ; bc = actor type
+  
+  sm_load_ptr hl
+  
+  ; input handling
+  input_held BTNDOWN
+  jr z, @notdown REL
+  
+    ; set animation params
+    ld a, smt_player_go_south 
+    ld [hl+], a ; set next state
+    ld a, ANIM_PLAYER_WALK_FRAMES
+    ld [hl], a ; set param[0]
+  
+    ; perform collision check
+    ld d, ANIM_PLAYER_WALK_FRAMES
+    ld e, 0
+    call player_collision_check
+
+    ret
+@notdown:
+
+  input_held BTNUP
+  jr z, @notup REL
+  
+    ; set animation params
+    ld a, smt_player_go_north 
+    ld [hl+], a ; set next state
+    ld a, ANIM_PLAYER_WALK_FRAMES
+    ld [hl], a ; set param[0]
+
+
+    ; perform collision check
+    ld d, 0xFF & 0 - ANIM_PLAYER_WALK_FRAMES
+    ld e, 0
+    call player_collision_check
+
+    ret
+@notup:
+
+  input_held BTNLEFT 
+  jr z, @notleft REL
+  
+    ; set animation params
+    ld a, smt_player_go_west 
+    ld [hl+], a ; set next state
+    ld a, ANIM_PLAYER_WALK_FRAMES
+    ld [hl], a ; set param[0]
+
+    ; perform collision check
+    ld d, 0
+    ld e, 0xFF & 0 - ANIM_PLAYER_WALK_FRAMES
+    call player_collision_check
+
+    ret
+@notleft:
+
+  input_held BTNRIGHT 
+  jr z, @notright REL
+  
+    ; set animation params
+    ld a, smt_player_go_east 
+    ld [hl+], a ; set next state
+    ld a, ANIM_PLAYER_WALK_FRAMES
+    ld [hl], a ; set param[0]
+
+    ; perform collision check
+    ld d, 0
+    ld e, ANIM_PLAYER_WALK_FRAMES
+    call player_collision_check
+
+    ret
+@notright:
+
   ret
 
   ; loads initial state if