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

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