Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

SDLSystem.cpp 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. /*================================================================
  3. *
  4. * Project : OpenRaider
  5. * Author : Terry 'Mongoose' Hendrix II
  6. * Website : http://www.westga.edu/~stu7440/
  7. * Email : stu7440@westga.edu
  8. * Object : SDL
  9. * License : No use w/o permission (C) 2002 Mongoose
  10. * Comments:
  11. *
  12. *
  13. * This file was generated using Mongoose's C++
  14. * template generator script. <stu7440@westga.edu>
  15. *
  16. *-- History -------------------------------------------------
  17. *
  18. * 2003.06.30,
  19. * Mongoose - SDL_TTF support moved to Texture class
  20. *
  21. * 2003.06.03:
  22. * Mongoose - SDL_TTF support based on Sam Lantinga's public domain
  23. * SDL_TTF demo functions and algorithms
  24. *
  25. * 2002.06.06:
  26. * Mongoose - Created
  27. =================================================================*/
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <cmath>
  32. #ifdef MEMEORY_TEST
  33. #include "memeory_test.h"
  34. #endif
  35. #ifdef USING_OPENGL
  36. #include <SDL/SDL_opengl.h>
  37. #else
  38. #error "SDLSystem requires -DUSING_OPENGL"
  39. #endif
  40. #ifdef PS2_LINUX
  41. #include "ps2.h"
  42. #endif
  43. #include "SDLSystem.h"
  44. unsigned int *gWidth = 0x0;
  45. unsigned int *gHeight = 0x0;
  46. /* 500, 50 */
  47. void glDrawGrid(float size, float step)
  48. {
  49. float x, y;
  50. // Draw grid
  51. glPushMatrix();
  52. glScalef(2.0f, 2.0f, 2.0f);
  53. glColor3f(0.4f, 0.4f, 0.6f);
  54. for (x = -size; x < size; x += step)
  55. {
  56. glBegin(GL_LINE_LOOP);
  57. for (y = -size; y < size; y += step)
  58. {
  59. glVertex3f(x + step, 0.0f, y);
  60. glVertex3f(x, 0.0f, y);
  61. glVertex3f(x, 0.0f, y + step);
  62. glVertex3f(x + step, 0.0f, y + step);
  63. }
  64. glEnd();
  65. }
  66. glPopMatrix();
  67. }
  68. void glDrawAxis(float length, float arrowLenght)
  69. {
  70. /* Draw axis list to show bone orientation */
  71. glBegin(GL_LINES);
  72. /* X axis */
  73. glColor3f(1.0f, 0.0f, 0.0f);
  74. glVertex3f(-8.0f, 0.0f, 0.0f);
  75. glVertex3f(8.0f, 0.0f, 0.0f);
  76. /* X direction */
  77. glVertex3f(8.0f, 0.0f, 0.0f);
  78. glVertex3f(7.0f, 1.0f, 0.0f);
  79. glVertex3f(8.0f, 0.0f, 0.0f);
  80. glVertex3f(7.0f, -1.0f, 0.0f);
  81. /* Y axis */
  82. glColor3f(0.0f, 1.0f, 0.0f);
  83. glVertex3f(0.0f, -8.0f, 0.0f);
  84. glVertex3f(0.0f, 8.0f, 0.0f);
  85. /* Y direction */
  86. glVertex3f(0.0f, 8.0f, 0.0f);
  87. glVertex3f(0.0f, 7.0f, 1.0f);
  88. glVertex3f(0.0f, 8.0f, 0.0f);
  89. glVertex3f(0.0f, 7.0f, -1.0f);
  90. /* Z axis */
  91. glColor3f(0.0f, 0.0f, 1.0f);
  92. glVertex3f(0.0f, 0.0f, -8.0f);
  93. glVertex3f(0.0f, 0.0f, 8.0f);
  94. /* Z direction */
  95. glVertex3f(0.0f, 0.0f, 8.0f);
  96. glVertex3f(0.0f, 1.0f, 7.0f);
  97. glVertex3f(0.0f, 0.0f, 8.0f);
  98. glVertex3f(0.0f, -1.0f, 7.0f);
  99. glEnd();
  100. }
  101. ////////////////////////////////////////////////////////////
  102. // Constructors
  103. ////////////////////////////////////////////////////////////
  104. SDLSystem::SDLSystem() : System()
  105. {
  106. mWindow = 0x0;
  107. gWidth = &m_width;
  108. gHeight = &m_height;
  109. mFirstMouseEvent = false;
  110. mFullscreen = false;
  111. }
  112. SDLSystem::~SDLSystem()
  113. {
  114. }
  115. ////////////////////////////////////////////////////////////
  116. // Public Accessors
  117. ////////////////////////////////////////////////////////////
  118. unsigned int SDLSystem::getTicks()
  119. {
  120. return SDL_GetTicks();
  121. }
  122. ////////////////////////////////////////////////////////////
  123. // Public Mutators
  124. ////////////////////////////////////////////////////////////
  125. #ifdef FIXME
  126. void SDLSystem::bindKeyCommand(const char *cmd, int key, int event)
  127. {
  128. if (key > 255)
  129. {
  130. printf("Currently key event mapping only handles ASCII characters\n");
  131. return;
  132. }
  133. printf("Bound command '%s' -> event %i (0x%x key)\n", cmd, event, key);
  134. keyEvents[key] = event;
  135. }
  136. #endif
  137. void SDLSystem::glPrintf2d(float x, float y, char *string)
  138. {
  139. #ifdef HAVE_SDL_TTF
  140. # ifdef FIXME
  141. // FIXME: Filler
  142. glBindTexture(GL_TEXTURE_2D, texture);
  143. glBegin(GL_TRIANGLE_STRIP);
  144. glTexCoord2f(texMinX, texMinY); glVertex2i(x, y );
  145. glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y );
  146. glTexCoord2f(texMinX, texMaxY); glVertex2i(x, y+h);
  147. glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
  148. glEnd();
  149. # endif
  150. #endif
  151. }
  152. void SDLSystem::glPrintf3d(float x, float y, float z, char *string)
  153. {
  154. #ifdef HAVE_SDL_TTF_FIXME
  155. // FIXME: Filler
  156. // FIXME: Billboarding here requires a yaw jackass =)
  157. glBindTexture(GL_TEXTURE_2D, texture);
  158. glBegin(GL_TRIANGLE_STRIP);
  159. glTexCoord2f(texMinX, texMinY); glVertex2i(x, y );
  160. glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y );
  161. glTexCoord2f(texMinX, texMaxY); glVertex2i(x, y+h);
  162. glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
  163. glEnd();
  164. #endif
  165. }
  166. void SDLSystem::setGrabMouse(bool on)
  167. {
  168. SDL_WM_GrabInput(on ? SDL_GRAB_ON : SDL_GRAB_OFF);
  169. }
  170. void SDLSystem::initVideo(unsigned int width, unsigned int height,
  171. bool fullscreen)
  172. {
  173. int flags; //, x, y;
  174. // Create GL context
  175. SDL_Init(SDL_INIT_VIDEO);
  176. printf("Created OpenGL Context\n");
  177. atexit(SDL_Quit);
  178. m_width = width;
  179. m_height = height;
  180. #ifndef __APPLE__
  181. if (!m_driver || !m_driver[0] || SDL_GL_LoadLibrary(m_driver) < 0)
  182. {
  183. SDL_ClearError();
  184. // Fallback 1
  185. if (SDL_GL_LoadLibrary("libGL.so") < 0)
  186. {
  187. SDL_ClearError();
  188. // Fallback 2
  189. if (SDL_GL_LoadLibrary("libGL.so.1") < 0)
  190. {
  191. fprintf(stderr, "initVideo> SDL_GL_LoadLibrary failed!\n");
  192. fprintf(stderr, "initVideo> Error is [%s].\n", SDL_GetError());
  193. shutdown(1);
  194. }
  195. }
  196. }
  197. #endif
  198. flags = 0;
  199. flags |= SDL_OPENGL;
  200. mFullscreen = fullscreen;
  201. if (mFullscreen)
  202. {
  203. flags |= SDL_FULLSCREEN;
  204. }
  205. SDL_ShowCursor(SDL_DISABLE);
  206. setGrabMouse(true); // Always grab mouse!
  207. SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
  208. SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
  209. SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
  210. SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
  211. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  212. mWindow = SDL_SetVideoMode(width, height, 16, flags);
  213. SDL_WM_SetCaption(VERSION, VERSION);
  214. //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
  215. SDL_EnableKeyRepeat(100, SDL_DEFAULT_REPEAT_INTERVAL);
  216. #ifdef UNICODE_SUPPORT
  217. //@JML get Unicode value of key for international keyboard
  218. SDL_EnableUNICODE(1);
  219. #endif
  220. // Start game renderer
  221. initGL();
  222. // Resize context
  223. resizeGL(width, height);
  224. }
  225. void SDLSystem::resize(unsigned int width, unsigned int height)
  226. {
  227. int flags;
  228. GLfloat aspect;
  229. m_width = width;
  230. m_height = height;
  231. aspect = (GLfloat)width/(GLfloat)height;
  232. glViewport(0, 0, width, height);
  233. glMatrixMode(GL_PROJECTION);
  234. glLoadIdentity();
  235. // gluPerspective is deprecated!
  236. // gluPerspective(m_fovY, aspect, m_clipNear, m_clipFar);
  237. // fix: http://stackoverflow.com/a/2417756
  238. GLfloat fH = tan(float(m_fovY / 360.0f * 3.14159f) ) * m_clipNear;
  239. GLfloat fW = fH * aspect;
  240. glFrustum(-fW, fW, -fH, fH, m_clipNear, m_clipFar);
  241. glMatrixMode(GL_MODELVIEW);
  242. glLoadIdentity();
  243. // Resize window
  244. flags = SDL_OPENGL;
  245. if (mFullscreen)
  246. flags |= SDL_FULLSCREEN;
  247. mWindow = SDL_SetVideoMode(width, height, 16, flags);
  248. // Resize context
  249. resizeGL(width, height);
  250. }
  251. void SDLSystem::runGame()
  252. {
  253. SDL_Event event;
  254. unsigned int mkeys, mod, key;
  255. int btn;
  256. bool specialKey;
  257. for (;;)
  258. {
  259. // Pause for 10-20 ms
  260. SDL_Delay(10);
  261. while (SDL_PollEvent(&event))
  262. {
  263. switch (event.type)
  264. {
  265. case SDL_QUIT:
  266. shutdown(0);
  267. break;
  268. case SDL_MOUSEMOTION:
  269. // Wrap motion
  270. if (!mFirstMouseEvent) {
  271. mFirstMouseEvent = true;
  272. } else {
  273. handleMouseMotionEvent(event.motion.xrel/2, event.motion.yrel/2);
  274. }
  275. break;
  276. case SDL_MOUSEBUTTONDOWN:
  277. case SDL_MOUSEBUTTONUP:
  278. //handleMouseEvent(event.button.button, event.button.state,
  279. // event.button.x, event.button.y);
  280. switch (event.button.button)
  281. {
  282. case SDL_BUTTON_LEFT:
  283. btn = SYS_MOUSE_LEFT;
  284. break;
  285. case SDL_BUTTON_RIGHT:
  286. btn = SYS_MOUSE_RIGHT;
  287. break;
  288. case SDL_BUTTON_MIDDLE:
  289. btn = SYS_MOUSE_MIDDLE;
  290. break;
  291. }
  292. if (event.button.state == SDL_PRESSED)
  293. {
  294. handleKeyPressEvent(btn, 0); // FIXME: mod not used
  295. }
  296. else
  297. {
  298. handleKeyReleaseEvent(btn, 0); // FIXME: mod not used
  299. }
  300. break;
  301. case SDL_KEYUP:
  302. case SDL_KEYDOWN:
  303. //SDL_GetMouseState(&x, &y); // Get cursor pos
  304. mkeys = (unsigned int)SDL_GetModState();
  305. mod = 0;
  306. if (mkeys & KMOD_LSHIFT)
  307. mod |= SYS_MOD_KEY_LSHIFT;
  308. if (mkeys & KMOD_RSHIFT)
  309. mod |= SYS_MOD_KEY_RSHIFT;
  310. if (mkeys & KMOD_LCTRL)
  311. mod |= SYS_MOD_KEY_LCTRL;
  312. if (mkeys & KMOD_RCTRL)
  313. mod |= SYS_MOD_KEY_RCTRL;
  314. if (mkeys & KMOD_LALT)
  315. mod |= SYS_MOD_KEY_LALT;
  316. if (mkeys & KMOD_RALT)
  317. mod |= SYS_MOD_KEY_RALT;
  318. if (mkeys & KMOD_LMETA)
  319. mod |= SYS_MOD_KEY_LMETA;
  320. if (mkeys & KMOD_RMETA)
  321. mod |= SYS_MOD_KEY_RMETA;
  322. key = event.key.keysym.sym;
  323. specialKey = false;
  324. switch (key)
  325. {
  326. case SDLK_F1:
  327. key = SYS_KEY_F1;
  328. specialKey = true;
  329. break;
  330. case SDLK_F2:
  331. key = SYS_KEY_F2;
  332. specialKey = true;
  333. break;
  334. case SDLK_F3:
  335. key = SYS_KEY_F3;
  336. specialKey = true;
  337. break;
  338. case SDLK_F4:
  339. key = SYS_KEY_F4;
  340. specialKey = true;
  341. break;
  342. case SDLK_F5:
  343. key = SYS_KEY_F5;
  344. specialKey = true;
  345. break;
  346. case SDLK_F6:
  347. key = SYS_KEY_F6;
  348. specialKey = true;
  349. break;
  350. case SDLK_F7:
  351. key = SYS_KEY_F7;
  352. specialKey = true;
  353. break;
  354. case SDLK_F8:
  355. key = SYS_KEY_F8;
  356. specialKey = true;
  357. break;
  358. case SDLK_F9:
  359. key = SYS_KEY_F9;
  360. specialKey = true;
  361. break;
  362. case SDLK_F10:
  363. key = SYS_KEY_F10;
  364. specialKey = true;
  365. break;
  366. case SDLK_F11:
  367. key = SYS_KEY_F11;
  368. specialKey = true;
  369. break;
  370. case SDLK_F12:
  371. key = SYS_KEY_F12;
  372. specialKey = true;
  373. break;
  374. case SDLK_UP:
  375. key = SYS_KEY_UP;
  376. specialKey = true;
  377. break;
  378. case SDLK_DOWN:
  379. key = SYS_KEY_DOWN;
  380. specialKey = true;
  381. break;
  382. case SDLK_RIGHT:
  383. key = SYS_KEY_RIGHT;
  384. specialKey = true;
  385. break;
  386. case SDLK_LEFT:
  387. key = SYS_KEY_LEFT;
  388. specialKey = true;
  389. break;
  390. case SDLK_PAGEDOWN:
  391. key = SYS_KEY_PAGEDOWN;
  392. specialKey = true;
  393. break;
  394. case SDLK_PAGEUP:
  395. key = SYS_KEY_PAGEUP;
  396. specialKey = true;
  397. break;
  398. }
  399. #ifdef __APPLE__
  400. // Handle CMD+Q to quit in all circumstances
  401. if (key == 'q') {
  402. if (mod & SYS_MOD_KEY_LMETA) {
  403. shutdown(0);
  404. }
  405. }
  406. #endif
  407. #ifdef UNICODE_SUPPORT
  408. // JML: if a std key was pressed get it ascii code
  409. if (!specialKey && key != 0)
  410. {
  411. if ((event.key.keysym.unicode & 0xFF80) == 0)
  412. {
  413. key= (unsigned int)(event.key.keysym.unicode & 0x7F);
  414. }
  415. else
  416. {
  417. key = 0;
  418. }
  419. }
  420. #else
  421. // FIXME: Avoid passing modifers as a key, since the
  422. // consoles using this expect text characters, add unicode
  423. // support later when they're able to handle it
  424. if (key > 255 && key < 1000)
  425. {
  426. key = 0;
  427. }
  428. #endif
  429. if (key == mConsoleKey)
  430. {
  431. if (event.type == SDL_KEYDOWN)
  432. {
  433. mConsoleMode = !mConsoleMode;
  434. // Tmp hack
  435. handleConsoleKeyPressEvent(mConsoleKey, 0);
  436. }
  437. }
  438. else if (mConsoleMode) // Console keying ( text input )
  439. {
  440. switch (event.type)
  441. {
  442. case SDL_KEYDOWN:
  443. handleConsoleKeyPressEvent(key, mod);
  444. break;
  445. default:
  446. ;
  447. }
  448. }
  449. else if (mKeyEvents[key] != 0)// Bound key
  450. {
  451. //if (key < 255 && mKeyEvents[key] != 0)
  452. key = mKeyEvents[key];
  453. switch (event.type)
  454. {
  455. case SDL_KEYDOWN:
  456. handleBoundKeyPressEvent(key);
  457. break;
  458. default:
  459. handleBoundKeyReleaseEvent(key);
  460. }
  461. }
  462. else // 'Classic' key event handlers
  463. {
  464. switch (event.type)
  465. {
  466. case SDL_KEYDOWN:
  467. handleKeyPressEvent(key, mod);
  468. break;
  469. default:
  470. handleKeyReleaseEvent(key, mod);
  471. }
  472. }
  473. break;
  474. case SDL_VIDEORESIZE:
  475. resizeGL(event.resize.w, event.resize.h);
  476. gameFrame();
  477. break;
  478. }
  479. }
  480. // Game frame
  481. gameFrame();
  482. }
  483. }
  484. void SDLSystem::shutdown(int i)
  485. {
  486. //SDL_QuitSubSystem(SDL_OPENGL);
  487. //SDL_Quit(); // Moved to atexit() call
  488. //#ifdef DEBUG_MEMEORY
  489. //printf("[Mongoose MEMEORY_DEBUG]\nUnfreed memory table:\n");
  490. //dump_memory_report();
  491. //#endif
  492. exit(0);
  493. }
  494. void SDLSystem::toggleFullscreen()
  495. {
  496. if (mWindow)
  497. {
  498. mFullscreen = !mFullscreen;
  499. SDL_ShowCursor(SDL_DISABLE);
  500. // SDL_WM_ToggleFullScreen does not work on all platforms
  501. // eg. Mac OS X
  502. // SDL_WM_ToggleFullScreen(mWindow);
  503. // I added a mFullscreen flag to this class. Then I modified it's
  504. // resize() method to use the SDL_FULLSCREEN flag in the
  505. // SetVideoMode() call based on the mFullscreen flag.
  506. // Then, I modified this method to find out an available
  507. // resolution for the fullscreen mode.
  508. // Now you can see something when switching to Fullscreen,
  509. // but it's full of graphical glitches...? I don't know...
  510. // -- xythobuz 2013-12-31
  511. int width, height;
  512. if (mFullscreen) {
  513. m_old_width = m_width;
  514. m_old_height = m_height;
  515. SDL_Rect **dimensions = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
  516. if (dimensions == NULL) {
  517. printf("Can't enter fullscreen!\n");
  518. mFullscreen = !mFullscreen;
  519. }
  520. if (dimensions != (SDL_Rect **)-1) {
  521. //! \fixme Don't just use first available resolution...
  522. width = dimensions[0]->w;
  523. height = dimensions[0]->h;
  524. } else {
  525. // No restrictions, use current resolution
  526. width = m_width;
  527. height = m_height;
  528. }
  529. }
  530. if (!mFullscreen) {
  531. width = m_old_width;
  532. height = m_old_height;
  533. }
  534. resize(width, height);
  535. }
  536. }
  537. void SDLSystem::swapBuffersGL()
  538. {
  539. SDL_GL_SwapBuffers();
  540. }