Detect diagonals better on controllers

This commit is contained in:
2026-05-21 23:03:15 -04:00
parent 5fd1957d74
commit 6e36254203
2 changed files with 132 additions and 42 deletions
+34 -23
View File
@@ -52,12 +52,28 @@ pub trait Mappings {
fn use_default_mappings(&mut self);
}
#[derive(Clone, Copy, Serialize, Deserialize)]
pub struct AxisMapping {
pub neg: VBKey,
pub pos: VBKey,
pub pair: Option<Code>,
}
impl Default for AxisMapping {
fn default() -> Self {
Self {
neg: VBKey::empty(),
pos: VBKey::empty(),
pair: None,
}
}
}
#[derive(Serialize, Deserialize)]
pub struct GamepadMapping {
buttons: HashMap<Code, VBKey>,
axes: HashMap<Code, (VBKey, VBKey)>,
axes: HashMap<Code, AxisMapping>,
default_buttons: HashMap<Code, VBKey>,
default_axes: HashMap<Code, (VBKey, VBKey)>,
default_axes: HashMap<Code, AxisMapping>,
}
impl GamepadMapping {
@@ -78,7 +94,8 @@ impl GamepadMapping {
let mut default_axes = HashMap::new();
let mut default_axis = |axis: Axis, neg: VBKey, pos: VBKey| {
if let Some(code) = gamepad.axis_code(axis) {
default_axes.insert(code, (neg, pos));
let pair = axis.second_axis().and_then(|a| gamepad.axis_code(a));
default_axes.insert(code, AxisMapping { neg, pos, pair });
}
};
default_axis(Axis::LeftStickX, VBKey::LL, VBKey::LR);
@@ -102,19 +119,13 @@ impl GamepadMapping {
}
pub fn add_axis_neg_mapping(&mut self, key: VBKey, code: Code) {
let entry = self
.axes
.entry(code)
.or_insert((VBKey::empty(), VBKey::empty()));
entry.0 = entry.0.union(key);
let entry = self.axes.entry(code).or_default();
entry.neg = entry.neg.union(key);
}
pub fn add_axis_pos_mapping(&mut self, key: VBKey, code: Code) {
let entry = self
.axes
.entry(code)
.or_insert((VBKey::empty(), VBKey::empty()));
entry.1 = entry.1.union(key);
let entry = self.axes.entry(code).or_default();
entry.pos = entry.pos.union(key);
}
fn save_mappings(&self) -> PersistedGamepadMapping {
@@ -145,11 +156,11 @@ impl GamepadMapping {
impl Mappings for GamepadMapping {
fn mapping_names(&self) -> HashMap<VBKey, Vec<String>> {
let mut results: HashMap<VBKey, Vec<String>> = HashMap::new();
for (axis, (left_keys, right_keys)) in &self.axes {
for key in left_keys.iter() {
for (axis, mapping) in &self.axes {
for key in mapping.neg.iter() {
results.entry(key).or_default().push(format!("-{axis}"));
}
for key in right_keys.iter() {
for key in mapping.pos.iter() {
results.entry(key).or_default().push(format!("+{axis}"));
}
}
@@ -162,10 +173,10 @@ impl Mappings for GamepadMapping {
}
fn clear_mappings(&mut self, key: VBKey) {
self.axes.retain(|_, (left, right)| {
*left = left.difference(key);
*right = right.difference(key);
!(left.is_empty() && right.is_empty())
self.axes.retain(|_, mapping| {
mapping.neg = mapping.neg.difference(key);
mapping.pos = mapping.pos.difference(key);
!(mapping.neg.is_empty() && mapping.pos.is_empty())
});
self.buttons.retain(|_, keys| {
*keys = keys.difference(key);
@@ -200,7 +211,7 @@ impl InputMapping {
mappings.buttons.get(code).copied()
}
pub fn map_axis(&self, id: &GamepadId, code: &Code) -> Option<(VBKey, VBKey)> {
pub fn map_axis(&self, id: &GamepadId, code: &Code) -> Option<AxisMapping> {
let mappings = self.gamepads.get(id)?.read().unwrap();
mappings.axes.get(code).copied()
}
@@ -459,9 +470,9 @@ struct PersistedKeyboardMapping {
#[derive(Serialize, Deserialize)]
struct PersistedGamepadMapping {
buttons: Vec<(Code, VBKey)>,
axes: Vec<(Code, (VBKey, VBKey))>,
axes: Vec<(Code, AxisMapping)>,
default_buttons: Vec<(Code, VBKey)>,
default_axes: Vec<(Code, (VBKey, VBKey))>,
default_axes: Vec<(Code, AxisMapping)>,
}
#[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]