feat: controller/gamepad support (#350)

Adds `nesgamepad`, basically "diet-coke vimputti" for Nestri's microVM
needs here.

Comes with direct mapping for:
- Sony
  - DualShock 4 (v2), DualSense
- Microsoft
  - Xbox 360 pad, Xbox One S pad
- Nintendo
  - Pro Controller
- Generic pad for unknown controllers

---------

Co-authored-by: DatCaptainHorse <DatCaptainHorse@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kristian Ollikainen
2026-09-27 17:50:02 +03:00
committed by GitHub
co-authored by DatCaptainHorse Claude Opus 5.5
parent 291fabd145
commit 451b495de6
24 changed files with 4528 additions and 41 deletions
+19 -1
View File
@@ -221,7 +221,8 @@ const WRITABLE: &[(&str, &str)] = &[
///
/// Ported from the nine init scripts this replaces, and the ordering is theirs:
/// the bus before anything that speaks on it, audio before whatever plays into
/// it, and the hub last because it binds the sockets the rest connect to.
/// it, and the hub after them because it binds the sockets the rest connect to.
/// Only something that dials the hub, and waits for it, comes after.
pub const STACK: &[Service] = &[
Service {
name: "dbus-system",
@@ -337,6 +338,23 @@ pub const STACK: &[Service] = &[
umask: None,
ready: None,
},
Service {
name: "nesgamepad",
argv: &["/usr/bin/nesgamepad"],
env: &[],
// Root, and it has to be: it creates devices through /dev/uinput,
// opens their nodes to the workload, and announces them the way udev
// would -- and libudev ignores an announcement from anyone but root.
user: None,
// Optional: a session without controllers is still played with a
// keyboard and mouse.
cost: "controllers plugged into the client do not reach the game",
required: false,
umask: None,
// It dials the hub rather than the other way round, and redials until
// the hub is there, so nothing waits on it.
ready: None,
},
];
/// The stack as running processes.
+4
View File
@@ -13,6 +13,10 @@
// compositor handles input through Wayland and opens nothing udev provides, so
// dropping it costs a box nothing and saves it a daemon and a settle.
//
// The one thing in a box that does need udev is a game looking for
// controllers, and those are devices `nesgamepad` creates itself -- so it
// stands in for udev for exactly those, and nothing else has to.
//
// # Best effort, one line per failure, each naming a cost
//
// Same discipline as the early filesystems: refusing to boot over any one of