; G = Give P=Pick up U=use M=walk ; O = Open L=Look at H=push ; C = Close T=Talk to N=pull ;============================== ; Handle Keypress ;============================== handle_keypress: ; first handle joystick lda JOYSTICK_ENABLED beq actually_handle_keypress ; only check joystick every-other frame lda FRAMEL and #$1 beq actually_handle_keypress check_button: lda PADDLE_BUTTON0 bpl button_clear lda JS_BUTTON_STATE bne js_check lda #1 sta JS_BUTTON_STATE lda #' ' jmp check_sound button_clear: lda #0 sta JS_BUTTON_STATE js_check: jsr handle_joystick js_check_left: lda value0 cmp #$20 bcs js_check_right ; if less than 32, left lda #'A' bne check_sound js_check_right: cmp #$40 bcc js_check_up lda #'D' bne check_sound js_check_up: lda value1 cmp #$20 bcs js_check_down lda #'W' bne check_sound js_check_down: cmp #$40 bcc done_joystick lda #'S' bne check_sound done_joystick: actually_handle_keypress: lda KEYPRESS bmi keypress jmp no_keypress keypress: and #$7f ; clear high bit cmp #' ' beq check_sound ; make sure not to lose space and #$df ; convert uppercase to lower case check_sound: cmp #$14 ; control-T bne check_joystick lda SOUND_STATUS eor #SOUND_DISABLED sta SOUND_STATUS jmp done_keypress ; can't be ^J as that's the same as down check_joystick: cmp #'J' ; J bne check_give lda JOYSTICK_ENABLED eor #1 sta JOYSTICK_ENABLED jmp done_keypress check_give: cmp #'G' bne check_open lda #VERB_GIVE sta CURRENT_VERB jmp done_keypress check_open: cmp #'O' bne check_close lda #VERB_OPEN sta CURRENT_VERB jmp done_keypress check_close: cmp #'C' bne check_pick_up lda #VERB_CLOSE sta CURRENT_VERB jmp done_keypress check_pick_up: cmp #'P' bne check_look_at lda #VERB_PICK_UP sta CURRENT_VERB jmp done_keypress check_look_at: cmp #'L' bne check_talk_to lda #VERB_LOOK_AT sta CURRENT_VERB jmp done_keypress check_talk_to: cmp #'T' bne check_use lda #VERB_TALK_TO sta CURRENT_VERB jmp done_keypress check_use: cmp #'U' bne check_push lda #VERB_USE sta CURRENT_VERB jmp done_keypress check_push: cmp #'H' bne check_pull lda #VERB_PUSH sta CURRENT_VERB jmp done_keypress check_pull: cmp #'N' bne check_walk lda #VERB_PULL sta CURRENT_VERB jmp done_keypress check_walk: cmp #'M' bne check_left lda #VERB_WALK sta CURRENT_VERB jmp done_keypress ;check_load: ; cmp #$C ; control-L ; bne check_save ; jsr load_game ; jmp done_keypress ;check_save: ; cmp #$13 ; control-S ; bne check_left ; jsr save_game ; jmp done_keypress check_left: cmp #'A' beq left_pressed cmp #8 ; left key bne check_right left_pressed: lda CURSOR_X ; if 4138 then clicking on verb lda CURSOR_Y cmp #38 bcc check_walking ; blt cmp #50 bcs check_walking lda CURSOR_X clc adc #3 ; get onto screen cmp #7 bcc menu_col1 cmp #16 bcc menu_col2 cmp #22 bcc menu_col3 bcs done_click_nochange menu_col1: lda CURSOR_Y cmp #40 beq menu_col1_row2 bcs menu_col1_row3 menu_col1_row1: lda #VERB_GIVE jmp done_click_menu menu_col1_row2: lda #VERB_OPEN jmp done_click_menu menu_col1_row3: lda #VERB_CLOSE jmp done_click_menu menu_col2: lda CURSOR_Y cmp #40 beq menu_col2_row2 bcs menu_col2_row3 menu_col2_row1: lda #VERB_PICK_UP jmp done_click_menu menu_col2_row2: lda #VERB_LOOK_AT jmp done_click_menu menu_col2_row3: lda #VERB_TALK_TO jmp done_click_menu menu_col3: lda CURSOR_Y cmp #40 beq menu_col3_row2 bcs menu_col3_row3 menu_col3_row1: lda #VERB_USE jmp done_click_menu menu_col3_row2: lda #VERB_PUSH jmp done_click_menu menu_col3_row3: lda #VERB_PULL jmp done_click_menu done_click_menu: sta CURRENT_VERB done_click_nochange: rts check_walking: ; check if walking verb lda CURRENT_VERB cmp #VERB_WALK beq action_walk_to ; otherwise see if there's a noun lda VALID_NOUN bne activate_noun ; wasn't valid, switch to walk lda #VERB_WALK sta CURRENT_VERB jmp done_return activate_noun: ;============================ ; handle_special ;=========================== ; set up jump table fakery lda NOUN_VECTOR_H ; h first pha lda NOUN_VECTOR_L pha rts ; jmp to it action_walk_to: jsr set_destination done_return: rts ;============================== ; set destination ;============================== set_destination: ; tiny: y=cursor_y+6 ; small: y=cursor_y+2 ; med: y=cursor_y-2 ; big: y=cursor_y-7 ; adjust differently depending on size lda GUYBRUSH_SIZE beq set_destination_big cmp #GUYBRUSH_MEDIUM beq set_destination_medium cmp #GUYBRUSH_SMALL beq set_destination_small set_destination_tiny: lda CURSOR_X bpl destination_tiny_x_is_positive ; we are off edge of screen, just say 0 lda #$FE destination_tiny_x_is_positive: clc adc #2 sta DESTINATION_X lda CURSOR_Y bpl destination_tiny_y_is_positive cmp #$Fc bcs destination_tiny_y_is_positive lda #$Fc destination_tiny_y_is_positive: clc adc #6 and #$FE ; has to be even sta DESTINATION_Y jmp set_destination_smc set_destination_small: lda CURSOR_X bpl destination_small_x_is_positive ; we are off edge of screen, just say 0 lda #$FE destination_small_x_is_positive: clc adc #2 sta DESTINATION_X lda CURSOR_Y bpl destination_small_y_is_positive lda #0 destination_small_y_is_positive: clc adc #2 and #$FE ; has to be even sta DESTINATION_Y jmp set_destination_smc set_destination_medium: lda CURSOR_X bpl destination_medium_x_is_positive ; we are off edge of screen, just say 0 lda #$ff destination_medium_x_is_positive: clc adc #1 sta DESTINATION_X lda CURSOR_Y bpl destination_medium_y_is_positive lda #0 destination_medium_y_is_positive: sec sbc #2 and #$FE ; has to be even sta DESTINATION_Y jmp set_destination_smc set_destination_big: lda CURSOR_X bpl destination_x_is_positive ; we are off edge of screen, just say 0 lda #0 destination_x_is_positive: sta DESTINATION_X lda CURSOR_Y bpl destination_y_is_positive lda #7 destination_y_is_positive: sec sbc #7 and #$FE ; has to be even sta DESTINATION_Y set_destination_smc: jsr $0000 done_set_destination: rts ;============================= ; change location ;============================= change_location: ; reset graphics bit SET_GR ; reset pointer to not visible lda #0 sta ANIMATE_FRAME sta CURSOR_VISIBLE ; don't center? ; lda #20 ; sta CURSOR_X ; sta CURSOR_Y lda LOCATION asl tay ;========================== ; update location pointer lda (LOCATIONS_L),Y sta LOCATION_STRUCT_L iny lda (LOCATIONS_L),Y sta LOCATION_STRUCT_H ;========================== ; update level info ldy #LOCATION_DESTINATION lda (LOCATION_STRUCT_L),Y sta set_destination_smc+1 iny lda (LOCATION_STRUCT_L),Y sta set_destination_smc+2 ldy #LOCATION_EXIT lda (LOCATION_STRUCT_L),Y sta check_exit_smc+1 iny lda (LOCATION_STRUCT_L),Y sta check_exit_smc+2 ldy #LOCATION_BOUNDS lda (LOCATION_STRUCT_L),Y sta keep_in_bounds_smc+1 iny lda (LOCATION_STRUCT_L),Y sta keep_in_bounds_smc+2 ; set on exit as might have multiple entrances ; ldy #LOCATION_SIZE ; lda (LOCATION_STRUCT_L),Y ; sta GUYBRUSH_SIZE ;========================== ; load new background ldy #LOCATION_BACKGROUND lda (LOCATION_STRUCT_L),Y sta LZSA_SRC_LO iny lda (LOCATION_STRUCT_L),Y sta LZSA_SRC_HI lda #$c ; load to page $c00 jsr decompress_lzsa2_fast rts