Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

445 Zeilen
12 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2017—2019 Sam Hocevar <sam@hocevar.net>
  5. // © 2010—2015 Benjamin Litzelmann
  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 = (int)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. ///////////////////////////////////////////////////////////////////////////////
  53. // AxisBinding
  54. void AxisBinding::Bind(const std::string& device_name, const std::string& axis_name)
  55. {
  56. const InputDevice* device = InputDevice::Get(device_name);
  57. if (!device)
  58. {
  59. msg::warn("trying to bind axis to nonexistent input device %s\n",
  60. device_name.c_str());
  61. return;
  62. }
  63. int axisindex = (int)device->GetAxisIndex(axis_name);
  64. if (axisindex < 0)
  65. {
  66. msg::warn("trying to bind nonexistent axis %s.%s\n",
  67. device_name.c_str(), axis_name.c_str());
  68. return;
  69. }
  70. m_axisbindings.push(device, axisindex);
  71. }
  72. void AxisBinding::BindKey(const std::string& device_name, const std::string& key_name)
  73. {
  74. const InputDevice* device = InputDevice::Get(device_name);
  75. if (!device)
  76. {
  77. msg::warn("trying to bind axis key to nonexistent input device %s\n",
  78. device_name.c_str());
  79. return;
  80. }
  81. int keyindex = (int)device->GetKeyIndex(key_name);
  82. if (keyindex < 0)
  83. {
  84. msg::warn("trying to bind nonexistent axis key %s.%s\n",
  85. device_name.c_str(), key_name.c_str());
  86. return;
  87. }
  88. m_keybindings.push(device, -1, keyindex);
  89. }
  90. void AxisBinding::BindKeys(const std::string& device_name, const std::string& min_key_name, const std::string& max_key_name)
  91. {
  92. const InputDevice* device = InputDevice::Get(device_name);
  93. if (!device)
  94. {
  95. msg::warn("trying to bind axis keys to nonexistent input device %s\n",
  96. device_name.c_str());
  97. return;
  98. }
  99. int minkeyindex = (int)device->GetKeyIndex(min_key_name);
  100. if (minkeyindex < 0)
  101. {
  102. msg::warn("trying to bind nonexistent axis key %s.%s\n",
  103. device_name.c_str(), min_key_name.c_str());
  104. return;
  105. }
  106. int maxkeyindex = (int)device->GetKeyIndex(max_key_name);
  107. if (maxkeyindex < 0)
  108. {
  109. msg::warn("trying to bind nonexistent axis key %s.%s\n",
  110. device_name.c_str(), max_key_name.c_str());
  111. return;
  112. }
  113. m_keybindings.push(device, minkeyindex, maxkeyindex);
  114. }
  115. bool AxisBinding::Unbind(const std::string& device_name, const std::string& axis_name)
  116. {
  117. for (int i = 0; i < m_keybindings.count(); ++i)
  118. {
  119. if (m_axisbindings[i].m1->GetName() == device_name)
  120. {
  121. if (m_axisbindings[i].m2 == m_axisbindings[i].m1->GetAxisIndex(axis_name))
  122. {
  123. m_axisbindings.remove(i);
  124. return true;
  125. }
  126. }
  127. }
  128. return false;
  129. }
  130. bool AxisBinding::UnbindKey(const std::string& device_name, const std::string& key_name)
  131. {
  132. for (int i = 0; i < m_keybindings.count(); ++i)
  133. {
  134. if (m_keybindings[i].m1->GetName() == device_name)
  135. {
  136. if (m_keybindings[i].m2 == -1 && m_keybindings[i].m3 == m_keybindings[i].m1->GetKeyIndex(key_name))
  137. {
  138. m_keybindings.remove(i);
  139. return true;
  140. }
  141. }
  142. }
  143. return false;
  144. }
  145. bool AxisBinding::UnbindKeys(const std::string& device_name, const std::string& min_key_name, const std::string& max_key_name)
  146. {
  147. for (int i = 0; i < m_keybindings.count(); ++i)
  148. {
  149. if (m_keybindings[i].m1->GetName() == device_name)
  150. {
  151. if (m_keybindings[i].m2 == m_keybindings[i].m1->GetKeyIndex(min_key_name)
  152. && m_keybindings[i].m3 == m_keybindings[i].m1->GetKeyIndex(max_key_name))
  153. {
  154. m_keybindings.remove(i);
  155. return true;
  156. }
  157. }
  158. }
  159. return false;
  160. }
  161. float AxisBinding::RetrieveCurrentValue()
  162. {
  163. float max_positive = 0.0f;
  164. float max_negative = 0.0f;
  165. for (int i = 0; i < m_axisbindings.count(); ++i)
  166. {
  167. float value = m_axisbindings[i].m1->GetAxis(m_axisbindings[i].m2);
  168. if (value > max_positive)
  169. max_positive = value;
  170. if (value < max_negative)
  171. max_negative = value;
  172. }
  173. for (int i = 0; i < m_keybindings.count(); ++i)
  174. {
  175. float value = 0.0f;
  176. m_keybindings[i].m1->key((input::key)m_keybindings[i].m2);
  177. value += m_keybindings[i].m1->key((input::key)m_keybindings[i].m3) ? 1.0f : 0.0f;
  178. if (m_keybindings[i].m2 != -1)
  179. value += m_keybindings[i].m1->key((input::key)m_keybindings[i].m2) ? -1.0f : 0.0f;
  180. if (value > max_positive)
  181. max_positive = value;
  182. if (value < max_negative)
  183. max_negative = value;
  184. }
  185. return max_negative + max_positive;
  186. }
  187. ///////////////////////////////////////////////////////////////////////////////
  188. // Controller
  189. static std::map<std::string, Controller*> g_controllers;
  190. static uint32_t g_active_layer = ~((uint32_t)0);
  191. //-----------------------------------------------------------------------------
  192. Controller::Controller(std::string const &name)
  193. {
  194. m_gamegroup = tickable::group::game::input;
  195. m_name = name;
  196. m_activate_nextframe = true;
  197. m_deactivate_nextframe = false;
  198. m_active = false;
  199. if (g_controllers[name])
  200. msg::warn("controller “%s” has already been registered\n", name.c_str());
  201. g_controllers[name] = this;
  202. }
  203. Controller::Controller(std::string const &name, InputProfile const& profile)
  204. : Controller(name)
  205. {
  206. Init(profile);
  207. }
  208. Controller::~Controller()
  209. {
  210. ClearProfile();
  211. if (g_controllers[m_name] == this)
  212. g_controllers.erase(m_name);
  213. }
  214. //Init mode 1: Input profile system -------------------------------------------
  215. void Controller::Init(InputProfile const& profile)
  216. {
  217. UnbindProfile();
  218. BindProfile(profile);
  219. }
  220. void Controller::ClearProfile()
  221. {
  222. UnbindProfile();
  223. }
  224. //Layer mask stuff ------------------------------------------------------------
  225. void Controller::SetLayerMask(uint32_t layer_mask)
  226. {
  227. m_layer_mask = layer_mask;
  228. }
  229. uint32_t Controller::GetLayerMask()
  230. {
  231. return m_layer_mask;
  232. }
  233. bool Controller::IsLayerActive()
  234. {
  235. return !!(m_layer_mask & g_active_layer);
  236. }
  237. //GetKeys/Axis stuff ----------------------------------------------------------
  238. KeyBinding& Controller::GetKey(int index)
  239. {
  240. return m_key_bindings[index];
  241. }
  242. AxisBinding& Controller::GetAxis(int index)
  243. {
  244. return m_axis_bindings[index];
  245. }
  246. //Axis methods: should not go directly to binding -----------------------------
  247. float Controller::GetAxisValue(int index) const
  248. {
  249. auto axis = m_axis_bindings.find(index);
  250. return axis != m_axis_bindings.end() ? axis->second.GetValue() : 0.f;
  251. }
  252. float Controller::GetAxisDelta(int index) const
  253. {
  254. auto axis = m_axis_bindings.find(index);
  255. return axis != m_axis_bindings.end() ? axis->second.GetDelta() : 0.f;
  256. }
  257. //Input profile system --------------------------------------------------------
  258. void Controller::UnbindProfile()
  259. {
  260. if (m_profile.IsEmpty())
  261. return;
  262. m_mutex.lock();
  263. //Keyboard
  264. if (m_keyboard)
  265. {
  266. for (InputProfile::KeyboardKey& key : m_profile.m_keys)
  267. GetKey(key.m_idx).UnbindKeyboard(key.m_name);
  268. m_keyboard = nullptr;
  269. }
  270. //Mouse
  271. if (m_mouse)
  272. {
  273. for (InputProfile::MouseKey& key : m_profile.m_mouse_keys)
  274. GetKey(key.m_idx).UnbindMouse(key.m_name);
  275. for (InputProfile::MouseAxis& axis : m_profile.m_mouse_axis)
  276. GetAxis(axis.m_idx).UnbindMouse(axis.m_name);
  277. m_mouse = nullptr;
  278. }
  279. //Joystick
  280. for (InputProfile::JoystickKey& key : m_profile.m_joystick_keys)
  281. {
  282. if (m_joystick_idx.find(key.m_joy) != INDEX_NONE)
  283. GetKey(key.m_idx).UnbindJoystick(key.m_joy, key.m_name);
  284. }
  285. for (InputProfile::JoystickAxis& axis : m_profile.m_joystick_axis)
  286. {
  287. if (m_joystick_idx.find(axis.m_joy) != INDEX_NONE)
  288. GetAxis(axis.m_idx).UnbindJoystick(axis.m_joy, axis.m_name);
  289. }
  290. m_joysticks.clear();
  291. m_joystick_idx.clear();
  292. m_mutex.unlock();
  293. }
  294. //Input profile system --------------------------------------------------------
  295. void Controller::BindProfile(InputProfile const& setup)
  296. {
  297. ASSERT(!setup.IsEmpty());
  298. m_mutex.lock();
  299. m_profile = setup;
  300. // Keyboard
  301. m_keyboard = input::keyboard();
  302. if (m_keyboard)
  303. {
  304. for (InputProfile::KeyboardKey& key : m_profile.m_keys)
  305. GetKey(key.m_idx).BindKeyboard(key.m_name);
  306. }
  307. // Mouse
  308. m_mouse = input::mouse();
  309. if (m_mouse)
  310. {
  311. for (InputProfile::MouseKey& key : m_profile.m_mouse_keys)
  312. GetKey(key.m_idx).BindMouse(key.m_name);
  313. for (InputProfile::MouseAxis& axis : m_profile.m_mouse_axis)
  314. GetAxis(axis.m_idx).BindMouse(axis.m_name);
  315. }
  316. // Joystick
  317. for (uint64_t joy_idx : m_profile.m_joystick)
  318. {
  319. class InputDevice* joystick = InputDevice::GetJoystick(joy_idx);
  320. if (joystick)
  321. {
  322. m_joysticks << joystick;
  323. m_joystick_idx << joy_idx;
  324. }
  325. }
  326. for (InputProfile::JoystickKey& key : m_profile.m_joystick_keys)
  327. {
  328. if (m_joystick_idx.find(key.m_joy) != INDEX_NONE)
  329. GetKey(key.m_idx).BindJoystick(key.m_joy, key.m_name);
  330. }
  331. for (InputProfile::JoystickAxis& axis : m_profile.m_joystick_axis)
  332. {
  333. if (m_joystick_idx.find(axis.m_joy) != INDEX_NONE)
  334. GetAxis(axis.m_idx).BindJoystick(axis.m_joy, axis.m_name);
  335. }
  336. m_mutex.unlock();
  337. }
  338. //-----------------------------------------------------------------------------
  339. void Controller::tick_game(float seconds)
  340. {
  341. Entity::tick_game(seconds);
  342. if (m_active)
  343. {
  344. for (auto &kv : m_key_bindings)
  345. kv.second.Update();
  346. for (auto &kv : m_axis_bindings)
  347. kv.second.Update();
  348. }
  349. if (m_activate_nextframe)
  350. m_active = true;
  351. if (m_deactivate_nextframe)
  352. m_active = false;
  353. m_activate_nextframe = false;
  354. m_deactivate_nextframe = false;
  355. }
  356. //-----------------------------------------------------------------------------
  357. void Controller::Activate()
  358. {
  359. m_activate_nextframe = true;
  360. m_deactivate_nextframe = false;
  361. }
  362. void Controller::Deactivate()
  363. {
  364. m_deactivate_nextframe = true;
  365. m_activate_nextframe = false;
  366. }
  367. //-----------------------------------------------------------------------------
  368. array<Controller*> Controller::DeactivateAll()
  369. {
  370. array<Controller*> result;
  371. for (auto it : g_controllers)
  372. {
  373. if (it.second->m_active || it.second->m_activate_nextframe)
  374. {
  375. result.push(it.second);
  376. it.second->Deactivate();
  377. }
  378. }
  379. return result;
  380. }
  381. } /* namespace lol */