Skip to content
Switch branches/tags


RetroWar: 8-bit Party Battle is out now. Defeat up to 15 of your friends in a tournament of 80s-inspired retro mini games.

sdl2gdx (Java SDL & GDX Controllers)


This library provides APIs at three layers:

  1. A Java wrapper around SDL. Currently we wrap most of Joystick and GameController. PRs to wrap further APIs are welcome. This wrapper is as close to the C source as possible, so you should be able to port any SDL examples with no changes.
  2. An OO wrapper on top of layer 1. The same functions as provided by SDL, but with a class based API to make them more friendly to use.
  3. An implementation of LibGDX Controller API on top of layer 2. You can slot this straight in to any LibGDX app, or you can use it directly in a non-LibGDX app.

Thanks to Jamepad by William Harman for providing the basis, native build system and inspiration for this project.


Compared to the default LibGDX Controller implementation:

  • Hotplug works.
  • Doesn't quit working when the screenmode changes.
  • Rumble!
  • Can get more info, such as device power level and XInput Player LED number.
  • Database of mappings for large number of controllers, so you don't have to worry about it.
  • SDL is recommended by Valve as second best way to do input for Steam (after Steam Input of course!)
  • Supports Nintendo and Sony controllers using USB drivers taken from Steam.
  • Supports more than 4 XInput controllers


Add the repo if you don't have it in your build.gradle already

    repositories {
+        jcenter()

For a project not using LibGDX

    dependencies {
+       compile ""

See examples and docs below for how to call the API.

For a LibGDX desktop project

project(":desktop") {
    dependencies {
        implementation "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"
        implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
        implementation "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop"
-       implementation "com.badlogicgames.gdx:gdx-controllers-desktop:$gdxVersion"
-       implementation "com.badlogicgames.gdx:gdx-controllers-platform:$gdxVersion:natives-desktop"

project(":core") {
    dependencies {
        implementation "com.badlogicgames.gdx:gdx:$gdxVersion"
        implementation "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
        implementation "com.badlogicgames.gdx:gdx-controllers:$gdxVersion"
+       implementation ""

This will use SDL under the hood for all your controllers. That's it, done, with no changes to your code! See LibGDX docs for how to use controllers.

Adding to the core project means you are free to use the additional SDL2 APIs anywhere in your code, but it won't work if you also have html5 or mobile projects. In that case add sdl2gdx to just the desktop project and not the core project.

Example LibGDX project


What if you want to use a feature of SDL that is not supported by the LibGDX Controller API, e.g. rumble?

If you didn't add sdl2gdx to your core project, you will need instead to create a file in your core project:

import com.badlogic.gdx.controllers.Controller;

public interface RumbleController extends Controller {
    boolean rumble(float leftMagnitude, float rightMagnitude, int duration_ms);

Then when you want to use rumble, make sure you're on Desktop platform and typecast:

if( == Application.ApplicationType.Desktop){
    RumbleController controller = (RumbleController) Controllers.getControllers().get(0);

You could also typecast your Controller to SDL2Controller for other features like power level.


You might also like


sdl2gdx is distributed under the GPL license with the Classpath Exception to allow linking, the same as OpenJDK itself, so you can use it anywhere that you use the JDK, for both free and non-free ('closed source') projects.

Building from source