]> git.lizzy.rs Git - dragonfireclient.git/blob - src/client/inputhandler.h
Reorder TileLayer. (#5638)
[dragonfireclient.git] / src / client / inputhandler.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef INPUT_HANDLER_H
21 #define INPUT_HANDLER_H
22
23 #include "irrlichttypes_extrabloated.h"
24 #include "joystick_controller.h"
25
26 class MyEventReceiver : public IEventReceiver
27 {
28 public:
29         // This is the one method that we have to implement
30         virtual bool OnEvent(const SEvent& event)
31         {
32                 /*
33                         React to nothing here if a menu is active
34                 */
35                 if (noMenuActive() == false) {
36 #ifdef HAVE_TOUCHSCREENGUI
37                         if (m_touchscreengui != 0) {
38                                 m_touchscreengui->Toggle(false);
39                         }
40 #endif
41                         return g_menumgr.preprocessEvent(event);
42                 }
43
44                 // Remember whether each key is down or up
45                 if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
46                         const KeyPress &keyCode = event.KeyInput;
47                         if (keysListenedFor[keyCode]) {
48                                 if (event.KeyInput.PressedDown) {
49                                         keyIsDown.set(keyCode);
50                                         keyWasDown.set(keyCode);
51                                 } else {
52                                         keyIsDown.unset(keyCode);
53                                 }
54                                 return true;
55                         }
56                 }
57
58 #ifdef HAVE_TOUCHSCREENGUI
59                 // case of touchscreengui we have to handle different events
60                 if ((m_touchscreengui != 0) &&
61                                 (event.EventType == irr::EET_TOUCH_INPUT_EVENT)) {
62                         m_touchscreengui->translateEvent(event);
63                         return true;
64                 }
65 #endif
66
67                 if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) {
68                         /* TODO add a check like:
69                         if (event.JoystickEvent != joystick_we_listen_for)
70                                 return false;
71                         */
72                         return joystick->handleEvent(event.JoystickEvent);
73                 }
74                 // handle mouse events
75                 if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) {
76                         if (noMenuActive() == false) {
77                                 left_active = false;
78                                 middle_active = false;
79                                 right_active = false;
80                         } else {
81                                 left_active = event.MouseInput.isLeftPressed();
82                                 middle_active = event.MouseInput.isMiddlePressed();
83                                 right_active = event.MouseInput.isRightPressed();
84
85                                 if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
86                                         leftclicked = true;
87                                 }
88                                 if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) {
89                                         rightclicked = true;
90                                 }
91                                 if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) {
92                                         leftreleased = true;
93                                 }
94                                 if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) {
95                                         rightreleased = true;
96                                 }
97                                 if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) {
98                                         mouse_wheel += event.MouseInput.Wheel;
99                                 }
100                         }
101                 } else if (event.EventType == irr::EET_LOG_TEXT_EVENT) {
102                         static const LogLevel irr_loglev_conv[] = {
103                                 LL_VERBOSE, // ELL_DEBUG
104                                 LL_INFO,    // ELL_INFORMATION
105                                 LL_WARNING, // ELL_WARNING
106                                 LL_ERROR,   // ELL_ERROR
107                                 LL_NONE,    // ELL_NONE
108                         };
109                         assert(event.LogEvent.Level < ARRLEN(irr_loglev_conv));
110                         g_logger.log(irr_loglev_conv[event.LogEvent.Level],
111                                 std::string("Irrlicht: ") + (const char*) event.LogEvent.Text);
112                         return true;
113                 }
114                 /* always return false in order to continue processing events */
115                 return false;
116         }
117
118         bool IsKeyDown(const KeyPress &keyCode) const
119         {
120                 return keyIsDown[keyCode];
121         }
122
123         // Checks whether a key was down and resets the state
124         bool WasKeyDown(const KeyPress &keyCode)
125         {
126                 bool b = keyWasDown[keyCode];
127                 if (b)
128                         keyWasDown.unset(keyCode);
129                 return b;
130         }
131
132         void listenForKey(const KeyPress &keyCode)
133         {
134                 keysListenedFor.set(keyCode);
135         }
136         void dontListenForKeys()
137         {
138                 keysListenedFor.clear();
139         }
140
141         s32 getMouseWheel()
142         {
143                 s32 a = mouse_wheel;
144                 mouse_wheel = 0;
145                 return a;
146         }
147
148         void clearInput()
149         {
150                 keyIsDown.clear();
151                 keyWasDown.clear();
152
153                 leftclicked = false;
154                 rightclicked = false;
155                 leftreleased = false;
156                 rightreleased = false;
157
158                 left_active = false;
159                 middle_active = false;
160                 right_active = false;
161
162                 mouse_wheel = 0;
163         }
164
165         MyEventReceiver()
166         {
167                 clearInput();
168 #ifdef HAVE_TOUCHSCREENGUI
169                 m_touchscreengui = NULL;
170 #endif
171         }
172
173         bool leftclicked;
174         bool rightclicked;
175         bool leftreleased;
176         bool rightreleased;
177
178         bool left_active;
179         bool middle_active;
180         bool right_active;
181
182         s32 mouse_wheel;
183
184         JoystickController *joystick;
185
186 #ifdef HAVE_TOUCHSCREENGUI
187         TouchScreenGUI* m_touchscreengui;
188 #endif
189
190 private:
191         // The current state of keys
192         KeyList keyIsDown;
193         // Whether a key has been pressed or not
194         KeyList keyWasDown;
195         // List of keys we listen for
196         // TODO perhaps the type of this is not really
197         // performant as KeyList is designed for few but
198         // often changing keys, and keysListenedFor is expected
199         // to change seldomly but contain lots of keys.
200         KeyList keysListenedFor;
201 };
202
203
204 /*
205         Separated input handler
206 */
207
208 class RealInputHandler : public InputHandler
209 {
210 public:
211         RealInputHandler(IrrlichtDevice *device, MyEventReceiver *receiver):
212                 m_device(device),
213                 m_receiver(receiver),
214                 m_mousepos(0,0)
215         {
216                 m_receiver->joystick = &joystick;
217         }
218         virtual bool isKeyDown(const KeyPress &keyCode)
219         {
220                 return m_receiver->IsKeyDown(keyCode);
221         }
222         virtual bool wasKeyDown(const KeyPress &keyCode)
223         {
224                 return m_receiver->WasKeyDown(keyCode);
225         }
226         virtual void listenForKey(const KeyPress &keyCode)
227         {
228                 m_receiver->listenForKey(keyCode);
229         }
230         virtual void dontListenForKeys()
231         {
232                 m_receiver->dontListenForKeys();
233         }
234         virtual v2s32 getMousePos()
235         {
236                 if (m_device->getCursorControl()) {
237                         return m_device->getCursorControl()->getPosition();
238                 }
239                 else {
240                         return m_mousepos;
241                 }
242         }
243         virtual void setMousePos(s32 x, s32 y)
244         {
245                 if (m_device->getCursorControl()) {
246                         m_device->getCursorControl()->setPosition(x, y);
247                 }
248                 else {
249                         m_mousepos = v2s32(x,y);
250                 }
251         }
252
253         virtual bool getLeftState()
254         {
255                 return m_receiver->left_active;
256         }
257         virtual bool getRightState()
258         {
259                 return m_receiver->right_active;
260         }
261
262         virtual bool getLeftClicked()
263         {
264                 return m_receiver->leftclicked;
265         }
266         virtual bool getRightClicked()
267         {
268                 return m_receiver->rightclicked;
269         }
270         virtual void resetLeftClicked()
271         {
272                 m_receiver->leftclicked = false;
273         }
274         virtual void resetRightClicked()
275         {
276                 m_receiver->rightclicked = false;
277         }
278
279         virtual bool getLeftReleased()
280         {
281                 return m_receiver->leftreleased;
282         }
283         virtual bool getRightReleased()
284         {
285                 return m_receiver->rightreleased;
286         }
287         virtual void resetLeftReleased()
288         {
289                 m_receiver->leftreleased = false;
290         }
291         virtual void resetRightReleased()
292         {
293                 m_receiver->rightreleased = false;
294         }
295
296         virtual s32 getMouseWheel()
297         {
298                 return m_receiver->getMouseWheel();
299         }
300
301         void clear()
302         {
303                 joystick.clear();
304                 m_receiver->clearInput();
305         }
306 private:
307         IrrlichtDevice  *m_device;
308         MyEventReceiver *m_receiver;
309         v2s32           m_mousepos;
310 };
311
312 class RandomInputHandler : public InputHandler
313 {
314 public:
315         RandomInputHandler()
316         {
317                 leftdown = false;
318                 rightdown = false;
319                 leftclicked = false;
320                 rightclicked = false;
321                 leftreleased = false;
322                 rightreleased = false;
323                 keydown.clear();
324         }
325         virtual bool isKeyDown(const KeyPress &keyCode)
326         {
327                 return keydown[keyCode];
328         }
329         virtual bool wasKeyDown(const KeyPress &keyCode)
330         {
331                 return false;
332         }
333         virtual v2s32 getMousePos()
334         {
335                 return mousepos;
336         }
337         virtual void setMousePos(s32 x, s32 y)
338         {
339                 mousepos = v2s32(x, y);
340         }
341
342         virtual bool getLeftState()
343         {
344                 return leftdown;
345         }
346         virtual bool getRightState()
347         {
348                 return rightdown;
349         }
350
351         virtual bool getLeftClicked()
352         {
353                 return leftclicked;
354         }
355         virtual bool getRightClicked()
356         {
357                 return rightclicked;
358         }
359         virtual void resetLeftClicked()
360         {
361                 leftclicked = false;
362         }
363         virtual void resetRightClicked()
364         {
365                 rightclicked = false;
366         }
367
368         virtual bool getLeftReleased()
369         {
370                 return leftreleased;
371         }
372         virtual bool getRightReleased()
373         {
374                 return rightreleased;
375         }
376         virtual void resetLeftReleased()
377         {
378                 leftreleased = false;
379         }
380         virtual void resetRightReleased()
381         {
382                 rightreleased = false;
383         }
384
385         virtual s32 getMouseWheel()
386         {
387                 return 0;
388         }
389
390         virtual void step(float dtime)
391         {
392                 {
393                         static float counter1 = 0;
394                         counter1 -= dtime;
395                         if (counter1 < 0.0) {
396                                 counter1 = 0.1 * Rand(1, 40);
397                                 keydown.toggle(getKeySetting("keymap_jump"));
398                         }
399                 }
400                 {
401                         static float counter1 = 0;
402                         counter1 -= dtime;
403                         if (counter1 < 0.0) {
404                                 counter1 = 0.1 * Rand(1, 40);
405                                 keydown.toggle(getKeySetting("keymap_special1"));
406                         }
407                 }
408                 {
409                         static float counter1 = 0;
410                         counter1 -= dtime;
411                         if (counter1 < 0.0) {
412                                 counter1 = 0.1 * Rand(1, 40);
413                                 keydown.toggle(getKeySetting("keymap_forward"));
414                         }
415                 }
416                 {
417                         static float counter1 = 0;
418                         counter1 -= dtime;
419                         if (counter1 < 0.0) {
420                                 counter1 = 0.1 * Rand(1, 40);
421                                 keydown.toggle(getKeySetting("keymap_left"));
422                         }
423                 }
424                 {
425                         static float counter1 = 0;
426                         counter1 -= dtime;
427                         if (counter1 < 0.0) {
428                                 counter1 = 0.1 * Rand(1, 20);
429                                 mousespeed = v2s32(Rand(-20, 20), Rand(-15, 20));
430                         }
431                 }
432                 {
433                         static float counter1 = 0;
434                         counter1 -= dtime;
435                         if (counter1 < 0.0) {
436                                 counter1 = 0.1 * Rand(1, 30);
437                                 leftdown = !leftdown;
438                                 if (leftdown)
439                                         leftclicked = true;
440                                 if (!leftdown)
441                                         leftreleased = true;
442                         }
443                 }
444                 {
445                         static float counter1 = 0;
446                         counter1 -= dtime;
447                         if (counter1 < 0.0) {
448                                 counter1 = 0.1 * Rand(1, 15);
449                                 rightdown = !rightdown;
450                                 if (rightdown)
451                                         rightclicked = true;
452                                 if (!rightdown)
453                                         rightreleased = true;
454                         }
455                 }
456                 mousepos += mousespeed;
457         }
458
459         s32 Rand(s32 min, s32 max)
460         {
461                 return (myrand()%(max-min+1))+min;
462         }
463 private:
464         KeyList keydown;
465         v2s32 mousepos;
466         v2s32 mousespeed;
467         bool leftdown;
468         bool rightdown;
469         bool leftclicked;
470         bool rightclicked;
471         bool leftreleased;
472         bool rightreleased;
473 };
474
475 #endif