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; int currentsavever;
}; };
enum EMenuSounds : int;
struct GameInterface struct GameInterface
{ {
enum EMenuSounds
{
SelectSound,
ChooseSound
};
virtual ~GameInterface() {} virtual ~GameInterface() {}
virtual void faketimerhandler() {} // This is a remnant of older versions, but Blood backend has not updated yet. virtual void faketimerhandler() {} // This is a remnant of older versions, but Blood backend has not updated yet.
virtual int app_main() = 0; virtual int app_main() = 0;

View file

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

View file

@ -195,8 +195,8 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller)
{ {
if (scriptID != 0) if (scriptID != 0)
{ {
M_MenuSound(DMenu::CurrentMenu->mParentMenu? BackSound : CloseSound);
Close(); Close();
//S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE);
return true; return true;
} }
} }
@ -473,15 +473,15 @@ bool M_SetMenu(FName menu, int param, FName caller)
const char *msg = AllSkills[param].MustConfirmText; const char *msg = AllSkills[param].MustConfirmText;
if (*msg==0) msg = GStrings("NIGHTMARE"); if (*msg==0) msg = GStrings("NIGHTMARE");
M_StartMessage (msg, 0, NAME_StartgameConfirmed); M_StartMessage (msg, 0, -1, NAME_StartgameConfirmed);
return; return;
} }
case NAME_Savegamemenu: case NAME_Savegamemenu:
if (!usergame || (players[consoleplayer].health <= 0 && !multiplayer) || gamestate != GS_LEVEL) if (gi->canSave())
{ {
// cannot save outside the game. // cannot save outside the game.
M_StartMessage (GStrings("SAVEDEAD"), 1); M_StartMessage (GStrings("SAVEDEAD"), 1, -1);
return; return;
} }
#endif #endif
@ -861,6 +861,18 @@ void Menu_Close(int playerid)
{ {
M_ClearMenus(); 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 MENU_OnNoPause, // Menu is opened but does not pause the game
}; };
enum EMenuSounds : int
{
CursorSound,
AdvanceSound,
BackSound,
CloseSound,
PageSound
ChangeSound
};
struct event_t; struct event_t;
class FTexture; class FTexture;
class FFont; class FFont;
enum EColorRange; enum EColorRange : int;
class FPlayerClass; class FPlayerClass;
class FKeyBindings; class FKeyBindings;
@ -558,7 +568,14 @@ protected:
FString mLabel; FString mLabel;
bool mCentered = false; 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: public:
FOptionMenuItem(const char *text, FName action = NAME_None, bool center = false) 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); void M_StartControlPanel (bool makeSound);
bool M_SetMenu(FName menu, int param = -1, FName callingMenu = NAME_None); 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_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_UnhideCustomMenu(int menu, int itemmask);
void M_MenuSound(EMenuSounds snd);
void I_SetMouseCapture(); void I_SetMouseCapture();

View file

@ -601,6 +601,19 @@ static void ParseImageScrollerBody(FScanner &sc, FImageScrollerDescriptor *desc)
} }
desc->mItems.Push(item); 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")) else if (sc.Compare("animatedtransition"))
{ {
desc->mFlags |= LMF_Animate; 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) 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); DMenu *newmenu = new DMessageBoxMenu(DMenu::CurrentMenu, message, messagemode, false, action);
newmenu->mParentMenu = DMenu::CurrentMenu; newmenu->mParentMenu = DMenu::CurrentMenu;
newmenu->scriptID = scriptId;
M_ActivateMenu(newmenu); 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, return NewSmallFont;
DTA_CellX, 8 * CleanXfac_1,
DTA_CellY, 8 * CleanYfac_1,
TAG_DONE);
} }
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) if (mDesc->mSelectedItem != startedAt)
{ {
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); M_MenuSound(CursorSound);
} }
return true; return true;
} }
@ -355,7 +367,8 @@ bool DOptionMenu::MouseEvent(int type, int x, int y)
if (yline != mDesc->mSelectedItem) if (yline != mDesc->mSelectedItem)
{ {
mDesc->mSelectedItem = yline; 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); mDesc->mItems[yline]->MouseEvent(type, x, y);
return true; return true;
@ -390,21 +403,9 @@ void DOptionMenu::Drawer ()
{ {
int y = mDesc->mPosition; int y = mDesc->mPosition;
if (y <= 0) if (mDesc->mTitle.IsNotEmpty())
{ {
if (BigFont && mDesc->mTitle.IsNotEmpty()) gi->DrawMenuCaption(origin, mDesc->mTitle);
{
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;
}
} }
mDesc->mDrawTop = y; mDesc->mDrawTop = y;
int fontheight = OptionSettings.mLinespacing * CleanYfac_1; int fontheight = OptionSettings.mLinespacing * CleanYfac_1;
@ -445,7 +446,8 @@ void DOptionMenu::Drawer ()
{ {
if ((((DMenu::MenuTime>>2)%8) < 6) || DMenu::CurrentMenu != this) 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) 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) 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(); Super::Drawer();
} }
@ -497,30 +501,40 @@ bool FOptionMenuItem::MouseEvent(int type, int x, int y)
int FOptionMenuItem::GetIndent() int FOptionMenuItem::GetIndent()
{ {
if (mCentered) if (mCentered) return 0;
{ if (screen->GetWidth() < 640) return screen->GetWidth() / 2;
return 0;
}
const char *label = mLabel; const char *label = mLabel;
if (*label == '$') label = GStrings(label+1); 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; const char *label = mLabel;
if (*label == '$') label = GStrings(label+1); if (*label == '$') label = GStrings(label+1);
int overlay = grayed? MAKEARGB(96,48,0,0) : 0;
int x; int x;
int w = SmallFont->StringWidth(label) * CleanXfac_1; int w = OptionWidth(label) * CleanXfac_1;
if (!mCentered) x = indent - w; if (!mCentered) x = indent - w;
else x = (screen->GetWidth() - w) / 2; 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() void FOptionMenuDescriptor::CalcIndent()
{ {

View file

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

View file

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

View file

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

View file

@ -380,6 +380,22 @@ ImageScroller "HelpMenu"
ImageItem "TEXTSTORY", 400 ImageItem "TEXTSTORY", 400
ImageItem "F1HELP", 401 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" ImageScroller "CreditsMenu"
{ {
ifgame(Duke, Nam, WW2GI, Fury) ifgame(Duke, Nam, WW2GI)
{ {
ImageItem "CREDITSTEXT1", 990 ImageItem "CREDITSTEXT1", 990
ImageItem "CREDITSTEXT2", 991 ImageItem "CREDITSTEXT2", 991
ImageItem "CREDITSTEXT3", 992 ImageItem "CREDITSTEXT3", 992
animatedtransition 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) ifgame(Redneck)
{ {
// no point putting this into the string table. // 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 TextItem "REDNECK RAMPAGE RIDES AGAIN\n(c) 1998 XATRIX ENTERTAINMENT, INC.\n\nREDNECK RAMPAGE RIDES AGAIN\nIS A TRADEMARK OF\nINTERPLAY PRODUCTIONS", 70
animatedtransition animatedtransition
} }
ifgame(blood)
{
QAVAnimationItem "Credits"
}
ifgame(ShadowWarrior)
{
ifshareware
{
ImageItem "#5110"
ImageItem "#5112"
}
ImageItem "#5111"
ImageItem "#5118"
ImageItem "#4979"
ImageItem "#5113"
}
} }
//------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------