mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
Better evdev joystick axis scaling (#3202)
Fix evdev scaling when the minimum value is <0 Declare a trigger as pressed as long as any value >0 is given
This commit is contained in:
parent
956117a74f
commit
6d14583f28
@ -34,7 +34,6 @@ void evdev_joystick_handler::Init(const u32 max_connect)
|
|||||||
|
|
||||||
g_evdev_joystick_config.load();
|
g_evdev_joystick_config.load();
|
||||||
|
|
||||||
needscale = static_cast<bool>(g_evdev_joystick_config.needscale);
|
|
||||||
axistrigger = static_cast<bool>(g_evdev_joystick_config.axistrigger);
|
axistrigger = static_cast<bool>(g_evdev_joystick_config.axistrigger);
|
||||||
|
|
||||||
revaxis.emplace_back(g_evdev_joystick_config.lxreverse);
|
revaxis.emplace_back(g_evdev_joystick_config.lxreverse);
|
||||||
@ -173,12 +172,16 @@ bool evdev_joystick_handler::try_open_dev(u32 index)
|
|||||||
int axes=0;
|
int axes=0;
|
||||||
for (int i=ABS_X; i<=ABS_RZ; i++)
|
for (int i=ABS_X; i<=ABS_RZ; i++)
|
||||||
{
|
{
|
||||||
// Skip ABS_Z and ABS_RZ on controllers where it's used for the triggers.
|
|
||||||
if (axistrigger && (i == ABS_Z || i == ABS_RZ)) continue;
|
|
||||||
|
|
||||||
if (libevdev_has_event_code(dev, EV_ABS, i))
|
if (libevdev_has_event_code(dev, EV_ABS, i))
|
||||||
{
|
{
|
||||||
LOG_NOTICE(GENERAL, "Joystick #%d has axis %d as %d", index, i, axes);
|
LOG_NOTICE(GENERAL, "Joystick #%d has axis %d as %d", index, i, axes);
|
||||||
|
|
||||||
|
axis_ranges[i].first = libevdev_get_abs_minimum(dev, i);
|
||||||
|
axis_ranges[i].second = libevdev_get_abs_maximum(dev, i);
|
||||||
|
|
||||||
|
// Skip ABS_Z and ABS_RZ on controllers where it's used for the triggers.
|
||||||
|
if (axistrigger && (i == ABS_Z || i == ABS_RZ)) continue;
|
||||||
joy_axis_maps[index][i - ABS_X] = axes++;
|
joy_axis_maps[index][i - ABS_X] = axes++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,6 +223,28 @@ void evdev_joystick_handler::Close()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int evdev_joystick_handler::scale_axis(int axis, int value)
|
||||||
|
{
|
||||||
|
auto range = axis_ranges[axis];
|
||||||
|
// Check if scaling is needed.
|
||||||
|
if (range.first != 0 || range.second != 255)
|
||||||
|
{
|
||||||
|
if (range.first < 0)
|
||||||
|
{
|
||||||
|
// Move the ranges up to make the following calculation actually *work*
|
||||||
|
value += -range.first;
|
||||||
|
range.second += -range.first;
|
||||||
|
range.first = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (static_cast<float>(value - range.first) / range.second) * 255;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void evdev_joystick_handler::thread_func()
|
void evdev_joystick_handler::thread_func()
|
||||||
{
|
{
|
||||||
while (active)
|
while (active)
|
||||||
@ -331,7 +356,7 @@ void evdev_joystick_handler::thread_func()
|
|||||||
}
|
}
|
||||||
else if (axistrigger && (evt.code == ABS_Z || evt.code == ABS_RZ))
|
else if (axistrigger && (evt.code == ABS_Z || evt.code == ABS_RZ))
|
||||||
{
|
{
|
||||||
// For Xbox 360 controllers, a third axis represent the left/right triggers.
|
// For Xbox controllers, a third axis represent the left/right triggers.
|
||||||
int which_trigger=0;
|
int which_trigger=0;
|
||||||
|
|
||||||
if (evt.code == ABS_Z)
|
if (evt.code == ABS_Z)
|
||||||
@ -356,8 +381,10 @@ void evdev_joystick_handler::thread_func()
|
|||||||
LOG_ERROR(GENERAL, "Joystick #%d's pad has no trigger %d", i, which_trigger);
|
LOG_ERROR(GENERAL, "Joystick #%d's pad has no trigger %d", i, which_trigger);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
which_button->m_pressed = evt.value == 255;
|
|
||||||
which_button->m_value = evt.value;
|
int value = scale_axis(evt.code, evt.value);
|
||||||
|
which_button->m_pressed = value > 0;
|
||||||
|
which_button->m_value = value;
|
||||||
}
|
}
|
||||||
else if (evt.code >= ABS_X && evt.code <= ABS_RZ)
|
else if (evt.code >= ABS_X && evt.code <= ABS_RZ)
|
||||||
{
|
{
|
||||||
@ -369,22 +396,7 @@ void evdev_joystick_handler::thread_func()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& stick = pad.m_sticks[axis];
|
pad.m_sticks[axis].m_value = scale_axis(evt.code, evt.value);
|
||||||
|
|
||||||
int value = evt.value;
|
|
||||||
|
|
||||||
if (needscale)
|
|
||||||
{
|
|
||||||
// Scale from the -32768...32768 range to the 0...256 range.
|
|
||||||
value = (value / 256) + 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (revaxis[axis])
|
|
||||||
{
|
|
||||||
value = 256 - value;
|
|
||||||
}
|
|
||||||
|
|
||||||
stick.m_value = value;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -44,7 +44,6 @@ struct evdev_joystick_config final : cfg::node
|
|||||||
cfg::_bool lxreverse{this, "Reverse left stick X axis", false};
|
cfg::_bool lxreverse{this, "Reverse left stick X axis", false};
|
||||||
cfg::_bool lyreverse{this, "Reverse left stick Y axis", false};
|
cfg::_bool lyreverse{this, "Reverse left stick Y axis", false};
|
||||||
|
|
||||||
cfg::_bool needscale{this, "Axis scaling", true};
|
|
||||||
cfg::_bool axistrigger{this, "Z axis triggers", true};
|
cfg::_bool axistrigger{this, "Z axis triggers", true};
|
||||||
|
|
||||||
bool load()
|
bool load()
|
||||||
@ -76,6 +75,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void update_devs();
|
void update_devs();
|
||||||
bool try_open_dev(u32 index);
|
bool try_open_dev(u32 index);
|
||||||
|
int scale_axis(int axis, int value);
|
||||||
void thread_func();
|
void thread_func();
|
||||||
|
|
||||||
std::unique_ptr<std::thread> joy_thread;
|
std::unique_ptr<std::thread> joy_thread;
|
||||||
@ -85,6 +85,7 @@ private:
|
|||||||
std::vector<std::vector<int>> joy_button_maps;
|
std::vector<std::vector<int>> joy_button_maps;
|
||||||
std::vector<std::vector<int>> joy_axis_maps;
|
std::vector<std::vector<int>> joy_axis_maps;
|
||||||
std::vector<int> joy_hat_ids;
|
std::vector<int> joy_hat_ids;
|
||||||
bool needscale, axistrigger;
|
bool axistrigger;
|
||||||
|
std::map<int, std::pair<int, int>> axis_ranges;
|
||||||
std::vector<bool> revaxis;
|
std::vector<bool> revaxis;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user