diff options
Diffstat (limited to 'engine')
-rw-r--r-- | engine/Cargo.toml | 1 | ||||
-rw-r--r-- | engine/src/camera/fly.rs | 3 | ||||
-rw-r--r-- | engine/src/input.rs | 4 | ||||
-rw-r--r-- | engine/src/window.rs | 402 |
4 files changed, 381 insertions, 29 deletions
diff --git a/engine/Cargo.toml b/engine/Cargo.toml index a2cc7aa..f6cd5cf 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -12,6 +12,7 @@ tracing = "0.1.39" seq-macro = "0.3.5" paste = "1.0.14" ecs = { path = "../ecs" } +util-macros = { path = "../util-macros" } [dependencies.image] version = "0.24.7" diff --git a/engine/src/camera/fly.rs b/engine/src/camera/fly.rs index 4c49846..1333360 100644 --- a/engine/src/camera/fly.rs +++ b/engine/src/camera/fly.rs @@ -2,12 +2,11 @@ use ecs::component::local::Local; use ecs::sole::Single; use ecs::system::{Into, System}; use ecs::{Component, Query}; -use glfw::window::{Key, KeyState}; use crate::camera::{Active as ActiveCamera, Camera}; use crate::delta_time::DeltaTime; use crate::event::Update as UpdateEvent; -use crate::input::{Cursor, CursorFlags, Keys}; +use crate::input::{Cursor, CursorFlags, Key, KeyState, Keys}; use crate::transform::Position; use crate::util::builder; use crate::vector::{Vec2, Vec3}; diff --git a/engine/src/input.rs b/engine/src/input.rs index 04e5263..e847702 100644 --- a/engine/src/input.rs +++ b/engine/src/input.rs @@ -68,10 +68,6 @@ impl Keys pub fn set_key_state(&mut self, key: Key, new_key_state: KeyState) { - if matches!(new_key_state, KeyState::Repeat) { - return; - } - let Some(key_data) = self.map.get_mut(&key) else { unreachable!(); }; diff --git a/engine/src/window.rs b/engine/src/window.rs index b65831a..ad239a1 100644 --- a/engine/src/window.rs +++ b/engine/src/window.rs @@ -1,31 +1,19 @@ use std::borrow::Cow; use std::ffi::{CStr, CString}; +use bitflags::bitflags; use ecs::actions::Actions; use ecs::extension::Collector as ExtensionCollector; use ecs::sole::Single; use ecs::Sole; +use glfw::window::{Hint as WindowCreationHint, HintValue as WindowCreationHintValue}; use glfw::WindowSize; +use util_macros::VariantArr; use crate::data_types::dimens::Dimens; use crate::event::{Conclude as ConcludeEvent, Start as StartEvent}; use crate::vector::Vec2; -mod reexports -{ - pub use glfw::window::{ - CursorMode, - Hint as CreationHint, - HintValue as CreationHintValue, - InputMode, - Key, - KeyModifiers, - KeyState, - }; -} - -pub use reexports::*; - #[derive(Debug, Sole)] /// Has to be dropped last since it holds the OpenGL context. #[sole(drop_last)] @@ -53,7 +41,9 @@ impl Window enabled: bool, ) -> Result<(), Error> { - Ok(self.inner.set_input_mode(input_mode, enabled)?) + Ok(self + .inner + .set_input_mode(input_mode.to_glfw_input_mode(), enabled)?) } /// Sets the cursor mode. @@ -62,7 +52,9 @@ impl Window /// If a platform error occurs. pub fn set_cursor_mode(&self, cursor_mode: CursorMode) -> Result<(), Error> { - Ok(self.inner.set_cursor_mode(cursor_mode)?) + Ok(self + .inner + .set_cursor_mode(cursor_mode.to_glfw_cursor_mode())?) } /// Returns whether or not the window should close. Will return true when the user has @@ -155,7 +147,19 @@ impl Window callback: impl Fn(Key, i32, KeyState, KeyModifiers) + 'static, ) { - self.inner.set_key_callback(callback); + self.inner + .set_key_callback(move |key, scancode, key_state, key_modifiers| { + let Some(key_state) = KeyState::from_glfw_key_state(key_state) else { + return; + }; + + callback( + Key::from_glfw_key(key), + scancode, + key_state, + KeyModifiers::from_bits_truncate(key_modifiers.bits()), + ) + }); } /// Sets the window's cursor position callback. @@ -188,10 +192,26 @@ pub struct Builder impl Builder { - #[must_use] - pub fn creation_hint(mut self, hint: CreationHint, value: CreationHintValue) -> Self + /// Sets whether the OpenGL context should be created in debug mode, which may + /// provide additional error and diagnostic reporting functionality. + pub fn opengl_debug_context(mut self, enabled: bool) -> Self { - self.inner = self.inner.hint(hint, value); + self.inner = self.inner.hint( + WindowCreationHint::OpenGLDebugContext, + WindowCreationHintValue::Bool(enabled), + ); + + self + } + + /// Set the desired number of samples to use for multisampling. Zero disables + /// multisampling. + pub fn multisampling_sample_count(mut self, sample_count: u16) -> Self + { + self.inner = self.inner.hint( + WindowCreationHint::Samples, + WindowCreationHintValue::Number(sample_count as i32), + ); self } @@ -204,8 +224,8 @@ impl Builder pub fn create(&self, size: Dimens<u32>, title: &str) -> Result<Window, Error> { let builder = self.inner.clone().hint( - CreationHint::OpenGLDebugContext, - CreationHintValue::Bool(true), + WindowCreationHint::OpenGLDebugContext, + WindowCreationHintValue::Bool(true), ); let window = builder.create( @@ -220,6 +240,342 @@ impl Builder } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, VariantArr)] +#[variant_arr(name = KEYS)] +pub enum Key +{ + Space, + Apostrophe, + Comma, + Minus, + Period, + Slash, + Digit0, + Digit1, + Digit2, + Digit3, + Digit4, + Digit5, + Digit6, + Digit7, + Digit8, + Digit9, + Semicolon, + Equal, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + LeftBracket, + Backslash, + RightBracket, + GraveAccent, + World1, + World2, + Escape, + Enter, + Tab, + Backspace, + Insert, + Delete, + Right, + Left, + Down, + Up, + PageUp, + PageDown, + Home, + End, + CapsLock, + ScrollLock, + NumLock, + PrintScreen, + Pause, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, + F25, + Kp0, + Kp1, + Kp2, + Kp3, + Kp4, + Kp5, + Kp6, + Kp7, + Kp8, + Kp9, + KpDecimal, + KpDivide, + KpMultiply, + KpSubtract, + KpAdd, + KpEnter, + KpEqual, + LeftShift, + LeftControl, + LeftAlt, + LeftSuper, + RightShift, + RightControl, + RightAlt, + RightSuper, + Menu, +} + +impl Key +{ + fn from_glfw_key(glfw_key: glfw::window::Key) -> Self + { + match glfw_key { + glfw::window::Key::Space => Self::Space, + glfw::window::Key::Apostrophe => Self::Apostrophe, + glfw::window::Key::Comma => Self::Comma, + glfw::window::Key::Minus => Self::Minus, + glfw::window::Key::Period => Self::Period, + glfw::window::Key::Slash => Self::Slash, + glfw::window::Key::Digit0 => Self::Digit0, + glfw::window::Key::Digit1 => Self::Digit1, + glfw::window::Key::Digit2 => Self::Digit2, + glfw::window::Key::Digit3 => Self::Digit3, + glfw::window::Key::Digit4 => Self::Digit4, + glfw::window::Key::Digit5 => Self::Digit5, + glfw::window::Key::Digit6 => Self::Digit6, + glfw::window::Key::Digit7 => Self::Digit7, + glfw::window::Key::Digit8 => Self::Digit8, + glfw::window::Key::Digit9 => Self::Digit9, + glfw::window::Key::Semicolon => Self::Semicolon, + glfw::window::Key::Equal => Self::Equal, + glfw::window::Key::A => Self::A, + glfw::window::Key::B => Self::B, + glfw::window::Key::C => Self::C, + glfw::window::Key::D => Self::D, + glfw::window::Key::E => Self::E, + glfw::window::Key::F => Self::F, + glfw::window::Key::G => Self::G, + glfw::window::Key::H => Self::H, + glfw::window::Key::I => Self::I, + glfw::window::Key::J => Self::J, + glfw::window::Key::K => Self::K, + glfw::window::Key::L => Self::L, + glfw::window::Key::M => Self::M, + glfw::window::Key::N => Self::N, + glfw::window::Key::O => Self::O, + glfw::window::Key::P => Self::P, + glfw::window::Key::Q => Self::Q, + glfw::window::Key::R => Self::R, + glfw::window::Key::S => Self::S, + glfw::window::Key::T => Self::T, + glfw::window::Key::U => Self::U, + glfw::window::Key::V => Self::V, + glfw::window::Key::W => Self::W, + glfw::window::Key::X => Self::X, + glfw::window::Key::Y => Self::Y, + glfw::window::Key::Z => Self::Z, + glfw::window::Key::LeftBracket => Self::LeftBracket, + glfw::window::Key::Backslash => Self::Backslash, + glfw::window::Key::RightBracket => Self::RightBracket, + glfw::window::Key::GraveAccent => Self::GraveAccent, + glfw::window::Key::World1 => Self::World1, + glfw::window::Key::World2 => Self::World2, + glfw::window::Key::Escape => Self::Escape, + glfw::window::Key::Enter => Self::Enter, + glfw::window::Key::Tab => Self::Tab, + glfw::window::Key::Backspace => Self::Backspace, + glfw::window::Key::Insert => Self::Insert, + glfw::window::Key::Delete => Self::Delete, + glfw::window::Key::Right => Self::Right, + glfw::window::Key::Left => Self::Left, + glfw::window::Key::Down => Self::Down, + glfw::window::Key::Up => Self::Up, + glfw::window::Key::PageUp => Self::PageUp, + glfw::window::Key::PageDown => Self::PageDown, + glfw::window::Key::Home => Self::Home, + glfw::window::Key::End => Self::End, + glfw::window::Key::CapsLock => Self::CapsLock, + glfw::window::Key::ScrollLock => Self::ScrollLock, + glfw::window::Key::NumLock => Self::NumLock, + glfw::window::Key::PrintScreen => Self::PrintScreen, + glfw::window::Key::Pause => Self::Pause, + glfw::window::Key::F1 => Self::F1, + glfw::window::Key::F2 => Self::F2, + glfw::window::Key::F3 => Self::F3, + glfw::window::Key::F4 => Self::F4, + glfw::window::Key::F5 => Self::F5, + glfw::window::Key::F6 => Self::F6, + glfw::window::Key::F7 => Self::F7, + glfw::window::Key::F8 => Self::F8, + glfw::window::Key::F9 => Self::F9, + glfw::window::Key::F10 => Self::F10, + glfw::window::Key::F11 => Self::F11, + glfw::window::Key::F12 => Self::F12, + glfw::window::Key::F13 => Self::F13, + glfw::window::Key::F14 => Self::F14, + glfw::window::Key::F15 => Self::F15, + glfw::window::Key::F16 => Self::F16, + glfw::window::Key::F17 => Self::F17, + glfw::window::Key::F18 => Self::F18, + glfw::window::Key::F19 => Self::F19, + glfw::window::Key::F20 => Self::F20, + glfw::window::Key::F21 => Self::F21, + glfw::window::Key::F22 => Self::F22, + glfw::window::Key::F23 => Self::F23, + glfw::window::Key::F24 => Self::F24, + glfw::window::Key::F25 => Self::F25, + glfw::window::Key::Kp0 => Self::Kp0, + glfw::window::Key::Kp1 => Self::Kp1, + glfw::window::Key::Kp2 => Self::Kp2, + glfw::window::Key::Kp3 => Self::Kp3, + glfw::window::Key::Kp4 => Self::Kp4, + glfw::window::Key::Kp5 => Self::Kp5, + glfw::window::Key::Kp6 => Self::Kp6, + glfw::window::Key::Kp7 => Self::Kp7, + glfw::window::Key::Kp8 => Self::Kp8, + glfw::window::Key::Kp9 => Self::Kp9, + glfw::window::Key::KpDecimal => Self::KpDecimal, + glfw::window::Key::KpDivide => Self::KpDivide, + glfw::window::Key::KpMultiply => Self::KpMultiply, + glfw::window::Key::KpSubtract => Self::KpSubtract, + glfw::window::Key::KpAdd => Self::KpAdd, + glfw::window::Key::KpEnter => Self::KpEnter, + glfw::window::Key::KpEqual => Self::KpEqual, + glfw::window::Key::LeftShift => Self::LeftShift, + glfw::window::Key::LeftControl => Self::LeftControl, + glfw::window::Key::LeftAlt => Self::LeftAlt, + glfw::window::Key::LeftSuper => Self::LeftSuper, + glfw::window::Key::RightShift => Self::RightShift, + glfw::window::Key::RightControl => Self::RightControl, + glfw::window::Key::RightAlt => Self::RightAlt, + glfw::window::Key::RightSuper => Self::RightSuper, + glfw::window::Key::Menu => Self::Menu, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum KeyState +{ + Pressed, + Released, +} + +impl KeyState +{ + fn from_glfw_key_state(glfw_key_state: glfw::window::KeyState) -> Option<Self> + { + match glfw_key_state { + glfw::window::KeyState::Pressed => Some(Self::Pressed), + glfw::window::KeyState::Released => Some(Self::Released), + glfw::window::KeyState::Repeat => None, + } + } +} + +bitflags! { + #[derive(Debug, Clone, Copy)] + pub struct KeyModifiers: i32 { + const SHIFT = glfw::window::KeyModifiers::SHIFT.bits(); + const CONTROL = glfw::window::KeyModifiers::CONTROL.bits(); + const ALT = glfw::window::KeyModifiers::ALT.bits(); + const SUPER = glfw::window::KeyModifiers::SUPER.bits(); + const CAPS_LOCK = glfw::window::KeyModifiers::CAPS_LOCK.bits(); + const NUM_LOCK = glfw::window::KeyModifiers::NUM_LOCK.bits(); + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum CursorMode +{ + /// Hides and grabs the cursor, providing virtual and unlimited cursor movement. + Disabled, + + /// Makes the cursor invisible when it is over the content area of the window but + /// does not restrict the cursor from leaving. + Hidden, + + /// Makes the cursor visible and behaving normally. + Normal, +} + +impl CursorMode +{ + fn to_glfw_cursor_mode(self) -> glfw::window::CursorMode + { + match self { + Self::Disabled => glfw::window::CursorMode::Disabled, + Self::Hidden => glfw::window::CursorMode::Hidden, + Self::Normal => glfw::window::CursorMode::Normal, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum InputMode +{ + /// When the cursor is disabled, raw (unscaled and unaccelerated) mouse motion can be + /// enabled if available. + /// + /// Raw mouse motion is closer to the actual motion of the mouse across a surface. It + /// is not affected by the scaling and acceleration applied to the motion of the + /// desktop cursor. That processing is suitable for a cursor while raw motion is + /// better for controlling for example a 3D camera. Because of this, raw mouse motion + /// is only provided when the cursor is disabled. + RawMouseMotion, +} + +impl InputMode +{ + fn to_glfw_input_mode(self) -> glfw::window::InputMode + { + match self { + Self::RawMouseMotion => glfw::window::InputMode::RawMouseMotion, + } + } +} + #[derive(Debug)] pub struct Extension { |