]> git.lizzy.rs Git - dragonfireclient.git/blob - src/client/inputhandler.h
Network cleanup (#6302)
[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 #pragma once
21
22 #include "irrlichttypes_extrabloated.h"
23 #include "joystick_controller.h"
24 #include <list>
25 #include "keycode.h"
26 #include "renderingengine.h"
27
28 #ifdef HAVE_TOUCHSCREENGUI
29 #include "touchscreengui.h"
30 #endif
31
32 class KeyList : private std::list<KeyPress>
33 {
34         typedef std::list<KeyPress> super;
35         typedef super::iterator iterator;
36         typedef super::const_iterator const_iterator;
37
38         virtual const_iterator find(const KeyPress &key) const
39         {
40                 const_iterator f(begin());
41                 const_iterator e(end());
42
43                 while (f != e) {
44                         if (*f == key)
45                                 return f;
46
47                         ++f;
48                 }
49
50                 return e;
51         }
52
53         virtual iterator find(const KeyPress &key)
54         {
55                 iterator f(begin());
56                 iterator e(end());
57
58                 while (f != e) {
59                         if (*f == key)
60                                 return f;
61
62                         ++f;
63                 }
64
65                 return e;
66         }
67
68 public:
69         void clear() { super::clear(); }
70
71         void set(const KeyPress &key)
72         {
73                 if (find(key) == end())
74                         push_back(key);
75         }
76
77         void unset(const KeyPress &key)
78         {
79                 iterator p(find(key));
80
81                 if (p != end())
82                         erase(p);
83         }
84
85         void toggle(const KeyPress &key)
86         {
87                 iterator p(this->find(key));
88
89                 if (p != end())
90                         erase(p);
91                 else
92                         push_back(key);
93         }
94
95         bool operator[](const KeyPress &key) const { return find(key) != end(); }
96 };
97
98 class MyEventReceiver : public IEventReceiver
99 {
100 public:
101         // This is the one method that we have to implement
102         virtual bool OnEvent(const SEvent &event);
103
104         bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown[keyCode]; }
105
106         // Checks whether a key was down and resets the state
107         bool WasKeyDown(const KeyPress &keyCode)
108         {
109                 bool b = keyWasDown[keyCode];
110                 if (b)
111                         keyWasDown.unset(keyCode);
112                 return b;
113         }
114
115         void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); }
116         void dontListenForKeys() { keysListenedFor.clear(); }
117
118         s32 getMouseWheel()
119         {
120                 s32 a = mouse_wheel;
121                 mouse_wheel = 0;
122                 return a;
123         }
124
125         void clearInput()
126         {
127                 keyIsDown.clear();
128                 keyWasDown.clear();
129
130                 leftclicked = false;
131                 rightclicked = false;
132                 leftreleased = false;
133                 rightreleased = false;
134
135                 left_active = false;
136                 middle_active = false;
137                 right_active = false;
138
139                 mouse_wheel = 0;
140         }
141
142         MyEventReceiver()
143         {
144 #ifdef HAVE_TOUCHSCREENGUI
145                 m_touchscreengui = NULL;
146 #endif
147         }
148
149         bool leftclicked = false;
150         bool rightclicked = false;
151         bool leftreleased = false;
152         bool rightreleased = false;
153
154         bool left_active = false;
155         bool middle_active = false;
156         bool right_active = false;
157
158         s32 mouse_wheel = 0;
159
160         JoystickController *joystick = nullptr;
161
162 #ifdef HAVE_TOUCHSCREENGUI
163         TouchScreenGUI *m_touchscreengui;
164 #endif
165
166 private:
167         // The current state of keys
168         KeyList keyIsDown;
169         // Whether a key has been pressed or not
170         KeyList keyWasDown;
171         // List of keys we listen for
172         // TODO perhaps the type of this is not really
173         // performant as KeyList is designed for few but
174         // often changing keys, and keysListenedFor is expected
175         // to change seldomly but contain lots of keys.
176         KeyList keysListenedFor;
177 };
178
179 class InputHandler
180 {
181 public:
182         InputHandler() = default;
183
184         virtual ~InputHandler() = default;
185
186         virtual bool isKeyDown(const KeyPress &keyCode) = 0;
187         virtual bool wasKeyDown(const KeyPress &keyCode) = 0;
188
189         virtual void listenForKey(const KeyPress &keyCode) {}
190         virtual void dontListenForKeys() {}
191
192         virtual v2s32 getMousePos() = 0;
193         virtual void setMousePos(s32 x, s32 y) = 0;
194
195         virtual bool getLeftState() = 0;
196         virtual bool getRightState() = 0;
197
198         virtual bool getLeftClicked() = 0;
199         virtual bool getRightClicked() = 0;
200         virtual void resetLeftClicked() = 0;
201         virtual void resetRightClicked() = 0;
202
203         virtual bool getLeftReleased() = 0;
204         virtual bool getRightReleased() = 0;
205         virtual void resetLeftReleased() = 0;
206         virtual void resetRightReleased() = 0;
207
208         virtual s32 getMouseWheel() = 0;
209
210         virtual void step(float dtime) {}
211
212         virtual void clear() {}
213
214         JoystickController joystick;
215 };
216 /*
217         Separated input handler
218 */
219
220 class RealInputHandler : public InputHandler
221 {
222 public:
223         RealInputHandler(MyEventReceiver *receiver) : m_receiver(receiver)
224         {
225                 m_receiver->joystick = &joystick;
226         }
227         virtual bool isKeyDown(const KeyPress &keyCode)
228         {
229                 return m_receiver->IsKeyDown(keyCode);
230         }
231         virtual bool wasKeyDown(const KeyPress &keyCode)
232         {
233                 return m_receiver->WasKeyDown(keyCode);
234         }
235         virtual void listenForKey(const KeyPress &keyCode)
236         {
237                 m_receiver->listenForKey(keyCode);
238         }
239         virtual void dontListenForKeys() { m_receiver->dontListenForKeys(); }
240         virtual v2s32 getMousePos()
241         {
242                 if (RenderingEngine::get_raw_device()->getCursorControl()) {
243                         return RenderingEngine::get_raw_device()
244                                         ->getCursorControl()
245                                         ->getPosition();
246                 }
247
248                 return m_mousepos;
249         }
250
251         virtual void setMousePos(s32 x, s32 y)
252         {
253                 if (RenderingEngine::get_raw_device()->getCursorControl()) {
254                         RenderingEngine::get_raw_device()
255                                         ->getCursorControl()
256                                         ->setPosition(x, y);
257                 } else {
258                         m_mousepos = v2s32(x, y);
259                 }
260         }
261
262         virtual bool getLeftState() { return m_receiver->left_active; }
263         virtual bool getRightState() { return m_receiver->right_active; }
264
265         virtual bool getLeftClicked() { return m_receiver->leftclicked; }
266         virtual bool getRightClicked() { return m_receiver->rightclicked; }
267         virtual void resetLeftClicked() { m_receiver->leftclicked = false; }
268         virtual void resetRightClicked() { m_receiver->rightclicked = false; }
269
270         virtual bool getLeftReleased() { return m_receiver->leftreleased; }
271         virtual bool getRightReleased() { return m_receiver->rightreleased; }
272         virtual void resetLeftReleased() { m_receiver->leftreleased = false; }
273         virtual void resetRightReleased() { m_receiver->rightreleased = false; }
274
275         virtual s32 getMouseWheel() { return m_receiver->getMouseWheel(); }
276
277         void clear()
278         {
279                 joystick.clear();
280                 m_receiver->clearInput();
281         }
282
283 private:
284         MyEventReceiver *m_receiver = nullptr;
285         v2s32 m_mousepos;
286 };
287
288 class RandomInputHandler : public InputHandler
289 {
290 public:
291         RandomInputHandler() = default;
292
293         virtual bool isKeyDown(const KeyPress &keyCode) { return keydown[keyCode]; }
294         virtual bool wasKeyDown(const KeyPress &keyCode) { return false; }
295         virtual v2s32 getMousePos() { return mousepos; }
296         virtual void setMousePos(s32 x, s32 y) { mousepos = v2s32(x, y); }
297
298         virtual bool getLeftState() { return leftdown; }
299         virtual bool getRightState() { return rightdown; }
300
301         virtual bool getLeftClicked() { return leftclicked; }
302         virtual bool getRightClicked() { return rightclicked; }
303         virtual void resetLeftClicked() { leftclicked = false; }
304         virtual void resetRightClicked() { rightclicked = false; }
305
306         virtual bool getLeftReleased() { return leftreleased; }
307         virtual bool getRightReleased() { return rightreleased; }
308         virtual void resetLeftReleased() { leftreleased = false; }
309         virtual void resetRightReleased() { rightreleased = false; }
310
311         virtual s32 getMouseWheel() { return 0; }
312
313         virtual void step(float dtime)
314         {
315                 {
316                         static float counter1 = 0;
317                         counter1 -= dtime;
318                         if (counter1 < 0.0) {
319                                 counter1 = 0.1 * Rand(1, 40);
320                                 keydown.toggle(getKeySetting("keymap_jump"));
321                         }
322                 }
323                 {
324                         static float counter1 = 0;
325                         counter1 -= dtime;
326                         if (counter1 < 0.0) {
327                                 counter1 = 0.1 * Rand(1, 40);
328                                 keydown.toggle(getKeySetting("keymap_special1"));
329                         }
330                 }
331                 {
332                         static float counter1 = 0;
333                         counter1 -= dtime;
334                         if (counter1 < 0.0) {
335                                 counter1 = 0.1 * Rand(1, 40);
336                                 keydown.toggle(getKeySetting("keymap_forward"));
337                         }
338                 }
339                 {
340                         static float counter1 = 0;
341                         counter1 -= dtime;
342                         if (counter1 < 0.0) {
343                                 counter1 = 0.1 * Rand(1, 40);
344                                 keydown.toggle(getKeySetting("keymap_left"));
345                         }
346                 }
347                 {
348                         static float counter1 = 0;
349                         counter1 -= dtime;
350                         if (counter1 < 0.0) {
351                                 counter1 = 0.1 * Rand(1, 20);
352                                 mousespeed = v2s32(Rand(-20, 20), Rand(-15, 20));
353                         }
354                 }
355                 {
356                         static float counter1 = 0;
357                         counter1 -= dtime;
358                         if (counter1 < 0.0) {
359                                 counter1 = 0.1 * Rand(1, 30);
360                                 leftdown = !leftdown;
361                                 if (leftdown)
362                                         leftclicked = true;
363                                 if (!leftdown)
364                                         leftreleased = true;
365                         }
366                 }
367                 {
368                         static float counter1 = 0;
369                         counter1 -= dtime;
370                         if (counter1 < 0.0) {
371                                 counter1 = 0.1 * Rand(1, 15);
372                                 rightdown = !rightdown;
373                                 if (rightdown)
374                                         rightclicked = true;
375                                 if (!rightdown)
376                                         rightreleased = true;
377                         }
378                 }
379                 mousepos += mousespeed;
380         }
381
382         s32 Rand(s32 min, s32 max);
383
384 private:
385         KeyList keydown;
386         v2s32 mousepos;
387         v2s32 mousespeed;
388         bool leftdown = false;
389         bool rightdown = false;
390         bool leftclicked = false;
391         bool rightclicked = false;
392         bool leftreleased = false;
393         bool rightreleased = false;
394 };