home *** CD-ROM | disk | FTP | other *** search
/ Over 1,000 Games for Windows / Over1000GamesForWindows.iso / ARCADE / SInv78 / inv78-02.bas next >
Encoding:
BASIC Source File  |  2000-12-12  |  30.2 KB  |  1,321 lines

  1. '
  2. '                      Taito Space Invaders
  3. '
  4. '                               ██
  5. '                              ████
  6. '                             ██████
  7. '                            ██ ██ ██
  8. '                            ████████
  9. '                              █  █
  10. '                             █ ██ █
  11. '                            █ █  █ █
  12. '
  13. '                         PC Version 02
  14. '
  15. '                  James Eibisch - December 2000
  16.  
  17. DEFINT A-Z
  18.  
  19. DECLARE FUNCTION ArrayBytes (x, y)
  20. DECLARE SUB DefineGraphics ()
  21. DECLARE SUB SetColour (colour, r, g, b)
  22. DECLARE SUB Display (x, y, a$)
  23. DECLARE SUB DisplayLife (life, visible)
  24. DECLARE SUB DisplayScore ()
  25. DECLARE SUB DrawPlanet (visible)
  26. DECLARE SUB DrawShelters (visible)
  27. DECLARE SUB Delay (seconds!)
  28. DECLARE SUB ClearScreen ()
  29. DECLARE SUB ClearScreenToCRT ()
  30. DECLARE SUB IncScore (scoregain)
  31. DECLARE SUB ErodeShelter (x, y)
  32.  
  33. DECLARE FUNCTION sbvoicetoreg (voice)
  34. DECLARE SUB sbwritereg (register, byte)
  35. DECLARE SUB sbresetcard ()
  36. DECLARE SUB sbsetupvoice (voice)
  37. DECLARE SUB sbvoiceoff (voice)
  38. DECLARE SUB sbplaynote (voice, octave, note)
  39. DECLARE SUB sbvolume (voice, volume)
  40. DECLARE SUB sbmodulate (voice, volume)
  41.  
  42. DEF SEG = 0
  43. RANDOMIZE TIMER
  44. SCREEN 13
  45.  
  46. true = -1
  47. false = NOT true
  48.  
  49. screenwidth = 256
  50. screenorgx = 32
  51. shipwidth = 15
  52. shipheight = 8
  53. shipminx = 50
  54. shipmaxx = 270 - shipwidth
  55. bulletheight = 3
  56. bulletd = 3
  57. invwidth = 12
  58. invheight = 8
  59. invbombheight = 5
  60. invdiry = 7
  61. invzaptime = 15
  62. saucerwidth = 16
  63. saucerheight = 7
  64. saucery = 28
  65. sheltery = 156
  66. shelterwidth = 24
  67. shelterheight = 16
  68.  
  69. shipcolour = 255
  70. bulletcolour = 254
  71. bombcolour = 253
  72. shipexplodecolour = 252
  73. sheltercolour = 251
  74. textcolour = 250
  75. invexplodewhitecolour = 249
  76. invexplodegreencolour = 248
  77. planetcolour = 247
  78. saucercolour = 246
  79. crtcolour = 245
  80.  
  81. SetColour shipcolour, 0, 63, 0
  82. SetColour bulletcolour, 63, 63, 63
  83. SetColour bombcolour, 63, 63, 63
  84. SetColour shipexplodecolour, 0, 63, 0
  85. SetColour sheltercolour, 0, 63, 0
  86. SetColour textcolour, 63, 63, 63
  87. SetColour invexplodewhitecolour, 63, 63, 63
  88. SetColour invexplodegreencolour, 0, 63, 0
  89. SetColour planetcolour, 0, 63, 0
  90. SetColour saucercolour, 63, 0, 0
  91. SetColour crtcolour, 14, 14, 14
  92.  
  93. shipgsize = ArrayBytes(shipwidth - 4, shipheight - 4)
  94. DIM shipg(shipgsize)
  95. DIM shipexpg(2 * shipgsize)
  96. invgsize = ArrayBytes(invwidth - 3, invheight - 3)
  97. DIM invg(4 * 55 * invgsize)
  98. DIM invg2(4 * 55 * invgsize)
  99. invbombgsize = ArrayBytes(1, 3)
  100. DIM invbombg(2 * invbombgsize)
  101. DIM invexpg(3 * invgsize)
  102. DIM saucerg(ArrayBytes(saucerwidth - 3, saucerheight - 3))
  103. DIM shelterg(ArrayBytes(shelterwidth - 6, shelterheight - 6))
  104. chargsize = ArrayBytes(2, 5)
  105. DIM charset(chargsize * 39)
  106.  
  107. DIM damagex(255), damagey(255)
  108. FOR i = 0 TO 255
  109.   damagex(i) = RND * 4
  110.   damagey(i) = RND * 6
  111. NEXT
  112.  
  113. invvoice = 1
  114. bulletvoice = 2
  115. invzapvoice = 3
  116. saucervoice = 4
  117. shipexpvoice = 5
  118.  
  119. DIM invnote(3)
  120. FOR i = 0 TO 3
  121.   READ invnote(i)
  122. NEXT
  123. DATA &H2AE,&H287,&H263,&H241
  124. sbresetcard
  125. FOR i = 1 TO 5
  126.   sbsetupvoice i
  127. NEXT
  128. sbmodulate invvoice, 40
  129. sbmodulate bulletvoice, 45
  130. sbvolume bulletvoice, 45
  131. sbmodulate invzapvoice, 20
  132. sbvolume invzapvoice, 53
  133. sbvolume saucervoice, 55
  134. sbmodulate shipexpvoice, 63
  135.  
  136. DefineGraphics
  137. DIM invx(55), invy(55), invs(55)
  138. DIM bombx(20), bomby(20), bombs(20), bombtype(20)
  139.  
  140. speedtest = false
  141. score = 0
  142.  
  143. WHILE NOT switchoff
  144.   ClearScreen
  145.   WHILE INKEY$ > ""
  146.   WEND
  147.   Display 0, 0, "SCORE"
  148.   DisplayScore
  149.   a$ = ""
  150.   WHILE a$ = ""
  151.     WAIT &H3DA, 8
  152.     WAIT &H3DA, 8, 8
  153.     Display 11 * 8, 10 * 9, "GAME OVER"
  154.     FOR i = 1 TO 2
  155.       WAIT &H3DA, 8
  156.       WAIT &H3DA, 8, 8
  157.     NEXT
  158.     Display 11 * 8, 10 * 9, "         "
  159.     a$ = INKEY$
  160.     switchoff = (a$ = CHR$(27))
  161.   WEND
  162.  
  163.   '------------------ Next Game ---------------
  164.  
  165.   IF NOT switchoff THEN
  166.     score = 0
  167.     lives = 3
  168.     level = 1
  169.     damagecounter = RND * 200
  170.     maxbombs = 12
  171.     bombchance = 95
  172.     gameover = false
  173.     ClearScreen
  174.     Display 0, 0, "SCORE"
  175.     DisplayScore
  176.     Display 16 * 8, 0, "LIVES"
  177.     FOR i = 1 TO lives
  178.       DisplayLife i, true
  179.     NEXT
  180.   END IF
  181.  
  182.   '------------------ Next Level --------------
  183.  
  184.   WHILE NOT gameover AND NOT switchoff
  185.     DrawPlanet true
  186.     IF level < 5 THEN
  187.       DrawShelters true
  188.     END IF
  189.     maxbombs = maxbombs - (maxbombs < 20)
  190.     bombchance = bombchance + (bombchance > 80)
  191.     shipx = shipminx
  192.     shipy = 199 - shipheight * 2
  193.     canfire = false
  194.     saucers = false
  195.     inv = 1
  196.     FOR y = 0 TO 4
  197.       FOR x = 0 TO 10
  198.         invx(inv) = shipminx + shipwidth + x * 16
  199.         invy(inv) = shipy - 2 - invheight - (6 - level) * 14 - y * 14
  200.         invs(inv) = true
  201.         inv = inv + 1
  202.       NEXT
  203.     NEXT
  204.     invleft = 55
  205.     inv = 0
  206.     invanim = 0
  207.     invnote = 0
  208.     invnotelength = 12
  209.     invnoted = 1
  210.     invnotes = true
  211.     invdirx = 2
  212.     changedir = 0
  213.     numbombs = 0
  214.     FOR i = 1 TO maxbombs
  215.       bombs(i) = false
  216.     NEXT
  217.     endinglevel = false
  218.     Delay .6
  219.     saucercycles = 0
  220.     shots = 0
  221.     saucercount = 0
  222.  
  223.     '------------------ Next Cycle --------------
  224.  
  225.     WHILE NOT endlevel AND NOT gameover AND NOT switchoff
  226.       WAIT &H3DA, 8
  227.       WAIT &H3DA, 8, 8
  228.       IF speedtest THEN
  229.         SetColour 0, 32, 16, 16
  230.       END IF
  231.  
  232.       'move invaders
  233.  
  234.       IF (NOT dying) AND (NOT endinglevel) AND (invzapticks = 0) THEN
  235.         inv = inv + 1
  236.         oldinvanim = invanim
  237.         IF inv = 56 THEN
  238.           inv = 1
  239.           invanim = invanim XOR 1
  240.           SELECT CASE changedir
  241.             CASE 1
  242.             changedir = 2
  243.             CASE 2
  244.             invdirx = -invdirx
  245.             changedir = 0
  246.           END SELECT
  247.         END IF
  248.         WHILE invs(inv) = false
  249.           inv = inv + 1
  250.           IF inv = 56 THEN
  251.             inv = 1
  252.             invanim = invanim XOR 1
  253.             SELECT CASE changedir
  254.               CASE 1
  255.               changedir = 2
  256.               CASE 2
  257.               invdirx = -invdirx
  258.               changedir = 0
  259.             END SELECT
  260.           END IF
  261.         WEND
  262.         LINE (invx(inv), invy(inv))-STEP(invwidth - 1, invheight - 1), crtcolour, BF
  263.         IF changedir = 2 THEN
  264.           invy(inv) = invy(inv) + invdiry
  265.           IF invy(inv) > shipy - invheight THEN
  266.             lives = 1
  267.             LINE (shipx, shipy)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF
  268.             dying = true
  269.             deathroes = 0
  270.           END IF
  271.           ELSE
  272.           invx(inv) = invx(inv) + invdirx
  273.           IF invx(inv) <= shipminx - invwidth OR invx(inv) >= shipmaxx + shipwidth THEN
  274.             changedir = 1
  275.           END IF
  276.         END IF
  277.         IF invy(inv) < sheltery - invheight THEN
  278.           PUT (invx(inv), invy(inv)), invg((inv - 1) * invgsize * 4 + invanim * 2 * invgsize), PSET
  279.           ELSEIF invy(inv) < sheltery THEN
  280.           PUT (invx(inv), invy(inv)), invg((inv - 1) * invgsize * 4 + invanim * 2 * invgsize + invgsize), PSET
  281.           ELSE
  282.           PUT (invx(inv), invy(inv)), invg2((inv - 1) * invgsize * 4 + invanim * 2 * invgsize), PSET
  283.         END IF
  284.       END IF
  285.  
  286.       'invader move sound
  287.  
  288.       invnoted = invnoted - 1
  289.       IF invnoted = 0 THEN
  290.         IF invnotes THEN
  291.           IF invleft > 11 THEN
  292.             sbvoiceoff invvoice
  293.           END IF
  294.           invnoted = invleft - invnotelength
  295.           IF invnoted < 1 THEN
  296.             invnoted = 1
  297.           END IF
  298.           ELSE
  299.           IF invleft > 0 AND NOT dying AND NOT endinglevel THEN
  300.             sbplaynote invvoice, 1, invnote(invnote)
  301.             invnote = (invnote + 1) AND 3
  302.           END IF
  303.           invnoted = invnotelength
  304.         END IF
  305.         invnotes = NOT invnotes
  306.       END IF
  307.  
  308.       'drop bomb
  309.  
  310.       IF NOT dying AND NOT endinglevel THEN
  311.         IF numbombs < maxbombs AND RND * 100 > bombchance THEN
  312.           obstructed = false
  313.           FOR i = inv - 11 TO 1 STEP -11
  314.             IF invs(i) THEN
  315.               obstructed = true
  316.               i = 1
  317.             END IF
  318.           NEXT
  319.           IF NOT obstructed THEN
  320.             i = 1
  321.             WHILE bombs(i)
  322.               i = i + 1
  323.             WEND
  324.             bombx(i) = invx(inv) + 5
  325.             bomby(i) = invy(inv) + 8
  326.             bombs(i) = true
  327.             IF RND * 100 > 85 THEN
  328.               bombtype(i) = 1
  329.               ELSE
  330.               bombtype(i) = 0
  331.             END IF
  332.             numbombs = numbombs + 1
  333.           END IF
  334.         END IF
  335.       END IF
  336.  
  337.       'move bombs
  338.  
  339.       FOR i = 1 TO maxbombs
  340.         IF bombs(i) THEN
  341.           LINE (bombx(i), bomby(i))-STEP(2, 4), crtcolour, BF
  342.           IF bombtype(i) = 0 THEN
  343.             bomby(i) = bomby(i) + 1
  344.             ELSE
  345.             bomby(i) = bomby(i) + 2
  346.           END IF
  347.           a = POINT(bombx(i), bomby(i) + 5)
  348.           b = POINT(bombx(i) + 2, bomby(i) + 5)
  349.           IF bomby(i) > 194 THEN
  350.             bombs(i) = false
  351.             numbombs = numbombs - 1
  352.             ELSEIF a = sheltercolour OR b = sheltercolour THEN
  353.             ErodeShelter bombx(i), bomby(i) + 7
  354.             bombs(i) = false
  355.             numbombs = numbombs - 1
  356.             ELSEIF a = shipcolour OR b = shipcolour THEN
  357.             bombs(i) = false
  358.             numbombs = numbombs - 1
  359.             DisplayLife lives, false
  360.             LINE (shipx, shipy)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF
  361.             sbvoiceoff invvoice
  362.             dying = true
  363.             deathroes = 0
  364.             ELSE
  365.             PUT (bombx(i), bomby(i)), invbombg(bombtype(i) * invbombgsize), PSET
  366.           END IF
  367.         END IF
  368.       NEXT
  369.  
  370.       'launch saucer
  371.  
  372.       IF NOT saucers AND NOT saucerdying THEN
  373.         IF saucercycles = 25 * 70 AND invleft > 9 THEN
  374.           IF RND > .5 THEN
  375.             saucerx = screenorgx
  376.             saucerdx = 1
  377.             ELSE
  378.             saucerx = screenorgx + screenwidth - saucerwidth
  379.             saucerdx = -1
  380.           END IF
  381.           saucernote = &H202
  382.           saucerd = 1
  383.           saucers = true
  384.           saucercount = saucercount + 1
  385.         END IF
  386.       END IF
  387.  
  388.       'move saucer
  389.  
  390.       IF saucers THEN
  391.         saucerd = saucerd - 1
  392.         IF saucerd = 0 THEN
  393.           LINE (saucerx, saucery)-STEP(saucerwidth - 1, saucerheight - 1), crtcolour, BF
  394.           saucerx = saucerx + saucerdx
  395.           IF saucerx > screenorgx + screenwidth - saucerwidth OR saucerx < screenorgx THEN
  396.             sbvoiceoff saucervoice
  397.             saucers = false
  398.             saucercycles = 0
  399.             ELSE
  400.             PUT (saucerx, saucery), saucerg(0), PSET
  401.             saucernote = saucernote - 15
  402.             IF saucernote < &H1B0 THEN
  403.               saucernote = &H202
  404.             END IF
  405.             sbplaynote saucervoice, 5, saucernote
  406.             saucerd = 2
  407.           END IF
  408.         END IF
  409.       END IF
  410.  
  411.       'explode saucer
  412.  
  413.       IF saucerdying THEN
  414.         saucerdeathroes = saucerdeathroes - 1
  415.         IF saucerdeathroes = 0 THEN
  416.           LINE (saucerx, saucery)-STEP(3 * 8, 1 * 9), crtcolour, BF
  417.           sbvoiceoff saucervoice
  418.           saucercycles = 0
  419.           saucerdying = false
  420.           ELSE
  421.           saucernote = saucernote + 4
  422.           IF saucernote > &H202 THEN
  423.             saucernote = &H1B0
  424.           END IF
  425.           sbplaynote saucervoice, 4, saucernote
  426.         END IF
  427.       END IF
  428.  
  429.       'move player and fire bullet
  430.  
  431.       IF NOT dying THEN
  432.         k = PEEK(&H417)
  433.         LINE (shipx, shipy)-STEP(14, 7), crtcolour, BF
  434.         IF (k AND 4) AND shipx > shipminx THEN shipx = shipx - 1
  435.         IF (k AND 8) AND shipx < shipmaxx THEN shipx = shipx + 1
  436.         PUT (shipx, shipy), shipg, PSET
  437.         IF canfire AND (k AND 1) AND (bullets = false) AND (invzapticks = 0) THEN
  438.           bulletx = shipx + 7
  439.           bullety = shipy - bulletheight
  440.           bulletsound = true
  441.           bulletsoundd = 10
  442.           bullets = true
  443.           shots = shots + 1
  444.         END IF
  445.         canfire = (bullets = false) AND (invzapticks = 0) AND (k AND 1) = 0
  446.       END IF
  447.  
  448.       'move bullet
  449.  
  450.       IF bullets THEN
  451.         LINE (bulletx, bullety)-STEP(0, bulletheight), crtcolour
  452.         bullety = bullety - bulletd
  453.         IF bulletsound THEN
  454.           bulletsoundd = bulletsoundd - 1
  455.           IF bulletsoundd = 0 THEN
  456.             sbvoiceoff bulletvoice
  457.             bulletsound = false
  458.             ELSE
  459.             sbplaynote bulletvoice, 5, RND * 255 + 256
  460.           END IF
  461.         END IF
  462.         IF bullety < saucery THEN
  463.           bullets = false
  464.           ELSE
  465.           a = POINT(bulletx, bullety)
  466.           b = POINT(bulletx, bullety + 2)
  467.           IF (a > 0 AND a < 111) OR (b > 0 AND b < 111) THEN
  468.             bulletsound = false
  469.             sbvoiceoff bulletvoice
  470.             IF a = crtcolour THEN a = b
  471.             a = (a - 1) \ 2 + 1
  472.             invs(a) = false
  473.             invleft = invleft - 1
  474.             invzapx = invx(a)
  475.             invzapy = invy(a)
  476.             LINE (invzapx, invzapy)-STEP(invwidth - 1, invheight - 1), crtcolour, BF
  477.             IF invzapy < sheltery - invheight THEN
  478.               PUT (invzapx, invzapy), invexpg(0), PSET
  479.               ELSEIF invzapy < sheltery THEN
  480.               PUT (invzapx, invzapy), invexpg(invgsize), PSET
  481.               ELSE
  482.               PUT (invzapx, invzapy), invexpg(2 * invgsize), PSET
  483.             END IF
  484.             invzapticks = invzaptime
  485.             IF invleft > 11 THEN
  486.               invnotelength = 12
  487.               ELSEIF invleft > 0 THEN
  488.               invnotelength = VAL("&H" + MID$("6778899AABB", invleft, 1))
  489.               ELSE
  490.               sbvoiceoff invvoice
  491.             END IF
  492.             SELECT CASE a
  493.               CASE 1 TO 22
  494.               IncScore 10
  495.               CASE 23 TO 44
  496.               IncScore 20
  497.               CASE ELSE
  498.               IncScore 30
  499.             END SELECT
  500.             bullets = false
  501.             ELSEIF a = sheltercolour THEN
  502.             ErodeShelter bulletx, bullety
  503.             bulletsound = false
  504.             sbvoiceoff bulletvoice
  505.             bullets = false
  506.             ELSEIF a = saucercolour OR b = saucercolour THEN
  507.             LINE (saucerx, saucery)-STEP(saucerwidth - 1, saucerheight - 1), crtcolour, BF
  508.             IF (shots = 23 AND saucercount = 1) OR (shots = 15 AND saucercount >= 2) THEN
  509.               saucerscore = 300
  510.               ELSE
  511.               saucerscore = INT(RND * 3 + 1) * 50
  512.             END IF
  513.             Display saucerx - screenorgx, saucery, MID$(STR$(saucerscore), 2)
  514.             IncScore saucerscore
  515.             saucers = false
  516.             saucerdying = true
  517.             saucerdeathroes = 120
  518.             saucernote = &H1B0
  519.             bullets = false
  520.             shots = 0
  521.             ELSE
  522.             LINE (bulletx, bullety)-STEP(0, bulletheight), bulletcolour
  523.           END IF
  524.         END IF
  525.       END IF
  526.  
  527.       'explode ship
  528.  
  529.       IF dying THEN
  530.         deathroes = deathroes + 1
  531.         IF deathroes < 130 OR numbombs > 0 THEN
  532.           LINE (shipx, shipy)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF
  533.           PUT (shipx, shipy), shipexpg((deathroes AND 4) / 4 * shipgsize), PSET
  534.           sbplaynote shipexpvoice, 1, RND * 255 + &H100
  535.           ELSE
  536.           sbvoiceoff shipexpvoice
  537.           sbvoiceoff saucervoice
  538.           LINE (shipx, shipy)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF
  539.           dying = false
  540.           lives = lives - 1
  541.           IF lives = 0 THEN
  542.             sbvoiceoff invvoice
  543.             gameover = true
  544.             ELSE
  545.             shipx = shipminx
  546.             shipy = 199 - shipheight * 2
  547.             Delay 1
  548.           END IF
  549.         END IF
  550.       END IF
  551.  
  552.       'count down exploding invader
  553.  
  554.       IF invzapticks THEN
  555.         invzapticks = invzapticks - 1
  556.         sbplaynote invzapvoice, 6, &H280 + invzapticks * 40
  557.         IF invzapticks = 0 THEN
  558.           sbvoiceoff invzapvoice
  559.           LINE (invzapx, invzapy)-STEP(invwidth - 1, invheight - 1), crtcolour, BF
  560.           IF invleft = 0 THEN
  561.             endinglevel = true
  562.             endingleveld = 0
  563.           END IF
  564.         END IF
  565.       END IF
  566.  
  567.       'counting down at end of level
  568.  
  569.       IF endinglevel THEN
  570.         endingleveld = endingleveld + 1
  571.         IF endingleveld > 200 AND numbombs = 0 AND NOT bullets AND dying = false THEN
  572.           LINE (shipx, shipy)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF
  573.           endinglevel = false
  574.           endlevel = true
  575.         END IF
  576.       END IF
  577.  
  578.       IF speedtest THEN
  579.         SetColour 0, 0, 0, 0
  580.       END IF
  581.  
  582.       key$ = INKEY$
  583.       switchoff = (key$ = CHR$(27))
  584.       IF key$ = "=" THEN
  585.         speedtest = NOT speedtest
  586.       END IF
  587.       saucercycles = saucercycles + 1
  588.  
  589.     WEND '(cycle)
  590.  
  591.     IF gameover THEN
  592.       a$ = "GAME OVER"
  593.       FOR i = 1 TO LEN(a$)
  594.         Display 10 * 8 + i * 8, 4 * 9, MID$(a$, i, 1)
  595.         Delay .15
  596.       NEXT
  597.       Delay 3
  598.     END IF
  599.  
  600.     IF endlevel THEN
  601.       DrawPlanet true
  602.       DrawShelters false
  603.       Delay .9
  604.       level = level + 1
  605.       IF level > 6 THEN
  606.         level = 6
  607.       END IF
  608.       endlevel = false
  609.     END IF
  610.  
  611.   WEND '(level)
  612.  
  613. WEND '(game/attract)
  614.  
  615. FOR i = 1 TO 5
  616.   sbvoiceoff i
  617. NEXT
  618. sbresetcard
  619.  
  620. SYSTEM
  621.  
  622.  
  623. DATA "       #       "
  624. DATA "      ###      "
  625. DATA "      ###      "
  626. DATA " ############# "
  627. DATA "###############"
  628. DATA "###############"
  629. DATA "###############"
  630. DATA "###############"
  631.  
  632. DATA "    #          "
  633. DATA "  #     #    # "
  634. DATA "    #  #  #    "
  635. DATA "  #      # #   "
  636. DATA "     # ##   #  "
  637. DATA "#  ########    "
  638. DATA "  ##########   "
  639. DATA " ############  "
  640.  
  641. DATA " #     #    #  "
  642. DATA "    #          "
  643. DATA "  #    #    #  "
  644. DATA "      #   #    "
  645. DATA " #   ## #     #"
  646. DATA "    ######  #  "
  647. DATA "   ########    "
  648. DATA " ############  "
  649.  
  650. DATA "    ####    "
  651. DATA " ########## "
  652. DATA "############"
  653. DATA "###  ##  ###"
  654. DATA "############"
  655. DATA "   ##  ##   "
  656. DATA "  ## ## ##  "
  657. DATA "##        ##"
  658.  
  659. DATA "    ####    "
  660. DATA " ########## "
  661. DATA "############"
  662. DATA "###  ##  ###"
  663. DATA "############"
  664. DATA "  ###  ###  "
  665. DATA " ##  ##  ## "
  666. DATA "  ##    ##  "
  667.  
  668. DATA "  #     #   "
  669. DATA "#  #   #  # "
  670. DATA "# ####### # "
  671. DATA "### ### ### "
  672. DATA "########### "
  673. DATA " #########  "
  674. DATA "  #     #   "
  675. DATA " #       #  "
  676.  
  677. DATA "  #     #   "
  678. DATA "   #   #    "
  679. DATA "  #######   "
  680. DATA " ## ### ##  "
  681. DATA "########### "
  682. DATA "# ####### # "
  683. DATA "# #     # # "
  684. DATA "   ## ##    "
  685.  
  686. DATA "     ##     "
  687. DATA "    ####    "
  688. DATA "   ######   "
  689. DATA "  ## ## ##  "
  690. DATA "  ########  "
  691. DATA "    #  #    "
  692. DATA "   # ## #   "
  693. DATA "  # #  # #  "
  694.  
  695. DATA "     ##     "
  696. DATA "    ####    "
  697. DATA "   ######   "
  698. DATA "  ## ## ##  "
  699. DATA "  ########  "
  700. DATA "   # ## #   "
  701. DATA "  #      #  "
  702. DATA "   #    #   "
  703.  
  704. DATA "     #  #   "
  705. DATA "  #  #  #  #"
  706. DATA "   #   #  # "
  707. DATA "###         "
  708. DATA "    #     ##"
  709. DATA "  ##    #   "
  710. DATA " #    #  #  "
  711. DATA "      #   # "
  712.  
  713. DATA " # "
  714. DATA " # "
  715. DATA " # "
  716. DATA "###"
  717. DATA " # "
  718.  
  719. DATA " # "
  720. DATA "#  "
  721. DATA " # "
  722. DATA "  #"
  723. DATA " # "
  724.  
  725. DATA "     ######     "
  726. DATA "   ##########   "
  727. DATA "  ############  "
  728. DATA " ## ## ## ## ## "
  729. DATA "################"
  730. DATA "  ###  ##  ###  "
  731. DATA "   #        #   "
  732.  
  733.  
  734. DATA "    ################    "
  735. DATA "   ##################   "
  736. DATA "  ####################  "
  737. DATA " ###################### "
  738. DATA "########################"
  739. DATA "########################"
  740. DATA "########################"
  741. DATA "########################"
  742. DATA "########################"
  743. DATA "########################"
  744. DATA "########################"
  745. DATA "########################"
  746. DATA "#######          #######"
  747. DATA "######            ######"
  748. DATA "#####              #####"
  749. DATA "#####              #####"
  750.  
  751. DATA A
  752. DATA "  #  "
  753. DATA " # # "
  754. DATA "#   #"
  755. DATA "#####"
  756. DATA "#   #"
  757. DATA "#   #"
  758. DATA "#   #"
  759.  
  760. DATA C
  761. DATA " ### "
  762. DATA "#   #"
  763. DATA "#    "
  764. DATA "#    "
  765. DATA "#    "
  766. DATA "#   #"
  767. DATA " ### "
  768.  
  769. DATA E
  770. DATA "#####"
  771. DATA "#    "
  772. DATA "#    "
  773. DATA "#### "
  774. DATA "#    "
  775. DATA "#    "
  776. DATA "#####"
  777.  
  778. DATA G
  779. DATA " ### "
  780. DATA "#   #"
  781. DATA "#    "
  782. DATA "# ###"
  783. DATA "#   #"
  784. DATA "#   #"
  785. DATA " ### "
  786.  
  787. DATA I
  788. DATA " ### "
  789. DATA "  #  "
  790. DATA "  #  "
  791. DATA "  #  "
  792. DATA "  #  "
  793. DATA "  #  "
  794. DATA " ### "
  795.  
  796. DATA L
  797. DATA "#    "
  798. DATA "#    "
  799. DATA "#    "
  800. DATA "#    "
  801. DATA "#    "
  802. DATA "#    "
  803. DATA "#####"
  804.  
  805. DATA M
  806. DATA "#   #"
  807. DATA "## ##"
  808. DATA "# # #"
  809. DATA "# # #"
  810. DATA "#   #"
  811. DATA "#   #"
  812. DATA "#   #"
  813.  
  814. DATA O
  815. DATA " ### "
  816. DATA "#   #"
  817. DATA "#   #"
  818. DATA "#   #"
  819. DATA "#   #"
  820. DATA "#   #"
  821. DATA " ### "
  822.  
  823. DATA R
  824. DATA "#### "
  825. DATA "#   #"
  826. DATA "#   #"
  827. DATA "#### "
  828. DATA "# #  "
  829. DATA "#  # "
  830. DATA "#   #"
  831.  
  832. DATA S
  833. DATA " ### "
  834. DATA "#   #"
  835. DATA "#    "
  836. DATA " ### "
  837. DATA "    #"
  838. DATA "#   #"
  839. DATA " ### "
  840.  
  841. DATA V
  842. DATA "#   #"
  843. DATA "#   #"
  844. DATA "#   #"
  845. DATA "#   #"
  846. DATA "#   #"
  847. DATA " # # "
  848. DATA "  #  "
  849.  
  850. DATA 0
  851. DATA " ### "
  852. DATA "#   #"
  853. DATA "#  ##"
  854. DATA "# # #"
  855. DATA "##  #"
  856. DATA "#   #"
  857. DATA " ### "
  858.  
  859. DATA 1
  860. DATA "  #  "
  861. DATA " ##  "
  862. DATA "  #  "
  863. DATA "  #  "
  864. DATA "  #  "
  865. DATA "  #  "
  866. DATA " ### "
  867.  
  868. DATA 2
  869. DATA " ### "
  870. DATA "#   #"
  871. DATA "    #"
  872. DATA " ### "
  873. DATA "#    "
  874. DATA "#    "
  875. DATA "#####"
  876.  
  877. DATA 3
  878. DATA " ### "
  879. DATA "#   #"
  880. DATA "    #"
  881. DATA "  ## "
  882. DATA "    #"
  883. DATA "#   #"
  884. DATA " ### "
  885.  
  886. DATA 4
  887. DATA "#    "
  888. DATA "#    "
  889. DATA "#  # "
  890. DATA "#####"
  891. DATA "   # "
  892. DATA "   # "
  893. DATA "   # "
  894.  
  895. DATA 5
  896. DATA "#####"
  897. DATA "#    "
  898. DATA "#### "
  899. DATA "    #"
  900. DATA "    #"
  901. DATA "#   #"
  902. DATA " ### "
  903.  
  904. DATA 6
  905. DATA " ### "
  906. DATA "#   #"
  907. DATA "#    "
  908. DATA "#### "
  909. DATA "#   #"
  910. DATA "#   #"
  911. DATA " ### "
  912.  
  913. DATA 7
  914. DATA "#####"
  915. DATA "    #"
  916. DATA "   # "
  917. DATA "  #  "
  918. DATA " #   "
  919. DATA " #   "
  920. DATA " #   "
  921.  
  922. DATA 8
  923. DATA " ### "
  924. DATA "#   #"
  925. DATA "#   #"
  926. DATA " ### "
  927. DATA "#   #"
  928. DATA "#   #"
  929. DATA " ### "
  930.  
  931. DATA 9
  932. DATA " ### "
  933. DATA "#   #"
  934. DATA "#   #"
  935. DATA " ####"
  936. DATA "    #"
  937. DATA "#   #"
  938. DATA " ### "
  939.  
  940. FUNCTION ArrayBytes (x, y)
  941.  
  942. ArrayBytes = 4 + INT(((PMAP(x, 0) - PMAP(0, 0) + 1) * 8 + 7) / 8) * (PMAP(y, 1) - PMAP(0, 1) + 1)
  943.  
  944. END FUNCTION
  945.  
  946. SUB ClearScreen
  947.  
  948. SHARED screenwidth, screenorgx, crtcolour
  949.  
  950. LINE (0, 0)-(319, 199), 0, BF
  951. LINE (screenorgx, 0)-STEP(screenwidth, 199), crtcolour, BF
  952.  
  953. END SUB
  954.  
  955. SUB ClearScreenToCRT
  956.  
  957. SHARED crtcolour
  958.  
  959. LINE (0, 0)-(319, 199), crtcolour, BF
  960.  
  961. END SUB
  962.  
  963. SUB DefineGraphics
  964.  
  965. SHARED shipwidth, shipheight, shipgsize, shipg(), shipexpg()
  966. SHARED invwidth, invheight, invgsize, invg(), invg2()
  967. SHARED invexpg(), invbombheight, invbombgsize, invbombg()
  968. SHARED saucerwidth, saucerheight, saucerg()
  969. SHARED shelterwidth, shelterheight, shelterg()
  970. SHARED chargsize, charset()
  971.  
  972. SHARED shipcolour, bulletcolour, bombcolour, shipexplodecolour
  973. SHARED sheltercolour, textcolour, invexplodewhitecolour
  974. SHARED invexplodegreencolour, saucercolour, crtcolour
  975.  
  976. 'define ship
  977.  
  978. ClearScreenToCRT
  979. FOR y = 1 TO shipheight
  980.   READ a$
  981.   FOR x = 1 TO shipwidth
  982.     IF MID$(a$, x, 1) = "#" THEN PSET (x, y), shipcolour
  983.   NEXT
  984. NEXT
  985. GET (1, 1)-STEP(shipwidth - 1, shipheight - 1), shipg(0)
  986.  
  987. 'define ship explosion
  988.  
  989. FOR i = 1 TO 2
  990.   LINE (1, 1)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF
  991.   FOR y = 1 TO shipheight
  992.     READ a$
  993.     FOR x = 1 TO shipwidth
  994.       IF MID$(a$, x, 1) = "#" THEN PSET (x, y), shipexplodecolour
  995.     NEXT
  996.   NEXT
  997.   GET (1, 1)-STEP(shipwidth - 1, shipheight - 1), shipexpg((i - 1) * shipgsize)
  998. NEXT
  999.  
  1000. 'define invaders
  1001.  
  1002. ClearScreenToCRT
  1003. FOR invtype = 0 TO 2
  1004.   FOR anim = 0 TO 1
  1005.     LINE (1, 1)-STEP(invwidth - 1, invheight - 1), crtcolour, BF
  1006.     FOR y = 1 TO invheight
  1007.       READ a$
  1008.       FOR x = 1 TO invwidth
  1009.         IF MID$(a$, x, 1) = "#" THEN PSET (x, y), 255
  1010.       NEXT
  1011.     NEXT
  1012.     IF invtype = 2 THEN rows = 1 ELSE rows = 2
  1013.     FOR inv = invtype * 22 TO invtype * 22 + rows * 11 - 1
  1014.       arraypointer = inv * invgsize * 4 + anim * invgsize * 2
  1015.       invcolour = inv * 2 + 1
  1016.       SetColour invcolour, 63, 63, 63
  1017.       SetColour invcolour + 1, 0, 63, 0
  1018.       FOR y = 1 TO invheight
  1019.         FOR x = 1 TO invwidth
  1020.           IF POINT(x, y) <> crtcolour THEN PSET (x, y), invcolour
  1021.         NEXT
  1022.       NEXT
  1023.       GET (1, 1)-STEP(invwidth - 1, invheight - 1), invg(arraypointer)
  1024.       FOR y = 5 TO invheight
  1025.         FOR x = 1 TO invwidth
  1026.           IF POINT(x, y) <> crtcolour THEN PSET (x, y), invcolour + 1
  1027.         NEXT
  1028.       NEXT
  1029.       GET (1, 1)-STEP(invwidth - 1, invheight - 1), invg(arraypointer + invgsize)
  1030.       FOR y = 1 TO 4
  1031.         FOR x = 1 TO invwidth
  1032.           IF POINT(x, y) <> crtcolour THEN PSET (x, y), invcolour + 1
  1033.         NEXT
  1034.       NEXT
  1035.       GET (1, 1)-STEP(invwidth - 1, invheight - 1), invg2(arraypointer)
  1036.     NEXT
  1037.   NEXT
  1038. NEXT
  1039.  
  1040. 'define invader explosion
  1041.  
  1042. ClearScreenToCRT
  1043. FOR y = 1 TO invheight
  1044.   READ a$
  1045.   FOR x = 1 TO invwidth
  1046.     IF MID$(a$, x, 1) = "#" THEN PSET (x, y), invexplodewhitecolour
  1047.   NEXT
  1048. NEXT
  1049. GET (1, 1)-STEP(invwidth - 1, invheight - 1), invexpg(0)
  1050. FOR y = 5 TO invheight
  1051.   FOR x = 1 TO invwidth
  1052.     IF POINT(x, y) <> crtcolour THEN PSET (x, y), invexplodegreencolour
  1053.   NEXT
  1054. NEXT
  1055. GET (1, 1)-STEP(invwidth - 1, invheight - 1), invexpg(invgsize)
  1056. FOR y = 1 TO 4
  1057.   FOR x = 1 TO invwidth
  1058.     IF POINT(x, y) <> crtcolour THEN PSET (x, y), invexplodegreencolour
  1059.   NEXT
  1060. NEXT
  1061. GET (1, 1)-STEP(invwidth - 1, invheight - 1), invexpg(2 * invgsize)
  1062.  
  1063. 'define bombs
  1064.  
  1065. ClearScreenToCRT
  1066. FOR i = 1 TO 2
  1067.   FOR y = 1 TO invbombheight
  1068.     READ a$
  1069.     FOR x = 1 TO 3
  1070.       IF MID$(a$, x, 1) = "#" THEN PSET (x, y), bombcolour
  1071.     NEXT
  1072.   NEXT
  1073.   GET (1, 1)-STEP(2, invbombheight - 1), invbombg((i - 1) * invbombgsize)
  1074.   ClearScreenToCRT
  1075. NEXT
  1076.  
  1077. 'define saucer
  1078.  
  1079. ClearScreenToCRT
  1080. FOR y = 1 TO saucerheight
  1081.   READ a$
  1082.   FOR x = 1 TO saucerwidth
  1083.     IF MID$(a$, x, 1) = "#" THEN PSET (x, y), saucercolour
  1084.   NEXT
  1085. NEXT
  1086. GET (1, 1)-STEP(saucerwidth, saucerheight), saucerg(0)
  1087.  
  1088. 'define shelter
  1089.  
  1090. ClearScreenToCRT
  1091. FOR y = 1 TO shelterheight
  1092.   READ a$
  1093.   FOR x = 1 TO shelterwidth
  1094.     IF MID$(a$, x, 1) = "#" THEN PSET (x, y), sheltercolour
  1095.   NEXT
  1096. NEXT
  1097. GET (1, 1)-STEP(shelterwidth - 1, shelterheight - 1), shelterg(0)
  1098.  
  1099. 'define character set
  1100.  
  1101. ClearScreenToCRT
  1102. FOR i = 1 TO 21
  1103.   READ a$
  1104.   a = ASC(a$)
  1105.   FOR y = 1 TO 7
  1106.     READ a$
  1107.     FOR x = 1 TO 5
  1108.       IF MID$(a$, x, 1) = "#" THEN PSET (x, y), textcolour
  1109.     NEXT
  1110.   NEXT
  1111.   GET (1, 1)-STEP(4, 7), charset((a - 48) * chargsize)
  1112.   LINE (1, 1)-STEP(4, 7), crtcolour, BF
  1113. NEXT
  1114.  
  1115. ClearScreenToCRT
  1116.  
  1117. END SUB
  1118.  
  1119. SUB Delay (seconds!)
  1120.  
  1121. SHARED true, switchoff
  1122.  
  1123. t# = TIMER
  1124. DO
  1125.   IF INKEY$ = CHR$(27) THEN
  1126.     switchoff = true
  1127.   END IF
  1128. LOOP UNTIL TIMER > t# + seconds! OR switchoff
  1129.  
  1130. END SUB
  1131.  
  1132. SUB Display (x, y, a$)
  1133.  
  1134. SHARED screenorgx, chargsize, charset(), crtcolour
  1135.  
  1136. FOR i = 1 TO LEN(a$)
  1137.   LINE (screenorgx + x + (i - 1) * 8, y)-STEP(5, 7), crtcolour, BF
  1138.   a = ASC(MID$(a$, i))
  1139.   IF a <> 32 THEN
  1140.     PUT (screenorgx + x + (i - 1) * 8, y), charset((a - 48) * chargsize), PSET
  1141.   END IF
  1142. NEXT
  1143.  
  1144. END SUB
  1145.  
  1146. SUB DisplayLife (life, visible)
  1147.  
  1148. SHARED screenorgx, shipwidth, shipheight, shipg(), crtcolour
  1149.  
  1150. IF visible THEN
  1151.   PUT (screenorgx + 16 * 8 + (life - 1) * shipwidth * 1.5, 1.5 * 8), shipg(0), PSET
  1152.   ELSE
  1153.   LINE (screenorgx + 16 * 8 + (life - 1) * shipwidth * 1.5, 1.5 * 8)-STEP(shipwidth, shipheight), crtcolour, BF
  1154. END IF
  1155.  
  1156. END SUB
  1157.  
  1158. SUB DisplayScore
  1159.  
  1160. SHARED score
  1161.  
  1162. Display 0, 1 * 9, RIGHT$("000" + MID$(STR$(score), 2), 4)
  1163.  
  1164. END SUB
  1165.  
  1166. SUB DrawPlanet (visible)
  1167.  
  1168. SHARED screenwidth, screenorgx, planetcolour, crtcolour
  1169.  
  1170. IF visible THEN
  1171.   LINE (screenorgx, 199)-STEP(screenwidth - 1, 0), planetcolour
  1172.   ELSE
  1173.   LINE (screenorgx, 199)-STEP(screenwidth - 1, 0), crtcolour
  1174. END IF
  1175.  
  1176. END SUB
  1177.  
  1178. SUB DrawShelters (visible)
  1179.  
  1180. SHARED shipwidth, sheltery, shelterwidth, shelterheight, shelterg()
  1181. SHARED shipminx, shipmaxx, crtcolour
  1182.  
  1183. shelterspace = (shipmaxx + shipwidth - shipwidth * .9) - (shipminx + shipwidth * .9)
  1184. xstep = (shelterspace - 4 * shelterwidth) / 3 + shelterwidth
  1185.  
  1186. FOR i = 0 TO 3
  1187.   x = shipminx + shipwidth * .9 + i * xstep
  1188.   IF visible THEN
  1189.     PUT (x, sheltery), shelterg(0), PSET
  1190.     ELSE
  1191.     LINE (x, sheltery)-STEP(shelterwidth - 1, shelterheight - 1), crtcolour, BF
  1192.   END IF
  1193. NEXT
  1194.  
  1195. END SUB
  1196.  
  1197. SUB ErodeShelter (x, y)
  1198.  
  1199. SHARED damagex(), damagey(), damagecounter, crtcolour
  1200.  
  1201. FOR i = 1 TO 35
  1202.   PSET (x + damagex(damagecounter + i) - 2, y + damagey(damagecounter + i + 1) - 4), crtcolour
  1203. NEXT
  1204. damagecounter = damagecounter + 20
  1205. IF damagecounter > 255 - i THEN
  1206.   damagecounter = 0
  1207. END IF
  1208.  
  1209. END SUB
  1210.  
  1211. SUB IncScore (scoregain)
  1212.  
  1213. SHARED true, score, lives
  1214.  
  1215. score = score + scoregain
  1216. IF score >= 1000 AND score < 1000 + scoregain THEN
  1217.   lives = lives + 1
  1218.   DisplayLife lives, true
  1219. END IF
  1220.  
  1221. DisplayScore
  1222.  
  1223. END SUB
  1224.  
  1225. SUB sbmodulate (voice, volume)
  1226.  
  1227. sbwritereg &H40 + sbvoicetoreg(voice), &H3F - volume
  1228.  
  1229. END SUB
  1230.  
  1231. SUB sbplaynote (voice, octave, note)
  1232.  
  1233. sbwritereg &HA0 - 1 + voice, note AND 255
  1234. sbwritereg &HB0 - 1 + voice, &H20 OR (octave * 4) OR ((note AND &H300) / 256)
  1235.  
  1236. END SUB
  1237.  
  1238. SUB sbresetcard
  1239.  
  1240. FOR i = 1 TO &HF5
  1241.   sbwritereg i, 0
  1242. NEXT
  1243.  
  1244. END SUB
  1245.  
  1246. SUB sbsetupvoice (voice)
  1247.  
  1248. 'Sets up one voice.
  1249.  
  1250. 'Modulator volume  = silent
  1251. 'Modulator attack  = fastest
  1252. 'Modulator decay   = slowest
  1253. 'Modulator sustain = medium
  1254. 'Modulator release = medium
  1255. 'Tone volume       = loudest
  1256. 'Tone attack       = fastest
  1257. 'Tone decay        = slowest
  1258. 'Tone sustain      = medium
  1259. 'Tone release      = medium
  1260.  
  1261. sbwritereg &H20 + sbvoicetoreg(voice), &H1
  1262. sbwritereg &H40 + sbvoicetoreg(voice), &H3F
  1263. sbwritereg &H60 + sbvoicetoreg(voice), &HF0
  1264. sbwritereg &H80 + sbvoicetoreg(voice), &H77
  1265. sbwritereg &H23 + sbvoicetoreg(voice), &H1
  1266. sbwritereg &H43 + sbvoicetoreg(voice), &H0
  1267. sbwritereg &H63 + sbvoicetoreg(voice), &HF0
  1268. sbwritereg &H83 + sbvoicetoreg(voice), &H77
  1269.  
  1270. END SUB
  1271.  
  1272. SUB sbvoiceoff (voice)
  1273.  
  1274. sbwritereg &HB0 - 1 + voice, 0
  1275.  
  1276. END SUB
  1277.  
  1278. FUNCTION sbvoicetoreg (voice)
  1279.  
  1280. IF voice <= 3 THEN
  1281.   offset = -1
  1282.   ELSEIF voice <= 6 THEN
  1283.   offset = 4
  1284.   ELSE
  1285.   offset = 9
  1286. END IF
  1287.  
  1288. sbvoicetoreg = voice + offset
  1289.  
  1290. END FUNCTION
  1291.  
  1292. SUB sbvolume (voice, volume)
  1293.  
  1294. sbwritereg &H43 + sbvoicetoreg(voice), &H3F - volume
  1295.  
  1296. END SUB
  1297.  
  1298. SUB sbwritereg (register, byte)
  1299.  
  1300. OUT &H388, register
  1301. FOR i = 1 TO 6
  1302.   a = INP(&H388)
  1303. NEXT
  1304. OUT &H389, byte
  1305. FOR i = 1 TO 35
  1306.   a = INP(&H388)
  1307. NEXT
  1308.  
  1309. END SUB
  1310.  
  1311. SUB SetColour (colour, r, g, b)
  1312.  
  1313. OUT &H3C6, &HFF
  1314. OUT &H3C8, colour
  1315. OUT &H3C9, r
  1316. OUT &H3C9, g
  1317. OUT &H3C9, b
  1318.  
  1319. END SUB
  1320.  
  1321.