input.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * Copyright 2010-2014 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include <memory.h>
  6. #include "entry_p.h"
  7. #include "input.h"
  8. #include <tinystl/allocator.h>
  9. #include <tinystl/unordered_map.h>
  10. namespace stl = tinystl;
  11. struct Mouse
  12. {
  13. Mouse()
  14. : m_width(1280)
  15. , m_height(720)
  16. , m_wheelDelta(120)
  17. , m_lock(false)
  18. {
  19. }
  20. void reset()
  21. {
  22. if (m_lock)
  23. {
  24. m_norm[0] = 0.0f;
  25. m_norm[1] = 0.0f;
  26. m_norm[2] = 0.0f;
  27. }
  28. memset(m_buttons, 0, sizeof(m_buttons) );
  29. }
  30. void setResolution(uint16_t _width, uint16_t _height)
  31. {
  32. m_width = _width;
  33. m_height = _height;
  34. }
  35. void setPos(int32_t _mx, int32_t _my, int32_t _mz)
  36. {
  37. m_absolute[0] = _mx;
  38. m_absolute[1] = _my;
  39. m_absolute[2] = _mz;
  40. m_norm[0] = float(_mx)/float(m_width);
  41. m_norm[1] = float(_my)/float(m_height);
  42. m_norm[2] = float(_mz)/float(m_wheelDelta);
  43. }
  44. void setButtonState(entry::MouseButton::Enum _button, uint8_t _state)
  45. {
  46. m_buttons[_button] = _state;
  47. }
  48. int32_t m_absolute[3];
  49. float m_norm[3];
  50. int32_t m_wheel;
  51. uint8_t m_buttons[entry::MouseButton::Count];
  52. uint16_t m_width;
  53. uint16_t m_height;
  54. uint16_t m_wheelDelta;
  55. bool m_lock;
  56. };
  57. struct Keyboard
  58. {
  59. Keyboard()
  60. {
  61. }
  62. void reset()
  63. {
  64. memset(m_key, 0, sizeof(m_key) );
  65. memset(m_once, 0xff, sizeof(m_once) );
  66. }
  67. static uint32_t encodeKeyState(uint8_t _modifiers, bool _down)
  68. {
  69. uint32_t state = 0;
  70. state |= uint32_t(_modifiers)<<16;
  71. state |= uint32_t(_down)<<8;
  72. return state;
  73. }
  74. static void decodeKeyState(uint32_t _state, uint8_t& _modifiers, bool& _down)
  75. {
  76. _modifiers = (_state>>16)&0xff;
  77. _down = 0 != ( (_state>>8)&0xff);
  78. }
  79. void setKeyState(entry::Key::Enum _key, uint8_t _modifiers, bool _down)
  80. {
  81. m_key[_key] = encodeKeyState(_modifiers, _down);
  82. m_once[_key] = false;
  83. }
  84. uint32_t m_key[256];
  85. bool m_once[256];
  86. };
  87. struct Input
  88. {
  89. Input()
  90. {
  91. reset();
  92. }
  93. ~Input()
  94. {
  95. }
  96. void addBindings(const char* _name, const InputBinding* _bindings)
  97. {
  98. m_inputBindingsMap.insert(stl::make_pair(_name, _bindings) );
  99. }
  100. void removeBindings(const char* _name)
  101. {
  102. m_inputBindingsMap.erase(m_inputBindingsMap.find(_name));
  103. }
  104. void process(const InputBinding* _bindings)
  105. {
  106. for (const InputBinding* binding = _bindings; binding->m_key != entry::Key::None; ++binding)
  107. {
  108. uint8_t modifiers;
  109. bool down;
  110. Keyboard::decodeKeyState(m_keyboard.m_key[binding->m_key], modifiers, down);
  111. if (binding->m_flags == 1)
  112. {
  113. if (down)
  114. {
  115. if (modifiers == binding->m_modifiers
  116. && !m_keyboard.m_once[binding->m_key])
  117. {
  118. binding->m_fn(binding->m_userData);
  119. m_keyboard.m_once[binding->m_key] = true;
  120. }
  121. }
  122. else
  123. {
  124. m_keyboard.m_once[binding->m_key] = false;
  125. }
  126. }
  127. else
  128. {
  129. if (down
  130. && modifiers == binding->m_modifiers)
  131. {
  132. binding->m_fn(binding->m_userData);
  133. }
  134. }
  135. }
  136. }
  137. void process()
  138. {
  139. for (InputBindingMap::const_iterator it = m_inputBindingsMap.begin(); it != m_inputBindingsMap.end(); ++it)
  140. {
  141. process(it->second);
  142. }
  143. }
  144. void reset()
  145. {
  146. m_mouse.reset();
  147. m_keyboard.reset();
  148. }
  149. typedef stl::unordered_map<const char*, const InputBinding*> InputBindingMap;
  150. InputBindingMap m_inputBindingsMap;
  151. Mouse m_mouse;
  152. Keyboard m_keyboard;
  153. };
  154. static Input s_input;
  155. void inputAddBindings(const char* _name, const InputBinding* _bindings)
  156. {
  157. s_input.addBindings(_name, _bindings);
  158. }
  159. void inputRemoveBindings(const char* _name)
  160. {
  161. s_input.removeBindings(_name);
  162. }
  163. void inputProcess()
  164. {
  165. s_input.process();
  166. }
  167. void inputSetMouseResolution(uint16_t _width, uint16_t _height)
  168. {
  169. s_input.m_mouse.setResolution(_width, _height);
  170. }
  171. void inputSetKeyState(entry::Key::Enum _key, uint8_t _modifiers, bool _down)
  172. {
  173. s_input.m_keyboard.setKeyState(_key, _modifiers, _down);
  174. }
  175. void inputSetMousePos(int32_t _mx, int32_t _my, int32_t _mz)
  176. {
  177. s_input.m_mouse.setPos(_mx, _my, _mz);
  178. }
  179. void inputSetMouseButtonState(entry::MouseButton::Enum _button, uint8_t _state)
  180. {
  181. s_input.m_mouse.setButtonState(_button, _state);
  182. }
  183. void inputGetMouse(float _mouse[3])
  184. {
  185. _mouse[0] = s_input.m_mouse.m_norm[0];
  186. _mouse[1] = s_input.m_mouse.m_norm[1];
  187. _mouse[2] = s_input.m_mouse.m_norm[2];
  188. s_input.m_mouse.m_norm[0] = 0.0f;
  189. s_input.m_mouse.m_norm[1] = 0.0f;
  190. s_input.m_mouse.m_norm[2] = 0.0f;
  191. }
  192. bool inputIsMouseLocked()
  193. {
  194. return s_input.m_mouse.m_lock;
  195. }
  196. void inputSetMouseLock(bool _lock)
  197. {
  198. if (s_input.m_mouse.m_lock != _lock)
  199. {
  200. s_input.m_mouse.m_lock = _lock;
  201. entry::WindowHandle defaultWindow = { 0 };
  202. entry::setMouseLock(defaultWindow, _lock);
  203. if (_lock)
  204. {
  205. s_input.m_mouse.m_norm[0] = 0.0f;
  206. s_input.m_mouse.m_norm[1] = 0.0f;
  207. s_input.m_mouse.m_norm[2] = 0.0f;
  208. }
  209. }
  210. }