Mercurial > games > semicongine
view semicongine/input.nim @ 1364:8f774d9c2518 default tip
fix: change implementation to allow for easier reload of whole engine
author | sam <sam@basx.dev> |
---|---|
date | Tue, 05 Nov 2024 23:28:25 +0700 |
parents | 966032c7a3aa |
children |
line wrap: on
line source
import std/strutils import std/tables import ./core import ./events import ./rendering import ./storage type Input = object keyIsDown: set[Key] keyWasPressed: set[Key] keyWasReleased: set[Key] mouseIsDown: set[MouseButton] mouseWasPressed: set[MouseButton] mouseWasReleased: set[MouseButton] mousePosition: Vec2i mouseMove: Vec2i mouseWheel: float32 windowWasResized: bool = true windowIsMinimized: bool = false lockMouse: bool = false hasFocus: bool = false # warning, shit is not thread safe var input = Input() proc updateInputs*(): bool = # reset input states input.keyWasPressed = {} input.keyWasReleased = {} input.mouseWasPressed = {} input.mouseWasReleased = {} input.mouseWheel = 0 input.mouseMove = vec2i(0, 0) input.windowWasResized = false let newMousePos = getMousePosition(vulkan.window) 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(): case event.eventType of Quit: killed = true of ResizedWindow: input.windowWasResized = true of KeyPressed: input.keyWasPressed.incl event.key input.keyIsDown.incl event.key of KeyReleased: input.keyWasReleased.incl event.key input.keyIsDown.excl event.key of MousePressed: input.mouseWasPressed.incl event.button input.mouseIsDown.incl event.button of MouseReleased: input.mouseWasReleased.incl event.button input.mouseIsDown.excl event.button of MouseWheel: input.mouseWheel = event.amount of MinimizedWindow: input.windowIsMinimized = true of RestoredWindow: input.windowIsMinimized = false of GotFocus: input.hasFocus = true of LostFocus: input.hasFocus = false return not killed proc keyIsDown*(key: Key): bool = key in input.keyIsDown proc keyWasPressed*(key: Key): bool = key in input.keyWasPressed proc keyWasPressed*(): bool = input.keyWasPressed.len > 0 proc keyWasReleased*(key: Key): bool = key in input.keyWasReleased proc mouseIsDown*(button: MouseButton): bool = button in input.mouseIsDown proc mouseWasPressed*(): bool = input.mouseWasPressed.len > 0 proc mouseWasPressed*(button: MouseButton): bool = button in input.mouseWasPressed proc mousePressedButtons*(): set[MouseButton] = input.mouseWasPressed proc mouseWasReleased*(): bool = input.mouseWasReleased.len > 0 proc mouseWasReleased*(button: MouseButton): bool = button in input.mouseWasReleased proc mouseReleasedButtons*(): set[MouseButton] = input.mouseWasReleased proc mousePositionPixel*(): Vec2i = input.mousePosition proc mousePosition*(): Vec2f = result = input.mousePosition.f32 / vulkan.window.size().f32 * 2.0'f32 - 1.0'f32 result.y = result.y * -1 proc mouseMove*(): Vec2i = input.mouseMove proc mouseWheel*(): float32 = input.mouseWheel proc windowWasResized*(): auto = input.windowWasResized proc windowIsMinimized*(): auto = input.windowIsMinimized proc lockMouse*(value: bool) = input.lockMouse = value proc hasFocus*(): bool = input.hasFocus # actions as a slight abstraction over raw input type ActionMap = object keyActions: Table[string, set[Key]] mouseActions: Table[string, set[MouseButton]] # warning, shit is not thread safe var actionMap: ActionMap proc mapAction*[T: enum](action: T, key: Key) = if not actionMap.keyActions.contains($action): actionMap.keyActions[$action] = {} actionMap.keyActions[$action].incl key proc mapAction*[T: enum](action: T, button: MouseButton) = if not actionMap.mouseActions.contains($action): actionMap.mouseActions[$action] = {} 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 actionMap.keyActions.contains($action): actionMap.keyActions[$action].excl(key) proc unmapAction*[T: enum](action: T, button: MouseButton) = if actionMap.mouseActions.contains($action): actionMap.mouseActions[$action].excl(button) proc unmapAction*[T: enum](action: T) = if actionMap.keyActions.contains($action): actionMap.keyActions[$action] = {} if actionMap.mouseActions.contains($action): actionMap.mouseActions[$action] = {} proc saveCurrentActionMapping*() = for name, keys in actionMap.keyActions.pairs: SystemStorage.store(name, keys, table = "input_mapping_key") for name, buttons in actionMap.mouseActions.pairs: SystemStorage.store(name, buttons, table = "input_mapping_mouse") proc loadActionMapping*[T]() = reset(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 actionMap.keyActions.contains($action): for key in actionMap.keyActions[$action]: if key in input.keyIsDown: return true return false if actionMap.mouseActions.contains($action): for button in actionMap.mouseActions[$action]: if button in input.mouseIsDown: return true return false proc actionPressed*[T](action: T): bool = if actionMap.keyActions.contains($action): for key in actionMap.keyActions[$action]: if key in input.keyWasPressed: return true elif actionMap.mouseActions.contains($action): for button in actionMap.mouseActions[$action]: if button in input.mouseWasPressed: return true proc actionReleased*[T](action: T): bool = if actionMap.keyActions.contains($action): for key in actionMap.keyActions[$action]: if key in input.keyWasReleased: return true elif actionMap.mouseActions.contains($action): for button in actionMap.mouseActions[$action]: if button in input.mouseWasReleased: return true proc actionValue*[T](action: T): float32 = if actionMap.keyActions.contains($action): for key in actionMap.keyActions[$action]: if key in input.keyIsDown: return 1 elif actionMap.mouseActions.contains($action): for button in actionMap.mouseActions[$action]: if button in input.mouseIsDown: return 1