 rem ------------------------------------------------
 rem *** BREAKOUT 2002 LASERBEAMS R3 (PAL PALETTE) -
 rem *** LASER LIGHT AND SOUND SHOW -----------------
 rem ------------------------------------------------
   
 rem BREAKOUT 2002 LASERBEAMS is an upgrade to the Hyperkin licensed game BREAKOUT 2000 with cooler music and visuals
 rem Improvements: More action, a score, level indicator and goal to reach the playable treasure room ending scene on level 10! 
  
 rem A game For Zero or more Players!
 rem 20191124 Fixed creeping black rows: Each proceeding level on real PAL CRT added another back row via color $20 seed; should have been $22 [all $N0 colors are black]
 rem 20191124 PAL colors tuned with Yolk on a real PAL CRT, fix for PAL color cycle reset to 34/$22 -  32/$20 will not display! 
 rem 20191122 SillyVenture PAL 262 version with PAL optimized colors - added visual opt to leave the ball amimation colors alone after the PAL tuning [backport this to NTSC!]
 rem 20191107 Added Startup Board Art design - extra initial board via SuperCharger static RAM properties, keeping the trip on below
 rem 20191030 tuning color cycle animation after rolling it back - slowed it to 7.5 FPS; excellent effect now, player can trip it on
 rem 20191011 found 100 bytes; added sideways color cyle animation to the Ball to complement the 4 frames of 30 FPS forward animation  
 rem 20191007 Laserbeams run out after 3/4 of a level is completed
 rem          CAM animation is at 7.5 FPS via 30 FPS increments using MBR [Motion Blur Reduction]
 rem 20191007 controls reversed - holding button preserves LASERBEAM reserves and remaps the Harmony on oscillator #1 
 rem 20191007 fixed black row (bugfix 20191008)
 rem 20191004 NTSC Palette Optimization for 30 Hz (flicker on the verge of perception)
 rem 20190909 interactive melodious musical score with player initiated Cannons and Arpeggios
 rem 20190909 interactive game score and game Level elements
 rem 20221002 restored flashing color balls for the C64 and set color bytes nybbles to have 4-bit C64 color values 
 rem 20221002 found stuck background color from player2/CPU tagging player 
 rem 20221004 stuck background color is a bug in C64 Atari emu only:
 rem 20221004 !Find where emu propagtes bgcolor to border color, it's getting recycled from there (use bgcolor to reseed, otherwise border color caches the background color change)
 rem -----------------------------------------------
 rem -- new: Now you can blow stuff up! ------------
 rem -----------------------------------------------
 rem *** FEATURING THE BALL AS PLAYER 1/CPU 
 rem *** AND THE ATARI LOGO AS PLAYER 2/CPU
 rem -----------------------------------------------
 rem *** BREAKOUT or Laser enough blocks to clear the board, clear all 10 to make it to the treasure room!
 rem *** The Camera only follows Player 1,
 rem *** and the AI can control either player! (play solo as the logo for a real challenge!) 

 rem Make it to Level 10, the playable green-screen treasure room ending scene!
 rem Look out - Player2 can blue-screen you on direct contact (playable blue scene) and drop your level back to 0!
 rem -----------------------------------------------
 rem 20190909 fixed color scrolling to match where it was off x1
 rem 20190909 balanced 30 Hz rendering instead of staggered 60/60/30
 rem 20190909 Player2 or the AI can catch the player and blue screens the game [ends but can continue, reset clears the blue]
 rem 20190909 Added Score and Level counter; reset and blue screen event clear level counter 
 rem 20190910 Added winning ending sequence with green screen and big Smiley face and end tune!
 rem 20221003 fixed screen color sticking after player2/CPU tags player 
 rem 20221004 !bug persists, change presisting bgcolor to white if player is tagged

 rem -----------------------------------------
 rem ---init section, runs once: -------------
 rem -----------------------------------------
 rem -----------------------------------------
 
 MUSICINDEX=0:rem make sure this is zeroed on init for button transition delay to next load 20200904

 data mazecolors $b0,$50,$60,$a0,$02,$40,$22,$c0,$92,$f4,$52,$a2,$d0,$f2,$70,$e2
 rem ballwaveform deprecated
 data ballwaveform 6,6,4,7,8,1,2,6,6,4,4,7
 data ballmusic 31,29,26,23,19,17,15,14,11,9,8,7,5,4,3,4,5,4,3,4,3
 data ballmusic2 11
 data ballwaveform2 4,4,4,4,4,4,4,6,6,4,4,7
 rem 20191009 !Found init error de-tuing the first note in the Ball theme arpeggio: ballmusic(x)=ballmusic(x)+1

 g=3
 
 u=5:v=6:x=5:y=5:w=1:z=2:p=2:q=2:r=16:h=112
 score=61: gosub createlevel:rem gosub setuproutine
 rem 20191011 Saving memory: Vars are preinitialized and Init is only called again at the setuproutine label below   
 rem f=0:t=0
 rem m=0
 rem l=0:k=0:n=0:score=0:o=0:var1=0
 rem var2=0:rem missile init
 rem py=0:rem used for music algorithm

 COLUPF=$3A 
 COLUP0=$54
 NUSIZ1=%00111111:rem wide player2, wide missile
 NUSIZ0=%00110000:rem normal player1, wide missile
 gosub ColorPlayerAndBoard
 return:rem 20191107 initial "extra" opening board design, courtesy of unique SuperCharger "Static RAM" properties!

setuproutine rem ---- can call this
 scrollvirtualworldtoggle=1:rem refresh cam after drawing on virtual world
 rem goto skipit
 for i = 13 to 19 step 2
 for j = 0 to 3
 vwpixel(i,j,on)
 next j,i
 for i= 91 to 13 step -2
 for j = 6 to 11
 vwpixel (i,j,on)
 next j,i
skipit

 rem Aha.... rowcolors array was overwriting into the player0 color array behind it [cool feature] but took a while to find it ;)

 rem 20191003 optimization skip this routine and call a sub: j= $3c:for i = 0 to 17: rowcolors(i)=j:j=j+5:next i
 gosub ColorPlayerAndBoard

 rem ------------------------------------------------
 rem end init section (implicit return)--------------
 rem ------------------------------------------------
 rem ------------------------------------------------ 

 rem ------------------------------------------------
 rem ---:the next comment line is used by the compiler
 rem ---gameloop subroutine, runs every frame:    ---
 rem ------------------------------------------------
 rem ------------------------------------------------
 rem vars t-toggle x,y f-frame g - direction (12345678, 1 is up)
 rem varx u,v (p1 xy), r - marquee in center of virtual world index
 rem w, z dir x/y, : p,q dir p1 x/y,   m - musical pixels p0
 rem i,j,e - temp vars for loops, expressions
 rem o - player1 animation l used by player 2 scroll animation, k, n too.
 rem t - level counter, py loop
 rem score - score
 rem ------------------------------------------------
 rem ------------------------------------------------

 rem ---------------------------------------------------
 rem TinyBASIC program
 rem ---------------------------------------------------

 rem --- gameplay - BREAKOUT! knockout the bricks as the ball, shoot a laser too!
 rem --- Shoot the AI opponent or player 2 with your laser, shoot score and level indicator
 rem --- Scrolling Breakout Banner Bounces players - reveals awesome phrase intermittently during play 
 rem --- Avoid being hit by the opponent; ends game with a playable blue screen; you must level up from Zero again!
 rem --- Reset - restarts the game - To Win the game reach Level 10, the playable green-screen treasure room! 
 
 rem --20221005 c64 2nd joystick button controls changing tile petscii
 rem if joy1fire=0 or f<>1 then goto skippetscii
 rem comment block for Atari 2600 (c64 only)
 rem if joy1up=1 then BackgroundTileCharacters(0)=BackgroundTileCharacters(0)+1
 rem if joy1down=1 then BackgroundTileCharacters(1)=BackgroundTileCharacters(1)+1
 rem if joy1left=1 then BackgroundTileCharacters(2)=BackgroundTileCharacters(2)+1
 rem if joy1right=1 then BackgroundTileCharacters(3)=BackgroundTileCharacters(3)+1

 rem if joy0up=1 then TileCharacters(0)=TileCharacters(0)+1
 rem if joy0down=1 then TileCharacters(1)=TileCharacters(1)+1
 rem if joy0left=1 then TileCharacters(2)=TileCharacters(2)+1
 rem if joy0right=1 then TileCharacters(3)=TileCharacters(3)+1
skippetscii   

 rem -- music algorithm 20190101
 rem if py<4 then py=py+1:SUSTAINFORFRAMES=SUSTAINFORFRAMES+1 else py=0

 rem bluescreen if player2 opponent or computer AI catches the player! 
 rem ------------------------------------------------------------------
 rem PAL palette juxtapositioning: PAL blue screen $DD; $90 is the PAL Green screen for the treasure room ending
 rem 20221003 fix sticking color when player1/CPU tags player
 rem test codes A pink D light green B dark gray
 if x=u and y=v then COLUBK=$DB:t=0:MUSICINDEX=240:rem play end/next level theme, bluescreen and reset level counter t

 rem Reset game: clear bluescreen on reset:
 if SWCHB|%11111110<>255 then COLUBK=$0B:score=0:MUSICINDEX=240:gosub createlevel:gosub setuproutine
  
 rem ---------------------------------------------------
 rem ------- four loads, split every 16 frames - revision: now revised for balanced 30 Hz

 f=f+1
 scrollvirtualworldtoggle=1
 rem  if f<2 then SUSTAINFORFRAMES=SUSTAINFORFRAMES+1
 if f=1 then goto framehandler1 
 if f=2 then goto framehandler2
 if f=3 then goto framehandler3
 if f=4 then f=0:goto framehandler4 

 return
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------

 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
framehandler1 rem ---------------------------- start framehandler1
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------

 vwpixel(x,y,bindplayer0)
 vwpixel(u,v,bindplayer1)

 rem --- player 1 action/input:
 rem z=0:w=0
 rem COLUP0=$84
 if joy0left=1 then w=1 
 if w=1 and x>0 then x=x-1 
 if joy0right=1 then w=2
 if w=2 and x<91 then x=x+1
 if joy0up=1 then z=1
 if z=1 and y>1 then y=y-1
 if joy0down=1 then z=2
 if z=2 and y<19 then y=y+1
 if x=0 and w=1 then w=2: rem flip direction if at border of virtual world
 if x=91 and w=2 then w=1
 if z=1 and y=1 then z=2
 if z=2 and y=19 then z=1

 if vwpixel(x,y,poll)=0 then return

 if w=1 and z=1 then z=2:goto jmpxif :rem if left and up go down and left
 if w=2 and z=1 then z=2:goto jmpxif:rem if right and up go down and right
 if w=1 and z=2 then z=1:goto jmpxif:rem if left and down go left and up
 if w=2 and z=2 then z=1 : rem if right and down then right and up  
jmpxif

 vwpixel(x,y,flip):rem pixel destroyed, take over one voice; fx with the music:
 AUDC0=4:rem ballwaveform(var1):rem ball wave
 AUDF0=ballmusic(var1):rem ball music
 if var1>21 then var1=0 else var1=var1+1
 rem SUSTAINFORFRAMES=12
 rem 20190910 harder to score; 20% no score
 if var1>5 then score=score+1 
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 return: rem ---------end framehandler1
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------

 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
framehandler2 rem ----------------------------- start framehander2 
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 gosub animateplayer1
  
 rem COLUP1=68:REFP1=0: rem player face forward
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 return : rem -------------end framehandler2
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------

 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
framehandler3 rem ----------------------------- start framehander3
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 
 rem if p=1 then player1x=player1x-5:rem fine adjust to offset
 rem if p=2 then player1x=player1x+5:rem fine adjust to offset
 rem vertical... skipping, too close to virtual world scroll

 rem player2 action/input:
 rem q=0:p=0
 if joy1left=1 then p=1 
 if p=1 and u>0 then u=u-1 
 if joy1right=1 then p=2
 if p=2 and u<91 then u=u+1
 if joy1up=1 then q=1
 if q=1 and v>1 then v=v-1
 if joy1down=1 then q=2
 if q=2 and v<19 then v=v+1
 rem REFP1=0: rem face forward, default incommming

 if u=0 and p=1 then p=2: rem flip direction if at border of virtual world
 if u=91 and p=2 then p=1
 if q=1 and v=2 then q=2
 if q=2 and v=19 then q=1

 if vwpixel(u,v,poll)=0 then return

 if p=1 and q=1 then q=2:goto jmpxif2 :rem if left and up go down and left
 if p=2 and q=1 then q=2:goto jmpxif2:rem if right and up go down and right
 if p=1 and q=2 then q=1:goto jmpxif2:rem if left and down go left and up
 if p=2 and q=2 then q=1 : rem if right and down then right and up  
jmpxif2

 vwpixel(u,v,flip):rem pixel destroyed, take over one voice; fx with the music:
 rem unless both players have simultaneous hits - then both fx
 AUDC1=6: rem ballwaveform2(m):rem ball wave
 AUDF1=ballmusic(m):rem ball music
 if m>21 then m=0 else m=m+1
 rem SUSTAINFORFRAMES=10
 
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 return : rem -------------end framehandler3
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------

 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
framehandler4 rem --------------------------- start frame handler4
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 
 rem COLUP1=50:REFP1=255:rem player face backwards

 rem ------------------------------------------------
 rem ------pan the camera to follow player 1:
 rem ------------------------------------------------
 
 rem if joy0fire=1 then goto skipmovecamera
 if x-BITIndex > 12 and BITIndex < 72 then BITIndex=BITIndex+1:scrollvirtualworldtoggle=1
 if x < BITIndex+9 and BITIndex>0 then BITIndex=BITIndex-1:scrollvirtualworldtoggle=1
 rem -----pan camera vertically (BYTErowoffset) if player is near the edge of the playfield CAM
 i = y*12: rem "read i(fastyindex,y)" is faster (12 step lookup table for virtual world y values)
 rem table not available anymore i=fastyindex(y): rem index the y*12 lookup table
 
 if BYTErowoffset<120 and BYTErowoffset+36<i then BYTErowoffset=BYTErowoffset+12: rem scrollvirtualworldtoggle=1
 rem Flashback limit to avoid vars in virtualworld: if i>36 then i=i-36
 if BYTErowoffset>i then BYTErowoffset=BYTErowoffset-12:rem scrollvirtualworldtoggle=1	
skipmovecamera 
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 rem ----------end framehandler4 
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 return

 rem----------------------subroutines:
 rem-----------------------------------------------------------
animateplayer1 rem --- flip sprite in four directions

 
 if o=0 then REFP0=0:loadplayer0(0):COLUP0=255: rem face forward, default incommming
 
 if o=1 then REFP0=255:COLUP0=$64:rem player face backwards
 rem COLUP0=$64
  
 rem COLUP0=$44
 if o=2 then loadplayer0upsidedown(0):COLUP0=$44:rem player upsidedown
 if o=3 then REFP0=0:COLUP0=$ef:rem player face forward
 o=o+1
 if o=4 then o=0
 if score<210 then COLUP0=$64: rem --- only show player 1 on fire beyond 210 (indicates close to clearing board)
 rem return 
 rem -------------------------------------------------------------
 rem ------------------------------------------------
 rem end game loop (implicit return)-----------------
 rem ------------------------------------------------
 rem -------------------------------------------------------------

 return

playerscore
 rem -----------------------------------------------------------------------------------
 rem 20190909 Adding the players score to Breakout 2000 R2: -------------------------------
 rem -----------------------------------------------------------------------------------
 rem i,j,k,py and s are available - 
 rem --- k 1's, py 10's, j 100's
 i=score:j=0
gethundreds if i<100 then goto donehundreds
 i=i-100:j=j+1:goto gethundreds
donehundreds
 py=i/10:rem 10's column
 k=b:rem remainder is 1's column

 rem 100's first:
 s=j*8
 for i=9 to 105 step 12
 gosub setvirtualworldscore
 s=s+1:next i

 rem 10's next:
 s=py*8
 for i=10 to 106 step 12
 gosub setvirtualworldscore
 s=s+1:next i

 rem 1's next:
 s=k*8
 for i=11 to 107 step 12
 gosub setvirtualworldscore
 s=s+1:next i

 rem -- test
 rem if t=1 then t=10

 rem Level counter next!!!
 s=t*8
 for i= 107 to 203 step 12
 gosub setvirtualworldscore
 s=s+1:next i
 
 rem --- winner ---
 rem if t>9 then COLUBK=$DA:MUSICINDEX=245
 rem PAL green is $90:rem C64 colorfix on nybble
 if t>9 then COLUBK=$9A:MUSICINDEX=245
 return

setvirtualworldscore
  virtualworld(i)=scoredata(s)
 return

fixblackrow rem --- handles staggered left palette tuning for low intensity
 rem PAL will need extra rules to limit algorithmic color register and shadow reister values to be  >= 32 and <224  
 rem if BREAKOUT2000colors(i)+16<4 then j=32 else j=16
 rem PAL will need extra rules to limit algorithmic color register and shadow reister values to be  >= 32 and <224  
 j=BREAKOUT2000colors(i)+16

 rem if j>=224 or j<32 then j=32
 if j>=224 or j<32 then j=34: rem 32/$20 will not display!
 
PALfix rem superfluous label; fixed below
 rem BREAKOUT2000colors(i)=BREAKOUT2000colors(i)+j
 BREAKOUT2000colors(i)=j

 return

createlevel 
 rem - score is 255, reset board and new graphics for player!
 score=0:COLUBK=0:MUSICINDEX=240:for i=0 to 91:for j=2 to 19 step 3:vwpixel(i,j,on):next j,i:COLUPF=mazecolors(k):j=k:k=k+1
 gosub setuproutine:rem redundant, dropt this? 
 return


 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 rem ---:the next comment line is used by the compiler
 rem ---gameloop2 subroutine, runs every frame:    --
 rem ------------------------------------------------
 rem -------------------------------------------------------------

 rem --------handle missle init 
 rem COLUBK=0

 rem 20190101
 rem 20190909 better Fx override on TIA oscillator 1 - algorithmic subtune with a phat bassline
 rem if joy0fire=1 and var2=0 and score <170 then var2=10:bx=x:by=y:px=w:SUSTAINFORFRAMES=20:AUDC0=11:AUDF0=player0y:rem init missile graphic
 rem 20191007 LASERBEAM - continous laser bursts until 195
 rem with reverse controls - button surpresses laser beam for reserve
 if joy0fire=0 and var2=0 and score <195 then var2=10:bx=x:by=y:px=w:SUSTAINFORFRAMES=20:AUDC0=11:AUDF0=player0y:rem init missile graphic
  
 rem -- multicolored defender style missile can destroy blocks in front of you
 rem -- todo: freeze Atari opponent for a duration if hit and flash screen - done without flashing
 rem -- todo: Atari opponent fires back at you :)
 
 if var2=0 then missile1x=0:missile1y=0:missile0x=0:missile0y=0:goto skipmissile1
 if px=2 and bx<91 then bx=bx+1
 if px=1 and bx>0 then bx=bx-1
 vwpixel(bx,by,bindmissile1)
 missile1y=missile1y-5:missile0y=missile1y+2:missile0x=missile1x:rem 20191007 double missiles

 rem -- screen turns red if Atari logo is hit, logo vanishes and reinitializes
 rem -- removed red screen 

 rem 20190101 no
 rem 20191004 Adding sustained chord Fx when player2 is shot: 
 rem if u=bx and v=by then var2=0:u=1:v=5:AUDF1=5:AUDC1=14:SUSTAINFORFRAMES=80:goto skipmissile1
 rem .... rollback ... offset the musicindex for offset Fx insead...

 rem make the large Logo easier to hit using collision detection instead of tiles
 rem if u=bx and v=by then var2=0:u=1:v=5:MUSICINDEX=212:goto skipmissile1
 rem rolling it back too easy - better as a dog fight where the center of the logo has to be hit EXACTLY using virtual world tile pixel coordinates
 rem if CXM1P>126 then CXCLR=0:var2=0:u=1:v=5:MUSICINDEX=212:goto skipmissile1
 if u=bx and v=by then var2=0:u=1:v=5:MUSICINDEX=207:goto skipmissile1

 rem if u=bx and v=by then var2=0:u=1:v=5:score=score+10:AUDC0=5:goto skipmissile1

 var2=var2-1
 rem -- blocks blow up if they are hit
 if vwpixel(bx,by,poll)=0 then goto skipmissile1 
 vwpixel(bx,by,flip):var2=0:AUDC0=7:rem COLUBK=64
 rem 20190910 ---- blowing up bricks only counts 1/2 points
 if f=3 then score=score+1: rem -- blowing up blocks increases score only until player catches fire 
skipmissile1

 
 rem vars: h - sliding index for player 2 sprite message

 if l<>4 and l<>8 and l<>12 and l<>16 then goto scrollplayerdelay
 loadplayer1(h)
 h=h+1
 if h>184 then h=112
scrollplayerdelay
 rem i=i+1:mazecolours(l)=i
 l=l+1
 if l>16 then l=0:COLUP1=mazecolors(n):n=n+1
 if n>16 then n=0
 rem play 2nd or 3rd (60/90 MUSICINDEX) and clear board if enough blocks are destroyed:

 return

 rem 20190910 adding color animation to the ball animation, always cycle ball colors  -----------------
ColorPlayerAndBoard
 for i=0 to 19
 rem 20191003 Palette Optimization for 30 Hz stability 
 rem NTSC data BREAKOUT2000colors $22,$32,$42,$52,$62,$72,$82,$92,$a2,$b2,$c2,$d2,$e2,$f2,$f1,$e1,$d1,$c1,$b1,$a1,$91,$81             
 rem PAL: 
 rem PAL will need extra rules to limit algorithmic color register and shadow reister values to be  >= 32 and <224  
 rem 20191124 PAL color patch; thisworked in the emu but blank rows appeared on real hardware where left most column was used; fixing that...
 rem data BREAKOUT2000colors $32,$42,$40,$a0,$b0,$c0,$c2,$b0,$72,$52,$32,$70,$22,$62,$a2,$90,$92,$30,$20,$d2,$80,$82             
 data BREAKOUT2000colors $32,$42,$44,$a2,$b2,$c4,$c2,$b4,$72,$52,$32,$34,$22,$62,$a2,$90,$92,$32,$22,$d2,$94,$82             
 

 rem 20191014 create ebb and flow pulsing mood Ball...
 
 rem if score= 255 then gosub fixblackrow:j=BREAKOUT2000colors(i)+16 else j=player0colors(i)+16
 rem 20191122 SillyVenture PAL 262 version with PAL optimized colors - added visual opt to leave the ball amimation colors alone after the PAL tuning [backport this to NTSC!]
 if score= 255 then gosub fixblackrow: rem PAL visual opt is to leave faded color ball Fx alone with the new boards:
 j=player0colors(i)+17:c64 nybble fix, +16 was always same nybble...

colorcycleball
 rem 20191030 using VAR1, it goes up higher allowing much slower animation on the ball color cycling, otherwise roll it back for interfering with 
 rem          the sprites frame animation, color cycling must be lazy;languid effect on an otherwise hyperactive BREAKOUT through the looking glass. 
 rem ----------------------------------------------------------------------------------------------------------------------------------------------
 if i>7 then goto skipcoloredballs
 rem removing off cycle ball color animation phase:
 rem 7.5 FPS lazy side scrolling color cycling animation stays on like the 30 FPS forward roll animation 
 if var1>5 and f=1 then e=1 else e=0 : rem "f=1" works out to 7.5 FPS on the ball color cycling ;) 
 if score=255 or e=1 then player0colors(i)=j
 rem rem if score=255 or f=1 then player0colors(i)=j
skipcoloredballs 

 rem 20191003 Palette Optimization for 30 Hz stability-- must also insure initial color seed falls on the left of the chart (stagger the 20 across the 2 or 3 on the left):
 
 next i  

 if score=255 then t=t+1:gosub createlevel: rem Breakout board complete, increment Level conter and clear score counter

 rem player0colors $22,$32,$42,$52,$62,$72,$82,$92
 rem PAL
 rem PAL -fixing real hardware kickouts: player0colors $30,$32,$50,$52,$54,$70,$72,$74
player0colors $32,$52,$34,$54,$74,$94,$92,$B2


 rem --- superfluous??? if k>16 then k=0

 rem 201910 unlikely to see 2nd bonus msg because other player is in motion; if score=210 then score=211:h=0:MUSICINDEX=60: rem --- display bonus message in player 2, play reward song, earn extra point. 

 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 rem end gameloop2 (implicit return)----------------- 
 rem ------------------------------------------------
 rem -------------------------------------------------------------

 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 rem ---:the next comment line is used by the compiler
 rem ---KITCHENSINK subroutine, runs when scrollvirtualworldtoggle=1
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------


 rem 20190101 BREAKOUT2000colors ----

 gosub ColorPlayerAndBoard

 rem BYTErowoffset
 k=BYTErowoffset/12

 rem py=1-py
 rem if py=1 then goto loadbalancethis

 rem for i=0 to 9:rowcolors(i)=BREAKOUT2000colors(j):j=j+1:next i

 rem 20190909 fixed color scrolling to match where it was off x1

 j=BYTErowoffset/12:k=j+9:py=9
 for i = j to k
 rowcolors(py)=BREAKOUT2000colors(i)
 py=py+1
 if py=10 then py=0
 next i: rem done mapping virtual world row colors to Camera

 rem goto kickout

loadbalancethis
 if BITIndex>58 then gosub playerscore:goto kickout
 if f=1 or f=3 then goto kickout

 rem run playfield central banner routine when scrolling:
 if score>175 then goto extraphrase
 if r>96 then r=0
extraphrase
 py=k-10: rem already +9:rem 20190105 opt to allow supercharger BASIC to keep up with Flashback BASIC (CBS RAM is faster than supercharger ram!)
 for j=py to k: rem --- slide sprite library array through virtual world array
 i=r+j
 e=fastyindex2(j)+3: rem same as j*12+3, lookup table
 rem e=e+3
 
 rem virtualworld(e)=sprites(i):push a slice of sprites array into world array
 rem fix - Flashback BASIC cannot see spritelibrary data but can load it into sprites:
 loadplayer1upsidedown(i):virtualworld(e)=player1(0)
 next j
 r=r+1 :rem 20
 data fastyindex2 0,12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204,216,228
kickout
 rem -----------------------------------------------------------------------------------
 rem 20190909 Adding player score in the upper right, multicolor! better tune too...
 rem -----------------------------------------------------------------------------------

 rem -------------------------------------------------------------
 rem -------------------------------------------------------------
 rem end KITCHENSINK (implicit return)----------------------------
 rem -------------------------------------------------------------
 rem -------------------------------------------------------------

 data scoredata  %00000000
 data scoredataa %01111110
 data scoredatab %01100110
 data scoredatac %01100110
 data scoredatad %01100110
 data scoredatae %01110110
 data scoredataf %01111110
 data scoredatag %00000000

 data scoredata1 %00000000
 data scoredat1a %00011000
 data scoredat1b %00111000
 data scoredat1c %00011000
 data scoredat1d %00011000
 data scoredat1e %00011000
 data scoredat1f %00111100
 data scoredat1g %00000000

 data scoredata2 %00000000
 data scoredat2a %00111000
 data scoredat2b %01001100
 data scoredat2c %00011000
 data scoredat2d %01110000
 data scoredat2e %01100000
 data scoredat2f %01111100
 data scoredat2g %00000000

 data scoredata3 %00000000
 data scoredat3a %00111000
 data scoredat3b %00001100
 data scoredat3c %00001100
 data scoredat3d %01111100
 data scoredat3e %00001100
 data scoredat3f %01111000
 data scoredat3g %00000000

 data scoredata4 %00000000
 data scoredat4a %01100110
 data scoredat4b %01100110
 data scoredat4c %01111110
 data scoredat4d %01111110
 data scoredat4e %00001110
 data scoredat4f %00001110
 data scoredat4g %00000000

 data scoredata5 %00000000
 data scoredat5a %01111110
 data scoredat5b %01100000
 data scoredat5c %01111110
 data scoredat5d %00000110
 data scoredat5e %00001110
 data scoredat5f %01111110
 data scoredat5g %00000000

 data scoredata6 %00000000
 data scoredat6a %01111110
 data scoredat6b %01100000
 data scoredat6c %01111100
 data scoredat6d %01100110
 data scoredat6e %01100110
 data scoredat6f %01111110
 data scoredat6g %00000000

 data scoredata7 %00000000
 data scoredat7a %01111110
 data scoredat7b %00000110
 data scoredat7c %00001100
 data scoredat7d %00011000
 data scoredat7e %00011000
 data scoredat7f %00011000
 data scoredat7g %00000000

 data scoredata8 %00000000
 data scoredat8a %01111110
 data scoredat8b %01100110
 data scoredat8c %01111110
 data scoredat8d %01100110
 data scoredat8e %01110110
 data scoredat8f %01111110
 data scoredat8g %00000000

 data scoredata9 %00000000
 data scoredat9a %01111110
 data scoredat9b %01100110
 data scoredat9c %01111110
 data scoredat9d %00001110
 data scoredat9e %00001110
 data scoredat9f %00001110
 data scoredat9g %00000000

 data scoredataw %00111100
 data scoredatwa %01111110
 data scoredatwb %10011001
 data scoredatwc %11111111
 data scoredatwd %11100111
 data scoredatwe %10111101
 data scoredatwf %01000010
 data scoredatwg %00111100

virtualworld
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
....x...............................................................................x...xx.x
....x...............................................................................x....xxx
....x....................................................................................xxx
....xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.......xxx
.................................................................................x.......xxx
.................................................................................x.......xxx
....xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx......x.......xxx
....x....................................................................................xxx
....x....................................................................................xxx
....x......xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
...........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
..........................................................................................xx
....xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
..........................................................................................xx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xx
.........................................................................................xxx
...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
.........................................................................................xxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


sprites
0
..XXXX..
.XX..XX.
XXXxx.XX
XxXXx..X
Xxx.XX.X
XXXxxXXX
.X.XXXX.
..XXXX..
8
..XXXX..
.XXXXXX.
X..XX..X
XXXXXXXX
XXX..XXX
X.XXXX.X
.X....X.
..XXXX..
16
........
XXXXXX..
XX..XX..
XX..XXX.
XXXXXXX.
xX....XX
XX....XX
XXXXXXX.
24
........
XXXXXXX.
XXX...XX
XXX...XX
XXXXXX..
XXX..XXX
XXX...XX
XXX...XX
32
........
XXXXXXXX
XX......
XXxxxxXX
XXXxxxxx
XX......
XXXXXXXX
........
40
........
..XXXX..
.XXXXXX.
XXX..XXX
XXX...XX
XXXXXXXX
XXXXXXXX
XXX...XX
48
........
XXX..xx.
XXX.xx..
XXXxx...
XXXx....
XXXxxx..
xxx.xxx.
xxx..xxx
56
........
XXXXXXXX
XX....XX
XX....XX
XXX...XX
XXX...XX
XXXXXXXX
........
64
........
XX....XX
XX....XX
XX....XX
XXX...XX
XXX...XX
XXXXXXXX
........
72
XXXXXXXX
XXXXXXXX
..XXXX..
..XXXX..
..XXXX..
..XXXX..
..XXXX..
........
80
........
.XXXXXX.
xx....XX
.....xXX
..xxxxXX
xXXxxxX.
XXX.....
xxxxxxxx
88
........
XXXXXXXX
XX....XX
XX....XX
XXX...XX
XXX...XX
XXXXXXXX
........
96
........
XXXXXXXX
XX....XX
XX....XX
XXX...XX
XXX...XX
XXXXXXXX
........
104
........
.XXXXXX.
xx....XX
.....xXX
..xxxxXX
xXXxxxX.
XXX.....
xxxxxxxx
112
........
..XXXX..
.XXXXXX.
XXX..XXX
XXX...XX
XXXXXXXX
XXXXXXXX
XXX...XX

120
........
XXXXXXXX
XXXXXXXX
..XXXX..
..XXXX..
..XXXX..
..XXXX..
........
128
........
..XXXX..
.XXXXXX.
XXX..XXX
XXX...XX
XXXXXXXX
XXXXXXXX
XXX...XX
136
........
XXXXXXX.
XXX...XX
XXX...XX
XXXXXX..
XXX..XXX
XXX...XX
XXX...XX
144
........
XXXXXXXX
..XXXX..
..XXXX..
..XXXX..
..XXXX..
xxxxxxxx
xxxxxxxx

152
........
.XXXXXX.
xx....XX
.....xXX
..xxxxXX
xXXxxxX.
XXX.....
xxxxxxxx
160
........
.XXXXXx.
XXx.....
XX......
XXXXXXX.
XX....XX
XXX...XX
xXXXXXX.
........
168
........
........
XXXXXXXX
XX....XX
XX....XX
XXX...XX
XXX...XX
XXXXXXXX
........
176
........
XXXXXXXX
XX....XX
XX....XX
XXX...XX
XXX...XX
XXXXXXXX
........
........
184


........
..XXXX..
.XXXXXX.
XXX..XXX
XXX...XX
XXXXXXXX
XXXXXXXX
XXX...XX

........
XX...XXX
XX...xxx
XX.x.xXX
XX.x.xxx
XX.x.xxx
XXXXXXX.
........

........
XXXXXXXX
XX......
XXxxxxXX
XXXxxxxx
XX......
XXXXXXXX
........

........
XXXXXXXX
XX......
XXxxxxXX
XXXxxxxx
......xx
XXXXXXXX
........

........
XXXXXXXX
XX....XX
XX....XX
XXX...XX
XXX...XX
XXXXXXXX
........

........
XX...XX.
XXx.xxxx
XX.x..XX
XX.xx.xx
XX.xx.xx
XX.Xx.xx
........

........
XXXXXXXX
XX......
XXxxxxXX
XXXxxxxx
XX......
XXXXXXXX
........

...XX...
..XXXX..
..XXXX..
..XXXX..
...XX...
........
...xx...
...xx...

 
chiptunes
4,19,4,19,8
4,17,4,17,8
4,15,4,15,8
4,14,4,14,16
4,19,4,19,8
4,14,4,14,16
4,19,4,19,8
4,14,4,14,16
4,19,4,19,8
4,14,4,14,8
4,14,4,14,8
4,15,4,15,8
4,17,4,17,8
4,19,4,19,16
4,26,4,26,8
4,19,4,19,16
4,26,4,26,8 
4,19,4,19,16
4,26,4,26,8
4,19,4,19,8
4,19,4,19,8
4,17,4,17,8
4,15,4,15,8
4,14,4,9,32
0,0,0,0,48
6,30,6,30,8
6,27,6,27,8
6,24,6,24,8
6,22,6,22,8
6,30,6,30,16
6,22,6,22,8
6,30,6,30,16
6,22,6,22,8
6,30,6,30,16
6,22,6,22,8
6,22,6,22,8
6,24,6,24,8
6,27,6,27,8
6,30,6,30,8   
1,5,1,5,16
6,30,6,30,8   
1,5,1,5,16
6,30,6,30,8   
1,5,1,5,16
6,30,6,30,8
1,5,1,5,16
0,0,0,0,64
0,0,0,0,0
7,24,7,24,24
7,30,7,30,38
0,0,0,0,0

                                          