Step 1. Add the JitPack repository to your build file
Add it in your root settings.gradle at the end of repositories:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
Add it in your settings.gradle.kts at the end of repositories:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}
Add to pom.xml
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Add it in your build.sbt at the end of resolvers:
resolvers += "jitpack" at "https://jitpack.io"
Add it in your project.clj at the end of repositories:
:repositories [["jitpack" "https://jitpack.io"]]
Step 2. Add the dependency
dependencies {
implementation 'com.github.loriopatrick:Jamepad:1.3'
}
dependencies {
implementation("com.github.loriopatrick:Jamepad:1.3")
}
<dependency>
<groupId>com.github.loriopatrick</groupId>
<artifactId>Jamepad</artifactId>
<version>1.3</version>
</dependency>
libraryDependencies += "com.github.loriopatrick" % "Jamepad" % "1.3"
:dependencies [[com.github.loriopatrick/Jamepad "1.3"]]
Jamepad is a library for using gamepads in Java. It's based on SDL2 (here) and uses jnigen (more info here). We also use this really nice database of gamepad mappings.
Other gamepad libraries are missing stuff developers need. For most libraries, Xbox 360 controllers on windows are not properly supported. The libraries that do support Xbox 360 controllers are not cross platform (or are GPL encumbered). On some, hotplugging controllers is not supported.
Jamepad has:
If you use gradle, you can pull this package in from jitpack. First, add jitpack to your repositories section:
repositories {
...
maven { url "https://jitpack.io" }
}
Next, add this line to your dependencies section. Update the version number to whatever the latest release is.
dependencies {
...
compile 'com.github.WilliamAHartman:Jamepad:1.1'
}
If you aren't using gradle, just download the .jar file from the releases section and add it to your project as usual.
There are two main ways to use Jamepad. Both rely on a ControllerManager Object.
ControllerManager controllers = new ControllerManager();
controllers.initSDLGamepad();
For most applications, using the getState() method in ControllerManager is best. This method returns an immutable ControllerState object that describes the state of the controller at the instant the method is called. Using this method, you don't need to litter code with a bunch of exceoption handling or handle the possiblity of controller disconnections at weird times.
If a controller is disconnected, the returned ControllerState object has the isConnected field set to false. All other fields are either false (for buttons) or 0 (for axes).
Here's a simple example:
//Print a message when the "A" button is pressed. Exit if the "B" button is pressed
//or the controller disconnects.
while(true) {
ControllerState currState = controllers.getState(0);
if(!currState.isConnected || currState.b) {
break;
}
if(currState.a) {
System.out.println("\"A\" on \"" + currState.controllerType + "\" is pressed");
}
}
For a select few applications, getState() might not be the best decision. Since ControllerState is immutable, a new one is instantiated on each call to getState(). This should be fine for normal desktop JVMs; both Oracle's JVM and the OpenJDK one should absolutely be able to handle this. What problems do come up could probably be solved with some GC tuning.
If these allocations do end up being an actual problem, you can access the internal representation of the controllers. This is more complicated to use, and you might need to deal with some exceptions.
Here's a pretty barebones example:
//Print a message when the "A" button is pressed. Exit if the "B" button is pressed
//or the controller disconnects.
ControllerIndex currController = controllers.getControllerIndex(0);
while(true) {
controllers.update(); //If using ControllerIndex, you should call update() to check if a new controller
//was plugged in or unplugged at this index.
try {
if(currController.isButtonPressed(ControllerButton.A)) {
System.out.println("\"A\" on \"" + currController.getName() + "\" is pressed");
}
if(currController.isButtonPressed(ControllerButton.B)) {
break;
}
} catch (ControllerUnpluggedException e) {
break;
}
}
When you're finished with your gamepad stuff, you should call quitSDLGamepad() to free the native library.
controllers.quitSDLGamepad();
gradle windowsNatives
gradle linuxNatives
libs
folder) to the macgradle OSXNatives
gradle dist
to generate a .jar file with all the dependencies bundledRight now the Windows and Linux binaries, Jamepad needs to be built on Linux. The binaries for Windows are cross-compiled.
The following packages (or equivalents) are needed:
gradle
ant
build-essential
libc6-i386
libc6-dev-i386
g++-multilib
g++-mingw-w64-i686
g++-mingw-w64-x86-64
If you've built C stuff for different platforms and bitnesses, you probably have all this stuff. If not, use your package manager to get them all. It should be something like this if you're on Ubuntu or Debian or whatever:
sudo apt-get install ant gradle build-essential libc6-i386 libc6-dev-i386 g++-multilib g++-mingw-w64-i686 g++-mingw-w64-x86-64
The OS X binaries currently must be built on OS X. It is probably possible to build the Windows and Linux binaries here too, but I haven't tried that out.
The dependencies are pretty much the same (gradle, ant, g++). These packages can be installed from homebrew.