Mercurial > games > semicongine
annotate semiconginev2/input.nim @ 1256:bfb75c934f4e
add: window focus handling, improve window api a bit
| author | sam <sam@basx.dev> |
|---|---|
| date | Sun, 28 Jul 2024 17:33:41 +0700 |
| parents | b0f4c8ccd49a |
| children |
| rev | line source |
|---|---|
| 1199 | 1 type |
| 2 Input = object | |
| 3 keyIsDown: set[Key] | |
| 4 keyWasPressed: set[Key] | |
| 5 keyWasReleased: set[Key] | |
| 6 mouseIsDown: set[MouseButton] | |
| 7 mouseWasPressed: set[MouseButton] | |
| 8 mouseWasReleased: set[MouseButton] | |
| 9 mousePosition: Vec2f | |
| 10 mouseMove: Vec2f | |
| 11 mouseWheel: float32 | |
| 12 windowWasResized: bool = true | |
| 13 windowIsMinimized: bool = false | |
| 1254 | 14 lockMouse: bool = false |
|
1256
bfb75c934f4e
add: window focus handling, improve window api a bit
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
15 hasFocus: bool = false |
| 1199 | 16 |
| 17 # warning, shit is not thread safe | |
|
1256
bfb75c934f4e
add: window focus handling, improve window api a bit
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
18 var input = Input() |
| 1199 | 19 |
| 20 proc UpdateInputs*(): bool = | |
| 21 # reset input states | |
| 22 input.keyWasPressed = {} | |
| 23 input.keyWasReleased = {} | |
| 24 input.mouseWasPressed = {} | |
| 25 input.mouseWasReleased = {} | |
| 26 input.mouseWheel = 0 | |
| 27 input.mouseMove = NewVec2f() | |
| 28 input.windowWasResized = false | |
| 29 | |
|
1256
bfb75c934f4e
add: window focus handling, improve window api a bit
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
30 if input.lockMouse and input.hasFocus: |
| 1254 | 31 SetMousePosition(vulkan.window, x=int(vulkan.swapchain.width div 2), y=int(vulkan.swapchain.height div 2)) |
| 32 | |
| 1199 | 33 var killed = false |
| 34 for event in vulkan.window.PendingEvents(): | |
| 35 case event.eventType: | |
| 36 of Quit: | |
| 37 killed = true | |
| 38 of ResizedWindow: | |
| 39 input.windowWasResized = true | |
| 40 of KeyPressed: | |
| 41 input.keyWasPressed.incl event.key | |
| 42 input.keyIsDown.incl event.key | |
| 43 of KeyReleased: | |
| 44 input.keyWasReleased.incl event.key | |
| 45 input.keyIsDown.excl event.key | |
| 46 of MousePressed: | |
| 47 input.mouseWasPressed.incl event.button | |
| 48 input.mouseIsDown.incl event.button | |
| 49 of MouseReleased: | |
| 50 input.mouseWasReleased.incl event.button | |
| 51 input.mouseIsDown.excl event.button | |
| 52 of MouseMoved: | |
| 53 let newPos = NewVec2(float32(event.x), float32(event.y)) | |
| 54 input.mouseMove = newPos - input.mousePosition | |
| 55 input.mousePosition = newPos | |
| 56 of MouseWheel: | |
| 57 input.mouseWheel = event.amount | |
| 58 of MinimizedWindow: | |
| 59 input.windowIsMinimized = true | |
| 60 of RestoredWindow: | |
| 61 input.windowIsMinimized = false | |
|
1256
bfb75c934f4e
add: window focus handling, improve window api a bit
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
62 of GotFocus: |
|
bfb75c934f4e
add: window focus handling, improve window api a bit
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
63 input.hasFocus = true |
|
bfb75c934f4e
add: window focus handling, improve window api a bit
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
64 of LostFocus: |
|
bfb75c934f4e
add: window focus handling, improve window api a bit
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
65 input.hasFocus = false |
| 1199 | 66 |
| 67 return not killed | |
| 68 | |
| 69 proc KeyIsDown*(key: Key): bool = key in input.keyIsDown | |
| 70 proc KeyWasPressed*(key: Key): bool = key in input.keyWasPressed | |
| 71 proc KeyWasPressed*(): bool = input.keyWasPressed.len > 0 | |
| 72 proc KeyWasReleased*(key: Key): bool = key in input.keyWasReleased | |
| 73 proc MouseIsDown*(button: MouseButton): bool = button in input.mouseIsDown | |
| 74 proc MouseWasPressed*(): bool = input.mouseWasPressed.len > 0 | |
| 75 proc MouseWasPressed*(button: MouseButton): bool = button in input.mouseWasPressed | |
| 76 proc MousePressedButtons*(): set[MouseButton] = input.mouseWasPressed | |
| 77 proc MouseWasReleased*(): bool = input.mouseWasReleased.len > 0 | |
| 78 proc MouseWasReleased*(button: MouseButton): bool = button in input.mouseWasReleased | |
| 79 proc MouseReleasedButtons*(): set[MouseButton] = input.mouseWasReleased | |
| 80 proc MousePosition*(): Vec2f = input.mousePosition | |
| 81 proc MousePositionNormalized*(size: (int, int)): Vec2f = | |
| 82 result.x = (input.mousePosition.x / float32(size[0])) * 2.0 - 1.0 | |
| 83 result.y = (input.mousePosition.y / float32(size[1])) * 2.0 - 1.0 | |
| 1254 | 84 proc MouseMove*(): Vec2f = input.mouseMove |
| 85 proc MouseWheel*(): float32 = input.mouseWheel | |
| 1199 | 86 proc WindowWasResized*(): auto = input.windowWasResized |
| 87 proc WindowIsMinimized*(): auto = input.windowIsMinimized | |
| 1254 | 88 proc LockMouse*(value: bool) = input.lockMouse = value |
|
1256
bfb75c934f4e
add: window focus handling, improve window api a bit
sam <sam@basx.dev>
parents:
1254
diff
changeset
|
89 proc HasFocus*(): bool = input.hasFocus |
| 1254 | 90 |
| 1199 | 91 |
| 92 # actions as a slight abstraction over raw input | |
| 93 | |
| 94 type | |
| 95 ActionMap = object | |
| 96 keyActions: Table[string, set[Key]] | |
| 97 mouseActions: Table[string, set[MouseButton]] | |
| 98 | |
| 99 # warning, shit is not thread safe | |
| 100 var actionMap: ActionMap | |
| 101 | |
| 102 proc MapAction*[T: enum](action: T, key: Key) = | |
| 103 if not actionMap.keyActions.contains($action): | |
| 104 actionMap.keyActions[$action] = {} | |
| 105 actionMap.keyActions[$action].incl key | |
| 106 | |
| 107 proc MapAction*[T: enum](action: T, button: MouseButton) = | |
| 108 if not actionMap.mouseActions.contains($action): | |
| 109 actionMap.mouseActions[$action] = {} | |
| 110 actionMap.mouseActions[$action].incl button | |
| 111 | |
| 112 proc MapAction*[T: enum](action: T, keys: openArray[Key|MouseButton]) = | |
| 113 for key in keys: | |
| 114 MapAction(action, key) | |
| 115 | |
| 116 proc UnmapAction*[T: enum](action: T, key: Key) = | |
| 117 if actionMap.keyActions.contains($action): | |
| 118 actionMap.keyActions[$action].excl(key) | |
| 119 | |
| 120 proc UnmapAction*[T: enum](action: T, button: MouseButton) = | |
| 121 if actionMap.mouseActions.contains($action): | |
| 122 actionMap.mouseActions[$action].excl(button) | |
| 123 | |
| 124 proc UnmapAction*[T: enum](action: T) = | |
| 125 if actionMap.keyActions.contains($action): | |
| 126 actionMap.keyActions[$action] = {} | |
| 127 if actionMap.mouseActions.contains($action): | |
| 128 actionMap.mouseActions[$action] = {} | |
| 129 | |
| 130 proc SaveCurrentActionMapping*() = | |
| 131 for name, keys in actionMap.keyActions.pairs: | |
| 132 SystemStorage.Store(name, keys, table = "input_mapping_key") | |
| 133 for name, buttons in actionMap.mouseActions.pairs: | |
| 134 SystemStorage.Store(name, buttons, table = "input_mapping_mouse") | |
| 135 | |
| 136 proc LoadActionMapping*[T]() = | |
| 137 reset(actionMap) | |
| 138 for name in SystemStorage.List(table = "input_mapping_key"): | |
| 139 let action = parseEnum[T](name) | |
| 140 let keys = SystemStorage.Load(name, set[Key](), table = "input_mapping_key") | |
| 141 for key in keys: | |
| 142 MapAction(action, key) | |
| 143 | |
| 144 proc ActionDown*[T](action: T): bool = | |
| 145 if actionMap.keyActions.contains($action): | |
| 146 for key in actionMap.keyActions[$action]: | |
| 147 if key in input.keyIsDown: | |
| 148 return true | |
| 149 return false | |
| 150 if actionMap.mouseActions.contains($action): | |
| 151 for button in actionMap.mouseActions[$action]: | |
| 152 if button in input.mouseIsDown: | |
| 153 return true | |
| 154 return false | |
| 155 | |
| 156 proc ActionPressed*[T](action: T): bool = | |
| 157 if actionMap.keyActions.contains($action): | |
| 158 for key in actionMap.keyActions[$action]: | |
| 159 if key in input.keyWasPressed: | |
| 160 return true | |
| 161 elif actionMap.mouseActions.contains($action): | |
| 162 for button in actionMap.mouseActions[$action]: | |
| 163 if button in input.mouseWasPressed: | |
| 164 return true | |
| 165 | |
| 166 proc ActionReleased*[T](action: T): bool = | |
| 167 if actionMap.keyActions.contains($action): | |
| 168 for key in actionMap.keyActions[$action]: | |
| 169 if key in input.keyWasReleased: | |
| 170 return true | |
| 171 elif actionMap.mouseActions.contains($action): | |
| 172 for button in actionMap.mouseActions[$action]: | |
| 173 if button in input.mouseWasReleased: | |
| 174 return true | |
| 175 | |
| 176 proc ActionValue*[T](action: T): float32 = | |
| 177 if actionMap.keyActions.contains($action): | |
| 178 for key in actionMap.keyActions[$action]: | |
| 179 if key in input.keyIsDown: | |
| 180 return 1 | |
| 181 elif actionMap.mouseActions.contains($action): | |
| 182 for button in actionMap.mouseActions[$action]: | |
| 183 if button in input.mouseIsDown: | |
| 184 return 1 |
