diff src/zamikongine/platform/windows/win32.nim @ 38:c3c963e7c1a6

did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
author Sam <sam@basx.dev>
date Wed, 18 Jan 2023 09:52:03 +0700
parents a3d46f434616
children
line wrap: on
line diff
--- a/src/zamikongine/platform/windows/win32.nim	Mon Jan 16 00:51:03 2023 +0700
+++ b/src/zamikongine/platform/windows/win32.nim	Wed Jan 18 09:52:03 2023 +0700
@@ -1,5 +1,6 @@
 import winim
 
+import ./virtualkey_map
 import ../../events
 
 type
@@ -7,6 +8,7 @@
     hinstance*: HINSTANCE
     hwnd*: HWND
 
+# sorry, have to use module-global variable to capture windows events
 var currentEvents: seq[Event]
 
 template checkWin32Result*(call: untyped) =
@@ -14,10 +16,42 @@
   if value != 0:
     raise newException(Exception, "Win32 error: " & astToStr(call) & " returned " & $value)
 
+
+proc MapLeftRightKeys(key: INT, lparam: LPARAM): INT =
+  case key
+  of VK_SHIFT:
+    MapVirtualKey(UINT((lParam and 0x00ff0000) shr 16), MAPVK_VSC_TO_VK_EX)
+  of VK_CONTROL:
+    if (lParam and 0x01000000) == 0: VK_LCONTROL else: VK_RCONTROL
+  of VK_MENU:
+    if (lParam and 0x01000000) == 0: VK_LMENU else: VK_RMENU
+  else:
+    key
+
 proc WindowHandler(hwnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM): LRESULT {.stdcall.} =
   case uMsg
   of WM_DESTROY:
     currentEvents.add(Event(eventType: events.EventType.Quit))
+  of WM_KEYDOWN, WM_SYSKEYDOWN:
+    let key = MapLeftRightKeys(INT(wParam), lParam)
+    currentEvents.add(Event(eventType: KeyPressed, key: KeyTypeMap.getOrDefault(key, Key.UNKNOWN)))
+  of WM_KEYUP, WM_SYSKEYUP:
+    let key = MapLeftRightKeys(INT(wParam), lParam)
+    currentEvents.add(Event(eventType: KeyReleased, key: KeyTypeMap.getOrDefault(key, Key.UNKNOWN)))
+  of WM_LBUTTONDOWN:
+    currentEvents.add(Event(eventType: MousePressed, button: MouseButton.Mouse1))
+  of WM_LBUTTONUP:
+    currentEvents.add(Event(eventType: MouseReleased, button: MouseButton.Mouse1))
+  of WM_MBUTTONDOWN:
+    currentEvents.add(Event(eventType: MousePressed, button: MouseButton.Mouse2))
+  of WM_MBUTTONUP:
+    currentEvents.add(Event(eventType: MouseReleased, button: MouseButton.Mouse2))
+  of WM_RBUTTONDOWN:
+    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: events.MouseMoved, x: GET_X_LPARAM(lParam), y: GET_Y_LPARAM(lParam)))
   else:
     return DefWindowProc(hwnd, uMsg, wParam, lParam)
 
@@ -49,7 +83,8 @@
       nil
     )
 
-  discard ShowWindow(result.hwnd, 1)
+  discard ShowWindow(result.hwnd, SW_SHOW)
+  discard ShowCursor(false)
 
 proc trash*(window: NativeWindow) =
   discard
@@ -60,8 +95,10 @@
   (int(rect.right - rect.left), int(rect.bottom - rect.top))
 
 proc pendingEvents*(window: NativeWindow): seq[Event] =
+  # empty queue
   currentEvents = newSeq[Event]()
   var msg: MSG
+  # fill queue
   while PeekMessage(addr(msg), window.hwnd, 0, 0, PM_REMOVE):
     DispatchMessage(addr(msg))
   return currentEvents