PlatformLinux.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  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. // Get the display and initialize.
  370. __display = XOpenDisplay(NULL);
  371. if (__display == NULL)
  372. {
  373. perror("XOpenDisplay");
  374. return NULL;
  375. }
  376. // GLX version
  377. GLint majorGLX, minorGLX = 0;
  378. glXQueryVersion(__display, &majorGLX, &minorGLX);
  379. if(majorGLX == 1 && minorGLX < 2)
  380. {
  381. perror("GLX 1.2 or greater is required.");
  382. XCloseDisplay(__display);
  383. return NULL;
  384. }
  385. else
  386. {
  387. printf( "GLX version: %d.%d\n", majorGLX , minorGLX);
  388. }
  389. // Get the GLX Functions
  390. glXCreateContextAttribsARB = (GLXContext(*)(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list))glXGetProcAddressARB((GLubyte*)"glXCreateContextAttribsARB");
  391. glXChooseFBConfig = (GLXFBConfig*(*)(Display *dpy, int screen, const int *attrib_list, int *nelements))glXGetProcAddressARB((GLubyte*)"glXChooseFBConfig");
  392. glXGetVisualFromFBConfig = (XVisualInfo*(*)(Display *dpy, GLXFBConfig config))glXGetProcAddressARB((GLubyte*)"glXGetVisualFromFBConfig");
  393. glXGetFBConfigAttrib = (int(*)(Display *dpy, GLXFBConfig config, int attribute, int *value))glXGetProcAddressARB((GLubyte*)"glXGetFBConfigAttrib");
  394. // Get the configs
  395. int configAttribs[] =
  396. {
  397. GLX_RENDER_TYPE, GLX_RGBA_BIT,
  398. GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
  399. GLX_X_RENDERABLE, True,
  400. GLX_DEPTH_SIZE, 24,
  401. GLX_STENCIL_SIZE, 8,
  402. GLX_RED_SIZE, 8,
  403. GLX_GREEN_SIZE, 8,
  404. GLX_BLUE_SIZE, 8,
  405. GLX_DOUBLEBUFFER, True,
  406. 0
  407. };
  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. glXMakeCurrent(__display, __window, __context);
  438. // Use OpenGL 2.x with GLEW
  439. glewExperimental = GL_TRUE;
  440. GLenum glewStatus = glewInit();
  441. if(glewStatus != GLEW_OK)
  442. {
  443. perror("glewInit");
  444. return NULL;
  445. }
  446. // GL Version
  447. int versionGL[2] = {-1, -1};
  448. glGetIntegerv(GL_MAJOR_VERSION, versionGL);
  449. glGetIntegerv(GL_MINOR_VERSION, versionGL + 1);
  450. printf("GL version: %d.%d\n", versionGL[0], versionGL[1]);
  451. // TODO: Get this workings
  452. //if (GLXEW_EXT_swap_control)
  453. // glXSwapIntervalEXT(__display, glXGetCurrentDrawable(), __vsync ? 1 : 0);
  454. return platform;
  455. }
  456. void cleanupX11()
  457. {
  458. if (__display)
  459. {
  460. glXMakeCurrent(__display, None, NULL);
  461. if (__context)
  462. glXDestroyContext(__display, __context);
  463. if (__window)
  464. XDestroyWindow(__display, __window);
  465. XCloseDisplay(__display);
  466. }
  467. }
  468. double timespec2millis(struct timespec *a)
  469. {
  470. GP_ASSERT(a);
  471. return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
  472. }
  473. void updateWindowSize()
  474. {
  475. GP_ASSERT(__display);
  476. GP_ASSERT(__window);
  477. XWindowAttributes windowAttrs;
  478. XGetWindowAttributes(__display, __window, &windowAttrs);
  479. __windowSize[0] = windowAttrs.width;
  480. __windowSize[1] = windowAttrs.height;
  481. }
  482. int Platform::enterMessagePump()
  483. {
  484. GP_ASSERT(_game);
  485. updateWindowSize();
  486. static const float ACCELEROMETER_X_FACTOR = 90.0f / __windowSize[0];
  487. static const float ACCELEROMETER_Y_FACTOR = 90.0f / __windowSize[1];
  488. static int lx = 0;
  489. static int ly = 0;
  490. static bool shiftDown = false;
  491. static bool capsOn = false;
  492. static XEvent evt;
  493. // Get the initial time.
  494. clock_gettime(CLOCK_REALTIME, &__timespec);
  495. __timeStart = timespec2millis(&__timespec);
  496. __timeAbsolute = 0L;
  497. // Run the game.
  498. _game->run();
  499. // Setup select for message handling (to allow non-blocking)
  500. int x11_fd = ConnectionNumber(__display);
  501. pollfd xpolls[1];
  502. xpolls[0].fd = x11_fd;
  503. xpolls[0].events = POLLIN|POLLPRI;
  504. // Message loop.
  505. while (true)
  506. {
  507. int ret = poll( xpolls, 1, 16 );
  508. // handle all pending events in one block
  509. while (ret && XPending(__display))
  510. {
  511. XNextEvent(__display, &evt);
  512. switch (evt.type)
  513. {
  514. case DestroyNotify :
  515. {
  516. cleanupX11();
  517. exit(0);
  518. }
  519. break;
  520. case Expose:
  521. {
  522. updateWindowSize();
  523. }
  524. break;
  525. case KeyPress:
  526. {
  527. KeySym sym = XLookupKeysym(&evt.xkey, 0);
  528. Keyboard::Key key = getKey(sym);
  529. gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_PRESS, key);
  530. }
  531. break;
  532. case KeyRelease:
  533. {
  534. KeySym sym = XLookupKeysym(&evt.xkey, 0);
  535. Keyboard::Key key = getKey(sym);
  536. gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_PRESS, key);
  537. }
  538. break;
  539. case ButtonPress:
  540. {
  541. gameplay::Mouse::MouseEvent mouseEvt;
  542. switch(evt.xbutton.button)
  543. {
  544. case 1:
  545. mouseEvt = gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON;
  546. break;
  547. case 2:
  548. mouseEvt = gameplay::Mouse::MOUSE_PRESS_MIDDLE_BUTTON;
  549. break;
  550. case 3:
  551. mouseEvt = gameplay::Mouse::MOUSE_PRESS_RIGHT_BUTTON;
  552. break;
  553. case 4:
  554. case 5:
  555. gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_WHEEL,
  556. evt.xbutton.x, evt.xbutton.y,
  557. evt.xbutton.button == Button4 ? 1 : -1);
  558. break;
  559. default:
  560. break;
  561. }
  562. if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
  563. {
  564. gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, evt.xbutton.x, evt.xbutton.y, 0);
  565. }
  566. }
  567. break;
  568. case ButtonRelease:
  569. {
  570. gameplay::Mouse::MouseEvent mouseEvt;
  571. switch(evt.xbutton.button)
  572. {
  573. case 1:
  574. mouseEvt = gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON;
  575. break;
  576. case 2:
  577. mouseEvt = gameplay::Mouse::MOUSE_RELEASE_MIDDLE_BUTTON;
  578. break;
  579. case 3:
  580. mouseEvt = gameplay::Mouse::MOUSE_RELEASE_RIGHT_BUTTON;
  581. break;
  582. default:
  583. break;
  584. }
  585. if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
  586. {
  587. gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, evt.xbutton.x, evt.xbutton.y, 0);
  588. }
  589. }
  590. break;
  591. case MotionNotify:
  592. {
  593. if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_MOVE, evt.xmotion.x, evt.xmotion.y, 0))
  594. {
  595. if (evt.xmotion.state & Button1Mask)
  596. {
  597. gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, evt.xmotion.x, evt.xmotion.y, 0);
  598. }
  599. else if (evt.xmotion.state & Button3Mask)
  600. {
  601. // Update the pitch and roll by adding the scaled deltas.
  602. __roll += (float)(evt.xbutton.x - lx) * ACCELEROMETER_X_FACTOR;
  603. __pitch += -(float)(evt.xbutton.y - ly) * ACCELEROMETER_Y_FACTOR;
  604. // Clamp the values to the valid range.
  605. __roll = max(min(__roll, 90.0f), -90.0f);
  606. __pitch = max(min(__pitch, 90.0f), -90.0f);
  607. // Update the last X/Y values.
  608. lx = evt.xbutton.x;
  609. ly = evt.xbutton.y;
  610. }
  611. }
  612. }
  613. break;
  614. default:
  615. break;
  616. }
  617. }
  618. _game->frame();
  619. glXSwapBuffers(__display, __window);
  620. }
  621. cleanupX11();
  622. return 0;
  623. }
  624. void Platform::signalShutdown()
  625. {
  626. // nothing to do
  627. }
  628. unsigned int Platform::getDisplayWidth()
  629. {
  630. return __windowSize[0];
  631. }
  632. unsigned int Platform::getDisplayHeight()
  633. {
  634. return __windowSize[1];
  635. }
  636. double Platform::getAbsoluteTime()
  637. {
  638. clock_gettime(CLOCK_REALTIME, &__timespec);
  639. double now = timespec2millis(&__timespec);
  640. __timeAbsolute = now - __timeStart;
  641. return __timeAbsolute;
  642. }
  643. void Platform::setAbsoluteTime(double time)
  644. {
  645. __timeAbsolute = time;
  646. }
  647. bool Platform::isVsync()
  648. {
  649. return __vsync;
  650. }
  651. void Platform::setVsync(bool enable)
  652. {
  653. // TODO: Get this working
  654. //if (GLXEW_EXT_swap_control)
  655. // glXSwapIntervalEXT(__display, glXGetCurrentDrawable(), __vsync ? 1 : 0);
  656. __vsync = enable;
  657. }
  658. void Platform::setMultiTouch(bool enabled)
  659. {
  660. // not supported
  661. }
  662. bool Platform::isMultiTouch()
  663. {
  664. false;
  665. }
  666. void Platform::getAccelerometerValues(float* pitch, float* roll)
  667. {
  668. GP_ASSERT(pitch);
  669. GP_ASSERT(roll);
  670. *pitch = __pitch;
  671. *roll = __roll;
  672. }
  673. bool Platform::hasMouse()
  674. {
  675. return true;
  676. }
  677. void Platform::setMouseCaptured(bool captured)
  678. {
  679. // TODO
  680. }
  681. bool Platform::isMouseCaptured()
  682. {
  683. // TODO
  684. return false;
  685. }
  686. void Platform::setCursorVisible(bool visible)
  687. {
  688. if (visible != __cursorVisible)
  689. {
  690. if (visible)
  691. {
  692. XDefineCursor(__display, __window, None);
  693. }
  694. else
  695. {
  696. XUndefineCursor(__display, __window);
  697. }
  698. XFlush(__display);
  699. __cursorVisible = visible;
  700. }
  701. }
  702. bool Platform::isCursorVisible()
  703. {
  704. return __cursorVisible;
  705. }
  706. void Platform::swapBuffers()
  707. {
  708. glXSwapBuffers(__display, __window);
  709. }
  710. void Platform::displayKeyboard(bool display)
  711. {
  712. // not supported
  713. }
  714. void Platform::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  715. {
  716. if (!Form::touchEventInternal(evt, x, y, contactIndex))
  717. {
  718. Game::getInstance()->touchEvent(evt, x, y, contactIndex);
  719. Game::getInstance()->getScriptController()->touchEvent(evt, x, y, contactIndex);
  720. }
  721. }
  722. void Platform::keyEventInternal(Keyboard::KeyEvent evt, int key)
  723. {
  724. if (!Form::keyEventInternal(evt, key))
  725. {
  726. Game::getInstance()->keyEvent(evt, key);
  727. Game::getInstance()->getScriptController()->keyEvent(evt, key);
  728. }
  729. }
  730. bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
  731. {
  732. if (Form::mouseEventInternal(evt, x, y, wheelDelta))
  733. {
  734. return true;
  735. }
  736. else if (Game::getInstance()->mouseEvent(evt, x, y, wheelDelta))
  737. {
  738. return true;
  739. }
  740. else
  741. {
  742. return Game::getInstance()->getScriptController()->mouseEvent(evt, x, y, wheelDelta);
  743. }
  744. }
  745. void Platform::sleep(long ms)
  746. {
  747. usleep(ms * 1000);
  748. }
  749. unsigned int Platform::getGamepadsConnected()
  750. {
  751. return 0;
  752. }
  753. bool Platform::isGamepadConnected(unsigned int gamepadHandle)
  754. {
  755. return false;
  756. }
  757. const char* Platform::getGamepadId(unsigned int gamepadHandle)
  758. {
  759. return NULL;
  760. }
  761. unsigned int Platform::getGamepadButtonCount(unsigned int gamepadHandle)
  762. {
  763. return 0;
  764. }
  765. bool Platform::getGamepadButtonState(unsigned int gamepadHandle, unsigned int buttonIndex)
  766. {
  767. return false;
  768. }
  769. unsigned int Platform::getGamepadJoystickCount(unsigned int gamepadHandle)
  770. {
  771. return 0;
  772. }
  773. bool Platform::isGamepadJoystickActive(unsigned int gamepadHandle, unsigned int joystickIndex)
  774. {
  775. return false;
  776. }
  777. float Platform::getGamepadJoystickAxisX(unsigned int gamepadHandle, unsigned int joystickIndex)
  778. {
  779. return 0.0f;
  780. }
  781. float Platform::getGamepadJoystickAxisY(unsigned int gamepadHandle, unsigned int joystickIndex)
  782. {
  783. return 0.0f;
  784. }
  785. void Platform::getGamepadJoystickAxisValues(unsigned int gamepadHandle, unsigned int joystickIndex, Vector2* outValue)
  786. {
  787. }
  788. unsigned int Platform::getGamepadTriggerCount(unsigned int gamepadHandle)
  789. {
  790. return 0;
  791. }
  792. float Platform::getGamepadTriggerValue(unsigned int gamepadHandle, unsigned int triggerIndex)
  793. {
  794. return 0.0f;
  795. }
  796. }
  797. #endif