0,]']>S}Wup8d%qy)6o;]AsVl3>>>3333333333333333?3===3===3>>>33333333333333333ffb"ff""ff&"fff&fff"ffff"""b"""bb&b"f&f&f"f"ffffffffffffffff  ""#$%&)*+,,--.//////////////1124 =>??????????????????09=>??????????????????????????  !"$%&)*+,-./---+*))))**+,-..// @@@@@@@@@@@@@@@@@@ACDFHIJKLMNO !#%',..///////////////////////1>3>8>:><>????????????????????s bbDddHddMddOddDddHddMddOddDddHddMddOddDddHddMddOddDddHddMddOddDddHddMddOddDddHddMddOddDddHddMddOddIddKddMddOddIddKddMddOddIddKddMddOddIddKddMddOddIddKddMddOddIddKddMddOddIddKddMddOddIddKddMddOdd#d#d !```                                cCCcCcccCCcC' ' ''' ' '' '8'ggGg G`` ``` ``` ``` ``` ``` ``` ``` `@@ @@@ @@@'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' $b $D$D$D$D$D$D$DD$DD$D$D$D$D$D$D$DqD$DD8`h`H`8`4'` B I   ,-- title: Everybody Make Friends -- author: iceolate -- desc: Field FX 2024 demo compo entry -- site: website link -- license: MIT License (change this to your license of choice) -- version: 0.1 -- script: lua d=4 local greets={"Porffor","Aldroid","reality404","ToBach","RaccoonViolet","MrsBeanbag","Gasman","Hoffman","psenough","THUB","alice","jtruk","Crypt","Stormcaller"} local st=0 local tt=0 -- Function to rotate a point (x, y) by angle theta (in radians) function rotatePoint(x, y, theta) local cosTheta = math.cos(theta) local sinTheta = math.sin(theta) local xNew = x * cosTheta - y * sinTheta local yNew = x * sinTheta + y * cosTheta return xNew, yNew end -- Function to calculate the centroid of a triangle local function calculateCentroid(triangle) local xSum, ySum = 0, 0 for _, vertex in ipairs(triangle) do xSum = xSum + vertex.x ySum = ySum + vertex.y end local centroidX = xSum / #triangle local centroidY = ySum / #triangle return centroidX, centroidY end function easeInOutCirc(x) if x<0.5 then return (1 - math.sqrt(1 - math.pow(2 * x, 2))) / 2 else return (math.sqrt(1 - math.pow(-2 * x + 2, 2)) + 1) / 2 end end local trot=0 function tri_me() cls(8) trot = math.floor((easeInOutCirc((time()/2000) % 1) * 360)+0.5) -- Rotation angle in radians (e.g., 90 degrees = math.pi / 2) local theta = trot * (math.pi / 180) -- Triangle vertices local triangle = { --{x = -1, y = 1}, --{x = 0, y = -1}, --{x = 1, y = 1} {x = -1, y = -1}, {x = 1, y = 0}, {x = -1, y = 1} } -- Calculate the centroid of the triangle local centroidX, centroidY = calculateCentroid(triangle) -- Rotating the triangle for i, vertex in ipairs(triangle) do -- Translate the vertex to the origin local translatedX = vertex.x - centroidX local translatedY = vertex.y - centroidY -- Rotate the translated vertex local rotatedX, rotatedY = rotatePoint(translatedX, translatedY, theta) -- Translate the rotated vertex back triangle[i].x = rotatedX + centroidX triangle[i].y = rotatedY + centroidY end for x=0,6 do for y=0,4 do tri(20+(x*33)+math.floor(triangle[1].x*16), 16+(y*33)+math.floor(triangle[1].y*16), 20+(x*33)+math.floor(triangle[2].x*16), 16+(y*33)+math.floor(triangle[2].y*16), 20+(x*33)+math.floor(triangle[3].x*16), 16+(y*33)+math.floor(triangle[3].y*16), 9) end end str="Hello Field FX & EMF, this is a little prod to celebrate and say hello to the diverse community of this festival. This is my first full length TIC-80 demo and first prod to be more than a single scene or scroller. So without further ado, I say *waves* hello to..." for i=1,#str do print(str:sub(i,i),162+(i*12)-st*80,62+(math.sin(st*3+(i/6))*20)+((math.cos(st*8)*12)),0,true,2) print(str:sub(i,i),160+(i*12)-st*80,60+(math.sin(st*3+(i/6))*20)+((math.cos(st*8)*12)),12,true,2) end end local g_idx=1 function scene_greets() cls(13) -- print("iceolate",44,64,15,false,3) print("Scene greets to:",24,32,15,false,2) if g_idx<#greets+1 then print(greets[g_idx],44,64,15,false,3) end --g_idx=1+(st//1) % #greets g_idx=1+(st//1) end local l2_idx=1 local flip=0 function ducks_sake() if st<3 then hrz=-80 elseif st<=6 then hrz=-80+(((st-3)/3)*180) --(time()/20) else hrz=100 end vrt=20+(math.sin(time()/200)*5) wv_x=math.sin(time()/200)*5 wv_z=math.sin(time()/400)*5 if st>=8 and st//0.1%2==0 then cls(2) else cls(11) end for x=-1,11 do tri(wv_z+10+(x*30),136, wv_z+10+(x+1)*30,136, wv_z+10+(x*30)+15,116,8) end circ(hrz+20,vrt+ 20,16,7) rect(hrz+04,vrt+ 24,33,50,7) circ(hrz+26,vrt+ 22, 3,0) circ(hrz+12,vrt+ 22, 3,0) if st<8 or time()//200 % 2 == 0 then elli(hrz+20,vrt+ 40,20,8,4) else elli(hrz+20,vrt+ 36,20,4,4) elli(hrz+20,vrt+ 44,20,4,4) elli(hrz+20,vrt+ 40,16,4,3) end elli(hrz+20,vrt+100,50,24,1) rect(hrz+04,vrt+ 74,33,6,12) for x=-1,7 do tri(-5+wv_x+(x*30),136, wv_x+(x+1)*30,136, wv_x+(x*30)+5,116,9) end if st>=8 then qx=math.sin(st*80)*2 print("QUACK!",qx+14,10,3,false,2) print("QUACK!",qx+14,70,3,false,2) print("QUACK!",qx+160,30,3,false,2) print("QUACK!",qx+160,90,3,false,2) end if st>5 and st<8 then rtext("DUCKS") end end local lzEcoord={ {-20,-35},{-20,40},{20,40},{20,25},{-5,25}, {-5,10},{20,10},{20,-5},{-5,-5},{-5,-20}, {20,-20},{20,-35},{-20,-35} } local lzMcoord={ {-35,-35},{-35,40},{-20,40},{-20,-20},{-5,-20}, {-5,40},{10,40},{10,-20},{25,-20},{25,40}, {40,40},{40,-35},{-35,-35} } local lzFcoord={ {-20,-35},{-20,40},{-5,40},{-5,10},{25,10}, {25,-5},{-5,-5},{-5,-20},{25,-20}, {25,-35},{-20,-35} } local lzW={0,70,145} local lzSeq={lzEcoord,lzMcoord,lzFcoord} local lSeq=1 local ldrawn=1 local ldo=1 local lnx=0 local lny=0 local lst=0 function drawT(coords,num,xo,yo,scale) xmin=coords[1][1] xmax=0 lx=xo+(coords[1][1]*scale) ly=yo+(coords[1][2]*scale) for i=2,num do x=xo+(coords[i][1]*scale) y=yo+(coords[i][2]*scale) line(lx,ly,x,y,6) lx=x ly=y if coords[i][1]>xmax then xmax=coords[i][1] end end return xmax-xmin end local lox=40 local loy=60 function lasers() cls(0) seq=lzSeq[lSeq] if lSeq>#lzSeq then for i=1,#lzSeq do drawT(lzSeq[i],#lzSeq[i],lox+lzW[i],loy,1) end return end for i=1,lSeq-1 do drawT(lzSeq[i],#lzSeq[i],lox+lzW[i],loy,1) end drawT(seq,ldrawn,lox+lzW[lSeq],loy,1) ldrawn=math.min(math.floor((st-lst)*5),#seq) if ldrawn==ldo and ldrawn<#seq then pc=((st-lst)%0.2)*5 tx=lx+((lzW[lSeq]+lox+seq[ldrawn+1][1]-lx)*pc) ty=ly+((loy+seq[ldrawn+1][2]-ly)*pc) line(lx,ly,tx,ty,6) line(120,136,tx,ty,6) circ(tx,ty,2+(math.sin(st*100)*6),4) end if ldrawn>=#seq then lst=st ldrawn=0 ldo=0 lSeq=lSeq+1 end ldo=ldrawn end function laser_scale() cls(0) for i=1,#lzSeq do drawT(lzSeq[i],#lzSeq[i],lox+10+((i-1)*70),loy,1) end end function make_friends() cls(0) if st<3 then drawT(lzSeq[1],#lzSeq[1],lox,loy,math.max(8-(st*8),1)) print("verybody",math.max(80,240-(st*160)),55,6,false,3) elseif st<5 then drawT(lzSeq[2],#lzSeq[2],lox,loy,math.max(8-((st-3)*8),1)) print("ake",math.max(90,240-((st-3)*160)),55,6,false,3) else drawT(lzSeq[3],#lzSeq[3],lox,loy,math.max(8-((st-5)*5),1)) print("riends",math.max(80,320-((st-5)*160)),55,6,false,3) end end spdr={ {20,16,10,6}, {10,6,0,16}, {20,22,10,12}, {10,12,0,22}, {10,18,0,28}, {12,22,0,34}, {20,16,30, 6}, {30, 6,40,16}, {20,22,30,12}, {30,12,40,22}, {30,18,40,28}, {22,16,40,34} } function rtext(str) for i=3,0,-1 do --xi=((math.sin(st*20)+1)/2)*2 --yi=((math.cos(st*20)+1)/2)*2 xi=math.cos(math.sin(st*8))*4 yi=math.sin(math.cos(st*8))*4 print(str,20+i*xi,20+i*yi,12+i,false,3) end print(str,20,20,(st*16)%16,false,3) end function spiders() centreX=100 centreY=0 radius=80 cls(0) angle=math.pi*((math.sin(st*2)+1)/2) x=centreX+radius*math.cos(angle) y=centreY+radius*math.sin(angle) line(centreX+20,centreY,x+20,y+20,12) circ(x+20,y+20,9,14) for i, sp in pairs(spdr) do line(x+sp[1],y+sp[2],x+sp[3],y+sp[4],14) end rtext("SPIDERS") end function habers() cls(10) for i=0,2 do elli(50,(i*200)+120-(st*80),40,8,12) elli(110,(i*200)+190-(st*60),30,8,12) elli(190,(i*200)+160-(st*120),40,8,12) end line(60,130-(st*30),60,170-(st*30),12) circ(60,130-(st*30),16,2) rect(40,170-(st*30),40,20,14) rtext("HABers") end function paw(x,y,c,b) circ(x+25,y+32,23,c) elli(x+9,y+22,9,12,c) elli(x+19,y+12,9,12,c) elli(x+32,y+12,9,12,c) elli(x+42,y+22,9,12,c) circ(x+17,y+40,7,b) elli(x+25,y+32,8,9,b) circ(x+33,y+40,7,b) elli(x+9,y+22,5,8,b) elli(x+19,y+12,5,8,b) elli(x+32,y+12,5,8,b) elli(x+42,y+22,5,8,b) end function furries() cls(7) paws={{10,0},{1,4},{3,4},{8,9},{15,13},{11,12},{2,12}} for i=1,#paws do c=paws[i][1] b=paws[i][2] clip_x=80+(((st*2)+(i-1))*8)%(#paws*8) clip(clip_x,60,8,56) paw(80,60,c,b) if clip_x>128 then clip(80,60,clip_x%128,56) paw(80,60,c,b) end clip() end rtext("Furries") end function roboteers() cls(8) rtext("Roboteers") circ(100,68,8,2) circ(150,68,8,2) rect(100,50,50,40,14) circ(112,62,5,2) circ(112,62,3,4) circ(136,62,5,2) circ(136,62,3,4) rect(108,72,32,10,12) line(108,77,139,77,0) rect(90,90,70,60,14) centreX=50 centreY=100 radius=40 for i=0,8 do angle=(i*16)*math.pi/180 x=centreX+radius*math.cos(angle) y=centreY+(math.sin((st/10)/(math.pi/180))*radius)*math.sin(angle) circ(x,y,11,9) circb(x,y,11,8) end centreX=120 centreY=100 radius=40 for i=0,8 do angle=(i*16)*math.pi/180 x=centreX+radius*math.cos(angle) y=centreY+(math.sin((st/12)/(math.pi/180))*radius)*math.sin(angle) circ(x,y,11,9) circb(x,y,11,8) end end function made_in() cls(10) rect(0,90,240,50,5) for i=0,120 do clip(65+i,0,1,140) spr(5,65,20+(math.cos((i/24+(st*3)))*10),0,5,0,0,3,2) end clip() print("Made in Wales",10,110,1,false,3) end function film_buffs() cls(14) rect(10,0,80,140,0) for i=0,14 do rect(15,(i*9),7,4,12) rect(78,(i*9),7,4,12) end for i=0,1 do rect(25,i*68,50,60,7) print("HACK",38,(i*68)+10,4) print("THE",40,(i*68)+25,4) print("PLANET",32,(i*68)+40,4) end end function film_title() rtext("Film Buffs") end function hackers_title() rtext("Hackers") end cpus={"Z80","6502","PPC","8088","68000","ARM","6809","SH4"} function hackers() cls(0) for j=0,3 do for i=0,8 do txt=cpus[1+((i+j)%#cpus)] spr(1,i*40,j*35,3,2,0,0,2,2) print(txt,(i*40)+2+(math.ceil((5-#txt)/2)*4),8+j*35,12,false,1,true) end end end -- Scan line FX --------- function line_fx(line) if line<40 then poke(0x3FF9,0) return end x=1.0-((time()/2000)%2) --x=0.5 --trace(x) if line%2==0 then poke(0x3FF9, x*100) else poke(0x3FF9, -x*100) end end function wobble_crt(line) poke(0x3FF9,(math.sin(((time()//8)+line)/16)*6)+math.tan((time()//64)+line)/16) end function film(line) poke(0x3FFA,st^4) end function slide_alt(line) if line%70<35 then poke(0x3FF9,st*20) else poke(0x3FF9,-st*20) end end -- DEMO SEQUENCE local demo_seq = { { scene=lasers, t=8 }, { scene=make_friends, t=8 }, { scene=tri_me, t=40 }, { scene=habers, t=8 }, { scene=film_buffs, scnfx=film, ovrfx=film_title, t=8 }, { scene=spiders, t=8 }, { scene=roboteers, t=8 }, { scene=hackers, scnfx=slide_alt, ovrfx=hackers_title, t=8 }, { scene=furries, t=8 }, { scene=ducks_sake, t=16 }, { scene=scene_greets, scnfx=wobble_crt, t=16 }, { scene=made_in, scnfx=flagin, t=8 }, } local seq_idx=1 local t_target=demo_seq[seq_idx].t local seq_main=nil local seq_scn=nil function BOOT() st=0 seq_main=demo_seq[seq_idx].scene seq_scn=demo_seq[seq_idx].scnfx seq_ovr=demo_seq[seq_idx].ovrfx t_target=demo_seq[seq_idx].t music(1) end function TIC() t=time()//1000 if t>=t_target then tt=t seq_idx=(seq_idx+1) if seq_idx>#demo_seq then cls(0) print("FIN",90,60,12,false,3) return end -- Reset scanline trickery poke(0x3FF9,0) poke(0x3FFA,0) seq_main=demo_seq[seq_idx].scene seq_scn=demo_seq[seq_idx].scnfx seq_ovr=demo_seq[seq_idx].ovrfx t_target=t_target+demo_seq[seq_idx].t end st=(time()/1000)-tt seq_main() end function SCN(line) if seq_scn then seq_scn(line) end end function OVR(line) if seq_ovr then seq_ovr() end end