Implemented mouse lock and delta

This commit is contained in:
2026-05-16 13:14:03 +02:00
parent a40dc779ad
commit 8f246a1f3e
+53 -2
View File
@@ -16,6 +16,8 @@ pub struct PlatformConfig {
pub aspect_ratio: Option<f32>,
pub palette: [[u8; 3]; 256],
pub vsync: bool,
pub mouse_visible: bool,
pub mouse_capture: bool,
}
impl Default for PlatformConfig {
@@ -27,6 +29,8 @@ impl Default for PlatformConfig {
aspect_ratio: Some(4.0 / 3.0),
palette: palette::RGB332,
vsync: true,
mouse_visible: true,
mouse_capture: false,
}
}
}
@@ -99,6 +103,13 @@ pub struct Platform {
event_queue: VecDeque<Event>,
event_scratch: Vec<glfw::WindowEvent>,
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 {
@@ -203,7 +214,7 @@ impl Platform {
],
});
Self {
let mut platform = Self {
bind_group, pipeline, index_tex, palette_tex, params_buf, params,
surface, config: surface_config, device, queue, instance,
window, events, glfw,
@@ -213,7 +224,41 @@ impl Platform {
event_queue: VecDeque::new(),
event_scratch: Vec::new(),
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() }
@@ -312,6 +357,12 @@ impl Platform {
}
W::Char(c) => self.event_queue.push_back(Event::Char(c)),
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 (fw, fh) = self.framebuffer_size;
let fx = ((x - cx as f64) / cw as f64 * fw as f64) as f32;