mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
Merge pull request #884 from ajrhacker/ioport_field
Ioport refactoring and cleanups (nw)
This commit is contained in:
commit
209e4f8de7
@ -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 "???";
|
||||
}
|
||||
|
||||
@ -2795,32 +2818,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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
|
@ -664,7 +664,7 @@ luabridge::LuaRef lua_engine::l_ioports_port_get_fields(const ioport_port *i)
|
||||
luabridge::LuaRef f_table = luabridge::LuaRef::newTable(L);
|
||||
|
||||
for (ioport_field &field : p->fields()) {
|
||||
if(field.name())
|
||||
if (field.type_class() != INPUT_CLASS_INTERNAL)
|
||||
f_table[field.name()] = &field;
|
||||
}
|
||||
|
||||
@ -1985,7 +1985,7 @@ void lua_engine::update_machine()
|
||||
{
|
||||
for (ioport_field &field : port.fields())
|
||||
{
|
||||
if (field.name())
|
||||
if (field.type_class() != INPUT_CLASS_INTERNAL)
|
||||
{
|
||||
push(m_lua_state, &field, tname_ioport);
|
||||
lua_setfield(m_lua_state, -2, field.name());
|
||||
@ -2214,7 +2214,7 @@ void lua_engine::initialize()
|
||||
.addProperty ("sensitivity", &ioport_field::sensitivity)
|
||||
.addProperty ("way", &ioport_field::way)
|
||||
.addProperty ("is_analog", &ioport_field::is_analog)
|
||||
.addProperty ("is_digitial_joystick", &ioport_field::is_digital_joystick)
|
||||
.addProperty ("is_digital_joystick", &ioport_field::is_digital_joystick)
|
||||
.addProperty ("enabled", &ioport_field::enabled)
|
||||
.addProperty ("unused", &ioport_field::unused)
|
||||
.addProperty ("cocktail", &ioport_field::cocktail)
|
||||
|
@ -263,7 +263,7 @@ void ui_menu_autofire::populate()
|
||||
bool is_first_button = true;
|
||||
for (ioport_field &field : port.fields())
|
||||
{
|
||||
if ((field.name()) && ((field.type() >= IPT_BUTTON1 && field.type() <= IPT_BUTTON16))) // IPT_BUTTON1 + 15)))
|
||||
if (field.type() >= IPT_BUTTON1 && field.type() <= IPT_BUTTON16)
|
||||
{
|
||||
menu_items++;
|
||||
ioport_field::user_settings settings;
|
||||
|
@ -167,20 +167,19 @@ void ui_menu_input_specific::populate()
|
||||
port_count++;
|
||||
for (ioport_field &field : port.fields())
|
||||
{
|
||||
const char *name = field.name();
|
||||
ioport_type_class type_class = field.type_class();
|
||||
|
||||
/* add if we match the group and we have a valid name */
|
||||
if (name != nullptr && field.enabled() &&
|
||||
((field.type() == IPT_OTHER && field.name() != nullptr) || machine().ioport().type_group(field.type(), field.player()) != IPG_INVALID))
|
||||
if (field.enabled() && (type_class == INPUT_CLASS_CONTROLLER || type_class == INPUT_CLASS_MISC))
|
||||
{
|
||||
input_seq_type seqtype;
|
||||
UINT32 sortorder;
|
||||
|
||||
/* determine the sorting order */
|
||||
if (field.type() >= IPT_START1 && field.type() < IPT_ANALOG_LAST)
|
||||
if (type_class == INPUT_CLASS_CONTROLLER)
|
||||
{
|
||||
sortorder = (field.type() << 2) | (field.player() << 12);
|
||||
if (strcmp(field.device().tag(), ":"))
|
||||
if (field.device().owner() != nullptr)
|
||||
sortorder |= (port_count & 0xfff) * 0x10000;
|
||||
}
|
||||
else
|
||||
@ -200,7 +199,7 @@ void ui_menu_input_specific::populate()
|
||||
item->defseq = &field.defseq(seqtype);
|
||||
item->sortorder = sortorder + suborder[seqtype];
|
||||
item->type = field.is_analog() ? (INPUT_TYPE_ANALOG + seqtype) : INPUT_TYPE_DIGITAL;
|
||||
item->name = name;
|
||||
item->name = field.name();
|
||||
item->owner_name = field.device().tag();
|
||||
item->next = itemlist;
|
||||
itemlist = item;
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "imgui/imgui.h"
|
||||
#include "render.h"
|
||||
#include "uiinput.h"
|
||||
|
||||
#include "debug/debugvw.h"
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "emuopts.h"
|
||||
#include "render.h"
|
||||
#include "ui/uimain.h"
|
||||
|
||||
// OSD headers
|
||||
|
@ -25,6 +25,8 @@
|
||||
// TYPE DEFINITIONS
|
||||
//============================================================
|
||||
|
||||
class render_target;
|
||||
|
||||
// forward of SDL_DisplayMode not possible (typedef struct) - define wrapper
|
||||
|
||||
class SDL_DM_Wrapper;
|
||||
|
Loading…
Reference in New Issue
Block a user