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