Joystick / Gamepad Integration

Hi,

what’s the recommended way to implement joystick / gamepad integration in a JME 3.1 (stable) based game project?

I’ve found a few different approaches and I’m not sure how to do it properly:

The wiki mentions JoyButtonTrigger / JoyAxisTrigger in the “Choose Trigger” section:

input.addMapping( TRIGGER_A, new JoyButtonTrigger( 0, 0 ) );

The TestJoystick.java sample program does implement its own RawInputListener:

protected class JoystickEventListener implements RawInputListener

There are also methods to assign mappings to joystick buttons when iterating through them:

Joystick[] joysticks = inputManager.getJoysticks();
		
for ( Joystick joystick : joysticks )
{
	for ( JoystickButton button : joystick.getButtons() )
	{				
		if ( joystick.getJoyId() == 0 )
			if ( button.getButtonId() == 0 )
				button.assignButton( TRIGGER_A );
	}
}

I have already done this on app initialization:

settings.setUseJoysticks( true );

The gamepad works fine in other engines (original Gamecube controller connected to a Windows 7 64-bit PC through a USB adapter).
It also gets reported correctly by the input manager if I do some console logging with inputManager.getJoysticks() (for example joystick id 0 and button id 0 should be available).

I basically just want to be able to assign events to axis / button input on a gamepad.

So how should I do this?

Any help is greatly appreciated!

Run TestJoyStick if you want to see how your joystick is reporting things. For joysticks that report their names nicely, we can even include mappings (even specific to your game) to map them to the standard buttons through a properties file.

As for how to map them to use in your game, my (somewhat biased) opinion is that you will have a much nicer time if you use the InputMapper that is built into Lemur. (You can use it without the rest of Lemur if you like… but it’s super useful.)

InputMapper is nice because it lets you treat joystick axes like any other button-based axes, mouse axes, etc. you can map them all to the same functions and your code doesn’t care. You can even scale them differently, etc…

You can see an example of this in the first Lemur Gem.

…which as I recall works out of the box with many standard game controllers as well as mouse/keyboard. All with the same handler code.

1 Like

Where is this properties file? What do you mean by standard buttons? Is there some documentation about his? Sorry, but I just don’t quite understand the purpose of it. I guess it’s to help users have their controller devices automatically recognized and mapped to the proper actions.

As for how to map them to use in your game, my (somewhat biased) opinion is that you will have a much nicer time if you use the InputMapper that is built into Lemur.

Thanks for the hint! I’m just not sure if I want to add another layer of abstraction to my input system at this point but I will evaluate this API.

So, meanwhile I figured out that it was actually a hardware problem! There is some issue with the controller connecting through the adapter socket. Although the driver reports the gamepad as properly connected, no input data can be polled if the connector is not in a certain position. I contacted the adapter manufacturer (raphnet) about this.

Edit:
On the attached image you can see my incredibly professional hardware fix using a piece of folded paper :smile:

1 Like

It’s built into JME… but you can also have one locally in your app’s classpath. Often placing it in the assets folder is the way to go.

Mostly the remapping is for strange axis configurations but it can also be used to remap one button to another if they are very strange. But for example, it’s nice for users if the select/start buttons, etc. are the same mapping.

This is what the file looks like:

For joysticks that give proper names, it’s nice if we can create a sort of database of consistent mappings. Kind of crucial for the axes to be mapped properly but really nice for the buttons as well.

There is talk about moving this particular API to core because it fills in a lot of gaps of InputManager. It’s not really another layer of abstraction but an alternate layer of abstraction. Instead of using JME’s triggers and analog stuff… you us InputMapper’s versions of those. InputMapper is not using JME’s triggers… it’s adding a RawInputListener to InputManager and doing its own thing.