changeset 1233:1cf698973dca

did: cleanup tests and old platform layer files
author sam <sam@basx.dev>
date Fri, 19 Jul 2024 21:25:42 +0700
parents 32a977c71ba5
children 841e12f33c47
files semiconginev2/platform/linux/audio.nim semiconginev2/platform/linux/surface.nim semiconginev2/platform/linux/symkey_map.nim semiconginev2/platform/linux/vulkan_extensions.nim semiconginev2/platform/linux/window.nim semiconginev2/platform/surface.nim semiconginev2/platform/vulkan_extensions.nim semiconginev2/platform/window.nim semiconginev2/platform/windows/audio.nim semiconginev2/platform/windows/surface.nim semiconginev2/platform/windows/virtualkey_map.nim semiconginev2/platform/windows/vulkan_extensions.nim semiconginev2/platform/windows/window.nim semiconginev2/rendering.nim tests/test_rendering.nim
diffstat 15 files changed, 10 insertions(+), 549 deletions(-) [+]
line wrap: on
line diff
--- a/semiconginev2/platform/linux/audio.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-# alsa API
-type
-  OpenMode*{.size: sizeof(culong).} = enum
-    SND_PCM_BLOCK = 0x00000000 # added by semicongine, for clarity
-    SND_PCM_NONBLOCK = 0x00000001
-  StreamMode* {.size: sizeof(cint).} = enum
-    SND_PCM_STREAM_PLAYBACK = 0
-  AccessMode*{.size: sizeof(cint).} = enum
-    SND_PCM_ACCESS_RW_INTERLEAVED = 3
-  PCMFormat*{.size: sizeof(cint).} = enum
-    SND_PCM_FORMAT_S16_LE = 2
-  snd_pcm_p* = ptr object
-  snd_pcm_hw_params_p* = ptr object
-  snd_pcm_uframes_t* = culong
-  snd_pcm_sframes_t* = clong
-{.pragma: alsafunc, importc, cdecl, dynlib: "libasound.so.2".}
-proc snd_pcm_open*(pcm_ref: ptr snd_pcm_p, name: cstring, streamMode: StreamMode, openmode: OpenMode): cint {.alsafunc.}
-proc snd_pcm_close*(pcm: snd_pcm_p): cint {.alsafunc.}
-proc snd_pcm_hw_params_malloc*(hw_params_ptr: ptr snd_pcm_hw_params_p): cint {.alsafunc.}
-proc snd_pcm_hw_params_free*(hw_params: snd_pcm_hw_params_p) {.alsafunc.}
-proc snd_pcm_hw_params_any*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p): cint {.alsafunc.}
-proc snd_pcm_hw_params_set_access*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p, mode: AccessMode): cint {.alsafunc.}
-proc snd_pcm_hw_params_set_format*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p, format: PCMFormat): cint {.alsafunc.}
-proc snd_pcm_hw_params_set_channels*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p, val: cuint): cint {.alsafunc.}
-proc snd_pcm_hw_params_set_buffer_size*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p, size: snd_pcm_uframes_t): cint {.alsafunc.}
-proc snd_pcm_hw_params_set_rate*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p, val: cuint, dir: cint): cint {.alsafunc.}
-proc snd_pcm_hw_params*(pcm: snd_pcm_p, params: snd_pcm_hw_params_p): cint {.alsafunc.}
-proc snd_pcm_writei*(pcm: snd_pcm_p, buffer: pointer, size: snd_pcm_uframes_t): snd_pcm_sframes_t {.alsafunc.}
-proc snd_pcm_recover*(pcm: snd_pcm_p, err: cint, silent: cint): cint {.alsafunc.}
-
-template checkAlsaResult(call: untyped) =
-  let value = call
-  if value < 0:
-    raise newException(Exception, "Alsa error: " & astToStr(call) &
-      " returned " & $value)
-
-# required for engine:
-
-type
-  NativeSoundDevice* = object
-    handle: snd_pcm_p
-    buffers: seq[ptr SoundData]
-
-proc OpenSoundDevice*(sampleRate: uint32, buffers: seq[ptr SoundData]): NativeSoundDevice =
-  var hw_params: snd_pcm_hw_params_p = nil
-  checkAlsaResult snd_pcm_open(addr result.handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_BLOCK)
-
-  # hw parameters, quiet a bit of hardcoding here
-  checkAlsaResult snd_pcm_hw_params_malloc(addr hw_params)
-  checkAlsaResult snd_pcm_hw_params_any(result.handle, hw_params)
-  checkAlsaResult snd_pcm_hw_params_set_access(result.handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)
-  checkAlsaResult snd_pcm_hw_params_set_format(result.handle, hw_params, SND_PCM_FORMAT_S16_LE)
-  checkAlsaResult snd_pcm_hw_params_set_rate(result.handle, hw_params, sampleRate, 0)
-  checkAlsaResult snd_pcm_hw_params_set_channels(result.handle, hw_params, 2)
-  checkAlsaResult snd_pcm_hw_params_set_buffer_size(result.handle, hw_params, snd_pcm_uframes_t(buffers[0][].len))
-  checkAlsaResult snd_pcm_hw_params(result.handle, hw_params)
-  snd_pcm_hw_params_free(hw_params)
-  result.buffers = buffers
-
-proc WriteSoundData*(soundDevice: NativeSoundDevice, buffer: int) =
-  var ret = snd_pcm_writei(soundDevice.handle, addr soundDevice.buffers[buffer][][0], snd_pcm_uframes_t(soundDevice.buffers[buffer][].len))
-  if ret < 0:
-    checkAlsaResult snd_pcm_recover(soundDevice.handle, cint(ret), 0)
-
-proc CloseSoundDevice*(soundDevice: NativeSoundDevice) =
-  discard snd_pcm_close(soundDevice.handle)
--- a/semiconginev2/platform/linux/surface.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-proc CreateNativeSurface*(instance: VkInstance, window: NativeWindow): VkSurfaceKHR =
-  var surfaceCreateInfo = VkXlibSurfaceCreateInfoKHR(
-    sType: VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
-    dpy: cast[ptr Display](window.display),
-    window: cast[Window](window.window),
-  )
-  checkVkResult vkCreateXlibSurfaceKHR(instance, addr(surfaceCreateInfo), nil, addr(result))
--- a/semiconginev2/platform/linux/symkey_map.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-# got values (keycodes) from xev
-const KeyTypeMap* = {
-  9: Escape, 67: F1, 68: F2, 69: F3, 70: F4, 71: F5, 72: F6, 73: F7, 74: F8,
-  75: F9, 76: F10, 95: F11, 96: F12,
-  49: NumberRowExtra1, 10: `1`, 11: `2`, 12: `3`, 13: `4`, 14: `5`, 15: `6`,
-  16: `7`, 17: `8`, 18: `9`, 19: `0`, 20: NumberRowExtra2, 21: NumberRowExtra3,
-  24: Q, 25: W, 26: E, 27: R, 28: T, 29: Y, 30: U, 31: I, 32: O, 33: P, 38: A,
-  39: S, 40: D, 41: Key.F, 42: G, 43: H, 44: J, 45: K, 46: L, 52: Z, 53: X,
-  54: C, 55: V, 56: B, 57: N, 58: M,
-
-  23: Tab, 66: CapsLock, 50: ShiftL, 62: ShiftR, 37: CtrlL, 105: CtrlR,
-  133: SuperL, 134: SuperR,
-  64: AltL, 108: AltR,
-  65: Space, 36: Enter, 22: Backspace,
-  34: LetterRow1Extra1, 35: LetterRow1Extra2,
-  47: LetterRow2Extra1, 48: LetterRow2Extra2, 51: LetterRow2Extra3,
-  59: LetterRow3Extra1, 60: LetterRow3Extra2, 61: LetterRow3Extra3,
-  111: Up, 116: Down, 113: Left, 114: Right,
-  112: PageUp, 117: PageDown, 110: Home, 115: End, 118: Insert, 119: Delete,
-  107: PrintScreen, 78: ScrollLock, 127: Pause,
-}.toTable
-
-const MouseButtonTypeMap* = {
-  x11.Button1: MouseButton.Mouse1,
-  x11.Button2: MouseButton.Mouse2,
-  x11.Button3: MouseButton.Mouse3,
-}.toTable
--- a/semiconginev2/platform/linux/vulkan_extensions.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-const REQUIRED_PLATFORM_EXTENSIONS = @["VK_KHR_xlib_surface"]
--- a/semiconginev2/platform/linux/window.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-import ../../thirdparty/x11/xlib
-import ../../thirdparty/x11/xutil
-import ../../thirdparty/x11/keysym
-import ../../thirdparty/x11/x as x11
-import ../../thirdparty/x11/xkblib
-
-include ./symkey_map
-
-var deleteMessage*: Atom
-
-type
-  NativeWindow* = object
-    display*: ptr xlib.Display
-    window*: x11.Window
-    emptyCursor: Cursor
-
-template checkXlibResult(call: untyped) =
-  let value = call
-  if value == 0:
-    raise newException(Exception, "Xlib error: " & astToStr(call) &
-        " returned " & $value)
-
-proc XErrorLogger(display: PDisplay, event: PXErrorEvent): cint {.cdecl.} =
-  logging.error &"Xlib: {event[]}"
-
-proc CreateWindow*(title: string): NativeWindow =
-  checkXlibResult XInitThreads()
-  let display = XOpenDisplay(nil)
-  if display == nil:
-    quit "Failed to open display"
-  discard XSetErrorHandler(XErrorLogger)
-
-  let rootWindow = display.XDefaultRootWindow()
-  discard display.XkbSetDetectableAutoRepeat(true, nil)
-  var
-    attribs: XWindowAttributes
-    width = cuint(800)
-    height = cuint(600)
-  checkXlibResult display.XGetWindowAttributes(rootWindow, addr(attribs))
-
-  var attrs = XSetWindowAttributes()
-  let window = XCreateWindow(
-    display,
-    rootWindow,
-    (attribs.width - cint(width)) div 2, (attribs.height - cint(height)) div 2,
-    width, height,
-    0,
-    CopyFromParent,
-    InputOutput,
-    cast[PVisual](CopyFromParent),
-    0, # CWOverrideRedirect,
-    addr attrs,
-    # 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)
-  checkXlibResult XMapWindow(display, window)
-
-  deleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", XBool(false))
-  checkXlibResult XSetWMProtocols(display, window, addr(deleteMessage), 1)
-
-  var data = "\0".cstring
-  var pixmap = display.XCreateBitmapFromData(window, data, 1, 1)
-  var color: XColor
-  var empty_cursor = display.XCreatePixmapCursor(pixmap, pixmap, addr(color), addr(color), 0, 0)
-  checkXlibResult display.XFreePixmap(pixmap)
-  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)
-
-proc Fullscreen*(window: var NativeWindow, enable: bool) =
-  var
-    wm_state = window.display.XInternAtom("_NET_WM_STATE", 0)
-    wm_fullscreen = window.display.XInternAtom("_NET_WM_STATE_FULLSCREEN", 0)
-  var
-    xev: XEvent
-  xev.xclient = XClientMessageEvent(
-    message_type: wm_state,
-    format: 32,
-    window: window.window,
-    data: XClientMessageData(
-      l: [
-        int(not enable) xor 1,
-        clong(wm_fullscreen),
-        0,
-        0,
-        0
-    ]
-  )
-  )
-  xev.theType = ClientMessage
-
-  checkXlibResult window.display.XSendEvent(
-    window.display.DefaultRootWindow(),
-    0,
-    SubstructureRedirectMask or SubstructureNotifyMask,
-    addr xev
-  )
-  checkXlibResult window.display.XFlush()
-
-proc HideSystemCursor*(window: NativeWindow) =
-  checkXlibResult XDefineCursor(window.display, window.window, window.emptyCursor)
-  checkXlibResult window.display.XFlush()
-
-proc ShowSystemCursor*(window: NativeWindow) =
-  checkXlibResult XUndefineCursor(window.display, window.window)
-  checkXlibResult window.display.XFlush()
-
-proc Destroy*(window: NativeWindow) =
-  checkXlibResult window.display.XFreeCursor(window.emptyCursor)
-  checkXlibResult window.display.XDestroyWindow(window.window)
-  discard window.display.XCloseDisplay() # always returns 0
-
-proc Size*(window: NativeWindow): (int, int) =
-  var attribs: XWindowAttributes
-  checkXlibResult XGetWindowAttributes(window.display, window.window, addr(attribs))
-  return (int(attribs.width), int(attribs.height))
-
-proc PendingEvents*(window: NativeWindow): seq[Event] =
-  var event: XEvent
-  while window.display.XPending() > 0:
-    discard window.display.XNextEvent(addr(event))
-    case event.theType
-    of ClientMessage:
-      if cast[Atom](event.xclient.data.l[0]) == deleteMessage:
-        result.add(Event(eventType: Quit))
-    of KeyPress:
-      let keyevent = cast[PXKeyEvent](addr(event))
-      let xkey = int(keyevent.keycode)
-      result.add Event(eventType: KeyPressed, key: KeyTypeMap.getOrDefault(xkey, Key.UNKNOWN))
-    of KeyRelease:
-      let keyevent = cast[PXKeyEvent](addr(event))
-      let xkey = int(keyevent.keycode)
-      result.add Event(eventType: KeyReleased, key: KeyTypeMap.getOrDefault(xkey, Key.UNKNOWN))
-    of ButtonPress:
-      let button = int(cast[PXButtonEvent](addr(event)).button)
-      if button == Button4:
-        result.add Event(eventType: MouseWheel, amount: 1'f32)
-      elif button == Button5:
-        result.add Event(eventType: MouseWheel, amount: -1'f32)
-      else:
-        result.add Event(eventType: MousePressed, button: MouseButtonTypeMap.getOrDefault(button, MouseButton.UNKNOWN))
-    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))
-      result.add Event(eventType: MouseMoved, x: motion.x, y: motion.y)
-    of ConfigureNotify, Expose:
-      result.add Event(eventType: ResizedWindow)
-    else:
-      discard
-
-
-proc GetMousePosition*(window: NativeWindow): Option[Vec2f] =
-  var
-    root: x11.Window
-    win: x11.Window
-    rootX: cint
-    rootY: cint
-    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(Vec2f([float32(winX), float32(winY)]))
-
--- a/semiconginev2/platform/surface.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-when defined(linux):
-  include ./linux/surface
-elif defined(windows):
-  include ./windows/surface
-else:
-  {.error: "Unsupported platform".}
-
--- a/semiconginev2/platform/vulkan_extensions.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-when defined(linux):
-  include ./linux/vulkan_extensions
-elif defined(windows):
-  include ./windows/vulkan_extensions
-else:
-  {.error: "Unsupported platform".}
-
--- a/semiconginev2/platform/window.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-when defined(linux):
-  include ./linux/window
-elif defined(windows):
-  include ./windows/window
-else:
-  {.error: "Unsupported platform".}
-
--- a/semiconginev2/platform/windows/audio.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-include ./thirdparty/winim/winim/inc/mmsystem
-
-template CheckWinMMResult*(call: untyped) =
-  let value = call
-  if value < 0:
-    raise newException(Exception, "Windows multimedia error: " & astToStr(call) &
-      " returned " & $value)
-type
-  NativeSoundDevice* = object
-    handle: HWAVEOUT
-    buffers: seq[WAVEHDR]
-
-proc OpenSoundDevice*(sampleRate: uint32, buffers: seq[ptr SoundData]): NativeSoundDevice =
-  var format = WAVEFORMATEX(
-    wFormatTag: WAVE_FORMAT_PCM,
-    nChannels: 2,
-    nSamplesPerSec: DWORD(sampleRate),
-    nAvgBytesPerSec: DWORD(sampleRate) * 4,
-    nBlockAlign: 4,
-    wBitsPerSample: 16,
-    cbSize: 0,
-  )
-  CheckWinMMResult waveOutOpen(addr result.handle, WAVE_MAPPER, addr format, DWORD_PTR(0), DWORD_PTR(0), CALLBACK_NULL)
-
-  for i in 0 ..< buffers.len:
-    result.buffers.add WAVEHDR(
-      lpData: cast[cstring](addr buffers[i][][0]),
-      dwBufferLength: DWORD(buffers[i][].len * sizeof(Sample)),
-      dwLoops: 1,
-    )
-  for i in 0 ..< result.buffers.len:
-    CheckWinMMResult waveOutPrepareHeader(result.handle, addr result.buffers[i], UINT(sizeof(WAVEHDR)))
-    CheckWinMMResult waveOutWrite(result.handle, addr result.buffers[i], UINT(sizeof(WAVEHDR)))
-
-proc WriteSoundData*(soundDevice: var NativeSoundDevice, buffer: int) =
-  while (soundDevice.buffers[buffer].dwFlags and WHDR_DONE) == 0:
-    sleep(1)
-  CheckWinMMResult waveOutWrite(soundDevice.handle, addr soundDevice.buffers[buffer], UINT(sizeof(WAVEHDR)))
-
-proc CloseSoundDevice*(soundDevice: var NativeSoundDevice) =
-  for i in 0 ..< soundDevice.buffers.len:
-    discard waveOutUnprepareHeader(soundDevice.handle, addr soundDevice.buffers[i], UINT(sizeof(WAVEHDR)))
-  waveOutClose(soundDevice.handle)
--- a/semiconginev2/platform/windows/surface.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-proc CreateNativeSurface*(instance: VkInstance, window: NativeWindow): VkSurfaceKHR =
-  assert instance.Valid
-  var surfaceCreateInfo = VkWin32SurfaceCreateInfoKHR(
-    sType: VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
-    hinstance: cast[HINSTANCE](window.hinstance),
-    hwnd: cast[HWND](window.hwnd),
-  )
-  checkVkResult vkCreateWin32SurfaceKHR(instance, addr(surfaceCreateInfo), nil, addr(result))
--- a/semiconginev2/platform/windows/virtualkey_map.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-const KeyTypeMap* = {
-  VK_ESCAPE: Key.Escape, VK_F1: F1, VK_F2: F2, VK_F3: F3, VK_F4: F4, VK_F5: F5,
-  VK_F6: F6, VK_F7: F7, VK_F8: F8, VK_F9: F9, VK_F10: F10, VK_F11: F11,
-  VK_F12: F12,
-  VK_OEM_3: NumberRowExtra1, int('0'): `0`, int('1'): `1`, int('2'): `2`, int(
-      '3'): `3`, int('4'): `4`, int('5'): `5`, int('6'): `6`, int('7'): `7`,
-      int('8'): `8`, int('9'): `9`, VK_OEM_MINUS: NumberRowExtra2,
-      VK_OEM_PLUS: NumberRowExtra3,
-  int('A'): A, int('B'): B, int('C'): C, int('D'): D, int('E'): E, int('F'): F,
-      int('G'): G, int('H'): H, int('I'): I, int('J'): J, int('K'): K, int(
-      'L'): L, int('M'): M, int('N'): N, int('O'): O, int('P'): P, int('Q'): Q,
-      int('R'): R, int('S'): S, int('T'): T, int('U'): U, int('V'): V, int(
-      'W'): W, int('X'): X, int('Y'): Y, int('Z'): Z,
-  VK_TAB: Tab, VK_CAPITAL: CapsLock, VK_LSHIFT: ShiftL, VK_SHIFT: ShiftL,
-      VK_RSHIFT: ShiftR, VK_LCONTROL: CtrlL, VK_CONTROL: CtrlL,
-      VK_RCONTROL: CtrlR, VK_LWIN: SuperL, VK_RWIN: SuperR, VK_LMENU: AltL,
-      VK_RMENU: AltR, VK_SPACE: Space, VK_RETURN: Enter, VK_BACK: Backspace,
-  VK_OEM_4: LetterRow1Extra1, VK_OEM_6: LetterRow1Extra2,
-      VK_OEM_5: LetterRow2Extra3,
-  VK_OEM_1: LetterRow2Extra1, VK_OEM_7: LetterRow2Extra2,
-  VK_OEM_COMMA: LetterRow3Extra1, VK_OEM_PERIOD: LetterRow3Extra2,
-      VK_OEM_2: LetterRow3Extra3,
-    VK_UP: Up, VK_DOWN: Down, VK_LEFT: Left, VK_RIGHT: Right,
-    VK_PRIOR: PageUp, VK_NEXT: PageDown, VK_HOME: Home, VK_END: End,
-        VK_INSERT: Insert, VK_DELETE: Key.Delete,
-}.toTable
--- a/semiconginev2/platform/windows/vulkan_extensions.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-const REQUIRED_PLATFORM_EXTENSIONS = @["VK_KHR_win32_surface"]
--- a/semiconginev2/platform/windows/window.nim	Fri Jul 19 20:00:15 2024 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-import ../../thirdparty/winim/winim/inc/[windef, winuser, wincon, winbase]
-import ../../thirdparty/winim/winim/[winstr, utils]
-
-include ./virtualkey_map
-
-type
-  NativeWindow* = object
-    hinstance*: HINSTANCE
-    hwnd*: HWND
-    g_wpPrev: WINDOWPLACEMENT
-
-
-# sorry, have to use module-global variable to capture windows events
-var currentEvents: seq[Event]
-
-template CheckWin32Result*(call: untyped) =
-  let value = call
-  if value == 0:
-    raise newException(Exception, "Win32 error: " & astToStr(call) & " returned " & $value)
-
-let
-  andCursorMask = [0xff]
-  xorCursorMask = [0x00]
-  invisibleCursor = CreateCursor(0, 0, 0, 1, 1, pointer(addr andCursorMask), pointer(addr xorCursorMask))
-  defaultCursor = LoadCursor(0, IDC_ARROW)
-var currentCursor = defaultCursor
-
-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: 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: 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:
-    currentEvents.add(Event(eventType: ResizedWindow))
-  of WM_SIZE:
-    if wParam == SIZE_MINIMIZED:
-      currentEvents.add(Event(eventType: MinimizedWindow))
-    elif wParam == SIZE_RESTORED:
-      currentEvents.add(Event(eventType: RestoredWindow))
-  of WM_SETCURSOR:
-    if LOWORD(lParam) == HTCLIENT:
-      SetCursor(currentCursor)
-      return 1
-    else:
-      return DefWindowProc(hwnd, uMsg, wParam, lParam)
-  else:
-    return DefWindowProc(hwnd, uMsg, wParam, lParam)
-
-
-proc CreateWindow*(title: string): NativeWindow =
-  when DEBUG:
-    AllocConsole()
-    discard stdin.reopen("conIN$", fmRead)
-    discard stdout.reopen("conOUT$", fmWrite)
-    discard stderr.reopen("conOUT$", fmWrite)
-
-  result.hInstance = HINSTANCE(GetModuleHandle(nil))
-  var
-    windowClassName = T"EngineWindowClass"
-    windowName = T(title)
-    windowClass = WNDCLASSEX(
-      cbSize: UINT(WNDCLASSEX.sizeof),
-      lpfnWndProc: WindowHandler,
-      hInstance: result.hInstance,
-      lpszClassName: windowClassName,
-       hcursor: currentCursor,
-    )
-
-  if(RegisterClassEx(addr(windowClass)) == 0):
-    raise newException(Exception, "Unable to register window class")
-
-  result.hwnd = CreateWindowEx(
-      DWORD(0),
-      windowClassName,
-      windowName,
-      DWORD(WS_OVERLAPPEDWINDOW),
-      CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
-      HMENU(0),
-      HINSTANCE(0),
-      result.hInstance,
-      nil
-    )
-
-  result.g_wpPrev.length = UINT(sizeof(WINDOWPLACEMENT))
-  discard result.hwnd.ShowWindow(SW_SHOW)
-
-proc SetTitle*(window: NativeWindow, title: string) =
-  window.hwnd.SetWindowText(T(title))
-
-# inspired by the one and only, Raymond Chen
-# https://devblogs.microsoft.com/oldnewthing/20100412-00/?p=14353
-proc Fullscreen*(window: var NativeWindow, enable: bool) =
-  let dwStyle: DWORD = GetWindowLong(window.hwnd, GWL_STYLE)
-  if enable:
-    var mi = MONITORINFO(cbSize: DWORD(sizeof(MONITORINFO)))
-    if GetWindowPlacement(window.hwnd, addr window.g_wpPrev) and GetMonitorInfo(MonitorFromWindow(window.hwnd, MONITOR_DEFAULTTOPRIMARY), addr mi):
-      SetWindowLong(window.hwnd, GWL_STYLE, dwStyle and (not WS_OVERLAPPEDWINDOW))
-      SetWindowPos(window.hwnd, HWND_TOP, mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top, SWP_NOOWNERZORDER or SWP_FRAMECHANGED)
-  else:
-    SetWindowLong(window.hwnd, GWL_STYLE, dwStyle or WS_OVERLAPPEDWINDOW)
-    SetWindowPlacement(window.hwnd, addr window.g_wpPrev)
-    SetWindowPos(window.hwnd, HWND(0), 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_NOOWNERZORDER or SWP_FRAMECHANGED)
-
-proc HideSystemCursor*(window: NativeWindow) =
-  currentCursor = invisibleCursor
-  SetCursor(currentCursor)
-
-proc ShowSystemCursor*(window: NativeWindow) =
-  currentCursor = defaultCursor
-  SetCursor(currentCursor)
-
-proc Destroy*(window: NativeWindow) =
-  discard
-
-proc Size*(window: NativeWindow): (int, int) =
-  var rect: RECT
-  CheckWin32Result GetWindowRect(window.hwnd, addr(rect))
-  (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):
-    TranslateMessage(addr(msg))
-    DispatchMessage(addr(msg))
-  return currentEvents
-
-proc GetMousePosition*(window: NativeWindow): Option[Vec2f] =
-  var p: POINT
-  let res = GetCursorPos(addr(p))
-  if res:
-    return some(Vec2f([float32(p.x), float32(p.y)]))
-  return none(Vec2f)
--- a/semiconginev2/rendering.nim	Fri Jul 19 20:00:15 2024 +0700
+++ b/semiconginev2/rendering.nim	Fri Jul 19 21:25:42 2024 +0700
@@ -217,8 +217,6 @@
 
 proc InitVulkan*(appName: string = "semicongine app") =
 
-  include ./platform/vulkan_extensions # for REQUIRED_PLATFORM_EXTENSIONS
-
   # instance creation
 
   # enagle all kind of debug stuff
--- a/tests/test_rendering.nim	Fri Jul 19 20:00:15 2024 +0700
+++ b/tests/test_rendering.nim	Fri Jul 19 21:25:42 2024 +0700
@@ -1,3 +1,4 @@
+import std/os
 import std/sequtils
 import std/monotimes
 import std/times
@@ -416,13 +417,13 @@
   var t = tStart
   while UpdateInputs() and c < nFrames:
 
-    let t = getMonoTime() - tStart
+    let tStartLoop = getMonoTime() - tStart
 
     uniforms1.data.data.data.mvp = (
       Perspective(-PI / 2, GetAspectRatio(swapchain), 0.01, 100) *
       Translate(0, 0, 2) *
       Rotate(PI / 4, X) *
-      Rotate(PI * 0.5 * (t.inMicroseconds() / 1_000_000), Y)
+      Rotate(PI * 0.1 * (tStartLoop.inMicroseconds() / 1_000_000), Y)
     )
     UpdateGPUBuffer(uniforms1.data.data, flush = true)
     WithNextFrame(swapchain, framebuffer, commandbuffer):
@@ -431,6 +432,13 @@
           WithBind(commandbuffer, (uniforms1, ), pipeline, swapchain.currentFiF):
             Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = mesh)
             Render(commandbuffer = commandbuffer, pipeline = pipeline, mesh = floor)
+
+    let tEndLoop = getMonoTime() - tStart
+    let looptime = tEndLoop - tStartLoop
+    let waitTime = 16_666 - looptime.inMicroseconds
+    if waitTime > 0:
+      echo "sleep ", waitTime / 1000
+      sleep((waitTime / 1000).int)
     inc c
 
   # cleanup