Skip to content

Commit

Permalink
joy2key: new version using PySDL2
Browse files Browse the repository at this point in the history
Added a new `joy2key` implementation, using PySDL2 for joystick event handling.
PySDL2 is a python module that wraps SDL2 (and other SDL libraries) using the built-in `ctypes` module.

Pros:
 * event handling is simplified a bit, using SDL's event loop.
 * (subjective) the code is a bit more structured and easy to follow.
 * joystick handling is rewritten based on EmulationStation code, movement is smoother and scrolling is improved.
 * support for input repeat to improve scrolling, just keep the input pressed and scrolling continues

Cons:
 * module is a bit larger (296 LOC vs 224 in current joy2key.py)
 * needs PySDL2 (which might not be packaged, see the notes below) and SDL2
 * arguably, device config to keyboard event mapping is more complex (abstracted as InputDev)

Notes:
 * availability of PySDL2 as a system package is good, but it's not standard in Debian 10 (stable) at the moment.
   The module is present though (as a backport) in Ubuntu 18.04 (and later) and Raspberry Pi OS (Buster).
   When it will be universally available, we should probably revisit the code that checks for the version and make it a hard requirement in `get_retropie_depends`, similar to `python3-pyudev`.

 * added PgUp/PgDown to the default parameters for `joy2key`, they are mapped in a similar fashion to EmulationStation to the shoulder buttons. This doesn't apply to Runcommand's invocation, since it uses a different set of parameters.

 * added a configuration option in `runcommand` for selecting the joy2key version used. Default is the SDL version (when PySDL2 is installed), with the ability to fallback to the previous version (udev based).
  • Loading branch information
cmitu committed Jun 28, 2021
1 parent 3e3fd25 commit fab62e2
Show file tree
Hide file tree
Showing 5 changed files with 582 additions and 15 deletions.
24 changes: 18 additions & 6 deletions scriptmodules/helpers.sh
Expand Up @@ -1213,7 +1213,7 @@ _EOF_
## @param but2 mapping for button 2
## @param but3 mapping for button 3
## @param butX mapping for button X ...
## @brief Start joy2key.py process in background to map joystick presses to keyboard
## @brief Start joy2key process in background to map joystick presses to keyboard
## @details Arguments are curses capability names or hex values starting with '0x'
## see: http://pubs.opengroup.org/onlinepubs/7908799/xcurses/terminfo.html
function joy2keyStart() {
Expand All @@ -1223,18 +1223,30 @@ function joy2keyStart() {
local params=("$@")
if [[ "${#params[@]}" -eq 0 ]]; then
params=(kcub1 kcuf1 kcuu1 kcud1 0x0a 0x20 0x1b)
# Default button-to-keyboard mappings:
# * cursor keys for axis/dpad
# * enter, space and esc for buttons 'a', 'b' and 'x'
# * page up/page down for buttons 5,6 (shoulder buttons)
params=(kcub1 kcuf1 kcuu1 kcud1 0x0a 0x20 0x1b 0x00 kpp knp)
fi
# Choose the joy2key implementation here, since `runcommand` may not be installed
local joy2key="joy2key.py"
if hasPackage "python3-sdl2"; then
iniConfig " =" '"' "$configdir/all/runcommand.cfg"
iniGet "joy2key_version"
[[ $ini_value != "0" ]] && joy2key="joy2key_sdl.py"
fi
# get the first joystick device (if not already set)
[[ -c "$__joy2key_dev" ]] || __joy2key_dev="/dev/input/jsX"
# if no joystick device, or joy2key is already running exit
[[ -z "$__joy2key_dev" ]] || pgrep -f joy2key.py >/dev/null && return 1
[[ -z "$__joy2key_dev" ]] || pgrep -f "$joy2key" >/dev/null && return 1
# if joy2key.py is installed run it with cursor keys for axis/dpad, and enter + space for buttons 0 and 1
if "$scriptdir/scriptmodules/supplementary/runcommand/joy2key.py" "$__joy2key_dev" "${params[@]}" 2>/dev/null; then
__joy2key_pid=$(pgrep -f joy2key.py)
# if joy2key is installed, run it
if "$scriptdir/scriptmodules/supplementary/runcommand/$joy2key" "$__joy2key_dev" "${params[@]}" 2>/dev/null; then
__joy2key_pid=$(pgrep -f "$joy2key")
return 0
fi
Expand Down
27 changes: 22 additions & 5 deletions scriptmodules/supplementary/runcommand.sh
Expand Up @@ -28,11 +28,11 @@ function depends_runcommand() {
}

function install_bin_runcommand() {
cp "$md_data/runcommand.sh" "$md_inst/"
cp "$md_data/joy2key.py" "$md_inst/"
chmod a+x "$md_inst/runcommand.sh"
chmod a+x "$md_inst/joy2key.py"
python3 -m compileall "$md_inst/joy2key.py"
for file in "runcommand.sh" "joy2key.py" "joy2key_sdl.py"; do
cp "$md_data/$file" "$md_inst/"
chmod +x "$md_inst/$file"
done
python3 -m compileall "$md_inst/joy2key.py" "$md_inst/joy2key_sdl.py"
if [[ ! -f "$configdir/all/runcommand.cfg" ]]; then
mkUserDir "$configdir/all"
iniConfig " = " '"' "$configdir/all/runcommand.cfg"
Expand All @@ -41,8 +41,16 @@ function install_bin_runcommand() {
iniSet "governor" ""
iniSet "disable_menu" "0"
iniSet "image_delay" "2"
if hasPackage "python3-sdl2"; then
iniSet "joy2key_version" "1"
fi
chown $user:$user "$configdir/all/runcommand.cfg"
fi
# if PySDL2 is not installed, force the udev version of joy2key
if ! hasPackage "python3-sdl2"; then
iniConfig " = " '"' "$configdir/all/runcommand.cfg"
iniSet "joy2key_version" "0"
fi
if [[ ! -f "$configdir/all/runcommand-launch-dialog.cfg" ]]; then
dialog --create-rc "$configdir/all/runcommand-launch-dialog.cfg"
chown $user:$user "$configdir/all/runcommand-launch-dialog.cfg"
Expand Down Expand Up @@ -108,6 +116,7 @@ function gui_runcommand() {
'disable_joystick=0' \
'image_delay=2' \
'governor=' \
'joy2key_version=1' \
)"

[[ -z "$governor" ]] && governor="Default: don't change"
Expand Down Expand Up @@ -135,6 +144,11 @@ function gui_runcommand() {

options+=(4 "Launch image delay in seconds (currently $image_delay)")
options+=(5 "CPU governor configuration (currently: $governor)")
if [[ "$joy2key_version" -eq 1 ]]; then
options+=(6 "Joy2key version (currently: sdl)")
else
options+=(6 "Joy2key version (currently: udev)")
fi

local choice=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
[[ -z "$choice" ]] && break
Expand All @@ -157,6 +171,9 @@ function gui_runcommand() {
5)
governor_runcommand
;;
6)
iniSet "joy2key_version" "$((joy2key_version ^ 1))"
;;
esac
done
}

0 comments on commit fab62e2

Please sign in to comment.