mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-21 11:01:36 +00:00
- moved the drawing utilities to the abstact base statusbar function.
This commit is contained in:
parent
3f61ab7fbf
commit
196d3c32bb
6 changed files with 612 additions and 586 deletions
|
@ -44,6 +44,7 @@
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
|
||||||
|
|
||||||
int ListGetInt(VMVa_List &tags);
|
int ListGetInt(VMVa_List &tags);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,19 +42,24 @@
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
|
#include "v_font.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
#include "v_text.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
|
||||||
FGameTexture* CrosshairImage;
|
FGameTexture* CrosshairImage;
|
||||||
static int CrosshairNum;
|
static int CrosshairNum;
|
||||||
|
|
||||||
|
|
||||||
IMPLEMENT_CLASS(DStatusBarCore, false, false)
|
IMPLEMENT_CLASS(DStatusBarCore, true, false)
|
||||||
|
IMPLEMENT_CLASS(DHUDFont, true, false);
|
||||||
|
|
||||||
|
|
||||||
CVAR(Color, crosshaircolor, 0xff0000, CVAR_ARCHIVE);
|
CVAR(Color, crosshaircolor, 0xff0000, CVAR_ARCHIVE);
|
||||||
CVAR(Int, crosshairhealth, 1, CVAR_ARCHIVE);
|
CVAR(Int, crosshairhealth, 1, CVAR_ARCHIVE);
|
||||||
CVAR(Float, crosshairscale, 1.0, CVAR_ARCHIVE);
|
CVAR(Float, crosshairscale, 1.0, CVAR_ARCHIVE);
|
||||||
CVAR(Bool, crosshairgrow, false, CVAR_ARCHIVE);
|
CVAR(Bool, crosshairgrow, false, CVAR_ARCHIVE);
|
||||||
|
EXTERN_CVAR(Bool, vid_fps)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -228,16 +233,437 @@ void FormatNumber(int number, int minsize, int maxsize, int flags, const FString
|
||||||
else fmt.Format("%s%*d", prefix.GetChars(), minsize, number);
|
else fmt.Format("%s%*d", prefix.GetChars(), minsize, number);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, FormatNumber, FormatNumber)
|
void DStatusBarCore::ValidateResolution(int& hres, int& vres) const
|
||||||
{
|
{
|
||||||
PARAM_PROLOGUE;
|
if (hres == 0)
|
||||||
PARAM_INT(number);
|
{
|
||||||
PARAM_INT(minsize);
|
static const int HORIZONTAL_RESOLUTION_DEFAULT = 320;
|
||||||
PARAM_INT(maxsize);
|
hres = HORIZONTAL_RESOLUTION_DEFAULT;
|
||||||
PARAM_INT(flags);
|
|
||||||
PARAM_STRING(prefix);
|
|
||||||
FString fmt;
|
|
||||||
FormatNumber(number, minsize, maxsize, flags, prefix, &fmt);
|
|
||||||
ACTION_RETURN_STRING(fmt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vres == 0)
|
||||||
|
{
|
||||||
|
static const int VERTICAL_RESOLUTION_DEFAULT = 200;
|
||||||
|
vres = VERTICAL_RESOLUTION_DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// draw stuff
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void DStatusBarCore::StatusbarToRealCoords(double& x, double& y, double& w, double& h) const
|
||||||
|
{
|
||||||
|
if (SBarScale.X == -1 || ForcedScale)
|
||||||
|
{
|
||||||
|
int hres = HorizontalResolution;
|
||||||
|
int vres = VerticalResolution;
|
||||||
|
ValidateResolution(hres, vres);
|
||||||
|
|
||||||
|
VirtualToRealCoords(twod, x, y, w, h, hres, vres, true, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = ST_X + x * SBarScale.X;
|
||||||
|
y = ST_Y + y * SBarScale.Y;
|
||||||
|
w *= SBarScale.X;
|
||||||
|
h *= SBarScale.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// draw stuff
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void DStatusBarCore::DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY)
|
||||||
|
{
|
||||||
|
if (!texture.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
FGameTexture* tex = TexMan.GetGameTexture(texture, !(flags & DI_DONTANIMATE));
|
||||||
|
|
||||||
|
double texwidth = tex->GetDisplayWidth() * scaleX;
|
||||||
|
double texheight = tex->GetDisplayHeight() * scaleY;
|
||||||
|
|
||||||
|
if (boxwidth > 0 || boxheight > 0)
|
||||||
|
{
|
||||||
|
if (!(flags & DI_FORCEFILL))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
if (Alpha <= 0) return;
|
||||||
|
x += drawOffset.X;
|
||||||
|
y += drawOffset.Y;
|
||||||
|
|
||||||
|
switch (flags & DI_ITEM_HMASK)
|
||||||
|
{
|
||||||
|
case DI_ITEM_HCENTER: x -= boxwidth / 2; break;
|
||||||
|
case DI_ITEM_RIGHT: x -= boxwidth; break;
|
||||||
|
case DI_ITEM_HOFFSET: x -= tex->GetDisplayLeftOffset() * boxwidth / texwidth; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flags & DI_ITEM_VMASK)
|
||||||
|
{
|
||||||
|
case DI_ITEM_VCENTER: y -= boxheight / 2; break;
|
||||||
|
case DI_ITEM_BOTTOM: y -= boxheight; break;
|
||||||
|
case DI_ITEM_VOFFSET: y -= tex->GetDisplayTopOffset() * boxheight / texheight; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fullscreenOffsets)
|
||||||
|
{
|
||||||
|
StatusbarToRealCoords(x, y, boxwidth, boxheight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double orgx, orgy;
|
||||||
|
|
||||||
|
switch (flags & DI_SCREEN_HMASK)
|
||||||
|
{
|
||||||
|
default: orgx = 0; break;
|
||||||
|
case DI_SCREEN_HCENTER: orgx = twod->GetWidth() / 2; break;
|
||||||
|
case DI_SCREEN_RIGHT: orgx = twod->GetWidth(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flags & DI_SCREEN_VMASK)
|
||||||
|
{
|
||||||
|
default: orgy = 0; break;
|
||||||
|
case DI_SCREEN_VCENTER: orgy = twod->GetHeight() / 2; break;
|
||||||
|
case DI_SCREEN_BOTTOM: orgy = twod->GetHeight(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
x *= Scale.X;
|
||||||
|
y *= Scale.Y;
|
||||||
|
boxwidth *= Scale.X;
|
||||||
|
boxheight *= Scale.Y;
|
||||||
|
x += orgx;
|
||||||
|
y += orgy;
|
||||||
|
}
|
||||||
|
DrawTexture(twod, tex, x, y,
|
||||||
|
DTA_TopOffset, 0,
|
||||||
|
DTA_LeftOffset, 0,
|
||||||
|
DTA_DestWidthF, boxwidth,
|
||||||
|
DTA_DestHeightF, boxheight,
|
||||||
|
DTA_TranslationIndex, (flags & DI_TRANSLATABLE) ? GetTranslation() : 0,
|
||||||
|
DTA_ColorOverlay, (flags & DI_DIM) ? MAKEARGB(170, 0, 0, 0) : 0,
|
||||||
|
DTA_Alpha, Alpha,
|
||||||
|
DTA_AlphaChannel, !!(flags & DI_ALPHAMAPPED),
|
||||||
|
DTA_FillColor, (flags & DI_ALPHAMAPPED) ? 0 : -1,
|
||||||
|
DTA_FlipX, !!(flags & DI_MIRROR),
|
||||||
|
TAG_DONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// draw a string
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void DStatusBarCore::DrawString(FFont* font, const FString& cstring, double x, double y, int flags, double Alpha, int translation, int spacing, EMonospacing monospacing, int shadowX, int shadowY, double scaleX, double scaleY)
|
||||||
|
{
|
||||||
|
bool monospaced = monospacing != EMonospacing::Off;
|
||||||
|
double dx = 0;
|
||||||
|
int spacingparm = monospaced ? -spacing : spacing;
|
||||||
|
|
||||||
|
switch (flags & DI_TEXT_ALIGN)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case DI_TEXT_ALIGN_RIGHT:
|
||||||
|
dx = font->StringWidth(cstring, spacingparm);
|
||||||
|
break;
|
||||||
|
case DI_TEXT_ALIGN_CENTER:
|
||||||
|
dx = font->StringWidth(cstring, spacingparm) / 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take text scale into account
|
||||||
|
x -= dx * scaleX;
|
||||||
|
|
||||||
|
const uint8_t* str = (const uint8_t*)cstring.GetChars();
|
||||||
|
const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1);
|
||||||
|
int fontcolor = translation;
|
||||||
|
double orgx = 0, orgy = 0;
|
||||||
|
DVector2 Scale;
|
||||||
|
|
||||||
|
if (fullscreenOffsets)
|
||||||
|
{
|
||||||
|
Scale = GetHUDScale();
|
||||||
|
shadowX *= (int)Scale.X;
|
||||||
|
shadowY *= (int)Scale.Y;
|
||||||
|
|
||||||
|
switch (flags & DI_SCREEN_HMASK)
|
||||||
|
{
|
||||||
|
default: orgx = 0; break;
|
||||||
|
case DI_SCREEN_HCENTER: orgx = twod->GetWidth() / 2; break;
|
||||||
|
case DI_SCREEN_RIGHT: orgx = twod->GetWidth(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flags & DI_SCREEN_VMASK)
|
||||||
|
{
|
||||||
|
default: orgy = 0; break;
|
||||||
|
case DI_SCREEN_VCENTER: orgy = twod->GetHeight() / 2; break;
|
||||||
|
case DI_SCREEN_BOTTOM: orgy = twod->GetHeight(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
Scale = { 1.,1. };
|
||||||
|
}
|
||||||
|
int ch;
|
||||||
|
while (ch = GetCharFromString(str), ch != '\0')
|
||||||
|
{
|
||||||
|
if (ch == ' ')
|
||||||
|
{
|
||||||
|
x += monospaced ? spacing : font->GetSpaceWidth() + spacing;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (ch == TEXTCOLOR_ESCAPE)
|
||||||
|
{
|
||||||
|
EColorRange newColor = V_ParseFontColor(str, translation, boldTranslation);
|
||||||
|
if (newColor != CR_UNDEFINED)
|
||||||
|
fontcolor = newColor;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int width;
|
||||||
|
auto c = font->GetChar(ch, fontcolor, &width);
|
||||||
|
if (c == NULL) //missing character.
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!monospaced) //If we are monospaced lets use the offset
|
||||||
|
x += (c->GetDisplayLeftOffset() + 1); //ignore x offsets since we adapt to character size
|
||||||
|
|
||||||
|
double rx, ry, rw, rh;
|
||||||
|
rx = x + drawOffset.X;
|
||||||
|
ry = y + drawOffset.Y;
|
||||||
|
rw = c->GetDisplayWidth();
|
||||||
|
rh = c->GetDisplayHeight();
|
||||||
|
|
||||||
|
if (monospacing == EMonospacing::CellCenter)
|
||||||
|
rx += (spacing - rw) / 2;
|
||||||
|
else if (monospacing == EMonospacing::CellRight)
|
||||||
|
rx += (spacing - rw);
|
||||||
|
|
||||||
|
if (!fullscreenOffsets)
|
||||||
|
{
|
||||||
|
StatusbarToRealCoords(rx, ry, rw, rh);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rx *= Scale.X;
|
||||||
|
ry *= Scale.Y;
|
||||||
|
rw *= Scale.X;
|
||||||
|
rh *= Scale.Y;
|
||||||
|
|
||||||
|
rx += orgx;
|
||||||
|
ry += orgy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply text scale
|
||||||
|
rw *= scaleX;
|
||||||
|
rh *= scaleY;
|
||||||
|
|
||||||
|
// This is not really such a great way to draw shadows because they can overlap with previously drawn characters.
|
||||||
|
// This may have to be changed to draw the shadow text up front separately.
|
||||||
|
if ((shadowX != 0 || shadowY != 0) && !(flags & DI_NOSHADOW))
|
||||||
|
{
|
||||||
|
DrawChar(twod, font, CR_UNTRANSLATED, rx + shadowX, ry + shadowY, ch,
|
||||||
|
DTA_DestWidthF, rw,
|
||||||
|
DTA_DestHeightF, rh,
|
||||||
|
DTA_Alpha, (Alpha * 0.4),
|
||||||
|
DTA_FillColor, 0,
|
||||||
|
TAG_DONE);
|
||||||
|
}
|
||||||
|
DrawChar(twod, font, fontcolor, rx, ry, ch,
|
||||||
|
DTA_DestWidthF, rw,
|
||||||
|
DTA_DestHeightF, rh,
|
||||||
|
DTA_Alpha, Alpha,
|
||||||
|
TAG_DONE);
|
||||||
|
|
||||||
|
dx = monospaced
|
||||||
|
? spacing
|
||||||
|
: width + spacing - (c->GetDisplayLeftOffset() + 1);
|
||||||
|
|
||||||
|
// Take text scale into account
|
||||||
|
x += dx * scaleX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBar_DrawString(DStatusBarCore* self, DHUDFont* font, const FString& string, double x, double y, int flags, int trans, double alpha, int wrapwidth, int linespacing, double scaleX, double scaleY)
|
||||||
|
{
|
||||||
|
if (font == nullptr) ThrowAbortException(X_READ_NIL, nullptr);
|
||||||
|
if (!twod->HasBegun2D()) 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))
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
auto brk = V_BreakLines(font->mFont, int(wrapwidth * scaleX), string, true);
|
||||||
|
for (auto& line : brk)
|
||||||
|
{
|
||||||
|
self->DrawString(font->mFont, line.Text, x, y, flags, alpha, trans, font->mSpacing, font->mMonospacing, font->mShadowX, font->mShadowY, scaleX, scaleY);
|
||||||
|
y += (font->mFont->GetHeight() + linespacing) * scaleY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self->DrawString(font->mFont, string, x, y, flags, alpha, trans, font->mSpacing, font->mMonospacing, font->mShadowX, font->mShadowY, scaleX, scaleY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// draw stuff
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void DStatusBarCore::TransformRect(double& x, double& y, double& w, double& h, int flags)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
x += drawOffset.X;
|
||||||
|
y += drawOffset.Y;
|
||||||
|
|
||||||
|
if (!fullscreenOffsets)
|
||||||
|
{
|
||||||
|
StatusbarToRealCoords(x, y, w, h);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double orgx, orgy;
|
||||||
|
|
||||||
|
switch (flags & DI_SCREEN_HMASK)
|
||||||
|
{
|
||||||
|
default: orgx = 0; break;
|
||||||
|
case DI_SCREEN_HCENTER: orgx = twod->GetWidth() / 2; break;
|
||||||
|
case DI_SCREEN_RIGHT: orgx = twod->GetWidth(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flags & DI_SCREEN_VMASK)
|
||||||
|
{
|
||||||
|
default: orgy = 0; break;
|
||||||
|
case DI_SCREEN_VCENTER: orgy = twod->GetHeight() / 2; break;
|
||||||
|
case DI_SCREEN_BOTTOM: orgy = twod->GetHeight(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
x *= Scale.X;
|
||||||
|
y *= Scale.Y;
|
||||||
|
w *= Scale.X;
|
||||||
|
h *= Scale.Y;
|
||||||
|
x += orgx;
|
||||||
|
y += orgy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// draw stuff
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void DStatusBarCore::Fill(PalEntry color, double x, double y, double w, double h, int flags)
|
||||||
|
{
|
||||||
|
double Alpha = color.a * this->Alpha / 255;
|
||||||
|
if (Alpha <= 0) return;
|
||||||
|
|
||||||
|
TransformRect(x, y, w, h, flags);
|
||||||
|
|
||||||
|
int x1 = int(x);
|
||||||
|
int y1 = int(y);
|
||||||
|
int ww = int(x + w - x1); // account for scaling to non-integers. Truncating the values separately would fail for cases like
|
||||||
|
int hh = int(y + h - y1); // y=3.5, height = 5.5 where adding both values gives a larger integer than adding the two integers.
|
||||||
|
|
||||||
|
Dim(twod, color, float(Alpha), x1, y1, ww, hh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// draw stuff
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void DStatusBarCore::SetClipRect(double x, double y, double w, double h, int flags)
|
||||||
|
{
|
||||||
|
TransformRect(x, y, w, h, flags);
|
||||||
|
int x1 = int(x);
|
||||||
|
int y1 = int(y);
|
||||||
|
int ww = int(x + w - x1); // account for scaling to non-integers. Truncating the values separately would fail for cases like
|
||||||
|
int hh = int(y + h - y1); // y=3.5, height = 5.5 where adding both values gives a larger integer than adding the two integers.
|
||||||
|
twod->SetClipRect(x1, y1, ww, hh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,171 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "dobject.h"
|
#include "dobject.h"
|
||||||
|
#include "textureid.h"
|
||||||
|
#include "zstring.h"
|
||||||
|
#include "v_draw.h"
|
||||||
|
|
||||||
class FGameTexture;
|
class FGameTexture;
|
||||||
|
class FFont;
|
||||||
extern FGameTexture* CrosshairImage;
|
extern FGameTexture* CrosshairImage;
|
||||||
void ST_LoadCrosshair(int num, bool alwaysload);
|
void ST_LoadCrosshair(int num, bool alwaysload);
|
||||||
void ST_UnloadCrosshair();
|
void ST_UnloadCrosshair();
|
||||||
void ST_DrawCrosshair(int phealth, double xpos, double ypos, double scale);
|
void ST_DrawCrosshair(int phealth, double xpos, double ypos, double scale);
|
||||||
|
|
||||||
|
|
||||||
|
enum DI_Flags
|
||||||
|
{
|
||||||
|
DI_SKIPICON = 0x1,
|
||||||
|
DI_SKIPALTICON = 0x2,
|
||||||
|
DI_SKIPSPAWN = 0x4,
|
||||||
|
DI_SKIPREADY = 0x8,
|
||||||
|
DI_ALTICONFIRST = 0x10,
|
||||||
|
DI_TRANSLATABLE = 0x20,
|
||||||
|
DI_FORCESCALE = 0x40,
|
||||||
|
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
|
||||||
|
DI_MIRROR = 0x1000, // flip the texture horizontally, like a mirror
|
||||||
|
|
||||||
|
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,
|
||||||
|
DI_NOSHADOW = 0x4000000,
|
||||||
|
DI_ALWAYSSHOWCOUNTERS = 0x8000000,
|
||||||
|
DI_ARTIFLASH = 0x10000000,
|
||||||
|
DI_FORCEFILL = 0x20000000,
|
||||||
|
|
||||||
|
// These 2 flags are only used by SBARINFO so these duplicate other flags not used by SBARINFO
|
||||||
|
DI_DRAWINBOX = DI_TEXT_ALIGN_RIGHT,
|
||||||
|
DI_ALTERNATEONFAIL = DI_TEXT_ALIGN_CENTER,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// encapsulates all settings a HUD font may need
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
class DHUDFont : public DObject
|
||||||
|
{
|
||||||
|
// this blocks CreateNew on this class which is the intent here.
|
||||||
|
DECLARE_ABSTRACT_CLASS(DHUDFont, DObject);
|
||||||
|
|
||||||
|
public:
|
||||||
|
FFont* mFont;
|
||||||
|
int mSpacing;
|
||||||
|
EMonospacing mMonospacing;
|
||||||
|
int mShadowX;
|
||||||
|
int mShadowY;
|
||||||
|
|
||||||
|
DHUDFont(FFont* f, int sp, EMonospacing ms, int sx, int sy)
|
||||||
|
: mFont(f), mSpacing(sp), mMonospacing(ms), mShadowX(sx), mShadowY(sy)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DStatusBarCore : public DObject
|
class DStatusBarCore : public DObject
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(DStatusBarCore, DObject)
|
DECLARE_CLASS(DStatusBarCore, DObject)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum EAlign
|
||||||
|
{
|
||||||
|
TOP = 0,
|
||||||
|
VCENTER = 1,
|
||||||
|
BOTTOM = 2,
|
||||||
|
VOFFSET = 3,
|
||||||
|
VMASK = 3,
|
||||||
|
|
||||||
|
LEFT = 0,
|
||||||
|
HCENTER = 4,
|
||||||
|
RIGHT = 8,
|
||||||
|
HOFFSET = 12,
|
||||||
|
HMASK = 12,
|
||||||
|
|
||||||
|
CENTER = VCENTER | HCENTER,
|
||||||
|
CENTER_BOTTOM = BOTTOM | HCENTER
|
||||||
|
};
|
||||||
|
|
||||||
|
int ST_X;
|
||||||
|
int ST_Y;
|
||||||
|
int SBarTop;
|
||||||
|
DVector2 SBarScale;
|
||||||
|
int RelTop;
|
||||||
|
int HorizontalResolution, VerticalResolution;
|
||||||
|
double Alpha = 1.;
|
||||||
|
DVector2 drawOffset = { 0,0 }; // can be set by subclasses to offset drawing operations
|
||||||
|
double drawClip[4] = { 0,0,0,0 }; // defines a clipping rectangle (not used yet)
|
||||||
|
bool fullscreenOffsets = false; // current screen is displayed with fullscreen behavior.
|
||||||
|
bool ForcedScale = false;
|
||||||
|
|
||||||
|
|
||||||
|
virtual DVector2 GetHUDScale() const = 0;
|
||||||
|
virtual uint32_t GetTranslation() const { return 0; }
|
||||||
|
void ValidateResolution(int& hres, int& vres) const;
|
||||||
|
void StatusbarToRealCoords(double& x, double& y, double& w, double& h) const;
|
||||||
|
void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY);
|
||||||
|
void DrawString(FFont* font, const FString& cstring, double x, double y, int flags, double Alpha, int translation, int spacing, EMonospacing monospacing, int shadowX, int shadowY, double scaleX, double scaleY);
|
||||||
|
void TransformRect(double& x, double& y, double& w, double& h, int flags = 0);
|
||||||
|
void Fill(PalEntry color, double x, double y, double w, double h, int flags = 0);
|
||||||
|
void SetClipRect(double x, double y, double w, double h, int flags = 0);
|
||||||
|
|
||||||
};
|
};
|
|
@ -332,30 +332,6 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// encapsulates all settings a HUD font may need
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
class DHUDFont : public DObject
|
|
||||||
{
|
|
||||||
// this blocks CreateNew on this class which is the intent here.
|
|
||||||
DECLARE_ABSTRACT_CLASS(DHUDFont, DObject);
|
|
||||||
|
|
||||||
public:
|
|
||||||
FFont *mFont;
|
|
||||||
int mSpacing;
|
|
||||||
EMonospacing mMonospacing;
|
|
||||||
int mShadowX;
|
|
||||||
int mShadowY;
|
|
||||||
|
|
||||||
DHUDFont(FFont *f, int sp, EMonospacing ms, int sx, int sy)
|
|
||||||
: mFont(f), mSpacing(sp), mMonospacing(ms), mShadowX(sx), mShadowY(sy)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class DBaseStatusBar : public DStatusBarCore
|
class DBaseStatusBar : public DStatusBarCore
|
||||||
{
|
{
|
||||||
friend class DSBarInfo;
|
friend class DSBarInfo;
|
||||||
|
@ -392,24 +368,6 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum EAlign
|
|
||||||
{
|
|
||||||
TOP = 0,
|
|
||||||
VCENTER = 1,
|
|
||||||
BOTTOM = 2,
|
|
||||||
VOFFSET = 3,
|
|
||||||
VMASK = 3,
|
|
||||||
|
|
||||||
LEFT = 0,
|
|
||||||
HCENTER = 4,
|
|
||||||
RIGHT = 8,
|
|
||||||
HOFFSET = 12,
|
|
||||||
HMASK = 12,
|
|
||||||
|
|
||||||
CENTER = VCENTER | HCENTER,
|
|
||||||
CENTER_BOTTOM = BOTTOM | HCENTER
|
|
||||||
};
|
|
||||||
|
|
||||||
DBaseStatusBar ();
|
DBaseStatusBar ();
|
||||||
void SetSize(int reltop = 32, int hres = 320, int vres = 200, int hhres = -1, int hvres = -1);
|
void SetSize(int reltop = 32, int hres = 320, int vres = 200, int hhres = -1, int hvres = -1);
|
||||||
void OnDestroy() override;
|
void OnDestroy() override;
|
||||||
|
@ -435,7 +393,7 @@ public:
|
||||||
void DrawBottomStuff (EHudState state);
|
void DrawBottomStuff (EHudState state);
|
||||||
void DrawTopStuff (EHudState state);
|
void DrawTopStuff (EHudState state);
|
||||||
void AttachToPlayer(player_t *player);
|
void AttachToPlayer(player_t *player);
|
||||||
DVector2 GetHUDScale() const;
|
DVector2 GetHUDScale() const override;
|
||||||
virtual void FlashCrosshair ();
|
virtual void FlashCrosshair ();
|
||||||
void NewGame ();
|
void NewGame ();
|
||||||
virtual void ScreenSizeChanged ();
|
virtual void ScreenSizeChanged ();
|
||||||
|
@ -444,21 +402,14 @@ public:
|
||||||
virtual bool MustDrawLog(EHudState state);
|
virtual bool MustDrawLog(EHudState state);
|
||||||
virtual void SetMugShotState (const char *state_name, bool wait_till_done=false, bool reset=false);
|
virtual void SetMugShotState (const char *state_name, bool wait_till_done=false, bool reset=false);
|
||||||
void DrawLog();
|
void DrawLog();
|
||||||
uint32_t GetTranslation() const;
|
uint32_t GetTranslation() const override;
|
||||||
|
|
||||||
void CreateAltHUD();
|
void CreateAltHUD();
|
||||||
void DrawAltHUD();
|
void DrawAltHUD();
|
||||||
|
|
||||||
void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY);
|
|
||||||
void DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, EMonospacing monospacing, int shadowX, int shadowY, double scaleX, double scaleY);
|
|
||||||
void TransformRect(double &x, double &y, double &w, double &h, int flags = 0);
|
|
||||||
void Fill(PalEntry color, double x, double y, double w, double h, int flags = 0);
|
|
||||||
void SetClipRect(double x, double y, double w, double h, int flags = 0);
|
|
||||||
|
|
||||||
void BeginStatusBar(int resW, int resH, int relTop, bool forceScaled);
|
void BeginStatusBar(int resW, int resH, int relTop, bool forceScaled);
|
||||||
void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false);
|
void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false);
|
||||||
bool ForceHUDScale(bool on) { std::swap(ForcedScale, on); return on; } // This is for SBARINFO which should not use BeginStatusBar or BeginHUD.
|
bool ForceHUDScale(bool on) { std::swap(ForcedScale, on); return on; } // This is for SBARINFO which should not use BeginStatusBar or BeginHUD.
|
||||||
void StatusbarToRealCoords(double &x, double &y, double &w, double &h) const;
|
|
||||||
int GetTopOfStatusbar() const
|
int GetTopOfStatusbar() const
|
||||||
{
|
{
|
||||||
return SBarTop;
|
return SBarTop;
|
||||||
|
@ -481,15 +432,8 @@ public:
|
||||||
void DrawCrosshair ();
|
void DrawCrosshair ();
|
||||||
|
|
||||||
// Sizing info for ths status bar.
|
// Sizing info for ths status bar.
|
||||||
int ST_X;
|
|
||||||
int ST_Y;
|
|
||||||
int SBarTop;
|
|
||||||
DVector2 SBarScale;
|
|
||||||
int RelTop;
|
|
||||||
int HorizontalResolution, VerticalResolution;
|
|
||||||
bool Scaled; // This needs to go away.
|
bool Scaled; // This needs to go away.
|
||||||
DVector2 defaultScale; // factor for fully scaled fullscreen display.
|
DVector2 defaultScale; // factor for fully scaled fullscreen display.
|
||||||
bool ForcedScale = false;
|
|
||||||
|
|
||||||
bool Centering;
|
bool Centering;
|
||||||
bool FixedOrigin;
|
bool FixedOrigin;
|
||||||
|
@ -502,10 +446,6 @@ public:
|
||||||
|
|
||||||
player_t *CPlayer;
|
player_t *CPlayer;
|
||||||
|
|
||||||
double Alpha = 1.;
|
|
||||||
DVector2 drawOffset = { 0,0 }; // can be set by subclasses to offset drawing operations
|
|
||||||
double drawClip[4] = { 0,0,0,0 }; // defines a clipping rectangle (not used yet)
|
|
||||||
bool fullscreenOffsets = false; // current screen is displayed with fullscreen behavior.
|
|
||||||
FMugShot mugshot;
|
FMugShot mugshot;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -544,82 +484,4 @@ void C_MidPrint(FFont* font, const char* message, bool bold = false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum DI_Flags
|
|
||||||
{
|
|
||||||
DI_SKIPICON = 0x1,
|
|
||||||
DI_SKIPALTICON = 0x2,
|
|
||||||
DI_SKIPSPAWN = 0x4,
|
|
||||||
DI_SKIPREADY = 0x8,
|
|
||||||
DI_ALTICONFIRST = 0x10,
|
|
||||||
DI_TRANSLATABLE = 0x20,
|
|
||||||
DI_FORCESCALE = 0x40,
|
|
||||||
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
|
|
||||||
DI_MIRROR = 0x1000, // flip the texture horizontally, like a mirror
|
|
||||||
|
|
||||||
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,
|
|
||||||
DI_NOSHADOW = 0x4000000,
|
|
||||||
DI_ALWAYSSHOWCOUNTERS = 0x8000000,
|
|
||||||
DI_ARTIFLASH = 0x10000000,
|
|
||||||
DI_FORCEFILL = 0x20000000,
|
|
||||||
|
|
||||||
// These 2 flags are only used by SBARINFO so these duplicate other flags not used by SBARINFO
|
|
||||||
DI_DRAWINBOX = DI_TEXT_ALIGN_RIGHT,
|
|
||||||
DI_ALTERNATEONFAIL = DI_TEXT_ALIGN_CENTER,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* __SBAR_H__ */
|
#endif /* __SBAR_H__ */
|
||||||
|
|
|
@ -71,7 +71,6 @@
|
||||||
#define XHAIRPICKUPSIZE (2+XHAIRSHRINKSIZE)
|
#define XHAIRPICKUPSIZE (2+XHAIRSHRINKSIZE)
|
||||||
#define POWERUPICONSIZE 32
|
#define POWERUPICONSIZE 32
|
||||||
|
|
||||||
IMPLEMENT_CLASS(DHUDFont, true, false);
|
|
||||||
IMPLEMENT_CLASS(DBaseStatusBar, false, true)
|
IMPLEMENT_CLASS(DBaseStatusBar, false, true)
|
||||||
|
|
||||||
IMPLEMENT_POINTERS_START(DBaseStatusBar)
|
IMPLEMENT_POINTERS_START(DBaseStatusBar)
|
||||||
|
@ -401,21 +400,6 @@ DBaseStatusBar::DBaseStatusBar ()
|
||||||
CreateAltHUD();
|
CreateAltHUD();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ValidateResolution(int &hres, int &vres)
|
|
||||||
{
|
|
||||||
if (hres == 0)
|
|
||||||
{
|
|
||||||
static const int HORIZONTAL_RESOLUTION_DEFAULT = 320;
|
|
||||||
hres = HORIZONTAL_RESOLUTION_DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vres == 0)
|
|
||||||
{
|
|
||||||
static const int VERTICAL_RESOLUTION_DEFAULT = 200;
|
|
||||||
vres = VERTICAL_RESOLUTION_DEFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DBaseStatusBar::SetSize(int reltop, int hres, int vres, int hhres, int hvres)
|
void DBaseStatusBar::SetSize(int reltop, int hres, int vres, int hhres, int hvres)
|
||||||
{
|
{
|
||||||
ValidateResolution(hres, vres);
|
ValidateResolution(hres, vres);
|
||||||
|
@ -1494,424 +1478,6 @@ uint32_t DBaseStatusBar::GetTranslation() const
|
||||||
return TRANSLATION(TRANSLATION_Players, int(CPlayer - players));
|
return TRANSLATION(TRANSLATION_Players, int(CPlayer - players));
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// draw stuff
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
void DBaseStatusBar::StatusbarToRealCoords(double &x, double &y, double &w, double &h) const
|
|
||||||
{
|
|
||||||
if (SBarScale.X == -1 || ForcedScale)
|
|
||||||
{
|
|
||||||
int hres = HorizontalResolution;
|
|
||||||
int vres = VerticalResolution;
|
|
||||||
ValidateResolution(hres, vres);
|
|
||||||
|
|
||||||
VirtualToRealCoords(twod, x, y, w, h, hres, vres, true, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x = ST_X + x * SBarScale.X;
|
|
||||||
y = ST_Y + y * SBarScale.Y;
|
|
||||||
w *= SBarScale.X;
|
|
||||||
h *= SBarScale.Y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// draw stuff
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY)
|
|
||||||
{
|
|
||||||
if (!texture.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
FGameTexture *tex = TexMan.GetGameTexture(texture, !(flags & DI_DONTANIMATE));
|
|
||||||
|
|
||||||
double texwidth = tex->GetDisplayWidth() * scaleX;
|
|
||||||
double texheight = tex->GetDisplayHeight() * scaleY;
|
|
||||||
|
|
||||||
if (boxwidth > 0 || boxheight > 0)
|
|
||||||
{
|
|
||||||
if (!(flags & DI_FORCEFILL))
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
if (Alpha <= 0) return;
|
|
||||||
x += drawOffset.X;
|
|
||||||
y += drawOffset.Y;
|
|
||||||
|
|
||||||
switch (flags & DI_ITEM_HMASK)
|
|
||||||
{
|
|
||||||
case DI_ITEM_HCENTER: x -= boxwidth / 2; break;
|
|
||||||
case DI_ITEM_RIGHT: x -= boxwidth; break;
|
|
||||||
case DI_ITEM_HOFFSET: x -= tex->GetDisplayLeftOffset() * boxwidth / texwidth; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flags & DI_ITEM_VMASK)
|
|
||||||
{
|
|
||||||
case DI_ITEM_VCENTER: y -= boxheight / 2; break;
|
|
||||||
case DI_ITEM_BOTTOM: y -= boxheight; break;
|
|
||||||
case DI_ITEM_VOFFSET: y -= tex->GetDisplayTopOffset() * boxheight / texheight; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fullscreenOffsets)
|
|
||||||
{
|
|
||||||
StatusbarToRealCoords(x, y, boxwidth, boxheight);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double orgx, orgy;
|
|
||||||
|
|
||||||
switch (flags & DI_SCREEN_HMASK)
|
|
||||||
{
|
|
||||||
default: orgx = 0; break;
|
|
||||||
case DI_SCREEN_HCENTER: orgx = twod->GetWidth() / 2; break;
|
|
||||||
case DI_SCREEN_RIGHT: orgx = twod->GetWidth(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flags & DI_SCREEN_VMASK)
|
|
||||||
{
|
|
||||||
default: orgy = 0; break;
|
|
||||||
case DI_SCREEN_VCENTER: orgy = twod->GetHeight() / 2; break;
|
|
||||||
case DI_SCREEN_BOTTOM: orgy = twod->GetHeight(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
x *= Scale.X;
|
|
||||||
y *= Scale.Y;
|
|
||||||
boxwidth *= Scale.X;
|
|
||||||
boxheight *= Scale.Y;
|
|
||||||
x += orgx;
|
|
||||||
y += orgy;
|
|
||||||
}
|
|
||||||
DrawTexture(twod, tex, x, y,
|
|
||||||
DTA_TopOffset, 0,
|
|
||||||
DTA_LeftOffset, 0,
|
|
||||||
DTA_DestWidthF, boxwidth,
|
|
||||||
DTA_DestHeightF, boxheight,
|
|
||||||
DTA_TranslationIndex, (flags & DI_TRANSLATABLE) ? GetTranslation() : 0,
|
|
||||||
DTA_ColorOverlay, (flags & DI_DIM) ? MAKEARGB(170, 0, 0, 0) : 0,
|
|
||||||
DTA_Alpha, Alpha,
|
|
||||||
DTA_AlphaChannel, !!(flags & DI_ALPHAMAPPED),
|
|
||||||
DTA_FillColor, (flags & DI_ALPHAMAPPED) ? 0 : -1,
|
|
||||||
DTA_FlipX, !!(flags & DI_MIRROR),
|
|
||||||
TAG_DONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// draw a string
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, EMonospacing monospacing, int shadowX, int shadowY, double scaleX, double scaleY)
|
|
||||||
{
|
|
||||||
bool monospaced = monospacing != EMonospacing::Off;
|
|
||||||
double dx = 0;
|
|
||||||
int spacingparm = monospaced ? -spacing : spacing;
|
|
||||||
|
|
||||||
switch (flags & DI_TEXT_ALIGN)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
case DI_TEXT_ALIGN_RIGHT:
|
|
||||||
dx = font->StringWidth(cstring, spacingparm);
|
|
||||||
break;
|
|
||||||
case DI_TEXT_ALIGN_CENTER:
|
|
||||||
dx = font->StringWidth(cstring, spacingparm) / 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take text scale into account
|
|
||||||
x -= dx * scaleX;
|
|
||||||
|
|
||||||
const uint8_t* str = (const uint8_t*)cstring.GetChars();
|
|
||||||
const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1);
|
|
||||||
int fontcolor = translation;
|
|
||||||
double orgx = 0, orgy = 0;
|
|
||||||
DVector2 Scale;
|
|
||||||
|
|
||||||
if (fullscreenOffsets)
|
|
||||||
{
|
|
||||||
Scale = GetHUDScale();
|
|
||||||
shadowX *= (int)Scale.X;
|
|
||||||
shadowY *= (int)Scale.Y;
|
|
||||||
|
|
||||||
switch (flags & DI_SCREEN_HMASK)
|
|
||||||
{
|
|
||||||
default: orgx = 0; break;
|
|
||||||
case DI_SCREEN_HCENTER: orgx = twod->GetWidth() / 2; break;
|
|
||||||
case DI_SCREEN_RIGHT: orgx = twod->GetWidth(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flags & DI_SCREEN_VMASK)
|
|
||||||
{
|
|
||||||
default: orgy = 0; break;
|
|
||||||
case DI_SCREEN_VCENTER: orgy = twod->GetHeight() / 2; break;
|
|
||||||
case DI_SCREEN_BOTTOM: orgy = twod->GetHeight(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
{
|
|
||||||
Scale = { 1.,1. };
|
|
||||||
}
|
|
||||||
int ch;
|
|
||||||
while (ch = GetCharFromString(str), ch != '\0')
|
|
||||||
{
|
|
||||||
if (ch == ' ')
|
|
||||||
{
|
|
||||||
x += monospaced ? spacing : font->GetSpaceWidth() + spacing;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (ch == TEXTCOLOR_ESCAPE)
|
|
||||||
{
|
|
||||||
EColorRange newColor = V_ParseFontColor(str, translation, boldTranslation);
|
|
||||||
if (newColor != CR_UNDEFINED)
|
|
||||||
fontcolor = newColor;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int width;
|
|
||||||
auto c = font->GetChar(ch, fontcolor, &width);
|
|
||||||
if (c == NULL) //missing character.
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!monospaced) //If we are monospaced lets use the offset
|
|
||||||
x += (c->GetDisplayLeftOffset() + 1); //ignore x offsets since we adapt to character size
|
|
||||||
|
|
||||||
double rx, ry, rw, rh;
|
|
||||||
rx = x + drawOffset.X;
|
|
||||||
ry = y + drawOffset.Y;
|
|
||||||
rw = c->GetDisplayWidth();
|
|
||||||
rh = c->GetDisplayHeight();
|
|
||||||
|
|
||||||
if (monospacing == EMonospacing::CellCenter)
|
|
||||||
rx += (spacing - rw) / 2;
|
|
||||||
else if (monospacing == EMonospacing::CellRight)
|
|
||||||
rx += (spacing - rw);
|
|
||||||
|
|
||||||
if (!fullscreenOffsets)
|
|
||||||
{
|
|
||||||
StatusbarToRealCoords(rx, ry, rw, rh);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rx *= Scale.X;
|
|
||||||
ry *= Scale.Y;
|
|
||||||
rw *= Scale.X;
|
|
||||||
rh *= Scale.Y;
|
|
||||||
|
|
||||||
rx += orgx;
|
|
||||||
ry += orgy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply text scale
|
|
||||||
rw *= scaleX;
|
|
||||||
rh *= scaleY;
|
|
||||||
|
|
||||||
// This is not really such a great way to draw shadows because they can overlap with previously drawn characters.
|
|
||||||
// This may have to be changed to draw the shadow text up front separately.
|
|
||||||
if ((shadowX != 0 || shadowY != 0) && !(flags & DI_NOSHADOW))
|
|
||||||
{
|
|
||||||
DrawChar(twod, font, CR_UNTRANSLATED, rx + shadowX, ry + shadowY, ch,
|
|
||||||
DTA_DestWidthF, rw,
|
|
||||||
DTA_DestHeightF, rh,
|
|
||||||
DTA_Alpha, (Alpha * HR_SHADOW),
|
|
||||||
DTA_FillColor, 0,
|
|
||||||
TAG_DONE);
|
|
||||||
}
|
|
||||||
DrawChar(twod, font, fontcolor, rx, ry, ch,
|
|
||||||
DTA_DestWidthF, rw,
|
|
||||||
DTA_DestHeightF, rh,
|
|
||||||
DTA_Alpha, Alpha,
|
|
||||||
TAG_DONE);
|
|
||||||
|
|
||||||
dx = monospaced
|
|
||||||
? spacing
|
|
||||||
: width + spacing - (c->GetDisplayLeftOffset() + 1);
|
|
||||||
|
|
||||||
// Take text scale into account
|
|
||||||
x += dx * scaleX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SBar_DrawString(DBaseStatusBar *self, DHUDFont *font, const FString &string, double x, double y, int flags, int trans, double alpha, int wrapwidth, int linespacing, double scaleX, double scaleY)
|
|
||||||
{
|
|
||||||
if (font == nullptr) ThrowAbortException(X_READ_NIL, nullptr);
|
|
||||||
if (!twod->HasBegun2D()) 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))
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
auto brk = V_BreakLines(font->mFont, int(wrapwidth * scaleX), string, true);
|
|
||||||
for (auto &line : brk)
|
|
||||||
{
|
|
||||||
self->DrawString(font->mFont, line.Text, x, y, flags, alpha, trans, font->mSpacing, font->mMonospacing, font->mShadowX, font->mShadowY, scaleX, scaleY);
|
|
||||||
y += (font->mFont->GetHeight() + linespacing) * scaleY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self->DrawString(font->mFont, string, x, y, flags, alpha, trans, font->mSpacing, font->mMonospacing, font->mShadowX, font->mShadowY, scaleX, scaleY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// draw stuff
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
void DBaseStatusBar::TransformRect(double &x, double &y, double &w, double &h, int flags)
|
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
x += drawOffset.X;
|
|
||||||
y += drawOffset.Y;
|
|
||||||
|
|
||||||
if (!fullscreenOffsets)
|
|
||||||
{
|
|
||||||
StatusbarToRealCoords(x, y, w, h);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double orgx, orgy;
|
|
||||||
|
|
||||||
switch (flags & DI_SCREEN_HMASK)
|
|
||||||
{
|
|
||||||
default: orgx = 0; break;
|
|
||||||
case DI_SCREEN_HCENTER: orgx = twod->GetWidth() / 2; break;
|
|
||||||
case DI_SCREEN_RIGHT: orgx = twod->GetWidth(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flags & DI_SCREEN_VMASK)
|
|
||||||
{
|
|
||||||
default: orgy = 0; break;
|
|
||||||
case DI_SCREEN_VCENTER: orgy = twod->GetHeight() / 2; break;
|
|
||||||
case DI_SCREEN_BOTTOM: orgy = twod->GetHeight(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
x *= Scale.X;
|
|
||||||
y *= Scale.Y;
|
|
||||||
w *= Scale.X;
|
|
||||||
h *= Scale.Y;
|
|
||||||
x += orgx;
|
|
||||||
y += orgy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// draw stuff
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
void DBaseStatusBar::Fill(PalEntry color, double x, double y, double w, double h, int flags)
|
|
||||||
{
|
|
||||||
double Alpha = color.a * this->Alpha / 255;
|
|
||||||
if (Alpha <= 0) return;
|
|
||||||
|
|
||||||
TransformRect(x, y, w, h, flags);
|
|
||||||
|
|
||||||
int x1 = int(x);
|
|
||||||
int y1 = int(y);
|
|
||||||
int ww = int(x + w - x1); // account for scaling to non-integers. Truncating the values separately would fail for cases like
|
|
||||||
int hh = int(y + h - y1); // y=3.5, height = 5.5 where adding both values gives a larger integer than adding the two integers.
|
|
||||||
|
|
||||||
Dim(twod, color, float(Alpha), x1, y1, ww, hh);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// draw stuff
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
void DBaseStatusBar::SetClipRect(double x, double y, double w, double h, int flags)
|
|
||||||
{
|
|
||||||
TransformRect(x, y, w, h, flags);
|
|
||||||
int x1 = int(x);
|
|
||||||
int y1 = int(y);
|
|
||||||
int ww = int(x + w - x1); // account for scaling to non-integers. Truncating the values separately would fail for cases like
|
|
||||||
int hh = int(y + h - y1); // y=3.5, height = 5.5 where adding both values gives a larger integer than adding the two integers.
|
|
||||||
twod->SetClipRect(x1, y1, ww, hh);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// CCMD showpop
|
// CCMD showpop
|
||||||
|
|
|
@ -2160,7 +2160,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, DrawImage, SBar_DrawImage)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBar_DrawString(DBaseStatusBar *self, DHUDFont *font, const FString &string, double x, double y, int flags, int trans, double alpha, int wrapwidth, int linespacing, double scaleX, double scaleY);
|
void SBar_DrawString(DStatusBarCore *self, DHUDFont *font, const FString &string, double x, double y, int flags, int trans, double alpha, int wrapwidth, int linespacing, double scaleX, double scaleY);
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, DrawString, SBar_DrawString)
|
DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, DrawString, SBar_DrawString)
|
||||||
{
|
{
|
||||||
|
@ -2241,6 +2241,22 @@ DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, SetClipRect, SBar_SetClipRect)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FormatNumber(int number, int minsize, int maxsize, int flags, const FString& prefix, FString* result);
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, FormatNumber, FormatNumber)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_INT(number);
|
||||||
|
PARAM_INT(minsize);
|
||||||
|
PARAM_INT(maxsize);
|
||||||
|
PARAM_INT(flags);
|
||||||
|
PARAM_STRING(prefix);
|
||||||
|
FString fmt;
|
||||||
|
FormatNumber(number, minsize, maxsize, flags, prefix, &fmt);
|
||||||
|
ACTION_RETURN_STRING(fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void GetGlobalACSString(int index, FString *result)
|
static void GetGlobalACSString(int index, FString *result)
|
||||||
{
|
{
|
||||||
*result = primaryLevel->Behaviors.LookupString(ACS_GlobalVars[index]);
|
*result = primaryLevel->Behaviors.LookupString(ACS_GlobalVars[index]);
|
||||||
|
|
Loading…
Reference in a new issue