From: Arne Meyer <meyer.arne83@netcologne.de>
To: "9front@9front.org" <9front@9front.org>
Subject: [9front] [patch] nusb/ joy: xbox360 controller support and improved hid parsing
Date: Sat, 19 Oct 2024 14:44:52 +0200 (CEST) [thread overview]
Message-ID: <1471971331.1907621.1729341892650@comcenter.netcologne.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 304 bytes --]
Hello,
this patch adds some improvements to nusb/joy.
Support for xbox360 controllers.
Up to six axes are now supported for analog input.
The DPad gets mapped to buttons 16-19.
Added a simple deadband filter for analog axes.
Thanks qwx for feedback and help with the man page changes!
Greetings,
Arne
[-- Attachment #2: nusbjoy.patch --]
[-- Type: application/octet-stream, Size: 5600 bytes --]
diff 0c4e4cb9e92e372dc0cb3df182790dc0b1c757ad uncommitted
--- a/sys/man/4/nusb
+++ b/sys/man/4/nusb
@@ -44,6 +44,9 @@
.B nusb/joy
[
.B -d
+] [
+.B -b
+.I deadband
]
.I devid
.PP
@@ -190,7 +193,7 @@
any changes in the device's axes or buttons.
Buttons are identified via an integer id.
.PP
-Directional buttons are reported as axes
+Directional buttons are reported either as buttons or axes
with 3 positions:
.IR 0 ,
.IR 128 ,
@@ -198,6 +201,12 @@
.I 255
for left (or up), center and right (or down) respectively.
Messages are in the form \fIaxis id position\fR.
+.PP
+A deadband in the range of
+.RI [ 0.0 , 1.0 ]
+can be set with the
+.B \-b
+option to filter out input below a threshold on all analog axes.
.PP
On/off buttons are reported as either
.I down
--- a/sys/src/cmd/nusb/joy/hid.h
+++ b/sys/src/cmd/nusb/joy/hid.h
@@ -7,8 +7,9 @@
/* HID class subclass protocol ids */
JoyCSP = 0x000003,
+ Xbox360CSP = 0x015dff,
- Maxaxes = 3,
+ Maxaxes = 6,
/* Requests */
Getreport = 0x01,
@@ -74,4 +75,88 @@
Flinear = 0<<4, Fnonlin = 1<<4,
Fpref = 0<<5, Fnopref = 1<<5,
Fnonull = 0<<6, Fnullst = 1<<6,
+};
+
+uchar xbox360desc[] = {
+ 0x05, 0x01,
+ 0x09, 0x05,
+ 0xa1, 0x01,
+ 0x75, 0x08,
+ 0x95, 0x01,
+ 0x81, 0x01,
+ 0x75, 0x08,
+ 0x95, 0x01,
+ 0x05, 0x01,
+ 0x09, 0x3b,
+ 0x81, 0x01,
+ 0x05, 0x01,
+ 0x09, 0x01,
+ 0xa1, 0x00,
+ 0x75, 0x01,
+ 0x15, 0x00,
+ 0x25, 0x01,
+ 0x35, 0x00,
+ 0x45, 0x01,
+ 0x95, 0x04,
+ 0x05, 0x01,
+ 0x09, 0x90,
+ 0x09, 0x91,
+ 0x09, 0x93,
+ 0x09, 0x92,
+ 0x81, 0x02,
+ 0xc0,
+ 0x75, 0x01,
+ 0x15, 0x00,
+ 0x25, 0x01,
+ 0x35, 0x00,
+ 0x45, 0x01,
+ 0x95, 0x07,
+ 0x05, 0x09,
+ 0x09, 0x08,
+ 0x09, 0x07,
+ 0x09, 0x09,
+ 0x09, 0x0a,
+ 0x09, 0x05,
+ 0x09, 0x06,
+ 0x09, 0x0b,
+ 0x81, 0x02,
+ 0x75, 0x01,
+ 0x95, 0x01,
+ 0x81, 0x01,
+ 0x75, 0x01,
+ 0x15, 0x00,
+ 0x25, 0x01,
+ 0x35, 0x00,
+ 0x45, 0x01,
+ 0x95, 0x04,
+ 0x05, 0x09,
+ 0x19, 0x01,
+ 0x29, 0x04,
+ 0x81, 0x02,
+ 0x75, 0x08,
+ 0x15, 0x00,
+ 0x26, 0xff, 0x00,
+ 0x35, 0x00,
+ 0x46, 0xff, 0x00,
+ 0x95, 0x02,
+ 0x05, 0x01,
+ 0x09, 0x32,
+ 0x09, 0x35,
+ 0x81, 0x02,
+ 0x75, 0x10,
+ 0x16, 0x00, 0x80,
+ 0x26, 0xff, 0x7f,
+ 0x36, 0x00, 0x80,
+ 0x46, 0xff, 0x7f,
+ 0x95, 0x04,
+ 0x05, 0x01,
+ 0x09, 0x30,
+ 0x09, 0x31,
+ 0x09, 0x33,
+ 0x09, 0x34,
+ 0x81, 0x02,
+ 0x75, 0x30,
+ 0x95, 0x01,
+ 0x81, 0x01,
+ 0xc0,
};
--- a/sys/src/cmd/nusb/joy/joy.c
+++ b/sys/src/cmd/nusb/joy/joy.c
@@ -47,6 +47,7 @@
}
static int debug, kbd;
+static double deadband;
static int
signext(int v, int bits)
@@ -219,8 +220,7 @@
fprint(2, "\n");
}
proto = Reportproto;
- }else
- kbfatal(f, "no report");
+ }
/*
* if a HID's subclass code is 1 (boot mode), it will support
@@ -283,15 +283,28 @@
case 0x010030:
case 0x010031:
case 0x010032:
+ case 0x010033:
+ case 0x010034:
+ case 0x010035:
i = l[Usage] - 0x010030;
if((f & (Fabs|Frel)) == Fabs)
- p->axes[i] = v;
+ p->axes[i] = (abs(v)<(g[LogiMax]*deadband))?0:v;
else
- p->axes[i] += v;
+ p->axes[i] += (abs(v)<(g[LogiMax]*deadband))?0:v;
break;
+
+ case 0x010090:
+ case 0x010091:
+ case 0x010092:
+ case 0x010093:
+ m = 1ULL << (l[Usage] & 0x1f);
+ p->btns &= ~m;
+ if(v != 0)
+ p->btns |= m;
+ break;
}
if((l[Usage] >> 16) == 0x09){
- m = 1ULL << (l[Usage] & 0xff);
+ m = 1ULL << (l[Usage] & 0x0f);
p->btns &= ~m;
if(v != 0)
p->btns |= m;
@@ -365,11 +378,15 @@
/* apply quirks for special devices */
static void
-quirks(Dev *d)
+quirks(KDev *kd)
{
int ret;
+ Dev *d;
uchar buf[17];
+ static uchar xbox360ledcmd[] = {1,3,0};
+ d = kd->dev;
+
/* sony dualshock 3 (ps3) controller requires special enable command */
if(d->usb->vid == 0x054c && d->usb->did == 0x0268){
ret = usbcmd(d, Rd2h|Rclass|Riface, Getreport, (0x3<<8) | 0xF2, 0, buf, sizeof(buf));
@@ -376,6 +393,15 @@
if(ret < 0)
sysfatal("failed to enable ps3 controller: %r");
}
+
+ /* XBox360 controller returns no HID descriptor, so we provide one */
+ if(d->usb->vid == 0x045e && d->usb->did == 0x028e
+ || d->usb->vid == 0x1bad && d->usb->did == 0xf03a){
+ memcpy(kd->rep, xbox360desc, sizeof(xbox360desc));
+ kd->nrep = sizeof(xbox360desc);
+ /* no blinken lights */
+ usbcmd(d, Rh2d|Rclass|Riface, Setreport, Reportout, 0, xbox360ledcmd, 3);
+ }
}
static void
@@ -399,7 +425,9 @@
fprint(2, "%s: %s: opendevdata: %r\n", argv0, kd->ep->dir);
goto Err;
}
- quirks(kd->dev);
+ quirks(kd);
+ if(kd->nrep == 0) kbfatal(kd, "no report");
+
f(kd);
return;
Err:
@@ -409,7 +437,7 @@
static void
usage(void)
{
- fprint(2, "usage: %s [-d] devid\n", argv0);
+ fprint(2, "usage: %s [-d] [-b deadband] devid\n", argv0);
threadexits("usage");
}
@@ -420,11 +448,16 @@
Dev *d;
Ep *ep;
Usbdev *ud;
+ char *b;
ARGBEGIN{
case 'd':
debug++;
break;
+ case 'b':
+ b = EARGF(usage());
+ deadband = atof(b);
+ if(deadband > 0.0 && deadband < 1.0) break;
default:
usage();
}ARGEND;
@@ -438,8 +471,10 @@
for(i = 0; i < nelem(ud->ep); i++){
if((ep = ud->ep[i]) == nil)
continue;
- if(ep->type == Eintr && ep->dir == Ein && ep->iface->csp == JoyCSP)
- break;
+ if(ep->type != Eintr || (ep->dir == Eout))
+ continue;
+ if(ep->iface->csp == JoyCSP) break;
+ if(ep->iface->csp == Xbox360CSP) break;
}
if(ep == nil)
sysfatal("no suitable endpoint found");
next reply other threads:[~2024-10-19 12:46 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-19 12:44 Arne Meyer [this message]
2024-10-19 12:59 ` qwx
2024-11-09 13:32 ` Arne Meyer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1471971331.1907621.1729341892650@comcenter.netcologne.de \
--to=meyer.arne83@netcologne.de \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).