Zen 0.3.0
Loading...
Searching...
No Matches
ZEN_Event.cpp
1#include <zen/events/ZEN_Event.h>
2
3namespace Zen {
4
5 static ZenEvent TranslateWindowEvent(const SDL_Event &e) {
6 ZenEvent event{};
7 event.header.category = EventCategory::Application;
8
9 switch (e.type) {
10 case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
11 event.header.type = EventType::WindowClose;
12 break;
13
14 case SDL_EVENT_WINDOW_RESIZED:
15 event.header.type = EventType::WindowResize;
16 event.windowResize.width = e.window.data1;
17 event.windowResize.height = e.window.data2;
18 break;
19
20 case SDL_EVENT_WINDOW_FOCUS_GAINED:
21 event.header.type = EventType::WindowFocus;
22 break;
23
24 case SDL_EVENT_WINDOW_FOCUS_LOST:
25 event.header.type = EventType::WindowLostFocus;
26 break;
27
28 case SDL_EVENT_WINDOW_MOVED:
29 event.header.type = EventType::WindowMoved;
30 event.windowMoved.x = e.window.data1;
31 event.windowMoved.y = e.window.data2;
32 break;
33
34 default:
35 event.header.type = EventType::None;
36 break;
37 }
38
39 return event;
40 }
41
42 static ZenEvent TranslateKeyEvent(const SDL_Event &e) {
43 ZenEvent event{};
44 event.header.category = EventCategory::Input | EventCategory::Keyboard;
45
46 if (e.type == SDL_EVENT_KEY_DOWN) {
47 event.header.type = EventType::KeyPressed;
48 event.key.repeat = e.key.repeat;
49 } else {
50 event.header.type = EventType::KeyReleased;
51 }
52
53 event.key.scancode = e.key.scancode;
54 event.key.mods = mapSDLMods(e.key.mod);
55
56 return event;
57 }
58
59 static ZenEvent TranslateMouseEvent(const SDL_Event &e) {
60 ZenEvent event{};
61 event.header.category = EventCategory::Input | EventCategory::Mouse;
62
63 switch (e.type) {
64 case SDL_EVENT_MOUSE_MOTION:
65 event.header.type = EventType::MouseMoved;
66 event.mouseMove.state = mapSDLMouseStates(e.motion.state);
67 event.mouseMove.x = e.motion.x;
68 event.mouseMove.y = e.motion.y;
69 event.mouseMove.dx = e.motion.xrel;
70 event.mouseMove.dy = e.motion.yrel;
71 break;
72
73 case SDL_EVENT_MOUSE_BUTTON_DOWN:
74 case SDL_EVENT_MOUSE_BUTTON_UP:
75 event.header.type = (e.type == SDL_EVENT_MOUSE_BUTTON_DOWN)
76 ? EventType::MouseButtonPressed
77 : EventType::MouseButtonReleased;
78
79 event.mouseButton.button = static_cast<MouseButton>(e.button.button);
80 event.mouseButton.clicks = e.button.clicks;
81 event.mouseButton.x = e.button.x;
82 event.mouseButton.y = e.button.y;
83 break;
84
85 case SDL_EVENT_MOUSE_WHEEL:
86 event.header.type = EventType::MouseScrolled;
87
88 event.mouseWheel.x = e.wheel.x;
89 event.mouseWheel.y = e.wheel.y;
90 event.mouseWheel.pos_x = e.wheel.mouse_x;
91 event.mouseWheel.pos_y = e.wheel.mouse_y;
92 event.mouseWheel.scrl_length = e.wheel.integer_x;
93 event.mouseWheel.scrl_height = e.wheel.integer_y;
94 break;
95
96 default:
97 event.header.type = EventType::None;
98 break;
99 }
100
101 return event;
102 }
103
104 static void *utf8_decode(void *buf, uint32_t *c, int *e) { // Thank you Chris Wellons
105 static const char lengths[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
106 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0};
107 static const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
108 static const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
109 static const int shiftc[] = {0, 18, 12, 6, 0};
110 static const int shifte[] = {0, 6, 4, 2, 0};
111
112 unsigned char *s = static_cast<unsigned char *>(buf);
113 ;
114 int len = static_cast<unsigned char>(lengths[s[0] >> 3]);
115
116 /* Compute the pointer to the next character early so that the next
117 * iteration can start working on the next character. Neither Clang
118 * nor GCC figure out this reordering on their own.
119 */
120 unsigned char *next = s + len + !len;
121
122 /* Assume a four-byte character and load four bytes. Unused bits are
123 * shifted out.
124 */
125 *c = (uint32_t)(s[0] & masks[len]) << 18;
126 *c |= (uint32_t)(s[1] & 0x3f) << 12;
127 *c |= (uint32_t)(s[2] & 0x3f) << 6;
128 *c |= (uint32_t)(s[3] & 0x3f) << 0;
129 *c >>= shiftc[len];
130
131 /* Accumulate the various error conditions. */
132 *e = (*c < mins[len]) << 6; // non-canonical encoding
133 *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half?
134 *e |= (*c > 0x10FFFF) << 8; // out of range?
135 *e |= (s[1] & 0xc0) >> 2;
136 *e |= (s[2] & 0xc0) >> 4;
137 *e |= (s[3]) >> 6;
138 *e ^= 0x2a; // top two bits of each tail byte correct?
139 *e >>= shifte[len];
140
141 return next;
142 }
143
144 static ZenEvent TranslateTextInputEvent(const SDL_Event &e) {
145 ZenEvent event{};
146 event.header.category = EventCategory::Input | EventCategory::Text;
147 event.header.type = EventType::TextInput;
148
149 uint32_t codepoint;
150 int error;
151
152 utf8_decode((void *)e.text.text, &codepoint, &error);
153 event.textInput.codepoint = (error ? U'\uFFFD' : static_cast<char32_t>(codepoint));
154 return event;
155 }
156
157 static ZenEvent TranslateApplicationEvent(const SDL_Event &e) {
158 ZenEvent event{};
159 event.header.category = EventCategory::Application;
160 event.header.type = EventType::Quit;
161
162 return event;
163 }
164
165 ZenEvent TranslateEvent(const SDL_Event &e) {
166 switch (e.type) {
167 case SDL_EVENT_QUIT:
168 return TranslateApplicationEvent(e);
169 case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
170 case SDL_EVENT_WINDOW_RESIZED:
171 case SDL_EVENT_WINDOW_FOCUS_GAINED:
172 case SDL_EVENT_WINDOW_FOCUS_LOST:
173 case SDL_EVENT_WINDOW_MOVED:
174 return TranslateWindowEvent(e);
175 case SDL_EVENT_KEY_DOWN:
176 case SDL_EVENT_KEY_UP:
177 return TranslateKeyEvent(e);
178 case SDL_EVENT_MOUSE_BUTTON_DOWN:
179 case SDL_EVENT_MOUSE_BUTTON_UP:
180 case SDL_EVENT_MOUSE_MOTION:
181 case SDL_EVENT_MOUSE_WHEEL:
182 return TranslateMouseEvent(e);
183 case SDL_EVENT_TEXT_INPUT:
184 return TranslateTextInputEvent(e);
185
186 default: {
187 ZenEvent event{};
188 event.header.type = EventType::None;
189 event.header.category = EventCategory::None;
190 return event;
191 }
192 }
193 }
194} // namespace Zen