From fea6833ea00efefec5dccd2ee85656e759726168 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 20 Dec 2023 14:09:01 +0700 Subject: [PATCH 1/5] update DRS parameters --- src/d_main.c | 16 ++++++---------- src/doomstat.h | 2 -- src/i_video.c | 40 ++++++++++++++++++++++------------------ src/i_video.h | 10 ++++++---- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index ad289eeb..0d5fdf59 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -210,7 +210,6 @@ void D_ProcessEvents (void) gamestate_t wipegamestate = GS_DEMOSCREEN; boolean screen_melt = true; extern int showMessages; -boolean enable_drs; void D_Display (void) { @@ -246,10 +245,14 @@ void D_Display (void) } } - enable_drs = true; - redrawsbar = false; + // save the current screen if about to wipe + if ((wipe = gamestate != wipegamestate) && NOTSTRICTMODE(screen_melt)) + wipe_StartScreen(0, 0, video.unscaledw, SCREENHEIGHT); + else + I_DynamicResolution(); + if (setsizeneeded) // change the view size if needed { R_ExecuteSetViewSize(); @@ -257,13 +260,6 @@ void D_Display (void) borderdrawcount = 3; } - // save the current screen if about to wipe - if ((wipe = gamestate != wipegamestate) && NOTSTRICTMODE(screen_melt)) - { - enable_drs = false; - wipe_StartScreen(0, 0, video.unscaledw, SCREENHEIGHT); - } - if (gamestate == GS_LEVEL && gametic) HU_Erase(); diff --git a/src/doomstat.h b/src/doomstat.h index 6f30d5f7..8bccef38 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -368,8 +368,6 @@ extern boolean precache; // to force a wipe on the next draw extern gamestate_t wipegamestate; -extern boolean enable_drs; - extern int mouseSensitivity_horiz; // killough extern int mouseSensitivity_vert; extern int mouseSensitivity_horiz_strafe; // [FG] strafe diff --git a/src/i_video.c b/src/i_video.c index 3f3c903d..9377ccea 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -479,7 +479,7 @@ static int targetrefresh; static void ResetResolution(int height); static void ResetLogicalSize(void); -static void DynamicResolution(void) +void I_DynamicResolution(void) { if (resolution_mode != RES_DRS || frametime_withoutpresent == 0 || frametime_withoutpresent > 1000000 / 15) @@ -494,9 +494,10 @@ static void DynamicResolution(void) double actualpercent = actual / target; #define DRS_MIN_HEIGHT 400 - #define DRS_DELTA 0.5 + #define DRS_DELTA 0.01 #define DRS_GREATER (1 + DRS_DELTA) #define DRS_LESS (1 - DRS_DELTA) + #define DRS_STEP (SCREENHEIGHT / 2) int newheight = 0; int oldheight = video.height; @@ -516,6 +517,15 @@ static void DynamicResolution(void) return; } + int mul = (newheight + (DRS_STEP - 1)) / DRS_STEP; // integer round + + newheight = mul * DRS_STEP; + + if (newheight > native_height_adjusted) + { + newheight -= DRS_STEP; + } + if (newheight == oldheight) { return; @@ -563,8 +573,8 @@ void I_FinishUpdate(void) time = frametime_start - last_time; - // Update FPS counter every second - if (time >= 1000000) + // Update FPS counter every 10th of second + if (time >= 100000) { fps = (frame_counter * 1000000) / time; frame_counter = 0; @@ -590,11 +600,6 @@ void I_FinishUpdate(void) I_ResetScreen(); need_reset = false; } - else if (enable_drs) - { - DynamicResolution(); - enable_drs = false; - } if (need_resize) { @@ -966,14 +971,16 @@ static void ResetResolution(int height) { int w, h; + int unscaled_ah = use_aspect ? ACTUALHEIGHT : SCREENHEIGHT; + actualheight = use_aspect ? (int)(height * 1.2) : height; video.height = height; switch (widescreen) { case RATIO_ORIG: - w = 4; - h = 3; + w = SCREENWIDTH; + h = unscaled_ah; break; case RATIO_MATCH_SCREEN: w = native_width; @@ -1004,14 +1011,11 @@ static void ResetResolution(int height) aspect_ratio = 2.4; } - video.unscaledw = (int)(ACTUALHEIGHT * aspect_ratio); - video.width = (int)(actualheight * aspect_ratio); + video.unscaledw = (int)(unscaled_ah * aspect_ratio); - // width and height shoud be even - video.unscaledw = (video.unscaledw + 1) & ~1; - video.width = (video.width + 1) & ~1; - video.height = (video.height + 1) & ~1; - actualheight = (actualheight + 1) & ~1; + double vertscale = (double)actualheight / (double)unscaled_ah; + video.width = (int)(video.unscaledw * vertscale); + video.width = (video.width + 1) & ~1; video.deltaw = (video.unscaledw - NONWIDEWIDTH) / 2; diff --git a/src/i_video.h b/src/i_video.h index 2b6b01d4..8a564916 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -51,20 +51,22 @@ typedef enum // determines the hardware configuration // and sets up the video mode -void I_InitGraphics (void); +void I_InitGraphics(void); void I_ShutdownGraphics(void); // Takes full 8 bit values. -void I_SetPalette (byte* palette); +void I_SetPalette(byte* palette); -void I_FinishUpdate (void); +void I_FinishUpdate(void); -void I_ReadScreen (byte* scr); +void I_ReadScreen(byte* dst); void I_ResetScreen(void); // killough 10/98 void I_ResetTargetRefresh(void); void I_ToggleVsync(void); // [JN] Calls native SDL vsync toggle +void I_DynamicResolution(void); + extern boolean use_vsync; // killough 2/8/98: controls whether vsync is called extern boolean disk_icon; // killough 10/98 extern resolution_mode_t resolution_mode, default_resolution_mode; From 9f0197338f9b024bfc8d87ab8432796259c58062 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 20 Dec 2023 14:09:26 +0700 Subject: [PATCH 2/5] introduce video.pitch, avoid screen copying in I_FinishUpdate --- src/f_wipe.c | 8 ++++---- src/i_video.c | 30 ++++++++---------------------- src/m_snapshot.c | 7 +++---- src/r_draw.c | 4 ++-- src/r_voxel.c | 2 +- src/st_stuff.c | 13 +++---------- src/v_video.c | 2 +- src/v_video.h | 1 + 8 files changed, 23 insertions(+), 44 deletions(-) diff --git a/src/f_wipe.c b/src/f_wipe.c index 8cdc012a..025d047d 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -55,7 +55,7 @@ static void wipe_shittyColMajorXform(byte *array, int width, int height) static int wipe_initColorXForm(int width, int height, int ticks) { - memcpy(wipe_scr, wipe_scr_start, width*height); + V_PutBlock(0, 0, width, height, wipe_scr_start); return 0; } @@ -94,7 +94,7 @@ static int wipe_initMelt(int width, int height, int ticks) col_y = Z_Malloc(num_columns * sizeof(*col_y), PU_STATIC, NULL); // copy start screen to main screen - memcpy(wipe_scr, wipe_scr_start, width*height); + V_PutBlock(0, 0, width, height, wipe_scr_start); // makes this wipe faster (in theory) // to have stuff in column-major format @@ -152,14 +152,14 @@ static int wipe_doMelt(int width, int height, int ticks) for (y = 0; y < scroff; ++y) { *d = *s; - d += width; + d += video.pitch; s++; } s = wipe_scr_start + x * height; for (; y < height; ++y) { *d = *s; - d += width; + d += video.pitch; s++; } } diff --git a/src/i_video.c b/src/i_video.c index 9377ccea..f37d5621 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -436,20 +436,6 @@ void I_StartFrame(void) static void UpdateRender(void) { - int i; - - // Copy linear video buffer to rectangle on surface - - byte *dest = screenbuffer->pixels; - const pixel_t *src = I_VideoBuffer; - - for (i = 0; i < blit_rect.h; ++i) - { - memcpy(dest, src, blit_rect.w); - dest += screenbuffer->w; - src += blit_rect.w; - } - SDL_LowerBlit(screenbuffer, &blit_rect, argbbuffer, &blit_rect); SDL_UpdateTexture(texture, &blit_rect, argbbuffer->pixels, argbbuffer->pitch); SDL_RenderClear(renderer); @@ -639,9 +625,9 @@ void I_FinishUpdate(void) // I_ReadScreen // -void I_ReadScreen(byte *scr) +void I_ReadScreen(byte *dst) { - memcpy(scr, I_VideoBuffer, video.width * video.height * sizeof(*I_VideoBuffer)); + V_GetBlock(0, 0, video.width, video.height, dst); } // @@ -1381,6 +1367,8 @@ static void CreateSurfaces(void) w = (w + 3) & ~3; h = (h + 3) & ~3; + video.pitch = w; + // [FG] create paletted frame buffer if (screenbuffer != NULL) @@ -1393,14 +1381,12 @@ static void CreateSurfaces(void) 0, 0, 0, 0); SDL_FillRect(screenbuffer, NULL, 0); - if (I_VideoBuffer != NULL) - { - Z_Free(I_VideoBuffer); - } - - I_VideoBuffer = Z_Calloc(1, w * h * sizeof(*I_VideoBuffer), PU_STATIC, NULL); + I_VideoBuffer = screenbuffer->pixels; V_RestoreBuffer(); + // Clear the screen to black. + memset(I_VideoBuffer, 0, w * h * sizeof(*I_VideoBuffer)); + if (argbbuffer != NULL) { SDL_FreeSurface(argbbuffer); diff --git a/src/m_snapshot.c b/src/m_snapshot.c index 3c0985d0..6c001529 100644 --- a/src/m_snapshot.c +++ b/src/m_snapshot.c @@ -21,7 +21,6 @@ #include "doomtype.h" #include "doomstat.h" -#include "i_video.h" #include "m_io.h" #include "v_video.h" #include "r_main.h" @@ -123,7 +122,7 @@ static void M_TakeSnapshot (void) { for (x = video.deltaw; x < NONWIDEWIDTH + video.deltaw; x++) { - *p++ = s[V_ScaleY(y) * video.width + V_ScaleX(x)]; + *p++ = s[V_ScaleY(y) * video.pitch + V_ScaleX(x)]; } } @@ -164,7 +163,7 @@ boolean M_DrawSnapshot (int n, int x, int y, int w, int h) const fixed_t step_x = (SCREENWIDTH << FRACBITS) / rect.sw; const fixed_t step_y = (SCREENHEIGHT << FRACBITS) / rect.sh; - byte *dest = I_VideoBuffer + rect.sy * video.width + rect.sx; + byte *dest = I_VideoBuffer + rect.sy * video.pitch + rect.sx; fixed_t srcx, srcy; int destx, desty; @@ -172,7 +171,7 @@ boolean M_DrawSnapshot (int n, int x, int y, int w, int h) for (desty = 0, srcy = 0; desty < rect.sh; desty++, srcy += step_y) { - destline = dest + desty * video.width; + destline = dest + desty * video.pitch; srcline = snapshots[n] + (srcy >> FRACBITS) * SCREENWIDTH; for (destx = 0, srcx = 0; destx < rect.sw; destx++, srcx += step_x) diff --git a/src/r_draw.c b/src/r_draw.c index abbb0f9f..d1df014d 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -47,7 +47,7 @@ int viewwindowx; int viewwindowy; static byte **ylookup = NULL; static int *columnofs = NULL; -static int linesize = SCREENWIDTH; // killough 11/98 +static int linesize; // killough 11/98 // Color tables for different players, // translate a limited part to another @@ -824,7 +824,7 @@ void R_InitBuffer(void) { int i; - linesize = video.width; // killough 11/98 + linesize = video.pitch; // killough 11/98 // Handle resize, // e.g. smaller view windows diff --git a/src/r_voxel.c b/src/r_voxel.c index 1a3bc2a6..fe42eca6 100644 --- a/src/r_voxel.c +++ b/src/r_voxel.c @@ -813,7 +813,7 @@ static void VX_DrawColumn (vissprite_t * spr, int x, int y) boolean shadow = ((spr->mobjflags & MF_SHADOW) != 0); - int linesize = video.width; + int linesize = video.pitch; byte * dest = I_VideoBuffer + viewwindowy * linesize + viewwindowx; // iterate over screen columns diff --git a/src/st_stuff.c b/src/st_stuff.c index 64f4d25a..b837e131 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -342,7 +342,7 @@ static void ST_DrawSolidBackground(int st_x) { for (x = 0; x < depth; x++) { - byte *c = st_backing_screen + V_ScaleY(y) * video.width + V_ScaleX(x + offset); + byte *c = st_backing_screen + V_ScaleY(y) * video.pitch + V_ScaleX(x + offset); r += pal[3 * c[0] + 0]; g += pal[3 * c[0] + 1]; b += pal[3 * c[0] + 2]; @@ -1327,14 +1327,7 @@ void ST_Init(void) void ST_InitRes(void) { - vrect_t rect; - - rect.x = 0; - rect.y = 0; - rect.w = video.unscaledw; - rect.h = StatusBarBufferHeight(); - - V_ScaleRect(&rect); + int height = V_ScaleY(StatusBarBufferHeight()); if (st_backing_screen) { @@ -1342,7 +1335,7 @@ void ST_InitRes(void) } // killough 11/98: allocate enough for hires - st_backing_screen = Z_Malloc(rect.sw * rect.sh * sizeof(*st_backing_screen), PU_STATIC, 0); + st_backing_screen = Z_Malloc(video.pitch * height * sizeof(*st_backing_screen), PU_STATIC, 0); } void ST_Warnings(void) diff --git a/src/v_video.c b/src/v_video.c index d77d2bc4..987ee59f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -970,7 +970,7 @@ void V_Init(void) int i; fixed_t frac, lastfrac; - linesize = video.width; + linesize = video.pitch; video.xscale = (video.width << FRACBITS) / video.unscaledw; video.yscale = (video.height << FRACBITS) / SCREENHEIGHT; diff --git a/src/v_video.h b/src/v_video.h index 44ec9d25..e4f8cb23 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -93,6 +93,7 @@ typedef struct { int width; int height; + int pitch; int unscaledw; // unscaled width with correction for widecreen int deltaw; // widescreen delta From d05570e334bb551f26a9f5f2634642ea963369d4 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Wed, 20 Dec 2023 15:49:31 +0700 Subject: [PATCH 3/5] fix automap and overlay * Fix background buffer size --- src/am_map.c | 10 ++++++++-- src/i_video.c | 2 +- src/r_draw.c | 2 +- src/v_video.c | 10 +++++++--- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/am_map.c b/src/am_map.c index 2d81b71c..9a00d1d6 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -1074,7 +1074,13 @@ void AM_Ticker (void) // static void AM_clearFB(int color) { - memset(fb, color, f_w*f_h); + int h = f_h; + byte *src = fb; + while (h--) + { + memset(src, color, f_w); + src += video.pitch; + } } // @@ -1252,7 +1258,7 @@ static void AM_drawFline_Vanilla(fline_t* fl, int color) } #endif -#define PUTDOT(xx,yy,cc) fb[(yy)*f_w+(xx)]=(cc) +#define PUTDOT(xx,yy,cc) fb[(yy)*video.pitch+(xx)]=(cc) dx = fl->b.x - fl->a.x; ax = 2 * (dx<0 ? -dx : dx); diff --git a/src/i_video.c b/src/i_video.c index f37d5621..d8eb1792 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -480,7 +480,7 @@ void I_DynamicResolution(void) double actualpercent = actual / target; #define DRS_MIN_HEIGHT 400 - #define DRS_DELTA 0.01 + #define DRS_DELTA 0.1 #define DRS_GREATER (1 + DRS_DELTA) #define DRS_LESS (1 - DRS_DELTA) #define DRS_STEP (SCREENHEIGHT / 2) diff --git a/src/r_draw.c b/src/r_draw.c index d1df014d..78b1818f 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -896,7 +896,7 @@ void R_FillBackScreen (void) // Allocate the background buffer if necessary if (background_buffer == NULL) { - int size = video.width * video.height; + int size = video.pitch * video.height; background_buffer = Z_Malloc(size * sizeof(*background_buffer), PU_STATIC, NULL); } diff --git a/src/v_video.c b/src/v_video.c index 987ee59f..7ff20efd 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -920,7 +920,7 @@ void V_PutBlock(int x, int y, int width, int height, byte *src) void V_ShadeScreen(void) { - int y; + int x, y; byte *dest = dest_screen; const int targshade = 20, step = 2; static int oldtic = -1; @@ -932,9 +932,13 @@ void V_ShadeScreen(void) screenshade = 0; } - for (y = 0; y < video.width * video.height; y++) + for (y = 0; y < video.height; y++) { - dest[y] = colormaps[0][screenshade * 256 + dest[y]]; + for (x = 0; x < video.width; x++) + { + dest[x] = colormaps[0][screenshade * 256 + dest[x]]; + } + dest += linesize; } if (screenshade < targshade && gametic != oldtic) From d38fd80fed896e7ae7e07e7e72b10e2a4262dfd2 Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Fri, 22 Dec 2023 17:54:42 +0700 Subject: [PATCH 4/5] fix 21:9 aspect ratio, tweak DRS parameters --- src/i_video.c | 109 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 38 deletions(-) diff --git a/src/i_video.c b/src/i_video.c index d8eb1792..9c78688c 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -85,6 +85,7 @@ static SDL_Rect blit_rect = {0}; static int window_x, window_y; static int actualheight; +static int unscaled_actualheight; static int native_width; static int native_height; @@ -467,6 +468,9 @@ static void ResetLogicalSize(void); void I_DynamicResolution(void) { + static int frame_counter; + static double averagepercent; + if (resolution_mode != RES_DRS || frametime_withoutpresent == 0 || frametime_withoutpresent > 1000000 / 15) { @@ -480,7 +484,7 @@ void I_DynamicResolution(void) double actualpercent = actual / target; #define DRS_MIN_HEIGHT 400 - #define DRS_DELTA 0.1 + #define DRS_DELTA 0.01 #define DRS_GREATER (1 + DRS_DELTA) #define DRS_LESS (1 - DRS_DELTA) #define DRS_STEP (SCREENHEIGHT / 2) @@ -488,14 +492,17 @@ void I_DynamicResolution(void) int newheight = 0; int oldheight = video.height; + frame_counter++; + averagepercent = (averagepercent + actualpercent) / frame_counter; + if (actualpercent > DRS_GREATER) { double reduction = (actualpercent - DRS_GREATER ) * 0.2; newheight = (int)MAX(DRS_MIN_HEIGHT, oldheight - oldheight * reduction); } - else if (actualpercent < DRS_LESS) + else if (averagepercent < DRS_LESS && frame_counter > targetrefresh) { - double addition = (DRS_LESS - actualpercent) * 0.25; + double addition = (DRS_LESS - averagepercent) * 0.25; newheight = (int)MIN(native_height_adjusted, oldheight + oldheight * addition); } else @@ -503,6 +510,8 @@ void I_DynamicResolution(void) return; } + frame_counter = 0; + int mul = (newheight + (DRS_STEP - 1)) / DRS_STEP; // integer round newheight = mul * DRS_STEP; @@ -570,13 +579,13 @@ void I_FinishUpdate(void) I_DrawDiskIcon(); + UpdateRender(); + if (frametime_start) { frametime_withoutpresent = I_GetTimeUS() - frametime_start; } - UpdateRender(); - SDL_RenderPresent(renderer); I_RestoreDiskBackground(); @@ -953,20 +962,15 @@ static void I_GetWindowPosition(int *x, int *y, int w, int h) } } -static void ResetResolution(int height) +static double CurrentAspectRatio(void) { int w, h; - int unscaled_ah = use_aspect ? ACTUALHEIGHT : SCREENHEIGHT; - - actualheight = use_aspect ? (int)(height * 1.2) : height; - video.height = height; - switch (widescreen) { case RATIO_ORIG: w = SCREENWIDTH; - h = unscaled_ah; + h = unscaled_actualheight; break; case RATIO_MATCH_SCREEN: w = native_width; @@ -997,9 +1001,19 @@ static void ResetResolution(int height) aspect_ratio = 2.4; } - video.unscaledw = (int)(unscaled_ah * aspect_ratio); + return aspect_ratio; +} - double vertscale = (double)actualheight / (double)unscaled_ah; +static void ResetResolution(int height) +{ + double aspect_ratio = CurrentAspectRatio(); + + actualheight = use_aspect ? (int)(height * 1.2) : height; + video.height = height; + + video.unscaledw = (int)(unscaled_actualheight * aspect_ratio); + + double vertscale = (double)actualheight / (double)unscaled_actualheight; video.width = (int)(video.unscaledw * vertscale); video.width = (video.width + 1) & ~1; @@ -1015,7 +1029,7 @@ static void ResetResolution(int height) I_InitDiskFlash(); - I_Printf(VB_DEBUG, "ResetResolution: %dx%d", video.width, actualheight); + I_Printf(VB_DEBUG, "ResetResolution: %dx%d", video.width, video.height); } static void CreateUpscaledTexture(boolean force) @@ -1149,6 +1163,30 @@ void I_ResetTargetRefresh(void) static void I_InitVideoParms(void) { int p, tmp_scalefactor; + SDL_DisplayMode mode; + + if (SDL_GetCurrentDisplayMode(video_display, &mode)) + { + I_Error("Error getting display mode: %s", SDL_GetError()); + } + + native_width = mode.w; + native_height = mode.h; + native_refresh_rate = mode.refresh_rate; + + widescreen = default_widescreen; + + double aspect_ratio = CurrentAspectRatio(); + double native_aspect_ratio = (double)native_width / (double)native_height; + + if (widescreen && native_aspect_ratio < aspect_ratio) + { + native_height = (int)(native_width / aspect_ratio); + } + + native_height_adjusted = use_aspect ? (int)(native_height / 1.2) : native_height; + + unscaled_actualheight = use_aspect ? ACTUALHEIGHT: SCREENHEIGHT; I_ResetInvalidDisplayIndex(); resolution_mode = default_resolution_mode; @@ -1326,46 +1364,44 @@ static void I_InitGraphicsMode(void) static int CurrentResolutionMode(void) { + int height; + switch (resolution_mode) { case RES_ORIGINAL: - return SCREENHEIGHT; + height = SCREENHEIGHT; + break; case RES_DOUBLE: - return SCREENHEIGHT * 2; + height = SCREENHEIGHT * 2; + break; case RES_TRIPLE: - return SCREENHEIGHT * 3; - case RES_DRS: - return native_height_adjusted; + height = SCREENHEIGHT * 3; + break; default: - return native_height_adjusted; + height = native_height_adjusted; + break; } + + if (height > native_height_adjusted) + { + height = native_height_adjusted; + } + + return height; } static void CreateSurfaces(void) { int w, h; - SDL_DisplayMode mode; - - if (SDL_GetCurrentDisplayMode(video_display, &mode)) - { - I_Error("Error getting display mode: %s", SDL_GetError()); - } - - native_width = mode.w; - native_height = mode.h; - native_refresh_rate = mode.refresh_rate; w = native_width; - h = use_aspect ? (int)(native_height / 1.2) : native_height; - - native_height_adjusted = h; + h = native_height_adjusted; // [FG] For performance reasons, SDL2 insists that the screen pitch, i.e. // the *number of bytes* that one horizontal row of pixels occupy in // memory, must be a multiple of 4. w = (w + 3) & ~3; - h = (h + 3) & ~3; video.pitch = w; @@ -1384,9 +1420,6 @@ static void CreateSurfaces(void) I_VideoBuffer = screenbuffer->pixels; V_RestoreBuffer(); - // Clear the screen to black. - memset(I_VideoBuffer, 0, w * h * sizeof(*I_VideoBuffer)); - if (argbbuffer != NULL) { SDL_FreeSurface(argbbuffer); From 472aeb099699ca376c0e125992191b8a328c16ee Mon Sep 17 00:00:00 2001 From: Roman Fomin Date: Sat, 23 Dec 2023 14:57:40 +0700 Subject: [PATCH 5/5] add comments --- src/i_video.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/i_video.c b/src/i_video.c index 9c78688c..44b3dbf5 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -472,6 +472,7 @@ void I_DynamicResolution(void) static double averagepercent; if (resolution_mode != RES_DRS || frametime_withoutpresent == 0 || + // Skip if frame time is too long (e.g. window event). frametime_withoutpresent > 1000000 / 15) { return; @@ -487,11 +488,15 @@ void I_DynamicResolution(void) #define DRS_DELTA 0.01 #define DRS_GREATER (1 + DRS_DELTA) #define DRS_LESS (1 - DRS_DELTA) + // 100px step to make scaling artefacts less noticeable. #define DRS_STEP (SCREENHEIGHT / 2) int newheight = 0; int oldheight = video.height; + // Decrease the resolution quickly, increase only when the average frame + // time is stable for the `targetrefresh` number of frames. + frame_counter++; averagepercent = (averagepercent + actualpercent) / frame_counter; @@ -1013,6 +1018,11 @@ static void ResetResolution(int height) video.unscaledw = (int)(unscaled_actualheight * aspect_ratio); + // Unscaled widescreen 16:9 resolution truncates to 426x240, which is not + // quite 16:9. To avoid visual instability, we calculate the scaled width + // without the actual aspect ratio. For example, at 1280x720 we get + // 1278x720. + double vertscale = (double)actualheight / (double)unscaled_actualheight; video.width = (int)(video.unscaledw * vertscale); video.width = (video.width + 1) & ~1;