changeset 1306:7be3628298f5

did: reworked locked mouse
author sam <sam@basx.dev>
date Wed, 07 Aug 2024 20:58:11 +0700
parents 21c4e598d820
children 5a898b18a58a
files semicongine/events.nim semicongine/input.nim semicongine/rendering/platform/linux.nim semicongine/rendering/platform/windows.nim tests/test_gltf.nim
diffstat 5 files changed, 50 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/semicongine/events.nim	Wed Aug 07 19:09:03 2024 +0700
+++ b/semicongine/events.nim	Wed Aug 07 20:58:11 2024 +0700
@@ -3,7 +3,7 @@
     Quit
     ResizedWindow, MinimizedWindow, RestoredWindow
     KeyPressed, KeyReleased
-    MousePressed, MouseReleased, MouseMoved,
+    MousePressed, MouseReleased,
     MouseWheel
     GotFocus, LostFocus
   Key* {.size: sizeof(cint), pure.} = enum
@@ -28,8 +28,6 @@
       key*: Key
     of MousePressed, MouseReleased:
       button*: MouseButton
-    of MouseMoved:
-      x*, y*: int
     of MouseWheel:
       amount*: float32
     of GotFocus:
--- a/semicongine/input.nim	Wed Aug 07 19:09:03 2024 +0700
+++ b/semicongine/input.nim	Wed Aug 07 20:58:11 2024 +0700
@@ -32,15 +32,20 @@
   input.mouseWasPressed = {}
   input.mouseWasReleased = {}
   input.mouseWheel = 0
-  input.mouseMove = vec2(0, 0)
+  input.mouseMove = vec2i(0, 0)
   input.windowWasResized = false
 
   # if input.lockMouse and input.hasFocus:
     # setMousePosition(vulkan.window, x=int(vulkan.swapchain.width div 2), y=int(vulkan.swapchain.height div 2))
 
   let newMousePos = getMousePosition(vulkan.window)
-  input.mouseMove = newPos - input.mousePosition
-  input.mousePosition = newPos
+
+  input.mouseMove = newMousePos - input.mousePosition
+  if input.lockMouse and input.hasFocus:
+    input.mousePosition = vulkan.window.size div 2
+    setMousePosition(vulkan.window, input.mousePosition)
+  else:
+    input.mousePosition = newMousePos
 
   var killed = false
   for event in vulkan.window.pendingEvents():
@@ -89,7 +94,7 @@
 proc mousePosition*(size: (int, int)): Vec2f =
   result.x = (input.mousePosition.x.float32 / float32(size[0])) * 2.0 - 1.0
   result.y = (input.mousePosition.y.float32 / float32(size[1])) * 2.0 - 1.0
-proc mouseMove*(): Vec2f = input.mouseMove
+proc mouseMove*(): Vec2i = input.mouseMove
 proc mouseWheel*(): float32 = input.mouseWheel
 proc windowWasResized*(): auto = input.windowWasResized
 proc windowIsMinimized*(): auto = input.windowIsMinimized
--- a/semicongine/rendering/platform/linux.nim	Wed Aug 07 19:09:03 2024 +0700
+++ b/semicongine/rendering/platform/linux.nim	Wed Aug 07 20:58:11 2024 +0700
@@ -88,7 +88,7 @@
     # foregroundColor, backgroundColor
   )
   checkXlibResult XSetStandardProperties(display, window, title, "window", 0, nil, 0, nil)
-  checkXlibResult XSelectInput(display, window, PointerMotionMask or ButtonPressMask or ButtonReleaseMask or KeyPressMask or KeyReleaseMask or ExposureMask or FocusChangeMask)
+  checkXlibResult XSelectInput(display, window, ButtonPressMask or ButtonReleaseMask or KeyPressMask or KeyReleaseMask or ExposureMask or FocusChangeMask)
   checkXlibResult XMapWindow(display, window)
 
   deleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", XBool(false))
@@ -102,7 +102,7 @@
   return NativeWindow(display: display, window: window, emptyCursor: empty_cursor)
 
 proc setTitle*(window: NativeWindow, title: string) =
-  checkXlibResult XSetStandardProperties(window.display, window.window, title, "window", 0, nil, 0, nil)
+  discard XSetStandardProperties(window.display, window.window, title, "window", 0, nil, 0, nil)
 
 proc setFullscreen*(window: var NativeWindow, enable: bool) =
   var
@@ -147,10 +147,10 @@
   checkXlibResult window.display.XDestroyWindow(window.window)
   discard window.display.XCloseDisplay() # always returns 0
 
-proc size*(window: NativeWindow): (int, int) =
+proc size*(window: NativeWindow): Vec2i =
   var attribs: XWindowAttributes
-  checkXlibResult XGetWindowAttributes(window.display, window.window, addr(attribs))
-  return (int(attribs.width), int(attribs.height))
+  discard XGetWindowAttributes(window.display, window.window, addr(attribs))
+  vec2i(attribs.width, attribs.height)
 
 proc pendingEvents*(window: NativeWindow): seq[Event] =
   var event: XEvent
@@ -179,10 +179,6 @@
     of ButtonRelease:
       let button = int(cast[PXButtonEvent](addr(event)).button)
       result.add Event(eventType: MouseReleased, button: MouseButtonTypeMap.getOrDefault(button, MouseButton.UNKNOWN))
-    of MotionNotify:
-      let motion = cast[PXMotionEvent](addr(event))
-      if motion.x > 0 or motion.y > 0:
-        result.add Event(eventType: MouseMoved, x: motion.x, y: motion.y)
     of FocusIn:
       result.add Event(eventType: GotFocus)
     of FocusOut:
@@ -193,7 +189,7 @@
       discard
 
 
-proc getMousePosition*(window: NativeWindow): Option[Vec2i] =
+proc getMousePosition*(window: NativeWindow): Vec2i =
   var
     root: x11.Window
     win: x11.Window
@@ -202,32 +198,28 @@
     winX: cint
     winY: cint
     mask: cuint
-    onscreen = XQueryPointer(
-      window.display,
-      window.window,
-      addr(root),
-      addr(win),
-      addr(rootX),
-      addr(rootY),
-      addr(winX),
-      addr(winY),
-      addr(mask),
-    )
-  if onscreen != 0:
-    result = some(vec2(winX, winY))
+  discard XQueryPointer(
+    window.display,
+    window.window,
+    addr(root),
+    addr(win),
+    addr(rootX),
+    addr(rootY),
+    addr(winX),
+    addr(winY),
+    addr(mask),
+  )
+  vec2i(winX, winY)
 
-proc lockMouse*(window: NativeWindow, lock: bool) =
-  if lock:
-    let s = window.size()
-    checkXlibResult XWarpPointer(
-      window.display,
-      default(x11.Window),
-      window.window,
-      0, 0, 0, 0,
-      s[0].cint div 2,
-      s[1].cint div 2,
-    )
-    checkXlibResult XSync(window.display, false.XBool)
+proc setMousePosition*(window: NativeWindow, pos: Vec2i) =
+  discard XWarpPointer(
+    window.display,
+    default(x11.Window),
+    window.window,
+    0, 0, 0, 0,
+    pos.x.cint,
+    pos.y.cint,
+  )
 
 proc createNativeSurface(instance: VkInstance, window: NativeWindow): VkSurfaceKHR =
   var surfaceCreateInfo = VkXlibSurfaceCreateInfoKHR(
--- a/semicongine/rendering/platform/windows.nim	Wed Aug 07 19:09:03 2024 +0700
+++ b/semicongine/rendering/platform/windows.nim	Wed Aug 07 20:58:11 2024 +0700
@@ -92,8 +92,6 @@
     currentEvents.add(Event(eventType: MousePressed, button: MouseButton.Mouse3))
   of WM_RBUTTONUP:
     currentEvents.add(Event(eventType: MouseReleased, button: MouseButton.Mouse3))
-  of WM_MOUSEMOVE:
-    currentEvents.add(Event(eventType: MouseMoved, x: GET_X_LPARAM(lParam), y: GET_Y_LPARAM(lParam)))
   of WM_MOUSEWHEEL:
     currentEvents.add(Event(eventType: MouseWheel, amount: float32(GET_WHEEL_DELTA_WPARAM(wParam)) / WHEEL_DELTA))
   of WM_SIZING:
@@ -184,10 +182,10 @@
 proc destroy*(window: NativeWindow) =
   discard
 
-proc size*(window: NativeWindow): (int, int) =
+proc size*(window: NativeWindow): Vec2i =
   var rect: RECT
-  checkWin32Result GetWindowRect(window.hwnd, addr(rect))
-  (int(rect.right - rect.left), int(rect.bottom - rect.top))
+  discard GetClientRect(window.hwnd, addr(rect))
+  vec2i(rect.right - rect.left, rect.bottom - rect.top)
 
 proc pendingEvents*(window: NativeWindow): seq[Event] =
   # empty queue
@@ -199,15 +197,16 @@
   result = currentEvents
   currentEvents.setLen(0)
 
-proc getMousePosition*(window: NativeWindow): Option[Vec2i] =
+proc getMousePosition*(window: NativeWindow): Vec2i =
   var p: POINT
-  let res = GetCursorPos(addr(p))
-  if res:
-    return some(vec2i(p.x, p.y))
-  return none(Vec2i)
+  discard GetCursorPos(addr(p))
+  discard window.hwnd.ScreenToClient(addr(p))
+  vec2i(p.x, p.y)
 
-proc setMousePosition*(window: NativeWindow, x, y: int) =
-  checkWin32Result SetCursorPos(x.int32, y.int32)
+proc setMousePosition*(window: NativeWindow, pos: Vec2i) =
+  var p = POINT(x: pos.x, y: pos.y)
+  discard window.hwnd.ScreenToClient(addr(p))
+  discard SetCursorPos(pos.x, pos.y)
 
 proc createNativeSurface*(instance: VkInstance, window: NativeWindow): VkSurfaceKHR =
   assert instance.Valid
--- a/tests/test_gltf.nim	Wed Aug 07 19:09:03 2024 +0700
+++ b/tests/test_gltf.nim	Wed Aug 07 20:58:11 2024 +0700
@@ -158,8 +158,8 @@
     let dt = ((getMonoTime() - lastT).inNanoseconds().int / 1_000_000_000).float32
     lastT = getMonoTime()
 
-    camYaw  -= mouseMove().x / 1000
-    camPitch -= mouseMove().y / 1000
+    camYaw  += mouseMove().x.float32 / 1000'f32
+    camPitch += mouseMove().y.float32 / 1000'f32
     var
       forward = 0'f32
       sideward = 0'f32