A Weird Imagination

Emulating Xbox controllers on Linux

Posted in

The problem#

The Xbox 360 controller has become the defacto standard controller in PC gaming in recent years, likely due to both the popularity of the Xbox and the fact that the controller can easily be used with a computer. One downside of this is that some games assume you have one. If the game supports it and is running through Steam, then Steam's controller settings will let you use any controller, but that doesn't work for all games, and you might not be using Steam. The game that prompted this blog post actually does have Steam controller support promised in the future, but it's in early access and they are busy developing other parts of the game.1

xboxdrv#

The solution is xboxdrv, the userspace Xbox controller driver. In addition to supporting actual Xbox controllers, it can also simulate Xbox controllers based on inputs from other devices like a PlayStation controller or some less common controller.

Read more…

Shadowrun's text compression

The problem#

Several years ago, I was in a ROM hacking IRC room where another regular Alchemic was reverse engineering the text system of the SNES game Shadowrun. He figured it out and wrote a python script to decompress the text but had some questions about why it was designed the way it was. So we're going to walk through figuring out how the code works, with some help from his notes, and try to understand the design.

If you don't want spoilers and would rather try to reverse engineer it yourself, just read up to the end of the Trace format section and see how much you can figure out on your own.

Read more…

Identifying joystick devices

Posted in

Too many input devices#

On a modern computer there are often many input devices,

$ ls /dev/input/event* | wc -l
28

They are just identified by numbers, so it can be difficult to choose the right one and trial-and-error can get tiresome with so many. There is some help from the by-id and by-path listings:

$ ls -go --time-style=+ /dev/input/by-id/
...
lrwxrwxrwx 1 10  usb-045e_0291-if06-event-joystick -> ../event26
lrwxrwxrwx 1  6  usb-045e_0291-if06-joystick -> ../js6
lrwxrwxrwx 1 10  usb-0b43_0003-event-if00 -> ../event20
lrwxrwxrwx 1 10  usb-0b43_0003-event-joystick -> ../event19
lrwxrwxrwx 1  6  usb-0b43_0003-joystick -> ../js1
lrwxrwxrwx 1  9  usb-BTC_USB_Multimedia_Keyboard-event-if01 -> ../event2
lrwxrwxrwx 1  9  usb-BTC_USB_Multimedia_Keyboard-event-kbd -> ../event1
...

$ ls -go --time-style=+ /dev/input/by-path/
...
lrwxrwxrwx 1  9  pci-0000:00:1a.2-usb-0:2:1.0-event-kbd -> ../event1
lrwxrwxrwx 1  9  pci-0000:00:1a.2-usb-0:2:1.1-event -> ../event2
...
lrwxrwxrwx 1 10  pci-0000:00:1d.0-usb-0:1:1.6-event-joystick -> ../event26
lrwxrwxrwx 1  6  pci-0000:00:1d.0-usb-0:1:1.6-joystick -> ../js6
lrwxrwxrwx 1 10  pci-0000:00:1d.0-usb-0:2:1.0-event -> ../event20
lrwxrwxrwx 1 10  pci-0000:00:1d.0-usb-0:2:1.0-event-joystick -> ../event19
...

But, for the most part, those names aren't very helpful, especially since many joystick devices support 2 or 4 joysticks connected to the same device.

identify_evdev.py#

Enter identify_evdev.py:

$ identify_evdev.py
/dev/input/event22

Where /dev/input/event22 is the device of the joystick I touched after running identify_evdev.py.

Read more…

Read-only filesystem errors

Linux has a tendency to give very unhelpful error messages when it is unable to create a file. I previously blogged about a few different reasons Linux might report a disk is full, but all of the reasons included the disk actually not having space for more files. Yet another reason to get similar errors is if the partition is mounted readonly (ro):

$ mount | grep -F /usr
/dev/sdc2 on /usr type ext4 (ro,nodev,noatime,data=ordered)

mount without any options lists all of the mounted partitions along with their mount options.

Many programs will show a helpful error message:

$ touch test
touch: cannot touch ‘test’: Read-only file system

But some others won't:

rtorrent: Could not lock session directory: "./session/", held by "<error>".

That error is normally caused by ./session/rtorrent.lock not being writable due to being held by another process, but in this case it's not writable due to the filesystem being readonly. rtorrent doesn't distinguish the two.

For that reason, when running into weird behavior from a program on Linux, it's a good idea to check that the directories the program might try to write to are actually writable.

How not to fix USB HID errors

The error#

I was having trouble with a USB joystick adapter (an EMS Playstation controller adapter, to be specific). When I plugged it in, it wouldn't work and checking dmesg showed the same error getting generated over and over again (at least once per second):

$ dmesg
...
[81700.968873] usbhid 6-1:1.0: can't add hid device: -71
[81700.968885] usbhid: probe of 6-1:1.0 failed with error -71
[81700.968986] usb usb6-port1: disabled by hub (EMI?), re-enabling...
[81700.968991] usb 6-1: USB disconnect, device number 53
[81701.208025] usb 6-1: new low-speed USB device number 54 using uhci_hcd
[81701.384866] usb 6-1: string descriptor 0 read error: -32
...

The wrong fix#

I decided the sensible thing to do was to reload the driver:

$ sudo modprobe -r usbhid  # Bad idea, don't run this

Read more…

PulseAudio

Posted in

PulseAudio is what most modern Linux distributions use as a sound server, the part of the sound subsystem that sits between applications and the sound driver supporting features like allowing multiple applications to output sound simultaneously. PulseAudio adds various features not present in other Linux sound servers like per-application volume controls and easily outputting to different audio devices (for instance, using HDMI audio instead of the normal audio jack).

PulseAudio can be controlled using pavucontrol, which is a GUI audio mixer. It shows a volume meter and control for every application producing sound as well as an option to choose which audio device it is outputting to. It additionally lists all of the hardware input and output devices, as you would expect from an audio mixer.

Fixing problems#

Restarting PulseAudio#

If PulseAudio is not working properly, you can restart it by running

$ killall -9 pulseaudio

No, really, that's what Debian's PulseAudio page says to do.

When I initially installed PulseAudio, it didn't have my sound cards listed and just had the default null outuput, making it not very useful. Running that command to restart it fixed it.

Muted devices#

PulseAudio seems to mute my sound card all by itself. Currently, I just go into pavucontrol and unmute it.

Detachable X sessions

X forwarding#

Normally with X, it's easy to run an application on a remote computer just by using X forwarding:

local:~$ ssh -X host
host:~$ echo $DISPLAY
localhost:20.0
host:~$ xterm

The xterm will appear on your local computer.

But if you want to continue working with that application on a different remote computer (or once you are physically in front of the computer it is running on), then you're out of luck.

For an application running in the terminal, you can start it inside a GNU Screen (or tmux) session which you can detach and then attach to again on another ssh connection.

GNU Screen for X#

xpra (X Persistent Remote Applications) lets you move graphical applications from one computer to another in addition to fixing other problems with X forwarding. If you instead use xpra for the forwarding, then you can detach and reattach to the session at will.

Read more…

Impromptu dice

Posted in

Dice in shell#

Today I was borrowing a board game from the lending library at Emerald City Comicon and it was missing its dice. We could have gotten some physical dice somewhere, but instead we decided to use the materials we had on hand. The people I was playing with agreed that we did not want to drain our phone batteries by using a dice app on our phones, but I had a laptop with me. So I wrote a dice app for the shell:

while true
do
    reset
    seq 1 6 | shuf -n1
    seq 1 6 | shuf -n1
    read
done

This rolls two six-sided dice every time you hit enter and clears the screen before showing the result using reset.

Read more…

Fixing broken alternatives

The problem#

Trying to install the python-numpy package in Debian Unstable ("Sid") I got the following error on the liblapack3 package (seen also in this bug):

$ sudo apt-get install -f
Reading package lists... Done
Building dependency tree       
Reading state information... Done
0 upgraded, 0 newly installed, 0 to remove and 36 not upgraded.
4 not fully installed or removed.
After this operation, 0 B of additional disk space will be used.
Setting up liblapack3 (3.5.0-4) ...
update-alternatives: error: alternative liblapack.so.3gf can't be slave of liblapack.so.3: it is a master alternative
dpkg: error processing package liblapack3 (--configure):
 subprocess installed post-installation script returned error exit status 2
dpkg: dependency problems prevent configuration of python-numpy:
 python-numpy depends on liblapack3 | liblapack.so.3; however:
  Package liblapack3 is not configured yet.
  Package liblapack.so.3 is not installed.
  Package lapack3 which provides liblapack.so.3 is not installed.
  Package atlas3-base which provides liblapack.so.3 is not installed.
  Package liblapack3 which provides liblapack.so.3 is not configured yet.
  Package libatlas3-base which provides liblapack.so.3 is not installed.

The solution#

Run the following command to fix the error:

$ sudo update-alternatives --remove-all liblapack.so.3gf

And then rerun the install:

$ sudo apt-get install -f

Read more…

The clipboard in the command-line

Posted in

X clipboard#

The X Window System, the basis for the GUI on most desktop Linux systems, defines how the clipboard works for copying and pasting between applications in Linux. One notable quark of X clipboard is that there's actually two clipboards in common use: the one you expect explicitly accessed via Copy and Paste menu items or key shortcuts called the CLIPBOARD and another one where you copy by selecting text and paste by pressing the middle mouse button called the PRIMARY selection.

X clipboard utilities#

Occasionally it is useful to be able to read or write the clipboard at the command-line. For most uses, your terminal emulator's copy and paste options are probably enough. The primary use case I have for using a command-line program to interact with the clipboard is when I am uploading a file as a Gist:

<file xclip

The xclip utility will copy the contents of the file onto the clipboard (PRIMARY, not CLIPBOARD, by default) and then I can paste it on the Gist website.

My system also has xsel which is very similar to xclip. Wikipedia actually lists several such programs, including the unfortunately named xcopy, not to be confused with XCOPY.

GNU Screen copy mode#

GNU Screen provides its own clipboard for copying information between the different windows of a screen session. ctrl+a, [ enters copy mode. In copy mode you can move the cursor using the arrow keys and page up/page down keys. Screen keeps a history (of configurable size), so you can scroll back pretty far. In fact, I use Screen's copy mode far more often for viewing the history in a terminal than for actually copying anything. You can exit copy mode either by using esc to cancel or enter once to mark the start of the selection and again to mark the end of it. Once you have copied something, ctrl+a, ] pastes the contents of the clipboard.