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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*!
  2. * \file src/SDLSystem.cpp
  3. * \brief SDL System interface implementation
  4. *
  5. * \author Mongoose
  6. */
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <cmath>
  11. #include "SDL_opengl.h"
  12. #include "utils/math.h"
  13. #include "SDLSystem.h"
  14. unsigned int *gWidth = 0x0;
  15. unsigned int *gHeight = 0x0;
  16. SDLSystem::SDLSystem() : System() {
  17. mWindow = 0x0;
  18. gWidth = &m_width;
  19. gHeight = &m_height;
  20. mFullscreen = false;
  21. }
  22. SDLSystem::~SDLSystem() {
  23. }
  24. unsigned int SDLSystem::getTicks() {
  25. return SDL_GetTicks();
  26. }
  27. #ifdef FIXME
  28. void SDLSystem::bindKeyCommand(const char *cmd, int key, int event) {
  29. if (key > 255) {
  30. printf("Currently key event mapping only handles ASCII characters\n");
  31. return;
  32. }
  33. printf("Bound command '%s' -> event %i (0x%x key)\n", cmd, event, key);
  34. keyEvents[key] = event;
  35. }
  36. #endif
  37. void SDLSystem::setGrabMouse(bool on) {
  38. SDL_SetRelativeMouseMode(on ? SDL_TRUE : SDL_FALSE);
  39. }
  40. void SDLSystem::initVideo(unsigned int width, unsigned int height, bool fullscreen) {
  41. int flags = 0; //, x, y;
  42. // Create GL context
  43. SDL_Init(SDL_INIT_VIDEO);
  44. printf("Created OpenGL Context\n");
  45. atexit(SDL_Quit);
  46. m_width = width;
  47. m_height = height;
  48. #ifndef __APPLE__
  49. if (!m_driver || !m_driver[0] || SDL_GL_LoadLibrary(m_driver) < 0) {
  50. SDL_ClearError();
  51. // Fallback 1
  52. if (SDL_GL_LoadLibrary("libGL.so") < 0) {
  53. SDL_ClearError();
  54. // Fallback 2
  55. if (SDL_GL_LoadLibrary("libGL.so.1") < 0) {
  56. fprintf(stderr, "initVideo> SDL_GL_LoadLibrary failed!\n");
  57. fprintf(stderr, "initVideo> Error is [%s].\n", SDL_GetError());
  58. shutdown(1);
  59. }
  60. }
  61. }
  62. #endif
  63. flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
  64. mFullscreen = fullscreen;
  65. if (mFullscreen)
  66. flags |= SDL_WINDOW_FULLSCREEN;
  67. setGrabMouse(true); // Always grab mouse!
  68. SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
  69. SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
  70. SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
  71. SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
  72. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  73. mWindow = SDL_CreateWindow(VERSION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
  74. width, height, flags);
  75. mGLContext = SDL_GL_CreateContext(mWindow);
  76. // Start game renderer
  77. initGL();
  78. // Resize context
  79. resizeGL(width, height);
  80. }
  81. void SDLSystem::resize(unsigned int width, unsigned int height) {
  82. m_width = width;
  83. m_height = height;
  84. glViewport(0, 0, width, height);
  85. /* All this is already done in System::resizeGL() !?
  86. GLfloat aspect = (GLfloat)width/(GLfloat)height;
  87. glMatrixMode(GL_PROJECTION);
  88. glLoadIdentity();
  89. // gluPerspective is deprecated!
  90. // gluPerspective(m_fovY, aspect, m_clipNear, m_clipFar);
  91. // fix: http://stackoverflow.com/a/2417756
  92. GLfloat fH = tanf(m_fovY * HEL_PI / 360.0f) * m_clipNear;
  93. GLfloat fW = fH * aspect;
  94. glFrustum(-fW, fW, -fH, fH, m_clipNear, m_clipFar);
  95. glMatrixMode(GL_MODELVIEW);
  96. glLoadIdentity();
  97. */
  98. // Resize context
  99. resizeGL(width, height);
  100. }
  101. void SDLSystem::runGame() {
  102. SDL_Event event;
  103. unsigned int mkeys, mod, key;
  104. int btn = 0;
  105. bool specialKey;
  106. for (;;) {
  107. // Pause for 10-20 ms
  108. SDL_Delay(10);
  109. while (SDL_PollEvent(&event)) {
  110. switch (event.type) {
  111. case SDL_QUIT:
  112. shutdown(0);
  113. break;
  114. case SDL_MOUSEMOTION:
  115. // Wrap motion
  116. handleMouseMotionEvent(event.motion.xrel / 2, event.motion.yrel / 2);
  117. break;
  118. case SDL_MOUSEBUTTONDOWN:
  119. case SDL_MOUSEBUTTONUP:
  120. //handleMouseEvent(event.button.button, event.button.state,
  121. // event.button.x, event.button.y);
  122. switch (event.button.button) {
  123. case SDL_BUTTON_LEFT:
  124. btn = SYS_MOUSE_LEFT;
  125. break;
  126. case SDL_BUTTON_RIGHT:
  127. btn = SYS_MOUSE_RIGHT;
  128. break;
  129. case SDL_BUTTON_MIDDLE:
  130. btn = SYS_MOUSE_MIDDLE;
  131. break;
  132. }
  133. if (event.button.state == SDL_PRESSED) {
  134. handleKeyPressEvent(btn, 0); //! \fixme mod not used
  135. } else {
  136. handleKeyReleaseEvent(btn, 0); //! \fixme mod not used
  137. }
  138. break;
  139. case SDL_KEYUP:
  140. case SDL_KEYDOWN:
  141. //SDL_GetMouseState(&x, &y); // Get cursor pos
  142. mkeys = (unsigned int)SDL_GetModState();
  143. mod = 0;
  144. if (mkeys & KMOD_LSHIFT)
  145. mod |= SYS_MOD_KEY_LSHIFT;
  146. if (mkeys & KMOD_RSHIFT)
  147. mod |= SYS_MOD_KEY_RSHIFT;
  148. if (mkeys & KMOD_LCTRL)
  149. mod |= SYS_MOD_KEY_LCTRL;
  150. if (mkeys & KMOD_RCTRL)
  151. mod |= SYS_MOD_KEY_RCTRL;
  152. if (mkeys & KMOD_LALT)
  153. mod |= SYS_MOD_KEY_LALT;
  154. if (mkeys & KMOD_RALT)
  155. mod |= SYS_MOD_KEY_RALT;
  156. if (mkeys & KMOD_LGUI)
  157. mod |= SYS_MOD_KEY_LMETA;
  158. if (mkeys & KMOD_RGUI)
  159. mod |= SYS_MOD_KEY_RMETA;
  160. key = event.key.keysym.sym;
  161. specialKey = false;
  162. switch (key) {
  163. case SDLK_F1:
  164. key = SYS_KEY_F1;
  165. specialKey = true;
  166. break;
  167. case SDLK_F2:
  168. key = SYS_KEY_F2;
  169. specialKey = true;
  170. break;
  171. case SDLK_F3:
  172. key = SYS_KEY_F3;
  173. specialKey = true;
  174. break;
  175. case SDLK_F4:
  176. key = SYS_KEY_F4;
  177. specialKey = true;
  178. break;
  179. case SDLK_F5:
  180. key = SYS_KEY_F5;
  181. specialKey = true;
  182. break;
  183. case SDLK_F6:
  184. key = SYS_KEY_F6;
  185. specialKey = true;
  186. break;
  187. case SDLK_F7:
  188. key = SYS_KEY_F7;
  189. specialKey = true;
  190. break;
  191. case SDLK_F8:
  192. key = SYS_KEY_F8;
  193. specialKey = true;
  194. break;
  195. case SDLK_F9:
  196. key = SYS_KEY_F9;
  197. specialKey = true;
  198. break;
  199. case SDLK_F10:
  200. key = SYS_KEY_F10;
  201. specialKey = true;
  202. break;
  203. case SDLK_F11:
  204. key = SYS_KEY_F11;
  205. specialKey = true;
  206. break;
  207. case SDLK_F12:
  208. key = SYS_KEY_F12;
  209. specialKey = true;
  210. break;
  211. case SDLK_UP:
  212. key = SYS_KEY_UP;
  213. specialKey = true;
  214. break;
  215. case SDLK_DOWN:
  216. key = SYS_KEY_DOWN;
  217. specialKey = true;
  218. break;
  219. case SDLK_RIGHT:
  220. key = SYS_KEY_RIGHT;
  221. specialKey = true;
  222. break;
  223. case SDLK_LEFT:
  224. key = SYS_KEY_LEFT;
  225. specialKey = true;
  226. break;
  227. case SDLK_PAGEDOWN:
  228. key = SYS_KEY_PAGEDOWN;
  229. specialKey = true;
  230. break;
  231. case SDLK_PAGEUP:
  232. key = SYS_KEY_PAGEUP;
  233. specialKey = true;
  234. break;
  235. }
  236. #ifdef __APPLE__
  237. // Handle CMD+Q to quit in all circumstances
  238. if (key == 'q') {
  239. if (mod & SYS_MOD_KEY_LMETA) {
  240. shutdown(0);
  241. }
  242. }
  243. #endif
  244. /*! \fixme Avoid passing modifers as a key, since the
  245. * consoles using this expect text characters, add unicode
  246. * support later when they're able to handle it
  247. */
  248. if (key > 255 && key < 1000) {
  249. key = 0;
  250. }
  251. if (key == mConsoleKey) {
  252. if (event.type == SDL_KEYDOWN) {
  253. mConsoleMode = !mConsoleMode;
  254. // Tmp hack
  255. handleConsoleKeyPressEvent(mConsoleKey, 0);
  256. }
  257. } else if (mConsoleMode) { // Console keying (text input)
  258. switch (event.type) {
  259. case SDL_KEYDOWN:
  260. handleConsoleKeyPressEvent(key, mod);
  261. break;
  262. default:
  263. ;
  264. }
  265. } else if (mKeyEvents[key] != 0) { // Bound key
  266. //if (key < 255 && mKeyEvents[key] != 0)
  267. key = mKeyEvents[key];
  268. switch (event.type) {
  269. case SDL_KEYDOWN:
  270. handleBoundKeyPressEvent(key);
  271. break;
  272. default:
  273. handleBoundKeyReleaseEvent(key);
  274. }
  275. } else { // 'Classic' key event handlers
  276. switch (event.type) {
  277. case SDL_KEYDOWN:
  278. handleKeyPressEvent(key, mod);
  279. break;
  280. default:
  281. handleKeyReleaseEvent(key, mod);
  282. }
  283. }
  284. break;
  285. case SDL_WINDOWEVENT:
  286. switch(event.window.event) {
  287. case SDL_WINDOWEVENT_RESIZED:
  288. resizeGL(event.window.data1, event.window.data2);
  289. break;
  290. }
  291. break;
  292. }
  293. }
  294. // Game frame
  295. gameFrame();
  296. }
  297. }
  298. void SDLSystem::shutdown(int i) {
  299. //SDL_QuitSubSystem(SDL_OPENGL);
  300. //SDL_Quit(); // Moved to atexit() call
  301. exit(i);
  302. }
  303. void SDLSystem::toggleFullscreen() {
  304. if (mWindow) {
  305. mFullscreen = !mFullscreen;
  306. if (mFullscreen)
  307. SDL_SetWindowFullscreen(mWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);
  308. else
  309. SDL_SetWindowFullscreen(mWindow, 0);
  310. }
  311. }
  312. void SDLSystem::swapBuffersGL() {
  313. SDL_GL_SwapWindow(mWindow);
  314. }