From b720f1f03c70c1b83482a902ad0f0c9a34a6861a Mon Sep 17 00:00:00 2001 From: Stuart Carnie Date: Sat, 11 Dec 2021 08:10:21 +1100 Subject: [PATCH] Backends: OSX: Add Game Controller support. (#4759) --- backends/imgui_impl_osx.h | 1 + backends/imgui_impl_osx.mm | 48 +++++++++++++++++++ docs/CHANGELOG.txt | 1 + .../project.pbxproj | 4 ++ .../project.pbxproj | 4 ++ 5 files changed, 58 insertions(+) diff --git a/backends/imgui_impl_osx.h b/backends/imgui_impl_osx.h index e4c1d04a6..c223c2cc1 100644 --- a/backends/imgui_impl_osx.h +++ b/backends/imgui_impl_osx.h @@ -5,6 +5,7 @@ // Implemented features: // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend). +// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // Issues: // [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters].. diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 97555e6ce..0c1b3dec2 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -5,6 +5,7 @@ // Implemented features: // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend). +// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // Issues: // [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters].. @@ -17,9 +18,11 @@ #include "imgui_impl_osx.h" #import #include +#import // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-12-13: Add game controller support. // 2021-09-21: Use mach_absolute_time as CFAbsoluteTimeGetCurrent can jump backwards. // 2021-08-17: Calling io.AddFocusEvent() on NSApplicationDidBecomeActiveNotification/NSApplicationDidResignActiveNotification events. // 2021-06-23: Inputs: Added a fix for shortcuts using CTRL key instead of CMD key. @@ -234,6 +237,50 @@ static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() } } +void ImGui_ImplOSX_UpdateGamepads() +{ + ImGuiIO& io = ImGui::GetIO(); + memset(io.NavInputs, 0, sizeof(io.NavInputs)); + if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) + return; + + GCController* controller; + if (@available(macOS 11.0, *)) + controller = GCController.current; + else + controller = GCController.controllers.firstObject; + + if (controller == nil || controller.extendedGamepad == nil) + { + io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; + return; + } + + GCExtendedGamepad* gp = controller.extendedGamepad; + +#define MAP_BUTTON(NAV_NO, NAME) { io.NavInputs[NAV_NO] = gp.NAME.isPressed ? 1.0 : 0.0; } + MAP_BUTTON(ImGuiNavInput_Activate, buttonA); + MAP_BUTTON(ImGuiNavInput_Cancel, buttonB); + MAP_BUTTON(ImGuiNavInput_Menu, buttonX); + MAP_BUTTON(ImGuiNavInput_Input, buttonY); + MAP_BUTTON(ImGuiNavInput_DpadLeft, dpad.left); + MAP_BUTTON(ImGuiNavInput_DpadRight, dpad.right); + MAP_BUTTON(ImGuiNavInput_DpadUp, dpad.up); + MAP_BUTTON(ImGuiNavInput_DpadDown, dpad.down); + MAP_BUTTON(ImGuiNavInput_FocusPrev, leftShoulder); + MAP_BUTTON(ImGuiNavInput_FocusNext, rightShoulder); + MAP_BUTTON(ImGuiNavInput_TweakSlow, leftTrigger); + MAP_BUTTON(ImGuiNavInput_TweakFast, rightTrigger); +#undef MAP_BUTTON + + io.NavInputs[ImGuiNavInput_LStickLeft] = gp.leftThumbstick.left.value; + io.NavInputs[ImGuiNavInput_LStickRight] = gp.leftThumbstick.right.value; + io.NavInputs[ImGuiNavInput_LStickUp] = gp.leftThumbstick.up.value; + io.NavInputs[ImGuiNavInput_LStickDown] = gp.leftThumbstick.down.value; + + io.BackendFlags |= ImGuiBackendFlags_HasGamepad; +} + void ImGui_ImplOSX_NewFrame(NSView* view) { // Setup display size @@ -256,6 +303,7 @@ void ImGui_ImplOSX_NewFrame(NSView* view) g_Time = current_time; ImGui_ImplOSX_UpdateMouseCursorAndButtons(); + ImGui_ImplOSX_UpdateGamepads(); } static int mapCharacterToKey(int c) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index bc72a06b5..6af83a6e2 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -103,6 +103,7 @@ Other Changes: - Backends: DX12: Fixed DRAW_EMPTY_SCISSOR_RECTANGLE warnings. (#4775) - Backends: SDL_Renderer: Added support for large meshes (64k+ vertices) with 16-bit indices, enabling 'ImGuiBackendFlags_RendererHasVtxOffset' in the backend. (#3926) [@rokups] +- Backends: OSX: Add Game Controller support (need linking GameController framework) (#4759) [@stuartcarnie] - Backends: WebGPU: Passing explicit buffer sizes to wgpuRenderPassEncoderSetVertexBuffer() and wgpuRenderPassEncoderSetIndexBuffer() functions as validation layers appears to not do what the in-flux specs says. (#4766) [@meshula] diff --git a/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj b/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj index 040fcd642..4bb4fc288 100644 --- a/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj +++ b/examples/example_apple_metal/example_apple_metal.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05318E0E274C397200A8DE2E /* GameController.framework */; }; 07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; }; 07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; }; 5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; }; @@ -32,6 +33,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 05318E0E274C397200A8DE2E /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; 07A82ED62139413C0078D120 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = ""; }; 07A82ED72139413C0078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = ""; }; 5079822D257677DB0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = ""; }; @@ -76,6 +78,7 @@ files = ( 8309BDC6253CCCFE0045E2A1 /* AppKit.framework in Frameworks */, 83BBE9EC20EB471700295997 /* MetalKit.framework in Frameworks */, + 05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */, 83BBE9ED20EB471700295997 /* Metal.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -133,6 +136,7 @@ 83BBE9E320EB46B800295997 /* Frameworks */ = { isa = PBXGroup; children = ( + 05318E0E274C397200A8DE2E /* GameController.framework */, 8309BDC5253CCCFE0045E2A1 /* AppKit.framework */, 8309BD8E253CCAAA0045E2A1 /* UIKit.framework */, 83BBE9EE20EB471C00295997 /* ModelIO.framework */, diff --git a/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj b/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj index 82fb267c9..a168373d4 100644 --- a/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj +++ b/examples/example_apple_opengl2/example_apple_opengl2.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 05E31B59274EF0700083FCB6 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05E31B57274EF0360083FCB6 /* GameController.framework */; }; 07A82EDB213941D00078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82EDA213941D00078D120 /* imgui_widgets.cpp */; }; 4080A99820B02D340036BA46 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4080A98A20B02CD90036BA46 /* main.mm */; }; 4080A9A220B034280036BA46 /* imgui_impl_opengl2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A99E20B034280036BA46 /* imgui_impl_opengl2.cpp */; }; @@ -32,6 +33,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 05E31B57274EF0360083FCB6 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; 07A82EDA213941D00078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = ""; }; 4080A96B20B029B00036BA46 /* example_osx_opengl2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = example_osx_opengl2; sourceTree = BUILT_PRODUCTS_DIR; }; 4080A98A20B02CD90036BA46 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = SOURCE_ROOT; }; @@ -57,6 +59,7 @@ files = ( 4080A9B520B034EA0036BA46 /* OpenGL.framework in Frameworks */, 4080A9B320B034E40036BA46 /* Cocoa.framework in Frameworks */, + 05E31B59274EF0700083FCB6 /* GameController.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -95,6 +98,7 @@ 4080A9B120B034E40036BA46 /* Frameworks */ = { isa = PBXGroup; children = ( + 05E31B57274EF0360083FCB6 /* GameController.framework */, 4080A9B420B034EA0036BA46 /* OpenGL.framework */, 4080A9B220B034E40036BA46 /* Cocoa.framework */, );