; Strongbad Zone ; ; Yet Another HR project ; ; by deater (Vince Weaver) ; some notes on the engine from the original ; bullet moving is not 3d in any way, it's just 2D ; there are distinct Y locations with different sized sprites ; X velocity starts at 3 ; hitting shield left, subs random 0..5 ; hitting shield right, adds random 0..5 ; hitting shield center, adds random -0.5 .. 0.5 ; bounces off side walls roughly at same X as back walls ; doesn't even try to adjust for Y ; if it hits back wall, it reflects back ; if it misses you, makes small explosion, starts again at far wall ; with same X as it went off screen with ; things missing from real game ; some of the animations (both of player and head being destroyed) ; there are some pauses after things happen ; ; Notes ; collision detection on shield should really be 16 bit, some things ; get past the shield check but then collide on the next frame ; sprite routines cheat in a lot of ways. assume blue/orange ; assume X only in 3.5 pixel offsets ; do minimal transparency using black0 ; Challenges: ; moving such huge sprites ; fitting all in RAM ; sound .include "zp.inc" .include "hardware.inc" div7_table = $400 mod7_table = $500 hposn_high = $600 hposn_low = $700 strongbadzone_start: ;=================== ; set graphics mode ;=================== jsr HOME bit HIRES bit FULLGR bit SET_GR bit PAGE1 ;==================== ; set up tables ;==================== lda #$20 sta HGR_PAGE jsr hgr_make_tables ;========================== ; Load Sound ;=========================== lda SOUND_STATUS and #SOUND_IN_LC beq done_load_sound ; read/write RAM, use $d000 bank1 bit $C083 bit $C083 lda #sound_data sta ZX0_src+1 lda #$D0 jsr full_decomp ; read ROM/no-write bit $C082 done_load_sound: ;========================== ; Load Title ;=========================== load_title: lda #title_data sta ZX0_src+1 lda #$20 jsr full_decomp ; load to page2 for color cycle lda #title_data sta ZX0_src+1 lda #$A0 jsr full_decomp title_cycle_loop: jsr cycle_colors inc FRAME lda KEYPRESS bpl title_cycle_loop bit KEYRESET ;=================== ; setup game ;=================== ;========================== ; Load Backgrounds ;=========================== ; this is tricky as there's not enough room ; so we are over-writing stuff carefully load_backgrounds: lda #bg2_data sta ZX0_src+1 lda #$A0 jsr full_decomp lda #bg1_data sta ZX0_src+1 lda #$80 jsr full_decomp ;=================== ; set up variables lda #16 sta STRONGBAD_X sta PLAYER_X lda #1 sta STRONGBAD_DIR sta BULLET_YDIR lda #SHIELD_DOWN sta SHIELD_POSITION sta SHIELD_COUNT lda #0 sta BULLET_X_L sta BULLET_X_VEL sta HEAD_DAMAGE lda #$80 sta BULLET_X_VEL_L lda #20 sta BULLET_X lda #0 sta BULLET_Y jmp main_loop title_data: .incbin "asplode_graphics/sb_title.hgr.zx02" bg1_data: .incbin "asplode_graphics/sb_zone.hgr.zx02" sound_data: .incbin "asplode_sound/asplode_sound.btc.zx02" .include "hgr_tables.s" .include "zx02_optim.s" ; start at least 8k in? ;========================== ; main loop ;=========================== main_loop: jsr flip_page ;======================== ; copy over background ;======================== reset_loop: lda FRAME and #$2 beq odd_bg even_bg: lda #$A0 bne do_bg odd_bg: lda #$80 do_bg: jsr hgr_copy inc FRAME ;========================== ; adjust shield ;========================== lda SHIELD_COUNT beq done_shield_count dec SHIELD_COUNT bne done_shield_count lda #SHIELD_DOWN ; put shield down if timeout sta SHIELD_POSITION done_shield_count: ;=========================== ; move head ;=========================== lda FRAME and #$3 bne no_move_head lda STRONGBAD_X cmp #21 bcs reverse_head_dir cmp #12 bcs no_reverse_head_dir reverse_head_dir: lda STRONGBAD_DIR eor #$FF sta STRONGBAD_DIR inc STRONGBAD_DIR no_reverse_head_dir: clc lda STRONGBAD_X adc STRONGBAD_DIR sta STRONGBAD_X no_move_head: ;========================== ; draw head ;=========================== ldx HEAD_DAMAGE lda head_sprites_l,X sta INL lda head_sprites_h,X sta INH lda STRONGBAD_X sta SPRITE_X lda #36 sta SPRITE_Y jsr hgr_draw_sprite_big ;========================== ; move bullet ;=========================== ; 16 bit add clc lda BULLET_X_L adc BULLET_X_VEL_L sta BULLET_X_L lda BULLET_X adc BULLET_X_VEL sta BULLET_X ;======================== ; bounce off "walls" ; in reality just bounce if <9 or > 29? lda BULLET_X cmp #29 bcs walls_out ; bge cmp #9 bcs walls_good ; bge walls_out: ; flip X direction sec lda #0 sbc BULLET_X_VEL_L sta BULLET_X_VEL_L lda #0 sbc BULLET_X_VEL sta BULLET_X_VEL walls_good: ; move bullet Y lda BULLET_YDIR bne bullet_down bullet_up: dec BULLET_Y jmp bullet_y_done bullet_down: inc BULLET_Y bullet_y_done: ; see if off end lda BULLET_Y cmp #17 bcc bullet_still_good ; reset to top lda #0 sta BULLET_Y bullet_still_good: ;========================== ; check bullet collisions ;=========================== ;=========================== ; check player ; if (bullet_x > player_x+2) && ; (bullet_xplayer_sprite,>shield_left_sprite .byte >shield_center_sprite,>shield_right_sprite head_sprites_l: .byte big_head0_sprite,>big_head1_sprite,>big_head2_sprite .byte >big_head3_sprite,>big_head4_sprite y_positions: ; 90 to 160 roughly? Let's say 64? ; have 16 positions? 4 each? ; can probably optimize this bullet_sprite_l: .byte bullet0_sprite, >bullet1_sprite, >bullet2_sprite, >bullet3_sprite .byte >bullet4_sprite, >bullet5_sprite, >bullet6_sprite, >bullet7_sprite .byte >bullet8_sprite, >bullet9_sprite,>bullet10_sprite,>bullet11_sprite .byte >bullet12_sprite,>bullet13_sprite,>bullet14_sprite,>bullet15_sprite .byte >bullet_done_sprite bullet_sprite_y: .byte 83,88,93,98 .byte 103,108,113,118 .byte 123,128,133,138 .byte 143,148,153,158 .byte 163 bullet_vals: .byte $10,$20,$20,$40 bullet_vals_center: .byte $20,$00,$00,$20 ; original ; 1 = 6 ; 2 = 12 ; 3 = 18 ; 4 = 25 ; 5 = 32 ; 6 = 38 ; 7 = 44 ; 8 = 50 ; 9 = 57 ; 10= 63 ; 11= 70 ; 12= 77 ; 13= 82 ; 14= 89 ; 15= 95 ; 27= 167 (peak) ; 30= 148 ; 31= 139 ; 9,5 -> 22,14 = 12x9 roughly. 3 times smaller, 4x3? 2x6? bg2_data: .incbin "asplode_graphics/sb_zone2.hgr.zx02"