From 3ec4f59f58951e535c1e28906c7bdb8d00d68851 Mon Sep 17 00:00:00 2001 From: Till Date: Sat, 27 Jul 2019 19:26:11 +0200 Subject: [PATCH] analog wheel input --- config/input.toml | 15 ++---- config/log.toml | 2 +- src/input.rs | 117 +++++++++++++++++++++++++++++++++------------- src/main.rs | 2 +- 4 files changed, 91 insertions(+), 45 deletions(-) diff --git a/config/input.toml b/config/input.toml index c012252..2ea6cfd 100644 --- a/config/input.toml +++ b/config/input.toml @@ -2,14 +2,6 @@ name = "QUIT" scan_code = 1 -[[button]] -name = "FORWARD" -mouse = "WheelUp" - -[[button]] -name = "BACKWARD" -mouse = "WheelDown" - [[button]] name = "RELOAD_SHADERS" scan_code = 19 @@ -17,5 +9,8 @@ ctrl = true [[axis]] name = "FORWARD_AXIS" -positive_button = "FORWARD" -negative_button = "BACKWARD" \ No newline at end of file +mouse_wheel = true +ctrl = true + +[config] +line_height_px = 16 \ No newline at end of file diff --git a/config/log.toml b/config/log.toml index 6215a06..77f557f 100644 --- a/config/log.toml +++ b/config/log.toml @@ -1 +1 @@ -input = true \ No newline at end of file +input = false \ No newline at end of file diff --git a/src/input.rs b/src/input.rs index 8c321a2..b8af56e 100644 --- a/src/input.rs +++ b/src/input.rs @@ -18,15 +18,6 @@ pub struct VirtualAxis { pub axis_inputs: Vec } -#[derive(Debug)] -pub struct InputState { - pub virtual_buttons: HashMap, - pub virtual_axes: HashMap, - input_events: HashSet, - pressed_scan_codes: HashSet, - pressed_mouse_buttons: HashSet, -} - #[derive(Debug, PartialEq, Eq, Hash)] pub enum DigitalInputEvent { Pressed(DigitalInput), @@ -35,10 +26,16 @@ pub enum DigitalInputEvent { #[derive(Debug, Serialize, Deserialize)] struct InputConfig { + config: InputConfigConfig, button: Vec, axis: Vec, } +#[derive(Debug, Serialize, Deserialize)] +struct InputConfigConfig { + line_height_px: f32, +} + #[derive(Debug, Serialize, Deserialize)] struct InputConfigButton { name: String, @@ -53,17 +50,35 @@ struct InputConfigButton { #[derive(Debug, Serialize, Deserialize)] struct InputConfigAxis { name: String, - positive_button: String, - negative_button: String, + positive_button: Option, + negative_button: Option, + mouse_wheel: Option, + ctrl: Option, + shift: Option, + alt: Option, + logo: Option, +} + +#[derive(Debug)] +pub struct InputState { + pub virtual_buttons: HashMap, + pub virtual_axes: HashMap, + input_events: HashSet, + pressed_scan_codes: HashSet, + pressed_mouse_buttons: HashSet, + analog_wheel_state: f32, + config: InputConfigConfig, } impl InputState { pub fn new(toml_path: &str) -> InputState { - 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() }; - let config: InputConfig = toml::from_slice(&fs::read(toml_path).expect("Failed to read input config!")).expect("Failed to parse input config!"); + 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 }; + config.button.iter().for_each(|bn| { let modifiers = ModifiersState { shift: bn.shift.is_some(), @@ -95,10 +110,28 @@ impl InputState { }); config.axis.iter().for_each(|a| { - let positive_button = state.virtual_buttons.get(&a.positive_button).expect(&format!("Button {:?} of axis {:?} not found!", a.positive_button, a.name)).clone(); - let negative_button = state.virtual_buttons.get(&a.negative_button).expect(&format!("Button {:?} of axis {:?} not found!", a.positive_button, a.name)).clone(); + let axis_input = match a { + InputConfigAxis { positive_button: Some(pos_button_name), negative_button: Some(neg_button_name), .. } => { + let positive_button = state.virtual_buttons.get(pos_button_name) + .expect(&format!("Button {:?} of axis {:?} not found!", a.positive_button, a.name)) + .clone(); + let negative_button = state.virtual_buttons.get(neg_button_name) + .expect(&format!("Button {:?} of axis {:?} not found!", a.positive_button, a.name)) + .clone(); - let axis_input = AxisInput::Digital(positive_button, negative_button); + AxisInput::Digital(positive_button, negative_button) + }, + InputConfigAxis { mouse_wheel: Some(true), .. } => { + let modifiers = ModifiersState { + shift: a.shift.is_some(), + ctrl: a.ctrl.is_some(), + alt: a.alt.is_some(), + logo: a.logo.is_some() + }; + AxisInput::Wheel(modifiers) + }, + other => panic!("Axis {:?} needs either positive_button and negative_button or mouse_wheel must be set to true!", other.name) + }; if let Some(virtual_axis) = state.virtual_axes.get_mut(&a.name) { virtual_axis.axis_inputs.push(axis_input); @@ -162,7 +195,7 @@ impl InputState { if let Some(axis) = self.virtual_axes.get(axis_code) { axis.axis_inputs.iter().fold(0.0, |fold, item| { let val = match item { - AxisInput::Analog(_) => 0.0, //TODO + AxisInput::Wheel(modifiers) => if self.modifiers_are_pressed(*modifiers) { self.analog_wheel_state } else { 0.0 }, AxisInput::Digital(positive_button, negative_button) => self.virtual_button_to_float(positive_button) - self.virtual_button_to_float(negative_button), }; if f32::abs(val) > fold { @@ -233,16 +266,33 @@ impl InputState { } pub fn on_mouse_wheel_event(self: &mut Self, delta: &MouseScrollDelta, modifiers: &ModifiersState) { - let direction = match delta { - MouseScrollDelta::LineDelta(_x, y) => if *y >= 0.0 { WheelInputDirection::Up } else { WheelInputDirection::Down }, - MouseScrollDelta::PixelDelta(pixels) => if pixels.y >= 0.0 { WheelInputDirection::Up } else { WheelInputDirection::Down }, + let vertical_direction = match delta { + MouseScrollDelta::LineDelta(_x, y) => { + if *y > 0.0 { Some(WheelInputDirection::Up) } + else if *y < 0.0 { Some(WheelInputDirection::Down) } + else { None } + }, + MouseScrollDelta::PixelDelta(pixels) => { + if pixels.y > 0.0 { Some(WheelInputDirection::Up) } + else if pixels.y < 0.0 { Some(WheelInputDirection::Down) } + else { None } + } + }; + + if let Some(direction) = vertical_direction { + let input = DigitalInput::Wheel(WheelInput { direction, modifiers: modifiers.clone() }); + self.input_events.insert(DigitalInputEvent::Pressed(input.clone())); + self.input_events.insert(DigitalInputEvent::Released(input)); + } + + self.analog_wheel_state = match delta { + MouseScrollDelta::LineDelta(_x, y) => *y * self.config.line_height_px, + MouseScrollDelta::PixelDelta(pixels) => pixels.y as f32, }; - let input = DigitalInput::Wheel(WheelInput { direction, modifiers: modifiers.clone() }); - self.input_events.insert(DigitalInputEvent::Pressed(input.clone())); - self.input_events.insert(DigitalInputEvent::Released(input)); } pub fn frame_end(self: &mut Self) { + self.analog_wheel_state = 0.0; self.input_events.clear(); } } @@ -257,7 +307,7 @@ pub fn mods_to_string(modifiers: &ModifiersState) -> String { #[derive(Debug)] pub enum AxisInput { - Analog(AnalogInput), + Wheel(ModifiersState), Digital(VirtualButton, VirtualButton), } @@ -265,34 +315,35 @@ pub enum AxisInput { pub enum DigitalInput { Keyboard(KeyboardInput), Wheel(WheelInput), - Mouse(MouseInput) + Mouse(MouseInput), } #[derive(Debug, Eq, PartialEq, Hash, Clone)] pub struct KeyboardInput { scan_code: ScanCode, - modifiers: ModifiersState + modifiers: ModifiersState, } #[derive(Debug, Eq, PartialEq, Hash, Clone)] pub struct MouseInput { button: MouseButton, - modifiers: ModifiersState + modifiers: ModifiersState, } #[derive(Debug, Eq, PartialEq, Hash, Clone)] pub struct WheelInput { direction: WheelInputDirection, - modifiers: ModifiersState + modifiers: ModifiersState, } #[derive(Debug, Eq, PartialEq, Hash, Clone)] pub enum WheelInputDirection { Up, - Down + Down, } -#[derive(Debug, Eq, PartialEq, Clone)] -pub struct AnalogInput { - +#[derive(Debug, PartialEq, Clone)] +pub struct AnalogWheelInput { + value: f32, + modifiers: ModifiersState, } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 4f88786..a803a82 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,7 @@ impl Game for TestGame { game_data.recreate_pipeline = true; } - self.cam_pos.x += self.input.get_axis("FORWARD_AXIS"); + self.cam_pos.x += self.input.get_axis("FORWARD_AXIS") * 0.01; // Move game objects game_data.push_constants.time = game_data.start_time.elapsed().unwrap().as_millis() as f32 / 1000.0;