libgdx/Jamepad

Doesn't react to controller being turned on

morvael opened this issue · 15 comments

When the app is turned on before the controller, it will never start working (unless perhaps quitSDLGamepad and initSDLGamepad will be called). Calling ControllerManager.update does nothing.

It is working for gdx-controllers desktop (which uses this lib), please check the implementation: https://github.com/libgdx/gdx-controllers/tree/master/gdx-controllers-desktop/src/main/java/com/badlogic/gdx/controllers/desktop

In my case getNumControllers always returns 0, and checking ControllerIndex like JamepadControllerMonitor (used by JamepadControllerManager) to maxNumControllers shows all are always disconnected. I have a wireless Xbox pad with adapter.

I'm trying to use this in a non-gdx project.

Issue number 1: had to manually specify gdx-jnigen-loader version in my pom, because the pom for Jamepad 2.0.14.1 wants gdx-jnigen-loader 2.0.0-SNAPSHOT, and by default SNAPSHOTs are not downloaded by Maven.

Issue number 2: had to extend ControllerManager and provide gamecontrollerdb.txt inside my jar for the mappings to load correctly (I think jamepad relies on the file from gdx-controllers-desktop). Luckily it uses getClass() do get the resource, so a workaround is possible.

Issue number 3: getLastNativeError from initSDLGamepad returns Couldn't find mapping for device (3), but I think it's a minor problem for some device that can be ignored. It exists whether the gamepad works (turned before app is started) or not (turned after the app is started).

Tried to find if the issue is in nativeControllerConnectedOrDisconnected, by manually calling reconnectController for all ControllerIndex objects, but it doesn't help. Simply put, when the pad is turned on after the app starts, getNumControllers will always return 0, and all ControllerIndex will return false from isConnected, even after calling reconnectController. When the pad is turned on before the app starts, getNumControllers returns 1, and ControllerIndex at index 0 is connected.

Likewise, turning the controller off when it works in the app will make no effect on the app - it will still show it as connected.

It makes no difference whether it's the actual pad that is turned on or off, or the wireless dongle that is plugged in or out of an USB port. It seems like the library recognizes only the at-app-start status of the controller(s), and nothing can change this later.

I can safely say this is not a general problem as hot plugging is possible with this lib on Mac, Windows and Linux. Either there is a device problem or an implementation problem. I get that you don't want to use the lib with gdx, but using the test application gdx-controllers provides can give you a hint if you have a device problem or implementation problem.

Issue number 4: after using quitSDLGamepad it's impossible to reuse the object by calling initSDLGamepad, because controllers array will stay at 0 length.

I got it working by destroying the controller manager object in every loop.

          cm.quitSDLGamepad();
          cm = new GamePadControllerManager(configuration);
          cm.initSDLGamepad();
          cm.update();

Only in this case will it detect connected/disconnected controller. So somehow the SDL is not refreshing correctly.

The API is simple so it's not an implementation problem. The device is working.

Hotplugging works for me when using the https://github.com/electronstudio/sdl2gdx library, but it has its own set of problems.

IMHO somethings wrong with the SDL layer when this library is used without GDX.

Perhaps GDX does some SDL_refresh (if there is such a thing, I'm just imaginig this), while this app when standalone doesn't.

Maybe it's about SDL_PumpEvents?

It seems sdl2gdx uses SDL_PumpEvents instead of SDL_JoystickUpdate (though documentation says SDL_PollEvent uses SDL_PumpEvents internally).

Perhaps GDX does some SDL_refresh (if there is such a thing, I'm just imaginig this), while this app when standalone doesn't.

I would suggest you to check the code, it is open source in the linked repo :)

This library is advertised as being able to work without gdx ("The following information is only needed for non-gdx Java projects"), but it doesn't. Refering to gdx and their examples is not helpful in that case, I think there is place for a Jamepad-only example. The core way to use the API is:

ControllerManager cm = new ControllerManager();
cm.initSDLGamepad();
while (doWork) {
  cm.update();
  ...
}
cm.quitSDLGamepad();

and it doesn't work when it comes to detecting connected/disconnected controllers while the app is running. It only works when used this way:

ControllerManager cm = new ControllerManager();
cm.initSDLGamepad();
while (doWork) {
  cm.quitSDLGamepad();
  cm = new ControllerManager();
  cm.initSDLGamepad();
  cm.update();
  ...
}
cm.quitSDLGamepad();

which means full SDL re-init is needed to get a snapshot of the controllers connected to the system. Something doesn't work correcty in the cm.update(); (at least when not using GDX).

The library does as it should when used within the libgdx convinience wrapper gdx-controllers. If it does not work for you, compare where your code differs from that wrapper and track down what's the problem. If you find that there's a problem in Jamepad that needs to be fixed, feel free to open a PR with the changes.