From f5fb44a9dbd6f74d2015cc095e5a92199e2345e9 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sat, 22 Aug 2020 21:12:38 +1000 Subject: Cleaned up save/load state menu code. * Fixed display names for states saved with keyboard keys * Wait for at least one frame with no keys pressed before saving/loading. --- src/frontend/mame/ui/menuitem.h | 7 +- src/frontend/mame/ui/state.cpp | 167 ++++++++++++++++++++++------------------ src/frontend/mame/ui/state.h | 19 +++-- 3 files changed, 106 insertions(+), 87 deletions(-) diff --git a/src/frontend/mame/ui/menuitem.h b/src/frontend/mame/ui/menuitem.h index 0ba4629c93b..4900e78485b 100644 --- a/src/frontend/mame/ui/menuitem.h +++ b/src/frontend/mame/ui/menuitem.h @@ -9,13 +9,14 @@ ***************************************************************************/ -#pragma once - #ifndef MAME_FRONTEND_UI_MENUITEM_H #define MAME_FRONTEND_UI_MENUITEM_H +#pragma once + namespace ui { + // special menu item for separators #define MENU_SEPARATOR_ITEM "---" @@ -38,7 +39,7 @@ public: std::string text; std::string subtext; - uint32_t flags; + uint32_t flags; void *ref; menu_item_type type; // item type (eventually will go away when itemref is proper ui_menu_item class rather than void*) }; diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp index f66b5af4a9a..6939401d566 100644 --- a/src/frontend/mame/ui/state.cpp +++ b/src/frontend/mame/ui/state.cpp @@ -10,7 +10,9 @@ #include "emu.h" #include "ui/state.h" + #include "emuopts.h" +#include "inputdev.h" namespace ui { @@ -21,20 +23,6 @@ namespace ui { namespace { -const int MAX_SAVED_STATE_JOYSTICK = 4; - -//------------------------------------------------- -// keyboard_code -//------------------------------------------------- - -input_code keyboard_code(input_item_id id) -{ - // only supported for A-Z|0-9 - assert((id >= ITEM_ID_A && id <= ITEM_ID_Z) || (id >= ITEM_ID_0 && id <= ITEM_ID_9)); - return input_code(DEVICE_CLASS_KEYBOARD, 0, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, id); -} - - //------------------------------------------------- // keyboard_input_item_name //------------------------------------------------- @@ -57,20 +45,15 @@ std::string keyboard_input_item_name(input_item_id id) std::pair code_item_pair(const running_machine &machine, input_item_id id) { - // identify the input code name (translated appropriately) - input_code code = keyboard_code(id); - std::string code_name = machine.input().code_name(code); - strmakelower(code_name); - - // identify the keyboard item name - std::string input_item_name = keyboard_input_item_name(id); + // only supported for A-Z|0-9 + assert((id >= ITEM_ID_A && id <= ITEM_ID_Z) || (id >= ITEM_ID_0 && id <= ITEM_ID_9)); + input_code const code = input_code(DEVICE_CLASS_KEYBOARD, 0, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, id); - // return them - return std::make_pair(code_name, input_item_name); + return std::make_pair(keyboard_input_item_name(id), machine.input().code_name(code)); } +} // anonymous namespace -}; /*************************************************************************** FILE ENTRY @@ -104,8 +87,8 @@ menu_load_save_state_base::menu_load_save_state_base(mame_ui_manager &mui, rende , m_header(header) , m_footer(footer) , m_must_exist(must_exist) - , m_pause_checked(false) , m_was_paused(false) + , m_keys_released(false) { } @@ -139,11 +122,33 @@ void menu_load_save_state_base::populate(float &customtop, float &custombottom) m_filename_to_code_map.emplace(code_item_pair(machine(), id)); for (input_item_id id = ITEM_ID_0; id <= ITEM_ID_9; id++) m_filename_to_code_map.emplace(code_item_pair(machine(), id)); + + // do joysticks + input_class const &sticks = machine().input().device_class(DEVICE_CLASS_JOYSTICK); + if (sticks.enabled()) + { + for (int i = 0; sticks.maxindex() >= i; ++i) + { + input_device const *const stick = sticks.device(i); + if (stick) + { + for (input_item_id j = ITEM_ID_BUTTON1; (ITEM_ID_BUTTON32 >= j) && (stick->maxitem() >= j); ++j) + { + input_device_item const *const item = stick->item(j); + if (item && (item->itemclass() == ITEM_CLASS_SWITCH)) + { + m_filename_to_code_map.emplace( + util::string_format("joy%i-%i", i, j - ITEM_ID_BUTTON1 + 1), + machine().input().code_name(item->code())); + } + } + } + } + } } // open the state directory - std::string statedir = state_directory(); - osd::directory::ptr dir = osd::directory::open(statedir); + osd::directory::ptr dir = osd::directory::open(state_directory()); // create a separate vector, so we can add sorted entries to the menu std::vector m_entries_vec; @@ -173,12 +178,12 @@ void menu_load_save_state_base::populate(float &customtop, float &custombottom) // sort the vector; put recently modified state files at the top std::sort( - m_entries_vec.begin(), - m_entries_vec.end(), - [](const file_entry *a, const file_entry *b) - { - return a->last_modified() > b->last_modified(); - }); + m_entries_vec.begin(), + m_entries_vec.end(), + [] (const file_entry *a, const file_entry *b) + { + return a->last_modified() > b->last_modified(); + }); // add the entries for (const file_entry *entry : m_entries_vec) @@ -190,11 +195,11 @@ void menu_load_save_state_base::populate(float &customtop, float &custombottom) // format the text std::string text = util::string_format("%s: %s", - entry->visible_name(), - time_string); + entry->visible_name(), + time_string); // append the menu item - void *itemref = itemref_from_file_entry(*entry); + void *const itemref = itemref_from_file_entry(*entry); item_append(std::move(text), std::string(), 0, itemref); // is this item selected? @@ -202,18 +207,25 @@ void menu_load_save_state_base::populate(float &customtop, float &custombottom) set_selection(itemref); } + if (m_entries_vec.empty()) + { + item_append(_("No save states found"), std::string(), 0, nullptr); + set_selection(nullptr); + } + item_append(menu_item_type::SEPARATOR); + // set up custom render proc customtop = ui().get_line_height() + 3.0f * ui().box_tb_border(); custombottom = ui().get_line_height() + 3.0f * ui().box_tb_border(); // pause if appropriate - if (!m_pause_checked) - { - m_was_paused = machine().paused(); - if (!m_was_paused) - machine().pause(); - m_pause_checked = true; - } + m_was_paused = machine().paused(); + if (!m_was_paused) + machine().pause(); + + // get ready to poll inputs + machine().input().reset_polling(); + m_keys_released = false; } @@ -224,14 +236,17 @@ void menu_load_save_state_base::populate(float &customtop, float &custombottom) void menu_load_save_state_base::handle() { // process the menu - const event *event = process(0); + event const *const event = process(0); // process the event if (event && (event->iptkey == IPT_UI_SELECT)) { - // user selected one of the entries - const file_entry &entry = file_entry_from_itemref(event->itemref); - slot_selected(std::string(entry.file_name())); + if (event->itemref) + { + // user selected one of the entries + file_entry const &entry = file_entry_from_itemref(event->itemref); + slot_selected(std::string(entry.file_name())); + } } else { @@ -249,12 +264,9 @@ void menu_load_save_state_base::handle() std::string menu_load_save_state_base::get_visible_name(const std::string &file_name) { - if (file_name.size() == 1) - { - auto iter = m_filename_to_code_map.find(file_name); - if (iter != m_filename_to_code_map.end()) - return iter->second; - } + auto const iter = m_filename_to_code_map.find(file_name); + if (iter != m_filename_to_code_map.end()) + return iter->second; // otherwise these are the same return file_name; @@ -267,28 +279,22 @@ std::string menu_load_save_state_base::get_visible_name(const std::string &file_ std::string menu_load_save_state_base::poll_inputs() { - // poll A-Z - for (input_item_id id = ITEM_ID_A; id <= ITEM_ID_Z; id++) + input_code const code = machine().input().poll_switches(); + if (INPUT_CODE_INVALID == code) { - if (machine().input().code_pressed_once(keyboard_code(id))) - return keyboard_input_item_name(id); + m_keys_released = true; } - - // poll 0-9 - for (input_item_id id = ITEM_ID_0; id <= ITEM_ID_9; id++) + else if (m_keys_released) { - if (machine().input().code_pressed_once(keyboard_code(id))) + input_item_id const id = code.item_id(); + + // keyboard A-Z and 0-9 + if (((ITEM_ID_A <= id) && (ITEM_ID_Z >= id)) || ((ITEM_ID_0 <= id) && (ITEM_ID_9 >= id))) return keyboard_input_item_name(id); - } - // poll joysticks - for (int joy_index = 0; joy_index <= MAX_SAVED_STATE_JOYSTICK; joy_index++) - { - for (input_item_id id = ITEM_ID_BUTTON1; id <= ITEM_ID_BUTTON32; ++id) - { - if (machine().input().code_pressed_once(input_code(DEVICE_CLASS_JOYSTICK, joy_index, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, id))) - return util::string_format("joy%i-%i", joy_index, id - ITEM_ID_BUTTON1 + 1); - } + // joystick buttons + if ((DEVICE_CLASS_JOYSTICK == code.device_class()) && (ITEM_CLASS_SWITCH == code.item_class()) && (ITEM_MODIFIER_NONE == code.item_modifier()) && (ITEM_ID_BUTTON1 <= id) && (ITEM_ID_BUTTON32 >= id)) + return util::string_format("joy%i-%i", code.device_index(), id - ITEM_ID_BUTTON1 + 1); } return ""; } @@ -328,7 +334,16 @@ void menu_load_save_state_base::slot_selected(std::string &&name) void menu_load_save_state_base::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) { - extra_text_render(top, bottom, origx1, origy1, origx2, origy2, m_header, m_footer); + extra_text_render(top, bottom, origx1, origy1, origx2, origy2, m_header, nullptr); + if (m_footer) + { + char const *const text[] = { m_footer }; + draw_text_box( + std::begin(text), std::end(text), + origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom, + ui::text_layout::CENTER, ui::text_layout::NEVER, false, + ui().colors().text_color(), ui().colors().background_color(), 1.0f); + } } @@ -360,9 +375,9 @@ std::string menu_load_save_state_base::state_directory() const { const char *stateopt = machine().options().state_name(); return util::string_format("%s%s%s", - machine().options().state_directory(), - PATH_SEPARATOR, - machine().get_statename(stateopt)); + machine().options().state_directory(), + PATH_SEPARATOR, + machine().get_statename(stateopt)); } @@ -385,7 +400,7 @@ bool menu_load_save_state_base::is_present(const std::string &name) const //------------------------------------------------- menu_load_state::menu_load_state(mame_ui_manager &mui, render_container &container) - : menu_load_save_state_base(mui, container, _("Load State"), _("Select position to load from"), true) + : menu_load_save_state_base(mui, container, _("Load State"), _("Select state to load"), true) { } @@ -409,7 +424,7 @@ void menu_load_state::process_file(std::string &&file_name) //------------------------------------------------- menu_save_state::menu_save_state(mame_ui_manager &mui, render_container &container) - : menu_load_save_state_base(mui, container, _("Save State"), _("Select position to save to"), false) + : menu_load_save_state_base(mui, container, _("Save State"), _("Press a key or joystick button, or select state to overwrite"), false) { } diff --git a/src/frontend/mame/ui/state.h b/src/frontend/mame/ui/state.h index 0d7bdd2fea9..72c76f238de 100644 --- a/src/frontend/mame/ui/state.h +++ b/src/frontend/mame/ui/state.h @@ -7,14 +7,16 @@ Menus for saving and loading state ***************************************************************************/ - -#pragma once - #ifndef MAME_FRONTEND_UI_STATE_H #define MAME_FRONTEND_UI_STATE_H +#pragma once + #include "ui/menu.h" +#include +#include + namespace ui { // ======================> menu_load_save_state_base @@ -54,14 +56,15 @@ private: std::unordered_map m_file_entries; std::unordered_map m_filename_to_code_map; - const char * m_header; - const char * m_footer; - bool m_must_exist; - bool m_pause_checked; + char const *const m_header; + char const *const m_footer; + bool const m_must_exist; bool m_was_paused; + bool m_keys_released; static void *itemref_from_file_entry(const file_entry &entry); static const file_entry &file_entry_from_itemref(void *itemref); + void try_select_slot(std::string &&name); void slot_selected(std::string &&name); std::string state_directory() const; @@ -92,6 +95,6 @@ protected: virtual void process_file(std::string &&file_name) override; }; -}; +} // namespace ui #endif // MAME_FRONTEND_UI_STATE_H -- cgit v1.2.3