DEFINT A-Z DECLARE FUNCTION IsAlien (pixel) DECLARE FUNCTION IsCell (pixel) DECLARE FUNCTION Cellx (x, dir) DECLARE FUNCTION ArrayBytes (x, y) DECLARE FUNCTION BombObstructed (a, b) DECLARE SUB DisplayLives (lives) DECLARE SUB DisplayLevel () DECLARE SUB WaitRetrace () DECLARE SUB DefineGraphics () DECLARE SUB SetColour (colour, r, g, b) DECLARE SUB Display (x, y, a$) DECLARE SUB DisplayScore () DECLARE SUB DrawPlanet (visible) DECLARE SUB DrawShelters (visible) DECLARE SUB DrawCells (visible) DECLARE SUB Delay (seconds!) DECLARE SUB ClearScreen () DECLARE SUB ClearScreenToCRT () DECLARE SUB IncScore (scoregain) DECLARE SUB ErodeShelter (x, y) DECLARE FUNCTION sbvoicetoreg (voice) DECLARE SUB sbwritereg (register, byte) DECLARE SUB sbresetcard () DECLARE SUB sbsetupvoice (voice) DECLARE SUB sbvoiceoff (voice) DECLARE SUB sbplaynote (voice, octave, note) DECLARE SUB sbvolume (voice, volume) DECLARE SUB sbmodulate (voice, volume) DEF SEG = 0 RANDOMIZE TIMER SCREEN 13 true = -1 false = NOT true invaders = 22 screenwidth = 256 screenorgx = 32 invwidth = 8 invheight = 8 invminx = screenorgx + 2 invmaxx = screenorgx + screenwidth - invwidth - 2 invbombheight = 5 invystep = 7 invzaptime = 15 invexpwidth = 12 shipwidth = 15 shipheight = 8 shipminx = screenorgx + invwidth * 1.4 shipmaxx = screenorgx + screenwidth - invwidth * 1.4 - shipwidth shipy = 199 - 12 bulletheight = 3 bulletd = 3 maxbombs = 20 saucerwidth = 16 saucerheight = 7 saucery = 14 shelterwidth = 24 shelterheight = 16 sheltery = shipy - shipheight * 1.3 - shelterheight molewidth = 18 moleheight = 8 moley = sheltery - moleheight * 1.5 molexstep = 10 molezaptime = 15 cellwidth = 6 invbasey = saucery + saucerheight + 8 cellcolour = invaders + 1 shipcolour = 255 bulletcolour = 254 bombcolour = 253 shipexplodecolour = 252 invexplodecolour = 251 sheltercolour = 250 textcolour = 249 planetcolour = 248 saucercolour = 247 crtcolour = 246 molecolour = 245 moleexpcolour = 244 FOR i = 1 TO invaders c = 63 - ((i - 1) AND &HFE) SetColour i, c, 32 - c, 0 NEXT FOR i = 0 TO invaders * 3 - 1 SetColour cellcolour + i, 32, 32, 40 NEXT SetColour shipcolour, 0, 63, 0 SetColour shipexplodecolour, 0, 63, 0 SetColour invexplodecolour, 63, 52, 16 SetColour molecolour, 63, 63, 63 SetColour moleexpcolour, 63, 63, 63 SetColour bulletcolour, 63, 63, 63 SetColour bombcolour, 48, 0, 0 SetColour sheltercolour, 0, 48, 0 SetColour textcolour, 63, 0, 0 SetColour planetcolour, 0, 63, 0 SetColour saucercolour, 63, 63, 0 SetColour crtcolour, 14, 14, 14 'SetColour crtcolour, 30, 30, 30 shipgsize = ArrayBytes(shipwidth - 4, shipheight - 4) DIM shipg(shipgsize) DIM shipexpg(2 * shipgsize) invgsize = ArrayBytes(invwidth - 3, invheight - 3) DIM invg(2 * invaders * invgsize) invbombgsize = ArrayBytes(1, 3) DIM invbombg(2 * invbombgsize) invexpgsize = ArrayBytes(invexpwidth, invheight) DIM invexpg(invexpgsize) molegsize = ArrayBytes(molewidth, moleheight) DIM moleg(2 * molegsize) DIM moleexpg(2 * molegsize) DIM saucerg(ArrayBytes(saucerwidth - 3, saucerheight - 3)) DIM shelterg(ArrayBytes(shelterwidth - 6, shelterheight - 6)) chargsize = ArrayBytes(2, 5) DIM charset(chargsize * 127) DIM damagex(255), damagey(255) FOR i = 0 TO 255 damagex(i) = RND * 4 damagey(i) = RND * 6 NEXT invvoice = 1 bulletvoice = 2 invzapvoice = 3 saucervoice = 4 shipexpvoice = 5 molevoice = 6 DIM invnote(3) FOR i = 0 TO 3 READ invnote(i) NEXT DATA &H2AE,&H287,&H263,&H241 sbresetcard FOR i = 1 TO 6 sbsetupvoice i NEXT sbmodulate invvoice, 40 sbmodulate bulletvoice, 45 sbvolume bulletvoice, 45 sbmodulate invzapvoice, 20 sbvolume invzapvoice, 53 sbvolume saucervoice, 55 sbmodulate saucervoice, 24 sbmodulate shipexpvoice, 63 sbmodulate molevoice, 63 sbvolume molevoice, 63 DefineGraphics DIM invx(invaders), invy(invaders), invd(invaders), invc(invaders), invs(invaders) DIM bombx(maxbombs), bomby(maxbombs), bombs(maxbombs), bombtype(maxbombs) speedtest = false score = 0 WHILE NOT switchoff ClearScreen WHILE INKEY$ > "" WEND Display 0, 0, "SCORE:" DisplayScore a$ = "" WHILE a$ = "" AND 0 WaitRetrace Display 11 * 8, 10 * 9, "GAME OVER" FOR i = 1 TO 2 WaitRetrace NEXT Display 11 * 8, 10 * 9, " " a$ = INKEY$ switchoff = (a$ = CHR$(27)) WEND '------------------ Next Game --------------- IF NOT switchoff THEN score = 0 lives = 3 level = 1 damagecounter = RND * 200 bombchance = 98 invmovechance = 99 molebasetrigger = 20 gameover = false ClearScreen Display 0, 0, "SCORE:" DisplayScore Display 13 * 8, 0, "LEVEL:" Display 25 * 8, 0, "LIVES:" DisplayLives lives END IF '------------------ Next Level -------------- WHILE NOT gameover AND NOT switchoff DisplayLevel DrawPlanet true DrawShelters true Delay .5 DrawCells true bombchance = bombchance + (bombchance > 89) invmovechance = invmovechance + (invmovechance > 87) shipx = screenorgx + screenwidth / 2 - shipwidth / 2 canfire = false pause = false saucers = false moles = false molebasetrigger = molebasetrigger + 2 * (molebasetrigger > 10) moletrigger = molebasetrigger + RND * 7 numbombs = 0 FOR i = 1 TO maxbombs bombs(i) = false NEXT inv = 1 FOR y = 0 TO invaders / 2 - 1 FOR x = 0 TO 1 IF x = 0 THEN invx(inv) = invminx ELSE invx(inv) = invmaxx END IF invy(inv) = invbasey + y * 10 invd(inv) = 0 invc(inv) = false invs(inv) = true inv = inv + 1 NEXT NEXT invleft = invaders inv = 0 invanim = 0 invnote = 0 invnotelength = 12 invnoted = 1 invnotes = true endinglevel = false Delay .5 saucercycles = 0 molecycles = 0 '------------------ Next Cycle -------------- WHILE NOT endlevel AND NOT gameover AND NOT switchoff FOR l = 1 TO 1 WaitRetrace NEXT IF speedtest THEN SetColour 0, 63, 0, 0 END IF IF NOT pause THEN 'move invaders IF (NOT dying) AND (NOT endinglevel) AND (invzapticks = 0) THEN DO inv = inv + 1 IF inv > invaders THEN inv = 1 invanim = invanim XOR 1 END IF LOOP UNTIL invs(inv) LINE (invx(inv), invy(inv))-STEP(invwidth - 1, invheight - 1), crtcolour, BF IF invc(inv) THEN x = Cellx(invx(inv), invd(inv)) LINE (x, invy(inv) + 1)-STEP(cellwidth - 1, cellwidth), crtcolour, BF END IF invx(inv) = invx(inv) + invd(inv) anim = (inv AND 2) \ 2 IF invanim = 1 THEN anim = anim XOR 1 PUT (invx(inv), invy(inv)), invg((inv - 1) * 2 * invgsize + anim * invgsize), PSET IF invc(inv) THEN x = Cellx(invx(inv), invd(inv)) LINE (x, invy(inv) + 1)-STEP(cellwidth - 1, cellwidth - 1), 63, BF END IF IF invd(inv) <> 0 AND NOT invc(inv) THEN SELECT CASE SGN(invd(inv)) CASE 1 a = POINT(invx(inv) + invwidth + 2, invy(inv) + 2) CASE -1 a = POINT(invx(inv) - 3, invy(inv) + 2) END SELECT IF IsCell(a) THEN invd(inv) = -invd(inv) invc(inv) = true END IF END IF IF invx(inv) = invminx OR invx(inv) = invmaxx THEN invd(inv) = 0 IF invc(inv) THEN LINE (x, invy(inv) + 1)-STEP(cellwidth - 1, cellwidth - 1), crtcolour, BF invc(inv) = false END IF END IF IF invd(inv) = 0 AND RND * 100 > invmovechance THEN IF invx(inv) < screenorgx + screenwidth \ 2 THEN invd(inv) = 2 ELSE invd(inv) = -2 END IF END IF END IF 'invader move sound invnoted = invnoted - 1 IF invnoted = 0 THEN IF invnotes THEN IF invleft > 11 THEN sbvoiceoff invvoice END IF invnoted = invleft - invnotelength IF invnoted < 1 THEN invnoted = 1 END IF ELSE IF invleft > 0 AND NOT dying AND NOT endinglevel THEN sbplaynote invvoice, 1, invnote(invnote) invnote = (invnote + 1) AND 3 END IF invnoted = invnotelength END IF invnotes = NOT invnotes END IF 'drop bomb IF NOT dying AND NOT endinglevel AND invd(inv) <> 0 AND numbombs < maxbombs AND RND * 100 > bombchance THEN x = invx(inv) + 3 y = invy(inv) + 8 IF NOT BombObstructed(POINT(x, y + 5), POINT(x + 2, y + 5)) AND NOT BombObstructed(POINT(x, y + 2), POINT(x + 2, y + 2)) THEN i = 1 WHILE bombs(i) i = i + 1 WEND bombx(i) = x bomby(i) = y bombs(i) = true IF RND * 100 > 98 AND y < invbasey + 5 * 10 THEN bombtype(i) = 1 ELSE bombtype(i) = 0 END IF numbombs = numbombs + 1 END IF END IF 'move bombs FOR i = 1 TO maxbombs IF bombs(i) THEN LINE (bombx(i), bomby(i))-STEP(2, 4), crtcolour, BF IF bombtype(i) = 0 THEN bomby(i) = bomby(i) + 2 ELSE bomby(i) = bomby(i) + 3 END IF a = POINT(bombx(i), bomby(i) + 5) b = POINT(bombx(i) + 2, bomby(i) + 5) IF BombObstructed(a, b) THEN bombs(i) = false numbombs = numbombs - 1 ELSEIF bomby(i) > 194 THEN bombs(i) = false numbombs = numbombs - 1 ELSEIF a = sheltercolour OR b = sheltercolour THEN ErodeShelter bombx(i), bomby(i) + 7 bombs(i) = false numbombs = numbombs - 1 ELSEIF a = shipcolour OR b = shipcolour THEN bombs(i) = false numbombs = numbombs - 1 DisplayLives lives - 1 LINE (shipx, shipy)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF sbvoiceoff invvoice dying = true deathroes = 0 ELSE PUT (bombx(i), bomby(i)), invbombg(bombtype(i) * invbombgsize), PSET END IF END IF NEXT 'launch saucer IF NOT saucers AND NOT saucerdying THEN IF saucercycles = 25 * 70 AND invleft > 5 THEN IF RND > .5 THEN saucerx = screenorgx saucerdx = 1 ELSE saucerx = screenorgx + screenwidth - saucerwidth saucerdx = -1 END IF saucernote = &H202 saucerd = 1 saucers = true END IF END IF 'move saucer and drop bomb IF saucers THEN saucerd = saucerd - 1 IF saucerd = 0 THEN LINE (saucerx, saucery)-STEP(saucerwidth - 1, saucerheight - 1), crtcolour, BF saucerx = saucerx + saucerdx IF saucerx > screenorgx + screenwidth - saucerwidth OR saucerx < screenorgx THEN sbvoiceoff saucervoice saucers = false saucercycles = 0 ELSE PUT (saucerx, saucery), saucerg(0), PSET saucernote = saucernote - 15 IF saucernote < &H1B0 THEN saucernote = &H202 END IF sbplaynote saucervoice, 5, saucernote IF NOT dying AND NOT endinglevel AND numbombs < maxbombs AND RND * 100 > 95 THEN i = 1 WHILE bombs(i) i = i + 1 WEND bombx(i) = saucerx + saucerwidth / 2 bomby(i) = saucery + saucerheight bombs(i) = true bombtype(i) = 1 numbombs = numbombs + 1 END IF saucerd = 2 END IF END IF END IF 'explode saucer IF saucerdying THEN saucerdeathroes = saucerdeathroes - 1 IF saucerdeathroes = 0 THEN LINE (saucerx, saucery)-STEP(3 * 8, 1 * 9), crtcolour, BF sbvoiceoff saucervoice saucercycles = 0 saucerdying = false ELSE IF saucerdeathroes AND 2 THEN LINE (saucerx, saucery)-STEP(8 * 3, 7), crtcolour, BF ELSE Display saucerx - screenorgx, saucery, MID$(STR$(saucerscore), 2) END IF saucernote = saucernote + 4 IF saucernote > &H202 THEN saucernote = &H1B0 END IF sbplaynote saucervoice, 4, saucernote END IF END IF 'launch mole IF NOT moles AND NOT moledying THEN IF molecycles = moletrigger * 70 AND invleft > 3 THEN IF RND > .5 THEN molex = screenorgx + RND * 5 moledx = molexstep ELSE molex = screenorgx + screenwidth - molewidth - RND * 5 moledx = -molexstep END IF moled = 1 moleanim = 0 sbmodulate molevoice, 63 moles = true END IF END IF 'move mole and drop bomb IF moles THEN moled = moled - 1 IF moled = 0 THEN LINE (molex, moley)-STEP(molewidth - 1, moleheight - 1), crtcolour, BF molex = molex + moledx PUT (molex, moley), moleg(moleanim * molegsize), PSET molemidx = molex + molewidth \ 2 IF NOT dying AND NOT endinglevel AND numbombs < maxbombs AND RND * 100 > 75 THEN i = 1 WHILE bombs(i) i = i + 1 WEND bombx(i) = molemidx bomby(i) = moley + moleheight bombs(i) = true bombtype(i) = 0 numbombs = numbombs + 1 END IF IF moledx = 0 THEN moletrackd = moletrackd - 1 IF moletrackd = 0 THEN IF molemidx > shipx + shipwidth THEN moledx = -molexstep ELSEIF molemidx < shipx THEN moledx = molexstep ELSE moletrackd = 5 END IF END IF ELSE sbplaynote molevoice, 3, 100 IF molemidx > shipx AND molemidx < shipx + shipwidth THEN moledx = 0 moletrackd = 7 + RND * 5 END IF END IF moleanim = moleanim XOR 1 moled = 7 ELSEIF moled = 3 THEN sbvoiceoff molevoice END IF END IF 'explode mole IF moledying THEN moledeathroes = moledeathroes - 1 IF moledeathroes = 0 THEN LINE (molex, moley)-STEP(molewidth - 1, moleheight - 1), crtcolour, BF sbvoiceoff molevoice molecycles = 0 moletrigger = molebasetrigger + RND * 7 moledying = false ELSE LINE (molex, moley)-STEP(molewidth - 1, moleheight - 1), crtcolour, BF IF moledeathroes AND 4 THEN PUT (molex, moley), moleexpg(0), PSET ELSE PUT (molex, moley), moleexpg(molegsize), PSET END IF molenote = molenote + molenoted sbmodulate molevoice, 63 - moledeathroes sbplaynote molevoice, 3, molenote IF molenote = &HFC OR molenote = &H104 THEN molenoted = -molenoted END IF END IF END IF 'move player and fire bullet IF NOT dying THEN k = PEEK(&H417) LINE (shipx, shipy)-STEP(14, 7), crtcolour, BF IF (k AND 4) AND shipx > shipminx THEN shipx = shipx - 1 IF (k AND 8) AND shipx < shipmaxx THEN shipx = shipx + 1 PUT (shipx, shipy), shipg, PSET IF canfire AND (k AND 1) AND (bullets = false) AND (invzapticks = 0) THEN bulletx = shipx + 7 bullety = shipy - bulletheight bulletsound = true bulletsoundd = 10 bullets = true END IF canfire = (bullets = false) AND (invzapticks = 0) AND (k AND 1) = 0 END IF 'move bullet IF bullets THEN LINE (bulletx, bullety)-STEP(0, bulletheight), crtcolour bullety = bullety - bulletd IF bulletsound THEN bulletsoundd = bulletsoundd - 1 IF bulletsoundd = 0 THEN sbvoiceoff bulletvoice bulletsound = false ELSE sbplaynote bulletvoice, 5, RND * 255 + 256 END IF END IF IF bullety < saucery THEN bullets = false ELSE a = POINT(bulletx, bullety) b = POINT(bulletx, bullety + 2) IF (a > 0 AND a <= invaders) OR (b > 0 AND b <= invaders) THEN bulletsound = false sbvoiceoff bulletvoice IF a = 0 OR a > invaders THEN a = b invs(a) = false invleft = invleft - 1 invzapx = invx(a) - 2 invzapy = invy(a) IF invc(a) THEN LINE (Cellx(invx(a), invd(a)), invy(a))-STEP(cellwidth + 1, cellwidth + 1), crtcolour, BF IncScore 40 ELSE IncScore 20 END IF LINE (invzapx + 2, invzapy)-STEP(invwidth - 1, invheight - 1), crtcolour, BF PUT (invzapx, invzapy), invexpg(0), PSET invzapticks = invzaptime IF invleft > 11 THEN invnotelength = 12 ELSEIF invleft > 0 THEN invnotelength = VAL("&H" + MID$("6778899AABB", invleft, 1)) ELSE sbvoiceoff invvoice END IF bullets = false ELSEIF (a >= cellcolour AND a < cellcolour + invaders * 3) OR (b >= cellcolour AND b < cellcolour + invaders * 3) THEN bulletsound = false sbvoiceoff bulletvoice bullets = false ELSEIF a = sheltercolour THEN ErodeShelter bulletx, bullety bulletsound = false sbvoiceoff bulletvoice bullets = false ELSEIF a = saucercolour OR b = saucercolour THEN SELECT CASE RND * 100 CASE IS < 60 saucerscore = 100 CASE IS < 90 saucerscore = 200 CASE ELSE saucerscore = 300 END SELECT IncScore saucerscore saucers = false saucerdying = true saucerdeathroes = 120 saucernote = &H1B0 bullets = false ELSEIF a = molecolour OR b = molecolour THEN bulletsound = false sbvoiceoff bulletvoice IncScore 150 LINE (molex, moley)-STEP(molewidth - 1, moleheight - 1), crtcolour, BF moles = false moledying = true moledeathroes = 63 molenote = &H100 molenoted = 1 bullets = false ELSE LINE (bulletx, bullety)-STEP(0, bulletheight), bulletcolour END IF END IF END IF 'explode ship IF dying THEN deathroes = deathroes + 1 IF deathroes < 130 OR numbombs > 0 THEN LINE (shipx, shipy)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF PUT (shipx, shipy), shipexpg((deathroes AND 4) / 4 * shipgsize), PSET sbplaynote shipexpvoice, 1, RND * 255 + &H100 ELSE sbvoiceoff shipexpvoice sbvoiceoff saucervoice LINE (shipx, shipy)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF dying = false lives = lives - 1 IF lives = 0 THEN sbvoiceoff invvoice gameover = true ELSE shipx = screenorgx + screenwidth / 2 - shipwidth / 2 Delay 1 END IF END IF END IF 'count down exploding invader IF invzapticks THEN invzapticks = invzapticks - 1 sbplaynote invzapvoice, 6, &H280 + invzapticks * 40 IF invzapticks = 0 THEN sbvoiceoff invzapvoice LINE (invzapx, invzapy)-STEP(invexpwidth - 1, invheight - 1), crtcolour, BF IF invleft = 0 THEN endinglevel = true endingleveld = 0 END IF END IF END IF 'counting down at end of level IF endinglevel THEN endingleveld = endingleveld + 1 IF endingleveld > 200 AND numbombs = 0 AND NOT bullets AND dying = false THEN LINE (shipx, shipy)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF endinglevel = false endlevel = true END IF END IF END IF IF speedtest THEN SetColour 0, 0, 0, 0 END IF key$ = INKEY$ SELECT CASE key$ CASE CHR$(27) switchoff = true CASE "=" speedtest = NOT speedtest CASE "p", "P" pause = NOT pause END SELECT saucercycles = saucercycles + 1 molecycles = molecycles + 1 WEND '(cycle) IF gameover THEN a$ = "GAME OVER" FOR i = 1 TO LEN(a$) Display 10 * 8 + i * 8, 4 * 9, MID$(a$, i, 1) Delay .15 NEXT Delay 3 END IF IF endlevel THEN DrawPlanet true DrawCells false Delay .5 DrawShelters false Delay .5 level = level + 1 endlevel = false END IF WEND '(level) WEND '(game/attract) FOR i = 1 TO 6 sbvoiceoff i NEXT sbresetcard SYSTEM DATA " # " DATA " ### " DATA " ### " DATA " ############# " DATA "###############" DATA "###############" DATA "###############" DATA "###############" DATA " # " DATA " # # # " DATA " # # # " DATA " # # # " DATA " # ## # " DATA "# ######## " DATA " ########## " DATA " ############ " DATA " # # # " DATA " # " DATA " # # # " DATA " # # " DATA " # ## # #" DATA " ###### # " DATA " ######## " DATA " ############ " DATA " ## " DATA " #### " DATA " ###### " DATA "## ## ##" DATA "########" DATA " # # " DATA " # ## # " DATA "# # # #" DATA " ## " DATA " #### " DATA " ###### " DATA "## ## ##" DATA "########" DATA " # ## # " DATA "# #" DATA " # # " DATA " # # " DATA " # # # #" DATA " # # # " DATA "### " DATA " # ##" DATA " ## # " DATA " # # # " DATA " # # " DATA " # # " DATA " # ########## # " DATA " # ## ## ## # " DATA "###### ## ######" DATA "##################" DATA "##################" DATA "# # # # # # " DATA " # # # # # #" DATA "# #" DATA " # ########## # " DATA " # ## ## ## # " DATA "###### ## ######" DATA "##################" DATA "##################" DATA " # # # # # #" DATA "# # # # # # " DATA " # # " DATA " # # # " DATA " # # # # # " DATA " # # # # # " DATA " # # ## # #" DATA " # # ##### # ## " DATA " ####### " DATA " " DATA " # " DATA " # # " DATA " # # # " DATA " # # # # " DATA " ## # ## # ## " DATA " ## ##### ## " DATA " ####### #" DATA " " 'DATA " ########## " 'DATA " ## ## " 'DATA " # # " 'DATA "# #" 'DATA "# #" 'DATA " # # " 'DATA " ## ## " 'DATA " ########## " DATA " # " DATA " # " DATA " # " DATA "###" DATA " # " DATA " # " DATA "# " DATA " # " DATA " #" DATA " # " DATA " ###### " DATA " ########## " DATA " ############ " DATA " ## ## ## ## ## " DATA "################" DATA " ### ## ### " DATA " # # " DATA " ################ " DATA " ################## " DATA " #################### " DATA " ###################### " DATA "########################" DATA "########################" DATA "########################" DATA "########################" DATA "########################" DATA "########################" DATA "########################" DATA "########################" DATA "####### #######" DATA "###### ######" DATA "##### #####" DATA "##### #####" DATA A DATA " # " DATA " # # " DATA "# #" DATA "#####" DATA "# #" DATA "# #" DATA "# #" DATA B DATA "#### " DATA "# #" DATA "# #" DATA "#### " DATA "# #" DATA "# #" DATA "#### " DATA C DATA " ### " DATA "# #" DATA "# " DATA "# " DATA "# " DATA "# #" DATA " ### " DATA D DATA "#### " DATA "# #" DATA "# #" DATA "# #" DATA "# #" DATA "# #" DATA "#### " DATA E DATA "#####" DATA "# " DATA "# " DATA "#### " DATA "# " DATA "# " DATA "#####" DATA F DATA "#####" DATA "# " DATA "# " DATA "#### " DATA "# " DATA "# " DATA "# " DATA G DATA " ### " DATA "# #" DATA "# " DATA "# ###" DATA "# #" DATA "# #" DATA " ### " DATA H DATA "# #" DATA "# #" DATA "# #" DATA "#####" DATA "# #" DATA "# #" DATA "# #" DATA I DATA " ### " DATA " # " DATA " # " DATA " # " DATA " # " DATA " # " DATA " ### " DATA J DATA " #" DATA " #" DATA " #" DATA " #" DATA " #" DATA "# #" DATA " ### " DATA K DATA "# #" DATA "# # " DATA "# # " DATA "## " DATA "# # " DATA "# # " DATA "# #" DATA L DATA "# " DATA "# " DATA "# " DATA "# " DATA "# " DATA "# " DATA "#####" DATA M DATA "# #" DATA "## ##" DATA "# # #" DATA "# # #" DATA "# #" DATA "# #" DATA "# #" DATA N DATA "# #" DATA "# #" DATA "## #" DATA "# # #" DATA "# ##" DATA "# #" DATA "# #" DATA O DATA " ### " DATA "# #" DATA "# #" DATA "# #" DATA "# #" DATA "# #" DATA " ### " DATA P DATA "#### " DATA "# #" DATA "# #" DATA "#### " DATA "# " DATA "# " DATA "# " DATA Q DATA " ### " DATA "# #" DATA "# #" DATA "# #" DATA "# # #" DATA "# # " DATA " ## #" DATA R DATA "#### " DATA "# #" DATA "# #" DATA "#### " DATA "# # " DATA "# # " DATA "# #" DATA S DATA " ### " DATA "# #" DATA "# " DATA " ### " DATA " #" DATA "# #" DATA " ### " DATA T DATA "#####" DATA " # " DATA " # " DATA " # " DATA " # " DATA " # " DATA " # " DATA U DATA "# #" DATA "# #" DATA "# #" DATA "# #" DATA "# #" DATA "# #" DATA " ### " DATA V DATA "# #" DATA "# #" DATA "# #" DATA "# #" DATA "# #" DATA " # # " DATA " # " DATA W DATA "# #" DATA "# #" DATA "# #" DATA "# # #" DATA "# # #" DATA "## ##" DATA "# #" DATA X DATA "# #" DATA "# #" DATA " # # " DATA " # " DATA " # # " DATA "# #" DATA "# #" DATA Y DATA "# #" DATA "# #" DATA " # # " DATA " # " DATA " # " DATA " # " DATA " # " DATA Z DATA "#####" DATA " #" DATA " # " DATA " # " DATA " # " DATA "# " DATA "#####" DATA 0 DATA " ### " DATA "# #" DATA "# ##" DATA "# # #" DATA "## #" DATA "# #" DATA " ### " DATA 1 DATA " # " DATA " ## " DATA " # " DATA " # " DATA " # " DATA " # " DATA " ### " DATA 2 DATA " ### " DATA "# #" DATA " #" DATA " ### " DATA "# " DATA "# " DATA "#####" DATA 3 DATA " ### " DATA "# #" DATA " #" DATA " ## " DATA " #" DATA "# #" DATA " ### " DATA 4 DATA "# " DATA "# # " DATA "# # " DATA "#####" DATA " # " DATA " # " DATA " # " DATA 5 DATA "#####" DATA "# " DATA "#### " DATA " #" DATA " #" DATA "# #" DATA " ### " DATA 6 DATA " ### " DATA "# #" DATA "# " DATA "#### " DATA "# #" DATA "# #" DATA " ### " DATA 7 DATA "#####" DATA " #" DATA " # " DATA " # " DATA " # " DATA " # " DATA " # " DATA 8 DATA " ### " DATA "# #" DATA "# #" DATA " ### " DATA "# #" DATA "# #" DATA " ### " DATA 9 DATA " ### " DATA "# #" DATA "# #" DATA " ####" DATA " #" DATA "# #" DATA " ### " DATA ":" DATA " " DATA " " DATA " # " DATA " " DATA " " DATA " # " DATA " " DATA * FUNCTION ArrayBytes (x, y) ArrayBytes = 4 + INT(((PMAP(x, 0) - PMAP(0, 0) + 1) * 8 + 7) / 8) * (PMAP(y, 1) - PMAP(0, 1) + 1) END FUNCTION FUNCTION BombObstructed (a, b) BombObstructed = (IsAlien(a) OR IsAlien(b) OR IsCell(a) OR IsCell(b)) END FUNCTION FUNCTION Cellx (x, dir) SHARED invwidth, cellwidth SELECT CASE SGN(dir) CASE -1 Cellx = x + invwidth + 2 CASE 1 Cellx = x - 2 - cellwidth END SELECT END FUNCTION SUB ClearScreen SHARED screenwidth, screenorgx, crtcolour LINE (0, 0)-(319, 199), 0, BF LINE (screenorgx, 0)-STEP(screenwidth - 1, 199), crtcolour, BF END SUB SUB ClearScreenToCRT SHARED crtcolour LINE (0, 0)-(319, 199), crtcolour, BF END SUB SUB DefineGraphics SHARED shipwidth, shipheight, shipgsize, shipg(), shipexpg() SHARED invaders, invwidth, invheight, invgsize, invg() SHARED invexpwidth, invexpg(), invbombheight, invbombgsize, invbombg() SHARED molewidth, moleheight, molegsize, moleg(), moleexpg() SHARED saucerwidth, saucerheight, saucerg() SHARED shelterwidth, shelterheight, shelterg() SHARED chargsize, charset() SHARED shipcolour, bulletcolour, bombcolour, shipexplodecolour SHARED invexplodecolour, sheltercolour, textcolour, saucercolour SHARED crtcolour, molecolour, moleexpcolour 'define ship ClearScreenToCRT FOR y = 1 TO shipheight READ a$ FOR x = 1 TO shipwidth IF MID$(a$, x, 1) = "#" THEN PSET (x, y), shipcolour NEXT NEXT GET (1, 1)-STEP(shipwidth - 1, shipheight - 1), shipg(0) 'define ship explosion FOR i = 1 TO 2 LINE (1, 1)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF FOR y = 1 TO shipheight READ a$ FOR x = 1 TO shipwidth IF MID$(a$, x, 1) = "#" THEN PSET (x, y), shipexplodecolour NEXT NEXT GET (1, 1)-STEP(shipwidth - 1, shipheight - 1), shipexpg((i - 1) * shipgsize) NEXT 'define invaders FOR anim = 0 TO 1 LINE (1, 1)-STEP(invwidth - 1, invheight - 1), crtcolour, BF FOR y = 1 TO invheight READ a$ FOR x = 1 TO invwidth IF MID$(a$, x, 1) = "#" THEN PSET (x, y), 255 NEXT NEXT FOR inv = 0 TO invaders - 1 FOR y = 1 TO invheight FOR x = 1 TO invwidth IF POINT(x, y) <> crtcolour THEN PSET (x, y), inv + 1 NEXT NEXT GET (1, 1)-STEP(invwidth - 1, invheight - 1), invg(inv * invgsize * 2 + anim * invgsize) NEXT NEXT 'define invader explosion ClearScreenToCRT FOR y = 1 TO invheight READ a$ FOR x = 1 TO invexpwidth IF MID$(a$, x, 1) = "#" THEN PSET (x, y), invexplodecolour NEXT NEXT GET (1, 1)-STEP(invexpwidth - 1, invheight - 1), invexpg(0) 'define mole FOR anim = 0 TO 1 LINE (1, 1)-STEP(molewidth - 1, moleheight - 1), crtcolour, BF FOR y = 1 TO moleheight READ a$ FOR x = 1 TO molewidth IF MID$(a$, x, 1) = "#" THEN PSET (x, y), molecolour NEXT NEXT GET (1, 1)-STEP(molewidth - 1, moleheight - 1), moleg(anim * molegsize) NEXT 'define mole explosion FOR anim = 0 TO 1 LINE (1, 1)-STEP(molewidth - 1, moleheight - 1), crtcolour, BF FOR y = 1 TO moleheight READ a$ FOR x = 1 TO molewidth IF MID$(a$, x, 1) = "#" THEN PSET (x, y), moleexpcolour NEXT NEXT GET (1, 1)-STEP(molewidth - 1, moleheight - 1), moleexpg(anim * molegsize) NEXT 'define bombs ClearScreenToCRT FOR i = 0 TO 1 FOR y = 1 TO invbombheight READ a$ FOR x = 1 TO 3 IF MID$(a$, x, 1) = "#" THEN PSET (x, y), bombcolour NEXT NEXT GET (1, 1)-STEP(2, invbombheight - 1), invbombg(i * invbombgsize) ClearScreenToCRT NEXT 'define saucer ClearScreenToCRT FOR y = 1 TO saucerheight READ a$ FOR x = 1 TO saucerwidth IF MID$(a$, x, 1) = "#" THEN PSET (x, y), saucercolour NEXT NEXT GET (1, 1)-STEP(saucerwidth, saucerheight), saucerg(0) 'define shelter ClearScreenToCRT FOR y = 1 TO shelterheight READ a$ FOR x = 1 TO shelterwidth IF MID$(a$, x, 1) = "#" THEN PSET (x, y), sheltercolour NEXT NEXT GET (1, 1)-STEP(shelterwidth - 1, shelterheight - 1), shelterg(0) 'define character set ClearScreenToCRT READ a$ WHILE a$ <> "*" a = ASC(a$) FOR y = 1 TO 7 READ a$ FOR x = 1 TO 5 IF MID$(a$, x, 1) = "#" THEN PSET (x, y), textcolour NEXT NEXT GET (1, 1)-STEP(4, 7), charset((a) * chargsize) LINE (1, 1)-STEP(4, 7), crtcolour, BF READ a$ WEND ClearScreenToCRT END SUB SUB Delay (seconds!) SHARED true, switchoff t# = TIMER DO IF INKEY$ = CHR$(27) THEN switchoff = true END IF LOOP UNTIL TIMER > t# + seconds! OR switchoff END SUB SUB Display (x, y, a$) SHARED screenorgx, chargsize, charset(), crtcolour FOR i = 1 TO LEN(a$) LINE (screenorgx + x + (i - 1) * 8, y)-STEP(5, 7), crtcolour, BF a = ASC(MID$(a$, i)) IF a <> 32 THEN PUT (screenorgx + x + (i - 1) * 8, y), charset((a) * chargsize), PSET END IF NEXT END SUB SUB DisplayLevel SHARED level Display 19 * 8, 0, MID$(STR$(level), 2) END SUB SUB DisplayLives (lives) Display 31 * 8, 0, MID$(STR$(lives), 2) END SUB SUB DisplayScore SHARED score Display 6 * 8, 0, RIGHT$("0000" + MID$(STR$(score), 2), 5) END SUB SUB DrawCells (visible) SHARED screenorgx, screenwidth, invbasey, invaders SHARED cellwidth, cellcolour, crtcolour IF visible THEN c = cellcolour ELSE c = crtcolour END IF FOR y = 0 TO invaders \ 2 - 1 FOR x = 0 TO 2 LINE (screenorgx + screenwidth / 2 + 16 + x * 10, invbasey + y * 10 + 2)-STEP(cellwidth - 1, cellwidth - 1), c, BF IF visible THEN c = c + 1 END IF NEXT FOR x = 0 TO 2 LINE (screenorgx + screenwidth / 2 - 17 - x * 10, invbasey + y * 10 + 2)-STEP(-cellwidth + 1, cellwidth - 1), c, BF IF visible THEN c = c + 1 END IF NEXT NEXT END SUB SUB DrawPlanet (visible) SHARED screenwidth, screenorgx, planetcolour, crtcolour IF visible THEN LINE (screenorgx, 199)-STEP(screenwidth - 1, 0), planetcolour ELSE LINE (screenorgx, 199)-STEP(screenwidth - 1, 0), crtcolour END IF END SUB SUB DrawShelters (visible) SHARED screenorgx, screenwidth, crtcolour SHARED shelterwidth, sheltery, shelterheight, shelterg() FOR i = 1 TO 3 x = screenorgx + i * ((screenwidth - 3 * shelterwidth) / 4) + (i - 1) * shelterwidth IF visible THEN PUT (x, sheltery), shelterg(0), PSET ELSE LINE (x, sheltery)-STEP(shelterwidth - 1, shelterheight - 1), crtcolour, BF END IF NEXT END SUB SUB ErodeShelter (x, y) SHARED damagex(), damagey(), damagecounter, crtcolour FOR i = 1 TO 35 PSET (x + damagex(damagecounter + i) - 2, y + damagey(damagecounter + i + 1) - 4), crtcolour NEXT damagecounter = damagecounter + 20 IF damagecounter > 255 - i THEN damagecounter = 0 END IF END SUB SUB IncScore (scoregain) SHARED true, score, lives a$ = "02 05 10" score = score + scoregain FOR i = 1 TO 3 a = VAL(MID$(a$, (i - 1) * 3 + 1, 2)) * 1000 IF score >= a AND score < a + scoregain THEN lives = lives + 1 DisplayLives lives END IF NEXT DisplayScore END SUB FUNCTION IsAlien (pixel) SHARED invaders, molecolour IsAlien = (pixel > 0 AND pixel <= invaders) OR pixel = molecolour END FUNCTION FUNCTION IsCell (pixel) SHARED invaders, cellcolour IsCell = (pixel >= cellcolour AND pixel < cellcolour + invaders * 3) END FUNCTION SUB sbmodulate (voice, volume) sbwritereg &H40 + sbvoicetoreg(voice), &H3F - volume END SUB SUB sbplaynote (voice, octave, note) sbwritereg &HA0 - 1 + voice, note AND 255 sbwritereg &HB0 - 1 + voice, &H20 OR (octave * 4) OR ((note AND &H300) / 256) END SUB SUB sbresetcard FOR i = 1 TO &HF5 sbwritereg i, 0 NEXT END SUB SUB sbsetupvoice (voice) 'Sets up one voice. 'Modulator volume = silent 'Modulator attack = fastest 'Modulator decay = slowest 'Modulator sustain = medium 'Modulator release = medium 'Tone volume = loudest 'Tone attack = fastest 'Tone decay = slowest 'Tone sustain = medium 'Tone release = medium sbwritereg &H20 + sbvoicetoreg(voice), &H1 sbwritereg &H40 + sbvoicetoreg(voice), &H3F sbwritereg &H60 + sbvoicetoreg(voice), &HF0 sbwritereg &H80 + sbvoicetoreg(voice), &H77 sbwritereg &H23 + sbvoicetoreg(voice), &H1 sbwritereg &H43 + sbvoicetoreg(voice), &H0 sbwritereg &H63 + sbvoicetoreg(voice), &HF0 sbwritereg &H83 + sbvoicetoreg(voice), &H77 END SUB SUB sbvoiceoff (voice) sbwritereg &HB0 - 1 + voice, 0 END SUB FUNCTION sbvoicetoreg (voice) IF voice <= 3 THEN offset = -1 ELSEIF voice <= 6 THEN offset = 4 ELSE offset = 9 END IF sbvoicetoreg = voice + offset END FUNCTION SUB sbvolume (voice, volume) sbwritereg &H43 + sbvoicetoreg(voice), &H3F - volume END SUB SUB sbwritereg (register, byte) OUT &H388, register FOR i = 1 TO 6 a = INP(&H388) NEXT OUT &H389, byte FOR i = 1 TO 35 a = INP(&H388) NEXT END SUB SUB SetColour (colour, r, g, b) OUT &H3C6, &HFF OUT &H3C8, colour OUT &H3C9, r OUT &H3C9, g OUT &H3C9, b END SUB SUB WaitRetrace 'NOTE!!!!!!!! IT SHOULD BE 8,8 THEN 8 (14/1/97) WAIT &H3DA, 8 WAIT &H3DA, 8, 8 END SUB