actor: Added actor spawning map object
authorLukas Krickl <lukas@krickl.dev>
Fri, 26 Sep 2025 15:33:25 +0000 (17:33 +0200)
committerLukas Krickl <lukas@krickl.dev>
Fri, 26 Sep 2025 15:33:25 +0000 (17:33 +0200)
src/actor.s
src/enemy.s
src/macros.inc
src/map.s
src/mapobj.s
src/update.s

index e13760acab9d27b28b31f9d772b69bb65b0a6eb6..ff14a32e2476b91347f39cf0a678d7a830934d4c 100644 (file)
@@ -1,3 +1,29 @@
+       
+       ; attempts to spawna a new actor
+       ; by searching for a free slot of type 0
+       ; returns:
+       ;               hl: free actor ptr
+       ;               hl: NULL if no slot is available
+       ; note: memory is not cleared
+       ; the caller will have to initialize the actor
+actor_try_add:
+       ld b, ACTS_MAX
+       ld hl, actors
+       ld de, act_size
+@loop:
+               ld a, [hl] ; check type
+               cp a, 0
+               ret z ; if 0 type -> match! return now 
+               ; go to next ptr
+               add hl, de
+               dec b
+               jr nz, @loop REL
+       
+       ; nothing found
+       ld hl, NULL
+       ret
+
+
        ; draws a single object
        ; for an actor accounting for scroll
        ; inputs:
@@ -69,12 +95,39 @@ actor_update_draw_table:
        dw act_nop 
        dw player_update_and_draw
        dw act_guard_update_and_draw
+       
+       ; called when an actor is spawned
+       ; via a map object
+actor_init_table:
+       dw act_nop
+       dw act_nop
+       dw act_guard_init 
 
 actor_collision_res_table:
        dw act_nop
        dw player_col_res
        dw act_guard_col_res
        
+       ; inits an actors
+       ; inputs:
+       ;               de: actor
+actor_init:
+       ld a, [de]
+       add a, a ; * 2 for offset
+       ld hl, actor_init_table
+       ld b, 0
+       ld c, a
+       add hl, bc
+       
+       ld a, [hl+]
+       ld b, a
+       ld a, [hl]
+       ld h, a
+       ld l, b
+       call_hl
+
+       ret
+       
        ; calls update for all actors
        ; and draws them
 actor_update_all:
@@ -109,36 +162,6 @@ actor_update_all:
                jr nz, @loop REL
        ret
        
-       ; spawns a test guard 
-       ; inputs:
-       ;               $1: actor offset
-       ;               $2: y
-       ;               $3: x
-#macro actor_spawn_test_guard
-       ld de, act_enemy_guard
-       ld hl, actors+act_size * $1
-       ld bc, act_size
-       call memcpy
-
-       ; set a test position
-       ld a, $2 
-       ld [actors+ act_size * $1 + act_pos_y], a
-       ld a, $3 
-       ld [actors+ act_size * $1 + act_pos_x], a
-#endmacro
-
-
-       ; loads a test actor
-actor_load_test:
-       actor_spawn_test_guard 0, 30, 30
-       actor_spawn_test_guard 1, 20, 40
-       actor_spawn_test_guard 2, 20, 50
-       actor_spawn_test_guard 3, 20, 60
-       actor_spawn_test_guard 4, 20, 70
-       actor_spawn_test_guard 5, 20, 80
-       actor_spawn_test_guard 6, 30, 80
-       ret
-       
        ; despawns an actor
        ; inputs:
        ;               de: actor ptr
index 77903ed1f8fd73da6fa85aff96218bb68cb61cb4..3469546aae8faa9419229b5d3ba744c12ebae117 100644 (file)
@@ -65,3 +65,13 @@ act_guard_col_res:
        dec a
        ld [hl], a
        ret
+       
+       ; inits a guard
+       ; inputs:
+       ;               de: actor
+act_guard_init:
+       ld hl, act_hp
+       add hl, de
+       ld a, 4
+       ld [hl], a
+       ret
index 3aa5bba1385b437d55c7d4c35981b4bedb9b1ca1..01ab53f3360651300c34a16dadafe0a6a595a62b 100644 (file)
@@ -207,6 +207,14 @@ $1:
        dw $4
 #endmacro
        
+       ; same as modef
+       ; but 
+       ;       $4: dat1
+       ;               $5: dat2
+#macro modef2
+       .db $1, $2, $3, $4, $5
+#endmacro
+       
        
        ; defines a rectangle
        ; inputs:
index 641595052a6bc3e0590e25c42295d4c4b2521ef4..a1e82310ad68498db99839206e2d81eb722c2ec1 100644 (file)
--- a/src/map.s
+++ b/src/map.s
@@ -242,6 +242,7 @@ l1_map:
 
 l1_objs:
        modef MOT_SET_PAT, 0, 8, pat_center_empty_wall
+       modef2 MOT_ACTOR_SPAWNER, 0, 8, ACT_T_GUARD, 0x40 
        ; rectangle at y/x 0/0 with height 32 width 64
        modef MOT_RECT, 0, 8, 0x0804 
 
@@ -255,6 +256,7 @@ l1_objs:
        modef MOT_SET_PAT, 0, 18, pat_center_empty_wall
 
        modef MOT_RECT, 0, 18, 0x080F
+       modef2 MOT_ACTOR_SPAWNER, 0, 18, ACT_T_GUARD, 0x40 
 
        modef MOT_SET_PAT, 0, 0x1E, pat_empty 
        modef MOT_DISABLE_SCROLL, 0, 0x20, 0
index c4c057bf1240c22942ade3537aa190a3b9fce69b..e182f2d28b16a282a65aa1440ab5ba171bda6dd3 100644 (file)
@@ -163,7 +163,55 @@ mo_rect:
        ret
        
        ; spawns an actor spawner
+       ; dat1: actor type
+       ;       dat2 nnnn0000: x offset to spawn at / 8 
        ; inputs:
        ;               de: map object ptr
 mo_actor_spawner:
+       ld hl, mo_dat
+       add hl, de
+       
+       push hl
+       call actor_try_add
+       pop de 
+       ld a, h
+       or a, l
+       ret z ; bail if hl is NULL
+
+       ; we have a ptr!
+       ld a, [de]
+       inc de ; go to dat2
+       
+       push hl
+       ; set type
+       ld [hl+], a
+       
+       ; clear flags
+       xor a, a
+       ld [hl+], a
+
+       ; y position is always the same
+       ld a, -16 & 0xFF 
+       ld [hl+], a
+
+       ; TODO:
+       ; x position is based on dat2
+       ld a, [de]
+       and a, 0xF0 
+       swap a
+       add a, a ; * 2
+       add a, a ; * 4
+       add a, a ; * 8 
+       ld [hl+], a
+       
+       ; clear p0 and state
+       xor a, a
+       ld [hl+], a
+       ld [hl+], a
+
+       ; TODO: run some init code based on type
+       pop de
+       ; de = actor base
+       call actor_init
+
        ret
index d286ec0912911f5684eb4b1c90092f645d69bd39..010c83a4c63cd6ae57fe20f41e29be8338d61709 100644 (file)
@@ -22,8 +22,6 @@ new_game:
        ld de, l1_map
        call map_load
 
-       call actor_load_test
-
        ld hl, update_game
        call game_set_state