Browse by type
索尼PS4手柄(也叫DualShock4 DS4)、任天堂Switch JoyCons(成对使用)以及Switch Pro手柄有很多共同点。他们有许多现代游戏控制器应有的功能。此外,他们还拥有其最大的竞争对手(微软的Xbox One控制器)所没有的特殊功能: 3轴陀螺仪(以下简称“体感/陀螺仪”)。
我使用JoyShockMapper(JSM)的目标是使你能够使用DS4、JoyCons和Pro手柄畅玩PC端的游戏,甚至比你在它们各自的主机上玩得更好——并演示,证明更多游戏应该包含的操作模式。
点击这里 下载JoyShockMapper!
对于开发者来说,这也是一个使用JoyShockLibrary(JSL) 读取DualShock 4、JoyCons和Pro手柄输入的借鉴参考。它也是“体感维基(GyroWiki) ”上描述的许多最佳实践的案例。
JSM在Windows(Win)上工作,它使用JSL从手柄读取输入,而手柄(以下称控制器)只对Win进行编译。但是JSL没有使用Win指定的特性,而JSM只使用特定于Win的代码来模拟键盘和鼠标,并将特定于Win的代码与inputHelpers.cpp隔离开来。因此,我希望其他开发人员能够轻松地让JSL和JSM在其他平台(如Linux或Mac)上工作。
JoyShockMapper是用c++编写的,使用CMake构建。
项目被构造成一组平台无关的头文件,而特定于平台的源文件可以在它们各自的子目录中找到。
以下文件是平台无关的:
1. include/InputHelpers.h - 这是平台无关的声明包装OS函数调用和特性。
2. include/PlatformDefinitions.h - 这是一组声明,在处理特定于平台的类型和定义时创建了一个公共基础。
3. include/TrayIcon.h - 这是一个自包含的模块,用于在Windows中显示一个带有上下文菜单的系统托盘图标。
4. include/Whitelister.h - 这是另一个自包含的Windows特定模块,它使用套接字与HIDCerberus和白列表JSM通信,Linux实现目前是一个存根。
5. main.cpp - 它完成了应用程序的所有主要逻辑。它可能有点大,但我选择保持文件结构简单,代价是有一个大的主文件。
Windows实现可以在以下文件中找到:
1. src/win32/InputHelpers.cpp
2. src/win32/PlatformDefinitions.cpp
3. src/win32/Whitelister.cpp.cpp
4. include/win32/WindowsTrayIcon.h
5. src/win32/WindowsTrayIcon.cpp
Linux实现可在以下文件中找到:
1. src/linux/InputHelpers.cpp
2. src/linux/PlatformDefinitions.cpp
3. src/linux/Whitelister.cpp.cpp
4. include/linux/StatusNotifierItem.h
5. src/linux/StatusNotifierItem.cpp
通过在项目根目录下的命令提示符中运行以下命令生成项目:
-窗口:
* mkdir build && cd build
创建一个Visual Studio x86配置: cmake .. -G "Visual Studio 16 2019" -A Win32 .
创建一个Visual Studio x64配置: cmake .. -G "Visual Studio 16 2019" -A x64 .
Linux:
* mkdir build && cd build
* cmake .. -DCMAKE_CXX_COMPILER=clang++ && cmake --build .
为了建立在Linux上,必须满足以下依赖,与他们各自的开发包: - gtk + 3 - libappindicator3 - libevdev
由于GCC中的bug,当前形式的项目将只使用Clang构建。
JoyShockMapper最初是为Windows开发的,它的副作用是代码库中使用的某些类型是特定于Windows的。这些已经在Linux上重新定义。这样做是为了将对应用程序核心逻辑的更改保持在最低限度,并降低导致现有用户回归的可能性。
应用程序需要rw访问/dev/uinput和 /dev/hidraw[0-n](实际设备取决于操作系统分配的节点)。这可以通过chown -ing所需的设备节点给运行应用程序的用户来实现,或者通过应用dist/linux/50-joyshockmapper.rules中的udev规则,将用户添加到输入组,并重新启动计算机使更改生效。更多关于udev规则的信息可以在
https://wiki.archlinux.org/index.php/Udev#About_udev_rules 找到。
该应用程序将在X11和Wayland上工作,尽管聚焦窗口检测只在X11上工作。
最新版本的JoyShockMapper总是可以在这里 找到。你所要做的就是运行JoyShockMapper.exe。
包括一个叫作GyroConfigs的文件夹。这包括为2D和3D游戏创建新配置的模板,以及包含用于简单RW校准的配置文件。
1.通过USB或蓝牙连接你的DualShock 4(DS4),或通过蓝牙连接你的JoyCons或Pro控制器。
2.运行JoyShockMapper.exe,你将看到一个控制台窗口“欢迎使用JoyShockMapper!” * 如果你想在启动JSM后连接你的控制器,你可以使用命令RECONNECT_CONTROLLERS来连接这些控制器。
3.拖入一个配置文件并按enter键加载该文件中的所有设置。 * Configuration文件只是文本文件。文本文件中的每个命令都可以直接输入到控制台窗口中。有关JSM命令的全面指南,请参阅下面的“命令”。 示例配置文件包含在GyroConfigs文件夹中。
4.如果你正在使用一个配置,利用陀螺仪/体感控制,陀螺仪将需要校准(被告知什么是“静止的”)。见“命令”下的“陀螺鼠标输入”获得更多信息,但这里有简短的版本: * 把所有的控制器放在一个静止的表面上; * 输入命令RESTART_GYRO_CALIBRATION开始对它们进行校准; * 几秒钟后,输入命令FINISH_GYRO_CALIBRATION来完成对它们的校准。
5.一个好的配置文件已经校准了灵敏度设置到有用的RW值。这使得转换灵敏度在不同的游戏之间变得很容易,不同的游戏对于他们自己的灵敏度设置有不同的尺度。更多信息请参见下面的RW校准。
6.每次游戏窗口进入焦点时,JSM可以自动加载游戏配置文件。将文件放入自动加载文件夹中,挨着可执行文件(exe)。JSM将根据启动的程序的可执行名称查找配置。当它进入焦点并启用自动加载时(默认情况下),JSM将告诉你它要查找的文件的名称—不区分大小写。你可以通过输入命令AUTOLOAD = off来关闭它。你也可以通过AUTOLOAD = ON再次启用它。
7.支持控制器的游戏,比如Apex Legends,有时候并不能忽略你的控制器(会导致控制器与虚拟键鼠冲突)。像HIDGuardian / HIDCerberus这样的程序允许你屏蔽除白名单之外的所有应用程序。如果你已经安装并运行了HIDCerberus,那么可以通过输入命令WHITELIST_ADD将JoyShockMapper添加到白名单中,通过命令WHITELIST_REMOVE将其删除,并且你可以通过输入WHITELIST_SHOW在浏览器中显示HIDCerberus配置页面。
只需在JSM控制台窗口中输入命令并按“enter”即可执行命令。你还可以将一些命令放到文本文件中,通过在JSM中输入文件的路径(完整路径或相对于JSM可执行文件的路径)并单击’enter’,执行所有这些命令。我将这样的文件称为“配置文件(configuration file)”。在Windows中,还可以将文件从文件游览器(Explorer)拖放到JSM控制台窗口中,以输入该文件的完整路径。
配置文件还可以包含对其他配置文件的引用。这可以简化在不同游戏中的共享设置——如果你有首选的摇杆和陀螺设置,你可以将它们保存在一个单独的文件中,并让所有其他配置文件引用该文件,而不是将摇杆和体感设置复制上百遍。
大部分命令可以被分为4类:
1.数字输入. 这些是最简单的。将控制器按键按下或移动映射到键盘按键或鼠标按键上。有许多可用的映射选项,如短按/长按键,同时下压键和组合键。
2.模拟扳机. Dualshock 4控制器有2个模拟扳机:L2和R2。JSM可以在扳机的“半按”和“全按”上设置不同的映射,最大化地使用这些扳机。这一功能对于有数字扳机的控制器是不可用的,比如任天堂Pro和Joycons。
3.摇杆鼠标. 你可以通过摇杆/体感移动鼠标指针。摇杆鼠标有两种模式:
4.体感鼠标. 用陀螺仪控制鼠标通常比用摇杆要精确的多。可以把陀螺仪想象成一个放在在隐形、无摩擦的鼠标垫上的鼠标。无论你如何舒服地旋转控制器,鼠标垫都可以延伸。对于直接控制视角的游戏来说,固定的鼠标输入提供了快捷的方式来完成小精度的大旋转,而陀螺鼠标输入允许你在相对有限的范围内做出更精确、快速的运动。
5.RW校准. 校准正确可以使甩枪瞄准更精确,为陀螺仪和瞄准摇杆设置有意义的现实参考数据,并为允许玩家在不同游戏之间分享相同的灵敏度设置。
6.快速切换. 各种配置可以根据控制器当前按下的按键重新设置,类似于组合按键。例如这可以很方便的处理“武器轮盘”。根据SI命名被称为“快速切换(modeshifts)”。
7.其他的命令. 它们不属于上述类别,但仍然很有用。
因此,让我们深入研究可用的命令。
数字输入真的很简单。它们的结构大致如下:
[Controller Input] = [Key or Mouse Button]
例如,要将方向点映射到左边的F1键,你需要输入:
LEFT = F1
JSM的一个重要特性是,适用于DualShock 4的配置同样适用于一对JoyCons或Pro控制器。因为JoyCons的输入比DualShock 4稍微多一点(JoyCons有SL和SR),所以按键的名字大多来自任天堂设备。主要的例外是face按键和stick-click(摇杆下压)。因为它们的名字更简洁,摇杆下压以DualShock 4命名:L3 和R3.
face按键是一个更复杂的东西。
Xbox的布局实际上已经成为PC控制器的布局。大多数使用某种控制器的PC玩家都很熟悉Xbox的布局,无论是Xbox控制器、Steam控制器,还是其他可以被游戏理解为Xbox控制器的第三方控制器。即使是DualShock 4的用户也会在某种程度上习惯Xbox face按键的名称。任天堂的设备有相同的正面按键,但布局不同。X和Y互换了,A和B也互换了。任天堂的布局也存在了较长时间,但PC玩家并不太熟悉。
因此,在我看来,最好的解决方案是两种布局都不使用,而是使用一个明确的命名系统,其中的按键名称不采用任何控制器的,但仍然有明显的方向。北、东、南、西,分别用N、E、S、W表示。
所以,这里是完整的数字输入列表:
UP: d-pad的↑
DOWN: d-pad的↓
LEFT: d-pad的←
RIGHT: d-pad的→
L: L1 or L, 左侧小肩键
ZL: L2 or ZL, 左侧大肩键 (或扳机)
R: R1 or R, 右侧小肩键
ZR: R2 or ZR, 右侧大肩键 (或扳机)
ZRF: 完全下压右扳机, 只有DS4有
ZLF: 完全下压左扳机, 只有DS4有
-: share 或 -
+: option 或 +
HOME: PS 或Home
CAPTURE: 触控板下压 或 Capture
SL: SL, 只有JoyCons有
SR: SR, 只有JoyCons有
L3: 左摇杆下压
R3: 右摇杆下压
N: 朝北按键, △ 或 X
E: 朝东按键, ○ 或 A
S: 朝南按键, ⨉ 或 B
W: 朝西按键, □ 或 Y
LUP: 左摇杆上倾
LDOWN: 左摇杆下倾
LLEFT: 左摇杆左倾
LRIGHT: 左摇杆右倾
LRING: 左摇杆内环/外环
RUP: 右摇杆上倾
RDOWN: 右摇杆下倾
RLEFT: 右摇杆左倾
RRIGHT: 右摇杆右倾
RRING: 右摇杆内环/外环
这些都可以映射到以下键盘和鼠标输入:
0-9: 键盘顶部的数字键
N0-N9: 小键盘的数字键
F1-F29: F1-F29
A-Z: 字母键
UP, DOWN, LEFT, RIGHT: 方向键(箭头键)
LCONTROL, RCONTROL, CONTROL: 左Ctrl, 右Ctrl, 通用Ctrl
LALT, RALT, ALT: 左Alt, 右Alt, 通用Alt
LSHIFT, RSHIFT, SHIFT: 左Shift, 右Shift, 通用Shift
TAB: Tab
ENTER: 回车
LMOUSE, MMOUSE, RMOUSE: 鼠标左键, 中键和右键
BMOUSE, FMOUSE: 鼠标后退键 (第四键)和鼠标前进键(第五键)
SCROLLUP, SCROLLDOWN: 滚轮上, 下
PAGEUP, PAGEDOWN, HOME, END, INSERT, DELETE, BACKSPACE
NONE: 无输出(空)
CALIBRATE: 当收到输入时校准手柄
GYRO_ON, GYRO_OFF: 开启/关闭手柄
GYRO_INVERT, GYRO_INV_X, GYRO_INV_Y: 反转陀螺仪, 或只有 x/y轴
; ' , . / \ [ ] + -
例如,在一个R代表’reload(换弹)’, E代表’use(使用)’的游戏中,你可以将□对应为’reload’,△对应为’use’。
W = R
N = E
由于键盘比大多数控制器有更多的输入,主机端游戏通常会将多个动作映射到同一个按键上,而PC端会将这些动作映射到不同的键上。为了在控制器上适应键盘映射,JSM允许你将短按和长按映射到不同的键盘/鼠标输入。那么让我们拿着同样的游戏,让它我们可以点击□来’R换弹’或者按住△来’E使用’
W = R E
如果你想要短按□时’换弹’,但按住时不做任何动作(NONE),你可以参考:
W = R NONE
体感相关的点击映射会在释放按键大约半秒后应用,但其他映射会非常快速的响应按键。
JSM还允许将同时按下的按键绑定到不同的映射上。例如,你可以像这样在你的两个小肩键(Bumper)上绑定角色的普通技能和终极技能。
L = LSHIFT # 技能1
R = E # 技能2
L+R = Q # 终极技能
要启用同时绑定,两个按键需要在很短的时间内按下。这样做将忽略单独的按键绑定,并应用指定的绑定,直到其中一个按键被释放。与其他映射一样,同时绑定也支持短按&长按绑定。这个特性非常适合使用DPAD对角线,或者添加JSM特定的特性,比如陀螺仪校准和体感控制,而不需要占用更有用的按键。
组合键与同时触发键不同,尽管乍一看是相似的。当按下组合键时,组合键可以覆盖按键映射。这样就可以使用各种不同的实际组合,从而允许使用前后关系进行绑定。这里有个Left 4 Dead 2的例子,它可以让你不用把拇指从左摇杆上移开就能装备物品。
W = R E # 换弹/使用
S = SPACE # 跳跃
E = CONTROL # 蹲下
N = T # 语音沟通
L = Q NONE # 下个武器, 按住以使用Face按键切换.
L,W = 3 # 投掷物
L,S = 4 # 药
L,E = 5 # 大包
L,N = F # 手电筒
一个按键可以与多个其他按键连接。在这种情况下,最新的组合键优先于之前的组合键。这可以理解为每次按下组合键时,在映射之上的层堆栈,其中只有顶部是活动的。注意,你不需要使用NONE作为绑定。组合键可以很好地绑定到一个按键,例如一个武器轮盘。
你还可以将按键的双击分配给不同的映射。双击按键与组合按键相似,只是按键本身就是它的组合键的。它支持短按和长按,就像以前的所有条目一样。
N = SCROLLDOWN # 切换武器
N,N = X # 切换武器开火模式
当在第一次按下后的0.2秒内发生第二次按下时会激活双击映射。在这段时间内,不能设置其他映射,因此常规的点击将引入延迟。此时,时间不能更改。
最后,有一种数字输入的工作方式不同,因为它可能与其他任何输入重叠。有两个输入,但在给定的配置中,你最多只会用到其中一个:
GYRO_OFF
GYRO_ON
当你分配一个按键到GYRO_ON,该按键被按下时,体感鼠标工作。当你分配一个按键到GYRO_OFF,该按键被按下时,体感鼠标关闭。这是大多数游戏缺失的一个非常重要的功能,体感瞄准——就像电脑游戏玩家可以暂时通过将鼠标台离鼠标垫“禁用”鼠标,以重新定位,体感玩家可以暂时禁用陀螺为了重新定位它。此绑定不影响与该按键关联的其他映射。这是为了使体感可以与某些游戏动作一起被启用,或者使体感可以立即被禁用或启用,而不管什么短按或长按被映射到那个按键。
对于那些真正需要使用控制器上所有可用按键的游戏,但是其中一个输入很少使用,并且可以很容易地进行切换(比如蹲伏),所以让这个输入只进行短按是符合逻辑的,并且当你握住它时,让它作为双倍的GYRO_OFF:
E = LCONTROL NONE
GYRO_OFF = E
或者如果你真的不能腾出一个按键来禁用陀螺仪,你可以使用LEFT_STICK或RIGHT_STICK禁用陀螺仪,而输入正在被使用:
GYRO_OFF = RIGHT_STICK # 当使用摇杆瞄准时关闭体感
我喜欢使用摇杆瞄准(或甩枪瞄准)的同时与体感瞄准,但这仍然可以比没有禁用体感强...如果你的游戏没有一个明显的功能进行体感瞄准(比如一个专门的“武器开镜”按键,在第三人称动作游戏中很常见)。
GYRO_ON在你只需要偶尔精确瞄准的游戏中非常有用。如果ZL让你的角色瞄准他们的弓(就像塞尔达:荒野之气或魔多之影),也许这是你唯一需要启用体感瞄准的时候:
ZL = RMOUSE # 用弓瞄准
GYRO_ON = ZL # 当ZL被按下时使用体感
GYRO_ON和GYRO_OFF也可以作为一个动作绑定到特定的按键。与上面的命令相反,它采用了操作绑定的位置。但你需要它时,你仍然可以找到创造性的方式与短按/长按键或和组合按键正确的绑定体感控制。
请注意,点击应用陀螺相关绑定需要半秒响应。另一种选择是用GYRO_INVERT反转陀螺仪输入。如果你只玩一个joycon,这样的绑定会很方便,因为你没有第二个摇杆。当这个动作被启用时,倒转使它使你可以重新进入手继续在相反的方向!
SL + SR = GYRO_OFF GYRO_INVERT # 当SL SR被同时按下时关闭体感半秒并反转轴向
绑定体感的行动,像那些有优先超过分配的体感按键,如果他们冲突。
命令NO_GYRO_BUTTON可以用来删除GYRO-ON或-OFF映射,使体感总是启用。要始终禁用它,只需设置GYRO_ON = NONE或让GYRO_SENS为0。
下面的部分只适用于DS4控制器,因为它是唯一支持的具有模拟扳机的控制器。
模拟扳机报告一个介于0%和100%之间的值,表示你扣动扳机的距离。将一个数字按键绑定到一个模拟扳机是通过一个固定值来实现的。当触发值跨越threashold(临界/阈)值(介于0%和100%之间)时,按键按下被发送。默认的threashold值是0,意味着最轻微地按下扳机发送按键按。这对于响应性很好,但可能会导致意外按压。threashold可以通过运行以下命令自定义:
TRIGGER_THRESHOLD = 0.5 #在扳机被按下一半时发送扳机信号
两个扳机使用相同的threashold值。值为1.0或更高会使绑定无法达到,而小于0则会使其始终按下。
JSM可以为扳机的完全拉动分配不同的映射,允许你在考虑持有绑定时在每个扳机上有多达4个映射位。处理这些映射的方式是用变量ZR_MODE和ZL_MODE为R2和L2设置扳机。一旦设置完毕,你就可以将按键分配给ZRF和ZLF,以便分别使用R2和L2的全拉绑定。在这种情况下,ZL和ZR被称为软压映射,因为它们在100%完全拉绑定之前激活。下面列出了所有可能的触发模式。
NO_FULL (default): 忽略完全下压。 数字扳机手柄,如Switch Pro强制在这种模式下工作
NO_SKIP: 永远不跳过软压映射,完全下压映射将会在扳机完全下压时激活
MUST_SKIP: 只会在扳机快速达到完全下压时触发完全下压映射, 忽略软压映射
MAY_SKIP: 结合 NO_SKIP 和MUST_SKIP: 当在快速完全下压时软压会被忽略, 并且完全下压可以在软压上正常工作
MUST_SKIP_R: 快速反应版本的 MUST_SKIP. 见后文
MAY_SKIP_R: 快速反应版本的 MAY_SKIP. 见后文
例如,在《使命召唤》中,当你使用狙击时,你必须屏住呼吸。你可以这样将软压绑定致开镜并将全压绑定到屏息:
ZL_MODE = NO_SKIP # 开启完全下压映射,永远不跳过开镜
ZL = RMOUSE # 开镜
ZLF = LSHIFT # 按住以屏息
使用NO_SKIP模式使得LSHIFT只有在RMOUSE也处于活动状态时才处于活动状态。然后在右边的扳机上,你可以绑定你不同的攻击绑定:使用跳跃功能,以避免它们之间的冲突,像这样:
ZR_MODE = MUST_SKIP # 启动完全下压映射, 软压和完全下压映射不可同时触发的
ZR = LMOUSE # 开火
ZRF = V G # 快速软压以使用近战武器; 快速全压以温雷并在松开时投掷出
使用MUST_SKIP模式确保一旦你开始射击,完全下压将不会使你停止射击并开始近战。
SKIP模式的“响应式”变体启用了不同的行为,可以在特定环境下提供比原始版本更好地体验。一个典型的例子是,软压映射是一个类似于开镜或趴下的模式映射,而该软压映射没有按住或一直按住映射。不同之处在于,软压映射在扳机越过阈值时就会被激活,从而提供所需的响应感觉(快速反应),但如果快速达到全压,则会被忽略,因此仍然允许你以腰射为例。这将导致一个有希望可忽略的范围出错,但授予一个更快速地开镜。
每个摇杆有7种不同的运行方式:
AIM: 传统的摇杆瞄准
FLICK: 甩枪瞄准
FLICK_ONLY: flick stick without rotation after tilting the stick
ROTATE_ONLY: flick stick rotation without the initial flick
MOUSE_RING: 将光标位置直接设置屏幕中心相对摇杆的圆上
MOUSE_AREA: 将摇杆映射在一个光标可操作的圆形区域
NO_MOUSE: 不影响鼠标,使用按钮映射(默认)
左右摇杆模式设置如下:
LEFT_STICK_MODE = NO_MOUSE
RIGHT_STICK_MODE = AIM
不管是什么模式,你都可以将输入范围绑定到一个部分或完全倾斜的摇杆。例如,当摇杆完全倾斜时,你可能想要一直按下LSHIFT(以疾跑):
LEFT_RING_MODE = OUTER # 外环是默认的,所以这条命令行是选择性的
LRING = LSHIFT
或者你可能想要摇杆部分倾斜时一直按LALT:
LEFT_RING_MODE = INNER
LRING = LALT
出于向后兼容性的考虑,还有两个额外的选项为LEFT_STICK_MODE和RIGHT_STICK_MODE对于同时设置相应stick_mode和RING_MODE的LEFT_STICK_MODE和RIGHT_STICK_MODE:
INNER_RING: 相同于 _STICK_MODE = NO_MOUSE 和 _RING_MODE = INNER
OUTER_RING: 相同于 _STICK_MODE = NO_MOUSE 和 _RING_MODE = OUTER
让我们看看所有不同的操作模式。
当使用标准瞄准摇杆模式时,有几个重要的命令:
FLICK模式有更少的配置。没有死区和灵敏度。当你将摇杆推向一个方向, JSM只需要把输入的角度,并把它转换成游戏相对于视角的角度, 一切都发生在一瞬间。摇杆一旦被倾斜,旋转X度将立即使游戏中的视角旋转X度。这提供了一种非常自然的方式来快速旋转,对视野外的事件做出反应,或者在不移动控制器的情况下逐步旋转。
由于甩枪瞄准模式下摇杆只会水平转动视角,它一般只有实际结合体感瞄准,才可以处理垂直瞄准。
甩枪瞄准将使用上面提到的STICK_DEADZONE_OUTER来决定摇杆已经被推得足够远,来进行“甩”或旋转。甩枪瞄准依赖REAL_WORLD_CALIBRATION(RW校准)来正确工作(后面会讲到,因为它会影响所有转换为鼠标移动的输入)。这是因为JSM只能通过使鼠标移动来将视角指向一个给定的方向,而RW校准帮助JSM计算该怎么移动。本身兼容摇杆的游戏将不需要校准。甩枪瞄准有几个设置参数,如果你真的想玩弄一下:
$ claude mcp add JoyShockMapper \
-- python -m otcore.mcp_server <graph>