- simplified the parameters of the HUD draw functions by moving all booleans into one flags word and ordering them so that the less likely ones to be used can be made optional.

- got rid of the image list in the Doom status bar. The cost of the texture lookup is mostly irrelevant here so clearer and shorter code is preferrable.
- moved the box fitting code from DrawTexture into the native function to have all coordinate calculations in one place which is necessary to implement proper alignment default handling. Without higher level functions altering positioning the default can be set to automatic alignment determination, i.e. the value's sign decides where something is placed. Of course for special cases this can be overridden.
- use ANIMDEFS to animate the inventory arrow,
This commit is contained in:
Christoph Oelckers 2017-03-26 18:41:24 +02:00
parent 1c71d038dd
commit 08b3c38304
9 changed files with 400 additions and 350 deletions

View file

@ -356,13 +356,6 @@ public:
CENTER_BOTTOM = BOTTOM | HCENTER CENTER_BOTTOM = BOTTOM | HCENTER
}; };
enum ETextAlign
{
ALIGN_LEFT = 0,
ALIGN_CENTER = 1,
ALIGN_RIGHT = 2
};
DBaseStatusBar (); DBaseStatusBar ();
void SetSize(int reltop = 32, int hres = 320, int vres = 200); void SetSize(int reltop = 32, int hres = 320, int vres = 200);
void OnDestroy() override; void OnDestroy() override;
@ -402,10 +395,8 @@ public:
void DrawLog(); void DrawLog();
uint32_t GetTranslation() const; uint32_t GetTranslation() const;
void DrawGraphic(FTextureID texture, bool animate, double x, double y, double Alpha = 1., bool translatable = false, bool dim = false, void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY);
int imgAlign = TOP | LEFT, int screenalign = TOP | LEFT, bool alphamap = false, double width = -1, double height = -1); void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY);
void DrawString(FFont *font, const FString &cstring, double x, double y, double Alpha, int translation, int align, int screenalign, int spacing = 0, bool monospaced = false, int shadowX = 0, int shadowY = 0);
void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false); void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false);
void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false); void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false);
@ -436,8 +427,6 @@ public:
double Displacement; double Displacement;
bool ShowLog; bool ShowLog;
FImageCollection Images;
player_t *CPlayer; player_t *CPlayer;
double Alpha = 1.; double Alpha = 1.;
@ -471,6 +460,7 @@ extern FTexture *CrosshairImage;
FTextureID GetInventoryIcon(AInventory *item, uint32_t flags, bool *applyscale); FTextureID GetInventoryIcon(AInventory *item, uint32_t flags, bool *applyscale);
enum DI_Flags enum DI_Flags
{ {
DI_SKIPICON = 0x1, DI_SKIPICON = 0x1,
@ -478,11 +468,68 @@ enum DI_Flags
DI_SKIPSPAWN = 0x4, DI_SKIPSPAWN = 0x4,
DI_SKIPREADY = 0x8, DI_SKIPREADY = 0x8,
DI_ALTICONFIRST = 0x10, DI_ALTICONFIRST = 0x10,
DI_TRANSLATABLE = 0x20,
DI_DRAWINBOX = 0x20, // Set when either width or height is not zero
DI_FORCESCALE = 0x40, DI_FORCESCALE = 0x40,
DI_ALTERNATEONFAIL = 0x80 DI_DIM = 0x80,
DI_DRAWCURSORFIRST = 0x100, // only for DrawInventoryBar.
DI_ALWAYSSHOWCOUNT = 0x200, // only for DrawInventoryBar.
DI_DIMDEPLETED = 0x400,
DI_DONTANIMATE = 0x800, // do not animate the texture
// These 2 flags are only used by SBARINFO
DI_DRAWINBOX = 0x1000, // Set when either width or height is not zero
DI_ALTERNATEONFAIL = 0x2000,
DI_SCREEN_AUTO = 0, // decide based on given offsets.
DI_SCREEN_MANUAL_ALIGN = 0x4000, // If this is on, the following flags will have an effect
DI_SCREEN_TOP = DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_VCENTER = 0x8000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_BOTTOM = 0x10000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_VOFFSET = 0x18000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_VMASK = 0x18000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_LEFT = DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_HCENTER = 0x20000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_RIGHT = 0x40000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_HOFFSET = 0x60000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_HMASK = 0x60000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_LEFT_TOP = DI_SCREEN_TOP|DI_SCREEN_LEFT,
DI_SCREEN_RIGHT_TOP = DI_SCREEN_TOP|DI_SCREEN_RIGHT,
DI_SCREEN_LEFT_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_LEFT,
DI_SCREEN_RIGHT_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_RIGHT,
DI_SCREEN_CENTER = DI_SCREEN_VCENTER|DI_SCREEN_HCENTER,
DI_SCREEN_CENTER_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_HCENTER,
DI_SCREEN_OFFSETS = DI_SCREEN_HOFFSET|DI_SCREEN_VOFFSET,
DI_ITEM_AUTO = 0, // equivalent with bottom center, which is the default alignment.
DI_ITEM_TOP = 0x80000,
DI_ITEM_VCENTER = 0x100000,
DI_ITEM_BOTTOM = 0, // this is the default vertical alignment
DI_ITEM_VOFFSET = 0x180000,
DI_ITEM_VMASK = 0x180000,
DI_ITEM_LEFT = 0x200000,
DI_ITEM_HCENTER = 0, // this is the deafault horizontal alignment
DI_ITEM_RIGHT = 0x400000,
DI_ITEM_HOFFSET = 0x600000,
DI_ITEM_HMASK = 0x600000,
DI_ITEM_LEFT_TOP = DI_ITEM_TOP|DI_ITEM_LEFT,
DI_ITEM_RIGHT_TOP = DI_ITEM_TOP|DI_ITEM_RIGHT,
DI_ITEM_LEFT_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_LEFT,
DI_ITEM_RIGHT_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_RIGHT,
DI_ITEM_CENTER = DI_ITEM_VCENTER|DI_ITEM_HCENTER,
DI_ITEM_CENTER_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_HCENTER,
DI_ITEM_OFFSETS = DI_ITEM_HOFFSET|DI_ITEM_VOFFSET,
DI_TEXT_ALIGN_LEFT = 0,
DI_TEXT_ALIGN_RIGHT = 0x800000,
DI_TEXT_ALIGN_CENTER = 0x1000000,
DI_TEXT_ALIGN = 0x1800000,
DI_ALPHAMAPPED = 0x2000000,
}; };
#endif /* __SBAR_H__ */ #endif /* __SBAR_H__ */

View file

@ -65,9 +65,7 @@ enum
imgSELECTBOX, imgSELECTBOX,
imgCURSOR, imgCURSOR,
imgINVLFGEM1, imgINVLFGEM1,
imgINVLFGEM2,
imgINVRTGEM1, imgINVRTGEM1,
imgINVRTGEM2,
}; };
EXTERN_CVAR(Int, fraglimit) EXTERN_CVAR(Int, fraglimit)
@ -981,8 +979,7 @@ public:
static const char *InventoryBarLumps[] = static const char *InventoryBarLumps[] =
{ {
"ARTIBOX", "SELECTBO", "INVCURS", "INVGEML1", "ARTIBOX", "SELECTBO", "INVCURS", "INVGEML1", "INVGEMR1",
"INVGEML2", "INVGEMR1", "INVGEMR2",
"USEARTIA", "USEARTIB", "USEARTIC", "USEARTID", "USEARTIA", "USEARTIB", "USEARTIC", "USEARTID",
}; };
TArray<const char *> patchnames; TArray<const char *> patchnames;

View file

@ -2230,16 +2230,14 @@ class CommandDrawInventoryBar : public SBarInfoCommand
{ {
int offset = (style != STYLE_Strife ? (style != STYLE_HexenStrict ? -12 : -10) : 14); int offset = (style != STYLE_Strife ? (style != STYLE_HexenStrict ? -12 : -10) : 14);
int yOffset = style != STYLE_HexenStrict ? 0 : -1; int yOffset = style != STYLE_HexenStrict ? 0 : -1;
statusBar->DrawGraphic(statusBar->Images[!(gametic & 4) ? statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgINVLFGEM1], x + (!vertical ? offset : yOffset), y + (vertical ? offset : yOffset), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets());
statusBar->invBarOffset + imgINVLFGEM1 : statusBar->invBarOffset + imgINVLFGEM2], x + (!vertical ? offset : yOffset), y + (vertical ? offset : yOffset), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets());
} }
// Is there something to the right? // Is there something to the right?
if (!noArrows && item != NULL) if (!noArrows && item != NULL)
{ {
int offset = (style != STYLE_Strife ? (style != STYLE_HexenStrict ? size*31+2 : size*31) : size*35-4); int offset = (style != STYLE_Strife ? (style != STYLE_HexenStrict ? size*31+2 : size*31) : size*35-4);
int yOffset = style != STYLE_HexenStrict ? 0 : -1; int yOffset = style != STYLE_HexenStrict ? 0 : -1;
statusBar->DrawGraphic(statusBar->Images[!(gametic & 4) ? statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgINVRTGEM1], x + (!vertical ? offset : yOffset), y + (vertical ? offset : yOffset), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets());
statusBar->invBarOffset + imgINVRTGEM1 : statusBar->invBarOffset + imgINVRTGEM2], x + (!vertical ? offset : yOffset), y + (vertical ? offset : yOffset), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets());
} }
} }
} }

View file

@ -1543,31 +1543,71 @@ uint32_t DBaseStatusBar::GetTranslation() const
// //
//============================================================================ //============================================================================
void DBaseStatusBar::DrawGraphic(FTextureID texture, bool animate, double x, double y, double Alpha, bool translatable, bool dim, void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY)
int imgAlign, int screenalign, bool alphamap, double width, double height)
{ {
if (!texture.isValid()) if (!texture.isValid())
return; return;
FTexture *tex = (flags & DI_DONTANIMATE)? TexMan[texture] : TexMan(texture);
double texwidth = tex->GetScaledWidthDouble() * scaleX;
double texheight = tex->GetScaledHeightDouble() * scaleY;
if (boxwidth > 0 || boxheight > 0)
{
double scale1 = 1., scale2 = 1.;
if (boxwidth > 0 && (boxwidth < texwidth || (flags & DI_FORCESCALE)))
{
scale1 = boxwidth / texwidth;
}
if (boxheight != -1 && (boxheight < texheight || (flags & DI_FORCESCALE)))
{
scale2 = boxheight / texheight;
}
if (flags & DI_FORCESCALE)
{
if (boxwidth <= 0 || (boxheight > 0 && scale2 < scale1))
scale1 = scale2;
}
else scale1 = MIN(scale1, scale2);
boxwidth = texwidth * scale1;
boxheight = texheight * scale1;
}
else
{
boxwidth = texwidth;
boxheight = texheight;
}
// resolve auto-alignment before making any adjustments to the position values.
if (!(flags & DI_SCREEN_MANUAL_ALIGN))
{
if (x < 0) flags |= DI_SCREEN_RIGHT;
else flags |= DI_SCREEN_LEFT;
if (y < 0) flags |= DI_SCREEN_BOTTOM;
else flags |= DI_SCREEN_TOP;
}
Alpha *= this->Alpha; Alpha *= this->Alpha;
if (Alpha <= 0) return; if (Alpha <= 0) return;
x += drawOffset.X; x += drawOffset.X;
y += drawOffset.Y; y += drawOffset.Y;
FTexture *tex = animate ? TexMan(texture) : TexMan[texture]; switch (flags & DI_ITEM_HMASK)
switch (imgAlign & HMASK)
{ {
case HCENTER: x -= width / 2; break; case DI_ITEM_HCENTER: x -= boxwidth / 2; break;
case RIGHT: x -= width; break; case DI_ITEM_RIGHT: x -= boxwidth; break;
case HOFFSET: x -= tex->GetScaledLeftOffsetDouble() * width / tex->GetScaledWidthDouble(); break; case DI_ITEM_HOFFSET: x -= tex->GetScaledLeftOffsetDouble() * boxwidth / texwidth; break;
} }
switch (imgAlign & VMASK) switch (flags & DI_ITEM_VMASK)
{ {
case VCENTER: y -= height / 2; break; case DI_ITEM_VCENTER: y -= texheight / 2; break;
case BOTTOM: y -= height; break; case DI_ITEM_BOTTOM: y -= texheight; break;
case VOFFSET: y -= tex->GetScaledTopOffsetDouble() * height / tex->GetScaledHeightDouble(); break; case DI_ITEM_VOFFSET: y -= tex->GetScaledTopOffsetDouble() * boxheight / texheight; break;
} }
if (!fullscreenOffsets) if (!fullscreenOffsets)
@ -1578,89 +1618,139 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, bool animate, double x, dou
// Todo: Allow other scaling values, too. // Todo: Allow other scaling values, too.
if (Scaled) if (Scaled)
{ {
screen->VirtualToRealCoords(x, y, width, height, HorizontalResolution, VerticalResolution, true, true); screen->VirtualToRealCoords(x, y, boxwidth, boxheight, HorizontalResolution, VerticalResolution, true, true);
} }
} }
else else
{ {
double orgx, orgy; double orgx, orgy;
switch (screenalign & HMASK) switch (flags & DI_SCREEN_HMASK)
{ {
default: orgx = 0; break; default: orgx = 0; break;
case HCENTER: orgx = screen->GetWidth() / 2; break; case DI_SCREEN_HCENTER: orgx = screen->GetWidth() / 2; break;
case RIGHT: orgx = screen->GetWidth(); break; case DI_SCREEN_RIGHT: orgx = screen->GetWidth(); break;
} }
switch (screenalign & VMASK) switch (flags & DI_SCREEN_VMASK)
{ {
default: orgy = 0; break; default: orgy = 0; break;
case VCENTER: orgy = screen->GetHeight() / 2; break; case DI_SCREEN_VCENTER: orgy = screen->GetHeight() / 2; break;
case BOTTOM: orgy = screen->GetHeight(); break; case DI_SCREEN_BOTTOM: orgy = screen->GetHeight(); break;
} }
if (screenalign == (RIGHT | TOP) && vid_fps) y += 10; // move stuff in the top right corner a bit down if the fps counter is on.
if ((flags & (DI_SCREEN_HMASK|DI_SCREEN_VMASK)) == DI_SCREEN_RIGHT_TOP && vid_fps) y += 10;
DVector2 Scale = GetHUDScale(); DVector2 Scale = GetHUDScale();
x *= Scale.X; x *= Scale.X;
y *= Scale.Y; y *= Scale.Y;
width *= Scale.X; boxwidth *= Scale.X;
height *= Scale.Y; boxheight *= Scale.Y;
x += orgx; x += orgx;
y += orgy; y += orgy;
} }
screen->DrawTexture(tex, x, y, screen->DrawTexture(tex, x, y,
DTA_TopOffset, 0, DTA_TopOffset, 0,
DTA_LeftOffset, 0, DTA_LeftOffset, 0,
DTA_DestWidthF, width, DTA_DestWidthF, boxwidth,
DTA_DestHeightF, height, DTA_DestHeightF, boxheight,
DTA_TranslationIndex, translatable ? GetTranslation() : 0, DTA_TranslationIndex, (flags & DI_TRANSLATABLE) ? GetTranslation() : 0,
DTA_ColorOverlay, dim ? MAKEARGB(170, 0, 0, 0) : 0, DTA_ColorOverlay, (flags & DI_DIM) ? MAKEARGB(170, 0, 0, 0) : 0,
DTA_Alpha, Alpha, DTA_Alpha, Alpha,
DTA_AlphaChannel, alphamap, DTA_AlphaChannel, !!(flags & DI_ALPHAMAPPED),
DTA_FillColor, alphamap ? 0 : -1); DTA_FillColor, (flags & DI_ALPHAMAPPED) ? 0 : -1);
} }
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawGraphic) DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawTexture)
{ {
PARAM_SELF_PROLOGUE(DBaseStatusBar); PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_INT(texid); PARAM_INT(texid);
PARAM_BOOL(animate);
PARAM_FLOAT(x); PARAM_FLOAT(x);
PARAM_FLOAT(y); PARAM_FLOAT(y);
PARAM_FLOAT(alpha); PARAM_INT_DEF(flags);
PARAM_BOOL(translatable); PARAM_FLOAT_DEF(alpha);
PARAM_BOOL(dim); PARAM_FLOAT_DEF(w);
PARAM_INT(ialign); PARAM_FLOAT_DEF(h);
PARAM_INT(salign); PARAM_FLOAT_DEF(scaleX);
PARAM_BOOL(alphamap); PARAM_FLOAT_DEF(scaleY);
PARAM_FLOAT(w); self->DrawGraphic(FSetTextureID(texid), x, y, flags, alpha, w, h, scaleX, scaleY);
PARAM_FLOAT(h); return 0;
self->DrawGraphic(FSetTextureID(texid), animate, x, y, alpha, translatable, dim, ialign, salign, alphamap, w, h); }
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawImage)
{
PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_STRING(texid);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_INT_DEF(flags);
PARAM_FLOAT_DEF(alpha);
PARAM_FLOAT_DEF(w);
PARAM_FLOAT_DEF(h);
PARAM_FLOAT_DEF(scaleX);
PARAM_FLOAT_DEF(scaleY);
self->DrawGraphic(TexMan.CheckForTexture(texid, FTexture::TEX_Any), x, y, flags, alpha, w, h, scaleX, scaleY);
return 0; return 0;
} }
//============================================================================ //============================================================================
// //
// draw stuff // encapsulates all settings a HUD font may need
// //
//============================================================================ //============================================================================
void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, double y, double Alpha, int translation, int align, int screenalign, int spacing, bool monospaced, int shadowX, int shadowY) class DHUDFont : public DObject
{ {
switch (align) // this blocks CreateNew on this class which is the intent here.
DECLARE_ABSTRACT_CLASS(DHUDFont, DObject);
public:
FFont *mFont;
int mSpacing;
bool mMonospaced;
int mShadowX;
int mShadowY;
DHUDFont(FFont *f, int sp, bool ms, int sx, int sy)
: mFont(f), mSpacing(sp), mMonospaced(ms), mShadowX(sx), mShadowY(sy)
{}
};
IMPLEMENT_CLASS(DHUDFont, true, false);
DEFINE_ACTION_FUNCTION(DHUDFont, Create)
{
PARAM_PROLOGUE;
PARAM_POINTER(fnt, FFont);
PARAM_INT_DEF(spac);
PARAM_BOOL_DEF(mono);
PARAM_INT_DEF(sx);
PARAM_INT_DEF(sy);
ACTION_RETURN_POINTER(new DHUDFont(fnt, spac, mono, sy, sy));
}
//============================================================================
//
// draw a string
//
//============================================================================
void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY)
{
switch (flags & DI_TEXT_ALIGN)
{ {
default: default:
break; break;
case ALIGN_RIGHT: case DI_TEXT_ALIGN_RIGHT:
if (!monospaced) if (!monospaced)
x -= static_cast<int> (font->StringWidth(cstring) + (spacing * cstring.Len())); x -= static_cast<int> (font->StringWidth(cstring) + (spacing * cstring.Len()));
else //monospaced, so just multiply the character size else //monospaced, so just multiply the character size
x -= static_cast<int> ((spacing) * cstring.Len()); x -= static_cast<int> ((spacing) * cstring.Len());
break; break;
case ALIGN_CENTER: case DI_TEXT_ALIGN_CENTER:
if (!monospaced) if (!monospaced)
x -= static_cast<int> (font->StringWidth(cstring) + (spacing * cstring.Len())) / 2; x -= static_cast<int> (font->StringWidth(cstring) + (spacing * cstring.Len())) / 2;
else //monospaced, so just multiply the character size else //monospaced, so just multiply the character size
@ -1680,21 +1770,22 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
shadowX *= (int)Scale.X; shadowX *= (int)Scale.X;
shadowY *= (int)Scale.Y; shadowY *= (int)Scale.Y;
switch (screenalign & HMASK) switch (flags & DI_SCREEN_HMASK)
{ {
default: orgx = 0; break; default: orgx = 0; break;
case HCENTER: orgx = screen->GetWidth() / 2; break; case DI_SCREEN_HCENTER: orgx = screen->GetWidth() / 2; break;
case RIGHT: orgx = screen->GetWidth(); break; case DI_SCREEN_RIGHT: orgx = screen->GetWidth(); break;
} }
switch (screenalign & VMASK) switch (flags & DI_SCREEN_VMASK)
{ {
default: orgy = 0; break; default: orgy = 0; break;
case VCENTER: orgy = screen->GetHeight() / 2; break; case DI_SCREEN_VCENTER: orgy = screen->GetHeight() / 2; break;
case BOTTOM: orgy = screen->GetHeight(); break; case DI_SCREEN_BOTTOM: orgy = screen->GetHeight(); break;
} }
if (screenalign == (RIGHT | TOP) && vid_fps) orgy += 10; // move stuff in the top right corner a bit down if the fps counter is on.
if ((flags & (DI_SCREEN_HMASK | DI_SCREEN_VMASK)) == DI_SCREEN_RIGHT_TOP && vid_fps) y += 10;
} }
else else
{ {
@ -1732,23 +1823,6 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
rw = c->GetScaledWidthDouble(); rw = c->GetScaledWidthDouble();
rh = c->GetScaledHeightDouble(); rh = c->GetScaledHeightDouble();
if (monospaced)
{
// align the character in the monospaced cell according to the general alignment to ensure that it gets positioned properly
// (i.e. right aligned text aligns to the right edge of the character and not the empty part of the cell.)
switch (align)
{
default:
break;
case ALIGN_CENTER:
rx -= (spacing) / 2;
break;
case ALIGN_RIGHT:
rx -= spacing;
break;
}
}
if (!fullscreenOffsets) if (!fullscreenOffsets)
{ {
rx += ST_X; rx += ST_X;
@ -1795,39 +1869,42 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
} }
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawString) DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawString)
{ {
PARAM_SELF_PROLOGUE(DBaseStatusBar); PARAM_SELF_PROLOGUE(DBaseStatusBar);
PARAM_POINTER(font, FFont); PARAM_POINTER(font, DHUDFont);
PARAM_STRING(string); PARAM_STRING(string);
PARAM_FLOAT(x); PARAM_FLOAT(x);
PARAM_FLOAT(y); PARAM_FLOAT(y);
PARAM_FLOAT(alpha); PARAM_INT_DEF(flags);
PARAM_INT(trans); PARAM_INT_DEF(trans);
PARAM_INT(ialign); PARAM_FLOAT_DEF(alpha);
PARAM_INT(salign);
PARAM_INT_DEF(spacing);
PARAM_BOOL_DEF(monospaced);
PARAM_INT_DEF(shadowX);
PARAM_INT_DEF(shadowY);
PARAM_INT_DEF(wrapwidth); PARAM_INT_DEF(wrapwidth);
PARAM_INT_DEF(linespacing); PARAM_INT_DEF(linespacing);
// resolve auto-alignment before making any adjustments to the position values.
if (!(flags & DI_SCREEN_MANUAL_ALIGN))
{
if (x < 0) flags |= DI_SCREEN_RIGHT;
else flags |= DI_SCREEN_LEFT;
if (y < 0) flags |= DI_SCREEN_BOTTOM;
else flags |= DI_SCREEN_TOP;
}
if (wrapwidth > 0) if (wrapwidth > 0)
{ {
FBrokenLines *brk = V_BreakLines(font, wrapwidth, string, true); FBrokenLines *brk = V_BreakLines(font->mFont, wrapwidth, string, true);
for (int i = 0; brk[i].Width >= 0; i++) for (int i = 0; brk[i].Width >= 0; i++)
{ {
self->DrawString(font, brk[i].Text, x, y, alpha, trans, ialign, salign, spacing, monospaced, shadowX, shadowY); self->DrawString(font->mFont, brk[i].Text, x, y, flags, alpha, trans, font->mSpacing, font->mMonospaced, font->mShadowX, font->mShadowY);
y += font->GetHeight() + linespacing; y += font->mFont->GetHeight() + linespacing;
} }
V_FreeBrokenLines(brk); V_FreeBrokenLines(brk);
} }
else else
{ {
self->DrawString(font, string, x, y, alpha, trans, ialign, salign, spacing, monospaced, shadowX, shadowY); self->DrawString(font->mFont, string, x, y, flags, alpha, trans, font->mSpacing, font->mMonospaced, font->mShadowX, font->mShadowY);
} }
return 0; return 0;
} }
@ -1928,9 +2005,9 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, FormatNumber)
{ {
PARAM_PROLOGUE; PARAM_PROLOGUE;
PARAM_INT(number); PARAM_INT(number);
PARAM_INT(minsize); PARAM_INT_DEF(minsize);
PARAM_INT(maxsize); PARAM_INT_DEF(maxsize);
PARAM_INT(flags); PARAM_INT_DEF(flags);
PARAM_STRING_DEF(prefix); PARAM_STRING_DEF(prefix);
static int maxvals[] = { 1, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999 }; static int maxvals[] = { 1, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999 };

View file

@ -183,6 +183,14 @@ texture optional FBULB0
// The Wings of Wrath are not included, because they stop spinning when // The Wings of Wrath are not included, because they stop spinning when
// you stop flying, so they can't be a simple animation. // you stop flying, so they can't be a simple animation.
texture optional INVGEML1
pic INVGEML1 tics 4
pic INVGEML2 tics 4
texture optional INVGEMR1
pic INVGEMR1 tics 4
pic INVGEMR2 tics 4
switch doom 1 SW1BRCOM on pic SW2BRCOM tics 0 switch doom 1 SW1BRCOM on pic SW2BRCOM tics 0
switch doom 1 SW1BRN1 on pic SW2BRN1 tics 0 switch doom 1 SW1BRN1 on pic SW2BRN1 tics 0
switch doom 1 SW1BRN2 on pic SW2BRN2 tics 0 switch doom 1 SW1BRN2 on pic SW2BRN2 tics 0

View file

@ -169,7 +169,7 @@ struct Screen native
// This is a leftover of the abandoned Inventory.DrawPowerup method. // This is a leftover of the abandoned Inventory.DrawPowerup method.
deprecated("2.5") static ui void DrawHUDTexture(TextureID tex, double x, double y) deprecated("2.5") static ui void DrawHUDTexture(TextureID tex, double x, double y)
{ {
statusBar.DrawTexture(tex, (x, y), true, 1., BaseStatusBar.ALIGN_TOP|BaseStatusBar.ALIGN_RIGHT, (32, 32), BaseStatusBar.ALIGN_CENTER_BOTTOM); statusBar.DrawTexture(tex, (x, y), BaseStatusBar.DI_SCREEN_RIGHT_TOP, 1., (32, 32));
} }
} }

View file

@ -1,53 +1,29 @@
class DoomStatusBar : BaseStatusBar class DoomStatusBar : BaseStatusBar
{ {
// it is not really needed to precache all textures but should be good practice to reduce execution time. HUDFont mHUDFont;
enum eImg //DrawInventoryBarParms diparms;
{
imgMEDIA0,
imgPSTRA0,
imgSTBAR,
imgSTTPRCNT,
imgSTKEYS0,
imgSTKEYS1,
imgSTKEYS2,
imgSTKEYS3,
imgSTKEYS4,
imgSTKEYS5,
imgSTKEYS6,
imgSTKEYS7,
imgSTKEYS8,
imgSTARMS,
imgSTGNUM2,
imgSTGNUM3,
imgSTGNUM4,
imgSTGNUM5,
imgSTGNUM6,
imgSTGNUM7,
imgSTYSNUM2,
imgSTYSNUM3,
imgSTYSNUM4,
imgSTYSNUM5,
imgSTYSNUM6,
imgSTYSNUM7,
imgSTFBANY,
NUMIMG
}
TextureID Images[NUMIMG];
int HUDFontSpacing;
override void Init() override void Init()
{ {
Super.Init(); Super.Init();
SetSize(32, 320, 200); SetSize(32, 320, 200);
DoCommonInit();
// set up the inventory bar drawer.
/*
diparms.SetDefaults(HX_SHADOW);
diparms.SetTextures("SELECTBO", "ARTIBOX", "INVGEML1", "INVGEMR1");
diparms.SetLeftArrow("INVGEML1");
diparms.SetRightArrow("INVGEMR1");
*/
// Create the font used for the fullscreen HUD
Font fnt = "HUDFONT_DOOM";
mHUDFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 1, 1);
} }
override void NewGame () override void NewGame ()
{ {
DoCommonInit ();
if (CPlayer != NULL) if (CPlayer != NULL)
{ {
AttachToPlayer (CPlayer); AttachToPlayer (CPlayer);
@ -70,27 +46,6 @@ class DoomStatusBar : BaseStatusBar
} }
} }
void DoCommonInit ()
{
static const String LumpNames[] =
{
"MEDIA0", "PSTRA0", "STBAR", "STTPRCNT", "STKEYS0",
"STKEYS1", "STKEYS2", "STKEYS3", "STKEYS4", "STKEYS5", "STKEYS6", "STKEYS7", "STKEYS8",
"STARMS",
"STGNUM2", "STGNUM3", "STGNUM4", "STGNUM5", "STGNUM6", "STGNUM7",
"STYSNUM2", "STYSNUM3", "STYSNUM4", "STYSNUM5", "STYSNUM6", "STYSNUM7",
"STFBANY"
};
for(int i = 0; i < NUMIMG; i++)
{
Images[i] = TexMan.CheckForTexture(LumpNames[i], TexMan.TYPE_MiscPatch);
}
Font fnt = "HUDFONT_DOOM";
if (fnt != null) HudFontSpacing = fnt.GetCharWidth("0");
}
protected void DrawMainBar (double TicFrac) protected void DrawMainBar (double TicFrac)
{ {
//DrawTexture(Images[imgINVBACK], (0, 0), true, 1.0, itemAlign:ALIGN_OFFSETS); //DrawTexture(Images[imgINVBACK], (0, 0), true, 1.0, itemAlign:ALIGN_OFFSETS);
@ -105,39 +60,38 @@ class DoomStatusBar : BaseStatusBar
Vector2 iconbox = (40, 20); Vector2 iconbox = (40, 20);
// Draw health // Draw health
let berserk = CPlayer.mo.FindInventory("PowerStrength"); let berserk = CPlayer.mo.FindInventory("PowerStrength");
DrawTexture(Images[berserk? imgPSTRA0 : imgMEDIA0], (20, -2), true, 1.0, ALIGN_BOTTOM|ALIGN_LEFT, iconbox, ALIGN_BOTTOM|ALIGN_HCENTER); DrawImage(berserk? "PSTRA0" : "MEDIA0", (20, -2));
DrawString("HUDFONT_DOOM", FormatNumber(CPlayer.health, 3, 0, 0), (44, -20), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_LEFT|ALIGN_BOTTOM, HUdFontSpacing, true, 1, 1); DrawString(mHUDFont, FormatNumber(CPlayer.health, 3), (44, -20));
let armor = CPlayer.mo.FindInventory("BasicArmor"); let armor = CPlayer.mo.FindInventory("BasicArmor");
if (armor != null) if (armor != null)
{ {
DrawInventoryIcon(armor, (20, -22), true, 1.0, ALIGN_BOTTOM|ALIGN_LEFT, iconbox, ALIGN_BOTTOM|ALIGN_HCENTER); DrawInventoryIcon(armor, (20, -22));
DrawString("HUDFONT_DOOM", FormatNumber(armor.Amount, 3, 0, 0), (44, -40), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_LEFT|ALIGN_BOTTOM, HUdFontSpacing, true, 1, 1); DrawString(mHUDFont, FormatNumber(armor.Amount, 3), (44, -40));
} }
Inventory ammotype1, ammotype2; Inventory ammotype1, ammotype2;
int ammoamount1, ammoamount2; [ammotype1, ammotype2] = GetCurrentAmmo();
[ammotype1, ammotype2, ammoamount1, ammoamount2] = GetCurrentAmmo();
int invY = -20; int invY = -20;
if (ammotype1 != null) if (ammotype1 != null)
{ {
DrawInventoryIcon(ammotype1, (-14, -4), true, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, iconbox, ALIGN_BOTTOM|ALIGN_HCENTER); DrawInventoryIcon(ammotype1, (-14, -4));
DrawString("HUDFONT_DOOM", FormatNumber(ammoamount1, 3, 0, 0), (-25, -20), 1., Font.CR_UNTRANSLATED, TEXT_RIGHT, ALIGN_RIGHT|ALIGN_BOTTOM, HUdFontSpacing, true, 1, 1); DrawString(mHUDFont, FormatNumber(ammotype1.Amount, 3), (-30, -20), DI_TEXT_ALIGN_RIGHT);
invY -= 20; invY -= 20;
} }
if (ammotype2 != null && ammotype2 != ammotype1) if (ammotype2 != null && ammotype2 != ammotype1)
{ {
DrawInventoryIcon(ammotype2, (-14, invY + 17), true, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, iconbox, ALIGN_BOTTOM|ALIGN_HCENTER); DrawInventoryIcon(ammotype2, (-14, invY + 17));
DrawString("HUDFONT_DOOM", FormatNumber(ammoamount2, 3, 0, 0), (-25, invY), 1., Font.CR_UNTRANSLATED, TEXT_RIGHT, ALIGN_RIGHT|ALIGN_BOTTOM, HUdFontSpacing, true, 1, 1); DrawString(mHUDFont, FormatNumber(ammotype2.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT);
invY -= 20; invY -= 20;
} }
if (CPlayer.inventorytics == 0 && CPlayer.mo.InvSel != null) if (CPlayer.inventorytics == 0 && CPlayer.mo.InvSel != null)
{ {
DrawInventoryIcon(CPlayer.mo.InvSel, (-14, invY + 17), true, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, iconbox, ALIGN_BOTTOM|ALIGN_HCENTER); DrawInventoryIcon(CPlayer.mo.InvSel, (-14, invY + 17));
DrawString("HUDFONT_DOOM", FormatNumber(CPlayer.mo.InvSel.Amount, 3, 0, 0), (-25, invY), 1., Font.CR_UNTRANSLATED, TEXT_RIGHT, ALIGN_RIGHT|ALIGN_BOTTOM, HUdFontSpacing, true, 1, 1); DrawString(mHUDFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT);
} }
if (deathmatch) if (deathmatch)
{ {
DrawString("HUDFONT_DOOM", FormatNumber(CPlayer.fragSum(), 3, 0, 0), (-3, -1), 1., Font.CR_UNTRANSLATED, TEXT_RIGHT, ALIGN_RIGHT|ALIGN_TOP, HUdFontSpacing, true, 1, 1); DrawString(mHUDFont, FormatNumber(CPlayer.fragSum(), 3), (-3, 1), DI_TEXT_ALIGN_RIGHT);
} }
// Draw the keys. This does not use a special draw function like SBARINFO because the specifics will be different for each mod // Draw the keys. This does not use a special draw function like SBARINFO because the specifics will be different for each mod
@ -149,7 +103,7 @@ class DoomStatusBar : BaseStatusBar
{ {
if (i is "Key" && i.Icon.IsValid()) if (i is "Key" && i.Icon.IsValid())
{ {
DrawTexture(i.Icon, keypos, true, 1., ALIGN_TOP|ALIGN_RIGHT, (-1,-1), ALIGN_TOP|ALIGN_LEFT); DrawTexture(i.Icon, keypos, DI_SCREEN_RIGHT_TOP|DI_ITEM_LEFT_TOP);
Vector2 size = TexMan.GetScaledSize(i.Icon); Vector2 size = TexMan.GetScaledSize(i.Icon);
keypos.Y += size.Y + 2; keypos.Y += size.Y + 2;
roww = max(roww, size.X); roww = max(roww, size.X);
@ -164,8 +118,7 @@ class DoomStatusBar : BaseStatusBar
} }
if (CPlayer.inventorytics != 0) if (CPlayer.inventorytics != 0)
{ {
//DrawInventoryBar("A //DrawInventoryBar(diparms, (0, 0), 7, ALIGN_CENTER_BOTTOM, ALIGN_CENTER_BOTTOM);
//drawinventorybar Doom, translucent, 7, INDEXFONT, -106+center, -31;
} }
} }
} }

View file

@ -15,6 +15,12 @@ struct MugShot
} }
} }
class HUDFont native ui
{
// This is intentionally opaque to the script side.
native static HUDFont Create(Font fnt, int spacing = 0, bool monospaced = false, int shadowx = 0, int shadowy = 0);
}
class BaseStatusBar native ui class BaseStatusBar native ui
{ {
@ -65,8 +71,66 @@ class BaseStatusBar native ui
DI_TRANSLATABLE = 0x20, DI_TRANSLATABLE = 0x20,
DI_FORCESCALE = 0x40, DI_FORCESCALE = 0x40,
DI_DIM = 0x80, DI_DIM = 0x80,
}; DI_DRAWCURSORFIRST = 0x100, // only for DrawInventoryBar.
DI_ALWAYSSHOWCOUNT = 0x200, // only for DrawInventoryBar.
DI_DIMDEPLETED = 0x400,
DI_DONTANIMATE = 0x800, // do not animate the texture
// These 2 flags are only used by SBARINFO
DI_DRAWINBOX = 0x1000, // Set when either width or height is not zero
DI_ALTERNATEONFAIL = 0x2000,
DI_SCREEN_AUTO = 0, // decide based on given offsets.
DI_SCREEN_MANUAL_ALIGN = 0x4000, // If this is on, the following flags will have an effect
DI_SCREEN_TOP = DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_VCENTER = 0x8000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_BOTTOM = 0x10000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_VOFFSET = 0x18000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_VMASK = 0x18000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_LEFT = DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_HCENTER = 0x20000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_RIGHT = 0x40000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_HOFFSET = 0x60000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_HMASK = 0x60000 | DI_SCREEN_MANUAL_ALIGN,
DI_SCREEN_LEFT_TOP = DI_SCREEN_TOP|DI_SCREEN_LEFT,
DI_SCREEN_RIGHT_TOP = DI_SCREEN_TOP|DI_SCREEN_RIGHT,
DI_SCREEN_LEFT_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_LEFT,
DI_SCREEN_RIGHT_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_RIGHT,
DI_SCREEN_CENTER = DI_SCREEN_VCENTER|DI_SCREEN_HCENTER,
DI_SCREEN_CENTER_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_HCENTER,
DI_SCREEN_OFFSETS = DI_SCREEN_HOFFSET|DI_SCREEN_VOFFSET,
DI_ITEM_AUTO = 0, // equivalent with bottom center, which is the default alignment.
DI_ITEM_TOP = 0x80000,
DI_ITEM_VCENTER = 0x100000,
DI_ITEM_BOTTOM = 0, // this is the default vertical alignment
DI_ITEM_VOFFSET = 0x180000,
DI_ITEM_VMASK = 0x180000,
DI_ITEM_LEFT = 0x200000,
DI_ITEM_HCENTER = 0, // this is the deafault horizontal alignment
DI_ITEM_RIGHT = 0x400000,
DI_ITEM_HOFFSET = 0x600000,
DI_ITEM_HMASK = 0x600000,
DI_ITEM_LEFT_TOP = DI_ITEM_TOP|DI_ITEM_LEFT,
DI_ITEM_RIGHT_TOP = DI_ITEM_TOP|DI_ITEM_RIGHT,
DI_ITEM_LEFT_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_LEFT,
DI_ITEM_RIGHT_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_RIGHT,
DI_ITEM_CENTER = DI_ITEM_VCENTER|DI_ITEM_HCENTER,
DI_ITEM_CENTER_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_HCENTER,
DI_ITEM_OFFSETS = DI_ITEM_HOFFSET|DI_ITEM_VOFFSET,
DI_TEXT_ALIGN_LEFT = 0,
DI_TEXT_ALIGN_RIGHT = 0x800000,
DI_TEXT_ALIGN_CENTER = 0x1000000,
DI_ALPHAMAPPED = 0x2000000,
};
enum IconType enum IconType
{ {
ITYPE_PLAYERICON = 1000, ITYPE_PLAYERICON = 1000,
@ -87,32 +151,6 @@ class BaseStatusBar native ui
HEXENARMOR_AMULET, HEXENARMOR_AMULET,
}; };
enum EAlign
{
ALIGN_TOP = 0,
ALIGN_VCENTER = 1,
ALIGN_BOTTOM = 2,
ALIGN_VOFFSET = 3,
ALIGN_VMASK = 3,
ALIGN_LEFT = 0,
ALIGN_HCENTER = 4,
ALIGN_RIGHT = 8,
ALIGN_HOFFSET = 12,
ALIGN_HMASK = 12,
ALIGN_CENTER = ALIGN_VCENTER|ALIGN_HCENTER,
ALIGN_CENTER_BOTTOM = ALIGN_BOTTOM|ALIGN_HCENTER,
ALIGN_OFFSETS = ALIGN_HOFFSET|ALIGN_VOFFSET
};
enum ETextAlign
{
TEXT_LEFT = 0,
TEXT_CENTER = 1,
TEXT_RIGHT = 2
};
enum SBGameModes enum SBGameModes
{ {
GAMEMODE_SINGLEPLAYER = 0x1, GAMEMODE_SINGLEPLAYER = 0x1,
@ -193,9 +231,10 @@ class BaseStatusBar native ui
// These functions are kept native solely for performance reasons. They get called repeatedly and can drag down performance easily if they get too slow. // These functions are kept native solely for performance reasons. They get called repeatedly and can drag down performance easily if they get too slow.
native Inventory ValidateInvFirst (int numVisible) const; native Inventory ValidateInvFirst (int numVisible) const;
native static TextureID, bool GetInventoryIcon(Inventory item, int flags); native static TextureID, bool GetInventoryIcon(Inventory item, int flags);
native void DrawGraphic(TextureID texture, bool animate, Vector2 pos, double Alpha, bool translatable, bool dim, int imgAlign, int screenalign, bool alphamap, Vector2 box); native void DrawTexture(TextureID texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1));
native void DrawString(Font font, String string, Vector2 pos , double Alpha, int translation, int align, int screenalign, int spacing=0, bool monospaced = false, int shadowX=0, int shadowY=0, int wrapwidth = -1, int linespacing = 4); native void DrawImage(String texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1));
native static String FormatNumber(int number, int minsize, int maxsize, int format, String prefix = ""); native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4);
native static String FormatNumber(int number, int minsize = 0, int maxsize = 0, int format = 0, String prefix = "");
//============================================================================ //============================================================================
@ -535,7 +574,7 @@ class BaseStatusBar native ui
if (icon.IsValid()) if (icon.IsValid())
{ {
// Each icon gets a 32x32 block. // Each icon gets a 32x32 block.
DrawTexture(icon, pos, true, 1.0, ALIGN_TOP|ALIGN_RIGHT, (POWERUPICONSIZE, POWERUPICONSIZE), ALIGN_CENTER_BOTTOM); DrawTexture(icon, pos, DI_SCREEN_RIGHT_TOP, 1.0, (POWERUPICONSIZE, POWERUPICONSIZE));
pos.x -= POWERUPICONSIZE; pos.x -= POWERUPICONSIZE;
if (pos.x < -maxpos) if (pos.x < -maxpos)
{ {
@ -560,70 +599,13 @@ class BaseStatusBar native ui
return Translation.MakeID(TRANSLATION_Players, CPlayer.mo.PlayerNumber()); return Translation.MakeID(TRANSLATION_Players, CPlayer.mo.PlayerNumber());
} }
//============================================================================
//
// draw stuff
//
//============================================================================
void DrawTexture(TextureID texture, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0, Vector2 scale = (1., 1.) )
{
if (!texture.IsValid()) return; // nothing to draw
alpha *= self.alpha;
if (alpha <= 0) return; // invisible
Vector2 texsize = TexMan.GetScaledSize(texture);
texsize.X *= scale.X;
texsize.Y *= scale.Y;
if (boxsize.X > 0 || boxsize.Y > 0)
{
double scale1 = 1., scale2 = 1.;
if (boxsize.X != -1 && (boxsize.X < texsize.X || (flags & DI_FORCESCALE)))
{
scale1 = boxsize.X / texsize.X;
}
if (boxsize.Y != -1 && (boxsize.Y < texsize.Y || (flags & DI_FORCESCALE)))
{
scale2 = boxsize.Y / texsize.Y;
}
if (flags & DI_FORCESCALE)
{
if (boxsize.X == -1 || (boxsize.Y != -1 && scale2 < scale1))
scale1 = scale2;
}
else scale1 = min(scale1, scale2);
boxsize = texsize * scale1;
}
else
{
boxsize = texsize;
}
DrawGraphic(texture, animated, pos, Alpha, !!(flags & DI_TRANSLATABLE), !!(flags & DI_DIM), itemAlign, screenAlign, false, boxsize);
}
//============================================================================ //============================================================================
// //
// //
// //
//============================================================================ //============================================================================
void DrawImage(String imagename, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0, Vector2 scale = (1., 1.) ) void DrawHexenArmor(int armortype, String image, Vector2 pos, int flags = 0, double alpha = 1.0, Vector2 boxsize = (-1, -1), Vector2 scale = (1.,1.))
{
let tex = TexMan.CheckForTexture(imagename, TexMan.TYPE_MiscPatch);
DrawTexture(tex, pos, animated, screenalign, alpha, boxsize, itemAlign, flags, scale);
}
//============================================================================
//
//
//
//============================================================================
void DrawHexenArmor(int armortype, String image, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0)
{ {
let harmor = HexenArmor(statusBar.CPlayer.mo.FindInventory("HexenArmor")); let harmor = HexenArmor(statusBar.CPlayer.mo.FindInventory("HexenArmor"));
if (harmor != NULL) if (harmor != NULL)
@ -638,7 +620,7 @@ class BaseStatusBar native ui
} }
else return; else return;
} }
DrawImage(image, pos, animated, screenalign, alpha, boxsize, itemAlign, flags); DrawImage(image, pos, flags, alpha, boxsize, scale);
} }
//============================================================================ //============================================================================
@ -647,14 +629,17 @@ class BaseStatusBar native ui
// //
//============================================================================ //============================================================================
void DrawInventoryIcon(Inventory item, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0) void DrawInventoryIcon(Inventory item, Vector2 pos, int flags = 0, double alpha = 1.0, Vector2 boxsize = (-1, -1), Vector2 scale = (1.,1.))
{ {
TextureID texture; TextureID texture;
Vector2 applyscale = (1, 1); Vector2 applyscale;
[texture, applyscale] = GetIcon(item, flags, false); [texture, applyscale] = GetIcon(item, flags, false);
if (texture.IsValid()) if (texture.IsValid())
{ {
DrawTexture(texture, pos, animated, alpha, screenalign, boxsize, itemAlign, flags, applyscale); if ((flags & DI_DIMDEPLETED) && item.Amount <= 0) flags |= DI_DIM;
applyscale.X *= scale.X;
applyscale.Y *= scale.Y;
DrawTexture(texture, pos, flags, alpha, boxsize, applyscale);
} }
} }

View file

@ -15,23 +15,10 @@ class StrifeStatusBar : BaseStatusBar
{ {
imgINVCURS, imgINVCURS,
imgCURSOR01, imgCURSOR01,
imgINVBACK,
imgINVTOP,
imgINVPOP, imgINVPOP,
imgINVPOP2, imgINVPOP2,
imgINVPBAK, imgINVPBAK,
imgINVPBAK2, imgINVPBAK2,
imgFONG0,
imgFONG1,
imgFONG2,
imgFONG3,
imgFONG4,
imgFONG5,
imgFONG6,
imgFONG7,
imgFONG8,
imgFONG9,
imgFONG_PERCENT,
imgFONY0, imgFONY0,
imgFONY1, imgFONY1,
imgFONY2, imgFONY2,
@ -43,10 +30,6 @@ class StrifeStatusBar : BaseStatusBar
imgFONY8, imgFONY8,
imgFONY9, imgFONY9,
imgFONY_PERCENT, imgFONY_PERCENT,
imgCOMM,
imgMEDI,
imgARM1,
imgARM2,
imgNEGATIVE, imgNEGATIVE,
}; };
@ -55,17 +38,40 @@ class StrifeStatusBar : BaseStatusBar
int CurrentPop, PendingPop, PopHeight, PopHeightChange; int CurrentPop, PendingPop, PopHeight, PopHeightChange;
int KeyPopPos, KeyPopScroll; int KeyPopPos, KeyPopScroll;
double ItemFlash; double ItemFlash;
HUDFont mYelFont, mGrnFont, mBigFont;
override void Init() override void Init()
{ {
static const Name strifeLumpNames[] =
{
"INVCURS", "CURSOR01", "INVPOP", "INVPOP2",
"INVPBAK", "INVPBAK2",
"INVFONY0", "INVFONY1", "INVFONY2", "INVFONY3", "INVFONY4",
"INVFONY5", "INVFONY6", "INVFONY7", "INVFONY8", "INVFONY9",
"INVFONY%", ""
};
Super.Init(); Super.Init();
SetSize(32, 320, 200); SetSize(32, 320, 200);
DoCommonInit(); Reset();
for(int i = 0; i <= imgNEGATIVE; i++)
{
Images[i] = TexMan.CheckForTexture(strifeLumpNames[i], TexMan.TYPE_MiscPatch);
}
CursorImage = Images[imgINVCURS].IsValid() ? imgINVCURS : imgCURSOR01;
mYelFont = HUDFont.Create("Indexfont_Strife_Yellow", 7, true, 1, 1);
mGrnFont = HUDFont.Create("Indexfont_Strife_Green", 7, true, 1, 1);
mBigFont = HUDFont.Create("BigFont", 0, false, 2, 2);
} }
override void NewGame () override void NewGame ()
{ {
DoCommonInit (); Reset ();
if (CPlayer != NULL) if (CPlayer != NULL)
{ {
AttachToPlayer (CPlayer); AttachToPlayer (CPlayer);
@ -142,29 +148,8 @@ class StrifeStatusBar : BaseStatusBar
return false; return false;
} }
void DoCommonInit () void Reset ()
{ {
static const String strifeLumpNames[] =
{
"INVCURS", "CURSOR01", "INVBACK", "INVTOP", "INVPOP", "INVPOP2",
"INVPBAK", "INVPBAK2",
"INVFONG0", "INVFONG1", "INVFONG2", "INVFONG3", "INVFONG4",
"INVFONG5", "INVFONG6", "INVFONG7", "INVFONG8", "INVFONG9",
"INVFONG%",
"INVFONY0", "INVFONY1", "INVFONY2", "INVFONY3", "INVFONY4",
"INVFONY5", "INVFONY6", "INVFONY7", "INVFONY8", "INVFONY9",
"INVFONY%",
"I_COMM", "I_MDKT", "I_ARM1", "I_ARM2", ""
};
for(int i = 0; i <= imgNEGATIVE; i++)
{
Images[i] = TexMan.CheckForTexture(strifeLumpNames[i], TexMan.TYPE_MiscPatch);
}
CursorImage = Images[imgINVCURS].IsValid() ? imgINVCURS : imgCURSOR01;
CurrentPop = POP_None; CurrentPop = POP_None;
PendingPop = POP_NoChange; PendingPop = POP_NoChange;
PopHeight = 0; PopHeight = 0;
@ -305,11 +290,11 @@ class StrifeStatusBar : BaseStatusBar
DrawPopScreen (Scaled ? (ST_Y - 8) * screen.GetHeight() / 200 : ST_Y - 8, TicFrac); DrawPopScreen (Scaled ? (ST_Y - 8) * screen.GetHeight() / 200 : ST_Y - 8, TicFrac);
} }
DrawTexture(Images[imgINVBACK], (0, 0), true, 1.0, itemAlign:ALIGN_OFFSETS); DrawImage("INVBACK", (0, 0), DI_ITEM_OFFSETS);
DrawTexture(Images[imgINVTOP], (0, -8), true, 1.0, itemAlign:ALIGN_OFFSETS); DrawImage("INVTOP", (0, -8), DI_ITEM_OFFSETS);
// Health // Health
DrawString("Indexfont_Strife_Green", FormatNumber(CPlayer.health, 3, 5, 0), (86, -6), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, 0, 7, true, 1, 1); DrawString(mGrnFont, FormatNumber(CPlayer.health, 3, 5), (79, -6), DI_TEXT_ALIGN_RIGHT);
int points; int points;
if (CPlayer.cheats & CF_GODMODE) if (CPlayer.cheats & CF_GODMODE)
{ {
@ -326,23 +311,23 @@ class StrifeStatusBar : BaseStatusBar
item = CPlayer.mo.FindInventory('BasicArmor'); item = CPlayer.mo.FindInventory('BasicArmor');
if (item != NULL && item.Amount > 0) if (item != NULL && item.Amount > 0)
{ {
DrawInventoryIcon(item, (2, 9), true, 1.0, itemAlign:ALIGN_OFFSETS); DrawInventoryIcon(item, (2, 9), DI_ITEM_OFFSETS);
DrawString("Indexfont_Strife_Yellow", FormatNumber(item.Amount, 3, 5, 0), (34, 23), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, 0, 7, true, 1, 1); DrawString(mYelFont, FormatNumber(item.Amount, 3, 5), (27, 23), DI_TEXT_ALIGN_RIGHT);
} }
// Ammo // Ammo
Inventory = GetCurrentAmmo (); Inventory ammo1 = GetCurrentAmmo ();
if (ammo1 != NULL) if (ammo1 != NULL)
{ {
DrawString("Indexfont_Strife_Green", FormatNumber(ammo1.Amount, 3, 5, 0), (318, -6), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, 0, 7, true, 1, 1); DrawString(mGrnFont, FormatNumber(ammo1.Amount, 3, 5), (311, -6), DI_TEXT_ALIGN_RIGHT);
DrawInventoryIcon (ammo1, (290, 13), true, 1.0, itemAlign:ALIGN_OFFSETS); DrawInventoryIcon (ammo1, (290, 13), DI_ITEM_OFFSETS);
} }
// Sigil // Sigil
item = CPlayer.mo.FindInventory('Sigil'); item = CPlayer.mo.FindInventory('Sigil');
if (item != NULL) if (item != NULL)
{ {
DrawInventoryIcon (item, (253, 7), true, 1.0, itemAlign:ALIGN_OFFSETS); DrawInventoryIcon (item, (253, 7), DI_ITEM_OFFSETS);
} }
// Inventory // Inventory
@ -351,29 +336,29 @@ class StrifeStatusBar : BaseStatusBar
i = 0; i = 0;
for (item = CPlayer.mo.InvFirst; item != NULL && i < 6; item = item.NextInv()) for (item = CPlayer.mo.InvFirst; item != NULL && i < 6; item = item.NextInv())
{ {
int flags = item.Amount <= 0? DI_ITEM_OFFSETS|DI_DIM : DI_ITEM_OFFSETS;
if (item == CPlayer.mo.InvSel) if (item == CPlayer.mo.InvSel)
{ {
DrawTexture (Images[CursorImage], (42 + 35*i, 12), true, 1. - ItemFlash, itemAlign:ALIGN_OFFSETS, item.Amount <= 0? DI_DIM : 0); DrawTexture (Images[CursorImage], (42 + 35*i, 12), flags, 1. - ItemFlash);
} }
DrawInventoryIcon (item, (48 + 35*i, 14), true, 1.0, itemAlign:ALIGN_OFFSETS, item.Amount <= 0? DI_DIM : 0); DrawInventoryIcon (item, (48 + 35*i, 14), flags);
DrawString("Indexfont_Strife_Yellow", FormatNumber(item.Amount, 3, 5, 0), (81 + 35*i, 23), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, 0, 7, true, 1, 1); DrawString(mYelFont, FormatNumber(item.Amount, 3, 5), (75 + 35*i, 23), DI_TEXT_ALIGN_RIGHT);
i++; i++;
} }
} }
protected void DrawFullScreenStuff () protected void DrawFullScreenStuff ()
{ {
// Draw health // Draw health (use red color if health is below the run health threashold.)
DrawString(mGrnFont, FormatNumber(CPlayer.health, 3), (4, -10), DI_TEXT_ALIGN_LEFT, (CPlayer.health < CPlayer.mo.RunHealth)? Font.CR_BRICK : Font.CR_UNTRANSLATED);
DrawString("Indexfont_Strife_Green", FormatNumber(CPlayer.health, 3, 0, 0), (4, -10), 1., (CPlayer.health < CPlayer.mo.RunHealth)? Font.CR_BRICK : Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_LEFT|ALIGN_BOTTOM, 7, true, 1, 1); DrawImage("I_MDKT", (14, -17));
DrawTexture(Images[imgMEDI], (14, -17), false, 1.0, ALIGN_BOTTOM|ALIGN_LEFT, itemalign: ALIGN_BOTTOM|ALIGN_HCENTER);
// Draw armor // Draw armor
let armor = CPlayer.mo.FindInventory('BasicArmor'); let armor = CPlayer.mo.FindInventory('BasicArmor');
if (armor != NULL && armor.Amount != 0) if (armor != NULL && armor.Amount != 0)
{ {
DrawString("Indexfont_Strife_Yellow", FormatNumber(armor.Amount, 3, 0, 0), (35, -10), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_LEFT|ALIGN_BOTTOM, 7, true, 1, 1); DrawString(mYelFont, FormatNumber(armor.Amount, 3), (35, -10));
DrawInventoryIcon(armor, (45, -17), false, 1.0, ALIGN_BOTTOM|ALIGN_LEFT, itemalign: ALIGN_BOTTOM|ALIGN_HCENTER); DrawInventoryIcon(armor, (45, -17));
} }
// Draw ammo // Draw ammo
@ -384,19 +369,19 @@ class StrifeStatusBar : BaseStatusBar
if (ammo1 != NULL) if (ammo1 != NULL)
{ {
// Draw primary ammo in the bottom-right corner // Draw primary ammo in the bottom-right corner
DrawString("Indexfont_Strife_Green", FormatNumber(ammo1.Amount, 3, 0, 0), (-23, -10), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_RIGHT|ALIGN_BOTTOM, 7, true, 1, 1); DrawString(mGrnFont, FormatNumber(ammo1.Amount, 3), (-23, -10));
DrawInventoryIcon(ammo1, (-14, -17), false, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, itemalign: ALIGN_BOTTOM|ALIGN_HCENTER); DrawInventoryIcon(ammo1, (-14, -17));
if (ammo2 != NULL && ammo1!=ammo2) if (ammo2 != NULL && ammo1!=ammo2)
{ {
// Draw secondary ammo just above the primary ammo // Draw secondary ammo just above the primary ammo
DrawString("Indexfont_Strife_Green", FormatNumber(ammo1.Amount, 3, 0, 0), (-23, -48), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_RIGHT|ALIGN_BOTTOM, 7, true, 1, 1); DrawString(mGrnFont, FormatNumber(ammo1.Amount, 3), (-23, -48));
DrawInventoryIcon(ammo1, (-14, -55), false, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, itemalign: ALIGN_BOTTOM|ALIGN_HCENTER); DrawInventoryIcon(ammo1, (-14, -55));
} }
} }
if (deathmatch) if (deathmatch)
{ // Draw frags (in DM) { // Draw frags (in DM)
DrawString("BigFont", FormatNumber(CPlayer.FragCount, 3, 0, 0), (-44, 1), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_RIGHT|ALIGN_TOP, 0, false, 2, 2); DrawString(mBigFont, FormatNumber(CPlayer.FragCount, 3), (4, 1));
} }
// Draw inventory // Draw inventory
@ -406,10 +391,10 @@ class StrifeStatusBar : BaseStatusBar
{ {
if (ItemFlash > 0) if (ItemFlash > 0)
{ {
DrawTexture(Images[CursorImage], (-28, -15), true, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, ItemAlign:ALIGN_BOTTOM|ALIGN_RIGHT); DrawTexture(Images[CursorImage], (-42, -15));
} }
DrawString("Indexfont_Strife_Yellow", FormatNumber(CPlayer.mo.InvSel.Amount, 3, 5, 0), (-23, -10), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, ALIGN_BOTTOM|ALIGN_RIGHT, 7, true, 1, 1); DrawString(mYelFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3, 5), (-30, -10), DI_TEXT_ALIGN_RIGHT);
DrawInventoryIcon(CPlayer.mo.InvSel, (-42, -17), true, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, ItemAlign:ALIGN_BOTTOM|ALIGN_HCENTER, CPlayer.mo.InvSel.Amount > 0 ? 0 : DI_DIM); DrawInventoryIcon(CPlayer.mo.InvSel, (-42, -17), DI_DIMDEPLETED);
} }
} }
else else
@ -424,13 +409,13 @@ class StrifeStatusBar : BaseStatusBar
{ {
if (item == CPlayer.mo.InvSel) if (item == CPlayer.mo.InvSel)
{ {
DrawTexture(Images[CursorImage], (-90+i*35, -3), true, 0.75, ALIGN_CENTER_BOTTOM, ItemAlign:ALIGN_CENTER_BOTTOM); DrawTexture(Images[CursorImage], (-90+i*35, -3), DI_SCREEN_CENTER_BOTTOM, 0.75);
} }
if (item.Icon.isValid()) if (item.Icon.isValid())
{ {
DrawInventoryIcon(item, (-90+i*35, -5), true, 0.75, ALIGN_CENTER_BOTTOM, box, ALIGN_CENTER_BOTTOM, CPlayer.mo.InvSel.Amount > 0 ? 0 : DI_DIM); DrawInventoryIcon(item, (-90+i*35, -5), DI_SCREEN_CENTER_BOTTOM|DI_DIMDEPLETED, 0.75);
} }
DrawString("Indexfont_Strife_Yellow", FormatNumber(item.Amount, 3, 5, 0), (-65 + i*35, -8), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, ALIGN_CENTER_BOTTOM, 7, true, 1, 1); DrawString(mYelFont, FormatNumber(item.Amount, 3, 5), (-72 + i*35, -8), DI_TEXT_ALIGN_RIGHT|DI_SCREEN_CENTER_BOTTOM);
++i; ++i;
} }
} }