Mercurial > games > semicongine
diff semiconginev2/input.nim @ 1218:56781cc0fc7c compiletime-tests
did: renamge main package
author | sam <sam@basx.dev> |
---|---|
date | Wed, 17 Jul 2024 21:01:37 +0700 |
parents | semicongine/input.nim@ba1af13233ee |
children | b0f4c8ccd49a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/semiconginev2/input.nim Wed Jul 17 21:01:37 2024 +0700 @@ -0,0 +1,172 @@ +type + Input = object + keyIsDown: set[Key] + keyWasPressed: set[Key] + keyWasReleased: set[Key] + mouseIsDown: set[MouseButton] + mouseWasPressed: set[MouseButton] + mouseWasReleased: set[MouseButton] + mousePosition: Vec2f + mouseMove: Vec2f + mouseWheel: float32 + windowWasResized: bool = true + windowIsMinimized: 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 = NewVec2f() + input.windowWasResized = false + + 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 MouseMoved: + let newPos = NewVec2(float32(event.x), float32(event.y)) + input.mouseMove = newPos - input.mousePosition + input.mousePosition = newPos + of MouseWheel: + input.mouseWheel = event.amount + of MinimizedWindow: + input.windowIsMinimized = true + of RestoredWindow: + input.windowIsMinimized = 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 MousePosition*(): Vec2f = input.mousePosition +proc MousePositionNormalized*(size: (int, int)): Vec2f = + result.x = (input.mousePosition.x / float32(size[0])) * 2.0 - 1.0 + result.y = (input.mousePosition.y / float32(size[1])) * 2.0 - 1.0 +proc MouseMove*(): auto = input.mouseMove +proc MouseWheel*(): auto = input.mouseWheel +proc WindowWasResized*(): auto = input.windowWasResized +proc WindowIsMinimized*(): auto = input.windowIsMinimized + +# 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