controller input
This commit is contained in:
@@ -16,4 +16,5 @@ image = "0.22.0"
|
||||
collada = "0.11.0"
|
||||
serde = "1.0.97"
|
||||
serde_derive = "1.0.97"
|
||||
toml = "0.5.1"
|
||||
toml = "0.5.1"
|
||||
gilrs = "0.7.1"
|
||||
|
||||
@@ -29,7 +29,7 @@ scan_code = 32
|
||||
|
||||
[[button]]
|
||||
name = "test"
|
||||
scan_code = 20
|
||||
controller_button = "West"
|
||||
ctrl = true
|
||||
|
||||
[[axis]]
|
||||
@@ -46,6 +46,10 @@ name = "move_sideways"
|
||||
positive_button = "d"
|
||||
negative_button = "a"
|
||||
|
||||
[[axis]]
|
||||
name = "move_sideways"
|
||||
controller_axis = "LeftStickX"
|
||||
|
||||
[[axis]]
|
||||
name = "look_horizontal"
|
||||
mouse_axis = "x"
|
||||
|
||||
110
src/input.rs
110
src/input.rs
@@ -2,11 +2,15 @@ use winit::{ScanCode, ModifiersState, MouseButton, ElementState, MouseScrollDelt
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use toml;
|
||||
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use gilrs;
|
||||
use gilrs::{Gilrs, EventType};
|
||||
|
||||
use crate::config::LogConfig;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -42,6 +46,7 @@ struct InputConfigButton {
|
||||
name: String,
|
||||
scan_code: Option<u32>,
|
||||
mouse: Option<String>,
|
||||
controller_button: Option<String>,
|
||||
ctrl: Option<bool>,
|
||||
shift: Option<bool>,
|
||||
alt: Option<bool>,
|
||||
@@ -54,6 +59,7 @@ struct InputConfigAxis {
|
||||
positive_button: Option<String>,
|
||||
negative_button: Option<String>,
|
||||
mouse_axis: Option<String>,
|
||||
controller_axis: Option<String>,
|
||||
ctrl: Option<bool>,
|
||||
shift: Option<bool>,
|
||||
alt: Option<bool>,
|
||||
@@ -72,6 +78,7 @@ pub struct InputState<'a> {
|
||||
analog_wheel_state: f32,
|
||||
config: InputConfigConfig,
|
||||
log_config: &'a LogConfig,
|
||||
controller_input: Gilrs,
|
||||
}
|
||||
|
||||
impl <'a> InputState<'a> {
|
||||
@@ -81,7 +88,8 @@ impl <'a> InputState<'a> {
|
||||
let mut state = InputState { virtual_buttons: HashMap::new(), virtual_axes: HashMap::new(),
|
||||
input_events: HashSet::new(), pressed_scan_codes: HashSet::new(),
|
||||
pressed_mouse_buttons: HashSet::new(), analog_wheel_state: 0.0,
|
||||
config: config.config, mouse_delta_x: 0.0, mouse_delta_y: 0.0, log_config };
|
||||
config: config.config, mouse_delta_x: 0.0, mouse_delta_y: 0.0, log_config,
|
||||
controller_input: Gilrs::new().unwrap() };
|
||||
|
||||
config.button.iter().for_each(|bn| {
|
||||
let modifiers = ModifiersState {
|
||||
@@ -102,6 +110,10 @@ impl <'a> InputState<'a> {
|
||||
"wheeldown" => DigitalInput::Wheel(WheelInput { direction: WheelInputDirection::Down, modifiers }),
|
||||
other => DigitalInput::Mouse(MouseInput { button: MouseButton::Other(other.parse().expect(&format!("Unknown button: {:?}", other))), modifiers }),
|
||||
}
|
||||
} else if let Some(controller_button) = &bn.controller_button {
|
||||
DigitalInput::Controller(ControllerInput {
|
||||
button: string_to_button(controller_button.as_str()).expect(&format!("Unknown controller button: {}", controller_button.as_str()))
|
||||
})
|
||||
} else {
|
||||
panic!("No mouse or keyboard input for button {:?}", bn.name);
|
||||
};
|
||||
@@ -139,7 +151,10 @@ impl <'a> InputState<'a> {
|
||||
other => panic!("Axis {:?} has unknown mouse axis name {:?}!", axis_name, other),
|
||||
}
|
||||
},
|
||||
other => panic!("Axis {:?} needs either positive_button and negative_button or mouse_wheel must be set to true!", other.name)
|
||||
InputConfigAxis { controller_axis: Some(controller_axis_name), .. } => {
|
||||
AxisInput::Controller(AnalogControllerInput { axis: string_to_axis(controller_axis_name).expect(&format!("Unknown controller axis: {}", controller_axis_name)) })
|
||||
},
|
||||
other => panic!("Axis {:?} needs either positive_button and negative_button or mouse_wheel or controller_axis must be set to true!", other.name)
|
||||
};
|
||||
|
||||
if let Some(virtual_axis) = state.virtual_axes.get_mut(&axis.name) {
|
||||
@@ -269,8 +284,13 @@ impl <'a> InputState<'a> {
|
||||
AxisInput::Digital(positive_button, negative_button) => {
|
||||
self.virtual_button_to_float(positive_button) - self.virtual_button_to_float(negative_button)
|
||||
},
|
||||
AxisInput::Controller(controller_input) => {
|
||||
self.controller_input.gamepads()
|
||||
.map(|(_id, gamepad)| gamepad.value(controller_input.axis))
|
||||
.fold(0.0, fold_axis_value)
|
||||
}
|
||||
}
|
||||
}).fold(0.0, |fold, it| if f32::abs(it) > f32::abs(fold) { it } else { fold })
|
||||
}).fold(0.0, fold_axis_value)
|
||||
} else {
|
||||
assert!(false, format!("Axis {:?} not found!", axis_code));
|
||||
0.0
|
||||
@@ -289,6 +309,9 @@ impl <'a> InputState<'a> {
|
||||
},
|
||||
DigitalInput::Wheel(wheel_input) => {
|
||||
self.input_events.contains(&DigitalInputEvent::Pressed(DigitalInput::Wheel(wheel_input.clone())))
|
||||
},
|
||||
DigitalInput::Controller(controller_input) => {
|
||||
self.controller_input.gamepads().any(|(_id, gamepad)| gamepad.is_pressed(controller_input.button))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,6 +381,25 @@ impl <'a> InputState<'a> {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn frame_start(self: &mut Self) {
|
||||
while let Some(event) = self.controller_input.next_event() {
|
||||
match event.event {
|
||||
EventType::ButtonPressed(button, _) => {
|
||||
self.input_events.insert(DigitalInputEvent::Pressed(DigitalInput::Controller(ControllerInput { button })));
|
||||
},
|
||||
EventType::ButtonRepeated(_, _) => {},
|
||||
EventType::ButtonReleased(button, _) => {
|
||||
self.input_events.insert(DigitalInputEvent::Released(DigitalInput::Controller(ControllerInput { button })));
|
||||
},
|
||||
EventType::ButtonChanged(_, _, _) => {},
|
||||
EventType::AxisChanged(_, _, _) => {},
|
||||
EventType::Connected => {},
|
||||
EventType::Disconnected => {},
|
||||
EventType::Dropped => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn frame_end(self: &mut Self) {
|
||||
self.analog_wheel_state = 0.0;
|
||||
self.mouse_delta_x = 0.0;
|
||||
@@ -379,6 +421,7 @@ pub enum AxisInput {
|
||||
Wheel(ModifiersState),
|
||||
MouseMove(MouseMoveDirection, ModifiersState),
|
||||
Digital(VirtualButton, VirtualButton),
|
||||
Controller(AnalogControllerInput),
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
||||
@@ -386,6 +429,7 @@ pub enum DigitalInput {
|
||||
Keyboard(KeyboardInput),
|
||||
Wheel(WheelInput),
|
||||
Mouse(MouseInput),
|
||||
Controller(ControllerInput),
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
||||
@@ -406,6 +450,11 @@ pub struct WheelInput {
|
||||
modifiers: ModifiersState,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
||||
pub struct ControllerInput {
|
||||
button: gilrs::Button,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
||||
pub enum WheelInputDirection {
|
||||
Up,
|
||||
@@ -422,4 +471,57 @@ pub enum MouseMoveDirection {
|
||||
pub struct AnalogWheelInput {
|
||||
value: f32,
|
||||
modifiers: ModifiersState,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct AnalogControllerInput {
|
||||
axis: gilrs::Axis,
|
||||
}
|
||||
|
||||
fn fold_axis_value(fold: f32, it: f32) -> f32 {
|
||||
if f32::abs(it) > f32::abs(fold) { it } else { fold }
|
||||
}
|
||||
|
||||
fn string_to_button(button_name: &str) -> Option<gilrs::Button> {
|
||||
match button_name {
|
||||
"South" => Some(gilrs::Button::South),
|
||||
"East" => Some(gilrs::Button::East),
|
||||
"North" => Some(gilrs::Button::North),
|
||||
"West" => Some(gilrs::Button::West),
|
||||
"C" => Some(gilrs::Button::C),
|
||||
"Z" => Some(gilrs::Button::Z),
|
||||
// Triggers
|
||||
"LeftTrigger" => Some(gilrs::Button::LeftTrigger),
|
||||
"LeftTrigger2" => Some(gilrs::Button::LeftTrigger2),
|
||||
"RightTrigger" => Some(gilrs::Button::RightTrigger),
|
||||
"RightTrigger2" => Some(gilrs::Button::RightTrigger2),
|
||||
// Menu Pad
|
||||
"Select" => Some(gilrs::Button::Select),
|
||||
"Start" => Some(gilrs::Button::Start),
|
||||
"Mode" => Some(gilrs::Button::Mode),
|
||||
// Sticks
|
||||
"LeftThumb" => Some(gilrs::Button::LeftThumb),
|
||||
"RightThumb" => Some(gilrs::Button::RightThumb),
|
||||
// D-Pad
|
||||
"DPadUp" => Some(gilrs::Button::DPadUp),
|
||||
"DPadDown" => Some(gilrs::Button::DPadDown),
|
||||
"DPadLeft" => Some(gilrs::Button::DPadLeft),
|
||||
"DPadRight" => Some(gilrs::Button::DPadRight),
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn string_to_axis(axis_name: &str) -> Option<gilrs::Axis> {
|
||||
match axis_name {
|
||||
"LeftStickX" => Some(gilrs::Axis::LeftStickX),
|
||||
"LeftStickY" => Some(gilrs::Axis::LeftStickY),
|
||||
"LeftZ" => Some(gilrs::Axis::LeftZ),
|
||||
"RightStickX" => Some(gilrs::Axis::RightStickX),
|
||||
"RightStickY" => Some(gilrs::Axis::RightStickY),
|
||||
"RightZ" => Some(gilrs::Axis::RightZ),
|
||||
"DPadX" => Some(gilrs::Axis::DPadX),
|
||||
"DPadY" => Some(gilrs::Axis::DPadY),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,8 @@ impl TestGame<'_> {
|
||||
}
|
||||
|
||||
fn update(self: &mut Self, renderer: &mut VulkanRenderer) {
|
||||
self.input.frame_start();
|
||||
|
||||
let new_time = renderer.game_data.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0;
|
||||
let frame_time = new_time - renderer.game_data.push_constants.time;
|
||||
renderer.game_data.push_constants.time = new_time;
|
||||
@@ -51,6 +53,7 @@ impl TestGame<'_> {
|
||||
}
|
||||
|
||||
if self.input.button_just_pressed("test") {
|
||||
println!("test");
|
||||
self.cubes.push(renderer.add_game_object(GameObject::new(self.cube_mesh.unwrap())));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user