diff options
Diffstat (limited to 'src/emu/input.cpp')
-rw-r--r-- | src/emu/input.cpp | 142 |
1 files changed, 89 insertions, 53 deletions
diff --git a/src/emu/input.cpp b/src/emu/input.cpp index 6c3699a833a..d8029216624 100644 --- a/src/emu/input.cpp +++ b/src/emu/input.cpp @@ -24,6 +24,8 @@ +namespace { + //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -49,8 +51,8 @@ struct code_string_table return nullptr; } - u32 m_code; - const char * m_string; + u32 m_code; + const char * m_string; }; @@ -60,7 +62,7 @@ struct code_string_table //************************************************************************** // token strings for device classes -static const code_string_table devclass_token_table[] = +const code_string_table devclass_token_table[] = { { DEVICE_CLASS_KEYBOARD, "KEYCODE" }, { DEVICE_CLASS_MOUSE, "MOUSECODE" }, @@ -70,7 +72,7 @@ static const code_string_table devclass_token_table[] = }; // friendly strings for device classes -static const code_string_table devclass_string_table[] = +const code_string_table devclass_string_table[] = { { DEVICE_CLASS_KEYBOARD, "Kbd" }, { DEVICE_CLASS_MOUSE, "Mouse" }, @@ -80,7 +82,7 @@ static const code_string_table devclass_string_table[] = }; // token strings for item modifiers -static const code_string_table modifier_token_table[] = +const code_string_table modifier_token_table[] = { { ITEM_MODIFIER_REVERSE, "REVERSE" }, { ITEM_MODIFIER_POS, "POS" }, @@ -93,7 +95,7 @@ static const code_string_table modifier_token_table[] = }; // friendly strings for item modifiers -static const code_string_table modifier_string_table[] = +const code_string_table modifier_string_table[] = { { ITEM_MODIFIER_REVERSE, "Reverse" }, { ITEM_MODIFIER_POS, "+" }, @@ -106,7 +108,7 @@ static const code_string_table modifier_string_table[] = }; // token strings for item classes -static const code_string_table itemclass_token_table[] = +const code_string_table itemclass_token_table[] = { { ITEM_CLASS_SWITCH, "SWITCH" }, { ITEM_CLASS_ABSOLUTE, "ABSOLUTE" }, @@ -115,7 +117,7 @@ static const code_string_table itemclass_token_table[] = }; // token strings for standard item ids -static const code_string_table itemid_token_table[] = +const code_string_table itemid_token_table[] = { // standard keyboard codes { ITEM_ID_A, "A" }, @@ -355,6 +357,48 @@ static const code_string_table itemid_token_table[] = //************************************************************************** +// UTILITY FUNCTIONS +//************************************************************************** + +inline void accumulate_axis_value( + s32 &result, + input_item_class &resultclass, + input_item_class &resultclasszero, + s32 value, + input_item_class valueclass, + input_item_class valueclasszero) +{ + if (!value) + { + // track the highest-priority zero + if ((ITEM_CLASS_ABSOLUTE == valueclasszero) || (ITEM_CLASS_INVALID == resultclasszero)) + resultclasszero = valueclasszero; + } + else if (ITEM_CLASS_ABSOLUTE == valueclass) + { + // absolute values override relative values + if (ITEM_CLASS_ABSOLUTE == resultclass) + result += value; + else + result = value; + resultclass = ITEM_CLASS_ABSOLUTE; + } + else if (ITEM_CLASS_RELATIVE == valueclass) + { + // relative values accumulate + if (resultclass != ITEM_CLASS_ABSOLUTE) + { + result += value; + resultclass = ITEM_CLASS_RELATIVE; + } + } +} + +} // anonymous namespace + + + +//************************************************************************** // INPUT MANAGER //************************************************************************** @@ -861,91 +905,83 @@ bool input_manager::seq_pressed(const input_seq &seq) s32 input_manager::seq_axis_value(const input_seq &seq, input_item_class &itemclass) { - // start with no valid classes - input_item_class itemclasszero = ITEM_CLASS_INVALID; + // start with zero result and no valid classes + s32 result = 0; itemclass = ITEM_CLASS_INVALID; + input_item_class itemclasszero = ITEM_CLASS_INVALID; // iterate over all of the codes - s32 result = 0; + s32 groupval = 0; + input_item_class groupclass = ITEM_CLASS_INVALID; + input_item_class groupclasszero = ITEM_CLASS_INVALID; bool invert = false; bool enable = true; for (int codenum = 0; ; codenum++) { - input_code code = seq[codenum]; + input_code const code = seq[codenum]; if (code == input_seq::not_code) { - // handle NOT + // handle NOT - invert the next code invert = true; } else if (code == input_seq::end_code) { - // handle END + // handle END - commit group and break out of loop + accumulate_axis_value( + result, itemclass, itemclasszero, + groupval, groupclass, groupclasszero); break; } else if (code == input_seq::or_code) { - // handle OR - - // reset invert and enable for the next group + // handle OR - commit group and reset for the next group + accumulate_axis_value( + result, itemclass, itemclasszero, + groupval, groupclass, groupclasszero); + groupval = 0; + groupclasszero = ITEM_CLASS_INVALID; + groupclass = ITEM_CLASS_INVALID; invert = false; enable = true; } else if (enable) { // handle everything else only if we're still enabled + input_item_class const codeclass = code.item_class(); // switch codes serve as enables - if (code.item_class() == ITEM_CLASS_SWITCH) + if (ITEM_CLASS_SWITCH == codeclass) { // AND against previous digital codes if (enable) + { enable = code_pressed(code) ^ invert; - // FIXME: need to clear current group value if enable became false - // you can't create a sequence where this matters using the internal UI, - // but you can by editing a CFG file (or controller config file) + if (!enable) + { + // clear current group if enable became false - only way out is an OR code + groupval = 0; + groupclasszero = ITEM_CLASS_INVALID; + groupclass = ITEM_CLASS_INVALID; + } + } } else { // non-switch codes are analog values - s32 value = code_value(code); - - // if we got a 0 value, don't do anything except remember the first type - if (value == 0) - { - if (itemclasszero == ITEM_CLASS_INVALID) - itemclasszero = code.item_class(); - } - else if (code.item_class() == ITEM_CLASS_ABSOLUTE) - { - // non-zero absolute values override relative values - if (itemclass == ITEM_CLASS_ABSOLUTE) - result += value; - else - result = value; - itemclass = ITEM_CLASS_ABSOLUTE; - } - else if (code.item_class() == ITEM_CLASS_RELATIVE) - { - // non-zero relative values accumulate in the absence of absolute values - if (itemclass != ITEM_CLASS_ABSOLUTE) - { - result += value; - itemclass = ITEM_CLASS_RELATIVE; - } - } + accumulate_axis_value( + groupval, groupclass, groupclasszero, + code_value(code), codeclass, codeclass); } - // clear the invert flag + // clear the invert flag - it only applies to one item invert = false; } } - // saturate mixed absolute values - if (itemclass == ITEM_CLASS_ABSOLUTE) + // saturate mixed absolute values, report neutral type + if (ITEM_CLASS_ABSOLUTE == itemclass) result = std::clamp(result, osd::INPUT_ABSOLUTE_MIN, osd::INPUT_ABSOLUTE_MAX); - - // if the caller wants to know the type, provide it - if (result == 0) + else if (ITEM_CLASS_INVALID == itemclass) itemclass = itemclasszero; return result; } |