- Status bar draw code is now identical with GZDoom's.

This commit is contained in:
Christoph Oelckers 2020-10-28 17:02:40 +01:00
parent 3a0c84d3ca
commit 37024df405
3 changed files with 94 additions and 37 deletions

View file

@ -264,8 +264,7 @@ 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);
} }
void DStatusBarCore::ValidateResolution(int& hres, int& vres) const
void ValidateResolution(int &hres, int &vres)
{ {
if (hres == 0) if (hres == 0)
{ {
@ -287,12 +286,23 @@ void ValidateResolution(int &hres, int &vres)
// //
//============================================================================ //============================================================================
void DStatusBarCore::StatusbarToRealCoords(double &x, double &y, double &w, double &h) const 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; x = ST_X + x * SBarScale.X;
y = ST_Y + y * SBarScale.Y; y = ST_Y + y * SBarScale.Y;
w *= SBarScale.X; w *= SBarScale.X;
h *= SBarScale.Y; h *= SBarScale.Y;
}
} }
//============================================================================ //============================================================================
@ -314,6 +324,9 @@ void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flag
{ {
double texwidth = tex->GetDisplayWidth() * scaleX; double texwidth = tex->GetDisplayWidth() * scaleX;
double texheight = tex->GetDisplayHeight() * scaleY; double texheight = tex->GetDisplayHeight() * scaleY;
double texleftoffs = tex->GetDisplayLeftOffset() * scaleY;
double textopoffs = tex->GetDisplayTopOffset() * scaleY;
double boxleftoffs, boxtopoffs;
if (boxwidth > 0 || boxheight > 0) if (boxwidth > 0 || boxheight > 0)
{ {
@ -339,12 +352,16 @@ void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flag
boxwidth = texwidth * scale1; boxwidth = texwidth * scale1;
boxheight = texheight * scale1; boxheight = texheight * scale1;
boxleftoffs = texleftoffs * scale1;
boxtopoffs = textopoffs * scale1;
} }
} }
else else
{ {
boxwidth = texwidth; boxwidth = texwidth;
boxheight = texheight; boxheight = texheight;
boxleftoffs = texleftoffs;
boxtopoffs = textopoffs;
} }
// resolve auto-alignment before making any adjustments to the position values. // resolve auto-alignment before making any adjustments to the position values.
@ -361,26 +378,27 @@ void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flag
x += drawOffset.X; x += drawOffset.X;
y += drawOffset.Y; y += drawOffset.Y;
double xo = 0, yo = 0;
if (flags & DI_ITEM_RELCENTER) if (flags & DI_ITEM_RELCENTER)
{ {
xo = tex->GetDisplayWidth() / 2 + tex->GetDisplayLeftOffset(); if (flags & DI_MIRROR) boxleftoffs = -boxleftoffs;
yo = tex->GetDisplayHeight() / 2 + tex->GetDisplayTopOffset(); if (flags & DI_MIRRORY) boxtopoffs = -boxtopoffs;
x -= boxwidth / 2 + boxleftoffs;
y -= boxheight / 2 + boxtopoffs;
} }
else else
{ {
switch (flags & DI_ITEM_HMASK) switch (flags & DI_ITEM_HMASK)
{ {
case DI_ITEM_HCENTER: xo = tex->GetDisplayWidth() / 2; break; case DI_ITEM_HCENTER: x -= boxwidth / 2; break;
case DI_ITEM_RIGHT: xo = tex->GetDisplayWidth(); break; case DI_ITEM_RIGHT: x -= boxwidth; break;
case DI_ITEM_HOFFSET: xo = tex->GetDisplayLeftOffset(); break; case DI_ITEM_HOFFSET: x -= boxleftoffs; break;
} }
switch (flags & DI_ITEM_VMASK) switch (flags & DI_ITEM_VMASK)
{ {
case DI_ITEM_VCENTER: yo = tex->GetDisplayHeight() / 2; break; case DI_ITEM_VCENTER: y -= boxheight / 2; break;
case DI_ITEM_BOTTOM: yo = tex->GetDisplayHeight(); break; case DI_ITEM_BOTTOM: y -= boxheight; break;
case DI_ITEM_VOFFSET: yo = tex->GetDisplayTopOffset(); break; case DI_ITEM_VOFFSET: y -= boxtopoffs; break;
} }
} }
@ -418,14 +436,13 @@ void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flag
x += orgx; x += orgx;
y += orgy; y += orgy;
} }
// Now reapply the texture offsets. We will need them
DrawTexture(twod, tex, x, y, DrawTexture(twod, tex, x, y,
DTA_TopOffsetF, yo, DTA_TopOffset, 0,
DTA_LeftOffsetF, xo, DTA_LeftOffset, 0,
DTA_DestWidthF, boxwidth, DTA_DestWidthF, boxwidth,
DTA_DestHeightF, boxheight, DTA_DestHeightF, boxheight,
DTA_Color, color, DTA_Color, color,
DTA_TranslationIndex, translation, // (flags & DI_TRANSLATABLE) ? GetTranslation() : 0, DTA_TranslationIndex, translation? translation : (flags & DI_TRANSLATABLE) ? GetTranslation() : 0,
DTA_ColorOverlay, (flags & DI_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, !!(flags & DI_ALPHAMAPPED), DTA_AlphaChannel, !!(flags & DI_ALPHAMAPPED),
@ -433,7 +450,6 @@ void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flag
DTA_FlipX, !!(flags & DI_MIRROR), DTA_FlipX, !!(flags & DI_MIRROR),
DTA_FlipY, !!(flags& DI_MIRRORY), DTA_FlipY, !!(flags& DI_MIRRORY),
DTA_Rotate, rotate, DTA_Rotate, rotate,
DTA_FlipOffsets, true,
DTA_LegacyRenderStyle, style, DTA_LegacyRenderStyle, style,
TAG_DONE); TAG_DONE);
} }
@ -445,24 +461,21 @@ void DStatusBarCore::DrawGraphic(FGameTexture* tex, double x, double y, int flag
// //
//============================================================================ //============================================================================
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) 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; bool monospaced = monospacing != EMonospacing::Off;
double dx = 0; double dx = 0;
int spacingparm = monospaced ? -spacing : spacing;
switch (flags & DI_TEXT_ALIGN) switch (flags & DI_TEXT_ALIGN)
{ {
default: default:
break; break;
case DI_TEXT_ALIGN_RIGHT: case DI_TEXT_ALIGN_RIGHT:
dx = monospaced dx = font->StringWidth(cstring, spacingparm);
? static_cast<int> ((spacing)*cstring.CharacterCount()) //monospaced, so just multiply the character size
: static_cast<int> (font->StringWidth(cstring) + (spacing * cstring.CharacterCount()));
break; break;
case DI_TEXT_ALIGN_CENTER: case DI_TEXT_ALIGN_CENTER:
dx = monospaced dx = font->StringWidth(cstring, spacingparm) / 2;
? static_cast<int> ((spacing)*cstring.CharacterCount()) / 2 //monospaced, so just multiply the character size
: static_cast<int> (font->StringWidth(cstring) + (spacing * cstring.CharacterCount())) / 2;
break; break;
} }
@ -585,10 +598,10 @@ void DStatusBarCore::DrawString(FFont *font, const FString &cstring, double x, d
} }
} }
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) 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 (font == nullptr) ThrowAbortException(X_READ_NIL, nullptr);
//if (!screen->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); 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. // resolve auto-alignment before making any adjustments to the position values.
if (!(flags & DI_SCREEN_MANUAL_ALIGN)) if (!(flags & DI_SCREEN_MANUAL_ALIGN))
@ -602,7 +615,7 @@ void SBar_DrawString(DStatusBarCore *self, DHUDFont *font, const FString &string
if (wrapwidth > 0) if (wrapwidth > 0)
{ {
auto brk = V_BreakLines(font->mFont, int(wrapwidth * scaleX), string, true); auto brk = V_BreakLines(font->mFont, int(wrapwidth * scaleX), string, true);
for (auto &line : brk) 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); 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; y += (font->mFont->GetHeight() + linespacing) * scaleY;
@ -621,7 +634,7 @@ void SBar_DrawString(DStatusBarCore *self, DHUDFont *font, const FString &string
// //
//============================================================================ //============================================================================
void DStatusBarCore::TransformRect(double &x, double &y, double &w, double &h, int flags) void DStatusBarCore::TransformRect(double& x, double& y, double& w, double& h, int flags)
{ {
// resolve auto-alignment before making any adjustments to the position values. // resolve auto-alignment before making any adjustments to the position values.
if (!(flags & DI_SCREEN_MANUAL_ALIGN)) if (!(flags & DI_SCREEN_MANUAL_ALIGN))
@ -672,3 +685,42 @@ void DStatusBarCore::TransformRect(double &x, double &y, double &w, double &h, i
} }
//============================================================================
//
// 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);
}

View file

@ -179,12 +179,14 @@ public:
void AttachToPlayer(player_t *player); void AttachToPlayer(player_t *player);
DVector2 GetHUDScale() const; DVector2 GetHUDScale() const;
void NewGame (); void NewGame ();
int GetTranslation() { return 0; }
void DrawGraphic(FGameTexture *texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, double rotate = 0, ERenderStyle style = STYLE_Translucent); void DrawGraphic(FGameTexture *texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, double rotate = 0, ERenderStyle style = STYLE_Translucent);
void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, double rotate = 0, ERenderStyle style = STYLE_Translucent); void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY, PalEntry color = 0xffffffff, int translation = 0, double rotate = 0, ERenderStyle style = STYLE_Translucent);
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 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 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 Fill(PalEntry color, double x, double y, double w, double h, int flags = 0);
void ValidateResolution(int& hres, int& vres) const;
void BeginStatusBar(int resW, int resH, int relTop); void BeginStatusBar(int resW, int resH, int relTop);
void BeginHUD(int resW, int resH, double Alpha); void BeginHUD(int resW, int resH, double Alpha);
@ -230,6 +232,7 @@ public:
double CrosshairSize; double CrosshairSize;
double Displacement; double Displacement;
bool ShowLog; bool ShowLog;
bool ForcedScale = false;
double Alpha = 1.; double Alpha = 1.;
DVector2 drawOffset = { 0,0 }; // can be set by subclasses to offset drawing operations DVector2 drawOffset = { 0,0 }; // can be set by subclasses to offset drawing operations

View file

@ -573,8 +573,10 @@ private:
short chunkFlag = ChunkFlag[nFrameBase]; short chunkFlag = ChunkFlag[nFrameBase];
if (chunkFlag & 1) flags |= DI_MIRROR; if (chunkFlag & 1)
if (chunkFlag & 2) flags |= DI_MIRRORY; flags |= DI_MIRROR;
if (chunkFlag & 2)
flags |= DI_MIRRORY;
DrawGraphic(tileGetTexture(tile), x, y, flags, 1, -1, -1, 1, 1); DrawGraphic(tileGetTexture(tile), x, y, flags, 1, -1, -1, 1, 1);
nFrameBase++; nFrameBase++;