diff --git a/Aquaria/DSQ.cpp b/Aquaria/DSQ.cpp index 5c3bea5..27a621a 100644 --- a/Aquaria/DSQ.cpp +++ b/Aquaria/DSQ.cpp @@ -888,7 +888,19 @@ void DSQ::setVersionLabelText() #ifdef BBGE_BUILD_SDL static bool sdlVideoModeOK(const int w, const int h, const int bpp) { +#ifdef BBGE_BUILD_SDL2 + SDL_DisplayMode mode; + const int modecount = SDL_GetNumDisplayModes(0); + for (int i = 0; i < modecount; i++) { + SDL_GetDisplayMode(0, i, &mode); + if (!mode.w || !mode.h || (w >= mode.w && h >= mode.h)) { + return true; + } + } + return false; +#else return SDL_VideoModeOK(w, h, bpp, SDL_OPENGL | SDL_FULLSCREEN); +#endif } #endif diff --git a/Aquaria/Network.cpp b/Aquaria/Network.cpp index e1358f5..64acdc9 100644 --- a/Aquaria/Network.cpp +++ b/Aquaria/Network.cpp @@ -157,7 +157,13 @@ static void init() userAgent = os.str(); if(!worker) + { +#ifdef BBGE_BUILD_SDL2 + worker = SDL_CreateThread(_NetworkWorkerThread, "network", NULL); +#else worker = SDL_CreateThread(_NetworkWorkerThread, NULL); +#endif + } } void shutdown() diff --git a/BBGE/BBGECompileConfig.h b/BBGE/BBGECompileConfig.h index 125b5bf..ba8f915 100644 --- a/BBGE/BBGECompileConfig.h +++ b/BBGE/BBGECompileConfig.h @@ -11,6 +11,7 @@ #define BBGE_BUILD_FMOD_OPENAL_BRIDGE 1 #define BBGE_BUILD_ACHIEVEMENTS_INTERNAL 1 #define BBGE_BUILD_VFS 1 +#define BBGE_BUILD_SDL2 1 #endif diff --git a/BBGE/Core.cpp b/BBGE/Core.cpp index 45e14f0..5593056 100644 --- a/BBGE/Core.cpp +++ b/BBGE/Core.cpp @@ -46,7 +46,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef BBGE_BUILD_SDL #include "SDL_syswm.h" + #ifdef BBGE_BUILD_SDL2 + static SDL_Window *gScreen=0; + static SDL_GLContext gGLctx=0; + #else static SDL_Surface *gScreen=0; + #endif + bool ignoreNextMouse=false; Vector unchange; #endif @@ -68,13 +74,13 @@ void Core::initIcon() SDL_SysWMinfo wminfo; SDL_VERSION(&wminfo.version) - if (SDL_GetWMInfo(&wminfo) != 1) + if (SDL_GetWindowWMInfo(gScreen, &wminfo) != 1) { //errorLog("wrong SDL version"); // error: wrong SDL version } - HWND hwnd = wminfo.window; + HWND hwnd = wminfo.info.win.window; ::SetClassLong(hwnd, GCL_HICON, (LONG) icon_windows); #endif @@ -205,8 +211,10 @@ void Core::updateCursorFromJoystick(float dt, int spd) void Core::setWindowCaption(const std::string &caption, const std::string &icon) { #ifdef BBGE_BUILD_SDL +#ifndef BBGE_BUILD_SDL2 SDL_WM_SetCaption(caption.c_str(), icon.c_str()); #endif +#endif } RenderObjectLayer *Core::getRenderObjectLayer(int i) @@ -1220,7 +1228,11 @@ void Core::setInputGrab(bool on) if (isWindowFocus()) { #ifdef BBGE_BUILD_SDL + #ifdef BBGE_BUILD_SDL2 + SDL_SetWindowGrab(gScreen, on ? SDL_TRUE : SDL_FALSE); + #else SDL_WM_GrabInput(on?SDL_GRAB_ON:SDL_GRAB_OFF); + #endif #endif } } @@ -1258,9 +1270,11 @@ void Core::init() exit(0); #endif #ifdef BBGE_BUILD_SDL +#ifndef BBGE_BUILD_SDL2 // Disable relative mouse motion at the edges of the screen, which breaks // mouse control for absolute input devices like Wacom tablets and touchscreens. SDL_putenv((char *) "SDL_MOUSE_RELATIVE=0"); +#endif if((SDL_Init(0))==-1) { @@ -1536,7 +1550,11 @@ bool Core::initJoystickLibrary(int numSticks) { //joystickEnabled = false; #ifdef BBGE_BUILD_SDL +#ifdef BBGE_BUILD_SDL2 + SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER); +#else SDL_InitSubSystem(SDL_INIT_JOYSTICK); +#endif #endif if (numSticks > 0) @@ -1821,7 +1839,10 @@ void Core::setSDLGLAttributes() debugLog(os.str()); #ifdef BBGE_BUILD_SDL +#ifndef BBGE_BUILD_SDL2 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, _vsync); +#endif + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); #endif } @@ -1897,11 +1918,15 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync //setenv("SDL_VIDEO_CENTERED", "1", 1); //SDL_putenv("SDL_VIDEO_WINDOW_POS=400,300"); +#ifndef BBGE_BUILD_SDL2 +#if !defined(BBGE_BUILD_MACOSX) // have to cast away constness, since SDL_putenv() might be #defined to // putenv(), which takes a (char *), and freaks out newer GCC releases // when you try to pass a (const!) string literal here... --ryan. SDL_putenv((char *) "SDL_VIDEO_CENTERED=1"); - SDL_putenv((char *) "LIBGL_DEBUG=verbose"); // temp, to track errors on linux with nouveau drivers. +#endif +#endif + //SDL_putenv((char *) "LIBGL_DEBUG=verbose"); // temp, to track errors on linux with nouveau drivers. if (recreate) { @@ -1929,6 +1954,30 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync //if (!didOnce) { +#ifdef BBGE_BUILD_SDL2 + Uint32 flags = 0; + flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; + if (fullscreen) + flags |= SDL_WINDOW_FULLSCREEN; + gScreen = SDL_CreateWindow(appName.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, flags); + if (gScreen == NULL) + { + std::ostringstream os; + os << "Couldn't set resolution [" << width << "x" << height << "]\n" << SDL_GetError(); + errorLog(os.str()); + SDL_Quit(); + exit(0); + } + gGLctx = SDL_GL_CreateContext(gScreen); + if (gGLctx == NULL) + { + std::ostringstream os; + os << "Couldn't create OpenGL context!\n" << SDL_GetError(); + errorLog(os.str()); + SDL_Quit(); + exit(0); + } +#else Uint32 flags = 0; flags = SDL_OPENGL; if (fullscreen) @@ -1942,6 +1991,7 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync SDL_Quit(); exit_error(os.str()); } +#endif #if BBGE_BUILD_OPENGL_DYNAMIC if (!lookup_all_glsyms()) @@ -1956,9 +2006,21 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync setWindowCaption(appName, appName); +#ifdef BBGE_BUILD_SDL2 + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapWindow(gScreen); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapWindow(gScreen); + if ((_vsync != 1) || (SDL_GL_SetSwapInterval(-1) == -1)) + SDL_GL_SetSwapInterval(_vsync); + const char *name = SDL_GetCurrentVideoDriver(); + SDL_SetWindowGrab(gScreen, SDL_TRUE); +#else SDL_WM_GrabInput(grabInputOnReentry==0 ? SDL_GRAB_OFF : SDL_GRAB_ON); char name[256]; SDL_VideoDriverName((char*)name, 256); +#endif glViewport(0, 0, width, height); glScissor(0, 0, width, height); @@ -1975,11 +2037,13 @@ bool Core::initGraphicsLibrary(int width, int height, bool fullscreen, int vsync keys[i] = 0; } +/* #ifdef BBGE_BUILD_WINDOWS SDL_SysWMinfo wmInfo; SDL_GetWMInfo(&wmInfo); hWnd = wmInfo.window; #endif +*/ #endif @@ -2045,6 +2109,23 @@ void Core::enumerateScreenModes() screenModes.clear(); #ifdef BBGE_BUILD_SDL +#ifdef BBGE_BUILD_SDL2 + SDL_DisplayMode mode; + const int modecount = SDL_GetNumDisplayModes(0); + if(modecount == 0){ + debugLog("No modes available!"); + return; + } + + for (int i = 0; i < modecount; i++) { + SDL_GetDisplayMode(0, i, &mode); + if (mode.w && mode.h && (mode.w > mode.h)) + { + screenModes.push_back(ScreenMode(i, mode.w, mode.h)); + } + } + +#else SDL_Rect **modes; int i; @@ -2072,6 +2153,7 @@ void Core::enumerateScreenModes() } } #endif +#endif } void Core::shutdownSoundLibrary() @@ -2083,8 +2165,17 @@ void Core::shutdownGraphicsLibrary(bool killVideo) #ifdef BBGE_BUILD_SDL glFinish(); if (killVideo) { + #ifdef BBGE_BUILD_SDL2 + SDL_SetWindowGrab(gScreen, SDL_FALSE); + SDL_GL_MakeCurrent(gScreen, NULL); + SDL_GL_DeleteContext(gGLctx); + SDL_DestroyWindow(gScreen); + gGLctx = 0; + SDL_QuitSubSystem(SDL_INIT_VIDEO); + #else SDL_QuitSubSystem(SDL_INIT_VIDEO); SDL_WM_GrabInput(SDL_GRAB_OFF); + #endif FrameBuffer::resetOpenGL(); @@ -2171,6 +2262,7 @@ void centerWindow(HWND hwnd) } #endif +/* void Core::adjustWindowPosition(int x, int y) { #ifdef BBGE_BUILD_WINDOWS @@ -2181,6 +2273,7 @@ void Core::adjustWindowPosition(int x, int y) ::SetWindowPos(hWnd, HWND_TOP, rcWnd.left, rcWnd.top, 0, 0, SWP_NOSIZE); #endif } +*/ bool Core::createWindow(int width, int height, int bits, bool fullscreen, std::string windowTitle) { @@ -2631,7 +2724,11 @@ void Core::setMousePosition(const Vector &p) float px = p.x + virtualOffX; float py = p.y;// + virtualOffY; + #ifdef BBGE_BUILD_SDL2 + SDL_WarpMouseInWindow(gScreen, px * (float(width)/float(virtualWidth)), py * (float(height)/float(virtualHeight))); + #else SDL_WarpMouse( px * (float(width)/float(virtualWidth)), py * (float(height)/float(virtualHeight))); + #endif /* ignoreNextMouse = true; @@ -2719,7 +2816,11 @@ float Core::stopWatch(int d) bool Core::isWindowFocus() { #ifdef BBGE_BUILD_SDL + #ifdef BBGE_BUILD_SDL2 + return ((SDL_GetWindowFlags(gScreen) & SDL_WINDOW_INPUT_FOCUS) != 0); + #else return ((SDL_GetAppState() & SDL_APPINPUTFOCUS) != 0); + #endif #endif return true; } @@ -3236,6 +3337,174 @@ bool Core::doMouseConstraint() return false; } +#if defined(BBGE_BUILD_SDL) + +#if defined(BBGE_BUILD_SDL2) +typedef std::map sdlKeyMap; +#else +typedef std::map sdlKeyMap; +#endif + +static sdlKeyMap *initSDLKeymap(void) +{ + sdlKeyMap *_retval = new sdlKeyMap; + sdlKeyMap &retval = *_retval; + + #define SETKEYMAP(gamekey,sdlkey) retval[sdlkey] = gamekey + +#ifdef BBGE_BUILD_SDL2 + SETKEYMAP(KEY_LSUPER, SDLK_LGUI); + SETKEYMAP(KEY_RSUPER, SDLK_RGUI); + SETKEYMAP(KEY_LMETA, SDLK_LGUI); + SETKEYMAP(KEY_RMETA, SDLK_RGUI); + SETKEYMAP(KEY_PRINTSCREEN, SDLK_PRINTSCREEN); + SETKEYMAP(KEY_NUMPAD1, SDLK_KP_1); + SETKEYMAP(KEY_NUMPAD2, SDLK_KP_2); + SETKEYMAP(KEY_NUMPAD3, SDLK_KP_3); + SETKEYMAP(KEY_NUMPAD4, SDLK_KP_4); + SETKEYMAP(KEY_NUMPAD5, SDLK_KP_5); + SETKEYMAP(KEY_NUMPAD6, SDLK_KP_6); + SETKEYMAP(KEY_NUMPAD7, SDLK_KP_7); + SETKEYMAP(KEY_NUMPAD8, SDLK_KP_8); + SETKEYMAP(KEY_NUMPAD9, SDLK_KP_9); + SETKEYMAP(KEY_NUMPAD0, SDLK_KP_0); +#else + SETKEYMAP(KEY_LSUPER, SDLK_LSUPER); + SETKEYMAP(KEY_RSUPER, SDLK_RSUPER); + SETKEYMAP(KEY_LMETA, SDLK_LMETA); + SETKEYMAP(KEY_RMETA, SDLK_RMETA); + SETKEYMAP(KEY_PRINTSCREEN, SDLK_PRINT); + SETKEYMAP(KEY_NUMPAD1, SDLK_KP1); + SETKEYMAP(KEY_NUMPAD2, SDLK_KP2); + SETKEYMAP(KEY_NUMPAD3, SDLK_KP3); + SETKEYMAP(KEY_NUMPAD4, SDLK_KP4); + SETKEYMAP(KEY_NUMPAD5, SDLK_KP5); + SETKEYMAP(KEY_NUMPAD6, SDLK_KP6); + SETKEYMAP(KEY_NUMPAD7, SDLK_KP7); + SETKEYMAP(KEY_NUMPAD8, SDLK_KP8); + SETKEYMAP(KEY_NUMPAD9, SDLK_KP9); + SETKEYMAP(KEY_NUMPAD0, SDLK_KP0); +#endif + + SETKEYMAP(KEY_BACKSPACE, SDLK_BACKSPACE); + + //SETKEYMAP(KEY_CAPSLOCK, DIK_CAPSLOCK); + //SETKEYMAP(KEY_CIRCUMFLEX, DIK_CIRCUMFLEX); + SETKEYMAP(KEY_LALT, SDLK_LALT); + SETKEYMAP(KEY_RALT, SDLK_RALT); + SETKEYMAP(KEY_LSHIFT, SDLK_LSHIFT); + SETKEYMAP(KEY_RSHIFT, SDLK_RSHIFT); + SETKEYMAP(KEY_LCONTROL, SDLK_LCTRL); + SETKEYMAP(KEY_RCONTROL, SDLK_RCTRL); + SETKEYMAP(KEY_NUMPADMINUS, SDLK_KP_MINUS); + SETKEYMAP(KEY_NUMPADPERIOD, SDLK_KP_PERIOD); + SETKEYMAP(KEY_NUMPADPLUS, SDLK_KP_PLUS); + SETKEYMAP(KEY_NUMPADSLASH, SDLK_KP_DIVIDE); + SETKEYMAP(KEY_NUMPADSTAR, SDLK_KP_MULTIPLY); + SETKEYMAP(KEY_PGDN, SDLK_PAGEDOWN); + SETKEYMAP(KEY_PGUP, SDLK_PAGEUP); + SETKEYMAP(KEY_APOSTROPHE, SDLK_QUOTE); + SETKEYMAP(KEY_EQUALS, SDLK_EQUALS); + SETKEYMAP(KEY_SEMICOLON, SDLK_SEMICOLON); + SETKEYMAP(KEY_LBRACKET, SDLK_LEFTBRACKET); + SETKEYMAP(KEY_RBRACKET, SDLK_RIGHTBRACKET); + //SETKEYMAP(KEY_RALT, GLFW_SETKEYMAP(KEY_RALT); + SETKEYMAP(KEY_TILDE, SDLK_BACKQUOTE); + SETKEYMAP(KEY_0, SDLK_0); + SETKEYMAP(KEY_1, SDLK_1); + SETKEYMAP(KEY_2, SDLK_2); + SETKEYMAP(KEY_3, SDLK_3); + SETKEYMAP(KEY_4, SDLK_4); + SETKEYMAP(KEY_5, SDLK_5); + SETKEYMAP(KEY_6, SDLK_6); + SETKEYMAP(KEY_7, SDLK_7); + SETKEYMAP(KEY_8, SDLK_8); + SETKEYMAP(KEY_9, SDLK_9); + SETKEYMAP(KEY_A, SDLK_a); + SETKEYMAP(KEY_B, SDLK_b); + SETKEYMAP(KEY_C, SDLK_c); + SETKEYMAP(KEY_D, SDLK_d); + SETKEYMAP(KEY_E, SDLK_e); + SETKEYMAP(KEY_F, SDLK_f); + SETKEYMAP(KEY_G, SDLK_g); + SETKEYMAP(KEY_H, SDLK_h); + SETKEYMAP(KEY_I, SDLK_i); + SETKEYMAP(KEY_J, SDLK_j); + SETKEYMAP(KEY_K, SDLK_k); + SETKEYMAP(KEY_L, SDLK_l); + SETKEYMAP(KEY_M, SDLK_m); + SETKEYMAP(KEY_N, SDLK_n); + SETKEYMAP(KEY_O, SDLK_o); + SETKEYMAP(KEY_P, SDLK_p); + SETKEYMAP(KEY_Q, SDLK_q); + SETKEYMAP(KEY_R, SDLK_r); + SETKEYMAP(KEY_S, SDLK_s); + SETKEYMAP(KEY_T, SDLK_t); + SETKEYMAP(KEY_U, SDLK_u); + SETKEYMAP(KEY_V, SDLK_v); + SETKEYMAP(KEY_W, SDLK_w); + SETKEYMAP(KEY_X, SDLK_x); + SETKEYMAP(KEY_Y, SDLK_y); + SETKEYMAP(KEY_Z, SDLK_z); + + SETKEYMAP(KEY_LEFT, SDLK_LEFT); + SETKEYMAP(KEY_RIGHT, SDLK_RIGHT); + SETKEYMAP(KEY_UP, SDLK_UP); + SETKEYMAP(KEY_DOWN, SDLK_DOWN); + + SETKEYMAP(KEY_DELETE, SDLK_DELETE); + SETKEYMAP(KEY_SPACE, SDLK_SPACE); + SETKEYMAP(KEY_RETURN, SDLK_RETURN); + SETKEYMAP(KEY_PERIOD, SDLK_PERIOD); + SETKEYMAP(KEY_MINUS, SDLK_MINUS); + SETKEYMAP(KEY_CAPSLOCK, SDLK_CAPSLOCK); + SETKEYMAP(KEY_SYSRQ, SDLK_SYSREQ); + SETKEYMAP(KEY_TAB, SDLK_TAB); + SETKEYMAP(KEY_HOME, SDLK_HOME); + SETKEYMAP(KEY_END, SDLK_END); + SETKEYMAP(KEY_COMMA, SDLK_COMMA); + SETKEYMAP(KEY_SLASH, SDLK_SLASH); + + SETKEYMAP(KEY_F1, SDLK_F1); + SETKEYMAP(KEY_F2, SDLK_F2); + SETKEYMAP(KEY_F3, SDLK_F3); + SETKEYMAP(KEY_F4, SDLK_F4); + SETKEYMAP(KEY_F5, SDLK_F5); + SETKEYMAP(KEY_F6, SDLK_F6); + SETKEYMAP(KEY_F7, SDLK_F7); + SETKEYMAP(KEY_F8, SDLK_F8); + SETKEYMAP(KEY_F9, SDLK_F9); + SETKEYMAP(KEY_F10, SDLK_F10); + SETKEYMAP(KEY_F11, SDLK_F11); + SETKEYMAP(KEY_F12, SDLK_F12); + SETKEYMAP(KEY_F13, SDLK_F13); + SETKEYMAP(KEY_F14, SDLK_F14); + SETKEYMAP(KEY_F15, SDLK_F15); + + SETKEYMAP(KEY_ESCAPE, SDLK_ESCAPE); + //SETKEYMAP(KEY_ANYKEY, 4059); + //SETKEYMAP(KEY_MAXARRAY, SDLK_LAST+1 + + #undef SETKEYMAP + + return _retval; +} + +#if defined(BBGE_BUILD_SDL2) +static int mapSDLKeyToGameKey(const SDL_Keycode val) +#else +static int mapSDLKeyToGameKey(const SDLKey val) +#endif +{ + static sdlKeyMap *keymap = NULL; + if (keymap == NULL) + keymap = initSDLKeymap(); + + return (*keymap)[val]; +} +#endif + + void Core::pollEvents() { #if defined(BBGE_BUILD_SDL) @@ -3306,8 +3575,7 @@ void Core::pollEvents() } else if (_hasFocus) { - int k = (int)event.key.keysym.sym; - keys[k] = 1; + keys[mapSDLKeyToGameKey(event.key.keysym.sym)] = 1; } } break; @@ -3316,8 +3584,7 @@ void Core::pollEvents() { if (_hasFocus) { - int k = (int)event.key.keysym.sym; - keys[k] = 0; + keys[mapSDLKeyToGameKey(event.key.keysym.sym)] = 0; } } break; @@ -3338,6 +3605,31 @@ void Core::pollEvents() } break; + #ifdef BBGE_BUILD_SDL2 + case SDL_WINDOWEVENT: + { + if (event.window.event == SDL_WINDOWEVENT_CLOSE) + { + SDL_Quit(); + _exit(0); + //loopDone = true; + //quit(); + } + } + break; + + case SDL_MOUSEWHEEL: + { + if (_hasFocus && updateMouse) + { + if (event.wheel.y > 0) + mouse.scrollWheelChange = 1; + else if (event.wheel.y < 0) + mouse.scrollWheelChange = -1; + } + } + break; + #else case SDL_MOUSEBUTTONDOWN: { if (_hasFocus && updateMouse) @@ -3371,6 +3663,7 @@ void Core::pollEvents() } } break; + #endif case SDL_QUIT: SDL_Quit(); @@ -3914,10 +4207,13 @@ void Core::render(int startLayer, int endLayer, bool useFrameBufferIfAvail) void Core::showBuffer() { BBGE_PROF(Core_showBuffer); -#ifdef BBGE_BUILD_SDL +#ifdef BBGE_BUILD_SDL2 + SDL_GL_SwapWindow(gScreen); +#elif BBGE_BUILD_SDL SDL_GL_SwapBuffers(); //glFlush(); #endif + #ifdef BBGE_BUILD_GLFW glfwSwapBuffers(); //_glfwPlatSwapBuffers(); diff --git a/BBGE/Core.h b/BBGE/Core.h index 8da8b9c..4089ce6 100644 --- a/BBGE/Core.h +++ b/BBGE/Core.h @@ -283,122 +283,115 @@ enum GameKeys KEY_LEFTARROW = GLFW_KEY_LEFT, */ + KEY_LSUPER, + KEY_RSUPER, + KEY_LMETA, + KEY_RMETA, + KEY_BACKSPACE, + KEY_PRINTSCREEN, - KEY_LSUPER = SDLK_LSUPER, - KEY_RSUPER = SDLK_RSUPER, - KEY_LMETA = SDLK_LMETA, - KEY_RMETA = SDLK_RMETA, - - KEY_BACKSPACE = SDLK_BACKSPACE, - KEY_PRINTSCREEN = SDLK_PRINT, - - //KEY_CAPSLOCK = DIK_CAPSLOCK, - //KEY_CIRCUMFLEX = DIK_CIRCUMFLEX, - KEY_LALT = SDLK_LALT, - KEY_RALT = SDLK_RALT, - KEY_LSHIFT = SDLK_LSHIFT, - KEY_RSHIFT = SDLK_RSHIFT, - KEY_LCONTROL = SDLK_LCTRL, - KEY_RCONTROL = SDLK_RCTRL, - KEY_NUMPADMINUS = SDLK_KP_MINUS, - KEY_NUMPADPERIOD = SDLK_KP_PERIOD, - KEY_NUMPADPLUS = SDLK_KP_PLUS, - KEY_NUMPADSLASH = SDLK_KP_DIVIDE, - KEY_NUMPADSTAR = SDLK_KP_MULTIPLY, - KEY_PGDN = SDLK_PAGEDOWN, - KEY_PGUP = SDLK_PAGEUP, - KEY_APOSTROPHE = SDLK_QUOTE, - KEY_EQUALS = SDLK_EQUALS, - KEY_SEMICOLON = SDLK_SEMICOLON, - KEY_LBRACKET = SDLK_LEFTBRACKET, - KEY_RBRACKET = SDLK_RIGHTBRACKET, - //KEY_RALT = GLFW_KEY_RALT, - KEY_TILDE = SDLK_BACKQUOTE, - KEY_0 = SDLK_0, - KEY_1 = SDLK_1, - KEY_2 = SDLK_2, - KEY_3 = SDLK_3, - KEY_4 = SDLK_4, - KEY_5 = SDLK_5, - KEY_6 = SDLK_6, - KEY_7 = SDLK_7, - KEY_8 = SDLK_8, - KEY_9 = SDLK_9, - KEY_A = SDLK_a, - KEY_B = SDLK_b, - KEY_C = SDLK_c, - KEY_D = SDLK_d, - KEY_E = SDLK_e, - KEY_F = SDLK_f, - KEY_G = SDLK_g, - KEY_H = SDLK_h, - KEY_I = SDLK_i, - KEY_J = SDLK_j, - KEY_K = SDLK_k, - KEY_L = SDLK_l, - KEY_M = SDLK_m, - KEY_N = SDLK_n, - KEY_O = SDLK_o, - KEY_P = SDLK_p, - KEY_Q = SDLK_q, - KEY_R = SDLK_r, - KEY_S = SDLK_s, - KEY_T = SDLK_t, - KEY_U = SDLK_u, - KEY_V = SDLK_v, - KEY_W = SDLK_w, - KEY_X = SDLK_x, - KEY_Y = SDLK_y, - KEY_Z = SDLK_z, - - KEY_LEFT = SDLK_LEFT, - KEY_RIGHT = SDLK_RIGHT, - KEY_UP = SDLK_UP, - KEY_DOWN = SDLK_DOWN, - - KEY_NUMPAD1 = SDLK_KP1, - KEY_NUMPAD2 = SDLK_KP2, - KEY_NUMPAD3 = SDLK_KP3, - KEY_NUMPAD4 = SDLK_KP4, - KEY_NUMPAD5 = SDLK_KP5, - KEY_NUMPAD6 = SDLK_KP6, - KEY_NUMPAD7 = SDLK_KP7, - KEY_NUMPAD8 = SDLK_KP8, - KEY_NUMPAD9 = SDLK_KP9, - KEY_NUMPAD0 = SDLK_KP0, - - KEY_DELETE = SDLK_DELETE, - KEY_SPACE = SDLK_SPACE, - KEY_RETURN = SDLK_RETURN, - KEY_PERIOD = SDLK_PERIOD, - KEY_MINUS = SDLK_MINUS, - KEY_CAPSLOCK = SDLK_CAPSLOCK, - KEY_SYSRQ = SDLK_SYSREQ, - KEY_TAB = SDLK_TAB, - KEY_HOME = SDLK_HOME, - KEY_END = SDLK_END, - KEY_COMMA = SDLK_COMMA, - KEY_SLASH = SDLK_SLASH, - - KEY_F1 = SDLK_F1, - KEY_F2 = SDLK_F2, - KEY_F3 = SDLK_F3, - KEY_F4 = SDLK_F4, - KEY_F5 = SDLK_F5, - KEY_F6 = SDLK_F6, - KEY_F7 = SDLK_F7, - KEY_F8 = SDLK_F8, - KEY_F9 = SDLK_F9, - KEY_F10 = SDLK_F10, - KEY_F11 = SDLK_F11, - KEY_F12 = SDLK_F12, - KEY_F13 = SDLK_F13, - KEY_F14 = SDLK_F14, - KEY_F15 = SDLK_F15, - - KEY_ESCAPE = SDLK_ESCAPE, - KEY_ANYKEY = 4059, - KEY_MAXARRAY = SDLK_LAST+1 + //KEY_CAPSLOCK, + //KEY_CIRCUMFLEX, + KEY_LALT, + KEY_RALT, + KEY_LSHIFT, + KEY_RSHIFT, + KEY_LCONTROL, + KEY_RCONTROL, + KEY_NUMPADMINUS, + KEY_NUMPADPERIOD, + KEY_NUMPADPLUS, + KEY_NUMPADSLASH, + KEY_NUMPADSTAR, + KEY_PGDN, + KEY_PGUP, + KEY_APOSTROPHE, + KEY_EQUALS, + KEY_SEMICOLON, + KEY_LBRACKET, + KEY_RBRACKET, + //KEY_RALT, + KEY_TILDE, + KEY_0, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, + KEY_7, + KEY_8, + KEY_9, + KEY_A, + KEY_B, + KEY_C, + KEY_D, + KEY_E, + KEY_F, + KEY_G, + KEY_H, + KEY_I, + KEY_J, + KEY_K, + KEY_L, + KEY_M, + KEY_N, + KEY_O, + KEY_P, + KEY_Q, + KEY_R, + KEY_S, + KEY_T, + KEY_U, + KEY_V, + KEY_W, + KEY_X, + KEY_Y, + KEY_Z, + KEY_LEFT, + KEY_RIGHT, + KEY_UP, + KEY_DOWN, + KEY_NUMPAD1, + KEY_NUMPAD2, + KEY_NUMPAD3, + KEY_NUMPAD4, + KEY_NUMPAD5, + KEY_NUMPAD6, + KEY_NUMPAD7, + KEY_NUMPAD8, + KEY_NUMPAD9, + KEY_NUMPAD0, + KEY_DELETE, + KEY_SPACE, + KEY_RETURN, + KEY_PERIOD, + KEY_MINUS, + KEY_CAPSLOCK, + KEY_SYSRQ, + KEY_TAB, + KEY_HOME, + KEY_END, + KEY_COMMA, + KEY_SLASH, + KEY_F1, + KEY_F2, + KEY_F3, + KEY_F4, + KEY_F5, + KEY_F6, + KEY_F7, + KEY_F8, + KEY_F9, + KEY_F10, + KEY_F11, + KEY_F12, + KEY_F13, + KEY_F14, + KEY_F15, + KEY_ESCAPE, + KEY_ANYKEY, + KEY_MAXARRAY }; #elif defined(BBGE_BUILD_XINPUT) enum GameKeys @@ -808,9 +801,13 @@ public: bool inited, xinited; bool anyButton(); #ifdef BBGE_BUILD_SDL +# ifdef BBGE_BUILD_SDL2 + SDL_GameController *sdl_controller; + SDL_Haptic *sdl_haptic; +# endif SDL_Joystick *sdl_joy; #endif -#ifdef __LINUX__ +#if defined(__LINUX__) && !defined(BBGE_BUILD_SDL2) int eventfd; int16_t effectid; #endif @@ -1013,7 +1010,7 @@ public: void main(float runTime = -1); // can use main - void adjustWindowPosition(int x, int y); + //void adjustWindowPosition(int x, int y); // state functions diff --git a/BBGE/FmodOpenALBridge.cpp b/BBGE/FmodOpenALBridge.cpp index 6db0855..42a67ef 100644 --- a/BBGE/FmodOpenALBridge.cpp +++ b/BBGE/FmodOpenALBridge.cpp @@ -177,7 +177,11 @@ void OggDecoder::startDecoderThread() { #ifdef BBGE_BUILD_SDL stop_thread = false; +#ifdef BBGE_BUILD_SDL2 + decoderThread = SDL_CreateThread((int (*)(void *))decode_loop, "OggDecoder", NULL); +#else decoderThread = SDL_CreateThread((int (*)(void *))decode_loop, NULL); +#endif if (!decoderThread) { debugLog("Failed to create Ogg Vorbis decode thread: " diff --git a/BBGE/Joystick.cpp b/BBGE/Joystick.cpp index f4e6e01..ee1655c 100644 --- a/BBGE/Joystick.cpp +++ b/BBGE/Joystick.cpp @@ -90,9 +90,13 @@ Joystick::Joystick() xinited = false; stickIndex = -1; #ifdef BBGE_BUILD_SDL - sdl_joy = 0; +# ifdef BBGE_BUILD_SDL2 + sdl_controller = NULL; + sdl_haptic = NULL; +# endif + sdl_joy = NULL; #endif -#ifdef __LINUX__ +#if defined(__LINUX__) && !defined(BBGE_BUILD_SDL2) eventfd = -1; effectid = -1; #endif @@ -126,16 +130,48 @@ void Joystick::init(int stick) #ifdef BBGE_BUILD_SDL stickIndex = stick; - int numJoy = SDL_NumJoysticks(); + const int numJoy = SDL_NumJoysticks(); os << "Found [" << numJoy << "] joysticks"; debugLog(os.str()); + if (numJoy > stick) { - sdl_joy = SDL_JoystickOpen(stick); + #ifdef BBGE_BUILD_SDL2 + if (SDL_IsGameController(stick)) + { + sdl_controller = SDL_GameControllerOpen(stick); + if (sdl_controller) + sdl_joy = SDL_GameControllerGetJoystick(sdl_controller); + } + if (!sdl_joy) + sdl_joy = SDL_JoystickOpen(stick); + if (sdl_joy && SDL_JoystickIsHaptic(sdl_joy)) + { + sdl_haptic = SDL_HapticOpenFromJoystick(sdl_joy); + bool rumbleok = false; + if (sdl_haptic && SDL_HapticRumbleSupported(sdl_haptic)) + rumbleok = (SDL_HapticRumbleInit(sdl_haptic) == 0); + if (!rumbleok) + { + SDL_HapticClose(sdl_haptic); + sdl_haptic = NULL; + } + } + #endif + + if (!sdl_joy) + sdl_joy = SDL_JoystickOpen(stick); + if (sdl_joy) { inited = true; + #ifdef BBGE_BUILD_SDL2 + debugLog(std::string("Initialized Joystick [") + std::string(SDL_JoystickName(sdl_joy)) + std::string("]")); + if (sdl_controller) debugLog(std::string("Joystick is a Game Controller")); + if (sdl_haptic) debugLog(std::string("Joystick has force feedback support")); + #else debugLog(std::string("Initialized Joystick [") + std::string(SDL_JoystickName(stick)) + std::string("]")); + #endif } else { @@ -150,7 +186,7 @@ void Joystick::init(int stick) } #endif -#ifdef __LINUX__ +#if defined(__LINUX__) && !defined(BBGE_BUILD_SDL2) os.seekp(0); os << "AQUARIA_EVENT_JOYSTICK" << stick; @@ -205,7 +241,7 @@ void Joystick::init(int stick) void Joystick::shutdown() { -#ifdef __LINUX__ +#if defined(__LINUX__) && !defined(BBGE_BUILD_SDL2) if (eventfd >= 0) { if (effectid != -1 && ioctl(eventfd, EVIOCRMFF, effectid) == -1) { debugLog(std::string("Remove rumble effect: ") + strerror(errno)); @@ -217,9 +253,7 @@ void Joystick::shutdown() #ifdef BBGE_BUILD_SDL if (sdl_joy) { - if (SDL_JoystickOpened(stickIndex)) { - SDL_JoystickClose(sdl_joy); - } + SDL_JoystickClose(sdl_joy); sdl_joy = 0; } #endif @@ -229,7 +263,17 @@ void Joystick::rumble(float leftMotor, float rightMotor, float time) { if (core->joystickEnabled && inited) { -#if defined(BBGE_BUILD_WINDOWS) && defined(BBGE_BUILD_XINPUT) +#ifdef BBGE_BUILD_SDL2 + if (sdl_haptic) + { + const float power = (leftMotor + rightMotor) / 2.0f; + if ((power > 0.0f) && (time > 0.0f)) + SDL_HapticRumblePlay(sdl_haptic, power, (Uint32) (time * 1000.0f)); + else + SDL_HapticRumbleStop(sdl_haptic); + } + +#elif defined(BBGE_BUILD_WINDOWS) && defined(BBGE_BUILD_XINPUT) XINPUT_VIBRATION vib; vib.wLeftMotorSpeed = WORD(leftMotor*65535); vib.wRightMotorSpeed = WORD(rightMotor*65535); @@ -325,14 +369,55 @@ void Joystick::callibrate(Vector &calvec, float deadZone) } void Joystick::update(float dt) -{ +{ #ifdef BBGE_BUILD_SDL if (core->joystickEnabled && inited && sdl_joy && stickIndex != -1) - { + { +#ifdef BBGE_BUILD_SDL2 + if (!SDL_JoystickGetAttached(sdl_joy)) + { + debugLog("Lost Joystick"); + if (sdl_haptic) { SDL_HapticClose(sdl_haptic); sdl_haptic = NULL; } + if (!sdl_controller) + SDL_JoystickClose(sdl_joy); + else + { + SDL_GameControllerClose(sdl_controller); + sdl_controller = NULL; + } + sdl_joy = NULL; + return; + } + + if (sdl_controller) + { + Sint16 xaxis = SDL_GameControllerGetAxis(sdl_controller, SDL_CONTROLLER_AXIS_LEFTX); + Sint16 yaxis = SDL_GameControllerGetAxis(sdl_controller, SDL_CONTROLLER_AXIS_LEFTY); + position.x = double(xaxis)/32768.0; + position.y = double(yaxis)/32768.0; + + Sint16 xaxis2 = SDL_GameControllerGetAxis(sdl_controller, SDL_CONTROLLER_AXIS_RIGHTX); + Sint16 yaxis2 = SDL_GameControllerGetAxis(sdl_controller, SDL_CONTROLLER_AXIS_RIGHTY); + rightStick.x = double(xaxis2)/32768.0; + rightStick.y = double(yaxis2)/32768.0; + } + else + { + Sint16 xaxis = SDL_JoystickGetAxis(sdl_joy, s1ax); + Sint16 yaxis = SDL_JoystickGetAxis(sdl_joy, s1ay); + position.x = double(xaxis)/32768.0; + position.y = double(yaxis)/32768.0; + + Sint16 xaxis2 = SDL_JoystickGetAxis(sdl_joy, s2ax); + Sint16 yaxis2 = SDL_JoystickGetAxis(sdl_joy, s2ay); + rightStick.x = double(xaxis2)/32768.0; + rightStick.y = double(yaxis2)/32768.0; + } +#else if (!SDL_JoystickOpened(stickIndex)) { debugLog("Lost Joystick"); - sdl_joy = 0; + sdl_joy = NULL; return; } @@ -341,11 +426,11 @@ void Joystick::update(float dt) position.x = xaxis/32768.0f; position.y = yaxis/32768.0f; - Sint16 xaxis2 = SDL_JoystickGetAxis(sdl_joy, s2ax); Sint16 yaxis2 = SDL_JoystickGetAxis(sdl_joy, s2ay); rightStick.x = xaxis2/32768.0f; rightStick.y = yaxis2/32768.0f; +#endif /* std::ostringstream os; @@ -364,8 +449,23 @@ void Joystick::update(float dt) os2 << "joy2(" << position.x << ", " << position.y << ")"; debugLog(os2.str()); */ +#ifdef BBGE_BUILD_SDL2 + if (sdl_controller) + { + for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) + buttons[i] = SDL_GameControllerGetButton(sdl_controller, (SDL_GameControllerButton)i)?DOWN:UP; + for (int i = SDL_CONTROLLER_BUTTON_MAX; i < maxJoyBtns; i++) + buttons[i] = UP; + } + else + { + for (int i = 0; i < maxJoyBtns; i++) + buttons[i] = SDL_JoystickGetButton(sdl_joy, i)?DOWN:UP; + } +#else for (int i = 0; i < maxJoyBtns; i++) buttons[i] = SDL_JoystickGetButton(sdl_joy, i)?DOWN:UP; +#endif /* unsigned char btns[maxJoyBtns]; glfwGetJoystickButtons(GLFW_JOYSTICK_1, btns, maxJoyBtns); diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b3823b..2099adf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ OPTION(AQUARIA_DEVELOPER_BUILD "Developer Build?" FALSE) OPTION(AQUARIA_DEMO_BUILD "Demo Build?" FALSE) OPTION(AQUARIA_USE_VFS "Use Virtual File System? Required for some additional features." TRUE) +OPTION(AQUARIA_USE_SDL2 "Use SDL2" TRUE) + # No Steamworks SDK for Linux at the moment. Roll our own achievements. ADD_DEFINITIONS(-DBBGE_BUILD_ACHIEVEMENTS_INTERNAL=1) @@ -161,20 +163,37 @@ endif(NOT OGGVORBIS_FOUND) OPTION(AQUARIA_INTERNAL_SDL "Always use included SDL library" ${WIN32_TRUE}) if(NOT AQUARIA_INTERNAL_SDL) - find_package(SDL) + if(AQUARIA_USE_SDL2) + find_package(SDL2) + else(AQUARIA_USE_SDL2) + find_package(SDL) + endif(AQUARIA_USE_SDL2) endif(NOT AQUARIA_INTERNAL_SDL) if(NOT SDL_FOUND) - if(MACOSX) + if(AQUARIA_USE_SDL2) + set(SDLDIR "${EXTLIBDIR}/SDL2") + else(AQUARIA_USE_SDL2) set(SDLDIR "${EXTLIBDIR}/SDL12") + endif(AQUARIA_USE_SDL2) + + if(MACOSX) set(SDL_INCLUDE_DIR "${SDLDIR}/include") message(STATUS "Using internal copy of SDL") - set(SDL_LIBRARY "${SDLDIR}/lib/macosx/libSDL-1.2.0.dylib;${SDLDIR}/lib/macosx/libSDLmain.a") + if(AQUARIA_USE_SDL2) + set(SDL_LIBRARY "${SDLDIR}/lib/macosx/libSDL-2.0.0.dylib") + else(AQUARIA_USE_SDL2) + set(SDL_LIBRARY "${SDLDIR}/lib/macosx/libSDL-1.2.0.dylib;${SDLDIR}/lib/macosx/libSDLmain.a") + endif(AQUARIA_USE_SDL2) elseif(WIN32) - set(SDLDIR "${EXTLIBDIR}/SDL12") set(SDL_INCLUDE_DIR "${SDLDIR}/include" CACHE PATH "SDL include directory" FORCE) message(STATUS "Using internal copy of SDL") - set(SDLMAIN_LIBRARY "${SDLDIR}/lib/win32/SDLmain.lib" CACHE FILEPATH "Where the SDLmain library can be found" FORCE) - set(SDL_LIBRARY "${SDLDIR}/lib/win32/SDL.lib" CACHE FILEPATH "Where the SDL library can be found" FORCE) + if(AQUARIA_USE_SDL2) + set(SDLMAIN_LIBRARY "${SDLDIR}/lib/win32/SDL2main.lib" CACHE FILEPATH "Where the SDL2main library can be found" FORCE) + set(SDL_LIBRARY "${SDLDIR}/lib/win32/SDL2.lib" CACHE FILEPATH "Where the SDL2 library can be found" FORCE) + else(AQUARIA_USE_SDL2) + set(SDLMAIN_LIBRARY "${SDLDIR}/lib/win32/SDLmain.lib" CACHE FILEPATH "Where the SDLmain library can be found" FORCE) + set(SDL_LIBRARY "${SDLDIR}/lib/win32/SDL.lib" CACHE FILEPATH "Where the SDL library can be found" FORCE) + endif(AQUARIA_USE_SDL2) set(SDL_LIBRARY ${SDLMAIN_LIBRARY} ${SDL_LIBRARY}) # not seen by user else(MACOSX) message(SEND_ERROR "We don't have a prebuilt SDL for this platform.") @@ -258,6 +277,10 @@ IF(AQUARIA_USE_VFS) ADD_DEFINITIONS(-DBBGE_BUILD_VFS=1) ENDIF(AQUARIA_USE_VFS) +IF(AQUARIA_USE_SDL2) + ADD_DEFINITIONS(-DBBGE_BUILD_SDL2=1) +ENDIF(AQUARIA_USE_SDL2) + IF(AQUARIA_DEVELOPER_BUILD) message(STATUS "Developer build.") ELSE(AQUARIA_DEVELOPER_BUILD)