-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support AB / XY Button Swapping / Remap #5723
Conversation
@@ -72,7 +75,7 @@ | |||
#include <TargetConditionals.h> | |||
#endif | |||
|
|||
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__) | |||
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__) && !defined(__SWITCH__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The specific __SWITCH__
check could be replaced with a generic IMGUI_
define
4ba455c
to
06f4433
Compare
Please clarify why you need to disable
I think it would be preferable to provide a backend-agnostic and less intrusive alternative, e.g. by iterating |
Here's a function doing that (untested) #include "imgui_internal.h"
void ImGui_ImplSwitch_SwapABXY(int start_event)
{
auto& input_queue = ImGui::GetCurrentContext()->InputEventsQueue;
for (int n = start_event; n < input_queue.Size; n++)
{
ImGuiInputEvent& e = input_queue[n];
if (e.Type == ImGuiInputEventType_Key)
{
switch (e.Key.Key)
{
case ImGuiKey_GamepadFaceLeft: e.Key.Key = ImGuiKey_GamepadFaceUp; break; // X<>Y
case ImGuiKey_GamepadFaceUp: e.Key.Key = ImGuiKey_GamepadFaceLeft; break;
case ImGuiKey_GamepadFaceRight: e.Key.Key = ImGuiKey_GamepadFaceDown; break; // X<>B
case ImGuiKey_GamepadFaceDown: e.Key.Key = ImGuiKey_GamepadFaceRight; break;
}
}
}
} Usage: // Start the Dear ImGui frame
const int input_queue_size_before = ImGui::GetCurrentContext()->InputEventsQueue.Size; // record event count before backend submit them
ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
// Call between backend and main lib NewFrame():
ImGui_ImplSwitch_SwapABXY(input_queue_size_before);
ImGui::NewFrame(); |
As the imgui core code never actually uses #define ImGuiKey_NavGamepadActivate ImGuiKey_GamepadFaceDown
#define ImGuiKey_NavGamepadCancel ImGuiKey_GamepadFaceRight
#define ImGuiKey_NavGamepadMenu ImGuiKey_GamepadFaceLeft
#define ImGuiKey_NavGamepadInput ImGuiKey_GamepadFaceUp Another and more correct solution would be to allow you to redefine those, then access to e.g. Closing as solved but let me know if you have any more issue. |
Thanks for the suggestion, I'm doing it this way now. It also seems to be fine now with Looks like all is working well! In case its still useful using the latest SDL from devKitPro |
I finally ended up getting this into our production. Unfortunately doing the swap in this manner messed with NavEnableGamepad. I’m exploring now the option of redefining what ImGui uses. If you happen to have any other suggestions I’d appreciate it! Would be good to have a good sign off to guide the work in case it’s something that’s useful to upstream. |
Can you clarify? |
Yeah.. still digging but essentially: doing a swap in this way is messing with the ability of navigating via gamepad buttons. It now seems to only handle the first button press then nothing more. Before we were doing it in sdl_impl:
My guess is that it’s the difference between changing the definition itself vs swapping the button press — but still trying to find a better working solution. |
Ok, can confirm that this instead still has gamepad navigation working: (doing this just if platform is SWITCH) #define ImGuiKey_NavGamepadActivate ImGuiKey_GamepadFaceRight
#define ImGuiKey_NavGamepadCancel ImGuiKey_GamepadFaceDown
#define ImGuiKey_NavGamepadMenu ImGuiKey_GamepadFaceUp
#define ImGuiKey_NavGamepadInput ImGuiKey_GamepadFaceLeft then changing #ifndef ImGuiKey_NavGamepadActivate
#define ImGuiKey_NavGamepadActivate ImGuiKey_GamepadFaceDown
#endif
#ifndef ImGuiKey_NavGamepadCancel
#define ImGuiKey_NavGamepadCancel ImGuiKey_GamepadFaceRight
#endif
#ifndef ImGuiKey_NavGamepadMenu
#define ImGuiKey_NavGamepadMenu ImGuiKey_GamepadFaceLeft
#endif
#ifndef ImGuiKey_NavGamepadInput
#define ImGuiKey_NavGamepadInput ImGuiKey_GamepadFaceUp
#endif Would you like me to PR something like this @ocornut ? and if so, should all properties be able to be overwritten? |
This is not the right solution, you should be able swap the buttons in the InputQueue using code similar to what I provided: |
Yeah, this is what I had originally. But here, if I understand correctly we’re basically just replacing the button press. The code in ImGui for game pad navigation is specifically looking for |
ImGuiKey_NavGamepadInput is defined to ImGuiKey_GamepadFaceLeft so if you swap _Left to something else it'll work. |
It doesn’t for some reason. None of the buttons trigger navigation. I’ll try to dig into it later.. technically I have two solutions that work, but was aiming to do it without modifying ImGui. I’ll see if I can get the example project setup with the reproduction. |
My solution doesn't modify dear imgui, and I can't comprehend how it would not work, it's a very simple thing just swapping buttons after the backend submitted them. You'll have to focus on getting this working or understanding why it doesn't. |
@dcvz Did you get to the bottom of that? I was thinking that I may understand why would attempt may be broken: if you have a function doing a single replacement and calling this function multiple times, one remap would lead to another. Note how my own does all the replacements in the same spot. Also note that since |
I have now added a runtime option But I was wondering why did you also need to swap X<>Y ? |
This PR primarily adds support for swapped AB & XY buttons (classic on Nintendo consoles)
It also disables
SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
for the__SWITCH__
platform but I'm not sure if its ok to add this check when there's no build workflow for it. Though one could likely be added using homebrew development tools. But again that's up for discussion.