- added safeguards to all 2D drawing functions to throw an exception if used outside a valid 2D draw context.

This is necessary because the hardware accelerated renderers will hide the problem, but with pure software rendering to a locked hardware surface, like DirectDraw can result in a crash.
Note that ANY mod that gets caught in this did something wrong!
This commit is contained in:
Christoph Oelckers 2017-03-28 13:25:17 +02:00
parent f3db5f3803
commit e2e17f575c
6 changed files with 13 additions and 3 deletions

View file

@ -1700,6 +1700,7 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawTexture)
PARAM_FLOAT_DEF(h);
PARAM_FLOAT_DEF(scaleX);
PARAM_FLOAT_DEF(scaleY);
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
self->DrawGraphic(FSetTextureID(texid), x, y, flags, alpha, w, h, scaleX, scaleY);
return 0;
}
@ -1716,6 +1717,7 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawImage)
PARAM_FLOAT_DEF(h);
PARAM_FLOAT_DEF(scaleX);
PARAM_FLOAT_DEF(scaleY);
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
self->DrawGraphic(TexMan.CheckForTexture(texid, FTexture::TEX_Any), x, y, flags, alpha, w, h, scaleX, scaleY);
return 0;
}
@ -1908,6 +1910,7 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawString)
PARAM_INT_DEF(wrapwidth);
PARAM_INT_DEF(linespacing);
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
// resolve auto-alignment before making any adjustments to the position values.
if (!(flags & DI_SCREEN_MANUAL_ALIGN))
@ -2012,6 +2015,7 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, Fill)
PARAM_FLOAT(w);
PARAM_FLOAT(h);
PARAM_INT_DEF(flags);
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
self->Fill(color, x, y, w, h);
return 0;
}

View file

@ -137,6 +137,8 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawTexture)
PARAM_FLOAT(x);
PARAM_FLOAT(y);
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
FTexture *tex = animate ? TexMan(FSetTextureID(texid)) : TexMan[FSetTextureID(texid)];
VMVa_List args = { param + 4, 0, numparam - 4 };
screen->DrawTexture(tex, x, y, args);
@ -959,6 +961,7 @@ DEFINE_ACTION_FUNCTION(_Screen, Clear)
PARAM_INT(y2);
PARAM_INT(color);
PARAM_INT_DEF(palcol);
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
screen->Clear(x1, y1, x2, y2, palcol, color);
return 0;
}
@ -1010,6 +1013,7 @@ DEFINE_ACTION_FUNCTION(_Screen, Dim)
PARAM_INT(y1);
PARAM_INT(w);
PARAM_INT(h);
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
screen->Dim(color, float(amount), x1, y1, w, h);
return 0;
}

View file

@ -116,6 +116,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawChar)
PARAM_FLOAT(y);
PARAM_INT(chr);
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
VMVa_List args = { param + 5, 0, numparam - 5 };
screen->DrawChar(font, cr, x, y, chr, args);
return 0;
@ -241,6 +242,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawText)
PARAM_FLOAT(y);
PARAM_STRING(chr);
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
VMVa_List args = { param + 5, 0, numparam - 5 };
const char *txt = chr[0] == '$' ? GStrings(&chr[1]) : chr.GetChars();
screen->DrawText(font, cr, x, y, txt, args);

View file

@ -1153,7 +1153,7 @@ void Win32GLFrameBuffer::Unlock ()
bool Win32GLFrameBuffer::IsLocked ()
{
return m_Lock>0;// true;
return m_Lock > 0;
}
//==========================================================================

View file

@ -189,7 +189,7 @@ class HereticStatusBar : BaseStatusBar
y -= 40;
}
if (!isInventoryBarVisible() && !level.NoInventoryBar)
if (!isInventoryBarVisible() && !level.NoInventoryBar && CPlayer.mo.InvSel != null)
{
// This code was changed to always fit the item into the box, regardless of alignment or sprite size.
// Heretic's ARTIBOX is 30x30 pixels.

View file

@ -69,7 +69,7 @@ class HexenStatusBar : BaseStatusBar
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (70, -16));
}
if (!isInventoryBarVisible() && !level.NoInventoryBar)
if (!isInventoryBarVisible() && !level.NoInventoryBar && CPlayer.mo.InvSel != null)
{
// This code was changed to always fit the item into the box, regardless of alignment or sprite size.
// Heretic's ARTIBOX is 30x30 pixels.