PlatformLinux.cpp 24 KB

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