controller input

This commit is contained in:
2019-07-31 19:13:59 +02:00
parent 7dff6354b9
commit 7fe3d34d79
4 changed files with 116 additions and 6 deletions

View File

@@ -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"

View File

@@ -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"

View File

@@ -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,
}
}

View File

@@ -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())));
}