Joystick support for Cave Story snap (aka accessing joysticks via /dev/input/event*)

Hey there,

I’m working on a snap for NXEngine Evo / Cave Story (Doukutsu Monogatari) (which is a masterpiece of a game =)).

image

I got audio working by adding the process-control plug (see @popey’s comment here).

Unfortunately, the joystick doesn’t work when running in confined mode. It does work when installing the snap in devmode. Note that I added the joystick plug and connected it manually. I also connected the process-control plug manually.

Here is my snapcraft.yaml.

If you want to test this yourself, please note that you have to go to Options > Controls where you can change the default controls to joystick keys.

Some logs:

$ journaletc
Feb 23 23:29:38 ... dbus[6050]: apparmor="DENIED" operation="dbus_method_call"  bus="session" path="/org/gnome/ScreenSaver" interface="org.gnome.ScreenSaver" member="SimulateUserActivity" mask="send" name="org.gnome.ScreenSav
Feb 23 23:29:38 ... kernel: audit: type=1400 audit(1519424978.970:2639): apparmor="DENIED" operation="open" profile="snap.cavestory.cavestory" name="/etc/timidity/freepats.cfg" pid=18195 comm="nx" requested_mask="r" denied_ma
Feb 23 23:29:38 ... audit[18195]: AVC apparmor="DENIED" operation="open" profile="snap.cavestory.cavestory" name="/etc/timidity/freepats.cfg" pid=18195 comm="nx" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0

$ snappy-debug.security scanlog
kernel.printk_ratelimit = 0
= AppArmor =
Time: Feb 23 23:29:38
Log: apparmor="DENIED" operation="open" profile="snap.cavestory.cavestory" name="/etc/timidity/freepats.cfg" pid=18195 comm="nx" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /etc/timidity/freepats.cfg (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Feb 23 23:29:38
Log: apparmor="DENIED" operation="dbus_method_call"  bus="session" path="/org/gnome/ScreenSaver" interface="org.gnome.ScreenSaver" member="SimulateUserActivity" mask="send" name="org.gnome.ScreenSaver" pid=18195 label="snap.cavestory.cavestory" peer_pid=6240 peer_label="unconfined"
DBus access
Suggestion:
* try adding 'screen-inhibit-control' to 'plugs'

Any help would be highly appreciated!

All the best,
Tim

2 Likes

You can download the latest build here if you don’t want to build it yourself :slight_smile:

$ snap install --dangerous --devmode cavestory_2.6.2-snap0_amd64.snap

or

$ snap remove cavestory
$ snap install --dangerous cavestory_2.6.2-snap0_amd64.snap
$ snap connect cavestory:process-control :process-control
$ snap connect cavestory:joystick :joystick

(joystick won’t work when installing without devmode as mentioned above)

This is actually a bug you can ignore, it is about to be fixed in snapd soon, see:

1 Like

Thanks for the information @ogra!

I published cavestory in the beta channel.

$ snap install --beta cavestory
$ snap connect cavestory:process-control :process-control
$ snap connect cavestory:joystick :joystick
# Joystick doesn't work (yet)

Any ideas about the joystick issue?

1 Like

Confirmed my joystick (an 8bitdo gamepad) doesn’t work in your cavestory snap either.

Here is how my gamepad shows up in dmesg.

 [Thu Mar  1 01:48:04 2018] usb 1-3: new full-speed USB device number 17 using xhci_hcd
[Thu Mar  1 01:48:05 2018] usb 1-3: New USB device found, idVendor=2dc8, idProduct=ab21
[Thu Mar  1 01:48:05 2018] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[Thu Mar  1 01:48:05 2018] usb 1-3: Product: SFC30 Joystick
[Thu Mar  1 01:48:05 2018] usb 1-3: Manufacturer: SFC30
[Thu Mar  1 01:48:05 2018] input: SFC30              SFC30 Joystick as /devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0/0003:2DC8:AB21.000A/input/input39
[Thu Mar  1 01:48:05 2018] hid-generic 0003:2DC8:AB21.000A: input,hidraw8: USB HID v1.10 Joystick [SFC30              SFC30 Joystick] on usb-0000:00:14.0-3/input0

However… if I break out of confinement, the joystick still doesn’t work.

cd /snap/cavestory/current`
export LD_LIBRARY_PATH=/snap/cavestory/current/usr/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/snap/cavestory/current/usr/lib/x86_64-linux-gnu/pulseaudio/:$LD_LIBRARY_PATH
bin/nx

Doing the above results in no joystick working. Do you have the joystick working outside of the snap?

1 Like

I’m here with a message from my sons:

https://www.youtube.com/watch?v=1emSWVcSu8s

1 Like

@chipaca :wink:

@popey it does work with my XBOX 360 controller:

[ 5226.847476] usb 1-7.2: new full-speed USB device number 11 using xhci_hcd
[ 5226.964561] usb 1-7.2: New USB device found, idVendor=045e, idProduct=028e
[ 5226.964568] usb 1-7.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 5226.964573] usb 1-7.2: Product: Controller
[ 5226.964578] usb 1-7.2: Manufacturer: ©Microsoft Corporation
[ 5226.964582] usb 1-7.2: SerialNumber: 058335F
[ 5226.997411] input: Microsoft X-Box 360 pad as /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.2/1-7.2:1.0/input/input28
[ 5226.998213] usbcore: registered new interface driver xpad

But only when installing with devmode:

$ sudo snap install --devmode --beta cavestory

or if I run NXEngine Evo manually from source.

Note that you have to restart the game and set the controls in the settings as described above.

1 Like

Repository for this snap package.

I took a look at this. The problem is that cavestory is using /dev/input/event* instead of /dev/input/js*. This means that the device is not getting properly udev tagged to be added to the device cgroup and doesn’t have the proper apparmor rule. The joystick interface currently only supports js* devices.

Eg, when running cavestory in strict mode:

$ cavestory 
Loading settings...
<nothing about the joystick>

I am able to get cavestory to notice my gamepad strict mode by:

$ sudo snap install cavestory --beta
$ sudo snap connect cavestory:joystick 

# plug in and turn on your controller

# figure out which evdev device is for the joystick
$ ls -l /dev/input/by-id/*event-joystick
lrwxrwxrwx 1 root root 9 May 24 12:02 /dev/input/by-id/usb-hongjingda_HJD-X-event-joystick -> ../event9

# make note of 'event9' here as it is used below. May be different on your system

# update the udev tags for this device
$ sudo sh -c 'echo "# joystick evdev\nKERNEL==\"event9\", TAG+=\"snap_cavestory_cavestory\"" >> /etc/udev/rules.d/70-snap.cavestory.rules'

# make the system see your new tagging rule
$ sudo udevadm trigger

# verify the device is tagged for cavestory
$ udevadm info /dev/input/event9
P: /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/0003:2563:0526.0034/input/input78/event9
N: input/event9
S: input/by-id/usb-hongjingda_HJD-X-event-joystick
S: input/by-path/pci-0000:00:14.0-usb-0:2:1.0-event-joystick
E: DEVLINKS=/dev/input/by-id/usb-hongjingda_HJD-X-event-joystick /dev/input/by-path/pci-0000:00:14.0-usb-0:2:1.0-event-joystick
E: DEVNAME=/dev/input/event9
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/0003:2563:0526.0034/input/input78/event9
...
E: SUBSYSTEM=input
E: TAGS=:snap_cavestory_cavestory:

# update the apparmor profile to for this device
$ sudo sed -i 's/^}$/\/dev\/input\/event9 rw,\n}/' /var/lib/snapd/apparmor/profiles/snap.cavestory.cavestory
$ sudo apparmor_parser -r /var/lib/snapd/apparmor/profiles/snap.cavestory.cavestory

# launch cavestory
$ cavestory
Opened Joystick 0
Name: hongjingda HJD-X
Number of Axes: 6
Number of Buttons: 16
Number of Balls: 0
No force feedback support
Loading settings...
...

As you can see, the gamepad is now accessible. For some reason cavestory is not able to use my particular gamepad though (going into ‘Options/Control’ I can’t change anything to make it work either).

1 Like

FYI, I discovered that SDL1 games might be convinced to use the older joystich interface instead of the newer evdev joystick interfaces by using: export SDL_JOYSTICK_DEVICE=/dev/input/js0. That doesn’t happen to help cavestory, but may help someone else.

1 Like

FYI, this adds support for evdev joysticks: https://github.com/snapcore/snapd/pull/5203

2 Likes

Awesome, thanks a lot!

Thank you for making this snap. Now I don’t have to compile it anymore.

1 Like