AndroidInput.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platformAndroid/platformAndroid.h"
  23. #include "platformAndroid/AndroidUtil.h"
  24. #include "platform/platformInput.h"
  25. #include "platform/event.h"
  26. #include "console/console.h"
  27. #include "game/gameInterface.h"
  28. #include "string/unicode.h"
  29. #include "gui/guiCanvas.h"
  30. // <Mat> just some random number 50, we'll get a proper value later
  31. #define Android_DOUBLE_CLICK_TIME ( 50 * 60.0f * 1000.0f)
  32. // Static class variables:
  33. InputManager* Input::smManager;
  34. bool Input::smActive;
  35. CursorManager* Input::smCursorManager = 0;
  36. bool gInputEnabled = false;
  37. bool gMouseEnabled = false;
  38. bool gKBEnabled = false;
  39. bool gMouseActive = false;
  40. bool gKBActive = false;
  41. //------------------------------------------------------------------------------
  42. // Helper functions. Should migrate to an InputManager object at some point.
  43. bool enableKeyboard(void);
  44. void disableKeyboard(void);
  45. bool activateKeyboard(void);
  46. void deactivateKeyboard(void);
  47. bool enableMouse(void);
  48. void disableMouse(void);
  49. bool activateMouse(void);
  50. void deactivateMouse(void);
  51. static void fillAsciiTable();
  52. struct touchEvent {
  53. S32 number;
  54. S32 x;
  55. S32 y;
  56. touchEvent( S32 a, S32 b, S32 c ) {
  57. number = a;
  58. x = b;
  59. y = c;
  60. }
  61. };
  62. Vector<touchEvent> TouchMoveEvents;//<Mat> to make sure we don't have multiple events per frame
  63. Vector<touchEvent> TouchDownEvents;
  64. Vector<touchEvent> TouchUpEvents;
  65. // EFM - BEGIN TOUCH CHANGES
  66. #define MAX_TOUCH_EVENTS 5
  67. struct touchTracker {
  68. S32 lastX;
  69. S32 lastY;
  70. Vector<touchEvent> downEvents;
  71. Vector<touchEvent> moveEvents;
  72. Vector<touchEvent> upEvents;
  73. };
  74. touchTracker CombinedTouchEvents[MAX_TOUCH_EVENTS];
  75. struct touchCorrelation {
  76. S32 lastX;
  77. S32 lastY;
  78. };
  79. touchCorrelation lastTouches[MAX_TOUCH_EVENTS];
  80. // EFM - END TOUCH CHANGES
  81. //Luma: Tap support
  82. Vector<touchEvent> TouchTapEvents;
  83. int processMultipleTouches();
  84. //------------------------------------------------------------------------------
  85. //
  86. // This function gets the standard ASCII code corresponding to our key code
  87. // and the existing modifier key state.
  88. //
  89. //------------------------------------------------------------------------------
  90. struct AsciiData
  91. {
  92. struct KeyData
  93. {
  94. U16 ascii;
  95. bool isDeadChar;
  96. };
  97. KeyData upper;
  98. KeyData lower;
  99. KeyData goofy;
  100. };
  101. #define NUM_KEYS ( KEY_OEM_102 + 1 )
  102. #define KEY_FIRST KEY_ESCAPE
  103. static AsciiData AsciiTable[NUM_KEYS];
  104. void Input::enableMouse()
  105. {
  106. // Do nothing on Android
  107. }
  108. void Input::disableMouse()
  109. {
  110. // Do nothing on Android
  111. }
  112. void Input::enableKeyboard()
  113. {
  114. // Do nothing on Android
  115. }
  116. void Input::disableKeyboard()
  117. {
  118. // Do nothing on Android
  119. }
  120. bool Input::isMouseEnabled()
  121. {
  122. return true;
  123. }
  124. bool Input::isKeyboardEnabled()
  125. {
  126. return false;
  127. }
  128. //--------------------------------------------------------------------------
  129. void Input::init()
  130. {
  131. Con::printf( "Input Init:" );
  132. destroy();
  133. smManager = NULL;
  134. //smManager = new AndroidInputManager();
  135. smActive = false;
  136. // stop the double-cursor thing
  137. Con::setBoolVariable("$pref::Gui::noClampTorqueCursorToWindow", true);
  138. // enable main input
  139. Input::enable();
  140. // Startup the Cursor Manager
  141. if(!smCursorManager)
  142. {
  143. smCursorManager = new CursorManager();
  144. if(smCursorManager)
  145. {
  146. // Add the arrow cursor to the stack
  147. smCursorManager->pushCursor(CursorManager::curArrow);
  148. }
  149. else
  150. {
  151. Con::printf(" Cursor Manager not enabled.");
  152. }
  153. }
  154. for(int i = 0 ; i < MAX_TOUCH_EVENTS; i++ )
  155. {
  156. lastTouches[i].lastX = -1;
  157. lastTouches[i].lastY = -1;
  158. }
  159. Con::printf( "" );
  160. }
  161. //------------------------------------------------------------------------------
  162. ConsoleFunction( isJoystickDetected, bool, 1, 1, "Always false on the Android." )
  163. {
  164. /*
  165. argc; argv;
  166. return( DInputDevice::joystickDetected() );
  167. */
  168. return(false);
  169. }
  170. //------------------------------------------------------------------------------
  171. ConsoleFunction( getJoystickAxes, const char*, 2, 2, "(handle instance)" )
  172. {
  173. return( "" );
  174. }
  175. //------------------------------------------------------------------------------
  176. static void fillAsciiTable()
  177. {
  178. }
  179. //------------------------------------------------------------------------------
  180. U16 Input::getKeyCode( U16 asciiCode )
  181. {
  182. U16 keyCode = 0;
  183. U16 i;
  184. // This is done three times so the lowerkey will always
  185. // be found first. Some foreign keyboards have duplicate
  186. // chars on some keys.
  187. for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
  188. {
  189. if ( AsciiTable[i].lower.ascii == asciiCode )
  190. {
  191. keyCode = i;
  192. break;
  193. };
  194. }
  195. for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
  196. {
  197. if ( AsciiTable[i].upper.ascii == asciiCode )
  198. {
  199. keyCode = i;
  200. break;
  201. };
  202. }
  203. for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
  204. {
  205. if ( AsciiTable[i].goofy.ascii == asciiCode )
  206. {
  207. keyCode = i;
  208. break;
  209. };
  210. }
  211. return( keyCode );
  212. }
  213. //------------------------------------------------------------------------------
  214. U16 Input::getAscii( U16 keyCode, KEY_STATE keyState )
  215. {
  216. if ( keyCode >= NUM_KEYS )
  217. return 0;
  218. switch ( keyState )
  219. {
  220. case STATE_LOWER:
  221. return AsciiTable[keyCode].lower.ascii;
  222. case STATE_UPPER:
  223. return AsciiTable[keyCode].upper.ascii;
  224. case STATE_GOOFY:
  225. return AsciiTable[keyCode].goofy.ascii;
  226. default:
  227. return(0);
  228. }
  229. }
  230. //------------------------------------------------------------------------------
  231. void Input::destroy()
  232. {
  233. // turn us off.
  234. if (gInputEnabled)
  235. disable();
  236. if ( smManager && smManager->isEnabled() )
  237. {
  238. smManager->disable();
  239. delete smManager;
  240. smManager = NULL;
  241. }
  242. }
  243. //------------------------------------------------------------------------------
  244. bool Input::enable()
  245. {
  246. Con::printf( "[]Input::enable." );
  247. gInputEnabled = true;
  248. if ( smManager && !smManager->isEnabled() )
  249. return( smManager->enable() );
  250. enableMouse();
  251. //enableKeyboard();
  252. return( gInputEnabled );
  253. }
  254. //------------------------------------------------------------------------------
  255. void Input::disable()
  256. {
  257. Con::printf( "[]Input::disable." );
  258. gInputEnabled = false;
  259. if ( smManager && smManager->isEnabled() )
  260. smManager->disable();
  261. disableMouse();
  262. //disableKeyboard();
  263. }
  264. //------------------------------------------------------------------------------
  265. void Input::activate()
  266. {
  267. smActive = true;
  268. enableMouse();
  269. // enableKeyboard();
  270. }
  271. //------------------------------------------------------------------------------
  272. void Input::deactivate()
  273. {
  274. //Con::printf( "[]Input::deactivate." );
  275. deactivateMouse();
  276. //deactivateKeyboard();
  277. smActive = false;
  278. }
  279. //------------------------------------------------------------------------------
  280. void Input::reactivate()
  281. {
  282. // don't think mac needs to do anything right now!!!!!! TBD
  283. // This is soo hacky...
  284. // SetForegroundWindow( winState.appWindow );
  285. // PostMessage( winState.appWindow, WM_ACTIVATE, WA_ACTIVE, NULL );
  286. }
  287. //------------------------------------------------------------------------------
  288. bool Input::isEnabled()
  289. {
  290. if ( smManager )
  291. return smManager->isEnabled();
  292. return(gInputEnabled);
  293. }
  294. //------------------------------------------------------------------------------
  295. bool Input::isActive()
  296. {
  297. return smActive;
  298. }
  299. //------------------------------------------------------------------------------
  300. void Input::process()
  301. {
  302. //only gets called once per frame, create touches and accelerometer events here
  303. //post, then pop each event
  304. if(platState.multipleTouchesEnabled) processMultipleTouches();
  305. if (!smActive || !gInputEnabled)
  306. return;
  307. if (!gMouseEnabled || !gMouseActive)
  308. return;
  309. if ( smManager && smManager->isEnabled() && smActive )
  310. smManager->process();
  311. }
  312. //------------------------------------------------------------------------------
  313. InputManager* Input::getManager()
  314. {
  315. return( smManager );
  316. }
  317. #pragma mark ---- Clipboard functions ----
  318. //-----------------------------------------------------------------------------
  319. const char* Platform::getClipboard()
  320. {
  321. return NULL;//no clipboard on Android
  322. }
  323. //-----------------------------------------------------------------------------
  324. bool Platform::setClipboard(const char *text)
  325. {
  326. return false;//no clipboard on Android
  327. }
  328. #pragma mark ---- Cursor Functions ----
  329. //------------------------------------------------------------------------------
  330. void Input::pushCursor(S32 cursorID)
  331. {
  332. CursorManager* cm = getCursorManager();
  333. if(cm)
  334. cm->pushCursor(cursorID);
  335. }
  336. //------------------------------------------------------------------------------
  337. void Input::popCursor()
  338. {
  339. CursorManager* cm = getCursorManager();
  340. if(cm)
  341. cm->popCursor();
  342. }
  343. //------------------------------------------------------------------------------
  344. void Input::refreshCursor()
  345. {
  346. CursorManager* cm = getCursorManager();
  347. if(cm)
  348. cm->refreshCursor();
  349. }
  350. #pragma mark ---- DoubleClick Functions ----
  351. //------------------------------------------------------------------------------
  352. U32 Input::getDoubleClickTime()
  353. {
  354. return Android_DOUBLE_CLICK_TIME;
  355. }
  356. //------------------------------------------------------------------------------
  357. S32 Input::getDoubleClickWidth()
  358. {
  359. // this is an arbitrary value.
  360. return 10;
  361. }
  362. //------------------------------------------------------------------------------
  363. S32 Input::getDoubleClickHeight()
  364. {
  365. return getDoubleClickWidth();
  366. }
  367. #pragma mark -
  368. //------------------------------------------------------------------------------
  369. bool enableKeyboard()
  370. {
  371. if ( !gInputEnabled )
  372. return( false );
  373. if ( gKBEnabled && gKBActive )
  374. return( true );
  375. gKBEnabled = true;
  376. if ( Input::isActive() )
  377. gKBEnabled = activateKeyboard();
  378. if ( gKBEnabled )
  379. {
  380. Con::printf( "Hardware-direct keyboard enabled." );
  381. }
  382. else
  383. {
  384. Con::warnf( "Hardware-direct keyboard failed to enable!" );
  385. }
  386. return( gKBEnabled );
  387. }
  388. //------------------------------------------------------------------------------
  389. void disableKeyboard()
  390. {
  391. if ( !gInputEnabled || !gKBEnabled )
  392. return;
  393. deactivateKeyboard();
  394. gKBEnabled = false;
  395. Con::printf( "Hardware-direct keyboard disabled." );
  396. }
  397. //------------------------------------------------------------------------------
  398. bool activateKeyboard()
  399. {
  400. if ( !gInputEnabled || !Input::isActive() || !gKBEnabled )
  401. return( false );
  402. gKBActive = true;
  403. return( gKBActive );
  404. }
  405. //------------------------------------------------------------------------------
  406. void deactivateKeyboard()
  407. {
  408. if ( gInputEnabled && gKBActive )
  409. {
  410. gKBActive = false;
  411. }
  412. }
  413. //------------------------------------------------------------------------------
  414. bool enableMouse()
  415. {
  416. if ( !gInputEnabled )
  417. return( false );
  418. if ( gMouseEnabled && gMouseActive )
  419. return( true );
  420. gMouseEnabled = activateMouse();
  421. return( gMouseEnabled );
  422. }
  423. //------------------------------------------------------------------------------
  424. void disableMouse()
  425. {
  426. if ( !gInputEnabled || !gMouseEnabled )
  427. return;
  428. deactivateMouse();
  429. gMouseEnabled = false;
  430. bool hwMouse = false;
  431. Con::printf( "%s disabled", hwMouse?"Hardware-direct mouse":"Basic mouse capture");
  432. }
  433. //------------------------------------------------------------------------------
  434. bool activateMouse()
  435. {
  436. if ( !gInputEnabled || !Input::isActive() || !gMouseEnabled )
  437. return( false );
  438. if (gMouseActive)
  439. return(true);
  440. gMouseActive = true;
  441. return( gMouseActive );
  442. }
  443. //------------------------------------------------------------------------------
  444. void deactivateMouse()
  445. {
  446. if ( !gInputEnabled || !gMouseActive )
  447. return;
  448. gMouseActive = false;
  449. }
  450. //------------------------------------------------------------------------------
  451. ConsoleFunction( enableMouse, bool, 1, 1, "enableMouse()" )
  452. {
  453. return( enableMouse() );
  454. }
  455. //------------------------------------------------------------------------------
  456. ConsoleFunction( disableMouse, void, 1, 1, "disableMouse()" )
  457. {
  458. disableMouse();
  459. }
  460. //------------------------------------------------------------------------------
  461. void printInputState(void)
  462. {
  463. if ( gInputEnabled )
  464. {
  465. Con::printf( "Low-level input system is enabled." );
  466. Con::printf( "- Keyboard is %sabled and %sactive.",
  467. gKBEnabled ? "en" : "dis",
  468. gKBActive ? "" : "in" );
  469. Con::printf( "- Mouse is %sabled and %sactive.",
  470. gMouseEnabled ? "en" : "dis",
  471. gMouseActive ? "" : "in" );
  472. /*
  473. Con::printf( "- Joystick is %sabled and %sactive.",
  474. gJoystickEnabled() ? "en" : "dis",
  475. gJoystickActive() ? "" : "in" );
  476. */
  477. }
  478. else
  479. {
  480. Con::printf( "Low-level input system is disabled." );
  481. }
  482. }
  483. //------------------------------------------------------------------------------
  484. ConsoleFunction( echoInputState, void, 1, 1, "echoInputState()" )
  485. {
  486. printInputState();
  487. }
  488. //------------------------------------------------------------------------------
  489. ConsoleFunction( toggleInputState, void, 1, 1, "toggleInputState()" )
  490. {
  491. if (gInputEnabled)
  492. Input::disable();
  493. else
  494. Input::enable();
  495. printInputState();
  496. }
  497. //------------------------------------------------------------------------------
  498. ConsoleFunction( deactivateKeyboard, void, 1, 1, "deactivateKeyboard();")
  499. {
  500. // these are only useful on the windows side. They deal with some vagaries of win32 DirectInput.
  501. }
  502. ConsoleFunction( activateKeyboard, void, 1, 1, "activateKeyboard();")
  503. {
  504. // these are only useful on the windows side. They deal with some vagaries of win32 DirectInput.
  505. }
  506. //------------------------------------------------------------------------------
  507. void Input::setCursorPos(S32 x, S32 y)
  508. {
  509. //this gets called from GuiCanvas to set the game mouse cursor
  510. }
  511. int processMultipleTouches()
  512. {
  513. char posX[256], posY[256], temp[10], touchNums[256];
  514. dMemset(posX, 0, sizeof(posX));
  515. dMemset(posY, 0, sizeof(posY));
  516. dMemset(touchNums, 0, sizeof(touchNums));
  517. touchEvent *currentEvent;
  518. //Down Events
  519. int numTouchDownEvents = TouchDownEvents.size();
  520. while( TouchDownEvents.size() > 0 )
  521. {
  522. currentEvent = &TouchDownEvents.last();
  523. dItoa( currentEvent->x, temp );
  524. dStrcat( posX, temp );
  525. dStrcat( posX, " " );
  526. dItoa( currentEvent->y, temp );
  527. dStrcat( posY, temp );
  528. dStrcat( posY, " " );
  529. dItoa( currentEvent->number, temp );
  530. dStrcat( touchNums, temp );
  531. dStrcat( touchNums, " " );
  532. TouchDownEvents.pop_back();
  533. }
  534. dItoa( numTouchDownEvents, temp );
  535. if( numTouchDownEvents > 0 )
  536. {
  537. InputEvent touchEvent;
  538. touchEvent.deviceInst = 0;
  539. touchEvent.objInst = SI_TOUCHDOWN;
  540. touchEvent.deviceType = ScreenTouchDeviceType;
  541. touchEvent.action = SI_TOUCH;
  542. touchEvent.objType = SI_TOUCHDOWN;
  543. dStrcpy(touchEvent.fingersX, posX);
  544. dStrcpy(touchEvent.fingersY, posY);
  545. dStrcpy(touchEvent.fingerIDs, touchNums);
  546. touchEvent.modifier = 0;
  547. Game->postEvent(touchEvent);
  548. }
  549. // Deprecated in 1.5
  550. //if( numTouchDownEvents > 0 )
  551. // Con::executef( 4, "onAndroidTouchDown", touchNums , posX, posY );
  552. //Move events
  553. int numTouchMoveEvents = TouchMoveEvents.size();
  554. while( TouchMoveEvents.size() > 0 )
  555. {
  556. currentEvent = &TouchMoveEvents.last();
  557. dItoa( currentEvent->x, temp );
  558. dStrcat( posX, temp );
  559. dStrcat( posX, " " );
  560. dItoa( currentEvent->y, temp );
  561. dStrcat( posY, temp );
  562. dStrcat( posY, " " );
  563. dItoa( currentEvent->number, temp );
  564. dStrcat( touchNums, temp );
  565. dStrcat( touchNums, " " );
  566. TouchMoveEvents.pop_back();
  567. }
  568. dItoa( numTouchMoveEvents, temp );
  569. if( numTouchMoveEvents > 0 )
  570. {
  571. InputEvent touchEvent;
  572. touchEvent.deviceInst = 0;
  573. touchEvent.objInst = SI_TOUCHMOVE;
  574. touchEvent.deviceType = ScreenTouchDeviceType;
  575. touchEvent.action = SI_TOUCH;
  576. touchEvent.objType = SI_TOUCHMOVE;
  577. dStrcpy(touchEvent.fingersX, posX);
  578. dStrcpy(touchEvent.fingersY, posY);
  579. dStrcpy(touchEvent.fingerIDs, touchNums);
  580. touchEvent.modifier = 0;
  581. Game->postEvent(touchEvent);
  582. }
  583. // Deprecated in 1.5 -MP
  584. //if( numTouchMoveEvents > 0 )
  585. // Con::executef( 4, "onAndroidTouchMove", touchNums , posX, posY );
  586. //Up events
  587. int numTouchUpEvents = TouchUpEvents.size();
  588. dMemset(posX, 0, sizeof(posX));
  589. dMemset(posY, 0, sizeof(posY));
  590. dMemset(touchNums, 0, sizeof(touchNums));
  591. while( TouchUpEvents.size() > 0 )
  592. {
  593. currentEvent = &TouchUpEvents.last();
  594. dItoa( currentEvent->x, temp );
  595. dStrcat( posX, temp );
  596. dStrcat( posX, " " );
  597. dItoa( currentEvent->y, temp );
  598. dStrcat( posY, temp );
  599. dStrcat( posY, " " );
  600. dItoa( currentEvent->number, temp );
  601. dStrcat( touchNums, temp );
  602. dStrcat( touchNums, " " );
  603. lastTouches[currentEvent->number].lastX = -1;
  604. lastTouches[currentEvent->number].lastY = -1;
  605. int x;
  606. x = -1;
  607. lastTouches[currentEvent->number].lastX = -1;
  608. lastTouches[currentEvent->number].lastY = -1;
  609. TouchUpEvents.pop_back();
  610. }
  611. dItoa( numTouchUpEvents, temp );
  612. if( numTouchUpEvents > 0 )
  613. {
  614. InputEvent touchEvent;
  615. touchEvent.deviceInst = 0;
  616. touchEvent.objInst = SI_TOUCHUP;
  617. touchEvent.deviceType = ScreenTouchDeviceType;
  618. touchEvent.action = SI_TOUCH;
  619. touchEvent.objType = SI_TOUCHUP;
  620. dStrcpy(touchEvent.fingersX, posX);
  621. dStrcpy(touchEvent.fingersY, posY);
  622. dStrcpy(touchEvent.fingerIDs, touchNums);
  623. touchEvent.modifier = 0;
  624. Game->postEvent(touchEvent);
  625. }
  626. // Deprecated in 1.5 -MP
  627. //if( numTouchUpEvents > 0 )
  628. // Con::executef( 4, "onAndroidTouchUp", touchNums , posX, posY );
  629. //Luma: Tap support
  630. posX[0] = '\0';
  631. posY[0] = '\0';
  632. int numTapEvents = TouchTapEvents.size();
  633. while( TouchTapEvents.size() > 0 )
  634. {
  635. currentEvent = &TouchTapEvents.last();
  636. sprintf( temp, "%d ", currentEvent->x );
  637. dStrcat( posX, temp );
  638. sprintf( temp, "%d ", currentEvent->y );
  639. dStrcat( posY, temp );
  640. TouchTapEvents.pop_back();
  641. }
  642. sprintf( temp, "%d", numTapEvents );
  643. //if( numTapEvents > 0 )
  644. // Con::executef( 4, "onAndroidTouchTap", temp , posX, posY );
  645. return numTouchDownEvents + numTouchMoveEvents + numTouchUpEvents;
  646. }
  647. //we want these to only be called once per frame!!
  648. bool createMouseMoveEvent( S32 touchNumber, S32 x, S32 y, S32 lastX, S32 lastY ) //EFM
  649. {
  650. S32 currentSlot = -1;
  651. if (Canvas == NULL)
  652. return false;
  653. for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (currentSlot == -1) ; i++ )
  654. {
  655. if( (lastX == lastTouches[i].lastX ) &&
  656. (lastY == lastTouches[i].lastY ) )
  657. {
  658. currentSlot = i;
  659. }
  660. }
  661. if( currentSlot == -1 ) return false;
  662. ScreenTouchEvent event;
  663. event.xPos = x;
  664. event.yPos = y;
  665. event.action = SI_MOVE;
  666. event.touchID = currentSlot;
  667. event.numTouches = 0;
  668. //Luma: Mouse not moving (no hover for mouse fingers!)
  669. Canvas->setCursorPos( Point2I( x, y ) );
  670. if( currentSlot != -1 )
  671. {
  672. lastTouches[currentSlot].lastX = x;
  673. lastTouches[currentSlot].lastY = y;
  674. }
  675. TouchMoveEvents.push_back( touchEvent( currentSlot, x, y ) );
  676. Game->postEvent(event);
  677. return true;//return false if we get bad values or something
  678. }
  679. bool createMouseDownEvent( S32 touchNumber, S32 x, S32 y, U32 numTouches )
  680. {
  681. S32 vacantSlot = -1;
  682. if (Canvas == NULL)
  683. return false;
  684. for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (vacantSlot == -1) ; i++ )
  685. {
  686. if( lastTouches[i].lastX == -1 )
  687. {
  688. vacantSlot = i;
  689. }
  690. }
  691. if( vacantSlot == -1 )
  692. return false;
  693. ScreenTouchEvent event;
  694. event.xPos = x;
  695. event.yPos = y;
  696. event.touchID = vacantSlot;
  697. event.action = SI_MAKE;
  698. event.numTouches = numTouches;
  699. //Luma: Update position
  700. Canvas->setCursorPos( Point2I( x, y ) );
  701. if( vacantSlot != -1 )
  702. {
  703. lastTouches[vacantSlot].lastX = x;
  704. lastTouches[vacantSlot].lastY = y;
  705. }
  706. TouchDownEvents.push_back( touchEvent( vacantSlot, x, y ) );
  707. Game->postEvent(event);
  708. return true;//return false if we get bad values or something
  709. }
  710. bool createMouseUpEvent( S32 touchNumber, S32 x, S32 y, S32 lastX, S32 lastY, U32 numTouches ) //EFM
  711. {
  712. S32 currentSlot = -1;
  713. for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (currentSlot == -1) ; i++ )
  714. {
  715. if(( (x == lastTouches[i].lastX) && (y == lastTouches[i].lastY )) ||
  716. ( (lastX == lastTouches[i].lastX ) && (lastY == lastTouches[i].lastY )))
  717. {
  718. currentSlot = i;
  719. }
  720. }
  721. if( currentSlot == -1 )
  722. return false;
  723. ScreenTouchEvent event;
  724. event.xPos = x;
  725. event.yPos = y;
  726. event.action = SI_BREAK;
  727. event.touchID = currentSlot;
  728. event.numTouches = numTouches;
  729. TouchUpEvents.push_back( touchEvent( currentSlot, x, y ) );
  730. Game->postEvent(event);
  731. return true;//return false if we get bad values or something
  732. }
  733. void clearPendingMultitouchEvents( void ) //EFM
  734. {
  735. for( int i = 0 ; i < MAX_TOUCH_EVENTS ; i++ )
  736. {
  737. lastTouches[i].lastX = -1;
  738. lastTouches[i].lastY = -1;
  739. }
  740. TouchMoveEvents.clear();
  741. TouchDownEvents.clear();
  742. TouchUpEvents.clear();
  743. }
  744. //Luma: Tap support
  745. void createMouseTapEvent( S32 nbrTaps, S32 x, S32 y ) {
  746. TouchTapEvents.push_back( touchEvent( nbrTaps, x, y ) );
  747. }