- ported slope sorite support from NBlood.

For Polymost only so far.
This commit is contained in:
Christoph Oelckers 2021-12-20 20:27:12 +01:00
parent 156369ac8a
commit 6fd4d6d550
6 changed files with 257 additions and 43 deletions

View file

@ -67,10 +67,9 @@ static inline void get_wallspr_points(T const * const spr, int32_t *x1, int32_t
// x1, y1: in/out
// rest x/y: out
template <typename T>
static inline void get_floorspr_points(T const * const spr, int32_t px, int32_t py,
static inline void get_floorspr_points(spritetype const * const spr, int32_t px, int32_t py,
int32_t *x1, int32_t *x2, int32_t *x3, int32_t *x4,
int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4)
int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4, int heinum = 0)
{
const int32_t tilenum = spr->picnum;
const int32_t cosang = bcos(spr->ang);
@ -81,6 +80,8 @@ static inline void get_floorspr_points(T const * const spr, int32_t px, int32_t
vec2_t adjofs = { tileLeftOffset(tilenum) + spr->xoffset, tileTopOffset(tilenum) + spr->yoffset };
int32_t const ratio = ksqrt(heinum * heinum + 4096 * 4096);
if (spr->cstat & CSTAT_SPRITE_XFLIP)
adjofs.x = -adjofs.x;
@ -89,10 +90,11 @@ static inline void get_floorspr_points(T const * const spr, int32_t px, int32_t
vec2_t const center = { ((span.x >> 1) + adjofs.x) * repeat.x, ((span.y >> 1) + adjofs.y) * repeat.y };
vec2_t const rspan = { span.x * repeat.x, span.y * repeat.y };
vec2_t const ofs = { -MulScale(cosang, rspan.y, 16), -MulScale(sinang, rspan.y, 16) };
vec2_t const ofs = { -DivScale(MulScale(cosang, rspan.y, 16), ratio, 12), -DivScale(MulScale(sinang, rspan.y, 16), ratio, 12) };
vec2_t const cossinslope = { DivScale(cosang, ratio, 12), DivScale(sinang, ratio, 12) };
*x1 += DMulScale(sinang, center.x, cosang, center.y, 16) - px;
*y1 += DMulScale(sinang, center.y, -cosang, center.x, 16) - py;
*x1 += DMulScale(sinang, center.x, cossinslope.x, center.y, 16) - px;
*y1 += DMulScale(cossinslope.y, center.y, -cosang, center.x, 16) - py;
*x2 = *x1 - MulScale(sinang, rspan.x, 16);
*y2 = *y1 + MulScale(cosang, rspan.x, 16);
@ -131,6 +133,16 @@ int clipinsidebox(vec2_t *vect, int wallnum, int walldist)
return (v2.x >= v2.y) << 1;
}
static int32_t spriteGetZOfSlope(const spritetype* spr, int32_t dax, int32_t day)
{
int16_t const heinum = spriteGetSlope(spr);
if (heinum == 0)
return spr->z;
int const j = DMulScale(bsin(spr->ang + 1024), day - spr->y, -bsin(spr->ang + 512), dax - spr->x, 4);
return spr->z + MulScale(heinum, j, 18);
}
//
// clipinsideboxline
@ -590,7 +602,7 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
CollisionBase obj;
obj.setSprite(actor);
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)
@ -644,18 +656,32 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
}
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
{
if (pos->z > spr->z-flordist && pos->z < spr->z+ceildist)
int heinum, sz;
if ((cstat & (CSTAT_SPRITE_ALIGNMENT_MASK)) == CSTAT_SPRITE_ALIGNMENT_SLOPE)
{
heinum = spriteGetSlope(spr);
sz = spriteGetZOfSlope(spr, pos->x, pos->y);
}
else
{
heinum = 0;
sz = spr->z;
}
if (pos->z > sz - flordist && pos->z < sz + ceildist)
{
if ((cstat & CSTAT_SPRITE_ONE_SIDE) != 0)
if ((pos->z > spr->z) == ((cstat & CSTAT_SPRITE_YFLIP)==0))
if ((pos->z > sz) == ((cstat & CSTAT_SPRITE_YFLIP)==0))
continue;
rxi[0] = p1.x;
ryi[0] = p1.y;
get_floorspr_points((uspriteptr_t) spr, 0, 0, &rxi[0], &rxi[1], &rxi[2], &rxi[3],
&ryi[0], &ryi[1], &ryi[2], &ryi[3]);
get_floorspr_points(spr, 0, 0, &rxi[0], &rxi[1], &rxi[2], &rxi[3],
&ryi[0], &ryi[1], &ryi[2], &ryi[3], heinum);
vec2_t v = { MulScale(bcos(spr->ang - 256), walldist, 14),
MulScale(bsin(spr->ang - 256), walldist, 14) };
@ -682,6 +708,58 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
addclipline(rxi[0]+v.x, ryi[0]+v.y, rxi[3]+v.y, ryi[3]-v.x, obj, false);
}
}
if (heinum == 0)
continue;
// the rest is for slope sprites only.
const int32_t tilenum = spr->picnum;
const int32_t cosang = bcos(spr->ang);
const int32_t sinang = bsin(spr->ang);
vec2_t const span = { tileWidth(tilenum), tileHeight(tilenum) };
vec2_t const repeat = { spr->xrepeat, spr->yrepeat };
vec2_t adjofs = { tileLeftOffset(tilenum), tileTopOffset(tilenum) };
if (spr->cstat & CSTAT_SPRITE_XFLIP)
adjofs.x = -adjofs.x;
if (spr->cstat & CSTAT_SPRITE_YFLIP)
adjofs.y = -adjofs.y;
int32_t const centerx = ((span.x >> 1) + adjofs.x) * repeat.x;
int32_t const centery = ((span.y >> 1) + adjofs.y) * repeat.y;
int32_t const rspanx = span.x * repeat.x;
int32_t const rspany = span.y * repeat.y;
int32_t const ratio = ksqrt(heinum * heinum + 4096 * 4096);
int32_t zz[3] = { pos->z, pos->z + flordist, pos->z - ceildist };
for (int k = 0; k < 3; k++)
{
int32_t jj = DivScale(spr->z - zz[k], heinum, 18);
int32_t jj2 = MulScale(jj, ratio, 12);
if (jj2 > (centery << 8) || jj2 < ((centery - rspany) << 8))
continue;
int32_t x1 = spr->x + MulScale(sinang, centerx, 16) + MulScale(jj, cosang, 24);
int32_t y1 = spr->y - MulScale(cosang, centerx, 16) + MulScale(jj, sinang, 24);
int32_t x2 = x1 - MulScale(sinang, rspanx, 16);
int32_t y2 = y1 + MulScale(cosang, rspanx, 16);
vec2_t const v = { MulScale(bcos(spr->ang - 256), walldist, 14),
MulScale(bsin(spr->ang - 256), walldist, 14) };
if (clipinsideboxline(cent.x, cent.y, x1, y1, x2, y2, rad) != 0)
{
if ((x1 - pos->x) * (y2 - pos->y) >= (x2 - pos->x) * (y1 - pos->y))
{
addclipline(x1 + v.x, y1 + v.y, x2 + v.y, y2 - v.x, obj, false);
}
else
{
if ((cstat & CSTAT_SPRITE_ONE_SIDE) != 0)
continue;
addclipline(x2 - v.x, y2 - v.y, x1 - v.y, y1 + v.x, obj, false);
}
}
}
break;
}
}
@ -1095,15 +1173,17 @@ void getzrange(const vec3_t& pos, sectortype* sect, int32_t* ceilz, CollisionBas
}
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
{
daz = spr->z; daz2 = daz;
if ((cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR) daz = spr->z;
else daz = spriteGetZOfSlope(spr, pos.x, pos.y);
if ((cstat & CSTAT_SPRITE_ONE_SIDE) != 0 && (pos.z > daz) == ((cstat & CSTAT_SPRITE_YFLIP)==0))
continue;
vec2_t v2, v3, v4;
get_floorspr_points((uspriteptr_t) spr, pos.x, pos.y, &v1.x, &v2.x, &v3.x, &v4.x,
&v1.y, &v2.y, &v3.y, &v4.y);
&v1.y, &v2.y, &v3.y, &v4.y, spriteGetSlope(spr));
vec2_t const da = { MulScale(bcos(spr->ang - 256), walldist + 4, 14),
MulScale(bsin(spr->ang - 256), walldist + 4, 14) };
@ -1409,13 +1489,44 @@ int hitscan(const vec3_t& start, const sectortype* startsect, const vec3_t& dire
continue;
get_floorspr_points((uspriteptr_t)spr, intx, inty, &x1, &x2, &x3, &x4,
&y1, &y2, &y3, &y4);
&y1, &y2, &y3, &y4, spriteGetSlope(spr));
if (get_floorspr_clipyou({x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}))
hit_set(&hitinfo, sec, nullptr, actor, intx, inty, intz);
break;
}
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
{
int32_t x3, y3, x4, y4, zz;
int32_t const heinum = spriteGetSlope(spr);
int32_t const dax = (heinum * sintable[(spr->ang + 1024) & 2047]) << 1;
int32_t const day = (heinum * sintable[(spr->ang + 512) & 2047]) << 1;
int32_t const j = (vz << 8) - DMulScale(dax, vy, -day, vx, 15);
if (j == 0) continue;
if ((cstat & 64) != 0)
if ((j < 0) == ((cstat & 8) == 0)) continue;
int32_t i = ((spr->z - sv->z) << 8) + DMulScale(dax, sv->y - spr->y, -day, sv->x - spr->x, 15);
if ((i ^ j) < 0 || (abs(i) >> 1) >= abs(j)) continue;
i = DivScale(i, j, 30);
intx = sv->x + MulScale(vx, i, 30);
inty = sv->y + MulScale(vy, i, 30);
intz = sv->z + MulScale(vz, i, 30);
if (abs(intx - sv->x) + abs(inty - sv->y) > abs((hitinfo.hitpos.x) - sv->x) + abs((hitinfo.hitpos.y) - sv->y))
continue;
get_floorspr_points((uspriteptr_t)spr, intx, inty, &x1, &x2, &x3, &x4,
&y1, &y2, &y3, &y4, spriteGetSlope(spr));
if (get_floorspr_clipyou({ x1, y1 }, { x2, y2 }, { x3, y3 }, { x4, y4 }))
hit_set(&hitinfo, sec, nullptr, actor, intx, inty, intz);
break;
}
}
}
}

View file

@ -2635,6 +2635,35 @@ static int32_t polymost_lintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y
return rv;
}
static inline int16_t tspriteGetSlope(tspriteptr_t const tspr)
{
if (!(tspr->cstat2 & CSTAT2_SPRITE_SLOPE))
return 0;
return uint8_t(tspr->xoffset) + (uint8_t(tspr->yoffset) << 8);
}
static inline int32_t tspriteGetZOfSlope(tspriteptr_t const tspr, int32_t dax, int32_t day)
{
int16_t const heinum = tspriteGetSlope(tspr);
if (heinum == 0)
return tspr->z;
int const j = DMulScale(bsin(tspr->ang + 1024), day - tspr->y, -bsin(tspr->ang + 512), dax - tspr->x, 4);
return tspr->z + MulScale(heinum, j, 18);
}
static inline float tspriteGetZOfSlopeFloat(tspriteptr_t const tspr, float dax, float day)
{
int16_t const heinum = tspriteGetSlope(tspr);
if (heinum == 0)
return float(tspr->z);
float const f = bsin(tspr->ang + 1024) * (day - tspr->y) - bsin(tspr->ang + 512) * (dax - tspr->x);
return float(tspr->z) + heinum * f * (1.f / 4194304.f);
}
#define TSPR_OFFSET_FACTOR .0002f
#define TSPR_OFFSET(tspr) (TSPR_OFFSET_FACTOR + ((tspr->ownerActor ? tspr->ownerActor->GetIndex() & 63 : 0) * TSPR_OFFSET_FACTOR))
@ -2664,9 +2693,16 @@ void polymost_drawsprite(int32_t snum)
if ((globalorientation & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_SLAB) // only non-voxel sprites should do this
{
int const flag = hw_hightile && TileFiles.tiledata[globalpicnum].hiofs.xsize;
int const flag = hw_hightile && TileFiles.tiledata[globalpicnum].hiofs.xsize > 0;
off = { (int32_t)tspr->xoffset + (flag ? TileFiles.tiledata[globalpicnum].hiofs.xoffs : tileLeftOffset(globalpicnum)),
(int32_t)tspr->yoffset + (flag ? TileFiles.tiledata[globalpicnum].hiofs.yoffs : tileTopOffset(globalpicnum)) };
if (!(tspr->cstat2 & CSTAT2_SPRITE_SLOPE))
{
off.x += tspr->xoffset;
off.y += tspr->yoffset;
}
}
int32_t method = DAMETH_MASK | DAMETH_CLAMPED;
@ -3013,24 +3049,29 @@ void polymost_drawsprite(int32_t snum)
case 2: // Floor sprite
GLInterface.SetVisibility(sectorVisibility(tspr->sector()) * (4.f/5.f)); // No idea why this uses a different visibility setting...
if ((globalorientation & 64) != 0 && (globalposz > pos.z) == (!(globalorientation & 8)))
if ((globalorientation & 64) != 0
&& (globalposz > tspriteGetZOfSlope(tspr, globalposx, globalposy)) == (!(globalorientation & 8)))
goto _drawsprite_return;
else
{
int16_t const heinum = tspriteGetSlope(tspr);
float const fheinum = heinum * (1.f / 4096.f);
float ratio = 1.f / sqrtf(fheinum * fheinum + 1.f);
if ((globalorientation & 4) > 0)
off.x = -off.x;
if ((globalorientation & 8) > 0)
off.y = -off.y;
FVector2 const p0 = { (float)(((tsiz.x + 1) >> 1) - off.x) * tspr->xrepeat,
(float)(((tsiz.y + 1) >> 1) - off.y) * tspr->yrepeat },
(float)(((tsiz.y + 1) >> 1) - off.y) * tspr->yrepeat * ratio },
p1 = { (float)((tsiz.x >> 1) + off.x) * tspr->xrepeat,
(float)((tsiz.y >> 1) + off.y) * tspr->yrepeat };
(float)((tsiz.y >> 1) + off.y) * tspr->yrepeat * ratio };
float const c = bcosf(tspr->ang, -16);
float const s = bsinf(tspr->ang, -16);
FVector2 pxy[6];
FVector3 pxy[6];
// Project 3D to 2D
for (intptr_t j = 0; j < 4; j++)
@ -3058,20 +3099,19 @@ void polymost_drawsprite(int32_t snum)
s0.Y -= c * p1.X;
}
pxy[j] = { s0.Y * gcosang - s0.X * gsinang, s0.X * gcosang2 + s0.Y * gsinang2 };
pxy[j] = { s0.Y * gcosang - s0.X * gsinang, s0.X * gcosang2 + s0.Y * gsinang2,
float(tspriteGetZOfSlopeFloat(tspr, s0.X + globalposx, s0.Y + globalposy)) };
}
if (pos.z < globalposz) // if floor sprite is above you, reverse order of points
if (tspriteGetZOfSlope(tspr, globalposx, globalposy) < globalposz) // if floor sprite is above you, reverse order of points
{
static_assert(sizeof(uint64_t) == sizeof(FVector2));
std::swap(pxy[0], pxy[1]);
std::swap(pxy[2], pxy[3]);
}
// Clip to SCISDIST plane
int32_t npoints = 0;
FVector2 p2[6];
FVector3 p2[6];
for (intptr_t i = 0, j = 1; i < 4; j = ((++i + 1) & 3))
{
@ -3081,8 +3121,9 @@ void polymost_drawsprite(int32_t snum)
if ((pxy[i].Y >= SCISDIST) != (pxy[j].Y >= SCISDIST))
{
float const f = (SCISDIST - pxy[i].Y) / (pxy[j].Y - pxy[i].Y);
FVector2 const t = { (pxy[j].X - pxy[i].X) * f + pxy[i].X,
(pxy[j].Y - pxy[i].Y) * f + pxy[i].Y };
FVector3 const t = { (pxy[j].X - pxy[i].X) * f + pxy[i].X,
(pxy[j].Y - pxy[i].Y) * f + pxy[i].Y,
(pxy[j].Z - pxy[i].Z)* f + pxy[i].Z };
p2[npoints++] = t;
}
}
@ -3094,32 +3135,40 @@ void polymost_drawsprite(int32_t snum)
int fadjust = 0;
// unfortunately, offsetting by only 1 isn't enough on most Android devices
if (pos.z == sec->ceilingz || pos.z == sec->ceilingz + 1)
pos.z = sec->ceilingz + 2, fadjust = (tspr->ownerActor->GetIndex() & 31);
if (heinum == 0)
{
// unfortunately, offsetting by only 1 isn't enough on most Android devices
if (pos.z == sec->ceilingz || pos.z == sec->ceilingz + 1)
pos.z = sec->ceilingz + 2, fadjust = (tspr->ownerActor->GetIndex() & 31);
if (pos.z == sec->floorz || pos.z == sec->floorz - 1)
pos.z = sec->floorz - 2, fadjust = -((tspr->ownerActor->GetIndex() & 31));
if (pos.z == sec->floorz || pos.z == sec->floorz - 1)
pos.z = sec->floorz - 2, fadjust = -((tspr->ownerActor->GetIndex() & 31));
}
float f = (float)(pos.z - globalposz + fadjust) * gyxscale;
FVector2 pxy2[6];
double pfy[6];
for (intptr_t j = 0; j < npoints; j++)
{
float const ryp0 = 1.f / p2[j].Y;
pxy[j] = { ghalfx * p2[j].X * ryp0 + ghalfx, f * ryp0 + ghoriz };
float const fs = (float)(p2[j].Z - globalposz + fadjust) * gyxscale;
pxy2[j] = { ghalfx * p2[j].X * ryp0 + ghalfx, fs * ryp0 + ghoriz };
pfy[j] = double(gyxscale * ryp0) + ghoriz;
}
// gd? Copied from floor rendering code
xtex.d = 0;
ytex.d = gxyaspect / (double)(pos.z - globalposz + fadjust);
ytex.d = gxyaspect;
if (heinum == 0)
ytex.d /= (double)(pos.z - globalposz + fadjust);
otex.d = -ghoriz * ytex.d;
// copied&modified from relative alignment
FVector2 const vv = { (float)tspr->x + s * p1.X + c * p1.Y, (float)tspr->y + s * p1.Y - c * p1.X };
FVector2 ff = { -(p0.X + p1.X) * s, (p0.X + p1.X) * c };
f = polymost_invsqrt_approximation(ff.X * ff.X + ff.Y * ff.Y);
float f = 1.f / sqrtf(ff.X * ff.X + ff.Y * ff.Y);
ff.X *= f;
ff.Y *= f;
@ -3156,10 +3205,48 @@ void polymost_drawsprite(int32_t snum)
otex.u = ftsiz.X * otex.d - otex.u;
}
if (heinum != 0)
{
vec3d_t const duv[3] = {
{ (pxy2[0].X * xtex.d + pfy[0] * ytex.d + otex.d),
(pxy2[0].X * xtex.u + pfy[0] * ytex.u + otex.u),
(pxy2[0].X * xtex.v + pfy[0] * ytex.v + otex.v)
},
{ (pxy2[1].X * xtex.d + pfy[1] * ytex.d + otex.d),
(pxy2[1].X * xtex.u + pfy[1] * ytex.u + otex.u),
(pxy2[1].X * xtex.v + pfy[1] * ytex.v + otex.v)
},
{ (pxy2[2].X * xtex.d + pfy[2] * ytex.d + otex.d),
(pxy2[2].X * xtex.u + pfy[2] * ytex.u + otex.u),
(pxy2[2].X * xtex.v + pfy[2] * ytex.v + otex.v)
}
};
FVector3 oxyz[2] = { { (float)(pxy2[1].Y - pxy2[2].Y), (float)(pxy2[2].Y - pxy2[0].Y), (float)(pxy2[0].Y - pxy2[1].Y) },
{ (float)(pxy2[2].X - pxy2[1].X), (float)(pxy2[0].X - pxy2[2].X), (float)(pxy2[1].X - pxy2[0].X) } };
float const r = 1.f / (oxyz[0].X * pxy2[0].X + oxyz[0].Y * pxy2[1].X + oxyz[0].Z * pxy2[2].X);
xtex.d = (oxyz[0].X * duv[0].d + oxyz[0].Y * duv[1].d + oxyz[0].Z * duv[2].d) * r;
xtex.u = (oxyz[0].X * duv[0].u + oxyz[0].Y * duv[1].u + oxyz[0].Z * duv[2].u) * r;
xtex.v = (oxyz[0].X * duv[0].v + oxyz[0].Y * duv[1].v + oxyz[0].Z * duv[2].v) * r;
ytex.d = (oxyz[1].X * duv[0].d + oxyz[1].Y * duv[1].d + oxyz[1].Z * duv[2].d) * r;
ytex.u = (oxyz[1].X * duv[0].u + oxyz[1].Y * duv[1].u + oxyz[1].Z * duv[2].u) * r;
ytex.v = (oxyz[1].X * duv[0].v + oxyz[1].Y * duv[1].v + oxyz[1].Z * duv[2].v) * r;
otex.d = duv[0].d - pxy2[0].X * xtex.d - pxy2[0].Y * ytex.d;
otex.u = duv[0].u - pxy2[0].X * xtex.u - pxy2[0].Y * ytex.u;
otex.v = duv[0].v - pxy2[0].X * xtex.v - pxy2[0].Y * ytex.v;
float const rr = sqrtf(fheinum * fheinum + 1.f);
xtex.v *= rr; ytex.v *= rr; otex.v *= rr;
}
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
pow2xsplit = 0;
polymost_drawpoly(pxy, npoints, method, tempsiz);
polymost_drawpoly(pxy2, npoints, method, tempsiz);
drawpoly_srepeat = 0;
drawpoly_trepeat = 0;

View file

@ -569,7 +569,7 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang)
if (spr->cstat & CSTAT_SPRITE_INVISIBLE)
continue;
if ((spr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FLOOR)
if (spr->cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR) // floor and slope sprites
{
if ((spr->cstat & (CSTAT_SPRITE_ONE_SIDE | CSTAT_SPRITE_YFLIP)) == (CSTAT_SPRITE_ONE_SIDE | CSTAT_SPRITE_YFLIP))
continue; // upside down

View file

@ -260,7 +260,7 @@ inline void spriteSetSlope(spritetype* spr, int heinum)
}
}
inline int spriteGetSlope(spritetype* spr)
inline int spriteGetSlope(const spritetype* spr)
{
return ((spr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_SLOPE) ? 0 : uint8_t(spr->xoffset) + (uint8_t(spr->yoffset) << 8);
}

View file

@ -163,6 +163,7 @@ enum ESpriteBits2
CSTAT2_SPRITE_MDLROTATE = 1, // Only for tsprites: rotate if this is a model or voxel.
CSTAT2_SPRITE_NOFIND = 2, // Invisible to neartag and hitscan
CSTAT2_SPRITE_MAPPED = 4, // sprite was mapped for automap
CSTAT2_SPRITE_SLOPE = 8, // Only for tsprites: render as sloped sprite
};
@ -568,6 +569,14 @@ struct tspritetype : public spritetypebase
time = spr->time;
cstat2 = spr->cstat2;
ownerActor = nullptr;
// need to copy the slope sprite flag around because for tsprites the bit combination means 'voxel'.
if ((cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_SLOPE)
{
cstat &= ~CSTAT_SPRITE_ALIGNMENT_WALL;
cstat2 |= CSTAT2_SPRITE_SLOPE;
}
}
};

View file

@ -416,7 +416,7 @@ bool GameInterface::DrawAutomapPlayer(int mx, int my, int cposx, int cposy, int
if ((spr->cstat & CSTAT_SPRITE_BLOCK_ALL) != 0) switch (spr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK)
{
case 0:
case CSTAT_SPRITE_ALIGNMENT_FACING:
//break;
ox = sprx - cposx;
@ -440,7 +440,7 @@ bool GameInterface::DrawAutomapPlayer(int mx, int my, int cposx, int cposy, int
x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
break;
case 16:
case CSTAT_SPRITE_ALIGNMENT_WALL:
if (spr->picnum == TILE_LASERLINE)
{
x1 = sprx;
@ -475,10 +475,17 @@ bool GameInterface::DrawAutomapPlayer(int mx, int my, int cposx, int cposy, int
break;
case 32:
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
case CSTAT_SPRITE_ALIGNMENT_SLOPE:
tilenum = spr->picnum;
xoff = tileLeftOffset(tilenum) + spr->xoffset;
yoff = tileTopOffset(tilenum) + spr->yoffset;
xoff = tileLeftOffset(tilenum);
yoff = tileTopOffset(tilenum);
if ((spr->cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != CSTAT_SPRITE_ALIGNMENT_SLOPE)
{
xoff += spr->xoffset;
yoff += spr->yoffset;
}
if ((spr->cstat & CSTAT_SPRITE_XFLIP) > 0) xoff = -xoff;
if ((spr->cstat & CSTAT_SPRITE_YFLIP) > 0) yoff = -yoff;