blooddemohack -> enginecompatibility_mode

This commit is contained in:
nukeykt 2019-09-23 04:26:07 +09:00 committed by Christoph Oelckers
parent c2e8cc6607
commit 895fb719d9
7 changed files with 318 additions and 75 deletions

View file

@ -592,7 +592,7 @@ void StartLevel(GAMEOPTIONS *gameOptions)
} }
} }
bVanilla = gDemo.at1 && gDemo.m_bLegacy; bVanilla = gDemo.at1 && gDemo.m_bLegacy;
blooddemohack = 2;//bVanilla; enginecompatibility_mode = ENGINECOMPATIBILITY_19960925;//bVanilla;
memset(xsprite,0,sizeof(xsprite)); memset(xsprite,0,sizeof(xsprite));
memset(sprite,0,kMaxSprites*sizeof(spritetype)); memset(sprite,0,kMaxSprites*sizeof(spritetype));
drawLoadingScreen(); drawLoadingScreen();

View file

@ -935,7 +935,14 @@ static FORCE_INLINE int32_t videoGetRenderMode(void)
} }
extern int32_t bloodhack; extern int32_t bloodhack;
extern int32_t blooddemohack; enum {
ENGINECOMPATIBILITY_NONE = 0,
ENGINECOMPATIBILITY_19950829, // Powerslave/Exhumed
ENGINECOMPATIBILITY_19960925, // Blood v1.21
ENGINECOMPATIBILITY_19961112, // Duke 3d v1.5, Redneck Rampage
};
EXTERN int32_t enginecompatibility_mode;
/************************************************************************* /*************************************************************************
POSITION VARIABLES: POSITION VARIABLES:
@ -1520,9 +1527,9 @@ static FORCE_INLINE CONSTEXPR bool inside_p(int32_t const x, int32_t const y, in
return; \ return; \
} while (0) } while (0)
static inline int64_t maybe_truncate_to_int32(int64_t val) static inline int64_t compat_maybe_truncate_to_int32(int64_t val)
{ {
return blooddemohack ? (int32_t)val : val; return enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? (int32_t)val : val;
} }
static inline int32_t clipmove_old(int32_t *x, int32_t *y, int32_t *z, int16_t *sectnum, int32_t xvect, int32_t yvect, int32_t walldist, static inline int32_t clipmove_old(int32_t *x, int32_t *y, int32_t *z, int16_t *sectnum, int32_t xvect, int32_t yvect, int32_t walldist,

View file

@ -778,6 +778,9 @@ static FORCE_INLINE void clipmove_tweak_pos(const vec3_t *pos, int32_t gx, int32
{ {
int32_t daz; int32_t daz;
if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
return;
if (rintersect(pos->x, pos->y, 0, gx, gy, 0, x1, y1, x2, y2, daxptr, dayptr, &daz) == -1) if (rintersect(pos->x, pos->y, 0, gx, gy, 0, x1, y1, x2, y2, daxptr, dayptr, &daz) == -1)
{ {
*daxptr = pos->x; *daxptr = pos->x;
@ -785,6 +788,34 @@ static FORCE_INLINE void clipmove_tweak_pos(const vec3_t *pos, int32_t gx, int32
} }
} }
int32_t getceilzofslope_old(int32_t sectnum, int32_t dax, int32_t day)
{
int32_t dx, dy, i, j;
if (!(sector[sectnum].ceilingstat&2)) return sector[sectnum].ceilingz;
j = sector[sectnum].wallptr;
dx = wall[wall[j].point2].x-wall[j].x;
dy = wall[wall[j].point2].y-wall[j].y;
i = (ksqrtasm_old(dx*dx+dy*dy)); if (i == 0) return(sector[sectnum].ceilingz);
i = divscale20(sector[sectnum].ceilingheinum,i);
dx *= i; dy *= i;
return(sector[sectnum].ceilingz+dmulscale23(dx,day-wall[j].y,-dy,dax-wall[j].x));
}
int32_t getflorzofslope_old(int32_t sectnum, int32_t dax, int32_t day)
{
int32_t dx, dy, i, j;
if (!(sector[sectnum].floorstat&2)) return sector[sectnum].floorz;
j = sector[sectnum].wallptr;
dx = wall[wall[j].point2].x-wall[j].x;
dy = wall[wall[j].point2].y-wall[j].y;
i = (ksqrtasm_old(dx*dx+dy*dy)); if (i == 0) return sector[sectnum].floorz;
i = divscale20(sector[sectnum].floorheinum,i);
dx *= i; dy *= i;
return(sector[sectnum].floorz+dmulscale23(dx,day-wall[j].y,-dy,dax-wall[j].x));
}
// Returns: should clip? // Returns: should clip?
static int cliptestsector(int const dasect, int const nextsect, int32_t const flordist, int32_t const ceildist, vec2_t const pos, int32_t const posz) static int cliptestsector(int const dasect, int const nextsect, int32_t const flordist, int32_t const ceildist, vec2_t const pos, int32_t const posz)
{ {
@ -792,7 +823,25 @@ static int cliptestsector(int const dasect, int const nextsect, int32_t const fl
auto const sec2 = (usectorptr_t)&sector[nextsect]; auto const sec2 = (usectorptr_t)&sector[nextsect];
if (blooddemohack) switch (enginecompatibility_mode)
{
case ENGINECOMPATIBILITY_NONE:
break;
case ENGINECOMPATIBILITY_19950829:
{
int32_t daz = getflorzofslope_old(dasect, pos.x, pos.y);
int32_t daz2 = getflorzofslope_old(nextsect, pos.x, pos.y);
if (daz2 < daz && (sec2->floorstat&1) == 0)
if (posz >= daz2-(flordist-1)) return 1;
daz = getceilzofslope_old(dasect, pos.x, pos.y);
daz2 = getceilzofslope_old(nextsect, pos.x, pos.y);
if (daz2 > daz && (sec2->ceilingstat&1) == 0)
if (posz <= daz2+(ceildist-1)) return 1;
return 0;
}
default:
{ {
int32_t daz = getflorzofslope(dasect, pos.x, pos.y); int32_t daz = getflorzofslope(dasect, pos.x, pos.y);
int32_t daz2 = getflorzofslope(nextsect, pos.x, pos.y); int32_t daz2 = getflorzofslope(nextsect, pos.x, pos.y);
@ -806,6 +855,7 @@ static int cliptestsector(int const dasect, int const nextsect, int32_t const fl
return 0; return 0;
} }
}
int32_t daz2 = sec2->floorz; int32_t daz2 = sec2->floorz;
int32_t dacz2 = sec2->ceilingz; int32_t dacz2 = sec2->ceilingz;
@ -817,6 +867,7 @@ static int cliptestsector(int const dasect, int const nextsect, int32_t const fl
return 1; return 1;
auto const sec = (usectorptr_t)&sector[dasect]; auto const sec = (usectorptr_t)&sector[dasect];
int32_t daz = sec->floorz; int32_t daz = sec->floorz;
int32_t dacz = sec->ceilingz; int32_t dacz = sec->ceilingz;
@ -961,7 +1012,7 @@ static int get_floorspr_clipyou(vec2_t const v1, vec2_t const v2, vec2_t const v
static void clipupdatesector(vec2_t const pos, int16_t * const sectnum, int const walldist) static void clipupdatesector(vec2_t const pos, int16_t * const sectnum, int const walldist)
{ {
if (blooddemohack) if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
{ {
updatesector(pos.x, pos.y, sectnum); updatesector(pos.x, pos.y, sectnum);
return; return;
@ -1044,7 +1095,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
//Extra walldist for sprites on sector lines //Extra walldist for sprites on sector lines
vec2_t const diff = { goal.x - (pos->x), goal.y - (pos->y) }; vec2_t const diff = { goal.x - (pos->x), goal.y - (pos->y) };
int32_t const rad = nsqrtasm(maybe_truncate_to_int32(uhypsq(diff.x, diff.y))) + MAXCLIPDIST + walldist + 8; int32_t const rad = clip_nsqrtasm(compat_maybe_truncate_to_int32(uhypsq(diff.x, diff.y))) + MAXCLIPDIST + walldist + 8;
vec2_t const clipMin = { cent.x - rad, cent.y - rad }; vec2_t const clipMin = { cent.x - rad, cent.y - rad };
vec2_t const clipMax = { cent.x + rad, cent.y + rad }; vec2_t const clipMax = { cent.x + rad, cent.y + rad };
@ -1188,7 +1239,8 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
} }
// We're not interested in any sector reached by portal traversal that we're "inside" of. // We're not interested in any sector reached by portal traversal that we're "inside" of.
if (!blooddemohack && !curspr && dasect != initialsectnum && inside(pos->x, pos->y, dasect) == 1) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE && !curspr && dasect != initialsectnum
&& inside(pos->x, pos->y, dasect) == 1)
{ {
int k; int k;
for (k=startwall; k<endwall; k++) for (k=startwall; k<endwall; k++)
@ -1213,7 +1265,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
v.x = walldist; if (d.y > 0) v.x = -v.x; v.x = walldist; if (d.y > 0) v.x = -v.x;
v.y = walldist; if (d.x < 0) v.y = -v.y; v.y = walldist; if (d.x < 0) v.y = -v.y;
if (!blooddemohack && d.x * (pos->y-p1.y-v.y) < (pos->x-p1.x-v.x) * d.y) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE && d.x * (pos->y-p1.y-v.y) < (pos->x-p1.x-v.x) * d.y)
v.x >>= 1, v.y >>= 1; v.x >>= 1, v.y >>= 1;
addclipline(p1.x+v.x, p1.y+v.y, p2.x+v.x, p2.y+v.y, objtype, false); addclipline(p1.x+v.x, p1.y+v.y, p2.x+v.x, p2.y+v.y, objtype, false);
@ -1371,7 +1423,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
do do
{ {
if (!blooddemohack) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
for (native_t i=clipnum-1;i>=0;--i) for (native_t i=clipnum-1;i>=0;--i)
{ {
if (!bitmap_test(clipignore, i) && clipinsideboxline(pos->x, pos->y, clipit[i].x1, clipit[i].y1, clipit[i].x2, clipit[i].y2, walldist)) if (!bitmap_test(clipignore, i) && clipinsideboxline(pos->x, pos->y, clipit[i].x1, clipit[i].y1, clipit[i].x2, clipit[i].y2, walldist))
@ -1389,25 +1441,36 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
if ((hitwall = cliptrace(pos->vec2, &vec)) >= 0) if ((hitwall = cliptrace(pos->vec2, &vec)) >= 0)
{ {
vec2_t const clipr = { clipit[hitwall].x2 - clipit[hitwall].x1, clipit[hitwall].y2 - clipit[hitwall].y1 }; vec2_t const clipr = { clipit[hitwall].x2 - clipit[hitwall].x1, clipit[hitwall].y2 - clipit[hitwall].y1 };
int64_t const templl = maybe_truncate_to_int32((int64_t)clipr.x * clipr.x + (int64_t)clipr.y * clipr.y); int64_t const templl = compat_maybe_truncate_to_int32((int64_t)clipr.x * clipr.x + (int64_t)clipr.y * clipr.y);
if (templl > 0) if (templl > 0)
{ {
int64_t const templl2 = maybe_truncate_to_int32((int64_t)(goal.x-vec.x)*clipr.x + (int64_t)(goal.y-vec.y)*clipr.y); int64_t const templl2 = compat_maybe_truncate_to_int32((int64_t)(goal.x-vec.x)*clipr.x + (int64_t)(goal.y-vec.y)*clipr.y);
int32_t const i = ((llabs(templl2)>>11) < templl) ? divscale64(templl2, templl, 20) : 0; int32_t const i = enginecompatibility_mode == ENGINECOMPATIBILITY_19950829 || ((llabs(templl2)>>11) < templl) ?
divscale64(templl2, templl, 20) : 0;
goal = { mulscale20(clipr.x, i)+vec.x, mulscale20(clipr.y, i)+vec.y }; goal = { mulscale20(clipr.x, i)+vec.x, mulscale20(clipr.y, i)+vec.y };
} }
int32_t const tempint = dmulscale6(clipr.x, move.x, clipr.y, move.y); int32_t tempint;
if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
tempint = clipr.x*(move.x>>6)+clipr.y*(move.y>>6);
else
tempint = dmulscale6(clipr.x, move.x, clipr.y, move.y);
for (native_t i=cnt+1, j; i<=clipmoveboxtracenum; ++i) for (native_t i=cnt+1, j; i<=clipmoveboxtracenum; ++i)
{ {
j = hitwalls[i]; j = hitwalls[i];
if ((tempint ^ dmulscale6(clipit[j].x2-clipit[j].x1, move.x, clipit[j].y2-clipit[j].y1, move.y)) < 0) int32_t tempint2;
if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
tempint2 = (clipit[j].x2-clipit[j].x1)*(move.x>>6)+(clipit[j].y2-clipit[j].y1)*(move.y>>6);
else
tempint2 = dmulscale6(clipit[j].x2-clipit[j].x1, move.x, clipit[j].y2-clipit[j].y1, move.y);
if ((tempint ^ tempint2) < 0)
{ {
if (blooddemohack == 1) if (enginecompatibility_mode == ENGINECOMPATIBILITY_19961112)
updatesector(pos->x, pos->y, sectnum); updatesector(pos->x, pos->y, sectnum);
return clipReturn; return clipReturn;
} }
@ -1422,7 +1485,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
hitwalls[cnt] = hitwall; hitwalls[cnt] = hitwall;
} }
if (!blooddemohack) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
clipupdatesector(vec, sectnum, rad); clipupdatesector(vec, sectnum, rad);
pos->x = vec.x; pos->x = vec.x;
@ -1430,7 +1493,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
cnt--; cnt--;
} while ((xvect|yvect) != 0 && hitwall >= 0 && cnt > 0); } while ((xvect|yvect) != 0 && hitwall >= 0 && cnt > 0);
if (blooddemohack) if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
{ {
for (native_t j=0; j<clipsectnum; j++) for (native_t j=0; j<clipsectnum; j++)
if (inside(pos->x, pos->y, clipsectorlist[j]) == 1) if (inside(pos->x, pos->y, clipsectorlist[j]) == 1)
@ -1444,7 +1507,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
for (native_t j=numsectors-1; j>=0; j--) for (native_t j=numsectors-1; j>=0; j--)
if (inside(pos->x, pos->y, j) == 1) if (inside(pos->x, pos->y, j) == 1)
{ {
if (sector[j].ceilingstat&2) if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sector[j].ceilingstat&2))
tempint2 = getceilzofslope(j, pos->x, pos->y) - pos->z; tempint2 = getceilzofslope(j, pos->x, pos->y) - pos->z;
else else
tempint2 = sector[j].ceilingz - pos->z; tempint2 = sector[j].ceilingz - pos->z;
@ -1458,7 +1521,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
} }
else else
{ {
if (sector[j].floorstat&2) if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829 && (sector[j].floorstat&2))
tempint2 = pos->z - getflorzofslope(j, pos->x, pos->y); tempint2 = pos->z - getflorzofslope(j, pos->x, pos->y);
else else
tempint2 = pos->z - sector[j].floorz; tempint2 = pos->z - sector[j].floorz;
@ -1565,7 +1628,12 @@ int pushmove(vec3_t *const vect, int16_t *const sectnum,
else else
{ {
int32_t daz2; int32_t daz2;
vec2_t closest;
if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
closest = vect->vec2;
else
{
//Find closest point on wall (dax, day) to (vect->x, vect->y) //Find closest point on wall (dax, day) to (vect->x, vect->y)
int32_t dax = wall[wal->point2].x-wal->x; int32_t dax = wall[wal->point2].x-wal->x;
int32_t day = wall[wal->point2].y-wal->y; int32_t day = wall[wal->point2].y-wal->y;
@ -1581,7 +1649,8 @@ int pushmove(vec3_t *const vect, int16_t *const sectnum,
dax = wal->x + mulscale30(dax, t); dax = wal->x + mulscale30(dax, t);
day = wal->y + mulscale30(day, t); day = wal->y + mulscale30(day, t);
vec2_t closest = { dax, day }; closest = { dax, day };
}
j = cliptestsector(clipsectorlist[clipsectcnt], wal->nextsector, flordist, ceildist, closest, vect->z); j = cliptestsector(clipsectorlist[clipsectcnt], wal->nextsector, flordist, ceildist, closest, vect->z);
} }
@ -1647,8 +1716,14 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
const int32_t dasprclipmask = (cliptype>>16); const int32_t dasprclipmask = (cliptype>>16);
vec2_t closest = { pos->x, pos->y }; vec2_t closest = { pos->x, pos->y };
if (!blooddemohack) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
getsectordist(closest, sectnum, &closest); getsectordist(closest, sectnum, &closest);
if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
{
*ceilz = getceilzofslope_old(sectnum,closest.x,closest.y);
*florz = getflorzofslope_old(sectnum,closest.x,closest.y);
}
else
getzsofslope(sectnum,closest.x,closest.y,ceilz,florz); getzsofslope(sectnum,closest.x,closest.y,ceilz,florz);
*ceilhit = sectnum+16384; *florhit = sectnum+16384; *ceilhit = sectnum+16384; *florhit = sectnum+16384;
@ -1703,13 +1778,13 @@ restart_grand:
int32_t daz, daz2; int32_t daz, daz2;
closest = { pos->x, pos->y }; closest = { pos->x, pos->y };
if (!blooddemohack) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
getsectordist(closest, k, &closest); getsectordist(closest, k, &closest);
getzsofslope(k,closest.x,closest.y,&daz,&daz2); getzsofslope(k,closest.x,closest.y,&daz,&daz2);
int32_t fz, cz; int32_t fz, cz;
closest = { pos->x, pos->y }; closest = { pos->x, pos->y };
if (!blooddemohack) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
getsectordist(closest, sectq[clipinfo[curidx].qend], &closest); getsectordist(closest, sectq[clipinfo[curidx].qend], &closest);
getzsofslope(sectq[clipinfo[curidx].qend],closest.x,closest.y,&cz,&fz); getzsofslope(sectq[clipinfo[curidx].qend],closest.x,closest.y,&cz,&fz);
@ -1795,8 +1870,14 @@ restart_grand:
//It actually got here, through all the continue's!!! //It actually got here, through all the continue's!!!
int32_t daz, daz2; int32_t daz, daz2;
closest = { pos->x, pos->y }; closest = { pos->x, pos->y };
if (!blooddemohack) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
getsectordist(closest, k, &closest); getsectordist(closest, k, &closest);
if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
{
daz = getceilzofslope_old(k, closest.x,closest.y);
daz2 = getflorzofslope_old(k, closest.x,closest.y);
}
else
getzsofslope(k, closest.x,closest.y, &daz,&daz2); getzsofslope(k, closest.x,closest.y, &daz,&daz2);
#ifdef HAVE_CLIPSHAPE_FEATURE #ifdef HAVE_CLIPSHAPE_FEATURE
@ -1805,7 +1886,7 @@ restart_grand:
int32_t fz,cz, hitwhat=(curspr-(uspritetype *)sprite)+49152; int32_t fz,cz, hitwhat=(curspr-(uspritetype *)sprite)+49152;
closest = { pos->x, pos->y }; closest = { pos->x, pos->y };
if (!blooddemohack) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
getsectordist(closest, sectq[clipinfo[curidx].qend], &closest); getsectordist(closest, sectq[clipinfo[curidx].qend], &closest);
getzsofslope(sectq[clipinfo[curidx].qend],closest.x,closest.y,&cz,&fz); getzsofslope(sectq[clipinfo[curidx].qend],closest.x,closest.y,&cz,&fz);
@ -1992,7 +2073,7 @@ restart_grand:
addclipsect(j); addclipsect(j);
closest = { pos->x, pos->y }; closest = { pos->x, pos->y };
if (!blooddemohack) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
getsectordist(closest, j, &closest); getsectordist(closest, j, &closest);
int const daz = getceilzofslope(j, closest.x, closest.y); int const daz = getceilzofslope(j, closest.x, closest.y);
@ -2033,7 +2114,7 @@ restart_grand:
addclipsect(j); addclipsect(j);
closest = { pos->x, pos->y }; closest = { pos->x, pos->y };
if (!blooddemohack) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
getsectordist(closest, j, &closest); getsectordist(closest, j, &closest);
int const daz = getflorzofslope(j, closest.x,closest.y); int const daz = getflorzofslope(j, closest.x,closest.y);
@ -2125,7 +2206,7 @@ static int32_t hitscan_trysector(const vec3_t *sv, usectorptr_t sec, hitdata_t *
auto const wal2 = (uwallptr_t)&wall[wal->point2]; auto const wal2 = (uwallptr_t)&wall[wal->point2];
int32_t j, dax=wal2->x-wal->x, day=wal2->y-wal->y; int32_t j, dax=wal2->x-wal->x, day=wal2->y-wal->y;
i = nsqrtasm(maybe_truncate_to_int32(uhypsq(dax,day))); if (i == 0) return 1; //continue; i = nsqrtasm(compat_maybe_truncate_to_int32(uhypsq(dax,day))); if (i == 0) return 1; //continue;
i = divscale15(heinum,i); i = divscale15(heinum,i);
dax *= i; day *= i; dax *= i; day *= i;
@ -2272,10 +2353,13 @@ restart_grand:
else tmp[2] = 0; else tmp[2] = 0;
} }
#endif #endif
if (enginecompatibility_mode != ENGINECOMPATIBILITY_19950829)
{
if (hitscan_trysector(sv, sec, hit, vx,vy,vz, sec->ceilingstat, sec->ceilingheinum, sec->ceilingz, -i, tmpptr)) if (hitscan_trysector(sv, sec, hit, vx,vy,vz, sec->ceilingstat, sec->ceilingheinum, sec->ceilingz, -i, tmpptr))
continue; continue;
if (hitscan_trysector(sv, sec, hit, vx,vy,vz, sec->floorstat, sec->floorheinum, sec->floorz, i, tmpptr)) if (hitscan_trysector(sv, sec, hit, vx,vy,vz, sec->floorstat, sec->floorheinum, sec->floorz, i, tmpptr))
continue; continue;
}
////////// Walls ////////// ////////// Walls //////////
@ -2291,13 +2375,49 @@ restart_grand:
x1 = wal->x; y1 = wal->y; x2 = wal2->x; y2 = wal2->y; x1 = wal->x; y1 = wal->y; x2 = wal2->x; y2 = wal2->y;
if (maybe_truncate_to_int32((coord_t)(x1-sv->x)*(y2-sv->y)) < maybe_truncate_to_int32((coord_t)(x2-sv->x)*(y1-sv->y))) continue; 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;
if (rintersect(sv->x,sv->y,sv->z, vx,vy,vz, x1,y1, x2,y2, &intx,&inty,&intz) == -1) continue; if (rintersect(sv->x,sv->y,sv->z, vx,vy,vz, x1,y1, x2,y2, &intx,&inty,&intz) == -1) continue;
if (klabs(intx-sv->x)+klabs(inty-sv->y) >= klabs((hit->pos.x)-sv->x)+klabs((hit->pos.y)-sv->y)) if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
{
if (vz != 0)
if ((intz <= sec->ceilingz) || (intz >= sec->floorz))
if (klabs(intx-sv->x)+klabs(inty-sv->y) < klabs(hit->pos.x-sv->x)+klabs(hit->pos.y-sv->y))
{
//x1,y1,z1 are temp variables
if (vz > 0) z1 = sec->floorz; else z1 = sec->ceilingz;
x1 = sv->x + scale(z1-sv->z,vx,vz);
y1 = sv->y + scale(z1-sv->z,vy,vz);
if (inside(x1,y1,dasector) == 1)
{
hit_set(hit, dasector, -1, -1, x1, y1, z1);
continue;
}
}
}
else if (klabs(intx-sv->x)+klabs(inty-sv->y) >= klabs((hit->pos.x)-sv->x)+klabs((hit->pos.y)-sv->y))
continue; continue;
if (!curspr) if (!curspr)
{
if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
{
if ((nextsector < 0) || (wal->cstat&dawalclipmask))
{
if ((klabs(intx-sv->x)+klabs(inty-sv->y) < klabs(hit->pos.x-sv->x)+klabs(hit->pos.y-sv->y)))
hit_set(hit, dasector, z, -1, intx, inty, intz);
continue;
}
if (intz <= sector[nextsector].ceilingz || intz >= sector[nextsector].floorz)
{
if ((klabs(intx-sv->x)+klabs(inty-sv->y) < klabs(hit->pos.x-sv->x)+klabs(hit->pos.y-sv->y)))
hit_set(hit, dasector, z, -1, intx, inty, intz);
continue;
}
}
else
{ {
if ((nextsector < 0) || (wal->cstat&dawalclipmask)) if ((nextsector < 0) || (wal->cstat&dawalclipmask))
{ {
@ -2313,6 +2433,7 @@ restart_grand:
continue; continue;
} }
} }
}
#ifdef HAVE_CLIPSHAPE_FEATURE #ifdef HAVE_CLIPSHAPE_FEATURE
else else
{ {
@ -2393,7 +2514,8 @@ restart_grand:
get_wallspr_points(spr, &x1, &x2, &y1, &y2); get_wallspr_points(spr, &x1, &x2, &y1, &y2);
if ((cstat&64) != 0) //back side of 1-way sprite if ((cstat&64) != 0) //back side of 1-way sprite
if (maybe_truncate_to_int32((coord_t)(x1-sv->x)*(y2-sv->y)) < maybe_truncate_to_int32((coord_t)(x2-sv->x)*(y1-sv->y))) continue; 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,x1,y1,x2,y2,&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 (ucoefup16 == -1) continue;
@ -2438,7 +2560,7 @@ restart_grand:
if ((cstat&64) != 0) if ((cstat&64) != 0)
if ((sv->z > intz) == ((cstat&8)==0)) continue; if ((sv->z > intz) == ((cstat&8)==0)) continue;
if (!blooddemohack) if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
{ {
// Abyss crash prevention code ((intz-sv->z)*zx overflowing a 8-bit word) // Abyss crash prevention code ((intz-sv->z)*zx overflowing a 8-bit word)
// PK: the reason for the crash is not the overflowing (even if it IS a problem; // PK: the reason for the crash is not the overflowing (even if it IS a problem;

View file

@ -223,7 +223,8 @@ int32_t ldist(const void *s1, const void *s2)
{ {
auto sp1 = (vec2_t const *)s1; auto sp1 = (vec2_t const *)s1;
auto sp2 = (vec2_t const *)s2; auto sp2 = (vec2_t const *)s2;
return sepldist(sp1->x - sp2->x, sp1->y - sp2->y) + (blooddemohack ? 1 : 0); return sepldist(sp1->x - sp2->x, sp1->y - sp2->y)
+ (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? 1 : 0);
} }
int32_t dist(const void *s1, const void *s2) int32_t dist(const void *s1, const void *s2)

View file

@ -176,7 +176,7 @@ static int16_t radarang[1280];
static int32_t qradarang[10240], *radarang2; static int32_t qradarang[10240], *radarang2;
const char ATTRIBUTE((used)) pow2char_[8] = {1,2,4,8,16,32,64,128}; const char ATTRIBUTE((used)) pow2char_[8] = {1,2,4,8,16,32,64,128};
uint16_t ATTRIBUTE((used)) sqrtable[4096], ATTRIBUTE((used)) shlookup[4096+256]; uint16_t ATTRIBUTE((used)) sqrtable[4096], ATTRIBUTE((used)) shlookup[4096+256], ATTRIBUTE((used)) sqrtable_old[2048];
char britable[16][256]; // JBF 20040207: full 8bit precision char britable[16][256]; // JBF 20040207: full 8bit precision
@ -198,7 +198,6 @@ static fix16_t global100horiz; // (-100..300)-scale horiz (the one passed to dr
int32_t(*getpalookup_replace)(int32_t davis, int32_t dashade) = NULL; int32_t(*getpalookup_replace)(int32_t davis, int32_t dashade) = NULL;
int32_t bloodhack = 0; int32_t bloodhack = 0;
int32_t blooddemohack = 0;
// adapted from build.c // adapted from build.c
static void getclosestpointonwall_internal(vec2_t const p, int32_t const dawall, vec2_t *const closest) static void getclosestpointonwall_internal(vec2_t const p, int32_t const dawall, vec2_t *const closest)
@ -7475,6 +7474,8 @@ static uint32_t msqrtasm(uint32_t c)
static inline void initksqrt(void) static inline void initksqrt(void)
{ {
int32_t i, j, k; int32_t i, j, k;
uint32_t root, num;
int32_t temp;
j = 1; k = 0; j = 1; k = 0;
for (i=0; i<4096; i++) for (i=0; i<4096; i++)
@ -7484,6 +7485,29 @@ static inline void initksqrt(void)
shlookup[i] = (k<<1)+((10-k)<<8); shlookup[i] = (k<<1)+((10-k)<<8);
if (i < 256) shlookup[i+4096] = ((k+6)<<1)+((10-(k+6))<<8); if (i < 256) shlookup[i+4096] = ((k+6)<<1)+((10-(k+6))<<8);
} }
for(i=0;i<2048;i++)
{
root = 128;
num = i<<20;
do
{
temp = root;
root = (root+num/root)>>1;
} while((temp-root+1) > 2);
temp = root*root-num;
while (klabs(int32_t(temp-2*root+1)) < klabs(temp))
{
temp += -(2*root)+1;
root--;
}
while (klabs(int32_t(temp+2*root+1)) < klabs(temp))
{
temp += 2*root+1;
root++;
}
sqrtable_old[i] = root;
}
} }
@ -7736,7 +7760,7 @@ LISTFN_STATIC int32_t insertspritestat(int16_t statnum)
// make back-link of the new freelist head point to nil // make back-link of the new freelist head point to nil
if (headspritestat[MAXSTATUS] >= 0) if (headspritestat[MAXSTATUS] >= 0)
prevspritestat[headspritestat[MAXSTATUS]] = -1; prevspritestat[headspritestat[MAXSTATUS]] = -1;
else if (!blooddemohack) else if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
tailspritefree = -1; tailspritefree = -1;
do_insertsprite_at_headofstat(blanktouse, statnum); do_insertsprite_at_headofstat(blanktouse, statnum);
@ -7805,7 +7829,7 @@ int32_t deletesprite(int16_t spritenum)
sprite[spritenum].sectnum = MAXSECTORS; sprite[spritenum].sectnum = MAXSECTORS;
// insert at tail of status freelist // insert at tail of status freelist
if (blooddemohack) if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
do_insertsprite_at_headofstat(spritenum, MAXSTATUS); do_insertsprite_at_headofstat(spritenum, MAXSTATUS);
else else
{ {
@ -7886,7 +7910,7 @@ int32_t lintersect(const int32_t originX, const int32_t originY, const int32_t o
if (rayCrossLineVec == 0) if (rayCrossLineVec == 0)
{ {
if (originDiffCrossRay != 0 || blooddemohack) if (originDiffCrossRay != 0 || enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
{ {
// line segments are parallel // line segments are parallel
return 0; return 0;
@ -8000,7 +8024,7 @@ int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
{ {
//p1 towards p2 is a ray //p1 towards p2 is a ray
if (blooddemohack) if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
return rintersect_old(x1,y1,z1,vx,vy,vz,x3,y3,x4,y4,intx,inty,intz); return rintersect_old(x1,y1,z1,vx,vy,vz,x3,y3,x4,y4,intx,inty,intz);
int64_t const x34=x3-x4, y34=y3-y4; int64_t const x34=x3-x4, y34=y3-y4;
@ -10710,7 +10734,32 @@ void vox_undefine(int32_t const tile)
// //
// See http://fabiensanglard.net/duke3d/build_engine_internals.php, // See http://fabiensanglard.net/duke3d/build_engine_internals.php,
// "Inside details" for the idea behind the algorithm. // "Inside details" for the idea behind the algorithm.
int32_t inside_ps(int32_t x, int32_t y, int16_t sectnum)
{
if (sectnum >= 0 && sectnum < numsectors)
{
int32_t cnt = 0;
auto wal = (uwallptr_t)&wall[sector[sectnum].wallptr];
int wallsleft = sector[sectnum].wallnum;
do
{
vec2_t v1 = { wal->x - x, wal->y - y };
auto const &wal2 = *(uwallptr_t)&wall[wal->point2];
vec2_t v2 = { wal2.x - x, wal2.y - y };
if ((v1.y^v2.y) < 0)
cnt ^= (((v1.x^v2.x) < 0) ? (v1.x*v2.y<v2.x*v1.y)^(v1.y<v2.y) : (v1.x >= 0));
wal++;
}
while (--wallsleft);
return cnt;
}
return -1;
}
int32_t inside_old(int32_t x, int32_t y, int16_t sectnum) int32_t inside_old(int32_t x, int32_t y, int16_t sectnum)
{ {
if (sectnum >= 0 && sectnum < numsectors) if (sectnum >= 0 && sectnum < numsectors)
@ -10748,8 +10797,15 @@ int32_t inside_old(int32_t x, int32_t y, int16_t sectnum)
int32_t inside(int32_t x, int32_t y, int16_t sectnum) int32_t inside(int32_t x, int32_t y, int16_t sectnum)
{ {
if (blooddemohack) switch (enginecompatibility_mode)
{
case ENGINECOMPATIBILITY_NONE:
break;
case ENGINECOMPATIBILITY_19950829:
return inside_ps(x, y, sectnum);
default:
return inside_old(x, y, sectnum); return inside_old(x, y, sectnum);
}
if ((unsigned)sectnum < (unsigned)numsectors) if ((unsigned)sectnum < (unsigned)numsectors)
{ {
uint32_t cnt1 = 0, cnt2 = 0; uint32_t cnt1 = 0, cnt2 = 0;
@ -10946,8 +11002,48 @@ int32_t nextsectorneighborz(int16_t sectnum, int32_t refz, int16_t topbottom, in
// //
// cansee // cansee
// //
int32_t cansee_old(int32_t xs, int32_t ys, int32_t zs, int16_t sectnums, int32_t xe, int32_t ye, int32_t ze, int16_t sectnume)
{
sectortype *sec, *nsec;
walltype *wal, *wal2;
int32_t intx, inty, intz, i, cnt, nextsector, dasectnum, dacnt, danum;
if ((xs == xe) && (ys == ye) && (sectnums == sectnume)) return 1;
clipsectorlist[0] = sectnums; danum = 1;
for(dacnt=0;dacnt<danum;dacnt++)
{
dasectnum = clipsectorlist[dacnt]; sec = &sector[dasectnum];
for(cnt=sec->wallnum,wal=&wall[sec->wallptr];cnt>0;cnt--,wal++)
{
wal2 = &wall[wal->point2];
if (lintersect(xs,ys,zs,xe,ye,ze,wal->x,wal->y,wal2->x,wal2->y,&intx,&inty,&intz) != 0)
{
nextsector = wal->nextsector; if (nextsector < 0) return 0;
if (intz <= sec->ceilingz) return 0;
if (intz >= sec->floorz) return 0;
nsec = &sector[nextsector];
if (intz <= nsec->ceilingz) return 0;
if (intz >= nsec->floorz) return 0;
for(i=danum-1;i>=0;i--)
if (clipsectorlist[i] == nextsector) break;
if (i < 0) clipsectorlist[danum++] = nextsector;
}
}
if (clipsectorlist[dacnt] == sectnume)
return 1;
}
return 0;
}
int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, int32_t y2, int32_t z2, int16_t sect2) int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, int32_t y2, int32_t z2, int16_t sect2)
{ {
if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
return cansee_old(x1, y1, z2, sect1, x2, y2, z2, sect2);
int32_t dacnt, danum; int32_t dacnt, danum;
const int32_t x21 = x2-x1, y21 = y2-y1, z21 = z2-z1; const int32_t x21 = x2-x1, y21 = y2-y1, z21 = z2-z1;
@ -11559,7 +11655,7 @@ int findwallbetweensectors(int sect1, int sect2)
// //
void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum) void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum)
{ {
if (blooddemohack) if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
{ {
if (inside_p(x, y, *sectnum)) if (inside_p(x, y, *sectnum))
return; return;
@ -11629,7 +11725,7 @@ void updatesectorexclude(int32_t const x, int32_t const y, int16_t * const sectn
void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum) void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum)
{ {
if (blooddemohack) if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
{ {
if ((uint32_t)(*sectnum) < 2*MAXSECTORS) if ((uint32_t)(*sectnum) < 2*MAXSECTORS)
{ {
@ -12416,7 +12512,7 @@ int32_t getceilzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day)
if (i == 0) return sec->ceilingz; if (i == 0) return sec->ceilingz;
int const j = dmulscale3(d.x, day-w.y, -d.y, dax-w.x); int const j = dmulscale3(d.x, day-w.y, -d.y, dax-w.x);
int const shift = blooddemohack ? 0 : 1; int const shift = enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? 0 : 1;
return sec->ceilingz + (scale(sec->ceilingheinum,j>>shift,i)<<shift); return sec->ceilingz + (scale(sec->ceilingheinum,j>>shift,i)<<shift);
} }
@ -12435,7 +12531,7 @@ int32_t getflorzofslopeptr(usectorptr_t sec, int32_t dax, int32_t day)
if (i == 0) return sec->floorz; if (i == 0) return sec->floorz;
int const j = dmulscale3(d.x, day-w.y, -d.y, dax-w.x); int const j = dmulscale3(d.x, day-w.y, -d.y, dax-w.x);
int const shift = blooddemohack ? 0 : 1; int const shift = enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? 0 : 1;
return sec->floorz + (scale(sec->floorheinum,j>>shift,i)<<shift); return sec->floorz + (scale(sec->floorheinum,j>>shift,i)<<shift);
} }
@ -12455,7 +12551,7 @@ void getzsofslopeptr(usectorptr_t sec, int32_t dax, int32_t day, int32_t *ceilz,
if (i == 0) return; if (i == 0) return;
int const j = dmulscale3(d.x,day-wal->y, -d.y,dax-wal->x); int const j = dmulscale3(d.x,day-wal->y, -d.y,dax-wal->x);
int const shift = blooddemohack ? 0 : 1; int const shift = enginecompatibility_mode != ENGINECOMPATIBILITY_NONE ? 0 : 1;
if (sec->ceilingstat&2) if (sec->ceilingstat&2)
*ceilz += scale(sec->ceilingheinum,j>>shift,i)<<shift; *ceilz += scale(sec->ceilingheinum,j>>shift,i)<<shift;
if (sec->floorstat&2) if (sec->floorstat&2)

View file

@ -28,7 +28,7 @@
extern int32_t globalx1, globaly2; extern int32_t globalx1, globaly2;
extern uint16_t ATTRIBUTE((used)) sqrtable[4096], ATTRIBUTE((used)) shlookup[4096+256]; extern uint16_t ATTRIBUTE((used)) sqrtable[4096], ATTRIBUTE((used)) shlookup[4096+256], ATTRIBUTE((used)) sqrtable_old[2048];
static inline int32_t nsqrtasm(uint32_t a) static inline int32_t nsqrtasm(uint32_t a)
@ -71,6 +71,23 @@ extern uint16_t ATTRIBUTE((used)) sqrtable[4096], ATTRIBUTE((used)) shlookup[409
} }
inline int32_t ksqrtasm_old(int32_t n)
{
n = klabs(n);
int shift;
for (shift = 0; n >= 2048; n >>=2, shift++)
{
}
return (sqrtable_old[n]<<shift)>>10;
}
inline int32_t clip_nsqrtasm(int32_t n)
{
if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
return ksqrtasm_old(n);
return nsqrtasm(n);
}
extern int16_t thesector[MAXWALLSB], thewall[MAXWALLSB]; extern int16_t thesector[MAXWALLSB], thewall[MAXWALLSB];
extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB]; extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
extern int16_t maskwall[MAXWALLSB], maskwallcnt; extern int16_t maskwall[MAXWALLSB], maskwallcnt;

View file

@ -7456,7 +7456,7 @@ static void G_Startup(void)
G_CompileScripts(); G_CompileScripts();
blooddemohack = 1; enginecompatibility_mode = ENGINECOMPATIBILITY_19961112;
if (engineInit()) if (engineInit())
G_FatalEngineError(); G_FatalEngineError();