Implemented mouse lock and delta
This commit is contained in:
+53
-2
@@ -16,6 +16,8 @@ pub struct PlatformConfig {
|
|||||||
pub aspect_ratio: Option<f32>,
|
pub aspect_ratio: Option<f32>,
|
||||||
pub palette: [[u8; 3]; 256],
|
pub palette: [[u8; 3]; 256],
|
||||||
pub vsync: bool,
|
pub vsync: bool,
|
||||||
|
pub mouse_visible: bool,
|
||||||
|
pub mouse_capture: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlatformConfig {
|
impl Default for PlatformConfig {
|
||||||
@@ -27,6 +29,8 @@ impl Default for PlatformConfig {
|
|||||||
aspect_ratio: Some(4.0 / 3.0),
|
aspect_ratio: Some(4.0 / 3.0),
|
||||||
palette: palette::RGB332,
|
palette: palette::RGB332,
|
||||||
vsync: true,
|
vsync: true,
|
||||||
|
mouse_visible: true,
|
||||||
|
mouse_capture: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,6 +103,13 @@ pub struct Platform {
|
|||||||
event_queue: VecDeque<Event>,
|
event_queue: VecDeque<Event>,
|
||||||
event_scratch: Vec<glfw::WindowEvent>,
|
event_scratch: Vec<glfw::WindowEvent>,
|
||||||
close_requested: bool,
|
close_requested: bool,
|
||||||
|
|
||||||
|
mouse_visible: bool,
|
||||||
|
mouse_capture: bool,
|
||||||
|
// Letzte rohe (window-space) Cursorposition, um Deltas zu bilden. None nach
|
||||||
|
// Mode-Wechsel/erstem Frame, damit der GLFW-Recenter keinen Riesensprung erzeugt.
|
||||||
|
last_cursor_pos: Option<(f64, f64)>,
|
||||||
|
mouse_delta: (f32, f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Platform {
|
impl Platform {
|
||||||
@@ -203,7 +214,7 @@ impl Platform {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
Self {
|
let mut platform = Self {
|
||||||
bind_group, pipeline, index_tex, palette_tex, params_buf, params,
|
bind_group, pipeline, index_tex, palette_tex, params_buf, params,
|
||||||
surface, config: surface_config, device, queue, instance,
|
surface, config: surface_config, device, queue, instance,
|
||||||
window, events, glfw,
|
window, events, glfw,
|
||||||
@@ -213,7 +224,41 @@ impl Platform {
|
|||||||
event_queue: VecDeque::new(),
|
event_queue: VecDeque::new(),
|
||||||
event_scratch: Vec::new(),
|
event_scratch: Vec::new(),
|
||||||
close_requested: false,
|
close_requested: false,
|
||||||
}
|
mouse_visible: cfg.mouse_visible,
|
||||||
|
mouse_capture: cfg.mouse_capture,
|
||||||
|
last_cursor_pos: None,
|
||||||
|
mouse_delta: (0.0, 0.0),
|
||||||
|
};
|
||||||
|
platform.apply_cursor_mode();
|
||||||
|
platform
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_mouse_visible(&mut self, visible: bool) {
|
||||||
|
self.mouse_visible = visible;
|
||||||
|
self.apply_cursor_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_mouse_capture(&mut self, capture: bool) {
|
||||||
|
self.mouse_capture = capture;
|
||||||
|
// Recenter nach Mode-Wechsel würde den nächsten Delta springen lassen.
|
||||||
|
self.last_cursor_pos = None;
|
||||||
|
self.apply_cursor_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_cursor_mode(&mut self) {
|
||||||
|
// capture impliziert hidden — GLFW kennt keinen "locked + visible".
|
||||||
|
let mode = match (self.mouse_capture, self.mouse_visible) {
|
||||||
|
(true, _) => glfw::CursorMode::Disabled,
|
||||||
|
(false, true) => glfw::CursorMode::Normal,
|
||||||
|
(false, false) => glfw::CursorMode::Hidden,
|
||||||
|
};
|
||||||
|
self.window.set_cursor_mode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Akkumulierte Mausbewegung seit dem letzten Aufruf, in Window-Pixeln.
|
||||||
|
/// Bei `set_mouse_capture(true)` liefert GLFW unbegrenzte Deltas (FPS-Stil).
|
||||||
|
pub fn mouse_delta(&mut self) -> (f32, f32) {
|
||||||
|
std::mem::replace(&mut self.mouse_delta, (0.0, 0.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn should_close(&self) -> bool { self.close_requested || self.window.should_close() }
|
pub fn should_close(&self) -> bool { self.close_requested || self.window.should_close() }
|
||||||
@@ -312,6 +357,12 @@ impl Platform {
|
|||||||
}
|
}
|
||||||
W::Char(c) => self.event_queue.push_back(Event::Char(c)),
|
W::Char(c) => self.event_queue.push_back(Event::Char(c)),
|
||||||
W::CursorPos(x, y) => {
|
W::CursorPos(x, y) => {
|
||||||
|
if let Some((lx, ly)) = self.last_cursor_pos {
|
||||||
|
self.mouse_delta.0 += (x - lx) as f32;
|
||||||
|
self.mouse_delta.1 += (y - ly) as f32;
|
||||||
|
}
|
||||||
|
self.last_cursor_pos = Some((x, y));
|
||||||
|
|
||||||
let (cx, cy, cw, ch) = self.content_rect;
|
let (cx, cy, cw, ch) = self.content_rect;
|
||||||
let (fw, fh) = self.framebuffer_size;
|
let (fw, fh) = self.framebuffer_size;
|
||||||
let fx = ((x - cx as f64) / cw as f64 * fw as f64) as f32;
|
let fx = ((x - cx as f64) / cw as f64 * fw as f64) as f32;
|
||||||
|
|||||||
Reference in New Issue
Block a user