~xdavidwu/motion-control

9a8b1f13cf5de05045804a98dbede80f8356a943 — Pinghao Wu 2 months ago 94f8980
joycon: identify by ids and accel

nso controllers patch in 6.8 removed the fixed imu names and use names
from devices + (IMU) instead, breaking the old code.

move to ids to be more reliable.
2 files changed, 29 insertions(+), 16 deletions(-)

M sensors/joycon/joycon.ha
M sensors/joycon/types.ha
M sensors/joycon/joycon.ha => sensors/joycon/joycon.ha +22 -16
@@ 4,7 4,6 @@ use fmt;
use fs;
use io;
use os;
use strings;
use types;

export fn new(dev: (io::file | void)) (joycon | errors::error) = {


@@ 12,12 11,11 @@ export fn new(dev: (io::file | void)) (joycon | errors::error) = {
	case let f: io::file =>
		return alloc(joycon_impl { dev = evdev::new_from_fd(f)?, ... });
	case void =>
		const preferences: []const str = [
			"Nintendo Switch Pro Controller IMU",
			"Nintendo Switch Right Joy-Con IMU (Grip)",
			"Nintendo Switch Left Joy-Con IMU (Grip)",
			"Nintendo Switch Right Joy-Con IMU",
			"Nintendo Switch Left Joy-Con IMU",
		const preferences: []int = [
			USB_DEVICE_ID_NINTENTO_PROCON,
			USB_DEVICE_ID_NINTENTO_CHRGGRIP,
			USB_DEVICE_ID_NINTENTO_JOYCONR,
			USB_DEVICE_ID_NINTENTO_JOYCONL,
		];
		const fs = os::diropen("/dev/input")!;
		const iter = fs::iter(fs, ".")!;


@@ 41,24 39,32 @@ export fn new(dev: (io::file | void)) (joycon | errors::error) = {
				continue;
			};
			const e = evdev::new_from_fd(f)!;
			const name = evdev::get_name(e);
			let taken = false;
			defer if (!taken) {
				evdev::destroy(e);
				io::close(f)!;
			};

			if (evdev::get_id_vendor(e) != USB_VENDOR_ID_NINTENDO ||
					!evdev::has_property(e, evdev::INPUT_PROP_ACCELEROMETER)) {
				continue;
			};

			let eligible = false;
			const product = evdev::get_id_product(e);
			for (let i = 0z; i < candidate.preference; i += 1) {
				if (strings::compare(name, preferences[i]) == 0) {
				if (product == preferences[i]) {
					if (has_candidate) {
						evdev::destroy(candidate.dev as evdev::libevdev);
						io::close(candidate.fd)!;
					};
					has_candidate = true;
					eligible = true;
					taken = true;
					candidate.fd = f;
					candidate.dev = e;
					candidate.preference = i;
					break;
				};
			};

			if (!eligible) {
				evdev::destroy(e);
				io::close(f)!;
			};
		};
		fs::finish(iter);


M sensors/joycon/types.ha => sensors/joycon/types.ha +7 -0
@@ 22,4 22,11 @@ def READ_RY: u8	= 1 << 4;
def READ_RZ: u8	= 1 << 5;
def READ_FULL: u8	 = (1 << 6) - 1;

def USB_VENDOR_ID_NINTENDO: int = 0x057e;

def USB_DEVICE_ID_NINTENTO_PROCON: int		= 0x2009;
def USB_DEVICE_ID_NINTENTO_CHRGGRIP: int	= 0x200e;
def USB_DEVICE_ID_NINTENTO_JOYCONL: int		= 0x2006;
def USB_DEVICE_ID_NINTENTO_JOYCONR: int		= 0x2007;

export type joycon = *joycon_impl;