123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607 |
- /*!
- * \file src/system/WindowSDL.cpp
- * \brief SDL2 Windowing Implementation
- *
- * \author xythobuz
- */
-
- #include <sstream>
-
- #include "SDL_revision.h"
-
- #include "global.h"
- #include "Log.h"
- #include "RunTime.h"
- #include "UI.h"
- #include "system/Window.h"
- #include "system/WindowSDL.h"
-
- #define SUBSYSTEMS_USED (SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER)
-
- glm::i32vec2 WindowSDL::size(DEFAULT_WIDTH, DEFAULT_HEIGHT);
- bool WindowSDL::fullscreen = false;
- bool WindowSDL::mousegrab = false;
- bool WindowSDL::textinput = false;
- SDL_Window* WindowSDL::window = nullptr;
- SDL_GLContext WindowSDL::context = nullptr;
- SDL_GameController* WindowSDL::controller = nullptr;
-
- int WindowSDL::initialize() {
- if (SDL_Init(SUBSYSTEMS_USED) != 0) {
- Log::get(LOG_ERROR) << "SDL_Init Error: " << SDL_GetError() << Log::endl;
- return -1;
- }
-
- int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
- if (fullscreen)
- flags |= SDL_WINDOW_FULLSCREEN;
-
- if ((SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8) != 0)
- || (SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8) != 0)
- || (SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8) != 0)
- || (SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8) != 0)
- || (SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24) != 0)
- || (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) != 0)
- || (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) != 0)
- //|| (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2) != 0)
- || (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4) != 0)
- || (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) != 0)
- || (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3) != 0)
- || (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE))) {
- Log::get(LOG_ERROR) << "SDL_GL_SetAttribute Error: " << SDL_GetError() << Log::endl;
- return -2;
- }
-
- window = SDL_CreateWindow(VERSION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
- size.x, size.y, flags);
- if (!window) {
- Log::get(LOG_ERROR) << "SDL_CreateWindow Error: " << SDL_GetError() << Log::endl;
- return -3;
- }
-
- int w = size.x, h = size.y;
- SDL_GetWindowSize(window, &w, &h);
- size.x = w;
- size.y = h;
-
- context = SDL_GL_CreateContext(window);
- if (!context) {
- Log::get(LOG_ERROR) << "SDL_GL_CreateContext Error: " << SDL_GetError() << Log::endl;
- return -4;
- }
-
- setMousegrab(mousegrab);
- setTextInput(textinput);
-
- if (SDL_NumJoysticks() == 0) {
- Log::get(LOG_INFO) << "No Joystick found!" << Log::endl;
- return 0;
- }
-
- SDL_GameControllerAddMapping("341a0000000000000208000000000000,"
- "USB GAMEPAD 8116,"
- "a:b0,x:b2,start:b7,back:b6,leftstick:b8,rightstick:b9,"
- "leftshoulder:b4,rightshoulder:b5,"
- "dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,"
- "leftx:a0,lefty:a1,rightx:a3,righty:a2,"
- "lefttrigger:,b:b1,y:b3,lefttrigger:a4,righttrigger:a4");
-
- SDL_GameControllerAddMapping("10080000000000000100000000000000,"
- "Twin USB Joystick,"
- "a:b4,b:b2,y:b0,x:b6,start:b18,back:b16,leftstick:b20,"
- "rightstick:b22,leftshoulder:b12,rightshoulder:b14,dpup:h0.1,"
- "dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a2,rightx:a6,"
- "righty:a4,lefttrigger:b8,righttrigger:b10");
-
- for (int i = 0; i < SDL_NumJoysticks(); i++) {
- if (SDL_IsGameController(i)) {
- controller = SDL_GameControllerOpen(i);
- if (controller) {
- Log::get(LOG_INFO) << "Using controller \"" << SDL_GameControllerName(controller)
- << "\"..." << Log::endl;
- break;
- } else {
- Log::get(LOG_WARNING) << "Couldn't open controller \"" << SDL_GameControllerNameForIndex(i)
- << "\"!" << Log::endl;
- }
- } else {
- Log::get(LOG_WARNING) << "Joystick \"" << SDL_JoystickNameForIndex(i)
- << "\" is no compatible controller!" << Log::endl;
- }
- }
-
- return 0;
- }
-
- void WindowSDL::eventHandling() {
- SDL_Event event;
- KeyboardButton button;
-
- while (SDL_PollEvent(&event)) {
- switch (event.type) {
- case SDL_CONTROLLERAXISMOTION:
- button = unknownKey;
- if (event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX)
- button = leftXAxis;
- else if (event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY)
- button = leftYAxis;
- else if (event.caxis.axis == SDL_CONTROLLER_AXIS_RIGHTX)
- button = rightXAxis;
- else if (event.caxis.axis == SDL_CONTROLLER_AXIS_RIGHTY)
- button = rightYAxis;
- else if (event.caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)
- button = leftTrigger;
- else if (event.caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
- button = rightTrigger;
- if (button != unknownKey)
- UI::handleControllerAxis(event.caxis.value / 32768.0f, button);
- break;
-
- case SDL_CONTROLLERBUTTONDOWN:
- case SDL_CONTROLLERBUTTONUP:
- button = unknownKey;
- if (event.cbutton.button == SDL_CONTROLLER_BUTTON_A)
- button = aButton;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_B)
- button = bButton;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_X)
- button = xButton;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_Y)
- button = yButton;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK)
- button = backButton;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_GUIDE)
- button = guideButton;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_START)
- button = startButton;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_LEFTSTICK)
- button = leftStick;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_RIGHTSTICK)
- button = rightStick;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_LEFTSHOULDER)
- button = leftShoulder;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)
- button = rightShoulder;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_UP)
- button = padUp;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_DOWN)
- button = padDown;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_LEFT)
- button = padLeft;
- else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_DPAD_RIGHT)
- button = padRight;
- if (button != unknownKey)
- UI::handleControllerButton(button, (event.type == SDL_CONTROLLERBUTTONUP));
- break;
-
- case SDL_MOUSEMOTION:
- UI::handleMouseMotion(event.motion.xrel, event.motion.yrel, event.motion.x, event.motion.y);
- break;
-
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- button = unknownKey;
- if (event.button.button == SDL_BUTTON_LEFT)
- button = leftmouseKey;
- else if (event.button.button == SDL_BUTTON_RIGHT)
- button = rightmouseKey;
- else if (event.button.button == SDL_BUTTON_MIDDLE)
- button = middlemouseKey;
- else if (event.button.button == SDL_BUTTON_X1)
- button = fourthmouseKey;
- else if (event.button.button == SDL_BUTTON_X2)
- button = fifthmouseKey;
- if (button != unknownKey)
- UI::handleMouseClick(event.button.x, event.button.y, button,
- (event.type == SDL_MOUSEBUTTONUP));
- break;
-
- case SDL_MOUSEWHEEL:
- if ((event.wheel.x != 0) || (event.wheel.y != 0))
- UI::handleMouseScroll(event.wheel.x, event.wheel.y);
- break;
-
- case SDL_TEXTINPUT:
- case SDL_TEXTEDITING:
- UI::handleText(event.text.text, (event.type == SDL_TEXTEDITING));
- break;
-
- case SDL_KEYDOWN:
- case SDL_KEYUP:
- KeyboardButton key;
- switch (event.key.keysym.sym) {
- case SDLK_0:
- key = zeroKey;
- break;
- case SDLK_1:
- key = oneKey;
- break;
- case SDLK_2:
- key = twoKey;
- break;
- case SDLK_3:
- key = threeKey;
- break;
- case SDLK_4:
- key = fourKey;
- break;
- case SDLK_5:
- key = fiveKey;
- break;
- case SDLK_6:
- key = sixKey;
- break;
- case SDLK_7:
- key = sevenKey;
- break;
- case SDLK_8:
- key = eightKey;
- break;
- case SDLK_9:
- key = nineKey;
- break;
- case SDLK_a:
- key = aKey;
- break;
- case SDLK_b:
- key = bKey;
- break;
- case SDLK_c:
- key = cKey;
- break;
- case SDLK_d:
- key = dKey;
- break;
- case SDLK_e:
- key = eKey;
- break;
- case SDLK_f:
- key = fKey;
- break;
- case SDLK_g:
- key = gKey;
- break;
- case SDLK_h:
- key = hKey;
- break;
- case SDLK_i:
- key = iKey;
- break;
- case SDLK_j:
- key = jKey;
- break;
- case SDLK_k:
- key = kKey;
- break;
- case SDLK_l:
- key = lKey;
- break;
- case SDLK_m:
- key = mKey;
- break;
- case SDLK_n:
- key = nKey;
- break;
- case SDLK_o:
- key = oKey;
- break;
- case SDLK_p:
- key = pKey;
- break;
- case SDLK_q:
- key = qKey;
- break;
- case SDLK_r:
- key = rKey;
- break;
- case SDLK_s:
- key = sKey;
- break;
- case SDLK_t:
- key = tKey;
- break;
- case SDLK_u:
- key = uKey;
- break;
- case SDLK_v:
- key = vKey;
- break;
- case SDLK_w:
- key = wKey;
- break;
- case SDLK_x:
- key = xKey;
- break;
- case SDLK_y:
- key = yKey;
- break;
- case SDLK_z:
- key = zKey;
- break;
- case SDLK_QUOTE:
- key = quoteKey;
- break;
- case SDLK_BACKSLASH:
- key = backslashKey;
- break;
- case SDLK_BACKSPACE:
- key = backspaceKey;
- break;
- case SDLK_CAPSLOCK:
- key = capslockKey;
- break;
- case SDLK_COMMA:
- key = commaKey;
- break;
- case SDLK_DELETE:
- key = delKey;
- break;
- case SDLK_UP:
- key = upKey;
- break;
- case SDLK_DOWN:
- key = downKey;
- break;
- case SDLK_LEFT:
- key = leftKey;
- break;
- case SDLK_RIGHT:
- key = rightKey;
- break;
- case SDLK_END:
- key = endKey;
- break;
- case SDLK_EQUALS:
- key = equalsKey;
- break;
- case SDLK_ESCAPE:
- key = escapeKey;
- break;
- case SDLK_F1:
- key = f1Key;
- break;
- case SDLK_F2:
- key = f2Key;
- break;
- case SDLK_F3:
- key = f3Key;
- break;
- case SDLK_F4:
- key = f4Key;
- break;
- case SDLK_F5:
- key = f5Key;
- break;
- case SDLK_F6:
- key = f6Key;
- break;
- case SDLK_F7:
- key = f7Key;
- break;
- case SDLK_F8:
- key = f8Key;
- break;
- case SDLK_F9:
- key = f9Key;
- break;
- case SDLK_F10:
- key = f10Key;
- break;
- case SDLK_F11:
- key = f11Key;
- break;
- case SDLK_F12:
- key = f12Key;
- break;
- case SDLK_BACKQUOTE:
- key = backquoteKey;
- break;
- case SDLK_HOME:
- key = homeKey;
- break;
- case SDLK_INSERT:
- key = insertKey;
- break;
- case SDLK_LALT:
- key = leftaltKey;
- break;
- case SDLK_LCTRL:
- key = leftctrlKey;
- break;
- case SDLK_LEFTBRACKET:
- key = leftbracketKey;
- break;
- case SDLK_LGUI:
- key = leftguiKey;
- break;
- case SDLK_LSHIFT:
- key = leftshiftKey;
- break;
- case SDLK_MINUS:
- key = minusKey;
- break;
- case SDLK_NUMLOCKCLEAR:
- key = numlockKey;
- break;
- case SDLK_PAGEDOWN:
- key = pagedownKey;
- break;
- case SDLK_PAGEUP:
- key = pageupKey;
- break;
- case SDLK_PAUSE:
- key = pauseKey;
- break;
- case SDLK_PERIOD:
- key = dotKey;
- break;
- case SDLK_RALT:
- key = rightaltKey;
- break;
- case SDLK_RCTRL:
- key = rightctrlKey;
- break;
- case SDLK_RETURN:
- case SDLK_RETURN2:
- key = enterKey;
- break;
- case SDLK_RGUI:
- key = rightguiKey;
- break;
- case SDLK_RIGHTBRACKET:
- key = rightbracketKey;
- break;
- case SDLK_RSHIFT:
- key = rightshiftKey;
- break;
- case SDLK_SCROLLLOCK:
- key = scrolllockKey;
- break;
- case SDLK_SEMICOLON:
- key = semicolonKey;
- break;
- case SDLK_SLASH:
- key = slashKey;
- break;
- case SDLK_SPACE:
- key = spaceKey;
- break;
- case SDLK_TAB:
- key = tabKey;
- break;
- default:
- key = unknownKey;
- break;
-
- }
- UI::handleKeyboard(key, (event.type == SDL_KEYDOWN));
- break;
-
- case SDL_WINDOWEVENT:
- if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
- size = glm::i32vec2(event.window.data1, event.window.data2);
- Window::setSize(size);
- }
- break;
-
- case SDL_QUIT:
- RunTime::setRunning(false);
- break;
- }
- }
-
- UI::eventsFinished();
- }
-
- void WindowSDL::swapBuffers() {
- SDL_GL_SwapWindow(window);
- }
-
- void WindowSDL::shutdown() {
- if (context) {
- SDL_GL_DeleteContext(context);
- context = nullptr;
- }
-
- if (controller) {
- SDL_GameControllerClose(controller);
- controller = nullptr;
- }
-
- if (window) {
- SDL_DestroyWindow(window);
- SDL_QuitSubSystem(SUBSYSTEMS_USED);
- SDL_Quit();
- window = nullptr;
- }
- }
-
- void WindowSDL::setSize(glm::i32vec2 s) {
- orAssert((s.x > 0) && (s.y > 0));
- if (window) {
- if ((s.x != size.x) || (s.y != size.y)) {
- SDL_SetWindowSize(window, s.x, s.y);
- }
- }
- size = s;
- }
-
- void WindowSDL::setFullscreen(bool f) {
- fullscreen = f;
- if (window) {
- if (fullscreen) {
- SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
- } else {
- SDL_SetWindowFullscreen(window, 0);
- }
- }
- }
-
- void WindowSDL::setMousegrab(bool g) {
- mousegrab = g;
- if (window) {
- if (mousegrab) {
- SDL_SetRelativeMouseMode(SDL_TRUE);
- } else {
- SDL_SetRelativeMouseMode(SDL_FALSE);
- SDL_ShowCursor(1);
- }
- }
- }
-
- void WindowSDL::setTextInput(bool t) {
- textinput = t;
- if (textinput)
- SDL_StartTextInput();
- else
- SDL_StopTextInput();
- }
-
- void WindowSDL::setClipboard(const char* s) {
- if (window) {
- if (SDL_SetClipboardText(s) < 0) {
- Log::get(LOG_ERROR) << "SDL_SetClipboardText Error: " << SDL_GetError() << Log::endl;
- }
- }
- }
-
- const char* WindowSDL::getClipboard() {
- if (window) {
- //! \fixme Should be freed with SDL_free(). But how, where, when?
- const char* ret = SDL_GetClipboardText();
- if (ret == nullptr) {
- Log::get(LOG_ERROR) << "SDL_GetClipboardText Error: " << SDL_GetError() << Log::endl;
- }
- return ret;
- }
-
- return nullptr;
- }
-
- void WindowSDL::inputPositionCallback(int x, int y) {
- SDL_Rect rect;
- rect.x = x;
- rect.y = y;
- rect.w = 50;
- rect.h = 25;
- SDL_SetTextInputRect(&rect);
- }
-
- std::string WindowSDL::getVersion(bool linked) {
- SDL_version vers;
-
- if (linked) {
- SDL_GetVersion(&vers);
- } else {
- SDL_VERSION(&vers);
- }
-
- std::ostringstream str;
- str << "SDL2 v" << int(vers.major) << "." << int(vers.minor) << "." << int(vers.patch);
- if (linked) {
- return str.str() + " (" + SDL_GetRevision() + ")";
- } else {
- return str.str() + " (" + SDL_REVISION + ")";
- }
- }
|