#CONSTANT FALSE = 0
#CONSTANT TRUE = 1
#CONSTANT ALIEN_SIZE = 2
#CONSTANT IMG_ALIEN1 = 1
#CONSTANT IMG_ALIEN2 = 2
#CONSTANT IMG_SHIP = 3
#CONSTANT IMG_UFO = 4
#CONSTANT SPRT_UFO = 500
#CONSTANT BLOCK_SIZE = 5
#CONSTANT BULLET_SIZE = 2
#CONSTANT pVELOCITY = 10
#CONSTANT pGRAVITY = 2
#CONSTANT ALIEN_SX = 20
#CONSTANT ALIEN_SY = 16
#CONSTANT SFX_EXPLODE = 1
#CONSTANT SFX_SHIP_BULLET = 2
#CONSTANT SFX_FALL = 3
#CONSTANT SFX_BLOCK_HIT = 4
#CONSTANT SFX_ALIEN_BULLET = 5
#CONSTANT SFX_TITLE = 6
#CONSTANT SFX_1 = 7
#CONSTANT SFX_2 = 8
#CONSTANT SFX_UFO = 9
#CONSTANT INTRO_MAX_SIZE = 12
 
 
REM for intro graphics
type block
   state as boolean
   size as integer
endtype
 
REM alien
type Alien
   s as integer
   x as integer
   y as integer
   img as integer
   dead as boolean
   message as integer
endtype
 
 
REM
type Particle
   x as integer
   y as integer
   a as integer
   v as integer
endtype
 
 
REM
type Vector2D
   x as integer
   y as integer
endtype
 
 
REM ship properties
type SpaceShip
   x as integer
   y as integer
   sx as integer
   sy as integer
endtype
 
type BulletObject
   x as integer
   y as integer
   speed as integer
endtype
 
rem size to draw alien images
 
cls
REM get alien images
restore alien1
for y = 0 to 7
   for x = 0 to 9
      read z
      if z = 1
         box x*ALIEN_SIZE,y*ALIEN_SIZE,(x+1)*ALIEN_SIZE,(y+1)*ALIEN_SIZE
      endif
   next x
next y
 
restore alien2
for y = 0 to 7
   for x = 10 to 19
      read z
      if z = 1
         box x*ALIEN_SIZE,y*ALIEN_SIZE,(x+1)*ALIEN_SIZE,(y+1)*ALIEN_SIZE
      endif
   next x
next y
 
rem grab the alien images
get image IMG_ALIEN1, 0,0,10*ALIEN_SIZE,8*ALIEN_SIZE,1
get image IMG_ALIEN2, 10*ALIEN_SIZE,0,20*ALIEN_SIZE,8*ALIEN_SIZE,1
 
cls
rem size to draw ship at
size = 5
restore ship1
for y = 0 to 6
   for x = 0 to 6
      read z
      if z = 1
         box x*size,y*size,(x+1)*size,(y+1)*size
      endif
   next x
next y
rem grab ship image
get image IMG_SHIP, 0,0,7*size,7*size,1
 
 
rem grab ufo image
cls
restore ufo
sizex = 4
sizey = 2
ink rgb(255,0,0),0
for y = 0 to 4
   for x = 0 to 7
      read z
      if z = 1 then box x*sizex,y*sizey,(x+1)*sizex,(y+1)*sizey
   next x
next y
get image IMG_UFO,0,0,8*sizex,5*sizey,1
sprite SPRT_UFO,ux,20,IMG_UFO
hide sprite SPRT_UFO
 
rem bullet shape
dim bulletImage(3,10)
bullet as BulletObject
bullet.speed = 8
 
 
restore bulletData
for y=1 to 10
   for x=1 to 3
      read bulletImage(x,y)
   next x
next y
 
 
rem alien array
rows = 5
columns = 10
dim aliens(rows*columns) as Alien
 
 
sizeX = 5*ALIEN_SIZE
sizeY = 5*ALIEN_SIZE
spacingX = sizeX*2
spacingY = sizeY+sizeY/2
offsetX = (screen width() - (10*(ALIEN_SIZE+spacingX))) / 2 + sizeX
offsetY = 20
 
for y = 0 to rows-1
   for i = 1 to columns
      inc j
      aliens(j).s = j
      aliens(j).x = offsetX + (i-1)*spacingX
      aliens(j).y = offsetY + y*spacingY
      aliens(j).img = rnd(1)+1
      sprite j,aliens(j).x, aliens(j).y,aliens(j).img
      hide sprite j
      set sprite diffuse j, rnd(205)+50,rnd(205)+50,rnd(205)+50
   next i
next y
 
 
 
rem ship properties
ship as SpaceShip
 
ship.x = 302
ship.y = 445
ship.sx = 35
ship.sy = 35
sprite 100, ship.x, ship.y, IMG_SHIP
set sprite diffuse 100, 0,200,40
 
 
rem top boundary for ship movement
upper_boundary = 410
 
 
rem direction and speed of aliens
rem positive moves right, negative moves left
direction = 4
 
 
rem blocks for guarding ship
dim blocks(3,6,10)
 
for i = 1 to 3
   restore block
   for y = 1 to 6
      for x = 1 to 10
         read z
         blocks(i,y,x) = z
      next x
   next y
next i
 
rem starfield background
starfield_size = 400
dim starfield#(starfield_size,2)
 
for i = 1 to starfield_size
   starfield#(i,0) = rnd(screen width())
   starfield#(i,1) = rnd(screen height())
next i
 
 
rem bullet array
dim bullets(0) as Vector2D
 
 
rem random funny messages
dim messages$(13)
messages$(1) = "Lies!"
messages$(2) = "Oh, Snap!"
messages$(3) = "Oh, %#*@!!!"
messages$(4) = "Oh, Noodles!"
messages$(5) = "Bloody Hell!"
messages$(6) = "Cheater!"
messages$(7) = "Oh, gee wiz!"
messages$(8) = "pfft, again?"
messages$(9) = "F*%# YOU!"
messages$(10) = "Son of a B*%&#!"
messages$(11) = "le sigh...."
messages$(12) = "I'm falling..."
messages$(13) = "Weeeeeeee!!!"
 
 
 
REM SFX
createsound("explosion",SFX_EXPLODE,1000,2000,3500,5,0.1,0.05,0,0,0,10)
createsound("ship_bullet",SFX_SHIP_BULLET,1500,100,4000,0.20,1.00,0.00,0,0.00,0,10.00)
`createsound("alien_fall2",SFX_FALL,3000,2200,900,0.01,3.00,0.00,0,0.00,0,0.00)
createsound("alien_fall",SFX_FALL,2000,100,2000,-0.09,6.78,0.30,649,0.00,0,0.00)
createsound("block",SFX_BLOCK_HIT,500,41,4000,0.25,8.60,0.00,0,0.00,0,5.82)
createsound("alien_bullet",SFX_ALIEN_BULLET,1200,30,2000,0.06,3.96,0.00,0,0.00,0,1.06)
`createsound("title",SFX_TITLE,1186,3000,4000,0.01,0.00,0.55,3,0.00,0,10.00)
createsound("title",SFX_TITLE,1186,3000,4000,0.0,0.00,1.0,3,0.00,0,10.00)
createsound("beat1",SFX_1,150,100,8000,0.0,0.0,0.0,0,0.0,0,10.00)
createsound("beat2",SFX_2,120,100,8000,0.0,0.0,0.0,0,0.0,0,10.00)
createsound("ufo",SFX_UFO,500,2000,5000,0.00,0.00,0.02,2,0.00,0,10.00)
 
 
sync on
sync rate 40
backdrop on
color backdrop 0
 
shots = 0
hits = 0
 
 
dim shipBlow(ship.sx, ship.sy) as Particle
 
 
 
gosub intro
gosub play_game
 
 
 
 
 
 
 
REM +++++++++++++ INTRO +++++++++++++++
intro:
 
   for s = 1 to array count(aliens())
      if sprite exist(s) = 1 then hide sprite s
   next s
 
   dim colors(1) as dword
 
   colors(0) = rgb(0,192,0)
   colors(1) = rgb(0,0,192)
 
   for i = 1 to starfield_size
      starfield#(i,0) = rnd(screen width())
      starfield#(i,1) = rnd(screen height())
      starfield#(i,2) = atanfull(starfield#(i,0) - 320, starfield#(i,1) - 240)
   next i
 
   dim intro(47,17) as block
 
   restore title
   for y = 1 to 17
      for x = 1 to 47
         read intro(x,y).state
      next x
   next y
 
   offsetX = (640-(48*INTRO_MAX_SIZE))/2.0
   delay = 100
   timestamp = timer()
   row = 1
 
   play sound SFX_TITLE
 
   REPEAT
      cls
 
      ink 0xffffff,0
      for i = 1 to starfield_size
         starfield#(i,0) = starfield#(i,0) + sin(starfield#(i,2))*4
         starfield#(i,1) = starfield#(i,1) + cos(starfield#(i,2))*4
         dot starfield#(i,0),starfield#(i,1)
         if starfield#(i,0) > screen width() or starfield#(i,0) < 0 or starfield#(i,1) > screen height() or starfield#(i,1) < 0
            starfield#(i,0) = 320 + rnd(10)-5
            starfield#(i,1) = 240 + rnd(10)-5
            starfield#(i,2) = atanfull(starfield#(i,0) - 320, starfield#(i,1) - 240)
         endif
      next i
 
 
      if timer() >= timestamp+delay
         timestamp = timer()
         if row < 17 then inc row
         sizeFlag = 1
      else
         sizeFlag = 0
      endif
 
      for y = 1 to row
         for x = 1 to 47
            if intro(x,y).state = 1
               if sizeFlag = 1 then intro(x,y).size = intro(x,y).size + 2
               if intro(x,y).size > INTRO_MAX_SIZE then intro(x,y).size = INTRO_MAX_SIZE
               size = intro(x,y).size/2.0
               ink colors(rnd(1)),0
               box offsetX+(x*INTRO_MAX_SIZE-size),50+y*INTRO_MAX_SIZE-size,offsetX+(x*INTRO_MAX_SIZE+size),50+y*INTRO_MAX_SIZE+size
            endif
         next x
      next y
 
      center text 320,350, "Play Game"
      w = text width("Play Game")/2 + 4
      h = text height("P")+2
 
      if mousex() > 320-w and mousex() < 320+w and mousey() > 350 and mousey() < 350+h
         ink rgb(0,255,0),0
         line 320-w,350,320+w,350
         line 320-w,350+h,320+w,350+h
         line 320-w,350,320-w,350+h
         line 320+w,350,320+w,350+h
         if mouseclick() = 1 then start = 1
      endif
      sync
   UNTIL start = 1
RETURN
 
 
 
 
REM +++++++++++++ GAME LOOP +++++++++++++++
PLAY_GAME:
 
   hide mouse
 
   rem 0 = movement delay
   rem 1 = fire rate
   rem 2 = bullet speed
   dim levels(3,2)
   levels(1,0) = 400
   levels(1,1) = 50
   levels(1,2) = 3
   levels(2,0) = 300
   levels(2,1) = 40
   levels(2,2) = 3
   levels(3,0) = 150
   levels(3,1) = 30
   levels(3,2) = 4
 
   oldLevel = 0
   LEVEL = 1
 
   lives = 3
 
 
 
   for s = 1 to array count(aliens())
      `if sprite exist(s) then show sprite s
   next s
 
 
   score = 0
   DO
      cls
 
      if alien_dead_count = 50 then inc LEVEL
      if LEVEL > 3 then gameOver("No more levels to play!")
 
 
      REM if level changes
      if LEVEL <> oldLevel
 
         stamp = timer()
         repeat
            seconds = 3 - (timer()-stamp)/1000
            center text screen width()/2, screen height()/2,"Get ready in "+str$(seconds)
            sync
         until timer() > stamp+4000
 
 
         alien_dead_count = 0
         oldLevel = LEVEL
         alien_delay = levels(LEVEL,0)
         alien_fire_rate = levels(LEVEL,1)
         alien_bullet_speed = levels(LEVEL,2)
 
         backgroundMusic = SFX_1
         timestamp2 = timer()
 
 
         rem restore blocks
         for i = 1 to 3
            restore block
            for y = 1 to 6
               for x = 1 to 10
                  read z
                  blocks(i,y,x) = z
               next x
            next y
         next i
 
         rem reinitialize aliens
         spacingX = 10*ALIEN_SIZE*2
         spacingY = 8*ALIEN_SIZE*2
 
         offsetX = (screen width() - 10*spacingX)/2.0
         offsetY = 20
 
         undim aliens()
         rows = 5
         columns = 10
         dim aliens(rows*columns) as Alien
 
         j = 0
         for y = 1 to rows
            for i = 1 to columns
               inc j
               aliens(j).s = j
               aliens(j).x = offsetX + (i-1)*spacingX
               aliens(j).y = offsetY + y*spacingY
               aliens(j).img = rnd(1)+1
               sprite j,aliens(j).x, aliens(j).y,aliens(j).img
               show sprite j
               set sprite diffuse j, rnd(205)+50,rnd(205)+50,rnd(205)+50
               offset sprite j, 0,0
               rotate sprite j, 0
            next i
         next y
 
         rem reposition spaceship
         ship.x = 302
      endif : `end load new level
 
 
 
      REM starfield
      lock pixels
        for i = 1 to starfield_size
           if starfield#(i,1) < 0
              starfield#(i,0) = rnd(screen width())
              starfield#(i,1) = screen height()
           endif
           pdot(starfield#(i,0), starfield#(i,1),0xffffff)
           starfield#(i,1) = starfield#(i,1) - 1
        next i
      unlock pixels
 
 
      rem update alien positions every 4/10 of a second
      if timer() >= timestamp+alien_delay
         timestamp = timer()
         update = 1
      else
         update = 0
      endif
 
 
      if update = 1
         play sound backgroundMusic
         inc backgroundMusic
         if backgroundMusic > SFX_2 then backgroundMusic = SFX_1
      endif
 
 
      rem ufo movement across top
      if timer() >= timestamp2+10000 and updateUFO = 0
         timestamp2 = timer()
         if rnd(3) = 1
            loop sound SFX_UFO
            updateUFO = 1
            ux = -sprite width(SPRT_UFO)
            show sprite SPRT_UFO
         endif
      endif
 
      if updateUFO = 1
         ux = ux + 2
         sprite SPRT_UFO,ux,20,IMG_UFO
         if ux > screen width()
            updateUFO = 0
            stop sound SFX_UFO
         endif
      endif
 
 
 
      rem loop through aliens
      for i = 1 to array count(aliens())
         if fire = 1
            if aliens(i).dead = FALSE
               if overlap(aliens(i).x,aliens(i).y,aliens(i).x+ALIEN_SX,aliens(i).y+ALIEN_SY,bullet.x,bullet.y,bullet.x+6,bullet.y+20) = 1
                  fire = 0
                  aliens(i).dead = TRUE
                  play sound SFX_FALL
                  inc hits
                  inc shots
                  offset sprite aliens(i).s, ALIEN_SX/2, ALIEN_SY/2
                  aliens(i).x = aliens(i).x + ALIEN_SX/2
                  aliens(i).y = aliens(i).y + ALIEN_SY/2
                  inc score, 10
                  if rnd(3) = 1
                     aliens(i).message = rnd(array count(messages$())-1)+1
                  else
                     aliens(i).message = -1
                  endif
               endif
            endif
         endif
 
         rem position sprite
         sprite aliens(i).s, aliens(i).x, aliens(i).y, aliens(i).img
 
         if aliens(i).dead = TRUE
            rotate sprite aliens(i).s, wrapvalue(sprite angle(aliens(i).s)+10)
            `rotate sprite aliens(i).s, wrapvalue(sprite angle(i)+10)
            if aliens(i).message > -1 then displayMessage(sprite x(aliens(i).s),sprite Y(aliens(i).s),messages$(aliens(i).message))
            aliens(i).y = aliens(i).y + 5
            if aliens(i).y > screen height()+30
               aliens(i).dead = FALSE
               array delete element aliens(), i
               inc alien_dead_count, 1
               dec i, 1
            endif
         else
            if update = 1
               if rnd(alien_fire_rate) = 1
                  addBullet(aliens(i).x+sprite width(aliens(i).s)/2, aliens(i).y+sprite height(aliens(i).s))
                  play sound SFX_ALIEN_BULLET
               endif
               aliens(i).x = aliens(i).x + direction
               if aliens(i).x+ALIEN_SX+2 >= screen width() then dropFlag = 1
               if aliens(i).x <= 2 then dropFlag = 1
               aliens(i).img = aliens(i).img + 1
               if aliens(i).img > 2 then aliens(i).img = 1
            endif
         endif
      next i
 
      rem if an alien hit a side, drop the aliens down further
      if dropFlag = 1
         dropFlag = 0
         if isNegative(direction) = 1
            direction = 4
         else
            direction = -4
         endif
         for i = 1 to array count(aliens())
            if aliens(i).dead = FALSE then aliens(i).y = aliens(i).y+ALIEN_SY
         next i
      endif
 
 
      REM alien bullets
      for i = 1 to array count(bullets())
         REM collision check with guarding blocks
         for b = 0 to 2
            for y = 1 to 6
               for x = 1 to 10
                  if blocks(b+1,y,x) = 1
                     xoffset = b*213 + 75
                     yoffset = 400
                     if overlap(bullets(i).x-3,bullets(i).y-3,bullets(i).x+3,bullets(i).y+3,xoffset+x*BLOCK_SIZE,yoffset+y*BLOCK_SIZE,xoffset+(x+1)*BLOCK_SIZE,yoffset+(y+1)*BLOCK_SIZE)
                        blocks(b+1,y,x) = 0
                        array delete element bullets(), i
                        play sound SFX_BLOCK_HIT
                        goto skip
                     endif
                  endif
               next x
            next y
         next b
 
         REM draw the bullets then update position for next loop
         drawBullet(bullets(i).x, bullets(i).y, 3)
         bullets(i).y = bullets(i).y + alien_bullet_speed
 
         if dead = 0 and overlap(bullets(i).x-3,bullets(i).y-3,bullets(i).x+3,bullets(i).y+3,ship.x,ship.y,ship.x+ship.sx,ship.y+ship.sy)
            array delete element bullets(), i
            dead = 1
            dec lives
            if lives < 0 then gameOver("Game Over")
            hide sprite 100
            for x = 1 to ship.sx
               for y = 1 to ship.sy
                  shipBlow(x,y).x = ship.x+x
                  shipBlow(x,y).y = ship.y+y
                  shipBlow(x,y).a = rnd(180)+180
                  shipBlow(x,y).v = rnd(10)+5
               next y
            next x
            play sound SFX_EXPLODE
         else
            if bullets(i).y > screen height() then array delete element bullets(),i : alive = 0
         endif
 
         REM just a label to break out of many nested loops
         skip:
      next i
 
 
      REM guarding blocks
      ink rgb(128,128,128),0
 
      for i = 0 to 2
         for y = 1 to 6
            for x = 1 to 10
               if blocks(i+1,y,x) = 1
                  xoffset = i*213 + 75
                  yoffset = 400
                  box xoffset+x*BLOCK_SIZE,yoffset+y*BLOCK_SIZE,xoffset+(x+1)*BLOCK_SIZE,yoffset+(y+1)*BLOCK_SIZE
               endif
            next x
         next y
      next i
 
 
      ink rgb(100,255,100),0
 
      if dead = 0
         REM ship controls
         gosub _CONTROLS
         REM display ship
         sprite 100, ship.x, ship.y, IMG_SHIP
      else
         lock pixels
         for x = 1 to ship.sx
            for y = 1 to ship.sy
               px = shipBlow(x,y).x + shipBlow(x,y).v*cos(shipBlow(x,y).a)*t#
               py = shipBlow(x,y).y + shipBlow(x,y).v*sin(shipBlow(x,y).a)*t# + 0.5*pGRAVITY*t#^2
               pDot(px,py,rgb(100,255,100))
            next y
         next x
         unlock pixels
         t# = t# + 0.5
 
         if t# >= 50
            t# = 0
            dead = 0
            rem reposition spaceship
            ship.x = 302
            sprite 100, ship.x, ship.y, IMG_SHIP
            show sprite 100
         endif
      endif
 
      rem update bullet
      if fire = 1
         for y = 1 to 10
            for x = 1 to 3
               if bulletImage(x,y)
                  rem draw bullet
                  box bullet.x+x*BULLET_SIZE, bullet.y+y*BULLET_SIZE,bullet.x+(x+1)*BULLET_SIZE, bullet.y+(y+1)*BULLET_SIZE
                  rem ufo collision
                  if updateUFO = 1
                     if overlap(bullet.x+x*BULLET_SIZE, bullet.y+y*BULLET_SIZE,bullet.x+(x+1)*BULLET_SIZE, bullet.y+(y+1)*BULLET_SIZE, sprite x(SPRT_UFO),sprite y(SPRT_UFO),sprite x(SPRT_UFO)+sprite width(SPRT_UFO),sprite y(SPRT_UFO)+sprite height(SPRT_UFO))
                        updateUFO = 0
                        fire = 0
                        hide sprite SPRT_UFO
                        stop sound SFX_UFO
                        play sound SFX_EXPLODE
                        inc score, 100
                        inc hits
                        inc shots
                        goto skip2
                     endif
                  endif
                  rem bullet collision with guarding blocks
                  for b = 0 to 2
                     for yy = 1 to 6
                        for xx = 1 to 10
                           if blocks(b+1,yy,xx) = 1
                              xoffset = b*213 + 75
                              yoffset = 400
                              if overlap(bullet.x+x*BULLET_SIZE, bullet.y+y*BULLET_SIZE,bullet.x+(x+1)*BULLET_SIZE, bullet.y+(y+1)*BULLET_SIZE,xoffset+xx*BLOCK_SIZE,yoffset+yy*BLOCK_SIZE,xoffset+(xx+1)*BLOCK_SIZE,yoffset+(yy+1)*BLOCK_SIZE)
                                 blocks(b+1,yy,xx) = 0
                                 play sound SFX_BLOCK_HIT
                                 fire = 0
                                 inc shots
                                 goto skip2
                              endif
                           endif
                        next xx
                     next yy
                  next b
               endif
            next x
         next y
         bullet.y = bullet.y - bullet.speed
         if bullet.y < -10 then fire = 0 : inc shots
         skip2:
      endif
 
      center text 320,1,"Score: "+str$(score)
      if shots > 0 then acc = hits/(shots*1.0) * 100.0
      text 1,1,"Accuracy: "+str$(acc)+"%"
      text 540,1,"Lives: "+str$(lives)
      `text 540,1,"FPS: "+str$(screen fps())
 
      sync
   LOOP
RETURN
 
 
 
 
 
 
REM player controls
_CONTROLS:
   speed = 2
   if rightkey() then inc ship.x,speed
   if leftkey() then dec ship.x,speed
 
   rem fire bullet
   if spacekey() = 1 and fire=0 and spaceFlag = 0
      spaceFlag = 1
      play sound SFX_SHIP_BULLET
      fire = 1
      bullet.x = ship.x + ship.sx/2
      bullet.y = ship.y
   endif
   if spacekey() = 0 then spaceFlag = 0
 
   if ship.y > screen height()-ship.sy then ship.y = screen height()-ship.sy
   if ship.y < upper_boundary then ship.y = upper_boundary
   if ship.x < 0 then ship.x = 0
   if ship.x > screen width() - ship.sx then ship.x = screen width() - ship.sx
RETURN
 
 
function isNegative(x as integer)
   a = x >> 31
endfunction a
 
 
 
function overlap(ax1,ay1,ax2,ay2,bx1,by1,bx2,by2)
   if ax1 < bx2 and ax2 > bx1 and ay1 < by2 and ay2 > by1 then exitfunction 1
endfunction 0
 
 
 
function displayMessage(x,y,t$)
   length = text width(t$)+20
   if x-length > 0 then x = x-length
   y = y - text height(t$)*2
   ink rgb(255,255,255),0
   text x+10,y+10,t$
endfunction
 
 
 
function addBullet(x,y)
   array insert at bottom bullets()
   i = array count(bullets())
   bullets(i).x = x
   bullets(i).y = y
endfunction
 
 
 
function drawBullet(cx as integer, cy as integer, radius as integer)
   lock pixels
   r2# = radius*radius
   for x = cx-radius to cx+radius
      for y = cy-radius to cy+radius
         d# = ((cx-x)^2 + (cy-y)^2)
         if d# <= r2#
            t# = d#/r2#
            pDot(x,y,fade(rgb(255,255,255), rgb(0,80,255), t#))
         endif
      next y
   next x
   unlock pixels
endfunction
 
 
REM
function pDot(x as integer, y as integer, color_value as dword )
   if x > 0 and x < screen width() and y > 0 and y < screen height()
      start = get pixels pointer()
      repeat_number = get pixels pitch()
      bits_per_pixel = bitmap depth(num)/8
      pointer = start + y*repeat_number + x*bits_per_pixel
      *pointer = color_value
   endif
endfunction
 
 
REM
function fade(a as dword, b as dword, d as float)
   r1 = rgbr(a)
   g1 = rgbg(a)
   b1 = rgbb(a)
 
   r2 = rgbr(b)
   g2 = rgbg(b)
   b2 = rgbb(b)
 
   r = r1 + (r2-r1)*d
   g = g1 + (g2-g1)*d
   b = b1 + (b2-b1)*d
 
   c as dword
   c = rgb(r,g,b)
endfunction c
 
 
 
REM Gracefully swiped from Ric!
function createsound(name$,soundnumber,frequency#,length#,loudness#,bend#,decay#,vibratospeed#,vibratodepth#,tremelospeed#,tremelodepth#,attack#)
 
   outWord as word
   dword1 as dword: dword2 as dword: dword3 as dword: dword4 as dword
   dword5 as dword: dword6 as dword: dword7 as dword
 
   samples=int((length#/1000)*44100)
 
   if memblock exist(1) then delete memblock 1
   make memblock 1,samples*2+28
 
   ` write 28 memblock header bytes
   dword1=1      ` gg query: is this the number of channels?
   dword2=2      ` gg query: is this the number of bytes per sample?
   dword3=22050  ` gg query: seems to be half the number of samples per second - why?
   dword4=88200  ` gg query: is this the number of bytes per second?
   dword5=4      ` gg query: what does this represent?
   dword6=16     ` gg query:     (ditto)            ?
   dword7=0      ` gg query:     (ditto)            ?
 
   position=0
   write memblock dword 1, position, dword1 : inc position,4
   write memblock dword 1, position, dword2 : inc position,4
   write memblock dword 1, position, dword3 : inc position,4
   write memblock dword 1, position, dword4 : inc position,4
   write memblock dword 1, position, dword5 : inc position,4
   write memblock dword 1, position, dword6 : inc position,4
   write memblock dword 1, position, dword7 : inc position,4
 
   rem generate and write wave
   riseinloudness#=loudness#
   for x=1 to samples
      outInteger=int(sin((x/122.5)*(frequency#+vibratodepth#*sin(theta#)))*(loudness#-fallinloudness#-riseinloudness#+tremelodepth#*sin(phi#)))*3.0
      if outInteger <-32767 then outInteger=-32767  ` gg query: is this the valid range?
      if outInteger>32767 then outInteger=32767     ` gg query:       (ditto)          ?
      outWord=outInteger
      inc theta#,vibratospeed#
      inc phi#,tremelospeed#
      dec frequency#,bend#
 
      if fallinloudness#<loudness#
         inc fallinloudness#,decay#
      endif
 
      if riseinloudness#>0
         dec riseinloudness#,attack#
      endif
 
      write memblock word 1, position, outWord : inc position,2
   next x
 
   if sound exist(soundnumber)=1 then delete sound soundnumber
 
   make sound from memblock 999, 1
   clone sound soundnumber, 999
 
   delete sound 999
   ` memblock no longer required
   delete memblock 1
 
endfunction
 
 
function gameOver(s$)
 
   if sound playing(SFX_UFO) then stop sound SFX_UFO
 
   repeat
      center text 320,240,s$
      if s$ = "Game Over"
         center text 320,260, "All your base are belong to them!"
      else
         center text 320,260, "All their base are belong to you!"
      endif
      center text 320,300, "Press return key to exit"
      sync
   until returnkey()
   end
 
endfunction
 
 
alien1:
data 0,0,1,0,0,0,0,1,0,0
data 0,0,0,1,0,0,1,0,0,0
data 0,0,1,1,1,1,1,1,0,0
data 0,1,1,0,1,1,0,1,1,0
data 1,1,1,1,1,1,1,1,1,1
data 1,0,1,1,1,1,1,1,0,1
data 1,0,1,0,0,0,0,1,0,1
data 0,0,0,1,0,0,1,0,0,0
 
 
alien2:
data 0,0,1,0,0,0,0,1,0,0
data 1,0,0,1,0,0,1,0,0,1
data 1,0,1,1,1,1,1,1,0,1
data 1,1,1,0,1,1,0,1,1,1
data 1,1,1,1,1,1,1,1,1,1
data 0,0,1,1,1,1,1,1,0,0
data 0,0,1,0,0,0,0,1,0,0
data 0,1,0,0,0,0,0,0,1,0
 
 
ship1:
data 0,0,0,1,0,0,0
data 0,0,1,1,1,0,0
data 0,0,1,1,1,0,0
data 0,1,1,1,1,1,0
data 1,1,1,1,1,1,1
data 1,1,1,1,1,1,1
data 0,1,1,1,1,1,0
 
 
block:
data 0,0,1,1,1,1,1,1,0,0
data 0,1,1,1,1,1,1,1,1,0
data 1,1,1,1,1,1,1,1,1,1
data 1,1,1,1,1,1,1,1,1,1
data 1,1,0,0,0,0,0,0,1,1
data 1,0,0,0,0,0,0,0,0,1
 
 
bulletData:
data 0,1,0
data 1,0,0
data 1,0,0
data 0,1,0
data 0,0,1
data 0,0,1
data 0,1,0
data 1,0,0
data 1,0,0
data 0,1,0
 
title:
data 0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0
data 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0
data 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0
data 0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0
data 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0
data 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0
data 0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0
data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
data 1,1,1,1,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,1,1,1,0,0,1,1,1,0,0,0,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1
data 0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0
data 0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0
data 0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,1,1,1,1,1,0,1,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1
data 0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1
data 0,0,1,0,0,0,1,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1
data 1,1,1,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,1,1,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,1,1,1,1,1
 
ufo:
data 0,0,1,1,1,1,0,0
data 0,1,1,1,1,1,1,0
data 1,1,1,1,1,1,1,1
data 0,1,1,1,1,1,1,0
data 0,0,1,1,1,1,0,0