Merge branch 'menu_for_real' of https://github.com/coelckers/demolition into menu_for_real

# Conflicts:
#	source/common/menu/loadsavemenu.cpp
#	source/duke3d/src/d_menu.cpp
#	source/rr/src/d_menu.cpp
This commit is contained in:
Christoph Oelckers 2019-11-30 01:06:37 +01:00
commit b3c335cd1d
12 changed files with 303 additions and 159 deletions

View file

@ -185,14 +185,10 @@ struct FSavegameInfo
int currentsavever;
};
enum EMenuSounds : int;
struct GameInterface
{
enum EMenuSounds
{
SelectSound,
ChooseSound
};
virtual ~GameInterface() {}
virtual void faketimerhandler() {} // This is a remnant of older versions, but Blood backend has not updated yet.
virtual int app_main() = 0;

View file

@ -133,7 +133,7 @@ bool DListMenu::Responder (event_t *ev)
{
mDesc->mSelectedItem = i;
SelectionChanged();
gi->MenuSound(GameInterface::SelectSound);
M_MenuSound(CursorSound);
return true;
}
}
@ -143,7 +143,7 @@ bool DListMenu::Responder (event_t *ev)
{
mDesc->mSelectedItem = i;
SelectionChanged();
gi->MenuSound(GameInterface::SelectSound);
M_MenuSound(CursorSound);
return true;
}
}
@ -171,7 +171,7 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller)
}
while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt);
SelectionChanged();
gi->MenuSound(GameInterface::SelectSound);
M_MenuSound(CursorSound);
return true;
case MKEY_Down:
@ -181,13 +181,13 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller)
}
while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt);
SelectionChanged();
gi->MenuSound(GameInterface::SelectSound);
M_MenuSound(CursorSound);
return true;
case MKEY_Enter:
if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate(mDesc->mMenuName))
{
gi->MenuSound(GameInterface::ChooseSound);
M_MenuSound(AdvanceSound);
}
return true;

View file

@ -195,8 +195,8 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller)
{
if (scriptID != 0)
{
M_MenuSound(DMenu::CurrentMenu->mParentMenu? BackSound : CloseSound);
Close();
//S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE);
return true;
}
}
@ -473,15 +473,15 @@ bool M_SetMenu(FName menu, int param, FName caller)
const char *msg = AllSkills[param].MustConfirmText;
if (*msg==0) msg = GStrings("NIGHTMARE");
M_StartMessage (msg, 0, NAME_StartgameConfirmed);
M_StartMessage (msg, 0, -1, NAME_StartgameConfirmed);
return;
}
case NAME_Savegamemenu:
if (!usergame || (players[consoleplayer].health <= 0 && !multiplayer) || gamestate != GS_LEVEL)
if (gi->canSave())
{
// cannot save outside the game.
M_StartMessage (GStrings("SAVEDEAD"), 1);
M_StartMessage (GStrings("SAVEDEAD"), 1, -1);
return;
}
#endif
@ -861,6 +861,18 @@ void Menu_Close(int playerid)
{
M_ClearMenus();
}
//=============================================================================
//
//
//
//=============================================================================
CVAR(Bool, menu_sounds, true, CVAR_ARCHIVE) // added mainly because RR's sounds are so supremely annoying.
void M_MenuSound(EMenuSounds snd)
{
if (menu_sounds) gi->MenuSound(snd);
}
//=============================================================================
//
//

View file

@ -92,10 +92,20 @@ enum EMenuState : int
MENU_OnNoPause, // Menu is opened but does not pause the game
};
enum EMenuSounds : int
{
CursorSound,
AdvanceSound,
BackSound,
CloseSound,
PageSound
ChangeSound
};
struct event_t;
class FTexture;
class FFont;
enum EColorRange;
enum EColorRange : int;
class FPlayerClass;
class FKeyBindings;
@ -558,7 +568,14 @@ protected:
FString mLabel;
bool mCentered = false;
void drawLabel(int indent, int y, EColorRange color, bool grayed = false);
void drawText(int x, int y, int color, const char * text, bool grayed = false);
int drawLabel(int indent, int y, EColorRange color, bool grayed = false);
void drawValue(int indent, int y, int color, const char *text, bool grayed = false);
int CursorSpace();
public:
FOptionMenuItem(const char *text, FName action = NAME_None, bool center = false)
@ -639,6 +656,10 @@ public:
}
};
FFont *OptionFont();
int OptionHeight();
int OptionWidth(const char * s);
void DrawOptionText(int x, int y, int color, const char *text, bool grayed = false);
//=============================================================================
//
@ -716,8 +737,9 @@ int M_GetDefaultSkill();
void M_StartControlPanel (bool makeSound);
bool M_SetMenu(FName menu, int param = -1, FName callingMenu = NAME_None);
void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave);
void M_StartMessage(const char *message, int messagemode, FName action = NAME_None);
void M_StartMessage(const char *message, int messagemode, int scriptId, FName action = NAME_None);
void M_UnhideCustomMenu(int menu, int itemmask);
void M_MenuSound(EMenuSounds snd);
void I_SetMouseCapture();

View file

@ -601,6 +601,19 @@ static void ParseImageScrollerBody(FScanner &sc, FImageScrollerDescriptor *desc)
}
desc->mItems.Push(item);
}
else if (sc.Compare("qavanimationitem"))
{
if (!(g_gameType & GAMEFLAG_BLOOD))
{
I_Error("QAV animations not available!"); // these (currently) only exist in Blood.
}
FImageScrollerDescriptor::ScrollerItem item;
sc.GetString();
item.text = sc.String;
item.type = -1;
item.scriptID = INT_MAX;
desc->mItems.Push(item);
}
else if (sc.Compare("animatedtransition"))
{
desc->mFlags |= LMF_Animate;

View file

@ -345,7 +345,7 @@ bool DMessageBoxMenu::MouseEvent(int type, int x, int y)
//
//=============================================================================
void M_StartMessage(const char *message, int messagemode, FName action)
void M_StartMessage(const char *message, int messagemode, int scriptId, FName action)
{
if (DMenu::CurrentMenu == NULL)
{
@ -354,6 +354,7 @@ void M_StartMessage(const char *message, int messagemode, FName action)
}
DMenu *newmenu = new DMessageBoxMenu(DMenu::CurrentMenu, message, messagemode, false, action);
newmenu->mParentMenu = DMenu::CurrentMenu;
newmenu->scriptID = scriptId;
M_ActivateMenu(newmenu);
}

View file

@ -53,15 +53,27 @@
//
//=============================================================================
void M_DrawConText (int color, int x, int y, const char *str)
FFont *OptionFont()
{
DrawText (&twod, ConFont, color, x, y, str,
DTA_CellX, 8 * CleanXfac_1,
DTA_CellY, 8 * CleanYfac_1,
TAG_DONE);
return NewSmallFont;
}
int OptionHeight()
{
return OptionFont()->GetHeight();
}
int OptionWidth(const char * s)
{
return OptionFont()->StringWidth(s);
}
void DrawOptionText(int x, int y, int color, const char *text, bool grayed)
{
text = *text == '$'? GStrings(text+1) : text;
PalEntry overlay = grayed? PalEntry(96,48,0,0) : PalEntry(0,0,0);
DrawText (&twod, OptionFont(), color, x, y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay);
}
//=============================================================================
//
@ -323,7 +335,7 @@ bool DOptionMenu::MenuEvent (int mkey, bool fromcontroller)
if (mDesc->mSelectedItem != startedAt)
{
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
M_MenuSound(CursorSound);
}
return true;
}
@ -355,7 +367,8 @@ bool DOptionMenu::MouseEvent(int type, int x, int y)
if (yline != mDesc->mSelectedItem)
{
mDesc->mSelectedItem = yline;
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
//M_MenuSound(CursorSound); too noisy
}
mDesc->mItems[yline]->MouseEvent(type, x, y);
return true;
@ -390,21 +403,9 @@ void DOptionMenu::Drawer ()
{
int y = mDesc->mPosition;
if (y <= 0)
if (mDesc->mTitle.IsNotEmpty())
{
if (BigFont && mDesc->mTitle.IsNotEmpty())
{
const char *tt = mDesc->mTitle;
if (*tt == '$') tt = GStrings(tt+1);
DrawText (&twod, BigFont, OptionSettings.mTitleColor,
(screen->GetWidth() - BigFont->StringWidth(tt) * CleanXfac_1) / 2, 10*CleanYfac_1,
tt, DTA_CleanNoMove_1, true, TAG_DONE);
y = -y + BigFont->GetHeight();
}
else
{
y = -y;
}
gi->DrawMenuCaption(origin, mDesc->mTitle);
}
mDesc->mDrawTop = y;
int fontheight = OptionSettings.mLinespacing * CleanYfac_1;
@ -445,7 +446,8 @@ void DOptionMenu::Drawer ()
{
if ((((DMenu::MenuTime>>2)%8) < 6) || DMenu::CurrentMenu != this)
{
M_DrawConText(OptionSettings.mFontColorSelection, cur_indent + 3 * CleanXfac_1, y+fontheight-9*CleanYfac_1, "\xd");
DrawOptionText(cur_indent + 3 * CleanXfac_1, y, OptionSettings.mFontColorSelection, "");
//M_DrawConText(OptionSettings.mFontColorSelection, cur_indent + 3 * CleanXfac_1, y+fontheight-9*CleanYfac_1, "\xd");
}
}
}
@ -456,11 +458,13 @@ void DOptionMenu::Drawer ()
if (CanScrollUp)
{
M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop, "\x1a");
DrawOptionText(screen->GetWidth() - 11 * CleanXfac_1, ytop, OptionSettings.mFontColorSelection, "");
//M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop, "\x1a");
}
if (CanScrollDown)
{
M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1, "\x1b");
DrawOptionText(screen->GetWidth() - 11 * CleanXfac_1 , y - 8*CleanYfac_1, OptionSettings.mFontColorSelection, "");
//M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1, "\x1b");
}
Super::Drawer();
}
@ -497,30 +501,40 @@ bool FOptionMenuItem::MouseEvent(int type, int x, int y)
int FOptionMenuItem::GetIndent()
{
if (mCentered)
{
return 0;
}
if (mCentered) return 0;
if (screen->GetWidth() < 640) return screen->GetWidth() / 2;
const char *label = mLabel;
if (*label == '$') label = GStrings(label+1);
return SmallFont->StringWidth(label);
return OptionWidth(label);
}
void FOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool grayed)
void FOptionMenuItem::drawText(int x, int y, int color, const char * text, bool grayed)
{
DrawOptionText(x, y, color, text, grayed);
}
int FOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool grayed)
{
const char *label = mLabel;
if (*label == '$') label = GStrings(label+1);
int overlay = grayed? MAKEARGB(96,48,0,0) : 0;
int x;
int w = SmallFont->StringWidth(label) * CleanXfac_1;
int w = OptionWidth(label) * CleanXfac_1;
if (!mCentered) x = indent - w;
else x = (screen->GetWidth() - w) / 2;
DrawText (&twod, SmallFont, color, x, y, label, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE);
DrawOptionText(x, y, color, label, grayed);
return x;
}
void FOptionMenuItem::drawValue(int indent, int y, int color, const char *text, bool grayed)
{
DrawOptionText(indent + CursorSpace(), y, color, text, grayed);
}
int FOptionMenuItem::CursorSpace()
{
return (14 * CleanXfac_1);
}
void FOptionMenuDescriptor::CalcIndent()
{

View file

@ -57,21 +57,48 @@ public:
mParam = param;
}
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override
{
drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColorMore);
return indent;
}
bool Activate()
bool Activate(FName caller) override
{
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE);
M_MenuSound(CursorSound);
M_SetMenu(mAction, mParam);
return true;
}
};
//=============================================================================
//
// opens a submenu, command is a submenu name
//
//=============================================================================
class FOptionMenuItemLabeledSubmenu : public FOptionMenuItemSubmenu
{
FBaseCVar *mLabelCVar;
FOptionMenuItemLabeledSubmenu(const char * label, FBaseCVar *labelcvar, FName command, int param = 0)
: FOptionMenuItemSubmenu(label, command, param)
{
mLabelCVar = labelcvar;
}
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override
{
drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor);
auto text = mLabelCVar->GetHumanString();
if (text[0] == 0) text = GStrings("notset");
drawValue(indent, y, OptionSettings.mFontColorValue, text);
return indent;
}
};
//=============================================================================
//
// Executes a CCMD, action is a CCMD name
@ -86,9 +113,9 @@ public:
{
}
bool Activate()
bool Activate(FName caller) override
{
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE);
M_MenuSound(AdvanceSound);
C_DoCommand(mAction);
return true;
}
@ -104,13 +131,17 @@ public:
class FOptionMenuItemSafeCommand : public FOptionMenuItemCommand
{
// action is a CCMD
FString mPrompt;
int mScriptId; // shouldn't be used, but just in case.
public:
FOptionMenuItemSafeCommand(const char *label, const char *menu)
FOptionMenuItemSafeCommand(const char *label, const char *menu, const char *prompt = nullptr, int scriptid = INT_MAX)
: FOptionMenuItemCommand(label, menu)
{
mPrompt = prompt;
mScriptId = scriptid;
}
bool MenuEvent (int mkey, bool fromcontroller)
bool MenuEvent (int mkey, bool fromcontroller) override
{
if (mkey == MKEY_MBYes)
{
@ -120,9 +151,15 @@ public:
return FOptionMenuItemCommand::MenuEvent(mkey, fromcontroller);
}
bool Activate()
bool Activate(FName caller) override
{
M_StartMessage("Do you really want to do this?", 0);
auto msg = mPrompt.IsNotEmpty()? mPrompt.GetChars() : "$SAFEMESSAGE";
if (*msg == '$') msg = GStrings(msg+1);
auto actionLabel = mLabel.GetChars();
if (*actionLabel == '$') actionLabel = GStrings(actionLabel+1);
FStringf FullString("%s%s%s\n\n%s", TEXTCOLOR_WHITE, actionLabel, TEXTCOLOR_NORMAL, msg);
M_StartMessage(FullString, 0, mScriptId);
return true;
}
};
@ -155,7 +192,7 @@ public:
mCenter = center;
}
bool SetString(int i, const char *newtext)
bool SetString(int i, const char *newtext) override
{
if (i == OP_VALUES)
{
@ -179,19 +216,16 @@ public:
virtual void SetSelection(int Selection) = 0;
//=============================================================================
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override
{
bool grayed = mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool);
if (mCenter)
{
indent = (screen->GetWidth() / 2);
}
drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed);
drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, isGrayed());
int overlay = grayed? MAKEARGB(96,48,0,0) : 0;
const char *text;
int Selection = GetSelection();
const char *text;
FOptionValues **opt = OptionValues.CheckKey(mValues);
if (Selection < 0 || opt == NULL || *opt == NULL)
{
@ -202,13 +236,13 @@ public:
text = (*opt)->mValues[Selection].Text;
}
if (*text == '$') text = GStrings(text + 1);
DrawText(&twod,SmallFont, OptionSettings.mFontColorValue, indent + CURSORSPACE, y,
text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE);
drawValue(indent, y, OptionSettings.mFontColorValue, text, isGrayed());
return indent;
}
//=============================================================================
bool MenuEvent (int mkey, bool fromcontroller)
bool MenuEvent (int mkey, bool fromcontroller) override
{
FOptionValues **opt = OptionValues.CheckKey(mValues);
if (opt != NULL && *opt != NULL && (*opt)->mValues.Size() > 0)
@ -228,14 +262,19 @@ public:
return FOptionMenuItem::MenuEvent(mkey, fromcontroller);
}
SetSelection(Selection);
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE);
M_MenuSound(ChangeSound);
}
return true;
}
bool Selectable()
virtual bool isGrayed()
{
return !(mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool));
return mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool);
}
bool Selectable() override
{
return !isGrayed();
}
};
@ -258,7 +297,7 @@ public:
}
//=============================================================================
int GetSelection()
int GetSelection() override
{
int Selection = -1;
FOptionValues **opt = OptionValues.CheckKey(mValues);
@ -292,7 +331,7 @@ public:
return Selection;
}
void SetSelection(int Selection)
void SetSelection(int Selection) override
{
UCVarValue value;
FOptionValues **opt = OptionValues.CheckKey(mValues);
@ -333,27 +372,25 @@ public:
menuactive = MENU_WaitKey; // There should be a better way to disable GUI capture...
}
bool TranslateKeyboardEvents()
bool TranslateKeyboardEvents() override
{
return false;
}
void SetMenuMessage(int which)
{
/*
if (mParentMenu->IsKindOf(RUNTIME_CLASS(DOptionMenu)))
DOptionMenu *m = static_cast<DOptionMenu*>(mParentMenu);
if (m)
{
DOptionMenu *m = static_cast<DOptionMenu*>(mParentMenu);
FListMenuItem *it = m->GetItem(NAME_Controlmessage);
if (it != NULL)
{
it->SetValue(0, which);
}
}
*/
}
bool Responder(event_t *ev)
bool Responder(event_t *ev) override
{
if (ev->type == EV_KeyDown)
{
@ -367,7 +404,7 @@ public:
return false;
}
void Drawer()
void Drawer() override
{
mParentMenu->Drawer();
}
@ -395,27 +432,27 @@ public:
//=============================================================================
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override
{
drawLabel(indent, y, mWaiting? OptionSettings.mFontColorHighlight:
drawLabel(indent, y, mWaiting? OptionSettings.mFontColorHighlight:
(selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor));
auto keys = mBindings->GetKeysForCommand(mAction);
auto description = C_NameKeys(keys.Data(), keys.Size());
if (description.IsNotEmpty())
auto binds = mBindings->GetKeysForCommand(mAction);
auto description = C_NameKeys(binds.Data(), binds.Size());
if (description.Len() > 0)
{
M_DrawConText(CR_WHITE, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, description);
drawValue(indent, y, CR_WHITE, description);
}
else
{
DrawText(&twod,SmallFont, CR_BLACK, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, "---",
DTA_CleanNoMove_1, true, TAG_DONE);
drawValue(indent, y, CR_BLACK, "---");
}
return indent;
}
//=============================================================================
bool MenuEvent(int mkey, bool fromcontroller)
bool MenuEvent(int mkey, bool fromcontroller) override
{
if (mkey == MKEY_Input)
{
@ -436,9 +473,9 @@ public:
return false;
}
bool Activate()
bool Activate(FName caller) override
{
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE);
M_MenuSound(AdvanceSound);
mWaiting = true;
DMenu *input = new DEnterKey(DMenu::CurrentMenu, &mInput);
M_ActivateMenu(input);
@ -456,19 +493,19 @@ class FOptionMenuItemStaticText : public FOptionMenuItem
{
EColorRange mColor;
public:
FOptionMenuItemStaticText(const char *label, bool header)
FOptionMenuItemStaticText(const char *label, EColorRange color = CR_UNDEFINED)
: FOptionMenuItem(label, NAME_None, true)
{
mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor;
mColor = color == CR_UNDEFINED? (EColorRange)OptionSettings.mFontColor : color;
}
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override
{
drawLabel(indent, y, mColor);
return -1;
}
bool Selectable()
bool Selectable() override
{
return false;
}
@ -488,25 +525,25 @@ class FOptionMenuItemStaticTextSwitchable : public FOptionMenuItem
int mCurrent;
public:
FOptionMenuItemStaticTextSwitchable(const char *label, const char *label2, FName action, bool header)
FOptionMenuItemStaticTextSwitchable(const char *label, const char *label2, FName action, EColorRange color = CR_UNDEFINED)
: FOptionMenuItem(label, action, true)
{
mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor;
mColor = color == CR_UNDEFINED? (EColorRange)OptionSettings.mFontColor : color;
mAltText = label2;
mCurrent = 0;
}
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override
{
const char *txt = mCurrent? mAltText.GetChars() : mLabel.GetChars();
if (*txt == '$') txt = GStrings(txt + 1);
int w = SmallFont->StringWidth(txt) * CleanXfac_1;
int w = OptionWidth(txt) * CleanXfac_1;
int x = (screen->GetWidth() - w) / 2;
DrawText(&twod,SmallFont, mColor, x, y, txt, DTA_CleanNoMove_1, true, TAG_DONE);
drawText(x, y, mColor, txt);
return -1;
}
bool SetValue(int i, int val)
bool SetValue(int i, int val) override
{
if (i == 0)
{
@ -516,7 +553,7 @@ public:
return false;
}
bool SetString(int i, const char *newtext)
bool SetString(int i, const char *newtext) override
{
if (i == 0)
{
@ -526,7 +563,7 @@ public:
return false;
}
bool Selectable()
bool Selectable() override
{
return false;
}
@ -547,8 +584,8 @@ class FOptionMenuSliderBase : public FOptionMenuItem
int mSliderShort;
public:
FOptionMenuSliderBase(const char *label, double min, double max, double step, int showval)
: FOptionMenuItem(label, NAME_None)
FOptionMenuSliderBase(const char *label, double min, double max, double step, int showval, FName command = NAME_None)
: FOptionMenuItem(label, command)
{
mMin = min;
mMax = max;
@ -566,6 +603,11 @@ public:
// Draw a slider. Set fracdigits negative to not display the current value numerically.
//
//=============================================================================
void DrawSliderElement (int color, int x, int y, const char * str)
{
DrawText (&twod, ConFont, color, x, y, str, DTA_CellX, 16 * CleanXfac_1, DTA_CellY, 16 * CleanYfac_1);
}
void DrawSlider (int x, int y, double min, double max, double cur, int fracdigits, int indent)
{
@ -588,36 +630,36 @@ public:
if (!mSliderShort)
{
M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12");
M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), cy, "\x13");
DrawSliderElement(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12");
DrawSliderElement(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), cy, "\x13");
}
else
{
// On 320x200 we need a shorter slider
M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x12");
M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), cy, "\x13");
DrawSliderElement(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x12");
DrawSliderElement(CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), cy, "\x13");
right -= 5*8*CleanXfac_1;
}
if (fracdigits >= 0 && right + maxlen <= screen->GetWidth())
{
snprintf(textbuf, countof(textbuf), "%.*f", fracdigits, cur);
DrawText(&twod,SmallFont, CR_DARKGRAY, right, y, textbuf, DTA_CleanNoMove_1, true, TAG_DONE);
drawText(right, y, CR_DARKGRAY, textbuf);
}
}
//=============================================================================
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) override
{
drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor);
mDrawX = indent + CURSORSPACE;
mDrawX = indent + CursorSpace();
DrawSlider (mDrawX, y, mMin, mMax, GetSliderValue(), mShowValue, indent);
return indent;
}
//=============================================================================
bool MenuEvent (int mkey, bool fromcontroller)
bool MenuEvent (int mkey, bool fromcontroller) override
{
double value = GetSliderValue();
@ -634,11 +676,11 @@ public:
return FOptionMenuItem::MenuEvent(mkey, fromcontroller);
}
SetSliderValue(clamp(value, mMin, mMax));
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE);
M_MenuSound(ChangeSound);
return true;
}
bool MouseEvent(int type, int x, int y)
bool MouseEvent(int type, int x, int y) override
{
DOptionMenu *lm = static_cast<DOptionMenu*>(DMenu::CurrentMenu);
if (type != DMenu::MOUSE_Click)
@ -651,7 +693,7 @@ public:
}
int slide_left = mDrawX+8*CleanXfac_1;
int slide_right = slide_left + (10*8*CleanXfac_1 >> mSliderShort); // 12 char cells with 8 pixels each.
int slide_right = slide_left + (10*8*CleanXfac_1 >> mSliderShort); // 10 char cells with 8 pixels each.
if (type == DMenu::MOUSE_Click)
{
@ -663,7 +705,7 @@ public:
if (v != GetSliderValue())
{
SetSliderValue(v);
////S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE);
M_MenuSound(ChangeSound);
}
if (type == DMenu::MOUSE_Click)
{
@ -690,7 +732,7 @@ public:
mCVar = FindCVar(menu, NULL);
}
double GetSliderValue()
double GetSliderValue() override
{
if (mCVar != NULL)
{
@ -702,7 +744,7 @@ public:
}
}
void SetSliderValue(double val)
void SetSliderValue(double val) override
{
if (mCVar != NULL)
{
@ -730,12 +772,12 @@ public:
mPVal = pVal;
}
double GetSliderValue()
double GetSliderValue() override
{
return *mPVal;
}
void SetSliderValue(double val)
void SetSliderValue(double val) override
{
*mPVal = (float)val;
}
@ -771,18 +813,15 @@ public:
return GetCVarString();
}
int Draw ( FOptionMenuDescriptor*, int y, int indent, bool selected )
int Draw ( FOptionMenuDescriptor*, int y, int indent, bool selected ) override
{
bool grayed = mGrayCheck != NULL && !( mGrayCheck->GetGenericRep( CVAR_Bool ).Bool );
drawLabel( indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed );
int overlay = grayed? MAKEARGB( 96, 48, 0, 0 ) : 0;
DrawText(&twod, SmallFont, OptionSettings.mFontColorValue, indent + CURSORSPACE, y,
Represent().GetChars(), DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, TAG_DONE );
drawLabel(indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed);
drawValue(indent, y, OptionSettings.mFontColorValue, Represent(), grayed);
return indent;
}
bool GetString ( int i, char* s, int len )
bool GetString ( int i, char* s, int len ) override
{
if ( i == 0 )
{
@ -794,7 +833,7 @@ public:
return false;
}
bool SetString ( int i, const char* s )
bool SetString ( int i, const char* s ) override
{
if ( i == 0 )
{
@ -832,9 +871,9 @@ public:
FOptionMenuFieldBase ( label, menu, graycheck ),
mEntering ( false ) {}
FString Represent()
FString Represent() override
{
FString text = mEntering ? mEditName : GetCVarString();
FString text = mEntering ? mEditName : FString(GetCVarString());
if ( mEntering )
text += '_';
@ -842,28 +881,28 @@ public:
return text;
}
int Draw(FOptionMenuDescriptor*desc, int y, int indent, bool selected)
int Draw(FOptionMenuDescriptor*desc, int y, int indent, bool selected) override
{
if (mEntering)
{
// reposition the text so that the cursor is visible when in entering mode.
FString text = Represent();
int tlen = SmallFont->StringWidth(text) * CleanXfac_1;
int newindent = screen->GetWidth() - tlen - CURSORSPACE;
int newindent = screen->GetWidth() - tlen - CursorSpace();
if (newindent < indent) indent = newindent;
}
return FOptionMenuFieldBase::Draw(desc, y, indent, selected);
}
bool MenuEvent ( int mkey, bool fromcontroller )
bool MenuEvent ( int mkey, bool fromcontroller ) override
{
if ( mkey == MKEY_Enter )
{
//S_Sound( CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE );
strcpy( mEditName, GetCVarString() );
M_MenuSound(AdvanceSound);
mEditName = GetCVarString();
mEntering = true;
//DMenu* input = new DTextEnterMenu ( DMenu::CurrentMenu, mEditName, sizeof mEditName, 2, fromcontroller );
//M_ActivateMenu( input );
DMenu* input = new DTextEnterMenu ( DMenu::CurrentMenu, mEditName, sizeof mEditName, 2, fromcontroller );
M_ActivateMenu( input );
return true;
}
else if ( mkey == MKEY_Input )
@ -889,7 +928,7 @@ public:
private:
bool mEntering;
char mEditName[128];
FString mEditName;
};
//=============================================================================
@ -918,7 +957,7 @@ public:
mStep = 1;
}
bool MenuEvent ( int mkey, bool fromcontroller )
bool MenuEvent ( int mkey, bool fromcontroller ) override
{
if ( mCVar )
{
@ -944,7 +983,7 @@ public:
UCVarValue vval;
vval.Float = value;
mCVar->SetGenericRep( vval, CVAR_Float );
//S_Sound( CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE );
M_MenuSound(ChangeSound);
}
return true;

View file

@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gstrings.h"
#include "version.h"
#include "namesdyn.h"
#include "menus.h"
#include "../../glbackend/glbackend.h"
BEGIN_DUKE_NS
@ -435,17 +436,21 @@ void GameInterface::MenuOpened()
}
}
void GameInterface::MenuSound(::GameInterface::EMenuSounds snd)
void GameInterface::MenuSound(EMenuSounds snd)
{
switch (snd)
{
case SelectSound:
case CursorSound:
S_PlaySound(KICK_HIT);
break;
case ChooseSound:
case AdvanceSound:
S_PlaySound(PISTOL_BODYHIT);
break;
case CloseSound:
S_PlaySound(EXITMENUSOUND);
break;
default:
return;
@ -455,7 +460,6 @@ void GameInterface::MenuSound(::GameInterface::EMenuSounds snd)
void GameInterface::MenuClosed()
{
S_PlaySound(EXITMENUSOUND);
auto& gm = g_player[myconnectindex].ps->gm;
if (gm & MODE_GAME)
@ -503,6 +507,8 @@ void GameInterface::CustomMenuSelection(int menu, int item)
VM_OnEventWithReturn(EVENT_NEWGAMECUSTOM, -1, myconnectindex, menu);
}
EXTERN_CVAR(Bool, menu_sounds)
void GameInterface::StartGame(FGameStartup& gs)
{
int32_t skillsound = PISTOL_BODYHIT;
@ -524,7 +530,7 @@ void GameInterface::StartGame(FGameStartup& gs)
}
ud.m_player_skill = gs.Skill + 1;
ud.skill_voice = S_PlaySound(skillsound);
if (menu_sounds) ud.skill_voice = S_PlaySound(skillsound);
ud.m_respawn_monsters = (gs.Skill == 3);
ud.m_monsters_off = ud.monsters_off = 0;
ud.m_respawn_items = 0;

View file

@ -363,27 +363,29 @@ void GameInterface::MenuOpened()
}
}
void GameInterface::MenuSound(::GameInterface::EMenuSounds snd)
void GameInterface::MenuSound(EMenuSounds snd)
{
switch (snd)
{
case SelectSound:
case CursorSound:
S_PlaySound(RR ? 335 : KICK_HIT);
break;
case ChooseSound:
case AdvanceSound:
S_PlaySound(RR? 341 : PISTOL_BODYHIT);
break;
case CloseSound:
S_PlaySound(EXITMENUSOUND);
break;
default:
return;
}
}
void GameInterface::MenuClosed()
{
S_PlaySound(EXITMENUSOUND);
auto& gm = g_player[myconnectindex].ps->gm;
if (gm & MODE_GAME)
@ -424,6 +426,7 @@ bool GameInterface::CanSave()
return true;
}
EXTERN_CVAR(Bool, menu_sounds)
void GameInterface::StartGame(FGameStartup& gs)
{
int32_t skillsound = PISTOL_BODYHIT;
@ -448,7 +451,7 @@ void GameInterface::StartGame(FGameStartup& gs)
}
ud.m_player_skill = gs.Skill + 1;
g_skillSoundVoice = S_PlaySound(skillsound);
if (menu_sounds) g_skillSoundVoice = S_PlaySound(skillsound);
ud.m_respawn_monsters = (gs.Skill == 3);
ud.m_monsters_off = ud.monsters_off = 0;
ud.m_respawn_items = 0;

View file

@ -160,7 +160,7 @@ struct GameInterface : ::GameInterface
GameStats getStats() override;
void DrawNativeMenuText(int fontnum, int state, int xpos, int ypos, float fontscale, const char* text, int flags);
void MenuOpened() override;
void MenuSound(::GameInterface::EMenuSounds snd) override;
void MenuSound(EMenuSounds snd) override;
void MenuClosed() override;
bool CanSave() override;
void StartGame(FGameStartup& gs) override;

View file

@ -380,6 +380,22 @@ ImageScroller "HelpMenu"
ImageItem "TEXTSTORY", 400
ImageItem "F1HELP", 401
}
ifgame(blood)
{
QAVAnimationItem "Help4"
QAVAnimationItem "Help5"
QAVAnimationItem "Help3"
QAVAnimationItem "Help3b"
}
ifgame(ShadowWarrior)
{
// The menu has no default binding, but if someone tries to open it anyway show the cool retro ads that were shipped with the game. :D
ImageItem "#5262"
ifnotshareware
{
ImageItem "#5261"
}
}
}
//-------------------------------------------------------------------------------------------
@ -395,13 +411,19 @@ ImageScroller "HelpMenu"
ImageScroller "CreditsMenu"
{
ifgame(Duke, Nam, WW2GI, Fury)
ifgame(Duke, Nam, WW2GI)
{
ImageItem "CREDITSTEXT1", 990
ImageItem "CREDITSTEXT2", 991
ImageItem "CREDITSTEXT3", 992
animatedtransition
}
ifgame(fury)
{
// Ion Fury does not have a separate credits menu, so if someone tries to open it anyway, use the same screens as "Help" but start on the one for the credits.
ImageItem "F1HELP", 401
ImageItem "TEXTSTORY", 400
}
ifgame(Redneck)
{
// no point putting this into the string table.
@ -464,6 +486,22 @@ ImageScroller "CreditsMenu"
TextItem "REDNECK RAMPAGE RIDES AGAIN\n(c) 1998 XATRIX ENTERTAINMENT, INC.\n\nREDNECK RAMPAGE RIDES AGAIN\nIS A TRADEMARK OF\nINTERPLAY PRODUCTIONS", 70
animatedtransition
}
ifgame(blood)
{
QAVAnimationItem "Credits"
}
ifgame(ShadowWarrior)
{
ifshareware
{
ImageItem "#5110"
ImageItem "#5112"
}
ImageItem "#5111"
ImageItem "#5118"
ImageItem "#4979"
ImageItem "#5113"
}
}
//-------------------------------------------------------------------------------------------
@ -491,4 +529,4 @@ ListMenu "SaveGameMenu"
Position 0, 40
Class "SaveMenu" // uses its own implementation
}