- fixed clipping code.

This seems to require the old code as-is - the latest refactoring broke some stuff again and had to be reverted.
This commit is contained in:
Christoph Oelckers 2021-03-27 15:03:57 +01:00
parent d1c23d1ad0
commit e7d73fd8e7
1 changed files with 122 additions and 49 deletions

View File

@ -23,6 +23,8 @@ static uint8_t clipsectormap[(MAXSECTORS+7)>>3];
static uint8_t origclipsectormap[(MAXSECTORS+7)>>3];
static int16_t clipobjectval[MAXCLIPNUM];
static uint8_t clipignore[(MAXCLIPNUM+7)>>3];
static int32_t rxi[8], ryi[8];
int32_t quickloadboard=0;
@ -32,6 +34,73 @@ int32_t hitallsprites = 0;
////////// CLIPMOVE //////////
// x1, y1: in/out
// rest x/y: out
template <typename T>
static inline void get_wallspr_points(T const * const spr, int32_t *x1, int32_t *x2,
int32_t *y1, int32_t *y2)
{
//These lines get the 2 points of the rotated sprite
//Given: (x1, y1) starts out as the center point
const int32_t tilenum=spr->picnum, ang=spr->ang;
const int32_t xrepeat = spr->xrepeat;
int32_t xoff = tileLeftOffset(tilenum) + spr->xoffset;
int32_t k, l, dax, day;
if (spr->cstat&4)
xoff = -xoff;
dax = bsin(ang) * xrepeat;
day = -bcos(ang) * xrepeat;
l = tileWidth(tilenum);
k = (l>>1)+xoff;
*x1 -= MulScale(dax,k, 16);
*x2 = *x1 + MulScale(dax,l, 16);
*y1 -= MulScale(day,k, 16);
*y2 = *y1 + MulScale(day,l, 16);
}
// 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,
int32_t *x1, int32_t *x2, int32_t *x3, int32_t *x4,
int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4)
{
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) + spr->xoffset, tileTopOffset(tilenum) + spr->yoffset };
if (spr->cstat & 4)
adjofs.x = -adjofs.x;
if (spr->cstat & 8)
adjofs.y = -adjofs.y;
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) };
*x1 += DMulScale(sinang, center.x, cosang, center.y, 16) - px;
*y1 += DMulScale(sinang, center.y, -cosang, center.x, 16) - py;
*x2 = *x1 - MulScale(sinang, rspan.x, 16);
*y2 = *y1 + MulScale(cosang, rspan.x, 16);
*x3 = *x2 + ofs.x, *x4 = *x1 + ofs.x;
*y3 = *y2 + ofs.y, *y4 = *y1 + ofs.y;
}
int32_t clipmoveboxtracenum = 3;
//
@ -569,30 +638,31 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
{
int32_t height, daz = spr->z+spriteheightofs(j, &height, 1);
if (pos->z > daz - height - flordist && pos->z < daz + ceildist)
if (pos->z > daz-height-flordist && pos->z < daz+ceildist)
{
vec2_t pp[2];
GetWallSpritePosition(spr, p1, pp);
vec2_t p2;
if (clipinsideboxline(cent.x, cent.y, pp[0].x, pp[0].y, pp[1].x, pp[1].y, rad) != 0)
get_wallspr_points(spr, &p1.x, &p2.x, &p1.y, &p2.y);
if (clipinsideboxline(cent.x, cent.y, p1.x, p1.y, p2.x, p2.y, rad) != 0)
{
vec2_t v = { MulScale(bcos(spr->ang + 256), walldist, 14),
MulScale(bsin(spr->ang + 256), walldist, 14) };
if ((pp[0].x - pos->x) * (pp[1].y - pos->y) >= (pp[1].x - pos->x) * (pp[0].y - pos->y)) // Front
addclipline(pp[0].x + v.x, pp[0].y + v.y, pp[1].x + v.y, pp[1].y - v.x, (int16_t)j + 49152, false);
if ((p1.x-pos->x) * (p2.y-pos->y) >= (p2.x-pos->x) * (p1.y-pos->y)) // Front
addclipline(p1.x+v.x, p1.y+v.y, p2.x+v.y, p2.y-v.x, (int16_t)j+49152, false);
else
{
if ((cstat & 64) != 0)
continue;
addclipline(pp[1].x - v.x, pp[1].y - v.y, pp[0].x - v.y, pp[0].y + v.x, (int16_t)j + 49152, false);
addclipline(p2.x-v.x, p2.y-v.y, p1.x-v.y, p1.y+v.x, (int16_t)j+49152, false);
}
//Side blocker
if ((pp[1].x - pp[0].x) * (pos->x - pp[0].x) + (pp[1].y - pp[0].y) * (pos->y - pp[0].y) < 0)
addclipline(pp[0].x - v.y, pp[0].y + v.x, pp[0].x + v.x, pp[0].y + v.y, (int16_t)j + 49152, true);
else if ((pp[0].x - pp[1].x) * (pos->x - pp[1].x) + (pp[0].y - pp[1].y) * (pos->y - pp[1].y) < 0)
addclipline(pp[1].x + v.y, pp[1].y - v.x, pp[1].x - v.x, pp[1].y - v.y, (int16_t)j + 49152, true);
if ((p2.x-p1.x) * (pos->x-p1.x)+(p2.y-p1.y) * (pos->y-p1.y) < 0)
addclipline(p1.x-v.y, p1.y+v.x, p1.x+v.x, p1.y+v.y, (int16_t)j+49152, true);
else if ((p1.x-p2.x) * (pos->x-p2.x)+(p1.y-p2.y) * (pos->y-p2.y) < 0)
addclipline(p2.x+v.y, p2.y-v.x, p2.x-v.x, p2.y-v.y, (int16_t)j+49152, true);
}
}
break;
@ -600,38 +670,41 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
{
if (pos->z > spr->z - flordist && pos->z < spr->z + ceildist)
if (pos->z > spr->z-flordist && pos->z < spr->z+ceildist)
{
if ((cstat & 64) != 0)
if ((pos->z > spr->z) == ((cstat & 8) == 0))
if ((cstat&64) != 0)
if ((pos->z > spr->z) == ((cstat&8)==0))
continue;
vec2_t pp[4];
GetFlatSpritePosition(spr, p1, pp);
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]);
vec2_t v = { MulScale(bcos(spr->ang - 256), walldist, 14),
MulScale(bsin(spr->ang - 256), walldist, 14) };
if ((pp[0].x - pos->x) * (pp[1].y - pos->y) < (pp[1].x - pos->x) * (pp[0].y - pos->y))
if ((rxi[0]-pos->x) * (ryi[1]-pos->y) < (rxi[1]-pos->x) * (ryi[0]-pos->y))
{
if (clipinsideboxline(cent.x, cent.y, pp[1].x, pp[1].y, pp[0].x, pp[0].y, rad) != 0)
addclipline(pp[1].x - v.y, pp[1].y + v.x, pp[0].x + v.x, pp[0].y + v.y, (int16_t)j + 49152, false);
if (clipinsideboxline(cent.x, cent.y, rxi[1], ryi[1], rxi[0], ryi[0], rad) != 0)
addclipline(rxi[1]-v.y, ryi[1]+v.x, rxi[0]+v.x, ryi[0]+v.y, (int16_t)j+49152, false);
}
else if ((pp[2].x - pos->x) * (pp[3].y - pos->y) < (pp[3].x - pos->x) * (pp[2].y - pos->y))
else if ((rxi[2]-pos->x) * (ryi[3]-pos->y) < (rxi[3]-pos->x) * (ryi[2]-pos->y))
{
if (clipinsideboxline(cent.x, cent.y, pp[3].x, pp[3].y, pp[2].x, pp[2].y, rad) != 0)
addclipline(pp[3].x + v.y, pp[3].y - v.x, pp[2].x - v.x, pp[2].y - v.y, (int16_t)j + 49152, false);
if (clipinsideboxline(cent.x, cent.y, rxi[3], ryi[3], rxi[2], ryi[2], rad) != 0)
addclipline(rxi[3]+v.y, ryi[3]-v.x, rxi[2]-v.x, ryi[2]-v.y, (int16_t)j+49152, false);
}
if ((pp[1].x - pos->x) * (pp[2].y - pos->y) < (pp[2].x - pos->x) * (pp[1].y - pos->y))
if ((rxi[1]-pos->x) * (ryi[2]-pos->y) < (rxi[2]-pos->x) * (ryi[1]-pos->y))
{
if (clipinsideboxline(cent.x, cent.y, pp[2].x, pp[2].y, pp[1].x, pp[1].y, rad) != 0)
addclipline(pp[2].x - v.x, pp[2].y - v.y, pp[1].x - v.y, pp[1].y + v.x, (int16_t)j + 49152, false);
if (clipinsideboxline(cent.x, cent.y, rxi[2], ryi[2], rxi[1], ryi[1], rad) != 0)
addclipline(rxi[2]-v.x, ryi[2]-v.y, rxi[1]-v.y, ryi[1]+v.x, (int16_t)j+49152, false);
}
else if ((pp[3].x - pos->x) * (pp[0].y - pos->y) < (pp[0].x - pos->x) * (pp[3].y - pos->y))
else if ((rxi[3]-pos->x) * (ryi[0]-pos->y) < (rxi[0]-pos->x) * (ryi[3]-pos->y))
{
if (clipinsideboxline(cent.x, cent.y, pp[0].x, pp[0].y, pp[3].x, pp[3].y, rad) != 0)
addclipline(pp[0].x + v.x, pp[0].y + v.y, pp[3].x + v.y, pp[3].y - v.x, (int16_t)j + 49152, false);
if (clipinsideboxline(cent.x, cent.y, rxi[0], ryi[0], rxi[3], ryi[3], rad) != 0)
addclipline(rxi[0]+v.x, ryi[0]+v.y, rxi[3]+v.y, ryi[3]-v.x, (int16_t)j+49152, false);
}
}
break;
@ -1009,7 +1082,7 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
{
int32_t clipyou = 0;
auto v1 = sprite[j].pos.vec2;
vec2_t v1 = sprite[j].pos.vec2;
switch (cstat & CSTAT_SPRITE_ALIGNMENT_MASK)
{
@ -1027,14 +1100,14 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
case CSTAT_SPRITE_ALIGNMENT_WALL:
{
vec2_t pp[2];
GetWallSpritePosition(&sprite[j], v1, pp);
vec2_t v2;
get_wallspr_points((uspriteptr_t)&sprite[j], &v1.x, &v2.x, &v1.y, &v2.y);
if (clipinsideboxline(pos->x, pos->y, pp[0].x, pp[0].y, pp[1].x, pp[1].y, walldist + 1) != 0)
if (clipinsideboxline(pos->x,pos->y,v1.x,v1.y,v2.x,v2.y,walldist+1) != 0)
{
int32_t k;
daz = sprite[j].z + spriteheightofs(j, &k, 1);
daz2 = daz - k;
daz2 = daz-k;
clipyou = 1;
}
break;
@ -1047,16 +1120,17 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
if ((cstat&64) != 0 && (pos->z > daz) == ((cstat&8)==0))
continue;
vec2_t pp[4];
GetFlatSpritePosition(&sprite[j], v1 - pos->vec2, pp);
vec2_t v2, v3, v4;
get_floorspr_points((uspriteptr_t) &sprite[j], pos->x, pos->y, &v1.x, &v2.x, &v3.x, &v4.x,
&v1.y, &v2.y, &v3.y, &v4.y);
vec2_t const da = { MulScale(bcos(sprite[j].ang - 256), walldist + 4, 14),
MulScale(bsin(sprite[j].ang - 256), walldist + 4, 14) };
pp[0].x += da.x; pp[1].x -= da.y; pp[2].x -= da.x; pp[3].x += da.y;
pp[0].y += da.y; pp[1].y += da.x; pp[2].y -= da.y; pp[3].y -= da.x;
v1.x += da.x; v2.x -= da.y; v3.x -= da.x; v4.x += da.y;
v1.y += da.y; v2.y += da.x; v3.y -= da.y; v4.y -= da.x;
clipyou = get_floorspr_clipyou(pp[0], pp[1], pp[2], pp[3]);
clipyou = get_floorspr_clipyou(v1, v2, v3, v4);
break;
}
}
@ -1344,6 +1418,7 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
if ((cstat&dasprclipmask) == 0)
continue;
x1 = spr->x; y1 = spr->y; z1 = spr->z;
switch (cstat&CSTAT_SPRITE_ALIGNMENT)
{
case 0:
@ -1363,14 +1438,13 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
int32_t ucoefup16;
int32_t tilenum = spr->picnum;
vec2_t pp[2];
GetWallSpritePosition(spr, spr->pos.vec2, pp);
get_wallspr_points(spr, &x1, &x2, &y1, &y2);
if ((cstat & 64) != 0) //back side of 1-way sprite
if (compat_maybe_truncate_to_int32((coord_t)(pp[0].x - sv->x) * (pp[1].y - sv->y))
< compat_maybe_truncate_to_int32((coord_t)(pp[1].x - sv->x) * (pp[0].y - sv->y))) continue;
if ((cstat&64) != 0) //back side of 1-way sprite
if (compat_maybe_truncate_to_int32((coord_t)(x1-sv->x)*(y2-sv->y))
< compat_maybe_truncate_to_int32((coord_t)(x2-sv->x)*(y1-sv->y))) continue;
ucoefup16 = rintersect(sv->x, sv->y, sv->z, vx, vy, vz, pp[0].x, pp[0].y, pp[1].x, pp[1].y, &intx, &inty, &intz);
ucoefup16 = rintersect(sv->x,sv->y,sv->z,vx,vy,vz,x1,y1,x2,y2,&intx,&inty,&intz);
if (ucoefup16 == -1) continue;
if (abs(intx-sv->x)+abs(inty-sv->y) > abs((hit->pos.x)-sv->x)+abs((hit->pos.y)-sv->y))
@ -1403,10 +1477,9 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
case CSTAT_SPRITE_ALIGNMENT_FLOOR:
{
int32_t zz;
int32_t x3, y3, x4, y4, zz;
intz = z1;
if (vz == 0 || ((intz-sv->z)^vz) < 0) continue;
if ((cstat&64) != 0)
@ -1431,10 +1504,10 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
if (abs(intx-sv->x)+abs(inty-sv->y) > abs((hit->pos.x)-sv->x)+abs((hit->pos.y)-sv->y))
continue;
vec2_t pp[4];
GetFlatSpritePosition(spr, spr->pos.vec2 - vec2_t(intx, inty), pp);
get_floorspr_points((uspriteptr_t)spr, intx, inty, &x1, &x2, &x3, &x4,
&y1, &y2, &y3, &y4);
if (get_floorspr_clipyou(pp[0], pp[1], pp[2], pp[3]))
if (get_floorspr_clipyou({x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}))
hit_set(hit, dasector, -1, z, intx, inty, intz);
break;