# This game is written for the 10 basic line challenge
# This is an Asteroid game for the C64
# Written by Johan Berntsson, 5 Feb 2020
#
# The game features complete gameplay, colour and
# sound effects on 10 lines of CBM Basic 2.
#
# This is written for the 10 basic line challenge
# I have moved things around to fit as much as
# possible. In a normal program such things would
# of course be in a more logical order. Keep this in
# mind when reading the code.

#
# Init variables and colours
#
1 
  # p=0: # score/position (this is 0 by default so no need to set)
  # h=0 # spaceship height (vertical position) (default 0)

  v=53248: # vic-ii base address
  q=54272: # SID chip offset (sound)

  fori=1to6:
      readn,a,d,w: # n=sprite data, a=vic-ii offset, d= vic-ii data
      poke12288+3*i,n: # update sprite data
      pokev+a,d: # program the vic-ii chip (sprite attributes)
      pokeq+7-i,w # program the SID chip (sound attributes)

#
# Setup the spaceship sprite
#
2
  next:
  f=200:   # speedup factor

  # 12288-12351 is zero on init, so we only need to define sprite
  # data where it is non-zero
  data96,,50,200,248,33,,97,255,29,1,17,199,39,7,,255,21,1,,62,32,,
  # SPRITE 0 (spaceship)
  # .***.... 96
  # *****... 248
  # ******** 255
  # **...*** 199
  # ******** 255
  # ..*****. 62
  # With embedded poke data
  # 96,,50: pokev+0,50 (poke53248,0: x coordinate for sprite 0), pokes+6,200
  # 248,33,: pokev+33,0 (poke 53281,0: black background), pokes+5,97
  # 255,29,1: pokev+29,1 (poke 53277,1: sprite expansion x), pokes+4,17
  # 199,39,7: pokev+39,7 (poke 53287,7: sprite 0 color), pokes+3,0
  # 255,21,1: pokev+21,1 (poke 53269,1: show/enable sprites), pokes+2,0
  # 62,32,: pokev+32,0 (poke 53280,0: black border), pokes+1,0

#
# Init variables, add stars and init sound
#
3
  print"{white}{clr}": # make all text white and clear the screen

  # sprite 0: spaceship
  poke2040,192: # sprite 0 in location 12288/64=192

  l=15: # number of lines to scroll (23 max)
  b=1063: # right-most column (to put new stars in)
  r=q+24: # volume control

  # Add some stars
  fori=0to63:
      poke1024+rnd(1)*l*40,46 # put a star at a random pos. in video ram

# continue sound initiation and read asteroid data into m$()
4
  next:

  a=2: # number of bullets

  fori=0to2:
      readm$(i):
  next:

  # Asteroids
  data "W","V{left}{down}V","{left}NM{left}{left}{down}MN":

#
# Here is the scrolling magic. Created in x$ so we save
# time in the game loop
#

  x$="{home}":
  fori=0tol

5
      # The trick to scroll is to use the line buffer in the
      # screen editor. Starting from the leftmost column, go 
      # one step to the right, delete the character in the
      # leftmost column, then go down and repeat on the next line
      x$=x$+"{right}"+chr$(20)+"{down}":
  next:
  # Add some info and a score counter
  x$=x$+"astro{right}m,k,z:{right}score/ammo":

  y=1030: # bullet base position (pointer to video memory)

  poke650,128 # enable keyboard repeat

#
# This is the entry point to the game loop.
# Scroll the screen, read keyboard input, add
# obstacles, and check if crashed
#
6
  # scroll leftwards
  printx$p,a:
  #wait53265,128: # wait for raster line (doesn't reduce flickering)
  # add new stars in the rightmost column
  pokeb+40*int(l*rnd(1)),46:

  geta$:
  h=h+(a$="k"andh>0)-(a$="m"andh<l) # update spaceship vertical position


#
# Add new astroids
#
7
  # add asteroids rightmost column
  ifrnd(1)<p/fthenpoke211,38:poke214,l*rnd(1):sys58732:print"{brown}"m$(3*rnd(1))"{white}";


#
# Check if time to fire a bullet
#
8 
  ifa$="z"andathena=a-1:
      fori=1to34:
          poker,i*6: # sound effect
          t=y+h*40+i:
          poket,67: # draw bullet
          poket-1,32: # erase behind
      next

#
# Move the spaceship, check if crashed
#
9 
  poker,15: # volume on
  pokev+1,50+h*8: # move spaceship
  c=peek(1028+h*40): # character under spaceship
  ifc=32orc=46then # crash if not star or space
     # didn't crash: update score and continue game loop
     poker,0: # sound volume to 0 (creates a small sound effect)
     p=p+1:
     goto6

#
# GAME OVER: show info and play sound effect, then restart
#
10
  print"{home}crash";:
  # sound effect
  pokeq+1,40: # frequency
  pokeq+5,0: # reset attack/release
  pokeq+4,129:pokeq+4,128: # white noise on, then off
  # wait for keypress
  wait198,1:
  # restart
  run

