Linux 上的 SDL 是不是支持多个游戏手柄/操纵杆?

Posted

技术标签:

【中文标题】Linux 上的 SDL 是不是支持多个游戏手柄/操纵杆?【英文标题】:Does SDL on linux support more than one gamepad/joystick?Linux 上的 SDL 是否支持多个游戏手柄/操纵杆? 【发布时间】:2015-04-12 13:26:31 【问题描述】:

我有一个便宜的 PS3 控制器和一个 NEO-GEO X 控制器。它们都在例如检测到。 Fedora 20 和 Lubuntu 14.04。它们出现在 lsusb 中

Bus 001 Device 012: ID 0e8f:0003 GreenAsia Inc. MaxFire Blaze2
Bus 001 Device 016: ID 1292:4e47 Innomedia

设备出现在/dev/input 下方。在它们上运行 udevadm 表明 GreenAsia 设备使用pantherlord 驱动程序,而另一个设备使用hid-generic

如果我运行以下测试代码,SDL 只会报告 GreenAsia 设备。如果我拔下它,则检测到另一个设备。这是 SDL 的已知限制还是其他问题?

// from http://www.libsdl.org/release/SDL-1.2.15/docs/html/guideinput.html
#include "SDL/SDL.h"

int main () 
    if (SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0)
    
        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
        exit(1);
    
    printf("%i joysticks were found.\n\n", SDL_NumJoysticks() );
    printf("The names of the joysticks are:\n");

    for( int i=0; i < SDL_NumJoysticks(); i++ ) 
    
        printf("    %s\n", SDL_JoystickName(i));
    
   return 0;

【问题讨论】:

应该可以正常工作。你能同时看到两者的原始事件输出吗?最简单的方法是为两个终端中的每个设备“cat /dev/input/”,然后按下两个终端上的按钮。 另外,仅供参考,SDL2 引入了一个新的 Gamepad 抽象层,可以更轻松地使用这些设备。不过它是建立在操纵杆 API 之上的,因此切换可能无法解决您的问题。 @BrianMcFarland 嗨,我可以同时对两个设备进行分类并从它们那里获取输入。我的测试程序一次只能检测到一个,并且我在 MAME 和其他模拟器中得到相同的行为 此时,我可能会尝试以下操作:1) 使用 SDL_JOYSTICK_DEVICE env 变量(':' 分隔的 abs 路径)明确指定两个操纵杆,或 2) 从源代码构建 SDL并逐步通过src/linux/SDL_sysjoystick.c:SDL_SYS_JoystickInit()。浏览代码,我不明白为什么它不起作用,但调试起来应该不会太难,因为您现在已经有效地排除了驱动程序问题。 @BrianMcFarland 还没有逐步完成代码,但是在SDL_JOYSTICK_DEVICE 变量中设置两个摇杆会给我列出 3 个操纵杆! (其中一个操纵杆列出了两次)。因此,至少一种解决方法是找出 SDL 未拾取哪个操纵杆并将其设置为该环境变量。 【参考方案1】:

如果只有一个操纵杆映射到设备 /dev/input/event13 或类似设备,我的问题的答案似乎是否定的,这就是我的 PS3 控制器的情况。

SDL_SYS_JoystickInit中有如下代码

#if SDL_INPUT_LINUXEV
        /* This is a special case...
           If the event devices are valid then the joystick devices
           will be duplicates but without extra information about their
           hats or balls. Unfortunately, the event devices can't
           currently be calibrated, so it's a win-lose situation.
           So : /dev/input/eventX = /dev/input/jsY = /dev/jsY
        */
        if ( (i == 0) && (numjoysticks > 0) )
            break;
#endif

i 为0 时,它正在寻找“事件”设备。我的 PS3 控制器获取设备 /dev/input/event13/dev/input/js1,但我的 NEO-GEO X 控制器只有设备 /dev/input/js0,因此脱离循环会导致它被忽略。

这种情况下的解决方法是将没有相应“事件”设备的设备添加到SDL_JOYSTICK_DEVICE

感谢 Brian McFarland 帮助我们查明真相。

【讨论】:

以上是关于Linux 上的 SDL 是不是支持多个游戏手柄/操纵杆?的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 Unity3d 中使用多个游戏手柄吗?

使用原始输入在 Windows 上的游戏手柄力反馈(振动)

SDL2:触觉方法表现不如预期

Three.js 中的操纵杆、游戏手柄或 3D 鼠标支持

Nimbus 游戏手柄方向键映射?

Linux 上的 SDL OpenGL 新手,这有啥问题?