input.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /*
  2. * Copyright 2010-2025 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
  4. */
  5. #include <memory.h>
  6. #include "entry_p.h"
  7. #include "input.h"
  8. #include "cmd.h"
  9. #include <bx/allocator.h>
  10. #include <bx/ringbuffer.h>
  11. #include <tinystl/string.h>
  12. #include <tinystl/allocator.h>
  13. #include <tinystl/unordered_map.h>
  14. namespace stl = tinystl;
  15. struct InputMouse
  16. {
  17. InputMouse()
  18. : m_width(1280)
  19. , m_height(720)
  20. , m_wheelDelta(120)
  21. , m_lock(false)
  22. {
  23. }
  24. void reset()
  25. {
  26. if (m_lock)
  27. {
  28. m_norm[0] = 0.0f;
  29. m_norm[1] = 0.0f;
  30. m_norm[2] = 0.0f;
  31. }
  32. bx::memSet(m_buttons, 0, sizeof(m_buttons) );
  33. }
  34. void setResolution(uint16_t _width, uint16_t _height)
  35. {
  36. m_width = _width;
  37. m_height = _height;
  38. }
  39. void setPos(int32_t _mx, int32_t _my, int32_t _mz)
  40. {
  41. m_absolute[0] = _mx;
  42. m_absolute[1] = _my;
  43. m_absolute[2] = _mz;
  44. m_norm[0] = float(_mx)/float(m_width);
  45. m_norm[1] = float(_my)/float(m_height);
  46. m_norm[2] = float(_mz)/float(m_wheelDelta);
  47. }
  48. void setButtonState(entry::MouseButton::Enum _button, uint8_t _state)
  49. {
  50. m_buttons[_button] = _state;
  51. }
  52. int32_t m_absolute[3];
  53. float m_norm[3];
  54. int32_t m_wheel;
  55. uint8_t m_buttons[entry::MouseButton::Count];
  56. uint16_t m_width;
  57. uint16_t m_height;
  58. uint16_t m_wheelDelta;
  59. bool m_lock;
  60. };
  61. struct InputKeyboard
  62. {
  63. InputKeyboard()
  64. : m_ring(BX_COUNTOF(m_char)-4)
  65. {
  66. }
  67. void reset()
  68. {
  69. bx::memSet(m_key, 0, sizeof(m_key) );
  70. bx::memSet(m_once, 0xff, sizeof(m_once) );
  71. }
  72. static uint32_t encodeKeyState(uint8_t _modifiers, bool _down)
  73. {
  74. uint32_t state = 0;
  75. state |= uint32_t(_down ? _modifiers : 0)<<16;
  76. state |= uint32_t(_down)<<8;
  77. return state;
  78. }
  79. static bool decodeKeyState(uint32_t _state, uint8_t& _modifiers)
  80. {
  81. _modifiers = (_state>>16)&0xff;
  82. return 0 != ( (_state>> 8)&0xff);
  83. }
  84. void setKeyState(entry::Key::Enum _key, uint8_t _modifiers, bool _down)
  85. {
  86. m_key[_key] = encodeKeyState(_modifiers, _down);
  87. m_once[_key] = false;
  88. }
  89. bool getKeyState(entry::Key::Enum _key, uint8_t* _modifiers)
  90. {
  91. uint8_t modifiers;
  92. _modifiers = NULL == _modifiers ? &modifiers : _modifiers;
  93. return decodeKeyState(m_key[_key], *_modifiers);
  94. }
  95. uint8_t getModifiersState()
  96. {
  97. uint8_t modifiers = 0;
  98. for (uint32_t ii = 0; ii < entry::Key::Count; ++ii)
  99. {
  100. modifiers |= (m_key[ii]>>16)&0xff;
  101. }
  102. return modifiers;
  103. }
  104. void pushChar(uint8_t _len, const uint8_t _char[4])
  105. {
  106. for (uint32_t len = m_ring.reserve(4)
  107. ; len < _len
  108. ; len = m_ring.reserve(4)
  109. )
  110. {
  111. popChar();
  112. }
  113. bx::memCopy(&m_char[m_ring.m_current], _char, 4);
  114. m_ring.commit(4);
  115. }
  116. const uint8_t* popChar()
  117. {
  118. if (0 < m_ring.getNumUsed() )
  119. {
  120. uint8_t* utf8 = &m_char[m_ring.m_read];
  121. m_ring.consume(4);
  122. return utf8;
  123. }
  124. return NULL;
  125. }
  126. void charFlush()
  127. {
  128. m_ring.m_current = 0;
  129. m_ring.m_write = 0;
  130. m_ring.m_read = 0;
  131. }
  132. uint32_t m_key[256];
  133. bool m_once[256];
  134. bx::RingBufferControl m_ring;
  135. uint8_t m_char[256];
  136. };
  137. struct Gamepad
  138. {
  139. Gamepad()
  140. {
  141. reset();
  142. }
  143. void reset()
  144. {
  145. bx::memSet(m_axis, 0, sizeof(m_axis) );
  146. }
  147. void setAxis(entry::GamepadAxis::Enum _axis, int32_t _value)
  148. {
  149. m_axis[_axis] = _value;
  150. }
  151. int32_t getAxis(entry::GamepadAxis::Enum _axis)
  152. {
  153. return m_axis[_axis];
  154. }
  155. int32_t m_axis[entry::GamepadAxis::Count];
  156. };
  157. struct Input
  158. {
  159. Input()
  160. {
  161. reset();
  162. }
  163. ~Input()
  164. {
  165. }
  166. void addBindings(const char* _name, const InputBinding* _bindings)
  167. {
  168. m_inputBindingsMap.insert(stl::make_pair(stl::string(_name), _bindings) );
  169. }
  170. void removeBindings(const char* _name)
  171. {
  172. InputBindingMap::iterator it = m_inputBindingsMap.find(stl::string(_name));
  173. if (it != m_inputBindingsMap.end() )
  174. {
  175. m_inputBindingsMap.erase(it);
  176. }
  177. }
  178. void process(const InputBinding* _bindings)
  179. {
  180. for (const InputBinding* binding = _bindings; binding->m_key != entry::Key::None; ++binding)
  181. {
  182. uint8_t modifiers;
  183. bool down = InputKeyboard::decodeKeyState(m_keyboard.m_key[binding->m_key], modifiers);
  184. if (binding->m_flags == 1)
  185. {
  186. if (down)
  187. {
  188. if (modifiers == binding->m_modifiers
  189. && !m_keyboard.m_once[binding->m_key])
  190. {
  191. if (NULL == binding->m_fn)
  192. {
  193. cmdExec( (const char*)binding->m_userData);
  194. }
  195. else
  196. {
  197. binding->m_fn(binding->m_userData);
  198. }
  199. m_keyboard.m_once[binding->m_key] = true;
  200. }
  201. }
  202. else
  203. {
  204. m_keyboard.m_once[binding->m_key] = false;
  205. }
  206. }
  207. else
  208. {
  209. if (down
  210. && modifiers == binding->m_modifiers)
  211. {
  212. if (NULL == binding->m_fn)
  213. {
  214. cmdExec( (const char*)binding->m_userData);
  215. }
  216. else
  217. {
  218. binding->m_fn(binding->m_userData);
  219. }
  220. }
  221. }
  222. }
  223. }
  224. void process()
  225. {
  226. for (InputBindingMap::const_iterator it = m_inputBindingsMap.begin(); it != m_inputBindingsMap.end(); ++it)
  227. {
  228. process(it->second);
  229. }
  230. }
  231. void reset()
  232. {
  233. m_mouse.reset();
  234. m_keyboard.reset();
  235. for (uint32_t ii = 0; ii < BX_COUNTOF(m_gamepad); ++ii)
  236. {
  237. m_gamepad[ii].reset();
  238. }
  239. }
  240. typedef stl::unordered_map<stl::string, const InputBinding*> InputBindingMap;
  241. InputBindingMap m_inputBindingsMap;
  242. InputKeyboard m_keyboard;
  243. InputMouse m_mouse;
  244. Gamepad m_gamepad[ENTRY_CONFIG_MAX_GAMEPADS];
  245. };
  246. static Input* s_input;
  247. void inputInit()
  248. {
  249. s_input = BX_NEW(entry::getAllocator(), Input);
  250. }
  251. void inputShutdown()
  252. {
  253. bx::deleteObject(entry::getAllocator(), s_input);
  254. }
  255. void inputAddBindings(const char* _name, const InputBinding* _bindings)
  256. {
  257. s_input->addBindings(_name, _bindings);
  258. }
  259. void inputRemoveBindings(const char* _name)
  260. {
  261. s_input->removeBindings(_name);
  262. }
  263. void inputProcess()
  264. {
  265. s_input->process();
  266. }
  267. void inputSetMouseResolution(uint16_t _width, uint16_t _height)
  268. {
  269. s_input->m_mouse.setResolution(_width, _height);
  270. }
  271. void inputSetKeyState(entry::Key::Enum _key, uint8_t _modifiers, bool _down)
  272. {
  273. s_input->m_keyboard.setKeyState(_key, _modifiers, _down);
  274. }
  275. bool inputGetKeyState(entry::Key::Enum _key, uint8_t* _modifiers)
  276. {
  277. return s_input->m_keyboard.getKeyState(_key, _modifiers);
  278. }
  279. uint8_t inputGetModifiersState()
  280. {
  281. return s_input->m_keyboard.getModifiersState();
  282. }
  283. void inputChar(uint8_t _len, const uint8_t _char[4])
  284. {
  285. s_input->m_keyboard.pushChar(_len, _char);
  286. }
  287. const uint8_t* inputGetChar()
  288. {
  289. return s_input->m_keyboard.popChar();
  290. }
  291. void inputCharFlush()
  292. {
  293. s_input->m_keyboard.charFlush();
  294. }
  295. void inputSetMousePos(int32_t _mx, int32_t _my, int32_t _mz)
  296. {
  297. s_input->m_mouse.setPos(_mx, _my, _mz);
  298. }
  299. void inputSetMouseButtonState(entry::MouseButton::Enum _button, uint8_t _state)
  300. {
  301. s_input->m_mouse.setButtonState(_button, _state);
  302. }
  303. void inputGetMouse(float _mouse[3])
  304. {
  305. _mouse[0] = s_input->m_mouse.m_norm[0];
  306. _mouse[1] = s_input->m_mouse.m_norm[1];
  307. _mouse[2] = s_input->m_mouse.m_norm[2];
  308. s_input->m_mouse.m_norm[0] = 0.0f;
  309. s_input->m_mouse.m_norm[1] = 0.0f;
  310. s_input->m_mouse.m_norm[2] = 0.0f;
  311. }
  312. bool inputIsMouseLocked()
  313. {
  314. return s_input->m_mouse.m_lock;
  315. }
  316. void inputSetMouseLock(bool _lock)
  317. {
  318. if (s_input->m_mouse.m_lock != _lock)
  319. {
  320. s_input->m_mouse.m_lock = _lock;
  321. entry::setMouseLock(entry::kDefaultWindowHandle, _lock);
  322. if (_lock)
  323. {
  324. s_input->m_mouse.m_norm[0] = 0.0f;
  325. s_input->m_mouse.m_norm[1] = 0.0f;
  326. s_input->m_mouse.m_norm[2] = 0.0f;
  327. }
  328. }
  329. }
  330. void inputSetGamepadAxis(entry::GamepadHandle _handle, entry::GamepadAxis::Enum _axis, int32_t _value)
  331. {
  332. s_input->m_gamepad[_handle.idx].setAxis(_axis, _value);
  333. }
  334. int32_t inputGetGamepadAxis(entry::GamepadHandle _handle, entry::GamepadAxis::Enum _axis)
  335. {
  336. return s_input->m_gamepad[_handle.idx].getAxis(_axis);
  337. }