diff --git a/config/input.toml b/config/input.toml index 78711c1..c49606b 100644 --- a/config/input.toml +++ b/config/input.toml @@ -1,13 +1,18 @@ [[button]] name = "QUIT" -scancode = 1 +scan_code = 1 + +[[button]] +name = "QUIT" +mouse = "Left" +shift = true [[button]] name = "RELOAD_SHADERS" -scancode = 19 +scan_code = 19 ctrl = true [[axis]] name = "FORWARD" -scancode_positive = 17 -scancode_negative = 31 \ No newline at end of file +scan_code_positive = 17 +scan_code_negative = 31 \ No newline at end of file diff --git a/config/log.toml b/config/log.toml index 77f557f..6215a06 100644 --- a/config/log.toml +++ b/config/log.toml @@ -1 +1 @@ -input = false \ No newline at end of file +input = true \ No newline at end of file diff --git a/src/input.rs b/src/input.rs index d1ad20f..79677b4 100644 --- a/src/input.rs +++ b/src/input.rs @@ -6,6 +6,7 @@ use std::fs; use toml; use serde_derive::{Serialize, Deserialize}; +use std::iter::FromIterator; pub struct VirtualButton { pub digital_inputs: Vec @@ -19,7 +20,8 @@ pub struct InputState { pub virtual_buttons: HashMap, pub virtual_axes: HashMap, input_events: HashSet, - pressed_buttons: HashSet + pressed_scan_codes: HashSet, + pressed_mouse_buttons: HashSet } #[derive(Debug, PartialEq, Eq, Hash)] @@ -37,34 +39,51 @@ struct InputConfig { #[derive(Debug, Serialize, Deserialize)] struct InputConfigButton { name: String, - scancode: u32, - ctrl: Option + scan_code: Option, + mouse: Option, + ctrl: Option, + shift: Option, + alt: Option, + logo: Option, } #[derive(Debug, Serialize, Deserialize)] struct InputConfigAxis { name: String, - scancode_positive: u32, + scan_code_positive: u32, ctrl_positive: Option, - scancode_negative: u32, + scan_code_negative: u32, ctrl_negative: Option } 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_buttons: HashSet::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!"); config.button.iter().for_each(|bn| { let modifiers = ModifiersState { - shift: false, + shift: bn.shift.is_some(), ctrl: bn.ctrl.is_some(), - alt: false, - logo: false + alt: bn.alt.is_some(), + logo: bn.logo.is_some() }; - let input = DigitalInput::Keyboard(KeyboardInput { scancode: bn.scancode, modifiers }); + let input = if let Some(scan_code) = bn.scan_code { + DigitalInput::Keyboard(KeyboardInput { scan_code, modifiers }) + } else if let Some(button_name) = &bn.mouse { + let button = match button_name.to_lowercase().as_str() { + "left" => MouseButton::Left, + "middle" => MouseButton::Middle, + "right" => MouseButton::Right, + other => MouseButton::Other(other.parse().expect(&format!("Unknown button: {:?}", other))) + }; + DigitalInput::Mouse(MouseInput { button, modifiers }) + } else { + panic!("No mouse or keyboard input for button {:?}", bn.name); + }; + if let Some(virtual_button) = state.virtual_buttons.get_mut(&bn.name) { virtual_button.digital_inputs.push(input); } else { @@ -86,8 +105,8 @@ impl InputState { logo: false }; let axis = AxisInput::Digital( - DigitalInput::Keyboard(KeyboardInput { scancode: a.scancode_positive, modifiers: modifiers_positive }), - DigitalInput::Keyboard(KeyboardInput { scancode: a.scancode_negative, modifiers: modifiers_negative }) + DigitalInput::Keyboard(KeyboardInput { scan_code: a.scan_code_positive, modifiers: modifiers_positive }), + DigitalInput::Keyboard(KeyboardInput { scan_code: a.scan_code_negative, modifiers: modifiers_negative }) ); if let Some(virtual_axis) = state.virtual_axes.get_mut(&a.name) { virtual_axis.axis_inputs.push(axis); @@ -168,35 +187,52 @@ impl InputState { pub fn digital_input_pressed(self: &Self, digital_input: &DigitalInput) -> bool { match digital_input { - DigitalInput::Keyboard(keyboard_input) => - self.pressed_buttons.contains(&keyboard_input.scancode) - && self.modifiers_are_pressed(keyboard_input.modifiers), - DigitalInput::Mouse(_) => false + DigitalInput::Keyboard(keyboard_input) => { + self.pressed_scan_codes.contains(&keyboard_input.scan_code) + && self.modifiers_are_pressed(keyboard_input.modifiers) + }, + DigitalInput::Mouse(mouse_input) => { + self.pressed_mouse_buttons.contains(&mouse_input.button) + && self.modifiers_are_pressed(mouse_input.modifiers) + } } } fn modifiers_are_pressed(self: &Self, modifiers: ModifiersState) -> bool { - (!modifiers.ctrl || self.pressed_buttons.contains(&29)) - && (!modifiers.shift || self.pressed_buttons.contains(&42) || self.pressed_buttons.contains(&54)) - && (!modifiers.alt || self.pressed_buttons.contains(&56)) - && (!modifiers.logo || self.pressed_buttons.contains(&91) || self.pressed_buttons.contains(&92)) + (!modifiers.ctrl || self.pressed_scan_codes.contains(&29)) + && (!modifiers.shift || self.pressed_scan_codes.contains(&42) || self.pressed_scan_codes.contains(&54)) + && (!modifiers.alt || self.pressed_scan_codes.contains(&56)) + && (!modifiers.logo || self.pressed_scan_codes.contains(&91) || self.pressed_scan_codes.contains(&92)) } fn digital_input_to_float(self: &Self, input: &DigitalInput) -> f32 { if self.digital_input_pressed(input) { 1.0 } else { 0.0 } } - pub fn on_keyboard_event(self: &mut Self, state: ElementState, scancode: ScanCode, modifiers: ModifiersState) { - let input = DigitalInput::Keyboard(KeyboardInput { scancode, modifiers }); - + pub fn on_keyboard_event(self: &mut Self, state: ElementState, scan_code: ScanCode, modifiers: ModifiersState) { + let input = DigitalInput::Keyboard(KeyboardInput { scan_code, modifiers }); match state { ElementState::Pressed => { self.input_events.insert(DigitalInputEvent::Pressed(input)); - self.pressed_buttons.insert(scancode); + self.pressed_scan_codes.insert(scan_code); }, ElementState::Released => { self.input_events.insert(DigitalInputEvent::Released(input)); - self.pressed_buttons.remove(&scancode); + self.pressed_scan_codes.remove(&scan_code); + }, + } + } + + pub fn on_mouse_event(self: &mut Self, state: &ElementState, button: &MouseButton, modifiers: &ModifiersState) { + let input = DigitalInput::Mouse(MouseInput { button: button.clone(), modifiers: modifiers.clone() }); + match state { + ElementState::Pressed => { + self.input_events.insert(DigitalInputEvent::Pressed(input)); + self.pressed_mouse_buttons.insert(button.clone()); + }, + ElementState::Released => { + self.input_events.insert(DigitalInputEvent::Released(input)); + self.pressed_mouse_buttons.remove(button); }, } } @@ -206,6 +242,14 @@ impl InputState { } } +pub fn mods_to_string(modifiers: &ModifiersState) -> String { + String::from_iter( + vec!["shift", "ctrl", "alt", "logo"].iter() + .zip(vec![modifiers.shift, modifiers.ctrl, modifiers.alt, modifiers.logo]) + .filter(|(&_name, state)| *state) + .map(|(&name, _state)| name)) +} + pub enum AxisInput { Analog(AnalogInput), Digital(DigitalInput, DigitalInput), @@ -219,7 +263,7 @@ pub enum DigitalInput { #[derive(Debug, Eq, PartialEq, Hash)] pub struct KeyboardInput { - scancode: ScanCode, + scan_code: ScanCode, modifiers: ModifiersState } diff --git a/src/main.rs b/src/main.rs index 58e349c..2a3d765 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,11 @@ use winit::{Event, WindowEvent}; -use std::iter::FromIterator; use cgmath::{Matrix4, Rad, Point3, Vector3, Deg}; mod vulkan; use crate::vulkan::{GameData, Game, LinePoint}; mod input; -use crate::input::{InputState}; +use crate::input::{InputState, mods_to_string}; mod config; use crate::config::LogConfig; @@ -63,23 +62,28 @@ impl Game for TestGame { match event { Event::WindowEvent { event: WindowEvent::KeyboardInput { device_id, input }, .. } => { if self.log_config.input { - let mods = String::from_iter( - vec!["shift", "ctrl", "alt", "logo"].iter() - .zip(vec![input.modifiers.shift, input.modifiers.ctrl, input.modifiers.alt, input.modifiers.logo]) - .filter(|(&_name, state)| *state) - .map(|(&name, _state)| name)); + let mods = mods_to_string(&input.modifiers); if mods.len() > 0 { - println!("Keyboard {:?} input {:?} {:?} + {:?}", device_id, input.state, &mods, input.scancode) + println!("Keyboard {:?} {:?} {:?} + {:?}", device_id, input.state, &mods, input.scancode) } else { - println!("Keyboard {:?} input {:?} {:?}", device_id, input.state, input.scancode) + println!("Keyboard {:?} {:?} {:?}", device_id, input.state, input.scancode) } } self.input.on_keyboard_event(input.state, input.scancode, input.modifiers); }, -// Event::WindowEvent { event: WindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => { -// -// } + Event::WindowEvent { event: WindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => { + if self.log_config.input { + let mods = mods_to_string(modifiers); + if mods.len() > 0 { + println!("Mouse {:?} {:?} {:?} + {:?}", device_id, state, &mods, button) + } else { + println!("Mouse {:?} {:?} {:?}", device_id, state, button) + } + } + + self.input.on_mouse_event(state, button, modifiers); + } _ => {} } }