summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--engine/Cargo.toml1
-rw-r--r--engine/src/camera/fly.rs3
-rw-r--r--engine/src/input.rs4
-rw-r--r--engine/src/window.rs402
5 files changed, 382 insertions, 29 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e7faae2..6f3bc09 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -144,6 +144,7 @@ dependencies = [
"seq-macro",
"thiserror",
"tracing",
+ "util-macros",
]
[[package]]
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
{