sƕ]eF1U5QufzV|ڂ fr翨0} 8@4Llt|dqA9IAlqi鑉%5:JEU]bB}}z5c. &#{Kt$  ( FĎa9w1]22**BZzbjRrͯʻ ¼/ˇwb P8fMR2LG#plNi!B>>@;Z+(mġY~ uvZ`YK} ^3OC845# =I=:R3Sd/.0 oh(8Q8") @1^˛OdtiYHҝiaZMlʥ_h@c\@ !2`A%5QԀcTN x]C40p/ĊdNxHƱ|jRĜpqg8pk4Pj% rh[ n ry-=67?o 3YFSpUh@uNB .*ϳ31 )6RԤ]v̷pGIn.u1^_0sjUvADr,!R[P0#=ڪ8NMe^)fV4mnO]pf\qͥPctR̊28ލZVB]{,KWR+EEԘaT!T'o" F-㛞ZNGvFKeDeIŕ:JIQlk5Vks#|֜*ޡZ:x P{Il"O!^"|Y'쨹B97:2[nϡIY;f{]A7:GL XNCFa?ƉiACͱP3qǶGdؒ+ʤZ‚Uy0pbm76XJH|okO6e¹r䌿zMKB{Zi@1 lHAdҚ\I6,Ŕ!1`&7,c:.dQ3B0J;{yi2`ᦁA' cPB/P!yV$|%``@ə;&$Y㝀Rǃ`*]R=J_1 !>Q?L2Jɖ#&q(H-<:7)Q6q<*SC #j2N> p R:PًrPD,ȡ*/(|`T0_@"1GȆ94EBa^Z 6 kIҵ'mкȼ͒|(@>9D "V# |ZIqr?$rYGesO&ܹg B)5ʤ!$j0ˆRhBQ'U Nf=>Rb'"1tYB:Tn̂F$dR_+ :[a&?=jF M҇E+yNX$:Aat} F')KquAL4&N/MSOdU(46Qh#YCs2-|"ww3i*رM e"=D30es8Â-5Q`Yzq4Qrc(1y Ye~~:ExG3<.f9-/+2 Y到@!SVyeorDkۛy\tNt ``>ߩl4nS OHW۔qX Uit/;c6rQ!Юc!ke=GY:C^vՊnCxyb:7uԴW:` Oz- `+&+6&Dr ļ8ȕ 7Ŋk 꾫q<cpD9PSTRRvQw`[A*95:c .;1<{9 3[=6a91AЇ<v6963{F8 ֟+\I*=!廴! 2z1X>مK+a?T19̀kᓽk865ӏ{I둾YK&{4*׊1 I+dCB ɏ0ͦT{SAb糋S!D.KP/xw<zD6i6tCr9o;"))89s1#QH{$ !D'>;"t*ɚ;"CJPG\$&lw'>FBkG{>N8 CrC$CM2*:[Hh=#,fdEkD@t5[\k[|qp.(<0*IIzw'jxl|m$ɔzz$=;"l~LA (P `%ؚtCV62܏4 &apXAGRȓC #DU.CCKL Ǭ3;KL{̌L?\L̜ȁ1l̐̈W cuѡW>΄RNK(Ǖ]직y[dʅ`@(ZJ!(M`-`GsP IBŋ:Et[>OIq+ ZVIL p>y|8.. ͂*T08Eˊp pƑ,SAPxL2050euL Q0X%C<} (>T<PG,{QdL*y[ֹv#hռE |[ NchW`F f:@hhAgOH TuX .ⱝRcа<6!GJLhE̅nD24zX&@( H3 4ˏ$=+`\4+.z~at n(MBW.Q]@Z u(2Ec"(hoX@oL*"rY`k=1Z[Plt+$:E <D@ `:>i gFٖbQxN)桱`u`2ξևY.*x P9DQ8ۦv2d . ^ fvOdDhvr`vJcgvg\i@h*B`qGq/ssw(lΪx#M`C]Cigxɵ/ oxpD:;w[jO ]"x6a(Px䮨bnU` Xﺯ'N-orz<ʆW-xL%51pjz_޹fOm*؃,\Ehl^@vщAxOlW?ofxOr7ohBwgwGxuR.(rXOnBE81 Y~2`D#Pj F\>evDv߆wvwhgz~'+05݆rIP.u(,XyF׵Wa@:hGѐqEvgt&,~e9G  zV"J2QV޿t*W  $ _L NTŪi xssȖqJ7X@bcc30T"WUlMYo\2ۙ& Ôjg b9z pƯx }Rr8Ap 8'U`{KH4BPz3~Т!j@M7a0mBЈ4? } J.U19,Bz3ڂ gpBc,`3X@.t/3sh g5TOA L FmFࣈl/A8&X5Q\5l"_!-3D /@d8+ Hg#O%` @!8+2 8d@(PfrN8\"y; t@`K ,_"(e:D27($B,^ |( !(iA|c՞a=wpvryϠw`@ cu)ƭp3ڢļ?tdk]qS-+')ԀSZoE: X=-/E!>>՜%bd\ e͊ b%S҇MV#3gmD:2Ϭ4,*VXOXyA ј$L=!9 tݧт^&nN 'NCrp0 b<Sպ\GDBFf7GG.`3V\ Nh8qLt#6% Ui 3,`ZFr2T 0)5+b9!ANmC!Aa_Qd{D-8O Mlys-P>BdsKԳL&*)8(Vl?5+[qpLNsDb]m~dmAb2)< O)TuHe1i_,v/"gZP:\Ls;1(X12W&/1c*Dmdț=2x>A=Ab6d(Kr۟&C4XA5Ŝ Bg 6X.C% óNXYȽ\<pAPLTAc#q jUeA3qAcS.-Eʜ)+ 2('@rAO0<L6 m!=lFO[`$ AدDž/?˜$E;H0Ȣ31-u1LW; OۓVUM!9@B?lB8}1¤]`#ս (e+0Ce4R.mo_G񕆉4XH> °HnFN4C!rT 10O1:LIgY >D2የ@ %`*r)*7迈Jd`6_YXjs81E>9BE⭑߬vTҰ͸IcaG5H`2RSSPV_gMSXRCvX{ =B0a-&ǧuoi"!JU~!5MR*PHekIB?uQSA|COZ )DRL ce*-IņvYI`ti%R88't$(t3'hD\by,U!zWhhm(Em" u`Id s ʁ ^>va5`]L"V#%*Ap|9Em@p\N3EQ2,KBh>cH$ ^xQ~1 __T&|ꁇjgqXR);B b66eeck[9QWg昐!DӦ6 NeV]G~'BZ^naEUJ2EрH4k}Dਁ'GSJLpA'𽶚CVʼn0 KWlT$,zKWQ|  \l,rtw; 5)L l '3~sbm`>Ǫ!W&qa\yNQHeK"IsQy}xA ᬉt4 W^@z%P 3{ ܫ[هp8# X(hQ=XMF J."0KK/]YWpxuxĝȥ˭Ѱӷٻ=7>; PU3Zc9beLnumw}|Ũͷٺ89A> CENR-v~nĝȦˮбѷٺ74;=$RSMM,]`&ejXqzħˮбзغ..<7%B=+@B.cib}ĝǧ˯аѶٺ&(?B0\\ZnnnuÞǦˮаҶغ$7:4@H=ly{ÝƧˮаүҶػ62*HR8Y][W\c\jTWejmĨ̵غ7>99 CJHK5HQT]e`enjÞƧˮаҵغ00HHGH)BC0RSBq{}ÞƦʮаѵغ;6+E6F:"CJ"hq\{{è̵׺*$=D J8+@F&^ZKu{xè˵׺1.96(SR(jmoÞƦʯаϰѵ׺?@A9D2 HFLI-^d$\^]hhOé˵׺02?2%B2"FGON&TTRW\etx~xè˵ָH2&UTUM3ZVJotwÞƧʮаαѵM4'VO3V^LdjIntsu}žƧʮЯе9.%P-$SN3YVTmqsr}wžƨʮаѴ:"?/*O3.RA+^UFŸǨʯг6/>-$J<J4+TK3deTp~žƨɱϰг1+=8*B0&DEQJ.zsžƨɯаϯг83#>A)C;&SQ6SSL\aYeeQntjvèɮг71;='C9*KN3JHBq||ßŨɮвɳ(<+?.(N9*YR3djdr{yèɳ9.&N6$C?@RE3XWZl_T|z{~èȲ92>6#F9&OF(bNEßĠ§ȴDz8.?.!=GB;F4%C@LT aG1liêdz43G'C:1DK)lmT\xb}rlʸ­6+$68!G:,@=4RD/he\]yc|qydwλ­N?3[T5^no\xc|ulWκ(B9.UR2chda{qvcͺű0+$;4*E=0LD3OH;cnnb{qnVsijıjdXd|qxgu˹¯_u{d{ryitʶİ^u}`v~e|rpľı̹hx|i}swisIJͻïix{k|tn|İ̺­Zllgwzk|wzWfͺİeuwk|w}Xn˹ïcw}j|vsƳɸįj}nux~Ųʻİsl|wïνƴy­̹ƴлozzn~w®κǴr|rp}v|y}|ȴǵпu|vwsyxįмȶpwps~zyǴƴr{wtu}y{u{˷ƴq|zr}y~zŰ̻dzλpyt{||ĭѾƳtz|y~}||˵dz{~¿˶Dz|xw~~~}èʷƱ{z²ʶį̵y{u|~r¿ɵĮͷuvo}|{UoŮʷí͸wxkf}z`nŭкíͷxuigw_^kpǮӺİ̷H82ygO{sw[kʹǰxiNwVhǮһĮͶzgHuTaŮѻïͶxiIyXgƯͷȱe_[vWmŭθ¬˴xhIxWmŮϷ¿Į˵yYb]cmƭͶî̶uZEyZiŮͷżîηL4(^D5}hLwZjȰηïͶuW}c{frĬηį̶wppww[lŭͶİ̶yi`yY{a]hnīϸű̶qX?gKsT}b]fpƮϸİͷwZ}a\epƮîʴӼ­ű̶zX}b[eoƭíʴԻƳηwU{`Y[grŮŮʴԼİθwW}e]gqƮĮʴӻ¬IJθoKzYc]bqƯįʴӼðͷ|V}e\gsŬïʵӻ¯ηjNwUxd\fp~ɰͷñ̶vT|b\glȯϹ¯˵~fExW}`[]epŭηðϹuV\enŬîɳӺӽIJϹ}hOvXva[dlŮͶñ̷ӻپs`GyZ\d]o~ìθñθ~dOuY{gf^oǮͷòͷrYzcgsȯϸòθ|Zz`ht~ŭθĴͷ O       !"#####0#######################d2024679 < ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? !#((((((((((((((((((((((((((((P QP Q RTVWXYZ[[\\]]^^___________ABCCCCC0CCCCCCCCCCCCCCCCCCCCCCCdABCCCCC0CCCCCCCCCCCCCCCCCCCCCCCdABCCCCC0CCCCCCCCCCCCCCCCCCCCCCCd!"#####0#######################d!"#####2#######################d!"#####0#######################d!"#####1#######################dABCCCCC0CCCCCCCCCCCCCCCCCCCCCCCdCCCD0DEEEFFGHIIJKLMMNOOOOOOOOOOt2###$0$%%%&&'())*+,--.//////////t2 012222222222222222222222222222012222222222222222222222222222012222222222222222222222222222012222222222222222222222222222012222222222222222222222222222012222222222222222222222222222012222222222222222222222222222!#((((((((((((((((((((((((((((0!#((((((((((((((((((((((((((((0!!""##$$%%&&''(())**++,,--....T1 11112223344444677889;;<<< < < < <  1111122233444446 7 7 8 8 9 ; ; < < < < < < < 1 11112223344444677889;;<<<<<<<0 1247:;;;;;;;;;<<<<<<<<<<<<<<<01356789::;;<<==>>>>?????????? "#$%&&'()*++,,,---.....//////00 ,BBBBBBBB      BBBBBBBB            " " " "BBBB d "222222222222222222   e eeeea @ a@ @a @ a@ @a @ a@ @a @ a@ @f ffff ffff ffff fff8ss;tt8vv;ww8xx?yy8;yy8ww;vv8uu?tt8;tt8vv;ww8xx?yy8=yy8ww:vv8uu6tt8a @ a@ @a @ a@ @ @ @ @ @  @ @ @8ss;tt8vv;ww8xx?yy8;yy8ww;vv8uu?tt8;tt8vv;ww8xx?yy8=yy8ww:vv 8ss;tt8vv;ww8xx?yy8;yy8ww;vv8uu?tt8;tt8vv;ww8xx?yy e eeeea @ a@ @a @ a@ @a @ a @ @a @ a @ @f ffff fff ff f f ff f f z x{ x x{ x{ x x }{ x }} v{ x { { {{ {} } { z { } { z {a @ a @ @a @ a @ @a@`@a`@`a @ a@ @@ f f f f f f fff {}t x }} t}t x }}vt x} v v{ x{ { { { { {{ {} } { z { } { za @ a @ @a @ a @ @@  a @ a@ @a @ a@ @a @ a@ @a @ a@@@fffffffff ffff fff}t x}  vvt x}  vx vz  xx vz  x } x{  x{ x{  x} x{  x{ x{  x  h >>          _c B"BaC " ?_c B"BaC " ?    ;   < ~~  ~~  ~~ ~~  ~~  ~~ ` ` ? C " " " A # "??C " ""A# "?  ` ` `` ? C "A ? C "A?C " A?C "A>>          _c B!_c B A_c B!_c B A  0q A,q 0q L4EPPPXtQtQtQtaqqqqHdHdHdHd0qL뺮l l lp,lKp\plxpxplxpA. l p l p 0 D$404mNJNL04e$FHuqaY}},m,Ҫm^.-- title: Sijofsjfsoeife -- author: Pigu, DevEd, tfx, Zlew, doctor -- desc: Demo for Battle of the Bits Very Rare Formats compo -- script: lua -- Utility functions function stri(str,i,j) -- Return str[i:j] if j is defined else str[i] if j then return string.sub(str,i,j) else return string.sub(str,i,i) end end function join(a,b) -- join list b at the end of list a -- if b is not defined then just do a deep copy of list a local out={} for i=1,#a do table.insert(out,a[i]) end if b then for i=1,#b do table.insert(out,b[i]) end end return out end -- Coroutine wrappers function mkco(func,...) local co=coroutine.create(func) coroutine.resume(co,...) return co end function ticco(co) local st=coroutine.status(co) if st=="dead" then return false elseif st=="suspended" then coroutine.resume(co) end return true end function yieldcnt(cnt,limit) local cnt=cnt+1 if cnt==limit then coroutine.yield() cnt=0 end return cnt end -- Decompressor routines, based on LZW with 4-bit words local BASE85_CHARS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~" local b85table={} function itobs(a,b) -- Convert integer a into bit string of length b local s="" for i=1,b do if a&1==1 then s="1"..s else s="0"..s end a=a>>1 end return s end function b85decode(b,limit) -- Decode Base85 string into a list of bytes if #b85table==0 then for i=1,#BASE85_CHARS do b85table[stri(BASE85_CHARS,i)]=i-1 end end local padding=(-#b)%5 local b=b..string.rep("~", padding) local bits={} local cnt=0 for i=1,#b,5 do local acc=0 for j=0,4 do acc=acc*85+b85table[stri(b,i+j)] end table.insert(bits,acc>>24) table.insert(bits,acc>>16&255) table.insert(bits,acc>>8&255) table.insert(bits,acc&255) if limit then cnt=yieldcnt(cnt,limit) end end for i=1,padding do table.remove(bits) end return bits end function decompress(b,dest,limit) -- b: compressed data bit string -- dest: destination RAM address dest=dest*2 -- adjust for poke4 local dict={} local di=15 for i=0,15 do dict[i]={i} end local blen=5 local bi=0 local w={} local cnt=0 while bi<#b do local t=tonumber(stri(b,bi+1,bi+blen),2) bi=bi+blen local e=dict[t] if not e and t==di then e=join(w,{w[1]}) elseif t==(1<15 then dict[di]=join(w,{e[1]}) end di=di+1 if di>=1<>16)&255) poke(a+1,(r>>8)&255) poke(a+2,r&255) end end function hsv2rgb(h,s,v) local h=h/60 local c=s*v*255 local x=c*(1-math.abs(h%2-1)) local m=v*255-c if h>5 then return c+m,m,x+m elseif h>4 then return x+m,m,c+m elseif h>3 then return m,x+m,c+m elseif h>2 then return m,c+m,x+m elseif h>1 then return x+m,c+m,m else return c+m,x+m,m end end local COMP_HICOLOR_GFX_LEN=10182 local COMP_PALETTE_MAPPED_GFX="1S2WZw!8za@FM&WgdCF0B^1ytmfSWNj6Rx?zXbK!Ui@4L10lm38aUC?rOF>Vc=Hsg)T>&(izH6mJc$x)DzUE0$%9soHM?~A{1I^?$c-{x3HH7G`}_Ek=;HeW2|F2EDPuXCOIf>Xb9;-JW2!s4Ys!oS?DYKn6dWM@GZQ3GD?3O$e1mIvRHK}_Ow8Qn1=Zc+tq|QMEioiOB~4s(e2kr%C9KGG#qOS_sLlHICKw(rIhIRhgMtjMd%l*pPgM@a2^}`;Hva{A=Nc8Gu7^bEcxX@{3a+3IhQ_Akt&(A`)L=yhW^mu;s-Paz0|D$Km!e4F*Re(f}wDMEm1CqL*^+do8g?7iylw&spR%QA)rvGwc^Dc3a1rAO%Fgs$z?RDO^+2*^y+sUj@G0!8ts1aRCdbH)TCW8TMz`ZDltMuQ1v+_T&J_?{ct}+y=4N+`bCUVFTk>*HmovQrsubw<1wskcOP53Cdfk0RAm{M0Rax$LEdckQfTcP>aDMRbsGI^N%-O*dh)qo!@NE7nSFFPIiziB41C#h`Otb#sCzx_#Ox&U7`tNcwRQ$FuUQ{ejp0pAhNH1D_1ROEL{w)IPPGw9fxdTSYAl+5l9h4xh3()!Mg`?K}Qa!J2`Dldo>uzZ1O%TRbhlLmZA$APPWm{uv73I#0_91g+h%^I7hF$MgC{HaPNOjAhkk{6-T?YCVSgS@wJ%Y%Bm^xEc!bozDxyb((iw*YUlNWx!}%7bJ{%y8FAP>`hO68uNSSJK=iX$_?5p-rq0Yce^LW@%o=PLAk&GK4>S2pK7t3_qiKVe5{?yqJaDdhTy6I<`6jqk#aAfBGiA5wPHX6#J3qc>N1DeEfA52U@cGUe}v>a2SB(n!eTd(0(0H7{PhkP@Jhrl>PcyJWK3v7Q)F{dxn#CaQA=nG`28x*o&s7JzTfS^_rMUWzJO+w^o@V&vOWXO||3?M1xtw=^F%GL|4ZHMYpx8#Q=1XdvSmHQKyi~)*CB)W0RUnxPzfmK9Tg#z6lvW&5a}l+3t`!Wl3Xi6(TyaBsZc6NoV`jUnt@V;rbmb>RLZ$nAmBoI87es*r{yCmhg`Li2{}Ba0|a#tNr#t`_9G#{Mr|X6agavs1<28-D5V-7nUggsO#*EO+PNt*@ggqFA|of1giakZeJ0GZnK>oYyP8RcbkE6?8_+RMM{~Y-N(sE3lNuhJGunWqGp|7==|!KkNdZKO>oaD`J2U7gTTc;tH|Rm^N%M||P}%c7iv1I%DA6V<=>St^9D|#a98XdC=|z*$I;6Cj22(NBN~!u{7*w@Sr5a$BDV05d)6RMpRC0AF%Lg}CHNtD4wd(>aR6w$iXaV6-KAZ2UO-U2dQ%^o70K|MorZYq4k7L*6QJ5s6@)Hbr!nS`oUWyJvFaomb2I7(0q_xRH-5YtJrbeHsf^5nU&DorjxNb?1f`MlHSTx`z(nMoba$vd?H$>V9VW+vR1CA9|JsYlBKY&=8$$z+iPvDy$PH%iqX{sNOmfun7B6L$=pj?l~`D|hS-%CzL7eqLIIdCT#CM;ET@m}{?gEksAZ*KXmKdx~yuJ@~&jyeZyG`+v!10i;(_wBT#?FRe|gzL$3gSNfw=u$7M}#3KIStS@dZmKsVpI}TlYmKE=f^1*mB8C~J-XfF-ozjLbc;^LErYc(Urc>5FLfcK6tRv9`|I{Rbm!DccJ2%?tPBH#jBYVBoS%GbLI#j3|*E{&7Exc4REa}#EQk$lT}a+_9MzmjrQytlZcH-Su_VhCnm#AqV>-;CXsYkh{!dDA20jKNW}7FWa9!jI?t0wXjLX-AhL4KIUq9#z69{}kywhi9_pqSShkGi5{Na&3-S!kVuT-%Qns1&znj7Q~Cj3ssc%hEtsL}q-WsZGWY**eO#>q)7ztB%mxDd1GnB=xm#VW8U??>-HCwT`wfn7G@EHttR6dN(r>>)?`Cu7CcPaCYIB~8#W#-@={&})T>LSpx_>w8oaYi?PQW?0?-=3L?)2p@yR0|gE~lKpK=izG#`pwbY9!SyMHh19Rs=bz1`6}y9e<0V`g*yGvB*5jN{xJsO}9j%V^xi?_9&I^c%UpZa0zVog)e76g$m42R8G3r@MGwzv{3zSIz#D#(HgESi&v5&DbIab2JDtA|;`jf*=kiZ=^uJT;1!LMiyQ93Di?yq=J#+fMv#33r-#%kxKEwVu>;FGXX)81VKC=hCOL4qQ;lNAozBA*qOb0-G2rm0gz?;OttGPa#-nf(TwTuqE6c4`R`a7Hvz-xoR%fdcmgumOKz@p7P+!rz27(dhZy9?Gk>*B%020fGkF&mY_L?Apw6|;l?z`MG@)Au`c13MGGJ|n-qgLb*Y2Ev>wH;ffRyevSof)2l^*K^cP&wPYyVFlY65G2ww8#`5!8t#nHX2XWx>OtEcLG+i&gri7A1HVMVH@vVhlqyV2vMeJNw?o&!ygkWb9ZO`k#LU4=8lcMjPs^k^!u&=%jFe1k%**7{M67pBOe;-X))4HuHl&Bmi)_c-Sk0`_&Ae2(REm&pS1|__oZv&`#9%PkhJBguh3`gF{=~#ms(A0}t=PYm9L#RX7Y^0!#&C%Zh&lB-YzbH}X#&y1WlO$|@1q(zMn(E{Bq-1Mp3FfL>!O|(5pTl~<>`bB*g(Ssb&Z5gI|Xf1-Zi8S`ae7(i|E>ZL6Gt|pbyv#2(A}9qKEh<7zH2=}eAlRfRILy!%VSmQ}J`Rl-=JYP=FnUeQFy(-h&>6)4pGDpjIUr($f@S}@cST0ylrJk1^lqr24YMbph$$>n3Fx+NqPW>)n}R|DeI%+jtTG}FUK*Gk9+5+tPJ8x0DMn1y*&^+Uc@VAX|lvIR!e8Uv;PGz5Yh1GRV)tWwaeg1jAr#>A(;>GY#IKy*kOogjrRpTLDg66_UpNs7DR6*xVsoQAEb=vDS^Pw+)Rygqd5Q2><^" -- Music local EXT_WAV_RAM=0xfc00 local SEQ_LENGTH=5 local SEQ_LOOP=4 local FIXED_ARPS={[0]="Bm",[1]="Bm",[36]="FDxe"} local WAVE_SEQ_POINTERS=b85decode("009C61O)~M2nYxS1Ox;K2m}HN3JVMk4i5$f5D^j+5EBy<6crH>") local WAVE_SEQ_LOOPS=b85decode("|NsC00RI60000000000000960|NsC0|Nj600RR900RR90|NsC0") local WAVE_SEQS={"009","00IL",1,"1O)~J2L}i","2?+`c3kwVk4Gj(s4-W$a0|O5a4h{_s3=9hk3JM7c","5D@","0|O5a4h{_s3=9hk3JM7c2?+`c3kwVk4Gj(s4-W$a","5)%>=6BG","0}l=j3=0Yg2?`4g4Gs?j",21,22,23,24,25,26,27,"92^`R92^}T9UUDV9v&VZ9v&YbA0HndARr(hARr+jAt50lA|fIpA|fLrBO@atBqSsxBqSvzB_$;#CMG5(CME",39,40,41,"6axbk",20} local WAVE_DATA="0}^J5EFj3mApsBslu>{HC}1BnXV+EpU3OXNHynf*EP?`%k57OEJZQ-R#|w})VBxG>)Nq7=Ffas2_j=0 then music(SEQ_LOOP,-1,-1,false) seq=SEQ_LOOP+1 end end if nord~=ord then ord=nord row=-1 trk={} for i=0,5 do trk[i]=peek4(0x27c62+seq*102+ord*6+i) end trk={trk[0]+trk[1]%4*16,trk[1]//4+trk[2]*4, trk[3]+trk[4]%4*16,trk[4]//4+trk[5]*4} end if nrow~=row then row=nrow for i=1,4 do local rowaddr=0x11164+(trk[i]-1)*192+row*3 local note=peek(rowaddr)&15 if note>=4 then ins[i]=(peek(rowaddr+1)&128)//4+(peek(rowaddr+2)&31) wavpos[i]=1 if FIXED_ARPS[ins[i]] then farppos[i]=1 else farppos[i]=0 end end end end for i=1,4 do local wseq=WAVE_SEQS[WAVE_SEQ_POINTERS[ins[i]+1]+1] local loop=WAVE_SEQ_LOOPS[ins[i]+1] local farp=FIXED_ARPS[ins[i]] if wavpos[i]<=#wseq then local wav=wseq[wavpos[i]] local slot=peek4(0x201c9+ins[i]*132) memcpy(0xffe4+slot*16,EXT_WAV_RAM+wav*16,16) memcpy(0xff8c+i*18,EXT_WAV_RAM+wav*16,16) wavpos[i]=wavpos[i]+1 if wavpos[i]>#wseq and loop~=255 then wavpos[i]=loop+1 end end if farppos[i]>0 then local note=farp[farppos[i]] local freq=math.floor(440*2^((note-57)/12)) poke(0xff8a+i*18,freq&255) poke4(0x1ff16+i*36,freq>>8) farppos[i]=farppos[i]+1 if farppos[i]>#farp then farppos[i]=0 end end end end local t=0 local UPD=nil function TIC() if t%3==0 then memcpy(0x3fc3,0x3fc0,45) end t=t+1 if t<80 then return end P1.init() UPD=P1.TIC1 TIC=TIC2 end function TIC2() updateMusic() UPD() end -- Part 1: line logo + part 2 rendering P1={} local LOGO_LINS={"6bvu`fB*mh0000000SUE!vX*R1ONyC2>=W>NZBJ~f&d!;0{{j902ly3","A`Som3_}=%03i%w7ytkO0Kh^4fB*mh000","Jski50000000001kRV}!0000$06+i;0T2uggo9xqAQ^x#00saC0000","8U_Hs1ONa403ZQ?zytsS7{mYq02lxO000","Di{F7001$700=+;000627ytkOz+eCZ5C8xG0DuMn0000","9ti*p06+i$0st5Q01RLt5C~uc5C{YV7ytkO000","CK~_@KmZ|(06-uCfB*mh3;;kN0e}Di000","5e5td03i%uFc1g^0|5YlV*vmF2nH|^0E97sz(4{J#sDx72nGN","7aj}*03i%uFc1KQF@OvN0s)K!001Buz(4{J#sdKWfMWpw2tybE","Eei|;03i%uFc1KQF@V5800IGw1OOonU@#B}1~3o+gfW1?KmriP00","GaUfNApi&l0|5YlV*vnwU@?e50s)K!001Buz(4{J#sDx72nGN","6bS$T000003?K*uK+FaKga7~l00000","Fc<&;00000000Ou3#LINSATT then cls() P2.init() UPD=P2.TIC1 elseif LINSATT[P1.atti]<0 then UPD=P1.TIC2 else for i=1,LINSATT[P1.atti] do table.insert(P1.cos,mkco(P1.draw,LOGO_LINS[P1.lini])) P1.lini=P1.lini+1 end P1.atti=P1.atti+1 end else local i=1 local l=#P1.cos while i<=l do if not ticco(P1.cos[i]) then table.remove(P1.cos,i) i=i-1 l=l-1 end i=i+1 end end end function P1.TIC2() ticco(P1.calcfract) if t>=140 then t=0 cls() defpal() P1.atti=P1.atti+1 UPD=P1.TIC1 elseif t>=60 and t%5==0 then memcpy(0x3fc3,0x3fc0,45) end t=t+1 end -- fractzoom rendering local RE=-1.8598751454646481 local IM=-0.0015213370292345814 local fract={} local scrrad={} local scrphi={} P1.calcfract=coroutine.create(function() local cnt=0 for i=0,2200 do local tf={} for j=-128,128 do local r=math.exp(1.1-i/60) local p=j*math.pi/128 local x=RE+r*math.cos(p) local y=IM+r*math.sin(p) local zx=x local zy=y local iter=0 while iter<120 do local zx2=zx*zx local zy2=zy*zy if zx2+zy2>=4 then break end local tx=zx2-zy2+x local tzy=math.abs(2*zx*zy)+y local tzx=math.abs(tx) if tzx==zx and tzy==zy then iter=120 break end zy=tzy zx=tzx iter=iter+1 end tf[j%256]=math.floor(iter/8) cnt=cnt+1 if cnt%320==0 then coroutine.yield() end end fract[i]=tf end coroutine.yield() for i=0,135 do for j=0,239 do local x=(j-79.5)/68 local y=(i-67.5)/68 scrrad[i*240+j]=-math.log(x^2+y^2)*30 local phi=math.atan2(y,x)*128/math.pi scrphi[i*240+j]=math.floor(phi) end end end) -- Part 2: fractal zoom P2={} function P2.init() -- put initial view into a buffer for i=0,135 do for j=0,239 do local addr=240*i+j local r=math.floor(scrrad[addr]+25) local col=0 if r>=0 then col=fract[r][scrphi[addr]%256] end poke4(0x10000+addr,col) end end end function P2.TIC1() -- slide in from left if t<120 then t=t+2 for i=0,135 do memcpy(i*120,0x8079+i*120-t,t) end elseif seq==2 then t=0 UPD=P2.TIC2 end end function P2.TIC2() local z=math.sin(t/360-math.pi/2)*1200+1225 local p=math.floor(t^3/3e6) for i=0,135 do for j=0,239 do local addr=240*i+j local r=math.floor(scrrad[addr]+z) local col=0 if r>=0 then if r>2200 then r=2200 end col=fract[r][(scrphi[addr]+p)%256] end poke4(addr,col) end end t=t+1 if ord==4 then P3.init() UPD=P3.TIC1 end end -- Part 3: imbored.tic P3={} local pils={} P3.pfuncs={ function() return 0 end, function(x) return (x-230)/60 end, function(x,y) return (x-230)/60+y/5 end } function P3.init() whitepal() P3.fadeco=mkco(fadepal,DEF_PAL,60) P3.transt=0 P3.cp=1 t=0 end function P3.rotmat(p) return { {math.cos(p),-math.sin(p)}, {math.sin(p), math.cos(p)}} end function P3.matline(m,c) for i=1,#m[1],2 do line( 120+m[1][i],68+m[2][i], 120+m[1][i+1],68+m[2][i+1], c[i//2+1]) end end function P3.matrect(m,c) for i=1,#m[1],4 do tri( 120+m[1][i],68+m[2][i], 120+m[1][i+1],68+m[2][i+1], 120+m[1][i+2],68+m[2][i+2], c[i//4+1]) tri( 120+m[1][i],68+m[2][i], 120+m[1][i+2],68+m[2][i+2], 120+m[1][i+3],68+m[2][i+3], c[i//4+1]) end end function P3.TIC1() cls() if t==235 or t==466 then P3.fadeco=mkco(fadepal,DEF_PAL,20) P3.cp=P3.cp+1 elseif t==205 or t==436 then P3.fadeco=mkco(fadepal,WHITE_PAL,20) end ticco(P3.fadeco) local g=-t%10/10 if g==0 then table.insert(pils,{21,math.random()*60-30,math.random()*14+1}) table.insert(pils,{21,math.random()*60-30,math.random()*14+1}) end local pp=#pils for i=20,0,-1 do while pp>0 and pils[pp][1]>(i+g) do x=pils[pp][2] y=50/pils[pp][1] x1=(x-1)*y x2=(x+1)*y pmat={{x1,x2,x2,x1},{-y,-y,y,y}} pmat=matmul(P3.rotmat(P3.pfuncs[P3.cp](t,pils[pp][1])),pmat) P3.matrect(pmat,{pils[pp][3]}) pils[pp][1]=pils[pp][1]-.1 pp=pp-1 end local z=50/(i+g) local c=math.min(z/2,15) local p=P3.pfuncs[P3.cp](t,i+g) local gl={{-138,138,-138,138},{z,z,-z,-z}} gl=matmul(P3.rotmat(p),gl) P3.matline(gl,{c,c}) end while #pils>0 and pils[1][1]<=0 do table.remove(pils,1) end if t==900 then P4.init() UPD=P4.TIC1 SCN=P4.SCN1 end if t>800 then -- just draw 4 squares that will close in -- color 3 to match P4 background rect(0,0,P3.transt*1.25,P3.transt*0.68,3) rect(240-P3.transt*1.25,0,P3.transt*1.25+1,P3.transt*0.68,3) rect(0,136-P3.transt*0.68,P3.transt*1.25,P3.transt*0.68+1,3) rect(240-P3.transt*1.25,136-P3.transt*0.68,P3.transt*1.25+1,P3.transt*0.68+1,3) P3.transt=P3.transt+1 end t=t+1 end -- Part 4: sine scroller P4={} function P4.init() P4.tx=400 P4.txs=3 P4.sca=3.005 P4.text="hey yall its ayce cominatcha! bringin you dis bitsize dentro cuz we poor bois cant afford pico8. but oh well... pico8 is poop and tic80 is sexier! enjoy watching while we get laid by nice anime ladies!" P4.vtext="sijofsjfsoeife" P4.traco=0 P4.plasmaoff=0 P4.plasmavel=0 P4.vtextoff=-7 P4.vtextvel=0 P4.dotrans=false P4.transtimer=0 P4.plasfade=32 P4.smark=t P4.sttrans=true -- decompress part 5's gfx in the background P4.co=mkco(decompressFromRAM,0x4000,0x8000,COMP_HICOLOR_GFX_LEN,23) end function P4.TIC1() cls(3) P4.Scroller() if P4.sttrans then P4.plasmavel=0.3 P4.vtextvel=0.17 if P4.plasmaoff>23 then P4.plasmavel=0 end if P4.vtextoff>6 then P4.vtextvel=0 P4.sttrans=false end end if t-P4.smark==1775 and not P4.dotrans then P4.dotrans=true end P4.plasmaoff=P4.plasmaoff+P4.plasmavel P4.vtextoff=P4.vtextoff+P4.vtextvel if P4.dotrans then P4.plasmavel=P4.plasmavel+0.1 P4.vtextvel=P4.vtextvel-0.025 P4.transtimer=P4.transtimer+1 if P4.transtimer>75 then if P4.plasfade>0 then P4.plasfade=P4.plasfade-1 else P5.init() UPD=P5.TIC1 SCN=P5.SCN1 end end end ticco(P4.co) t=t+1 end function P4.Scroller() l=string.len(P4.text) for ch=1,l do for i=0,7 do P4.SlcSpr(P4.AlMa(string.sub(P4.text,ch)),P4.flr(math.sin(P4.tx/25+i/16+ch)*30),i,25+i+P4.tx+(P4.sca*8+1)*ch,50,P4.sca,P4.traco) end end P4.tx=P4.tx-P4.txs for y=0,136 do line(0,y,P4.plasmaoff+(math.sin((y+(t/12))/8)*3+math.cos((t/8)-y/5)*2),y,1) end l=string.len(P4.vtext) for ch=1,l do spr(P4.AlMa(string.sub(P4.vtext,ch)),math.cos((ch*5-8)+t/24)*5+P4.vtextoff,ch*9.6-8,0) end end function P4.flr(a) return math.floor(a) end function P4.AlMa(tx) local tb=string.byte(tx) if tb==32 then return 463 -- ' ' elseif tb==33 then return 458 -- ! elseif tb==46 then return 459 -- . elseif tb==56 then return 460 -- 8 elseif tb==48 then return 461 -- 0 else return 432+(tb-97) end end function P4.SlcSpr(sp,s,sx,x,y,sc,tc) if x>239 then return end base=0x8000+sp*64+sx if x>0 then targ=y*240+x for i=0,7 do --if we have scale, we need to do some tricks --c/sc gets the row we're in --c%sc gets the column np=peek4(base+i*8) if np~=tc then for c=0,sc*sc-1 do if (targ%240)+(c%sc)+sx*(sc-1)<239 then poke4(targ+i*240+s*240+P4.flr(c/sc)*240+(c%sc)+(i*240*(sc-1))+sx*(sc-1),np) end end end end elseif x>0-(sc*sc) then targ=y*240+x --left most of screen for i=0,7 do np=peek4(base+i*8) if np~=tc then for c=0,sc*sc-1 do if ((targ%239)+(c%sc)+sx*(sc-1)>240) then poke4(targ+i*240+s*240+P4.flr(c/sc)*240+(c%sc)+(i*240*(sc-1))+sx*(sc-1),np) end end end end end end function P4.SCN1(x) a=math.abs((math.sin((x+(t/12))/8)*3+math.cos((t/8)-x/5)*2))*P4.plasfade b=math.abs((math.sin(((x+24)+(t/12))/8)*3+math.cos((t/8)-(x+24)/5)*2))*P4.plasfade c=math.abs((math.sin(((x+48)+(t/12))/8)*3+math.cos((t/8)-(x+48)/5)*2))*P4.plasfade modifycolor(1,a,b,c) end -- Part 5: Hicolor pic P5={} local cylxlut={} local cylylut={} for i=0,32 do cylxlut[i]=math.sqrt(1-((i-16)/16)^2)*10/6 cylylut[i]=math.floor(math.asin((i-16)/16)*10) end function P5.init() cls() for i=0,135 do memcpy(8+i*120,0x8008+i*120,104) end t=0 P5.cylpos=-32 P5.cyla=0 P5.cpf=0 P5.cdir=-0.3 P5.h=-50 P5.unroll=0 P5.side=15 P5.cylofs=0 P5.lnc=0 P5.lns={} P5.pos=-7 SCN=P5.SCN1 OVR=P5.OVR for i=0,135 do P5.lns[i]=i end end function P5.TIC1() t=t+1 P5.h=math.min(P5.h+1/5,103) P5.cpf=P5.cpf+P5.cdir local cpft=P5.cpf^2+P5.h if cpft>103 then P5.cdir=P5.cdir*-1 P5.cpf=P5.cpf+P5.cdir cpft=103 end P5.cyla=6*math.sin(t/60+1) local cylposl=P5.cylpos P5.cylpos=math.floor(cpft) if P5.h>52 then P5.cdir=P5.cylpos-cylposl UPD=P5.TIC2 P5.unroll=P5.cylpos+32 end end function P5.TIC2() P5.cylpos=P5.cylpos+P5.cdir P5.unroll=math.min(P5.unroll+.5,136) t=t+1 if P5.cyla>0 then P5.cyla=6*math.sin(t/60) end if P5.cyla<0 then P5.cyla=0 elseif P5.cyla==0 then if t%6==0 then for i=0,135 do local p=peek4(0x10000+i*240+P5.side) poke4(i*240+P5.side,p) p=peek4(0x100ef+i*240-P5.side) poke4(239+i*240-P5.side,p) end P5.side=P5.side-1 end end if t%2==0 then P5.cylofs=math.min(P5.cylofs+1,68) end if P5.side<0 then UPD=P5.TIC3 SCN=P5.SCN2 t=210 end end function P5.TIC3() t=t-1 if t==0 then UPD=P5.TIC4 SCN=P5.SCN3 end end function P5.TIC4() P5.pos=P5.pos+1/5 for i=0,135 do P5.lns[i]=(P5.pos+i/27)^2+i*35/27-49 end P5.lnc=0 if ord==4 then cls() memset(0x3ff9,0,2) defpal() P6.init() UPD=P6.TIC1 SCN=nil OVR=nil end end function P5.SCN1(ln) if lnP5.lns[P5.lnc] do P5.lnc=P5.lnc+1 end else blackpal() end end function P5.OVR() if P5.cyla~=0 then for i=0,14 do memset(0x3fc3+i*3,i*15+40,3) end for i=0,32 do local x=224-P5.cyla if P5.cyla<0 then x=15-P5.cyla end line(-cylxlut[i]*P5.cyla+x,i+P5.cylpos,cylxlut[i]*P5.cyla+x,i+P5.cylpos,cylxlut[i]*8+1) end end end -- Part 6: Cubes P6={} P6.vertQ={} P6.texQ={} P6.pars={} P6.PROJ={ {1,0,0,0}, } P6.cubeverts={ {-1,-1,-1,-1, 1, 1, 1, 1}, {-1,-1, 1, 1,-1,-1, 1, 1}, {-1, 1,-1, 1,-1, 1,-1, 1}, { 1, 1, 1, 1, 1, 1, 1, 1} } P6.cubefaces={{1,2,3}, {2,3,4}, {2,4,6}, {4,6,8}, {5,6,7}, {6,7,8}, {1,3,5}, {3,5,7}, {1,2,5}, {2,5,6}, {3,4,7}, {4,7,8}} P6.cubeUVs={ { 0,31, 0,31,31, 0,31, 0}, { 0, 0,31,31,31,31, 0, 0} } P6.s60=math.sqrt(3)/2 P6.triverts={ { 0, P6.s60,-P6.s60}, {-1, 0.5, 0.5}, { 0, 0 , 0}, { 1, 1 , 1} } P6.placols={{232,1,0.5},{248,0.82,0.69},{268,0.76,0.82},{291,0.71,0.91},{268,0.76,0.82},{248,0.82,0.69},{232,1,0.5}} function P6.init() P6.SprPla(4) --init plasma -- palettes for i=1,7 do modifycolor(i,hsv2rgb((P6.placols[i][1]+i*3)%360, P6.placols[i][2],P6.placols[i][3])) end for i=1,8 do local t=math.sin(i*math.pi/16)*255 modifycolor(i+7,t,t,t) end t=0 P6.co=mkco(decompressFromBase85,COMP_PALETTE_MAPPED_GFX,0x8000,37) end function P6.mattextri3d(m,u) for i=1,#m[1],3 do local tve={{},{},{},{}} local tuv={} for j=1,3 do local d=i+j-1 tve[1][j]=m[1][d] tve[2][j]=m[2][d] tve[3][j]=m[3][d] tve[4][j]=m[4][d] tuv[j*2-1]=u[1][d] tuv[j*2]=u[2][d] end table.insert(P6.vertQ,tve) table.insert(P6.texQ,tuv) end end function P6.render() -- vertQ=[x11,x12,x13,x21,..;y11,..;z11,..;w11,..] -- assuming camera is at [0;0;0] and -- display surface is at [0;0;160] (roughly normal lens focal distance) -- render ordering is based on the nearest vertex of the triangle local m=P6.vertQ local tris={} for i=1,#m do local vert={} local z={} for j=1,3 do local zt=m[i][3][j]*m[i][4][j]/160 vert[j*2-1]=m[i][1][j]/zt vert[j*2] =m[i][2][j]/zt z[j]=zt end table.sort(z) tris[i]={z,vert,P6.texQ[i]} end -- this is probably the best solution right now since tic80 lacks -- the actual per-pixel z buffering table.sort(tris,function(x,y) for i=#x[1],1,-1 do if x[1][i]~=y[1][i] then return x[1][i]>y[1][i] end end return x[1][1]>y[1][1] end) for i=1,#tris do if type(tris[i][3])=="number" then tri( 120+tris[i][2][1],68+tris[i][2][2], 120+tris[i][2][3],68+tris[i][2][4], 120+tris[i][2][5],68+tris[i][2][6], tris[i][3]) else textri( 120+tris[i][2][1],68+tris[i][2][2], 120+tris[i][2][3],68+tris[i][2][4], 120+tris[i][2][5],68+tris[i][2][6], tris[i][3][1],tris[i][3][2], tris[i][3][3],tris[i][3][4], tris[i][3][5],tris[i][3][6], false,-1) end end P6.vertQ={} P6.texQ={} end function P6.trmat(x,y,z,p,q,r) local sp=math.sin(p) local cp=math.cos(p) local sq=math.sin(q) local cq=math.cos(q) local sr=math.sin(r) local cr=math.cos(r) return { {cq*cr,sp*sq*cr-cp*sr,cp*sq*cr+sp*sr,x}, {cq*sr,sp*sq*sr+cp*cr,cp*sq*sr-sp*cr,y}, { -sq, sp*cq, cp*cq,z}, { 0, 0, 0,1}} end function P6.TIC1() ticco(P6.co) cls(0) -- Particles if t<832 then local rnd=function() return math.random()-0.5 end table.insert(P6.pars,{ rnd()*30,rnd()*30,90, -- pos 0,0,0, -- rot rnd()/2,rnd()/2,rnd()/2, -- drot rnd()+1.5}) -- spd end local i=1 repeat if #P6.pars==0 then break end local cp=P6.pars[i] local trans=P6.trmat(cp[1],cp[2],cp[3],cp[4],cp[5],cp[6]) local norm=matmul(P6.trmat(0,0,0,cp[4],cp[5],cp[6]),{{0},{0},{1},{1}}) table.insert(P6.vertQ,matmul(trans,P6.triverts)) table.insert(P6.texQ,math.abs(norm[3][1])*math.min(8000/cp[3]^2,7)+8) cp[3]=cp[3]-cp[10] for j=1,3 do cp[j+3]=cp[j+3]+cp[j+6] end if cp[3]<1 then table.remove(P6.pars,i) else i=i+1 end until i>#P6.pars -- Cubes local z=10 if t>840 then z=z-(t-840)/10 elseif t<60 then z=600/(t+1) end local rotm1=P6.trmat(math.sin(t/20)*5,math.sin(t/25)*3,z,t/60,t/50,t/40) local rot=matmul(rotm1,P6.cubeverts) local tris={{},{},{},{}} local uvs={{},{}} for i=1,#P6.cubefaces do for j=1,3 do local d=i*3+j-3 local f=P6.cubefaces[i][j] tris[1][d]=rot[1][f] tris[2][d]=rot[2][f] tris[3][d]=rot[3][f] tris[4][d]=rot[4][f] uvs[1][d]=P6.cubeUVs[1][f] uvs[2][d]=P6.cubeUVs[2][f] end end P6.mattextri3d(tris,uvs) P6.mattextri3d(matmul({{-1,0,0,0},{0,-1,0,0},{0,0,1,0},{0,0,0,1}},tris),uvs) P6.render() t=t+1 if t%3==0 then P6.CycSpr(0,4,7) local c=(t//3)%8 if c>0 then modifycolor(c,hsv2rgb((P6.placols[c][1]+t)%360, P6.placols[c][2],P6.placols[c][3])) end end if t==922 then P7.init() UPD=P7.TIC1 SCN=P7.SCN1 end end function P6.SprPla(w) base=0x8000 for x=0,w*8-1 do for y=0,w*8-1 do --v=7+8*(math.sin((x-w)*(x-w)+(y-w)*(y-w))+math.cos(x/25)/10) v=4+4*(8/math.sin((-30+x)/50+math.cos((65+y)/25))) v2=4+4*(math.sin(x*y/36)) p=(x-x%8)/8 q=(y-y%8)/8 poke4(base+q*1024+p*64+(y%8)*8+(x%8),(v+v2)/2) end end end function P6.CycSpr(sp,w,p) base=0x8000 local a={} for i=0,w*w-1 do a[i]=base+((i-i%4)/4)*1024+(i%4)*64 end for i=0,w*w-1 do for j=0,63 do v=peek4(a[i]+j) v=v+1 if(v>p) then v=0 end poke4(a[i]+j,v) end end end -- Part 7: Palette Scroller P7={} P7.gfxdata={ 2032, 16385, 16385, 9187, 8195, 4103, 4551, 2063, 2063, 1183, 1183, 575, 575, 383, 383, 255, 255, 16510, 16501, 8234, 8246, 4120, 4116, 2056, 2088, 7252, 5204, 11890, 5714, 12115, 24405, 28547, 24453, 28619, 24533, 16362, 16374, 8188, 8180, 4088, 4008, 8108, 6060, 11230, 13276, 27102, 20957, 24826, 20733, 24698, 20597, 8234, 8246, 4120, 4116, 2056, 2088, 7252, 5140, 11794, 5650, 12115, 24357, 28547, 24453, 28619, 24533, 16362, 16374, 8188, 8180, 4088, 3976, 8172, 6124, 11214, 13294, 25071, 16783, 255, 255, 383, 383, 575, 575, 1183, 1183, 2063, 2063, 4551, 4103, 8195, 9187, 16385, 16385, 2032, 0, 0, 4088, 0, 0, 16382, 0, 0, 31327, 2628, 2628, 15300, 2628, 2628, 31300, 0, 0, 14895, 19041, 19105, 19111, 19233, 18977, 14895, 0, 0, 16382, 0, 0, 4088, 0, 0 } P7.palette={ 0x22121a, 0x181a36, 0x272527, 0x432618, 0x1a3212, 0x682324, 0x3a3830, 0x2d3f67, 0x693f16, 0x424a50, 0x365516, 0x69554d, 0x366165, 0x6d6a2f, 0x6f776b, 0xa56a87, 0x8181d5, 0xac98ac, 0xee9b72, 0x7dbe65, 0xff9892, 0xd1c8a4, 0xacd5ff, 0xffd270, 0xcdf3ff, 0xc0ff72, 0xffffe6, 0xaaffff, 0xffffa2, 0xffffff } function P7.init() cls() t=0 P7.fadeamt=0 end function P7.TIC1() t=t+1 if t<=68 then memcpy((68-t)*240,0x8000,t*240) elseif t>=864 then local bp=135-(t-864)//2 line(0,bp,240,bp,0) if t==1152 then P8.init() UPD=P8.TIC1 SCN=P8.SCN1 end end end function P7.SCN1(x) local st=x+t/2-170 local sc=P7.gfxdata[(st//2)%#P7.gfxdata+1] for i=1,15 do if st>0 and sc&1==1 then modifycolor(i,P7.palette[i+15]) else modifycolor(i,P7.palette[i]) end sc=sc//2 end end function P7.fade() for i=0,47 do poke(0x03Fc0,peek(0x03FC0+i)-P7.fadeamt) end P7.fadeamt=P7.fadeamt-1 end -- Part 8: Credits P8={} function P8.init() decompressFromBase85(EXT_PAT_DATA,0x11164) t=0 defpal() P8.transtime=300 P8.x=120 P8.y=68 P8.s=64 P8.sin=math.sin P8.cos=math.cos P8.acos=math.acos P8.pi=math.pi P8.abs=math.abs P8.charoffset=464 P8.chartable={ -- ! " # $ % & ' ( ) * + , - . / 43,36,43,43,43,43,43,43,43,43,40,43,39,42,38,41, -- 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,43,43,43,43,43,37, -- @ A B C D E F G H I J K L M N O 43,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, -- P Q R S T U V W X Y Z [ \ } ^ _ 25,26,27,28,29,30,31,32,33,34,35,43,43,43,43,43, -- ` a b c d e f g h i j k l m n o 43,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, -- p q r s t u v w x y z { | } ~ 25,26,27,28,29,30,31,32,33,34,35,43,43,43,43,43 } P8.credtext= { -- @pigu feel free to modify this as needed {"this has been","sijofsjfsoeife"}, {"a demo by","ayce"}, {"first presented at","botb very rare formats"}, {"april","2019"}, {"*****"}, {"greets go","out to"}, {"titan","vlk","malmen","delta99 and the f060"}, {"lamers","dhs","mystic bytes","tomchi"}, {"dekadence","snorpung","aleksi eeben","phantasy"}, {"forsaken","dcs","loni","robyn"}, {"sinc-x","sintel","sibcrew","speccy.pl"}, {"saanix","metriczero","booze design","fairlight"}, {"*****"}, {"credits"}, {"code","pigu","tfx","deved"}, {"gfx","doctor","pigu","deved"}, {"msx","zlew","deved"}, {"*****"}, {"enjoy the rest","of the entries"}, {"we done here","cya"}, {"*****"} } end function P8.TIC1() cls(0) ce=(t//400)%6 cc=(t//200)%#P8.credtext q=t+100000 for i=0,P8.abs(P8.sin(t%400/128)*128) do if ce==0 then -- spinning circle xe=P8.x+P8.sin((-(i*P8.pi))/32)*P8.s ye=P8.y+P8.cos((-(i*P8.pi))/32)*P8.s ye=68+(ye*P8.sin(t/43)-(68*P8.sin(t/43))) xe=120+(xe*P8.sin(t/65)-(120*P8.sin(t/65))) end if ce==1 then -- from tweetcart xe=P8.x+P8.sin((t-(i*4.12))/48)*P8.s ye=P8.y+P8.cos((t+(i*4))/64.13)*P8.s end if ce==2 then -- snek xe=P8.x+P8.sin((i+(t/i)+t)/30)*((i+5)/2) ye=30+(i/1.5) end if ce==3 then xe=P8.x+P8.sin((t-(i*3.7))/69)*P8.s ye=P8.y+P8.cos((t+(i*6))/133.7)*P8.s end if ce==4 then xe=P8.x+P8.sin((t-(i*5.1237))/73.47)*P8.s ye=P8.y+P8.cos((t+(i*4.2))/25)*P8.s end if ce==5 then -- cone xe=P8.x+P8.sin((i+(q/i)+q)/30)*((i+5)/2) ye=30+(i/1.5) end circ(xe,ye,P8.sin(((i*5)+t)/8)+2.5,((((i*5)+t)/8)%8)+8) end -- draw text P8.credstr(P8.credtext[cc+1]) t=t+1 end function P8.credstr(sl) yp=144-P8.abs(P8.sin(t%200/64)*96) for i=1,#sl do for j=1,#sl[i] do spr(P8.getchar(string.sub(sl[i],j,j)),(j*8)+P8.cos((((i*4)+j*5)+t)/8),yp+P8.sin((((i*4)+j*5)+t)/8)*2,0) end yp=yp+8 end end function P8.getchar(c) return P8.charoffset+P8.chartable[string.byte(c)-31] end function P8.SCN1(x) a=math.abs((math.sin((x+(t/12))/8)*3+math.cos((t/8)-x/5)*2))*32 modifycolor(0,0,0,a*math.min(t/60,1)) end