diff --git a/assets/game.yaml b/assets/game.yaml index 6310e660b8..e9821e2189 100644 --- a/assets/game.yaml +++ b/assets/game.yaml @@ -44,6 +44,11 @@ default_settings: left: !AxisNegative LeftStickX down: !AxisNegative LeftStickY right: !AxisPositive LeftStickX + movement_alt: + up: !Button DPadUp + left: !Button DPadLeft + down: !Button DPadDown + right: !Button DPadRight jump: !Button South grab: !Button East shoot: !Button West diff --git a/assets/locales/en-US/controls.ftl b/assets/locales/en-US/controls.ftl index 21aec11ca2..82d0929fc8 100644 --- a/assets/locales/en-US/controls.ftl +++ b/assets/locales/en-US/controls.ftl @@ -2,6 +2,10 @@ move-up = Move Up move-down = Move Down move-left = Move Left move-right = Move Right +move-up-alt = Move Up Alt +move-down-alt = Move Down Alt +move-left-alt = Move Left Alt +move-right-alt = Move Right Alt jump = Jump grab-drop = Grab / Drop shoot = Shoot diff --git a/src/input.rs b/src/input.rs index c41153b249..e2e46c2032 100644 --- a/src/input.rs +++ b/src/input.rs @@ -367,16 +367,42 @@ impl<'a> } } - if let Some(left) = get_input_value(&mapping.movement.left, source) { + // helper for merging two inputs (like dpad + joystick for example) allowing multiple bindings + // for same control + let merge_inputs = |input1: &InputKind, input2: &InputKind| -> Option { + let mut out: Option = None; + if let Some(value1) = get_input_value(input1, source) { + out = Some(value1.abs()); + } + if let Some(value2) = get_input_value(input2, source) { + match out { + Some(prev) if prev == 0.0 => { + // If first input is 0.0, override with second input + out = Some(value2.abs()); + } + None => { + // No input from first, use second + out = Some(value2.abs()); + } + // If first input is non-zero input, use it and ignore second. + Some(_) => {} + } + } + + out + }; + + if let Some(left) = merge_inputs(&mapping.movement.left, &mapping.movement_alt.left) { control.left = left.abs(); } - if let Some(right) = get_input_value(&mapping.movement.right, source) { + if let Some(right) = merge_inputs(&mapping.movement.right, &mapping.movement_alt.right) + { control.right = right.abs(); } - if let Some(up) = get_input_value(&mapping.movement.up, source) { + if let Some(up) = merge_inputs(&mapping.movement.up, &mapping.movement_alt.up) { control.up = up.abs(); } - if let Some(down) = get_input_value(&mapping.movement.down, source) { + if let Some(down) = merge_inputs(&mapping.movement.down, &mapping.movement_alt.down) { control.down = down.abs(); } }; diff --git a/src/settings.rs b/src/settings.rs index 7158aa7722..bfc6cd2ac7 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -83,6 +83,7 @@ impl PlayerControlMapping { #[repr(C)] pub struct PlayerControlSetting { pub movement: VirtualDPad, + pub movement_alt: VirtualDPad, pub pause: InputKind, pub jump: InputKind, pub grab: InputKind, diff --git a/src/ui/main_menu/settings/controls.rs b/src/ui/main_menu/settings/controls.rs index 00e3cb9446..2850880f74 100644 --- a/src/ui/main_menu/settings/controls.rs +++ b/src/ui/main_menu/settings/controls.rs @@ -71,6 +71,38 @@ pub(super) fn widget( &mut mapping.gamepad.movement.right, ], ), + ( + localization.get("move-up-alt"), + [ + &mut mapping.keyboard1.movement_alt.up, + &mut mapping.keyboard2.movement_alt.up, + &mut mapping.gamepad.movement_alt.up, + ], + ), + ( + localization.get("move-down-alt"), + [ + &mut mapping.keyboard1.movement_alt.down, + &mut mapping.keyboard2.movement_alt.down, + &mut mapping.gamepad.movement_alt.down, + ], + ), + ( + localization.get("move-left-alt"), + [ + &mut mapping.keyboard1.movement_alt.left, + &mut mapping.keyboard2.movement_alt.left, + &mut mapping.gamepad.movement_alt.left, + ], + ), + ( + localization.get("move-right-alt"), + [ + &mut mapping.keyboard1.movement_alt.right, + &mut mapping.keyboard2.movement_alt.right, + &mut mapping.gamepad.movement_alt.right, + ], + ), ( localization.get("jump"), [