Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ServoStiks & RetroPie
#!/usr/bin/env ruby
require 'io/console'
require 'json'
require 'optparse'
require 'pathname'
$opts = OptionParser.new do |opts|
opts.banner = "Usage: joystick-type [options] system game\nReturns the type of joystick for the given system and game."
opts.separator ""
opts.on_tail('-h', '--help', 'Prints this help message.') do
STDOUT.puts(opts)
exit 0
end
end
begin
$opts.parse!
rescue OptionParser::InvalidArgument => e
STDERR.puts("#{e.message}\n\n")
STDERR.puts($opts)
exit 1
end
SYSTEM, GAME = ARGV
CONTROLS_PATH = Pathname.new('/home/pi/controls')
SYSTEM_PATH = CONTROLS_PATH.join(SYSTEM)
unless SYSTEM_PATH.directory?
STDERR.puts(%Q{System #{SYSTEM} does not exist!})
exit 1
end
GAME_PATH = SYSTEM_PATH.join("#{GAME}.cfg")
if GAME_PATH.file?
puts GAME_PATH.read
exit 0
end
# At this point, if the game doesn't have a config file, we can try to look
# up its joystick type _if_ it's an arcade game. Otherwise we're out of luck.
if SYSTEM != 'arcade'
STDERR.puts(%Q{Could not find joystick config file for game #{GAME} on system #{SYSTEM}})
exit 1
end
def decide_on(type)
GAME_PATH.open('w') { |f| f.write(type) }
puts type
exit 0
end
JSON_PATH = SYSTEM_PATH.join('restructuredControls.json')
# Reluctantly read from the gigantic JSON file. But then store what we find
# so that we never have to do the lookup for that game again.
controls = JSON::load(JSON_PATH.open)
# Each game has control configurations. Each control configuration has
# control sets. Each control set, if it has a joystick, specifies whether
# it's 4-way or 8-way.
#
# 99% of the time, these configurations will not disagree about 4-way versus
# 8-way. The remaining 1% can be figured out manually.
game = controls['gameMap'][GAME]
if game.nil?
STDERR.puts(%Q{Game #{GAME} does not exist!})
exit 1
end
sets = game['controlConfigurations'].map { |cfg| cfg['controlSets'] }.flatten
begin
control_types = sets.map { |s| s['controls'][0]['type'] }
rescue Exception => e
STDERR.puts(%Q{Couldn't figure this game out at all. Maybe it doesn't use a joystick.})
exit 1
end
if control_types.all? { |t| t == 'joy-4way' || t == 'joy-2way-horizontal' || t == 'joy-2way-vertical' }
decide_on(4)
elsif control_types.all? { |t| t == 'joy-8way' }
decide_on(8)
else
STDERR.puts "Can't figure out joystick automatically. Here are the options:"
control_types.uniq.each do |type|
STDERR.puts " #{type}"
end
exit 1
end
# ARGUMENTS, IN ORDER:
# 1. System (e.g., "arcade")
# 2. Emulator (e.g. "lr-fba-next")
# 3. Full path to game (e.g., /home/pi/RetroPie/roms/arcade/wjammers.zip)
if [ -z "$3" ]; then
exit 0
fi
system=$1
emulator=$2
# Gets the basename of the game (e.g., "wjammers")
game=$(basename $3)
game=${game%.*}
###
# Return the joystick to 8-way mode no matter what.
# TODO: I don't know why this needs `sudo`. It seems to work fine without it
# in an interactive shell. Investigate.
sudo /home/pi/bin/set-joystick 8
#!/usr/bin/bash
# ARGUMENTS, IN ORDER:
# 1. System (e.g., "arcade")
# 2. Emulator (e.g. "lr-fba-next")
# 3. Full path to game (e.g., /home/pi/RetroPie/roms/arcade/wjammers.zip)
if [ -z "$3" ]; then
exit 0
fi
system=$1
emulator=$2
# Gets the basename of the game (e.g., "wjammers")
game=$(basename $3)
game=${game%.*}
###
# Figure out the joystick mode of the game.
joystick_mode=`/home/pi/bin/joystick-type "$system" "$game"`
# Strip all spaces. Replace "8" with an empty string so it fails the
# conditional below.
joystick_mode=${joystick_mode// /}
joystick_mode=${joystick_mode//8/}
# If the joystick type needs to be switched to 4-way mode, notify the user.
# We don't care about 8-way mode because that's the default. We don't care
# about when `joystick-mode` returns nothing, because in that case we take
# no action.
if [[ ! -z "$joystick_mode" ]]; then
DIALOGRC="/opt/retropie/configs/all/runcommand-launch-dialog.cfg" dialog --infobox "\nSetting joystick to ${joystick_mode}-way mode." 5 60
sleep 0.5
fi
# TODO: I don't know why this needs `sudo`. It seems to work fine without it
# in an interactive shell. Investigate.
sudo /home/pi/bin/set-joystick "$joystick_mode"
#!/usr/bin/env python3
"""
A script for setting the ServoStik to 4-way mode or 8-way mode.
"""
usage = """
Usage: set-joystick [4|8|0]
Takes a single argument which should be either "4" (four-way), "8" (eight-way),
or "0" (which means "I have no clue what to do and am willing to leave it up to
this script to decide.")
"""
import sys
from RPi import GPIO
GPIO.setmode(GPIO.BCM)
MODE_8 = 6 # white
MODE_4 = 5 # green
GPIO.setup(MODE_4, GPIO.OUT)
GPIO.setup(MODE_8, GPIO.OUT)
def set_joystick_mode(mode):
target_pin = MODE_8
other_pin = MODE_4
if mode == 4:
target_pin = MODE_4
other_pin = MODE_8
GPIO.output(other_pin, GPIO.LOW)
GPIO.output(target_pin, GPIO.HIGH)
mode = sys.argv[1]
if mode not in ("0", "4", "8", ""):
print("Invalid argument!", file=sys.stderr)
print(usage)
GPIO.cleanup()
sys.exit(1)
if mode == "0" or mode == "":
# Zero equals a shrug. Put the joystick in 8-way mode.
set_joystick_mode(8)
elif mode == "4":
set_joystick_mode(4)
elif mode == "8":
set_joystick_mode(8)
GPIO.cleanup()
sys.exit()
@Wilstorm

This comment has been minimized.

Copy link

commented Mar 13, 2018

I was curious is this for using an Ultimarc Servostik with RetroPie?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.