PlatformLinux.cpp 24 KB

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