mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- Added cybermind's HUD message clipping patch, with numerous changes. There is a new flag
and two new functions, both of which are intended for use in conjunction with SetHUDSize: * SetHUDClipRect(x, y, width, height[, wrapwidth]) - Set the clipping rectangle for future HUD messages. If you do not specify <wrapwidth>, the HUD message will be layed out as normal, but pixels outside the rectangle will not be drawn. If you specify <wrapwidth>, then the message will be wrapped to that width. Use SetHUDClipRect(0, 0, 0, 0[, 0]) to reset everything back to normal. * SetHUDWrapWidth(wrapwidth) - Sets the wrapping width for future HUD messages without altering the clipping rectangle. If you set the wrapping width to 0, messages will wrap to the full width of the HUD, as normal. * HUDMSG_NOWRAP - A HUDMessage() flag that disables wrapping for one message. It is functionally equivalent to SetHUDWrapWidth(0x7FFFFFFF), except that it only affects the message it's attached to. SVN r3960 (trunk)
This commit is contained in:
parent
955d929d5e
commit
e398957a4c
4 changed files with 127 additions and 12 deletions
|
@ -131,6 +131,9 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h
|
|||
Left = intpart - (float)(fracpart & 3) / 10.f;
|
||||
}
|
||||
}
|
||||
NoWrap = false;
|
||||
ClipX = ClipY = ClipWidth = ClipHeight = 0;
|
||||
WrapWidth = 0;
|
||||
Top = y;
|
||||
Next = NULL;
|
||||
Lines = NULL;
|
||||
|
@ -182,6 +185,17 @@ void DHUDMessage::Serialize (FArchive &arc)
|
|||
<< Tics << State << TextColor
|
||||
<< SBarID << SourceText << Font << Next
|
||||
<< HUDWidth << HUDHeight;
|
||||
if (SaveVersion >= 3960)
|
||||
{
|
||||
arc << NoWrap;
|
||||
arc << ClipX << ClipY << ClipWidth << ClipHeight;
|
||||
arc << WrapWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
NoWrap = false;
|
||||
ClipX = ClipY = ClipWidth = ClipHeight = WrapWidth = 0;
|
||||
}
|
||||
if (arc.IsLoading ())
|
||||
{
|
||||
Lines = NULL;
|
||||
|
@ -220,6 +234,37 @@ void DHUDMessage::ScreenSizeChanged ()
|
|||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// DHUDMessage :: CalcClipCoords
|
||||
//
|
||||
// Take the clip rectangle in HUD coordinates (set via SetHudSize in ACS)
|
||||
// and convert them to screen coordinates.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void DHUDMessage::CalcClipCoords(int hudheight)
|
||||
{
|
||||
int x = ClipX, y = ClipY, w = ClipWidth, h = ClipHeight;
|
||||
|
||||
if ((x | y | w | h) == 0)
|
||||
{ // No clipping rectangle set; use the full screen.
|
||||
ClipLeft = 0;
|
||||
ClipTop = 0;
|
||||
ClipRight = screen->GetWidth();
|
||||
ClipBot = screen->GetHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->VirtualToRealCoordsInt(x, y, w, h,
|
||||
HUDWidth, hudheight, false, true);
|
||||
ClipLeft = x;
|
||||
ClipTop = y;
|
||||
ClipRight = x + w;
|
||||
ClipBot = y + h;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// DHUDMessage :: ResetText
|
||||
|
@ -232,11 +277,11 @@ void DHUDMessage::ResetText (const char *text)
|
|||
|
||||
if (HUDWidth != 0)
|
||||
{
|
||||
width = HUDWidth;
|
||||
width = ClipWidth == 0 ? HUDWidth : ClipWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = con_scaletext >=2 ? SCREENWIDTH/2 : (con_scaletext ? SCREENWIDTH / CleanXfac : SCREENWIDTH);
|
||||
width = con_scaletext >= 2 ? SCREENWIDTH/2 : (con_scaletext ? SCREENWIDTH / CleanXfac : SCREENWIDTH);
|
||||
}
|
||||
|
||||
if (Lines != NULL)
|
||||
|
@ -244,7 +289,7 @@ void DHUDMessage::ResetText (const char *text)
|
|||
V_FreeBrokenLines (Lines);
|
||||
}
|
||||
|
||||
Lines = V_BreakLines (Font, width, (BYTE *)text);
|
||||
Lines = V_BreakLines (Font, NoWrap ? INT_MAX : width, (BYTE *)text);
|
||||
|
||||
NumLines = 0;
|
||||
Width = 0;
|
||||
|
@ -377,15 +422,14 @@ void DHUDMessage::Draw (int bottom, int visibility)
|
|||
ystep = Font->GetHeight() * yscale;
|
||||
|
||||
if (HUDHeight < 0)
|
||||
{
|
||||
// A negative height means the HUD size covers the status bar
|
||||
{ // A negative height means the HUD size covers the status bar
|
||||
hudheight = -HUDHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
// A positive height means the HUD size does not cover the status bar
|
||||
{ // A positive height means the HUD size does not cover the status bar
|
||||
hudheight = Scale (HUDHeight, screen_height, bottom);
|
||||
}
|
||||
CalcClipCoords(hudheight);
|
||||
|
||||
for (i = 0; i < NumLines; i++)
|
||||
{
|
||||
|
@ -441,6 +485,10 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight)
|
|||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_ClipLeft, ClipLeft,
|
||||
DTA_ClipRight, ClipRight,
|
||||
DTA_ClipTop, ClipTop,
|
||||
DTA_ClipBottom, ClipBot,
|
||||
DTA_Alpha, Alpha,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
|
@ -541,6 +589,10 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh
|
|||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_ClipLeft, ClipLeft,
|
||||
DTA_ClipRight, ClipRight,
|
||||
DTA_ClipTop, ClipTop,
|
||||
DTA_ClipBottom, ClipBot,
|
||||
DTA_Alpha, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
|
@ -638,6 +690,10 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu
|
|||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_ClipLeft, ClipLeft,
|
||||
DTA_ClipRight, ClipRight,
|
||||
DTA_ClipTop, ClipTop,
|
||||
DTA_ClipBottom, ClipBot,
|
||||
DTA_Alpha, trans,
|
||||
DTA_RenderStyle, Style,
|
||||
TAG_DONE);
|
||||
|
@ -814,6 +870,10 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in
|
|||
screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text,
|
||||
DTA_VirtualWidth, HUDWidth,
|
||||
DTA_VirtualHeight, hudheight,
|
||||
DTA_ClipLeft, ClipLeft,
|
||||
DTA_ClipRight, ClipRight,
|
||||
DTA_ClipTop, ClipTop,
|
||||
DTA_ClipBottom, ClipBot,
|
||||
DTA_Alpha, Alpha,
|
||||
DTA_TextLen, LineVisible,
|
||||
DTA_RenderStyle, Style,
|
||||
|
|
|
@ -85,22 +85,42 @@ public:
|
|||
{
|
||||
Alpha = alpha;
|
||||
}
|
||||
void SetNoWrap(bool nowrap)
|
||||
{
|
||||
NoWrap = nowrap;
|
||||
ResetText(SourceText);
|
||||
}
|
||||
void SetClipRect(int x, int y, int width, int height)
|
||||
{
|
||||
ClipX = x;
|
||||
ClipY = y;
|
||||
ClipWidth = width;
|
||||
ClipHeight = height;
|
||||
}
|
||||
void SetWrapWidth(int wrap)
|
||||
{
|
||||
WrapWidth = wrap;
|
||||
ResetText(SourceText);
|
||||
}
|
||||
|
||||
protected:
|
||||
FBrokenLines *Lines;
|
||||
int Width, Height, NumLines;
|
||||
float Left, Top;
|
||||
bool CenterX;
|
||||
bool CenterX, NoWrap;
|
||||
int HoldTics;
|
||||
int Tics;
|
||||
int State;
|
||||
int VisibilityFlags;
|
||||
int HUDWidth, HUDHeight;
|
||||
int ClipX, ClipY, ClipWidth, ClipHeight, WrapWidth; // in HUD coords
|
||||
int ClipLeft, ClipTop, ClipRight, ClipBot; // in screen coords
|
||||
EColorRange TextColor;
|
||||
FFont *Font;
|
||||
FRenderStyle Style;
|
||||
fixed_t Alpha;
|
||||
|
||||
void CalcClipCoords(int hudheight);
|
||||
DHUDMessage () : SourceText(NULL) {}
|
||||
|
||||
private:
|
||||
|
|
|
@ -93,6 +93,7 @@ FRandom pr_acs ("ACS");
|
|||
#define HUDMSG_COLORSTRING (0x40000000)
|
||||
#define HUDMSG_ADDBLEND (0x20000000)
|
||||
#define HUDMSG_ALPHA (0x10000000)
|
||||
#define HUDMSG_NOWRAP (0x08000000)
|
||||
|
||||
// HUD message layers; these are not flags
|
||||
#define HUDMSG_LAYER_SHIFT 12
|
||||
|
@ -2169,6 +2170,15 @@ void DLevelScript::Serialize (FArchive &arc)
|
|||
|
||||
arc << activefont
|
||||
<< hudwidth << hudheight;
|
||||
if (SaveVersion >= 3960)
|
||||
{
|
||||
arc << ClipRectLeft << ClipRectTop << ClipRectWidth << ClipRectHeight
|
||||
<< WrapWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClipRectLeft = ClipRectTop = ClipRectWidth = ClipRectHeight = WrapWidth = 0;
|
||||
}
|
||||
}
|
||||
|
||||
DLevelScript::DLevelScript ()
|
||||
|
@ -3382,10 +3392,12 @@ enum EACSFunctions
|
|||
ACSF_Sqrt,
|
||||
ACSF_FixedSqrt,
|
||||
ACSF_VectorLength,
|
||||
ACSF_SetHUDClipRect,
|
||||
ACSF_SetHUDWrapWidth,
|
||||
|
||||
// ZDaemon
|
||||
ACSF_GetTeamScore = 19620,
|
||||
ACSF_SetTeamScore,
|
||||
ACSF_GetTeamScore = 19620, // (int team)
|
||||
ACSF_SetTeamScore, // (int team, int value)
|
||||
};
|
||||
|
||||
int DLevelScript::SideFromID(int id, int side)
|
||||
|
@ -3900,11 +3912,9 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
|||
|
||||
case ACSF_UniqueTID:
|
||||
return P_FindUniqueTID(argCount > 0 ? args[0] : 0, argCount > 1 ? args[1] : 0);
|
||||
break;
|
||||
|
||||
case ACSF_IsTIDUsed:
|
||||
return P_IsTIDUsed(args[0]);
|
||||
break;
|
||||
|
||||
case ACSF_Sqrt:
|
||||
return xs_FloorToInt(sqrt(double(args[0])));
|
||||
|
@ -3915,6 +3925,18 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
|||
case ACSF_VectorLength:
|
||||
return FLOAT2FIXED(TVector2<double>(FIXED2DBL(args[0]), FIXED2DBL(args[1])).Length());
|
||||
|
||||
case ACSF_SetHUDClipRect:
|
||||
ClipRectLeft = argCount > 0 ? args[0] : 0;
|
||||
ClipRectTop = argCount > 1 ? args[1] : 0;
|
||||
ClipRectWidth = argCount > 2 ? args[2] : 0;
|
||||
ClipRectHeight = argCount > 3 ? args[3] : 0;
|
||||
WrapWidth = argCount > 4 ? args[4] : 0;
|
||||
break;
|
||||
|
||||
case ACSF_SetHUDWrapWidth:
|
||||
WrapWidth = argCount > 0 ? args[0] : 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -5737,7 +5759,16 @@ scriptwait:
|
|||
}
|
||||
break;
|
||||
}
|
||||
msg->SetClipRect(ClipRectLeft, ClipRectTop, ClipRectWidth, ClipRectHeight);
|
||||
if (WrapWidth != 0)
|
||||
{
|
||||
msg->SetWrapWidth(WrapWidth);
|
||||
}
|
||||
msg->SetVisibility((type & HUDMSG_VISIBILITY_MASK) >> HUDMSG_VISIBILITY_SHIFT);
|
||||
if (type & HUDMSG_NOWRAP)
|
||||
{
|
||||
msg->SetNoWrap(true);
|
||||
}
|
||||
if (type & HUDMSG_ALPHA)
|
||||
{
|
||||
msg->SetAlpha(alpha);
|
||||
|
@ -7351,7 +7382,9 @@ DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr
|
|||
backSide = flags & ACS_BACKSIDE;
|
||||
activefont = SmallFont;
|
||||
hudwidth = hudheight = 0;
|
||||
ClipRectLeft = ClipRectTop = ClipRectWidth = ClipRectHeight = WrapWidth = 0;
|
||||
state = SCRIPT_Running;
|
||||
|
||||
// Hexen waited one second before executing any open scripts. I didn't realize
|
||||
// this when I wrote my ACS implementation. Now that I know, it's still best to
|
||||
// run them right away because there are several map properties that can't be
|
||||
|
|
|
@ -707,6 +707,8 @@ protected:
|
|||
bool backSide;
|
||||
FFont *activefont;
|
||||
int hudwidth, hudheight;
|
||||
int ClipRectLeft, ClipRectTop, ClipRectWidth, ClipRectHeight;
|
||||
int WrapWidth;
|
||||
FBehavior *activeBehavior;
|
||||
|
||||
void Link ();
|
||||
|
|
Loading…
Reference in a new issue