implemented code rabbits suggestions

- Preserved NSO GameCube analog triggers.
  - Made modal closure and Escape cancel every rebind kind.
  - Deduced the native button array size; <array> already existed.
  - Centralized axis/sign decoding.
  - Kept threshold updates live, saving only when editing ends.
This commit is contained in:
GalaxisBeast
2026-09-05 13:59:25 -04:00
parent 5381c4ecf2
commit 88643d6884
5 changed files with 21 additions and 9 deletions
+2
View File
@@ -181,6 +181,8 @@ constexpr u32 PADEncodeAxisButton(u32 axis, bool negative, u32 threshold = 50) {
}
constexpr bool PADIsAxisButton(u32 binding) { return (binding & 0xffff0000u) == 0x10000u; }
constexpr u32 PADAxisButtonThreshold(u32 binding) { return (binding >> 8) & 0xffu; }
constexpr u32 PADAxisButtonAxis(u32 binding) { return binding & 0x7fu; }
constexpr bool PADAxisButtonNegative(u32 binding) { return (binding & 0x80u) != 0; }
constexpr u32 PADAxisButtonIdentity(u32 binding) {
return PADIsAxisButton(binding) ? (binding & ~0xff00u) : binding;
}
+5 -3
View File
@@ -321,11 +321,11 @@ std::array<bool, PAD_CHANMAX> g_suppressRightTrigger{};
bool is_mouse_scancode(const s32 scancode) { return scancode < PAD_KEY_INVALID; }
bool is_native_binding_pressed(SDL_Gamepad* gamepad, u32 binding) {
if (PADIsAxisButton(binding)) {
const u32 axis = binding & 0x7fu;
const u32 axis = PADAxisButtonAxis(binding);
const u32 threshold = PADAxisButtonThreshold(binding);
if (axis >= SDL_GAMEPAD_AXIS_COUNT || threshold < 1 || threshold > 100) return false;
int value = SDL_GetGamepadAxis(gamepad, static_cast<SDL_GamepadAxis>(axis));
if ((binding & 0x80u) != 0) value = -value;
if (PADAxisButtonNegative(binding)) value = -value;
return value > 0 && value * 100 >= static_cast<int>(threshold) * 32767;
}
return binding < SDL_GAMEPAD_BUTTON_COUNT &&
@@ -962,7 +962,9 @@ u32 PADRead(PADStatus* status) {
// An explicit button binding must drive both, otherwise the original
// L2/R2 axis still activates L/R even when it was rebound to L1/R1.
// Real GC pads retain independent analog travel and end-stop clicks.
if (!controller->m_isGameCube) {
if (!(controller->m_isGameCube ||
(SDL_GetGamepadType(controller->m_controller) == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO &&
controller->m_pid == 0x2073))) {
if (leftTriggerSet) tl = (status[i].button & PAD_TRIGGER_L) != 0 ? 32767 : 0;
if (rightTriggerSet) tr = (status[i].button & PAD_TRIGGER_R) != 0 ? 32767 : 0;
}
+2 -2
View File
@@ -48,7 +48,7 @@ struct NativeButtonItem {
uint32_t nativeButton;
};
inline constexpr std::array<NativeButtonItem, SDL_GAMEPAD_BUTTON_COUNT + 12> kNativeButtons = {{
inline constexpr auto kNativeButtons = std::to_array<NativeButtonItem>({
{"disabled", "Unmapped", PAD_NATIVE_BUTTON_DISABLED},
{"left_trigger", "Left trigger (LT / L2)", PADEncodeAxisButton(SDL_GAMEPAD_AXIS_LEFT_TRIGGER, false)},
{"right_trigger", "Right trigger (RT / R2)", PADEncodeAxisButton(SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, false)},
@@ -87,7 +87,7 @@ inline constexpr std::array<NativeButtonItem, SDL_GAMEPAD_BUTTON_COUNT + 12> kNa
{"misc4", "Misc 4 / GC R click", SDL_GAMEPAD_BUTTON_MISC4},
{"misc5", "Misc 5", SDL_GAMEPAD_BUTTON_MISC5},
{"misc6", "Misc 6", SDL_GAMEPAD_BUTTON_MISC6},
}};
});
inline std::string TrimToken(std::string_view token) {
const size_t begin = token.find_first_not_of(" \t");
+2 -2
View File
@@ -95,8 +95,8 @@ double ReadInput(SDL_Gamepad* gamepad, const std::string& name) {
// here does not have to use Dolphin vocabulary.
if (const auto* native = ControllerNames::FindNativeButton(name)) {
if (PADIsAxisButton(native->nativeButton)) {
const auto axis = static_cast<SDL_GamepadAxis>(native->nativeButton & 0x7fu);
const double sign = (native->nativeButton & 0x80u) != 0 ? -1.0 : 1.0;
const auto axis = static_cast<SDL_GamepadAxis>(PADAxisButtonAxis(native->nativeButton));
const double sign = PADAxisButtonNegative(native->nativeButton) ? -1.0 : 1.0;
return std::clamp(SDL_GetGamepadAxis(gamepad, axis) / 32767.0 * sign, 0.0, 1.0);
}
if (native->nativeButton < SDL_GAMEPAD_BUTTON_COUNT) {
+10 -2
View File
@@ -509,13 +509,16 @@ void DrawRebindPrompt() {
ImGui::OpenPopup("Rebind input");
g_rebind.openPopup = false;
}
if (!ImGui::BeginPopupModal("Rebind input", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) return;
if (!ImGui::BeginPopupModal("Rebind input", &g_rebind.active, ImGuiWindowFlags_AlwaysAutoResize)) {
g_rebind.active = false;
return;
}
if (g_rebind.active) {
ImGui::Text("Rebind: %s", g_rebind.label.c_str());
ImGui::TextUnformatted(g_rebind.kind == RebindKind::Controller
? "Press a controller button, pull a trigger, or move a stick."
: "Press a keyboard key or click a mouse button.");
ImGui::TextUnformatted("Release any held input first. F10 is reserved for settings.");
ImGui::TextUnformatted("Release any held input first. Escape cancels. F10 is reserved for settings.");
const float remaining = std::chrono::duration<float>(g_rebind.deadline - Clock::now()).count();
ImGui::Text("Unmapped in %d seconds", std::max(0, static_cast<int>(std::ceil(remaining))));
if (remaining <= 0.0f) {
@@ -867,6 +870,8 @@ void DrawControllerSettings() {
};
if (secondary) PADSetAltButtonMapping(selectedGamePort, updated);
else PADSetButtonMapping(selectedGamePort, updated);
}
if (ImGui::IsItemDeactivatedAfterEdit()) {
writeBinding(i, mappingIt->nativeButton,
altIt != nullptr ? altIt->nativeButton : PAD_NATIVE_BUTTON_INVALID);
PADSerializeMappings();
@@ -1306,6 +1311,9 @@ void HandleEvents(const AuroraEvent* events) noexcept {
continue;
}
controller_mapping_wizard::HandleSdlEvent(ev->sdl);
if (g_rebind.active && IsToggleKey(ev->sdl, SDL_SCANCODE_ESCAPE)) {
g_rebind.active = false;
}
if (!g_rebind.active && IsToggleKey(ev->sdl, SDL_SCANCODE_F10)) {
SetTopBarVisible(!g_topBarVisible);
}