actor: wip collision code
authorLukas Krickl <lukas@krickl.dev>
Mon, 22 Sep 2025 15:34:06 +0000 (17:34 +0200)
committerLukas Krickl <lukas@krickl.dev>
Mon, 22 Sep 2025 15:34:06 +0000 (17:34 +0200)
src/actor.s
src/player.s
src/rectangle.s
src/wram.s

index b0a30cd8104be418a4cd1e006277874edd9eb75c..026cd26f9e63d6647441bbab1589dc81e15e2565 100644 (file)
@@ -158,4 +158,43 @@ actor_write_default_collider:
        ;               a == 1: collision
        ;               hl: if collided with an actor points to the actor hit, otherwise NULL
 actor_test_movement:
+       ld [tmp_rect_mask], a
+       ; check all static rectangles
+       ld hl, rectangles
+       ld b, RECT_MAX
+       ld de, r_size
+@rect_test_loop:
+               ; pre-filter rectangle mask
+               ld a, [tmp_rect_mask]
+               call rect_test_mask
+               jp z,  @skip_rect 
+
+               ; test all corners of tmp_rect 
+               push_all
+               
+               push hl
+               call rect_tl ; bc = top left point
+               push de
+               pop bc
+               pop hl ; hl = test rect
+
+               ld a, [tmp_rect_mask]
+               call rect_point_test
+               cp a, 1
+               jp z, @rect_collision
+
+               pop_all
+
+@skip_rect:
+               add hl, de ; next rect (de = r_size)
+               dec b
+               jp nz, @rect_test_loop
+
+
+       xor a, a ; no collision
+       ret
+@rect_collision:
+       pop_all
+       ld hl, NULL
+       ld a, 1
        ret
index c835f17f01536da673d22361821d81eb4d270aae..94e2e24b49441290694ad64513fe921a6018864e 100644 (file)
@@ -146,6 +146,11 @@ player_try_move:
        call actor_test_movement
        pop bc
 
+       ; TODO: handle collision with another actor 
+       ; if hl != NULL
+       cp a, 0
+       ret nz
+
        ld a, b
        ld [player+act_pos_y], a
 
index be67463d92e1fc25db2f1a92f4c470c9a82e835b..6e44b1b3da4730cbd9dc3b63965c2d3da18f16b2 100644 (file)
@@ -148,28 +148,67 @@ rect_br:
        ret
 
        ; tests if a point is inside r1
-       ;                a: mask
+       ;        does not perform collision mask test
        ;               bc: y/x point
        ;               hl: rectangle
        ;       returns:
        ;               a == 1: inside
        ;               a == 0: not inside
 rect_point_test:
-       ; check collision mask
-       ld d, a
-       ld [hl], a
-       and a, d
-       ; exit if mask is no match
-       jp z, @no_collision_mask_match
+       ; top left
+       push hl
+       call rect_tl
+       pop hl
 
+       ld a, b ; compare y points
+       cp a, d
+       jp nc, @no_collision
+       ld a, c ; compare x position
+       cp a, e
+       jp nc, @no_collision
+       
+       ; bottom left
+       push hl
+       call rect_bl
+       pop hl
+
+       ld a, b ; compare y
+       cp a, d
+       jp c, @no_collision
+       ld a, c ; compare x
+       cp a, e
+       jp c, @no_collision
+
+       ; top right
        push hl
        call rect_tr
        pop hl
-       
 
+
+       ; bottom right 
+       push hl
+       call rect_br
+       pop hl
+
+
+@collision:
+       ld a, 1
        ret
-@no_collision_mask_match:
-       xor a, a
+@no_collision:
+       xor a, a ; no collision
+       ret
+       
+       ; tests rectangle mask
+       ;       inputs:
+       ;               a: mask
+       ;               hl: rectangle
+       ; returns:
+       ;               z-flag: != 0 if mask is ok
+       ;       uses: a, c 
+rect_test_mask:
+       ld c, a
+       ld a, [hl]
+       and a, c 
        ret
        
        ; removes a rectangle
index 243b85cbfb239ac5193dbb0bbe14774bd57ae817..e16109cc9851bf9b11e648a833cd5c1044fdcbcf 100644 (file)
@@ -72,6 +72,7 @@ rectangles: .adv r_size * RECT_MAX
        ; temporary rectangle used for collision checks 
        ; during movement
 tmp_rect: .adv r_size
+tmp_rect_mask: .adv 1
 
        ; current row that is being drawn
 map_curr_row: .adv 1