X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=vid_sdl.c;h=8a7a326aaf93a4cca41ce1a8ef6e56781dae417d;hb=406899eb226c2aaf9ff20abdccb6e6823b02b376;hp=0a6bb75e4ff0fa10161cc28f60bf7532936c996d;hpb=2a97ec851bd607510e33148335fc61d51e7138cf;p=xonotic%2Fdarkplaces.git diff --git a/vid_sdl.c b/vid_sdl.c index 0a6bb75e..8a7a326a 100644 --- a/vid_sdl.c +++ b/vid_sdl.c @@ -72,7 +72,6 @@ static qbool vid_usingmouse = false; static qbool vid_usingmouse_relativeworks = false; // SDL2 workaround for unimplemented RelativeMouse mode static qbool vid_usinghidecursor = false; static qbool vid_hasfocus = false; -static qbool vid_isfullscreen; static qbool vid_usingvsync = false; static SDL_Joystick *vid_sdljoystick = NULL; static SDL_GameController *vid_sdlgamecontroller = NULL; @@ -83,12 +82,9 @@ static cvar_t *steelstorm_showing_mousecursor = NULL; // detect but do not creat static int win_half_width = 50; static int win_half_height = 50; -static int video_bpp; static SDL_GLContext context; static SDL_Window *window; -static int window_flags; -static vid_mode_t desktop_mode; // Input handling @@ -100,7 +96,8 @@ static int MapKey( unsigned int sdlkey ) { switch(sdlkey) { - default: return 0; + // sdlkey can be Unicode codepoint for non-ascii keys, which are valid + default: return sdlkey & SDLK_SCANCODE_MASK ? 0 : sdlkey; // case SDLK_UNKNOWN: return K_UNKNOWN; case SDLK_RETURN: return K_ENTER; case SDLK_ESCAPE: return K_ESCAPE; @@ -377,7 +374,7 @@ void VID_SetMouse(qbool relative, qbool hidecursor) #ifdef MACOSX if(relative) if(vid_usingmouse && (vid_usingnoaccel != !!apple_mouse_noaccel.integer)) - VID_SetMouse(false, false, false); // ungrab first! + VID_SetMouse(false, false); // ungrab first! #endif if (vid_usingmouse != relative) { @@ -1059,13 +1056,12 @@ static keynum_t buttonremap[] = }; //#define DEBUGSDLEVENTS - -// SDL2 -void Sys_SendKeyEvents( void ) +void Sys_SDL_HandleEvents(void) { static qbool sound_active = true; int keycode; int i; + const char *chp; qbool isdown; Uchar unicode; SDL_Event event; @@ -1222,9 +1218,14 @@ void Sys_SendKeyEvents( void ) #endif // convert utf8 string to char // NOTE: this code is supposed to run even if utf8enable is 0 - unicode = u8_getchar_utf8_enabled(event.text.text + (int)u8_bytelen(event.text.text, 0), NULL); - Key_Event(K_TEXT, unicode, true); - Key_Event(K_TEXT, unicode, false); + chp = event.text.text; + while (*chp != 0) + { + // input the chars one by one (there can be multiple chars when e.g. using an "input method") + unicode = u8_getchar_utf8_enabled(chp, &chp); + Key_Event(K_TEXT, unicode, true); + Key_Event(K_TEXT, unicode, false); + } break; case SDL_MOUSEMOTION: break; @@ -1319,8 +1320,6 @@ qbool GL_ExtensionSupported(const char *name) return SDL_GL_ExtensionSupported(name); } -static qbool vid_sdl_initjoysticksystem = false; - void VID_Init (void) { #ifndef __IPHONEOS__ @@ -1339,10 +1338,8 @@ void VID_Init (void) if (SDL_Init(SDL_INIT_VIDEO) < 0) Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError()); - vid_sdl_initjoysticksystem = SDL_InitSubSystem(SDL_INIT_JOYSTICK) >= 0; - if (!vid_sdl_initjoysticksystem) + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) Con_Printf(CON_ERROR "Failed to init SDL joystick subsystem: %s\n", SDL_GetError()); - vid_isfullscreen = false; } static int vid_sdljoystickindex = -1; @@ -1465,12 +1462,6 @@ static void AdjustWindowBounds(viddef_mode_t *mode, RECT *rect) } #endif -extern cvar_t gl_info_vendor; -extern cvar_t gl_info_renderer; -extern cvar_t gl_info_version; -extern cvar_t gl_info_platform; -extern cvar_t gl_info_driver; - static qbool VID_InitModeGL(viddef_mode_t *mode) { int windowflags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; @@ -1480,7 +1471,8 @@ static qbool VID_InitModeGL(viddef_mode_t *mode) int yPos = SDL_WINDOWPOS_UNDEFINED; int i; #ifndef USE_GLES2 - const char *drivername; + // SDL usually knows best + const char *drivername = NULL; #endif win_half_width = mode->width>>1; @@ -1492,9 +1484,6 @@ static qbool VID_InitModeGL(viddef_mode_t *mode) VID_OutputVersion(); #ifndef USE_GLES2 - // SDL usually knows best - drivername = NULL; - // COMMANDLINEOPTION: SDL GL: -gl_driver selects a GL driver library, default is whatever SDL recommends, useful only for 3dfxogl.dll/3dfxvgl.dll or fxmesa or similar, if you don't know what this is for, you don't need it i = Sys_CheckParm("-gl_driver"); if (i && i < sys.argc - 1) @@ -1513,40 +1502,41 @@ static qbool VID_InitModeGL(viddef_mode_t *mode) windowflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS; #endif - vid_isfullscreen = false; + + if (mode->fullscreen) { - if (mode->fullscreen) { - if (vid_desktopfullscreen.integer) - { - vid_mode_t *m = VID_GetDesktopMode(); - mode->width = m->width; - mode->height = m->height; - windowflags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - } - else - windowflags |= SDL_WINDOW_FULLSCREEN; - vid_isfullscreen = true; + if (vid_desktopfullscreen.integer) + { + vid_mode_t m = VID_GetDesktopMode(); + mode->width = m.width; + mode->height = m.height; + windowflags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } - else { - if (vid_borderless.integer) - windowflags |= SDL_WINDOW_BORDERLESS; + else + windowflags |= SDL_WINDOW_FULLSCREEN; + } + else + { + if (vid_borderless.integer) + windowflags |= SDL_WINDOW_BORDERLESS; #ifdef WIN32 - if (vid_ignore_taskbar.integer) { - xPos = SDL_WINDOWPOS_CENTERED; - yPos = SDL_WINDOWPOS_CENTERED; - } - else { - RECT rect; - AdjustWindowBounds(mode, &rect); - xPos = rect.left; - yPos = rect.top; - } -#endif + if (vid_ignore_taskbar.integer) + { + xPos = SDL_WINDOWPOS_CENTERED; + yPos = SDL_WINDOWPOS_CENTERED; + } + else + { + RECT rect; + AdjustWindowBounds(mode, &rect); + xPos = rect.left; + yPos = rect.top; } +#endif } - //flags |= SDL_HWSURFACE; - if (vid_mouse_clickthrough.integer && !vid_isfullscreen) + + if (vid_mouse_clickthrough.integer) SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); @@ -1572,12 +1562,13 @@ static qbool VID_InitModeGL(viddef_mode_t *mode) SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + /* Requesting a Core profile and 3.2 minimum is mandatory on macOS and older Mesa drivers. + * It works fine on other drivers too except NVIDIA, see HACK below. + */ #endif SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, (gl_debug.integer > 0 ? SDL_GL_CONTEXT_DEBUG_FLAG : 0)); - video_bpp = mode->bitsperpixel; - window_flags = windowflags; window = SDL_CreateWindow(gamename, xPos, yPos, mode->width, mode->height, windowflags); if (window == NULL) { @@ -1594,10 +1585,39 @@ static qbool VID_InitModeGL(viddef_mode_t *mode) return false; } + GL_InitFunctions(); + +#if !defined(USE_GLES2) && !defined(MACOSX) + // NVIDIA hates the Core profile and limits the version to the minimum we specified. + // HACK: to detect NVIDIA we first need a context, fortunately replacing it takes a few milliseconds + gl_vendor = (const char *)qglGetString(GL_VENDOR); + if (strncmp(gl_vendor, "NVIDIA", 6) == 0) + { + Con_DPrint("The Way It's Meant To Be Played: replacing OpenGL Core profile with Compatibility profile...\n"); + SDL_GL_DeleteContext(context); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); + context = SDL_GL_CreateContext(window); + if (context == NULL) + { + Con_Printf(CON_ERROR "Failed to initialize OpenGL context: %s\n", SDL_GetError()); + VID_Shutdown(); + return false; + } + } +#endif + SDL_GL_SetSwapInterval(bound(-1, vid_vsync.integer, 1)); vid_usingvsync = (vid_vsync.integer != 0); - gl_platform = "SDL"; + vid_hidden = false; + vid_activewindow = true; + vid_hasfocus = true; + vid_usingmouse = false; + vid_usinghidecursor = false; + + // clear to black (loading plaque will be seen over this) + GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 0); + VID_Finish(); // checks vid_hidden GL_Setup(); @@ -1605,40 +1625,12 @@ static qbool VID_InitModeGL(viddef_mode_t *mode) Cvar_SetQuick(&gl_info_vendor, gl_vendor); Cvar_SetQuick(&gl_info_renderer, gl_renderer); Cvar_SetQuick(&gl_info_version, gl_version); - Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : ""); - Cvar_SetQuick(&gl_info_driver, gl_driver); - - // LadyHavoc: report supported extensions - Con_DPrintf("\nQuakeC extensions for server and client:"); - for (i = 0; vm_sv_extensions[i]; i++) - Con_DPrintf(" %s", vm_sv_extensions[i]); - Con_DPrintf("\n"); -#ifdef CONFIG_MENU - Con_DPrintf("\nQuakeC extensions for menu:"); - for (i = 0; vm_m_extensions[i]; i++) - Con_DPrintf(" %s", vm_m_extensions[i]); - Con_DPrintf("\n"); -#endif - - // clear to black (loading plaque will be seen over this) - GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 0); + Cvar_SetQuick(&gl_info_platform, "SDL"); + Cvar_SetQuick(&gl_info_driver, drivername ? drivername : ""); - vid_hidden = false; - vid_activewindow = false; - vid_hasfocus = true; - vid_usingmouse = false; - vid_usinghidecursor = false; - return true; } -extern cvar_t gl_info_extensions; -extern cvar_t gl_info_vendor; -extern cvar_t gl_info_renderer; -extern cvar_t gl_info_version; -extern cvar_t gl_info_platform; -extern cvar_t gl_info_driver; - qbool VID_InitMode(viddef_mode_t *mode) { // GAME_STEELSTORM specific @@ -1657,14 +1649,12 @@ void VID_Shutdown (void) VID_EnableJoystick(false); VID_SetMouse(false, false); + SDL_GL_DeleteContext(context); + context = NULL; SDL_DestroyWindow(window); window = NULL; SDL_QuitSubSystem(SDL_INIT_VIDEO); - - gl_driver[0] = 0; - gl_extensions = ""; - gl_platform = ""; } void VID_Finish (void) @@ -1699,11 +1689,13 @@ void VID_Finish (void) } } -vid_mode_t *VID_GetDesktopMode(void) +vid_mode_t VID_GetDesktopMode(void) { SDL_DisplayMode mode; int bpp; Uint32 rmask, gmask, bmask, amask; + vid_mode_t desktop_mode; + SDL_GetDesktopDisplayMode(0, &mode); SDL_PixelFormatEnumToMasks(mode.format, &bpp, &rmask, &gmask, &bmask, &amask); desktop_mode.width = mode.w; @@ -1715,7 +1707,7 @@ vid_mode_t *VID_GetDesktopMode(void) // TODO check whether this actually works, or whether we do still need // a read-window-size-after-entering-desktop-fullscreen hack for // multiscreen setups. - return &desktop_mode; + return desktop_mode; } size_t VID_ListModes(vid_mode_t *modes, size_t maxcount)