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 |