diff options
Diffstat (limited to 'src')
110 files changed, 2071 insertions, 1715 deletions
diff --git a/src/emu/main.h b/src/emu/main.h index 5d51d0ba844..78553ca5236 100644 --- a/src/emu/main.h +++ b/src/emu/main.h @@ -54,7 +54,7 @@ public: static void display_ui_chooser(running_machine &machine); static int start_frontend(emu_options &options, osd_interface &osd, std::vector<std::string> &args); static int start_frontend(emu_options &options, osd_interface &osd, int argc, char *argv[]); - static void draw_user_interface(running_machine& machine); + static bool draw_user_interface(running_machine& machine); static void periodic_check(); static bool frame_hook(); static void sound_hook(); diff --git a/src/emu/video.cpp b/src/emu/video.cpp index 5bb3ecdaf47..ed00fab3ea7 100644 --- a/src/emu/video.cpp +++ b/src/emu/video.cpp @@ -219,8 +219,8 @@ void video_manager::frame_update(bool from_debugger) bool anything_changed = update_screens && finish_screen_updates(); // update inputs and draw the user interface - machine().osd().input_update(); - emulator_info::draw_user_interface(machine()); + machine().osd().input_update(true); + anything_changed = emulator_info::draw_user_interface(machine()) || anything_changed; // let plugins draw over the UI anything_changed = emulator_info::frame_hook() || anything_changed; @@ -235,7 +235,7 @@ void video_manager::frame_update(bool from_debugger) // if we're throttling, synchronize before rendering attotime current_time = machine().time(); - if (!from_debugger && !skipped_it && phase > machine_phase::INIT && !m_low_latency && effective_throttle()) + if (!from_debugger && phase > machine_phase::INIT && !m_low_latency && effective_throttle()) update_throttle(current_time); // ask the OSD to update @@ -244,10 +244,10 @@ void video_manager::frame_update(bool from_debugger) g_profiler.stop(); // we synchronize after rendering instead of before, if low latency mode is enabled - if (!from_debugger && !skipped_it && phase > machine_phase::INIT && m_low_latency && effective_throttle()) + if (!from_debugger && phase > machine_phase::INIT && m_low_latency && effective_throttle()) update_throttle(current_time); - machine().osd().input_update(); + machine().osd().input_update(false); emulator_info::periodic_check(); if (!from_debugger) diff --git a/src/frontend/mame/mame.cpp b/src/frontend/mame/mame.cpp index 045ef56ac82..56c5638b3a8 100644 --- a/src/frontend/mame/mame.cpp +++ b/src/frontend/mame/mame.cpp @@ -458,9 +458,9 @@ int emulator_info::start_frontend(emu_options &options, osd_interface &osd, int return start_frontend(options, osd, args); } -void emulator_info::draw_user_interface(running_machine& machine) +bool emulator_info::draw_user_interface(running_machine& machine) { - mame_machine_manager::instance()->ui().update_and_render(machine.render().ui_container()); + return mame_machine_manager::instance()->ui().update_and_render(machine.render().ui_container()); } void emulator_info::periodic_check() diff --git a/src/frontend/mame/ui/about.cpp b/src/frontend/mame/ui/about.cpp index 62d0a1c5241..afb2b73d5d3 100644 --- a/src/frontend/mame/ui/about.cpp +++ b/src/frontend/mame/ui/about.cpp @@ -125,10 +125,12 @@ void menu_about::populate() // handle - manages inputs in the about modal //------------------------------------------------- -void menu_about::handle(event const *ev) +bool menu_about::handle(event const *ev) { if (ev) - handle_key(ev->iptkey); + return handle_key(ev->iptkey); + else + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/about.h b/src/frontend/mame/ui/about.h index 5e394ba5d9e..3e84aff7a5e 100644 --- a/src/frontend/mame/ui/about.h +++ b/src/frontend/mame/ui/about.h @@ -36,7 +36,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool 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 393feeb7822..f8767ad3c58 100644 --- a/src/frontend/mame/ui/analogipt.cpp +++ b/src/frontend/mame/ui/analogipt.cpp @@ -227,158 +227,171 @@ void menu_analog::menu_activated() } -void menu_analog::handle(event const *ev) +bool menu_analog::handle(event const *ev) { - // handle events - if (ev) + if (!ev) { - if (IPT_UI_ON_SCREEN_DISPLAY == ev->iptkey) - { - m_hide_menu = !m_hide_menu; - set_process_flags(PROCESS_LR_REPEAT | (m_hide_menu ? (PROCESS_CUSTOM_NAV | PROCESS_CUSTOM_ONLY) : 0)); - } - else if (IPT_UI_HELP == ev->iptkey) - { - stack_push<menu_fixed_textbox>( - ui(), - container(), - _("menu-analoginput", "Analog Input Adjustments Help"), - util::string_format( - _("menu-analoginput", HELP_TEXT), - ui().get_general_input_setting(IPT_UI_ON_SCREEN_DISPLAY), - ui().get_general_input_setting(IPT_UI_LEFT), - ui().get_general_input_setting(IPT_UI_RIGHT), - ui().get_general_input_setting(IPT_UI_CLEAR), - ui().get_general_input_setting(IPT_UI_PREV_GROUP), - ui().get_general_input_setting(IPT_UI_NEXT_GROUP), - ui().get_general_input_setting(IPT_UI_BACK))); - } - else if (m_hide_menu) + return false; + } + else if (IPT_UI_ON_SCREEN_DISPLAY == ev->iptkey) + { + m_hide_menu = !m_hide_menu; + set_process_flags(PROCESS_LR_REPEAT | (m_hide_menu ? (PROCESS_CUSTOM_NAV | PROCESS_CUSTOM_ONLY) : 0)); + return true; + } + else if (IPT_UI_HELP == ev->iptkey) + { + stack_push<menu_fixed_textbox>( + ui(), + container(), + _("menu-analoginput", "Analog Input Adjustments Help"), + util::string_format( + _("menu-analoginput", HELP_TEXT), + ui().get_general_input_setting(IPT_UI_ON_SCREEN_DISPLAY), + ui().get_general_input_setting(IPT_UI_LEFT), + ui().get_general_input_setting(IPT_UI_RIGHT), + ui().get_general_input_setting(IPT_UI_CLEAR), + ui().get_general_input_setting(IPT_UI_PREV_GROUP), + ui().get_general_input_setting(IPT_UI_NEXT_GROUP), + ui().get_general_input_setting(IPT_UI_BACK))); + return false; + } + else if (m_hide_menu) + { + switch (ev->iptkey) { - switch (ev->iptkey) - { - case IPT_UI_UP: - --m_top_field; - break; - case IPT_UI_DOWN: - ++m_top_field; - break; - case IPT_UI_HOME: - m_top_field = 0; - break; - case IPT_UI_END: - m_top_field = m_field_data.size(); - break; - } + case IPT_UI_UP: + --m_top_field; + return true; + case IPT_UI_DOWN: + ++m_top_field; + return true; + case IPT_UI_HOME: + m_top_field = 0; + return true; + case IPT_UI_END: + m_top_field = m_field_data.size(); + return true; + default: + return false; } - else if (ev->itemref) + } + else if (ev->itemref) + { + item_data &data(*reinterpret_cast<item_data *>(ev->itemref)); + int newval(data.cur); + + switch (ev->iptkey) { - item_data &data(*reinterpret_cast<item_data *>(ev->itemref)); - int newval(data.cur); + // flip toggles when selected + case IPT_UI_SELECT: + if (ANALOG_ITEM_REVERSE == data.type) + newval = newval ? 0 : 1; + break; + + // if cleared, reset to default value + case IPT_UI_CLEAR: + newval = data.defvalue; + break; + + // left decrements + case IPT_UI_LEFT: + newval -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; + break; - switch (ev->iptkey) + // right increments + case IPT_UI_RIGHT: + newval += machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; + break; + + // move to first item for previous device + case IPT_UI_PREV_GROUP: { - // flip toggles when selected - case IPT_UI_SELECT: - if (ANALOG_ITEM_REVERSE == data.type) - newval = newval ? 0 : 1; - break; - - // if cleared, reset to default value - case IPT_UI_CLEAR: - newval = data.defvalue; - break; - - // left decrements - case IPT_UI_LEFT: - newval -= machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; - break; - - // right increments - case IPT_UI_RIGHT: - newval += machine().input().code_pressed(KEYCODE_LSHIFT) ? 10 : 1; - break; - - // move to first item for previous device - case IPT_UI_PREV_GROUP: + auto current = std::distance(m_item_data.data(), &data); + device_t const *dev(&data.field.get().device()); + bool found_break = false; + while (0 < current) { - auto current = std::distance(m_item_data.data(), &data); - device_t const *dev(&data.field.get().device()); - bool found_break = false; - while (0 < current) + if (!found_break) { - if (!found_break) - { - device_t const *prev(&m_item_data[--current].field.get().device()); - if (prev != dev) - { - dev = prev; - found_break = true; - } - } - else if (&m_item_data[current - 1].field.get().device() != dev) + device_t const *prev(&m_item_data[--current].field.get().device()); + if (prev != dev) { - set_selection(&m_item_data[current]); - set_top_line(selected_index() - 1); - break; - } - else - { - --current; - } - if (found_break && !current) - { - set_selection(&m_item_data[current]); - set_top_line(selected_index() - 1); - break; + dev = prev; + found_break = true; } } + else if (&m_item_data[current - 1].field.get().device() != dev) + { + set_selection(&m_item_data[current]); + set_top_line(selected_index() - 1); + return true; + } + else + { + --current; + } + if (found_break && !current) + { + set_selection(&m_item_data[current]); + set_top_line(selected_index() - 1); + return true; + } } - break; + } + break; - // move to first item for next device - case IPT_UI_NEXT_GROUP: + // move to first item for next device + case IPT_UI_NEXT_GROUP: + { + auto current = std::distance(m_item_data.data(), &data); + device_t const *const dev(&data.field.get().device()); + while (m_item_data.size() > ++current) { - auto current = std::distance(m_item_data.data(), &data); - device_t const *const dev(&data.field.get().device()); - while (m_item_data.size() > ++current) + if (&m_item_data[current].field.get().device() != dev) { - if (&m_item_data[current].field.get().device() != dev) - { - set_selection(&m_item_data[current]); - set_top_line(selected_index() - 1); - break; - } + set_selection(&m_item_data[current]); + set_top_line(selected_index() - 1); + return true; } } - break; } + break; + } - // clamp to range - newval = std::clamp(newval, data.min, data.max); - - // if things changed, update - if (newval != data.cur) - { - ioport_field::user_settings settings; + // clamp to range + newval = std::clamp(newval, data.min, data.max); - // get the settings and set the new value - data.field.get().get_user_settings(settings); - switch (data.type) - { - case ANALOG_ITEM_KEYSPEED: settings.delta = newval; break; - case ANALOG_ITEM_CENTERSPEED: settings.centerdelta = newval; break; - case ANALOG_ITEM_REVERSE: settings.reverse = newval; break; - case ANALOG_ITEM_SENSITIVITY: settings.sensitivity = newval; break; - } - data.field.get().set_user_settings(settings); - data.cur = newval; + // if things changed, update + if (newval != data.cur) + { + ioport_field::user_settings settings; - // update the menu item - ev->item->set_subtext(item_text(data.type, newval)); - ev->item->set_flags((data.cur <= data.min) ? FLAG_RIGHT_ARROW : (data.cur >= data.max) ? FLAG_LEFT_ARROW : FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW); + // get the settings and set the new value + data.field.get().get_user_settings(settings); + switch (data.type) + { + case ANALOG_ITEM_KEYSPEED: settings.delta = newval; break; + case ANALOG_ITEM_CENTERSPEED: settings.centerdelta = newval; break; + case ANALOG_ITEM_REVERSE: settings.reverse = newval; break; + case ANALOG_ITEM_SENSITIVITY: settings.sensitivity = newval; break; } + data.field.get().set_user_settings(settings); + data.cur = newval; + + // update the menu item + ev->item->set_subtext(item_text(data.type, newval)); + ev->item->set_flags((data.cur <= data.min) ? FLAG_RIGHT_ARROW : (data.cur >= data.max) ? FLAG_LEFT_ARROW : FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW); + return true; } + else + { + return false; + } + } + else + { + return false; } } diff --git a/src/frontend/mame/ui/analogipt.h b/src/frontend/mame/ui/analogipt.h index 26f2580318a..d60aafd6cc4 100644 --- a/src/frontend/mame/ui/analogipt.h +++ b/src/frontend/mame/ui/analogipt.h @@ -68,7 +68,7 @@ private: using field_data_vector = std::vector<field_data>; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool 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 07f55510ec8..d225535c4e7 100644 --- a/src/frontend/mame/ui/auditmenu.cpp +++ b/src/frontend/mame/ui/auditmenu.cpp @@ -150,7 +150,7 @@ void menu_audit::populate() item_append(menu_item_type::SEPARATOR, 0); } -void menu_audit::handle(event const *ev) +bool menu_audit::handle(event const *ev) { switch (m_phase) { @@ -166,6 +166,7 @@ void menu_audit::handle(event const *ev) m_future.resize(std::thread::hardware_concurrency()); for (auto &future : m_future) future = std::async(std::launch::async, [this] () { return do_audit(); }); + return true; } } break; @@ -191,13 +192,17 @@ void menu_audit::handle(event const *ev) m_phase = phase::CANCELLATION; else m_phase = phase::AUDIT; + return true; } else if ((phase::CANCELLATION == m_phase) && machine().ui_input().pressed(IPT_UI_SELECT)) { m_cancel.store(true); + return true; } break; } + + return false; } bool menu_audit::do_audit() diff --git a/src/frontend/mame/ui/auditmenu.h b/src/frontend/mame/ui/auditmenu.h index f0a37f09fba..5d71b63fd2f 100644 --- a/src/frontend/mame/ui/auditmenu.h +++ b/src/frontend/mame/ui/auditmenu.h @@ -37,7 +37,7 @@ private: enum class phase { CONFIRMATION, AUDIT, CANCELLATION }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; bool do_audit(); void save_available_machines(); diff --git a/src/frontend/mame/ui/barcode.cpp b/src/frontend/mame/ui/barcode.cpp index 31dcf768e78..979203f0133 100644 --- a/src/frontend/mame/ui/barcode.cpp +++ b/src/frontend/mame/ui/barcode.cpp @@ -75,66 +75,74 @@ void menu_barcode_reader::populate() // handle - manages inputs in the barcode input menu //------------------------------------------------- -void menu_barcode_reader::handle(event const *ev) +bool menu_barcode_reader::handle(event const *ev) { - // process the event - if (ev) + if (!ev) + return false; + + switch (ev->iptkey) { - // handle selections - switch (ev->iptkey) + case IPT_UI_LEFT: + if (ev->itemref == ITEMREF_SELECT_READER) + return previous(); + break; + + case IPT_UI_RIGHT: + if (ev->itemref == ITEMREF_SELECT_READER) + return next(); + break; + + case IPT_UI_SELECT: + if (ev->itemref == ITEMREF_ENTER_BARCODE) { - case IPT_UI_LEFT: - if (ev->itemref == ITEMREF_SELECT_READER) - previous(); - break; - - case IPT_UI_RIGHT: - if (ev->itemref == ITEMREF_SELECT_READER) - next(); - break; - - case IPT_UI_SELECT: - if (ev->itemref == ITEMREF_ENTER_BARCODE) + //osd_printf_verbose("code %s\n", m_barcode_buffer); + if (!current_device()->is_valid(m_barcode_buffer.length())) { - std::string tmp_file(m_barcode_buffer); - //printf("code %s\n", m_barcode_buffer); - if (!current_device()->is_valid(tmp_file.length())) - ui().popup_time(5, "%s", _("Barcode length invalid!")); - else - { - current_device()->write_code(tmp_file.c_str(), tmp_file.length()); - // if sending was successful, reset char buffer - m_barcode_buffer.clear(); - reset(reset_options::REMEMBER_POSITION); - } + ui().popup_time(5, "%s", _("Barcode length invalid!")); } - break; - - case IPT_UI_CLEAR: - if (get_selection_ref() == ITEMREF_NEW_BARCODE) + else { + current_device()->write_code(m_barcode_buffer.c_str(), m_barcode_buffer.length()); + // if sending was successful, reset char buffer m_barcode_buffer.clear(); reset(reset_options::REMEMBER_POSITION); } - break; + } + break; + + case IPT_UI_CLEAR: + if (ev->itemref == ITEMREF_NEW_BARCODE) + { + m_barcode_buffer.clear(); + ev->item->set_subtext(m_barcode_buffer); + return true; + } + break; - case IPT_UI_PASTE: - if (get_selection_ref() == ITEMREF_NEW_BARCODE) + case IPT_UI_PASTE: + if (get_selection_ref() == ITEMREF_NEW_BARCODE) + { + if (paste_text(m_barcode_buffer, uchar_is_digit)) { - if (paste_text(m_barcode_buffer, uchar_is_digit)) - ev->item->set_subtext(m_barcode_buffer); + ev->item->set_subtext(m_barcode_buffer); + return true; } - break; + } + break; - case IPT_SPECIAL: - if (get_selection_ref() == ITEMREF_NEW_BARCODE) + case IPT_SPECIAL: + if (get_selection_ref() == ITEMREF_NEW_BARCODE) + { + if (input_character(m_barcode_buffer, ev->unichar, uchar_is_digit)) { - if (input_character(m_barcode_buffer, ev->unichar, uchar_is_digit)) - ev->item->set_subtext(m_barcode_buffer); + ev->item->set_subtext(m_barcode_buffer); + return true; } - break; } + break; } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/barcode.h b/src/frontend/mame/ui/barcode.h index 5f70fe65276..7fa9881c3dd 100644 --- a/src/frontend/mame/ui/barcode.h +++ b/src/frontend/mame/ui/barcode.h @@ -13,9 +13,13 @@ #pragma once -#include "machine/bcreader.h" #include "ui/devctrl.h" +#include "machine/bcreader.h" + +#include <string> + + namespace ui { class menu_barcode_reader : public menu_device_control<barcode_reader_device> { @@ -25,7 +29,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool 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 193a3c9efd6..054df4aed81 100644 --- a/src/frontend/mame/ui/cheatopt.cpp +++ b/src/frontend/mame/ui/cheatopt.cpp @@ -29,76 +29,77 @@ namespace ui { menu_cheat - handle the cheat menu -------------------------------------------------*/ -void menu_cheat::handle(event const *ev) +bool menu_cheat::handle(event const *ev) { - // handle events - if (ev && ev->itemref) - { - bool changed = false; + if (!ev || !ev->itemref) + return false; - // clear cheat comment on any movement or keypress - machine().popmessage(); + bool changed = false; - if ((ev->itemref == ITEMREF_CHEATS_RESET_ALL || ev->itemref == ITEMREF_CHEATS_RELOAD_ALL) && ev->iptkey == IPT_UI_SELECT) - { - // handle reset all + reset all cheats for reload all option - for (auto &curcheat : mame_machine_manager::instance()->cheat().entries()) - if (curcheat->select_default_state()) - changed = true; - } - else if (ev->itemref >= ITEMREF_CHEATS_FIRST_ITEM) - { - // handle individual cheats - cheat_entry *curcheat = reinterpret_cast<cheat_entry *>(ev->itemref); - const char *string; - switch (ev->iptkey) - { - // if selected, activate a oneshot - case IPT_UI_SELECT: - changed = curcheat->activate(); - break; - - // if cleared, reset to default value - case IPT_UI_CLEAR: - changed = curcheat->select_default_state(); - break; - - // left decrements - case IPT_UI_LEFT: - changed = curcheat->select_previous_state(); - break; - - // right increments - case IPT_UI_RIGHT: - changed = curcheat->select_next_state(); - break; - - // bring up display comment if one exists - case IPT_UI_DISPLAY_COMMENT: - case IPT_UI_UP: - case IPT_UI_DOWN: - string = curcheat->comment(); - if (string && *string) - machine().popmessage(_("Cheat Comment:\n%s"), string); - break; - } - } + // clear cheat comment on any movement or keypress + machine().popmessage(); - // handle reload all - if (ev->itemref == ITEMREF_CHEATS_RELOAD_ALL && ev->iptkey == IPT_UI_SELECT) + if ((ev->itemref == ITEMREF_CHEATS_RESET_ALL || ev->itemref == ITEMREF_CHEATS_RELOAD_ALL) && ev->iptkey == IPT_UI_SELECT) + { + // handle reset all + reset all cheats for reload all option + for (auto &curcheat : mame_machine_manager::instance()->cheat().entries()) + if (curcheat->select_default_state()) + changed = true; + } + else if (ev->itemref >= ITEMREF_CHEATS_FIRST_ITEM) + { + // handle individual cheats + cheat_entry *curcheat = reinterpret_cast<cheat_entry *>(ev->itemref); + const char *string; + switch (ev->iptkey) { - // re-init cheat engine and thus reload cheats/cheats have already been turned off by here - mame_machine_manager::instance()->cheat().reload(); - - // display the reloaded cheats - reset(reset_options::REMEMBER_REF); - machine().popmessage(_("All cheats reloaded")); + // if selected, activate a oneshot + case IPT_UI_SELECT: + changed = curcheat->activate(); + break; + + // if cleared, reset to default value + case IPT_UI_CLEAR: + changed = curcheat->select_default_state(); + break; + + // left decrements + case IPT_UI_LEFT: + changed = curcheat->select_previous_state(); + break; + + // right increments + case IPT_UI_RIGHT: + changed = curcheat->select_next_state(); + break; + + // bring up display comment if one exists + case IPT_UI_DISPLAY_COMMENT: + case IPT_UI_UP: + case IPT_UI_DOWN: + string = curcheat->comment(); + if (string && *string) + machine().popmessage(_("Cheat Comment:\n%s"), string); + break; } + } - // if things changed, update - if (changed) - reset(reset_options::REMEMBER_REF); + // handle reload all + if (ev->itemref == ITEMREF_CHEATS_RELOAD_ALL && ev->iptkey == IPT_UI_SELECT) + { + // re-init cheat engine and thus reload cheats/cheats have already been turned off by here + mame_machine_manager::instance()->cheat().reload(); + + // display the reloaded cheats + reset(reset_options::REMEMBER_REF); + machine().popmessage(_("All cheats reloaded")); } + + // if things changed, update + if (changed) + reset(reset_options::REMEMBER_REF); + + return false; // always triggers an item reset if the menu needs to be redrawn } diff --git a/src/frontend/mame/ui/cheatopt.h b/src/frontend/mame/ui/cheatopt.h index ba0f144dbaf..b704562202b 100644 --- a/src/frontend/mame/ui/cheatopt.h +++ b/src/frontend/mame/ui/cheatopt.h @@ -25,7 +25,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/confswitch.cpp b/src/frontend/mame/ui/confswitch.cpp index 7d6030ce669..946062b9a1d 100644 --- a/src/frontend/mame/ui/confswitch.cpp +++ b/src/frontend/mame/ui/confswitch.cpp @@ -171,103 +171,106 @@ void menu_confswitch::populate() } -void menu_confswitch::handle(event const *ev) +bool menu_confswitch::handle(event const *ev) { - // handle events - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + if (uintptr_t(ev->itemref) == 1U) { - if (uintptr_t(ev->itemref) == 1U) - { - // reset - if (ev->iptkey == IPT_UI_SELECT) - machine().schedule_hard_reset(); - } - else - { - // actual settings - ioport_field &field(*reinterpret_cast<ioport_field *>(ev->itemref)); - bool changed(false); + // reset + if (ev->iptkey == IPT_UI_SELECT) + machine().schedule_hard_reset(); + } + else + { + // actual settings + ioport_field &field(*reinterpret_cast<ioport_field *>(ev->itemref)); + bool changed(false); - switch (ev->iptkey) + switch (ev->iptkey) + { + // left goes to previous setting + case IPT_UI_LEFT: + field.select_previous_setting(); + changed = true; + break; + + // right goes to next setting + case IPT_UI_SELECT: + case IPT_UI_RIGHT: + field.select_next_setting(); + changed = true; + break; + + // if cleared, reset to default value + case IPT_UI_CLEAR: { - // left goes to previous setting - case IPT_UI_LEFT: - field.select_previous_setting(); - changed = true; - break; - - // right goes to next setting - case IPT_UI_SELECT: - case IPT_UI_RIGHT: - field.select_next_setting(); - changed = true; - break; - - // if cleared, reset to default value - case IPT_UI_CLEAR: + ioport_field::user_settings settings; + field.get_user_settings(settings); + if (field.defvalue() != settings.value) { - ioport_field::user_settings settings; - field.get_user_settings(settings); - if (field.defvalue() != settings.value) - { - settings.value = field.defvalue(); - field.set_user_settings(settings); - changed = true; - } + settings.value = field.defvalue(); + field.set_user_settings(settings); + changed = true; } - break; + } + break; - // trick to get previous group - depend on headings having null reference - case IPT_UI_PREV_GROUP: + // trick to get previous group - depend on headings having null reference + case IPT_UI_PREV_GROUP: + { + auto current = selected_index(); + bool found_break = false; + while (0 < current) { - auto current = selected_index(); - bool found_break = false; - while (0 < current) + if (!found_break) { - if (!found_break) - { - if (!item(--current).ref()) - found_break = true; - } - else if (!item(current - 1).ref()) - { - set_selected_index(current); - set_top_line(current - 1); - break; - } - else - { - --current; - } + if (!item(--current).ref()) + found_break = true; + } + else if (!item(current - 1).ref()) + { + set_selected_index(current); + set_top_line(current - 1); + return true; + } + else + { + --current; } } - break; + } + break; - // trick to get next group - depend on special item references - case IPT_UI_NEXT_GROUP: + // trick to get next group - depend on special item references + case IPT_UI_NEXT_GROUP: + { + auto current = selected_index(); + while (item_count() > ++current) { - auto current = selected_index(); - while (item_count() > ++current) + if (!item(current).ref()) { - if (!item(current).ref()) + if ((item_count() > (current + 1)) && (uintptr_t(item(current + 1).ref()) != 1)) { - if ((item_count() > (current + 1)) && (uintptr_t(item(current + 1).ref()) != 1)) - { - set_selected_index(current + 1); - set_top_line(current); - } - break; + set_selected_index(current + 1); + set_top_line(current); + return true; } + break; } } - break; } - - // if anything changed, rebuild the menu, trying to stay on the same field - if (changed) - reset(reset_options::REMEMBER_REF); + break; } + + // if anything changed, rebuild the menu, trying to stay on the same field + if (changed) + reset(reset_options::REMEMBER_REF); } + + // changing settings triggers an item rebuild because it can affect whether things are enabled + return false; } diff --git a/src/frontend/mame/ui/confswitch.h b/src/frontend/mame/ui/confswitch.h index 9094fb2dc22..2d025f7dfc8 100644 --- a/src/frontend/mame/ui/confswitch.h +++ b/src/frontend/mame/ui/confswitch.h @@ -64,7 +64,7 @@ protected: unsigned active_switch_groups() const { return m_active_switch_groups; } private: - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void find_fields(); diff --git a/src/frontend/mame/ui/custui.cpp b/src/frontend/mame/ui/custui.cpp index 22740412ff9..1db4a64ba13 100644 --- a/src/frontend/mame/ui/custui.cpp +++ b/src/frontend/mame/ui/custui.cpp @@ -110,99 +110,103 @@ void menu_custom_ui::menu_dismissed() // handle //------------------------------------------------- -void menu_custom_ui::handle(event const *ev) +bool menu_custom_ui::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + switch ((uintptr_t)ev->itemref) { - switch ((uintptr_t)ev->itemref) + case FONT_MENU: + if (ev->iptkey == IPT_UI_SELECT) + menu::stack_push<menu_font_ui>(ui(), container(), nullptr); + break; + case COLORS_MENU: + if (ev->iptkey == IPT_UI_SELECT) + menu::stack_push<menu_colors_ui>(ui(), container()); + break; + case LANGUAGE_MENU: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) { - case FONT_MENU: - if (ev->iptkey == IPT_UI_SELECT) - menu::stack_push<menu_font_ui>(ui(), container(), nullptr); - break; - case COLORS_MENU: - if (ev->iptkey == IPT_UI_SELECT) - menu::stack_push<menu_colors_ui>(ui(), container()); - break; - case LANGUAGE_MENU: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - if (ev->iptkey == IPT_UI_LEFT) - --m_currlang; - else if (ev->iptkey == IPT_UI_RIGHT) - ++m_currlang; - else - m_currlang = 0; - ev->item->set_subtext(m_languages[m_currlang]); - ev->item->set_flags(get_arrow_flags<std::size_t>(0, m_languages.size() - 1, m_currlang)); - } - else if (ev->iptkey == IPT_UI_SELECT) - { - // copying list of language names - expensive - menu::stack_push<menu_selector>( - ui(), container(), _("UI Language"), std::vector<std::string>(m_languages), m_currlang, - [this, item = ev->item] (int selection) - { - m_currlang = selection; - item->set_subtext(m_languages[selection]); - item->set_flags(get_arrow_flags<std::size_t>(0, m_languages.size() - 1, selection)); - }); - } - break; - case SYSNAMES_MENU: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - if (ev->iptkey == IPT_UI_LEFT) - --m_currsysnames; - else if (ev->iptkey == IPT_UI_RIGHT) - ++m_currsysnames; - else - m_currsysnames = 0; - ev->item->set_subtext(m_sysnames[m_currsysnames]); - ev->item->set_flags(get_arrow_flags<std::size_t>(0, m_sysnames.size() - 1, m_currsysnames)); - } - else if (ev->iptkey == IPT_UI_SELECT) - { - // copying list of file names - expensive - menu::stack_push<menu_selector>( - ui(), container(), _("System Names"), std::vector<std::string>(m_sysnames), m_currsysnames, - [this, item = ev->item] (int selection) - { - m_currsysnames = selection; - item->set_subtext(m_sysnames[selection]); - item->set_flags(get_arrow_flags<std::size_t>(0, m_sysnames.size() - 1, selection)); - }); - } - break; - case HIDE_MENU: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - if (ev->iptkey == IPT_UI_LEFT) - --m_currpanels; - else if (ev->iptkey == IPT_UI_RIGHT) - ++m_currpanels; - else - m_currpanels = 0; - ev->item->set_subtext(_(HIDE_STATUS[m_currpanels])); - ev->item->set_flags(get_arrow_flags<uint16_t>(0, HIDE_BOTH, m_currpanels)); - } - else if (ev->iptkey == IPT_UI_SELECT) - { - std::vector<std::string> s_sel(std::size(HIDE_STATUS)); - std::transform(std::begin(HIDE_STATUS), std::end(HIDE_STATUS), s_sel.begin(), [](auto &s) { return _(s); }); - menu::stack_push<menu_selector>( - ui(), container(), _("Show Side Panels"), std::move(s_sel), m_currpanels, - [this, item = ev->item] (int selection) - { - m_currpanels = selection; - item->set_subtext(_(HIDE_STATUS[selection])); - item->set_flags(get_arrow_flags<uint16_t>(0, HIDE_BOTH, selection)); - }); - } - break; + if (ev->iptkey == IPT_UI_LEFT) + --m_currlang; + else if (ev->iptkey == IPT_UI_RIGHT) + ++m_currlang; + else + m_currlang = 0; + ev->item->set_subtext(m_languages[m_currlang]); + ev->item->set_flags(get_arrow_flags<std::size_t>(0, m_languages.size() - 1, m_currlang)); + return true; + } + else if (ev->iptkey == IPT_UI_SELECT) + { + // copying list of language names - expensive + menu::stack_push<menu_selector>( + ui(), container(), _("UI Language"), std::vector<std::string>(m_languages), m_currlang, + [this, item = ev->item] (int selection) + { + m_currlang = selection; + item->set_subtext(m_languages[selection]); + item->set_flags(get_arrow_flags<std::size_t>(0, m_languages.size() - 1, selection)); + }); + } + break; + case SYSNAMES_MENU: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) + { + if (ev->iptkey == IPT_UI_LEFT) + --m_currsysnames; + else if (ev->iptkey == IPT_UI_RIGHT) + ++m_currsysnames; + else + m_currsysnames = 0; + ev->item->set_subtext(m_sysnames[m_currsysnames]); + ev->item->set_flags(get_arrow_flags<std::size_t>(0, m_sysnames.size() - 1, m_currsysnames)); + return true; + } + else if (ev->iptkey == IPT_UI_SELECT) + { + // copying list of file names - expensive + menu::stack_push<menu_selector>( + ui(), container(), _("System Names"), std::vector<std::string>(m_sysnames), m_currsysnames, + [this, item = ev->item] (int selection) + { + m_currsysnames = selection; + item->set_subtext(m_sysnames[selection]); + item->set_flags(get_arrow_flags<std::size_t>(0, m_sysnames.size() - 1, selection)); + }); } + break; + case HIDE_MENU: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) + { + if (ev->iptkey == IPT_UI_LEFT) + --m_currpanels; + else if (ev->iptkey == IPT_UI_RIGHT) + ++m_currpanels; + else + m_currpanels = 0; + ev->item->set_subtext(_(HIDE_STATUS[m_currpanels])); + ev->item->set_flags(get_arrow_flags<uint16_t>(0, HIDE_BOTH, m_currpanels)); + return true; + } + else if (ev->iptkey == IPT_UI_SELECT) + { + std::vector<std::string> s_sel(std::size(HIDE_STATUS)); + std::transform(std::begin(HIDE_STATUS), std::end(HIDE_STATUS), s_sel.begin(), [](auto &s) { return _(s); }); + menu::stack_push<menu_selector>( + ui(), container(), _("Show Side Panels"), std::move(s_sel), m_currpanels, + [this, item = ev->item] (int selection) + { + m_currpanels = selection; + item->set_subtext(_(HIDE_STATUS[selection])); + item->set_flags(get_arrow_flags<uint16_t>(0, HIDE_BOTH, selection)); + }); + } + break; } + + return false; } //------------------------------------------------- @@ -405,93 +409,97 @@ void menu_font_ui::menu_dismissed() // handle //------------------------------------------------- -void menu_font_ui::handle(event const *ev) +bool menu_font_ui::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + switch ((uintptr_t)ev->itemref) { - switch ((uintptr_t)ev->itemref) + case FONT_SIZE: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) { - case FONT_SIZE: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - m_changed = true; - if (ev->iptkey == IPT_UI_LEFT) - --m_font_size; - else if (ev->iptkey == IPT_UI_RIGHT) - ++m_font_size; - else - m_font_size = parse_number<int>(ui().options().get_entry(OPTION_FONT_ROWS)->default_value().c_str()); - ev->item->set_subtext(string_format("%d", m_font_size)); - ev->item->set_flags(get_arrow_flags(m_font_min, m_font_max, m_font_size)); - } - break; + m_changed = true; + if (ev->iptkey == IPT_UI_LEFT) + --m_font_size; + else if (ev->iptkey == IPT_UI_RIGHT) + ++m_font_size; + else + m_font_size = parse_number<int>(ui().options().get_entry(OPTION_FONT_ROWS)->default_value().c_str()); + ev->item->set_subtext(string_format("%d", m_font_size)); + ev->item->set_flags(get_arrow_flags(m_font_min, m_font_max, m_font_size)); + return true; + } + break; - case INFOS_SIZE: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - m_changed = true; - if (ev->iptkey == IPT_UI_LEFT) - m_info_size -= 0.05f; - else if (ev->iptkey == IPT_UI_RIGHT) - m_info_size += 0.05f; - else - m_info_size = parse_number<float>(ui().options().get_entry(OPTION_INFOS_SIZE)->default_value().c_str()); - ev->item->set_subtext(string_format("%.2f", m_info_size)); - ev->item->set_flags(get_arrow_flags(m_info_min, m_info_max, m_info_size)); - } - break; + case INFOS_SIZE: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) + { + m_changed = true; + if (ev->iptkey == IPT_UI_LEFT) + m_info_size -= 0.05f; + else if (ev->iptkey == IPT_UI_RIGHT) + m_info_size += 0.05f; + else + m_info_size = parse_number<float>(ui().options().get_entry(OPTION_INFOS_SIZE)->default_value().c_str()); + ev->item->set_subtext(string_format("%.2f", m_info_size)); + ev->item->set_flags(get_arrow_flags(m_info_min, m_info_max, m_info_size)); + return true; + } + break; - case MUI_FNT: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) - { - m_face_changed = true; - m_changed = true; - if (ev->iptkey == IPT_UI_LEFT) - --m_actual; - else if (ev->iptkey == IPT_UI_RIGHT) - ++m_actual; - else - m_actual = 0; - reset(reset_options::REMEMBER_REF); - } - else if (ev->iptkey == IPT_UI_SELECT) - { - std::vector<std::string> display_names; - display_names.reserve(m_fonts.size()); - for (auto const &font : m_fonts) - display_names.emplace_back(font.second); - menu::stack_push<menu_selector>( - ui(), container(), _("UI Font"), std::move(display_names), m_actual, - [this] (int selection) - { - m_face_changed = true; - m_changed = true; - m_actual = selection; - reset(reset_options::REMEMBER_REF); - }); - } - break; + case MUI_FNT: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_CLEAR)) + { + m_face_changed = true; + m_changed = true; + if (ev->iptkey == IPT_UI_LEFT) + --m_actual; + else if (ev->iptkey == IPT_UI_RIGHT) + ++m_actual; + else + m_actual = 0; + reset(reset_options::REMEMBER_REF); + } + else if (ev->iptkey == IPT_UI_SELECT) + { + std::vector<std::string> display_names; + display_names.reserve(m_fonts.size()); + for (auto const &font : m_fonts) + display_names.emplace_back(font.second); + menu::stack_push<menu_selector>( + ui(), container(), _("UI Font"), std::move(display_names), m_actual, + [this] (int selection) + { + m_face_changed = true; + m_changed = true; + m_actual = selection; + reset(reset_options::REMEMBER_REF); + }); + } + break; #ifdef UI_WINDOWS - case MUI_BOLD: - case MUI_ITALIC: - if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_SELECT) || (ev->iptkey == IPT_UI_CLEAR)) - { - m_face_changed = true; - m_changed = true; - bool &val = ((uintptr_t)ev->itemref == MUI_BOLD) ? m_bold : m_italic; - if (ev->iptkey == IPT_UI_CLEAR) - val = false; - else - val = !val; - ev->item->set_subtext(val ? _("On") : _("Off")); - ev->item->set_flags(val ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); - } - break; -#endif + case MUI_BOLD: + case MUI_ITALIC: + if ((ev->iptkey == IPT_UI_LEFT) || (ev->iptkey == IPT_UI_RIGHT) || (ev->iptkey == IPT_UI_SELECT) || (ev->iptkey == IPT_UI_CLEAR)) + { + m_face_changed = true; + m_changed = true; + bool &val = ((uintptr_t)ev->itemref == MUI_BOLD) ? m_bold : m_italic; + if (ev->iptkey == IPT_UI_CLEAR) + val = false; + else + val = !val; + ev->item->set_subtext(val ? _("On") : _("Off")); + ev->item->set_flags(val ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); + return true; } + break; +#endif } + + return false; } //------------------------------------------------- @@ -601,9 +609,8 @@ void menu_colors_ui::menu_dismissed() // handle //------------------------------------------------- -void menu_colors_ui::handle(event const *ev) +bool menu_colors_ui::handle(event const *ev) { - // process the menu if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT) { if ((uintptr_t)ev->itemref != MUI_RESTORE) @@ -613,8 +620,11 @@ void menu_colors_ui::handle(event const *ev) else { restore_colors(); + return true; } } + + return false; } //------------------------------------------------- @@ -813,81 +823,82 @@ menu_rgb_ui::menu_rgb_ui(mame_ui_manager &mui, render_container &container, rgb_ // handle //------------------------------------------------- -void menu_rgb_ui::handle(event const *ev) +bool menu_rgb_ui::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + switch (ev->iptkey) { - switch (ev->iptkey) + case IPT_UI_LEFT: + case IPT_UI_RIGHT: { - case IPT_UI_LEFT: - case IPT_UI_RIGHT: + bool changed = false; + int updated = (IPT_UI_LEFT == ev->iptkey) ? -1 : 1; + switch (uintptr_t(ev->itemref)) { - bool changed = false; - int updated = (IPT_UI_LEFT == ev->iptkey) ? -1 : 1; - switch (uintptr_t(ev->itemref)) + case RGB_ALPHA: + updated += m_color->a(); + if ((0 <= updated) && (255 >= updated)) { - case RGB_ALPHA: - updated += m_color->a(); - if ((0 <= updated) && (255 >= updated)) - { - m_color->set_a(updated); - changed = true; - } - break; - case RGB_RED: - updated += m_color->r(); - if ((0 <= updated) && (255 >= updated)) - { - m_color->set_r(updated); - changed = true; - } - break; - case RGB_GREEN: - updated += m_color->g(); - if ((0 <= updated) && (255 >= updated)) - { - m_color->set_g(updated); - changed = true; - } - break; - case RGB_BLUE: - updated += m_color->b(); - if ((0 <= updated) && (255 >= updated)) - { - m_color->set_b(updated); - changed = true; - } - break; + m_color->set_a(updated); + changed = true; } - if (changed) + break; + case RGB_RED: + updated += m_color->r(); + if ((0 <= updated) && (255 >= updated)) { - ev->item->set_subtext(string_format("%3u", updated)); - ev->item->set_flags(get_arrow_flags<uint8_t>(0, 255, updated)); + m_color->set_r(updated); + changed = true; } - } - break; - - case IPT_UI_SELECT: - if (uintptr_t(ev->itemref) == PALETTE_CHOOSE) - { - menu::stack_push<menu_palette_sel>(ui(), container(), *m_color); break; - } - [[fallthrough]]; - case IPT_SPECIAL: - switch (uintptr_t(ev->itemref)) - { - case RGB_ALPHA: - case RGB_RED: case RGB_GREEN: + updated += m_color->g(); + if ((0 <= updated) && (255 >= updated)) + { + m_color->set_g(updated); + changed = true; + } + break; case RGB_BLUE: - inkey_special(ev); + updated += m_color->b(); + if ((0 <= updated) && (255 >= updated)) + { + m_color->set_b(updated); + changed = true; + } break; } + if (changed) + { + ev->item->set_subtext(string_format("%3u", updated)); + ev->item->set_flags(get_arrow_flags<uint8_t>(0, 255, updated)); + return true; + } + } + break; + + case IPT_UI_SELECT: + if (uintptr_t(ev->itemref) == PALETTE_CHOOSE) + { + menu::stack_push<menu_palette_sel>(ui(), container(), *m_color); break; } + [[fallthrough]]; + case IPT_SPECIAL: + switch (uintptr_t(ev->itemref)) + { + case RGB_ALPHA: + case RGB_RED: + case RGB_GREEN: + case RGB_BLUE: + return inkey_special(ev); + } + break; } + + return false; } //------------------------------------------------- @@ -997,7 +1008,7 @@ void menu_rgb_ui::custom_render(void *selectedref, float top, float bottom, floa // handle special key event //------------------------------------------------- -void menu_rgb_ui::inkey_special(const event *menu_event) +bool menu_rgb_ui::inkey_special(const event *menu_event) { if (menu_event->iptkey == IPT_UI_SELECT) { @@ -1040,11 +1051,16 @@ void menu_rgb_ui::inkey_special(const event *menu_event) menu_event->item->set_subtext("_"); menu_event->item->set_flags(0); } + return true; } - else if (m_key_active) + else if (m_key_active && input_character(m_search, 3, menu_event->unichar, uchar_is_digit)) { - input_character(m_search, 3, menu_event->unichar, uchar_is_digit); menu_event->item->set_subtext(m_search + "_"); + return true; + } + else + { + return false; } } @@ -1074,9 +1090,8 @@ menu_palette_sel::menu_palette_sel(mame_ui_manager &mui, render_container &conta // handle //------------------------------------------------- -void menu_palette_sel::handle(event const *ev) +bool menu_palette_sel::handle(event const *ev) { - // process the menu if (ev && ev->itemref) { if (ev->iptkey == IPT_UI_SELECT) @@ -1086,6 +1101,8 @@ void menu_palette_sel::handle(event const *ev) stack_pop(); } } + + return false; } //------------------------------------------------- diff --git a/src/frontend/mame/ui/custui.h b/src/frontend/mame/ui/custui.h index c009a4eccf0..981546c64e3 100644 --- a/src/frontend/mame/ui/custui.h +++ b/src/frontend/mame/ui/custui.h @@ -16,6 +16,8 @@ #include "ui/menu.h" #include <functional> +#include <string> +#include <vector> namespace ui { @@ -34,7 +36,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void find_languages(); void find_sysnames(); @@ -63,7 +65,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void list(); @@ -126,7 +128,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; s_color_table m_color_table[MUI_RESTORE]; void restore_colors(); @@ -156,15 +158,14 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; - void inkey_special(const event *menu_event); + bool inkey_special(const event *menu_event); rgb_t *m_color; std::string m_search; bool m_key_active; int m_lock_ref; - std::string m_title; }; //------------------------------------------------- @@ -178,7 +179,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; static std::pair<const char *, const char *> const s_palette[]; rgb_t &m_original; diff --git a/src/frontend/mame/ui/datmenu.cpp b/src/frontend/mame/ui/datmenu.cpp index 47ed1f2ca8f..35deb7ff523 100644 --- a/src/frontend/mame/ui/datmenu.cpp +++ b/src/frontend/mame/ui/datmenu.cpp @@ -166,32 +166,36 @@ void menu_dats_view::add_info_text(text_layout &layout, std::string_view text, r // handle //------------------------------------------------- -void menu_dats_view::handle(event const *ev) +bool menu_dats_view::handle(event const *ev) { - if (ev) + if (!ev) + return false; + + switch (ev->iptkey) { - switch (ev->iptkey) + case IPT_UI_LEFT: + if (m_actual > 0) { - case IPT_UI_LEFT: - if (m_actual > 0) - { - m_actual--; - reset_layout(); - } - break; - - case IPT_UI_RIGHT: - if ((m_actual + 1) < m_items_list.size()) - { - m_actual++; - reset_layout(); - } - break; + m_actual--; + reset_layout(); + return true; + } + break; - default: - handle_key(ev->iptkey); + case IPT_UI_RIGHT: + if ((m_actual + 1) < m_items_list.size()) + { + m_actual++; + reset_layout(); + return true; } + break; + + default: + return handle_key(ev->iptkey); } + + return false; } //------------------------------------------------- diff --git a/src/frontend/mame/ui/datmenu.h b/src/frontend/mame/ui/datmenu.h index 680e4f0f37a..5c255c5fbff 100644 --- a/src/frontend/mame/ui/datmenu.h +++ b/src/frontend/mame/ui/datmenu.h @@ -60,7 +60,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void get_data(std::string &buffer); void get_data_sw(std::string &buffer); diff --git a/src/frontend/mame/ui/devctrl.h b/src/frontend/mame/ui/devctrl.h index ec9dc0d2928..ad89f726172 100644 --- a/src/frontend/mame/ui/devctrl.h +++ b/src/frontend/mame/ui/devctrl.h @@ -37,8 +37,8 @@ protected: int count() { return m_count; } int current_index(); - void previous(); - void next(); + bool previous(); + bool next(); std::string current_display_name(); uint32_t current_display_flags(); @@ -82,7 +82,7 @@ int menu_device_control<DeviceType>::current_index() //------------------------------------------------- template<class DeviceType> -void menu_device_control<DeviceType>::previous() +bool menu_device_control<DeviceType>::previous() { // left arrow - rotate left through devices if (m_device && (1 < m_count)) @@ -96,6 +96,7 @@ void menu_device_control<DeviceType>::previous() m_device = iter.byindex(index); reset(reset_options::REMEMBER_POSITION); } + return false; // triggers an item reset on changes anyway } @@ -104,7 +105,7 @@ void menu_device_control<DeviceType>::previous() //------------------------------------------------- template<class DeviceType> -void menu_device_control<DeviceType>::next() +bool menu_device_control<DeviceType>::next() { // right arrow - rotate right through cassette devices if (m_device && (1 < m_count)) @@ -118,6 +119,7 @@ void menu_device_control<DeviceType>::next() m_device = iter.byindex(index); reset(reset_options::REMEMBER_POSITION); } + return false; // triggers an item reset on changes anyway } diff --git a/src/frontend/mame/ui/devopt.cpp b/src/frontend/mame/ui/devopt.cpp index 9886c4e941d..0e9b44a25fc 100644 --- a/src/frontend/mame/ui/devopt.cpp +++ b/src/frontend/mame/ui/devopt.cpp @@ -359,10 +359,12 @@ void menu_device_config::populate() { } -void menu_device_config::handle(event const *ev) +bool menu_device_config::handle(event const *ev) { if (ev) - handle_key(ev->iptkey); + return handle_key(ev->iptkey); + else + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/devopt.h b/src/frontend/mame/ui/devopt.h index 05fef63240b..67500c81a41 100644 --- a/src/frontend/mame/ui/devopt.h +++ b/src/frontend/mame/ui/devopt.h @@ -29,7 +29,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; device_slot_interface::slot_option const *const m_option; bool const m_mounted; diff --git a/src/frontend/mame/ui/dirmenu.cpp b/src/frontend/mame/ui/dirmenu.cpp index a4000dc68b7..e597b973d32 100644 --- a/src/frontend/mame/ui/dirmenu.cpp +++ b/src/frontend/mame/ui/dirmenu.cpp @@ -9,11 +9,10 @@ *********************************************************************/ #include "emu.h" +#include "ui/dirmenu.h" #include "ui/ui.h" -#include "ui/dirmenu.h" #include "ui/utils.h" -#include "ui/optsmenu.h" #include "emuopts.h" #include "fileio.h" @@ -83,7 +82,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::string m_searchpath; int const m_ref; @@ -115,7 +114,7 @@ menu_remove_folder::menu_remove_folder(mame_ui_manager &mui, render_container &c // handle //------------------------------------------------- -void menu_remove_folder::handle(event const *ev) +bool menu_remove_folder::handle(event const *ev) { // process the menu if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT) @@ -132,13 +131,13 @@ void menu_remove_folder::handle(event const *ev) if (ui().options().exists(f_folders[m_ref].option)) ui().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); else if (machine().options().value(f_folders[m_ref].option) != tmppath) - { machine().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); - } reset_parent(reset_options::REMEMBER_REF); stack_pop(); } + + return false; } //------------------------------------------------- @@ -172,7 +171,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void update_search(); @@ -211,86 +210,92 @@ menu_add_change_folder::menu_add_change_folder(mame_ui_manager &mui, render_cont // handle //------------------------------------------------- -void menu_add_change_folder::handle(event const *ev) +bool menu_add_change_folder::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + if (ev->iptkey == IPT_UI_SELECT) { - if (ev->iptkey == IPT_UI_SELECT) - { - assert(ev->item); - menu_item const &pitem = *ev->item; + assert(ev->item); + menu_item const &pitem = *ev->item; - // go up to the parent path - if (pitem.text() == "..") - { - size_t const first_sep = m_current_path.find_first_of(PATH_SEPARATOR[0]); - size_t const last_sep = m_current_path.find_last_of(PATH_SEPARATOR[0]); - m_current_path.erase(last_sep + ((first_sep == last_sep) ? 1 : 0)); - } + // go up to the parent path + if (pitem.text() == "..") + { + size_t const first_sep = m_current_path.find_first_of(PATH_SEPARATOR[0]); + size_t const last_sep = m_current_path.find_last_of(PATH_SEPARATOR[0]); + m_current_path.erase(last_sep + ((first_sep == last_sep) ? 1 : 0)); + } + else + { + // if isn't a drive, appends the directory + if (pitem.subtext() != "[DRIVE]") + util::path_append(m_current_path, pitem.text()); else - { - // if isn't a drive, appends the directory - if (pitem.subtext() != "[DRIVE]") - util::path_append(m_current_path, pitem.text()); - else - m_current_path = pitem.text(); - } - - // reset the char buffer also in this case - m_search.clear(); - reset(reset_options::SELECT_FIRST); + m_current_path = pitem.text(); } - else if (ev->iptkey == IPT_UI_PASTE) + + // reset the char buffer also in this case + m_search.clear(); + reset(reset_options::SELECT_FIRST); + } + else if (ev->iptkey == IPT_UI_PASTE) + { + if (paste_text(m_search, uchar_is_printable)) { - if (paste_text(m_search, uchar_is_printable)) - update_search(); + update_search(); + return true; } - else if (ev->iptkey == IPT_SPECIAL) + } + else if (ev->iptkey == IPT_SPECIAL) + { + if (ev->unichar == 0x09) { - if (ev->unichar == 0x09) + // Tab key, save current path + std::string error_string; + if (!m_multipath) { - // Tab key, save current path - std::string error_string; - if (!m_multipath) - { - if (ui().options().exists(f_folders[m_ref].option)) - ui().options().set_value(f_folders[m_ref].option, m_current_path, OPTION_PRIORITY_CMDLINE); - else if (machine().options().value(f_folders[m_ref].option) != m_current_path) - machine().options().set_value(f_folders[m_ref].option, m_current_path, OPTION_PRIORITY_CMDLINE); - } - else + if (ui().options().exists(f_folders[m_ref].option)) + ui().options().set_value(f_folders[m_ref].option, m_current_path, OPTION_PRIORITY_CMDLINE); + else if (machine().options().value(f_folders[m_ref].option) != m_current_path) + machine().options().set_value(f_folders[m_ref].option, m_current_path, OPTION_PRIORITY_CMDLINE); + } + else + { + m_folders.push_back(m_current_path); + std::string tmppath; + for (int x = 0; x < m_folders.size(); ++x) { - m_folders.push_back(m_current_path); - std::string tmppath; - for (int x = 0; x < m_folders.size(); ++x) - { - tmppath.append(m_folders[x]); - if (x != m_folders.size() - 1) - tmppath.append(";"); - } - - if (ui().options().exists(f_folders[m_ref].option)) - ui().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); - else if (machine().options().value(f_folders[m_ref].option) != tmppath) - machine().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); + tmppath.append(m_folders[x]); + if (x != m_folders.size() - 1) + tmppath.append(";"); } - reset_parent(reset_options::SELECT_FIRST); - stack_pop(); - } - else if (input_character(m_search, ev->unichar, uchar_is_printable)) - { - // if it's any other key and we're not maxed out, update - update_search(); + if (ui().options().exists(f_folders[m_ref].option)) + ui().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); + else if (machine().options().value(f_folders[m_ref].option) != tmppath) + machine().options().set_value(f_folders[m_ref].option, tmppath, OPTION_PRIORITY_CMDLINE); } + + reset_parent(reset_options::SELECT_FIRST); + stack_pop(); } - else if (ev->iptkey == IPT_UI_CANCEL) + else if (input_character(m_search, ev->unichar, uchar_is_printable)) { - // reset the char buffer also in this case - m_search.clear(); + // if it's any other key and we're not maxed out, update + update_search(); + return true; } } + else if (ev->iptkey == IPT_UI_CANCEL) + { + // reset the char buffer also in this case + m_search.clear(); + return true; + } + + return false; } //------------------------------------------------- @@ -451,7 +456,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; bool is_multipath(std::string_view folder) const; @@ -480,9 +485,8 @@ bool menu_display_actual::is_multipath(std::string_view folder) const // handle //------------------------------------------------- -void menu_display_actual::handle(event const *ev) +bool menu_display_actual::handle(event const *ev) { - // process the menu if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT) { switch ((uintptr_t)ev->itemref) @@ -496,6 +500,8 @@ void menu_display_actual::handle(event const *ev) break; } } + + return false; } //------------------------------------------------- @@ -589,11 +595,12 @@ menu_directory::~menu_directory() // handle //------------------------------------------------- -void menu_directory::handle(event const *ev) +bool menu_directory::handle(event const *ev) { - // process the menu if (ev && ev->itemref && ev->iptkey == IPT_UI_SELECT) menu::stack_push<menu_display_actual>(ui(), container(), selected_index()); + + return false; } //------------------------------------------------- diff --git a/src/frontend/mame/ui/dirmenu.h b/src/frontend/mame/ui/dirmenu.h index 209fb7953fe..54eb155267e 100644 --- a/src/frontend/mame/ui/dirmenu.h +++ b/src/frontend/mame/ui/dirmenu.h @@ -32,7 +32,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/filecreate.cpp b/src/frontend/mame/ui/filecreate.cpp index cf55499ab00..4532f2bf747 100644 --- a/src/frontend/mame/ui/filecreate.cpp +++ b/src/frontend/mame/ui/filecreate.cpp @@ -53,11 +53,11 @@ CONFIRM SAVE AS MENU // ctor //------------------------------------------------- -menu_confirm_save_as::menu_confirm_save_as(mame_ui_manager &mui, render_container &container, bool *yes) +menu_confirm_save_as::menu_confirm_save_as(mame_ui_manager &mui, render_container &container, bool &yes) : menu(mui, container) + , m_yes(yes) { - m_yes = yes; - *m_yes = false; + m_yes = false; } @@ -86,17 +86,19 @@ void menu_confirm_save_as::populate() // handle - confirm save as menu //------------------------------------------------- -void menu_confirm_save_as::handle(event const *ev) +bool menu_confirm_save_as::handle(event const *ev) { // process the event if (ev && (ev->iptkey == IPT_UI_SELECT)) { if (ev->itemref == ITEMREF_YES) - *m_yes = true; + m_yes = true; // no matter what, pop out stack_pop(); } + + return false; } @@ -207,56 +209,64 @@ void menu_file_create::populate() // handle - file creator menu //------------------------------------------------- -void menu_file_create::handle(event const *ev) +bool menu_file_create::handle(event const *ev) { - // process the event - if (ev) + if (!ev) + return false; + + // handle selections + switch (ev->iptkey) { - // handle selections - switch (ev->iptkey) + case IPT_UI_SELECT: + if ((ev->itemref == ITEMREF_CREATE) || (ev->itemref == ITEMREF_NEW_IMAGE_NAME)) { - case IPT_UI_SELECT: - if ((ev->itemref == ITEMREF_CREATE) || (ev->itemref == ITEMREF_NEW_IMAGE_NAME)) + std::string tmp_file(m_filename); + if (tmp_file.find('.') != -1 && tmp_file.find('.') < tmp_file.length() - 1) { - std::string tmp_file(m_filename); - if (tmp_file.find('.') != -1 && tmp_file.find('.') < tmp_file.length() - 1) - { - m_current_file = m_filename; - m_ok = true; - stack_pop(); - } - else - { - ui().popup_time(1, "%s", _("Please enter a file extension too")); - } + m_current_file = m_filename; + m_ok = true; + stack_pop(); } - break; - - case IPT_UI_PASTE: - if (ev->itemref == ITEMREF_NEW_IMAGE_NAME) + else { - if (paste_text(m_filename, &osd_is_valid_filename_char)) - ev->item->set_subtext(m_filename + "_"); + ui().popup_time(1, "%s", _("Please enter a file extension too")); } - break; + } + break; - case IPT_SPECIAL: - if (ev->itemref == ITEMREF_NEW_IMAGE_NAME) + case IPT_UI_PASTE: + if (ev->itemref == ITEMREF_NEW_IMAGE_NAME) + { + if (paste_text(m_filename, &osd_is_valid_filename_char)) { - if (input_character(m_filename, ev->unichar, &osd_is_valid_filename_char)) - ev->item->set_subtext(m_filename + "_"); + ev->item->set_subtext(m_filename + "_"); + return true; } - break; + } + break; - case IPT_UI_CANCEL: - if ((ev->itemref == ITEMREF_NEW_IMAGE_NAME) && !m_filename.empty()) + case IPT_SPECIAL: + if (ev->itemref == ITEMREF_NEW_IMAGE_NAME) + { + if (input_character(m_filename, ev->unichar, &osd_is_valid_filename_char)) { - m_filename.clear(); - ev->item->set_subtext("_"); + ev->item->set_subtext(m_filename + "_"); + return true; } - break; } + break; + + case IPT_UI_CANCEL: + if ((ev->itemref == ITEMREF_NEW_IMAGE_NAME) && !m_filename.empty()) + { + m_filename.clear(); + ev->item->set_subtext("_"); + return true; + } + break; } + + return false; } @@ -308,7 +318,7 @@ void menu_select_format::populate() // handle //------------------------------------------------- -void menu_select_format::handle(event const *ev) +bool menu_select_format::handle(event const *ev) { // process the menu if (ev && ev->iptkey == IPT_UI_SELECT) @@ -316,6 +326,8 @@ void menu_select_format::handle(event const *ev) *m_result = (floppy_image_format_t *)ev->itemref; stack_pop(); } + + return false; } @@ -362,7 +374,7 @@ void menu_select_floppy_init::populate() // handle //------------------------------------------------- -void menu_select_floppy_init::handle(event const *ev) +bool menu_select_floppy_init::handle(event const *ev) { // process the menu if (ev && ev->iptkey == IPT_UI_SELECT) @@ -370,6 +382,8 @@ void menu_select_floppy_init::handle(event const *ev) *m_result = int(uintptr_t(ev->itemref)); stack_pop(); } + + return false; } diff --git a/src/frontend/mame/ui/filecreate.h b/src/frontend/mame/ui/filecreate.h index c4ef529168b..9537003a6f7 100644 --- a/src/frontend/mame/ui/filecreate.h +++ b/src/frontend/mame/ui/filecreate.h @@ -27,14 +27,14 @@ namespace ui { class menu_confirm_save_as : public menu { public: - menu_confirm_save_as(mame_ui_manager &mui, render_container &container, bool *yes); + menu_confirm_save_as(mame_ui_manager &mui, render_container &container, bool &yes); virtual ~menu_confirm_save_as() override; private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; - bool *m_yes; + bool &m_yes; }; @@ -53,7 +53,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; bool & m_ok; device_image_interface * m_image; @@ -74,7 +74,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // internal state std::vector<const floppy_image_format_t *> m_formats; @@ -93,7 +93,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // internal state std::vector<std::reference_wrapper<const floppy_image_device::fs_info>> m_fs; diff --git a/src/frontend/mame/ui/filemngr.cpp b/src/frontend/mame/ui/filemngr.cpp index 81540b568b0..47cfd7be4fa 100644 --- a/src/frontend/mame/ui/filemngr.cpp +++ b/src/frontend/mame/ui/filemngr.cpp @@ -171,31 +171,32 @@ void menu_file_manager::populate() // handle //------------------------------------------------- -void menu_file_manager::handle(event const *ev) +bool menu_file_manager::handle(event const *ev) { - // process the menu - if (ev && ev->itemref && (ev->iptkey == IPT_UI_SELECT)) + if (!ev || !ev->itemref || (ev->iptkey != IPT_UI_SELECT)) + return false; + + if ((uintptr_t)ev->itemref == 1) { - if ((uintptr_t)ev->itemref == 1) - { - machine().schedule_hard_reset(); - } - else + machine().schedule_hard_reset(); + } + else + { + selected_device = (device_image_interface *) ev->itemref; + if (selected_device) { - selected_device = (device_image_interface *) ev->itemref; - if (selected_device) - { - floppy_image_device *floppy_device = dynamic_cast<floppy_image_device *>(selected_device); - if (floppy_device) - menu::stack_push<menu_control_floppy_image>(ui(), container(), *floppy_device); - else - menu::stack_push<menu_control_device_image>(ui(), container(), *selected_device); - - // reset the existing menu - reset(reset_options::REMEMBER_POSITION); - } + floppy_image_device *floppy_device = dynamic_cast<floppy_image_device *>(selected_device); + if (floppy_device) + menu::stack_push<menu_control_floppy_image>(ui(), container(), *floppy_device); + else + menu::stack_push<menu_control_device_image>(ui(), container(), *selected_device); + + // reset the existing menu + reset(reset_options::REMEMBER_POSITION); } } + + return false; } // force file manager menu diff --git a/src/frontend/mame/ui/filemngr.h b/src/frontend/mame/ui/filemngr.h index a2368e5a959..2c0be45449c 100644 --- a/src/frontend/mame/ui/filemngr.h +++ b/src/frontend/mame/ui/filemngr.h @@ -35,7 +35,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool 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 e12beadb8eb..f43ddeac007 100644 --- a/src/frontend/mame/ui/filesel.cpp +++ b/src/frontend/mame/ui/filesel.cpp @@ -446,40 +446,49 @@ void menu_file_selector::populate() // handle //------------------------------------------------- -void menu_file_selector::handle(event const *ev) +bool menu_file_selector::handle(event const *ev) { - // process the menu - if (ev) + if (!ev) + return false; + + if (ev->iptkey == IPT_SPECIAL) { - if (ev->iptkey == IPT_SPECIAL) + // if it's any other key and we're not maxed out, update + if (input_character(m_filename, ev->unichar, uchar_is_printable)) { - // if it's any other key and we're not maxed out, update - if (input_character(m_filename, ev->unichar, uchar_is_printable)) - update_search(); + update_search(); + return true; } - else if (ev->iptkey == IPT_UI_PASTE) + } + else if (ev->iptkey == IPT_UI_PASTE) + { + if (paste_text(m_filename, uchar_is_printable)) { - if (paste_text(m_filename, uchar_is_printable)) - update_search(); + update_search(); + return true; } - else if (ev->iptkey == IPT_UI_CANCEL) - { - // reset the char buffer also in this case - if (!m_filename.empty()) - { - m_filename.clear(); - ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename); - } - } - else if (ev->itemref && (ev->iptkey == IPT_UI_SELECT)) + } + else if (ev->iptkey == IPT_UI_CANCEL) + { + // reset the char buffer also in this case + if (!m_filename.empty()) { - // handle selections - select_item(*reinterpret_cast<file_selector_entry const *>(ev->itemref)); - - // reset the char buffer when pressing IPT_UI_SELECT m_filename.clear(); + ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename); + return true; } } + else if (ev->itemref && (ev->iptkey == IPT_UI_SELECT)) + { + // handle selections + select_item(*reinterpret_cast<file_selector_entry const *>(ev->itemref)); + + // reset the char buffer when pressing IPT_UI_SELECT + m_filename.clear(); + return true; + } + + return false; } @@ -529,14 +538,15 @@ void menu_select_rw::populate() // handle //------------------------------------------------- -void menu_select_rw::handle(event const *ev) +bool menu_select_rw::handle(event const *ev) { - // process the menu if (ev && ev->iptkey == IPT_UI_SELECT) { m_result = result_from_itemref(ev->itemref); stack_pop(); } + + return false; } diff --git a/src/frontend/mame/ui/filesel.h b/src/frontend/mame/ui/filesel.h index f8968f798c9..8bef06e53ca 100644 --- a/src/frontend/mame/ui/filesel.h +++ b/src/frontend/mame/ui/filesel.h @@ -84,7 +84,7 @@ private: std::string m_filename; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // methods file_selector_entry &append_entry(file_selector_entry_type entry_type, const std::string &entry_basename, const std::string &entry_fullpath); @@ -121,7 +121,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // internal state bool m_can_in_place; diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp index 174b8bab9e6..053da006a43 100644 --- a/src/frontend/mame/ui/imgcntrl.cpp +++ b/src/frontend/mame/ui/imgcntrl.cpp @@ -12,20 +12,22 @@ #include "ui/imgcntrl.h" -#include "ui/ui.h" -#include "ui/filesel.h" #include "ui/filecreate.h" +#include "ui/filesel.h" #include "ui/swlist.h" +#include "ui/ui.h" #include "audit.h" #include "drivenum.h" #include "emuopts.h" #include "image.h" #include "softlist_dev.h" -#include "zippath.h" + +#include "util/zippath.h" namespace ui { + /*************************************************************************** IMPLEMENTATION ***************************************************************************/ @@ -194,7 +196,7 @@ void menu_control_device_image::populate() // handle //------------------------------------------------- -void menu_control_device_image::handle(event const *ev) +bool menu_control_device_image::handle(event const *ev) { throw emu_fatalerror("menu_control_device_image::handle: Shouldn't get here!"); } @@ -338,7 +340,7 @@ void menu_control_device_image::menu_activated() { if (need_confirm) { - menu::stack_push<menu_confirm_save_as>(ui(), container(), &m_create_confirmed); + menu::stack_push<menu_confirm_save_as>(ui(), container(), m_create_confirmed); m_state = CREATE_CONFIRM; } else diff --git a/src/frontend/mame/ui/imgcntrl.h b/src/frontend/mame/ui/imgcntrl.h index 80b4548686a..22911f70141 100644 --- a/src/frontend/mame/ui/imgcntrl.h +++ b/src/frontend/mame/ui/imgcntrl.h @@ -56,7 +56,7 @@ protected: // methods virtual void menu_activated() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; virtual void hook_load(const std::string &filename); private: diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp index 32575133a24..1a19fd10c49 100644 --- a/src/frontend/mame/ui/info.cpp +++ b/src/frontend/mame/ui/info.cpp @@ -552,10 +552,9 @@ void menu_game_info::populate() { } -void menu_game_info::handle(event const *ev) +bool menu_game_info::handle(event const *ev) { - if (ev) - handle_key(ev->iptkey); + return ev && handle_key(ev->iptkey); } @@ -617,10 +616,9 @@ void menu_warn_info::populate() { } -void menu_warn_info::handle(event const *ev) +bool menu_warn_info::handle(event const *ev) { - if (ev) - handle_key(ev->iptkey); + return ev && handle_key(ev->iptkey); } @@ -648,8 +646,9 @@ void menu_image_info::populate() image_info(&image); } -void menu_image_info::handle(event const *ev) +bool menu_image_info::handle(event const *ev) { + return false; } diff --git a/src/frontend/mame/ui/info.h b/src/frontend/mame/ui/info.h index d36c476c7b5..4d5e5e434b7 100644 --- a/src/frontend/mame/ui/info.h +++ b/src/frontend/mame/ui/info.h @@ -101,7 +101,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; @@ -116,7 +116,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; @@ -131,7 +131,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool 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 018c3bc9b61..6aa4826e241 100644 --- a/src/frontend/mame/ui/info_pty.cpp +++ b/src/frontend/mame/ui/info_pty.cpp @@ -39,8 +39,9 @@ void menu_pty_info::populate() } } -void menu_pty_info::handle(event const *ev) +bool menu_pty_info::handle(event const *ev) { + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/info_pty.h b/src/frontend/mame/ui/info_pty.h index af384a5a92d..203209fddc4 100644 --- a/src/frontend/mame/ui/info_pty.h +++ b/src/frontend/mame/ui/info_pty.h @@ -25,7 +25,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/inputdevices.cpp b/src/frontend/mame/ui/inputdevices.cpp index 4890b1ac724..0fe8de2a1c0 100644 --- a/src/frontend/mame/ui/inputdevices.cpp +++ b/src/frontend/mame/ui/inputdevices.cpp @@ -139,7 +139,7 @@ private: 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 + virtual bool handle(event const *ev) override { // FIXME: hacky, depending on first item being "copy ID", but need a better model for item reference values if (ev && ev->item && (IPT_UI_SELECT == ev->iptkey) && (&item(0) == ev->item)) @@ -150,15 +150,23 @@ private: machine().popmessage(_("menu-inputdev", "Error copying device ID to clipboard")); } + bool updated = false; for (int i = 0; item_count() > i; ++i) { void *const ref(item(i).ref()); if (ref) { input_device_item &input = *reinterpret_cast<input_device_item *>(ref); - item(i).set_subtext(format_value(input)); + std::string value(format_value(input)); + if (item(i).subtext() != value) + { + item(i).set_subtext(std::move(value)); + updated = true; + } } } + + return updated; } static std::string format_value(input_device_item &input) @@ -233,68 +241,70 @@ void menu_input_devices::populate() } -void menu_input_devices::handle(event const *ev) +bool menu_input_devices::handle(event const *ev) { - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + input_device &dev = *reinterpret_cast<input_device *>(ev->itemref); + switch (ev->iptkey) { - input_device &dev = *reinterpret_cast<input_device *>(ev->itemref); - switch (ev->iptkey) - { - case IPT_UI_SELECT: - stack_push<menu_input_device>(ui(), container(), dev); - break; + case IPT_UI_SELECT: + stack_push<menu_input_device>(ui(), container(), dev); + break; - case IPT_UI_PREV_GROUP: + case IPT_UI_PREV_GROUP: + { + auto group = dev.devclass(); + bool found_break = false; + int target = 0; + for (auto i = selected_index(); 0 < i--; ) { - auto group = dev.devclass(); - bool found_break = false; - int target = 0; - for (auto i = selected_index(); 0 < i--; ) + input_device *const candidate = reinterpret_cast<input_device *>(item(i).ref()); + if (candidate) { - input_device *const candidate = reinterpret_cast<input_device *>(item(i).ref()); - if (candidate) + if (candidate->devclass() == group) + { + target = i; + } + else if (!found_break) { - if (candidate->devclass() == group) - { - target = i; - } - else if (!found_break) - { - group = candidate->devclass(); - found_break = true; - target = i; - } - else - { - set_selected_index(target); - break; - } + group = candidate->devclass(); + found_break = true; + target = i; } - if (!i && found_break) + else { set_selected_index(target); - break; + return true; } } + if (!i && found_break) + { + set_selected_index(target); + return true; + } } - break; + } + break; - case IPT_UI_NEXT_GROUP: + case IPT_UI_NEXT_GROUP: + { + auto const group = dev.devclass(); + for (auto i = selected_index(); item_count() > ++i; ) { - auto const group = dev.devclass(); - for (auto i = selected_index(); item_count() > ++i; ) + input_device *const candidate = reinterpret_cast<input_device *>(item(i).ref()); + if (candidate && (candidate->devclass() != group)) { - input_device *const candidate = reinterpret_cast<input_device *>(item(i).ref()); - if (candidate && (candidate->devclass() != group)) - { - set_selected_index(i); - break; - } + set_selected_index(i); + return true; } } - break; } + break; } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/inputdevices.h b/src/frontend/mame/ui/inputdevices.h index 39d2afda4e5..3d4bfb51e4e 100644 --- a/src/frontend/mame/ui/inputdevices.h +++ b/src/frontend/mame/ui/inputdevices.h @@ -26,7 +26,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/inputmap.cpp b/src/frontend/mame/ui/inputmap.cpp index 4fa6ffab25b..b5b56b6e1fb 100644 --- a/src/frontend/mame/ui/inputmap.cpp +++ b/src/frontend/mame/ui/inputmap.cpp @@ -46,9 +46,8 @@ void menu_input_groups::populate() item_append(menu_item_type::SEPARATOR); } -void menu_input_groups::handle(event const *ev) +bool menu_input_groups::handle(event const *ev) { - // process the menu if (ev && (ev->iptkey == IPT_UI_SELECT)) { menu::stack_push<menu_input_general>( @@ -57,6 +56,8 @@ void menu_input_groups::handle(event const *ev) int(uintptr_t(ev->itemref) - 1), util::string_format(_("Input Assignments (%1$s)"), ev->item->text())); } + + return false; } @@ -377,10 +378,11 @@ void menu_input::custom_render(void *selectedref, float top, float bottom, float } } -void menu_input::handle(event const *ev) +bool menu_input::handle(event const *ev) { input_item_data *seqchangeditem = nullptr; bool invalidate = false; + bool redraw = false; // process the menu if (pollingitem) @@ -421,6 +423,11 @@ void menu_input::handle(event const *ev) seq_poll.reset(); machine().ui_input().reset(); } + else + { + // always redraw to ensure it updates as soon as possible in response to changes + redraw = true; + } } else if (ev && ev->itemref) { @@ -516,6 +523,7 @@ void menu_input::handle(event const *ev) } record_next = false; lastitem = &item; + redraw = true; } // flip between set and append @@ -531,6 +539,7 @@ void menu_input::handle(event const *ev) { record_next = !record_next; } + redraw = true; } } @@ -546,6 +555,8 @@ void menu_input::handle(event const *ev) // if the menu is invalidated, clear it now if (invalidate) reset(reset_options::REMEMBER_POSITION); + + return redraw && !invalidate; } diff --git a/src/frontend/mame/ui/inputmap.h b/src/frontend/mame/ui/inputmap.h index d512b670345..e5947a9b649 100644 --- a/src/frontend/mame/ui/inputmap.h +++ b/src/frontend/mame/ui/inputmap.h @@ -29,7 +29,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; @@ -84,7 +84,7 @@ private: osd_ticks_t modified_ticks; input_seq starting_seq; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; virtual void update_input(input_item_data &seqchangeditem) = 0; }; diff --git a/src/frontend/mame/ui/inputopts.cpp b/src/frontend/mame/ui/inputopts.cpp index e4802e8de8f..48db7698e71 100644 --- a/src/frontend/mame/ui/inputopts.cpp +++ b/src/frontend/mame/ui/inputopts.cpp @@ -111,7 +111,7 @@ void menu_input_options::populate() } -void menu_input_options::handle(event const *ev) +bool menu_input_options::handle(event const *ev) { if (ev && (IPT_UI_SELECT == ev->iptkey)) { @@ -137,6 +137,8 @@ void menu_input_options::handle(event const *ev) break; } } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/inputopts.h b/src/frontend/mame/ui/inputopts.h index 7cff7713537..bf6afebabf5 100644 --- a/src/frontend/mame/ui/inputopts.h +++ b/src/frontend/mame/ui/inputopts.h @@ -29,7 +29,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/inputtoggle.cpp b/src/frontend/mame/ui/inputtoggle.cpp index 172ae16b141..7a307c01c66 100644 --- a/src/frontend/mame/ui/inputtoggle.cpp +++ b/src/frontend/mame/ui/inputtoggle.cpp @@ -110,109 +110,111 @@ void menu_input_toggles::populate() } -void menu_input_toggles::handle(event const *ev) +bool menu_input_toggles::handle(event const *ev) { - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + auto const ref = reinterpret_cast<std::reference_wrapper<ioport_field> *>(ev->itemref); + ioport_field &field = ref->get(); + bool invalidate = false; + switch (ev->iptkey) { - auto const ref = reinterpret_cast<std::reference_wrapper<ioport_field> *>(ev->itemref); - ioport_field &field = ref->get(); - bool invalidate = false; - switch (ev->iptkey) + case IPT_UI_SELECT: // toggle regular items, cycle multi-value items + if (field.settings().empty()) + field.live().value ^= field.mask(); + else + field.select_next_setting(); + invalidate = true; + break; + + case IPT_UI_CLEAR: // set to default + if (field.defvalue() != field.live().value) { - case IPT_UI_SELECT: // toggle regular items, cycle multi-value items - if (field.settings().empty()) - field.live().value ^= field.mask(); - else - field.select_next_setting(); + field.live().value = field.defvalue(); invalidate = true; - break; - - case IPT_UI_CLEAR: // set to default - if (field.defvalue() != field.live().value) - { - field.live().value = field.defvalue(); - invalidate = true; - } - break; - - case IPT_UI_LEFT: // toggle or select previous setting - if (field.settings().empty()) - field.live().value ^= field.mask(); - else - field.select_previous_setting(); - invalidate = true; - break; - - case IPT_UI_RIGHT: // toggle or select next setting - if (field.settings().empty()) - field.live().value ^= field.mask(); - else - field.select_next_setting(); - invalidate = true; - break; - - case IPT_UI_PREV_GROUP: // previous device if any + } + break; + + case IPT_UI_LEFT: // toggle or select previous setting + if (field.settings().empty()) + field.live().value ^= field.mask(); + else + field.select_previous_setting(); + invalidate = true; + break; + + case IPT_UI_RIGHT: // toggle or select next setting + if (field.settings().empty()) + field.live().value ^= field.mask(); + else + field.select_next_setting(); + invalidate = true; + break; + + case IPT_UI_PREV_GROUP: // previous device if any + { + auto current = std::distance(m_fields.data(), ref); + device_t const *dev = &field.device(); + bool found_break = false; + void *candidate = nullptr; + while (0 < current) { - auto current = std::distance(m_fields.data(), ref); - device_t const *dev = &field.device(); - bool found_break = false; - void *candidate = nullptr; - while (0 < current) + if (!found_break) { - if (!found_break) + if (m_fields[--current].get().enabled()) { - if (m_fields[--current].get().enabled()) + device_t const *prev = &m_fields[current].get().device(); + if (prev != dev) { - device_t const *prev = &m_fields[current].get().device(); - if (prev != dev) - { - dev = prev; - found_break = true; - candidate = &m_fields[current]; - } + dev = prev; + found_break = true; + candidate = &m_fields[current]; } } - else if (&m_fields[--current].get().device() != dev) - { - set_selection(candidate); - set_top_line(selected_index() - 1); - break; - } - else if (m_fields[current].get().enabled()) - { - candidate = &m_fields[current]; - } - if (found_break && !current) - { - set_selection(candidate); - set_top_line(selected_index() - 1); - break; - } + } + else if (&m_fields[--current].get().device() != dev) + { + set_selection(candidate); + set_top_line(selected_index() - 1); + return true; + } + else if (m_fields[current].get().enabled()) + { + candidate = &m_fields[current]; + } + if (found_break && !current) + { + set_selection(candidate); + set_top_line(selected_index() - 1); + return true; } } - break; + } + break; - case IPT_UI_NEXT_GROUP: // next device if any + case IPT_UI_NEXT_GROUP: // next device if any + { + auto current = std::distance(m_fields.data(), ref); + device_t const *const dev = &field.device(); + while (m_fields.size() > ++current) { - auto current = std::distance(m_fields.data(), ref); - device_t const *const dev = &field.device(); - while (m_fields.size() > ++current) + if (m_fields[current].get().enabled() && (&m_fields[current].get().device() != dev)) { - if (m_fields[current].get().enabled() && (&m_fields[current].get().device() != dev)) - { - set_selection(&m_fields[current]); - set_top_line(selected_index() - 1); - break; - } + set_selection(&m_fields[current]); + set_top_line(selected_index() - 1); + return true; } } - break; } - - // changing value can enable or disable other fields - if (invalidate) - reset(reset_options::REMEMBER_REF); + break; } + + // changing value can enable or disable other fields + if (invalidate) + reset(reset_options::REMEMBER_REF); + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/inputtoggle.h b/src/frontend/mame/ui/inputtoggle.h index b4d48908d96..676be71e58d 100644 --- a/src/frontend/mame/ui/inputtoggle.h +++ b/src/frontend/mame/ui/inputtoggle.h @@ -32,7 +32,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool 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 931ff96f046..9eaeb5c94ee 100644 --- a/src/frontend/mame/ui/keyboard.cpp +++ b/src/frontend/mame/ui/keyboard.cpp @@ -71,47 +71,51 @@ menu_keyboard_mode::~menu_keyboard_mode() { } -void menu_keyboard_mode::handle(event const *ev) +bool menu_keyboard_mode::handle(event const *ev) { - if (ev && uintptr_t(ev->itemref)) + if (!ev || !uintptr_t(ev->itemref)) + return false; + + natural_keyboard &natkbd(machine().natkeyboard()); + uintptr_t const ref(uintptr_t(ev->itemref)); + bool left(IPT_UI_LEFT == ev->iptkey); + bool right(IPT_UI_RIGHT == ev->iptkey); + if (ITEM_KBMODE == ref) { - natural_keyboard &natkbd(machine().natkeyboard()); - uintptr_t const ref(uintptr_t(ev->itemref)); - bool left(IPT_UI_LEFT == ev->iptkey); - bool right(IPT_UI_RIGHT == ev->iptkey); - if (ITEM_KBMODE == ref) + if (IPT_UI_SELECT == ev->iptkey) { - if (IPT_UI_SELECT == ev->iptkey) - { - left = natkbd.in_use(); - right = !left; - } - if ((left || right) && (natkbd.in_use() != right)) - { - natkbd.set_in_use(right); - ev->item->set_subtext(right ? _("menu-keyboard", "Natural") : _("menu-keyboard", "Emulated")); - ev->item->set_flags(right ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); - } + left = natkbd.in_use(); + right = !left; } - else if (ITEM_KBDEV_FIRST <= ref) + if ((left || right) && (natkbd.in_use() != right)) { - auto const kbdno(ref - ITEM_KBDEV_FIRST); - if (IPT_UI_SELECT == ev->iptkey) - { - left = natkbd.keyboard_enabled(kbdno); - right = !left; - } - if ((left || right) && (natkbd.keyboard_enabled(kbdno) != right)) - { - if (right) - natkbd.enable_keyboard(kbdno); - else - natkbd.disable_keyboard(kbdno); - ev->item->set_subtext(right ? _("Enabled") : _("Disabled")); - ev->item->set_flags(right ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); - } + natkbd.set_in_use(right); + ev->item->set_subtext(right ? _("menu-keyboard", "Natural") : _("menu-keyboard", "Emulated")); + ev->item->set_flags(right ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); + return true; } } + else if (ITEM_KBDEV_FIRST <= ref) + { + auto const kbdno(ref - ITEM_KBDEV_FIRST); + if (IPT_UI_SELECT == ev->iptkey) + { + left = natkbd.keyboard_enabled(kbdno); + right = !left; + } + if ((left || right) && (natkbd.keyboard_enabled(kbdno) != right)) + { + if (right) + natkbd.enable_keyboard(kbdno); + else + natkbd.disable_keyboard(kbdno); + ev->item->set_subtext(right ? _("Enabled") : _("Disabled")); + ev->item->set_flags(right ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); + return true; + } + } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/keyboard.h b/src/frontend/mame/ui/keyboard.h index 478d97a5a11..dd51e6c9d1e 100644 --- a/src/frontend/mame/ui/keyboard.h +++ b/src/frontend/mame/ui/keyboard.h @@ -28,7 +28,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp index 7d53266e65b..240ac30f1ee 100644 --- a/src/frontend/mame/ui/mainmenu.cpp +++ b/src/frontend/mame/ui/mainmenu.cpp @@ -206,7 +206,7 @@ void menu_main::populate() handle - handle main menu events -------------------------------------------------*/ -void menu_main::handle(event const *ev) +bool menu_main::handle(event const *ev) { // process the menu if (ev && (ev->iptkey == IPT_UI_SELECT)) @@ -321,12 +321,14 @@ void menu_main::handle(event const *ev) case DISMISS: stack_pop(); - return; + break; default: fatalerror("ui::menu_main::handle - unknown reference\n"); } } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/mainmenu.h b/src/frontend/mame/ui/mainmenu.h index de596716da6..d34da5e009e 100644 --- a/src/frontend/mame/ui/mainmenu.h +++ b/src/frontend/mame/ui/mainmenu.h @@ -29,7 +29,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool 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 c945b3f0297..f3273752299 100644 --- a/src/frontend/mame/ui/menu.cpp +++ b/src/frontend/mame/ui/menu.cpp @@ -195,8 +195,7 @@ uint32_t menu::global_state::ui_handler(render_container &container) // update the menu state m_hide = false; - if (m_stack) - m_stack->do_handle(); + bool need_update = m_stack && m_stack->do_handle(); // clear up anything pending being released clear_free_list(); @@ -216,10 +215,10 @@ uint32_t menu::global_state::ui_handler(render_container &container) m_stack->menu_deactivated(); } } - return UI_HANDLER_CANCEL; + return mame_ui_manager::HANDLER_CANCEL; } - return 0; + return need_update ? mame_ui_manager::HANDLER_UPDATE : 0; } @@ -392,7 +391,7 @@ void menu::set_custom_space(float top, float bottom) // and returning any interesting events //------------------------------------------------- -const menu::event *menu::process() +std::pair<const menu::event *, bool> menu::process() { // reset the event m_event.iptkey = IPT_INVALID; @@ -414,6 +413,8 @@ const menu::event *menu::process() container().add_rect(0.0F, 0.0F, 1.0F, 1.0F, rgb_t(114, 0, 0, 0), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); // draw the menu proper + // FIXME: this should happen after processing events to fix the egregious latency + // The main thing preventing this is that mouse handling is mixed up with drawing draw(m_process_flags); // process input @@ -432,11 +433,11 @@ const menu::event *menu::process() { m_event.itemref = get_selection_ref(); m_event.item = &m_items[m_selected]; - return &m_event; + return std::make_pair(&m_event, false); } else { - return nullptr; + return std::make_pair(nullptr, false); } } @@ -1250,8 +1251,10 @@ void menu::validate_selection(int scandir) MENU STACK MANAGEMENT ***************************************************************************/ -void menu::do_handle() +bool menu::do_handle() { + bool need_update = false; + // let OSD do its thing machine().osd().check_osd_inputs(); @@ -1265,6 +1268,7 @@ void menu::do_handle() m_last_size = uisize; m_last_aspect = aspect; recompute_metrics(uisize.first, uisize.second, aspect); + need_update = true; } if (m_items.empty()) @@ -1278,6 +1282,7 @@ void menu::do_handle() // let implementation add other items populate(); + need_update = true; } catch (...) { @@ -1287,7 +1292,11 @@ void menu::do_handle() } m_rebuilding = false; } - handle(process()); + + auto [eventptr, changed] = process(); + need_update = need_update || changed; + need_update = handle(eventptr) || need_update; + return need_update; } diff --git a/src/frontend/mame/ui/menu.h b/src/frontend/mame/ui/menu.h index 16223ebebd8..eeeb7ae6eb3 100644 --- a/src/frontend/mame/ui/menu.h +++ b/src/frontend/mame/ui/menu.h @@ -102,7 +102,7 @@ public: // Used by sliders void validate_selection(int scandir); - void do_handle(); + bool do_handle(); protected: using bitmap_ptr = widgets_manager::bitmap_ptr; @@ -418,7 +418,7 @@ private: }; // process a menu, drawing it and returning any interesting events - const event *process(); + std::pair<const event *, bool> process(); virtual void draw(uint32_t flags); // request the specific handling of the game selection main menu @@ -428,7 +428,7 @@ private: virtual void populate() = 0; // to be implemented in derived classes - virtual void handle(event const *ev) = 0; + virtual bool handle(event const *ev) = 0; void extra_text_draw_box(float origx1, float origx2, float origy, float yspan, std::string_view text, int direction); diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp index 9839d59a966..6a41da2f070 100644 --- a/src/frontend/mame/ui/miscmenu.cpp +++ b/src/frontend/mame/ui/miscmenu.cpp @@ -90,57 +90,64 @@ menu_bios_selection::~menu_bios_selection() menu_bios_selection - menu that -------------------------------------------------*/ -void menu_bios_selection::handle(event const *ev) +bool menu_bios_selection::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) - { - if ((uintptr_t)ev->itemref == 1 && ev->iptkey == IPT_UI_SELECT) - machine().schedule_hard_reset(); - else - { - device_t *dev = (device_t *)ev->itemref; - int bios_val = 0; - - switch (ev->iptkey) - { - // reset to default - case IPT_UI_SELECT: - bios_val = dev->default_bios(); - break; + if (!ev || !ev->itemref) + return false; - // previous/next bios setting - case IPT_UI_LEFT: case IPT_UI_RIGHT: - { - int const cnt = ([bioses = romload::entries(dev->rom_region()).get_system_bioses()] () { return std::distance(bioses.begin(), bioses.end()); })(); - bios_val = dev->system_bios() + ((ev->iptkey == IPT_UI_LEFT) ? -1 : +1); + if ((uintptr_t)ev->itemref == 1 && ev->iptkey == IPT_UI_SELECT) + { + machine().schedule_hard_reset(); + return false; + } - // wrap - if (bios_val < 1) - bios_val = cnt; - if (bios_val > cnt) - bios_val = 1; + device_t *const dev = (device_t *)ev->itemref; + int bios_val = 0; - break; - } + switch (ev->iptkey) + { + // reset to default + case IPT_UI_CLEAR: + bios_val = dev->default_bios(); + break; + + // previous/next BIOS setting + case IPT_UI_SELECT: + case IPT_UI_LEFT: + case IPT_UI_RIGHT: + { + int const cnt = ([bioses = romload::entries(dev->rom_region()).get_system_bioses()] () { return std::distance(bioses.begin(), bioses.end()); })(); + bios_val = dev->system_bios() + ((ev->iptkey == IPT_UI_LEFT) ? -1 : +1); + + // wrap + if (bios_val < 1) + bios_val = cnt; + if (bios_val > cnt) + bios_val = 1; + } + break; - default: - break; - } + default: + break; + } - if (bios_val > 0) - { - dev->set_system_bios(bios_val); - if (strcmp(dev->tag(),":")==0) { - machine().options().set_value("bios", bios_val-1, OPTION_PRIORITY_CMDLINE); - } else { - const char *slot_option_name = dev->owner()->tag() + 1; - machine().options().slot_option(slot_option_name).set_bios(string_format("%d", bios_val - 1)); - } - reset(reset_options::REMEMBER_REF); - } + if (bios_val > 0) + { + dev->set_system_bios(bios_val); + if (!strcmp(dev->tag(), ":")) + { + machine().options().set_value("bios", bios_val - 1, OPTION_PRIORITY_CMDLINE); } + else + { + const char *slot_option_name = dev->owner()->tag() + 1; + machine().options().slot_option(slot_option_name).set_bios(string_format("%d", bios_val - 1)); + } + reset(reset_options::REMEMBER_REF); } + + // triggers an item reset for any change + return false; } @@ -166,15 +173,16 @@ void menu_network_devices::populate() { int curr = network.get_interface(); const char *title = nullptr; - for(auto &entry : get_netdev_list()) + for (auto &entry : get_netdev_list()) { - if(entry->id==curr) { + if (entry->id == curr) + { title = entry->description; break; } } - item_append(network.device().tag(), (title) ? title : "------", FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, (void *)&network); + item_append(network.device().tag(), title ? title : "------", FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, (void *)&network); } item_append(menu_item_type::SEPARATOR); @@ -184,24 +192,41 @@ void menu_network_devices::populate() menu_network_devices - menu that -------------------------------------------------*/ -void menu_network_devices::handle(event const *ev) +bool menu_network_devices::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) + if (!ev || !ev->itemref) { - if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT) + return false; + } + else if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT) + { + device_network_interface *const network = (device_network_interface *)ev->itemref; + int curr = network->get_interface(); + if (ev->iptkey == IPT_UI_LEFT) + curr--; + else + curr++; + if (curr == -2) + curr = netdev_count() - 1; + network->set_interface(curr); + + curr = network->get_interface(); + const char *title = nullptr; + for (auto &entry : get_netdev_list()) { - device_network_interface *network = (device_network_interface *)ev->itemref; - int curr = network->get_interface(); - if (ev->iptkey == IPT_UI_LEFT) - curr--; - else - curr++; - if (curr == -2) - curr = netdev_count() - 1; - network->set_interface(curr); - reset(reset_options::REMEMBER_REF); + if (entry->id == curr) + { + title = entry->description; + break; + } } + + ev->item->set_subtext(title ? title : "------"); + return true; + } + else + { + return false; } } @@ -272,16 +297,20 @@ void menu_bookkeeping::populate() { } -void menu_bookkeeping::handle(event const *ev) +bool menu_bookkeeping::handle(event const *ev) { // if the time has rolled over another second, regenerate // TODO: what about other bookkeeping events happening with the menu open? attotime const curtime = machine().time(); if (curtime.seconds() != prevtime.seconds()) + { reset_layout(); - - if (ev) - handle_key(ev->iptkey); + return true; + } + else + { + return ev && handle_key(ev->iptkey); + } } @@ -290,7 +319,7 @@ void menu_bookkeeping::handle(event const *ev) menu -------------------------------------------------*/ -void menu_crosshair::handle(event const *ev) +bool menu_crosshair::handle(event const *ev) { // handle events if (ev && ev->itemref) @@ -383,6 +412,9 @@ void menu_crosshair::handle(event const *ev) if (changed) reset(reset_options::REMEMBER_REF); // rebuild the menu } + + // triggers an item reset for any changes + return false; } @@ -601,7 +633,7 @@ menu_export::~menu_export() // handle the export menu //------------------------------------------------- -void menu_export::handle(event const *ev) +bool menu_export::handle(event const *ev) { // process the menu if (ev && ev->itemref) @@ -640,7 +672,7 @@ void menu_export::handle(event const *ev) auto iter = std::find_if( driver_list.begin(), driver_list.end(), - [shortname](const game_driver *driver) { return !strcmp(shortname, driver->name); }); + [shortname] (const game_driver *driver) { return !strcmp(shortname, driver->name); }); return iter != driver_list.end(); }; @@ -695,6 +727,8 @@ void menu_export::handle(event const *ev) break; } } + + return false; } //------------------------------------------------- @@ -752,7 +786,7 @@ menu_machine_configure::~menu_machine_configure() // handle the machine options menu //------------------------------------------------- -void menu_machine_configure::handle(event const *ev) +bool menu_machine_configure::handle(event const *ev) { // process the menu if (ev && ev->itemref) @@ -805,6 +839,9 @@ void menu_machine_configure::handle(event const *ev) reset(reset_options::REMEMBER_POSITION); } } + + // triggers an item reset for any changes + return false; } //------------------------------------------------- @@ -905,25 +942,25 @@ menu_plugins_configure::~menu_plugins_configure() // handle the plugins menu //------------------------------------------------- -void menu_plugins_configure::handle(event const *ev) +bool menu_plugins_configure::handle(event const *ev) { - // process the menu - bool changed = false; - plugin_options &plugins = mame_machine_manager::instance()->plugins(); - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT || ev->iptkey == IPT_UI_SELECT) { - if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT || ev->iptkey == IPT_UI_SELECT) + plugin_options &plugins = mame_machine_manager::instance()->plugins(); + plugin_options::plugin *p = plugins.find((const char*)ev->itemref); + if (p) { - plugin_options::plugin *p = plugins.find((const char*)ev->itemref); - if (p) - { - p->m_start = !p->m_start; - changed = true; - } + p->m_start = !p->m_start; + ev->item->set_subtext(p->m_start ? _("On") : _("Off")); + ev->item->set_flags(p->m_start ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW); + return true; } } - if (changed) - reset(reset_options::REMEMBER_REF); + + return false; } //------------------------------------------------- diff --git a/src/frontend/mame/ui/miscmenu.h b/src/frontend/mame/ui/miscmenu.h index ab763b7ed26..6d365ddba67 100644 --- a/src/frontend/mame/ui/miscmenu.h +++ b/src/frontend/mame/ui/miscmenu.h @@ -34,7 +34,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; class menu_bookkeeping : public menu_textbox @@ -49,7 +49,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; attotime prevtime; }; @@ -82,7 +82,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::vector<crosshair_item_data> m_data; std::vector<std::string> m_pics; @@ -97,7 +97,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; @@ -113,7 +113,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::vector<const game_driver*> m_list; }; @@ -149,7 +149,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void setup_bios(); @@ -175,7 +175,7 @@ public: protected: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/optsmenu.cpp b/src/frontend/mame/ui/optsmenu.cpp index 91e5fb52adb..07178b2cae4 100644 --- a/src/frontend/mame/ui/optsmenu.cpp +++ b/src/frontend/mame/ui/optsmenu.cpp @@ -60,11 +60,9 @@ menu_simple_game_options::~menu_simple_game_options() // handle //------------------------------------------------- -void menu_simple_game_options::handle(event const *ev) +bool menu_simple_game_options::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) - handle_item_event(*ev); + return ev && ev->itemref && handle_item_event(*ev); } //------------------------------------------------- @@ -91,7 +89,7 @@ void menu_simple_game_options::populate() // handle item //------------------------------------------------- -void menu_simple_game_options::handle_item_event(event const &menu_event) +bool menu_simple_game_options::handle_item_event(event const &menu_event) { if (IPT_UI_SELECT == menu_event.iptkey) { @@ -130,6 +128,7 @@ void menu_simple_game_options::handle_item_event(event const &menu_event) break; } } + return false; } @@ -161,11 +160,9 @@ menu_game_options::~menu_game_options() // handle //------------------------------------------------- -void menu_game_options::handle(event const *ev) +bool menu_game_options::handle(event const *ev) { - // process the menu - if (ev && ev->itemref) - handle_item_event(*ev); + return ev && ev->itemref && handle_item_event(*ev); } //------------------------------------------------- @@ -203,7 +200,7 @@ void menu_game_options::populate() // handle item //------------------------------------------------- -void menu_game_options::handle_item_event(event const &menu_event) +bool menu_game_options::handle_item_event(event const &menu_event) { bool changed = false; @@ -268,12 +265,14 @@ void menu_game_options::handle_item_event(event const &menu_event) menu::stack_push<menu_custom_ui>(ui(), container(), [this] () { reset(reset_options::REMEMBER_REF); }); break; default: - menu_simple_game_options::handle_item_event(menu_event); - return; + return menu_simple_game_options::handle_item_event(menu_event); } if (changed) reset(reset_options::REMEMBER_REF); + + // triggers an item reset for any changes + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/optsmenu.h b/src/frontend/mame/ui/optsmenu.h index d1779ede52a..b300ed90cd5 100644 --- a/src/frontend/mame/ui/optsmenu.h +++ b/src/frontend/mame/ui/optsmenu.h @@ -28,10 +28,10 @@ public: virtual ~menu_simple_game_options() override; protected: - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; virtual void populate() override; - void handle_item_event(event const &menu_event); + bool handle_item_event(event const &menu_event); private: enum @@ -62,10 +62,10 @@ public: virtual ~menu_game_options() override; protected: - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; virtual void populate() override; - void handle_item_event(event const &menu_event); + bool handle_item_event(event const &menu_event); private: enum diff --git a/src/frontend/mame/ui/pluginopt.cpp b/src/frontend/mame/ui/pluginopt.cpp index bbf3c447087..2a091d25b7a 100644 --- a/src/frontend/mame/ui/pluginopt.cpp +++ b/src/frontend/mame/ui/pluginopt.cpp @@ -19,13 +19,14 @@ namespace ui { -void menu_plugin::handle(event const *ev) +bool menu_plugin::handle(event const *ev) { if (ev && ev->itemref) { if (ev->iptkey == IPT_UI_SELECT) menu::stack_push<menu_plugin_opt>(ui(), container(), (char *)ev->itemref); } + return false; } menu_plugin::menu_plugin(mame_ui_manager &mui, render_container &container) : @@ -68,7 +69,7 @@ menu_plugin_opt::menu_plugin_opt(mame_ui_manager &mui, render_container &contain { } -void menu_plugin_opt::handle(event const *ev) +bool menu_plugin_opt::handle(event const *ev) { void *const itemref = ev ? ev->itemref : get_selection_ref(); std::string key; @@ -116,16 +117,19 @@ void menu_plugin_opt::handle(event const *ev) break; } } - if (!key.empty() || m_need_idle) - { - auto const result = mame_machine_manager::instance()->lua()->menu_callback(m_menu, uintptr_t(itemref), key); - if (result.second) - set_selection(reinterpret_cast<void *>(uintptr_t(*result.second))); - if (result.first) - reset(reset_options::REMEMBER_REF); - else if (ev && (ev->iptkey == IPT_UI_BACK)) - stack_pop(); - } + + if (key.empty() && !m_need_idle) + return false; + + auto const result = mame_machine_manager::instance()->lua()->menu_callback(m_menu, uintptr_t(itemref), key); + if (result.second) + set_selection(reinterpret_cast<void *>(uintptr_t(*result.second))); + if (result.first) + reset(reset_options::REMEMBER_REF); + else if (ev && (ev->iptkey == IPT_UI_BACK)) + stack_pop(); + + return result.second && !result.first; } void menu_plugin_opt::populate() diff --git a/src/frontend/mame/ui/pluginopt.h b/src/frontend/mame/ui/pluginopt.h index 1e947a9ccd3..46b386f5ff0 100644 --- a/src/frontend/mame/ui/pluginopt.h +++ b/src/frontend/mame/ui/pluginopt.h @@ -33,11 +33,12 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::vector<std::string> &m_plugins; }; + class menu_plugin_opt : public menu { public: @@ -49,7 +50,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::string const m_menu; bool m_need_idle; diff --git a/src/frontend/mame/ui/quitmenu.cpp b/src/frontend/mame/ui/quitmenu.cpp index cd1fb4ac59b..2177313a0cd 100644 --- a/src/frontend/mame/ui/quitmenu.cpp +++ b/src/frontend/mame/ui/quitmenu.cpp @@ -20,7 +20,8 @@ menu_confirm_quit::menu_confirm_quit(mame_ui_manager &mui, render_container &con : autopause_menu<>(mui, container) { set_one_shot(true); - set_process_flags(PROCESS_CUSTOM_ONLY | PROCESS_NOINPUT); + set_needs_prev_menu_item(false); + set_heading(_("menu-quit", "Are you sure you want to quit?")); } @@ -29,33 +30,24 @@ menu_confirm_quit::~menu_confirm_quit() } -void menu_confirm_quit::custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) -{ - ui().draw_text_box( - container(), - util::string_format( - _("Are you sure you want to quit?\n\n" - "Press %1$s to quit\n" - "Press %2$s to return to emulation"), - ui().get_general_input_setting(IPT_UI_SELECT), - ui().get_general_input_setting(IPT_UI_BACK)), - text_layout::text_justify::CENTER, - 0.5f, 0.5f, - UI_RED_COLOR); -} - - void menu_confirm_quit::populate() { + item_append(_("menu-quit", "Quit"), 0, nullptr); + item_append(_("menu-quit", "Return to emulation"), 0, nullptr); } -void menu_confirm_quit::handle(event const *ev) +bool menu_confirm_quit::handle(event const *ev) { - if (machine().ui_input().pressed(IPT_UI_SELECT)) - machine().schedule_exit(); - else if (machine().ui_input().pressed(IPT_UI_BACK)) - stack_pop(); + if (ev && (IPT_UI_SELECT == ev->iptkey)) + { + if (0 == selected_index()) + machine().schedule_exit(); + else + stack_pop(); + } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/quitmenu.h b/src/frontend/mame/ui/quitmenu.h index 206ef1983ea..9f22801fdba 100644 --- a/src/frontend/mame/ui/quitmenu.h +++ b/src/frontend/mame/ui/quitmenu.h @@ -23,12 +23,9 @@ public: menu_confirm_quit(mame_ui_manager &mui, render_container &container); virtual ~menu_confirm_quit(); -protected: - virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; - private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; } // namespace ui diff --git a/src/frontend/mame/ui/selector.cpp b/src/frontend/mame/ui/selector.cpp index b3a579cd049..e21026f6d44 100644 --- a/src/frontend/mame/ui/selector.cpp +++ b/src/frontend/mame/ui/selector.cpp @@ -49,46 +49,47 @@ menu_selector::~menu_selector() // handle //------------------------------------------------- -void menu_selector::handle(event const *ev) +bool menu_selector::handle(event const *ev) { - // process the menu - if (ev) + if (!ev) + return false; + + switch (ev->iptkey) { - switch (ev->iptkey) + case IPT_UI_SELECT: + if (ev->itemref) { - case IPT_UI_SELECT: - if (ev->itemref) - { - int selection(-1); - for (size_t idx = 0; (m_str_items.size() > idx) && (0 > selection); ++idx) - if ((void*)&m_str_items[idx] == ev->itemref) - selection = int(unsigned(idx)); + int selection(-1); + for (size_t idx = 0; (m_str_items.size() > idx) && (0 > selection); ++idx) + if ((void*)&m_str_items[idx] == ev->itemref) + selection = int(unsigned(idx)); - m_handler(selection); - stack_pop(); - } - break; + m_handler(selection); + stack_pop(); + } + break; - case IPT_UI_PASTE: - if (paste_text(m_search, uchar_is_printable)) - reset(reset_options::SELECT_FIRST); - break; + case IPT_UI_PASTE: + if (paste_text(m_search, uchar_is_printable)) + reset(reset_options::SELECT_FIRST); + break; - case IPT_SPECIAL: - if (input_character(m_search, ev->unichar, uchar_is_printable)) - reset(reset_options::SELECT_FIRST); - break; + case IPT_SPECIAL: + if (input_character(m_search, ev->unichar, uchar_is_printable)) + reset(reset_options::SELECT_FIRST); + break; - case IPT_UI_CANCEL: - if (!m_search.empty()) - { - // escape pressed with non-empty search text clears the search text - m_search.clear(); - reset(reset_options::SELECT_FIRST); - } - break; + case IPT_UI_CANCEL: + if (!m_search.empty()) + { + // escape pressed with non-empty search text clears the search text + m_search.clear(); + reset(reset_options::SELECT_FIRST); } + break; } + + return false; // any changes will trigger an item reset } //------------------------------------------------- diff --git a/src/frontend/mame/ui/selector.h b/src/frontend/mame/ui/selector.h index 07528364f4d..4b8043a990a 100644 --- a/src/frontend/mame/ui/selector.h +++ b/src/frontend/mame/ui/selector.h @@ -46,7 +46,7 @@ private: enum { VISIBLE_SEARCH_ITEMS = 200 }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool 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 047e6f6f721..f9b2c702503 100644 --- a/src/frontend/mame/ui/selgame.cpp +++ b/src/frontend/mame/ui/selgame.cpp @@ -194,7 +194,7 @@ void menu_select_game::menu_deactivated() // handle //------------------------------------------------- -void menu_select_game::handle(event const *ev) +bool menu_select_game::handle(event const *ev) { if (!m_prev_selected && item_count() > 0) m_prev_selected = item(0).ref(); @@ -207,38 +207,52 @@ void menu_select_game::handle(event const *ev) const ui_software_info *software; get_selection(software, system); menu::stack_push<menu_select_software>(ui(), container(), *system); - return; + return false; } // FIXME: everything above here used to run before events were processed // process the menu + bool changed = false; if (ev) { if (dismiss_error()) { // reset the error on any subsequent menu event + changed = true; } else switch (ev->iptkey) { case IPT_UI_UP: if ((get_focus() == focused_menu::LEFT) && (machine_filter::FIRST < m_filter_highlight)) + { --m_filter_highlight; + changed = true; + } break; case IPT_UI_DOWN: if ((get_focus() == focused_menu::LEFT) && (machine_filter::LAST > m_filter_highlight)) + { m_filter_highlight++; + changed = true; + } break; case IPT_UI_HOME: if (get_focus() == focused_menu::LEFT) + { m_filter_highlight = machine_filter::FIRST; + changed = true; + } break; case IPT_UI_END: if (get_focus() == focused_menu::LEFT) + { m_filter_highlight = machine_filter::LAST; + changed = true; + } break; case IPT_UI_EXPORT: @@ -258,9 +272,9 @@ void menu_select_game::handle(event const *ev) if (get_focus() == focused_menu::MAIN) { if (m_populated_favorites) - inkey_select_favorite(ev); + changed = inkey_select_favorite(ev); else - inkey_select(ev); + changed = inkey_select(ev); } break; @@ -292,16 +306,16 @@ void menu_select_game::handle(event const *ev) case IPT_UI_LEFT: if (right_panel() == RP_IMAGES) - previous_image_view(); // Images + changed = previous_image_view(); // Images else if (right_panel() == RP_INFOS) - change_info_pane(-1); // Infos + changed = change_info_pane(-1); // Infos break; case IPT_UI_RIGHT: if (right_panel() == RP_IMAGES) - next_image_view(); // Images + changed = next_image_view(); // Images else if (right_panel() == RP_INFOS) - change_info_pane(1); // Infos + changed = change_info_pane(1); // Infos break; case IPT_UI_FAVORITES: @@ -322,6 +336,7 @@ void menu_select_game::handle(event const *ev) mfav.remove_favorite_system(driver); machine().popmessage(_("%s\n removed from favorites list."), info.description); } + changed = true; } else { @@ -343,6 +358,7 @@ void menu_select_game::handle(event const *ev) // if we're in an error state, overlay an error message draw_error_text(); + return changed; } //------------------------------------------------- @@ -606,7 +622,7 @@ void menu_select_game::force_game_select(mame_ui_manager &mui, render_container // handle select key event //------------------------------------------------- -void menu_select_game::inkey_select(const event *menu_event) +bool menu_select_game::inkey_select(const event *menu_event) { auto const system = reinterpret_cast<ui_system_info const *>(menu_event->itemref); @@ -618,13 +634,14 @@ void menu_select_game::inkey_select(const event *menu_event) container(), m_persistent_data.filter_data(), [this] () { reset(reset_options::SELECT_FIRST); }); + return false; } else if (uintptr_t(system) == CONF_MACHINE) { // special case for configure machine if (m_prev_selected) menu::stack_push<menu_machine_configure>(ui(), container(), *reinterpret_cast<const ui_system_info *>(m_prev_selected)); - return; + return false; } else { @@ -638,7 +655,7 @@ void menu_select_game::inkey_select(const event *menu_event) if (!swlistdev.get_info().empty()) { menu::stack_push<menu_select_software>(ui(), container(), *system); - return; + return false; } } @@ -651,11 +668,13 @@ void menu_select_game::inkey_select(const event *menu_event) { if (!select_bios(*system->driver, false)) launch_system(*system->driver); + return false; } else { // otherwise, display an error set_error(reset_options::REMEMBER_REF, make_system_audit_fail_text(auditor, summary)); + return true; } } } @@ -664,7 +683,7 @@ void menu_select_game::inkey_select(const event *menu_event) // handle select key event for favorites menu //------------------------------------------------- -void menu_select_game::inkey_select_favorite(const event *menu_event) +bool menu_select_game::inkey_select_favorite(const event *menu_event) { ui_software_info *ui_swinfo = (ui_software_info *)menu_event->itemref; @@ -676,6 +695,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) container(), m_persistent_data.filter_data(), [this] () { reset(reset_options::SELECT_FIRST); }); + return false; } else if ((uintptr_t)ui_swinfo == CONF_MACHINE) { @@ -694,7 +714,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) reset(empty ? reset_options::SELECT_FIRST : reset_options::REMEMBER_REF); }); } - return; + return false; } else if (ui_swinfo->startempty) { @@ -708,7 +728,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) { ui_system_info const &system(m_persistent_data.systems()[driver_list::find(ui_swinfo->driver->name)]); menu::stack_push<menu_select_software>(ui(), container(), system); - return; + return false; } } @@ -724,11 +744,13 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) reselect_last::reselect(true); launch_system(*ui_swinfo->driver); } + return false; } else { // otherwise, display an error set_error(reset_options::REMEMBER_REF, make_system_audit_fail_text(auditor, summary)); + return true; } } else @@ -741,6 +763,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) if (!audit_passed(sysaudit)) { set_error(reset_options::REMEMBER_REF, make_system_audit_fail_text(auditor, sysaudit)); + return true; } else { @@ -755,11 +778,13 @@ void menu_select_game::inkey_select_favorite(const event *menu_event) reselect_last::reselect(true); if (!select_bios(*ui_swinfo, false) && !select_part(*swinfo, *ui_swinfo)) launch_system(drv.driver(), *ui_swinfo, ui_swinfo->part); + return false; } else { // otherwise, display an error set_error(reset_options::REMEMBER_REF, make_software_audit_fail_text(auditor, swaudit)); + return true; } } } @@ -779,34 +804,46 @@ bool menu_select_game::isfavorite() const // change what's displayed in the info box //------------------------------------------------- -void menu_select_game::change_info_pane(int delta) +bool menu_select_game::change_info_pane(int delta) { - auto const cap_delta = [this, &delta] (uint8_t ¤t, uint8_t &total) - { - if ((0 > delta) && (-delta > current)) - delta = -int(unsigned(current)); - else if ((0 < delta) && ((current + unsigned(delta)) >= total)) - delta = int(unsigned(total - current - 1)); - if (delta) - { - current += delta; - m_topline_datsview = 0; - } - }; + auto const cap_delta = + [this, &delta] (uint8_t ¤t, uint8_t &total) -> bool + { + if ((0 > delta) && (-delta > current)) + delta = -int(unsigned(current)); + else if ((0 < delta) && ((current + unsigned(delta)) >= total)) + delta = int(unsigned(total - current - 1)); + if (delta) + { + current += delta; + m_topline_datsview = 0; + return true; + } + else + { + return false; + } + }; ui_system_info const *sys; ui_software_info const *soft; get_selection(soft, sys); if (!m_populated_favorites) { if (uintptr_t(sys) > m_skip_main_items) - cap_delta(ui_globals::curdats_view, ui_globals::curdats_total); + return cap_delta(ui_globals::curdats_view, ui_globals::curdats_total); + else + return false; } else if (uintptr_t(soft) > m_skip_main_items) { if (soft->startempty) - cap_delta(ui_globals::curdats_view, ui_globals::curdats_total); + return cap_delta(ui_globals::curdats_view, ui_globals::curdats_total); else - cap_delta(ui_globals::cur_sw_dats_view, ui_globals::cur_sw_dats_total); + return cap_delta(ui_globals::cur_sw_dats_view, ui_globals::cur_sw_dats_total); + } + else + { + return false; } } diff --git a/src/frontend/mame/ui/selgame.h b/src/frontend/mame/ui/selgame.h index af1dad248ac..4aae7261687 100644 --- a/src/frontend/mame/ui/selgame.h +++ b/src/frontend/mame/ui/selgame.h @@ -59,7 +59,7 @@ private: static bool s_first_start; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // drawing virtual float draw_left_panel(float x1, float y1, float x2, float y2) override; @@ -80,7 +80,7 @@ private: virtual void inkey_export() override; // internal methods - void change_info_pane(int delta); + bool change_info_pane(int delta); void build_available_list(); @@ -90,8 +90,8 @@ private: void load_custom_filters(); // handlers - void inkey_select(const event *menu_event); - void inkey_select_favorite(const event *menu_event); + bool inkey_select(const event *menu_event); + bool inkey_select_favorite(const event *menu_event); }; } // namespace ui diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp index 1a0789bc394..baa89bfefe0 100644 --- a/src/frontend/mame/ui/selmenu.cpp +++ b/src/frontend/mame/ui/selmenu.cpp @@ -173,7 +173,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; ui_software_info const &m_uiinfo; s_parts const m_parts; @@ -190,7 +190,7 @@ private: bios_selection(mame_ui_manager &mui, render_container &container, s_bios &&biosname, void const *driver, bool software, bool inlist); virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; void const *m_driver; bool m_software, m_inlist; @@ -297,9 +297,8 @@ void menu_select_launch::software_parts::populate() // handle //------------------------------------------------- -void menu_select_launch::software_parts::handle(event const *ev) +bool menu_select_launch::software_parts::handle(event const *ev) { - // process the menu if (ev && (ev->iptkey == IPT_UI_SELECT) && ev->itemref) { for (auto const &elem : m_parts) @@ -311,6 +310,8 @@ void menu_select_launch::software_parts::handle(event const *ev) } } } + + return false; } @@ -362,9 +363,8 @@ void menu_select_launch::bios_selection::populate() // handle //------------------------------------------------- -void menu_select_launch::bios_selection::handle(event const *ev) +bool menu_select_launch::bios_selection::handle(event const *ev) { - // process the menu if (ev && (ev->iptkey == IPT_UI_SELECT) && ev->itemref) { for (auto & elem : m_bios) @@ -402,6 +402,8 @@ void menu_select_launch::bios_selection::handle(event const *ev) } } } + + return false; } @@ -526,22 +528,32 @@ menu_select_launch::menu_select_launch(mame_ui_manager &mui, render_container &c } -void menu_select_launch::next_image_view() +bool menu_select_launch::next_image_view() { if (LAST_VIEW > m_image_view) { ++m_image_view; set_switch_image(); + return true; + } + else + { + return false; } } -void menu_select_launch::previous_image_view() +bool menu_select_launch::previous_image_view() { if (FIRST_VIEW < m_image_view) { --m_image_view; set_switch_image(); + return true; + } + else + { + return false; } } diff --git a/src/frontend/mame/ui/selmenu.h b/src/frontend/mame/ui/selmenu.h index 42edf8a773a..88ef0476ffe 100644 --- a/src/frontend/mame/ui/selmenu.h +++ b/src/frontend/mame/ui/selmenu.h @@ -114,8 +114,8 @@ protected: focused_menu get_focus() const { return m_focus; } void set_focus(focused_menu focus) { m_focus = focus; } - void next_image_view(); - void previous_image_view(); + bool next_image_view(); + bool previous_image_view(); bool dismiss_error(); void set_error(reset_options ropt, std::string &&message); diff --git a/src/frontend/mame/ui/selsoft.cpp b/src/frontend/mame/ui/selsoft.cpp index 50822545dd1..4d0c9554a9d 100644 --- a/src/frontend/mame/ui/selsoft.cpp +++ b/src/frontend/mame/ui/selsoft.cpp @@ -420,7 +420,7 @@ menu_select_software::~menu_select_software() // handle //------------------------------------------------- -void menu_select_software::handle(event const *ev) +bool menu_select_software::handle(event const *ev) { if (m_prev_selected == nullptr && item_count() > 0) m_prev_selected = item(0).ref(); @@ -428,30 +428,33 @@ void menu_select_software::handle(event const *ev) // FIXME: everything above here used run before events were processed // process the menu + bool changed = false; if (ev) { if (dismiss_error()) { // reset the error on any subsequent menu event + changed = true; } else switch (ev->iptkey) { case IPT_UI_SELECT: if ((get_focus() == focused_menu::MAIN) && ev->itemref) - inkey_select(ev); + changed = inkey_select(ev); break; case IPT_UI_LEFT: if (right_panel() == RP_IMAGES) { // Images - previous_image_view(); + changed = previous_image_view(); } else if (right_panel() == RP_INFOS && ui_globals::cur_sw_dats_view > 0) { // Infos ui_globals::cur_sw_dats_view--; m_topline_datsview = 0; + changed = true; } break; @@ -459,34 +462,47 @@ void menu_select_software::handle(event const *ev) if (right_panel() == RP_IMAGES) { // Images - next_image_view(); + changed = next_image_view(); } else if (right_panel() == RP_INFOS && ui_globals::cur_sw_dats_view < (ui_globals::cur_sw_dats_total - 1)) { // Infos ui_globals::cur_sw_dats_view++; m_topline_datsview = 0; + changed = true; } break; case IPT_UI_UP: if ((get_focus() == focused_menu::LEFT) && (software_filter::FIRST < m_filter_highlight)) + { --m_filter_highlight; + changed = true; + } break; case IPT_UI_DOWN: if ((get_focus() == focused_menu::LEFT) && (software_filter::LAST > m_filter_highlight)) + { ++m_filter_highlight; + changed = true; + } break; case IPT_UI_HOME: if (get_focus() == focused_menu::LEFT) + { m_filter_highlight = software_filter::FIRST; + changed = true; + } break; case IPT_UI_END: if (get_focus() == focused_menu::LEFT) + { m_filter_highlight = software_filter::LAST; + changed = true; + } break; case IPT_UI_DATS: @@ -509,12 +525,12 @@ void menu_select_software::handle(event const *ev) mfav.add_favorite_software(*swinfo); machine().popmessage(_("%s\n added to favorites list."), swinfo->longname); } - else { machine().popmessage(_("%s\n removed from favorites list."), swinfo->longname); mfav.remove_favorite_software(*swinfo); } + changed = true; } } } @@ -523,6 +539,7 @@ void menu_select_software::handle(event const *ev) // if we're in an error state, overlay an error message draw_error_text(); + return changed; } //------------------------------------------------- @@ -633,7 +650,7 @@ void menu_select_software::populate() // handle select key event //------------------------------------------------- -void menu_select_software::inkey_select(const event *menu_event) +bool menu_select_software::inkey_select(const event *menu_event) { ui_software_info *ui_swinfo = (ui_software_info *)menu_event->itemref; driver_enumerator drivlist(machine().options(), *ui_swinfo->driver); @@ -645,6 +662,7 @@ void menu_select_software::inkey_select(const event *menu_event) if (!audit_passed(sysaudit)) { set_error(reset_options::REMEMBER_REF, make_system_audit_fail_text(auditor, sysaudit)); + return true; } else if (ui_swinfo->startempty == 1) { @@ -653,6 +671,7 @@ void menu_select_software::inkey_select(const event *menu_event) reselect_last::reselect(true); launch_system(*ui_swinfo->driver, *ui_swinfo); } + return false; } else { @@ -668,11 +687,13 @@ void menu_select_software::inkey_select(const event *menu_event) reselect_last::reselect(true); launch_system(drivlist.driver(), *ui_swinfo); } + return false; } else { // otherwise, display an error set_error(reset_options::REMEMBER_REF, make_software_audit_fail_text(auditor, swaudit)); + return true; } } } diff --git a/src/frontend/mame/ui/selsoft.h b/src/frontend/mame/ui/selsoft.h index 1ac874ac93a..3b3074ddcdf 100644 --- a/src/frontend/mame/ui/selsoft.h +++ b/src/frontend/mame/ui/selsoft.h @@ -45,7 +45,7 @@ private: class machine_data; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // drawing virtual float draw_left_panel(float x1, float y1, float x2, float y2) override; @@ -65,7 +65,7 @@ private: virtual void inkey_export() override { throw false; } // handlers - void inkey_select(const event *menu_event); + bool inkey_select(const event *menu_event); std::map<std::string, std::string> m_icon_paths; ui_system_info const &m_system; diff --git a/src/frontend/mame/ui/simpleselgame.cpp b/src/frontend/mame/ui/simpleselgame.cpp index 2c1cb28e29a..3919f97df23 100644 --- a/src/frontend/mame/ui/simpleselgame.cpp +++ b/src/frontend/mame/ui/simpleselgame.cpp @@ -110,37 +110,36 @@ void simple_menu_select_game::build_driver_list() // handle - handle the game select menu //------------------------------------------------- -void simple_menu_select_game::handle(event const *ev) +bool simple_menu_select_game::handle(event const *ev) { - // process the menu - if (ev) + if (!ev) + return false; + + if (m_error) { - if (m_error) - { - // reset the error on any subsequent menu event - m_error = false; - machine().ui_input().reset(); - } - else - { - // handle selections - switch (ev->iptkey) - { - case IPT_UI_SELECT: - inkey_select(*ev); - break; - case IPT_UI_CANCEL: - inkey_cancel(); - break; - case IPT_UI_PASTE: - if (paste_text(m_search, uchar_is_printable)) - reset(reset_options::SELECT_FIRST); - break; - case IPT_SPECIAL: - inkey_special(*ev); - break; - } - } + // reset the error on any subsequent menu event + m_error = false; + machine().ui_input().reset(); + return true; + } + + // handle selections + bool changed = false; + switch (ev->iptkey) + { + case IPT_UI_SELECT: + changed = inkey_select(*ev); + break; + case IPT_UI_CANCEL: + inkey_cancel(); + break; + case IPT_UI_PASTE: + if (paste_text(m_search, uchar_is_printable)) + reset(reset_options::SELECT_FIRST); + break; + case IPT_SPECIAL: + inkey_special(*ev); + break; } // if we're in an error state, overlay an error message @@ -152,6 +151,7 @@ void simple_menu_select_game::handle(event const *ev) "Please select a different game.\n\nPress any key to continue."), text_layout::text_justify::CENTER, 0.5f, 0.5f, UI_RED_COLOR); } + return changed; } @@ -159,7 +159,7 @@ void simple_menu_select_game::handle(event const *ev) // inkey_select //------------------------------------------------- -void simple_menu_select_game::inkey_select(const event &menu_event) +bool simple_menu_select_game::inkey_select(const event &menu_event) { const game_driver *driver = (const game_driver *)menu_event.itemref; @@ -169,10 +169,12 @@ void simple_menu_select_game::inkey_select(const event &menu_event) ui(), container(), [this] () { reset(reset_options::SELECT_FIRST); }); + return false; } else if (!driver) // special case for previous menu { stack_pop(); + return false; } else // anything else is a driver { @@ -188,12 +190,14 @@ void simple_menu_select_game::inkey_select(const event &menu_event) mame_machine_manager::instance()->schedule_new_driver(*driver); machine().schedule_hard_reset(); stack_reset(); + return false; } else { // otherwise, display an error reset(reset_options::REMEMBER_REF); m_error = true; + return true; } } } diff --git a/src/frontend/mame/ui/simpleselgame.h b/src/frontend/mame/ui/simpleselgame.h index b1f4c1946e3..f010bf14e8e 100644 --- a/src/frontend/mame/ui/simpleselgame.h +++ b/src/frontend/mame/ui/simpleselgame.h @@ -37,11 +37,11 @@ private: enum { VISIBLE_GAMES_IN_LIST = 15 }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // internal methods void build_driver_list(); - void inkey_select(const event &menu_event); + bool inkey_select(const event &menu_event); void inkey_cancel(); void inkey_special(const event &menu_event); diff --git a/src/frontend/mame/ui/sliders.cpp b/src/frontend/mame/ui/sliders.cpp index db1dbbe7b66..b708b6af56a 100644 --- a/src/frontend/mame/ui/sliders.cpp +++ b/src/frontend/mame/ui/sliders.cpp @@ -39,118 +39,134 @@ menu_sliders::~menu_sliders() // menu_sliders - handle the sliders menu //------------------------------------------------- -void menu_sliders::handle(event const *ev) +bool menu_sliders::handle(event const *ev) { - // process the menu - if (ev) + if (!ev) + return false; + + if (ev->iptkey == IPT_UI_ON_SCREEN_DISPLAY) + { + // toggle visibility + if (m_menuless_mode) + { + stack_pop(); + return false; + } + else + { + m_hidden = !m_hidden; + set_process_flags(PROCESS_LR_REPEAT | (m_hidden ? PROCESS_CUSTOM_ONLY : 0)); + return true; + } + } + + // handle keys if there is a valid item selected + if (ev->itemref && (ev->item->type() == menu_item_type::SLIDER)) { - if (ev->iptkey == IPT_UI_ON_SCREEN_DISPLAY) + const slider_state *slider = (const slider_state *)ev->itemref; + int32_t curvalue = slider->update(nullptr, SLIDER_NOCHANGE); + int32_t increment = 0; + bool const alt_pressed = machine().input().code_pressed(KEYCODE_LALT) || machine().input().code_pressed(KEYCODE_RALT); + bool const ctrl_pressed = machine().input().code_pressed(KEYCODE_LCONTROL) || machine().input().code_pressed(KEYCODE_RCONTROL); + bool const shift_pressed = machine().input().code_pressed(KEYCODE_LSHIFT) || machine().input().code_pressed(KEYCODE_RSHIFT); + + switch (ev->iptkey) { - // toggle visibility + // decrease value + case IPT_UI_LEFT: + if (alt_pressed && shift_pressed) + increment = -1; + else if (alt_pressed) + increment = -(curvalue - slider->minval); + else if (shift_pressed) + increment = (slider->incval > 10) ? -(slider->incval / 10) : -1; + else if (ctrl_pressed) + increment = -slider->incval * 10; + else + increment = -slider->incval; + break; + + // increase value + case IPT_UI_RIGHT: + if (alt_pressed && shift_pressed) + increment = 1; + else if (alt_pressed) + increment = slider->maxval - curvalue; + else if (shift_pressed) + increment = (slider->incval > 10) ? (slider->incval / 10) : 1; + else if (ctrl_pressed) + increment = slider->incval * 10; + else + increment = slider->incval; + break; + + // restore default + case IPT_UI_CLEAR: + increment = slider->defval - curvalue; + break; + } + + // handle any changes + if (increment != 0) + { + int32_t newvalue = curvalue + increment; + + // clamp within bounds + if (newvalue < slider->minval) + newvalue = slider->minval; + if (newvalue > slider->maxval) + newvalue = slider->maxval; + + // update the slider and recompute the menu + slider->update(nullptr, newvalue); if (m_menuless_mode) + ui().get_session_data<menu_sliders, void *>(nullptr) = ev->itemref; + reset(reset_options::REMEMBER_REF); + } + + // slider changes trigger an item reset as they can change the available sliders + return false; + } + + // when highlighting an item that isn't a slider with the menu is hidden, skip to the next one + if (m_hidden) + { + if (ev->iptkey == IPT_UI_UP || ev->iptkey == IPT_UI_PAGE_UP) + { + // if we got here via up or page up, select the previous item + if (is_first_selected()) { - stack_pop(); + select_last_item(); } else { - m_hidden = !m_hidden; - set_process_flags(PROCESS_LR_REPEAT | (m_hidden ? PROCESS_CUSTOM_ONLY : 0)); + set_selected_index(selected_index() - 1); + validate_selection(-1); } - + return true; } - else if (ev->itemref && (ev->item->type() == menu_item_type::SLIDER)) + else if (ev->iptkey == IPT_UI_DOWN || ev->iptkey == IPT_UI_PAGE_DOWN) { - // handle keys if there is a valid item selected - const slider_state *slider = (const slider_state *)ev->itemref; - int32_t curvalue = slider->update(nullptr, SLIDER_NOCHANGE); - int32_t increment = 0; - bool const alt_pressed = machine().input().code_pressed(KEYCODE_LALT) || machine().input().code_pressed(KEYCODE_RALT); - bool const ctrl_pressed = machine().input().code_pressed(KEYCODE_LCONTROL) || machine().input().code_pressed(KEYCODE_RCONTROL); - bool const shift_pressed = machine().input().code_pressed(KEYCODE_LSHIFT) || machine().input().code_pressed(KEYCODE_RSHIFT); - - switch (ev->iptkey) + // otherwise select the next item + if (is_last_selected()) { - // decrease value - case IPT_UI_LEFT: - if (alt_pressed && shift_pressed) - increment = -1; - else if (alt_pressed) - increment = -(curvalue - slider->minval); - else if (shift_pressed) - increment = (slider->incval > 10) ? -(slider->incval / 10) : -1; - else if (ctrl_pressed) - increment = -slider->incval * 10; - else - increment = -slider->incval; - break; - - // increase value - case IPT_UI_RIGHT: - if (alt_pressed && shift_pressed) - increment = 1; - else if (alt_pressed) - increment = slider->maxval - curvalue; - else if (shift_pressed) - increment = (slider->incval > 10) ? (slider->incval / 10) : 1; - else if (ctrl_pressed) - increment = slider->incval * 10; - else - increment = slider->incval; - break; - - // restore default - case IPT_UI_CLEAR: - increment = slider->defval - curvalue; - break; + select_first_item(); } - - // handle any changes - if (increment != 0) + else { - int32_t newvalue = curvalue + increment; - - // clamp within bounds - if (newvalue < slider->minval) - newvalue = slider->minval; - if (newvalue > slider->maxval) - newvalue = slider->maxval; - - // update the slider and recompute the menu - slider->update(nullptr, newvalue); - if (m_menuless_mode) - ui().get_session_data<menu_sliders, void *>(nullptr) = ev->itemref; - reset(reset_options::REMEMBER_REF); + set_selected_index(selected_index() + 1); + validate_selection(1); } + return true; } - else if (m_hidden) + else { - // if we are selecting an invalid item and we are hidden, skip to the next one - if (ev->iptkey == IPT_UI_UP || ev->iptkey == IPT_UI_PAGE_UP) - { - // if we got here via up or page up, select the previous item - if (is_first_selected()) - { - select_last_item(); - } - else - { - set_selected_index(selected_index() - 1); - validate_selection(-1); - } - } - else if (ev->iptkey == IPT_UI_DOWN || ev->iptkey == IPT_UI_PAGE_DOWN) - { - // otherwise select the next item - if (is_last_selected()) - select_first_item(); - else - { - set_selected_index(selected_index() + 1); - validate_selection(1); - } - } + return false; } } + + // didn't do anything + return false; } diff --git a/src/frontend/mame/ui/sliders.h b/src/frontend/mame/ui/sliders.h index 645169189cc..f9c0c69a176 100644 --- a/src/frontend/mame/ui/sliders.h +++ b/src/frontend/mame/ui/sliders.h @@ -32,7 +32,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; bool const m_menuless_mode; bool m_hidden; diff --git a/src/frontend/mame/ui/slotopt.cpp b/src/frontend/mame/ui/slotopt.cpp index 1b30b6120c1..bd92a2f9c9b 100644 --- a/src/frontend/mame/ui/slotopt.cpp +++ b/src/frontend/mame/ui/slotopt.cpp @@ -242,29 +242,30 @@ void menu_slot_devices::custom_render(void *selectedref, float top, float bottom // handle - process an input event //------------------------------------------------- -void menu_slot_devices::handle(event const *ev) +bool menu_slot_devices::handle(event const *ev) { - // process the menu - if (ev && ev->itemref != nullptr) + if (!ev || !ev->itemref) + return false; + + if (ev->itemref == ITEMREF_RESET) { - if (ev->itemref == ITEMREF_RESET) - { - if (ev->iptkey == IPT_UI_SELECT) - machine().schedule_hard_reset(); - } - else if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT) - { - device_slot_interface *slot = (device_slot_interface *)ev->itemref; - rotate_slot_device(*slot, ev->iptkey == IPT_UI_LEFT ? step_t::PREVIOUS : step_t::NEXT); - } - else if (ev->iptkey == IPT_UI_SELECT) - { - device_slot_interface *slot = (device_slot_interface *)ev->itemref; - device_slot_interface::slot_option const *const option = get_current_option(*slot); - if (option) - menu::stack_push<menu_device_config>(ui(), container(), slot, option); - } + if (ev->iptkey == IPT_UI_SELECT) + machine().schedule_hard_reset(); } + else if (ev->iptkey == IPT_UI_LEFT || ev->iptkey == IPT_UI_RIGHT) + { + device_slot_interface *slot = (device_slot_interface *)ev->itemref; + rotate_slot_device(*slot, ev->iptkey == IPT_UI_LEFT ? step_t::PREVIOUS : step_t::NEXT); + } + else if (ev->iptkey == IPT_UI_SELECT) + { + device_slot_interface *slot = (device_slot_interface *)ev->itemref; + device_slot_interface::slot_option const *const option = get_current_option(*slot); + if (option) + menu::stack_push<menu_device_config>(ui(), container(), slot, option); + } + + return false; // any changes require the menu to be rebuilt } diff --git a/src/frontend/mame/ui/slotopt.h b/src/frontend/mame/ui/slotopt.h index 6dae4ce062a..af272dde8ed 100644 --- a/src/frontend/mame/ui/slotopt.h +++ b/src/frontend/mame/ui/slotopt.h @@ -37,7 +37,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; device_slot_interface::slot_option const *get_current_option(device_slot_interface &slot) const; void set_slot_device(device_slot_interface &slot, std::string_view val); diff --git a/src/frontend/mame/ui/sndmenu.cpp b/src/frontend/mame/ui/sndmenu.cpp index f389c128c07..e5516f41cfa 100644 --- a/src/frontend/mame/ui/sndmenu.cpp +++ b/src/frontend/mame/ui/sndmenu.cpp @@ -72,7 +72,7 @@ void menu_sound_options::menu_dismissed() // handle //------------------------------------------------- -void menu_sound_options::handle(event const *ev) +bool menu_sound_options::handle(event const *ev) { bool changed = false; @@ -130,8 +130,9 @@ void menu_sound_options::handle(event const *ev) } } - if (changed) + if (changed) // FIXME: most changes only require the item sub text to be updated reset(reset_options::REMEMBER_REF); + return false; } diff --git a/src/frontend/mame/ui/sndmenu.h b/src/frontend/mame/ui/sndmenu.h index 6e79d4f6faa..01d69f6d8ff 100644 --- a/src/frontend/mame/ui/sndmenu.h +++ b/src/frontend/mame/ui/sndmenu.h @@ -39,7 +39,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; uint16_t m_cur_rates; static const int m_sound_rate[]; diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp index a7795c0347b..0c39c89d9e6 100644 --- a/src/frontend/mame/ui/state.cpp +++ b/src/frontend/mame/ui/state.cpp @@ -234,13 +234,14 @@ void menu_load_save_state_base::populate() // handle //------------------------------------------------- -void menu_load_save_state_base::handle(event const *ev) +bool menu_load_save_state_base::handle(event const *ev) { // process the event if (INPUT_CODE_INVALID != m_slot_selected) { if (!machine().input().code_pressed(m_slot_selected)) stack_pop(); + return false; } else if (ev && (ev->iptkey == IPT_UI_SELECT)) { @@ -251,6 +252,7 @@ void menu_load_save_state_base::handle(event const *ev) slot_selected(std::string(entry.file_name())); } stack_pop(); + return false; } else if (ev && (ev->iptkey == IPT_UI_CLEAR)) { @@ -263,6 +265,11 @@ void menu_load_save_state_base::handle(event const *ev) m_confirm_delete->visible_name(), ui().get_general_input_setting(IPT_UI_SELECT), ui().get_general_input_setting(IPT_UI_BACK)); + return true; + } + else + { + return false; } } else if (!m_confirm_delete) @@ -275,6 +282,11 @@ void menu_load_save_state_base::handle(event const *ev) m_switch_poller.reset(); m_slot_selected = code; } + return false; + } + else + { + return false; } } diff --git a/src/frontend/mame/ui/state.h b/src/frontend/mame/ui/state.h index 8d982678d7d..8d02ab08881 100644 --- a/src/frontend/mame/ui/state.h +++ b/src/frontend/mame/ui/state.h @@ -40,7 +40,7 @@ protected: 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() override; - virtual void handle(event const *ev) override; + virtual bool 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 5fbb0c47d9c..188f6622c71 100644 --- a/src/frontend/mame/ui/submenu.cpp +++ b/src/frontend/mame/ui/submenu.cpp @@ -245,7 +245,7 @@ submenu::~submenu() // handle the options menu //------------------------------------------------- -void submenu::handle(event const *ev) +bool submenu::handle(event const *ev) { bool changed = false; std::string error_string, tmptxt; @@ -332,8 +332,9 @@ void submenu::handle(event const *ev) } } - if (changed) + if (changed) // FIXME: most changes should only require updating the item's subtext reset(reset_options::REMEMBER_REF); + return false; } //------------------------------------------------- diff --git a/src/frontend/mame/ui/submenu.h b/src/frontend/mame/ui/submenu.h index c307f220924..87e92cc3d9d 100644 --- a/src/frontend/mame/ui/submenu.h +++ b/src/frontend/mame/ui/submenu.h @@ -65,7 +65,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::vector<option> m_options; game_driver const *const m_driver; diff --git a/src/frontend/mame/ui/swlist.cpp b/src/frontend/mame/ui/swlist.cpp index da0ec08cbac..294cd5d3058 100644 --- a/src/frontend/mame/ui/swlist.cpp +++ b/src/frontend/mame/ui/swlist.cpp @@ -124,9 +124,8 @@ void menu_software_parts::populate() // handle //------------------------------------------------- -void menu_software_parts::handle(event const *ev) +bool menu_software_parts::handle(event const *ev) { - // process the menu if (ev && (ev->iptkey == IPT_UI_SELECT) && ev->itemref) { software_part_menu_entry *entry = (software_part_menu_entry *)ev->itemref; @@ -134,6 +133,8 @@ void menu_software_parts::handle(event const *ev) *m_selected_part = entry->part; stack_pop(); } + + return false; } @@ -286,55 +287,79 @@ void menu_software_list::populate() // handle //------------------------------------------------- -void menu_software_list::handle(event const *ev) +bool menu_software_list::handle(event const *ev) { - // process the menu - if (ev) + if (!ev) + { + return false; + } + else if (ev->iptkey == IPT_UI_SELECT) { - if (ev->iptkey == IPT_UI_SELECT) + if (ev->itemref == ITEMREF_SWITCH_ITEM_ORDERING) { - if (ev->itemref == ITEMREF_SWITCH_ITEM_ORDERING) - { - m_ordered_by_shortname = !m_ordered_by_shortname; + m_ordered_by_shortname = !m_ordered_by_shortname; - // reset the char buffer if we change ordering criterion - m_search.clear(); + // reset the char buffer if we change ordering criterion + m_search.clear(); - // reload the menu with the new order - reset(reset_options::REMEMBER_REF); - machine().popmessage( - m_ordered_by_shortname - ? _("Switched Order: entries now ordered by shortname") - : _("Switched Order: entries now ordered by description")); - } - else if (ev->itemref) - { - // handle selections - entry_info *info = (entry_info *)ev->itemref; - m_result = info->short_name; - stack_pop(); - } + // reload the menu with the new order + reset(reset_options::REMEMBER_REF); + machine().popmessage( + m_ordered_by_shortname + ? _("Switched Order: entries now ordered by shortname") + : _("Switched Order: entries now ordered by description")); } - else if (ev->iptkey == IPT_UI_PASTE) + else if (ev->itemref) { - if (paste_text(m_search, m_ordered_by_shortname ? is_valid_softlist_part_char : uchar_is_printable)) - update_search(ev->itemref); + // handle selections + entry_info *info = (entry_info *)ev->itemref; + m_result = info->short_name; + stack_pop(); } - else if (ev->iptkey == IPT_SPECIAL) + return false; + } + else if (ev->iptkey == IPT_UI_PASTE) + { + if (paste_text(m_search, m_ordered_by_shortname ? is_valid_softlist_part_char : uchar_is_printable)) { - if (input_character(m_search, ev->unichar, m_ordered_by_shortname ? is_valid_softlist_part_char : uchar_is_printable)) - update_search(ev->itemref); + update_search(ev->itemref); + return true; } - else if (ev->iptkey == IPT_UI_CANCEL) + else { - // reset the char buffer also in this case - if (!m_search.empty()) - { - m_search.clear(); - ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_search); - } + return false; } } + else if (ev->iptkey == IPT_SPECIAL) + { + if (input_character(m_search, ev->unichar, m_ordered_by_shortname ? is_valid_softlist_part_char : uchar_is_printable)) + { + update_search(ev->itemref); + return true; + } + else + { + return false; + } + } + else if (ev->iptkey == IPT_UI_CANCEL) + { + // reset the char buffer also in this case + if (!m_search.empty()) + { + m_search.clear(); + ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_search); + return true; + } + else + { + return false; + } + } + else + { + return false; + } } @@ -420,15 +445,16 @@ void menu_software::populate() // handle //------------------------------------------------- -void menu_software::handle(event const *ev) +bool menu_software::handle(event const *ev) { - // process the menu if (ev && (ev->iptkey == IPT_UI_SELECT)) { //menu::stack_push<menu_software_list>(ui(), container(), (software_list_config *)ev->itemref, image); *m_result = reinterpret_cast<software_list_device *>(ev->itemref); stack_pop(); } + + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/swlist.h b/src/frontend/mame/ui/swlist.h index ab913373115..891d81e054b 100644 --- a/src/frontend/mame/ui/swlist.h +++ b/src/frontend/mame/ui/swlist.h @@ -44,7 +44,7 @@ private: using entry_list = std::list<software_part_menu_entry>; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // variables entry_list m_entries; @@ -89,7 +89,7 @@ private: bool m_ordered_by_shortname; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; // functions void append_software_entry(const software_info &swinfo); @@ -105,7 +105,7 @@ public: menu_software(mame_ui_manager &mui, render_container &container, const char *interface, software_list_device **result); virtual ~menu_software() override; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; private: const char * m_interface; diff --git a/src/frontend/mame/ui/tapectrl.cpp b/src/frontend/mame/ui/tapectrl.cpp index f41a52addd5..c302577cc63 100644 --- a/src/frontend/mame/ui/tapectrl.cpp +++ b/src/frontend/mame/ui/tapectrl.cpp @@ -118,7 +118,7 @@ void menu_tape_control::populate() // handle - main tape control menu //------------------------------------------------- -void menu_tape_control::handle(event const *ev) +bool menu_tape_control::handle(event const *ev) { // process the menu if (ev) @@ -158,6 +158,7 @@ void menu_tape_control::handle(event const *ev) // hacky way to update the tape counter by repopulating every frame reset(reset_options::REMEMBER_POSITION); + return false; } diff --git a/src/frontend/mame/ui/tapectrl.h b/src/frontend/mame/ui/tapectrl.h index 5a7fba62b64..f03fe371dda 100644 --- a/src/frontend/mame/ui/tapectrl.h +++ b/src/frontend/mame/ui/tapectrl.h @@ -26,7 +26,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool 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 e3cb88cdd36..065fca79101 100644 --- a/src/frontend/mame/ui/textbox.cpp +++ b/src/frontend/mame/ui/textbox.cpp @@ -102,33 +102,36 @@ void menu_textbox::reset_layout() } -void menu_textbox::handle_key(int key) +bool menu_textbox::handle_key(int key) { switch (key) { case IPT_UI_UP: --m_top_line; - break; + return true; case IPT_UI_DOWN: ++m_top_line; - break; + return true; case IPT_UI_PAGE_UP: m_top_line -= m_window_lines - 3; - break; + return true; case IPT_UI_PAGE_DOWN: m_top_line += m_window_lines - 3; - break; + return true; case IPT_UI_HOME: m_top_line = 0; - break; + return true; case IPT_UI_END: m_top_line = m_layout->lines() - m_window_lines; - break; + return true; + + default: + return false; } } @@ -365,10 +368,9 @@ void menu_fixed_textbox::populate() } -void menu_fixed_textbox::handle(event const *ev) +bool menu_fixed_textbox::handle(event const *ev) { - if (ev) - handle_key(ev->iptkey); + return ev && handle_key(ev->iptkey); } } // namespace ui diff --git a/src/frontend/mame/ui/textbox.h b/src/frontend/mame/ui/textbox.h index f7993f79121..af755761d4b 100644 --- a/src/frontend/mame/ui/textbox.h +++ b/src/frontend/mame/ui/textbox.h @@ -28,7 +28,7 @@ protected: menu_textbox(mame_ui_manager &mui, render_container &container); void reset_layout(); - void handle_key(int key); + bool handle_key(int key); virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) = 0; @@ -65,7 +65,7 @@ protected: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; std::string const m_heading; std::string const m_content; diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp index fc7c6f43298..37f60a8795d 100644 --- a/src/frontend/mame/ui/ui.cpp +++ b/src/frontend/mame/ui/ui.cpp @@ -175,7 +175,6 @@ mame_ui_manager::mame_ui_manager(running_machine &machine) , m_font() , m_handler_callback() , m_handler_callback_type(ui_callback_type::GENERAL) - , m_handler_param(0) , m_single_step(false) , m_showfps(false) , m_showfps_end(0) @@ -184,6 +183,8 @@ mame_ui_manager::mame_ui_manager(running_machine &machine) , m_mouse_bitmap(32, 32) , m_mouse_arrow_texture(nullptr) , m_mouse_show(false) + , m_mouse_target(-1) + , m_mouse_position(0, 0) , m_target_font_height(0) , m_has_warnings(false) , m_unthrottle_mute(false) @@ -439,17 +440,17 @@ void mame_ui_manager::display_startup_screens(bool first_time) { // if the user cancels, exit out completely machine().schedule_exit(); - return UI_HANDLER_CANCEL; + return HANDLER_CANCEL; } else if (machine().ui_input().pressed(IPT_UI_MENU)) { config_menu = true; - return UI_HANDLER_CANCEL; + return HANDLER_CANCEL; } else if (poller.poll() != INPUT_CODE_INVALID) { // if any key is pressed, just exit - return UI_HANDLER_CANCEL; + return HANDLER_CANCEL; } return 0; @@ -632,7 +633,7 @@ void mame_ui_manager::set_startup_text(const char *text, bool force) // render it; called by video.c //------------------------------------------------- -void mame_ui_manager::update_and_render(render_container &container) +bool mame_ui_manager::update_and_render(render_container &container) { // always start clean container.empty(); @@ -668,7 +669,7 @@ void mame_ui_manager::update_and_render(render_container &container) mame_machine_manager::instance()->cheat().render_text(*this, container); // call the current UI handler - m_handler_param = m_handler_callback(container); + uint32_t const handler_result = m_handler_callback(container); // display any popup messages if (osd_ticks() < m_popup_text_end) @@ -677,28 +678,42 @@ void mame_ui_manager::update_and_render(render_container &container) m_popup_text_end = 0; // display the internal mouse cursor + bool mouse_moved = false; if (m_mouse_show || (is_menu_active() && machine().options().ui_mouse())) { int32_t mouse_target_x, mouse_target_y; bool mouse_button; - render_target *mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button); + render_target *const mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button); - if (mouse_target != nullptr) + float mouse_y = -1, mouse_x = -1; + if (mouse_target && mouse_target->map_point_container(mouse_target_x, mouse_target_y, container, mouse_x, mouse_y)) { - float mouse_y=-1,mouse_x=-1; - if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, container, mouse_x, mouse_y)) + const float cursor_size = 0.6 * get_line_height(); + container.add_quad(mouse_x, mouse_y, mouse_x + cursor_size * container.manager().ui_aspect(&container), mouse_y + cursor_size, colors().text_color(), m_mouse_arrow_texture, PRIMFLAG_ANTIALIAS(1) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + if ((m_mouse_target != mouse_target->index()) || (std::make_pair(mouse_x, mouse_y) != m_mouse_position)) { - const float cursor_size = 0.6 * get_line_height(); - container.add_quad(mouse_x, mouse_y, mouse_x + cursor_size * container.manager().ui_aspect(&container), mouse_y + cursor_size, colors().text_color(), m_mouse_arrow_texture, PRIMFLAG_ANTIALIAS(1) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); + m_mouse_target = mouse_target->index(); + m_mouse_position = std::make_pair(mouse_x, mouse_y); + mouse_moved = true; } } + else if (0 <= m_mouse_target) + { + m_mouse_target = -1; + mouse_moved = true; + } } - - // cancel takes us back to the ingame handler - if (m_handler_param == UI_HANDLER_CANCEL) + else if (0 <= m_mouse_target) { - set_handler(ui_callback_type::GENERAL, handler_callback_func(&mame_ui_manager::handler_ingame, this)); + m_mouse_target = -1; + mouse_moved = true; } + + // cancel takes us back to the in-game handler + if (handler_result & HANDLER_CANCEL) + set_handler(ui_callback_type::GENERAL, handler_callback_func(&mame_ui_manager::handler_ingame, this)); + + return mouse_moved || (handler_result & HANDLER_UPDATE); } diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h index 46a5ae4c383..a4056e796a2 100644 --- a/src/frontend/mame/ui/ui.h +++ b/src/frontend/mame/ui/ui.h @@ -57,9 +57,6 @@ class laserdisc_device; #define UI_YELLOW_COLOR rgb_t(0xef,0xcc,0x7a,0x28) #define UI_RED_COLOR rgb_t(0xef,0xb2,0x00,0x00) -/* cancel return value for a UI handler */ -#define UI_HANDLER_CANCEL ((uint32_t)~0) - /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ @@ -122,6 +119,12 @@ private: class mame_ui_manager : public ui_manager { public: + enum : uint32_t + { + HANDLER_UPDATE = 1U << 0, // force video update + HANDLER_CANCEL = 1U << 1 // return to in-game event handler + }; + enum draw_mode { NONE, @@ -151,7 +154,7 @@ public: void display_startup_screens(bool first_time); virtual void set_startup_text(const char *text, bool force) override; - void update_and_render(render_container &container); + bool update_and_render(render_container &container); render_font *get_font(); float get_line_height(float scale = 1.0F); float get_char_width(char32_t ch); @@ -237,16 +240,19 @@ private: std::unique_ptr<render_font> m_font; handler_callback_func m_handler_callback; ui_callback_type m_handler_callback_type; - uint32_t m_handler_param; bool m_single_step; bool m_showfps; osd_ticks_t m_showfps_end; bool m_show_profiler; osd_ticks_t m_popup_text_end; std::unique_ptr<uint8_t []> m_non_char_keys_down; + bitmap_argb32 m_mouse_bitmap; render_texture * m_mouse_arrow_texture; bool m_mouse_show; + int m_mouse_target; + std::pair<float, float> m_mouse_position; + ui_options m_ui_options; ui_colors m_ui_colors; float m_target_font_height; diff --git a/src/frontend/mame/ui/utils.cpp b/src/frontend/mame/ui/utils.cpp index aaafd1944ba..a0fe2a58c97 100644 --- a/src/frontend/mame/ui/utils.cpp +++ b/src/frontend/mame/ui/utils.cpp @@ -404,7 +404,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; bool set_filter_type(unsigned pos, typename Base::type n) { @@ -556,110 +556,111 @@ void composite_filter_impl_base<Impl, Base, Type>::menu_configure::populate() } template <class Impl, class Base, typename Base::type Type> -void composite_filter_impl_base<Impl, Base, Type>::menu_configure::handle(event const *ev) +bool composite_filter_impl_base<Impl, Base, Type>::menu_configure::handle(event const *ev) { - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + m_added = false; + bool changed(false); + uintptr_t const ref(reinterpret_cast<uintptr_t>(ev->itemref)); + switch (ev->iptkey) { - m_added = false; - bool changed(false); - uintptr_t const ref(reinterpret_cast<uintptr_t>(ev->itemref)); - switch (ev->iptkey) + case IPT_UI_LEFT: + case IPT_UI_RIGHT: + if ((FILTER_FIRST <= ref) && (FILTER_LAST >= ref)) { - case IPT_UI_LEFT: - case IPT_UI_RIGHT: - if ((FILTER_FIRST <= ref) && (FILTER_LAST >= ref)) + // change filter type + unsigned const pos(ref - FILTER_FIRST); + typename Base::type const current(m_parent.m_filters[pos]->get_type()); + if (IPT_UI_LEFT == ev->iptkey) { - // change filter type - unsigned const pos(ref - FILTER_FIRST); - typename Base::type const current(m_parent.m_filters[pos]->get_type()); - if (IPT_UI_LEFT == ev->iptkey) + typename Base::type n(current); + while ((Base::FIRST < n) && !changed) { - typename Base::type n(current); - while ((Base::FIRST < n) && !changed) - { - if (m_parent.check_type(pos, --n)) - changed = set_filter_type(pos, n); - } - } - else - { - typename Base::type n(current); - while ((Base::LAST > n) && !changed) - { - if (m_parent.check_type(pos, ++n)) - changed = set_filter_type(pos, n); - } + if (m_parent.check_type(pos, --n)) + changed = set_filter_type(pos, n); } } - else if ((ADJUST_FIRST <= ref) && (ADJUST_LAST >= ref)) + else { - // change filter value - Base &pos(*m_parent.m_filters[ref - ADJUST_FIRST]); - changed = (IPT_UI_LEFT == ev->iptkey) ? pos.adjust_left() : pos.adjust_right(); + typename Base::type n(current); + while ((Base::LAST > n) && !changed) + { + if (m_parent.check_type(pos, ++n)) + changed = set_filter_type(pos, n); + } } - break; + } + else if ((ADJUST_FIRST <= ref) && (ADJUST_LAST >= ref)) + { + // change filter value + Base &pos(*m_parent.m_filters[ref - ADJUST_FIRST]); + changed = (IPT_UI_LEFT == ev->iptkey) ? pos.adjust_left() : pos.adjust_right(); + } + break; - case IPT_UI_SELECT: - if ((FILTER_FIRST <= ref) && (FILTER_LAST >= ref)) + case IPT_UI_SELECT: + if ((FILTER_FIRST <= ref) && (FILTER_LAST >= ref)) + { + // show selector with non-contradictory types + std::vector<typename Base::type> types; + std::vector<std::string> names; + types.reserve(Base::COUNT); + names.reserve(Base::COUNT); + int sel(-1); + unsigned const pos(ref - FILTER_FIRST); + typename Base::type const current(m_parent.m_filters[pos]->get_type()); + for (typename Base::type candidate = Base::FIRST; Base::COUNT > candidate; ++candidate) { - // show selector with non-contradictory types - std::vector<typename Base::type> types; - std::vector<std::string> names; - types.reserve(Base::COUNT); - names.reserve(Base::COUNT); - int sel(-1); - unsigned const pos(ref - FILTER_FIRST); - typename Base::type const current(m_parent.m_filters[pos]->get_type()); - for (typename Base::type candidate = Base::FIRST; Base::COUNT > candidate; ++candidate) + if (Impl::type_allowed(pos, candidate)) { - if (Impl::type_allowed(pos, candidate)) + if (current == candidate) + sel = types.size(); + unsigned i = 0; + while ((MAX > i) && m_parent.m_filters[i] && ((pos == i) || !Impl::types_contradictory(m_parent.m_filters[i]->get_type(), candidate))) + ++i; + if ((MAX <= i) || !m_parent.m_filters[i]) { - if (current == candidate) - sel = types.size(); - unsigned i = 0; - while ((MAX > i) && m_parent.m_filters[i] && ((pos == i) || !Impl::types_contradictory(m_parent.m_filters[i]->get_type(), candidate))) - ++i; - if ((MAX <= i) || !m_parent.m_filters[i]) - { - types.emplace_back(candidate); - names.emplace_back(Base::display_name(candidate)); - } + types.emplace_back(candidate); + names.emplace_back(Base::display_name(candidate)); } } - menu::stack_push<menu_selector>( - ui(), - container(), - std::string(ev->item->text()), - std::move(names), - sel, - [this, pos, t = std::move(types)] (int selection) - { - if (set_filter_type(pos, t[selection])) - reset(reset_options::REMEMBER_REF); - }); - } - else if ((ADJUST_FIRST <= ref) && (ADJUST_LAST >= ref)) - { - // show selected filter's UI - m_parent.m_filters[ref - ADJUST_FIRST]->show_ui(ui(), container(), [this] (Base &filter) { reset(reset_options::REMEMBER_REF); }); } - else if (REMOVE_FILTER == ref) - { - changed = drop_last_filter(); - } - else if (ADD_FILTER == ref) - { - m_added = append_filter(); - } - break; + menu::stack_push<menu_selector>( + ui(), + container(), + std::string(ev->item->text()), + std::move(names), + sel, + [this, pos, t = std::move(types)] (int selection) + { + if (set_filter_type(pos, t[selection])) + reset(reset_options::REMEMBER_REF); + }); } - - // rebuild if anything changed - if (changed) - reset(reset_options::REMEMBER_REF); - else if (m_added) - reset(reset_options::SELECT_FIRST); + else if ((ADJUST_FIRST <= ref) && (ADJUST_LAST >= ref)) + { + // show selected filter's UI + m_parent.m_filters[ref - ADJUST_FIRST]->show_ui(ui(), container(), [this] (Base &filter) { reset(reset_options::REMEMBER_REF); }); + } + else if (REMOVE_FILTER == ref) + { + changed = drop_last_filter(); + } + else if (ADD_FILTER == ref) + { + m_added = append_filter(); + } + break; } + + // rebuild if anything changed + if (changed) + reset(reset_options::REMEMBER_REF); + else if (m_added) + reset(reset_options::SELECT_FIRST); + return false; } @@ -996,7 +997,7 @@ private: }; virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; category_machine_filter &m_parent; std::function<void (machine_filter &)> m_handler; @@ -1074,105 +1075,106 @@ void category_machine_filter::menu_configure::populate() item_append(menu_item_type::SEPARATOR); } -void category_machine_filter::menu_configure::handle(event const *ev) +bool category_machine_filter::menu_configure::handle(event const *ev) { - if (ev && ev->itemref) + if (!ev || !ev->itemref) + return false; + + bool changed(false); + uintptr_t const ref(reinterpret_cast<uintptr_t>(ev->itemref)); + inifile_manager const &mgr(mame_machine_manager::instance()->inifile()); + switch (ev->iptkey) { - bool changed(false); - uintptr_t const ref(reinterpret_cast<uintptr_t>(ev->itemref)); - inifile_manager const &mgr(mame_machine_manager::instance()->inifile()); - switch (ev->iptkey) + case IPT_UI_LEFT: + if ((INI_FILE == ref) && m_ini) { - case IPT_UI_LEFT: - if ((INI_FILE == ref) && m_ini) - { - --m_ini; - changed = true; - } - else if ((SYSTEM_GROUP == ref) && m_state[m_ini].first) - { - --m_state[m_ini].first; - changed = true; - } - else if ((INCLUDE_CLONES == ref) && m_state[m_ini].second) - { - m_state[m_ini].second = false; - changed = true; - } - break; - case IPT_UI_RIGHT: - if ((INI_FILE == ref) && (mgr.get_file_count() > (m_ini + 1))) - { - ++m_ini; - changed = true; - } - else if ((SYSTEM_GROUP == ref) && (mgr.get_category_count(m_ini) > (m_state[m_ini].first + 1))) - { - ++m_state[m_ini].first; - changed = true; - } - else if ((INCLUDE_CLONES == ref) && !m_state[m_ini].second) - { - m_state[m_ini].second = true; - changed = true; - } - break; + --m_ini; + changed = true; + } + else if ((SYSTEM_GROUP == ref) && m_state[m_ini].first) + { + --m_state[m_ini].first; + changed = true; + } + else if ((INCLUDE_CLONES == ref) && m_state[m_ini].second) + { + m_state[m_ini].second = false; + changed = true; + } + break; + case IPT_UI_RIGHT: + if ((INI_FILE == ref) && (mgr.get_file_count() > (m_ini + 1))) + { + ++m_ini; + changed = true; + } + else if ((SYSTEM_GROUP == ref) && (mgr.get_category_count(m_ini) > (m_state[m_ini].first + 1))) + { + ++m_state[m_ini].first; + changed = true; + } + else if ((INCLUDE_CLONES == ref) && !m_state[m_ini].second) + { + m_state[m_ini].second = true; + changed = true; + } + break; - case IPT_UI_SELECT: - if (INI_FILE == ref) - { - std::vector<std::string> choices; - choices.reserve(mgr.get_file_count()); - for (size_t i = 0; mgr.get_file_count() > i; ++i) - choices.emplace_back(mgr.get_file_name(i)); - menu::stack_push<menu_selector>( - ui(), - container(), - _("Category File"), - std::move(choices), - m_ini, - [this] (int selection) + case IPT_UI_SELECT: + if (INI_FILE == ref) + { + std::vector<std::string> choices; + choices.reserve(mgr.get_file_count()); + for (size_t i = 0; mgr.get_file_count() > i; ++i) + choices.emplace_back(mgr.get_file_name(i)); + menu::stack_push<menu_selector>( + ui(), + container(), + _("Category File"), + std::move(choices), + m_ini, + [this] (int selection) + { + if (selection != m_ini) { - if (selection != m_ini) - { - m_ini = selection; - reset(reset_options::REMEMBER_REF); - } - }); - } - else if (SYSTEM_GROUP == ref) - { - std::vector<std::string> choices; - choices.reserve(mgr.get_category_count(m_ini)); - for (size_t i = 0; mgr.get_category_count(m_ini) > i; ++i) - choices.emplace_back(mgr.get_category_name(m_ini, i)); - menu::stack_push<menu_selector>( - ui(), - container(), - _("Group"), - std::move(choices), - m_state[m_ini].first, - [this] (int selection) + m_ini = selection; + reset(reset_options::REMEMBER_REF); + } + }); + } + else if (SYSTEM_GROUP == ref) + { + std::vector<std::string> choices; + choices.reserve(mgr.get_category_count(m_ini)); + for (size_t i = 0; mgr.get_category_count(m_ini) > i; ++i) + choices.emplace_back(mgr.get_category_name(m_ini, i)); + menu::stack_push<menu_selector>( + ui(), + container(), + _("Group"), + std::move(choices), + m_state[m_ini].first, + [this] (int selection) + { + if (selection != m_state[m_ini].first) { - if (selection != m_state[m_ini].first) - { - m_state[m_ini].first = selection; - reset(reset_options::REMEMBER_REF); - } - }); - } - else if (INCLUDE_CLONES == ref) - { - m_state[m_ini].second = !m_state[m_ini].second; - reset(reset_options::REMEMBER_REF); - } - break; + m_state[m_ini].first = selection; + reset(reset_options::REMEMBER_REF); + } + }); } - - // rebuild if anything changed - if (changed) + else if (INCLUDE_CLONES == ref) + { + m_state[m_ini].second = !m_state[m_ini].second; reset(reset_options::REMEMBER_REF); + } + break; } + + // rebuild if anything changed + if (changed) + reset(reset_options::REMEMBER_REF); + return false; } diff --git a/src/frontend/mame/ui/videoopt.cpp b/src/frontend/mame/ui/videoopt.cpp index 0aafba84d26..95ffca3e5e9 100644 --- a/src/frontend/mame/ui/videoopt.cpp +++ b/src/frontend/mame/ui/videoopt.cpp @@ -70,7 +70,7 @@ void menu_video_targets::populate() menu -------------------------------------------------*/ -void menu_video_targets::handle(event const *ev) +bool menu_video_targets::handle(event const *ev) { if (ev && (ev->iptkey == IPT_UI_SELECT)) { @@ -82,6 +82,8 @@ void menu_video_targets::handle(event const *ev) *target, &machine().video().snapshot_target() == target); } + + return false; } @@ -200,9 +202,14 @@ void menu_video_options::populate() menu -------------------------------------------------*/ -void menu_video_options::handle(event const *ev) +bool menu_video_options::handle(event const *ev) { - auto const lockout_popup([this] () { machine().popmessage(_("Cannot change options while recording!")); }); + auto const lockout_popup( + [this] () + { + machine().popmessage(_("Cannot change options while recording!")); + return true; + }); bool const snap_lockout(m_snapshot && machine().video().is_recording()); bool changed(false); @@ -340,6 +347,7 @@ void menu_video_options::handle(event const *ev) // if something changed, rebuild the menu if (changed) reset(reset_options::REMEMBER_REF); + return false; } } // namespace ui diff --git a/src/frontend/mame/ui/videoopt.h b/src/frontend/mame/ui/videoopt.h index cea2f231073..a725cba0f71 100644 --- a/src/frontend/mame/ui/videoopt.h +++ b/src/frontend/mame/ui/videoopt.h @@ -27,7 +27,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; }; @@ -39,7 +39,7 @@ public: private: virtual void populate() override; - virtual void handle(event const *ev) override; + virtual bool handle(event const *ev) override; render_target &m_target; bool const m_snapshot; diff --git a/src/frontend/mame/ui/viewgfx.cpp b/src/frontend/mame/ui/viewgfx.cpp index 4c57e569e10..c4a6ecdbf68 100644 --- a/src/frontend/mame/ui/viewgfx.cpp +++ b/src/frontend/mame/ui/viewgfx.cpp @@ -544,7 +544,7 @@ private: m_machine.resume(); m_machine.ui_input().reset(); m_bitmap_dirty = true; - return UI_HANDLER_CANCEL; + return mame_ui_manager::HANDLER_CANCEL; } uint32_t handle_palette(mame_ui_manager &mui, render_container &container, bool uistate); diff --git a/src/osd/mac/osdmac.h b/src/osd/mac/osdmac.h index aa7d9086215..1b8fc86f393 100644 --- a/src/osd/mac/osdmac.h +++ b/src/osd/mac/osdmac.h @@ -44,7 +44,7 @@ public: // general overridables virtual void init(running_machine &machine) override; virtual void update(bool skip_redraw) override; - virtual void input_update() override; + virtual void input_update(bool relative_reset) override; virtual void check_osd_inputs() override; // input overridables diff --git a/src/osd/mac/video.cpp b/src/osd/mac/video.cpp index b0eed52a1c3..e5feba57f76 100644 --- a/src/osd/mac/video.cpp +++ b/src/osd/mac/video.cpp @@ -122,12 +122,12 @@ void mac_osd_interface::update(bool skip_redraw) // input_update //============================================================ -void mac_osd_interface::input_update() +void mac_osd_interface::input_update(bool relative_reset) { // poll the joystick values here process_events_buf(); MacPollInputs(); - poll_input_modules(); + poll_input_modules(relative_reset); } //============================================================ diff --git a/src/osd/modules/debugger/debugwin.cpp b/src/osd/modules/debugger/debugwin.cpp index 220d0c96e3b..43d20ae371d 100644 --- a/src/osd/modules/debugger/debugwin.cpp +++ b/src/osd/modules/debugger/debugwin.cpp @@ -195,7 +195,7 @@ void debugger_windows::wait_for_debugger(device_t &device, bool firststop) show_all(); // run input polling to ensure that our status is in sync - downcast<windows_osd_interface&>(machine().osd()).poll_input_modules(); + downcast<windows_osd_interface&>(machine().osd()).poll_input_modules(false); // get and process messages MSG message; diff --git a/src/osd/modules/input/input_common.cpp b/src/osd/modules/input/input_common.cpp index 53f053e6d1b..ec9521ab4b8 100644 --- a/src/osd/modules/input/input_common.cpp +++ b/src/osd/modules/input/input_common.cpp @@ -286,16 +286,16 @@ void input_module_base::input_init(running_machine &machine) m_manager = &machine.input(); } -void input_module_base::poll_if_necessary() +void input_module_base::poll_if_necessary(bool relative_reset) { timepoint_type const now = m_clock.now(); - if (now >= (m_last_poll + std::chrono::milliseconds(MIN_POLLING_INTERVAL))) + if (relative_reset || (now >= (m_last_poll + std::chrono::milliseconds(MIN_POLLING_INTERVAL)))) { // grab the current time m_last_poll = now; before_poll(); - poll(); + poll(relative_reset); } } diff --git a/src/osd/modules/input/input_common.h b/src/osd/modules/input/input_common.h index 2893e1c8aee..e767d2b07f2 100644 --- a/src/osd/modules/input/input_common.h +++ b/src/osd/modules/input/input_common.h @@ -226,7 +226,7 @@ public: input_module &module() const { return m_module; } // Poll and reset methods - virtual void poll() { } + virtual void poll(bool relative_reset) = 0; virtual void reset() = 0; virtual void configure(osd::input_device &device) = 0; }; @@ -266,7 +266,7 @@ public: m_event_queue.pop(); } - void virtual poll() override + void virtual poll(bool relative_reset) override { std::lock_guard<std::mutex> scope_lock(m_device_lock); @@ -296,10 +296,10 @@ public: auto begin() const { return m_list.begin(); } auto end() const { return m_list.end(); } - void poll_devices() + void poll_devices(bool relative_reset) { for (auto &device: m_list) - device->poll(); + device->poll(relative_reset); } void reset_devices() @@ -408,7 +408,7 @@ private: const osd_options * m_options; osd::input_manager * m_manager; - virtual void poll() = 0; + virtual void poll(bool relative_reset) = 0; protected: input_module_base(char const *type, char const *name); @@ -423,7 +423,7 @@ public: virtual int init(osd_interface &osd, const osd_options &options) override; virtual void input_init(running_machine &machine) override; - virtual void poll_if_necessary() override; + virtual void poll_if_necessary(bool relative_reset) override; virtual void reset_devices() = 0; // SDL OSD uses this to forcibly release keys }; @@ -490,11 +490,11 @@ protected: } private: - virtual void poll() override final + virtual void poll(bool relative_reset) override final { // poll all of the devices if (should_poll_devices()) - m_devicelist.poll_devices(); + m_devicelist.poll_devices(relative_reset); else m_devicelist.reset_devices(); } diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp index ce19ed88dfe..1ec3c85a886 100644 --- a/src/osd/modules/input/input_dinput.cpp +++ b/src/osd/modules/input/input_dinput.cpp @@ -163,7 +163,7 @@ public: DIDEVCAPS const &caps, LPCDIDATAFORMAT format); - virtual void poll() override; + virtual void poll(bool relative_reset) override; virtual void reset() override; virtual void configure(input_device &device) override; @@ -184,7 +184,7 @@ dinput_keyboard_device::dinput_keyboard_device( { } -void dinput_keyboard_device::poll() +void dinput_keyboard_device::poll(bool relative_reset) { // poll the DirectInput immediate state std::lock_guard<std::mutex> scope_lock(m_device_lock); @@ -233,7 +233,7 @@ public: DIDEVCAPS const &caps, LPCDIDATAFORMAT format); - void poll() override; + void poll(bool relative_reset) override; void reset() override; virtual void configure(input_device &device) override; @@ -256,10 +256,10 @@ dinput_mouse_device::dinput_mouse_device( m_caps.dwButtons = std::min(m_caps.dwButtons, DWORD((m_format == &c_dfDIMouse) ? 4 : 8)); } -void dinput_mouse_device::poll() +void dinput_mouse_device::poll(bool relative_reset) { // poll - if (poll_dinput(&m_mouse) == DI_OK) + if (relative_reset && (poll_dinput(&m_mouse) == DI_OK)) { // scale the axis data m_mouse.lX *= input_device::RELATIVE_PER_PIXEL; @@ -566,7 +566,7 @@ void dinput_joystick_device::reset() std::fill(std::begin(m_joystick.state.rgdwPOV), std::end(m_joystick.state.rgdwPOV), 0xffff); } -void dinput_joystick_device::poll() +void dinput_joystick_device::poll(bool relative_reset) { // poll the device first if (dinput_device::poll_dinput(&m_joystick.state) == DI_OK) diff --git a/src/osd/modules/input/input_dinput.h b/src/osd/modules/input/input_dinput.h index a5d6877723e..3ee60c530aa 100644 --- a/src/osd/modules/input/input_dinput.h +++ b/src/osd/modules/input/input_dinput.h @@ -160,7 +160,7 @@ public: LPCDIDATAFORMAT format); void reset() override; - void poll() override; + void poll(bool relative_reset) override; void configure(input_device &device) override; private: diff --git a/src/osd/modules/input/input_module.h b/src/osd/modules/input/input_module.h index 115a56294ce..64e5ebb2332 100644 --- a/src/osd/modules/input/input_module.h +++ b/src/osd/modules/input/input_module.h @@ -21,7 +21,7 @@ public: virtual ~input_module() = default; virtual void input_init(running_machine &machine) = 0; - virtual void poll_if_necessary() = 0; + virtual void poll_if_necessary(bool relative_reset) = 0; }; //============================================================ diff --git a/src/osd/modules/input/input_none.cpp b/src/osd/modules/input/input_none.cpp index 3110f6a3e5d..96c3f116868 100644 --- a/src/osd/modules/input/input_none.cpp +++ b/src/osd/modules/input/input_none.cpp @@ -19,7 +19,7 @@ public: keyboard_input_none() : osd_module(OSD_KEYBOARDINPUT_PROVIDER, "none") { } int init(osd_interface &osd, const osd_options &options) override { return 0; } void input_init(running_machine &machine) override { } - void poll_if_necessary() override { } + void poll_if_necessary(bool relative_reset) override { } }; @@ -29,7 +29,7 @@ public: mouse_input_none() : osd_module(OSD_MOUSEINPUT_PROVIDER, "none") { } int init(osd_interface &osd, const osd_options &options) override { return 0; } void input_init(running_machine &machine) override { } - void poll_if_necessary() override { } + void poll_if_necessary(bool relative_reset) override { } }; @@ -39,7 +39,7 @@ public: lightgun_input_none() : osd_module(OSD_LIGHTGUNINPUT_PROVIDER, "none") { } int init(osd_interface &osd, const osd_options &options) override { return 0; } void input_init(running_machine &machine) override { } - void poll_if_necessary() override { } + void poll_if_necessary(bool relative_reset) override { } }; @@ -49,7 +49,7 @@ public: joystick_input_none() : osd_module(OSD_JOYSTICKINPUT_PROVIDER, "none") { } int init(osd_interface &osd, const osd_options &options) override { return 0; } void input_init(running_machine &machine) override { } - void poll_if_necessary() override { } + void poll_if_necessary(bool relative_reset) override { } }; } // anonymous namesapce diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp index ca6522f20e2..3ee8e2d8f7e 100644 --- a/src/osd/modules/input/input_rawinput.cpp +++ b/src/osd/modules/input/input_rawinput.cpp @@ -367,22 +367,28 @@ class rawinput_mouse_device : public rawinput_device public: rawinput_mouse_device(std::string &&name, std::string &&id, input_module &module, HANDLE handle) : rawinput_device(std::move(name), std::move(id), module, handle), - m_mouse({0}) + m_mouse({0}), + m_x(0), + m_y(0), + m_z(0) { } - virtual void poll() override + virtual void poll(bool relative_reset) override { - m_mouse.lX = 0; - m_mouse.lY = 0; - m_mouse.lZ = 0; - - rawinput_device::poll(); + rawinput_device::poll(relative_reset); + if (relative_reset) + { + m_mouse.lX = std::exchange(m_x, 0); + m_mouse.lY = std::exchange(m_y, 0); + m_mouse.lZ = std::exchange(m_z, 0); + } } virtual void reset() override { memset(&m_mouse, 0, sizeof(m_mouse)); + m_x = m_y = m_z = 0; } virtual void configure(input_device &device) override @@ -417,12 +423,12 @@ public: if (rawinput.data.mouse.usFlags == MOUSE_MOVE_RELATIVE) { - m_mouse.lX += rawinput.data.mouse.lLastX * input_device::RELATIVE_PER_PIXEL; - m_mouse.lY += rawinput.data.mouse.lLastY * input_device::RELATIVE_PER_PIXEL; + m_x += rawinput.data.mouse.lLastX * input_device::RELATIVE_PER_PIXEL; + m_y += rawinput.data.mouse.lLastY * input_device::RELATIVE_PER_PIXEL; - // update zaxis + // update Z axis (vertical scroll) if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) - m_mouse.lZ += int16_t(rawinput.data.mouse.usButtonData) * input_device::RELATIVE_PER_PIXEL; + m_z += int16_t(rawinput.data.mouse.usButtonData) * input_device::RELATIVE_PER_PIXEL; // update the button states; always update the corresponding mouse buttons if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) m_mouse.rgbButtons[0] = 0x80; @@ -440,6 +446,7 @@ public: private: mouse_state m_mouse; + LONG m_x, m_y, m_z; }; @@ -452,20 +459,22 @@ class rawinput_lightgun_device : public rawinput_device public: rawinput_lightgun_device(std::string &&name, std::string &&id, input_module &module, HANDLE handle) : rawinput_device(std::move(name), std::move(id), module, handle), - m_lightgun({0}) + m_lightgun({0}), + m_z(0) { } - virtual void poll() override + virtual void poll(bool relative_reset) override { - m_lightgun.lZ = 0; - - rawinput_device::poll(); + rawinput_device::poll(relative_reset); + if (relative_reset) + m_lightgun.lZ = std::exchange(m_z, 0); } virtual void reset() override { memset(&m_lightgun, 0, sizeof(m_lightgun)); + m_z = 0; } virtual void configure(input_device &device) override @@ -513,7 +522,7 @@ public: // update zaxis if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) - m_lightgun.lZ += int16_t(rawinput.data.mouse.usButtonData) * input_device::RELATIVE_PER_PIXEL; + m_z += int16_t(rawinput.data.mouse.usButtonData) * input_device::RELATIVE_PER_PIXEL; // update the button states; always update the corresponding mouse buttons if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) m_lightgun.rgbButtons[0] = 0x80; @@ -531,6 +540,7 @@ public: private: mouse_state m_lightgun; + LONG m_z; }; diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp index ff52fbee478..1eaed99f16b 100644 --- a/src/osd/modules/input/input_sdl.cpp +++ b/src/osd/modules/input/input_sdl.cpp @@ -573,9 +573,9 @@ public: { } - virtual void poll() override + virtual void poll(bool relative_reset) override { - sdl_device::poll(); + sdl_device::poll(relative_reset); #ifdef __APPLE__ if (m_keyboard.state[SDL_SCANCODE_CAPSLOCK] && (std::chrono::steady_clock::now() > (m_capslock_pressed + std::chrono::milliseconds(30)))) @@ -655,22 +655,30 @@ class sdl_mouse_device : public sdl_device public: sdl_mouse_device(std::string &&name, std::string &&id, input_module &module) : sdl_device(std::move(name), std::move(id), module), - m_mouse({0}) + m_mouse({0}), + m_x(0), + m_y(0), + m_v(0), + m_h(0) { } - virtual void poll() override + virtual void poll(bool relative_reset) override { - m_mouse.lX = 0; - m_mouse.lY = 0; - m_mouse.lV = 0; - m_mouse.lH = 0; - sdl_device::poll(); + sdl_device::poll(relative_reset); + if (relative_reset) + { + m_mouse.lX = std::exchange(m_x, 0); + m_mouse.lY = std::exchange(m_y, 0); + m_mouse.lV = std::exchange(m_v, 0); + m_mouse.lH = std::exchange(m_h, 0); + } } virtual void reset() override { memset(&m_mouse, 0, sizeof(m_mouse)); + m_x = m_y = m_v = m_h = 0; } virtual void configure(input_device &device) override @@ -720,8 +728,8 @@ public: switch (event.type) { case SDL_MOUSEMOTION: - m_mouse.lX += event.motion.xrel * input_device::RELATIVE_PER_PIXEL; - m_mouse.lY += event.motion.yrel * input_device::RELATIVE_PER_PIXEL; + m_x += event.motion.xrel * input_device::RELATIVE_PER_PIXEL; + m_y += event.motion.yrel * input_device::RELATIVE_PER_PIXEL; break; case SDL_MOUSEBUTTONDOWN: @@ -734,11 +742,11 @@ public: case SDL_MOUSEWHEEL: #if SDL_VERSION_ATLEAST(2, 0, 18) - m_mouse.lV += event.wheel.preciseY * input_device::RELATIVE_PER_PIXEL; - m_mouse.lH += event.wheel.preciseX * input_device::RELATIVE_PER_PIXEL; + m_v += event.wheel.preciseY * input_device::RELATIVE_PER_PIXEL; + m_h += event.wheel.preciseX * input_device::RELATIVE_PER_PIXEL; #else - m_mouse.lV += event.wheel.y * input_device::RELATIVE_PER_PIXEL; - m_mouse.lH += event.wheel.x * input_device::RELATIVE_PER_PIXEL; + m_v += event.wheel.y * input_device::RELATIVE_PER_PIXEL; + m_h += event.wheel.x * input_device::RELATIVE_PER_PIXEL; #endif break; } @@ -753,6 +761,7 @@ private: }; mouse_state m_mouse; + s32 m_x, m_y, m_v, m_h; }; diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp index 5c584e33d93..6919c8d5c42 100644 --- a/src/osd/modules/input/input_win32.cpp +++ b/src/osd/modules/input/input_win32.cpp @@ -137,9 +137,12 @@ public: { } - virtual void poll() override + virtual void poll(bool relative_reset) override { - event_based_device::poll(); + event_based_device::poll(relative_reset); + + if (!relative_reset) + return; CURSORINFO cursor_info = {0}; cursor_info.cbSize = sizeof(CURSORINFO); @@ -202,10 +205,6 @@ protected: { // set the button state m_mouse.rgbButtons[args.button] = args.keydown ? 0x80 : 0x00; - - // Make sure we have a fresh mouse position on button down - if (args.keydown) - module().poll_if_necessary(); } private: @@ -322,9 +321,9 @@ public: { } - virtual void poll() override + virtual void poll(bool relative_reset) override { - event_based_device::poll(); + event_based_device::poll(relative_reset); int32_t xpos = 0, ypos = 0; diff --git a/src/osd/modules/input/input_xinput.cpp b/src/osd/modules/input/input_xinput.cpp index 783dc720994..ec3f956b909 100644 --- a/src/osd/modules/input/input_xinput.cpp +++ b/src/osd/modules/input/input_xinput.cpp @@ -713,7 +713,7 @@ public: XINPUT_CAPABILITIES const &caps, xinput_api_helper const &helper); - virtual void poll() override; + virtual void poll(bool relative_reset) override; virtual void reset() override; virtual void configure(input_device &device) override; @@ -805,7 +805,7 @@ xinput_joystick_device::xinput_joystick_device( } -void xinput_joystick_device::poll() +void xinput_joystick_device::poll(bool relative_reset) { // poll the device first, and skip if nothing changed if (!read_state()) @@ -1255,7 +1255,7 @@ public: XINPUT_CAPABILITIES const &caps, xinput_api_helper const &helper); - virtual void poll() override; + virtual void poll(bool relative_reset) override; virtual void reset() override; virtual void configure(input_device &device) override; @@ -1335,7 +1335,7 @@ xinput_flight_stick_device::xinput_flight_stick_device( } -void xinput_flight_stick_device::poll() +void xinput_flight_stick_device::poll(bool relative_reset) { // poll the device first, and skip if nothing changed if (!read_state()) @@ -1717,7 +1717,7 @@ public: XINPUT_CAPABILITIES const &caps, xinput_api_helper const &helper); - virtual void poll() override; + virtual void poll(bool relative_reset) override; virtual void reset() override; virtual void configure(input_device &device) override; @@ -1796,7 +1796,7 @@ xinput_guitar_device::xinput_guitar_device( } -void xinput_guitar_device::poll() +void xinput_guitar_device::poll(bool relative_reset) { // poll the device first, and skip if nothing changed if (!read_state()) @@ -2002,7 +2002,7 @@ public: XINPUT_CAPABILITIES const &caps, xinput_api_helper const &helper); - virtual void poll() override; + virtual void poll(bool relative_reset) override; virtual void reset() override; virtual void configure(input_device &device) override; @@ -2078,7 +2078,7 @@ xinput_drumkit_device::xinput_drumkit_device( } -void xinput_drumkit_device::poll() +void xinput_drumkit_device::poll(bool relative_reset) { // poll the device first, and skip if nothing changed if (!read_state()) @@ -2258,7 +2258,7 @@ public: XINPUT_CAPABILITIES const &caps, xinput_api_helper const &helper); - virtual void poll() override; + virtual void poll(bool relative_reset) override; virtual void reset() override; virtual void configure(input_device &device) override; @@ -2337,7 +2337,7 @@ xinput_turntable_device::xinput_turntable_device( } -void xinput_turntable_device::poll() +void xinput_turntable_device::poll(bool relative_reset) { // poll the device first bool const was_reset = is_reset(); @@ -2355,17 +2355,23 @@ void xinput_turntable_device::poll() m_axes[AXIS_TURNTABLE] = s32(thumb_left_y()) * input_device::RELATIVE_PER_PIXEL * 2; m_axes[AXIS_CROSSFADE] = normalize_absolute_axis(thumb_right_y(), XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE); - // convert effect dial value to relative displacement - s32 effect_delta = s32(u32(u16(thumb_right_x()))) - s32(u32(m_prev_effect)); - if (!was_reset) + // handle effect dial + if (was_reset) { + // just grab the current count after regaining focus + m_prev_effect = u16(thumb_right_x()); + } + else if (relative_reset) + { + // convert value to relative displacement + s32 effect_delta = s32(u32(u16(thumb_right_x()))) - s32(u32(m_prev_effect)); + m_prev_effect = u16(thumb_right_x()); if (0x8000 < effect_delta) effect_delta -= 0x1'0000; else if (-0x8000 > effect_delta) effect_delta += 0x1'0000; m_axes[AXIS_EFFECT] = effect_delta * input_device::RELATIVE_PER_PIXEL / 128; } - m_prev_effect = u16(thumb_right_x()); } else { @@ -2683,7 +2689,7 @@ public: XINPUT_CAPABILITIES const &caps, xinput_api_helper const &helper); - virtual void poll() override; + virtual void poll(bool relative_reset) override; virtual void reset() override; virtual void configure(input_device &device) override; @@ -2758,7 +2764,7 @@ xinput_keyboard_device::xinput_keyboard_device( } -void xinput_keyboard_device::poll() +void xinput_keyboard_device::poll(bool relative_reset) { // TODO: how many bits are really velocity? // TODO: how are touch strip and overdrive read? diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp index 7b93e1d5a37..6a2fef81e86 100644 --- a/src/osd/modules/lib/osdobj_common.cpp +++ b/src/osd/modules/lib/osdobj_common.cpp @@ -675,12 +675,12 @@ bool osd_common_t::input_init() return true; } -void osd_common_t::poll_input_modules() +void osd_common_t::poll_input_modules(bool relative_reset) { - m_keyboard_input->poll_if_necessary(); - m_mouse_input->poll_if_necessary(); - m_lightgun_input->poll_if_necessary(); - m_joystick_input->poll_if_necessary(); + m_keyboard_input->poll_if_necessary(relative_reset); + m_mouse_input->poll_if_necessary(relative_reset); + m_lightgun_input->poll_if_necessary(relative_reset); + m_joystick_input->poll_if_necessary(relative_reset); } void osd_common_t::exit_subsystems() diff --git a/src/osd/modules/lib/osdobj_common.h b/src/osd/modules/lib/osdobj_common.h index 0860d0d0288..d339a784dfa 100644 --- a/src/osd/modules/lib/osdobj_common.h +++ b/src/osd/modules/lib/osdobj_common.h @@ -279,7 +279,7 @@ protected: virtual void build_slider_list() { } virtual void update_slider_list() { } - void poll_input_modules(); + void poll_input_modules(bool relative_reset); static std::list<std::unique_ptr<osd_window> > s_window_list; diff --git a/src/osd/osdepend.h b/src/osd/osdepend.h index 99ad1dc8834..8f1d86bc816 100644 --- a/src/osd/osdepend.h +++ b/src/osd/osdepend.h @@ -66,7 +66,7 @@ public: // general overridables virtual void init(running_machine &machine) = 0; virtual void update(bool skip_redraw) = 0; - virtual void input_update() = 0; + virtual void input_update(bool relative_reset) = 0; virtual void check_osd_inputs() = 0; virtual void set_verbose(bool print_verbose) = 0; diff --git a/src/osd/sdl/osdsdl.cpp b/src/osd/sdl/osdsdl.cpp index 8df698d3e5b..070e0f338e0 100644 --- a/src/osd/sdl/osdsdl.cpp +++ b/src/osd/sdl/osdsdl.cpp @@ -294,10 +294,10 @@ void sdl_osd_interface::init(running_machine &machine) } -void sdl_osd_interface::input_update() +void sdl_osd_interface::input_update(bool relative_reset) { process_events_buf(); - poll_input_modules(); + poll_input_modules(relative_reset); } diff --git a/src/osd/sdl/osdsdl.h b/src/osd/sdl/osdsdl.h index 2d695d5dfde..c8ce167d699 100644 --- a/src/osd/sdl/osdsdl.h +++ b/src/osd/sdl/osdsdl.h @@ -145,7 +145,7 @@ public: // general overridables virtual void init(running_machine &machine) override; virtual void update(bool skip_redraw) override; - virtual void input_update() override; + virtual void input_update(bool relative_reset) override; virtual void check_osd_inputs() override; // input overridables diff --git a/src/osd/windows/video.cpp b/src/osd/windows/video.cpp index 14339614a0c..41e03770332 100644 --- a/src/osd/windows/video.cpp +++ b/src/osd/windows/video.cpp @@ -114,11 +114,11 @@ void windows_osd_interface::update(bool skip_redraw) // input_update //============================================================ -void windows_osd_interface::input_update() +void windows_osd_interface::input_update(bool relative_reset) { // poll the joystick values here process_events(true, false); - poll_input_modules(); + poll_input_modules(relative_reset); } //============================================================ diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h index a1797d9cc7e..22920b94bba 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -59,7 +59,7 @@ public: // general overridables virtual void init(running_machine &machine) override; virtual void update(bool skip_redraw) override; - virtual void input_update() override; + virtual void input_update(bool relative_reset) override; virtual void check_osd_inputs() override; // input overrideables |