diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index 916953c51..c16ecf467 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -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 +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 +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;