💿🐜 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.

788 lines
17 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
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. notifyingWheelObservers(false)
  65. {}
  66. Mouse::~Mouse()
  67. {}
  68. void Mouse::addMouseMotionObserver(MouseMotionObserver* observer)
  69. {
  70. if (notifyingMotionObservers)
  71. {
  72. additionFlaggedMotionObservers.push_back(observer);
  73. }
  74. else
  75. {
  76. motionObservers.push_back(observer);
  77. }
  78. }
  79. void Mouse::addMouseButtonObserver(MouseButtonObserver* observer)
  80. {
  81. if (notifyingButtonObservers)
  82. {
  83. additionFlaggedButtonObservers.push_back(observer);
  84. }
  85. else
  86. {
  87. buttonObservers.push_back(observer);
  88. }
  89. }
  90. void Mouse::addMouseWheelObserver(MouseWheelObserver* observer)
  91. {
  92. if (notifyingWheelObservers)
  93. {
  94. additionFlaggedWheelObservers.push_back(observer);
  95. }
  96. else
  97. {
  98. wheelObservers.push_back(observer);
  99. }
  100. }
  101. void Mouse::removeMouseMotionObserver(MouseMotionObserver* observer)
  102. {
  103. if (notifyingMotionObservers)
  104. {
  105. removalFlaggedMotionObservers.push_back(observer);
  106. }
  107. else
  108. {
  109. motionObservers.remove(observer);
  110. }
  111. }
  112. void Mouse::removeMouseButtonObserver(MouseButtonObserver* observer)
  113. {
  114. if (notifyingButtonObservers)
  115. {
  116. removalFlaggedButtonObservers.push_back(observer);
  117. }
  118. else
  119. {
  120. buttonObservers.remove(observer);
  121. }
  122. }
  123. void Mouse::removeMouseWheelObserver(MouseWheelObserver* observer)
  124. {
  125. if (notifyingWheelObservers)
  126. {
  127. removalFlaggedWheelObservers.push_back(observer);
  128. }
  129. else
  130. {
  131. wheelObservers.remove(observer);
  132. }
  133. }
  134. void Mouse::removeMouseMotionObservers()
  135. {
  136. motionObservers.clear();
  137. }
  138. void Mouse::removeMouseButtonObservers()
  139. {
  140. buttonObservers.clear();
  141. }
  142. void Mouse::removeMouseWheelObservers()
  143. {
  144. wheelObservers.clear();
  145. }
  146. void Mouse::press(int button, int x, int y)
  147. {
  148. // Notify observers
  149. notifyingButtonObservers = true;
  150. for (auto observer: buttonObservers)
  151. {
  152. observer->mouseButtonPressed(button, x, y);
  153. }
  154. notifyingButtonObservers = false;
  155. // Process flags
  156. processFlaggedButtonObservers();
  157. }
  158. void Mouse::release(int button, int x, int y)
  159. {
  160. // Notify observers
  161. notifyingButtonObservers = true;
  162. for (auto observer: buttonObservers)
  163. {
  164. observer->mouseButtonReleased(button, x, y);
  165. }
  166. notifyingButtonObservers = false;
  167. // Process flags
  168. processFlaggedButtonObservers();
  169. }
  170. void Mouse::move(int x, int y)
  171. {
  172. previousPosition = currentPosition;
  173. currentPosition = glm::ivec2(x, y);
  174. // Notify observers
  175. notifyingMotionObservers = true;
  176. for (auto observer: motionObservers)
  177. {
  178. observer->mouseMoved(x, y);
  179. }
  180. notifyingMotionObservers = false;
  181. // Process flags
  182. processFlaggedMotionObservers();
  183. }
  184. void Mouse::scroll(int x, int y)
  185. {
  186. // Notify observers
  187. notifyingWheelObservers = true;
  188. for (auto observer: wheelObservers)
  189. {
  190. observer->mouseWheelScrolled(x, y);
  191. }
  192. notifyingWheelObservers = false;
  193. // Process flags
  194. processFlaggedWheelObservers();
  195. }
  196. void Mouse::processFlaggedMotionObservers()
  197. {
  198. // Remove observers which are flagged for removal
  199. for (auto observer: removalFlaggedMotionObservers)
  200. {
  201. motionObservers.remove(observer);
  202. }
  203. removalFlaggedMotionObservers.clear();
  204. // Add observers which are flagged for addition
  205. for (auto observer: additionFlaggedMotionObservers)
  206. {
  207. motionObservers.push_back(observer);
  208. }
  209. additionFlaggedMotionObservers.clear();
  210. }
  211. void Mouse::processFlaggedButtonObservers()
  212. {
  213. // Remove observers which are flagged for removal
  214. for (auto observer: removalFlaggedButtonObservers)
  215. {
  216. buttonObservers.remove(observer);
  217. }
  218. removalFlaggedButtonObservers.clear();
  219. // Add observers which are flagged for addition
  220. for (auto observer: additionFlaggedButtonObservers)
  221. {
  222. buttonObservers.push_back(observer);
  223. }
  224. additionFlaggedButtonObservers.clear();
  225. }
  226. void Mouse::processFlaggedWheelObservers()
  227. {
  228. // Remove observers which are flagged for removal
  229. for (auto observer: removalFlaggedWheelObservers)
  230. {
  231. wheelObservers.remove(observer);
  232. }
  233. removalFlaggedWheelObservers.clear();
  234. // Add observers which are flagged for addition
  235. for (auto observer: additionFlaggedWheelObservers)
  236. {
  237. wheelObservers.push_back(observer);
  238. }
  239. additionFlaggedWheelObservers.clear();
  240. }
  241. Gamepad::Gamepad(const std::string& name):
  242. InputDevice(name)
  243. {}
  244. Gamepad::~Gamepad()
  245. {}
  246. void Gamepad::addGamepadButtonObserver(GamepadButtonObserver* observer)
  247. {
  248. buttonObservers.push_back(observer);
  249. }
  250. void Gamepad::removeGamepadButtonObserver(GamepadButtonObserver* observer)
  251. {
  252. buttonObservers.remove(observer);
  253. }
  254. void Gamepad::removeGamepadButtonObservers()
  255. {
  256. buttonObservers.clear();
  257. }
  258. void Gamepad::addGamepadAxisObserver(GamepadAxisObserver* observer)
  259. {
  260. axisObservers.push_back(observer);
  261. }
  262. void Gamepad::removeGamepadAxisObserver(GamepadAxisObserver* observer)
  263. {
  264. axisObservers.remove(observer);
  265. }
  266. void Gamepad::removeGamepadAxisObservers()
  267. {
  268. axisObservers.clear();
  269. }
  270. void Gamepad::press(int button)
  271. {
  272. for (auto observer: buttonObservers)
  273. {
  274. observer->gamepadButtonPressed(button);
  275. }
  276. }
  277. void Gamepad::release(int button)
  278. {
  279. for (auto observer: buttonObservers)
  280. {
  281. observer->gamepadButtonReleased(button);
  282. }
  283. }
  284. void Gamepad::move(int axis, bool negative, float value)
  285. {
  286. for (auto observer: axisObservers)
  287. {
  288. observer->gamepadAxisMoved(axis, negative, value);
  289. }
  290. }
  291. InputEvent::InputEvent():
  292. type(InputEvent::Type::NONE)
  293. {}
  294. InputManager::InputManager():
  295. closed(false)
  296. {}
  297. void InputManager::addWindowObserver(WindowObserver* observer)
  298. {
  299. windowObservers.push_back(observer);
  300. }
  301. void InputManager::removeWindowObserver(WindowObserver* observer)
  302. {
  303. windowObservers.remove(observer);
  304. }
  305. void InputManager::removeWindowObservers()
  306. {
  307. windowObservers.clear();
  308. }
  309. void InputManager::registerKeyboard(Keyboard* keyboard)
  310. {
  311. keyboards.push_back(keyboard);
  312. }
  313. void InputManager::registerMouse(Mouse* mouse)
  314. {
  315. mice.push_back(mouse);
  316. }
  317. void InputManager::registerGamepad(Gamepad* gamepad)
  318. {
  319. gamepads.push_back(gamepad);
  320. }
  321. void InputManager::unregisterKeyboard(Keyboard* keyboard)
  322. {
  323. keyboards.remove(keyboard);
  324. }
  325. void InputManager::unregisterMouse(Mouse* mouse)
  326. {
  327. mice.remove(mouse);
  328. }
  329. void InputManager::unregisterGamepad(Gamepad* gamepad)
  330. {
  331. gamepads.remove(gamepad);
  332. }
  333. bool InputManager::isRegistered(const Keyboard* keyboard) const
  334. {
  335. for (auto it = keyboards.begin(); it != keyboards.end(); ++it)
  336. {
  337. if (*it == keyboard)
  338. return true;
  339. }
  340. return false;
  341. }
  342. bool InputManager::isRegistered(const Mouse* mouse) const
  343. {
  344. for (auto it = mice.begin(); it != mice.end(); ++it)
  345. {
  346. if (*it == mouse)
  347. return true;
  348. }
  349. return false;
  350. }
  351. bool InputManager::isRegistered(const Gamepad* gamepad) const
  352. {
  353. for (auto it = gamepads.begin(); it != gamepads.end(); ++it)
  354. {
  355. if (*it == gamepad)
  356. return true;
  357. }
  358. return false;
  359. }
  360. const Gamepad* InputManager::getGamepad(const std::string& name) const
  361. {
  362. for (auto gamepad: gamepads)
  363. {
  364. if (gamepad->getName() == name)
  365. return gamepad;
  366. }
  367. return nullptr;
  368. }
  369. Gamepad* InputManager::getGamepad(const std::string& name)
  370. {
  371. for (auto gamepad: gamepads)
  372. {
  373. if (gamepad->getName() == name)
  374. return gamepad;
  375. }
  376. return nullptr;
  377. }
  378. SDLInputManager::SDLInputManager()
  379. {
  380. keyboard = new Keyboard("Default Keyboard");
  381. mouse = new Mouse("Default Mouse");
  382. registerKeyboard(keyboard);
  383. registerMouse(mouse);
  384. keyboard->setDisconnected(false);
  385. mouse->setDisconnected(false);
  386. }
  387. SDLInputManager::~SDLInputManager()
  388. {
  389. unregisterKeyboard(keyboard);
  390. unregisterMouse(mouse);
  391. for (auto gamepad: allocatedGamepads)
  392. {
  393. unregisterGamepad(gamepad);
  394. delete gamepad;
  395. }
  396. delete keyboard;
  397. delete mouse;
  398. }
  399. void SDLInputManager::update()
  400. {
  401. while (SDL_PollEvent(&event))
  402. {
  403. switch (event.type)
  404. {
  405. case SDL_KEYDOWN:
  406. {
  407. int scancode = event.key.keysym.scancode;
  408. keyboard->press(scancode);
  409. break;
  410. }
  411. case SDL_KEYUP:
  412. {
  413. int scancode = event.key.keysym.scancode;
  414. keyboard->release(scancode);
  415. break;
  416. }
  417. case SDL_MOUSEMOTION:
  418. {
  419. int x = event.motion.x;
  420. int y = event.motion.y;
  421. mouse->move(x, y);
  422. break;
  423. }
  424. case SDL_MOUSEBUTTONDOWN:
  425. {
  426. int button = event.button.button;
  427. mouse->press(button, event.button.x, event.button.y);
  428. break;
  429. }
  430. case SDL_MOUSEBUTTONUP:
  431. {
  432. int button = event.button.button;
  433. mouse->release(button, event.button.x, event.button.y);
  434. break;
  435. }
  436. case SDL_MOUSEWHEEL:
  437. {
  438. int direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) ? -1 : 1;
  439. int x = event.wheel.x * direction;
  440. int y = event.wheel.y * direction;
  441. mouse->scroll(x, y);
  442. break;
  443. }
  444. case SDL_CONTROLLERBUTTONDOWN:
  445. {
  446. int instanceID = event.cbutton.which;
  447. auto it = gamepadMap.find(instanceID);
  448. if (it == gamepadMap.end())
  449. {
  450. std::cerr << std::string("Received event from invalid gamepad") << std::endl;
  451. break;
  452. }
  453. Gamepad* gamepad = it->second;
  454. int button = event.cbutton.button;
  455. gamepad->press(button);
  456. break;
  457. }
  458. case SDL_CONTROLLERBUTTONUP:
  459. {
  460. int instanceID = event.cbutton.which;
  461. auto it = gamepadMap.find(instanceID);
  462. if (it == gamepadMap.end())
  463. {
  464. std::cerr << std::string("Received event from invalid gamepad") << std::endl;
  465. break;
  466. }
  467. Gamepad* gamepad = it->second;
  468. int button = event.cbutton.button;
  469. gamepad->release(button);
  470. break;
  471. }
  472. case SDL_CONTROLLERAXISMOTION:
  473. {
  474. int instanceID = event.caxis.which;
  475. auto it = gamepadMap.find(instanceID);
  476. if (it == gamepadMap.end())
  477. {
  478. std::cerr << std::string("Received event from invalid gamepad") << std::endl;
  479. break;
  480. }
  481. Gamepad* gamepad = it->second;
  482. int axis = event.caxis.axis;
  483. bool negative;
  484. float value;
  485. if (event.caxis.value < 0)
  486. {
  487. negative = true;
  488. value = (float)event.caxis.value / -32768.0f;
  489. }
  490. else
  491. {
  492. negative = false;
  493. value = (float)event.caxis.value / 32767.0f;
  494. }
  495. gamepad->move(axis, negative, value);
  496. break;
  497. }
  498. case SDL_CONTROLLERDEVICEADDED:
  499. {
  500. SDL_GameController* controller = SDL_GameControllerOpen(event.cdevice.which);
  501. if (controller != nullptr)
  502. {
  503. // Find controller's joystick instance ID
  504. SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller);
  505. int instanceID = SDL_JoystickInstanceID(joystick);
  506. // Determine gamepad name
  507. std::string name = SDL_GameControllerName(controller);
  508. if (name.empty())
  509. {
  510. name = "Unknown Gamepad";
  511. }
  512. bool reconnected = false;
  513. const std::list<Gamepad*>* gamepads = getGamepads();
  514. for (auto it = gamepads->begin(); it != gamepads->end(); ++it)
  515. {
  516. // Check if this gamepad was previously connected
  517. if ((*it)->isDisconnected() && (*it)->getName() == name)
  518. {
  519. // Map to new instance ID
  520. Gamepad* gamepad = *it;
  521. gamepadMap[instanceID] = gamepad;
  522. gamepad->setDisconnected(false);
  523. reconnected = true;
  524. std::cout << std::string("Reconnected gamepad \"") << name << std::string("\" with ID ") << instanceID << std::endl;
  525. break;
  526. }
  527. }
  528. if (!reconnected)
  529. {
  530. // Create new gamepad
  531. Gamepad* gamepad = new Gamepad(name);
  532. // Add to list of allocated gamepads
  533. allocatedGamepads.push_back(gamepad);
  534. // Register with the input manager
  535. registerGamepad(gamepad);
  536. // Map instance ID to gamepad pointer
  537. gamepadMap[instanceID] = gamepad;
  538. // Connect gamepad
  539. gamepad->setDisconnected(false);
  540. std::cout << std::string("Connected gamepad \"") << name << std::string("\" with ID ") << instanceID << std::endl;
  541. }
  542. }
  543. break;
  544. }
  545. case SDL_CONTROLLERDEVICEREMOVED:
  546. {
  547. int instanceID = event.cdevice.which;
  548. // Find gamepad
  549. auto mapIt = gamepadMap.find(instanceID);
  550. if (mapIt == gamepadMap.end())
  551. {
  552. std::cerr << std::string("Attempted to remove nonexistent gamepad with ID ") << instanceID << std::endl;
  553. break;
  554. }
  555. Gamepad* gamepad = mapIt->second;
  556. // Remove from gamepad map
  557. gamepadMap.erase(mapIt);
  558. // Set disconnected flag
  559. gamepad->setDisconnected(true);
  560. std::cout << std::string("Disconnected gamepad \"") << gamepad->getName() << std::string("\" with ID ") << instanceID << std::endl;
  561. break;
  562. }
  563. case SDL_WINDOWEVENT:
  564. {
  565. if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
  566. {
  567. for (auto observer: windowObservers)
  568. {
  569. observer->windowResized(event.window.data1, event.window.data2);
  570. }
  571. }
  572. else if (event.window.event == SDL_WINDOWEVENT_CLOSE)
  573. {
  574. closed = true;
  575. for (auto observer: windowObservers)
  576. {
  577. observer->windowClosed();
  578. }
  579. }
  580. break;
  581. }
  582. case SDL_QUIT:
  583. {
  584. closed = true;
  585. for (auto observer: windowObservers)
  586. {
  587. observer->windowClosed();
  588. }
  589. break;
  590. }
  591. default:
  592. break;
  593. }
  594. }
  595. }
  596. void SDLInputManager::listen(InputEvent* inputEvent)
  597. {
  598. int eventCount;
  599. // Gather events
  600. SDL_PumpEvents();
  601. // Check for key events
  602. eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN);
  603. if (eventCount)
  604. {
  605. int scancode = event.key.keysym.scancode;
  606. inputEvent->type = InputEvent::Type::KEY;
  607. inputEvent->key.first = keyboard;
  608. inputEvent->key.second = scancode;
  609. return;
  610. }
  611. // Check for mouse button events
  612. eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONDOWN);
  613. if (eventCount)
  614. {
  615. int button = event.button.button;
  616. inputEvent->type = InputEvent::Type::MOUSE_BUTTON;
  617. inputEvent->mouseButton.first = mouse;
  618. inputEvent->mouseButton.second = button;
  619. return;
  620. }
  621. // Check for mouse wheel events
  622. eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_MOUSEWHEEL, SDL_MOUSEWHEEL);
  623. if (eventCount)
  624. {
  625. int direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) ? -1 : 1;
  626. int x = event.wheel.x * direction;
  627. int y = event.wheel.y * direction;
  628. inputEvent->type = InputEvent::Type::MOUSE_WHEEL;
  629. std::get<0>(inputEvent->mouseWheel) = mouse;
  630. std::get<1>(inputEvent->mouseWheel) = x;
  631. std::get<2>(inputEvent->mouseWheel) = y;
  632. return;
  633. }
  634. // Check for gamepad button events
  635. eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONDOWN);
  636. if (eventCount)
  637. {
  638. int instanceID = event.cbutton.which;
  639. auto it = gamepadMap.find(instanceID);
  640. if (it == gamepadMap.end())
  641. {
  642. std::cerr << std::string("Received event from invalid gamepad") << std::endl;
  643. return;
  644. }
  645. Gamepad* gamepad = it->second;
  646. int button = event.cbutton.button;
  647. inputEvent->type = InputEvent::Type::GAMEPAD_BUTTON;
  648. inputEvent->gamepadButton.first = gamepad;
  649. inputEvent->gamepadButton.second = button;
  650. return;
  651. }
  652. // Check for gamepad axis events
  653. eventCount = SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERAXISMOTION);
  654. if (eventCount)
  655. {
  656. int instanceID = event.caxis.which;
  657. auto it = gamepadMap.find(instanceID);
  658. if (it == gamepadMap.end())
  659. {
  660. std::cerr << std::string("Received event from invalid gamepad") << std::endl;
  661. return;
  662. }
  663. Gamepad* gamepad = it->second;
  664. int axis = event.caxis.axis;
  665. bool negative = event.caxis.value < 0;
  666. inputEvent->type = InputEvent::Type::GAMEPAD_AXIS;
  667. std::get<0>(inputEvent->gamepadAxis) = gamepad;
  668. std::get<1>(inputEvent->gamepadAxis) = axis;
  669. std::get<2>(inputEvent->gamepadAxis) = negative;
  670. return;
  671. }
  672. }