From 6dcdd0148aa18f49eb5cb6b5514198b0d8c4afa8 Mon Sep 17 00:00:00 2001 From: Plagman Date: Mon, 16 Oct 2006 22:07:15 +0000 Subject: [PATCH] Animation, interpolation, fixed cliplanes, fixed map switching. git-svn-id: https://svn.eduke32.com/eduke32@313 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/build/include/build.h | 6 +- polymer/build/include/polymer.h | 2 +- polymer/build/src/engine.c | 9 ++- polymer/build/src/polymer.c | 100 ++++++++++++++++++++++++++------ polymer/build/src/polymost.c | 2 +- polymer/eduke32/Makefile.deps | 2 +- polymer/polymer/polymer.suo | Bin 79360 -> 84992 bytes 7 files changed, 97 insertions(+), 24 deletions(-) diff --git a/polymer/build/include/build.h b/polymer/build/include/build.h index dbfc4dc23..f938253c1 100644 --- a/polymer/build/include/build.h +++ b/polymer/build/include/build.h @@ -202,7 +202,9 @@ EXTERN short prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES]; EXTERN short nextspritesect[MAXSPRITES], nextspritestat[MAXSPRITES]; EXTERN short tilesizx[MAXTILES], tilesizy[MAXTILES]; +EXTERN char picsiz[MAXTILES]; EXTERN char walock[MAXTILES]; +EXTERN long pow2long[32]; EXTERN long numtiles, picanm[MAXTILES], waloff[MAXTILES]; //These variables are for auto-mapping with the draw2dscreen function. @@ -438,7 +440,7 @@ typedef struct s_equation { float a, b, c; } _equation; typedef struct s_point2d { - long x, y; + float x, y; } _point2d; _equation equation(long x1, long y1, long x2, long y2); int sameside(_equation* eq, _point2d* p1, _point2d* p2); @@ -471,6 +473,8 @@ void setrollangle(long rolla); // clamping is for sprites, repeating is for walls void invalidatetile(short tilenume, long pal, long how); +long animateoffs(short tilenum, short fakevar); + void setpolymost2dview(void); // sets up GL for 2D drawing long polymost_drawtilescreen(long tilex, long tiley, long wallnum, long dimen); diff --git a/polymer/build/include/polymer.h b/polymer/build/include/polymer.h index 98b7b8613..99b0bbaee 100644 --- a/polymer/build/include/polymer.h +++ b/polymer/build/include/polymer.h @@ -90,7 +90,7 @@ void polymer_drawwall(short wallnum); // HSR void polymer_extractfrustum(void); int polymer_portalinfrustum(short wallnum); -void polymer_addcliplane(_equation clip, _equation left, _equation right, long refx, long refy); +void polymer_addcliplane(_equation clip, _equation left, _equation right, float refx, float refy); int polymer_wallincliplanes(short wallnum); #endif // !_polymer_h_ diff --git a/polymer/build/src/engine.c b/polymer/build/src/engine.c index a7c1aeb0d..18d59632c 100644 --- a/polymer/build/src/engine.c +++ b/polymer/build/src/engine.c @@ -1251,7 +1251,7 @@ static void prepwall(long z, walltype *wal) // // animateoffs (internal) // -static long animateoffs(short tilenum, short fakevar) +long animateoffs(short tilenum, short fakevar) { long i, k, offs; @@ -5808,7 +5808,7 @@ _equation equation(long x1, long y1, long x2, long y2) if ((x2 - x1) != 0) { - ret.a = (float)(y2 - y1)/(x2 - x1); + ret.a = (float)(y2 - y1)/(float)(x2 - x1); ret.b = -1; ret.c = (y1 - (ret.a * x1)); } @@ -7630,6 +7630,11 @@ void loadtile(short tilenume) } else Bmemset((char *)waloff[tilenume],0,dasiz); } +void checktile(short tilenume) +{ + if (!waloff[tilenume]) + loadtile(tilenume); +} // // allocatepermanenttile diff --git a/polymer/build/src/polymer.c b/polymer/build/src/polymer.c index 843f52799..905a81a66 100644 --- a/polymer/build/src/polymer.c +++ b/polymer/build/src/polymer.c @@ -153,7 +153,7 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho cliplanecount = 0; - if (updatesectors) + if ((updatesectors) || 1) { i = 0; while (i < numsectors) @@ -209,8 +209,8 @@ void polymer_drawrooms(long daposx, long daposy, long daposz, sho polymer_addcliplane(equation(wal->x, wal->y, wall[wal->point2].x, wall[wal->point2].y), equation(daposx, daposy, wal->x, wal->y), equation(daposx, daposy, wall[wal->point2].x, wall[wal->point2].y), - (daposx + wal->x + wall[wal->point2].x) / 3, - (daposy + wal->y + wall[wal->point2].y) / 3); + (float)(daposx + wal->x + wall[wal->point2].x) / 3.0f, + (float)(daposy + wal->y + wall[wal->point2].y) / 3.0f); } } @@ -242,10 +242,12 @@ void polymer_rotatesprite(long sx, long sy, long z, short a, shor void polymer_drawmaskwall(long damaskwallcnt) { + OSD_Printf("PR : Masked wall %i...\n", damaskwallcnt); } void polymer_drawsprite(long snum) { + OSD_Printf("PR : Sprite %i...\n", snum); } // SECTORS @@ -359,6 +361,11 @@ int polymer_updatesector(short sectnum) curypanning = sec->ceilingypanning; } + if (picanm[curpicnum]&192) curpicnum += animateoffs(curpicnum,sectnum); + + if (!waloff[curpicnum]) + loadtile(curpicnum); + tex = (curstat & 64) ? ((wal->x - wall[sec->wallptr].x) * secangsin) + ((-wal->y - -wall[sec->wallptr].y) * secangcos) : wal->x; tey = (curstat & 64) ? ((wal->x - wall[sec->wallptr].x) * secangcos) - ((wall[sec->wallptr].y - wal->y) * secangsin) : -wal->y; @@ -394,7 +401,12 @@ int polymer_updatesector(short sectnum) curpicnum = sec->ceilingpicnum; curglpic = &s->ceilglpic; } + + if (picanm[curpicnum]&192) curpicnum += animateoffs(curpicnum,sectnum); + if (!waloff[curpicnum]) + loadtile(curpicnum); + curbuffer[0] = curbuffer[1] = curbuffer[2] = ((float)(numpalookups-min(max(curstat,0),numpalookups)))/((float)numpalookups); curbuffer[3] = 1.0f; @@ -598,13 +610,14 @@ int polymer_initwall(short wallnum) void polymer_updatewall(short wallnum) { - short nwallnum, nnwallnum; + short nwallnum, nnwallnum, curpicnum; walltype *wal; sectortype *sec, *nsec; _prwall *w; _prsector *s, *ns; pthtyp* pth; - long xref[2], yref, xdif, ydif, dist, ypancoef; + long xref[2], yref, xdif, ydif, dist; + float ypancoef; int i; wal = &wall[wallnum]; @@ -638,7 +651,14 @@ void polymer_updatewall(short wallnum) memcpy(&w->wallbuffer[10], &s->ceilbuffer[(wal->point2 - sec->wallptr) * 5], sizeof(GLfloat) * 3); memcpy(&w->wallbuffer[15], &s->ceilbuffer[(wallnum - sec->wallptr) * 5], sizeof(GLfloat) * 3); - pth = gltexcache(wal->picnum, wal->pal, 0); + curpicnum = wal->picnum; + + if (picanm[curpicnum]&192) curpicnum += animateoffs(curpicnum,wallnum+16384); + + if (!waloff[curpicnum]) + loadtile(curpicnum); + + pth = gltexcache(curpicnum, wal->pal, 0); w->wallglpic = pth ? pth->glpic : 0; if (pth && (pth->flags & 2) && (pth->palnum != wal->pal)) { @@ -652,7 +672,15 @@ void polymer_updatewall(short wallnum) else yref = sec->ceilingz; - ypancoef = (int)(256.0f / tilesizy[wal->picnum]); + if (wal->ypanning) + { + ypancoef = (float)(pow2long[picsiz[curpicnum] >> 4]); + if (ypancoef < tilesizy[curpicnum]) + ypancoef *= 2; + ypancoef *= (float)(wal->ypanning) / (256.0f * (float)(tilesizy[curpicnum])); + } + else + ypancoef = 0; i = 0; while (i < 4) @@ -661,8 +689,8 @@ void polymer_updatewall(short wallnum) ydif = xref[1] - w->wallbuffer[(i * 5)]; dist = ((xdif * xdif) + (ydif * ydif)) != 0; - w->wallbuffer[(i * 5) + 3] = ((dist * 8.0f * wal->xrepeat) + wal->xpanning) / (float)(tilesizx[wal->picnum]); - w->wallbuffer[(i * 5) + 4] = (-(float)(yref + w->wallbuffer[(i * 5) + 1]) / ((tilesizy[wal->picnum] * 2048.0f) / (float)(wal->yrepeat))) + ((float)(wal->ypanning) / (float)(ypancoef * tilesizy[wal->picnum])); + w->wallbuffer[(i * 5) + 3] = ((dist * 8.0f * wal->xrepeat) + wal->xpanning) / (float)(tilesizx[curpicnum]); + w->wallbuffer[(i * 5) + 4] = (-(float)(yref + w->wallbuffer[(i * 5) + 1]) / ((tilesizy[curpicnum] * 2048.0f) / (float)(wal->yrepeat))) + ypancoef; if (wal->cstat & 256) w->wallbuffer[(i * 5) + 4] = -w->wallbuffer[(i * 5) + 4]; @@ -687,7 +715,17 @@ void polymer_updatewall(short wallnum) memcpy(&w->wallbuffer[10], &ns->floorbuffer[(nwallnum - nsec->wallptr) * 5], sizeof(GLfloat) * 3); memcpy(&w->wallbuffer[15], &ns->floorbuffer[(nnwallnum - nsec->wallptr) * 5], sizeof(GLfloat) * 3); - pth = gltexcache(wal->picnum, wal->pal, 0); + if (wal->cstat & 2) + curpicnum = wall[nwallnum].picnum; + else + curpicnum = wal->picnum; + + if (picanm[curpicnum]&192) curpicnum += animateoffs(curpicnum,wallnum+16384); + + if (!waloff[curpicnum]) + loadtile(curpicnum); + + pth = gltexcache(curpicnum, wal->pal, 0); w->wallglpic = pth ? pth->glpic : 0; if (pth && (pth->flags & 2) && (pth->palnum != wal->pal)) { @@ -701,7 +739,15 @@ void polymer_updatewall(short wallnum) else yref = nsec->floorz; - ypancoef = (int)(256.0f / tilesizy[wal->picnum]); + if (wal->ypanning) + { + ypancoef = (float)(pow2long[picsiz[curpicnum] >> 4]); + if (ypancoef < tilesizy[curpicnum]) + ypancoef *= 2; + ypancoef *= (float)(wal->ypanning) / (256.0f * (float)(tilesizy[curpicnum])); + } + else + ypancoef = 0; i = 0; while (i < 4) @@ -710,8 +756,8 @@ void polymer_updatewall(short wallnum) ydif = xref[1] - w->wallbuffer[(i * 5)]; dist = ((xdif * xdif) + (ydif * ydif)) != 0; - w->wallbuffer[(i * 5) + 3] = ((dist * 8.0f * wal->xrepeat) + wal->xpanning) / (float)(tilesizx[wal->picnum]); - w->wallbuffer[(i * 5) + 4] = (-(float)(yref + w->wallbuffer[(i * 5) + 1]) / ((tilesizy[wal->picnum] * 2048.0f) / (float)(wal->yrepeat))) + ((float)(wal->ypanning) / (float)(ypancoef * tilesizy[wal->picnum])); + w->wallbuffer[(i * 5) + 3] = ((dist * 8.0f * wal->xrepeat) + wal->xpanning) / (float)(tilesizx[curpicnum]); + w->wallbuffer[(i * 5) + 4] = (-(float)(yref + w->wallbuffer[(i * 5) + 1]) / ((tilesizy[curpicnum] * 2048.0f) / (float)(wal->yrepeat))) + ypancoef; if (wal->cstat & 256) w->wallbuffer[(i * 5) + 4] = -w->wallbuffer[(i * 5) + 4]; @@ -734,7 +780,17 @@ void polymer_updatewall(short wallnum) memcpy(&w->overbuffer[10], &s->ceilbuffer[(wal->point2 - sec->wallptr) * 5], sizeof(GLfloat) * 3); memcpy(&w->overbuffer[15], &s->ceilbuffer[(wallnum - sec->wallptr) * 5], sizeof(GLfloat) * 3); - pth = gltexcache((wal->overpicnum) ? wal->overpicnum : wal->picnum, wal->pal, 0); + if ((wal->cstat & 16) || (wal->overpicnum == 0)) + curpicnum = wal->picnum; + else + curpicnum = wal->picnum; + + if (picanm[curpicnum]&192) curpicnum += animateoffs(curpicnum,wallnum+16384); + + if (!waloff[curpicnum]) + loadtile(curpicnum); + + pth = gltexcache(curpicnum, wal->pal, 0); w->overglpic = pth ? pth->glpic : 0; memcpy(w->overcolor, w->wallcolor, sizeof(GLfloat) * 4); @@ -750,7 +806,15 @@ void polymer_updatewall(short wallnum) else yref = nsec->ceilingz; - ypancoef = (int)(256.0f / tilesizy[wal->picnum]); + if (wal->ypanning) + { + ypancoef = (float)(pow2long[picsiz[curpicnum] >> 4]); + if (ypancoef < tilesizy[curpicnum]) + ypancoef *= 2; + ypancoef *= (float)(wal->ypanning) / (256.0f * (float)(tilesizy[curpicnum])); + } + else + ypancoef = 0; i = 0; while (i < 4) @@ -759,8 +823,8 @@ void polymer_updatewall(short wallnum) ydif = xref[1] - w->overbuffer[(i * 5)]; dist = ((xdif * xdif) + (ydif * ydif)) != 0; - w->overbuffer[(i * 5) + 3] = ((dist * 8.0f * wal->xrepeat) + wal->xpanning) / (float)(tilesizx[wal->picnum]); - w->overbuffer[(i * 5) + 4] = (-(float)(yref + w->overbuffer[(i * 5) + 1]) / ((tilesizy[wal->picnum] * 2048.0f) / (float)(wal->yrepeat))) + ((float)(wal->ypanning) / (float)(ypancoef * tilesizy[wal->picnum])); + w->overbuffer[(i * 5) + 3] = ((dist * 8.0f * wal->xrepeat) + wal->xpanning) / (float)(tilesizx[curpicnum]); + w->overbuffer[(i * 5) + 4] = (-(float)(yref + w->overbuffer[(i * 5) + 1]) / ((tilesizy[curpicnum] * 2048.0f) / (float)(wal->yrepeat))) + ypancoef; if (wal->cstat & 256) w->overbuffer[(i * 5) + 4] = -w->overbuffer[(i * 5) + 4]; @@ -866,7 +930,7 @@ int polymer_portalinfrustum(short wallnum) return (1); } -void polymer_addcliplane(_equation clip, _equation left, _equation right, long refx, long refy) +void polymer_addcliplane(_equation clip, _equation left, _equation right, float refx, float refy) { if (cliplanecount == maxcliplanecount) cliplanes = realloc(cliplanes, sizeof(_cliplane) * ++maxcliplanecount); diff --git a/polymer/build/src/polymost.c b/polymer/build/src/polymost.c index 01a142004..d4baacfe4 100644 --- a/polymer/build/src/polymost.c +++ b/polymer/build/src/polymost.c @@ -65,7 +65,7 @@ Low priority: **************************************************************************************************/ -static long animateoffs(short tilenum, short fakevar); +long animateoffs(short tilenum, short fakevar); long rendmode = 0; long usemodels=1, usehightile=1; diff --git a/polymer/eduke32/Makefile.deps b/polymer/eduke32/Makefile.deps index e5a936034..77cc1bcc1 100644 --- a/polymer/eduke32/Makefile.deps +++ b/polymer/eduke32/Makefile.deps @@ -1,4 +1,4 @@ -duke3d_h=$(EINC)/build.h $(EINC)/pragmas.h $(EINC)/compat.h $(EINC)/cache1d.h $(EINC)/baselayer.h $(SRC)/jmact/types.h $(SRC)/jmact/file_lib.h $(SRC)/jmact/util_lib.h $(SRC)/jmact/keyboard.h $(SRC)/jmact/control.h $(INC)/develop.h $(INC)/gamedefs.h $(INC)/function.h $(INC)/config.h $(INC)/sounds.h $(INC)/rts.h $(INC)/_rts.h $(INC)/soundefs.h $(SRC)/jaudiolib/fx_man.h $(SRC)/jaudiolib/music.h $(INC)/namesdyn.h $(INC)/funct.h $(INC)/duke3d.h $(EINC)/mmulti.h +duke3d_h=$(EINC)/build.h $(EINC)/polymer.h $(EINC)/pragmas.h $(EINC)/compat.h $(EINC)/cache1d.h $(EINC)/baselayer.h $(SRC)/jmact/types.h $(SRC)/jmact/file_lib.h $(SRC)/jmact/util_lib.h $(SRC)/jmact/keyboard.h $(SRC)/jmact/control.h $(INC)/develop.h $(INC)/gamedefs.h $(INC)/function.h $(INC)/config.h $(INC)/sounds.h $(INC)/rts.h $(INC)/_rts.h $(INC)/soundefs.h $(SRC)/jaudiolib/fx_man.h $(SRC)/jaudiolib/music.h $(INC)/namesdyn.h $(INC)/funct.h $(INC)/duke3d.h $(EINC)/mmulti.h gamedef_h=$(SRC)/gamedef.h $(OBJ)/game.$o: $(SRC)/*.c $(SRC)/jmact/scriplib.h $(duke3d_h) $(INC)/osdfuncs.h $(INC)/osdcmds.h $(INC)/grpscan.h diff --git a/polymer/polymer/polymer.suo b/polymer/polymer/polymer.suo index a356a588d9962a09404a69518c13832b9dcdafcc..c1c20262767c44cdba3cdc9372ef271ab203ce02 100644 GIT binary patch delta 8483 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 delta 5366 zcmbtYYjjlA6~5=@-pNb|W8RrOO+tc`kSC7>g5n4Ws6Zl#SPQELM8sFE7$Sm_QNu&U z7P2iD1vDTCLgbN42~w>QSQIS;L{!>>B6g{(3kB_9aal>feX|F{kFL_y9lqK7e0QI7 z_C1e%&Lz0q44yW&j)};s(KPKsS6A2F&_jS*fw91Cz|R4i5#jIM3kH0;g;qt3HrS*u zBbvO2SGo3dp4q1&;1XOzbBuS*1eh-R(wnOsUCZ?(yBdBRU! zU!n9-FPd}34Ibt0+1!mWC>;k_T$)EyO4H6GfG9*g2;9L<1LMwI__~Yv7T^tlr6)fX z<%czUSd2?|`mc|xq7lhu6pA}+=HQtgj>8VcHz`#{OZ+#Pm1s!Ou$m;AotWL6wAW06 zXYa5lg_45mXEZChM)ePKy)xjD7>OT@{il@~cDnD&NP}mH+*$kM2BE=nU@kBicuc2L zSq<)6VLCo_*^7-wQJ}NgL-o=KyC`RcuA;(?Qz-Ya8H<(+!;Bru>#g^?!|ATT3sPu6LAC1b zFe_ns9n0)jt*&saU&4xkl|&!(n~=(ZU=oIF58&@!?S5^FHWRwPRz@ciebiBS^tNQU z;B7R&6QHK0Ll+1)P`FI!a^WgP^P^h+f!qRc8}R_Tb7UfYRaDbhGW5rtT;!)=NrVw6 zg}%^Si)BE!av}-$%zKBWAHcnFJNJm@1-KsY0DFX+4}CAda#+(E9it7u?>UyH9Tj~w z^ao-e6I}-VXR&!Lb7#Ceegt^A=<*i4o<9ay+`?7B_K3Ye^nF@D(-unMx1#wimx;YX zG>`2{v0FqB2e(?$*_2eOOV6~bz5ucTP1COTJIMSG1>wSi`pRhgU?GQ*3_#nV%o zO-ub_jPh-h2GD}S%I5x0*!qBgK~MA#((sC5jod>CaEM10asisTY@kcHUWMIUDY$6Z zELRD~@9!6GoN&CS#tS!JIIgomxMzjK#5Zcc7P7gABMJ9{aJ(*82=`JCzZT)v3zq=D z4Z^kd@Ow?T?ZWY@`<=s0(zMrmIPMb1w}nfA<8I;h_3-)R^N$19ip{kVfll_NU3qeUqBsBBKCdNb;<~#M2BxqNGrkU|A2xEnityz zpbNmP(6+>QGZIN6!pU*_s^TdyVT}1=&cj(6sT1+kGU0jUrplUBDw+^ahikC2kybpY zVWP%ldc2~st@a6J>k~_38~F(Er*_XQ&p3y_6F>aU`=OcR1h9i2Kn@7U_Cev^gLd8( z9Q&guZKqGuMnJy{&D>DnY1k~UqH*RRX|gyVh^5F`iUlVEvk zZpL$#yzmQ9<1J6x`iu)63eM~p;Bw9!ZJOf~ubqxKp+|9~O4rnV<0Jx2+j{RfwI5|B zcmSw?s=wK%pO8GEKyjGV1$MZj=+d}oT23MxG+p>bXDtKajRUVJauoK$(x znd3p^@#1BV@p3p$>sbIx9>9LgaS~?XL1vD1e}JVPU@jk+1+c8QzQC`(Rf%#2l@|P`-bWi&6`F$1XGv_rgM7~^PcpI-lm+{i|mC$VR zxMT@8T{wQ_yM%j8IG(b3!YvYxQ~y)Kk#L-DpA)V{IG&T$N)E3rLV7`N6~`UI#e-`X z`z_JDyVzzqDIAagr@|$}flZ!dA3H;GgyUfP2v@A*@MK4hrbNhJh+`jcw+r{6aNOWb z;T8(V4K5PyCE>We7U6aX$EQcTaA%;M{6gx=Y+Bo%9=JxH@VPTg?6abIOurF38b={V zJPPo_X6XxU2M#4G3MS;o@|A(biyGa1#5NS^OAb)S@?hHwdv%kW>l;2yDYUZMyb?_E zMW%jLl}GVaiEBF-X*;y)fZ5!NP5W{};~_k`3ivC)k?^FQ7W-?_vCy3Pd2GHDj`Q+) zfX9`$HP>a~Ltrd$2MFePCvO)!ya@Q_%{HXy;%eZnA6^-+O9gghn`IX?JvgWz70mI{ ztj-CeFF#RT4DP2e51_TdX!S!yN7fZn;Q5ZWSAM0E-r}qd`2m{ybw*rkcU`A;skV({ z6fUpfPnh~miz&EpD*gS051%wHYD>wbB^fdH_SUg#2-giSeO?3Gn1GxX&D>XF=k-_@ zSJ^{0FVw?x{x6ymJI?AIt2R-`w!oSl2ECY>YNzi0JYrd_nnLp?xUAbV)#Tjc#xoI7 z9PEENIP5tGBbBY*=)%(Kth(%K{GPn`GMwjS+t=ktGQ#3 zwa2f@>`+HEW^`|{UA*szNs~IG?dVWQQ6SCR?scng)%uR%%9YK>j)`ICh3$goV43SB zb~JsuHr^90rFhzsQeqb#c}_JS9pTdW7$^!a12u$Z9qsfeP7xP37}bBUm^$7Mw0*eK z-Ih>4(n>J`=RS;?D6FpkKsWzun6D?IGV6L%?G`ra5r|~gkhR|qGg9E zsy|gldklPQc5A!-vz91>-^TWRJx!I?!I}b01!e=&fI9)c%-tpWZs>c&rq(n5ehpH1 z3i=UX4loyZ6yS=CM%Y1Jqq@#SJK^kUy+q>|DZ?>yc^3zMGhI8+Ynys+D5bamaqaq` zPw8#nMMvlH81j->04xNa0=Uzsp`QU318GZdj*o7J@f^Spt!iEQw$(0II}FvK%x#0M z(cKrNW2VY#ydPdztlAuahnW-2lK|($CV;sFfV<^0kh^7$XO5?aPYDi#xf_6>*h@rn z-4y`0yHYsLqAfrc-#b>r;L6Fs8ekOgGQb>nvKHW*<2ryjZfFz0XJ9M99Cz{>kOpi4 z!ki78zs24ZE*E+kz>)=_e0LCw@eg9V1n1WbOYQ0z%>QcejMq32iOuqlWq~xz$ZhH#lgPt&`G?{U~>j zl-!^%&E}U=)%gs-g|Nn2nyCsdy+i(o-ny$)sQKZKbFbB2u4;_|0|%9p@{Fb!&tN)f zB+=AA!d|%iEM%1@ Hs@?wvqBIw@