Mercurial > games > semicongine
view semicongine/input.nim @ 1493:986e37dc76e0 default tip main
fix: storage API, some changes in new vulkan version
author | sam <sam@basx.dev> |
---|---|
date | Sun, 01 Jun 2025 21:57:13 +0700 |
parents | 9e27438ed96f |
children |
line wrap: on
line source
import std/strutils import std/unicode import std/tables import ./core import ./rendering import ./storage proc updateInputs*(readChars: bool = false): bool = # in order to prevent key-events to generate while the program # is reading text-input from the keyboard, set `readChars` to true # reset input states engine().input.keyWasPressed = {} engine().input.keyWasReleased = {} engine().input.mouseWasPressed = {} engine().input.mouseWasReleased = {} engine().input.mouseWheel = 0 engine().input.mouseMove = vec2i(0, 0) engine().input.windowWasResized = false engine().input.characterInput = default(Rune) let newMousePos = getMousePosition(engine().vulkan.window) engine().input.mouseMove = newMousePos - engine().input.mousePosition if engine().input.lockMouse and engine().input.hasFocus: engine().input.mousePosition = engine().vulkan.window.size div 2 setMousePosition(engine().vulkan.window, engine().input.mousePosition) else: engine().input.mousePosition = newMousePos proc isControlChar(r: Rune): bool = (0x00'i32 <= int32(r) and int32(r) <= 0x1F'i32) or int(r) == 0x7f var killed = false for event in engine().vulkan.window.pendingEvents(): case event.eventType of Quit: killed = true of ResizedWindow: engine().input.windowWasResized = true of KeyPressed: # exclude control characters for text input if not readChars or event.char.isControlChar(): engine().input.keyWasPressed.incl event.key engine().input.keyIsDown.incl event.key else: engine().input.characterInput = event.char of KeyReleased: if not readChars or event.char.isControlChar(): engine().input.keyWasReleased.incl event.key engine().input.keyIsDown.excl event.key of MousePressed: engine().input.mouseWasPressed.incl event.button engine().input.mouseIsDown.incl event.button of MouseReleased: engine().input.mouseWasReleased.incl event.button engine().input.mouseIsDown.excl event.button of MouseWheel: engine().input.mouseWheel = event.amount of MinimizedWindow: engine().input.windowIsMinimized = true of RestoredWindow: engine().input.windowIsMinimized = false of GotFocus: engine().input.hasFocus = true of LostFocus: engine().input.hasFocus = false return not killed proc keyIsDown*(key: Key): bool = key in engine().input.keyIsDown proc keyWasPressed*(key: Key): bool = key in engine().input.keyWasPressed proc keyWasPressed*(): bool = engine().input.keyWasPressed.len > 0 proc keyWasReleased*(key: Key): bool = key in engine().input.keyWasReleased proc characterInput*(): Rune = engine().input.characterInput proc mouseIsDown*(button: MouseButton): bool = button in engine().input.mouseIsDown proc mouseWasPressed*(): bool = engine().input.mouseWasPressed.len > 0 proc mouseWasPressed*(button: MouseButton): bool = button in engine().input.mouseWasPressed proc mousePressedButtons*(): set[MouseButton] = engine().input.mouseWasPressed proc mouseWasReleased*(): bool = engine().input.mouseWasReleased.len > 0 proc mouseWasReleased*(button: MouseButton): bool = button in engine().input.mouseWasReleased proc mouseReleasedButtons*(): set[MouseButton] = engine().input.mouseWasReleased proc mousePositionPixel*(): Vec2i = engine().input.mousePosition proc mousePosition*(): Vec2f = result = engine().input.mousePosition.f32 / engine().vulkan.window.size().f32 * 2.0'f32 - 1.0'f32 result.y = result.y * -1 proc mouseMove*(): Vec2i = engine().input.mouseMove proc mouseWheel*(): float32 = engine().input.mouseWheel proc windowWasResized*(): auto = engine().input.windowWasResized proc windowIsMinimized*(): auto = engine().input.windowIsMinimized proc lockMouse*(value: bool) = engine().input.lockMouse = value proc hasFocus*(): bool = engine().input.hasFocus # actions as a slight abstraction over raw input proc mapAction*[T: enum](action: T, key: Key) = if not engine().actionMap.keyActions.contains($action): engine().actionMap.keyActions[$action] = {} engine().actionMap.keyActions[$action].incl key proc mapAction*[T: enum](action: T, button: MouseButton) = if not engine().actionMap.mouseActions.contains($action): engine().actionMap.mouseActions[$action] = {} engine().actionMap.mouseActions[$action].incl button proc mapAction*[T: enum](action: T, keys: openArray[Key | MouseButton]) = for key in keys: mapAction(action, key) proc unmapAction*[T: enum](action: T, key: Key) = if engine().actionMap.keyActions.contains($action): engine().actionMap.keyActions[$action].excl(key) proc unmapAction*[T: enum](action: T, button: MouseButton) = if engine().actionMap.mouseActions.contains($action): engine().actionMap.mouseActions[$action].excl(button) proc unmapAction*[T: enum](action: T) = if engine().actionMap.keyActions.contains($action): engine().actionMap.keyActions[$action] = {} if engine().actionMap.mouseActions.contains($action): engine().actionMap.mouseActions[$action] = {} proc saveCurrentActionMapping*() = for name, keys in engine().actionMap.keyActions.pairs: SystemStorage.store(name, keys, table = "input_mapping_key") for name, buttons in engine().actionMap.mouseActions.pairs: SystemStorage.store(name, buttons, table = "input_mapping_mouse") proc loadActionMapping*[T]() = reset(engine().actionMap) for name in SystemStorage.List(table = "input_mapping_key"): let action = parseEnum[T](name) let keys = SystemStorage.Load(name, set[Key](), table = "input_mapping_key") for key in keys: mapAction(action, key) proc actionDown*[T](action: T): bool = if engine().actionMap.keyActions.contains($action): for key in engine().actionMap.keyActions[$action]: if key in engine().input.keyIsDown: return true return false if engine().actionMap.mouseActions.contains($action): for button in engine().actionMap.mouseActions[$action]: if button in engine().input.mouseIsDown: return true return false proc actionPressed*[T](action: T): bool = if engine().actionMap.keyActions.contains($action): for key in engine().actionMap.keyActions[$action]: if key in engine().input.keyWasPressed: return true elif engine().actionMap.mouseActions.contains($action): for button in engine().actionMap.mouseActions[$action]: if button in engine().input.mouseWasPressed: return true proc actionReleased*[T](action: T): bool = if engine().actionMap.keyActions.contains($action): for key in engine().actionMap.keyActions[$action]: if key in engine().input.keyWasReleased: return true elif engine().actionMap.mouseActions.contains($action): for button in engine().actionMap.mouseActions[$action]: if button in engine().input.mouseWasReleased: return true proc actionValue*[T](action: T): float32 = if engine().actionMap.keyActions.contains($action): for key in engine().actionMap.keyActions[$action]: if key in engine().input.keyIsDown: return 1 elif engine().actionMap.mouseActions.contains($action): for button in engine().actionMap.mouseActions[$action]: if button in engine().input.mouseIsDown: return 1