Joystick implementation

Hello,
yesterday I finally managed to get Joystick rumblers to work, though the driver implementation isn’t very robust and let to JVM crashes during my first experiments.

Now my question:
Why does the jME implementation hide the fact that there are multiple rumblers on most gamepads?
The code only supports one float value which is then forwarded to all motors, so you can only have very simple rumble effect curves.
I would like two phase-shiftet sine waves that cause a left-right-left-right-left-… vibration pattern in the players hands.
It may also be that one motor generates the “bass” while the second motor provides the “high frequency” vibration.

I don’t see any reason why the interface couldn’t be changed

  • from -
    void rumble(float amount);
  • to -
    void rumble(float amount);
    void rumble(float amount, int id);
    int getNumRumblers( );

What do you think?

@Ogli said: Hello, yesterday I finally managed to get Joystick rumblers to work, though the driver implementation isn't very robust and let to JVM crashes during my first experiments.

Now my question:
Why does the jME implementation hide the fact that there are multiple rumblers on most gamepads?
The code only supports one float value which is then forwarded to all motors, so you can only have very simple rumble effect curves.
I would like two phase-shiftet sine waves that cause a left-right-left-right-left-… vibration pattern in the players hands.
It may also be that one motor generates the “bass” while the second motor provides the “high frequency” vibration.

I don’t see any reason why the interface couldn’t be changed

  • from -
    void rumble(float amount);
  • to -
    void rumble(float amount);
    void rumble(float amount, int id);
    int getNumRumblers( );

What do you think?

Does the underlying jInput API support it?

I don’t mind adding support for multiple rumblers but I have no way of testing it and I don’t know if we are just exposing the limitations of the underlying API or not. I think at least two of my gamepads support rumble but I was never able to get it working.

Have you already looked deeper?

Hey,
I just finished a simple testing of all my gaming devices, many of them have rumble support.
Yes, the underlying API gives an iterable collection to jME! (see net.java.games.input.Controller from lwjgl.jar)

I will post my “TestRumble.java” tonight or tomorrow and you can check rumble by pressing SPACE.
I simply used a modified SVN version of TestJoystick.java together with the latest SVN.
But the test program seems to run under jME SDK as well.

Here is what I found out:

  • most gamepads with vibration have two motors
  • to work properly you need the commercial drivers under Windows
  • most of these drivers have a rumble test included (you push a stick and rumble starts)
  • LWJGL recognized all but one vibration device, which is my wireless PS-style gamepad (has rumble, but LWJGL returns 0 rumblers)

There are things to be found out, like these:

  • why does the rumble call lead to crashes under certain circumstances
  • is there a “adjust rumble” or will calls to “rumble” always reset the motors (looks like it does, which is bad)
  • why don’t I get weak rumbles with rumble < 1.0f (feels always the same, even when I start rumble(0.0001f) or so)

Thanks for doing the legwork.

I may have to see if I can get the drivers for mine to play with this also.

Maybe you will have to wait another day.
It’s because I’m almost full-time forum writing and reading.
And then there is a life aside all this - at least basic things must be done. :wink:

I will report back soon and post the code in the contrib section of the forum.

I couldn’t make this as cool as I wanted (yet), but here it is … the TestRumble.java (simple version)

http://www.lostplanets.de/files/TestRumble.java

Some words about it:

  • when you press [SPACE] a rumble curve is started for all attached gaming devices
  • I’m using the current version of the rumble implementation which isn’t perfect (see previous post)
  • I couldn’t get my XBox360 pad get to rumble - but other gamepads work (if they have rumble motors)
  • I changed the controller visualization slightly:
  • some elements were being repositioned (dpad / coolie hat) with a 45 degree rotation
  • at code line 504 I’m using some cool rotation maths, because I was too lazy to add an additional pivot node

I’m currently working on a more sophisticated version with visualization for rumble curves.
This “more sophisticated” is the reason why it’s taking me so long to finish it. :slight_smile:

sorry to dig this one back, but I just got a gamepad (with two motors)
and checked your code, it only has a rumble(float) function, so it does not solve anything …?

I found this code on another post, althought it pretends to turn on multiple motors, I dont feel any difference in my hands, just as if it only the right motor was turning (also it does not turns smoothly, it feels jerky)

I tested the gamepad with the control pannel tester, and both motors work, so I am wondering if JInput really works at all

ControllerEnvironment cEnvironment = ControllerEnvironment.getDefaultEnvironment();

            Controller[] cControllers = cEnvironment.getControllers();

            if (cControllers.length>0)
            {
                for (int i = 0; i < cControllers.length; i++) 
                {
                      if (cControllers[i].getType() == Controller.Type.GAMEPAD) 
                      {
                          System.out.println ("Controller Name: " + cControllers[i].getName()+" Type: " + (cControllers[i].getType())+" Rumble: " + ((cControllers[i].getRumblers().length > 0) ? "Yes" : "No"));

                          for (int o = 0; o < cControllers[i].getRumblers().length; o++) 
                          {
                              System.out.println ("- Rumbling Axis: " + cControllers[i].getRumblers()[o].getAxisName());
                              cControllers[i].getRumblers()[o].rumble(1.0f);
                              Thread.Sleep(5000);
                              cControllers[i].getRumblers()[o].rumble(0.0f);
                              Thread.Sleep(2000);
                          }
                      }
                }
            }

any advice ?

thanks