OpenRaider  0.1.4-dev
Open Source Tomb Raider Game Engine implementation
WindowSDL.cpp
Go to the documentation of this file.
1 
8 #include "global.h"
9 #include "Log.h"
10 #include "RunTime.h"
11 #include "UI.h"
12 #include "system/Window.h"
13 #include "system/WindowSDL.h"
14 
15 #define SUBSYSTEMS_USED (SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER)
16 
17 glm::i32vec2 WindowSDL::size(DEFAULT_WIDTH, DEFAULT_HEIGHT);
18 bool WindowSDL::fullscreen = false;
19 bool WindowSDL::mousegrab = false;
20 bool WindowSDL::textinput = false;
21 SDL_Window* WindowSDL::window = nullptr;
22 SDL_GLContext WindowSDL::context = nullptr;
23 SDL_GameController* WindowSDL::controller = nullptr;
24 
26  if (SDL_Init(SUBSYSTEMS_USED) != 0) {
27  Log::get(LOG_ERROR) << "SDL_Init Error: " << SDL_GetError() << Log::endl;
28  return -1;
29  }
30 
31  int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
32  if (fullscreen)
33  flags |= SDL_WINDOW_FULLSCREEN;
34 
35  if ((SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8) != 0)
36  || (SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8) != 0)
37  || (SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8) != 0)
38  || (SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8) != 0)
39  || (SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24) != 0)
40  || (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) != 0)
41  || (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) != 0)
42  //|| (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2) != 0)
43  || (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4) != 0)
44  || (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) != 0)
45  || (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3) != 0)
46  || (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE))) {
47  Log::get(LOG_ERROR) << "SDL_GL_SetAttribute Error: " << SDL_GetError() << Log::endl;
48  return -2;
49  }
50 
51  window = SDL_CreateWindow(VERSION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
52  size.x, size.y, flags);
53  if (!window) {
54  Log::get(LOG_ERROR) << "SDL_CreateWindow Error: " << SDL_GetError() << Log::endl;
55  return -3;
56  }
57 
58  int w = size.x, h = size.y;
59  SDL_GetWindowSize(window, &w, &h);
60  size.x = w;
61  size.y = h;
62 
63  context = SDL_GL_CreateContext(window);
64  if (!context) {
65  Log::get(LOG_ERROR) << "SDL_GL_CreateContext Error: " << SDL_GetError() << Log::endl;
66  return -4;
67  }
68 
71 
72  if (SDL_NumJoysticks() == 0) {
73  Log::get(LOG_INFO) << "No Joystick found!" << Log::endl;
74  return 0;
75  }
76 
77  SDL_GameControllerAddMapping("341a0000000000000208000000000000,"
78  "USB GAMEPAD 8116,"
79  "a:b0,x:b2,start:b7,back:b6,leftstick:b8,rightstick:b9,"
80  "leftshoulder:b4,rightshoulder:b5,"
81  "dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,"
82  "leftx:a0,lefty:a1,rightx:a3,righty:a2,"
83  "lefttrigger:,b:b1,y:b3,lefttrigger:a4,righttrigger:a4");
84 
85  SDL_GameControllerAddMapping("10080000000000000100000000000000,"
86  "Twin USB Joystick,"
87  "a:b4,b:b2,y:b0,x:b6,start:b18,back:b16,leftstick:b20,"
88  "rightstick:b22,leftshoulder:b12,rightshoulder:b14,dpup:h0.1,"
89  "dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a2,rightx:a6,"
90  "righty:a4,lefttrigger:b8,righttrigger:b10");
91 
92  for (int i = 0; i < SDL_NumJoysticks(); i++) {
93  if (SDL_IsGameController(i)) {
94  controller = SDL_GameControllerOpen(i);
95  if (controller) {
96  Log::get(LOG_INFO) << "Using controller \"" << SDL_GameControllerName(controller)
97  << "\"..." << Log::endl;
98  break;
99  } else {
100  Log::get(LOG_WARNING) << "Couldn't open controller \"" << SDL_GameControllerNameForIndex(i)
101  << "\"!" << Log::endl;
102  }
103  } else {
104  Log::get(LOG_WARNING) << "Joystick \"" << SDL_JoystickNameForIndex(i)
105  << "\" is no compatible controller!" << Log::endl;
106  }
107  }
108 
109  return 0;
110 }
111 
113  SDL_Event event;
114  KeyboardButton button;
115 
116  while (SDL_PollEvent(&event)) {
117  switch (event.type) {
118  case SDL_CONTROLLERAXISMOTION:
119  button = unknownKey;
120  if (event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX)
121  button = leftXAxis;
122  else if (event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY)
123  button = leftYAxis;
124  else if (event.caxis.axis == SDL_CONTROLLER_AXIS_RIGHTX)
125  button = rightXAxis;
126  else if (event.caxis.axis == SDL_CONTROLLER_AXIS_RIGHTY)
127  button = rightYAxis;
128  else if (event.caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)
129  button = leftTrigger;
130  else if (event.caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
131  button = rightTrigger;
132  if (button != unknownKey)
133  UI::handleControllerAxis(event.caxis.value / 32768.0f, button);
134  break;
135 
136  case SDL_CONTROLLERBUTTONDOWN:
137  case SDL_CONTROLLERBUTTONUP:
138  button = unknownKey;
139  if (event.cbutton.button == SDL_CONTROLLER_BUTTON_A)
140  button = aButton;
141  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_B)
142  button = bButton;
143  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_X)
144  button = xButton;
145  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_Y)
146  button = yButton;
147  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK)
148  button = backButton;
149  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_GUIDE)
150  button = guideButton;
151  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_START)
152  button = startButton;
153  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_LEFTSTICK)
154  button = leftStick;
155  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_RIGHTSTICK)
156  button = rightStick;
157  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER)
158  button = leftShoulder;
159  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)
160  button = rightShoulder;
161  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
162  button = padUp;
163  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
164  button = padDown;
165  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT)
166  button = padLeft;
167  else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT)
168  button = padRight;
169  if (button != unknownKey)
170  UI::handleControllerButton(button, (event.type == SDL_CONTROLLERBUTTONUP));
171  break;
172 
173  case SDL_MOUSEMOTION:
174  UI::handleMouseMotion(event.motion.xrel, event.motion.yrel, event.motion.x, event.motion.y);
175  break;
176 
177  case SDL_MOUSEBUTTONDOWN:
178  case SDL_MOUSEBUTTONUP:
179  button = unknownKey;
180  if (event.button.button == SDL_BUTTON_LEFT)
181  button = leftmouseKey;
182  else if (event.button.button == SDL_BUTTON_RIGHT)
183  button = rightmouseKey;
184  else if (event.button.button == SDL_BUTTON_MIDDLE)
185  button = middlemouseKey;
186  else if (event.button.button == SDL_BUTTON_X1)
187  button = fourthmouseKey;
188  else if (event.button.button == SDL_BUTTON_X2)
189  button = fifthmouseKey;
190  if (button != unknownKey)
191  UI::handleMouseClick(event.button.x, event.button.y, button,
192  (event.type == SDL_MOUSEBUTTONUP));
193  break;
194 
195  case SDL_MOUSEWHEEL:
196  if ((event.wheel.x != 0) || (event.wheel.y != 0))
197  UI::handleMouseScroll(event.wheel.x, event.wheel.y);
198  break;
199 
200  case SDL_TEXTINPUT:
201  case SDL_TEXTEDITING:
202  if (event.text.text != nullptr)
203  UI::handleText(event.text.text, (event.type == SDL_TEXTEDITING));
204  break;
205 
206  case SDL_KEYDOWN:
207  case SDL_KEYUP:
208  KeyboardButton key;
209  switch (event.key.keysym.sym) {
210  case SDLK_0:
211  key = zeroKey;
212  break;
213  case SDLK_1:
214  key = oneKey;
215  break;
216  case SDLK_2:
217  key = twoKey;
218  break;
219  case SDLK_3:
220  key = threeKey;
221  break;
222  case SDLK_4:
223  key = fourKey;
224  break;
225  case SDLK_5:
226  key = fiveKey;
227  break;
228  case SDLK_6:
229  key = sixKey;
230  break;
231  case SDLK_7:
232  key = sevenKey;
233  break;
234  case SDLK_8:
235  key = eightKey;
236  break;
237  case SDLK_9:
238  key = nineKey;
239  break;
240  case SDLK_a:
241  key = aKey;
242  break;
243  case SDLK_b:
244  key = bKey;
245  break;
246  case SDLK_c:
247  key = cKey;
248  break;
249  case SDLK_d:
250  key = dKey;
251  break;
252  case SDLK_e:
253  key = eKey;
254  break;
255  case SDLK_f:
256  key = fKey;
257  break;
258  case SDLK_g:
259  key = gKey;
260  break;
261  case SDLK_h:
262  key = hKey;
263  break;
264  case SDLK_i:
265  key = iKey;
266  break;
267  case SDLK_j:
268  key = jKey;
269  break;
270  case SDLK_k:
271  key = kKey;
272  break;
273  case SDLK_l:
274  key = lKey;
275  break;
276  case SDLK_m:
277  key = mKey;
278  break;
279  case SDLK_n:
280  key = nKey;
281  break;
282  case SDLK_o:
283  key = oKey;
284  break;
285  case SDLK_p:
286  key = pKey;
287  break;
288  case SDLK_q:
289  key = qKey;
290  break;
291  case SDLK_r:
292  key = rKey;
293  break;
294  case SDLK_s:
295  key = sKey;
296  break;
297  case SDLK_t:
298  key = tKey;
299  break;
300  case SDLK_u:
301  key = uKey;
302  break;
303  case SDLK_v:
304  key = vKey;
305  break;
306  case SDLK_w:
307  key = wKey;
308  break;
309  case SDLK_x:
310  key = xKey;
311  break;
312  case SDLK_y:
313  key = yKey;
314  break;
315  case SDLK_z:
316  key = zKey;
317  break;
318  case SDLK_QUOTE:
319  key = quoteKey;
320  break;
321  case SDLK_BACKSLASH:
322  key = backslashKey;
323  break;
324  case SDLK_BACKSPACE:
325  key = backspaceKey;
326  break;
327  case SDLK_CAPSLOCK:
328  key = capslockKey;
329  break;
330  case SDLK_COMMA:
331  key = commaKey;
332  break;
333  case SDLK_DELETE:
334  key = delKey;
335  break;
336  case SDLK_UP:
337  key = upKey;
338  break;
339  case SDLK_DOWN:
340  key = downKey;
341  break;
342  case SDLK_LEFT:
343  key = leftKey;
344  break;
345  case SDLK_RIGHT:
346  key = rightKey;
347  break;
348  case SDLK_END:
349  key = endKey;
350  break;
351  case SDLK_EQUALS:
352  key = equalsKey;
353  break;
354  case SDLK_ESCAPE:
355  key = escapeKey;
356  break;
357  case SDLK_F1:
358  key = f1Key;
359  break;
360  case SDLK_F2:
361  key = f2Key;
362  break;
363  case SDLK_F3:
364  key = f3Key;
365  break;
366  case SDLK_F4:
367  key = f4Key;
368  break;
369  case SDLK_F5:
370  key = f5Key;
371  break;
372  case SDLK_F6:
373  key = f6Key;
374  break;
375  case SDLK_F7:
376  key = f7Key;
377  break;
378  case SDLK_F8:
379  key = f8Key;
380  break;
381  case SDLK_F9:
382  key = f9Key;
383  break;
384  case SDLK_F10:
385  key = f10Key;
386  break;
387  case SDLK_F11:
388  key = f11Key;
389  break;
390  case SDLK_F12:
391  key = f12Key;
392  break;
393  case SDLK_BACKQUOTE:
394  key = backquoteKey;
395  break;
396  case SDLK_HOME:
397  key = homeKey;
398  break;
399  case SDLK_INSERT:
400  key = insertKey;
401  break;
402  case SDLK_LALT:
403  key = leftaltKey;
404  break;
405  case SDLK_LCTRL:
406  key = leftctrlKey;
407  break;
408  case SDLK_LEFTBRACKET:
409  key = leftbracketKey;
410  break;
411  case SDLK_LGUI:
412  key = leftguiKey;
413  break;
414  case SDLK_LSHIFT:
415  key = leftshiftKey;
416  break;
417  case SDLK_MINUS:
418  key = minusKey;
419  break;
420  case SDLK_NUMLOCKCLEAR:
421  key = numlockKey;
422  break;
423  case SDLK_PAGEDOWN:
424  key = pagedownKey;
425  break;
426  case SDLK_PAGEUP:
427  key = pageupKey;
428  break;
429  case SDLK_PAUSE:
430  key = pauseKey;
431  break;
432  case SDLK_PERIOD:
433  key = dotKey;
434  break;
435  case SDLK_RALT:
436  key = rightaltKey;
437  break;
438  case SDLK_RCTRL:
439  key = rightctrlKey;
440  break;
441  case SDLK_RETURN:
442  case SDLK_RETURN2:
443  key = enterKey;
444  break;
445  case SDLK_RGUI:
446  key = rightguiKey;
447  break;
448  case SDLK_RIGHTBRACKET:
449  key = rightbracketKey;
450  break;
451  case SDLK_RSHIFT:
452  key = rightshiftKey;
453  break;
454  case SDLK_SCROLLLOCK:
455  key = scrolllockKey;
456  break;
457  case SDLK_SEMICOLON:
458  key = semicolonKey;
459  break;
460  case SDLK_SLASH:
461  key = slashKey;
462  break;
463  case SDLK_SPACE:
464  key = spaceKey;
465  break;
466  case SDLK_TAB:
467  key = tabKey;
468  break;
469  default:
470  key = unknownKey;
471  break;
472 
473  }
474  UI::handleKeyboard(key, (event.type == SDL_KEYDOWN));
475  break;
476 
477  case SDL_WINDOWEVENT:
478  if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
479  size = glm::i32vec2(event.window.data1, event.window.data2);
481  }
482  break;
483 
484  case SDL_QUIT:
485  RunTime::setRunning(false);
486  break;
487  }
488  }
489 
491 }
492 
494  SDL_GL_SwapWindow(window);
495 }
496 
498  if (context) {
499  SDL_GL_DeleteContext(context);
500  context = nullptr;
501  }
502 
503  if (controller) {
504  SDL_GameControllerClose(controller);
505  controller = nullptr;
506  }
507 
508  if (window) {
509  SDL_DestroyWindow(window);
510  SDL_QuitSubSystem(SUBSYSTEMS_USED);
511  SDL_Quit();
512  window = nullptr;
513  }
514 }
515 
516 void WindowSDL::setSize(glm::i32vec2 s) {
517  assert((s.x > 0) && (s.y > 0));
518  if (window) {
519  if ((s.x != size.x) || (s.y != size.y)) {
520  SDL_SetWindowSize(window, s.x, s.y);
521  }
522  }
523  size = s;
524 }
525 
527  fullscreen = f;
528  if (window) {
529  if (fullscreen) {
530  SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
531  } else {
532  SDL_SetWindowFullscreen(window, 0);
533  }
534  }
535 }
536 
538  mousegrab = g;
539  if (window) {
540  if (mousegrab) {
541  SDL_SetRelativeMouseMode(SDL_TRUE);
542  } else {
543  SDL_SetRelativeMouseMode(SDL_FALSE);
544  SDL_ShowCursor(1);
545  }
546  }
547 }
548 
550  textinput = t;
551  if (textinput)
552  SDL_StartTextInput();
553  else
554  SDL_StopTextInput();
555 }
556 
557 void WindowSDL::setClipboard(const char* s) {
558  if (window) {
559  if (SDL_SetClipboardText(s) < 0) {
560  Log::get(LOG_ERROR) << "SDL_SetClipboardText Error: " << SDL_GetError() << Log::endl;
561  }
562  }
563 }
564 
565 const char* WindowSDL::getClipboard() {
566  if (window) {
568  const char* ret = SDL_GetClipboardText();
569  if (ret == nullptr) {
570  Log::get(LOG_ERROR) << "SDL_GetClipboardText Error: " << SDL_GetError() << Log::endl;
571  }
572  return ret;
573  }
574 
575  return nullptr;
576 }
577 
579  SDL_Rect rect;
580  rect.x = x;
581  rect.y = y;
582  rect.w = 50;
583  rect.h = 25;
584  SDL_SetTextInputRect(&rect);
585 }
586 
Definition: global.h:48
#define LOG_WARNING
Definition: Log.h:20
static void handleMouseScroll(int xrel, int yrel)
Definition: UI.cpp:403
Definition: global.h:61
Definition: global.h:48
Definition: global.h:61
Definition: global.h:44
SDL2 Windowing Implementation.
Definition: global.h:63
Definition: global.h:43
static int initialize()
Definition: WindowSDL.cpp:25
Definition: global.h:49
static void handleControllerAxis(float value, KeyboardButton axis)
Definition: UI.cpp:410
Definition: global.h:40
static SDL_Window * window
Definition: WindowSDL.h:44
Definition: global.h:61
static void swapBuffers()
Definition: WindowSDL.cpp:493
static void setMousegrab(bool g)
Definition: WindowSDL.cpp:537
static void handleControllerButton(KeyboardButton button, bool released)
Definition: UI.cpp:414
Definition: global.h:41
Definition: global.h:36
Definition: global.h:49
Definition: global.h:40
KeyboardButton
Definition: global.h:34
Definition: global.h:45
Definition: global.h:36
static void setClipboard(const char *s)
Definition: WindowSDL.cpp:557
static void setTextInput(bool t)
Definition: WindowSDL.cpp:549
static SDL_GameController * controller
Definition: WindowSDL.h:46
Definition: global.h:36
Included everywhere.
static void inputPositionCallback(int x, int y)
Definition: WindowSDL.cpp:578
Definition: global.h:47
static LogLevel & get(int level)
Definition: Log.cpp:14
static bool fullscreen
Definition: WindowSDL.h:41
Definition: global.h:37
Definition: global.h:42
Definition: global.h:43
Definition: global.h:45
static void handleMouseMotion(int xrel, int yrel, int xabs, int yabs)
Definition: UI.cpp:396
Definition: global.h:44
Global Logging Utility.
Definition: global.h:49
Definition: global.h:45
Definition: global.h:39
static bool mousegrab
Definition: WindowSDL.h:42
static void setFullscreen(bool f)
Definition: WindowSDL.cpp:526
Windowing Interface.
#define assert(x)
Definition: global.h:124
Definition: global.h:37
static void handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released)
Definition: UI.cpp:378
static glm::i32vec2 size
Definition: WindowSDL.h:40
Definition: global.h:45
static void setRunning(bool run)
Definition: RunTime.h:36
Definition: global.h:63
#define LOG_INFO
Definition: Log.h:21
static void shutdown()
Definition: WindowSDL.cpp:497
Definition: global.h:43
Definition: global.h:39
Definition: global.h:47
Definition: global.h:49
Definition: global.h:48
Definition: global.h:42
Definition: global.h:50
Definition: global.h:42
Definition: global.h:52
static const char endl
Definition: Log.h:35
Runtime Configuration Storage.
Definition: global.h:41
#define LOG_ERROR
Definition: Log.h:19
#define SUBSYSTEMS_USED
Definition: WindowSDL.cpp:15
Definition: global.h:49
static void handleKeyboard(KeyboardButton key, bool pressed)
Definition: UI.cpp:355
static bool textinput
Definition: WindowSDL.h:43
Definition: global.h:48
Definition: global.h:42
UI/Event Manager.
Definition: global.h:48
static SDL_GLContext context
Definition: WindowSDL.h:45
Definition: global.h:48
Definition: global.h:41
Definition: global.h:61
Definition: global.h:54
Definition: global.h:47
Definition: global.h:39
Definition: global.h:49
Definition: global.h:49
Definition: global.h:47
Definition: global.h:40
Definition: global.h:63
Definition: global.h:38
Definition: global.h:43
static void eventsFinished()
Definition: UI.cpp:147
static void handleText(char *text, bool notFinished)
Definition: UI.cpp:367
static void setSize(glm::i32vec2 s)
Definition: WindowSDL.cpp:516
static void setSize(glm::i32vec2 s)
Definition: Window.cpp:59
Definition: global.h:40
static void eventHandling()
Definition: WindowSDL.cpp:112
Definition: global.h:44
Definition: global.h:44
static const char * getClipboard()
Definition: WindowSDL.cpp:565
Definition: global.h:41