- fixed: R_PointToAngle could overflow with very long vectors passed to

it. This caused rendering bugs on some maps. (Interestingly the only
  other port having a safeguard for this in place was PrBoom.)


SVN r1985 (trunk)
This commit is contained in:
Christoph Oelckers 2009-11-17 13:50:46 +00:00
parent 53a717673f
commit 23d0d70ea6
2 changed files with 57 additions and 41 deletions

View File

@ -1,4 +1,7 @@
November 17, 2009 (Changes by Graf Zahl) November 17, 2009 (Changes by Graf Zahl)
- fixed: R_PointToAngle could overflow with very long vectors passed to
it. This caused rendering bugs on some maps. (Interestingly the only
other port having a safeguard for this in place was PrBoom.)
- reverted the change that makes 0-damage projectiles call P_DamageMobj. - reverted the change that makes 0-damage projectiles call P_DamageMobj.
Both Hexen and Heretic depend on such projectiles not doing it as do many Both Hexen and Heretic depend on such projectiles not doing it as do many
mods that create snow/rain effects plus any terrain splash mod. mods that create snow/rain effects plus any terrain splash mod.

View File

@ -264,58 +264,71 @@ angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x, fixed_t y)
return 0; return 0;
} }
if (x >= 0) // We need to be aware of overflows here. If the values get larger than INT_MAX/4
// this code won't work anymore.
if (x < INT_MAX/4 && x > -INT_MAX/4 && y < INT_MAX/4 && y > -INT_MAX/4)
{ {
if (y >= 0) if (x >= 0)
{ {
if (x > y) if (y >= 0)
{ // octant 0 {
return SlopeDiv(y, x); if (x > y)
{ // octant 0
return SlopeDiv(y, x);
}
else
{ // octant 1
return ANG90 - 1 - SlopeDiv(x, y);
}
} }
else else // y < 0
{ // octant 1 {
return ANG90 - 1 - SlopeDiv(x, y); y = -y;
if (x > y)
{ // octant 8
return 0 - SlopeDiv(y, x);
}
else
{ // octant 7
return ANG270 + SlopeDiv(x, y);
}
} }
} }
else // y < 0 else // x < 0
{ {
y = -y; x = -x;
if (x > y) if (y >= 0)
{ // octant 8 {
return 0 - SlopeDiv(y, x); if (x > y)
{ // octant 3
return ANG180 - 1 - SlopeDiv(y, x);
}
else
{ // octant 2
return ANG90 + SlopeDiv(x, y);
}
} }
else else // y < 0
{ // octant 7 {
return ANG270 + SlopeDiv(x, y); y = -y;
if (x > y)
{ // octant 4
return ANG180 + SlopeDiv(y, x);
}
else
{ // octant 5
return ANG270 - 1 - SlopeDiv(x, y);
}
} }
} }
} }
else // x < 0 else
{ {
x = -x; // we have to use the slower but more precise floating point atan2 function here.
if (y >= 0) // (use quickertoint to speed this up because the CRT's conversion is rather slow and
{ // this is used in time critical code.)
if (x > y) return quickertoint((float)(atan2f(float(y-viewy), float(x-viewx)) * (ANGLE_180/M_PI)));
{ // octant 3
return ANG180 - 1 - SlopeDiv(y, x);
}
else
{ // octant 2
return ANG90 + SlopeDiv(x, y);
}
}
else // y < 0
{
y = -y;
if (x > y)
{ // octant 4
return ANG180 + SlopeDiv(y, x);
}
else
{ // octant 5
return ANG270 - 1 - SlopeDiv(x, y);
}
}
} }
} }