diff options
author | AJR <ajrhacker@users.noreply.github.com> | 2016-05-18 19:23:54 -0400 |
---|---|---|
committer | AJR <ajrhacker@users.noreply.github.com> | 2016-05-18 19:23:54 -0400 |
commit | ea43e9a3865f386213a05ff1a82ec1f751197755 (patch) | |
tree | c3e3f61a911e301a1599427e4040e08f01bea514 /src/emu | |
parent | ce5dadc9f61e4a8de5c6f3bcedc17b554cf4ac85 (diff) |
Ioport refactoring and cleanups (nw)
- Completely move mouse hit testing down into the UI input module. This reduces some dependencies.
- Never return a null pointer from ioport_field::name() to prevent potential crashes. All anonymous inputs are classified as INPUT_CLASS_INTERNAL, so several frontend functions now check type_class instead.
- Correct a couple of typos.
Diffstat (limited to 'src/emu')
-rw-r--r-- | src/emu/ioport.cpp | 96 | ||||
-rw-r--r-- | src/emu/ioport.h | 7 | ||||
-rw-r--r-- | src/emu/machine.cpp | 2 | ||||
-rw-r--r-- | src/emu/uiinput.cpp | 46 | ||||
-rw-r--r-- | src/emu/uiinput.h | 8 | ||||
-rw-r--r-- | src/emu/validity.cpp | 14 |
6 files changed, 103 insertions, 70 deletions
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index 5a68a76a0ae..971aa51080f 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -96,7 +96,6 @@ #include "xmlfile.h" #include "profiler.h" #include "ui/uimain.h" -#include "uiinput.h" #include "osdepend.h" @@ -1516,7 +1515,7 @@ ioport_field::~ioport_field() //------------------------------------------------- // name - return the field name for a given input -// field +// field (this must never return nullptr) //------------------------------------------------- const char *ioport_field::name() const @@ -1583,22 +1582,28 @@ const input_seq &ioport_field::defseq(input_seq_type seqtype) const ioport_type_class ioport_field::type_class() const { + // inputs associated with specific players ioport_group group = manager().type_group(m_type, m_player); - if (group >= IPG_PLAYER1 && group <= IPG_PLAYER8) + if (group >= IPG_PLAYER1 && group <= IPG_PLAYER10) return INPUT_CLASS_CONTROLLER; + // keys (names derived from character codes) if (m_type == IPT_KEYPAD || m_type == IPT_KEYBOARD) return INPUT_CLASS_KEYBOARD; + // configuration settings (specific names required) if (m_type == IPT_CONFIG) return INPUT_CLASS_CONFIG; + // DIP switches (specific names required) if (m_type == IPT_DIPSWITCH) return INPUT_CLASS_DIPSWITCH; + // miscellaneous non-player inputs (named and user-mappable) if (group == IPG_OTHER || (group == IPG_INVALID && m_name != nullptr)) return INPUT_CLASS_MISC; + // internal inputs (these may be anonymous) return INPUT_CLASS_INTERNAL; } @@ -1843,7 +1848,7 @@ void ioport_field::select_next_setting() // digital field //------------------------------------------------- -void ioport_field::frame_update(ioport_value &result, bool mouse_down) +void ioport_field::frame_update(ioport_value &result) { // skip if not enabled if (!enabled()) @@ -1861,7 +1866,7 @@ void ioport_field::frame_update(ioport_value &result, bool mouse_down) return; // if the state changed, look for switch down/switch up - bool curstate = mouse_down || machine().input().seq_pressed(seq()) || m_digital_value; + bool curstate = m_digital_value || machine().input().seq_pressed(seq()); if (m_live->autofire && !machine().ioport().get_autofire_toggle()) { if (curstate) @@ -1928,7 +1933,7 @@ void ioport_field::frame_update(ioport_value &result, bool mouse_down) curstate = false; // additional logic to restrict digital joysticks - if (curstate && !m_digital_value && !mouse_down && m_live->joystick != nullptr && m_way != 16 && !machine().options().joystick_contradictory()) + if (curstate && !m_digital_value && m_live->joystick != nullptr && m_way != 16 && !machine().options().joystick_contradictory()) { UINT8 mask = (m_way == 4) ? m_live->joystick->current4way() : m_live->joystick->current(); if (!(mask & (1 << m_live->joydir))) @@ -2273,14 +2278,14 @@ void ioport_port::write(ioport_value data, ioport_value mem_mask) // frame_update - once/frame update //------------------------------------------------- -void ioport_port::frame_update(ioport_field *mouse_field) +void ioport_port::frame_update() { // start with 0 values for the digital bits m_live->digital = 0; // now loop back and modify based on the inputs for (ioport_field &field : fields()) - field.frame_update(m_live->digital, &field == mouse_field); + field.frame_update(m_live->digital); // hook for MESS's natural keyboard support manager().natkeyboard().frame_update(*this, m_live->digital); @@ -2372,6 +2377,24 @@ void ioport_port::init_live_state() } +//------------------------------------------------- +// update_defvalue - force an update to the input +// port values based on current conditions +//------------------------------------------------- + +void ioport_port::update_defvalue(bool flush_defaults) +{ + // only clear on the first pass + if (flush_defaults) + m_live->defvalue = 0; + + // recompute the default value for the entire port + for (ioport_field &field : m_fieldlist) + if (field.enabled()) + m_live->defvalue = (m_live->defvalue & ~field.mask()) | (field.live().value & field.mask()); +} + + //************************************************************************** // I/O PORT LIVE STATE @@ -2648,10 +2671,10 @@ const char *ioport_manager::type_name(ioport_type type, UINT8 player) { // if we have a machine, use the live state and quick lookup input_type_entry *entry = m_type_to_entry[type][player]; - if (entry != nullptr) + if (entry != nullptr && entry->name() != nullptr) return entry->name(); - // if we find nothing, return an invalid group + // if we find nothing, return a default string (not a null pointer) return "???"; } @@ -2796,32 +2819,6 @@ bool ioport_manager::crosshair_position(int player, float &x, float &y) //------------------------------------------------- -// update_defaults - force an update to the input -// port values based on current conditions -//------------------------------------------------- - -void ioport_manager::update_defaults() -{ - // two passes to catch conditionals properly - for (int loopnum = 0; loopnum < 2; loopnum++) - { - // loop over all input ports - for (ioport_port &port : m_portlist) - { - // only clear on the first pass - if (loopnum == 0) - port.live().defvalue = 0; - - // first compute the default value for the entire port - for (ioport_field &field : port.fields()) - if (field.enabled()) - port.live().defvalue = (port.live().defvalue & ~field.mask()) | (field.live().value & field.mask()); - } - } -} - - -//------------------------------------------------- // frame_update - core logic for per-frame input // port updating //------------------------------------------------- @@ -2873,31 +2870,16 @@ g_profiler.start(PROFILER_INPUT); joystick.frame_update(); // compute default values for all the ports - update_defaults(); - - // perform mouse hit testing - INT32 mouse_target_x, mouse_target_y; - bool mouse_button; - render_target *mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button); - - // if the button is pressed, map the point and determine what was hit - ioport_field *mouse_field = nullptr; - if (mouse_button && mouse_target != nullptr) - { - ioport_port *port = nullptr; - ioport_value mask; - float x, y; - if (mouse_target->map_point_input(mouse_target_x, mouse_target_y, port, mask, x, y)) - { - if (port != nullptr) - mouse_field = port->field(mask); - } - } + // two passes to catch conditionals properly + for (ioport_port &port : m_portlist) + port.update_defvalue(true); + for (ioport_port &port : m_portlist) + port.update_defvalue(false); // loop over all input ports for (ioport_port &port : m_portlist) { - port.frame_update(mouse_field); + port.frame_update(); // handle playback/record playback_port(port); diff --git a/src/emu/ioport.h b/src/emu/ioport.h index 3f6a0185337..808bdd3d580 100644 --- a/src/emu/ioport.h +++ b/src/emu/ioport.h @@ -1117,6 +1117,7 @@ public: ioport_condition &condition() { return m_condition; } ioport_type type() const { return m_type; } UINT8 player() const { return m_player; } + bool digital_value() const { return m_digital_value; } void set_value(ioport_value value); bool unused() const { return ((m_flags & FIELD_FLAG_UNUSED) != 0); } @@ -1171,7 +1172,7 @@ public: void select_next_setting(); void crosshair_position(float &x, float &y, bool &gotx, bool &goty); void init_live_state(analog_field *analog); - void frame_update(ioport_value &result, bool mouse_down); + void frame_update(ioport_value &result); void reduce_mask(ioport_value bits_to_remove) { m_mask &= ~bits_to_remove; } // user-controllable settings for a field @@ -1308,8 +1309,9 @@ public: // other operations ioport_field *field(ioport_value mask) const; void collapse_fields(std::string &errorbuf); - void frame_update(ioport_field *mouse_field); + void frame_update(); void init_live_state(); + void update_defvalue(bool flush_defaults); private: void insert_field(ioport_field &newfield, ioport_value &disallowedbits, std::string &errorbuf); @@ -1516,7 +1518,6 @@ private: ioport_port *port(const char *tag) const { return m_portlist.find(tag); } void exit(); input_seq_type token_to_seq_type(const char *string); - void update_defaults(); void load_config(config_type cfg_type, xml_data_node *parentnode); void load_remap_table(xml_data_node *parentnode); diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp index 6b18f910425..12c127f0e03 100644 --- a/src/emu/machine.cpp +++ b/src/emu/machine.cpp @@ -203,7 +203,7 @@ void running_machine::start() // allocate a soft_reset timer m_soft_reset_timer = m_scheduler.timer_alloc(timer_expired_delegate(FUNC(running_machine::soft_reset), this)); - // intialize UI input + // initialize UI input m_ui_input = make_unique_clear<ui_input_manager>(*this); // init the osd layer diff --git a/src/emu/uiinput.cpp b/src/emu/uiinput.cpp index 8d710ebcbfc..9707793b2a3 100644 --- a/src/emu/uiinput.cpp +++ b/src/emu/uiinput.cpp @@ -25,17 +25,18 @@ enum //************************************************************************** -// NETWORK MANAGER +// UI INPUT MANAGER //************************************************************************** //------------------------------------------------- -// network_manager - constructor +// ui_input_manager - constructor //------------------------------------------------- ui_input_manager::ui_input_manager(running_machine &machine) : m_machine(machine), m_current_mouse_target(nullptr), m_current_mouse_down(false), + m_current_mouse_field(nullptr), m_events_start(0), m_events_end(0) { @@ -68,6 +69,22 @@ void ui_input_manager::frame_update() if (!pressed || m_seqpressed[code] != SEQ_PRESSED_RESET) m_seqpressed[code] = pressed; } + + // perform mouse hit testing + ioport_field *mouse_field = m_current_mouse_down ? find_mouse_field() : nullptr; + if (m_current_mouse_field != mouse_field) + { + // clear the old field if there was one + if (m_current_mouse_field != nullptr) + m_current_mouse_field->set_value(0); + + // set the new field if it exists and isn't already being pressed + if (mouse_field != nullptr && !mouse_field->digital_value()) + mouse_field->set_value(1); + + // update internal state + m_current_mouse_field = mouse_field; + } } @@ -166,7 +183,7 @@ void ui_input_manager::reset() location of the mouse -------------------------------------------------*/ -render_target *ui_input_manager::find_mouse(INT32 *x, INT32 *y, bool *button) +render_target *ui_input_manager::find_mouse(INT32 *x, INT32 *y, bool *button) const { if (x != nullptr) *x = m_current_mouse_x; @@ -178,6 +195,29 @@ render_target *ui_input_manager::find_mouse(INT32 *x, INT32 *y, bool *button) } +/*------------------------------------------------- + find_mouse_field - retrieves the input field + the mouse is currently pointing at +-------------------------------------------------*/ + +ioport_field *ui_input_manager::find_mouse_field() const +{ + // map the point and determine what was hit + if (m_current_mouse_target != nullptr) + { + ioport_port *port = nullptr; + ioport_value mask; + float x, y; + if (m_current_mouse_target->map_point_input(m_current_mouse_x, m_current_mouse_y, port, mask, x, y)) + { + if (port != nullptr) + return port->field(mask); + } + } + return nullptr; +} + + /*************************************************************************** USER INTERFACE SEQUENCE READING diff --git a/src/emu/uiinput.h b/src/emu/uiinput.h index 2bd715e01aa..e1752f64b19 100644 --- a/src/emu/uiinput.h +++ b/src/emu/uiinput.h @@ -12,8 +12,6 @@ #ifndef __UIINPUT_H__ #define __UIINPUT_H__ -#include "render.h" - /*************************************************************************** CONSTANTS @@ -25,6 +23,8 @@ TYPE DEFINITIONS ***************************************************************************/ +class render_target; + enum ui_event_type { UI_EVENT_NONE, @@ -71,7 +71,8 @@ public: void reset(); /* retrieves the current location of the mouse */ - render_target *find_mouse(INT32 *x, INT32 *y, bool *button); + render_target *find_mouse(INT32 *x, INT32 *y, bool *button) const; + ioport_field *find_mouse_field() const; /* return TRUE if a key down for the given user interface sequence is detected */ bool pressed(int code); @@ -110,6 +111,7 @@ private: INT32 m_current_mouse_x; INT32 m_current_mouse_y; bool m_current_mouse_down; + ioport_field * m_current_mouse_field; /* popped states; ring buffer of ui_events */ ui_event m_events[EVENT_QUEUE_SIZE]; diff --git a/src/emu/validity.cpp b/src/emu/validity.cpp index 91f218b9470..f31cd20a8cd 100644 --- a/src/emu/validity.cpp +++ b/src/emu/validity.cpp @@ -872,14 +872,22 @@ void validity_checker::validate_inputs() // verify dip switches if (field.type() == IPT_DIPSWITCH) { - // dip switch fields must have a name - if (field.name() == nullptr) - osd_printf_error("DIP switch has a nullptr name\n"); + // dip switch fields must have a specific name + if (field.specific_name() == nullptr) + osd_printf_error("DIP switch has no specific name\n"); // verify the settings list validate_dip_settings(field); } + // verify config settings + if (field.type() == IPT_CONFIG) + { + // config fields must have a specific name + if (field.specific_name() == nullptr) + osd_printf_error("Config switch has no specific name\n"); + } + // verify names const char *name = field.specific_name(); if (name != nullptr) |