diff options
author | feos <vadosnaprimer@users.noreply.github.com> | 2022-02-27 18:12:25 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-28 02:12:25 +1100 |
commit | 300206e308c2c5f9ad8898fb62f1873be682df5a (patch) | |
tree | cb780133d4b724eb390bf84fa9c14a7b7ee4dc1a | |
parent | 029f4232fe9779cbe7d2f9cf2d3e991108da75dc (diff) |
Lua engine: Make setting analog I/O port field values user-friendly. (#9322)
Exposed minimum/maximum values for analog fields. together with defvalue, they can be used to check range of values and neutral position.
Previously you had to send a normalised value between -65535 and 65535 which would be scaled depending on machine specifics. You could read the scaled value from the port, but you couldn't send scaled values in. This allows scripts to set scaled values as seen by the machine.
-rw-r--r-- | docs/source/techspecs/luareference.rst | 13 | ||||
-rw-r--r-- | src/emu/ioport.cpp | 60 | ||||
-rw-r--r-- | src/emu/ioport.h | 8 | ||||
-rw-r--r-- | src/frontend/mame/luaengine_input.cpp | 11 |
4 files changed, 71 insertions, 21 deletions
diff --git a/docs/source/techspecs/luareference.rst b/docs/source/techspecs/luareference.rst index 68704b95951..bc896c34ebc 100644 --- a/docs/source/techspecs/luareference.rst +++ b/docs/source/techspecs/luareference.rst @@ -1962,7 +1962,7 @@ Wraps MAME’s ``ioport_field`` class, representing a field within an I/O port. Instantiation ^^^^^^^^^^^^^ -manager.machine.ioport.ports[tag]:field[mask] +manager.machine.ioport.ports[tag]:field(mask) Gets a field for the given port by bit mask. manager.machine.ioport.ports[tag].fields[name] Gets a field for the given port by display name. @@ -1974,6 +1974,9 @@ field:set_value(value) Set the value of the I/O port field. For digital fields, the value is compared to zero to determine whether the field should be active; for analog fields, the value must be right-aligned and in the correct range. +field:clear_value() + Clear programmatically overridden value and restore the field’s regular + behaviour. field:set_input_seq(seqtype, seq) Set the :ref:`input sequence <luareference-input-iptseq>` for the specified sequence type. This is used to configure per-machine input @@ -2018,9 +2021,13 @@ field.player (read-only) field.mask (read-only) Bits in the I/O port corresponding to this field. field.defvalue (read-only) - The field’s default value + The field’s default value. +field.minvalue (read-only) + The minimum allowed value for analog fields, or nil for digital fields. +field.maxvalue (read-only) + The maximum allowed value for analog fields, or nil for digital fields. field.sensitivity (read-only) - The sensitivity or gain for analog fields + The sensitivity or gain for analog fields. field.way (read-only) The number of directions allowed by the restrictor plate/gate for a digital joystick, or zero (0) for other inputs. diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index f96b2a8d323..5999a75abe5 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -824,6 +824,20 @@ ioport_field::ioport_field(ioport_port &port, ioport_type type, ioport_value def } } + +//------------------------------------------------- +// ~ioport_field - destructor +//------------------------------------------------- + +ioport_field::~ioport_field() +{ +} + + +//------------------------------------------------- +// set_value - programmatically set field value +//------------------------------------------------- + void ioport_field::set_value(ioport_value value) { if (is_analog()) @@ -834,11 +848,15 @@ void ioport_field::set_value(ioport_value value) //------------------------------------------------- -// ~ioport_field - destructor +// clear_value - clear programmatic override //------------------------------------------------- -ioport_field::~ioport_field() +void ioport_field::clear_value() { + if (is_analog()) + live().analog->clear_value(); + else + m_digital_value = false; } @@ -3442,6 +3460,7 @@ analog_field::analog_field(ioport_field &field) m_adjdefvalue(field.defvalue() & field.mask()), m_adjmin(field.minval() & field.mask()), m_adjmax(field.maxval() & field.mask()), + m_adjoverride(field.defvalue() & field.mask()), m_sensitivity(field.sensitivity()), m_reverse(field.analog_reverse()), m_delta(field.delta()), @@ -3449,7 +3468,6 @@ analog_field::analog_field(ioport_field &field) m_accum(0), m_previous(0), m_previousanalog(0), - m_prog_analog_value(0), m_minimum(INPUT_ABSOLUTE_MIN), m_maximum(INPUT_ABSOLUTE_MAX), m_center(0), @@ -3465,7 +3483,7 @@ analog_field::analog_field(ioport_field &field) m_single_scale(false), m_interpolate(false), m_lastdigital(false), - m_was_written(false) + m_use_adjoverride(false) { // compute the shift amount and number of bits for (ioport_value mask = field.mask(); !(mask & 1); mask >>= 1) @@ -3705,16 +3723,28 @@ s32 analog_field::apply_settings(s32 value) const //------------------------------------------------- -// set_value - take a new value to be used -// at next frame update +// set_value - override the value that will be +// read from the field //------------------------------------------------- void analog_field::set_value(s32 value) { - m_was_written = true; - m_prog_analog_value = value; + m_use_adjoverride = true; + m_adjoverride = std::clamp(value, m_adjmin, m_adjmax); +} + + +//------------------------------------------------- +// clear_value - clear programmatic override +//------------------------------------------------- + +void analog_field::clear_value() +{ + m_use_adjoverride = false; + m_adjoverride = m_adjdefvalue; } + //------------------------------------------------- // frame_update - update the internals of a // single analog field periodically @@ -3733,13 +3763,6 @@ void analog_field::frame_update(running_machine &machine) input_item_class itemclass; s32 rawvalue = machine.input().seq_axis_value(m_field.seq(SEQ_TYPE_STANDARD), itemclass); - // use programmatically set value if available - if (m_was_written) - { - m_was_written = false; - rawvalue = m_prog_analog_value; - } - // if we got an absolute input, it overrides everything else if (itemclass == ITEM_CLASS_ABSOLUTE) { @@ -3885,6 +3908,13 @@ void analog_field::read(ioport_value &result) if (!m_field.enabled()) return; + // if set programmatically, only use the override value + if (m_use_adjoverride) + { + result = m_adjoverride; + return; + } + // start with the raw value s32 value = m_accum; diff --git a/src/emu/ioport.h b/src/emu/ioport.h index 2d9bd855918..76f61debcac 100644 --- a/src/emu/ioport.h +++ b/src/emu/ioport.h @@ -916,6 +916,7 @@ public: u8 player() const { return m_player; } bool digital_value() const { return m_digital_value; } void set_value(ioport_value value); + void clear_value(); bool optional() const { return ((m_flags & FIELD_FLAG_OPTIONAL) != 0); } bool cocktail() const { return ((m_flags & FIELD_FLAG_COCKTAIL) != 0); } @@ -1152,8 +1153,9 @@ public: float crosshair_read(); void frame_update(running_machine &machine); - // setters + // programmatic override (for script bindings) void set_value(s32 value); + void clear_value(); private: // helpers @@ -1170,6 +1172,7 @@ private: s32 m_adjdefvalue; // adjusted default value from the config s32 m_adjmin; // adjusted minimum value from the config s32 m_adjmax; // adjusted maximum value from the config + s32 m_adjoverride; // programmatically set adjusted value // live values of configurable parameters s32 m_sensitivity; // current live sensitivity (100=normal) @@ -1181,7 +1184,6 @@ private: s32 m_accum; // accumulated value (including relative adjustments) s32 m_previous; // previous adjusted value s32 m_previousanalog; // previous analog value - s32 m_prog_analog_value; // programmatically set analog value // parameters for modifying live values s32 m_minimum; // minimum adjusted value @@ -1203,7 +1205,7 @@ private: bool m_single_scale; // scale joystick differently if default is between min/max bool m_interpolate; // should we do linear interpolation for mid-frame reads? bool m_lastdigital; // was the last modification caused by a digital form? - bool m_was_written; // was the last modification caused programmatically? + bool m_use_adjoverride; // override what will be read from the field }; diff --git a/src/frontend/mame/luaengine_input.cpp b/src/frontend/mame/luaengine_input.cpp index 1812bdc17b3..4f13b7e2484 100644 --- a/src/frontend/mame/luaengine_input.cpp +++ b/src/frontend/mame/luaengine_input.cpp @@ -257,6 +257,7 @@ void lua_engine::initialize_input(sol::table &emu) auto ioport_field_type = sol().registry().new_usertype<ioport_field>("ioport_field", sol::no_constructor); ioport_field_type["set_value"] = &ioport_field::set_value; + ioport_field_type["clear_value"] = &ioport_field::clear_value; ioport_field_type["set_input_seq"] = [] (ioport_field &f, std::string const &seq_type_string, const input_seq &seq) { @@ -312,6 +313,16 @@ void lua_engine::initialize_input(sol::table &emu) ioport_field_type["player"] = sol::property(&ioport_field::player, &ioport_field::set_player); ioport_field_type["mask"] = sol::property(&ioport_field::mask); ioport_field_type["defvalue"] = sol::property(&ioport_field::defvalue); + ioport_field_type["minvalue"] = sol::property( + [] (ioport_field &f) + { + return f.is_analog() ? std::make_optional(f.minval()) : std::nullopt; + }); + ioport_field_type["maxvalue"] = sol::property( + [] (ioport_field &f) + { + return f.is_analog() ? std::make_optional(f.maxval()) : std::nullopt; + }); ioport_field_type["sensitivity"] = sol::property(&ioport_field::sensitivity); ioport_field_type["way"] = sol::property(&ioport_field::way); ioport_field_type["type_class"] = sol::property( |