-osd: Better XInput and SDL game controller input enhancements:

* Added initial support for XInput controller subtypes, starting with
  driving, arcade and flight controllers.
* Check XInput capabilities to ignore buttons and hats that aren't
  present.
* Added preliminary SDL Game Controller joystick provider.  Reconnection
  and mixed Game Controller/Joystick devices are unsupported.
* Show the input token for the highlighted control on input device
  menus.

-ui: Allow menus to set required space above and below menu when metrics
change.  Fixes the initial bad layout on the system selecton menu, or
bad layout after resizing windows.
This commit is contained in:
Vas Crabb 2023-01-12 17:59:59 +11:00
parent 9e8064c85e
commit fee7047c16
92 changed files with 1916 additions and 693 deletions

View File

@ -899,22 +899,24 @@ Example:
- dinput
- xinput
- none
- sdl
- sdljoy
- sdlgame
* - **SDL**
- auto [#JIPAutoSDL]_.
-
-
-
- none
- sdl
- sdljoy
- sdlgame
.. rubric:: Footnotes
.. [#JIPAutoWindows] On Windows, auto will default to ``dinput``.
.. [#JIPAutoSDL] On SDL, auto will default to ``sdl``.
.. [#JIPAutoSDL] On SDL, auto will default to ``sdljoy``.
.. Tip:: Note that Microsoft XBox 360 and XBox One controllers connected to
.. Tip:: Note that Microsoft Xbox 360 and Xbox One controllers connected to
Windows will work best with ``winhybrid`` or ``xinput``. The
``winhybrid`` option supports a mix of DirectInput and XInput
controllers at the same time.

View File

@ -70,8 +70,9 @@ SDL Joystick Mapping
**-sixaxis**
Use special handling for PlayStation 3 SixAxis controllers. Default is OFF
(**-nosixaxis**)
Use special handling for PlayStation 3 SixAxis controllers. May cause
undesirable behaviour with other controllers. Only affects the ``sdljoy``
joystick provider. Default is OFF (**-nosixaxis**)
SDL Lightgun Mapping

View File

@ -63,9 +63,9 @@ copyright = u'1997-2023, MAMEdev and contributors'
# built documents.
#
# The short X.Y version.
version = '0.251'
version = '0.252'
# The full version, including alpha/beta/rc tags.
release = '0.251'
release = '0.252'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -1013,9 +1013,9 @@ void render_target::set_bounds(s32 width, s32 height, float pixel_aspect)
m_width = width;
m_height = height;
m_bounds.x0 = m_bounds.y0 = 0;
m_bounds.x1 = (float)width;
m_bounds.y1 = (float)height;
m_pixel_aspect = pixel_aspect != 0.0? pixel_aspect : 1.0;
m_bounds.x1 = float(width);
m_bounds.y1 = float(height);
m_pixel_aspect = pixel_aspect != 0.0F ? pixel_aspect : 1.0F;
}

View File

@ -63,6 +63,19 @@ menu_about::~menu_about()
}
//-------------------------------------------------
// recompute metrics
//-------------------------------------------------
void menu_about::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu_textbox::recompute_metrics(width, height, aspect);
// make space for the title and revision
set_custom_space((line_height() * m_header.size()) + (tb_border() * 3.0F), 0.0F);
}
//-------------------------------------------------
// perform our special rendering
//-------------------------------------------------
@ -103,10 +116,8 @@ void menu_about::populate_text(std::optional<text_layout> &layout, float &width,
// populate - populates the about modal
//-------------------------------------------------
void menu_about::populate(float &customtop, float &custombottom)
void menu_about::populate()
{
// make space for the title and revision
customtop = (line_height() * m_header.size()) + (tb_border() * 3.0f);
}

View File

@ -29,12 +29,13 @@ public:
virtual ~menu_about() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
std::vector<std::string> const m_header;

View File

@ -66,6 +66,15 @@ menu_analog::~menu_analog()
}
void menu_analog::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
// space for live display
set_custom_space(0.0f, (line_height() * m_visible_fields) + (tb_border() * 3.0f));
}
void menu_analog::custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2)
{
// work out how much space to use for field names
@ -331,7 +340,7 @@ void menu_analog::handle(event const *ev)
}
void menu_analog::populate(float &customtop, float &custombottom)
void menu_analog::populate()
{
// loop over input ports
if (m_item_data.empty())
@ -401,7 +410,7 @@ void menu_analog::populate(float &customtop, float &custombottom)
item_append(menu_item_type::SEPARATOR);
// space for live display
custombottom = (line_height() * m_visible_fields) + (tb_border() * 3.0f);
set_custom_space(0.0f, (line_height() * m_visible_fields) + (tb_border() * 3.0f));
}

View File

@ -27,6 +27,7 @@ public:
virtual ~menu_analog() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual void menu_activated() override;
@ -66,7 +67,7 @@ private:
using item_data_vector = std::vector<item_data>;
using field_data_vector = std::vector<field_data>;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void find_fields();

View File

@ -74,6 +74,14 @@ menu_audit::~menu_audit()
}
void menu_audit::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
set_custom_space(0.0F, (line_height() * 1.0F) + (tb_border() * 3.0F));
}
void menu_audit::custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2)
{
switch (m_phase)
@ -107,7 +115,7 @@ void menu_audit::custom_render(void *selectedref, float top, float bottom, float
container(),
std::move(text).str(),
text_layout::text_justify::CENTER,
0.5f, 0.5f,
0.5F, 0.5F,
ui().colors().background_color());
}
break;
@ -120,7 +128,7 @@ void menu_audit::custom_render(void *selectedref, float top, float bottom, float
ui().get_general_input_setting(IPT_UI_SELECT),
ui().get_general_input_setting(IPT_UI_CANCEL)),
text_layout::text_justify::CENTER,
0.5f, 0.5f,
0.5F, 0.5F,
UI_RED_COLOR);
break;
}
@ -133,13 +141,12 @@ bool menu_audit::custom_ui_cancel()
}
void menu_audit::populate(float &customtop, float &custombottom)
void menu_audit::populate()
{
if (m_unavailable && (m_availablesorted.size() != m_unavailable))
item_append(util::string_format(_("Audit media for %1$u systems marked unavailable"), m_unavailable), 0, ITEMREF_START_FAST);
item_append(util::string_format(_("Audit media for all %1$u systems"), m_availablesorted.size()), 0, ITEMREF_START_FULL);
item_append(menu_item_type::SEPARATOR, 0);
custombottom = (line_height() * 1.0f) + (tb_border() * 3.0f);
}
void menu_audit::handle(event const *ev)

View File

@ -29,13 +29,14 @@ public:
virtual ~menu_audit() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_cancel() override;
private:
enum class phase { CONFIRMATION, AUDIT, CANCELLATION };
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
bool do_audit();

View File

@ -54,7 +54,7 @@ menu_barcode_reader::~menu_barcode_reader()
// populate - populates the barcode input menu
//-------------------------------------------------
void menu_barcode_reader::populate(float &customtop, float &custombottom)
void menu_barcode_reader::populate()
{
if (current_device())
{

View File

@ -24,7 +24,7 @@ public:
virtual ~menu_barcode_reader() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
std::string m_barcode_buffer;

View File

@ -111,7 +111,7 @@ menu_cheat::menu_cheat(mame_ui_manager &mui, render_container &container) : menu
set_process_flags(PROCESS_LR_REPEAT);
}
void menu_cheat::populate(float &customtop, float &custombottom)
void menu_cheat::populate()
{
/* iterate over cheats */
std::string text;

View File

@ -24,7 +24,7 @@ public:
virtual ~menu_cheat() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};

View File

@ -89,7 +89,7 @@ void menu_confswitch::menu_activated()
}
void menu_confswitch::populate(float &customtop, float &custombottom)
void menu_confswitch::populate()
{
// locate relevant fields if necessary
if (m_fields.empty())
@ -320,6 +320,18 @@ menu_settings_dip_switches::~menu_settings_dip_switches()
}
void menu_settings_dip_switches::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu_confswitch::recompute_metrics(width, height, aspect);
set_custom_space(
0.0f,
m_visible_switch_groups
? ((m_visible_switch_groups * (DIP_SWITCH_HEIGHT * line_height())) + ((m_visible_switch_groups - 1) * (DIP_SWITCH_SPACING * line_height())) + (tb_border() * 3.0f))
: 0.0f);
}
void menu_settings_dip_switches::custom_render(void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2)
{
// catch if no DIP locations have to be drawn
@ -470,10 +482,10 @@ bool menu_settings_dip_switches::custom_mouse_down()
}
void menu_settings_dip_switches::populate(float &customtop, float &custombottom)
void menu_settings_dip_switches::populate()
{
// let the base class add items
menu_confswitch::populate(customtop, custombottom);
menu_confswitch::populate();
// use up to about 70% of height for DIP switch display
if (active_switch_groups())
@ -485,12 +497,12 @@ void menu_settings_dip_switches::populate(float &customtop, float &custombottom)
m_visible_switch_groups = unsigned(0.7f / (groupheight + groupspacing));
else
m_visible_switch_groups = active_switch_groups();
custombottom = (m_visible_switch_groups * groupheight) + ((m_visible_switch_groups - 1) * groupspacing) + (tb_border() * 3.0f);
set_custom_space(0.0f, (m_visible_switch_groups * groupheight) + ((m_visible_switch_groups - 1) * groupspacing) + (tb_border() * 3.0f));
}
else
{
m_visible_switch_groups = 0U;
custombottom = 0.0f;
set_custom_space(0.0f, 0.0f);
}
}

View File

@ -57,7 +57,7 @@ protected:
menu_confswitch(mame_ui_manager &mui, render_container &container, uint32_t type);
virtual void menu_activated() override;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
field_vector const &fields() { return m_fields; }
switch_group_vector const &switch_groups() { return m_switch_groups; }
@ -82,11 +82,12 @@ public:
virtual ~menu_settings_dip_switches() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_mouse_down() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
std::vector<float> m_switch_group_y;
unsigned m_visible_switch_groups;

View File

@ -209,7 +209,7 @@ void menu_custom_ui::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_custom_ui::populate(float &customtop, float &custombottom)
void menu_custom_ui::populate()
{
uint32_t arrow_flags;
item_append(_("Fonts"), 0, (void *)(uintptr_t)FONT_MENU);
@ -498,7 +498,7 @@ void menu_font_ui::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_font_ui::populate(float &customtop, float &custombottom)
void menu_font_ui::populate()
{
// set filter arrow
uint32_t arrow_flags;
@ -523,8 +523,17 @@ void menu_font_ui::populate(float &customtop, float &custombottom)
item_append(_("Infos text size"), string_format("%.2f", m_info_size), arrow_flags, (void *)(uintptr_t)INFOS_SIZE);
item_append(menu_item_type::SEPARATOR);
}
custombottom = line_height() + 3.0f * tb_border();
//-------------------------------------------------
// recompute metrics
//-------------------------------------------------
void menu_font_ui::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
set_custom_space(0.0f, line_height() + 3.0f * tb_border());
}
//-------------------------------------------------
@ -612,7 +621,7 @@ void menu_colors_ui::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_colors_ui::populate(float &customtop, float &custombottom)
void menu_colors_ui::populate()
{
item_append(_("color-option", "Normal text"), 0, (void *)(uintptr_t)MUI_TEXT_COLOR);
item_append(_("color-option", "Selected color"), 0, (void *)(uintptr_t)MUI_SELECTED_COLOR);
@ -634,8 +643,17 @@ void menu_colors_ui::populate(float &customtop, float &custombottom)
item_append(menu_item_type::SEPARATOR);
item_append(_("Restore default colors"), 0, (void *)(uintptr_t)MUI_RESTORE);
}
custombottom = line_height() + 3.0f * tb_border();
//-------------------------------------------------
// recompute metrics
//-------------------------------------------------
void menu_colors_ui::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
set_custom_space(0.0f, line_height() + 3.0f * tb_border());
}
//-------------------------------------------------
@ -876,7 +894,7 @@ void menu_rgb_ui::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_rgb_ui::populate(float &customtop, float &custombottom)
void menu_rgb_ui::populate()
{
// set filter arrow
std::string s_text = std::string(m_search).append("_");
@ -917,8 +935,17 @@ void menu_rgb_ui::populate(float &customtop, float &custombottom)
item_append(menu_item_type::SEPARATOR);
item_append(_("Choose from palette"), 0, (void *)(uintptr_t)PALETTE_CHOOSE);
item_append(menu_item_type::SEPARATOR);
}
custombottom = line_height() + 3.0f * tb_border();
//-------------------------------------------------
// recompute metrics
//-------------------------------------------------
void menu_rgb_ui::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
set_custom_space(0.0f, line_height() + 3.0f * tb_border());
}
//-------------------------------------------------
@ -1065,7 +1092,7 @@ void menu_palette_sel::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_palette_sel::populate(float &customtop, float &custombottom)
void menu_palette_sel::populate()
{
for (unsigned x = 0; x < std::size(s_palette); ++x)
item_append(_("color-preset", s_palette[x].first), s_palette[x].second, FLAG_COLOR_BOX, (void *)(uintptr_t)(x + 1));

View File

@ -33,7 +33,7 @@ protected:
virtual void menu_dismissed() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void find_languages();
@ -57,11 +57,12 @@ public:
menu_font_ui(mame_ui_manager &mui, render_container &container, std::function<void (bool)> &&handler);
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual void menu_dismissed() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void list();
@ -92,6 +93,7 @@ public:
menu_colors_ui(mame_ui_manager &mui, render_container &container);
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual void menu_dismissed() override;
@ -123,7 +125,7 @@ private:
const char *option;
};
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
s_color_table m_color_table[MUI_RESTORE];
@ -140,6 +142,7 @@ public:
menu_rgb_ui(mame_ui_manager &mui, render_container &container, rgb_t *color, std::string &&title);
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
@ -152,7 +155,7 @@ private:
PALETTE_CHOOSE
};
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void inkey_special(const event *menu_event);
@ -174,7 +177,7 @@ public:
menu_palette_sel(mame_ui_manager &mui, render_container &container, rgb_t &_color);
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
static std::pair<const char *, const char *> const s_palette[];

View File

@ -198,10 +198,19 @@ void menu_dats_view::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_dats_view::populate(float &customtop, float &custombottom)
void menu_dats_view::populate()
{
customtop = 2.0f * line_height() + 4.0f * tb_border();
custombottom = line_height() + 3.0f * tb_border();
}
//-------------------------------------------------
// recompute metrics
//-------------------------------------------------
void menu_dats_view::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu_textbox::recompute_metrics(width, height, aspect);
set_custom_space(2.0F * line_height() + 4.0F * tb_border(), line_height() + 3.0F * tb_border());
}
//-------------------------------------------------
@ -219,10 +228,10 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
maxwidth = std::max(maxwidth, width);
// compute our bounds
float x1 = 0.5f - 0.5f * maxwidth;
float x1 = 0.5F - 0.5F * maxwidth;
float x2 = x1 + maxwidth;
float y1 = origy1 - top;
float y2 = origy1 - 2.0f * tb_border() - line_height();
float y2 = origy1 - 2.0F * tb_border() - line_height();
// draw a box
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
@ -245,13 +254,13 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
maxwidth += width;
}
float space = (1.0f - maxwidth) / (m_items_list.size() * 2);
float space = (1.0F - maxwidth) / (m_items_list.size() * 2);
// compute our bounds
x1 -= lr_border();
x2 += lr_border();
y1 = y2 + tb_border();
y2 += line_height() + 2.0f * tb_border();
y2 += line_height() + 2.0F * tb_border();
// draw a box
ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
@ -283,7 +292,7 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
ui().draw_text_full(
container(),
elem.label,
x1, y1, 1.0f,
x1, y1, 1.0F,
text_layout::text_justify::LEFT, text_layout::word_wrapping::NEVER,
mame_ui_manager::NORMAL, fcolor, bcolor,
&width, nullptr,
@ -298,13 +307,13 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
std::string const revision(util::string_format(_("Revision: %1$s"), m_items_list[m_actual].revision));
width = get_text_width(
revision,
0.0f, 0.0f, 1.0f,
0.0F, 0.0F, 1.0F,
text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE);
width += 2 * lr_border();
maxwidth = std::max(origx2 - origx1, width);
// compute our bounds
x1 = 0.5f - 0.5f * maxwidth;
x1 = 0.5F - 0.5F * maxwidth;
x2 = x1 + maxwidth;
y1 = origy2 + tb_border();
y2 = origy2 + bottom;

View File

@ -43,6 +43,7 @@ public:
static void add_info_text(text_layout &layout, std::string_view text, rgb_t color, float size = 1.0f);
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_mouse_down() override;
@ -58,7 +59,7 @@ private:
std::string revision;
};
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void get_data(std::string &buffer);

View File

@ -355,7 +355,7 @@ void menu_device_config::populate_text(std::optional<text_layout> &layout, float
width = layout->actual_width();
}
void menu_device_config::populate(float &customtop, float &custombottom)
void menu_device_config::populate()
{
}

View File

@ -28,7 +28,7 @@ protected:
virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
device_slot_interface::slot_option const *const m_option;

View File

@ -82,7 +82,7 @@ public:
menu_remove_folder(mame_ui_manager &mui, render_container &container, int ref);
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
std::string m_searchpath;
@ -145,7 +145,7 @@ void menu_remove_folder::handle(event const *ev)
// populate menu
//-------------------------------------------------
void menu_remove_folder::populate(float &customtop, float &custombottom)
void menu_remove_folder::populate()
{
int folders_count = 0;
for (auto & elem : m_folders)
@ -165,12 +165,13 @@ public:
menu_add_change_folder(mame_ui_manager &mui, render_container &container, int ref, bool multipath);
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_cancel() override { return !m_search.empty(); }
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void update_search();
@ -296,7 +297,7 @@ void menu_add_change_folder::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_add_change_folder::populate(float &customtop, float &custombottom)
void menu_add_change_folder::populate()
{
int folders_count = 0;
@ -331,10 +332,18 @@ void menu_add_change_folder::populate(float &customtop, float &custombottom)
item_append(name, "[DIR]", 0, (void *)(uintptr_t)++folders_count);
item_append(menu_item_type::SEPARATOR);
}
//-------------------------------------------------
// recompute metrics
//-------------------------------------------------
void menu_add_change_folder::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
// configure the custom rendering
customtop = 2.0f * line_height() + 3.0f * tb_border();
custombottom = 1.0f * line_height() + 3.0f * tb_border();
set_custom_space(2.0f * line_height() + 3.0f * tb_border(), 1.0f * line_height() + 3.0f * tb_border());
}
//-------------------------------------------------
@ -431,6 +440,7 @@ public:
}
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
@ -440,7 +450,7 @@ private:
REMOVE,
};
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
bool is_multipath(std::string_view folder) const;
@ -492,7 +502,7 @@ void menu_display_actual::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_display_actual::populate(float &customtop, float &custombottom)
void menu_display_actual::populate()
{
auto const &folder = f_folders[m_ref];
auto option = ui().options().get_entry(folder.option);
@ -522,7 +532,18 @@ void menu_display_actual::populate(float &customtop, float &custombottom)
item_append(menu_item_type::SEPARATOR);
customtop = (m_folders.size() + 1) * line_height() + 6.0f * tb_border();
set_custom_space((m_folders.size() + 1) * line_height() + 6.0f * tb_border(), 0.0f);
}
//-------------------------------------------------
// recompute metrics
//-------------------------------------------------
void menu_display_actual::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
set_custom_space((m_folders.size() + 1) * line_height() + 6.0f * tb_border(), 0.0f);
}
//-------------------------------------------------
@ -579,7 +600,7 @@ void menu_directory::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_directory::populate(float &customtop, float &custombottom)
void menu_directory::populate()
{
for (auto & elem : f_folders)
item_append(_("path-option", elem.name), 0, this); // need a non-null reference pointer - value is immaterial

View File

@ -31,7 +31,7 @@ public:
virtual ~menu_directory() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};

View File

@ -74,7 +74,7 @@ menu_confirm_save_as::~menu_confirm_save_as()
// populate
//-------------------------------------------------
void menu_confirm_save_as::populate(float &customtop, float &custombottom)
void menu_confirm_save_as::populate()
{
item_append(_("File Already Exists - Override?"), FLAG_DISABLE, nullptr);
item_append(menu_item_type::SEPARATOR);
@ -133,6 +133,18 @@ menu_file_create::~menu_file_create()
}
//-------------------------------------------------
// recompute_metrics - recompute metrics
//-------------------------------------------------
void menu_file_create::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
set_custom_space(line_height() + 3.0F * tb_border(), 0.0F);
}
//-------------------------------------------------
// custom_render - perform our special rendering
//-------------------------------------------------
@ -140,8 +152,8 @@ menu_file_create::~menu_file_create()
void menu_file_create::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
{
extra_text_render(top, bottom, origx1, origy1, origx2, origy2,
m_current_directory,
std::string_view());
m_current_directory,
std::string_view());
}
@ -149,7 +161,7 @@ void menu_file_create::custom_render(void *selectedref, float top, float bottom,
// populate - populates the file creator menu
//-------------------------------------------------
void menu_file_create::populate(float &customtop, float &custombottom)
void menu_file_create::populate()
{
std::string buffer;
const image_device_format *format;
@ -178,8 +190,6 @@ void menu_file_create::populate(float &customtop, float &custombottom)
// finish up the menu
item_append(menu_item_type::SEPARATOR);
item_append(_("Create"), 0, ITEMREF_CREATE);
customtop = line_height() + 3.0f * tb_border();
}
@ -263,7 +273,7 @@ menu_select_format::~menu_select_format()
// populate
//-------------------------------------------------
void menu_select_format::populate(float &customtop, float &custombottom)
void menu_select_format::populate()
{
item_append(_("Select image format"), FLAG_DISABLE, nullptr);
for (unsigned int i = 0; i != m_formats.size(); i++)
@ -322,7 +332,7 @@ menu_select_floppy_init::~menu_select_floppy_init()
// populate
//-------------------------------------------------
void menu_select_floppy_init::populate(float &customtop, float &custombottom)
void menu_select_floppy_init::populate()
{
item_append(_("Select initial contents"), FLAG_DISABLE, nullptr);
int id = 0;

View File

@ -31,7 +31,7 @@ public:
virtual ~menu_confirm_save_as() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
bool *m_yes;
@ -47,10 +47,11 @@ public:
virtual ~menu_file_create() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
bool & m_ok;
@ -71,7 +72,7 @@ public:
virtual ~menu_select_format() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
// internal state
@ -90,7 +91,7 @@ public:
virtual ~menu_select_floppy_init() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
// internal state

View File

@ -53,6 +53,18 @@ menu_file_manager::~menu_file_manager()
}
//-------------------------------------------------
// recompute_metrics - recompute metrics
//-------------------------------------------------
void menu_file_manager::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
set_custom_space(0.0F, line_height() + 3.0F * tb_border());
}
//-------------------------------------------------
// custom_render - perform our special rendering
//-------------------------------------------------
@ -101,7 +113,7 @@ void menu_file_manager::fill_image_line(device_image_interface *img, std::string
// populate
//-------------------------------------------------
void menu_file_manager::populate(float &customtop, float &custombottom)
void menu_file_manager::populate()
{
std::string tmp_inst, tmp_name;
@ -152,8 +164,6 @@ void menu_file_manager::populate(float &customtop, float &custombottom)
if (m_warnings.empty() || !missing_mandatory)
item_append(m_warnings.empty() ? _("Reset System") : _("Start System"), 0, (void *)1);
custombottom = line_height() + 3.0f * tb_border();
}

View File

@ -30,10 +30,11 @@ public:
virtual ~menu_file_manager();
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void fill_image_line(device_image_interface *img, std::string &instance, std::string &filename);

View File

@ -72,6 +72,19 @@ menu_file_selector::~menu_file_selector()
}
//-------------------------------------------------
// recompute_metrics - recompute metrics
//-------------------------------------------------
void menu_file_selector::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
// set up custom render proc
set_custom_space(line_height() + 3.0F * tb_border(), 0.0F);
}
//-------------------------------------------------
// custom_render - perform our special rendering
//-------------------------------------------------
@ -347,7 +360,7 @@ void menu_file_selector::update_search()
// populate
//-------------------------------------------------
void menu_file_selector::populate(float &customtop, float &custombottom)
void menu_file_selector::populate()
{
const file_selector_entry *selected_entry = nullptr;
@ -426,9 +439,6 @@ void menu_file_selector::populate(float &customtop, float &custombottom)
// set the selection (if we have one)
if (selected_entry)
set_selection((void *)selected_entry);
// set up custom render proc
customtop = line_height() + 3.0f * tb_border();
}
@ -504,7 +514,7 @@ menu_select_rw::~menu_select_rw()
// populate
//-------------------------------------------------
void menu_select_rw::populate(float &customtop, float &custombottom)
void menu_select_rw::populate()
{
item_append(_("Select access mode"), FLAG_DISABLE, nullptr);
item_append(_("Read-only"), 0, itemref_from_result(result::READONLY));

View File

@ -44,6 +44,7 @@ public:
virtual ~menu_file_selector() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_cancel() override { return !m_filename.empty(); }
virtual bool custom_mouse_down() override;
@ -82,7 +83,7 @@ private:
std::string m_hover_directory;
std::string m_filename;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
// methods
@ -119,7 +120,7 @@ public:
static result result_from_itemref(void *itemref);
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
// internal state

View File

@ -184,7 +184,7 @@ void menu_control_device_image::hook_load(const std::string &name)
// populate
//-------------------------------------------------
void menu_control_device_image::populate(float &customtop, float &custombottom)
void menu_control_device_image::populate()
{
throw emu_fatalerror("menu_control_device_image::populate: Shouldn't get here!");
}

View File

@ -68,7 +68,7 @@ private:
std::string m_software_info_name;
// methods
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
void test_create(bool &can_create, bool &need_confirm);
void load_software_part();
};

View File

@ -548,7 +548,7 @@ void menu_game_info::populate_text(std::optional<text_layout> &layout, float &wi
width = layout->actual_width();
}
void menu_game_info::populate(float &customtop, float &custombottom)
void menu_game_info::populate()
{
}
@ -613,7 +613,7 @@ void menu_warn_info::populate_text(std::optional<text_layout> &layout, float &wi
width = layout->actual_width();
}
void menu_warn_info::populate(float &customtop, float &custombottom)
void menu_warn_info::populate()
{
}
@ -642,7 +642,7 @@ void menu_image_info::menu_activated()
reset(reset_options::REMEMBER_POSITION);
}
void menu_image_info::populate(float &customtop, float &custombottom)
void menu_image_info::populate()
{
for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
image_info(&image);

View File

@ -100,7 +100,7 @@ protected:
virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};
@ -115,7 +115,7 @@ protected:
virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};
@ -130,7 +130,7 @@ protected:
virtual void menu_activated() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void image_info(device_image_interface *image);
};

View File

@ -26,7 +26,7 @@ menu_pty_info::~menu_pty_info()
{
}
void menu_pty_info::populate(float &customtop, float &custombottom)
void menu_pty_info::populate()
{
for (device_pty_interface &pty : pty_interface_enumerator(machine().root_device()))
{

View File

@ -24,7 +24,7 @@ public:
virtual ~menu_pty_info() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};

View File

@ -27,6 +27,7 @@ public:
menu_input_device(mame_ui_manager &mui, render_container &container, input_device &device)
: menu(mui, container)
, m_device(device)
, m_have_analog(false)
{
set_heading(
util::string_format(_("menu-inputdev", "%1$s (%2$s %3$d)"),
@ -36,25 +37,54 @@ public:
}
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override
{
menu::recompute_metrics(width, height, aspect);
set_custom_space(0.0F, (line_height() * (m_have_analog ? 2.0F : 1.0F)) + (tb_border() * 3.0F));
}
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override
{
if (selectedref)
{
// get the complete token for the highlighted input
input_device_item &input = *reinterpret_cast<input_device_item *>(selectedref);
input_code code = input.code();
if (!machine().input().device_class(m_device.devclass()).multi())
code.set_device_index(0);
std::string const token = machine().input().code_to_token(code);
// measure the name of the token string
float const tokenwidth = (std::min)(get_string_width(token) + (gutter_width() * 2.0F), 1.0F);
float const boxwidth = (std::max)(tokenwidth, x2 - x);
rgb_t const fgcolor(ui().colors().text_color());
// draw the outer box
ui().draw_outlined_box(
container(),
(1.0F - boxwidth) * 0.5F, y2 + tb_border(),
(1.0F + boxwidth) * 0.5F, y2 + bottom,
ui().colors().background_color());
// show the token
draw_text_normal(
token,
(1.0F - boxwidth) * 0.5F, y2 + (tb_border() * 2.0F), boxwidth,
text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
fgcolor);
// first show the token
switch (input.itemclass())
{
case ITEM_CLASS_ABSOLUTE:
case ITEM_CLASS_RELATIVE:
{
// draw the outer box
ui().draw_outlined_box(container(), x, y2 + tb_border(), x2, y2 + bottom, ui().colors().background_color());
// draw the indicator
rgb_t const fgcolor(ui().colors().text_color());
float const indleft = x + lr_border();
float const indright = x2 - lr_border();
float const indtop = y2 + (tb_border() * 2.0F) + (line_height() * 0.2F);
float const indbottom = y2 + (tb_border() * 2.0F) + (line_height() * 0.8F);
float const indleft = x + gutter_width();
float const indright = x2 - gutter_width();
float const indtop = y2 + (tb_border() * 2.0F) + (line_height() * 1.2F);
float const indbottom = y2 + (tb_border() * 2.0F) + (line_height() * 1.8F);
float const indcentre = (x + x2) * 0.5F;
s32 const value = (input.itemclass() == ITEM_CLASS_ABSOLUTE) ? input.read_as_absolute(ITEM_MODIFIER_NONE) : input.read_as_relative(ITEM_MODIFIER_NONE);
if (0 < value)
@ -81,12 +111,11 @@ protected:
}
private:
virtual void populate(float &customtop, float &custombottom) override
virtual void populate() override
{
item_append(_("menu-inputdev", "Copy Device ID"), 0U, nullptr);
item_append(menu_item_type::SEPARATOR);
bool haveanalog = false;
for (input_item_id itemid = ITEM_ID_FIRST_VALID; m_device.maxitem() >= itemid; ++itemid)
{
input_device_item *const input = m_device.item(itemid);
@ -96,7 +125,7 @@ private:
{
case ITEM_CLASS_ABSOLUTE:
case ITEM_CLASS_RELATIVE:
haveanalog = true;
m_have_analog = true;
break;
default:
break;
@ -107,8 +136,7 @@ private:
item_append(menu_item_type::SEPARATOR);
if (haveanalog)
custombottom = line_height() + (tb_border() * 3.0F);
set_custom_space(0.0F, (line_height() * (m_have_analog ? 2.0F : 1.0F)) + (tb_border() * 3.0F));
}
virtual void handle(event const *ev) override
@ -148,6 +176,7 @@ private:
}
input_device &m_device;
bool m_have_analog;
};
} // anonymous namespace
@ -166,7 +195,7 @@ menu_input_devices::~menu_input_devices()
}
void menu_input_devices::populate(float &customtop, float &custombottom)
void menu_input_devices::populate()
{
// iterate input device classes and devices within each class
bool found = false;

View File

@ -25,7 +25,7 @@ public:
virtual ~menu_input_devices();
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};

View File

@ -33,7 +33,7 @@ menu_input_groups::~menu_input_groups()
{
}
void menu_input_groups::populate(float &customtop, float &custombottom)
void menu_input_groups::populate()
{
// build up the menu
item_append(_("User Interface"), 0, (void *)uintptr_t(IPG_UI + 1));
@ -82,7 +82,7 @@ void menu_input_general::menu_activated()
reset(reset_options::REMEMBER_POSITION);
}
void menu_input_general::populate(float &customtop, float &custombottom)
void menu_input_general::populate()
{
if (data.empty())
{
@ -130,7 +130,7 @@ void menu_input_general::populate(float &customtop, float &custombottom)
}
// populate the menu in a standard fashion
populate_sorted(customtop, custombottom);
populate_sorted();
item_append(menu_item_type::SEPARATOR);
}
@ -164,7 +164,7 @@ void menu_input_specific::menu_activated()
reset(reset_options::REMEMBER_POSITION);
}
void menu_input_specific::populate(float &customtop, float &custombottom)
void menu_input_specific::populate()
{
if (data.empty())
{
@ -249,7 +249,7 @@ void menu_input_specific::populate(float &customtop, float &custombottom)
// populate the menu in a standard fashion
if (!data.empty())
populate_sorted(customtop, custombottom);
populate_sorted();
else
item_append(_("[no assignable inputs are enabled]"), FLAG_DISABLE, nullptr);
@ -311,6 +311,16 @@ void menu_input::toggle_none_default(input_seq &selected_seq, input_seq &origina
selected_seq.reset();
}
void menu_input::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
// leave space for showing the input sequence below the menu
set_custom_space(0.0F, 2.0F * line_height() + 3.0F * tb_border());
}
void menu_input::custom_render(void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2)
{
if (pollingitem)
@ -554,7 +564,7 @@ void menu_input::handle(event const *ev)
// menu from them
//-------------------------------------------------
void menu_input::populate_sorted(float &customtop, float &custombottom)
void menu_input::populate_sorted()
{
const char *nameformat[INPUT_TYPE_TOTAL] = { nullptr };
@ -608,9 +618,6 @@ void menu_input::populate_sorted(float &customtop, float &custombottom)
appendprompt = util::string_format(_("Press %1$s to append\n"), ui().get_general_input_setting(IPT_UI_SELECT));
clearprompt = util::string_format(_("Press %1$s to clear\n"), ui().get_general_input_setting(IPT_UI_CLEAR));
defaultprompt = util::string_format(_("Press %1$s to restore default\n"), ui().get_general_input_setting(IPT_UI_CLEAR));
// leave space for showing the input sequence below the menu
custombottom = 2.0f * line_height() + 3.0f * tb_border();
}
} // namespace ui

View File

@ -28,7 +28,7 @@ public:
virtual ~menu_input_groups() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};
@ -64,7 +64,10 @@ protected:
menu_input(mame_ui_manager &mui, render_container &container);
void populate_sorted(float &customtop, float &custombottom);
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2) override;
void populate_sorted();
void toggle_none_default(input_seq &selected_seq, input_seq &original_seq, const input_seq &selected_defseq);
data_vector data;
@ -81,7 +84,6 @@ private:
osd_ticks_t modified_ticks;
input_seq starting_seq;
virtual void custom_render(void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2) override;
virtual void handle(event const *ev) override;
virtual void update_input(input_item_data &seqchangeditem) = 0;
};
@ -97,7 +99,7 @@ protected:
virtual void menu_activated() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void update_input(input_item_data &seqchangeditem) override;
const int group;
@ -114,7 +116,7 @@ protected:
virtual void menu_activated() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void update_input(input_item_data &seqchangeditem) override;
};

View File

@ -87,7 +87,7 @@ void menu_input_options::menu_activated()
}
void menu_input_options::populate(float &customtop, float &custombottom)
void menu_input_options::populate()
{
bool inputmap, analog, toggle;
scan_inputs(machine(), inputmap, analog, toggle);

View File

@ -28,7 +28,7 @@ protected:
virtual void menu_activated() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};

View File

@ -35,7 +35,7 @@ void menu_input_toggles::menu_activated()
}
void menu_input_toggles::populate(float &customtop, float &custombottom)
void menu_input_toggles::populate()
{
// find toggle fields
if (m_fields.empty())

View File

@ -31,7 +31,7 @@ protected:
virtual void menu_activated() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
std::vector<std::reference_wrapper<ioport_field> > m_fields;

View File

@ -35,7 +35,7 @@ void menu_keyboard_mode::menu_activated()
reset(reset_options::REMEMBER_POSITION);
}
void menu_keyboard_mode::populate(float &customtop, float &custombottom)
void menu_keyboard_mode::populate()
{
natural_keyboard &natkbd(machine().natkeyboard());

View File

@ -27,7 +27,7 @@ protected:
virtual void menu_activated() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};

View File

@ -108,7 +108,7 @@ void menu_main::menu_activated()
populate - populate main menu items
-------------------------------------------------*/
void menu_main::populate(float &customtop, float &custombottom)
void menu_main::populate()
{
m_phase = machine().phase();

View File

@ -28,7 +28,7 @@ protected:
virtual void menu_activated() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
machine_phase m_phase;

View File

@ -373,6 +373,18 @@ void menu::item_append_on_off(const std::string &text, bool state, uint32_t flag
}
//-------------------------------------------------
// set_custom_space - set space required for
// custom rendering above and below menu
//-------------------------------------------------
void menu::set_custom_space(float top, float bottom)
{
m_customtop = top;
m_custombottom = bottom;
}
//-------------------------------------------------
// process - process a menu, drawing it
// and returning any interesting events
@ -1260,7 +1272,7 @@ void menu::do_handle()
item_append(_("Return to Previous Menu"), 0, nullptr);
// let implementation add other items
populate(m_customtop, m_custombottom);
populate();
}
catch (...)
{

View File

@ -70,6 +70,9 @@ public:
void item_append(menu_item_type type, uint32_t flags = 0);
void item_append_on_off(const std::string &text, bool state, uint32_t flags, void *ref, menu_item_type type = menu_item_type::UNKNOWN);
// set space required for drawing extra content
void set_custom_space(float top, float bottom);
// reset the menus, clearing everything
static void stack_reset(mame_ui_manager &ui) { get_global_state(ui).stack_reset(); }
@ -422,7 +425,7 @@ private:
void set_special_main_menu(bool disable);
// to be implemented in derived classes
virtual void populate(float &customtop, float &custombottom) = 0;
virtual void populate() = 0;
// to be implemented in derived classes
virtual void handle(event const *ev) = 0;

View File

@ -54,7 +54,7 @@ menu_bios_selection::menu_bios_selection(mame_ui_manager &mui, render_container
set_heading(_("BIOS Selection"));
}
void menu_bios_selection::populate(float &customtop, float &custombottom)
void menu_bios_selection::populate()
{
// cycle through all devices for this system
for (device_t &device : device_enumerator(machine().root_device()))
@ -159,7 +159,7 @@ menu_network_devices::~menu_network_devices()
network device menu
-------------------------------------------------*/
void menu_network_devices::populate(float &customtop, float &custombottom)
void menu_network_devices::populate()
{
/* cycle through all devices for this system */
for (device_network_interface &network : network_interface_enumerator(machine().root_device()))
@ -268,7 +268,7 @@ void menu_bookkeeping::populate_text(std::optional<text_layout> &layout, float &
width = layout->actual_width();
}
void menu_bookkeeping::populate(float &customtop, float &custombottom)
void menu_bookkeeping::populate()
{
}
@ -397,7 +397,7 @@ menu_crosshair::menu_crosshair(mame_ui_manager &mui, render_container &container
set_heading(_("menu-crosshair", "Crosshair Options"));
}
void menu_crosshair::populate(float &customtop, float &custombottom)
void menu_crosshair::populate()
{
if (m_data.empty())
{
@ -701,7 +701,7 @@ void menu_export::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_export::populate(float &customtop, float &custombottom)
void menu_export::populate()
{
// add options items
item_append(_("Export list in XML format (like -listxml)"), 0, (void *)(uintptr_t)1);
@ -811,7 +811,7 @@ void menu_machine_configure::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_machine_configure::populate(float &customtop, float &custombottom)
void menu_machine_configure::populate()
{
// add options items
item_append(_("BIOS"), FLAG_DISABLE | FLAG_UI_HEADING, nullptr);
@ -930,7 +930,7 @@ void menu_plugins_configure::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_plugins_configure::populate(float &customtop, float &custombottom)
void menu_plugins_configure::populate()
{
plugin_options const &plugins = mame_machine_manager::instance()->plugins();

View File

@ -33,7 +33,7 @@ public:
virtual ~menu_network_devices();
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};
@ -48,7 +48,7 @@ protected:
virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
attotime prevtime;
@ -81,7 +81,7 @@ private:
std::string next_name;
};
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
std::vector<crosshair_item_data> m_data;
@ -96,7 +96,7 @@ public:
virtual ~menu_bios_selection();
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};
@ -112,7 +112,7 @@ public:
virtual ~menu_export();
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
std::vector<const game_driver*> m_list;
@ -148,7 +148,7 @@ private:
LAST = ADVANCED
};
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void setup_bios();
@ -174,7 +174,7 @@ public:
virtual ~menu_plugins_configure();
protected:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};

View File

@ -71,7 +71,7 @@ void menu_simple_game_options::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_simple_game_options::populate(float &customtop, float &custombottom)
void menu_simple_game_options::populate()
{
item_append(_(submenu::video_options()[0].description), 0, (void *)(uintptr_t)DISPLAY_MENU);
item_append(_("Sound Options"), 0, (void *)(uintptr_t)SOUND_MENU);
@ -85,8 +85,6 @@ void menu_simple_game_options::populate(float &customtop, float &custombottom)
item_append(_("Input Devices"), 0, (void *)(uintptr_t)INPUTDEV_MENU);
item_append(menu_item_type::SEPARATOR);
item_append(_("Save Settings"), 0, (void *)(uintptr_t)SAVE_CONFIG);
custombottom = 2.0f * line_height() + 3.0f * tb_border();
}
//-------------------------------------------------
@ -174,7 +172,7 @@ void menu_game_options::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_game_options::populate(float &customtop, float &custombottom)
void menu_game_options::populate()
{
// set filter arrow
std::string fbuff;
@ -198,7 +196,7 @@ void menu_game_options::populate(float &customtop, float &custombottom)
item_append(_("Configure Folders"), 0, (void *)(uintptr_t)CONF_DIR);
// add the options that don't relate to the UI
menu_simple_game_options::populate(customtop, custombottom);
menu_simple_game_options::populate();
}
//-------------------------------------------------

View File

@ -29,7 +29,7 @@ public:
protected:
virtual void handle(event const *ev) override;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
void handle_item_event(event const &menu_event);
@ -63,7 +63,7 @@ public:
protected:
virtual void handle(event const *ev) override;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
void handle_item_event(event const &menu_event);

View File

@ -35,7 +35,7 @@ menu_plugin::menu_plugin(mame_ui_manager &mui, render_container &container) :
set_heading(_("Plugin Options"));
}
void menu_plugin::populate(float &customtop, float &custombottom)
void menu_plugin::populate()
{
for (auto &curplugin : m_plugins)
item_append(curplugin, 0, (void *)curplugin.c_str());
@ -125,7 +125,7 @@ void menu_plugin_opt::handle(event const *ev)
}
}
void menu_plugin_opt::populate(float &customtop, float &custombottom)
void menu_plugin_opt::populate()
{
std::vector<std::tuple<std::string, std::string, std::string>> menu_list;
std::string flags;

View File

@ -32,7 +32,7 @@ public:
virtual ~menu_plugin();
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
std::vector<std::string> &m_plugins;
@ -48,7 +48,7 @@ protected:
virtual bool custom_ui_cancel() override { return true; }
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
std::string const m_menu;

View File

@ -45,7 +45,7 @@ void menu_confirm_quit::custom_render(void *selectedref, float top, float bottom
}
void menu_confirm_quit::populate(float &customtop, float &custombottom)
void menu_confirm_quit::populate()
{
}

View File

@ -27,7 +27,7 @@ protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};

View File

@ -95,7 +95,7 @@ void menu_selector::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_selector::populate(float &customtop, float &custombottom)
void menu_selector::populate()
{
set_heading(util::string_format(_("menu-selector", "%1$s - Search: %2$s_"), m_title, m_search));
@ -124,10 +124,20 @@ void menu_selector::populate(float &customtop, float &custombottom)
}
item_append(menu_item_type::SEPARATOR);
custombottom = line_height() + 3.0f * tb_border();
m_initial = -1;
}
//-------------------------------------------------
// recompute metrics
//-------------------------------------------------
void menu_selector::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
set_custom_space(0.0F, line_height() + 3.0F * tb_border());
}
//-------------------------------------------------
// perform our special rendering
//-------------------------------------------------

View File

@ -38,13 +38,14 @@ public:
virtual ~menu_selector() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_cancel() override { return !m_search.empty(); }
private:
enum { VISIBLE_SEARCH_ITEMS = 200 };
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void find_matches(const char *str);

View File

@ -135,6 +135,9 @@ void menu_select_game::recompute_metrics(uint32_t width, uint32_t height, float
menu_select_launch::recompute_metrics(width, height, aspect);
m_icons.clear();
// configure the custom rendering
set_custom_space(3.0F * line_height() + 5.0F * tb_border(), 4.0F * line_height() + 3.0F * tb_border());
}
@ -346,7 +349,7 @@ void menu_select_game::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_select_game::populate(float &customtop, float &custombottom)
void menu_select_game::populate()
{
for (auto &icon : m_icons) // TODO: why is this here? maybe better on resize or setting change?
icon.second.texture.reset();
@ -468,10 +471,6 @@ void menu_select_game::populate(float &customtop, float &custombottom)
m_skip_main_items = 0;
}
// configure the custom rendering
customtop = 3.0f * line_height() + 5.0f * tb_border();
custombottom = 4.0f * line_height() + 3.0f * tb_border();
// reselect prior game launched, if any
if (old_item_selected != -1)
{

View File

@ -58,7 +58,7 @@ private:
static bool s_first_start;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
// drawing

View File

@ -172,7 +172,7 @@ public:
virtual ~software_parts() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
ui_software_info const &m_uiinfo;
@ -189,7 +189,7 @@ public:
private:
bios_selection(mame_ui_manager &mui, render_container &container, s_bios &&biosname, void const *driver, bool software, bool inlist);
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
void const *m_driver;
@ -280,7 +280,7 @@ menu_select_launch::software_parts::~software_parts()
// populate
//-------------------------------------------------
void menu_select_launch::software_parts::populate(float &customtop, float &custombottom)
void menu_select_launch::software_parts::populate()
{
std::vector<s_parts::const_iterator> parts;
parts.reserve(m_parts.size());
@ -350,7 +350,7 @@ menu_select_launch::bios_selection::~bios_selection()
// populate
//-------------------------------------------------
void menu_select_launch::bios_selection::populate(float &customtop, float &custombottom)
void menu_select_launch::bios_selection::populate()
{
for (auto &elem : m_bios)
item_append(elem.first, 0, (void *)&elem.first);

View File

@ -525,6 +525,18 @@ void menu_select_software::handle(event const *ev)
draw_error_text();
}
//-------------------------------------------------
// recompute_metrics
//-------------------------------------------------
void menu_select_software::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu_select_launch::recompute_metrics(width, height, aspect);
// configure the custom rendering
set_custom_space(4.0F * line_height() + 5.0F * tb_border(), 4.0F * line_height() + 4.0F * tb_border());
}
//-------------------------------------------------
// menu_deactivated
//-------------------------------------------------
@ -545,7 +557,7 @@ void menu_select_software::menu_deactivated()
// populate
//-------------------------------------------------
void menu_select_software::populate(float &customtop, float &custombottom)
void menu_select_software::populate()
{
for (auto &icon : m_data->icons()) // TODO: why is this here? maybe better on resize or setting change?
icon.second.texture.reset();
@ -605,10 +617,7 @@ void menu_select_software::populate(float &customtop, float &custombottom)
m_displaylist[curitem].get().parentname.empty() ? 0 : FLAG_INVERT, (void *)&m_displaylist[curitem].get());
}
// configure the custom rendering
m_skip_main_items = 0;
customtop = 4.0f * line_height() + 5.0f * tb_border();
custombottom = 4.0f * line_height() + 4.0f * tb_border();
if (old_software != -1)
{

View File

@ -33,6 +33,8 @@ public:
virtual ~menu_select_software() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void menu_deactivated() override;
private:
@ -42,7 +44,7 @@ private:
struct search_item;
class machine_data;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
// drawing

View File

@ -236,7 +236,7 @@ void simple_menu_select_game::inkey_special(const event &menu_event)
// populate - populate the game select menu
//-------------------------------------------------
void simple_menu_select_game::populate(float &customtop, float &custombottom)
void simple_menu_select_game::populate()
{
int matchcount;
int curitem;
@ -282,10 +282,19 @@ void simple_menu_select_game::populate(float &customtop, float &custombottom)
{
item_append(_("Return to Previous Menu"), 0, nullptr);
}
}
//-------------------------------------------------
// recompute_metrics - recompute metrics
//-------------------------------------------------
void simple_menu_select_game::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
// configure the custom rendering
customtop = line_height() + 3.0f * tb_border();
custombottom = 4.0f * line_height() + 3.0f * tb_border();
set_custom_space(line_height() + 3.0f * tb_border(), 4.0f * line_height() + 3.0f * tb_border());
}

View File

@ -29,13 +29,14 @@ public:
static void force_game_select(mame_ui_manager &mui, render_container &container);
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_ui_cancel() override { return !m_search.empty(); }
private:
enum { VISIBLE_GAMES_IN_LIST = 15 };
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
// internal methods

View File

@ -160,7 +160,7 @@ void menu_sliders::handle(event const *ev)
// menu
//-------------------------------------------------
void menu_sliders::populate(float &customtop, float &custombottom)
void menu_sliders::populate()
{
std::string tempstring;
@ -224,8 +224,18 @@ void menu_sliders::populate(float &customtop, float &custombottom)
if (ref)
set_selection(ref);
}
}
custombottom = 2.0f * line_height() + 2.0f * tb_border();
//-------------------------------------------------
// recompute_metrics - recompute metrics
//-------------------------------------------------
void menu_sliders::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
set_custom_space(0.0f, 2.0f * line_height() + 2.0f * tb_border());
}

View File

@ -25,12 +25,13 @@ public:
virtual ~menu_sliders() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual void menu_activated() override;
virtual void menu_deactivated() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
bool const m_menuless_mode;

View File

@ -171,7 +171,7 @@ bool menu_slot_devices::try_refresh_current_options()
// populate
//-------------------------------------------------
void menu_slot_devices::populate(float &customtop, float &custombottom)
void menu_slot_devices::populate()
{
// we need to keep our own copy of the machine_config because we
// can change this out from under the caller
@ -202,9 +202,19 @@ void menu_slot_devices::populate(float &customtop, float &custombottom)
}
item_append(menu_item_type::SEPARATOR);
item_append(_("Reset System"), 0, ITEMREF_RESET);
}
//-------------------------------------------------
// recompute metrics
//-------------------------------------------------
void menu_slot_devices::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
// leave space for the name of the current option at the bottom
custombottom = line_height() + 3.0f * tb_border();
set_custom_space(0.0F, line_height() + 3.0F * tb_border());
}

View File

@ -25,6 +25,10 @@ public:
menu_slot_devices(mame_ui_manager &mui, render_container &container);
virtual ~menu_slot_devices() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) override;
private:
enum class step_t
{
@ -32,8 +36,7 @@ private:
PREVIOUS
};
virtual void populate(float &customtop, float &custombottom) override;
virtual void custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
device_slot_interface::slot_option const *get_current_option(device_slot_interface &slot) const;

View File

@ -139,7 +139,7 @@ void menu_sound_options::handle(event const *ev)
// populate
//-------------------------------------------------
void menu_sound_options::populate(float &customtop, float &custombottom)
void menu_sound_options::populate()
{
uint32_t arrow_flags = get_arrow_flags(uint16_t(0), uint16_t(std::size(m_sound_rate) - 1), m_cur_rates);
m_sample_rate = m_sound_rate[m_cur_rates];

View File

@ -38,7 +38,7 @@ private:
ENABLE_SAMPLES
};
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
uint16_t m_cur_rates;

View File

@ -118,7 +118,7 @@ menu_load_save_state_base::~menu_load_save_state_base()
// populate
//-------------------------------------------------
void menu_load_save_state_base::populate(float &customtop, float &custombottom)
void menu_load_save_state_base::populate()
{
// build the "filename to code" map, if we have not already (if it were not for the
// possibility that the system keyboard can be changed at runtime, I would put this
@ -224,9 +224,6 @@ void menu_load_save_state_base::populate(float &customtop, float &custombottom)
if (is_one_shot())
item_append(_("Cancel"), 0, nullptr);
// set up custom render proc
custombottom = (2.0f * line_height()) + (3.0f * tb_border());
// get ready to poll inputs
m_switch_poller.reset();
m_keys_released = false;
@ -420,6 +417,19 @@ void menu_load_save_state_base::handle_keys(uint32_t flags, int &iptkey)
}
//-------------------------------------------------
// recompute_metrics - recompute metrics
//-------------------------------------------------
void menu_load_save_state_base::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
autopause_menu<>::recompute_metrics(width, height, aspect);
// set up custom render proc
set_custom_space(0.0F, (2.0F * line_height()) + (3.0F * tb_border()));
}
//-------------------------------------------------
// custom_render - perform our special rendering
//-------------------------------------------------
@ -446,14 +456,14 @@ void menu_load_save_state_base::custom_render(void *selectedref, float top, floa
{
draw_text_box(
std::begin(text), std::next(std::begin(text), count),
origx1, origx2, origy2 + tb_border(), origy2 + (count * line_height()) + (3.0f * tb_border()),
origx1, origx2, origy2 + tb_border(), origy2 + (count * line_height()) + (3.0F * tb_border()),
text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), ui().colors().background_color());
}
// draw the confirmation prompt if necessary
if (!m_confirm_prompt.empty())
ui().draw_text_box(container(), m_confirm_prompt, text_layout::text_justify::CENTER, 0.5f, 0.5f, ui().colors().background_color());
ui().draw_text_box(container(), m_confirm_prompt, text_layout::text_justify::CENTER, 0.5F, 0.5F, ui().colors().background_color());
}

View File

@ -36,9 +36,10 @@ protected:
bool must_exist,
bool one_shot);
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual void handle_keys(uint32_t flags, int &iptkey) override;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
virtual void process_file(std::string &&file_name) = 0;

View File

@ -285,7 +285,7 @@ void submenu::handle(event const *ev)
const char *minimum = sm_option.entry->minimum();
const char *maximum = sm_option.entry->maximum();
f_step = atof(minimum);
if (f_step <= 0.0f) {
if (f_step <= 0.0F) {
int pmin = getprecisionchr(minimum);
int pmax = getprecisionchr(maximum);
tmptxt = '1' + std::string((pmin > pmax) ? pmin : pmax, '0');
@ -339,7 +339,7 @@ void submenu::handle(event const *ev)
// populate
//-------------------------------------------------
void submenu::populate(float &customtop, float &custombottom)
void submenu::populate()
{
// add options
for (auto sm_option = m_options.begin(); sm_option < m_options.end(); ++sm_option)
@ -405,7 +405,7 @@ void submenu::populate(float &customtop, float &custombottom)
}
else
{
f_min = 0.0f;
f_min = 0.0F;
f_max = std::numeric_limits<float>::max();
}
arrow_flags = get_arrow_flags(f_min, f_max, f_cur);
@ -446,7 +446,17 @@ void submenu::populate(float &customtop, float &custombottom)
}
item_append(menu_item_type::SEPARATOR);
custombottom = ui().get_line_height() + (3.0f * tb_border());
}
//-------------------------------------------------
// recompute metrics
//-------------------------------------------------
void submenu::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
set_custom_space(0.0F, line_height() + (3.0F * tb_border()));
}
//-------------------------------------------------

View File

@ -60,10 +60,11 @@ public:
//static std::vector<option> export_options();
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
std::vector<option> m_options;

View File

@ -77,7 +77,7 @@ menu_software_parts::~menu_software_parts()
// populate
//-------------------------------------------------
void menu_software_parts::populate(float &customtop, float &custombottom)
void menu_software_parts::populate()
{
m_entries.clear();
@ -243,7 +243,7 @@ void menu_software_list::update_search(void *selectedref)
// populate
//-------------------------------------------------
void menu_software_list::populate(float &customtop, float &custombottom)
void menu_software_list::populate()
{
// build up the list of entries for the menu
if (m_entrylist.empty())
@ -368,7 +368,7 @@ menu_software::~menu_software()
// populate
//-------------------------------------------------
void menu_software::populate(float &customtop, float &custombottom)
void menu_software::populate()
{
bool have_compatible = false;

View File

@ -43,7 +43,7 @@ private:
};
using entry_list = std::list<software_part_menu_entry>;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
// variables
@ -88,7 +88,7 @@ private:
std::string m_search;
bool m_ordered_by_shortname;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
// functions
@ -104,7 +104,7 @@ class menu_software : public menu
public:
menu_software(mame_ui_manager &mui, render_container &container, const char *interface, software_list_device **result);
virtual ~menu_software() override;
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
private:

View File

@ -56,7 +56,7 @@ menu_tape_control::~menu_tape_control()
// populate - populates the main tape control menu
//-------------------------------------------------
void menu_tape_control::populate(float &customtop, float &custombottom)
void menu_tape_control::populate()
{
if (current_device())
{

View File

@ -25,7 +25,7 @@ public:
virtual ~menu_tape_control() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
static void get_time_string(std::string &dest, cassette_image_device *cassette, int *curpos, int *endpos);

View File

@ -91,6 +91,18 @@ void menu_textbox::handle_key(int key)
}
//-------------------------------------------------
// recompute_metrics - recompute metrics
//-------------------------------------------------
void menu_textbox::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
m_layout = std::nullopt;
}
//-------------------------------------------------
// custom_mouse_scroll - handle scroll events
//-------------------------------------------------

View File

@ -31,6 +31,7 @@ protected:
virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) = 0;
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual bool custom_mouse_scroll(int lines) override;
private:

View File

@ -403,7 +403,7 @@ private:
ADD_FILTER
};
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
bool set_filter_type(unsigned pos, typename Base::type n)
@ -529,7 +529,7 @@ void composite_filter_impl_base<Impl, Base, Type>::show_ui(
template <class Impl, class Base, typename Base::type Type>
void composite_filter_impl_base<Impl, Base, Type>::menu_configure::populate(float &customtop, float &custombottom)
void composite_filter_impl_base<Impl, Base, Type>::menu_configure::populate()
{
// add items for each active filter
unsigned i = 0;
@ -995,7 +995,7 @@ private:
INCLUDE_CLONES
};
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
category_machine_filter &m_parent;
@ -1047,7 +1047,7 @@ void category_machine_filter::show_ui(mame_ui_manager &mui, render_container &co
}
void category_machine_filter::menu_configure::populate(float &customtop, float &custombottom)
void category_machine_filter::menu_configure::populate()
{
inifile_manager const &mgr(mame_machine_manager::instance()->inifile());
unsigned const filecnt(mgr.get_file_count());

View File

@ -46,7 +46,7 @@ menu_video_targets::~menu_video_targets()
{
}
void menu_video_targets::populate(float &customtop, float &custombottom)
void menu_video_targets::populate()
{
// find the targets
for (unsigned targetnum = 0; ; targetnum++)
@ -113,7 +113,7 @@ menu_video_options::~menu_video_options()
{
}
void menu_video_options::populate(float &customtop, float &custombottom)
void menu_video_options::populate()
{
uintptr_t ref;

View File

@ -26,7 +26,7 @@ public:
virtual ~menu_video_targets() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
};
@ -38,7 +38,7 @@ public:
virtual ~menu_video_options() override;
private:
virtual void populate(float &customtop, float &custombottom) override;
virtual void populate() override;
virtual void handle(event const *ev) override;
render_target &m_target;

File diff suppressed because it is too large Load Diff

View File

@ -71,10 +71,10 @@ void sdl_event_manager::process_events(running_machine &machine)
auto subscribers = m_subscription_index.equal_range(sdlevent.type);
// Dispatch the events
std::for_each(subscribers.first, subscribers.second, [&sdlevent](auto sub)
{
sub.second->handle_event(sdlevent);
});
std::for_each(
subscribers.first,
subscribers.second,
[&sdlevent] (auto sub) { sub.second->handle_event(sdlevent); });
}
}

View File

@ -226,8 +226,6 @@ protected:
if (result != DI_OK)
fatalerror("DirectInput: Unable to enumerate game controllers (result=%08X)\n", uint32_t(result));
xinput_joystick_device *devinfo;
// now add all xinput devices
if (!m_xinput_detect_failed)
{
@ -236,16 +234,9 @@ protected:
{
XINPUT_STATE state = { 0 };
// allocate and link in a new device
if (m_xinput_helper->xinput_get_state(i, &state) == ERROR_SUCCESS)
{
// allocate and link in a new device
devinfo = m_xinput_helper->create_xinput_device(machine, i, *this);
if (!devinfo)
continue;
// Configure each gamepad to add buttons and Axes, etc.
devinfo->configure();
}
m_xinput_helper->create_xinput_device(machine, i, *this);
}
}
}

View File

@ -5,6 +5,101 @@
// input_xinput.cpp - XInput API input support for Windows
//
//============================================================
/*
XInput is infamously inflexible. It currently only supports a single
controller type (game controller) with a fixed report format. The
report format includes:
* 16-bit field for single-bit buttons and D-pad directions (two bits
undefined)
* Two 8-bit axis values, used for triggers, pedals, buttons or throttle
and rudder controls, depending on the controller
* Four 16-bit axis values, used for joysticks, steering wheels or hat
switches, depending on the controller
Some button names have changed at various times:
* Face buttons White and Black became shoulder buttons LB and RB,
respectively.
* Navigation buttons Start and Back became Menu and View, respectively.
Subtype Gamepad Wheel Arcade stick Arcade pad Flight stick Dance pad Guitar Drum kit
D-pad D-pad D-pad Joystick D-pad Foot switch D-Pad/Strum D-pad
L trigger Trigger Brake Button Button Rudder Pickup select^
R trigger Trigger Accelerator Button Button Throttle ^
L stick X Stick Wheel Roll
L stick Y Stick Pitch
R stick X Stick Hat left/right Whammy bar
R stick Y Stick Hat up/down Orientation
A Button Button Button Button Primary fire Foot switch Fret 1 Floor tom
B Button Button Button Button Secondary fire Foot switch Fret 2 Snare
X Button Button Button Button Button Foot switch Fret 4 Low tom
Y Button Button Button Button Button Foot switch Fret 3 High tom
LB Button Button Button^ Button Button^ Fret 5 Bass drum
RB Button Button Button^ Button Button^ Button^ Button^
LSB Button Button^ Button^ Button^ Button^ Fret mod^ Button^
RSB Button Button^ Button^ Button^ Button^ Button^ Button^
^ optional
There are multiple physical button layouts for arcade sticks, for
example:
Gamester Xbox Arcade Stick, Hori Real Arcade Pro EX
LT X Y LB
RT A B RB
PXN 0082 Arcade Stick
LB X Y RB
LT A B RT
Mortal Kombat Tournament Edition Arcade Stick
X Y
RT
LB A B
Hori Fighting Stick EX2
B X Y
A LT RT
Hori Real Arcade Pro VX-SA Kai, Razer Atrox
B X Y LB
A LT RT RB
Hori Real Arcade Pro.V Kai, Mayflash F300, Mayflash F500
X Y RB LB
A B RT LT
Mad Catz Brawl Stick
X Y LB LT
A B RB RT
Arcade pads typically have six face buttons, and come with different
layouts corresponding to the latter two arcade stick layouts, with the
rightmost column on the shoulder buttons.
Dance mats usually have this layout:
BK ST
B U A
L R
Y D X
This layout seems somewhat unusual:
BK ST
A U B
L R
X D Y
This layout is also available but rare:
BK ST
A U B
L R
Y D X
*/
#include "modules/osdmodule.h"
@ -17,83 +112,441 @@
// standard windows headers
#include <windows.h>
#include <algorithm>
#include <cstdint>
#include <string>
#include <tuple>
#include <utility>
#define XINPUT_LIBRARIES { "xinput1_4.dll", "xinput9_1_0.dll" }
#define XINPUT_AXIS_MINVALUE -32767
#define XINPUT_AXIS_MAXVALUE 32767
#define XINPUT_AXIS_MINVALUE (-32'767)
#define XINPUT_AXIS_MAXVALUE (32'767)
namespace {
// default axis names
const char *const xinput_axis_name[] =
char const *const AXIS_NAMES_GAMEPAD[]{
"LSX",
"LSY",
"RSX",
"RSY",
"LT",
"RT" };
char const *const AXIS_NAMES_WHEEL[]{
"Wheel",
"LSY",
"RSX",
"RSY",
"Brake",
"Accelerator" };
char const *const AXIS_NAMES_FLIGHT_STICK[]{
"Joystick X",
"Joystick Y",
nullptr,
nullptr,
"Rudder",
"Throttle" };
input_item_id const AXIS_IDS_GAMEPAD[]{
ITEM_ID_XAXIS,
ITEM_ID_YAXIS,
ITEM_ID_ZAXIS,
ITEM_ID_RZAXIS,
ITEM_ID_SLIDER1,
ITEM_ID_SLIDER2 };
input_item_id const AXIS_IDS_FLIGHT_STICK[]{
ITEM_ID_XAXIS,
ITEM_ID_YAXIS,
ITEM_ID_INVALID,
ITEM_ID_INVALID,
ITEM_ID_RZAXIS,
ITEM_ID_ZAXIS };
const char *const HAT_NAMES_GAMEPAD[]{
"D-pad Up",
"D-pad Down",
"D-pad Left",
"D-pad Right",
"POV Hat Up",
"POV Hat Down",
"POV Hat Left",
"POV Hat Right" };
const char *const HAT_NAMES_ARCADE_STICK[]{
"Joystick Up",
"Joystick Down",
"Joystick Left",
"Joystick Right",
nullptr,
nullptr,
nullptr,
nullptr };
//============================================================
// xinput_joystick_device
//============================================================
class xinput_joystick_device : public device_info
{
"LSX",
"LSY",
"RSX",
"RSY"
public:
xinput_joystick_device(
running_machine &machine,
std::string &&name,
std::string &&id,
input_module &module,
uint32_t player,
XINPUT_CAPABILITIES const &caps,
std::shared_ptr<xinput_api_helper> helper);
void poll() override;
void reset() override;
void configure();
private:
static inline constexpr USHORT SWITCH_BITS[] =
{
XINPUT_GAMEPAD_A,
XINPUT_GAMEPAD_B,
XINPUT_GAMEPAD_X,
XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_LEFT_SHOULDER,
XINPUT_GAMEPAD_RIGHT_SHOULDER,
XINPUT_GAMEPAD_LEFT_THUMB,
XINPUT_GAMEPAD_RIGHT_THUMB,
XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_BACK,
XINPUT_GAMEPAD_DPAD_UP,
XINPUT_GAMEPAD_DPAD_DOWN,
XINPUT_GAMEPAD_DPAD_LEFT,
XINPUT_GAMEPAD_DPAD_RIGHT
};
enum
{
SWITCH_A, // button bits
SWITCH_B,
SWITCH_X,
SWITCH_Y,
SWITCH_LB,
SWITCH_RB,
SWITCH_LSB,
SWITCH_RSB,
SWITCH_START,
SWITCH_BACK,
SWITCH_DPAD_UP, // D-pad bits
SWITCH_DPAD_DOWN,
SWITCH_DPAD_LEFT,
SWITCH_DPAD_RIGHT,
SWITCH_HAT_UP, // for flight stick with POV hat as right stick
SWITCH_HAT_DOWN,
SWITCH_HAT_LEFT,
SWITCH_HAT_RIGHT,
SWITCH_LT, // for arcade stick/pad with LT/RT buttons
SWITCH_RT,
SWITCH_TOTAL
};
enum
{
AXIS_LT, // half-axes for triggers
AXIS_RT,
AXIS_LSX, // full-precision axes
AXIS_LSY,
AXIS_RSX,
AXIS_RSY,
AXIS_RUDDER, // LT/RT mapped differently for flight sticks
AXIS_THROTTLE,
AXIS_TOTAL
};
uint32_t const m_player_index;
XINPUT_CAPABILITIES const m_capabilities;
XINPUT_STATE m_xinput_state;
uint8_t m_switches[SWITCH_TOTAL];
int32_t m_axes[AXIS_TOTAL];
std::shared_ptr<xinput_api_helper> m_xinput_helper;
};
const input_item_id xinput_axis_ids[] =
xinput_joystick_device::xinput_joystick_device(
running_machine &machine,
std::string &&name,
std::string &&id,
input_module &module,
uint32_t player,
XINPUT_CAPABILITIES const &caps,
std::shared_ptr<xinput_api_helper> helper) :
device_info(machine, std::move(name), std::move(id), DEVICE_CLASS_JOYSTICK, module),
m_player_index(player),
m_capabilities(caps),
m_xinput_state{ 0 },
m_xinput_helper(helper)
{
ITEM_ID_XAXIS,
ITEM_ID_YAXIS,
ITEM_ID_ZAXIS,
ITEM_ID_RZAXIS
};
std::fill(std::begin(m_switches), std::end(m_switches), 0);
std::fill(std::begin(m_axes), std::end(m_axes), 0);
}
const USHORT xinput_pov_dir[] = {
XINPUT_GAMEPAD_DPAD_UP,
XINPUT_GAMEPAD_DPAD_DOWN,
XINPUT_GAMEPAD_DPAD_LEFT,
XINPUT_GAMEPAD_DPAD_RIGHT
};
void xinput_joystick_device::poll()
{
// poll the device first
DWORD const prevpacket = m_xinput_state.dwPacketNumber;
HRESULT result = m_xinput_helper->xinput_get_state(m_player_index, &m_xinput_state);
const char *const xinput_pov_names[] = {
"DPAD Up",
"DPAD Down",
"DPAD Left",
"DPAD Right"
};
// if we can't poll the device or nothing changed, skip
if (FAILED(result) || (prevpacket == m_xinput_state.dwPacketNumber))
return;
const USHORT xinput_buttons[] = {
XINPUT_GAMEPAD_A,
XINPUT_GAMEPAD_B,
XINPUT_GAMEPAD_X,
XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_LEFT_SHOULDER,
XINPUT_GAMEPAD_RIGHT_SHOULDER,
XINPUT_GAMEPAD_LEFT_THUMB,
XINPUT_GAMEPAD_RIGHT_THUMB,
XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_BACK
};
// translate button bits
for (unsigned i = 0; std::size(SWITCH_BITS) > i; ++i)
m_switches[SWITCH_A + i] = (m_xinput_state.Gamepad.wButtons & SWITCH_BITS[i]) ? 0xff : 0x00;
const char *const xinput_button_names[] = {
"A",
"B",
"X",
"Y",
"LB",
"RB",
"LS",
"RS",
"Start",
"Back"
};
// translate the triggers onto the negative side of the axes
m_axes[AXIS_LT] = -normalize_absolute_axis(m_xinput_state.Gamepad.bLeftTrigger, -255, 255);
m_axes[AXIS_RT] = -normalize_absolute_axis(m_xinput_state.Gamepad.bRightTrigger, -255, 255);
const input_item_id xinput_button_ids[] = {
ITEM_ID_BUTTON1,
ITEM_ID_BUTTON2,
ITEM_ID_BUTTON3,
ITEM_ID_BUTTON4,
ITEM_ID_BUTTON5,
ITEM_ID_BUTTON6,
ITEM_ID_BUTTON7,
ITEM_ID_BUTTON8,
ITEM_ID_START,
ITEM_ID_SELECT
};
// translate full-precision axes - Y direction is opposite to what MAME uses
m_axes[AXIS_LSX] = normalize_absolute_axis(m_xinput_state.Gamepad.sThumbLX, XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE);
m_axes[AXIS_LSY] = normalize_absolute_axis(-m_xinput_state.Gamepad.sThumbLY, XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE);
m_axes[AXIS_RSX] = normalize_absolute_axis(m_xinput_state.Gamepad.sThumbRX, XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE);
m_axes[AXIS_RSY] = normalize_absolute_axis(-m_xinput_state.Gamepad.sThumbRY, XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE);
// translate LT/RT switches for arcade sticks/pads
m_switches[SWITCH_LT] = (0x80 <= m_xinput_state.Gamepad.bLeftTrigger) ? 0xff : 0x00;
m_switches[SWITCH_RT] = (0x80 <= m_xinput_state.Gamepad.bRightTrigger) ? 0xff : 0x00;
// translate POV hat for flight sticks
m_switches[SWITCH_HAT_UP] = (16'384 <= m_xinput_state.Gamepad.sThumbRY) ? 0xff : 0x00;
m_switches[SWITCH_HAT_DOWN] = (-16'384 >= m_xinput_state.Gamepad.sThumbRY) ? 0xff : 0x00;
m_switches[SWITCH_HAT_LEFT] = (-16'384 >= m_xinput_state.Gamepad.sThumbRX) ? 0xff : 0x00;
m_switches[SWITCH_HAT_RIGHT] = (16'384 <= m_xinput_state.Gamepad.sThumbRX) ? 0xff : 0x00;
// translate rudder and throttle for flight sticks
m_axes[AXIS_RUDDER] = normalize_absolute_axis(m_xinput_state.Gamepad.bLeftTrigger, 0, 255);
m_axes[AXIS_THROTTLE] = normalize_absolute_axis(m_xinput_state.Gamepad.bRightTrigger, 0, 255);
}
void xinput_joystick_device::reset()
{
std::fill(std::begin(m_switches), std::end(m_switches), 0);
std::fill(std::begin(m_axes), std::end(m_axes), 0);
}
void xinput_joystick_device::configure()
{
// TODO: don't add axes not present in capabilities
// TODO: proper support for dance mat, guitar and drum kit controllers
// default characteristics for a gamepad
char const *type_name = "unsupported";
char const *subtype_name = "unsupported";
bool lt_rt_button = false;
bool lt_rt_fullaxis = false;
bool rstick_hat = false;
char const *const *axis_names = AXIS_NAMES_GAMEPAD;
input_item_id const *axis_ids = AXIS_IDS_GAMEPAD;
char const *const *hat_names = HAT_NAMES_GAMEPAD;
// consider the device type to decide how to map controls
switch (m_capabilities.Type)
{
case XINPUT_DEVTYPE_GAMEPAD:
type_name = "game controller";
switch (m_capabilities.SubType)
{
case 0x00: // XINPUT_DEVSUBTYPE_UNKNOWN: work around MinGW header issues
subtype_name = "unknown";
break;
case XINPUT_DEVSUBTYPE_GAMEPAD:
subtype_name = "gamepad";
break;
case XINPUT_DEVSUBTYPE_WHEEL:
subtype_name = "wheel";
axis_names = AXIS_NAMES_WHEEL;
break;
case XINPUT_DEVSUBTYPE_ARCADE_STICK:
subtype_name = "arcade stick";
lt_rt_button = true;
hat_names = HAT_NAMES_ARCADE_STICK;
break;
case 0x04: // XINPUT_DEVSUBTYPE_FLIGHT_STICK: work around MinGW header issues
subtype_name = "flight stick";
lt_rt_fullaxis = true;
rstick_hat = true;
axis_names = AXIS_NAMES_FLIGHT_STICK;
axis_ids = AXIS_IDS_FLIGHT_STICK;
break;
case XINPUT_DEVSUBTYPE_DANCE_PAD:
subtype_name = "dance pad";
break;
case XINPUT_DEVSUBTYPE_GUITAR:
case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
case XINPUT_DEVSUBTYPE_GUITAR_BASS:
subtype_name = "guitar";
break;
case XINPUT_DEVSUBTYPE_DRUM_KIT:
subtype_name = "drum kit";
break;
case XINPUT_DEVSUBTYPE_ARCADE_PAD:
subtype_name = "arcade pad";
lt_rt_button = true;
break;
}
break;
}
// log some diagnostic information
osd_printf_verbose(
"Configuring XInput player %d type 0x%02X (%s) sub type 0x%02X (%s)\n",
m_player_index + 1,
m_capabilities.Type,
type_name,
m_capabilities.SubType,
subtype_name);
osd_printf_verbose(
"XInput switch capabilities A=%d B=%d X=%d Y=%d LB=%d RB=%d LSB=%d RSB=%d Start=%d Back=%d Up=%d Down=%d Left=%d Right=%d\n",
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_A) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_B) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_X) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_Y) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_START) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) ? 1 : 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) ? 1 : 0);
osd_printf_verbose(
"XInput axis capabilities LT=0x%02X (%d-bit) RT=0x%02X (%d-bit) LSX=0x%04X (%d-bit) LSY=0x%04X (%d-bit) RSX=0x%04X (%d-bit) RSY=0x%04X (%d-bit)\n",
m_capabilities.Gamepad.bLeftTrigger,
count_leading_ones_32(uint32_t(m_capabilities.Gamepad.bLeftTrigger) << 24),
m_capabilities.Gamepad.bRightTrigger,
count_leading_ones_32(uint32_t(m_capabilities.Gamepad.bRightTrigger) << 24),
m_capabilities.Gamepad.sThumbLX,
count_leading_ones_32(uint32_t(uint16_t(m_capabilities.Gamepad.sThumbLX)) << 16),
m_capabilities.Gamepad.sThumbLY,
count_leading_ones_32(uint32_t(uint16_t(m_capabilities.Gamepad.sThumbLY)) << 16),
m_capabilities.Gamepad.sThumbRX,
count_leading_ones_32(uint32_t(uint16_t(m_capabilities.Gamepad.sThumbRX)) << 16),
m_capabilities.Gamepad.sThumbRY,
count_leading_ones_32(uint32_t(uint16_t(m_capabilities.Gamepad.sThumbRY)) << 16));
// add full-precision axes
for (unsigned i = 0; ((rstick_hat ? AXIS_LSY : AXIS_RSY) - AXIS_LSX) >= i; ++i)
{
device()->add_item(
axis_names[i],
axis_ids[i],
generic_axis_get_state<int32_t>,
&m_axes[AXIS_LSX + i]);
}
// add extra axes for flight sticks
if (lt_rt_fullaxis)
{
for (unsigned i = 0; (AXIS_THROTTLE - AXIS_RUDDER) >= i; ++i)
{
device()->add_item(
axis_names[4 + i],
axis_ids[4 + i],
generic_axis_get_state<int32_t>,
&m_axes[AXIS_RUDDER + i]);
}
}
// add hats
bool const hat_caps[]{
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) != 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) != 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) != 0,
(m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) != 0,
rstick_hat && m_capabilities.Gamepad.sThumbRY,
rstick_hat && m_capabilities.Gamepad.sThumbRY,
rstick_hat && m_capabilities.Gamepad.sThumbRX,
rstick_hat && m_capabilities.Gamepad.sThumbRX };
for (unsigned i = 0; (SWITCH_HAT_RIGHT - SWITCH_DPAD_UP) >= i; ++i)
{
if (hat_caps[i])
{
device()->add_item(
hat_names[i],
input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order
generic_button_get_state<uint8_t>,
&m_switches[SWITCH_DPAD_UP + i]);
}
}
// add buttons
std::tuple<unsigned, char const *, bool> const button_caps[]{
{ SWITCH_A, "A", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_A) != 0 },
{ SWITCH_B, "B", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_B) != 0 },
{ SWITCH_X, "X", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_X) != 0 },
{ SWITCH_Y, "Y", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_Y) != 0 },
{ SWITCH_LT, "LT", lt_rt_button && m_capabilities.Gamepad.bLeftTrigger },
{ SWITCH_RT, "RT", lt_rt_button && m_capabilities.Gamepad.bRightTrigger },
{ SWITCH_LB, "LB", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0 },
{ SWITCH_RB, "RB", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0 },
{ SWITCH_LSB, "LSB", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0 },
{ SWITCH_RSB, "RSB", (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0 } };
input_item_id button_id = ITEM_ID_BUTTON1;
for (auto [i, name, supported] : button_caps)
{
if (supported)
{
device()->add_item(
name,
button_id++,
generic_button_get_state<uint8_t>,
&m_switches[i]);
}
}
// add start/back
if (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_START)
{
device()->add_item(
"Start",
ITEM_ID_START,
generic_button_get_state<uint8_t>,
&m_switches[SWITCH_START]);
}
if (m_capabilities.Gamepad.wButtons & XINPUT_GAMEPAD_BACK)
{
device()->add_item(
"Back",
ITEM_ID_SELECT,
generic_button_get_state<uint8_t>,
&m_switches[SWITCH_BACK]);
}
// add triggers/pedals
if (!lt_rt_button && !lt_rt_fullaxis)
{
for (unsigned i = 0; (AXIS_RT - AXIS_LT) >= i; ++i)
{
device()->add_item(
axis_names[4 + i],
axis_ids[4 + i],
generic_axis_get_state<int32_t>,
&m_axes[AXIS_LT + i]);
}
}
}
//============================================================
@ -134,16 +587,9 @@ protected:
{
XINPUT_STATE state = {0};
// allocate and link in a new device
if (m_xinput_helper->xinput_get_state(i, &state) == ERROR_SUCCESS)
{
// allocate and link in a new device
auto *devinfo = m_xinput_helper->create_xinput_device(machine, i, *this);
if (!devinfo)
continue;
// Configure each gamepad to add buttons and Axes, etc.
devinfo->configure();
}
m_xinput_helper->create_xinput_device(machine, i, *this);
}
}
@ -174,141 +620,32 @@ int xinput_api_helper::initialize()
// create_xinput_device
//============================================================
xinput_joystick_device * xinput_api_helper::create_xinput_device(running_machine &machine, UINT index, wininput_module &module)
device_info *xinput_api_helper::create_xinput_device(running_machine &machine, UINT index, wininput_module &module)
{
// If we can't get the capabilities skip this device
XINPUT_CAPABILITIES caps = { 0 };
if (FAILED(xinput_get_capabilities(index, 0, &caps)))
{
// If we can't get the capabilities skip this device
return nullptr;
}
char device_name[16];
snprintf(device_name, sizeof(device_name), "XInput Player %u", index + 1);
// allocate the device object
auto &devinfo = module.devicelist().create_device<xinput_joystick_device>(machine, device_name, device_name, module, shared_from_this());
auto &devinfo = module.devicelist().create_device<xinput_joystick_device>(
machine,
device_name,
device_name,
module,
index,
caps,
shared_from_this());
// Set the player ID
devinfo.xinput_state.player_index = index;
// Assign the caps we captured earlier
devinfo.xinput_state.caps = caps;
// configure each controller to add buttons, axes, etc.
devinfo.configure();
return &devinfo;
}
//============================================================
// xinput_joystick_device
//============================================================
xinput_joystick_device::xinput_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module, std::shared_ptr<xinput_api_helper> helper) :
device_info(machine, std::string(name), std::string(id), DEVICE_CLASS_JOYSTICK, module),
gamepad({ { 0 } }),
xinput_state({ 0 }),
m_xinput_helper(helper),
m_configured(false)
{
}
void xinput_joystick_device::poll()
{
if (!m_configured)
return;
// poll the device first
HRESULT result = m_xinput_helper->xinput_get_state(xinput_state.player_index, &xinput_state.xstate);
// If we can't poll the device, skip
if (FAILED(result))
return;
// Copy the XState into State
// Start with the POV (DPAD)
for (int povindex = 0; povindex < XINPUT_MAX_POV; povindex++)
{
int currentPov = xinput_pov_dir[povindex];
gamepad.povs[povindex] = (xinput_state.xstate.Gamepad.wButtons & currentPov) ? 0xFF : 0;
}
// Now do the buttons
for (int buttonindex = 0; buttonindex < XINPUT_MAX_BUTTONS; buttonindex++)
{
int currentButton = xinput_buttons[buttonindex];
gamepad.buttons[buttonindex] = (xinput_state.xstate.Gamepad.wButtons & currentButton) ? 0xFF : 0;
}
// Now grab the axis values
// Each of the thumbstick axis members is a signed value between -32768 and 32767 describing the position of the thumbstick
// However, the Y axis values are inverted from what MAME expects, so negate the value
gamepad.left_thumb_x = normalize_absolute_axis(xinput_state.xstate.Gamepad.sThumbLX, XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE);
gamepad.left_thumb_y = normalize_absolute_axis(-xinput_state.xstate.Gamepad.sThumbLY, XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE);
gamepad.right_thumb_x = normalize_absolute_axis(xinput_state.xstate.Gamepad.sThumbRX, XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE);
gamepad.right_thumb_y = normalize_absolute_axis(-xinput_state.xstate.Gamepad.sThumbRY, XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE);
// Now the triggers, place them on half-axes (negative side)
gamepad.left_trigger = -normalize_absolute_axis(xinput_state.xstate.Gamepad.bLeftTrigger, -255, 255);
gamepad.right_trigger = -normalize_absolute_axis(xinput_state.xstate.Gamepad.bRightTrigger, -255, 255);
}
void xinput_joystick_device::reset()
{
memset(&gamepad, 0, sizeof(gamepad));
}
void xinput_joystick_device::configure()
{
std::lock_guard<std::mutex> scope_lock(m_device_lock);
if (m_configured)
return;
// Add the axes
for (int axisnum = 0; axisnum < XINPUT_MAX_AXIS; axisnum++)
{
device()->add_item(
xinput_axis_name[axisnum],
xinput_axis_ids[axisnum],
generic_axis_get_state<LONG>,
&gamepad.left_thumb_x + axisnum);
}
// Populate the POVs
// For XBOX, we treat the DPAD as a hat switch
for (int povnum = 0; povnum < XINPUT_MAX_POV; povnum++)
{
device()->add_item(
xinput_pov_names[povnum],
input_item_id(ITEM_ID_HAT1UP + povnum), // matches up/down/left/right order
generic_button_get_state<BYTE>,
&gamepad.povs[povnum]);
}
// populate the buttons
for (int butnum = 0; butnum < XINPUT_MAX_BUTTONS; butnum++)
{
device()->add_item(
xinput_button_names[butnum],
xinput_button_ids[butnum],
generic_button_get_state<BYTE>,
&gamepad.buttons[butnum]);
}
device()->add_item(
"RT",
ITEM_ID_ADD_ABSOLUTE1,
generic_axis_get_state<LONG>,
&gamepad.right_trigger);
device()->add_item(
"LT",
ITEM_ID_ADD_ABSOLUTE2,
generic_axis_get_state<LONG>,
&gamepad.left_trigger);
m_configured = true;
}
#else // defined(OSD_WINDOWS)
#include "input_module.h"

View File

@ -7,15 +7,9 @@
#include "modules/lib/osdlib.h"
#include <cstdint>
#include <memory>
#include <mutex>
#include <string_view>
#include <xinput.h>
class xinput_joystick_device;
#include <memory>
class xinput_api_helper : public std::enable_shared_from_this<xinput_api_helper>
@ -24,7 +18,7 @@ public:
xinput_api_helper() { }
int initialize();
xinput_joystick_device *create_xinput_device(running_machine &machine, UINT index, wininput_module &module);
device_info *create_xinput_device(running_machine &machine, UINT index, wininput_module &module);
DWORD xinput_get_state(DWORD dwUserindex, XINPUT_STATE *pState) const
{
@ -46,48 +40,4 @@ private:
xinput_get_caps_fn XInputGetCapabilities = nullptr;
};
class xinput_joystick_device : public device_info
{
public:
static inline constexpr int XINPUT_MAX_POV = 4;
static inline constexpr int XINPUT_MAX_BUTTONS = 10;
static inline constexpr int XINPUT_MAX_AXIS = 4;
struct gamepad_state
{
BYTE buttons[XINPUT_MAX_BUTTONS];
BYTE povs[XINPUT_MAX_POV];
LONG left_trigger;
LONG right_trigger;
LONG left_thumb_x;
LONG left_thumb_y;
LONG right_thumb_x;
LONG right_thumb_y;
};
// state information for a gamepad; state must be first element
struct xinput_api_state
{
uint32_t player_index;
XINPUT_STATE xstate;
XINPUT_CAPABILITIES caps;
};
gamepad_state gamepad;
xinput_api_state xinput_state;
private:
std::shared_ptr<xinput_api_helper> m_xinput_helper;
std::mutex m_device_lock;
bool m_configured;
public:
xinput_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module, std::shared_ptr<xinput_api_helper> helper);
void poll() override;
void reset() override;
void configure();
};
#endif // MAME_OSD_INPUT_INPUT_XINPUT_H

View File

@ -283,7 +283,8 @@ void osd_common_t::register_options()
REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_WIN32);
REGISTER_MODULE(m_mod_man, LIGHTGUN_NONE);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_SDL);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_SDLJOY);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_SDLGAME);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_WINHYBRID);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_DINPUT);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_XINPUT);