Cannot Open Controller but Joystick Recognized

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.

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.

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

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?

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?

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

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

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

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.