""" retrogamepy.py by Marcus Schebesta 24 Aug 2016
based on rpi-gpio-jstk.py by Chris Swan 9 Aug 2012
GPIO keyboard,mouse,joystick simulator
requires uinput kernel module (sudo modprobe uinput)
requires python-uinput
(git clone https://github.com/tuomasjjrasanen/python-uinput)
requires python RPi.GPIO (from http://pypi.python.org/pypi/RPi.GPIO/0.3.1a)
Changes
24 Aug 2016 - First Version
"""
import uinput
import time
import sys
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
# GPIO Mapping
pin_left = 23
pin_right = 0
pin_up = 22
pin_down = 1
pin_a = 16
pin_b = 6
pin_x = 26
pin_y = 19
pin_l = 21
pin_r = 20
pin_start = 12
pin_select = 5
pin_mode = 99 # To change between keyboard, mouse or joystick at runtime!
mode = 1
# mode = 1 -> Keyboard
# mode = 2 -> Mouse
# mode = 3 -> Joystick
# Keys Mapping -> Mode 1
key_left = uinput.KEY_LEFT
key_right = uinput.KEY_RIGHT
key_up = uinput.KEY_UP
key_down = uinput.KEY_DOWN
key_a = uinput.KEY_A
key_b = uinput.KEY_B
key_x = uinput.KEY_X
key_y = uinput.KEY_Y
key_l = uinput.KEY_RETURN # To enable system menu navigation
key_r = uinput.KEY_ESC # To enable system menu navigation
key_start = uinput.KEY_E
key_select = uinput.KEY_S
# Mouse Mapping (with ScummVM in mind) -> Mode 2
mouse_axis_x = uinput.REL_X
mouse_axis_y = uinput.REL_Y
mouse_a = uinput.BTN_LEFT
mouse_b = uinput.BTN_RIGHT
mouse_x = uinput.BTN_MIDDLE
mouse_y = uinput.KEY_F2
mouse_l = uinput.KEY_RETURN # To enable system menu navigation
mouse_r = uinput.KEY_ESC # To enable system menu navigation
mouse_start = uinput.KEY_F5
mouse_select = uinput.KEY_F1
# Joystick Mapping -> Mode 3
joystick_axis_x = uinput.ABS_X
joystick_axis_y = uinput.ABS_Y
joystick_a = uinput.BTN_JOYSTICK
joystick_b = uinput.KEY_B
joystick_x = uinput.KEY_X
joystick_y = uinput.KEY_Y
joystick_l = uinput.KEY_RETURN # To enable system menu navigation
joystick_r = uinput.KEY_ESC # To enable system menu navigation
joystick_start = uinput.KEY_E
joystick_select = uinput.KEY_S
# Setup GPIO's
GPIO.setup(pin_left, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_right, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_up, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_down, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_a, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_b, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_x, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_y, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_l, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_r, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_start, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_select, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_mode, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Setup Flags
flag_up = False
flag_down = False
flag_left = False
flag_right = False
flag_a = False
flag_b = False
flag_x = False
flag_y = False
flag_l = False
flag_r = False
flag_start = False
flag_select = False
flag_mode = False
# Setup Events
if mode == 1:
events = (key_left,
key_right,
key_up,
key_down,
key_a,
key_b,
key_x,
key_y,
key_l,
key_r,
key_start,
key_select)
elif mode == 2:
events = (mouse_axis_x + (0, 255, 0, 0),
mouse_axis_y + (0, 255, 0, 0),
mouse_a,
mouse_b,
mouse_x,
mouse_y,
mouse_l,
mouse_r,
mouse_start,
mouse_select)
elif mode == 3:
events = (joystick_axis_x + (0, 255, 0, 0),
joystick_axis_y + (0, 255, 0, 0),
joystick_a,
joystick_b,
joystick_x,
joystick_y,
joystick_l,
joystick_r,
joystick_start,
joystick_select)
else:
sys.exit("Mode Error")
# Setup uinput, give it a little extra time :)
device = uinput.Device(events)
time.sleep(1)
# Setup Mouse and Joystick
if mode == 2:
device.emit(mouse_axis_x, 128, syn=False)
device.emit(mouse_axis_y, 128)
elif mode == 3:
device.emit(joystick_axis_x, 128, syn=False)
device.emit(joystick_axis_y, 128)
# Main Loop
while True:
#------------ Mode pin ---------------
if (not flag_mode) and (not GPIO.input(pin_mode)): # Mode pressed
flag_mode = True
if flag_mode and GPIO.input(pin_mode): # Mode released
flag_mode = False
if mode == 3:
mode = 1
else:
mode += 1
#------------ Up pin ---------------
if (not flag_up) and (not GPIO.input(pin_up)): # Up pressed
flag_up = True
if mode == 1:
device.emit(key_up, 1)
elif mode == 2:
device.emit(mouse_axis_y, 0) # Zero Y
elif mode == 3:
device.emit(joystick_axis_y, 0) # Zero Y
if flag_up and GPIO.input(pin_up): # Up released
flag_up = False
if mode == 1:
device.emit(key_up, 0)
elif mode == 2:
device.emit(mouse_axis_y, 128) # Center Y
elif mode == 3:
device.emit(joystick_axis_y, 128) # Center Y
#------------ Down pin ---------------
if (not flag_down) and (not GPIO.input(pin_down)): # Down pressed
flag_down = True
if mode == 1:
device.emit(key_down, 1)
elif mode == 2:
device.emit(mouse_axis_y, 255) # Max Y
elif mode == 3:
device.emit(joystick_axis_y, 255) # Max Y
if flag_down and GPIO.input(pin_down): # Down released
flag_down = False
if mode == 1:
device.emit(key_down, 0)
elif mode == 2:
device.emit(mouse_axis_y, 128) # Center Y
elif mode == 3:
device.emit(joystick_axis_y, 128) # Center Y
#------------ Left pin ---------------
if (not flag_left) and (not GPIO.input(pin_left)): # Left pressed
flag_left = True
if mode == 1:
device.emit(key_left, 1)
elif mode == 2:
device.emit(mouse_axis_x, 0) # Zero X
elif mode == 3:
device.emit(joystick_axis_x, 0) # Zero X
if flag_left and GPIO.input(pin_left): # Left released
flag_left = False
if mode == 1:
device.emit(key_left, 0)
elif mode == 2:
device.emit(mouse_axis_x, 128) # Center X
elif mode == 3:
device.emit(joystick_axis_x, 128) # Center X
#------------ Right pin ---------------
if (not flag_right) and (not GPIO.input(pin_right)): # Right pressed
flag_right = True
if mode == 1:
device.emit(key_right, 1)
elif mode == 2:
device.emit(mouse_axis_x, 255) # Max X
elif mode == 3:
device.emit(joystick_axis_x, 255) # Max X
if flag_right and GPIO.input(pin_right): # Right released
flag_right = False
if mode == 1:
device.emit(key_right, 0)
elif mode == 2:
device.emit(mouse_axis_x, 128) # Center X
elif mode == 3:
device.emit(joystick_axis_x, 128) # Center X
#------------ A pin ---------------
if (not flag_a) and (not GPIO.input(pin_a)): # A pressed
flag_a = True
if mode == 1:
device.emit(key_a, 1)
elif mode == 2:
device.emit(mouse_a, 1)
elif mode == 3:
device.emit(joystick_a, 1)
if flag_a and GPIO.input(pin_a): # A released
flag_a = False
if mode == 1:
device.emit(key_a, 0)
elif mode == 2:
device.emit(mouse_a, 0)
elif mode == 3:
device.emit(joystick_a, 0)
#------------ B pin ---------------
if (not flag_b) and (not GPIO.input(pin_b)): # B pressed
flag_b = True
if mode == 1:
device.emit(key_b, 1)
elif mode == 2:
device.emit(mouse_b, 1)
elif mode == 3:
device.emit(joystick_b, 1)
if flag_b and GPIO.input(pin_b): # B released
flag_b = False
if mode == 1:
device.emit(key_b, 0)
elif mode == 2:
device.emit(mouse_b, 0)
elif mode == 3:
device.emit(joystick_b, 0)
#------------ X pin ---------------
if (not flag_x) and (not GPIO.input(pin_x)): # X pressed
flag_x = True
if mode == 1:
device.emit(key_x, 1)
elif mode == 2:
device.emit(mouse_x, 1)
elif mode == 3:
device.emit(joystick_x, 1)
if flag_x and GPIO.input(pin_x): # X released
flag_x = False
if mode == 1:
device.emit(key_x, 0)
elif mode == 2:
device.emit(mouse_x, 0)
elif mode == 3:
device.emit(joystick_x, 0)
#------------ Y pin ---------------
if (not flag_y) and (not GPIO.input(pin_y)): # Y pressed
flag_y = True
if mode == 1:
device.emit(key_y, 1)
elif mode == 2:
device.emit(mouse_y, 1)
elif mode == 3:
device.emit(joystick_y, 1)
if flag_y and GPIO.input(pin_y): # Y released
flag_y = False
if mode == 1:
device.emit(key_y, 0)
elif mode == 2:
device.emit(mouse_y, 0)
elif mode == 3:
device.emit(joystick_y, 0)
#------------ L pin ---------------
if (not flag_l) and (not GPIO.input(pin_l)): # L pressed
flag_l = True
if mode == 1:
device.emit(key_l, 1)
elif mode == 2:
device.emit(mouse_l, 1)
elif mode == 3:
device.emit(joystick_l, 1)
if flag_l and GPIO.input(pin_y): # L released
flag_l = False
if mode == 1:
device.emit(key_l, 0)
elif mode == 2:
device.emit(mouse_l, 0)
elif mode == 3:
device.emit(joystick_l, 0)
#------------ R pin ---------------
if (not flag_r) and (not GPIO.input(pin_r)): # R pressed
flag_r = True
if mode == 1:
device.emit(key_r, 1)
elif mode == 2:
device.emit(mouse_r, 1)
elif mode == 3:
device.emit(joystick_r, 1)
if flag_r and GPIO.input(pin_r): # R released
flag_r = False
if mode == 1:
device.emit(key_r, 0)
elif mode == 2:
device.emit(mouse_r, 0)
elif mode == 3:
device.emit(joystick_r, 0)
#------------ Start pin ---------------
if (not flag_start) and (not GPIO.input(pin_start)): # Start pressed
flag_start = True
if mode == 1:
device.emit(key_start, 1)
elif mode == 2:
device.emit(mouse_start, 1)
elif mode == 3:
device.emit(joystick_start, 1)
if flag_start and GPIO.input(pin_start): # Start released
flag_start = False
if mode == 1:
device.emit(key_start, 0)
elif mode == 2:
device.emit(mouse_start, 0)
elif mode == 3:
device.emit(joystick_start, 0)
#------------ Select pin ---------------
if (not flag_select) and (not GPIO.input(pin_select)): # Select pressed
flag_select = True
if mode == 1:
device.emit(key_select, 1)
elif mode == 2:
device.emit(mouse_select, 1)
elif mode == 3:
device.emit(joystick_select, 1)
if flag_select and GPIO.input(pin_select): # Select released
flag_select = False
if mode == 1:
device.emit(key_select, 0)
elif mode == 2:
device.emit(mouse_select, 0)
elif mode == 3:
device.emit(joystick_select, 0)
time.sleep(.02) # Poll every 20ms (otherwise CPU load gets too high)