9J;5"ǧG#g13dd ( @ (//(  0/80@0?/8 0( ?G@POWOXOP?H0@/7@O_``h_hPX 0(P_oppxow_g@O/8'' 7p`o?G/7 0??H/8`/o?GOX@H0?/pOW?H/8 7OP?G/7( P0@PX@O0@ 0O @H/@' 00@@P0?'_OP@H( 7/7' ^^^^^^^^^^^^^^^^^^^^^^^^^^TeeBBBBeTT^^^^^^^eBDJ33333JJDBeZ^^^^TD33==#####==3JDBT^^^^eJ=###=3DeZ^^TB3# #=3JBZ^^T3#  #=JBT^^J# Sll #=JBZ^T# %,68??86,/@A*< ##45('.6787-9%:;*<=#$+&,--.,/01)2 3 $%&&'%($!)* ##  !"#     ??d1.@sprite0  =xs-cd3 b.(fd;@Q@ a$p% 5t_aa*A;@wall-ew #xsf@@Č ` X@Fq"wall-ns %xsf@,@,Č ` aH#Btreeperspectivey}@ x]8zI#='YRg'塽.U{\AގGw"]}"A*_~$ZIR?ol~?qsa4}}׶pzC8tklfl0Cw{|뫪_01|}8 6ai#nyHp?~UaoUU߹cm#UpW@HO3w Lk/[­CA !_8*Pjkw@_O:3*(>T%}Bi% A999>O|>18<{`(VPe^ޕ7D (|7oڊ(RnM'|+` f7OOBA7ƺv{r-N?XO.|*~8;[ & ࿿IKŀb7tg'G9m;?3sݒ`+ǟy 5Jk6b>Ĉ/<S?|^UQw j {W/7Ad_ Jچ`o#}~csр( 0 %S`2Oy{v 9SRѽ oMk+H\vOx3w N)pzӘ%e-.MW#s&ӝ'&I?E'ݚjDf'/d eb _?et|zȆ =sLqD¾rpTr f=Ul | ݒr!8F~%2x33gxc61xdvU#!=yˈ|ȠQOx !b?_7y"$Ew g˜D=+{EDK'g':qu7i9 1t6RR~[T5~^?*6LX+S6v7sA#,ߋBf|'?|> "eO >>F7)%ӾZruiM=(4 e)oMlP@PEhUk*(xl΅j=dp<+VZX`Y=v`gL<_sn᠀# R@J,F?b0KlA]d[f1K}U|KGL5oN1tMS_3bvJ9Ml)G?  Ɏ"6=VAzBaŎ8r~;̠c"IԿE4NS/?{ C򂒛g8c_`Yvs<ˮ=V2+U p ,&pۓ %b)"1²W>3{%(ߴ)4ݫ2uhˁ"B}xy#ԍ5BqW(k M4]>P kCL1+׎B)OWu2+ 2 O) k9.ðjUוֹwL "Rzԣv$?3(\aZ9Z<̑a7yc:!RA%>m#ĕ- 8HӮH07yi +^„_wi 槂T+0}dsL gqDo2]?(ϗ?%j{U]&gFrO buPkEk9Eѳ" NefڈE52.ks{ ʊvXOL~iHxӂ NI߃GzaD+Wژ]ؽ;bz_> d p|9QFNnJ>ҳ!!It<#9HX3՗/'0 5`4ິb@;0R Jjf^|f$P/qO7$6pOR;&52ݰ/姇j|p{e'$W& 0<`529{@,b ZъP&q.8#O5띇<+]689|v'Od~S9~"| lbegA˪(^xKh -D M:FR\#竴tاLcA>.6{?mW3.HO;yE>3_+Gcᆕqx#I A97iawSKjTAB>'5^l/d4i\bĢ1WZ$ͳ'H3|^\}{kMAF&zr&Ēn "众L_g 5J]Wog^Qmy8PQr2BdseX El4ma oɈ%tyɭ_ MB(PQwݪgM)-~Im ADy3;Ǟj5:H4?>l)5gLRO:zaKzNM NP?DzxgpYЭֆzAkjgӉA?ͣƀ8Caif,cLTp7o 90,)r%ҁKfį6Ea@vzsJǩ#]{wyNok!)澐˽{'6uNԘ& =KPA9'uXcRQI#4M\;}Q p3=| 6w-maƌ9ia-7Fo8Z>C2 >/ Ǹr9O+urCm~̧G+Ab>SDO;F Bbu]_ y?Tq*T5.B"Э4nA_Dx|F,TSIč@Hal^t6'7Ki6zbyIn) lwJcmnL1W܂-C(ԮWדy:]OnXs9yRM$آA(.C'|(0+KJ1rpa li>cs]or1)a CTsTtPsWO$)@KK>Դ$7YHNsb]$捒q]l>2 L([F/ڧq~hz'ofk]VNbvISn*p[#EI6<P4X$2MSpL3t5Bk79"OJ S`%Uuʴgy2LrQf&«|s%vx_YQF$>rF7>K%d۔yƂ(O6?eh*.KY`rXzrY9>|BuK =;xrd 0BjZP/:B >aᩈ\.h>!5^EEpޢ1^`[y42 bVZxS^K"W4sBUޚWcʚP JXDۮ|EQsm)hBa(Ȃ6ڵyqSG/^_'~OS G +5SFBb1^%#fYUW8Y@X_|(Ji|X.WP&(,cޫ"+BZ(p8!G od+oA 4RZ3 N򔐧MrPFyr 16Jɷ*]\Z*9 CMZN=kS}6WRALi/'C5^_r=Ӫ2e ($4&8夔mQOSWt3ix(iN!ܮ8KJe8D]xJ36wPK3mg:*FuoE'w"* hUZM6=C7 sWV]d9l}dkG) O^OԢ u5P=CVr޹nUdϓ)uliY9suS~j RucrpZ-q3ȘEamS;!D>QAFYfըKR/q\3WuȢX(+pL )y OZv0pşuļY2^dR+JySwAG!sIKA֨|#{sӊܸFqظ-Qrl쁵GY@ɋz`v*h*_>Bh֯'|o>[ݴEQlM'P(s!9yT:qSgZ?QwI~T)3-劮H!n[UߩP, -p QFk=x=muK?Fbg/q "d8rx;G 9QJ] =x61 s$j s|"DR6p;*CF~9v>nkn)qK\K7"N=Ȥ)^n~Ù>L mì4SDOqAJE :׷*8No.\:H 2Š}QJt߀> 2BbQ\~~Ocɯcxčn9C8=%w3c|+U멻ݛ/еJf;Znn KQ5(vsK;NmwZ0-~yT@4{(wWV?I/s++:,`Lp)ծޡVG A{J>s!SZg %QueNpn^VОifF(ԏ0jogx E4Qy7kğTI͑G-5 QMH\&XF236gj~5(J+RIW&TwUPG\g('@q$A[x#~I!vviFYu !)홴>.;Z:-m.%4M7Ҳ6ȹŁ:3D&ށ&{hTì9KkO%3k{y)2aٰ@nyN[|nrɿHWåH cmD `,qȻMy]M_@(q9ױ ̤(G[M ڰPA\ւ KΒ4Z?K.mo7Ag7зr&qCZB`@O=Ƶpɯo0Av E4B.ﴪmKc OW׈զEBUuZ(i5a0ug\2#P OJo}( &˺>f/1":E 3)\S4  L"7i&/Y8 |l\T|/WZ/y|Q /\h>wJ9I?9hd,5 U2Xu"Go/qXp3P=ۦ_:C6ֵ &f:xc:uS _?Wf isk>Km77cd{)5@**nMKdPJ'aҲ`jȔ[<$:hԚ_rZNRau@`vݴCּ̓3k/M =.ō8‰5 ?>Z%:g+32?, 0rFoT^jܞ55}꫍=Ib1=vYNT;le vhZF}x~F7IK0,AsāqrV;pTWA,Hk/_$wZӀ'DxըT鎰Py3tD 'eq6_/9Hkdsǃ7!gU|,pg/6-?>UVT 1xb\VW8v$ߙGd0m\b~i$$Gg>Pr^!_7Tk.:W׈Cks[ڂVrrvSmqNڪҮ8I"0"r+ڮx?g(%A+D<ḯxTgt1HQj,O] c]~] ΂Wʽd 1m&In=f7ɫ|e[ʘ1Ռ5K,yږS(n$dvt9BAyBh>5\YMʣЅاyˈ cT!Y.S^!pJ x۠\UWq^3Be>-nuޤ-䗞j|%3!p'|ZΚV9Mtree2d  lxsf@P&@+¥xH2CE!x"FgQlU̡ܐQ4`KT_TT,H5 !Eoy- background1 Ikx캲$3R?f~6THJ,(+r* DGdս_ $;cwgkV^ٞ{}zG~>\ekO+9u&9e'\ܟ.W=2c͒x7۳m?JyQo8lzdsz&y\FNWmv ?VOJȽ|+/EY_J^H"oʡvm5)S ۿS{GAxe"bϻWi1H=YG]2:YFώ?~2=aՑ37t?RZh+1ߟ6s~T"~GoQƵwJ)o+5t%WʯgL^9s7D|_U?0 LXg3`?gY؎=źAOjv-F9ϐ2>OByf}8˜`8YYclo1GAk9e`yK; JVj'xD'hDӊ9bJ'$$]=h>QN1,;ѫ]F$' wU57Qi18kC li7%2ŏ> {qQ<܏oϼ8- @Mq[.\5:\h{"zp;< l^D[N|c:ToBU3:ަ>~}NgjlC&kk >v12:VbϹ[l1nj؝'~ NLt r8-Ʒϼ[#wS!ϻ Le!B=w 2wO![Uy*d[_)+o} <#ҟǐzH1%}8GB$Ǡ-ͺa|g!x~(;UY5J '*z3mmbmWhÚ(Ofh\5 gyL nuD3[ e$Ӗ\]y'j~@C`)\7׃=rnZ[|4r UPWj]V(/7)#P}1GRY]]U^YHVUk>@Q;y4h]xmAN9ID U#{¬oo<ּ{7L.50mή}}D2<;YA BK10Y?LԃbH}1LU Ȁq6'*kjOqS"+Sţx|N~b/Oe-%AjsQ6j@BVC˙gd,dgz"ewq\LlxNf:.)V'WjM$I{0skricMmCjo\WwGdȫE}4'nvX˔|Tri3ޢ4bUo:(jff}a/ZyWII ǒ<6o Vz1U9DxyDK3/+HfVK^1IWso{BLkSxu; AK O%^õdq|)l3:pm'nSgxNB^p,uh #h=`"3杈Pju}~+ y h{RvϷk^5 _E:<8o1.Oyup[}3MXd3㽐z%[fxˈU\%a2A!Is! z-/)I@G>m;p9A/=b5_T⑉GF;x˸x\YyR,s+*Z%{׿z}N_zy3pRNY_`^8[ZjsОȗG e9Ω+joXZ(om}^ їylϨ%y\Pd)WpͻH* R2Xf| SM/"渑Y%Y">Av(?cn/9amV{{C8 5yJoʻđGt`ǻw) +B( M/:IϽqr}(M3t{ݤ2165n}_V/k<0;{j":*߃ d7YOVgωj+yg i]6{V^w1 ;c}Dk5z6BSNF=?<*s'df$π=5<|sexo=_7J!>@Kcƅf.({qlFz繞ٳ।nߛ#f_U )m\!]ȉ荫?V&rAz裙#]#tA8/F/qNh{6+A^3jFd]M]Ni+ٲ`$ssJ?:RT!A:ҍ~?E/Z?{3hn{,l xV2.B<ۿDDM 1P ]81":'k(>&}oC1Xt;6aʒtXl }&9cnOij6+e@wlMH"(i=?O6  ٢|N C5FW&vQ$''x(?95:qtc"^"c lX`KO^8٣p(fqBv9U zt`uv2d\^`8[Ȣ:dz47T@w;èp15:n๙wvX|y\q>zhp܍f(_lpLӫ!@{[j'1p&JՌQ{ q~E0ƠoLwWJn{Wӫneͩ.jd&"*k_(qđWћx*'X3{xϴh(͆S_lԖ!faLNXg7 TSm?ayWÏ/,ܤU2Mq՛p% ]MkTrBmwnpU Z΂ۈHy\ΦءgH?䜊T 1CQ% #UcBЋ?xnD{%b@7r6RD$|CvU7J4b57-3v8;#1fTx/WCZ5¶K=)0WXН(!'"9e[ p4- C~?Q{|9* GpO]r?6M|p-_3{9# j7N1Թx8U$ecݠ 9aI:Cg[Tp[쓊8\#; \f4k֬#e4)q)E $^U9EkL.X͢Pu}!gj: 8]W3ΞcI݌ h ^1[X]ğ'\ !3"|a{'XFɑc!v,\;]U7*OCZ7܀Un_]|.DD% #eY}T@ڂ3v."ySmC۝j8$KU]-ar7z}UQsln*¨߰ɷm\)Y67QBrq/z&i)p-Q!qw?p~6$j{kLSD5iŇQAA،t Z|  پ4 rn5؃mVHsDooc|P4݇x^fR£N<"}/XCdZ 7Fy^5QY¾.FӃQQpi]) aNs<ƿ= ZDj T֪*,4 ~ X@b *ݯ78&|PbE ؤSڟYw-yŨҧp:$R)T|)7wOz*\1 Oѻij-f|x(# Q2?.Y3dU3Ïl U P-bU;ہPL}8g=W\0NΠ >_FRߟݪ'E<[bݾȣx&cO7fv1p3N4#8#yq3|z\Q$x[ |mugt/Лrkdh \dGpC*%|1ϻC&FbhF\P3u?z<sحFXۧKvU5ba1~g6ūAPͪ zR"sܸbN /9UɁtTeGfxf~1!o<5=-3Bh<؝|+yR$SO|q{)43h+讀Ӝpfco?RwzBL3x DƚS5tf*T3=-cg|$L2sꙜ0rP`;tg/l]Ȗeq]:׏ktкUx\/8{ww2 &]8ЫSev{^*t.& w͝8Qx?*|0"O;WP:+>2x E=~ײg .OW2v>d\91Đ>Xi׋L33iadlja<8Ȣb.sK $u+'HSh:(pxI;*Vh\`D60dQLg|>6SEj&ujFuI#<6`,^Klg R\8!*LIW cG=\Xse\7O=.1M-z)Jgj)'"5$` ֓#-o2ІWubxrm;jZ UW )Do1'ѪC _D/dX3MkdR45sLwћV$b˄1#1J5"JȡG&WM0onyz iTcWosPOᒷϿ7~xZZO9!;g'DNseznɅ:SzO<7.gS,r10 ^f8G~OcTfkB \!B4`F-ft"PxYJ UD#:9$(B ;F$'tcG\ŰV E@Q/ݤq;t3){4F_D;Y qqc1L4FN":*xR !NE*7Dz NE9{Tz DyӳϷ_{$xrl6*ѯ2Qsy<cߍfRvs=K:\1Pw0*БlTCߨ X:{~ŖJzM$z_-akuk[1c3jow/]gyrs Û&._4h$sSqcwXTd 4j } 47i ?ns_9drԡc<wGum|M= 8$hjn\j`xy)8AL'wWyu9<.ϡLOt>k7c\J|Cbv2GA+[L5 hޝ|NK<ւ"G"|ԱQUlFPO&Z0?[fkƗ vR8IBg`0mfUw%g WS0~6Ȏ[ [v=* 1;7Q`t=h)z&k^yq/:`!2# ;={SocJAՆSVDMNڹ ocT߳;,2Iu\مB[6am NwBHĪJgƻc7+c<#zKl o^ہ` :9!DÜ?u.pL7NiOc^I 1N~:_"zzi\<eb5㡿 xFlyhEOxY1{/uɥ%5،_yH*ѠEsvEٺڍTM% D&<qE'Wr -V 6g}ʶwbf*3ԅW:=%؍L[ve OF/ 7,XcW"Krs}rZ>J}eaxVtsU9Y~^n2.YOgXZ  z]Y:_jI\K'ڥOJKg0I5DkT{Gcz'x~ĵl}LLJt]?ū<auL`Edk 5)FײwZ_9'z* P^<7:3$YUTO,9s?9h=l9(7P&HQ:>(ynvVpɵƳCoo"iXkYcYJ9ź~o*/qwZKq/BFz4Skg{l-[)򟳷@bݿx;qua|^c8?:TH 6 T&$*pU޵A){/z+jtWC=WeTs>,!/mEiv砜$9cy7Y&V`3cdȉն Z^ wD Pֻ-P7;fe/֗w{|PIknXW]/o슍5S5w{0_"Lr5Zt8|xV#yҧN1p- }#yx$ک& }$x2UEmTK9Mtщ_/lG}zxNu'x>'q ;m2_WfKU5^߫x7e~8Nj_p~xXјE2C/ +QMޚTmj5R[\7R$6k\x6ǝfX䪸jQ1gv0D>hI$.pԑ2Kޒ>-jzҗR^GL͢P򷘫sVZ^yEXoꭊxƫUOy.%FF+tK̬Gs= u.`>=~mt=;8M\HЖ9 QEi;ׄRfu a"X0x3EH +Aʶ07~]hdΌVGiˆاU:MaETɘ:sQl y]K}#mT# q;}<[hmΓc\bߴ5|=zVCP"a=Y?? dkg7 t"ͼ,:Y`y?=dk?H(a-8j$mBJLD X?yl$]a!m>  w8WarޜstȪ}R6qZB}Pu5E*,a@J!oA(Hzfh_9OaNMڅL9O#>lap*n-8 sC{>fD]:]x?-ꢸvYOhgzDfU bi8R3q_KąH&8xy~ Rs+)&~Uln.%z^.gW**p ~xDz$vn|.2Nzo0C؇ ^=ogmU+~fWeuz6[0ZCZ{5T/QQ 6y?R@~FjF5NP/0."d|$ Ays@bv.3Z6 -)2-zRKҥp25\EfngTA݋SWqSBh8dRi\Q{<[#0~N R;7\6G0+5-0ƫ#V^X34f_ըDt2a9)@TH丂z0e'ϓFdzuNߠkO0fOO yΦ1㕉 /\f.> Ƙ^9}&zBQzНoJEwU,8v2xUj`FC] 9Ydhگb c\W{>2}ѻkR)l+J"Pht r/O) OsP(o;hz) n l#>(\( )s PQD&Lש 1nTR*_vwA{7*d9H=~k2L{hEdpO{""d2^:Э53/ Nm;[zG;kKAxt %hzs k _:ꉚ g=3$x I#5lc _.n񌻴{%rUϭGC= Nqga-CD/lA?l>TӿgsyUfbͼS:3 :6A] o3VXy5(!ݣpX9f̻xkJ^ "JHgv"*K*kw}AWnpm6 orA^0Aq QQ&wK4fq=e)xRik—~dPAOdNE]xy]#⹃v}K o\F$H%<-34ρ瞾S/,*'Ϗqj/eN|"srx>*&yz%dS3 K3q(]'0w`WsŔެZb2xŒI=G}JNV0;ةw GN?i2٬mE`<˴Ic!޻[Ӛy0ve 9pn P*-s=\f&~%E5Ƅ>Ex.WI1̫hzٸ1u*M%M o=yojf87n9J=~'u%^߰K[2QhnZD}S\hr8u\l1f9T85#Qc,"T<I.PҊmqR&+,d3k)x!8x- Kޣn[WWsij7v7$_*v~fE[x6K^H|=PUQ3:;;$)X̉GP*8D4QIԆM gm;tVu_P⑺??OLmI'^Q*^'!am{5/u C[DC'}tE8_I䎉0E)qO[݂qͅ^L]P(8E8'६g?5oq6&n9%SeR-?( Qs8P4 *efcz@e-Ge*<@41pUrؓ#wI&zn5Y23!HӚh䋇alaךL:.V>,R\hO(z=v`)6# N94ӱC|-6]uf3iC†QHt|4ecg}gK_:PWch1 eniax3 pM'9"*XljvF$@GՅ\ -_h~vqjYXBq^AYq8Q~8VS&XҫhZh4zPOPU`&4'o9gOE[t~n˨Wit"jb MS)4a uH38XbŤ#VHihWSm5(ݱv(ƃrggZ XcU鞬ԆDZPA>ltegOq"0D b<!UL+@\ma qynyREV'lɌO].a%sgN,v@o!b'`(.<Q.ɢ#n;hEK֨ޗ8q42G#Igjr#[=.ҵ<-l~/ tsβ-k d5zc jvqzbi׻T&9VANnIS~!4H& UzyFD-*p_=-ZÈudxVj)%6zC^|w{4 ah{ɅqwObmF NXsq?%u k)^c$xmYTƿ,"]ssw+-asA8Iw`ūN?19mcz&wV%+TׄdIeQ1^e}u\%h{6ѵxnΝ);ǿwq(HA6t@wx(hEzfd* T' )ϯc[) .;5<WD:1˜v*E}b!e3gKZU뿁i-wC ]x۫Bou_5c%ʼnR~"X$|97y*{Ҥ1n.bBM7ᙟ3mNoos+j )V]e]kov6|67U.+瞃Sh-Xe\9ΙizDq)^x/.᪨:/=G8GTb[lQXcni@5-.O2|0/3z Z|=T`<ޟq"W4?tr͉Q ~?F>Y- (jqZ+GoW=JR»E#>rH%uQZ*ayM܍@]ACt'$T[;ɥ*nt!>Cxbt[RK@|\7Өٱ2g^QxM}jIoRgDakgT!5Vx~Ä5UFYEݽQ} )03G^yI<JvQ`>0SIoyճ[6SSNxVKslD^2S~񻔱d~W5Üԃ4FZ=jlG ySogL` a?|_ V3N$RG8ENbzez9-ǘcKw23~JԣnY0Qk ?YfKq/^O֎ƬkF_U^`7-2\tYsFAuƈFHfWWʬ-vbFVN;ėuTb21UWBWB'#V**\58̽nZm7!ch ("?atTt9JA0R67ᙈ =ugoQ@]i5{G yM)QQ_IiGF:3hڨTǻ(.ϳ#qjFkHT&s_Y33eVٱGd>1))=HjfFRz ثEb/gzC1v-x/%Ut{ÿ yObfSk9n4! =m zɊ!՜ݝF=2-G9C,=Qu|OdfKU(sVElgRtnrHO_29[&lWķj ̅Ɏe7nBF>j]-wq:5xX[b90RόGd{^m rU7^)Bd$+8mG~Oʆx;tSn&-a/zKbc>'6x(xˤbeLU56aFb -dCEo*`xfzfW"Eb+uOirݝ":VqF}>uEj2 /:TO /{W9 AW[9lVO|fSv 3Ȩ̄py|D}25uR>ZkOz'gXS3fWeZ\berdЭW L ׼OGߔh?Bŝ&wT*8OxJSjGfV9A#d*|Ǘ99^*fu{zNJ;we!NkPZ(#hT6TF^R&sl+mC3 Cş\;ZAF6F ՈN+,%`Cd6"@H=W2 1F\JKu3%0z"zMWg8|%~&9u!ewg&bJLr=R")"ٛ^RUdƱ)UK>aKP[झDQ@}:Ovt߶=}j7 B90š7fkVuwoZ>G&Y؃k $ #gӑRƸPqAo?pNunpvm+gpԯovդ݃-go+xS#")]HOb vNgxVKF7+*[Sp<T2V'w\vֻK{aNҿ8܎+ʩ6w FrI jSw!bTV1XY z^efW<8v ȷzS1?w񛶄^Fk.|g%6ԭ8#ÆCn$ ť{\ro*yFwdz! 1FfOgUɞO] uv1s s7z-2 >،Ej6)Y|ժ@ݕUμ ýxCo$ qJ5"ksV%^ΟK *D'`=gủzK$o"Obg2i -X# 鞩$^hZ#^X8vt*W#h qlT8A=e3wM$3ae"=l'J9b $8CLZuxr c اq>]subʈ"y2<ەww{MٱdU.OErFrѮ¸pEfR%ۍV8Oف}glG%D)G'O>,cX?dlo/*:EufK 6lU\5#ZTUs}sxT'}tdCXe7̩aeR~J`TAVmniIt] ITsFhv0j9$N}WD[O{f`FgD8pa5Fgbl&m8a ^V3Wz{YND ϐӨ mvN& *p=A³SEz~ _2;`+׺.Z"JcM]n]!_=y@_w|ܘ (Bo-'4cč֙ݻ"J/HR|rUos\S\'!g9zPuT01'8Lxǁt~2Q3U wgEi_H4}0Zx$ rJS"<p^ vDx7_@}JG#sMre'Wh]H;$B%7hՉ B2DggNHf%׻ f7gI o1[mA,q#[伍Ewtp󟜍 ߀6 Hr e}aWhAQhӪ3vpK#5§nKdH5kI0hQfS<J6^yJG,CJn_x{glyj^>j xE\!D0!{؇ּQz/@/!i3g?f4pMyv}f&ht<=D<`mwq ?JU]JkqRJj  S(^be{@Қ=rџ/\33c]4MAɄx/b;j% V/-/.ܤ9˸UpÃ%NY$i)-;We؇›4 /DaaWiHTˈŤ |"/m2c[{'֣9ʦ"2ꑙ^BCo˕ٽ5|:یE&:eMǻH6?եG0Z , o饪"CUIm}WcWlWI1kT@{$yܫFghՉn~~Glq3.}>VXR̫G_)`@b'WY w S #ST D w<;B(wQEx^GLSr3c4ѮoZPh /_E< !!zR蔭NmwQbPo>ع!u q+a}Q|)^P'+E0)KA97{}0mWDxڅAwrhe_O_PݯUy 2K8ûK/ϝߘYIj%o3-Vw{hU- |21DxI_d,i4 5a}sd~ǭqS 㩶ש-?銡WNqax& (m㦀9EoJJ;>Fh}>rP=`]"FWhèE]21 Q̟;gW3X1ߦʼnPQk2Gj2jEafزr蝍aTxO"Hp/!gmg??X4/oL|SHg6' A'\"xOT4fg׿=C$Ac/)wywB@u`/&_xrOcp&jQ ȚƝ&GN%utO+x;{@n'=*u:IC[d\!y[jgt,Yv?(9p}C[>³ܧ2F- 2qC:@QwXg<*Hs| 廡=Fs~c;~TZv`̘sx+Xc9cW<+{xvг>n/<wz|NYs@Ԇwz||Ws \;=Cߘ\\0 |3z JE~Sgo~ qfFH-geZRxV෭k%5c)"ǻr Uu,}KL@xg ";)O-3?*|9C#37*?(pzo`Ai-S{|6@^?[yF+uUsupR^mX G9/`viewport cfacing0000000]viewer facing north0000000cmapmode-1000000]start in perspective view0000000czed480-y000000cexx-320000000c room_captionK"direction: "+string(facing) +" X: " +string(ex) +" Z: " +string(zed) 000000cexx-320000000czed480-y000000]need an event for solid0000000]needs an event0000000]needs an event0000000(cycos(facing*pi/180)000000cx-sin(facing*pi/180)000000'cfacing1000000 action_if facing>1800000000cfacing-360000000cbackground_hspeed[0]-10000000&cy-cos(facing*pi/180)000000cxsin(facing*pi/180)000000%cfacing-1000000 action_if facing<-1800000000cfacing360000000cbackground_hspeed[0]10000000 action_if mapmode>00000000action_draw_sprite000-10000Mcmapmode-mapmode000000'cbackground_hspeed[0]0000000%cbackground_hspeed[0]0000000wallew   action_color 652800000000[ex1=x-320 ex2=ex1+sprite_width zed1=480-y zed2=480-y // //distance to point 1&2 distto1=sqrt(sqr(viewport.ex-ex1)+sqr(viewport.zed-zed1)) distto2=sqrt(sqr(viewport.ex-ex2)+sqr(viewport.zed-zed2)) // //get depth order depth=distto1 if distto1>distto2 depth=distto2 // //angle to point 1&2 if(zed1-viewport.zed!=0) angleto1=(180/pi)*arctan((ex1-viewport.ex)/(zed1-viewport.zed)) else { if(ex1-viewport.ex>0)angleto1=90 else angleto1=-90 } if(zed2-viewport.zed!=0) angleto2=(180/pi)*arctan((ex2-viewport.ex)/(zed2-viewport.zed)) else { if(ex2-viewport.ex>0)angleto2=90 else angleto2=-90 } if(zed1-viewport.zed<0) angleto1+=180 //arctan function is only 2 quadrant if(zed2-viewport.zed<0) angleto2+=180 //arctan function is only 2 quadrant // angleto1=angleto1-viewport.facing angleto2=angleto2-viewport.facing if angleto1<-180 angleto1+=360 if angleto2<-180 angleto2+=360 if angleto1>180 angleto1-=360 if angleto2>180 angleto2-=360 //check either points are in front if((angleto1>-90&&angleto1<90)||(angleto2>-90&&angleto2<90)) { draw_polygon_begin() //Start describing a polygon for drawing. draw_polygon_vertex(320+angleto1*10,240-5000/distto1) //Add vertex1 bottom draw_polygon_vertex(320+angleto1*10,240+5000/distto1) //Add vertex1 top draw_polygon_vertex(320+angleto2*10,240+5000/distto2) //Add vertex2 top draw_polygon_vertex(320+angleto2*10,240-5000/distto2) //Add vertex2 bottom draw_polygon_end() //End the description of the polygon. This function actually draws it }0000000 action_ifviewport.mapmode>00000000action_draw_sprite100-10000wallns   action_color 83888630000000[ex1=x-320 ex2=x-320 zed1=480-y zed2=480-y-sprite_height // //distance to point 1&2 distto1=sqrt(sqr(viewport.ex-ex1)+sqr(viewport.zed-zed1)) distto2=sqrt(sqr(viewport.ex-ex2)+sqr(viewport.zed-zed2)) // //get depth order depth=distto1 if distto1>distto2 depth=distto2 // //angle to point 1&2 if(zed1-viewport.zed!=0) angleto1=(180/pi)*arctan((ex1-viewport.ex)/(zed1-viewport.zed)) else { if(ex1-viewport.ex>0)angleto1=90 else angleto1=-90 } if(zed2-viewport.zed!=0) angleto2=(180/pi)*arctan((ex2-viewport.ex)/(zed2-viewport.zed)) else { if(ex2-viewport.ex>0)angleto2=90 else angleto2=-90 } if(zed1-viewport.zed<0) angleto1+=180 //arctan function is only 2 quadrant if(zed2-viewport.zed<0) angleto2+=180 //arctan function is only 2 quadrant angleto1=angleto1-viewport.facing angleto2=angleto2-viewport.facing if angleto1<-180 angleto1+=360 if angleto2<-180 angleto2+=360 if angleto1>180 angleto1-=360 if angleto2>180 angleto2-=360 //check either points are in front if((angleto1>-90&&angleto1<90)||(angleto2>-90&&angleto2<90)) { draw_polygon_begin() //Start describing a polygon for drawing. draw_polygon_vertex(320+angleto1*10,240-5000/distto1) //Add vertex1 bottom draw_polygon_vertex(320+angleto1*10,240+5000/distto1) //Add vertex1 top draw_polygon_vertex(320+angleto2*10,240+5000/distto2) //Add vertex2 top draw_polygon_vertex(320+angleto2*10,240-5000/distto2) //Add vertex2 bottom draw_polygon_end() //End the description of the polygon. This function actually draws it }0000000 action_ifviewport.mapmode>00000000action_draw_sprite300-10000tree [ex=x-320 zed=480-y // //distance to point distto=sqrt(sqr(viewport.ex-ex)+sqr(viewport.zed-zed)) // //get depth order depth=distto // //angle to point if(zed-viewport.zed!=0) angleto=(180/pi)*arctan((ex-viewport.ex)/(zed-viewport.zed)) else { if(ex-viewport.ex>0)angleto=90 else angleto=-90 } if(zed-viewport.zed<0) angleto+=180 //arctan function is only 2 quadrant angleto=angleto-viewport.facing if angleto<-180 angleto+=360 if angleto>180 angleto-=360 //check if in front if(angleto>-90&&angleto<90) { if(distto>5) draw_sprite_scaled(treeperspective,-1,320+angleto*10,240+5000/distto,90/distto ) }0000000 action_ifviewport.mapmode>00000000action_draw_sprite500-10000room1@ show_info()        P@p@p`pppppPpppp@&`(088{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\fmodern\fcharset1 Courier New;}{\f3\fswiss\fcharset1 Arial;}{\f4\fswiss\fcharset1 Arial;}{\f5\fmodern\fcharset1 Courier New;}} {\colortbl\red0\green0\blue0;\red128\green0\blue128;\red0\green0\blue128;\red128\green0\blue0;\red0\green0\blue255;} \deflang1033\pard\plain\f3\fs24\cf0 Perspective Demo \par Tony Forster June 2004 \par May be freely copied with acknowlegement of authorship \par \par To make your own game, keep the viewport, 2 walls and tree object. Duplicate the tree object for baddies bullets etc. Then just program as for a normal 2D game. \par \par With true perspective, 3D games show parallel lines converging at infinity. A rectangular wall looks rectangular straight on and a trapezium if viewed obliquely. \par \par This example, gets most of the way there. \par \par Keys: \par m toggle map mode \par left turn left \par right turn right \par up forward \par down backward \par \par The coordinates for the world we are viewing may not match the screen so the coordinates ex and zed are used. Zed is north and ex is east. In the map mode, x and y of the map (2D) view almost match these except ex,zed 0,0 is the bottom centre of screen x,y 320,480 \par \par There is the viewport object which moves around with the cursor keys but is invisible in the perspective mode. There are 2 kinds of wall object \par \par Any wall will have coordinates ex1,zed1 ex2,zed2. The distance to the viewer and angle are computed. \par \par \plain\f5\fs20\cf0 distto1=\plain\f5\fs20\cf2 sqrt\plain\f5\fs20\cf0 (\plain\f5\fs20\cf2 sqr\plain\f5\fs20\cf0 (\plain\f5\fs20\cf1 viewport\plain\f5\fs20\cf0 .ex-ex1)+\plain\f5\fs20\cf2 sqr\plain\f5\fs20\cf0 (\plain\f5\fs20\cf1 viewport\plain\f5\fs20\cf0 .zed-zed1))\plain\f5\fs20 \par \plain\f5\fs20\cf0 distto2=\plain\f5\fs20\cf2 sqrt\plain\f5\fs20\cf0 (\plain\f5\fs20\cf2 sqr\plain\f5\fs20\cf0 (\plain\f5\fs20\cf1 viewport\plain\f5\fs20\cf0 .ex-ex2)+\plain\f5\fs20\cf2 sqr\plain\f5\fs20\cf0 (\plain\f5\fs20\cf1 viewport\plain\f5\fs20\cf0 .zed-zed2))\plain\f5\fs20 \par \plain\f3\fs24\cf0 \par \plain\f5\fs20\cf0 angleto1=(180/\plain\f5\fs20\cf3 pi\plain\f5\fs20\cf0 )*\plain\f5\fs20\cf2 arctan\plain\f5\fs20\cf0 ((ex1-\plain\f5\fs20\cf1 viewport\plain\f5\fs20\cf0 .ex)/(zed1-\plain\f5\fs20\cf1 viewport\plain\f5\fs20\cf0 .zed))\plain\f5\fs20 \par \plain\f5\fs20\cf0 angleto2=(180/\plain\f5\fs20\cf3 pi\plain\f5\fs20\cf0 )*\plain\f5\fs20\cf2 arctan\plain\f5\fs20\cf0 ((ex2-\plain\f5\fs20\cf1 viewport\plain\f5\fs20\cf0 .ex)/(zed2-\plain\f5\fs20\cf1 viewport\plain\f5\fs20\cf0 .zed))\plain\f5\fs20 \par \plain\f3\fs24\cf0 \par Walls are drawn as polygons, the screen x is proportional to the angle and the screen height inversely proportional to the distance. This mostly works unless you stand too close to a wall edge. Problems can be minimised by having a large viewport collision sprite, narrow view angle and keeping wall segments short. \par \par \plain\f5\fs20 draw_polygon_vertex(320+angleto1*10,240-5000/distto1) \par \par \plain\f3\fs24 Dont draw walls that are behind you. The formula below can occasionally flash up walls that are behind you, replacing the or (||) with an and (&&) gives the opposite problem, walls in front dissapearing. Why? Walls with both edges behind you are behind you, walls with both edges infront of you are infront of you, walls with one edge behind and one infront could be either. Problems minimised by keeping away from walls, keeping the view narrow and keeping wall segments short. \par \par \plain\f5\fs20\cf0 (angleto1>-90&&angleto1<90)||(angleto2>-90&&angleto2<90) \par \par \plain\f3\fs24 Near walls must obscure far ones so the depth of each wall is taken as the distance of the nearer edge. \par \par \plain\f5\fs20\cf4 depth\plain\f5\fs20\cf0 =distto1\plain\f5\fs20 \par \plain\f5\fs20\cf0\b if\plain\f5\fs20\cf0 distto1>distto2 \plain\f5\fs20\cf4 depth\plain\f5\fs20\cf0 =distto2\plain\f5\fs20 \par \plain\f3\fs24 \par \plain\f3\fs24\cf0 Note that this causes the map information to break up and sometimes two walls with equal near edge are incorrectly displayed. \par \par Objects with axial symmetry (trees, bullets and bad guys who always face you) are handled similarly. There is only one coordinate, ex,zed. Instead of a draw_polygon in the draw event, there is a scaled sprite \par \par \plain\f5\fs20\cf2 draw_sprite_scaled\plain\f5\fs20\cf0 (\plain\f5\fs20\cf1 treeperspective\plain\f5\fs20\cf0 ,-1,320+angleto*10,240+5000/distto,90/distto )\plain\f3\fs24\cf0 \par \par The +5000/distto determines whether the tree is at ground level. For a sprite with the origin at its base, +5000 is just right, it matches the 5000 in the walls. For a bullet, put the origin at the centre and +0/distto will make it at eye level. \par \par The 90 determines the object's size, along with the sprite size. \par \par Each object has 3 sprites. The one in the object properties dialogue box, this is used for calculating collisions (unless there is a collision mask) and in laying out the room. The one at the end of the block of code in the draw event, this is the 3D sprite. The one in the drag and drop "draw sprite" action determines the 2D map sprite. \par \par All the collision events are being calculated in the underlying 2D game, regardless of whether map information is displayed \par \par } Spritessprite0tree2dwall-ewwall-nstreeperspectiveSounds Backgrounds background1PathsScripts Data Files Time LinesObjectswallewwallnstreeviewportRoomsroom1 Game Information Game Options