Mana
Loading...
Searching...
No Matches
sdlinput.cpp
Go to the documentation of this file.
1/* _______ __ __ __ ______ __ __ _______ __ __
2 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
3 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
4 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
5 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
6 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
7 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
8 *
9 * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessén and Per Larsson
10 * Copyright (C) 2007-2010 The Mana World Development Team
11 * Copyright (C) 2010-2012 The Mana Developers
12 *
13 * Js_./
14 * Per Larsson a.k.a finalman _RqZ{a<^_aa
15 * Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
16 * _Qhm`] _f "'c 1!5m
17 * Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
18 * .)j(] .d_/ '-( P . S
19 * License: (BSD) <Td/Z <fP"5(\"??"\a. .L
20 * Redistribution and use in source and _dV>ws?a-?' ._/L #'
21 * binary forms, with or without )4d[#7r, . ' )d`)[
22 * modification, are permitted provided _Q-5'5W..j/?' -?!\‍)cam'
23 * that the following conditions are met: j<<WP+k/);. _W=j f
24 * 1. Redistributions of source code must .$%w\/]Q . ."' . mj$
25 * retain the above copyright notice, ]E.pYY(Q]>. a J@\
26 * this list of conditions and the j(]1u<sE"L,. . ./^ ]{a
27 * following disclaimer. 4'_uomm\. )L);-4 (3=
28 * 2. Redistributions in binary form must )_]X{Z('a_"a7'<a"a, ]"[
29 * reproduce the above copyright notice, #}<]m7`Za??4,P-"'7. ).m
30 * this list of conditions and the ]d2e)Q(<Q( ?94 b- LQ/
31 * following disclaimer in the <B!</]C)d_, '(<' .f. =C+m
32 * documentation and/or other materials .Z!=J ]e []('-4f _ ) -.)m]'
33 * provided with the distribution. .w[5]' _[ /.)_-"+? _/ <W"
34 * 3. Neither the name of Guichan nor the :$we` _! + _/ . j?
35 * names of its contributors may be used =3)= _f (_yQmWW$#( "
36 * to endorse or promote products derived - W, sQQQQmZQ#Wwa]..
37 * from this software without specific (js, \[QQW$QWW#?!V"".
38 * prior written permission. ]y:.<\.. .
39 * -]n w/ ' [.
40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT )/ )/ !
41 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY < (; sac , '
42 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, ]^ .- %
43 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF c < r
44 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR aga< <La
45 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5% )P'-3L
46 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR _bQf` y`..)a
47 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ,J?4P'.P"_(\?d'.,
48 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES _Pa,)!f/<[]/ ?"
49 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT _2-..:. .r+_,.. .
50 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ?a.<%"' " -'.a_ _,
51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ^
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
53 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
55 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
56 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 */
58
59#include "sdlinput.h"
60#include "graphics.h"
61
62#include <guichan/exception.hpp>
63
64SDLInput::SDLInput() = default;
65
67{
68 return mKeyInputQueue.empty();
69}
70
72{
73 gcn::KeyInput keyInput;
74
75 if (mKeyInputQueue.empty())
76 {
77 throw GCN_EXCEPTION("The queue is empty.");
78 }
79
80 keyInput = mKeyInputQueue.front();
81 mKeyInputQueue.pop();
82
83 return keyInput;
84}
85
87{
88 return mMouseInputQueue.empty();
89}
90
92{
93 gcn::MouseInput mouseInput;
94
95 if (mMouseInputQueue.empty())
96 {
97 throw GCN_EXCEPTION("The queue is empty.");
98 }
99
100 mouseInput = mMouseInputQueue.front();
101 mMouseInputQueue.pop();
102
103 return mouseInput;
104}
105
107{
108 return mTextInputQueue.empty();
109}
110
112{
113 if (mTextInputQueue.empty())
114 {
115 throw GCN_EXCEPTION("The queue is empty.");
116 }
117
118 TextInput textInput(mTextInputQueue.front());
119 mTextInputQueue.pop();
120 return textInput;
121}
122
123static void setMouseCoordinates(gcn::MouseInput &mouseInput, int x, int y)
124{
125 float logicalX;
126 float logicalY;
127 graphics->windowToLogical(x, y, logicalX, logicalY);
128 mouseInput.setX(static_cast<int>(logicalX));
129 mouseInput.setY(static_cast<int>(logicalY));
130}
131
132void SDLInput::pushInput(SDL_Event event)
133{
134 gcn::KeyInput keyInput;
135 gcn::MouseInput mouseInput;
136
137 switch (event.type)
138 {
139 case SDL_KEYDOWN:
140 keyInput.setKey(gcn::Key(convertKeyCharacter(event)));
141 keyInput.setType(gcn::KeyInput::PRESSED);
142 keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT);
143 keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL);
144 keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT);
145 keyInput.setMetaPressed(event.key.keysym.mod & KMOD_GUI);
146 keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP_0
147 && event.key.keysym.sym <= SDLK_KP_EQUALS);
148
149 mKeyInputQueue.push(keyInput);
150 break;
151
152 case SDL_KEYUP:
153 keyInput.setKey(gcn::Key(convertKeyCharacter(event)));
154 keyInput.setType(gcn::KeyInput::RELEASED);
155 keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT);
156 keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL);
157 keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT);
158 keyInput.setMetaPressed(event.key.keysym.mod & KMOD_GUI);
159 keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP_0
160 && event.key.keysym.sym <= SDLK_KP_EQUALS);
161
162 mKeyInputQueue.push(keyInput);
163 break;
164
165 case SDL_MOUSEBUTTONDOWN:
166 mMouseDown = true;
167 setMouseCoordinates(mouseInput, event.button.x, event.button.y);
168 mouseInput.setButton(convertMouseButton(event.button.button));
169 mouseInput.setType(gcn::MouseInput::PRESSED);
170 mouseInput.setTimeStamp(SDL_GetTicks());
171 mMouseInputQueue.push(mouseInput);
172 break;
173
174 case SDL_MOUSEBUTTONUP:
175 mMouseDown = false;
176 setMouseCoordinates(mouseInput, event.button.x, event.button.y);
177 mouseInput.setButton(convertMouseButton(event.button.button));
178 mouseInput.setType(gcn::MouseInput::RELEASED);
179 mouseInput.setTimeStamp(SDL_GetTicks());
180 mMouseInputQueue.push(mouseInput);
181 break;
182
183 case SDL_MOUSEMOTION:
184 setMouseCoordinates(mouseInput, event.button.x, event.button.y);
185 mouseInput.setButton(gcn::MouseInput::EMPTY);
186 mouseInput.setType(gcn::MouseInput::MOVED);
187 mouseInput.setTimeStamp(SDL_GetTicks());
188 mMouseInputQueue.push(mouseInput);
189 break;
190
191 case SDL_MOUSEWHEEL:
192 if (event.wheel.y) {
193#if SDL_VERSION_ATLEAST(2, 26, 0)
194 setMouseCoordinates(mouseInput, event.wheel.mouseX, event.wheel.mouseY);
195#else
196 int x, y;
197 SDL_GetMouseState(&x, &y);
198 setMouseCoordinates(mouseInput, x, y);
199#endif
200 mouseInput.setButton(gcn::MouseInput::EMPTY);
201 mouseInput.setType(event.wheel.y > 0 ? gcn::MouseInput::WHEEL_MOVED_UP
202 : gcn::MouseInput::WHEEL_MOVED_DOWN);
203 mouseInput.setTimeStamp(SDL_GetTicks());
204 mMouseInputQueue.push(mouseInput);
205 }
206 break;
207
208 case SDL_TEXTINPUT:
209 mTextInputQueue.emplace(event.text.text);
210 break;
211
212 // TODO_SDL2: This is now a window event
213 // case SDL_WINDOWEVENT:
214 // switch (event.window.event) {
215 // }
216 // break;
217#if 0
218 case SDL_ACTIVEEVENT:
219 /*
220 * This occurs when the mouse leaves the window and the Gui-chan
221 * application loses its mousefocus.
222 */
223 if ((event.active.state & SDL_APPMOUSEFOCUS)
224 && !event.active.gain)
225 {
226 if (!mMouseDown)
227 {
228 mouseInput.setX(-1);
229 mouseInput.setY(-1);
230 mouseInput.setButton(gcn::MouseInput::EMPTY);
231 mouseInput.setType(gcn::MouseInput::MOVED);
232 mMouseInputQueue.push(mouseInput);
233 }
234 }
235 break;
236#endif
237 } // end switch
238}
239
241{
242 switch (button)
243 {
244 case SDL_BUTTON_LEFT:
245 return gcn::MouseInput::LEFT;
246 case SDL_BUTTON_RIGHT:
247 return gcn::MouseInput::RIGHT;
248 case SDL_BUTTON_MIDDLE:
249 return gcn::MouseInput::MIDDLE;
250 default:
251 // We have an unknown mouse type which is ignored.
252 return button;
253 }
254}
255
257{
258 SDL_Keysym keysym = event.key.keysym;
259
260 int value = keysym.sym;
261
262 switch (keysym.sym)
263 {
264 case SDLK_TAB:
265 value = Key::TAB;
266 break;
267 case SDLK_LALT:
268 value = Key::LEFT_ALT;
269 break;
270 case SDLK_RALT:
271 value = Key::RIGHT_ALT;
272 break;
273 case SDLK_LSHIFT:
274 value = Key::LEFT_SHIFT;
275 break;
276 case SDLK_RSHIFT:
277 value = Key::RIGHT_SHIFT;
278 break;
279 case SDLK_LCTRL:
280 value = Key::LEFT_CONTROL;
281 break;
282 case SDLK_RCTRL:
283 value = Key::RIGHT_CONTROL;
284 break;
285 case SDLK_BACKSPACE:
286 value = Key::BACKSPACE;
287 break;
288 case SDLK_PAUSE:
289 value = Key::PAUSE;
290 break;
291 case SDLK_SPACE:
292 value = Key::SPACE;
293 break;
294 case SDLK_ESCAPE:
295 case SDLK_AC_BACK:
296 value = Key::ESCAPE;
297 break;
298 case SDLK_DELETE:
299 value = Key::DELETE_KEY;
300 break;
301 case SDLK_INSERT:
302 value = Key::INSERT;
303 break;
304 case SDLK_HOME:
305 value = Key::HOME;
306 break;
307 case SDLK_END:
308 value = Key::END;
309 break;
310 case SDLK_PAGEUP:
311 value = Key::PAGE_UP;
312 break;
313 case SDLK_PRINTSCREEN:
314 value = Key::PRINT_SCREEN;
315 break;
316 case SDLK_PAGEDOWN:
317 value = Key::PAGE_DOWN;
318 break;
319 case SDLK_F1:
320 value = Key::F1;
321 break;
322 case SDLK_F2:
323 value = Key::F2;
324 break;
325 case SDLK_F3:
326 value = Key::F3;
327 break;
328 case SDLK_F4:
329 value = Key::F4;
330 break;
331 case SDLK_F5:
332 value = Key::F5;
333 break;
334 case SDLK_F6:
335 value = Key::F6;
336 break;
337 case SDLK_F7:
338 value = Key::F7;
339 break;
340 case SDLK_F8:
341 value = Key::F8;
342 break;
343 case SDLK_F9:
344 value = Key::F9;
345 break;
346 case SDLK_F10:
347 value = Key::F10;
348 break;
349 case SDLK_F11:
350 value = Key::F11;
351 break;
352 case SDLK_F12:
353 value = Key::F12;
354 break;
355 case SDLK_F13:
356 value = Key::F13;
357 break;
358 case SDLK_F14:
359 value = Key::F14;
360 break;
361 case SDLK_F15:
362 value = Key::F15;
363 break;
364 case SDLK_NUMLOCKCLEAR:
365 value = Key::NUM_LOCK;
366 break;
367 case SDLK_CAPSLOCK:
368 value = Key::CAPS_LOCK;
369 break;
370 case SDLK_SCROLLLOCK:
371 value = Key::SCROLL_LOCK;
372 break;
373 case SDLK_RGUI:
374 value = Key::RIGHT_META;
375 break;
376 case SDLK_LGUI:
377 value = Key::LEFT_META;
378 break;
379 case SDLK_MODE:
380 value = Key::ALT_GR;
381 break;
382 case SDLK_UP:
383 value = Key::UP;
384 break;
385 case SDLK_DOWN:
386 value = Key::DOWN;
387 break;
388 case SDLK_LEFT:
389 value = Key::LEFT;
390 break;
391 case SDLK_RIGHT:
392 value = Key::RIGHT;
393 break;
394 case SDLK_RETURN:
395 value = Key::ENTER;
396 break;
397 case SDLK_KP_ENTER:
398 value = Key::ENTER;
399 break;
400
401 default:
402 break;
403 }
404
405 if (!(keysym.mod & KMOD_NUM))
406 {
407 switch (keysym.sym)
408 {
409 case SDLK_KP_0:
410 value = Key::INSERT;
411 break;
412 case SDLK_KP_1:
413 value = Key::END;
414 break;
415 case SDLK_KP_2:
416 value = Key::DOWN;
417 break;
418 case SDLK_KP_3:
419 value = Key::PAGE_DOWN;
420 break;
421 case SDLK_KP_4:
422 value = Key::LEFT;
423 break;
424 case SDLK_KP_5:
425 value = 0;
426 break;
427 case SDLK_KP_6:
428 value = Key::RIGHT;
429 break;
430 case SDLK_KP_7:
431 value = Key::HOME;
432 break;
433 case SDLK_KP_8:
434 value = Key::UP;
435 break;
436 case SDLK_KP_9:
437 value = Key::PAGE_UP;
438 break;
439 default:
440 break;
441 }
442 }
443
444 return value;
445}
virtual void windowToLogical(int windowX, int windowY, float &logicalX, float &logicalY) const =0
Converts a window coordinate to a logical coordinate.
static int convertKeyCharacter(SDL_Event event)
Converts an SDL event key to a key value.
Definition sdlinput.cpp:256
gcn::MouseInput dequeueMouseInput() override
Definition sdlinput.cpp:91
virtual void pushInput(SDL_Event event)
Pushes an SDL event.
Definition sdlinput.cpp:132
bool mMouseDown
Definition sdlinput.h:204
std::queue< gcn::KeyInput > mKeyInputQueue
Definition sdlinput.h:200
bool isMouseQueueEmpty() override
Definition sdlinput.cpp:86
bool isTextQueueEmpty() const
Definition sdlinput.cpp:106
std::queue< gcn::MouseInput > mMouseInputQueue
Definition sdlinput.h:201
TextInput dequeueTextInput()
Definition sdlinput.cpp:111
bool isKeyQueueEmpty() override
Definition sdlinput.cpp:66
static int convertMouseButton(int button)
Converts a mouse button from SDL to a Guichan mouse button representation.
Definition sdlinput.cpp:240
gcn::KeyInput dequeueKeyInput() override
Definition sdlinput.cpp:71
SDLInput()
Constructor.
std::queue< TextInput > mTextInputQueue
Definition sdlinput.h:202
Graphics * graphics
Definition client.cpp:104
@ LEFT_META
Definition sdlinput.h:86
@ F2
Definition sdlinput.h:100
@ F3
Definition sdlinput.h:101
@ ENTER
Definition sdlinput.h:78
@ PAUSE
Definition sdlinput.h:116
@ INSERT
Definition sdlinput.h:90
@ TAB
Definition sdlinput.h:77
@ F7
Definition sdlinput.h:105
@ SPACE
Definition sdlinput.h:76
@ LEFT
Definition sdlinput.h:119
@ PAGE_UP
Definition sdlinput.h:92
@ PRINT_SCREEN
Definition sdlinput.h:114
@ HOME
Definition sdlinput.h:91
@ RIGHT_SHIFT
Definition sdlinput.h:83
@ LEFT_CONTROL
Definition sdlinput.h:84
@ F10
Definition sdlinput.h:108
@ RIGHT
Definition sdlinput.h:120
@ LEFT_SHIFT
Definition sdlinput.h:82
@ F5
Definition sdlinput.h:103
@ UP
Definition sdlinput.h:121
@ F9
Definition sdlinput.h:107
@ ESCAPE
Definition sdlinput.h:96
@ F8
Definition sdlinput.h:106
@ BACKSPACE
Definition sdlinput.h:98
@ RIGHT_ALT
Definition sdlinput.h:81
@ F6
Definition sdlinput.h:104
@ SCROLL_LOCK
Definition sdlinput.h:115
@ DOWN
Definition sdlinput.h:122
@ LEFT_ALT
Definition sdlinput.h:80
@ F14
Definition sdlinput.h:112
@ RIGHT_CONTROL
Definition sdlinput.h:85
@ F1
Definition sdlinput.h:99
@ RIGHT_META
Definition sdlinput.h:87
@ F13
Definition sdlinput.h:111
@ F11
Definition sdlinput.h:109
@ CAPS_LOCK
Definition sdlinput.h:97
@ NUM_LOCK
Definition sdlinput.h:117
@ F15
Definition sdlinput.h:113
@ F12
Definition sdlinput.h:110
@ END
Definition sdlinput.h:94
@ ALT_GR
Definition sdlinput.h:118
@ F4
Definition sdlinput.h:102
@ DELETE_KEY
Definition sdlinput.h:93
@ PAGE_DOWN
Definition sdlinput.h:95