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 12KB

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