From d625caf03c7d5a7cc673af432a8b6d32787c3bf1 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 8 Dec 2014 18:46:10 -0500 Subject: [PATCH] - Ported SDL backend to SDL 2.0. Still needs a little bit of polish, but it works. --- FindSDL2.cmake | 180 +++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 9 +- src/sdl/i_gui.cpp | 54 +++--------- src/sdl/i_input.cpp | 196 ++++++++++++++--------------------------- src/sdl/i_joystick.cpp | 2 +- src/sdl/i_main.cpp | 17 +--- src/sdl/sdlvideo.cpp | 99 ++++++++++++++------- 7 files changed, 331 insertions(+), 226 deletions(-) create mode 100644 FindSDL2.cmake diff --git a/FindSDL2.cmake b/FindSDL2.cmake new file mode 100644 index 000000000..614426ccc --- /dev/null +++ b/FindSDL2.cmake @@ -0,0 +1,180 @@ +# Locate SDL2 library +# This module defines +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2_main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDL2main.h and SDL2main.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2DIR is an environment variable that would +# correspond to the ./configure --prefix=$SDL2DIR +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL2 guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL2 convention +# is #include "SDL.h", not . This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). +# +# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake +# module with the minor edit of changing "SDL" to "SDL2" where necessary. This +# was not created for redistribution, and exists temporarily pending official +# SDL2 CMake modules. + +#============================================================================= +# Copyright 2003-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES include/SDL2 include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/include/SDL2 + /usr/include/SDL2 + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) +#MESSAGE("SDL2_INCLUDE_DIR is ${SDL2_INCLUDE_DIR}") + +FIND_LIBRARY(SDL2_LIBRARY_TEMP + NAMES SDL2 + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + /sw + /opt/local + /opt/csw + /opt +) + +#MESSAGE("SDL2_LIBRARY_TEMP is ${SDL2_LIBRARY_TEMP}") + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + /sw + /opt/local + /opt/csw + /opt + ) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional library, mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows +# (Actually on second look, I think it only needs one of the m* libraries.) +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +SET(SDL2_FOUND "NO") +IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") + + SET(SDL2_FOUND "YES") +ENDIF(SDL2_LIBRARY_TEMP) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 + REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 07c13c20c..8838dea05 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -210,14 +210,11 @@ else( WIN32 ) endif( NO_GTK ) # Non-Windows version also needs SDL - find_package( SDL ) - if( NOT SDL_FOUND ) - message( SEND_ERROR "SDL is required for building." ) - endif( NOT SDL_FOUND ) + find_package( SDL2 REQUIRED ) if( NOT APPLE OR NOT OSX_COCOA_BACKEND ) - set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL_LIBRARY}" ) + set( ZDOOM_LIBS ${ZDOOM_LIBS} "${SDL2_LIBRARY}" ) endif( NOT APPLE OR NOT OSX_COCOA_BACKEND ) - include_directories( "${SDL_INCLUDE_DIR}" ) + include_directories( "${SDL2_INCLUDE_DIR}" ) find_path( FPU_CONTROL_DIR fpu_control.h ) if( FPU_CONTROL_DIR ) diff --git a/src/sdl/i_gui.cpp b/src/sdl/i_gui.cpp index b40fb7517..39b66c085 100644 --- a/src/sdl/i_gui.cpp +++ b/src/sdl/i_gui.cpp @@ -9,9 +9,6 @@ #include "v_palette.h" #include "textures.h" -extern SDL_Surface *cursorSurface; -extern SDL_Rect cursorBlit; - #ifdef USE_XCURSOR // Xlib has its own GC, so don't let it interfere. #define GC XGC @@ -22,40 +19,6 @@ bool UseXCursor; SDL_Cursor *X11Cursor; SDL_Cursor *FirstCursor; -// Hack! Hack! SDL does not provide a clean way to get the XDisplay. -// On the other hand, there are no more planned updates for SDL 1.2, -// so we should be fine making assumptions. -struct SDL_PrivateVideoData -{ - int local_X11; - Display *X11_Display; -}; - -struct SDL_VideoDevice -{ - const char *name; - int (*functions[9])(); - SDL_VideoInfo info; - SDL_PixelFormat *displayformatalphapixel; - int (*morefuncs[9])(); - Uint16 *gamma; - int (*somefuncs[9])(); - unsigned int texture; // Only here if SDL was compiled with OpenGL support. Ack! - int is_32bit; - int (*itsafuncs[13])(); - SDL_Surface *surfaces[3]; - SDL_Palette *physpal; - SDL_Color *gammacols; - char *wm_strings[2]; - int offsets[2]; - SDL_GrabMode input_grab; - int handles_any_size; - SDL_PrivateVideoData *hidden; // Why did they have to bury this so far in? -}; - -extern SDL_VideoDevice *current_video; -#define SDL_Display (current_video->hidden->X11_Display) - SDL_Cursor *CreateColorCursor(FTexture *cursorpic) { return NULL; @@ -64,6 +27,9 @@ SDL_Cursor *CreateColorCursor(FTexture *cursorpic) bool I_SetCursor(FTexture *cursorpic) { + static SDL_Cursor *cursor; + static SDL_Surface *cursorSurface; + if (cursorpic != NULL && cursorpic->UseType != FTexture::TEX_Null) { // Must be no larger than 32x32. @@ -90,7 +56,6 @@ bool I_SetCursor(FTexture *cursorpic) if (cursorSurface == NULL) cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0)); - SDL_ShowCursor(0); SDL_LockSurface(cursorSurface); BYTE buffer[32*32*4]; memset(buffer, 0, 32*32*4); @@ -98,11 +63,20 @@ bool I_SetCursor(FTexture *cursorpic) cursorpic->CopyTrueColorPixels(&bmp, 0, 0); memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4); SDL_UnlockSurface(cursorSurface); + + if (cursor) + SDL_FreeCursor (cursor); + cursor = SDL_CreateColorCursor (cursorSurface, 0, 0); + SDL_SetCursor (cursor); } else { - SDL_ShowCursor(1); - + if (cursor) + { + SDL_SetCursor (NULL); + SDL_FreeCursor (cursor); + cursor = NULL; + } if (cursorSurface != NULL) { SDL_FreeSurface(cursorSurface); diff --git a/src/sdl/i_input.cpp b/src/sdl/i_input.cpp index bf676db70..722345cb2 100644 --- a/src/sdl/i_input.cpp +++ b/src/sdl/i_input.cpp @@ -29,19 +29,16 @@ extern int paused; CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, sdl_nokeyrepeat, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) EXTERN_CVAR (Bool, fullscreen) extern int WaitingForKey, chatmodeon; extern constate_e ConsoleState; -extern SDL_Surface *cursorSurface; -extern SDL_Rect cursorBlit; +static TMap KeySymToDIK; +static bool DownState[SDL_NUM_SCANCODES]; -static BYTE KeySymToDIK[SDLK_LAST], DownState[SDLK_LAST]; - -static WORD DIKToKeySym[256] = +static SDL_Keycode DIKToKeySym[256] = { 0, SDLK_ESCAPE, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', SDLK_BACKSPACE, SDLK_TAB, @@ -51,9 +48,9 @@ static WORD DIKToKeySym[256] = '\'', '`', SDLK_LSHIFT, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', SDLK_RSHIFT, SDLK_KP_MULTIPLY, SDLK_LALT, ' ', SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, - SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCK, SDLK_SCROLLOCK, SDLK_KP7, - SDLK_KP8, SDLK_KP9, SDLK_KP_MINUS, SDLK_KP4, SDLK_KP5, SDLK_KP6, SDLK_KP_PLUS, SDLK_KP1, - SDLK_KP2, SDLK_KP3, SDLK_KP0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11, + SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCKCLEAR, SDLK_SCROLLLOCK, SDLK_KP_7, + SDLK_KP_8, SDLK_KP_9, SDLK_KP_MINUS, SDLK_KP_4, SDLK_KP_5, SDLK_KP_6, SDLK_KP_PLUS, SDLK_KP_1, + SDLK_KP_2, SDLK_KP_3, SDLK_KP_0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11, SDLK_F12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SDLK_F13, SDLK_F14, SDLK_F15, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -70,7 +67,7 @@ static WORD DIKToKeySym[256] = 0, 0, 0, 0, 0, SDLK_PAUSE, 0, SDLK_HOME, SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END, SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0, - 0, 0, 0, SDLK_LSUPER, SDLK_RSUPER, SDLK_MENU, SDLK_POWER, 0, + 0, 0, 0, SDLK_LGUI, SDLK_RGUI, SDLK_MENU, SDLK_POWER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -92,16 +89,12 @@ static void InitKeySymMap () KeySymToDIK[SDLK_RCTRL] = DIK_LCONTROL; KeySymToDIK[SDLK_RALT] = DIK_LMENU; // Depending on your Linux flavor, you may get SDLK_PRINT or SDLK_SYSREQ - KeySymToDIK[SDLK_PRINT] = DIK_SYSRQ; + KeySymToDIK[SDLK_PRINTSCREEN] = DIK_SYSRQ; } static void I_CheckGUICapture () { bool wantCapt; - bool repeat; - int oldrepeat, interval; - - SDL_GetKeyRepeat(&oldrepeat, &interval); if (menuactive == MENU_Off) { @@ -117,56 +110,20 @@ static void I_CheckGUICapture () GUICapture = wantCapt; if (wantCapt) { - int x, y; - SDL_GetMouseState (&x, &y); - cursorBlit.x = x; - cursorBlit.y = y; - FlushDIKState (); memset (DownState, 0, sizeof(DownState)); - repeat = !sdl_nokeyrepeat; - SDL_EnableUNICODE (1); - } - else - { - repeat = false; - SDL_EnableUNICODE (0); - } - } - if (wantCapt) - { - repeat = !sdl_nokeyrepeat; - } - else - { - repeat = false; - } - if (repeat != (oldrepeat != 0)) - { - if (repeat) - { - SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - } - else - { - SDL_EnableKeyRepeat (0, 0); } } } void I_SetMouseCapture() { + SDL_SetRelativeMouseMode (SDL_TRUE); } void I_ReleaseMouseCapture() { -} - -static void CenterMouse () -{ - SDL_WarpMouse (screen->GetWidth()/2, screen->GetHeight()/2); - SDL_PumpEvents (); - SDL_GetRelativeMouseState (NULL, NULL); + SDL_SetRelativeMouseMode (SDL_FALSE); } static void PostMouseMove (int x, int y) @@ -210,33 +167,10 @@ static void MouseRead () } if (x | y) { - CenterMouse (); PostMouseMove (x, -y); } } -static void WheelMoved(event_t *event) -{ - if (GUICapture) - { - if (event->type != EV_KeyUp) - { - SDLMod mod = SDL_GetModState(); - event->type = EV_GUI_Event; - event->subtype = event->data1 == KEY_MWHEELUP ? EV_GUI_WheelUp : EV_GUI_WheelDown; - event->data1 = 0; - event->data3 = ((mod & KMOD_SHIFT) ? GKM_SHIFT : 0) | - ((mod & KMOD_CTRL) ? GKM_CTRL : 0) | - ((mod & KMOD_ALT) ? GKM_ALT : 0); - D_PostEvent(event); - } - } - else - { - D_PostEvent(event); - } -} - CUSTOM_CVAR(Int, mouse_capturemode, 1, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) { if (self < 0) self = 0; @@ -259,26 +193,20 @@ static bool inGame() static void I_CheckNativeMouse () { - bool focus = (SDL_GetAppState() & (SDL_APPINPUTFOCUS|SDL_APPACTIVE)) - == (SDL_APPINPUTFOCUS|SDL_APPACTIVE); - bool fs = (SDL_GetVideoSurface ()->flags & SDL_FULLSCREEN) != 0; + bool focus = SDL_GetMouseFocus() != NULL; + bool fs = screen->IsFullscreen(); bool wantNative = !focus || (!use_mouse || GUICapture || paused || demoplayback || !inGame()); if (wantNative != NativeMouse) { NativeMouse = wantNative; - SDL_ShowCursor (wantNative ? cursorSurface == NULL : 0); + SDL_ShowCursor (wantNative); + SDL_SetRelativeMouseMode (wantNative ? SDL_FALSE : SDL_TRUE); if (wantNative) { - SDL_WM_GrabInput (SDL_GRAB_OFF); FlushDIKState (KEY_MOUSE1, KEY_MOUSE8); } - else - { - SDL_WM_GrabInput (SDL_GRAB_ON); - CenterMouse (); - } } } @@ -293,14 +221,17 @@ void MessagePump (const SDL_Event &sev) case SDL_QUIT: exit (0); - case SDL_ACTIVEEVENT: - if (sev.active.state == SDL_APPINPUTFOCUS) + case SDL_WINDOWEVENT: + switch (sev.window.event) { - if (sev.active.gain == 0) - { // kill focus - FlushDIKState (); - } - S_SetSoundPaused(sev.active.gain); + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + if (sev.window.event == SDL_WINDOWEVENT_FOCUS_LOST) + { // kill focus + FlushDIKState (); + } + S_SetSoundPaused(sev.window.event == SDL_WINDOWEVENT_FOCUS_GAINED); + break; } break; @@ -320,32 +251,20 @@ void MessagePump (const SDL_Event &sev) */ switch (sev.button.button) { - case 1: event.data1 = KEY_MOUSE1; break; - case 2: event.data1 = KEY_MOUSE3; break; - case 3: event.data1 = KEY_MOUSE2; break; - case 4: event.data1 = KEY_MWHEELUP; break; - case 5: event.data1 = KEY_MWHEELDOWN; break; - case 6: event.data1 = KEY_MOUSE4; break; /* dunno; not generated by my mouse */ - case 7: event.data1 = KEY_MOUSE5; break; /* ditto */ - case 8: event.data1 = KEY_MOUSE4; break; + case SDL_BUTTON_LEFT: event.data1 = KEY_MOUSE1; break; + case SDL_BUTTON_MIDDLE: event.data1 = KEY_MOUSE3; break; + case SDL_BUTTON_RIGHT: event.data1 = KEY_MOUSE2; break; + case 8: event.data1 = KEY_MOUSE4; break; // For whatever reason my side mouse buttons are here. case 9: event.data1 = KEY_MOUSE5; break; - case 10: event.data1 = KEY_MOUSE6; break; - case 11: event.data1 = KEY_MOUSE7; break; - case 12: event.data1 = KEY_MOUSE8; break; + case SDL_BUTTON_X1: event.data1 = KEY_MOUSE6; break; // And these don't exist + case SDL_BUTTON_X2: event.data1 = KEY_MOUSE7; break; + case 6: event.data1 = KEY_MOUSE8; break; default: printf("SDL mouse button %s %d\n", sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break; } if (event.data1 != 0) { - //DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown); - if (event.data1 == KEY_MWHEELUP || event.data1 == KEY_MWHEELDOWN) - { - WheelMoved(&event); - } - else - { - D_PostEvent(&event); - } + D_PostEvent(&event); } } } @@ -354,8 +273,8 @@ void MessagePump (const SDL_Event &sev) int x, y; SDL_GetMouseState (&x, &y); - cursorBlit.x = event.data1 = x; - cursorBlit.y = event.data2 = y; + event.data1 = x; + event.data2 = y; event.type = EV_GUI_Event; if(sev.type == SDL_MOUSEMOTION) event.subtype = EV_GUI_MouseMove; @@ -368,11 +287,25 @@ void MessagePump (const SDL_Event &sev) } break; + case SDL_MOUSEWHEEL: + if (GUICapture) + { + event.type = EV_GUI_Event; + event.subtype = sev.wheel.y > 0 ? EV_GUI_WheelUp : EV_GUI_WheelDown; + D_PostEvent (&event); + } + else + { + event.type = EV_KeyDown; + event.data1 = sev.wheel.y > 0 ? KEY_MWHEELUP : KEY_MWHEELDOWN; + D_PostEvent (&event); + event.type = EV_KeyUp; + D_PostEvent (&event); + } + break; + case SDL_KEYDOWN: case SDL_KEYUP: - if (sev.key.keysym.sym >= SDLK_LAST) - break; - if (!GUICapture) { event.type = sev.type == SDL_KEYDOWN ? EV_KeyDown : EV_KeyUp; @@ -394,19 +327,19 @@ void MessagePump (const SDL_Event &sev) ((sev.key.keysym.mod & KMOD_CTRL) ? GKM_CTRL : 0) | ((sev.key.keysym.mod & KMOD_ALT) ? GKM_ALT : 0); - if (sev.key.keysym.sym < SDLK_LAST) + //if (sev.key.keysym.sym < SDLK_LAST) { if (event.subtype == EV_GUI_KeyDown) { - if (DownState[sev.key.keysym.sym]) + if (DownState[sev.key.keysym.scancode]) { event.subtype = EV_GUI_KeyRepeat; } - DownState[sev.key.keysym.sym] = 1; + DownState[sev.key.keysym.scancode] = 1; } else { - DownState[sev.key.keysym.sym] = 0; + DownState[sev.key.keysym.scancode] = 0; } } @@ -442,20 +375,21 @@ void MessagePump (const SDL_Event &sev) } break; } - event.data2 = sev.key.keysym.unicode & 0xff; if (event.data1 < 128) { event.data1 = toupper(event.data1); D_PostEvent (&event); } - if (!iscntrl(event.data2) && event.subtype != EV_GUI_KeyUp) - { - event.subtype = EV_GUI_Char; - event.data1 = event.data2; - event.data2 = sev.key.keysym.mod & KMOD_ALT; - event.data3 = 0; - D_PostEvent (&event); - } + } + break; + + case SDL_TEXTINPUT: + if (GUICapture) + { + event.type = EV_GUI_Event; + event.subtype = EV_GUI_Char; + event.data1 = sev.text.text[0]; + D_PostEvent (&event); } break; diff --git a/src/sdl/i_joystick.cpp b/src/sdl/i_joystick.cpp index 7a529861f..9b1d326ae 100644 --- a/src/sdl/i_joystick.cpp +++ b/src/sdl/i_joystick.cpp @@ -35,7 +35,7 @@ public: FString GetName() { - return SDL_JoystickName(DeviceIndex); + return SDL_JoystickName(Device); } float GetSensitivity() { diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index 7a18fb05f..a928b7e7c 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -278,22 +278,11 @@ int main (int argc, char **argv) } atterm (SDL_Quit); - { - char viddriver[80]; - - if (SDL_VideoDriverName(viddriver, sizeof(viddriver)) != NULL) - { - printf("Using video driver %s\n", viddriver); + printf("Using video driver %s\n", SDL_GetCurrentVideoDriver()); #ifdef USE_XCURSOR - UseXCursor = (strcmp(viddriver, "x11") == 0); + UseXCursor = (strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0); #endif - } - printf("\n"); - } - - char caption[100]; - mysnprintf(caption, countof(caption), GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); - SDL_WM_SetCaption(caption, caption); + printf("\n"); #ifdef __APPLE__ diff --git a/src/sdl/sdlvideo.cpp b/src/sdl/sdlvideo.cpp index e4222633d..838c082b4 100644 --- a/src/sdl/sdlvideo.cpp +++ b/src/sdl/sdlvideo.cpp @@ -12,6 +12,7 @@ #include "v_palette.h" #include "sdlvideo.h" #include "r_swrenderer.h" +#include "version.h" #include @@ -56,13 +57,15 @@ private: int FlashAmount; float Gamma; bool UpdatePending; - - SDL_Surface *Screen; - + + SDL_Window *Screen; + SDL_Renderer *Renderer; + SDL_Texture *Texture; + bool NeedPalUpdate; bool NeedGammaUpdate; bool NotPaletted; - + void UpdateColors (); SDLFB () {} @@ -83,9 +86,6 @@ struct MiniModeInfo extern IVideo *Video; extern bool GUICapture; -SDL_Surface *cursorSurface = NULL; -SDL_Rect cursorBlit = {0, 0, 32, 32}; - EXTERN_CVAR (Float, Gamma) EXTERN_CVAR (Int, vid_maxfps) EXTERN_CVAR (Bool, cl_capfps) @@ -93,6 +93,8 @@ EXTERN_CVAR (Bool, vid_vsync) // PUBLIC DATA DEFINITIONS ------------------------------------------------- +CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + CVAR (Int, vid_displaybits, 8, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // vid_asyncblit needs a restart to work. SDL doesn't seem to change if the @@ -204,14 +206,19 @@ bool SDLVideo::NextMode (int *width, int *height, bool *letterbox) } else { - SDL_Rect **modes = SDL_ListModes (NULL, SDL_FULLSCREEN|SDL_HWSURFACE); - if (modes != NULL && modes[IteratorMode] != NULL) + SDL_DisplayMode mode = {}, oldmode = {}; + if(IteratorMode != 0) + SDL_GetDisplayMode(vid_adapter, IteratorMode-1, &oldmode); + do { - *width = modes[IteratorMode]->w; - *height = modes[IteratorMode]->h; + if (SDL_GetDisplayMode(vid_adapter, IteratorMode, &mode) != 0) + return false; ++IteratorMode; - return true; - } + } while(mode.w == oldmode.w && mode.h == oldmode.h); + + *width = mode.w; + *height = mode.h; + return true; } return false; } @@ -230,11 +237,11 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer (int width, int height, bool fullscree if (fb->Width == width && fb->Height == height) { - bool fsnow = (fb->Screen->flags & SDL_FULLSCREEN) != 0; + bool fsnow = (SDL_GetWindowFlags (fb->Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; if (fsnow != fullscreen) { - SDL_WM_ToggleFullScreen (fb->Screen); + SDL_SetWindowFullscreen (fb->Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); } return old; } @@ -313,24 +320,37 @@ SDLFB::SDLFB (int width, int height, bool fullscreen) UpdatePending = false; NotPaletted = false; FlashAmount = 0; - Screen = SDL_SetVideoMode (width, height, vid_displaybits, - (vid_asyncblit ? SDL_ASYNCBLIT : 0)|SDL_HWSURFACE|SDL_HWPALETTE|SDL_DOUBLEBUF|SDL_ANYFORMAT| - (fullscreen ? SDL_FULLSCREEN : 0)); + + FString caption; + caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); + Screen = SDL_CreateWindow (caption, + SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), + width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); if (Screen == NULL) return; + Renderer = SDL_CreateRenderer (Screen, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE); + if (Renderer == NULL) + return; + + Texture = SDL_CreateTexture (Renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height); + for (i = 0; i < 256; i++) { GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i; } - if (Screen->format->palette == NULL) + //if (Screen->format->palette == NULL) { NotPaletted = true; - GPfx.SetFormat (Screen->format->BitsPerPixel, - Screen->format->Rmask, - Screen->format->Gmask, - Screen->format->Bmask); + + Uint32 format; + SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); + + Uint32 Rmask, Gmask, Bmask, Amask; + int bpp; + SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); } memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); UpdateColors (); @@ -339,6 +359,16 @@ SDLFB::SDLFB (int width, int height, bool fullscreen) SDLFB::~SDLFB () { + if(Screen) + { + if (Renderer) + { + if (Texture) + SDL_DestroyTexture (Texture); + SDL_DestroyRenderer (Renderer); + } + SDL_DestroyWindow (Screen); + } } bool SDLFB::IsValid () @@ -403,15 +433,18 @@ void SDLFB::Update () SDLFlipCycles.Reset(); BlitCycles.Clock(); - if (SDL_LockSurface (Screen) == -1) + void *pixels; + int pitch; + if (SDL_LockTexture (Texture, NULL, &pixels, &pitch)) return; if (NotPaletted) { GPfx.Convert (MemBuffer, Pitch, - Screen->pixels, Screen->pitch, Width, Height, + pixels, pitch, Width, Height, FRACUNIT, FRACUNIT, 0, 0); } +#if 0 else { if (Screen->pitch == Pitch) @@ -426,17 +459,13 @@ void SDLFB::Update () } } } - - SDL_UnlockSurface (Screen); +#endif - if (cursorSurface != NULL && GUICapture) - { - // SDL requires us to draw a surface to get true color cursors. - SDL_BlitSurface(cursorSurface, NULL, Screen, &cursorBlit); - } + SDL_UnlockTexture (Texture); SDLFlipCycles.Clock(); - SDL_Flip (Screen); + SDL_RenderCopy(Renderer, Texture, NULL, NULL); + SDL_RenderPresent(Renderer); SDLFlipCycles.Unclock(); BlitCycles.Unclock(); @@ -478,6 +507,7 @@ void SDLFB::UpdateColors () } GPfx.SetPalette (palette); } +#if 0 else { SDL_Color colors[256]; @@ -496,6 +526,7 @@ void SDLFB::UpdateColors () } SDL_SetPalette (Screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256); } +#endif } PalEntry *SDLFB::GetPalette () @@ -541,7 +572,7 @@ void SDLFB::GetFlashedPalette (PalEntry pal[256]) bool SDLFB::IsFullscreen () { - return (Screen->flags & SDL_FULLSCREEN) != 0; + return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; } void SDLFB::SetVSync (bool vsync)