From 1694aeb3eeafe37f50d26ae5ae474fedb88e8a02 Mon Sep 17 00:00:00 2001 From: Slyvtt Date: Fri, 11 Mar 2022 22:44:47 +0100 Subject: [PATCH] 0.25 with minor corrections --- CMakeLists.txt | 7 +- CppOutRun.cbp | 3 + CppOutRun.layout | 112 +++--- assets-cg/backgrnd/fxconv-metadata.txt | 5 + assets-cg/backgrnd/mountain.png | Bin 0 -> 31376 bytes assets-cg/backgrnd/treeline.png | Bin 0 -> 39179 bytes assets-cg/trees/tree4.png | Bin 0 -> 11839 bytes assets-cg/trees/tree5.png | Bin 0 -> 2267 bytes assets-cg/trees/tree6.png | Bin 0 -> 1245 bytes src/colors.h | 19 ++ src/include/cars.h | 35 ++ src/include/circuit.h | 38 ++- src/include/clouds.h | 2 +- src/include/drawstuff.h | 5 + src/include/segment.h | 19 +- src/main.cc | 350 ++++++++++++++++--- src/parameters.h | 13 + src/src/cars.cc | 53 +++ src/src/circuit.cc | 454 ++++++++++++++++++------- src/src/clouds.cc | 3 +- src/src/drawstuff.cc | 54 +++ src/src/segment.cc | 10 +- 22 files changed, 939 insertions(+), 243 deletions(-) create mode 100644 assets-cg/backgrnd/fxconv-metadata.txt create mode 100644 assets-cg/backgrnd/mountain.png create mode 100644 assets-cg/backgrnd/treeline.png create mode 100644 assets-cg/trees/tree4.png create mode 100644 assets-cg/trees/tree5.png create mode 100644 assets-cg/trees/tree6.png create mode 100644 src/colors.h create mode 100644 src/include/cars.h create mode 100644 src/src/cars.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 840f4d8..9376c52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ set(SOURCES src/src/circuit.cc src/src/drawstuff.cc src/src/clouds.cc - # ... + src/src/cars.cc ) set(ASSETS_cg @@ -31,10 +31,15 @@ set(ASSETS_cg assets-cg/trees/tree1.png assets-cg/trees/tree2.png assets-cg/trees/tree3.png + assets-cg/trees/tree4.png + assets-cg/trees/tree5.png + assets-cg/trees/tree6.png assets-cg/player/player.png assets-cg/clouds/sky1.png assets-cg/clouds/sky2.png assets-cg/clouds/sky3.png + assets-cg/backgrnd/mountain.png + assets-cg/backgrnd/treeline.png ) fxconv_declare_assets(${ASSETS_cg} WITH_METADATA) diff --git a/CppOutRun.cbp b/CppOutRun.cbp index 70e132b..6a04d9f 100644 --- a/CppOutRun.cbp +++ b/CppOutRun.cbp @@ -28,8 +28,10 @@ + + @@ -37,6 +39,7 @@ + diff --git a/CppOutRun.layout b/CppOutRun.layout index ad57dc2..7aa6b18 100644 --- a/CppOutRun.layout +++ b/CppOutRun.layout @@ -2,49 +2,19 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + @@ -52,14 +22,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + diff --git a/assets-cg/backgrnd/fxconv-metadata.txt b/assets-cg/backgrnd/fxconv-metadata.txt new file mode 100644 index 0000000..7e05b58 --- /dev/null +++ b/assets-cg/backgrnd/fxconv-metadata.txt @@ -0,0 +1,5 @@ +*.png: + type: bopti-image + profile: p4 + name_regex: (.*)\.png \1 + diff --git a/assets-cg/backgrnd/mountain.png b/assets-cg/backgrnd/mountain.png new file mode 100644 index 0000000000000000000000000000000000000000..90a6c1f03a37f394d9bedc4d8b9069a4ef2483ec GIT binary patch literal 31376 zcmV)6K*+y|P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+NGRnk{maZh5zFeIs$gUkAu~0ZZOB6?;(?vs8*}h zHlkQ0v$7%(fcskzpv4*t^p=fCm32A|*8_g~B3 z?}cAq=R)6aL|#h#nLhvQ_51qa^~n3<_x1I?&fxX(hYQ*Heq;Xnjq$xu?B5%FU;lBV z6h1fb`+K4By-afBr@& zf4$sqO@9r{@V#;TWkkNl@ykQ^-+$k``@QG$bR$Pb%Xa0UYT*GnP-`Gw%Mo6u?U})S6Own z)t9ZY<4&7A-gUR#x9xGlA(T!&#hrTE>Br8v#M(_a-*W41w_m&C=c;{I^3!|zs_|-TpFiD;7cQbTW5r?)ta#H35YSO;=6lFFYUQ+M-Xd91B7-bin;rZJ zHD;Ic39;PpbM1a#x&Lb2T+M&GZt*zX>-HC`wgq?Vt=K0EHK#t2 zeXEbi|MTXVZgJPYf0DZY8_Q=QuTcSv=iqDv5w2)&sFCdW6yLN3(2!h z{>*3EU2*bX+JNSnq2y3+b*1iL<@7Z}>@}^LlKC`tW2wfvr%v(36kh3?~G zj{3@-$4sfme1{)%k6vypwis07yJO#$lbyK}!x?_35sj(JJo;RFl$$02S@Jq-8?g`b z+&;%mx=dedOG}tBJ;q~MUGpelS}0}}h)Z$qY;(4{tsO^xmDxG~S>`lF7gN1X3k1il?OE~ng9T-s+79*pG{KRZdb?qWs>5!=&z8?{ag5Fv}bFU&a>QD;oe zsf~ZM6C)4kavh6IfMNLt;j{|b62XbqPt5%;NE7V`<#!f-w{(mo-*w%LU_CvMl>A6@ z{m#*tdL~pLUDo2!TPGlhG*)BqI~8wpS*&~=02}wz^%zY`Yn99-v1;YAymu9)&pIuf zkyxLtm+v^Il{+khYI%>mxJKp1;1lq6@~ZKeG3b=sBJL+?#uHitJ&?1rWr1egF&}S@ z)ewZVyaI5*NDAvj^0qsP#7Sl{>D%oCJfEq&Zef+kQj4}*xWr>FVXaGaR~~tAtILyK zAcQpF!4uQAS(9CgIbvq(TRb^~J$3m7R%^+bIZr&#&<4>1?s4H^OT>L=9~(s70K&S) zdUVHYt)w~o-AJ}Td@z*3iq@3NN~9e6hRi2R?dDVG>DQN40+T@q@qmOKk>rT^9jd>8 zR%O9!(l>}8f@xjg_~ctH^u7;DH~R`D^u-D*t?q0api1M8fOOe5qV5Tsw) zOL}o%n@ndV5D}SVjh*UYu{rFroCH@Q9TJSyr*P7k(z}+WU<*;79LYZKt|0mX!&~r> znIEl@BgMCcodZ31>pDzwxC`Lpsm@^qH*88k78W5J#;<@qL5KjTZUO|5BRvNc4$&z+ z6aqvb1oB(hQWOi`>z2TTom}Rv8r8`_%Uhte8=zmpoqPkvLT-d=sFnkZ;3(1aH!;zN zMTbbLKp`AA(Fq8KWTPU|qK7kT-V>=pe8Y}Q#ACvLz5pLkiZM}yduDcg*vfR`!tFTy zEj$s)iakZIZ15bKAe;`@oIN5>C(#<Kk$D-A+(ORY z%dE42sA@v4k^O^QTS`0x222^5IhX`Jojg!cjGRbH;tKc$q)nZ@f?#Rxjf29B8Dbk@ z?nrLzH+DEcVubGrh>hN#5I}>0fdm-JEED=78iWUgOIk$8qaWSx7E%?;Mk@wbR_KFx zE|$4XaaF~PJ99m1vGHG<0OidEppICVD@(~9Od!#K$^fjm41@tF`sro{*2*M7m_pzbfjwZO z1XqJOxq8qCn5_^KTn7!4XfU6V+hi$FwPs;a%n>DIJQ@|Zm2hn)s^Xp)6?vry%p1n}pNkb(4ewJg`g-{ojzDg;Ya4kala5R0PlQTwpFuHBJJN5+R3$A~rx5 z@qm8c6`|ZOn%OqS?-0*V4%nf z2N)rN^4)~zU3>c7p`Q!tg8O6eR9V8KNL_SB4o)MONydiuy&xS=SeXsfNCTXw0V@i=HfWG*PA0^%(n(ZpOh?U2UBCrZt@@k6F@_=GL zhtx_aRU!oJCPpfj2I{+5JNORa-+_?=Kez^1614uti7Z7sA4EOxuANXzh)`1WfRhjs zWCh$HWr)xf5QWHT)*sI_RwikYdqa-^Vv+?VZqOL{gjzsXZRT|28Nj_E)3+pvIxfw) zNoC&2DFQuI2cTl@$t)RGZnd##j0`7*`&j1^QbkIkkPS#EV77K}9BDR($O06Wk}qz8 z?<{z~OoQY+UTeKM#PBg_Bm)T-EwGMACMK$hb?^$fX;^Sz+zDDH8$CzPMdWhAPBWW4 z<;Lz3lMCb`?pMO*p67H4^CBWf6G~+vwV)=6r+5j-n*Gr4LkzG|JPU}8?^5vYg16c% zVkBKrdw7)#xbi@_qnL={gNn=C$CZRzR~e&-_3@Y3yF|p9*MpR{JHnbsA)6!S8ADjh zn8X0?3b|B)XRZU&lG+&86aYtX9h-)eB=Jde-oqk5c`%bVi_9UIiI@ix;efD!`vbP_ zD23r7#szW)2<7>i!1029j0xZYlkWxcV7CUyMMgt1C-^?#ElR!SixEex!q@15 z)}fKv8EyjtM9IQpgj7`>BI9*0HVmWH-PjSf#F_ws2)QvZ2Dm-II{{!wu3oVS1j}5# zW|R{16fi7Lx-O^=nhz}v2k0l1sqA1P+6y3!NJrC=`*jkcNXcPv1zrjgKuv?DEOCP| zF3SS{lWI^l8VF`xDm_J%x`bw3vBC?c#1S8~(uUjB10j*!6Ba zDtG|TGtHzaPP~_yu>xcY&&4tpf^0Ioi~wmBb^@u?_N5uOB*oC4nJsPh;#wdk=1cZ<)7?IIQDpe%O9fNmG zt_FFYB1xHW$UJBzX^AMJnZdc?VR9yc@trm=FuoM?WlB}6#C)0X&J5$NV9Eod6S#Qu zi87C>0j?BqKv;+~iG#=k4$^WlpG-UKL&V9Bqd!p8KrqP45>!-v2_2n9f@TCa6v~Pi z(yu4w72!+BAV-aRu()z1E%5VX7%@RvhyYVKbf#u?5EKX^;;}a9y56%kBQgpr!JDY?4A^6m^%u|v3?>7*A0az);vo)gvlvEyMjI;m#rCx9JdJk!$01QGxtf-A`8%r2t>Yt^MRuvS|$VzV8-f&kXT;yZyb6JHbWb~ViX~P z5_v^q#^%uFR#c?buf3{Ab1s%8G{vH2RX`^62<}|qMY{@I7X{CMIPntvonU~u8VOLs zZFQ2ZVP~==qzwJupF86#+h)o;@_4jCD3OHV_7xy3EMvAly*p$Ldf~E4U;-$v*=I!3 z8f1+^5}TwNXH_a7LshpSV3D_Y)`HDp95EA++)Z^O!WGpYRb|IUUwo~qCRMM1ucZD$ z*)s&LV?+l_6cl-cDYoHMH-X)K&<(r|unikzRhhDmSm2o~5x7-!hdYcgA{V!0CU`}% zkq)|PVDLPWqseTnSD_?#xhB?{jx$5s$A>GU4^MtrM zc|>9+9r+dF5-?ygmZ{nSv#^ZBg|>Z7big_w*pn)8Q3N1rl;oBtgsf(SEDyS1VKs53 zp@RrQB*-z-J~GywP2F3v%&p=3>;6Ti& zy}%h34_GXkYDE!&671^%5JnRSbj$?lVIbc^xL4u`Sq;~dr{}h0tU2#XxO)T%ushHf za1+8NPaqGH&K>`qaYtBh@u+Giuk=J-7Jgu#}<5v!M3olSGY8i!Clu)~HDbOekx3w}R%HC*E zl6iWt9lf$-?h62q`+FonlnBeG&j;=pEMpi^ItjvDMvBDuK!dj-*)~IZ^P!lks*fxg zDKU~{E*P)_Z%xdHC)Vp`@w|3zc(j#>KjND=!ik1QM?A;tCw7svfD+M(Ey%9}9H#Kz zOS=qG8Al*QIG~SkYFT<0r0z3m4_6iYiANNrYeK;Z&@TyLvxK2<$Z~D6Pu>XiXWVgg z+7+y@p2}K?uSEoD3!>iVy^WAZ^Mb(PV$q@}j>^NI_YdhJ=- z6ZKUU0)$0H?twAY0SdiJyJJZQ6fJi=n0L|)RA8;Pw*S!INBGd7Crmt61H;gt=R?-A z+Q?%9aqu`%Z$}wDTZ}$K&Jun|jQ)}sv!6law`0lrro$?8rRMd|grau0qV&A>A&CE` zs4mjS9eWn)%g<|3d;@I0-q-Yi02EBB4G+SC z;4>ng*8oXvm;2&WgdAH-idq9}@e^Au0r(XZFsY8m@Fb8lFHzE;-;Jn79!?t*g~bf< zHn&Zi0;*^>Qgbe$Qt_Y$*{!lP0KyHrYKzEpnKndDGn|6t7Fc<^Xhy|4aF(~Lal^7Y zGv;S|!`t(wL7RtC-V@qS=zOjXV+reeN+G}9@9B?Iech+WVTaYoat-l_Lod*CTj17<@~r!NRyuqaprD2FJ{*9U%zIfoq!;w_yi!pQrAx16XKoeIGa7Y7K8l`JPDp35ikLj&94^?bT^A<@{kNu=NoJOUW1ZhH|L(q6A=5GYS& zb->{upS^+vV&Orx-zoRoHQPZI(FGQI8PoL4aw9%MQU!PJ^7bH0L$MAZ%TLvUS-Nx( zn3x&=HZ!z+h)%f6AGjYqjV@xQu=5ECaXQ(3-O@g#niF8Kp{Xn4JdjouCxWL|HFL>; z;CIpJgseyieWIq6N?QV44gP>Cd<^30gv8_sNNPk3PebU?;S-&HbN*EFTV~=C(k;G7TA=!gT^C2*nOTb|Qr#A%(hB=aF2ooX{ z3}|0;8sY83K&3~ie!@+x2JjGX-l-V_Ai>g`z_;?ZQsw8PkXm7RGR?l6q8p7-*#8rn1^c7%Ol40%)+l?$yhaA8fZEdEvZ@fFwF|MWkw5A3Vlo;tgh>`77-oR37pAjvE zb_r8k?Z9LyGFnV8{smuwmO*c>XLm4DVQJ%MshmY1rQwKl1b5~h%%xlm!~vSblRwI` zE0+^!-_#e)V&<1)D)wWdAqMrg68J8tQvjvW)!T*VNowHXD`Bl25S2iqJPlC;`PdUy zj8x;c;lY9^uX{k0J`cKxJf2QOy}`w>o0pvFuz)yG7F3 z+P_667Ih$2^%GUXxt(}{a%stehKoEpm@A1Sh|w;RSrLpt8EWkVq10A6)psauw!wsr zU#pPQ-J~dbHmFZY-A+Kt8THv45=ix<5!B1V_!p)@LIoQ=f*gmM0!g@vOsXoU0Hcr; zUcOAA76}0DMs4Xx<|k)wASf#BcMX;&-;=Y7HOS2aOOPiKwaEatL|&aFj0#>pnEbe~ z2*27~ep`VgR__gDtymjx@E<0EB|k~U)X-m5Sq2JSZg8#?U>XNsD9UsZw^h;1;dcB;nl0{$R_b78!nfl?YNTA zcwBm_L&SlOlAO@N9Vn8M)kbGnb8d$!EP0_`wFjxg5mh6iYYiFkKN0L02VzML4O}Iw$43on zaEIYDqlCoAw$`QTHP)B$cXh&^m+XfORY`+@Jvityuz{^=mj`eF_TV09RR~ekRsbTZ z&xq&OqJR~z?cntYF+tW%M`60kNstxE-Q=R75N+Egh^VTwvS1im^%H9;GRdk3V!^pB zLt*j(U|hBuDZ#d;UN`joRWrlf0BWD{mG0GREyJI+g~?nOteh2fs-_}|gcxKc3Iw^e zF#=8cipYXcwACs@#zh$f1PARhFOv6KN5phg^Bfos%c&z0c~X*^nALzsw$+B6C5!>Z z-5==%O@6vw4A#}KxH}m>fhv>z-d?gbW_77}hbV%Gw))K0538kv0l3B_R2_3#=1V$o%Q+ERD501Q;}6E1aZ$23Qh+((fCB`7m)b%Hih5d-QI^{$&%3poep`HU!A z^);Mn!$>~(1o#~X%d8+-fqYc>RL6N$&`-t!(4g{MR`(_lF#0;GxvCc!nhNMoCPJwK z1n<)U9#|Cx>pPAlYL{)kB0Ml)gdmD7sSYDw51wS?RnVp~Pp{fB&y8J-5yvcBIAtdw zYrLj9IUzFSQeo?l}AbJyeu3m>iygG8By|n%4XK7EQg?u+Q_-bNUo#MFO)U)FP zj@mW}H{eXGc$xCNE-}wg0cNg<9t`Bpf!w#+3t zeJo%$>Kq$Z0@IBLLz{#qoq%8_s*<8F<82+W2v8la0jMch0$ws}hYaPV!)pT%gULFo zMWCKlG@U9ZZ^cu6Iv96*T~gH(k;$Ski;TMpUOVruL8VYrzd3ixs`GaBkFuaV{5zyz z9n?z^Dr}A=!1YggA%xcEDOlvDayXZq(h$gsO6CFcMIFt^_kh8{2qd*SU>0y`$DBb| zpeq#m$}v(f2~z>idIBY34+Uz6XU589I8;?#`3_4Mk+%((MdNPs7)&;J!`F+^+oYwO zhW6Ua?0Bg=&y|;kS6*RMW{Sr+5m`ZEuat-@$INSY*FQz04m54Hg0)GZj6VmnUQ=`M zIC}MIBsE#8gBuZk)fvhx7vJ1a&wKf_cWXis%4Z3rh)MMjb?ik1oHw^Ax)V>$1Hgs58U!}2e7bd~|DyzdA>SU{B#>-mO`&{`I5(E*AJjb_dd-R5?+AmBhox2h~TOD!^_-%Dr{KG0%_pq*O2V^ICi zBU*GqLFc=?0hn8D66B{8{w?_a5LD?Nym52oc42P>Hc|#JVpnZ20DA0bO_i?J1_lwf z#P8OD7wk8L5VcWv-m>s>4e7;XtEncv9Ru9E!S84@5RdppTC||8!ARufRpfkh#F4CO z4aJ5}4ohtUIzOoGV#F>6MD=ZgigA+x0E+y;#+_~LFW`IO+^jtUG@Cj)9T5tyVra1^ z+6FVVe#xgCW3U)fL>zHfG-7PNY{JD>J%6Y*KQ5}pTH1Js+acW*; z_IVlD_gkw=kg{l5n9I6}=uEeKg?9(qRrH=8P@7i|rKvgmTMLY`y_ZX>S|^31!vH)= zQFAFVx=cH`b&{DIq7dj}pHT}}*lh@DxjAwSWoN!@6z zP+Tibdl^Tv&3}|L9%Bk000Vx!>IBlbQl&aw2zeSp5^JT7#ihf78LrAsZPrD5b6d?e zs8@0w6?)~5wY?}OFxA*=QfOE=c_KXVR4o{tmvJ8ua(9H2SNm5ONiyV}+j{3MrA#0o z|3GyrdqE?T0$S^&Bsd^zh-M|+nP69lMf|HOk4!G!f)U7toVS6gigwmM8IE7aF|9Wh zT$orjWw2gDEyE4T>X^c+P8;xsk!kCY=oaSn=R=F;dd7?#eVZN?ixDcu8VnlTyMuJN zumOw6ebiiu)oJPwYbyI`Zndpmt9l4nbaeqCd%8O5RBIG%srjMEG8E9+fpqE#LI4pE z;#`7WTOg`P={ndChO0wLhTv-w4BE50OYKoS17SyOTrPz4L}8$R8XU#wrwTF1NMr_I zndluQ(|e4yG4twq(V3(OoT&m&4w;HKF8Oh#$rQWNSpId(29*nSf=wwtNez;ptV#G> z?iq8eo{IqBY6<9=xaopA+8}=9iT0fZL&ydOp(?Y1qg}eS5NliD-*t#(GlHT<$krs0 z50f07y8E?Dg7xfb^YmWlIDv{`iTkRBIC@cp2-ZTL9P`;ouUh>t5#JUwmi5_`2efLC9a$o)r*r*6lw{C zOJF}4y{m05H4>E8HI-h?fs!#P;)k8KI%v=>JRcfR?wv4-e=78sq2P`g#_L}+Jp z!0zt^lLth(Z)4Ii9|TfWPjW8KlLg`7kDNkALaDU{2!a^`UJ-|fw(jaF!Dx$F_B-Et zAW`Oj0(KC#9}d7JCUM>@L)ZXsM}KyF1I8+OHL53ai*Vwu;a>fu+V@|R$?KN|Y2`hg zPS~JEz0i27r>yD-0J?8N)m?p4)xYilHErmyegG;JVHl>M?pOq;O6U&Ei*M(u%fn-l zj;f;S)TuJ*NdG}Ns+R-B0IXGnZpE1m6b9>R*yM=xGk4V7ff!fGEWk(;iz9u>r9dt+ zcW{y8hqhs_x~r;O9SFK56LbmyFu>Ef!XM0s3e`*5ii-0?GwVGl+Tj>}3?^fhJDx6! z$CFy?-X{vEWB&(B`^IJx4ohgo8lz=(N5LO2yrU zN;s_QW@h%i&f+$;1)L-JXR9pe!1BzwVFtn#*JcMAXF7zv%bMMaBX4Btj> zbn;Z0PasBZ5Hy`CS8rZLqiCN@wPgK+tl>gc24#$Q+`L|>Y}XRo(dRTk07s3KATIOr zge-6#bSTz~-ip1GyiHhmBf)&7L|`wRFT$oX8xJYhk{^uBgDl4U77&Ra%Ao(P~HM6a)!D zh7ovGW5#?R*MT;MS6YtfK3xTsjktH8e;^gqU6*8?&&3!OR>CJ8$2xNaupkRn?mPFd z4PP|{pb4PkgIpnaU*iDe->P;{N+bk;Y{)|g%GF7$gV(zD>$f4)LP?}wJ4|MPAa^*1 zkhAEzHo2i7H2eEtDJ7XYCH3#20zFa-I4CaYK^!Fr{}QyMBh-?IyP>n@B_A>;3BFv zbPWpk=)iH-nIRSv|Aq`ISQKG78UYKThAONd(XFmpHTQTKz}1UBU+l?tH4YV7KzSs- zLHe*{@3>cx=4KxJbP(){Iz*KS~)#~azTRSBUouf~9i8^Pc!(?O*~ zD^8@-DvMI>z+NgOCWV$hzeD!b>p(@*m05DqxJe!;4TFvp6zN1%OhX?Laq1;2Km|Cy zy`D;JQ~mP#Fo||`6P2G{-)}40U3kYtfMDO%i`T3cSH*R45|TPHMlKh9tjH8Zl)(J( zixu2aHCe<&EC+QJv>B`ZNzfOK$`b|D2!n&{)Jz{4G^h#sf<)@$Cy_B2xHK7edGNHR zy3~=G>7BBWtwW-cJx<3o^VCPXn0f~zCJ56&yqbDD)H*&Sf|tpln`ucX=2{cgQMvvm)c?ba(8$=4y>+I5NR^Zs!fU47(Gqa1_lyR96Rm$2&k0LH5RLw$sT`t5uJpLW*Ar4?ID zD&aMoYg?ap@Q&WAcz}=I0o$%mi$X`l(3K>BdePa<-BXs#IKsc%bwaIZSKqhlut;8~ z-ox9sWCT$0c&v_e6d`SWBuWNKbTUz*#^X8Q0e!>`=owqYY4+es(iQ|UjR*+S^ZsjB zA8%$-O3SPFRQFV>}`W&(to!4gv z9bH}hZbPS|Oov84KSYM2rMv1S@Sz&+AcrLaya;N%CK4p5A=B&gkMx{KJNdv%{Av4@ zT=JyEd>`u3b=_z8+m!-+;KeE^32Ka78eDs| zZ&p=(qdJBbj*ebxg9$YVti|Q@!IX#((%as-(zJx{rkk!^?>mQ#^;Yjf)Y-_SPvq*# zROxgbV%8zNc3iQbO*&kU4z&X{NDU!S(+6LmJoRZfEcSW};nl+-Ht6cv-@v(!48M;y z0BZM%24ECzyGNb;>Dm}3ZM;4hOy`^!FIMOvw>+X;V2UoA3V^7C5;%`=iKFO+iqhaP z{uX?JYZJiAOi4@hH(?Dl-`YH= zfm{-DSy%0lXq?)xdNpe|UhGv>){57@gLc_2h?%lF^e_QBv%BWjsdsIRHR%)LRF*1Y zM$u4WKplhCViEcBzfsSRkJ;w_4^kD_92iY`*(|B^zB7!Qv7@$TN^?j0c1N=&ob#sE#X%~T>TX0j_{=oLY9 zA&e0W%FHrmB`FEt@pX>?U+-c(%m3V;qg%~c3gwv8Tdh_^EunyfB%%lw$#}qkO)xgW z$Hpc&FxUuVj4=$(HaK829%C?BSOz3OD4`r%QY*C7IaF6yj=OfK`$rcHo@efvx#!M3 zcg{KUJQb~67Uva17u(i5Jf=3K>IhYQwI$H z=XovD|8amW1%3y#Qw_P>Ap79@$=iAI%~zPUd?^<;UXGzElnxp+2^|j!RlOYA-;Z(F zvF@z!d3)-O)g{uvG)#OQ88#OW8gExW_v&-E&9z^*_L7Mk#=N7QW8D8=fc}3wz6Lx- z7qIuAzZ_y)&uc7buEJt%24(}6^09YOQQ0|~V9%Z%jEoQA_u2RPDmEA^R++Z7Xs8;YH$ngUtRY6J>zV!8vh08f7G}ExSuXM_XFy$ zVPV&YhxTwg-k|_(^|u4{Q(qQ-1J(xi^c-U2{%(dQQxvrD>5!YZ$B*h25{1O`?FR{^)%kHhK$pr|Y8 zsz$M>P*fFMf(4J)&t!HIB(Pa+NUDHKaFC5Ad9`_zb5G94=8vE(+Qn!39;#V>(-+77 z3($Y>SP5)o4eVMA*~`HH;FKyA$|vmP-M&9@tot-yyzCiZ0+<0LI6VF;5C8Pnm@R%J zQNSVDP=zc-rAR@^0WyNgf~Kn!6%8GoMbqaHj)uu6)k6{2%-J!v8iv&Id|#v2hf59$2s!7CZ=ZKlYj@ zNsq_r%&+DXUFQRO8BBmUkN@`96rFy;r0H5b6GQ07X7P~AE5wsIiUr8!R3@W&@;M2Q ztsaZrN;aFuC7kLLXh?`E`$jV4*S; zV1CDRwr+n7fda{N8p9CqxhnB`E0IJSc_oV=h=hV6B9mi8Qeg~5A)m^ViDpSAlSC%Q z$Ye6i?Eea?y`Jv2Qyg*cBdo;8r{k0oV|%TG<10UT?V`H>$f*$5u;zdE^m~EA|Env^ z116F&+;%Vh>f4Nm4-n7xG92t>)RRUW z>p~h>h@n)$&;umY@9n+$TGN`IRYOhx`2qd@n^rcx$!nM0yD^;K`l**^f1hd9SFrl5 z6{B;1-@Ims{k}q7cuMM~1Ix?X(gAn?DD5dxI#^;YC06rII9h^m8LUM4CIgJdo}zo; zk0_!W&1wZqS$P+3;1`^&m_4`8R~^y_Tdy$7e$&UKeQ2($s+Wg9w!p5AA9Zp#j8 zx-KP~j&O!o;rvkm=L=0M9cK0ZXUsg_D( zkfyX1bGnM&3Lg#D84vwz{nyt>yM+H=ZKx%E&&F2EPew~T*6%pEYt6dIiVC%LOv9Ny3Tj&peAS3jV;w->?c#T%#wLB=rYsKo+__udpq0uc&Mvl?ma5e#d6QnmbwM~_{{m=2Ks?XzzR5luD^MR@xH$&nbqi+bt!NbaFT*?n8-*k_4OA4cGhnFJ&K`m zdiXTqOpKbUIV8# z0hHwO%&8b96_+cF&s_)DNT#MtK)~n4ED7Y47*?g0mPR+<{K7W?l}Dbso3-!0jVLXo zA~+96dMgv2r3`vSGk@gw-dZN%*DYz<|Zo1^o`dw+0j>HCZRUBF2HUIcsQzdQ4_ zg>M{L?|R4gzH(&o4NddEJ1fxKb?;}+1+Fej%p{Nnw(;`D*Xc?3(`cN_m8&1*SmZcr zUgqS{?F4)Z(ZqY4Id>X2UwR*zfnC`B3)pvb9}5<(D92P^0=@ujE1UW*;5dDUU!r-| zD)tZUqi;gwszsj$X7Sx0bx61=)~jQwMS3{OvTQ*VOVLw5Ewn;Et^@muS# z8F@4|Lm|+!?5t~Vzk2@ar+>NO+hWC`3jO~UqyU(1`N9opu1x{dPH4p&wA{xg6|!iszsI3FmYy=fbQ02;_L-xvRP6Q&)j}EAS3K|IxSk z+5RCGv@f8kHiSt@lSoHUj9i&ciDa?@Ma3YW7f_02AdvwT096~s>#D+HwxAmZki%vZ zF49m{>hiCe)F=a>aMnuRkC0e&4}d% zs2fnwi(u%uBlT2!Jh*IDrqwnO4^L3#H@M{s=aEkL@at`75*ax`E^!2ZFp9rQLlrc% zoEftgB+!tcN^0ij6?XxRKwnugR6_ba5{_}a!p&vIDwcx*FO((yma?6U@cbJ;W#hqv zq)aXfib}QDkD%wt=b@-f(pu9ccE?GN$O-#m)P*UY0|dKzeE^R_RueCgT1 zr+{(b1mAr8A$IhJnc31oMZk%!q{!wIWR*0zk^!O>!EjP2Kr*YK9@DdJF@sn7IqBG^tss>B;jkuZjcSJrZl>!Qmp&M(`rdG>*TI-hoV0Y<^jXg-2s7rkkt-x=Y^`MA;3+y9 znwZsfF3?<-uyk2^TY$|x{^Ykf5RYO6nuzDq1SFlHRzS}5lMY>sq~*{uW7x$4qFKP> zs-k_?Lb5rPTQ2Mb7GtmrLyI6u7SzchlFn%e)&*R9+f}sHHsW)d(bP1mkt40E_|CJxr7spnHrufl^9ac(HJ%y*fmR|pGm0wV z33!R8!^Dz%@!Kt&J$o*fuUyQ$)(W5jXyK)`KVa+rBb+&VIilT#vx@ z;w7^Y`aq3V@~Mn+b;B%|6?cWF~; z;q(P$b6JiI_TYCos1G&ZusO)9c~&i3!hxP+>_2gYWU+|H?#7IctQ8Ohot8$CrHjv@ zv96YunhNUu0VK`^)&UF4KprEO*vBhxZ)M-flNh1}r`JV6O_Mb_m{uDkd}=SNmtRP8 zV=X`X#bY!yEnx4_Jy?BH0VRJRgrURu_y7QQyN^sJNwH|)cDe9-T`XO^fD0Ec!j2n^ zArKY;PS&pb8e4Y!o`)a&N34<`xb$PJA;&W>+{U_XZ&KZI7HL(Zs3fTMc!`X6gX~9= zykwFvnO0F0h-R_?)CX(9$Rh|chM}XEL_o#ika0OAoK6ciTMC!mOJ!w<(V<@40^EJu zomhl6-dX!KJ~*D>y1)A@>F5yiy3PVt01+Pf)x9W!ouI{oipD$JUS}{e&iuKTvVO-p zGFfQ%Na&6VYOCjg5Wt3j>F@6UyHY$ECzH?McZIOXW{wY@B$~}LuWc4Vx0zx|qi8@{ zNirEdMTJ@7g0oj}^%a+M?BKh&-7-sOF9G6Z7o)4JTEcW6+=61*h~$bKI6lNsB#O`N z$L(^E$we8J`te&UnA0$i;l2ru9`0rTiEga!5EX%XLhd07`KbxCT5MppVzt^$py3#myW%y@$20{F3k7`zT=JjTfFECImQp@nR}{Hk{77a_&_Uh&`H{x7N9Fxib?{H(+${&MpH!63KDjZB(x$(l0+&yj4ap@1R0nDRuBvv zHXE`G-liz%9vpH^$4aJr7nF zi_g9Ye;~xJoqGX^6FrAHopSM)^?yb)U{?KEh+@04CX!1a%OV*y2PP9Wp*m#Q!bB>@ zL}Hkc*d)nJ5=sVstAyK;M$lsn_3lP66*>FNF067***2^Ix=E+Id2!u~L=-c-j~rpg z;e8B@4N($GSe;gi#Tfm=hiGnXAU2U^deeM%Za>Dmd-l^&(gk%l#>V_Bj)CHGt z?@gcM*x~mPS6y-D8oe;aw7Pce0_;2aE|c-YxMT-Sl|cj(xU5dnN`Z;^ATC>pvllMs zt~>AGg85%&?(}o9$|j%_n8mK0cauZlbgabAo+0)fdY_c0Qq$bd^qI4^47wNkmZ<^iq+WqM~XV4vQ0;WWi##BFj>l zC>aFpk^0bO<@oIq;COlB z%w>Oe7x#YWMh5b3Lem!^IV)ITAE&;qnH_s}5lg3;G4o8~$s~LC?<5>Kia-mhUPLJ- zu)8V=`fJJMA(75wGrP#=lgP4w*(_if%9M9t=ztj!3xeX{tgaB3UsS`~_J=>_j~*}Y z+t_#bMbz{Jie-HJNVv>Cg1%}jHVEHose2rvNao%|8&m2G1jbXB5H~WaClSIZNB%)c; zsW>`5#^PgyY8%L?QIt{?m%D=Pd)87NTux<81Ck^Ws_-yx=3G{-Si#w|&L!xybK>Cp zw6wP&37s4{`aTu@AWp}Uvah?VY$NSuRkoQ~7cNC}da>98WMV^D^+`^gI6=`cGkey2 zdQKi7GCsnBc?&R%B9dTcXf#QMFNi3}OlC&ViXcdKl%hr=ok14BB$yBd6@&tUSVWQx z95yRXhZTQ~8_|?u@bqpL&eo9RY&oq|Ti#MsSGH1D?=9Q*k7v+6Owb$H9ZRv<$Jo@&0V zPtY-=it&*#_8mS*Jf5N?N*Hnem#FIaGEe^I2433!R|MNM_J{jul$}fr z9l&dDL6!no%x)6-9En((lF5Nh@}g)qjzoua>w3F9L43CFttv`nuGgna6 z=%-LfA!rIEC5A;XXsMeCbW&YoXCgXCc=9kqLqoLIx6sr5C#q|Mz~b`6K_vDJ|832^ z%v*L1n0+K-{nR;P1WbKYwp@m;m*_ch5SQIcG<=lt@c}No?bGIQ@sf+_i|pa8 zm%hgxw>=2LWo2T~45$>wzk{{vEZ}0+Z~GQ+eXx_>ks)eo=aA3mnNb5-MMTX@$d&*) zI)N$&!;{@yxavX{>s5H$KgEl$eIAQ1fZ5-|{cFC3$9z5xb1e;ZaTFm(tS}1J6kcZl zK{1e2sIb8fI~zuODSmJbS2QIUZbRmvxk(h||QQ>ye8VaIJ zyotMFNjZoz&hYTdBx4h-JZm9~=R8oB%8w%KKqJG4zroQHJzRO&_sYyT2}%LX7a|BI zhPr?KA)tGJy*&A=FY$-PoA>oQWYK4gnP*Zd`GW_Oi0vn6}^Xa z#>b=Ie}dR#jMnKva+$qkywe$uMaji%sFN1lawUme2H7iPt*Rt(@;w%uc`>Du&dA6I zxNQ>GUi3xW6*rcX5k4S>+ugv-Y1d;f9l&aLlwF#SC&fl_SGH5%aBG?12~+A>x};3} zL_DESBCc6;!LKLN`?=&4*v>})T5NznGMlzY-e8GbYJz#QFE3BP zIub+2uzD`#H?KTJ_o)#{b zP9~Bpsp(+VMVGN){+V=ko=N}7eVjV6k@<5kEths|1wJUJ^!!-ui$1m}`4p84Qk%@y_NKx$WkAxOUOmeEX+g#%2q$ za^)u&4NvgvKR!%GuRtw02{`Oz^&;6^0hhf2i)i6gcodJ_jmKp}6f^`uK-D0xd$i^uY5`dM;rUmqk z@8GH>%ej2jGJgK^JD~`_{K-oU4Gra{xr=m4#c8i(+pfKMt3&wY z9P`@UEb3a$%P&5`U$<;x{fQ`Z=iP)c{t_-v3unw6(4AQeT8ho@zs`)NMk?B#_!lmWwM>-8%Tc-dzez6wh>t$`$eKh}n4 z@VWvtH3jKC_BI}enPqdnhN|sn*S6=l>DpVE({MZ2Ub>j${e74;8#&!dQ3JQ5n!Kih z2{c2&VR51BB@i>HnvSZ0sbs}wb|ML8R6`-B1W-kUYs^JKCh3b{`>xs8%t8T+AschZ(XX>h}c;ue1VnX4AZ98~t%Vr+^*<+lX%##*oaD1YO%`Jf? zO4nH}Tz%EKoIR(56T{n3v^a_QAYNT2JhF$*RxdR*w=iSoH7s4xN?-Rl$9m+qF&_W` zAOJ~3K~(yvZ=6mdm*vFiqYU=-(bhSGX~8oniA7#}@w-$vO~>n-3B1F7U%#A=X2EpL67MQ7b#CQHG8EggZu#w{y+;^M2R@Vi+u>#IEZWG7$w@{bXub9r;~&BU{57N7k&?)>UQC}I#n5UB7~ zuhg}+rThB4KsHI;7!QBsja z8BI6H7P3>)EjdXRa||ZJbk%nunKd??c!jIxt|Ax+^8WVcu}U+j_cbCg%F+J4v^LEL zvxv(fGc>%7-~Rk%PM_?dr7FaafAlSmoF2y?m`7f>g6JfrE9iz!ifvT6>L5GJ;*RCq z`GqfY&$^UA z)s2LQo@Qk9I7^nDPxs+bcI-Tf&0ojf!BbcS6BbdzZFe&sA4fpK<8Wg#6)+6YbkH;b zN)nWG5Dl!78KtOU!h|G>2qx1BuW&uB$<4IQVD!cKbpx*B$q@MMB1yHNsmOZ zn@TjfYmp3*_+)~7#)H*ViLN@ZOXGaw?(eaD>2e~mC=HEuTzToISik;N#>e~E*3*y0 zGo7}Mi`aW)9JjL$i)^D`EvpLwYX9EM_-Q>r1(7pe6 zOq*e1s%>MUOn8O>8)uyPBw%Cx_J8Cr2ad6OB*oY6{0>*2^ZoMqaPshXx%4ZKa%gx2 z({;DbE2T9EYXVqZfXe)7t?b(IkKBL9LtJ(Kyt30<1#Bic8NpN0!FL~BLs1v#9yds2 zqZmaM$!bLu1TsaHf(BTvSW(N>zrw#>6fB5;YXknpIcgD7g(v}cfNV~sv8tY*Xc@cuY&y|)8LpuqGw zE*iuZV&nZ>dclQM1p|EYbDyVUZW9rqnw;cD9gQPPGNL$D9HxKF<^w!=-`yNJeuUGf zhpDKn;l!!a^bd`2aO@Oajq@4Rj?-Ry20M-%W_m?46*e1QH^gE`F&O6CcRkGTz(JB@ z2f5)h4**vI2YK?zPq6Hqn^`#TdVc!iA9?$&Ewt4d$mY#F{=hNd9bhi^J@z~Yj~zfo zrLL|8v1ZBqHDjtyxR}RpvtchqSU9bk;rrQgsGr`b!Ism5 zoC=TNa=39gy=0X<8AU-fo3WW4lvEW#C_#y-8psbfQwcCp0!$x$E&&1`?v*~wKe#K% z7qeI`R#KTfs#-)W8Po(SiN+@o9qQ5d6h`V3Z|^B7*w90DPo{YM7qkEuix5&^4(U=k2a zrt)hTm@pwrG8WmwmaVU{>%c~K_v|K_EOK&m5K*>bksY|*0mibY2s(pEB>~Z-p%r5U zDn!m%xs0o>yoLqMU!tR>nmKb@%E9<*pp7LaZYd*<^=id!1D2vJCAZl#d z_!_TmTu(*}@xuFWldbGzPIWB>!yr-6P?0c65{7QVWKwaM&1lBIQl$1VfJ>$lrIM-q zvGmbq`tZN0M7EH{W$|H@bTnPZ||R$R_11i^+b2n2n#m@F3Z#Ug&Y6WtIn1FD+B z5R<6d5W#?l@yJP9s^X+$Jvd!$fWd3e-%CT28QDCCO*_|8U0un^p$Vop&ZBGYQnu{< zDeW^f?Dj@%wz(XQ43gK2<5W~p3YCIBje0cgs^M^g`Ly;leb~mc7 zVK-Y41OrXUGc#^n@EsC~eyn*Pe|mibsrYer?Ae1_%nFA25$|k&4J83fyY3*R zK&GhUv^eniU5HKf18dHj*1?yq{xnbA{WDr;&7-e>h)!b_yASlUV9qiiLRIxF z=Fa{s)9R{eM9iXu%VDRaYRD!7hgoEH-2%*_6#XCOJ$HvMM|Xv;zQrMWz8M8e1VxWXR`C~E?#)`CHlwXxGURH#VYn6AK{gCKcls& zk$u}=Br&#unx+tNie+b?gH7}ii}tePS9yN9x5W;!4JAE- z*)y%o2iloA%|bGsARJCm?f26;eKtd*{iL#EjD=6~@B`nb)?dxWeM88Ch}~kxESr%; zY04~6qGU2*k<28rNi67;bQPy85l^1RL>fuZI5yBnv6w;{v{$(HT= zSiAnWj7=mM7(7lv9c2HJP4x7QVRp8VRZRq)Ax;b*VQ%9zO6ZJD#wlUryrq{i8js+% z`H&3*^ddoz8EHIY@YdGde6W2BzkcUE&a8*Cm)yj@y}j)3-c4UNf~_#j-lNC4@v`p% zN4fLfRWvrv3MTBC4!LeSjSiNhlkJoemkz*aWxe4kVy%jy;P0RqnY>42F` z`UQUVyWe7nP_kvH^=#*f$4&rluDts^#-m5L?7SPOvtGrh?bJs;v2N%HhVYSFB?=-U z;ITVESMa;t2xv4`S2Inm!XNM=iza$UkCQ7Xd~o=EoEfl5bzpdyjK{FZPMkF>dFMbM zesP$J9laEFz~aE+lIZC_$%3YKX4lVVU~Dh4RE;Qj@Ho7z+x8aKeg_l{WI>_AQ%O@z z2yxtRtmz+_WPCDAd#I9S3$7#+k8}9YR=hSJIZ>j$VGa}FK6V{=ljd0q7|+<)+8?Gb zE6^-Qsj8~S?QCFRe1!M=PEzBlpwbm29t$Iw&HsHNEdBR;Yr@${V#!HbYNj)zsg=|H zNAP-VSfwKS5537BHk{_K>rZg-&=D3cIfGEeY6g_ox$k@T^Xy-Wtbg~n93NRrrnsG+ zzIS-#)$MHhU^f?k@^d&K;7VXA&%b*QZ*6`HhuKMI(-PGD2tR(}%OvC)1e1Wt zWJ1$5bVEloG)kosf=NKhWhfN#m`e(i@sn5t3x)gy7Fi&lo?zy@23DPa9y8ioShn~g zymmh&U1KO3!D@Ffu9{KQ5?*JJ$wZQ4rw^f;BovbgyUT%*R&d!xf?glt_!uF7Jr0{2 zMM+|FNl0pzLOy|7G>AlEn9lv|r6q?)Bb|SntFO40SsiVxXnUAv)_snrfBy^(({Cf0 zjFU``P%s7v`83WvV+Nfa4IpHY#4gso`yvf>H5}|)hhTw)3zx9>*mi2GAwLO;1jOQy zOF}9MS`qwi2zVrfViS4If~JbtEM9^h7cPs2piN+?gWP%XVrDJ>B7b=9IsUTs5NUG- zBatu;tB#;0h!!MP%vsC>U%d;VkYRLmlr=wmkVMf#L9k*J9N4WAvLur$rhpMD)u;FkSWQ#EpN(NE# z;4yMU5@F1eg_>X;vLq3Xjw1*nwUu>XWXUUW8tUulnmZ4}(Ac?a7rg@~u}B_NacaS9 z3gt+c6{pQNRbZM|$yqa4Eq03eB-vsFpV^8mfX(6}=p@^Rm8OPh8s#U z8Irlv)P)>CfmJI$!8;o_5e|=HYi>r=GDwn6wlKlzv3{IV6|%TKgISe?75e z53Q}U$te>Ij_#$drit#}egp*~Q5X+HHVKIWs0FY|;Iu+(0P+T41gP{)r?aht3sx>= zN#mJiqA=C_`tqB9&p*An2?akB@gx;43+M`yMuB>dlew+!OpcvIQ(=4ed$>YN5G{UC zvt)BgRIP}^YQ^pFAekYNjuTCt#6cI8ej5{sgZO;`E;{FO1T1{@;Rm_l((4#jdJu{p z48?*{n50nbM>i*t%}pQ#K}*qI*N#?%Q^O}IY6@ZLh`a@}p@Gjz$2e@CG?JmZsL@$BKZ}D&euYFbsoyI*lwzNFEE3 zcps`ZLWReR>D*f{F6D~~7DFbPNl{b^h=M>{QzI>nEvTOL96J_cGTez(ng$xE))Ab( z)5w-XTyeupBt(poj-n(P=o=;+14)Eb2D}ys#~~7dLI!koDkqyMLdKZ#r86H39W}Y& zjB1$CT1QQ&kuP5Lb9#n$^T1>Oz|n95w|zRXOpXS(2d$7HVHa=-2BH=x9X*C1IKVZ-*j=rc%^W7=}hi-G!iMu-Xg`9({=lcM~B`1BE~onncOH>wobB6pkxVDBS{)P$8j7l56TobdF$`r2 zSV6>P^CJot6h$QvveD4chDEk8G(1Q+8pR@;(R7ViJcY~SM=)e!$ry!#j^FM?EkZJr zLKXz%&^AP49;odka&}BhZ=;mUgJ3jal^SrHT?~#LVeZUMLcsvhOq}opn2ekvF?o_zD?i6) zufLU--`vW zYG)!jiqGvr7G)H5iXb{{4m3?8p3cxz=cKK58nS3+V5pBwK2LS97KhzIGM!|2=l}q* z|%z2;axO0!JS`v9Gwske&-3|Mhsc9QYdOzB_BawCE0wQTtTHK zSWPS$L)BD@nu?)KsbN9VF-tPCB;#1wi5vUU)%BJYbj^F0wV6VOnEs+PLg? zySloox+*KLalf7W2_C+kmD$*$ElLVy#mR_$_TFo)Z++|A`|Mc0 z8$A2yl(1SSFEWxe0na6h=fr7Dqt;}ZU!#A0z^&K5$=%N_u)7Dp{EofeWjGHg%PJp? zhuqxRV4APUD?>U5-{S3GIpMc{`@iyw4>u?qha8?w7@nmpX3%Rs;PLwd!T=^C5uSDn zK7J0X6h<@fU2q-2ZI;10)gz1L8g93sYQt;|aRGq?4O_;vE!f(EUa0GzOkpsUR*?Xo zj3IYN#Oo1fE7+_a^K3e!Qh7mCIcK-qC67n=UQQ#lsd@!jxgaY>H0uqn^|yI^^7s7a zuYZ-n;FLf4vp)tV+<$nJ-~GL>@E70s4)^YSj%5^4642Y&B3(~;^uY`M@mr61dOV=t zyM^zy@SPfQ8tb^YdV>l%|M=0@xw&_rqJ&Dtqfu|-2R><8!L};Y>jCS$LS7bF6_>yd z4H=4*9HHiQ;o&B3BaHaQ^%+TEDF8`~_Seg5Wezs}<)kJxDL z6I6Hk^S}Cke0U7^?!3Xb&i{dJ=XHXz%F!sJwEEPd0@uxP+qZ={`GR`YCk&uq#liJ! zG{P#DJ?CuvoU-%?oQBRdD#0cr&R4|KA<-h?#`aCTAYeWp(P-3oc<-kv%9xkOFL-|b z9wi=eFeYq0V`p!l?q;2KJ7j0O!O#30#Qc9Aj{*iS7C1lqMVB;tpN9`$=V(5pyA7ZJ z=_MzFA-yhq?OjcLuQenLU=+dWq0tKpa1!|P>yRe!rO)>{AD{5gAHv2SeD5jTYYJXR zGdQ0@9Bb3WB89^#9GK|q1rR$Dah+23bwXGzWMta{C)K9M^AQ|IaIgXUA#4V4p2CxJ zImY!3s5>y8LL-223>i7S&I!AFFdo6t_=FduuhDluPw4Lw`b%2PHc4Xfjdve2&hOEn z$7Uxbu)1W+26zn`^&Mhs&LoMj9gC_Pa(F(#vTS_cXFfkATFnUS7PbSP<6&6=We%hH zR1aNwE;YA7xsGW$`y^RLl+20qjAT4wxlFL_f}$*W>py;%99%F5JAa&vA zJU@Xu2avC!+l9o?)$tg1`|#-d;1`hPuw1}=Dd$+EDpisa>ejz~T2kFe!FefT=2sMQ z$GY;qG*NB7QxBl#z_ndLzU2r#tcnhW8qDDNIpkCL!X20`q1T3A`tnz~d+SYp{}2C= zWt3uvyDXvwMOollHLxt=SbJ$hF9hqzJchW(zb;7f4Bu~ISr*YUrzkC4 zM{BEbnh;na%`jw^O!;K>E;n`-eD19c_HGS{a=3ob=j8N+`5gQ}=#*qawz7oiRL=hK zQ*jdKoBtcq9Hvu2==}JQ#R}#TOiv*QpxuPyGq`^po;-&e+wkE>&xNzLcPSX#f{+t*a|8KmItZIREr@=U*8=E7gwUK-;-&|KfW`139Gas2{E) zhxA=V@=**g#_;W9*f@h``>$EWG1KG`aT?${0cn|GTQ*n;V40%}3b0&?T(xCUmXyYz zwq@ykX<<1v%FH6kb7rf#A~diFynrBpk52z5H-kRyuEU$xVs^Ic^fnu~Rzgx)@QuGa zVQP5D_9l!fa6Zu7wi`-8gCS&v=DhN2f5f`X6g_33FHRP)h@oDE-EHN+5`Dq*;f3*v z{-*L?w2b3CekjXbJRl*KEJ_agc(t`!#8Rtc7BU#uyiU&nHCN^));%<=pw6*p%Mq?Y

Oj4L9VyH_4chePYwFOHL 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�XyhyI>Y_8s~eAm15EuPB(JaxBSv-qeb9G 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 literal 0 HcmV?d00001 diff --git a/assets-cg/trees/tree4.png b/assets-cg/trees/tree4.png new file mode 100644 index 0000000000000000000000000000000000000000..54ec506d5f5d789af009629daecfbfa1fc5e766b GIT binary patch literal 11839 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 literal 0 HcmV?d00001 diff --git a/assets-cg/trees/tree5.png b/assets-cg/trees/tree5.png new file mode 100644 index 0000000000000000000000000000000000000000..7cdb96c8d77d0a17bdcfba249757c452699208bd GIT binary patch literal 2267 zcmV<12qgE3P)EX>4Tx04R}tkv&MmKpe$iQ$;Nm2Rn#31guULL`5963Pq?8YK2xEOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4P#Iyou2NQwVT3N2zhIPS;0dyl(!fKV?p&FUBjG~G5+ ziMW`_u8Li+2qJ_CdN3?A%b1g-Bz(u$Jpz2ai}5V~bAOIrHD@s(AQI0q!?cMvh^IGg zgY!OdgcW6#_?&pmqze*1a$WKGjdQ_efoDd{bZVYBLM#^ASZQNcG&SNW;;5?WlrLmF zRyl8R*2-1ZyeEHQIH#{HbDic85?I6%B#2N@MG0lth|#K(Vj)HQaUcJn>zBx-kgEhn zjs;YpL3aJ%fAG6oD?d5mC57Wa=ZoWfi~wD`K%?e3-^Y&AI01ssz?I(eSL(pbC+W48 z7Ci#`wteSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00y&3L_t(&-sM`qYa>S#{#IBjdZGAx)~Z!HpsRKwKOt41sIJfw`z!h(Pusumq>GWH_(ja)kxn z6gzM9W_I?6EC()R;9z$(yEEUs?|tuw5BMJpD|N=fZa|lA*;jt@TH5Qc-dO)VkO#W~ z2j-1!06?>Lh2eD`-q?m)_QU7h$!81JxEc4yF9QyWfDmAMo@(LG1Z*xs&4b;*DNSPm z=-{L!Ikk+;0EXB32%RN$>&5VTQH$+7;T#F6@V`b046{gv%~04(A>KbmQ=yHWgi}F;MHQ_-0dJ_Nxe9883^DRz{&~s zqxAp){L2fA6xBXHpWTy1cD91%-i-jPZh#BYoh?dMOQAe>6S+>z_l*w~zzO#N;5RC> z7inW$Y3Bhc)I73z{X5zLNbCOaXLgWThy7?h@Gmbc9kjb0n0++vw0E`w2|xqGK}#?# z3+{FRr!-ZVD}C)q#74#F+_KpF7HDm4id>P2{C zz$sn9DNREys24-9bwo74x)-I38=O`qYYJZ{tMI{9o2xhXds6>cg%|7O{tbY3XJqy% zlYnRdhu3)wuk&z9Q~8`HAM~4B_9NivxgOhdnZfC*S1+2cnHbrfQ9Mu)mpQ<-l_@qi zK1Hlbo3@Y7Wx^5C)WXTxsxqGrr@40{jWVB4>axxO7{El7m*!|W@!HDNxExuHMqeD< zaJ#IoTT9N&tb6sr80sou1x4x93FNyE`3Tr|A42MGZhQg&w0q0wACAEl-M_rBc&^>7 zUE$drrl)?juu;lW>qPQ({=I%s(k5bcgx>Eeo z=@^%d@Hm%1V`UTF37k?MCoc=we;&2y+R7B|-m-k=H!8s8MI?{ych&S*n4O1!@&WG~c?u>AB`UC*5|8zKi%%*G%2on?_fbd-_ zHN6sXjAt7BTB$7=a6K&WdrIu3&x#FF7WK`~4`Y4v=-aG_a6L>8Pc4q{; zGg72HPE?%I6wTTd{I8$H3fFJneT=-BZD~!k9~ZOYT?#GLG^!H!9G3@FSg5451O?r49j`+JCIpW|8R`zi!%K2lYp2t zzwqb{B27)J8aO`opAL<2%^TaWF;49;%tJ#eoFVq(4F=gk%CON5+m0t^tFSu;D;P$* zw~Wn=Pm%!ySXwbdE5&aKO0%S+`TbND(thIs{1)KVg))C(1@7DTmYV`L7s)kwHQt@f z#eE(sNU%%*rTAz9M?M>AX=t5!Q}s`7evq8eN_)kVCQdt++n=?kk52LacptlzE|F@zEHaX z)b@yr2pnimh6RzMa%s=BNtWTz`|aK`PJg;ie8>20VO9E#Qb*%K2%w2gG66JaDrV!r zd4qxccP}Hw=M`G>>W5K0@`vCw;YnIJ2^jasc5gY;!p7{yu(s*Iso&bHUCHt8Ijab!S0RJJYvp7U(m0bcl0Q}px6kfPoJ{l< ztVt^W`1(tCu~6)XTUJQ>!Ql1Wl-H=5un*aZ6YHhExA6bYh*TsQ4=ITyY2TnOTx{ug p-yro3&%*>0(5&y%AAqyW{RcKtNGdg#QjP!s002ovPDHLkV1jXyFW>+G literal 0 HcmV?d00001 diff --git a/assets-cg/trees/tree6.png b/assets-cg/trees/tree6.png new file mode 100644 index 0000000000000000000000000000000000000000..3d049e7291ec59df1728f27466048c3725454b24 GIT binary patch literal 1245 zcmV<31S0#1P)EX>4Tx04R}tkv&MmKpe$iQ$;Nm2Rn#31guULL`5963Pq?8YK2xEOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4P#Iyou2NQwVT3N2zhIPS;0dyl(!fKV?p&FUBjG~G5+ ziMW`_u8Li+2qJ_CdN3?A%b1g-Bz(u$Jpz2ai}5V~bAOIrHD@s(AQI0q!?cMvh^IGg zgY!OdgcW6#_?&pmqze*1a$WKGjdQ_efoDd{bZVYBLM#^ASZQNcG&SNW;;5?WlrLmF zRyl8R*2-1ZyeEHQIH#{HbDic85?I6%B#2N@MG0lth|#K(Vj)HQaUcJn>zBx-kgEhn zjs;YpL3aJ%fAG6oD?d5mC57Wa=ZoWfi~wD`K%?e3-^Y&AI01ssz?I(eSL(pbC+W48 z7Ci#`wtot%N^t-H02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00Om1L_t(Y$E{XPYZ^fqekN70_K>mQ2V1BHi4iO;IhdT% zOQ0Y*^pIas`XfqyMCe7xFYp)y!HXBMLSYYrA4tt15>3(ZB5jv;dYGNby6&!P>t1%< zd3T1orH}dV&Gn#s7l?fEF`15%^;V zHl`FiQI2|xRC{q0vr9q1$7(&npv6p~y51r?QI75c<)$VGT%B;Q+9+n1sP^K4frEit z1a=x17~E1)Zfe3-XYQ@v_p|WU9T`k{y+x!dRea~CT&gvu6yy2!;GuwVuh-t>_W_)8 zarZAo0IOYaT_f9o{{(<)FOJgDBLMf7qMZrYxgaEpa0~z_-@E|oHL|YUkweAw(-(X2 zL_XNSt*EK>@84dvH4+#{rOR;iw!i_0a6)b@a zQ1_niF2F8xmNUYoO+6n10QN8gx%2s*`>U5G%1up$9M-;LF!)ORz@Gv5O;Z`p3P~WpkJ8cOihA0atffGL$^*$Q zo;{3+zjCWTop#YmUw}All>qu%E~>uLem|dbh zj4I%CBuvu78OHONm=PD0>$mVE;A*=Q*cc7g3XE3zYbTimx%)f?t@J@Fecb&pxpO~H z+ueZO){Kh-^|wjC{YJdvy!P@fIAb(`U%u=LopD~@IZ6EmRh@lZ=s9#N00000NkvXX Hu0mjfJMS;) literal 0 HcmV?d00001 diff --git a/src/colors.h b/src/colors.h new file mode 100644 index 0000000..9eb8c39 --- /dev/null +++ b/src/colors.h @@ -0,0 +1,19 @@ +#ifndef COLORS_H +#define COLORS_H + + +#define LIGHT_GREY_ROAD 0xC638 +#define DARK_GREY_ROAD 0xBDD7 //0xB5B6 + +#define WHITE_STRIPE 0xFFFF +#define RED_STRIPE 0xF800 + +#define LIGHT_GREEN_GRASS 0x07E5 +#define DARK_GREEN_GRASS 0x0680 + +#define LIGHT_YELLOW_GRASS 0xFFE0 +#define DARK_YELLOW_GRASS 0xD6A0 + +#define DAY_BLUE_SKY 0x017F + +#endif // PARAMETERS_H diff --git a/src/include/cars.h b/src/include/cars.h new file mode 100644 index 0000000..92fa02b --- /dev/null +++ b/src/include/cars.h @@ -0,0 +1,35 @@ +#ifndef CARS_H +#define CARS_H + +#include +#include "camera.h" + + +class Cars +{ + public: + Cars(); + Cars( float x, double z, uint8_t s, uint8_t t ); + ~Cars(); + + void Project3DFP( camera* c, uint16_t index ); + + + float wX; + double wZ; + + int16_t X; + int16_t Y; + uint8_t S; + + uint8_t Speed; + uint8_t Type; + + uint8_t DScale; + + // for debugging only + bool visible; + uint16_t segnum; +}; + +#endif // CARS_H diff --git a/src/include/circuit.h b/src/include/circuit.h index 752ac86..332d530 100644 --- a/src/include/circuit.h +++ b/src/include/circuit.h @@ -12,9 +12,11 @@ enum Length enum HillSize { - H_SMALL = 10, - H_MEDIUM = 20, - H_BIG = 40 + H_VERYSMALL = 20, + H_SMALL = 40, + H_MEDIUM = 60, + H_BIG = 80, + H_VERYBIG = 100 }; enum HillType @@ -25,9 +27,11 @@ enum HillType enum CurveStrength { - C_EASY = 2, - C_MEDIUM = 4, - C_HARD = 6 + C_VERYEASY = 2, + C_EASY = 4, + C_MEDIUM = 6, + C_HARD = 8, + C_VERYHARD = 10 }; enum CurveType @@ -40,30 +44,42 @@ enum Decoration { PALMTREE = 0, DEADTREE = 1, - OAKTREE = 2 + OAKTREE = 2, + CACTUS = 3, + BIGLEAF = 4, + SMALLLEAF = 5 }; void initData( void ); void createCircuit( void ); void createClouds( void ); +void createTraffic( void ); void projectCircuitFP( void ); void projectCircuitFP( uint16_t index ); +void updateTraffic( float dt ); + void printCircuit( void ); void printCircuit( int i ); void drawCircuitSegment( uint16_t index ); void drawDecoration( uint16_t index ); +void drawTraffic( uint16_t index ); void drawClouds( int offset ); +void drawFarBackground( int offset ); +void drawNearBackground( int offset ); void freeDecoration( void ); void prepareDecoration( void ); -void addStraightLine( Length l ); -void addCurve( Length l, CurveStrength s, CurveType t ); -void addHill( Length l, HillSize s, HillType t ); +void freeTraffic( void ); +void prepareTraffic( void ); + +void addStraightLine( Length l, int8_t biome ); +void addCurve( Length l, CurveStrength s, CurveType t, int8_t biome ); +void addHill( Length l, HillSize s, HillType t, int8_t biome ); fixed_t interpolatePositionX( double currentZ ); fixed_t interpolatePositionY( double currentZ ); - +uint16_t findIndex( double currentZ ); diff --git a/src/include/clouds.h b/src/include/clouds.h index 1f8158a..3ea27d4 100644 --- a/src/include/clouds.h +++ b/src/include/clouds.h @@ -21,7 +21,7 @@ class Clouds int16_t X; int16_t Y; - int8_t type; + int8_t Type; }; #endif // CLOUDS_H diff --git a/src/include/drawstuff.h b/src/include/drawstuff.h index dff6916..43f1385 100644 --- a/src/include/drawstuff.h +++ b/src/include/drawstuff.h @@ -3,8 +3,13 @@ void gint_dhline(int x1, int x2, int y, uint16_t color); void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint8_t R, uint8_t G, uint8_t B ); +void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint16_t color ); void drawGrass( int y1, int y2, uint8_t R, uint8_t G, uint8_t B ); +void drawGrass( int y1, int y2, uint16_t color ); void drawSky( void ); +void drawSky( uint16_t color ); +void drawSky( uint8_t R, uint8_t G, uint8_t B ); void drawSky( int ymin, int ymax ); +void drawSkyOptimised( uint16_t color ); diff --git a/src/include/segment.h b/src/include/segment.h index c64779a..7c83c1e 100644 --- a/src/include/segment.h +++ b/src/include/segment.h @@ -5,19 +5,32 @@ #include #include "camera.h" +#include + +#define std ustl + +enum BiomeType +{ + PLAINS = 0, + DESERT = 1 +}; + + class Segment { public: Segment(); Segment( uint16_t n_seg ); - Segment( int16_t x, int16_t y, double z, int8_t c ); - Segment( int16_t x, int16_t y, double z, int8_t c, int8_t left, int8_t right ); + Segment( int16_t x, int16_t y, double z, int8_t c, int8_t s ); + Segment( int16_t x, int16_t y, double z, int8_t c, int8_t s, int8_t left, int8_t right ); ~Segment(); void Project3DFP( camera* c ); + int8_t environment = PLAINS; int8_t Curve=0; + int8_t Slope=0; int16_t CumulatedCurve=0; // World Coordinates (X,Y,Z) @@ -34,6 +47,8 @@ class Segment int8_t LDeco=-1; int8_t RDeco=-1; int8_t DScale=0; + + std::vector CarList; }; #endif // SEGMENT_H diff --git a/src/main.cc b/src/main.cc index 09e3fa7..80648d8 100644 --- a/src/main.cc +++ b/src/main.cc @@ -13,19 +13,23 @@ #include #include +#include "parameters.h" +#include "colors.h" #include "include/camera.h" #include "include/segment.h" -#include "parameters.h" #include "include/circuit.h" #include "include/drawstuff.h" #include "include/clouds.h" +#include "include/cars.h" extern bopti_image_t car1, car2, car3, car4, car5, car6, car7, car8; -extern bopti_image_t tree1, tree2, tree3; +extern bopti_image_t tree1, tree2, tree3, tree4, tree5, tree6; extern bopti_image_t player; extern bopti_image_t sky1, sky2, sky3; +extern bopti_image_t mountain; +extern bopti_image_t treeline; std::vector circuit; @@ -33,26 +37,48 @@ int MAX_SEGMENT=0; camera *cam; std::vector nuages; +std::vector traffic; bool stop = false; bool record = false; bool screenshot = false; + bool ShowDebug1 = false; bool ShowDebug2 = false; +bool ShowDebug3 = false; + +bool BDrawDeco = true; +bool BDrawClds = true; +bool BDrawCars = true; +bool BDrawRoad = true; + uint16_t currentcurve=0; uint8_t shiftcolor=0; float speed = 0; -float maxspeedforward = 8; -float maxspeedbackward = 4; +float maxspeedforward = 5; +float maxspeedbackward = 2; int direction = 1; bool speedcontrol = false; -static void get_inputs( float dt ) +uint8_t minYRoad = 224; // We will track the upper Y (in fact the minimum Y during the RoadDrawing to optimize the rendering of the Sky +int8_t viewside = 0; + +int deltaFarbackground = 0; +int deltaNearbackground = 0; +int lastindex=0; + +int CC=0; // current curve +int CS=0; + +static void get_inputs( float dt, int index ) { + CC = circuit[index]->Curve; + CS = circuit[index]->Slope; + key_event_t ev; while((ev = pollevent()).type != KEYEV_NONE) { @@ -60,8 +86,35 @@ static void get_inputs( float dt ) } speedcontrol = false; - if(keydown(KEY_LEFT)) cam->decX(25.0); - if(keydown(KEY_RIGHT)) cam->incX(25.0); + + viewside=0; + if (CC<0) + { + viewside=-1; + cam->decX( CC*dt*speed/100 ); + } + else if (CC>0) + { + viewside=+1; + cam->decX( CC*dt*speed/100 ); + } + + + if(keydown(KEY_LEFT)) + { + cam->decX(25.0); + viewside=-1; + if (CC<0) viewside=-2; // We are in a curve and turning + if (CC>0) viewside=0; + } + + if(keydown(KEY_RIGHT)) + { + cam->incX(25.0); + viewside=1; + if (CC>0) viewside=+2; + if (CC<0) viewside=0; + } if(keydown(KEY_SHIFT)) { @@ -108,19 +161,41 @@ static void get_inputs( float dt ) if(keydown(KEY_EXIT)) stop = true; - if(keydown(KEY_F1)) +#if IS_FXLIB==1 + if(keydown(KEY_XOT)) { - ShowDebug1 = !ShowDebug1; - ShowDebug2 = false; - } - if(keydown(KEY_F2)) - { - ShowDebug2 = !ShowDebug2; ShowDebug1 = false; + ShowDebug2 = false; + ShowDebug3 = false; + } + if(keydown(KEY_LOG)) + { + ShowDebug1 = true; + ShowDebug2 = false; + ShowDebug3 = false; + } + if(keydown(KEY_LN)) + { + ShowDebug1 = false; + ShowDebug2 = true; + ShowDebug3 = false; + } + if(keydown(KEY_SIN)) + { + ShowDebug1 = false; + ShowDebug2 = false; + ShowDebug3 = true; } + if(keydown(KEY_F1)) BDrawDeco = !BDrawDeco; + if(keydown(KEY_F2)) BDrawClds = !BDrawClds; + if(keydown(KEY_F3)) BDrawCars = !BDrawCars; + if(keydown(KEY_F4)) BDrawRoad = !BDrawRoad; + + if(keydown(KEY_F5)) screenshot = true; if(keydown(KEY_F6)) record = !record; - if(keydown(KEY_F4)) screenshot = true; + +#endif // IS_FXLIB if (speedcontrol==false) { @@ -132,6 +207,30 @@ static void get_inputs( float dt ) else cam->decZ(speed*dt); } + + + /* Adjust position of the background */ + if (lastindex!=index) + { + deltaFarbackground -= CC*speed*dt/250; + deltaNearbackground -= CC*speed*dt/100; + } + lastindex = index; + + /* adjust speed if we drive on the side of the road */ + if (fround(cam->cX)<-1*ROAD_WIDTH && speed>2.0) speed=2.0; + if (fround(cam->cX)>ROAD_WIDTH && speed>2.0) speed=2.0; + + if (fround(cam->cX)<-1.35*ROAD_WIDTH && speed>0.0) + { + speed=0.0; + cam->cX=fix(-0.75*ROAD_WIDTH); + } + if (fround(cam->cX)>1.35*ROAD_WIDTH && speed>0.0) + { + speed=0.0; + cam->cX=fix(0.75*ROAD_WIDTH); + } } @@ -140,27 +239,27 @@ int main(void) __printf_enable_fp(); __printf_enable_fixed(); + #if IS_FXLIB==1 usb_interface_t const *interfaces[] = { &usb_ff_bulk, NULL }; usb_open(interfaces, GINT_CALL_NULL); + #endif - prof_t perf_create, perf_project, perf_render; - uint32_t time_create=0, time_project=0, time_render=0; + prof_t perf_update, perf_create, perf_project, perf_render; + uint32_t time_update=0, time_create=0, time_project=0, time_render=0; prof_init(); - int nbInterestingSegments = (MAX_RENDER_DISTANCE / SEGMENT_LENGTH) + 10; // the number of segments to be projected considering the rendering distance + int nbInterestingSegments = (MAX_RENDER_DISTANCE / SEGMENT_LENGTH); // the number of segments to be projected considering the rendering distance - //-------------- - - initData( ); - - //-------------- perf_create = prof_make(); prof_enter(perf_create); - createCircuit(); - createClouds(); - prepareDecoration(); + initData( ); // Positioning of the Camera + createCircuit(); // Creates the circuit + createClouds(); // Creates the Sky and Clouds + createTraffic(); // Creates the cas + prepareDecoration(); // Prepares the multiple variations of Decoration (image scaling) + prepareTraffic(); // Prepares the multiple variations of Cars (image scaling) prof_leave(perf_create); time_create = prof_time(perf_create); @@ -171,44 +270,77 @@ int main(void) int indexstart = 0; int indexend = 0; - uint32_t maxDistance = (MAX_SEGMENT-nbInterestingSegments-5)*SEGMENT_LENGTH; + uint32_t maxDistance = (MAX_SEGMENT-nbInterestingSegments-1)*SEGMENT_LENGTH; uint32_t dt=0; uint16_t l=0; while (!stop) { - get_inputs( dt ); - dt = ((float) (time_render+time_project) / 1000.0); + + perf_update = prof_make(); + prof_enter(perf_update); + + get_inputs( dt, indexstart ); + dt = ((float) (time_update+time_render+time_project) / 1000.0); //-------------- if (fround(cam->cZ)<=0) cam->cZ=fixdouble(0.0); if (fround(cam->cZ)>=maxDistance) cam->cZ=fixdouble(maxDistance); indexstart = fround(cam->cZ) / SEGMENT_LENGTH; - indexend = indexstart+nbInterestingSegments+1; - - // there is an offset equals to 400 on z position - // this is to compute the first index of segment to be projected to screen - if (indexstart<0) indexstart=0; - if (indexstart>MAX_SEGMENT-nbInterestingSegments-1-2) indexstart=MAX_SEGMENT-nbInterestingSegments-1-2; + indexend = indexstart+nbInterestingSegments+1; + if (indexstart>MAX_SEGMENT-nbInterestingSegments-2) indexstart=MAX_SEGMENT-nbInterestingSegments-2; + + + prof_leave(perf_update); + time_update = prof_time(perf_update); //-------------- perf_project = prof_make(); prof_enter(perf_project); - //cam->cY = fix( 300 + interpolatePositionY(fround(cam->cZ)) ); - uint16_t cumulCurve=0; - for (int k=indexstart; k<=indexend; k++) // Need to project 1 more segment than actual drawing - { - projectCircuitFP( k ); - circuit[k]->CumulatedCurve = cumulCurve; - cumulCurve += circuit[k]->Curve; - } + if (BDrawCars) + { + updateTraffic( dt ); + + for (int k=0; kwZ / SEGMENT_LENGTH; + if (CarSegment>=indexstart && CarSegmentvisible = true; + circuit[CarSegment]->CarList.push_back(k); + } + else + traffic[k]->visible = false; + } + } + + minYRoad = SCREEN_HEIGHT; + + uint16_t cumulCurve=0; + for (int k=indexstart; k<=indexend; k++) // Need to project 1 more segment than actual drawing + { + projectCircuitFP( k ); // We project the current segment + + if (circuit[k]->Y < minYRoad) // This is a trick to save precious time while drawing the Sky + minYRoad = circuit[k]->Y; + + circuit[k]->CumulatedCurve = cumulCurve; // This is the curve accumulated when we are drawing curves + cumulCurve += circuit[k]->Curve; + + if (BDrawCars) + for( int l=0; lCarList.size(); l++ ) // For all cars inside that road segment + { + uint8_t indexCar = circuit[k]->CarList[l]; + traffic[indexCar]->Project3DFP( cam, k ); + } + } prof_leave(perf_project); time_project = prof_time(perf_project); @@ -218,20 +350,90 @@ int main(void) perf_render = prof_make(); prof_enter(perf_render); - drawSky( ); - drawClouds( l % 396 ); - cam->cY = fix( 300 ) + interpolatePositionY(fround(cam->cZ)); + drawSky( DAY_BLUE_SKY ); + + if (BDrawClds) + drawClouds( l % 396 ); + + drawFarBackground( deltaFarbackground ); + drawNearBackground( deltaNearbackground ); + + cam->cY = fix( 300+2*CS ) + interpolatePositionY(fround(cam->cZ) ); for( int k=indexend-1; k>=indexstart; k--) { currentcurve = circuit[k]->CumulatedCurve; - drawCircuitSegment( k ); - drawDecoration( k ); + + if (BDrawRoad) + drawCircuitSegment( k ); + + if (BDrawDeco) + drawDecoration( k ); + + if (BDrawCars) + for( int l=0; lCarList.size(); l++ ) // For all cars inside that road segment + { + uint8_t indexCar = circuit[k]->CarList[l]; + drawTraffic( indexCar ); + } + + circuit[k]->CarList.clear(); } + int mod_base=20; + int mod_comp=10; + + if (abs(speed)<1.0) mod_base = 30, mod_comp = 15; + else if (abs(speed)<2.0) mod_base = 20, mod_comp = 10; + else if (abs(speed)<3.0) mod_base = 16, mod_comp = 8; + else if (abs(speed)<4.0) mod_base = 12, mod_comp = 6; + else if (abs(speed)<5.0) mod_base = 8, mod_comp = 4; + else mod_base = 4, mod_comp = 2; + + + if ((speed==0) || (l%mod_base<=mod_comp)) // the small rick to have the speed impression on wheels and to have the correct view of the car during turns + { + if (viewside==-2) dsubimage( SCREEN_CX-40, SCREEN_HEIGHT-46, &player, 99,1,80,46, DIMAGE_NONE); + else if (viewside==-1) dsubimage( SCREEN_CX-37, SCREEN_HEIGHT-46, &player, 181,1,74,46, DIMAGE_NONE); + else if (viewside==0) dsubimage( SCREEN_CX-36, SCREEN_HEIGHT-46, &player, 257,1,72,46, DIMAGE_NONE); + else if (viewside==1) dsubimage( SCREEN_CX-37, SCREEN_HEIGHT-46, &player, 331,1,74,46, DIMAGE_NONE); + else if (viewside==2) dsubimage( SCREEN_CX-40, SCREEN_HEIGHT-46, &player, 407,1,80,46, DIMAGE_NONE); + } + else + { + if (viewside==-2) dsubimage( SCREEN_CX-40, SCREEN_HEIGHT-46, &player, 99,49,80,46, DIMAGE_NONE); + else if (viewside==-1) dsubimage( SCREEN_CX-37, SCREEN_HEIGHT-46, &player, 181,49,74,46, DIMAGE_NONE); + else if (viewside==0) dsubimage( SCREEN_CX-36, SCREEN_HEIGHT-46, &player, 257,49,72,46, DIMAGE_NONE); + else if (viewside==1) dsubimage( SCREEN_CX-37, SCREEN_HEIGHT-46, &player, 331,49,74,46, DIMAGE_NONE); + else if (viewside==2) dsubimage( SCREEN_CX-40, SCREEN_HEIGHT-46, &player, 407,49,80,46, DIMAGE_NONE); + } + + + //dprint( 1, 1, C_BLACK, "Crt=%.3D ms", time_create ); + + //dprint( 1, 15, C_RED, "Prj=%.3D ms", time_project ); + //dprint( 1, 30, C_RED, "Rdr=%.3D ms", time_render ); + //dprint( 1, 45, C_RED, "Upd=%.3D ms", time_update ); + + dprint( 1, 1, C_BLACK, "Dt=%.3D ms", dt ); + + //dprint( 1, 1, C_BLACK, "FPS=%.3D ms", 1000/dt ); + +/* + #if 0 + dprint( 1, 210, C_WHITE, "Decs: %c", BDrawDeco==true?'Y':'N' ); // Key F1 + dprint( 67, 210, C_WHITE, "Clds: %c", BDrawClds==true?'Y':'N' ); // Key F2 + dprint( 133, 210, C_WHITE, "Cars: %c", BDrawCars==true?'Y':'N' ); // Key F3 + + dprint( 199, 210, C_WHITE, "DtR: %.1f", ((float) (time_render) / 1000.0) ); // Key F4 + dprint( 265, 210, C_WHITE, "ScrSht" ); // Key F5 + dprint( 331, 210, C_WHITE, "RecVid" ); // Key F6 + #endif // 1 + + #if 0 if (ShowDebug1) { Segment* currentSeg = circuit[indexstart]; @@ -261,34 +463,72 @@ int main(void) } if (ShowDebug2) { + #if 0 dprint( 1, 1, C_RED, "Crt=%.3D ms", time_create ); dprint( 1, 15, C_RED, "Prj=%.3D ms", time_project ); dprint( 1, 29, C_RED, "Rdr=%.3D ms", time_render ); + dprint( 1, 50, C_BLACK, "ISt_Z=%.1lf", circuit[indexstart]->wZ); + dprint( 1, 65, C_BLACK, "IEd_Z=%.1lf", circuit[indexend]->wZ); + + for( int k=indexend-1; k>=indexstart; k--) { dprint( 100, 1+10*k-indexstart, C_WHITE, "S[%d]=%d", k, circuit[k]->DScale ); } + + for( int k=0; kX, nuages[k]->Y, nuages[k]->type ); } + #endif // 0 + + for( int k=0; kvisible == true) dprint( 1, 1+10*k, C_GREEN, "Car %d Sc=%d wZ=%.0lf / Seg=%d X=%d Y=%d", k, traffic[k]->DScale, traffic[k]->wZ, traffic[k]->segnum, traffic[k]->X, traffic[k]->Y, traffic[k]->S ); + else dprint( 1, 1+10*k, C_RED, "Car %d Sc=%d wZ=%.0lf / Seg=%d X=%d Y=%d", k, traffic[k]->DScale, traffic[k]->wZ, traffic[k]->segnum, traffic[k]->X, traffic[k]->Y, traffic[k]->S ); + } } + if (ShowDebug3) + { + dprint( 1, 1, C_BLACK, "S"); + for( int k=0; k<=indexend-indexstart; k++) + { + int nbCars=circuit[indexstart+k]->CarList.size(); + dprint( 25+k*25, 1, C_BLACK, "%d", indexstart+k ); + dprint( 25+k*25, 11, C_RED, "%d", nbCars ); - dsubimage( SCREEN_CX-36, SCREEN_HEIGHT-48, &player, 257,1,72,46, DIMAGE_NONE); + for( int l=0; lCarList[l]); + } + } + } + #endif +*/ - dupdate(); - //r61524_display(gint_vram, 0, DHEIGHT, R61524_DMA_WAIT); +/* + for( int k=indexend-1; k>=indexstart; k--) + { + circuit[k]->CarList.clear(); + } +*/ + + //dupdate(); + r61524_display(gint_vram, 0, DHEIGHT, R61524_DMA_WAIT); prof_leave(perf_render); time_render = prof_time(perf_render); +#if IS_FXLIB==1 if (screenshot && usb_is_open()) { - usb_fxlink_screenshot(true); + usb_fxlink_screenshot(false); screenshot = false; } @@ -296,19 +536,23 @@ int main(void) { usb_fxlink_videocapture(false); } +#endif l++; } prof_quit(); - usb_close(); +#if IS_FXLIB==1 + usb_close(); +#endif circuit.clear(); nuages.clear(); delete cam; freeDecoration(); + freeTraffic(); return 1; } diff --git a/src/parameters.h b/src/parameters.h index 0722682..0d435b5 100644 --- a/src/parameters.h +++ b/src/parameters.h @@ -14,9 +14,22 @@ #define ASPECT_RATIO 1.767 #define DISTANCE_SCREEN 0.83444 + #define MAX_RENDER_DISTANCE 3000 + +#define NB_CLOUDS_SKY 10 +#define NB_CARS_TRAFFIC 100 + +#define MAX_SUBIMAGES_TREES 12 +#define NB_TREES_TYPES 6 + +#define MAX_SUBIMAGES_CARS 12 +#define NB_CARS_TYPES 8 + #define std ustl +#define IS_FXLIB 1 + #endif // PARAMETERS_H diff --git a/src/src/cars.cc b/src/src/cars.cc new file mode 100644 index 0000000..79853b8 --- /dev/null +++ b/src/src/cars.cc @@ -0,0 +1,53 @@ +#include "../include/cars.h" +#include "../include/camera.h" + +#include +#include +#include "../include/segment.h" +#include "../parameters.h" +#include "../include/circuit.h" + + +extern std::vector circuit; + + +Cars::Cars() +{ + //ctor +} + +Cars::~Cars() +{ + //dtor +} + +Cars::Cars( float x, double z, uint8_t s, uint8_t t ) +{ + wX = x; + wZ = z; + Speed = s; + Type = t; + X = 0; +} + + +void Cars::Project3DFP( camera* c, uint16_t index ) +{ + fixed_t DX = fix(wX*ROAD_WIDTH) - c->cX; + fixed_t DY = interpolatePositionY(wZ) - c->cY; + + fixed_t divDZ = fdiv( fix(1), (fixdouble(wZ) - c->cZ)); + fixed_t divAR = fdiv(fix(1), fixdouble(ASPECT_RATIO)); + fixed_t Scale = fmul(fixdouble(DISTANCE_SCREEN), divDZ); + + fixed_t tempx = fmul(fmul(DX,Scale), divAR); + fixed_t tempy = fmul(DY, Scale); + + fixed_t sX=fmul(fix(SCREEN_CX), (fix(1)+tempx)); + fixed_t sY=fmul(fix(SCREEN_CY), (fix(1)-tempy)); + + X = fround(sX) + circuit[ index ]->CumulatedCurve; + Y = fround(sY); +} + + diff --git a/src/src/circuit.cc b/src/src/circuit.cc index 7a5fe64..8893572 100644 --- a/src/src/circuit.cc +++ b/src/src/circuit.cc @@ -2,6 +2,8 @@ #include "../include/segment.h" #include "../include/camera.h" #include "../include/clouds.h" +#include "../include/cars.h" + #include "../parameters.h" #include @@ -9,10 +11,13 @@ #include #include "../include/drawstuff.h" +#include "../colors.h" extern std::vector circuit; extern std::vector nuages; +extern std::vector traffic; + extern camera *cam; extern uint16_t currentcurve; extern uint8_t shiftcolor; @@ -21,11 +26,13 @@ extern bool ShowDebug1; extern bopti_image_t car1, car2, car3, car4, car5, car6, car7, car8; -extern bopti_image_t tree1, tree2, tree3; +extern bopti_image_t tree1, tree2, tree3, tree4, tree5, tree6; extern bopti_image_t sky1, sky2, sky3; +extern bopti_image_t mountain; +extern bopti_image_t treeline; -bopti_image_t *scaledTrees[3][25] = { 0 }; - +bopti_image_t *scaledTrees[NB_TREES_TYPES][MAX_SUBIMAGES_TREES] = { 0 }; +bopti_image_t *scaledCars[NB_CARS_TYPES][MAX_SUBIMAGES_CARS] = { 0 }; size_t image_size_profile(int profile, int width, int height) @@ -121,15 +128,12 @@ bopti_image_t *resize(bopti_image_t const *src, int w, int h) } - - - void initData( void ) { cam = new camera(); cam->cX = fixdouble(0.0f); cam->cY = fixdouble(300.0f); - cam->cZ = fixdouble(260.0f); + cam->cZ = fixdouble(0.0f); } @@ -142,33 +146,29 @@ void createCircuit( void ) } */ - addStraightLine( L_VERYSHORT ); - addStraightLine( L_VERYSHORT ); - addCurve( L_SHORT, C_EASY, LEFT_CURVE ); - addHill( L_MEDIUM, H_BIG, UP_HILL ); - addHill( L_MEDIUM, H_BIG, DOWN_HILL ); - addCurve( L_SHORT, C_HARD, RIGHT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_HARD, LEFT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_EASY, LEFT_CURVE ); - addHill( L_MEDIUM, H_BIG, UP_HILL ); - addHill( L_MEDIUM, H_BIG, DOWN_HILL ); - addCurve( L_SHORT, C_HARD, RIGHT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_HARD, LEFT_CURVE ); - addHill( L_MEDIUM, H_BIG, UP_HILL ); - addHill( L_MEDIUM, H_BIG, DOWN_HILL ); - addCurve( L_SHORT, C_HARD, RIGHT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_HARD, LEFT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_EASY, LEFT_CURVE ); - addHill( L_MEDIUM, H_BIG, UP_HILL ); - addHill( L_MEDIUM, H_BIG, DOWN_HILL ); - addCurve( L_SHORT, C_HARD, RIGHT_CURVE ); - addStraightLine( L_VERYLONG ); - addCurve( L_SHORT, C_HARD, LEFT_CURVE ); + addStraightLine( L_VERYSHORT, PLAINS ); + addStraightLine( L_VERYSHORT, DESERT ); + //addStraightLine( L_VERYSHORT, PLAINS ); + //addStraightLine( L_VERYSHORT, DESERT ); + addCurve( L_SHORT, C_HARD, LEFT_CURVE, DESERT ); + addCurve( L_SHORT, C_HARD, RIGHT_CURVE, DESERT ); + addStraightLine( L_LONG, DESERT ); + addHill( L_MEDIUM, H_BIG, UP_HILL, DESERT ); + addHill( L_MEDIUM, H_BIG, DOWN_HILL, PLAINS ); + //addCurve( L_SHORT, C_HARD, RIGHT_CURVE, PLAINS ); + addStraightLine( L_VERYLONG, PLAINS ); + addCurve( L_SHORT, C_HARD, LEFT_CURVE, PLAINS ); + addStraightLine( L_VERYLONG, DESERT ); + addCurve( L_SHORT, C_EASY, LEFT_CURVE, DESERT ); + //addHill( L_MEDIUM, H_BIG, UP_HILL, DESERT ); + //addHill( L_MEDIUM, H_BIG, DOWN_HILL, DESERT ); + //addCurve( L_SHORT, C_HARD, RIGHT_CURVE, PLAINS ); + //addStraightLine( L_VERYLONG, PLAINS ); + //addCurve( L_SHORT, C_HARD, LEFT_CURVE, PLAINS ); + //addHill( L_MEDIUM, H_BIG, UP_HILL, PLAINS ); + //addHill( L_MEDIUM, H_BIG, DOWN_HILL, PLAINS ); + //addCurve( L_SHORT, C_HARD, RIGHT_CURVE, DESERT ); + //addStraightLine( L_VERYLONG, DESERT ); }; @@ -176,10 +176,10 @@ void createClouds( void ) { srand( rtc_ticks() ); - for( int k = 0; k < 10; k++) + for( int k = 0; k < NB_CLOUDS_SKY; k++) { - int X = (rand() % 1188) - 396; - int Y = rand() % 80; + int X = (rand() % 792); + int Y = rand() % 60; int T = rand() % 3; Clouds* cl=new Clouds( X, Y, T ); @@ -188,73 +188,45 @@ void createClouds( void ) } -void addStraightLine( Length l ) +void createTraffic( void ) { - double lastZ=0; - int16_t lastY=0; - - if (circuit.size()!=0) - { - lastY=circuit[circuit.size()-1]->wY; - lastZ=circuit[circuit.size()-1]->wZ; - } - srand( rtc_ticks() ); - for( int i=0; iwY; - lastZ=circuit[circuit.size()-1]->wZ; - } - srand( rtc_ticks() ); - - for( int i=0; iwY; - lastZ=circuit[circuit.size()-1]->wZ; + lastY=circuit[lastIndex-1]->wY; + lastZ=circuit[lastIndex-1]->wZ+SEGMENT_LENGTH; } + srand( rtc_ticks() ); for( int i=0; ienvironment = biome; + circuit.push_back( seg ); + } + } +} + +void addCurve( Length l, CurveStrength s, CurveType t, int8_t biome ) +{ + double lastZ=0; + int16_t lastY=0; + + uint16_t lastIndex = circuit.size(); + if (lastIndex!=0) + { + lastY=circuit[lastIndex-1]->wY; + lastZ=circuit[lastIndex-1]->wZ+SEGMENT_LENGTH; + } + + srand( rtc_ticks() ); + + for( int i=0; ienvironment = biome; + circuit.push_back( seg ); + } + } +} + + +void addHill( Length l, HillSize s, HillType t, int8_t biome ) +{ + double lastZ=0; + int16_t lastY=0; + + uint16_t lastIndex = circuit.size(); + if (lastIndex!=0) + { + lastY=circuit[lastIndex-1]->wY; + lastZ=circuit[lastIndex-1]->wZ+SEGMENT_LENGTH; + } + + srand( rtc_ticks() ); + + for( int i=0; ienvironment = biome; + circuit.push_back( seg ); + } } } @@ -317,43 +361,79 @@ void drawCircuitSegment( uint16_t index ) if (Y1==Y2) return; - if (index%2==0) + /* + if (index==0) { - drawGrass( Y2, Y1, 0, 255-shiftcolor, 45-shiftcolor ); + drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, DARK_GREEN_GRASS ); - // route - drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, 196-shiftcolor, 196-shiftcolor, 196-shiftcolor ); + drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, C_RED ); - // ligne blanche centrale - drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); - // ligne blanche gauche - drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); + drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50-W2/2+currentcurve, X2+W2/50-W2/2+currentcurve, Y2, X1-W1/50-W1/2+currentcurve, X1+W1/50-W1/2+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50+W2/2+currentcurve, X2+W2/50+W2/2+currentcurve, Y2, X1-W1/50+W1/2+currentcurve, X1+W1/50+W1/2+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, WHITE_STRIPE ); - // ligne blanche centrale gauche - drawPolygon( X2-W2/50-W2/2+currentcurve, X2+W2/50-W2/2+currentcurve, Y2, X1-W1/50-W1/2+currentcurve, X1+W1/50-W1/2+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); - - // ligne blanche centrale - drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); - - // ligne blanche centrale droite - drawPolygon( X2-W2/50+W2/2+currentcurve, X2+W2/50+W2/2+currentcurve, Y2, X1-W1/50+W1/2+currentcurve, X1+W1/50+W1/2+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); - - // ligne blanche droite - drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, 255-shiftcolor, 255-shiftcolor, 255-shiftcolor ); + drawPolygon( X2+W2/16+W2+currentcurve, 396, Y2, X1+W1/16+W1+currentcurve, 396, Y1, DARK_GREEN_GRASS ); + return; } - else + */ + + if (circuit[index]->environment == PLAINS) { + if (index%2==0) + { + //drawGrass( Y2, Y1, DARK_GREEN_GRASS ); - drawGrass( Y2, Y1, 0, 255-shiftcolor, 0 ); + drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, DARK_GREEN_GRASS ); - drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, 180-shiftcolor, 180-shiftcolor, 180-shiftcolor ); - // ligne rouge gauche - drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, 255-shiftcolor, 0, 0 ); - // ligne rouge droite - drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, 255-shiftcolor, 0, 0 ); + drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, LIGHT_GREY_ROAD ); + drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50-W2/2+currentcurve, X2+W2/50-W2/2+currentcurve, Y2, X1-W1/50-W1/2+currentcurve, X1+W1/50-W1/2+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50+W2/2+currentcurve, X2+W2/50+W2/2+currentcurve, Y2, X1-W1/50+W1/2+currentcurve, X1+W1/50+W1/2+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, WHITE_STRIPE ); + + drawPolygon( X2+W2/16+W2+currentcurve, 396, Y2, X1+W1/16+W1+currentcurve, 396, Y1, DARK_GREEN_GRASS ); + } + else + { + //drawGrass( Y2, Y1, LIGHT_GREEN_GRASS ); + drawPolygon( 0, X2-W2/16-W2+currentcurve, Y2, 0, X1-W1/16-W1+currentcurve, Y1, LIGHT_GREEN_GRASS ); + + drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, DARK_GREY_ROAD ); + drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, RED_STRIPE ); + drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, RED_STRIPE ); + + drawPolygon( X2+W2/16+W2+currentcurve, 396, Y2, X1+W1/16+W1+currentcurve, 396, Y1, LIGHT_GREEN_GRASS ); + } } + else if (circuit[index]->environment == DESERT) + { + if (index%2==0) + { + drawGrass( Y2, Y1, DARK_YELLOW_GRASS ); + drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, LIGHT_GREY_ROAD ); + drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50-W2/2+currentcurve, X2+W2/50-W2/2+currentcurve, Y2, X1-W1/50-W1/2+currentcurve, X1+W1/50-W1/2+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50+currentcurve, X2+W2/50+currentcurve, Y2, X1-W1/50+currentcurve, X1+W1/50+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2-W2/50+W2/2+currentcurve, X2+W2/50+W2/2+currentcurve, Y2, X1-W1/50+W1/2+currentcurve, X1+W1/50+W1/2+currentcurve, Y1, WHITE_STRIPE ); + drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, WHITE_STRIPE ); + } + else + { + drawGrass( Y2, Y1, LIGHT_YELLOW_GRASS ); + drawPolygon( X2-W2+currentcurve, X2+W2+currentcurve, Y2, X1-W1+currentcurve, X1+W1+currentcurve, Y1, DARK_GREY_ROAD ); + drawPolygon( X2-W2/16-W2+currentcurve, X2-W2+currentcurve, Y2, X1-W1/16-W1+currentcurve, X1-W1+currentcurve, Y1, RED_STRIPE ); + drawPolygon( X2+W2+currentcurve, X2+W2+W2/16+currentcurve, Y2, X1+W1+currentcurve, X1+W1+W1/16+currentcurve, Y1, RED_STRIPE ); + } + } + } @@ -403,24 +483,61 @@ fixed_t interpolatePositionY( double currentZ ) } +uint16_t findIndex( double currentZ ) +{ + return (uint16_t) (currentZ / SEGMENT_LENGTH); +} + + void prepareDecoration( void ) { bopti_image_t const *src; - for( int k=0; k<3; k++) + for( int k=0; kwidth * scale); int height = (int) ((float) src->height * scale); scaledTrees[k][i] = resize(src, width, height); - //scale*=0.85f; + //scale*=0.82; + } + } +} + +void prepareTraffic( void ) +{ + bopti_image_t const *src; + + for( int k=0; kwidth * scale); + int height = (int) ((float) src->height * scale); + scaledCars[k][i] = resize(src, width, height); + scale*=0.82; } } } @@ -428,12 +545,20 @@ void prepareDecoration( void ) void freeDecoration( void ) { - for( int k=0; k<3; k++) - for( int i=0; i<25; i++) + for( int k=0; kwZ) - cam->cZ), fix(SEGMENT_LENGTH) )) - 1; if (distance<0) distance = 0; - else if (distance>24) distance = 24; + else if (distance>(MAX_SUBIMAGES_TREES-1)) distance = (MAX_SUBIMAGES_TREES-1); circuit[index]->DScale = distance; @@ -471,16 +596,87 @@ void drawDecoration( uint16_t index ) } +void updateTraffic( float dt ) +{ + for(int k=0; kwZ += traffic[k]->Speed*dt; +} + + +void drawTraffic( uint16_t index ) +{ + bopti_image_t *image; + + int distance = fround(fdiv( (fixdouble(traffic[index]->wZ) - cam->cZ), fix(SEGMENT_LENGTH/2) ))-2; + if (distance<0) distance = 0; + else if (distance>(MAX_SUBIMAGES_CARS-1)) distance = (MAX_SUBIMAGES_CARS-1); + + int segnumber = findIndex( traffic[index]->wZ ); + traffic[index]->segnum = segnumber; + traffic[index]->DScale = distance; + + image = scaledCars[traffic[index]->Type][distance]; + + int X = traffic[index]->X - image->width/2; + int Y = traffic[index]->Y - image->height; + + dimage( X, Y, image ); +} + + void drawClouds( int offset ) { bopti_image_t *cloud; for( int k =0; ktype==0) cloud=&sky1; - else if (nuages[k]->type==1) cloud=&sky2; - else if (nuages[k]->type==2) cloud=&sky3; + if (nuages[k]->Type==0) cloud=&sky1; + else if (nuages[k]->Type==1) cloud=&sky2; + else cloud=&sky3; - dimage( nuages[k]->X-offset, nuages[k]->Y, cloud ); + nuages[k]->X--; + + if (nuages[k]->X>792) nuages[k]->X-=396*3; + else if (nuages[k]->X<-396) nuages[k]->X+=396*3; + + dimage( nuages[k]->X, nuages[k]->Y, cloud ); } } + + +void drawFarBackground( int offset ) +{ + int X = offset; + int DX = mountain.width; + + while (X>0) + { + X-=DX; + } + + do + { + if (X>-1*DX) dimage(X, 60, &mountain); + X+=DX; + } + while(X0) + { + X-=DX; + } + + do + { + if (X>-1*DX) dimage(X, 90, &treeline); + X+=DX; + } + while(X +#include #include "../fixed.h" +extern uint8_t minYRoad; + void gint_dhline(int x1, int x2, int y, uint16_t color) { if((uint)y >= 224) return; @@ -34,6 +37,12 @@ void drawGrass( int y1, int y2, uint8_t R, uint8_t G, uint8_t B ) }; +void drawGrass( int y1, int y2, uint16_t color ) +{ + for (int y=y1; y<=y2; y++) gint_dhline( 0, SCREEN_WIDTH, y, color ); +}; + + void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint8_t R, uint8_t G, uint8_t B ) { @@ -63,11 +72,56 @@ void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, ui } }; + +void drawPolygon( int x1min, int x1max, int y1, int x2min, int x2max, int y2, uint16_t color ) +{ + if (y1==y2) + { + gint_dhline( x1min, x1max, y1, color ); + return; + } + + fixed_t deltay = fdiv(fix(1), fix(y2-y1)); + + fixed_t xmin = fix(x1min); + fixed_t xmax = fix(x1max); + fixed_t dxmin = fix(x2min-x1min); + fixed_t dxmax = fix(x2max-x1max); + + for (int y=y1; y<=y2; y++) + { + if (y>0 && y