Skip to content
This repository was archived by the owner on Feb 8, 2025. It is now read-only.

Commit b37e3ed

Browse files
committed
Added gamepad support
1 parent 13bcf44 commit b37e3ed

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

.idea/gradle.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/java/imguiimplsdl24j/library/ImGuiImplSDL2.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@
1111
import imgui.flag.ImGuiKey;
1212
import imgui.flag.ImGuiMouseCursor;
1313
import io.github.libsdl4j.api.event.SDL_Event;
14+
import io.github.libsdl4j.api.gamecontroller.SDL_GameController;
1415
import io.github.libsdl4j.api.mouse.SDL_Cursor;
1516
import io.github.libsdl4j.api.syswm.SDL_SysWMInfo;
1617
import io.github.libsdl4j.api.video.SDL_Window;
1718
import org.jetbrains.annotations.NotNull;
1819
import org.lwjgl.system.Platform;
1920

2021
import static io.github.libsdl4j.api.event.SDL_EventType.*;
22+
import static io.github.libsdl4j.api.gamecontroller.SDL_GameControllerAxis.*;
23+
import static io.github.libsdl4j.api.gamecontroller.SDL_GameControllerButton.*;
24+
import static io.github.libsdl4j.api.gamecontroller.SdlGamecontroller.*;
2125
import static io.github.libsdl4j.api.hints.SdlHints.SDL_SetHint;
2226
import static io.github.libsdl4j.api.hints.SdlHintsConst.SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH;
2327
import static io.github.libsdl4j.api.keycode.SDL_Keycode.*;
@@ -307,6 +311,7 @@ public static void newFrame() {
307311

308312
updateMouseData();
309313
updateMouseCursor();
314+
updateGamepads();
310315
}
311316

312317
private static void updateMouseData() {
@@ -340,6 +345,55 @@ private static void updateMouseCursor() {
340345
}
341346
}
342347

348+
private static void updateGamepads() {
349+
ImGuiIO io = ImGui.getIO();
350+
if(!io.hasConfigFlags(ImGuiConfigFlags.NavEnableGamepad)) return;
351+
352+
final SDL_GameController controller = SDL_GameControllerOpen(0);
353+
if(controller == null) return;
354+
355+
io.addBackendFlags(ImGuiBackendFlags.HasGamepad);
356+
357+
final int thumbDeadZone = 8000;
358+
mapButton(ImGuiKey.GamepadStart, SDL_CONTROLLER_BUTTON_START, io, controller);
359+
mapButton(ImGuiKey.GamepadBack, SDL_CONTROLLER_BUTTON_BACK, io, controller);
360+
mapButton(ImGuiKey.GamepadFaceDown, SDL_CONTROLLER_BUTTON_A, io, controller); // Xbox A, PS Cross
361+
mapButton(ImGuiKey.GamepadFaceRight, SDL_CONTROLLER_BUTTON_B, io, controller); // Xbox B, PS Circle
362+
mapButton(ImGuiKey.GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X, io, controller); // Xbox X, PS Square
363+
mapButton(ImGuiKey.GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y, io, controller); // Xbox Y, PS Triangle
364+
mapButton(ImGuiKey.GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT, io, controller);
365+
mapButton(ImGuiKey.GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, io, controller);
366+
mapButton(ImGuiKey.GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP, io, controller);
367+
mapButton(ImGuiKey.GamepadDpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN, io, controller);
368+
mapButton(ImGuiKey.GamepadL1, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, io, controller);
369+
mapButton(ImGuiKey.GamepadR1, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, io, controller);
370+
mapAnalog(ImGuiKey.GamepadL2, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0.0f, 32767, io, controller);
371+
mapAnalog(ImGuiKey.GamepadR2, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767, io, controller);
372+
mapButton(ImGuiKey.GamepadL3, SDL_CONTROLLER_BUTTON_LEFTSTICK, io, controller);
373+
mapButton(ImGuiKey.GamepadR3, SDL_CONTROLLER_BUTTON_RIGHTSTICK, io, controller);
374+
mapAnalog(ImGuiKey.GamepadLStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumbDeadZone, -32768, io, controller);
375+
mapAnalog(ImGuiKey.GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumbDeadZone, +32767, io, controller);
376+
mapAnalog(ImGuiKey.GamepadLStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumbDeadZone, -32768, io, controller);
377+
mapAnalog(ImGuiKey.GamepadLStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumbDeadZone, +32767, io, controller);
378+
mapAnalog(ImGuiKey.GamepadRStickLeft, SDL_CONTROLLER_AXIS_RIGHTX, -thumbDeadZone, -32768, io, controller);
379+
mapAnalog(ImGuiKey.GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumbDeadZone, +32767, io, controller);
380+
mapAnalog(ImGuiKey.GamepadRStickUp, SDL_CONTROLLER_AXIS_RIGHTY, -thumbDeadZone, -32768, io, controller);
381+
mapAnalog(ImGuiKey.GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumbDeadZone, +32767, io, controller);
382+
}
383+
384+
private static void mapButton(int keyNo, int buttonNo, @NotNull ImGuiIO io, SDL_GameController controller) {
385+
io.addKeyEvent(keyNo, SDL_GameControllerGetButton(controller, buttonNo) != 0);
386+
}
387+
388+
private static void mapAnalog(int keyNo, int axisNo, float v0, float v1, @NotNull ImGuiIO io, SDL_GameController controller) {
389+
float vn = imSaturate((SDL_GameControllerGetAxis(controller, axisNo) - v0) / (v1 - v0));
390+
io.addKeyAnalogEvent(keyNo, vn > 0.1f, vn);
391+
}
392+
393+
private static float imSaturate(float v) {
394+
return v < 0.0f ? 0.0f : Math.min(v, 1.0f);
395+
}
396+
343397
/**
344398
* Disposes ImGuiImplSDL2.
345399
*/

src/test/java/Main.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import imgui.ImGui;
22
import imgui.ImGuiIO;
3+
import imgui.flag.ImGuiConfigFlags;
34
import imgui.gl3.ImGuiImplGl3;
45
import imguiimplsdl24j.library.ImGuiImplSDL2;
56
import io.github.libsdl4j.api.event.SDL_Event;
@@ -10,6 +11,7 @@
1011

1112
import static io.github.libsdl4j.api.Sdl.SDL_Init;
1213
import static io.github.libsdl4j.api.Sdl.SDL_Quit;
14+
import static io.github.libsdl4j.api.SdlSubSystemConst.SDL_INIT_GAMECONTROLLER;
1315
import static io.github.libsdl4j.api.SdlSubSystemConst.SDL_INIT_VIDEO;
1416
import static io.github.libsdl4j.api.error.SdlError.SDL_GetError;
1517
import static io.github.libsdl4j.api.event.SDL_EventType.SDL_QUIT;
@@ -24,7 +26,7 @@
2426
public final class Main {
2527
public static void main(String[] args) {
2628
// Initialize SDL2 with SDL_INIT_VIDEO
27-
if(SDL_Init(SDL_INIT_VIDEO) != 0) throw new IllegalStateException("Failed to initialize SDL2: " + SDL_GetError());
29+
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) != 0) throw new IllegalStateException("Failed to initialize SDL2: " + SDL_GetError());
2830

2931
// Create an SDL2 window
3032
final SDL_Window window = SDL_CreateWindow("ImGuiImplSDL2-4j Demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
@@ -40,6 +42,7 @@ public static void main(String[] args) {
4042
ImGui.createContext();
4143
ImGuiIO io = ImGui.getIO();
4244
io.setIniFilename(null);
45+
io.addConfigFlags(ImGuiConfigFlags.NavEnableGamepad);
4346
// Enable the FreeType font renderer if we are not on MacOS
4447
if(Platform.get() != Platform.MACOSX) io.getFonts().setFreeTypeRenderer(true);
4548
io.getFonts().addFontDefault();

0 commit comments

Comments
 (0)