rem --------------------------------------------------------- rem ---Ring Raiders C64 Atari 2600 SuperCharger BASIC program rem ---Protect the 9 Rings of Saturn with Photon Torpedoes & Rainbows rem ---Star Raiders and Star Ship genre rem ---------------------------------------------------------------------------------- rem --- 20250102 Streamlining for Atari 2600 (removing Tracker Editor, etc)... rem --- Beta running with 2029 & 2039 of 2048 bytes in banks 1 & 3 rem --- todo: Find intermittent frame going over cycle... found main spot where m=7... rem --- Add starfield (crunch to fit) rem --- Add AI algorithm to rebuild music in system bank (~200 bytes free)... rem --- 20250108 loadbalanced over cycle frameskip to gameloop2; bottom vertical blank cycles rem ---------------------------------------------------------------------------------- rem --- 20241019 Added twinkling stars and stars moving Fx behind Rings rem --- 20241019 Color coded TIE Fighter class status indicator rem --- 20241012 Added 3D TIE Fighter rem --- Hi score timer persist hi score every 5 minutes if current hi exceeded.... rem --- 29241010 Patched Tracker module to return to main SID tune after edit rem --- 20241007 RC5 reset MUSICINDEX to zero when exiting Editor (minor) rem --- 20241003 RC4 add the ability to display and edit pattern [freeze display hear sound Tx] rem --- 20241002 SIDFx try changing SID4,SID5,SID6 arrays ... test dynamic instrument revision... rem --- 20241002 RC3 increase speed on warp (always fast forward)... rem --- 20240921 added photon torpedeoes to 3d cube cargo ship too rem --- and increased challenge for missed photon torpedoes... rem ---20240920 added explosion when Saucer or 3D cube are hit (4 frames...) rem and when Saucer or 3D cube impact the Ring (ring pieces in explosion) rem ---20240920 Saucer shoots Photo Torpedeo at player if above horizon or close (alt w/sidewinder) rem ---no harm to player if Torpedeo is dodged... rem ---20240919 adding horizontal drift to 3D objects (testing optimization) rem ---20240918 tuned relative spatial movement coordinate geometry for 3D floating Fx rem ---20240911 horizon expansion demo b, multicolor frontier rem ---(scale sprites across 3 expanding color illusion zones like Rainbow Walker!) rem ---20240903 Last Star Fighter 3D / 2.5D expanding rings like Buck Rogers/Solaris perspective rem ---20240830 inspiration from Star Raiders cover art showing Saturns Rings. rem --- rem ------------------------------------------------------ rem ---Tracker script programmable demo in the game: -- rem ------------------------------------------------------ rem ---Holding the Button long enough loads a new SID rem ---moving stick in 4 directions plays chords or subtunes rem ---when held or released, main tune resumes after. rem ---New Tracker controls: rem ---shift-lock or holding left shift = Space Waltz mode rem ---left shift + left = new SID using algoritm 2 rem ---left shift + right = Starts Tracker Editor rem ---left shift + up/down = algorithms revise SID instrument array (Tracker has 39 instruments) rem ------------------------------------------------------ rem --- sid 21/31 ring 5 nice combination... rem ---------------------------------------------------------------------------------- rem -- variable map rem -- p color seed var (excludes 0, background color black) rem -- q,r temp vars used by color routines rem -- m delay counter (in frames) to call palette switching routine rem -- t alt frame toggle (0,1) rem -- n Fx for palette switching (0 color chaser, 1 red & blue, 2, b&w greyscale, etc) different rem -- x,y,z,w,v screamer x,y,pos index,sprite animation,player0/missile0 size bitmask rem -- f counter for next SID (130 frames button held) rem -- e,h sidewinder weapon x,y rem -- g = Photo Torpedo, missle1 in action and used in rebuidmusic levelup (repos missile) rem -- s - 1 up slow, 2 down slow (when stick is not engaged) rem -- l Rainbow Rings frames delay duration rem -- o holds n index rem -- k enemy weapon toggle (alternates) sidewider or Saucers Photon Torpedeo rem -- i,j saucer and 3d cube explosion state (0 no explosion), i is reused in rebuildmusic rem ---u extra saucer or cube attack rem ---var1 used to hook left shift/shift-lock/bwcolor & and stick up/down to Tx instruments rem ---var1,var2,bx,by,score used by Tracker Editor (cannot Tx instruments from Editor) rem ---(reusing px) px hiscore timeout (3 minutes play to obtain highest score/ StarShip scoring system rem -- py (0/1) toggle between green 3Dcube and 3D TIE Fighter rem ----------------------------------------- rem ---init section, runs once: ------------- rem ----------------------------------------- gosub testr rem --- 20241002 SIDFx try changing SID4,SID5,SID6 arrays ... test dynamic instrument revision: rem gosub rebuildsid456a rem passing line fx rem HMBL = $FF rem WSYNC = $C0 : HMOVE = $C0 rem ENABL=2 rem HMBL = $C0 missile1x=80:s=1 h=45:k=0 rem rem for x=1 to 20:gosub rebuildmusic:next x rem data titles "RINGWORLD=0 RAINBOWMETER=000 SID=00" rem for x=0 to 60 rem iF x<4 then y=80+x:w=titles(x):w=w-64:DisplayList3Shadow(y)=w :rem titles(x)-65 rem iF x<37 and x>33 then y=80+x:w=titles(x):w=w-64:DisplayList3Shadow(y)=w :rem titles(x)-65 rem DisplayList3Shadow(87)=128 rem 20241005 preserve initial musical score... rem f x<20 then gosub rebuildmusic:rem advance SID rem next x rem DisplayList3Shadow(154)=53:rem display 5 as median SID 4,5,6 set SID Orchestra reference got playah... rem DisplayList3Shadow(119)=48:DisplayList3Shadow(118)=48 rem hiscore rem DisplayList3Shadow(105)=48:DisplayList3Shadow(106)=48:DisplayList3Shadow(107)=48 q=8:r=4:n=1 rem DisplayList3Shadow(85)=49:rem Starts on RING 1 initscore rem DisplayList3Shadow(111)=48:DisplayList3Shadow(110)=48 rem DisplayList3Shadow(109)=48 return incp p=p+1 if p=16 then p=1 return newsidewinder rem 20240920 alternate sidewinder with Saucers Photon Tordpedeo if Saucer is far away: rem 20240921 allow 3dcube to use photo torpedeo if Saucer is too far away... if k<>0 then goto knot0 repeatphotonshot if player1y>45 then k=1:e=player1x+4:h=player1y-3:return rem - this launches more photon torpedoes... trythis k=1:e=x:h=y:return knot0 k=0 e=0:h=screamers(z):z=z+1 return screamerrender rem ----------------------------------------------------------------- rem moving this to fix cube animation! otherise some w values missed rem --- dont think this can move... rem 20250109 tuning object animation (not a bug) if w<4 then w=w+1 else w=0 rem 3D cube and Tie Fighters look better at this animation rate: if w<4 then w=w+t else w=0 if y=0 then v=0:y=92:x=screamers(z):z=z+1 if z>32 then z=0 y=y-2 rem 20250102 if y<2 then j=5:player0y=7:gosub decreasescore:rem change back color fx removed, add sound Fx? rem if y<2 then j=5:player0y=7: rem change back color fx removed, add sound Fx? rem push to outside loop when t=1 rem sprite 1 multiplexed alternate () sidewider weapon (e,h) rem 20250102 freeing ROM/total bank 1 memory used by RAM array access... rem if k=0 then e=e+4:player0colors(1)=4:goto donek if k=0 then e=e+4:goto donek rem 20250102 freeing ROM/total bank 1 memory used by RAM array access... rem h=h-6:player0colors(1)=h/2 h=h-6 if e<80 then e=e+5 else e=e-5:rem homing beam, check if within range when hit [decrease score] donek rem if h<5 then gosub newsidewinder:rem altenates with saucher photon torpedeo rem wait for wraparound to reach ... if h>245 then gosub decreasescore:gosub newsidewinder:rem altenates with saucher photon torpedeo if e>160 then gosub decreasescore:gosub newsidewinder:rem altenates with saucher photon torpedeo rem if h>245 then gosub newsidewinder:rem altenates with saucher photon torpedeo rem if e>160 then gosub newsidewinder:rem altenates with saucher photon torpedeo if z>32 then z=0 skipnextj rem sprite 2 if player1y=0 then gosub rebuildsaucer if z>32 then z=0 rem flip sprite 4 different ways, backwards/upsidedown: if i=0 then goto normalsaucer else i=i-1 if i=1 then loadplayer1(64):REFP1=0:rem 40 is explosion sequence animatino if i=2 then loadplayer1upsidedown(56):REFP1=255 if i=3 then loadplayer1upsidedown(48):REFP1=0 if i=4 then loadplayer1(40):REFP1=255 if i=0 then gosub rebuildsaucer:gosub maybesaucerattack goto donesaucer normalsaucer if w=0 then loadplayer1(24):REFP1=0:rem 24 is Saucer if w=1 then loadplayer1upsidedown(24):REFP1=255 if w=2 then loadplayer1upsidedown(24):REFP1=0 if w=3 then loadplayer1(24):REFP1=255 player1y=player1y-4 donesaucer rem --changing back color bad Fx --- if player1y<4 then COLUBK=1:player1y=0 rem 20250102 if player1y<4 then player1y=7:i=5:gosub decreasescore:rem add sound Fx? rem if player1y<4 then player1y=7:i=5:rem add sound Fx? rem now scale sprite based on zone using NUSIZ0 000 , 101, 111 (last 3 bits) d=0:rem v&%00000000 --------- d is a tempvar, not using v (v is preserved) if player1y<31 then d=%00000111:goto donescaleplayer1 if player1y<52 then d=%00000101 donescaleplayer1 rem if missile1y<31 then d=d|%00110000:goto donescaleplayer1b if missile1y<52 then d=d|%00110000 donescaleplayer1b rem and (missile 1 too) NUSIZ1=d :rem v&%00000000 if r>0 then COLUP1=r else COLUP1=15 return decreasescore rem --- only take away points in 1's and 10 digit column... encourages 100 point incremental goals! rem if DisplayList3Shadow(111)>48 then DisplayList3Shadow(111)=DisplayList3Shadow(111)-1:return rem if DisplayList3Shadow(110)=48 then return rem DisplayList3Shadow(111)=53:DisplayList3Shadow(110)=DisplayList3Shadow(110)-1 rem 220250103 reusing px variable in place of C64 screen RAM to count 10 hits for Warp Fx if px>0 then px=px-1 return rem tilemap screamers to relative BITIndex rem data screamers 1,5,10,4,15,11,19,3,7,2,18,16,12,6,15,3,18,1,4,7,11,4,14,17,12,13,2,3,16,4,17,18,3,19,5,6,11,14,8,19,13,2,14,19,1,5,4,12 rem overlay x,y coordinates data screamers 10,50,100,40,150,110,30,90,152,8,16,45,20,130,95,115,150,110,30,90,152,80,20,40,150,125,22,110,5 rem if screamers hit last row increment border color or flash screen for M frames (better, M can set COLUBK=0) rem ------------------------------------------------ rem ---gameloop subroutine, runs every frame: --- rem ------------------------------------------------ rem 30/25 or 60/50 Hz Fx: leave MBR filter on/off in template scrollvirtualworldtoggle=1 t=1-t:rem toggles variable between 0 and 1 rem 202409919 Horizontal cross drift for 3D objects -------- horozontaldrift if m<>2 then goto horozontaldrift2 if screamers(z)<40 then player1x=player1x+3:goto donehorizontaldrift else player1x=player1x-2:goto donehorizontaldrift horozontaldrift2 if m<>5 then goto donehorizontaldrift if screamers(z)<60 then x=x+2 else x=x-2:rem ai drift driven off of z index to center on z axis ;) rem ... remember to seed random generator for z... donehorizontaldrift rem -------------------------------------------------------- rem 20250109 loadbalancing moving this to the bottom vertial blank if l>0 then l=l-1 if l=1 then n=o:gosub advancepallette rem ---this caused ineresting Fx on scaled 3D cube, perhaps make intermittent? v=%00000000 if t=0 then goto skipt1: rem need this for sidewinder? rem flip sprite 4 different ways, backwards/upsidedown: rem py alternates with 40 and 72 (cube or ship, shoud have different color too) if j=0 then goto load3dcubenormally else j=j-1 if j=1 then loadplayer0(64):REFP0=0 if j=2 then loadplayer0upsidedown(56):REFP0=255 if j=3 then loadplayer0upsidedown(48):REFP0=0 if j=4 then loadplayer0(40):REFP0=255 rem 20250102 removed reference to C64 screen location DisplayList3Shadow(87): rem if j=0 then py=1-py:DisplayList3Shadow(87)=DisplayList3Shadow(87)+py:gosub rebuild3dcube:gosub maybesaucerattack:rem maybe3dcubeattack too! :) if j=0 then py=1-py:gosub rebuild3dcube:gosub maybesaucerattack:rem maybe3dcubeattack too! :) player0colors(0)=8-j goto done3dcube load3dcubenormally rem TIE Fighter if py=0 then goto load3dcube rem player0colors(0)=player0y/20 rem player0colors(0)=15:rem player0x/16 rem 20250102 now need Atari 2600 fade colors for TIE fighers in color RAM array player0colors(0-7) ... rem if DisplayList3Shadow(87)=144 then DisplayList3Shadow(87)=128 else player0colors(0)=DisplayList3Shadow(87)&%01111111 if w=0 then loadplayer0(72):REFP0=0 if w=1 then loadplayer0upsidedown(80):REFP0=0 if w=2 then loadplayer0(72):REFP0=255 if w=3 then loadplayer0(96):REFP0=255 goto almostdone3dcube load3dcube rem green player0colors(0)=5 if w=0 then loadplayer0(8):REFP0=0 if w=1 then loadplayer0upsidedown(8):REFP0=255 if w=2 then loadplayer0upsidedown(8):REFP0=0 if w=3 then loadplayer0(8):REFP0=255 almostdone3dcube player0y=y:player0x=x done3dcube if y<31 then v=%00000111:goto donescaleplayer0 else v=0 rem if y<52 then v=%11110101:goto donescaleplayer0 if y<52 then v=%00000101:rem goto donescaleplayer0 donescaleplayer0 rem NUSIZ0=v rem goto skipt0 skipt1 rem now using missile1, not skipped... no multiplexing rem if e=0 or t=1 then goto skipt0 rem t0 -- multiplex sidewinder: rem flip sprite 4 different ways, backwards/upsidedown: missile0y=h:missile0x=e if h<48 then v= v|%11110000 NUSIZ0=v if w>2 then missile0y=missile0y-2 else missile0y=missile0y+2 donescaleplayer0a skipt0 rem ----------------------------------------------------- rem twinkle stars m=m+1 rem -- 20240921 deactivating this - to hectic to watch double speed palette switching on top of fast scrolling... rem if m<>3 then goto skipdoublespeedscroll: rem -----------faster palette switching when speeding rem if joy0up=1 or joy0down=1 then goto fasterinmotion skipdoublespeedscroll return:rem --------------------loadbalancing test - call from bottom vertial blank "gosub loadbalanceframeskiploadbalanceframeskip" loadbalanceframeskip if m<7 then goto skiprowcoloring m=0 rem HMM0 = $FF rem WSYNC = $C0 : HMOVE = $C0 rem " nop" rem ENAM0=2 rem HMM0 = $C0 rem passing line fx rem HMBL = $FF rem WSYNC = $C0 : HMOVE = SUSTAINFORFRAMES:rem $C0 rem ENABL=2 rem HMBL = SUSTAINFORFRAMES :rem $C0 rem if TileCharacters(0)<>123 and t=1 then TileCharacters(0)=123 else TileCharacters(0)=46 rem if TileCharacters(3)<>123 and t=0 then TileCharacters(3)=123 else TileCharacters(3)=46 fasterinmotion d=q:q=r:r=d:rem swap q and r COLUBK=0 gosub alternaterowcolors if s=1 and joy0up=0 then BYTErowoffset=BYTErowoffset-12: if s=2 and joy0down=0 then BYTErowoffset=BYTErowoffset+12:rem slow drift down return:rem 20250102 patching likely over cycle skiprowcoloring if score>0 then goto donehit:rem 20241005 (tracker editor is active) rem set right/left ring boundries? rem if joy0right=1 and BITIndex<71 then MUSICINDEX=45:BITIndex=BITIndex+1:s=1:gosub adjustright rem if joy0left=1 and BITIndex>0 then MUSICINDEX=75:BITIndex=BITIndex-1:s=1:gosub adjustleft if joy0right=1 then MUSICINDEX=45:BITIndex=BITIndex+1:s=1:gosub adjustright if joy0left=1 then MUSICINDEX=75:BITIndex=BITIndex-1:s=1:gosub adjustleft if joy0up=1 then MUSICINDEX=160:BYTErowoffset=BYTErowoffset-12:s=1:gosub speedup:goto pickupmain rem 20241002 warp forward when The Rainbow is active rem superflous, joy0up already 0 if n=0 and joy0up=0 then BYTErowoffset=BYTErowoffset-12:s=1:gosub speedup:goto pickupmain if n=0 then BYTErowoffset=BYTErowoffset-12:s=1:gosub speedup:goto pickupmain if joy0down=1 then MUSICINDEX=230:BYTErowoffset=BYTErowoffset+12:s=2:gosub slowdown pickupmain if SWCHB|%11110111=247 and t=1 then SUSTAINFORFRAMES=SUSTAINFORFRAMES+1:gosub shiftlocktogglebw rem hit something? stream colors and allow a new palette to be selected if not in motion... rem --------------- rem 20240921 hitting floating pieces of the ring or photon torpedoes does not increase score: rem (but missing them decreases score) if CXPPMM & %01000000>0 then k=0:gosub newsidewinder:CXCLR=0:goto donehit:rem hit satellite rem if CXM1P & %01000000>0 then player1y=92:player1x=missile0x:CXCLR=0:gosub increasescore:goto donehit:rem --- rainbow pushes triangle back to top! if CXM1P & %01000000>0 then i=5:CXCLR=0:gosub increasescore:goto donehit:rem --- rainbow pushes triangle back to top! rem tst if CXM1P & %10000000>0 then y=92:v=0:x=player1x+7:CXCLR=0:gosub increasescore tst if CXM1P & %10000000>0 then j=5:CXCLR=0:gosub increasescore donehit rem 20241007 -- persist hi score with px counter rem -- 20240102 freeing cycles still over .... if px>29 then gosub persisthiscore rem -- 20240102 freeing cycles still over .... if f=0 then px=px+1 rem 20241009 fall thru opt saving cycles if joy0fire=1 and f=0 then f=130 else f=f-1:return rebuildmusic rem create new musical score and instrument defs:" rem for i=0 to 255 rem if i=44 or i=74 or i=159 or i=229 then goto skipnote rem d=MusicData(i)&%00011111 rem MusicData(i)=d+3:rem 3 skipnote rem next i:DisplayList3Shadow(119)=DisplayList3Shadow(119)+1 rem i=0:rem restore i variable to 0 state, used for explosion status of Saucer rem if DisplayList3Shadow(119)=58 then DisplayList3Shadow(119)=48:DisplayList3Shadow(118)=DisplayList3Shadow(118)+1 return slowdown if m>2 then return if y<96 then y=y+1 if player1y<96 then player1y=player1y+1 if h<94 then h=h+1:rem missile0y=missile0y+1 return speedup rem y ... if player0y>4 then player0y=player0y-1 if t=1 then return if y>4 then y=y-1 if player1y>4 then player1y=player1y-1 if h>4 then h=h-1:rem missile0y=missile0y-1 return adjustleft x=x+5 player1x=player1x+5 if t=1 then e=e+2:rem missile0x=missile0x+3 return adjustright x=x-5 player1x=player1x-5 if t=1 then e=e-2:rem missile0x=missile0x-3 return maybesaucerattack u=u+1 if u=5 then u=0:k=0:gosub newsidewinder return rem data paletter 5,5,2,3,12,4,14,7,8,1 rem data paletteq 13,13,6,14,11,10,6,8,4,15 rem adding 1st nybble for Atari2600 (otherwise greyscale) rem data paletter $55,$d5,$22,$33,$cc,$44,$ee,$77,$88,$11 rem data paletteq $dd,$5d,$66,$ee,$bb,$aa,$66,$88,$44,$ff rem expanding to 18 data paletter $55,$d5,$22,$33,$cc,$44,$ee,$77,$88,$11,$2c,$84,$0e,$5a,$cc,$4a,$4e,$94,$9c,$b8 data paletteq $dd,$5d,$66,$ee,$bb,$aa,$66,$88,$44,$ff,$28,$de,$42,$54,$c6,$dc,$44,$9a,$98,$bc rem ------------------------------------------------ rem ---gameloop2 subroutine, runs every frame: -- rem ------------------------------------------------ rem loadbalancing -(Televisions bottom vertical blank cycle space)- gosub loadbalanceframeskip rem end loadbalancing rem COLUBK=12 if missile1y=0 and joy0fire=1 and g<>15 then g=15:rem flag in action if g=15 then missile1y=missile1y+2 else goto skipmissile1 if missile1y>96 then g=0:missile1y=0:missile1x=80 if joy0left=1 and t=0 then missile1x=missile1x-4 if joy0right=1 and t=1 then missile1x=missile1x+4 skipmissile1 if score=0 then return:rem score is musical score being edited :) rem ---- call tracker editor ------ if SUSTAINFORFRAMES<5 then SUSTAINFORFRAMES=5:rem SUSTAINFORFRAMES+1 if score=1 then MUSICINDEX=0:gosub drawtrackergui:score=2:return if score>1 then by=score-2:bx=MUSICINDEX+by:gosub doedit:rem edit all 5! rem if score=2 then bx=MUSICINDEX:gosub doedit:rem edit v1 note rem if score=3 then bx=MUSICINDEX+1:gosub doedit:rem v1 instrument rem checknext if score=7 then goto checknext:rem debug on next return rem ------------------------------------------------------------------------ rem --- relocated subroutines from 1st gameloop (reserved memory exceeded): rem ------------------------------------------------------------------------ rem 20250102 2143 reverse orign in bank 1, relocating more: rem 2091 reverse orign, closer... rem 2055 reverse origin, closer still... decp p=p-1 if p=0 then p=15 return rem releasesaucer rem player1y=0:gosub decreasescore:i=0:rem i is explosion flag rem return rebuildsaucer player1y=92:player1x=screamers(z):z=z+1:rem too aggressive... k=0:gosub newsidewinder rem if crashes? if m=3 then k=0:gosub newsidewinder rem works k=0:gosub newsidewinder return rem release3dcube rem y=0:gosub decreasescore:j=0:v=0:rem i is explosion flag v is scaling facor rem return rebuild3dcube y=92:x=screamers(z):z=z+1 return increasescore rem if t=1 then return rem DisplayList3Shadow(111)=DisplayList3Shadow(111)+1 rem if DisplayList3Shadow(111)<>58 then return rem DisplayList3Shadow(111)=48:DisplayList3Shadow(110)=DisplayList3Shadow(110)+1 rem 20250103 reusing px variable in place of C64 screen RAM to count 10 hits for Warp Fx if px>16 then px=0 else px=px+1:return o=n:n=0:l=255:rem Rainbow Rings Fx! rem if DisplayList3Shadow(110)<>58 then return rem DisplayList3Shadow(110)=48:DisplayList3Shadow(109)=DisplayList3Shadow(109)+1 gosub testr:rem include tennuous Rings! 2025 RC8 return advancepallette if n<19 then n=n+1 else n=1 r=paletter(n):q=paletteq(n) rem DisplayList3Shadow(85)=48+n return rebuildsid456a rem 20241002 rebuild instrument defintions - sounds better rem for bx=0 to 32 rem 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 rem SID5(bx)=SID5(bx)+2 rem SID6(bx)=SID6(bx)+2 rem next bx rem DisplayList3Shadow(154)=DisplayList3Shadow(154)+1 return rebuildsid456b rem 20241002 rebuild instrument defintions - reverse direction rem for bx=0 to 32 rem SID4(bx)=SID4(bx)-2:rem SID4(bx)=SID4(bx)&%11110111 rem SID5(bx)=SID5(bx)-2 rem SID6(bx)=SID6(bx)-2 rem next bx rem DisplayList3Shadow(154)=DisplayList3Shadow(154)-1 return rebuildmusic2 rem create new musical score and instrument defs:" rem for i=0 to 255 rem if i=44 or i=74 or i=159 or i=229 then goto skipnote2 rem d=MusicData(i)&%00001111 rem MusicData(i)=d+5:rem 3 skipnote2 rem next i:DisplayList3Shadow(119)=DisplayList3Shadow(119)+1 rem i=0:rem restore i variable to 0 state, used for explosion status of Saucer rem if DisplayList3Shadow(119)=58 then DisplayList3Shadow(119)=48:DisplayList3Shadow(118)=DisplayList3Shadow(118)+1 rem MUSICINDEX=0 return shiftlocktogglebw rem ---- either bw color switch or left shift/shift lock thrown rem --------- if var1=0 and joy0up=1 then var1=1:gosub rebuildsid456a:return if var1=0 and joy0down=1 then var1=1:gosub rebuildsid456b:return if var1=0 and joy0left=1 then var1=2 if var1=1 and joy0up=0 and joy0down=0 then var1=0 if var1=2 and joy0left=0 then var1=0:gosub rebuildmusic2:rem avoid starting left subtune rem 20250109 (locked cam when BW switch was engaged) if joy0right=1 then score=1:rem was gosub editpattern return persisthiscore rem DisplayList3Shadow(109),DisplayList3Shadow(110),DisplayList3Shadow(111) rem reusing px px=0 m=3:COLUBK=5 rem goto setthiscore:rem debug rem if DisplayList3Shadow(109) < DisplayList3Shadow(105) then goto resetscore rem if DisplayList3Shadow(109) = DisplayList3Shadow(105) and DisplayList3Shadow(110) < DisplayList3Shadow(106) then goto resetscore rem if DisplayList3Shadow(110) = DisplayList3Shadow(106) and DisplayList3Shadow(111) < DisplayList3Shadow(107) then goto resetscore sethiscore rem DisplayList3Shadow(105)=DisplayList3Shadow(109):DisplayList3Shadow(106)=DisplayList3Shadow(110):DisplayList3Shadow(107)=DisplayList3Shadow(111) resetscore gosub initscore: rem same as below rem DisplayList3Shadow(109)=48:DisplayList3Shadow(110)=48:DisplayList3Shadow(111)=48 return alternaterowcolors rem expects i and j to have colors if n=0 then gosub incp:q=p*16:rem 20250111 rem rowcolors(8)=q: rem bottom row rem rowcolors(7)=q:rem 2nd up from bottom rem rowcolors(6)=q:rem 3rd up from bottom rem space saving: for f=6 to 8:rowcolors(f)=q:next f:rem reused counter for next SID when button is held if n=0 then gosub incp:r=p*16 rem rowcolors(5)=r:rem 4th up from bottom rem rowcolors(4)=r:rem 5th up from bottom for f=4 to 5:rowcolors(f)=r:next f:f=75:remreused counterf2again; needed more space,,, if n=0 then gosub incp:q=p*16 rowcolors(3)=q:rem 6th up from bottom if n=0 then gosub incp:r=p*16 rowcolors(2)=r:rem 7th up from bottom rem one more row... if n=0 then gosub incp:q=p*16 rowcolors(1)=q:rem 6th up from bottom rem --keep top 3 rows black for fade fx over the horizon rowcolors(0)=0:rem 2nd rowcolors(9)=0:rem top row rem rowcolors(1)=0:rem 3rd if n=0 then gosub decp:gosub decp:gosub decp:gosub decp:gosub decp:gosub decp gosub screamerrender return testr for f=239 to 0 step -1 rem virtualworld(f)=0 rem f=virtualworld(f) rem virtualworld(f)=f^255 virtualworld(f)=virtualworld(f)^255 next f return rem -----------------------TRACKER EDITOR INGAME------------------------------ rem editpattern rem --- input causes CRT jump like a ZX80 at 30/25 Hz rem ------------color coded editor with syntax checking, like vim or vi ;) doedit rem hilight cursor rem if score=2 then DisplayList3ShadowColor(8)=1:DisplayList3ShadowColor(9)=1:DisplayList3ShadowColor(31)=14:goto editj:rem 1st datum rem if score=3 then DisplayList3ShadowColor(8)=14:DisplayList3ShadowColor(9)=14:DisplayList3ShadowColor(13)=1:DisplayList3ShadowColor(14)=1:goto editj rem if score=4 then DisplayList3ShadowColor(13)=14:DisplayList3ShadowColor(14)=14:DisplayList3ShadowColor(18)=1:DisplayList3ShadowColor(19)=1:goto editj rem if score=5 then DisplayList3ShadowColor(18)=14:DisplayList3ShadowColor(19)=14:DisplayList3ShadowColor(23)=1:DisplayList3ShadowColor(24)=1:goto editj rem if score=6 then DisplayList3ShadowColor(23)=14:DisplayList3ShadowColor(24)=14:DisplayList3ShadowColor(28)=1:DisplayList3ShadowColor(29)=1:goto editj rem if score=7 then DisplayList3ShadowColor(28)=14:DisplayList3ShadowColor(29)=14:DisplayList3ShadowColor(31)=1 editj rem if joy0right=0 and joy0up=0 and joy0down=0 and var1=1 then var1=0:rem same input scheme to move joystick incrementally rem if joy0up=1 and var1=0 and score=7 then var1=1:score=2:gosub skipcontrols:return:rem next pattern rem if joy0down=1 and var1=0 and score=7 then var1=1:score=2:gosub skipcontrols:return:rem next pattern rem if joy0up=1 and MusicData(bx)<38 and var1=0 then var1=1:MusicData(bx)=MusicData(bx)+1:SUSTAINFORFRAMES=0:gosub PlayMusic:MUSICINDEX=MUSICINDEX-5:gosub drawtrackergui:SUSTAINFORFRAMES=SUSTAINFORFRAMES+1 rem if joy0down=1 and MusicData(bx)>0 and var1=0 then var1=1:MusicData(bx)=MusicData(bx)-1:SUSTAINFORFRAMES=0:gosub PlayMusic:MUSICINDEX=MUSICINDEX-5:gosub drawtrackergui:SUSTAINFORFRAMES=SUSTAINFORFRAMES+1 rem if joy0right=1 and var1=0 then var1=1:score=score+1:rem edit next rem 20241010 patched to prevent right tune from always launching after editing (tied to event) rem if joy0right=0 and score=8 then score=0:gosub cleartrackergui:DisplayList3ShadowColor(31)=14:MUSICINDEX=0:SUSTAINFORFRAMES=0:rem done return:rem goto doedit cleartrackergui rem for bx=0 to 79 rem by=120+bx:rem var2=trkedit(bx):var2=var2-64 rem rem if bx>30 then by=by+40:rem labels on next line rem if bx>30 and bx < 40 then by=by+40:DisplayList3Shadow(by)=DisplayList3Shadow(88) else DisplayList3Shadow(by)=DisplayList3Shadow(88):rem labels on next line rem next bx return skipcontrols bx=MUSICINDEX+9 rem if MusicData(bx)=0 then MUSICINDEX=MUSICINDEX+10 else MUSICINDEX=MUSICINDEX+5 rem SUSTAINFORFRAMES=0:gosub PlayMusic:rem want next pattern 0 duration setting increments MUSICINDEX by 5 rem MUSICINDEX=MUSICINDEX-5 rem SUSTAINFORFRAMES=SUSTAINFORFRAMES+1 rem gosub drawtrackergui return drawtrackergui rem var1=1:rem init to wait to release joystick rem data trkedit "PATTERN INST NOTE INST NOTE LENNEXT DONE" rem for bx=0 to 39 rem by=120+bx:var2=trkedit(bx):var2=var2-64 rem if bx>30 then by=by+40:rem labels on next line rem DisplayList3Shadow(by)=var2 rem next bx rem if MUSICINDEX<100 then DisplayList3Shadow(164)=48:bx=MUSICINDEX:goto donewithmusicindex100s rem if MUSICINDEX>=200 then DisplayList3Shadow(164)=50:bx=MUSICINDEX-200:goto donewithmusicindex100s rem DisplayList3Shadow(164)=49:bx=MUSICINDEX-100 donewithmusicindex100s rem bx=bx/10:by=b:rem (modulus remainder in temp variable b) rem bx=bx+48:by=by+48 rem DisplayList3Shadow(165)=bx rem DisplayList3Shadow(166)=by rem ----v1 note rem var2=MusicData(MUSICINDEX) rem if var2>29 then DisplayList3Shadow(168)=51:bx=var2-30:goto donev1tens rem if var2>19 then DisplayList3Shadow(168)=50:bx=var2-20:goto donev1tens rem if var2>9 then DisplayList3Shadow(168)=49:bx=var2-10:goto donev1tens rem DisplayList3Shadow(168)=48:bx=var2 donev1tens rem DisplayList3Shadow(169)=bx+48 rem --- instrument v1 rem bx=MUSICINDEX+1:var2=MusicData(bx) rem if var2>29 then DisplayList3Shadow(173)=51:bx=var2-30:goto donev1tens2 rem if var2>19 then DisplayList3Shadow(173)=50:bx=var2-20:goto donev1tens2 rem if var2>9 then DisplayList3Shadow(173)=49:bx=var2-10:goto donev1tens2 rem DisplayList3Shadow(173)=48:bx=var2 donev1tens2 rem DisplayList3Shadow(174)=bx+48 rem --- v2 note rem bx=MUSICINDEX+2:var2=MusicData(bx) rem if var2>29 then DisplayList3Shadow(178)=51:bx=var2-30:goto donev1tens3 rem if var2>19 then DisplayList3Shadow(178)=50:bx=var2-20:goto donev1tens3 rem if var2>9 then DisplayList3Shadow(178)=49:bx=var2-10:goto donev1tens3 rem DisplayList3Shadow(178)=48:bx=var2 donev1tens3 rem DisplayList3Shadow(179)=bx+48 rem --- instrument v2 rem bx=MUSICINDEX+3:var2=MusicData(bx) rem if var2>29 then DisplayList3Shadow(183)=51:bx=var2-30:goto donev1tens4 rem if var2>19 then DisplayList3Shadow(183)=50:bx=var2-20:goto donev1tens4 rem if var2>9 then DisplayList3Shadow(183)=49:bx=var2-10:goto donev1tens4 rem DisplayList3Shadow(183)=48:bx=var2 donev1tens4 rem DisplayList3Shadow(184)=bx+48 rem -- duration rem bx=MUSICINDEX+4:var2=MusicData(bx) rem if var2>29 then DisplayList3Shadow(188)=51:bx=var2-30:goto donev1tens5 rem if var2>19 then DisplayList3Shadow(188)=50:bx=var2-20:goto donev1tens5 rem if var2>9 then DisplayList3Shadow(188)=49:bx=var2-10:goto donev1tens5 rem DisplayList3Shadow(188)=48:bx=var2 donev1tens5 rem DisplayList3Shadow(189)=bx+48 return rem ------------------end--TRACKER EDITOR INGAME------------------------------ virtualworld ........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxx....xxxxxxxx ...xx...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xx.xxxxx.....xxxxxxxx ...xx...xxxx......xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxxxxxxxxxxxxx....xxxxx....x.xxxxxxxx ........xxxx.xxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xx.xxxxxxxxxxxxxxx.xx.xxxxx....xx.xxxxxxxx xxxxxxxxxxxx.xxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxxxxxxxxxxx.x..xxxxx....xxx.xxxxxxxx xxxxxxxxxxxx......xxxxxxxxxxxx.....xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxx....xxxx.xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxx........xxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxx...xxxxx.xxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx...........xxxxxxxxxxx.xxxxxxxxxxxxxxx....xxxxx...xxxxx.xxxxxxxx xx.xxxx......xxxxx..xxxxxxx.............xxxxxxxxx...xxxxxxxxxxxxxx....xxxxx...xxxxx.xxxxxxxx xx...xxxx....xx.....xxxxxxxx..........xxxxxxxxxx.....xxxxxxxxxxxxx....xxxxx...xxxxx.xxxxxxxx xx...xxxxxxxxxx..xxxxxxxxxxxx........xxxxxxxxxx.......xxxxxxxxxxxx....xxxxx...xxxx.xxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx......xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxx...xxx.xxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxx...xx.xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..xxxxxxxx.xx....xxxxx....xxxxxxxxxxxxx .......xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx .xx.xx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx .......xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.....xxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxx .xx.xx.xxxxxxxxxxxxxx..........xxxxxxxxxxxxxxxxxxxxxx......xxxxxxxxxxxxxxxxxxxxxxxxxx...xxxx x......xxxxxxxxxxxxxx..........xxxxxxxxxxxxxxxxxxxxxx.......xxxxxxxxxxxxxxxxxxxxxxxx.xxx.xxx xxxxxxxxxxxxxxxxxxxxx..........xxxxxxxxxxxxxxxxxxxxxx........xxxxxxxxxxxxxxxxxxxxxxxx...xxxx sprites ..xxxx.. .xXXXXx. XX.xx.XX XxxxxxXX x.XXXX.x XX....XX .xxxxxx. ..xxxx.. ........ ..xxxxxx .x....xx x....x.x xxxxx..x x...x.x. x...xx.. xxxxx... X....... ........ .xxxxxx. xx..XXxx x.xxxxXx x.xx...x xx....xx .xxxxxx. 24 ...x.... ..xxx... .x.xxx.. x..xxxx. .x.xxxx. ..xxxx.. ...xx... ........ ........ ........ ........ ........ ........ ........ ........ ........ 40 x....x.. ........ ...x..x. .x...x.. .xxx.x.. .x..x..x ..xxx.x. x...x... ........ ..x..x.. ...x.... ...x.x.. ..xx.x.. ..x.x... ...xx.x. ........ ........ ........ ........ ...x.... ...x.x.. ..x.x... ...x.... ........ ........ ........ ........ ........ ...x.x.. ...xx... ........ ........ 72 ..X..... .X.XX... X.XXXX.X ..XXX.X. .....X.. ........ ........ ........ ........ ........ X..XX..X X.XXXX.X X.XX.X.X X..XX..X ........ ........ ........ ........ .X.....X XX.XX.XX XXXXXXXX XX.XX.XX .X.....X ........ ........ X.....X. XX.XX.Xx xXXXXXXX .X.XX.XX ..x....x ........ ........ player0colors 5,4,4,4,15,15,15,15 chiptunes 1,23,1,31,12 1,16,1,31,4 1,15,1,31,8 0,0,0,0,14 1,23,1,31,12 1,16,1,31,8 1,15,1,31,15 1,31,1,31,35 0,0,0,0,0 45 1,15,1,7,15 1,13,1,7,15 1,15,1,31,12 1,15,1,31,12 1,15,1,31,12 0,0,0,0,24 75 1,15,1,7,7 1,13,1,7,15 1,15,1,31,7 1,15,1,31,12 1,15,1,31,6 0,0,0,0,12 1,15,1,7,15 1,13,1,7,7 1,15,1,31,15 1,15,1,31,6 1,15,1,31,12 0,0,0,0,24 1,29,1,19,20 1,31,1,23,20 1,29,1,19,20 1,31,1,23,20 0,0,0,0,0 160 1,31,1,31,15 1,31,1,23,15 1,29,1,19,15 1,31,1,23,15 8,24,8,20,8 10,24,10,20,8 8,24,8,20,4 12,9,12,7,4 8,24,8,20,8 10,24,10,20,15 8,24,8,20,8 10,24,10,20,8 8,24,8,20,4 0,0,0,0,0 230 10,24,10,20,4 8,24,8,20,4 10,24,10,20,4 8,24,8,20,4 10,24,10,20,4 7,27,7,27,8 EXT RA 8,24,8,20,95 7,27,7,27,8 7,13,7,13,8 7,6,7,6,8 0,0,0,0,4 7,27,7,27,8 7,6,7,6,8 7,6,7,6,8 12,3,12,2,4 12,5,12,2,4 7,27,7,27,8 7,13,7,13,8 7,6,7,6,8 0,0,0,0,4 7,27,7,27,8 7,6,7,6,8 7,6,7,6,8 12,3,12,2,4 12,5,12,2,4 0,0,0,0,0