From 6877930ed9f1b52c76117c64a9215ea0a51d49c9 Mon Sep 17 00:00:00 2001 From: Sryder13 Date: Fri, 8 Sep 2017 00:56:58 +0100 Subject: [PATCH 01/56] Go through and draw MD2s and sprites at the same time so they are sorted from each other (mostly) correctly --- src/hardware/hw_main.c | 67 ++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 05391f4d0..f38e67ce6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4914,7 +4914,8 @@ static void HWR_CreateDrawNodes(void) // Draw all vissprites // -------------------------------------------------------------------------- #ifdef SORTING -static void HWR_DrawSprites(void) +// added the stransform so they can be switched as drawing happenes so MD2s and sprites are sorted correctly with each other +static void HWR_DrawSprites(FTransform *stransform) { if (gr_visspritecount > 0) { @@ -4933,45 +4934,33 @@ static void HWR_DrawSprites(void) if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { if (!cv_grmd2.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) + { + HWD.pfnSetTransform(stransform); HWR_DrawSprite(spr); - } - else if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) - HWR_DrawSprite(spr); - } - } -} -#endif -// -------------------------------------------------------------------------- -// Draw all MD2 -// -------------------------------------------------------------------------- -static void HWR_DrawMD2S(void) -{ - if (gr_visspritecount > 0) - { - gr_vissprite_t *spr; - - // draw all MD2 back to front - for (spr = gr_vsprsortedhead.next; - spr != &gr_vsprsortedhead; - spr = spr->next) - { -#ifdef HWPRECIP - if (!spr->precip) - { -#endif - if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - { - if (md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound == false && md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale > 0.0f) + } + else + { + HWD.pfnSetTransform(&atransform); HWR_DrawMD2(spr); + } + } + else + { + if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + { + HWD.pfnSetTransform(stransform); + HWR_DrawSprite(spr); + } + else + { + HWD.pfnSetTransform(&atransform); + HWR_DrawMD2(spr); + } } - else if (md2_models[spr->mobj->sprite].notfound == false && md2_models[spr->mobj->sprite].scale > 0.0f) - HWR_DrawMD2(spr); -#ifdef HWPRECIP - } -#endif } } } +#endif // -------------------------------------------------------------------------- // HWR_AddSprites @@ -5644,12 +5633,9 @@ if (0) #ifdef SORTING HWR_SortVisSprites(); #endif - HWR_DrawMD2S(); - // Draw the sprites with trivial transform - HWD.pfnSetTransform(&stransform); #ifdef SORTING - HWR_DrawSprites(); + HWR_DrawSprites(&stransform); #endif #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? @@ -5874,12 +5860,9 @@ if (0) #ifdef SORTING HWR_SortVisSprites(); #endif - HWR_DrawMD2S(); - // Draw the sprites with trivial transform - HWD.pfnSetTransform(&stransform); #ifdef SORTING - HWR_DrawSprites(); + HWR_DrawSprites(&stransform); #endif #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? From db99537a6b67f2942c08680787a7215844770f87 Mon Sep 17 00:00:00 2001 From: Sryder13 Date: Sat, 9 Sep 2017 00:41:11 +0100 Subject: [PATCH 02/56] Various Transparent Texture Fixes Draw Textures and Flats that have holes in them like a solid polygon so they use the depth buffer and don't need to be sorted Disable all linear filtering on textures and flats that have holes in them, the linear filtering introduces translucency into the textures where the edges are. Leaving them with either a black border, or causing pixels behind the slightly translucent areas to not be drawn. Doesn't apply to sprites and the HUD as they are always already sorted properly. Make the Alpha Testing more strict on non-translucent blend modes. This makes it so any transparency below 0.5 is discarded instead. Would make anything that is blended and has holes in it look slightly better, only the HUD and MD2s where the texture has holes are effected currently. Set TF_TRANSPARENT on flat texture flags when there are holes in the texture. Minor fix to make sure MD2s always set the right blend mode --- src/hardware/hw_main.c | 30 +++++------------ src/hardware/r_opengl/r_opengl.c | 57 ++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f38e67ce6..971789122 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1072,7 +1072,6 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, /* SoM: split up and light walls according to the lightlist. This may also include leaving out parts of the wall that can't be seen */ - GLTexture_t * glTex; float realtop, realbot, top, bot; float pegt, pegb, pegmul; @@ -1238,11 +1237,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - glTex = HWR_GetTexture(texnum); + //glTex = HWR_GetTexture(texnum); if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); - else if (glTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); @@ -1298,11 +1295,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - glTex = HWR_GetTexture(texnum); + //glTex = HWR_GetTexture(texnum); if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); - else if (glTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); } @@ -2033,15 +2028,14 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } #endif - if (grTex->mipmap.flags & TF_TRANSPARENT) - blendmode = PF_Translucent; - if (gr_frontsector->numlights) { if (!(blendmode & PF_Masked)) HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_TRANSLUCENT); else + { HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTSOLIDS); + } } else if (!(blendmode & PF_Masked)) HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, blendmode, false, lightnum, colormap); @@ -2338,15 +2332,11 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { FBITFIELD blendmode = PF_Masked; - if (rover->flags & FF_TRANSLUCENT) + if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { blendmode = PF_Translucent; Surf.FlatColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; } - else if (grTex->mipmap.flags & TF_TRANSPARENT) - { - blendmode = PF_Environment; - } if (gr_frontsector->numlights) HWR_SplitWall(gr_frontsector, wallVerts, texnum, &Surf, rover->flags); @@ -2461,15 +2451,11 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { FBITFIELD blendmode = PF_Masked; - if (rover->flags & FF_TRANSLUCENT) + if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { blendmode = PF_Translucent; Surf.FlatColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; } - else if (grTex->mipmap.flags & TF_TRANSPARENT) - { - blendmode = PF_Environment; - } if (gr_backsector->numlights) HWR_SplitWall(gr_backsector, wallVerts, texnum, &Surf, rover->flags); @@ -3575,7 +3561,7 @@ static void HWR_Subsector(size_t num) alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } - else if (rover->flags & FF_TRANSLUCENT) // SoM: Flags are more efficient + else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) // SoM: Flags are more efficient { light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); #ifndef SORTING @@ -3638,7 +3624,7 @@ static void HWR_Subsector(size_t num) alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } - else if (rover->flags & FF_TRANSLUCENT) + else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); #ifndef SORTING diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index e6ff83e89..80df8afba 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1056,30 +1056,48 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) switch (PolyFlags & PF_Blending) { case PF_Translucent & PF_Blending: pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_NOTEQUAL, 0.0f); +#endif break; case PF_Masked & PF_Blending: // Hurdler: does that mean lighting is only made by alpha src? // it sounds ok, but not for polygonsmooth pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_GREATER, 0.5f); +#endif break; case PF_Additive & PF_Blending: #ifdef ATI_RAGE_PRO_COMPATIBILITY pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency #else pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest +#endif +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_NOTEQUAL, 0.0f); #endif break; case PF_Environment & PF_Blending: pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_NOTEQUAL, 0.0f); +#endif break; case PF_Substractive & PF_Blending: // good for shadow // not realy but what else ? pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_NOTEQUAL, 0.0f); +#endif break; default : // must be 0, otherwise it's an error // No blending pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_GREATER, 0.5f); +#endif break; } } @@ -1339,6 +1357,7 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) tex[w*j+i].s.green = 0; tex[w*j+i].s.blue = 0; tex[w*j+i].s.alpha = 0; + pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it } else { @@ -1409,8 +1428,22 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) tex_downloaded = pTexInfo->downloaded; pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues + if (pTexInfo->flags & TF_TRANSPARENT) + { +#ifdef KOS_GL_COMPATIBILITY + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NONE); +#else + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +#endif + } + else + { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + } #ifdef KOS_GL_COMPATIBILITY pglTexImage2D(GL_TEXTURE_2D, 0, GL_ARGB4444, w, h, 0, GL_ARGB4444, GL_UNSIGNED_BYTE, ptex); @@ -1865,12 +1898,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration ambient[1] = 0.75f; if (ambient[2] > 0.75f) ambient[2] = 0.75f; - - if (color[3] < 255) - { - pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - pglDepthMask(GL_FALSE); - } } pglEnable(GL_CULL_FACE); @@ -1897,10 +1924,12 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); #endif + if (color[3] < 255) + SetBlend(PF_Translucent|PF_Modulated|PF_Clip); + else + SetBlend(PF_Masked|PF_Modulated|PF_Occlude|PF_Clip); } - DrawPolygon(NULL, NULL, 0, PF_Masked|PF_Modulated|PF_Occlude|PF_Clip); - pglPushMatrix(); // should be the same as glLoadIdentity //Hurdler: now it seems to work pglTranslatef(pos->x, pos->z, pos->y); @@ -1908,14 +1937,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration scaley = -scaley; pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f); - //pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency - - // Remove depth mask when the model is transparent so it doesn't cut thorugh sprites // SRB2CBTODO: For all stuff too?! - if (color && color[3] < 255) - { - pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency - pglDepthMask(GL_FALSE); - } val = *gl_cmd_buffer++; From f3a605de6b12a947a9819561f711ee637107e46d Mon Sep 17 00:00:00 2001 From: Sryder13 Date: Fri, 15 Sep 2017 18:03:06 +0100 Subject: [PATCH 03/56] I need to stop leaving things commented out that are going --- src/hardware/hw_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 971789122..3a2b0f0ed 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1237,7 +1237,6 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - //glTex = HWR_GetTexture(texnum); if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); else @@ -1295,7 +1294,6 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - //glTex = HWR_GetTexture(texnum); if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); else From 8090ea4ed0469f23456f16636ba5b0fe3fba0aa3 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 30 Jan 2018 21:25:28 +0000 Subject: [PATCH 04/56] Stop leaking names. --- src/m_misc.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index 8193571e8..041899a3b 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -644,13 +644,12 @@ static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_byte movie) { #ifdef PNG_TEXT_SUPPORTED -#define SRB2PNGTXT 11 //PNG_KEYWORD_MAX_LENGTH(79) is the max +#define SRB2PNGTXT 10 //PNG_KEYWORD_MAX_LENGTH(79) is the max png_text png_infotext[SRB2PNGTXT]; char keytxt[SRB2PNGTXT][12] = { - "Title", "Author", "Description", "Playername", "Mapnum", "Mapname", + "Title", "Description", "Playername", "Mapnum", "Mapname", "Location", "Interface", "Revision", "Build Date", "Build Time"}; char titletxt[] = "Sonic Robo Blast 2 " VERSIONSTRING; - png_charp authortxt = I_GetUserName(); png_charp playertxt = cv_playername.zstring; char desctxt[] = "SRB2 Screenshot"; char Movietxt[] = "SRB2 Movie"; @@ -700,19 +699,18 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png png_infotext[i].key = keytxt[i]; png_infotext[0].text = titletxt; - png_infotext[1].text = authortxt; if (movie) - png_infotext[2].text = Movietxt; + png_infotext[1].text = Movietxt; else - png_infotext[2].text = desctxt; - png_infotext[3].text = playertxt; - png_infotext[4].text = maptext; - png_infotext[5].text = lvlttltext; - png_infotext[6].text = locationtxt; - png_infotext[7].text = interfacetxt; - png_infotext[8].text = strncpy(ctrevision, comprevision, sizeof(ctrevision)-1); - png_infotext[9].text = strncpy(ctdate, compdate, sizeof(ctdate)-1); - png_infotext[10].text = strncpy(cttime, comptime, sizeof(cttime)-1); + png_infotext[1].text = desctxt; + png_infotext[2].text = playertxt; + png_infotext[3].text = maptext; + png_infotext[4].text = lvlttltext; + png_infotext[5].text = locationtxt; + png_infotext[6].text = interfacetxt; + png_infotext[7].text = strncpy(ctrevision, comprevision, sizeof(ctrevision)-1); + png_infotext[8].text = strncpy(ctdate, compdate, sizeof(ctdate)-1); + png_infotext[9].text = strncpy(cttime, comptime, sizeof(cttime)-1); png_set_text(png_ptr, png_info_ptr, png_infotext, SRB2PNGTXT); #undef SRB2PNGTXT From 5adfdf9516ab99637af7b0bb05b8978b397ca0aa Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 30 Jan 2018 22:48:53 +0000 Subject: [PATCH 05/56] cv_playername already has a valid default value of "Sonic". We do NOT need to expose things like this. --- src/d_netcmd.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 3696dd974..673d64fd8 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -582,7 +582,6 @@ void D_RegisterServerCommands(void) */ void D_RegisterClientCommands(void) { - const char *username; INT32 i; for (i = 0; i < MAXSKINCOLORS; i++) @@ -639,8 +638,6 @@ void D_RegisterClientCommands(void) #endif // register these so it is saved to config - if ((username = I_GetUserName())) - cv_playername.defaultvalue = username; CV_RegisterVar(&cv_playername); CV_RegisterVar(&cv_playercolor); CV_RegisterVar(&cv_skin); // r_things.c (skin NAME) From c7320f9f8281bf7878da43ec7bab1c7b583bab37 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 14 Feb 2018 15:09:52 +0100 Subject: [PATCH 06/56] Don't allocate memory for net commands already executed, as it would cause them to be never freed --- src/d_clisrv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d48f223c7..004eed86f 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3984,7 +3984,8 @@ FILESTAMP INT32 k = *txtpak++; // playernum const size_t txtsize = txtpak[0]+1; - M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize); + if (i >= gametic) // Don't copy old net commands + M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize); txtpak += txtsize; } } From d921f26e54c1f9234a6eca2a31225ffe5372de32 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 17 Feb 2018 00:01:42 -0500 Subject: [PATCH 07/56] Don't init the sound system on dedicated servers --- src/d_main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 063d28453..ea24430ec 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1223,7 +1223,13 @@ void D_SRB2Main(void) CONS_Printf("R_Init(): Init SRB2 refresh daemon.\n"); R_Init(); - // setting up sound + // setting up sound + if (dedicated) + { + nosound = true; + nomidimusic = nodigimusic = true; + } + else CONS_Printf("S_Init(): Setting up sound.\n"); if (M_CheckParm("-nosound")) nosound = true; @@ -1239,7 +1245,7 @@ void D_SRB2Main(void) I_StartupSound(); I_InitMusic(); S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); - + CONS_Printf("ST_Init(): Init status bar.\n"); ST_Init(); From 36d1259cebcfb7f3ecf7be7469724379e87e3d31 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 17 Feb 2018 00:37:17 -0500 Subject: [PATCH 08/56] Removed some redundant checks --- src/sdl/sdl_sound.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 1a2cabd23..6c70c163b 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1180,12 +1180,6 @@ void I_StartupSound(void) audio.callback = I_UpdateStream; audio.userdata = &localdata; - if (dedicated) - { - nosound = nomidimusic = nodigimusic = true; - return; - } - // Configure sound device CONS_Printf("I_StartupSound:\n"); @@ -1481,9 +1475,6 @@ void I_InitMusic(void) I_AddExitFunc(I_ShutdownGMEMusic); #endif - if ((nomidimusic && nodigimusic) || dedicated) - return; - #ifdef HAVE_MIXER MIX_VERSION(&MIXcompiled) MIXlinked = Mix_Linked_Version(); From fb3e78c0205057de87222d9004cfafe0f74bc8f6 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 20 Feb 2018 17:06:03 +0000 Subject: [PATCH 09/56] Make CON_Responder eat Ctrl+key combos that have no effect, instead of passing the key on to G_Responder --- src/console.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/console.c b/src/console.c index 70f8ab6f8..267a91744 100644 --- a/src/console.c +++ b/src/console.c @@ -842,8 +842,9 @@ boolean CON_Responder(event_t *ev) return true; } - // don't eat the key - return false; + // ...why shouldn't it eat the key? if it doesn't, it just means you + // can control Sonic from the console, which is silly + return true; //return false; } // command completion forward (tab) and backward (shift-tab) From 6e21059713d7012bdd4244e0a21f36f764e25581 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 23 Feb 2018 20:08:02 +0000 Subject: [PATCH 10/56] Eat unprintable keys too, since there's no reason to feed them to G_Responder anyway when the console is open --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index 267a91744..3c06561ce 100644 --- a/src/console.c +++ b/src/console.c @@ -1043,7 +1043,7 @@ boolean CON_Responder(event_t *ev) // enter a char into the command prompt if (key < 32 || key > 127) - return false; + return true; // even if key can't be printed, eat it anyway // add key to cmd line here if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers From 1216c9da18b1d3c7e22d7a13c1d7f98040d82e27 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 23 Feb 2018 20:21:16 +0000 Subject: [PATCH 11/56] Use __linux__ instead of LINUX/LINUX64 Turns out compiling for Linux 32-bit using the Makefiles never actually defines LINUX! Apart from that, most of the existing Linux-specific code in SRB2's source code (except for tmap.s) actually uses __linux__ instead anyway --- src/sdl/i_system.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 3ad57559d..4675ac142 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2709,7 +2709,7 @@ const char *I_LocateWad(void) return waddir; } -#if defined(LINUX) || defined(LINUX64) +#ifdef __linux__ #define MEMINFO_FILE "/proc/meminfo" #define MEMTOTAL "MemTotal:" #define MEMFREE "MemFree:" @@ -2773,7 +2773,7 @@ UINT32 I_GetFreeMem(UINT32 *total) (PVOID) &pr_arena, sizeof (UINT32)); return pr_arena; -#elif defined (LINUX) || defined (LINUX64) +#elif defined (__linux__) /* Linux */ char buf[1024]; char *memTag; @@ -2822,7 +2822,7 @@ UINT32 I_GetFreeMem(UINT32 *total) if (total) *total = 48<<20; return 48<<20; -#endif /* LINUX */ +#endif } const CPUInfoFlags *I_CPUInfo(void) From 4a0305eec8e4646d171ccc527cb706175609a3ba Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 23 Feb 2018 20:40:19 +0000 Subject: [PATCH 12/56] more I_GetFreeMem fixes: don't attempt to set *total to 0L if total itself is NULL --- src/sdl/i_system.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 4675ac142..e86a39cab 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2729,20 +2729,23 @@ UINT32 I_GetFreeMem(UINT32 *total) }; if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) { - *total = 0L; + if (total) + *total = 0L; return 0; } if (kvm_nlist(kd, namelist) != 0) { kvm_close (kd); - *total = 0L; + if (total) + *total = 0L; return 0; } if (kvm_read(kd, namelist[X_SUM].n_value, &sum, sizeof (sum)) != sizeof (sum)) { kvm_close(kd); - *total = 0L; + if (total) + *total = 0L; return 0; } kvm_close(kd); @@ -2789,25 +2792,28 @@ UINT32 I_GetFreeMem(UINT32 *total) if (n < 0) { // Error - *total = 0L; + if (total) + *total = 0L; return 0; } buf[n] = '\0'; - if (NULL == (memTag = strstr(buf, MEMTOTAL))) + if ((memTag = strstr(buf, MEMTOTAL)) == NULL) { // Error - *total = 0L; + if (total) + *total = 0L; return 0; } memTag += sizeof (MEMTOTAL); totalKBytes = atoi(memTag); - if (NULL == (memTag = strstr(buf, MEMFREE))) + if ((memTag = strstr(buf, MEMFREE)) == NULL) { // Error - *total = 0L; + if (total) + *total = 0L; return 0; } From 1fe79a0d718bece374aa17b32c55c9a842137f6a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Mar 2018 19:08:53 +0000 Subject: [PATCH 13/56] Fix movies not recording the "extension" to special stage intro fades --- src/p_setup.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 8e746457b..52cd6ddbb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2565,6 +2565,7 @@ boolean P_SetupLevel(boolean skipprecip) { tic_t starttime = I_GetTime(); tic_t endtime = starttime + (3*TICRATE)/2; + tic_t nowtime; S_StartSound(NULL, sfx_s3kaf); @@ -2574,9 +2575,17 @@ boolean P_SetupLevel(boolean skipprecip) F_WipeEndScreen(); F_RunWipe(wipedefs[wipe_speclevel_towhite], false); + nowtime = lastwipetic; // Hold on white for extra effect. - while (I_GetTime() < endtime) - I_Sleep(); + while (nowtime < endtime) + { + // wait loop + while (!((nowtime = I_GetTime()) - lastwipetic)) + I_Sleep(); + lastwipetic = nowtime; + if (moviemode) // make sure we save frames for the white hold too + M_SaveFrame(); + } ranspecialwipe = 1; } From e3151f26dc901fb9762ba28a5558b0704e6113a9 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 5 Mar 2018 22:24:03 +0000 Subject: [PATCH 14/56] rewrite download file screen code: * fix screen to properly truncate the filename to just the real name only * if the real name itself is too long, use ellipsis and paste in parts of the start and end of the actual name note: I haven't actually tested if this works or compiles yet, I haven't the time right now --- src/d_clisrv.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 004eed86f..8783fb365 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1158,21 +1158,38 @@ static inline void CL_DrawConnectionStatus(void) { INT32 dldlength; static char tempname[32]; + fileneeded_t *file = &fileneeded[lastfilenum]; + char *filename = file->filename; Net_GetNetStat(); - dldlength = (INT32)((fileneeded[lastfilenum].currentsize/(double)fileneeded[lastfilenum].totalsize) * 256); + dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256); if (dldlength > 256) dldlength = 256; V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175); V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 160); memset(tempname, 0, sizeof(tempname)); - nameonly(strncpy(tempname, fileneeded[lastfilenum].filename, 31)); + // offset filename to just the name only part + filename += strlen(filename) - nameonlylength(filename); + + if (strlen(filename) > 31) // too long to display fully + { + size_t endhalfpos = strlen(filename)-12; + // display as first 16 chars + ... + last 12 chars + // which should add up to 31 if our math(s) is correct + strncpy(tempname, filename, 16); + strncpy(tempname+16, "...", 3); + strncpy(tempname+16+3, filename+endhalfpos, 12); + } + else // we can copy the whole thing in safely + { + strncpy(tempname, filename, 31); + } V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP, va(M_GetText("Downloading \"%s\""), tempname)); V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, - va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,fileneeded[lastfilenum].totalsize>>10)); + va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,file->totalsize>>10)); V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE, va("%3.1fK/s ", ((double)getbps)/1024)); } From a66824d63f5ed6eaeaca8afc518d5579247f0abb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 6 Mar 2018 20:20:27 +0000 Subject: [PATCH 15/56] replace the 3 strncpys with a snprintf --- src/d_clisrv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 8783fb365..46f8a9a10 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1177,9 +1177,7 @@ static inline void CL_DrawConnectionStatus(void) size_t endhalfpos = strlen(filename)-12; // display as first 16 chars + ... + last 12 chars // which should add up to 31 if our math(s) is correct - strncpy(tempname, filename, 16); - strncpy(tempname+16, "...", 3); - strncpy(tempname+16+3, filename+endhalfpos, 12); + snprintf(tempname, 31, "%.16s...%.12s", filename, filename+endhalfpos); } else // we can copy the whole thing in safely { From aba4adfabca9adb9c3aa85b680c78bc685cea02b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 6 Mar 2018 20:52:55 +0000 Subject: [PATCH 16/56] shrunk buffer from 32 to 28 so that all of "Downloading "extremely...longname.wad"" can fit on screen at once. --- src/d_clisrv.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 46f8a9a10..7d0e44b45 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1157,7 +1157,7 @@ static inline void CL_DrawConnectionStatus(void) if (lastfilenum != -1) { INT32 dldlength; - static char tempname[32]; + static char tempname[28]; fileneeded_t *file = &fileneeded[lastfilenum]; char *filename = file->filename; @@ -1172,16 +1172,16 @@ static inline void CL_DrawConnectionStatus(void) // offset filename to just the name only part filename += strlen(filename) - nameonlylength(filename); - if (strlen(filename) > 31) // too long to display fully + if (strlen(filename) > sizeof(tempname)-1) // too long to display fully { - size_t endhalfpos = strlen(filename)-12; - // display as first 16 chars + ... + last 12 chars - // which should add up to 31 if our math(s) is correct - snprintf(tempname, 31, "%.16s...%.12s", filename, filename+endhalfpos); + size_t endhalfpos = strlen(filename)-10; + // display as first 14 chars + ... + last 10 chars + // which should add up to 27 if our math(s) is correct + snprintf(tempname, sizeof(tempname), "%.14s...%.10s", filename, filename+endhalfpos); } else // we can copy the whole thing in safely { - strncpy(tempname, filename, 31); + strncpy(tempname, filename, sizeof(tempname)-1); } V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP, From 67ee1637c98688f5d9cae6ad781373b27e372c48 Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 6 Mar 2018 03:48:15 +0000 Subject: [PATCH 17/56] Decrease far clipping plane The Far clipping plane did not need to be nearly as high as it was, the new value is 32768, which I suspect is about how far software can render before it completely falls apart. It is desirable to increase the near clipping plane to between 6-10, but it can introduce more issues with close geometry not being drawn when the player or camera is scaled or viewheight is set to MIN in first person view. It would also stop sprites from being drawn ever so slightly too early, but this isn't too much of an issue and isn't too noticeable with those values. Might look into scaling near clipping plane in accordance to camera scale in the future. The reason for wanting to increase the near clipping plane is because the small value can cause very noticeable Z-fighting where there shouldn't be on older GPU's, usually Intel ones, that don't support 24-bits for the depth buffer. --- src/hardware/hw_defs.h | 4 ++-- src/hardware/hw_main.c | 13 +++++++------ src/hardware/r_opengl/r_opengl.c | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 70d776d9e..04802122e 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -20,8 +20,8 @@ #define _HWR_DEFS_ #include "../doomtype.h" -#define ZCLIP_PLANE 4.0f -#define NZCLIP_PLANE 0.9f +#define ZCLIP_PLANE 4.0f // Used for the actual game drawing +#define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures // ========================================================================== // SIMPLE TYPES diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3a2b0f0ed..3a1cf3d9b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5330,12 +5330,13 @@ static void HWR_DrawSkyBackground(player_t *player) //Hurdler: the sky is the only texture who need 4.0f instead of 1.0 // because it's called just after clearing the screen // and thus, the near clipping plane is set to 3.99 - v[0].x = v[3].x = -4.0f; - v[1].x = v[2].x = 4.0f; - v[0].y = v[1].y = -4.0f; - v[2].y = v[3].y = 4.0f; + // Sryder: Just use the near clipping plane value then + v[0].x = v[3].x = -ZCLIP_PLANE-1; + v[1].x = v[2].x = ZCLIP_PLANE+1; + v[0].y = v[1].y = -ZCLIP_PLANE-1; + v[2].y = v[3].y = ZCLIP_PLANE+1; - v[0].z = v[1].z = v[2].z = v[3].z = 4.0f; + v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1; // X @@ -5403,7 +5404,7 @@ static inline void HWR_ClearView(void) (INT32)gr_viewwindowy, (INT32)(gr_viewwindowx + gr_viewwidth), (INT32)(gr_viewwindowy + gr_viewheight), - 3.99f); + ZCLIP_PLANE); HWD.pfnClearBuffer(false, true, 0); //disable clip window - set to full size diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 2ee5c8a80..0ab2bdae8 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -59,7 +59,7 @@ typedef struct GLRGBAFloat GLRGBAFloat; #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) #define ASPECT_RATIO (1.0f) //(320.0f/200.0f) -#define FAR_CLIPPING_PLANE 150000.0f // Draw further! Tails 01-21-2001 +#define FAR_CLIPPING_PLANE 32768.0f // Draw further! Tails 01-21-2001 static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; // ************************************************************************** From 77af3a8f95c453cfd013cf37c97cfe03f5554e7f Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 7 Mar 2018 05:19:06 +0000 Subject: [PATCH 18/56] Optimise the screen texture setup for SDL2, Post-processor, and wipes. Only use glCopyTexImage2D when first creating the screen texture, use glCopyTexSubImage2D anytime after that as it does not define a new texture each time. Flushing of the screen textures has been implemented for when the screen size changes (so that the screen textures don't stay at a wrong size) and the game is closed, I believe they would leave a memory leak before. --- src/hardware/hw_drv.h | 2 + src/hardware/hw_main.c | 3 + src/hardware/r_opengl/r_opengl.c | 145 +++++++++++++++++++++++-------- src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + src/sdl12/hwsym_sdl.c | 1 + src/sdl12/i_video.c | 1 + src/win32/win_dll.c | 2 + 8 files changed, 122 insertions(+), 34 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 7672f47c2..a5ac82001 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -79,6 +79,7 @@ EXPORT char *HWRAPI(GetRenderer) (void); #define SCREENVERTS 10 EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); #endif +EXPORT void HWRAPI(FlushScreenTextures) (void); EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(EndScreenWipe) (void); EXPORT void HWRAPI(DoScreenWipe) (float alpha); @@ -124,6 +125,7 @@ struct hwdriver_s #ifdef SHUFFLE PostImgRedraw pfnPostImgRedraw; #endif + FlushScreenTextures pfnFlushScreenTextures; StartScreenWipe pfnStartScreenWipe; EndScreenWipe pfnEndScreenWipe; DoScreenWipe pfnDoScreenWipe; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3a1cf3d9b..d401bc374 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5443,6 +5443,8 @@ void HWR_SetViewSize(void) gr_pspritexscale = gr_viewwidth / BASEVIDWIDTH; gr_pspriteyscale = ((vid.height*gr_pspritexscale*BASEVIDWIDTH)/BASEVIDHEIGHT)/vid.width; + + HWD.pfnFlushScreenTextures(); } // ========================================================================== @@ -6036,6 +6038,7 @@ void HWR_Shutdown(void) HWR_FreeExtraSubsectors(); HWR_FreePolyPool(); HWR_FreeTextureCache(); + HWD.pfnFlushScreenTextures(); } void transform(float *cx, float *cy, float *cz) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 0ab2bdae8..9eb013a13 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -107,10 +107,19 @@ static GLint viewport[4]; #endif // Yay for arbitrary numbers! NextTexAvail is buggy for some reason. -static GLuint screentexture = 60000; -static GLuint startScreenWipe = 60001; -static GLuint endScreenWipe = 60002; -static GLuint finalScreenTexture = 60003; +// Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing +// flush all of the stored textures, leaving them unavailable at times such as between levels +// These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs +// can know when the textures aren't there, as textures are always considered resident in their virtual memory +// TODO: Store them in a more normal way +#define SCRTEX_SCREENTEXTURE 65535 +#define SCRTEX_STARTSCREENWIPE 65534 +#define SCRTEX_ENDSCREENWIPE 65533 +#define SCRTEX_FINALSCREENTEXTURE 65532 +static GLuint screentexture = 0; +static GLuint startScreenWipe = 0; +static GLuint endScreenWipe = 0; +static GLuint finalScreenTexture = 0; #if 0 GLuint screentexture = FIRST_TEX_AVAIL; #endif @@ -263,6 +272,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) /* texture mapping */ //GL_EXT_copy_texture #ifndef KOS_GL_COMPATIBILITY #define pglCopyTexImage2D glCopyTexImage2D +#define pglCopyTexSubImage2D glCopyTexSubImage2D #endif #else //!STATIC_OPENGL @@ -387,6 +397,8 @@ static PFNglBindTexture pglBindTexture; /* texture mapping */ //GL_EXT_copy_texture typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); static PFNglCopyTexImage2D pglCopyTexImage2D; +typedef void (APIENTRY * PFNglCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +static PFNglCopyTexSubImage2D pglCopyTexSubImage2D; #endif /* GLU functions */ typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data); @@ -503,6 +515,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglBindTexture , glBindTexture) GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D) + GETOPENGLFUNC(pglCopyTexSubImage2D , glCopyTexSubImage2D) #undef GETOPENGLFUNC @@ -654,6 +667,10 @@ void SetModelView(GLint w, GLint h) { // DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); + // The screen textures need to be flushed if the width or height change so that they be remade for the correct size + if (screen_width != w || screen_height != h) + FlushScreenTextures(); + screen_width = w; screen_height = h; @@ -801,6 +818,7 @@ void Flush(void) screentexture = FIRST_TEX_AVAIL; } #endif + tex_downloaded = 0; } @@ -2156,10 +2174,25 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) } #endif //SHUFFLE +// Sryder: This needs to be called whenever the screen changes resolution in order to reset the screen textures to use +// a new size +EXPORT void HWRAPI(FlushScreenTextures) (void) +{ + pglDeleteTextures(1, &screentexture); + pglDeleteTextures(1, &startScreenWipe); + pglDeleteTextures(1, &endScreenWipe); + pglDeleteTextures(1, &finalScreenTexture); + screentexture = 0; + startScreenWipe = 0; + endScreenWipe = 0; + finalScreenTexture = 0; +} + // Create Screen to fade from EXPORT void HWRAPI(StartScreenWipe) (void) { INT32 texsize = 2048; + boolean firstTime = (startScreenWipe == 0); // Use a power of two texture, dammit if(screen_width <= 512) @@ -2168,27 +2201,38 @@ EXPORT void HWRAPI(StartScreenWipe) (void) texsize = 1024; // Create screen texture + if (firstTime) + startScreenWipe = SCRTEX_STARTSCREENWIPE; pglBindTexture(GL_TEXTURE_2D, startScreenWipe); + + if (firstTime) + { #ifdef KOS_GL_COMPATIBILITY - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); #else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #endif - Clamp2D(GL_TEXTURE_WRAP_S); - Clamp2D(GL_TEXTURE_WRAP_T); + Clamp2D(GL_TEXTURE_WRAP_S); + Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); +#endif + } + else +#ifndef KOS_GL_COMPATIBILITY + pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); #endif - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + tex_downloaded = startScreenWipe; } // Create Screen to fade to EXPORT void HWRAPI(EndScreenWipe)(void) { INT32 texsize = 2048; + boolean firstTime = (endScreenWipe == 0); // Use a power of two texture, dammit if(screen_width <= 512) @@ -2197,21 +2241,32 @@ EXPORT void HWRAPI(EndScreenWipe)(void) texsize = 1024; // Create screen texture + if (firstTime) + endScreenWipe = SCRTEX_ENDSCREENWIPE; pglBindTexture(GL_TEXTURE_2D, endScreenWipe); + + if (firstTime) + { #ifdef KOS_GL_COMPATIBILITY - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); #else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #endif - Clamp2D(GL_TEXTURE_WRAP_S); - Clamp2D(GL_TEXTURE_WRAP_T); + Clamp2D(GL_TEXTURE_WRAP_S); + Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); +#endif + } + else +#ifndef KOS_GL_COMPATIBILITY + pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); #endif - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + + tex_downloaded = endScreenWipe; } @@ -2253,7 +2308,7 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void) pglEnd(); - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + tex_downloaded = screentexture; } // Do screen fades! @@ -2344,6 +2399,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha) pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit pglActiveTexture(GL_TEXTURE0); + tex_downloaded = endScreenWipe; } else { @@ -2369,11 +2425,10 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha) pglTexCoord2f(xfix, 0.0f); pglVertex3f(1.0f, -1.0f, 1.0f); pglEnd(); + tex_downloaded = endScreenWipe; #ifndef MINI_GL_COMPATIBILITY } #endif - - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now } @@ -2381,6 +2436,7 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha) EXPORT void HWRAPI(MakeScreenTexture) (void) { INT32 texsize = 2048; + boolean firstTime = (screentexture == 0); // Use a power of two texture, dammit if(screen_width <= 512) @@ -2389,7 +2445,12 @@ EXPORT void HWRAPI(MakeScreenTexture) (void) texsize = 1024; // Create screen texture + if (firstTime) + screentexture = SCRTEX_SCREENTEXTURE; pglBindTexture(GL_TEXTURE_2D, screentexture); + + if (firstTime) + { #ifdef KOS_GL_COMPATIBILITY pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); @@ -2400,15 +2461,21 @@ EXPORT void HWRAPI(MakeScreenTexture) (void) Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); +#endif + } + else +#ifndef KOS_GL_COMPATIBILITY + pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); #endif - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + tex_downloaded = screentexture; } EXPORT void HWRAPI(MakeScreenFinalTexture) (void) { INT32 texsize = 2048; + boolean firstTime = (finalScreenTexture == 0); // Use a power of two texture, dammit if(screen_width <= 512) @@ -2417,21 +2484,31 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void) texsize = 1024; // Create screen texture + if (firstTime) + finalScreenTexture = SCRTEX_FINALSCREENTEXTURE; pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); + + if (firstTime) + { #ifdef KOS_GL_COMPATIBILITY - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); #else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #endif - Clamp2D(GL_TEXTURE_WRAP_S); - Clamp2D(GL_TEXTURE_WRAP_T); + Clamp2D(GL_TEXTURE_WRAP_S); + Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); +#endif + } + else +#ifndef KOS_GL_COMPATIBILITY + pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); #endif - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + tex_downloaded = finalScreenTexture; } @@ -2476,7 +2553,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) SetModelView(screen_width, screen_height); SetStates(); - tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now + tex_downloaded = finalScreenTexture; } #endif //HWRENDER diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index f4686d2bf..05ac6450e 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -94,6 +94,7 @@ void *hwSym(const char *funcName,void *handle) #ifdef SHUFFLE GETFUNC(PostImgRedraw); #endif //SHUFFLE + GETFUNC(FlushScreenTextures); GETFUNC(StartScreenWipe); GETFUNC(EndScreenWipe); GETFUNC(DoScreenWipe); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 1bda0e180..87ce84158 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1442,6 +1442,7 @@ void I_StartupGraphics(void) #ifdef SHUFFLE HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); #endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); diff --git a/src/sdl12/hwsym_sdl.c b/src/sdl12/hwsym_sdl.c index 54f5da3a0..49340138f 100644 --- a/src/sdl12/hwsym_sdl.c +++ b/src/sdl12/hwsym_sdl.c @@ -100,6 +100,7 @@ void *hwSym(const char *funcName,void *handle) #ifdef SHUFFLE GETFUNC(PostImgRedraw); #endif //SHUFFLE + GETFUNC(FlushScreenTextures); GETFUNC(StartScreenWipe); GETFUNC(EndScreenWipe); GETFUNC(DoScreenWipe); diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index 197924eda..349e06cba 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -1972,6 +1972,7 @@ void I_StartupGraphics(void) #ifdef SHUFFLE HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); #endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index 8fa4d17f7..c9b3fba4e 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -117,6 +117,7 @@ static loadfunc_t hwdFuncTable[] = { #ifdef SHUFFLE {"PostImgRedraw@4", &hwdriver.pfnPostImgRedraw}, #endif + {"FlushScreenTextures@0",&hwdriver.pfnFlushScreenTextures}, {"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe}, {"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe}, {"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe}, @@ -147,6 +148,7 @@ static loadfunc_t hwdFuncTable[] = { #ifdef SHUFFLE {"PostImgRedraw", &hwdriver.pfnPostImgRedraw}, #endif + {"FlushScreenTextures"},&hwdriver.pfnFlushScreenTextures}, {"StartScreenWipe", &hwdriver.pfnStartScreenWipe}, {"EndScreenWipe", &hwdriver.pfnEndScreenWipe}, {"DoScreenWipe", &hwdriver.pfnDoScreenWipe}, From 121fcd83692d2e3946678bc270a80fe679247110 Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 8 Mar 2018 22:28:38 +0000 Subject: [PATCH 19/56] Fix screenshot functionality in fullscreen in SDL2 --- src/hardware/hw_draw.c | 14 ++++++ src/hardware/hw_drv.h | 6 +++ src/hardware/r_opengl/r_opengl.c | 79 ++++++++++++++++++++++++++++++++ src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + src/sdl12/hwsym_sdl.c | 1 + src/sdl12/i_video.c | 1 + 7 files changed, 103 insertions(+) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index f23753ee5..867a86a15 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -769,6 +769,9 @@ UINT8 *HWR_GetScreenshot(void) if (!buf) return NULL; // returns 24bit 888 RGB +#ifdef HAVE_SDL + if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf)) +#endif HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); return buf; } @@ -782,8 +785,19 @@ boolean HWR_Screenshot(const char *lbmname) return false; // returns 24bit 888 RGB +#ifdef HAVE_SDL + // Sryder: SDL2 uses borderless fullscreen mode, and creates a screen texture to upscale to the screen size. + // This breaks screenshots because the code here takes a screenshot of just the resolution from the bottom + // left corner, while the "true" resolution is the monitor resolution. We can either take a screenshot of + // the true resolution or just use the already made screen texture + // NOTE: The SDL1.2 version should get a return of false from ReadScreenTexture as no screen texture will have + // been made, this will also mean that if the screen texture doesn't exist for some reason it will fall + // back to the old version + if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf)) +#endif HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); + #ifdef USE_PNG ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL); #else diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index a5ac82001..ab4025697 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -58,6 +58,9 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data); +#ifdef HAVE_SDL +EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 * dst_data); +#endif EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); EXPORT void HWRAPI(ClearMipMapCache) (void); @@ -104,6 +107,9 @@ struct hwdriver_s ClearBuffer pfnClearBuffer; SetTexture pfnSetTexture; ReadRect pfnReadRect; +#ifdef HAVE_SDL + ReadScreenTexture pfnReadScreenTexture; +#endif GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 9eb013a13..fb8555aa9 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -260,6 +260,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglTexEnvi glTexEnvi #define pglTexParameteri glTexParameteri #define pglTexImage2D glTexImage2D +#define pglGetTexImage glGetTexImage /* Fog */ #define pglFogf glFogf @@ -381,6 +382,8 @@ typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint static PFNglTexParameteri pglTexParameteri; typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static PFNglTexImage2D pglTexImage2D; +typedef void (APIENTRY * PFNglGetTexImage) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +static PFNglGetTexImage pglGetTexImage; /* Fog */ typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param); @@ -507,6 +510,7 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglTexEnvi , glTexEnvi) GETOPENGLFUNC(pglTexParameteri , glTexParameteri) GETOPENGLFUNC(pglTexImage2D , glTexImage2D) + GETOPENGLFUNC(pglGetTexImage , glGetTexImage) GETOPENGLFUNC(pglFogf , glFogf) GETOPENGLFUNC(pglFogfv , glFogfv) @@ -933,6 +937,81 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, #endif } +#ifdef HAVE_SDL +EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width, + INT32 height, INT32 dst_stride, + UINT16 * dst_data) +{ +#ifdef KOS_GL_COMPATIBILITY + (void)x; + (void)y; + (void)width; + (void)height; + (void)dst_stride; + (void)dst_data; +#else + INT32 i, j; + INT32 texsize = 2048; + GLubyte *image; + // DBG_Printf ("ReadScreenTexture()\n"); + if (screentexture == 0) + return false; // No screen texture + + if(screen_width <= 1024) + texsize = 1024; + if(screen_width <= 512) + texsize = 512; + + if (x < 0) + x = 0; + if (x + width > screen_width) + width = screen_width - x; + if (y < 0) + y = 0; + if (y + height > screen_height) + height = screen_height - y; + + image = malloc(texsize*texsize*3*sizeof (*image)); + if (!image) + return false; + pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); + tex_downloaded = finalScreenTexture; + pglGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image); + + if (dst_stride == width*3) + { + UINT8 *dest = (void *)dst_data; + for (i = y + height-1; i >= y; i--) + { + for (j = x; j < width + x; j++) + { + dest[((height-1-i-y)*width+j-x)*3] = image[(i*texsize+j)*3]; + dest[((height-1-i-y)*width+j-x)*3+1] = image[(i*texsize+j)*3+1]; + dest[((height-1-i-y)*width+j-x)*3+2] = image[(i*texsize+j)*3+2]; + } + } + } + else + { + // Sryder: NOTE: I'm not entirely sure this works, as far as I know nothing in the game uses it. + for (i = y + height-1; i >= y; i--) + { + for (j = x; j < width + x; j++) + { + dst_data[(height-1-i-y)*width+j-x] = + (UINT16)( + ((image[(i*texsize+j)*3]>>3)<<11) | + ((image[(i*texsize+j)*3+1]>>2)<<5) | + ((image[(i*texsize+j)*3+2]>>3))); + } + } + } + free(image); + return true; +#endif +} +#endif + // -----------------+ // GClipRect : Defines the 2D hardware clipping window diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 05ac6450e..33bcfd6f3 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -83,6 +83,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearBuffer); GETFUNC(SetTexture); GETFUNC(ReadRect); + GETFUNC(ReadScreenTexture); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); GETFUNC(SetSpecialState); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 87ce84158..2df8a6ff5 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1430,6 +1430,7 @@ void I_StartupGraphics(void) HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); diff --git a/src/sdl12/hwsym_sdl.c b/src/sdl12/hwsym_sdl.c index 49340138f..3a10d8253 100644 --- a/src/sdl12/hwsym_sdl.c +++ b/src/sdl12/hwsym_sdl.c @@ -89,6 +89,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearBuffer); GETFUNC(SetTexture); GETFUNC(ReadRect); + GETFUNC(ReadScreenTexture); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); GETFUNC(SetSpecialState); diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index 349e06cba..076ce4fd2 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -1960,6 +1960,7 @@ void I_StartupGraphics(void) HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); From e4ed3a793b7ad37db1ecb8cc600f300af6b20c91 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 9 Mar 2018 09:58:10 +0000 Subject: [PATCH 20/56] Small hacky fix for MD2s and sprites until sorting for walls, floors, and sprites is done Sorts all translucent sprites and MD2s so they're drawn after all the opaque ones. Fixes most of the observable issues between translucent MD2s and opaque sprites/MD2s. --- src/hardware/hw_main.c | 30 ++++++++++++++++++++++++++++++ src/hardware/r_opengl/r_opengl.c | 1 - 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d401bc374..33cf54a38 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4565,6 +4565,33 @@ static void HWR_SortVisSprites(void) gr_vsprsortedhead.prev->next = best; gr_vsprsortedhead.prev = best; } + + // Sryder: Oh boy, while it's nice having ALL the sprites sorted properly, it fails when we bring MD2's into the + // mix and they want to be translucent. So let's place all the translucent sprites and MD2's AFTER + // everything else, but still ordered of course, the depth buffer can handle the opaque ones plenty fine. + // We just need to move all translucent ones to the end in order + // TODO: Fully sort all sprites and MD2s with walls and floors, this part will be unnecessary after that + best = gr_vsprsortedhead.next; + for (i = 0; i < gr_visspritecount; i++) + { + if ((best->mobj->flags2 & MF2_SHADOW) || (best->mobj->frame & FF_TRANSMASK)) + { + if (best == gr_vsprsortedhead.next) + { + gr_vsprsortedhead.next = best->next; + } + best->prev->next = best->next; + best->next->prev = best->prev; + best->prev = gr_vsprsortedhead.prev; + gr_vsprsortedhead.prev->next = best; + gr_vsprsortedhead.prev = best; + ds = best; + best = best->next; + ds->next = &gr_vsprsortedhead; + } + else + best = best->next; + } } // A drawnode is something that points to a 3D floor, 3D side, or masked @@ -4912,7 +4939,10 @@ static void HWR_DrawSprites(FTransform *stransform) { #ifdef HWPRECIP if (spr->precip) + { + HWD.pfnSetTransform(stransform); HWR_DrawPrecipitationSprite(spr); + } else #endif if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index fb8555aa9..14cff5995 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2100,7 +2100,6 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, if (color) pglDisable(GL_LIGHTING); pglShadeModel(GL_FLAT); - pglDepthMask(GL_TRUE); pglDisable(GL_CULL_FACE); } From aefe06e2ef61681a5c34b803e6cce739c12c7c52 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 9 Mar 2018 16:34:09 +0100 Subject: [PATCH 21/56] Fix Lua panic when archiving a table element with an userdata key --- src/lua_script.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index 167e4a0b4..ce96878bf 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -478,10 +478,10 @@ static const struct { {NULL, ARCH_NULL} }; -static UINT8 GetUserdataArchType(void) +static UINT8 GetUserdataArchType(int index) { UINT8 i; - lua_getmetatable(gL, -1); + lua_getmetatable(gL, index); for (i = 0; meta2arch[i].meta; i++) { @@ -560,7 +560,7 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) break; } case LUA_TUSERDATA: - switch (GetUserdataArchType()) + switch (GetUserdataArchType(myindex)) { case ARCH_MOBJINFO: { @@ -777,6 +777,7 @@ static void ArchiveTables(void) CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -1), luaL_typename(gL, -1)); lua_pop(gL, 1); } + lua_pop(gL, 1); } lua_pop(gL, 1); From 68cb91920508ada5962640a46afe041873933e31 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 14 Mar 2018 16:47:19 +0000 Subject: [PATCH 22/56] down with cis --- src/f_finale.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 692abb35f..17110df4f 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -969,7 +969,7 @@ static const char *credits[] = { "\1Programming", "Alam \"GBC\" Arias", "Logan \"GBA\" Arias", - "Tim \"RedEnchilada\" Bordelon", + "Colette \"fickle\" Bordelon", "Callum Dickinson", "Scott \"Graue\" Feeney", "Nathan \"Jazz\" Giroux", @@ -979,11 +979,11 @@ static const char *credits[] = { "John \"JTE\" Muniz", "Ehab \"Wolfy\" Saeed", "\"SSNTails\"", - "Matthew \"Inuyasha\" Walsh", + "\"Kaito Sinclaire\"", "", "\1Programming", "\1Assistance", - "\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom) + "\"chi.miru\"", // helped port slope drawing code from ZDoom "Andrew \"orospakr\" Clunis", "Gregor \"Oogaland\" Dick", "Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol) @@ -1047,7 +1047,7 @@ static const char *credits[] = { "Rob Tisdell", "Jarrett \"JEV3\" Voight", "Johnny \"Sonikku\" Wallbank", - "Matthew \"Inuyasha\" Walsh", + "\"Kaito Sinclaire\"", "Marco \"Digiku\" Zafra", "", "\1Boss Design", From a5ab9f01bbb9114af91b3073e845136a848192a9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 14 Mar 2018 16:49:10 +0000 Subject: [PATCH 23/56] oh yeah this guy's name needs changing too --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 17110df4f..36258664a 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1017,7 +1017,7 @@ static const char *credits[] = { "\1Music and Sound", "\1Production", "Malcolm \"RedXVI\" Brown", - "David \"Bulmybag\" Bulmer", + "Dave \"DemonTomatoDave\" Bulmer", "Paul \"Boinciel\" Clempson", "Cyan Helkaraxe", "Kepa \"Nev3r\" Iceta", From fee87141096949b139cd052f9f0e7a13861180e8 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 14 Mar 2018 16:55:33 +0000 Subject: [PATCH 24/56] i suck at the alphabet! --- src/f_finale.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 36258664a..0bcf24ed5 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -978,8 +978,8 @@ static const char *credits[] = { "Ronald \"Furyhunter\" Kinard", // The SDL2 port "John \"JTE\" Muniz", "Ehab \"Wolfy\" Saeed", - "\"SSNTails\"", "\"Kaito Sinclaire\"", + "\"SSNTails\"", "", "\1Programming", "\1Assistance", @@ -1041,13 +1041,13 @@ static const char *credits[] = { "Kepa \"Nev3r\" Iceta", "Thomas \"Shadow Hog\" Igoe", "Erik \"Torgo\" Nielsen", + "\"Kaito Sinclaire\"", "Wessel \"Spherallic\" Smit", "\"Spazzo\"", "\"SSNTails\"", "Rob Tisdell", "Jarrett \"JEV3\" Voight", "Johnny \"Sonikku\" Wallbank", - "\"Kaito Sinclaire\"", "Marco \"Digiku\" Zafra", "", "\1Boss Design", From 5a4ea9fab3d447abc5374ab24a361c43e6784ddf Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 15 Mar 2018 23:58:37 +0000 Subject: [PATCH 25/56] Better fog block colouring They still aren't perfect, but now they are at least not quite so obviously just translucent polygons over the level. A mixture between partially modulating the background colours and adding the fog colour. Notably white fog blocks look like they're brightening what's behind them. Additive was also setting noalphatest before, can probably decide that depending on what it needs anyway. I don't think it's currently used anyway. --- src/hardware/hw_defs.h | 5 ++-- src/hardware/hw_main.c | 40 +++++++++++++++----------------- src/hardware/r_opengl/r_opengl.c | 8 +++++++ 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 04802122e..c05ff3e79 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -133,12 +133,13 @@ enum EPolyFlags PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture) PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency - PF_Additive = 0x00000024, // Poly is added to the frame buffer + PF_Additive = 0x00000004, // Poly is added to the frame buffer PF_Environment = 0x00000008, // Poly should be drawn environment mapped. // Hurdler: used for text drawing PF_Substractive = 0x00000010, // for splat PF_NoAlphaTest = 0x00000020, // hiden param - PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive)&~PF_NoAlphaTest, + PF_Fog = 0x00000040, // Fog blocks + PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest, // other flag bits diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 33cf54a38..284c2c555 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -489,10 +489,10 @@ UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogbloc } -static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color, UINT32 fadecolor) // Let's see if this can work +static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this can work { - RGBA_t realcolor, fogcolor, surfcolor; - INT32 alpha, fogalpha; + RGBA_t realcolor, surfcolor; + INT32 alpha; // Don't go out of bounds if (light < 0) @@ -501,13 +501,11 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color, UINT32 fadecolor) // L light = 255; realcolor.rgba = color; - fogcolor.rgba = fadecolor; alpha = (realcolor.s.alpha*255)/25; - fogalpha = (fogcolor.s.alpha*255)/25; - // Fog blocks seem to get slightly more opaque with more opaque colourmap opacity, and much more opaque with darker brightness - surfcolor.s.alpha = (UINT8)(CALCLIGHT(light, ((0xFF-light)+alpha)/2)+CALCLIGHT(0xFF-light, ((light)+fogalpha)/2)); + // at 255 brightness, alpha is between 0 and 127, at 0 brightness alpha will always be 255 + surfcolor.s.alpha = (alpha*light)/(2*256)+255-light; return surfcolor.s.alpha; } @@ -773,7 +771,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, true); } - if (PolyFlags & PF_Translucent) + if (PolyFlags & (PF_Translucent|PF_Fog)) { Surf.FlatColor.s.alpha = (UINT8)alpha; PolyFlags |= PF_Modulated|PF_Occlude|PF_Clip; @@ -1380,7 +1378,7 @@ static void HWR_SplitFog(sector_t *sector, wallVert3D *wallVerts, FSurfaceInfo* wallVerts[0].y = wallVerts[1].y = bot; if (!solid) // Don't draw it if there's more fog behind it - HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Translucent|PF_NoTexture, true, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Fog|PF_NoTexture, true, lightnum, colormap); top = height; } @@ -2306,7 +2304,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { FBITFIELD blendmode; - blendmode = PF_Translucent|PF_NoTexture; + blendmode = PF_Fog|PF_NoTexture; lightnum = rover->master->frontsector->lightlevel; colormap = rover->master->frontsector->extra_colormap; @@ -2314,11 +2312,11 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (rover->master->frontsector->extra_colormap) { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba,rover->master->frontsector->extra_colormap->fadergba); + Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba); } else { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG,FADEFOG); + Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG); } if (gr_frontsector->numlights) @@ -2426,18 +2424,18 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { FBITFIELD blendmode; - blendmode = PF_Translucent|PF_NoTexture; + blendmode = PF_Fog|PF_NoTexture; lightnum = rover->master->frontsector->lightlevel; colormap = rover->master->frontsector->extra_colormap; if (rover->master->frontsector->extra_colormap) { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba,rover->master->frontsector->extra_colormap->fadergba); + Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba); } else { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG,FADEFOG); + Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG); } if (gr_backsector->numlights) @@ -3547,16 +3545,16 @@ static void HWR_Subsector(size_t num) light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); if (rover->master->frontsector->extra_colormap) - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba, rover->master->frontsector->extra_colormap->fadergba); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba); else - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG, FADEFOG); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); HWR_AddTransparentFloor(0, &extrasubsectors[num], false, *rover->bottomheight, *gr_frontsector->lightlist[light].lightlevel, - alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture, + alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) // SoM: Flags are more efficient @@ -3610,16 +3608,16 @@ static void HWR_Subsector(size_t num) light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); if (rover->master->frontsector->extra_colormap) - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba, rover->master->frontsector->extra_colormap->fadergba); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba); else - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG, FADEFOG); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); HWR_AddTransparentFloor(0, &extrasubsectors[num], true, *rover->topheight, *gr_frontsector->lightlist[light].lightlevel, - alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture, + alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 14cff5995..cf87c101e 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1187,6 +1187,14 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); #ifndef KOS_GL_COMPATIBILITY pglAlphaFunc(GL_NOTEQUAL, 0.0f); +#endif + break; + case PF_Fog & PF_Fog: + // Sryder: Fog + // multiplies input colour by input alpha, and destination colour by input colour, then adds them + pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR); +#ifndef KOS_GL_COMPATIBILITY + pglAlphaFunc(GL_NOTEQUAL, 0.0f); #endif break; default : // must be 0, otherwise it's an error From 1b3e1f78af6d58519a011eb84b55f3edf22e3cd0 Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 15 Mar 2018 23:59:01 +0000 Subject: [PATCH 26/56] Translucent floors shouldn't write into the depth buffer --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 284c2c555..83783072f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -774,7 +774,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (PolyFlags & (PF_Translucent|PF_Fog)) { Surf.FlatColor.s.alpha = (UINT8)alpha; - PolyFlags |= PF_Modulated|PF_Occlude|PF_Clip; + PolyFlags |= PF_Modulated|PF_Clip; } else PolyFlags |= PF_Masked|PF_Modulated|PF_Clip; From 7764a1bb5dcc8c91929c5c9a475e1f61633dce0c Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 16 Mar 2018 18:08:24 +0000 Subject: [PATCH 27/56] Match HWR_DrawFixedPatch to V_DrawFixedPatch --- src/hardware/hw_draw.c | 103 ++++++++++++++++++++++++++++++++--------- 1 file changed, 82 insertions(+), 21 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 867a86a15..30b0518cb 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -147,10 +147,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, // | /| // |/ | // 0--1 - float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; - float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; - float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale); - float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale); + float dupx, dupy, fscale, fwidth, fheight; if (alphalevel >= 10 && alphalevel < 13) return; @@ -161,40 +158,104 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, else HWR_GetMappedPatch(gpatch, colormap); + dupx = (float)vid.dupx; + dupy = (float)vid.dupy; + switch (option & V_SCALEPATCHMASK) { case V_NOSCALEPATCH: - pdupx = pdupy = 2.0f; + dupx = dupy = 1.0f; break; case V_SMALLSCALEPATCH: - pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); - pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); + dupx = (float)vid.smalldupx; + dupy = (float)vid.smalldupy; break; case V_MEDSCALEPATCH: - pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); - pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); + dupx = (float)vid.meddupx; + dupy = (float)vid.meddupy; break; } - if (option & V_NOSCALESTART) - sdupx = sdupy = 2.0f; + dupx = dupy = (dupx < dupy ? dupx : dupy); + fscale = FIXED_TO_FLOAT(pscale); - if (option & V_SPLITSCREEN) - sdupy /= 2.0f; - - if (option & V_FLIP) // Need to flip both this and sow + if (option & V_OFFSET) { - v[0].x = v[3].x = (cx*sdupx-(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; - v[2].x = v[1].x = (cx*sdupx+gpatch->leftoffset*pdupx)/vid.width - 1; + cx -= (float)gpatch->leftoffset * dupx * fscale; + cy -= (float)gpatch->topoffset * dupy * fscale; } else { - v[0].x = v[3].x = (cx*sdupx-gpatch->leftoffset*pdupx)/vid.width - 1; - v[2].x = v[1].x = (cx*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; + cy -= (float)gpatch->topoffset * fscale; + if (option & V_FLIP) + cx -= ((float)gpatch->width - (float)gpatch->leftoffset) * fscale; + else + cx -= (float)gpatch->leftoffset * fscale; } - v[0].y = v[1].y = 1-(cy*sdupy-gpatch->topoffset*pdupy)/vid.height; - v[2].y = v[3].y = 1-(cy*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height; + if (option & V_SPLITSCREEN) + cy /= 2; + + if (!(option & V_NOSCALESTART)) + { + cx = cx * dupx; + cy = cy * dupy; + + if (!(option & V_SCALEPATCHMASK)) + { + // centre screen + if (vid.width != BASEVIDWIDTH * vid.dupx) + { + if (option & V_SNAPTORIGHT) + cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(option & V_SNAPTOLEFT)) + cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2; + } + if (vid.height != BASEVIDHEIGHT * vid.dupy) + { + if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) + cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy)); + else if (option & V_SNAPTOBOTTOM) + cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(option & V_SNAPTOTOP)) + cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2; + } + // if it's meant to cover the whole screen, black out the rest + // TODO + /*if (x == 0 && SHORT(gpatch->width) == BASEVIDWIDTH && y == 0 && SHORT(gpatch->height) == BASEVIDHEIGHT) + { + const column_t *column = (const column_t *)((const UINT8 *)((patch_t *)gpatch) + LONG(((patch_t *)gpatch)->columnofs[0])); + const UINT8 *source = (const UINT8 *)(column) + 3; + HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); + }*/ + } + } + + if (pscale != FRACUNIT) + { + fwidth = (float)gpatch->width * fscale * dupx; + fheight = (float)gpatch->height * fscale * dupy; + } + else + { + fwidth = (float)gpatch->width * dupx; + fheight = (float)gpatch->height * dupy; + } + + // positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1 + cx = -1 + (cx / (vid.width/2)); + cy = 1 - (cy / (vid.height/2)); + + // fwidth and fheight are similar + fwidth /= vid.width / 2; + fheight /= vid.height / 2; + + // set the polygon vertices to the right positions + v[0].x = v[3].x = cx; + v[2].x = v[1].x = cx + fwidth; + + v[0].y = v[1].y = cy; + v[2].y = v[3].y = cy - fheight; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; From 7830c031f786e8820c7b29b9da7d2b5f094f75be Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 16 Mar 2018 19:46:45 +0000 Subject: [PATCH 28/56] Make HWR_DrawFill match V_DrawFill --- src/hardware/hw_draw.c | 81 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 30b0518cb..c9ba87786 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -717,7 +717,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) { FOutVector v[4]; FSurfaceInfo Surf; - float sdupx, sdupy; + float fx, fy, fw, fh; if (w < 0 || h < 0) return; // consistency w/ software @@ -726,16 +726,79 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) // | /| // |/ | // 0--1 - sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; - sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; - if (color & V_NOSCALESTART) - sdupx = sdupy = 2.0f; + fx = (float)x; + fy = (float)y; + fw = (float)w; + fh = (float)h; - v[0].x = v[3].x = (x*sdupx)/vid.width - 1; - v[2].x = v[1].x = (x*sdupx + w*sdupx)/vid.width - 1; - v[0].y = v[1].y = 1-(y*sdupy)/vid.height; - v[2].y = v[3].y = 1-(y*sdupy + h*sdupy)/vid.height; + if (!(color & V_NOSCALESTART)) + { + float dupx = (float)vid.dupx, dupy = (float)vid.dupy; + + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) + { + RGBA_t rgbaColour = V_GetColor(color); + FRGBAFloat clearColour; + clearColour.red = (float)rgbaColour.s.red / 255; + clearColour.green = (float)rgbaColour.s.green / 255; + clearColour.blue = (float)rgbaColour.s.blue / 255; + clearColour.alpha = 1; + HWD.pfnClearBuffer(true, false, &clearColour); + return; + } + + fx *= dupx; + fy *= dupy; + fw *= dupx; + fh *= dupy; + + if (vid.width != BASEVIDWIDTH * vid.dupx) + { + if (color & V_SNAPTORIGHT) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(color & V_SNAPTOLEFT)) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (color & V_SNAPTOBOTTOM) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(color & V_SNAPTOTOP)) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2; + } + } + + if (fx >= vid.width || fy >= vid.height) + return; + if (fx < 0) + { + fw += fx; + fx = 0; + } + if (fy < 0) + { + fh += fy; + fy = 0; + } + + if (fw <= 0 || fh <= 0) + return; + if (fx + fw > vid.width) + fw = (float)vid.width - fx; + if (fy + fh > vid.height) + fh = (float)vid.height - fy; + + fx = -1 + fx / (vid.width / 2); + fy = 1 - fy / (vid.height / 2); + fw = fw / (vid.width / 2); + fh = fh / (vid.height / 2); + + v[0].x = v[3].x = fx; + v[2].x = v[1].x = fx + fw; + v[0].y = v[1].y = fy; + v[2].y = v[3].y = fy - fh; //Hurdler: do we still use this argb color? if not, we should remove it v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; From 801f7547d3893a338fa40fe86afeeab46a60f87d Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 17 Mar 2018 13:26:43 +0000 Subject: [PATCH 29/56] Add the full-screen drawfill functionality to HWR_DrawFixedPatch --- src/hardware/hw_draw.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index c9ba87786..8b5c2f76c 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -203,6 +203,18 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (!(option & V_SCALEPATCHMASK)) { + // if it's meant to cover the whole screen, black out the rest + // cx and cy are possibly *slightly* off from float maths + // This is done before here compared to software because we directly alter cx and cy to centre + if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) + { + // Need to temporarily cache the real patch to get the colour of the top left pixel + patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); + const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); + const UINT8 *source = (const UINT8 *)(column) + 3; + HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); + Z_Free(realpatch); + } // centre screen if (vid.width != BASEVIDWIDTH * vid.dupx) { @@ -220,14 +232,6 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, else if (!(option & V_SNAPTOTOP)) cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2; } - // if it's meant to cover the whole screen, black out the rest - // TODO - /*if (x == 0 && SHORT(gpatch->width) == BASEVIDWIDTH && y == 0 && SHORT(gpatch->height) == BASEVIDHEIGHT) - { - const column_t *column = (const column_t *)((const UINT8 *)((patch_t *)gpatch) + LONG(((patch_t *)gpatch)->columnofs[0])); - const UINT8 *source = (const UINT8 *)(column) + 3; - HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); - }*/ } } From a9214ebd378414401d67c3beb720bcd7b8b1ecf3 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 17 Mar 2018 13:58:44 +0000 Subject: [PATCH 30/56] Match HWR_DrawCroppedPatch to V_DrawCroppedPatch --- src/hardware/hw_draw.c | 108 +++++++++++++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 15 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 8b5c2f76c..14e9b6f54 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -312,10 +312,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal // | /| // |/ | // 0--1 - float sdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f; - float sdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f; - float pdupx = FIXED_TO_FLOAT(vid.fdupx)*2.0f*FIXED_TO_FLOAT(pscale); - float pdupy = FIXED_TO_FLOAT(vid.fdupy)*2.0f*FIXED_TO_FLOAT(pscale); + float dupx, dupy, fscale, fwidth, fheight; if (alphalevel >= 10 && alphalevel < 13) return; @@ -323,28 +320,109 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal // make patch ready in hardware cache HWR_GetPatch(gpatch); + dupx = (float)vid.dupx; + dupy = (float)vid.dupy; + switch (option & V_SCALEPATCHMASK) { case V_NOSCALEPATCH: - pdupx = pdupy = 2.0f; + dupx = dupy = 1.0f; break; case V_SMALLSCALEPATCH: - pdupx = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupx); - pdupy = 2.0f * FIXED_TO_FLOAT(vid.fsmalldupy); + dupx = (float)vid.smalldupx; + dupy = (float)vid.smalldupy; break; case V_MEDSCALEPATCH: - pdupx = 2.0f * FIXED_TO_FLOAT(vid.fmeddupx); - pdupy = 2.0f * FIXED_TO_FLOAT(vid.fmeddupy); + dupx = (float)vid.meddupx; + dupy = (float)vid.meddupy; break; } - if (option & V_NOSCALESTART) - sdupx = sdupy = 2.0f; + dupx = dupy = (dupx < dupy ? dupx : dupy); + fscale = FIXED_TO_FLOAT(pscale); - v[0].x = v[3].x = (cx*sdupx - gpatch->leftoffset * pdupx) / vid.width - 1; - v[2].x = v[1].x = (cx*sdupx + ((w-sx) - gpatch->leftoffset) * pdupx) / vid.width - 1; - v[0].y = v[1].y = 1 - (cy*sdupy - gpatch->topoffset * pdupy) / vid.height; - v[2].y = v[3].y = 1 - (cy*sdupy + ((h-sy) - gpatch->topoffset) * pdupy) / vid.height; + cy -= (float)gpatch->topoffset * fscale; + cx -= (float)gpatch->leftoffset * fscale; + + if (!(option & V_NOSCALESTART)) + { + cx = cx * dupx; + cy = cy * dupy; + + if (!(option & V_SCALEPATCHMASK)) + { + // if it's meant to cover the whole screen, black out the rest + // cx and cy are possibly *slightly* off from float maths + // This is done before here compared to software because we directly alter cx and cy to centre + if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) + { + // Need to temporarily cache the real patch to get the colour of the top left pixel + patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); + const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); + const UINT8 *source = (const UINT8 *)(column) + 3; + HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); + Z_Free(realpatch); + } + // centre screen + if (vid.width != BASEVIDWIDTH * vid.dupx) + { + if (option & V_SNAPTORIGHT) + cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(option & V_SNAPTOLEFT)) + cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2; + } + if (vid.height != BASEVIDHEIGHT * vid.dupy) + { + if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) + cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy)); + else if (option & V_SNAPTOBOTTOM) + cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(option & V_SNAPTOTOP)) + cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2; + } + } + } + + fwidth = w; + fheight = h; + + if (fwidth > w - sx) + fwidth = w - sx; + + if (fheight > h - sy) + fheight = h - sy; + + if (fwidth > gpatch->width) + fwidth = gpatch->width; + + if (fheight > gpatch->height) + fheight = gpatch->height; + + if (pscale != FRACUNIT) + { + fwidth *= fscale * dupx; + fheight *= fscale * dupy; + } + else + { + fwidth *= dupx; + fheight *= dupy; + } + + // positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1 + cx = -1 + (cx / (vid.width/2)); + cy = 1 - (cy / (vid.height/2)); + + // fwidth and fheight are similar + fwidth /= vid.width / 2; + fheight /= vid.height / 2; + + // set the polygon vertices to the right positions + v[0].x = v[3].x = cx; + v[2].x = v[1].x = cx + fwidth; + + v[0].y = v[1].y = cy; + v[2].y = v[3].y = cy - fheight; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; From 6de0cc6bccb02529107cc2c7a093969784214d6f Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 17 Mar 2018 14:47:06 +0000 Subject: [PATCH 31/56] Remove the OpenGL only code from V_DrawPatchFill That's all of the HUD drawing functions that are currently used updated in GL. --- src/v_video.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index cc81cedbc..161c03d0b 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -937,14 +937,6 @@ void V_DrawPatchFill(patch_t *pat) INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; -#ifdef HWRENDER - if (rendermode == render_opengl) - { - pw = FixedMul(SHORT(pat->width)*FRACUNIT, vid.fdupx)>>FRACBITS; - ph = FixedMul(SHORT(pat->height)*FRACUNIT, vid.fdupy)>>FRACBITS; - } -#endif - for (x = 0; x < vid.width; x += pw) { for (y = 0; y < vid.height; y += ph) From 527df5c248cbb9e453355cdd9a14aa8698dea00e Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 17 Mar 2018 15:11:32 +0000 Subject: [PATCH 32/56] Fix OpenGL Title Screen Sky My IDE doesn't seem to like Vada's name. --- src/f_finale.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 692abb35f..f2a9f4038 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -233,11 +233,19 @@ static void F_SkyScroll(INT32 scrollspeed) #ifdef HWRENDER else if (rendermode != render_none) { // if only software rendering could be this simple and retarded - scrolled = animtimer; - if (scrolled > 0) - V_DrawScaledPatch(scrolled - SHORT(pat->width), 0, 0, pat); - for (x = 0; x < fakedwidth; x += SHORT(pat->width)) - V_DrawScaledPatch(x + scrolled, 0, 0, pat); + INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); + INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; + scrolled = animtimer * dupz; + for (x = 0; x < vid.width; x += pw) + { + for (y = 0; y < vid.height; y += ph) + { + if (scrolled > 0) + V_DrawScaledPatch(scrolled - pw, y, V_NOSCALESTART, pat); + + V_DrawScaledPatch(x + scrolled, y, V_NOSCALESTART, pat); + } + } } #endif @@ -999,7 +1007,7 @@ static const char *credits[] = { "", "\1Sprite Artists", "Odi \"Iceman404\" Atunzu", - "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: + "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: "Jim \"MotorRoach\" DeMello", "Desmond \"Blade\" DesJardins", "Sherman \"CoatRack\" DesJardins", From 31d1ef8db05c77a755d243c6b612fd32886cbc45 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 17 Mar 2018 19:22:14 +0000 Subject: [PATCH 33/56] Draw the final screen texture in the centre with black bars Only applies when the monitor aspect ratio is different to the game's aspect ratio. --- src/hardware/r_opengl/r_opengl.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index cf87c101e..026d0126b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2601,6 +2601,9 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void) EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) { float xfix, yfix; + float origaspect, newaspect; + float xoff = 1, yoff = 1; // xoffset and yoffset for the polygon to have black bars around the screen + FRGBAFloat clearColour; INT32 texsize = 2048; if(screen_width <= 1024) @@ -2611,28 +2614,43 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) xfix = 1/((float)(texsize)/((float)((screen_width)))); yfix = 1/((float)(texsize)/((float)((screen_height)))); - //pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + origaspect = (float)screen_width / screen_height; + newaspect = (float)width / height; + if (origaspect < newaspect) + { + xoff = origaspect / newaspect; + yoff = 1; + } + else if (origaspect > newaspect) + { + xoff = 1; + yoff = newaspect / origaspect; + } + pglViewport(0, 0, width, height); + clearColour.red = clearColour.green = clearColour.blue = 0; + clearColour.alpha = 1; + ClearBuffer(true, false, &clearColour); pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglBegin(GL_QUADS); pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); // Bottom left pglTexCoord2f(0.0f, 0.0f); - pglVertex3f(-1, -1, 1.0f); + pglVertex3f(-xoff, -yoff, 1.0f); // Top left pglTexCoord2f(0.0f, yfix); - pglVertex3f(-1, 1, 1.0f); + pglVertex3f(-xoff, yoff, 1.0f); // Top right pglTexCoord2f(xfix, yfix); - pglVertex3f(1, 1, 1.0f); + pglVertex3f(xoff, yoff, 1.0f); // Bottom right pglTexCoord2f(xfix, 0.0f); - pglVertex3f(1, -1, 1.0f); + pglVertex3f(xoff, -yoff, 1.0f); pglEnd(); From a984d979d113e119ca64ca4e53693064470c22f9 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 18 Mar 2018 17:12:12 +0000 Subject: [PATCH 34/56] Fix wipes in low resolutions --- src/hardware/r_opengl/r_opengl.c | 15 ++++++--------- src/sdl/ogl_sdl.c | 7 +++++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 026d0126b..5d861e618 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2538,14 +2538,14 @@ EXPORT void HWRAPI(MakeScreenTexture) (void) if (firstTime) { #ifdef KOS_GL_COMPATIBILITY - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER_NONE); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER_NONE); #else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #endif - Clamp2D(GL_TEXTURE_WRAP_S); - Clamp2D(GL_TEXTURE_WRAP_T); + Clamp2D(GL_TEXTURE_WRAP_S); + Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); #endif @@ -2654,9 +2654,6 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) pglEnd(); - SetModelView(screen_width, screen_height); - SetStates(); - tex_downloaded = finalScreenTexture; } diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index cd7ced7ca..4347b35b2 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -214,8 +214,11 @@ void OglSdlFinishUpdate(boolean waitvbl) HWR_DrawScreenFinalTexture(sdlw, sdlh); SDL_GL_SwapWindow(window); - SetModelView(realwidth, realheight); - SetStates(); + GClipRect(0, 0, realwidth, realheight, 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 + HWR_DrawScreenFinalTexture(realwidth, realheight); } EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) From f3d63b82cedd57b668d334607d4d22f935c3381d Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 18 Mar 2018 18:31:51 +0000 Subject: [PATCH 35/56] Revert "Fix screenshot functionality in fullscreen in SDL2" This reverts commit 121fcd83692d2e3946678bc270a80fe679247110. The reason I am reverting this is because the last commit actually fixes the *old* screenshot functionality, as the screen is being drawn back onto the buffer after they're swapped in the "real" size. Meaning the old function actually works perfectly fine now. --- src/hardware/hw_draw.c | 14 ------ src/hardware/hw_drv.h | 6 --- src/hardware/r_opengl/r_opengl.c | 79 -------------------------------- src/sdl/hwsym_sdl.c | 1 - src/sdl/i_video.c | 1 - src/sdl12/hwsym_sdl.c | 1 - src/sdl12/i_video.c | 1 - 7 files changed, 103 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 14e9b6f54..84081dd25 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -975,9 +975,6 @@ UINT8 *HWR_GetScreenshot(void) if (!buf) return NULL; // returns 24bit 888 RGB -#ifdef HAVE_SDL - if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf)) -#endif HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); return buf; } @@ -991,19 +988,8 @@ boolean HWR_Screenshot(const char *lbmname) return false; // returns 24bit 888 RGB -#ifdef HAVE_SDL - // Sryder: SDL2 uses borderless fullscreen mode, and creates a screen texture to upscale to the screen size. - // This breaks screenshots because the code here takes a screenshot of just the resolution from the bottom - // left corner, while the "true" resolution is the monitor resolution. We can either take a screenshot of - // the true resolution or just use the already made screen texture - // NOTE: The SDL1.2 version should get a return of false from ReadScreenTexture as no screen texture will have - // been made, this will also mean that if the screen texture doesn't exist for some reason it will fall - // back to the old version - if (!HWD.pfnReadScreenTexture(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf)) -#endif HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); - #ifdef USE_PNG ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL); #else diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index ab4025697..a5ac82001 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -58,9 +58,6 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data); -#ifdef HAVE_SDL -EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 * dst_data); -#endif EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); EXPORT void HWRAPI(ClearMipMapCache) (void); @@ -107,9 +104,6 @@ struct hwdriver_s ClearBuffer pfnClearBuffer; SetTexture pfnSetTexture; ReadRect pfnReadRect; -#ifdef HAVE_SDL - ReadScreenTexture pfnReadScreenTexture; -#endif GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 5d861e618..8e3ae3e21 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -260,7 +260,6 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglTexEnvi glTexEnvi #define pglTexParameteri glTexParameteri #define pglTexImage2D glTexImage2D -#define pglGetTexImage glGetTexImage /* Fog */ #define pglFogf glFogf @@ -382,8 +381,6 @@ typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint static PFNglTexParameteri pglTexParameteri; typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static PFNglTexImage2D pglTexImage2D; -typedef void (APIENTRY * PFNglGetTexImage) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); -static PFNglGetTexImage pglGetTexImage; /* Fog */ typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param); @@ -510,7 +507,6 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglTexEnvi , glTexEnvi) GETOPENGLFUNC(pglTexParameteri , glTexParameteri) GETOPENGLFUNC(pglTexImage2D , glTexImage2D) - GETOPENGLFUNC(pglGetTexImage , glGetTexImage) GETOPENGLFUNC(pglFogf , glFogf) GETOPENGLFUNC(pglFogfv , glFogfv) @@ -937,81 +933,6 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, #endif } -#ifdef HAVE_SDL -EXPORT boolean HWRAPI(ReadScreenTexture) (INT32 x, INT32 y, INT32 width, - INT32 height, INT32 dst_stride, - UINT16 * dst_data) -{ -#ifdef KOS_GL_COMPATIBILITY - (void)x; - (void)y; - (void)width; - (void)height; - (void)dst_stride; - (void)dst_data; -#else - INT32 i, j; - INT32 texsize = 2048; - GLubyte *image; - // DBG_Printf ("ReadScreenTexture()\n"); - if (screentexture == 0) - return false; // No screen texture - - if(screen_width <= 1024) - texsize = 1024; - if(screen_width <= 512) - texsize = 512; - - if (x < 0) - x = 0; - if (x + width > screen_width) - width = screen_width - x; - if (y < 0) - y = 0; - if (y + height > screen_height) - height = screen_height - y; - - image = malloc(texsize*texsize*3*sizeof (*image)); - if (!image) - return false; - pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); - tex_downloaded = finalScreenTexture; - pglGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image); - - if (dst_stride == width*3) - { - UINT8 *dest = (void *)dst_data; - for (i = y + height-1; i >= y; i--) - { - for (j = x; j < width + x; j++) - { - dest[((height-1-i-y)*width+j-x)*3] = image[(i*texsize+j)*3]; - dest[((height-1-i-y)*width+j-x)*3+1] = image[(i*texsize+j)*3+1]; - dest[((height-1-i-y)*width+j-x)*3+2] = image[(i*texsize+j)*3+2]; - } - } - } - else - { - // Sryder: NOTE: I'm not entirely sure this works, as far as I know nothing in the game uses it. - for (i = y + height-1; i >= y; i--) - { - for (j = x; j < width + x; j++) - { - dst_data[(height-1-i-y)*width+j-x] = - (UINT16)( - ((image[(i*texsize+j)*3]>>3)<<11) | - ((image[(i*texsize+j)*3+1]>>2)<<5) | - ((image[(i*texsize+j)*3+2]>>3))); - } - } - } - free(image); - return true; -#endif -} -#endif - // -----------------+ // GClipRect : Defines the 2D hardware clipping window diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 33bcfd6f3..05ac6450e 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -83,7 +83,6 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearBuffer); GETFUNC(SetTexture); GETFUNC(ReadRect); - GETFUNC(ReadScreenTexture); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); GETFUNC(SetSpecialState); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 2df8a6ff5..87ce84158 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1430,7 +1430,6 @@ void I_StartupGraphics(void) HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); diff --git a/src/sdl12/hwsym_sdl.c b/src/sdl12/hwsym_sdl.c index 3a10d8253..49340138f 100644 --- a/src/sdl12/hwsym_sdl.c +++ b/src/sdl12/hwsym_sdl.c @@ -89,7 +89,6 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearBuffer); GETFUNC(SetTexture); GETFUNC(ReadRect); - GETFUNC(ReadScreenTexture); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); GETFUNC(SetSpecialState); diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index 076ce4fd2..349e06cba 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -1960,7 +1960,6 @@ void I_StartupGraphics(void) HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); From 4e95066f5ac700bd868c140c90394bd94a9c2fad Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 20 Mar 2018 14:20:02 +0000 Subject: [PATCH 36/56] Some fixes and updates for HWR_SplitWall Solid walls *can* be cut Fix issues with water and fog FOFs not cutting each other out correctly Fix Fog colourmap and lighting setting that is done here. Remove HWR_SplitFog There is currently a bug with FF_DOUBLESHADOW (that also exists in software) but has a larger impact here. When 2 FF_DOUBLESHADOW lights are directly stacked on each other the bottom one has its height set incorrectly. This causes all the Fog in the timed gravity flipping section of ERZ2 to be drawn and it looks really bad. --- src/hardware/hw_main.c | 246 +++++++++++++---------------------------- 1 file changed, 76 insertions(+), 170 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 83783072f..c4e3d879e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1065,7 +1065,7 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) // // HWR_SplitWall // -static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, FSurfaceInfo* Surf, UINT32 cutflag) +static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, FSurfaceInfo* Surf, UINT32 cutflag, ffloor_t *pfloor) { /* SoM: split up and light walls according to the lightlist. This may also include leaving out parts @@ -1093,7 +1093,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, lightlist_t * list = sector->lightlist; const UINT8 alpha = Surf->FlatColor.s.alpha; FUINT lightnum; - extracolormap_t *colormap; + extracolormap_t *colormap = NULL; realtop = top = wallVerts[3].y; realbot = bot = wallVerts[0].y; @@ -1109,7 +1109,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, endpegmul = (endpegb - endpegt) / (endtop - endbot); #endif - for (i = 1; i < sector->numlights; i++) + for (i = 0; i < sector->numlights; i++) { #ifdef ESLOPE if (endtop < endrealbot) @@ -1117,35 +1117,38 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (top < realbot) return; - //Hurdler: fix a crashing bug, but is it correct? -// if (!list[i].caster) -// continue; + // There's a compiler warning here if this comment isn't here because of indentation + if (!(list[i].flags & FF_NOSHADE)) + { + if (pfloor && (pfloor->flags & FF_FOG)) + { + lightnum = pfloor->master->frontsector->lightlevel; + colormap = pfloor->master->frontsector->extra_colormap; + } + else + { + lightnum = *list[i].lightlevel; + colormap = list[i].extra_colormap; + } + } solid = false; - if (list[i].caster) + if ((sector->lightlist[i].flags & FF_CUTSOLIDS) && !(cutflag & FF_EXTRA)) + solid = true; + else if ((sector->lightlist[i].flags & FF_CUTEXTRA) && (cutflag & FF_EXTRA)) { - if (sector->lightlist[i].caster->flags & FF_CUTSOLIDS && !(cutflag & FF_EXTRA)) - solid = true; - else if (sector->lightlist[i].caster->flags & FF_CUTEXTRA && cutflag & FF_EXTRA) + if (sector->lightlist[i].flags & FF_EXTRA) { - if (sector->lightlist[i].caster->flags & FF_EXTRA) - { - if (sector->lightlist[i].caster->flags == cutflag) // Only merge with your own types - solid = true; - } - else + if ((sector->lightlist[i].flags & (FF_FOG|FF_SWIMMABLE)) == (cutflag & (FF_FOG|FF_SWIMMABLE))) // Only merge with your own types solid = true; } else - solid = false; + solid = true; } else solid = false; - if (cutflag == FF_CUTSOLIDS) // These are regular walls sent in from StoreWallRange, they shouldn't be cut from this - solid = false; - #ifdef ESLOPE if (list[i].slope) { @@ -1185,34 +1188,53 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (solid && endtop > endbheight) endtop = endbheight; #endif - continue; } +#ifdef ESLOPE + if (i + 1 < sector->numlights) + { + if (list[i+1].slope) + { + temp = P_GetZAt(list[i+1].slope, v1x, v1y); + bheight = FIXED_TO_FLOAT(temp); + temp = P_GetZAt(list[i+1].slope, v2x, v2y); + endbheight = FIXED_TO_FLOAT(temp); + } + else + bheight = endbheight = FIXED_TO_FLOAT(list[i+1].height); + } + else + { + bheight = realbot; + endbheight = endrealbot; + } +#else + if (i + 1 < sector->numlights) + { + bheight = FIXED_TO_FLOAT(list[i+1].height); + } + else + { + bheight = realbot; + } +#endif + + if (endbheight >= endtop) + if (bheight >= top) + continue; + //Found a break; - bot = height; + bot = bheight; if (bot < realbot) bot = realbot; #ifdef ESLOPE - endbot = endheight; + endbot = endbheight; if (endbot < endrealbot) endbot = endrealbot; #endif - - // colormap test - if (list[i-1].caster) - { - lightnum = *list[i-1].lightlevel; - colormap = list[i-1].extra_colormap; - } - else - { - lightnum = sector->lightlevel; - colormap = sector->extra_colormap; - } - Surf->FlatColor.s.alpha = alpha; #ifdef ESLOPE @@ -1235,20 +1257,16 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - if (cutflag & FF_TRANSLUCENT) + if (cutflag & FF_FOG) + HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture, true, lightnum, colormap); + else if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); - if (solid) - top = bheight; - else - top = height; + top = bot; #ifdef ESLOPE - if (solid) - endtop = endbheight; - else - endtop = endheight; + endtop = endbot; #endif } @@ -1260,17 +1278,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (top <= realbot) return; - if (list[i-1].caster) - { - lightnum = *list[i-1].lightlevel; - colormap = list[i-1].extra_colormap; - } - else - { - lightnum = sector->lightlevel; - colormap = sector->extra_colormap; - } - Surf->FlatColor.s.alpha = alpha; + Surf->FlatColor.s.alpha = alpha; #ifdef ESLOPE wallVerts[3].t = pegt + ((realtop - top) * pegmul); @@ -1292,116 +1300,14 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, wallVerts[0].y = wallVerts[1].y = bot; #endif - if (cutflag & FF_TRANSLUCENT) + if (cutflag & FF_FOG) + HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture, true, lightnum, colormap); + else if (cutflag & FF_TRANSLUCENT) HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); } -// -// HWR_SplitFog -// Exclusively for fog -// -static void HWR_SplitFog(sector_t *sector, wallVert3D *wallVerts, FSurfaceInfo* Surf, UINT32 cutflag, FUINT lightnum, extracolormap_t *colormap) -{ - /* SoM: split up and light walls according to the - lightlist. This may also include leaving out parts - of the wall that can't be seen */ - float realtop, realbot, top, bot; - float pegt, pegb, pegmul; - float height = 0.0f, bheight = 0.0f; - INT32 solid, i; - lightlist_t * list = sector->lightlist; - const UINT8 alpha = Surf->FlatColor.s.alpha; - - realtop = top = wallVerts[2].y; - realbot = bot = wallVerts[0].y; - pegt = wallVerts[2].t; - pegb = wallVerts[0].t; - pegmul = (pegb - pegt) / (top - bot); - - for (i = 1; i < sector->numlights; i++) - { - if (top < realbot) - return; - - //Hurdler: fix a crashing bug, but is it correct? -// if (!list[i].caster) -// continue; - - solid = false; - - if (list[i].caster) - { - if (sector->lightlist[i].caster->flags & FF_FOG && cutflag & FF_FOG) // Only fog cuts fog - { - if (sector->lightlist[i].caster->flags & FF_EXTRA) - { - if (sector->lightlist[i].caster->flags == cutflag) // only cut by the same - solid = true; - } - else - solid = true; - } - } - - height = FIXED_TO_FLOAT(list[i].height); - - if (solid) - bheight = FIXED_TO_FLOAT(*list[i].caster->bottomheight); - - if (height >= top) - { - if (solid && top > bheight) - top = bheight; - continue; - } - - //Found a break; - bot = height; - - if (bot < realbot) - bot = realbot; - - { - - - - Surf->FlatColor.s.alpha = alpha; - } - - wallVerts[3].t = wallVerts[2].t = pegt + ((realtop - top) * pegmul); - wallVerts[0].t = wallVerts[1].t = pegt + ((realtop - bot) * pegmul); - - // set top/bottom coords - wallVerts[2].y = wallVerts[3].y = top; - wallVerts[0].y = wallVerts[1].y = bot; - - if (!solid) // Don't draw it if there's more fog behind it - HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Fog|PF_NoTexture, true, lightnum, colormap); - - top = height; - } - - bot = realbot; - if (top <= realbot) - return; - - { - - Surf->FlatColor.s.alpha = alpha; - } - - wallVerts[3].t = wallVerts[2].t = pegt + ((realtop - top) * pegmul); - wallVerts[0].t = wallVerts[1].t = pegt + ((realtop - bot) * pegmul); - - // set top/bottom coords - wallVerts[2].y = wallVerts[3].y = top; - wallVerts[0].y = wallVerts[1].y = bot; - - HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Translucent|PF_NoTexture, true, lightnum, colormap); -} - // HWR_DrawSkyWalls // Draw walls into the depth buffer so that anything behind is culled properly static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top) @@ -1678,7 +1584,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, gr_toptexture, &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_toptexture, &Surf, FF_CUTLEVEL, NULL); else if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, gr_toptexture, PF_Environment, false, lightnum, colormap); else @@ -1761,7 +1667,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, gr_bottomtexture, &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_bottomtexture, &Surf, FF_CUTLEVEL, NULL); else if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, gr_bottomtexture, PF_Environment, false, lightnum, colormap); else @@ -2027,10 +1933,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (gr_frontsector->numlights) { if (!(blendmode & PF_Masked)) - HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_TRANSLUCENT); + HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_TRANSLUCENT, NULL); else { - HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTLEVEL, NULL); } } else if (!(blendmode & PF_Masked)) @@ -2182,7 +2088,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) #endif // I don't think that solid walls can use translucent linedef types... if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTSOLIDS); + HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTLEVEL, NULL); else { if (grTex->mipmap.flags & TF_TRANSPARENT) @@ -2320,7 +2226,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } if (gr_frontsector->numlights) - HWR_SplitFog(gr_frontsector, wallVerts, &Surf, rover->flags, lightnum, colormap); + HWR_SplitWall(gr_frontsector, wallVerts, 0, &Surf, rover->flags, rover); else HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap); } @@ -2335,7 +2241,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, texnum, &Surf, rover->flags); + HWR_SplitWall(gr_frontsector, wallVerts, texnum, &Surf, rover->flags, rover); else { if (blendmode != PF_Masked) @@ -2439,7 +2345,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } if (gr_backsector->numlights) - HWR_SplitFog(gr_backsector, wallVerts, &Surf, rover->flags, lightnum, colormap); + HWR_SplitWall(gr_backsector, wallVerts, 0, &Surf, rover->flags, rover); else HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap); } @@ -2454,7 +2360,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } if (gr_backsector->numlights) - HWR_SplitWall(gr_backsector, wallVerts, texnum, &Surf, rover->flags); + HWR_SplitWall(gr_backsector, wallVerts, texnum, &Surf, rover->flags, rover); else { if (blendmode != PF_Masked) From 0885d271711155e02d389c04f12bf2c234d1a7f1 Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 21 Mar 2018 19:45:37 +0000 Subject: [PATCH 37/56] Transform sprites in world space rather than screen space Transformation based on screen space would make sense if we didn't want anything in the world to effect the sprites. This should allow sprite splitting and sorting of sprites with level geometry easier. stransform is no longer needed. --- src/hardware/hw_glob.h | 1 + src/hardware/hw_main.c | 249 +++++++++++++---------------------------- 2 files changed, 79 insertions(+), 171 deletions(-) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 94eef1d3e..fea06caff 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -68,6 +68,7 @@ typedef struct gr_vissprite_s struct gr_vissprite_s *prev; struct gr_vissprite_s *next; float x1, x2; + float z1, z2; float tz, ty; lumpnum_t patchlumpnum; boolean flip; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c4e3d879e..7b9628b3d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3928,12 +3928,10 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale) { - UINT8 i; - float tr_x, tr_y; - FOutVector *wv; FOutVector swallVerts[4]; FSurfaceInfo sSurf; fixed_t floorheight, mobjfloor; + float offset = 0; mobjfloor = HWR_OpaqueFloorAtPos( spr->mobj->x, spr->mobj->y, @@ -3972,6 +3970,8 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t } floorheight = FixedInt(spr->mobj->z - floorheight); + + offset = floorheight; } else floorheight = FixedInt(spr->mobj->z - mobjfloor); @@ -3984,47 +3984,42 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t // 0--1 // x1/x2 were already scaled in HWR_ProjectSprite + // First match the normal sprite swallVerts[0].x = swallVerts[3].x = spr->x1; swallVerts[2].x = swallVerts[1].x = spr->x2; + swallVerts[0].z = swallVerts[3].z = spr->z1; + swallVerts[2].z = swallVerts[1].z = spr->z2; if (spr->mobj && this_scale != 1.0f) { // Always a pixel above the floor, perfectly flat. swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3); - swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset) * this_scale; - swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset * this_scale; + // Now transform the TOP vertices along the floor in the direction of the camera + swallVerts[3].x = spr->x1 + ((gpatch->height * this_scale) + offset) * gr_viewcos; + swallVerts[2].x = spr->x2 + ((gpatch->height * this_scale) + offset) * gr_viewcos; + swallVerts[3].z = spr->z1 + ((gpatch->height * this_scale) + offset) * gr_viewsin; + swallVerts[2].z = spr->z2 + ((gpatch->height * this_scale) + offset) * gr_viewsin; } else { // Always a pixel above the floor, perfectly flat. swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3); - // Spread out top away from the camera. (Fixme: Make it always move out in the same direction!... somehow.) - swallVerts[0].z = swallVerts[1].z = spr->tz - (gpatch->height-gpatch->topoffset); - swallVerts[2].z = swallVerts[3].z = spr->tz + gpatch->topoffset; + // Now transform the TOP vertices along the floor in the direction of the camera + swallVerts[3].x = spr->x1 + (gpatch->height + offset) * gr_viewcos; + swallVerts[2].x = spr->x2 + (gpatch->height + offset) * gr_viewcos; + swallVerts[3].z = spr->z1 + (gpatch->height + offset) * gr_viewsin; + swallVerts[2].z = spr->z2 + (gpatch->height + offset) * gr_viewsin; } - // transform - wv = swallVerts; - - for (i = 0; i < 4; i++,wv++) + // We also need to move the bottom ones away when shadowoffs is on + if (cv_shadowoffs.value) { - // Offset away from the camera based on height from floor. - if (cv_shadowoffs.value) - wv->z += floorheight; - wv->z += 3; - - //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - tr_x = wv->z; - tr_y = wv->y; - wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin); - wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos); - // ---------------------- mega lame test ---------------------------------- - - //scale y before frustum so that frustum can be scaled to screen height - wv->y *= ORIGINAL_ASPECT * gr_fovlud; - wv->x *= gr_fovlud; + swallVerts[0].x = spr->x1 + offset * gr_viewcos; + swallVerts[1].x = spr->x2 + offset * gr_viewcos; + swallVerts[0].z = spr->z1 + offset * gr_viewsin; + swallVerts[1].z = spr->z2 + offset * gr_viewsin; } if (spr->flip) @@ -4111,10 +4106,8 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t // -----------------+ static void HWR_DrawSprite(gr_vissprite_t *spr) { - UINT8 i; - float tr_x, tr_y, this_scale = 1.0f; + float this_scale = 1.0f; FOutVector wallVerts[4]; - FOutVector *wv; GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES); @@ -4161,24 +4154,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // make a wall polygon (with 2 triangles), using the floor/ceiling heights, // and the 2d map coords of start/end vertices - wallVerts[0].z = wallVerts[1].z = wallVerts[2].z = wallVerts[3].z = spr->tz; - - // transform - wv = wallVerts; - - for (i = 0; i < 4; i++,wv++) - { - //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - tr_x = wv->z; - tr_y = wv->y; - wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin); - wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos); - // ---------------------- mega lame test ---------------------------------- - - //scale y before frustum so that frustum can be scaled to screen height - wv->y *= ORIGINAL_ASPECT * gr_fovlud; - wv->x *= gr_fovlud; - } + wallVerts[0].z = wallVerts[3].z = spr->z1; + wallVerts[1].z = wallVerts[2].z = spr->z2; if (spr->flip) { @@ -4289,11 +4266,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // Sprite drawer for precipitation static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) { - UINT8 i; FBITFIELD blend = 0; - float tr_x, tr_y; FOutVector wallVerts[4]; - FOutVector *wv; GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; @@ -4319,24 +4293,8 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) // make a wall polygon (with 2 triangles), using the floor/ceiling heights, // and the 2d map coords of start/end vertices - wallVerts[0].z = wallVerts[1].z = wallVerts[2].z = wallVerts[3].z = spr->tz; - - // transform - wv = wallVerts; - - for (i = 0; i < 4; i++, wv++) - { - //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - tr_x = wv->z; - tr_y = wv->y; - wv->y = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin); - wv->z = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos); - // ---------------------- mega lame test ---------------------------------- - - //scale y before frustum so that frustum can be scaled to screen height - wv->y *= ORIGINAL_ASPECT * gr_fovlud; - wv->x *= gr_fovlud; - } + wallVerts[0].z = wallVerts[3].z = spr->z1; + wallVerts[1].z = wallVerts[2].z = spr->z2; wallVerts[0].sow = wallVerts[3].sow = 0; wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; @@ -4830,7 +4788,7 @@ static void HWR_CreateDrawNodes(void) // -------------------------------------------------------------------------- #ifdef SORTING // added the stransform so they can be switched as drawing happenes so MD2s and sprites are sorted correctly with each other -static void HWR_DrawSprites(FTransform *stransform) +static void HWR_DrawSprites() { if (gr_visspritecount > 0) { @@ -4843,37 +4801,22 @@ static void HWR_DrawSprites(FTransform *stransform) { #ifdef HWPRECIP if (spr->precip) - { - HWD.pfnSetTransform(stransform); HWR_DrawPrecipitationSprite(spr); - } else #endif if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { if (!cv_grmd2.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) - { - HWD.pfnSetTransform(stransform); HWR_DrawSprite(spr); - } else - { - HWD.pfnSetTransform(&atransform); HWR_DrawMD2(spr); - } } else { if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) - { - HWD.pfnSetTransform(stransform); HWR_DrawSprite(spr); - } else - { - HWD.pfnSetTransform(&atransform); HWR_DrawMD2(spr); - } } } } @@ -4963,8 +4906,10 @@ static void HWR_ProjectSprite(mobj_t *thing) { gr_vissprite_t *vis; float tr_x, tr_y; - float tx, tz; + float tz; float x1, x2; + float z1, z2; + float rightsin, rightcos; float this_scale; float gz, gzt; spritedef_t *sprdef; @@ -4991,7 +4936,9 @@ static void HWR_ProjectSprite(mobj_t *thing) if (tz < ZCLIP_PLANE && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear return; - tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos); + // The above can stay as it works for cutting sprites that are too close + tr_x = FIXED_TO_FLOAT(thing->x); + tr_y = FIXED_TO_FLOAT(thing->y); // decide which patch to use for sprite relative to player #ifdef RANGECHECK @@ -5046,23 +4993,23 @@ static void HWR_ProjectSprite(mobj_t *thing) if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale); - // calculate edges of the shape + rightsin = FIXED_TO_FLOAT(FINESINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); + rightcos = FIXED_TO_FLOAT(FINECOSINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); if (flip) - tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale; + { + x1 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale); + x2 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale); + } else - tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale; + { + x1 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale); + x2 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale); + } - // project x - x1 = gr_windowcenterx + (tx * gr_centerx / tz); - - //faB : tr_x doesnt matter - // hurdler: it's used in cliptosolidsegs - tr_x = x1; - - x1 = tx; - - tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale; - x2 = gr_windowcenterx + (tx * gr_centerx / tz); + z1 = tr_y + x1 * rightsin; + z2 = tr_y - x2 * rightsin; + x1 = tr_x + x1 * rightcos; + x2 = tr_x - x2 * rightcos; if (thing->eflags & MFE_VERTICALFLIP) { @@ -5099,13 +5046,10 @@ static void HWR_ProjectSprite(mobj_t *thing) // store information in a vissprite vis = HWR_NewVisSprite(); vis->x1 = x1; -#if 0 vis->x2 = x2; -#else - (void)x2; -#endif - vis->x2 = tx; - vis->tz = tz; + vis->z1 = z1; + vis->z2 = z2; + vis->tz = tz; // Keep tz for the simple sprite sorting that happens vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST vis->patchlumpnum = sprframe->lumppat[rot]; vis->flip = flip; @@ -5136,7 +5080,7 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->colormap = colormaps; // set top/bottom coords - vis->ty = gzt - gr_viewz; + vis->ty = gzt; //CONS_Debug(DBG_RENDER, "------------------\nH: sprite : %d\nH: frame : %x\nH: type : %d\nH: sname : %s\n\n", // thing->sprite, thing->frame, thing->type, sprnames[thing->sprite]); @@ -5155,8 +5099,10 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) { gr_vissprite_t *vis; float tr_x, tr_y; - float tx, tz; + float tz; float x1, x2; + float z1, z2; + float rightsin, rightcos; spritedef_t *sprdef; spriteframe_t *sprframe; size_t lumpoff; @@ -5174,7 +5120,8 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) if (tz < ZCLIP_PLANE) return; - tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos); + tr_x = FIXED_TO_FLOAT(thing->x); + tr_y = FIXED_TO_FLOAT(thing->y); // decide which patch to use for sprite relative to player if ((unsigned)thing->sprite >= numsprites) @@ -5201,32 +5148,32 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) lumpoff = sprframe->lumpid[0]; flip = sprframe->flip; // Will only be 0x00 or 0xFF - // calculate edges of the shape - tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset); + rightsin = FIXED_TO_FLOAT(FINESINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); + rightcos = FIXED_TO_FLOAT(FINECOSINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); + if (flip) + { + x1 = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset); + x2 = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset); + } + else + { + x1 = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset); + x2 = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset); + } - // project x - x1 = gr_windowcenterx + (tx * gr_centerx / tz); - - //faB : tr_x doesnt matter - // hurdler: it's used in cliptosolidsegs - tr_x = x1; - - x1 = tx; - - tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width); - x2 = gr_windowcenterx + (tx * gr_centerx / tz); + z1 = tr_y + x1 * rightsin; + z2 = tr_y - x2 * rightsin; + x1 = tr_x + x1 * rightcos; + x2 = tr_x - x2 * rightcos; // // store information in a vissprite // vis = HWR_NewVisSprite(); vis->x1 = x1; -#if 0 vis->x2 = x2; -#else - (void)x2; -#endif - vis->x2 = tx; + vis->z1 = z1; + vis->z2 = z2; vis->tz = tz; vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST vis->patchlumpnum = sprframe->lumppat[rot]; @@ -5236,7 +5183,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->colormap = colormaps; // set top/bottom coords - vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset) - gr_viewz; + vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset); vis->precip = true; } @@ -5387,7 +5334,6 @@ void HWR_SetViewSize(void) void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) { const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); - FTransform stransform; postimg_t *type; if (splitscreen && player == &players[secondarydisplayplayer]) @@ -5457,25 +5403,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) atransform.fovyangle = fpov; // Tails atransform.splitscreen = splitscreen; - // Transform for sprites - stransform.anglex = 0.0f; - stransform.angley = -270.0f; - - if (*type == postimg_flip) - stransform.flip = true; - else - stransform.flip = false; - - stransform.x = 0.0f; - stransform.y = 0.0f; - stransform.z = 0.0f; - stransform.scalex = 1; - stransform.scaley = 1; - stransform.scalez = 1; - stransform.fovxangle = 90.0f; - stransform.fovyangle = 90.0f; - stransform.splitscreen = splitscreen; - gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); //------------------------------------------------------------------------ @@ -5556,7 +5483,7 @@ if (0) #endif #ifdef SORTING - HWR_DrawSprites(&stransform); + HWR_DrawSprites(); #endif #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? @@ -5599,7 +5526,6 @@ if (0) void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) { const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); - FTransform stransform; postimg_t *type; const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on @@ -5684,25 +5610,6 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) atransform.fovyangle = fpov; // Tails atransform.splitscreen = splitscreen; - // Transform for sprites - stransform.anglex = 0.0f; - stransform.angley = -270.0f; - - if (*type == postimg_flip) - stransform.flip = true; - else - stransform.flip = false; - - stransform.x = 0.0f; - stransform.y = 0.0f; - stransform.z = 0.0f; - stransform.scalex = 1; - stransform.scaley = 1; - stransform.scalez = 1; - stransform.fovxangle = 90.0f; - stransform.fovyangle = 90.0f; - stransform.splitscreen = splitscreen; - gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); //------------------------------------------------------------------------ @@ -5783,7 +5690,7 @@ if (0) #endif #ifdef SORTING - HWR_DrawSprites(&stransform); + HWR_DrawSprites(); #endif #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? From 839ee0ab852c0ccfe8b974b93dccbb0a38fdba6d Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 22 Mar 2018 00:52:14 +0000 Subject: [PATCH 38/56] OpenGL Sprite Splitting --- src/hardware/hw_main.c | 309 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 289 insertions(+), 20 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7b9628b3d..b17ead955 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1219,7 +1219,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, } #endif +#ifdef ESLOPE if (endbheight >= endtop) +#endif if (bheight >= top) continue; @@ -4099,6 +4101,285 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t } } +static void HWR_SplitSprite(gr_vissprite_t *spr) +{ + float this_scale = 1.0f; + FOutVector wallVerts[4]; + GLPatch_t *gpatch; + FSurfaceInfo Surf; + const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES); + extracolormap_t *colormap; + FUINT lightlevel; + FBITFIELD blend = 0; + UINT8 alpha; + + INT32 i; + float realtop, realbot, top, bot; + float towtop, towbot, towmult; + float bheight; + const sector_t *sector = spr->mobj->subsector->sector; + const lightlist_t *list = sector->lightlist; +#ifdef ESLOPE + float endrealtop, endrealbot, endtop, endbot; + float endbheight; + fixed_t temp; + fixed_t v1x, v1y, v2x, v2y; +#endif + + this_scale = FIXED_TO_FLOAT(spr->mobj->scale); + + if (hires) + this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)spr->mobj->skin)->highresscale); + + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + + // cache the patch in the graphics card memory + //12/12/99: Hurdler: same comment as above (for md2) + //Hurdler: 25/04/2000: now support colormap in hardware mode + HWR_GetMappedPatch(gpatch, spr->colormap); + + // Draw shadow BEFORE sprite + if (cv_shadow.value // Shadows enabled + && (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow. + && !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow. +#ifdef ALAM_LIGHTING + && !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow. + && (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players. +#endif + && (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground. + { + //////////////////// + // SHADOW SPRITE! // + //////////////////// + HWR_DrawSpriteShadow(spr, gpatch, this_scale); + } + + wallVerts[0].x = wallVerts[3].x = spr->x1; + wallVerts[2].x = wallVerts[1].x = spr->x2; + wallVerts[0].z = wallVerts[3].z = spr->z1; + wallVerts[1].z = wallVerts[2].z = spr->z2; + + wallVerts[2].y = wallVerts[3].y = spr->ty; + if (spr->mobj && this_scale != 1.0f) + wallVerts[0].y = wallVerts[1].y = spr->ty - gpatch->height * this_scale; + else + wallVerts[0].y = wallVerts[1].y = spr->ty - gpatch->height; + + v1x = FLOAT_TO_FIXED(spr->x1); + v1y = FLOAT_TO_FIXED(spr->z1); + v2x = FLOAT_TO_FIXED(spr->x2); + v2y = FLOAT_TO_FIXED(spr->z2); + + if (spr->flip) + { + wallVerts[0].sow = wallVerts[3].sow = gpatch->max_s; + wallVerts[2].sow = wallVerts[1].sow = 0; + }else{ + wallVerts[0].sow = wallVerts[3].sow = 0; + wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; + } + + // flip the texture coords (look familiar?) + if (spr->vflip) + { + wallVerts[3].tow = wallVerts[2].tow = gpatch->max_t; + wallVerts[0].tow = wallVerts[1].tow = 0; + }else{ + wallVerts[3].tow = wallVerts[2].tow = 0; + wallVerts[0].tow = wallVerts[1].tow = gpatch->max_t; + } + + realtop = top = wallVerts[3].y; + realbot = bot = wallVerts[0].y; + towtop = wallVerts[3].tow; + towbot = wallVerts[0].tow; + towmult = (towbot - towtop) / (top - bot); + +#ifdef ESLOPE + endrealtop = endtop = wallVerts[2].y; + endrealbot = endbot = wallVerts[1].y; +#endif + + if (!cv_translucency.value) // translucency disabled + { + Surf.FlatColor.s.alpha = 0xFF; + blend = PF_Translucent|PF_Occlude; + } + else if (spr->mobj->flags2 & MF2_SHADOW) + { + Surf.FlatColor.s.alpha = 0x40; + blend = PF_Translucent; + } + else if (spr->mobj->frame & FF_TRANSMASK) + blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); + else + { + // BP: i agree that is little better in environement but it don't + // work properly under glide nor with fogcolor to ffffff :( + // Hurdler: PF_Environement would be cool, but we need to fix + // the issue with the fog before + Surf.FlatColor.s.alpha = 0xFF; + blend = PF_Translucent|PF_Occlude; + } + + alpha = Surf.FlatColor.s.alpha; + + // Start with the lightlevel and colormap from the top of the sprite + lightlevel = *list[sector->numlights - 1].lightlevel; + colormap = list[sector->numlights - 1].extra_colormap; + i = 0; + temp = FLOAT_TO_FIXED(realtop); + +#ifdef ESLOPE + for (i = 1; i < sector->numlights; i++) + { + fixed_t h = sector->lightlist[i].slope ? P_GetZAt(sector->lightlist[i].slope, spr->mobj->x, spr->mobj->y) + : sector->lightlist[i].height; + if (h <= temp) + { + lightlevel = *list[i-1].lightlevel; + colormap = list[i-1].extra_colormap; + break; + } + } +#else + i = R_GetPlaneLight(sector, temp, false); + lightlevel = *list[i].lightlevel; + colormap = list[i].extra_colormap; +#endif + + for (i = 0; i < sector->numlights; i++) + { +#ifdef ESLOPE + if (endtop < endrealbot) +#endif + if (top < realbot) + return; + + // even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite + if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES)) + { + lightlevel = *list[i].lightlevel; + colormap = list[i].extra_colormap; + } + +#ifdef ESLOPE + if (i + 1 < sector->numlights) + { + if (list[i+1].slope) + { + temp = P_GetZAt(list[i+1].slope, v1x, v1y); + bheight = FIXED_TO_FLOAT(temp); + temp = P_GetZAt(list[i+1].slope, v2x, v2y); + endbheight = FIXED_TO_FLOAT(temp); + } + else + bheight = endbheight = FIXED_TO_FLOAT(list[i+1].height); + } + else + { + bheight = realbot; + endbheight = endrealbot; + } +#else + if (i + 1 < sector->numlights) + { + bheight = FIXED_TO_FLOAT(list[i+1].height); + } + else + { + bheight = realbot; + } +#endif + +#ifdef ESLOPE + if (endbheight >= endtop) +#endif + if (bheight >= top) + continue; + + bot = bheight; + + if (bot < realbot) + bot = realbot; + +#ifdef ESLOPE + endbot = endbheight; + + if (endbot < endrealbot) + endbot = endrealbot; +#endif + +#ifdef ESLOPE + wallVerts[3].tow = towtop + ((realtop - top) * towmult); + wallVerts[2].tow = towtop + ((endrealtop - endtop) * towmult); + wallVerts[0].tow = towtop + ((realtop - bot) * towmult); + wallVerts[1].tow = towtop + ((endrealtop - endbot) * towmult); + + wallVerts[3].y = top; + wallVerts[2].y = endtop; + wallVerts[0].y = bot; + wallVerts[1].y = endbot; +#else + wallVerts[3].tow = wallVerts[2].tow = towtop + ((realtop - top) * towmult); + wallVerts[0].tow = wallVerts[1].tow = towtop + ((realtop - bot) * towmult); + + wallVerts[2].y = wallVerts[3].y = top; + wallVerts[0].y = wallVerts[1].y = bot; +#endif + + if (colormap) + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); + else + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + + Surf.FlatColor.s.alpha = alpha; + + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + + top = bot; +#ifdef ESLOPE + endtop = endbot; +#endif + } + + bot = realbot; +#ifdef ESLOPE + endbot = endrealbot; + if (endtop <= endrealbot) +#endif + if (top <= realbot) + return; + + // If we're ever down here, somehow the above loop hasn't draw all the light levels of sprite +#ifdef ESLOPE + wallVerts[3].tow = towtop + ((realtop - top) * towmult); + wallVerts[2].tow = towtop + ((endrealtop - endtop) * towmult); + wallVerts[0].tow = towtop + ((realtop - bot) * towmult); + wallVerts[1].tow = towtop + ((endrealtop - endbot) * towmult); + + wallVerts[3].y = top; + wallVerts[2].y = endtop; + wallVerts[0].y = bot; + wallVerts[1].y = endbot; +#else + wallVerts[3].tow = wallVerts[2].tow = towtop + ((realtop - top) * towmult); + wallVerts[0].tow = wallVerts[1].tow = towtop + ((realtop - bot) * towmult); + + wallVerts[2].y = wallVerts[3].y = top; + wallVerts[0].y = wallVerts[1].y = bot; +#endif + + if (colormap) + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); + else + Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + + Surf.FlatColor.s.alpha = alpha; + + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); +} + // -----------------+ // HWR_DrawSprite : Draw flat sprites // : (monsters, bonuses, weapons, lights, ...) @@ -4122,6 +4403,12 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) if (!spr->mobj->subsector) return; + if (spr->mobj->subsector->sector->numlights) + { + HWR_SplitSprite(spr); + return; + } + // cache sprite graphics //12/12/99: Hurdler: // OK, I don't change anything for MD2 support because I want to be @@ -4207,26 +4494,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) UINT8 lightlevel = 255; extracolormap_t *colormap = sector->extra_colormap; - if (sector->numlights) - { - INT32 light; - - light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before - - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *sector->lightlist[light].lightlevel; - - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; - } - else - { - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = sector->lightlevel; - - if (sector->extra_colormap) - colormap = sector->extra_colormap; - } + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = sector->lightlevel; if (colormap) Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); From fab4b7f5eab7509a6c2a3a6bc1b05ce7d3452ebd Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 22 Mar 2018 01:10:53 +0000 Subject: [PATCH 39/56] Stop squashing the screen vertically in non-green resolutions --- src/hardware/hw_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b17ead955..86b80904f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5666,7 +5666,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy) atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz) atransform.scalex = 1; - atransform.scaley = ORIGINAL_ASPECT; + atransform.scaley = (float)vid.width/vid.height; atransform.scalez = 1; atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails @@ -5873,7 +5873,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy) atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz) atransform.scalex = 1; - atransform.scaley = ORIGINAL_ASPECT; + atransform.scaley = (float)vid.width/vid.height; atransform.scalez = 1; atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails From a431197921a847cf387da362dc2cbfebb0299ef8 Mon Sep 17 00:00:00 2001 From: jameds Date: Thu, 11 Jan 2018 17:35:39 -0800 Subject: [PATCH 40/56] Fixed "invalid pointer" error when passing "" to Command_connect(). --- src/d_clisrv.c | 2 +- src/m_menu.c | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7d0e44b45..36d13fc14 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2244,7 +2244,7 @@ static void Command_connect(void) // Assume we connect directly. boolean viams = false; - if (COM_Argc() < 2) + if (COM_Argc() < 2 || *COM_Argv(1) == 0) { CONS_Printf(M_GetText( "Connect (port): connect to a server\n" diff --git a/src/m_menu.c b/src/m_menu.c index ea93d1e2d..0ab771579 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6295,6 +6295,13 @@ static void M_DrawConnectIPMenu(void) static void M_ConnectIP(INT32 choice) { (void)choice; + + if (*setupm_ip == 0) + { + M_StartMessage("You must specify an IP address.\n", NULL, MM_NOTHING); + return; + } + COM_BufAddText(va("connect \"%s\"\n", setupm_ip)); // A little "please wait" message. From f62cb3a30a7bd36d52a5c6a7853baf9aaf887aa9 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 23 Mar 2018 22:27:29 +0000 Subject: [PATCH 41/56] I've commented out the call to HWR_CorrectSWTricks. I don't think it does anything for us anymore, and might even break things with slopes. Someone let me know if I'm wrong and am breaking things horribly here. --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 8e746457b..e93cbed51 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2718,7 +2718,7 @@ boolean P_SetupLevel(boolean skipprecip) HWR_ResetLights(); #endif // Correct missing sidedefs & deep water trick - HWR_CorrectSWTricks(); + //HWR_CorrectSWTricks(); HWR_CreatePlanePolygons((INT32)numnodes - 1); } #endif From 876d0fa58b3ba39d86cfd4b46a488c711211d706 Mon Sep 17 00:00:00 2001 From: jameds Date: Fri, 23 Mar 2018 18:06:32 -0700 Subject: [PATCH 42/56] Removed contradictory `-connect` check --- src/d_main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 063d28453..7368383b5 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1068,7 +1068,7 @@ void D_SRB2Main(void) // add any files specified on the command line with -file wadfile // to the wad list - if (!(M_CheckParm("-connect"))) + if (!(M_CheckParm("-connect") && !M_CheckParm("-server"))) { if (M_CheckParm("-file")) { @@ -1323,7 +1323,7 @@ void D_SRB2Main(void) ultimatemode = true; } - if (autostart || netgame || M_CheckParm("+connect") || M_CheckParm("-connect")) + if (autostart || netgame) { gameaction = ga_nothing; @@ -1361,8 +1361,7 @@ void D_SRB2Main(void) } } - if (server && !M_CheckParm("+map") && !M_CheckParm("+connect") - && !M_CheckParm("-connect")) + if (server && !M_CheckParm("+map")) { // Prevent warping to nonexistent levels if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR) From 65c893da86e23bc3c75aeb16a4d4ec1cdebdc79d Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 29 Mar 2018 23:28:54 +0100 Subject: [PATCH 43/56] static tempsec for R_FakeFlat I don't fully understand this, but it's what software does and it fixes the issue of the lighting in DSZ3. Also don't need the extra call to R_Prep3DFloors. --- src/hardware/hw_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 86b80904f..a0ea9b47a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2676,7 +2676,7 @@ static void HWR_AddLine(seg_t * line) angle_t span, tspan; // SoM: Backsector needs to be run through R_FakeFlat - sector_t tempsec; + static sector_t tempsec; if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; @@ -3235,7 +3235,7 @@ static void HWR_Subsector(size_t num) INT16 count; seg_t *line; subsector_t *sub; - sector_t tempsec; //SoM: 4/7/2000 + static sector_t tempsec; //SoM: 4/7/2000 INT32 floorlightlevel; INT32 ceilinglightlevel; INT32 locFloorHeight, locCeilingHeight; @@ -3418,8 +3418,6 @@ static void HWR_Subsector(size_t num) { /// \todo fix light, xoffs, yoffs, extracolormap ? ffloor_t * rover; - - R_Prep3DFloors(gr_frontsector); for (rover = gr_frontsector->ffloors; rover; rover = rover->next) { From f3aa02e26dad0ce1178925284f65cc8eb7b6e4f3 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 30 Mar 2018 18:13:52 +0100 Subject: [PATCH 44/56] Start with lightnum on sector lightlevel --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a0ea9b47a..16587e5db 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1092,7 +1092,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, INT32 solid, i; lightlist_t * list = sector->lightlist; const UINT8 alpha = Surf->FlatColor.s.alpha; - FUINT lightnum; + FUINT lightnum = sector->lightlevel; extracolormap_t *colormap = NULL; realtop = top = wallVerts[3].y; From 0aaae501d379ee8526d190634e8af02ce4e8d1e8 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 30 Mar 2018 18:53:23 +0100 Subject: [PATCH 45/56] Warnings must die --- src/f_finale.c | 2 +- src/hardware/hw_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index cd699b6cb..958bef0f6 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -234,7 +234,7 @@ static void F_SkyScroll(INT32 scrollspeed) else if (rendermode != render_none) { // if only software rendering could be this simple and retarded INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); - INT32 x, y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; + INT32 y, pw = SHORT(pat->width) * dupz, ph = SHORT(pat->height) * dupz; scrolled = animtimer * dupz; for (x = 0; x < vid.width; x += pw) { diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 16587e5db..becd1b1c2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5055,7 +5055,7 @@ static void HWR_CreateDrawNodes(void) // -------------------------------------------------------------------------- #ifdef SORTING // added the stransform so they can be switched as drawing happenes so MD2s and sprites are sorted correctly with each other -static void HWR_DrawSprites() +static void HWR_DrawSprites(void) { if (gr_visspritecount > 0) { From 6f2de824fb015d71940e9c4d12b321b30bcb63b2 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 30 Mar 2018 23:12:44 +0100 Subject: [PATCH 46/56] Uncomment HWR_CorrectSWTricks but set gr_correcttricks to be off by default I wasn't aware of the cvar, this should do for now since I don't believe any maps use these software tricks, probably an old leftover from DOOM. --- src/hardware/hw_main.c | 2 +- src/p_setup.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index becd1b1c2..81021ef7f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -117,7 +117,7 @@ consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL, grfiltermode_c consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t, CV_anisotropic_ONChange, 0, NULL, NULL, 0, 0, NULL}; //static consvar_t cv_grzbuffer = {"gr_zbuffer", "On", 0, CV_OnOff}; -consvar_t cv_grcorrecttricks = {"gr_correcttricks", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static void CV_FogDensity_ONChange(void) diff --git a/src/p_setup.c b/src/p_setup.c index e93cbed51..8e746457b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2718,7 +2718,7 @@ boolean P_SetupLevel(boolean skipprecip) HWR_ResetLights(); #endif // Correct missing sidedefs & deep water trick - //HWR_CorrectSWTricks(); + HWR_CorrectSWTricks(); HWR_CreatePlanePolygons((INT32)numnodes - 1); } #endif From 759ea8cb4200e1c99e9450595965db23c798e8dc Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 3 Apr 2018 16:11:07 -0400 Subject: [PATCH 47/56] Indentation fixup --- src/d_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index ea24430ec..b8f24e4b6 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1230,7 +1230,9 @@ void D_SRB2Main(void) nomidimusic = nodigimusic = true; } else - CONS_Printf("S_Init(): Setting up sound.\n"); + { + CONS_Printf("S_Init(): Setting up sound.\n"); + } if (M_CheckParm("-nosound")) nosound = true; if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic @@ -1245,7 +1247,7 @@ void D_SRB2Main(void) I_StartupSound(); I_InitMusic(); S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); - + CONS_Printf("ST_Init(): Init status bar.\n"); ST_Init(); From 3fb12cf337dd02bf559b2c7986978d7d56a68d61 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 15 Apr 2018 19:59:57 +0100 Subject: [PATCH 48/56] Don't use CV_StealthSetValue on cv_itemfinder if running the game in dedicated mode --- src/g_game.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index d3c55e0cc..bcae69fda 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3588,7 +3588,8 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean unlocktriggers = 0; // clear itemfinder, just in case - CV_StealthSetValue(&cv_itemfinder, 0); + if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds + CV_StealthSetValue(&cv_itemfinder, 0); } // internal game map From 9cdf87404e3a2e2a0acc6b7861e90c9426f30dd3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 15 Apr 2018 22:00:31 +0100 Subject: [PATCH 49/56] Rewrote findfile to store whether any of the three paths searched had a bad MD5 rather than just simply being not there. This means that, if the three paths are not the same, you should be able to tell if at least one of them has a file that just had a bad MD5. Most relevant for Linux peeps I expect. Note: Untested as of writing --- src/d_netfil.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 172624ad2..6742cfe28 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -990,19 +990,41 @@ filestatus_t checkfilemd5(char *filename, const UINT8 *wantedmd5sum) return FS_FOUND; // will never happen, but makes the compiler shut up } +// Rewritten by Monster Iestyn to be less stupid +// Note: if completepath is true, "filename" is modified, but only if FS_FOUND is going to be returned +// (Don't worry about WinCE's version of filesearch, nobody cares about that OS anymore) filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean completepath) { - filestatus_t homecheck = filesearch(filename, srb2home, wantedmd5sum, false, 10); - if (homecheck == FS_FOUND) - return filesearch(filename, srb2home, wantedmd5sum, completepath, 10); + filestatus_t homecheck; // store result of last file search + boolean badmd5 = false; // store whether md5 was bad from either of the first two searches (if nothing was found in the third) - homecheck = filesearch(filename, srb2path, wantedmd5sum, false, 10); - if (homecheck == FS_FOUND) - return filesearch(filename, srb2path, wantedmd5sum, completepath, 10); + // first, check SRB2's "home" directory + homecheck = filesearch(filename, srb2home, wantedmd5sum, completepath, 10); + if (homecheck == FS_FOUND) // we found the file, so return that we have :) + return FS_FOUND; + else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5 + badmd5 = true; + // if not found at all, just move on without doing anything + + // next, check SRB2's "path" directory + homecheck = filesearch(filename, srb2path, wantedmd5sum, completepath, 10); + + if (homecheck == FS_FOUND) // we found the file, so return that we have :) + return FS_FOUND; + else if (homecheck == FS_MD5SUMBAD) // file has a bad md5; move on and look for a file with the right md5 + badmd5 = true; + // if not found at all, just move on without doing anything + + // finally check "." directory #ifdef _arch_dreamcast - return filesearch(filename, "/cd", wantedmd5sum, completepath, 10); + homecheck = filesearch(filename, "/cd", wantedmd5sum, completepath, 10); #else - return filesearch(filename, ".", wantedmd5sum, completepath, 10); + homecheck = filesearch(filename, ".", wantedmd5sum, completepath, 10); #endif + + if (homecheck != FS_NOTFOUND) // if not found this time, fall back on the below return statement + return homecheck; // otherwise return the result we got + + return (badmd5 ? FS_MD5SUMBAD : FS_NOTFOUND); // md5 sum bad or file not found } From badbb4324eb3f0b29ba0462753de45f5a9743dd3 Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 16 May 2018 21:04:57 +0100 Subject: [PATCH 50/56] Fix FF_FULLBRIGHT not working in sectors with multiple light levels in OpenGL --- src/hardware/hw_main.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 81021ef7f..b758c828e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4228,6 +4228,9 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) i = 0; temp = FLOAT_TO_FIXED(realtop); + if (spr->mobj->frame & FF_FULLBRIGHT) + lightlevel = 255; + #ifdef ESLOPE for (i = 1; i < sector->numlights; i++) { @@ -4235,14 +4238,16 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) : sector->lightlist[i].height; if (h <= temp) { - lightlevel = *list[i-1].lightlevel; + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *list[i-1].lightlevel; colormap = list[i-1].extra_colormap; break; } } #else i = R_GetPlaneLight(sector, temp, false); - lightlevel = *list[i].lightlevel; + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *list[i].lightlevel; colormap = list[i].extra_colormap; #endif @@ -4257,7 +4262,8 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) // even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES)) { - lightlevel = *list[i].lightlevel; + if (!(spr->mobj->frame & FF_FULLBRIGHT)) + lightlevel = *list[i].lightlevel; colormap = list[i].extra_colormap; } From 0bef99f5666ca80bdbcf867814a9e0c75d89fca4 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 17 May 2018 13:57:19 -0400 Subject: [PATCH 51/56] Fix console typo --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 52cd6ddbb..362e0966d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3003,7 +3003,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX) { - CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename); + CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename); return false; } else wadnum = (UINT16)(numwadfiles-1); From 092e70923573cf365a4035fc1c10148f5d9becb1 Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 17 May 2018 22:17:20 +0100 Subject: [PATCH 52/56] OpenGL Map Specific palettes working This makes OpenGL stop using a specific function that doesn't really do anything for it anymore. It looks like it was used for a hack that would change the colour of polygons for the flashpal equivalent in DOOM. I made it so ST_DoPaletteStuff doesn't set the flashpal in OpenGL as it already does its own hacky overlay and doing that would cause all the textures to be flushed more mid-level, it could be enabled for more correct flashpals, but they still wouldn't effect fog or lighting. This means the palette will be set when going to the title screen, and twice when starting a map, (causing the OpenGL cached textures to also be flushed at those times) --- src/d_main.c | 7 +------ src/p_setup.c | 5 ----- src/st_stuff.c | 10 +++++----- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 4cdfb13d9..fbec5f7d8 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -730,11 +730,6 @@ void D_StartTitle(void) CON_ToggleOff(); // Reset the palette -#ifdef HWRENDER - if (rendermode == render_opengl) - HWR_SetPaletteColor(0); - else -#endif if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); } @@ -1223,7 +1218,7 @@ void D_SRB2Main(void) CONS_Printf("R_Init(): Init SRB2 refresh daemon.\n"); R_Init(); - // setting up sound + // setting up sound if (dedicated) { nosound = true; diff --git a/src/p_setup.c b/src/p_setup.c index 52cd6ddbb..c3aa9884d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2503,11 +2503,6 @@ boolean P_SetupLevel(boolean skipprecip) // Reset the palette -#ifdef HWRENDER - if (rendermode == render_opengl) - HWR_SetPaletteColor(0); - else -#endif if (rendermode != render_none) V_SetPaletteLump("PLAYPAL"); diff --git a/src/st_stuff.c b/src/st_stuff.c index 3562a9b71..72e0b6b94 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -210,17 +210,17 @@ void ST_doPaletteStuff(void) else palette = 0; +#ifdef HWRENDER + if (rendermode == render_opengl) + palette = 0; // No flashpals here in OpenGL +#endif + palette = min(max(palette, 0), 13); if (palette != st_palette) { st_palette = palette; -#ifdef HWRENDER - if (rendermode == render_opengl) - HWR_SetPaletteColor(0); - else -#endif if (rendermode != render_none) { V_SetPaletteLump(GetPalette()); // Reset the palette From 001e4e11ca1dfd0ded1bbc29e26f71be50c86aac Mon Sep 17 00:00:00 2001 From: Tasos Sahanidis Date: Thu, 17 May 2018 17:55:38 +0300 Subject: [PATCH 53/56] Correct C FixedMul() off-by-one errors The FixedMul() C implementation would produce off by one results, causing constant desyncs on 64 bit builds and builds without an ASM implementation of the function. This is fixed by shifting instead of dividing, possibly avoiding rounding errors. --- src/m_fixed.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/m_fixed.c b/src/m_fixed.c index ce7471a28..014457386 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -33,7 +33,9 @@ */ fixed_t FixedMul(fixed_t a, fixed_t b) { - return (fixed_t)((((INT64)a * b) ) / FRACUNIT); + // Need to cast to unsigned before shifting to avoid undefined behaviour + // for negative integers + return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS); } #endif //__USE_C_FIXEDMUL__ From f4181f7eb6203af8d8363cd03a351d8b780061da Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 26 May 2018 13:13:37 +0100 Subject: [PATCH 54/56] Very large map rendering issue fixed Move old fix for too large maps having rendering issues from R_CheckBBox to OpenGL's HWR_CheckBBox From what I know, this effects at least Aerial Garden and Seraphic Skylands --- src/hardware/hw_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 81021ef7f..059a09b15 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2901,8 +2901,8 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) py2 = bspcoord[checkcoord[boxpos][3]]; // check clip list for an open space - angle1 = R_PointToAngle(px1, py1) - dup_viewangle; - angle2 = R_PointToAngle(px2, py2) - dup_viewangle; + angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle; + angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle; span = angle1 - angle2; From 41e9c20c04bde872c794e2a8287baba627bedc25 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 28 May 2018 21:29:46 +0100 Subject: [PATCH 55/56] Ignore mouse button events if the mouse's focus is not actually on the window at the moment. This should hopefully kill the F12 getting stuck issue once and for all. --- src/sdl/i_video.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 87ce84158..4eab0ae3c 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -658,6 +658,14 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type) SDL_memset(&event, 0, sizeof(event_t)); + // Ignore the event if the mouse is not actually focused on the window. + // This can happen if you used the mouse to restore keyboard focus; + // this apparently makes a mouse button down event but not a mouse button up event, + // resulting in whatever key was pressed down getting "stuck" if we don't ignore it. + // -- Monster Iestyn (28/05/18) + if (SDL_GetMouseFocus() != window) + return; + /// \todo inputEvent.button.which if (USE_MOUSEINPUT) { From 415c0952740f8dd0587f07e0688286ebf60a6e27 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 26 Jun 2018 17:46:04 +0100 Subject: [PATCH 56/56] fix the multiplayer menu not allowing the full max length for player names unlike the "name" console command --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 0ab771579..79ac6800b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6543,7 +6543,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice) if (choice < 32 || choice > 127 || itemOn != 0) break; l = strlen(setupm_name); - if (l < MAXPLAYERNAME-1) + if (l < MAXPLAYERNAME) { S_StartSound(NULL,sfx_menu1); // Tails setupm_name[l] =(char)choice;