;=========== ; CONSTANTS ;=========== CONST_SHIPX EQU 15 CONST_TILE_W EQU 64 CONST_TILE_H EQU 64 CONST_MAP_MASK_X EQU (CONST_TILE_W - 1) CONST_MAP_MASK_Y EQU (CONST_TILE_H - 1) CONST_LOWRES_W EQU 40 CONST_LOWRES_H EQU 40 CONST_BETA_I EQU $ff CONST_BETA_F EQU $80 CONST_SCALE_I EQU $14 CONST_SCALE_F EQU $00 CONST_LOWRES_HALF_I EQU $ec ; -(LOWRES_W/2) CONST_LOWRES_HALF_F EQU $00 flying_start: ;=================== ; Clear screen/pages ;=================== jsr clear_screens ; jsr set_gr_page0 lda #$4 sta DRAW_PAGE jsr clear_bottom lda #$8 sta DRAW_PAGE jsr clear_bottom ;===================== ; Set Up Double Lowres ;===================== lda SET_GR ; graphics C050 lda LORES ; lores C056 lda TEXTGR ; mixset C053 sta SET80COL ; 80store C001 sta EIGHTYCOL ; 80col C00d lda AN3 ; AN3 C05E ; jsr page_flip jsr init_multiply_tables ;=============== ; Init Variables ;=============== lda #20 sta SHIPY lda #0 sta TURNING sta ANGLE sta SPACEX_I sta SPACEY_I sta CX_I sta CX_F sta CY_I sta CY_F sta DRAW_SPLASH sta SPEED sta SPLASH_COUNT lda #1 sta ANGLE lda #2 ; initialize sky both pages sta DRAW_SKY lda #4 ; starts out at 4.5 sta SPACEZ_I lda #$80 sta SPACEZ_F jsr update_z_factor flying_loop: lda SPLASH_COUNT ; 3 beq flying_keyboard ; 2nt/3 dec SPLASH_COUNT ; decrement splash count ; 5 flying_keyboard: jsr get_key ; get keypress ; 6 lda LASTKEY ; 3 ; cmp #('Q') ; if quit, then return ; bne skipskip ; rts ;skipskip: cmp #('W') ; 2 bne check_down ; 3/2nt ;=========== ; UP PRESSED ;=========== lda SHIPY cmp #17 bcc check_down ; bgt, if shipy>16 dec SHIPY dec SHIPY ; move ship up inc SPACEZ_I ; incement height jsr update_z_factor lda #0 sta SPLASH_COUNT check_down: cmp #('S') bne check_left ;============= ; DOWN PRESSED ;============= lda SHIPY cmp #28 bcs splashy ; ble, if shipy < 28 inc SHIPY inc SHIPY ; move ship down dec SPACEZ_I ; decrement height jsr update_z_factor bcc check_left splashy: lda #10 sta SPLASH_COUNT check_left: cmp #('A') bne check_right ;============= ; LEFT PRESSED ;============= lda TURNING bmi turn_left beq turn_left lda #$0 sta TURNING clv bvc check_right turn_left: lda #253 ; -3 sta TURNING dec ANGLE check_right: cmp #('D') bne check_speedup ;============== ; RIGHT PRESSED ;============== lda TURNING ;; FIXME: optimize me bpl turn_right lda #0 sta TURNING clv bvc check_speedup turn_right: lda #3 sta TURNING inc ANGLE check_speedup: cmp #('Z') bne check_speeddown ;========= ; SPEED UP ;========= lda #$8 cmp SPEED beq check_speeddown inc SPEED check_speeddown: cmp #('X') bne check_brake ;=========== ; SPEED DOWN ;=========== lda SPEED beq check_brake dec SPEED check_brake: cmp #(' '+128) bne check_land ;============ ; BRAKE ;============ lda #$0 sta SPEED check_land: cmp #13 bne check_help ;===== ; LAND ;===== ; finds value in space_x.i,space_y.i ; returns color in A lda CX_I sta SPACEX_I lda CY_I sta SPACEY_I jsr lookup_map cmp #COLOR_BOTH_LIGHTGREEN bne must_land_on_grass landing_loop: jsr draw_background_mode7_standard ; Draw Shadow lda #>shadow_forward sta INH lda #ship_forward sta INH lda #(grass_string) sta OUTH lda #<(grass_string) sta OUTL jsr print_both_pages ; "NEED TO LAND ON GRASS!" check_help: cmp #('H') bne check_done ;===== ; HELP ;===== ; jsr print_help lda #2 sta DRAW_SKY check_done: ;================ ; Wrap the Angle ;================ ; FIXME: only do this in right/left routine? lda ANGLE ; 3 and #$f ; 2 sta ANGLE ; 3 ;================ ; Handle Movement ;================ speed_move: ldx SPEED ; 3 beq draw_background ; 2nt/3 ;============= lda ANGLE ; dx.i=fixed_sin[(angle+4)&0xf].i; // cos() ; 3 clc ; 2 adc #4 ; 2 and #$f ; 2 asl ; 2 tay ; 2 lda fixed_sin_scale,Y ; 4 sta DX_I ; 3 iny ; dx.f=fixed_sin[(angle+4)&0xf].f; // cos() ; 2 lda fixed_sin_scale,Y ; 4 sta DX_F ; 3 lda ANGLE ; dy.i=fixed_sin[angle&0xf].i; // sin() ; 3 and #$f ; 2 asl ; 2 tay ; 2 lda fixed_sin_scale,Y ; 4 sta DY_I ; 3 iny ; dx.f=fixed_sin[angle&0xf].f; // sin() ; 2 lda fixed_sin_scale,Y ; 4 sta DY_F ; 3 ;============ ; 54 speed_loop: clc ; fixed_add(&cx,&dx,&cx); ; 2 lda CX_F ; 3 adc DX_F ; 3 sta CX_F ; 3 lda CX_I ; 3 adc DX_I ; 3 sta CX_I ; 3 clc ; fixed_add(&cy,&dy,&cy); ; 2 lda CY_F ; 3 adc DY_F ; 3 sta CY_F ; 3 lda CY_I ; 3 adc DY_I ; 3 sta CY_I ; 3 dex ; 2 bne speed_loop ; 2nt/3 ;============ ; 45 ;============================= ; Draw the background_standard ;============================= draw_background: jsr draw_background_mode7_standard ; 6 ;============================= ; Draw the ship, standard ;============================= check_over_water: ; See if we are over water lda CX_I ; 3 sta SPACEX_I ; 3 lda CY_I ; 3 sta SPACEY_I ; 3 jsr lookup_map ; 6 sec ; 2 sbc #COLOR_BOTH_DARKBLUE ; 2 sta OVER_LAND ; 3 ;=========== ; 31 ; Calculate whether to draw the splash lda #0 ; set splash drawing to 0 ; 2 sta DRAW_SPLASH ; 3 lda SPEED ; if speed==0, no splash ; 3 beq no_splash ; 2nt/3 lda TURNING ; 3 beq no_turning_splash ; 2nt/3 lda SHIPY ; 3 cmp #27 ; 2 bcc no_turning_splash ; blt if shipy<25 skip ; 2nt/3 lda #1 ; 2 sta SPLASH_COUNT ; 3 no_turning_splash: lda OVER_LAND ; no splash if over land ; 3 bne no_splash ; 2nt/3 lda SPLASH_COUNT ; no splash if splash_count expired ; 3 beq no_splash ; 2nt/3 lda #1 ; 2 sta DRAW_SPLASH ; 3 no_splash: ;============== ; Draw the ship ;============== clv ; 2 lda TURNING ; 3 beq draw_ship_forward ; 2nt/3 bpl draw_ship_right ; 2nt/3 bmi draw_ship_left ;; FIXME: optimize order ; 2nt/3 draw_ship_forward: lda DRAW_SPLASH ; 2 beq no_forward_splash ; 2nt/3 ; Draw Splash lda #>splash_forward ; 2 sta INH ; 3 lda #shadow_forward ; 2 sta INH ; 3 lda #ship_forward ; 2 sta INH ; 3 lda #splash_right ; 2 sta INH ; 3 lda #shadow_right ; 2 sta INH ; 3 lda #ship_right ; 2 sta INH ; 3 lda #splash_left ; 2 sta INH ; 3 lda #shadow_left ; 2 sta INH ; 3 lda #ship_left ; 2 sta INH ; 3 lda #splash_forward_aux ; 2 sta INH ; 3 lda #shadow_forward_aux ; 2 sta INH ; 3 lda #ship_forward_aux ; 2 sta INH ; 3 lda #splash_right_aux ; 2 sta INH ; 3 lda #shadow_right_aux ; 2 sta INH ; 3 lda #ship_right_aux ; 2 sta INH ; 3 lda #splash_left_aux ; 2 sta INH ; 3 lda #shadow_left_aux ; 2 sta INH ; 3 lda #ship_left_aux ; 2 sta INH ; 3 lda # 1110 1110 ee ;cc = 1100 1100 > 0110 0110 66 ;88 > 44 ;99 1001 1001 > 1100 1100 = cc flying_map_aux: .byte $11,$ff,$ff,$ff, $ff,$ff,$ff,$11 .byte $ee,$66,$66,$44, $22,$22,$00,$ee .byte $ee,$66,$66,$66, $44,$22,$22,$ee .byte $ee,$66,$66,$44, $22,$22,$22,$ee .byte $ee,$66,$cc,$cc, $44,$22,$22,$ee .byte $ee,$66,$cc,$44, $22,$22,$22,$ee .byte $ee,$66,$cc,$cc, $88,$22,$22,$ee .byte $11,$ee,$ee,$ee, $ee,$ee,$ee,$11 water_map: .byte $22,$22,$22,$22, $22,$22,$22,$22 .byte $ee,$22,$22,$22, $22,$22,$22,$22 .byte $22,$22,$22,$22, $22,$22,$22,$22 .byte $22,$22,$22,$22, $ee,$22,$22,$22 water_map_aux: .byte $11,$11,$11,$11, $11,$11,$11,$11 .byte $77,$11,$11,$11, $11,$11,$11,$11 .byte $11,$11,$11,$11, $11,$11,$11,$11 .byte $11,$11,$11,$11, $77,$11,$11,$11 .include "fast_multiply.s" ; 8.8 fixed point ; should we store as two arrays, one I one F? fixed_sin: .byte $00,$00 ; 0.000000=00.00 .byte $00,$61 ; 0.382683=00.61 .byte $00,$b5 ; 0.707107=00.b5 .byte $00,$ec ; 0.923880=00.ec .byte $01,$00 ; 1.000000=01.00 .byte $00,$ec ; 0.923880=00.ec .byte $00,$b5 ; 0.707107=00.b5 .byte $00,$61 ; 0.382683=00.61 .byte $00,$00 ; 0.000000=00.00 .byte $ff,$9f ; -0.382683=ff.9f .byte $ff,$4b ; -0.707107=ff.4b .byte $ff,$14 ; -0.923880=ff.14 .byte $ff,$00 ; -1.000000=ff.00 .byte $ff,$14 ; -0.923880=ff.14 .byte $ff,$4b ; -0.707107=ff.4b .byte $ff,$9f ; -0.382683=ff.9f fixed_sin_scale: .byte $00,$00 .byte $00,$0c .byte $00,$16 .byte $00,$1d .byte $00,$20 .byte $00,$1d .byte $00,$16 .byte $00,$0c .byte $00,$00 .byte $ff,$f4 .byte $ff,$ea .byte $ff,$e3 .byte $ff,$e0 .byte $ff,$e3 .byte $ff,$ea .byte $ff,$f4 ;horizontal_lookup_20: ; .byte $0C,$0A,$09,$08,$07,$06,$05,$05,$04,$04,$04,$04,$03,$03,$03,$03 ; .byte $26,$20,$1B,$18,$15,$13,$11,$10,$0E,$0D,$0C,$0C,$0B,$0A,$0A,$09 ; .byte $40,$35,$2D,$28,$23,$20,$1D,$1A,$18,$16,$15,$14,$12,$11,$10,$10 ; .byte $59,$4A,$40,$38,$31,$2C,$28,$25,$22,$20,$1D,$1C,$1A,$18,$17,$16 ; .byte $73,$60,$52,$48,$40,$39,$34,$30,$2C,$29,$26,$24,$21,$20,$1E,$1C ; .byte $8C,$75,$64,$58,$4E,$46,$40,$3A,$36,$32,$2E,$2C,$29,$27,$25,$23 ; .byte $A6,$8A,$76,$68,$5C,$53,$4B,$45,$40,$3B,$37,$34,$30,$2E,$2B,$29 ; we can guarantee 4 cycle indexed reads if we page-aligned this .align 256 horizontal_lookup: .byte $0C,$0B,$0A,$09,$09,$08,$08,$07,$07,$06,$06,$06,$05,$05,$05,$05 .byte $04,$04,$04,$04,$04,$04,$04,$03,$03,$03,$03,$03,$03,$03,$03,$03 .byte $26,$22,$20,$1D,$1B,$19,$18,$16,$15,$14,$13,$12,$11,$10,$10,$0F .byte $0E,$0E,$0D,$0D,$0C,$0C,$0C,$0B,$0B,$0A,$0A,$0A,$0A,$09,$09,$09 .byte $40,$3A,$35,$31,$2D,$2A,$28,$25,$23,$21,$20,$1E,$1D,$1B,$1A,$19 .byte $18,$17,$16,$16,$15,$14,$14,$13,$12,$12,$11,$11,$10,$10,$10,$0F .byte $59,$51,$4A,$44,$40,$3B,$38,$34,$31,$2F,$2C,$2A,$28,$26,$25,$23 .byte $22,$21,$20,$1E,$1D,$1C,$1C,$1B,$1A,$19,$18,$18,$17,$16,$16,$15 .byte $73,$68,$60,$58,$52,$4C,$48,$43,$40,$3C,$39,$36,$34,$32,$30,$2E .byte $2C,$2A,$29,$27,$26,$25,$24,$22,$21,$20,$20,$1F,$1E,$1D,$1C,$1C .byte $8C,$80,$75,$6C,$64,$5D,$58,$52,$4E,$4A,$46,$43,$40,$3D,$3A,$38 .byte $36,$34,$32,$30,$2E,$2D,$2C,$2A,$29,$28,$27,$26,$25,$24,$23,$22 .byte $A6,$97,$8A,$80,$76,$6E,$68,$61,$5C,$57,$53,$4F,$4B,$48,$45,$42 .byte $40,$3D,$3B,$39,$37,$35,$34,$32,$30,$2F,$2E,$2C,$2B,$2A,$29,$28 grass_string: .asciiz "NEED TO LAND ON GRASS!"