summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/render.cpp6
-rw-r--r--src/frontend/mame/ui/about.cpp17
-rw-r--r--src/frontend/mame/ui/about.h3
-rw-r--r--src/frontend/mame/ui/analogipt.cpp13
-rw-r--r--src/frontend/mame/ui/analogipt.h3
-rw-r--r--src/frontend/mame/ui/auditmenu.cpp15
-rw-r--r--src/frontend/mame/ui/auditmenu.h3
-rw-r--r--src/frontend/mame/ui/barcode.cpp2
-rw-r--r--src/frontend/mame/ui/barcode.h2
-rw-r--r--src/frontend/mame/ui/cheatopt.cpp2
-rw-r--r--src/frontend/mame/ui/cheatopt.h2
-rw-r--r--src/frontend/mame/ui/confswitch.cpp22
-rw-r--r--src/frontend/mame/ui/confswitch.h5
-rw-r--r--src/frontend/mame/ui/custui.cpp43
-rw-r--r--src/frontend/mame/ui/custui.h13
-rw-r--r--src/frontend/mame/ui/datmenu.cpp29
-rw-r--r--src/frontend/mame/ui/datmenu.h3
-rw-r--r--src/frontend/mame/ui/devopt.cpp2
-rw-r--r--src/frontend/mame/ui/devopt.h2
-rw-r--r--src/frontend/mame/ui/dirmenu.cpp41
-rw-r--r--src/frontend/mame/ui/dirmenu.h2
-rw-r--r--src/frontend/mame/ui/filecreate.cpp26
-rw-r--r--src/frontend/mame/ui/filecreate.h9
-rw-r--r--src/frontend/mame/ui/filemngr.cpp16
-rw-r--r--src/frontend/mame/ui/filemngr.h3
-rw-r--r--src/frontend/mame/ui/filesel.cpp20
-rw-r--r--src/frontend/mame/ui/filesel.h5
-rw-r--r--src/frontend/mame/ui/imgcntrl.cpp2
-rw-r--r--src/frontend/mame/ui/imgcntrl.h2
-rw-r--r--src/frontend/mame/ui/info.cpp6
-rw-r--r--src/frontend/mame/ui/info.h6
-rw-r--r--src/frontend/mame/ui/info_pty.cpp2
-rw-r--r--src/frontend/mame/ui/info_pty.h2
-rw-r--r--src/frontend/mame/ui/inputdevices.cpp57
-rw-r--r--src/frontend/mame/ui/inputdevices.h2
-rw-r--r--src/frontend/mame/ui/inputmap.cpp25
-rw-r--r--src/frontend/mame/ui/inputmap.h12
-rw-r--r--src/frontend/mame/ui/inputopts.cpp2
-rw-r--r--src/frontend/mame/ui/inputopts.h2
-rw-r--r--src/frontend/mame/ui/inputtoggle.cpp2
-rw-r--r--src/frontend/mame/ui/inputtoggle.h2
-rw-r--r--src/frontend/mame/ui/keyboard.cpp2
-rw-r--r--src/frontend/mame/ui/keyboard.h2
-rw-r--r--src/frontend/mame/ui/mainmenu.cpp2
-rw-r--r--src/frontend/mame/ui/mainmenu.h2
-rw-r--r--src/frontend/mame/ui/menu.cpp14
-rw-r--r--src/frontend/mame/ui/menu.h5
-rw-r--r--src/frontend/mame/ui/miscmenu.cpp14
-rw-r--r--src/frontend/mame/ui/miscmenu.h14
-rw-r--r--src/frontend/mame/ui/optsmenu.cpp8
-rw-r--r--src/frontend/mame/ui/optsmenu.h4
-rw-r--r--src/frontend/mame/ui/pluginopt.cpp4
-rw-r--r--src/frontend/mame/ui/pluginopt.h4
-rw-r--r--src/frontend/mame/ui/quitmenu.cpp2
-rw-r--r--src/frontend/mame/ui/quitmenu.h2
-rw-r--r--src/frontend/mame/ui/selector.cpp14
-rw-r--r--src/frontend/mame/ui/selector.h3
-rw-r--r--src/frontend/mame/ui/selgame.cpp9
-rw-r--r--src/frontend/mame/ui/selgame.h2
-rw-r--r--src/frontend/mame/ui/selmenu.cpp8
-rw-r--r--src/frontend/mame/ui/selsoft.cpp17
-rw-r--r--src/frontend/mame/ui/selsoft.h4
-rw-r--r--src/frontend/mame/ui/simpleselgame.cpp15
-rw-r--r--src/frontend/mame/ui/simpleselgame.h3
-rw-r--r--src/frontend/mame/ui/sliders.cpp14
-rw-r--r--src/frontend/mame/ui/sliders.h3
-rw-r--r--src/frontend/mame/ui/slotopt.cpp14
-rw-r--r--src/frontend/mame/ui/slotopt.h7
-rw-r--r--src/frontend/mame/ui/sndmenu.cpp2
-rw-r--r--src/frontend/mame/ui/sndmenu.h2
-rw-r--r--src/frontend/mame/ui/state.cpp22
-rw-r--r--src/frontend/mame/ui/state.h3
-rw-r--r--src/frontend/mame/ui/submenu.cpp18
-rw-r--r--src/frontend/mame/ui/submenu.h3
-rw-r--r--src/frontend/mame/ui/swlist.cpp6
-rw-r--r--src/frontend/mame/ui/swlist.h6
-rw-r--r--src/frontend/mame/ui/tapectrl.cpp2
-rw-r--r--src/frontend/mame/ui/tapectrl.h2
-rw-r--r--src/frontend/mame/ui/textbox.cpp12
-rw-r--r--src/frontend/mame/ui/textbox.h1
-rw-r--r--src/frontend/mame/ui/utils.cpp8
-rw-r--r--src/frontend/mame/ui/videoopt.cpp4
-rw-r--r--src/frontend/mame/ui/videoopt.h4
-rw-r--r--src/osd/modules/input/input_sdl.cpp999
-rw-r--r--src/osd/modules/input/input_sdlcommon.cpp8
-rw-r--r--src/osd/modules/input/input_winhybrid.cpp13
-rw-r--r--src/osd/modules/input/input_xinput.cpp723
-rw-r--r--src/osd/modules/input/input_xinput.h54
-rw-r--r--src/osd/modules/lib/osdobj_common.cpp3
89 files changed, 1870 insertions, 650 deletions
diff --git a/src/emu/render.cpp b/src/emu/render.cpp
index 32aebcf8eb7..89281b11dd2 100644
--- a/src/emu/render.cpp
+++ b/src/emu/render.cpp
@@ -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;
}
diff --git a/src/frontend/mame/ui/about.cpp b/src/frontend/mame/ui/about.cpp
index 715815399f9..62d0a1c5241 100644
--- a/src/frontend/mame/ui/about.cpp
+++ b/src/frontend/mame/ui/about.cpp
@@ -64,6 +64,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);
}
diff --git a/src/frontend/mame/ui/about.h b/src/frontend/mame/ui/about.h
index 13fc8e3e84f..5e394ba5d9e 100644
--- a/src/frontend/mame/ui/about.h
+++ b/src/frontend/mame/ui/about.h
@@ -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;
diff --git a/src/frontend/mame/ui/analogipt.cpp b/src/frontend/mame/ui/analogipt.cpp
index 4e3b15aecc8..520026ea479 100644
--- a/src/frontend/mame/ui/analogipt.cpp
+++ b/src/frontend/mame/ui/analogipt.cpp
@@ -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));
}
diff --git a/src/frontend/mame/ui/analogipt.h b/src/frontend/mame/ui/analogipt.h
index f6807947ce6..26f2580318a 100644
--- a/src/frontend/mame/ui/analogipt.h
+++ b/src/frontend/mame/ui/analogipt.h
@@ -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();
diff --git a/src/frontend/mame/ui/auditmenu.cpp b/src/frontend/mame/ui/auditmenu.cpp
index b8656d3163c..bc01cbc4a2a 100644
--- a/src/frontend/mame/ui/auditmenu.cpp
+++ b/src/frontend/mame/ui/auditmenu.cpp
@@ -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)
diff --git a/src/frontend/mame/ui/auditmenu.h b/src/frontend/mame/ui/auditmenu.h
index de42c33b6d1..040316edb5b 100644
--- a/src/frontend/mame/ui/auditmenu.h
+++ b/src/frontend/mame/ui/auditmenu.h
@@ -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();
diff --git a/src/frontend/mame/ui/barcode.cpp b/src/frontend/mame/ui/barcode.cpp
index a0e4791dfb6..31dcf768e78 100644
--- a/src/frontend/mame/ui/barcode.cpp
+++ b/src/frontend/mame/ui/barcode.cpp
@@ -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())
{
diff --git a/src/frontend/mame/ui/barcode.h b/src/frontend/mame/ui/barcode.h
index e171485cf79..5f70fe65276 100644
--- a/src/frontend/mame/ui/barcode.h
+++ b/src/frontend/mame/ui/barcode.h
@@ -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;
diff --git a/src/frontend/mame/ui/cheatopt.cpp b/src/frontend/mame/ui/cheatopt.cpp
index 9aae81134ef..193a3c9efd6 100644
--- a/src/frontend/mame/ui/cheatopt.cpp
+++ b/src/frontend/mame/ui/cheatopt.cpp
@@ -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;
diff --git a/src/frontend/mame/ui/cheatopt.h b/src/frontend/mame/ui/cheatopt.h
index c01ec151189..ba0f144dbaf 100644
--- a/src/frontend/mame/ui/cheatopt.h
+++ b/src/frontend/mame/ui/cheatopt.h
@@ -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;
};
diff --git a/src/frontend/mame/ui/confswitch.cpp b/src/frontend/mame/ui/confswitch.cpp
index f267d7fa725..ffeae2fff38 100644
--- a/src/frontend/mame/ui/confswitch.cpp
+++ b/src/frontend/mame/ui/confswitch.cpp
@@ -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);
}
}
diff --git a/src/frontend/mame/ui/confswitch.h b/src/frontend/mame/ui/confswitch.h
index 598b0208085..9094fb2dc22 100644
--- a/src/frontend/mame/ui/confswitch.h
+++ b/src/frontend/mame/ui/confswitch.h
@@ -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;
diff --git a/src/frontend/mame/ui/custui.cpp b/src/frontend/mame/ui/custui.cpp
index 35c8bd29bd1..22740412ff9 100644
--- a/src/frontend/mame/ui/custui.cpp
+++ b/src/frontend/mame/ui/custui.cpp
@@ -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);
+}
+
+//-------------------------------------------------
+// recompute metrics
+//-------------------------------------------------
+
+void menu_colors_ui::recompute_metrics(uint32_t width, uint32_t height, float aspect)
+{
+ menu::recompute_metrics(width, height, aspect);
- custombottom = line_height() + 3.0f * tb_border();
+ 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);
+}
+
+//-------------------------------------------------
+// recompute metrics
+//-------------------------------------------------
+
+void menu_rgb_ui::recompute_metrics(uint32_t width, uint32_t height, float aspect)
+{
+ menu::recompute_metrics(width, height, aspect);
- custombottom = line_height() + 3.0f * tb_border();
+ 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));
diff --git a/src/frontend/mame/ui/custui.h b/src/frontend/mame/ui/custui.h
index f720318d854..c009a4eccf0 100644
--- a/src/frontend/mame/ui/custui.h
+++ b/src/frontend/mame/ui/custui.h
@@ -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[];
diff --git a/src/frontend/mame/ui/datmenu.cpp b/src/frontend/mame/ui/datmenu.cpp
index 2d65f2a8484..47ed1f2ca8f 100644
--- a/src/frontend/mame/ui/datmenu.cpp
+++ b/src/frontend/mame/ui/datmenu.cpp
@@ -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;
diff --git a/src/frontend/mame/ui/datmenu.h b/src/frontend/mame/ui/datmenu.h
index 79b9bd8c1f6..680e4f0f37a 100644
--- a/src/frontend/mame/ui/datmenu.h
+++ b/src/frontend/mame/ui/datmenu.h
@@ -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);
diff --git a/src/frontend/mame/ui/devopt.cpp b/src/frontend/mame/ui/devopt.cpp
index e03b8da9042..9886c4e941d 100644
--- a/src/frontend/mame/ui/devopt.cpp
+++ b/src/frontend/mame/ui/devopt.cpp
@@ -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()
{
}
diff --git a/src/frontend/mame/ui/devopt.h b/src/frontend/mame/ui/devopt.h
index 74c81a75809..05fef63240b 100644
--- a/src/frontend/mame/ui/devopt.h
+++ b/src/frontend/mame/ui/devopt.h
@@ -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;
diff --git a/src/frontend/mame/ui/dirmenu.cpp b/src/frontend/mame/ui/dirmenu.cpp
index 252b53a5aae..2f77e98433c 100644
--- a/src/frontend/mame/ui/dirmenu.cpp
+++ b/src/frontend/mame/ui/dirmenu.cpp
@@ -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
diff --git a/src/frontend/mame/ui/dirmenu.h b/src/frontend/mame/ui/dirmenu.h
index 644a71ba564..209fb7953fe 100644
--- a/src/frontend/mame/ui/dirmenu.h
+++ b/src/frontend/mame/ui/dirmenu.h
@@ -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;
};
diff --git a/src/frontend/mame/ui/filecreate.cpp b/src/frontend/mame/ui/filecreate.cpp
index 21622d3d179..341c19545ba 100644
--- a/src/frontend/mame/ui/filecreate.cpp
+++ b/src/frontend/mame/ui/filecreate.cpp
@@ -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);
@@ -134,14 +134,26 @@ 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
//-------------------------------------------------
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;
diff --git a/src/frontend/mame/ui/filecreate.h b/src/frontend/mame/ui/filecreate.h
index 9d47605f5a7..629bd24f3ec 100644
--- a/src/frontend/mame/ui/filecreate.h
+++ b/src/frontend/mame/ui/filecreate.h
@@ -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
diff --git a/src/frontend/mame/ui/filemngr.cpp b/src/frontend/mame/ui/filemngr.cpp
index bbd38a9a411..81540b568b0 100644
--- a/src/frontend/mame/ui/filemngr.cpp
+++ b/src/frontend/mame/ui/filemngr.cpp
@@ -54,6 +54,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();
}
diff --git a/src/frontend/mame/ui/filemngr.h b/src/frontend/mame/ui/filemngr.h
index 379912c8dfb..a2368e5a959 100644
--- a/src/frontend/mame/ui/filemngr.h
+++ b/src/frontend/mame/ui/filemngr.h
@@ -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);
diff --git a/src/frontend/mame/ui/filesel.cpp b/src/frontend/mame/ui/filesel.cpp
index 182e130dc61..e12beadb8eb 100644
--- a/src/frontend/mame/ui/filesel.cpp
+++ b/src/frontend/mame/ui/filesel.cpp
@@ -73,6 +73,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));
diff --git a/src/frontend/mame/ui/filesel.h b/src/frontend/mame/ui/filesel.h
index 8fa309c2fb9..71b2b17e3ad 100644
--- a/src/frontend/mame/ui/filesel.h
+++ b/src/frontend/mame/ui/filesel.h
@@ -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
diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp
index 5708a4a832a..174b8bab9e6 100644
--- a/src/frontend/mame/ui/imgcntrl.cpp
+++ b/src/frontend/mame/ui/imgcntrl.cpp
@@ -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!");
}
diff --git a/src/frontend/mame/ui/imgcntrl.h b/src/frontend/mame/ui/imgcntrl.h
index 66a5ee5f81a..80b4548686a 100644
--- a/src/frontend/mame/ui/imgcntrl.h
+++ b/src/frontend/mame/ui/imgcntrl.h
@@ -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();
};
diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp
index ce4999bb0fa..32575133a24 100644
--- a/src/frontend/mame/ui/info.cpp
+++ b/src/frontend/mame/ui/info.cpp
@@ -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);
diff --git a/src/frontend/mame/ui/info.h b/src/frontend/mame/ui/info.h
index 5c8f153d6ae..d36c476c7b5 100644
--- a/src/frontend/mame/ui/info.h
+++ b/src/frontend/mame/ui/info.h
@@ -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);
};
diff --git a/src/frontend/mame/ui/info_pty.cpp b/src/frontend/mame/ui/info_pty.cpp
index 1aadb85deb9..018c3bc9b61 100644
--- a/src/frontend/mame/ui/info_pty.cpp
+++ b/src/frontend/mame/ui/info_pty.cpp
@@ -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()))
{
diff --git a/src/frontend/mame/ui/info_pty.h b/src/frontend/mame/ui/info_pty.h
index 16f65435be2..af384a5a92d 100644
--- a/src/frontend/mame/ui/info_pty.h
+++ b/src/frontend/mame/ui/info_pty.h
@@ -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;
};
diff --git a/src/frontend/mame/ui/inputdevices.cpp b/src/frontend/mame/ui/inputdevices.cpp
index 5c1a7a8931a..71d09a0b280 100644
--- a/src/frontend/mame/ui/inputdevices.cpp
+++ b/src/frontend/mame/ui/inputdevices.cpp
@@ -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;
diff --git a/src/frontend/mame/ui/inputdevices.h b/src/frontend/mame/ui/inputdevices.h
index cb81caaaf47..39d2afda4e5 100644
--- a/src/frontend/mame/ui/inputdevices.h
+++ b/src/frontend/mame/ui/inputdevices.h
@@ -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;
};
diff --git a/src/frontend/mame/ui/inputmap.cpp b/src/frontend/mame/ui/inputmap.cpp
index 2fbc8aeb95d..387d3db7423 100644
--- a/src/frontend/mame/ui/inputmap.cpp
+++ b/src/frontend/mame/ui/inputmap.cpp
@@ -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
diff --git a/src/frontend/mame/ui/inputmap.h b/src/frontend/mame/ui/inputmap.h
index c651a8cc3d3..d512b670345 100644
--- a/src/frontend/mame/ui/inputmap.h
+++ b/src/frontend/mame/ui/inputmap.h
@@ -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;
};
diff --git a/src/frontend/mame/ui/inputopts.cpp b/src/frontend/mame/ui/inputopts.cpp
index ff433e72e7e..e4802e8de8f 100644
--- a/src/frontend/mame/ui/inputopts.cpp
+++ b/src/frontend/mame/ui/inputopts.cpp
@@ -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);
diff --git a/src/frontend/mame/ui/inputopts.h b/src/frontend/mame/ui/inputopts.h
index 11432ce5035..7cff7713537 100644
--- a/src/frontend/mame/ui/inputopts.h
+++ b/src/frontend/mame/ui/inputopts.h
@@ -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;
};
diff --git a/src/frontend/mame/ui/inputtoggle.cpp b/src/frontend/mame/ui/inputtoggle.cpp
index b21cd572c1d..e86d41b7031 100644
--- a/src/frontend/mame/ui/inputtoggle.cpp
+++ b/src/frontend/mame/ui/inputtoggle.cpp
@@ -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())
diff --git a/src/frontend/mame/ui/inputtoggle.h b/src/frontend/mame/ui/inputtoggle.h
index 7a3016f6254..b4d48908d96 100644
--- a/src/frontend/mame/ui/inputtoggle.h
+++ b/src/frontend/mame/ui/inputtoggle.h
@@ -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;
diff --git a/src/frontend/mame/ui/keyboard.cpp b/src/frontend/mame/ui/keyboard.cpp
index 7efebefd64c..931ff96f046 100644
--- a/src/frontend/mame/ui/keyboard.cpp
+++ b/src/frontend/mame/ui/keyboard.cpp
@@ -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());
diff --git a/src/frontend/mame/ui/keyboard.h b/src/frontend/mame/ui/keyboard.h
index 36371f5711c..478d97a5a11 100644
--- a/src/frontend/mame/ui/keyboard.h
+++ b/src/frontend/mame/ui/keyboard.h
@@ -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;
};
diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp
index 0ef893dfd1c..7d53266e65b 100644
--- a/src/frontend/mame/ui/mainmenu.cpp
+++ b/src/frontend/mame/ui/mainmenu.cpp
@@ -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();
diff --git a/src/frontend/mame/ui/mainmenu.h b/src/frontend/mame/ui/mainmenu.h
index 6671dd9f554..de596716da6 100644
--- a/src/frontend/mame/ui/mainmenu.h
+++ b/src/frontend/mame/ui/mainmenu.h
@@ -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;
diff --git a/src/frontend/mame/ui/menu.cpp b/src/frontend/mame/ui/menu.cpp
index ba5767c794a..69e75563985 100644
--- a/src/frontend/mame/ui/menu.cpp
+++ b/src/frontend/mame/ui/menu.cpp
@@ -374,6 +374,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 (...)
{
diff --git a/src/frontend/mame/ui/menu.h b/src/frontend/mame/ui/menu.h
index 85a2f935d86..4126fa66cb5 100644
--- a/src/frontend/mame/ui/menu.h
+++ b/src/frontend/mame/ui/menu.h
@@ -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;
diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp
index 057df11e17d..9839d59a966 100644
--- a/src/frontend/mame/ui/miscmenu.cpp
+++ b/src/frontend/mame/ui/miscmenu.cpp
@@ -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();
diff --git a/src/frontend/mame/ui/miscmenu.h b/src/frontend/mame/ui/miscmenu.h
index 22a2d1dc135..ab763b7ed26 100644
--- a/src/frontend/mame/ui/miscmenu.h
+++ b/src/frontend/mame/ui/miscmenu.h
@@ -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;
};
diff --git a/src/frontend/mame/ui/optsmenu.cpp b/src/frontend/mame/ui/optsmenu.cpp
index bc9757a44a4..91e5fb52adb 100644
--- a/src/frontend/mame/ui/optsmenu.cpp
+++ b/src/frontend/mame/ui/optsmenu.cpp
@@ -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();
}
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/optsmenu.h b/src/frontend/mame/ui/optsmenu.h
index b10d6601926..d1779ede52a 100644
--- a/src/frontend/mame/ui/optsmenu.h
+++ b/src/frontend/mame/ui/optsmenu.h
@@ -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);
diff --git a/src/frontend/mame/ui/pluginopt.cpp b/src/frontend/mame/ui/pluginopt.cpp
index 08f7f84a752..3ad7a2ec2c3 100644
--- a/src/frontend/mame/ui/pluginopt.cpp
+++ b/src/frontend/mame/ui/pluginopt.cpp
@@ -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;
diff --git a/src/frontend/mame/ui/pluginopt.h b/src/frontend/mame/ui/pluginopt.h
index 15196c1ca2d..3779cf130c2 100644
--- a/src/frontend/mame/ui/pluginopt.h
+++ b/src/frontend/mame/ui/pluginopt.h
@@ -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;
diff --git a/src/frontend/mame/ui/quitmenu.cpp b/src/frontend/mame/ui/quitmenu.cpp
index bb26f7e6290..29f12143831 100644
--- a/src/frontend/mame/ui/quitmenu.cpp
+++ b/src/frontend/mame/ui/quitmenu.cpp
@@ -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()
{
}
diff --git a/src/frontend/mame/ui/quitmenu.h b/src/frontend/mame/ui/quitmenu.h
index 81ca61e2892..206ef1983ea 100644
--- a/src/frontend/mame/ui/quitmenu.h
+++ b/src/frontend/mame/ui/quitmenu.h
@@ -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;
};
diff --git a/src/frontend/mame/ui/selector.cpp b/src/frontend/mame/ui/selector.cpp
index 71643f4bf4e..b3a579cd049 100644
--- a/src/frontend/mame/ui/selector.cpp
+++ b/src/frontend/mame/ui/selector.cpp
@@ -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,11 +124,21 @@ 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
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/selector.h b/src/frontend/mame/ui/selector.h
index 17fdb972343..8d504a42e2d 100644
--- a/src/frontend/mame/ui/selector.h
+++ b/src/frontend/mame/ui/selector.h
@@ -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);
diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp
index 7b268f7ba97..047e6f6f721 100644
--- a/src/frontend/mame/ui/selgame.cpp
+++ b/src/frontend/mame/ui/selgame.cpp
@@ -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)
{
diff --git a/src/frontend/mame/ui/selgame.h b/src/frontend/mame/ui/selgame.h
index 1f28052ff88..af1dad248ac 100644
--- a/src/frontend/mame/ui/selgame.h
+++ b/src/frontend/mame/ui/selgame.h
@@ -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
diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp
index 7cceaa6ccb8..f24eb7b3581 100644
--- a/src/frontend/mame/ui/selmenu.cpp
+++ b/src/frontend/mame/ui/selmenu.cpp
@@ -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);
diff --git a/src/frontend/mame/ui/selsoft.cpp b/src/frontend/mame/ui/selsoft.cpp
index 56590e9e7ee..50822545dd1 100644
--- a/src/frontend/mame/ui/selsoft.cpp
+++ b/src/frontend/mame/ui/selsoft.cpp
@@ -526,6 +526,18 @@ void menu_select_software::handle(event const *ev)
}
//-------------------------------------------------
+// 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)
{
diff --git a/src/frontend/mame/ui/selsoft.h b/src/frontend/mame/ui/selsoft.h
index 4b22ebc6eaf..1ac874ac93a 100644
--- a/src/frontend/mame/ui/selsoft.h
+++ b/src/frontend/mame/ui/selsoft.h
@@ -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
diff --git a/src/frontend/mame/ui/simpleselgame.cpp b/src/frontend/mame/ui/simpleselgame.cpp
index be3e056c97f..9fd0b5bb177 100644
--- a/src/frontend/mame/ui/simpleselgame.cpp
+++ b/src/frontend/mame/ui/simpleselgame.cpp
@@ -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());
}
diff --git a/src/frontend/mame/ui/simpleselgame.h b/src/frontend/mame/ui/simpleselgame.h
index e5ea310c7ec..4f1effa4305 100644
--- a/src/frontend/mame/ui/simpleselgame.h
+++ b/src/frontend/mame/ui/simpleselgame.h
@@ -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
diff --git a/src/frontend/mame/ui/sliders.cpp b/src/frontend/mame/ui/sliders.cpp
index e95789500ca..e162ebeee1a 100644
--- a/src/frontend/mame/ui/sliders.cpp
+++ b/src/frontend/mame/ui/sliders.cpp
@@ -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);
}
+}
+
+
+//-------------------------------------------------
+// recompute_metrics - recompute metrics
+//-------------------------------------------------
+
+void menu_sliders::recompute_metrics(uint32_t width, uint32_t height, float aspect)
+{
+ menu::recompute_metrics(width, height, aspect);
- custombottom = 2.0f * line_height() + 2.0f * tb_border();
+ set_custom_space(0.0f, 2.0f * line_height() + 2.0f * tb_border());
}
diff --git a/src/frontend/mame/ui/sliders.h b/src/frontend/mame/ui/sliders.h
index 99a5c6e9cfb..645169189cc 100644
--- a/src/frontend/mame/ui/sliders.h
+++ b/src/frontend/mame/ui/sliders.h
@@ -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;
diff --git a/src/frontend/mame/ui/slotopt.cpp b/src/frontend/mame/ui/slotopt.cpp
index f1419122f98..1b30b6120c1 100644
--- a/src/frontend/mame/ui/slotopt.cpp
+++ b/src/frontend/mame/ui/slotopt.cpp
@@ -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());
}
diff --git a/src/frontend/mame/ui/slotopt.h b/src/frontend/mame/ui/slotopt.h
index 449d22627aa..6dae4ce062a 100644
--- a/src/frontend/mame/ui/slotopt.h
+++ b/src/frontend/mame/ui/slotopt.h
@@ -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;
diff --git a/src/frontend/mame/ui/sndmenu.cpp b/src/frontend/mame/ui/sndmenu.cpp
index 136cbcf98f4..f389c128c07 100644
--- a/src/frontend/mame/ui/sndmenu.cpp
+++ b/src/frontend/mame/ui/sndmenu.cpp
@@ -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];
diff --git a/src/frontend/mame/ui/sndmenu.h b/src/frontend/mame/ui/sndmenu.h
index 48d85b7d1a5..6e79d4f6faa 100644
--- a/src/frontend/mame/ui/sndmenu.h
+++ b/src/frontend/mame/ui/sndmenu.h
@@ -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;
diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp
index 3e3c460f203..49412c8a244 100644
--- a/src/frontend/mame/ui/state.cpp
+++ b/src/frontend/mame/ui/state.cpp
@@ -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;
@@ -421,6 +418,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());
}
diff --git a/src/frontend/mame/ui/state.h b/src/frontend/mame/ui/state.h
index c9594cf25cf..8d982678d7d 100644
--- a/src/frontend/mame/ui/state.h
+++ b/src/frontend/mame/ui/state.h
@@ -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;
diff --git a/src/frontend/mame/ui/submenu.cpp b/src/frontend/mame/ui/submenu.cpp
index 3450504fc4c..82eb23d6a17 100644
--- a/src/frontend/mame/ui/submenu.cpp
+++ b/src/frontend/mame/ui/submenu.cpp
@@ -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()));
}
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/submenu.h b/src/frontend/mame/ui/submenu.h
index fdcbfa2c7c2..c307f220924 100644
--- a/src/frontend/mame/ui/submenu.h
+++ b/src/frontend/mame/ui/submenu.h
@@ -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;
diff --git a/src/frontend/mame/ui/swlist.cpp b/src/frontend/mame/ui/swlist.cpp
index 5d3c74f8676..da0ec08cbac 100644
--- a/src/frontend/mame/ui/swlist.cpp
+++ b/src/frontend/mame/ui/swlist.cpp
@@ -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;
diff --git a/src/frontend/mame/ui/swlist.h b/src/frontend/mame/ui/swlist.h
index b77d8090d7b..ce50ad2cfae 100644
--- a/src/frontend/mame/ui/swlist.h
+++ b/src/frontend/mame/ui/swlist.h
@@ -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:
diff --git a/src/frontend/mame/ui/tapectrl.cpp b/src/frontend/mame/ui/tapectrl.cpp
index 5eb505712a4..f41a52addd5 100644
--- a/src/frontend/mame/ui/tapectrl.cpp
+++ b/src/frontend/mame/ui/tapectrl.cpp
@@ -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())
{
diff --git a/src/frontend/mame/ui/tapectrl.h b/src/frontend/mame/ui/tapectrl.h
index 1117e88ef5e..5a7fba62b64 100644
--- a/src/frontend/mame/ui/tapectrl.h
+++ b/src/frontend/mame/ui/tapectrl.h
@@ -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);
diff --git a/src/frontend/mame/ui/textbox.cpp b/src/frontend/mame/ui/textbox.cpp
index ac3f7337668..9c6dfded606 100644
--- a/src/frontend/mame/ui/textbox.cpp
+++ b/src/frontend/mame/ui/textbox.cpp
@@ -92,6 +92,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
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/textbox.h b/src/frontend/mame/ui/textbox.h
index bdbb63f934a..724134a482b 100644
--- a/src/frontend/mame/ui/textbox.h
+++ b/src/frontend/mame/ui/textbox.h
@@ -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:
diff --git a/src/frontend/mame/ui/utils.cpp b/src/frontend/mame/ui/utils.cpp
index 6a3d95d2139..aaafd1944ba 100644
--- a/src/frontend/mame/ui/utils.cpp
+++ b/src/frontend/mame/ui/utils.cpp
@@ -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());
diff --git a/src/frontend/mame/ui/videoopt.cpp b/src/frontend/mame/ui/videoopt.cpp
index 67881db6cd0..0aafba84d26 100644
--- a/src/frontend/mame/ui/videoopt.cpp
+++ b/src/frontend/mame/ui/videoopt.cpp
@@ -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;
diff --git a/src/frontend/mame/ui/videoopt.h b/src/frontend/mame/ui/videoopt.h
index b296cad06ab..cea2f231073 100644
--- a/src/frontend/mame/ui/videoopt.h
+++ b/src/frontend/mame/ui/videoopt.h
@@ -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;
diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp
index 2c8f604c9a2..94b904d0cf8 100644
--- a/src/osd/modules/input/input_sdl.cpp
+++ b/src/osd/modules/input/input_sdl.cpp
@@ -18,15 +18,6 @@
// standard sdl header
#include <SDL2/SDL.h>
-#include <cctype>
-// ReSharper disable once CppUnusedIncludeDirective
-#include <algorithm>
-#include <cstddef>
-#include <iterator>
-#include <memory>
-#include <mutex>
-#include <optional>
-#include <queue>
// MAME headers
#include "emu.h"
@@ -41,6 +32,14 @@
#include "../../sdl/osdsdl.h"
#include "../../sdl/window.h"
+#include <algorithm>
+#include <cctype>
+#include <cstddef>
+#include <iterator>
+#include <memory>
+#include <optional>
+#include <tuple>
+
// winnt.h defines this
#ifdef DELETE
#undef DELETE
@@ -53,6 +52,145 @@ namespace {
#define GET_FOCUS_WINDOW(ev) focus_window()
//#define GET_FOCUS_WINDOW(ev) window_from_id((ev)->windowID)
+char const *const CONTROLLER_AXIS_XBOX[]{
+ "LSX",
+ "LSY",
+ "RSX",
+ "RSY",
+ "LT",
+ "RT" };
+
+[[maybe_unused]] char const *const CONTROLLER_AXIS_PS[]{
+ "LSX",
+ "LSY",
+ "RSX",
+ "RSY",
+ "L2",
+ "R2" };
+
+[[maybe_unused]] char const *const CONTROLLER_AXIS_SWITCH[]{
+ "LSX",
+ "LSY",
+ "RSX",
+ "RSY",
+ "ZL",
+ "ZR" };
+
+char const *const CONTROLLER_BUTTON_XBOX360[]{
+ "A",
+ "B",
+ "X",
+ "Y",
+ "Back",
+ "Guide",
+ "Start",
+ "LSB",
+ "RSB",
+ "LB",
+ "RB",
+ "D-pad Up",
+ "D-pad Down",
+ "D-pad Left",
+ "D-pad Right",
+ "Share",
+ "P1",
+ "P2",
+ "P3",
+ "P4",
+ "Touchpad" };
+
+[[maybe_unused]] char const *const CONTROLLER_BUTTON_XBOXONE[]{
+ "A",
+ "B",
+ "X",
+ "Y",
+ "View",
+ "Guide",
+ "Menu",
+ "LSB",
+ "RSB",
+ "LB",
+ "RB",
+ "D-pad Up",
+ "D-pad Down",
+ "D-pad Left",
+ "D-pad Right",
+ "Share",
+ "P1",
+ "P2",
+ "P3",
+ "P4",
+ "Touchpad" };
+
+[[maybe_unused]] char const *const CONTROLLER_BUTTON_PS3[]{
+ "Cross",
+ "Circle",
+ "Square",
+ "Triangle",
+ "Select",
+ "PS",
+ "Start",
+ "L3",
+ "R3",
+ "L1",
+ "R1",
+ "D-pad Up",
+ "D-pad Down",
+ "D-pad Left",
+ "D-pad Right",
+ "Microphone",
+ "P1",
+ "P2",
+ "P3",
+ "P4",
+ "Touchpad" };
+
+[[maybe_unused]] char const *const CONTROLLER_BUTTON_PS4[]{
+ "Cross",
+ "Circle",
+ "Square",
+ "Triangle",
+ "Share",
+ "PS",
+ "Options",
+ "L3",
+ "R3",
+ "L1",
+ "R1",
+ "D-pad Up",
+ "D-pad Down",
+ "D-pad Left",
+ "D-pad Right",
+ "Microphone",
+ "P1",
+ "P2",
+ "P3",
+ "P4",
+ "Touchpad" };
+
+[[maybe_unused]] char const *const CONTROLLER_BUTTON_SWITCH[]{
+ "B",
+ "A",
+ "Y",
+ "Z",
+ "-",
+ "Home",
+ "+",
+ "LSB",
+ "RSB",
+ "L",
+ "R",
+ "D-pad Up",
+ "D-pad Down",
+ "D-pad Left",
+ "D-pad Right",
+ "Capture",
+ "P1",
+ "P2",
+ "P3",
+ "P4",
+ "Touchpad" };
+
struct key_lookup_table
{
int code;
@@ -326,9 +464,7 @@ key_lookup_table sdl_lookup_table[] =
KE(APP2)
-{
- -1, ""
-}
+ { -1, "" }
};
//============================================================
@@ -615,111 +751,305 @@ public:
};
//============================================================
-// sdl_joystick_device
+// sdl_joystick_device_base
//============================================================
-class sdl_joystick_device : public sdl_device
+class sdl_joystick_device_base : public sdl_device
{
public:
- // state information for a joystick
- struct sdl_joystick_state
+ std::optional<std::string> const &serial() const { return m_serial; }
+ SDL_JoystickID instance() const { return m_instance; }
+
+ bool is_instance(SDL_JoystickID instance) const { return m_instance == instance; }
+
+protected:
+ sdl_joystick_device_base(
+ running_machine &machine,
+ std::string &&name,
+ std::string &&id,
+ input_module &module,
+ char const *serial) :
+ sdl_device(machine, std::move(name), std::move(id), DEVICE_CLASS_JOYSTICK, module),
+ m_instance(-1)
{
- int32_t axes[MAX_AXES];
- int32_t buttons[MAX_BUTTONS];
- int32_t hatsU[MAX_HATS], hatsD[MAX_HATS], hatsL[MAX_HATS], hatsR[MAX_HATS];
- int32_t balls[MAX_AXES];
- };
+ if (serial)
+ m_serial = serial;
+ }
- struct sdl_api_state
+ void set_instance(SDL_JoystickID instance)
{
- SDL_Joystick *device = nullptr;
- SDL_Haptic *hapdevice = nullptr;
- SDL_JoystickID joystick_id;
- std::optional<std::string> serial;
- };
+ assert(0 > m_instance);
+ assert(0 <= instance);
- sdl_joystick_state joystick;
- sdl_api_state sdl_state;
+ m_instance = instance;
+ }
- sdl_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
- sdl_device(machine, std::move(name), std::move(id), DEVICE_CLASS_JOYSTICK, module),
- joystick({{0}})
+ void clear_instance()
{
+ m_instance = -1;
+ }
+
+private:
+ std::optional<std::string> m_serial;
+ SDL_JoystickID m_instance;
+};
+
+//============================================================
+// sdl_joystick_device
+//============================================================
+
+class sdl_joystick_device : public sdl_joystick_device_base
+{
+public:
+ sdl_joystick_device(
+ running_machine &machine,
+ std::string &&name,
+ std::string &&id,
+ input_module &module,
+ SDL_Joystick *joy,
+ char const *serial) :
+ sdl_joystick_device_base(
+ machine,
+ std::move(name),
+ std::move(id),
+ module,
+ serial),
+ m_joystick({{0}}),
+ m_joydevice(joy),
+ m_hapdevice(SDL_HapticOpenFromJoystick(joy))
+ {
+ set_instance(SDL_JoystickInstanceID(joy));
+ }
+
+ void configure()
+ {
+ char tempname[32];
+
+ // loop over all axes
+ for (int axis = 0; (axis < MAX_AXES) && (axis < SDL_JoystickNumAxes(m_joydevice)); axis++)
+ {
+ input_item_id itemid;
+
+ if (axis < INPUT_MAX_AXIS)
+ itemid = input_item_id(ITEM_ID_XAXIS + axis);
+ else if (axis < (INPUT_MAX_AXIS + INPUT_MAX_ADD_ABSOLUTE))
+ itemid = input_item_id(ITEM_ID_ADD_ABSOLUTE1 - INPUT_MAX_AXIS + axis);
+ else
+ itemid = ITEM_ID_OTHER_AXIS_ABSOLUTE;
+
+ snprintf(tempname, sizeof(tempname), "A%d", axis + 1);
+ device()->add_item(
+ tempname,
+ itemid,
+ generic_axis_get_state<std::int32_t>,
+ &m_joystick.axes[axis]);
+ }
+
+ // loop over all buttons
+ for (int button = 0; (button < MAX_BUTTONS) && (button < SDL_JoystickNumButtons(m_joydevice)); button++)
+ {
+ input_item_id itemid;
+
+ m_joystick.buttons[button] = 0;
+
+ if (button < INPUT_MAX_BUTTONS)
+ itemid = input_item_id(ITEM_ID_BUTTON1 + button);
+ else if (button < INPUT_MAX_BUTTONS + INPUT_MAX_ADD_SWITCH)
+ itemid = input_item_id(ITEM_ID_ADD_SWITCH1 - INPUT_MAX_BUTTONS + button);
+ else
+ itemid = ITEM_ID_OTHER_SWITCH;
+
+ device()->add_item(
+ default_button_name(button),
+ itemid,
+ generic_button_get_state<std::int32_t>,
+ &m_joystick.buttons[button]);
+ }
+
+ // loop over all hats
+ for (int hat = 0; (hat < MAX_HATS) && (hat < SDL_JoystickNumHats(m_joydevice)); hat++)
+ {
+ input_item_id itemid;
+
+ snprintf(tempname, sizeof(tempname), "Hat %d Up", hat + 1);
+ itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1UP + 4 * hat : ITEM_ID_OTHER_SWITCH);
+ device()->add_item(
+ tempname,
+ itemid,
+ generic_button_get_state<std::int32_t>,
+ &m_joystick.hatsU[hat]);
+
+ snprintf(tempname, sizeof(tempname), "Hat %d Down", hat + 1);
+ itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1DOWN + 4 * hat : ITEM_ID_OTHER_SWITCH);
+ device()->add_item(
+ tempname,
+ itemid,
+ generic_button_get_state<std::int32_t>,
+ &m_joystick.hatsD[hat]);
+
+ snprintf(tempname, sizeof(tempname), "Hat %d Left", hat + 1);
+ itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1LEFT + 4 * hat : ITEM_ID_OTHER_SWITCH);
+ device()->add_item(
+ tempname,
+ itemid,
+ generic_button_get_state<std::int32_t>,
+ &m_joystick.hatsL[hat]);
+
+ snprintf(tempname, sizeof(tempname), "Hat %d Right", hat + 1);
+ itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1RIGHT + 4 * hat : ITEM_ID_OTHER_SWITCH);
+ device()->add_item(
+ tempname,
+ itemid,
+ generic_button_get_state<std::int32_t>,
+ &m_joystick.hatsR[hat]);
+ }
+
+ // loop over all (track)balls
+ for (int ball = 0; (ball < (MAX_AXES / 2)) && (ball < SDL_JoystickNumBalls(m_joydevice)); ball++)
+ {
+ int itemid;
+
+ if (ball * 2 < INPUT_MAX_ADD_RELATIVE)
+ itemid = ITEM_ID_ADD_RELATIVE1 + ball * 2;
+ else
+ itemid = ITEM_ID_OTHER_AXIS_RELATIVE;
+
+ snprintf(tempname, sizeof(tempname), "R%d X", ball + 1);
+ device()->add_item(
+ tempname,
+ input_item_id(itemid),
+ generic_axis_get_state<std::int32_t>,
+ &m_joystick.balls[ball * 2]);
+
+ snprintf(tempname, sizeof(tempname), "R%d Y", ball + 1);
+ device()->add_item(
+ tempname, input_item_id(itemid + 1),
+ generic_axis_get_state<std::int32_t>,
+ &m_joystick.balls[ball * 2 + 1]);
+ }
}
~sdl_joystick_device()
{
- if (sdl_state.device)
+ if (m_joydevice)
{
- if (sdl_state.hapdevice)
+ if (m_hapdevice)
{
- SDL_HapticClose(sdl_state.hapdevice);
- sdl_state.hapdevice = nullptr;
+ SDL_HapticClose(m_hapdevice);
+ m_hapdevice = nullptr;
}
- SDL_JoystickClose(sdl_state.device);
- sdl_state.device = nullptr;
+ SDL_JoystickClose(m_joydevice);
+ m_joydevice = nullptr;
}
}
- void reset() override
+ virtual void reset() override
{
- memset(&joystick, 0, sizeof(joystick));
+ memset(&m_joystick, 0, sizeof(m_joystick));
}
- void process_event(SDL_Event &sdlevent) override
+ virtual void process_event(SDL_Event &sdlevent) override
{
switch (sdlevent.type)
{
case SDL_JOYAXISMOTION:
- joystick.axes[sdlevent.jaxis.axis] = (sdlevent.jaxis.value * 2);
+ if (sdlevent.jaxis.axis < MAX_AXES)
+ m_joystick.axes[sdlevent.jaxis.axis] = (sdlevent.jaxis.value * 2);
break;
case SDL_JOYBALLMOTION:
//printf("Ball %d %d\n", sdlevent.jball.xrel, sdlevent.jball.yrel);
- joystick.balls[sdlevent.jball.ball * 2] = sdlevent.jball.xrel * osd::INPUT_RELATIVE_PER_PIXEL;
- joystick.balls[sdlevent.jball.ball * 2 + 1] = sdlevent.jball.yrel * osd::INPUT_RELATIVE_PER_PIXEL;
+ if (sdlevent.jball.ball < (MAX_AXES / 2))
+ {
+ m_joystick.balls[sdlevent.jball.ball * 2] = sdlevent.jball.xrel * osd::INPUT_RELATIVE_PER_PIXEL;
+ m_joystick.balls[sdlevent.jball.ball * 2 + 1] = sdlevent.jball.yrel * osd::INPUT_RELATIVE_PER_PIXEL;
+ }
break;
case SDL_JOYHATMOTION:
- joystick.hatsU[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_UP) ? 0x80 : 0;
- joystick.hatsD[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_DOWN) ? 0x80 : 0;
- joystick.hatsL[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_LEFT) ? 0x80 : 0;
- joystick.hatsR[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_RIGHT) ? 0x80 : 0;
+ if (sdlevent.jhat.hat < MAX_HATS)
+ {
+ m_joystick.hatsU[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_UP) ? 0x80 : 0;
+ m_joystick.hatsD[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_DOWN) ? 0x80 : 0;
+ m_joystick.hatsL[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_LEFT) ? 0x80 : 0;
+ m_joystick.hatsR[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_RIGHT) ? 0x80 : 0;
+ }
break;
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
if (sdlevent.jbutton.button < MAX_BUTTONS)
- joystick.buttons[sdlevent.jbutton.button] = (sdlevent.jbutton.state == SDL_PRESSED) ? 0x80 : 0;
+ m_joystick.buttons[sdlevent.jbutton.button] = (sdlevent.jbutton.state == SDL_PRESSED) ? 0x80 : 0;
break;
case SDL_JOYDEVICEREMOVED:
osd_printf_verbose("Joystick: %s [GUID %s] disconnected\n", name(), id());
+ clear_instance();
reset();
- if (sdl_state.device)
+ if (m_joydevice)
{
- if (sdl_state.hapdevice)
+ if (m_hapdevice)
{
- SDL_HapticClose(sdl_state.hapdevice);
- sdl_state.hapdevice = nullptr;
+ SDL_HapticClose(m_hapdevice);
+ m_hapdevice = nullptr;
}
- SDL_JoystickClose(sdl_state.device);
- sdl_state.device = nullptr;
+ SDL_JoystickClose(m_joydevice);
+ m_joydevice = nullptr;
}
break;
}
}
+
+ bool has_haptic() const
+ {
+ return m_hapdevice != nullptr;
+ }
+
+ bool reconnect_match(std::string_view g, char const *s) const
+ {
+ return
+ !m_joydevice &&
+ (id() == g) &&
+ ((s && serial() && (*serial() == s)) || (!s && !serial()));
+ }
+
+ void attach_device(SDL_Joystick *joy)
+ {
+ assert(joy);
+ assert(!m_joydevice);
+
+ set_instance(SDL_JoystickInstanceID(joy));
+ m_joydevice = joy;
+ m_hapdevice = SDL_HapticOpenFromJoystick(joy);
+ }
+
+protected:
+ // state information for a joystick
+ struct sdl_joystick_state
+ {
+ int32_t axes[MAX_AXES];
+ int32_t buttons[MAX_BUTTONS];
+ int32_t hatsU[MAX_HATS], hatsD[MAX_HATS], hatsL[MAX_HATS], hatsR[MAX_HATS];
+ int32_t balls[MAX_AXES];
+ };
+
+ sdl_joystick_state m_joystick;
+
+private:
+ SDL_Joystick *m_joydevice;
+ SDL_Haptic *m_hapdevice;
};
+//============================================================
+// sdl_sixaxis_joystick_device
+//============================================================
+
class sdl_sixaxis_joystick_device : public sdl_joystick_device
{
public:
- sdl_sixaxis_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
- sdl_joystick_device(machine, std::move(name), std::move(id), module)
- {
- }
+ using sdl_joystick_device::sdl_joystick_device;
- void process_event(SDL_Event &sdlevent) override
+ virtual void process_event(SDL_Event &sdlevent) override
{
switch (sdlevent.type)
{
@@ -728,12 +1058,12 @@ public:
int const axis = sdlevent.jaxis.axis;
if (axis <= 3)
{
- joystick.axes[sdlevent.jaxis.axis] = (sdlevent.jaxis.value * 2);
+ m_joystick.axes[sdlevent.jaxis.axis] = (sdlevent.jaxis.value * 2);
}
else
{
int const magic = (sdlevent.jaxis.value / 2) + 16384;
- joystick.axes[sdlevent.jaxis.axis] = magic;
+ m_joystick.axes[sdlevent.jaxis.axis] = magic;
}
}
break;
@@ -747,13 +1077,315 @@ public:
};
//============================================================
+// sdl_game_controller_device
+//============================================================
+
+class sdl_game_controller_device : public sdl_joystick_device_base
+{
+public:
+ sdl_game_controller_device(
+ running_machine &machine,
+ std::string &&name,
+ std::string &&id,
+ input_module &module,
+ SDL_GameController *ctrl,
+ char const *serial) :
+ sdl_joystick_device_base(
+ machine,
+ std::move(name),
+ std::move(id),
+ module,
+ serial),
+ m_controller({{0}}),
+ m_ctrldevice(ctrl)
+ {
+ set_instance(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(ctrl)));
+ }
+
+ ~sdl_game_controller_device()
+ {
+ if (m_ctrldevice)
+ {
+ SDL_GameControllerClose(m_ctrldevice);
+ m_ctrldevice = nullptr;
+ }
+ }
+
+ void configure()
+ {
+ char const *const *axisnames = CONTROLLER_AXIS_XBOX;
+ char const *const *buttonnames = CONTROLLER_BUTTON_XBOX360;
+#if SDL_VERSION_ATLEAST(2, 0, 12)
+ auto const ctrltype = SDL_GameControllerGetType(m_ctrldevice);
+ switch (ctrltype)
+ {
+ case SDL_CONTROLLER_TYPE_UNKNOWN:
+ osd_printf_verbose("Game Controller: ... unknown type\n", int(ctrltype));
+ break;
+ case SDL_CONTROLLER_TYPE_XBOX360:
+ osd_printf_verbose("Game Controller: ... Xbox 360 type\n");
+ axisnames = CONTROLLER_AXIS_XBOX;
+ buttonnames = CONTROLLER_BUTTON_XBOX360;
+ break;
+ case SDL_CONTROLLER_TYPE_XBOXONE:
+ osd_printf_verbose("Game Controller: ... Xbox One type\n");
+ axisnames = CONTROLLER_AXIS_XBOX;
+ buttonnames = CONTROLLER_BUTTON_XBOXONE;
+ break;
+ case SDL_CONTROLLER_TYPE_PS3:
+ osd_printf_verbose("Game Controller: ... PlayStation 3 type\n");
+ axisnames = CONTROLLER_AXIS_PS;
+ buttonnames = CONTROLLER_BUTTON_PS3;
+ break;
+ case SDL_CONTROLLER_TYPE_PS4:
+ osd_printf_verbose("Game Controller: ... PlayStation 4 type\n");
+ axisnames = CONTROLLER_AXIS_PS;
+ buttonnames = CONTROLLER_BUTTON_PS4;
+ break;
+ case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
+ osd_printf_verbose("Game Controller: ... Switch Pro Controller type\n");
+ axisnames = CONTROLLER_AXIS_SWITCH;
+ buttonnames = CONTROLLER_BUTTON_SWITCH;
+ break;
+#if SDL_VERSION_ATLEAST(2, 0, 14) // TODO: support more controller types
+ //case SDL_CONTROLLER_TYPE_VIRTUAL:
+ //case SDL_CONTROLLER_TYPE_PS5:
+ //case SDL_CONTROLLER_TYPE_AMAZON_LUNA:
+ //case SDL_CONTROLLER_TYPE_GOOGLE_STADIA:
+ //case SDL_CONTROLLER_TYPE_SWITCH_JOYCON_LEFT:
+ //case SDL_CONTROLLER_TYPE_SWITCH_JOYCON_RIGHT:
+ //case SDL_CONTROLLER_TYPE_SWITCH_JOYCON_PAIR:
+#endif
+ default: // default to Xbox 360 names
+ osd_printf_verbose("Game Controller: ... unrecognised type (%d)\n", int(ctrltype));
+ break;
+ }
+#endif
+
+ // add axes
+ std::tuple<SDL_GameControllerAxis, input_item_id, bool> axes[]{
+ { SDL_CONTROLLER_AXIS_LEFTX, ITEM_ID_XAXIS, false },
+ { SDL_CONTROLLER_AXIS_LEFTY, ITEM_ID_YAXIS, false },
+ { SDL_CONTROLLER_AXIS_RIGHTX, ITEM_ID_ZAXIS, false },
+ { SDL_CONTROLLER_AXIS_RIGHTY, ITEM_ID_RZAXIS, false },
+ { SDL_CONTROLLER_AXIS_TRIGGERLEFT, ITEM_ID_SLIDER1, true },
+ { SDL_CONTROLLER_AXIS_TRIGGERRIGHT, ITEM_ID_SLIDER2, true } };
+ for (auto [axis, item, buttontest] : axes)
+ {
+ bool avail = true;
+#if SDL_VERSION_ATLEAST(2, 0, 14)
+ avail = SDL_GameControllerHasAxis(m_ctrldevice, axis);
+#endif
+ if (avail)
+ {
+ auto const binding = SDL_GameControllerGetBindForAxis(m_ctrldevice, axis);
+ switch (binding.bindType)
+ {
+ case SDL_CONTROLLER_BINDTYPE_NONE:
+ avail = false;
+ break;
+ case SDL_CONTROLLER_BINDTYPE_BUTTON:
+ if (buttontest)
+ avail = false;
+ break;
+ default:
+ break;
+ }
+ }
+ if (avail)
+ {
+ device()->add_item(
+ axisnames[axis],
+ item,
+ generic_axis_get_state<std::int32_t>,
+ &m_controller.axes[axis]);
+ }
+ }
+
+ // add automatically numbered buttons
+ std::pair<SDL_GameControllerButton, SDL_GameControllerAxis> numberedbuttons[]{
+ { SDL_CONTROLLER_BUTTON_A, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_B, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_X, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_Y, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_LEFTSHOULDER, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_INVALID, SDL_CONTROLLER_AXIS_TRIGGERLEFT },
+ { SDL_CONTROLLER_BUTTON_INVALID, SDL_CONTROLLER_AXIS_TRIGGERRIGHT },
+ { SDL_CONTROLLER_BUTTON_LEFTSTICK, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_RIGHTSTICK, SDL_CONTROLLER_AXIS_INVALID },
+#if SDL_VERSION_ATLEAST(2, 0, 14)
+ { SDL_CONTROLLER_BUTTON_PADDLE1, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_PADDLE2, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_PADDLE3, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_PADDLE4, SDL_CONTROLLER_AXIS_INVALID },
+#endif
+ { SDL_CONTROLLER_BUTTON_GUIDE, SDL_CONTROLLER_AXIS_INVALID },
+#if SDL_VERSION_ATLEAST(2, 0, 14)
+ { SDL_CONTROLLER_BUTTON_MISC1, SDL_CONTROLLER_AXIS_INVALID },
+ { SDL_CONTROLLER_BUTTON_TOUCHPAD, SDL_CONTROLLER_AXIS_INVALID },
+#endif
+ };
+ input_item_id button_item = ITEM_ID_BUTTON1;
+ for (auto [button, axis] : numberedbuttons)
+ {
+ bool avail = true;
+ if (SDL_CONTROLLER_BUTTON_INVALID != button)
+ {
+#if SDL_VERSION_ATLEAST(2, 0, 14)
+ avail = SDL_GameControllerHasButton(m_ctrldevice, button);
+#endif
+ if (avail)
+ {
+ auto const binding = SDL_GameControllerGetBindForButton(m_ctrldevice, button);
+ switch (binding.bindType)
+ {
+ case SDL_CONTROLLER_BINDTYPE_NONE:
+ avail = false;
+ break;
+ default:
+ break;
+ }
+ }
+ if (avail)
+ {
+ device()->add_item(
+ buttonnames[button],
+ button_item++,
+ generic_button_get_state<std::int32_t>,
+ &m_controller.buttons[button]);
+ }
+ }
+ else
+ {
+#if SDL_VERSION_ATLEAST(2, 0, 14)
+ avail = SDL_GameControllerHasAxis(m_ctrldevice, axis);
+#endif
+ if (avail)
+ {
+ auto const binding = SDL_GameControllerGetBindForAxis(m_ctrldevice, axis);
+ switch (binding.bindType)
+ {
+ case SDL_CONTROLLER_BINDTYPE_BUTTON:
+ break;
+ default:
+ avail = false;
+ }
+ }
+ if (avail)
+ {
+ device()->add_item(
+ axisnames[axis],
+ button_item++,
+ [] (void *device_internal, void *item_internal) -> int
+ {
+ return (*reinterpret_cast<int32_t const *>(item_internal) <= -16'384) ? 1 : 0;
+ },
+ &m_controller.axes[axis]);
+ }
+ }
+ }
+
+ // add buttons with fixed item IDs
+ std::pair<SDL_GameControllerButton, input_item_id> fixedbuttons[]{
+ { SDL_CONTROLLER_BUTTON_BACK, ITEM_ID_SELECT },
+ { SDL_CONTROLLER_BUTTON_START, ITEM_ID_START },
+ { SDL_CONTROLLER_BUTTON_DPAD_UP, ITEM_ID_HAT1UP },
+ { SDL_CONTROLLER_BUTTON_DPAD_DOWN, ITEM_ID_HAT1DOWN },
+ { SDL_CONTROLLER_BUTTON_DPAD_LEFT, ITEM_ID_HAT1LEFT },
+ { SDL_CONTROLLER_BUTTON_DPAD_RIGHT, ITEM_ID_HAT1RIGHT } };
+ for (auto [button, item] : fixedbuttons)
+ {
+ bool avail = true;
+#if SDL_VERSION_ATLEAST(2, 0, 14)
+ avail = SDL_GameControllerHasButton(m_ctrldevice, button);
+#endif
+ if (avail)
+ {
+ auto const binding = SDL_GameControllerGetBindForButton(m_ctrldevice, button);
+ switch (binding.bindType)
+ {
+ case SDL_CONTROLLER_BINDTYPE_NONE:
+ avail = false;
+ break;
+ default:
+ break;
+ }
+ }
+ if (avail)
+ {
+ device()->add_item(
+ buttonnames[button],
+ item,
+ generic_button_get_state<std::int32_t>,
+ &m_controller.buttons[button]);
+ }
+ }
+ }
+
+ virtual void reset() override
+ {
+ memset(&m_controller, 0, sizeof(m_controller));
+ }
+
+ virtual void process_event(SDL_Event &sdlevent) override
+ {
+ switch (sdlevent.type)
+ {
+ case SDL_CONTROLLERAXISMOTION:
+ if (sdlevent.caxis.axis < SDL_CONTROLLER_AXIS_MAX)
+ {
+ switch (sdlevent.caxis.axis)
+ {
+ case SDL_CONTROLLER_AXIS_TRIGGERLEFT: // MAME wants negative values for triggers
+ case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
+ m_controller.axes[sdlevent.caxis.axis] = -normalize_absolute_axis(sdlevent.caxis.value, -32'767, 32'767);
+ break;
+ default:
+ m_controller.axes[sdlevent.caxis.axis] = normalize_absolute_axis(sdlevent.caxis.value, -32'767, 32'767);
+ }
+ }
+ break;
+
+ case SDL_CONTROLLERBUTTONDOWN:
+ case SDL_CONTROLLERBUTTONUP:
+ if (sdlevent.cbutton.button < SDL_CONTROLLER_BUTTON_MAX)
+ m_controller.buttons[sdlevent.cbutton.button] = (sdlevent.cbutton.state == SDL_PRESSED) ? 0x80 : 0x00;
+ break;
+
+ case SDL_CONTROLLERDEVICEREMOVED:
+ osd_printf_verbose("Game Controller: %s [GUID %s] disconnected\n", name(), id());
+ clear_instance();
+ reset();
+ if (m_ctrldevice)
+ {
+ SDL_GameControllerClose(m_ctrldevice);
+ m_ctrldevice = nullptr;
+ }
+ break;
+ }
+ }
+
+private:
+ // state information for a game controller
+ struct sdl_controller_state
+ {
+ int32_t axes[SDL_CONTROLLER_AXIS_MAX];
+ int32_t buttons[SDL_CONTROLLER_BUTTON_MAX];
+ };
+
+ sdl_controller_state m_controller;
+ SDL_GameController *m_ctrldevice;
+};
+
+//============================================================
// sdl_input_module
//============================================================
class sdl_input_module : public input_module_base, public sdl_event_subscriber
{
public:
- sdl_input_module(const char *type) : input_module_base(type, "sdl")
+ sdl_input_module(char const *type, char const *name) : input_module_base(type, name)
{
}
@@ -804,7 +1436,7 @@ class sdl_keyboard_module : public sdl_input_module
keyboard_trans_table * m_key_trans_table;
public:
sdl_keyboard_module() :
- sdl_input_module(OSD_KEYBOARDINPUT_PROVIDER),
+ sdl_input_module(OSD_KEYBOARDINPUT_PROVIDER, "sdl"),
m_key_trans_table(nullptr)
{
}
@@ -936,7 +1568,7 @@ private:
class sdl_mouse_module : public sdl_input_module
{
public:
- sdl_mouse_module() : sdl_input_module(OSD_MOUSEINPUT_PROVIDER)
+ sdl_mouse_module() : sdl_input_module(OSD_MOUSEINPUT_PROVIDER, "sdl")
{
}
@@ -979,16 +1611,11 @@ public:
class sdl_joystick_module : public sdl_input_module
{
-private:
- bool m_initialized_joystick;
- bool m_initialized_haptic;
- bool m_sixaxis_mode;
public:
sdl_joystick_module() :
- sdl_input_module(OSD_JOYSTICKINPUT_PROVIDER),
+ sdl_input_module(OSD_JOYSTICKINPUT_PROVIDER, "sdljoy"),
m_initialized_joystick(false),
- m_initialized_haptic(false),
- m_sixaxis_mode(false)
+ m_initialized_haptic(false)
{
}
@@ -997,14 +1624,10 @@ public:
sdl_input_module::exit();
if (m_initialized_joystick)
- {
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
- }
if (m_initialized_haptic)
- {
SDL_QuitSubSystem(SDL_INIT_HAPTIC);
- }
}
virtual void input_init(running_machine &machine) override
@@ -1026,9 +1649,7 @@ public:
sdl_input_module::input_init(machine);
- char tempname[512];
-
- m_sixaxis_mode = downcast<const sdl_options *>(options())->sixaxis();
+ bool const sixaxis_mode = downcast<const sdl_options *>(options())->sixaxis();
osd_printf_verbose("Joystick: Start initialization\n");
for (int physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++)
@@ -1047,9 +1668,9 @@ public:
if (serial)
id.append(1, '-').append(serial);
- sdl_joystick_device *const devinfo = m_sixaxis_mode
- ? &devicelist().create_device<sdl_sixaxis_joystick_device>(machine, name ? name : guid_str, guid_str, *this)
- : &devicelist().create_device<sdl_joystick_device>(machine, name ? name : guid_str, guid_str, *this);
+ sdl_joystick_device *const devinfo = sixaxis_mode
+ ? &devicelist().create_device<sdl_sixaxis_joystick_device>(machine, name ? name : guid_str, guid_str, *this, joy, serial)
+ : &devicelist().create_device<sdl_joystick_device>(machine, name ? name : guid_str, guid_str, *this, joy, serial);
if (!devinfo)
{
@@ -1057,12 +1678,6 @@ public:
continue;
}
- devinfo->sdl_state.device = joy;
- devinfo->sdl_state.joystick_id = SDL_JoystickInstanceID(joy);
- devinfo->sdl_state.hapdevice = SDL_HapticOpenFromJoystick(joy);
- if (serial)
- devinfo->sdl_state.serial = serial;
-
osd_printf_verbose("Joystick: %s [GUID %s] Vendor ID %04X, Product ID %04X, Revision %04X, Serial %s\n",
name ? name : "<nullptr>",
guid_str,
@@ -1075,80 +1690,14 @@ public:
SDL_JoystickNumButtons(joy),
SDL_JoystickNumHats(joy),
SDL_JoystickNumBalls(joy));
- if (devinfo->sdl_state.hapdevice)
+ if (devinfo->has_haptic())
osd_printf_verbose("Joystick: ... Has haptic capability\n");
else
osd_printf_verbose("Joystick: ... Does not have haptic capability\n");
-
- // loop over all axes
- for (int axis = 0; axis < SDL_JoystickNumAxes(joy); axis++)
- {
- input_item_id itemid;
-
- if (axis < INPUT_MAX_AXIS)
- itemid = (input_item_id)(ITEM_ID_XAXIS + axis);
- else if (axis < INPUT_MAX_AXIS + INPUT_MAX_ADD_ABSOLUTE)
- itemid = (input_item_id)(ITEM_ID_ADD_ABSOLUTE1 - INPUT_MAX_AXIS + axis);
- else
- itemid = ITEM_ID_OTHER_AXIS_ABSOLUTE;
-
- snprintf(tempname, sizeof(tempname), "A%d", axis + 1);
- devinfo->device()->add_item(tempname, itemid, generic_axis_get_state<std::int32_t>, &devinfo->joystick.axes[axis]);
- }
-
- // loop over all buttons
if (SDL_JoystickNumButtons(joy) > MAX_BUTTONS)
osd_printf_verbose("Joystick: ... Has %d buttons which exceeds supported %d buttons\n", SDL_JoystickNumButtons(joy), MAX_BUTTONS);
- for (int button = 0; (button < MAX_BUTTONS) && (button < SDL_JoystickNumButtons(joy)); button++)
- {
- input_item_id itemid;
-
- devinfo->joystick.buttons[button] = 0;
-
- if (button < INPUT_MAX_BUTTONS)
- itemid = (input_item_id)(ITEM_ID_BUTTON1 + button);
- else if (button < INPUT_MAX_BUTTONS + INPUT_MAX_ADD_SWITCH)
- itemid = (input_item_id)(ITEM_ID_ADD_SWITCH1 - INPUT_MAX_BUTTONS + button);
- else
- itemid = ITEM_ID_OTHER_SWITCH;
-
- devinfo->device()->add_item(default_button_name(button), itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.buttons[button]);
- }
-
- // loop over all hats
- for (int hat = 0; hat < SDL_JoystickNumHats(joy); hat++)
- {
- input_item_id itemid;
-
- snprintf(tempname, sizeof(tempname), "Hat %d Up", hat + 1);
- itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1UP + 4 * hat : ITEM_ID_OTHER_SWITCH);
- devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsU[hat]);
- snprintf(tempname, sizeof(tempname), "Hat %d Down", hat + 1);
- itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1DOWN + 4 * hat : ITEM_ID_OTHER_SWITCH);
- devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsD[hat]);
- snprintf(tempname, sizeof(tempname), "Hat %d Left", hat + 1);
- itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1LEFT + 4 * hat : ITEM_ID_OTHER_SWITCH);
- devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsL[hat]);
- snprintf(tempname, sizeof(tempname), "Hat %d Right", hat + 1);
- itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1RIGHT + 4 * hat : ITEM_ID_OTHER_SWITCH);
- devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsR[hat]);
- }
-
- // loop over all (track)balls
- for (int ball = 0; ball < SDL_JoystickNumBalls(joy); ball++)
- {
- int itemid;
- if (ball * 2 < INPUT_MAX_ADD_RELATIVE)
- itemid = ITEM_ID_ADD_RELATIVE1 + ball * 2;
- else
- itemid = ITEM_ID_OTHER_AXIS_RELATIVE;
-
- snprintf(tempname, sizeof(tempname), "R%d X", ball + 1);
- devinfo->device()->add_item(tempname, (input_item_id)itemid, generic_axis_get_state<std::int32_t>, &devinfo->joystick.balls[ball * 2]);
- snprintf(tempname, sizeof(tempname), "R%d Y", ball + 1);
- devinfo->device()->add_item(tempname, (input_item_id)(itemid + 1), generic_axis_get_state<std::int32_t>, &devinfo->joystick.balls[ball * 2 + 1]);
- }
+ devinfo->configure();
}
static int const event_types[] = {
@@ -1186,17 +1735,12 @@ public:
[&guid_str, &serial] (auto const &device)
{
auto &devinfo = downcast<sdl_joystick_device &>(*device);
- return
- !devinfo.sdl_state.device &&
- (devinfo.id() == guid_str) &&
- ((serial && devinfo.sdl_state.serial && (*devinfo.sdl_state.serial == serial)) || (!serial && !devinfo.sdl_state.serial));
+ return devinfo.reconnect_match(guid_str, serial);
});
if (devicelist().end() != target_device)
{
auto &devinfo = downcast<sdl_joystick_device &>(**target_device);
- devinfo.sdl_state.device = joy;
- devinfo.sdl_state.joystick_id = SDL_JoystickInstanceID(joy);
- devinfo.sdl_state.hapdevice = SDL_HapticOpenFromJoystick(joy);
+ devinfo.attach_device(joy);
osd_printf_verbose("Joystick: %s [GUID %s] reconnected\n", devinfo.name(), guid_str);
}
else
@@ -1207,10 +1751,10 @@ public:
}
else
{
- // Figure out which joystick this event id destined for
+ // figure out which joystick this event is destined for
sdl_joystick_device *const target_device = find_joystick(sdlevent.jdevice.which); // FIXME: this depends on SDL_JoystickID being the same size as Sint32
- // If we find a matching joystick, dispatch the event to the joystick
+ // if we find a matching joystick, dispatch the event to the joystick
if (target_device)
target_device->queue_events(&sdlevent, 1);
}
@@ -1222,11 +1766,128 @@ private:
for (auto &ptr : devicelist())
{
sdl_joystick_device *const device = downcast<sdl_joystick_device *>(ptr.get());
- if (device->sdl_state.device && (device->sdl_state.joystick_id == instance))
+ if (device->is_instance(instance))
return device;
}
return nullptr;
}
+
+ bool m_initialized_joystick;
+ bool m_initialized_haptic;
+};
+
+
+//============================================================
+// sdl_game_controller_module
+//============================================================
+
+class sdl_game_controller_module : public sdl_input_module
+{
+public:
+ sdl_game_controller_module() :
+ sdl_input_module(OSD_JOYSTICKINPUT_PROVIDER, "sdlgame"),
+ m_initialized_game_controller(false)
+ {
+ }
+
+ virtual void exit() override
+ {
+ sdl_input_module::exit();
+
+ if (m_initialized_game_controller)
+ SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
+ }
+
+ virtual void input_init(running_machine &machine) override
+ {
+ m_initialized_game_controller = !SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
+ if (!m_initialized_game_controller)
+ {
+ osd_printf_error("Could not initialize SDL Game Controller: %s.\n", SDL_GetError());
+ return;
+ }
+
+ sdl_input_module::input_init(machine);
+
+ osd_printf_verbose("Game Controller: Start initialization\n");
+ for (int physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++)
+ {
+ if (!SDL_IsGameController(physical_stick))
+ continue;
+
+ SDL_GameController *const ctrl = SDL_GameControllerOpen(physical_stick);
+ char const *const name = SDL_GameControllerName(ctrl);
+ SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(physical_stick);
+ char guid_str[256];
+ guid_str[0] = '\0';
+ SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str) - 1);
+ char const *serial = nullptr;
+#if SDL_VERSION_ATLEAST(2, 0, 14)
+ serial = SDL_GameControllerGetSerial(ctrl);
+#endif
+ std::string id(guid_str);
+ if (serial)
+ id.append(1, '-').append(serial);
+
+ sdl_game_controller_device *const devinfo = &devicelist().create_device<sdl_game_controller_device>(
+ machine,
+ name ? name : guid_str,
+ guid_str,
+ *this,
+ ctrl,
+ serial);
+
+ if (!devinfo)
+ {
+ SDL_GameControllerClose(ctrl);
+ continue;
+ }
+
+ osd_printf_verbose("Game Controller: %s [GUID %s] Vendor ID %04X, Product ID %04X, Revision %04X, Serial %s\n",
+ name ? name : "<nullptr>",
+ guid_str,
+ SDL_GameControllerGetVendor(ctrl),
+ SDL_GameControllerGetProduct(ctrl),
+ SDL_GameControllerGetProductVersion(ctrl),
+ serial ? serial : "<nullptr>");
+
+ devinfo->configure();
+ }
+
+ static int const event_types[] = {
+ int(SDL_CONTROLLERAXISMOTION),
+ int(SDL_CONTROLLERBUTTONDOWN),
+ int(SDL_CONTROLLERBUTTONUP),
+ int(SDL_CONTROLLERDEVICEREMOVED) };
+
+ sdl_event_manager::instance().subscribe(event_types, this);
+
+ osd_printf_verbose("Joystick: End initialization\n");
+ }
+
+ virtual void handle_event(SDL_Event &sdlevent) override
+ {
+ // figure out which game controller this event is destined for
+ sdl_game_controller_device *const target_device = find_controller(sdlevent.jdevice.which); // FIXME: this depends on SDL_JoystickID being the same size as Sint32
+
+ // if we find a matching controller, dispatch the event to the game controller
+ if (target_device)
+ target_device->queue_events(&sdlevent, 1);
+ }
+
+private:
+ sdl_game_controller_device *find_controller(SDL_JoystickID instance)
+ {
+ for (auto &ptr : devicelist())
+ {
+ sdl_game_controller_device *const device = downcast<sdl_game_controller_device *>(ptr.get());
+ if (device->is_instance(instance))
+ return device;
+ }
+ return nullptr;
+ }
+
+ bool m_initialized_game_controller;
};
} // anonymous namespace
@@ -1237,10 +1898,12 @@ private:
MODULE_NOT_SUPPORTED(sdl_keyboard_module, OSD_KEYBOARDINPUT_PROVIDER, "sdl")
MODULE_NOT_SUPPORTED(sdl_mouse_module, OSD_MOUSEINPUT_PROVIDER, "sdl")
-MODULE_NOT_SUPPORTED(sdl_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "sdl")
+MODULE_NOT_SUPPORTED(sdl_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "sdljoy")
+MODULE_NOT_SUPPORTED(sdl_game_controller_module, OSD_JOYSTICKINPUT_PROVIDER, "sdlgame")
#endif // defined(SDLMAME_SDL2)
MODULE_DEFINITION(KEYBOARDINPUT_SDL, sdl_keyboard_module)
MODULE_DEFINITION(MOUSEINPUT_SDL, sdl_mouse_module)
-MODULE_DEFINITION(JOYSTICKINPUT_SDL, sdl_joystick_module)
+MODULE_DEFINITION(JOYSTICKINPUT_SDLJOY, sdl_joystick_module)
+MODULE_DEFINITION(JOYSTICKINPUT_SDLGAME, sdl_game_controller_module)
diff --git a/src/osd/modules/input/input_sdlcommon.cpp b/src/osd/modules/input/input_sdlcommon.cpp
index f0d8a8632f6..7fd13ce2b8f 100644
--- a/src/osd/modules/input/input_sdlcommon.cpp
+++ b/src/osd/modules/input/input_sdlcommon.cpp
@@ -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); });
}
}
diff --git a/src/osd/modules/input/input_winhybrid.cpp b/src/osd/modules/input/input_winhybrid.cpp
index 52d991a9674..5280d42c818 100644
--- a/src/osd/modules/input/input_winhybrid.cpp
+++ b/src/osd/modules/input/input_winhybrid.cpp
@@ -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);
}
}
}
diff --git a/src/osd/modules/input/input_xinput.cpp b/src/osd/modules/input/input_xinput.cpp
index e7242a4e38a..fda2b9d8b23 100644
--- a/src/osd/modules/input/input_xinput.cpp
+++ b/src/osd/modules/input/input_xinput.cpp
@@ -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;
+
+ // 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);
+
+ // 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);
+}
-const char *const xinput_button_names[] = {
- "A",
- "B",
- "X",
- "Y",
- "LB",
- "RB",
- "LS",
- "RS",
- "Start",
- "Back"
-};
+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);
+}
-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
-};
+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());
-
- // Set the player ID
- devinfo.xinput_state.player_index = index;
-
- // Assign the caps we captured earlier
- devinfo.xinput_state.caps = caps;
+ auto &devinfo = module.devicelist().create_device<xinput_joystick_device>(
+ machine,
+ device_name,
+ device_name,
+ module,
+ index,
+ caps,
+ shared_from_this());
+
+ // 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"
diff --git a/src/osd/modules/input/input_xinput.h b/src/osd/modules/input/input_xinput.h
index bd918f9aacb..edf3dc23ce5 100644
--- a/src/osd/modules/input/input_xinput.h
+++ b/src/osd/modules/input/input_xinput.h
@@ -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
diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp
index 6d6a865a9c7..d370bb0e658 100644
--- a/src/osd/modules/lib/osdobj_common.cpp
+++ b/src/osd/modules/lib/osdobj_common.cpp
@@ -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);