; *************** Galaxian - Copyright 1998 by Patrick Davidson ************ .include "usgard.h" .org 0 .db "Galaxian 3.0 by Patrick D",0 ; *************** Variables ************************************************ score =TEXT_MEM lives =TEXT_MEM+2 level =TEXT_MEM+4 x =TEXT_MEM+6 y =TEXT_MEM+7 lasers =TEXT_MEM+8 ybullets =TEXT_MEM+9 ebuls =TEXT_MEM+39 enemies =TEXT_MEM+69 boss_status =TEXT_MEM+149 boss_pwr =TEXT_MEM+150 boss_x =TEXT_MEM+151 boss_y =TEXT_MEM+152 boss_2bytes =TEXT_MEM+154 timer =TEXT_MEM+155 your_status =TEXT_MEM+156 enemies_remaining =TEXT_MEM+157 storage_length =158 ; *************** Level Data *********************************************** enemy_coords =DELC_LEN+1 enemy_image =DELC_LEN+41 boss_image =DELC_LEN+43 enemy_pwr =DELC_LEN+45 ; *************** Temporary Variables ************************************** temp1 =DELC_LEN+80 temp =DELC_LEN+82 next_type =DELC_LEN+84 jpf1 =DELC_LEN+85 jpf2 =DELC_LEN+86 contrst =DELC_LEN+87 ; *************** Initialize Control Flags ********************************* init: ld hl,DELC_LEN xor a ld (hl),a set 0,(iy+3) ld (iy+13),0 inc a ld (USG_BITS),a ld a,(CONTRAST) cp $1f jr z,no_inc1 inc a no_inc1: cp $1f jr z,no_inc2 inc a no_inc2: out (2),a ld (contrst),a ; *************** Main Loop ************************************************ ld de,&title_message ld hl,&title_menu call &display_info_screen main_loop: call GET_KEY cp K_EXIT jr z,exit_game cp K_CLEAR jr z,exit_game cp K_F1 jr z,inst cp K_ENTER jr nz,main_loop call &play_game jr game_over inst: ld de,&igc ld hl,&instructions call &display_info_screen jr main_loop ; *************** Exit The Game ******************************************** exit_game: ld a,(CONTRAST) out (2),a jp OTH_EXIT ; **************** High-Score Handling ************************************* game_over: ;Set up score page ld hl,(&lowest) ;See if ya got a hi-score ld de,(score) call CP_HL_DE jp nc,&display_scores call CLEARLCD ld ($800c),de ld hl,&hi_score_str call D_ZT_STR ld hl,&lowest+2 ld (temp),hl ld b,16 space_loop: ld (hl),32 inc hl djnz space_loop ld ix,(temp) ld b,0 enter_name_loop: call GET_KEY or a jr z,enter_name_loop cp K_DEL jr z,backup cp K_ENTER jr z,nomore ld c,a ld a,15 cp b jr z,enter_name_loop ld hl,&chartable-10 ld e,c ld d,0 add hl,de ld a,(hl) ld (ix),a call TX_CHARPUT inc b inc ix jr enter_name_loop backup: dec b ld a,255 cp b jr z,too_far dec ix ld (ix),32 ld hl,CURSOR_COL dec (hl) ld a,32 call TX_CHARPUT dec (hl) jr enter_name_loop too_far: inc b jr enter_name_loop nomore: ld hl,&lowest ld de,(score) ld (hl),e push hl inc hl ld (hl),d pop ix ;sort hiscore table ld b,6 sort_scores ld e,(ix) ld d,(ix+1) ld l,(ix-19) ld h,(ix-18) call CP_HL_DE jr nc,display_scores push bc ld b,19 exg_loop:ld e,(ix) ld c,(ix-19) ld (ix),c ld (ix-19),e inc ix inc hl djnz exg_loop ld de,-38 add ix,de pop bc djnz sort_scores display_scores: call CLEARLCD ld ($800c),de ld hl,&hstitle call D_ZT_STR ld hl,$1001 ld (CURSOR_ROW),hl ld de,&hsdata ld b,7 high_display_loop: ;Display high scores ld a,(de) ld l,a inc de ld a,(de) ld h,a inc de push de call D_HL_DECI ld hl,CURSOR_ROW dec (hl) pop hl call D_ZT_STR ex de,hl ld hl,CURSOR_ROW inc (hl) djnz high_display_loop wk__: call GET_KEY or a jr z,wk__ jp &init ; *************** Display Information Screen ******************************* display_info_screen: push hl push de call CLEARLCD ld hl,$fc0f ld b,63 ld de,15 l2: ld (hl),1 inc hl ld (hl),128 add hl,de djnz l2 ld hl,$fc00 ld b,16 l1: ld (hl),255 inc hl djnz l1 ld hl,$fff0 ld b,16 l3: ld (hl),255 inc hl djnz l3 ld de,$0301 ld ($800c),de pop hl call D_ZT_STR pop hl ld b,5 l4: ld a,(hl) ld (CURSOR_X),a inc hl ld a,(hl) ld (CURSOR_Y),a inc hl call D_ZM_STR) djnz l4 ret ; *************** Restore Saved Game *************************************** restore: ld (hl),0 inc hl ld de,TEXT_MEM ld bc,storage_length ldir call &Load_Level_Data jr set_up_display ; *************** Set Up Game Variables ************************************ play_game: ld hl,&saved_flag ld a,(hl) or a jr nz,restore ld hl,TEXT_MEM ld (hl),0 ld de,TEXT_MEM+1 ld bc,storage_length ldir ld a,9 ld (lasers),a ld (lives),a ld a,70 ld (x),a ld (y),a ; *************** Set Up Game Display ************************************** set_up_display: call CLEARLCD ld hl,&in_game_text ld b,3 l11: ld a,(hl) ld (CURSOR_COL),a inc hl ld a,(hl) ld (CURSOR_ROW),a inc hl call D_ZT_STR djnz l11 call &display_lives call &Update_Level_Number ; *************** Game Main Loop ******************************************* game_main_loop: ld a,(enemies_remaining) or a call z,&Next_Level ld hl,timer inc (hl) xor a ld hl,GRAPH_MEM+(16*12) ld b,a csl: ld (hl),a inc hl ld (hl),a inc hl ld (hl),a inc hl djnz csl call &You_Shoot call &You_Shoot_Laser call &Your_Ship call &Move_Your_Bullets call &Enemy_Swoop call &Handle_Enemies CALL &Enemies_Hit_You call &Boss call &Boss_Shoot call &Enemies_Shoot_You call &Move_Enemy_Bullets call &Display_Screen call &Misc_Keys jr game_main_loop ; ************** Update Level Number *************************************** Update_Level_Number: ld hl,$1004 ld (CURSOR_ROW),hl ld hl,(level) jp D_HL_DECI ; *************** Make Boss Shoot You ************************************** Boss_Shoot: ld a,(timer) and 63 ret nz ld hl,boss_status ld a,(hl) or a ret z ret m inc hl inc hl ld d,(hl) inc hl ld a,(hl) add a,5 ld e,a push de call &boss_shoot ld hl,(boss_image) ld de,&spr_boss_3 call CP_HL_DE jr z,bosssuper pop de ld a,13 add a,d ld d,a boss_shoot: ld b,10 ld hl,ebuls find_enemy_bullet2: ld a,(hl) or a jr z,feb___2 inc hl inc hl inc hl djnz find_enemy_bullet2 ret feb___2: ld (hl),1 ld a,(x) sub d add a,18 jp p,&no_left_bossshoot ld (hl),2 add a,18 jp p,&no_left_bossshoot ld (hl),4 no_left_bossshoot: sub 54 jp m,&no_right_bossshoot ld (hl),3 sub 18 jp m,&no_right_bossshoot ld (hl),5 no_right_bossshoot: inc hl ld (hl),d inc hl ld (hl),e ret bosssuper: pop de push de ld a,10 add a,d ld d,a call &boss_shoot pop de push de ld a,20 add a,d ld d,a call &boss_shoot pop de ld a,30 add a,d ld d,a jp &boss_shoot ; *************** Move the Boss ******************************************** deploy_enemies: ld a,r ;Spit out enemies cp 7 ret p and 7 add a,a add a,a ld b,0 ld c,a ld hl,enemies add hl,bc ;HL -> slot in enemy data ld a,(hl) or a ret nz ;Return if enemy not destroyed ld (hl),11 ;Type to 11 (swooping) inc hl ld a,(enemy_pwr) ld (hl),a ;Load enemy's power inc hl ld a,(boss_x) add a,12 ld (hl),a ;Load enemy X coordinate inc hl ld (hl),24 ;Load enemy Y coordinate ld hl,enemies_remaining inc (hl) ;One more enemy remaining ld de,-200 ;Remove points jp &sub_score boss_5: dec (hl) ;Superboss left to X=0 ret nz dec hl dec hl ld (hl),6 ret boss_6: inc hl ld a,(hl) cp 16 jr z,sbpok inc (hl) dec hl dec hl dec hl ret sbpok: dec hl inc (hl) ;superboss right to X=65 ld a,(hl) cp 65 ret nz dec hl dec hl ld (hl),5 ret Boss: ld hl,boss_status ld a,(hl) or a ret z jp m,&boss_explode inc hl inc hl ld ix,(boss_image) ld d,(hl) inc hl ld e,(hl) call &drw_sprw ld hl,boss_status ld a,(hl) inc hl inc hl dec a jr z,boss_1 dec a jr z,boss_2 dec a jr z,boss_3 dec a jr z,boss_4 ld de,&deploy_enemies push de dec a jr z,boss_5 jr boss_6 boss_4: dec (hl) ;Going left to X=0 ret nz dec hl dec hl ld (hl),1 ret boss_1: inc hl ;Going down to Y=20 inc (hl) ld a,(hl) cp 20 ret nz boss_common: ld hl,boss_status inc (hl) ret boss_2: inc (hl) ;Going right to X=80 ld a,(hl) cp 80 ret nz jr boss_common boss_3: inc hl ;Going up to X=16 dec (hl) ld a,(hl) cp 16 ret nz jr boss_common boss_explode: inc hl push hl ld a,(hl) call &explosion_stuff pop hl inc hl ld a,(hl) push af push hl add a,8 ld (hl),a dec hl ld a,(hl) call &explosion_stuff pop hl pop af ld (hl),a dec hl ld a,(hl) cp 15 jr z,blown_up_enemyb inc a ld (hl),a ret blown_up_enemyb: dec hl ld (hl),0 ld hl,enemies_remaining dec (hl) ld hl,(score) ld de,1000 add hl,de ld (score),hl ret ; *************** Enemies Hit You ****************************************** Enemies_Hit_You: ld a,(your_status) or a ret nz ld de,(x) ;E = X, D = Y ld hl,enemies ld b,20 lehy: push hl ld a,(hl) or a jr z,noeyc inc hl inc hl ld a,(hl) sub e add a,6 jp m,&noeyc cp 12 jr nc,noeyc inc hl ld a,(hl) sub d add a,6 jp m,&noeyc cp 12 jr nc,noeyc dec hl dec hl ld (hl),0 dec hl ld (hl),4 pop hl jp &damage_you noeyc: pop hl inc hl inc hl inc hl inc hl djnz lehy ret ; *************** Make Enemies Swoop Down ********************************** Enemy_Swoop: ld a,(timer) and 3 cp 2 ret nz ld a,r and 127 cp 19 ret p add a,a add a,a ld c,a ld b,0 ld hl,enemies add hl,bc ld a,(hl) cp 3 ret nz ld a,r and 1 add a,5 ld (hl),a inc hl inc hl ld a,(hl) dec hl dec hl bit 6,a jr nz,force_left bit 5,a ret nz ld (hl),5 ret force_left: ld (hl),6 ret ; *************** Make Enemies Shoot You *********************************** Enemies_Shoot_You: ld a,r and 127 cp 19 ret p add a,a add a,a ld c,a ld b,0 ld hl,enemies add hl,bc ld a,(hl) or a ret z dec a ret z inc hl inc hl ld d,(hl) inc d inc d inc hl ld a,(hl) add a,5 ld e,a call &test_operator jp z,&boss_shoot ld b,10 ld hl,ebuls find_enemy_bullet: ld a,(hl) or a jr z,feb___ inc hl inc hl inc hl djnz find_enemy_bullet ret feb___: ld (hl),1 inc hl ld (hl),d inc hl ld (hl),e ret ; *************** Move Enemy Bullets *************************************** Move_Enemy_Bullets: ld hl,ebuls ld b,10 leb: push bc push hl ld a,(hl) inc hl dec a jr z,ebul1 dec a jr z,ebul2 dec a jr z,ebul3 dec a jr z,ebul4 dec a jr z,ebul5 ebul_return: pop hl pop bc inc hl inc hl inc hl djnz leb ret ebul3: ld a,(timer) rra jr c,ebul1 ebul5: inc (hl) ld a,(hl) cp 95 jr z,kill_enemy_bullet jr ebul1 ebul2: ld a,(timer) rra jr c,ebul1 ebul4: dec (hl) jr z,kill_enemy_bullet ebul1: ld d,(hl) inc hl ld a,81 cp (hl) jr z,kill_enemy_bullet inc (hl) ld e,(hl) ld ix,&spr_enemy_bullet call &drw_spr ld a,(your_status) or a jr nz,ebul_return pop hl push hl inc hl ld a,(x) sub (hl) add a,6 jp m,&ebul_return cp 9 jr nc,ebul_return inc hl ld a,(y) sub (hl) add a,6 jp m,&ebul_return cp 9 jr nc,ebul_return call &damage_you kill_enemy_bullet: pop hl push hl ld (hl),0 jr ebul_return ; *************** Hit Your Ship ******************************************** damage_you: ld a,31 ld (your_status),a ld hl,lives dec (hl) display_lives: ld hl,$1001 ld (CURSOR_ROW),hl ld hl,(lives) jp D_HL_DECI ; *************** Enemy Type 1 (Waiting to Descend) ************************ enemy_type_1: ld a,(timer) and 127 or %10000000 ld hl,enemy_coords-1 add hl,bc add a,(hl) RET NZ dec hl ld a,(hl) pop BC POP HL PUSH HL push BC ld (hl),2 inc hl inc hl ld (hl),a inc hl ld (hl),0 RET ; *************** Move The Enemies ***************************************** Handle_Enemies: ld hl,enemies ld bc,40 l_enemies: push bc push hl ld ix,(enemy_image) ld a,14 cp c jr nc,no_i2 ld a,(boss_image) inc a jr nz,no_i2 ld ix,&spr_enemy_1 no_i2: ld a,(hl) ld de,&enemy_return push de dec a jr z,enemy_type_1 dec a jr z,enemy_type_2 dec a jr z,enemy_type_3 dec a jr z,enemy_type_4 dec a jp z,&enemy_type_5 dec a jp z,&enemy_type_6 dec a jp z,&enemy_type_7 dec a jp z,&enemy_type_8 dec a jp z,&enemy_type_9 dec a jp z,&enemy_type_10 dec a jp z,&enemy_type_11 dec a jp z,&enemy_type_12 dec a jp z,&enemy_type_13 pop HL enemy_return: pop hl pop bc inc hl inc hl inc hl inc hl dec c dec c jr nz,l_enemies ret ; *************** Enemy Type 2 (Descending to Normal Position) ************* enemy_type_2: ld a,(timer) add a,a jr z,make_type_3 inc hl inc hl ld d,(hl) inc hl inc (hl) ecommon_2: ld e,(hl) JP &drw_spr make_type_3: ld (hl),3 ; **************** Enemy Type 3 (Normal Pattern) *************************** enemy_type_3: Inc hl inc hl ld a,(timer) rra jr c,noslide inc (hl) bit 5,a jr z,noslide dec (hl) dec (hl) noslide: ld d,(hl) inc hl jr ecommon_2 ; *************** Enemy Type 4 (Exploding) ********************************* enemy_type_4: inc hl push hl ld a,(hl) call &explosion_stuff pop hl ld a,(hl) cp 15 jr z,blown_up_enemy inc a ld (hl),a RET blown_up_enemy: dec hl ld (hl),0 ld hl,enemies_remaining dec (hl) ld hl,(score) smc_scoring: ld de,100 add hl,de ld (score),hl RET ; *************** Enemy Type 5 (Swooping Up + Right) *********************** enemy_type_5: ld a,7 ld bc,$01FF enemy_common: inc hl inc hl ld (next_type),a ld a,b add a,(hl) ld (hl),a ld d,a inc hl ld a,c add a,(hl) ld (hl),a ld e,a call &drw_spr ld a,(timer) and 3 RET nz POP BC pop hl push hl PUSH BC ld a,(next_type) ld (hl),a RET ; *************** Enemy Type 6 (Swooping Up + Left) ************************ enemy_type_6: ld a,8 ld bc,$FFFF jr enemy_common ; *************** Enemy Type 7 (Swooping Right) **************************** enemy_type_7: ld a,9 ld bc,$0100 jr enemy_common ; *************** Enemy Type 8 (Swooping Left) ***************************** enemy_type_8: ld a,10 ld bc,$ff00 jr enemy_common ; *************** Enemy Type 9 (Swooping Right / Down) ********************* enemy_type_9: ld bc,$0101 ld a,11 jr enemy_common ; *************** Enemy Type 10 (Swooping Left / Down) ********************* enemy_type_10: ld bc,$ff01 ld a,11 jr enemy_common ; *************** Enemy Type 11 (Swooping Down) **************************** enemy_type_11: ld a,12 ld bc,$0001 jr enemy_common ; *************** Enemy Type 12 (Swooping Down Quickly) ******************** enemy_type_12: inc hl inc hl ld d,(hl) inc hl inc (hl) inc (hl) ld e,(hl) ld a,78 cp e jr c,enemy_restore JP &drw_spr enemy_restore: POP BC pop hl push hl PUSH BC ld (hl),1 ld de,-1 ; *************** Subtract DE points from score ***************************** sub_score: push hl ld hl,(score) add hl,de jr nc,zero ld (score),hl pop hl ret zero: ld hl,0 ld (score),hl pop hl ret ; *************** Enemy Type 13 (Warp Enemy) ******************************* enemy_type_13: inc hl inc hl ld a,(hl) inc hl inc hl inc hl add a,(hl) ld d,a cp 1 jr nz,et13_not_x_2 ld (hl),1 et13_not_x_2: cp 23 jr nz,et13_not_x_23 ld (hl),1 ld a,r rra jr c,et13_not_x_23 ld (hl),-1 et13_not_x_23: cp 45 jr nz,et13_not_x_45 ld (hl),1 ld a,r rra jr c,et13_not_x_45 ld (hl),-1 et13_not_x_45: cp 87 jr nz,et13_not_x_87 ld (hl),-1 et13_not_x_87: dec hl dec hl dec hl ld (hl),d inc hl ld a,(hl) inc hl inc hl inc hl add a,(hl) jr z,et13_gone ld e,a cp 15 jr nz,et13_not_y_15 ld (hl),1 et13_not_y_15: cp 27 jr nz,et13_not_y_27 ld (hl),1 ld a,r rra jr c,et13_not_y_27 ld (hl),-1 et13_not_y_27: cp 39 jr nz,et13_not_y_39 ld (hl),-1 ld a,r rra jr c,et13_not_y_39 rra jr c,et13_not_y_39 call &test_operator jr z,et13_not_y_39 bit 3,c jr z,et13_not_y_39 ld (hl),-2 dec e et13_not_y_39: dec hl dec hl dec hl ld (hl),e jp &drw_spr et13_gone: pop bc pop hl push hl push bc ld (hl),a ld hl,enemies_remaining dec (hl) ld de,-50 call &sub_score ret test_operator: push hl push de ld hl,(enemy_image) ld de,&enemy_o call CP_HL_DE pop de pop hl ret ; *************** Shoot Your Lasers **************************************** You_Shoot_Laser: ld hl,jpf2 ;Test if F2 clicked in a,(1) bit 3,a jr z,pressed2 ld (hl),0 ret pressed2:ld a,(hl) or a ret nz ld (hl),1 ld hl,lasers ;Test # of lasers ld a,(hl) dec a ret m ld (hl),a ld a,(x) add a,3 ld b,a ;Draw laser ld c,63 call FIND_PIXEL ld de,$8641 add hl,de ld b,84 ld de,12 ldrawlaser: ld (hl),a add hl,de djnz ldrawlaser ld a,(x) ;Laser kills enemies add a,3 ld e,a ld hl,enemies ld b,20 l_laser: ld a,(hl) inc hl inc hl or a jr z,nohitl dec a jr z,nohitl cp 3 jr z,nohitl ld a,e sub (hl) and 248 jr nz,nohitl dec hl ld (hl),0 dec hl ld (hl),4 inc hl inc hl nohitl: inc hl inc hl djnz l_laser ret ; *************** Allow You To Shoot *************************************** You_Shoot: ld a,%00111111 out (1),a ld a,(your_status) or a ret nz ld hl,jpf1 in a,(1) bit 4,a jr z,pressed ld (hl),0 ret pressed: ld a,(hl) or a ret nz ld (hl),1 ;Comment out for auto-fire ld hl,ybullets ld de,3 ld b,10 find_ybullet: ld a,(hl) or a jr z,found_ybullet add hl,de djnz find_ybullet ret found_ybullet: ld (hl),1 inc hl ld a,(x) add a,2 ld (hl),a ld a,(y) sub 4 inc hl ld (hl),a ret ; *************** Move Your Bullets **************************************** kill_bullet: dec hl dec hl ld (hl),0 ret Move_Your_Bullets: ld hl,ybullets ld b,10 scan_your_bullets: push bc push hl ld (temp1),hl ld a,(hl) inc hl dec a call z,&bullet_type_1 pop hl pop bc ld de,3 add hl,de djnz scan_your_bullets ret bullet_type_1: ld d,(hl) inc hl ld e,(hl) dec e jr z,kill_bullet dec e jr z,kill_bullet ld (hl),e ld ix,&spr_bullet_1 push de call &drw_spr pop de ld b,20 ld hl,enemies hit_enemies: ;Hits with normal enemies push hl ld a,(hl) or a jr z,nohit dec a jr z,nohit cp 3 jr z,nohit inc hl inc hl ld a,(hl) sub d add a,5 jp m,&nohit cp 8 jr nc,nohit inc hl ld a,(hl) sub e add a,5 jp m,&nohit cp 10 jr nc,nohit push hl ld hl,(temp1) ld (hl),0 ld hl,(score) ld de,10 add hl,de ld (score),hl pop hl dec hl dec hl dec (hl) jr nz,nohit ld (hl),0 dec hl ld (hl),4 pop hl ret nohit: pop hl inc hl inc hl inc hl inc hl djnz hit_enemies ld hl,boss_status ;Hits with boss ld a,(hl) or a ret m ret z inc hl inc hl ld a,(hl) sub d bhsmc1: add a,15 ret m bhsmc2: cp 18 ret p inc hl ld a,(hl) sub e add a,8 ret m cp 13 ret p ld hl,(temp1) ld (hl),0 ld hl,(score) ld de,25 add hl,de ld (score),hl ld hl,boss_pwr dec (hl) ret nz ld (hl),0 dec hl ld (hl),-1 ret ; *************** In-Game Text ********************************************* in_game_text: .db 16,0,"LIVES",0 .db 16,3,"LEVEL",0 .db 16,6,"SCORE",0 ; *************** Display the Screen *************************************** Display_Screen: ld a,64 ;Display Image ld hl,GRAPH_MEM+(16*12) ld de,$fc00 dsl: ld bc,12 ldir inc de inc de inc de inc de dec a jr nz,dsl ld a,(lasers) ;Display number of lasers or a jr z,nolasers add a,'0' ld (CURSOR_X),de call M_CHARPUT nolasers: ld hl,$1007 ;Display Score ld (CURSOR_ROW),hl ld hl,(score) jp D_HL_DECI ; *************** Handle Your Ship ***************************************** Your_Ship: ld a,(your_status) bit 4,a jr nz,you_not_normal or a jr z,ok dec a ld (your_status),a ld hl,(lives) ld a,l or h jr nz,ok pop af ret ok: ld a,%01111110 out (1),a ld hl,y in a,(1) rra ld b,a jr c,no_down ld a,(hl) inc a cp 73 jr z,no_down ld (hl),a no_down: dec hl rr b jr c,no_left ld a,(hl) dec a jr z,no_left ld (hl),a no_left: rr b jr c,no_right ld a,(hl) inc a cp 89 jr z,no_right ld (hl),a no_right:ld d,(hl) inc hl rr b jr c,no_up ld a,(hl) dec a cp 60 jr z,no_up ld (hl),a no_up: ld ix,&spr_your_ship display_common: ld e,(hl) jp &drw_spr you_not_normal: ld de,-16 call &sub_score ld a,(your_status) dec a ld (your_status),a inc a and 14 xor 14 ld hl,x-1 explosion_stuff: rra add a,a add a,a add a,a ld c,a ld b,0 ld ix,&spr_explosion add ix,bc inc hl ld d,(hl) inc hl jr display_common ; *************** Control Key Processing *********************************** ;cheat: xor a ; ld (enemies_remaining),a ; ld hl,0 ; ld (score),hl ; ld (boss_status),hl ; ret Misc_Keys: call GET_KEY ;cp K_DOT ;jr z,cheat cp K_ENTER jr z,pause cp K_MORE jr z,e_save cp K_EXIT jr z,e_exit cp K_CLEAR ret nz pop af ret e_save: LD A,3 ;Save the game ld (USG_BITS),a ld de,&saved_flag ld (de),a inc de ld hl,TEXT_MEM ld bc,storage_length ldir jp &exit_game e_exit: ld a,3 ld (USG_BITS),a jp &exit_game pause: ld hl,$1901 ld (CURSOR_X),hl ld hl,&paused_msg call D_ZM_STR) ld de,$2001 ld (CURSOR_X),de call D_ZM_STR wenter: call GET_KEY ld hl,contrst cp K_ENTER ret z cp K_PLUS jr nz,nic ld a,(hl) cp $1f jr z,wenter inc a jr cc_common nic: cp K_MINUS jr nz,wenter ld a,(hl) or a jr z,wenter dec a cc_common: ld (hl),a out (2),a jr wenter paused_msg: .db "Paused - [ENTER] " .db "to continue",0 .db "[+] or [-] to " .db "change contrast",0 ; *************** Sprite Rendering Routine ********************************* offsets_table: .db 128,64,32,16,8,4,2,1 drw_spr: ld a,d and 7 ld hl,&offsets_table ld c,a ld b,0 add hl,bc ld a,(hl) ld (&_smc1+1),a ld hl,GRAPH_MEM ld a,e add a,a add a,e add a,a rl b add a,a rl b srl d srl d srl d add a,d jr nc,_n1 inc b _n1: ld c,a add hl,bc ld d,(ix) ld b,(ix+1) _oloop: push bc ;Save # of rows push hl ;Save screen address ld b,d ;Load width ld c,(ix+2) ;Load one line of image inc ix _smc1 ld a,1 ;Load pixel mask _iloop: sla c ;Test leftmost pixel jr nc,_noplot ;See if a plot is needed ld e,a ;OR pixel with screen or (hl) ld (hl),a ld a,e _noplot: rrca jr nc,_notedge ;Test if edge of byte reached inc hl ;Go to next byte _notedge:djnz _iloop pop hl ;Restore address ld bc,12 ;Go to next line add hl,bc pop bc ;Restore data djnz _oloop ret drw_sprw: ld a,d and 7 ld hl,&offsets_table ld c,a ld b,0 add hl,bc ld a,(hl) ld (&wsmc1+1),a ld (&wsmc2+1),a ld hl,GRAPH_MEM ld a,e add a,a add a,e add a,a rl b add a,a rl b srl d srl d srl d add a,d jr nc,n1 inc b n1: ld c,a add hl,bc ld d,(ix) ld b,(ix+1) woloop: push bc ;Save # of rows push hl ;Save screen address ld b,d ;Load width ld c,(ix+2) ;Load one line of image inc ix wsmc1 ld a,1 ;Load pixel mask wiloop: sla c ;Test leftmost pixel jr nc,wnoplot ;See if a plot is needed ld e,a ;OR pixel with screen or (hl) ld (hl),a ld a,e wnoplot: rrca jr nc,wnotedge ;Test if edge of byte reached inc hl ;Go to next byte wnotedge wsmc2: cp 1 jr z,wover_1 djnz wiloop pop hl ;Restore address ld bc,12 ;Go to next line add hl,bc pop bc ;Restore data djnz woloop ret wover_1: ld c,(ix+2) inc ix djnz wiloop dec ix pop hl ld bc,12 add hl,bc pop bc djnz woloop ret ; *************** Enter Next Level ***************************************** Next_Level: ld hl,enemies ld bc,80 call OTH_CLEAR xor a ld (timer),a ld hl,(score) ld de,200 add hl,de ld (score),hl ld hl,level inc (hl) ld a,(hl) cp 21 jp z,&won call &Update_Level_Number call &Load_Level_Data jp (hl) ; *************** Give Victory Bonus *************************************** won: pop af ld hl,(score) ld de,5000 add hl,de ld (score),hl ret ; *************** Load a Level Data Bank *********************************** Load_Level_Data: ld hl,(level) add hl,hl ld bc,&levels_jump_table-2 add hl,bc call LD_HL_MHL ld bc,(PROGRAM_ADDR) add hl,bc ld e,1 jp (hl) ; *************** Level Data Loaders *************************************** levels_jump_table: .dw level1 ;20xEnemy 1 .dw level2 ;20xEnemy 1 .dw level3 ;20xEnemy 1 & Boss 1 .dw level4 ;13xEnemy 1 & 7xEnemy 2 .dw level5 ;10xCross .dw level6 ;20xEnemy 2 .dw level7 ;20xEnemy 2 & Boss 2 .dw level8 ;13xEnemy 1 & 7xEnemy 3 .dw level9 ;10xCross .dw level10 ;20xEnemy 3 .dw level11 ;20xEnemy 3 & Boss 2 .dw level12 ;13xEnemy 1 & 7xEnemy 4 .dw level13 ;10xCross .dw level14 ;20xEnemy 4 .dw level17 ;10xO enemies .dw level15 ;20xEnemy 4 & Boss 2 .dw level17 ;10xO enemies .dw level16 ;Super-Boss & 8xEnemy 1 .dw level17 ;10xO enemies .dw level18 ;Super-Boss & 8xEnemy 2 load_coordinates: ld (enemy_image),bc ld (boss_image),de LD (enemy_pwr),a ld de,enemy_coords ld bc,40 ldir ret level1: ;Levels with one type of enemy ld hl,&Level1Pattern level1_: ld a,1 ld bc,&spr_enemy_1 level1__: call &load_coordinates ld hl,&setup_standard ret level2: ld hl,&Level2Pattern jr level1_ level6: ld hl,&Level6Pattern ld a,2 ld bc,&spr_enemy_2 jr level1__ level10: ld a,3 ld bc,&spr_enemy_3 level10_: ld hl,&Level10Pattern jr level1__ level14: ld a,4 ld bc,&spr_enemy_4 jr level10_ level3: ;Levels with bosses ld hl,&Level3Pattern ld a,1 ld bc,&spr_enemy_1 ld de,&spr_boss_1 level3_: call &load_coordinates ld hl,&setup_boss ret level7: ld hl,&Level7Pattern ld a,2 ld bc,&spr_enemy_2 level7_: ld de,&spr_boss_2 jr level3_ level11: ld a,3 ld bc,&spr_enemy_3 level11_: ld hl,&Level11Pattern jr level7_ level15: ld a,4 ld bc,&spr_enemy_4 jr level11_ level4: ;Levels with two enemy types ld hl,&Level4Pattern ld a,2 ld bc,&spr_enemy_2 level4_: ld e,-1 call &load_coordinates ld hl,&setup_weak ret level8: ld a,3 ld bc,&spr_enemy_3 level8_: ld hl,&Level8Pattern jr level4_ level12: ld a,4 ld bc,&spr_enemy_4 jr level8_ level5: ;Levels with cross enemies level9: level13: ld a,5 ld (enemy_pwr),a ld hl,&enemy_warped ld (enemy_image),hl ld (boss_image),hl ld hl,&setup_cross ret level17: ld a,8 ld (enemy_pwr),a ld hl,&enemy_o ld (enemy_image),hl ld (boss_image),hl ld hl,&setup_o ret level16: ld a,1 ld bc,&spr_enemy_1 level16_: ld hl,&Level1Pattern ld de,&spr_boss_3 call &load_coordinates ld hl,&setup_super ret level18: ld a,4 ld bc,&spr_enemy_4 jr level16_ ; *************** Level Set-Up Routines ************************************ setup_standard: ld a,20 setup_common: ld b,20 put8: ld hl,enemies_remaining ld (hl),a ld hl,enemies ld c,1 ld a,(enemy_pwr) ld d,110 lle: ld (hl),c inc hl ld (hl),a inc hl ld (hl),d inc hl ld (hl),d inc hl djnz lle ret setup_boss: ld hl,&bhsmc1+1 ld (hl),15 ld hl,&bhsmc2+1 ld (hl),18 ld hl,boss_status ld (hl),1 inc hl ld (hl),10 inc hl ld (HL),30 INC HL LD (HL),0 ld a,21 jr setup_common setup_weak: call &setup_standard ld hl,enemies+1 ld b,13 weak: ld (hl),1 inc hl inc hl inc hl inc hl djnz weak ret setup_o: setup_cross: ld a,10 ld (enemies_remaining),a ld b,a ld hl,enemies generate_warp_enemies: ld (hl),13 inc hl ld a,(enemy_pwr) ld (hl),a inc hl ld a,r and 63 add a,10 ld (hl),a inc hl xor a ld (hl),a inc hl ld (hl),a inc hl inc a ld (hl),a inc hl ld (hl),a inc hl inc hl djnz generate_warp_enemies ret setup_super: ld b,8 ld a,9 call &put8 ld hl,&bhsmc1+1 ld (hl),31 ld hl,&bhsmc2+1 ld (hl),34 ld hl,boss_status ld (hl),5 inc hl ld (hl),98 inc hl ld (HL),2 INC HL LD (HL),0 ret ; *************** Level Data *********************************************** Level1Pattern: .db 10,16,20,16,30,16,40,16,50,16 .db 5,24,15,24,25,24,35,24,45,24 .db 50,32,10,32,20,32,30,32,40,32 .db 5,40,15,40,25,40,35,40,45,40 Level2Pattern: .db 1,16,14,16,27,16,40,16,53,16 .db 1,24,14,24,27,24,40,24,53,24 .db 1,32,14,32,27,32,40,32,53,32 .db 1,40,14,40,27,40,40,40,53,40 Level3Pattern: .db 1,26,14,26,27,26,40,26,53,26 .db 1,34,14,34,27,34,40,34,53,34 .db 1,42,14,42,27,42,40,42,53,42 .db 1,50,14,50,27,50,40,50,53,50 Level4Pattern: .db 5,18,13,18,21,18,29,18,37,18,45,18,53,18 .db 9,28,17,28,25,28,33,28,41,28,49,28 .db 5,38,13,38,21,38,29,38,37,38,45,38,53,38 Level6Pattern: .db 53,28 .db 52,32 .db 48,35 .db 42,38 .db 35,39 .db 27,40 .DB 19,39 .DB 12,38 .DB 6,35 .db 2,32 .db 1,28 .db 2,24 .DB 6,21 .DB 12,18 .DB 19,17 .DB 27,16 .DB 35,17 .DB 42,18 .DB 48,21 .db 52,24 Level7Pattern: .db 1,26,14,26,27,26,40,26,53,26 .db 1,34,14,34,27,34,40,34,53,34 .db 1,42,14,42,27,42,40,42,53,42 .db 1,50,14,50,27,50,40,50,53,50 Level8Pattern: .db 5,18,13,18,21,18,29,18,37,18,45,18,53,18 .db 9,28,17,28,25,28,33,28,41,28,49,28 .db 5,38,13,38,21,38,29,38,37,38,45,38,53,38 Level10Pattern: .DB 01,16,01,22,01,28,01,34,01,40 .DB 19,16,19,22,19,28,19,34,19,40 .db 37,16,37,22,37,28,37,34,37,40 .db 55,16,55,22,55,28,55,34,55,40 Level11Pattern: .db 1,26,14,26,27,26,40,26,53,26 .db 1,34,14,34,27,34,40,34,53,34 .db 1,42,14,42,27,42,40,42,53,42 .db 1,50,14,50,27,50,40,50,53,50 ; *************** Sprites ************************************************** enemy_warped: .db 7,7 .db %11000110 .db %11101110 .db %01111100 .db %00111000 .db %01111100 .db %11101110 .db %11000110 spr_enemy_1: .db 6,6 .db %10000100 .db %10000100 .db %11111100 .DB %11111100 .DB %01111000 .DB %00110000 spr_enemy_2: .db 6,7 .db %10000100 .db %11001100 .db %11111100 .db %10000100 .db %10000100 .db %01001000 .db %00110000 spr_enemy_3: .db 6,5 .db %10000100 .db %11111100 .DB %10000100 .DB %01001000 .db %00110000 spr_enemy_4: .db 7,5 .db %10000010 .db %11000110 .db %10101010 .db %10010010 .db %10000010 enemy_o: .db 7,7 .db %01111100 .db %11111110 .db %11000110 .db %11000110 .db %11000110 .db %11111110 .db %01111100 spr_boss_1: .db 16,8 .db %10000000,%00000001 .db %11000000,%00000011 .db %10111111,%11111101 .db %10000001,%10000001 .db %10000001,%10000001 .db %01000001,%10000010 .db %00100001,%10000100 .db %00011111,%11111000 spr_boss_2: .db 16,8 .db %11111111,%11111111 .db %11100000,%00000111 .db %11100000,%00000111 .db %11100000,%00000111 .db %11100000,%00000111 .db %11110000,%00001111 .db %11101000,%00010111 .db %01000111,%11100010 spr_boss_3: .db 31,8 .db %11111111,%11111111,%11111111,%11111110 .db %10101000,%00000000,%00000000,%00101010 .db %10101001,%01010101,%01010101,%00101010 .db %10101000,%00000000,%00000000,%00101010 .db %10101000,%00000111,%11000000,%00101010 .db %10001111,%11000010,%10000111,%11100010 .db %01010000,%00100001,%00001000,%00010100 .db %00100000,%00011111,%11110000,%00001000 spr_enemy_bullet: .db 3,3 .db %01000000 .db %11100000 .db %01000000 spr_explosion: .db 8,6 .db %00000000 .db %00011100 .DB %00111110 .DB %01010110 .DB %00111000 .DB %00000000 .db 8,6 .db %00110000 .db %01001110 .DB %10111110 .DB %01001111 .DB %00111000 .DB %00011010 .db 8,6 .db %11110011 .db %01001110 .DB %10110101 .DB %01000101 .DB %00111110 .DB %11011010 .db 8,6 .db %11110011 .db %01001110 .DB %10110101 .DB %01000101 .DB %00111110 .DB %11011010 .db 8,6 .db %01000001 .db %00100110 .DB %00010101 .DB %01000100 .DB %00010010 .DB %10011010 .db 8,6 .db %01000010 .db %00100000 .DB %00000001 .DB %01000100 .DB %00100010 .DB %10001010 .db 8,6 .db %00001000 .db %11000010 .DB %00000000 .db %00100000 .db %00000001 .db %00110000 .db 8,6 .db %00000100 .DB %00000000 .DB %01000000 .DB %00000000 .db %00000001 .db %00100100 spr_bullet_1: .db 3,5 .db %01000000 .db %11100000 .db %11100000 .db %11100000 .DB %11100000 spr_your_ship: .db 7,7 .DB %00010000 .DB %00111000 .DB %10111010 .DB %10111010 .DB %10111010 .DB %11111110 .DB %11111110 ; **************** Title Screen Text *************************************** title_message: .db "G A L A X I A N",0 title_menu: .db 38,20,"Version 3.0",0 .db 5,28,"Copyright 1998 by" .db " Patrick Davidson",0 .db 11,36,"E-Mail : " .db "eeulplek@hotmail.com",0 .db 18,47,"Press [F1] for " .db "instructions",0 instructions: .db 10,55,"Press [ENTER] " .db "to begin the game!",0 .db 28,23,"Arrow keys - move ship",0 .db 25,30,"[F1] - Cannon" .db " [F2]-Laser",0 .db 13,37,"[ENTER] - Pause " .db "[CLEAR] - Quit",0 .db 9,44,"[EXIT] - Exit " .db "[MORE] - Save & exit",0 igc: .db "Ingame Controls",0 ; **************** Saved Game Data ***************************************** saved_flag: .db 0 save_data: .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; **************** High-Score Data ***************************************** hi_score_str: .db "----> GALAXIAN! <----" .db " You have a hiscore!" .db "Enter your name: ",0 hstitle: .db "=GALAXIAN HIGHSCORES=",0 hsdata: .dw 50000 .db "Galaxian 3.0 ",0 .dw 40000 .db "Galaxian 3.0 ",0 .dw 30000 .db "Galaxian 3.0 ",0 .dw 25000 .db "Galaxian 3.0 ",0 .dw 20000 .db "Galaxian 3.0 ",0 .dw 15000 .db "Galaxian 3.0 ",0 lowest .dw 10000 .db "Galaxian 3.0 ",0 chartable: .db "XTOJE." .db ". WSNID!.ZVRMHC?" .db ".YUQLGB#x~+PKFA|" .db "@54321.~+" .end