Skip to content

Commit

Permalink
Menu|All Games: Automatic Episode selection
Browse files Browse the repository at this point in the history
If there is only one episode defined, the episode selection page will be skipped in the menu.

The Doom menu cursor was scaled 25% smaller.
  • Loading branch information
skyjake committed Sep 29, 2018
1 parent 6447c22 commit 24c4061
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 55 deletions.
2 changes: 1 addition & 1 deletion doomsday/apps/plugins/common/include/hu_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ void Hu_MenuConsoleRegister();

void Hu_MenuDefaultFocusAction(menu::Widget &wi, menu::Widget::Action action);

void Hu_MenuDrawFocusCursor(de::Vector2i const &origin, int focusObjectHeight, float alpha);
void Hu_MenuDrawFocusCursor(de::Vector2i const &origin, float scale, float alpha);

void Hu_MenuDrawPageTitle(de::String titleText, de::Vector2i const &origin);
void Hu_MenuDrawPageHelp(de::String helpText, de::Vector2i const &origin);
Expand Down
21 changes: 10 additions & 11 deletions doomsday/apps/plugins/common/include/menu/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,11 @@ class Page
};
Q_DECLARE_FLAGS(Flags, Flag)

typedef WidgetList Children;
using Children = WidgetList;

typedef void (*OnActiveCallback) (Page &);
typedef void (*OnDrawCallback) (Page const &, de::Vector2i const &);

typedef int (*CommandResponder) (Page &, menucommand_e);
using OnActiveCallback = std::function<void(Page &)>;
using OnDrawCallback = std::function<void(Page const &, de::Vector2i const &)>;
using CommandResponder = std::function<int(Page &, menucommand_e)>;

public:
/**
Expand All @@ -77,14 +76,14 @@ class Page
* @param name Symbolic name/identifier for the page.
* @param origin Origin of the page in fixed 320x200 space.
* @param flags Page flags.
* ---
* @param drawer
* @param cmdResponder
*/
explicit Page(de::String name, de::Vector2i const &origin = de::Vector2i(),
Flags const &flags = DefaultFlags,
OnDrawCallback drawer = 0,
CommandResponder cmdResponder = 0);
explicit Page(de::String name,
de::Vector2i const & origin = de::Vector2i(),
Flags const & flags = DefaultFlags,
const OnDrawCallback & drawer = {},
const CommandResponder &cmdResponder = {});

virtual ~Page();

Expand Down Expand Up @@ -193,7 +192,7 @@ class Page
*
* @param newCallback Function to callback on page activation. Use @c 0 to clear.
*/
void setOnActiveCallback(OnActiveCallback newCallback);
void setOnActiveCallback(const OnActiveCallback &newCallback);

/**
* Retrieve a predefined color triplet associated with this page by it's logical
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class ButtonWidget : public Widget
void updateGeometry();
int handleCommand(menucommand_e command);

void setSilent(bool silent);

ButtonWidget &setText(de::String const &newText);
de::String text() const;

Expand Down
62 changes: 38 additions & 24 deletions doomsday/apps/plugins/common/src/hu_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1996,8 +1996,8 @@ void Hu_MenuInitSoundOptionsPage()
page->addWidget(new LabelWidget("Music Volume"))
.setLeft();
page->addWidget(new CVarSliderWidget("music-volume", 0, 255, 16, false))
.setRight()
.setShortcut('m');
.setRight()
.setShortcut('m');
}

/**
Expand All @@ -2013,33 +2013,47 @@ void Hu_MenuInitEpisodePage()
Vector2i const origin(48, 63);
#endif

Page *page = Hu_MenuAddPage(new Page("Episode", origin, Page::FixedLayout, Hu_MenuDrawEpisodePage));
Page *page =
Hu_MenuAddPage(new Page("Episode", origin, Page::FixedLayout, Hu_MenuDrawEpisodePage));

page->setPredefinedFont(MENU_FONT1, FID(GF_FONTB));
page->setPreviousPage(Hu_MenuPagePtr("Main"));
page->setOnActiveCallback([](Page &page) {
const auto &items = page.children();
if (items.size() == 1)
{
// If there is only one episode, select it automatically.
auto &ep = items.front()->as<ButtonWidget>();
ep.setSilent(true);
ep.handleCommand(MCMD_SELECT);
ep.setSilent(false);
}
});

DictionaryValue::Elements const &episodesById = Defs().episodes.lookup("id").elements();
if(!episodesById.size())
const DictionaryValue::Elements &episodesById = Defs().episodes.lookup("id").elements();
if (!episodesById.size())
{
LOG_WARNING("No episodes are defined. It will not be possible to start a new game from the menu");
LOG_WARNING(
"No episodes are defined. It will not be possible to start a new game from the menu");
return;
}

int y = 0;
int n = 0;
for(auto const &pair : episodesById)
for (auto const &pair : episodesById)
{
Record const &episodeDef = *pair.second->as<RecordValue>().record();
String const episodeId = episodeDef.gets("id");
String const episodeId = episodeDef.gets("id");

auto *btn = new ButtonWidget(G_EpisodeTitle(episodeId));
btn->setFixedY(y);

// Has a menu image been specified?
de::Uri image(episodeDef.gets("menuImage"), RC_NULL);
if(!image.path().isEmpty())
if (!image.path().isEmpty())
{
// Presently only patches are supported.
if(!image.scheme().compareWithoutCase("Patches"))
if (!image.scheme().compareWithoutCase("Patches"))
{
btn->setPatch(R_DeclarePatch(image.path().toUtf8().constData()));
}
Expand All @@ -2048,20 +2062,20 @@ void Hu_MenuInitEpisodePage()
// Has a menu shortcut/hotkey been specified?
/// @todo Validate symbolic dday key names.
String const shortcut = episodeDef.gets("menuShortcut");
if(!shortcut.isEmpty() && shortcut.first().isLetterOrNumber())
if (!shortcut.isEmpty() && shortcut.first().isLetterOrNumber())
{
btn->setShortcut(shortcut.first().toLower().toLatin1());
}

// Has a menu help/info text been specified?
String const helpInfo = episodeDef.gets("menuHelpInfo");
if(!helpInfo.isEmpty())
if (!helpInfo.isEmpty())
{
btn->setHelpInfo(helpInfo);
}

de::Uri startMap(episodeDef.gets("startMap"), RC_NULL);
if(P_MapExists(startMap.compose().toUtf8().constData()))
if (P_MapExists(startMap.compose().toUtf8().constData()))
{
btn->setAction(Widget::Deactivated, Hu_MenuSelectEpisode);
btn->setUserValue(episodeId);
Expand All @@ -2070,13 +2084,13 @@ void Hu_MenuInitEpisodePage()
{
#if __JDOOM__ || __JHERETIC__
// In shareware display a prompt to buy the full game.
if(
#if __JHERETIC__
gameMode == heretic_shareware
#else // __JDOOM__
gameMode == doom_shareware
#endif
&& startMap.path() != "E1M1")
if (
# if __JHERETIC__
gameMode == heretic_shareware
# else // __JDOOM__
gameMode == doom_shareware
# endif
&& startMap.path() != "E1M1")
{
btn->setAction(Widget::Deactivated, Hu_MenuActivateNotSharewareEpisode);
}
Expand All @@ -2087,7 +2101,7 @@ void Hu_MenuInitEpisodePage()
btn->setFlags(Widget::Disabled);
LOG_RES_WARNING("Failed to locate the starting map \"%s\" for episode '%s'."
" This episode will not be selectable from the menu")
<< startMap << episodeId;
<< startMap << episodeId;
}
}

Expand Down Expand Up @@ -2387,11 +2401,11 @@ short Hu_MenuMergeEffectWithDrawTextFlags(short f)
return ((~cfg.common.menuEffectFlags & DTF_NO_EFFECTS) | (f & ~DTF_NO_EFFECTS));
}

void Hu_MenuDrawFocusCursor(Vector2i const &origin, int /*focusObjectHeight*/, float alpha)
void Hu_MenuDrawFocusCursor(Vector2i const &origin, float scale, float alpha)
{
#if __JDOOM__ || __JDOOM64__
# define OFFSET_X (-22)
# define OFFSET_Y (-2)
# define OFFSET_Y (-1)
#elif __JHERETIC__ || __JHEXEN__
# define OFFSET_X (-16)
# define OFFSET_Y (1)
Expand All @@ -2405,7 +2419,7 @@ void Hu_MenuDrawFocusCursor(Vector2i const &origin, int /*focusObjectHeight*/, f
if(!R_GetPatchInfo(pCursor, &info))
return;

float const scale = /*de::min((focusObjectHeight * 1.267f) /*/ 1; //info.geometry.size.height; //, 1.f);
// float const scale = /*de::min((focusObjectHeight * 1.267f) /*/ 1; //info.geometry.size.height; //, 1.f);
Vector2i pos = origin + Vector2i(OFFSET_X, OFFSET_Y) * scale;
// pos.y -= info.geometry.size.height / 2;

Expand Down
26 changes: 17 additions & 9 deletions doomsday/apps/plugins/common/src/menu/page.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ DENG2_PIMPL(Page)
fontid_t fonts[MENU_FONT_COUNT]; ///< Predefined. Used by all widgets.
uint colors[MENU_COLOR_COUNT]; ///< Predefined. Used by all widgets.

OnActiveCallback onActiveCallback = nullptr;
OnDrawCallback drawer = nullptr;
CommandResponder cmdResponder = nullptr;
OnActiveCallback onActiveCallback;
OnDrawCallback drawer;
CommandResponder cmdResponder;

// User data values.
QVariant userValue;
Expand Down Expand Up @@ -364,8 +364,11 @@ DENG2_PIMPL(Page)
#endif
};

Page::Page(String name, Vector2i const &origin, Flags const &flags,
OnDrawCallback drawer, CommandResponder cmdResponder)
Page::Page(String name,
Vector2i const & origin,
Flags const & flags,
const OnDrawCallback & drawer,
const CommandResponder &cmdResponder)
: d(new Impl(this))
{
d->origin = origin;
Expand Down Expand Up @@ -399,7 +402,7 @@ Page::Children const &Page::children() const
return d->children;
}

void Page::setOnActiveCallback(Page::OnActiveCallback newCallback)
void Page::setOnActiveCallback(const OnActiveCallback &newCallback)
{
d->onActiveCallback = newCallback;
}
Expand Down Expand Up @@ -567,9 +570,14 @@ void Page::draw(float alpha, bool showFocusCursor)

// How about a focus cursor?
/// @todo cursor should be drawn on top of the page drawer.
if(showFocusCursor && focused)
if (showFocusCursor && focused)
{
Hu_MenuDrawFocusCursor(cursorOrigin, 0, alpha);
#if defined (__JDOOM__) || defined (__JDOOM64__)
const float cursorScale = .75f;
#else
const float cursorScale = 1.f;
#endif
Hu_MenuDrawFocusCursor(cursorOrigin, cursorScale, alpha);
}

DGL_MatrixMode(DGL_MODELVIEW);
Expand Down Expand Up @@ -727,7 +735,7 @@ void Page::activate()

d->refocus();

if(d->onActiveCallback)
if (d->onActiveCallback)
{
d->onActiveCallback(*this);
}
Expand Down
26 changes: 16 additions & 10 deletions doomsday/apps/plugins/common/src/menu/widgets/buttonwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ namespace menu {

DENG2_PIMPL_NOREF(ButtonWidget)
{
String text; ///< Label text.
patchid_t patch = -1; ///< Used when drawing this instead of text, if set.
bool noAltText = false;
String text; ///< Label text.
patchid_t patch = -1; ///< Used when drawing this instead of text, if set.
bool noAltText = false;
bool silent = false;
};

ButtonWidget::ButtonWidget(String const &text, patchid_t patch)
Expand Down Expand Up @@ -102,25 +103,30 @@ void ButtonWidget::draw() const

int ButtonWidget::handleCommand(menucommand_e cmd)
{
if(cmd == MCMD_SELECT)
if (cmd == MCMD_SELECT)
{
if(!isActive())
if (!isActive())
{
setFlags(Active);
execAction(Activated);
}

// We are not going to receive an "up event" so action that now.
S_LocalSound(SFX_MENU_ACCEPT, NULL);
// We are not going to receive a separate "up event".
if (!d->silent)
{
S_LocalSound(SFX_MENU_ACCEPT, NULL);
}
setFlags(Active, UnsetFlags);
execAction(Deactivated);

return true;
}

return false; // Not eaten.
}

void ButtonWidget::setSilent(bool silent)
{
d->silent = silent;
}

void ButtonWidget::updateGeometry()
{
String useText = d->text;
Expand Down

0 comments on commit 24c4061

Please sign in to comment.