You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2015 Benjamin Litzelmann
  5. // © 2017—2018 Sam Hocevar <sam@hocevar.net>
  6. //
  7. // Lol Engine is free software. It comes without any warranty, to
  8. // the extent permitted by applicable law. You can redistribute it
  9. // and/or modify it under the terms of the Do What the Fuck You Want
  10. // to Public License, Version 2, as published by the WTFPL Task Force.
  11. // See http://www.wtfpl.net/ for more details.
  12. //
  13. #include <lol/engine-internal.h>
  14. #include <string>
  15. namespace lol
  16. {
  17. ///////////////////////////////////////////////////////////////////////////////
  18. // KeyBinding
  19. void KeyBinding::Bind(const std::string& device_name, const std::string& key_name)
  20. {
  21. const InputDevice* device = InputDevice::Get(device_name);
  22. if (!device)
  23. {
  24. msg::warn("trying to bind key to nonexistent input device %s\n",
  25. device_name.c_str());
  26. return;
  27. }
  28. int keyindex = device->GetKeyIndex(key_name);
  29. if (keyindex < 0)
  30. {
  31. msg::warn("trying to bind nonexistent key %s.%s\n",
  32. device_name.c_str(), key_name.c_str());
  33. return;
  34. }
  35. m_keybindings.push(device, keyindex);
  36. }
  37. bool KeyBinding::Unbind(const std::string& device_name, const std::string& key_name)
  38. {
  39. for (int i = 0; i < m_keybindings.count(); ++i)
  40. {
  41. if (m_keybindings[i].m1->GetName() == device_name)
  42. {
  43. if (m_keybindings[i].m2 == m_keybindings[i].m1->GetKeyIndex(key_name))
  44. {
  45. m_keybindings.remove(i);
  46. return true;
  47. }
  48. }
  49. }
  50. return false;
  51. }
  52. void KeyBinding::ClearBindings()
  53. {
  54. m_keybindings.clear();
  55. }
  56. ///////////////////////////////////////////////////////////////////////////////
  57. // AxisBinding
  58. void AxisBinding::Bind(const std::string& device_name, const std::string& axis_name)
  59. {
  60. const InputDevice* device = InputDevice::Get(device_name);
  61. if (!device)
  62. {
  63. msg::warn("trying to bind axis to nonexistent input device %s\n",
  64. device_name.c_str());
  65. return;
  66. }
  67. int axisindex = device->GetAxisIndex(axis_name);
  68. if (axisindex < 0)
  69. {
  70. msg::warn("trying to bind nonexistent axis %s.%s\n",
  71. device_name.c_str(), axis_name.c_str());
  72. return;
  73. }
  74. m_axisbindings.push(device, axisindex);
  75. }
  76. void AxisBinding::BindKey(const std::string& device_name, const std::string& key_name)
  77. {
  78. const InputDevice* device = InputDevice::Get(device_name);
  79. if (!device)
  80. {
  81. msg::warn("trying to bind axis key to nonexistent input device %s\n",
  82. device_name.c_str());
  83. return;
  84. }
  85. int keyindex = device->GetKeyIndex(key_name);
  86. if (keyindex < 0)
  87. {
  88. msg::warn("trying to bind nonexistent axis key %s.%s\n",
  89. device_name.c_str(), key_name.c_str());
  90. return;
  91. }
  92. m_keybindings.push(device, -1, keyindex);
  93. }
  94. void AxisBinding::BindKeys(const std::string& device_name, const std::string& min_key_name, const std::string& max_key_name)
  95. {
  96. const InputDevice* device = InputDevice::Get(device_name);
  97. if (!device)
  98. {
  99. msg::warn("trying to bind axis keys to nonexistent input device %s\n",
  100. device_name.c_str());
  101. return;
  102. }
  103. int minkeyindex = device->GetKeyIndex(min_key_name);
  104. if (minkeyindex < 0)
  105. {
  106. msg::warn("trying to bind nonexistent axis key %s.%s\n",
  107. device_name.c_str(), min_key_name.c_str());
  108. return;
  109. }
  110. int maxkeyindex = device->GetKeyIndex(max_key_name);
  111. if (maxkeyindex < 0)
  112. {
  113. msg::warn("trying to bind nonexistent axis key %s.%s\n",
  114. device_name.c_str(), max_key_name.c_str());
  115. return;
  116. }
  117. m_keybindings.push(device, minkeyindex, maxkeyindex);
  118. }
  119. bool AxisBinding::Unbind(const std::string& device_name, const std::string& axis_name)
  120. {
  121. for (int i = 0; i < m_keybindings.count(); ++i)
  122. {
  123. if (m_axisbindings[i].m1->GetName() == device_name)
  124. {
  125. if (m_axisbindings[i].m2 == m_axisbindings[i].m1->GetAxisIndex(axis_name))
  126. {
  127. m_axisbindings.remove(i);
  128. return true;
  129. }
  130. }
  131. }
  132. return false;
  133. }
  134. bool AxisBinding::UnbindKey(const std::string& device_name, const std::string& key_name)
  135. {
  136. for (int i = 0; i < m_keybindings.count(); ++i)
  137. {
  138. if (m_keybindings[i].m1->GetName() == device_name)
  139. {
  140. if (m_keybindings[i].m2 == -1 && m_keybindings[i].m3 == m_keybindings[i].m1->GetKeyIndex(key_name))
  141. {
  142. m_keybindings.remove(i);
  143. return true;
  144. }
  145. }
  146. }
  147. return false;
  148. }
  149. bool AxisBinding::UnbindKeys(const std::string& device_name, const std::string& min_key_name, const std::string& max_key_name)
  150. {
  151. for (int i = 0; i < m_keybindings.count(); ++i)
  152. {
  153. if (m_keybindings[i].m1->GetName() == device_name)
  154. {
  155. if (m_keybindings[i].m2 == m_keybindings[i].m1->GetKeyIndex(min_key_name)
  156. && m_keybindings[i].m3 == m_keybindings[i].m1->GetKeyIndex(max_key_name))
  157. {
  158. m_keybindings.remove(i);
  159. return true;
  160. }
  161. }
  162. }
  163. return false;
  164. }
  165. void AxisBinding::ClearBindings()
  166. {
  167. m_axisbindings.clear();
  168. m_keybindings.clear();
  169. }
  170. float AxisBinding::RetrieveCurrentValue()
  171. {
  172. float max_positive = 0.0f;
  173. float max_negative = 0.0f;
  174. for (int i = 0; i < m_axisbindings.count(); ++i)
  175. {
  176. float value = m_axisbindings[i].m1->GetAxis(m_axisbindings[i].m2);
  177. if (value > max_positive)
  178. max_positive = value;
  179. if (value < max_negative)
  180. max_negative = value;
  181. }
  182. for (int i = 0; i < m_keybindings.count(); ++i)
  183. {
  184. float value = 0.0f;
  185. m_keybindings[i].m1->GetKey(m_keybindings[i].m2);
  186. value += m_keybindings[i].m1->GetKey(m_keybindings[i].m3) ? 1.0f : 0.0f;
  187. if (m_keybindings[i].m2 != -1)
  188. value += m_keybindings[i].m1->GetKey(m_keybindings[i].m2) ? -1.0f : 0.0f;
  189. if (value > max_positive)
  190. max_positive = value;
  191. if (value < max_negative)
  192. max_negative = value;
  193. }
  194. return max_negative + max_positive;
  195. }
  196. ///////////////////////////////////////////////////////////////////////////////
  197. // Controller
  198. array<Controller*> Controller::controllers;
  199. uint32_t Controller::m_active_layer = ~((uint32_t)0);
  200. //-----------------------------------------------------------------------------
  201. Controller::Controller(std::string const &name)
  202. {
  203. m_gamegroup = GAMEGROUP_INPUT;
  204. m_name = name;
  205. m_activate_nextframe = true;
  206. m_deactivate_nextframe = false;
  207. m_active = false;
  208. if (Get(name) != nullptr)
  209. {
  210. msg::warn("controller “%s” has already been registered\n", name.c_str());
  211. }
  212. controllers.push(this);
  213. }
  214. Controller::Controller(std::string const &name, InputProfile const& profile)
  215. : Controller(name)
  216. {
  217. Init(profile);
  218. }
  219. Controller::~Controller()
  220. {
  221. ClearProfile();
  222. for (int i = 0; i < controllers.count(); ++i)
  223. {
  224. if (controllers[i] == this)
  225. {
  226. controllers.remove(i);
  227. break;
  228. }
  229. }
  230. }
  231. //Init mode 1: Input profile system -------------------------------------------
  232. void Controller::Init(InputProfile const& profile)
  233. {
  234. UnbindProfile();
  235. BindProfile(profile);
  236. }
  237. void Controller::ClearProfile()
  238. {
  239. UnbindProfile();
  240. }
  241. //Init mode 2: By hand, key/axis by key/axis ----------------------------------
  242. void Controller::SetInputCount(int nb_keys, int nb_axis)
  243. {
  244. m_keys.resize(nb_keys);
  245. m_axis.resize(nb_axis);
  246. }
  247. //Layer mask stuff ------------------------------------------------------------
  248. void Controller::SetLayerMask(uint32_t layer_mask)
  249. {
  250. m_layer_mask = layer_mask;
  251. }
  252. uint32_t Controller::GetLayerMask()
  253. {
  254. return m_layer_mask;
  255. }
  256. bool Controller::IsLayerActive()
  257. {
  258. return !!(m_layer_mask & m_active_layer);
  259. }
  260. //GetKeys/Axis stuff ----------------------------------------------------------
  261. KeyBinding& Controller::GetKey(int index)
  262. {
  263. return m_keys[index];
  264. }
  265. KeyBinding const& Controller::GetKey(int index) const
  266. {
  267. return m_keys[index];
  268. }
  269. AxisBinding& Controller::GetAxis(int index)
  270. {
  271. return m_axis[index];
  272. }
  273. AxisBinding const& Controller::GetAxis(int index) const
  274. {
  275. return m_axis[index];
  276. }
  277. //Key methods: should not go directly to binding ------------------------------
  278. bool Controller::IsKeyPressed(int index) const
  279. {
  280. //#error do something better IsLayerActive()
  281. return GetKey(index).IsPressed();
  282. }
  283. bool Controller::IsKeyReleased(int index) const
  284. {
  285. return GetKey(index).IsReleased();
  286. }
  287. bool Controller::WasKeyPressedThisFrame(int index) const
  288. {
  289. return GetKey(index).WasPressedThisFrame();
  290. }
  291. bool Controller::WasKeyReleasedThisFrame(int index) const
  292. {
  293. return GetKey(index).WasReleasedThisFrame();
  294. }
  295. //Axis methods: should not go directly to binding -----------------------------
  296. float Controller::GetAxisValue(int index) const
  297. {
  298. return GetAxis(index).GetValue();
  299. }
  300. float Controller::GetAxisDelta(int index) const
  301. {
  302. return GetAxis(index).GetDelta();
  303. }
  304. //-----------------------------------------------------------------------------
  305. Controller* Controller::Get(std::string const &name)
  306. {
  307. for (auto controller : controllers)
  308. if (controller->m_name == name)
  309. return controller;
  310. return nullptr;
  311. }
  312. //Input profile system --------------------------------------------------------
  313. void Controller::UnbindProfile()
  314. {
  315. if (m_profile.IsEmpty())
  316. return;
  317. m_mutex.lock();
  318. //Keyboard
  319. if (m_keyboard)
  320. {
  321. for (InputProfile::Keyboard& key : m_profile.m_keys)
  322. GetKey(key.m_idx).UnbindKeyboard(key.m_name);
  323. m_keyboard = nullptr;
  324. }
  325. //Mouse
  326. if (m_mouse)
  327. {
  328. for (InputProfile::MouseKey& key : m_profile.m_mouse_keys)
  329. GetKey(key.m_idx).UnbindMouse(key.m_name);
  330. for (InputProfile::MouseAxis& axis : m_profile.m_mouse_axis)
  331. GetAxis(axis.m_idx).UnbindMouse(axis.m_name);
  332. m_mouse = nullptr;
  333. }
  334. //Joystick
  335. for (InputProfile::JoystickKey& key : m_profile.m_joystick_keys)
  336. {
  337. if (m_joystick_idx.find(key.m_joy) != INDEX_NONE)
  338. GetKey(key.m_idx).UnbindJoystick(key.m_joy, key.m_name);
  339. }
  340. for (InputProfile::JoystickAxis& axis : m_profile.m_joystick_axis)
  341. {
  342. if (m_joystick_idx.find(axis.m_joy) != INDEX_NONE)
  343. GetAxis(axis.m_idx).UnbindJoystick(axis.m_joy, axis.m_name);
  344. }
  345. m_joystick.clear();
  346. m_joystick_idx.clear();
  347. m_mutex.unlock();
  348. }
  349. //Input profile system --------------------------------------------------------
  350. void Controller::BindProfile(InputProfile const& setup)
  351. {
  352. ASSERT(!setup.IsEmpty());
  353. m_mutex.lock();
  354. m_profile = setup;
  355. m_keys.resize(m_profile.GetKeyCount());
  356. m_axis.resize(m_profile.GetAxisCount());
  357. //Keyboard
  358. m_keyboard = InputDevice::GetKeyboard();
  359. if (m_keyboard)
  360. {
  361. for (InputProfile::Keyboard& key : m_profile.m_keys)
  362. GetKey(key.m_idx).BindKeyboard(key.m_name);
  363. }
  364. //Mouse
  365. m_mouse = InputDevice::GetMouse();
  366. if (m_mouse)
  367. {
  368. for (InputProfile::MouseKey& key : m_profile.m_mouse_keys)
  369. GetKey(key.m_idx).BindMouse(key.m_name);
  370. for (InputProfile::MouseAxis& axis : m_profile.m_mouse_axis)
  371. GetAxis(axis.m_idx).BindMouse(axis.m_name);
  372. }
  373. //Joystick
  374. for (uint64_t joy_idx : m_profile.m_joystick)
  375. {
  376. class InputDevice* joystick = InputDevice::GetJoystick(joy_idx);
  377. if (joystick)
  378. {
  379. m_joystick << joystick;
  380. m_joystick_idx << joy_idx;
  381. }
  382. }
  383. for (InputProfile::JoystickKey& key : m_profile.m_joystick_keys)
  384. {
  385. if (m_joystick_idx.find(key.m_joy) != INDEX_NONE)
  386. GetKey(key.m_idx).BindJoystick(key.m_joy, key.m_name);
  387. }
  388. for (InputProfile::JoystickAxis& axis : m_profile.m_joystick_axis)
  389. {
  390. if (m_joystick_idx.find(axis.m_joy) != INDEX_NONE)
  391. GetAxis(axis.m_idx).BindJoystick(axis.m_joy, axis.m_name);
  392. }
  393. m_mutex.unlock();
  394. }
  395. //-----------------------------------------------------------------------------
  396. void Controller::tick_game(float seconds)
  397. {
  398. Entity::tick_game(seconds);
  399. if (m_active)
  400. {
  401. for (int i = 0; i < m_keys.count(); ++i)
  402. m_keys[i].Update();
  403. for (int i = 0; i < m_axis.count(); ++i)
  404. m_axis[i].Update();
  405. }
  406. if (m_activate_nextframe)
  407. m_active = true;
  408. if (m_deactivate_nextframe)
  409. m_active = false;
  410. m_activate_nextframe = false;
  411. m_deactivate_nextframe = false;
  412. }
  413. //-----------------------------------------------------------------------------
  414. void Controller::Activate()
  415. {
  416. m_activate_nextframe = true;
  417. m_deactivate_nextframe = false;
  418. }
  419. void Controller::Deactivate()
  420. {
  421. m_deactivate_nextframe = true;
  422. m_activate_nextframe = false;
  423. }
  424. //-----------------------------------------------------------------------------
  425. array<Controller*> Controller::DeactivateAll()
  426. {
  427. array<Controller*> result;
  428. for (int i = 0; i < controllers.count(); ++i)
  429. {
  430. if (controllers[i]->m_active || controllers[i]->m_activate_nextframe)
  431. {
  432. result.push(controllers[i]);
  433. controllers[i]->Deactivate();
  434. }
  435. }
  436. return result;
  437. }
  438. } /* namespace lol */