dw act_nop
dw player_update_and_draw
dw act_guard_update_and_draw
+
+actor_collision_res_table:
+ dw act_nop
+ dw player_col_res
+ dw act_guard_col_res
; calls update for all actors
; and draws them
; a == 1: collision
; hl: if collided with an actor points to the actor hit, otherwise NULL
actor_test_movement:
+ push de
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
- actor_test_movement_corner rect_bl, @rect_collision
- actor_test_movement_corner rect_br, @rect_collision
- actor_test_movement_corner rect_tl, @rect_collision
- actor_test_movement_corner rect_tr, @rect_collision
+@rect_test_loop:
+ call actor_test_rect
+ cp a, 0
+ jp nz, @rect_collision
@skip_rect:
add hl, de ; next rect (de = r_size)
dec b
jp nz, @rect_test_loop
+ pop de
+ ld b, ACTS_MAX
+
+ ; start at player actor
+ ld hl, player
+@actor_test_loop:
+ ld a, [hl]
+ cp a, 0 ; check if type is 0
+ jp z, @skip_actor
+
+ ; check if current actor is in de
+ ld a, d
+ cp a, h
+ jr nz, @test_actor REL
+ ld a, e
+ cp a, l
+ jr z, @skip_actor REL
+
+@test_actor:
+ push de
+ push hl
+ ld de, act_rect
+ add hl, de ; hl = rectangle for actor
+
+ call actor_test_rect
+ cp a, 0
+ pop hl
+ pop de
+ jp nz, @actor_collision
+
+@skip_actor:
+ push bc
+ ld bc, act_size
+ add hl, bc ; next actor
+ pop bc
+ dec b
+ jp nz, @actor_test_loop
+
+@no_collision:
+ ld hl, NULL
xor a, a ; no collision
ret
@rect_collision:
- pop_all
+ pop de
ld hl, NULL
ld a, 1
ret
+@actor_collision:
+ ; hl = actor already
+ ld a, 1
+ ret
+
+ ; tests a single rectangle against an actor
+ ; inputs:
+ ; tmp_rect: new collision rectangle
+ ; tmp_rect_mask: mask to test agains
+ ; hl: rectangle to test
+ ; returns:
+ ; a: 1 collision
+ ; a: 0 no collision
+actor_test_rect:
+ ; pre-filter rectangle mask
+ ld a, [tmp_rect_mask]
+ call rect_test_mask
+ ret z
+
+ ; test all corners of tmp_rect
+
+ actor_test_movement_corner rect_bl, @rect_collision
+ actor_test_movement_corner rect_br, @rect_collision
+ actor_test_movement_corner rect_tl, @rect_collision
+ actor_test_movement_corner rect_tr, @rect_collision
+
+ xor a, a
+ ret
+@rect_collision:
+ ; actor_test_movement does not pop all when the check
+ ; passes
+ pop_all
+ ld a, 1
+ ret
+
+ ; calls collision resolution
+ ; inputs:
+ ; de: event origin actor
+ ; hl: actor collided with
+actor_col_res:
+ ld a, h
+ or a, l
+ cp a, 0
+ ret z ; do nothing if 0
+
+ ld a, [hl]
+ add a, a ; type * 2 as offset into table
+
+ push hl
+
+ ld hl, actor_collision_res_table
+ ld b, 0
+ ld c, a
+ add hl, bc ; hl = routine ptr
+
+ ld a, [hl+]
+ ld b, a
+ ld a, [hl]
+ ld h, a
+ ld l, b
+
+ pop bc ; the rotuine wants collider in bc
+ call_hl
+ ret
modef MOT_SET_PAT, 0, 10, pat_center_grass
modef MOT_SET_PAT, 0, 18, pat_center_empty_wall
+
+ modef MOT_RECT, 0, 18, 0x080F
+
modef MOT_SET_PAT, 0, 0x1E, pat_empty
modef MOT_DISABLE_SCROLL, 0, 0x20, 0
modef MOT_NOP, 0, 0xFF, 0