From 9f336388042f6dd64708f567e789df718e26dd55 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 29 Jun 2020 22:00:38 +0200 Subject: [PATCH] - RR multiplayer screen. --- source/games/duke/src/2d_d.cpp | 12 +- source/games/duke/src/2d_r.cpp | 351 ++++++++++++--------------- source/games/duke/src/zz_screens.cpp | 69 +----- 3 files changed, 160 insertions(+), 272 deletions(-) diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index a38969c40..2a8b5ca64 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -99,7 +99,7 @@ void InitFonts_d() fontdata.Insert('!' + i, tile); } fontdata.Insert(1, TexMan.FindGameTexture("TINYBLAK")); // this is only here to widen the color range of the font to produce a better translation. - SmallFont2 = new ::FFont("SmallFont2", nullptr, "defsmallfont2", 0, 0, 0, -1, 4, false, false, false, &fontdata); + SmallFont2 = new ::FFont("SmallFont2", nullptr, "defsmallfont2", 0, 0, 0, -1, 3, false, false, false, &fontdata); SmallFont2->SetKerning(1); fontdata.Clear(); @@ -687,12 +687,12 @@ static void PlayBonusMusic() } -class DMultiplayerBonusScreen : public DScreenJob +class DDukeMultiplayerBonusScreen : public DScreenJob { int playerswhenstarted; public: - DMultiplayerBonusScreen(int pws) + DDukeMultiplayerBonusScreen(int pws) { playerswhenstarted = pws; } @@ -770,10 +770,10 @@ public: yfragtotal += frag; } mysnprintf(tempbuf, 32, "%-4ld", yfragtotal); - minitext(92 + (y * 23), 96 + (8 * 7), tempbuf, 2, 2 + 8 + 16 + 128); + MiniText(92 + (y * 23), 96 + (8 * 7), tempbuf, 0, -1, 2); } - minitext(45, 96 + (8 * 7), GStrings("Deaths"), 8, 2 + 8 + 16 + 128); + MiniText(45, 96 + (8 * 7), GStrings("Deaths"), 0, -1, 8); return skiprequest ? -1 : 1; } }; @@ -781,7 +781,7 @@ public: void ShowMPBonusScreen_d(int pws, CompletionFunc completion) { PlayBonusMusic(); - JobDesc job = { Create(pws) }; + JobDesc job = { Create(pws) }; RunScreenJob(&job, 1, completion); } diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp index a86620dfa..6a963f20a 100644 --- a/source/games/duke/src/2d_r.cpp +++ b/source/games/duke/src/2d_r.cpp @@ -60,10 +60,11 @@ void InitFonts_r() for (int i = 0; i < 95; i++) { auto tile = tileGetTexture(STARTALPHANUM + i); - if (tile && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0) + if (tile && tile->isValid() && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0) fontdata.Insert('!' + i, tile); } - SmallFont = new ::FFont("SmallFont", nullptr, "defsmallfont", 0, 0, 0, -1, -1, false, false, false, &fontdata); + SmallFont = new ::FFont("SmallFont", nullptr, "defsmallfont", 0, 0, 0, -1, 10, false, false, false, &fontdata); + SmallFont->SetKerning(2); fontdata.Clear(); // Big font @@ -85,18 +86,22 @@ void InitFonts_r() fontdata.Insert('`', tileGetTexture(BIGAPPOS)); fontdata.Insert('"', tileGetTexture(BIGAPPOS)); fontdata.Insert('\'', tileGetTexture(BIGAPPOS)); - BigFont = new ::FFont("BigFont", nullptr, "defbigfont", 0, 0, 0, -1, -1, false, false, false, &fontdata); + GlyphSet::Iterator it(fontdata); + GlyphSet::Pair* pair; + while (it.NextPair(pair)) pair->Value->SetOffsetsNotForFont(); + BigFont = new ::FFont("BigFont", nullptr, "defbigfont", 0, 0, 0, -1, 10, false, false, false, &fontdata); fontdata.Clear(); // Tiny font for (int i = 0; i < 95; i++) { auto tile = tileGetTexture(MINIFONT + i); - if (tile && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0) + if (tile && tile->isValid() && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0) fontdata.Insert('!' + i, tile); } fontdata.Insert(1, TexMan.FindGameTexture("TINYBLAK")); // this is only here to widen the color range of the font to produce a better translation. - SmallFont2 = new ::FFont("SmallFont2", nullptr, "defsmallfont2", 0, 0, 0, -1, -1, false, false, false, &fontdata); + SmallFont2 = new ::FFont("SmallFont2", nullptr, "defsmallfont2", 0, 0, 0, -1, 6, false, false, false, &fontdata); + SmallFont2->SetKerning(2); fontdata.Clear(); // SBAR index font @@ -116,213 +121,40 @@ void InitFonts_r() } +//========================================================================== +// +// wrappers around DrawText to allow easier reuse of the old code. +// The vertical displacements are to have the same positioning as with the original code. +// +//========================================================================== -static int gametext(int x,int y,char *t,char s) +static void BigText(double x, double y, const char* text) { - short ac,newx; - char centre, *oldt; - - centre = ( x == (320>>1) ); - newx = 0; - oldt = t; - - if(centre) - { - while(*t) - { - if(*t == 32) {newx+=5;t++;continue;} - else ac = *t - '!' + STARTALPHANUM; - - if( ac < STARTALPHANUM || ac > ENDALPHANUM ) break; - - if(*t >= '0' && *t <= '9') - newx += 8; - else newx += tilesiz[ac].x / 2; - t++; - } - - t = oldt; - x = (320>>1)-(newx>>1); - } - - while(*t) - { - if(*t == 32) {x+=5;t++;continue;} - else ac = *t - '!' + STARTALPHANUM; - - if( ac < STARTALPHANUM || ac > ENDALPHANUM ) - break; - - rotatesprite(x<<16,y<<16,32768L,0,ac,s,0,2+8+16,0,0,xdim-1,ydim-1); - - if(*t >= '0' && *t <= '9') - x += 8; - else x += tilesiz[ac].x / 2; - - t++; - } - - return (x); + x *= 2; y *= 2; + auto width = BigFont->StringWidth(text); + DrawText(twod, BigFont, CR_UNTRANSLATED, x - width / 2, y - 24, text, DTA_FullscreenScale, 3, DTA_VirtualWidth, 640, DTA_VirtualHeight, 400, TAG_DONE); } -static int gametext2(int x,int y,char *t,char s) +static void GameText(double x, double y, const char* t, int shade, int align = -1, int trans = 0) { - short ac,newx; - char centre, *oldt; - - centre = ( x == (320>>1) ); - newx = 0; - oldt = t; - - if(centre) - { - while(*t) - { - if(*t == 32) {newx+=5;t++;continue;} - else ac = *t - '!' + STARTALPHANUM; - - if( ac < STARTALPHANUM || ac > ENDALPHANUM ) break; - - if(*t >= '0' && *t <= '9') - newx += 8; - else newx += tilesiz[ac].x / 2; - t++; - } - - t = oldt; - x = (320>>1)-(newx>>1); - } - - while(*t) - { - if(*t == 32) {x+=5;t++;continue;} - else if(*t == '\'') ac = '`' - '!' + STARTALPHANUM; - else ac = *t - '!' + STARTALPHANUM; - - if( ac < STARTALPHANUM || ac > ENDALPHANUM ) - break; - - rotatesprite(x<<16,y<<16,32768L,0,ac,s,s,2+8+16,0,0,xdim-1,ydim-1); - - if(*t >= '0' && *t <= '9') - x += 8; - else x += tilesiz[ac].x / 2; - - t++; - } - - return (x); + x *= 2; y *= 2; + if (align != -1) + x -= SmallFont->StringWidth(t) * (align == 0 ? 0.5 : 1); + int light = Scale(numshades - shade, 255, numshades); + PalEntry pe(255, light, light, light); + DrawText(twod, SmallFont, CR_UNDEFINED, x, y + 2, t, DTA_FullscreenScale, 3, DTA_VirtualWidth, 640, DTA_VirtualHeight, 400, DTA_TranslationIndex, TRANSLATION(Translation_Remap, trans), DTA_Color, pe, TAG_DONE); } -static int gametextpal(int x,int y,char *t,char s,char p) +static void MiniText(double x, double y, const char* t, int shade, int align = -1, int trans = 0) { - short ac,newx; - char centre, *oldt; - - centre = ( x == (320>>1) ); - newx = 0; - oldt = t; - - if(centre) - { - while(*t) - { - if(*t == 32) {newx+=5;t++;continue;} - else ac = *t - '!' + STARTALPHANUM; - - if( ac < STARTALPHANUM || ac > ENDALPHANUM ) break; - - if(*t >= '0' && *t <= '9') - newx += 8; - else newx += tilesiz[ac].x; - t++; - } - - t = oldt; - x = (320>>1)-(newx>>1); - } - - while(*t) - { - if(*t == 32) {x+=5;t++;continue;} - else ac = *t - '!' + STARTALPHANUM; - - if( ac < STARTALPHANUM || ac > ENDALPHANUM ) - break; - - rotatesprite(x<<16,y<<16,65536L,0,ac,s,p,2+8+16,0,0,xdim-1,ydim-1); - if(*t >= '0' && *t <= '9') - x += 8; - else x += tilesiz[ac].x; - - t++; - } - - return (x); + x *= 2; y *= 2; + if (align != -1) + x -= SmallFont2->StringWidth(t) * (align == 0 ? 0.5 : 1); + int light = Scale(numshades - shade, 255, numshades); + PalEntry pe(255, light, light, light); + DrawText(twod, SmallFont2, CR_UNDEFINED, x, y, t, DTA_FullscreenScale, 3, DTA_VirtualWidth, 640, DTA_VirtualHeight, 400, DTA_TranslationIndex, TRANSLATION(Translation_Remap, trans), DTA_Color, pe, TAG_DONE); } -static int gametextpart(int x,int y,char *t,char s,short p) -{ - short ac,newx, cnt; - char centre, *oldt; - - centre = ( x == (320>>1) ); - newx = 0; - oldt = t; - cnt = 0; - - if(centre) - { - while(*t) - { - if(cnt == p) break; - - if(*t == 32) {newx+=5;t++;continue;} - else ac = *t - '!' + STARTALPHANUM; - - if( ac < STARTALPHANUM || ac > ENDALPHANUM ) break; - - newx += tilesiz[ac].x; - t++; - cnt++; - - } - - t = oldt; - x = (320>>1)-(newx>>1); - } - - cnt = 0; - while(*t) - { - if(*t == 32) {x+=5;t++;continue;} - else ac = *t - '!' + STARTALPHANUM; - - if( ac < STARTALPHANUM || ac > ENDALPHANUM ) break; - - if(cnt == p) - { - rotatesprite(x<<16,y<<16,65536L,0,ac,s,1,2+8+16,0,0,xdim-1,ydim-1); - break; - } - else - rotatesprite(x<<16,y<<16,65536L,0,ac,s,0,2+8+16,0,0,xdim-1,ydim-1); - - x += tilesiz[ac].x; - - t++; - cnt++; - } - - return (x); -} - -static void gamenumber(long x,long y,long n,char s) -{ - char b[10]; - ltoa(n,b,10); - gametext(x,y,b,s); -} #if 0 @@ -506,6 +338,121 @@ void PlayMapAnim(CompletionFunc completion) else completion(false); } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DRRMultiplayerBonusScreen : public DScreenJob +{ + int playerswhenstarted; + +public: + DRRMultiplayerBonusScreen(int pws) + { + playerswhenstarted = pws; + } + + int Frame(uint64_t clock, bool skiprequest) + { + char tempbuf[32]; + twod->ClearScreen(); + DrawTexture(twod, tileGetTexture(MENUSCREEN), 0, 0, DTA_FullscreenEx, 3, DTA_Color, 0xff808080, DTA_LegacyRenderStyle, STYLE_Normal, TAG_DONE); + double scale = 0.36; + DrawTexture(twod, tileGetTexture(INGAMEDUKETHREEDEE, true), 160, 34, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, + DTA_CenterOffset, true, DTA_ScaleX, scale, DTA_ScaleY, 0.36, TAG_DONE); + + GameText(160, 58, GStrings("Multiplayer Totals"), 0, 0); + GameText(160, 58 + 10, currentLevel->DisplayName(), 0, 0); + GameText(160, 165, GStrings("Presskey"), 0, 0); + + int t = 0; + + MiniText(38, 80, GStrings("Name"), 0); + MiniText(269 + 20, 80, GStrings("Kills"), 0, 1); + + for (int i = 0; i < playerswhenstarted; i++) + { + mysnprintf(tempbuf, 32, "%-4ld", i + 1); + MiniText(92 + (i * 23), 80, tempbuf, 0); + } + + for (int i = 0; i < playerswhenstarted; i++) + { + int xfragtotal = 0; + mysnprintf(tempbuf, 32, "%ld", i + 1); + + MiniText(30, 90 + t, tempbuf, 0); + MiniText(38, 90 + t, g_player[i].user_name, 0, -1, ps[i].palookup); + + for (int y = 0; y < playerswhenstarted; y++) + { + int frag = g_player[i].frags[y];// frags[i][y]); + if (i == y) + { + mysnprintf(tempbuf, 32, "%-4ld", ps[y].fraggedself); + MiniText(92 + (y * 23), 90 + t, tempbuf, 0); + xfragtotal -= ps[y].fraggedself; + } + else + { + mysnprintf(tempbuf, 32, "%-4ld", frag); + MiniText(92 + (y * 23), 90 + t, tempbuf, 0); + xfragtotal += frag; + } + /* + if (myconnectindex == connecthead) + { + mysnprintf(tempbuf, 32, "stats %ld killed %ld %ld\n", i + 1, y + 1, frag); + sendscore(tempbuf); + } + */ + } + + mysnprintf(tempbuf, 32, "%-4ld", xfragtotal); + MiniText(101 + (8 * 23), 90 + t, tempbuf, 0); + + t += 7; + } + + for (int y = 0; y < playerswhenstarted; y++) + { + int yfragtotal = 0; + for (int i = 0; i < playerswhenstarted; i++) + { + if (i == y) + yfragtotal += ps[i].fraggedself; + int frag = g_player[i].frags[y];// frags[i][y]); + yfragtotal += frag; + } + mysnprintf(tempbuf, 32, "%-4ld", yfragtotal); + MiniText(92 + (y * 23), 96 + (8 * 7), tempbuf, 0); + } + + MiniText(45, 96 + (8 * 7), GStrings("Deaths"), 0); + return skiprequest ? -1 : 1; + } +}; + +void ShowMPBonusScreen_r(int pws, CompletionFunc completion) +{ + JobDesc job = { Create(pws) }; + RunScreenJob(&job, 1, completion); +} + + +#if 1 +CCMD(testrbonus) +{ + if (argv.argc() > 1) + { + //bonussequence_d(strtol(argv[1], nullptr, 0), nullptr); + ShowMPBonusScreen_r(strtol(argv[1], nullptr, 0), nullptr); + } +} +#endif + #if 0 diff --git a/source/games/duke/src/zz_screens.cpp b/source/games/duke/src/zz_screens.cpp index c8300f493..08029fd3a 100644 --- a/source/games/duke/src/zz_screens.cpp +++ b/source/games/duke/src/zz_screens.cpp @@ -1108,72 +1108,13 @@ static void G_BonusCutscenes(void) bonussequence_d(ud.volume_number, [](bool){}); } +void ShowMPBonusScreen_d(int pws, CompletionFunc completion); +void ShowMPBonusScreen_r(int pws, CompletionFunc completion); + static void G_DisplayMPResultsScreen(void) { - int32_t i, y, t = 0; - - rotatesprite_fs(160<<16, 100<<16, 65536L, 0, TILE_MENUSCREEN, 16, 0, 2+8+64+BGSTRETCH); - rotatesprite_fs(160<<16, 34<<16, RR ? 23592L : 65536L, 0, TILE_INGAMEDUKETHREEDEE, 0, 0, 10); - if (!RR && PLUTOPAK) // JBF 20030804 - rotatesprite_fs((260)<<16, 36<<16, 65536L, 0, TILE_PLUTOPAKSPRITE+2, 0, 0, 2+8); - gametext_center(58+(RR ? 0 : 2), GStrings("Multiplayer Totals")); - gametext_center(58+10, currentLevel->DisplayName()); - - gametext_center_shade(RR ? 175 : 165, GStrings("Presskey"), quotepulseshade); - - minitext(38, 80, GStrings("Name"), 8, 2+8+16+128); - minitext(269, 80, GStrings("Kills"), 8, 2+8+16+128); - for (i=0; ipalookup, 2+8+16+128); - - for (y=0; yfraggedself); - minitext(92+(y*23), 90+t, tempbuf, RR ? 0 : 2, 2+8+16+128); - xfragtotal -= g_player[y].ps->fraggedself; - } - else - { - Bsprintf(tempbuf, "%-4d", g_player[i].frags[y]); - minitext(92+(y*23), 90+t, tempbuf, 0, 2+8+16+128); - xfragtotal += g_player[i].frags[y]; - } - } - - Bsprintf(tempbuf, "%-4d", xfragtotal); - minitext(101+(8*23), 90+t, tempbuf, RR ? 0 : 2, 2+8+16+128); - - t += 7; - } - - for (y=0; yfraggedself; - else - yfragtotal += g_player[i].frags[y]; - } - Bsprintf(tempbuf, "%-4d", yfragtotal); - minitext(92+(y*23), 96+(8*7), tempbuf, RR ? 0 : 2, 2+8+16+128); - } - - minitext(45, 96+(8*7), GStrings("Deaths"), RR ? 0 : 8, 2+8+16+128); + if (!isRR()) ShowMPBonusScreen_d(g_mostConcurrentPlayers, [](bool){}); + else ShowMPBonusScreen_r(g_mostConcurrentPlayers, [](bool) {}); } static int32_t G_PrintTime_ClockPad(void)