From bb566685e4bb531fad69c6149693ba18fb96d6d6 Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 9 Feb 2025 11:31:45 -0500 Subject: [PATCH] Port opengl VHS effect from SRB2Kart-Saturn Does not include uncap stuff currently --- src/hardware/hw_drv.h | 2 + src/hardware/hw_main.c | 5 ++ src/hardware/hw_main.h | 1 + src/hardware/r_opengl/r_opengl.c | 80 ++++++++++++++++++++++++++++++++ src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.cpp | 1 + src/v_video.c | 25 +++++++++- 7 files changed, 113 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 82be505d7..da4fb8542 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -66,6 +66,7 @@ EXPORT void HWRAPI(EndScreenWipe) (void); EXPORT void HWRAPI(DoScreenWipe) (void); EXPORT void HWRAPI(DrawIntermissionBG) (void); EXPORT void HWRAPI(MakeScreenTexture) (void); +EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize); EXPORT void HWRAPI(MakeScreenFinalTexture) (void); EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height); @@ -121,6 +122,7 @@ struct hwdriver_s DoScreenWipe pfnDoScreenWipe; DrawIntermissionBG pfnDrawIntermissionBG; MakeScreenTexture pfnMakeScreenTexture; + RenderVhsEffect pfnRenderVhsEffect; MakeScreenFinalTexture pfnMakeScreenFinalTexture; DrawScreenFinalTexture pfnDrawScreenFinalTexture; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index eac16206c..7d8efb29e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6672,6 +6672,11 @@ void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum) HWR_DoWipe(wipenum, scrnnum); } +void HWR_RenderVhsEffect(INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize) +{ + HWD.pfnRenderVhsEffect(upbary, downbary, updistort, downdistort, barsize); +} + void HWR_MakeScreenFinalTexture(void) { HWD.pfnMakeScreenFinalTexture(); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 7460d9d05..41a742134 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -67,6 +67,7 @@ void HWR_EndScreenWipe(void); void HWR_DrawIntermissionBG(void); void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum); void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum); +void HWR_RenderVhsEffect(INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize); void HWR_MakeScreenFinalTexture(void); void HWR_DrawScreenFinalTexture(int width, int height); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 50db95a52..b41297d24 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -3512,6 +3512,86 @@ EXPORT void HWRAPI(MakeScreenTexture) (void) tex_downloaded = screentexture; } +EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize) +{ + float xfix, yfix; + float fix[8]; + GLubyte color[4] = {255, 255, 255, 255}; + float i; + float screenVerts[12] = + { + -1.0f, -1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, -1.0f, 1.0f + }; + // look for power of two that is large enough for the screen + while (texsize < screen_width || texsize < screen_height) + texsize <<= 1; + xfix = 1/((float)(texsize)/((float)((screen_width)))); + yfix = 1/((float)(texsize)/((float)((screen_height)))); + // Slight fuzziness + MakeScreenTexture(); + SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest); + pglBindTexture(GL_TEXTURE_2D, screentexture); + for (i = 0; i < 1; i += 2.f/vid.height) + { + fix[2] = (float)(rand() % 128) / -22000 * xfix; + fix[0] = fix[2]; + fix[6] = fix[0] + xfix; + fix[4] = fix[2] + xfix; + fix[1] = fix[7] = i*yfix; + fix[3] = fix[5] = (i+0.015)*yfix; + screenVerts[1] = screenVerts[10] = 2*i - 1.0f; + screenVerts[4] = screenVerts[7] = screenVerts[1] + 0.03; + pglColor4ubv(color); + pglTexCoordPointer(2, GL_FLOAT, 0, fix); + pglVertexPointer(3, GL_FLOAT, 0, screenVerts); + pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + // Upward bar + MakeScreenTexture(); + pglBindTexture(GL_TEXTURE_2D, screentexture); + color[0] = color[1] = color[2] = 190; + color[3] = 250; + pglColor4ubv(color); + fix[0] = 0.0f; + fix[6] = xfix; + fix[2] = (float)updistort / screen_width * xfix; + fix[4] = fix[2] + fix[6]; + screenVerts[1] = screenVerts[10] = 2.0f*upbary/screen_height - 1.0f; + screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/screen_height; + fix[1] = fix[7] = (float)upbary/screen_height * yfix; + fix[3] = fix[5] = fix[1] + (float)barsize/2/screen_height * yfix; + pglTexCoordPointer(2, GL_FLOAT, 0, fix); + pglVertexPointer(3, GL_FLOAT, 0, screenVerts); + pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); + fix[1] = fix[7] += (fix[3] - fix[7])*2; + screenVerts[1] = screenVerts[10] += (screenVerts[4] - screenVerts[1])*2; + pglTexCoordPointer(2, GL_FLOAT, 0, fix); + pglVertexPointer(3, GL_FLOAT, 0, screenVerts); + pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); + // Downward bar + MakeScreenTexture(); + pglBindTexture(GL_TEXTURE_2D, screentexture); + fix[0] = 0.0f; + fix[6] = xfix; + fix[2] = (float)downdistort / screen_width * -xfix; + fix[4] = fix[2] + fix[6]; + screenVerts[1] = screenVerts[10] = 2.0f*downbary/screen_height - 1.0f; + screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/screen_height; + fix[1] = fix[7] = (float)downbary/screen_height * yfix; + fix[3] = fix[5] = fix[1] + (float)barsize/2/screen_height * yfix; + pglTexCoordPointer(2, GL_FLOAT, 0, fix); + pglVertexPointer(3, GL_FLOAT, 0, screenVerts); + pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); + fix[1] = fix[7] += (fix[3] - fix[7])*2; + screenVerts[1] = screenVerts[10] += (screenVerts[4] - screenVerts[1])*2; + pglTexCoordPointer(2, GL_FLOAT, 0, fix); + pglVertexPointer(3, GL_FLOAT, 0, screenVerts); + pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); +} + EXPORT void HWRAPI(MakeScreenFinalTexture) (void) { boolean firstTime = (finalScreenTexture == 0); diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index ff4f9f664..16a8c9478 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -102,6 +102,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(DoScreenWipe); GETFUNC(DrawIntermissionBG); GETFUNC(MakeScreenTexture); + GETFUNC(RenderVhsEffect); GETFUNC(MakeScreenFinalTexture); GETFUNC(DrawScreenFinalTexture); diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 074e8e52a..a41e6766b 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -2080,6 +2080,7 @@ void VID_StartupOpenGL(void) *(void**)&HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); *(void**)&HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); *(void**)&HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + *(void**)&HWD.pfnRenderVhsEffect = hwSym("RenderVhsEffect",NULL); *(void**)&HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); *(void**)&HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); diff --git a/src/v_video.c b/src/v_video.c index 9f53cb1de..b29dae81f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -30,6 +30,7 @@ #include "m_misc.h" #include "m_random.h" #include "doomstat.h" +#include "r_fps.h" #ifdef HWRENDER #include "hardware/hw_glob.h" @@ -1421,11 +1422,31 @@ void V_DrawVhsEffect(boolean rewind) if (rewind) V_DrawVhsEffect(false); // experimentation - upbary -= FixedMul(vid.dupy * (rewind ? 3 : 1.8f), renderdeltatics); - downbary += FixedMul(vid.dupy * (rewind ? 2 : 1), renderdeltatics); + if (R_UsingFrameInterpolation()) // omg i fucking hate interp so much, its a bit smoother but still not great whatever, atleast like this shit wont completely go nuts when youre on high framerates + { + if (renderisnewtic) + { + upbary -= FixedMul(vid.dupy * (rewind ? 3 : 1.8f), 22937*3); + downbary += FixedMul(vid.dupy * (rewind ? 2 : 1), 22937*3); + } + } + else + { + upbary -= vid.dupy * (rewind ? 3 : 1.8f); + downbary += vid.dupy * (rewind ? 2 : 1); + } + if (upbary < -barsize) upbary = vid.height; if (downbary > vid.height) downbary = -barsize; +#ifdef HWRENDER + if ((rendermode == render_opengl)) + { + HWR_RenderVhsEffect(upbary, downbary, updistort, downdistort, barsize); + return; + } +#endif + for (y = 0; y < vid.height; y+=2) { thismapstart = normalmapstart;