- 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)
- 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.
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.

View File

@ -264,58 +264,71 @@ angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x, fixed_t y)
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)
{ // octant 0
return SlopeDiv(y, x);
if (y >= 0)
{
if (x > y)
{ // octant 0
return SlopeDiv(y, x);
}
else
{ // octant 1
return ANG90 - 1 - SlopeDiv(x, y);
}
}
else
{ // octant 1
return ANG90 - 1 - SlopeDiv(x, y);
else // y < 0
{
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;
if (x > y)
{ // octant 8
return 0 - SlopeDiv(y, x);
x = -x;
if (y >= 0)
{
if (x > y)
{ // octant 3
return ANG180 - 1 - SlopeDiv(y, x);
}
else
{ // octant 2
return ANG90 + SlopeDiv(x, y);
}
}
else
{ // octant 7
return ANG270 + 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);
}
}
}
}
else // x < 0
else
{
x = -x;
if (y >= 0)
{
if (x > y)
{ // 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);
}
}
// we have to use the slower but more precise floating point atan2 function here.
// (use quickertoint to speed this up because the CRT's conversion is rather slow and
// this is used in time critical code.)
return quickertoint((float)(atan2f(float(y-viewy), float(x-viewx)) * (ANGLE_180/M_PI)));
}
}