unit: Added unit to unit collision
authorLukas Krickl <lukas@krickl.dev>
Sat, 21 Jun 2025 11:01:50 +0000 (13:01 +0200)
committerLukas Krickl <lukas@krickl.dev>
Sat, 21 Jun 2025 11:01:50 +0000 (13:01 +0200)
src/defs.s
src/macros.inc
src/unit.s
src/unit_demo.s
src/update.s
src/video.s
src/wram.s

index 7ca8fce5f0bce6a8a3da6bd386a502ad8ce4bab7..88b927da5ecf67062cc5e0c8300642ad2e9a82a9 100644 (file)
 .se 0
   ; time until next state
 .de st_time, 1
-  ; state routine (BE)
+  ; state routine (LE)
   ; it can return 0000 in hl
-  ; or a new state address in hl (BE)
+  ; or a new state address in hl (LE)
   ; if bc is not 0000 after
   ; the calling state's address
   ; will be set to bc immediatly 
   ; inputs for all state routines:
   ;   de: state pointer
 .de st_routine, 2
-  ; next state (BE)
+  ; next state (LE)
 .de st_next, 2
 .de st_size, 0
 
 .de act_rt_dd_d16, 1 ; dice display value
 .de act_rt_dd_timer, 1
 .de act_rt_dd_flags, 1
-
+  ; last collision with actor
+  ; set during unit_collision_woth_any_other
+.de act_rt_collided_with, 2
 .de act_size, 0
   
   ; max bge queue size
index fcc3fe35f7c28aabf5743dd0e9c3113713e7cbb5..7ff8947e2c05619a390da2900cffc75b9b4a292c 100644 (file)
@@ -52,8 +52,8 @@
 #endmacro
 
   ; same as dw but 
-  ; stores in little endian
-#macro dwl 
+  ; stores in big endian
+#macro dwb 
 .db ($1 >> 8) & 0xFF 
 .db $1 & 0xFF
 #endmacro
   ; these can generally not be set at build time
 #macro act_rt_def
   .db 0, 0, 0 ; act_rt_dd_*
+  ; act_rt_collided_woth
+  dw 0 
 #endmacro
 
   ; defines an actors attributes
index b51c747fdd5bd5596bfab3a21cd474f948879ff9..8cc4457041cd1bc571563625567926decc2f8229 100644 (file)
@@ -3,7 +3,7 @@
   ; inputs:
   ;   hl: unit table (p0/p1)
 units_update:
-  
+
   ; loop counter
   ld a, UNITS_MAX 
 
@@ -236,16 +236,98 @@ unit_handle_inputs:
   ; inputs:
   ;   $1: dec/inc instruction
   ;   $2: collision mask for tile
+  ;   de: actor
 #macro unit_test_collision
   ; perform tile collision check
   push de
   call unit_get_pos
   $1 
+  push bc
   call map_get_tile
-  and a, $2 
+  and a, $2
+  pop bc
   pop de
-  ret nz 
+  ret nz
+
+  push de
+  call unit_collides_with_any_other
+  and a, $2
+  pop de
+  ret nz
 #endmacro
+  
+  ; tests a tile position for collision with 
+  ; any other actor. Skips actors of type 0
+  ; inputs:
+  ;   b/c: y/x tile positon to test
+  ;   de : current actor
+  ; returns:
+  ;   a = CF_COLLISION if collision occured
+  ;   sets act_rt_collided_with
+unit_collides_with_any_other:
+  ld hl, p0_units
+  ld a, UNITS_MAX ; loop counter
+
+  BREAK
+@loop:
+    push de ; save current actor on stack
+    push bc
+    
+    ; check if actor is current actor
+    ld a, h
+    cp a, d
+    jr nz, @no_skip REL
+    ld a, l
+    cp a, l
+    jr z, @skip REL
+@no_skip:
+
+    push hl
+    ld de, act_pos_y
+    add hl, de ; hl = pos_y of current actor
+
+    ld a, [hl+] ; a = y
+    cp a, b 
+    ; a != b -> no collision
+    jr nz, @no_collision REL
+
+    ld a, [hl] ; a = x
+    cp a, c
+    ; a != c -> no collision
+    jr z, @collision REL
+@no_collision:
+    pop hl
+
+@skip: 
+    ld de, act_size
+    add hl, de ; move to next actor
+    dec a
+
+    pop bc
+    pop de
+  jp nz, @loop 
+  
+  ; if we get here
+  ; no collision occured
+  ld a, 0
+  ret
+@collision:
+  pop hl
+  pop bc
+  pop de
+  ; set de to hl's current collider actor
+  ld bc, act_rt_collided_with 
+  add hl, bc
+  ld a, e
+  ld [hl+], a
+  ld a, d
+  ld [hl], a
+
+  BREAK
+  ; if we get here clean up the stack 
+  ; and set the CF_COLLISION flag
+  ld a, CF_COLLISION
+  ret
 
   ; moves a unit up
   ; moves are aborted 
index 21ada6bfad25e2c0556225fc24e202f3d71dab71..13da365d09cf8fab2d42f421793b4e6a11c2e9ed 100644 (file)
@@ -11,6 +11,12 @@ unit_demo_1_cpu_update:
  
   ret
 
+unit_demo_1_cpu_update_idle:
+  call unit_use_move
+  call unit_next_request
+  ldnull bc
+  ret
+
 unit_demo_2:
   st_def 0x00, unit_demo_1_init, st_unit_idle
   act_def ACT_T_DEMO_1, 0, 3, 3, 0 
@@ -20,7 +26,7 @@ unit_demo_2:
   act_inventory_empty
   act_equipment_empty
   act_effects_empty
-  act_st_def NULL, NULL, st_unit_demo_1_cpu_update, st_unit_idle
+  act_st_def NULL, NULL, st_unit_demo_1_cpu_update_idle, st_unit_idle
   act_def_draw unit_draw, 0x84, 0
   act_rt_def
 
@@ -41,3 +47,5 @@ unit_demo_3:
 st_unit_demo_1_cpu_update:
   st_def 0x00, unit_demo_1_cpu_update, st_unit_demo_1_cpu_update
 
+st_unit_demo_1_cpu_update_idle:
+  st_def 0x00, unit_demo_1_cpu_update_idle, st_unit_demo_1_cpu_update_idle
index 2c6f0d221c46c0ef3b8c41374f6c9bc1c1b4e3bc..bdc3555e1b512b6f2ff63aa3a84b673e2ffe66c5 100644 (file)
@@ -4,13 +4,7 @@ update_game_over:
 update_game:
   ; tick rng every frame
   call rand
-  call rand_save_srand
-  
-  ; update some tiles asap!
-  ; TODO: move this to vblank handler
-  ld a, [draw_flags]
-  and a, DRAWF_UPDATE_UI
-  call nz, ui_draw
+  call rand_save_srand 
 
   ; clear oam
   call shadow_oam_clear
index 159b29aac275b8601fc54e79d5f0285f7ba6f2e2..cf9b6d9ef2034442227bbea45f7ef683a93d92d3 100644 (file)
@@ -13,6 +13,11 @@ vblank:
   call scroll_write
   call bg_update_queue_process
 
+  ; update some tiles asap!
+  ld a, [draw_flags]
+  and a, DRAWF_UPDATE_UI
+  call nz, ui_draw
+
   ; cycle bg tiles for animations
   ld a, [frame_count]
   and a, BG_CYCLE_FRAMES
index 92a80e61a636b6b8648b7cd7ce538563e25806e2..be83c99ca98bb9143cf066470eab3999bec60496 100644 (file)
@@ -1,6 +1,12 @@
 .org WRAM
 .section wram 
 
+  ; temporary variables
+  ; that can be used by any routine
+  ; as storage
+scratch: .adv 16
+
+
 shadow_oam: .adv OBJSMAX * oamsize 
 
 frame_ready: .adv 1