; / \ / ; \ pace \ / ar ; / \/\/ v1.0 ; by Joe Wingbermuehle #INCLUDE "CRASH82.INC" .DB "SpaceWar v1.0 by Joe W",0 #define max_aliens 15 ;---------= Variables =--------- alien_num = APD_BUF ; number of aliens on field shipy = APD_BUF+1 ; ship y shipx = APD_BUF+2 ; ship x bullety = APD_BUF+3 ; bullet y bulletx = APD_BUF+4 ; bullet x bullet_active = APD_BUF+5 ; is bullet active? bullet_dir = APD_BUF+6 ; bullet direction active_ship = APD_BUF+7 ; ship direction (specifies sprite) alien_timer = APD_BUF+8 ; so alien doesn't move too fast dead = APD_BUF+9 ; 1 if dead, 0 if alive bomb_map = APD_BUF+10 ; count, x,y 3*10=30 bytes alien_map = APD_BUF+40 ; type, phase, x, y, movx, movy, count ; 7*max_aliens bytes level = APD_BUF+145 ; current level 0-15 main_timer = APD_BUF+146 ; move bullets twice before updating score = APD_BUF+147 ; 2 bytes ;---------= Beginning of Code =--------- start_of_program: ROM_CALL(CLEARLCD) ld hl,2*256+2 ld (CURSOR_ROW),hl ld hl,title ROM_CALL(D_LT_STR) ld hl,5*256+3 ld (CURSOR_ROW),hl ld hl,about1 ROM_CALL(D_ZT_STR) ld de,2*256+4 ld (CURSOR_ROW),de ROM_CALL(D_ZT_STR) ld de,7 ld (CURSOR_ROW),de ROM_CALL(D_ZT_STR) ld hl,(high_score) call disphl call wait_key xor a ld (level),a sbc hl,hl ld (score),hl new_level: ld hl,level inc (hl) call BUFCLR ld a,1 ld (active_ship),a ld hl,40*256+30 ld (shipy),hl call draw_my_ship ;-----> Clear out some variables xor a ld (bullet_active),a ld (main_timer),a ld (alien_timer),a ld (dead),a ld hl,bomb_map ld b,(3*10)+(max_aliens*7) clear_vars: ld (hl),a inc hl djnz clear_vars ld a,r ld (data),a ld a,(level) ld (alien_num),a ;-----> Start up aliens ld b,a ld hl,alien_map spawn_loop: push bc ld b,3 call rand inc a ld (hl),a ; type push af inc hl ld (hl),0 ; phase ld d,h ld e,l inc hl ld (hl),85 ; x inc hl ld b,54 call rand inc a ld (hl),a ; y inc hl ld b,3 call rand dec a ld (hl),a ; movx inc hl ld b,3 call rand dec a ld (hl),a ; movy inc hl ld b,20 call rand inc a ld (hl),a ; count pop af ld b,0 push hl call draw_alien_ship pop hl inc hl pop bc djnz spawn_loop ;---------= Main Loop =--------- main: call move_bullet ld a,(main_timer) xor %00000001 ld (main_timer),a jr z,main call move_aliens call update_bombs call collision_chk ld a,(alien_num) or a jp z,winner ld a,(dead) or a jr nz,exit call CR_GRBCopy ld a,$FF out (1),a ld a,$FE out (1),a in a,(1) cp 247 jp z,mup cp 251 jp z,mright sub 253 jp z,mleft dec a jp z,mdown ld a,$BF out (1),a in a,(1) cp 191 jp z,pause cp 223 jp z,fire_missle cp 127 jr nz,main exit: ROM_CALL(CLEARLCD) ld hl,4*256+2 ld (CURSOR_ROW),hl ld hl,lost_text quit: ROM_CALL(D_ZT_STR) ld hl,2*256+4 ld (CURSOR_ROW),hl ld hl,level_text ROM_CALL(D_ZT_STR) ld hl,(level) ld h,0 call disphl ld hl,2*256+5 ld (CURSOR_ROW),hl ld hl,score_text ROM_CALL(D_ZT_STR) ld hl,(score) push hl call disphl pop hl ld de,(high_score) call hiscr ld (high_score),hl jr nz,not_nhs ld hl,1*256+7 ld (CURSOR_ROW),hl ld hl,nhs_text ROM_CALL(D_ZT_STR) not_nhs: jp wait_key ;---------= Beat level or game =--------- winner: ld a,(level) cp 15 jp nz,new_level ROM_CALL(CLEARLCD) ld hl,4*256+2 ld (CURSOR_ROW),hl ld hl,win_text jr quit ;---------= Move Left =--------- mleft: call draw_my_ship ld a,2 ld (active_ship),a ld hl,shipx ld a,(hl) dec a jr nz,end_move ld a,89 jr end_move ;---------= Move Right =--------- mright: call draw_my_ship ld a,1 ld (active_ship),a ld hl,shipx ld a,(hl) inc a cp 90 jr nz,end_move ld a,1 jr end_move ;---------= Move Up =--------- mup: call draw_my_ship ld a,3 ld (active_ship),a ld hl,shipy ld a,(hl) dec a jr nz,end_move ld a,58 jr end_move ;---------= Move Down =--------- mdown: call draw_my_ship ld a,4 ld (active_ship),a ld hl,shipy ld a,(hl) inc a cp 59 jr nz,end_move ld a,1 end_move: ld (hl),a call draw_my_ship jp main ;---------= Fire a missle =--------- fire_missle: ld a,(bullet_active) or a jr nz,fire_exit ld a,(active_ship) ld (bullet_dir),a ld hl,(shipy) inc h inc l ld (bullety),hl ld a,1 ld (bullet_active),a call draw_bullet fire_exit: jp main ;---------= Pause =--------- pause: ; call getkey ; call getkey ; for screen shot set 3,(iy+5) ld hl,3*256+2 ld (CURSOR_ROW),hl ld hl,paused_text ROM_CALL(D_ZT_STR) ld de,3*256+3 ld (CURSOR_ROW),de ROM_CALL(D_ZT_STR) ld hl,(level) ld h,0 call disphl ld hl,3*256+4 ld (CURSOR_ROW),hl ld hl,score_text ROM_CALL(D_ZT_STR) ld hl,(score) call disphl res 3,(iy+5) call wait_key jp main ;---------= Draw my ship =--------- draw_my_ship: ld ix,my_ships-5 ld de,$0005 ld bc,(active_ship-1) draw_my_ship_lp: add ix,de djnz draw_my_ship_lp ld hl,(shipy) ld a,h ld b,e jp sprite ;---------= Update Bombs =--------- update_bombs: ld b,10 ld hl,bomb_map bomb_loop: push bc push hl ld a,(hl) or a jr z,bomb_not_active dec a ld (hl),a ld c,0 ld ix,bomb cp 21 jr nz,bomb_skip0 inc c bomb_skip0: cp 11 jr z,bomb_is1 cp 20 jr nz,bomb_skip1 bomb_is1: ld ix,bomb2 inc c bomb_skip1: cp 10 jr z,bomb_is3 or a jr nz,bomb_skip3 bomb_is3: ld ix,bomb3 inc c bomb_skip3: inc hl inc hl ex de,hl ld a,(de) ld l,a dec de ld a,(de) ld b,8 dec c call z,sprite bomb_not_active: pop hl inc hl inc hl inc hl pop bc djnz bomb_loop ret ;---------= Move Bullet =--------- move_bullet: ld a,(bullet_active) or a ret z call draw_bullet ld a,(bullet_dir) dec a jr nz,bul_nright ld a,(bulletx) inc a ld (bulletx),a cp 92 jr z,bullet_not_active jr bullet_still_active bul_nright: ; left dec a jr nz,bul_nleft ld a,(bulletx) dec a ld (bulletx),a jr z,bullet_not_active jr bullet_still_active bul_nleft: ; up dec a jr nz,bul_nup ld a,(bullety) dec a ld (bullety),a jr z,bullet_not_active jr bullet_still_active bul_nup: ; down ld a,(bullety) inc a ld (bullety),a cp 60 jr nz,bullet_still_active bullet_not_active: xor a ld (bullet_active),a ret bullet_still_active: ;---------= Draw Bullet =--------- draw_bullet: ld ix,bullet ld hl,(bullety) ld a,h ld b,3 jp sprite ;---------= Check for Collision =--------- collision_chk: ld b,max_aliens ld hl,alien_map collision_lp: push hl ld a,(hl) or a jr z,collision_sk2 inc hl ; phase inc hl ; x ld a,(shipx) sub 6 cp (hl) jr nc,collision_sk1 add a,10 cp (hl) jr c,collision_sk1 inc hl ld a,(shipy) sub 6 cp (hl) jr nc,collision_sk1 add a,10 cp (hl) jr c,collision_sk1 ld a,1 ld (dead),a collision_sk1: ld a,(bullet_active) or a jr z,collision_sk2 pop hl push hl inc hl ; phase inc hl ; x ld a,(bulletx) cp (hl) jr c,collision_sk2 sub 6 cp (hl) jr nc,collision_sk2 inc hl ld a,(bullety) cp (hl) jr c,collision_sk2 sub 6 cp (hl) jr nc,collision_sk2 ex de,hl dec de ; x dec de ; phase dec de ; type ld a,(de) ld b,a inc de ; phase ld a,(de) call draw_alien_ship dec de ; type xor a ld (de),a ld hl,alien_num dec (hl) ld hl,(score) inc hl ld (score),hl pop hl jr collision_chk collision_sk2: pop hl ld de,$0007 add hl,de djnz collision_lp ld b,10 ld hl,bomb_map collision_lp2: push hl ld a,(hl) or a jr z,collision_sk3 cp 50 jr nc,collision_sk3 inc hl ld a,(shipx) sub 8 cp (hl) jr nc,collision_sk3 add a,12 cp (hl) jr c,collision_sk3 inc hl ld a,(shipy) sub 8 cp (hl) jr nc,collision_sk3 add a,12 cp (hl) jr c,collision_sk3 ld a,1 ld (dead),a collision_sk3: pop hl inc hl inc hl inc hl djnz collision_lp2 ret ;---------= Start a Bomb! =--------- start_bomb: push de ld hl,bomb_map ld b,10 find_bomb: ld a,(hl) or a jr nz,bomb_active ld (hl),$FF inc hl ; x ld a,(de) ld (hl),a inc hl ; y inc de ld a,(de) ld (hl),a ex de,hl ld a,(de) ld l,a dec de ld a,(de) ld ix,bomb ld b,8 call sprite pop de ret bomb_active: inc hl inc hl inc hl djnz find_bomb pop de ret ; oh well ;---------= Move Aliens =--------- move_aliens: ld a,(alien_timer) xor 1 ld (alien_timer),a ret z ld de,alien_map ld b,max_aliens move_alien_loop: push bc push de ld a,(de) ; type or a jr z,alien_not_active ld b,a inc de ld a,(de) ; phase call draw_alien_ship ld a,(de) xor 1 ld (de),a inc de ; x ld l,e ld h,d inc de ; y inc de ; movx ld a,(de) ld b,(hl) add a,b ld (hl),a jr nz,alien_skip1 ld a,86 ld (hl),a alien_skip1: cp 87 jr nz,alien_skip2 ld a,1 ld (hl),a alien_skip2: inc hl inc de ld a,(de) ld b,(hl) add a,b ld (hl),a jr nz,alien_skip3 ld a,54 ld (hl),a alien_skip3: cp 55 jr nz,alien_skip4 ld a,1 ld (hl),a alien_skip4: inc de ld a,(de) ; decrease count dec a ld (de),a jr nz,alien_still_active push de ;-----> Get new direction dec de dec de ; movx ld b,3 call rand dec a ld (de),a inc de ld b,3 call rand dec a ld (de),a inc de ld b,20 call rand inc a ld (de),a dec de dec de ; y dec de ; x dec de ; phase ld a,(de) ld b,a dec de ; type ld a,(de) pop de alien_still_active: dec de ; movy dec de ; movx dec de ; y dec de ; x ld b,100 call rand or a call z,start_bomb dec de ; phase dec de ; type ld a,(de) ld b,a inc de ; phase ld a,(de) call draw_alien_ship alien_not_active: pop hl ld de,$0007 add hl,de ex de,hl pop bc djnz move_alien_loop ret ;---------= Draw Alien Ship =--------- draw_alien_ship: add a,b ; type+phase (type starts at 1, phase at 0) ld ix,alien_ships-8 ld bc,$0008 draw_alien_ship_lp: add ix,bc dec a jr nz,draw_alien_ship_lp push de inc de ; x inc de ; y ld a,(de) ld l,a dec de ; x ld a,(de) ld b,8 call sprite pop de ret ;---------= Wait for a keypress =--------- wait_key: ld b,50 key_loop1: ei halt djnz key_loop1 key_loop2: call GET_KEY or a jr z,key_loop2 ret ;-------= BufClr =---------- BUFCLR: ld hl,$88B8 ld de,$88B9 ld bc,$2FF ld (hl),0 ldir ret ;-----= Disp HL =------ disphl: ROM_CALL(D_HL_DECI) ret ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ;-= Data -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ;---------= Sprites =--------- bullet: .db %01000000 .db %11100000 .db %01000000 my_ships: .db %11000000 ; right .db %01100000 .db %01111000 .db %01100000 .db %11000000 .db %00011000 ; left .db %00110000 .db %11110000 .db %00110000 .db %00011000 .db %00100000 ; up .db %00100000 .db %01110000 .db %11111000 .db %10001000 .db %10001000 ; down .db %11111000 .db %01110000 .db %00100000 .db %00100000 alien_ships: ; type 1 .db %00001100 ; phase 0 .db %01101000 .db %00101110 .db %11100000 .db %00000111 .db %01110101 .db %00010100 .db %00110000 .db %00101100 ; phase 1 .db %01001110 .db %11101101 .db %11100000 .db %00000111 .db %10110111 .db %01110010 .db %00110100 ; type 3 (types are in increments of 2) .db %00111100 .db %00011000 .db %10011001 .db %11111111 .db %11111111 .db %10011001 .db %00011000 .db %00111100 .db %00100100 .db %01000010 .db %10000001 .db %00011000 .db %00011000 .db %10000001 .db %01000010 .db %00100100 bomb: .db %00000000 .db %00000000 .db %00011000 .db %00111100 .db %00111100 .db %00011000 .db %00000000 .db %00000000 bomb2: .db %00000000 .db %00001000 .db %01011010 .db %00111100 .db %00111110 .db %01011000 .db %00010010 .db %00000000 bomb3: .db %01010010 .db %10101000 .db %00011010 .db %01101101 .db %00110110 .db %10011100 .db %01100010 .db %00010100 ;---------= Dialog =--------- paused_text: .db " - Pause - ",0 level_text: .db "Level:",0 score_text: .db "Score:",0 lost_text: .db "You Lost",0 win_text: .db "You Won!",0 high_text: .db "HiScore:",0 nhs_text: .db "New High Score",0 about1: .db "by Joe",0 about2: .db "Wingbermuehle",0 about3: .db "HiScore:",0 high_score: .dw 0 title: .db 13 sos_description: .db "SpaceWar v1.0 by Joe W" .db 0 ;--------= Libs =--------- #define data APD_BUF+150 ; 2 bytes of data .dw sprite ; draw a sprite 1 .dw rand ; random number 2 .dw hiscr ; check for/set high score D ;---------= XOR a sprite =--------- ; b=size of sprite ; l=yc ; a=xc ; ix holds pointer sprite: ld e,l ld h,$00 ld d,h add hl,de add hl,de add hl,hl add hl,hl ld e,a and $07 ld c,a srl e srl e srl e add hl,de ld de,GRAPH_MEM add hl,de push ix pop de sl1: push bc ld a,(de) ld b,a ld a,c or a jr z,sl3 ld c,$00 sl2: srl b rr c dec a jr nz,sl2 sl3: ld a,(hl) xor b ld (hl),a inc hl ld a,(hl) xor c ld (hl),a ld bc,$0B add hl,bc inc de pop bc djnz sl1 ret ;---------= Random number generator =--------- ; input b=upper bound ; ouput a=answer 0<=a