Skip to content

Commit

Permalink
[WIP] xpadneo, deadzones: Implement our own dead zone as a vector
Browse files Browse the repository at this point in the history
This commit sets flatness to zero to let us calculate the dead zone on
a 2D plane instead of on a 1D axis, otherwise we'd have rectangular
dead zones along the two axes per thumb stick.

We also need to set fuzz to 0, otherwise `joydev` doesn't always return
to the center.

See-also: atar-axis#231
Signed-off-by: Kai Krakow <[email protected]>

WIP

Signed-off-by: Kai Krakow <[email protected]>
  • Loading branch information
kakra committed Jul 17, 2020
1 parent 79c5428 commit 57b0340
Showing 1 changed file with 30 additions and 6 deletions.
36 changes: 30 additions & 6 deletions hid-xpadneo/src/hid-xpadneo.c
Original file line number Diff line number Diff line change
Expand Up @@ -942,10 +942,10 @@ static int xpadneo_input_configured(struct hid_device *hdev, struct hid_input *h

if (param_gamepad_compliance) {
hid_info(hdev, "enabling compliance with Linux Gamepad Specification\n");
input_set_abs_params(xdata->idev, ABS_X, -32768, 32767, 7, 4095);
input_set_abs_params(xdata->idev, ABS_Y, -32768, 32767, 7, 4095);
input_set_abs_params(xdata->idev, ABS_RX, -32768, 32767, 7, 4095);
input_set_abs_params(xdata->idev, ABS_RY, -32768, 32767, 7, 4095);
input_set_abs_params(xdata->idev, ABS_X, -32768, 32767, 0, 0);
input_set_abs_params(xdata->idev, ABS_Y, -32768, 32767, 0, 0);
input_set_abs_params(xdata->idev, ABS_RX, -32768, 32767, 0, 0);
input_set_abs_params(xdata->idev, ABS_RY, -32768, 32767, 0, 0);
}

/* combine triggers to form a rudder, use ABS_MISC to order after dpad */
Expand All @@ -954,8 +954,28 @@ static int xpadneo_input_configured(struct hid_device *hdev, struct hid_input *h
return 0;
}

static void xpadneo_report_abs(struct xpadneo_devdata *xdata, unsigned int code, int value) {
unsigned int offset = 0;
static inline s32 scale_axis(s32 this15, s32 other15, s32 zone15) {
s32 cubic_mag30 = this15 * this15 + other15 * other15;
s32 cubic_zone30 = zone15 * zone15;
s32 cubic_scaled30 = (1ULL<<30) - cubic_zone30 - 1;
s32 normalized15 = ((s64)(cubic_mag30 - cubic_zone30) << 15) / cubic_scaled30;
if (cubic_mag30 < cubic_zone30) {
return 0;
} else if (normalized15 <= 0) {
return this15;
} else {
if (this15 < 0)
this15 = clamp(this15 + zone15, -32768 + zone15, 0);
else
this15 = clamp(this15 - zone15, 0, 32767 - zone15);
this15 = (s64)this15 * normalized15 * normalized15 / cubic_mag30;
return clamp(this15, -32768, 32767);
}
}

static void xpadneo_report_abs(struct xpadneo_devdata *xdata, unsigned int code, s32 value) {
s32 offset = 0;
static u32 deadzone = 2560;

switch (code) {
case ABS_X:
Expand All @@ -972,18 +992,22 @@ static void xpadneo_report_abs(struct xpadneo_devdata *xdata, unsigned int code,
switch (code) {
case ABS_X:
xdata->abs.x = value;
value = scale_axis(value, xdata->abs.y, deadzone);
break;
case ABS_Y:
xdata->abs.y = value;
value = scale_axis(value, xdata->abs.x, deadzone);
break;
case ABS_Z:
xdata->abs.z = value;
break;
case ABS_RX:
xdata->abs.rx = value;
value = scale_axis(value, xdata->abs.ry, deadzone);
break;
case ABS_RY:
xdata->abs.ry = value;
value = scale_axis(value, xdata->abs.rx, deadzone);
break;
case ABS_RZ:
xdata->abs.rz = value;
Expand Down

0 comments on commit 57b0340

Please sign in to comment.