.include "mode7_zp.inc" square1_lo = $2000 square1_hi = $2200 square2_lo = $2400 square2_hi = $2600 scroll_row1 = $2800 scroll_row2 = $2900 scroll_row3 = $2a00 scroll_row4 = $2b00 ;=========== ; CONSTANTS ;=========== CONST_SHIPX = 15 CONST_TILE_W = 64 CONST_TILE_H = 64 CONST_MAP_MASK_X = (CONST_TILE_W - 1) CONST_MAP_MASK_Y = (CONST_TILE_H - 1) CONST_LOWRES_W = 40 CONST_LOWRES_H = 40 CONST_BETA_I = $ff CONST_BETA_F = $80 CONST_SCALE_I = $14 CONST_SCALE_F = $00 CONST_LOWRES_HALF_I = $ec ; -(LOWRES_W/2) CONST_LOWRES_HALF_F = $00 ; pre-programmed directions island_flying_directions: .byte $2,$00 ; 2 frames, do nothing .byte $2,'Z' ; start moving forward .byte $8,$00 ; 8 frames, do nothing .byte $3,'D' ; 3 frames, turn right .byte $1,'Z' ; move faster .byte $6,$00 ; 6 frames, do nothing .byte $2,'D' ; 2 frames, turn left .byte $6,$00 ; 8 frames, do nothing .byte $3,'A' ; 3 frames, turn left .byte $1,'Z' ; speedup .byte $6,$00 ; 6 frames, do nothing .byte $6,'S' ; 6 frames down .byte $4,$00 ; 4 frames do nothing .byte $3,'A' ; 3 frames left .byte $3,'D' ; 3 frames right .byte $2,$00 ; 2 frames nothing .byte $1,'D' ; 1 frame right .byte $2,$00 ; 2 frames nothing .byte $8,'D' ; 8 frame right .byte $1,'Z' ; 1 frames up .byte $6,'W' ; 2 speedup .byte $8,$00 ; 8 nothing .byte $2,'S' ; 2 down .byte $1,'Q' ; quit ;===================== ; Flying ;===================== mode7_flying: ; cli ; enable interrupts (play music) ;================================ ; one-time setup ;================================ ; Initialize the 2kB of multiply lookup tables jsr init_multiply_tables ; initialize lda #>sky_background sta INH lda #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 inc DRAW_SKY inc DRAW_SKY 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 inc DRAW_SKY inc DRAW_SKY 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 check_help: cmp #('H') bne check_done 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 ;==================== draw_background: jsr draw_background_mode7 ; 6 ;======================================== ;======================================== ; DRAW SPACESHIP CODE ;======================================== ;======================================== draw_spaceship: 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_island_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 #