Browse Source

Added support to use controllers via SDL_GameController. (#2509)

Updated sdl examples to use SDL_INIT_GAMECONTROLLER flag
David Amador 6 years ago
parent
commit
994a92d79d

+ 1 - 1
examples/example_sdl_opengl2/main.cpp

@@ -16,7 +16,7 @@
 int main(int, char**)
 int main(int, char**)
 {
 {
     // Setup SDL
     // Setup SDL
-    if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0)
+    if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_GAMECONTROLLER) != 0)
     {
     {
         printf("Error: %s\n", SDL_GetError());
         printf("Error: %s\n", SDL_GetError());
         return -1;
         return -1;

+ 1 - 1
examples/example_sdl_opengl3/main.cpp

@@ -25,7 +25,7 @@
 int main(int, char**)
 int main(int, char**)
 {
 {
     // Setup SDL
     // Setup SDL
-    if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0)
+    if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_GAMECONTROLLER) != 0)
     {
     {
         printf("Error: %s\n", SDL_GetError());
         printf("Error: %s\n", SDL_GetError());
         return -1;
         return -1;

+ 1 - 1
examples/example_sdl_vulkan/main.cpp

@@ -319,7 +319,7 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
 int main(int, char**)
 int main(int, char**)
 {
 {
     // Setup SDL
     // Setup SDL
-    if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0)
+    if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_GAMECONTROLLER) != 0)
     {
     {
         printf("Error: %s\n", SDL_GetError());
         printf("Error: %s\n", SDL_GetError());
         return 1;
         return 1;

+ 46 - 0
examples/imgui_impl_sdl.cpp

@@ -266,6 +266,49 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
     }
     }
 }
 }
 
 
+static void ImGui_ImplSDL2_UpdateGamepads()
+{
+    ImGuiIO& io = ImGui::GetIO();
+    memset(io.NavInputs, 0, sizeof(io.NavInputs));
+    if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
+        return;
+    
+    // Update gamepad inputs
+#define MAP_BUTTON(NAV_NO, BUTTON_NO)       { io.NavInputs[NAV_NO] = (SDL_GameControllerGetButton(game_controller, BUTTON_NO) == 1) ? 1.0f : 0.0f; }
+#define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
+   
+    int axes_count = 0, buttons_count = 0;
+    SDL_GameController* game_controller = SDL_GameControllerOpen(0);
+    if(game_controller !=NULL)
+    {
+        const int thumb_dead_zone = 8000;
+        
+        MAP_BUTTON(ImGuiNavInput_Activate, SDL_CONTROLLER_BUTTON_A);     // Cross / A
+        MAP_BUTTON(ImGuiNavInput_Cancel, SDL_CONTROLLER_BUTTON_B);     // Circle / B
+        MAP_BUTTON(ImGuiNavInput_Menu, SDL_CONTROLLER_BUTTON_X);     // Square / X
+        MAP_BUTTON(ImGuiNavInput_Input, SDL_CONTROLLER_BUTTON_Y);     // Triangle / Y
+        MAP_BUTTON(ImGuiNavInput_DpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT);    // D-Pad Left
+        MAP_BUTTON(ImGuiNavInput_DpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);    // D-Pad Right
+        MAP_BUTTON(ImGuiNavInput_DpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP);    // D-Pad Up
+        MAP_BUTTON(ImGuiNavInput_DpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN);    // D-Pad Down
+        MAP_BUTTON(ImGuiNavInput_FocusPrev, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);     // L1 / LB
+        MAP_BUTTON(ImGuiNavInput_FocusNext, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);     // R1 / RB
+        MAP_BUTTON(ImGuiNavInput_TweakSlow, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);     // L1 / LB
+        MAP_BUTTON(ImGuiNavInput_TweakFast, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);     // R1 / RB
+        MAP_ANALOG(ImGuiNavInput_LStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768);
+        MAP_ANALOG(ImGuiNavInput_LStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767);
+        MAP_ANALOG(ImGuiNavInput_LStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32767);
+        MAP_ANALOG(ImGuiNavInput_LStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767);
+#undef MAP_BUTTON
+#undef MAP_ANALOG
+    }
+    
+    if (axes_count > 0 && buttons_count > 0)
+        io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
+    else
+        io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
+}
+
 void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
 void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
 {
 {
     ImGuiIO& io = ImGui::GetIO();
     ImGuiIO& io = ImGui::GetIO();
@@ -288,4 +331,7 @@ void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
 
 
     ImGui_ImplSDL2_UpdateMousePosAndButtons();
     ImGui_ImplSDL2_UpdateMousePosAndButtons();
     ImGui_ImplSDL2_UpdateMouseCursor();
     ImGui_ImplSDL2_UpdateMouseCursor();
+
+    // Gamepad navigation mapping
+    ImGui_ImplSDL2_UpdateGamepads();
 }
 }