Cannot Open Controller but Joystick Recognized


#1

I am writing a C++ program using SDL 2 for the platform layer and opengl for graphics and rendering. I am now trying to use SDL’s game controller APIs to connect a gamepad (to replace or supplement keyboard controls). Unfortunately the controller does not seem to be recognized despite the fact that it works perfectly with other software. It’s a Sony Dualshock 4 (for the Playstation 4 system). My system is Mac OS 10.9.5, and I am using SDL 2.0.5 and loading the official community controller database for SDL 2.0.5, which contains ps4 controller mappings:

030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X

I also added a new mapping using one of the official tools. That also loads successfully according to the relevant function call.

The following is my code, and it’s about as close to a minimal example as I can get:


// in main
    // initialize SDL
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) < 0) {
        fprintf(stderr, "%s\n", "SDL could not initialize");
        return EXIT_FAILURE;
    }

    // load controller mappings, I tested this and 35 mappings load successfully, which is expected
    SDL_GameControllerAddMappingsFromFile("./mapping/gamecontrollerdb_205.txt");

    // the controller handle
    SDL_GameController* controller = nullptr;
    // max_joysticks is 1, which means that the device connects at least
    int max_joysticks = SDL_NumJoysticks();

    if (max_joysticks < 1) {
        return EXIT_FAILURE;
    }

    // this returns, which means that the joystick exists, but it isn't recognized as a game controller.
    if (!SDL_IsGameController(0)) {
        return EXIT_FAILURE;
    }

    // I never get passed this.
    controller = SDL_GameControllerOpen(0);

    fprintf(stdout, "CONTROLLER: %s\n", SDL_GameControllerName(controller));

Has anyone encountered this problem? I’ve done some preliminary searching as I mentioned, but it seems that usually either the number of joysticks is 0, or everything is recognized.

Also, SDL_CONTROLLERDEVICEADDED isn’t firing when I connect the controller.

The controller is plugged in before I start the program.


#2

Looks like you haven’t created an SDL window yet. If I’m not mistaken, currently you need a window created by SDL before you can capture any keyboard, mouse, or joystick events. The window can have OpenGL as the renderer as its backend.

It’s a bit beyond me currently as I haven’t been working on my graphics yet, but I think you can use: this link to get started on using OpenGL with SDL2.


#3

Oh, no I did create a window. I just haven’t included every line of code. I already have a full prototype opengl application with mouse and keyboard controls. I just want to use a playstation 4 controller, which just doesn’t seem to be detected, unless I’m missing something. The documentation is somewhat sparse in this area. hmmm


#4

Are you only connecting the controller with USB, or are you using Bluetooth? Could you try using the other to see if that helps? There was a bug where the PS4 DS controller wasn’t being detected using Bluetooth but a USB cable worked. Here it is. Another thing to try would be to see if it’s being registered as a joystick for some odd reason.

After looking at this and your Stack Overflow question again, I’ve got a quick question, what do you mean by:

either the number of joysticks is 0, or everything is recognized.

Do you mean that the controller doesn’t always work when you try to detect it?


#5

I am connecting via usb and “either 0 or it works” was my response to the discussions I found online related to my problem. In my case, the controller is registered as a joystick (number of joysticks is 1), but SDL_IsGameController() returns false. The discussions online are about figuring out why controllers don’t even register as joysticks, so I haven’t found helpful articles.
I have to double check whether I can open as a joystick, so I will follow-up with that. If I CAN open as a joystick, then that means I have a version of the ps4 whose information is not in the database, is that correct? A newer version of the controller was created at some point, so maybe only the most up-to-date database with the new syntax has the correct mapping. I can’t figure how to create a mapping with 2.0.5 syntax since most tools to help with that process seem to use 2.0.7 and 2.0.8.

I COULD try to update to 2.0.8 via homebrew, but upgrading toolsets in the middle of a project tends to be risky. As I mentioned, I am using Mac OS 10.9.5 (Mavericks). Is there evidence of someone using SDL 2.0.8 on that system?

In short: joystick count is 1, IsGameController is false, I’m connecting via USB, and I am going to double check whether I can open the DS4 as an unnamed controller, in which case I need to figure whether upgrading is possible / safe and whether that may help.

Thanks.

EDIT:

The official homebrew site shows that a Mac Mavericks install isn’t included as a “tap,” and I REALLY do not want to install from source: https://formulae.brew.sh/formula/sdl2

The actual script:

I wonder what the “any” portion does. Only three mac oses are listed there.

EDIT: updating to SDL 2.0.8 worked, thankfully. The mapping was just missing in earlier versions. Is there a known way to get the controller working via bluetooth by the way?


#6

“IsGameController is false” basically boils down to - there is no mapping record for the device GUID.


#7

Is there any example of connecting via Bluetooth? I haven’t been able to find any documentation.


#8

I think you just connect the controller through Bluetooth using the OS to do so.


#9

I see, so that part is abstracted away. I’ll see whether it works. If not, then it’s probably an issue with the type of controller.
Thanks, all.

EDIT: Bluetooth works as expected.