From 2016f56a7e9f7bfb3fec6f3e3f132c7925f14547 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 3 Oct 2020 13:32:39 +0200 Subject: [PATCH] - added a new scaling mode to the level summary screen to scale to a given size. In this mode the clean scaling factors are ignored and content is always scaled to fit the screen as efficently as possible. For the default summary screens an option was added to use this mode, which is a lot closer to the original look of this screen. It is not 100% identical because it still factors in the author, if given and long level names that may be broken into multiple lines of text. --- src/common/engine/namedef.h | 10 + src/wi_stuff.cpp | 24 +++ .../zscript/ui/statscreen/statscreen.zs | 189 ++++++++++-------- .../zscript/ui/statscreen/statscreen_sp.zs | 32 +-- 4 files changed, 161 insertions(+), 94 deletions(-) diff --git a/src/common/engine/namedef.h b/src/common/engine/namedef.h index 53fca85d0..e6bdcee92 100644 --- a/src/common/engine/namedef.h +++ b/src/common/engine/namedef.h @@ -660,7 +660,10 @@ xx(Static) xx(Staticconst) xx(DeathmatchStatusScreen) xx(CoopStatusScreen) +xx(DoomStatusScreen) xx(RavenStatusScreen) +xx(DoomStatusScreenSized) +xx(RavenStatusScreenSized) xx(StatusbarWidget) xx(StatusbarHead) xx(StatusbarCondition) @@ -1076,3 +1079,10 @@ xx(NewPlayerMenu) xx(AltHud) xx(GameScreen) +// summary +xx(cwidth) +xx(cheight) +xx(wrapwidth) +xx(scalefactorx) +xx(scalefactory) +xx(scalemode) diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index fca44fd17..c0c666eb2 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -61,6 +61,7 @@ CVAR(Bool, wi_percents, true, CVAR_ARCHIVE) CVAR(Bool, wi_showtotaltime, true, CVAR_ARCHIVE) CVAR(Bool, wi_noautostartmap, false, CVAR_USERINFO | CVAR_ARCHIVE) CVAR(Int, wi_autoadvance, 0, CVAR_SERVERINFO) +CVAR(Bool, wi_cleantextscale, true, CVAR_ARCHIVE) EXTERN_CVAR(Bool, inter_classic_scaling) // States for the intermission @@ -769,12 +770,35 @@ void WI_Start(wbstartstruct_t *wbstartstruct) } WI_Screen = cls->CreateNew(); + + ScaleOverrider s(twod); IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Start) { VMValue val[2] = { WI_Screen, wbstartstruct }; VMCall(func, val, 2, nullptr, 0); } + + if (!wi_cleantextscale) + { + // Only modify the original single player screens. Everything else must set itself up as intended + if (cls->TypeName == NAME_DoomStatusScreen || cls->TypeName == NAME_RavenStatusScreen) + { + int w = screen->GetWidth(); + int h = screen->GetHeight(); + float ratio = ActiveRatio(w, h); + int pixw = int(320 * (ratio * 0.75)); + if (pixw > 336) pixw -= 16; // leave a bit of space at the sides. + + WI_Screen->IntVar(NAME_cwidth) = 320; + WI_Screen->IntVar(NAME_cheight) = 200; + WI_Screen->IntVar(NAME_scalemode) = FSMode_ScaleToFit43; + WI_Screen->IntVar(NAME_scalefactorx) = 1; + WI_Screen->IntVar(NAME_scalefactory) = 1; + WI_Screen->IntVar(NAME_wrapwidth) = pixw; + } + } + GC::AddSoftRoot(WI_Screen); } diff --git a/wadsrc/static/zscript/ui/statscreen/statscreen.zs b/wadsrc/static/zscript/ui/statscreen/statscreen.zs index c1dcca7d5..d118111be 100644 --- a/wadsrc/static/zscript/ui/statscreen/statscreen.zs +++ b/wadsrc/static/zscript/ui/statscreen/statscreen.zs @@ -39,7 +39,6 @@ struct PatchInfo play version("2.5") }; -// Will be made a class later, but for now needs to mirror the internal version. class StatusScreen abstract play version("2.5") { enum EValues @@ -129,6 +128,11 @@ class StatusScreen abstract play version("2.5") int player_deaths[MAXPLAYERS]; int sp_state; + + int cWidth, cHeight; // size of the canvas + int scalemode; + int wrapwidth; // size used to word wrap level names + int scaleFactorX, scaleFactorY; //==================================================================== @@ -140,9 +144,34 @@ class StatusScreen abstract play version("2.5") int DrawCharPatch(Font fnt, int charcode, int x, int y, int translation = Font.CR_UNTRANSLATED, bool nomove = false) { int width = fnt.GetCharWidth(charcode); - screen.DrawChar(fnt, translation, x, y, charcode, nomove ? DTA_CleanNoMove : DTA_Clean, true); + if (scalemode == -1) screen.DrawChar(fnt, translation, x, y, charcode, nomove ? DTA_CleanNoMove : DTA_Clean, true); + else screen.DrawChar(fnt, translation, x, y, charcode, DTA_FullscreenScale, scalemode, DTA_VirtualWidth, cwidth, DTA_VirtualHeight, cheight); return x - width; } + + //==================================================================== + // + // + // + //==================================================================== + + void DrawTexture(TextureID tex, double x, double y, bool nomove = false) + { + if (scalemode == -1) screen.DrawTexture(tex, true, x, y, nomove ? DTA_CleanNoMove : DTA_Clean, true); + else screen.DrawTexture(tex, true, x, y, DTA_FullscreenScale, scalemode, DTA_VirtualWidth, cwidth, DTA_VirtualHeight, cheight); + } + + //==================================================================== + // + // + // + //==================================================================== + + void DrawText(Font fnt, int color, double x, double y, String str, bool nomove = false, bool shadow = false) + { + if (scalemode == -1) screen.DrawText(fnt, color, x, y, str, nomove ? DTA_CleanNoMove : DTA_Clean, true, DTA_Shadow, shadow); + else screen.DrawText(fnt, color, x, y, str, DTA_FullscreenScale, scalemode, DTA_VirtualWidth, cwidth, DTA_VirtualHeight, cheight, DTA_Shadow, shadow); + } //==================================================================== // @@ -159,25 +188,25 @@ class StatusScreen abstract play version("2.5") if (tex.isValid()) { let size = TexMan.GetScaledSize(tex); - screen.DrawTexture(tex, true, (screen.GetWidth() - size.X * CleanXfac) /2, y, DTA_CleanNoMove, true); + DrawTexture(tex, (cwidth - size.X * scaleFactorX) /2, y, true); if (size.Y > 50) { // Fix for Deus Vult II and similar wads that decide to make these hugely tall // patches with vast amounts of empty space at the bottom. size.Y = TexMan.CheckRealHeight(tex); } - return y + int(Size.Y) * CleanYfac; + return y + int(Size.Y) * scaleFactorY; } else if (levelname.Length() > 0) { int h = 0; - int lumph = mapname.mFont.GetHeight() * CleanYfac; + int lumph = mapname.mFont.GetHeight() * scaleFactorY; - BrokenLines lines = mapname.mFont.BreakLines(levelname, screen.GetWidth() / CleanXfac); + BrokenLines lines = mapname.mFont.BreakLines(levelname, wrapwidth / scaleFactorX); int count = lines.Count(); for (int i = 0; i < count; i++) { - screen.DrawText(mapname.mFont, mapname.mColor, (screen.GetWidth() - lines.StringWidth(i) * CleanXfac) / 2, y + h, lines.StringAt(i), DTA_CleanNoMove, true); + DrawText(mapname.mFont, mapname.mColor, (cwidth - lines.StringWidth(i) * scaleFactorX) / 2, y + h, lines.StringAt(i), true); h += lumph; } return y + h; @@ -187,7 +216,7 @@ class StatusScreen abstract play version("2.5") //==================================================================== // - // Draws a level author's name with the big font + // Draws a level author's name with the given font // //==================================================================== @@ -196,14 +225,14 @@ class StatusScreen abstract play version("2.5") if (levelname.Length() > 0) { int h = 0; - int lumph = author.mFont.GetHeight() * CleanYfac; + int lumph = author.mFont.GetHeight() * scaleFactorY; - BrokenLines lines = author.mFont.BreakLines(levelname, screen.GetWidth() / CleanXfac); + BrokenLines lines = author.mFont.BreakLines(levelname, wrapwidth / scaleFactorX); int count = lines.Count(); for (int i = 0; i < count; i++) { - screen.DrawText(author.mFont, author.mColor, (screen.GetWidth() - lines.StringWidth(i) * CleanXfac) / 2, y + h, lines.StringAt(i), DTA_CleanNoMove, true); + DrawText(author.mFont, author.mColor, (cwidth - lines.StringWidth(i) * scaleFactorX) / 2, y + h, lines.StringAt(i), true); h += lumph; } return y + h; @@ -235,22 +264,21 @@ class StatusScreen abstract play version("2.5") int DrawPatchOrText(int y, PatchInfo pinfo, TextureID patch, String stringname) { String string = Stringtable.Localize(stringname); - int midx = screen.GetWidth() / 2; + int midx = cwidth / 2; if (TexMan.OkForLocalization(patch, stringname)) { let size = TexMan.GetScaledSize(patch); - screen.DrawTexture(patch, true, midx - size.X * CleanXfac/2, y, DTA_CleanNoMove, true); - return y + int(size.Y * CleanYfac); + DrawTexture(patch, midx - size.X * scaleFactorX/2, y, true); + return y + int(size.Y * scaleFactorY); } else { - screen.DrawText(pinfo.mFont, pinfo.mColor, midx - pinfo.mFont.StringWidth(string) * CleanXfac/2, y, string, DTA_CleanNoMove, true); - return y + pinfo.mFont.GetHeight() * CleanYfac; + DrawText(pinfo.mFont, pinfo.mColor, midx - pinfo.mFont.StringWidth(string) * scaleFactorX/2, y, string, true); + return y + pinfo.mFont.GetHeight() * scaleFactorY; } } - //==================================================================== // // Draws " Finished!" @@ -263,7 +291,7 @@ class StatusScreen abstract play version("2.5") virtual int drawLF () { bool ispatch = wbs.LName0.isValid(); - int oldy = TITLEY * CleanYfac; + int oldy = TITLEY * scaleFactorY; int h; if (!ispatch) @@ -271,7 +299,7 @@ class StatusScreen abstract play version("2.5") let asc = mapname.mFont.GetMaxAscender(lnametexts[1]); if (asc > TITLEY - 2) { - oldy = (asc+2) * CleanYfac; + oldy = (asc+2) * scaleFactorY; } } @@ -285,7 +313,7 @@ class StatusScreen abstract play version("2.5") if (authortexts[0].length() == 0) { int h1 = BigFont.GetHeight() - BigFont.GetDisplacement(); - int h2 = (y - oldy) / CleanYfac / 4; + int h2 = (y - oldy) / scaleFactorY / 4; disp = min(h1, h2); if (!TexMan.OkForLocalization(finishedPatch, "$WI_FINISHED")) @@ -297,15 +325,15 @@ class StatusScreen abstract play version("2.5") { disp += author.mFont.GetMaxAscender(authortexts[0]); } - y += disp * CleanYfac; + y += disp * scaleFactorY; } y = DrawAuthor(y, authortexts[0]); // draw "Finished!" - int statsy = multiplayer? NG_STATSY : SP_STATSY * CleanYFac; - if (y < (statsy - finished.mFont.GetHeight()*3/4) * CleanYfac) + int statsy = multiplayer? NG_STATSY : SP_STATSY * scaleFactorY; + if (y < (statsy - finished.mFont.GetHeight()*3/4) * scaleFactorY) { // don't draw 'finished' if the level name is too tall y = DrawPatchOrText(y, finished, finishedPatch, "$WI_FINISHED"); @@ -313,7 +341,6 @@ class StatusScreen abstract play version("2.5") return y; } - //==================================================================== // // Draws "Entering " @@ -326,14 +353,14 @@ class StatusScreen abstract play version("2.5") virtual void drawEL () { bool ispatch = TexMan.OkForLocalization(enteringPatch, "$WI_ENTERING"); - int oldy = TITLEY * CleanYfac; + int oldy = TITLEY * scaleFactorY; if (!ispatch) { let asc = entering.mFont.GetMaxAscender("$WI_ENTERING"); if (asc > TITLEY - 2) { - oldy = (asc+2) * CleanYfac; + oldy = (asc+2) * scaleFactorY; } } @@ -352,7 +379,7 @@ class StatusScreen abstract play version("2.5") { disp += mapname.mFont.GetMaxAscender(lnametexts[1]); } - y += disp * CleanYfac; + y += disp * scaleFactorY; } y = DrawName(y, wbs.LName1, lnametexts[1]); @@ -360,14 +387,13 @@ class StatusScreen abstract play version("2.5") if (wbs.LName1.isValid() && authortexts[1].length() > 0) { // Consdider the ascender height of the following text. - y += author.mFont.GetMaxAscender(authortexts[1]) * CleanYfac; + y += author.mFont.GetMaxAscender(authortexts[1]) * scaleFactorY; } DrawAuthor(y, authortexts[1]); } - //==================================================================== // // Draws a number. @@ -383,9 +409,9 @@ class StatusScreen abstract play version("2.5") String text; int len; - if (nomove) + if (nomove && scalemode == -1) { - fntwidth *= CleanXfac; + fntwidth *= scaleFactorX; } text = String.Format("%d", n); len = text.Length(); @@ -435,35 +461,76 @@ class StatusScreen abstract play version("2.5") if (wi_percents) { - if (nomove) + if (nomove && scalemode == -1) { - x -= fnt.StringWidth("%") * CleanXfac; + x -= fnt.StringWidth("%") * scaleFactorX; } else { x -= fnt.StringWidth("%"); } - screen.DrawText(fnt, color, x, y, "%", nomove? DTA_CleanNoMove : DTA_Clean, true); + DrawText(fnt, color, x, y, "%", nomove); if (nomove) { x -= 2*CleanXfac; } - drawNum(fnt, x, y, b == 0 ? 100 : p * 100 / b, -1, false, color); + drawNum(fnt, x, y, b == 0 ? 100 : p * 100 / b, -1, false, color, nomove); } else { if (show_total) { - x = drawNum(fnt, x, y, b, 2, false, color); + x = drawNum(fnt, x, y, b, 2, false, color, nomove); x -= fnt.StringWidth("/"); - screen.DrawText (fnt, color, x, y, "/", nomove? DTA_CleanNoMove : DTA_Clean, true); + DrawText (fnt, color, x, y, "/", nomove); } - drawNum (fnt, x, y, p, -1, false, color); + drawNum (fnt, x, y, p, -1, false, color, nomove); } } + + //==================================================================== + // + // Display level completion time and par, or "sucks" message if overflow. + // + //==================================================================== + + void drawTimeFont (Font printFont, int x, int y, int t, int color) + { + bool sucky; + + if (t < 0) + return; + + int hours = t / 3600; + t -= hours * 3600; + int minutes = t / 60; + t -= minutes * 60; + int seconds = t; + + // Why were these offsets hard coded? Half the WADs with custom patches + // I tested screwed up miserably in this function! + int num_spacing = printFont.GetCharWidth("3"); + int colon_spacing = printFont.GetCharWidth(":"); + + x = drawNum (printFont, x, y, seconds, 2, true, color) - 1; + DrawCharPatch (printFont, ":", x -= colon_spacing, y, color); + x = drawNum (printFont, x, y, minutes, 2, hours!=0, color); + if (hours) + { + DrawCharPatch (printFont, ":", x -= colon_spacing, y, color); + drawNum (printFont, x, y, hours, 2, false, color); + } + } + + void drawTime (int x, int y, int t, bool no_sucks=false) + { + drawTimeFont(IntermissionFont, x, y, t, Font.CR_UNTRANSLATED); + } + //==================================================================== // + // the 'scaled' drawers are for the multiplayer scoreboard // //==================================================================== @@ -531,46 +598,6 @@ class StatusScreen abstract play version("2.5") drawTextScaled(fnt, x - fnt.StringWidth(s) * scale, y, s, scale, color); } - //==================================================================== - // - // Display level completion time and par, or "sucks" message if overflow. - // - //==================================================================== - - void drawTimeFont (Font printFont, int x, int y, int t, int color) - { - bool sucky; - - if (t < 0) - return; - - int hours = t / 3600; - t -= hours * 3600; - int minutes = t / 60; - t -= minutes * 60; - int seconds = t; - - // Why were these offsets hard coded? Half the WADs with custom patches - // I tested screwed up miserably in this function! - int num_spacing = printFont.GetCharWidth("3"); - int colon_spacing = printFont.GetCharWidth(":"); - - x = drawNum (printFont, x, y, seconds, 2, true, color) - 1; - DrawCharPatch (printFont, ":", x -= colon_spacing, y, color); - x = drawNum (printFont, x, y, minutes, 2, hours!=0, color); - if (hours) - { - DrawCharPatch (printFont, ":", x -= colon_spacing, y, color); - drawNum (printFont, x, y, hours, 2, false, color); - } - } - - void drawTime (int x, int y, int t, bool no_sucks=false) - { - drawTimeFont(IntermissionFont, x, y, t, Font.CR_UNTRANSLATED); - } - - //==================================================================== // // @@ -897,6 +924,12 @@ class StatusScreen abstract play version("2.5") bg = InterBackground.Create(wbs); noautostartmap = bg.LoadBackground(false); initStats(); + + wrapwidth = cwidth = screen.GetWidth(); + cheight = screen.GetHeight(); + scalemode = -1; + scaleFactorX = CleanXfac; + scaleFactorY = CleanYfac; } diff --git a/wadsrc/static/zscript/ui/statscreen/statscreen_sp.zs b/wadsrc/static/zscript/ui/statscreen/statscreen_sp.zs index ccce22dda..3ea43d345 100644 --- a/wadsrc/static/zscript/ui/statscreen/statscreen_sp.zs +++ b/wadsrc/static/zscript/ui/statscreen/statscreen_sp.zs @@ -158,11 +158,11 @@ class DoomStatusScreen : StatusScreen if (useGfx) { printFont = IntermissionFont; - screen.DrawTexture (Kills, true, statsx, SP_STATSY, DTA_Clean, true); - screen.DrawTexture (Items, true, statsx, SP_STATSY+lh, DTA_Clean, true); - screen.DrawTexture (P_secret, true, statsx, SP_STATSY+2*lh, DTA_Clean, true); - screen.DrawTexture (Timepic, true, SP_TIMEX, SP_TIMEY, DTA_Clean, true); - if (wbs.partime) screen.DrawTexture (Par, true, 160 + SP_TIMEX, SP_TIMEY, DTA_Clean, true); + DrawTexture (Kills, statsx, SP_STATSY); + DrawTexture (Items, statsx, SP_STATSY+lh); + DrawTexture (P_secret, statsx, SP_STATSY+2*lh); + DrawTexture (Timepic, SP_TIMEX, SP_TIMEY); + if (wbs.partime) DrawTexture (Par, 160 + SP_TIMEX, SP_TIMEY); } else { @@ -179,11 +179,11 @@ class DoomStatusScreen : StatusScreen } printFont = generic_ui? IntermissionFont : content.mFont; - screen.DrawText (textFont, tcolor, statsx, SP_STATSY, "$TXT_IMKILLS", DTA_Clean, true); - screen.DrawText (textFont, tcolor, statsx, SP_STATSY+lh, "$TXT_IMITEMS", DTA_Clean, true); - screen.DrawText (textFont, tcolor, statsx, SP_STATSY+2*lh, "$TXT_IMSECRETS", DTA_Clean, true); - screen.DrawText (textFont, tcolor, SP_TIMEX, SP_TIMEY, "$TXT_IMTIME", DTA_Clean, true); - if (wbs.partime) screen.DrawText (textFont, tcolor, 160 + SP_TIMEX, SP_TIMEY, "$TXT_IMPAR", DTA_Clean, true); + DrawText (textFont, tcolor, statsx, SP_STATSY, "$TXT_IMKILLS"); + DrawText (textFont, tcolor, statsx, SP_STATSY+lh, "$TXT_IMITEMS"); + DrawText (textFont, tcolor, statsx, SP_STATSY+2*lh, "$TXT_IMSECRETS"); + DrawText (textFont, tcolor, SP_TIMEX, SP_TIMEY, "$TXT_IMTIME"); + if (wbs.partime) screen.DrawText (textFont, tcolor, 160 + SP_TIMEX, SP_TIMEY, "$TXT_IMPAR"); } drawPercent (printFont, 320 - statsx, SP_STATSY, cnt_kills[0], wbs.maxkills, true, tcolor); @@ -201,11 +201,11 @@ class DoomStatusScreen : StatusScreen if (useGfx && TexMan.OkForLocalization(Sucks, "$TXT_IMSUCKS")) { let size = TexMan.GetScaledSize(Sucks); - screen.DrawTexture (Sucks, true, x - size.X, y - size.Y - 2, DTA_Clean, true); + DrawTexture (Sucks, x - size.X, y - size.Y - 2); } else { - screen.DrawText (textFont, tColor, x - printFont.StringWidth("$TXT_IMSUCKS"), y - printFont.GetHeight() - 2, "$TXT_IMSUCKS", DTA_Clean, true); + DrawText (textFont, tColor, x - printFont.StringWidth("$TXT_IMSUCKS"), y - printFont.GetHeight() - 2, "$TXT_IMSUCKS"); } } @@ -233,9 +233,9 @@ class RavenStatusScreen : DoomStatusScreen Font textFont = generic_ui? NewSmallFont : content.mFont; let tcolor = content.mColor; - screen.DrawText (textFont, tcolor, 50, 65, "$TXT_IMKILLS", DTA_Clean, true, DTA_Shadow, true); - screen.DrawText (textFont, tcolor, 50, 90, "$TXT_IMITEMS", DTA_Clean, true, DTA_Shadow, true); - screen.DrawText (textFont, tcolor, 50, 115, "$TXT_IMSECRETS", DTA_Clean, true, DTA_Shadow, true); + DrawText (textFont, tcolor, 50, 65, "$TXT_IMKILLS", shadow:true); + DrawText (textFont, tcolor, 50, 90, "$TXT_IMITEMS", shadow:true); + DrawText (textFont, tcolor, 50, 115, "$TXT_IMSECRETS", shadow:true); int countpos = gameinfo.gametype==GAME_Strife? 285:270; if (sp_state >= 2) @@ -252,7 +252,7 @@ class RavenStatusScreen : DoomStatusScreen } if (sp_state >= 8) { - screen.DrawText (textFont, tcolor, 85, 160, "$TXT_IMTIME", DTA_Clean, true, DTA_Shadow, true); + DrawText (textFont, tcolor, 85, 160, "$TXT_IMTIME", shadow:true); drawTimeFont (textFont, 249, 160, cnt_time, tcolor); if (wi_showtotaltime) {