controller input
This commit is contained in:
@@ -17,3 +17,4 @@ collada = "0.11.0"
|
|||||||
serde = "1.0.97"
|
serde = "1.0.97"
|
||||||
serde_derive = "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]]
|
[[button]]
|
||||||
name = "test"
|
name = "test"
|
||||||
scan_code = 20
|
controller_button = "West"
|
||||||
ctrl = true
|
ctrl = true
|
||||||
|
|
||||||
[[axis]]
|
[[axis]]
|
||||||
@@ -46,6 +46,10 @@ name = "move_sideways"
|
|||||||
positive_button = "d"
|
positive_button = "d"
|
||||||
negative_button = "a"
|
negative_button = "a"
|
||||||
|
|
||||||
|
[[axis]]
|
||||||
|
name = "move_sideways"
|
||||||
|
controller_axis = "LeftStickX"
|
||||||
|
|
||||||
[[axis]]
|
[[axis]]
|
||||||
name = "look_horizontal"
|
name = "look_horizontal"
|
||||||
mouse_axis = "x"
|
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::collections::{HashMap, HashSet};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
use toml;
|
use toml;
|
||||||
|
|
||||||
use serde_derive::{Serialize, Deserialize};
|
use serde_derive::{Serialize, Deserialize};
|
||||||
use std::iter::FromIterator;
|
|
||||||
|
use gilrs;
|
||||||
|
use gilrs::{Gilrs, EventType};
|
||||||
|
|
||||||
use crate::config::LogConfig;
|
use crate::config::LogConfig;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -42,6 +46,7 @@ struct InputConfigButton {
|
|||||||
name: String,
|
name: String,
|
||||||
scan_code: Option<u32>,
|
scan_code: Option<u32>,
|
||||||
mouse: Option<String>,
|
mouse: Option<String>,
|
||||||
|
controller_button: Option<String>,
|
||||||
ctrl: Option<bool>,
|
ctrl: Option<bool>,
|
||||||
shift: Option<bool>,
|
shift: Option<bool>,
|
||||||
alt: Option<bool>,
|
alt: Option<bool>,
|
||||||
@@ -54,6 +59,7 @@ struct InputConfigAxis {
|
|||||||
positive_button: Option<String>,
|
positive_button: Option<String>,
|
||||||
negative_button: Option<String>,
|
negative_button: Option<String>,
|
||||||
mouse_axis: Option<String>,
|
mouse_axis: Option<String>,
|
||||||
|
controller_axis: Option<String>,
|
||||||
ctrl: Option<bool>,
|
ctrl: Option<bool>,
|
||||||
shift: Option<bool>,
|
shift: Option<bool>,
|
||||||
alt: Option<bool>,
|
alt: Option<bool>,
|
||||||
@@ -72,6 +78,7 @@ pub struct InputState<'a> {
|
|||||||
analog_wheel_state: f32,
|
analog_wheel_state: f32,
|
||||||
config: InputConfigConfig,
|
config: InputConfigConfig,
|
||||||
log_config: &'a LogConfig,
|
log_config: &'a LogConfig,
|
||||||
|
controller_input: Gilrs,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a> InputState<'a> {
|
impl <'a> InputState<'a> {
|
||||||
@@ -81,7 +88,8 @@ impl <'a> InputState<'a> {
|
|||||||
let mut state = InputState { virtual_buttons: HashMap::new(), virtual_axes: HashMap::new(),
|
let mut state = InputState { virtual_buttons: HashMap::new(), virtual_axes: HashMap::new(),
|
||||||
input_events: HashSet::new(), pressed_scan_codes: HashSet::new(),
|
input_events: HashSet::new(), pressed_scan_codes: HashSet::new(),
|
||||||
pressed_mouse_buttons: HashSet::new(), analog_wheel_state: 0.0,
|
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| {
|
config.button.iter().for_each(|bn| {
|
||||||
let modifiers = ModifiersState {
|
let modifiers = ModifiersState {
|
||||||
@@ -102,6 +110,10 @@ impl <'a> InputState<'a> {
|
|||||||
"wheeldown" => DigitalInput::Wheel(WheelInput { direction: WheelInputDirection::Down, modifiers }),
|
"wheeldown" => DigitalInput::Wheel(WheelInput { direction: WheelInputDirection::Down, modifiers }),
|
||||||
other => DigitalInput::Mouse(MouseInput { button: MouseButton::Other(other.parse().expect(&format!("Unknown button: {:?}", other))), 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 {
|
} else {
|
||||||
panic!("No mouse or keyboard input for button {:?}", bn.name);
|
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 {:?} 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) {
|
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) => {
|
AxisInput::Digital(positive_button, negative_button) => {
|
||||||
self.virtual_button_to_float(positive_button) - self.virtual_button_to_float(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 {
|
} else {
|
||||||
assert!(false, format!("Axis {:?} not found!", axis_code));
|
assert!(false, format!("Axis {:?} not found!", axis_code));
|
||||||
0.0
|
0.0
|
||||||
@@ -289,6 +309,9 @@ impl <'a> InputState<'a> {
|
|||||||
},
|
},
|
||||||
DigitalInput::Wheel(wheel_input) => {
|
DigitalInput::Wheel(wheel_input) => {
|
||||||
self.input_events.contains(&DigitalInputEvent::Pressed(DigitalInput::Wheel(wheel_input.clone())))
|
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) {
|
pub fn frame_end(self: &mut Self) {
|
||||||
self.analog_wheel_state = 0.0;
|
self.analog_wheel_state = 0.0;
|
||||||
self.mouse_delta_x = 0.0;
|
self.mouse_delta_x = 0.0;
|
||||||
@@ -379,6 +421,7 @@ pub enum AxisInput {
|
|||||||
Wheel(ModifiersState),
|
Wheel(ModifiersState),
|
||||||
MouseMove(MouseMoveDirection, ModifiersState),
|
MouseMove(MouseMoveDirection, ModifiersState),
|
||||||
Digital(VirtualButton, VirtualButton),
|
Digital(VirtualButton, VirtualButton),
|
||||||
|
Controller(AnalogControllerInput),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
||||||
@@ -386,6 +429,7 @@ pub enum DigitalInput {
|
|||||||
Keyboard(KeyboardInput),
|
Keyboard(KeyboardInput),
|
||||||
Wheel(WheelInput),
|
Wheel(WheelInput),
|
||||||
Mouse(MouseInput),
|
Mouse(MouseInput),
|
||||||
|
Controller(ControllerInput),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
||||||
@@ -406,6 +450,11 @@ pub struct WheelInput {
|
|||||||
modifiers: ModifiersState,
|
modifiers: ModifiersState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
||||||
|
pub struct ControllerInput {
|
||||||
|
button: gilrs::Button,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
|
||||||
pub enum WheelInputDirection {
|
pub enum WheelInputDirection {
|
||||||
Up,
|
Up,
|
||||||
@@ -423,3 +472,56 @@ pub struct AnalogWheelInput {
|
|||||||
value: f32,
|
value: f32,
|
||||||
modifiers: ModifiersState,
|
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) {
|
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 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;
|
let frame_time = new_time - renderer.game_data.push_constants.time;
|
||||||
renderer.game_data.push_constants.time = new_time;
|
renderer.game_data.push_constants.time = new_time;
|
||||||
@@ -51,6 +53,7 @@ impl TestGame<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.input.button_just_pressed("test") {
|
if self.input.button_just_pressed("test") {
|
||||||
|
println!("test");
|
||||||
self.cubes.push(renderer.add_game_object(GameObject::new(self.cube_mesh.unwrap())));
|
self.cubes.push(renderer.add_game_object(GameObject::new(self.cube_mesh.unwrap())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user