collision: added basic stubs for collision rectangles
authorLukas Krickl <lukas@krickl.dev>
Sun, 21 Sep 2025 04:27:57 +0000 (06:27 +0200)
committerLukas Krickl <lukas@krickl.dev>
Sun, 21 Sep 2025 04:27:57 +0000 (06:27 +0200)
src/defs.s
src/macros.inc
src/main.s
src/map.s
src/mapobj.s
src/rectangle.s [new file with mode: 0644]

index dab08a275743fa88bb2c83ec134e846e2568f64d..84bce887d0cc139332e07801737a838371db16bb 100644 (file)
 #define UI_TILE_WIDTH 32
 #define UI_TILE_HEIGHT 4
 
+       
+       ; rectangle collision flags
+.se 1
+       ; collides with player
+.de RF_PLAYER, 1
+       ; is a generic wall
+.de RF_WALL, 2
+       ; collides with enemy
+.de RF_ENEMY, 4
+
+       ; rectangle struct
+.se 0
+       ; if flags == 0 the rectangle is free
+.de r_flags, 1
+.de r_pos_y, 1
+.de r_pos_y_hi, 1
+.de r_pos_x, 1
+.de r_h, 1
+.de r_w, 1
+.de r_size, 0
+
 
   ; actor type enum
 .se 0
 
   ; custom parameter
 .de act_p0, 1
+       
+       ; state parameter
+.de act_state, 1
 
        ; stats
 .de act_hp, 1 
 .de act_ac, 1
+
+       ; every actor has a collision rectangle
+.de act_rectangle, r_size
 .de act_size, 0
   
 
 .de mo_row, 1
 .de mo_dat, 2 
 .de mo_size, 0
-       
-       ; rectangle collision flags
-.se 1
-       ; collides with player
-.de RF_PLAYER, 1
-       ; is a generic wall
-.de RF_WALL, 2
-       ; collides with enemy
-.de RF_ENEMY, 4
-
-       ; rectangle struct
-.se 0
-       ; if flags == 0 the rectangle is free
-.de r_flags, 1
-.de r_pos_y, 1
-.de r_pos_y_hi, 1
-.de r_pos_x, 1
-.de r_h, 1
-.de r_w, 1
-.de r_size, 0
 
 
        ; gameplay control flags
index f687d226f9bcd23268b96b91eef068dc08b56dc8..e29fe98b1ea5a749629f03dff68194d7ae3fc43f 100644 (file)
@@ -177,11 +177,23 @@ $1:
        ;               $4: hp
        ;               $5: armor
 #macro actdef
-       .db $1, $2, $3
+       .db $1, $2
+
        ; placeholder for y, row and x
        ; since those are set at runtime
        .db 0, 0, 0
+
+       .db $3
+
+       ; placeholder for state parameter
+       ; this is set by the actor update routine as needed
+       .db 0
+
        .db $4, $5
+       
+       ; placeholder for collision rectangle
+       ; since those are runtime values
+       .db 0, 0, 0, 0, 0, 0
 #endmacro
        
        ; defines a map object
index 544376a02860bd07c5769450a3a1b8c701b27488..e1ff764c52cd0d67df88cfac2ed4faeab7ac910f 100644 (file)
@@ -66,6 +66,7 @@ main:
 #include "math.s"
 #include "game.s"
 #include "actor.s"
+#include "rectangle.s"
 
 #include "tiles.inc"
 #include "text.s"
index 57f64d9807f15e01ed430c64e9ebead42a8e3644..86430a8557864ca2c2a9ae5acbe84d31439a5c45 100644 (file)
--- a/src/map.s
+++ b/src/map.s
@@ -236,6 +236,7 @@ l1_map:
 
 l1_objs:
        modef MOT_SET_PAT, 0, 3, pat_center_empty_wall
+       modef MOT_RECT, 0, 3, 0
        modef MOT_SET_PAT, 0, 8, pat_center_grass 
        modef MOT_SET_PAT, 0, 10, pat_center_empty_wall
        modef MOT_SET_PAT, 0, 0x1E, pat_empty 
index 98487c07dfd0863ece7ed2f835b3b8a6bc2cebc7..930b653ffdf2915e54145821f1fd7229db07f5e9 100644 (file)
@@ -107,6 +107,11 @@ mo_enable_scroll:
        ret
 
        ; spawns a collision rectangle
+       ; the origin of a rectangle is the bottom left
+       ; dat1: nnnn0000: y offset from row in 8 pixel increments 
+       ;                 0000nnnn: height in 8 pixel increments
+       ; dat2: nnnn0000: x offset from row in 8 pixel increments 
+       ;                               0000nnnn: width in 8 pixel increments
        ; inputs:
        ;               de: map object ptr
 mo_rect:
diff --git a/src/rectangle.s b/src/rectangle.s
new file mode 100644 (file)
index 0000000..f41e049
--- /dev/null
@@ -0,0 +1,110 @@
+
+       ; attempts to add a rectangle
+       ; to the rectangle buffer
+       ; if no slots are availabel it will simply be skipped
+       ;       this function always sets y_hi to 0
+       ; inputs:
+       ;               a: flags
+       ;               b/c: y/x position
+       ;               d/e: h/w
+rect_try_add:
+       push af
+       push bc
+       push de
+       call rect_find_slot
+       ld a, h
+       or a, l
+       cp a, 0
+       ; if hl == 00 exit
+       jp z, @exit
+
+       pop de
+       pop bc
+       pop af
+       
+       ; write flags
+       ld [hl+], a
+
+       ; write y
+       ld a, b
+       ld [hl+], a
+
+       ; wirte y hi
+       xor a, a
+       ld [hl+], a
+
+       ; wirte x
+       ld a, c
+       ld [hl+], a
+
+       ; write h
+       ld a, d
+       ld [hl+], a
+
+       ; write w
+       ld a, e
+       ld [hl], a
+
+       ret
+@exit:
+       pop de
+       pop bc
+       pop af
+       ret
+       
+       ; attempts to find a rectangle slot where 
+       ; flags == 0 (unused)
+       ; returns:
+       ;               hl: 0000 -> no slot
+       ;               hl: ptr -> slot
+rect_find_slot:
+       ld hl, rectangles
+       ld de, r_size
+       ld b, RECT_MAX
+
+@loop:
+               ; hl = flags
+               ld a, [hl]
+               ; if flags is 0 we ret
+               cp a, 0
+               ret z
+       
+               add hl, de
+               dec b
+       jr nz, @loop REL
+       
+       ; if nothing was found ld NULL 
+       ld hl, 0
+       ret
+       
+       ; tests if any point
+       ; of r1 is inside r2
+       ; inputs:
+       ;               de: r1
+       ;               hl: r2
+       ;       returns:
+       ;               a == 1: inside
+       ;               a == 0: not inside
+rect_test:
+       ld a, [de]
+       ld b, a
+       ld a, [hl]
+       ; check if masks have a match
+       ; otherwise skip
+       and a, b
+       cp a, 0
+       jp z, @no_collision_mask_match
+       
+       ret
+@no_collision_mask_match:
+       ld a, 0
+       ret
+       
+       ; tests if a point is inside r1
+       ;               bc: y/x point
+       ;               hl: rectangle
+       ;       returns:
+       ;               a == 1: inside
+       ;               a == 0: not inside
+rect_point_test:
+       ret