From 5f512205e4467e149fe6566fa6e834998fd7cd06 Mon Sep 17 00:00:00 2001 From: abcpea Date: Sun, 11 Jan 2026 14:46:12 +1100 Subject: [PATCH 1/6] Improved deadzone implementation (sneaking now possible even with high deadzones) --- src/pc/controller/controller_sdl2.c | 43 +++++++++++++++++++---------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/pc/controller/controller_sdl2.c b/src/pc/controller/controller_sdl2.c index 373065415..411de9183 100644 --- a/src/pc/controller/controller_sdl2.c +++ b/src/pc/controller/controller_sdl2.c @@ -176,6 +176,32 @@ static inline void update_button(const int i, const bool new) { } } +static inline void update_analog_stick(s8 *stick_x, s8 *stick_y, + int16_t input_x, int16_t input_y) { + static const float FSHRT_MAX = 32768.f; + + uint32_t magnitude_sq = (uint32_t)(input_x * input_x) + (uint32_t)(input_y * input_y); + uint32_t stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP; + + if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) { + uint32_t magnitude = sqrt(magnitude_sq); + float stickDeadzoneScale = FSHRT_MAX / (FSHRT_MAX - stickDeadzoneActual); + float dir_x = (float)input_x / magnitude; + float dir_y = (float)input_y / magnitude; + float dir_sum = fabsf(dir_x) + fabsf(dir_y); + + magnitude -= stickDeadzoneActual; + magnitude *= stickDeadzoneScale; + if (dir_sum >= 1) + magnitude /= (dir_sum); + magnitude /= 0x100; + magnitude = magnitude >= 127 ? 127 : magnitude; + + *stick_x = dir_x * magnitude; + *stick_y = -dir_y * magnitude; + } +} + extern s16 gMenuMode; static void controller_sdl_read(OSContPad *pad) { if (!init_ok) { return; } @@ -305,21 +331,8 @@ static void controller_sdl_read(OSContPad *pad) { if (righty < -0x4000) pad->button |= U_CBUTTONS; if (righty > 0x4000) pad->button |= D_CBUTTONS; - uint32_t magnitude_sq = (uint32_t)(leftx * leftx) + (uint32_t)(lefty * lefty); - uint32_t stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP; - if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) { - pad->stick_x = leftx / 0x100; - int stick_y = -lefty / 0x100; - pad->stick_y = stick_y == 128 ? 127 : stick_y; - } - - magnitude_sq = (uint32_t)(rightx * rightx) + (uint32_t)(righty * righty); - stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP; - if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) { - pad->ext_stick_x = rightx / 0x100; - int stick_y = -righty / 0x100; - pad->ext_stick_y = stick_y == 128 ? 127 : stick_y; - } + update_analog_stick(&pad->stick_x, &pad->stick_y, leftx, lefty); + update_analog_stick(&pad->ext_stick_x, &pad->ext_stick_y, rightx, righty); } static void controller_sdl_rumble_play(f32 strength, f32 length) { From 9f9ec5d75424d0fa62172b172258e58d2113d253 Mon Sep 17 00:00:00 2001 From: abcpea Date: Tue, 13 Jan 2026 15:45:25 +1100 Subject: [PATCH 2/6] Reworked deadzone algorithm --- src/pc/controller/controller_sdl2.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/pc/controller/controller_sdl2.c b/src/pc/controller/controller_sdl2.c index 411de9183..d5fff2569 100644 --- a/src/pc/controller/controller_sdl2.c +++ b/src/pc/controller/controller_sdl2.c @@ -176,25 +176,24 @@ static inline void update_button(const int i, const bool new) { } } -static inline void update_analog_stick(s8 *stick_x, s8 *stick_y, +static inline void update_analog_stick(s8 *stick_x, s8 *stick_y, int16_t input_x, int16_t input_y) { static const float FSHRT_MAX = 32768.f; - + uint32_t magnitude_sq = (uint32_t)(input_x * input_x) + (uint32_t)(input_y * input_y); uint32_t stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP; if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) { - uint32_t magnitude = sqrt(magnitude_sq); - float stickDeadzoneScale = FSHRT_MAX / (FSHRT_MAX - stickDeadzoneActual); + float magnitude = sqrt(magnitude_sq); float dir_x = (float)input_x / magnitude; float dir_y = (float)input_y / magnitude; - float dir_sum = fabsf(dir_x) + fabsf(dir_y); + float scale = 1.f / (fabs(dir_x) >= fabs(dir_y) ? fabs(dir_x) : fabs(dir_y)); + float deadzone = stickDeadzoneActual / (FSHRT_MAX); - magnitude -= stickDeadzoneActual; - magnitude *= stickDeadzoneScale; - if (dir_sum >= 1) - magnitude /= (dir_sum); - magnitude /= 0x100; + magnitude /= FSHRT_MAX; + magnitude = scale * (magnitude - deadzone); + magnitude /= scale - deadzone; + magnitude *= 127; magnitude = magnitude >= 127 ? 127 : magnitude; *stick_x = dir_x * magnitude; From 5b7585a3d8b598eb101d64348046fea7535b1363 Mon Sep 17 00:00:00 2001 From: abcpea Date: Sun, 18 Jan 2026 13:21:30 +1100 Subject: [PATCH 3/6] Faster/Stronger/Better --- src/pc/controller/controller_sdl2.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/pc/controller/controller_sdl2.c b/src/pc/controller/controller_sdl2.c index d5fff2569..c12ed9a07 100644 --- a/src/pc/controller/controller_sdl2.c +++ b/src/pc/controller/controller_sdl2.c @@ -180,21 +180,20 @@ static inline void update_analog_stick(s8 *stick_x, s8 *stick_y, int16_t input_x, int16_t input_y) { static const float FSHRT_MAX = 32768.f; - uint32_t magnitude_sq = (uint32_t)(input_x * input_x) + (uint32_t)(input_y * input_y); - uint32_t stickDeadzoneActual = configStickDeadzone * DEADZONE_STEP; + float magnitude_sq = (float)(input_x * input_x) + (float)(input_y * input_y); + float deadzone = configStickDeadzone * DEADZONE_STEP; - if (magnitude_sq > (uint32_t)(stickDeadzoneActual * stickDeadzoneActual)) { + if (magnitude_sq > (deadzone * deadzone)) { float magnitude = sqrt(magnitude_sq); float dir_x = (float)input_x / magnitude; float dir_y = (float)input_y / magnitude; - float scale = 1.f / (fabs(dir_x) >= fabs(dir_y) ? fabs(dir_x) : fabs(dir_y)); - float deadzone = stickDeadzoneActual / (FSHRT_MAX); + float scale = 1.f / fmaxf(fabsf(dir_x), fabsf(dir_y)); + float max_magnitude = FSHRT_MAX * scale; - magnitude /= FSHRT_MAX; - magnitude = scale * (magnitude - deadzone); - magnitude /= scale - deadzone; - magnitude *= 127; - magnitude = magnitude >= 127 ? 127 : magnitude; + magnitude -= deadzone; + magnitude *= max_magnitude / (max_magnitude - deadzone); + magnitude /= 0x100; + magnitude = fminf(magnitude, scale * 127.f); *stick_x = dir_x * magnitude; *stick_y = -dir_y * magnitude; From 33274b8f8f62ee2b81b526a3961df72ae06bc708 Mon Sep 17 00:00:00 2001 From: abcpea Date: Fri, 13 Feb 2026 21:05:43 +1100 Subject: [PATCH 4/6] minor renaming --- src/pc/controller/controller_sdl2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pc/controller/controller_sdl2.c b/src/pc/controller/controller_sdl2.c index c12ed9a07..40b2d09a2 100644 --- a/src/pc/controller/controller_sdl2.c +++ b/src/pc/controller/controller_sdl2.c @@ -178,7 +178,7 @@ static inline void update_button(const int i, const bool new) { static inline void update_analog_stick(s8 *stick_x, s8 *stick_y, int16_t input_x, int16_t input_y) { - static const float FSHRT_MAX = 32768.f; + static const float INPUT_ABS_MAX = 0x8000; float magnitude_sq = (float)(input_x * input_x) + (float)(input_y * input_y); float deadzone = configStickDeadzone * DEADZONE_STEP; @@ -188,7 +188,7 @@ static inline void update_analog_stick(s8 *stick_x, s8 *stick_y, float dir_x = (float)input_x / magnitude; float dir_y = (float)input_y / magnitude; float scale = 1.f / fmaxf(fabsf(dir_x), fabsf(dir_y)); - float max_magnitude = FSHRT_MAX * scale; + float max_magnitude = INPUT_ABS_MAX * scale; magnitude -= deadzone; magnitude *= max_magnitude / (max_magnitude - deadzone); From fa5ca5a0fd5732506cb4c23f02a3936dc7e3f041 Mon Sep 17 00:00:00 2001 From: abcpea Date: Sun, 29 Mar 2026 15:10:42 +1100 Subject: [PATCH 5/6] Requested change --- src/pc/controller/controller_sdl2.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pc/controller/controller_sdl2.c b/src/pc/controller/controller_sdl2.c index 40b2d09a2..9ed46f263 100644 --- a/src/pc/controller/controller_sdl2.c +++ b/src/pc/controller/controller_sdl2.c @@ -178,8 +178,6 @@ static inline void update_button(const int i, const bool new) { static inline void update_analog_stick(s8 *stick_x, s8 *stick_y, int16_t input_x, int16_t input_y) { - static const float INPUT_ABS_MAX = 0x8000; - float magnitude_sq = (float)(input_x * input_x) + (float)(input_y * input_y); float deadzone = configStickDeadzone * DEADZONE_STEP; @@ -188,7 +186,7 @@ static inline void update_analog_stick(s8 *stick_x, s8 *stick_y, float dir_x = (float)input_x / magnitude; float dir_y = (float)input_y / magnitude; float scale = 1.f / fmaxf(fabsf(dir_x), fabsf(dir_y)); - float max_magnitude = INPUT_ABS_MAX * scale; + float max_magnitude = 0x8000 * scale; magnitude -= deadzone; magnitude *= max_magnitude / (max_magnitude - deadzone); From b9b307863bea5c35e3da4e97afe378882930b188 Mon Sep 17 00:00:00 2001 From: abcpea Date: Mon, 30 Mar 2026 17:05:08 +1100 Subject: [PATCH 6/6] use float instead of double sqrt() --- src/pc/controller/controller_sdl2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pc/controller/controller_sdl2.c b/src/pc/controller/controller_sdl2.c index 9ed46f263..9ed2e02fd 100644 --- a/src/pc/controller/controller_sdl2.c +++ b/src/pc/controller/controller_sdl2.c @@ -182,7 +182,7 @@ static inline void update_analog_stick(s8 *stick_x, s8 *stick_y, float deadzone = configStickDeadzone * DEADZONE_STEP; if (magnitude_sq > (deadzone * deadzone)) { - float magnitude = sqrt(magnitude_sq); + float magnitude = sqrtf(magnitude_sq); float dir_x = (float)input_x / magnitude; float dir_y = (float)input_y / magnitude; float scale = 1.f / fmaxf(fabsf(dir_x), fabsf(dir_y));