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

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