在 Linux 中处理 tty 中的游戏手柄按钮点击

Posted

技术标签:

【中文标题】在 Linux 中处理 tty 中的游戏手柄按钮点击【英文标题】:Handling gamepad button clicks in tty, in Linux 【发布时间】:2021-12-29 09:55:32 【问题描述】:

我有一个带有 EmulationStation 的 Linux 设备(键盘通过 USB 连接到它)。我想在终端中处理游戏手柄击键,这样我就不必为此插入键盘。

检测游戏手柄按键代码的测试脚本:

#!/bin/bash

echo 'Press button "L1":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "L1":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "L2":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "L2":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "Up":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "Up":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "Down":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "Down":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "Left":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "Left":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "Right":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "Right":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "Select":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "Select":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "L3":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "L3":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "Start":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "Start":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "X":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "X":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "Y":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "Y":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "B":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "B":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "A":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "A":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "R3":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "R3":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "R2":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "R2":' >> keycode.txt
echo "$key" >> keycode.txt

echo 'Press button "R1":'
key=`jstest --event /dev/input/js0 | grep -m 1 "type 1, time .*, number .*, value 1" | awk -F ',' 'print $3' | awk 'print $2'`
echo 'Button "R1":' >> keycode.txt
echo "$key" >> keycode.txt

当您通过 SSH 连接或退出 EmulationStation 并启动 tty 时,脚本正常工作,当您按下游戏手柄键时,检测到键码,成功写入文件,过程完成。

如果脚本直接从 EmulationStation 运行,就会出现问题,显然 jstest --event /dev/input/js0 正在循环。

从 EmulationStation 运行脚本的过程如下所示:

Press button "L1":

脚本不响应游戏手柄按键,或者我们看不到它。同时连接游戏手柄,使用第二个脚本可以看出按键的不同:

#!/bin/bash

jstest --event /dev/input/js0

第二个脚本的输出:

Event: type 1, time -195236, number 9, value 1
Event: type 1, time -195128, number 9, value 0
Event: type 1, time -194840, number 8, value 1
Event: type 1, time -194744, number 8, value 0
Event: type 1, time -194492, number 10, value 1
Event: type 1, time -194360, number 10, value 0
Event: type 1, time -194096, number 9, value 1
Event: type 1, time -194096, number 11, value 1
Event: type 1, time -194000, number 9, value 0
Event: type 1, time -193988, number 11, value 0

显然,问题与循环无限期运行有关,使用grep -m 1 "type 1, time .*, number .*, value 1" 并不会结束它。

当脚本不工作时,ps aux 显示如下进程:

user        635  0.0  0.0   2048   508 ?        S    03:58   0:00 sh -c sudo chmod 666 /dev/tty1; /opt/system/Scripts/Keycode.sh > /dev/tty1; printf "\033c" >> /dev/tty1
user        645  0.0  0.3   6464  2916 ?        S    03:58   0:00 /bin/bash /opt/system/Scripts/Keycode.sh
user        646  0.0  0.1   6464  1572 ?        S    03:58   0:00 /bin/bash /opt/system/Scripts/Keycode.sh
user        647  0.0  0.0   1924   464 ?        S    03:58   0:00 jstest --event /dev/input/js0
user        651  0.0  0.2   8416  2728 pts/0    R+   03:59   0:00 ps aux

我想从 EmulationStation 运行一个脚本,以便它对按下游戏手柄按钮作出反应。如果有其他方法可以在不使用 GUI 的情况下执行此操作,请编写。

【问题讨论】:

【参考方案1】:

我通过使用这个 perl module 解决了终端中游戏手柄输入的问题。

【讨论】:

以上是关于在 Linux 中处理 tty 中的游戏手柄按钮点击的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Linux 中从 Mono/C# 访问游戏杆/游戏手柄?

如何在 Windows 中禁用游戏手柄/操纵杆上的按钮/轴?

Arduino Leonardo 作为游戏手柄

当我在模拟器中按下 Apple TV 游戏手柄按钮时,它们不会触发

如何编写程序可以检测 C++ 中游戏手柄按钮的信号? [关闭]

为游戏手柄创建自定义设备驱动程序