前不久入了台二手的北通168游戏方向盘。说起来这个方向盘的年代非常久远,比我的年龄都大,卖家也是个称得上爷爷辈的老人了(囧)但它只要80元!真的是相当值的价格!!
于是我毫不犹豫便入手了,千里迢迢把它带回家:
缺点当然也不是没有,抛开本身的老化和定位不准问题,年代久远,兼容性多少也都不如现代手柄。测试了几个赛车和驾驶游戏,欧卡2尚可一试,而Forza地平线索性直接不支持了,必须想办法映射成Xbox手柄……
最近又试了下我最爱的尘埃拉力赛 (DiRT Rally) ,和欧卡2类似,也需要自己设置控制器配置。然而情况有些特殊:每次重新打开游戏,就要重新配置方向盘,甚是不爽,何况,有些菜单操作还是需要用到F区键盘……
前言
在解决这些问题前,首先要说明的是,Windows系统连接控制器外设(通俗意义上的手柄,包括方向盘),分为DirectInput和XInput两种驱动模式:大多数通用控制器采用DirectInput模式,而XInput模式对应Xbox 360及之后的手柄输入,两者区别在于布局关系上。具体而言,后者有明确的XYAB标准布局,而前者数量均无限制(对方向盘排挡杆是刚需),由此影响控制器外设跟游戏的兼容性。
北通168方向盘年代久远,尽管是自动挡娱乐方向盘,没有挡杆那么多按键的要求,但在360主机尚未盛行的年代,市面上清一色也都是通用的DirectInput模式,免驱、但不免配置。没有XInput的Xbox手柄模式,也不能直接用来玩地平线。
即使到了2023年,这样的廉价方向盘外设仍然存世于淘宝上,相同的模具、相似的主控,价格还“上涨”了几百块(如果不考虑转换2006年货币汇率的话)
虽说的确可以考虑用x360ce之类的软件,或者Steam的控制器配置,把方向盘转换映射成Xbox手柄,但考虑到资源占用以及延迟关系,还是尽量用游戏自带的控制器支持吧。比较好的例子是欧卡2,可以清晰分明手柄和方向盘的转向区别。
Google搜索了一番,在Steam上找到一篇教程,发现也有同样问题的玩家:
上面的链接教程中,描述了以下三种问题:
- 无法自动识别方向盘,也不能保存配置
- 转向、加减速存在线性轴死区(Deadzone)
- 没有肩键功能控制快速菜单 (键盘对应F3/F4)
简单来说,尘埃拉力赛通过读取游戏目录本身的XML配置文件,实现对DirectInput方向盘控制器的支持,并且内置了多个主流厂商的方向盘适配(如罗技G系列、图马斯特等)
然而不同的控制器,按键、线性轴(axis)的位置也有所差异,不像Xbox手柄那么规范,就需要游戏开发商独一适配。而游戏中没有杂牌手柄和方向盘的配置,索性加载出来就是空的默认配置文件。
尘埃使用通用控制器的情况下,默认设定1、2键对应确认和返回,然而游戏并不认识方向盘的布局,不看说明也不知道按键的位置。在奇葩手柄上这个问题更加严重,连接了英伟达手柄,本用于确认的2号键居然在触控板上……
解决方案就是对症下药,既然游戏不能自动识别,那就自己写一份配置文件,自行针对方向盘布局定制配置。
实践
在Steam中浏览游戏本地文件位置,找到Input文件夹(默认位置大概在 C:\Program Files (x86)\Steam\SteamApps\common\DIRT Rally\Input
),可以看到众多方向盘和手柄的适配文件。
上文教程的解决方案是直接编辑 dinput_default.xml 文件,打开可以看到很多命名为</Action>
的代码行。写过HTML基本上也能看懂一些,这里我已经修改过了,一般情况下,这个文件内基本上是空的配置。
逐个</Action>
代码行内,直接添加DirectInput的按键事件,如 <Axis id="di_button_0">
代表的就是1号键点击,从0算1起,button_1代表2号键,以此类推。
通过直接编辑XML文件,也可以实现多功能复用同一按键:比如Xbox手柄默认摇杆和方向键都可以转向,就是在一个Action填写两个Axis实现的。
线性轴的操作事件稍有区别,在后面还需填写biDirUpper/Lower上下增减的附加属性,根据方向盘的类比轴 (Axis) 配置不同,添加转向、踏板对应的Axis轴配置。
我的北通方向盘是X轴左右转向、Y轴向上刹车 (biDirUpper) 、向下踩油门加速 (biDirLower) 。如果方向盘是全轴控制的设计(比如从左到右的Z轴),则应该设置为uniDirPos/Neg(反向)
还需要设置转向、油门起始死区 (deadzone) 和最大极限 (saturation) 的值,对于方向盘可以直接关闭死区,设置为0,获得更精细的线性操作;而转向根据我的偏好,设置为极限的85%,也就是0.85,避免90°暴力打方向撞击边缘,伤害方向盘和相关部件的问题(虽说方向盘就是拿来糙的,不过也已经坏了一个拨片了)
缺少的F3/F4用于菜单切换的功能键,在游戏中用于切换涂装、视图之类的功能。通过游戏内无法映射,则可以直接从Xbox手柄配置文件(比如xinput_pad_0.xml) 拿过来,配置识别为肩键。我的方向盘设置为了5和6号键,代码如下:
<Action id="Menu Left Shoulder"> <Axis id="di_button_4" /> </Action> <Action id="Menu Right Shoulder"> <Axis id="di_button_5" /> </Action>
以此类推,编辑剩下的事件,保存。打开尘埃拉力赛,在Settings>Control设置界面加载默认的Joystick布局,逐一测试每个按键和线性灵敏度。
有时候会出现反向的问题,退出游戏,重复编辑配置文件保存,再次打开尘埃,加载布局测试。改动XML配置后一定要记得手动加载一次!直到配置成正确的布局,基本上就完成啦。
以下是完整配置:
<!-- Default action map for Direct Input --> <ActionMap name="betop_3168" device_type="{00060079-0000-0000-0000-504944564944}" priority="0"> <!-- In Game Actions --> <Action id="Accelerate"> <Axis id="di_y_axis" type="biDirLower" deadzone="0.0" saturation="1.0" /> </Action> <Action id="Brake"> <Axis id="di_y_axis" type="biDirUpper" deadzone="0.0" saturation="1.0" /> </Action> <Action id="Clutch"> </Action> <Action id="Handbrake"> <Axis id="di_button_2" /> </Action> <Action id="Steer Left"> <Axis id="di_x_axis" type="biDirLower" deadzone="0.0" saturation="0.85" /> </Action> <Action id="Steer Right"> <Axis id="di_x_axis" type="biDirUpper" deadzone="0.0" saturation="0.85" /> </Action> <Action id="Change View"> <Axis id="di_button_5" /> </Action> <Action id="Gear Up"> <Axis id="di_button_0" /> </Action> <Action id="Gear Down"> <Axis id="di_button_1" /> </Action> <Action id="Look Left"> <Axis id="di_dpad_0_left" /> </Action> <Action id="Look Right"> <Axis id="di_dpad_0_right" /> </Action> <Action id="Look Up"> <Axis id="di_dpad_0_up" /> </Action> <Action id="Look Down"> <Axis id="di_dpad_0_down" /> </Action> <Action id="Look Back"> <Axis id="di_button_4" /> </Action> <Action id="Pause"> <Axis id="di_button_9" /> </Action> <Action id="Instant Replay"> <Axis id="di_button_1" /> </Action> <Action id="Horn"> </Action> <Action id="Reset Vehicle"> <Axis id="di_button_7" /> </Action> <Action id="Gear 1"> </Action> <Action id="Gear 2"> </Action> <Action id="Gear 3"> </Action> <Action id="Gear 4"> </Action> <Action id="Gear 5"> </Action> <Action id="Gear 6"> </Action> <Action id="Gear 7"> </Action> <Action id="Gear Reverse"> </Action> <Action id="Push To Speak"> </Action> <Action id="Headlights"> </Action> <Action id="Wipers"> </Action> <Action id="SeatMoveForward"> </Action> <Action id="SeatMoveBackward"> </Action> <Action id="SeatMoveUp"> </Action> <Action id="SeatMoveDown"> </Action> <Action id="SeatTiltUp"> </Action> <Action id="SeatTiltDown"> </Action> <Action id="SeatReset"> </Action> <!-- Menu Actions --> <Action id="Menu Left"> <Axis id="di_dpad_0_left" /> </Action> <Action id="Menu Right"> <Axis id="di_dpad_0_right" /> </Action> <Action id="Menu Up"> <Axis id="di_dpad_0_up" /> </Action> <Action id="Menu Down"> <Axis id="di_dpad_0_down" /> </Action> <Action id="Menu Select"> <Axis id="di_button_3" /> </Action> <Action id="Menu Back"> <Axis id="di_button_2" /> </Action> <Action id="Menu Button3"> <Axis id="di_button_0" /> </Action> <Action id="Menu Button4"> <Axis id="di_button_1" /> </Action> <Action id="Menu Start Button"> <Axis id="di_button_9" /> </Action> <Action id="Menu Select Button"> <Axis id="di_button_8" /> </Action> <Action id="Menu Left Shoulder"> <Axis id="di_button_4" /> </Action> <Action id="Menu Right Shoulder"> <Axis id="di_button_5" /> </Action> <Action id="Fe View Tweak Left"> <Axis id="di_x_axis" type="biDirLower" deadzone="0.0" saturation="1.0" /> </Action> <Action id="Fe View Tweak Right"> <Axis id="di_x_axis" type="biDirUpper" deadzone="0.0" saturation="1.0" /> </Action> <Action id="Fe View Tweak Up"> </Action> <Action id="Fe View Tweak Down"> </Action> <Action id="Fe View Tweak In"> <Axis id="di_y_axis" type="biDirLower" deadzone="0.0" saturation="1.0" /> </Action> <Action id="Fe View Tweak Out"> <Axis id="di_x_axis" type="biDirUpper" deadzone="0.0" saturation="1.0" /> </Action> <!-- Replay Actions --> <Action id="Replay Rewind"> <Axis id="di_y_axis" type="biDirUpper" deadzone="0.0" saturation="1.0" /> <Axis id="di_x_axis" type="biDirLower" deadzone="0.0" saturation="1.0" /> </Action> <Action id="Replay Fast Forward"> <Axis id="di_y_axis" type="biDirLower" deadzone="0.0" saturation="1.0" /> <Axis id="di_x_axis" type="biDirUpper" deadzone="0.0" saturation="1.0" /> </Action> <Action id="Replay Pause"> <Axis id="di_button_3" /> </Action> <Action id="Replay Next Camera"> <Axis id="di_button_5" /> </Action> <Action id="Replay Prev Camera"> <Axis id="di_button_4" /> </Action> <Action id="Replay Jump In"> </Action> <Action id="Replay Audio Mute"> <Axis id="di_button_6" /> </Action> <Action id="Replay Exit"> <Axis id="di_button_2" /> </Action> <Action id="Replay UI On Off"> <Axis id="di_button_8" /> </Action> <Action id="Replay Youtube"> </Action> <Action id="Youtube Drag Left"> </Action> <Action id="Youtube Drag Right"> </Action> <Action id="Youtube Speed Up"> </Action> <Action id="Youtube Speed Down"> </Action> <Action id="Youtube Upload"> </Action> <Action id="Youtube Exit"> </Action> <!-- Spectator actions --> <Action id="Spectator Next Camera"> <Axis id="di_button_5" /> </Action> <Action id="Spectator Previous Camera"> <Axis id="di_button_4" /> </Action> <Action id="Spectator UI On Off"> <Axis id="di_button_8" /> </Action> <Action id="Spectator List On Off"> <Axis id="di_button_1" /> </Action> <Action id="Cycle Forward On Board Cameras"> <Axis id="di_button_4" /> </Action> <Action id="Activate Replay System"> <Axis id="di_button_5" /> </Action> </ActionMap>
另外研究了一下如何能自动识别方向盘的方法,像罗技、图马斯特那种大厂产品一样。不过丑话说在前:实测自行配置会导致无法使用RaceNet线上功能、无法保存游戏等诸多游戏问题
Input文件夹下包含各种方向盘的配置文件,每个都打开看了一下,又发现了一些新的思路:所有的方向盘布局配置文件,实际上都链接在paths.xml文件下,调取对应的ActionMap参数识别方向盘布局,有点类似于网站的sitemap(毕竟都是XML):
仅有文件超链接还不够,若要让方向盘能够即插即用,又不影响其他的手柄,便需要修改对应的ActionMap参数——device_type,而自动识别实际上就是基于device_type中的设备GUID实现的:
设备的GUID可以通过ditool获取。打开会出现一个命令行窗口,找到方向盘控制器的名称,下方的guidProduct便是游戏识别需要的设备ID:
ditool二进制exe可以通过sourceforge地址下载:sourceforge.net/projects/x360ce/files/ditool.zip/download
(参考:granitedevices.com/wiki/Simucube_product_USB_interface_documentation)
将guidProduct的值填入到device_type中,另存为新的xml文件。随后打开paths.xml文件,添加下面内链接代码:
<xmlreader processor="Input" filename="input/betop_3168.xml" map="UPDATE" pool="UPDATE_TEMPORARY" userdata="presets" />
再打开尘埃,设置控制器,便可以看到新的配置了:
名称前缀的LNG好像有些奇怪,可能是没有i18n/mui翻译字符串之类的关系。还是要提醒一下:自行修改游戏文件会导致RaceNet以及游戏进度无法保存!
如此一番设置以后,享受精细控制带来的驾驶乐趣吧!原本称之为“性能怪兽”的Group B组赛车,也能够轻松驾驭。
开着蓝旗亚Delta S4冲进第一名也非常容易,就像开斯巴鲁STI和奥迪Quattro一样,然而R4组的STI和三菱EVO X又感到慢了半拍,像是开前驱车一样,莫得灵魂,没有以前的驾驶乐趣了。这不是个游戏嘛?我是谁我在哪?(大雾)
下次研究一下怎么更完美地玩上《极限竞速:地平线》系列吧,实话说地平线的调教更偏向手柄。地平线默认好像不支持北通的方向盘,即使用的是x360ce映射也能感受到明显的延迟。
另外,两个方向拨片已经整坏了一个,本来绑定的也是默认A和B键的确认/手刹,看来还是把它们设置成肩键,老老实实用在欧卡转向灯上吧(逃)