-- 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
This commit is contained in:
helixhorned 2011-05-12 23:31:13 +00:00
parent 76be874e7e
commit 98456aefe3
17 changed files with 575 additions and 186 deletions

View file

@ -41,6 +41,7 @@ extern "C" {
#define MAXYDIM 3200 #define MAXYDIM 3200
#define MAXBASEPALS 8 #define MAXBASEPALS 8
#define MAXPALOOKUPS 256 #define MAXPALOOKUPS 256
#define MAXPSKYMULTIS 8
#define MAXPSKYTILES 256 #define MAXPSKYTILES 256
#define MAXSPRITESONSCREEN 4096 #define MAXSPRITESONSCREEN 4096
#define MAXUNIQHUDID 256 //Extra slots so HUD models can store animation state without messing game sprites #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; \ # 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))) 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); int16_t yax_getbunch(int16_t i, int16_t cf);
void yax_getbunches(int16_t i, int16_t *cb, int16_t *fb); 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_setbunch(int16_t i, int16_t cf, int16_t bunchnum);
void yax_setbunches(int16_t i, int16_t cb, int16_t fb); void yax_setbunches(int16_t i, int16_t cb, int16_t fb);
int16_t yax_getnextwall(int16_t wal, int16_t cf); int16_t yax_getnextwall(int16_t wal, int16_t cf);
void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall); 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); 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) 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 int32_t windowx1, windowy1, windowx2, windowy2;
EXTERN int16_t startumost[MAXXDIM], startdmost[MAXXDIM]; EXTERN int16_t startumost[MAXXDIM], startdmost[MAXXDIM];
// original multi-psky handling (only one per map)
EXTERN int16_t pskyoff[MAXPSKYTILES], pskybits; 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 headspritesect[MAXSECTORS+1], headspritestat[MAXSTATUS+1];
EXTERN int16_t prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES]; EXTERN int16_t prevspritesect[MAXSPRITES], prevspritestat[MAXSPRITES];

View file

@ -45,7 +45,7 @@ extern int32_t zmode, kensplayerheight, zlock;
//extern int16_t defaultspritecstat; //extern int16_t defaultspritecstat;
extern int32_t temppicnum, tempcstat, templotag, temphitag, tempextra; 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 int32_t tempshade, tempxvel, tempyvel, tempzvel;
extern char somethingintab; extern char somethingintab;
@ -73,6 +73,10 @@ extern int32_t showambiencesounds;
extern uint8_t graysectbitmap[MAXSECTORS>>3]; extern uint8_t graysectbitmap[MAXSECTORS>>3];
extern uint8_t graywallbitmap[MAXWALLS>>3]; extern uint8_t graywallbitmap[MAXWALLS>>3];
#ifdef YAX_ENABLE
int32_t yax_is121(int16_t bunchnum, int16_t getfloor);
#endif
// editor side view // editor side view
extern int32_t m32_sideview; extern int32_t m32_sideview;
extern int32_t m32_sideelev; extern int32_t m32_sideelev;

View file

@ -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)))) : f = (vis > 239) ? (float)(gvisibility*((vis-240+f)/(klabs(vis-256)))) :
(float)(gvisibility*(vis+16+f)); (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)); Bmemcpy(fogcol, &fogtable[pal<<2], sizeof(fogcol));
} }

View file

@ -109,7 +109,7 @@ int16_t highlightsector[MAXSECTORS], highlightsectorcnt = -1;
extern char textfont[128][8]; extern char textfont[128][8];
int32_t temppicnum, tempcstat, templotag, temphitag, tempextra; 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; int32_t tempshade, tempxvel, tempyvel, tempzvel;
char somethingintab = 255; char somethingintab = 255;
@ -338,6 +338,21 @@ static void M32_drawdebug(void)
#endif #endif
#ifdef YAX_ENABLE #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) static void yax_fixreverselinks(int16_t oldwall, int16_t newwall)
{ {
int32_t cf, ynw; int32_t cf, ynw;
@ -2241,6 +2256,7 @@ void overheadeditor(void)
int32_t prefixarg = 0; int32_t prefixarg = 0;
int32_t resetsynctics = 0, lasttick=getticks(), waitdelay=totalclock, lastdraw=getticks(); int32_t resetsynctics = 0, lasttick=getticks(), waitdelay=totalclock, lastdraw=getticks();
int32_t tsign; int32_t tsign;
int32_t olen[2]={0,0}, nlen[2]={0,0}, dragwall[2] = {-1, -1};
m32_setkeyfilter(1); m32_setkeyfilter(1);
@ -2788,9 +2804,46 @@ void overheadeditor(void)
if (linehighlight >= 0) if (linehighlight >= 0)
{ {
int32_t secti = sectorofwall(linehighlight); int32_t secti = sectorofwall(linehighlight);
#ifdef YAX_ENABLE
int16_t cf, bunchnum, tempsect, tempwall;
for (i=0; i<numwalls; i++)
wall[i].cstat &= ~(1<<14);
for (cf=0; cf<2; cf++)
{
tempsect = secti;
tempwall = linehighlight;
while ((bunchnum = yax_getbunch(tempsect, cf)) >= 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<numsectors; i++)
for (WALLS_OF_SECTOR(i, j))
{
if (wall[j].cstat & (1<<14))
{
setfirstwall(i, j);
k++;
break;
}
}
if (k > 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); setfirstwall(secti, linehighlight);
asksave = 1; 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) 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; goto end_yax;
} }
} }
@ -3565,7 +3618,6 @@ end_yax: ;
goto end_after_dragging; goto end_after_dragging;
j = 1; j = 1;
if (highlightcnt > 0)
for (i=0; i<highlightcnt; i++) for (i=0; i<highlightcnt; i++)
if (pointhighlight == highlight[i]) if (pointhighlight == highlight[i])
{ {
@ -3588,6 +3640,29 @@ end_yax: ;
{ {
dax = wall[pointhighlight].x; dax = wall[pointhighlight].x;
day = wall[pointhighlight].y; day = wall[pointhighlight].y;
for (i=0; i<2; i++)
{
if (dragwall[i] < 0)
break;
nlen[i] = wallength(dragwall[i]);
if (olen[i] != 0 && nlen[i] != 0)
{
int32_t nw = wall[dragwall[i]].nextwall;
j = divscale10(nlen[i], olen[i]);
k = getlenbyrep(olen[i], wall[dragwall[i]].xrepeat);
fixxrepeat(dragwall[i], k);
if (nw >= 0)
{
k = getlenbyrep(olen[i], wall[nw].xrepeat);
fixxrepeat(nw, k);
}
}
}
} }
else if ((pointhighlight&0xc000) == 16384) else if ((pointhighlight&0xc000) == 16384)
{ {
@ -3595,6 +3670,8 @@ end_yax: ;
day = sprite[pointhighlight&16383].y; day = sprite[pointhighlight&16383].y;
} }
dragwall[0] = dragwall[1] = -1;
for (runi=0; runi<3; runi++) for (runi=0; runi<3; runi++)
for (i=numwalls-1; i>=0; i--) //delete points for (i=numwalls-1; i>=0; i--) //delete points
{ {
@ -3720,8 +3797,18 @@ end_after_dragging:
else //if (highlightsectorcnt <= 0) else //if (highlightsectorcnt <= 0)
{ {
if ((bstatus&1) > (oldmousebstatus&1)) if ((bstatus&1) > (oldmousebstatus&1))
{
pointhighlight = getpointhighlight(mousxplc, mousyplc, pointhighlight); 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 (pointhighlight >= 0 && (!m32_sideview || m32_sideelev>=32))
{ {
if (m32_sideview) if (m32_sideview)
@ -4923,6 +5010,7 @@ check_next_sector: ;
for (j=numwalls; j<danumwalls; j++) for (j=numwalls; j<danumwalls; j++)
{ {
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
// if (doSectorSplit || (j!=numwalls && j!=danumwalls-1))
yax_fixreverselinks(j, j); yax_fixreverselinks(j, j);
#endif #endif
if (wall[j].nextwall >= 0) if (wall[j].nextwall >= 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; int32_t n;
//do the x alignment //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]); wall[w1].xpanning = (uint8_t)((wall[w0].xpanning + (wall[w0].xrepeat<<3))%tilesizx[tilenum]);
for (n=picsiz[tilenum]>>4; (1<<n)<tilesizy[tilenum]; n++); for (n=picsiz[tilenum]>>4; (1<<n)<tilesizy[tilenum]; n++);
@ -8209,6 +8296,8 @@ void AlignWallPoint2(int32_t w0)
AlignWalls(w0,GetWallBaseZ(w0), w1,GetWallBaseZ(w1), wall[w0].picnum); AlignWalls(w0,GetWallBaseZ(w0), w1,GetWallBaseZ(w1), wall[w0].picnum);
} }
#define ALIGN_WALLS_CSTAT_MASK (4+8+256)
// flags: // flags:
// 1: recurse nextwalls // 1: recurse nextwalls
// 2: iterate point2's // 2: iterate point2's
@ -8216,7 +8305,7 @@ void AlignWallPoint2(int32_t w0)
int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs) int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs)
{ {
int32_t z0, z1, tilenum, w1, visible, nextsec, sectnum; int32_t z0, z1, tilenum, w1, visible, nextsec, sectnum;
static int32_t numaligned, wall0; static int32_t numaligned, wall0, cstat0;
static uint32_t lenrepquot; static uint32_t lenrepquot;
tilenum = wall[w0].picnum; tilenum = wall[w0].picnum;
@ -8229,6 +8318,7 @@ int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs)
numaligned = 0; numaligned = 0;
lenrepquot = getlenbyrep(wallength(w0), wall[w0].xrepeat); lenrepquot = getlenbyrep(wallength(w0), wall[w0].xrepeat);
wall0 = w0; wall0 = w0;
cstat0 = wall[w0].cstat & ALIGN_WALLS_CSTAT_MASK; // top/bottom orientation; x/y-flip
} }
z0 = GetWallBaseZ(w0); z0 = GetWallBaseZ(w0);
@ -8274,6 +8364,8 @@ int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs)
if ((flags&4) && w0!=wall0) if ((flags&4) && w0!=wall0)
fixxrepeat(w0, lenrepquot); fixxrepeat(w0, lenrepquot);
AlignWalls(w0,z0, w1,z1, tilenum); AlignWalls(w0,z0, w1,z1, tilenum);
wall[w1].cstat &= ~ALIGN_WALLS_CSTAT_MASK;
wall[w1].cstat |= cstat0;
numaligned++; numaligned++;
//if wall was 1-sided, no need to recurse //if wall was 1-sided, no need to recurse

View file

@ -548,7 +548,7 @@ static int32_t defsparser(scriptfile *script)
// initprintf("got bpl %d xsiz %d ysiz %d\n",bpl,xsiz,ysiz); // initprintf("got bpl %d xsiz %d ysiz %d\n",bpl,xsiz,ysiz);
ftd = Bmalloc(xsiz*ysiz); ftd = Bmalloc(xsiz*ysiz);
faketiledata[tile] = Bmalloc(xsiz*ysiz); faketiledata[tile] = Bmalloc(xsiz*ysiz + 400);
for (i=xsiz-1; i>=0; i--) for (i=xsiz-1; i>=0; i--)
{ {
@ -600,7 +600,7 @@ static int32_t defsparser(scriptfile *script)
// initprintf("got bpl %d xsiz %d ysiz %d\n",bpl,xsiz,ysiz); // initprintf("got bpl %d xsiz %d ysiz %d\n",bpl,xsiz,ysiz);
ftd = Bmalloc(xsiz*ysiz); ftd = Bmalloc(xsiz*ysiz);
faketiledata[tile] = Bmalloc(xsiz*ysiz); faketiledata[tile] = Bmalloc(xsiz*ysiz + 400);
for (i=xsiz-1; i>=0; i--) for (i=xsiz-1; i>=0; i--)
{ {

View file

@ -188,10 +188,10 @@ int16_t editstatus = 0;
////////// YAX ////////// ////////// YAX //////////
#if YAX_M32_DEBUG #ifdef YAX_DEBUG
extern char m32_debugstr[64][128]; extern char m32_debugstr[64][128];
extern int32_t m32_numdebuglines; 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 #else
# define yaxdebug(fmt, ...) # define yaxdebug(fmt, ...)
#endif #endif
@ -242,6 +242,7 @@ static int32_t scansector_retfast = 0;
static int32_t scansector_collectsprites = 1; static int32_t scansector_collectsprites = 1;
static int32_t yax_globalcf = -1; static int32_t yax_globalcf = -1;
static int32_t yax_globallev = YAX_MAXDRAWS; static int32_t yax_globallev = YAX_MAXDRAWS;
//static int32_t yax_globalbunch = -1;
// duplicated tsprites // duplicated tsprites
// [i]: // [i]:
@ -252,8 +253,8 @@ static int16_t yax_spritesortcnt[1 + 2*YAX_MAXDRAWS];
static int16_t yax_tsprite[1 + 2*YAX_MAXDRAWS][MAXSPRITESONSCREEN]; static int16_t yax_tsprite[1 + 2*YAX_MAXDRAWS][MAXSPRITESONSCREEN];
// game-time YAX data structures // game-time YAX data structures
static int16_t yax_bunchnum[MAXSECTORS][2]; int16_t yax_bunchnum[MAXSECTORS][2];
static int16_t yax_nextwall[MAXWALLS][2]; int16_t yax_nextwall[MAXWALLS][2];
static int32_t yax_islockededge(/*int16_t sec,*/ int16_t line, int16_t cf) static int32_t yax_islockededge(/*int16_t sec,*/ int16_t line, int16_t cf)
#if 1 #if 1
@ -364,7 +365,10 @@ void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall)
} }
//// in-struct --> array transfer; list construction //// 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 // TODO: always make bunchnums consecutive
int32_t i, j, oeditstatus=editstatus; int32_t i, j, oeditstatus=editstatus;
@ -374,27 +378,33 @@ void yax_update(int32_t onlyreset)
for (i=0; i<MAXSECTORS; i++) for (i=0; i<MAXSECTORS; i++)
{ {
if (resetstat != 2 || i>=numsectors)
yax_bunchnum[i][0] = yax_bunchnum[i][1] = -1; yax_bunchnum[i][0] = yax_bunchnum[i][1] = -1;
nextsectbunch[0][i] = nextsectbunch[1][i] = -1; nextsectbunch[0][i] = nextsectbunch[1][i] = -1;
} }
for (i=0; i<YAX_MAXBUNCHES; i++) for (i=0; i<YAX_MAXBUNCHES; i++)
headsectbunch[0][i] = headsectbunch[1][i] = -1; headsectbunch[0][i] = headsectbunch[1][i] = -1;
for (i=0; i<MAXWALLS; i++) for (i=0; i<MAXWALLS; i++)
if (resetstat != 2 || i>=numwalls)
yax_nextwall[i][0] = yax_nextwall[i][1] = -1; yax_nextwall[i][0] = yax_nextwall[i][1] = -1;
if (onlyreset) if (resetstat==1)
return; return;
// constuct singly linked list of sectors-of-bunch // 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--) for (i=numsectors-1; i>=0; i--)
{ {
yax_getbunches(i, &cb, &fb); yax_getbunches(i, &cb, &fb);
if (resetstat==0)
{
yax_bunchnum[i][0] = cb; yax_bunchnum[i][0] = cb;
yax_bunchnum[i][1] = fb; yax_bunchnum[i][1] = fb;
}
if (cb >= 0) if (cb >= 0)
{ {
if (resetstat==0)
for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++) for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++)
{ {
if (yax_islockededge(j,YAX_CEILING)) if (yax_islockededge(j,YAX_CEILING))
@ -406,6 +416,7 @@ void yax_update(int32_t onlyreset)
headsectbunch[0][cb] = i; headsectbunch[0][cb] = i;
// not duplicated in floors, since every extended ceiling // not duplicated in floors, since every extended ceiling
// must have a corresponding floor: // must have a corresponding floor:
if (resetstat==0)
numyaxbunches++; numyaxbunches++;
} }
else else
@ -418,6 +429,7 @@ void yax_update(int32_t onlyreset)
if (fb >= 0) if (fb >= 0)
{ {
if (resetstat==0)
for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++) for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++)
{ {
if (yax_islockededge(j,YAX_FLOOR)) if (yax_islockededge(j,YAX_FLOOR))
@ -456,31 +468,35 @@ int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf, i
return -1; return -1;
} }
// >0 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) static int yax_cmpbunches(const int16_t *b1, const int16_t *b2)
{ {
int32_t s1,s2, w1,w2; 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]; s1 = headsectbunch[yax_globalcf][*b1];
s2 = headsectbunch[yax_globalcf][*b2]; s2 = headsectbunch[yax_globalcf][*b2];
w1 = sector[s1].wallptr; w1 = sector[s1].wallptr;
w2 = sector[s2].wallptr; w2 = sector[s2].wallptr;
#if 1
return (yax_walldist(w2) - yax_walldist(w1));
#else
{
int64_t dx1,dy1, dx2,dy2, r;
dx1 = wall[w1].x-globalposx; dy1 = wall[w1].y-globalposy; dx1 = wall[w1].x-globalposx; dy1 = wall[w1].y-globalposy;
dx2 = wall[w2].x-globalposx; dy2 = wall[w2].y-globalposy; dx2 = wall[w2].x-globalposx; dy2 = wall[w2].y-globalposy;
#if 1
r = klabs(dx2+dy2) - klabs(dx1+dy1);
return r;
#else
r = (dx2*dx2 + dy2*dy2) - (dx1*dx1 + dy1*dy1); r = (dx2*dx2 + dy2*dy2) - (dx1*dx1 + dy1*dy1);
if (r > 0) if (r > 0)
return 1; return 1;
return r>>63; return r>>63;
}
#endif #endif
} }
@ -491,27 +507,55 @@ static int32_t yax_getbestsector(int32_t bunchnum, int32_t cf, const int16_t *ou
if (bunchnum==ourbunch[cf]) if (bunchnum==ourbunch[cf])
{ {
k = yax_getneighborsect(globalposx, globalposy, sectnum, cf, NULL); k = yax_getneighborsect(globalposx, globalposy, sectnum, cf, NULL);
if (k < 0) if (k >= 0)
k = headsectbunch[!cf][bunchnum];
return k; 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_retfast = 1;
scansector_collectsprites = 0; scansector_collectsprites = 0;
for (k = headsectbunch[!cf][bunchnum]; k != -1; k = nextsectbunch[!cf][k]) for (k = headsectbunch[!cf][bunchnum]; k != -1; k = nextsectbunch[!cf][k])
{
startwall = sector[k].wallptr;
endwall = startwall+sector[k].wallnum;
checkthis = 0;
for (j=startwall; j<endwall; j++)
{
/*
if (wall[j].nextsector == globalcursectnum)
{
scansector_collectsprites = 1;
scansector_retfast = 0;
return k;
}
*/
walldist = yax_walldist(j);
if (walldist < bestwalldist)
{
checkthis = 1;
bestwalldist = walldist;
}
}
if (checkthis)
{ {
numscans = numbunches = 0; numscans = numbunches = 0;
scansector(k); scansector(k);
if (numbunches > 0) if (numbunches > 0)
break; bestsec = k;
}
} }
scansector_collectsprites = 1; scansector_collectsprites = 1;
scansector_retfast = 0; scansector_retfast = 0;
return k; if (bestsec < 0)
bestsec = headsectbunch[!cf][bunchnum];
return bestsec;
} }
} }
@ -538,13 +582,14 @@ 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; int16_t bunchnum;
int32_t i, spritenum, gotthrough, sectnum, cf; int32_t i, spritenum, gotthrough, sectnum, cf;
int32_t sortcnt = yax_spritesortcnt[yax_globallev]; int32_t sortcnt = yax_spritesortcnt[yax_globallev];
const spritetype *spr; const spritetype *spr;
if (resetsortcnt)
spritesortcnt = 0; spritesortcnt = 0;
for (i=0; i<sortcnt; i++) for (i=0; i<sortcnt; i++)
@ -574,6 +619,9 @@ static void yax_copytsprite(int16_t curbunchnum)
continue; continue;
} }
if (spritesortcnt >= MAXSPRITESONSCREEN)
break;
Bmemcpy(&tsprite[spritesortcnt], spr, sizeof(spritetype)); Bmemcpy(&tsprite[spritesortcnt], spr, sizeof(spritetype));
spriteext[spritenum].tspr = &tsprite[spritesortcnt]; spriteext[spritenum].tspr = &tsprite[spritesortcnt];
tsprite[spritesortcnt].owner = spritenum; 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 // original (1st-draw) and accumulated ('per-level') gotsector bitmaps
static uint8_t ogotsector[MAXSECTORS>>3], lgotsector[MAXSECTORS>>3]; static uint8_t ogotsector[MAXSECTORS>>3], lgotsector[MAXSECTORS>>3];
// int32_t t; #ifdef YAX_DEBUG
int32_t t;
#endif
if (rendmode!=0 || numyaxbunches==0) if (rendmode!=0 || numyaxbunches==0)
{ {
@ -648,6 +698,10 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn
j = yax_getbunch(i, cf); j = yax_getbunch(i, cf);
if (j >= 0 && !(havebunch[j>>3]&(1<<(j&7)))) if (j >= 0 && !(havebunch[j>>3]&(1<<(j&7))))
{
if ((SECTORFLD(i,stat, cf)&2) ||
(cf==0 && globalposz > sector[i].ceilingz) ||
(cf==1 && globalposz < sector[i].floorz))
{ {
havebunch[j>>3] |= (1<<(j&7)); havebunch[j>>3] |= (1<<(j&7));
bunches[cf][bnchnum[cf]++] = j; bunches[cf][bnchnum[cf]++] = j;
@ -655,6 +709,7 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn
numhere++; numhere++;
} }
} }
}
if (numhere > 0) if (numhere > 0)
{ {
@ -668,22 +723,20 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn
for (bnchcnt=bbeg; bnchcnt < bbeg+numhere; bnchcnt++) for (bnchcnt=bbeg; bnchcnt < bbeg+numhere; bnchcnt++)
{ {
j = bunches[cf][bnchcnt]; // the actual bunchnum... j = bunches[cf][bnchcnt]; // the actual bunchnum...
// yax_globalbunch = j;
// t=getticks(); #ifdef YAX_DEBUG
t=getticks();
#endif
k = yax_getbestsector(j, cf, ourbunch, sectnum); k = yax_getbestsector(j, cf, ourbunch, sectnum);
bestsec[cf][bnchcnt] = k; bestsec[cf][bnchcnt] = k;
if (k < 0) 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; continue;
} }
if (ourbunch[cf]==j)
{
ourbunch[cf] = yax_getbunch(k, cf);
sectnum = k;
}
if (lev != YAX_MAXDRAWS-1) if (lev != YAX_MAXDRAWS-1)
{ {
// +MAXSECTORS: force // +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++) for (i=0; i<(numsectors+7)>>3; i++)
lgotsector[i] |= gotsector[i]; lgotsector[i] |= gotsector[i];
// yaxdebug("cf %d, lev %d: fake-drawn sec %d (bunch %d), %d dspr, %2d ms", yaxdebug("%s, l %d: faked sec %3d (bunch %2d),%3d dspr, ob=[%2d,%2d], sn=%3d,%3d ms",
// cf, lev, k, j, yax_spritesortcnt[yax_globallev], getticks()-t); 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; g_nodraw = 0;
scansector_collectsprites = 0; scansector_collectsprites = 0;
#if 0 #ifdef ENGINE_CLEAR_SCREEN
begindrawing(); begindrawing();
for (i=0; i<xdim*ydim; i++) for (i=0; i<xdim*ydim; i++)
*((char *)frameplace + i) = i; *((char *)frameplace + i) = i;
@ -728,23 +788,26 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn
for (lev=maxlev[cf]; lev>=0; lev--) for (lev=maxlev[cf]; lev>=0; lev--)
{ {
yax_globallev = YAX_MAXDRAWS + (-1 + 2*cf)*(lev+1); yax_globallev = YAX_MAXDRAWS + (-1 + 2*cf)*(lev+1);
scansector_collectsprites = (lev == YAX_MAXDRAWS-1);
for (bnchcnt=bnchbeg[lev][cf]; bnchcnt<bnchend[lev][cf]; bnchcnt++) for (bnchcnt=bnchbeg[lev][cf]; bnchcnt<bnchend[lev][cf]; bnchcnt++)
{ {
j = bunches[cf][bnchcnt]; // the actual bunchnum... j = bunches[cf][bnchcnt]; // the actual bunchnum...
k = bestsec[cf][bnchcnt]; // best start-drawing sector k = bestsec[cf][bnchcnt]; // best start-drawing sector
// yax_globalbunch = j;
// t=getticks(); #ifdef YAX_DEBUG
t=getticks();
#endif
yax_tweakpicnums(j, cf, 0); yax_tweakpicnums(j, cf, 0);
if (k < 0) if (k < 0)
continue; continue;
drawrooms(globalposx,globalposy,globalposz,globalang,horiz,k+MAXSECTORS); // +MAXSECTORS: force drawrooms(globalposx,globalposy,globalposz,globalang,horiz,k+MAXSECTORS); // +MAXSECTORS: force
yax_copytsprite(j); yax_copytsprite(j, !scansector_collectsprites);
// yaxdebug("cf %d, lev %d: DRAWN sec %d (bunch %d), %d tspr, %2d ms", yaxdebug("%s, l %d: DRAWN sec %3d (bunch %2d),%3d tspr,%3d ms",
// cf, lev, k, j, spritesortcnt, getticks()-t); cf?"v":"^", lev, k, j, spritesortcnt, getticks()-t);
ExtAnalyzeSprites(); ExtAnalyzeSprites();
drawmasks(); drawmasks();
@ -756,22 +819,23 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn
} }
} }
// t=getticks(); #ifdef YAX_DEBUG
t=getticks();
#endif
yax_globallev = YAX_MAXDRAWS; yax_globallev = YAX_MAXDRAWS;
scansector_collectsprites = 0;
// draw base level // draw base level
drawrooms(globalposx,globalposy,globalposz,globalang,horiz,osectnum); drawrooms(globalposx,globalposy,globalposz,globalang,horiz,osectnum);
yaxdebug("DRAWN base level sec %d, %2d ms", osectnum, getticks()-t);
yax_copytsprite(-1); yax_copytsprite(-1, scansector_collectsprites);
scansector_collectsprites = 1; scansector_collectsprites = 1;
for (cf=0; cf<2; cf++) for (cf=0; cf<2; cf++)
if (maxlev[cf] >= 0) if (maxlev[cf] >= 0)
for (bnchcnt=bnchbeg[0][cf]; bnchcnt<bnchend[0][cf]; bnchcnt++) for (bnchcnt=bnchbeg[0][cf]; bnchcnt<bnchend[0][cf]; bnchcnt++)
yax_tweakpicnums(bunches[cf][bnchcnt], cf, 1); // restore picnums yax_tweakpicnums(bunches[cf][bnchcnt], cf, 1); // restore picnums
// yaxdebug("DRAWN base level sec %d, %2d ms", osectnum, getticks()-t);
#ifdef ENGINE_SCREENSHOT_DEBUG #ifdef ENGINE_SCREENSHOT_DEBUG
engine_screenshot = 0; engine_screenshot = 0;
@ -3710,6 +3774,10 @@ static void parascan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat, i
int32_t j, k, l, m, n, x, z, wallnum, nextsectnum, globalhorizbak; int32_t j, k, l, m, n, x, z, wallnum, nextsectnum, globalhorizbak;
int16_t *topptr, *botptr; int16_t *topptr, *botptr;
int16_t dapskybits;
static const int16_t zeropskyoff[MAXPSKYTILES];
const int16_t *dapskyoff;
UNREFERENCED_PARAMETER(dax1); UNREFERENCED_PARAMETER(dax1);
UNREFERENCED_PARAMETER(dax2); UNREFERENCED_PARAMETER(dax2);
@ -3752,7 +3820,20 @@ static void parascan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat, i
globalyscale = (8<<(globalshiftval-19)); globalyscale = (8<<(globalshiftval-19));
//if (globalorientation&256) globalyscale = -globalyscale, globalzd = -globalzd; //if (globalorientation&256) globalyscale = -globalyscale, globalzd = -globalzd;
k = 11 - (picsiz[globalpicnum]&15) - pskybits; dapskyoff = zeropskyoff;
dapskybits = pskybits;
for (j=0; j<pskynummultis; j++)
{
if (globalpicnum == pskymultilist[j])
{
dapskybits = pskymultibits[j];
dapskyoff = pskymultioff[j];
break;
}
}
k = 11 - (picsiz[globalpicnum]&15) - dapskybits;
x = -1; x = -1;
for (z=bunchfirst[bunch]; z>=0; z=p2[z]) for (z=bunchfirst[bunch]; z>=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) else if (x >= 0)
{ {
l = globalpicnum; m = (picsiz[globalpicnum]&15); 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) if (((lplc[x]^lplc[xb1[z]-1])>>m) == 0)
wallscan(x,xb1[z]-1,topptr,botptr,swplc,lplc); 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; j = x;
while (x < xb1[z]) while (x < xb1[z])
{ {
n = l+pskyoff[lplc[x]>>m]; n = l + dapskyoff[lplc[x]>>m];
if (n != globalpicnum) if (n != globalpicnum)
{ {
wallscan(j,x-1,topptr,botptr,swplc,lplc); 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) if (x >= 0)
{ {
l = globalpicnum; m = (picsiz[globalpicnum]&15); 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) if (((lplc[x]^lplc[xb2[bunchlast[bunch]]])>>m) == 0)
wallscan(x,xb2[bunchlast[bunch]],topptr,botptr,swplc,lplc); 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; j = x;
while (x <= xb2[bunchlast[bunch]]) while (x <= xb2[bunchlast[bunch]])
{ {
n = l+pskyoff[lplc[x]>>m]; n = l + dapskyoff[lplc[x]>>m];
if (n != globalpicnum) if (n != globalpicnum)
{ {
wallscan(j,x-1,topptr,botptr,swplc,lplc); 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 ((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++) for (x=x1; x<=x2; x++)
if (dplc[x] < dmost[x]) if (dplc[x] < dmost[x])
if (umost[x] <= dmost[x]) if (umost[x] <= dmost[x])
@ -4236,13 +4322,41 @@ static void drawalls(int32_t bunch)
} }
#ifdef ENGINE_SCREENSHOT_DEBUG #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 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<xdim; x++)
{
if (umost[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); Bsprintf(fn, "engshot%04d.png", engine_screenshot);
screencapture(fn, 0, "BUILD engine"); screencapture(fn, 0, "BUILD engine");
engine_screenshot++; engine_screenshot++;
Bmemcpy((char *)frameplace, bakframe, xdim*ydim);
enddrawing(); //}}}
} }
#endif #endif
} }
@ -7102,6 +7216,7 @@ int32_t initengine(void)
xyaspect = -1; xyaspect = -1;
pskyoff[0] = 0; pskybits = 0; pskyoff[0] = 0; pskybits = 0;
pskynummultis = 0;
parallaxtype = 2; parallaxyoffs = 0L; parallaxyscale = 65536; parallaxtype = 2; parallaxyoffs = 0L; parallaxyscale = 65536;
showinvisibility = 0; showinvisibility = 0;
@ -7261,7 +7376,7 @@ void drawrooms(int32_t daposx, int32_t daposy, int32_t daposz,
i = mulscale16(xdimenscale,viewingrangerecip); i = mulscale16(xdimenscale,viewingrangerecip);
globalpisibility = mulscale16(parallaxvisibility,i); globalpisibility = mulscale16(parallaxvisibility,i);
globalvisibility = mulscale16(visibility,i); globalvisibility = rendmode==0 ? mulscale16(visibility,i) : scale(visibility<<2,4,3);
globalhisibility = mulscale16(globalvisibility,xyaspect); globalhisibility = mulscale16(globalvisibility,xyaspect);
globalcisibility = mulscale8(globalhisibility,320); globalcisibility = mulscale8(globalhisibility,320);
@ -7313,6 +7428,15 @@ void drawrooms(int32_t daposx, int32_t daposy, int32_t daposz,
begindrawing(); //{{{ begindrawing(); //{{{
#ifdef ENGINE_CLEAR_SCREEN
#ifdef YAX_ENABLE
if (!g_nodraw)
#endif
if (numyaxbunches==0)
for (i=0; i<xdim*ydim; i++)
*((char *)frameplace + i) = i;
#endif
//frameoffset = frameplace + viewoffset; //frameoffset = frameplace + viewoffset;
frameoffset = frameplace + windowy1*bytesperline + windowx1; frameoffset = frameplace + windowy1*bytesperline + windowx1;
@ -10103,7 +10227,7 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
intptr_t tmp[3], *tmpptr=NULL; intptr_t tmp[3], *tmpptr=NULL;
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
vec3_t newsv; vec3_t newsv;
int32_t oldhitsect = -1; int32_t oldhitsect = -1, oldhitsect2 = -2;
#endif #endif
hitinfo->hitsect = -1; hitinfo->hitwall = -1; hitinfo->hitsprite = -1; hitinfo->hitsect = -1; hitinfo->hitwall = -1; hitinfo->hitsprite = -1;
if (sectnum < 0) return(-1); if (sectnum < 0) return(-1);
@ -10385,7 +10509,8 @@ restart_grand:
if (numyaxbunches == 0 || editstatus) if (numyaxbunches == 0 || editstatus)
return 0; 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) if (hitinfo->hitsect == -1 && oldhitsect >= 0)
{ {
@ -10409,6 +10534,7 @@ restart_grand:
sectnum = i; sectnum = i;
sv = &newsv; sv = &newsv;
oldhitsect2 = oldhitsect;
oldhitsect = hitinfo->hitsect; oldhitsect = hitinfo->hitsect;
hitinfo->hitsect = -1; hitinfo->hitsect = -1;
@ -11679,6 +11805,10 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
dawalclipmask = (cliptype&65535); dawalclipmask = (cliptype&65535);
dasprclipmask = (cliptype>>16); dasprclipmask = (cliptype>>16);
#ifdef YAX_ENABLE
origclipsectorlist[0] = sectnum;
origclipsectnum = 1;
#endif
clipsectorlist[0] = sectnum; clipsectorlist[0] = sectnum;
clipsectcnt = 0; clipsectnum = 1; clipsectcnt = 0; clipsectnum = 1;
clipspritecnt = clipspritenum = 0; clipspritecnt = clipspritenum = 0;
@ -11792,7 +11922,10 @@ restart_grand:
if (dx > 0) dax += dx*MAXCLIPDIST; else dax -= dx*MAXCLIPDIST; if (dx > 0) dax += dx*MAXCLIPDIST; else dax -= dx*MAXCLIPDIST;
if (dy > 0) day -= dy*MAXCLIPDIST; else day += dy*MAXCLIPDIST; if (dy > 0) day -= dy*MAXCLIPDIST; else day += dy*MAXCLIPDIST;
if (dax >= day) continue; 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!!! //It actually got here, through all the continue's!!!
getzsofslope(k, pos->x,pos->y, &daz,&daz2); getzsofslope(k, pos->x,pos->y, &daz,&daz2);
if (curspr) if (curspr)
@ -11963,12 +12096,6 @@ restart_grand:
int16_t cb, fb, didchange; int16_t cb, fb, didchange;
yax_getbunches(sectnum, &cb, &fb); yax_getbunches(sectnum, &cb, &fb);
if (mcf==-1)
{
Bmemcpy(origclipsectorlist, clipsectorlist, clipsectnum*sizeof(clipsectorlist[0]));
origclipsectnum = clipsectnum;
}
mcf++; mcf++;
clipsectcnt = 0; clipsectnum = 0; clipsectcnt = 0; clipsectnum = 0;

View file

@ -8,8 +8,12 @@
#define MAXNODESPERLINE 42 //Warning: This depends on MAXYSAVES & MAXYDIM! #define MAXNODESPERLINE 42 //Warning: This depends on MAXYSAVES & MAXYDIM!
#define MAXCLIPDIST 1024 #define MAXCLIPDIST 1024
// uncomment to clear the screen before each top-level draw
// (classic only)
// #define ENGINE_CLEAR_SCREEN
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
# define YAX_MAXDRAWS 4 # define YAX_MAXDRAWS 8
#endif #endif
extern uint8_t **basepaltableptr; extern uint8_t **basepaltableptr;

View file

@ -1486,7 +1486,7 @@ void writexcache(char *fn, int32_t len, int32_t dameth, char effect, texcachehea
if (!picc) goto failure; else pic = picc; if (!picc) goto failure; else pic = picc;
alloclen = miplen; alloclen = miplen;
picc = Brealloc(packbuf, alloclen+16); picc = Brealloc(packbuf, alloclen+400);
if (!picc) goto failure; else packbuf = picc; if (!picc) goto failure; else packbuf = picc;
picc = Brealloc(midbuf, miplen); picc = Brealloc(midbuf, miplen);

View file

@ -412,9 +412,13 @@ int32_t A_MoveSprite(int32_t spritenum, const vec3_t *change, uint32_t cliptype)
{ {
spr->z = daz; spr->z = daz;
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if (change->z && yax_getbunch(spr->sectnum, !!change->z)>=0) if (change->z && yax_getbunch(spr->sectnum, (change->z>0))>=0)
if ((SECTORFLD(spr->sectnum,stat, !!change->z)&yax_waltosecmask(cliptype))==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); setspritez(spritenum, (vec3_t *)spr);
}
#endif #endif
} }
else if (retval == 0) retval = 16384+dasectnum; 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.x = g_player[p].ps->pos.x;
vect.y = g_player[p].ps->pos.y; vect.y = g_player[p].ps->pos.y;
vect.z = g_player[p].ps->pos.z+PHEIGHT; vect.z = g_player[p].ps->pos.z+PHEIGHT;
setsprite(g_player[p].ps->i,&vect); setsprite(g_player[p].ps->i,&vect);
P_UpdateScreenPal(g_player[p].ps); P_UpdateScreenPal(g_player[p].ps);
@ -5625,7 +5628,10 @@ ACTOR_STATIC void G_MoveEffectors(void) //STATNUM 3
if (s->owner == -1) 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); G_GameExit(tempbuf);
} }

View file

@ -191,21 +191,6 @@ static uint8_t wallflag[MAXWALLS>>3];
static uint8_t havebunch[YAX_MAXBUNCHES]; static uint8_t havebunch[YAX_MAXBUNCHES];
static int32_t *tempzar[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 void silentmessage(const char *fmt, ...);
static int32_t yax_invalidop() static int32_t yax_invalidop()
{ {
@ -693,15 +678,60 @@ const char *ExtGetVer(void)
return s_buildRev; 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) void ExtLoadMap(const char *mapname)
{ {
int32_t i; int32_t i;
int32_t sky=0; int32_t sky=-1;
getmessageleng = 0; getmessageleng = 0;
getmessagetimeoff = 0; getmessagetimeoff = 0;
Bstrcpy(levelname,mapname); Bstrcpy(levelname,mapname);
// old-fashioned multi-psky handling
for (i=0; i<8; i++) for (i=0; i<8; i++)
pskyoff[i] = 0; pskyoff[i] = 0;
@ -720,36 +750,24 @@ void ExtLoadMap(const char *mapname)
switch (sky) switch (sky)
{ {
case MOONSKY1 : case MOONSKY1 :
// earth mountian mountain sun // keep in sync with MultiPskyInit
pskyoff[6]=1; // -v-
pskyoff[1]=2; Bmemcpy(pskyoff, pskymultioff[0], sizeof(pskymultioff[0]));
pskyoff[4]=2;
pskyoff[2]=3;
break; break;
case BIGORBIT1 : // orbit case BIGORBIT1 : // orbit
// earth1 2 3 moon/sun Bmemcpy(pskyoff, pskymultioff[1], sizeof(pskymultioff[0]));
pskyoff[5]=1;
pskyoff[6]=2;
pskyoff[7]=3;
pskyoff[2]=4;
break; break;
case LA : // la city case LA : // la city
// earth1 2 3 moon/sun Bmemcpy(pskyoff, pskymultioff[2], sizeof(pskymultioff[0]));
pskyoff[0]=1;
pskyoff[1]=2;
pskyoff[2]=1;
pskyoff[3]=3;
pskyoff[4]=4;
pskyoff[5]=0;
pskyoff[6]=2;
pskyoff[7]=3;
break; break;
} }
pskybits=3; pskybits=3;
parallaxtype=0; parallaxtype=0;
//////////
Bsprintf(tempbuf, "Mapster32 - %s",mapname); Bsprintf(tempbuf, "Mapster32 - %s",mapname);
map_undoredo_free(); map_undoredo_free();
@ -6544,13 +6562,12 @@ static void Keys3d(void)
mouseay=0; mouseay=0;
if (AIMING_AT_CEILING_OR_FLOOR) if (AIMING_AT_CEILING_OR_FLOOR)
#ifdef YAX_ENABLE
if (YAXCHK(yax_getbunch(searchsector, AIMING_AT_FLOOR) < 0))
#endif
{ {
changedir = 1-2*(x1<0); changedir = 1-2*(x1<0);
x1 = klabs(x1); x1 = klabs(x1);
#ifdef YAX_ENABLE
if (yax_getbunch(searchsector, AIMING_AT_FLOOR) < 0)
#endif
while (x1--) while (x1--)
AIMED_CEILINGFLOOR(xpanning) = changechar(AIMED_CEILINGFLOOR(xpanning),changedir,0,0); 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) else if (AIMING_AT_CEILING_OR_FLOOR)
{ {
#ifdef YAX_ENABLE
if (YAXCHK(yax_getbunch(searchsector, AIMING_AT_FLOOR) < 0))
#endif
{ {
while (updownunits--) while (updownunits--)
AIMED_CEILINGFLOOR(ypanning) = changechar(AIMED_CEILINGFLOOR(ypanning), changedir, smooshyalign, 0); AIMED_CEILINGFLOOR(ypanning) = changechar(AIMED_CEILINGFLOOR(ypanning), changedir, smooshyalign, 0);
@ -6839,6 +6853,8 @@ static void Keys3d(void)
tempxrepeat = AIMED_SEL_WALL(xrepeat); tempxrepeat = AIMED_SEL_WALL(xrepeat);
tempxrepeat = max(1, tempxrepeat); tempxrepeat = max(1, tempxrepeat);
tempyrepeat = AIMED_SEL_WALL(yrepeat); tempyrepeat = AIMED_SEL_WALL(yrepeat);
tempxpanning = AIMED_SEL_WALL(xpanning);
tempypanning = AIMED_SEL_WALL(ypanning);
tempcstat = AIMED_SEL_WALL(cstat) & ~YAX_NEXTWALLBITS; tempcstat = AIMED_SEL_WALL(cstat) & ~YAX_NEXTWALLBITS;
templenrepquot = getlenbyrep(wallength(searchwall), tempxrepeat); templenrepquot = getlenbyrep(wallength(searchwall), tempxrepeat);
} }
@ -6850,7 +6866,7 @@ static void Keys3d(void)
tempyrepeat = AIMED_CEILINGFLOOR(ypanning); tempyrepeat = AIMED_CEILINGFLOOR(ypanning);
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if (yax_getbunch(searchsector, AIMING_AT_FLOOR) >= 0) if (yax_getbunch(searchsector, AIMING_AT_FLOOR) >= 0)
tempxrepeat = tempyrepeat = 0; tempxrepeat = 0;
#endif #endif
tempcstat = AIMED_CEILINGFLOOR(stat) & ~YAX_BIT; tempcstat = AIMED_CEILINGFLOOR(stat) & ~YAX_BIT;
} }
@ -6954,8 +6970,12 @@ static void Keys3d(void)
{ {
wall[i].xrepeat = tempxrepeat; wall[i].xrepeat = tempxrepeat;
wall[i].yrepeat = tempyrepeat; 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); fixxrepeat(i, templenrepquot);
} }
@ -7051,6 +7071,10 @@ static void Keys3d(void)
{ {
wall[searchwall].xrepeat = tempxrepeat; wall[searchwall].xrepeat = tempxrepeat;
wall[searchwall].yrepeat = tempyrepeat; 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); SET_PROTECT_BITS(wall[searchwall].cstat, tempcstat, YAX_NEXTWALLBITS);
@ -7101,11 +7125,8 @@ paste_ceiling_or_floor:
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if (yax_getbunch(searchsector, AIMING_AT_FLOOR) < 0) if (yax_getbunch(searchsector, AIMING_AT_FLOOR) < 0)
#endif #endif
{
AIMED_CEILINGFLOOR(xpanning) = tempxrepeat; AIMED_CEILINGFLOOR(xpanning) = tempxrepeat;
AIMED_CEILINGFLOOR(ypanning) = tempyrepeat; AIMED_CEILINGFLOOR(ypanning) = tempyrepeat;
}
SET_PROTECT_BITS(AIMED_CEILINGFLOOR(stat), tempcstat, YAX_BIT); SET_PROTECT_BITS(AIMED_CEILINGFLOOR(stat), tempcstat, YAX_BIT);
sector[searchsector].visibility = tempvis; sector[searchsector].visibility = tempvis;
@ -7228,10 +7249,8 @@ paste_ceiling_or_floor:
j = yax_getbunch(searchsector, AIMING_AT_FLOOR); j = yax_getbunch(searchsector, AIMING_AT_FLOOR);
if (j < 0) if (j < 0)
#endif #endif
{
AIMED_CEILINGFLOOR(xpanning) = 0; AIMED_CEILINGFLOOR(xpanning) = 0;
AIMED_CEILINGFLOOR(ypanning) = 0; AIMED_CEILINGFLOOR(ypanning) = 0;
}
AIMED_CEILINGFLOOR(stat) &= ~2; AIMED_CEILINGFLOOR(stat) &= ~2;
AIMED_CEILINGFLOOR(heinum) = 0; AIMED_CEILINGFLOOR(heinum) = 0;
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
@ -7758,13 +7777,15 @@ static void Keys2d(void)
{ {
for (i=0; i<numsectors; i++) for (i=0; i<numsectors; i++)
if (inside_editor(&pos, searchx,searchy, zoom, mousxplc,mousyplc,i) == 1) if (inside_editor(&pos, searchx,searchy, zoom, mousxplc,mousyplc,i) == 1)
{
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if (yax_getbunch(i, YAX_FLOOR) < 0) if (yax_getbunch(i, YAX_FLOOR) < 0)
#endif #endif
{ sector[i].floorxpanning = 0;
sector[i].floorxpanning = sector[i].floorypanning = 0; sector[i].floorypanning = 0;
message("Sector %d floor panning reset", i); message("Sector %d floor panning reset", i);
asksave = 1; asksave = 1;
break;
} }
} }
} }
@ -7795,7 +7816,7 @@ static void Keys2d(void)
{ {
for (i=0; i<numsectors; i++) for (i=0; i<numsectors; i++)
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if (yax_getbunch(i, YAX_FLOOR) < 0) if (k==1 || yax_getbunch(i, YAX_FLOOR) < 0)
#endif #endif
if (inside_editor(&pos, searchx,searchy, zoom, mousxplc,mousyplc,i) == 1) if (inside_editor(&pos, searchx,searchy, zoom, mousxplc,mousyplc,i) == 1)
{ {
@ -8395,6 +8416,12 @@ static void G_CheckCommandLine(int32_t argc, const char **argv)
i++; i++;
continue; continue;
} }
if (!Bstrcasecmp(c+1,"-nm") || Bstrcasecmp(c+1,"-ns"))
{
COPYARG(i);
i++;
continue;
}
if (!Bstrcasecmp(c+1,"ww2gi")) if (!Bstrcasecmp(c+1,"ww2gi"))
{ {
Bstrcpy(g_grpNamePtr, "ww2gi.grp"); Bstrcpy(g_grpNamePtr, "ww2gi.grp");
@ -10164,6 +10191,8 @@ int32_t ExtInit(void)
ReadHelpFile("m32help.hlp"); ReadHelpFile("m32help.hlp");
MultiPskyInit();
signal(SIGINT, m32script_interrupt_handler); signal(SIGINT, m32script_interrupt_handler);
return rv; return rv;
@ -11098,7 +11127,31 @@ int32_t CheckMapCorruption(int32_t printfromlev, uint64_t tryfixing)
if (wall[jp2].x != wall[ynwp2].x || wall[jp2].y != wall[ynwp2].y) if (wall[jp2].x != wall[ynwp2].x || wall[jp2].y != wall[ynwp2].y)
CORRUPTCHK_PRINT(4, CORRUPT_WALL|j, "WALL %d's and its YAX-NEXTWALL(%d)=%d's p2-coordinates not equal", CORRUPTCHK_PRINT(4, CORRUPT_WALL|j, "WALL %d's and its YAX-NEXTWALL(%d)=%d's p2-coordinates not equal",
j, cf, ynw); j, cf, ynw);
else
{
int32_t onumct = numcorruptthings;
ynwp2 = yax_getnextwall(ynw, !cf);
if (ynwp2 != j)
{
CORRUPTCHK_PRINT(4, CORRUPT_WALL|j, "WALL %d's YAX-NEXTWALL(%d)=%d's reverse link wrong"
" (expected %d, have %d)", j, cf, ynw, j, ynwp2);
if (onumct < MAXCORRUPTTHINGS)
{
if (tryfixing & (1ull<<onumct))
{
yax_setnextwall(ynw, !cf, j);
OSD_Printf(CCHK_CORRECTED "auto-correction: set wall %d's yax-nextwall(%d)=%d's yax-nextwall(%d) to %d\n",
j, cf, ynw, !cf, j);
} }
else if (4>=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!
} }
} }
} }

View file

@ -64,7 +64,13 @@ extern "C" {
#define WW2GI (g_gameType & GAME_WW2) #define WW2GI (g_gameType & GAME_WW2)
// increase by 3, because atomic GRP adds 1, and Shareware adds 2 // 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_13 27
#define BYTEVERSION_14 116 #define BYTEVERSION_14 116
#define BYTEVERSION_15 117 #define BYTEVERSION_15 117

View file

@ -3212,9 +3212,9 @@ void G_SE40(int32_t smoothratio)
} }
} }
static int32_t g_yax_smoothratio; int32_t g_yax_smoothratio;
#ifdef YAX_ENABLE #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); 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); getzsofslope(ud.camerasect,ud.camera.x,ud.camera.y,&cz,&fz);
#ifdef YAX_ENABLE #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 #endif
if (ud.camera.z < cz+(4<<8)) ud.camera.z = cz+(4<<8); if (ud.camera.z < cz+(4<<8)) ud.camera.z = cz+(4<<8);
#ifdef YAX_ENABLE #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 #endif
if (ud.camera.z > fz-(4<<8)) ud.camera.z = fz-(4<<8); 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; j = visibility;
visibility = (j>>1) + (j>>2); visibility = (j>>1) + (j>>2);
yax_preparedrawrooms();
drawrooms(tposx,tposy,ud.camera.z,tang,ud.camerahoriz,g_mirrorSector[i]+MAXSECTORS); 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; display_mirror = 1;
G_DoSpriteAnimations(tposx,tposy,tang,smoothratio); G_DoSpriteAnimations(tposx,tposy,tang,smoothratio);
@ -6281,8 +6295,10 @@ PALONLY:
if (actor[i].dispicnum >= 0) if (actor[i].dispicnum >= 0)
actor[i].dispicnum = t->picnum; actor[i].dispicnum = t->picnum;
} }
else if (display_mirror == 1) // else if (display_mirror == 1)
t->cstat |= 4; // 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: skip:
if (g_player[screenpeek].ps->inv_amount[GET_HEATS] > 0 && g_player[screenpeek].ps->heat_on && if (g_player[screenpeek].ps->inv_amount[GET_HEATS] > 0 && g_player[screenpeek].ps->heat_on &&

View file

@ -242,6 +242,8 @@ extern uint8_t *basepaltable[BASEPALCOUNT];
extern user_defs ud; extern user_defs ud;
extern int32_t g_yax_smoothratio;
int32_t A_CheckInventorySprite(spritetype *s); 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_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); int32_t A_Spawn(int32_t j,int32_t pn);
@ -282,6 +284,9 @@ void G_HandleLocalKeys(void);
void G_HandleSpecialKeys(void); void G_HandleSpecialKeys(void);
void G_PrintGameQuotes(void); void G_PrintGameQuotes(void);
void G_SE40(int32_t smoothratio); 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_SetCrosshairColor(int32_t r,int32_t g,int32_t b);
void G_SetStatusBarScale(int32_t sc); void G_SetStatusBarScale(int32_t sc);
void G_Shutdown(void); void G_Shutdown(void);

View file

@ -2335,7 +2335,10 @@ nullquote:
j = visibility; j = visibility;
visibility = (j>>1) + (j>>2); visibility = (j>>1) + (j>>2);
yax_preparedrawrooms();
drawrooms(tposx,tposy,z,tang,horiz,g_mirrorSector[i]+MAXSECTORS); 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; display_mirror = 1;
G_DoSpriteAnimations(tposx,tposy,tang,smoothratio); G_DoSpriteAnimations(tposx,tposy,tang,smoothratio);

View file

@ -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_NEXTWALL: wall[i].nextwall=lValue; break;
case WALL_NEXTSECTOR: wall[i].nextsector=lValue; break; case WALL_NEXTSECTOR: wall[i].nextsector=lValue; break;
case WALL_CSTAT: case WALL_CSTAT:
wall[i].cstat = lValue&0x03ff; wall[i].cstat = lValue & (0x03ff
#ifdef YAX_ENABLE
| (m32_script_expertmode ? YAX_NEXTWALLBITS : 0)
#endif
);
break; break;
case WALL_PICNUM: wall[i].picnum=lValue; break; case WALL_PICNUM: wall[i].picnum=lValue; break;
case WALL_OVERPICNUM: wall[i].overpicnum=lValue; break; case WALL_OVERPICNUM: wall[i].overpicnum=lValue; break;

View file

@ -5013,6 +5013,9 @@ void P_ProcessInput(int32_t snum)
if (j < 0) if (j < 0)
{ {
if (p->cursectnum >= 0 && sector[p->cursectnum].lotag == 0 && sector[p->cursectnum].hitag == 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) switch (krand()&3)
{ {
@ -5353,7 +5356,6 @@ HORIZONLY:
p->pos.x += p->vel.x>>14; p->pos.x += p->vel.x>>14;
p->pos.y += p->vel.y>>14; p->pos.y += p->vel.y>>14;
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
// TODO: only if ceiling/floor bunchnum >= 0
updatesectorz(p->pos.x,p->pos.y,p->pos.z,&p->cursectnum); updatesectorz(p->pos.x,p->pos.y,p->pos.z,&p->cursectnum);
#else #else
updatesector(p->pos.x,p->pos.y,&p->cursectnum); updatesector(p->pos.x,p->pos.y,&p->cursectnum);
@ -5363,7 +5365,17 @@ HORIZONLY:
else else
{ {
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
// 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); updatesectorz(p->pos.x,p->pos.y,p->pos.z,&p->cursectnum);
}
#endif #endif
if ((j = clipmove((vec3_t *)p,&p->cursectnum, p->vel.x,p->vel.y,164L,(4L<<8),i,CLIPMASK0))) if ((j = clipmove((vec3_t *)p,&p->cursectnum, p->vel.x,p->vel.y,164L,(4L<<8),i,CLIPMASK0)))
P_CheckTouchDamage(p, j); P_CheckTouchDamage(p, j);

View file

@ -245,6 +245,19 @@ int32_t G_LoadPlayer(int32_t spot)
if (kdfread(&wall[0],sizeof(walltype),MAXWALLS,fil) != MAXWALLS) goto corrupt; if (kdfread(&wall[0],sizeof(walltype),MAXWALLS,fil) != MAXWALLS) goto corrupt;
if (kdfread(&numsectors,sizeof(numsectors),1,fil) != 1) goto corrupt; if (kdfread(&numsectors,sizeof(numsectors),1,fil) != 1) goto corrupt;
if (kdfread(&sector[0],sizeof(sectortype),MAXSECTORS,fil) != MAXSECTORS) goto corrupt; if (kdfread(&sector[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(&sprite[0],sizeof(spritetype),MAXSPRITES,fil) != MAXSPRITES) goto corrupt;
if (kdfread(&spriteext[0],sizeof(spriteext_t),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(&wall[0],sizeof(walltype),MAXWALLS,fil);
dfwrite(&numsectors,sizeof(numsectors),1,fil); dfwrite(&numsectors,sizeof(numsectors),1,fil);
dfwrite(&sector[0],sizeof(sectortype),MAXSECTORS,fil); dfwrite(&sector[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); dfwrite(&sprite[0],sizeof(spritetype),MAXSPRITES,fil);
#ifdef USE_OPENGL #ifdef USE_OPENGL
for (i=0; i<MAXSPRITES; i++) for (i=0; i<MAXSPRITES; i++)
@ -921,7 +944,11 @@ typedef struct dataspec_
intptr_t cnt; intptr_t cnt;
} dataspec_t; } dataspec_t;
#define SV_MAJOR_VER 0 #ifdef YAX_ENABLE
# define SV_MAJOR_VER 1
#else
# define SV_MAJOR_VER 0
#endif
#define SV_MINOR_VER 3 #define SV_MINOR_VER 3
#define SV_DEFAULTCOMPRTHRES 8 #define SV_DEFAULTCOMPRTHRES 8
static uint8_t savegame_diffcompress; // 0:none, 1:Ken's LZW in cache1d.c static uint8_t savegame_diffcompress; // 0:none, 1:Ken's LZW in cache1d.c
@ -940,6 +967,7 @@ static uint8_t savegame_comprthres;
#define DS_LOADFN 128 // .ptr is function that is run when loading #define DS_LOADFN 128 // .ptr is function that is run when loading
#define DS_SAVEFN 256 // .ptr is function that is run when saving #define DS_SAVEFN 256 // .ptr is function that is run when saving
#define DS_NOCHK 1024 // don't check for diffs (and don't write out in dump) since assumed constant throughout demo #define DS_NOCHK 1024 // don't check for diffs (and don't write out in dump) since assumed constant throughout demo
#define DS_PROTECTFN 512
#define DS_END (0x70000000) #define DS_END (0x70000000)
static int32_t ds_getcnt(const dataspec_t *sp) static int32_t ds_getcnt(const dataspec_t *sp)
@ -1199,7 +1227,7 @@ static void cmpspecdata(const dataspec_t *spec, uint8_t **dumpvar, uint8_t **dif
if ((sp->flags&(DS_NOCHK|DS_STRING|DS_CMP))) if ((sp->flags&(DS_NOCHK|DS_STRING|DS_CMP)))
continue; continue;
if (sp->flags&(DS_LOADFN|DS_SAVEFN)) if (sp->flags&(DS_LOADFN|DS_SAVEFN) && (sp->flags&(DS_PROTECTFN))==0)
{ {
(*(void ( *)())sp->ptr)(); (*(void ( *)())sp->ptr)();
continue; continue;
@ -1347,6 +1375,9 @@ static void sv_postudload();
static void sv_prespriteextsave(); static void sv_prespriteextsave();
static void sv_postspriteext(); static void sv_postspriteext();
#endif #endif
#ifdef YAX_ENABLE
static void sv_postyaxload();
#endif
static void sv_calcbitptrsize(); static void sv_calcbitptrsize();
static void sv_prescriptsave_once(); static void sv_prescriptsave_once();
static void sv_prescriptload_once(); static void sv_prescriptload_once();
@ -1421,6 +1452,12 @@ static const dataspec_t svgm_secwsp[] =
{ DS_NOCHK, &numsectors, sizeof(numsectors), 1 }, { DS_NOCHK, &numsectors, sizeof(numsectors), 1 },
{ DS_DYNAMIC|DS_CNT(numsectors), &sector, sizeof(sectortype), (intptr_t)&numsectors }, { DS_DYNAMIC|DS_CNT(numsectors), &sector, sizeof(sectortype), (intptr_t)&numsectors },
{ DS_DYNAMIC, &sprite, sizeof(spritetype), MAXSPRITES }, { 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, &headspritesect[0], sizeof(headspritesect[0]), MAXSECTORS+1 },
{ 0, &prevspritesect[0], sizeof(prevspritesect[0]), MAXSPRITES }, { 0, &prevspritesect[0], sizeof(prevspritesect[0]), MAXSPRITES },
{ 0, &nextspritesect[0], sizeof(nextspritesect[0]), MAXSPRITES }, { 0, &nextspritesect[0], sizeof(nextspritesect[0]), MAXSPRITES },
@ -1842,6 +1879,13 @@ static void sv_postspriteext()
} }
#endif #endif
#ifdef YAX_ENABLE
static void sv_postyaxload()
{
yax_update(numyaxbunches>0 ? 2 : 1);
}
#endif
static void sv_calcbitptrsize() static void sv_calcbitptrsize()
{ {
savegame_bitptrsize = (g_scriptSize+7)>>3; savegame_bitptrsize = (g_scriptSize+7)>>3;