But if I SSH into the Pi and open a text editor

August 2, 2017 • Posted in , , For the moment I’m out of hardware topics, so let’s look at some stuff that might be more widely applicable to folks who don’t make my exact hardware choices.
In a minute I’ll show you a script I wrote for testing input.

But first… Quitting EmulationStation

I usually don’t have a keyboard hooked up to the arcade Pi

I have one wireless keyboard/trackpad and it roams from Pi to Pi based on my needs

The more I can do from a remote session the better.

You might remember that RetroPie uses a frontend called EmulationStation

For reasons that will soon become clear, .

I wanted a quick way to close EmulationStation gracefully from a remote session

This is what the quit-emulationstation script does.
#!/bin/bash print_help_and_exit() { echo “Usage: quit-emulationstation [options]” echo “” echo “Exits EmulationStation gracefully (if it is running).” exit 0 } while true ; do case “$1″ in -h) print_help_and_exit ;; *) break ;; esac shift done pid=`ps -ef | awk ”/emulationstation\/emulationstation$/ {print $2}”` if [ -z $pid ]; then echo “EmulationStation doesn”t appear to be running.” exit 1 else printf “Quitting EmulationStation.
” kill $pid && echo -e “done.\n” exit 0 fi This is almost comically verbose for a script that does a really simple thing.
That’s on me.
My assumption with these scripts, as with most of the code I write, is that I will not remember how to use them six months later.
Like the others, this lives in /home/pi/bin and is just a few keystrokes away.
Testing controls.
When I was wiring up the control panel, I took advantage of the fact that the I‐Pac turns button presses into simulated keyboard presses.
At any point I could plug the half‐finished panel into the nearest computer via USB and make sure the button I just wired up was actually doing what I thought.
Typically I’d open an empty document in TextEdit or something just so I could have a sandbox for observing key presses.
Things got harder after I put the control panel in place.
Say a button seems to stop working in the middle of gameplay — what then.
I could quit the game and launch a text editor, but to do that I’d have to dig out the wireless keyboard and start a direct terminal session.

This is at odds with my preferred debugging strategy: SSHing into the Pi from my laptop

It’s easier to type on my laptop than on a small wireless keyboard, plus the second screen comes in handy.
But if I SSH into the Pi and open a text editor, input from the I‐Pac won’t be reflected in that document.
If local input affected remote sessions, Linux wouldn’t truly be multi‐user.
So I did some research to see how I could detect input from the I‐Pac’s pseudo‐keyboard from a remote SSH session.
I eventually found a Ruby gem called libdevinput that would let me listen to raw input from a specific device.
Since I wrote this script, libdevinput has been deprecated in favor of device_input, so in preparation for this article I ended up tweaking this script for the latter library’s slightly different API.
#!/usr/bin/env ruby require ”pathname” begin require ”highline” require ”device_input” rescue LoadError => e puts “This program requires Highline and device_input:” puts ” $ gem install highline device_input” exit 1 end KEY_MAP = { “Player 1 Button 1 (Red)” => 29.

# LeftControl “Player 1 Button 2 (Yellow)” => 56

# LeftAlt “Player 1 Button 3 (Green)” => 57, # Space “Player 1 Button 4 (Blue)” => 42, # LeftShift “Player 1 Button 5 (White)” => 44, # Z “Player 1 Button 6 (White)” => 45, # X “Player 1 Joystick UP” => 103, # Up “Player 1 Joystick DOWN” => 108, # Down “Player 1 Joystick LEFT” => 105, # Left “Player 1 Joystick RIGHT” => 106, # Right “Player 2 Button 1 (Red)” => 30, # A “Player 2 Button 2 (Yellow)” => 31, # S “Player 2 Button 3 (Green)” => 16, # Q “Player 2 Button 4 (Blue)” => 17, # W “Player 2 Button 5 (White)” => 37, # K “Player 2 Button 6 (White)” => 23, # I “Player 2 Joystick UP” => 19, # R “Player 2 Joystick DOWN” => 33, # F “Player 2 Joystick LEFT” => 32, # D “Player 2 Joystick RIGHT” => 34, # G “Player 1 Coin” => 6, # 5 “Player 2 Coin” => 7, # 6 “Player 1 Start” => 2, # 1 “Player 2 Start” => 3, # 2 “Pause” => 25, # P “Enter” => 28, # Enter “Tab” => 15, # Tab “Escape” => 1, # Escape } $cli = HighLine.new Signal.trap(”INT”) do puts “” exit 1 end def choose_device base_dir = Pathname.new(”/dev/input/by-id”) # Will get all non-hidden files.
list = Pathname::glob( base_dir.join(”*”) ) table = {} list.each do |p| table[p.basename.to_s] = p end names = table.keys puts “Select the device you want to test:” choice = $cli.choose do |menu| menu.prompt = “Choice: ” menu.choices(*names) end table[choice] end $device = choose_device def keypress?(event) return false if !event return false if event.data.type != 1 return false if event.data.value != 1 true end def description_from_code(event) KEY_MAP.key(event.data.code) end puts “Listening for presses.
” File.open($device, ”r”) do |dev| DeviceInput.read_loop(dev) do |event| if keypress?(event) desc = description_from_code(event) puts desc unless desc.nil.
end end end Notes.
The script requires the aforementioned device_input gem.
It also requires highline to generate the list of devices to choose from.
You’ll have noticed the KEY_MAP hash.
That’s the part you’d need to customize.
It maps my human‐readable button names to the keys they should be mapped to, as represented by key codes.
If you’re expecting the key codes to be the same as the ones you’d get from a key press in a web browser, I’ve got some awful news for you.
To figure out the right codes for the keys you want to test, run sudo showkey –keycodes, then press some keys on the keyboard that’s hooked up to the system — not the keyboard belonging to the computer running your SSH session.
With each key press it’ll log that key’s integer value.
This script works wonderfully for I‐Pac users, since an I‐Pac presents itself as a keyboard to the system.
Some other USB encoders for arcade controls present themselves as joypads or mice rather than keyboards, but since they’re all HID devices, I’d guess that this approach would work without much alteration.
You’d just have to figure out the codes produced by the buttons and joystick directions.
When you run this script, you’ll choose a device from the options listed (mine is usb-Ultimarc_IPAC_2_Ultimarc_IPAC_2_9-if01-event-kbd), at which point the script will go into a loop waiting for keypresses.
Any keypress that maps to a button will get that button’s name logged; press Player 1’s first button and you should see Player 1 Button 1 (Red) (or whatever you named it).
My original version of this script cycled through all the defined keys and had you press each one in turn.
Later I decided it was much simpler to have the script wait in a loop and tell you when you pressed a key it recognized.
There are more scripts to cover, but since they all revolve around editing game metadata, I’m saving them for their own post.
Nostalgia‐Tron, Part 9: A utility script for testing controls.
Sep 6th, 2017 at 12:00 pm Painfully Obvious → Nostalgia-Tron, Part 10: Metadata.
Leve a comment.
Log in using () Name.
Website (optional) Name.
What”s allowed.
syntax, with these caveats… GitHub-Flavored Markdown.
HTML tags/attributes allowed.
Now what.
Subscribe to this entry”s comment feed to follow the discussion.
The weblog of , web developer and writer.

Leave a Reply

Your email address will not be published. Required fields are marked *