X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=vid_sdl.c;h=8b0d1e3af2f77022ce9ae74dc2574ae217642a83;hb=ac8080688588aba1ab7934f7ba0c2ffea0c8eb91;hp=c9680a2f197bd2e4a0c9b7de4fa52b1a187e9522;hpb=371dd80226347111360c8222a17d1c3d6fc26c72;p=xonotic%2Fdarkplaces.git diff --git a/vid_sdl.c b/vid_sdl.c index c9680a2f..8b0d1e3a 100644 --- a/vid_sdl.c +++ b/vid_sdl.c @@ -30,7 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include -static cvar_t apple_mouse_noaccel = {CVAR_SAVE, "apple_mouse_noaccel", "1", "disables mouse acceleration while DarkPlaces is active"}; +static cvar_t apple_mouse_noaccel = {CVAR_CLIENT | CVAR_SAVE, "apple_mouse_noaccel", "1", "disables mouse acceleration while DarkPlaces is active"}; static qboolean vid_usingnoaccel; static double originalMouseSpeed = -1.0; io_connect_t IN_GetIOHandle(void) @@ -72,6 +72,8 @@ static qboolean vid_hasfocus = false; static qboolean vid_isfullscreen; static qboolean vid_usingvsync = false; static SDL_Joystick *vid_sdljoystick = NULL; +static SDL_GameController *vid_sdlgamecontroller = NULL; +static cvar_t joy_sdl2_trigger_deadzone = {CVAR_SAVE | CVAR_CLIENT, "joy_sdl2_trigger_deadzone", "0.5", "deadzone for triggers to be registered as key presses"}; // GAME_STEELSTORM specific static cvar_t *steelstorm_showing_map = NULL; // detect but do not create the cvar static cvar_t *steelstorm_showing_mousecursor = NULL; // detect but do not create the cvar @@ -692,14 +694,31 @@ void VID_BuildJoyState(vid_joystate_t *joystate) { SDL_Joystick *joy = vid_sdljoystick; int j; - int numaxes; - int numbuttons; - numaxes = SDL_JoystickNumAxes(joy); - for (j = 0;j < numaxes;j++) - joystate->axis[j] = SDL_JoystickGetAxis(joy, j) * (1.0f / 32767.0f); - numbuttons = SDL_JoystickNumButtons(joy); - for (j = 0;j < numbuttons;j++) - joystate->button[j] = SDL_JoystickGetButton(joy, j); + + if (vid_sdlgamecontroller) + { + for (j = 0; j <= SDL_CONTROLLER_AXIS_MAX; ++j) + { + joystate->axis[j] = SDL_GameControllerGetAxis(vid_sdlgamecontroller, (SDL_GameControllerAxis)j) * (1.0f / 32767.0f); + } + for (j = 0; j < SDL_CONTROLLER_BUTTON_MAX; ++j) + joystate->button[j] = SDL_GameControllerGetButton(vid_sdlgamecontroller, (SDL_GameControllerButton)j); + // emulate joy buttons for trigger "axes" + joystate->button[SDL_CONTROLLER_BUTTON_MAX] = VID_JoyState_GetAxis(joystate, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 1, joy_sdl2_trigger_deadzone.value) > 0.0f; + joystate->button[SDL_CONTROLLER_BUTTON_MAX+1] = VID_JoyState_GetAxis(joystate, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 1, joy_sdl2_trigger_deadzone.value) > 0.0f; + } + else + + { + int numaxes; + int numbuttons; + numaxes = SDL_JoystickNumAxes(joy); + for (j = 0;j < numaxes;j++) + joystate->axis[j] = SDL_JoystickGetAxis(joy, j) * (1.0f / 32767.0f); + numbuttons = SDL_JoystickNumButtons(joy); + for (j = 0;j < numbuttons;j++) + joystate->button[j] = SDL_JoystickGetButton(joy, j); + } } VID_Shared_BuildJoyState_Finish(joystate); @@ -875,7 +894,7 @@ static void IN_Move_TouchScreen_Quake(void) if (!VID_ShowingKeyboard()) { // user entered a command, close the console now - Con_ToggleConsole_f(); + Con_ToggleConsole_f(&cmd_client); } VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, NULL, &buttons[15], (keynum_t)0, NULL, 0, 0, 0, true); VID_TouchscreenArea( 0, 0, 0, 0, 0, NULL , 0.0f, NULL, move, &buttons[0], K_MOUSE4, NULL, 0, 0, 0, true); @@ -1156,11 +1175,11 @@ void Sys_SendKeyEvents( void ) vid.width = event.window.data1; vid.height = event.window.data2; #ifdef SDL_R_RESTART - // better not call R_Modules_Restart from here directly, as this may wreak havoc... + // better not call R_Modules_Restart_f from here directly, as this may wreak havoc... // so, let's better queue it for next frame if(!sdl_needs_restart) { - Cbuf_AddText("\nr_restart\n"); + Cbuf_AddText(&cmd_client, "\nr_restart\n"); sdl_needs_restart = true; } #endif @@ -1285,112 +1304,6 @@ void Sys_SendKeyEvents( void ) // Video system //// -#ifdef USE_GLES2 - -void GLES_Init(void) -{ - gl_renderer = (const char *)qglGetString(GL_RENDERER); - gl_vendor = (const char *)qglGetString(GL_VENDOR); - gl_version = (const char *)qglGetString(GL_VERSION); - gl_extensions = (const char *)qglGetString(GL_EXTENSIONS); - - if (!gl_extensions) - gl_extensions = ""; - if (!gl_platformextensions) - gl_platformextensions = ""; - - Con_Printf("GL_VENDOR: %s\n", gl_vendor); - Con_Printf("GL_RENDERER: %s\n", gl_renderer); - Con_Printf("GL_VERSION: %s\n", gl_version); - Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions); - Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions); - - // LordHavoc: report supported extensions - Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions ); - - // GLES devices in general do not like GL_BGRA, so use GL_RGBA - vid.forcetextype = TEXTYPE_RGBA; - - vid.support.amd_texture_texture4 = false; - vid.support.arb_draw_buffers = false; - vid.support.arb_occlusion_query = false; - vid.support.arb_query_buffer_object = false; - vid.support.arb_texture_compression = false; // different (vendor-specific) formats than on desktop OpenGL... - vid.support.arb_texture_gather = false; - vid.support.ext_blend_minmax = false; - vid.support.ext_blend_subtract = true; // GLES2 core - vid.support.ext_blend_func_separate = true; // GLES2 core - - vid.support.ext_packed_depth_stencil = false; - vid.support.ext_texture_compression_s3tc = SDL_GL_ExtensionSupported("GL_EXT_texture_compression_s3tc") != 0; - vid.support.ext_texture_filter_anisotropic = false; // probably don't want to use it... - vid.support.ext_texture_srgb = false; - vid.support.arb_texture_float = SDL_GL_ExtensionSupported("GL_OES_texture_float") != 0; - vid.support.arb_half_float_pixel = SDL_GL_ExtensionSupported("GL_OES_texture_half_float") != 0; - vid.support.arb_half_float_vertex = SDL_GL_ExtensionSupported("GL_OES_vertex_half_float") != 0; - - // NOTE: On some devices, a value of 512 gives better FPS than the maximum. - qglGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_2d); - -#ifdef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT - if (vid.support.ext_texture_filter_anisotropic) - qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint*)&vid.max_anisotropy); -#endif - if (vid.support.arb_texture_cube_map) - qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_cubemap); -#ifdef GL_MAX_3D_TEXTURE_SIZE - if (vid.support.ext_texture_3d) - qglGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_3d); -#endif - Con_Printf("GL_MAX_CUBE_MAP_TEXTURE_SIZE = %i\n", vid.maxtexturesize_cubemap); - Con_Printf("GL_MAX_3D_TEXTURE_SIZE = %i\n", vid.maxtexturesize_3d); - { -#define GL_ALPHA_BITS 0x0D55 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_DEPTH_BITS 0x0D56 -#define GL_STENCIL_BITS 0x0D57 - int fb_r = -1, fb_g = -1, fb_b = -1, fb_a = -1, fb_d = -1, fb_s = -1; - qglGetIntegerv(GL_RED_BITS , &fb_r); - qglGetIntegerv(GL_GREEN_BITS , &fb_g); - qglGetIntegerv(GL_BLUE_BITS , &fb_b); - qglGetIntegerv(GL_ALPHA_BITS , &fb_a); - qglGetIntegerv(GL_DEPTH_BITS , &fb_d); - qglGetIntegerv(GL_STENCIL_BITS, &fb_s); - Con_Printf("Framebuffer depth is R%iG%iB%iA%iD%iS%i\n", fb_r, fb_g, fb_b, fb_a, fb_d, fb_s); - } - - // verify that cubemap textures are really supported - if (vid.support.arb_texture_cube_map && vid.maxtexturesize_cubemap < 256) - vid.support.arb_texture_cube_map = false; - - // verify that 3d textures are really supported - if (vid.support.ext_texture_3d && vid.maxtexturesize_3d < 32) - { - vid.support.ext_texture_3d = false; - Con_Printf("GL_OES_texture_3d reported bogus GL_MAX_3D_TEXTURE_SIZE, disabled\n"); - } - - Con_DPrint("Using GLES2 rendering path\n"); - vid.renderpath = RENDERPATH_GLES2; - vid.sRGBcapable2D = false; - vid.sRGBcapable3D = false; - - // VorteX: set other info (maybe place them in VID_InitMode?) - 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; - 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); -} -#endif - void *GL_GetProcAddress(const char *name) { void *p = NULL; @@ -1398,6 +1311,11 @@ void *GL_GetProcAddress(const char *name) return p; } +qboolean GL_ExtensionSupported(const char *name) +{ + return SDL_GL_ExtensionSupported(name); +} + static qboolean vid_sdl_initjoysticksystem = false; void VID_Init (void) @@ -1410,6 +1328,7 @@ void VID_Init (void) #ifdef DP_MOBILETOUCH Cvar_SetValueQuick(&vid_touchscreen, 1); #endif + Cvar_RegisterVariable(&joy_sdl2_trigger_deadzone); #ifdef SDL_R_RESTART R_RegisterModule("SDL", sdl_start, sdl_shutdown, sdl_newmap, NULL, NULL); @@ -1418,8 +1337,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) - Con_Printf("Failed to init SDL joystick subsystem: %s\n", SDL_GetError()); + if (!vid_sdl_initjoysticksystem) + Con_Errorf("Failed to init SDL joystick subsystem: %s\n", SDL_GetError()); vid_isfullscreen = false; } @@ -1449,19 +1368,31 @@ void VID_EnableJoystick(qboolean enable) vid_sdljoystickindex = sdlindex; // close SDL joystick if active if (vid_sdljoystick) + { SDL_JoystickClose(vid_sdljoystick); - vid_sdljoystick = NULL; + vid_sdljoystick = NULL; + } + if (vid_sdlgamecontroller) + { + SDL_GameControllerClose(vid_sdlgamecontroller); + vid_sdlgamecontroller = NULL; + } if (sdlindex >= 0) { vid_sdljoystick = SDL_JoystickOpen(sdlindex); if (vid_sdljoystick) { const char *joystickname = SDL_JoystickName(vid_sdljoystick); + if (SDL_IsGameController(vid_sdljoystickindex)) + { + vid_sdlgamecontroller = SDL_GameControllerOpen(vid_sdljoystickindex); + Con_DPrintf("Using SDL GameController mappings for Joystick %i\n", index); + } Con_Printf("Joystick %i opened (SDL_Joystick %i is \"%s\" with %i axes, %i buttons, %i balls)\n", index, sdlindex, joystickname, (int)SDL_JoystickNumAxes(vid_sdljoystick), (int)SDL_JoystickNumButtons(vid_sdljoystick), (int)SDL_JoystickNumBalls(vid_sdljoystick)); } else { - Con_Printf("Joystick %i failed (SDL_JoystickOpen(%i) returned: %s)\n", index, sdlindex, SDL_GetError()); + Con_Errorf("Joystick %i failed (SDL_JoystickOpen(%i) returned: %s)\n", index, sdlindex, SDL_GetError()); sdlindex = -1; } } @@ -1487,6 +1418,11 @@ static void VID_OutputVersion(void) #ifdef WIN32 static void AdjustWindowBounds(viddef_mode_t *mode, RECT *rect) { + int workWidth; + int workHeight; + int titleBarPixels = 2; + int screenHeight; + RECT workArea; LONG width = mode->width; // vid_width LONG height = mode->height; // vid_height @@ -1497,16 +1433,14 @@ static void AdjustWindowBounds(viddef_mode_t *mode, RECT *rect) rect->bottom = height; AdjustWindowRectEx(rect, WS_CAPTION|WS_THICKFRAME, false, 0); - RECT workArea; SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0); - int workWidth = workArea.right - workArea.left; - int workHeight = workArea.bottom - workArea.top; + workWidth = workArea.right - workArea.left; + workHeight = workArea.bottom - workArea.top; // SDL forces the window height to be <= screen height - 27px (on Win8.1 - probably intended for the title bar) // If the task bar is docked to the the left screen border and we move the window to negative y, // there would be some part of the regular desktop visible on the bottom of the screen. - int titleBarPixels = 2; - int screenHeight = GetSystemMetrics(SM_CYSCREEN); + screenHeight = GetSystemMetrics(SM_CYSCREEN); if (screenHeight == workHeight) titleBarPixels = -rect->top; @@ -1528,9 +1462,17 @@ 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 qboolean VID_InitModeGL(viddef_mode_t *mode) { int windowflags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; + // currently SDL_WINDOWPOS_UNDEFINED behaves exactly like SDL_WINDOWPOS_CENTERED, this might change some day + // https://trello.com/c/j56vUcwZ/81-centered-vs-undefined-window-position int xPos = SDL_WINDOWPOS_UNDEFINED; int yPos = SDL_WINDOWPOS_UNDEFINED; #ifndef USE_GLES2 @@ -1556,7 +1498,7 @@ static qboolean VID_InitModeGL(viddef_mode_t *mode) drivername = com_argv[i + 1]; if (SDL_GL_LoadLibrary(drivername) < 0) { - Con_Printf("Unable to load GL driver \"%s\": %s\n", drivername, SDL_GetError()); + Con_Errorf("Unable to load GL driver \"%s\": %s\n", drivername, SDL_GetError()); return false; } #endif @@ -1567,16 +1509,6 @@ static qboolean VID_InitModeGL(viddef_mode_t *mode) // hide the menu with SDL_WINDOW_BORDERLESS windowflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS; #endif -#ifndef USE_GLES2 - if ((qglGetString = (const GLubyte* (GLAPIENTRY *)(GLenum name))GL_GetProcAddress("glGetString")) == NULL) - { - VID_Shutdown(); - Con_Print("Required OpenGL function glGetString not found\n"); - return false; - } -#endif - - // Knghtbrd: should do platform-specific extension string function here vid_isfullscreen = false; { @@ -1593,16 +1525,27 @@ static qboolean VID_InitModeGL(viddef_mode_t *mode) vid_isfullscreen = true; } else { + if (vid_borderless.integer) + windowflags |= SDL_WINDOW_BORDERLESS; #ifdef WIN32 - RECT rect; - AdjustWindowBounds(mode, &rect); - xPos = rect.left; - yPos = rect.top; + 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) + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); + SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8); @@ -1619,19 +1562,23 @@ static qboolean VID_InitModeGL(viddef_mode_t *mode) } #ifdef USE_GLES2 + SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0); - SDL_GL_SetAttribute (SDL_GL_RETAINED_BACKING, 1); #else - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, (gl_debug.integer > 0 ? SDL_GL_CONTEXT_DEBUG_FLAG : 0)); + 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); #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) { - Con_Printf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError()); + Con_Errorf("Failed to set video mode to %ix%i: %s\n", mode->width, mode->height, SDL_GetError()); VID_Shutdown(); return false; } @@ -1639,7 +1586,7 @@ static qboolean VID_InitModeGL(viddef_mode_t *mode) context = SDL_GL_CreateContext(window); if (context == NULL) { - Con_Printf("Failed to initialize OpenGL context: %s\n", SDL_GetError()); + Con_Errorf("Failed to initialize OpenGL context: %s\n", SDL_GetError()); VID_Shutdown(); return false; } @@ -1648,14 +1595,26 @@ static qboolean VID_InitModeGL(viddef_mode_t *mode) vid_usingvsync = (vid_vsync.integer != 0); gl_platform = "SDL"; - gl_platformextensions = ""; -#ifdef USE_GLES2 - GLES_Init(); + GL_Setup(); + + // VorteX: set other info + 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 +#ifdef CONFIG_MENU + Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions); #else - GL_Init(); + Con_DPrintf("\nQuakeC extensions for server and client: %s\n", vm_sv_extensions); #endif + // clear to black (loading plaque will be seen over this) + GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 0); + vid_hidden = false; vid_activewindow = false; vid_hasfocus = true; @@ -1675,8 +1634,8 @@ extern cvar_t gl_info_driver; qboolean VID_InitMode(viddef_mode_t *mode) { // GAME_STEELSTORM specific - steelstorm_showing_map = Cvar_FindVar("steelstorm_showing_map"); - steelstorm_showing_mousecursor = Cvar_FindVar("steelstorm_showing_mousecursor"); + steelstorm_showing_map = Cvar_FindVar(&cvars_all, "steelstorm_showing_map", ~0); + steelstorm_showing_mousecursor = Cvar_FindVar(&cvars_all, "steelstorm_showing_mousecursor", ~0); if (!SDL_WasInit(SDL_INIT_VIDEO) && SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) Sys_Error ("Failed to init SDL video subsystem: %s", SDL_GetError()); @@ -1698,7 +1657,6 @@ void VID_Shutdown (void) gl_driver[0] = 0; gl_extensions = ""; gl_platform = ""; - gl_platformextensions = ""; } void VID_Finish (void)