evdev: add analog to dpad option (#3551)

* evdev Analog to digital option

* rewrite conditions on axis rotation

* a bit of cleanup
This commit is contained in:
toccata10 2017-10-19 12:41:02 +02:00 committed by kd-11
parent 200557c036
commit b90a7dc66a
2 changed files with 48 additions and 16 deletions

View File

@ -413,10 +413,41 @@ void evdev_joystick_handler::ThreadProc()
break; break;
} }
case EV_ABS: case EV_ABS:
LOG_NOTICE(GENERAL, "Joystick #%d EV_ABS: %d %d", i, evt.code, evt.value); {
if (evt.code >= ABS_HAT0X && evt.code <= ABS_HAT3Y) { LOG_NOTICE(GENERAL, "Joystick #%d EV_ABS: %d %d", i, evt.code, evt.value);
int hat = evt.code - ABS_HAT0X; //duplicate the evt.code and evt.value, so that they're still available
//for the analog input
int code2 = evt.code;
int value2 = evt.value;
if (g_evdev_joystick_config.left_analog_to_dpad)
{
//some gamepad have a -32767 to +32767 range; others have a 0 to 255
float center2 = (axis_ranges[evt.code].second + axis_ranges[evt.code].first) / 2;
//arbitrary decision: when the value is higher than a 1/3 of the range, we simulate a dpad press
float threshold2 = (axis_ranges[evt.code].second-center2)/3;
if (code2 == 0 || code2 == 1)
{
value2 = 0;
if (evt.value > center2 + threshold2)
value2 = 1;
else if (evt.value < center2 - threshold2)
value2 = -1;
if (revaxis[code2])
value2 = -value2;
if (g_evdev_joystick_config.lxstick < g_evdev_joystick_config.lystick)
{
code2 = (code2 == 0) ? ABS_HAT0X : ABS_HAT0Y;
}
else
{
code2 = (code2 == 0) ? ABS_HAT0Y : ABS_HAT0X;
}
}
}
if (code2 >= ABS_HAT0X && code2 <= ABS_HAT3Y)
{
int hat = code2 - ABS_HAT0X;
if (hat != joy_hat_ids[i] && hat-1 != joy_hat_ids[i]) if (hat != joy_hat_ids[i] && hat-1 != joy_hat_ids[i])
{ {
LOG_ERROR(GENERAL, "Joystick #%d sent HAT event for invalid hat %d (expected %d)", i, hat, joy_hat_ids[i]); LOG_ERROR(GENERAL, "Joystick #%d sent HAT event for invalid hat %d (expected %d)", i, hat, joy_hat_ids[i]);
@ -429,7 +460,7 @@ void evdev_joystick_handler::ThreadProc()
{ {
if (bt.m_keyCode != source_axis) continue; if (bt.m_keyCode != source_axis) continue;
if (evt.value == 0) if (value2 == 0)
{ {
bt.m_pressed = false; bt.m_pressed = false;
bt.m_value = 0; bt.m_value = 0;
@ -439,13 +470,12 @@ void evdev_joystick_handler::ThreadProc()
int code; int code;
if (source_axis == EVDEV_DPAD_HAT_AXIS_X) if (source_axis == EVDEV_DPAD_HAT_AXIS_X)
{ {
code = evt.value > 0 ? CELL_PAD_CTRL_RIGHT : CELL_PAD_CTRL_LEFT; code = value2 > 0 ? CELL_PAD_CTRL_RIGHT : CELL_PAD_CTRL_LEFT;
} }
else else
{ {
code = evt.value > 0 ? CELL_PAD_CTRL_DOWN : CELL_PAD_CTRL_UP; code = value2 > 0 ? CELL_PAD_CTRL_DOWN : CELL_PAD_CTRL_UP;
} }
if (bt.m_outKeyCode == code) if (bt.m_outKeyCode == code)
{ {
bt.m_pressed = true; bt.m_pressed = true;
@ -486,7 +516,7 @@ void evdev_joystick_handler::ThreadProc()
which_button->m_pressed = value > 0; which_button->m_pressed = value > 0;
which_button->m_value = value; which_button->m_value = value;
} }
else if (evt.code >= ABS_X && evt.code <= ABS_RZ) if (evt.code >= ABS_X && evt.code <= ABS_RZ)
{ {
int axis = joy_axis_maps[i][evt.code - ABS_X]; int axis = joy_axis_maps[i][evt.code - ABS_X];
@ -531,6 +561,7 @@ void evdev_joystick_handler::ThreadProc()
pad->m_sticks[axis].m_value = scale_axis(evt.code, value); pad->m_sticks[axis].m_value = scale_axis(evt.code, value);
} }
break; break;
}
default: default:
LOG_ERROR(GENERAL, "Unknown joystick #%d event %d", i, evt.type); LOG_ERROR(GENERAL, "Unknown joystick #%d event %d", i, evt.type);
break; break;

View File

@ -47,6 +47,7 @@ struct evdev_joystick_config final : cfg::node
cfg::_bool squirclejoysticks{this, "Squircle Joysticks", true}; cfg::_bool squirclejoysticks{this, "Squircle Joysticks", true};
cfg::int32 squirclefactor{this, "Squircle Factor", 5000}; cfg::int32 squirclefactor{this, "Squircle Factor", 5000};
cfg::int32 deadzone{this, "Deadzone", 10}; cfg::int32 deadzone{this, "Deadzone", 10};
cfg::_bool left_analog_to_dpad{this, "Left Analog to Dpad", false};
bool load() bool load()
{ {