💿🐜 Antkeeper source code https://antkeeper.com
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.

704 lines
15 KiB

7 years ago
  1. /*
  2. * Copyright (C) 2017 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper Source Code.
  5. *
  6. * Antkeeper Source Code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper Source Code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "input.hpp"
  20. #include <iostream>
  21. InputDevice::InputDevice(const std::string& name):
  22. name(name),
  23. disconnected(true)
  24. {}
  25. void InputDevice::setDisconnected(bool disconnected)
  26. {
  27. this->disconnected = disconnected;
  28. }
  29. Keyboard::Keyboard(const std::string& name):
  30. InputDevice(name)
  31. {}
  32. Keyboard::~Keyboard()
  33. {}
  34. void Keyboard::addKeyObserver(KeyObserver* observer)
  35. {
  36. keyObservers.push_back(observer);
  37. }
  38. void Keyboard::removeKeyObserver(KeyObserver* observer)
  39. {
  40. keyObservers.remove(observer);
  41. }
  42. void Keyboard::removeKeyObservers()
  43. {
  44. keyObservers.clear();
  45. }
  46. void Keyboard::press(int scancode)
  47. {
  48. for (auto observer: keyObservers)
  49. {
  50. observer->keyPressed(scancode);
  51. }
  52. }
  53. void Keyboard::release(int scancode)
  54. {
  55. for (auto observer: keyObservers)
  56. {
  57. observer->keyReleased(scancode);
  58. }
  59. }
  60. Mouse::Mouse(const std::string& name):
  61. InputDevice(name),
  62. notifyingMotionObservers(false),
  63. notifyingButtonObservers(false)
  64. {}
  65. Mouse::~Mouse()
  66. {}
  67. void Mouse::addMouseMotionObserver(MouseMotionObserver* observer)
  68. {
  69. if (notifyingMotionObservers)
  70. {
  71. additionFlaggedMotionObservers.push_back(observer);
  72. }
  73. else
  74. {
  75. motionObservers.push_back(observer);
  76. }
  77. }
  78. void Mouse::addMouseButtonObserver(MouseButtonObserver* observer)
  79. {
  80. if (notifyingButtonObservers)
  81. {
  82. additionFlaggedButtonObservers.push_back(observer);
  83. }
  84. else
  85. {
  86. buttonObservers.push_back(observer);
  87. }
  88. }
  89. void Mouse::removeMouseMotionObserver(MouseMotionObserver* observer)
  90. {
  91. if (notifyingMotionObservers)
  92. {
  93. removalFlaggedMotionObservers.push_back(observer);
  94. }
  95. else
  96. {
  97. motionObservers.remove(observer);
  98. }
  99. }
  100. void Mouse::removeMouseButtonObserver(MouseButtonObserver* observer)
  101. {
  102. if (notifyingButtonObservers)
  103. {
  104. removalFlaggedButtonObservers.push_back(observer);
  105. }
  106. else
  107. {
  108. buttonObservers.remove(observer);
  109. }
  110. }
  111. void Mouse::removeMouseMotionObservers()
  112. {
  113. motionObservers.clear();
  114. }
  115. void Mouse::removeMouseButtonObservers()
  116. {
  117. buttonObservers.clear();
  118. }
  119. void Mouse::press(int button, int x, int y)
  120. {
  121. // Notify observers
  122. notifyingButtonObservers = true;
  123. for (auto observer: buttonObservers)
  124. {
  125. observer->mouseButtonPressed(button, x, y);
  126. }
  127. notifyingButtonObservers = false;
  128. // Process flags
  129. processFlaggedButtonObservers();
  130. }
  131. void Mouse::release(int button, int x, int y)
  132. {
  133. // Notify observers
  134. notifyingButtonObservers = true;
  135. for (auto observer: buttonObservers)
  136. {
  137. observer->mouseButtonReleased(button, x, y);
  138. }
  139. notifyingButtonObservers = false;
  140. // Process flags
  141. processFlaggedButtonObservers();
  142. }
  143. void Mouse::move(int x, int y)
  144. {
  145. previousPosition = currentPosition;
  146. currentPosition = glm::ivec2(x, y);
  147. // Notify observers
  148. notifyingMotionObservers = true;
  149. for (auto observer: motionObservers)
  150. {
  151. observer->mouseMoved(x, y);
  152. }
  153. notifyingMotionObservers = false;
  154. // Process flags
  155. processFlaggedMotionObservers();
  156. }
  157. void Mouse::processFlaggedMotionObservers()
  158. {
  159. // Remove observers which are flagged for removal
  160. for (auto observer: removalFlaggedMotionObservers)
  161. {
  162. motionObservers.remove(observer);
  163. }
  164. removalFlaggedMotionObservers.clear();
  165. // Add observers which are flagged for addition
  166. for (auto observer: additionFlaggedMotionObservers)
  167. {
  168. motionObservers.push_back(observer);
  169. }
  170. additionFlaggedMotionObservers.clear();
  171. }
  172. void Mouse::processFlaggedButtonObservers()
  173. {
  174. // Remove observers which are flagged for removal
  175. for (auto observer: removalFlaggedButtonObservers)
  176. {
  177. buttonObservers.remove(observer);
  178. }
  179. removalFlaggedButtonObservers.clear();
  180. // Add observers which are flagged for addition
  181. for (auto observer: additionFlaggedButtonObservers)
  182. {
  183. buttonObservers.push_back(observer);
  184. }
  185. additionFlaggedButtonObservers.clear();
  186. }
  187. Gamepad::Gamepad(const std::string& name):
  188. InputDevice(name)
  189. {}
  190. Gamepad::~Gamepad()
  191. {}
  192. void Gamepad::addGamepadButtonObserver(GamepadButtonObserver* observer)
  193. {
  194. buttonObservers.push_back(observer);
  195. }
  196. void Gamepad::removeGamepadButtonObserver(GamepadButtonObserver* observer)
  197. {
  198. buttonObservers.remove(observer);
  199. }
  200. void Gamepad::removeGamepadButtonObservers()
  201. {
  202. buttonObservers.clear();
  203. }
  204. void Gamepad::addGamepadAxisObserver(GamepadAxisObserver* observer)
  205. {
  206. axisObservers.push_back(observer);
  207. }
  208. void Gamepad::removeGamepadAxisObserver(GamepadAxisObserver* observer)
  209. {
  210. axisObservers.remove(observer);
  211. }
  212. void Gamepad::removeGamepadAxisObservers()
  213. {
  214. axisObservers.clear();
  215. }
  216. void Gamepad::press(int button)
  217. {
  218. for (auto observer: buttonObservers)
  219. {
  220. observer->gamepadButtonPressed(button);
  221. }
  222. }
  223. void Gamepad::release(int button)
  224. {
  225. for (auto observer: buttonObservers)
  226. {
  227. observer->gamepadButtonReleased(button);
  228. }
  229. }
  230. void Gamepad::move(int axis, bool negative, float value)
  231. {
  232. for (auto observer: axisObservers)
  233. {
  234. observer->gamepadAxisMoved(axis, negative, value);
  235. }
  236. }
  237. InputEvent::InputEvent():
  238. type(InputEvent::Type::NONE)
  239. {}
  240. InputManager::InputManager():
  241. closed(false)
  242. {}
  243. void InputManager::addWindowObserver(WindowObserver* observer)
  244. {
  245. windowObservers.push_back(observer);
  246. }
  247. void InputManager::removeWindowObserver(WindowObserver* observer)
  248. {
  249. windowObservers.remove(observer);
  250. }
  251. void InputManager::removeWindowObservers()
  252. {
  253. windowObservers.clear();
  254. }
  255. void InputManager::registerKeyboard(Keyboard* keyboard)
  256. {
  257. keyboards.push_back(keyboard);
  258. }
  259. void InputManager::registerMouse(Mouse* mouse)
  260. {
  261. mice.push_back(mouse);
  262. }
  263. void InputManager::registerGamepad(Gamepad* gamepad)
  264. {
  265. gamepads.push_back(gamepad);
  266. }
  267. void InputManager::unregisterKeyboard(Keyboard* keyboard)
  268. {
  269. keyboards.remove(keyboard);
  270. }
  271. void InputManager::unregisterMouse(Mouse* mouse)
  272. {
  273. mice.remove(mouse);
  274. }
  275. void InputManager::unregisterGamepad(Gamepad* gamepad)
  276. {
  277. gamepads.remove(gamepad);
  278. }
  279. bool InputManager::isRegistered(const Keyboard* keyboard) const
  280. {
  281. for (auto it = keyboards.begin(); it != keyboards.end(); ++it)
  282. {
  283. if (*it == keyboard)
  284. return true;
  285. }
  286. return false;
  287. }
  288. bool InputManager::isRegistered(const Mouse* mouse) const
  289. {
  290. for (auto it = mice.begin(); it != mice.end(); ++it)
  291. {
  292. if (*it == mouse)
  293. return true;
  294. }
  295. return false;
  296. }
  297. bool InputManager::isRegistered(const Gamepad* gamepad) const
  298. {
  299. for (auto it = gamepads.begin(); it != gamepads.end(); ++it)
  300. {
  301. if (*it == gamepad)
  302. return true;
  303. }
  304. return false;
  305. }
  306. const Gamepad* InputManager::getGamepad(const std::string& name) const
  307. {
  308. for (auto gamepad: gamepads)
  309. {
  310. if (gamepad->getName() == name)
  311. return gamepad;
  312. }
  313. return nullptr;
  314. }
  315. Gamepad* InputManager::getGamepad(const std::string& name)
  316. {
  317. for (auto gamepad: gamepads)
  318. {
  319. if (gamepad->getName() == name)
  320. return gamepad;
  321. }
  322. return nullptr;
  323. }
  324. SDLInputManager::SDLInputManager()
  325. {
  326. keyboard = new Keyboard("Default Keyboard");
  327. mouse = new Mouse("Default Mouse");
  328. registerKeyboard(keyboard);
  329. registerMouse(mouse);
  330. keyboard->setDisconnected(false);
  331. mouse->setDisconnected(false);
  332. }
  333. SDLInputManager::~SDLInputManager()
  334. {
  335. unregisterKeyboard(keyboard);
  336. unregisterMouse(mouse);
  337. for (auto gamepad: allocatedGamepads)
  338. {
  339. unregisterGamepad(gamepad);
  340. delete gamepad;
  341. }
  342. delete keyboard;
  343. delete mouse;
  344. }
  345. void SDLInputManager::update()
  346. {
  347. while (SDL_PollEvent(&event))
  348. {
  349. switch (event.type)
  350. {
  351. case SDL_KEYDOWN:
  352. {
  353. int scancode = event.key.keysym.scancode;
  354. keyboard->press(scancode);
  355. break;
  356. }
  357. case SDL_KEYUP:
  358. {
  359. int scancode = event.key.keysym.scancode;
  360. keyboard->release(scancode);
  361. break;
  362. }
  363. case SDL_MOUSEMOTION:
  364. {
  365. int x = event.motion.x;
  366. int y = event.motion.y;
  367. mouse->move(x, y);
  368. break;
  369. }
  370. case SDL_MOUSEBUTTONDOWN:
  371. {
  372. int button = event.button.button;
  373. mouse->press(button, event.button.x, event.button.y);
  374. break;
  375. }
  376. case SDL_MOUSEBUTTONUP:
  377. {
  378. int button = event.button.button;
  379. mouse->release(button, event.button.x, event.button.y);
  380. break;
  381. }
  382. case SDL_CONTROLLERBUTTONDOWN:
  383. {
  384. int instanceID = event.cbutton.which;
  385. auto it = gamepadMap.find(instanceID);
  386. if (it == gamepadMap.end())
  387. {
  388. std::cerr << "Received event from invalid gamepad" << std::endl;
  389. break;
  390. }
  391. Gamepad* gamepad = it->second;
  392. int button = event.cbutton.button;
  393. gamepad->press(button);
  394. break;
  395. }
  396. case SDL_CONTROLLERBUTTONUP:
  397. {
  398. int instanceID = event.cbutton.which;
  399. auto it = gamepadMap.find(instanceID);
  400. if (it == gamepadMap.end())
  401. {
  402. std::cerr << "Received event from invalid gamepad" << std::endl;
  403. break;
  404. }
  405. Gamepad* gamepad = it->second;
  406. int button = event.cbutton.button;
  407. gamepad->release(button);
  408. break;
  409. }
  410. case SDL_CONTROLLERAXISMOTION:
  411. {
  412. int instanceID = event.caxis.which;
  413. auto it = gamepadMap.find(instanceID);
  414. if (it == gamepadMap.end())
  415. {
  416. std::cerr << "Received event from invalid gamepad" << std::endl;
  417. break;
  418. }
  419. Gamepad* gamepad = it->second;
  420. int axis = event.caxis.axis;
  421. bool negative;
  422. float value;
  423. if (event.caxis.value < 0)
  424. {
  425. negative = true;
  426. value = (float)event.caxis.value / -32768.0f;
  427. }
  428. else
  429. {
  430. negative = false;
  431. value = (float)event.caxis.value / 32767.0f;
  432. }
  433. gamepad->move(axis, negative, value);
  434. break;
  435. }
  436. case SDL_CONTROLLERDEVICEADDED:
  437. {
  438. SDL_GameController* controller = SDL_GameControllerOpen(event.cdevice.which);
  439. if (controller != nullptr)
  440. {
  441. // Find controller's joystick instance ID
  442. SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller);
  443. int instanceID = SDL_JoystickInstanceID(joystick);
  444. // Determine gamepad name
  445. std::string name = SDL_GameControllerName(controller);
  446. if (name.empty())
  447. {
  448. name = "Unknown Gamepad";
  449. }
  450. bool reconnected = false;
  451. const std::list<Gamepad*>* gamepads = getGamepads();
  452. for (auto it = gamepads->begin(); it != gamepads->end(); ++it)
  453. {
  454. // Check if this gamepad was previously connected
  455. if ((*it)->isDisconnected() && (*it)->getName() == name)
  456. {
  457. // Map to new instance ID
  458. Gamepad* gamepad = *it;
  459. gamepadMap[instanceID] = gamepad;
  460. gamepad->setDisconnected(false);
  461. reconnected = true;
  462. std::cout << "Reconnected gamepad \"" << name << "\" with ID " << instanceID << std::endl;
  463. break;
  464. }
  465. }
  466. if (!reconnected)
  467. {
  468. // Create new gamepad
  469. Gamepad* gamepad = new Gamepad(name);
  470. // Add to list of allocated gamepads
  471. allocatedGamepads.push_back(gamepad);
  472. // Register with the input manager
  473. registerGamepad(gamepad);
  474. // Map instance ID to gamepad pointer
  475. gamepadMap[instanceID] = gamepad;
  476. // Connect gamepad
  477. gamepad->setDisconnected(false);
  478. std::cout << "Connected gamepad \"" << name << "\" with ID " << instanceID << std::endl;
  479. }
  480. }
  481. break;
  482. }
  483. case SDL_CONTROLLERDEVICEREMOVED:
  484. {
  485. int instanceID = event.cdevice.which;
  486. // Find gamepad
  487. auto mapIt = gamepadMap.find(instanceID);
  488. if (mapIt == gamepadMap.end())
  489. {
  490. std::cerr << "Attempted to remove nonexistent gamepad with ID " << instanceID << std::endl;
  491. break;
  492. }
  493. Gamepad* gamepad = mapIt->second;
  494. // Remove from gamepad map
  495. gamepadMap.erase(mapIt);
  496. // Set disconnected flag
  497. gamepad->setDisconnected(true);
  498. std::cout << "Disconnected gamepad \"" << gamepad->getName() << "\" with ID " << instanceID << std::endl;
  499. break;
  500. }
  501. case SDL_WINDOWEVENT:
  502. {
  503. if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
  504. {
  505. for (auto observer: windowObservers)
  506. {
  507. observer->windowResized(event.window.data1, event.window.data2);
  508. }
  509. }
  510. else if (event.window.event == SDL_WINDOWEVENT_CLOSE)
  511. {
  512. closed = true;
  513. for (auto observer: windowObservers)
  514. {
  515. observer->windowClosed();
  516. }
  517. }
  518. break;
  519. }
  520. case SDL_QUIT:
  521. {
  522. closed = true;
  523. for (auto observer: windowObservers)
  524. {
  525. observer->windowClosed();
  526. }
  527. break;
  528. }
  529. default:
  530. break;
  531. }
  532. }
  533. }
  534. void SDLInputManager::listen(InputEvent* inputEvent)
  535. {
  536. int eventCount;
  537. // Gather events
  538. SDL_PumpEvents();
  539. // Check for key events
  540. eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN);
  541. if (eventCount)
  542. {
  543. int scancode = event.key.keysym.scancode;
  544. inputEvent->type = InputEvent::Type::KEY;
  545. inputEvent->key.first = keyboard;
  546. inputEvent->key.second = scancode;
  547. return;
  548. }
  549. // Check for mouse button events
  550. eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN);
  551. if (eventCount)
  552. {
  553. int button = event.button.button;
  554. inputEvent->type = InputEvent::Type::MOUSE_BUTTON;
  555. inputEvent->mouseButton.first = mouse;
  556. inputEvent->mouseButton.second = button;
  557. return;
  558. }
  559. // Check for gamepad button events
  560. eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONDOWN);
  561. if (eventCount)
  562. {
  563. int instanceID = event.cbutton.which;
  564. auto it = gamepadMap.find(instanceID);
  565. if (it == gamepadMap.end())
  566. {
  567. std::cerr << "Received event from invalid gamepad" << std::endl;
  568. return;
  569. }
  570. Gamepad* gamepad = it->second;
  571. int button = event.cbutton.button;
  572. inputEvent->type = InputEvent::Type::GAMEPAD_BUTTON;
  573. inputEvent->gamepadButton.first = gamepad;
  574. inputEvent->gamepadButton.second = button;
  575. return;
  576. }
  577. // Check for gamepad axis events
  578. eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERAXISMOTION);
  579. if (eventCount)
  580. {
  581. int instanceID = event.caxis.which;
  582. auto it = gamepadMap.find(instanceID);
  583. if (it == gamepadMap.end())
  584. {
  585. std::cerr << "Received event from invalid gamepad" << std::endl;
  586. return;
  587. }
  588. Gamepad* gamepad = it->second;
  589. int axis = event.caxis.axis;
  590. bool negative = event.caxis.value < 0;
  591. inputEvent->type = InputEvent::Type::GAMEPAD_AXIS;
  592. std::get<0>(inputEvent->gamepadAxis) = gamepad;
  593. std::get<1>(inputEvent->gamepadAxis) = axis;
  594. std::get<2>(inputEvent->gamepadAxis) = negative;
  595. return;
  596. }
  597. }