安卓设备手柄无法映射线性扳机的解决思路(1)

[转载需注明作者及出处]
此方案需要安卓设备已经获取Root权限,并且本文只提供一个解决思路,文中所给代码并不能直接用在自己的设备上,请自行修改以适配自己的设备。
测试设备:小新pad pro 2021,安卓11


一、前言
众所周知移动端原生支持手柄的游戏实在不多,要用手柄畅玩流行手游基本上需要映射,还有模拟器使用手柄作为输入设备也需要通过键位映射。
博主最近买了很多手柄用在安卓设备上,发现其中有一些手柄的线性扳机无法使用映射app映射成屏幕点击,使用天际线模拟器时也无法成功映射成L2R2键,我研究了一个晚上解决了这个问题,并为手柄功能拓展提出了一些思路,故写此文为遇到同样问题的朋友提供参考。
理论上适用于所有手柄,已Root的安卓设备和Linux设备。
测试所用手柄:
原装DualShock 4(PS4配柄):USB连接和蓝牙连接,线性扳机
国产DualShock 4:蓝牙连接,线性扳机
1UP GC1(乐升盒子配柄):蓝牙连接,线性扳机
Obox OC1(蜗牛主机配柄):蓝牙连接,线性扳机
Fuze手柄(战斧F1主机配柄):蓝牙连接,线性扳机
国产xbox360手柄有线:USB连接,线性扳机
飞智八爪鱼一代:蓝牙连接,USB2.4G接收器,线性扳机
飞智Wee一代:蓝牙连接,无线性扳机
映射使用的APP(线性扳机无法映射的问题应该与APP无关):
ZUI外设模式
北通游戏厅
Mantis Gamepad
Shanwan Gamepad


二、问题分析
博主测试不同手柄线性扳机输入的过程中,发现了三种不同的输入模式:
1、只有GAS和BRAKE输入。

1d3c95a7cfa3487e9854fd674ae82b4e.png

2、同时有GAS/RTRIGGER 和 BRAKE/LTRIGGER的输入信号并且绑定在一起。

b2b1c2eaf72c40359542d8d71866907f.png
3、不仅同时有GAS/RTRIGGER 和 BRAKE/LTRIGGER的输入信号(ABS事件),并且在线性扳机的值达到某个阈值时会触发输入BUTTON_L2或BUTTON_R2(KEY事件),这种情况是手柄内部程序做了补偿,可能是为了兼容其他平台(ds4和飞智八爪鱼就是这种输入模式)。

b994383c62344aa8888f3f22482368c3.png

第一种情况通常表现为在软件中设置键位映射时识别不到扳机键
第二种情况通常表现为在软件中设置键位映射可以将扳机键识别为L2/R2,但是在游戏中无法触发映射;
第三种情况则可以正常识别按键也可以正常触发。

因为线性扳机的输入事件与摇杆同为ABS事件,输入的是模拟量;而普通按键输入的是KEY事件,只有0和1两种输入;我们点击屏幕的行为跟KEY事件是同类型的,如果手柄自身没有做BUTTON_L2/R2输入补偿,大部分映射软件不能把模拟输入映射为按键输入,因此出现了线性扳机无法映射的情况。
而博主使用飞智Wee手柄没有线性扳机,扳机键跟普通按键一样输入KEY事件,就不存在这种问题。


三、解决方法
1、修改kl文件
经测试发现,只有GAS和BRAKE输入的时候,映射软件无法识别;通过配置kl文件将两个扳机键绑定到LTRIGGER和RTRIGGER,映射软件就可以识别,并且部分设备设置到这一步就可以实现扳机键的映射,如果还是无法完成映射请看第二期。
这里使用1UP GC1手柄进行演示,这个手柄的扳机输入只有GAS和BRAKE,通过修改kl文件之后可以有LTRIGGER和RTRIGGER的输入信号。
kl文件位于/system/usr/keylayout目录中,部分设备需要解锁system分区才能修改,请自行解决分区解锁的问题。
kl文件的命名格式为文件命名格式为Vendor_xxxx_Product_xxxx.kl,如果能找到自己设备的文件,那么直接修改即可(一般是大厂设备比如xbox和ps手柄);而我手上的1UP GC1手柄在keylayout目录中是没有kl文件的,我们需要手动创建。
下面教大家如何查找自己设备的vendor和product代码。
首先打开终端(题主用的Termux)并输入su获取root权限,输入getevent命令,会弹出当前的input event信息并实时打印输入事件到屏幕上,我们随便按两下手柄上的按键可以看到终端中有输出信息,记下自己设备的event编号,题主这里是event21

$ su

# getevent

298fa4d844aa430aa25cd509cc857553.png
然后输入getevent -i /dev/input/event21,就可以看到自己设备的信息(想了解这些信息代表什么意思可以自行查找linux输入子系统的资料进行学习)

# getevent -i /dev/input/event21

dcc08368083a4039850cb32fb687e7e7.png可以看到vendor是1d79,product是1001,于是我们在/system/usr/keylayout目录中创建一个文件命名为Vendor_1d79_Product_1001.kl,打开后输入以下内容:(具体kl文件如何编写请自行查找资料,网上都有的)

# 1UP GC1
key 304 BUTTON_A
key 305 BUTTON_B
key 307 BUTTON_X
key 308 BUTTON_Y
key 310 BUTTON_L1
key 311 BUTTON_R1
key 315 BUTTON_START
key 314 BUTTON_SELECT
key 172 BUTTON_MODE
key 317 BUTTON_THUMBL
key 318 BUTTON_THUMBL

axis 0x00 X
axis 0x01 Y
axis 0x02 Z
axis 0x05 RZ
axis 0x09 RTRIGGER        #重点
axis 0x0a LTRIGGER        #重点
axis 0x10 HAT_X
axis 0x11 HAT_Y


这边要做的工作主要是将两个扳机的axis量绑定到RTRIGGER和LTRIGGER,
如果这两句改为

axis 0x09 GAS
axis 0x0a BRAKE


则app检测到的只有GAS和BRAKE
不是所有手柄的输入信号都是跟我这个手柄一样,就是说扳机键的输入信号不一定是0x09和0x0a,需要根据自己手柄的情况进行修改,获取输入信号的方法如下:
在终端中输入getevent  /dev/input/event21,拉一下左扳机可以看到很多输出,这里的输出全部使用16进制表示,0003表示输入ABS事件(即axis),000a就是我们写在kl文件中的0x0a。同理设置右扳机。

getevent  /dev/input/event21

081d61b33e444436be553bc8fa5d0279.png
编辑完kl文件后保存重新连接手柄,就可以检查自己的手柄扳机能否正常映射了。
如果还是不能请看第二期。

猜你喜欢

转载自blog.csdn.net/oyanzhishiyue/article/details/125966856
今日推荐