Gamepad.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. /*
  2. * Gamepad.cpp
  3. */
  4. #include "Base.h"
  5. #include "Gamepad.h"
  6. #include "Texture.h"
  7. namespace gameplay
  8. {
  9. static Gamepad* __gamepad = NULL;
  10. Gamepad::Gamepad()
  11. : _buttonCount(0), _joystickCount(0), _texture(NULL), _spriteBatch(NULL)
  12. {
  13. }
  14. Gamepad::Gamepad(const Gamepad* g)
  15. {
  16. }
  17. Gamepad::~Gamepad()
  18. {
  19. }
  20. Gamepad::Button::Button()
  21. : _pressed(BUTTON_RELEASED), _key(Input::KEY_NONE), _position(Vector2::zero()),
  22. _defaultTexCoord(Vector4::zero()), _defaultTexture(false),
  23. _focusTexCoord(Vector4::zero()), _focusTexture(false)
  24. {
  25. }
  26. Gamepad::Button::Button(const Button& button)
  27. {
  28. }
  29. Gamepad::Button::~Button()
  30. {
  31. }
  32. Gamepad::Joystick::Joystick()
  33. : _direction(Vector2::zero()), _deltaX(0.0f), _deltaY(0.0f),
  34. _north(Input::KEY_NONE), _south(Input::KEY_NONE), _east(Input::KEY_NONE), _west(Input::KEY_NONE), _radius(0.0f), _enabledMovement(false),
  35. _boundsInner(Vector4::zero()),
  36. _defaultTextureInner(false), _defaultTexCoordInner(Vector4::zero()),
  37. _focusTextureInner(false), _focusTexCoordInner(Vector4::zero()),
  38. _boundsOuter(Vector4::zero()),
  39. _defaultTextureOuter(false), _defaultTexCoordOuter(Vector4::zero()),
  40. _focusTextureOuter(false), _focusTexCoordOuter(Vector4::zero())
  41. {
  42. }
  43. Gamepad::Joystick::Joystick(const Joystick& joystick)
  44. {
  45. }
  46. Gamepad::Joystick::~Joystick()
  47. {
  48. }
  49. Gamepad::ButtonState Gamepad::getButtonState(unsigned int index) const
  50. {
  51. assert(index < MAX_BUTTONS);
  52. return _buttons[index]._pressed;
  53. }
  54. Input::Key Gamepad::getButtonKeyModifier(unsigned int index) const
  55. {
  56. assert(index < MAX_BUTTONS);
  57. return _buttons[index]._key;
  58. }
  59. void Gamepad::setButtonKeyModifier(unsigned int index, Input::Key key)
  60. {
  61. assert(index < MAX_BUTTONS);
  62. _buttons[index]._key = key;
  63. }
  64. const Vector2& Gamepad::getJoystickState(unsigned int index) const
  65. {
  66. assert(index < MAX_JOYSTICKS);
  67. return _joysticks[index]._direction;
  68. }
  69. Input::Key Gamepad::getJoystickKeyModifier(unsigned int index, JoystickOrientation orientation) const
  70. {
  71. assert(index < MAX_JOYSTICKS);
  72. Input::Key key;
  73. switch(orientation)
  74. {
  75. case NORTH:
  76. key = _joysticks[index]._north;
  77. break;
  78. case SOUTH:
  79. key = _joysticks[index]._south;
  80. break;
  81. case EAST:
  82. key = _joysticks[index]._east;
  83. break;
  84. case WEST:
  85. key = _joysticks[index]._west;
  86. break;
  87. }
  88. return key;
  89. }
  90. void Gamepad::setJoystickKeyModifier(unsigned int index, JoystickOrientation orientation, Input::Key key)
  91. {
  92. assert(index < MAX_JOYSTICKS);
  93. switch(orientation)
  94. {
  95. case NORTH:
  96. _joysticks[index]._north = key;
  97. break;
  98. case SOUTH:
  99. _joysticks[index]._south = key;
  100. break;
  101. case EAST:
  102. _joysticks[index]._east = key;
  103. break;
  104. case WEST:
  105. _joysticks[index]._west = key;
  106. break;
  107. }
  108. }
  109. bool Gamepad::loadButtons(Gamepad* gamepad, Properties* properties)
  110. {
  111. properties->rewind();
  112. Properties* buttons = NULL;
  113. while ((buttons = properties->getNextNamespace()))
  114. {
  115. buttons->rewind();
  116. // Create and load a button.
  117. if (strcmp(buttons->getNamespace(), "button") == 0)
  118. {
  119. Button* button = new Button();
  120. const char* name = NULL;
  121. while (name = buttons->getNextProperty())
  122. {
  123. float u1 = 0.0f, v1 = 0.0f , u2 = 0.0f, v2 = 0.0f;
  124. if (strcmp(name, "x") == 0)
  125. {
  126. button->_position.x = buttons->getFloat();
  127. }
  128. else if (strcmp(name, "y") == 0)
  129. {
  130. button->_position.y = buttons->getFloat();
  131. }
  132. if (strcmp(name, "width") == 0)
  133. {
  134. button->_width = buttons->getFloat();
  135. }
  136. else if (strcmp(name, "height") == 0)
  137. {
  138. button->_height = buttons->getFloat();
  139. }
  140. else if (strcmp(name, "default") == 0)
  141. {
  142. Vector2 out = Vector2(0.0, 0.0);
  143. buttons->getVector2(NULL, &out);
  144. button->_defaultTexCoord.x = out.x; // u1
  145. button->_defaultTexCoord.y = out.y; // v1
  146. button->_defaultTexture = true;
  147. }
  148. else if (strcmp(name, "focus") == 0)
  149. {
  150. Vector2 out = Vector2(0.0, 0.0);
  151. buttons->getVector2(NULL, &out);
  152. button->_focusTexCoord.x = out.x; // u1
  153. button->_focusTexCoord.y = out.y; // v1
  154. button->_focusTexture = true;
  155. }
  156. else if (strcmp(name, "key-modifier") == 0)
  157. {
  158. button->_key = (Input::Key)buttons->getInt();
  159. }
  160. }
  161. // if (u1, v1) of default and focus button texture is specified in the gamepad file then
  162. // calculate the respective (u2, v2).
  163. if (button->_defaultTexture)
  164. {
  165. button->_defaultTexCoord.x = (button->_defaultTexCoord.x / gamepad->_texture->getWidth() );
  166. button->_defaultTexCoord.y = 1.0f - (button->_defaultTexCoord.y / gamepad->_texture->getHeight());
  167. button->_defaultTexCoord.z = button->_defaultTexCoord.x + (button->_width / gamepad->_texture->getWidth()); // u2
  168. button->_defaultTexCoord.w = button->_defaultTexCoord.y - (button->_width / gamepad->_texture->getHeight()); // v2
  169. }
  170. if (button->_focusTexture)
  171. {
  172. button->_focusTexCoord.x = (button->_focusTexCoord.x / gamepad->_texture->getWidth() );
  173. button->_focusTexCoord.y = 1.0f - (button->_focusTexCoord.y / gamepad->_texture->getHeight());
  174. button->_focusTexCoord.z = button->_focusTexCoord.x + (button->_width / gamepad->_texture->getWidth()); // u2
  175. button->_focusTexCoord.w = button->_focusTexCoord.y - (button->_width / gamepad->_texture->getWidth()); // v2
  176. }
  177. gamepad->addButton(button);
  178. }
  179. }
  180. return true;
  181. }
  182. bool Gamepad::loadJoysticks(Gamepad* gamepad, Properties* properties)
  183. {
  184. properties->rewind();
  185. Properties* joysticks = NULL;
  186. while ((joysticks = properties->getNextNamespace()))
  187. {
  188. joysticks->rewind();
  189. Vector4 defaultTexCoordInner = Vector4::zero();
  190. Vector4 defaultTexCoordOuter = Vector4::zero();
  191. // Create and load a button.
  192. if (strcmp(joysticks->getNamespace(), "joystick") == 0)
  193. {
  194. Joystick* joystick = new Joystick();
  195. const char* name = NULL;
  196. while (name = joysticks->getNextProperty())
  197. {
  198. float u1 = 0.0f, v1 = 0.0f , u2 = 0.0f, v2 = 0.0f;
  199. if (strcmp(name, "bounds-outer") == 0)
  200. {
  201. joysticks->getVector4(NULL, &joystick->_boundsOuter);
  202. }
  203. else if (strcmp(name, "bounds-inner") == 0)
  204. {
  205. joysticks->getVector4(NULL, &joystick->_boundsInner);
  206. }
  207. else if (strcmp(name, "default-inner") == 0)
  208. {
  209. joysticks->getVector4(NULL, &defaultTexCoordInner);
  210. joystick->_defaultTextureInner = true;
  211. }
  212. else if (strcmp(name, "focus-inner") == 0)
  213. {
  214. // TODO.
  215. }
  216. else if (strcmp(name, "default-outer") == 0)
  217. {
  218. joysticks->getVector4(NULL, &defaultTexCoordOuter);
  219. joystick->_defaultTextureOuter = true;
  220. }
  221. else if (strcmp(name, "focus-outer") == 0)
  222. {
  223. // TODO.
  224. }
  225. else if (strcmp(name, "key-modifier") == 0)
  226. {
  227. // TODO.
  228. }
  229. else if (strcmp(name, "radius") == 0)
  230. {
  231. joystick->_radius = joysticks->getFloat(NULL);
  232. }
  233. }
  234. // if (u1, v1) of default and focus button texture is specified in the gamepad file then
  235. // calculate the respective (u2, v2).
  236. if (joystick->_defaultTextureInner)
  237. {
  238. joystick->_defaultTexCoordInner.x = (defaultTexCoordInner.x / gamepad->_texture->getWidth());
  239. joystick->_defaultTexCoordInner.y = 1.0f - (defaultTexCoordInner.y / gamepad->_texture->getHeight());
  240. joystick->_defaultTexCoordInner.z = joystick->_defaultTexCoordInner.x + (defaultTexCoordInner.z / gamepad->_texture->getWidth()); // u2
  241. joystick->_defaultTexCoordInner.w = joystick->_defaultTexCoordInner.y - (defaultTexCoordInner.w / gamepad->_texture->getHeight()); // v2
  242. }
  243. if (joystick->_defaultTextureOuter)
  244. {
  245. joystick->_defaultTexCoordOuter.x = (defaultTexCoordOuter.x / gamepad->_texture->getWidth());
  246. joystick->_defaultTexCoordOuter.y = 1.0f - (defaultTexCoordOuter.y / gamepad->_texture->getHeight());
  247. joystick->_defaultTexCoordOuter.z = joystick->_defaultTexCoordOuter.x + (defaultTexCoordOuter.z / gamepad->_texture->getWidth()); // u2
  248. joystick->_defaultTexCoordOuter.w = joystick->_defaultTexCoordOuter.y - (defaultTexCoordOuter.w / gamepad->_texture->getHeight()); // v2
  249. }
  250. gamepad->addJoystick(joystick);
  251. }
  252. }
  253. return true;
  254. }
  255. void Gamepad::setSpriteBatch(SpriteBatch* spriteBatch)
  256. {
  257. _spriteBatch = spriteBatch;
  258. }
  259. Gamepad* Gamepad::create(const char* gamepadPath)
  260. {
  261. assert (gamepadPath);
  262. // Load the gamepad properties from file
  263. Properties* properties = Properties::create(gamepadPath);
  264. assert(properties);
  265. if (properties == NULL)
  266. {
  267. return NULL;
  268. }
  269. Properties* gamepadProperties = properties->getNextNamespace();
  270. assert (gamepadProperties);
  271. if (!gamepadProperties || !(strcmp(gamepadProperties->getNamespace(), "gamepad") == 0))
  272. {
  273. SAFE_DELETE(properties);
  274. return NULL;
  275. }
  276. // Load the gamepad texture.
  277. const char* texturePath = gamepadProperties->getString("texture");
  278. if (strlen(texturePath) == 0)
  279. {
  280. LOG_ERROR_VARG("Error loading Gamepad: No valid texture path specified, in %s", gamepadPath);
  281. return NULL;
  282. }
  283. Gamepad* gamepad = new Gamepad();
  284. gamepad->_texture = Texture::create(texturePath, true);
  285. assert(gamepad->_texture);
  286. // Load gamepad components.
  287. Properties* componentProperties = NULL;
  288. while ((componentProperties = gamepadProperties->getNextNamespace()))
  289. {
  290. if (strcmp(componentProperties->getNamespace(), "buttons") == 0)
  291. {
  292. if (!loadButtons(gamepad, componentProperties))
  293. {
  294. SAFE_RELEASE(gamepad);
  295. SAFE_DELETE(properties);
  296. return NULL;
  297. }
  298. }
  299. else if (strcmp(componentProperties->getNamespace(), "joysticks") == 0)
  300. {
  301. if(!loadJoysticks(gamepad, componentProperties))
  302. {
  303. SAFE_RELEASE(gamepad);
  304. SAFE_DELETE(properties);
  305. return NULL;
  306. }
  307. }
  308. }
  309. // Create a sprite batch.
  310. // TODO: determine the "actual" number of sprites required when parsing the .gamepad file.
  311. SpriteBatch* spriteBatch = SpriteBatch::create(gamepad->_texture, 0, MAX_BUTTONS + MAX_JOYSTICKS);
  312. gamepad->_spriteBatch = spriteBatch;
  313. return gamepad;
  314. }
  315. void Gamepad::update(long elapsedTime)
  316. {
  317. }
  318. void Gamepad::draw()
  319. {
  320. _spriteBatch->begin();
  321. // Draw buttons.
  322. for (int i = 0; i < _buttonCount; ++i)
  323. {
  324. if ((_buttons[i]._pressed == BUTTON_PRESSED) && (_buttons[i]._focusTexture))
  325. {
  326. _spriteBatch->draw(_buttons[i]._position.x, _buttons[i]._position.y, _buttons[i]._width, _buttons[i]._height,
  327. _buttons[i]._focusTexCoord.x, _buttons[i]._focusTexCoord.y, _buttons[i]._focusTexCoord.z, _buttons[i]._focusTexCoord.w,
  328. Vector4::one());
  329. continue;
  330. }
  331. else
  332. {
  333. _spriteBatch->draw(_buttons[i]._position.x, _buttons[i]._position.y, _buttons[i]._width, _buttons[i]._height,
  334. _buttons[i]._defaultTexCoord.x, _buttons[i]._defaultTexCoord.y, _buttons[i]._defaultTexCoord.z, _buttons[i]._defaultTexCoord.w,
  335. Vector4::one());
  336. }
  337. }
  338. // Draw joysticks.
  339. for (int i = 0; i < _joystickCount; ++i)
  340. {
  341. // Draw Outer joggle.
  342. float x = _joysticks[i]._boundsOuter.x;
  343. float y = _joysticks[i]._boundsOuter.y;
  344. float width = _joysticks[i]._boundsOuter.z;
  345. float height = _joysticks[i]._boundsOuter.w;
  346. float radius = _joysticks[i]._radius;
  347. float outerJoggleRadius = _joysticks[i]._boundsOuter.z / 2.0f;
  348. x = x - (width / 2.0f);
  349. y = y - (height / 2.0f);
  350. float u1 = _joysticks[i]._defaultTexCoordOuter.x;
  351. float v1 = _joysticks[i]._defaultTexCoordOuter.y;
  352. float u2 = _joysticks[i]._defaultTexCoordOuter.z;
  353. float v2 = _joysticks[i]._defaultTexCoordOuter.w;
  354. _spriteBatch->draw(x, y, width, height, u1, v1, u2, v2, Vector4::one());
  355. // Draw Inner joggle.
  356. x = _joysticks[i]._boundsInner.x;
  357. y = _joysticks[i]._boundsInner.y;
  358. width = _joysticks[i]._boundsInner.z;
  359. height = _joysticks[i]._boundsInner.w;
  360. // Move position to reflect displacement.
  361. if (((_joysticks[i]._deltaX * _joysticks[i]._deltaX) +
  362. (_joysticks[i]._deltaY * _joysticks[i]._deltaY)) <=
  363. (outerJoggleRadius * outerJoggleRadius))
  364. {
  365. x += _joysticks[i]._deltaX;
  366. y += _joysticks[i]._deltaY;
  367. }
  368. else
  369. {
  370. Vector2 dir = Vector2(_joysticks[i]._deltaX, _joysticks[i]._deltaY);
  371. dir.normalize();
  372. dir.scale(outerJoggleRadius);
  373. x += dir.x;
  374. y += dir.y;
  375. }
  376. // Adjust inner joggle (x, y) position to point to top right.
  377. x = x - (width / 2.0f);
  378. y = y - (height / 2.0f);
  379. u1 = _joysticks[i]._defaultTexCoordInner.x;
  380. v1 = _joysticks[i]._defaultTexCoordInner.y;
  381. u2 = _joysticks[i]._defaultTexCoordInner.z;
  382. v2 = _joysticks[i]._defaultTexCoordInner.w;
  383. _spriteBatch->draw(x, y, width, height, u1, v1, u2, v2, Vector4::one());
  384. }
  385. _spriteBatch->end();
  386. }
  387. void Gamepad::keyPress(int key, int keyEvent)
  388. {
  389. }
  390. void Gamepad::touch(int x, int y, int touchEvent)
  391. {
  392. for (int i = 0; i < _buttonCount; ++i)
  393. {
  394. if ((x >= _buttons[i]._position.x) && (x <= (_buttons[i]._position.x + _buttons[i]._width)) &&
  395. (y >= _buttons[i]._position.y) && (y <= (_buttons[i]._position.y + _buttons[i]._height)))
  396. {
  397. switch(touchEvent)
  398. {
  399. case Input::TOUCHEVENT_PRESS:
  400. {
  401. _buttons[i]._pressed = BUTTON_PRESSED;
  402. }
  403. break;
  404. case Input::TOUCHEVENT_RELEASE:
  405. {
  406. _buttons[i]._pressed = BUTTON_RELEASED;
  407. }
  408. break;
  409. }
  410. }
  411. }
  412. for (int i = 0; i < _joystickCount; ++i)
  413. {
  414. switch(touchEvent)
  415. {
  416. case Input::TOUCHEVENT_PRESS:
  417. {
  418. float bx = _joysticks[i]._boundsOuter.x;
  419. float by = _joysticks[i]._boundsOuter.y;
  420. float bwidth = _joysticks[i]._boundsOuter.z;
  421. float bheight = _joysticks[i]._boundsOuter.w;
  422. if ((x >= (bx - (bwidth / 2.0f))) && (x <= (bx + (bwidth / 2.0f))) &&
  423. (y >= (by - (bheight / 2.0f))) && (y <= (by + (bheight / 2.0f))))
  424. {
  425. _joysticks[i]._enabledMovement = true;
  426. _joysticks[i]._deltaX = 0.0f;
  427. _joysticks[i]._deltaY = 0.0f;
  428. _joysticks[i]._direction.zero();
  429. }
  430. }
  431. case Input::TOUCHEVENT_MOVE:
  432. {
  433. if (_joysticks[i]._enabledMovement)
  434. {
  435. _joysticks[i]._deltaX = x - _joysticks[i]._boundsOuter.x;
  436. _joysticks[i]._deltaY = y - _joysticks[i]._boundsOuter.y;
  437. if (((_joysticks[i]._deltaX * _joysticks[i]._deltaX) +
  438. (_joysticks[i]._deltaY * _joysticks[i]._deltaY)) <=
  439. ((_joysticks[i]._radius * _joysticks[i]._radius)))
  440. {
  441. _joysticks[i]._direction.x = _joysticks[i]._deltaX;
  442. _joysticks[i]._direction.y = _joysticks[i]._deltaY;
  443. //_joysticks[i]._direction.normalize();
  444. _joysticks[i]._direction.scale(1.0f / _joysticks[i]._radius);
  445. }
  446. else
  447. {
  448. if (_joysticks[i]._deltaX > _joysticks[i]._radius)
  449. {
  450. _joysticks[i]._direction.x = _joysticks[i]._radius;
  451. }
  452. if (_joysticks[i]._deltaX < -_joysticks[i]._radius)
  453. {
  454. _joysticks[i]._direction.x = -_joysticks[i]._radius;
  455. }
  456. if (_joysticks[i]._deltaY > _joysticks[i]._radius)
  457. {
  458. _joysticks[i]._direction.y = _joysticks[i]._radius;
  459. }
  460. if (_joysticks[i]._deltaY < -_joysticks[i]._radius)
  461. {
  462. _joysticks[i]._direction.y = -_joysticks[i]._radius;
  463. }
  464. _joysticks[i]._direction.scale(1.0f / _joysticks[i]._radius);
  465. //_joysticks[i]._direction.scale(_joysticks[i]._radius);
  466. //_joysticks[i]._direction.normalize();
  467. }
  468. // _joysticks[i]._direction.normalize();
  469. // _joysticks[i]._direction.scale(1.0f / _joysticks[i]._radius);
  470. }
  471. }
  472. break;
  473. case Input::TOUCHEVENT_RELEASE:
  474. {
  475. if (_joysticks[i]._enabledMovement)
  476. {
  477. _joysticks[i]._deltaX = 0.0f;
  478. _joysticks[i]._deltaY = 0.0f;
  479. _joysticks[i]._direction.x = 0.0f;
  480. _joysticks[i]._direction.y = 0.0f;
  481. _joysticks[i]._enabledMovement = false;
  482. }
  483. }
  484. break;
  485. }
  486. }
  487. }
  488. void Gamepad::setCurrentGamepad(Gamepad* gamepad)
  489. {
  490. __gamepad = gamepad;
  491. }
  492. Gamepad* Gamepad::getCurrentGamepad()
  493. {
  494. return __gamepad;
  495. }
  496. void Gamepad::addButton(Button* button)
  497. {
  498. if (_buttonCount == MAX_BUTTONS)
  499. {
  500. return;
  501. }
  502. _buttons[_buttonCount] = *button;
  503. _buttonCount++;
  504. }
  505. void Gamepad::addJoystick(Joystick* joystick)
  506. {
  507. if (_joystickCount == MAX_JOYSTICKS)
  508. {
  509. return;
  510. }
  511. _joysticks[_joystickCount] = *joystick;
  512. _joystickCount++;
  513. }
  514. }