summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/input.cpp')
-rw-r--r--src/emu/input.cpp142
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;
}