From 2398f8223d6a175fc028e8144745fc76cb22ee9e Mon Sep 17 00:00:00 2001 From: feos Date: Sun, 27 Jul 2025 22:48:39 +0300 Subject: [PATCH 1/4] fix wipe effect skipping frames when rendering takes "too long" software mode at high resolutions takes longer to render and to dump frames than opengl at comparable resolutions. so more real time passes between frames, which makes the ending advance the melt effect further than normal on the next frame. the code was always doing this, but it was written with much lower resolution in mind too, and viddump wasn't as widespread back then maybe? now melt consistently takes 45 frames, even tho in `wipe_doMelt()` cph says it takes 25 for some reason (that whole comment kinda contradicts current reality anyway). fixes #714 --- prboom2/src/d_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prboom2/src/d_main.c b/prboom2/src/d_main.c index ce813d15d..3c7e7f3fa 100644 --- a/prboom2/src/d_main.c +++ b/prboom2/src/d_main.c @@ -301,7 +301,7 @@ static void D_Wipe(void) } wipestart = nowtime; - done = wipe_ScreenWipe(tics); + done = wipe_ScreenWipe(1); // elim - Render texture to screen if (V_IsOpenGLMode()) From ba4fb0fd6a91e65e0fea5d33a8b7ed6138bc5e3d Mon Sep 17 00:00:00 2001 From: feos Date: Tue, 5 Aug 2025 17:20:05 +0300 Subject: [PATCH 2/4] make wipe width-independent (by Pedro-Beirao) --- prboom2/src/f_wipe.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/prboom2/src/f_wipe.c b/prboom2/src/f_wipe.c index de1dbd536..30b854bf0 100644 --- a/prboom2/src/f_wipe.c +++ b/prboom2/src/f_wipe.c @@ -77,6 +77,7 @@ void R_InitMeltRes(void) static int wipe_initMelt(int ticks) { int i; + int block_width = WIDE_SCREENWIDTH / 320; if (V_IsSoftwareMode()) { @@ -89,16 +90,20 @@ static int wipe_initMelt(int ticks) // setup initial column positions (y<0 => not ready to scroll yet) y_lookup[0] = -(M_Random()%16); - for (i=1;i 0) - y_lookup[i] = 0; - else - if (y_lookup[i] == -16) - y_lookup[i] = -15; - } + for (i = 1; i < SCREENWIDTH; i++) + { + int r = y_lookup[i - 1]; + + if (i % block_width == 0) + r += (M_Random()%3) - 1; + + y_lookup[i] = r; + if (y_lookup[i] > 0) + y_lookup[i] = 0; + else + if (y_lookup[i] == -16) + y_lookup[i] = -15; + } return 0; } From 52b5c136e2c4810e3b157c847161cf0181de9bd7 Mon Sep 17 00:00:00 2001 From: feos Date: Sat, 30 Aug 2025 18:31:40 +0300 Subject: [PATCH 3/4] account for different heights and framerates --- prboom2/src/f_wipe.c | 84 ++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/prboom2/src/f_wipe.c b/prboom2/src/f_wipe.c index 30b854bf0..2d20f19a4 100644 --- a/prboom2/src/f_wipe.c +++ b/prboom2/src/f_wipe.c @@ -47,6 +47,7 @@ #include "e6y.h"//e6y #include "dsda/settings.h" +#include // // SCREEN WIPE PACKAGE @@ -66,6 +67,9 @@ static screeninfo_t wipe_scr; // e6y: resolution limitation is removed static int *y_lookup = NULL; +static int target_fps; +extern int capturing_video; + // e6y: resolution limitation is removed void R_InitMeltRes(void) { @@ -74,11 +78,35 @@ void R_InitMeltRes(void) y_lookup = Z_Calloc(1, SCREENWIDTH * sizeof(*y_lookup)); } +int rescale_pixels(int number) +{ + int new_number = number * SCREENHEIGHT / 200; + return (number >= 1 && new_number < 1) ? 1 : (number * SCREENHEIGHT / 200); +} + +int slow_down(int number) +{ + int new_number = number * TICRATE / target_fps; + return new_number < 1 ? 1 : new_number; +} + +int speed_up(int number) +{ + return number * target_fps / TICRATE; +} + static int wipe_initMelt(int ticks) { int i; int block_width = WIDE_SCREENWIDTH / 320; + if (block_width < 1) + block_width = 1; + + // wipe runs at fixed 35fps, but its framerate in the video is changed to cap_fps + // we change its speed depending on cap_fps so it looks the same in the video + target_fps = capturing_video ? dsda_IntConfig(dsda_config_cap_fps) : TICRATE; + if (V_IsSoftwareMode()) { // copy start screen to main screen @@ -104,6 +132,13 @@ static int wipe_initMelt(int ticks) if (y_lookup[i] == -16) y_lookup[i] = -15; } + + for (i = 0; i < SCREENWIDTH; i++) + { + // range of values has to be increased along with framerate + // so the pattern retains overall shape + y_lookup[i] = speed_up(rescale_pixels(y_lookup[i])); + } return 0; } @@ -115,7 +150,7 @@ static int wipe_doMelt(int ticks) while (ticks--) { for (i=0;i<(SCREENWIDTH);i++) { if (y_lookup[i]<0) { - y_lookup[i]++; + y_lookup[i] += rescale_pixels(1); done = false; continue; } @@ -124,33 +159,38 @@ static int wipe_doMelt(int ticks) int j, dy; /* cph 2001/07/29 - - * The original melt rate was 8 pixels/sec, i.e. 25 frames to melt - * the whole screen, so make the melt rate depend on SCREENHEIGHT - * so it takes no longer in high res - */ - dy = (y_lookup[i] < 16) ? y_lookup[i]+1 : SCREENHEIGHT/25; + * The original melt rate was 8 pixels/sec, i.e. 25 frames to melt + * the whole screen, so make the melt rate depend on SCREENHEIGHT + * so it takes no longer in high res + */ + + // slowing things down by reducing deltas + // so wipe retains duration at higher framerates + dy = (y_lookup[i] < slow_down(rescale_pixels(16))) + ? y_lookup[i] + slow_down(rescale_pixels(1)) + : slow_down(rescale_pixels(8)); if (y_lookup[i]+dy >= SCREENHEIGHT) dy = SCREENHEIGHT - y_lookup[i]; - if (V_IsSoftwareMode()) { - s = wipe_scr_end.data + (y_lookup[i]*wipe_scr_end.pitch+i); - d = wipe_scr.data + (y_lookup[i]*wipe_scr.pitch+i); - for (j=dy;j;j--) { - d[0] = s[0]; - d += wipe_scr.pitch; - s += wipe_scr_end.pitch; + if (V_IsSoftwareMode()) { + s = wipe_scr_end.data + (y_lookup[i]*wipe_scr_end.pitch+i); + d = wipe_scr.data + (y_lookup[i]*wipe_scr.pitch+i); + for (j=dy;j;j--) { + d[0] = s[0]; + d += wipe_scr.pitch; + s += wipe_scr_end.pitch; + } } - } y_lookup[i] += dy; - if (V_IsSoftwareMode()) { - s = wipe_scr_start.data + i; - d = wipe_scr.data + (y_lookup[i]*wipe_scr.pitch+i); - for (j=SCREENHEIGHT-y_lookup[i];j;j--) { - d[0] = s[0]; - d += wipe_scr.pitch; - s += wipe_scr_end.pitch; + if (V_IsSoftwareMode()) { + s = wipe_scr_start.data + i; + d = wipe_scr.data + (y_lookup[i]*wipe_scr.pitch+i); + for (j=SCREENHEIGHT-y_lookup[i];j;j--) { + d[0] = s[0]; + d += wipe_scr.pitch; + s += wipe_scr_end.pitch; + } } - } done = false; } } From a77a2ce80d1d2be25a90c66259011003796ad696 Mon Sep 17 00:00:00 2001 From: feos Date: Sat, 6 Sep 2025 16:52:54 +0300 Subject: [PATCH 4/4] fix overshooting --- prboom2/src/f_wipe.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/prboom2/src/f_wipe.c b/prboom2/src/f_wipe.c index 2d20f19a4..e9edaa735 100644 --- a/prboom2/src/f_wipe.c +++ b/prboom2/src/f_wipe.c @@ -81,13 +81,13 @@ void R_InitMeltRes(void) int rescale_pixels(int number) { int new_number = number * SCREENHEIGHT / 200; - return (number >= 1 && new_number < 1) ? 1 : (number * SCREENHEIGHT / 200); + return (number >= 1 && new_number < 1) ? 1 : new_number; } int slow_down(int number) { int new_number = number * TICRATE / target_fps; - return new_number < 1 ? 1 : new_number; + return (number >= 1 && new_number < 1) ? 1 : new_number; } int speed_up(int number) @@ -151,6 +151,11 @@ static int wipe_doMelt(int ticks) for (i=0;i<(SCREENWIDTH);i++) { if (y_lookup[i]<0) { y_lookup[i] += rescale_pixels(1); + // prevent overshooing and showing garbage pixels at the top. + // increments by 1 worked for native footage but now they're variable + // so the first positive step is not guaranteed to be 0 + if (y_lookup[i] > 0) + y_lookup[i] = 0; done = false; continue; }