mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-11-04 20:06:09 +00:00
607 lines
10 KiB
ArmAsm
607 lines
10 KiB
ArmAsm
TARGET_NONE = $00
|
|
TARGET_DOOR = $10
|
|
TARGET_SHIELD = $20
|
|
TARGET_FRIEND = $30
|
|
TARGET_ALIEN = $40
|
|
TARGET_PHYSICIST= $80
|
|
|
|
;=============================
|
|
;=============================
|
|
; recalc_walk_collision
|
|
;=============================
|
|
;=============================
|
|
; far left limit is LEVEL_LEFT limit
|
|
; far right limit is LEVEL_RIGHT limit
|
|
; any LOCKED doors in the way also stop things
|
|
; FIXME: only door collision if on same level
|
|
recalc_walk_collision:
|
|
|
|
; note the limits have $80 added to them :(
|
|
|
|
lda RIGHT_LIMIT
|
|
sta RIGHT_WALK_LIMIT
|
|
|
|
lda LEFT_LIMIT
|
|
sta LEFT_WALK_LIMIT
|
|
|
|
lda NUM_DOORS
|
|
beq done_recalc_walk_right_collision
|
|
|
|
recalc_walk_left:
|
|
|
|
ldy NUM_DOORS
|
|
dey
|
|
recalc_walk_left_loop:
|
|
|
|
lda PHYSICIST_X
|
|
cmp (DOOR_X),Y
|
|
bcc recalc_walk_left_continue ; blt
|
|
|
|
; only if on same level
|
|
lda (DOOR_Y),Y
|
|
clc
|
|
adc #4
|
|
cmp PHYSICIST_Y
|
|
bne recalc_walk_left_continue
|
|
|
|
; only if closer than previous found
|
|
lda (DOOR_X),Y
|
|
ora #$80
|
|
cmp LEFT_WALK_LIMIT
|
|
|
|
bcc recalc_walk_left_continue ; blt
|
|
|
|
lda (DOOR_STATUS),Y
|
|
cmp #DOOR_STATUS_LOCKED
|
|
bne recalc_walk_left_continue
|
|
|
|
; early exit
|
|
lda (DOOR_X),Y
|
|
ora #$80
|
|
sta LEFT_WALK_LIMIT
|
|
; jmp done_recalc_walk_left_collision
|
|
|
|
recalc_walk_left_continue:
|
|
dey
|
|
bpl recalc_walk_left_loop
|
|
|
|
done_recalc_walk_left_collision:
|
|
|
|
|
|
ldy #0
|
|
recalc_walk_right_loop:
|
|
|
|
; only if on same level
|
|
lda (DOOR_Y),Y
|
|
clc
|
|
adc #4
|
|
cmp PHYSICIST_Y
|
|
bne recalc_walk_right_continue
|
|
|
|
lda PHYSICIST_X
|
|
cmp (DOOR_X),Y
|
|
bcs recalc_walk_right_continue ; bge
|
|
|
|
; only if closer than previous found
|
|
lda (DOOR_X),Y
|
|
ora #$80
|
|
cmp RIGHT_WALK_LIMIT
|
|
|
|
bcs recalc_walk_right_continue ; bge
|
|
|
|
lda (DOOR_STATUS),Y
|
|
cmp #DOOR_STATUS_LOCKED
|
|
bne recalc_walk_right_continue
|
|
|
|
; early exit
|
|
lda (DOOR_X),Y
|
|
sec
|
|
sbc #4
|
|
ora #$80
|
|
sta RIGHT_WALK_LIMIT
|
|
jmp done_recalc_walk_right_collision
|
|
|
|
recalc_walk_right_continue:
|
|
iny
|
|
cpy NUM_DOORS
|
|
bne recalc_walk_right_loop
|
|
|
|
done_recalc_walk_right_collision:
|
|
|
|
|
|
rts
|
|
|
|
|
|
|
|
|
|
|
|
;=============================
|
|
;=============================
|
|
; calc_gun_right_collision
|
|
;=============================
|
|
;=============================
|
|
; far right limit is LEVEL_RIGHT
|
|
; any LOCKED or CLOSED doors with SAME_Y to left of LEVEL_RIGHT
|
|
; any shield stops things
|
|
; our friend stops things
|
|
; any enemies stop things
|
|
|
|
calc_gun_right_collision:
|
|
|
|
lda #$00
|
|
sta RIGHT_SHOOT_TARGET
|
|
|
|
;=====================================================================
|
|
; by default set it to left limit (which is often but not always a wall)
|
|
|
|
lda RIGHT_LIMIT
|
|
and #$7f
|
|
sta RIGHT_SHOOT_LIMIT
|
|
|
|
;===========================
|
|
; stop if hit door
|
|
|
|
calc_gun_right_door:
|
|
lda NUM_DOORS
|
|
beq done_calc_gun_right_door_collision
|
|
|
|
calc_gun_right_doors:
|
|
|
|
|
|
ldy #0
|
|
calc_gun_right_door_loop:
|
|
|
|
; only if on same level
|
|
lda (DOOR_Y),Y
|
|
clc
|
|
adc #4
|
|
cmp COLLISION_Y
|
|
bne calc_gun_right_door_continue
|
|
|
|
lda COLLISION_X
|
|
cmp (DOOR_X),Y
|
|
bcs calc_gun_right_door_continue ; bge
|
|
|
|
lda (DOOR_STATUS),Y
|
|
cmp #DOOR_STATUS_LOCKED
|
|
beq calc_gun_right_door_there
|
|
cmp #DOOR_STATUS_CLOSED
|
|
bne calc_gun_right_door_continue
|
|
|
|
calc_gun_right_door_there:
|
|
; early exit
|
|
lda (DOOR_X),Y
|
|
sta RIGHT_SHOOT_LIMIT
|
|
|
|
tya ; set target if hit
|
|
ora #TARGET_DOOR
|
|
sta RIGHT_SHOOT_TARGET
|
|
|
|
jmp done_calc_gun_right_door_collision
|
|
|
|
calc_gun_right_door_continue:
|
|
iny
|
|
cpy NUM_DOORS
|
|
bne calc_gun_right_door_loop
|
|
|
|
done_calc_gun_right_door_collision:
|
|
|
|
|
|
;==========================
|
|
; adjust for shield
|
|
|
|
calc_gun_right_shield:
|
|
|
|
lda SHIELD_OUT
|
|
beq done_calc_gun_right_shield_collision
|
|
|
|
ldx #0
|
|
calc_gun_right_shield_loop:
|
|
|
|
; FIXME: check for on same level?
|
|
|
|
lda shield_out,X
|
|
beq calc_gun_right_shield_continue
|
|
|
|
lda COLLISION_X
|
|
cmp shield_x,X
|
|
bcs calc_gun_right_shield_continue ; bge
|
|
|
|
; be sure closer than current max limit
|
|
lda RIGHT_SHOOT_LIMIT
|
|
cmp shield_x,X
|
|
bcc calc_gun_right_shield_continue ; blt
|
|
|
|
calc_gun_right_shield_there:
|
|
|
|
lda shield_x,X
|
|
sta RIGHT_SHOOT_LIMIT
|
|
|
|
txa ; set target if hit
|
|
ora #TARGET_SHIELD
|
|
sta RIGHT_SHOOT_TARGET
|
|
|
|
; can't early exit
|
|
|
|
calc_gun_right_shield_continue:
|
|
inx
|
|
cpx #MAX_SHIELDS
|
|
bne calc_gun_right_shield_loop
|
|
|
|
done_calc_gun_right_shield_collision:
|
|
|
|
|
|
;==========================
|
|
; adjust for friend
|
|
|
|
calc_gun_right_friend:
|
|
|
|
lda friend_room
|
|
cmp WHICH_ROOM
|
|
bne done_calc_gun_right_friend_collision
|
|
|
|
lda COLLISION_X
|
|
cmp friend_x
|
|
bcs calc_gun_right_friend_continue ; bge
|
|
|
|
; only if closer than previous found
|
|
lda RIGHT_SHOOT_LIMIT
|
|
cmp friend_x
|
|
bcc calc_gun_right_friend_continue ; blt
|
|
|
|
lda friend_state
|
|
cmp #F_DISINTEGRATING
|
|
beq calc_gun_right_friend_continue
|
|
|
|
calc_gun_right_friend_there:
|
|
; early exit
|
|
lda friend_x
|
|
sta RIGHT_SHOOT_LIMIT
|
|
|
|
; set target if hit
|
|
lda #TARGET_FRIEND
|
|
sta RIGHT_SHOOT_TARGET
|
|
|
|
calc_gun_right_friend_continue:
|
|
|
|
done_calc_gun_right_friend_collision:
|
|
|
|
|
|
;==========================
|
|
; adjust for physicist
|
|
|
|
calc_gun_right_physicist:
|
|
|
|
lda COLLISION_X
|
|
cmp PHYSICIST_X
|
|
bcs calc_gun_right_physicist_continue ; bge
|
|
|
|
; only if closer than previous found
|
|
lda RIGHT_SHOOT_LIMIT
|
|
cmp PHYSICIST_X
|
|
bcc calc_gun_right_physicist_continue ; blt
|
|
|
|
lda PHYSICIST_STATE
|
|
cmp #P_DISINTEGRATING
|
|
beq calc_gun_right_physicist_continue
|
|
|
|
calc_gun_right_physicist_there:
|
|
|
|
lda PHYSICIST_X
|
|
sta RIGHT_SHOOT_LIMIT
|
|
|
|
; set target if hit
|
|
lda #TARGET_PHYSICIST
|
|
sta RIGHT_SHOOT_TARGET
|
|
|
|
calc_gun_right_physicist_continue:
|
|
done_calc_gun_right_physicist_collision:
|
|
|
|
|
|
|
|
;==========================
|
|
; adjust for alien
|
|
|
|
calc_gun_right_alien:
|
|
|
|
lda ALIEN_OUT
|
|
beq done_calc_gun_right_alien_collision
|
|
|
|
ldx #0
|
|
calc_gun_right_alien_loop:
|
|
|
|
lda alien_room,X
|
|
cmp WHICH_ROOM
|
|
bne calc_gun_right_alien_continue
|
|
|
|
; only if on same level
|
|
lda alien_y,X
|
|
cmp COLLISION_Y
|
|
bne calc_gun_right_alien_continue
|
|
|
|
lda COLLISION_X
|
|
cmp alien_x,X
|
|
bcs calc_gun_right_alien_continue ; bge
|
|
|
|
; only if closer than previous found
|
|
lda RIGHT_SHOOT_LIMIT
|
|
cmp alien_x,X
|
|
bcc calc_gun_right_alien_continue ; blt
|
|
|
|
lda alien_state,X
|
|
cmp #A_DISINTEGRATING
|
|
beq calc_gun_right_alien_continue
|
|
|
|
calc_gun_right_alien_there:
|
|
lda alien_x,X
|
|
sta RIGHT_SHOOT_LIMIT
|
|
|
|
txa ; set target if hit
|
|
ora #TARGET_ALIEN
|
|
sta RIGHT_SHOOT_TARGET
|
|
|
|
; can't early exit
|
|
|
|
calc_gun_right_alien_continue:
|
|
inx
|
|
cpx #MAX_ALIENS
|
|
bne calc_gun_right_alien_loop
|
|
|
|
done_calc_gun_right_alien_collision:
|
|
|
|
|
|
rts
|
|
|
|
|
|
|
|
;=============================
|
|
;=============================
|
|
; calc_gun_left_collision
|
|
;=============================
|
|
;=============================
|
|
; far right limit is LEVEL_LEFT
|
|
; any LOCKED or CLOSED doors stop things
|
|
; any shield stops things
|
|
; our friend stops things
|
|
; any enemies stop things
|
|
|
|
calc_gun_left_collision:
|
|
|
|
lda #0
|
|
sta LEFT_SHOOT_TARGET
|
|
|
|
;=============================
|
|
; by default set to left limit
|
|
; tricky as LEFT_LIMIT does some hacks to put it up above $80
|
|
|
|
lda LEFT_LIMIT
|
|
sec
|
|
sbc #$80
|
|
bpl left_limit_ok
|
|
lda #0
|
|
|
|
left_limit_ok:
|
|
sta LEFT_SHOOT_LIMIT
|
|
|
|
;==========================
|
|
; stop if hit door
|
|
|
|
calc_gun_left_door:
|
|
lda NUM_DOORS
|
|
beq done_calc_gun_left_door_collision
|
|
|
|
calc_gun_left_doors:
|
|
|
|
|
|
ldy NUM_DOORS
|
|
dey
|
|
calc_gun_left_door_loop:
|
|
|
|
; only if on same level
|
|
lda (DOOR_Y),Y
|
|
clc
|
|
adc #4
|
|
cmp COLLISION_Y
|
|
bne calc_gun_left_door_continue
|
|
|
|
lda COLLISION_X
|
|
cmp (DOOR_X),Y
|
|
bcc calc_gun_left_door_continue ; blt
|
|
|
|
lda (DOOR_STATUS),Y
|
|
cmp #DOOR_STATUS_LOCKED
|
|
beq calc_gun_left_door_there
|
|
cmp #DOOR_STATUS_CLOSED
|
|
bne calc_gun_left_door_continue
|
|
|
|
calc_gun_left_door_there:
|
|
; early exit
|
|
lda (DOOR_X),Y
|
|
sta LEFT_SHOOT_LIMIT
|
|
|
|
tya ; set target if hit
|
|
ora #TARGET_DOOR
|
|
sta LEFT_SHOOT_TARGET
|
|
|
|
jmp done_calc_gun_left_door_collision
|
|
|
|
calc_gun_left_door_continue:
|
|
dey
|
|
bpl calc_gun_left_door_loop
|
|
|
|
done_calc_gun_left_door_collision:
|
|
|
|
|
|
;==========================
|
|
; adjust for shield
|
|
|
|
calc_gun_left_shield:
|
|
|
|
lda SHIELD_OUT
|
|
beq done_calc_gun_left_shield_collision
|
|
|
|
ldx #0
|
|
|
|
calc_gun_left_shield_loop:
|
|
|
|
; if shield not out, skip
|
|
lda shield_out,X
|
|
beq calc_gun_left_shield_continue
|
|
|
|
; if current wall is closer, skip
|
|
lda COLLISION_X
|
|
cmp shield_x,X
|
|
bcc calc_gun_left_shield_continue ; blt
|
|
|
|
; be sure closer than current max limit
|
|
lda LEFT_SHOOT_LIMIT
|
|
cmp shield_x,X
|
|
bcs calc_gun_left_shield_continue ; bge
|
|
|
|
calc_gun_left_shield_there:
|
|
|
|
lda shield_x,X
|
|
sta LEFT_SHOOT_LIMIT
|
|
|
|
txa ; set target if hit
|
|
ora #TARGET_SHIELD
|
|
sta LEFT_SHOOT_TARGET
|
|
|
|
; can't early exit
|
|
|
|
calc_gun_left_shield_continue:
|
|
inx
|
|
cpx #MAX_SHIELDS
|
|
bne calc_gun_left_shield_loop
|
|
|
|
|
|
done_calc_gun_left_shield_collision:
|
|
|
|
|
|
;==========================
|
|
; adjust for friend
|
|
|
|
calc_gun_left_friend:
|
|
|
|
lda friend_room
|
|
cmp WHICH_ROOM
|
|
bne done_calc_gun_left_friend_collision
|
|
|
|
lda COLLISION_X
|
|
cmp friend_x
|
|
bcc calc_gun_left_friend_continue ; blt
|
|
|
|
; only if closer than previous found
|
|
lda LEFT_SHOOT_LIMIT
|
|
cmp friend_x
|
|
bcs calc_gun_left_friend_continue ; bge
|
|
|
|
lda friend_state
|
|
cmp #F_DISINTEGRATING
|
|
beq calc_gun_left_friend_continue
|
|
|
|
calc_gun_left_friend_there:
|
|
|
|
lda friend_x
|
|
sta LEFT_SHOOT_LIMIT
|
|
; set target if hit
|
|
lda #TARGET_FRIEND
|
|
sta LEFT_SHOOT_TARGET
|
|
|
|
calc_gun_left_friend_continue:
|
|
done_calc_gun_left_friend_collision:
|
|
|
|
|
|
|
|
;==========================
|
|
; adjust for physicist
|
|
|
|
calc_gun_left_physicist:
|
|
|
|
lda COLLISION_X
|
|
cmp PHYSICIST_X
|
|
beq calc_gun_left_physicist_continue ; ble (not w self)
|
|
bcc calc_gun_left_physicist_continue ; blt
|
|
|
|
; only if closer than previous found
|
|
lda LEFT_SHOOT_LIMIT
|
|
cmp PHYSICIST_X
|
|
bcs calc_gun_left_physicist_continue ; bge
|
|
|
|
lda PHYSICIST_STATE
|
|
cmp #P_DISINTEGRATING
|
|
beq calc_gun_left_physicist_continue
|
|
|
|
calc_gun_left_physicist_there:
|
|
|
|
lda PHYSICIST_X
|
|
sta LEFT_SHOOT_LIMIT
|
|
; set target if hit
|
|
lda #TARGET_PHYSICIST
|
|
sta LEFT_SHOOT_TARGET
|
|
|
|
calc_gun_left_physicist_continue:
|
|
done_calc_gun_left_physicist_collision:
|
|
|
|
|
|
|
|
|
|
;==========================
|
|
; adjust for alien
|
|
|
|
calc_gun_left_alien:
|
|
|
|
lda ALIEN_OUT
|
|
beq done_calc_gun_left_alien_collision
|
|
|
|
ldx #MAX_ALIENS
|
|
dex
|
|
|
|
calc_gun_left_alien_loop:
|
|
|
|
lda alien_room,X
|
|
cmp WHICH_ROOM
|
|
bne calc_gun_left_alien_continue
|
|
|
|
; only if on same level
|
|
lda alien_y,X
|
|
cmp COLLISION_Y
|
|
bne calc_gun_left_alien_continue
|
|
|
|
lda COLLISION_X
|
|
cmp alien_x,X
|
|
beq calc_gun_left_alien_continue ; if exact equal
|
|
; might be ourselves
|
|
bcc calc_gun_left_alien_continue ; blt
|
|
|
|
; only if closer than previous found
|
|
lda LEFT_SHOOT_LIMIT
|
|
cmp alien_x,X
|
|
bcs calc_gun_left_alien_continue ; bge
|
|
|
|
lda alien_state,X
|
|
cmp #A_DISINTEGRATING
|
|
beq calc_gun_left_alien_continue
|
|
|
|
calc_gun_left_alien_there:
|
|
; early exit
|
|
lda alien_x,X
|
|
sta LEFT_SHOOT_LIMIT
|
|
|
|
txa ; set target if hit
|
|
ora #TARGET_ALIEN
|
|
sta LEFT_SHOOT_TARGET
|
|
|
|
jmp done_calc_gun_left_alien_collision
|
|
|
|
calc_gun_left_alien_continue:
|
|
dex
|
|
bpl calc_gun_left_alien_loop
|
|
|
|
done_calc_gun_left_alien_collision:
|
|
|
|
|
|
rts
|
|
|
|
|