- 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.
This commit is contained in:
Christoph Oelckers 2020-10-07 23:22:29 +02:00
parent 6041a3355c
commit a953404331
11 changed files with 187 additions and 122 deletions

View file

@ -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

View file

@ -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)

View file

@ -342,6 +342,7 @@ void Display()
}
screen->FrameTime = I_msTimeFS();
tileUpdateAnimations();
screen->BeginFrame();
twodpsp.Clear();
twodpsp.SetSize(screen->GetWidth(), screen->GetHeight());

View file

@ -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)
{

View file

@ -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);

View file

@ -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()

View file

@ -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;

View file

@ -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

View file

@ -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)

View file

@ -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"
}

View file

@ -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);
}
}