25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

506 lines
13 KiB

  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 */