Fix joystick and gamepad library before jME 3.1 stable?

I’ve tested the a Logitech F310 gamepad, which has a dip switch for selecting “DirectInput” mode or “Xinput” mode. I’ve tested both modes with the 3.1 and these are the result:

XInput mode

Almost all the buttons and axis are wrongly mapped, plus there are a few axis which aren’t even detected.

Joystick[0]:Gamepad F310 (Controller)
  buttons:10
   JoystickButton[name=Pulsante 0, parent=Gamepad F310 (Controller), id=0, logicalId=0]
   JoystickButton[name=Pulsante 1, parent=Gamepad F310 (Controller), id=1, logicalId=1]
   JoystickButton[name=Pulsante 2, parent=Gamepad F310 (Controller), id=2, logicalId=2]
   JoystickButton[name=Pulsante 3, parent=Gamepad F310 (Controller), id=3, logicalId=3]
   JoystickButton[name=Pulsante 4, parent=Gamepad F310 (Controller), id=4, logicalId=4]
   JoystickButton[name=Pulsante 5, parent=Gamepad F310 (Controller), id=5, logicalId=5]
   JoystickButton[name=Pulsante 6, parent=Gamepad F310 (Controller), id=6, logicalId=6]
   JoystickButton[name=Pulsante 7, parent=Gamepad F310 (Controller), id=7, logicalId=7]
   JoystickButton[name=Pulsante 8, parent=Gamepad F310 (Controller), id=8, logicalId=8]
   JoystickButton[name=Pulsante 9, parent=Gamepad F310 (Controller), id=9, logicalId=9]
  axes:8
   JoystickAxis[name=Asse Y, parent=Gamepad F310 (Controller), id=0, logicalId=y, isAnalog=true, isRelative=false, deadZone=0.0]
   JoystickAxis[name=Asse X, parent=Gamepad F310 (Controller), id=1, logicalId=x, isAnalog=true, isRelative=false, deadZone=0.0]
   JoystickAxis[name=Rotazione Y, parent=Gamepad F310 (Controller), id=2, logicalId=ry, isAnalog=true, isRelative=false, deadZone=0.0]
   JoystickAxis[name=Rotazione X, parent=Gamepad F310 (Controller), id=3, logicalId=rx, isAnalog=true, isRelative=false, deadZone=0.0]
   JoystickAxis[name=Asse Z, parent=Gamepad F310 (Controller), id=4, logicalId=z, isAnalog=true, isRelative=false, deadZone=0.0]
   JoystickAxis[name=Hat Switch, parent=Gamepad F310 (Controller), id=5, logicalId=pov, isAnalog=false, isRelative=false, deadZone=0.0]
   JoystickAxis[name=pov_x, parent=Gamepad F310 (Controller), id=6, logicalId=pov_x, isAnalog=false, isRelative=false, deadZone=0.0]
   JoystickAxis[name=pov_y, parent=Gamepad F310 (Controller), id=7, logicalId=pov_y, isAnalog=false, isRelative=false, deadZone=0.0]

DirectInput mode

Almost all mapping are correct. Front triggers are detected as buttons but that’s probably because I didn’t install the drivers.

Joystick[0]:Logitech Dual Action
  buttons:12
   JoystickButton[name=Pulsante 0, parent=Logitech Dual Action, id=0, logicalId=0]
   JoystickButton[name=Pulsante 1, parent=Logitech Dual Action, id=1, logicalId=1]
   JoystickButton[name=Pulsante 2, parent=Logitech Dual Action, id=2, logicalId=2]
   JoystickButton[name=Pulsante 3, parent=Logitech Dual Action, id=3, logicalId=3]
   JoystickButton[name=Pulsante 4, parent=Logitech Dual Action, id=4, logicalId=4]
   JoystickButton[name=Pulsante 5, parent=Logitech Dual Action, id=5, logicalId=5]
   JoystickButton[name=Pulsante 6, parent=Logitech Dual Action, id=6, logicalId=6]
   JoystickButton[name=Pulsante 7, parent=Logitech Dual Action, id=7, logicalId=7]
   JoystickButton[name=Pulsante 8, parent=Logitech Dual Action, id=8, logicalId=8]
   JoystickButton[name=Pulsante 9, parent=Logitech Dual Action, id=9, logicalId=9]
   JoystickButton[name=Pulsante 10, parent=Logitech Dual Action, id=10, logicalId=10]
   JoystickButton[name=Pulsante 11, parent=Logitech Dual Action, id=11, logicalId=11]
  axes:7
   JoystickAxis[name=Rotazione Z, parent=Logitech Dual Action, id=0, logicalId=rz, isAnalog=true, isRelative=false, deadZone=0.0]
   JoystickAxis[name=Asse Z, parent=Logitech Dual Action, id=1, logicalId=z, isAnalog=true, isRelative=false, deadZone=0.0]
   JoystickAxis[name=Asse Y, parent=Logitech Dual Action, id=2, logicalId=y, isAnalog=true, isRelative=false, deadZone=0.0]
   JoystickAxis[name=Asse X, parent=Logitech Dual Action, id=3, logicalId=x, isAnalog=true, isRelative=false, deadZone=0.0]
   JoystickAxis[name=Hat Switch, parent=Logitech Dual Action, id=4, logicalId=pov, isAnalog=false, isRelative=false, deadZone=0.0]
   JoystickAxis[name=pov_x, parent=Logitech Dual Action, id=5, logicalId=pov_x, isAnalog=false, isRelative=false, deadZone=0.0]
   JoystickAxis[name=pov_y, parent=Logitech Dual Action, id=6, logicalId=pov_y, isAnalog=false, isRelative=false, deadZone=0.0]

With that said, my question is: is there a way to detect if the connected device is working with DirectInput rather than Xinput?

Just the name, I guess.

1 Like

You mean I should check the name of the device and there’s no other way?

Hm… does your jME version have XInput binding?

Or if not … then both log files you posted use DirectInput under the hood. In that case it’s just some weird thingy that reports differently depending on how you select that mode switch.

1 Like

Where can I verify that?

There is some early work on XInput, but it’s not been integrated into jME yet.

If you downloaded jME 3.1 alpha 1 then it will not have XInput. If you use latest master then it should not have XInput (I guess). Only if you implemented XInput integration or somebody secretly made it then it would have XInput support. I’m not sure about the state of latest master since I don’t use it but have seen that things would change radically if jME really switches to GLFW for input.

1 Like

Given the API we have today, that’s how we check to see if we need to remap things for “every other joystick” that exists. There is even a built in way to setup a properties file to do this by joystick name.

1 Like

wiki page or that didn’t happen :wink:

Well… I’ve searched the wiki and the javadoc, but can’t figure out what you mean (which is very interesting).

Yeah, I know what you mean @Pesegato, it’s not documented.

It’s called joystick-mapping.properties and it remaps gamepads so that the TestJoystick shows the correct movement for all sticks and buttons. It currently has XBox360 gamepad and Final Fantasy mapping.

I found this file when I downloaded the jme3 from the repository (under “core-data”), but it must be somewhere on your computer even when you only use the SDK - but then you have to search through all places where jME stuff is located (that’s at least 3 different locations under Windows 7).

1 Like

I guess what @pspeed is trying to say is, that we could build up a database containing all names of all devices and then find out if they support XInput or DirectInput or whatever by looking up meta-data on the internet. I haven’t found such a database yet, but didn’t really search for it. I always wanted such thing for jME but it will stay a dream, I guess.

Note: The correct name will usually only show up if the drivers have been installed or detected. Until that the gamepads usually have strange nonesense names like “Human Interface Device” or else…

1 Like

It’s in the core data… which I think gets packaged in the jme3-core.jar… which is nice for reference.

It’s setup so that you can also have a custom one in your classpath. So if you put your own version of joystick-mapping.properties in your src directory or assets directory root then it should pick it up automatically to try local changes.

If you come up with mappings that work then we gladly accept them back in the built in version. :slight_smile:

2 Likes

At this point, I’d like to hear more about the possible causes of my axis not being detected while using Xinput, and also this line on the joystick mapping file:

requires custom code to support trigger buttons but this
keeps it from confusing the .rx mapping.

As I recall: Trigger buttons in XBox360 Gamepad are another axis during e.g. racing games - so they are not buttons but an axis with float values from -1.0f … +1.0f.
Problem with DirectInput is: These values are just being added (so if you press both triggers to the maximum, then the value should be 0.0f (zero).
With XInput the XBox gamepad has two separate axes for left and right trigger (so no sum is calculated).

For what that “custom code” is, I don’t know, maybe @pspeed remembers what that means.

Edit: Many cheap gamepads have two buttons instead of two soft triggers (and many Playstation gamepads too). So some gamepads are good for racing and others are not.

The axis I was missing was the up/down from a thumbstick (where the left/right was curiously handled by front triggers).

Yes, I need to clarify it: Your gamepad should be set to “DirectInput” mode when using it with jME, because jME uses DirectInput. The other mode is wrong because jME currently doesn’t have XInput support.

But then, how about the xbox360 controller? I believe my device is emulating that and having the same issues…

That would be new to me, one of the triggers uses the positive values and the other one negative values. Not very hard to solve that in your program.

The XBox controller works fine under direct input. (Well beside the rumbling)

Beside that, the xinput api is very limited on its own, probably 10 steps backward compared to directinput. You can see that it was designed for the xbox and then “ported” to pc. It basically allows no other controller layout then the xbox layout. No additional button, no additional axis, and only two rumblers. Strangely enough, they are called left and right, even on a xbox 360 controller there mapped to “hard and soft” rumblers.

As stated above, xinput does support only:

  • Max 4 controllers
  • 4 axes
  • 10 Buttons
  • 2 triggers
  • 8 direction d-pad

(Post #57 in this thread)

Either zzuegg’s code or code from GLFW 3.1.1 (which might become part of jME 3.1 Alpha 2).

Also note, that I and @Momoko_Fan suggested to give the user the choice over which input library (XInput or DirectInput) the user will use in future versions.

And note that both libraries have their pro and con. XInput does not support all devices (it’s pretty much XBox gamepad). XInput does not support more than 4 gamepads. XInput is Windows only. XInput is the only input API allowed for Windows Store apps.

The XBox 360 gamepad can be used with DirectInput. For many games it will be okay. But of course with XInput (or “custom code”) would be better. If used with DirectInput, the XBox gamepad has four strange things:

  1. the adding up of soft triggers (mentioned before).
  2. the force feedback motors won’t work.
  3. the XBox button will send you to the desktop (I mean the button with the “X Logo”)
  4. the analog sticks will have a maximum of 0.7f when pushed into diagonal position, but you can simply compensate for that strangeness by using a circular mapping for the XBox gamepad (the math is quite simple).

So it’s some problems currently, but I hope we can address those in the near future of jME. :chimpanzee_smile:

1 Like

That would not allow to use a xbox and a regulard controller at the same time. I there is a vote i would be against such a system. If implemented nicely it should be additive. JInput for everything and XInput only for XBox controllers

1 Like

(Damned, I can’t figure out how to quote something that has a quote in it).

The problem is that @Pesegato doesn’t use XInput. Under the hood it’s DirectInput, but the gamepad has a hardware switch for the mode (XInput or DirectInput) that gives strange values with jME when set to XInput, but still kind of works.