- added generic font support for intermission text screen.

This commit is contained in:
Christoph Oelckers 2019-04-11 00:14:53 +02:00
parent 2747eef0e0
commit 28c8bb47fb
3 changed files with 75 additions and 26 deletions

View file

@ -253,17 +253,34 @@ void DIntermissionScreenText::Init(FIntermissionAction *desc, bool first)
if (mText[0] == '$') mText = GStrings(&mText[1]);
mTextSpeed = static_cast<FIntermissionActionTextscreen*>(desc)->mTextSpeed;
mTextX = static_cast<FIntermissionActionTextscreen*>(desc)->mTextX;
bool usesDefault = mTextX < 0;
usesDefault = mTextX < 0;
if (mTextX < 0) mTextX =gameinfo.TextScreenX;
mTextY = static_cast<FIntermissionActionTextscreen*>(desc)->mTextY;
if (mTextY < 0) mTextY =gameinfo.TextScreenY;
// If the text is too wide, center it so that it works better on widescreen displays.
// On 4:3 it'd still be cut off, though.
int width = SmallFont->StringWidth(mText);
if (usesDefault && mTextX + width > 320 - mTextX)
if (!generic_ui)
{
mTextX = (320 - width) / 2;
// Todo: Split too long texts
// If the text is too wide, center it so that it works better on widescreen displays.
// On 4:3 it'd still be cut off, though.
int width = SmallFont->StringWidth(mText);
if (usesDefault && mTextX + width > 320 - mTextX)
{
mTextX = (320 - width) / 2;
}
}
else
{
// Todo: Split too long texts
mTextX *= 2;
mTextY *= 2;
int width = NewSmallFont->StringWidth(mText);
if (usesDefault && mTextX + width > 640 - mTextX)
{
mTextX = (640 - width) / 2;
}
}
@ -298,45 +315,59 @@ void DIntermissionScreenText::Drawer ()
int c;
const FRemapTable *range;
const uint8_t *ch = (const uint8_t*)mText.GetChars();
const int kerning = SmallFont->GetDefaultKerning();
// Count number of rows in this text. Since it does not word-wrap, we just count
// line feed characters.
int numrows;
auto font = generic_ui ? NewSmallFont : SmallFont;
auto fontscale = generic_ui ? MIN(screen->GetWidth()/640, screen->GetHeight()/400) : CleanXfac;
int cleanwidth = screen->GetWidth() / fontscale;
int cleanheight = screen->GetHeight() / fontscale;
int refwidth = generic_ui ? 640 : 320;
int refheight = generic_ui ? 400 : 200;
const int kerning = font->GetDefaultKerning();
for (numrows = 1, c = 0; ch[c] != '\0'; ++c)
{
numrows += (ch[c] == '\n');
}
int rowheight = SmallFont->GetHeight() * CleanYfac;
int rowpadding = (gameinfo.gametype & (GAME_DoomStrifeChex) ? 3 : -1) * CleanYfac;
int rowheight = font->GetHeight() * fontscale;
int rowpadding = (generic_ui? 2 : ((gameinfo.gametype & (GAME_DoomStrifeChex) ? 3 : -1))) * fontscale;
int cx = (mTextX - 160)*CleanXfac + screen->GetWidth() / 2;
int cy = (mTextY - 100)*CleanYfac + screen->GetHeight() / 2;
int cx = (mTextX - refwidth/2) * fontscale + screen->GetWidth() / 2;
int cy = (mTextY - refheight/2) * fontscale + screen->GetHeight() / 2;
cx = MAX<int>(0, cx);
int startx = cx;
// Does this text fall off the end of the screen? If so, try to eliminate some margins first.
while (rowpadding > 0 && cy + numrows * (rowheight + rowpadding) - rowpadding > screen->GetHeight())
if (usesDefault)
{
rowpadding--;
}
// If it's still off the bottom, try to center it vertically.
if (cy + numrows * (rowheight + rowpadding) - rowpadding > screen->GetHeight())
{
cy = (screen->GetHeight() - (numrows * (rowheight + rowpadding) - rowpadding)) / 2;
// If it's off the top now, you're screwed. It's too tall to fit.
if (cy < 0)
int allheight;
while ((allheight = numrows * (rowheight + rowpadding)), allheight > screen->GetHeight() && rowpadding > 0)
{
cy = 0;
rowpadding--;
}
allheight = numrows * (rowheight + rowpadding);
if (screen->GetHeight() - cy - allheight < cy)
{
cy = (screen->GetHeight() - allheight) / 2;
if (cy < 0) cy = 0;
}
}
else
{
// Does this text fall off the end of the screen? If so, try to eliminate some margins first.
while (rowpadding > 0 && cy + numrows * (rowheight + rowpadding) - rowpadding > screen->GetHeight())
{
rowpadding--;
}
// If it's still off the bottom, you are screwed if the origin is fixed.
}
rowheight += rowpadding;
// draw some of the text onto the screen
count = (mTicker - mTextDelay) / mTextSpeed;
range = SmallFont->GetColorTranslation (mTextColor);
range = font->GetColorTranslation (mTextColor);
for ( ; count > 0 ; count-- )
{
@ -350,13 +381,17 @@ void DIntermissionScreenText::Drawer ()
continue;
}
pic = SmallFont->GetChar (c, mTextColor, &w);
pic = font->GetChar (c, mTextColor, &w);
w += kerning;
w *= CleanXfac;
w *= fontscale;
if (cx + w > SCREENWIDTH)
continue;
screen->DrawChar(SmallFont, mTextColor, cx, cy, c, DTA_CleanNoMove, true, TAG_DONE);
if (generic_ui)
screen->DrawChar(font, mTextColor, cx/fontscale, cy/fontscale, c, DTA_KeepRatio, true, DTA_VirtualWidth, cleanwidth, DTA_VirtualHeight, cleanheight, TAG_DONE);
else
screen->DrawChar(font, mTextColor, cx, cy, c, DTA_CleanNoMove, true, TAG_DONE);
cx += w;
}
}

View file

@ -8,6 +8,7 @@
#include "s_sound.h"
#include "v_font.h"
#include "g_game.h"
#include "v_text.h"
struct event_t;
@ -214,6 +215,10 @@ class DIntermissionScreenText : public DIntermissionScreen
int mTextDelay;
int mTextLen;
EColorRange mTextColor;
bool usesDefault;
void MeasureText(bool posisfixed);
FString RemoveLineFeeds(const char *text);
public:

View file

@ -181,6 +181,10 @@ void DFrameBuffer::DrawChar (FFont *font, int normalcolor, double x, double y, i
int dummy;
bool redirected;
// Workaround until this can be automated.
if (font == NewSmallFont && normalcolor == CR_UNTRANSLATED)
normalcolor = C_GetDefaultFontColor();
if (NULL != (pic = font->GetChar (character, normalcolor, &dummy, &redirected)))
{
DrawParms parms;
@ -211,6 +215,11 @@ void DFrameBuffer::DrawChar(FFont *font, int normalcolor, double x, double y, in
int dummy;
bool redirected;
// Workaround until this can be automated.
if (font == NewSmallFont && normalcolor == CR_UNTRANSLATED)
normalcolor = C_GetDefaultFontColor();
if (NULL != (pic = font->GetChar(character, normalcolor, &dummy, &redirected)))
{
DrawParms parms;