mirror of
https://github.com/QB64-Phoenix-Edition/QB64pe.git
synced 2024-09-01 16:20:17 +00:00
1316 lines
30 KiB
QBasic
1316 lines
30 KiB
QBasic
' Taito Space Invaders
|
|
' ÛÛÛ
|
|
' ÛÛÛÛÛÛÛ
|
|
' ÛÛÛÛÛÛÛÛÛÛÛ
|
|
' Û ÛÛÛ Û
|
|
' ÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
|
|
' ÛÛ ÛÛ
|
|
' ÛÛ ÛÛ ÛÛ ÛÛ
|
|
' ÛÛ ÛÛ ÛÛ ÛÛ
|
|
' v1
|
|
' anarky - anarky.tk, 2005
|
|
|
|
DEFINT A-Z
|
|
|
|
DECLARE FUNCTION ArrayBytes (x, y)
|
|
DECLARE SUB DefineGraphics ()
|
|
DECLARE SUB SetColour (colour, r, g, b)
|
|
DECLARE SUB Display (x, y, a$)
|
|
DECLARE SUB DisplayLife (life, visible)
|
|
DECLARE SUB DisplayScore ()
|
|
DECLARE SUB DrawPlanet (visible)
|
|
DECLARE SUB DrawShelters (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
|
|
|
|
screenwidth = 256
|
|
screenorgx = 32
|
|
shipwidth = 15
|
|
shipheight = 8
|
|
shipminx = 50
|
|
shipmaxx = 270 - shipwidth
|
|
bulletheight = 3
|
|
bulletd = 3
|
|
invwidth = 12
|
|
invheight = 8
|
|
invbombheight = 5
|
|
invdiry = 7
|
|
invzaptime = 15
|
|
saucerwidth = 16
|
|
saucerheight = 7
|
|
saucery = 28
|
|
sheltery = 156
|
|
shelterwidth = 24
|
|
shelterheight = 16
|
|
|
|
shipcolour = 255
|
|
bulletcolour = 254
|
|
bombcolour = 253
|
|
shipexplodecolour = 252
|
|
sheltercolour = 251
|
|
textcolour = 250
|
|
invexplodewhitecolour = 249
|
|
invexplodegreencolour = 248
|
|
planetcolour = 247
|
|
saucercolour = 246
|
|
crtcolour = 245
|
|
|
|
SetColour shipcolour, 0, 63, 0
|
|
SetColour bulletcolour, 63, 63, 63
|
|
SetColour bombcolour, 63, 63, 63
|
|
SetColour shipexplodecolour, 0, 63, 0
|
|
SetColour sheltercolour, 0, 63, 0
|
|
SetColour textcolour, 63, 63, 63
|
|
SetColour invexplodewhitecolour, 63, 63, 63
|
|
SetColour invexplodegreencolour, 0, 63, 0
|
|
SetColour planetcolour, 0, 63, 0
|
|
SetColour saucercolour, 63, 0, 0
|
|
SetColour crtcolour, 14, 14, 14
|
|
|
|
shipgsize = ArrayBytes(shipwidth - 4, shipheight - 4)
|
|
DIM shipg(shipgsize)
|
|
DIM shipexpg(2 * shipgsize)
|
|
invgsize = ArrayBytes(invwidth - 3, invheight - 3)
|
|
DIM invg(4 * 55 * invgsize)
|
|
DIM invg2(4 * 55 * invgsize)
|
|
invbombgsize = ArrayBytes(1, 3)
|
|
DIM invbombg(2 * invbombgsize)
|
|
DIM invexpg(3 * invgsize)
|
|
DIM saucerg(ArrayBytes(saucerwidth - 3, saucerheight - 3))
|
|
DIM shelterg(ArrayBytes(shelterwidth - 6, shelterheight - 6))
|
|
chargsize = ArrayBytes(2, 5)
|
|
DIM charset(chargsize * 39)
|
|
|
|
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
|
|
|
|
DIM invnote(3)
|
|
FOR i = 0 TO 3
|
|
READ invnote(i)
|
|
NEXT
|
|
DATA &H2AE,&H287,&H263,&H241
|
|
sbresetcard
|
|
FOR i = 1 TO 5
|
|
sbsetupvoice i
|
|
NEXT
|
|
sbmodulate invvoice, 40
|
|
sbmodulate bulletvoice, 45
|
|
sbvolume bulletvoice, 45
|
|
sbmodulate invzapvoice, 20
|
|
sbvolume invzapvoice, 53
|
|
sbvolume saucervoice, 55
|
|
sbmodulate shipexpvoice, 63
|
|
|
|
DefineGraphics
|
|
DIM invx(55), invy(55), invs(55)
|
|
DIM bombx(20), bomby(20), bombs(20), bombtype(20)
|
|
|
|
speedtest = false
|
|
score = 0
|
|
|
|
WHILE NOT switchoff
|
|
ClearScreen
|
|
WHILE INKEY$ > ""
|
|
WEND
|
|
Display 0, 0, "SCORE"
|
|
DisplayScore
|
|
a$ = ""
|
|
WHILE a$ = ""
|
|
WAIT &H3DA, 8
|
|
WAIT &H3DA, 8, 8
|
|
Display 11 * 8, 10 * 9, "GAME OVER"
|
|
FOR i = 1 TO 2
|
|
WAIT &H3DA, 8
|
|
WAIT &H3DA, 8, 8
|
|
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
|
|
maxbombs = 12
|
|
bombchance = 95
|
|
gameover = false
|
|
ClearScreen
|
|
Display 0, 0, "SCORE"
|
|
DisplayScore
|
|
Display 16 * 8, 0, "LIVES"
|
|
FOR i = 1 TO lives
|
|
DisplayLife i, true
|
|
NEXT
|
|
END IF
|
|
|
|
'------------------ Next Level --------------
|
|
|
|
WHILE NOT gameover AND NOT switchoff
|
|
DrawPlanet true
|
|
IF level < 5 THEN
|
|
DrawShelters true
|
|
END IF
|
|
maxbombs = maxbombs - (maxbombs < 20)
|
|
bombchance = bombchance + (bombchance > 80)
|
|
shipx = shipminx
|
|
shipy = 199 - shipheight * 2
|
|
canfire = false
|
|
saucers = false
|
|
inv = 1
|
|
FOR y = 0 TO 4
|
|
FOR x = 0 TO 10
|
|
invx(inv) = shipminx + shipwidth + x * 16
|
|
invy(inv) = shipy - 2 - invheight - (6 - level) * 14 - y * 14
|
|
invs(inv) = true
|
|
inv = inv + 1
|
|
NEXT
|
|
NEXT
|
|
invleft = 55
|
|
inv = 0
|
|
invanim = 0
|
|
invnote = 0
|
|
invnotelength = 12
|
|
invnoted = 1
|
|
invnotes = true
|
|
invdirx = 2
|
|
changedir = 0
|
|
numbombs = 0
|
|
FOR i = 1 TO maxbombs
|
|
bombs(i) = false
|
|
NEXT
|
|
endinglevel = false
|
|
Delay .6
|
|
saucercycles = 0
|
|
shots = 0
|
|
saucercount = 0
|
|
|
|
'------------------ Next Cycle --------------
|
|
|
|
WHILE NOT endlevel AND NOT gameover AND NOT switchoff
|
|
WAIT &H3DA, 8
|
|
WAIT &H3DA, 8, 8
|
|
IF speedtest THEN
|
|
SetColour 0, 32, 16, 16
|
|
END IF
|
|
|
|
'move invaders
|
|
|
|
IF (NOT dying) AND (NOT endinglevel) AND (invzapticks = 0) THEN
|
|
inv = inv + 1
|
|
oldinvanim = invanim
|
|
IF inv = 56 THEN
|
|
inv = 1
|
|
invanim = invanim XOR 1
|
|
SELECT CASE changedir
|
|
CASE 1
|
|
changedir = 2
|
|
CASE 2
|
|
invdirx = -invdirx
|
|
changedir = 0
|
|
END SELECT
|
|
END IF
|
|
WHILE invs(inv) = false
|
|
inv = inv + 1
|
|
IF inv = 56 THEN
|
|
inv = 1
|
|
invanim = invanim XOR 1
|
|
SELECT CASE changedir
|
|
CASE 1
|
|
changedir = 2
|
|
CASE 2
|
|
invdirx = -invdirx
|
|
changedir = 0
|
|
END SELECT
|
|
END IF
|
|
WEND
|
|
LINE (invx(inv), invy(inv))-STEP(invwidth - 1, invheight - 1), crtcolour, BF
|
|
IF changedir = 2 THEN
|
|
invy(inv) = invy(inv) + invdiry
|
|
IF invy(inv) > shipy - invheight THEN
|
|
lives = 1
|
|
LINE (shipx, shipy)-STEP(shipwidth - 1, shipheight - 1), crtcolour, BF
|
|
dying = true
|
|
deathroes = 0
|
|
END IF
|
|
ELSE
|
|
invx(inv) = invx(inv) + invdirx
|
|
IF invx(inv) <= shipminx - invwidth OR invx(inv) >= shipmaxx + shipwidth THEN
|
|
changedir = 1
|
|
END IF
|
|
END IF
|
|
IF invy(inv) < sheltery - invheight THEN
|
|
PUT (invx(inv), invy(inv)), invg((inv - 1) * invgsize * 4 + invanim * 2 * invgsize), PSET
|
|
ELSEIF invy(inv) < sheltery THEN
|
|
PUT (invx(inv), invy(inv)), invg((inv - 1) * invgsize * 4 + invanim * 2 * invgsize + invgsize), PSET
|
|
ELSE
|
|
PUT (invx(inv), invy(inv)), invg2((inv - 1) * invgsize * 4 + invanim * 2 * invgsize), PSET
|
|
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 THEN
|
|
IF numbombs < maxbombs AND RND * 100 > bombchance THEN
|
|
obstructed = false
|
|
FOR i = inv - 11 TO 1 STEP -11
|
|
IF invs(i) THEN
|
|
obstructed = true
|
|
i = 1
|
|
END IF
|
|
NEXT
|
|
IF NOT obstructed THEN
|
|
i = 1
|
|
WHILE bombs(i)
|
|
i = i + 1
|
|
WEND
|
|
bombx(i) = invx(inv) + 5
|
|
bomby(i) = invy(inv) + 8
|
|
bombs(i) = true
|
|
IF RND * 100 > 85 THEN
|
|
bombtype(i) = 1
|
|
ELSE
|
|
bombtype(i) = 0
|
|
END IF
|
|
numbombs = numbombs + 1
|
|
END IF
|
|
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) + 1
|
|
ELSE
|
|
bomby(i) = bomby(i) + 2
|
|
END IF
|
|
a = POINT(bombx(i), bomby(i) + 5)
|
|
b = POINT(bombx(i) + 2, bomby(i) + 5)
|
|
IF 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
|
|
DisplayLife lives, false
|
|
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 > 9 THEN
|
|
IF RND > .5 THEN
|
|
saucerx = screenorgx
|
|
saucerdx = 1
|
|
ELSE
|
|
saucerx = screenorgx + screenwidth - saucerwidth
|
|
saucerdx = -1
|
|
END IF
|
|
saucernote = &H202
|
|
saucerd = 1
|
|
saucers = true
|
|
saucercount = saucercount + 1
|
|
END IF
|
|
END IF
|
|
|
|
'move saucer
|
|
|
|
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
|
|
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
|
|
saucernote = saucernote + 4
|
|
IF saucernote > &H202 THEN
|
|
saucernote = &H1B0
|
|
END IF
|
|
sbplaynote saucervoice, 4, saucernote
|
|
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
|
|
shots = shots + 1
|
|
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 < 111) OR (b > 0 AND b < 111) THEN
|
|
bulletsound = false
|
|
sbvoiceoff bulletvoice
|
|
IF a = crtcolour THEN a = b
|
|
a = (a - 1) \ 2 + 1
|
|
invs(a) = false
|
|
invleft = invleft - 1
|
|
invzapx = invx(a)
|
|
invzapy = invy(a)
|
|
LINE (invzapx, invzapy)-STEP(invwidth - 1, invheight - 1), crtcolour, BF
|
|
IF invzapy < sheltery - invheight THEN
|
|
PUT (invzapx, invzapy), invexpg(0), PSET
|
|
ELSEIF invzapy < sheltery THEN
|
|
PUT (invzapx, invzapy), invexpg(invgsize), PSET
|
|
ELSE
|
|
PUT (invzapx, invzapy), invexpg(2 * invgsize), PSET
|
|
END IF
|
|
invzapticks = invzaptime
|
|
IF invleft > 11 THEN
|
|
invnotelength = 12
|
|
ELSEIF invleft > 0 THEN
|
|
invnotelength = VAL("&H" + MID$("6778899AABB", invleft, 1))
|
|
ELSE
|
|
sbvoiceoff invvoice
|
|
END IF
|
|
SELECT CASE a
|
|
CASE 1 TO 22
|
|
IncScore 10
|
|
CASE 23 TO 44
|
|
IncScore 20
|
|
CASE ELSE
|
|
IncScore 30
|
|
END SELECT
|
|
bullets = false
|
|
ELSEIF a = sheltercolour THEN
|
|
ErodeShelter bulletx, bullety
|
|
bulletsound = false
|
|
sbvoiceoff bulletvoice
|
|
bullets = false
|
|
ELSEIF a = saucercolour OR b = saucercolour THEN
|
|
LINE (saucerx, saucery)-STEP(saucerwidth - 1, saucerheight - 1), crtcolour, BF
|
|
IF (shots = 23 AND saucercount = 1) OR (shots = 15 AND saucercount >= 2) THEN
|
|
saucerscore = 300
|
|
ELSE
|
|
saucerscore = INT(RND * 3 + 1) * 50
|
|
END IF
|
|
Display saucerx - screenorgx, saucery, MID$(STR$(saucerscore), 2)
|
|
IncScore saucerscore
|
|
saucers = false
|
|
saucerdying = true
|
|
saucerdeathroes = 120
|
|
saucernote = &H1B0
|
|
bullets = false
|
|
shots = 0
|
|
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 = shipminx
|
|
shipy = 199 - shipheight * 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(invwidth - 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
|
|
|
|
IF speedtest THEN
|
|
SetColour 0, 0, 0, 0
|
|
END IF
|
|
|
|
key$ = INKEY$
|
|
switchoff = (key$ = CHR$(27))
|
|
IF key$ = "=" THEN
|
|
speedtest = NOT speedtest
|
|
END IF
|
|
saucercycles = saucercycles + 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
|
|
DrawShelters false
|
|
Delay .9
|
|
level = level + 1
|
|
IF level > 6 THEN
|
|
level = 6
|
|
END IF
|
|
endlevel = false
|
|
END IF
|
|
|
|
WEND '(level)
|
|
|
|
WEND '(game/attract)
|
|
|
|
FOR i = 1 TO 5
|
|
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 A
|
|
DATA " # "
|
|
DATA " # # "
|
|
DATA "# #"
|
|
DATA "#####"
|
|
DATA "# #"
|
|
DATA "# #"
|
|
DATA "# #"
|
|
|
|
DATA C
|
|
DATA " ### "
|
|
DATA "# #"
|
|
DATA "# "
|
|
DATA "# "
|
|
DATA "# "
|
|
DATA "# #"
|
|
DATA " ### "
|
|
|
|
DATA E
|
|
DATA "#####"
|
|
DATA "# "
|
|
DATA "# "
|
|
DATA "#### "
|
|
DATA "# "
|
|
DATA "# "
|
|
DATA "#####"
|
|
|
|
DATA G
|
|
DATA " ### "
|
|
DATA "# #"
|
|
DATA "# "
|
|
DATA "# ###"
|
|
DATA "# #"
|
|
DATA "# #"
|
|
DATA " ### "
|
|
|
|
DATA I
|
|
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 O
|
|
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 V
|
|
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 " ### "
|
|
|
|
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
|
|
|
|
SUB ClearScreen
|
|
|
|
SHARED screenwidth, screenorgx, crtcolour
|
|
|
|
LINE (0, 0)-(319, 199), 0, BF
|
|
LINE (screenorgx, 0)-STEP(screenwidth, 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 invwidth, invheight, invgsize, invg(), invg2()
|
|
SHARED invexpg(), invbombheight, invbombgsize, invbombg()
|
|
SHARED saucerwidth, saucerheight, saucerg()
|
|
SHARED shelterwidth, shelterheight, shelterg()
|
|
SHARED chargsize, charset()
|
|
|
|
SHARED shipcolour, bulletcolour, bombcolour, shipexplodecolour
|
|
SHARED sheltercolour, textcolour, invexplodewhitecolour
|
|
SHARED invexplodegreencolour, saucercolour, crtcolour
|
|
|
|
'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
|
|
|
|
ClearScreenToCRT
|
|
FOR invtype = 0 TO 2
|
|
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
|
|
IF invtype = 2 THEN rows = 1 ELSE rows = 2
|
|
FOR inv = invtype * 22 TO invtype * 22 + rows * 11 - 1
|
|
arraypointer = inv * invgsize * 4 + anim * invgsize * 2
|
|
invcolour = inv * 2 + 1
|
|
SetColour invcolour, 63, 63, 63
|
|
SetColour invcolour + 1, 0, 63, 0
|
|
FOR y = 1 TO invheight
|
|
FOR x = 1 TO invwidth
|
|
IF POINT(x, y) <> crtcolour THEN PSET (x, y), invcolour
|
|
NEXT
|
|
NEXT
|
|
GET (1, 1)-STEP(invwidth - 1, invheight - 1), invg(arraypointer)
|
|
FOR y = 5 TO invheight
|
|
FOR x = 1 TO invwidth
|
|
IF POINT(x, y) <> crtcolour THEN PSET (x, y), invcolour + 1
|
|
NEXT
|
|
NEXT
|
|
GET (1, 1)-STEP(invwidth - 1, invheight - 1), invg(arraypointer + invgsize)
|
|
FOR y = 1 TO 4
|
|
FOR x = 1 TO invwidth
|
|
IF POINT(x, y) <> crtcolour THEN PSET (x, y), invcolour + 1
|
|
NEXT
|
|
NEXT
|
|
GET (1, 1)-STEP(invwidth - 1, invheight - 1), invg2(arraypointer)
|
|
NEXT
|
|
NEXT
|
|
NEXT
|
|
|
|
'define invader explosion
|
|
|
|
ClearScreenToCRT
|
|
FOR y = 1 TO invheight
|
|
READ a$
|
|
FOR x = 1 TO invwidth
|
|
IF MID$(a$, x, 1) = "#" THEN PSET (x, y), invexplodewhitecolour
|
|
NEXT
|
|
NEXT
|
|
GET (1, 1)-STEP(invwidth - 1, invheight - 1), invexpg(0)
|
|
FOR y = 5 TO invheight
|
|
FOR x = 1 TO invwidth
|
|
IF POINT(x, y) <> crtcolour THEN PSET (x, y), invexplodegreencolour
|
|
NEXT
|
|
NEXT
|
|
GET (1, 1)-STEP(invwidth - 1, invheight - 1), invexpg(invgsize)
|
|
FOR y = 1 TO 4
|
|
FOR x = 1 TO invwidth
|
|
IF POINT(x, y) <> crtcolour THEN PSET (x, y), invexplodegreencolour
|
|
NEXT
|
|
NEXT
|
|
GET (1, 1)-STEP(invwidth - 1, invheight - 1), invexpg(2 * invgsize)
|
|
|
|
'define bombs
|
|
|
|
ClearScreenToCRT
|
|
FOR i = 1 TO 2
|
|
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 - 1) * 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
|
|
FOR i = 1 TO 21
|
|
READ 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 - 48) * chargsize)
|
|
LINE (1, 1)-STEP(4, 7), crtcolour, BF
|
|
NEXT
|
|
|
|
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 - 48) * chargsize), PSET
|
|
END IF
|
|
NEXT
|
|
|
|
END SUB
|
|
|
|
SUB DisplayLife (life, visible)
|
|
|
|
SHARED screenorgx, shipwidth, shipheight, shipg(), crtcolour
|
|
|
|
IF visible THEN
|
|
PUT (screenorgx + 16 * 8 + (life - 1) * shipwidth * 1.5, 1.5 * 8), shipg(0), PSET
|
|
ELSE
|
|
LINE (screenorgx + 16 * 8 + (life - 1) * shipwidth * 1.5, 1.5 * 8)-STEP(shipwidth, shipheight), crtcolour, BF
|
|
END IF
|
|
|
|
END SUB
|
|
|
|
SUB DisplayScore
|
|
|
|
SHARED score
|
|
|
|
Display 0, 1 * 9, RIGHT$("000" + MID$(STR$(score), 2), 4)
|
|
|
|
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 shipwidth, sheltery, shelterwidth, shelterheight, shelterg()
|
|
SHARED shipminx, shipmaxx, crtcolour
|
|
|
|
shelterspace = (shipmaxx + shipwidth - shipwidth * .9) - (shipminx + shipwidth * .9)
|
|
xstep = (shelterspace - 4 * shelterwidth) / 3 + shelterwidth
|
|
|
|
FOR i = 0 TO 3
|
|
x = shipminx + shipwidth * .9 + i * xstep
|
|
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
|
|
|
|
score = score + scoregain
|
|
IF score >= 1000 AND score < 1000 + scoregain THEN
|
|
lives = lives + 1
|
|
DisplayLife lives, true
|
|
END IF
|
|
|
|
DisplayScore
|
|
|
|
END SUB
|
|
|
|
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
|
|
|