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