diff --git a/src/dedicated/i_video.c b/src/dedicated/i_video.c index 72fe0cdd50c324f783cd22f67254feca262bbb23..850eef60e97237b60f7c6b7d7366492a80f84f94 100644 --- a/src/dedicated/i_video.c +++ b/src/dedicated/i_video.c @@ -1,6 +1,7 @@ #include "../doomdef.h" #include "../command.h" #include "../i_video.h" +#include "../screen.h" rendermode_t rendermode = render_none; rendermode_t chosenrendermode = render_none; @@ -57,8 +58,21 @@ void VID_SetSize(INT32 width, INT32 height) (void)height; } +resolution_t *VID_GetSupportedResolutions(INT32 *count) +{ + *count = 0; + return NULL; +} + boolean VID_IsMaximized(void) { return false; } void VID_RestoreWindow(void){} + +boolean SCR_IsValidResolution(INT32 width, INT32 height) +{ + (void)width; + (void)height; + return false; +} diff --git a/src/f_finale.c b/src/f_finale.c index 31c68be736f658d90792691adf69860bac53372a..c4973a1ae6a42a14055af3a61999aea40c67c169 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2638,10 +2638,13 @@ static void F_FigureActiveTtScale(void) break; } - for (; newttscale <= 6; newttscale++) + if (newttscale < 1) { - if (ttavailable[newttscale-1]) - break; + for (newttscale++; newttscale <= 6; newttscale++) + { + if (ttavailable[newttscale-1]) + break; + } } activettscale = (newttscale >= 1 && newttscale <= 6) ? newttscale : 0; diff --git a/src/i_video.h b/src/i_video.h index 0cbdd8447a6e897c3c58320ea3ae82a33485037e..847faf2913f5b6435eed98373efbb0d8bc06301d 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -32,6 +32,13 @@ typedef enum render_none = 3 // for dedicated server } rendermode_t; +typedef struct +{ + UINT16 width; + UINT16 height; + UINT8 index; +} resolution_t; + /** \brief current render mode */ extern rendermode_t rendermode; @@ -85,6 +92,10 @@ void VID_RestoreWindow(void); */ boolean VID_GetNativeResolution(INT32 *width, INT32 *height); +/** \brief List resolutions that the current display supports +*/ +resolution_t *VID_GetSupportedResolutions(INT32 *count); + /** \brief can video system do fullscreen */ extern boolean allow_fullscreen; diff --git a/src/m_menu.c b/src/m_menu.c index cd23ef77bd5c1798b4a7721774014f79e3e0655f..4a608b3c804777564cce4743ad2c6a0ca407e8f9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -13811,18 +13811,20 @@ static modedesc_t modedescs[MAXMODEDESCS]; static void M_VideoModeMenu(INT32 choice) { (void)choice; + INT32 count; + resolution_t *res = VID_GetSupportedResolutions(&count); memset(modedescs, 0, sizeof(modedescs)); vidm_nummodes = 0; vidm_selected = -1; - for (INT32 i = 0; i < MAXWINMODES && vidm_nummodes < MAXMODEDESCS; i++) + for (INT32 i = 0; i < count; i++) { modedesc_t *desc = &modedescs[vidm_nummodes]; - INT32 width = windowedModes[i][0]; - INT32 height = windowedModes[i][1]; + INT32 width = res[i].width; + INT32 height = res[i].height; desc->width = width; desc->height = height; diff --git a/src/r_draw8.c b/src/r_draw8.c index 7ebfefa432af6ef34e23226d16c365a63b4b03af..349139f5e4a7700f35e93b304cbf71cbc25776e9 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -25,9 +25,9 @@ void R_DrawColumn_8(void) { INT32 count; - register UINT8 *dest; - register fixed_t frac; - fixed_t fracstep; + UINT8 *restrict dest; + intptr_t frac; + intptr_t fracstep; count = dc_yh - dc_yl; @@ -51,9 +51,9 @@ void R_DrawColumn_8(void) // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register const UINT8 *source = dc_source; - register const lighttable_t *colormap = dc_colormap; - register INT32 heightmask = dc_texheight-1; + const UINT8 *restrict source = dc_source; + const lighttable_t *restrict colormap = dc_colormap; + intptr_t heightmask = dc_texheight-1; if (dc_texheight & heightmask) // not a power of 2 -- killough { heightmask++; @@ -62,8 +62,7 @@ void R_DrawColumn_8(void) if (frac < 0) while ((frac += heightmask) < 0); else - while (frac >= heightmask) - frac -= heightmask; + frac %= heightmask; do { @@ -73,14 +72,15 @@ void R_DrawColumn_8(void) *dest = colormap[source[frac>>FRACBITS]]; dest += vid.width; +#if __SIZEOF_POINTER__ < 8 // 64-bit systems have large enough numbers for this to be a non-issue // Avoid overflow. if (fracstep > 0x7FFFFFFF - frac) frac += fracstep - heightmask; else +#endif frac += fracstep; - while (frac >= heightmask) - frac -= heightmask; + frac %= heightmask; } while (--count); } else @@ -106,9 +106,9 @@ void R_DrawColumn_8(void) void R_DrawColumnClamped_8(void) { INT32 count; - UINT8 *dest; - fixed_t frac; - fixed_t fracstep; + UINT8 *restrict dest; + intptr_t frac; + intptr_t fracstep; count = dc_yh - dc_yl; @@ -132,10 +132,10 @@ void R_DrawColumnClamped_8(void) // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - const UINT8 *source = dc_source; - const lighttable_t *colormap = dc_colormap; - INT32 heightmask = dc_texheight-1; - INT32 idx; + const UINT8 *restrict source = dc_source; + const lighttable_t *restrict colormap = dc_colormap; + intptr_t heightmask = dc_texheight-1; + intptr_t idx; if (dc_texheight & heightmask) // not a power of 2 -- killough { heightmask++; @@ -158,13 +158,14 @@ void R_DrawColumnClamped_8(void) dest += vid.width; // Avoid overflow. +#if __SIZEOF_POINTER__ < 8 if (fracstep > 0x7FFFFFFF - frac) frac += fracstep - heightmask; else +#endif frac += fracstep; - while (frac >= heightmask) - frac -= heightmask; + frac %= heightmask; } while (--count); } else @@ -195,9 +196,9 @@ void R_DrawColumnClamped_8(void) void R_Draw2sMultiPatchColumn_8(void) { INT32 count; - register UINT8 *dest; - register fixed_t frac; - fixed_t fracstep; + UINT8 *restrict dest; + intptr_t frac; + intptr_t fracstep; count = dc_yh - dc_yl; @@ -221,10 +222,10 @@ void R_Draw2sMultiPatchColumn_8(void) // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register const UINT8 *source = dc_source; - register const lighttable_t *colormap = dc_colormap; - register INT32 heightmask = dc_texheight-1; - register UINT8 val; + const UINT8 *restrict source = dc_source; + const lighttable_t *restrict colormap = dc_colormap; + intptr_t heightmask = dc_texheight-1; + UINT8 val; if (dc_texheight & heightmask) // not a power of 2 -- killough { heightmask++; @@ -233,8 +234,7 @@ void R_Draw2sMultiPatchColumn_8(void) if (frac < 0) while ((frac += heightmask) < 0); else - while (frac >= heightmask) - frac -= heightmask; + frac %= heightmask; do { @@ -249,13 +249,14 @@ void R_Draw2sMultiPatchColumn_8(void) dest += vid.width; // Avoid overflow. +#if __SIZEOF_POINTER__ < 8 if (fracstep > 0x7FFFFFFF - frac) frac += fracstep - heightmask; else +#endif frac += fracstep; - while (frac >= heightmask) - frac -= heightmask; + frac %= heightmask; } while (--count); } else @@ -726,14 +727,14 @@ void R_DrawTranslatedColumn_8(void) */ void R_DrawSpan_8 (void) { - fixed_t xposition; - fixed_t yposition; - fixed_t xstep, ystep; - - UINT8 *source; - UINT8 *colormap; - UINT8 *dest; - const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; + uintptr_t xposition; + uintptr_t yposition; + uintptr_t xstep, ystep; + + UINT8 *restrict source; + UINT8 *restrict colormap; + UINT8 *restrict dest; + const UINT8 *restrict deststop = screens[0] + vid.rowbytes * vid.height; size_t count = (ds_x2 - ds_x1 + 1); diff --git a/src/r_segs.c b/src/r_segs.c index bee349492e5b827f06820301e90cf5c6c3149585..5fdfdf271e6047f648c48a42e4b3a77d7b2dfc6c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1464,7 +1464,7 @@ static void R_RenderSegLoop (void) // calculate texture offset angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; textureoffset = rw_offset - FixedMul(FINETANGENT(angle & TANMASK), rw_distance); - texturecolumn = FixedDiv(textureoffset, rw_invmidtexturescalex); + texturecolumn = FixedMul(textureoffset, rw_midtexturescalex); // texturecolumn and lighting are independent of wall tiers if (segtextured) @@ -1564,7 +1564,7 @@ static void R_RenderSegLoop (void) if (mid >= floorclip[rw_x]) mid = floorclip[rw_x]-1; - toptexturecolumn = FixedDiv(textureoffset, rw_invtoptexturescalex); + toptexturecolumn = FixedMul(textureoffset, rw_toptexturescalex); if (mid >= yl) // back ceiling lower than front ceiling ? { @@ -1611,7 +1611,7 @@ static void R_RenderSegLoop (void) if (mid <= ceilingclip[rw_x]) mid = ceilingclip[rw_x]+1; - bottomtexturecolumn = FixedDiv(textureoffset, rw_invbottomtexturescalex); + bottomtexturecolumn = FixedMul(textureoffset, rw_bottomtexturescalex); if (mid <= yh) // back floor higher than front floor ? { diff --git a/src/r_things.c b/src/r_things.c index 7c096519fdeb461945d3e1a395d0f6a94d0f765a..6b1c531ae2d215df3f4df4bb5b5b1975729d2ad5 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1234,7 +1234,7 @@ static void R_DrawVisSprite(vissprite_t *vis) #endif // Non-paper drawing loop - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan) + for (dc_x = vis->x1; dc_x <= vis->x2 && (frac>>FRACBITS) < patch->width; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan) { column = &patch->columns[frac>>FRACBITS]; localcolfunc (column, lengthcol); diff --git a/src/screen.c b/src/screen.c index fff97dca7e54f7d834afc3ebe93ef9a9c37188f2..8978ed47f6f5a99490c96ce2c96ec65f4a9f254d 100644 --- a/src/screen.c +++ b/src/screen.c @@ -61,29 +61,6 @@ void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void); // ------------------ viddef_t vid; -// windowed video modes from which to choose from. -INT32 windowedModes[MAXWINMODES][2] = -{ - {1920,1200}, // 1.60,6.00 - {1920,1080}, // 1.66 - {1680,1050}, // 1.60,5.25 - {1600,1200}, // 1.33 - {1600, 900}, // 1.66 - {1366, 768}, // 1.66 - {1440, 900}, // 1.60,4.50 - {1280,1024}, // 1.33? - {1280, 960}, // 1.33,4.00 - {1280, 800}, // 1.60,4.00 - {1280, 720}, // 1.66 - {1152, 864}, // 1.33,3.60 - {1024, 768}, // 1.33,3.20 - { 800, 600}, // 1.33,2.50 - { 640, 480}, // 1.33,2.00 - { 640, 400}, // 1.60,2.00 - { 320, 240}, // 1.33,1.00 - { 320, 200}, // 1.60,1.00 -}; - static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}}; //added : 03-02-98: default screen mode, as loaded/saved in config @@ -267,15 +244,6 @@ void SCR_Recalc(void) #endif } -boolean SCR_IsValidResolution(INT32 width, INT32 height) -{ - if (width < BASEVIDWIDTH || width > MAXVIDWIDTH) - return false; - if (height < BASEVIDHEIGHT || height > MAXVIDHEIGHT) - return false; - return true; -} - static boolean SCR_SetSize(INT32 width, INT32 height) { if (SCR_IsValidResolution(width, height)) @@ -362,9 +330,9 @@ void SCR_CheckDefaultMode(void) if (!SCR_IsValidResolution(width, height)) { - CONS_Alert(CONS_WARNING, "Invalid resolution given, defaulting to base resolution\n"); - width = BASEVIDWIDTH; - height = BASEVIDHEIGHT; + CONS_Alert(CONS_WARNING, "Invalid resolution given, defaulting to a safe resolution\n"); + width = 800; + height = 600; } SCR_ChangeResolution(width, height); @@ -463,33 +431,6 @@ boolean SCR_IsAspectCorrect(INT32 width, INT32 height) ); } -const char *SCR_GetModeName(INT32 modeNum) -{ - static char vidModeName[MAXWINMODES][32]; - - if (modeNum == -1) - return "Fallback"; - else if (modeNum > MAXWINMODES) - return NULL; - - snprintf(&vidModeName[modeNum][0], 32, "%dx%d", windowedModes[modeNum][0], windowedModes[modeNum][1]); - - return &vidModeName[modeNum][0]; -} - -INT32 SCR_GetModeForSize(INT32 w, INT32 h) -{ - int i; - for (i = 0; i < MAXWINMODES; i++) - { - if (windowedModes[i][0] == w && windowedModes[i][1] == h) - { - return i; - } - } - return -1; -} - // XMOD FPS display // moved out of os-specific code for consistency static boolean ticsgraph[TICRATE]; diff --git a/src/screen.h b/src/screen.h index 2a9767dbd30aa62640df72a5be7fea4e6f0c647c..5cb53e0779ca68b590d56be780cd8e87a97cbe48 100644 --- a/src/screen.h +++ b/src/screen.h @@ -85,10 +85,6 @@ enum VID_GL_LIBRARY_ERROR }; -#define MAXWINMODES 18 - -extern INT32 windowedModes[MAXWINMODES][2]; - // --------------------------------------------- // color mode dependent drawer function pointers // --------------------------------------------- @@ -164,9 +160,6 @@ void SCR_SetWindowSize(INT32 width, INT32 height); void SCR_SetSizeNoRestore(INT32 width, INT32 height); void SCR_ChangeRenderer(void); -const char *SCR_GetModeName(INT32 modeNum); -INT32 SCR_GetModeForSize(INT32 w, INT32 h); - boolean SCR_IsValidResolution(INT32 width, INT32 height); extern CV_PossibleValue_t cv_renderer_t[]; diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index d745eec8d3953a3ade4906b6791623e469526203..b8d7d88140bf00795d97919574812561b625dc1e 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -70,6 +70,7 @@ #include "../st_stuff.h" #include "../hu_stuff.h" #include "../g_game.h" +#include "../z_zone.h" #include "../i_video.h" #include "../console.h" #include "../command.h" @@ -115,21 +116,14 @@ static SDL_bool disable_mouse = SDL_FALSE; static INT32 mousemovex = 0, mousemovey = 0; // SDL vars -static SDL_Surface *vidSurface = NULL; -static SDL_Surface *bufSurface = NULL; -static SDL_Color localPalette[256]; +static UINT32 softPalette[256]; static SDL_bool mousegrabok = SDL_TRUE; static SDL_bool wrapmouseok = SDL_FALSE; #define HalfWarpMouse(x,y) if (wrapmouseok) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2)) -static SDL_bool usesdl2soft = SDL_FALSE; static SDL_bool borderlesswindow = SDL_FALSE; -Uint16 realwidth = BASEVIDWIDTH; -Uint16 realheight = BASEVIDHEIGHT; - SDL_Window *window; SDL_Renderer *renderer; -static SDL_Texture *texture; static SDL_bool havefocus = SDL_TRUE; static UINT32 refresh_rate; @@ -138,9 +132,6 @@ static boolean video_init = false; static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); -static void Impl_VideoSetupSurfaces(int width, int height); -static void Impl_VideoSetupBuffer(void); - static void Impl_SetupSoftwareBuffer(void); static void Impl_InitOpenGL(void); @@ -167,32 +158,8 @@ static SDL_bool Impl_RenderContextCreate(void) { if (rendermode != render_opengl) { - int flags = 0; // Use this to set SDL_RENDERER_* flags now - - if (usesdl2soft) - flags |= SDL_RENDERER_SOFTWARE; - else if (cv_vidwait.value) - { -#if SDL_VERSION_ATLEAST(2, 0, 18) - // If SDL is new enough, we can turn off vsync later. - flags |= SDL_RENDERER_PRESENTVSYNC; -#else - // However, if it isn't, we should just silently turn vid_wait off - // This is because the renderer will be created before the config - // is read and vid_wait is set from the user's preferences, and thus - // vid_wait will have no effect. - CV_StealthSetValue(&cv_vidwait, 0); -#endif - } - - if (!renderer) - renderer = SDL_CreateRenderer(window, -1, flags); - - if (renderer == NULL) - { - VIDEO_INIT_ERROR("Couldn't create rendering context: %s"); - return SDL_FALSE; - } + // we do rasterization ourselves, so nothing to do + return SDL_TRUE; } #ifdef HWRENDER @@ -216,79 +183,23 @@ static SDL_bool Impl_RenderContextCreate(void) static SDL_bool Impl_RenderContextReset(void) { - if (renderer) - { - SDL_DestroyRenderer(renderer); - texture = NULL; // Destroying a renderer also destroys all of its textures - } - renderer = NULL; - if (Impl_RenderContextCreate() == SDL_FALSE) return SDL_FALSE; - if (vidSurface != NULL) - { - SDL_FreeSurface(vidSurface); - vidSurface = NULL; - } - - if (bufSurface != NULL) - { - SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - #ifdef HWRENDER if (rendermode == render_opengl) { SDL_GL_MakeCurrent(window, sdlglcontext); SDL_GL_SetSwapInterval(cv_vidwait.value ? 1 : 0); - OglSdlSurface(realwidth, realheight); + OglSdlSurface(vid.width, vid.height); HWR_Startup(); } - else #endif - { - SDL_RenderClear(renderer); - SDL_RenderSetLogicalSize(renderer, realwidth, realheight); - Impl_VideoSetupSurfaces(realwidth, realheight); - } return SDL_TRUE; } -static void Impl_VideoSetupSurfaces(int width, int height) -{ - int bpp = 16; - int sw_texture_format = SDL_PIXELFORMAT_ABGR8888; - - if (!usesdl2soft) - { - sw_texture_format = SDL_PIXELFORMAT_RGB565; - } - else - { - bpp = 32; - sw_texture_format = SDL_PIXELFORMAT_RGBA8888; - } - - if (texture == NULL) - texture = SDL_CreateTexture(renderer, sw_texture_format, SDL_TEXTUREACCESS_STREAMING, width, height); - - // Set up SW surface - if (vidSurface == NULL) - { - Uint32 rmask; - Uint32 gmask; - Uint32 bmask; - Uint32 amask; - - SDL_PixelFormatEnumToMasks(sw_texture_format, &bpp, &rmask, &gmask, &bmask, &amask); - vidSurface = SDL_CreateRGBSurface(0, width, height, bpp, rmask, gmask, bmask, amask); - } -} - static void Impl_SetupSoftwareBuffer(void) { // Set up game's software render buffer @@ -311,33 +222,62 @@ static void Impl_SetupSoftwareBuffer(void) I_Error("%s", M_GetText("Not enough memory for video buffer\n")); } -static SDL_Rect src_rect = { 0, 0, 0, 0 }; - -static SDL_bool SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool reposition) +resolution_t *VID_GetSupportedResolutions(INT32 *count) { - static SDL_bool wasfullscreen = SDL_FALSE; - int fullscreen_type = SDL_WINDOW_FULLSCREEN_DESKTOP; + static resolution_t *res; + static INT32 numres; + if (res != NULL) + { + *count = numres; + return res; + } - boolean should_set_window_size = realwidth != width || realheight != height; + // TODO: add support for multiple monitors + INT32 nummodes = SDL_GetNumDisplayModes(0); + SDL_DisplayMode mode, prevmode; - src_rect.w = realwidth = width; - src_rect.h = realheight = height; + res = Z_Malloc(sizeof(resolution_t *) * nummodes, PU_STATIC, NULL); + numres = 0; + CONS_Printf("Available resolutions:\n"); + for (INT32 i = 0; i < nummodes; i++) + { + SDL_GetDisplayMode(0, i, &mode); + CONS_Printf(" * %dx%d@%d\n", mode.w, mode.h, mode.refresh_rate); + if (i > 0 && prevmode.w == mode.w && prevmode.h == mode.h) + { + // pick the highest refresh rate of all duplicate resolutions + if (prevmode.refresh_rate < mode.refresh_rate) + { + res[numres-1].index = i; + prevmode = mode; + } + continue; + } + res[numres].width = mode.w; + res[numres].height = mode.h; + res[numres++].index = i; + prevmode = mode; + } + + *count = numres; + return res; +} + +static SDL_bool SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool reposition) +{ if (window) { if (fullscreen) { - wasfullscreen = SDL_TRUE; - SDL_SetWindowFullscreen(window, fullscreen_type); + SDL_DestroyWindow(window); + window = NULL; + // create a new window to fix resolution quirks + return SDLSetMode(width, height, fullscreen, reposition); } else // windowed mode { - if (wasfullscreen) - { - wasfullscreen = SDL_FALSE; - SDL_SetWindowFullscreen(window, 0); - } - + SDL_SetWindowFullscreen(window, 0); SDL_SetWindowSize(window, width, height); if (reposition) @@ -355,11 +295,42 @@ static SDL_bool SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_b if (Impl_CreateWindow(fullscreen) == SDL_FALSE) return SDL_FALSE; - wasfullscreen = fullscreen; - if (should_set_window_size) - SDL_SetWindowSize(window, width, height); + SDL_SetWindowSize(window, width, height); if (fullscreen) - SDL_SetWindowFullscreen(window, fullscreen_type); + { + resolution_t *res; + INT32 numres, i; + + res = VID_GetSupportedResolutions(&numres); + for (i = 0; i < numres; i++) + { + if (res[i].width == width && res[i].height == height) + { + SDL_DisplayMode mode; + SDL_GetDisplayMode(0, res[i].index, &mode); + if (SDL_SetWindowDisplayMode(window, &mode)) + { + CONS_Alert(CONS_WARNING, "Couldn't change resolution to %dx%d: %s\n", width, height, SDL_GetError()); + continue; + } + break; + } + } + + if (i == numres) + { + // resolution is not supported, so default to native + CONS_Alert(CONS_WARNING, "Resolution %dx%d is not supported, defaulting to native\n", width, height); + SDL_DisplayMode resolution; + + if (SDL_GetDesktopDisplayMode(i, &resolution) == 0) + { + vid.width = width = (INT32)(resolution.w); + vid.height = height = (INT32)(resolution.h); + SDL_SetWindowDisplayMode(window, &resolution); + } + } + } Impl_SetDefaultWindowSizes(); } @@ -606,43 +577,17 @@ void I_SetMouseGrab(boolean grab) static void VID_Command_NumModes_f (void) { - CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), MAXWINMODES); -} - -// SDL2 doesn't have SDL_GetVideoSurface or a lot of the SDL_Surface flags that SDL 1.2 had -static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) -{ - INT32 vfBPP; - - if (!infoSurface) - return; - - if (!SurfaceText) - SurfaceText = M_GetText("Unknown Surface"); - - vfBPP = infoSurface->format?infoSurface->format->BitsPerPixel:0; - - CONS_Printf("\x82" "%s\n", SurfaceText); - CONS_Printf(M_GetText(" %ix%i at %i bit color\n"), infoSurface->w, infoSurface->h, vfBPP); - - if (infoSurface->flags&SDL_PREALLOC) - CONS_Printf("%s", M_GetText(" Uses preallocated memory\n")); - else - CONS_Printf("%s", M_GetText(" Stored in system memory\n")); - if (infoSurface->flags&SDL_RLEACCEL) - CONS_Printf("%s", M_GetText(" Colorkey RLE acceleration blit\n")); -} - -static void VID_Command_Info_f (void) -{ - SurfaceInfo(bufSurface, M_GetText("Current Engine Mode")); - SurfaceInfo(vidSurface, M_GetText("Current Video Mode")); + INT32 numres; + VID_GetSupportedResolutions(&numres); + CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), numres); } static void VID_Command_ModeList_f(void) { - for (INT32 i = 0; i < MAXWINMODES; i++) - CONS_Printf("%2d: %dx%d\n", i, windowedModes[i][0], windowedModes[i][1]); + INT32 numres; + resolution_t *res = VID_GetSupportedResolutions(&numres); + for (INT32 i = 0; i < numres; i++) + CONS_Printf("%2d: %dx%d\n", i, res[i].width, res[i].height); } static void VID_Command_Mode_f (void) @@ -653,20 +598,43 @@ static void VID_Command_Mode_f (void) return; } + INT32 numres; + resolution_t *res = VID_GetSupportedResolutions(&numres); INT32 modenum = atoi(COM_Argv(1)); - if (modenum >= MAXWINMODES) + if (modenum >= numres) CONS_Printf(M_GetText("Video mode not present\n")); else { if (modenum < 0) modenum = 0; - vid.change.width = windowedModes[modenum][0]; - vid.change.height = windowedModes[modenum][1]; + vid.change.width = res[modenum].width; + vid.change.height = res[modenum].height; vid.change.set = VID_RESOLUTION_CHANGED; } } +boolean SCR_IsValidResolution(INT32 width, INT32 height) +{ + if (width < BASEVIDWIDTH || width > MAXVIDWIDTH) + return false; + if (height < BASEVIDHEIGHT || height > MAXVIDHEIGHT) + return false; + + if (USE_FULLSCREEN) + { + INT32 numres, i; + resolution_t *res = VID_GetSupportedResolutions(&numres); + for (i = 0; i < numres; i++) + { + if (res[i].width == width && res[i].height == height) + return true; + } + return false; + } + return true; +} + static void VID_Command_Width_f (void) { if (COM_Argc() != 2) @@ -745,9 +713,9 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) mousefocus = SDL_FALSE; break; case SDL_WINDOWEVENT_SIZE_CHANGED: - if ((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) == 0) { - if (realwidth != evt.data1 || realheight != evt.data2) + if (vid.width != evt.data1 || vid.height != evt.data2) SCR_SetSizeNoRestore(evt.data1, evt.data2); SCR_SetDefaultMode(evt.data1, evt.data2); } @@ -845,7 +813,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) // If the event is from warping the pointer to middle // of the screen then ignore it. - if ((evt.x == realwidth/2) && (evt.y == realheight/2)) + if ((evt.x == vid.width/2) && (evt.y == vid.height/2)) { firstmove = false; return; @@ -1265,8 +1233,8 @@ void I_GetEvent(void) //SDL_memset(&event, 0, sizeof(event_t)); event.type = ev_mouse; event.key = 0; - event.x = (INT32)lround(mousemovex * ((float)wwidth / (float)realwidth)); - event.y = (INT32)lround(mousemovey * ((float)wheight / (float)realheight)); + event.x = (INT32)lround(mousemovex * ((float)wwidth / (float)vid.width)); + event.y = (INT32)lround(mousemovey * ((float)wheight / (float)vid.height)); D_PostEvent(&event); } @@ -1284,7 +1252,7 @@ void I_StartupMouse(void) if (!firsttimeonmouse) { - HalfWarpMouse(realwidth, realheight); // warp to center + HalfWarpMouse(vid.width, vid.height); // warp to center } else firsttimeonmouse = SDL_FALSE; @@ -1360,18 +1328,40 @@ void I_FinishUpdate(void) if (rendermode == render_soft && screens[0]) { - if (!bufSurface) // Double-check - Impl_VideoSetupBuffer(); - - SDL_BlitSurface(bufSurface, &src_rect, vidSurface, &src_rect); - // Fury -- there's no way around UpdateTexture, the GL backend uses it anyway - SDL_LockSurface(vidSurface); - SDL_UpdateTexture(texture, &src_rect, vidSurface->pixels, vidSurface->pitch); - SDL_UnlockSurface(vidSurface); + SDL_Surface *surface = SDL_GetWindowSurface(window); + // make sure the surface is ready before we render + if (surface != NULL) + { + if (surface->w < vid.width || surface->h < vid.height) + return; // sway/x11 forced us into a lower resolution than we support, don't render - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, &src_rect, NULL); - SDL_RenderPresent(renderer); + SDL_LockSurface(surface); + UINT32 *restrict pixels = surface->pixels; + const UINT8 *restrict source = screens[0]; + if (surface->w != vid.width || surface->h != vid.height) + { + // the screen doesn't allow the resolution even though it was supported + // this happens on wayland for some reason + // as a workaround, scale manually so graphics don't get fucked + INT32 skip = surface->w - vid.width; + INT32 i, j; + for (i = 0; i < vid.height; i++) + { + for (j = 0; j < vid.width; j++) + *pixels++ = softPalette[*source++]; + pixels += skip; + } + } + else + { + INT32 size = surface->w * surface->h; + INT32 i; + for (i = 0; i < size; i++) + *pixels++ = softPalette[*source++]; + } + SDL_UnlockSurface(surface); + } + SDL_UpdateWindowSurface(window); } #ifdef HWRENDER else if (rendermode == render_opengl) @@ -1419,15 +1409,15 @@ void I_ReadScreen(UINT8 *scr) void I_SetPalette(RGBA_t *palette) { size_t i; + SDL_Surface *surface = SDL_GetWindowSurface(window); for (i=0; i<256; i++) { - localPalette[i].r = palette[i].s.red; - localPalette[i].g = palette[i].s.green; - localPalette[i].b = palette[i].s.blue; + UINT32 color = palette[i].s.red << surface->format->Rshift; + color |= palette[i].s.green << surface->format->Gshift; + color |= palette[i].s.blue << surface->format->Bshift; + color |= surface->format->Amask; + softPalette[i] = color; } - //if (vidSurface) SDL_SetPaletteColors(vidSurface->format->palette, localPalette, 0, 256); - // Fury -- SDL2 vidSurface is a 32-bit surface buffer copied to the texture. It's not palletized, like bufSurface. - if (bufSurface) SDL_SetPaletteColors(bufSurface->format->palette, localPalette, 0, 256); } void VID_CheckGLLoaded(rendermode_t oldrender) @@ -1591,7 +1581,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) return SDL_TRUE; if (fullscreen) - flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + flags |= SDL_WINDOW_FULLSCREEN; if (borderlesswindow) flags |= SDL_WINDOW_BORDERLESS; @@ -1606,14 +1596,15 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) #endif // Create a window - window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, realwidth, realheight, flags); + window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, vid.width, vid.height, flags); if (window == NULL) { VIDEO_INIT_ERROR("Couldn't create window: %s"); return SDL_FALSE; } - SDL_SetWindowMinimumSize(window, BASEVIDWIDTH, BASEVIDHEIGHT); + if (!fullscreen) + SDL_SetWindowMinimumSize(window, BASEVIDWIDTH, BASEVIDHEIGHT); #ifdef USE_WINDOW_ICON Impl_SetWindowIcon(); @@ -1630,34 +1621,6 @@ static void Impl_SetWindowIcon(void) } #endif -static void Impl_VideoSetupBuffer(void) -{ - if (bufSurface != NULL) - { - SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - // Set up the SDL palletized buffer (copied to vidbuffer before being rendered to texture) - if (vid.bpp == 1) - { - bufSurface = SDL_CreateRGBSurfaceFrom(screens[0],vid.width,vid.height,8, - (int)vid.rowbytes,0x00000000,0x00000000,0x00000000,0x00000000); // 256 mode - } - else if (vid.bpp == 2) // Fury -- don't think this is used at all anymore - { - bufSurface = SDL_CreateRGBSurfaceFrom(screens[0],vid.width,vid.height,15, - (int)vid.rowbytes,0x00007C00,0x000003E0,0x0000001F,0x00000000); // 555 mode - } - if (bufSurface) - { - SDL_SetPaletteColors(bufSurface->format->palette, localPalette, 0, 256); - } - else - { - I_Error("%s", M_GetText("No system memory for SDL buffer surface\n")); - } -} - static void Impl_InitVideoSubSystem(void) { if (video_init) @@ -1683,7 +1646,6 @@ void I_StartupGraphics(void) return; COM_AddCommand ("vid_nummodes", NULL, VID_Command_NumModes_f, COM_LUA); - COM_AddCommand ("vid_info", NULL, VID_Command_Info_f, COM_LUA); COM_AddCommand ("vid_modelist", NULL, VID_Command_ModeList_f, COM_LUA); COM_AddCommand ("vid_mode", NULL, VID_Command_Mode_f, 0); COM_AddCommand ("vid_width", NULL, VID_Command_Width_f, 0); @@ -1754,7 +1716,6 @@ void I_StartupGraphics(void) if (chosenrendermode != render_none) rendermode = chosenrendermode; - usesdl2soft = M_CheckParm("-softblit"); borderlesswindow = M_CheckParm("-borderless"); #ifdef HWRENDER @@ -1783,7 +1744,6 @@ void I_StartupGraphics(void) if (M_CheckParm("-nomousegrab")) mousegrabok = SDL_FALSE; - VID_Command_Info_f(); SDLdoUngrabMouse(); SDL_RaiseWindow(window); @@ -1863,17 +1823,6 @@ void I_ShutdownGraphics(void) icoSurface = NULL; #endif - if (rendermode == render_soft) - { - if (vidSurface) - SDL_FreeSurface(vidSurface); - vidSurface = NULL; - - if (bufSurface) - SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - free(vid.buffer); vid.buffer = NULL; diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index c78b43ec4097cafad8420ceb7497e2883220a67e..ea02279958ddac3e39c07caa8185ae8ae84880ba 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -189,7 +189,7 @@ void OglSdlFinishUpdate(boolean waitvbl) HWR_DrawScreenFinalTexture(sdlw, sdlh); SDL_GL_SwapWindow(window); - GClipRect(0, 0, realwidth, realheight, NZCLIP_PLANE); + GClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE); // Sryder: We need to draw the final screen texture again into the other buffer in the original position so that // effects that want to take the old screen can do so after this diff --git a/src/z_zone.c b/src/z_zone.c index dabd68dfa40dd880400b53f03d3a8ffaf851d579..0a84efe963269e3f0d480d351065a1d6e27f94a5 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -54,8 +54,8 @@ static boolean Z_calloc = false; #endif #if !defined(ASAN_POISON_MEMORY_REGION) -# define ASAN_POISON_MEMORY_REGION(a, b) do {} while(0) -# define ASAN_UNPOISON_MEMORY_REGION(a, b) do {} while(0) +# define ASAN_POISON_MEMORY_REGION(a, b) {} +# define ASAN_UNPOISON_MEMORY_REGION(a, b) {} #endif #define ZONEID 0xa441d13d