;====================================== ; handle keypress ;====================================== ; A or <- : start moving left ; D or -> : start moving right ; W or up : jump or elevator/transporter up ; S or down : crouch or pickup or elevator/transporter down ; L : charge gun ; space : action ; escape : quit ; if left: if running right, walk right ; if walk right, stand right ; if stand right, stand left ; if stand left, walk left ; if walk left, run left handle_keypress: lda PHYSICIST_STATE bmi no_keypress ; ignore keypress if dying/action lda KEYPRESS ; 4 bmi keypress ; 3 no_keypress: bit KEYRESET ; clear ; avoid keeping old keys around rts ; nothing pressed, return keypress: ; -1 and #$7f ; clear high bit ;====================== ; check escape check_quit: cmp #27 ; quit if ESCAPE pressed bne check_left ;===================== ; QUIT ;===================== quit: lda #$ff ; could just dec sta GAME_OVER rts ;====================== ; check left check_left: cmp #'A' beq left_pressed cmp #$8 ; left arrow bne check_right ;==================== ;==================== ; Left/A Pressed ;==================== ;==================== left_pressed: inc GUN_FIRE ; fire gun if charging ; left==0 lda DIRECTION ; if facing right, turn to face left bne left_going_right left_going_left: lda PHYSICIST_STATE cmp #P_STANDING beq walk_left cmp #P_SHOOTING beq walk_left cmp #P_WALKING beq run_left and #STATE_CROUCHING bne stand_left ;============================= ; already running, do nothing? rts left_going_right: lda PHYSICIST_STATE cmp #P_RUNNING beq walk_right cmp #P_WALKING beq stand_right cmp #P_STANDING beq stand_left cmp #P_SHOOTING beq stand_left and #STATE_CROUCHING bne stand_left ;=========================== ; otherwise? rts ;======================== ; check for right pressed check_right: cmp #'D' beq right_pressed cmp #$15 bne check_up ;=================== ;=================== ; Right/D Pressed ;=================== ;=================== right_pressed: inc GUN_FIRE ; fire if charging ; right==1 lda DIRECTION ; if facing left, turn to face right beq right_going_left right_going_right: lda PHYSICIST_STATE cmp #P_STANDING beq walk_right cmp #P_SHOOTING beq walk_right cmp #P_WALKING beq run_right and #STATE_CROUCHING bne stand_right ;============================= ; already running, do nothing? rts right_going_left: lda PHYSICIST_STATE cmp #P_RUNNING beq walk_left cmp #P_WALKING beq stand_left cmp #P_STANDING beq stand_right cmp #P_SHOOTING beq stand_right and #STATE_CROUCHING bne stand_right ;=========================== ; otherwise? rts ;===================== ; Left, direction=0 ; Right, direction=1 stand_left: lda #0 ; left sta DIRECTION sta GAIT lda #P_STANDING beq update_state walk_left: lda #P_WALKING bne update_state run_left: lda #P_RUNNING bne update_state stand_right: lda #0 sta GAIT lda #1 ; just inc DIRECTION? sta DIRECTION lda #P_STANDING beq update_state walk_right: lda #P_WALKING bne update_state run_right: lda #P_RUNNING bne update_state update_state: sta PHYSICIST_STATE bit KEYRESET rts ;===================== ; check up check_up: cmp #'W' beq up cmp #$0B bne check_down up: ;============================= ;============================= ; Up/W Pressed -- Jump, Get up ;============================= ;============================= lda PHYSICIST_STATE ; shoot if charging cmp #P_CROUCH_SHOOTING beq up_no_fire inc GUN_FIRE up_no_fire: lda ON_ELEVATOR beq up_not_elevator up_on_elevator: lda #P_ELEVATING_UP jmp change_state_clear_gait up_not_elevator: lda PHYSICIST_STATE cmp #P_CROUCHING beq stand_up cmp #P_CROUCH_SHOOTING beq stand_up_shoot up_jump: lda #P_JUMPING jmp change_state_clear_gait stand_up: lda #P_STANDING jmp change_state_clear_gait stand_up_shoot: lda #P_SHOOTING jmp change_state_clear_gait ;========================== check_down: cmp #'S' beq down cmp #$0A bne check_gun ;========================== ;========================== ; Down/S Pressed -- Crouch ;========================== ;========================== down: lda PHYSICIST_STATE ; shoot if charging cmp #P_SHOOTING beq down_no_fire inc GUN_FIRE down_no_fire: lda ON_ELEVATOR beq down_not_elevator down_on_elevator: lda #P_ELEVATING_DOWN jmp change_state_clear_gait down_not_elevator: lda PHYSICIST_STATE cmp #P_SHOOTING bne start_crouch lda #P_CROUCH_SHOOTING jmp change_state_clear_gait start_crouch: lda #P_CROUCHING jmp change_state_clear_gait ;========================== check_gun: cmp #'L' bne check_space ;====================== ; 'L' to charge gun ;====================== charge_gun: lda GUN_STATE beq not_already_firing inc GUN_FIRE ; if charging, fire jmp done_keypress not_already_firing: inc GUN_STATE lda PHYSICIST_STATE and #STATE_CROUCHING beq crouch_charge ldy #P_CROUCH_SHOOTING bne crouch_charge_go ; bra crouch_charge: ldy #P_SHOOTING crouch_charge_go: sty PHYSICIST_STATE jmp shoot check_space: cmp #' ' beq space ; cmp #$15 ; ascii 21=?? jmp unknown ;====================== ; Kick or shoot ;====================== space: lda HAVE_GUN beq kick ; shoot pressed inc GUN_FIRE ; if charging, shoot shoot: lda PHYSICIST_STATE ; if in stance, then shoot cmp #P_SHOOTING beq in_position cmp #P_CROUCH_SHOOTING bne no_stance in_position: lda #1 sta LASER_OUT jmp done_keypress no_stance: and #STATE_CROUCHING beq stand_stance crouch_stance: lda #P_CROUCH_SHOOTING jmp change_state_clear_gait stand_stance: lda #P_SHOOTING jmp change_state_clear_gait kick: lda #P_KICKING sta PHYSICIST_STATE lda #15 sta GAIT unknown: done_keypress: bit KEYRESET ; clear the keyboard strobe ; 4 rts ; 6 change_state_clear_gait: sta PHYSICIST_STATE lda #0 sta GAIT jmp done_keypress