summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
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
commitea43e9a3865f386213a05ff1a82ec1f751197755 (patch)
treec3e3f61a911e301a1599427e4040e08f01bea514 /src/emu
parentce5dadc9f61e4a8de5c6f3bcedc17b554cf4ac85 (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.cpp96
-rw-r--r--src/emu/ioport.h7
-rw-r--r--src/emu/machine.cpp2
-rw-r--r--src/emu/uiinput.cpp46
-rw-r--r--src/emu/uiinput.h8
-rw-r--r--src/emu/validity.cpp14
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)