From 32a81a017481b2fd33bfa7aedc612eaea8253eef Mon Sep 17 00:00:00 2001 From: Justin Marshall Date: Fri, 31 Jul 2020 21:52:32 -0700 Subject: [PATCH] Added Tiberian Sun/Red Alert SHP file support. Added EXPAND3.MIX for Allied Force data. --- EXPAND3.mix | Bin 0 -> 73141 bytes code/redalert/2keyfram.cpp | 93 +++++++++++++++++++++++++------- code/redalert/anim.cpp | 2 +- code/redalert/conquer.cpp | 20 +++---- code/redalert/dllinterface.cpp | 12 ++--- code/redalert/drop.cpp | 4 +- code/redalert/drop.h | 4 +- code/redalert/function.h | 11 ++-- code/redalert/init.cpp | 6 +++ code/redalert/shape.cpp | 45 +++++++++++++++- code/redalert/shapebtn.cpp | 4 +- code/redalert/sidebareditor.cpp | 4 +- code/redalert/udata.cpp | 4 +- code/redalert/unit.cpp | 2 +- 14 files changed, 160 insertions(+), 51 deletions(-) create mode 100644 EXPAND3.mix diff --git a/EXPAND3.mix b/EXPAND3.mix new file mode 100644 index 0000000000000000000000000000000000000000..dcfdf4e866efa8e0267ffdc7462e96e6fc176265 GIT binary patch literal 73141 zcmeFae{dV=dFR=bsL{~w2AhNkh{+}(NE@5Pa&~|?cCt=rTGJUj<78K&NJ^TYlFX>K zZZ9LxFOdND)&v@80gY}TzP;T|#(NcwW^6fiNoH?`(p>g7XEL{2J0?Y=uFmE1ot@Pm zn5w(Fx}+pIPF>aB-reVU8z4Xuq)1AaN^0jF4GA{-efoKSf4|T3yl-ooruAu``H3Fw zOaJ2!-z*zFns!jrmj3QPzF9Vd&p-Z7?2o?umzwsWsHWN9{dVKq5lvh8uBM&-S5N(| zzxQXFmh98C|K*qekB^tb!TqsAFMRU1B0bt$NWSsRZ~yvdqQUjEFaNJ!{LGI9pA%Z| z>dHz=`{aP8J$mWYWJK$^w6d~tNBiV37ZS&!!&;A#O1<{fi4#-WfmQDO*&o-m!-?cE z?)1i1R-Zk2Lek3W%9{4^ALA=GkvNKkls-K6vH9 zlC5hWSI_b0Q!69S%}mXlK7Hm}msaZ8Oz=f)Y-MFtKYeQQ)XeFX)z$fM=C=0n5z#Dh zDRt-R)02~@rcy7YR`p|vc~3j^xYjePedHKg@Ss&G*x9McneVK=kj;kYFCU9(2S(4I zzi{EacHlS8YahPkYlDw*ZzeN;Yjt&X?1hyTM6G4BSv`C?F*@7VcmDkOi(1b&F7#c{ zK7{5YnwjGMwY9Z+J(8mEtE;ILx0~79=DqCbg=>8m9{<=T5r+6ZK5Jp5{T>Ojb8<-(H^8-)>yEu+;Z>qpyE~JlZ3xRLNH-Pn?*X(t5tTlA6;F zOXl=isz6SAZfz}{$!5~A$nEpzm*p|b{C}Zud8wZVYKKs8_1S6F9DG{Q4o{Hzn~_SX zUcch}DN0ka;bWKAMn^A@udi>RuOAUh7to<{`LaRw75&W2=~E|8oPA+Fl@0Po>IpX- zF1dA;-!#Mb{0k~Od3ox>`M%}z=MIl#BJ)x|XJ=++PEViu&Prl9qaC(*{<~`_w_Z;g zwMaU>Mnz@K<>2W&yuZKi!cu?#^10br?LaD(y7c^M=^3X}sWFe9(VM)i^&sQXwN$0P zcG;+>(~$@gvgUb2^pm^qg8ZbiFP=MpPV1riR`1NrOwsSo()f{jRy&xue9Zq9WTfjx zeQnN@Qlv%3=y}O2g%DBvzjSW=+_`frbE)*1Nz$pQmAREw^R}sLJ&B~@4=W*&N~S({ zL+T=pjO@8(X@Qn5sB>X9{sI+2zgU?&J2gcgPt9esV{XEA6A?y|2wAIFGMOpgH>@3ef|j|JLTq~27_O%? z8EKeo_~spQE-k5=Q8H%7N2RwX>ea}|E&3EyYDU6UQy&`(O7lorq^DCTB2{ZfB9Zyw zd%7yd(p8Ftxc)DWkB)zzZ|yN^50z5cdNx~+Xa~nKk;vyY?U3<~s3-#Jb5#nIj-=-^ z=J-3(!gP=Yq2Ug;>gYJ_bfKxvxr?*27kNs=C}$&=ogW}66V7C-RdkO;koT)dDwHg`5Q*{14J&EW z%$nxC#dGJEmnqT$4YjmHznut&Q)_E;ZZ=#=W>AW9WruxV2|9qF1EplCG(B~4I<ao7y2-y{AwzUYnVonmWal zIyrS>a#fXVIHH@?JBzck=VmG4=x98AH#|QQ%cScGdi!M=HW{irlZ|MHKc_ji;Z~+a z$mGeBr)FlR|1z94_2FS=he-9Vc{4sfJ~}!+`|jOvIGmnOr!y5VQ+H7aA;`!?bX`02 zdCe{qoF}IdGAVP`$&+VBXsqG+uwIjfh%YWK{_*%Ivfe#{oCqo;yiC~jP%4wjWV0Ea zr1gGYOBQTf%5(B$uoOL;qN!f_gszL2o9|5A2p>5TJ`!KN8NV5>M(2k!^Ikpcdh~i} zEhgipoL=2?rl{eQCjvRNrhfUASC7rpy&~~=T#6G8SK~KtMj``qGWCZu8L1y8b|!;$ zeYBq5-qM-VEPp}KPOWCm;j#H+D#b*pY865JBn_z1xwe*~!P7{hCyGMaA?Z9J=SQ!- z_RQ4Dlc&y1pE$dso3XLPvAMaqV~Io}90?;RkXEflnqsJ>wG^vFnDH#-(zSzMKv3gV zR_>A4UW=chFOIC~k@@-gxnpzl2uerBVoDbJL?bcEC24Jqf46SQB&X^}iRwXAkDU+Z zla)&&uYL8okxbV2((@xIg~)U|aSV}6Qw+(3F*0>ldTJnV&CEvpNL4AN>%C8Ey| zy((X_axfQ};ZiZ=lw%_!^9V~*#Pt-LJ4MHzmPMLGWqXDf?U3Zq1MEiO6?MZ(TDQ0m zLRiU2UkW76&5z9|67#W<=@Zk_bd?j6XDP;A2BYuAd_$?#`vtAH*Y`>xyV0=iE2-7h zdrndJJqzifLdc3ns569&q1SxuyV7T6p_o21GdXi7I~+EA&o`{Hr}t_-%ti-#dwX@i z;@CF%onoWP-@U!Da?x(s4!U{iIaR>Qhq< zD$Vg?t5d-MWX+qJp88=n8>_fp)GIsTUhN=wN0-NIA%29Z3#!JpSEpvqoTBuSW9H1= z+cECLp7`;FT!&;h*FY{MAcs77KQPj`6)hu12+TP3s%dw2#TRv2r1w%jFjwsVl(r z&&ox;a;1=`to^#CrQ`x%ng*@$*9mq%KRpd>>jt}N;F%f5$?jnHPXQ`+0lQ-Yxzh@A zuOxPa+>g@iX>IW5xnJhBbhr!TUhah4hve~D?U9)F;a_TIs+(zW<94X~0;s$97M;sX zk1&8v$yB8E1)zJaZkhr!b_CrA$*>mw>RDj-BxT8Hed9d%n_=C&OXer8ki9GDUb?Wf zR5=DUx@6YtK;Eg-!A3BRtVGBbnm7n)q|Uzx8UG+FV^R>vRG$ zgAicb0mJjP9>LnTZh^IhJ8Z<-0k}oV8zAi;gi3YYq+?~$AQL``DpcqpqpS+My0)5{ zgBf(i*=p3qrVc>(*MN8^XRw_qrDeJHr%K zPur<_Jxp1$Eg6MMMNP#4;s+FN!PeIVTaQoByOVOQ2<>L`@+qk@Is5LdDoNL29V~`Sa(_jVnkExheb9`C5tD zBwVj&`Bzmf(-SHgRqFZPUx0#`0U$$C90AmkJEQA>`lbNtdEm52nKNWk0eXUDnt+0S zTY%aWa&r?v9bX638F&WtG3@#(ij%eE2%!GxGzdW93k*o>fI8|&ZpPzx?uLQ(3Q$+gxmD_fTA_ZJI6%Px z@YH$%!UCvYP;^6~oDsS1p0DMIf~?f7iUL zWGEb*h>bk+{4;0L*t(Qz*ceP7_^5A0)J4lmy2h!=8Ngr@QQLM|_mc^*eu8p>s6YDj z^mETY^UTxF&Hs#A#;T_NlSaM*5?3yvX(dgSRdC(fRoI(zonr_Y{w z`iI#_*)1D}(L~h1ivUquMY2EI>y{m`p&dg;$nwV0uRVR@)S0QX(@&j#>Y1nSDM)P? zm9hhDJP4i%AoYg@59+!fEAimslg{0HUnS3(Gt)C?XP#NhDpVaU2(ES=2W5Ics%anLzR443et0ka%;e;0D)pJ?zYVbV z%9V224GFLw1@)dfHT}ad;OD7lpONZ%dX=Vu=zy%D36IDf&$yE(rlD|anWtu+f9|>G zM|5hx&KT7!Y}`2c>`SF;WXxeK%o6$%CJ0a{ar zuFyJne`u{~pXWbJ9okQ6pVlx`t8`fXEcM8*kMjM9`WvXEe!r)F#kme4QK@;|ls{rz zPXw2n_y6x0xiw^eUi+C1*MFOO*R-Qt|M-UM{~#%U9^tzBz~?}|2~yP1_467XLZ#sP z_n2NZEyVRt1(%yYm!9f={TKeT?$`fiy8HE?DtEtr^|!lUKl+XC*MIBX?$;mvcXGX% ztYpP)ectu&VyK{LpeDz%08YEk#*I$CA>18WTnvRAt6cFayUkvZjO1h#7eexE7_{f@ zCU;0Os^?;ZAh+Wp2Ki~zS4666 zZgTfV%e1eZ$95#bqHeLJH22yFmI@3~(JHd?G-L$}l03XpEH(cWVSZBPZW3yutfZX$ zlVuLA4eS}~N$y|&qxEoG-7MKKj;O2+2BzH*3(yWpWcB)Gs?}D{B)14)a5W14jyan` z0Wi&yl8r>2IkvN#oSNLeohv{m!ncDZM+`8C2_mw1jXU6bX5C8OkJlR@s z<(qA%vCeGw|6F1|ue286``^Cx4$BE~v8ZNuS(kRbuxt{=fMZOEPMPTF<|I>vV1W80=f-v4@)nF5*hrGBp*X+DPb)ul_l*? zEr;n%GLw`bncgh^lVw4c2$n_H*o9gQcLqa42~x7uXF&yObWui2t&x@c=q1ymnn%_} zDZQvHmKn9yNGVw?%eeWh?aK%g#_Ug0vx(9Oxg@D^K@8+}imt4IO5V1jdVA@6Em0^X z3!8|MM4yrh68Nsli7?fcUDc8X!kk^C{Y5EeR)rmGY7Ld7su3a*_{pNER%NS8Gg7hA z2LS-GuBo|C6-wz;2=N%zKb3-Vr~HX9$4YKk;u#X?PkH1g@|s#9MgCA_I+`*GV;xST^S(xQgA#WE&B_=ogNir{Ul?5IVIxZshcd+^k8Xz-5RFe8r?ZG1* z7A(nD(qx82lpd`Vm3RcToJpvqTA)BB@iFM;@}Vh*@l$e2HrIvv21({zyh#YpHMn!!Q-24sV*sLzzkM=3Lq|#b`rH>7LJ%!65-+s36fL`N&O*9V=mXAwk;db0TbSs zB*N+n_OwKA)#l|-jl6p!tm66-hjJLNJK!DO*$7#1|P z7~ZQGO-63M5ULdNt_O*Mjpp;AYIsk&aC3<@N@~WntXieSnrqp~d?gy&J3eISHPl3v z%atu(=3G~Icff~T;Tek!6Ps;7jPp4=X6FiUTs>7t zH1Q!yHAUH_lBYr~1X~ppT6LTNA6opC1V|a4WjS`vc3i8?MS6Sbz=98(qJSpyhm;gm zp&LznsO&6G5gSLoMmUCL*&#bgOiin}8WT78P>dT5loG83@XDgsKqbM4QdiA{0LM?p zAiJfcQ}KLdISoXq@`x5>4@Aio0eGU6;6nuv`Gf8OY_NUDXLa@YL{!eYI^FQ0QcKAq zGX+L~B(b+xB^|L8x>UlR>~6t_a+gZdY|?-N>bRhOawSOW8z%|pE9FAO(*VVS)QJyy zDo+L<@>67~)WV8NP6_;#vt2irx5`Dwz=FmY+8sWm$xsH-4J1K*e4|oQR)VAv^+GBj zXdn2n$ndH7HJ5IfFNc#B2o=lK&iF7I05MfX!WICv(pT+JIZB_8m7<2Dj7f#$hSiL< z?SA+$7>j~|iY3>r(y1&;yia^6VkBX)p)(fpp}pb522976`~fypl9&wkjt>R&NVgJ6 z0kD$+^+5QLK8iT1{K4>{jArVGZn}Sb7?e!9<-@^;g@=I;VFwQdAA%77hT%h2q%AAl z`pmh950FWF54Uf3tM8VXejCi1MQ8u;P=osAVz?J`{R^@#Z1=SLUT1Bp#F*j0Qsq)% zKejgY2mo)Mus}(S!hPB7L{8NzIZ;SyIF#Ozg$%p?uPsvE^Ji&Zi2l=Rr1aW8n47Q!k)H5Xi*(D43f zm2z!YibB5FtEBxxYUng1;cU( zUPTxfI4GmSt7OlGrPCMfP{T5+t=3R@Rq6<>;1>KVm7|WVO@bIV;Z;ODpsNnyecI`BGoTARrBTewjE2nGIP`9j@eUEKtXgi> zXEZiC@hVVP!4O+;;6{6UUMDJcbS6f02~)TmP`f_ocX@hagjtt8eN71|x3FC_#~ zl5D5!CLwc03&9fEvoT4|Emv67s5S-T1cb>aDwB^gf1uC4@T!PWi4U~EgWy#_RDf5h z_jOR5L@*yYG=!#9cW!id8w)TW=MI2eagMgB)cis0&h@oeeWkJVIV^3 zN2gaebDL^^sdcsPDjbfxo=HuxyyyeJOHzBD3t9z5^Qjt@(E4Vg=A;bNoD!wbgs3FE z1t<=<Bi{vp6kb= zRljA(?!fcvRuLEgW)USxeyOVBrxm7D$e^z#OJ1z%d2L?M!t-PS*>1w~K#Ks+%eTle z3_l8!MlIw-qj<|uQtAgdBKuucLAX=uO7J|3kK|L@hluvd?P6}xYhnlh7IuvsD%)!h*=V~8hxL zAW2FdL%Cq@Jw5?B2xto86ZO7#`*TZ=KqHYxtrtKPyDL?z-s2P6 zGL$M0WPg_GQB%}kBRr4g=WiaKFEXH8P5mIhS^YZ@#J(jlXpEnO5 zS^3K`0VGM(p;WPLhygJLPEG93z|}Htj`q{IsA-;{2<+IRSIiHij%++^-_-g9*~wur zp_AE#9QMr)tp%4fDgxLP3U^CNjO>JLW$ySbogJD_BGMKJ(;hvt*24=#5rx7*p;9W@ zQM)yXAWsVb45L}U2MB{k*eI1GWO-7_!VkLelt##@lm&D$NfmNQYO*DVLJ7!3 zLqlxyBsUrpkR;kkYTYQmf%xDZWxWsCu5EhJmYj8-A~Z?KDq#?YEtdkG!X#2@hj$Bw z#hi{WzrwD}7 zDiU}v>cEF~wpHrB1uI3Nlt~Nq8GQ zo5WmJq{oR;7%HTE{4YF3hy}H)SS-NTlfAahenAyW)krZUTT_yf74Q`GEtmP)lKw?Q z$ygM15ZRQ|$x~WvM6xTb$SR*i0w4I_a)nz4vSbiOjaC3qFLBhtz4AbG!(Sr0pq&!M z5Aj3sr3kZp>GOf8GUU|o%1}=!SevJ)J4HmmQ}`g+xu7^_L&;%A!9V~CK$P$=&lfvS zvAosq&}jP|1WqDLJUmJ_`B-!nMe(R;=5YGG@SR=r6vVW7ikuQ4Ls2xtov=He;B&k63eZQNM(# z24@{TEWd*~A*u5b`}r(tZT7cqmP4=Dw>iB-7J&u%_QK!s#U4KzjuSI%+2Mp4V>8m) zy)4XqcC7$y%;m70ZjVXtBat~Wq+7D&gs|)FWUSs%kb@PZQc;UJfy?=Q`wQGsFzq4Hrv9hvVztwnG*ch*sJvJ-C8ln240JCGiIq7Ef01 zZEv*-A!FMwS^e=B7+%uOc`+|s-Ikxy-;1WbkYj@sjj{pGB3zd2GTYC^&M5u@mdkA( zDFL2IXc3(rv%%(JEhb7Az$Quj1>Sb?{2&o43T6!9eJQ!tX4c3N04<HY#nNK zDptfqz441 zcnYT(}HM0Yy?`VgJ{|}1)t#eFbl)R z;7|&|XRvCo-;xx7RKSq~F%@=6<$>73;SN{8`n?<~K_E5U64oQ=x6_NLcpQBT@i93p z#qbzi{ELPGr0Wub56WTS)|9`%W-Pb;JDO<2axE)&5&sb`uw)p%Op{^JN6XHR-z1-k zo_k5)d~AJokz;KFd`ukz0vz}Uwa0Nl5<)1GW3tWTIK74XO9tJZ6C7!fmgAwJKr-7B zgCw#le%Pau#61lE61qbps3RwI>O?X(o0VSgL#tJhg~xHUrbttgkYj{>TwcPsAW=;k zha}naEBM>sG?f#z7sc(p! z&|tP$Qx-@MRS!=QTS}{fg8F5-p&;Cyk)eU0fXB5qzS7GB9)~oW zB{yUl6iocSn9vM%lB;0TUGO-exuTTRnR0|68MVB!^hi%8qpdtn$YjTUShS;N6puq= z{8LiO2LJfONivo>T9sR@E&Cm~rJKKrjPSS+VFDs3kkn}CFw7_q>E>^eQ&w9^P^rJp zZlu%iNnB*It6RHwrUA7xE0^!LVHMNIi$wJZMaRuKBfhK9HeepOYNt}-jQZVrq z_sZkMF1F6%=syG^uz~{@_Ef6oepnGjX_!?Wl*h@mM7c2ANh{r#_H=Im>6m{*c^rLo z2XNfIxLvMd`t1lb>2kv^FL@=)tKfc+V3ExbVV5H0HlL+JcpUyF5beGTXt7%9;s~LZ z*o(Ru(e75EP_B_zku5kb@>arkO*RMb?*#ZqO0BLTxq5TKu0!J^X zJ-VUdX74YE7C;G)!%z(w@@xFx&br|f_Q-;`w{oi2Z`$PpqLqlP0JQ;(WzF4?d;Jd! z3@e@)c$||g7dLAy-iUR76Zjc$yq>l5gYg~2FViyN zZ@95wSsqdRpepvH)6cfF1_-Ok2q8X-$B9F3gAD#)*~#Y%B~FdO22v_XKihN*cwbnn zIQEcJmDnd;FWMNCI&TEG%sDgB$oVl?Q_0zXl_Ro+bV` zN>w$eA?8O3vGb!I$9N&r5T-)h7uP5vSKGZ_&}>NHj7UOOQQ{f>8Wt%U3~nG)4z+Yq zODM4HZI|+ug;sXdk8+8CN16#92RkK?fsffBf*BcTqSSJdoZ=|;=T(HLP(f{d$PPXO zcR~uJXpInqo$1G5v?+fja!5)o285JI1`rRz6vvNddnumF_IV*7`(Xv+$ELMu5^Mw=*o*Q^d zsT@In4*J$O>)GcriM5qRwxrFG=8D;iii5_v_zER8#UQAcmt!!1sbg7r40il+It0?y zs18o-YVur;o?zBw_$ZSKiYcDk8qDy=lBH;y$SFJ3Xa&;@c)cOWR0_ubq7AV#cEPGJ z2qo-KeBDZ&mPQRuD3E|uH77tjYB9G&ohe5s&){E>LZM`EC})v?ThAqq5jzM%nsVsI z1Qts0X^2_DYUpLw1NC@E@DyLu-4)&~p`#R^1P3G>lJ2SmNj3M<^XQ2Jc_iq-EgIC8 z+^sAUbQ{^KB}A9Cs>$OJ%=e8jn+y$%daAv81D>lSG2odu3Pl7f1se1#&Qg-DD0|fC z$H7LfKuodb!*dN*PSxx|TqW}PRw}#cuapm}6^m4F(5*SNEo4b=<4$g5cOb*vU<=?z zo{JU~Z!6EG;w(BI^S@z(ArR9LQF)!=3ePn{TY0W@qBhTEUq6#NddcH)LlFC+{$f-k zj$+XrB_y;cFA`}d$V2cpk=CVvPKdu!6&HDMrv?dIfWu0PztRKY?uF-ybI}&_%Z3Js}-Al=+4R*4x%R)~Y$BhQtoMZ%_NFEyFeDpYyV;<%R1%4yZf zw!h)Iwnc!Z3?CVFoSz`Y+ZWHxGf3&`1>z>yU?FA?MDEdFDN})JD_izj@@kp~V*1*Eo3`ywJAXlh(E33$JKwqEw^8gwRX3k! zV!-OP8LQZiCypD1_&0lQcFfxOC2NmWlfWM)b+Ev`_!siP2>Gxq!mQ?ug6(-z z=d-(fhH7(Gz0B&cT$~eLmwR?`iA}e*cwr07GAz&7ba#n$v_PPoDp!(70A4RfD7 z*Ae>{j0!fyBJQv>MYpf#@@DYeR!cVH1NjY0ICI`&Y1)D3E4oQVDo^0A1VO@c zw`(teg!mSCK~%ob$Zd-FG{p_BQ=ldFd6;<;7$KsBWr7o3P z0Jc_`UwG~|eseLc3N~i!lrRT~-kapeQM>Tgfal7-F5-J(aT_0|RoF3^FBw>6ETS2B z+7_#Wc#&j~qZUoB>POds^z6Utkj1fLKtkpNz!fzKUEWlS91;iLk_|_+ff`*vW6z=W zWaL^c#w_Rhmdday2`8rb8+fif4-ByGt}KU@IiVJHW#~^EN+E&by%TL0n;zatc*K7Q98cl2oAVZ$d4_b35d~yV=5uLh4^5qKqy6N^?=MZAT@HF-A`LV=`` z(My^#w(d7qyt~PBLI1d1;iuJF#W2~^s7g_4^X?!T5+jI+LSu+!%i1LMB5oRxF`X1{ z$ZkGt5^gn29K0Z0Y8KZ%{$-Sc=MvwG8WLD3-NA41FHLHh?k`M7nOF_h95d>Ax{6#D zGACuAw}^ik+Ypht@LcKjs(yqoE20ZI;W#ou!wp54OBU1~yC?iz%m7Lo%W6hiKnUrm zc;;mur<#$~lB4zZQfpv*ibrr&p}@GpSWAyn*i5B1+VeNiL2YqoGGZhI= z4El~(fY=1E&U5J}1xF%{;N2A*)$KT8d3k4p!V`tv@-G*KLsBi60#twlmXoHBQ1M)* z5(J4$f9rlm1aC z8~(m~|1z~jcFZqqrz}u!j5^*&iXC74=DTHHlNeZn%bc)E zyKxNAUU@fQhi|FY+^!D}Z2v3uSvzN<})u`OsXyc=rSomXmNmwBkX zo6U^(;oY(=ayPu&xgYQLDgut%HPZ1(@oojIcf-4dlyt8j;oZ>y7yT9TZV3u(GntNJ z?T>c@cROV85#U1FEARGkK8Bo6bcos;@5YBO3|03qC>aDP7uMC_A9ulYhex&ho1wwgxg?rR>zYF^V&7<7UrP)M!4ofm<*%{q=cJT(Y^6* zRVw!MDT0gwP<5yq;({N0;N4Xw#2VJEbwpoQF$;U<-KODHYfwUwqkbfDQ4{a4{_f7Z zfyJDH74UAzgW}!1sZ{u~Ur`yG!r*fisb&$pm3IS*Fay9PNaBYN8S;kSif0lM0Mhni zVp`-s8Xm*Wu6Q>H&{4cwH(V)|Aa;=?)+NPvOJZx1AZk%-2i^^g6yB{HNwH0ML}iN{ zf{aOq=tcCx{djjU1oIV#(D{4;+XU>Igbdgkesl~avC2-o8^<<$iV9X^nfEd1&|+dI zDnU3vAd2q8nUGlMcIMsSP=VD%=@)zx|2p-g*a#8yNHf^GA|+!N2x+&xyC&Y!AR&#{ zH5k}NDiV6`?vi)oN#u>QUXuO6tt5vRh%eu*&}L zV~g-**I<*V;@uooxm(_iWSB&mCK5}DGIqKTz`L1F<$V@vw=o-y#L`3!h<|y{yqiKM zIaq)g1~FLen|G@hJKA~2kU)V4;oZci2=B(U^bmMA#)J=ecLyHW{83(^@B#1MTq|4u z{(yHse1G>Q$h)=Dx4Q!5`2WG*z5lpw@plW!eK@?kfS3p6-4fR=Ry~Us3vK5=-L7_n z>uug0_`AK5-#Te=YsTICyQ@+59c>lRys~@VO~mo`XAbRwcf&63!@Cz2cH{4^VqEXe zPvP%Pe>YJc_v76JE3(_SOZ@<*fhU2#TcQwl_ICrEfp%T$xde5>Dk{)Hyd?MacLRDm zJ%4S*qB{Ba;O|y0%U1Tm)(3tIHr|83yOVb>FD=amlHfVQyCv$9ZodnEx47EG{-bzz zUtdcOhu15tjwNlE{%+Z}9@7=?{<-C)bH5kp1Jzvjck}9x`}(`ZRRXmPcy}`S_LV1E zbK@R)H~!oX-W}O5@2&|+s=?(H?}k88UHjqPFf?4$zPFKgNBuqXZu%ka?mhEvT#Sk} zs2_p9Tl~}=yc>TL{E`FpAsKt}cN0e>3{^P_;RFK3p_Rfd6<0Q7;B4}D7lokg$h)sd zW+)FwQVGHB&bx(4h$ET44(|r^w|O_)@?obz^fkj1va%cA4O%ZSn#JEuD8H17X7fES z9*2=hsra`K-c2k-K)Z!^%Z6Mb?fc^0Y;F(8GW*JTZ6C7s#k<89DGVM5X_Rq7RpFc5 z2k$249j`mQo8k%W_K1X6gk_ih?v1<~uKaL$x9l|*HY`ch+CT43e!#mo`@28j-5qOp z_m4uAKJa&UubcI&5@7oQ?_RHtZ9ja#yFcLF+jWk1ocTlWcZ*Fyc(=>W+U*{=<8>8h z9_*)9yqlK+?0Ek+UvB2zRcmvkbw|cM@a`%vY}*vF-4?V5-d(L#liLZ}6YnNuz0!&Z zY-=K)*8SZf?S66Q>_3I@Y|Os?SCe;hjQIU{H=B;w<7cerT>s$lsusn&fx#Rzc0b-N z5qO-q-K^*T=J&MU4`1#MZwX-Yv3Zw>ijL`Mb~ekroz~MNWy$3G4pu z?RhuG2<5L+;p0u-{hQ~P&}V6B83yl>HE_1=$h#{DoB@R6S07qF_76nO6#xN{zk3V0U55a&8#@ZhvuUslR_|LgbKk!@DiqoSbYVVye8Q z#?Zyz9a}uVe06E|_{(^@k+U0rH#;RcvRRJns>OJ5w1Z-1*t_SCk1pQ42k+*1Bw>T3 z9sS+BB%N?kdCf+JUdX|`Q3A4k2yP-0i3o?6c)H#AyNOlg03?W|yod$P&AU;A{tKPt zjXDydk2K}<-r3*XfPZklYrwnlcgIZp-9l>lFDb`@6FUQcz7Ow)?Fx_KpNca#+3pHM z6-S(SzsO#8@Z>57BtGi<@owQn5@#;f1pM7qW8&i56id0PnQ7ho@ou#bTC7Yhf48(1 za;lMuiN%R`#2f%QB&>25{%%w$5a}H7ZesbVRl|?mxv@At9v1_QCVlbT@y?#SJCu_{r6LkYr|2LpGmjN#33=9_po zp-DWJ4G)38yHSquUQhbxmN;{JJzguL<@VQ@{Ilkk)_`9VUsAK?o*EsWS{oO<{K%#>}B*lmBe zY@+60)8EYqlwqXe%*A%LhdA@V-_67n_`3r!R!JQk!Fsp1bIe>`p1B@pE+a-x_Y1RP zK6sotd&DKqe9!y4yT_UD`Mo(0E6)63^6vZxapp47-X{r%-!P)O+|TOXxy`T39lN^p z5chY7Wq)@}BRpwWPwskC$Np~i4!3+dU2om#qHt5rF_V2eK*0yw-|YhE!4;tY2lRJK zOw@z#?=E%l?(KNoPE`YY2=;e_$pU{je!!hGbpN)+yE)QH#hHhR-rII(|1Nkp@63_? z-M}y1-HtD7d*aQhX&uYXAcWbncgcz372JGSxUI2{Vn-ro%dmr!BtyrQ{%{TG%MV}^EXn|Zh2 zWcjG865tJX-`d};c%`OM9-+(qOZ`jdgfSD?9q?|#2jx6!_II;SU47B|QE_cUq70EG zXQ8o|72bWJufM;K|B-Wkc|uCC&byfvWPf+G=58E6p6~FQ!vZJ9!MkZJ4m8*LVBLKS zXmp_uru#Boy~(=)*TjklLFb&imL|b($Ptzr5EGP*or>&h^!0mhU+rJ$@4I?+X=&-= z_~LNcYV+=oTI6*=8__r`Jo-8`50-IxnAg5$=Bej~d^gU|&kz*InojW)C&Z0jo02S)Q&-VUqi5YJX3`UIjy9Jlh@*E~88=Z~x==Cdev7}mqgWmLyA{M0-W@e#F}(OUF3w`hK?t$Eyn4lrDfe(E?{2@pNo)DL z)jn3#YVz(VyxSZ0JWow!Mn>LEIcw8DPWiV-7FL>e|IfhWlw;~KHkWk z@!5&R@zI+RD52r7pVH&)%ACzsL^0W5-+h0#t#~)*nCV8qyFD**Gd@nLVku$2w;Uc( zWn}2wIkd31#XH_IIoGX&c_H01UGuZKDW0^pj$d zIL;GU_C9zw(g@^dAre~?3EoX?R0r?Y;kjJi%)3LOE^+1o?+#IeB8g$$-rr3HZH+VU z~4ezEqsPoxEd*|JB`35CcyjzY$-81hN#nyQ@d>P)&CKyKB1M_Z~ zkgApF!{FT)T(B7R_F)h z-2inJXTIg6s;)KK<>JP3)r1>#x#|9wHuG-TsdfKcTkhD*yQ|T1(b`DS+Ie=xyBkg3 zU5hF~v**uWfSoE<(2}$#-i?FMxw3e^@BI1mzpwq?(uH#^DcbINH?LO#*J;_=fA=R) zuvr@#MrsNQc=tm0ICJ4|@YCkGYU0?7Mzr%6zJUnwpTY`->8i9IXTFWU8#kkzt4894 zES$%m7++qN{G6U`xQec@GqnwpwPBUsF?l`K}i#WAP#I-ZjfKJYM!TV z10hnt3+G0kc;d=t-tE^oM$PCPiEKNhZj2`H4*TKk?6|1Y-@gFyCMMw8L@aq_3-7KO zvO~44js};ZZVbh{#f=xf7aw1~dR3K45$~%P$Hz?qT075G!<{YQu0x+9!#j#(#k<+) zOUvK9F}p+`6y7Zaera}mb`$S5*#9l>OzLPZ02kgs_>AJ+d`D=&y-|?^?N0C7dtu5*; z6ruryER~B4GY<5Ln!>wd_eN*WE3?E^eqOvd;YWmbLpj_2Zr&Kxt{!~ca(Wm*6f1TT zCww?8yxZ3omr0__()rnm2^~i&z16j2(QpOkn~X+{FfOoGEyD<9Plj+10ks@*Z_<0< z-R8vX>^Y_%ECEo|1aG{O_fFG&c}cN2zqmTvf#*#p|dc<7B zmOwf;8b5jua!N2XwM^szfi3u9;oSt(wB#@ia0FBkXCC;wYvC}vWpv@)?3Hu>;CRwqc?pxY538Wznd1}9gaob zXDnvepj5i>ZaHNPQOJ^W)xsSAUfjsL>BMZnQ2y>vUU7KJr+9a8o*uIH#k&i#zdIZw zwudo?RZhv-6YrKGD8v_2G{>ULhL8%5g^lN`ZSi+gYaP5hDgJJFE;YajdBVG8&k<{k zz2&`KjCOk?@8&{_cVk^-+z4L|&Q*(6%e-#gH+JvumLU`PyXo4BZvuECIRW_fiW-yys4}7i~@1zxrjMMQVwAKu})9>!Q zo6)q_bJafJ-8)rt>pNk}e?{l2DG>bNyxXxIUwa7tZi{!UXb;Z20r$T45d7WPbvfpVsBjj!Fe}0e8c{3UIWtQareJeQM|kD@9ubW%>6TW+(C$-DTye@`alJ8<$|Ve!Q@mSfE^-uKz7WvVrHkjzp92N1$C(HI zZecq_)vr@jY8EQw$w@XIW`H~6=Ow>l%%Tv)``kFJrS0!_6z}#;T`M_MZA&4L6_`i` z23Nqi*>mTYY3i0rV&a%xd|5~liF4JU?c(o_s)+njTMR+%9Mdg(L&e`6twrLavq~S) z35Pd4b>hacExg+l$12pjJy(^>1{xR51MD_$!w= z6oU8(-&Dm}3i$g{{};!{XFmaywi!O9vO3QkpNjB7akMExhLR&u&U7BH0-hx@pf>&v z?IgT=0pk6|YqJyMZ%61|4#%+DSgsh?0$DZe8?XlCaLEThHh5O3M7)6T?y62rk2AKK z=7gnl7cb6URFRZa0DD&`AVfDXO9W!Hf=mRG=;?f4@M;{`T^nAc>4kMKsQ3gr^F%bF zoYtHNo)o(SyjxBv!(XJxF2U%$wG2=!qG0kxQHPLs6Z=?;zc0_u&MxW^j*lb0h#DlA zHsIa#6nLhpoRVARtqd*RE$6D4@NQn zl0vBry~VqO{oOT)H-Xl*$lXP_JEnl;(b0JHhZqyY-_6VB%gGqSN1a61!Mo{>ig&{b zc#X6}sDP=HzyzNQx zZkIX|Iq}8C#rXIr!fp;lgm*){X>M1JS);Y7BsdeCQqz*e{cemir!RA&1r_c4H{Y39 z3=a*3kHi;mD%Uyh5#!Bq5DR5XXuh{g$!YR#c^?)mgv}nMYQVdBx_{$F9NQGcdnkVM zW+YNm`@6Z$$>^QDTU9i?8v~GN75KZWD$ZPpH*6V`Pr$hm#VmlooAzV_3g^nJw^DS* znTHhbrYEZN%ow0aZ^oI^&$w4CVT{P& z)_q&C6L4js>mzkm~$kEzRFaij4~K{P~Ea5 z@_^UJ1u5X&^5SXe;yUlfv8)s-iyRR}wsO*t^UNE_;$FL0VYD;lt;>;+0+G==S54|1 z<0(-e1jYr^F9*n>oSdts{N1uK*3M%lBDM#Ds#F4>Z{zQlpvb6?2@7pDoU6t&74POP zbOz=R!zz1vFBL6NU(PdEk?6(tdFDb%QOlrgymXQIw1ao!?~XE+F&{#hyTzGz<=yIB zHO0FnQba0&Q&YrSu zxjAtxI;oRk##UCJJ$XXX%IeD6mS^qaf}2PjrBEq-dUA5= z)a1&gRLa~%wk@|L5=KfY=c&`DXHL&NgF4yzmYa5SA>qxZRz{winVLC$`pma3t<~>6O*h`Ecg;mV0({A(6P0y7Tnu$;newsTWeK`mw~kr}FKM zcT+j5(h1K_P0oC0^@VIUJb(EZ9IY$wz7(MDZt7(+^S4%4SI1shSwWk%Y&NThFDFL3 z^KKesq?-_~t*x!q>yZ>4XmvG}LX4TcZQjdv<=vO)_Rnu4r@ruJ==X0p0@ z`}Q`xdzDV{)yWelCa1LTuB7HR3QVu13J9_1*4EOQY$hFx+}@6NQ>xWxr&YJ-)5=CU z-;7jB^}6N!DFvi%zM$moFQLS<%nToIZ8p#Mu|-Q`wDjBK3re%fYQHIi?xD z=WpfRhetAzd8y>HGcz-%r%!!nB{96Ix4yfUa_eT8#cdO976ASSyF@1~Mh@660hF`CcP;UaY@SK{)q^&XY38}+q0 zPl}ZmIip>9_qmn1RQk*$>D1K9+{&tX8{VD3Yct$ZC>^O}>T@@we$t4^o?8|J$p+pX ze}T%Of33`&otk1!NX=!lV{XEA6OnZ>+FHGm$&7hv1kF>b+g*5fd}O4alEE{!@|~5` zrIoqijF}kohIu`Ed#*~=E7kg#mx*N3N*^=Zjdx4$O3#Z@t1I(f7CEwKwylkJD~0s* zurXXuXEM@U+3?LfuUKq}dcgsY}LHrA3ibSteww}$_BUJEMCL+Hy&3H#N6%qBhD&zf;}ByJu%F@{EX4&PFafKR`|< zoXG~xOeIEmH+_o4Q0MEFv}tBd^WIk89S*0~*5=%7xRT7E5T(iz#!e+DXSHl7pPo87 zomxGtWUZ)S5sBy^t!8*Jh@trcSX`OirDcTvf#yj_79f zP6zJ}-wn@?#4_o6fYG!8oFT+_=A0B4vh*a;I z5@s&E``x=Z)6?_mbf)5E>MlAV2QisQK$kV)-A_&X%=6_1HX}D-w^#r99ZD6z?9Glf@*Q z$w(csC@?Lo>jM=jojDE42ugNpHERx!%^y=KCOUD5JOvUKUmZ{bbZsp~lcy0xKNNkW zSfr5iqt{-0X6oe0Q)i}6oL$k)*jVD&+}zx;L?RK6gpm}8Bk-Xqhgw=ov8;p{&r+^H zQsY&?*T`$H#m~?iN7nSn{QUgfvAKEVq$6W7B?^6_kr>62w6?~-TeoDkQ`Hklvh%@o zvT|wUwXZ%mlF9mBdVU0b5SLCTjvqVsoeH_0xg_NYwIH-rXp?qP|{9^M=1B?>5qx0y%T@WAll` zd~9U;#Pl>hWSc&9Cc6*bJr+aMrI|p^$&-^)QGwhGjrzd?fvrZznGaiMcpVl)6d+E?3Z_6`b+vL zbu@YU?3tN6xA)7t=cJ!r`q69OJUulvby^?ZFYo^T_f(fxL-Dz%&HcVd4Bq_;{S;XY zpi9|d;>@wxTGrmo0KJ~PWGkO9sFAq3$~Hl|?}NNY%r01|)$jeM!@GOb96g~urhS+| zSIGB*Tu8QpUe&jnmh1ly#CnJN7Z=|i>B*JNo&tWZcP4uBi;LQ!{Pjic(bDznqodca z^YM`RsM(YI#)%$Y;XN^NeB`s*@%%gQXiu0u<}Z!(jC?9Tdfohx_PLQqPCRbw{iE7I zsq)U7Z@!Iz+U(K#M;_IB@;7dr_)z{2M!)^PX^(w2ulH+7C%$<7`0=k#jGG5nkMunD z7|%WTY3)PiR|?;H#v>yWBfntI z+&a=TGLgR-@A>3of9tn~h87pSp}`{qg9Gs!HwOl^8(PnRrv3EDKYi>EuEgIxa`VQK zL9Hh@p!Iy^t;OSSe(mdTyv-@Ae%u=aA5bp-ABfkI6OZ+bjC-StK&fb7J+g2Yz?)c)1^^&d`wW*9Hczzj5u2!y^-R z#BdM(v|Tz{o0vH8+!L900Y1UnJUg@1DAS1Oe&_EkG{<%$o+)cXg= z&Ml2;cKoeDsxoqP><{vTZ)sM~&EE;X{PK%0Iyeg>wPeVC|LXf<|92ZtK6x;j_s1qC zas!Xqp8jr0?~nT7!6So5w4UCv-%VsMzx?u-UQ806IarOp|9)R!`IPgDR8#L>wwbXkr6_a=Z2L}Cx_ZJox*n{UDO}eg`#4|NA zQK|Aa*VkWv@(OOv#}*2;npx9&DyF%13s{%>M5(Nq|1=u8^8Wi*8~OhC?YP${7BdDX zM*ZApa(?nfduTv9S2bKaaKaye`n(4bO1+XyUOD)>Z<>YI-!8nr@P2<`;Kj&4EPUyS zWFqyCaF4ty4z5nDJZx6(;RCX$6C*Cn|I3`n`Q`*KD;|t|;+2AhR;t*&Xuz1vyc8+2X$$e>etEMG8Vo~unfGF_^9M~>isG|W>@By5H&?+?6Kdj0C( zU-;6?|6rwOy0!w=Huad_-){^Yag)FDxx8*@6K}+lLqkJH4Wme8&HL{cuEd9ihlWac zknlra?SJvrwUt#?h|%P>F>Sx(tD}3dUobU?zqVe6^S2zY~qT4^k~_?SvpiJyI1U?_jCRI zwsx>qBHG~S;9&9PmtO4u(kpYbzmPv3*FK#;dNlr-$0kZfB!YvtSp3MbD?@hiO7X^3 z)A93H+<53qUwZkamtT45mDx|_pNyN2j7&@{*ok!Jz>}PAel+g7@xk&HyZEkM?0K}* z?_A-Cj2FLj;9uvSnEjL;e{<3N?{ii2KiYb<(o-+=C+4%-zyGi0;J9S*=%9P_hC6^8 zuF)vFIj3A1d*bC6U;5l98NI|ExdZ?AffsUv+UIlCfu;YdGM3F=hLJ_WSCU?};*^h6 z^S!T>ioSm(mn(YOCvugE|AMG+T(2I!-H}?}tRDW2T%~8pj$#4GnMV$+e1#+7OoG$d z&wr%m`A3Z-2mihHO*!SJI$nTs6we{37~(fh~RFPmRR{I8i8wGZX0+Kc8>cE4U78PFchMYVruete{) z{h~S1`$y)da%S%n+J`jVG)*sOPVnfO78?1*kwYVYVE&jrU=A?Jzh%Dl*nb#!RP)gG zaL?q(na>W5JU;Si^DE}XT)*~=|`twKrtp4EzP5V6m9RL`G`28vEAfJBUdWN5x z_6zFg*6VM57~7Dh^(C}kv5RS+1Z+I2JQO{Fi{g_Qq8?SQhMsj_!vXO%{Opfw+F|89 z=-KQ&`1p_URabw2`lhRe|KsX8T}<}si*7dfkB^9E-Hhso9@lziwT~P_i*2ms2b$LM z14OBP7$f=MW88Zmi+GO;Mf(tBWkfUawTR_z7nbkCfzjLiWpeD!#{Ec#eY-~)xDQL_ zT^hCzq2LCq_TdRK2iEK>`>|%L{10HoK5X&)-CC~?Y_(qZV!Q4^#-qD5T=#UbTptv} z^{*h~0gTo?%4)5IJfOw8M}$16xw_|Zgglt7`rs3^%mdr0r8JK`h?)AJSgAj+X@?%j zNZk`ysh`xegAc__-SewRdKiZ40|+|sFih14KPQ47*j9arR_}RWTlL}3JrqOrq0c`Y zJ9Y2pAC8?GIS<87jT|`0gBz+3N#}VOcIty)K+wZ6RQDjN=OG!ZpVS_fxf)3-Q0&1C z)?dKTydElc7V86_2Iz@4 zu@ZZU3-Mz;5Nrp7bnj1VT3m7vURJPnusHXAMAJUX zeNJV2bMm3Mru}WJvAv=A5xJpZZ*KvX8xrcB8BcV#?H-mJb~4%?{z)F83dDAff?c3v z1jbltV6AUR(>^BO#>xdbFMh$1x&lo9tX$M9R|Y+$!R2#GJZD;80J_)erYXMg z9ivGOl3^|U)w2YXOj4GN*2gjMhrb!t&AViN;tJWjhL9|=4Zm`XP^n91y-vW!)auGu zI;-`4hTIXJXqu5sab9wpT?0pE*GAGfD(dyR3YL1|65$@M_NXB4Z<0$l>m`>MnC;?4 zF3!%TE~V!5`qMo7^vX&ilf7N?@HED>g90xRanIBpe9X;I5!vaX_ExNK(YUz$Cbg9{ z@12^SnoQv`$>OTSQRyWD5ma4WH_Axr9wo9MyE6{2q|&-RC2sR?&8^g9iHbP#*pYtl zxM227CVktA-V+hxF(p9c|7-7TzT3941O5Ph1H-{ z?6ECHvVGjdIn9~G$w}OaL~lB=W@{sG-|x}I$D>3k&v_82axjj0EGOWyT5{=h1F_#1T*Nc zhc5*bT4EpMl|4Q=o_qup%MZdJZ@jg$TK)cRaI)l|F?WGHT7oh2%O%2(a}Z%a%s~)5 zmHqVT(-ZZFKoH2kc=J@1?io;7=IG93wUVGNw_nJBZ&AoyagKmMMeyHVhCqIU7h%|W z1+06F36$j+z@?=GRZ+1FtW*fAALPCU&(^{ABqweD8v*jlKQds4x!%8c)c}?S?hLNc zb0IKlefSYH!kjVsFZc%}pfE z0aNzi0f5=T)xq$G`jz)>(#1bv_~Q`J4=m*)7CRL{Bw*rQMR`E|*+cg9^y_ba{rLpr zWS8H2PJRHt0+h+i~;06!or z1&EDr6D~0Lu>>RrP$%i(BcPpt_Q51dP9x+2HKb9(RP%F! zc)UFPt+7%+J@XYgIP^je4ygT$Fz1}lf&;AjE%>3qG6${JSI;E4k{tYa%ztzYIsvVK ze!y|S;NTe{fr=0aO^5+gtzau}6)YBZ+kes%C+@)_;EB^cF2P8?s+{m+>S5ljY*gmnKXJ0W-F>a{>aH%$rz(t_v5%uxE zLPrbIUfcg%Ia~sak>ekSfLQQ6#y{FQ{-Fizdsx=flVkTQW_5fb0siqBrd9Ig1@egc z&Ywe%ec}A&D@R9%uzDw6@L-$+Acs6~r@G~nTQobt$=rCz*< zs3F?~k~A)yzXbTf^Th_?s}7h);{ec<0O|=4h`)dF>a~M|{i}yz-i^cPFl0T#QWFn8 zg$U}qi25Pq%iO)c1ac=2Od&9ayaBvc2!v)>WgyDk-9I?E0^7lrrTgCGi}t5u$fnUA z+`;)5FGbW}eiB^+>3M_=@$i@Udq?iEm;rJ3chBwZ{cLaV%KqN&{@1rvSh|#DVLf1+ zdqF~YaTZa(`U!lzT7;#AAU3?y1R30`pS6$vZvWhc-Jk7UeEst42m7Zv_yJ4LKDhU* zA}T;Ua~4w5I38q}M@?9I^3Eqez4z?&bNI~e?!`-cmkv&D=a`3f|Km^CA}U4*HSy^X zXhyr|{_OVh>&v@)7j|C@A<{bRT_z~(^e13V^_@fimX&!4*pywS<> z^-I^TUcKfrp#8g$Zi*KZ$V2N_KmH~6(>%0(y4v46IQrtzT}ZWKb8O;8Xbmy&#~+`C z->c)>_aH)k&O>}ZwB{fk1kQob8tU+aq4h8S_s}{+S-z!N7H2!1=_1Q^8e3cQY$0!N zjI#wb*v``JcrEL!udinda%UQiGTY0tbed&JC!031sWhEN-h3+t87ZA4Nt$;2g_)&j zmROsK5+^e^tNUp-9BmDU+0LL5r=5A2WU&+uGcQd?qi{4F^+xmcadkaGSxn91_Atz> zxi}2xS&YI_ZyGnuNfw4#Z#WFYc^J*s`XfKiW|1@sLouri;`YKfrx6o|!$EBOQ5uHf zPDfgg&`yVHM=?LnhM^n=Npnr>M4d1gWNjktG$wB1M|L~dPTb+bvHT#70x#`IonT;f zx52KbZ8`|Ng)PP%%L{^;M-JLjW>JMX(F)w5Jq*0wuuabzjjVwJ&+|PiwIt7jU9aQG zsYO{{H?~d7SEZQQR)oN|V@sNvWWBu+*hVJkfvtG9y(3Y9EqIQh+v{wP zwmp@_fmyH}BQOlt<^w}XWy&*b!?puMXf!;-(LKZPO~x}6$%^3*u`GFpFck^kEbcI6 zra7<;Ba&&uu%$-ZGGsC&0U($&sG~@+L>fw%FoM#Mng%l9aug+@DO;<_nr$n5N2FMF znlea|hcNYL;C~@qL5OKelG-piSkrw&fDZ{phcyI6fO7=F5{eCh7L@v+h6K^@m?{MO ziU6C^rjfw(6@i2UiDzg*tMZ)&Q%w;P8KFTDG}}OWAtDh2bC^_(HFhIRm$YOPqU!Xfw#Qip~E50c=2@Gl`&VQvTZ5rtp!J$M8A z-&xET^NsDT>3n0dH5+YCL}PC_&3>q$>bx@yu@l0Z&;Dd|8F zleUm}eA22XE|)af#9?r;>BOQYjT$aybqvL*tU=MsP)1s5q!mYMaR@~z44}v)lvpBg z5s3(jK!i|uT>5p?=WywyOi(7J+VGMb7g6;M(~6Aq18w8o(MDB1{v)Q9O_YiR3{A@@|l7dfv^H<_wMm5oXf zEvNS0_9cwHUOS^tY1c zcB(8ks4PR1jwgTWw* zqF%4(`#!W#*L9(NnWhOzs9?sTD8f@4bXycfRVo#*ACe@ok<7Cl@PBExJM9p6alb7F}|xg+`gsOGqgok@T~!w-dQLYxd5pv9mBY=Vr2L4rfL` z)%~&F8fkW{nxU%o6vbENHp)yiH_?WPrY12lh>=0WI?>k%Un4w)Xv%~o5r#mhJRxyl z`B1eG|KJxTQ!*%u5-M;6hnXzH39ySmGvH2fPcdynwHFDzdRfw3jO@iopGWFE5;uKj z>J-O18i4XS6i~=3BW=8{^(R_;pxJ%=3j2d~EC>FlxMr1+MIyb3)FRSJ+#rjELZJvh zr9!b(DwV613j9{9m2w5%;E|eQ;KndC%YYkzH zcFS;lyXBca6yI!lwjbD`Z+H537&@BM_nc5|b)2?G5M-%TsnIMaN`k5@4cl@HU= zsdU9*Y5`M=*vgnHt(Qm`Hfeieucr-$&Ls8Yeyan<2$8pC5t>0tTCpydSdkKHj6&B9 zPILrIXF3i)=*Y9s$h!3`6-|kAHL>rg)hY|mzr9X#G_FN)HA!prfTNAdEX#V(Cy%39 zx|VLE-bST8!IOuel6bHgG)b>PS_&!F%5D)Yrq24v9EV!$L-jdbs&RCwSRmFSJq(nN zCpB%pVQ{KKi$aZKE3?^bG#Wu`YPDL8MnjfmxF_Xud3}9zZ7uEhN3B-ZFq)#M(R3X& zlZ~Cwk~$GA$mgko;mNwiiGEvY+V#x$w_LYu`ABiNpi^qvNLL*%GW{{+;QM~7@3*6< z?Rf*=8wCEa?}zub;P?8?x8MEX`egY2^>_09TOa1Tx8DEggW-pN^*+Ko?_U4;jc*U$e&fBHX9qXl zegDP>*Kgf=GylXp@4a#T9rxY058XGf-+~oXKfE!79R#xf`sUlWZryk{KkNJZ;E#as z{1L4dAsEqKM+kaX7)*reei(Cxs24_ZVXPJy1jwj>p0kb+4P!ugm$+Cg&KxJ);WSOb zUch$_heJpn08aon93rDmr*q~(9mlaO3!JE~>)o@W8DZ&@ldN*F~ZAP2aL0?tx?mOOk-=R9RM{C?5Ahac|o9CxJI=H)Gf8+eTojZB24z-WFJs zqcplASBpZ4fL_RRRo77*TecgLWs0UQ=qj(uby?&@o&o>DFg2R4LYGjjmdfSAbmSxh zYaCglz8Q7RzOQ%Ns^5~^j@+_D$K)-&Zt9|;VL6(@k2>|Z&GlPc;Bak=Yc)8>;4F=4 zsI;ljhD_-arHPa(Qi?!HJSA|oI$LGwDqX8k)e5K&JHm3=8`*ZG>s?9i)CHGj?J8xI zs%jz2tZdQ9w#;n9$Yy$$>e-sQ7|8#VSB_(7Y@5wyVwwX*>GFJwVH&lX3RVRc0=Ch_ z76z^3|Epx#cs%L#`mWp3bpuWE|9FJ5CN}gDLP?SZL1q}4HD=FR?T_oV{$&4uvj6Wz zB|p~w`z_UnrfrIj4ozD$Ro;|2RfIyRJR|cIcnO}Pc&5rR;47-*t~mRC#wp)^g|)+I{=QG%feVAB6b`_FxI_Mhe*v!wt4 literal 0 HcmV?d00001 diff --git a/code/redalert/2keyfram.cpp b/code/redalert/2keyfram.cpp index 6d19884..ece0af5 100644 --- a/code/redalert/2keyfram.cpp +++ b/code/redalert/2keyfram.cpp @@ -51,7 +51,25 @@ typedef struct { unsigned short height; unsigned short largest_frame_size; short flags; -} KeyFrameHeaderType; +} RedAlertShapeHeader; + +typedef struct { + unsigned short iden; // Always 0! + unsigned short width; // Width of the frames. + unsigned short height; // Height of the frames. + unsigned short NumFrames; +} TiberianSunShapeHeader; + +typedef struct { + unsigned short FrameX; + unsigned short FrameY; + unsigned short FrameWidth; + unsigned short FrameHeight; + unsigned int Flags; + byte FrameColor[4]; + unsigned int Reserved; + unsigned int DataOffset; +} TiberianSunShapeFrameInfo; #define INITIAL_BIG_SHAPE_BUFFER_SIZE (64 * 1024 * 1024) #define THEATER_BIG_SHAPE_BUFFER_SIZE 4000000 @@ -212,7 +230,7 @@ void Check_Use_Compressed_Shapes (void) // unsigned long offcurr, off16, offdiff; //#endif // unsigned long offset[SUBFRAMEOFFS]; -// KeyFrameHeaderType *keyfr; +// RedAlertShapeHeader *keyfr; // unsigned short buffsize, currframe, subframe; // unsigned long length = 0; // char frameflags; @@ -231,7 +249,7 @@ void Check_Use_Compressed_Shapes (void) // // look at header then check that frame to build is not greater // // than total frames // // -// keyfr = (KeyFrameHeaderType *) dataptr; +// keyfr = (RedAlertShapeHeader *) dataptr; // // if ( framenumber >= keyfr->frames ) { // return(0); @@ -300,7 +318,7 @@ void Check_Use_Compressed_Shapes (void) // buffsize = keyfr->width * keyfr->height; // // // get offset into data -// ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType)) ); +// ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)framenumber << 3) + sizeof(RedAlertShapeHeader)) ); // Mem_Copy( ptr, &offset[0], 12L ); // frameflags = (char)(offset[0] >> 24); // @@ -318,7 +336,7 @@ void Check_Use_Compressed_Shapes (void) // if ( (frameflags & KF_DELTA) ) { // currframe = (unsigned short)offset[1]; // -// ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) ); +// ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(RedAlertShapeHeader)) ); // Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) ); // } // @@ -388,7 +406,7 @@ void Check_Use_Compressed_Shapes (void) // currframe <= framenumber ) { // Mem_Copy( Add_Long_To_Pointer( dataptr, // (((unsigned long)currframe << 3) + -// sizeof(KeyFrameHeaderType)) ), +// sizeof(RedAlertShapeHeader)) ), // &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) ); // subframe = 0; // } @@ -463,6 +481,27 @@ void Check_Use_Compressed_Shapes (void) // } //} +bool Get_Build_TS_Shape(const void *dataptr) { + if(dataptr) { + const TiberianSunShapeHeader* ts = (const TiberianSunShapeHeader*)dataptr; + if(ts->iden == 0) { + return true; + } + + return false; + } + return false; +} + +TiberianSunShapeFrameInfo *Get_Build_TS_FrameInfo(const void *dataptr, int frameNum) { + const byte* tsptr = (const byte*)dataptr; + return (TiberianSunShapeFrameInfo*)((byte*)(tsptr + (sizeof(TiberianSunShapeFrameInfo) * frameNum) + sizeof(TiberianSunShapeHeader))); +} + +void *Get_Build_TS_FrameOffset(const void *dataptr, int framenum) { + TiberianSunShapeFrameInfo* frameInfo = Get_Build_TS_FrameInfo(dataptr, framenum); + return (void *)(((byte *)dataptr) + frameInfo->DataOffset); +} /*********************************************************************************************** * Get_Build_Frame_Count -- Fetches the number of frames in data block. * @@ -481,25 +520,36 @@ void Check_Use_Compressed_Shapes (void) unsigned short Get_Build_Frame_Count(void const *dataptr) { if (dataptr) { - return(((KeyFrameHeaderType const *)dataptr)->frames); + if(Get_Build_TS_Shape(dataptr)) { + const TiberianSunShapeHeader* ts = (const TiberianSunShapeHeader*)dataptr; + return ts->NumFrames; + } + + return(((RedAlertShapeHeader const *)dataptr)->frames); } return(0); } -unsigned short Get_Build_Frame_X(void const *dataptr) +unsigned short Get_Build_Frame_X(void const *dataptr, int frame) { if (dataptr) { - return(((KeyFrameHeaderType const *)dataptr)->x); + if (Get_Build_TS_Shape(dataptr)) { + return Get_Build_TS_FrameInfo(dataptr, frame)->FrameX; + } + return(((RedAlertShapeHeader const *)dataptr)->x); } return(0); } -unsigned short Get_Build_Frame_Y(void const *dataptr) +unsigned short Get_Build_Frame_Y(void const *dataptr, int frame) { if (dataptr) { - return(((KeyFrameHeaderType const *)dataptr)->y); + if (Get_Build_TS_Shape(dataptr)) { + return Get_Build_TS_FrameInfo(dataptr, frame)->FrameY; + } + return(((RedAlertShapeHeader const *)dataptr)->y); } return(0); } @@ -520,10 +570,14 @@ unsigned short Get_Build_Frame_Y(void const *dataptr) * HISTORY: * * 06/25/1995 JLB : Commented * *=============================================================================================*/ -unsigned short Get_Build_Frame_Width(void const *dataptr) +unsigned short Get_Build_Frame_Width(void const *dataptr, int frame) { if (dataptr) { - return(((KeyFrameHeaderType const *)dataptr)->width); + if(Get_Build_TS_Shape(dataptr)) { + return Get_Build_TS_FrameInfo(dataptr, frame)->FrameWidth; + } + + return(((RedAlertShapeHeader const *)dataptr)->width); } return(0); } @@ -544,10 +598,13 @@ unsigned short Get_Build_Frame_Width(void const *dataptr) * HISTORY: * * 06/25/1995 JLB : Commented * *=============================================================================================*/ -unsigned short Get_Build_Frame_Height(void const *dataptr) +unsigned short Get_Build_Frame_Height(void const *dataptr, int frame) { if (dataptr) { - return(((KeyFrameHeaderType const *)dataptr)->height); + if (Get_Build_TS_Shape(dataptr)) { + return Get_Build_TS_FrameInfo(dataptr, frame)->FrameHeight; + } + return(((RedAlertShapeHeader const *)dataptr)->height); } return(0); } @@ -555,11 +612,11 @@ unsigned short Get_Build_Frame_Height(void const *dataptr) bool Get_Build_Frame_Palette(void const * dataptr, void * palette) { - if (dataptr && (((KeyFrameHeaderType const *)dataptr)->flags & 1)) { + if (dataptr && (((RedAlertShapeHeader const *)dataptr)->flags & 1)) { char const * ptr = (char const *)Add_Long_To_Pointer( dataptr, ( (( (long)sizeof(unsigned long) << 1) * - ((KeyFrameHeaderType *) dataptr)->frames ) + - 16 + sizeof(KeyFrameHeaderType) ) ); + ((RedAlertShapeHeader *) dataptr)->frames ) + + 16 + sizeof(RedAlertShapeHeader) ) ); memcpy(palette, ptr, 768L); return(true); diff --git a/code/redalert/anim.cpp b/code/redalert/anim.cpp index 09796df..36e211e 100644 --- a/code/redalert/anim.cpp +++ b/code/redalert/anim.cpp @@ -273,7 +273,7 @@ void AnimClass::Draw_It(int x, int y, WindowNumberType window) const case ANIM_FLAG: x += (ICON_PIXEL_W / 2) - 2; - y += (3 * ICON_PIXEL_H / 4) - Get_Build_Frame_Height(shapefile); + y += (3 * ICON_PIXEL_H / 4) - Get_Build_Frame_Height(shapefile, shapenum); transtable = Map.UnitShadow; alt = true; break; diff --git a/code/redalert/conquer.cpp b/code/redalert/conquer.cpp index ff82bbd..00b864c 100644 --- a/code/redalert/conquer.cpp +++ b/code/redalert/conquer.cpp @@ -3366,8 +3366,8 @@ void const * Get_Radar_Icon(void const * shapefile, int shapenum, int frames, in ** Get the pixel width and height of the frame we built. This will ** be used to extract icons and build pixels. */ - int pixel_width = Get_Build_Frame_Width( shapefile ); - int pixel_height = Get_Build_Frame_Height( shapefile ); + int pixel_width = Get_Build_Frame_Width( shapefile, shapenum); + int pixel_height = Get_Build_Frame_Height( shapefile, shapenum); /* ** Find the width and height in icons, adjust these by half an @@ -3467,8 +3467,8 @@ void CC_Draw_Shape(void const * shapefile, int shapenum, int x, int y, WindowNum void CC_Draw_Shape(const ObjectClass *object, void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata, void const * ghostdata, DirType rotation, long virtualscale) { if (window == WINDOW_VIRTUAL) { - int width = Get_Build_Frame_Width(shapefile); - int height = Get_Build_Frame_Height(shapefile); + int width = Get_Build_Frame_Width(shapefile, shapenum); + int height = Get_Build_Frame_Height(shapefile, shapenum); DLL_Draw_Intercept(shapenum, x, y, width, height, (int)flags, object, rotation, virtualscale, NULL, HOUSE_NONE); return; } @@ -3479,8 +3479,8 @@ void CC_Draw_Shape(const ObjectClass *object, void const * shapefile, int shapen void CC_Draw_Shape(const ObjectClass *object, const char *shape_file_name, void const * shapefile, int shapenum, int x, int y, WindowNumberType window, ShapeFlags_Type flags, void const * fadingdata, void const * ghostdata, DirType rotation, long virtualscale, char override_owner) { if (window == WINDOW_VIRTUAL) { - int width = Get_Build_Frame_Width(shapefile); - int height = Get_Build_Frame_Height(shapefile); + int width = Get_Build_Frame_Width(shapefile, shapenum); + int height = Get_Build_Frame_Height(shapefile, shapenum); DLL_Draw_Intercept(shapenum, x, y, width, height, (int)flags, object, rotation, virtualscale, shape_file_name, override_owner); return; } @@ -3696,8 +3696,8 @@ void CC_Draw_Shape(void const * shapefile, int shapenum, int x, int y, WindowNum if (shapefile != NULL && shapenum != -1) { - int width = Get_Build_Frame_Width(shapefile); - int height = Get_Build_Frame_Height(shapefile); + int width = Get_Build_Frame_Width(shapefile, shapenum); + int height = Get_Build_Frame_Height(shapefile, shapenum); #ifdef NEVER /* @@ -3854,8 +3854,8 @@ Rect const Shape_Dimensions(void const * shapedata, int shapenum) shape = (char *)_ShapeBuffer; #endif - int width = Get_Build_Frame_Width(shapedata); - int height = Get_Build_Frame_Height(shapedata); + int width = Get_Build_Frame_Width(shapedata, shapenum); + int height = Get_Build_Frame_Height(shapedata, shapenum); rect.X = 0; rect.Y = 0; diff --git a/code/redalert/dllinterface.cpp b/code/redalert/dllinterface.cpp index 8856242..172e8ea 100644 --- a/code/redalert/dllinterface.cpp +++ b/code/redalert/dllinterface.cpp @@ -6290,8 +6290,8 @@ if (debug_output) { smudge_entry.DrawFlags = SHAPE_WIN_REL; // Looks like smudges are drawn top left smudge_entry.PositionX = xpixel; smudge_entry.PositionY = ypixel; - smudge_entry.Width = Get_Build_Frame_Width(smudge_type.Get_Image_Data()); - smudge_entry.Height = Get_Build_Frame_Height(smudge_type.Get_Image_Data()); + smudge_entry.Width = Get_Build_Frame_Width(smudge_type.Get_Image_Data(), 0); + smudge_entry.Height = Get_Build_Frame_Height(smudge_type.Get_Image_Data(), 0); smudge_entry.CellX = Cell_X(cell); smudge_entry.CellY = Cell_Y(cell); smudge_entry.ShapeIndex = cell_ptr->SmudgeData; @@ -6332,8 +6332,8 @@ if (debug_output) { overlay_entry.DrawFlags = SHAPE_CENTER|SHAPE_WIN_REL|SHAPE_GHOST; // Looks like overlays are drawn centered and translucent overlay_entry.PositionX = xpixel + (CELL_PIXEL_W>>1); overlay_entry.PositionY = ypixel + (CELL_PIXEL_H>>1); - overlay_entry.Width = Get_Build_Frame_Width(overlay_type.Get_Image_Data()); - overlay_entry.Height = Get_Build_Frame_Height(overlay_type.Get_Image_Data()); + overlay_entry.Width = Get_Build_Frame_Width(overlay_type.Get_Image_Data(), 0); + overlay_entry.Height = Get_Build_Frame_Height(overlay_type.Get_Image_Data(), 0); overlay_entry.CellX = Cell_X(cell); overlay_entry.CellY = Cell_Y(cell); overlay_entry.ShapeIndex = cell_ptr->OverlayData; @@ -6361,8 +6361,8 @@ if (debug_output) { flag_entry.DrawFlags = SHAPE_CENTER|SHAPE_GHOST|SHAPE_FADING; flag_entry.PositionX = xpixel + (ICON_PIXEL_W / 2); flag_entry.PositionY = ypixel + (ICON_PIXEL_H / 2); - flag_entry.Width = Get_Build_Frame_Width(image_data); - flag_entry.Height = Get_Build_Frame_Height(image_data); + flag_entry.Width = Get_Build_Frame_Width(image_data, 0); + flag_entry.Height = Get_Build_Frame_Height(image_data, 0); flag_entry.CellX = Cell_X(cell); flag_entry.CellY = Cell_Y(cell); flag_entry.ShapeIndex = Frame % 14; diff --git a/code/redalert/drop.cpp b/code/redalert/drop.cpp index ebd4185..26d5ea4 100644 --- a/code/redalert/drop.cpp +++ b/code/redalert/drop.cpp @@ -41,7 +41,7 @@ DropListClass::DropListClass(int id, char * text, int max_len, TextPrintType fla IsDropped(false), ListHeight(h), DropButton(0, down, x+w, y), - List(0, x, y+Get_Build_Frame_Height(down), w+Get_Build_Frame_Width(down), h, flags, up, down) + List(0, x, y+Get_Build_Frame_Height(down, 0), w+Get_Build_Frame_Width(down, 0), h, flags, up, down) { Fancy_Text_Print("", 0, 0, 0, 0, flags); EditClass::Height = FontHeight+1; @@ -189,7 +189,7 @@ DropListClass::DropListClass(DropListClass const & list) : void DropListClass::Set_Position(int x, int y) { EditClass::Set_Position(x, y); - List.Set_Position(x, y + Get_Build_Frame_Height(DropButton.Get_Shape_Data())); + List.Set_Position(x, y + Get_Build_Frame_Height(DropButton.Get_Shape_Data(), 0)); DropButton.Set_Position(x + Width, y); } diff --git a/code/redalert/drop.h b/code/redalert/drop.h index 7fcb258..0be802c 100644 --- a/code/redalert/drop.h +++ b/code/redalert/drop.h @@ -157,7 +157,7 @@ TDropListClass::TDropListClass(int id, char * text, int max_len, TextPrintTyp IsDropped(false), ListHeight(h), DropButton(0, down, x+w, y), - List(0, x, y+Get_Build_Frame_Height(down), w+Get_Build_Frame_Width(down), h, flags, up, down) + List(0, x, y+Get_Build_Frame_Height(down, 0), w+Get_Build_Frame_Width(down, 0), h, flags, up, down) { List.Make_Peer(*this); DropButton.Make_Peer(*this); @@ -330,7 +330,7 @@ template void TDropListClass::Set_Position(int x, int y) { EditClass::Set_Position(x, y); - List.Set_Position(x, y + Get_Build_Frame_Height(DropButton.Get_Shape_Data())); + List.Set_Position(x, y + Get_Build_Frame_Height(DropButton.Get_Shape_Data(), 0)); DropButton.Set_Position(x + Width, y); } diff --git a/code/redalert/function.h b/code/redalert/function.h index a30bc55..d233030 100644 --- a/code/redalert/function.h +++ b/code/redalert/function.h @@ -718,13 +718,16 @@ long __cdecl Buffer_Frame_To_Page(int shapeNum, int x, int y, int w, int h, Imag /* ** KEYFRAME.CPP */ +bool Get_Build_TS_Shape(const void* dataptr); +void* Get_Build_TS_FrameOffset(const void* dataptr, int framenum); + INT_PTR Build_Frame(void const *dataptr, unsigned short framenumber, void *buffptr); unsigned short Get_Build_Frame_Count(void const *dataptr); bool Get_Build_TiberianSun_Format(void const* dataptr); -unsigned short Get_Build_Frame_X(void const *dataptr); -unsigned short Get_Build_Frame_Y(void const *dataptr); -unsigned short Get_Build_Frame_Width(void const *dataptr); -unsigned short Get_Build_Frame_Height(void const *dataptr); +unsigned short Get_Build_Frame_X(void const *dataptr, int frame); +unsigned short Get_Build_Frame_Y(void const *dataptr, int frame); +unsigned short Get_Build_Frame_Width(void const *dataptr, int frame); +unsigned short Get_Build_Frame_Height(void const *dataptr, int frame); bool Get_Build_Frame_Palette(void const *dataptr, void *palette); int Get_Last_Frame_Length(void); diff --git a/code/redalert/init.cpp b/code/redalert/init.cpp index 3221f98..08ccc72 100644 --- a/code/redalert/init.cpp +++ b/code/redalert/init.cpp @@ -2996,6 +2996,12 @@ static void Init_Bootstrap_Mixfiles(void) int temp = RequiredCD; RequiredCD = -2; + new MFCD("expand3.mix", &FastKey, MIX_FILE_TS); + { + bool ok = MFCD::Cache("expand3.mix"); + assert(ok); + } + // Isometric Files new MFCD("isosnow.mix", &FastKey, MIX_FILE_TS); { diff --git a/code/redalert/shape.cpp b/code/redalert/shape.cpp index efa3e28..802b016 100644 --- a/code/redalert/shape.cpp +++ b/code/redalert/shape.cpp @@ -180,8 +180,51 @@ void* Build_Frame2(void* shape, uint16_t frame, void* buffer) return buffer; } +int TiberianSunSHPDecode(const byte* s, byte* d, int cx, int cy) +{ + const byte* r = s; + byte* w = d; + for (int y = 0; y < cy; y++) + { + int count = *reinterpret_cast(r) - 2; + r += 2; + int x = 0; + while (count--) + { + int v = *r++; + if (v) + { + x++; + *w++ = v; + } + else + { + count--; + v = *r++; + if (x + v > cx) + v = cx - x; + x += v; + while (v--) + *w++ = 0; + } + } + } + return w - d; +} + + INT_PTR Build_Frame(void const* dataptr, unsigned short framenumber, void* buffptr) { - return (INT_PTR)Build_Frame2((void*)dataptr, framenumber, buffptr); // 32 bit to 64 bit issue + // Check to see if we need to render a Tiberian Sun SHP file. + if(Get_Build_TS_Shape(dataptr)) { + byte* frame_offset = (byte *)Get_Build_TS_FrameOffset(dataptr, framenumber); + int frameX = Get_Build_Frame_Width(dataptr, framenumber); + int frameY = Get_Build_Frame_Height(dataptr, framenumber); + TiberianSunSHPDecode(frame_offset, (byte *)buffptr, frameX, frameY); + return (INT_PTR)buffptr; + } + + // Regular Red Alert sprite. + return (INT_PTR)Build_Frame2((void*)dataptr, framenumber, buffptr); // 32 bit to 64 bit issue } // This one appears to deal with the buffered shape data diff --git a/code/redalert/shapebtn.cpp b/code/redalert/shapebtn.cpp index ea07f16..f729b43 100644 --- a/code/redalert/shapebtn.cpp +++ b/code/redalert/shapebtn.cpp @@ -110,8 +110,8 @@ void ShapeButtonClass::Set_Shape(void const * data) { ShapeData = data; if (ShapeData) { - Width = Get_Build_Frame_Width(ShapeData); - Height = Get_Build_Frame_Height(ShapeData); + Width = Get_Build_Frame_Width(ShapeData, 0); + Height = Get_Build_Frame_Height(ShapeData, 0); } } diff --git a/code/redalert/sidebareditor.cpp b/code/redalert/sidebareditor.cpp index c030ea3..3d23bd6 100644 --- a/code/redalert/sidebareditor.cpp +++ b/code/redalert/sidebareditor.cpp @@ -18,8 +18,8 @@ Image_t* SidebarEditor::LoadEditorImage(const char* name) { return NULL; } - int width = Get_Build_Frame_Width(shapefile); - int height = Get_Build_Frame_Height(shapefile); + int width = Get_Build_Frame_Width(shapefile, 0); + int height = Get_Build_Frame_Height(shapefile, 0); unsigned char *shape_pointer = (unsigned char*)Build_Frame(shapefile, 0, _ShapeBuffer); short frameCount = Get_Build_Frame_Count(shapefile); diff --git a/code/redalert/udata.cpp b/code/redalert/udata.cpp index 7ff9096..ac61d13 100644 --- a/code/redalert/udata.cpp +++ b/code/redalert/udata.cpp @@ -1114,8 +1114,8 @@ void UnitTypeClass::One_Time(void) ((void const *&)uclass.ImageData) = ptr; if (ptr != NULL) { - largest = max(largest, (int)Get_Build_Frame_Width(ptr)); - largest = max(largest, (int)Get_Build_Frame_Height(ptr)); + largest = max(largest, (int)Get_Build_Frame_Width(ptr, 0)); + largest = max(largest, (int)Get_Build_Frame_Height(ptr, 0)); } { const char* imageFileName = Units_FindHDTexture(fullname, 0, 0); diff --git a/code/redalert/unit.cpp b/code/redalert/unit.cpp index 926fa5b..dda4895 100644 --- a/code/redalert/unit.cpp +++ b/code/redalert/unit.cpp @@ -2188,7 +2188,7 @@ void UnitClass::Draw_It(int x, int y, WindowNumberType window) const if (Flagged != HOUSE_NONE) { shapefile = MFCD::Retrieve("FLAGFLY.SHP"); int flag_x = x + (ICON_PIXEL_W / 2) - 2; - int flag_y = y + (3 * ICON_PIXEL_H / 4) - Get_Build_Frame_Height(shapefile); + int flag_y = y + (3 * ICON_PIXEL_H / 4) - Get_Build_Frame_Height(shapefile, 0); CC_Draw_Shape(this, "FLAGFLY", shapefile, Frame % 14, flag_x, flag_y, window, SHAPE_CENTER|SHAPE_FADING|SHAPE_GHOST, HouseClass::As_Pointer(Flagged)->Remap_Table(false, Class->Remap), Map.UnitShadow, DIR_N, 0x0100, Flagged); }