rem ------------------------------------------------ rem *** BREAKOUT 2002 LASERBEAMS R2 (NTSC 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 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 ----------------------------------------------- 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 ----------------------------------------- rem ---init section, runs once: ------------- rem ----------------------------------------- rem ----------------------------------------- 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:x=5:y=5:v=6:w=1:z=2 r=16:p=2:q=2:h=112 score=61:rem 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 -- 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 ------------------------------------------------------------------ if x=u and y=v then COLUBK=$90: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=0: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+3636 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 --- if t>9 then COLUBK=$D0:MUSICINDEX=245 return setvirtualworldscore virtualworld(i)=scoredata(s) return fixblackrow rem --- handles staggered left palette tuning for low intensity if BREAKOUT2000colors(i)+16<4 then j=32 else j=16 BREAKOUT2000colors(i)=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 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 20191014 create ebb and flow pulsing mood Ball... if score= 255 then gosub fixblackrow:j=BREAKOUT2000colors(i)+16 else j=player0colors(i)+16 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 rem 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 ;) rem if score=255 or e=1 then player0colors(i)=j 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 player0colors $22,$32,$42,$52,$62,$72,$82,$92 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