diff options
author | 2020-10-11 02:58:46 +1100 | |
---|---|---|
committer | 2020-10-11 02:58:46 +1100 | |
commit | c751a5348a89f2cd9d6b84938551e341ec7f8450 (patch) | |
tree | 6de05430e61f273376943b79ee61a5b83de3552d | |
parent | 9e971ab36e2752d554239f9eb92397f87679deb5 (diff) |
-emu/natkeyboard.cpp: Allow keyboard devices to be enabled/disabled.
This fixes the "typing on all keyboards at once" issue. You can now
enable and disable keyboard/keypad inputs per device in the Keyboard
Mode menu. Default is to enable the first device with keyboard inputs,
and all device with keypad inputs but no keyboard inputs. The settings
are saved in the CFG file for the machine.
Typing in natural keyboard mode only ever types on one keyboard at a
time, but now you can control which keyboard it types on, as it will be
the first enabled keyboard.
You can easily try this out with something like:
mame64d zorba -rs232 terminal cpm
-ui/inputmap.cpp: Show device descriptions as well as tag paths.
-mac128.cpp: Fixed mouse axis wrap compensation, cleaned up mouse code,
eliminated static variables for mouse input state.
You could see the issue with wrap detection easily enough just by
running mac128k/mac512k/macplus and tapping the arrow keys to move the
mouse one pixel at a time. As you moved past the point where the axis
count wrapped, it would move one pixel in the opposite direction.
There were two function static variables related to mouse input state,
probably still lurking from when the code was initially made to use a
driver state class. This obviously messes with save states and prevents
multiple instances.
- bus/a2bus/mouse.cpp: Fixed mouse axis wrap compensation.
This device had the same bug with wrap compensation as mac128k.cpp.
-rw-r--r-- | scripts/src/mame/frontend.lua | 2 | ||||
-rw-r--r-- | src/devices/bus/a2bus/mouse.cpp | 10 | ||||
-rw-r--r-- | src/emu/ioport.cpp | 36 | ||||
-rw-r--r-- | src/emu/natkeyboard.cpp | 228 | ||||
-rw-r--r-- | src/emu/natkeyboard.h | 41 | ||||
-rw-r--r-- | src/frontend/mame/ui/inputmap.cpp | 17 | ||||
-rw-r--r-- | src/frontend/mame/ui/inputmap.h | 2 | ||||
-rw-r--r-- | src/frontend/mame/ui/keyboard.cpp | 98 | ||||
-rw-r--r-- | src/frontend/mame/ui/keyboard.h | 33 | ||||
-rw-r--r-- | src/frontend/mame/ui/mainmenu.cpp | 3 | ||||
-rw-r--r-- | src/frontend/mame/ui/miscmenu.cpp | 37 | ||||
-rw-r--r-- | src/frontend/mame/ui/miscmenu.h | 12 | ||||
-rw-r--r-- | src/frontend/mame/ui/videoopt.cpp | 2 | ||||
-rw-r--r-- | src/mame/drivers/mac128.cpp | 261 |
14 files changed, 448 insertions, 334 deletions
diff --git a/scripts/src/mame/frontend.lua b/scripts/src/mame/frontend.lua index 8253bf439b5..04e06bd2b6e 100644 --- a/scripts/src/mame/frontend.lua +++ b/scripts/src/mame/frontend.lua @@ -121,6 +121,8 @@ files { MAME_DIR .. "src/frontend/mame/ui/inifile.h", MAME_DIR .. "src/frontend/mame/ui/inputmap.cpp", MAME_DIR .. "src/frontend/mame/ui/inputmap.h", + MAME_DIR .. "src/frontend/mame/ui/keyboard.cpp", + MAME_DIR .. "src/frontend/mame/ui/keyboard.h", MAME_DIR .. "src/frontend/mame/ui/mainmenu.cpp", MAME_DIR .. "src/frontend/mame/ui/mainmenu.h", MAME_DIR .. "src/frontend/mame/ui/menu.cpp", diff --git a/src/devices/bus/a2bus/mouse.cpp b/src/devices/bus/a2bus/mouse.cpp index 03b219cf72e..e5c2e7fcf84 100644 --- a/src/devices/bus/a2bus/mouse.cpp +++ b/src/devices/bus/a2bus/mouse.cpp @@ -299,17 +299,15 @@ void a2bus_mouse_device::mcu_port_c_w(uint8_t data) template <unsigned AXIS, u8 DIR, u8 CLK> void a2bus_mouse_device::update_axis() { - // read the axis + // read the axis and check for changes const int new_m = m_mousexy[AXIS]->read(); - - // did it change? int diff = new_m - m_last[AXIS]; // check for wrap if (diff > 0x80) - diff = 0x100 - diff; - if (diff < -0x80) - diff = -0x100 - diff; + diff -= 0x100; + else if (diff < -0x80) + diff += 0x100; m_count[AXIS] += diff; m_last[AXIS] = new_m; diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index bad25e4030a..49fd548dad7 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -1694,9 +1694,10 @@ time_t ioport_manager::initialize() if (&port.second->device() == &device) { for (ioport_field &field : port.second->fields()) - if (field.type_class()==INPUT_CLASS_CONTROLLER) + if (field.type_class() == INPUT_CLASS_CONTROLLER) { - if (players < field.player() + 1) players = field.player() + 1; + if (players < field.player() + 1) + players = field.player() + 1; field.set_player(field.player() + player_offset); } } @@ -2120,6 +2121,29 @@ void ioport_manager::load_config(config_type cfg_type, util::xml::data_node cons for (input_type_entry &entry : m_typelist) for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) entry.defseq(seqtype) = entry.seq(seqtype); + + // load keyboard enable/disable state + if (cfg_type == config_type::GAME) + { + for (util::xml::data_node const *kbdnode = parentnode->get_child("keyboard"); kbdnode; kbdnode = kbdnode->get_next_sibling("keyboard")) + { + char const *const tag = kbdnode->get_attribute_string("tag", nullptr); + int const enabled = kbdnode->get_attribute_int("enabled", -1); + if (tag && (0 <= enabled)) + { + for (size_t i = 0; natkeyboard().keyboard_count() > i; ++i) + { + if (!strcmp(natkeyboard().keyboard_device(i).tag(), tag)) + { + if (enabled) + natkeyboard().enable_keyboard(i); + else + natkeyboard().disable_keyboard(i); + } + } + } + } + } } @@ -2358,6 +2382,14 @@ void ioport_manager::save_default_inputs(util::xml::data_node &parentnode) void ioport_manager::save_game_inputs(util::xml::data_node &parentnode) { + // save keyboard enable/disable state + for (size_t i = 0; natkeyboard().keyboard_count() > i; ++i) + { + util::xml::data_node *const kbdnode = parentnode.add_child("keyboard", nullptr); + kbdnode->set_attribute("tag", natkeyboard().keyboard_device(i).tag()); + kbdnode->set_attribute_int("enabled", natkeyboard().keyboard_enabled(i)); + } + // iterate over ports for (auto &port : m_portlist) for (ioport_field &field : port.second->fields()) diff --git a/src/emu/natkeyboard.cpp b/src/emu/natkeyboard.cpp index 53a95f46a4b..05ce1f9d685 100644 --- a/src/emu/natkeyboard.cpp +++ b/src/emu/natkeyboard.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles,Vas Crabb /*************************************************************************** natkeyboard.cpp @@ -12,6 +12,9 @@ #include "natkeyboard.h" #include "emuopts.h" +#include <algorithm> +#include <cstring> + //************************************************************************** // DEBUGGING @@ -330,8 +333,8 @@ natural_keyboard::natural_keyboard(running_machine &machine) , m_charqueue_empty() { // try building a list of keycodes; if none are available, don't bother - build_codes(machine.ioport()); - if (!m_keycode_map.empty()) + build_codes(); + if (m_have_charkeys) { m_buffer.resize(KEY_BUFFER_SIZE); m_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(natural_keyboard::timer), this)); @@ -370,16 +373,18 @@ void natural_keyboard::set_in_use(bool usage) machine().options().set_value(OPTION_NATURAL_KEYBOARD, usage, OPTION_PRIORITY_CMDLINE); // lock out (or unlock) all keyboard inputs - for (auto &port : machine().ioport().ports()) - for (ioport_field &field : port.second->fields()) - if (field.type() == IPT_KEYBOARD) - { - field.live().lockout = usage; + for (kbd_dev_info &devinfo : m_keyboards) + { + for (ioport_field &field : devinfo.keyfields) + { + bool const is_keyboard(field.type() == IPT_KEYBOARD); + field.live().lockout = !devinfo.enabled || (is_keyboard && usage); - // clear pressed status when going out of use - if (!usage) - field.set_value(0); - } + // clear pressed status when going out of use + if (is_keyboard && !usage) + field.set_value(0); + } + } } } @@ -413,19 +418,24 @@ void natural_keyboard::post_char(char32_t ch, bool normalize_crlf) machine().logerror("natural_keyboard::post_char(): code=%i (%s) field.name='%s'\n", int(ch), unicode_to_string(ch).c_str(), (code != nullptr && code->field[0] != nullptr) ? code->field[0]->name() : "<null>"); } - // can we post this key in the queue directly? if (can_post_directly(ch)) + { + // can post this key in the queue directly internal_post(ch); - - // can we post this key with an alternate representation? + } else if (can_post_alternate(ch)) { - const char_info *info = char_info::find(ch); + // can post this key with an alternate representation + char_info const *const info = char_info::find(ch); assert(info != nullptr && info->alternate != nullptr); - const char *altstring = info->alternate; - while (*altstring != 0) + char const *altstring = info->alternate; + unsigned remain(std::strlen(altstring)); + while (remain) { - altstring += uchar_from_utf8(&ch, altstring, strlen(altstring)); + int const used(uchar_from_utf8(&ch, altstring, remain)); + assert(0 < used); + altstring += used; + remain -= used; internal_post(ch); } } @@ -601,16 +611,60 @@ void natural_keyboard::paste() // chars //------------------------------------------------- -void natural_keyboard::build_codes(ioport_manager &manager) +void natural_keyboard::build_codes() { - // find all shift keys - unsigned mask = 0; - std::array<ioport_field *, SHIFT_COUNT> shift; - std::fill(std::begin(shift), std::end(shift), nullptr); + ioport_manager &manager(machine().ioport()); + + // find all the devices with keyboard or keypad inputs for (auto const &port : manager.ports()) { + auto devinfo( + std::find_if( + m_keyboards.begin(), + m_keyboards.end(), + [&port] (kbd_dev_info const &info) + { + return &port.second->device() == &info.device.get(); + })); for (ioport_field &field : port.second->fields()) { + bool const is_keyboard(field.type() == IPT_KEYBOARD); + if (is_keyboard || (field.type() == IPT_KEYPAD)) + { + if (m_keyboards.end() == devinfo) + devinfo = m_keyboards.emplace(devinfo, port.second->device()); + devinfo->keyfields.emplace_back(field); + if (is_keyboard) + devinfo->keyboard = true; + else + devinfo->keypad = true; + } + } + } + std::sort( + std::begin(m_keyboards), + std::end(m_keyboards), + [] (kbd_dev_info const &l, kbd_dev_info const &r) + { + return 0 > std::strcmp(l.device.get().tag(), r.device.get().tag()); + }); + + // set up key mappings for each keyboard + std::array<ioport_field *, SHIFT_COUNT> shift; + unsigned mask; + bool have_keyboard(false); + for (kbd_dev_info &devinfo : m_keyboards) + { + // enable all pure keypads and the first keyboard + if (!devinfo.keyboard || !have_keyboard) + devinfo.enabled = true; + have_keyboard = have_keyboard || devinfo.keyboard; + + // find all shift keys + std::fill(std::begin(shift), std::end(shift), nullptr); + mask = 0; + for (ioport_field &field : devinfo.keyfields) + { if (field.type() == IPT_KEYBOARD) { std::vector<char32_t> const codes = field.keyboard_codes(0); @@ -624,13 +678,11 @@ void natural_keyboard::build_codes(ioport_manager &manager) } } } - } - // iterate over ports and fields - for (auto const &port : manager.ports()) - { - for (ioport_field &field : port.second->fields()) + // iterate over keyboard/keypad fields + for (ioport_field &field : devinfo.keyfields) { + field.live().lockout = !devinfo.enabled; if (field.type() == IPT_KEYBOARD) { // iterate over all shift states @@ -644,13 +696,14 @@ void natural_keyboard::build_codes(ioport_manager &manager) { if (((code < UCHAR_SHIFT_BEGIN) || (code > UCHAR_SHIFT_END)) && (code != 0)) { - keycode_map::iterator const found(m_keycode_map.find(code)); + m_have_charkeys = true; + keycode_map::iterator const found(devinfo.codemap.find(code)); keycode_map_entry newcode; std::fill(std::begin(newcode.field), std::end(newcode.field), nullptr); newcode.shift = curshift; newcode.condition = field.condition(); - unsigned fieldnum = 0; + unsigned fieldnum(0); for (unsigned i = 0, bits = curshift; (i < SHIFT_COUNT) && bits; ++i, bits >>= 1) { if (BIT(bits, 0)) @@ -658,11 +711,11 @@ void natural_keyboard::build_codes(ioport_manager &manager) } newcode.field[fieldnum] = &field; - if (m_keycode_map.end() == found) + if (devinfo.codemap.end() == found) { keycode_map_entries entries; entries.emplace_back(newcode); - m_keycode_map.emplace(code, std::move(entries)); + devinfo.codemap.emplace(code, std::move(entries)); } else found->second.emplace_back(newcode); @@ -670,7 +723,7 @@ void natural_keyboard::build_codes(ioport_manager &manager) if (LOG_NATURAL_KEYBOARD) { machine().logerror("natural_keyboard: code=%u (%s) port=%p field.name='%s'\n", - code, unicode_to_string(code), (void *)&port, field.name()); + code, unicode_to_string(code), (void *)&field.port(), field.name()); } } } @@ -678,15 +731,31 @@ void natural_keyboard::build_codes(ioport_manager &manager) } } } + + // sort mapping entries by shift state + for (auto &mapping : devinfo.codemap) + { + std::sort( + mapping.second.begin(), + mapping.second.end(), + [] (keycode_map_entry const &x, keycode_map_entry const &y) { return x.shift < y.shift; }); + } } +} - // sort mapping entries by shift state - for (auto &mapping : m_keycode_map) + +//------------------------------------------------- +// set_keyboard_enabled - enable or disable a +// device with key inputs +//------------------------------------------------- + +void natural_keyboard::set_keyboard_enabled(size_t n, bool enable) +{ + if (enable != m_keyboards[n].enabled) { - std::sort( - mapping.second.begin(), - mapping.second.end(), - [] (keycode_map_entry const &x, keycode_map_entry const &y) { return x.shift < y.shift; }); + m_keyboards[n].enabled = enable; + for (ioport_field &field : m_keyboards[n].keyfields) + field.live().lockout = !enable || ((field.type() == IPT_KEYBOARD) && in_use()); } } @@ -801,13 +870,15 @@ void natural_keyboard::timer(void *ptr, int param) // the driver does not have a queue_chars handler // loop through this character's component codes - const keycode_map_entry *const code = find_code(m_buffer[m_bufbegin]); + if (!m_fieldnum) + m_current_code = find_code(m_buffer[m_bufbegin]); bool advance; - if (code) + if (m_current_code) { + keycode_map_entry const code(*m_current_code); do { - ioport_field *const field = code->field[m_fieldnum]; + ioport_field *const field = code.field[m_fieldnum]; if (field) { // special handling for toggle fields @@ -817,8 +888,8 @@ void natural_keyboard::timer(void *ptr, int param) field->set_value(!field->digital_value()); } } - while (code->field[m_fieldnum] && (++m_fieldnum < code->field.size()) && m_status_keydown); - advance = (m_fieldnum >= code->field.size()) || !code->field[m_fieldnum]; + while (code.field[m_fieldnum] && (++m_fieldnum < code.field.size()) && m_status_keydown); + advance = (m_fieldnum >= code.field.size()) || !code.field[m_fieldnum]; } else { @@ -888,13 +959,20 @@ std::string natural_keyboard::unicode_to_string(char32_t ch) const const natural_keyboard::keycode_map_entry *natural_keyboard::find_code(char32_t ch) const { - keycode_map::const_iterator const found(m_keycode_map.find(ch)); - if (m_keycode_map.end() == found) - return nullptr; - for (keycode_map_entry const &entry : found->second) + for (kbd_dev_info const &devinfo : m_keyboards) { - if (entry.condition.eval()) - return &entry; + if (devinfo.enabled) + { + keycode_map::const_iterator const found(devinfo.codemap.find(ch)); + if (devinfo.codemap.end() != found) + { + for (keycode_map_entry const &entry : found->second) + { + if (entry.condition.eval()) + return &entry; + } + } + } } return nullptr; } @@ -908,25 +986,43 @@ void natural_keyboard::dump(std::ostream &str) const { constexpr size_t left_column_width = 24; - // loop through all codes - bool first(true); - for (auto &code : m_keycode_map) + // loop through all devices + bool firstdev(true); + for (kbd_dev_info const &devinfo : m_keyboards) { - // describe the character code - std::string const description(string_format("%08X (%s) ", code.first, unicode_to_string(code.first))); + if (!firstdev) + str << '\n'; + util::stream_format( + str, + "%s(%s) - %s%s%s %sabled\n", + devinfo.device.get().type().shortname(), + devinfo.device.get().tag(), + devinfo.keyboard ? "keyboard" : "", + (devinfo.keyboard && devinfo.keypad) ? "/" : "", + devinfo.keypad ? "keypad" : "", + devinfo.enabled ? "en" : "dis"); + firstdev = false; + + // loop through all codes + bool firstkey(true); + for (auto &code : devinfo.codemap) + { + // describe the character code + std::string const description(string_format("%08X (%s) ", code.first, unicode_to_string(code.first))); - // pad with spaces - util::stream_format(str, "%-*s", left_column_width, description); + // pad with spaces + util::stream_format(str, "%-*s", left_column_width, description); - for (auto &entry : code.second) - { - // identify the keys used - for (std::size_t field = 0; (entry.field.size() > field) && entry.field[field]; ++field) - util::stream_format(str, "%s'%s'", first ? "" : ", ", entry.field[field]->name()); + for (auto &entry : code.second) + { + // identify the keys used + for (std::size_t field = 0; (entry.field.size() > field) && entry.field[field]; ++field) + util::stream_format(str, "%s'%s'", firstkey ? "" : ", ", entry.field[field]->name()); - // carriage return - str << '\n'; - first = false; + // carriage return + str << '\n'; + firstkey = false; + } } } } diff --git a/src/emu/natkeyboard.h b/src/emu/natkeyboard.h index d411eb74173..e324205a088 100644 --- a/src/emu/natkeyboard.h +++ b/src/emu/natkeyboard.h @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles,Vas Crabb /*************************************************************************** natkeyboard.h @@ -12,8 +12,12 @@ #pragma once +#include <array> +#include <functional> #include <iosfwd> +#include <string> #include <unordered_map> +#include <vector> //************************************************************************** @@ -21,9 +25,9 @@ //************************************************************************** // keyboard helper function delegates -typedef delegate<int (const char32_t *, size_t)> ioport_queue_chars_delegate; -typedef delegate<bool (char32_t)> ioport_accept_char_delegate; -typedef delegate<bool ()> ioport_charqueue_empty_delegate; +using ioport_queue_chars_delegate = delegate<int (const char32_t *, size_t)>; +using ioport_accept_char_delegate = delegate<bool (char32_t)>; +using ioport_charqueue_empty_delegate = delegate<bool ()>; // ======================> natural_keyboard @@ -41,13 +45,18 @@ public: running_machine &machine() const { return m_machine; } bool empty() const { return (m_bufbegin == m_bufend); } bool full() const { return ((m_bufend + 1) % m_buffer.size()) == m_bufbegin; } - bool can_post() const { return (!m_queue_chars.isnull() || !m_keycode_map.empty()); } + bool can_post() const { return m_have_charkeys || !m_queue_chars.isnull(); } bool is_posting() const { return (!empty() || (!m_charqueue_empty.isnull() && !m_charqueue_empty())); } bool in_use() const { return m_in_use; } // configuration void configure(ioport_queue_chars_delegate queue_chars, ioport_accept_char_delegate accept_char, ioport_charqueue_empty_delegate charqueue_empty); void set_in_use(bool usage); + size_t keyboard_count() const { return m_keyboards.size(); } + device_t &keyboard_device(size_t n) { return m_keyboards[n].device; } + bool keyboard_enabled(size_t n) { return m_keyboards[n].enabled; } + void enable_keyboard(size_t n) { set_keyboard_enabled(n, true); } + void disable_keyboard(size_t n) { set_keyboard_enabled(n, false); } // posting void post_char(char32_t ch, bool normalize_crlf = false); @@ -74,13 +83,27 @@ private: { std::array<ioport_field *, SHIFT_COUNT + 1> field; unsigned shift; - ioport_condition condition; + ioport_condition condition; }; typedef std::vector<keycode_map_entry> keycode_map_entries; typedef std::unordered_map<char32_t, keycode_map_entries> keycode_map; + // per-device character-to-key mapping + struct kbd_dev_info + { + kbd_dev_info(device_t &dev) : device(dev) { } + + std::reference_wrapper<device_t> device; + std::vector<std::reference_wrapper<ioport_field> > keyfields; + keycode_map codemap; + bool keyboard = false; + bool keypad = false; + bool enabled = false; + }; + // internal helpers - void build_codes(ioport_manager &manager); + void build_codes(); + void set_keyboard_enabled(size_t n, bool enable); bool can_post_directly(char32_t ch); bool can_post_alternate(char32_t ch); attotime choose_delay(char32_t ch); @@ -90,11 +113,14 @@ private: const keycode_map_entry *find_code(char32_t ch) const; // internal state + std::vector<kbd_dev_info> m_keyboards; // info on keyboard devices in system running_machine & m_machine; // reference to our machine + bool m_have_charkeys; // are there keys with character? bool m_in_use; // is natural keyboard in use? u32 m_bufbegin; // index of starting character u32 m_bufend; // index of ending character std::vector<char32_t> m_buffer; // actual buffer + keycode_map_entry const * m_current_code; // current code being typed unsigned m_fieldnum; // current step in multi-key sequence bool m_status_keydown; // current keydown status bool m_last_cr; // was the last char a CR? @@ -103,7 +129,6 @@ private: ioport_queue_chars_delegate m_queue_chars; // queue characters callback ioport_accept_char_delegate m_accept_char; // accept character callback ioport_charqueue_empty_delegate m_charqueue_empty; // character queue empty callback - keycode_map m_keycode_map; // keycode map }; diff --git a/src/frontend/mame/ui/inputmap.cpp b/src/frontend/mame/ui/inputmap.cpp index 33cbd9223e0..bfb68e40da0 100644 --- a/src/frontend/mame/ui/inputmap.cpp +++ b/src/frontend/mame/ui/inputmap.cpp @@ -93,7 +93,7 @@ void menu_input_general::populate(float &customtop, float &custombottom) item.type = ioport_manager::type_is_analog(entry.type()) ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; item.is_optional = false; item.name = entry.name(); - item.owner_name = nullptr; + item.owner = nullptr; // stop after one, unless we're analog if (item.type == INPUT_TYPE_DIGITAL) @@ -164,7 +164,7 @@ void menu_input_specific::populate(float &customtop, float &custombottom) item.type = field.is_analog() ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL; item.is_optional = field.optional(); item.name = field.name(); - item.owner_name = field.device().tag(); + item.owner = &field.device(); // stop after one, unless we're analog if (item.type == INPUT_TYPE_DIGITAL) @@ -180,7 +180,7 @@ void menu_input_specific::populate(float &customtop, float &custombottom) data.end(), [] (const input_item_data &i1, const input_item_data &i2) { - int cmp = strcmp(i1.owner_name, i2.owner_name); + int cmp = strcmp(i1.owner->tag(), i2.owner->tag()); if (cmp < 0) return true; if (cmp > 0) @@ -431,21 +431,24 @@ void menu_input::populate_sorted(float &customtop, float &custombottom) // build the menu std::string text, subtext; - std::string prev_owner; + const device_t *prev_owner = nullptr; bool first_entry = true; for (input_item_data &item : data) { // generate the name of the item itself, based off the base name and the type assert(nameformat[item.type] != nullptr); - if (item.owner_name && strcmp(item.owner_name, prev_owner.c_str()) != 0) + if (item.owner && (item.owner != prev_owner)) { if (first_entry) first_entry = false; else item_append(menu_item_type::SEPARATOR); - item_append(string_format("[root%s]", item.owner_name), "", 0, nullptr); - prev_owner.assign(item.owner_name); + if (item.owner->owner()) + item_append(string_format(_("%1$s [root%2$s]"), item.owner->type().fullname(), item.owner->tag()), "", 0, nullptr); + else + item_append(string_format(_("[root%1$s]"), item.owner->tag()), "", 0, nullptr); + prev_owner = item.owner; } text = string_format(nameformat[item.type], item.name); diff --git a/src/frontend/mame/ui/inputmap.h b/src/frontend/mame/ui/inputmap.h index d2e41780211..01649b0b1ef 100644 --- a/src/frontend/mame/ui/inputmap.h +++ b/src/frontend/mame/ui/inputmap.h @@ -55,7 +55,7 @@ protected: input_seq seq; // copy of the live sequence const input_seq * defseq = nullptr; // pointer to the default sequence const char * name = nullptr; // pointer to the base name of the item - const char * owner_name = nullptr; // pointer to the name of the owner of the item + const device_t * owner = nullptr; // pointer to the owner of the item ioport_group group = IPG_INVALID; // group type uint8_t type = 0U; // type of port bool is_optional = false; // true if this input is considered optional diff --git a/src/frontend/mame/ui/keyboard.cpp b/src/frontend/mame/ui/keyboard.cpp new file mode 100644 index 00000000000..5d48f23cafe --- /dev/null +++ b/src/frontend/mame/ui/keyboard.cpp @@ -0,0 +1,98 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/*************************************************************************** + + ui/keyboard.cpp + + Keyboard mode menu. + +***************************************************************************/ + +#include "emu.h" +#include "ui/keyboard.h" + +#include "natkeyboard.h" + + +namespace ui { + +namespace { + +constexpr uintptr_t ITEM_KBMODE = 0x00000100; +constexpr uintptr_t ITEM_KBDEV_FIRST = 0x00000200; + +} // anonymous namespace + + +menu_keyboard_mode::menu_keyboard_mode(mame_ui_manager &mui, render_container &container) : menu(mui, container) +{ +} + +void menu_keyboard_mode::populate(float &customtop, float &custombottom) +{ + natural_keyboard &natkbd(machine().ioport().natkeyboard()); + + if (natkbd.can_post()) + { + bool const natmode(natkbd.in_use()); + item_append( + _("Keyboard Mode"), + natmode ? _("Natural") : _("Emulated"), + natmode ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW, + reinterpret_cast<void *>(ITEM_KBMODE)); + item_append(menu_item_type::SEPARATOR); + } + + uintptr_t ref(ITEM_KBDEV_FIRST); + for (size_t i = 0; natkbd.keyboard_count() > i; ++i, ++ref) + { + device_t &kbddev(natkbd.keyboard_device(i)); + bool const enabled(natkbd.keyboard_enabled(i)); + item_append( + util::string_format( + kbddev.owner() ? _("%1$s [root%2$s]") : _("[root%2$s"), + kbddev.type().fullname(), + kbddev.tag()), + enabled ? _("Enabled") : _("Disabled"), + enabled ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW, + reinterpret_cast<void *>(ref)); + } + item_append(menu_item_type::SEPARATOR); +} + +menu_keyboard_mode::~menu_keyboard_mode() +{ +} + +void menu_keyboard_mode::handle() +{ + event const *const menu_event(process(0)); + if (menu_event && uintptr_t(menu_event->itemref)) + { + natural_keyboard &natkbd(machine().ioport().natkeyboard()); + uintptr_t const ref(uintptr_t(menu_event->itemref)); + bool const left(IPT_UI_LEFT == menu_event->iptkey); + bool const right(IPT_UI_RIGHT == menu_event->iptkey); + if (ITEM_KBMODE == ref) + { + if ((left || right) && (natkbd.in_use() != right)) + { + natkbd.set_in_use(right); + reset(reset_options::REMEMBER_REF); + } + } + else if (ITEM_KBDEV_FIRST <= ref) + { + if ((left || right) && (natkbd.keyboard_enabled(ref - ITEM_KBDEV_FIRST) != right)) + { + if (right) + natkbd.enable_keyboard(ref - ITEM_KBDEV_FIRST); + else + natkbd.disable_keyboard(ref - ITEM_KBDEV_FIRST); + reset(reset_options::REMEMBER_REF); + } + } + } +} + +} // namespace ui diff --git a/src/frontend/mame/ui/keyboard.h b/src/frontend/mame/ui/keyboard.h new file mode 100644 index 00000000000..899385e74c2 --- /dev/null +++ b/src/frontend/mame/ui/keyboard.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/*************************************************************************** + + ui/keyboard.h + + Keyboard mode menu. + +***************************************************************************/ +#ifndef MAME_FRONTEND_UI_KEYBOARD_H +#define MAME_FRONTEND_UI_KEYBOARD_H + +#pragma once + +#include "ui/menu.h" + + +namespace ui { + +class menu_keyboard_mode : public menu +{ +public: + menu_keyboard_mode(mame_ui_manager &mui, render_container &container); + virtual ~menu_keyboard_mode(); + +private: + virtual void populate(float &customtop, float &custombottom) override; + virtual void handle() override; +}; + +} // namespace ui + +#endif // MAME_FRONTEND_UI_KEYBOARD_H diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp index bd7f274da29..b1a0e238935 100644 --- a/src/frontend/mame/ui/mainmenu.cpp +++ b/src/frontend/mame/ui/mainmenu.cpp @@ -22,6 +22,7 @@ #include "ui/info_pty.h" #include "ui/inifile.h" #include "ui/inputmap.h" +#include "ui/keyboard.h" #include "ui/miscmenu.h" #include "ui/pluginopt.h" #include "ui/selgame.h" @@ -108,7 +109,7 @@ void menu_main::populate(float &customtop, float &custombottom) if (network_interface_iterator(machine().root_device()).first() != nullptr) item_append(_("Network Devices"), "", 0, (void*)NETWORK_DEVICES); - if (ui().machine_info().has_keyboard() && machine().ioport().natkeyboard().can_post()) + if (machine().ioport().natkeyboard().keyboard_count()) item_append(_("Keyboard Mode"), "", 0, (void *)KEYBOARD_MODE); item_append(_("Slider Controls"), "", 0, (void *)SLIDERS); diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp index 82b7916e3a5..f0ab531360e 100644 --- a/src/frontend/mame/ui/miscmenu.cpp +++ b/src/frontend/mame/ui/miscmenu.cpp @@ -23,7 +23,6 @@ #include "mameopts.h" #include "pluginopts.h" #include "drivenum.h" -#include "natkeyboard.h" #include "romload.h" #include "uiinput.h" @@ -41,42 +40,6 @@ namespace ui { ***************************************************************************/ /*------------------------------------------------- - menu_keyboard_mode - menu that --------------------------------------------------*/ - -menu_keyboard_mode::menu_keyboard_mode(mame_ui_manager &mui, render_container &container) : menu(mui, container) -{ -} - -void menu_keyboard_mode::populate(float &customtop, float &custombottom) -{ - bool natural = machine().ioport().natkeyboard().in_use(); - item_append(_("Keyboard Mode:"), natural ? _("Natural") : _("Emulated"), natural ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW, nullptr); -} - -menu_keyboard_mode::~menu_keyboard_mode() -{ -} - -void menu_keyboard_mode::handle() -{ - bool natural = machine().ioport().natkeyboard().in_use(); - - /* process the menu */ - const event *menu_event = process(0); - - if (menu_event != nullptr) - { - if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) - { - machine().ioport().natkeyboard().set_in_use(!natural); - reset(reset_options::REMEMBER_REF); - } - } -} - - -/*------------------------------------------------- menu_bios_selection - populates the main bios selection menu -------------------------------------------------*/ diff --git a/src/frontend/mame/ui/miscmenu.h b/src/frontend/mame/ui/miscmenu.h index acff544dee6..c8d833ae4e2 100644 --- a/src/frontend/mame/ui/miscmenu.h +++ b/src/frontend/mame/ui/miscmenu.h @@ -7,7 +7,6 @@ Internal MAME menus for the user interface. ***************************************************************************/ - #ifndef MAME_FRONTEND_UI_MISCMENU_H #define MAME_FRONTEND_UI_MISCMENU_H @@ -24,17 +23,6 @@ namespace ui { -class menu_keyboard_mode : public menu -{ -public: - menu_keyboard_mode(mame_ui_manager &mui, render_container &container); - virtual ~menu_keyboard_mode(); - -private: - virtual void populate(float &customtop, float &custombottom) override; - virtual void handle() override; -}; - class menu_network_devices : public menu { public: diff --git a/src/frontend/mame/ui/videoopt.cpp b/src/frontend/mame/ui/videoopt.cpp index 58818328d41..2a876c5a1af 100644 --- a/src/frontend/mame/ui/videoopt.cpp +++ b/src/frontend/mame/ui/videoopt.cpp @@ -141,7 +141,7 @@ void menu_video_options::handle() // process the menu event const *const menu_event(process(0)); - if (menu_event && menu_event->itemref) + if (menu_event && uintptr_t(menu_event->itemref)) { switch (reinterpret_cast<uintptr_t>(menu_event->itemref)) { diff --git a/src/mame/drivers/mac128.cpp b/src/mame/drivers/mac128.cpp index d75819c4107..95540d9a50a 100644 --- a/src/mame/drivers/mac128.cpp +++ b/src/mame/drivers/mac128.cpp @@ -246,11 +246,8 @@ private: uint32_t m_overlay; int m_irq_count, m_ca1_data, m_ca2_data; - int m_mouse_bit_x; - int m_mouse_bit_y; - int last_mx, last_my; - int count_x, count_y; - int m_last_was_x; + uint8_t m_mouse_bit[2], m_mouse_last[2]; + int16_t m_mouse_last_m[2], m_mouse_count[2]; int m_screen_buffer; emu_timer *m_scan_timer; emu_timer *m_hblank_timer; @@ -288,13 +285,10 @@ void mac128_state::machine_start() save_item(NAME(m_irq_count)); save_item(NAME(m_ca1_data)); save_item(NAME(m_ca2_data)); - save_item(NAME(m_mouse_bit_x)); - save_item(NAME(m_mouse_bit_y)); - save_item(NAME(last_mx)); - save_item(NAME(last_my)); - save_item(NAME(count_x)); - save_item(NAME(count_y)); - save_item(NAME(m_last_was_x)); + save_item(NAME(m_mouse_bit)); + save_item(NAME(m_mouse_last)); + save_item(NAME(m_mouse_last_m)); + save_item(NAME(m_mouse_count)); save_item(NAME(m_screen_buffer)); save_item(NAME(m_scc_interrupt)); save_item(NAME(m_via_interrupt)); @@ -306,6 +300,9 @@ void mac128_state::machine_start() save_item(NAME(m_adb_irq_pending)); save_item(NAME(m_drive_select)); save_item(NAME(m_scsiirq_enable)); + + m_mouse_bit[0] = m_mouse_bit[1] = 0; + m_mouse_last[0] = m_mouse_last[1] = 0; } void mac128_state::machine_reset() @@ -314,7 +311,6 @@ void mac128_state::machine_reset() m_last_taken_interrupt = -1; m_overlay = 1; m_screen_buffer = 1; - m_mouse_bit_x = m_mouse_bit_y = 0; m_last_taken_interrupt = 0; m_snd_enable = false; m_main_buffer = true; @@ -518,137 +514,32 @@ void mac128_state::macplus_scsi_w(offs_t offset, uint16_t data, uint16_t mem_mas void mac128_state::scc_mouse_irq(int x, int y) { - static int lasty = 0; - static int lastx = 0; - // DCD lines are active low in hardware but active high to software - if (x && y) + if (x) { - if (m_last_was_x) + m_scc->dcda_w(m_mouse_last[0] ? 1 : 0); + if (x < 0) { - if(x == 2) - { - if(lastx) - { - m_scc->dcda_w(1); - m_mouse_bit_x = 0; - } - else - { - m_scc->dcda_w(0); - m_mouse_bit_x = 1; - } - } - else - { - if(lastx) - { - m_scc->dcda_w(1); - m_mouse_bit_x = 1; - } - else - { - m_scc->dcda_w(0); - m_mouse_bit_x = 0; - } - } - lastx = !lastx; + m_mouse_bit[0] = m_mouse_last[0] ? 0 : 1; } else { - if(y == 2) - { - if(lasty) - { - m_scc->dcdb_w(1); - m_mouse_bit_y = 0; - } - else - { - m_scc->dcdb_w(0); - m_mouse_bit_y = 1; - } - } - else - { - if(lasty) - { - m_scc->dcdb_w(1); - m_mouse_bit_y = 1; - } - else - { - m_scc->dcdb_w(0); - m_mouse_bit_y = 0; - } - } - lasty = !lasty; + m_mouse_bit[0] = m_mouse_last[0] ? 1 : 0; } - - m_last_was_x ^= 1; + m_mouse_last[0] = !m_mouse_last[0]; } - else + if (y) { - if (x) + m_scc->dcdb_w(m_mouse_last[1] ? 1 : 0); + if (y < 0) { - if(x == 2) - { - if(lastx) - { - m_scc->dcda_w(1); - m_mouse_bit_x = 0; - } - else - { - m_scc->dcda_w(0); - m_mouse_bit_x = 1; - } - } - else - { - if(lastx) - { - m_scc->dcda_w(1); - m_mouse_bit_x = 1; - } - else - { - m_scc->dcda_w(0); - m_mouse_bit_x = 0; - } - } - lastx = !lastx; + m_mouse_bit[1] = m_mouse_last[1] ? 0 : 1; } else { - if(y == 2) - { - if(lasty) - { - m_scc->dcdb_w(1); - m_mouse_bit_y = 0; - } - else - { - m_scc->dcdb_w(0); - m_mouse_bit_y = 1; - } - } - else - { - if(lasty) - { - m_scc->dcdb_w(1); - m_mouse_bit_y = 1; - } - else - { - m_scc->dcdb_w(0); - m_mouse_bit_y = 0; - } - } - lasty = !lasty; + m_mouse_bit[1] = m_mouse_last[1] ? 1 : 0; } + m_mouse_last[1] = !m_mouse_last[1]; } } @@ -748,12 +639,9 @@ uint8_t mac128_state::mac_via_in_b() { int val = 0x40; - if (m_mouse_bit_y) /* Mouse Y2 */ - val |= 0x20; - if (m_mouse_bit_x) /* Mouse X2 */ - val |= 0x10; - if ((m_mouse0->read() & 0x01) == 0) - val |= 0x08; + val |= m_mouse_bit[1] << 5; // Mouse Y2 + val |= m_mouse_bit[0] << 4; // Mouse X2 + val |= BIT(~m_mouse0->read(), 0) << 3; val |= m_rtc->data_r(); @@ -849,79 +737,66 @@ void mac128_state::mac_via_out_b_se(uint8_t data) void mac128_state::mouse_callback() { - int new_mx, new_my; - int x_needs_update = 0, y_needs_update = 0; - - new_mx = m_mouse1->read(); - new_my = m_mouse2->read(); - - /* see if it moved in the x coord */ - if (new_mx != last_mx) + // see if it moved in the x coord + const int new_mx = m_mouse1->read(); + if (new_mx != m_mouse_last_m[0]) { - int diff = new_mx - last_mx; + int diff = new_mx - m_mouse_last_m[0]; - /* check for wrap */ + // check for wrap if (diff > 0x80) - diff = 0x100-diff; - if (diff < -0x80) - diff = -0x100-diff; + diff -= 0x100; + else if (diff < -0x80) + diff += 0x100; - count_x += diff; - - last_mx = new_mx; + m_mouse_count[0] += diff; + m_mouse_last_m[0] = new_mx; } - /* see if it moved in the y coord */ - if (new_my != last_my) + + // see if it moved in the y coord + const int new_my = m_mouse2->read(); + if (new_my != m_mouse_last_m[1]) { - int diff = new_my - last_my; + int diff = new_my - m_mouse_last_m[1]; - /* check for wrap */ + // check for wrap if (diff > 0x80) - diff = 0x100-diff; - if (diff < -0x80) - diff = -0x100-diff; + diff -= 0x100; + else if (diff < -0x80) + diff += 0x100; - count_y += diff; - - last_my = new_my; + m_mouse_count[1] += diff; + m_mouse_last_m[1] = new_my; } - /* update any remaining count and then return */ - if (count_x) + // update any remaining count and then return + int x_needs_update = 0; + if (m_mouse_count[0] < 0) { - if (count_x < 0) - { - count_x++; - m_mouse_bit_x = 0; - x_needs_update = 2; - } - else - { - count_x--; - m_mouse_bit_x = 1; - x_needs_update = 1; - } + m_mouse_count[0]++; + x_needs_update = -1; } - else if (count_y) + else if (m_mouse_count[0]) { - if (count_y < 0) - { - count_y++; - m_mouse_bit_y = 1; - y_needs_update = 1; - } - else - { - count_y--; - m_mouse_bit_y = 0; - y_needs_update = 2; - } + m_mouse_count[0]--; + x_needs_update = 1; + } + int y_needs_update = 0; + if (m_mouse_count[1] < 0) + { + m_mouse_count[1]++; + y_needs_update = 1; + } + else if (m_mouse_count[1]) + { + m_mouse_count[1]--; + y_needs_update = -1; } if (x_needs_update || y_needs_update) { - /* assert Port B External Interrupt on the SCC */ - scc_mouse_irq(x_needs_update, y_needs_update ); + // assert Port B External Interrupt on the SCC + scc_mouse_irq(x_needs_update, y_needs_update); } } @@ -1164,10 +1039,10 @@ static INPUT_PORTS_START( macplus ) PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Mouse Button") PORT_CODE(MOUSECODE_BUTTON1) PORT_START("MOUSE1") /* Mouse - X AXIS */ - PORT_BIT( 0xff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1) + PORT_BIT( 0xff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_START("MOUSE2") /* Mouse - Y AXIS */ - PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1) + PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) INPUT_PORTS_END static INPUT_PORTS_START( macadb ) |