0,]']±>Sï}WÿÍu§ðp8·d%qy)6o;]ÉA¦ösï÷ôôô”°ÂVl†3-- title: Ready Error One -- author: jtruk and mantratronic MUSIC=true TIMER=false PART=0 GREETS={ "Revision", "Field-FX", "Lovebyte/TCC", "Team Bytejam", "TIC-80 sceners", "TIC-80 lovers", "Rift", "Slipstream", "gotbadger", "coldclimate", "YOU!", } mS=math.sin mC=math.cos mA=math.atan2 mMn=math.min mMx=math.max mPi=math.pi mPi2=mPi*2 mR=math.random mF=math.floor TIME=0 PART_START=0 function getPartTime() return TIME-PART_START end function TIC() poke(0x3FFB,1) -- remove mouse! local fn="part"..PART local t=getPartTime() init=(t==0) moveOn=_G[fn](init,t) TIME=TIME+1 if(moveOn)then PART=PART+1 PART_START=TIME end if(TIMER)then local elapsed=time()/1000 print(elapsed,1,128,0) print(elapsed,3,130,0) print(elapsed,2,129,12) end end function part0(init,t) cls(12) print("jtruk x mantratronic",126,121,0) print("Ready Error One / TIC-80",107,129,0) return t>300 end function part1(init,t) local T_IN=380 local T_HOLD=200 local T_OUT=165 if(init)then if(MUSIC)then music(0) end BDR=function(y) vbank(0) local t=getPartTime() local f=1 local fadeT=T_IN+T_HOLD+T_OUT-150 if(t<150)then f=t/150 elseif(t>fadeT)then f=1-(t-fadeT)/150 end local rgbs={} rgbs[1]=makeRgb(0,0,0) rgbs[2]=makeRgb(.7,0,.7) rgbs[3]=makeRgb(1,1,1) rgbs[4]=makeRgb(.7,.7,.7) rgbs[5]=makeRgb(1,0,0) rgbs[6]=makeRgb(1,0,0) rgbs[7]=makeRgb(1,0,0) rgbs[8]=makeRgb(0,1,0) rgbs[9]=makeRgb(0,1,0) rgbs[10]=makeRgb(0,1,0) rgbs[11]=makeRgb(0,0,1) rgbs[12]=makeRgb(0,0,1) rgbs[13]=makeRgb(0,0,1) rgbs[14]=makeRgb(0,0,0) rgbs[15]=makeRgb(0,0,0) rgbs[16]=makeRgb(0,0,0) for i=2,#rgbs do rgbs[i].r=f*rgbs[i].r+(1-f)*1 rgbs[i].g=f*rgbs[i].g+(1-f)*1 rgbs[i].b=f*rgbs[i].b+(1-f)*1 end setPalette(rgbs) end end return dotPhosphor(1,init,t, T_IN,T_HOLD,T_OUT) end function part2(init,t) local T_TOTAL=765 if(init)then BDR=function(y) vbank(0) t=getPartTime() local FADE_IN=200 local FADE_OUT=80 local rgbs={} local f=1 if(tT_TOTAL-FADE_OUT)then f=1-((t-(T_TOTAL-FADE_OUT))/FADE_OUT) end f=mMx(mMn(1,f),0) for c=2,16 do local i=c/16 local r=i*(0.5+mS(t*.061+y*.02)*0.5) local g=i*(0.5+mS(t*.053+y*.013)*0.5) local b=i*(0.5+mS(t*.045+y*.017)*0.5) rgbs[c]=makeRgb(r,g,b) end rgbs[1]=makeRgb(0,0,0) rgbs[2]=makeRgb(1,1,1) for i=2,16 do rgbs[i].r=f*rgbs[i].r+(1-f) rgbs[i].g=f*rgbs[i].g+(1-f) rgbs[i].b=f*rgbs[i].b+(1-f) end setPalette(rgbs) end end cls(1) local doMoveOn=orbitalTunnel(1,init,t,T_TOTAL) vbank(1) cls() vbank(1) cls() return doMoveOn end function part3(init,t) local T_ARRIVE=600 local T_RUMBLE=500 local T_EXPL_IN=50 local T_EXPL_OUT=150 local T_HOLD=980 if(init)then BDR=function(y) vbank(0) local t=getPartTime() local moment=getMoment(t,{ T_ARRIVE,T_RUMBLE,T_EXPL_IN,T_EXPL_OUT,T_HOLD }) local rgbs={} rgbs[1]=makeRgb(0,0,0) if(moment.s<=3)then for c=1,15 do local i=c/15 rgbs[c+1]=makeRgb( 0.5+mS(t*.017+c*.065)*.5, 0.5+mS(t*.020+c*.056)*.5, 0.5+mS(t*.013+c*.045)*.5 ) end else for c=1,15 do local i=c/15 local v=0.5+mS(t*.01+c*.25)*.5 rgbs[c+1]=makeRgb(v,0,(1-v)/2) end end local f=1 local rAim=1 local gAim=1 local bAim=1 if(moment.s==1)then f=(moment.f<.2)and moment.f*5 or 1 elseif(moment.s==3 or moment.s==4)then f=1-moment.f if(moment.s==4)then f=1-f end elseif(moment.s==5)then local finv=1-moment.f f=(finv<.1)and finv*10 or 1 end f=mMx(0,mMn(1,f)) for c=2,16 do rgb=rgbs[c] rgbs[c].r=f*rgb.r+(1-f)*rAim rgbs[c].g=f*rgb.g+(1-f)*gAim rgbs[c].b=f*rgb.b+(1-f)*bAim end vbank(0) setPalette(rgbs) vbank(1) for c=0,15 do rgb=rgbs[c+1] rgbs[c+1]=makeRgb(1-rgb.r,1-rgb.g,1-rgb.b) end for c=2,16 do rgb=rgbs[c] rgbs[c].r=f*rgb.r+(1-f)*1 rgbs[c].g=f*rgb.g+(1-f)*1 rgbs[c].b=f*rgb.b+(1-f)*1 end setPalette(rgbs) end end local moment=getMoment(t,{ T_ARRIVE,T_RUMBLE,T_EXPL_IN,T_EXPL_OUT,T_HOLD }) vbank(1) local w=48 local h=48 for y=0,w do for x=0,h do pix(x,y,8+mS(x^1.3*.01+y^1.3*.02+t*.1)*7//1) end end vbank(0) local segs=26 local oldRingP for ring=0,3 do local ringP={} for i=0,segs do a=i/segs*mPi2 local extent=ring*1.8 local p=makeP3( mC(a)*extent, mS(a)*extent, 4-ring^2 ) if(moment.s>=2)then local f=moment.s==2 and moment.f or 1 p.x=p.x+mR()*f*.5 p.y=p.y+mR()*f*.5 p.z=p.z+mR()*f*2 end local spinF=moment.s==1 and moment.f or 1 p=rotP3X(p,mC(t*.01)*(1-spinF)*.5) p=rotP3Y(p,mS(t*.01)*(1-spinF)*.5) p=transP3(p,0,0,7) ringP[i]=projP3(p) if(ring>0 and i>0)then p={ ringP[i-1], ringP[i%segs], oldRingP[i%segs], oldRingP[i-1], } local s0=makeP2(0,0) local s1=makeP2(w,0) local s2=makeP2(w,h) local s3=makeP2(0,h) if(i%2==0)then s0,s1=s1,s0 s2,s3=s3,s2 end if(ring%2==0)then s0,s3=s3,s0 s1,s2=s2,s1 end drawTQuad(p[1],p[2],p[3],p[4],s0,s1,s2,s3) end end oldRingP=ringP end if(moment.s>=4)then -- Yuk! if(not greet)then if(not greetCount)then greetCount=1 else greetCount=greetCount+1 end if(greetCount<=#GREETS)then greet={ text=GREETS[greetCount], t=t, } end end end if(greet)then vbank(1) cls() local greetH=8 rect(0,0,120,10,8) local greetW=print(greet.text,2,2,4)+2 print(greet.text,1,1,15) vbank(0) local p={} local quadW=greetW*.01 local quadH=greetH*.01 p[1]=makeP3(-quadW,-quadH,0) p[2]=makeP3(quadW,-quadH,0) p[3]=makeP3(quadW,quadH,0) p[4]=makeP3(-quadW,quadH,0) for i=1,4 do local greetT=greet.t-t p[i]=rotP3X(p[i],greetT*.0001) rotZ=greetT*.004 if(greetCount==#GREETS)then rotZ=0 elseif(greetCount%2==1)then rotZ=-rotZ end p[i]=rotP3Z(p[i],rotZ) p[i]=transP3(p[i], 0, 0, 3+greetT*.0315) end drawTQuad2(projTQuad(makeTQuad( makeP3T(p[1],makeP2(0,0)), makeP3T(p[2],makeP2(greetW,0)), makeP3T(p[3],makeP2(greetW,greetH)), makeP3T(p[4],makeP2(0,greetH)) ))) if(p[1].z<0)then greet=nil end end vbank(1) cls() if(moment.s<=3)then for i=0,40 do mX=((60+t)//200) mY=(t//200) x=mS(.2+i*mX+t*.024)*.5 y=mS(.2+i*mY+t*.032)*.1 z=1.5+mS(i+t*.023)*1.4 -- hacky! if(moment.s>2)then local shift=(moment.s-3)+moment.f z=z-shift*4 end p=makeP3(x,y,z) if(moment.s>=2)then local wobbleF=moment.s==2 and moment.f or 1 p=transP3(p, mR()*wobbleF*.1, mR()*wobbleF*.1, mR()*wobbleF*.1 ) end p=projP3(p) c=15-p.z^2 sh=.5/p.z p2=makeP3(p.x+sh,p.y+sh,p.z+.1) if(p2.z>.1)then drawPoly(p2,3,3+i%4,t*.1,1) drawPoly(p,3,3+i%4,t*.1,c+1) end end end vbank(0) return moment.f>=1 end function part4(init,t) local T_TOTAL=765 if(init)then BDR=function(y) vbank(0) t=getPartTime() local FADE_IN=200 local FADE_OUT=50 local f=1 local fStage=0 if(tT_TOTAL-FADE_OUT)then f=1-((t-(T_TOTAL-FADE_OUT))/FADE_OUT) fStage=2 end f=mMx(mMn(1,f),0) local rgbs={} fade=mMn(1,t/FADE_IN) for c=2,15 do local i=c/16 local r=i*(0.75+mS(t*.061+y*.02)*0.25) rgbs[c+1]=makeRgb(r,0,0) end rgbs[1]=makeRgb(0,0,0) rgbs[2]=makeRgb(1,0,0) local rAim,gAim,bAim=1,1,1 if(fStage==2)then gAim,bAim=0,0 end for i=2,16 do rgbs[i].r=f*rgbs[i].r+(1-f)*rAim rgbs[i].g=f*rgbs[i].g+(1-f)*gAim rgbs[i].b=f*rgbs[i].b+(1-f)*bAim end setPalette(rgbs) end end vbank(0) cls(1) local doMoveOn=orbitalTunnel(2,init,t,T_TOTAL) vbank(1) cls() return doMoveOn end function part5(init,t) local T_IN=380 local T_HOLD=200 local T_OUT=225 if(init)then BDR=function(y) vbank(0) local rgbs={} local t=getPartTime() local f=1 local fadeT=T_IN+T_HOLD+T_OUT-150 if(t>fadeT)then f=1-(t-fadeT)/150 end for c=0,15 do local i=c/15 rgbs[c+1]=makeRgb(i,0,0) end for i=2,#rgbs do rgbs[i].r=f*rgbs[i].r+(1-f)*1 rgbs[i].g=f*rgbs[i].g+(1-f)*1 rgbs[i].b=f*rgbs[i].b+(1-f)*1 end setPalette(rgbs) end end return dotPhosphor(2,init,t, T_IN,T_HOLD,T_OUT) end function part6(init,t) if(init)then music() BDR=function(y) local rgbs={} for c=0,15 do local i=c/15 rgbs[c+1]=makeRgb(i,i,i) end setPalette(rgbs) end end cls(15) print("Fantasy Console competition",45,50,8) print("in Revision 2024, please ;)",55,60,8) print("Sound: Mantratronic",133,113,0) print("Code: jtruk",178,121,0) print("Released at Revision 2023",102,129,0) return false end -- input: t and steps{t1,t2,t3} -- returns: step and fraction through function getMoment(t,times) for i=1,#times do local thisT=times[i] if(t READY"..cursor,0,0,2) else print(" ERROR!",0,0,14) end pixB=pixToBuf(0,0,pixBW,pixBH) cls() local moment=getMoment(t,{ T_ZOOM_OUT,T_ZOOM_HOLD,T_ZOOM_IN }) if(moment.s==1)then z=0.93-mC(mPi*moment.f)*.92 elseif(moment.s==2)then z=0.93+.92 else z=0.93+mC(mPi*moment.f)*.92 end for y=0,pixBH-1 do for x=0,pixBW-1 do local pcol=pixB[y*pixBW+x] draw=(stage==1) or mR()<.7 if(draw and pcol>0)then p=makeP3(x*.1-2,y*.1-.2,0) if(moment.s==3)then p=rotP3X(p,moment.f*.3) p=rotP3Y(p,-moment.f*.4) p=rotP3Z(p,moment.f^2*.6) end p=transP3(p,0,0,z) p=projP3(p) if(p.z>0)then local size=3.7 local sides=20 local rotate=.2 if(stage==2)then sides=mR(3,20) rotate=mR() p=transP3(p,0,0,mR()*.2) end if(moment.s==3)then local abber=moment.f^2/p.z p2=transP3(p,-abber,-abber,0) p3=transP3(p,abber,abber,0) drawPoly(p2,size,sides,rotate,6) drawPoly(p3,size,sides,rotate,12) end drawPoly(p,size,sides,rotate,pcol) end end end end for y=0,136,2 do for x=0,240,2 do pix(x,y,pix(x,y)+mR(2)-1) end end return moment.f>=1 end function orbitalTunnel(stage,init,t,T_TOTAL) local ZFAR=200 if(init)then SHAPES={} end local rot=mS(t*.01)*.2 if(stage==2)then rot=rot+mC(t*.02)*1.4 +mS(t*.05)*0.7 end local camera= makeP3( 0, 0, (stage==1) and t or -t ) for z=1,6,.5 do for x=-6,6,.5 do zT=t*.1 if(stage==2)then zT=-zT camera.x=mS(t*.007)*.02 camera.y=mS(t*.01)*.02 end zT=zT//1-zT p=makeP3(x,.1,z) p=transP3(p,0,0,zT) p=rotP3Z(p,rot) p=projP3(p) pix(p.x,p.y,12) end end if(stage==1)then if(( (t+26)%24==0 and t//24<21 )or (t==535 or t==570) )then addShape(camera.z+ZFAR,mR(3,10)) end else if((t+27)%24==0)then addShape(camera.z,mR(3,10)) end end table.sort(SHAPES, function(a,b) return a.zZFAR)then shape.alive=false else p=makeP3(0,0,z) if(stage==2)then p=transP3(p,mR()*.005, camera.y+mR()*.005, mR()*.005) shape.rot=shape.rot+mS(s)*.1 end radii={.025,.03} ringTQs=makeRingTQs(p,shape.sides,radii,rot+shape.rot,15) if(stage==2)then for i=1,#ringTQs do local dx=ringTQs[i].p0.p.x local dy=ringTQs[i].p0.p.y local d=((dx^2+dy^2)^.5)*((p.z^2)*16) local a=mA(dx,dy) -- Ugly, but needs a code refactor -- to make not ugly! ringTQs[i].p0.p=transP3(ringTQs[i].p0.p, mS(a)*d, mC(a)*d, 0 ) ringTQs[i].p1.p=transP3(ringTQs[i].p1.p, mS(a)*d, mC(a)*d, 0 ) ringTQs[i].p2.p=transP3(ringTQs[i].p2.p, mS(a)*d, mC(a)*d, 0 ) ringTQs[i].p3.p=transP3(ringTQs[i].p3.p, mS(a)*d, mC(a)*d, 0 ) end end vbank(1) cls(12) vbank(0) for i=1,#ringTQs do drawTQuad2(projTQuad(ringTQs[i])) end end end return t>T_TOTAL end function addShape(z,sides) local getFree=function() for i=1,#SHAPES do if(not SHAPES[i].alive)then return i end end return #SHAPES+1 end SHAPES[getFree()]={ z=z, rot=0, sides=sides, alive=true, } end function pixToBuf(x0,y0,w,h) local buf={} for y=0,h do for x=0,w do buf[y*w+x]=pix(x0+x,y0+y) end end return buf end function makeRgb(r,g,b) return{ r=r, g=g, b=b, } end -- Takes a table of rgbs -- .r,.g,.b are 0-1 function setPalette(rgbs) for i=0,15 do local rgb=rgbs[i+1] local addr=0x3fc0+i*3 poke(addr,(rgb.r*255)//1) poke(addr+1,(rgb.g*255)//1) poke(addr+2,(rgb.b*255)//1) end end function makeP3(x,y,z) return { x=x, y=y, z=z, } end function projP3(p) return { x=120+100*(p.x/p.z), y=68+100*(p.y/p.z), z=p.z, } end function transP3(p,x,y,z) return { x=p.x+x, y=p.y+y, z=p.z+z, } end function rotP3X(p,a) return { x=p.x, y=p.y*mC(a)-p.z*mS(a), z=p.y*mS(a)+p.z*mC(a), } end function rotP3Y(p,a) return { x=p.x*mC(a)-p.z*mS(a), y=p.y, z=p.x*mS(a)+p.z*mC(a), } end function rotP3Z(p,a) return { x=p.x*mC(a)-p.y*mS(a), y=p.x*mS(a)+p.y*mC(a), z=p.z, } end function makeP2(x,y) return { x=x, y=y, } end -- p: point -- t: texture function makeP3T(p,t) return { p=p, t=t, } end function makeTri(p0,p1,p2,c) return { p0=p0, p1=p1, p2=p2, c=c } end function makeTTri(p0,p1,p2) return { p0=p0, p1=p1, p2=p2, c=-1 } end function makeQuad(p0,p1,p2,p3,c) return { p0=p0, p1=p1, p2=p2, p3=p3, c=c } end function makeTQuad(pt0,pt1,pt2,pt3) return { p0=pt0, p1=pt1, p2=pt2, p3=pt3, c=-1 } end -- radii array of extents function makeRingTQs(pC,segs,radii,rot,col) local quads={} local s0=makeP2(0,0) local s1=makeP2(w,0) local s2=makeP2(w,h) local s3=makeP2(0,h) local p={} local lastP for r=1,#radii do local radius=radii[r] for i=1,segs+1 do local a=(i-1)/segs*mPi2+rot p[i]=transP3(pC, mS(a)*radius, mC(a)*radius, 0 ) if(r>1 and i>1)then quads[#quads+1]=makeQuad( makeP3T(p[i-1]), makeP3T(p[i]), makeP3T(lastP[i]), makeP3T(lastP[i-1]), mMx(1,15-(z*16)) ) end end lastP={} for i=1,#p do lastP[i]=p[i] end end return quads end function drawPoly(p,size,segs,rot,c) size=size/p.z for i=0,segs-1 do local a1=i/segs*mPi2+rot local a2=(i+1)/segs*mPi2+rot tri( p.x,p.y, p.x+mC(a1)*size,p.y+mS(a1)*size, p.x+mC(a2)*size,p.y+mS(a2)*size, c ) end end function drawTQuad(p0,p1,p2,p3,s0,s1,s2,s3) drawTTri(p0,p1,p2,s0,s1,s2) drawTTri(p2,p3,p0,s2,s3,s0) end function projTQuad(t) t.p0.p=projP3(t.p0.p) t.p1.p=projP3(t.p1.p) t.p2.p=projP3(t.p2.p) t.p3.p=projP3(t.p3.p) return t end function drawTQuad2(t) drawTTriPrim(t.p0,t.p1,t.p2,t.c) drawTTriPrim(t.p2,t.p3,t.p0,t.c) end function projTTri(t) t.p0.p=projP3(t.p0.p) t.p1.p=projP3(t.p1.p) t.p2.p=projP3(t.p2.p) return t end function drawTTri2(t) drawTTriPrim(t.p0,t.p1,t.p2,t.c) end function drawTTriPrim(p0,p1,p2,c) if(c~=-1)then tri( p0.p.x,p0.p.y, p1.p.x,p1.p.y, p2.p.x,p2.p.y, c ) else ttri( p0.p.x,p0.p.y, p1.p.x,p1.p.y, p2.p.x,p2.p.y, p0.t.x,p0.t.y, p1.t.x,p1.t.y, p2.t.x,p2.t.y, 2, 0, p0.p.z,p1.p.z,p2.p.z ) end end function drawTTri(p0,p1,p2,s0,s1,s2) ttri( p0.x,p0.y,p1.x,p1.y,p2.x,p2.y, s0.x,s0.y,s1.x,s1.y,s2.x,s2.y, 2, 0, p0.z,p1.z,p2.z ) end