diff --git a/source/blood/src/mapedit.cpp b/source/blood/src/mapedit.cpp index 4daa411a89..866aca648a 100644 --- a/source/blood/src/mapedit.cpp +++ b/source/blood/src/mapedit.cpp @@ -1555,7 +1555,7 @@ void adjustSprites() spritetype* pSprite = &sprite[i]; if (pSprite->statnum < kMaxStatus) { - if ((pSprite->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_SLAB) pSprite->cstat &= ~CSTAT_SPRITE_ALIGNMENT_MASK; + if ((pSprite->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_MASK) pSprite->cstat &= ~CSTAT_SPRITE_ALIGNMENT_MASK; if (pSprite->statnum == 1) continue; // don't turn unnamed types in Decoration diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index c877d43726..b2b8cac9c7 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -2486,8 +2486,8 @@ tspritetype *viewAddEffect(int nTSprite, VIEW_EFFECT nViewEffect) const int nVoxel = voxelIndex[nTile]; if (gShowWeapon == 2 && usevoxels && gDetail >= 4 && videoGetRenderMode() != REND_POLYMER && nVoxel != -1) { - pNSprite->cstat |= 48; - pNSprite->cstat &= ~8; + pNSprite->clipdist |= TSPR_FLAGS_SLAB; + pNSprite->cstat &= ~(8|CSTAT_SPRITE_ALIGNMENT); pNSprite->picnum = nVoxel; if (pPlayer->curWeapon == kWeaponLifeLeech) // position lifeleech behind player { @@ -2548,6 +2548,8 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t continue; } + auto const tsprflags = pTSprite->clipdist; + if (gViewInterpolate && TestBitString(gInterpolateSprite, nSprite) && !(pTSprite->flags&512)) { LOCATION *pPrevLoc = &gPrevSpriteLoc[nSprite]; @@ -2640,8 +2642,8 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t { if ((pTSprite->flags&kHitagRespawn) == 0) { - pTSprite->cstat |= 48; - pTSprite->cstat &= ~(4|8); + pTSprite->clipdist |= TSPR_FLAGS_SLAB; + pTSprite->cstat &= ~(4|8|CSTAT_SPRITE_ALIGNMENT); pTSprite->yoffset += picanm[pTSprite->picnum].yofs; pTSprite->picnum = voxelIndex[pTSprite->picnum]; if (!voxoff[pTSprite->picnum][0]) @@ -2661,7 +2663,7 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t nAnim--; } - if ((pTSprite->cstat&48) != 48 && usevoxels && videoGetRenderMode() != REND_POLYMER && !(spriteext[nSprite].flags&SPREXT_NOTMD)) + if (!(tsprflags & TSPR_FLAGS_SLAB) && usevoxels && videoGetRenderMode() != REND_POLYMER && !(spriteext[nSprite].flags&SPREXT_NOTMD)) { int const nRootTile = pTSprite->picnum; #if 0 @@ -2680,7 +2682,7 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t } #ifdef USE_OPENGL - if ((pTSprite->cstat&48) != 48 && usemodels && !(spriteext[nSprite].flags&SPREXT_NOTMD)) + if (!(tsprflags & TSPR_FLAGS_SLAB) && usemodels && !(spriteext[nSprite].flags&SPREXT_NOTMD)) { int const nRootTile = pTSprite->picnum; int nAnimTile = pTSprite->picnum + animateoffs_replace(pTSprite->picnum, 32768+nSprite); diff --git a/source/build/include/build.h b/source/build/include/build.h index 2519f6df77..16919dbb10 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -598,6 +598,7 @@ enum TSPR_FLAGS_NO_SHADOW = 1u<<2u, TSPR_FLAGS_INVISIBLE_WITH_SHADOW = 1u<<3u, TSPR_FLAGS_SLOPE_SPRITE = 1u<<4u, + TSPR_FLAGS_SLAB = 1u<<5u, }; EXTERN int32_t guniqhudid; diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 01a344eb12..5217cd79e3 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -139,7 +139,6 @@ enum CSTAT_SPRITE_ALIGNMENT_FACING = 0, CSTAT_SPRITE_ALIGNMENT_WALL = 1u<<4u, CSTAT_SPRITE_ALIGNMENT_FLOOR = 1u<<5u, - CSTAT_SPRITE_ALIGNMENT_SLAB = 1u<<4u | 1u<<5u, CSTAT_SPRITE_ALIGNMENT_SLOPE = 1u<<4u | 1u<<5u, CSTAT_SPRITE_ALIGNMENT_MASK = 1u<<4u | 1u<<5u, diff --git a/source/build/src/2d.cpp b/source/build/src/2d.cpp index e8441c3b1f..a462feda63 100644 --- a/source/build/src/2d.cpp +++ b/source/build/src/2d.cpp @@ -1245,7 +1245,8 @@ static void editorDraw2dSprite(int32_t j, int32_t posxe, int32_t posye, int32_t { auto const spr = &sprite[j]; int16_t const blocking = (spr->cstat&1), hitblocking = (spr->cstat&256); - int16_t const flooraligned = (spr->cstat&48) >= 32, wallaligned = (spr->cstat&48) == 16; + int16_t const flooraligned = spr->cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR; + int16_t const wallaligned = (spr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL; int16_t const angofs = m32_sideview ? m32_sideang : 0; int32_t const ang = spr->ang + angofs; diff --git a/source/build/src/build.cpp b/source/build/src/build.cpp index a6536c0309..4db54e4a40 100644 --- a/source/build/src/build.cpp +++ b/source/build/src/build.cpp @@ -1006,9 +1006,9 @@ void spriteoncfz(int32_t i, int32_t *czptr, int32_t *fzptr) int32_t height, zofs; getzsofslope(sprite[i].sectnum, sprite[i].x,sprite[i].y, czptr, fzptr); - if ((sprite[i].cstat&48)==32) + if ((sprite[i].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) return; - if ((sprite[i].cstat&48)==48) + if ((sprite[i].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLOPE) { int32_t const heinum = spriteGetSlope(i); int32_t const ratio = divscale12(heinum, ksqrt(heinum*heinum+16777216)); @@ -1550,10 +1550,10 @@ void editinput(void) spriteoncfz(i, &cz, &fz); sprite[i].z = clamp2(hit.z, cz, fz); - if (AIMING_AT_WALL || AIMING_AT_MASKWALL || (AIMING_AT_SPRITE && (sprite[searchwall].cstat & CSTAT_SPRITE_ALIGNMENT_SLAB) == CSTAT_SPRITE_ALIGNMENT_WALL)) + if (AIMING_AT_WALL || AIMING_AT_MASKWALL || (AIMING_AT_SPRITE && (sprite[searchwall].cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_WALL)) { - sprite[i].cstat &= ~48; - sprite[i].cstat |= (16+64); + sprite[i].cstat &= ~CSTAT_SPRITE_ALIGNMENT; + sprite[i].cstat |= CSTAT_SPRITE_ONE_SIDED|CSTAT_SPRITE_ALIGNMENT_WALL; correct_ornamented_sprite(i, hit); } @@ -2440,7 +2440,7 @@ static int32_t insert_sprite_common(int32_t sectnum, int32_t dax, int32_t day) void correct_sprite_yoffset(int32_t i) { - if ((sprite[i].cstat&48) >= 32) + if (sprite[i].cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR) return; int32_t tileyofs = picanm[sprite[i].picnum].yofs; int32_t tileysiz = tilesiz[sprite[i].picnum].y; @@ -3741,7 +3741,7 @@ extern void editorFlipHighlightedSectors(int about_x, int doMirror) sprite[j].ang = (2048-sprite[j].ang)&2047; //flip ang about 512 } - if (doMirror && (sprite[j].cstat & 0x30)) + if (doMirror && (sprite[j].cstat & CSTAT_SPRITE_ALIGNMENT)) sprite[j].cstat ^= 4; // mirror sprites about dax/day (don't mirror monsters) j = nextspritesect[j]; diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index faeeef1f0e..13617ae525 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -281,7 +281,7 @@ int32_t engineLoadClipMaps(void) if (i>=fispr[fi]) break; LOG_F(WARNING, "Error in %s: sprite %d points neither northward nor southward. %s will be incorrect.", - g_clipMapFiles[fi], i-fispr[fi], (sprite[i].cstat&48)==32 ? "Scaling and flipping" : "X-flipping"); + g_clipMapFiles[fi], i-fispr[fi], (sprite[i].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR ? "Scaling and flipping" : "X-flipping"); } } @@ -1362,7 +1362,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int #endif vec2_t p1 = spr->xy; - switch (cstat & (CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_ALIGNMENT_FLOOR)) + switch (cstat & CSTAT_SPRITE_ALIGNMENT_MASK) { case CSTAT_SPRITE_ALIGNMENT_FACING: if (p1.x >= clipMin.x && p1.x <= clipMax.x && p1.y >= clipMin.y && p1.y <= clipMax.y) @@ -1723,7 +1723,7 @@ int pushmove(vec3_t *const vect, int16_t *const sectnum, for (i=headspritesect[clipsectorlist[clipsectcnt]]; i>=0; i=nextspritesect[i]) { spr = &sprite[i]; - if (((spr->cstat&48) != 0) && ((spr->cstat&48) != 48)) continue; + if ((spr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_FACING) continue; if ((spr->cstat&dasprclipmask) == 0) continue; dax = (vect->x)-spr->x; day = (vect->y)-spr->y; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 03b987ed58..8a5617539b 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -1637,7 +1637,7 @@ int32_t renderAddTsprite(int16_t z, int16_t sectnum) (*sortcnt)++; // now check whether the tsprite needs duplication into another level - if ((spr->cstat&48)==32) + if ((spr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) return 0; int16_t cb, fb; @@ -1795,8 +1795,8 @@ static void classicScanSector(int16_t startsectnum) vec2_t const s = { spr->x-globalposx, spr->y-globalposy }; - if ((spr->cstat&48) || ((coord_t)s.x*cosglobalang+(coord_t)s.y*singlobalang > 0)) - if ((spr->cstat&(64+48))!=(64+16) || dmulscale6(sintable[(spr->ang+512)&2047],-s.x, sintable[spr->ang&2047],-s.y) > 0) + if ((spr->cstat & CSTAT_SPRITE_ALIGNMENT) || ((coord_t)s.x*cosglobalang+(coord_t)s.y*singlobalang > 0)) + if ((spr->cstat & (CSTAT_SPRITE_ONE_SIDED|CSTAT_SPRITE_ALIGNMENT)) != (CSTAT_SPRITE_ONE_SIDED|CSTAT_SPRITE_ALIGNMENT_WALL) || dmulscale6(sintable[(spr->ang+512)&2047],-s.x, sintable[spr->ang&2047],-s.y) > 0) if (renderAddTsprite(i, sectnum)) break; } @@ -5014,7 +5014,7 @@ typedef zint_t voxint_t; static void classicDrawVoxel(int32_t dasprx, int32_t daspry, int32_t dasprz, int32_t dasprang, int32_t daxscale, int32_t dayscale, int32_t daindex, int8_t dashade, char dapal, const int32_t *daumost, const int32_t *dadmost, - const int16_t cstat, const int32_t clipcf, int32_t floorz, int32_t ceilingz) + const int16_t cstat, const int32_t tsprflags, int32_t floorz, int32_t ceilingz) { int32_t i, j, k, x, y, mip; @@ -5108,7 +5108,7 @@ static void classicDrawVoxel(int32_t dasprx, int32_t daspry, int32_t dasprz, int int32_t zoff = dazsiz<<14; if (!(cstat & 128)) zoff += dazpivot<<7; - else if ((cstat&48) != 48) + else if (!(tsprflags & TSPR_FLAGS_SLAB)) { zoff += dazpivot<<7; zoff -= dazsiz<<14; @@ -5271,7 +5271,7 @@ static void classicDrawVoxel(int32_t dasprx, int32_t daspry, int32_t dasprz, int const int32_t l2 = mulscale(distrecip[clamp((ny+yoff)>>14, 1, DISTRECIPSIZ-1)], dayscale, 12+mip); int32_t cz1 = 0, cz2 = INT32_MAX; - if (clipcf) + if (!(tsprflags & TSPR_FLAGS_SLAB)) // clipcf { cz1 = mulscale32((ceilingoff < 0) ? l1 : l2, ceilingoff) + globalhoriz; cz2 = mulscale32((flooroff < 0) ? l2 : l1, flooroff) + globalhoriz; @@ -5477,8 +5477,9 @@ static void classicDrawSprite(int32_t snum) auto const sec = (usectorptr_t)§or[sectnum]; int32_t cstat=tspr->cstat, tilenum; + auto tsprflags = tspr->clipdist; - if ((cstat&48) != 48) + if (!(tsprflags & TSPR_FLAGS_SLAB)) tileUpdatePicnum(&tspr->picnum, spritenum+32768); if (!(cstat&2) && alpha > 0.0f) @@ -5510,15 +5511,16 @@ static void classicDrawSprite(int32_t snum) tilenum = tspr->picnum; - if ((cstat&48)==48) + if (tsprflags & TSPR_FLAGS_SLAB) vtilenum = tilenum; // if the game wants voxels, it gets voxels - else if ((cstat & 48) != 32 && usevoxels && tiletovox[tilenum] != -1 && spritenum != -1 && !(spriteext[spritenum].flags&SPREXT_NOTMD)) + else if ((cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_FLOOR && usevoxels && tiletovox[tilenum] != -1 && spritenum != -1 && !(spriteext[spritenum].flags&SPREXT_NOTMD)) { vtilenum = tiletovox[tilenum]; - cstat |= 48; + tsprflags |= TSPR_FLAGS_SLAB; + cstat &= ~CSTAT_SPRITE_ALIGNMENT; } - if ((cstat&48) != 48) + if (!(tsprflags & TSPR_FLAGS_SLAB)) { if (spritenum < 0 || tilesiz[tilenum].x <= 0 || tilesiz[tilenum].y <= 0) return; @@ -5542,912 +5544,1263 @@ static void classicDrawSprite(int32_t snum) off.y += tspr->yoffset; } - if ((cstat&48) == 0) + if (tsprflags & TSPR_FLAGS_SLAB) { - int32_t startum, startdm; - int32_t linum, linuminc; - -draw_as_face_sprite: - if (yp <= (4<<8)) return; - - int const isiz = divscale19(xdimenscale,yp); - int const xv = mulscale16(((int32_t)tspr->xrepeat)<<16,xyaspect); - vec2_16_t const span = tilesiz[tilenum]; - vec2_t const siz = { mulscale30(isiz, xv * span.x), mulscale14(isiz, tspr->yrepeat * span.y) }; - - if (/*EDUKE32_PREDICT_FALSE*/((span.x>>11) >= siz.x || span.y >= (siz.y>>1))) - return; //Watch out for divscale overflow - - vec2_16_t upscale = {}; - tileLoadScaled(tilenum, &upscale); - - x1 = xb-(siz.x>>1); - if (span.x&1) x1 += mulscale31(isiz,xv); //Odd xspans - i = mulscale30(isiz,xv*off.x); - if ((cstat&4) == 0) x1 -= i; else x1 += i; - - y1 = mulscale16(tspr->z-globalposz,isiz); - y1 -= mulscale14(isiz,tspr->yrepeat*off.y); - y1 += (globalhoriz<<8)-siz.y; - if (cstat&128) - { - y1 += (siz.y>>1); - if (span.y&1) y1 += mulscale15(isiz,tspr->yrepeat); //Odd yspans - } - - x2 = x1+siz.x-1; - y2 = y1+siz.y-1; - if ((y1|255) >= (y2|255)) return; - - int32_t lx = (x1>>8)+1; if (lx < 0) lx = 0; - int32_t rx = (x2>>8); if (rx >= xdimen) rx = xdimen-1; - if (lx > rx) return; - - startum = ((sec->ceilingstat&3) == 0) ? globalhoriz+mulscale24(isiz,sec->ceilingz-globalposz)-1 : 0; - startdm = ((sec->floorstat&3) == 0) ? globalhoriz+mulscale24(isiz,sec->floorz-globalposz)+1 : INT32_MAX; + const int32_t daxrepeat = ((sprite[spritenum].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL) ? + (tspr->xrepeat * 5) / 4 : + tspr->xrepeat; - if ((y1>>8) > startum) startum = (y1>>8); - if ((y2>>8) < startdm) startdm = (y2>>8); + const int32_t lx = 0, rx = xdimen-1; - if (startum < -32768) startum = -32768; - if (startdm > 32767) startdm = 32767; - if (startum >= startdm) return; + Bassert(rx+windowxy1.x < xdim); - if ((cstat&4) == 0) + for (x=lx; x<=rx; x++) { - linuminc = divscale24(span.x<cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL) { - linuminc = -divscale24(span.x< 0) - swaplong(&y1, &y2); + const int32_t xspan = tilesiz[tilenum].x; + //const int32_t yspan = tilesiz[tilenum].y; + const int32_t xv = tspr->xrepeat*sintable[(tspr->ang+2560+1536)&2047]; + const int32_t yv = tspr->xrepeat*sintable[(tspr->ang+2048+1536)&2047]; - x = lx; -#ifdef CLASSIC_SLICE_BY_4 - for (; x<=rx-4; x+=4) - { - uwall[x] = max(startumost[windowxy1.x+x]-windowxy1.y, startum); - uwall[x+1] = max(startumost[windowxy1.x+x+1]-windowxy1.y, startum); - uwall[x+2] = max(startumost[windowxy1.x+x+2]-windowxy1.y, startum); - uwall[x+3] = max(startumost[windowxy1.x+x+3]-windowxy1.y, startum); + i = (xspan>>1) + off.x; + x1 = tspr->x-globalposx-mulscale16(xv,i); x2 = x1+mulscale16(xv,xspan); + y1 = tspr->y-globalposy-mulscale16(yv,i); y2 = y1+mulscale16(yv,xspan); - dwall[x] = min(startdmost[windowxy1.x+x]-windowxy1.y, startdm); - dwall[x+1] = min(startdmost[windowxy1.x+x+1]-windowxy1.y, startdm); - dwall[x+2] = min(startdmost[windowxy1.x+x+2]-windowxy1.y, startdm); - dwall[x+3] = min(startdmost[windowxy1.x+x+3]-windowxy1.y, startdm); - } -#endif - for (; x<=rx; x++) - { - uwall[x] = max(startumost[windowxy1.x+x]-windowxy1.y,startum); - dwall[x] = min(startdmost[windowxy1.x+x]-windowxy1.y,startdm); - } + vec2_t p1 = get_rel_coords(x1, y1); + vec2_t p2 = get_rel_coords(x2, y2); - int32_t daclip = 0; - for (i=smostwallcnt-1; i>=0; i--) - { - if (smostwalltype[i]&daclip) continue; - j = smostwall[i]; - if ((xb1[j] > rx) || (xb2[j] < lx)) continue; - if ((yp <= yb1[j]) && (yp <= yb2[j])) continue; - if (spritewallfront(tspr,(int32_t)thewall[j]) && ((yp <= yb1[j]) || (yp <= yb2[j]))) continue; + if (p1.y <= 0 && p2.y <= 0) + return; - const int32_t dalx2 = max(xb1[j],lx); - const int32_t darx2 = min(xb2[j],rx); + x1 += globalposx; y1 += globalposy; + x2 += globalposx; y2 += globalposy; - switch (smostwalltype[i]) + if (dmulscale32(p1.x, p2.y, -p2.x, p1.y) >= 0) // If wall's NOT facing you { - case 0: - if (dalx2 <= darx2) - { - if ((dalx2 == lx) && (darx2 == rx)) return; - //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); - for (k=dalx2; k<=darx2; k++) dwall[k] = 0; - } - break; - case 1: - k = smoststart[i] - xb1[j]; - x = dalx2; -#ifdef CLASSIC_SLICE_BY_4 // ok, this one is really by 2 ;) - for (; x<=darx2-2; x+=2) - { - if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; - if (smost[k+x+1] > uwall[x+1]) uwall[x+1] = smost[k+x+1]; - } -#endif - for (; x<=darx2; x++) - if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; - if ((dalx2 == lx) && (darx2 == rx)) daclip |= 1; - break; - case 2: - k = smoststart[i] - xb1[j]; - x = dalx2; -#ifdef CLASSIC_SLICE_BY_4 - for (; x<=darx2-4; x+=4) - { - if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; - if (smost[k+x+1] < dwall[x+1]) dwall[x+1] = smost[k+x+1]; - if (smost[k+x+2] < dwall[x+2]) dwall[x+2] = smost[k+x+2]; - if (smost[k+x+3] < dwall[x+3]) dwall[x+3] = smost[k+x+3]; - } -#endif - for (; x<=darx2; x++) - if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; - if ((dalx2 == lx) && (darx2 == rx)) daclip |= 2; - break; + const vec2_t pt = p2; + p2 = p1; + p1 = pt; + i = x1, x1 = x2, x2 = i; + i = y1, y1 = y2, y2 = i; } - } - - if (uwall[rx] >= dwall[rx]) - { - for (x=lx; x= 1 && (searchx >= lx && searchx <= rx)) - if (searchy >= uwall[searchx] && searchy < dwall[searchx]) + for (i=smostwallcnt-1; i>=0; i--) { - searchsector = sectnum; searchwall = spritenum; - searchstat = 3; searchit = 1; - } + j = smostwall[i]; - setup_globals_sprite1(tspr, sec, span.y, off.y, tilenum, cstat, &z1, &z2, upscale); + if (xb1[j] > rx || xb2[j] < lx) + continue; - qinterpolatedown16((intptr_t)&lwall[lx],rx-lx+1,linum,linuminc); - clearbuf(&swall[lx],rx-lx+1,mulscale19(yp,xdimscale)); + int32_t dalx2 = xb1[j]; + int32_t darx2 = xb2[j]; - { -#ifdef HIGH_PRECISION_SPRITE - union { float f; int32_t i; } sw = { - // initialize the float of the union - ((cstat&8) ? -1 : 1) - * (float)yp * xdimscale - * (1<<(22-19)) / (span.y*tspr->yrepeat) - }; + if (max(p1.y,p2.y) > min(yb1[j],yb2[j])) + { + if (min(p1.y,p2.y) > max(yb1[j],yb2[j])) + { + x = INT32_MIN; + } + else + { + x = thewall[j]; xp1 = wall[x].x; yp1 = wall[x].y; + x = wall[x].point2; xp2 = wall[x].x; yp2 = wall[x].y; - clearbuf(&swallf[lx], rx-lx+1, sw.i); -#endif - } + z1 = (xp2-xp1)*(y1-yp1) - (yp2-yp1)*(x1-xp1); + z2 = (xp2-xp1)*(y2-yp1) - (yp2-yp1)*(x2-xp1); + if ((z1 == 0) | (z2 == 0)) + { + if ((xp2-xp1)*(tspr->y-yp1) == (tspr->x-xp1)*(yp2-yp1)) + { + if (wall[thewall[j]].nextsector == tspr->sectnum) + x = INT32_MIN; + else + x = INT32_MAX; + } + else + x = (z1+z2); + } + else if ((z1^z2) >= 0) + x = (z1+z2); + else + { + z1 = (x2-x1)*(yp1-y1) - (y2-y1)*(xp1-x1); + z2 = (x2-x1)*(yp2-y1) - (y2-y1)*(xp2-x1); - drawing_sprite = 1; + if (((z1^z2) >= 0) | (z1 == 0) | (z2 == 0)) + x = -(z1+z2); + else + { + if ((xp2-xp1)*(tspr->y-yp1) == (tspr->x-xp1)*(yp2-yp1)) + { + if (wall[thewall[j]].nextsector == tspr->sectnum) + x = INT32_MIN; + else + x = INT32_MAX; + } + else + { + x = INT32_MAX; +#if 0 + //INTERSECTION! + x = (xp1-globalposx) + scale(xp2-xp1,z1,z1-z2); + y = (yp1-globalposy) + scale(yp2-yp1,z1,z1-z2); - if ((cstat&2) == 0) - maskwallscan(lx,rx, (cstat&8)==0); - else - transmaskwallscan(lx,rx, (cstat&8)==0); + yp1 = dmulscale14(x,cosviewingrangeglobalang,y,sinviewingrangeglobalang); - drawing_sprite = 0; - globalht = nullptr; - } - else if ((cstat&48) == 16) - { - const int32_t xspan = tilesiz[tilenum].x; - const int32_t yspan = tilesiz[tilenum].y; - const int32_t xv = tspr->xrepeat*sintable[(tspr->ang+2560+1536)&2047]; - const int32_t yv = tspr->xrepeat*sintable[(tspr->ang+2048+1536)&2047]; + if (yp1 > 0) + { + xp1 = dmulscale14(y,cosglobalang,-x,singlobalang); - if ((cstat&4) > 0) off.x = -off.x; - if ((cstat&8) > 0) off.y = -off.y; + x = halfxdimen + scale(xp1,halfxdimen,yp1); + if (xp1 >= 0) x++; //Fix for SIGNED divide - i = (xspan>>1) + off.x; - x1 = tspr->x-globalposx-mulscale16(xv,i); x2 = x1+mulscale16(xv,xspan); - y1 = tspr->y-globalposy-mulscale16(yv,i); y2 = y1+mulscale16(yv,xspan); - - vec2_t p1 = get_rel_coords(x1, y1); - vec2_t p2 = get_rel_coords(x2, y2); - - if (p1.y <= 0 && p2.y <= 0) - return; + if (z1 < 0) + { if (dalx2 < x) dalx2 = x; } + else + { if (darx2 > x) darx2 = x; } + x = INT32_MIN+1; + } + else + x = INT32_MAX; +#endif + } + } + } + } - x1 += globalposx; y1 += globalposy; - x2 += globalposx; y2 += globalposy; + if (x < 0) + { + if (dalx2 < lx) dalx2 = lx; + if (darx2 > rx) darx2 = rx; - int32_t swapped = 0; - if (dmulscale32(p1.x, p2.y, -p2.x, p1.y) >= 0) // If wall's NOT facing you + switch (smostwalltype[i]) + { + case 0: + if (dalx2 <= darx2) + { + if ((dalx2 == lx) && (darx2 == rx)) return; + //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); + for (k=dalx2; k<=darx2; k++) swall[k] = 0; + } + break; + case 1: + k = smoststart[i] - xb1[j]; + x = dalx2; +#ifdef CLASSIC_SLICE_BY_4 + for (; x<=darx2-2; x+=2) + { + if (smost[k+x] > lwall[x]) lwall[x] = smost[k+x]; + if (smost[k+x+1] > lwall[x+1]) lwall[x+1] = smost[k+x+1]; + } +#endif + for (; x<=darx2; x++) + if (smost[k+x] > lwall[x]) lwall[x] = smost[k+x]; + break; + case 2: + k = smoststart[i] - xb1[j]; + x = dalx2; +#ifdef CLASSIC_SLICE_BY_4 + for (; x<=darx2-4; x+=4) + { + if (smost[k+x] < swall[x]) swall[x] = smost[k+x]; + if (smost[k+x+1] < swall[x+1]) swall[x+1] = smost[k+x+1]; + if (smost[k+x+2] < swall[x+2]) swall[x+2] = smost[k+x+2]; + if (smost[k+x+3] < swall[x+3]) swall[x+3] = smost[k+x+3]; + } +#endif + for (; x<=darx2; x++) + if (smost[k+x] < swall[x]) swall[x] = smost[k+x]; + break; + } + } + } + } + } + else { - if ((cstat&64) != 0) - return; + for (i=smostwallcnt-1; i>=0; i--) + { + j = smostwall[i]; + if ((xb1[j] > rx) || (xb2[j] < lx)) continue; + if ((yp <= yb1[j]) && (yp <= yb2[j])) continue; + if (spritewallfront(tspr,(int32_t)thewall[j]) && ((yp <= yb1[j]) || (yp <= yb2[j]))) continue; - const vec2_t pt = p2; - p2 = p1; - p1 = pt; - i = x1, x1 = x2, x2 = i; - i = y1, y1 = y2, y2 = i; - swapped = 1; - } + const int32_t dalx2 = max(xb1[j],lx); + const int32_t darx2 = min(xb2[j],rx); - int32_t sx1, sx2, sy1, sy2; - if (!get_screen_coords(p1, p2, &sx1, &sy1, &sx2, &sy2)) - return; + switch (smostwalltype[i]) + { + case 0: + if (dalx2 <= darx2) + { + if ((dalx2 == lx) && (darx2 == rx)) return; + //clearbufbyte(&swall[dalx2],(darx2-dalx2+1)*sizeof(swall[0]),0L); + for (x=dalx2; x<=darx2; x++) swall[x] = 0; + } + break; + case 1: + k = smoststart[i] - xb1[j]; + x = dalx2; +#ifdef CLASSIC_SLICE_BY_4 + for (; x<=darx2-2; x+=2) + { + if (smost[k+x] > lwall[x]) lwall[x] = smost[k+x]; + if (smost[k+x+1] > lwall[x+1]) lwall[x+1] = smost[k+x+1]; + } +#endif + for (; x<=darx2; x++) + if (smost[k+x] > lwall[x]) lwall[x] = smost[k+x]; + break; + case 2: + k = smoststart[i] - xb1[j]; + x = dalx2; +#ifdef CLASSIC_SLICE_BY_4 + for (; x<=darx2-4; x+=4) + { + if (smost[k+x] < swall[x]) swall[x] = smost[k+x]; + if (smost[k+x+1] < swall[x+1]) swall[x+1] = smost[k+x+1]; + if (smost[k+x+2] < swall[x+2]) swall[x+2] = smost[k+x+2]; + if (smost[k+x+3] < swall[x+3]) swall[x+3] = smost[k+x+3]; + } +#endif + for (; x<=darx2; x++) + if (smost[k+x] < swall[x]) swall[x] = smost[k+x]; + break; + } + } + } - vec2_16_t upscale = {}; - tileLoadScaled(tilenum, &upscale); + if (lwall[rx] >= swall[rx]) + { + for (x=lx; x>8; - int32_t bot = mulscale11(p1.x-p2.x,xdimen) + mulscale2(sx1-halfxdimen,botinc); + for (i=0; i>8); - for (x=sx1+4; x<=j; x+=4) + const int32_t *const longptr = (int32_t *)voxoff[vtilenum][0]; + if (longptr == NULL) { - top += topinc; bot += botinc; - zz = z; z = divscale10(top, bot); - i = ((z+zz)>>1); - lwall[x-3] = ((i+zz)>>9); - lwall[x-2] = (i>>8); - lwall[x-1] = ((i+z)>>9); - lwall[x] = (z>>8); + globalshade = 32; + tspr->xrepeat = tspr->yrepeat = 255; + goto draw_as_face_sprite; } - if (lwall[sx1] < 0) lwall[sx1] = 0; - if (lwall[sx2] >= (xspan<0)) > 0) + if (voxscale[vtilenum] == 65536) { - j = (xspan<yrepeat)<<16); + } + else + { + nxrepeat = daxrepeat*voxscale[vtilenum]; + nyrepeat = ((int32_t)tspr->yrepeat)*voxscale[vtilenum]; } - // XXX: UNUSED? - rx1[MAXWALLSB-1] = p1.x; ry1[MAXWALLSB-1] = p1.y; - rx2[MAXWALLSB-1] = p2.x; ry2[MAXWALLSB-1] = p2.y; + off.x = tspr->xoffset; + off.y = /*picanm[sprite[tspr->owner].picnum].yofs +*/ tspr->yoffset; + if (cstat & 4) off.x = -off.x; + if ((cstat & 8) && (tspr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_FACING) off.y = -off.y; + tspr->z -= off.y * tspr->yrepeat << 2; - setup_globals_sprite1(tspr, sec, yspan, off.y, tilenum, cstat, &z1, &z2, upscale); + const float xfactor = (tspr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_WALL ? (256.f/320.f) : 1.f; + const int32_t xv = (int32_t)(tspr->xrepeat*sintable[(tspr->ang+2560+1536)&2047]*xfactor); + const int32_t yv = (int32_t)(tspr->xrepeat*sintable[(tspr->ang+2048+1536)&2047]*xfactor); - if ((sec->ceilingstat&1) == 0 && z1 < sec->ceilingz) - z1 = sec->ceilingz; - if ((sec->floorstat&1) == 0 && z2 > sec->floorz) - z2 = sec->floorz; + tspr->x -= mulscale16(xv, off.x); + tspr->y -= mulscale16(yv, off.x); - xb1[MAXWALLSB-1] = sx1; - xb2[MAXWALLSB-1] = sx2; - yb1[MAXWALLSB-1] = sy1; - yb2[MAXWALLSB-1] = sy2; - owallmost(uwall, MAXWALLSB-1, z1-globalposz); - owallmost(dwall, MAXWALLSB-1, z2-globalposz); + globvis = globalvisibility; + if (sec->visibility != 0) globvis = mulscale4(globvis, (uint8_t)(sec->visibility+16)); - int32_t hplc = divscale19(xdimenscale,sy1); - const int32_t hplc2 = divscale19(xdimenscale,sy2); - const int32_t idiv = sx2-sx1; - int32_t hinc[4] = { idiv ? tabledivide32(hplc2-hplc, idiv) : 0 }; +#ifdef YAX_ENABLE + if (yax_globallev==YAX_MAXDRAWS || searchit==2) +#endif + if (searchit >= 1 && yp > (4<<8) && (searchy >= lwall[searchx] && searchy < swall[searchx])) + { + int32_t const xdsiz = divscale19(xdimenscale,yp); + int32_t const xv = mulscale16(nxrepeat,xyaspect); -#ifdef HIGH_PRECISION_SPRITE - float const cc = ((1<<19) * fxdimen * (float)yxaspect) * (1.f/320.f); - float const loopcc = ((cstat&8) ? -1.f : 1.f) * (float(1<<30) * float(1<<24)) / float(yspan * tspr->yrepeat); + int32_t const xspan = ((B_LITTLE32(longptr[0]) + B_LITTLE32(longptr[1])) >> 1); + int32_t const yspan = B_LITTLE32(longptr[2]); - float hplcf = cc / sy1; - float hincf[4] = { idiv ? (cc / sy2 - hplcf) / idiv : 0 }; + vec2_t const siz = { mulscale_triple30(xdsiz, xv, xspan), mulscale_triple30(xdsiz, nyrepeat, yspan) }; -#ifdef CLASSIC_SLICE_BY_4 - hincf[1] = hincf[0] * 2.f; - hincf[2] = hincf[0] * 3.f; - hincf[3] = hincf[0] * 4.f; -#endif // CLASSIC_SLICE_BY_4 -#endif // HIGH_PRECISION_SPRITE -#ifdef CLASSIC_SLICE_BY_4 - hinc[1] = hinc[0]<<1; - hinc[2] = hinc[0]*3; - hinc[3] = hinc[0]<<2; -#endif - i = sx1; + //Watch out for divscale overflow + if (((xspan>>11) < siz.x) && (yspan < (siz.y>>1))) + { + x1 = xb-(siz.x>>1); + if (xspan&1) x1 += mulscale31(xdsiz,xv); //Odd xspans + i = mulscale30(xdsiz,xv*off.x); + if ((cstat&4) == 0) x1 -= i; else x1 += i; -#ifdef CLASSIC_SLICE_BY_4 - for (; i<=sx2-4; i+=4) - { - swall[i] = (krecipasm(hplc)<<2); - swall[i+1] = (krecipasm(hplc+hinc[0])<<2); - swall[i+2] = (krecipasm(hplc+hinc[1])<<2); - swall[i+3] = (krecipasm(hplc+hinc[2])<<2); - hplc += hinc[3]; -#ifdef HIGH_PRECISION_SPRITE - swallf[i] = loopcc/hplcf; - swallf[i+1] = loopcc/(hplcf+hincf[0]); - swallf[i+2] = loopcc/(hplcf+hincf[1]); - swallf[i+3] = loopcc/(hplcf+hincf[2]); - hplcf += hincf[3]; -#endif // HIGH_PRECISION_SPRITE - } -#endif // CLASSIC_SLICE_BY_4 - - for (; i<=sx2; i++) - { - swall[i] = (krecipasm(hplc)<<2); - hplc += hinc[0]; -#ifdef HIGH_PRECISION_SPRITE - swallf[i] = loopcc/hplcf; - hplcf += hincf[0]; -#endif - } - - for (i=smostwallcnt-1; i>=0; i--) - { - j = smostwall[i]; - - if (xb1[j] > sx2 || xb2[j] < sx1) - continue; + y1 = mulscale16(tspr->z-globalposz,xdsiz); - int32_t dalx2 = xb1[j]; - int32_t darx2 = xb2[j]; + if (!(cstat & 128)) + y1 -= mulscale16(mulscale22(B_LITTLE32(longptr[5]), nyrepeat), xdsiz); + //y1 -= mulscale30(xdsiz,nyrepeat*yoff); + y1 += (globalhoriz<<8)-siz.y; + //if (cstat&128) //Already fixed up above + y1 += (siz.y>>1); - if (max(sy1,sy2) > min(yb1[j],yb2[j])) - { - if (min(sy1,sy2) > max(yb1[j],yb2[j])) - { - x = INT32_MIN; - } - else + x2 = x1+siz.x-1; + y2 = y1+siz.y-1; + if ((y1|255) < (y2|255) && searchx >= (x1>>8)+1 && searchx <= (x2>>8)) { - x = thewall[j]; xp1 = wall[x].x; yp1 = wall[x].y; - x = wall[x].point2; xp2 = wall[x].x; yp2 = wall[x].y; + int32_t startum, startdm; - z1 = (xp2-xp1)*(y1-yp1) - (yp2-yp1)*(x1-xp1); - z2 = (xp2-xp1)*(y2-yp1) - (yp2-yp1)*(x2-xp1); - if ((z1 == 0) | (z2 == 0)) - { - if ((xp2-xp1)*(tspr->y-yp1) == (tspr->x-xp1)*(yp2-yp1)) - { - if (wall[thewall[j]].nextsector == tspr->sectnum) - x = INT32_MIN; - else - x = INT32_MAX; - } - else - x = (z1+z2); - } - else if ((z1^z2) >= 0) - x = (z1+z2); + if ((sec->ceilingstat&3) == 0) + startum = globalhoriz+mulscale24(xdsiz,sec->ceilingz-globalposz)-1; else - { - z1 = (x2-x1)*(yp1-y1) - (y2-y1)*(xp1-x1); - z2 = (x2-x1)*(yp2-y1) - (y2-y1)*(xp2-x1); - - if (((z1^z2) >= 0) | (z1 == 0) | (z2 == 0)) - x = -(z1+z2); - else - { - if ((xp2-xp1)*(tspr->y-yp1) == (tspr->x-xp1)*(yp2-yp1)) - { - if (wall[thewall[j]].nextsector == tspr->sectnum) - x = INT32_MIN; - else - x = INT32_MAX; - } - else - { - //INTERSECTION! - x = (xp1-globalposx) + scale(xp2-xp1,z1,z1-z2); - y = (yp1-globalposy) + scale(yp2-yp1,z1,z1-z2); - - yp1 = dmulscale14(x,cosviewingrangeglobalang,y,sinviewingrangeglobalang); - - if (yp1 > 0) - { - xp1 = dmulscale14(y,cosglobalang,-x,singlobalang); - - x = halfxdimen + scale(xp1,halfxdimen,yp1); - if (xp1 >= 0) x++; //Fix for SIGNED divide - - if (z1 < 0) - { if (dalx2 < x) dalx2 = x; } - else - { if (darx2 > x) darx2 = x; } - x = INT32_MIN+1; - } - else - x = INT32_MAX; - } - } - } - } + startum = 0; - if (x < 0) - { - if (dalx2 < sx1) dalx2 = sx1; - if (darx2 > sx2) darx2 = sx2; + if ((sec->floorstat&3) == 0) + startdm = globalhoriz+mulscale24(xdsiz,sec->floorz-globalposz)+1; + else + startdm = INT32_MAX; - switch (smostwalltype[i]) + //sprite + if (searchy >= max(startum,(y1>>8)) && searchy < min(startdm,(y2>>8))) { - case 0: - if (dalx2 <= darx2) - { - if ((dalx2 == sx1) && (darx2 == sx2)) return; - //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); - for (k=dalx2; k<=darx2; k++) dwall[k] = 0; - } - break; - case 1: - k = smoststart[i] - xb1[j]; - x = dalx2; -#ifdef CLASSIC_SLICE_BY_4 - for (; x<=darx2-2; x+=2) - { - if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; - if (smost[k+x+1] > uwall[x+1]) uwall[x+1] = smost[k+x+1]; - } -#endif - for (; x<=darx2; x++) - if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; - break; - case 2: - k = smoststart[i] - xb1[j]; - x = dalx2; -#ifdef CLASSIC_SLICE_BY_4 - for (; x<=darx2-4; x+=4) - { - if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; - if (smost[k+x+1] < dwall[x+1]) dwall[x+1] = smost[k+x+1]; - if (smost[k+x+2] < dwall[x+2]) dwall[x+2] = smost[k+x+2]; - if (smost[k+x+3] < dwall[x+3]) dwall[x+3] = smost[k+x+3]; - } -#endif - for (; x<=darx2; x++) - if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; - break; + searchsector = sectnum; searchwall = spritenum; + searchstat = 3; searchit = 1; } } } } - //sprite -#ifdef YAX_ENABLE - if (yax_globallev==YAX_MAXDRAWS || searchit==2) -#endif - if (searchit >= 1 && (searchx >= sx1 && searchx <= sx2)) - if (searchy >= uwall[searchx] && searchy <= dwall[searchx]) - { - searchsector = sectnum; searchwall = spritenum; - searchstat = 3; searchit = 1; - } + x = tspr->x + spriteext[spritenum].mdposition_offset.x; + y = tspr->y + spriteext[spritenum].mdposition_offset.y; + z = tspr->z + spriteext[spritenum].mdposition_offset.z; - drawing_sprite = 1; + i = (int32_t)tspr->ang+1536; + i += spriteext[spritenum].mdangoff; - if ((cstat&2) == 0) - maskwallscan(sx1,sx2, (cstat&8)==0); - else - transmaskwallscan(sx1,sx2, (cstat&8)==0); + const int32_t ceilingz = (sec->ceilingstat&3) == 0 ? sec->ceilingz : INT32_MIN; + const int32_t floorz = (sec->floorstat&3) == 0 ? sec->floorz : INT32_MAX; - drawing_sprite = 0; - globalht = nullptr; + classicDrawVoxel(x,y,z,i,daxrepeat,(int32_t)tspr->yrepeat,vtilenum, + tspr->shade,tspr->pal,lwall,swall,tspr->cstat,tsprflags,floorz,ceilingz); } - else if ((cstat&48) == 32) + else if ((cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FACING) { - if ((cstat&64) != 0) - if ((globalposz > tspriteGetZOfSlope(tspr, globalposx, globalposy)) == ((cstat&8)==0)) - return; + int32_t startum, startdm; + int32_t linum, linuminc; - if ((cstat&4) > 0) off.x = -off.x; - if ((cstat&8) > 0) off.y = -off.y; - vec2_16_t span = tilesiz[tilenum]; - const int32_t ratio = nsqrtasm(slope * slope + 16777216); +draw_as_face_sprite: + if (yp <= (4<<8)) return; - //Rotate center point - dax = tspr->x-globalposx; - day = tspr->y-globalposy; - const int32_t cz = dmulscale10(cosglobalang,dax,singlobalang,day); - const int32_t cx = dmulscale10(cosglobalang,day,-singlobalang,dax); + int const isiz = divscale19(xdimenscale,yp); + int const xv = mulscale16(((int32_t)tspr->xrepeat)<<16,xyaspect); + vec2_16_t const span = tilesiz[tilenum]; + vec2_t const siz = { mulscale30(isiz, xv * span.x), mulscale14(isiz, tspr->yrepeat * span.y) }; - //Get top-left corner - int32_t const cosang = dmulscale14(sintable[(tspr->ang+512)&2047], cosglobalang, sintable[tspr->ang&2047], singlobalang); - int32_t const sinang = dmulscale14(sintable[(tspr->ang+512)&2047], -singlobalang, sintable[tspr->ang&2047], cosglobalang); - dax = (((span.x>>1)+off.x)*tspr->xrepeat)<<8; - day = divscale20(((span.y>>1)+off.y)*tspr->yrepeat,ratio); - rzi[0] = cz+dmulscale20(sinang,dax,cosang,day); - rxi[0] = cx+dmulscale20(sinang,day,-cosang,dax); + if (/*EDUKE32_PREDICT_FALSE*/((span.x>>11) >= siz.x || span.y >= (siz.y>>1))) + return; //Watch out for divscale overflow - //Get other 3 corners - dax = (span.x*tspr->xrepeat)<<8; - day = divscale20(span.y*tspr->yrepeat,ratio); - rzi[1] = rzi[0]-mulscale20(sinang,dax); - rxi[1] = rxi[0]+mulscale20(cosang,dax); - dax = -mulscale20(cosang,day); - day = -mulscale20(sinang,day); - rzi[2] = rzi[1]+dax; rxi[2] = rxi[1]+day; - rzi[3] = rzi[0]+dax; rxi[3] = rxi[0]+day; + vec2_16_t upscale = {}; + tileLoadScaled(tilenum, &upscale); - float sgzd = 0, sgzx = 0, sgz = 0, sdaz = 0; - vec2f_t sg_f = {}, sg_f2 = {}; - vec2_t sg1 = {}; + x1 = xb-(siz.x>>1); + if (span.x&1) x1 += mulscale31(isiz,xv); //Odd xspans + i = mulscale30(isiz,xv*off.x); + if ((cstat&4) == 0) x1 -= i; else x1 += i; - if (slope != 0) + y1 = mulscale16(tspr->z-globalposz,isiz); + y1 -= mulscale14(isiz,tspr->yrepeat*off.y); + y1 += (globalhoriz<<8)-siz.y; + if (cstat&128) { - int daz = 0; - float const fslope = (float)slope; - float const fsinang = (float)sinang; - float const fcosang = (float)cosang; + y1 += (siz.y>>1); + if (span.y&1) y1 += mulscale15(isiz,tspr->yrepeat); //Odd yspans + } - for (i = 0; i < 4; i++) - { - int const j = dmulscale8(-sinang, rxi[i]-cx, - -cosang, rzi[i]-cz); - int const z = (tspr->z + mulscale18(slope, j) - globalposz); + x2 = x1+siz.x-1; + y2 = y1+siz.y-1; + if ((y1|255) >= (y2|255)) return; - if (i == 0) - daz = z; + int32_t lx = (x1>>8)+1; if (lx < 0) lx = 0; + int32_t rx = (x2>>8); if (rx >= xdimen) rx = xdimen-1; + if (lx > rx) return; - ryi[i] = scale(z,yxaspect,320<<8); - } - - float const fi = (0-halfxdimen)*xdimenrecip; - sg_f = { fcosang*float(xdimenrecip)*(1.f/524288.f), fsinang*float(xdimenrecip)*(1.f/524288.f) }; - sg_f2 = { -fsinang*float(viewingrangerecip)*(1.f/4096.f) + fcosang*fi*(1.f/134217728.f), - fcosang*float(viewingrangerecip)*(1.f/4096.f) + fsinang*fi*(1.f/134217728.f) }; - - sgzd = xdimscale*512.f; - sgzx = sg_f2.y*fslope*(1.f/256.f) + (1-globalhoriz)*sgzd*(1.f/1024.f); - sgz = sg_f.y*fslope*(1.f/65536.f); - - float const fx = 64.f/float(tspr->xrepeat); - float const fy = 64.f/float(tspr->yrepeat) * float(ratio) * (1.f / 4096.f); - - sg_f.x *= fx; - sg_f.y *= fy; - sg_f2.x *= fx; - sg_f2.y *= fy; - - sg1 = { divscale6(dmulscale10(rxi[0], -cosang, rzi[0], sinang), tspr->xrepeat), - mulscale12(divscale6(dmulscale10(rxi[0], sinang, rzi[0], cosang), tspr->yrepeat), ratio) }; - - if (cstat & 4) - { - sg1.x = -sg1.x; - sg_f2.x = -sg_f2.x; - sg_f.x = -sg_f.x; - } + startum = ((sec->ceilingstat&3) == 0) ? globalhoriz+mulscale24(isiz,sec->ceilingz-globalposz)-1 : 0; + startdm = ((sec->floorstat&3) == 0) ? globalhoriz+mulscale24(isiz,sec->floorz-globalposz)+1 : INT32_MAX; - sdaz = fslope*(fsinang*float(rxi[0])+fcosang*float(rzi[0]))*(1.f/262144.f) + float(daz)*256.f; - sg_f = { (sg_f.x*sdaz)*(1.f/268435456.f), (sg_f.y*-sdaz)*(1.f/268435456.f) }; - sg_f2 = { (sg_f2.x*sdaz)*(1.f/1048576.f), (sg_f2.y*-sdaz)*(1.f/1048576.f) }; + if ((y1>>8) > startum) startum = (y1>>8); + if ((y2>>8) < startdm) startdm = (y2>>8); - rzi[0] = mulscale16(rzi[0], viewingrange); - rzi[1] = mulscale16(rzi[1], viewingrange); - rzi[2] = mulscale16(rzi[2], viewingrange); - rzi[3] = mulscale16(rzi[3], viewingrange); + if (startum < -32768) startum = -32768; + if (startdm > 32767) startdm = 32767; + if (startum >= startdm) return; - //If ceilsprite is above you, reverse order of points - if (globalposz > tspriteGetZOfSlope(tspr, globalposx, globalposy)) - { - i = rxi[1]; rxi[1] = rxi[3]; rxi[3] = i; - i = rzi[1]; rzi[1] = rzi[3]; rzi[3] = i; - i = ryi[1]; ryi[1] = ryi[3]; ryi[3] = i; - } + if ((cstat&4) == 0) + { + linuminc = divscale24(span.x<z-globalposz),yxaspect,320<<8); - if (ryi[0] == 0) return; - ryi[1] = ryi[2] = ryi[3] = ryi[0]; + linuminc = -divscale24(span.x< 0) + swaplong(&y1, &y2); - dax = rzi[z1]-rzi[z]; day = rxi[z1]-rxi[z]; - int32_t bot = dmulscale8(dax,dax,day,day); - if ((klabs(dax)>>13) >= bot || (klabs(day)>>13) >= bot) - return; - globalx1 = divscale18(dax,bot); - globalx2 = divscale18(day,bot); + x = lx; +#ifdef CLASSIC_SLICE_BY_4 + for (; x<=rx-4; x+=4) + { + uwall[x] = max(startumost[windowxy1.x+x]-windowxy1.y, startum); + uwall[x+1] = max(startumost[windowxy1.x+x+1]-windowxy1.y, startum); + uwall[x+2] = max(startumost[windowxy1.x+x+2]-windowxy1.y, startum); + uwall[x+3] = max(startumost[windowxy1.x+x+3]-windowxy1.y, startum); - dax = rzi[z2]-rzi[z]; day = rxi[z2]-rxi[z]; - bot = dmulscale8(dax,dax,day,day); - if ((klabs(dax)>>13) >= bot || (klabs(day)>>13) >= bot) - return; - globaly1 = divscale18(dax,bot); - globaly2 = divscale18(day,bot); + dwall[x] = min(startdmost[windowxy1.x+x]-windowxy1.y, startdm); + dwall[x+1] = min(startdmost[windowxy1.x+x+1]-windowxy1.y, startdm); + dwall[x+2] = min(startdmost[windowxy1.x+x+2]-windowxy1.y, startdm); + dwall[x+3] = min(startdmost[windowxy1.x+x+3]-windowxy1.y, startdm); + } +#endif + for (; x<=rx; x++) + { + uwall[x] = max(startumost[windowxy1.x+x]-windowxy1.y,startum); + dwall[x] = min(startdmost[windowxy1.x+x]-windowxy1.y,startdm); + } - //Calculate globals for hline texture mapping function - globalxpanning = rxi[z]; - globalypanning = rzi[z]; - globalzd = decltype(globalzd)(ryi[z]); + int32_t daclip = 0; + for (i=smostwallcnt-1; i>=0; i--) + { + if (smostwalltype[i]&daclip) continue; + j = smostwall[i]; + if ((xb1[j] > rx) || (xb2[j] < lx)) continue; + if ((yp <= yb1[j]) && (yp <= yb2[j])) continue; + if (spritewallfront(tspr,(int32_t)thewall[j]) && ((yp <= yb1[j]) || (yp <= yb2[j]))) continue; - rzi[0] = mulscale16(rzi[0],viewingrange); - rzi[1] = mulscale16(rzi[1],viewingrange); - rzi[2] = mulscale16(rzi[2],viewingrange); - rzi[3] = mulscale16(rzi[3],viewingrange); + const int32_t dalx2 = max(xb1[j],lx); + const int32_t darx2 = min(xb2[j],rx); - if (ryi[0] < 0) //If ceilsprite is above you, reverse order of points + switch (smostwalltype[i]) { - i = rxi[1]; rxi[1] = rxi[3]; rxi[3] = i; - i = rzi[1]; rzi[1] = rzi[3]; rzi[3] = i; + case 0: + if (dalx2 <= darx2) + { + if ((dalx2 == lx) && (darx2 == rx)) return; + //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); + for (k=dalx2; k<=darx2; k++) dwall[k] = 0; + } + break; + case 1: + k = smoststart[i] - xb1[j]; + x = dalx2; +#ifdef CLASSIC_SLICE_BY_4 // ok, this one is really by 2 ;) + for (; x<=darx2-2; x+=2) + { + if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; + if (smost[k+x+1] > uwall[x+1]) uwall[x+1] = smost[k+x+1]; + } +#endif + for (; x<=darx2; x++) + if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; + if ((dalx2 == lx) && (darx2 == rx)) daclip |= 1; + break; + case 2: + k = smoststart[i] - xb1[j]; + x = dalx2; +#ifdef CLASSIC_SLICE_BY_4 + for (; x<=darx2-4; x+=4) + { + if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; + if (smost[k+x+1] < dwall[x+1]) dwall[x+1] = smost[k+x+1]; + if (smost[k+x+2] < dwall[x+2]) dwall[x+2] = smost[k+x+2]; + if (smost[k+x+3] < dwall[x+3]) dwall[x+3] = smost[k+x+3]; + } +#endif + for (; x<=darx2; x++) + if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; + if ((dalx2 == lx) && (darx2 == rx)) daclip |= 2; + break; } } - //Clip polygon in 3-space - int32_t npoints = 4; - - //Clip edge 1 - int32_t npoints2 = 0; - int64_t zzsgn = rxi[0]+rzi[0], zsgn; - for (z=0; z= dwall[rx]) { - zz = z+1; if (zz == npoints) zz = 0; - zsgn = zzsgn; zzsgn = rxi[zz]+rzi[zz]; - if (zsgn >= 0) - { - rxi2[npoints2] = rxi[z]; ryi2[npoints2] = ryi[z]; rzi2[npoints2] = rzi[z]; - npoints2++; - } - if ((zsgn^zzsgn) < 0) - { - int64_t t = divscale64(zsgn,zsgn-zzsgn, 30); - rxi2[npoints2] = rxi[z] + int32_t((t * (rxi[zz]-rxi[z])) >> 30); - ryi2[npoints2] = ryi[z] + int32_t((t * (ryi[zz]-ryi[z])) >> 30); - rzi2[npoints2] = rzi[z] + int32_t((t * (rzi[zz]-rzi[z])) >> 30); - npoints2++; - } + for (x=lx; x= 1 && (searchx >= lx && searchx <= rx)) + if (searchy >= uwall[searchx] && searchy < dwall[searchx]) { - int64_t t = divscale64(zsgn,zsgn-zzsgn, 30); - rxi[npoints] = rxi2[z] + int32_t((t * (rxi2[zz]-rxi2[z])) >> 30); - ryi[npoints] = ryi2[z] + int32_t((t * (ryi2[zz]-ryi2[z])) >> 30); - rzi[npoints] = rzi2[z] + int32_t((t * (rzi2[zz]-rzi2[z])) >> 30); - npoints++; + searchsector = sectnum; searchwall = spritenum; + searchstat = 3; searchit = 1; } - } - if (npoints <= 2) return; - //Clip edge 3 - npoints2 = 0; - zzsgn = ryi[0]*int64_t(halfxdimen) + (rzi[0]*int64_t(globalhoriz-0)); - for (z=0; z= 0) - { - rxi2[npoints2] = rxi[z]; - ryi2[npoints2] = ryi[z]; - rzi2[npoints2] = rzi[z]; - npoints2++; - } - if ((zsgn^zzsgn) < 0) - { - int64_t t = divscale64(zsgn,zsgn-zzsgn, 30); - rxi2[npoints2] = rxi[z] + int32_t((t * (rxi[zz]-rxi[z])) >> 30); - ryi2[npoints2] = ryi[z] + int32_t((t * (ryi[zz]-ryi[z])) >> 30); - rzi2[npoints2] = rzi[z] + int32_t((t * (rzi[zz]-rzi[z])) >> 30); - npoints2++; - } +#ifdef HIGH_PRECISION_SPRITE + union { float f; int32_t i; } sw = { + // initialize the float of the union + ((cstat&8) ? -1 : 1) + * (float)yp * xdimscale + * (1<<(22-19)) / (span.y*tspr->yrepeat) + }; + + clearbuf(&swallf[lx], rx-lx+1, sw.i); +#endif } - if (npoints2 <= 2) return; - //Clip edge 4 - npoints = 0; - zzsgn = ryi2[0]*int64_t(halfxdimen) + (rzi2[0]*int64_t(globalhoriz-ydimen)); - for (z=0; z (xdimen<<16)) xsi[z] = (xdimen<<16); - if (ysi[z] < ((int32_t)0<<16)) ysi[z] = ((int32_t)0<<16); - if (ysi[z] > ((int32_t)ydimen<<16)) ysi[z] = ((int32_t)ydimen<<16); - if (xsi[z] < lmax) lmax = xsi[z], lpoint = z; - if (xsi[z] > rmax) rmax = xsi[z], rpoint = z; - } - - //Get uwall arrays - for (z=lpoint; z!=rpoint; z=zz) - { - zz = z+1; if (zz == npoints) zz = 0; + drawing_sprite = 1; - dax1 = ((xsi[z]+65535)>>16); - dax2 = ((xsi[zz]+65535)>>16); - if (dax2 > dax1) - { - int32_t yinc = divscale16(ysi[zz]-ysi[z],xsi[zz]-xsi[z]); - y = ysi[z] + mulscale16((dax1<<16)-xsi[z],yinc); - qinterpolatedown16short((intptr_t)(&uwall[dax1]),dax2-dax1,y,yinc); - } - } + if ((cstat&2) == 0) + maskwallscan(lx,rx, (cstat&8)==0); + else + transmaskwallscan(lx,rx, (cstat&8)==0); - //Get dwall arrays - for (; z!=lpoint; z=zz) - { - zz = z+1; if (zz == npoints) zz = 0; + drawing_sprite = 0; + globalht = nullptr; + } + else if ((cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL) + { + const int32_t xspan = tilesiz[tilenum].x; + const int32_t yspan = tilesiz[tilenum].y; + const int32_t xv = tspr->xrepeat*sintable[(tspr->ang+2560+1536)&2047]; + const int32_t yv = tspr->xrepeat*sintable[(tspr->ang+2048+1536)&2047]; - dax1 = ((xsi[zz]+65535)>>16); - dax2 = ((xsi[z]+65535)>>16); - if (dax2 > dax1) - { - int32_t yinc = divscale16(ysi[zz]-ysi[z],xsi[zz]-xsi[z]); - y = ysi[zz] + mulscale16((dax1<<16)-xsi[zz],yinc); - qinterpolatedown16short((intptr_t)(&dwall[dax1]),dax2-dax1,y,yinc); - } - } + if ((cstat&4) > 0) off.x = -off.x; + if ((cstat&8) > 0) off.y = -off.y; + i = (xspan>>1) + off.x; + x1 = tspr->x-globalposx-mulscale16(xv,i); x2 = x1+mulscale16(xv,xspan); + y1 = tspr->y-globalposy-mulscale16(yv,i); y2 = y1+mulscale16(yv,xspan); - const int32_t lx = ((lmax+65535)>>16); - const int32_t rx = min(((rmax+65535)>>16), xdim-1); - // min(): OOB prevention. Simple test case: have a floor-aligned sprite - // to the right of the player. Slowly rotate right toward it. When it - // just becomes visible, the condition rx == xdim can occur. + vec2_t p1 = get_rel_coords(x1, y1); + vec2_t p2 = get_rel_coords(x2, y2); - // Don't pointlessly keep going. If the following condition holds, the - // ceilspritescan() at the end of our block would not draw any lines, - // and moreover may access uwall[] OOB (with x1==xdim). - if (rx-1 < lx) + if (p1.y <= 0 && p2.y <= 0) return; - for (x=lx; x<=rx; x++) - { - uwall[x] = max(uwall[x],startumost[x+windowxy1.x]-windowxy1.y); - dwall[x] = min(dwall[x],startdmost[x+windowxy1.x]-windowxy1.y); - } + x1 += globalposx; y1 += globalposy; + x2 += globalposx; y2 += globalposy; - //Additional uwall/dwall clipping goes here - for (i=smostwallcnt-1; i>=0; i--) + int32_t swapped = 0; + if (dmulscale32(p1.x, p2.y, -p2.x, p1.y) >= 0) // If wall's NOT facing you { - j = smostwall[i]; - if ((xb1[j] > rx) || (xb2[j] < lx)) continue; - if ((yp <= yb1[j]) && (yp <= yb2[j])) continue; - - //if (spritewallfront(tspr,thewall[j]) == 0) - x = thewall[j]; xp1 = wall[x].x; yp1 = wall[x].y; - x = wall[x].point2; xp2 = wall[x].x; yp2 = wall[x].y; - x = (xp2-xp1)*(tspr->y-yp1)-(tspr->x-xp1)*(yp2-yp1); - if ((yp > yb1[j]) && (yp > yb2[j])) x = -1; - if ((x >= 0) && ((x != 0) || (wall[thewall[j]].nextsector != tspr->sectnum))) continue; - - const int32_t dalx2 = max(xb1[j],lx); - const int32_t darx2 = min(xb2[j],rx); + if ((cstat&64) != 0) + return; - switch (smostwalltype[i]) - { - case 0: - if (dalx2 <= darx2) - { - if ((dalx2 == lx) && (darx2 == rx)) return; - //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); - for (x=dalx2; x<=darx2; x++) dwall[x] = 0; - } - break; - case 1: - k = smoststart[i] - xb1[j]; - for (x=dalx2; x<=darx2; x++) - if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; - break; - case 2: - k = smoststart[i] - xb1[j]; - for (x=dalx2; x<=darx2; x++) - if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; - break; - } + const vec2_t pt = p2; + p2 = p1; + p1 = pt; + i = x1, x1 = x2, x2 = i; + i = y1, y1 = y2, y2 = i; + swapped = 1; } - //sprite -#ifdef YAX_ENABLE - if (yax_globallev==YAX_MAXDRAWS || searchit==2) -#endif - if (searchit >= 1 && (searchx >= lx && searchx <= rx)) - if (searchy >= uwall[searchx] && searchy <= dwall[searchx]) - { - searchsector = sectnum; searchwall = spritenum; - searchstat = 3; searchit = 1; - } - - globalorientation = cstat; - globalpicnum = tilenum; - if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; - - setgotpic(globalpicnum); + int32_t sx1, sx2, sy1, sy2; + if (!get_screen_coords(p1, p2, &sx1, &sy1, &sx2, &sy2)) + return; vec2_16_t upscale = {}; - globalbufplc = tileLoadScaled(globalpicnum, &upscale); + tileLoadScaled(tilenum, &upscale); - if (slope != 0) - { - x = picsiz[globalpicnum]; y = ((x>>4)&15); x &= 15; - x += upscale.x; - y += upscale.y; - sg1 = { divscale20(sg1.x, span.x) >> 16, divscale20(sg1.y, span.y) >> 16 }; - vec2f_t const tmp = { 256.f/float(span.x), 256.f/float(span.y) }; - sg_f2.x *= tmp.x; - sg_f2.y *= tmp.y; - sg_f.x *= tmp.x; - sg_f.y *= tmp.y; - span.x <<= upscale.x; - span.y <<= upscale.y; - int const ispow2 = (pow2long[x]==span.x && pow2long[y]==span.y); + const int32_t topinc = -mulscale10(p1.y,xspan<>8; + int32_t bot = mulscale11(p1.x-p2.x,xdimen) + mulscale2(sx1-halfxdimen,botinc); - //asm1 = -(globalzd>>(16-BITSOFPRECISION)); -#define LINTERPSIZ 4 - float const bzinc = -sgzd*(1.f/65536.f) * (1<visibility != 0) ? mulscale4(globalhisibility, (uint8_t)(sec->visibility+16)) : globalhisibility; - globvis = ((((int64_t)(vis*sdaz)) >> 13) * xdimscale) >> 16; + j = sx2+3; + z = divscale10(top,bot); + lwall[sx1] = (z>>8); + for (x=sx1+4; x<=j; x+=4) + { + top += topinc; bot += botinc; + zz = z; z = divscale10(top, bot); + i = ((z+zz)>>1); + lwall[x-3] = ((i+zz)>>9); + lwall[x-2] = (i>>8); + lwall[x-1] = ((i+z)>>9); + lwall[x] = (z>>8); + } - intptr_t fj = FP_OFF(palookup[globalpal]); + if (lwall[sx1] < 0) lwall[sx1] = 0; + if (lwall[sx2] >= (xspan<0)) > 0) + { + j = (xspan< 0) ? (4 << 15) : ((16380 - ydimen) << 15); // JBF: was 2044 - int32_t y1 = uwall[lx]; + if ((sec->ceilingstat&1) == 0 && z1 < sec->ceilingz) + z1 = sec->ceilingz; + if ((sec->floorstat&1) == 0 && z2 > sec->floorz) + z2 = sec->floorz; - int32_t m1 = Blrintf((y1*sgzd)*(1.f/65536.f) + sgzx*(1.f/64.f)); - //Avoid visibility overflow by crossing horizon - m1 += klabs(l); - int32_t m2 = m1+l; - int32_t shy1 = y1+(shoffs>>15); - int32_t shy2; - if ((unsigned)shy1 >= SLOPALOOKUPSIZ-1) - { - LOG_F(ERROR, "%s:%d: slopalookup[%" PRId32 "] overflow drawing sprite %d!", EDUKE32_FUNCTION, __LINE__, shy1, spritenum); - return; - } + xb1[MAXWALLSB-1] = sx1; + xb2[MAXWALLSB-1] = sx2; + yb1[MAXWALLSB-1] = sy1; + yb2[MAXWALLSB-1] = sy2; + owallmost(uwall, MAXWALLSB-1, z1-globalposz); + owallmost(dwall, MAXWALLSB-1, z2-globalposz); - intptr_t *mptr1 = &slopalookup[shy1]; intptr_t *mptr2 = mptr1+1; - sg_f2.x += sg_f.x * lx; - sg_f2.y += sg_f.y * lx; - sgzx += sgz * lx; - shoffs += shinc *lx; + int32_t hplc = divscale19(xdimenscale,sy1); + const int32_t hplc2 = divscale19(xdimenscale,sy2); + const int32_t idiv = sx2-sx1; + int32_t hinc[4] = { idiv ? tabledivide32(hplc2-hplc, idiv) : 0 }; - for (int x=lx; x>15); - shy2 = y2+(shoffs>>15); +#ifdef HIGH_PRECISION_SPRITE + float const cc = ((1<<19) * fxdimen * (float)yxaspect) * (1.f/320.f); + float const loopcc = ((cstat&8) ? -1.f : 1.f) * (float(1<<30) * float(1<<24)) / float(yspan * tspr->yrepeat); + + float hplcf = cc / sy1; + float hincf[4] = { idiv ? (cc / sy2 - hplcf) / idiv : 0 }; + +#ifdef CLASSIC_SLICE_BY_4 + hincf[1] = hincf[0] * 2.f; + hincf[2] = hincf[0] * 3.f; + hincf[3] = hincf[0] * 4.f; +#endif // CLASSIC_SLICE_BY_4 +#endif // HIGH_PRECISION_SPRITE +#ifdef CLASSIC_SLICE_BY_4 + hinc[1] = hinc[0]<<1; + hinc[2] = hinc[0]*3; + hinc[3] = hinc[0]<<2; +#endif + i = sx1; + +#ifdef CLASSIC_SLICE_BY_4 + for (; i<=sx2-4; i+=4) + { + swall[i] = (krecipasm(hplc)<<2); + swall[i+1] = (krecipasm(hplc+hinc[0])<<2); + swall[i+2] = (krecipasm(hplc+hinc[1])<<2); + swall[i+3] = (krecipasm(hplc+hinc[2])<<2); + hplc += hinc[3]; +#ifdef HIGH_PRECISION_SPRITE + swallf[i] = loopcc/hplcf; + swallf[i+1] = loopcc/(hplcf+hincf[0]); + swallf[i+2] = loopcc/(hplcf+hincf[1]); + swallf[i+3] = loopcc/(hplcf+hincf[2]); + hplcf += hincf[3]; +#endif // HIGH_PRECISION_SPRITE + } +#endif // CLASSIC_SLICE_BY_4 + + for (; i<=sx2; i++) + { + swall[i] = (krecipasm(hplc)<<2); + hplc += hinc[0]; +#ifdef HIGH_PRECISION_SPRITE + swallf[i] = loopcc/hplcf; + hplcf += hincf[0]; +#endif + } + + for (i=smostwallcnt-1; i>=0; i--) + { + j = smostwall[i]; + + if (xb1[j] > sx2 || xb2[j] < sx1) + continue; + + int32_t dalx2 = xb1[j]; + int32_t darx2 = xb2[j]; + + if (max(sy1,sy2) > min(yb1[j],yb2[j])) + { + if (min(sy1,sy2) > max(yb1[j],yb2[j])) + { + x = INT32_MIN; + } + else + { + x = thewall[j]; xp1 = wall[x].x; yp1 = wall[x].y; + x = wall[x].point2; xp2 = wall[x].x; yp2 = wall[x].y; + + z1 = (xp2-xp1)*(y1-yp1) - (yp2-yp1)*(x1-xp1); + z2 = (xp2-xp1)*(y2-yp1) - (yp2-yp1)*(x2-xp1); + if ((z1 == 0) | (z2 == 0)) + { + if ((xp2-xp1)*(tspr->y-yp1) == (tspr->x-xp1)*(yp2-yp1)) + { + if (wall[thewall[j]].nextsector == tspr->sectnum) + x = INT32_MIN; + else + x = INT32_MAX; + } + else + x = (z1+z2); + } + else if ((z1^z2) >= 0) + x = (z1+z2); + else + { + z1 = (x2-x1)*(yp1-y1) - (y2-y1)*(xp1-x1); + z2 = (x2-x1)*(yp2-y1) - (y2-y1)*(xp2-x1); + + if (((z1^z2) >= 0) | (z1 == 0) | (z2 == 0)) + x = -(z1+z2); + else + { + if ((xp2-xp1)*(tspr->y-yp1) == (tspr->x-xp1)*(yp2-yp1)) + { + if (wall[thewall[j]].nextsector == tspr->sectnum) + x = INT32_MIN; + else + x = INT32_MAX; + } + else + { + //INTERSECTION! + x = (xp1-globalposx) + scale(xp2-xp1,z1,z1-z2); + y = (yp1-globalposy) + scale(yp2-yp1,z1,z1-z2); + + yp1 = dmulscale14(x,cosviewingrangeglobalang,y,sinviewingrangeglobalang); + + if (yp1 > 0) + { + xp1 = dmulscale14(y,cosglobalang,-x,singlobalang); + + x = halfxdimen + scale(xp1,halfxdimen,yp1); + if (xp1 >= 0) x++; //Fix for SIGNED divide + + if (z1 < 0) + { if (dalx2 < x) dalx2 = x; } + else + { if (darx2 > x) darx2 = x; } + x = INT32_MIN+1; + } + else + x = INT32_MAX; + } + } + } + } + + if (x < 0) + { + if (dalx2 < sx1) dalx2 = sx1; + if (darx2 > sx2) darx2 = sx2; + + switch (smostwalltype[i]) + { + case 0: + if (dalx2 <= darx2) + { + if ((dalx2 == sx1) && (darx2 == sx2)) return; + //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); + for (k=dalx2; k<=darx2; k++) dwall[k] = 0; + } + break; + case 1: + k = smoststart[i] - xb1[j]; + x = dalx2; +#ifdef CLASSIC_SLICE_BY_4 + for (; x<=darx2-2; x+=2) + { + if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; + if (smost[k+x+1] > uwall[x+1]) uwall[x+1] = smost[k+x+1]; + } +#endif + for (; x<=darx2; x++) + if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; + break; + case 2: + k = smoststart[i] - xb1[j]; + x = dalx2; +#ifdef CLASSIC_SLICE_BY_4 + for (; x<=darx2-4; x+=4) + { + if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; + if (smost[k+x+1] < dwall[x+1]) dwall[x+1] = smost[k+x+1]; + if (smost[k+x+2] < dwall[x+2]) dwall[x+2] = smost[k+x+2]; + if (smost[k+x+3] < dwall[x+3]) dwall[x+3] = smost[k+x+3]; + } +#endif + for (; x<=darx2; x++) + if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; + break; + } + } + } + } + + //sprite +#ifdef YAX_ENABLE + if (yax_globallev==YAX_MAXDRAWS || searchit==2) +#endif + if (searchit >= 1 && (searchx >= sx1 && searchx <= sx2)) + if (searchy >= uwall[searchx] && searchy <= dwall[searchx]) + { + searchsector = sectnum; searchwall = spritenum; + searchstat = 3; searchit = 1; + } + + drawing_sprite = 1; + + if ((cstat&2) == 0) + maskwallscan(sx1,sx2, (cstat&8)==0); + else + transmaskwallscan(sx1,sx2, (cstat&8)==0); + + drawing_sprite = 0; + globalht = nullptr; + } + else if ((cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) + { + if ((cstat&64) != 0) + if ((globalposz > tspriteGetZOfSlope(tspr, globalposx, globalposy)) == ((cstat&8)==0)) + return; + + if ((cstat&4) > 0) off.x = -off.x; + if ((cstat&8) > 0) off.y = -off.y; + vec2_16_t span = tilesiz[tilenum]; + const int32_t ratio = nsqrtasm(slope * slope + 16777216); + + //Rotate center point + dax = tspr->x-globalposx; + day = tspr->y-globalposy; + const int32_t cz = dmulscale10(cosglobalang,dax,singlobalang,day); + const int32_t cx = dmulscale10(cosglobalang,day,-singlobalang,dax); + + //Get top-left corner + int32_t const cosang = dmulscale14(sintable[(tspr->ang+512)&2047], cosglobalang, sintable[tspr->ang&2047], singlobalang); + int32_t const sinang = dmulscale14(sintable[(tspr->ang+512)&2047], -singlobalang, sintable[tspr->ang&2047], cosglobalang); + dax = (((span.x>>1)+off.x)*tspr->xrepeat)<<8; + day = divscale20(((span.y>>1)+off.y)*tspr->yrepeat,ratio); + rzi[0] = cz+dmulscale20(sinang,dax,cosang,day); + rxi[0] = cx+dmulscale20(sinang,day,-cosang,dax); + + //Get other 3 corners + dax = (span.x*tspr->xrepeat)<<8; + day = divscale20(span.y*tspr->yrepeat,ratio); + rzi[1] = rzi[0]-mulscale20(sinang,dax); + rxi[1] = rxi[0]+mulscale20(cosang,dax); + dax = -mulscale20(cosang,day); + day = -mulscale20(sinang,day); + rzi[2] = rzi[1]+dax; rxi[2] = rxi[1]+day; + rzi[3] = rzi[0]+dax; rxi[3] = rxi[0]+day; + + float sgzd = 0, sgzx = 0, sgz = 0, sdaz = 0; + vec2f_t sg_f = {}, sg_f2 = {}; + vec2_t sg1 = {}; + + if (slope != 0) + { + int daz = 0; + float const fslope = (float)slope; + float const fsinang = (float)sinang; + float const fcosang = (float)cosang; + + for (i = 0; i < 4; i++) + { + int const j = dmulscale8(-sinang, rxi[i]-cx, + -cosang, rzi[i]-cz); + int const z = (tspr->z + mulscale18(slope, j) - globalposz); + + if (i == 0) + daz = z; + + ryi[i] = scale(z,yxaspect,320<<8); + } + + float const fi = (0-halfxdimen)*xdimenrecip; + sg_f = { fcosang*float(xdimenrecip)*(1.f/524288.f), fsinang*float(xdimenrecip)*(1.f/524288.f) }; + sg_f2 = { -fsinang*float(viewingrangerecip)*(1.f/4096.f) + fcosang*fi*(1.f/134217728.f), + fcosang*float(viewingrangerecip)*(1.f/4096.f) + fsinang*fi*(1.f/134217728.f) }; + + sgzd = xdimscale*512.f; + sgzx = sg_f2.y*fslope*(1.f/256.f) + (1-globalhoriz)*sgzd*(1.f/1024.f); + sgz = sg_f.y*fslope*(1.f/65536.f); + + float const fx = 64.f/float(tspr->xrepeat); + float const fy = 64.f/float(tspr->yrepeat) * float(ratio) * (1.f / 4096.f); + + sg_f.x *= fx; + sg_f.y *= fy; + sg_f2.x *= fx; + sg_f2.y *= fy; + + sg1 = { divscale6(dmulscale10(rxi[0], -cosang, rzi[0], sinang), tspr->xrepeat), + mulscale12(divscale6(dmulscale10(rxi[0], sinang, rzi[0], cosang), tspr->yrepeat), ratio) }; + + if (cstat & 4) + { + sg1.x = -sg1.x; + sg_f2.x = -sg_f2.x; + sg_f.x = -sg_f.x; + } + + sdaz = fslope*(fsinang*float(rxi[0])+fcosang*float(rzi[0]))*(1.f/262144.f) + float(daz)*256.f; + sg_f = { (sg_f.x*sdaz)*(1.f/268435456.f), (sg_f.y*-sdaz)*(1.f/268435456.f) }; + sg_f2 = { (sg_f2.x*sdaz)*(1.f/1048576.f), (sg_f2.y*-sdaz)*(1.f/1048576.f) }; + + rzi[0] = mulscale16(rzi[0], viewingrange); + rzi[1] = mulscale16(rzi[1], viewingrange); + rzi[2] = mulscale16(rzi[2], viewingrange); + rzi[3] = mulscale16(rzi[3], viewingrange); + + //If ceilsprite is above you, reverse order of points + if (globalposz > tspriteGetZOfSlope(tspr, globalposx, globalposy)) + { + i = rxi[1]; rxi[1] = rxi[3]; rxi[3] = i; + i = rzi[1]; rzi[1] = rzi[3]; rzi[3] = i; + i = ryi[1]; ryi[1] = ryi[3]; ryi[3] = i; + } + } + else + { + //Put all points on same z + ryi[0] = scale((tspr->z-globalposz),yxaspect,320<<8); + if (ryi[0] == 0) return; + ryi[1] = ryi[2] = ryi[3] = ryi[0]; + + if ((cstat&4) == 0) + { z = 0; z1 = 1; z2 = 3; } + else + { z = 1; z1 = 0; z2 = 2; } + + dax = rzi[z1]-rzi[z]; day = rxi[z1]-rxi[z]; + int32_t bot = dmulscale8(dax,dax,day,day); + if ((klabs(dax)>>13) >= bot || (klabs(day)>>13) >= bot) + return; + globalx1 = divscale18(dax,bot); + globalx2 = divscale18(day,bot); + + dax = rzi[z2]-rzi[z]; day = rxi[z2]-rxi[z]; + bot = dmulscale8(dax,dax,day,day); + if ((klabs(dax)>>13) >= bot || (klabs(day)>>13) >= bot) + return; + globaly1 = divscale18(dax,bot); + globaly2 = divscale18(day,bot); + + //Calculate globals for hline texture mapping function + globalxpanning = rxi[z]; + globalypanning = rzi[z]; + globalzd = decltype(globalzd)(ryi[z]); + + rzi[0] = mulscale16(rzi[0],viewingrange); + rzi[1] = mulscale16(rzi[1],viewingrange); + rzi[2] = mulscale16(rzi[2],viewingrange); + rzi[3] = mulscale16(rzi[3],viewingrange); + + if (ryi[0] < 0) //If ceilsprite is above you, reverse order of points + { + i = rxi[1]; rxi[1] = rxi[3]; rxi[3] = i; + i = rzi[1]; rzi[1] = rzi[3]; rzi[3] = i; + } + } + + //Clip polygon in 3-space + int32_t npoints = 4; + + //Clip edge 1 + int32_t npoints2 = 0; + int64_t zzsgn = rxi[0]+rzi[0], zsgn; + for (z=0; z= 0) + { + rxi2[npoints2] = rxi[z]; ryi2[npoints2] = ryi[z]; rzi2[npoints2] = rzi[z]; + npoints2++; + } + if ((zsgn^zzsgn) < 0) + { + int64_t t = divscale64(zsgn,zsgn-zzsgn, 30); + rxi2[npoints2] = rxi[z] + int32_t((t * (rxi[zz]-rxi[z])) >> 30); + ryi2[npoints2] = ryi[z] + int32_t((t * (ryi[zz]-ryi[z])) >> 30); + rzi2[npoints2] = rzi[z] + int32_t((t * (rzi[zz]-rzi[z])) >> 30); + npoints2++; + } + } + if (npoints2 <= 2) return; + + //Clip edge 2 + npoints = 0; + zzsgn = rxi2[0]-rzi2[0]; + for (z=0; z> 30); + ryi[npoints] = ryi2[z] + int32_t((t * (ryi2[zz]-ryi2[z])) >> 30); + rzi[npoints] = rzi2[z] + int32_t((t * (rzi2[zz]-rzi2[z])) >> 30); + npoints++; + } + } + if (npoints <= 2) return; + + //Clip edge 3 + npoints2 = 0; + zzsgn = ryi[0]*int64_t(halfxdimen) + (rzi[0]*int64_t(globalhoriz-0)); + for (z=0; z= 0) + { + rxi2[npoints2] = rxi[z]; + ryi2[npoints2] = ryi[z]; + rzi2[npoints2] = rzi[z]; + npoints2++; + } + if ((zsgn^zzsgn) < 0) + { + int64_t t = divscale64(zsgn,zsgn-zzsgn, 30); + rxi2[npoints2] = rxi[z] + int32_t((t * (rxi[zz]-rxi[z])) >> 30); + ryi2[npoints2] = ryi[z] + int32_t((t * (ryi[zz]-ryi[z])) >> 30); + rzi2[npoints2] = rzi[z] + int32_t((t * (rzi[zz]-rzi[z])) >> 30); + npoints2++; + } + } + if (npoints2 <= 2) return; + + //Clip edge 4 + npoints = 0; + zzsgn = ryi2[0]*int64_t(halfxdimen) + (rzi2[0]*int64_t(globalhoriz-ydimen)); + for (z=0; z (xdimen<<16)) xsi[z] = (xdimen<<16); + if (ysi[z] < ((int32_t)0<<16)) ysi[z] = ((int32_t)0<<16); + if (ysi[z] > ((int32_t)ydimen<<16)) ysi[z] = ((int32_t)ydimen<<16); + if (xsi[z] < lmax) lmax = xsi[z], lpoint = z; + if (xsi[z] > rmax) rmax = xsi[z], rpoint = z; + } + + //Get uwall arrays + for (z=lpoint; z!=rpoint; z=zz) + { + zz = z+1; if (zz == npoints) zz = 0; + + dax1 = ((xsi[z]+65535)>>16); + dax2 = ((xsi[zz]+65535)>>16); + if (dax2 > dax1) + { + int32_t yinc = divscale16(ysi[zz]-ysi[z],xsi[zz]-xsi[z]); + y = ysi[z] + mulscale16((dax1<<16)-xsi[z],yinc); + qinterpolatedown16short((intptr_t)(&uwall[dax1]),dax2-dax1,y,yinc); + } + } + + //Get dwall arrays + for (; z!=lpoint; z=zz) + { + zz = z+1; if (zz == npoints) zz = 0; + + dax1 = ((xsi[zz]+65535)>>16); + dax2 = ((xsi[z]+65535)>>16); + if (dax2 > dax1) + { + int32_t yinc = divscale16(ysi[zz]-ysi[z],xsi[zz]-xsi[z]); + y = ysi[zz] + mulscale16((dax1<<16)-xsi[zz],yinc); + qinterpolatedown16short((intptr_t)(&dwall[dax1]),dax2-dax1,y,yinc); + } + } + + + const int32_t lx = ((lmax+65535)>>16); + const int32_t rx = min(((rmax+65535)>>16), xdim-1); + // min(): OOB prevention. Simple test case: have a floor-aligned sprite + // to the right of the player. Slowly rotate right toward it. When it + // just becomes visible, the condition rx == xdim can occur. + + // Don't pointlessly keep going. If the following condition holds, the + // ceilspritescan() at the end of our block would not draw any lines, + // and moreover may access uwall[] OOB (with x1==xdim). + if (rx-1 < lx) + return; + + for (x=lx; x<=rx; x++) + { + uwall[x] = max(uwall[x],startumost[x+windowxy1.x]-windowxy1.y); + dwall[x] = min(dwall[x],startdmost[x+windowxy1.x]-windowxy1.y); + } + + //Additional uwall/dwall clipping goes here + for (i=smostwallcnt-1; i>=0; i--) + { + j = smostwall[i]; + if ((xb1[j] > rx) || (xb2[j] < lx)) continue; + if ((yp <= yb1[j]) && (yp <= yb2[j])) continue; + + //if (spritewallfront(tspr,thewall[j]) == 0) + x = thewall[j]; xp1 = wall[x].x; yp1 = wall[x].y; + x = wall[x].point2; xp2 = wall[x].x; yp2 = wall[x].y; + x = (xp2-xp1)*(tspr->y-yp1)-(tspr->x-xp1)*(yp2-yp1); + if ((yp > yb1[j]) && (yp > yb2[j])) x = -1; + if ((x >= 0) && ((x != 0) || (wall[thewall[j]].nextsector != tspr->sectnum))) continue; + + const int32_t dalx2 = max(xb1[j],lx); + const int32_t darx2 = min(xb2[j],rx); + + switch (smostwalltype[i]) + { + case 0: + if (dalx2 <= darx2) + { + if ((dalx2 == lx) && (darx2 == rx)) return; + //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); + for (x=dalx2; x<=darx2; x++) dwall[x] = 0; + } + break; + case 1: + k = smoststart[i] - xb1[j]; + for (x=dalx2; x<=darx2; x++) + if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x]; + break; + case 2: + k = smoststart[i] - xb1[j]; + for (x=dalx2; x<=darx2; x++) + if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x]; + break; + } + } + + //sprite +#ifdef YAX_ENABLE + if (yax_globallev==YAX_MAXDRAWS || searchit==2) +#endif + if (searchit >= 1 && (searchx >= lx && searchx <= rx)) + if (searchy >= uwall[searchx] && searchy <= dwall[searchx]) + { + searchsector = sectnum; searchwall = spritenum; + searchstat = 3; searchit = 1; + } + + globalorientation = cstat; + globalpicnum = tilenum; + if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0; + + setgotpic(globalpicnum); + + vec2_16_t upscale = {}; + globalbufplc = tileLoadScaled(globalpicnum, &upscale); + + if (slope != 0) + { + x = picsiz[globalpicnum]; y = ((x>>4)&15); x &= 15; + x += upscale.x; + y += upscale.y; + sg1 = { divscale20(sg1.x, span.x) >> 16, divscale20(sg1.y, span.y) >> 16 }; + vec2f_t const tmp = { 256.f/float(span.x), 256.f/float(span.y) }; + sg_f2.x *= tmp.x; + sg_f2.y *= tmp.y; + sg_f.x *= tmp.x; + sg_f.y *= tmp.y; + span.x <<= upscale.x; + span.y <<= upscale.y; + int const ispow2 = (pow2long[x]==span.x && pow2long[y]==span.y); + + //asm1 = -(globalzd>>(16-BITSOFPRECISION)); +#define LINTERPSIZ 4 + float const bzinc = -sgzd*(1.f/65536.f) * (1<visibility != 0) ? mulscale4(globalhisibility, (uint8_t)(sec->visibility+16)) : globalhisibility; + globvis = ((((int64_t)(vis*sdaz)) >> 13) * xdimscale) >> 16; + + intptr_t fj = FP_OFF(palookup[globalpal]); + + setupslopevlin_alsotrans(x + (y<<8),globalbufplc,-ylookup[1]); + + int32_t const l = Blrintf((sgzd)*(1.f/65536.f)); + + int32_t const shinc = Blrintf(sgz*xdimenscale*(1.f/65536.f)); + + int32_t shoffs = (shinc > 0) ? (4 << 15) : ((16380 - ydimen) << 15); // JBF: was 2044 + int32_t y1 = uwall[lx]; + + int32_t m1 = Blrintf((y1*sgzd)*(1.f/65536.f) + sgzx*(1.f/64.f)); + //Avoid visibility overflow by crossing horizon + m1 += klabs(l); + int32_t m2 = m1+l; + int32_t shy1 = y1+(shoffs>>15); + int32_t shy2; + if ((unsigned)shy1 >= SLOPALOOKUPSIZ-1) + { + LOG_F(ERROR, "%s:%d: slopalookup[%" PRId32 "] overflow drawing sprite %d!", EDUKE32_FUNCTION, __LINE__, shy1, spritenum); + return; + } + + intptr_t *mptr1 = &slopalookup[shy1]; intptr_t *mptr2 = mptr1+1; + sg_f2.x += sg_f.x * lx; + sg_f2.y += sg_f.y * lx; + sgzx += sgz * lx; + shoffs += shinc *lx; + + for (int x=lx; x>15); + shy2 = y2+(shoffs>>15); // Ridiculously steep gradient? if ((unsigned)shy1 >= SLOPALOOKUPSIZ || (unsigned)shy2 >= SLOPALOOKUPSIZ) @@ -6593,459 +6946,108 @@ static void classicDrawSprite(int32_t snum) while (cnt > 0) { bz += bzinc; - int const u1 = ((int)(sg_f3.x/bz)-u0)>>LINTERPSIZ; - int const v1 = ((int)(sg_f3.y/bz)-v0)>>LINTERPSIZ; - int cnt2 = min(cnt, 1<0; cnt2--) - { - uint16_t u = (sg1.x+u0)&0xffff; - uint16_t v = (sg1.y+v0)&0xffff; - char ch = ggbuf[mulscale16(u, span.x)*span.y+mulscale16(v, span.y)]; - if (ch != 255) - { - ch = *(uint8_t *)(((intptr_t)slopalptr[0])+ch); - *p = trans[(ch<<8)|*p]; - } - slopalptr--; - p += ggpinc; - u0 += u1; - v0 += v1; - } - cnt -= 1< 0) - { - bz += bzinc; - int const u1 = ((int)(sg_f3.x/bz)-u0)>>LINTERPSIZ; - int const v1 = ((int)(sg_f3.y/bz)-v0)>>LINTERPSIZ; - int cnt2 = min(cnt, 1<0; cnt2--) - { - uint16_t u = (sg1.x+u0)&0xffff; - uint16_t v = (sg1.y+v0)&0xffff; - char ch = ggbuf[mulscale16(u, span.x)*span.y+mulscale16(v, span.y)]; - if (ch != 255) - { - ch = *(uint8_t *)(((intptr_t)slopalptr[0])+ch); - *p = trans[(*p<<8)|ch]; - } - slopalptr--; - p += ggpinc; - u0 += u1; - v0 += v1; - } - cnt -= 1<visibility != 0) globvis = mulscale4(globvis, (uint8_t)(sec->visibility+16)); - - x = picsiz[globalpicnum]; y = ((x>>4)&15); x &= 15; - x += upscale.x; - y += upscale.y; -#if 0 - if (pow2long[x] != xspan) - { - x++; - globalx1 = mulscale(globalx1,xspan,x); - globalx2 = mulscale(globalx2,xspan,x); - } -#endif - dax = globalxpanning; day = globalypanning; - globalxpanning = -((globalx1*day+globalx2*dax)<<6); - globalypanning = -((globaly1*day+globaly2*dax)<<6); - - globalx2 = mulscale16(globalx2,viewingrange); - globaly2 = mulscale16(globaly2,viewingrange); - globalzd = decltype(globalzd)((globalzd*int64_t(viewingrangerecip))>>4); - - globalx1 = (globalx1-globalx2)*halfxdimen; - globaly1 = (globaly1-globaly2)*halfxdimen; - - if ((cstat&2) == 0) - msethlineshift(x,y); - else - tsethlineshift(x,y); - - span.x <<= upscale.x; - span.y <<= upscale.y; - - globalispow2 = (pow2long[x]==span.x && pow2long[y]==span.y); - globalxspan = span.x; - globalyspan = span.y; - - //Draw it! - ceilspritescan(lx,rx-1); - globalispow2 = 1; - } - } - else if ((cstat&48) == 48) - { - const int32_t daxrepeat = ((sprite[spritenum].cstat&48)==16) ? - (tspr->xrepeat * 5) / 4 : - tspr->xrepeat; - - const int32_t lx = 0, rx = xdimen-1; - - Bassert(rx+windowxy1.x < xdim); - - for (x=lx; x<=rx; x++) - { - lwall[x] = startumost[x+windowxy1.x]-windowxy1.y; - swall[x] = startdmost[x+windowxy1.x]-windowxy1.y; - } - if ((tspr->cstat & 48) == 16) - { - const int32_t xspan = tilesiz[tilenum].x; - //const int32_t yspan = tilesiz[tilenum].y; - const int32_t xv = tspr->xrepeat*sintable[(tspr->ang+2560+1536)&2047]; - const int32_t yv = tspr->xrepeat*sintable[(tspr->ang+2048+1536)&2047]; - - i = (xspan>>1) + off.x; - x1 = tspr->x-globalposx-mulscale16(xv,i); x2 = x1+mulscale16(xv,xspan); - y1 = tspr->y-globalposy-mulscale16(yv,i); y2 = y1+mulscale16(yv,xspan); - - vec2_t p1 = get_rel_coords(x1, y1); - vec2_t p2 = get_rel_coords(x2, y2); - - if (p1.y <= 0 && p2.y <= 0) - return; - - x1 += globalposx; y1 += globalposy; - x2 += globalposx; y2 += globalposy; - - if (dmulscale32(p1.x, p2.y, -p2.x, p1.y) >= 0) // If wall's NOT facing you - { - const vec2_t pt = p2; - p2 = p1; - p1 = pt; - i = x1, x1 = x2, x2 = i; - i = y1, y1 = y2, y2 = i; - } - - for (i=smostwallcnt-1; i>=0; i--) - { - j = smostwall[i]; - - if (xb1[j] > rx || xb2[j] < lx) - continue; - - int32_t dalx2 = xb1[j]; - int32_t darx2 = xb2[j]; - - if (max(p1.y,p2.y) > min(yb1[j],yb2[j])) - { - if (min(p1.y,p2.y) > max(yb1[j],yb2[j])) - { - x = INT32_MIN; - } - else - { - x = thewall[j]; xp1 = wall[x].x; yp1 = wall[x].y; - x = wall[x].point2; xp2 = wall[x].x; yp2 = wall[x].y; - - z1 = (xp2-xp1)*(y1-yp1) - (yp2-yp1)*(x1-xp1); - z2 = (xp2-xp1)*(y2-yp1) - (yp2-yp1)*(x2-xp1); - if ((z1 == 0) | (z2 == 0)) - { - if ((xp2-xp1)*(tspr->y-yp1) == (tspr->x-xp1)*(yp2-yp1)) - { - if (wall[thewall[j]].nextsector == tspr->sectnum) - x = INT32_MIN; - else - x = INT32_MAX; - } - else - x = (z1+z2); - } - else if ((z1^z2) >= 0) - x = (z1+z2); - else - { - z1 = (x2-x1)*(yp1-y1) - (y2-y1)*(xp1-x1); - z2 = (x2-x1)*(yp2-y1) - (y2-y1)*(xp2-x1); - - if (((z1^z2) >= 0) | (z1 == 0) | (z2 == 0)) - x = -(z1+z2); - else - { - if ((xp2-xp1)*(tspr->y-yp1) == (tspr->x-xp1)*(yp2-yp1)) - { - if (wall[thewall[j]].nextsector == tspr->sectnum) - x = INT32_MIN; - else - x = INT32_MAX; - } - else - { - x = INT32_MAX; -#if 0 - //INTERSECTION! - x = (xp1-globalposx) + scale(xp2-xp1,z1,z1-z2); - y = (yp1-globalposy) + scale(yp2-yp1,z1,z1-z2); - - yp1 = dmulscale14(x,cosviewingrangeglobalang,y,sinviewingrangeglobalang); - - if (yp1 > 0) - { - xp1 = dmulscale14(y,cosglobalang,-x,singlobalang); - - x = halfxdimen + scale(xp1,halfxdimen,yp1); - if (xp1 >= 0) x++; //Fix for SIGNED divide - - if (z1 < 0) - { if (dalx2 < x) dalx2 = x; } - else - { if (darx2 > x) darx2 = x; } - x = INT32_MIN+1; - } - else - x = INT32_MAX; -#endif - } - } - } - } - - if (x < 0) - { - if (dalx2 < lx) dalx2 = lx; - if (darx2 > rx) darx2 = rx; - - switch (smostwalltype[i]) - { - case 0: - if (dalx2 <= darx2) - { - if ((dalx2 == lx) && (darx2 == rx)) return; - //clearbufbyte(&dwall[dalx2],(darx2-dalx2+1)*sizeof(dwall[0]),0L); - for (k=dalx2; k<=darx2; k++) swall[k] = 0; - } - break; - case 1: - k = smoststart[i] - xb1[j]; - x = dalx2; -#ifdef CLASSIC_SLICE_BY_4 - for (; x<=darx2-2; x+=2) - { - if (smost[k+x] > lwall[x]) lwall[x] = smost[k+x]; - if (smost[k+x+1] > lwall[x+1]) lwall[x+1] = smost[k+x+1]; + int const u1 = ((int)(sg_f3.x/bz)-u0)>>LINTERPSIZ; + int const v1 = ((int)(sg_f3.y/bz)-v0)>>LINTERPSIZ; + int cnt2 = min(cnt, 1<0; cnt2--) + { + uint16_t u = (sg1.x+u0)&0xffff; + uint16_t v = (sg1.y+v0)&0xffff; + char ch = ggbuf[mulscale16(u, span.x)*span.y+mulscale16(v, span.y)]; + if (ch != 255) + { + ch = *(uint8_t *)(((intptr_t)slopalptr[0])+ch); + *p = trans[(ch<<8)|*p]; + } + slopalptr--; + p += ggpinc; + u0 += u1; + v0 += v1; + } + cnt -= 1< lwall[x]) lwall[x] = smost[k+x]; - break; - case 2: - k = smoststart[i] - xb1[j]; - x = dalx2; -#ifdef CLASSIC_SLICE_BY_4 - for (; x<=darx2-4; x+=4) + else { - if (smost[k+x] < swall[x]) swall[x] = smost[k+x]; - if (smost[k+x+1] < swall[x+1]) swall[x+1] = smost[k+x+1]; - if (smost[k+x+2] < swall[x+2]) swall[x+2] = smost[k+x+2]; - if (smost[k+x+3] < swall[x+3]) swall[x+3] = smost[k+x+3]; + while (cnt > 0) + { + bz += bzinc; + int const u1 = ((int)(sg_f3.x/bz)-u0)>>LINTERPSIZ; + int const v1 = ((int)(sg_f3.y/bz)-v0)>>LINTERPSIZ; + int cnt2 = min(cnt, 1<0; cnt2--) + { + uint16_t u = (sg1.x+u0)&0xffff; + uint16_t v = (sg1.y+v0)&0xffff; + char ch = ggbuf[mulscale16(u, span.x)*span.y+mulscale16(v, span.y)]; + if (ch != 255) + { + ch = *(uint8_t *)(((intptr_t)slopalptr[0])+ch); + *p = trans[(*p<<8)|ch]; + } + slopalptr--; + p += ggpinc; + u0 += u1; + v0 += v1; + } + cnt -= 1<=0; i--) - { - j = smostwall[i]; - if ((xb1[j] > rx) || (xb2[j] < lx)) continue; - if ((yp <= yb1[j]) && (yp <= yb2[j])) continue; - if (spritewallfront(tspr,(int32_t)thewall[j]) && ((yp <= yb1[j]) || (yp <= yb2[j]))) continue; - - const int32_t dalx2 = max(xb1[j],lx); - const int32_t darx2 = min(xb2[j],rx); - - switch (smostwalltype[i]) - { - case 0: - if (dalx2 <= darx2) - { - if ((dalx2 == lx) && (darx2 == rx)) return; - //clearbufbyte(&swall[dalx2],(darx2-dalx2+1)*sizeof(swall[0]),0L); - for (x=dalx2; x<=darx2; x++) swall[x] = 0; - } - break; - case 1: - k = smoststart[i] - xb1[j]; - x = dalx2; -#ifdef CLASSIC_SLICE_BY_4 - for (; x<=darx2-2; x+=2) - { - if (smost[k+x] > lwall[x]) lwall[x] = smost[k+x]; - if (smost[k+x+1] > lwall[x+1]) lwall[x+1] = smost[k+x+1]; - } -#endif - for (; x<=darx2; x++) - if (smost[k+x] > lwall[x]) lwall[x] = smost[k+x]; - break; - case 2: - k = smoststart[i] - xb1[j]; - x = dalx2; -#ifdef CLASSIC_SLICE_BY_4 - for (; x<=darx2-4; x+=4) - { - if (smost[k+x] < swall[x]) swall[x] = smost[k+x]; - if (smost[k+x+1] < swall[x+1]) swall[x+1] = smost[k+x+1]; - if (smost[k+x+2] < swall[x+2]) swall[x+2] = smost[k+x+2]; - if (smost[k+x+3] < swall[x+3]) swall[x+3] = smost[k+x+3]; - } -#endif - for (; x<=darx2; x++) - if (smost[k+x] < swall[x]) swall[x] = smost[k+x]; - break; - } - } - } - - if (lwall[rx] >= swall[rx]) - { - for (x=lx; xvisibility != 0) globvis = mulscale4(globvis, (uint8_t)(sec->visibility+16)); - for (i=0; i>4)&15); x &= 15; + x += upscale.x; + y += upscale.y; +#if 0 + if (pow2long[x] != xspan) { - if (loadvoxel_replace) - loadvoxel_replace(vtilenum); - break; + x++; + globalx1 = mulscale(globalx1,xspan,x); + globalx2 = mulscale(globalx2,xspan,x); } - - const int32_t *const longptr = (int32_t *)voxoff[vtilenum][0]; - if (longptr == NULL) - { - globalshade = 32; - tspr->xrepeat = tspr->yrepeat = 255; - goto draw_as_face_sprite; - } - - int32_t nxrepeat, nyrepeat; - - if (voxscale[vtilenum] == 65536) - { - nxrepeat = (daxrepeat<<16); - nyrepeat = (((int32_t)tspr->yrepeat)<<16); - } - else - { - nxrepeat = daxrepeat*voxscale[vtilenum]; - nyrepeat = ((int32_t)tspr->yrepeat)*voxscale[vtilenum]; - } - - off.x = tspr->xoffset; - off.y = /*picanm[sprite[tspr->owner].picnum].yofs +*/ tspr->yoffset; - if (cstat & 4) off.x = -off.x; - if ((cstat & 8) && (tspr->cstat&48) != 0) off.y = -off.y; - tspr->z -= off.y * tspr->yrepeat << 2; - - const float xfactor = (tspr->cstat&48) != 16 ? (256.f/320.f) : 1.f; - const int32_t xv = (int32_t)(tspr->xrepeat*sintable[(tspr->ang+2560+1536)&2047]*xfactor); - const int32_t yv = (int32_t)(tspr->xrepeat*sintable[(tspr->ang+2048+1536)&2047]*xfactor); - - tspr->x -= mulscale16(xv, off.x); - tspr->y -= mulscale16(yv, off.x); - - globvis = globalvisibility; - if (sec->visibility != 0) globvis = mulscale4(globvis, (uint8_t)(sec->visibility+16)); - -#ifdef YAX_ENABLE - if (yax_globallev==YAX_MAXDRAWS || searchit==2) #endif - if (searchit >= 1 && yp > (4<<8) && (searchy >= lwall[searchx] && searchy < swall[searchx])) - { - int32_t const xdsiz = divscale19(xdimenscale,yp); - int32_t const xv = mulscale16(nxrepeat,xyaspect); - - int32_t const xspan = ((B_LITTLE32(longptr[0]) + B_LITTLE32(longptr[1])) >> 1); - int32_t const yspan = B_LITTLE32(longptr[2]); - - vec2_t const siz = { mulscale_triple30(xdsiz, xv, xspan), mulscale_triple30(xdsiz, nyrepeat, yspan) }; - - //Watch out for divscale overflow - if (((xspan>>11) < siz.x) && (yspan < (siz.y>>1))) - { - x1 = xb-(siz.x>>1); - if (xspan&1) x1 += mulscale31(xdsiz,xv); //Odd xspans - i = mulscale30(xdsiz,xv*off.x); - if ((cstat&4) == 0) x1 -= i; else x1 += i; + dax = globalxpanning; day = globalypanning; + globalxpanning = -((globalx1*day+globalx2*dax)<<6); + globalypanning = -((globaly1*day+globaly2*dax)<<6); - y1 = mulscale16(tspr->z-globalposz,xdsiz); + globalx2 = mulscale16(globalx2,viewingrange); + globaly2 = mulscale16(globaly2,viewingrange); + globalzd = decltype(globalzd)((globalzd*int64_t(viewingrangerecip))>>4); - if (!(cstat & 128)) - y1 -= mulscale16(mulscale22(B_LITTLE32(longptr[5]), nyrepeat), xdsiz); - //y1 -= mulscale30(xdsiz,nyrepeat*yoff); - y1 += (globalhoriz<<8)-siz.y; - //if (cstat&128) //Already fixed up above - y1 += (siz.y>>1); + globalx1 = (globalx1-globalx2)*halfxdimen; + globaly1 = (globaly1-globaly2)*halfxdimen; - x2 = x1+siz.x-1; - y2 = y1+siz.y-1; - if ((y1|255) < (y2|255) && searchx >= (x1>>8)+1 && searchx <= (x2>>8)) - { - int32_t startum, startdm; + if ((cstat&2) == 0) + msethlineshift(x,y); + else + tsethlineshift(x,y); - if ((sec->ceilingstat&3) == 0) - startum = globalhoriz+mulscale24(xdsiz,sec->ceilingz-globalposz)-1; - else - startum = 0; + span.x <<= upscale.x; + span.y <<= upscale.y; - if ((sec->floorstat&3) == 0) - startdm = globalhoriz+mulscale24(xdsiz,sec->floorz-globalposz)+1; - else - startdm = INT32_MAX; + globalispow2 = (pow2long[x]==span.x && pow2long[y]==span.y); + globalxspan = span.x; + globalyspan = span.y; - //sprite - if (searchy >= max(startum,(y1>>8)) && searchy < min(startdm,(y2>>8))) - { - searchsector = sectnum; searchwall = spritenum; - searchstat = 3; searchit = 1; - } - } - } + //Draw it! + ceilspritescan(lx,rx-1); + globalispow2 = 1; } - - x = tspr->x + spriteext[spritenum].mdposition_offset.x; - y = tspr->y + spriteext[spritenum].mdposition_offset.y; - z = tspr->z + spriteext[spritenum].mdposition_offset.z; - - i = (int32_t)tspr->ang+1536; - i += spriteext[spritenum].mdangoff; - - const int32_t ceilingz = (sec->ceilingstat&3) == 0 ? sec->ceilingz : INT32_MIN; - const int32_t floorz = (sec->floorstat&3) == 0 ? sec->floorz : INT32_MAX; - - classicDrawVoxel(x,y,z,i,daxrepeat,(int32_t)tspr->yrepeat,vtilenum, - tspr->shade,tspr->pal,lwall,swall,tspr->cstat,(tspr->cstat&48)!=48,floorz,ceilingz); } if (automapping == 1 && (unsigned)spritenum < MAXSPRITES) @@ -9810,10 +9812,10 @@ static inline int comparetsprites(int const k, int const l) #ifdef USE_OPENGL if (videoGetRenderMode() == REND_POLYMOST) { - if ((kspr->cstat & 48) != (lspr->cstat & 48)) - return (kspr->cstat & 48) - (lspr->cstat & 48); + if ((kspr->cstat & CSTAT_SPRITE_ALIGNMENT) != (lspr->cstat & CSTAT_SPRITE_ALIGNMENT)) + return (kspr->cstat & CSTAT_SPRITE_ALIGNMENT) - (lspr->cstat & CSTAT_SPRITE_ALIGNMENT); - if ((kspr->cstat & 48) == 16 && kspr->ang != lspr->ang) + if ((kspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL && kspr->ang != lspr->ang) return kspr->ang - lspr->ang; } #endif @@ -9823,7 +9825,7 @@ static inline int comparetsprites(int const k, int const l) if (kspr->x == lspr->x && kspr->y == lspr->y && kspr->z == lspr->z && - (kspr->cstat & 48) == (lspr->cstat & 48) && + (kspr->cstat & CSTAT_SPRITE_ALIGNMENT) == (lspr->cstat & CSTAT_SPRITE_ALIGNMENT) && kspr->owner != lspr->owner) return kspr->owner - lspr->owner; @@ -9875,7 +9877,7 @@ static void sortsprites(int const start, int const end) auto const s = tspriteptr[k]; int32_t z = s->z; - if ((s->cstat & 48) != 32) + if ((s->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_FLOOR) { int32_t const yoff = picanm[s->picnum].yofs + s->yoffset; int32_t const yspan = (tilesiz[s->picnum].y * s->yrepeat << 2); @@ -9941,13 +9943,13 @@ static void PolymostDrawMasks(int32_t numSprites) for (bssize_t i = numSprites - 1; i >= spritesortcnt; /* 'i' set at and of loop */) { int32_t const py = spritesxyz[i].y; - int32_t const pcstat = tspriteptr[i]->cstat & 48; + int32_t const pcstat = tspriteptr[i]->cstat & CSTAT_SPRITE_ALIGNMENT; int32_t const pangle = tspriteptr[i]->ang; int j = i - 1; if (!polymost_spriteIsModelOrVoxel(tspriteptr[i])) { - while (j >= spritesortcnt && py == spritesxyz[j].y && pcstat == (tspriteptr[j]->cstat & 48) && (pcstat != 16 || pangle == tspriteptr[j]->ang) + while (j >= spritesortcnt && py == spritesxyz[j].y && pcstat == (tspriteptr[j]->cstat & CSTAT_SPRITE_ALIGNMENT) && (pcstat != CSTAT_SPRITE_ALIGNMENT_WALL || pangle == tspriteptr[j]->ang) && !polymost_spriteIsModelOrVoxel(tspriteptr[j])) { j--; @@ -10073,12 +10075,12 @@ static int32_t GetCornerPoints(tspriteptr_t tspr, int32_t (&xx)[4], int32_t (&yy // Consider face sprites as wall sprites with camera ang. // XXX: factor 4/5 needed? - if ((tspr->cstat & 48) != 16) + if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_WALL) tspr->ang = globalang; get_wallspr_points(tspr, &xx[0], &xx[1], &yy[0], &yy[1]); - if ((tspr->cstat & 48) != 16) + if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_WALL) tspr->ang = oang; } @@ -10138,7 +10140,7 @@ void renderDrawMasks(void) spritesxyz[i].x = scale(xp + yp, xdimen << 7, yp); } - else if ((tspriteptr[i]->cstat & 48) == 0) + else if ((tspriteptr[i]->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FACING) { killsprite: #ifdef USE_OPENGL @@ -10458,7 +10460,7 @@ void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang) if (sprite[i].cstat & 32768) continue; - if ((sprite[i].cstat & 48) >= 32) + if (sprite[i].cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR) { if ((sprite[i].cstat & (64 + 8)) == (64 + 8)) continue; @@ -10570,7 +10572,7 @@ void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang) for (s=sortnum-1; s>=0; s--) { auto const spr = (uspritetype * )&sprite[tsprite[s].owner]; - if ((spr->cstat&48) >= 32) + if (spr->cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR) { const int32_t xspan = tilesiz[spr->picnum].x; const int32_t yspan = tilesiz[spr->picnum].y; @@ -10861,8 +10863,8 @@ static int32_t engineFinishLoadBoard(const vec3_t* dapos, int16_t* dacursectnum, { int32_t removeit = 0; - if ((sprite[i].cstat & 48) == 48 && (sprite[i].xoffset|sprite[i].yoffset) == 0) - sprite[i].cstat &= ~48; + if ((sprite[i].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLOPE && (sprite[i].xoffset|sprite[i].yoffset) == 0) + sprite[i].cstat &= ~CSTAT_SPRITE_ALIGNMENT_SLOPE; if (sprite[i].statnum == MAXSTATUS) { diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index 53fe3c03c3..80a256d8b4 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -1999,10 +1999,12 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) if (m->vbos == NULL) mdloadvbos(m); - // if ((tspr->cstat&48) == 32) return 0; + // if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) return 0; updateanimation((md2model_t *)m, tspr, lpal); + auto const tsprflags = tspr->clipdist; + //create current&next frame's vertex list from whole list f = m->interpol; g = 1.f - f; @@ -2029,9 +2031,9 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) // Parkar: Moved up to be able to use k0 for the y-flipping code k0 = (float)tspr->z+spriteext[tspr->owner].mdposition_offset.z; - f = ((globalorientation&8) && (sprite[tspr->owner].cstat&48)!=0) ? -4.f : 4.f; + f = ((globalorientation&8) && (sprite[tspr->owner].cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_FACING) ? -4.f : 4.f; k0 -= (tspr->yoffset*tspr->yrepeat)*f; - if ((globalorientation&128) && !((globalorientation&48)==32)) + if ((globalorientation&128) && (globalorientation & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_FLOOR) k0 += (float)(sizyrep<<1); // Parkar: Changed to use the same method as centeroriented sprites @@ -2054,7 +2056,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) // floor aligned k1 = (float)tspr->y+spriteext[tspr->owner].mdposition_offset.y; - if ((globalorientation&48)==32) + if ((globalorientation & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) { m0.z = -m0.z; m1.z = -m1.z; a0.z = -a0.z; m0.y = -m0.y; m1.y = -m1.y; a0.y = -a0.y; @@ -2073,7 +2075,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) md3_vox_calcmat_common(tspr, &a0, f, mat); // floor aligned - if ((globalorientation&48)==32) + if ((globalorientation & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) { f = mat[4]; mat[4] = mat[8]*16.f; mat[8] = -f*(1.f/16.f); f = mat[5]; mat[5] = mat[9]*16.f; mat[9] = -f*(1.f/16.f); @@ -2088,7 +2090,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) // to use Z-buffer hacks to hide overdraw problems with the flat-tsprite-on-floor shadows, // also disabling detail, glow, normal, and specular maps. - if (tspr->clipdist & TSPR_FLAGS_MDHACK) + if (tsprflags & TSPR_FLAGS_MDHACK) { #ifdef __arm__ // GL ES has a glDepthRangef and the loss of precision is OK there float f = (float) (tspr->owner + 1) * (std::numeric_limits::epsilon() * 8.0); @@ -2161,7 +2163,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) if (sext->mdpivot_offset.y) // Compare with SCREEN_FACTORS above a0.y = (float) sext->mdpivot_offset.y * f; - if ((sext->mdpivot_offset.z) && !(tspr->clipdist & TSPR_FLAGS_MDHACK)) // Compare with SCREEN_FACTORS above + if ((sext->mdpivot_offset.z) && !(tsprflags & TSPR_FLAGS_MDHACK)) // Compare with SCREEN_FACTORS above a0.z = (float)(((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) ? -sext->mdpivot_offset.z : sext->mdpivot_offset.z) / (gxyaspect * fxdimen * (65536.f/128.f) * (m0.z+m1.z)); k0 = (float)sintable[(sext->mdpitch+512)&2047] * (1.f/16384.f); @@ -2285,7 +2287,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) glTranslatef(xpanning, ypanning, 1.0f); glMatrixMode(GL_MODELVIEW); - if (!(tspr->clipdist & TSPR_FLAGS_MDHACK)) + if (!(tsprflags & TSPR_FLAGS_MDHACK)) { #ifdef USE_GLEXT //POGOTODO: if we add support for palette indexing on model skins, the texture for the palswap could be setup here diff --git a/source/build/src/polymer.cpp b/source/build/src/polymer.cpp index d7868ebc84..14850ad737 100644 --- a/source/build/src/polymer.cpp +++ b/source/build/src/polymer.cpp @@ -1528,10 +1528,12 @@ void polymer_drawsprite(int32_t snum) if (bad_tspr(tspr)) return; - if ((tspr->clipdist & TSPR_FLAGS_NO_SHADOW) && (depth && !mirrors[depth-1].plane)) + auto const tsprflags = tspr->clipdist; + + if ((tsprflags & TSPR_FLAGS_NO_SHADOW) && (depth && !mirrors[depth-1].plane)) return; - if ((tspr->clipdist & TSPR_FLAGS_INVISIBLE_WITH_SHADOW) && (!depth || mirrors[depth-1].plane)) + if ((tsprflags & TSPR_FLAGS_INVISIBLE_WITH_SHADOW) && (!depth || mirrors[depth-1].plane)) return; int const spritenum = tspr->owner; @@ -1597,7 +1599,7 @@ void polymer_drawsprite(int32_t snum) break; } - if ((cs & 48) == 0) + if ((cs & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FACING) { int32_t curpriority = 0; @@ -4008,7 +4010,7 @@ void polymer_updatesprite(int32_t snum) s->hash = 0xDEADBEEF; } - if ((tspr->cstat & 48) && !s->plane.vbo) + if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) && !s->plane.vbo) { if (pr_nullrender < 2) { @@ -4018,7 +4020,7 @@ void polymer_updatesprite(int32_t snum) } } - if (tspr->cstat & 48 && searchit != 2) + if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) && searchit != 2) { uint32_t const changed = XXH3_64bits((uint8_t *) tspr, offsetof(spritetype, owner)); @@ -4505,6 +4507,8 @@ void polymer_drawmdsprite(tspriteptr_t tspr) if (m->indices == NULL) polymer_loadmodelvbos(m); + auto const tsprflags = tspr->clipdist; + // Hackish, but that means it's a model drawn by rotatesprite. if (tspriteptr[maxspritesonscreen] == tspr) { spos[0] = fglobalposy; @@ -4824,7 +4828,7 @@ void polymer_drawmdsprite(tspriteptr_t tspr) if (!mdspritematerial.diffusemap) continue; - if (!(tspr->clipdist & TSPR_FLAGS_MDHACK)) + if (!(tsprflags & TSPR_FLAGS_MDHACK)) { mdspritematerial.detailmap = mdloadskin((md2model_t *)m,tile2model[Ptile2tile(tspr->picnum,lpal)].skinnum,DETAILPAL,surfi); @@ -6233,7 +6237,7 @@ static int polymer_culllight(int16_t lighti) { _prsprite *s = prsprites[i]; - if ((sprite[i].cstat & 48) == 0 || s == NULL) + if ((sprite[i].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FACING || s == NULL) continue; if (polymer_planeinlight(s->plane, light)) diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 20cb010d33..ee949790ed 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -2761,6 +2761,19 @@ static inline pthtyp *our_texcache_fetch(int32_t dameth) return texcache_fetch(globalpicnum, globalpal, getpalookup(0, globalshade), dameth); } +static inline bool polymost_spriteIsLegacyVoxel(tspritetype const * const tspr) +{ + auto const tsprflags = tspr->clipdist; + auto const picnum = tspr->picnum; + return (tsprflags & TSPR_FLAGS_SLAB) && (unsigned)picnum < MAXVOXELS && voxmodels[picnum]; +} + +static inline bool polymost_spriteIsModernVoxel(tspritetype const * const tspr) +{ + auto const picnum = tspr->picnum; + return !polymost_spriteIsLegacyVoxel(tspr) && usevoxels && (unsigned)tiletovox[picnum] < MAXVOXELS && voxmodels[tiletovox[picnum]]; +} + int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall) { if (wall->cstat & CSTAT_WALL_TRANSLUCENT) @@ -2780,10 +2793,10 @@ int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall) int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr) { - if (usevoxels && (tspr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_SLAB && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]] && (voxflags[tiletovox[tspr->picnum]] & VF_NOTRANS) == VF_NOTRANS) + if (polymost_spriteIsModernVoxel(tspr) && (voxflags[tiletovox[tspr->picnum]] & VF_NOTRANS) == VF_NOTRANS) return false; - if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB && voxmodels[tspr->picnum] && (voxflags[tspr->picnum] & VF_NOTRANS) == VF_NOTRANS) + if (polymost_spriteIsLegacyVoxel(tspr) && (voxflags[tspr->picnum] & VF_NOTRANS) == VF_NOTRANS) return false; if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || (tspr->clipdist & TSPR_FLAGS_DRAW_LAST) || @@ -2811,10 +2824,10 @@ int32_t polymost_spriteIsModelOrVoxel(tspritetype const * const tspr) tile2model[Ptile2tile(tspr->picnum, tspr->pal)].framenum >= 0) return true; - if (usevoxels && (tspr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_SLAB && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]]) + if (polymost_spriteIsModernVoxel(tspr)) return true; - if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB && voxmodels[tspr->picnum]) + if (polymost_spriteIsLegacyVoxel(tspr)) return true; return false; @@ -6605,15 +6618,17 @@ void polymost_scansector(int32_t sectnum) vec2_t const s = { spr->x-globalposx, spr->y-globalposy }; - if ((spr->cstat&48) || + if ((spr->cstat & CSTAT_SPRITE_ALIGNMENT) || (usemodels && tile2model[spr->picnum].modelid>=0) || ((s.x * gcosang) + (s.y * gsinang) > 0)) { - if ((spr->cstat&(64+48))!=(64+16) || + if ((spr->cstat & (CSTAT_SPRITE_ONE_SIDED|CSTAT_SPRITE_ALIGNMENT)) != (CSTAT_SPRITE_ONE_SIDED|CSTAT_SPRITE_ALIGNMENT_WALL) || (usevoxels && tiletovox[spr->picnum] >= 0 && voxmodels[tiletovox[spr->picnum]]) || dmulscale6(sintable[(spr->ang+512)&2047],-s.x, sintable[spr->ang&2047],-s.y) > 0) + { if (renderAddTsprite(z, sectnum)) break; + } } } @@ -7573,6 +7588,7 @@ void polymost2_drawsprite(int32_t snum) usectorptr_t sec; int32_t spritenum = tspr->owner; + auto const tsprflags = tspr->clipdist; tileUpdatePicnum(&tspr->picnum, spritenum + 32768); @@ -7587,7 +7603,7 @@ void polymost2_drawsprite(int32_t snum) vec2f_t off = { 0.f, 0.f }; - if ((globalorientation & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_SLAB) // only non-voxel sprites should do this + if (!(tsprflags & TSPR_FLAGS_SLAB)) // only non-voxel sprites should do this { int const flag = usehightile && h_xsize[globalpicnum]; off.x = (float)((int32_t)tspr->xoffset + (flag ? h_xoffs[globalpicnum] : picanm[globalpicnum].xofs)); @@ -7619,13 +7635,13 @@ void polymost2_drawsprite(int32_t snum) break; // else, render as flat sprite } - if (usevoxels && (tspr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_SLAB && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]]) + if (polymost_spriteIsModernVoxel(tspr)) { if (polymost_voxdraw(voxmodels[tiletovox[tspr->picnum]], tspr)) return; break; // else, render as flat sprite } - if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB && voxmodels[tspr->picnum]) + if (polymost_spriteIsLegacyVoxel(tspr)) { polymost_voxdraw(voxmodels[tspr->picnum], tspr); return; @@ -7637,7 +7653,7 @@ void polymost2_drawsprite(int32_t snum) //POGO: some comments seem to indicate that spinning sprites were intended to be supported before the // decision was made to implement that behaviour with voxels. // Skip SLAB aligned sprites when not rendering as voxels. - if ((globalorientation & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB) + if (tsprflags & TSPR_FLAGS_SLAB) { return; } @@ -8157,7 +8173,9 @@ void polymost_drawsprite(int32_t snum) buildgl_outputDebugMessage(3, "polymost_drawsprite(snum:%d)", snum); - if ((tspr->cstat&48) != 48) + auto const tsprflags = tspr->clipdist; + + if (!(tsprflags & TSPR_FLAGS_SLAB)) tileUpdatePicnum(&tspr->picnum, spritenum + 32768); globalpicnum = tspr->picnum; @@ -8176,12 +8194,12 @@ void polymost_drawsprite(int32_t snum) vec2_t off = { 0, 0 }; - if ((globalorientation & 48) != 48) // only non-voxel sprites should do this + if (!(tsprflags & TSPR_FLAGS_SLAB)) // only non-voxel sprites should do this { int const flag = usehightile && h_xsize[globalpicnum]; off = { flag ? h_xoffs[globalpicnum] : picanm[globalpicnum].xofs, flag ? h_yoffs[globalpicnum] : picanm[globalpicnum].yofs }; - if (!(tspr->clipdist & TSPR_FLAGS_SLOPE_SPRITE)) + if (!(tsprflags & TSPR_FLAGS_SLOPE_SPRITE)) { off.x += tspr->xoffset; off.y += tspr->yoffset; @@ -8209,7 +8227,7 @@ void polymost_drawsprite(int32_t snum) break; // else, render as flat sprite } - if (usevoxels && (tspr->cstat & 48) != 48 && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]]) + if (polymost_spriteIsModernVoxel(tspr)) { if (polymost_voxdraw(voxmodels[tiletovox[tspr->picnum]], tspr)) { @@ -8221,7 +8239,7 @@ void polymost_drawsprite(int32_t snum) break; // else, render as flat sprite } - if ((tspr->cstat & 48) == 48 && voxmodels[tspr->picnum]) + if (polymost_spriteIsLegacyVoxel(tspr)) { polymost_voxdraw(voxmodels[tspr->picnum], tspr); diff --git a/source/build/src/voxmodel.cpp b/source/build/src/voxmodel.cpp index df9b33910b..987ff1b9b7 100644 --- a/source/build/src/voxmodel.cpp +++ b/source/build/src/voxmodel.cpp @@ -1155,19 +1155,21 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr) if ((intptr_t)m == (intptr_t)(-1)) // hackhackhack return 0; - if ((tspr->cstat&48)==32) + if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) return 0; buildgl_outputDebugMessage(3, "polymost_voxdraw(m:%p, tspr:%p)", m, tspr); //updateanimation((md2model *)m,tspr); + auto const tsprflags = tspr->clipdist; + vec3f_t m0 = { m->scale, m->scale, m->scale }; vec3f_t a0 = { 0, 0, m->zadd*m->scale }; k0 = m->bscale / 64.f; f = (float) tspr->xrepeat * (256.f/320.f) * k0; - if ((sprite[tspr->owner].cstat&48)==16) + if ((sprite[tspr->owner].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL) f *= 1.25f; a0.y -= tspr->xoffset*sintable[(spriteext[tspr->owner].mdangoff+512)&2047]*(1.f/(64.f*16384.f)); a0.x += tspr->xoffset*sintable[(spriteext[tspr->owner].mdangoff)&2047]*(1.f/(64.f*16384.f)); @@ -1181,12 +1183,12 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr) m0.z *= f; a0.z *= f; k0 = (float) (tspr->z+spriteext[tspr->owner].mdposition_offset.z); - f = ((globalorientation&8) && (sprite[tspr->owner].cstat&48)!=0) ? -4.f : 4.f; + f = ((globalorientation&8) && (sprite[tspr->owner].cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_FACING) ? -4.f : 4.f; k0 -= (tspr->yoffset*tspr->yrepeat)*f*m->bscale; zoff = m->siz.z*.5f; if (!(tspr->cstat&128)) zoff += m->piv.z; - else if ((tspr->cstat&48) != 48) + else if (!(tsprflags & TSPR_FLAGS_SLAB)) { zoff += m->piv.z; zoff -= m->siz.z*.5f; @@ -1196,7 +1198,7 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr) f = (65536.f*512.f) / ((float)xdimen*viewingrange); g = 32.f / ((float)xdimen*gxyaspect); - int const shadowHack = !!(tspr->clipdist & TSPR_FLAGS_MDHACK); + int const shadowHack = !!(tsprflags & TSPR_FLAGS_MDHACK); m0.y *= f; a0.y = (((float)(tspr->x+spriteext[tspr->owner].mdposition_offset.x-globalposx)) * (1.f/1024.f) + a0.y) * f; m0.x *=-f; a0.x = (((float)(tspr->y+spriteext[tspr->owner].mdposition_offset.y-globalposy)) * -(1.f/1024.f) + a0.x) * -f; @@ -1237,7 +1239,7 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr) if (have_basepal_tint()) hictinting_apply(pc, MAXPALOOKUPS - 1); - int32_t const voxid = (tspr->cstat & CSTAT_SPRITE_ALIGNMENT_SLAB) == CSTAT_SPRITE_ALIGNMENT_SLAB + int32_t const voxid = (tsprflags & TSPR_FLAGS_SLAB) ? tspr->picnum : tiletovox[tspr->picnum]; if (!shadowHack && (voxflags[voxid] & VF_NOTRANS) != VF_NOTRANS) diff --git a/source/duke3d/src/actors.cpp b/source/duke3d/src/actors.cpp index a53ec4e9ca..92a8968361 100644 --- a/source/duke3d/src/actors.cpp +++ b/source/duke3d/src/actors.cpp @@ -561,7 +561,7 @@ int A_GetClipdist(int spriteNum) if ((SpriteProjectile[spriteNum].workslike & PROJECTILE_REALCLIPDIST) == 0) clipDist = 16; } - else if ((pSprite->cstat & 48) == 16) + else if ((pSprite->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL) clipDist = 0; else if (A_CheckEnemySprite(pSprite)) { diff --git a/source/duke3d/src/astub.cpp b/source/duke3d/src/astub.cpp index 74abaa2fd4..ebb4a83534 100644 --- a/source/duke3d/src/astub.cpp +++ b/source/duke3d/src/astub.cpp @@ -4234,17 +4234,17 @@ static int32_t addtobyte(int8_t *byte, int32_t num) static void toggle_sprite_alignment(int32_t spritenum) { - static const char *aligntype[4] = { "view", "wall", "floor", "???" }; + static const char *aligntype[4] = { "view", "wall", "floor", "sloped" }; int32_t i = sprite[spritenum].cstat; - if ((i&48) < 32) - i += 16; + if ((i & CSTAT_SPRITE_ALIGNMENT) < CSTAT_SPRITE_ALIGNMENT_FLOOR) + i += CSTAT_SPRITE_ALIGNMENT_WALL; else - i &= ~48; + i &= ~CSTAT_SPRITE_ALIGNMENT; sprite[spritenum].cstat = i; - message("Sprite %d now %s aligned", spritenum, aligntype[(i&48)/16]); + message("Sprite %d now %s aligned", spritenum, aligntype[(i & CSTAT_SPRITE_ALIGNMENT) / CSTAT_SPRITE_ALIGNMENT_WALL]); asksave = 1; } @@ -4886,7 +4886,7 @@ static void Keys3d(void) { i = sprite[searchwall].cstat; i ^= 64; - if ((i&48) == 32) + if ((i & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) { i &= ~8; if ((i&64) && pos.z>sprite[searchwall].z) @@ -5260,7 +5260,7 @@ static void Keys3d(void) else if (AIMING_AT_SPRITE) { i = sprite[searchwall].cstat; - if (((i&48) == 32) && ((i&64) == 0)) + if (((i & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FLOOR) && ((i&64) == 0)) { sprite[searchwall].cstat &= ~0xc; sprite[searchwall].cstat |= ((i&4)^4); @@ -7572,7 +7572,7 @@ static void Keys2d(void) { changedir = 1-(j&2); - if ((ppointhighlight&0xc000) == 16384 && (sprite[cursprite].cstat & 48)) + if ((ppointhighlight&0xc000) == 16384 && (sprite[cursprite].cstat & CSTAT_SPRITE_ALIGNMENT)) { uint8_t *repeat = (k==0) ? &sprite[cursprite].xrepeat : &sprite[cursprite].yrepeat; *repeat = max(4, changechar(*repeat, changedir, smooshy, 1)); @@ -10393,14 +10393,14 @@ void ExtPreCheckKeys(void) // just before drawrooms { auto pSprite = (uspriteptr_t)&sprite[i]; - if ((pSprite->cstat & 48) != 0 || pSprite->statnum == MAXSTATUS || (unsigned)pSprite->sectnum >= MAXSECTORS) continue; + if ((pSprite->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_FACING || pSprite->statnum == MAXSTATUS || (unsigned)pSprite->sectnum >= MAXSECTORS) continue; if (bitmap_test(graysectbitmap, pSprite->sectnum)) continue; int daang = 0, flags = 0, shade = 0, frames = 0; int picnum = pSprite->picnum; int32_t xp1, yp1; - if ((sprite[i].cstat & 48) != 0 || sprite[i].statnum == MAXSTATUS) continue; + if ((sprite[i].cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_FACING || sprite[i].statnum == MAXSTATUS) continue; ii++; @@ -10613,7 +10613,7 @@ void ExtAnalyzeSprites(int32_t ourx, int32_t oury, int32_t ourz, int32_t oura, i if (tspr->sectnum<0) continue; - const int32_t wallaligned = (tspr->cstat & 16); + const int32_t wallaligned = (tspr->cstat & CSTAT_SPRITE_ALIGNMENT_WALL); const int32_t fpal = sector[tspr->sectnum].floorpal; // 1st rule diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index d65d6ef812..4bacf9d7b0 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -1491,7 +1491,7 @@ int A_Spawn(int spriteNum, int tileNum) practor[newSprite].lightId = -1; #endif - if ((s.cstat & 48) + if ((s.cstat & CSTAT_SPRITE_ALIGNMENT) #ifndef EDUKE32_STANDALONE && s.picnum != SPEAKER && s.picnum != LETTER && s.picnum != DUCK && s.picnum != TARGET && s.picnum != TRIPBOMB #endif @@ -1501,7 +1501,7 @@ int A_Spawn(int spriteNum, int tileNum) goto SPAWN_END; #ifndef EDUKE32_STANDALONE - if (A_CheckSwitchTile(newSprite) && (s.cstat & 16)) + if (A_CheckSwitchTile(newSprite) && (s.cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL) { if (s.pal && s.picnum != ACCESSSWITCH && s.picnum != ACCESSSWITCH2) { @@ -3456,7 +3456,7 @@ int A_Spawn(int spriteNum, int tileNum) } else { - pSprite->cstat |= (pSprite->cstat & 48) ? 1 : 17; + pSprite->cstat |= (pSprite->cstat & CSTAT_SPRITE_ALIGNMENT) ? 1 : (1 | CSTAT_SPRITE_ALIGNMENT_WALL); pSprite->extra = 1; } diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h index 23b7c5ff06..8bc293367b 100644 --- a/source/duke3d/src/game.h +++ b/source/duke3d/src/game.h @@ -414,7 +414,7 @@ void P_SetGamePalette(DukePlayer_t *player, uint32_t palid, int32_t set); // Cstat protection mask for (currently) spawned MASKWALL* sprites. // TODO: look at more cases of cstat=(cstat&PROTECTED)|ADDED in A_Spawn()? // 2048+(32+16)+8+4 -#define SPAWN_PROTECT_CSTAT_MASK (CSTAT_SPRITE_NOSHADE|CSTAT_SPRITE_ALIGNMENT_SLAB|CSTAT_SPRITE_XFLIP|CSTAT_SPRITE_YFLIP); +#define SPAWN_PROTECT_CSTAT_MASK (CSTAT_SPRITE_NOSHADE|CSTAT_SPRITE_ALIGNMENT_MASK|CSTAT_SPRITE_XFLIP|CSTAT_SPRITE_YFLIP); void fadepal(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step); //void fadepaltile(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step,int32_t tile); diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index aacee415b1..a6393b1222 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -502,7 +502,7 @@ void A_GetZLimits(int const spriteNum) { pActor->flags &= ~SFLAG_NOFLOORSHADOW; - if ((florhit & 49152) == 49152 && (sprite[florhit & (MAXSPRITES - 1)].cstat & 48) == 0) + if ((florhit & 49152) == 49152 && (sprite[florhit & (MAXSPRITES - 1)].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FACING) { auto const hitspr = (uspriteptr_t)&sprite[florhit & (MAXSPRITES - 1)]; @@ -530,7 +530,7 @@ void A_GetZLimits(int const spriteNum) if ((ceilhit&49152) == 49152) { auto const pCeil = &sprite[ceilhit&(MAXSPRITES-1)]; - if ((pCeil->cstat&48) == 0 && pCeil->z >= pActor->floorz) + if ((pCeil->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FACING && pCeil->z >= pActor->floorz) pActor->ceilingz = oceilz; } } diff --git a/source/duke3d/src/m32common.cpp b/source/duke3d/src/m32common.cpp index 64fa74c7ad..4c08d205ff 100644 --- a/source/duke3d/src/m32common.cpp +++ b/source/duke3d/src/m32common.cpp @@ -553,7 +553,8 @@ int32_t map_undoredo(int dir) // insert sprites for (int i=0; inum[UNDO_SPRITES]; i++) { - if ((sprite[i].cstat & 48) == 48 && (sprite[i].xoffset|sprite[i].yoffset) == 0) sprite[i].cstat &= ~48; + if ((sprite[i].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLOPE && (sprite[i].xoffset|sprite[i].yoffset) == 0) + sprite[i].cstat &= ~CSTAT_SPRITE_ALIGNMENT_SLOPE; Bassert((unsigned)sprite[i].sectnum < (unsigned)numsectors && (unsigned)sprite[i].statnum < MAXSTATUS); insertsprite(sprite[i].sectnum, sprite[i].statnum); @@ -1318,7 +1319,7 @@ int32_t CheckMapCorruption(int32_t printfromlev, uint64_t tryfixing) { const int32_t tilenum = sprite[i].picnum; - if (tilenum >= 1 && tilenum <= 9 && (sprite[i].cstat&48)) + if (tilenum >= 1 && tilenum <= 9 && (sprite[i].cstat & CSTAT_SPRITE_ALIGNMENT)) { const int32_t onumct = numcorruptthings; diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index 73bd4c5c73..3fa50a4dc3 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -396,9 +396,9 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16 sprx = spr->x; spry = spr->y; - if ((spr->cstat&257) != 0) switch (spr->cstat&48) + if ((spr->cstat&257) != 0) switch (spr->cstat & CSTAT_SPRITE_ALIGNMENT) { - case 0: + case CSTAT_SPRITE_ALIGNMENT_FACING: // break; ox = sprx-cposx; @@ -422,7 +422,7 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16 x1+x2+(xdim<<11), y1+y3+(ydim<<11), col); break; - case 16: + case CSTAT_SPRITE_ALIGNMENT_WALL: if (spr->picnum == LASERLINE) { x1 = sprx; @@ -457,14 +457,14 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16 break; - case 32: - case 48: + case CSTAT_SPRITE_ALIGNMENT_FLOOR: + case CSTAT_SPRITE_ALIGNMENT_SLOPE: heinum = spriteGetSlope(j); ratio = ksqrt(heinum * heinum + 16777216); tilenum = spr->picnum; xoff = picanm[tilenum].xofs; yoff = picanm[tilenum].yofs; - if ((spr->cstat & 48) != 48) + if ((spr->cstat & CSTAT_SPRITE_ALIGNMENT) != CSTAT_SPRITE_ALIGNMENT_SLOPE) { xoff += spr->xoffset; yoff += spr->yoffset; diff --git a/source/duke3d/src/sector.cpp b/source/duke3d/src/sector.cpp index 78e2d41253..4a8e1c91f9 100644 --- a/source/duke3d/src/sector.cpp +++ b/source/duke3d/src/sector.cpp @@ -2425,7 +2425,7 @@ void A_DamageObject_Duke3D(int spriteNum, int const dmgSrc) { if (sprite[spriteNum].extra > 0) { - if ((sprite[spriteNum].cstat & 48) == 0) + if ((sprite[spriteNum].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FACING) SA(spriteNum) = (sprite[dmgSrc].ang + 1024) & 2047; sprite[spriteNum].xvel = -(sprite[dmgSrc].extra << 2); @@ -2524,7 +2524,7 @@ void A_DamageObject_Generic(int spriteNum, int const dmgSrc) { if (sprite[spriteNum].extra > 0) { - if ((sprite[spriteNum].cstat & 48) == 0) + if ((sprite[spriteNum].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FACING) SA(spriteNum) = (sprite[dmgSrc].ang + 1024) & 2047; sprite[spriteNum].xvel = -(sprite[dmgSrc].extra << 2); int16_t sectNum = SECT(spriteNum); diff --git a/source/kenbuild/src/bstub.cpp b/source/kenbuild/src/bstub.cpp index 7908ac8006..5ea3852f2f 100644 --- a/source/kenbuild/src/bstub.cpp +++ b/source/kenbuild/src/bstub.cpp @@ -291,7 +291,8 @@ void ExtAnalyzeSprites(int32_t ourx, int32_t oury, int32_t ourz, int32_t oura, i if (voxid_PLAYER == -1) break; - tspr->cstat |= 48; + tspr->clipdist |= TSPR_FLAGS_SLAB; + tspr->cstat &= ~CSTAT_SPRITE_ALIGNMENT; tspr->picnum = voxid_PLAYER; longptr = (int32_t *)voxoff[voxid_PLAYER][0]; @@ -303,7 +304,8 @@ void ExtAnalyzeSprites(int32_t ourx, int32_t oury, int32_t ourz, int32_t oura, i if (voxid_BROWNMONSTER == -1) break; - tspr->cstat |= 48; + tspr->clipdist |= TSPR_FLAGS_SLAB; + tspr->cstat &= ~CSTAT_SPRITE_ALIGNMENT; tspr->picnum = voxid_BROWNMONSTER; break; } diff --git a/source/kenbuild/src/game.cpp b/source/kenbuild/src/game.cpp index 9681e5459f..d69b4589fb 100644 --- a/source/kenbuild/src/game.cpp +++ b/source/kenbuild/src/game.cpp @@ -2023,7 +2023,8 @@ void analyzesprites(int dax, int day) if (voxid_PLAYER == -1) break; - tspr->cstat |= 48; + tspr->clipdist |= TSPR_FLAGS_SLAB; + tspr->cstat &= ~CSTAT_SPRITE_ALIGNMENT; tspr->picnum = voxid_PLAYER; auto const voxptr = (int32_t const *)voxoff[voxid_PLAYER][0]; @@ -2036,7 +2037,8 @@ void analyzesprites(int dax, int day) if (voxid_BROWNMONSTER == -1) break; - tspr->cstat |= 48; + tspr->clipdist |= TSPR_FLAGS_SLAB; + tspr->cstat &= ~CSTAT_SPRITE_ALIGNMENT; tspr->picnum = voxid_BROWNMONSTER; break; } @@ -2841,14 +2843,14 @@ void statuslistcode(void) { if (sprite[hitobject&4095].picnum == BOUNCYMAT) { - if ((sprite[hitobject&4095].cstat&48) == 0) + if ((sprite[hitobject&4095].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FACING) { sprite[i].xvel = -sprite[i].xvel; sprite[i].yvel = -sprite[i].yvel; sprite[i].zvel = -sprite[i].zvel; dist = 255; } - else if ((sprite[hitobject&4095].cstat&48) == 16) + else if ((sprite[hitobject&4095].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL) { j = sprite[hitobject&4095].ang; @@ -4074,7 +4076,8 @@ void drawscreen(short snum, int dasmoothratio) drawrooms(tposx,tposy,cpos.z,fix16_to_int(tang),choriz,mirrorsector[i]|MAXSECTORS); for (j=0,tspr=&tsprite[0]; jcstat&48) == 0) tspr->cstat |= 4; + if ((tspr->cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_FACING) + tspr->cstat |= 4; analyzesprites(tposx,tposy); renderDrawMasks(); @@ -6037,9 +6040,9 @@ void drawoverheadmap(int cposx, int cposy, int czoom, short cang) spry = osprite[j].y+mulscale16(spry-osprite[j].y,l); } - switch (spr->cstat&48) + switch (spr->cstat & CSTAT_SPRITE_ALIGNMENT) { - case 0: + case CSTAT_SPRITE_ALIGNMENT_FACING: ox = sprx-cposx; oy = spry-cposy; x1 = dmulscale16(ox,xvect,-oy,yvect); y1 = dmulscale16(oy,xvect2,ox,yvect2); @@ -6077,7 +6080,7 @@ void drawoverheadmap(int cposx, int cposy, int czoom, short cang) } } break; - case 16: + case CSTAT_SPRITE_ALIGNMENT_WALL: x1 = sprx; y1 = spry; tilenum = spr->picnum; xoff = (int)picanm[tilenum].xofs+((int)spr->xoffset); @@ -6100,7 +6103,7 @@ void drawoverheadmap(int cposx, int cposy, int czoom, short cang) x2+(xdim<<11),y2+(ydim<<11),col); break; - case 32: + case CSTAT_SPRITE_ALIGNMENT_FLOOR: if (dimensionmode[screenpeek] == 1) { tilenum = spr->picnum; diff --git a/source/rr/src/game.h b/source/rr/src/game.h index 9aebc75988..35e42a64d3 100644 --- a/source/rr/src/game.h +++ b/source/rr/src/game.h @@ -376,7 +376,7 @@ void G_OffBoat(DukePlayer_t *pPlayer); // Cstat protection mask for (currently) spawned MASKWALL* sprites. // TODO: look at more cases of cstat=(cstat&PROTECTED)|ADDED in A_Spawn()? // 2048+(32+16)+8+4 -#define SPAWN_PROTECT_CSTAT_MASK (CSTAT_SPRITE_NOSHADE|CSTAT_SPRITE_ALIGNMENT_SLAB|CSTAT_SPRITE_XFLIP|CSTAT_SPRITE_YFLIP); +#define SPAWN_PROTECT_CSTAT_MASK (CSTAT_SPRITE_NOSHADE|CSTAT_SPRITE_ALIGNMENT_MASK|CSTAT_SPRITE_XFLIP|CSTAT_SPRITE_YFLIP); void fadepal(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step); //void fadepaltile(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step,int32_t tile); diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 358226d883..048473c7d5 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -411,7 +411,7 @@ DoShadows(tspriteptr_t tsp, int viewz, SWBOOL mirror) loz = tu->loz; if (tu->lo_sp) { - if (!TEST(tu->lo_sp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_ALIGNMENT_FLOOR)) + if (!TEST(tu->lo_sp->cstat, CSTAT_SPRITE_ALIGNMENT_MASK)) { loz = DoShadowFindGroundPoint(tsp); } @@ -576,12 +576,6 @@ DoMotionBlur(tspritetype const * const tsp) } -void SetVoxelSprite(SPRITEp sp, short pic) -{ - SET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_SLAB); - sp->picnum = pic; -} - void WarpCopySprite(void) { SPRITEp sp1, sp2, sp; diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 46002fd104..0ca0dd47cb 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -5628,9 +5628,9 @@ void drawoverheadmap(int cposx, int cposy, int czoom, short cang) spry = sprite[j].y; } - switch (spr->cstat & 48) + switch (spr->cstat & CSTAT_SPRITE_ALIGNMENT) { - case 0: // Regular sprite + case CSTAT_SPRITE_ALIGNMENT_FACING: // Regular sprite if (p >= 0 && Player[p].PlayerSprite == j) { ox = sprx - cposx; @@ -5688,7 +5688,7 @@ void drawoverheadmap(int cposx, int cposy, int czoom, short cang) } } break; - case 16: // Rotated sprite + case CSTAT_SPRITE_ALIGNMENT_WALL: // Rotated sprite x1 = sprx; y1 = spry; tilenum = spr->picnum; @@ -5720,7 +5720,7 @@ void drawoverheadmap(int cposx, int cposy, int czoom, short cang) x2 + (xdim << 11), y2 + (ydim << 11), col); break; - case 32: // Floor sprite + case CSTAT_SPRITE_ALIGNMENT_FLOOR: // Floor sprite if (dimensionmode == 5) { tilenum = spr->picnum; diff --git a/source/sw/src/jnstub.cpp b/source/sw/src/jnstub.cpp index 5c3ef6e4bc..2517202bc6 100644 --- a/source/sw/src/jnstub.cpp +++ b/source/sw/src/jnstub.cpp @@ -573,10 +573,10 @@ ExtAnalyzeSprites(int32_t ourx, int32_t oury, int32_t ourz, int32_t oura, int32_ if (aVoxelArray[tspr->picnum] >= 0) { - // Turn on voxels tspr->picnum = aVoxelArray[tspr->picnum]; // Get the voxel number - tspr->cstat |= 48; // Set stat to voxelize sprite + tspr->clipdist |= TSPR_FLAGS_SLAB; // Set stat to voxelize sprite + tspr->cstat &= ~CSTAT_SPRITE_ALIGNMENT; } } } diff --git a/source/sw/src/jsector.cpp b/source/sw/src/jsector.cpp index 166aee821f..6c5ce5f409 100644 --- a/source/sw/src/jsector.cpp +++ b/source/sw/src/jsector.cpp @@ -1083,7 +1083,8 @@ JAnalyzeSprites(tspriteptr_t tspr) { // Turn on voxels tspr->picnum = aVoxelArray[tspr->picnum].Voxel; // Get the voxel number - tspr->cstat |= 48; // Set stat to voxelize sprite + tspr->clipdist |= TSPR_FLAGS_SLAB; // Set stat to voxelize sprite + tspr->cstat &= ~CSTAT_SPRITE_ALIGNMENT; } } else @@ -1093,7 +1094,7 @@ JAnalyzeSprites(tspriteptr_t tspr) case 764: // Gun barrel if (!usevoxels || videoGetRenderMode() == REND_POLYMER || (spriteext[tspr->owner].flags&SPREXT_NOTMD)) { - tspr->cstat |= 16; + tspr->cstat |= CSTAT_SPRITE_ALIGNMENT_WALL; break; } @@ -1101,7 +1102,8 @@ JAnalyzeSprites(tspriteptr_t tspr) { // Turn on voxels tspr->picnum = aVoxelArray[tspr->picnum].Voxel; // Get the voxel number - tspr->cstat |= 48; // Set stat to voxelize sprite + tspr->clipdist |= TSPR_FLAGS_SLAB; // Set stat to voxelize sprite + tspr->cstat &= ~CSTAT_SPRITE_ALIGNMENT; } break; } diff --git a/source/sw/src/sector.cpp b/source/sw/src/sector.cpp index 103b251e18..be58a7318f 100644 --- a/source/sw/src/sector.cpp +++ b/source/sw/src/sector.cpp @@ -1036,7 +1036,7 @@ SectorExp(short SpriteNum, short sectnum, short orig_ang, int zh) USERp eu; int x,y,z; - RESET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_WALL|CSTAT_SPRITE_ALIGNMENT_FLOOR); + RESET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_MASK); SectorMidPoint(sectnum, &x, &y, &z); sp->ang = orig_ang; sp->x = x; diff --git a/source/sw/src/sprite.cpp b/source/sw/src/sprite.cpp index 1084f62631..89b55aa26b 100644 --- a/source/sw/src/sprite.cpp +++ b/source/sw/src/sprite.cpp @@ -1746,7 +1746,7 @@ SpriteSetupPost(void) if (ds->picnum == ST1) continue; - if (TEST(ds->cstat, CSTAT_SPRITE_ALIGNMENT_WALL|CSTAT_SPRITE_ALIGNMENT_FLOOR)) + if (TEST(ds->cstat, CSTAT_SPRITE_ALIGNMENT_MASK)) continue; if (User[i]) @@ -1812,8 +1812,8 @@ SpriteSetup(void) } // CSTAT_SPIN is insupported - get rid of it - if (TEST(sp->cstat, CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLAB) - RESET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_SLAB); + if (TEST(sp->cstat, CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_SLOPE) + RESET(sp->cstat, CSTAT_SPRITE_ALIGNMENT_SLOPE); // if BLOCK is set set BLOCK_HITSCAN // Hope this doesn't screw up anything