9front - general discussion about 9front
 help / color / mirror / Atom feed
From: Arne Meyer <meyer.arne83@netcologne.de>
To: 9front@9front.org
Subject: Re: [9front] [patch] nusb/ joy: xbox360 controller support and improved hid parsing
Date: Sat, 9 Nov 2024 14:32:04 +0100 (CET)	[thread overview]
Message-ID: <1056451222.2568637.1731159124673@comcenter.netcologne.de> (raw)
In-Reply-To: <1471971331.1907621.1729341892650@comcenter.netcologne.de>

[-- Attachment #1: Type: text/plain, Size: 539 bytes --]

new version. I fixed some style issues and the dpad buttons of the controller now get mapped to regular buttons.
ok?

> Arne Meyer <meyer.arne83@netcologne.de> hat am 19.10.2024 14:44 CEST geschrieben:
> 
>  
> 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: xbox360.diff --]
[-- Type: application/octet-stream, Size: 5238 bytes --]

diff c51566faa77810a457a543ffcf5707db9579c27a 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,
--- 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,18 @@
 		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;
 		}
 		if((l[Usage] >> 16) == 0x09){
-			m = 1ULL << (l[Usage] & 0xff);
+			m = 1ULL << (l[Usage] & 0x3f);
 			p->btns &= ~m;
 			if(v != 0)
 				p->btns |= m;
@@ -363,13 +366,112 @@
 	}
 }
 
+static void 
+xbox360(KDev *kd)
+{
+	static uchar descr[] = {
+		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, 0x09,
+		0x09, 0x0c,
+		0x09, 0x0d,
+		0x09, 0x0e,
+		0x09, 0x0f,
+		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,
+	};
+	static uchar ledcmd[] = {1,3,0};
+	Dev *d = kd->dev;
+
+	memcpy(kd->rep, descr, kd->nrep = sizeof(descr));
+	/* no blinken lights */
+	usbcmd(d, Rh2d|Rclass|Riface, Setreport, Reportout, 0, ledcmd, 3);
+}
+
+
 /* 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 +478,12 @@
 		if(ret < 0)
 			sysfatal("failed to enable ps3 controller: %r");
 	}
+
+	/* XBox360 controller and compatible return no HID descriptor, so we provide one */
+	if(d->usb->vid == 0x045e && d->usb->did == 0x028e
+	|| d->usb->vid == 0x1bad && d->usb->did == 0xf03a){
+		xbox360(kd);
+	}
 }
 
 static void
@@ -399,7 +507,10 @@
 		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 +520,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 +531,17 @@
 	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 +555,13 @@
 	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)
+		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");

  parent reply	other threads:[~2024-11-09 13:33 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-19 12:44 Arne Meyer
2024-10-19 12:59 ` qwx
2024-11-09 13:32 ` Arne Meyer [this message]
2024-11-23 16:45   ` Arne Meyer
2024-11-24 21:07     ` qwx

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=1056451222.2568637.1731159124673@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).