summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/mame/frontend.lua2
-rw-r--r--src/devices/bus/a2bus/mouse.cpp10
-rw-r--r--src/emu/ioport.cpp36
-rw-r--r--src/emu/natkeyboard.cpp228
-rw-r--r--src/emu/natkeyboard.h41
-rw-r--r--src/frontend/mame/ui/inputmap.cpp17
-rw-r--r--src/frontend/mame/ui/inputmap.h2
-rw-r--r--src/frontend/mame/ui/keyboard.cpp98
-rw-r--r--src/frontend/mame/ui/keyboard.h33
-rw-r--r--src/frontend/mame/ui/mainmenu.cpp3
-rw-r--r--src/frontend/mame/ui/miscmenu.cpp37
-rw-r--r--src/frontend/mame/ui/miscmenu.h12
-rw-r--r--src/frontend/mame/ui/videoopt.cpp2
-rw-r--r--src/mame/drivers/mac128.cpp261
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 )