rem ------------------------------------------------------------------------------ rem --- 6/4/2025 Demo Construction Set rem ------------------------------------------------------------------------------ rem --- Display List graphics and sprite animation studio rem --- bw switch/shiftlock - starts editor and loads 1st sprite frame* rem --- button: edit sprite pixels and Display Lists. rem --- Sprite edited is paintbrush/cursor and also updated. rem --- button + right/left: step thru sprite frames (frame marker at bottom) rem --- down + button: clone prior sprite as template (animation ctrl) rem --- up + button: change sprites row colors (hex code indicator on left) rem --- up/down/left/right: position cursor to edit sprite pixels, rem --- and explore amd edit display list graphics. rem --------------------------------------------------------------- rem --- 6/10/2025 petscii texturemap editor and pattern select: rem --- Pattern: hold left and press button in any zone to cycle patterns rem --- Full petscii editor: go to upper right of screen and press button rem --- then up/down/left/right changes petscii characters in a display list, rem --- Button advances through display lists and background/foreground petscii. rem ------------------------------------------------------------------------- rem --- Music Maker IDE: BW switch/shiftlock when character is in bottom zone rem --- Step through Tracker patterns to revise or write new music. rem --- 3rd voice manufactured as a logical and of the waverform. rem ------------------------------------------------------------------------- rem --- Instument Note Instrument Note Frames Duration rem ------------------------------------------------------------------------- rem --- Values are 0-31 for all fields except Frames Duration. rem --- Frames Duration goes to 99 and increases the beat in increments of 16. rem --- button: Step thru trace/plays next pattern. rem --- up/down: changes a field value and plays revised pattern again. rem --- left/right: Navigates between fields rem --- hold right + button: "sound search" revises current pattern rem --- hold up + button: "different sound search" revises current pattern rem --- hold down + button: clones previous pattern as template for rem ------------------------------------------------------------------------- rem --- Music revision during demo - hold right and press button for new tunes rem --- New tunes can be edited and reviewed in the Music Maker IDE. rem ------------------------------------------------------------------------- rem --- Inertia Zone Demo with interactive user mode (joystick) rem --- Pick up tile mapped friends to experience each zones different inertia. rem --- Demo switches between 30 and 60 Hz (25 and 50 Hz on PAL), rem --- when the music slows down the animation becomes crystal clear via MBR. rem --- Then plasma colors cycle for a few seconds and new colors are selected, rem --- then the music speeds up again and animation has a pleasant blur without MBR. rem ---------------------------------------------------------------- rem ---20231221 Inertia Zones --- rem ---------------------------------------------------------------- rem --- Inertia: Game idea travel thru inertia pickup zones each with different physics rem --- pickup your tilemapped friends in each quickly moving pickup zone rem --- "inertia zones" add horizontal or vertical directional currents based on scrolling direction (up/down/left/right) rem --- todo for the sequel: Diagonal zone with cross inertia. rem --- 4AB - switch every level MBR & MB with DLIs rem ------------------------------------------------------------------------------------------------- rem ------------------------------------------------------------------------------------------------- rem ---- SuperCharger BASIC program for Atari 2600 and Commodore 64 rem ---- Download SuperCharger BASIC 2025 BETA https://RelationalFramework.com/ rem ------------------------------------------------------------------------------------------------- rem ----------------------------------------- rem ---init section, runs once: ------------- rem ----------------------------------------- grabinit score=1:g=0:scrollvirtualworldtoggle=1 l=0 q=0 rem comment next line for SuperCharger: rem a=0:gosub loadvirtualworld:rem loads virtualworld into RAM, required for Flashback BASIC (CBS RAM) COLUBK=15 rem lost player colors under flashback BASIC rem data xplayer0colors $c2,$c2,$D2,$d2,$b2,$b2,$a2,$a2,$A1 data xrowcolors $42,$42,$42,$42,$c4,$c4,$c4,$b6,$b6,$42 for e=0 to 9:rowcolors(e)=xrowcolors(e):next e rem for e=0 to 7:player0colors(e)=xplayer0colors(e):next e rem SUPERCHARGERID=0:rem this is the Operating System so it is now always 0... rem=3 can be anywhere usually in the init, set to zero for testing (supercharger security) loadplayer1(0) COLUP1=$98:rem FE rem NA below - this is already init to 15 below line 0 setup rem MUSICINDEX=0:rem 20200904 SuperCharger var may be reset on reload and actively loaded! init for button load transition delay... rem ------------------------------------------------------------------------------------------------------------------------------- e=29:f=5:player0x=30:player0y=30:rem player0colors(0)=$c1 rem CXCLR=0 rem DisplayList3Shadow(119)=48:DisplayList3Shadow(118)=48 rem DisplayList3Shadow(154)=48 rem ------------------------------------------------ rem end init section (implicit return)-------------- rem ------------------------------------------------ rem -- variable map:------------------------------ rem freed l, using MUSICINDEX for toggle switching display modes instead of each level rem t = timer 0/1 used to seed display lists rem g = 1 after setup (setup var), 2 if button is pressed rem r = musical algorythm variable rem !Sound bug using r in kitchensink event setting color ram backbuffers rem score = level 2,3,4 create different instrument sets for the SID [C64 only] rem Interesting feature, enhanced sound algorithm... rem h,u,w - BITIndex for different DLI zones rem x,y,v,s,z - tile pixel x/y, s=sprite animation index,z= rem e,f - tilemapped sprites virtual world coordinates rem i,j - joy direction rem q - Music Editor IDE on/off (1/0) rem var1,var2 realtime petscii editor index/control rem ----------------------------------------------- rem --- Tracker editor variable map----------------- rem --- f - frames, z - draw grid flag, var1 - joystick released rem --- score - hilight cursor, var2 used by tracker editor rem --- z - on/off tracker GUI, y tilepixel virtualworld coordinate rem --- bx index of MusicData chiptunes rem 20250220 improving Editor to mirror waxing and waning of voice one and voice 2 Fx and variable sustain lengths rem --- w - SUSTAINFORFRAMES Fx mirror, var1, m - control toggle rem ------------------------------------------------ rem ---gameloop subroutine, runs every frame: --- rem ------------------------------------------------ if SWCHB|%11110111=247 then goto charactereditor hookgameloop1 if t<>0 then goto tisnot0 if f=17 then vwpixel(e,f,bindplayer1) gosub getpetscii2:scrollvirtualworldtoggle=35:gosub DLI:goto tisnot1: rem run this DLI every other frame tisnot0 rem if t=1 then gosub getpetscii3:BYTErowoffset=v*12:h=BITIndex:BITIndex=u::scrollvirtualworldtoggle=30:gosub DLI:BITIndex=h:BYTErowoffset=120 tisnot1 scrollvirtualworldtoggle=0 1 if g=0 then BYTErowoffset=120:COLUPF=$64:COLUP0=$b4:MUSICINDEX=0:gosub grabinit:g=1:z=0 rem ---setup complete--- if g=2 and joy0fire=0 then g=1 rem --- caught tile mapped item if CXPPMM & 128<>128 then COLUBK=0:goto skiphit: rem bit7 detects player0 and player1 sprite collision CXCLR=0 COLUBK=2 rem scrollvirtualworldtoggle=1:rem dynamic color RAM 20250421 rem alread on for 30 Hz/25 Hz mode with Display list calls! gosub increasescore:gosub colorcycle player0x=0:rem MUSICINDEX=10 if f=18 then goto set18 if e=22 then f=18:e=20:COLUP1=$54:goto skiphit if f=5 then f=17:e=22:COLUP1=$86:goto skiphit set18 e=29+w:f=5:COLUP1=$32 skiphit return rem ---- 20250422 Sound enhancement C64 only levels 2,3,4 have different Instrument set ADSR rem ---- changes 32 instrument orchestra ---- rebuildsid456a rem 20241002 rebuild instrument defintions - sounds better for bx=0 to 32 SID4(bx)=SID4(bx)+2:rem SID4(bx)=SID4(bx)&%11110111:mask squelch off rem test squelch, interesting not 100% effective SID4(bx)=SID4(bx)^%00001000 SID5(bx)=SID5(bx)+2 SID6(bx)=SID6(bx)+2 next bx rem DisplayList3Shadow(154)=DisplayList3Shadow(154)+1 return rebuildsid456b rem 20241002 rebuild instrument defintions - reverse direction for bx=0 to 32 SID4(bx)=SID4(bx)-2:rem SID4(bx)=SID4(bx)&%11110111 SID5(bx)=SID5(bx)-2 SID6(bx)=SID6(bx)-2 next bx rem DisplayList3Shadow(154)=DisplayList3Shadow(154)-1 return buttonpressed rem -------------- rem entering petscii multiple buffer editor? (player at upper right) if player0x>150 and player0y>80 and var1=0 then var1=1:return:rem start petscii editor at top DLI rem if player0x>150 and player0y<12 and var1=0 then var1=2:return:rem start petscii editor at 2nd DLI rem if joy0up=1 and var1=0 then var1=1:return:rem start petscii full editor in top zone if var1=6 then var1=0:rem turn off full petscii editor if var1>0 then var1=var1+1:return:rem step through petscii tilemap zones in full editor rem display hex value upper left ... petscii symbol lookup OK rem if joy0up=1 then gosub rebuildsid456a:return rem if joy0down=1 then gosub rebuildsid456b:return rem releasing button selects presets if joy0left=1 then goto editpetscii if joy0right=1 then gosub rebuildmusic:return rem ----------------------------- rem test gosub increasescore:rem use algorithm return petsciifulleditor if joy0right=0 and joy0left=0 and joy0up=0 and joy0down=0 then var2=0 if var1=2 then goto 2ndzonefulledit if var1=3 then goto 3rdzonefulledit if var1=4 then goto topzonefulledittile if var1=5 then goto 2ndzonefulledittile if var1=6 then goto 3rdzonefulledittile topzonefulledit if joy0up=1 and var2=0 then var2=1:petscii3(0)=petscii3(0)+1 if joy0down=1 and var2=0 then var2=1:petscii3(1)=petscii3(1)+1 if joy0right=1 and var2=0 then var2=1:petscii3(2)=petscii3(2)+1 if joy0left=1 and var2=0 then var2=1:petscii3(3)=petscii3(3)+1 return 2ndzonefulledit if joy0up=1 and var2=0 then var2=1:petscii2(0)=petscii2(0)+1 if joy0down=1 and var2=0 then var2=1:petscii2(1)=petscii2(1)+1 if joy0right=1 and var2=0 then var2=1:petscii2(2)=petscii2(2)+1 if joy0left=1 and var2=0 then var2=1:petscii2(3)=petscii2(3)+1 return 3rdzonefulledit if joy0up=1 and var2=0 then var2=1:petscii(0)=petscii(0)+1 if joy0down=1 and var2=0 then var2=1:petscii(1)=petscii(1)+1 if joy0right=1 and var2=0 then var2=1:petscii(2)=petscii(2)+1 if joy0left=1 and var2=0 then var2=1:petscii(3)=petscii(3)+1 return topzonefulledittile if joy0up=1 and var2=0 then var2=1:tilepetscii3(0)=tilepetscii3(0)+1 if joy0down=1 and var2=0 then var2=1:tilepetscii3(1)=tilepetscii3(1)+1 if joy0right=1 and var2=0 then var2=1:tilepetscii3(2)=tilepetscii3(2)+1 if joy0left=1 and var2=0 then var2=1:tilepetscii3(3)=tilepetscii3(3)+1 return 2ndzonefulledittile if joy0up=1 and var2=0 then var2=1:tilepetscii2(0)=tilepetscii2(0)+1 if joy0down=1 and var2=0 then var2=1:tilepetscii2(1)=tilepetscii2(1)+1 if joy0right=1 and var2=0 then var2=1:tilepetscii2(2)=tilepetscii2(2)+1 if joy0left=1 and var2=0 then var2=1:tilepetscii2(3)=tilepetscii2(3)+1 return 3rdzonefulledittile if joy0up=1 and var2=0 then var2=1:tilepetscii(0)=tilepetscii(0)+1 if joy0down=1 and var2=0 then var2=1:tilepetscii(1)=tilepetscii(1)+1 if joy0right=1 and var2=0 then var2=1:tilepetscii(2)=tilepetscii(2)+1 if joy0left=1 and var2=0 then var2=1:tilepetscii(3)=tilepetscii(3)+1 return editpetscii rem presets rem top pescii buffer if player0y>50 then petscii3(3)=petscii3(3)+1:petscii3(2)=petscii3(2)+1:petscii3(1)=petscii3(1)+1:petscii3(0)=petscii3(0)+1:return rem bottom if player0y<20 then petscii(2)=petscii(2)+1:petscii(1)=petscii(1)+1:petscii(0)=petscii(0)+1:petscii(3)=petscii(3)+1:return rem middle buffer, 2 elements petscii2(3)=petscii2(3)+1: petscii2(2)=petscii2(2)+1 return increasescore score=score+1 if score=2 then gosub rebuildsid456a:gosub rebuildsid456a:rem gosub changerefresh if score=4 then gosub rebuildsid456a:gosub rebuildsid456a if score=3 then gosub rebuildsid456a if score=5 then gosub rebuildsid456a rem reverse instrument algorithms and repeat rem if score>5 then for r=1 to 6:gosub rebuildsid456b:next r:score=0 if score=11 then score=0:return if score>4 then gosub rebuildsid456b:rem reverse ADSR algorithm return colorcycle rem if MUSICINDEX>40 or t=0 then return:rem roll dice if MUSICINDEX<210 or by=0 then return:rem roll dice for r=0 to 9 rowcolors(r)=rowcolors(r)+1:rem 17 next r return changerefresh rem freeing l... rem l=1-l:rem refreshrate scripting command for scrollvirtualworld if MUSICINDEX>160 then scrollvirtualworldtoggle=1 else scrollvirtualworldtoggle=0 return hookgameloop2 t=1-t rem 2x slow playback: rem 20210208 SUSTAINFORFRAMES=SUSTAINFORFRAMES+t:goto variableplaybackspeed rem if player0y>100 and 1=1 then SUSTAINFORFRAMES=SUSTAINFORFRAMES+t:goto variableplaybackspeed rem 20201013 4x slow playback: rem 20250502 if t=0 then r=1-r:SUSTAINFORFRAMES=SUSTAINFORFRAMES+r else SUSTAINFORFRAMES=SUSTAINFORFRAMES+t variableplaybackspeed if BITIndex>71 then BITIndex=255:rem overflows to 0 as intended, avoids off by 1 rem --- change color of words! rem if h>36 then goto changewordcolor rem for j=0 to 3:rem rowcolors(j)=$58:rem next:rem rowcolors(9)=$58 rem goto donechangewordcolor changewordcolor donechangewordcolor if x=255 then x=71 if t<>0 then goto tnot0 else z=1-z:x=x-z:BITIndex=BITIndex+1:h=BITIndex:BITIndex=x if f=18 then vwpixel(e,f,bindplayer1) rem scrollvirtualworldtoggle=8:gosub DLI:scrollvirtualworldtoggle=l:BITIndex=h:return: rem else COLUPF=100 rem use MUSICINDEX to determine graphics mode gosub getpetscii:scrollvirtualworldtoggle=8:gosub DLI:gosub changerefresh:BITIndex=h:return: rem else COLUPF=100 tnot0 rem animate character sprite if s>56 then s=0 rem byterowoffset is 120 for 1st DL w=w+1 if w<>3 then goto wnot3 loadplayer0(s) rem g=s+40:loadplayer1(g) rem loadplayer1upsidedown(s) s=s+8:h=BITIndex:BITIndex=u:w=0:v=v+1:BYTErowoffset=v*12 if f=5 then vwpixel(e,f,bindplayer1) rem scrollvirtualworldtoggle=3:gosub DLI:scrollvirtualworldtoggle=l:BITIndex=h:return gosub getpetscii3:scrollvirtualworldtoggle=3:gosub DLI:gosub changerefresh:BITIndex=h:return wnot3 if v>10 then v=0:u=u+20:rem SUSTAINFORFRAMES=4 if u>60 then u=19 rem rem 20231221 player0y=player0y+1:player0x=player0x+1 rem BITIndex=h:rem preserved BYTErowoffset=120 rem petscii full editor activated for any DLI zones? if var1>0 then gosub petsciifulleditor:rem goto skipmoveplayer rem debug this j=2:i=2:rem park mode if joy0down=1 then j=0 if joy0up=1 then j=1 if joy0left=1 then i=0:REFP0=255 if joy0right=1 then i=1:REFP0=0 rem skipmoveplayer rem if joy0down=1 then player0y=player0y-2 rem if joy0left=1 then player0x=player0x-3 rem reverse direction when hitting a wall if i=0 and player0x<5 then i=1:REFP0=0 if j=0 and player0y<12 then j=1 if i=1 and player0x>162 then i=0:REFP0=255 if j=1 and player0y>94 then j=0 rem add inertia for zone (experimental): rem ----------------------------------------- rem debug: rem if player0y>50 then COLUBK=1 else COLUBK=0:rem vwpixel(3,3,flip) if player0y>50 then player0y=player0y+1:goto abovefifty rem 50 or below, check for horizontal inertia rem this handles both lower zones (horizontal inertia in different directions) if player0y>22 then player0x=player0x-2 else player0x=player0x+2 rem ------------------------------- Inertia zone currents end abovefifty rem top zone if i=0 then player0x=player0x-3 if i=1 then player0x=player0x+3 if j=0 then player0y=player0y-2 if j=1 then player0y=player0y+2 rem -- Navigate Directory in SuperCharger File System: rem ------------------------------------------------------------------------------------------------- rem ------------ LOAD one of 3 6K SuperCharger games depending upon which zone the button is pressed! rem ------------------------------------------------------------------------------------------------- if joy0fire=1 and g=1 then g=2:gosub buttonpressed:rem debug/SID 4,5,6 algorithm testing feature rem not in use: rem if joy0fire=0 or MUSICINDEX<40 then goto skipLoad:rem basing delay on what has been initialized here :) rem ---superchargerindex of program to be loaded by SuperCharger ISAM file system rem if player0y<=26 then SUPERCHARGERINDEX=3:goto loadmenu:rem --- modular program1 rem if player0y<=56 then SUPERCHARGERINDEX=2:goto loadmenu:rem --- modular program2 rem SUPERCHARGERINDEX=1:rem default ---- rem -------------------------- loadmenu rem load rem load can also be overloaded with an argument, examples: rem i=5:load i rem load 5 rem load $a skipLoad rem --------------------------------------------------------------------- return charactereditor rem goto Editor1 if q<>0 then goto Editor1:rem music editor t=1-t if g<>0 then return:rem charactereditor initializes g to 0 after setup (reverse of demo/game) rem top blank return rem -------------------------------------------------------------------------------------- getcharl rem based on l, character frame to screen --------------------------------------- rem -------------------------------------------------------------------------------------- rem clear area: for bx=0 to 15:for by=0 to 9:vwpixel(bx,by,on):vwpixel(bx,by,flip):next by,bx m=l+7 loadplayer0(l) n=1 rem map bitmap character at lms l to bitmap virtualworld (big char to edit) for bx=l to m:virtualworld(n)=sprites(bx):n=n+12:next bx rem map sprite colors (fix one off) to large sprite bitmap on virtualworld n=6 for bx=0 to 6 rowcolors(bx)=player0colors(n) n=n-1 next bx rowcolors(9)=player0colors(7) scrollvirtualworldtoggle=1 return flipcharpix rem vwpixel(x,y,flip) rem mirror change on sprite: if x>15 or y>7 then return:rem allow edits to virtualworld beyond character staging j=l+y k=y*12 k=k+1 sprites(j)=virtualworld(k) loadplayer0(l) return hexcolordisplay rem --- display color list values using hexidecimal alphanumerics rem if alt frame move hex alphanumeric over 8 px if y=0 then n=rowcolors(9) else m=y-1:n=rowcolors(m) vwpixel(t,y,bindplayer1) if t=1 then goto otherhexdigit rem first nybble of byte: rem this takes 19 bytes less in asm: lda n: lsr: lsr: lsr: lsr: sta n n=n&%11110000:n=n/16 goto donehexdigits otherhexdigit rem second nybble of byte: n=n&%00001111 player1x=player1x+1 donehexdigits n=n*8:n=n+64:rem 0 character sprite is at 64 in the sprite library loadplayer1(n) rem ?? if y=0 then COLUP1=rowcolors(9) else n=y-1:COLUP1=rowcolors(n) COLUP1=$56 return cloneframe rem ----- clone bitmap of prior sprite frame as template for animation if s=0 and joy0fire=1 and joy0down=1 then s=1 else return i=l-8 for j=i to l k=j+8 sprites(k)=sprites(j) next j gosub getcharl:rem load cloned bitmap return scrollleft rem ---- scroll panoramic for editing bitmap virtualworld: if x-BITIndex=0 and x>0 then BITIndex=BITIndex-1:scrollvirtualworldtoggle=1 rem page up/down in panoramic bitmap image: if y=10 and BYTErowoffset=0 then BYTErowoffset=120:scrollvirtualworldtoggle=1 if y=9 and BYTErowoffset=120 then BYTErowoffset=0:scrollvirtualworldtoggle=1 rem return rem ------------------------------------------------------------- rem end game loop (implicit return)----------------- rem ------------------------------------------------------------- rem ------------------------------------------------------------- rem ---gameloop2 subroutine, runs every frame: -- rem ------------------------------------------------ if SWCHB|%11110111=247 then goto charactereditor2 goto hookgameloop2 rebuildmusic rem create new musical score:" for r=0 to 255 if r=44 or r=74 or r=159 or r=229 then goto skipnote d=MusicData(r)&%00011111 MusicData(r)=d+3:rem 3 skipnote next r rem DisplayList3Shadow(119)=DisplayList3Shadow(119)+1 r=0:rem restore r variable to 0 state, used for music bug (extended sound dilation) and sound dilation rem if DisplayList3Shadow(119)=58 then DisplayList3Shadow(119)=48:DisplayList3Shadow(118)=DisplayList3Shadow(118)+1 return rebuildmusic2 rem create new musical score:" rem for r=0 to 255 rem if r=44 or r=74 or r=159 or r=229 then goto skipnote2A rem d=MusicData(r)&%00001111 rem MusicData(r)=d+5:rem 3 skipnote2A rem next r rem DisplayList3Shadow(119)=DisplayList3Shadow(119)+1 rem r=0:rem restore r variable to 0 state, used for MUSIC DURATION AND MUSIC EXTENDED DURATION BUG rem if DisplayList3Shadow(119)=58 then DisplayList3Shadow(119)=48:DisplayList3Shadow(118)=DisplayList3Shadow(118)+1 rem MUSICINDEX=0 return charactereditor2 rem --- char editor variable map: rem --- l - character frame rem --- g setupvar (reversed for kickout init returning from editor) rem --- r,s button released, stick released while button pressed rem --- x,y tile coordinates for player sprite cursor (editor on editor) rem goto Editor2 if q<>0 then goto Editor2:rem music editor rem setup [when g!0] if g>0 then g=0:BITIndex=0:BYTErowoffset=0 else goto donecharsetup if player0y<30 then REFP0=0:q=1:m=0:var1=0:var2=0:t=0:z=0:goto Editor2:rem init and queue music editor JVB rem C64 drawing graph paper grid for editor with petscii tilemapping: rem BackgroundTileCharacters(0)=207 rem BackgroundTileCharacters(1)=208 rem BackgroundTileCharacters(2)=204 rem BackgroundTileCharacters(3)=250 BackgroundTileCharacters(0)=111 BackgroundTileCharacters(1)=111 BackgroundTileCharacters(2)=32 BackgroundTileCharacters(3)=32 rem TileCharacters(0)=32 rem TileCharacters(1)=32 rem TileCharacters(2)=32 rem TileCharacters(3)=32 l=0:r=0:gosub getcharl:rem get first character frame x=8:y=0:rem cursor upper left t=0 donecharsetup if r=1 and joy0left=0 and joy0fire=0 and joy0right=0 and joy0up=0 and joy0down=0 then r=0:s=0:goto skipctrls if r=0 and joy0right=1 then x=x+1:r=1 if r=0 and joy0left=1 then x=x-1:r=1 if r=0 and joy0up=1 then y=y-1:r=1 if r=0 and joy0down=1 then y=y+1:r=1 rem ---edit panoramic virtualworld scroll to right when edge is reached: if x-BITIndex=19 and x<91 then BITIndex=BITIndex+1:scrollvirtualworldtoggle=1 gosub scrollleft if r=0 and joy0fire=1 then r=1:vwpixel(x,y,flip):gosub flipcharpix rem holding button and pressing right? advance to next frame rem edit advance next frame if s=0 and joy0fire=1 and joy0right=1 then s=1:j=l/8:vwpixel(j,9,flip):l=l+8:gosub getcharl:return rem edit advance prior frame if s=0 and joy0fire=1 and joy0left=1 then s=1:j=l/8:vwpixel(j,9,flip):l=l-8:gosub getcharl:return if s=0 and joy0fire=1 and joy0up=1 then s=1:gosub adjustcolor:return gosub cloneframe:rem sprite character may be templated from prior sprite skipctrls vwpixel(x,y,bindplayer0):set sprite as cursor to edit large sprite image j=l/8 vwpixel(j,9,on):rem marker character frame position gosub hexcolordisplay SUSTAINFORFRAMES=SUSTAINFORFRAMES+t return adjustcolor n=7-y rem increase or decrease: player0colors(n)=player0colors(n)+17 gosub getcharl return rem C64 declare multiple petscii tilemap buffers getpetscii getpetscii1 if score<4 then goto getpetscii4 BackgroundTileCharacters(0)=petscii(0) BackgroundTileCharacters(1)=petscii(1) BackgroundTileCharacters(2)=petscii(2) BackgroundTileCharacters(3)=petscii(3) TileCharacters(0)=tilepetscii(0) TileCharacters(1)=tilepetscii(1) TileCharacters(2)=tilepetscii(2) TileCharacters(3)=tilepetscii(3) return getpetscii2 if score<6 then goto getpetscii4 BackgroundTileCharacters(0)=petscii2(0) BackgroundTileCharacters(1)=petscii2(1) BackgroundTileCharacters(2)=petscii2(2) BackgroundTileCharacters(3)=petscii2(3) TileCharacters(0)=tilepetscii2(0) TileCharacters(1)=tilepetscii2(1) TileCharacters(2)=tilepetscii2(2) TileCharacters(3)=tilepetscii2(3) return getpetscii3 if score<2 then goto getpetscii4 BackgroundTileCharacters(0)=petscii3(0) BackgroundTileCharacters(1)=petscii3(1) BackgroundTileCharacters(2)=petscii3(2) BackgroundTileCharacters(3)=petscii3(3) TileCharacters(0)=tilepetscii3(0) TileCharacters(1)=tilepetscii3(1) TileCharacters(2)=tilepetscii3(2) TileCharacters(3)=tilepetscii3(3) return getpetscii4 BackgroundTileCharacters(0)=32 BackgroundTileCharacters(1)=32 BackgroundTileCharacters(2)=32 BackgroundTileCharacters(3)=32 TileCharacters(0)=102 TileCharacters(1)=230 TileCharacters(2)=102 TileCharacters(3)=230 return rem petscii texture map C64: rem data petscii 209,230,208,208 rem data petscii 208,208,208,208 data petscii 208,208,33,250 rem pattern data petscii2 121,121,121,121 rem parallel lines rem data petscii3 205,206,206,205 rem diagonal fence pattern rem data petscii3 199,199,199,199 rem thickparallel lines data petscii3 210,210,210,210 rem horizontal lines data tilepetscii 210,210,210,210 data tilepetscii2 65,65,65,65 rem data tilepetscii3 205,206,206,205 rem diagonal fence pattern data tilepetscii3 64,64,64,64 rem starfield rem 102,230,102,230 rem ------------------------------------------------------------- rem 20250612 adding music editor, top vertical blank code: data fastm 0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248 Editor1 callalgorithms rem all chiptunes if var1=0 and SWCHB|254<>255 then var1=1:gosub algorithm2:gosub TraceTracker rem 2025024 2nd method to call algorithm2: hold left and press button: if var1=1 and joy0left=1 and joy0fire=1 and m=0 then m=1:gosub algorithm2:gosubTraceTracker rem pattern level if var1=0 and SWCHB|%11111101<>255 then var1=1:gosub algorithmpatt:gosub TraceTracker:rem select rem 2025024 2nd method to call algorithmpatt: hold right and press button: if var1=1 and joy0right=1 and joy0fire=1 and m=0 then m=1:gosub algorithmpatt:gosubTraceTracker if var1=1 and joy0up=1 and joy0fire=1 and m=0 then m=2:gosub algorithmpatt:gosubTraceTracker if var1=1 and joy0down=1 and joy0fire=1 and m=0 then m=1:gosub templatepattern:gosubTraceTracker checktokens rem next token? if var1=0 and joy0right=1 and score<4 then score=score+1:var1=1 rem prior token? if var1=0 and joy0left=1 and score>0 then score=score-1:var1=1 COLUBK=0 rem clear joystick input when stick is centered: (incldue reset, clear when reset is not set) if SWCHB|%11111101=255 and SWCHB|254=255 and joy0right=0 and joy0up=0 and joy0down=0 and joy0left=0 and var1=1 then var1=0:rem same input scheme to move joystick incrementally rem advance to next pattern? if m=0 and joy0fire=1 and MUSICINDEX<245 then m=1:y=y+1:gosub setrowcolors:gosub skipcontrols:return rem gosub checktokens -- done in top vertical blank if var1=0 and joy0up=1 then var1=1:t=1:gosub txpattern if var1=0 and joy0down=1 then var1=1:t=0:gosub txpattern rem --- music editor top vertical blank code --- return rem Muic editor bottom vertical blank code rem -------------------------------------- Editor2 rem setup editor grid: setup TPL Tracker Player list program to return 1st pattern: if z<10 then BITIndex=0:BYTErowoffset=0:NUSIZ1=0:gosub drawmusicscreen:MUSICINDEX=0:gosub TraceTracker:z=10:g=0:score=0:var1=0 COLUBK=5 SUSTAINFORFRAMES=SUSTAINFORFRAMES+1 rem apply shaped volume Fx to voices: if w>0 then w=w-1 else SUSTAINFORFRAMES=2:rem ? AUDV0=w:AUDV1=w if f>2 then f=0 else f=f+1:rem frame if f>0 then goto notframe0 if score=1 then COLUP1=60 else COLUP1=255 if score=0 then bx=60 else bx=255 gosub colorplayer0 rem --- instrument v1 bx=MUSICINDEX:gosub loadvar2 var2=fastm(var2):rem var2*8 rem q=var2:gosub loadplayer0lib2:rem loadplayer0(var2) vwpixel(2,y,bindplayer0) rem --- v1 note bx=MUSICINDEX+1:gosub loadvar2 var2=fastm(var2):rem var2*8 q=var2:gosub loadplayer1lib2:rem loadplayer1(var2) vwpixel(6,y,bindplayer1) goto doneframes notframe0 rem ---- if score=3 then COLUP1=60 else COLUP1=255 if score=2 then bx=60 else bx=255 gosub colorplayer0 if f>1 then goto notframe1 rem --- instrument v2 bx=MUSICINDEX+2:gosub loadvar2 var2=fastm(var2):rem var2*8 q=var2:gosub loadplayer0lib2:rem loadplayer0(var2) vwpixel(11,y,bindplayer0) rem --- v2 note bx=MUSICINDEX+3:gosub loadvar2 var2=fastm(var2):rem var2*8 q=var2:gosub loadplayer1lib2:rem loadplayer1(var2) vwpixel(14,y,bindplayer1) goto doneframes notframe1 rem duration --- rem color both digits for duration (up to 99): if score=4 then COLUP1=60:bx=60 else COLUP1=255:bx=255 rem gosub colorplayer0 rem --- first digit bx=MUSICINDEX+4:gosub loadvar2 j=var2/10:i=b j=fastm(j):rem j*8 q=j:gosub loadplayer0lib2:rem loadplayer0(j) vwpixel(17,y,bindplayer0) rem --- duration second digit (up to 99) i=i*8 q=i:gosub loadplayer1lib2:rem loadplayer1(i) vwpixel(18,y,bindplayer1) doneframes if m<>0 and joy0fire=0 then m=0:rem clear rem --- music editor bottom vertical blank code --- return loadvar2 var2=MusicData(bx) return setvar2 MusicData(bx)=var2 return setrowcolors rowcolors(y)=0 scrollvirtualworldtoggle=1 return txpattern bx=MUSICINDEX+score i=MusicData(bx) if t=1 then i=i+1 else i=i-1 if t=0 and i=255 then return:rem below zero if i=0 and score=4 then return:rem duration must be at least one frame (zero duration indicate4s control frames used to bind subtunes and Fx to game events) MusicData(bx)=i gosub TraceTracker return drawmusicscreen for y=0 to 9:rowcolors(y)=y+4:next y for y=0 to 8:for x=0 to 20 step 4:vwpixel(x,y,flip):next x,y:x=0:y=9:gosub setrowcolors:y=0:gosub setrowcolors return skipcontrols if y=10 then y=0:gosub drawmusicscreen:rem call screen column painter if MUSICINDEX=250 then MUSICINDEX=0:y=0:COLUBK=3:rem loop around to start (tx c olor) bx=MUSICINDEX+9 gosub loadvar2 test3 if var2=0 then MUSICINDEX=MUSICINDEX+10:gosub recolorscreen:gosub setrowcolors:score=0 else MUSICINDEX=MUSICINDEX+5:score=0 TraceTracker SUSTAINFORFRAMES=0:gosub PlayMusic:rem want next pattern 0 duration setting increments MUSICINDEX by 5 MUSICINDEX=MUSICINDEX-5 SUSTAINFORFRAMES=SUSTAINFORFRAMES+1 w=SUSTAINFORFRAMES:rem 20250220 for AUDV0/AUDV1 volume Fx mirror return colorplayer0 for i=0 to 3:player0colors(i)=bx:next i:return algorithmpatt rem one pattern only rem create new musical score g=MUSICINDEX+4 for bx=MUSICINDEX to g rem skip control codes rem -- not necessary since these algorithms are called from accessible patterns only: rem if bx=44 or bx=89 or bx=134 or bx=179 or bx=224 then goto skipnote2 gosub loadvar2 rem 20250224 up plus button = algorithm b applied at pattern level if m=2 then var2=var2&%00011111:var2=var2+5 else var2=var2&%00001111:var2=var2+3 gosub setvar2 rem MusicData(var2)=var2^%00001111+5:rem 3 skipnote2 next bx g=0 return algorithm2 rem create new musical score for bx=0 to 249 rem skip control codes if bx=44 or bx=89 or bx=134 or bx=179 or bx=224 then goto skipnote3 gosub loadvar2 var2=var2&%00001111 var2=var2+3 gosub setvar2 rem MusicData(bx)=var2&%00011111+3:rem 3 skipnote3 next bx return templatepattern rem --- Template prior pattern [composition ctrl] if MUSICINDEX=0 then return:cannot template 1st pattern (templates prior pattern) g=MUSICINDEX+4 for bx=MUSICINDEX to g m=bx-5 var2=MusicData(m):gosub setvar2 rem MusicData(bx)=var2 rem MusicData(bx)=MusicData(m) MusicData(bx)=var2 next bx g=0:m=1 return recolorscreen rem scrollvirtualworldtoggle=1 for y=0 to 8:x=y*16:x=x+7:x=x+y:rowcolors(y)=x:next y:y=0 return loadplayer0lib2 for bx=7 to 0 step -1 player0(bx)=spritelib2(q) q=q+1 next bx q=1:rem restore state return loadplayer1lib2 for bx=7 to 0 step -1 player1(bx)=spritelib2(q) q=q+1 next bx q=1:rem restore state return data spritelib2 %00000000 data spritel001 %00000110 data spritel002 %00001001 data spritel003 %00001001 data spritel004 %00001001 data spritel005 %00001011 data spritel006 %00000110 data spritel007 %00000000 data spritel008 %00000000 data spritel009 %00000110 data spritel00a %00001110 data spritel00b %00000110 data spritel00c %00000110 data spritel00d %00000110 data spritel00e %00000110 data spritel00f %00000000 data spritel00g %00000000 data spritel00h %00001110 data spritel00i %00001001 data spritel00j %00000001 data spritel00k %00000010 data spritel00l %00000110 data spritel00m %00001111 data spritel00n %00000000 data spritel00o %00000000 data spritel00p %00001110 data spritel00q %00000001 data spritel00r %00000001 data spritel00s %00001111 data spritel00t %00000001 data spritel00u %00001110 data spritel00v %00000000 data spritel00w %00000000 data spritel00x %00000001 data spritel00y %00000011 data spritel00z %00000101 data spritel010 %00001111 data spritel020a %00000011 data spritel030 %00000011 data spritel040a %00000000 data spritel050a %00000000 data spritel060 %00001111 data spritel070 %00001000 data spritel080 %00001111 data spritel090 %00000001 data spritel0a0 %00000001 data spritel0b0 %00001111 data spritel0c0 %00000000 data spritel0d0 %00000000 data spritel0e0 %00000110 data spritel0f0 %00001001 data spritel0g0 %00001000 data spritel0h0 %00001110 data spritel0i0 %00001001 data spritel0j0 %00001110 data spritel0k0 %00000000 data spritel0l0 %00000000 data spritel0m0 %00001111 data spritel0n0 %00000011 data spritel0o0 %00000110 data spritel0p0 %00001100 data spritel0q0 %00001100 data spritel0r0 %00001100 data spritel0s0 %00000000 data spritel0t0 %00000000 data spritel0u0 %00000110 data spritel0v0 %00001001 data spritel0w0 %00001001 data spritel0x0 %00000110 data spritel0y0 %00001001 data spritel0z0 %00000110 data spritel011 %00000000 data spritel012 %00000000 data spritel013 %00000110 data spritel014 %00001001 data spritel015 %00001001 data spritel016 %00000111 data spritel017 %00000001 data spritel018 %00000001 data spritel019 %00000000 data spritel01a %00000000 data spritel01b %01100110 data spritel01c %11101001 data spritel01d %01101001 data spritel01e %01101001 data spritel01f %01101011 data spritel01g %01100110 data spritel01h %00000000 data spritel01i %00000000 data spritel01j %01100110 data spritel01k %11101110 data spritel01l %01100110 data spritel01m %01100110 data spritel01n %01100110 data spritel01o %01100110 data spritel01p %00000000 data spritel01q %00000000 data spritel01r %01101110 data spritel01s %11101001 data spritel01t %01100001 data spritel01u %01100010 data spritel01v %01100110 data spritel01w %01101111 data spritel01x %00000000 data spritel01y %00000000 data spritel01z %01101110 data spritel020 %11100001 data spritel021 %01100001 data spritel022 %01101111 data spritel023 %01100001 data spritel024 %01101110 data spritel025 %00000000 data spritel026 %00000000 data spritel027 %01100001 data spritel028 %11100011 data spritel029 %01100101 data spritel02a %01101111 data spritel02b %01100011 data spritel02c %01100011 data spritel02d %00000000 data spritel02e %00000000 data spritel02f %01101111 data spritel02g %11101000 data spritel02h %01101111 data spritel02i %01100001 data spritel02j %01100001 data spritel02k %01101111 data spritel02l %00000000 data spritel02m %00000000 data spritel02n %01100110 data spritel02o %11101101 data spritel02p %01101100 data spritel02q %01101110 data spritel02r %01101001 data spritel02s %01101110 data spritel02t %00000000 data spritel02u %00000000 data spritel02v %01101111 data spritel02w %11100011 data spritel02x %01100110 data spritel030a %01101100 data spritel031 %01101100 data spritel032 %01101100 data spritel033 %00000000 data spritel034 %00000000 data spritel035 %01100110 data spritel036 %11101001 data spritel037 %01101001 data spritel038 %01100110 data spritel039 %01101001 data spritel03a %01100110 data spritel03b %00000000 data spritel03c %00000000 data spritel03d %01100110 data spritel03e %11101001 data spritel03f %01101001 data spritel03g %01100111 data spritel03h %01100001 data spritel03i %01100001 data spritel03j %00000000 data spritel03k %00000000 data spritel03l %11100110 data spritel03m %10101001 data spritel03n %00101001 data spritel03o %01001001 data spritel03p %10001011 data spritel03q %11100110 data spritel03r %00000000 data spritel03s %00000000 data spritel03t %11100110 data spritel03u %10101110 data spritel03v %00100110 data spritel03w %01000110 data spritel03x %10000110 data spritel03y %11100110 data spritel03z %00000000 data spritel040 %00000000 data spritel041 %11101110 data spritel042 %10101010 data spritel043 %00100010 data spritel044 %01000100 data spritel045 %10001000 data spritel046 %11101110 data spritel047 %00000000 data spritel048 %00000000 data spritel049 %11101110 data spritel04a %10100001 data spritel04b %00100001 data spritel04c %01001111 data spritel04d %10000001 data spritel04e %11101110 data spritel04f %00000000 data spritel04g %00000000 data spritel04h %11100001 data spritel04i %10100011 data spritel04j %00100101 data spritel04k %01001111 data spritel04l %10000011 data spritel04m %11100011 data spritel04n %00000000 data spritel04o %00000000 data spritel04p %11101111 data spritel04q %10101000 data spritel04r %00101111 data spritel04s %01000001 data spritel04t %10000001 data spritel04u %11101111 data spritel04v %00000000 data spritel04w %00000000 data spritel04x %11100110 data spritel04y %10101001 data spritel04z %00101000 data spritel050 %01001110 data spritel051 %10001001 data spritel052 %11101110 data spritel053 %00000000 data spritel054 %00000000 data spritel055 %11101111 data spritel056 %10100011 data spritel057 %00100110 data spritel058 %01001100 data spritel059 %10001100 data spritel05a %11101100 data spritel05b %00000000 data spritel05c %00000000 data spritel05d %11100110 data spritel05e %10101001 data spritel05f %00101001 data spritel05g %01000110 data spritel05h %10001001 data spritel05i %11100110 data spritel05j %00000000 data spritel05k %00000000 data spritel05l %11100110 data spritel05m %10101001 data spritel05n %00101001 data spritel05o %01000111 data spritel05p %10000001 data spritel05q %11100001 data spritel05r %00000000 data spritel05s %00000000 data spritel05t %11000110 data spritel05u %00101001 data spritel05v %00101001 data spritel05w %11101001 data spritel05x %00101011 data spritel05y %11000110 data spritel05z %00000000 data spritel060a %00000000 data spritel061 %11000110 data spritel062 %00101110 data spritel063 %00100110 data spritel064 %11100110 data spritel065 %00100110 data spritel066 %11000110 data spritel067 %00000000 rem ------------------------------------------------------------- rem end gameloop2 (implicit return)----------------- rem ------------------------------------------------ rem ------------------------------------------------------------- rem ---KITCHENSINK subroutine, runs when scrollvirtualworldtoggle=1 rem ------------------------------------------------------------- rem kitchensink by=1-by SUSTAINFORFRAMES=SUSTAINFORFRAMES+by if SWCHB|%11110111=247 then goto charactereditorKS gosub hookgameloop1 gosub hookgameloop2 rem gosub increasescore d=s/8 if dn>0 then gosub colorcycle rem - jump over playfield Camera LMS tp preserve display list zones: rem thislabel goto thislabel+5:rem SuperCharger BASIC can jump 5 bytes fwd on Atari rem missing in C64 SuperCharger BASIC so... esacping to Assembly as: "fw6 bvc fw6+5" charactereditorKS rem --------------character frames editor rem character frames editor does not jump over renderer to preserve DLI zones rem -------------------------------------------------------------------- rem end kitchensink events---------------------------------------------- rem -------------------------------------------------------------------- virtualworld ....................................................................xxx..................... ......................XXXXXXXXXXXXX.................................x....................... .....................XX............X................................xxx.....x............... .....................XX..XXXXXXXXX.XX.................................x.x.x.x............... .....................xX..xxx...XXx.xx..XXXXx..X............XX.XXX..X.xx..X..xxx............. .....................xX.XXxX...XXX.xx..XX..X.X.X...........X.XX.X.X.X....X.................. .....................xX.XXXXXXXXXXXxx..XXXXx.xxX..X...x....X.XX.X.XXX....X..x.X............. .....................xX................Xx....x.x..Xx.xxx..xX....X.X.X.......xxx............. ......................XXXXXXXXXXxXxx...XX....x.x..x...X.X.XX....X.X.X....................... ..........................XXXXXXXXxx...Xx....x.x..x...x.xXXX....X.X.X....xx.xxX............. ..........................................................X..............x.x..x............. ........................................................XXX..............x....x............. ............................................................................................ ............................................................................................ ............................................................................................ .XXXxX.xXXX.XXX.X.X.x.xx.xXXX..XX..XXX.XXX.XXX...XXX.X...X..X.X..X..X.X...XXXxX.xXXX.XXX.X.X .XxxxX..xX..X...XX..x.xx.xXxx...X..X.X.X.X.XX....XXX.X..XXX..X..XXX.XXX...Xxxxx..xX..X...XX. .XXx...xXXX.XXX.X.X.xxXx.xX.....XX.XXX.X.X.XXX...X...XX.X.X..X..X.x.X.X...XXX...xXXX.XXX.X.X x.x.x.x.x.x.x.x.x.xX.X.X.X.X.X.X.X.X.X.XxX.X.X.XxX.X.XxX.X.XxX.X.X.X...XxX.X.X.X.X.X.X.X.X.X .x.x.x.x.x.x.x.x.x..X.X.X.X.X.X.X.X.X.XxXxX.X.XxXxX.XxXxX.XxXxX.X.X.X.X.X.X.X.X.X.X.X.X.X.X. player0colors $c3,$c1,$D1,$d1,$b1,$b1,$a1,$a1 rowcolors $42,$42,$42,$42,$c4,$c4,$c4,$b6,$b6,$42 sprites 0 ........ .XX..... X.....X. X.....XX .XXXXX.. .XX..X.. X.....X. ........ 8 ........ .X...... X.X...X. X.....XX .XXXXX.. .XX..X.. .X...X.. ........ 16 ........ .XX..... X.....X. X.....XX .XXXXX.. .X...X.. ..X.X... ........ 24 ........ .X...X.. X....XXX X..XXX.. .XXXXXX. .X...X.X ..X.X... ........ 32 ........ XX....X. X.....XX XX.XXX.. .XXXXXXX .X...X.. XX....X. ........ 40 ........ XX...X.. X....XX. X..XXX.. .XXXXXXX .XX..X.. ..X...X. ..X..... 48 ........ .....X.. XX...XX. X...XX.. X.XXXXXX XXXXXX.. ..XX..X. ..XX.... 56 ........ ....XX.. ....X... ..XXXX.x ..xXX.X. x..XXX.. .xX...x. .....x.. 64 xxxxxxxx xx....XX Xx....XX XX....xx xxxx..xx Xxxx..XX Xxxx..xx xxxxxxxx 56x ..xxx... .xxxx... ..xxx... ..xxx... ..xxx... .xxxxx.. .xxxxx.. .xxxxx.. 64 ........ xxxxxxxx ......xx ......xx xxxxxxxx xxxx.... xxxx.... xxxxxxxx 72 xxxxxxx. ......x. ......x. ......x. xxxxxxxx ......xx ......xx xxxxxxxx 80 xx...... xx...... xx...... xx...xx. xxxxxxx. .....xx. .....xx. .....xx. 88 ........ xxxxxxxx xx...... xx...... xxxxxxxx ....xxxx ....xxxx xxxxxxxx 96 ........ xxxxxxxx xx....xx xx...... xxxxxxxx xx....xx xxxx..xx xxxxxxxx 104 xxxxxxxx xxxxxxxx xx...xxx ....xxx. ...xxx.. ...xxx.. ...xxx.. ...xxx.. 112 .xxxxxx. .x....X. .x....X. XXxxxxxx xx....xx Xxxx..XX Xxxx..xx xxxxxxxx 120 xxxxxxxx x.....xx x....xxx xxxxxxxx ......xx ......xx ......xx ......xx xxxxxxx. xx....X. xx....X. XXxxxxxx xx....xx Xx....XX Xx....xx xx....xx xx...... xx...... xx...... XXxxxxx. xx....xx Xx....XX Xx....xx xxxxxxx. ........ ........ ........ .Xxxxxx. xx...... Xx...... Xx...... .xxxxxx. ......xx ......xx ......xx .Xxxxxxx xx....xx Xx....XX Xx....xx .xxxxxxx xxxxxxx. xx...... xx...... XXxxxxx. xx...... Xx...... Xxxxxxx. xxxxxxx. xxxxxxx. xx...... xx...... XXxxxxx. xx...... Xx...... Xx...... Xx...... xxxxxxx. xx....x. xx...... XX...... xx..xxx. Xx...xx. Xxxxxxx. xxxxxxx. chiptunes 4,23,4,17,29 16,9,13,21,9 0,18,0,14,34 36,18,15,16,25 35,16,30,10,34 0,19,0,12,48 33,16,30,10,34 0,16,0,16,34 0,16,0,16,9 0,18,0,14,34 0,18,0,14,34 0,7,0,21,06 1,16,30,10,10 6,20,6,20,10 6,20,6,20,8 6,17,6,5,34 6,17,6,28,34 6,11,6,11,34 26,26,26,26,10 26,26,26,26,10 30,25,6,17,34 30,25,6,17,34 30,14,6,27,26 30,17,6,17,34 30,21,6,21,34 30,18,6,18,34 30,21,6,12,34 30,14,8,31,40 30,21,6,18,27 30,21,4,9,64 30,19,6,28,31 30,21,6,12,34 26,26,26,26,10 0,21,0,7,34 0,14,0,3,48 0,18,0,14,34 0,18,0,14,34 0,16,0,16,34 26,24,26,29,18 0,16,0,16,34 0,16,0,16,34 0,26,0,14,34 0,18,0,14,34 0,7,0,21,6 30,25,30,31,8 26,26,26,26,34 30,11,30,1,34 30,11,30,1,34 30,13,33,21,34 0,18,0,14,48 0,0,0,0,0