PlatformLinux.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. #ifdef __linux__
  2. #include "Base.h"
  3. #include "Platform.h"
  4. #include "FileSystem.h"
  5. #include "Game.h"
  6. #include "Form.h"
  7. #include "ScriptController.h"
  8. #include <X11/X.h>
  9. #include <X11/Xlib.h>
  10. #include <X11/keysym.h>
  11. #include <sys/time.h>
  12. #include <GL/glxew.h>
  13. #define TOUCH_COUNT_MAX 4
  14. using namespace std;
  15. struct timespec __timespec;
  16. static double __timeStart;
  17. static double __timeAbsolute;
  18. static bool __vsync = WINDOW_VSYNC;
  19. static float __pitch;
  20. static float __roll;
  21. static bool __cursorVisible = true;
  22. static Display* __display;
  23. static Window __window;
  24. static int __windowSize[2];
  25. static GLXContext __context;
  26. static Window __attachToWindow;
  27. namespace gameplay
  28. {
  29. // Gets the Keyboard::Key enumeration constant that corresponds to the given X11 key symbol.
  30. static Keyboard::Key getKey(KeySym sym)
  31. {
  32. switch (sym)
  33. {
  34. case XK_Sys_Req:
  35. return Keyboard::KEY_SYSREQ;
  36. case XK_Break:
  37. return Keyboard::KEY_BREAK;
  38. case XK_Menu :
  39. return Keyboard::KEY_MENU;
  40. case XK_KP_Enter:
  41. return Keyboard::KEY_KP_ENTER;
  42. case XK_Pause:
  43. return Keyboard::KEY_PAUSE;
  44. case XK_Scroll_Lock:
  45. return Keyboard::KEY_SCROLL_LOCK;
  46. case XK_Print:
  47. return Keyboard::KEY_PRINT;
  48. case XK_Escape:
  49. return Keyboard::KEY_ESCAPE;
  50. case XK_BackSpace:
  51. return Keyboard::KEY_BACKSPACE;
  52. case XK_Tab:
  53. return Keyboard::KEY_TAB;
  54. case XK_Return:
  55. return Keyboard::KEY_RETURN;
  56. case XK_Caps_Lock:
  57. return Keyboard::KEY_CAPS_LOCK;
  58. case XK_Shift_L:
  59. case XK_Shift_R:
  60. return Keyboard::KEY_SHIFT;
  61. case XK_Control_L:
  62. case XK_Control_R:
  63. return Keyboard::KEY_CTRL;
  64. case XK_Alt_L:
  65. case XK_Alt_R:
  66. return Keyboard::KEY_ALT;
  67. case XK_Hyper_L:
  68. case XK_Hyper_R:
  69. return Keyboard::KEY_HYPER;
  70. case XK_Insert:
  71. return Keyboard::KEY_INSERT;
  72. case XK_Home:
  73. return Keyboard::KEY_HOME;
  74. case XK_Page_Up:
  75. return Keyboard::KEY_PG_UP;
  76. case XK_Delete:
  77. return Keyboard::KEY_DELETE;
  78. case XK_End:
  79. return Keyboard::KEY_END;
  80. case XK_Page_Down:
  81. return Keyboard::KEY_PG_DOWN;
  82. case XK_Left:
  83. return Keyboard::KEY_LEFT_ARROW;
  84. case XK_Right:
  85. return Keyboard::KEY_RIGHT_ARROW;
  86. case XK_Up:
  87. return Keyboard::KEY_UP_ARROW;
  88. case XK_Down:
  89. return Keyboard::KEY_DOWN_ARROW;
  90. case XK_Num_Lock:
  91. return Keyboard::KEY_NUM_LOCK;
  92. case XK_KP_Add:
  93. return Keyboard::KEY_KP_PLUS;
  94. case XK_KP_Subtract:
  95. return Keyboard::KEY_KP_MINUS;
  96. case XK_KP_Multiply:
  97. return Keyboard::KEY_KP_MULTIPLY;
  98. case XK_KP_Divide:
  99. return Keyboard::KEY_KP_DIVIDE;
  100. case XK_KP_Home:
  101. return Keyboard::KEY_KP_HOME;
  102. case XK_KP_Up:
  103. return Keyboard::KEY_KP_UP;
  104. case XK_KP_Page_Up:
  105. return Keyboard::KEY_KP_PG_UP;
  106. case XK_KP_Left:
  107. return Keyboard::KEY_KP_LEFT;
  108. case XK_KP_5:
  109. return Keyboard::KEY_KP_FIVE;
  110. case XK_KP_Right:
  111. return Keyboard::KEY_KP_RIGHT;
  112. case XK_KP_End:
  113. return Keyboard::KEY_KP_END;
  114. case XK_KP_Down:
  115. return Keyboard::KEY_KP_DOWN;
  116. case XK_KP_Page_Down:
  117. return Keyboard::KEY_KP_PG_DOWN;
  118. case XK_KP_Insert:
  119. return Keyboard::KEY_KP_INSERT;
  120. case XK_KP_Delete:
  121. return Keyboard::KEY_KP_DELETE;
  122. case XK_F1:
  123. return Keyboard::KEY_F1;
  124. case XK_F2:
  125. return Keyboard::KEY_F2;
  126. case XK_F3:
  127. return Keyboard::KEY_F3;
  128. case XK_F4:
  129. return Keyboard::KEY_F4;
  130. case XK_F5:
  131. return Keyboard::KEY_F5;
  132. case XK_F6:
  133. return Keyboard::KEY_F6;
  134. case XK_F7:
  135. return Keyboard::KEY_F7;
  136. case XK_F8:
  137. return Keyboard::KEY_F8;
  138. case XK_F9:
  139. return Keyboard::KEY_F9;
  140. case XK_F10:
  141. return Keyboard::KEY_F10;
  142. case XK_F11:
  143. return Keyboard::KEY_F11;
  144. case XK_F12:
  145. return Keyboard::KEY_F12;
  146. case XK_KP_Space:
  147. return Keyboard::KEY_SPACE;
  148. case XK_parenright:
  149. return Keyboard::KEY_RIGHT_PARENTHESIS;
  150. case XK_0:
  151. return Keyboard::KEY_ZERO;
  152. case XK_exclam:
  153. return Keyboard::KEY_EXCLAM;
  154. case XK_1:
  155. return Keyboard::KEY_ONE;
  156. case XK_at:
  157. return Keyboard::KEY_AT;
  158. case XK_2:
  159. return Keyboard::KEY_TWO;
  160. case XK_numbersign:
  161. return Keyboard::KEY_NUMBER;
  162. case XK_3:
  163. return Keyboard::KEY_THREE;
  164. case XK_dollar:
  165. return Keyboard::KEY_DOLLAR;
  166. case XK_4:
  167. return Keyboard::KEY_FOUR;
  168. case XK_percent:
  169. case XK_asciicircum :
  170. return Keyboard::KEY_CIRCUMFLEX;
  171. return Keyboard::KEY_PERCENT;
  172. case XK_5:
  173. return Keyboard::KEY_FIVE;
  174. case XK_6:
  175. return Keyboard::KEY_SIX;
  176. case XK_ampersand:
  177. return Keyboard::KEY_AMPERSAND;
  178. case XK_7:
  179. return Keyboard::KEY_SEVEN;
  180. case XK_asterisk:
  181. return Keyboard::KEY_ASTERISK;
  182. case XK_8:
  183. return Keyboard::KEY_EIGHT;
  184. case XK_parenleft:
  185. return Keyboard::KEY_LEFT_PARENTHESIS;
  186. case XK_9:
  187. return Keyboard::KEY_NINE;
  188. case XK_equal:
  189. return Keyboard::KEY_EQUAL;
  190. case XK_plus:
  191. return Keyboard::KEY_PLUS;
  192. case XK_less:
  193. return Keyboard::KEY_LESS_THAN;
  194. case XK_comma:
  195. return Keyboard::KEY_COMMA;
  196. case XK_underscore:
  197. return Keyboard::KEY_UNDERSCORE;
  198. case XK_minus:
  199. return Keyboard::KEY_MINUS;
  200. case XK_greater:
  201. return Keyboard::KEY_GREATER_THAN;
  202. case XK_period:
  203. return Keyboard::KEY_PERIOD;
  204. case XK_colon:
  205. return Keyboard::KEY_COLON;
  206. case XK_semicolon:
  207. return Keyboard::KEY_SEMICOLON;
  208. case XK_question:
  209. return Keyboard::KEY_QUESTION;
  210. case XK_slash:
  211. return Keyboard::KEY_SLASH;
  212. case XK_grave:
  213. return Keyboard::KEY_GRAVE;
  214. case XK_asciitilde:
  215. return Keyboard::KEY_TILDE;
  216. case XK_braceleft:
  217. return Keyboard::KEY_LEFT_BRACE;
  218. case XK_bracketleft:
  219. return Keyboard::KEY_LEFT_BRACKET;
  220. case XK_bar:
  221. return Keyboard::KEY_BAR;
  222. case XK_backslash:
  223. return Keyboard::KEY_BACK_SLASH;
  224. case XK_braceright:
  225. return Keyboard::KEY_RIGHT_BRACE;
  226. case XK_bracketright:
  227. return Keyboard::KEY_RIGHT_BRACKET;
  228. case XK_quotedbl:
  229. return Keyboard::KEY_QUOTE;
  230. case XK_apostrophe:
  231. return Keyboard::KEY_APOSTROPHE;
  232. case XK_EuroSign:
  233. return Keyboard::KEY_EURO;
  234. case XK_sterling:
  235. return Keyboard::KEY_POUND;
  236. case XK_yen:
  237. return Keyboard::KEY_YEN;
  238. case XK_periodcentered:
  239. return Keyboard::KEY_MIDDLE_DOT;
  240. case XK_A:
  241. return Keyboard::KEY_CAPITAL_A;
  242. case XK_a:
  243. return Keyboard::KEY_A;
  244. case XK_B:
  245. return Keyboard::KEY_CAPITAL_B;
  246. case XK_b:
  247. return Keyboard::KEY_B;
  248. case XK_C:
  249. return Keyboard::KEY_CAPITAL_C;
  250. case XK_c:
  251. return Keyboard::KEY_C;
  252. case XK_D:
  253. return Keyboard::KEY_CAPITAL_D;
  254. case XK_d:
  255. return Keyboard::KEY_D;
  256. case XK_E:
  257. return Keyboard::KEY_CAPITAL_E;
  258. case XK_e:
  259. return Keyboard::KEY_E;
  260. case XK_F:
  261. return Keyboard::KEY_CAPITAL_F;
  262. case XK_f:
  263. return Keyboard::KEY_F;
  264. case XK_G:
  265. return Keyboard::KEY_CAPITAL_G;
  266. case XK_g:
  267. return Keyboard::KEY_G;
  268. case XK_H:
  269. return Keyboard::KEY_CAPITAL_H;
  270. case XK_h:
  271. return Keyboard::KEY_H;
  272. case XK_I:
  273. return Keyboard::KEY_CAPITAL_I;
  274. case XK_i:
  275. return Keyboard::KEY_I;
  276. case XK_J:
  277. return Keyboard::KEY_CAPITAL_J;
  278. case XK_j:
  279. return Keyboard::KEY_J;
  280. case XK_K:
  281. return Keyboard::KEY_CAPITAL_K;
  282. case XK_k:
  283. return Keyboard::KEY_K;
  284. case XK_L:
  285. return Keyboard::KEY_CAPITAL_L;
  286. case XK_l:
  287. return Keyboard::KEY_L;
  288. case XK_M:
  289. return Keyboard::KEY_CAPITAL_M;
  290. case XK_m:
  291. return Keyboard::KEY_M;
  292. case XK_N:
  293. return Keyboard::KEY_CAPITAL_N;
  294. case XK_n:
  295. return Keyboard::KEY_N;
  296. case XK_O:
  297. return Keyboard::KEY_CAPITAL_O;
  298. case XK_o:
  299. return Keyboard::KEY_O;
  300. case XK_P:
  301. return Keyboard::KEY_CAPITAL_P;
  302. case XK_p:
  303. return Keyboard::KEY_P;
  304. case XK_Q:
  305. return Keyboard::KEY_CAPITAL_Q;
  306. case XK_q:
  307. return Keyboard::KEY_Q;
  308. case XK_R:
  309. return Keyboard::KEY_CAPITAL_R;
  310. case XK_r:
  311. return Keyboard::KEY_R;
  312. case XK_S:
  313. return Keyboard::KEY_CAPITAL_S;
  314. case XK_s:
  315. return Keyboard::KEY_S;
  316. case XK_T:
  317. return Keyboard::KEY_CAPITAL_T;
  318. case XK_t:
  319. return Keyboard::KEY_T;
  320. case XK_U:
  321. return Keyboard::KEY_CAPITAL_U;
  322. case XK_u:
  323. return Keyboard::KEY_U;
  324. case XK_V:
  325. return Keyboard::KEY_CAPITAL_V;
  326. case XK_v:
  327. return Keyboard::KEY_V;
  328. case XK_W:
  329. return Keyboard::KEY_CAPITAL_W;
  330. case XK_w:
  331. return Keyboard::KEY_W;
  332. case XK_X:
  333. return Keyboard::KEY_CAPITAL_X;
  334. case XK_x:
  335. return Keyboard::KEY_X;
  336. case XK_Y:
  337. return Keyboard::KEY_CAPITAL_Y;
  338. case XK_y:
  339. return Keyboard::KEY_Y;
  340. case XK_Z:
  341. return Keyboard::KEY_CAPITAL_Z;
  342. case XK_z:
  343. return Keyboard::KEY_Z;
  344. default:
  345. return Keyboard::KEY_NONE;
  346. }
  347. }
  348. extern void printError(const char* format, ...)
  349. {
  350. GP_ASSERT(format);
  351. va_list argptr;
  352. va_start(argptr, format);
  353. vfprintf(stderr, format, argptr);
  354. va_end(argptr);
  355. }
  356. Platform::Platform(Game* game) : _game(game)
  357. {
  358. }
  359. Platform::~Platform()
  360. {
  361. }
  362. Platform* Platform::create(Game* game, void* attachToWindow)
  363. {
  364. GP_ASSERT(game);
  365. __attachToWindow = (Window)attachToWindow;
  366. FileSystem::setResourcePath("./");
  367. Platform* platform = new Platform(game);
  368. int configAttribs[] =
  369. {
  370. GLX_RENDER_TYPE, GLX_RGBA_BIT,GLX_RGBA,
  371. GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
  372. GLX_X_RENDERABLE, True,
  373. GLX_DEPTH_SIZE, 24,
  374. GLX_STENCIL_SIZE, 8,
  375. GLX_RED_SIZE, 8,
  376. GLX_BLUE_SIZE, 8,
  377. GLX_GREEN_SIZE, 8,
  378. GLX_DOUBLEBUFFER, True,
  379. 0
  380. };
  381. // Get the display and initialize.
  382. __display = XOpenDisplay(NULL);
  383. if (__display == NULL)
  384. {
  385. perror("XOpenDisplay");
  386. return NULL;
  387. }
  388. // GLX version
  389. GLint majorGLX, minorGLX = 0;
  390. glXQueryVersion(__display, &majorGLX, &minorGLX);
  391. if(majorGLX == 1 && minorGLX < 2)
  392. {
  393. perror("GLX 1.2 or greater is required.");
  394. XCloseDisplay(__display);
  395. return NULL;
  396. }
  397. else
  398. {
  399. printf( "GLX version: %d.%d\n", majorGLX , minorGLX);
  400. }
  401. // Get the GLX Functions
  402. glXCreateContextAttribsARB = (GLXContext(*)(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list))glXGetProcAddressARB((GLubyte*)"glXCreateContextAttribsARB");
  403. glXChooseFBConfig = (GLXFBConfig*(*)(Display *dpy, int screen, const int *attrib_list, int *nelements))glXGetProcAddressARB((GLubyte*)"glXChooseFBConfig");
  404. glXGetVisualFromFBConfig = (XVisualInfo*(*)(Display *dpy, GLXFBConfig config))glXGetProcAddressARB((GLubyte*)"glXGetVisualFromFBConfig");
  405. glXGetFBConfigAttrib = (int(*)(Display *dpy, GLXFBConfig config, int attribute, int *value))glXGetProcAddressARB((GLubyte*)"glXGetFBConfigAttrib");
  406. // Get the configs
  407. GLXFBConfig* configs;
  408. int configCount = 0;
  409. configs = glXChooseFBConfig(__display, DefaultScreen(__display), configAttribs, &configCount);
  410. // Create the windows
  411. XVisualInfo* visualInfo;
  412. visualInfo = glXGetVisualFromFBConfig(__display, configs[0]);
  413. XSetWindowAttributes winAttribs;
  414. long eventMask;
  415. eventMask = ExposureMask | VisibilityChangeMask | StructureNotifyMask |
  416. KeyPressMask | KeyReleaseMask | PointerMotionMask |
  417. ButtonPressMask | ButtonReleaseMask |
  418. EnterWindowMask | LeaveWindowMask;
  419. winAttribs.event_mask = eventMask;
  420. winAttribs.border_pixel = 0;
  421. winAttribs.bit_gravity = StaticGravity;
  422. winAttribs.colormap = XCreateColormap(__display, RootWindow(__display, visualInfo->screen), visualInfo->visual, AllocNone);
  423. GLint winMask;
  424. winMask = CWBorderPixel | CWBitGravity | CWEventMask| CWColormap;
  425. __window = XCreateWindow(__display, DefaultRootWindow(__display), 0, 0, 1280, 720, 0,
  426. visualInfo->depth, InputOutput, visualInfo->visual, winMask,
  427. &winAttribs);
  428. XMapWindow(__display, __window);
  429. XStoreName(__display, __window, "");
  430. __context = glXCreateContext(__display, visualInfo, NULL, True);
  431. glXMakeCurrent(__display, __window, __context);
  432. // Use OpenGL 2.x with GLEW (TODO: Currently crashing here...)
  433. glewExperimental = GL_TRUE;
  434. GLenum glewStatus = glewInit();
  435. if(glewStatus != GLEW_OK)
  436. {
  437. perror("glewInit");
  438. return NULL;
  439. }
  440. // GL Version
  441. int versionGL[2] = {-1, -1};
  442. glGetIntegerv(GL_MAJOR_VERSION, versionGL);
  443. glGetIntegerv(GL_MINOR_VERSION, versionGL + 1);
  444. printf("GL version: %d.%d\n", versionGL[0], versionGL[1]);
  445. // TODO: Get this workings
  446. //if (GLXEW_EXT_swap_control)
  447. // glXSwapIntervalEXT(__display, glXGetCurrentDrawable(), __vsync ? 1 : 0);
  448. return platform;
  449. }
  450. void cleanupX11()
  451. {
  452. if (__display)
  453. {
  454. glXMakeCurrent(__display, None, NULL);
  455. if (__context)
  456. glXDestroyContext(__display, __context);
  457. if (__window)
  458. XDestroyWindow(__display, __window);
  459. XCloseDisplay(__display);
  460. }
  461. }
  462. double timespec2millis(struct timespec *a)
  463. {
  464. GP_ASSERT(a);
  465. return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
  466. }
  467. int Platform::enterMessagePump()
  468. {
  469. GP_ASSERT(_game);
  470. static const float ACCELEROMETER_X_FACTOR = 90.0f / __windowSize[0];
  471. static const float ACCELEROMETER_Y_FACTOR = 90.0f / __windowSize[1];
  472. static int lx = 0;
  473. static int ly = 0;
  474. static bool suspended = false;
  475. static bool shiftDown = false;
  476. static bool capsOn = false;
  477. static XEvent evt;
  478. // Get the initial time.
  479. clock_gettime(CLOCK_REALTIME, &__timespec);
  480. __timeStart = timespec2millis(&__timespec);
  481. __timeAbsolute = 0L;
  482. // Run the game.
  483. _game->run();
  484. // Message loop.
  485. while (true)
  486. {
  487. XNextEvent(__display, &evt);
  488. switch (evt.type)
  489. {
  490. case DestroyNotify :
  491. {
  492. cleanupX11();
  493. exit(0);
  494. }
  495. break;
  496. case Expose:
  497. {
  498. XWindowAttributes windowAttrs;
  499. XGetWindowAttributes(__display, __window, &windowAttrs);
  500. __windowSize[0] = windowAttrs.width;
  501. __windowSize[1] = windowAttrs.height;
  502. if (!suspended)
  503. {
  504. _game->frame();
  505. glXSwapBuffers(__display, __window);
  506. }
  507. }
  508. break;
  509. case KeyPress:
  510. {
  511. KeySym sym = XLookupKeysym(&evt.xkey, 0);
  512. Keyboard::Key key = getKey(sym);
  513. gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_PRESS, key);
  514. }
  515. break;
  516. case KeyRelease:
  517. {
  518. KeySym sym = XLookupKeysym(&evt.xkey, 0);
  519. Keyboard::Key key = getKey(sym);
  520. gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_PRESS, key);
  521. }
  522. break;
  523. case ButtonPress:
  524. {
  525. gameplay::Mouse::MouseEvent mouseEvt;
  526. switch(evt.xbutton.button)
  527. {
  528. case 1:
  529. mouseEvt = gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON;
  530. break;
  531. case 2:
  532. mouseEvt = gameplay::Mouse::MOUSE_PRESS_MIDDLE_BUTTON;
  533. break;
  534. case 3:
  535. mouseEvt = gameplay::Mouse::MOUSE_PRESS_RIGHT_BUTTON;
  536. break;
  537. case 4:
  538. case 5:
  539. gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_WHEEL,
  540. evt.xbutton.x, evt.xbutton.y,
  541. evt.xbutton.button == Button4 ? 1 : -1);
  542. break;
  543. default:
  544. break;
  545. }
  546. if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
  547. {
  548. gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, evt.xbutton.x, evt.xbutton.y, 0);
  549. }
  550. }
  551. break;
  552. case ButtonRelease:
  553. {
  554. gameplay::Mouse::MouseEvent mouseEvt;
  555. switch(evt.xbutton.button)
  556. {
  557. case 1:
  558. mouseEvt = gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON;
  559. break;
  560. case 2:
  561. mouseEvt = gameplay::Mouse::MOUSE_RELEASE_MIDDLE_BUTTON;
  562. break;
  563. case 3:
  564. mouseEvt = gameplay::Mouse::MOUSE_RELEASE_RIGHT_BUTTON;
  565. break;
  566. default:
  567. break;
  568. }
  569. if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
  570. {
  571. gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, evt.xbutton.x, evt.xbutton.y, 0);
  572. }
  573. }
  574. break;
  575. case MotionNotify:
  576. {
  577. if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_MOVE, evt.xmotion.x, evt.xmotion.y, 0))
  578. {
  579. if (evt.xbutton.button == 1)
  580. {
  581. gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, evt.xmotion.x, evt.xmotion.y, 0);
  582. return 0;
  583. }
  584. else if (evt.xbutton.button == 3)
  585. {
  586. // Update the pitch and roll by adding the scaled deltas.
  587. __roll += (float)(evt.xbutton.x - lx) * ACCELEROMETER_X_FACTOR;
  588. __pitch += -(float)(evt.xbutton.y - ly) * ACCELEROMETER_Y_FACTOR;
  589. // Clamp the values to the valid range.
  590. __roll = max(min(__roll, 90.0f), -90.0f);
  591. __pitch = max(min(__pitch, 90.0f), -90.0f);
  592. // Update the last X/Y values.
  593. lx = evt.xbutton.x;
  594. ly = evt.xbutton.y;
  595. }
  596. }
  597. }
  598. break;
  599. default:
  600. break;
  601. }
  602. sleep(1);
  603. }
  604. cleanupX11();
  605. return 0;
  606. }
  607. void Platform::signalShutdown()
  608. {
  609. // nothing to do
  610. }
  611. unsigned int Platform::getDisplayWidth()
  612. {
  613. return __windowSize[0];
  614. }
  615. unsigned int Platform::getDisplayHeight()
  616. {
  617. return __windowSize[1];
  618. }
  619. double Platform::getAbsoluteTime()
  620. {
  621. clock_gettime(CLOCK_REALTIME, &__timespec);
  622. double now = timespec2millis(&__timespec);
  623. __timeAbsolute = now - __timeStart;
  624. return __timeAbsolute;
  625. }
  626. void Platform::setAbsoluteTime(double time)
  627. {
  628. __timeAbsolute = time;
  629. }
  630. bool Platform::isVsync()
  631. {
  632. return __vsync;
  633. }
  634. void Platform::setVsync(bool enable)
  635. {
  636. // TODO: Get this working
  637. //if (GLXEW_EXT_swap_control)
  638. // glXSwapIntervalEXT(__display, glXGetCurrentDrawable(), __vsync ? 1 : 0);
  639. __vsync = enable;
  640. }
  641. void Platform::setMultiTouch(bool enabled)
  642. {
  643. // not supported
  644. }
  645. bool Platform::isMultiTouch()
  646. {
  647. false;
  648. }
  649. void Platform::getAccelerometerValues(float* pitch, float* roll)
  650. {
  651. GP_ASSERT(pitch);
  652. GP_ASSERT(roll);
  653. *pitch = __pitch;
  654. *roll = __roll;
  655. }
  656. bool Platform::hasMouse()
  657. {
  658. return true;
  659. }
  660. void Platform::setMouseCaptured(bool captured)
  661. {
  662. // TODO
  663. }
  664. bool Platform::isMouseCaptured()
  665. {
  666. // TODO
  667. return false;
  668. }
  669. void Platform::setCursorVisible(bool visible)
  670. {
  671. if (visible != __cursorVisible)
  672. {
  673. if (visible)
  674. {
  675. XDefineCursor(__display, __window, None);
  676. }
  677. else
  678. {
  679. XUndefineCursor(__display, __window);
  680. }
  681. XFlush(__display);
  682. __cursorVisible = visible;
  683. }
  684. }
  685. bool Platform::isCursorVisible()
  686. {
  687. return __cursorVisible;
  688. }
  689. void Platform::swapBuffers()
  690. {
  691. glXSwapBuffers(__display, __window);
  692. }
  693. void Platform::displayKeyboard(bool display)
  694. {
  695. // not supported
  696. }
  697. void Platform::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  698. {
  699. if (!Form::touchEventInternal(evt, x, y, contactIndex))
  700. {
  701. Game::getInstance()->touchEvent(evt, x, y, contactIndex);
  702. Game::getInstance()->getScriptController()->touchEvent(evt, x, y, contactIndex);
  703. }
  704. }
  705. void Platform::keyEventInternal(Keyboard::KeyEvent evt, int key)
  706. {
  707. if (!Form::keyEventInternal(evt, key))
  708. {
  709. Game::getInstance()->keyEvent(evt, key);
  710. Game::getInstance()->getScriptController()->keyEvent(evt, key);
  711. }
  712. }
  713. bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
  714. {
  715. if (Form::mouseEventInternal(evt, x, y, wheelDelta))
  716. {
  717. return true;
  718. }
  719. else if (Game::getInstance()->mouseEvent(evt, x, y, wheelDelta))
  720. {
  721. return true;
  722. }
  723. else
  724. {
  725. return Game::getInstance()->getScriptController()->mouseEvent(evt, x, y, wheelDelta);
  726. }
  727. }
  728. void Platform::sleep(long ms)
  729. {
  730. usleep(ms * 1000);
  731. }
  732. }
  733. #endif