.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
#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
; inputs:
; hl: unit table (p0/p1)
units_update:
-
+
; loop counter
ld a, UNITS_MAX
; 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
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
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
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
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
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
.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