From 43d61833e4ae3f9c34776108ad45067f46a97a3e Mon Sep 17 00:00:00 2001 From: AJR Date: Wed, 4 Dec 2024 09:15:16 -0500 Subject: Natural keyboard improvements - NUL is no longer a reserved character, and PORT_CHAR(0) is meaningful now. The ioport_field structure now uses a reserved Unicode character rather than 0 as a filler. - PORT_CHAR() with no arguments (formerly illegal) may be used to skip over shift positions that produce no useful codes. * ioport.h: Use the empty string rather than nullptr as default tag for ioport_condition. (ioport_condition::operator== was blindly passing the null pointers to strcmp.) --- src/emu/ioport.cpp | 34 +++++++++++++++++----------------- src/emu/ioport.h | 8 +++++--- src/emu/natkeyboard.cpp | 4 ++-- src/mame/sfrj/tim011_kbd.cpp | 2 +- src/osd/sdl/osdsdl.cpp | 4 +++- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index d05a294d8f0..33f556e597f 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -740,8 +740,8 @@ ioport_field::ioport_field(ioport_port &port, ioport_type type, ioport_value def for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype) m_seq[seqtype].set_default(); - for (int i = 0; i < std::size(m_chars); i++) - std::fill(std::begin(m_chars[i]), std::end(m_chars[i]), char32_t(0)); + for (auto &chars : m_chars) + std::fill(std::begin(chars), std::end(chars), UCHAR_INVALID); // for DIP switches and configs, look for a default value from the owner if (type == IPT_DIPSWITCH || type == IPT_CONFIG) @@ -909,11 +909,8 @@ std::vector ioport_field::keyboard_codes(int which) const if (which >= std::size(m_chars)) throw emu_fatalerror("Tried to access keyboard_code with out-of-range index %d\n", which); - std::vector result; - for (int i = 0; i < std::size(m_chars[which]) && m_chars[which][i] != 0; i++) - result.push_back(m_chars[which][i]); - - return result; + auto &chars = m_chars[which]; + return std::vector(std::begin(chars), std::find(std::begin(chars), std::end(chars), UCHAR_INVALID)); } @@ -3289,7 +3286,8 @@ ioport_configurer::ioport_configurer(device_t &owner, ioport_list &portlist, std m_errorbuf(errorbuf), m_curport(nullptr), m_curfield(nullptr), - m_cursetting(nullptr) + m_cursetting(nullptr), + m_curshift(0) { } @@ -3394,6 +3392,7 @@ ioport_configurer& ioport_configurer::field_alloc(ioport_type type, ioport_value // reset the current setting m_cursetting = nullptr; + m_curshift = 0; return *this; } @@ -3404,16 +3403,17 @@ ioport_configurer& ioport_configurer::field_alloc(ioport_type type, ioport_value ioport_configurer& ioport_configurer::field_add_char(std::initializer_list charlist) { - for (int index = 0; index < std::size(m_curfield->m_chars); index++) - if (m_curfield->m_chars[index][0] == 0) - { - const size_t char_count = std::size(m_curfield->m_chars[index]); - assert(charlist.size() > 0 && charlist.size() <= char_count); + if (m_curshift < std::size(m_curfield->m_chars)) + { + auto &chars = m_curfield->m_chars[m_curshift++]; + assert(chars[0] == UCHAR_INVALID); + assert(charlist.size() <= std::size(chars)); - for (size_t i = 0; i < char_count; i++) - m_curfield->m_chars[index][i] = i < charlist.size() ? *(charlist.begin() + i) : 0; - return *this; - } + std::copy(charlist.begin(), charlist.end(), std::begin(chars)); + std::fill(std::begin(chars) + charlist.size(), std::end(chars), UCHAR_INVALID); + + return *this; + } std::ostringstream s; bool is_first = true; diff --git a/src/emu/ioport.h b/src/emu/ioport.h index 08ee30c4318..8e8009ffce6 100644 --- a/src/emu/ioport.h +++ b/src/emu/ioport.h @@ -46,12 +46,13 @@ constexpr ioport_value IP_ACTIVE_LOW = 0xffffffff; constexpr int MAX_PLAYERS = 10; // unicode constants +constexpr char32_t UCHAR_INVALID = 0xffff; constexpr char32_t UCHAR_PRIVATE = 0x100000; constexpr char32_t UCHAR_SHIFT_1 = UCHAR_PRIVATE + 0; constexpr char32_t UCHAR_SHIFT_2 = UCHAR_PRIVATE + 1; constexpr char32_t UCHAR_SHIFT_BEGIN = UCHAR_SHIFT_1; constexpr char32_t UCHAR_SHIFT_END = UCHAR_SHIFT_2; -constexpr char32_t UCHAR_MAMEKEY_BEGIN = UCHAR_PRIVATE + 2; +constexpr char32_t UCHAR_MAMEKEY_BEGIN = UCHAR_SHIFT_END + 1; // crosshair types @@ -473,7 +474,7 @@ public: bool none() const { return (m_condition == ALWAYS); } // configuration - void reset() { set(ALWAYS, nullptr, 0, 0); } + void reset() { set(ALWAYS, "", 0, 0); } void set(condition_t condition, const char *tag, ioport_value mask, ioport_value value) { m_condition = condition; @@ -488,7 +489,7 @@ public: private: // internal state condition_t m_condition; // condition to use - const char * m_tag; // tag of port whose condition is to be tested + const char * m_tag; // tag of port whose condition is to be tested (must never be nullptr) ioport_port * m_port; // reference to the port to be tested ioport_value m_mask; // mask to apply to the port ioport_value m_value; // value to compare against @@ -1091,6 +1092,7 @@ private: ioport_port * m_curport; ioport_field * m_curfield; ioport_setting * m_cursetting; + int m_curshift; }; diff --git a/src/emu/natkeyboard.cpp b/src/emu/natkeyboard.cpp index 3a83ea2a197..febcc8d07c0 100644 --- a/src/emu/natkeyboard.cpp +++ b/src/emu/natkeyboard.cpp @@ -678,11 +678,11 @@ void natural_keyboard::build_codes() { if (!(curshift & ~mask)) { - // fetch the code, ignoring 0 and shifters + // fetch the code, ignoring shifters std::vector const codes = field.keyboard_codes(curshift); for (char32_t code : codes) { - if (((code < UCHAR_SHIFT_BEGIN) || (code > UCHAR_SHIFT_END)) && (code != 0)) + if ((code < UCHAR_SHIFT_BEGIN) || (code > UCHAR_SHIFT_END)) { m_have_charkeys = true; keycode_map::iterator const found(devinfo.codemap.find(code)); diff --git a/src/mame/sfrj/tim011_kbd.cpp b/src/mame/sfrj/tim011_kbd.cpp index 3ee5d49f1fd..b9175dab9f7 100644 --- a/src/mame/sfrj/tim011_kbd.cpp +++ b/src/mame/sfrj/tim011_kbd.cpp @@ -223,7 +223,7 @@ static INPUT_PORTS_START(tim011_keyboard) PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CODE(KEYCODE_RIGHT) PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) // excluded from scan PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Ret") PORT_CHAR(0x0d) PORT_CODE(KEYCODE_ENTER) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHAR(0x20) PORT_CODE(KEYCODE_SPACE) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CHAR(0x20) PORT_CHAR() PORT_CHAR(0x00) PORT_CODE(KEYCODE_SPACE) PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CHAR('b') PORT_CHAR('B') PORT_CHAR(0x02) PORT_CODE(KEYCODE_B) PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CHAR('g') PORT_CHAR('G') PORT_CHAR(0x07) PORT_CODE(KEYCODE_G) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y") PORT_CHAR('y') PORT_CHAR('Y') PORT_CHAR(0x19) PORT_CODE(KEYCODE_Y) diff --git a/src/osd/sdl/osdsdl.cpp b/src/osd/sdl/osdsdl.cpp index 87af652733e..af15fdb1563 100644 --- a/src/osd/sdl/osdsdl.cpp +++ b/src/osd/sdl/osdsdl.cpp @@ -508,7 +508,9 @@ void sdl_osd_interface::process_events() } else if (m_modifier_keys & MODIFIER_KEY_SHIFT) { - if (event.key.keysym.sym == SDLK_6) // Ctrl-^ (RS) + if (event.key.keysym.sym == SDLK_2) // Ctrl-@ (NUL) + machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), 0x00); + else if (event.key.keysym.sym == SDLK_6) // Ctrl-^ (RS) machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), 0x1e); else if (event.key.keysym.sym == SDLK_MINUS) // Ctrl-_ (US) machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), 0x1f); -- cgit v1.2.3