diff --git a/Source/i_video.c b/Source/i_video.c index a2ab073a..e23483aa 100644 --- a/Source/i_video.c +++ b/Source/i_video.c @@ -42,6 +42,7 @@ #include "m_menu.h" #include "wi_stuff.h" #include "i_video.h" +#include "m_misc2.h" // [FG] set the application icon @@ -61,8 +62,9 @@ static SDL_Surface *argbbuffer; static SDL_Texture *texture; static SDL_Rect blit_rect = {0}; -// [FG] window size when returning from fullscreen mode -static int window_width, window_height; +int window_width, window_height; +char *window_position; +int video_display = 0; ///////////////////////////////////////////////////////////////////////////// // @@ -462,6 +464,8 @@ static void I_HandleKeyboardEvent(SDL_Event *sdlevent) static void HandleWindowEvent(SDL_WindowEvent *event) { + int i; + switch (event->event) { case SDL_WINDOWEVENT_RESIZED: @@ -496,6 +500,19 @@ static void HandleWindowEvent(SDL_WindowEvent *event) window_focused = false; break; + // We want to save the user's preferred monitor to use for running the + // game, so that next time we're run we start on the same display. So + // every time the window is moved, find which display we're now on and + // update the video_display config variable. + + case SDL_WINDOWEVENT_MOVED: + i = SDL_GetWindowDisplayIndex(screen); + if (i >= 0) + { + video_display = i; + } + break; + default: break; } @@ -888,7 +905,22 @@ void I_ShutdownGraphics(void) { if(in_graphics_mode) // killough 10/98 { - UpdateGrab(); + int x, y; + char buf[16]; + int buflen; + + // Store the (x, y) coordinates of the window + // in the "window_position" config parameter + SDL_GetWindowPosition(screen, &x, &y); + M_snprintf(buf, sizeof(buf), "%i,%i", x, y); + buflen = strlen(buf); + if (strlen(window_position) < buflen) + { + window_position = realloc(window_position, buflen); + } + M_StringCopy(window_position, buf, sizeof(window_position)); + + UpdateGrab(); in_graphics_mode = false; } } @@ -979,6 +1011,68 @@ int cfg_aspectratio; // haleyjd 05/11/09: aspect ratio correction // haleyjd 05/11/09: true if called from I_ResetScreen static boolean changeres = false; +// Check the display bounds of the display referred to by 'video_display' and +// set x and y to a location that places the window in the center of that +// display. +static void CenterWindow(int *x, int *y, int w, int h) +{ + SDL_Rect bounds; + + if (SDL_GetDisplayBounds(video_display, &bounds) < 0) + { + fprintf(stderr, "CenterWindow: Failed to read display bounds " + "for display #%d!\n", video_display); + return; + } + + *x = bounds.x + SDL_max((bounds.w - w) / 2, 0); + *y = bounds.y + SDL_max((bounds.h - h) / 2, 0); +} + +static void I_GetWindowPosition(int *x, int *y, int w, int h) +{ + // Check that video_display corresponds to a display that really exists, + // and if it doesn't, reset it. + if (video_display < 0 || video_display >= SDL_GetNumVideoDisplays()) + { + fprintf(stderr, + "I_GetWindowPosition: We were configured to run on display #%d, " + "but it no longer exists (max %d). Moving to display 0.\n", + video_display, SDL_GetNumVideoDisplays() - 1); + video_display = 0; + } + + // in fullscreen mode, the window "position" still matters, because + // we use it to control which display we run fullscreen on. + + if (fullscreen) + { + CenterWindow(x, y, w, h); + return; + } + + // in windowed mode, the desired window position can be specified + // in the configuration file. + + if (window_position == NULL || !strcmp(window_position, "")) + { + *x = *y = SDL_WINDOWPOS_UNDEFINED; + } + else if (!strcmp(window_position, "center")) + { + // Note: SDL has a SDL_WINDOWPOS_CENTER, but this is useless for our + // purposes, since we also want to control which display we appear on. + // So we have to do this ourselves. + CenterWindow(x, y, w, h); + } + else if (sscanf(window_position, "%i,%i", x, y) != 2) + { + // invalid format: revert to default + fprintf(stderr, "I_GetWindowPosition: invalid window_position setting\n"); + *x = *y = SDL_WINDOWPOS_UNDEFINED; + } +} + // [crispy] re-calculate SCREENWIDTH, SCREENHEIGHT, NONWIDEWIDTH and WIDESCREENDELTA void I_GetScreenDimensions(void) { @@ -993,7 +1087,7 @@ void I_GetScreenDimensions(void) ah = useaspect ? (6 * SCREENHEIGHT / 5) : SCREENHEIGHT; - if (SDL_GetCurrentDisplayMode(0/*video_display*/, &mode) == 0) + if (SDL_GetCurrentDisplayMode(video_display, &mode) == 0) { // [crispy] sanity check: really widescreen display? if (mode.w * ah >= mode.h * SCREENWIDTH) @@ -1046,13 +1140,14 @@ static void I_InitGraphicsMode(void) // haleyjd int v_w = ORIGWIDTH; int v_h = ORIGHEIGHT; + int v_x = 0; + int v_y = 0; int flags = 0; int scalefactor = cfg_scalefactor; int usehires = hires; // [FG] SDL2 uint32_t pixel_format; - int video_display; SDL_DisplayMode mode; if(firsttime) @@ -1066,26 +1161,6 @@ static void I_InitGraphicsMode(void) usehires = hires = false; // grrr... } - useaspect = cfg_aspectratio; - if(M_CheckParm("-aspect")) - useaspect = true; - - I_GetScreenDimensions(); - - if(usehires) - { - v_w = SCREENWIDTH*2; - v_h = SCREENHEIGHT*2; - } - else - { - v_w = SCREENWIDTH; - v_h = SCREENHEIGHT; - } - - blit_rect.w = v_w; - blit_rect.h = v_h; - // haleyjd 10/09/05: from Chocolate DOOM // mouse grabbing if(M_CheckParm("-grabmouse")) @@ -1121,16 +1196,20 @@ static void I_InitGraphicsMode(void) else if(M_CheckParm("-5")) scalefactor = 5; - actualheight = useaspect ? (6 * v_h / 5) : v_h; + useaspect = cfg_aspectratio; + if(M_CheckParm("-aspect")) + useaspect = true; + + I_GetWindowPosition(&v_x, &v_y, window_width, window_height); // [FG] create rendering window - if (screen == NULL) { screen = SDL_CreateWindow(NULL, // centered window - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - v_w, v_h, flags); + //SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + v_x, v_y, + window_width, window_height, flags); if (screen == NULL) { @@ -1142,10 +1221,30 @@ static void I_InitGraphicsMode(void) I_InitWindowIcon(); } + video_display = SDL_GetWindowDisplayIndex(screen); + + I_GetScreenDimensions(); + + if(usehires) + { + v_w = SCREENWIDTH*2; + v_h = SCREENHEIGHT*2; + } + else + { + v_w = SCREENWIDTH; + v_h = SCREENHEIGHT; + } + + blit_rect.w = v_w; + blit_rect.h = v_h; + + actualheight = useaspect ? (6 * v_h / 5) : v_h; + SDL_SetWindowMinimumSize(screen, v_w, actualheight); // [FG] window size when returning from fullscreen mode - if (!window_width || !window_height) + if (scalefactor * v_w > window_width) { window_width = scalefactor * v_w; window_height = scalefactor * actualheight; @@ -1157,7 +1256,6 @@ static void I_InitGraphicsMode(void) } pixel_format = SDL_GetWindowPixelFormat(screen); - video_display = SDL_GetWindowDisplayIndex(screen); // [FG] renderer flags flags = 0; diff --git a/Source/i_video.h b/Source/i_video.h index c1374589..46317007 100644 --- a/Source/i_video.h +++ b/Source/i_video.h @@ -75,6 +75,10 @@ extern int hires; // killough 11/98 extern int uncapped; // [FG] uncapped rendering frame rate extern int integer_scaling; // [FG] force integer scales extern int widescreen; // widescreen mode +extern int video_display; // display index +extern int window_width, window_height; +extern char *window_position; + boolean I_WritePNGfile(char *filename); // [FG] screenshots in PNG format #endif diff --git a/Source/m_misc.c b/Source/m_misc.c index e952a906..6c844be6 100644 --- a/Source/m_misc.c +++ b/Source/m_misc.c @@ -1874,6 +1874,38 @@ default_t defaults[] = { "1 to enable widescreen mode" }, + // display index + { + "video_display", + (config_t *) &video_display, NULL, + {0}, {0, UL}, number, ss_none, wad_no, + "current video display index" + }, + + // window position + { + "window_position", + (config_t *) &window_position, NULL, + {.s = "center"}, {0}, string, ss_none, wad_no, + "window position \"x,y\"" + }, + + // window width + { + "window_width", + (config_t *) &window_width, NULL, + {640}, {0, UL}, number, ss_none, wad_no, + "window width" + }, + + // window height + { + "window_height", + (config_t *) &window_height, NULL, + {480}, {0, UL}, number, ss_none, wad_no, + "window height" + }, + {NULL} // last entry };