diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index ac9c73a9e..dba3d0274 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -71,7 +71,8 @@ struct GameInterface virtual void StartGame(FNewGameStartup& gs) {} virtual FSavegameInfo GetSaveSig() { return { "", 0, 0}; } virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; } - virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool withbg = true) {} + virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool withbg = true); + virtual double SmallFontScale() { return 1; } virtual void DrawMenuCaption(const DVector2& origin, const char* text) {} virtual bool SaveGame(FSaveGameNode*) { return false; } virtual bool LoadGame(FSaveGameNode*) { return false; } diff --git a/source/core/menu/messagebox.cpp b/source/core/menu/messagebox.cpp index f1efd8ea0..44d7f3d1e 100644 --- a/source/core/menu/messagebox.cpp +++ b/source/core/menu/messagebox.cpp @@ -46,6 +46,28 @@ extern FSaveGameNode *quickSaveSlot; + +void GameInterface::DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) +{ + double scale = SmallFontScale(); + int formatwidth = int(320 / scale); + auto lines = V_BreakLines(SmallFont, formatwidth, text, true); + auto fheight = bg? 10 : SmallFont->GetHeight()* scale; // Fixme: Get spacing for text pages from elsewhere. + if (!bg) + { + auto totaltextheight = lines.Size() * fheight; + position -= totaltextheight / 2; + } + + double y = origin.Y + position; + for (auto& line : lines) + { + double x = origin.X + 160 - line.Width * scale * 0.5; + DrawText(twod, SmallFont, CR_UNTRANSLATED, x, y, line.Text, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_ScaleX, scale, DTA_ScaleY, scale, TAG_DONE); + y += fheight; + } +} + class DMessageBoxMenu : public DMenu { using Super = DMenu; @@ -202,10 +224,10 @@ void DMessageBoxMenu::Drawer() { y += fontheight; mMouseY = y; - DrawText(twod, NewSmallFont, + DrawText(twod, SmallFont, messageSelection == 0 ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, 160, y, GStrings["TXT_YES"], DTA_Clean, true, TAG_DONE); - DrawText(twod, NewSmallFont, + DrawText(twod, SmallFont, messageSelection == 1 ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, 160, y + fontheight + 1, GStrings["TXT_NO"], DTA_Clean, true, TAG_DONE); @@ -213,7 +235,7 @@ void DMessageBoxMenu::Drawer() { if (((DMenu::MenuTime >> 2) % 8) < 6) { - DrawText(twod, NewSmallFont, OptionSettings.mFontColorSelection, + DrawText(twod, SmallFont, OptionSettings.mFontColorSelection, (150 - 160) * CleanXfac + screen->GetWidth() / 2, (y + (fontheight + 1) * messageSelection - 100 + fontheight / 2 - 5) * CleanYfac + screen->GetHeight() / 2, "\xd", diff --git a/source/games/duke/CMakeLists.txt b/source/games/duke/CMakeLists.txt index f09c2bef0..eef3df3bf 100644 --- a/source/games/duke/CMakeLists.txt +++ b/source/games/duke/CMakeLists.txt @@ -10,6 +10,7 @@ set( PCH_SOURCES src/animatesprites_r.cpp src/animatesprites_d.cpp src/bowling.cpp + src/d_menu.cpp src/dispatch.cpp src/flags_d.cpp src/flags_r.cpp @@ -37,7 +38,6 @@ set( PCH_SOURCES src/spawn_r.cpp src/zz_cheats.cpp src/zz_common.cpp - src/zz_d_menu.cpp src/zz_demo.cpp src/zz_game.cpp src/zz_global.cpp diff --git a/source/games/duke/src/2d_d.cpp b/source/games/duke/src/2d_d.cpp index 38faa0b42..c3607b4d9 100644 --- a/source/games/duke/src/2d_d.cpp +++ b/source/games/duke/src/2d_d.cpp @@ -55,8 +55,11 @@ void InitFonts_d() for (int i = 0; i < 95; i++) { auto tile = tileGetTexture(STARTALPHANUM + i); - if (tile && tile->isValid() && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0) - fontdata.Insert('!' + i, tile); + if (tile && tile->isValid() && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0) + { + fontdata.Insert('!' + i, tile); + tile->SetOffsetsNotForFont(); + } } SmallFont = new ::FFont("SmallFont", nullptr, "defsmallfont", 0, 0, 0, -1, 5, false, false, false, &fontdata); fontdata.Clear(); diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp index f22d40e16..f99605903 100644 --- a/source/games/duke/src/2d_r.cpp +++ b/source/games/duke/src/2d_r.cpp @@ -57,7 +57,10 @@ void InitFonts_r() { auto tile = tileGetTexture(STARTALPHANUM + i); if (tile && tile->isValid() && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0) + { fontdata.Insert('!' + i, tile); + tile->SetOffsetsNotForFont(); + } } SmallFont = new ::FFont("SmallFont", nullptr, "defsmallfont", 0, 0, 0, -1, 10, false, false, false, &fontdata); SmallFont->SetKerning(2); diff --git a/source/games/duke/src/zz_d_menu.cpp b/source/games/duke/src/d_menu.cpp similarity index 71% rename from source/games/duke/src/zz_d_menu.cpp rename to source/games/duke/src/d_menu.cpp index 40420d00c..2d6d691a8 100644 --- a/source/games/duke/src/zz_d_menu.cpp +++ b/source/games/duke/src/d_menu.cpp @@ -1,29 +1,33 @@ //------------------------------------------------------------------------- /* -Copyright (C) 2016 EDuke32 developers and contributors -Copyright (C) 2019 Christoph Oelckers +Copyright (C) 1996, 2003 - 3D Realms Entertainment +Copyright (C) 2020 - Christoph Oelckers -This is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. +This file is part of Enhanced Duke Nukem 3D version 1.5 - Atomic Edition + +Duke Nukem 3D is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Original Source: 1996 - Todd Replogle +Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms + */ //------------------------------------------------------------------------- #include "ns.h" // Must come before everything else! -#include "cheats.h" -#include "compat.h" -#include "demo.h" #include "duke3d.h" #include "menus.h" @@ -51,7 +55,7 @@ BEGIN_DUKE_NS static void Menu_DrawBackground(const DVector2 &origin) { - DrawTexture(twod, tileGetTexture(TILE_MENUSCREEN), origin.X + 160, origin.Y + 100, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_Color, 0xff808080, TAG_DONE); + DrawTexture(twod, tileGetTexture(TILE_MENUSCREEN), origin.X + 160, origin.Y + 100, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_Color, 0xff808080, DTA_CenterOffset, true, TAG_DONE); } //---------------------------------------------------------------------------- @@ -91,7 +95,7 @@ protected: int y_lower = y_upper + mDesc->mYbotton; int y = 0; int spacing = 0; - int const height = 15; // cannot take value from the font because it would be inconsistent + const int height = 15; // cannot take value from the font because it would be inconsistent int totalheight = 0, numvalidentries = mDesc->mItems.Size(); @@ -105,7 +109,6 @@ protected: if (mDesc->mSpacing <= 0) spacing = std::max(0, (y_lower - y_upper - totalheight) / (numvalidentries > 1 ? numvalidentries - 1 : 1)); if (spacing <= 0) spacing = mDesc->mSpacing; - // totalHeight calculating pass int totalHeight; for (unsigned e = 0; e < mDesc->mItems.Size(); ++e) { @@ -137,19 +140,24 @@ class DukeMainMenu : public DukeListMenu void PreDraw() override { DukeListMenu::PreDraw(); + double x = origin.X + 160; if (RRRA) { - rotatesprite_fs(int(origin.X * 65536) + ((160 - 5) << 16), int(origin.Y * 65536) + ((57) << 16), 16592L, 0, TILE_THREEDEE, 0, 0, 10); + DrawTexture(twod, tileGetTexture(TILE_THREEDEE), x-5, origin.Y+57, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_ScaleX, 0.253, DTA_ScaleY, 0.253, DTA_CenterOffset, true, TAG_DONE); } else if (isRR()) { - rotatesprite_fs(int(origin.X * 65536) + ((160 + 5) << 16), int(origin.Y * 65536) + ((24) << 16), 23592L, 0, TILE_INGAMEDUKETHREEDEE, 0, 0, 10); + DrawTexture(twod, tileGetTexture(TILE_INGAMEDUKETHREEDEE), x+5, origin.Y + 24, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_ScaleX, 0.36, DTA_ScaleY, 0.36, DTA_CenterOffset, true, TAG_DONE); } else { - rotatesprite_fs(int(origin.X * 65536) + (160<<16), int(origin.Y * 65536) + ((28)<<16), 65536L,0,TILE_INGAMEDUKETHREEDEE,0,0,10); - if (PLUTOPAK) // JBF 20030804 - rotatesprite_fs(int(origin.X * 65536) + ((160+100)<<16), int(origin.Y * 65536) + (36<<16), 65536L,0,TILE_PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8); + DrawTexture(twod, tileGetTexture(TILE_INGAMEDUKETHREEDEE), x, origin.Y + 29, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_CenterOffset, true, TAG_DONE); + if (PLUTOPAK) + { + int light = 224 + 31 * sin(int(totalclock) / 40.); + PalEntry pe(255, light, light, light); + DrawTexture(twod, tileGetTexture(TILE_PLUTOPAKSPRITE + 2), x + 100, origin.Y + 36, DTA_FullscreenScale, 3, DTA_VirtualWidth, 320, DTA_VirtualHeight, 200, DTA_Color, pe, DTA_CenterOffset, true, TAG_DONE); + } } } @@ -291,51 +299,25 @@ void GameInterface::StartGame(FNewGameStartup& gs) int32_t skillsound = PISTOL_BODYHIT; soundEngine->StopAllChannels(); + + static const short sounds_d[] = { JIBBED_ACTOR6, BONUS_SPEECH1, DUKE_GETWEAPON2, JIBBED_ACTOR5, JIBBED_ACTOR5 }; + static const short sounds_r[] = { 427, 428, 196, 195, 197 }; + if (gs.Skill >=0 && gs.Skill <= 5) skillsound = isRR()? sounds_r[gs.Skill] : sounds_d[gs.Skill]; - if (!DEER) + ud.m_player_skill = gs.Skill + 1; + if (menu_sounds && skillsound >= 0 && SoundEnabled()) { + S_PlaySound(skillsound, CHAN_AUTO, CHANF_UI); - switch (gs.Skill) + while (S_CheckSoundPlaying(skillsound)) { - case 0: - skillsound = isRR() ? 427 : JIBBED_ACTOR6; - break; - case 1: - skillsound = isRR() ? 428 : BONUS_SPEECH1; - break; - case 2: - skillsound = isRR() ? 196 : DUKE_GETWEAPON2; - break; - case 3: - skillsound = isRR() ? 195 : JIBBED_ACTOR5; - break; - case 4: - skillsound = isRR() ? 197 : JIBBED_ACTOR5; // Does not exist in DN3D. - break; + S_Update(); + G_HandleAsync(); } - ud.m_player_skill = gs.Skill + 1; - if (menu_sounds && skillsound >= 0 && SoundEnabled()) - { - S_PlaySound(skillsound, CHAN_AUTO, CHANF_UI); - - while (S_CheckSoundPlaying(skillsound)) - { - S_Update(); - G_HandleAsync(); - } - } - ud.m_respawn_monsters = (gs.Skill == 3); - ud.m_volume_number = gs.Episode; - m_level_number = gs.Level; - } - else - { - ud.m_player_skill = 1; - ud.m_respawn_monsters = 0; - ud.m_volume_number = 0; - m_level_number = gs.Episode; - g_player[myconnectindex].ps->dhat61f = gs.Skill; } + ud.m_respawn_monsters = (gs.Skill == 3); + ud.m_volume_number = gs.Episode; + m_level_number = gs.Level; ud.m_monsters_off = ud.monsters_off = 0; ud.m_respawn_items = 0; @@ -367,29 +349,14 @@ void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text) void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position, bool bg) { if (bg) Menu_DrawBackground(origin); - else + else if (!isRR()) { - // Only used for the confirmation screen. - int lines = 1; - for (int i = 0; text[i]; i++) if (text[i] == '\n') lines++; - int height = lines * SmallFont->GetHeight(); - position -= height >> 17; - if (!isRR()) Menu_DrawCursor(160, 130, 1, false); + Menu_DrawCursor(160, 130, 1, false); } - G_ScreenText(MF_Bluefont.tilenum, int((origin.X + 160) * 65536), int((origin.Y + position) * 65536), MF_Bluefont.zoom, 0, 0, text, 0, MF_Bluefont.pal, - 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, - MF_Bluefont.textflags | TEXT_XCENTER, 0, 0, xdim - 1, ydim - 1); + ::GameInterface::DrawCenteredTextScreen(origin, text, position, bg); } -void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam) -{ - if (isRR()) - rotatesprite_fs(int(origin.X * 65536) + (260<<16), int(origin.Y * 65536) + ((24+(tilesiz[TILE_APLAYER].y>>2))<<16), 24576L,0,3845+36-((((8-((int32_t) totalclock>>4)))&7)*5),0,onteam ? G_GetTeamPalette(playerteam) : G_CheckPlayerColor(playercolor),10); - else - rotatesprite_fs(int(origin.X * 65536) + (260<<16), int(origin.Y * 65536) + ((24+(tilesiz[TILE_APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,onteam ? G_GetTeamPalette(playerteam) : G_CheckPlayerColor(playercolor),10); -} - void GameInterface::QuitToTitle() { g_player[myconnectindex].ps->gm = MODE_DEMO; diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 7c2290583..fe894a34a 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -212,10 +212,10 @@ struct GameInterface : ::GameInterface void StartGame(FNewGameStartup& gs) override; FSavegameInfo GetSaveSig() override; void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) override; + double SmallFontScale() override { return isRR() ? 0.5 : 1.; } void DrawMenuCaption(const DVector2& origin, const char* text) override; bool SaveGame(FSaveGameNode*) override; bool LoadGame(FSaveGameNode*) override; - void DrawPlayerSprite(const DVector2& origin, bool onteam) override; void QuitToTitle() override; FString GetCoordString() override; int GetStringTile(int font, const char* t, int f) override;