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 /src | |
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.
Diffstat (limited to 'src')
-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 |
3 files changed, 61 insertions, 18 deletions
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( |