Make sure g_timegetter is initalised before running speedtests
[oweals/minetest.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
25 class MyEventReceiver : public IEventReceiver
26 {
27 public:
28         // This is the one method that we have to implement
29         virtual bool OnEvent(const SEvent& event)
30         {
31                 /*
32                         React to nothing here if a menu is active
33                 */
34                 if (noMenuActive() == false) {
35 #ifdef HAVE_TOUCHSCREENGUI
36                         if (m_touchscreengui != 0) {
37                                 m_touchscreengui->Toggle(false);
38                         }
39 #endif
40                         return g_menumgr.preprocessEvent(event);
41                 }
42
43                 // Remember whether each key is down or up
44                 if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
45                         if (event.KeyInput.PressedDown) {
46                                 keyIsDown.set(event.KeyInput);
47                                 keyWasDown.set(event.KeyInput);
48                         } else {
49                                 keyIsDown.unset(event.KeyInput);
50                         }
51                 }
52
53 #ifdef HAVE_TOUCHSCREENGUI
54                 // case of touchscreengui we have to handle different events
55                 if ((m_touchscreengui != 0) &&
56                                 (event.EventType == irr::EET_TOUCH_INPUT_EVENT)) {
57                         m_touchscreengui->translateEvent(event);
58                         return true;
59                 }
60 #endif
61                 // handle mouse events
62                 if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) {
63                         if (noMenuActive() == false) {
64                                 left_active = false;
65                                 middle_active = false;
66                                 right_active = false;
67                         } else {
68                                 left_active = event.MouseInput.isLeftPressed();
69                                 middle_active = event.MouseInput.isMiddlePressed();
70                                 right_active = event.MouseInput.isRightPressed();
71
72                                 if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {
73                                         leftclicked = true;
74                                 }
75                                 if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) {
76                                         rightclicked = true;
77                                 }
78                                 if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) {
79                                         leftreleased = true;
80                                 }
81                                 if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) {
82                                         rightreleased = true;
83                                 }
84                                 if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) {
85                                         mouse_wheel += event.MouseInput.Wheel;
86                                 }
87                         }
88                 }
89                 if (event.EventType == irr::EET_LOG_TEXT_EVENT) {
90                         dstream << std::string("Irrlicht log: ") + std::string(event.LogEvent.Text)
91                                 << std::endl;
92                         return true;
93                 }
94                 /* always return false in order to continue processing events */
95                 return false;
96         }
97
98         bool IsKeyDown(const KeyPress &keyCode) const
99         {
100                 return keyIsDown[keyCode];
101         }
102
103         // Checks whether a key was down and resets the state
104         bool WasKeyDown(const KeyPress &keyCode)
105         {
106                 bool b = keyWasDown[keyCode];
107                 if (b)
108                         keyWasDown.unset(keyCode);
109                 return b;
110         }
111
112         s32 getMouseWheel()
113         {
114                 s32 a = mouse_wheel;
115                 mouse_wheel = 0;
116                 return a;
117         }
118
119         void clearInput()
120         {
121                 keyIsDown.clear();
122                 keyWasDown.clear();
123
124                 leftclicked = false;
125                 rightclicked = false;
126                 leftreleased = false;
127                 rightreleased = false;
128
129                 left_active = false;
130                 middle_active = false;
131                 right_active = false;
132
133                 mouse_wheel = 0;
134         }
135
136         MyEventReceiver()
137         {
138                 clearInput();
139 #ifdef HAVE_TOUCHSCREENGUI
140                 m_touchscreengui = NULL;
141 #endif
142         }
143
144         bool leftclicked;
145         bool rightclicked;
146         bool leftreleased;
147         bool rightreleased;
148
149         bool left_active;
150         bool middle_active;
151         bool right_active;
152
153         s32 mouse_wheel;
154
155 #ifdef HAVE_TOUCHSCREENGUI
156         TouchScreenGUI* m_touchscreengui;
157 #endif
158
159 private:
160         // The current state of keys
161         KeyList keyIsDown;
162         // Whether a key has been pressed or not
163         KeyList keyWasDown;
164 };
165
166
167 /*
168         Separated input handler
169 */
170
171 class RealInputHandler : public InputHandler
172 {
173 public:
174         RealInputHandler(IrrlichtDevice *device, MyEventReceiver *receiver):
175                 m_device(device),
176                 m_receiver(receiver),
177                 m_mousepos(0,0)
178         {
179         }
180         virtual bool isKeyDown(const KeyPress &keyCode)
181         {
182                 return m_receiver->IsKeyDown(keyCode);
183         }
184         virtual bool wasKeyDown(const KeyPress &keyCode)
185         {
186                 return m_receiver->WasKeyDown(keyCode);
187         }
188         virtual v2s32 getMousePos()
189         {
190                 if (m_device->getCursorControl()) {
191                         return m_device->getCursorControl()->getPosition();
192                 }
193                 else {
194                         return m_mousepos;
195                 }
196         }
197         virtual void setMousePos(s32 x, s32 y)
198         {
199                 if (m_device->getCursorControl()) {
200                         m_device->getCursorControl()->setPosition(x, y);
201                 }
202                 else {
203                         m_mousepos = v2s32(x,y);
204                 }
205         }
206
207         virtual bool getLeftState()
208         {
209                 return m_receiver->left_active;
210         }
211         virtual bool getRightState()
212         {
213                 return m_receiver->right_active;
214         }
215
216         virtual bool getLeftClicked()
217         {
218                 return m_receiver->leftclicked;
219         }
220         virtual bool getRightClicked()
221         {
222                 return m_receiver->rightclicked;
223         }
224         virtual void resetLeftClicked()
225         {
226                 m_receiver->leftclicked = false;
227         }
228         virtual void resetRightClicked()
229         {
230                 m_receiver->rightclicked = false;
231         }
232
233         virtual bool getLeftReleased()
234         {
235                 return m_receiver->leftreleased;
236         }
237         virtual bool getRightReleased()
238         {
239                 return m_receiver->rightreleased;
240         }
241         virtual void resetLeftReleased()
242         {
243                 m_receiver->leftreleased = false;
244         }
245         virtual void resetRightReleased()
246         {
247                 m_receiver->rightreleased = false;
248         }
249
250         virtual s32 getMouseWheel()
251         {
252                 return m_receiver->getMouseWheel();
253         }
254
255         void clear()
256         {
257                 m_receiver->clearInput();
258         }
259 private:
260         IrrlichtDevice  *m_device;
261         MyEventReceiver *m_receiver;
262         v2s32           m_mousepos;
263 };
264
265 class RandomInputHandler : public InputHandler
266 {
267 public:
268         RandomInputHandler()
269         {
270                 leftdown = false;
271                 rightdown = false;
272                 leftclicked = false;
273                 rightclicked = false;
274                 leftreleased = false;
275                 rightreleased = false;
276                 keydown.clear();
277         }
278         virtual bool isKeyDown(const KeyPress &keyCode)
279         {
280                 return keydown[keyCode];
281         }
282         virtual bool wasKeyDown(const KeyPress &keyCode)
283         {
284                 return false;
285         }
286         virtual v2s32 getMousePos()
287         {
288                 return mousepos;
289         }
290         virtual void setMousePos(s32 x, s32 y)
291         {
292                 mousepos = v2s32(x, y);
293         }
294
295         virtual bool getLeftState()
296         {
297                 return leftdown;
298         }
299         virtual bool getRightState()
300         {
301                 return rightdown;
302         }
303
304         virtual bool getLeftClicked()
305         {
306                 return leftclicked;
307         }
308         virtual bool getRightClicked()
309         {
310                 return rightclicked;
311         }
312         virtual void resetLeftClicked()
313         {
314                 leftclicked = false;
315         }
316         virtual void resetRightClicked()
317         {
318                 rightclicked = false;
319         }
320
321         virtual bool getLeftReleased()
322         {
323                 return leftreleased;
324         }
325         virtual bool getRightReleased()
326         {
327                 return rightreleased;
328         }
329         virtual void resetLeftReleased()
330         {
331                 leftreleased = false;
332         }
333         virtual void resetRightReleased()
334         {
335                 rightreleased = false;
336         }
337
338         virtual s32 getMouseWheel()
339         {
340                 return 0;
341         }
342
343         virtual void step(float dtime)
344         {
345                 {
346                         static float counter1 = 0;
347                         counter1 -= dtime;
348                         if (counter1 < 0.0) {
349                                 counter1 = 0.1 * Rand(1, 40);
350                                 keydown.toggle(getKeySetting("keymap_jump"));
351                         }
352                 }
353                 {
354                         static float counter1 = 0;
355                         counter1 -= dtime;
356                         if (counter1 < 0.0) {
357                                 counter1 = 0.1 * Rand(1, 40);
358                                 keydown.toggle(getKeySetting("keymap_special1"));
359                         }
360                 }
361                 {
362                         static float counter1 = 0;
363                         counter1 -= dtime;
364                         if (counter1 < 0.0) {
365                                 counter1 = 0.1 * Rand(1, 40);
366                                 keydown.toggle(getKeySetting("keymap_forward"));
367                         }
368                 }
369                 {
370                         static float counter1 = 0;
371                         counter1 -= dtime;
372                         if (counter1 < 0.0) {
373                                 counter1 = 0.1 * Rand(1, 40);
374                                 keydown.toggle(getKeySetting("keymap_left"));
375                         }
376                 }
377                 {
378                         static float counter1 = 0;
379                         counter1 -= dtime;
380                         if (counter1 < 0.0) {
381                                 counter1 = 0.1 * Rand(1, 20);
382                                 mousespeed = v2s32(Rand(-20, 20), Rand(-15, 20));
383                         }
384                 }
385                 {
386                         static float counter1 = 0;
387                         counter1 -= dtime;
388                         if (counter1 < 0.0) {
389                                 counter1 = 0.1 * Rand(1, 30);
390                                 leftdown = !leftdown;
391                                 if (leftdown)
392                                         leftclicked = true;
393                                 if (!leftdown)
394                                         leftreleased = true;
395                         }
396                 }
397                 {
398                         static float counter1 = 0;
399                         counter1 -= dtime;
400                         if (counter1 < 0.0) {
401                                 counter1 = 0.1 * Rand(1, 15);
402                                 rightdown = !rightdown;
403                                 if (rightdown)
404                                         rightclicked = true;
405                                 if (!rightdown)
406                                         rightreleased = true;
407                         }
408                 }
409                 mousepos += mousespeed;
410         }
411
412         s32 Rand(s32 min, s32 max)
413         {
414                 return (myrand()%(max-min+1))+min;
415         }
416 private:
417         KeyList keydown;
418         v2s32 mousepos;
419         v2s32 mousespeed;
420         bool leftdown;
421         bool rightdown;
422         bool leftclicked;
423         bool rightclicked;
424         bool leftreleased;
425         bool rightreleased;
426 };
427
428 #endif