PS4 controller throws error on SDL_GameControllerOpen()

I was just adding game controller support to my game/engine in SDL 2.0.10 and I’m running into a miscellaneous error with a PS4 controller.

On an x64 Windows build, having a Bluetooth PS4 controller running through DS4Windows works correctly. SDL reports the correct number of controllers (in this case, one), SDL_GameControllerOpen(i) opens the controller, and I’m able to use it, though the button mapping is off, which I’m fine fixing through user preferences. However, if I’m not running DS4Windows, SDL still reports one controller but when I call SDL_GameControllerOpen(i), SDL throws this error:

“That operation is not supported”

Surprisingly, the PS4 controller without DS4Windows works perfectly (correct button mapping) and life goes on as long as I ignore this error. The documentation for SDL_GetError() says that I need to check the return value on SDL functions, but the pointer to the controller is valid, so I’m not sure what’s throwing the error or if it’s safe to ignore it. (I’m using SDL_GetError()[0] != ‘\0’ followed by SDL_ClearError() for this purpose.)

On x86, the controller isn’t detected at all directly or through DS4Windows, but that’s most likely a driver issue and not especially important to me.

In short, is it safe for me to ignore that error? And am I doing something wrong? Thanks!

void engine::pollControllers() {
  if (SDL_NumJoysticks() > 0) {
    for (auto i = int{ 0 }; i < SDL_NumJoysticks(); ++i) {
      checkSdlErrors();
      auto * gameController = SDL_GameControllerOpen(i); // this is throwing an SDL error
      if (gameController == nullptr) {
        // ...real error occurred, so skip this controller
      }
      else {
        // ...add this controller
        if (SDL_GetError()[0] != '\0') { // clear the error
          SDL_ClearError();
        }
      }
    }
  }
}

SDL doesn’t “throw” errors, it doesn’t use exceptions.

Also, you’re not supposed to call SDL_GetError() all the time, only if an error happened, to get information on the error - and this is what the documentation says:

The message is only applicable when an SDL function has signaled an error.

In this specific case you’d call it if SDL_GameControllerOpen() returns NULL.

Fair enough re: terminology.

That makes sense about the return values with SDL functions. I was checking for an unrelated error in something later in SDL when I started seeing that message. That later check was more a sanity check than a response to a particular error, since indeed none existed. When I connected my Playstation 4 controller without DS4Windows running and I saw that message, I went looking for the cause.

So, I’ll keep in mind that I can only use SDL_GetError() when there’s an actual error from the return values. Thanks again, Daniel!

Can you clarify whether SDL_GetError() is thread safe? The docs say “The returned string is statically allocated” which makes me a little worried that an error occurring on another SDL thread might overwrite it. Or is that ‘static allocation’ in thread local storage?

AFAIK errors are thread-local as long as sdl threads are enabled. see here: https://hg.libsdl.org/SDL/file/963f11dbf153/src/thread/SDL_thread.c#l206

SDL_GetErrBuf is used both by SDL_SetError and SDL_GetError

I successfully call SDL_CreateThread(), so I assume that must mean threads are enabled, but it’s not as a result of me explicitly enabling them (I’m generally using a prebuilt SDL2 binary so if it’s a configuration setting it’s out of my control).

I don’t think any of the prebuild distributions you will find have them disabled.
And if they are disabled, you are probably not using threads anyway cause there is no proper support on the platform.

1 Like

Sorry to veer off-topic, but do you happen to know the current state of support for threads in Emscripten/Web Assembly? Can one use SDL_CreateThread() on that platform or is it (still) unsupported?

As far asi can see, building SDL for emscripten still has threads disabled (I looked here https://hg.libsdl.org/SDL/file/fab2cd7dee5b/CMakeLists.txt#l144).

However it seems that that pthread is available on emscripten these days, albeit having some limitations afaics, so perhaps that could be patched in? https://emscripten.org/docs/porting/pthreads.html

The web world isn’t really my thing so I can only say what I think when glancing at this, sorry.
Look for or open something on bugzilla I’d say, if you need support and I’m not mistaken (which I could be - I really don’t know the ins and outs how SDL works with emscripten!)

Have a good week!

Thank you, that’s very helpful. It looks as though atomics are disabled too (not surprisingly). I wonder, though, whether the SDL2 you get from the Emscripten compiler when specifying the USE_SDL=2 switch may be configured differently.