inputhandler.h 9.6 KB

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