@@ -1209,40 +1209,76 @@ void ImGuiManager::ProcessGenericAxisEvent(GenericInputBinding negative_key, Gen
12091209 static constexpr float DEADZONE = 0 .25f ;
12101210
12111211 // Ignore diagonal analog stick input — neither axis fires when both exceed the deadzone.
1212- static float s_left_stick_x = 0 .0f , s_left_stick_y = 0 .0f ;
1213- static float s_right_stick_x = 0 .0f , s_right_stick_y = 0 .0f ;
1212+ // Also track last sent binary state per direction to avoid bursting duplicate events when
1213+ // the controller sends many axis updates in quick succession.
1214+ struct AxisState
1215+ {
1216+ float x = 0 .0f , y = 0 .0f ;
1217+ bool x_neg_active = false , x_pos_active = false ;
1218+ bool y_neg_active = false , y_pos_active = false ;
1219+ };
1220+ static AxisState s_left_stick, s_right_stick;
12141221
1215- float suppressed_value = value;
1222+ AxisState* state = nullptr ;
1223+ bool is_x_axis = false ;
12161224 if (negative_key == GenericInputBinding::LeftStickLeft)
12171225 {
1218- s_left_stick_x = value ;
1219- if ( std::abs (s_left_stick_y) > DEADZONE)
1220- suppressed_value = 0 . 0f ;
1226+ state = &s_left_stick ;
1227+ state-> x = value;
1228+ is_x_axis = true ;
12211229 }
12221230 else if (negative_key == GenericInputBinding::LeftStickUp)
12231231 {
1224- s_left_stick_y = value ;
1225- if ( std::abs (s_left_stick_x) > DEADZONE)
1226- suppressed_value = 0 . 0f ;
1232+ state = &s_left_stick ;
1233+ state-> y = value;
1234+ is_x_axis = false ;
12271235 }
12281236 else if (negative_key == GenericInputBinding::RightStickLeft)
12291237 {
1230- s_right_stick_x = value ;
1231- if ( std::abs (s_right_stick_y) > DEADZONE)
1232- suppressed_value = 0 . 0f ;
1238+ state = &s_right_stick ;
1239+ state-> x = value;
1240+ is_x_axis = true ;
12331241 }
12341242 else if (negative_key == GenericInputBinding::RightStickUp)
12351243 {
1236- s_right_stick_y = value;
1237- if (std::abs (s_right_stick_x) > DEADZONE)
1244+ state = &s_right_stick;
1245+ state->y = value;
1246+ is_x_axis = false ;
1247+ }
1248+
1249+ float suppressed_value = value;
1250+ if (state)
1251+ {
1252+ const float other = is_x_axis ? state->y : state->x ;
1253+ if (std::abs (other) > DEADZONE)
12381254 suppressed_value = 0 .0f ;
12391255 }
12401256
12411257 // Treat as binary like the D-pad: either fully pressed or released, with a deadzone.
1258+ // Only forward the event if the binary state actually changed to avoid input bursts.
1259+ bool * neg_active_ptr = state ? (is_x_axis ? &state->x_neg_active : &state->y_neg_active ) : nullptr ;
1260+ bool * pos_active_ptr = state ? (is_x_axis ? &state->x_pos_active : &state->y_pos_active ) : nullptr ;
1261+
12421262 if (negative_key != GenericInputBinding::Unknown)
1243- ProcessGenericInputEvent (negative_key, layout, (suppressed_value < -DEADZONE) ? 1 .0f : 0 .0f );
1263+ {
1264+ const bool active = suppressed_value < -DEADZONE;
1265+ if (!neg_active_ptr || active != *neg_active_ptr)
1266+ {
1267+ if (neg_active_ptr)
1268+ *neg_active_ptr = active;
1269+ ProcessGenericInputEvent (negative_key, layout, active ? 1 .0f : 0 .0f );
1270+ }
1271+ }
12441272 if (positive_key != GenericInputBinding::Unknown)
1245- ProcessGenericInputEvent (positive_key, layout, (suppressed_value > DEADZONE) ? 1 .0f : 0 .0f );
1273+ {
1274+ const bool active = suppressed_value > DEADZONE;
1275+ if (!pos_active_ptr || active != *pos_active_ptr)
1276+ {
1277+ if (pos_active_ptr)
1278+ *pos_active_ptr = active;
1279+ ProcessGenericInputEvent (positive_key, layout, active ? 1 .0f : 0 .0f );
1280+ }
1281+ }
12461282}
12471283
12481284void ImGuiManager::SwapGamepadNorthWest (bool value)
0 commit comments