From a95340433153b23a4cfdff6b29dc880ba277c689 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 7 Oct 2020 23:22:29 +0200 Subject: [PATCH] - SW's text menus done. This also copies the Build texture animation info into the texture manager so that the 2D code can access it through existing interfaces. --- source/blood/src/globals.cpp | 8 ++ source/core/gamecontrol.cpp | 1 + source/core/mainloop.cpp | 1 + source/core/textures/buildtiles.cpp | 21 ++++ source/core/textures/buildtiles.h | 1 + source/sw/src/d_menu.cpp | 92 ++--------------- source/sw/src/game.h | 1 - source/sw/src/menus.h | 4 - source/sw/src/namelist.h | 4 + wadsrc/static/menudef.txt | 57 +++++------ wadsrc/static/zscript/games/sw/ui/menu.zs | 119 +++++++++++++++++++++- 11 files changed, 187 insertions(+), 122 deletions(-) diff --git a/source/blood/src/globals.cpp b/source/blood/src/globals.cpp index 50d02ab04..7f52a50ed 100644 --- a/source/blood/src/globals.cpp +++ b/source/blood/src/globals.cpp @@ -55,4 +55,12 @@ void _SetErrorLoc(const char *pzFile, int nLine) _line = nLine; } +// by NoOne: show warning msgs in game instead of throwing errors (in some cases) +void _consoleSysMsg(const char* pzFormat, ...) { + + va_list args; + va_start(args, pzFormat); + VPrintf(PRINT_LOW, TEXTCOLOR_RED "%s\n", args); +} + END_BLD_NS diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 79afae1e8..306d5dfb2 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -1841,6 +1841,7 @@ static const gamefilter games[] = { { "ShadowWarrior", GAMEFLAG_SW}, { "Exhumed", GAMEFLAG_POWERSLAVE | GAMEFLAG_EXHUMED}, { "Worldtour", GAMEFLAG_WORLDTOUR}, + { "Shareware", GAMEFLAG_SHAREWARE}, }; bool validFilter(const char* str) diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 7262dc428..cd9508a41 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -342,6 +342,7 @@ void Display() } screen->FrameTime = I_msTimeFS(); + tileUpdateAnimations(); screen->BeginFrame(); twodpsp.Clear(); twodpsp.SetSize(screen->GetWidth(), screen->GetHeight()); diff --git a/source/core/textures/buildtiles.cpp b/source/core/textures/buildtiles.cpp index 2d15b8f9a..7ddd2a4cf 100644 --- a/source/core/textures/buildtiles.cpp +++ b/source/core/textures/buildtiles.cpp @@ -1028,6 +1028,27 @@ bool tileEqualTo(int me, int other) // //=========================================================================== +void tileUpdateAnimations() +{ + for (int i = 0; i < MAXTILES; i++) + { + if (picanm[i].sf & PICANM_ANIMTYPE_MASK) + { + int j = i + animateoffs(i, 0); + + auto id1 = TileFiles.tiledata[i].texture->GetID(); + auto id2 = TileFiles.tiledata[j].texture->GetID(); + TexMan.SetTranslation(id1, id2); + } + } +} + +//=========================================================================== +// +// Picks a texture for rendering for a given tilenum/palette combination +// +//=========================================================================== + bool PickTexture(int picnum, FGameTexture* tex, int paletteid, TexturePick& pick) { diff --git a/source/core/textures/buildtiles.h b/source/core/textures/buildtiles.h index 99c461a9c..d8e445422 100644 --- a/source/core/textures/buildtiles.h +++ b/source/core/textures/buildtiles.h @@ -523,6 +523,7 @@ inline FGameTexture* tileGetTexture(int tile, bool animate = false) } bool tileEqualTo(int me, int other); +void tileUpdateAnimations(); bool PickTexture(int picnum, FGameTexture* tex, int paletteid, TexturePick& pick); diff --git a/source/sw/src/d_menu.cpp b/source/sw/src/d_menu.cpp index 0b330390b..2a7198f53 100644 --- a/source/sw/src/d_menu.cpp +++ b/source/sw/src/d_menu.cpp @@ -49,6 +49,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamestate.h" #include "raze_music.h" #include "v_draw.h" +#include "vm.h" #include "../../glbackend/glbackend.h" @@ -63,92 +64,21 @@ BEGIN_SW_NS // //---------------------------------------------------------------------------- -#if 0 -class SWMainMenu : public DListMenu -{ - void Ticker() override - { - // Dynamically enable and disable the save option - for (unsigned e = 0; e < mDesc->mItems.Size(); ++e) - { - auto entry = mDesc->mItems[e]; - if (entry->GetAction(nullptr) == NAME_Savegamemenu) - { - entry->mEnabled = gi->CanSave(); - } - } - } - - void PreDraw() override - { - DrawTexture(twod, tileGetTexture(pic_shadow_warrior), 160, 15, DTA_FullscreenScale, FSMode_Fit320x200, - DTA_CenterOffsetRel, true, DTA_Color, 0xfff0f0f0, TAG_DONE); - } -}; - static bool DidOrderSound; static int zero = 0; -class SWOrderMenu : public DImageScrollerMenu + +DEFINE_ACTION_FUNCTION(_SWMenuDelegate, PlayOrderSound) { -public: - SWOrderMenu() + if (SW_SHAREWARE && !DidOrderSound) { - if (SW_SHAREWARE && !DidOrderSound) - { - DidOrderSound = true; - int choose_snd = STD_RANDOM_RANGE(1000); - if (choose_snd > 500) - PlaySound(DIGI_WANGORDER1, v3df_dontpan, CHAN_BODY, CHANF_UI); - else - PlaySound(DIGI_WANGORDER2, v3df_dontpan, CHAN_BODY, CHANF_UI); - } + DidOrderSound = true; + int choose_snd = STD_RANDOM_RANGE(1000); + if (choose_snd > 500) + PlaySound(DIGI_WANGORDER1, v3df_dontpan, CHAN_BODY, CHANF_UI); + else + PlaySound(DIGI_WANGORDER2, v3df_dontpan, CHAN_BODY, CHANF_UI); } -}; -#endif - -//---------------------------------------------------------------------------- -// -// Menu related game interface functions -// -//---------------------------------------------------------------------------- - -void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) -{ -#if 0 - switch (fontnum) - { - case NIT_BigFont: - if (flags & LMF_Centered) xpos -= BigFont->StringWidth(text) * 0.5; - DrawText(twod, BigFont, CR_UNDEFINED, xpos, ypos, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_Color, state == NIT_InactiveState? 0xff505050 : 0xffffffff, TAG_DONE); - break; - - case NIT_SmallFont: - default: - MNU_DrawString(short(xpos), short(ypos), text, state == NIT_InactiveState? 20 : 0, 16, (flags & LMF_Centered) ? 0 : -1); - break; - } - if (state == NIT_SelectedState) - { - int x = int(xpos), y = int(ypos); - int scale = 65536; - short w,h; - - if (text) - { - scale /= 2; - x -= mulscale17(tilesiz[pic_yinyang].x,scale) + 2; - y += 4; - } - else - { - scale -= (1<<13); - x -= ((tilesiz[pic_yinyang].x) / 2) - 3; - y += 8; - } - DrawTexture(twod, tileGetTexture(pic_yinyang, true), x, y, DTA_FullscreenScale, FSMode_Fit320x200, - DTA_CenterOffset, true, DTA_Color, 0xfff0f0f0, DTA_ScaleX, scale / 65536., DTA_ScaleY, scale / 65536., TAG_DONE); - } -#endif + return 0; } void GameInterface::QuitToTitle() diff --git a/source/sw/src/game.h b/source/sw/src/game.h index c9b20b9a7..f26663419 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -2186,7 +2186,6 @@ struct GameInterface : ::GameInterface void FreeGameData() override; void FreeLevelData() override; bool GenerateSavePic() override; - void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) override; void MenuOpened() override; void MenuSound(EMenuSounds snd) override; void MenuClosed() override; diff --git a/source/sw/src/menus.h b/source/sw/src/menus.h index 0cd4b00d3..7105d669b 100644 --- a/source/sw/src/menus.h +++ b/source/sw/src/menus.h @@ -35,10 +35,6 @@ BEGIN_SW_NS void MNU_DrawString(int x, int y, const char* string, int shade, int pal, int align = -1); void MNU_DrawSmallString(int x, int y, const char* string, int shade, int pal, int align = -1, double alpha = 1); -#define pic_yinyang 2870 -#define pic_shadow_warrior 2366 - - END_SW_NS #endif diff --git a/source/sw/src/namelist.h b/source/sw/src/namelist.h index 84833a60f..36ba0d464 100644 --- a/source/sw/src/namelist.h +++ b/source/sw/src/namelist.h @@ -155,3 +155,7 @@ x(BLUE_CARD, 1767) x(RED_CARD, 1771) x(GREEN_CARD, 1775) x(YELLOW_CARD, 1779) + +x(YINYANG, 2870) +x(SHADOW_WARRIOR, 2366) + diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 91ba12cdd..3c6081e6d 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -37,24 +37,22 @@ LISTMENU "MainMenu" } ifgame(ShadowWarrior) { - /* Position 55, 32 Linespacing 17 - NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" - NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" - NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" - NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" - //NativeTextItem "$MNU_COOLSTUFF", "h", "HelpMenu" // Perfectly useless retro ads. :D - ifshareware(false) + SWLogo + SWTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" + SWTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + SWTextItem "$MNU_SAVEGAME", "s", "none" + SWTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + ifnotgame (shareware) { - NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + SWTextItem "$MNU_CREDITS", "c", "CreditsMenu" } else { - NativeTextItem "$MNU_HOWTOORDER", "h", "CreditsMenu" + SWTextItem "$MNU_HOWTOORDER", "h", "CreditsMenu" } - NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" - */ + SWTextItem "$MNU_QUITGAME", "q", "QuitMenu" } ifgame(Exhumed) { @@ -109,25 +107,26 @@ LISTMENU "IngameMenu" BloodTextItem "$MNU_QUITGAME", "q", "QuitMenu" BloodDripDrawer } - /* ifgame(ShadowWarrior) { Position 55, 32 Linespacing 17 - NativeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" - NativeTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" - NativeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" - NativeTextItem "$MNU_OPTIONS", "o", "OptionsMenu" - ifshareware(false) + SWLogo + SWTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" + SWTextItem "$MNU_LOADGAME", "l", "LoadGameMenu" + SWTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" + SWTextItem "$MNU_OPTIONS", "o", "OptionsMenu" + ifnotgame (shareware) { - NativeTextItem "$MNU_CREDITS", "c", "CreditsMenu" + SWTextItem "$MNU_CREDITS", "c", "CreditsMenu" } else { - NativeTextItem "$MNU_HOWTOORDER", "h", "CreditsMenu" + SWTextItem "$MNU_HOWTOORDER", "h", "CreditsMenu" } - NativeTextItem "$MNU_QUITGAME", "q", "QuitMenu" + SWTextItem "$MNU_QUITGAME", "q", "QuitMenu" } + /* ifgame(Exhumed) { Position 160, 65 @@ -164,14 +163,12 @@ LISTMENU "EpisodeMenu" CaptionItem "$MNU_EPISODES" BloodDripDrawer } - /* ifgame(ShadowWarrior) { - caption "$MNU_EPISODES" + CaptionItem "$MNU_EPISODES" Position 35, 32 Linespacing 17 } - */ } LISTMENU "SkillMenu" @@ -190,14 +187,12 @@ LISTMENU "SkillMenu" CaptionItem "$MNU_DIFFICULTY" BloodDripDrawer } - /* ifgame(ShadowWarrior) { - caption "$MNU_DIFFICULTY" + CaptionItem "$MNU_DIFFICULTY" Position 35, 32 Linespacing 17 } - */ } //------------------------------------------------------------------------------------------- @@ -211,8 +206,8 @@ ImageScroller "HelpMenu" { ifgame(Duke, Nam, WW2GI) { - ImageItem "#3280", 400 - ImageItem "#2445", 401 + ImageItem "#3280" + ImageItem "#2445" class "$.ImageScrollerMenu" ifgame(Duke, Nam, WW2GI) { @@ -268,9 +263,9 @@ ImageScroller "CreditsMenu" { ifgame(Duke, Nam, WW2GI) { - ImageItem "#2504", 990 - ImageItem "#2505", 991 - ImageItem "#2506", 992 + ImageItem "#2504" + ImageItem "#2505" + ImageItem "#2506" animatedtransition class "Duke.ImageScrollerMenu" } diff --git a/wadsrc/static/zscript/games/sw/ui/menu.zs b/wadsrc/static/zscript/games/sw/ui/menu.zs index 2ae2c8766..5bcb7e183 100644 --- a/wadsrc/static/zscript/games/sw/ui/menu.zs +++ b/wadsrc/static/zscript/games/sw/ui/menu.zs @@ -7,21 +7,130 @@ class SWMenuDelegate : RazeMenuDelegate let texid = TexMan.CheckForTexture("MENUBAR"); let texsize = TexMan.GetScaledSize(texid); let fonth = font.GetGlyphHeight("A"); - let fontscale = 0.7; // at full 1.0 scale the font is too large + let fontscale = 1.; if (drawit) { int width = font.StringWidth(title) * fontscale; + double scalex = 1.; if (texid.isValid()) { - double scalex = 1.; // Expand the box if the text is longer - if (texsize.X - 60 < width) scalex = width / (texsize.X - 60); - screen.DrawTexture(texid, false, 160, 20, DTA_FullscreenScale, FSMode_Fit320x200Top, DTA_CenterOffsetRel, true, DTA_ScaleX, scalex); + if (texsize.X - 60 < width) + { + // First start squashing the font down to 0.7x the original width. + fontscale = (texsize.X - 60) / width; + if (fontscale < 0.7) + { + // If that is not enough, extend the box. + fontscale = 0.7; + width *= 0.7; + scalex = width / (texsize.X - 60); + } + else width *= fontscale; + } + screen.DrawTexture(texid, false, 160, 15, DTA_FullscreenScale, FSMode_Fit320x200Top, DTA_CenterOffsetRel, true, DTA_ScaleX, scalex); } - screen.DrawText(font, Font.CR_UNTRANSLATED, 160 - width / 2, 22 - fonth / 2, title, DTA_FullscreenScale, FSMode_Fit320x200Top, DTA_ScaleX, fontscale); + screen.DrawText(font, Font.CR_UNTRANSLATED, 160 - width / 2, 17 - fonth / 2, title, DTA_FullscreenScale, FSMode_Fit320x200Top, DTA_ScaleX, fontscale); } double fx, fy, fw, fh; [fx, fy, fw, fh] = Screen.GetFullscreenRect(320, 200, FSMode_ScaleToFit43Top); int h = texid.isValid()? texsize.Y : fonth; return int((y+h) * fh / 200); // This must be the covered height of the header in true pixels. } + + override bool DrawSelector(ListMenuDescriptor desc) + { + let item = desc.mItems[desc.mSelectedItem]; + let x = item.GetX(); + let y = item.GetY(); + + + let tex = TexMan.CheckForTexture("YINYANG"); + + x -= TexMan.GetSize(tex) / 4 + 2; + y += 4; + + Screen.DrawTexture(tex, true, x, y, DTA_FullscreenScale, FSMode_Fit320x200, + DTA_CenterOffset, true, DTA_Color, 0xfff0f0f0, DTA_ScaleX, 0.5, DTA_ScaleY, 0.5); + return true; + } + + //native static void PlayOrderSound(); } + +//============================================================================= +// +// logo +// +//============================================================================= + +class ListMenuItemSWLogo : ListMenuItem +{ + void Init(ListMenuDescriptor desc) + { + Super.Init(0, 0); + } + + override void Draw(bool selected, ListMenuDescriptor desc) + { + screen.DrawTexture(TexMan.CheckForTexture("shadow_warrior"), false, 160, 15, DTA_FullscreenScale, FSMode_Fit320x200, DTA_CenterOffsetRel, true, DTA_Color, 0xfff0f0f0); + } +} + +//============================================================================= +// +// SW order sound +// +//============================================================================= +/* +class ListMenuItemOrderSound : ListMenuItem +{ + void Init(ListMenuDescriptor desc) + { + Super.Init(0, 0); + } + + override void Drawer() + { + if (mEnabled) SWMenuDelegate.PlayOrderSound(); + mEnabled = 0; + } +} +*/ + +//============================================================================= +// +// text item +// +//============================================================================= + +class ListMenuItemSWTextItem : ListMenuItemTextItem +{ + void Init(ListMenuDescriptor desc, String text, String hotkey, Name child, int param = 0) + { + Super.Init(desc, text, hotkey, child, param); + if (child == 'none') mEnabled = -1; + } + + void InitDirect(double x, double y, int height, String hotkey, String text, Font font, int color, int color2, Name child, int param = 0) + { + Super.InitDirect(x, y, height, hotkey, text, font, color, color2, child, param); + } + + override void Draw(bool selected, ListMenuDescriptor desc) + { + let gamefont = generic_ui ? NewSmallFont : BigFont; + int cr = generic_ui? Font.CR_RED : Font.CR_UNDEFINED; + double scalex = 1.; + + + // The font here is very bulky and may cause problems with localized content. Account for that by squashing the text if needed. + int length = gamefont.StringWidth(mText); + if (mXpos + length > 320) + { + scalex = (315. - mXpos) / length; + } + + Screen.DrawText(BigFont, cr, mXpos, mYpos, mText, DTA_FullscreenScale, FSMode_Fit320x200, DTA_Color, !Selectable()? 0xff505050 : 0xffffffff, DTA_ScaleX, scalex); + } +} +