Merge pull request #782 from h0tw1r3/feature-extmenu

refactor miscmenu and add adv menu (nw)
This commit is contained in:
Miodrag Milanović 2016-04-03 14:08:25 +02:00
commit 9c61e636f1
11 changed files with 484 additions and 137 deletions

View File

@ -206,6 +206,8 @@ files {
MAME_DIR .. "src/emu/ui/devctrl.h",
MAME_DIR .. "src/emu/ui/menu.cpp",
MAME_DIR .. "src/emu/ui/menu.h",
MAME_DIR .. "src/emu/ui/submenu.cpp",
MAME_DIR .. "src/emu/ui/submenu.h",
MAME_DIR .. "src/emu/ui/mainmenu.cpp",
MAME_DIR .. "src/emu/ui/mainmenu.h",
MAME_DIR .. "src/emu/ui/miscmenu.cpp",

View File

@ -150,8 +150,8 @@ const options_entry emu_options::s_option_entries[] =
{ OPTION_UI_ACTIVE, "0", OPTION_BOOLEAN, "enable user interface on top of emulated keyboard (if present)" },
{ OPTION_OFFSCREEN_RELOAD ";reload", "0", OPTION_BOOLEAN, "convert lightgun button 2 into offscreen reload" },
{ OPTION_JOYSTICK_MAP ";joymap", "auto", OPTION_STRING, "explicit joystick map, or auto to auto-select" },
{ OPTION_JOYSTICK_DEADZONE ";joy_deadzone;jdz", "0.3", OPTION_FLOAT, "center deadzone range for joystick where change is ignored (0.0 center, 1.0 end)" },
{ OPTION_JOYSTICK_SATURATION ";joy_saturation;jsat", "0.85", OPTION_FLOAT, "end of axis saturation range for joystick where change is ignored (0.0 center, 1.0 end)" },
{ OPTION_JOYSTICK_DEADZONE ";joy_deadzone;jdz(0.00-1)", "0.3", OPTION_FLOAT, "center deadzone range for joystick where change is ignored (0.0 center, 1.0 end)" },
{ OPTION_JOYSTICK_SATURATION ";joy_saturation;jsat(0.00-1)", "0.85", OPTION_FLOAT, "end of axis saturation range for joystick where change is ignored (0.0 center, 1.0 end)" },
{ OPTION_NATURAL_KEYBOARD ";nat", "0", OPTION_BOOLEAN, "specifies whether to use a natural keyboard or not" },
{ OPTION_JOYSTICK_CONTRADICTORY ";joy_contradictory","0", OPTION_BOOLEAN, "enable contradictory direction digital joystick input at the same time" },
{ OPTION_COIN_IMPULSE, "0", OPTION_INTEGER, "set coin impulse time (n<0 disable impulse, n==0 obey driver, 0<n set time n)" },

View File

@ -544,14 +544,25 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
if (!customonly)
machine().ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
// determine the first visible line based on the current selection
if (selected > top_line + visible_lines || selected < top_line - visible_lines)
top_line = selected - (visible_lines / 2);
if (top_line < 0 || selected == 0)
top_line = 0;
if (top_line + visible_lines >= item.size())
if (top_line > item.size() - visible_lines || selected == (item.size() - 1))
top_line = item.size() - visible_lines;
bool show_top_arrow = false;
bool show_bottom_arrow = false;
// if scrolling, show arrows
if (item.size() > visible_lines) {
if (top_line > 0)
show_top_arrow = true;
if (top_line != item.size() - visible_lines)
show_bottom_arrow = true;
}
// set the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
visitems = visible_lines - show_top_arrow - show_bottom_arrow;
// determine effective positions taking into account the hilighting arrows
float effective_width = visible_width - 2.0f * gutter_width;
float effective_left = visible_left + gutter_width;
@ -573,6 +584,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
if (!customonly)
{
for (linenum = 0; linenum < visible_lines; linenum++)
{
float line_y = visible_top + (float)linenum * line_height;
@ -613,7 +625,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
highlight(container, line_x0, line_y0, line_x1, line_y1, bgcolor);
// if we're on the top line, display the up arrow
if (linenum == 0 && top_line != 0)
if (linenum == 0 && show_top_arrow)
{
draw_arrow(container,
0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
@ -627,7 +639,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
}
// if we're on the bottom line, display the down arrow
else if (linenum == visible_lines - 1 && itemnum != item.size() - 1)
else if (linenum == visible_lines - 1 && show_bottom_arrow)
{
draw_arrow(container,
0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
@ -708,6 +720,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
}
}
}
}
// if the selected subitem is too big, display it in a separate offset box
if (selected_subitem_too_big)
@ -741,9 +754,6 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
// if there is something special to add, do it by calling the virtual method
custom_render((selected >= 0 && selected < item.size()) ? item[selected].ref : nullptr, customtop, custombottom, x1, y1, x2, y2);
// return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
visitems = visible_lines - (top_line != 0) - (top_line + visible_lines != item.size());
}
void ui_menu::custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2)
@ -989,7 +999,9 @@ void ui_menu::handle_keys(UINT32 flags)
}
(selected == 0) ? selected = top_line = item.size() - 1 : --selected;
validate_selection(-1);
top_line -= (selected == top_line && top_line != 0);
top_line -= (selected <= top_line && top_line != 0);
if (selected <= top_line && visitems != visible_lines)
top_line--;
}
// down advances by one item
@ -1001,7 +1013,10 @@ void ui_menu::handle_keys(UINT32 flags)
return;
}
(selected == item.size() - 1) ? selected = top_line = 0 : ++selected;
top_line += (selected == top_line + visitems + (top_line != 0));
validate_selection(1);
top_line += (selected >= top_line + visitems + (top_line != 0));
if (selected >= (top_line + visitems + (top_line != 0)))
top_line++;
}
// page up backs up by visitems

View File

@ -552,127 +552,6 @@ void ui_menu_quit_game::handle()
ui_menu::stack_reset(machine());
}
ui_menu_misc_options::misc_option ui_menu_misc_options::m_options[] = {
{ 0, nullptr, nullptr },
{ 0, __("Re-select last machine played"), OPTION_REMEMBER_LAST },
{ 0, __("Enlarge images in the right panel"), OPTION_ENLARGE_SNAPS },
{ 0, __("DATs info"), OPTION_DATS_ENABLED },
{ 0, __("Cheats"), OPTION_CHEAT },
{ 0, __("Show mouse pointer"), OPTION_UI_MOUSE },
{ 0, __("Confirm quit from machines"), OPTION_CONFIRM_QUIT },
{ 0, __("Skip displaying information's screen at startup"), OPTION_SKIP_GAMEINFO },
{ 0, __("Force 4:3 appearance for software snapshot"), OPTION_FORCED4X3 },
{ 0, __("Use image as background"), OPTION_USE_BACKGROUND },
{ 0, __("Skip bios selection menu"), OPTION_SKIP_BIOS_MENU },
{ 0, __("Skip software parts selection menu"), OPTION_SKIP_PARTS_MENU }
};
//-------------------------------------------------
// ctor / dtor
//-------------------------------------------------
ui_menu_misc_options::ui_menu_misc_options(running_machine &machine, render_container *container) : ui_menu(machine, container)
{
for (int d = 1; d < ARRAY_LENGTH(m_options); ++d)
if (machine.ui().options().exists(m_options[d].option))
m_options[d].status = machine.ui().options().bool_value(m_options[d].option);
else
m_options[d].status = machine.options().bool_value(m_options[d].option);
}
ui_menu_misc_options::~ui_menu_misc_options()
{
std::string error_string;
for (int d = 1; d < ARRAY_LENGTH(m_options); ++d) {
if (machine().ui().options().exists(m_options[d].option))
{
machine().ui().options().set_value(m_options[d].option, m_options[d].status, OPTION_PRIORITY_CMDLINE, error_string);
}
else
{
if (machine().options().bool_value(m_options[d].option) != m_options[d].status)
{
machine().options().set_value(m_options[d].option, m_options[d].status, OPTION_PRIORITY_CMDLINE, error_string);
machine().options().mark_changed(m_options[d].option);
}
}
}
ui_globals::reset = true;
}
//-------------------------------------------------
// handlethe options menu
//-------------------------------------------------
void ui_menu_misc_options::handle()
{
bool changed = false;
// process the menu
const ui_menu_event *m_event = process(0);
if (m_event != nullptr && m_event->itemref != nullptr)
{
if (m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT || m_event->iptkey == IPT_UI_SELECT)
{
changed = true;
int value = (FPTR)m_event->itemref;
if (!strcmp(m_options[value].option, OPTION_ENLARGE_SNAPS))
ui_globals::switch_image = true;
m_options[value].status = !m_options[value].status;
}
}
if (changed)
reset(UI_MENU_RESET_REMEMBER_REF);
}
//-------------------------------------------------
// populate
//-------------------------------------------------
void ui_menu_misc_options::populate()
{
// add options items
for (int opt = 1; opt < ARRAY_LENGTH(m_options); ++opt)
item_append(_(m_options[opt].description), m_options[opt].status ? _("On") : _("Off"), m_options[opt].status ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)opt);
item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);
customtop = machine().ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER);
}
//-------------------------------------------------
// perform our special rendering
//-------------------------------------------------
void ui_menu_misc_options::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
{
float width;
ui_manager &mui = machine().ui();
mui.draw_text_full(container, _("Miscellaneous Options"), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE,
DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
float maxwidth = MAX(origx2 - origx1, width);
// compute our bounds
float x1 = 0.5f - 0.5f * maxwidth;
float x2 = x1 + maxwidth;
float y1 = origy1 - top;
float y2 = origy1 - UI_BOX_TB_BORDER;
// draw a box
mui.draw_outlined_box(container, x1, y1, x2, y2, UI_GREEN_COLOR);
// take off the borders
x1 += UI_BOX_LR_BORDER;
x2 -= UI_BOX_LR_BORDER;
y1 += UI_BOX_TB_BORDER;
// draw the text within it
mui.draw_text_full(container, _("Miscellaneous Options"), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE,
DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
//-------------------------------------------------
// ctor / dtor
//-------------------------------------------------

View File

@ -11,6 +11,7 @@
#include "emu.h"
#include "ui/ui.h"
#include "ui/menu.h"
#include "ui/submenu.h"
#include "ui/datfile.h"
#include "ui/inifile.h"
#include "ui/selector.h"
@ -162,7 +163,7 @@ void ui_menu_game_options::handle()
break;
case MISC_MENU:
if (m_event->iptkey == IPT_UI_SELECT)
ui_menu::stack_push(global_alloc_clear<ui_menu_misc_options>(machine(), container));
ui_menu::stack_push(global_alloc_clear<ui_submenu>(machine(), container, misc_submenu_options));
break;
case SOUND_MENU:
if (m_event->iptkey == IPT_UI_SELECT)
@ -188,6 +189,10 @@ void ui_menu_game_options::handle()
if (m_event->iptkey == IPT_UI_SELECT)
ui_menu::stack_push(global_alloc_clear<ui_menu_custom_filter>(machine(), container));
break;
case ADVANCED_MENU:
if (m_event->iptkey == IPT_UI_SELECT)
ui_menu::stack_push(global_alloc_clear<ui_submenu>(machine(), container, advanced_submenu_options));
break;
case SAVE_CONFIG:
if (m_event->iptkey == IPT_UI_SELECT)
save_main_option(machine());
@ -260,9 +265,10 @@ void ui_menu_game_options::populate()
}
item_append(_("Display Options"), nullptr, 0, (void *)(FPTR)DISPLAY_MENU);
item_append(_("Sound Options"), nullptr, 0, (void *)(FPTR)SOUND_MENU);
item_append(_("Miscellaneous Options"), nullptr, 0, (void *)(FPTR)MISC_MENU);
item_append(misc_submenu_options[0].description, nullptr, 0, (void *)(FPTR)MISC_MENU);
item_append(_("Device Mapping"), nullptr, 0, (void *)(FPTR)CONTROLLER_MENU);
item_append(_("General Inputs"), nullptr, 0, (void *)(FPTR)CGI_MENU);
item_append(advanced_submenu_options[0].description, nullptr, 0, (void *)(FPTR)ADVANCED_MENU);
item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);
item_append(_("Save Configuration"), nullptr, 0, (void *)(FPTR)SAVE_CONFIG);

View File

@ -33,11 +33,12 @@ private:
YEAR_CAT_FILTER,
CATEGORY_FILTER,
CONF_DIR,
MISC_MENU,
DISPLAY_MENU,
CUSTOM_MENU,
SOUND_MENU,
CONTROLLER_MENU,
MISC_MENU,
ADVANCED_MENU,
SAVE_OPTIONS,
CGI_MENU,
CUSTOM_FILTER,

304
src/emu/ui/submenu.cpp Normal file
View File

@ -0,0 +1,304 @@
// license:BSD-3-Clause
// copyright-holders:Maurizio Petrarota,Jeffrey Clark
/***************************************************************************
ui/submenu.cpp
UI options menu
***************************************************************************/
#include "emu.h"
#include "ui/ui.h"
#include "ui/submenu.h"
#include "ui/utils.h"
#include <limits>
//-------------------------------------------------
// ctor / dtor
//-------------------------------------------------
ui_submenu::ui_submenu(running_machine &machine, render_container *container, std::vector<ui_submenu::option> &suboptions)
: ui_menu(machine, container),
m_options(suboptions)
{
for (auto & sm_option : m_options)
{
if (sm_option.type < ui_submenu::EMU)
continue;
// fixme use switch
sm_option.entry = machine.options().get_entry(sm_option.name);
if (sm_option.entry == nullptr)
{
sm_option.entry = machine.ui().options().get_entry(sm_option.name);
sm_option.options = dynamic_cast<core_options*>(&machine.ui().options());
}
else
{
sm_option.options = dynamic_cast<core_options*>(&machine.options());
}
}
}
ui_submenu::~ui_submenu()
{
}
//-------------------------------------------------
// handlethe options menu
//-------------------------------------------------
void ui_submenu::handle()
{
bool changed = false;
std::string error_string, tmptxt;
int i_cur;
float f_cur, f_step;
// process the menu
const ui_menu_event *m_event = process(UI_MENU_PROCESS_LR_REPEAT);
if (m_event != nullptr && m_event->itemref != nullptr &&
(m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT || m_event->iptkey == IPT_UI_SELECT))
{
ui_submenu::option *sm_option = (ui_submenu::option *)m_event->itemref;
switch (sm_option->type)
{
case ui_submenu::EMU:
case ui_submenu::UI:
case ui_submenu::OSD:
switch (sm_option->entry->type())
{
case OPTION_BOOLEAN:
changed = true;
sm_option->options->set_value(sm_option->name, !strcmp(sm_option->entry->value(),"1") ? "0" : "1", OPTION_PRIORITY_CMDLINE, error_string);
sm_option->entry->mark_changed();
break;
case OPTION_INTEGER:
if (m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT)
{
changed = true;
i_cur = atof(sm_option->entry->value());
(m_event->iptkey == IPT_UI_LEFT) ? i_cur-- : i_cur++;
sm_option->options->set_value(sm_option->name, i_cur, OPTION_PRIORITY_CMDLINE, error_string);
sm_option->entry->mark_changed();
}
break;
case OPTION_FLOAT:
if (m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT)
{
changed = true;
f_cur = atof(sm_option->entry->value());
if (sm_option->entry->has_range())
{
f_step = atof(sm_option->entry->minimum());
if (f_step <= 0.0f) {
int pmin = getprecisionchr(sm_option->entry->minimum());
int pmax = getprecisionchr(sm_option->entry->maximum());
tmptxt = '1' + std::string((pmin > pmax) ? pmin : pmax, '0');
f_step = 1 / atof(tmptxt.c_str());
}
}
else
{
int precision = getprecisionchr(sm_option->entry->default_value());
tmptxt = '1' + std::string(precision, '0');
f_step = 1 / atof(tmptxt.c_str());
}
if (m_event->iptkey == IPT_UI_LEFT)
f_cur -= f_step;
else
f_cur += f_step;
tmptxt = string_format("%g", f_cur);
sm_option->options->set_value(sm_option->name, tmptxt.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
sm_option->entry->mark_changed();
}
break;
}
break;
default:
osd_printf_error("Unhandled option: %s", sm_option->description);
break;
}
}
if (changed)
reset(UI_MENU_RESET_REMEMBER_REF);
}
//-------------------------------------------------
// populate
//-------------------------------------------------
void ui_submenu::populate()
{
UINT32 arrow_flags;
std::string tmptxt;
float f_min, f_max, f_cur;
int i_min, i_max, i_cur;
// add options
for (auto sm_option = m_options.begin(); sm_option < m_options.end(); sm_option++)
{
// skip first heading (is menu title)
if (sm_option == m_options.begin() && sm_option->type == ui_submenu::HEAD) continue;
switch (sm_option->type)
{
case ui_submenu::HEAD:
item_append(sm_option->description, nullptr, MENU_FLAG_INVERT | MENU_FLAG_DISABLE, nullptr);
break;
case ui_submenu::SEP:
item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);
break;
case ui_submenu::CMD:
item_append(sm_option->description, nullptr, 0, static_cast<void*>(&(*sm_option)));
break;
case ui_submenu::EMU:
case ui_submenu::UI:
case ui_submenu::OSD:
switch (sm_option->entry->type())
{
case OPTION_BOOLEAN:
arrow_flags = sm_option->options->bool_value(sm_option->name) ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW;
item_append(sm_option->description,
(arrow_flags == MENU_FLAG_RIGHT_ARROW) ? "On" : "Off",
arrow_flags,
static_cast<void*>(&(*sm_option)));
break;
case OPTION_INTEGER:
i_cur = atof(sm_option->entry->value());
if (sm_option->entry->has_range())
{
i_min = atof(sm_option->entry->minimum());
i_max = atof(sm_option->entry->maximum());
}
else
{
i_min = std::numeric_limits<int>::min();
i_max = std::numeric_limits<int>::max();
}
arrow_flags = get_arrow_flags(i_min, i_max, i_cur);
item_append(sm_option->description,
sm_option->entry->value(),
arrow_flags,
static_cast<void*>(&(*sm_option)));
break;
case OPTION_FLOAT:
f_cur = atof(sm_option->entry->value());
if (sm_option->entry->has_range())
{
f_min = atof(sm_option->entry->minimum());
f_max = atof(sm_option->entry->maximum());
}
else
{
f_min = 0.0f;
f_max = std::numeric_limits<float>::max();
}
arrow_flags = get_arrow_flags(f_min, f_max, f_cur);
tmptxt = string_format("%g", f_cur);
item_append(sm_option->description,
tmptxt.c_str(),
arrow_flags,
static_cast<void*>(&(*sm_option)));
break;
default:
arrow_flags = MENU_FLAG_RIGHT_ARROW;
item_append(sm_option->description,
sm_option->options->value(sm_option->name),
arrow_flags, static_cast<void*>(&(*sm_option)));
break;
}
break;
default:
osd_printf_error("Unknown option type: %s", sm_option->description);
break;
}
}
item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);
custombottom = customtop = machine().ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER);
}
//-------------------------------------------------
// perform our special rendering
//-------------------------------------------------
void ui_submenu::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
{
static int interval = 0;
static ui_submenu::option *last_sm_option = nullptr;
float width;
ui_manager &mui = machine().ui();
mui.draw_text_full(container, m_options[0].description, 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE,
DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
float maxwidth = MAX(origx2 - origx1, width);
// compute our bounds
float x1 = 0.5f - 0.5f * maxwidth;
float x2 = x1 + maxwidth;
float y1 = origy1 - top;
float y2 = origy1 - UI_BOX_TB_BORDER;
// draw a box
mui.draw_outlined_box(container, x1, y1, x2, y2, UI_GREEN_COLOR);
// take off the borders
x1 += UI_BOX_LR_BORDER;
x2 -= UI_BOX_LR_BORDER;
y1 += UI_BOX_TB_BORDER;
// draw the text within it
mui.draw_text_full(container, m_options[0].description, x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE,
DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
if (selectedref != nullptr)
{
ui_submenu::option *selected_sm_option = (ui_submenu::option *)selectedref;
if (last_sm_option == selected_sm_option) {
if (interval <= 30) interval++;
} else {
last_sm_option = selected_sm_option;
interval = 0;
}
if (interval > 30 && last_sm_option->entry != nullptr)
{
mui.draw_text_full(container, last_sm_option->entry->description(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE,
DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
maxwidth = MAX(origx2 - origx1, width);
// compute our bounds
x1 = 0.5f - 0.5f * maxwidth;
x2 = x1 + maxwidth;
y1 = origy2 + UI_BOX_TB_BORDER;
y2 = origy2 + bottom;
// draw a box
mui.draw_outlined_box(container, x1, y1, x2, y2, UI_RED_COLOR);
// take off the borders
x1 += UI_BOX_LR_BORDER;
x2 -= UI_BOX_LR_BORDER;
y1 += UI_BOX_TB_BORDER;
// draw the text within it
mui.draw_text_full(container, last_sm_option->entry->description(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER,
DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
}
else
{
last_sm_option = nullptr;
interval = 0;
}
}

129
src/emu/ui/submenu.h Normal file
View File

@ -0,0 +1,129 @@
// license:BSD-3-Clause
// copyright-holders:Maurizio Petrarota,Jeffrey Clark
/***************************************************************************
ui/submenu.h
UI options menu.
***************************************************************************/
#pragma once
#ifndef __UI_SUBMENU_H__
#define __UI_SUBMENU_H__
#include "ui/menu.h"
//-------------------------------------------------
// class ui menu
//-------------------------------------------------
class ui_submenu : public ui_menu
{
public:
enum option_type {
HEAD,
SEP,
MENU,
CMD,
EMU,
UI,
OSD,
};
struct option {
option_type type;
const char *description;
const char *name;
core_options::entry *entry;
core_options (*options);
};
ui_submenu(running_machine &machine, render_container *container, std::vector<ui_submenu::option> &suboptions);
virtual ~ui_submenu();
virtual void populate() override;
virtual void handle() override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
std::vector<option> &m_options;
};
static std::vector<ui_submenu::option> misc_submenu_options = {
{ ui_submenu::HEAD, _("Miscellaneous Options") },
{ ui_submenu::UI, _("Re-select last machine played"), OPTION_REMEMBER_LAST },
{ ui_submenu::UI, _("Enlarge images in the right panel"), OPTION_ENLARGE_SNAPS },
{ ui_submenu::UI, _("DATs info"), OPTION_DATS_ENABLED },
{ ui_submenu::EMU, _("Cheats"), OPTION_CHEAT },
{ ui_submenu::EMU, _("Show mouse pointer"), OPTION_UI_MOUSE },
{ ui_submenu::EMU, _("Confirm quit from machines"), OPTION_CONFIRM_QUIT },
{ ui_submenu::EMU, _("Skip information screen at startup"), OPTION_SKIP_GAMEINFO },
{ ui_submenu::UI, _("Force 4:3 aspect for snapshot display"), OPTION_FORCED4X3 },
{ ui_submenu::UI, _("Use image as background"), OPTION_USE_BACKGROUND },
{ ui_submenu::UI, _("Skip bios selection menu"), OPTION_SKIP_BIOS_MENU },
{ ui_submenu::UI, _("Skip software parts selection menu"), OPTION_SKIP_PARTS_MENU },
{ ui_submenu::UI, _("Info auto audit"), OPTION_INFO_AUTO_AUDIT },
};
static std::vector<ui_submenu::option> advanced_submenu_options = {
{ ui_submenu::HEAD, _("Advanced Options") },
{ ui_submenu::HEAD, _("Performance Options") },
{ ui_submenu::EMU, _("Auto frame skip"), OPTION_AUTOFRAMESKIP },
{ ui_submenu::EMU, _("Frame skip"), OPTION_FRAMESKIP },
{ ui_submenu::EMU, _("Throttle"), OPTION_THROTTLE },
{ ui_submenu::EMU, _("Sleep"), OPTION_SLEEP },
{ ui_submenu::EMU, _("Speed"), OPTION_SPEED },
{ ui_submenu::EMU, _("Refresh speed"), OPTION_REFRESHSPEED },
//};
//static std::vector<ui_submenu::option> rotate_submenu_options = {
{ ui_submenu::HEAD, _("Rotation Options") },
{ ui_submenu::EMU, _("Rotate"), OPTION_ROTATE },
{ ui_submenu::EMU, _("Rotate right"), OPTION_ROR },
{ ui_submenu::EMU, _("Rotate left"), OPTION_ROL },
{ ui_submenu::EMU, _("Auto rotate right"), OPTION_AUTOROR },
{ ui_submenu::EMU, _("Auto rotate left"), OPTION_AUTOROL },
{ ui_submenu::EMU, _("Flip X"), OPTION_FLIPX },
{ ui_submenu::EMU, _("Flip Y"), OPTION_FLIPY },
//};
//static std::vector<ui_submenu::option> artwork_submenu_options = {
{ ui_submenu::HEAD, _("Artwork Options") },
{ ui_submenu::EMU, _("Artwork Crop"), OPTION_ARTWORK_CROP },
{ ui_submenu::EMU, _("Use Backdrops"), OPTION_USE_BACKDROPS },
{ ui_submenu::EMU, _("Use Overlays"), OPTION_USE_OVERLAYS },
{ ui_submenu::EMU, _("Use Bezels"), OPTION_USE_BEZELS },
{ ui_submenu::EMU, _("Use Control Panels"), OPTION_USE_CPANELS },
{ ui_submenu::EMU, _("Use Marquees"), OPTION_USE_MARQUEES },
//};
//static std::vector<ui_submenu::option> state_submenu_options = {
{ ui_submenu::HEAD, _("State/Playback Options") },
{ ui_submenu::EMU, _("Automatic save/restore"), OPTION_AUTOSAVE },
{ ui_submenu::EMU, _("Bilinear snapshot"), OPTION_SNAPBILINEAR },
{ ui_submenu::EMU, _("Burn-in"), OPTION_BURNIN },
//};
//static std::vector<ui_submenu::option> input_submenu_options = {
{ ui_submenu::HEAD, _("Input Options") },
{ ui_submenu::EMU, _("Coin lockout"), OPTION_COIN_LOCKOUT },
{ ui_submenu::EMU, _("Mouse"), OPTION_MOUSE },
{ ui_submenu::EMU, _("Joystick"), OPTION_JOYSTICK },
{ ui_submenu::EMU, _("Lightgun"), OPTION_LIGHTGUN },
{ ui_submenu::EMU, _("Multi-keyboard"), OPTION_MULTIKEYBOARD },
{ ui_submenu::EMU, _("Multi-mouse"), OPTION_MULTIMOUSE },
{ ui_submenu::EMU, _("Steadykey"), OPTION_STEADYKEY },
{ ui_submenu::EMU, _("UI active"), OPTION_UI_ACTIVE },
{ ui_submenu::EMU, _("Offscreen reload"), OPTION_OFFSCREEN_RELOAD },
{ ui_submenu::EMU, _("Joystick deadzone"), OPTION_JOYSTICK_DEADZONE },
{ ui_submenu::EMU, _("Joystick saturation"), OPTION_JOYSTICK_SATURATION },
{ ui_submenu::EMU, _("Natural keyboard"), OPTION_NATURAL_KEYBOARD },
{ ui_submenu::EMU, _("Simultaneous contradictory"), OPTION_JOYSTICK_CONTRADICTORY },
{ ui_submenu::EMU, _("Coin impulse"), OPTION_COIN_IMPULSE },
};
//static std::vector<ui_submenu::option> export_submenu_options = {
// { ui_submenu::COMMAND, _("Export XML format (like -listxml)"), "exportxml" },
// { ui_submenu::COMMAND, _("Export TXT format (like -listfull)"), "exporttxt" },
//};
#endif /* __UI_SUBMENU_H__ */

View File

@ -84,6 +84,15 @@ const char* strensure(const char* s)
return s == nullptr ? "" : s;
}
int getprecisionchr(const char* s)
{
int precision = 1;
char *dp = const_cast<char *>(strchr(s, '.'));
if (dp != nullptr)
precision = strlen(s) - (dp - s) - 1;
return precision;
}
//-------------------------------------------------
// search a substring with even partial matching
//-------------------------------------------------

View File

@ -254,5 +254,6 @@ char* chartrimcarriage(char str[]);
const char* strensure(const char* s);
int getprecisionchr(const char* s);
#endif /* __UI_UTILS_H__ */

View File

@ -131,6 +131,7 @@ public:
// getters
entry *first() const { return m_entrylist.first(); }
const char *command() const { return m_command.c_str(); }
entry *get_entry(const char *option) { return (m_entrymap.find(option) != m_entrymap.end()) ? m_entrymap.find(option)->second : nullptr; }
// range iterators
using auto_iterator = simple_list<entry>::auto_iterator;