From 98456aefe3aa6637a56bb6f700f9df528563d986 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Thu, 12 May 2011 23:31:13 +0000 Subject: [PATCH] -- engine: * support for free mixing of multi- and single-tile parallaxed skies in classic * make visibility independent of yxaspect and viewingrange in OpenGL modes -- editor: * when dragging walls, restore pixel width after that (only for the left and right walls of pointhighlight, and its nextwalls, if any) * pasting on walls and auto-aligning them now carries over a few more fields -- fixes: * visibility in OpenGL modes wasn't incremented gradually (regression due to making 'clamp' an inline function instead of a macro) * memory corruption due to calling qlz_compress with less than the recommended surplus storage of 400 bytes * decorative sprites in the mirror showing non-flipped * make the subway SE message (much) more helpful by showing which sector the game considers to be the track sector git-svn-id: https://svn.eduke32.com/eduke32@1882 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/include/build.h | 11 +- polymer/eduke32/build/include/editor.h | 6 +- polymer/eduke32/build/include/polymost.h | 6 +- polymer/eduke32/build/src/build.c | 118 ++++++++- polymer/eduke32/build/src/defs.c | 4 +- polymer/eduke32/build/src/engine.c | 311 ++++++++++++++++------- polymer/eduke32/build/src/engine_priv.h | 6 +- polymer/eduke32/build/src/polymost.c | 2 +- polymer/eduke32/source/actors.c | 14 +- polymer/eduke32/source/astub.c | 169 +++++++----- polymer/eduke32/source/duke3d.h | 8 +- polymer/eduke32/source/game.c | 28 +- polymer/eduke32/source/game.h | 5 + polymer/eduke32/source/gameexec.c | 3 + polymer/eduke32/source/m32structures.c | 6 +- polymer/eduke32/source/player.c | 16 +- polymer/eduke32/source/savegame.c | 48 +++- 17 files changed, 575 insertions(+), 186 deletions(-) diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h index f42239b9d..2eadcc913 100644 --- a/polymer/eduke32/build/include/build.h +++ b/polymer/eduke32/build/include/build.h @@ -41,6 +41,7 @@ extern "C" { #define MAXYDIM 3200 #define MAXBASEPALS 8 #define MAXPALOOKUPS 256 +#define MAXPSKYMULTIS 8 #define MAXPSKYTILES 256 #define MAXSPRITESONSCREEN 4096 #define MAXUNIQHUDID 256 //Extra slots so HUD models can store animation state without messing game sprites @@ -81,13 +82,16 @@ void yax_updategrays(int32_t posze); # define YAX_ITER_WALLS(Wal, Itervar, Cfvar) Cfvar=0, Itervar=(Wal); Itervar!=-1; \ Itervar=yax_getnextwall(Itervar, Cfvar), (void)(Itervar==-1 && Cfvar==0 && (Cfvar=1) && (Itervar=yax_getnextwall((Wal), Cfvar))) +extern int16_t yax_bunchnum[MAXSECTORS][2]; +extern int16_t yax_nextwall[MAXWALLS][2]; + int16_t yax_getbunch(int16_t i, int16_t cf); void yax_getbunches(int16_t i, int16_t *cb, int16_t *fb); void yax_setbunch(int16_t i, int16_t cf, int16_t bunchnum); void yax_setbunches(int16_t i, int16_t cb, int16_t fb); int16_t yax_getnextwall(int16_t wal, int16_t cf); void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall); -void yax_update(int32_t onlyreset); +void yax_update(int32_t resetstat); int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf, int16_t *ret_bunchnum); static inline int32_t yax_waltosecmask(int32_t walclipmask) @@ -297,7 +301,12 @@ EXTERN int32_t visibility, parallaxvisibility; EXTERN int32_t windowx1, windowy1, windowx2, windowy2; EXTERN int16_t startumost[MAXXDIM], startdmost[MAXXDIM]; +// original multi-psky handling (only one per map) EXTERN int16_t pskyoff[MAXPSKYTILES], pskybits; +// new multi-psky -- up to MAXPSKYMULTIS +EXTERN int16_t pskynummultis; +EXTERN int16_t pskymultilist[MAXPSKYMULTIS], pskymultibits[MAXPSKYMULTIS]; +EXTERN int16_t pskymultioff[MAXPSKYMULTIS][MAXPSKYTILES]; EXTERN int16_t headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1]; EXTERN int16_t prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES]; diff --git a/polymer/eduke32/build/include/editor.h b/polymer/eduke32/build/include/editor.h index 4629e2bfd..ad40a6252 100644 --- a/polymer/eduke32/build/include/editor.h +++ b/polymer/eduke32/build/include/editor.h @@ -45,7 +45,7 @@ extern int32_t zmode, kensplayerheight, zlock; //extern int16_t defaultspritecstat; extern int32_t temppicnum, tempcstat, templotag, temphitag, tempextra; -extern uint32_t temppal, tempvis, tempxrepeat, tempyrepeat; +extern uint32_t temppal, tempvis, tempxrepeat, tempyrepeat, tempxpanning, tempypanning; extern int32_t tempshade, tempxvel, tempyvel, tempzvel; extern char somethingintab; @@ -73,6 +73,10 @@ extern int32_t showambiencesounds; extern uint8_t graysectbitmap[MAXSECTORS>>3]; extern uint8_t graywallbitmap[MAXWALLS>>3]; +#ifdef YAX_ENABLE +int32_t yax_is121(int16_t bunchnum, int16_t getfloor); +#endif + // editor side view extern int32_t m32_sideview; extern int32_t m32_sideelev; diff --git a/polymer/eduke32/build/include/polymost.h b/polymer/eduke32/build/include/polymost.h index 80c52017f..ddf6a0deb 100644 --- a/polymer/eduke32/build/include/polymost.h +++ b/polymer/eduke32/build/include/polymost.h @@ -131,7 +131,11 @@ static inline void fogcalc(const int32_t shade, const int32_t vis, const int32_t f = (vis > 239) ? (float)(gvisibility*((vis-240+f)/(klabs(vis-256)))) : (float)(gvisibility*(vis+16+f)); - fogresult = clamp(f, 0.001f, 100.f); + if (f < 0.001f) + f = 0.001f; + else if (f > 100.0f) + f = 100.0f; + fogresult = f; Bmemcpy(fogcol, &fogtable[pal<<2], sizeof(fogcol)); } diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index cfb5f5573..c8ebc00ae 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -109,7 +109,7 @@ int16_t highlightsector[MAXSECTORS], highlightsectorcnt = -1; extern char textfont[128][8]; int32_t temppicnum, tempcstat, templotag, temphitag, tempextra; -uint32_t temppal, tempvis, tempxrepeat, tempyrepeat; +uint32_t temppal, tempvis, tempxrepeat, tempyrepeat, tempxpanning=0, tempypanning=0; int32_t tempshade, tempxvel, tempyvel, tempzvel; char somethingintab = 255; @@ -338,6 +338,21 @@ static void M32_drawdebug(void) #endif #ifdef YAX_ENABLE +// Check whether bunchnum has exactly one corresponding floor and ceiling +// and return it in this case. If not 1-to-1, return -1. +int32_t yax_is121(int16_t bunchnum, int16_t getfloor) +{ + int32_t i; + i = headsectbunch[0][bunchnum]; + if (i<0 || nextsectbunch[0][i]>=0) + return -1; + i = headsectbunch[1][bunchnum]; + if (i<0 || nextsectbunch[1][i]>=0) + return -1; + + return headsectbunch[getfloor][bunchnum]; +} + static void yax_fixreverselinks(int16_t oldwall, int16_t newwall) { int32_t cf, ynw; @@ -2241,6 +2256,7 @@ void overheadeditor(void) int32_t prefixarg = 0; int32_t resetsynctics = 0, lasttick=getticks(), waitdelay=totalclock, lastdraw=getticks(); int32_t tsign; + int32_t olen[2]={0,0}, nlen[2]={0,0}, dragwall[2] = {-1, -1}; m32_setkeyfilter(1); @@ -2788,9 +2804,46 @@ void overheadeditor(void) if (linehighlight >= 0) { int32_t secti = sectorofwall(linehighlight); +#ifdef YAX_ENABLE + int16_t cf, bunchnum, tempsect, tempwall; + + for (i=0; i= 0 && + (tempsect=yax_is121(bunchnum, cf)) >= 0) + { + tempwall = yax_getnextwall(tempwall, cf); + if (tempwall < 0) + break; // corrupt! + wall[tempwall].cstat |= (1<<14); + } + } + + k = 0; + for (i=0; i 0) + message("Set first walls (sector[].wallptr) for %d sectors", k+1); + else +#endif + printmessage16("This wall now sector %d's first wall (sector[].wallptr)", secti); setfirstwall(secti, linehighlight); asksave = 1; - printmessage16("This wall now sector %d's first wall (sector[].wallptr)", secti); } } } @@ -3049,7 +3102,7 @@ void overheadeditor(void) if (highlightsectorcnt>1 && SECTORFLD(highlightsector[i],stat, cf)&2) { - message("Sector %ss must not be sloped", cfs[cf]); + message("Sector %ss must not be sloped if extending more than one", cfs[cf]); goto end_yax; } } @@ -3565,13 +3618,12 @@ end_yax: ; goto end_after_dragging; j = 1; - if (highlightcnt > 0) - for (i=0; i= 0) + { + k = getlenbyrep(olen[i], wall[nw].xrepeat); + fixxrepeat(nw, k); + } + } + } } else if ((pointhighlight&0xc000) == 16384) { @@ -3595,6 +3670,8 @@ end_yax: ; day = sprite[pointhighlight&16383].y; } + dragwall[0] = dragwall[1] = -1; + for (runi=0; runi<3; runi++) for (i=numwalls-1; i>=0; i--) //delete points { @@ -3720,8 +3797,18 @@ end_after_dragging: else //if (highlightsectorcnt <= 0) { if ((bstatus&1) > (oldmousebstatus&1)) + { pointhighlight = getpointhighlight(mousxplc, mousyplc, pointhighlight); + if (pointhighlight >= 0) + { + dragwall[0] = lastwall(pointhighlight); + dragwall[1] = pointhighlight; + olen[0] = wallength(dragwall[0]); + olen[1] = wallength(dragwall[1]); + } + } + if (pointhighlight >= 0 && (!m32_sideview || m32_sideelev>=32)) { if (m32_sideview) @@ -4923,7 +5010,8 @@ check_next_sector: ; for (j=numwalls; j= 0) { @@ -8194,7 +8282,6 @@ static void AlignWalls(int32_t w0, int32_t z0, int32_t w1, int32_t z1, int32_t t int32_t n; //do the x alignment - wall[w1].cstat &= ~0x0108; //Set to non-flip wall[w1].xpanning = (uint8_t)((wall[w0].xpanning + (wall[w0].xrepeat<<3))%tilesizx[tilenum]); for (n=picsiz[tilenum]>>4; (1<=0; i--) { @@ -600,7 +600,7 @@ static int32_t defsparser(scriptfile *script) // initprintf("got bpl %d xsiz %d ysiz %d\n",bpl,xsiz,ysiz); ftd = Bmalloc(xsiz*ysiz); - faketiledata[tile] = Bmalloc(xsiz*ysiz); + faketiledata[tile] = Bmalloc(xsiz*ysiz + 400); for (i=xsiz-1; i>=0; i--) { diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index ed3671af1..21a660415 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -188,10 +188,10 @@ int16_t editstatus = 0; ////////// YAX ////////// -#if YAX_M32_DEBUG +#ifdef YAX_DEBUG extern char m32_debugstr[64][128]; extern int32_t m32_numdebuglines; -# define yaxdebug(fmt, ...) do { if (m32_numdebuglines<64) Bsprintf(m32_debugstr[m32_numdebuglines++], fmt, ##__VA_ARGS__); } while (0) +# define yaxdebug(fmt, ...) do { if (m32_numdebuglines<64) Bsnprintf(m32_debugstr[m32_numdebuglines++], 128, fmt, ##__VA_ARGS__); } while (0) #else # define yaxdebug(fmt, ...) #endif @@ -242,6 +242,7 @@ static int32_t scansector_retfast = 0; static int32_t scansector_collectsprites = 1; static int32_t yax_globalcf = -1; static int32_t yax_globallev = YAX_MAXDRAWS; +//static int32_t yax_globalbunch = -1; // duplicated tsprites // [i]: @@ -252,8 +253,8 @@ static int16_t yax_spritesortcnt[1 + 2*YAX_MAXDRAWS]; static int16_t yax_tsprite[1 + 2*YAX_MAXDRAWS][MAXSPRITESONSCREEN]; // game-time YAX data structures -static int16_t yax_bunchnum[MAXSECTORS][2]; -static int16_t yax_nextwall[MAXWALLS][2]; +int16_t yax_bunchnum[MAXSECTORS][2]; +int16_t yax_nextwall[MAXWALLS][2]; static int32_t yax_islockededge(/*int16_t sec,*/ int16_t line, int16_t cf) #if 1 @@ -364,7 +365,10 @@ void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall) } //// in-struct --> array transfer; list construction -void yax_update(int32_t onlyreset) +// resetstat: 0: reset and read data from structs and construct linked lists etc. +// 1: only reset +// 2: read data from game-time arrays and construct linked lists etc. +void yax_update(int32_t resetstat) { // TODO: always make bunchnums consecutive int32_t i, j, oeditstatus=editstatus; @@ -374,39 +378,46 @@ void yax_update(int32_t onlyreset) for (i=0; i=numsectors) + yax_bunchnum[i][0] = yax_bunchnum[i][1] = -1; nextsectbunch[0][i] = nextsectbunch[1][i] = -1; } for (i=0; i=numwalls) + yax_nextwall[i][0] = yax_nextwall[i][1] = -1; - if (onlyreset) + if (resetstat==1) return; // constuct singly linked list of sectors-of-bunch - editstatus = 1; // read bunchnums directly from the sector struct! + editstatus = (resetstat==0); // read bunchnums directly from the sector struct! for (i=numsectors-1; i>=0; i--) { yax_getbunches(i, &cb, &fb); - yax_bunchnum[i][0] = cb; - yax_bunchnum[i][1] = fb; + if (resetstat==0) + { + yax_bunchnum[i][0] = cb; + yax_bunchnum[i][1] = fb; + } if (cb >= 0) { - for (j=sector[i].wallptr; j= 0) { - for (j=sector[i].wallptr; j0 b2 is farther away than b1 +static inline int32_t yax_walldist(int32_t w) +{ + return klabs(wall[w].x-globalposx) + klabs(wall[w].y-globalposy); +} + static int yax_cmpbunches(const int16_t *b1, const int16_t *b2) { int32_t s1,s2, w1,w2; -#if 1 - int32_t dx1,dy1, dx2,dy2, r; -#else - int64_t dx1,dy1, dx2,dy2, r; -#endif + s1 = headsectbunch[yax_globalcf][*b1]; s2 = headsectbunch[yax_globalcf][*b2]; w1 = sector[s1].wallptr; w2 = sector[s2].wallptr; - dx1 = wall[w1].x-globalposx; dy1 = wall[w1].y-globalposy; - dx2 = wall[w2].x-globalposx; dy2 = wall[w2].y-globalposy; #if 1 - r = klabs(dx2+dy2) - klabs(dx1+dy1); - return r; + return (yax_walldist(w2) - yax_walldist(w1)); #else - r = (dx2*dx2 + dy2*dy2) - (dx1*dx1 + dy1*dy1); - if (r > 0) - return 1; - return r>>63; + { + int64_t dx1,dy1, dx2,dy2, r; + + dx1 = wall[w1].x-globalposx; dy1 = wall[w1].y-globalposy; + dx2 = wall[w2].x-globalposx; dy2 = wall[w2].y-globalposy; + + r = (dx2*dx2 + dy2*dy2) - (dx1*dx1 + dy1*dy1); + if (r > 0) + return 1; + return r>>63; + } #endif } @@ -491,27 +507,55 @@ static int32_t yax_getbestsector(int32_t bunchnum, int32_t cf, const int16_t *ou if (bunchnum==ourbunch[cf]) { k = yax_getneighborsect(globalposx, globalposy, sectnum, cf, NULL); - if (k < 0) - k = headsectbunch[!cf][bunchnum]; - return k; + if (k >= 0) + return k; } - else + { -// return headsectbunch[!cf][bunchnum]; + int32_t j, walldist, bestsec=-1, bestwalldist=INT32_MAX; + int32_t startwall, endwall, checkthis; scansector_retfast = 1; scansector_collectsprites = 0; for (k = headsectbunch[!cf][bunchnum]; k != -1; k = nextsectbunch[!cf][k]) { - numscans = numbunches = 0; - scansector(k); - if (numbunches > 0) - break; + startwall = sector[k].wallptr; + endwall = startwall+sector[k].wallnum; + + checkthis = 0; + for (j=startwall; j 0) + bestsec = k; + } } scansector_collectsprites = 1; scansector_retfast = 0; - return k; + if (bestsec < 0) + bestsec = headsectbunch[!cf][bunchnum]; + + return bestsec; } } @@ -538,14 +582,15 @@ static void yax_tweakpicnums(int32_t bunchnum, int32_t cf, int32_t restore) } } -static void yax_copytsprite(int16_t curbunchnum) +static void yax_copytsprite(int32_t curbunchnum, int32_t resetsortcnt) { int16_t bunchnum; int32_t i, spritenum, gotthrough, sectnum, cf; int32_t sortcnt = yax_spritesortcnt[yax_globallev]; const spritetype *spr; - spritesortcnt = 0; + if (resetsortcnt) + spritesortcnt = 0; for (i=0; i= MAXSPRITESONSCREEN) + break; + Bmemcpy(&tsprite[spritesortcnt], spr, sizeof(spritetype)); spriteext[spritenum].tspr = &tsprite[spritesortcnt]; tsprite[spritesortcnt].owner = spritenum; @@ -605,7 +653,9 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn // original (1st-draw) and accumulated ('per-level') gotsector bitmaps static uint8_t ogotsector[MAXSECTORS>>3], lgotsector[MAXSECTORS>>3]; -// int32_t t; +#ifdef YAX_DEBUG + int32_t t; +#endif if (rendmode!=0 || numyaxbunches==0) { @@ -649,10 +699,15 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn j = yax_getbunch(i, cf); if (j >= 0 && !(havebunch[j>>3]&(1<<(j&7)))) { - havebunch[j>>3] |= (1<<(j&7)); - bunches[cf][bnchnum[cf]++] = j; - bnchend[lev][cf]++; - numhere++; + if ((SECTORFLD(i,stat, cf)&2) || + (cf==0 && globalposz > sector[i].ceilingz) || + (cf==1 && globalposz < sector[i].floorz)) + { + havebunch[j>>3] |= (1<<(j&7)); + bunches[cf][bnchnum[cf]++] = j; + bnchend[lev][cf]++; + numhere++; + } } } @@ -668,22 +723,20 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn for (bnchcnt=bbeg; bnchcnt < bbeg+numhere; bnchcnt++) { j = bunches[cf][bnchcnt]; // the actual bunchnum... - -// t=getticks(); +// yax_globalbunch = j; +#ifdef YAX_DEBUG + t=getticks(); +#endif k = yax_getbestsector(j, cf, ourbunch, sectnum); bestsec[cf][bnchcnt] = k; if (k < 0) { -// initprintf("cf %d, lev %d: skipped bunch %d\n", cf, lev, j); +#ifdef YAX_DEBUG + initprintf("%s, l %d: skipped bunch %d\n", cf?"v":"^", lev, j); +#endif continue; } - if (ourbunch[cf]==j) - { - ourbunch[cf] = yax_getbunch(k, cf); - sectnum = k; - } - if (lev != YAX_MAXDRAWS-1) { // +MAXSECTORS: force @@ -692,8 +745,15 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn for (i=0; i<(numsectors+7)>>3; i++) lgotsector[i] |= gotsector[i]; -// yaxdebug("cf %d, lev %d: fake-drawn sec %d (bunch %d), %d dspr, %2d ms", -// cf, lev, k, j, yax_spritesortcnt[yax_globallev], getticks()-t); + yaxdebug("%s, l %d: faked sec %3d (bunch %2d),%3d dspr, ob=[%2d,%2d], sn=%3d,%3d ms", + cf?"v":"^", lev, k, j, yax_spritesortcnt[yax_globallev], + ourbunch[0],ourbunch[1],sectnum,getticks()-t); + } + + if (ourbunch[cf]==j) + { + ourbunch[cf] = yax_getbunch(k, cf); + sectnum = k; } } @@ -716,7 +776,7 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn g_nodraw = 0; scansector_collectsprites = 0; -#if 0 +#ifdef ENGINE_CLEAR_SCREEN begindrawing(); for (i=0; i=0; lev--) { yax_globallev = YAX_MAXDRAWS + (-1 + 2*cf)*(lev+1); + scansector_collectsprites = (lev == YAX_MAXDRAWS-1); for (bnchcnt=bnchbeg[lev][cf]; bnchcnt= 0) for (bnchcnt=bnchbeg[0][cf]; bnchcnt=0; z=p2[z]) @@ -3792,7 +3873,7 @@ static void parascan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat, i else if (x >= 0) { l = globalpicnum; m = (picsiz[globalpicnum]&15); - globalpicnum = l+pskyoff[lplc[x]>>m]; + globalpicnum = l + dapskyoff[lplc[x]>>m]; if (((lplc[x]^lplc[xb1[z]-1])>>m) == 0) wallscan(x,xb1[z]-1,topptr,botptr,swplc,lplc); @@ -3801,7 +3882,7 @@ static void parascan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat, i j = x; while (x < xb1[z]) { - n = l+pskyoff[lplc[x]>>m]; + n = l + dapskyoff[lplc[x]>>m]; if (n != globalpicnum) { wallscan(j,x-1,topptr,botptr,swplc,lplc); @@ -3822,7 +3903,7 @@ static void parascan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat, i if (x >= 0) { l = globalpicnum; m = (picsiz[globalpicnum]&15); - globalpicnum = l+pskyoff[lplc[x]>>m]; + globalpicnum = l + dapskyoff[lplc[x]>>m]; if (((lplc[x]^lplc[xb2[bunchlast[bunch]]])>>m) == 0) wallscan(x,xb2[bunchlast[bunch]],topptr,botptr,swplc,lplc); @@ -3831,7 +3912,7 @@ static void parascan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat, i j = x; while (x <= xb2[bunchlast[bunch]]) { - n = l+pskyoff[lplc[x]>>m]; + n = l + dapskyoff[lplc[x]>>m]; if (n != globalpicnum) { wallscan(j,x-1,topptr,botptr,swplc,lplc); @@ -4039,7 +4120,12 @@ static void drawalls(int32_t bunch) { if ((fz[2] >= fz[0]) && (fz[3] >= fz[1])) { - if (globparaflorclip) + if (globparaflorclip +#ifdef YAX_ENABLE +// || ((sec->floorstat&2) && yax_globallev < YAX_MAXDRAWS) +// || yax_getbunch(wallnum, YAX_FLOOR) < 0 +#endif + ) for (x=x1; x<=x2; x++) if (dplc[x] < dmost[x]) if (umost[x] <= dmost[x]) @@ -4236,13 +4322,41 @@ static void drawalls(int32_t bunch) } #ifdef ENGINE_SCREENSHOT_DEBUG - if (engine_screenshot && !g_nodraw) + if (engine_screenshot) +#ifdef YAX_ENABLE + if (!g_nodraw) +#endif { static char fn[BMAX_PATH]; + static char bakframe[MAXXDIM*MAXYDIM]; + + char purple = getclosestcol(63, 0, 63); + char yellow = getclosestcol(63, 63, 0); + + begindrawing(); //{{{ + Bmemcpy(bakframe, (char *)frameplace, xdim*ydim); + for (x=0; x dmost[x]) + { + *((char *)frameplace + (ydim/2)*bytesperline + x) = yellow; + *((char *)frameplace + (ydim/2+1)*bytesperline + x) = purple; + continue; + } + + if (umost[x] >= 0 || umost[x] < ydim) + *((char *)frameplace + umost[x]*bytesperline + x) = purple; + + if (dmost[x]-1 >= 0 || dmost[x]-1 < ydim) + *((char *)frameplace + (dmost[x]-1)*bytesperline + x) = yellow; + } Bsprintf(fn, "engshot%04d.png", engine_screenshot); screencapture(fn, 0, "BUILD engine"); engine_screenshot++; + + Bmemcpy((char *)frameplace, bakframe, xdim*ydim); + enddrawing(); //}}} } #endif } @@ -7102,6 +7216,7 @@ int32_t initengine(void) xyaspect = -1; pskyoff[0] = 0; pskybits = 0; + pskynummultis = 0; parallaxtype = 2; parallaxyoffs = 0L; parallaxyscale = 65536; showinvisibility = 0; @@ -7261,7 +7376,7 @@ void drawrooms(int32_t daposx, int32_t daposy, int32_t daposz, i = mulscale16(xdimenscale,viewingrangerecip); globalpisibility = mulscale16(parallaxvisibility,i); - globalvisibility = mulscale16(visibility,i); + globalvisibility = rendmode==0 ? mulscale16(visibility,i) : scale(visibility<<2,4,3); globalhisibility = mulscale16(globalvisibility,xyaspect); globalcisibility = mulscale8(globalhisibility,320); @@ -7313,6 +7428,15 @@ void drawrooms(int32_t daposx, int32_t daposy, int32_t daposz, begindrawing(); //{{{ +#ifdef ENGINE_CLEAR_SCREEN +#ifdef YAX_ENABLE + if (!g_nodraw) +#endif + if (numyaxbunches==0) + for (i=0; ihitsect = -1; hitinfo->hitwall = -1; hitinfo->hitsprite = -1; if (sectnum < 0) return(-1); @@ -10385,7 +10509,8 @@ restart_grand: if (numyaxbunches == 0 || editstatus) return 0; - if (hitinfo->hitsprite==-1 && hitinfo->hitwall==-1 && hitinfo->hitsect!=oldhitsect) + if (hitinfo->hitsprite==-1 && hitinfo->hitwall==-1 && hitinfo->hitsect!=oldhitsect + && hitinfo->hitsect != oldhitsect2) // 'ping-pong' infloop protection { if (hitinfo->hitsect == -1 && oldhitsect >= 0) { @@ -10409,6 +10534,7 @@ restart_grand: sectnum = i; sv = &newsv; + oldhitsect2 = oldhitsect; oldhitsect = hitinfo->hitsect; hitinfo->hitsect = -1; @@ -11679,6 +11805,10 @@ void getzrange(const vec3_t *pos, int16_t sectnum, dawalclipmask = (cliptype&65535); dasprclipmask = (cliptype>>16); +#ifdef YAX_ENABLE + origclipsectorlist[0] = sectnum; + origclipsectnum = 1; +#endif clipsectorlist[0] = sectnum; clipsectcnt = 0; clipsectnum = 1; clipspritecnt = clipspritenum = 0; @@ -11792,7 +11922,10 @@ restart_grand: if (dx > 0) dax += dx*MAXCLIPDIST; else dax -= dx*MAXCLIPDIST; if (dy > 0) day -= dy*MAXCLIPDIST; else day += dy*MAXCLIPDIST; if (dax >= day) continue; - +#ifdef YAX_ENABLE + if (mcf==-1 && curspr==NULL) + origclipsectorlist[origclipsectnum++] = k; +#endif //It actually got here, through all the continue's!!! getzsofslope(k, pos->x,pos->y, &daz,&daz2); if (curspr) @@ -11963,12 +12096,6 @@ restart_grand: int16_t cb, fb, didchange; yax_getbunches(sectnum, &cb, &fb); - if (mcf==-1) - { - Bmemcpy(origclipsectorlist, clipsectorlist, clipsectnum*sizeof(clipsectorlist[0])); - origclipsectnum = clipsectnum; - } - mcf++; clipsectcnt = 0; clipsectnum = 0; diff --git a/polymer/eduke32/build/src/engine_priv.h b/polymer/eduke32/build/src/engine_priv.h index 468984292..4143f3a66 100644 --- a/polymer/eduke32/build/src/engine_priv.h +++ b/polymer/eduke32/build/src/engine_priv.h @@ -8,8 +8,12 @@ #define MAXNODESPERLINE 42 //Warning: This depends on MAXYSAVES & MAXYDIM! #define MAXCLIPDIST 1024 +// uncomment to clear the screen before each top-level draw +// (classic only) +// #define ENGINE_CLEAR_SCREEN + #ifdef YAX_ENABLE -# define YAX_MAXDRAWS 4 +# define YAX_MAXDRAWS 8 #endif extern uint8_t **basepaltableptr; diff --git a/polymer/eduke32/build/src/polymost.c b/polymer/eduke32/build/src/polymost.c index 672014f53..ee0404a3d 100644 --- a/polymer/eduke32/build/src/polymost.c +++ b/polymer/eduke32/build/src/polymost.c @@ -1486,7 +1486,7 @@ void writexcache(char *fn, int32_t len, int32_t dameth, char effect, texcachehea if (!picc) goto failure; else pic = picc; alloclen = miplen; - picc = Brealloc(packbuf, alloclen+16); + picc = Brealloc(packbuf, alloclen+400); if (!picc) goto failure; else packbuf = picc; picc = Brealloc(midbuf, miplen); diff --git a/polymer/eduke32/source/actors.c b/polymer/eduke32/source/actors.c index 9326a994c..0ac702c6a 100644 --- a/polymer/eduke32/source/actors.c +++ b/polymer/eduke32/source/actors.c @@ -412,9 +412,13 @@ int32_t A_MoveSprite(int32_t spritenum, const vec3_t *change, uint32_t cliptype) { spr->z = daz; #ifdef YAX_ENABLE - if (change->z && yax_getbunch(spr->sectnum, !!change->z)>=0) - if ((SECTORFLD(spr->sectnum,stat, !!change->z)&yax_waltosecmask(cliptype))==0) + if (change->z && yax_getbunch(spr->sectnum, (change->z>0))>=0) + if ((SECTORFLD(spr->sectnum,stat, (change->z>0))&yax_waltosecmask(cliptype))==0) + { +// initprintf("spr %d, sect %d: chz=%d, cfz=[%d,%d]\n", spritenum, spr->sectnum, change->z, +// actor[spritenum].ceilingz, actor[spritenum].floorz); setspritez(spritenum, (vec3_t *)spr); + } #endif } else if (retval == 0) retval = 16384+dasectnum; @@ -3279,7 +3283,6 @@ ACTOR_STATIC void G_MoveTransports(void) vect.x = g_player[p].ps->pos.x; vect.y = g_player[p].ps->pos.y; vect.z = g_player[p].ps->pos.z+PHEIGHT; - setsprite(g_player[p].ps->i,&vect); P_UpdateScreenPal(g_player[p].ps); @@ -5625,7 +5628,10 @@ ACTOR_STATIC void G_MoveEffectors(void) //STATNUM 3 if (s->owner == -1) { - Bsprintf(tempbuf,"Could not find any locators for SE# 6 and 14 with a hitag of %" PRIdPTR ".\n",t[3]); + // debugging subway cars (mapping-wise) is freakin annoying + // let's at least have a helpful message... + Bsprintf(tempbuf,"Could not find any locators in sector %d" + " for SE# 6 or 14 with hitag %d.\n", (int)t[0], (int)t[3]); G_GameExit(tempbuf); } diff --git a/polymer/eduke32/source/astub.c b/polymer/eduke32/source/astub.c index c67e317df..61e86dff5 100644 --- a/polymer/eduke32/source/astub.c +++ b/polymer/eduke32/source/astub.c @@ -191,21 +191,6 @@ static uint8_t wallflag[MAXWALLS>>3]; static uint8_t havebunch[YAX_MAXBUNCHES]; static int32_t *tempzar[YAX_MAXBUNCHES]; -// Check whether bunchnum has exactly one corresponding floor and ceiling -// and return it in this case. If not 1-to-1, return -1. -static int32_t yax_is121(int16_t bunchnum, int16_t getfloor) -{ - int32_t i; - i = headsectbunch[0][bunchnum]; - if (i<0 || nextsectbunch[0][i]>=0) - return -1; - i = headsectbunch[1][bunchnum]; - if (i<0 || nextsectbunch[1][i]>=0) - return -1; - - return headsectbunch[getfloor][bunchnum]; -} - static void silentmessage(const char *fmt, ...); static int32_t yax_invalidop() { @@ -693,15 +678,60 @@ const char *ExtGetVer(void) return s_buildRev; } +static void MultiPskyInit(void) +{ + int32_t i; + + // new-style multi-psky handling + pskymultilist[0] = MOONSKY1; + pskymultilist[1] = BIGORBIT1; + pskymultilist[2] = LA; + for (i=0; i<3; i++) + { + pskymultibits[i] = 3; + Bmemset(pskymultioff[i], 0, sizeof(pskymultioff[i])); + } + + // MOONSKY1 + // earth mountian mountain sun + pskymultioff[0][6]=1; + pskymultioff[0][1]=2; + pskymultioff[0][4]=2; + pskymultioff[0][2]=3; + + // BIGORBIT1 // orbit + // earth1 2 3 moon/sun + pskymultioff[1][5]=1; + pskymultioff[1][6]=2; + pskymultioff[1][7]=3; + pskymultioff[1][2]=4; + + // LA // la city + // earth1 2 3 moon/sun + pskymultioff[2][0]=1; + pskymultioff[2][1]=2; + pskymultioff[2][2]=1; + pskymultioff[2][3]=3; + pskymultioff[2][4]=4; + pskymultioff[2][5]=0; + pskymultioff[2][6]=2; + pskymultioff[2][7]=3; + + pskynummultis = 3; +} + void ExtLoadMap(const char *mapname) { int32_t i; - int32_t sky=0; + int32_t sky=-1; getmessageleng = 0; getmessagetimeoff = 0; Bstrcpy(levelname,mapname); + + // old-fashioned multi-psky handling + for (i=0; i<8; i++) pskyoff[i] = 0; @@ -720,36 +750,24 @@ void ExtLoadMap(const char *mapname) switch (sky) { case MOONSKY1 : - // earth mountian mountain sun - pskyoff[6]=1; - pskyoff[1]=2; - pskyoff[4]=2; - pskyoff[2]=3; + // keep in sync with MultiPskyInit + // -v- + Bmemcpy(pskyoff, pskymultioff[0], sizeof(pskymultioff[0])); break; case BIGORBIT1 : // orbit - // earth1 2 3 moon/sun - pskyoff[5]=1; - pskyoff[6]=2; - pskyoff[7]=3; - pskyoff[2]=4; + Bmemcpy(pskyoff, pskymultioff[1], sizeof(pskymultioff[0])); break; case LA : // la city - // earth1 2 3 moon/sun - pskyoff[0]=1; - pskyoff[1]=2; - pskyoff[2]=1; - pskyoff[3]=3; - pskyoff[4]=4; - pskyoff[5]=0; - pskyoff[6]=2; - pskyoff[7]=3; + Bmemcpy(pskyoff, pskymultioff[2], sizeof(pskymultioff[0])); break; } pskybits=3; parallaxtype=0; + + ////////// Bsprintf(tempbuf, "Mapster32 - %s",mapname); map_undoredo_free(); @@ -6544,13 +6562,12 @@ static void Keys3d(void) mouseay=0; if (AIMING_AT_CEILING_OR_FLOOR) -#ifdef YAX_ENABLE - if (YAXCHK(yax_getbunch(searchsector, AIMING_AT_FLOOR) < 0)) -#endif { changedir = 1-2*(x1<0); x1 = klabs(x1); - +#ifdef YAX_ENABLE + if (yax_getbunch(searchsector, AIMING_AT_FLOOR) < 0) +#endif while (x1--) AIMED_CEILINGFLOOR(xpanning) = changechar(AIMED_CEILINGFLOOR(xpanning),changedir,0,0); @@ -6764,9 +6781,6 @@ static void Keys3d(void) } else if (AIMING_AT_CEILING_OR_FLOOR) { -#ifdef YAX_ENABLE - if (YAXCHK(yax_getbunch(searchsector, AIMING_AT_FLOOR) < 0)) -#endif { while (updownunits--) AIMED_CEILINGFLOOR(ypanning) = changechar(AIMED_CEILINGFLOOR(ypanning), changedir, smooshyalign, 0); @@ -6839,6 +6853,8 @@ static void Keys3d(void) tempxrepeat = AIMED_SEL_WALL(xrepeat); tempxrepeat = max(1, tempxrepeat); tempyrepeat = AIMED_SEL_WALL(yrepeat); + tempxpanning = AIMED_SEL_WALL(xpanning); + tempypanning = AIMED_SEL_WALL(ypanning); tempcstat = AIMED_SEL_WALL(cstat) & ~YAX_NEXTWALLBITS; templenrepquot = getlenbyrep(wallength(searchwall), tempxrepeat); } @@ -6850,7 +6866,7 @@ static void Keys3d(void) tempyrepeat = AIMED_CEILINGFLOOR(ypanning); #ifdef YAX_ENABLE if (yax_getbunch(searchsector, AIMING_AT_FLOOR) >= 0) - tempxrepeat = tempyrepeat = 0; + tempxrepeat = 0; #endif tempcstat = AIMED_CEILINGFLOOR(stat) & ~YAX_BIT; } @@ -6954,8 +6970,12 @@ static void Keys3d(void) { wall[i].xrepeat = tempxrepeat; wall[i].yrepeat = tempyrepeat; - wall[i].cstat &= YAX_NEXTWALLBITS; - wall[i].cstat |= (tempcstat & ~YAX_NEXTWALLBITS); + + wall[i].xpanning = tempxpanning; + wall[i].ypanning = tempypanning; + wall[i].cstat &= ~(4+8+256); + wall[i].cstat |= (tempcstat & (4+8+256)); + fixxrepeat(i, templenrepquot); } @@ -7051,6 +7071,10 @@ static void Keys3d(void) { wall[searchwall].xrepeat = tempxrepeat; wall[searchwall].yrepeat = tempyrepeat; + wall[searchwall].xpanning = tempxpanning; + wall[searchwall].ypanning = tempypanning; + wall[searchwall].cstat &= (4+8+256); + wall[searchwall].cstat |= (tempcstat & (4+8+256)); SET_PROTECT_BITS(wall[searchwall].cstat, tempcstat, YAX_NEXTWALLBITS); @@ -7101,11 +7125,8 @@ paste_ceiling_or_floor: #ifdef YAX_ENABLE if (yax_getbunch(searchsector, AIMING_AT_FLOOR) < 0) #endif - { AIMED_CEILINGFLOOR(xpanning) = tempxrepeat; - AIMED_CEILINGFLOOR(ypanning) = tempyrepeat; - } - + AIMED_CEILINGFLOOR(ypanning) = tempyrepeat; SET_PROTECT_BITS(AIMED_CEILINGFLOOR(stat), tempcstat, YAX_BIT); sector[searchsector].visibility = tempvis; @@ -7228,10 +7249,8 @@ paste_ceiling_or_floor: j = yax_getbunch(searchsector, AIMING_AT_FLOOR); if (j < 0) #endif - { AIMED_CEILINGFLOOR(xpanning) = 0; - AIMED_CEILINGFLOOR(ypanning) = 0; - } + AIMED_CEILINGFLOOR(ypanning) = 0; AIMED_CEILINGFLOOR(stat) &= ~2; AIMED_CEILINGFLOOR(heinum) = 0; #ifdef YAX_ENABLE @@ -7758,13 +7777,15 @@ static void Keys2d(void) { for (i=0; i=printfromlev) + { + OSD_Printf(" will set wall %d's yax-nextwall(%d)=%d's yax-nextwall(%d) to %d on tryfix\n", + j, cf, ynw, !cf, j); + } + } + } + } + } // woot! } } } diff --git a/polymer/eduke32/source/duke3d.h b/polymer/eduke32/source/duke3d.h index 5c2decf70..b65a980b2 100644 --- a/polymer/eduke32/source/duke3d.h +++ b/polymer/eduke32/source/duke3d.h @@ -64,7 +64,13 @@ extern "C" { #define WW2GI (g_gameType & GAME_WW2) // increase by 3, because atomic GRP adds 1, and Shareware adds 2 -#define BYTEVERSION_JF 198 +#ifdef YAX_ENABLE +// we'll have to introduce a BYTEVERSION2 sooner or later anyway...: +# define BYTEVERSION_JF 228 +// keep in sync? v^v +#else +# define BYTEVERSION_JF 198 +#endif #define BYTEVERSION_13 27 #define BYTEVERSION_14 116 #define BYTEVERSION_15 117 diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 5302e226e..36f0e56cd 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -3212,9 +3212,9 @@ void G_SE40(int32_t smoothratio) } } -static int32_t g_yax_smoothratio; +int32_t g_yax_smoothratio; #ifdef YAX_ENABLE -static void G_AnalyzeSprites(void) +void G_AnalyzeSprites(void) { G_DoSpriteAnimations(ud.camera.x,ud.camera.y,ud.cameraang,g_yax_smoothratio); } @@ -3419,11 +3419,22 @@ void G_DrawRooms(int32_t snum, int32_t smoothratio) { getzsofslope(ud.camerasect,ud.camera.x,ud.camera.y,&cz,&fz); #ifdef YAX_ENABLE - if (yax_getbunch(ud.camerasect, YAX_CEILING) < 0) + if (yax_getbunch(ud.camerasect, YAX_CEILING) >= 0) + { + if (ud.camera.z < cz) + updatesectorz(ud.camera.x, ud.camera.y, ud.camera.z, &ud.camerasect); + } + else #endif if (ud.camera.z < cz+(4<<8)) ud.camera.z = cz+(4<<8); + #ifdef YAX_ENABLE - if (yax_getbunch(ud.camerasect, YAX_FLOOR) < 0) + if (yax_getbunch(ud.camerasect, YAX_FLOOR) >= 0) + { + if (ud.camera.z > fz) + updatesectorz(ud.camera.x, ud.camera.y, ud.camera.z, &ud.camerasect); + } + else #endif if (ud.camera.z > fz-(4<<8)) ud.camera.z = fz-(4<<8); } @@ -3456,7 +3467,10 @@ void G_DrawRooms(int32_t snum, int32_t smoothratio) j = visibility; visibility = (j>>1) + (j>>2); + yax_preparedrawrooms(); drawrooms(tposx,tposy,ud.camera.z,tang,ud.camerahoriz,g_mirrorSector[i]+MAXSECTORS); + g_yax_smoothratio = smoothratio; + yax_drawrooms(G_AnalyzeSprites, ud.camerahoriz, g_mirrorSector[i]+MAXSECTORS); display_mirror = 1; G_DoSpriteAnimations(tposx,tposy,tang,smoothratio); @@ -6281,8 +6295,10 @@ PALONLY: if (actor[i].dispicnum >= 0) actor[i].dispicnum = t->picnum; } - else if (display_mirror == 1) - t->cstat |= 4; +// else if (display_mirror == 1) +// t->cstat |= 4; +/* completemirror() already reverses the drawn frame, so the above isn't necessary. + * Even Polymost's and Polymer's mirror seems to function correctly this way. */ skip: if (g_player[screenpeek].ps->inv_amount[GET_HEATS] > 0 && g_player[screenpeek].ps->heat_on && diff --git a/polymer/eduke32/source/game.h b/polymer/eduke32/source/game.h index 26e226a20..5c8a2b72f 100644 --- a/polymer/eduke32/source/game.h +++ b/polymer/eduke32/source/game.h @@ -242,6 +242,8 @@ extern uint8_t *basepaltable[BASEPALCOUNT]; extern user_defs ud; +extern int32_t g_yax_smoothratio; + int32_t A_CheckInventorySprite(spritetype *s); int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int32_t s_pn,int32_t s_s,int32_t s_xr,int32_t s_yr,int32_t s_a,int32_t s_ve,int32_t s_zv,int32_t s_ow,int32_t s_ss); int32_t A_Spawn(int32_t j,int32_t pn); @@ -282,6 +284,9 @@ void G_HandleLocalKeys(void); void G_HandleSpecialKeys(void); void G_PrintGameQuotes(void); void G_SE40(int32_t smoothratio); +#ifdef YAX_ENABLE +void G_AnalyzeSprites(void); +#endif void G_SetCrosshairColor(int32_t r,int32_t g,int32_t b); void G_SetStatusBarScale(int32_t sc); void G_Shutdown(void); diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index ab0f910da..7c96ceb28 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -2335,7 +2335,10 @@ nullquote: j = visibility; visibility = (j>>1) + (j>>2); + yax_preparedrawrooms(); drawrooms(tposx,tposy,z,tang,horiz,g_mirrorSector[i]+MAXSECTORS); + g_yax_smoothratio = smoothratio; + yax_drawrooms(G_AnalyzeSprites, horiz, g_mirrorSector[i]+MAXSECTORS); display_mirror = 1; G_DoSpriteAnimations(tposx,tposy,tang,smoothratio); diff --git a/polymer/eduke32/source/m32structures.c b/polymer/eduke32/source/m32structures.c index 05712e5db..6e6bb9f3d 100644 --- a/polymer/eduke32/source/m32structures.c +++ b/polymer/eduke32/source/m32structures.c @@ -72,7 +72,11 @@ static int32_t __fastcall VM_AccessWall(int32_t how, int32_t lVar1, int32_t lLab case WALL_NEXTWALL: wall[i].nextwall=lValue; break; case WALL_NEXTSECTOR: wall[i].nextsector=lValue; break; case WALL_CSTAT: - wall[i].cstat = lValue&0x03ff; + wall[i].cstat = lValue & (0x03ff +#ifdef YAX_ENABLE + | (m32_script_expertmode ? YAX_NEXTWALLBITS : 0) +#endif + ); break; case WALL_PICNUM: wall[i].picnum=lValue; break; case WALL_OVERPICNUM: wall[i].overpicnum=lValue; break; diff --git a/polymer/eduke32/source/player.c b/polymer/eduke32/source/player.c index 0bec4772a..f7b84b307 100644 --- a/polymer/eduke32/source/player.c +++ b/polymer/eduke32/source/player.c @@ -5013,6 +5013,9 @@ void P_ProcessInput(int32_t snum) if (j < 0) { if (p->cursectnum >= 0 && sector[p->cursectnum].lotag == 0 && sector[p->cursectnum].hitag == 0) +#ifdef YAX_ENABLE + if (yax_getbunch(p->cursectnum, YAX_FLOOR) < 0 || (sector[p->cursectnum].floorstat&512)) +#endif { switch (krand()&3) { @@ -5353,7 +5356,6 @@ HORIZONLY: p->pos.x += p->vel.x>>14; p->pos.y += p->vel.y>>14; #ifdef YAX_ENABLE - // TODO: only if ceiling/floor bunchnum >= 0 updatesectorz(p->pos.x,p->pos.y,p->pos.z,&p->cursectnum); #else updatesector(p->pos.x,p->pos.y,&p->cursectnum); @@ -5363,7 +5365,17 @@ HORIZONLY: else { #ifdef YAX_ENABLE - updatesectorz(p->pos.x,p->pos.y,p->pos.z,&p->cursectnum); + // this updatesectorz conflicts with Duke3d's way of teleporting through water, + // so make it a bit conditional... OTOH, this way we have an ugly z jump when + // changing from above water to underwater + if (p->cursectnum < 0 || !(sector[p->cursectnum].lotag==1 && p->on_ground && yax_getbunch(p->cursectnum, YAX_FLOOR)>=0)) + { + // Do updatesectorz only if ceiling/floor bunchnum is >= 0. Otherwise, unwanted + // side-effects like dying when jumping into a lotag==1 sector can occur. + // The p->jetpack on is there because vel.z 'freezes' when using it + if (p->jetpack_on || (p->vel.z && p->cursectnum>=0 && yax_getbunch(p->cursectnum, (p->vel.z>0))>=0)) + updatesectorz(p->pos.x,p->pos.y,p->pos.z,&p->cursectnum); + } #endif if ((j = clipmove((vec3_t *)p,&p->cursectnum, p->vel.x,p->vel.y,164L,(4L<<8),i,CLIPMASK0))) P_CheckTouchDamage(p, j); diff --git a/polymer/eduke32/source/savegame.c b/polymer/eduke32/source/savegame.c index f4b57739b..903b2ecbb 100644 --- a/polymer/eduke32/source/savegame.c +++ b/polymer/eduke32/source/savegame.c @@ -245,6 +245,19 @@ int32_t G_LoadPlayer(int32_t spot) if (kdfread(&wall[0],sizeof(walltype),MAXWALLS,fil) != MAXWALLS) goto corrupt; if (kdfread(&numsectors,sizeof(numsectors),1,fil) != 1) goto corrupt; if (kdfread(§or[0],sizeof(sectortype),MAXSECTORS,fil) != MAXSECTORS) goto corrupt; + +#ifdef YAX_ENABLE + if (kdfread(&numyaxbunches,sizeof(numyaxbunches),1,fil) != 1) goto corrupt; + if (numyaxbunches > 0) + { + if (kdfread(yax_bunchnum,sizeof(yax_bunchnum[0]),numsectors,fil) != numsectors) goto corrupt; + if (kdfread(yax_nextwall,sizeof(yax_nextwall[0]),numwalls,fil) != numsectors) goto corrupt; + yax_update(2); + } + else + yax_update(1); +#endif + if (kdfread(&sprite[0],sizeof(spritetype),MAXSPRITES,fil) != MAXSPRITES) goto corrupt; if (kdfread(&spriteext[0],sizeof(spriteext_t),MAXSPRITES,fil) != MAXSPRITES) goto corrupt; @@ -678,6 +691,16 @@ int32_t G_SavePlayer(int32_t spot) dfwrite(&wall[0],sizeof(walltype),MAXWALLS,fil); dfwrite(&numsectors,sizeof(numsectors),1,fil); dfwrite(§or[0],sizeof(sectortype),MAXSECTORS,fil); + +#ifdef YAX_ENABLE + dfwrite(&numyaxbunches,sizeof(numyaxbunches),1,fil); + if (numyaxbunches > 0) + { + dfwrite(yax_bunchnum,sizeof(yax_bunchnum[0]),numsectors,fil); + dfwrite(yax_nextwall,sizeof(yax_nextwall[0]),numwalls,fil); + } +#endif + dfwrite(&sprite[0],sizeof(spritetype),MAXSPRITES,fil); #ifdef USE_OPENGL for (i=0; iflags&(DS_NOCHK|DS_STRING|DS_CMP))) continue; - if (sp->flags&(DS_LOADFN|DS_SAVEFN)) + if (sp->flags&(DS_LOADFN|DS_SAVEFN) && (sp->flags&(DS_PROTECTFN))==0) { (*(void ( *)())sp->ptr)(); continue; @@ -1347,6 +1375,9 @@ static void sv_postudload(); static void sv_prespriteextsave(); static void sv_postspriteext(); #endif +#ifdef YAX_ENABLE +static void sv_postyaxload(); +#endif static void sv_calcbitptrsize(); static void sv_prescriptsave_once(); static void sv_prescriptload_once(); @@ -1421,6 +1452,12 @@ static const dataspec_t svgm_secwsp[] = { DS_NOCHK, &numsectors, sizeof(numsectors), 1 }, { DS_DYNAMIC|DS_CNT(numsectors), §or, sizeof(sectortype), (intptr_t)&numsectors }, { DS_DYNAMIC, &sprite, sizeof(spritetype), MAXSPRITES }, +#ifdef YAX_ENABLE + { DS_NOCHK, &numyaxbunches, sizeof(numyaxbunches), 1 }, + { DS_CNT(numsectors), yax_bunchnum, sizeof(yax_bunchnum[0]), (intptr_t)&numsectors }, + { DS_CNT(numwalls), yax_nextwall, sizeof(yax_nextwall[0]), (intptr_t)&numwalls }, + { DS_LOADFN|DS_PROTECTFN, (void *)&sv_postyaxload, 0, 1 }, +#endif { 0, &headspritesect[0], sizeof(headspritesect[0]), MAXSECTORS+1 }, { 0, &prevspritesect[0], sizeof(prevspritesect[0]), MAXSPRITES }, { 0, &nextspritesect[0], sizeof(nextspritesect[0]), MAXSPRITES }, @@ -1842,6 +1879,13 @@ static void sv_postspriteext() } #endif +#ifdef YAX_ENABLE +static void sv_postyaxload() +{ + yax_update(numyaxbunches>0 ? 2 : 1); +} +#endif + static void sv_calcbitptrsize() { savegame_bitptrsize = (g_scriptSize+7)>>3;