From 6877930ed9f1b52c76117c64a9215ea0a51d49c9 Mon Sep 17 00:00:00 2001 From: Sryder13 Date: Fri, 8 Sep 2017 00:56:58 +0100 Subject: [PATCH 01/66] 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/66] 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/66] 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 e63c1d15d87bd4fbbb583a88145bd840c9a17972 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 17 Nov 2017 23:02:34 +0000 Subject: [PATCH 04/66] * Show an emerald token box on the tally screen. * Change the horizontal spacing of the emeralds on the special stage tally screen. * (unrelated) Fix a reference to srb2.srb instead of the now-correct srb2.pk3. --- src/d_main.c | 2 +- src/hu_stuff.c | 70 ++++++++++++++++++++++++++++---------------------- src/hu_stuff.h | 3 +-- src/m_menu.c | 2 +- src/st_stuff.c | 14 +++++----- src/y_inter.c | 33 ++++++++++++++++-------- 6 files changed, 71 insertions(+), 53 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 45f9d6763..b3039ee83 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -832,7 +832,7 @@ static void IdentifyVersion(void) else if (srb2wad1 != NULL && FIL_ReadFileOK(srb2wad1)) D_AddFile(srb2wad1); else - I_Error("SRB2.SRB/SRB2.WAD not found! Expected in %s, ss files: %s and %s\n", srb2waddir, srb2wad1, srb2wad2); + I_Error("SRB2.PK3/SRB2.WAD not found! Expected in %s, ss files: %s and %s\n", srb2waddir, srb2wad1, srb2wad2); if (srb2wad1) free(srb2wad1); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 28b20f61e..ff79bd1e3 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -89,8 +89,7 @@ patch_t *tallinfin; // coop hud //------------------------------------------- -patch_t *emeraldpics[7]; -patch_t *tinyemeraldpics[7]; +patch_t *emeraldpics[3][7]; // 0 = normal, 1 = tiny, 2 = coinbox static patch_t *emblemicon; patch_t *tokenicon; static patch_t *exiticon; @@ -250,20 +249,29 @@ void HU_LoadGraphics(void) tokenicon = W_CachePatchName("TOKNICON", PU_HUDGFX); exiticon = W_CachePatchName("EXITICON", PU_HUDGFX); - emeraldpics[0] = W_CachePatchName("CHAOS1", PU_HUDGFX); - emeraldpics[1] = W_CachePatchName("CHAOS2", PU_HUDGFX); - emeraldpics[2] = W_CachePatchName("CHAOS3", PU_HUDGFX); - emeraldpics[3] = W_CachePatchName("CHAOS4", PU_HUDGFX); - emeraldpics[4] = W_CachePatchName("CHAOS5", PU_HUDGFX); - emeraldpics[5] = W_CachePatchName("CHAOS6", PU_HUDGFX); - emeraldpics[6] = W_CachePatchName("CHAOS7", PU_HUDGFX); - tinyemeraldpics[0] = W_CachePatchName("TEMER1", PU_HUDGFX); - tinyemeraldpics[1] = W_CachePatchName("TEMER2", PU_HUDGFX); - tinyemeraldpics[2] = W_CachePatchName("TEMER3", PU_HUDGFX); - tinyemeraldpics[3] = W_CachePatchName("TEMER4", PU_HUDGFX); - tinyemeraldpics[4] = W_CachePatchName("TEMER5", PU_HUDGFX); - tinyemeraldpics[5] = W_CachePatchName("TEMER6", PU_HUDGFX); - tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX); + emeraldpics[0][0] = W_CachePatchName("CHAOS1", PU_HUDGFX); + emeraldpics[0][1] = W_CachePatchName("CHAOS2", PU_HUDGFX); + emeraldpics[0][2] = W_CachePatchName("CHAOS3", PU_HUDGFX); + emeraldpics[0][3] = W_CachePatchName("CHAOS4", PU_HUDGFX); + emeraldpics[0][4] = W_CachePatchName("CHAOS5", PU_HUDGFX); + emeraldpics[0][5] = W_CachePatchName("CHAOS6", PU_HUDGFX); + emeraldpics[0][6] = W_CachePatchName("CHAOS7", PU_HUDGFX); + + emeraldpics[1][0] = W_CachePatchName("TEMER1", PU_HUDGFX); + emeraldpics[1][1] = W_CachePatchName("TEMER2", PU_HUDGFX); + emeraldpics[1][2] = W_CachePatchName("TEMER3", PU_HUDGFX); + emeraldpics[1][3] = W_CachePatchName("TEMER4", PU_HUDGFX); + emeraldpics[1][4] = W_CachePatchName("TEMER5", PU_HUDGFX); + emeraldpics[1][5] = W_CachePatchName("TEMER6", PU_HUDGFX); + emeraldpics[2][6] = W_CachePatchName("TEMER7", PU_HUDGFX); + + emeraldpics[2][0] = W_CachePatchName("EMBOX1", PU_HUDGFX); + emeraldpics[2][1] = W_CachePatchName("EMBOX2", PU_HUDGFX); + emeraldpics[2][2] = W_CachePatchName("EMBOX3", PU_HUDGFX); + emeraldpics[2][3] = W_CachePatchName("EMBOX4", PU_HUDGFX); + emeraldpics[2][4] = W_CachePatchName("EMBOX5", PU_HUDGFX); + emeraldpics[2][5] = W_CachePatchName("EMBOX6", PU_HUDGFX); + emeraldpics[2][6] = W_CachePatchName("EMBOX7", PU_HUDGFX); } // Initialise Heads up @@ -1466,25 +1474,25 @@ void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds) { //Draw the emeralds, in the CORRECT order, using tiny emerald sprites. if (pemeralds & EMERALD1) - V_DrawSmallScaledPatch(x , y-6, 0, tinyemeraldpics[0]); + V_DrawSmallScaledPatch(x , y-6, 0, emeraldpics[1][0]); if (pemeralds & EMERALD2) - V_DrawSmallScaledPatch(x+4, y-3, 0, tinyemeraldpics[1]); + V_DrawSmallScaledPatch(x+4, y-3, 0, emeraldpics[1][1]); if (pemeralds & EMERALD3) - V_DrawSmallScaledPatch(x+4, y+3, 0, tinyemeraldpics[2]); + V_DrawSmallScaledPatch(x+4, y+3, 0, emeraldpics[1][2]); if (pemeralds & EMERALD4) - V_DrawSmallScaledPatch(x , y+6, 0, tinyemeraldpics[3]); + V_DrawSmallScaledPatch(x , y+6, 0, emeraldpics[1][3]); if (pemeralds & EMERALD5) - V_DrawSmallScaledPatch(x-4, y+3, 0, tinyemeraldpics[4]); + V_DrawSmallScaledPatch(x-4, y+3, 0, emeraldpics[1][4]); if (pemeralds & EMERALD6) - V_DrawSmallScaledPatch(x-4, y-3, 0, tinyemeraldpics[5]); + V_DrawSmallScaledPatch(x-4, y-3, 0, emeraldpics[1][5]); if (pemeralds & EMERALD7) - V_DrawSmallScaledPatch(x, y, 0, tinyemeraldpics[6]); + V_DrawSmallScaledPatch(x, y, 0, emeraldpics[1][6]); } // @@ -1753,19 +1761,19 @@ static void HU_DrawCoopOverlay(void) #endif if (emeralds & EMERALD1) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)-32, 0, emeraldpics[0]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)-32, 0, emeraldpics[0][0]); if (emeralds & EMERALD2) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[1]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[0][1]); if (emeralds & EMERALD3) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[2]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8+24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[0][2]); if (emeralds & EMERALD4) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)+32, 0, emeraldpics[3]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3)+32, 0, emeraldpics[0][3]); if (emeralds & EMERALD5) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[4]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)+16, 0, emeraldpics[0][4]); if (emeralds & EMERALD6) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[5]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8-24, (BASEVIDHEIGHT/3)-16, 0, emeraldpics[0][5]); if (emeralds & EMERALD7) - V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3) , 0, emeraldpics[6]); + V_DrawScaledPatch((BASEVIDWIDTH/2)-8 , (BASEVIDHEIGHT/3) , 0, emeraldpics[0][6]); } static void HU_DrawNetplayCoopOverlay(void) @@ -1780,7 +1788,7 @@ static void HU_DrawNetplayCoopOverlay(void) for (i = 0; i < 7; ++i) { if (emeralds & (1 << i)) - V_DrawScaledPatch(20 + (i * 20), 6, 0, emeraldpics[i]); + V_DrawScaledPatch(20 + (i * 20), 6, 0, emeraldpics[0][i]); } } diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 2dbeb556d..fb1fa1817 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -63,8 +63,7 @@ extern patch_t *tallnum[10]; extern patch_t *nightsnum[10]; extern patch_t *lt_font[LT_FONTSIZE]; extern patch_t *cred_font[CRED_FONTSIZE]; -extern patch_t *emeraldpics[7]; -extern patch_t *tinyemeraldpics[7]; +extern patch_t *emeraldpics[3][7]; extern patch_t *rflagico; extern patch_t *bflagico; extern patch_t *rmatcico; diff --git a/src/m_menu.c b/src/m_menu.c index dedbd86f0..6979c73b5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6274,7 +6274,7 @@ static void M_DrawLoadGameData(void) for (j = 0; j < 7; ++j) { if (savegameinfo[savetodraw].numemeralds & (1 << j)) - V_DrawScaledPatch(workx, y, 0, tinyemeraldpics[j]); + V_DrawScaledPatch(workx, y, 0, emeraldpics[1][j]); workx += 10; } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 437b6758a..24f4e590b 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1699,33 +1699,33 @@ static void ST_drawMatchHUD(void) offset = 136; // Used for Y now if (stplyr->powers[pw_emeralds] & EMERALD1) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[0]); + V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][0]); offset += 8; if (stplyr->powers[pw_emeralds] & EMERALD2) - V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[1]); + V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][1]); if (stplyr->powers[pw_emeralds] & EMERALD6) - V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[5]); + V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][5]); offset += 16; if (stplyr->powers[pw_emeralds] & EMERALD3) - V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[2]); + V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][2]); if (stplyr->powers[pw_emeralds] & EMERALD5) - V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[4]); + V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][4]); offset += 8; if (stplyr->powers[pw_emeralds] & EMERALD4) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[3]); + V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][3]); offset -= 16; if (stplyr->powers[pw_emeralds] & EMERALD7) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[6]); + V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][6]); #ifdef HAVE_BLUA } diff --git a/src/y_inter.c b/src/y_inter.c index 8a93b3eab..9c4d684ac 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -176,12 +176,23 @@ static INT32 SCY(INT32 z) static void Y_IntermissionTokenDrawer(void) { - INT32 y; - INT32 offs = 0; + INT32 y, offs, lowy, calc; UINT32 tokencount; - INT32 lowy = BASEVIDHEIGHT - 32; - INT16 temp = SHORT(tokenicon->height)/2; - INT32 calc; + INT16 temp; + UINT8 em; + + offs = 0; + lowy = BASEVIDHEIGHT - 32 - 8; + temp = SHORT(tokenicon->height)/2; + + if (!(emeralds & EMERALD1)) em = 0; + else if (!(emeralds & EMERALD2)) em = 1; + else if (!(emeralds & EMERALD3)) em = 2; + else if (!(emeralds & EMERALD4)) em = 3; + else if (!(emeralds & EMERALD5)) em = 4; + else if (!(emeralds & EMERALD6)) em = 5; + else if (!(emeralds & EMERALD7)) em = 6; + else return; if (tallydonetic != -1) { @@ -190,7 +201,7 @@ static void Y_IntermissionTokenDrawer(void) offs = 8; } - V_DrawFill(32, lowy-1, 16, 1, 31); // slot + V_DrawSmallScaledPatch(32, lowy-1, 0, emeraldpics[2][em]); // coinbox y = (lowy + offs + 1) - (temp + (token + 1)*8); @@ -370,14 +381,14 @@ void Y_IntermissionDrawer(void) } // draw the emeralds - if (intertic & 1) + //if (intertic & 1) { - INT32 emeraldx = 80; + INT32 emeraldx = 152 - 3*28; for (i = 0; i < 7; ++i) { - if (emeralds & (1 << i)) - V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[i]); - emeraldx += 24; + if ((emeralds & (1 << i)) && ((intertic & 1) || i != (gamemap + 1 - sstage_start))) + V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[0][i]); + emeraldx += 28; } } From 3d4adaac0908e52bc5ad39c92f78c7b1e8e9d922 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 9 Dec 2017 18:48:25 +0000 Subject: [PATCH 05/66] my mistake --- src/hu_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index ff79bd1e3..7af7aa768 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -263,7 +263,7 @@ void HU_LoadGraphics(void) emeraldpics[1][3] = W_CachePatchName("TEMER4", PU_HUDGFX); emeraldpics[1][4] = W_CachePatchName("TEMER5", PU_HUDGFX); emeraldpics[1][5] = W_CachePatchName("TEMER6", PU_HUDGFX); - emeraldpics[2][6] = W_CachePatchName("TEMER7", PU_HUDGFX); + emeraldpics[1][6] = W_CachePatchName("TEMER7", PU_HUDGFX); emeraldpics[2][0] = W_CachePatchName("EMBOX1", PU_HUDGFX); emeraldpics[2][1] = W_CachePatchName("EMBOX2", PU_HUDGFX); From ce724a61385b860f47ca0636f4eeedc1c5d88e52 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 9 Dec 2017 23:08:12 +0000 Subject: [PATCH 06/66] * Make lives pic appear in all gametypes. * Lives position now more consistent between players in splitscreen. * Ringslinger weapon bar is now at the same height as the lives pic, and also more centered horizontally. * Begin tweaking emerald icon locations for ringslinger gametypes. * Remove in-game team names from team gametypes, since this information is (mostly) conveyed by the lives pic. --- src/st_stuff.c | 129 +++++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 63 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 24f4e590b..98a4b7d95 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -688,29 +688,34 @@ static inline void ST_drawRings(void) ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); } -static void ST_drawLives(void) +static void ST_drawLivesPic(void) { - const INT32 v_splitflag = (splitscreen && stplyr == &players[displayplayer] ? V_SPLITSCREEN : 0); - INT32 livescount; - boolean notgreyedout; + const INT32 y = STRINGY(hudinfo[HUD_LIVESPIC].y+16)-16; if (!stplyr->skincolor) return; // Just joined a server, skin isn't loaded yet! // face background - V_DrawSmallScaledPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, livesback); + V_DrawSmallScaledPatch(hudinfo[HUD_LIVESPIC].x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, livesback); // face - if (stplyr->mo && stplyr->mo->color) + if (stplyr->spectator) + { + // spectator face + UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, SKINCOLOR_CLOUDY, GTC_CACHE); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); + } + else if (stplyr->mo && stplyr->mo->color) { // skincolor face/super UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->color, GTC_CACHE); patch_t *face = faceprefix[stplyr->skin]; if (stplyr->powers[pw_super]) face = superprefix[stplyr->skin]; - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag,face, colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, face, colormap); if (cv_translucenthud.value == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer) { INT32 v_supertrans = (stplyr->mo->tracer->frame & FF_TRANSMASK) >> FF_TRANSSHIFT; @@ -718,8 +723,8 @@ static void ST_drawLives(void) { v_supertrans <<= V_ALPHASHIFT; colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->tracer->color, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|v_supertrans|v_splitflag,face, colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|v_supertrans, face, colormap); } } } @@ -727,20 +732,30 @@ static void ST_drawLives(void) { // skincolor face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, hudinfo[HUD_LIVESPIC].y + (v_splitflag ? -12 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag,faceprefix[stplyr->skin], colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, faceprefix[stplyr->skin], colormap); } +} + +static void ST_drawLives(void) +{ + const INT32 y = STRINGY(hudinfo[HUD_LIVESNAME].y+16)-16; + INT32 livescount; + boolean notgreyedout; + + if (!stplyr->skincolor) + return; // Just joined a server, skin isn't loaded yet! // name if (strlen(skins[stplyr->skin].hudname) > 8) - V_DrawThinString(hudinfo[HUD_LIVESNAME].x, hudinfo[HUD_LIVESNAME].y + (v_splitflag ? -12 : 0), - V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP|v_splitflag, skins[stplyr->skin].hudname); + V_DrawThinString(hudinfo[HUD_LIVESNAME].x, y, + V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP, skins[stplyr->skin].hudname); else - V_DrawString(hudinfo[HUD_LIVESNAME].x, hudinfo[HUD_LIVESNAME].y + (v_splitflag ? -12 : 0), - V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP|v_splitflag, skins[stplyr->skin].hudname); + V_DrawString(hudinfo[HUD_LIVESNAME].x, y, + V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP, skins[stplyr->skin].hudname); // x - V_DrawScaledPatch(hudinfo[HUD_LIVESX].x, hudinfo[HUD_LIVESX].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, stlivex); + V_DrawScaledPatch(hudinfo[HUD_LIVESX].x, y+8, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, stlivex); // lives number if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) @@ -775,20 +790,20 @@ static void ST_drawLives(void) } if (livescount == 0x7f) - V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, false); + V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, y+8, + '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, false); else { if (livescount > 99) livescount = 99; - V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0), - V_SNAPTOLEFT|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF)|v_splitflag, + V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, y+8, + V_SNAPTOLEFT|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), ((livescount > 99) ? "!!" : va("%d",livescount))); } } static void ST_drawInput(void) { - //const INT32 v_splitflag = (splitscreen && stplyr == &players[displayplayer] ? V_SPLITSCREEN : 0); -- no splitscreen support - record attack only for base game const UINT8 accent = (stplyr->skincolor ? Color_Index[stplyr->skincolor-1][4] : 0); UINT8 col, offs; @@ -1620,7 +1635,7 @@ static void ST_drawNiGHTSHUD(void) splitscreen = true; } -static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, INT32 xoffs, patch_t *pat) +static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, INT32 xoffs, INT32 y, patch_t *pat) { INT32 txtflags = 0, patflags = 0; @@ -1638,23 +1653,24 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I patflags = V_80TRANS; } - V_DrawScaledPatch(8 + xoffs, STRINGY(162), V_SNAPTOLEFT|patflags, pat); + V_DrawScaledPatch(8 + xoffs, y, V_SNAPTOLEFT|patflags, pat); if (stplyr->powers[weapon] > 99) - V_DrawThinString(8 + xoffs + 1, STRINGY(162), V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); + V_DrawThinString(8 + xoffs + 1, y, V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); else - V_DrawString(8 + xoffs, STRINGY(162), V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); + V_DrawString(8 + xoffs, y, V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); if (stplyr->currentweapon == wepflag) - V_DrawScaledPatch(6 + xoffs, STRINGY(162 - (splitscreen ? 4 : 2)), V_SNAPTOLEFT, curweapon); + V_DrawScaledPatch(6 + xoffs, y-2, V_SNAPTOLEFT, curweapon); } else if (stplyr->ringweapons & rwflag) - V_DrawScaledPatch(8 + xoffs, STRINGY(162), V_SNAPTOLEFT|V_TRANSLUCENT, pat); + V_DrawScaledPatch(8 + xoffs, y, V_SNAPTOLEFT|V_TRANSLUCENT, pat); } static void ST_drawMatchHUD(void) { - INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10); + const INT32 y = STRINGY(176+16)-16; // HUD_LIVESPIC + INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10) - 6; if (!G_RingSlingerGametype()) return; @@ -1667,27 +1683,27 @@ static void ST_drawMatchHUD(void) #endif if (stplyr->powers[pw_infinityring]) - ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring); + ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring); else if (stplyr->rings > 0) - V_DrawScaledPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT, normring); + V_DrawScaledPatch(8 + offset, y, V_SNAPTOLEFT, normring); else - V_DrawTranslucentPatch(8 + offset, STRINGY(162), V_SNAPTOLEFT|V_80TRANS, normring); + V_DrawTranslucentPatch(8 + offset, y, V_SNAPTOLEFT|V_80TRANS, normring); if (!stplyr->currentweapon) - V_DrawScaledPatch(6 + offset, STRINGY(162 - (splitscreen ? 4 : 2)), V_SNAPTOLEFT, curweapon); + V_DrawScaledPatch(6 + offset, y-2, V_SNAPTOLEFT, curweapon); offset += 20; - ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, autoring); + ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring); offset += 20; - ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, bouncering); + ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, y, bouncering); offset += 20; - ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, scatterring); + ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, y, scatterring); offset += 20; - ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, grenadering); + ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, y, grenadering); offset += 20; - ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, explosionring); + ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, y, explosionring); offset += 20; - ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, railring); + ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, y, railring); #ifdef HAVE_BLUA } @@ -1696,36 +1712,36 @@ static void ST_drawMatchHUD(void) #endif // Power Stones collected - offset = 136; // Used for Y now + offset = STRINGY(128); // Used for Y now if (stplyr->powers[pw_emeralds] & EMERALD1) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][0]); + V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][0]); offset += 8; if (stplyr->powers[pw_emeralds] & EMERALD2) - V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][1]); + V_DrawScaledPatch(40, offset, V_SNAPTOLEFT, emeraldpics[1][1]); if (stplyr->powers[pw_emeralds] & EMERALD6) - V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][5]); + V_DrawScaledPatch(16, offset, V_SNAPTOLEFT, emeraldpics[1][5]); offset += 16; if (stplyr->powers[pw_emeralds] & EMERALD3) - V_DrawScaledPatch(40, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][2]); + V_DrawScaledPatch(40, offset, V_SNAPTOLEFT, emeraldpics[1][2]); if (stplyr->powers[pw_emeralds] & EMERALD5) - V_DrawScaledPatch(16, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][4]); + V_DrawScaledPatch(16, offset, V_SNAPTOLEFT, emeraldpics[1][4]); offset += 8; if (stplyr->powers[pw_emeralds] & EMERALD4) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][3]); + V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][3]); offset -= 16; if (stplyr->powers[pw_emeralds] & EMERALD7) - V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, emeraldpics[1][6]); + V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][6]); #ifdef HAVE_BLUA } @@ -1880,17 +1896,6 @@ static void ST_drawCTFHUD(void) } } -// Draws "Red Team", "Blue Team", or "Spectator" for team gametypes. -static inline void ST_drawTeamName(void) -{ - if (stplyr->ctfteam == 1) - V_DrawString(256, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "RED TEAM"); - else if (stplyr->ctfteam == 2) - V_DrawString(248, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "BLUE TEAM"); - else - V_DrawString(244, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "SPECTATOR"); -} - static void ST_drawSpecialStageHUD(void) { if (totalrings > 0) @@ -2061,6 +2066,8 @@ static void ST_overlayDrawer(void) if (LUA_HudEnabled(hud_rings)) #endif ST_drawRings(); + + ST_drawLivesPic(); // always do on mystic's request - allows us to kill "RED/BLUE TEAM" text if (G_GametypeUsesLives() #ifdef HAVE_BLUA && LUA_HudEnabled(hud_lives) @@ -2142,10 +2149,6 @@ static void ST_overlayDrawer(void) else if (gametype == GT_CTF) ST_drawCTFHUD(); - // Team names for team gametypes - if (G_GametypeHasTeams()) - ST_drawTeamName(); - // Special Stage HUD if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer]) ST_drawSpecialStageHUD(); From 336a26602d0d783ff5acf9a13bf6e8dd057eabf2 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 10 Dec 2017 14:35:55 +0000 Subject: [PATCH 07/66] Not strictly pretty, but fixes a bug I discovered whilst working on this. --- src/m_menu.c | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 6979c73b5..25039c596 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2045,35 +2045,7 @@ static void Newgametype_OnChange(void) P_AllocMapHeader((INT16)(cv_nextmap.value-1)); if (!M_CanShowLevelOnPlatter(cv_nextmap.value-1, cv_newgametype.value)) - { - INT32 value = 0; - - switch (cv_newgametype.value) - { - case GT_COOP: - value = TOL_COOP; - break; - case GT_COMPETITION: - value = TOL_COMPETITION; - break; - case GT_RACE: - value = TOL_RACE; - break; - case GT_MATCH: - case GT_TEAMMATCH: - value = TOL_MATCH; - break; - case GT_TAG: - case GT_HIDEANDSEEK: - value = TOL_TAG; - break; - case GT_CTF: - value = TOL_CTF; - break; - } - - CV_SetValue(&cv_nextmap, M_GetFirstLevelInList(value)); - } + CV_SetValue(&cv_nextmap, M_GetFirstLevelInList(cv_newgametype.value)); } } From 2141754e5468fc4366c3ea8870f69920254ace6d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 20 Jan 2018 22:14:24 +0000 Subject: [PATCH 08/66] V_PERPLAYER. (Hooh boy.) * Completely redid how splitscreen works, with eventual support for quads. Squish per-player stuff automatically into the right places! Works in GL, associated flag kills V_SPLITSCREEN. * Seriously update the lives-drawing function for all gametypes, with strings that replace the lives number whenever it's missing (deprecates SKINNAMEPADDING). * Improved how the nosshack works, alongside many other refactorings. --- src/dehacked.c | 16 +- src/doomdef.h | 3 - src/hardware/hw_draw.c | 47 ++- src/r_things.c | 8 - src/st_stuff.c | 782 ++++++++++++++++++----------------------- src/st_stuff.h | 12 +- src/v_video.c | 54 ++- src/v_video.h | 2 +- src/y_inter.c | 62 ++-- 9 files changed, 463 insertions(+), 523 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index cb76c663e..bd4530e00 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6799,32 +6799,22 @@ static const char *const POWERS_LIST[] = { }; static const char *const HUDITEMS_LIST[] = { - "LIVESNAME", - "LIVESPIC", - "LIVESNUM", - "LIVESX", + "LIVES", "RINGS", - "RINGSSPLIT", "RINGSNUM", - "RINGSNUMSPLIT", "SCORE", "SCORENUM", "TIME", - "TIMESPLIT", "MINUTES", - "MINUTESSPLIT", "TIMECOLON", - "TIMECOLONSPLIT", "SECONDS", - "SECONDSSPLIT", "TIMETICCOLON", "TICS", "SS_TOTALRINGS", - "SS_TOTALRINGS_SPLIT", "GETRINGS", "GETRINGSNUM", @@ -7353,7 +7343,7 @@ struct { {"V_WRAPX",V_WRAPX}, {"V_WRAPY",V_WRAPY}, {"V_NOSCALESTART",V_NOSCALESTART}, - {"V_SPLITSCREEN",V_SPLITSCREEN}, + {"V_PERPLAYER",V_PERPLAYER}, {"V_PARAMMASK",V_PARAMMASK}, {"V_SCALEPATCHMASK",V_SCALEPATCHMASK}, @@ -7503,7 +7493,7 @@ static hudnum_t get_huditem(const char *word) if (fastcmp(word, HUDITEMS_LIST[i])) return i; deh_warning("Couldn't find huditem named 'HUD_%s'",word); - return HUD_LIVESNAME; + return HUD_LIVES; } #ifndef HAVE_BLUA diff --git a/src/doomdef.h b/src/doomdef.h index a49fb0207..ee21cf308 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -560,9 +560,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls. //#define PAPER_COLLISIONCORRECTION -/// Hudname padding. -#define SKINNAMEPADDING - /// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up /// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down) /// on the bright side it fixes some weird issues with translucent walls diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index dc97f7014..f902b4802 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -33,6 +33,8 @@ #include "../z_zone.h" #include "../v_video.h" #include "../st_stuff.h" +#include "../p_local.h" // stplyr +#include "../g_game.h" // players #include #include "../i_video.h" // for rendermode != render_glide @@ -181,8 +183,49 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (option & V_NOSCALESTART) sdupx = sdupy = 2.0f; - if (option & V_SPLITSCREEN) - sdupy /= 2.0f; + if (splitscreen && (option & V_PERPLAYER)) + { + float adjusty = ((option & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; + pdupy /= 2; + cy /= 2; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; + pdupx /= 2; + cx /= 2; + if (stplyr == &players[displayplayer]) + option &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + else if (stplyr == &players[secondarydisplayplayer]) + { + cx += adjustx; + option &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + cy += adjusty; + option &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + cx += adjustx; + cy += adjusty; + option &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + option &= ~V_SNAPTOBOTTOM; + else //if (stplyr == &players[secondarydisplayplayer]) + { + cy += adjusty; + option &= ~V_SNAPTOTOP; + } + } + } if (option & V_FLIP) // Need to flip both this and sow { diff --git a/src/r_things.c b/src/r_things.c index d201786a5..fad47d26b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2497,11 +2497,7 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->flags = 0; strcpy(skin->realname, "Someone"); -#ifdef SKINNAMEPADDING - strcpy(skin->hudname, " ???"); -#else strcpy(skin->hudname, "???"); -#endif strncpy(skin->charsel, "CHRSONIC", 8); strncpy(skin->face, "MISSING", 8); strncpy(skin->superface, "MISSING", 8); @@ -2733,11 +2729,7 @@ static UINT16 W_CheckForSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) return INT16_MAX; // not found } -#ifdef SKINNAMEPADDING -#define HUDNAMEWRITE(value) snprintf(skin->hudname, sizeof(skin->hudname), "%5s", value) -#else #define HUDNAMEWRITE(value) STRBUFCPY(skin->hudname, value) -#endif // turn _ into spaces and . into katana dot #define SYMBOLCONVERT(name) for (value = name; *value; value++)\ diff --git a/src/st_stuff.c b/src/st_stuff.c index 98a4b7d95..1426ae405 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -125,33 +125,23 @@ static boolean facefreed[MAXPLAYERS]; hudinfo_t hudinfo[NUMHUDITEMS] = { - { 34, 176}, // HUD_LIVESNAME - { 16, 176}, // HUD_LIVESPIC - { 74, 184}, // HUD_LIVESNUM - { 38, 186}, // HUD_LIVESX + { 16, 176}, // HUD_LIVES { 16, 42}, // HUD_RINGS - { 220, 10}, // HUD_RINGSSPLIT { 96, 42}, // HUD_RINGSNUM - { 296, 10}, // HUD_RINGSNUMSPLIT { 120, 42}, // HUD_RINGSNUMTICS { 16, 10}, // HUD_SCORE { 120, 10}, // HUD_SCORENUM { 16, 26}, // HUD_TIME - { 128, 10}, // HUD_TIMESPLIT { 72, 26}, // HUD_MINUTES - { 188, 10}, // HUD_MINUTESSPLIT { 72, 26}, // HUD_TIMECOLON - { 188, 10}, // HUD_TIMECOLONSPLIT { 96, 26}, // HUD_SECONDS - { 212, 10}, // HUD_SECONDSSPLIT { 96, 26}, // HUD_TIMETICCOLON { 120, 26}, // HUD_TICS { 120, 56}, // HUD_SS_TOTALRINGS - { 296, 40}, // HUD_SS_TOTALRINGS_SPLIT { 110, 93}, // HUD_GETRINGS { 160, 93}, // HUD_GETRINGSNUM @@ -423,84 +413,26 @@ static INT32 SCZ(INT32 z) return FixedInt(FixedMul(z<>= 1; - if (stplyr != &players[displayplayer]) - y += vid.height / 2; - } - return y; -} - -static INT32 STRINGY(INT32 y) -{ - //31/10/99: fixed by Hurdler so it _works_ also in hardware mode - // do not scale to resolution for hardware accelerated - // because these modes always scale by default - if (splitscreen) - { - y >>= 1; - if (stplyr != &players[displayplayer]) - y += BASEVIDHEIGHT / 2; - } - return y; -} - -static INT32 SPLITFLAGS(INT32 f) -{ - // Pass this V_SNAPTO(TOP|BOTTOM) and it'll trim them to account for splitscreen! -Red - if (splitscreen) - { - if (stplyr != &players[displayplayer]) - f &= ~V_SNAPTOTOP; - else - f &= ~V_SNAPTOBOTTOM; - } - return f; -} - static INT32 SCX(INT32 x) { return FixedInt(FixedMul(x<>= 1; - if (stplyr != &players[displayplayer]) - y += vid.height / 2; - } - return FixedInt(FixedDiv(y, vid.fdupy)); -} -#endif - // ========================================================================= // INTERNAL DRAWING // ========================================================================= -#define ST_DrawOverlayNum(x,y,n) V_DrawTallNum(x, y, V_NOSCALESTART|V_HUDTRANS, n) -#define ST_DrawPaddedOverlayNum(x,y,n,d) V_DrawPaddedTallNum(x, y, V_NOSCALESTART|V_HUDTRANS, n, d) -#define ST_DrawOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_NOSCALESTART|V_HUDTRANS, p) -#define ST_DrawMappedOverlayPatch(x,y,p,c) V_DrawMappedScaledPatch(x, y, V_NOSCALESTART|V_HUDTRANS, p, c) -#define ST_DrawNumFromHud(h,n,f) V_DrawTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|f, n) -#define ST_DrawPadNumFromHud(h,n,q,f) V_DrawPaddedTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|f, n, q) -#define ST_DrawPatchFromHud(h,p,f) V_DrawScaledPatch(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART|f, p) -#define ST_DrawNumFromHudWS(h,n,f) V_DrawTallNum(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|f, n) -#define ST_DrawPadNumFromHudWS(h,n,q,f) V_DrawPaddedTallNum(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|f, n, q) -#define ST_DrawPatchFromHudWS(h,p,f) V_DrawScaledPatch(SCX(hudinfo[h+!!splitscreen].x), SCY(hudinfo[h+!!splitscreen].y), V_NOSCALESTART|f, p) +#define ST_DrawUnscaledOverlayNum(x,y,n) V_DrawTallNum(x, y, V_NOSCALESTART|V_PERPLAYER|V_HUDTRANS, n) +#define ST_DrawUnscaledPaddedOverlayNum(x,y,n,d) V_DrawPaddedTallNum(x, y, V_NOSCALESTART|V_PERPLAYER|V_HUDTRANS, n, d) +#define ST_DrawUnscaledOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_NOSCALESTART|V_PERPLAYER|V_HUDTRANS, p) +#define ST_DrawTopLeftOverlayNum(x,y,n) V_DrawTallNum(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, n) +#define ST_DrawTopLeftOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p) +#define ST_DrawMappedOverlayPatch(x,y,p,c) V_DrawMappedScaledPatch(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p, c) +#define ST_DrawNumFromHud(h,n,f) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n) +#define ST_DrawPadNumFromHud(h,n,q,f) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n, q) +#define ST_DrawPatchFromHud(h,p,f) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, p) +#define ST_DrawNumFromHudWS(h,n,f) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n) +#define ST_DrawPadNumFromHudWS(h,n,q,f) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n, q) +#define ST_DrawPatchFromHudWS(h,p,f) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, p) // Draw a number, scaled, over the view, maybe with set translucency // Always draw the number completely since it's overlay @@ -617,7 +549,7 @@ static void ST_drawScore(void) if (objectplacing) { if (op_displayflags > UINT16_MAX) - ST_DrawOverlayPatch(SCX(hudinfo[HUD_SCORENUM].x-tallminus->width), SCY(hudinfo[HUD_SCORENUM].y), tallminus); + ST_DrawTopLeftOverlayPatch((hudinfo[HUD_SCORENUM].x-tallminus->width), hudinfo[HUD_SCORENUM].y, tallminus); else ST_DrawNumFromHud(HUD_SCORENUM, op_displayflags, V_HUDTRANS); } @@ -655,7 +587,7 @@ static void ST_drawTime(void) ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon ST_DrawPadNumFromHudWS(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds - if (!splitscreen && (cv_timetic.value == 2 || cv_timetic.value == 3 || modeattacking)) // there's not enough room for tics in splitscreen, don't even bother trying! + if (cv_timetic.value == 2 || cv_timetic.value == 3 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! { ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod, V_HUDTRANS); // Period ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2, V_HUDTRANS); // Tics @@ -682,30 +614,31 @@ static inline void ST_drawRings(void) else ringnum = max(stplyr->rings, 0); - if (!splitscreen && cv_timetic.value == 3) // Yes, even in modeattacking - ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + if (cv_timetic.value == 3) // Yes, even in modeattacking + ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); else - ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); } -static void ST_drawLivesPic(void) +static void ST_drawLivesArea(void) { - const INT32 y = STRINGY(hudinfo[HUD_LIVESPIC].y+16)-16; + INT32 v_colmap = V_YELLOWMAP, livescount; + boolean notgreyedout; if (!stplyr->skincolor) return; // Just joined a server, skin isn't loaded yet! // face background - V_DrawSmallScaledPatch(hudinfo[HUD_LIVESPIC].x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, livesback); + V_DrawSmallScaledPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, livesback); // face if (stplyr->spectator) { // spectator face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, SKINCOLOR_CLOUDY, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); } else if (stplyr->mo && stplyr->mo->color) { @@ -714,8 +647,8 @@ static void ST_drawLivesPic(void) patch_t *face = faceprefix[stplyr->skin]; if (stplyr->powers[pw_super]) face = superprefix[stplyr->skin]; - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, face, colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, face, colormap); if (cv_translucenthud.value == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer) { INT32 v_supertrans = (stplyr->mo->tracer->frame & FF_TRANSMASK) >> FF_TRANSSHIFT; @@ -723,8 +656,8 @@ static void ST_drawLivesPic(void) { v_supertrans <<= V_ALPHASHIFT; colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->tracer->color, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|v_supertrans, face, colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|v_supertrans, face, colormap); } } } @@ -732,104 +665,172 @@ static void ST_drawLivesPic(void) { // skincolor face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE); - V_DrawSmallMappedPatch(hudinfo[HUD_LIVESPIC].x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, faceprefix[stplyr->skin], colormap); + V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, faceprefix[stplyr->skin], colormap); } -} -static void ST_drawLives(void) -{ - const INT32 y = STRINGY(hudinfo[HUD_LIVESNAME].y+16)-16; - INT32 livescount; - boolean notgreyedout; - - if (!stplyr->skincolor) - return; // Just joined a server, skin isn't loaded yet! - - // name - if (strlen(skins[stplyr->skin].hudname) > 8) - V_DrawThinString(hudinfo[HUD_LIVESNAME].x, y, - V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP, skins[stplyr->skin].hudname); - else - V_DrawString(hudinfo[HUD_LIVESNAME].x, y, - V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_MONOSPACE|V_YELLOWMAP, skins[stplyr->skin].hudname); - // x - V_DrawScaledPatch(hudinfo[HUD_LIVESX].x, y+8, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, stlivex); - - // lives number - if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) + // Lives number + if (G_GametypeUsesLives()) { - INT32 i; - livescount = 0; - notgreyedout = (stplyr->lives > 0); - for (i = 0; i < MAXPLAYERS; i++) + // x + V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, stlivex); + + // lives number + if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) { - if (!playeringame[i]) - continue; - - if (players[i].lives < 1) - continue; - - if (players[i].lives > 1) - notgreyedout = true; - - if (players[i].lives == 0x7f) + INT32 i; + livescount = 0; + notgreyedout = (stplyr->lives > 0); + for (i = 0; i < MAXPLAYERS; i++) { - livescount = 0x7f; - break; + if (!playeringame[i]) + continue; + + if (players[i].lives < 1) + continue; + + if (players[i].lives > 1) + notgreyedout = true; + + if (players[i].lives == 0x7f) + { + livescount = 0x7f; + break; + } + else if (livescount < 99) + livescount += (players[i].lives); } - else if (livescount < 99) - livescount += (players[i].lives); + } + else + { + livescount = ((cv_cooplives.value == 0) ? 0x7f : stplyr->lives); + notgreyedout = true; + } + + if (livescount == 0x7f) + V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8, + '\x16' | 0x80 | V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, false); + else + { + if (livescount > 99) + livescount = 99; + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, + V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); } } + // Spectator + else if (stplyr->spectator) + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "SPECTATE"); + v_colmap = V_GRAYMAP; + } + // Tag + else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + { + if (stplyr->pflags & PF_TAGIT) + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, (gametype == GT_HIDEANDSEEK) ? "SEEKER" : "IT!"); + v_colmap = V_ORANGEMAP; + } + else if (stplyr->pflags & PF_GAMETYPEOVER) + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANSHALF|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "FAILED"); + v_colmap = V_GRAYMAP; + } + else + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, (gametype == GT_HIDEANDSEEK) ? "HIDER" : "RUNNER"); + v_colmap = V_GREENMAP; + } + } + // Team name + else if (G_GametypeHasTeams()) + { + if (stplyr->ctfteam == 1) + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "RED"); + v_colmap = V_REDMAP; + } + else if (stplyr->ctfteam == 2) + { + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "BLUE"); + v_colmap = V_BLUEMAP; + } + else + v_colmap = V_GRAYMAP; + } else { - livescount = stplyr->lives; - notgreyedout = true; + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "PLAYING"); } - if (livescount == 0x7f) - V_DrawCharacter(hudinfo[HUD_LIVESNUM].x - 8, y+8, - '\x16' | 0x80 | V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, false); + // name + v_colmap |= (V_HUDTRANS|V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM); + if (strlen(skins[stplyr->skin].hudname) <= 5) + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); + else if (V_ThinStringWidth(skins[stplyr->skin].hudname, v_colmap) <= 40) + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); else + V_DrawThinString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); + + // Power Stones collected + if (G_RingSlingerGametype() +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_powerstones) +#endif + ) { - if (livescount > 99) - livescount = 99; - V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, y+8, - V_SNAPTOLEFT|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), - ((livescount > 99) ? "!!" : va("%d",livescount))); + INT32 workx = hudinfo[HUD_LIVES].x+1, j; + if ((leveltime & 1) && stplyr->powers[pw_invulnerability] && (stplyr->powers[pw_sneakers] == stplyr->powers[pw_invulnerability])) // hack; extremely unlikely to be activated unintentionally + { + for (j = 0; j < 7; ++j) // "super" indicator + { + V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, emeraldpics[1][j]); + workx += 8; + } + } + else + { + for (j = 0; j < 7; ++j) // powerstones + { + if (stplyr->powers[pw_emeralds] & (1 << j)) + V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, emeraldpics[1][j]); + workx += 8; + } + } } } static void ST_drawInput(void) { - const UINT8 accent = (stplyr->skincolor ? Color_Index[stplyr->skincolor-1][4] : 0); - UINT8 col, offs; + const INT32 accent = V_SNAPTOLEFT|V_SNAPTOBOTTOM|(stplyr->skincolor ? Color_Index[stplyr->skincolor-1][4] : 0); + INT32 col; + UINT8 offs; - INT32 x = hudinfo[HUD_LIVESPIC].x, y = hudinfo[HUD_LIVESPIC].y; + INT32 x = hudinfo[HUD_LIVES].x, y = hudinfo[HUD_LIVES].y; if (stplyr->powers[pw_carry] == CR_NIGHTSMODE) y -= 16; // O backing - V_DrawFill(x, y-1, 16, 16, 20); - V_DrawFill(x, y+15, 16, 1, 29); + V_DrawFill(x, y-1, 16, 16, V_SNAPTOLEFT|V_SNAPTOBOTTOM|20); + V_DrawFill(x, y+15, 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); if (cv_showinputjoy.value) // joystick render! { - /*V_DrawFill(x , y , 16, 1, 16); - V_DrawFill(x , y+15, 16, 1, 16); - V_DrawFill(x , y+ 1, 1, 14, 16); - V_DrawFill(x+15, y+ 1, 1, 14, 16); -- red's outline*/ + /*V_DrawFill(x , y , 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); + V_DrawFill(x , y+15, 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); + V_DrawFill(x , y+ 1, 1, 14, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); + V_DrawFill(x+15, y+ 1, 1, 14, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); -- red's outline*/ if (stplyr->cmd.sidemove || stplyr->cmd.forwardmove) { // joystick hole - V_DrawFill(x+5, y+4, 6, 6, 29); + V_DrawFill(x+5, y+4, 6, 6, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); // joystick top V_DrawFill(x+3+stplyr->cmd.sidemove/12, y+2-stplyr->cmd.forwardmove/12, - 10, 10, 29); + 10, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); V_DrawFill(x+3+stplyr->cmd.sidemove/9, y+1-stplyr->cmd.forwardmove/9, 10, 10, accent); @@ -837,10 +838,10 @@ static void ST_drawInput(void) else { // just a limited, greyed out joystick top - V_DrawFill(x+3, y+11, 10, 1, 29); + V_DrawFill(x+3, y+11, 10, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); V_DrawFill(x+3, y+1, - 10, 10, 16); + 10, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); } } else // arrows! @@ -854,10 +855,10 @@ static void ST_drawInput(void) else { offs = 1; - col = 16; - V_DrawFill(x- 2, y+10, 6, 1, 29); - V_DrawFill(x+ 4, y+ 9, 1, 1, 29); - V_DrawFill(x+ 5, y+ 8, 1, 1, 29); + col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; + V_DrawFill(x- 2, y+10, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+ 4, y+ 9, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+ 5, y+ 8, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); } V_DrawFill(x- 2, y+ 5-offs, 6, 6, col); V_DrawFill(x+ 4, y+ 6-offs, 1, 4, col); @@ -872,12 +873,12 @@ static void ST_drawInput(void) else { offs = 1; - col = 16; - V_DrawFill(x+ 5, y+ 3, 1, 1, 29); - V_DrawFill(x+ 6, y+ 4, 1, 1, 29); - V_DrawFill(x+ 7, y+ 5, 2, 1, 29); - V_DrawFill(x+ 9, y+ 4, 1, 1, 29); - V_DrawFill(x+10, y+ 3, 1, 1, 29); + col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; + V_DrawFill(x+ 5, y+ 3, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+ 6, y+ 4, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+ 7, y+ 5, 2, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+ 9, y+ 4, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+10, y+ 3, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); } V_DrawFill(x+ 5, y- 2-offs, 6, 6, col); V_DrawFill(x+ 6, y+ 4-offs, 4, 1, col); @@ -892,10 +893,10 @@ static void ST_drawInput(void) else { offs = 1; - col = 16; - V_DrawFill(x+12, y+10, 6, 1, 29); - V_DrawFill(x+11, y+ 9, 1, 1, 29); - V_DrawFill(x+10, y+ 8, 1, 1, 29); + col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; + V_DrawFill(x+12, y+10, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+11, y+ 9, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+10, y+ 8, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); } V_DrawFill(x+12, y+ 5-offs, 6, 6, col); V_DrawFill(x+11, y+ 6-offs, 1, 4, col); @@ -910,8 +911,8 @@ static void ST_drawInput(void) else { offs = 1; - col = 16; - V_DrawFill(x+ 5, y+17, 6, 1, 29); + col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; + V_DrawFill(x+ 5, y+17, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); } V_DrawFill(x+ 5, y+12-offs, 6, 6, col); V_DrawFill(x+ 6, y+11-offs, 4, 1, col); @@ -927,16 +928,16 @@ static void ST_drawInput(void) else\ {\ offs = 1;\ - col = 16;\ - V_DrawFill(x+16+(xoffs), y+9+(yoffs), 10, 1, 29);\ + col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16;\ + V_DrawFill(x+16+(xoffs), y+9+(yoffs), 10, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29);\ }\ V_DrawFill(x+16+(xoffs), y+(yoffs)-offs, 10, 10, col);\ - V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, symb, false) + V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, V_SNAPTOLEFT|V_SNAPTOBOTTOM|symb, false) drawbutt( 4,-3, BT_JUMP, 'J'); drawbutt(15,-3, BT_USE, 'S'); - V_DrawFill(x+16+4, y+8, 21, 10, 20); // sundial backing + V_DrawFill(x+16+4, y+8, 21, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|20); // sundial backing if (stplyr->mo) { UINT8 i, precision; @@ -956,7 +957,7 @@ static void ST_drawInput(void) { V_DrawFill(x+16+14-(i*xcomp)/precision, y+12-(i*ycomp)/precision, - 1, 1, 16); + 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); } if (ycomp <= 0) @@ -973,6 +974,7 @@ static void ST_drawInput(void) if (stplyr->pflags & PF_AUTOBRAKE) { V_DrawThinString(x, y, + V_SNAPTOLEFT|V_SNAPTOBOTTOM| ((!stplyr->powers[pw_carry] && (stplyr->pflags & PF_APPLYAUTOBRAKE) && !(stplyr->cmd.sidemove || stplyr->cmd.forwardmove) @@ -983,12 +985,12 @@ static void ST_drawInput(void) } if (stplyr->pflags & PF_ANALOGMODE) { - V_DrawThinString(x, y, 0, "ANALOG"); + V_DrawThinString(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM, "ANALOG"); y -= 8; } } if (!demosynced) // should always be last, so it doesn't push anything else around - V_DrawThinString(x, y, ((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); + V_DrawThinString(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); } static void ST_drawLevelTitle(void) @@ -1067,11 +1069,7 @@ static void ST_drawFirstPersonHUD(void) UINT8 i, max = (player->powers[pw_shield] & SH_FORCEHP); for (i = 0; i <= max; i++) { - INT32 flags = (V_SNAPTORIGHT|V_SNAPTOTOP)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF); - if (splitscreen) - V_DrawSmallScaledPatch(312-(3*i), STRINGY(24)+(3*i), flags, forceshield); - else - V_DrawScaledPatch(304-(3*i), 24+(3*i), flags, forceshield); + V_DrawScaledPatch(304-(3*i), 24+(3*i), (V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF), forceshield); } } else switch (player->powers[pw_shield] & SH_NOSTACK) @@ -1088,29 +1086,16 @@ static void ST_drawFirstPersonHUD(void) } if (p) - { - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24), V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - else - V_DrawScaledPatch(304, 24, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - } + V_DrawScaledPatch(304, 24, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); // pw_flashing just sets the icon to flash no matter what. invulntime = player->powers[pw_flashing] ? 1 : player->powers[pw_invulnerability]; if (invulntime > 3*TICRATE || (invulntime && leveltime & 1)) - { - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24) + 14, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); - else - V_DrawScaledPatch(304, 24 + 28, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); - } + V_DrawScaledPatch(304, 24 + 28, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); if (player->powers[pw_sneakers] > 3*TICRATE || (player->powers[pw_sneakers] && leveltime & 1)) { - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24) + 28, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); - else - V_DrawScaledPatch(304, 24 + 56, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); + V_DrawScaledPatch(304, 24 + 56, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); } p = NULL; @@ -1158,32 +1143,32 @@ static void ST_drawFirstPersonHUD(void) // Display the countdown drown numbers! if (p) - V_DrawScaledPatch(SCX((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset)), SCY(60 - SHORT(p->topoffset)), - V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, p); + V_DrawScaledPatch(SCX((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset)), SCZ(60 - SHORT(p->topoffset)), + V_PERPLAYER|V_NOSCALESTART|V_PERPLAYER|V_OFFSET|V_TRANSLUCENT, p); } static void ST_drawNightsRecords(void) { - INT32 aflag = 0; + INT32 aflag = V_PERPLAYER; if (!stplyr->texttimer) return; if (stplyr->texttimer < TICRATE/2) - aflag = (9 - 9*stplyr->texttimer/(TICRATE/2)) << V_ALPHASHIFT; + aflag |= (9 - 9*stplyr->texttimer/(TICRATE/2)) << V_ALPHASHIFT; // A "Bonus Time Start" by any other name... if (stplyr->textvar == 1) { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(52), V_GREENMAP|aflag, M_GetText("GET TO THE GOAL!")); - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), aflag, M_GetText("SCORE MULTIPLIER START!")); + V_DrawCenteredString(BASEVIDWIDTH/2, 52, V_GREENMAP|aflag, M_GetText("GET TO THE GOAL!")); + V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag, M_GetText("SCORE MULTIPLIER START!")); if (stplyr->finishedtime) { - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(140), aflag, "TIME:"); - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(148), aflag, "BONUS:"); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(140), V_ORANGEMAP|aflag, va("%d", (stplyr->startedtime - stplyr->finishedtime)/TICRATE)); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(148), V_ORANGEMAP|aflag, va("%d", (stplyr->finishedtime/TICRATE) * 100)); + V_DrawString(BASEVIDWIDTH/2 - 48, 140, aflag, "TIME:"); + V_DrawString(BASEVIDWIDTH/2 - 48, 148, aflag, "BONUS:"); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, 140, V_ORANGEMAP|aflag, va("%d", (stplyr->startedtime - stplyr->finishedtime)/TICRATE)); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, 148, V_ORANGEMAP|aflag, va("%d", (stplyr->finishedtime/TICRATE) * 100)); } } @@ -1194,7 +1179,7 @@ static void ST_drawNightsRecords(void) return; // Yes, this string is an abomination. - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), aflag, + V_DrawCenteredString(BASEVIDWIDTH/2, 60, aflag, va(M_GetText("\x80GET\x82 %d\x80 %s%s%s!"), stplyr->capsule->health, (stplyr->textvar == 3) ? M_GetText("MORE ") : "", (G_IsSpecialStage(gamemap)) ? "SPHERE" : "RING", @@ -1204,26 +1189,26 @@ static void ST_drawNightsRecords(void) // End Bonus else if (stplyr->textvar == 4) { - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(140), aflag, (G_IsSpecialStage(gamemap)) ? "ORBS:" : "RINGS:"); - V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(148), aflag, "BONUS:"); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(140), V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings)); - V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(148), V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings * 50)); - ST_DrawNightsOverlayNum((BASEVIDWIDTH/2 + 48)<lastmarescore, nightsnum, SKINCOLOR_AZURE); + V_DrawString(BASEVIDWIDTH/2 - 56, 140, aflag, (G_IsSpecialStage(gamemap)) ? "SPHERES:" : "RINGS:"); + V_DrawString(BASEVIDWIDTH/2 - 56, 148, aflag, "BONUS:"); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings)); + V_DrawRightAlignedString(BASEVIDWIDTH/2 + 56, 140, V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings * 50)); + ST_DrawNightsOverlayNum((BASEVIDWIDTH/2 + 56)<lastmarescore, nightsnum, SKINCOLOR_AZURE); // If new record, say so! if (!(netgame || multiplayer) && G_GetBestNightsScore(gamemap, stplyr->lastmare + 1) <= stplyr->lastmarescore) { if (stplyr->texttimer & 16) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), V_YELLOWMAP|aflag, "* NEW RECORD *"); + V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_YELLOWMAP|aflag, "* NEW RECORD *"); } if (P_HasGrades(gamemap, stplyr->lastmare + 1)) { if (aflag) - V_DrawTranslucentPatch(BASEVIDWIDTH/2 + 60, STRINGY(160), aflag, + V_DrawTranslucentPatch(BASEVIDWIDTH/2 + 60, 160, aflag, ngradeletters[P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare)]); else - V_DrawScaledPatch(BASEVIDWIDTH/2 + 60, STRINGY(160), 0, + V_DrawScaledPatch(BASEVIDWIDTH/2 + 60, 160, 0, ngradeletters[P_GetGrade(stplyr->lastmarescore, gamemap, stplyr->lastmare)]); } } @@ -1276,15 +1261,6 @@ static void ST_drawNiGHTSHUD(void) if (stplyr->texttimer && stplyr->textvar == 4) minlink = INT32_MAX; - if (G_IsSpecialStage(gamemap)) - { // Since special stages share score, time, rings, etc. - // disable splitscreen mode for its HUD. - if (stplyr != &players[displayplayer]) - return; - nosshack = splitscreen; - splitscreen = false; - } - // Drill meter if ( #ifdef HAVE_BLUA @@ -1296,7 +1272,7 @@ static void ST_drawNiGHTSHUD(void) INT32 dfill; UINT8 fillpatch; - if (splitscreen || nosshack) + if (splitscreen) { locx = 110; locy = 188; @@ -1313,46 +1289,29 @@ static void ST_drawNiGHTSHUD(void) else fillpatch = 0; - if (splitscreen) - { // 11-5-14 Replaced the old hack with a slightly better hack. -Red - V_DrawScaledPatch(locx, STRINGY(locy)-3, SPLITFLAGS(V_SNAPTOBOTTOM)|V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), SPLITFLAGS(V_SNAPTOBOTTOM)|V_HUDTRANS, drillfill[fillpatch]); - } - else if (nosshack) - { // Even dirtier hack-of-a-hack to draw seperate drill meters in splitscreen special stages but nothing else. - splitscreen = true; - V_DrawScaledPatch(locx, STRINGY(locy)-3, V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), V_HUDTRANS, drillfill[fillpatch]); - stplyr = &players[secondarydisplayplayer]; - if (stplyr->pflags & PF_DRILLING) - fillpatch = (stplyr->drillmeter & 1) + 1; - else - fillpatch = 0; - V_DrawScaledPatch(locx, STRINGY(locy-3), V_SNAPTOBOTTOM|V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]); - stplyr = &players[displayplayer]; - splitscreen = false; - } - else - { // Draw normally. <:3 - V_DrawScaledPatch(locx, locy, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillbar); - for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) - V_DrawScaledPatch(locx + 2 + dfill, locy + 3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]); - } + V_DrawScaledPatch(locx, locy, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillbar); + for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill) + V_DrawScaledPatch(locx + 2 + dfill, locy + 3, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]); // Display actual drill amount and bumper time - if (cv_debug & DBG_NIGHTSBASIC) + if (!splitscreen && (cv_debug & DBG_NIGHTSBASIC)) { if (stplyr->bumpertime) - V_DrawString(SCX(locx), SCY(locy - 8), V_NOSCALESTART|V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime))); + V_DrawString(SCX(locx), SCZ(locy - 8), V_NOSCALESTART|V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime))); else - V_DrawString(SCX(locx), SCY(locy - 8), V_NOSCALESTART|V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20))); + V_DrawString(SCX(locx), SCZ(locy - 8), V_NOSCALESTART|V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20))); } } + if (G_IsSpecialStage(gamemap)) + { // Since special stages share score, time, rings, etc. + // disable splitscreen mode for its HUD. + if (stplyr != &players[displayplayer]) + return; + nosshack = splitscreen; + splitscreen = false; + } + // Link drawing if ( #ifdef HAVE_BLUA @@ -1361,7 +1320,7 @@ static void ST_drawNiGHTSHUD(void) stplyr->linkcount > minlink) { skincolors_t colornum; - INT32 aflag; + INT32 aflag = V_PERPLAYER; fixed_t x, y, scale; if (stplyr->powers[pw_nights_linkfreeze] && (!(stplyr->powers[pw_nights_linkfreeze] & 2) || (stplyr->powers[pw_nights_linkfreeze] > flashingtics))) @@ -1369,22 +1328,20 @@ static void ST_drawNiGHTSHUD(void) else colornum = linkColor[((stplyr->linkcount-1 >= 300) ? 1 : 0)][((stplyr->linkcount-1) / 5) % NUMLINKCOLORS]; - aflag = ((stplyr->linktimer < 2*TICRATE/3) + aflag |= ((stplyr->linktimer < 2*TICRATE/3) ? (9 - 9*stplyr->linktimer/(2*TICRATE/3)) << V_ALPHASHIFT : 0); - if (splitscreen) + y = (nosshack ? 16+11+(BASEVIDHEIGHT/2) : 160+11)<linktimer) { @@ -1422,11 +1379,11 @@ static void ST_drawNiGHTSHUD(void) if (LUA_HudEnabled(hud_nightsrings)) { #endif - ST_DrawOverlayPatch(SCX(16), SCY(8), nbracket); + ST_DrawTopLeftOverlayPatch(16, 8, nbracket); if (G_IsSpecialStage(gamemap)) - ST_DrawOverlayPatch(SCX(24), SCY(8) + SCZ(8), nsshud); + ST_DrawTopLeftOverlayPatch(24, 16, nsshud); else - ST_DrawOverlayPatch(SCX(24), SCY(8) + SCZ(8), nhud[(leveltime/2)%12]); + ST_DrawTopLeftOverlayPatch(24, 16, nhud[(leveltime/2)%12]); if (G_IsSpecialStage(gamemap)) { @@ -1447,8 +1404,8 @@ static void ST_drawNiGHTSHUD(void) origamount = stplyr->capsule->spawnpoint->angle; I_Assert(origamount > 0); // should not happen now - ST_DrawOverlayPatch(SCX(72), SCY(8), nbracket); - ST_DrawOverlayPatch(SCX(74), SCY(8) + SCZ(4), minicaps); + ST_DrawTopLeftOverlayPatch(72, 8, nbracket); + ST_DrawTopLeftOverlayPatch(74, 8 + 4, minicaps); if (stplyr->capsule->reactiontime != 0) { @@ -1457,10 +1414,10 @@ static void ST_drawNiGHTSHUD(void) for (r = 0; r < 5; r++) { - ST_DrawOverlayPatch(SCX(230 - (7*r)), SCY(144), redstat); - ST_DrawOverlayPatch(SCX(188 - (7*r)), SCY(144), orngstat); - ST_DrawOverlayPatch(SCX(146 - (7*r)), SCY(144), yelstat); - ST_DrawOverlayPatch(SCX(104 - (7*r)), SCY(144), byelstat); + ST_DrawUnscaledOverlayPatch(SCX(230 - (7*r)), SCZ(144), redstat); + ST_DrawUnscaledOverlayPatch(SCX(188 - (7*r)), SCZ(144), orngstat); + ST_DrawUnscaledOverlayPatch(SCX(146 - (7*r)), SCZ(144), yelstat); + ST_DrawUnscaledOverlayPatch(SCX(104 - (7*r)), SCZ(144), byelstat); } amount = (origamount - stplyr->capsule->health); @@ -1479,7 +1436,7 @@ static void ST_drawNiGHTSHUD(void) if (r > 10) ++t; if (r > 5) ++t; - ST_DrawOverlayPatch(SCX(69 + (7*t)), SCY(144), bluestat); + ST_DrawUnscaledOverlayPatch(SCX(69 + (7*t)), SCZ(144), bluestat); } } } @@ -1488,27 +1445,27 @@ static void ST_drawNiGHTSHUD(void) INT32 cfill; // Lil' white box! - V_DrawScaledPatch(15, STRINGY(8) + 34, V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulebar); + V_DrawScaledPatch(15, 8 + 34, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulebar); amount = (origamount - stplyr->capsule->health); amount = (amount * length)/origamount; for (cfill = 0; cfill < amount && cfill < 88; ++cfill) - V_DrawScaledPatch(15 + cfill + 1, STRINGY(8) + 35, V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulefill); + V_DrawScaledPatch(15 + cfill + 1, 8 + 35, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOTOP|V_HUDTRANS, capsulefill); } if (total_ringcount >= stplyr->capsule->health) - ST_DrawOverlayPatch(SCX(40), SCY(8) + SCZ(5), nredar[leveltime%8]); + ST_DrawTopLeftOverlayPatch(40, 8 + 5, nredar[leveltime%8]); else - ST_DrawOverlayPatch(SCX(40), SCY(8) + SCZ(5), narrow[(leveltime/2)%8]); + ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[(leveltime/2)%8]); } else - ST_DrawOverlayPatch(SCX(40), SCY(8) + SCZ(5), narrow[8]); + ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[8]); if (total_ringcount >= 100) - ST_DrawOverlayNum((total_ringcount >= 1000) ? SCX(76) : SCX(72), SCY(8) + SCZ(11), total_ringcount); + ST_DrawTopLeftOverlayNum((total_ringcount >= 1000) ? 76 : 72, 8 + 11, total_ringcount); else - ST_DrawOverlayNum(SCX(68), SCY(8) + SCZ(11), total_ringcount); + ST_DrawTopLeftOverlayNum(68, 8 + 11, total_ringcount); #ifdef HAVE_BLUA } #endif @@ -1519,9 +1476,7 @@ static void ST_drawNiGHTSHUD(void) && LUA_HudEnabled(hud_nightsscore) #endif ) - { - ST_DrawNightsOverlayNum(304<marescore, nightsnum, SKINCOLOR_AZURE); - } + ST_DrawNightsOverlayNum(304<marescore, nightsnum, SKINCOLOR_AZURE); if (!stplyr->exiting #ifdef HAVE_BLUA @@ -1536,16 +1491,16 @@ static void ST_drawNiGHTSHUD(void) fixed_t cornerx = vid.width, cornery = vid.height-SCZ(20); #define ASSISHHUDFIX(n) (n*vid.dupx) - ST_DrawOverlayPatch(cornerx-ASSISHHUDFIX(22), cornery, W_CachePatchName("NGRTIMER", PU_HUDGFX)); - ST_DrawPaddedOverlayNum(cornerx-ASSISHHUDFIX(22), cornery, G_TicsToCentiseconds(maretime), 2); - ST_DrawOverlayPatch(cornerx-ASSISHHUDFIX(46), cornery, sboperiod); + ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(22), cornery, W_CachePatchName("NGRTIMER", PU_HUDGFX)); + ST_DrawUnscaledPaddedOverlayNum(cornerx-ASSISHHUDFIX(22), cornery, G_TicsToCentiseconds(maretime), 2); + ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(46), cornery, sboperiod); if (maretime < 60*TICRATE) - ST_DrawOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime)); + ST_DrawUnscaledOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime)); else { - ST_DrawPaddedOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime), 2); - ST_DrawOverlayPatch(cornerx-ASSISHHUDFIX(70), cornery, sbocolon); - ST_DrawOverlayNum(cornerx-ASSISHHUDFIX(70), cornery, G_TicsToMinutes(maretime, true)); + ST_DrawUnscaledPaddedOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime), 2); + ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(70), cornery, sbocolon); + ST_DrawUnscaledOverlayNum(cornerx-ASSISHHUDFIX(70), cornery, G_TicsToMinutes(maretime, true)); } } #undef ASSISHHUDFIX @@ -1577,10 +1532,10 @@ static void ST_drawNiGHTSHUD(void) if (flashingLeft < TICRATE/2) // Start fading out { UINT32 fadingFlag = (9 - 9*flashingLeft/(TICRATE/2)) << V_ALPHASHIFT; - V_DrawTranslucentPatch(SCX(160 - (minus5sec->width/2)), SCY(28), V_NOSCALESTART|fadingFlag, minus5sec); + V_DrawTranslucentPatch(SCX(160 - (minus5sec->width/2)), SCZ(28), V_NOSCALESTART|V_PERPLAYER|fadingFlag, minus5sec); } else - V_DrawScaledPatch(SCX(160 - (minus5sec->width/2)), SCY(28), V_NOSCALESTART, minus5sec); + V_DrawScaledPatch(SCX(160 - (minus5sec->width/2)), SCZ(28), V_NOSCALESTART|V_PERPLAYER, minus5sec); } if (realnightstime < 10) @@ -1590,7 +1545,7 @@ static void ST_drawNiGHTSHUD(void) else numbersize = 48/2; - ST_DrawNightsOverlayNum((160 + numbersize)<powers[pw_nights_superloop]) { pwr = stplyr->powers[pw_nights_superloop]; - V_DrawSmallScaledPatch(SCX(110), SCY(44), V_NOSCALESTART, W_CachePatchName("NPRUA0",PU_CACHE)); - V_DrawThinString(SCX(106), SCY(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(SCX(110), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUA0",PU_CACHE)); + V_DrawThinString(SCX(106), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } if (stplyr->powers[pw_nights_helper]) { pwr = stplyr->powers[pw_nights_helper]; - V_DrawSmallScaledPatch(SCX(150), SCY(44), V_NOSCALESTART, W_CachePatchName("NPRUC0",PU_CACHE)); - V_DrawThinString(SCX(146), SCY(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(SCX(150), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUC0",PU_CACHE)); + V_DrawThinString(SCX(146), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } if (stplyr->powers[pw_nights_linkfreeze]) { pwr = stplyr->powers[pw_nights_linkfreeze]; - V_DrawSmallScaledPatch(SCX(190), SCY(44), V_NOSCALESTART, W_CachePatchName("NPRUE0",PU_CACHE)); - V_DrawThinString(SCX(186), SCY(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(SCX(190), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUE0",PU_CACHE)); + V_DrawThinString(SCX(186), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } } @@ -1653,23 +1608,23 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I patflags = V_80TRANS; } - V_DrawScaledPatch(8 + xoffs, y, V_SNAPTOLEFT|patflags, pat); + V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|patflags, pat); if (stplyr->powers[weapon] > 99) - V_DrawThinString(8 + xoffs + 1, y, V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); + V_DrawThinString(8 + xoffs + 1, y, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); else - V_DrawString(8 + xoffs, y, V_SNAPTOLEFT|txtflags, va("%d", stplyr->powers[weapon])); + V_DrawString(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); if (stplyr->currentweapon == wepflag) - V_DrawScaledPatch(6 + xoffs, y-2, V_SNAPTOLEFT, curweapon); + V_DrawScaledPatch(6 + xoffs, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); } else if (stplyr->ringweapons & rwflag) - V_DrawScaledPatch(8 + xoffs, y, V_SNAPTOLEFT|V_TRANSLUCENT, pat); + V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_TRANSLUCENT, pat); } static void ST_drawMatchHUD(void) { - const INT32 y = STRINGY(176+16)-16; // HUD_LIVESPIC + const INT32 y = 176; // HUD_LIVES INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10) - 6; if (!G_RingSlingerGametype()) @@ -1678,74 +1633,30 @@ static void ST_drawMatchHUD(void) if (G_TagGametype() && !(stplyr->pflags & PF_TAGIT)) return; -#ifdef HAVE_BLUA - if (LUA_HudEnabled(hud_weaponrings)) { -#endif + { + if (stplyr->powers[pw_infinityring]) + ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring); + else if (stplyr->rings > 0) + V_DrawScaledPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM, normring); + else + V_DrawTranslucentPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_80TRANS, normring); - if (stplyr->powers[pw_infinityring]) - ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring); - else if (stplyr->rings > 0) - V_DrawScaledPatch(8 + offset, y, V_SNAPTOLEFT, normring); - else - V_DrawTranslucentPatch(8 + offset, y, V_SNAPTOLEFT|V_80TRANS, normring); + if (!stplyr->currentweapon) + V_DrawScaledPatch(6 + offset, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); - if (!stplyr->currentweapon) - V_DrawScaledPatch(6 + offset, y-2, V_SNAPTOLEFT, curweapon); - - offset += 20; - ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring); - offset += 20; - ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, y, bouncering); - offset += 20; - ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, y, scatterring); - offset += 20; - ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, y, grenadering); - offset += 20; - ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, y, explosionring); - offset += 20; - ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, y, railring); - -#ifdef HAVE_BLUA + offset += 20; + ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring); + offset += 20; + ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, y, bouncering); + offset += 20; + ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, y, scatterring); + offset += 20; + ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, y, grenadering); + offset += 20; + ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, y, explosionring); + offset += 20; + ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, y, railring); } - - if (LUA_HudEnabled(hud_powerstones)) { -#endif - - // Power Stones collected - offset = STRINGY(128); // Used for Y now - - if (stplyr->powers[pw_emeralds] & EMERALD1) - V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][0]); - - offset += 8; - - if (stplyr->powers[pw_emeralds] & EMERALD2) - V_DrawScaledPatch(40, offset, V_SNAPTOLEFT, emeraldpics[1][1]); - - if (stplyr->powers[pw_emeralds] & EMERALD6) - V_DrawScaledPatch(16, offset, V_SNAPTOLEFT, emeraldpics[1][5]); - - offset += 16; - - if (stplyr->powers[pw_emeralds] & EMERALD3) - V_DrawScaledPatch(40, offset, V_SNAPTOLEFT, emeraldpics[1][2]); - - if (stplyr->powers[pw_emeralds] & EMERALD5) - V_DrawScaledPatch(16, offset, V_SNAPTOLEFT, emeraldpics[1][4]); - - offset += 8; - - if (stplyr->powers[pw_emeralds] & EMERALD4) - V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][3]); - - offset -= 16; - - if (stplyr->powers[pw_emeralds] & EMERALD7) - V_DrawScaledPatch(28, offset, V_SNAPTOLEFT, emeraldpics[1][6]); - -#ifdef HAVE_BLUA - } -#endif } static inline void ST_drawRaceHUD(void) @@ -1776,15 +1687,15 @@ static inline void ST_drawRaceHUD(void) if (!bounce) S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); } - V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racenum->width))/2), (INT32)(SCY(height)), V_NOSCALESTART, racenum); + V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racenum->width))/2), (INT32)(SCZ(height)), V_NOSCALESTART|V_PERPLAYER, racenum); } if (circuitmap) { if (stplyr->exiting) - V_DrawString(hudinfo[HUD_LAP].x, STRINGY(hudinfo[HUD_LAP].y), V_YELLOWMAP, "FINISHED!"); + V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, V_YELLOWMAP, "FINISHED!"); else - V_DrawString(hudinfo[HUD_LAP].x, STRINGY(hudinfo[HUD_LAP].y), 0, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); + V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, 0, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); } } @@ -1832,36 +1743,27 @@ static void ST_drawTagHUD(void) // Print the stuff. if (pstext[0]) - { - if (splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(168), 0, pstext); - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), 0, pstext); - } + V_DrawCenteredString(BASEVIDWIDTH/2, 168, V_PERPLAYER|V_SNAPTOBOTTOM, pstext); + if (pstime[0]) - { - if (splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), 0, pstime); - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(192), 0, pstime); - } + V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_PERPLAYER|V_SNAPTOBOTTOM, pstime); } static void ST_drawCTFHUD(void) { - INT32 i; + INT32 i, y = 176; UINT16 whichflag = 0; // Draw the flags - V_DrawSmallScaledPatch(256, (splitscreen) ? STRINGY(160) : STRINGY(176), V_HUDTRANS, rflagico); - V_DrawSmallScaledPatch(288, (splitscreen) ? STRINGY(160) : STRINGY(176), V_HUDTRANS, bflagico); + V_DrawSmallScaledPatch(256, y, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, rflagico); + V_DrawSmallScaledPatch(280, y, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, bflagico); for (i = 0; i < MAXPLAYERS; i++) { if (players[i].gotflag & GF_REDFLAG) // Red flag isn't at base - V_DrawScaledPatch(256, (splitscreen) ? STRINGY(156) : STRINGY(174), V_HUDTRANS, nonicon); + V_DrawScaledPatch(256, y-4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, nonicon); else if (players[i].gotflag & GF_BLUEFLAG) // Blue flag isn't at base - V_DrawScaledPatch(288, (splitscreen) ? STRINGY(156) : STRINGY(174), V_HUDTRANS, nonicon); + V_DrawScaledPatch(280, y-4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, nonicon); whichflag |= players[i].gotflag; if ((whichflag & (GF_REDFLAG|GF_BLUEFLAG)) == (GF_REDFLAG|GF_BLUEFLAG)) @@ -1872,11 +1774,7 @@ static void ST_drawCTFHUD(void) if (stplyr->gotflag) { patch_t *p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; - - if (splitscreen) - V_DrawSmallScaledPatch(312, STRINGY(24) + 42, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - else - V_DrawScaledPatch(304, 24 + 84, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); + V_DrawScaledPatch(304, 24 + 84, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); } // Display a countdown timer showing how much time left until the flag your team dropped returns to base. @@ -1885,13 +1783,13 @@ static void ST_drawCTFHUD(void) if (redflag && redflag->fuse > 1) { sprintf(timeleft, "%u", (redflag->fuse / TICRATE)); - V_DrawCenteredString(268, STRINGY(184), V_YELLOWMAP|V_HUDTRANS, timeleft); + V_DrawCenteredString(268, y+8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, timeleft); } if (blueflag && blueflag->fuse > 1) { sprintf(timeleft, "%u", (blueflag->fuse / TICRATE)); - V_DrawCenteredString(300, STRINGY(184), V_YELLOWMAP|V_HUDTRANS, timeleft); + V_DrawCenteredString(300, y+8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, timeleft); } } } @@ -1909,7 +1807,7 @@ static void ST_drawSpecialStageHUD(void) if (sstimer) { - V_DrawString(hudinfo[HUD_TIMELEFT].x, STRINGY(hudinfo[HUD_TIMELEFT].y), V_HUDTRANS, M_GetText("TIME LEFT")); + V_DrawString(hudinfo[HUD_TIMELEFT].x, hudinfo[HUD_TIMELEFT].y, V_PERPLAYER|V_HUDTRANS, M_GetText("TIME LEFT")); ST_DrawNumFromHud(HUD_TIMELEFTNUM, sstimer/TICRATE, V_HUDTRANS); } else @@ -1952,7 +1850,7 @@ static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offse interval = 0; } - V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, STRINGY(hudinfo[HUD_HUNTPICS].y), V_HUDTRANS, patches[i]); + V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, V_PERPLAYER|V_HUDTRANS, patches[i]); return interval; } @@ -2067,13 +1965,12 @@ static void ST_overlayDrawer(void) #endif ST_drawRings(); - ST_drawLivesPic(); // always do on mystic's request - allows us to kill "RED/BLUE TEAM" text - if (G_GametypeUsesLives() + if (!modeattacking #ifdef HAVE_BLUA && LUA_HudEnabled(hud_lives) #endif ) - ST_drawLives(); + ST_drawLivesArea(); } } @@ -2113,7 +2010,7 @@ static void ST_overlayDrawer(void) } if (p) - V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, STRINGY(BASEVIDHEIGHT/2 - (SHORT(p->height)/2)) - (splitscreen ? 4 : 0), (stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p); + V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, BASEVIDHEIGHT/2 - (SHORT(p->height)/2), V_PERPLAYER|(stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p); } @@ -2121,22 +2018,21 @@ static void ST_overlayDrawer(void) { // Countdown timer for Race Mode if (countdown) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(176), 0, va("%d", countdown/TICRATE)); + V_DrawCenteredString(BASEVIDWIDTH/2, 176, V_PERPLAYER, va("%d", countdown/TICRATE)); // If you are in overtime, put a big honkin' flashin' message on the screen. if (G_RingSlingerGametype() && cv_overtime.value - && (leveltime > (timelimitintics + TICRATE/2)) && cv_timelimit.value && (leveltime/TICRATE % 2 == 0)) - { - if (splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(168), 0, M_GetText("OVERTIME!")); - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(184), 0, M_GetText("OVERTIME!")); - } + && (leveltime > (timelimitintics + TICRATE/2)) && cv_timelimit.value && (leveltime/TICRATE % 2 == 0)) + V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_PERPLAYER, M_GetText("OVERTIME!")); // Draw Match-related stuff //\note Match HUD is drawn no matter what gametype. // ... just not if you're a spectator. - if (!stplyr->spectator) + if (!stplyr->spectator +#ifdef HAVE_BLUA + && (LUA_HudEnabled(hud_weaponrings)) +#endif + ) ST_drawMatchHUD(); // Race HUD Stuff @@ -2160,7 +2056,7 @@ static void ST_overlayDrawer(void) ST_doHuntIconsAndSound(); if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) - V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, STRINGY(hudinfo[HUD_GRAVBOOTSICO].y), V_SNAPTORIGHT, gravboots); + V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, hudinfo[HUD_GRAVBOOTSICO].y, V_PERPLAYER|V_SNAPTORIGHT, gravboots); if(!P_IsLocalPlayer(stplyr)) { @@ -2219,12 +2115,10 @@ static void ST_overlayDrawer(void) total /= 4; } - if (exiting >= total) - ; - else + if (exiting < total) { total -= exiting; - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(124), 0, va(M_GetText("%d more player%s required to exit."), total, ((total == 1) ? "" : "s"))); + V_DrawCenteredString(BASEVIDWIDTH/2, 124, V_PERPLAYER, va(M_GetText("%d more player%s required to exit."), total, ((total == 1) ? "" : "s"))); if (!splitscreen) V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); } @@ -2234,7 +2128,7 @@ static void ST_overlayDrawer(void) else if (gametype == GT_HIDEANDSEEK && (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 116, V_PERPLAYER, M_GetText("You cannot move while hiding.")); if (!splitscreen) V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); } @@ -2242,9 +2136,9 @@ static void ST_overlayDrawer(void) { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; if (respawntime > 0 && !stplyr->spectator) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s")); else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); } else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE) #ifdef HAVE_BLUA @@ -2252,14 +2146,14 @@ static void ST_overlayDrawer(void) #endif ) { - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(60), V_HUDTRANSHALF, M_GetText("You are a spectator.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 60, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You are a spectator.")); if (G_GametypeHasTeams()) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); else if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); else if (gametype == GT_COOP && stplyr->lives <= 0) { - if (cv_cooplives.value == 1 + if (cv_cooplives.value == 2 && (netgame || multiplayer)) { INT32 i; @@ -2276,18 +2170,14 @@ static void ST_overlayDrawer(void) } if (i != MAXPLAYERS) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132)-(splitscreen ? 12 : 0), V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); } } else if (gametype != GT_COOP) - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); if (!splitscreen) - { - V_DrawCenteredString(BASEVIDWIDTH/2, 148, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); - } - else - V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(136), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 148, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); } } diff --git a/src/st_stuff.h b/src/st_stuff.h index 9be37b502..2294c35e4 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -77,33 +77,23 @@ typedef struct typedef enum { - HUD_LIVESNAME, - HUD_LIVESPIC, - HUD_LIVESNUM, - HUD_LIVESX, + HUD_LIVES, HUD_RINGS, - HUD_RINGSSPLIT, HUD_RINGSNUM, - HUD_RINGSNUMSPLIT, HUD_RINGSNUMTICS, HUD_SCORE, HUD_SCORENUM, HUD_TIME, - HUD_TIMESPLIT, HUD_MINUTES, - HUD_MINUTESSPLIT, HUD_TIMECOLON, - HUD_TIMECOLONSPLIT, HUD_SECONDS, - HUD_SECONDSSPLIT, HUD_TIMETICCOLON, HUD_TICS, HUD_SS_TOTALRINGS, - HUD_SS_TOTALRINGS_SPLIT, HUD_GETRINGS, HUD_GETRINGSNUM, diff --git a/src/v_video.c b/src/v_video.c index 20fe9229e..c9ab2933d 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -15,6 +15,8 @@ #include "doomdef.h" #include "r_local.h" +#include "p_local.h" // stplyr +#include "g_game.h" // players #include "v_video.h" #include "hu_stuff.h" #include "r_draw.h" @@ -624,8 +626,50 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t x -= FixedMul(SHORT(patch->leftoffset)<>=1; + if (splitscreen && (scrn & V_PERPLAYER)) + { + fixed_t adjusty = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1); + fdup >>= 1; + rowfrac <<= 1; + y >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + fixed_t adjustx = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1)); + colfrac <<= 1; + x >>= 1; + if (stplyr == &players[displayplayer]) + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + else if (stplyr == &players[secondarydisplayplayer]) + { + x += adjustx; + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + y += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + x += adjustx; + y += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + scrn &= ~V_SNAPTOBOTTOM; + else //if (stplyr == &players[secondarydisplayplayer]) + { + y += adjusty; + scrn &= ~V_SNAPTOTOP; + } + } + } desttop = screens[scrn&V_PARAMMASK]; @@ -670,9 +714,9 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t if (vid.height != BASEVIDHEIGHT * dupy) { // same thing here - if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) + /*if ((scrn & (V_PERPLAYER|V_SNAPTOBOTTOM)) == (V_PERPLAYER|V_SNAPTOBOTTOM)) y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); - else if (scrn & V_SNAPTOBOTTOM) + else */if (scrn & V_SNAPTOBOTTOM) y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; @@ -835,7 +879,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ if (vid.height != BASEVIDHEIGHT * dupy) { // same thing here - if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) + if ((scrn & (V_PERPLAYER|V_SNAPTOBOTTOM)) == (V_PERPLAYER|V_SNAPTOBOTTOM)) y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); else if (scrn & V_SNAPTOBOTTOM) y += (vid.height - (BASEVIDHEIGHT * dupy)); diff --git a/src/v_video.h b/src/v_video.h index f9fd475f4..66fd2f430 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -113,7 +113,7 @@ extern RGBA_t *pMasterPalette; #define V_WRAPY 0x20000000 // Don't clamp texture on Y (for HW mode) #define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords -#define V_SPLITSCREEN 0x80000000 +#define V_PERPLAYER 0x80000000 // defines for old functions #define V_DrawPatch(x,y,s,p) V_DrawFixedPatch((x)< Date: Sun, 21 Jan 2018 12:56:38 +0000 Subject: [PATCH 09/66] * Update V_DrawCroppedPatch and V_DrawFill to support V_PERPLAYER. * Fix some mistakes in the comments for v_video.h. --- src/hardware/hw_draw.c | 81 ++++++++++++++++++++++++------- src/v_video.c | 106 ++++++++++++++++++++++++++++++++++++++--- src/v_video.h | 4 +- 3 files changed, 166 insertions(+), 25 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index f902b4802..0a09a2b41 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -194,36 +194,22 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; pdupx /= 2; cx /= 2; - if (stplyr == &players[displayplayer]) - option &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; - else if (stplyr == &players[secondarydisplayplayer]) - { + if (stplyr == &players[secondarydisplayplayer]) cx += adjustx; - option &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; - } else if (stplyr == &players[thirddisplayplayer]) - { cy += adjusty; - option &= ~V_SNAPTOTOP|V_SNAPTORIGHT; - } - else //if (stplyr == &players[fourthdisplayplayer]) + else if (stplyr == &players[fourthdisplayplayer]) { cx += adjustx; cy += adjusty; - option &= ~V_SNAPTOTOP|V_SNAPTOLEFT; } } else #endif // 2 players { - if (stplyr == &players[displayplayer]) - option &= ~V_SNAPTOBOTTOM; - else //if (stplyr == &players[secondarydisplayplayer]) - { + if (stplyr == &players[secondarydisplayplayer]) cy += adjusty; - option &= ~V_SNAPTOTOP; - } } } @@ -323,6 +309,37 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal if (option & V_NOSCALESTART) sdupx = sdupy = 2.0f; + if (splitscreen && (option & V_PERPLAYER)) + { + float adjusty = ((option & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; + pdupy /= 2; + cy /= 2; + // unlike software no need to adjust texture sourcing +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; + pdupx /= 2; + cx /= 2; + if (stplyr == &players[secondarydisplayplayer]) + cx += adjustx; + else if (stplyr == &players[thirddisplayplayer]) + cy += adjusty; + if (stplyr == &players[fourthdisplayplayer]) + { + cx += adjustx; + cy += adjusty; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[secondarydisplayplayer]) + cy += adjusty; + } + } + v[0].x = v[3].x = (cx*sdupx - gpatch->leftoffset * pdupx) / vid.width - 1; v[2].x = v[1].x = (cx*sdupx + ((w) - gpatch->leftoffset) * pdupx) / vid.width - 1; v[0].y = v[1].y = 1 - (cy*sdupy - gpatch->topoffset * pdupy) / vid.height; @@ -718,6 +735,36 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) if (color & V_NOSCALESTART) sdupx = sdupy = 2.0f; + if (splitscreen && (color & V_PERPLAYER)) + { + float adjusty = ((color & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; + w >>= 1; + y >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + float adjustx = ((color & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; + w >>= 1; + x >>= 1; + if (stplyr == &players[secondarydisplayplayer]) + x += adjustx; + else if (stplyr == &players[thirddisplayplayer]) + y += adjusty; + else if (stplyr == &players[fourthdisplayplayer]) + { + x += adjustx; + y += adjusty; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[secondarydisplayplayer]) + y += adjusty; + } + } + 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; diff --git a/src/v_video.c b/src/v_video.c index c9ab2933d..10d2d9af5 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -714,9 +714,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t if (vid.height != BASEVIDHEIGHT * dupy) { // same thing here - /*if ((scrn & (V_PERPLAYER|V_SNAPTOBOTTOM)) == (V_PERPLAYER|V_SNAPTOBOTTOM)) - y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); - else */if (scrn & V_SNAPTOBOTTOM) + if (scrn & V_SNAPTOBOTTOM) y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; @@ -837,6 +835,60 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ y -= FixedMul(SHORT(patch->topoffset)<leftoffset)<>= 1; + rowfrac <<= 1; + y >>= 1; + sy >>= 1; + h >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + fixed_t adjustx = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1)); + colfrac <<= 1; + x >>= 1; + sx >>= 1; + w >>= 1; + if (stplyr == &players[displayplayer]) + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + else if (stplyr == &players[secondarydisplayplayer]) + { + x += adjustx; + sx += adjustx; + scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + y += adjusty; + sy += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + x += adjustx; + sx += adjustx; + y += adjusty; + sy += adjusty; + scrn &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + scrn &= ~V_SNAPTOBOTTOM; + else //if (stplyr == &players[secondarydisplayplayer]) + { + y += adjusty; + sy += adjusty; + scrn &= ~V_SNAPTOTOP; + } + } + } + desttop = screens[scrn&V_PARAMMASK]; if (!desttop) @@ -879,9 +931,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ if (vid.height != BASEVIDHEIGHT * dupy) { // same thing here - if ((scrn & (V_PERPLAYER|V_SNAPTOBOTTOM)) == (V_PERPLAYER|V_SNAPTOBOTTOM)) - y += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)); - else if (scrn & V_SNAPTOBOTTOM) + if (scrn & V_SNAPTOBOTTOM) y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; @@ -1042,6 +1092,50 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) } #endif + if (splitscreen && (c & V_PERPLAYER)) + { + fixed_t adjusty = ((c & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)>>1; + h >>= 1; + y >>= 1; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + fixed_t adjustx = ((c & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)>>1; + w >>= 1; + x >>= 1; + if (stplyr == &players[displayplayer]) + c &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + else if (stplyr == &players[secondarydisplayplayer]) + { + x += adjustx; + c &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + y += adjusty; + c &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else //if (stplyr == &players[fourthdisplayplayer]) + { + x += adjustx; + y += adjusty; + c &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + c &= ~V_SNAPTOBOTTOM; + else //if (stplyr == &players[secondarydisplayplayer]) + { + y += adjusty; + c &= ~V_SNAPTOTOP; + } + } + } + if (!(c & V_NOSCALESTART)) { INT32 dupx = vid.dupx, dupy = vid.dupy; diff --git a/src/v_video.h b/src/v_video.h index 66fd2f430..c5dfd35a5 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -112,8 +112,8 @@ extern RGBA_t *pMasterPalette; #define V_WRAPX 0x10000000 // Don't clamp texture on X (for HW mode) #define V_WRAPY 0x20000000 // Don't clamp texture on Y (for HW mode) -#define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords -#define V_PERPLAYER 0x80000000 +#define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords +#define V_PERPLAYER 0x80000000 // automatically adjust coordinates/scaling for splitscreen mode // defines for old functions #define V_DrawPatch(x,y,s,p) V_DrawFixedPatch((x)< Date: Mon, 22 Jan 2018 23:29:57 +0000 Subject: [PATCH 10/66] * Improve the rendering of emerald coinboxes. * Make emeralds fall onto the end tally. https://cdn.discordapp.com/attachments/400761370800422922/405122775272128512/srb20003.gif --- src/y_inter.c | 52 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index eb5e742ea..ebadfd324 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -176,14 +176,10 @@ static void Y_IntermissionTokenDrawer(void) lowy = BASEVIDHEIGHT - 32 - 8; temp = SHORT(tokenicon->height)/2; - if (!(emeralds & EMERALD1)) em = 0; - else if (!(emeralds & EMERALD2)) em = 1; - else if (!(emeralds & EMERALD3)) em = 2; - else if (!(emeralds & EMERALD4)) em = 3; - else if (!(emeralds & EMERALD5)) em = 4; - else if (!(emeralds & EMERALD6)) em = 5; - else if (!(emeralds & EMERALD7)) em = 6; - else return; + em = 0; + while (emeralds & (1 << em)) + if (++em == 7) + return; if (tallydonetic != -1) { @@ -325,7 +321,7 @@ void Y_IntermissionDrawer(void) Y_IntermissionTokenDrawer(); // draw the header - if (intertic <= TICRATE) + if (intertic <= 2*TICRATE) animatetic = 0; else if (!animatetic && data.spec.bonus.points == 0 && data.spec.passed3[0] != '\0') animatetic = intertic; @@ -378,12 +374,46 @@ void Y_IntermissionDrawer(void) //if (intertic & 1) { INT32 emeraldx = 152 - 3*28; + INT32 em = (gamemap - sstage_start); + for (i = 0; i < 7; ++i) { - if ((emeralds & (1 << i)) && ((intertic & 1) || i != (gamemap + 1 - sstage_start))) + if ((i != em) && !(intertic & 1) && (emeralds & (1 << i))) V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[0][i]); emeraldx += 28; } + + if (em < 7) + { + static UINT8 emeraldbounces = 0; + static INT32 emeraldmomy = 20; + static INT32 emeraldy = -40; + + emeraldx = 152 + (em-3)*28; + + if (intertic <= 1) + { + emeraldbounces = 0; + emeraldmomy = 20; + emeraldy = -40; + } + else + { + if (emeraldbounces < 3) + { + emeraldmomy += 1; + emeraldy += emeraldmomy; + if (emeraldy > 74) + { + S_StartSound(NULL, sfx_tink); // tink + emeraldbounces++; + emeraldmomy = -(emeraldmomy/2); + emeraldy = 74; + } + } + V_DrawScaledPatch(emeraldx, emeraldy, 0, emeraldpics[0][em]); + } + } } V_DrawScaledPatch(152, 108, 0, data.spec.bonuspatch); @@ -812,7 +842,7 @@ void Y_Ticker(void) tallydonetic = -1; } - if (intertic < TICRATE) // one second pause before tally begins + if (intertic < 2*TICRATE) // one second pause before tally begins return; for (i = 0; i < MAXPLAYERS; i++) From ab0296d1c1f3380a4e5d554170826a4f23dd0ce1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 23 Jan 2018 23:13:56 +0000 Subject: [PATCH 11/66] Added a failure animation if you don't get the emerald. https://cdn.discordapp.com/attachments/402861856219463681/405477752972509185/srb20004.gif --- src/y_inter.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index ebadfd324..063268626 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -399,13 +399,29 @@ void Y_IntermissionDrawer(void) } else { - if (emeraldbounces < 3) + if (emeralds & (1 << em)) + { + if (emeraldbounces < 3) + { + emeraldmomy += 1; + emeraldy += emeraldmomy; + if (emeraldy > 74) + { + S_StartSound(NULL, sfx_tink); // tink + emeraldbounces++; + emeraldmomy = -(emeraldmomy/2); + emeraldy = 74; + } + } + } + else { emeraldmomy += 1; emeraldy += emeraldmomy; - if (emeraldy > 74) + emeraldx += intertic - 6; + if (emeraldbounces < 1 && emeraldy > 74) { - S_StartSound(NULL, sfx_tink); // tink + S_StartSound(NULL, sfx_shldls); // nope emeraldbounces++; emeraldmomy = -(emeraldmomy/2); emeraldy = 74; From eba0978a0015527c6536596420253a7452cbabdb Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 24 Jan 2018 02:07:30 +0000 Subject: [PATCH 12/66] RIP smiles --- 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 52cf179e7..8a8e23654 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6165,7 +6165,7 @@ static void M_DrawLoadGameData(void) { V_DrawSmallScaledPatch(x+2, y+64, 0, savselp[5]); } -#ifndef PERFECTSAVE // disabled, don't touch +#ifdef PERFECTSAVE // disabled on request else if ((savegameinfo[savetodraw].skinnum == 1) && (savegameinfo[savetodraw].lives == 99) && (savegameinfo[savetodraw].gamemap & 8192) From bf88407d00858d2523e41dda5d24cc8485a659b8 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 9 Feb 2018 17:23:35 +0000 Subject: [PATCH 13/66] Make sure both software and OpenGL ignore patches that are completely out of a multi-patch texture's bounds. This fixes OpenGL in particular crashing because of such a weird situation. --- src/hardware/hw_cache.c | 16 ++++++++++++++-- src/r_data.c | 11 +++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 78fc31afc..919bbb31c 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -62,19 +62,31 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, UINT8 texel; UINT16 texelu16; + if (!ptexturewidth) + return; + x1 = originx; x2 = x1 + SHORT(realpatch->width); + if (x1 > ptexturewidth || x2 < 0) + return; // patch not located within texture's x bounds, ignore + + if (originy > ptextureheight || (originy + SHORT(realpatch->height)) < 0) + return; // patch not located within texture's y bounds, ignore + + // patch is actually inside the texture! + // now check if texture is partly off-screen and adjust accordingly + + // left edge if (x1 < 0) x = 0; else x = x1; + // right edge if (x2 > ptexturewidth) x2 = ptexturewidth; - if (!ptexturewidth) - return; col = x * pblockwidth / ptexturewidth; ncols = ((x2 - x) * pblockwidth) / ptexturewidth; diff --git a/src/r_data.c b/src/r_data.c index c4209fad6..169b04201 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -439,11 +439,22 @@ static UINT8 *R_GenerateTexture(size_t texnum) height = SHORT(realpatch->height); x2 = x1 + width; + if (x1 > texture->width || x2 < 0) + continue; // patch not located within texture's x bounds, ignore + + if (patch->originy > texture->height || (patch->originy + height) < 0) + continue; // patch not located within texture's y bounds, ignore + + // patch is actually inside the texture! + // now check if texture is partly off-screen and adjust accordingly + + // left edge if (x1 < 0) x = 0; else x = x1; + // right edge if (x2 > texture->width) x2 = texture->width; From c1b48ea79fb53cac98b1a5d30dcbfc65973c9ce7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 12 Feb 2018 17:47:31 +0000 Subject: [PATCH 14/66] * Total overhaul of V_DrawFadeScreen(color, strength! - controllable strengths between 0-31 for COLORMAP lump like before - arbitrary colour indices in the palette via TRANSMAP lumps, with strengths 0-9 - exposed to Lua as v.fadeScreen(color, strength)! * Remove last vestiges of V_STATICPATCH. --- src/d_clisrv.c | 2 +- src/hardware/hw_draw.c | 28 ++++++++++++++-------------- src/hardware/hw_main.h | 2 +- src/lua_hudlib.c | 18 ++++++++++++++++++ src/m_menu.c | 2 +- src/v_video.c | 36 +++++++++++++++++++++++++++--------- src/v_video.h | 2 +- 7 files changed, 63 insertions(+), 27 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 72f60aa9f..6a871057e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1125,7 +1125,7 @@ static inline void CL_DrawConnectionStatus(void) INT32 ccstime = I_GetTime(); // Draw background fade - V_DrawFadeScreen(); + V_DrawFadeScreen(0xFF00, 16); // Draw the bottom box. M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 0a09a2b41..0e10c6473 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -154,9 +154,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, 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); - if (alphalevel == 12) - alphalevel = 0; - else if (alphalevel >= 10 && alphalevel < 13) + if (alphalevel >= 10 && alphalevel < 13) return; // make patch ready in hardware cache @@ -283,9 +281,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal 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); - if (alphalevel == 12) - alphalevel = 0; - else if (alphalevel >= 10 && alphalevel < 13) + if (alphalevel >= 10 && alphalevel < 13) return; // make patch ready in hardware cache @@ -494,18 +490,14 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum // | /| // |/ | // 0--1 -void HWR_FadeScreenMenuBack(UINT32 color, INT32 height) +void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) { FOutVector v[4]; FSurfaceInfo Surf; - // setup some neat-o translucency effect - if (!height) //cool hack 0 height is full height - height = vid.height; - v[0].x = v[3].x = -1.0f; v[2].x = v[1].x = 1.0f; - v[0].y = v[1].y = 1.0f-((height<<1)/(float)vid.height); + v[0].y = v[1].y = -1.0f; v[2].y = v[3].y = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; @@ -514,8 +506,16 @@ void HWR_FadeScreenMenuBack(UINT32 color, INT32 height) v[0].tow = v[1].tow = 1.0f; v[2].tow = v[3].tow = 0.0f; - Surf.FlatColor.rgba = UINT2RGBA(color); - Surf.FlatColor.s.alpha = (UINT8)((0xff/2) * ((float)height / vid.height)); //calum: varies console alpha + if (color & 0xFF00) // Do COLORMAP fade. + { + Surf.FlatColor.rgba = UINT2RGBA(0x01010160); + Surf.FlatColor.s.alpha = 0xFF - (strength*8); + } + else // Do TRANSMAP** fade. + { + Surf.FlatColor.rgba = pLocalPalette[color].rgba; + Surf.FlatColor.s.alpha = (UINT8)((float)(10-strength)*25.5f); + } HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index cb49f817c..1ae2d8fc3 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -33,7 +33,7 @@ void HWR_Shutdown(void); void HWR_clearAutomap(void); void HWR_drawAMline(const fline_t *fl, INT32 color); -void HWR_FadeScreenMenuBack(UINT32 color, INT32 height); +void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength); void HWR_DrawConsoleBack(UINT32 color, INT32 height); void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player); void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 97835d845..c592cc2f1 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -679,6 +679,23 @@ static int libd_getColormap(lua_State *L) return 1; } +static int libd_fadeScreen(lua_State *L) +{ + UINT16 color = luaL_checkinteger(L, 1); + UINT8 strength = luaL_checkinteger(L, 2); + const UINT8 maxstrength = ((color & 0xFF00) ? 31 : 9); + + HUDONLY + if (!strength) + return 0; + + if (strength > maxstrength) + return luaL_error(L, "%s fade strength %d out of range (0 - %d)", ((color & 0xFF00) ? "COLORMAP" : "TRANSMAP"), strength, maxstrength); + + V_DrawFadeScreen(color, strength); + return 0; +} + static int libd_width(lua_State *L) { HUDONLY @@ -733,6 +750,7 @@ static luaL_Reg lib_draw[] = { {"drawString", libd_drawString}, {"stringWidth", libd_stringWidth}, {"getColormap", libd_getColormap}, + {"fadeScreen", libd_fadeScreen}, {"width", libd_width}, {"height", libd_height}, {"dupx", libd_dupx}, diff --git a/src/m_menu.c b/src/m_menu.c index 8a8e23654..9f1b7efe7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2583,7 +2583,7 @@ void M_Drawer(void) { // now that's more readable with a faded background (yeah like Quake...) if (!WipeInAction) - V_DrawFadeScreen(); + V_DrawFadeScreen(0xFF00, 16); if (currentMenu->drawroutine) currentMenu->drawroutine(); // call current menu Draw routine diff --git a/src/v_video.c b/src/v_video.c index 10d2d9af5..daf0514d5 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1321,25 +1321,43 @@ void V_DrawPatchFill(patch_t *pat) // // Fade all the screen buffer, so that the menu is more readable, // especially now that we use the small hufont in the menus... +// If color is 0x00 to 0xFF, draw transtable (strength range 0-10). +// Else, use COLORMAP lump (strength range 0-31). +// IF YOU ARE NOT CAREFUL, THIS CAN AND WILL CRASH! +// I have kept the safety checks out of this function; +// the v.fadeScreen Lua interface handles those. // -void V_DrawFadeScreen(void) +void V_DrawFadeScreen(UINT16 color, UINT8 strength) { - const UINT8 *fadetable = (UINT8 *)colormaps + 16*256; - const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - UINT8 *buf = screens[0]; + if (!strength) + return; + + if (!(color & 0xFF00) && strength == 10) + { + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, color); + return; + } #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) { - HWR_FadeScreenMenuBack(0x01010160, 0); // hack, 0 means full height + HWR_FadeScreenMenuBack(color, strength); return; } #endif - // heavily simplified -- we don't need to know x or y - // position when we're doing a full screen fade - for (; buf < deststop; ++buf) - *buf = fadetable[*buf]; + { + const UINT8 *fadetable = ((color & 0xFF00) // Color is not palette index? + ? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade. + : ((UINT8 *)transtables + ((10-strength)< Date: Mon, 12 Feb 2018 18:23:57 +0000 Subject: [PATCH 15/66] * Move the non-mapping drawFill out of the source code function and into the Lua interface. * Add a drawFill fallback for COLORMAP too. * Correct a few index mishaps. --- src/lua_hudlib.c | 9 ++++++++- src/v_video.c | 10 ++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index c592cc2f1..6991f00e7 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -683,15 +683,22 @@ static int libd_fadeScreen(lua_State *L) { UINT16 color = luaL_checkinteger(L, 1); UINT8 strength = luaL_checkinteger(L, 2); - const UINT8 maxstrength = ((color & 0xFF00) ? 31 : 9); + const UINT8 maxstrength = ((color & 0xFF00) ? 32 : 10); HUDONLY + if (!strength) return 0; if (strength > maxstrength) return luaL_error(L, "%s fade strength %d out of range (0 - %d)", ((color & 0xFF00) ? "COLORMAP" : "TRANSMAP"), strength, maxstrength); + if (strength == maxstrength) // Allow as a shortcut for drawfill... + { + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, ((color & 0xFF00) ? 31 : color)); + return 0; + } + V_DrawFadeScreen(color, strength); return 0; } diff --git a/src/v_video.c b/src/v_video.c index daf0514d5..47142484d 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1321,7 +1321,7 @@ void V_DrawPatchFill(patch_t *pat) // // Fade all the screen buffer, so that the menu is more readable, // especially now that we use the small hufont in the menus... -// If color is 0x00 to 0xFF, draw transtable (strength range 0-10). +// If color is 0x00 to 0xFF, draw transtable (strength range 0-9). // Else, use COLORMAP lump (strength range 0-31). // IF YOU ARE NOT CAREFUL, THIS CAN AND WILL CRASH! // I have kept the safety checks out of this function; @@ -1332,12 +1332,6 @@ void V_DrawFadeScreen(UINT16 color, UINT8 strength) if (!strength) return; - if (!(color & 0xFF00) && strength == 10) - { - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, color); - return; - } - #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) { @@ -1349,7 +1343,7 @@ void V_DrawFadeScreen(UINT16 color, UINT8 strength) { const UINT8 *fadetable = ((color & 0xFF00) // Color is not palette index? ? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade. - : ((UINT8 *)transtables + ((10-strength)< Date: Mon, 12 Feb 2018 21:31:03 +0000 Subject: [PATCH 16/66] Fixed the strengths going in the wrong direction of transparency in GL! --- src/hardware/hw_draw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 0e10c6473..072380e6b 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -509,12 +509,12 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) if (color & 0xFF00) // Do COLORMAP fade. { Surf.FlatColor.rgba = UINT2RGBA(0x01010160); - Surf.FlatColor.s.alpha = 0xFF - (strength*8); + Surf.FlatColor.s.alpha = (strength*8); } else // Do TRANSMAP** fade. { Surf.FlatColor.rgba = pLocalPalette[color].rgba; - Surf.FlatColor.s.alpha = (UINT8)((float)(10-strength)*25.5f); + Surf.FlatColor.s.alpha = (UINT8)(strength*25.5f); } HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } From 33d5baa2aad5eb6f27f19eb15900c3883c8cc8ba Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 2 Mar 2018 13:32:55 +0000 Subject: [PATCH 17/66] * Add new console text colours - sky, purple, aqua, peridot, azure, brown, rosy, and invert. * Remove redundant check from V_DrawFadeScreen(). * Clean up potential endless sound source in Race HUD. --- src/console.c | 82 +++++++++++++++++++++++++++----------------------- src/console.h | 2 +- src/dehacked.c | 10 +++++- src/st_stuff.c | 2 +- src/v_video.c | 35 ++++++++++++++------- src/v_video.h | 10 +++++- 6 files changed, 88 insertions(+), 53 deletions(-) diff --git a/src/console.c b/src/console.c index a504af06d..842d8766d 100644 --- a/src/console.c +++ b/src/console.c @@ -226,13 +226,9 @@ static void CONS_Bind_f(void) // Font colormap colors // TODO: This could probably be improved somehow... // These colormaps are 99% identical, with just a few changed bytes -UINT8 *yellowmap; -UINT8 *purplemap; -UINT8 *lgreenmap; -UINT8 *bluemap; -UINT8 *graymap; -UINT8 *redmap; -UINT8 *orangemap; +// This could EASILY be handled by modifying a centralised colormap +// for software depending on the prior state - but yknow, OpenGL... +UINT8 *yellowmap, *magentamap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap, *skymap, *purplemap, *aquamap, *peridotmap, *azuremap, *brownmap, *rosymap, *invertmap; // Console BG color UINT8 *consolebgmap = NULL; @@ -280,45 +276,55 @@ static void CONS_backcolor_Change(void) static void CON_SetupColormaps(void) { INT32 i; + UINT8 *memorysrc = (UINT8 *)Z_Malloc((256*15), PU_STATIC, NULL); - yellowmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - graymap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - purplemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - lgreenmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - bluemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - redmap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); - orangemap = (UINT8 *)Z_Malloc(256, PU_STATIC, NULL); + magentamap = memorysrc; + yellowmap = (magentamap+256); + lgreenmap = (yellowmap+256); + bluemap = (lgreenmap+256); + redmap = (bluemap+256); + graymap = (redmap+256); + orangemap = (graymap+256); + skymap = (orangemap+256); + purplemap = (skymap+256); + aquamap = (purplemap+256); + peridotmap = (aquamap+256); + azuremap = (peridotmap+256); + brownmap = (azuremap+256); + rosymap = (brownmap+256); + invertmap = (rosymap+256); // setup the other colormaps, for console text // these don't need to be aligned, unless you convert the // V_DrawMappedPatch() into optimised asm. - for (i = 0; i < 256; i++) - { - yellowmap[i] = (UINT8)i; // remap each color to itself... - graymap[i] = (UINT8)i; - purplemap[i] = (UINT8)i; - lgreenmap[i] = (UINT8)i; - bluemap[i] = (UINT8)i; - redmap[i] = (UINT8)i; - orangemap[i] = (UINT8)i; - } + for (i = 0; i < (256*15); i++, ++memorysrc) + *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... - yellowmap[3] = (UINT8)73; - yellowmap[9] = (UINT8)66; - purplemap[3] = (UINT8)184; - purplemap[9] = (UINT8)186; - lgreenmap[3] = (UINT8)98; - lgreenmap[9] = (UINT8)106; - bluemap[3] = (UINT8)147; - bluemap[9] = (UINT8)158; - graymap[3] = (UINT8)10; - graymap[9] = (UINT8)15; - redmap[3] = (UINT8)210; - redmap[9] = (UINT8)32; - orangemap[3] = (UINT8)52; - orangemap[9] = (UINT8)57; +#define colset(map, a, b, c) \ + map[1] = (UINT8)a;\ + map[3] = (UINT8)b;\ + map[9] = (UINT8)c + + colset(magentamap, 177, 178, 184); + colset(yellowmap, 82, 73, 66); + colset(lgreenmap, 97, 98, 106); + colset(bluemap, 146, 147, 155); + colset(redmap, 210, 32, 39); + colset(graymap, 8, 10, 15); + colset(orangemap, 51, 52, 57); + colset(skymap, 129, 130, 133); + colset(purplemap, 160, 161, 163); + colset(aquamap, 120, 121, 123); + colset(peridotmap, 88, 188, 190); + colset(azuremap, 144, 145, 170); + colset(brownmap, 219, 221, 224); + colset(rosymap, 200, 201, 203); + colset(invertmap, 27, 26, 22); + invertmap[26] = (UINT8)3; + +#undef colset // Init back colormap CON_SetupBackColormap(); diff --git a/src/console.h b/src/console.h index 1e510e89a..970f841d0 100644 --- a/src/console.h +++ b/src/console.h @@ -34,7 +34,7 @@ extern UINT32 con_scalefactor; // console text scale factor extern consvar_t cons_backcolor; -extern UINT8 *yellowmap, *purplemap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap; +extern UINT8 *yellowmap, *magentamap, *lgreenmap, *bluemap, *graymap, *redmap, *orangemap, *skymap, *purplemap, *aquamap, *peridotmap, *azuremap, *brownmap, *rosymap, *invertmap; // Console bg color (auto updated to match) extern UINT8 *consolebgmap; diff --git a/src/dehacked.c b/src/dehacked.c index bd4530e00..7202ba31b 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7311,13 +7311,21 @@ struct { {"V_6WIDTHSPACE",V_6WIDTHSPACE}, {"V_OLDSPACING",V_OLDSPACING}, {"V_MONOSPACE",V_MONOSPACE}, - {"V_PURPLEMAP",V_PURPLEMAP}, + {"V_MAGENTAMAP",V_MAGENTAMAP}, {"V_YELLOWMAP",V_YELLOWMAP}, {"V_GREENMAP",V_GREENMAP}, {"V_BLUEMAP",V_BLUEMAP}, {"V_REDMAP",V_REDMAP}, {"V_GRAYMAP",V_GRAYMAP}, {"V_ORANGEMAP",V_ORANGEMAP}, + {"V_SKYMAP",V_SKYMAP}, + {"V_PURPLEMAP",V_PURPLEMAP}, + {"V_AQUAMAP",V_AQUAMAP}, + {"V_PERIDOTMAP",V_PERIDOTMAP}, + {"V_AZUREMAP",V_AZUREMAP}, + {"V_BROWNMAP",V_BROWNMAP}, + {"V_ROSYMAP",V_ROSYMAP}, + {"V_INVERTMAP",V_INVERTMAP}, {"V_TRANSLUCENT",V_TRANSLUCENT}, {"V_10TRANS",V_10TRANS}, {"V_20TRANS",V_20TRANS}, diff --git a/src/st_stuff.c b/src/st_stuff.c index 1426ae405..6d6c2d017 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1684,7 +1684,7 @@ static inline void ST_drawRaceHUD(void) if (bounce < 3) { height -= (2 - bounce); - if (!bounce) + if (!(P_AutoPause() || paused) && !bounce) S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); } V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racenum->width))/2), (INT32)(SCZ(height)), V_NOSCALESTART|V_PERPLAYER, racenum); diff --git a/src/v_video.c b/src/v_video.c index 47142484d..d23e5f4f5 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1329,9 +1329,6 @@ void V_DrawPatchFill(patch_t *pat) // void V_DrawFadeScreen(UINT16 color, UINT8 strength) { - if (!strength) - return; - #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) { @@ -1395,20 +1392,36 @@ static const UINT8 *V_GetStringColormap(INT32 colorflags) { switch ((colorflags & V_CHARCOLORMASK) >> V_CHARCOLORSHIFT) { - case 1: // 0x81, purple - return purplemap; - case 2: // 0x82, yellow + case 1: // 0x81, magenta + return magentamap; + case 2: // 0x82, yellow return yellowmap; - case 3: // 0x83, lgreen + case 3: // 0x83, lgreen return lgreenmap; - case 4: // 0x84, blue + case 4: // 0x84, blue return bluemap; - case 5: // 0x85, red + case 5: // 0x85, red return redmap; - case 6: // 0x86, gray + case 6: // 0x86, gray return graymap; - case 7: // 0x87, orange + case 7: // 0x87, orange return orangemap; + case 8: // 0x88, sky + return skymap; + case 9: // 0x89, purple + return purplemap; + case 10: // 0x8A, aqua + return aquamap; + case 11: // 0x8B, peridot + return peridotmap; + case 12: // 0x8C, azure + return azuremap; + case 13: // 0x8D, brown + return brownmap; + case 14: // 0x8E, rosy + return rosymap; + case 15: // 0x8F, invert + return invertmap; default: // reset return NULL; } diff --git a/src/v_video.h b/src/v_video.h index ee244c671..5645ed2ce 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -73,13 +73,21 @@ extern RGBA_t *pMasterPalette; #define V_CHARCOLORSHIFT 12 #define V_CHARCOLORMASK 0x0000F000 // for simplicity's sake, shortcuts to specific colors -#define V_PURPLEMAP 0x00001000 +#define V_MAGENTAMAP 0x00001000 #define V_YELLOWMAP 0x00002000 #define V_GREENMAP 0x00003000 #define V_BLUEMAP 0x00004000 #define V_REDMAP 0x00005000 #define V_GRAYMAP 0x00006000 #define V_ORANGEMAP 0x00007000 +#define V_SKYMAP 0x00008000 +#define V_PURPLEMAP 0x00009000 +#define V_AQUAMAP 0x0000A000 +#define V_PERIDOTMAP 0x0000B000 +#define V_AZUREMAP 0x0000C000 +#define V_BROWNMAP 0x0000D000 +#define V_ROSYMAP 0x0000E000 +#define V_INVERTMAP 0x0000F000 // use bits 17-20 for alpha transparency #define V_ALPHASHIFT 16 From 67ee1637c98688f5d9cae6ad781373b27e372c48 Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 6 Mar 2018 03:48:15 +0000 Subject: [PATCH 18/66] 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 19/66] 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 20/66] 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 21/66] 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 5a4ea9fab3d447abc5374ab24a361c43e6784ddf Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 15 Mar 2018 23:58:37 +0000 Subject: [PATCH 22/66] 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 23/66] 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 24/66] 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 25/66] 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 26/66] 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 27/66] 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 28/66] 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 29/66] 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 30/66] 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 31/66] 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 32/66] 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 7d1885917ac8a06713b33f7cf68b79d630d2c2b5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 18 Mar 2018 18:26:41 +0000 Subject: [PATCH 33/66] Some minor intro tweaks. --- src/f_finale.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 05c3d5fc0..a85655e53 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -322,7 +322,7 @@ void F_StartIntro(void) "hovers around the planet.\xBF It suddenly\n" "appears from nowhere, circles around, and\n" "\xB6- just as mysteriously as it arrives -\xB6\n" - "vanishes after about two months.\xBF\n" + "vanishes after about one week.\xBF\n" "No one knows why it appears, or how.\n#"); introtext[5] = M_GetText( @@ -334,11 +334,11 @@ void F_StartIntro(void) "the screen, and just shrugged it off.\n#"); introtext[6] = M_GetText( - "It was only later\n" + "It was hours later\n" "that he had an\n" "idea. \xBF\xA7\"The Black\n" - "Rock usually has a\n" - "lot of energy\n" + "Rock has a large\n" + "amount of energy\n" "within it\xAC...\xA7\xBF\n" "If I can somehow\n" "harness this,\xB8 I\n" @@ -356,37 +356,37 @@ void F_StartIntro(void) "a reunion party...\n#"); introtext[8] = M_GetText( - "\xA5\"We're\xB6 ready\xB6 to\xB4 fire\xB6 in\xB6 15\xB6 seconds!\"\xA8\xB8\n" - "The robot said, his voice crackling a\n" - "little down the com-link. \xBF\xA7\"Good!\"\xA8\xB8\n" - "Eggman sat back in his Egg-Mobile and\n" + "\xA5\"PRE-""\xB6""PARING-""\xB6""TO-""\xB4""FIRE-\xB6IN-""\xB6""15-""\xB6""SECONDS!\"\xA8\xB8\n" + "his targeting system crackled\n" + "robotically down the com-link. \xBF\xA7\"Good!\"\xA8\xB8\n" + "Eggman sat back in his eggmobile and\n" "began to count down as he saw the\n" - "GreenFlower city on the main monitor.\n#"); + "Greenflower mountain on the monitor.\n#"); introtext[9] = M_GetText( "\xA5\"10...\xD2""9...\xD2""8...\"\xA8\xD2\n" "Meanwhile, Sonic was tearing across the\n" "zones. Everything became a blur as he\n" - "ran around loops, skimmed over water,\n" + "ran up slopes, skimmed over water,\n" "and catapulted himself off rocks with\n" "his phenomenal speed.\n#"); introtext[10] = M_GetText( "\xA5\"6...\xD2""5...\xD2""4...\"\xA8\xD2\n" "Sonic knew he was getting closer to the\n" - "City, and pushed himself harder.\xB4 Finally,\n" - "the city appeared in the horizon.\xD2\xD2\n" + "zone, and pushed himself harder.\xB4 Finally,\n" + "the mountain appeared in the horizon.\xD2\xD2\n" "\xA5\"3...\xD2""2...\xD2""1...\xD2""Zero.\"\n#"); introtext[11] = M_GetText( - "GreenFlower City was gone.\xC4\n" + "Greenflower Mountain was no more.\xC4\n" "Sonic arrived just in time to see what\n" "little of the 'ruins' were left.\n" - "Everyone and everything in the city\n" + "The natural beauty of the zone\n" "had been obliterated.\n#"); introtext[12] = M_GetText( - "\xA7\"You're not quite as dead as we thought,\n" + "\xA7\"You're not quite as gone as we thought,\n" "huh?\xBF Are you going to tell us your plan as\n" "usual or will I \xA8\xB4'have to work it out'\xA7 or\n" "something?\"\xD2\xD2\n" @@ -400,8 +400,8 @@ void F_StartIntro(void) "leaving Sonic\n" "and Tails behind.\xB6\n" "Tails looked at\n" - "the ruins of the\n" - "Greenflower City\n" + "the once-perfect\n" + "mountainside\n" "with a grim face\n" "and sighed.\xC6\n" "\xA7\"Now\xB6 what do we\n" From c0cc1471e5b0842a0138be0df7842f6a8aea620e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 19 Mar 2018 16:39:37 +0000 Subject: [PATCH 34/66] Make some tweaks to devmode offsets. --- src/st_stuff.c | 67 ++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 6d6c2d017..5601a85ee 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -470,55 +470,55 @@ static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fix static void ST_drawDebugInfo(void) { INT32 height = 192; - INT32 dist = 8; if (!(stplyr->mo && cv_debug)) return; if (cv_ticrate.value) - { height -= 12; - dist >>= 1; - } + +#define dist 4 +#define VFLAGS V_MONOSPACE|V_SNAPTOBOTTOM|V_SNAPTORIGHT if (cv_debug & DBG_BASIC) { const fixed_t d = AngleFixed(stplyr->mo->angle); - V_DrawRightAlignedString(320, height - 24, V_MONOSPACE, va("X: %6d", stplyr->mo->x>>FRACBITS)); - V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Y: %6d", stplyr->mo->y>>FRACBITS)); - V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Z: %6d", stplyr->mo->z>>FRACBITS)); - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("A: %6d", FixedInt(d))); + V_DrawRightAlignedString(320, height - 24, VFLAGS, va("X: %6d", stplyr->mo->x>>FRACBITS)); + V_DrawRightAlignedString(320, height - 16, VFLAGS, va("Y: %6d", stplyr->mo->y>>FRACBITS)); + V_DrawRightAlignedString(320, height - 8, VFLAGS, va("Z: %6d", stplyr->mo->z>>FRACBITS)); + V_DrawRightAlignedString(320, height, VFLAGS, va("A: %6d", FixedInt(d))); height -= (32+dist); } if (cv_debug & DBG_DETAILED) { - V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield])); - V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT)); - V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("CARRY: %5x", stplyr->powers[pw_carry])); - V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); + V_DrawRightAlignedString(320, height - 104, VFLAGS, va("SHIELD: %5x", stplyr->powers[pw_shield])); + V_DrawRightAlignedString(320, height - 96, VFLAGS, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT)); + V_DrawRightAlignedString(320, height - 88, VFLAGS, va("CARRY: %5x", stplyr->powers[pw_carry])); + V_DrawRightAlignedString(320, height - 80, VFLAGS, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); // Flags - V_DrawRightAlignedString(304-92, height - 72, V_MONOSPACE, "PF:"); - V_DrawString(304-90, height - 72, (stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP, "SJ"); - V_DrawString(304-72, height - 72, (stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP, "JD"); - V_DrawString(304-54, height - 72, (stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP, "SP"); - V_DrawString(304-36, height - 72, (stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP, "ST"); - V_DrawString(304-18, height - 72, (stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP, "TH"); - V_DrawString(304, height - 72, (stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP, "SH"); + V_DrawRightAlignedString(304-92, height - 72, VFLAGS, "PF:"); + V_DrawString(304-90, height - 72, VFLAGS|((stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP), "SJ"); + V_DrawString(304-72, height - 72, VFLAGS|((stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP), "JD"); + V_DrawString(304-54, height - 72, VFLAGS|((stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP), "SP"); + V_DrawString(304-36, height - 72, VFLAGS|((stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP), "ST"); + V_DrawString(304-18, height - 72, VFLAGS|((stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP), "TH"); + V_DrawString(304, height - 72, VFLAGS|((stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP), "SH"); - V_DrawRightAlignedString(320, height - 64, V_MONOSPACE, va("CEILZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); - V_DrawRightAlignedString(320, height - 56, V_MONOSPACE, va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); + V_DrawRightAlignedString(320, height - 64, VFLAGS, va("CEILZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); + V_DrawRightAlignedString(320, height - 56, VFLAGS, va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); - V_DrawRightAlignedString(320, height - 48, V_MONOSPACE, va("CNVX: %6d", stplyr->cmomx>>FRACBITS)); - V_DrawRightAlignedString(320, height - 40, V_MONOSPACE, va("CNVY: %6d", stplyr->cmomy>>FRACBITS)); - V_DrawRightAlignedString(320, height - 32, V_MONOSPACE, va("PLTZ: %6d", stplyr->mo->pmomz>>FRACBITS)); + V_DrawRightAlignedString(320, height - 48, VFLAGS, va("CNVX: %6d", stplyr->cmomx>>FRACBITS)); + V_DrawRightAlignedString(320, height - 40, VFLAGS, va("CNVY: %6d", stplyr->cmomy>>FRACBITS)); + V_DrawRightAlignedString(320, height - 32, VFLAGS, va("PLTZ: %6d", stplyr->mo->pmomz>>FRACBITS)); - V_DrawRightAlignedString(320, height - 24, V_MONOSPACE, va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); - V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); - V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("SPEED: %6d", stplyr->speed>>FRACBITS)); + V_DrawRightAlignedString(320, height - 24, VFLAGS, va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); + V_DrawRightAlignedString(320, height - 16, VFLAGS, va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); + V_DrawRightAlignedString(320, height - 8, VFLAGS, va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); + + V_DrawRightAlignedString(320, height, VFLAGS, va("SPEED: %6d", stplyr->speed>>FRACBITS)); height -= (112+dist); } @@ -529,17 +529,20 @@ static void ST_drawDebugInfo(void) peekres *= 10000; // Change from fixed point peekres >>= FRACBITS; // to displayable decimal - V_DrawRightAlignedString(320, height - 16, V_MONOSPACE, va("Init: %08x", P_GetInitSeed())); - V_DrawRightAlignedString(320, height - 8, V_MONOSPACE, va("Seed: %08x", P_GetRandSeed())); - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("== : .%04d", peekres)); + V_DrawRightAlignedString(320, height - 16, VFLAGS, va("Init: %08x", P_GetInitSeed())); + V_DrawRightAlignedString(320, height - 8, VFLAGS, va("Seed: %08x", P_GetRandSeed())); + V_DrawRightAlignedString(320, height, VFLAGS, va("== : .%04d", peekres)); height -= (24+dist); } if (cv_debug & DBG_MEMORY) { - V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10))); + V_DrawRightAlignedString(320, height, VFLAGS, va("Heap: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10))); } + +#undef VFLAGS +#undef dist } static void ST_drawScore(void) From 4798f853826820d12fc81b4cbe9b0617898d6908 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 19 Mar 2018 16:40:15 +0000 Subject: [PATCH 35/66] Fix issues with the level platter in nonstandard resolutions. --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 9f1b7efe7..24beff317 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4425,14 +4425,14 @@ static void M_DrawLevelPlatterMenu(void) V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); // finds row at top of the screen - while (y > 0) + while (y > -8) { iter = ((iter == 0) ? levelselect.numrows-1 : iter-1); y -= lsvseperation(iter); } // draw from top to bottom - while (y < 200) + while (y < (vid.height/vid.dupy)) { M_DrawLevelPlatterRow(iter, y); y += lsvseperation(iter); From 7885ae57e2e33af4e62025bea18c749ca62168d1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 19 Mar 2018 23:08:51 +0000 Subject: [PATCH 36/66] * Allow for V_ flag control for hudinfo SOC/Lua stuff through hudinfo[n].f (for flags). * Fix Old Special Stage offsets. * Fix drowning number offsets. * Remove useless "WS" macros. --- src/dehacked.c | 4 + src/lua_hudlib.c | 10 ++- src/st_stuff.c | 194 ++++++++++++++++++++++++----------------------- src/st_stuff.h | 2 +- src/y_inter.c | 6 +- 5 files changed, 117 insertions(+), 99 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 7202ba31b..0804999a8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1584,6 +1584,10 @@ static void readhuditem(MYFILE *f, INT32 num) { hudinfo[num].y = i; } + else if (fastcmp(word, "F")) + { + hudinfo[num].f = i; + } else deh_warning("Level header %d: unknown word '%s'", num, word); } diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 6991f00e7..a709ba9f4 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -63,12 +63,14 @@ static const char *const hud_disable_options[] = { enum hudinfo { hudinfo_x = 0, - hudinfo_y + hudinfo_y, + hudinfo_f }; static const char *const hudinfo_opt[] = { "x", "y", + "f", NULL}; enum patch { @@ -198,6 +200,9 @@ static int hudinfo_get(lua_State *L) case hudinfo_y: lua_pushinteger(L, info->y); break; + case hudinfo_f: + lua_pushinteger(L, info->f); + break; } return 1; } @@ -216,6 +221,9 @@ static int hudinfo_set(lua_State *L) case hudinfo_y: info->y = (INT32)luaL_checkinteger(L, 3); break; + case hudinfo_f: + info->f = (INT32)luaL_checkinteger(L, 3); + break; } return 0; } diff --git a/src/st_stuff.c b/src/st_stuff.c index 5601a85ee..4f7c8fc28 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -125,32 +125,34 @@ static boolean facefreed[MAXPLAYERS]; hudinfo_t hudinfo[NUMHUDITEMS] = { - { 16, 176}, // HUD_LIVES + { 16, 176, V_SNAPTOLEFT|V_SNAPTOBOTTOM}, // HUD_LIVES - { 16, 42}, // HUD_RINGS - { 96, 42}, // HUD_RINGSNUM - { 120, 42}, // HUD_RINGSNUMTICS + { 16, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGS + { 96, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGSNUM + { 120, 42, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_RINGSNUMTICS - { 16, 10}, // HUD_SCORE - { 120, 10}, // HUD_SCORENUM + { 16, 10, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SCORE + { 120, 10, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SCORENUM - { 16, 26}, // HUD_TIME - { 72, 26}, // HUD_MINUTES - { 72, 26}, // HUD_TIMECOLON - { 96, 26}, // HUD_SECONDS - { 96, 26}, // HUD_TIMETICCOLON - { 120, 26}, // HUD_TICS + { 16, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIME + { 72, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_MINUTES + { 72, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIMECOLON + { 96, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SECONDS + { 96, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TIMETICCOLON + { 120, 26, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_TICS - { 120, 56}, // HUD_SS_TOTALRINGS + { 0, 56, V_SNAPTOLEFT|V_SNAPTOTOP}, // HUD_SS_TOTALRINGS - { 110, 93}, // HUD_GETRINGS - { 160, 93}, // HUD_GETRINGSNUM - { 124, 160}, // HUD_TIMELEFT - { 168, 176}, // HUD_TIMELEFTNUM - { 130, 93}, // HUD_TIMEUP - { 152, 168}, // HUD_HUNTPICS - { 152, 24}, // HUD_GRAVBOOTSICO - { 240, 160}, // HUD_LAP + { 110, 93, 0}, // HUD_GETRINGS + { 160, 93, 0}, // HUD_GETRINGSNUM + { 124, 160, 0}, // HUD_TIMELEFT + { 168, 176, 0}, // HUD_TIMELEFTNUM + { 130, 93, 0}, // HUD_TIMEUP + { 152, 168, 0}, // HUD_HUNTPICS + + { 152, 24, V_SNAPTORIGHT}, // HUD_GRAVBOOTSICO + + { 240, 160, V_SNAPTOBOTTOM|V_SNAPTORIGHT}, // HUD_LAP }; // @@ -427,12 +429,9 @@ static INT32 SCX(INT32 x) #define ST_DrawTopLeftOverlayNum(x,y,n) V_DrawTallNum(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, n) #define ST_DrawTopLeftOverlayPatch(x,y,p) V_DrawScaledPatch(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p) #define ST_DrawMappedOverlayPatch(x,y,p,c) V_DrawMappedScaledPatch(x, y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, p, c) -#define ST_DrawNumFromHud(h,n,f) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n) -#define ST_DrawPadNumFromHud(h,n,q,f) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n, q) -#define ST_DrawPatchFromHud(h,p,f) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, p) -#define ST_DrawNumFromHudWS(h,n,f) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n) -#define ST_DrawPadNumFromHudWS(h,n,q,f) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, n, q) -#define ST_DrawPatchFromHudWS(h,p,f) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|f, p) +#define ST_DrawNumFromHud(h,n,flags) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, n) +#define ST_DrawPadNumFromHud(h,n,q,flags) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, n, q) +#define ST_DrawPatchFromHud(h,p,flags) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f|V_PERPLAYER|flags, p) // Draw a number, scaled, over the view, maybe with set translucency // Always draw the number completely since it's overlay @@ -565,7 +564,7 @@ static void ST_drawTime(void) INT32 seconds, minutes, tictrn, tics; // TIME: - ST_DrawPatchFromHudWS(HUD_TIME, ((mapheaderinfo[gamemap-1]->countdown && countdowntimer < 11*TICRATE && leveltime/5 & 1) ? sboredtime : sbotime), V_HUDTRANS); + ST_DrawPatchFromHud(HUD_TIME, ((mapheaderinfo[gamemap-1]->countdown && countdowntimer < 11*TICRATE && leveltime/5 & 1) ? sboredtime : sbotime), V_HUDTRANS); if (objectplacing) { @@ -583,12 +582,12 @@ static void ST_drawTime(void) } if (cv_timetic.value == 1) // Tics only -- how simple is this? - ST_DrawNumFromHudWS(HUD_SECONDS, tics, V_HUDTRANS); + ST_DrawNumFromHud(HUD_SECONDS, tics, V_HUDTRANS); else { - ST_DrawNumFromHudWS(HUD_MINUTES, minutes, V_HUDTRANS); // Minutes - ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon - ST_DrawPadNumFromHudWS(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds + ST_DrawNumFromHud(HUD_MINUTES, minutes, V_HUDTRANS); // Minutes + ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon + ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds if (cv_timetic.value == 2 || cv_timetic.value == 3 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! { @@ -602,7 +601,7 @@ static inline void ST_drawRings(void) { INT32 ringnum; - ST_DrawPatchFromHudWS(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + ST_DrawPatchFromHud(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); if (objectplacing) ringnum = op_currentdoomednum; @@ -620,7 +619,7 @@ static inline void ST_drawRings(void) if (cv_timetic.value == 3) // Yes, even in modeattacking ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); else - ST_DrawNumFromHudWS(HUD_RINGSNUM, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); + ST_DrawNumFromHud(HUD_RINGSNUM, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); } static void ST_drawLivesArea(void) @@ -633,7 +632,7 @@ static void ST_drawLivesArea(void) // face background V_DrawSmallScaledPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, livesback); + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, livesback); // face if (stplyr->spectator) @@ -641,7 +640,7 @@ static void ST_drawLivesArea(void) // spectator face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, SKINCOLOR_CLOUDY, GTC_CACHE); V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANSHALF, faceprefix[stplyr->skin], colormap); } else if (stplyr->mo && stplyr->mo->color) { @@ -651,7 +650,7 @@ static void ST_drawLivesArea(void) if (stplyr->powers[pw_super]) face = superprefix[stplyr->skin]; V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, face, colormap); + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, face, colormap); if (cv_translucenthud.value == 10 && stplyr->powers[pw_super] == 1 && stplyr->mo->tracer) { INT32 v_supertrans = (stplyr->mo->tracer->frame & FF_TRANSMASK) >> FF_TRANSSHIFT; @@ -660,7 +659,7 @@ static void ST_drawLivesArea(void) v_supertrans <<= V_ALPHASHIFT; colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->tracer->color, GTC_CACHE); V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|v_supertrans, face, colormap); + hudinfo[HUD_LIVES].f|V_PERPLAYER|v_supertrans, face, colormap); } } } @@ -669,7 +668,7 @@ static void ST_drawLivesArea(void) // skincolor face UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE); V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, faceprefix[stplyr->skin], colormap); + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, faceprefix[stplyr->skin], colormap); } // Lives number @@ -677,7 +676,7 @@ static void ST_drawLivesArea(void) { // x V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, stlivex); + hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); // lives number if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) @@ -713,19 +712,19 @@ static void ST_drawLivesArea(void) if (livescount == 0x7f) V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8, - '\x16' | 0x80 | V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|V_HUDTRANS, false); + '\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false); else { if (livescount > 99) livescount = 99; V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, - V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); + hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); } } // Spectator else if (stplyr->spectator) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "SPECTATE"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "SPECTATE"); v_colmap = V_GRAYMAP; } // Tag @@ -733,17 +732,17 @@ static void ST_drawLivesArea(void) { if (stplyr->pflags & PF_TAGIT) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, (gametype == GT_HIDEANDSEEK) ? "SEEKER" : "IT!"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, (gametype == GT_HIDEANDSEEK) ? "SEEKER" : "IT!"); v_colmap = V_ORANGEMAP; } else if (stplyr->pflags & PF_GAMETYPEOVER) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANSHALF|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "FAILED"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANSHALF|hudinfo[HUD_LIVES].f|V_PERPLAYER, "FAILED"); v_colmap = V_GRAYMAP; } else { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, (gametype == GT_HIDEANDSEEK) ? "HIDER" : "RUNNER"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, (gametype == GT_HIDEANDSEEK) ? "HIDER" : "RUNNER"); v_colmap = V_GREENMAP; } } @@ -752,12 +751,12 @@ static void ST_drawLivesArea(void) { if (stplyr->ctfteam == 1) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "RED"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED"); v_colmap = V_REDMAP; } else if (stplyr->ctfteam == 2) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "BLUE"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE"); v_colmap = V_BLUEMAP; } else @@ -765,11 +764,11 @@ static void ST_drawLivesArea(void) } else { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, "PLAYING"); + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "PLAYING"); } // name - v_colmap |= (V_HUDTRANS|V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM); + v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); if (strlen(skins[stplyr->skin].hudname) <= 5) V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); else if (V_ThinStringWidth(skins[stplyr->skin].hudname, v_colmap) <= 40) @@ -789,7 +788,7 @@ static void ST_drawLivesArea(void) { for (j = 0; j < 7; ++j) // "super" indicator { - V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, emeraldpics[1][j]); + V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, emeraldpics[1][j]); workx += 8; } } @@ -798,7 +797,7 @@ static void ST_drawLivesArea(void) for (j = 0; j < 7; ++j) // powerstones { if (stplyr->powers[pw_emeralds] & (1 << j)) - V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|V_SNAPTOLEFT|V_PERPLAYER|V_SNAPTOBOTTOM, emeraldpics[1][j]); + V_DrawScaledPatch(workx, hudinfo[HUD_LIVES].y-9, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, emeraldpics[1][j]); workx += 8; } } @@ -817,23 +816,23 @@ static void ST_drawInput(void) y -= 16; // O backing - V_DrawFill(x, y-1, 16, 16, V_SNAPTOLEFT|V_SNAPTOBOTTOM|20); - V_DrawFill(x, y+15, 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x, y-1, 16, 16, hudinfo[HUD_LIVES].f|20); + V_DrawFill(x, y+15, 16, 1, hudinfo[HUD_LIVES].f|29); if (cv_showinputjoy.value) // joystick render! { - /*V_DrawFill(x , y , 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); - V_DrawFill(x , y+15, 16, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); - V_DrawFill(x , y+ 1, 1, 14, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); - V_DrawFill(x+15, y+ 1, 1, 14, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); -- red's outline*/ + /*V_DrawFill(x , y , 16, 1, hudinfo[HUD_LIVES].f|16); + V_DrawFill(x , y+15, 16, 1, hudinfo[HUD_LIVES].f|16); + V_DrawFill(x , y+ 1, 1, 14, hudinfo[HUD_LIVES].f|16); + V_DrawFill(x+15, y+ 1, 1, 14, hudinfo[HUD_LIVES].f|16); -- red's outline*/ if (stplyr->cmd.sidemove || stplyr->cmd.forwardmove) { // joystick hole - V_DrawFill(x+5, y+4, 6, 6, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+5, y+4, 6, 6, hudinfo[HUD_LIVES].f|29); // joystick top V_DrawFill(x+3+stplyr->cmd.sidemove/12, y+2-stplyr->cmd.forwardmove/12, - 10, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + 10, 10, hudinfo[HUD_LIVES].f|29); V_DrawFill(x+3+stplyr->cmd.sidemove/9, y+1-stplyr->cmd.forwardmove/9, 10, 10, accent); @@ -841,10 +840,10 @@ static void ST_drawInput(void) else { // just a limited, greyed out joystick top - V_DrawFill(x+3, y+11, 10, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + V_DrawFill(x+3, y+11, 10, 1, hudinfo[HUD_LIVES].f|29); V_DrawFill(x+3, y+1, - 10, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); + 10, 10, hudinfo[HUD_LIVES].f|16); } } else // arrows! @@ -858,10 +857,10 @@ static void ST_drawInput(void) else { offs = 1; - col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; - V_DrawFill(x- 2, y+10, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+ 4, y+ 9, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+ 5, y+ 8, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x- 2, y+10, 6, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 4, y+ 9, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 5, y+ 8, 1, 1, hudinfo[HUD_LIVES].f|29); } V_DrawFill(x- 2, y+ 5-offs, 6, 6, col); V_DrawFill(x+ 4, y+ 6-offs, 1, 4, col); @@ -876,12 +875,12 @@ static void ST_drawInput(void) else { offs = 1; - col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; - V_DrawFill(x+ 5, y+ 3, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+ 6, y+ 4, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+ 7, y+ 5, 2, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+ 9, y+ 4, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+10, y+ 3, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x+ 5, y+ 3, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 6, y+ 4, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 7, y+ 5, 2, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+ 9, y+ 4, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+10, y+ 3, 1, 1, hudinfo[HUD_LIVES].f|29); } V_DrawFill(x+ 5, y- 2-offs, 6, 6, col); V_DrawFill(x+ 6, y+ 4-offs, 4, 1, col); @@ -896,10 +895,10 @@ static void ST_drawInput(void) else { offs = 1; - col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; - V_DrawFill(x+12, y+10, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+11, y+ 9, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); - V_DrawFill(x+10, y+ 8, 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x+12, y+10, 6, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+11, y+ 9, 1, 1, hudinfo[HUD_LIVES].f|29); + V_DrawFill(x+10, y+ 8, 1, 1, hudinfo[HUD_LIVES].f|29); } V_DrawFill(x+12, y+ 5-offs, 6, 6, col); V_DrawFill(x+11, y+ 6-offs, 1, 4, col); @@ -914,8 +913,8 @@ static void ST_drawInput(void) else { offs = 1; - col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16; - V_DrawFill(x+ 5, y+17, 6, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29); + col = hudinfo[HUD_LIVES].f|16; + V_DrawFill(x+ 5, y+17, 6, 1, hudinfo[HUD_LIVES].f|29); } V_DrawFill(x+ 5, y+12-offs, 6, 6, col); V_DrawFill(x+ 6, y+11-offs, 4, 1, col); @@ -931,16 +930,16 @@ static void ST_drawInput(void) else\ {\ offs = 1;\ - col = V_SNAPTOLEFT|V_SNAPTOBOTTOM|16;\ - V_DrawFill(x+16+(xoffs), y+9+(yoffs), 10, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|29);\ + col = hudinfo[HUD_LIVES].f|16;\ + V_DrawFill(x+16+(xoffs), y+9+(yoffs), 10, 1, hudinfo[HUD_LIVES].f|29);\ }\ V_DrawFill(x+16+(xoffs), y+(yoffs)-offs, 10, 10, col);\ - V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, V_SNAPTOLEFT|V_SNAPTOBOTTOM|symb, false) + V_DrawCharacter(x+16+1+(xoffs), y+1+(yoffs)-offs, hudinfo[HUD_LIVES].f|symb, false) drawbutt( 4,-3, BT_JUMP, 'J'); drawbutt(15,-3, BT_USE, 'S'); - V_DrawFill(x+16+4, y+8, 21, 10, V_SNAPTOLEFT|V_SNAPTOBOTTOM|20); // sundial backing + V_DrawFill(x+16+4, y+8, 21, 10, hudinfo[HUD_LIVES].f|20); // sundial backing if (stplyr->mo) { UINT8 i, precision; @@ -960,7 +959,7 @@ static void ST_drawInput(void) { V_DrawFill(x+16+14-(i*xcomp)/precision, y+12-(i*ycomp)/precision, - 1, 1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|16); + 1, 1, hudinfo[HUD_LIVES].f|16); } if (ycomp <= 0) @@ -977,7 +976,7 @@ static void ST_drawInput(void) if (stplyr->pflags & PF_AUTOBRAKE) { V_DrawThinString(x, y, - V_SNAPTOLEFT|V_SNAPTOBOTTOM| + hudinfo[HUD_LIVES].f| ((!stplyr->powers[pw_carry] && (stplyr->pflags & PF_APPLYAUTOBRAKE) && !(stplyr->cmd.sidemove || stplyr->cmd.forwardmove) @@ -988,12 +987,12 @@ static void ST_drawInput(void) } if (stplyr->pflags & PF_ANALOGMODE) { - V_DrawThinString(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM, "ANALOG"); + V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "ANALOG"); y -= 8; } } if (!demosynced) // should always be last, so it doesn't push anything else around - V_DrawThinString(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); + V_DrawThinString(x, y, hudinfo[HUD_LIVES].f|((leveltime & 4) ? V_YELLOWMAP : V_REDMAP), "BAD DEMO!!"); } static void ST_drawLevelTitle(void) @@ -1146,8 +1145,8 @@ static void ST_drawFirstPersonHUD(void) // Display the countdown drown numbers! if (p) - V_DrawScaledPatch(SCX((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset)), SCZ(60 - SHORT(p->topoffset)), - V_PERPLAYER|V_NOSCALESTART|V_PERPLAYER|V_OFFSET|V_TRANSLUCENT, p); + V_DrawScaledPatch((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset), 60 - SHORT(p->topoffset), + V_PERPLAYER|V_PERPLAYER|V_TRANSLUCENT, p); } static void ST_drawNightsRecords(void) @@ -1696,9 +1695,9 @@ static inline void ST_drawRaceHUD(void) if (circuitmap) { if (stplyr->exiting) - V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, V_YELLOWMAP, "FINISHED!"); + V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f|V_YELLOWMAP, "FINISHED!"); else - V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, 0, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); + V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); } } @@ -1800,7 +1799,14 @@ static void ST_drawCTFHUD(void) static void ST_drawSpecialStageHUD(void) { if (totalrings > 0) - ST_DrawNumFromHudWS(HUD_SS_TOTALRINGS, totalrings, V_HUDTRANS); + { + if (hudinfo[HUD_SS_TOTALRINGS].x) + ST_DrawNumFromHud(HUD_SS_TOTALRINGS, totalrings, V_HUDTRANS); + else if (cv_timetic.value == 3) + V_DrawTallNum(hudinfo[HUD_RINGSNUMTICS].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUMTICS].f|V_PERPLAYER|V_HUDTRANS, totalrings); + else + V_DrawTallNum(hudinfo[HUD_RINGSNUM].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUM].f|V_PERPLAYER|V_HUDTRANS, totalrings); + } if (leveltime < 5*TICRATE && totalrings > 0) { @@ -1810,7 +1816,7 @@ static void ST_drawSpecialStageHUD(void) if (sstimer) { - V_DrawString(hudinfo[HUD_TIMELEFT].x, hudinfo[HUD_TIMELEFT].y, V_PERPLAYER|V_HUDTRANS, M_GetText("TIME LEFT")); + V_DrawString(hudinfo[HUD_TIMELEFT].x, hudinfo[HUD_TIMELEFT].y, hudinfo[HUD_TIMELEFT].f|V_PERPLAYER|V_HUDTRANS, M_GetText("TIME LEFT")); ST_DrawNumFromHud(HUD_TIMELEFTNUM, sstimer/TICRATE, V_HUDTRANS); } else @@ -1853,7 +1859,7 @@ static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offse interval = 0; } - V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, V_PERPLAYER|V_HUDTRANS, patches[i]); + V_DrawScaledPatch(hudinfo[HUD_HUNTPICS].x+offset, hudinfo[HUD_HUNTPICS].y, hudinfo[HUD_HUNTPICS].f|V_PERPLAYER|V_HUDTRANS, patches[i]); return interval; } @@ -2059,7 +2065,7 @@ static void ST_overlayDrawer(void) ST_doHuntIconsAndSound(); if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) - V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, hudinfo[HUD_GRAVBOOTSICO].y, V_PERPLAYER|V_SNAPTORIGHT, gravboots); + V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, hudinfo[HUD_GRAVBOOTSICO].y, hudinfo[HUD_GRAVBOOTSICO].f|V_PERPLAYER, gravboots); if(!P_IsLocalPlayer(stplyr)) { diff --git a/src/st_stuff.h b/src/st_stuff.h index 2294c35e4..50937907f 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -72,7 +72,7 @@ extern patch_t *ngradeletters[7]; */ typedef struct { - INT32 x, y; + INT32 x, y, f; } hudinfo_t; typedef enum diff --git a/src/y_inter.c b/src/y_inter.c index 063268626..7ac28018b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -161,9 +161,9 @@ static void Y_FollowIntermission(void); static void Y_UnloadData(void); // Stuff copy+pasted from st_stuff.c -#define ST_DrawNumFromHud(h,n) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, V_SNAPTOTOP|V_SNAPTOLEFT, n) -#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, V_SNAPTOTOP|V_SNAPTOLEFT, n, q) -#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, V_SNAPTOTOP|V_SNAPTOLEFT, p) +#define ST_DrawNumFromHud(h,n) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, n) +#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, n, q) +#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, p) static void Y_IntermissionTokenDrawer(void) { From ae033a940911e15bd1c3bdae759f8b485550bb3a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 20 Mar 2018 00:19:20 +0000 Subject: [PATCH 37/66] * Clean up a lot of NiGHTS stuff still using the old, shitty NOSCALESTART offsetting in nonstandard resolutions. * Clean up the ST_ drawing macro list. --- src/st_stuff.c | 70 +++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 4f7c8fc28..168c98724 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -410,25 +410,10 @@ void ST_changeDemoView(void) boolean st_overlay; -static INT32 SCZ(INT32 z) -{ - return FixedInt(FixedMul(z<bumpertime) - V_DrawString(SCX(locx), SCZ(locy - 8), V_NOSCALESTART|V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime))); + V_DrawString(locx, locy - 8, V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime))); else - V_DrawString(SCX(locx), SCZ(locy - 8), V_NOSCALESTART|V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20))); + V_DrawString(locx, locy - 8, V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20))); } } @@ -1416,10 +1401,10 @@ static void ST_drawNiGHTSHUD(void) for (r = 0; r < 5; r++) { - ST_DrawUnscaledOverlayPatch(SCX(230 - (7*r)), SCZ(144), redstat); - ST_DrawUnscaledOverlayPatch(SCX(188 - (7*r)), SCZ(144), orngstat); - ST_DrawUnscaledOverlayPatch(SCX(146 - (7*r)), SCZ(144), yelstat); - ST_DrawUnscaledOverlayPatch(SCX(104 - (7*r)), SCZ(144), byelstat); + V_DrawScaledPatch(230 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, redstat); + V_DrawScaledPatch(188 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, orngstat); + V_DrawScaledPatch(146 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, yelstat); + V_DrawScaledPatch(104 - (7*r), 144, V_PERPLAYER|V_HUDTRANS, byelstat); } amount = (origamount - stplyr->capsule->health); @@ -1438,7 +1423,7 @@ static void ST_drawNiGHTSHUD(void) if (r > 10) ++t; if (r > 5) ++t; - ST_DrawUnscaledOverlayPatch(SCX(69 + (7*t)), SCZ(144), bluestat); + V_DrawScaledPatch(69 + (7*t), 144, V_PERPLAYER|V_HUDTRANS, bluestat); } } } @@ -1465,9 +1450,9 @@ static void ST_drawNiGHTSHUD(void) ST_DrawTopLeftOverlayPatch(40, 8 + 5, narrow[8]); if (total_ringcount >= 100) - ST_DrawTopLeftOverlayNum((total_ringcount >= 1000) ? 76 : 72, 8 + 11, total_ringcount); + V_DrawTallNum((total_ringcount >= 1000) ? 76 : 72, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_ringcount); else - ST_DrawTopLeftOverlayNum(68, 8 + 11, total_ringcount); + V_DrawTallNum(68, 8 + 11, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTOLEFT|V_HUDTRANS, total_ringcount); #ifdef HAVE_BLUA } #endif @@ -1490,22 +1475,21 @@ static void ST_drawNiGHTSHUD(void) if (modeattacking == ATTACKING_NIGHTS) { INT32 maretime = max(stplyr->realtime - stplyr->marebegunat, 0); - fixed_t cornerx = vid.width, cornery = vid.height-SCZ(20); -#define ASSISHHUDFIX(n) (n*vid.dupx) - ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(22), cornery, W_CachePatchName("NGRTIMER", PU_HUDGFX)); - ST_DrawUnscaledPaddedOverlayNum(cornerx-ASSISHHUDFIX(22), cornery, G_TicsToCentiseconds(maretime), 2); - ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(46), cornery, sboperiod); +#define VFLAGS V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_PERPLAYER|V_HUDTRANS + V_DrawScaledPatch(BASEVIDWIDTH-22, BASEVIDHEIGHT-20, VFLAGS, W_CachePatchName("NGRTIMER", PU_HUDGFX)); + V_DrawPaddedTallNum(BASEVIDWIDTH-22, BASEVIDHEIGHT-20, VFLAGS, G_TicsToCentiseconds(maretime), 2); + V_DrawScaledPatch(BASEVIDWIDTH-46, BASEVIDHEIGHT-20, VFLAGS, sboperiod); if (maretime < 60*TICRATE) - ST_DrawUnscaledOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime)); + V_DrawTallNum(BASEVIDWIDTH-46, BASEVIDHEIGHT-20, VFLAGS, G_TicsToSeconds(maretime)); else { - ST_DrawUnscaledPaddedOverlayNum(cornerx-ASSISHHUDFIX(46), cornery, G_TicsToSeconds(maretime), 2); - ST_DrawUnscaledOverlayPatch(cornerx-ASSISHHUDFIX(70), cornery, sbocolon); - ST_DrawUnscaledOverlayNum(cornerx-ASSISHHUDFIX(70), cornery, G_TicsToMinutes(maretime, true)); + V_DrawPaddedTallNum(BASEVIDWIDTH-46, BASEVIDHEIGHT-20, VFLAGS, G_TicsToSeconds(maretime), 2); + V_DrawScaledPatch(BASEVIDWIDTH-70, BASEVIDHEIGHT-20, VFLAGS, sbocolon); + V_DrawTallNum(BASEVIDWIDTH-70, BASEVIDHEIGHT-20, VFLAGS, G_TicsToMinutes(maretime, true)); } +#undef VFLAGS } -#undef ASSISHHUDFIX } // Ideya time remaining @@ -1534,10 +1518,10 @@ static void ST_drawNiGHTSHUD(void) if (flashingLeft < TICRATE/2) // Start fading out { UINT32 fadingFlag = (9 - 9*flashingLeft/(TICRATE/2)) << V_ALPHASHIFT; - V_DrawTranslucentPatch(SCX(160 - (minus5sec->width/2)), SCZ(28), V_NOSCALESTART|V_PERPLAYER|fadingFlag, minus5sec); + V_DrawTranslucentPatch(160 - (minus5sec->width/2), 28, V_PERPLAYER|fadingFlag, minus5sec); } else - V_DrawScaledPatch(SCX(160 - (minus5sec->width/2)), SCZ(28), V_NOSCALESTART|V_PERPLAYER, minus5sec); + V_DrawScaledPatch(160 - (minus5sec->width/2), 28, V_PERPLAYER, minus5sec); } if (realnightstime < 10) @@ -1563,22 +1547,22 @@ static void ST_drawNiGHTSHUD(void) if (stplyr->powers[pw_nights_superloop]) { pwr = stplyr->powers[pw_nights_superloop]; - V_DrawSmallScaledPatch(SCX(110), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUA0",PU_CACHE)); - V_DrawThinString(SCX(106), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(110, 44, 0, W_CachePatchName("NPRUA0",PU_CACHE)); + V_DrawThinString(106, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } if (stplyr->powers[pw_nights_helper]) { pwr = stplyr->powers[pw_nights_helper]; - V_DrawSmallScaledPatch(SCX(150), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUC0",PU_CACHE)); - V_DrawThinString(SCX(146), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(150, 44, 0, W_CachePatchName("NPRUC0",PU_CACHE)); + V_DrawThinString(146, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } if (stplyr->powers[pw_nights_linkfreeze]) { pwr = stplyr->powers[pw_nights_linkfreeze]; - V_DrawSmallScaledPatch(SCX(190), SCZ(44), V_NOSCALESTART, W_CachePatchName("NPRUE0",PU_CACHE)); - V_DrawThinString(SCX(186), SCZ(52), V_NOSCALESTART|V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); + V_DrawSmallScaledPatch(190, 44, 0, W_CachePatchName("NPRUE0",PU_CACHE)); + V_DrawThinString(186, 52, V_MONOSPACE, va("%2d.%02d", pwr/TICRATE, G_TicsToCentiseconds(pwr))); } } @@ -1689,7 +1673,7 @@ static inline void ST_drawRaceHUD(void) if (!(P_AutoPause() || paused) && !bounce) S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); } - V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racenum->width))/2), (INT32)(SCZ(height)), V_NOSCALESTART|V_PERPLAYER, racenum); + V_DrawScaledPatch(((BASEVIDWIDTH - SHORT(racenum->width))/2), height, V_PERPLAYER, racenum); } if (circuitmap) From 4e95066f5ac700bd868c140c90394bd94a9c2fad Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 20 Mar 2018 14:20:02 +0000 Subject: [PATCH 38/66] 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 05bf3674d3a34b868b215e78bb6c1b709d10ff45 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 20 Mar 2018 15:00:27 +0000 Subject: [PATCH 39/66] * M_Random function access to v! (so v.RandomFixed(), etc...) * Remove deprecated P_Random() from Lua. --- src/lua_baselib.c | 11 +------ src/lua_hudlib.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9d65a5832..ed29acc33 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -214,15 +214,7 @@ static int lib_pRandomRange(lua_State *L) return 1; } -// Deprecated, macros, etc. -static int lib_pRandom(lua_State *L) -{ - NOHUD - LUA_Deprecated(L, "P_Random", "P_RandomByte"); - lua_pushinteger(L, P_RandomByte()); - return 1; -} - +// Macros. static int lib_pSignedRandom(lua_State *L) { NOHUD @@ -2481,7 +2473,6 @@ static luaL_Reg lib[] = { {"P_RandomByte",lib_pRandomByte}, {"P_RandomKey",lib_pRandomKey}, {"P_RandomRange",lib_pRandomRange}, - {"P_Random",lib_pRandom}, // DEPRECATED {"P_SignedRandom",lib_pSignedRandom}, // MACRO {"P_RandomChance",lib_pRandomChance}, // MACRO diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index a709ba9f4..afc81c37d 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -20,6 +20,7 @@ #include "i_video.h" // rendermode #include "p_local.h" // camera_t #include "screen.h" // screen width/height +#include "m_random.h" // m_random #include "v_video.h" #include "w_wad.h" #include "z_zone.h" @@ -752,20 +753,92 @@ static int libd_renderer(lua_State *L) return 1; } +// M_RANDOM +////////////// + +static int libd_RandomFixed(lua_State *L) +{ + HUDONLY + lua_pushfixed(L, M_RandomFixed()); + return 1; +} + +static int libd_RandomByte(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, M_RandomByte()); + return 1; +} + +static int libd_RandomKey(lua_State *L) +{ + INT32 a = (INT32)luaL_checkinteger(L, 1); + + HUDONLY + if (a > 65536) + LUA_UsageWarning(L, "v.RandomKey: range > 65536 is undefined behavior"); + lua_pushinteger(L, M_RandomKey(a)); + return 1; +} + +static int libd_RandomRange(lua_State *L) +{ + INT32 a = (INT32)luaL_checkinteger(L, 1); + INT32 b = (INT32)luaL_checkinteger(L, 2); + + HUDONLY + if (b < a) { + INT32 c = a; + a = b; + b = c; + } + if ((b-a+1) > 65536) + LUA_UsageWarning(L, "v.RandomRange: range > 65536 is undefined behavior"); + lua_pushinteger(L, M_RandomRange(a, b)); + return 1; +} + +// Macros. +static int libd_SignedRandom(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, M_SignedRandom()); + return 1; +} + +static int libd_RandomChance(lua_State *L) +{ + fixed_t p = luaL_checkfixed(L, 1); + HUDONLY + lua_pushboolean(L, M_RandomChance(p)); + return 1; +} + static luaL_Reg lib_draw[] = { + // cache {"patchExists", libd_patchExists}, {"cachePatch", libd_cachePatch}, {"getSpritePatch", libd_getSpritePatch}, {"getSprite2Patch", libd_getSprite2Patch}, + {"getColormap", libd_getColormap}, + // drawing {"draw", libd_draw}, {"drawScaled", libd_drawScaled}, {"drawNum", libd_drawNum}, {"drawPaddedNum", libd_drawPaddedNum}, {"drawFill", libd_drawFill}, {"drawString", libd_drawString}, - {"stringWidth", libd_stringWidth}, - {"getColormap", libd_getColormap}, {"fadeScreen", libd_fadeScreen}, + // misc + {"stringWidth", libd_stringWidth}, + // m_random + {"RandomFixed",libd_RandomFixed}, + {"RandomByte",libd_RandomByte}, + {"RandomKey",libd_RandomKey}, + {"RandomRange",libd_RandomRange}, + {"SignedRandom",libd_SignedRandom}, // MACRO + {"RandomChance",libd_RandomChance}, // MACRO + // properties {"width", libd_width}, {"height", libd_height}, {"dupx", libd_dupx}, From 24c017564e603575cf8dc59923df45d7390a848d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 21 Mar 2018 18:18:45 +0000 Subject: [PATCH 40/66] Mammoth commit! * Make TIME part of HUD count down in a bunch of circumstances where it was otherwise some other seperate thing. * Make race countdown happen in a bunch of appropriate circumstances. * Refactor race countdown. * Remove a lot of useless stuff from H&S/Tag UI. * Make co-op/competition/race end-of-act countdown use the race countdown and bigger HUD font. * Remove useless PLAYING/SPECTATE text from lives element. * Merge lap counter into lives element. * Move some other text around. --- src/hu_stuff.c | 16 +--- src/m_menu.c | 8 +- src/p_user.c | 4 +- src/screen.c | 11 +-- src/st_stuff.c | 238 ++++++++++++++++++++++++++++--------------------- src/st_stuff.h | 1 - 6 files changed, 152 insertions(+), 126 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 7af7aa768..58db7961b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1591,20 +1591,8 @@ static void HU_DrawRankings(void) { if (cv_timelimit.value && timelimitintics > 0) { - INT32 timeval = (timelimitintics+1-leveltime)/TICRATE; - - if (leveltime <= timelimitintics) - { - V_DrawCenteredString(64, 8, 0, "TIME LEFT"); - V_DrawCenteredString(64, 16, 0, va("%u", timeval)); - } - - // overtime - if ((leveltime > (timelimitintics + TICRATE/2)) && cv_overtime.value) - { - V_DrawCenteredString(64, 8, 0, "TIME LEFT"); - V_DrawCenteredString(64, 16, 0, "OVERTIME"); - } + V_DrawCenteredString(64, 8, 0, "TIME"); + V_DrawCenteredString(64, 16, 0, va("%i:%02i", G_TicsToMinutes(stplyr->realtime, true), G_TicsToSeconds(stplyr->realtime))); } if (cv_pointlimit.value > 0) diff --git a/src/m_menu.c b/src/m_menu.c index 24beff317..e53d9012f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5682,7 +5682,7 @@ static void M_DrawChecklist(void) beat = va("Get %d points in %s", cond[condnum].requirement, level); break; case UC_MAPTIME: - beat = va("Beat %s in %d:%d.%d", level, + beat = va("Beat %s in %d:%02d.%02d", level, G_TicsToMinutes(cond[condnum].requirement, true), G_TicsToSeconds(cond[condnum].requirement), G_TicsToCentiseconds(cond[condnum].requirement)); @@ -5707,7 +5707,7 @@ static void M_DrawChecklist(void) beat = va("Get %d points over all maps", cond[condnum].requirement); break; case UC_OVERALLTIME: - beat = va("Get a total time of less than %d:%d.%d", + beat = va("Get a total time of less than %d:%02d.%02d", G_TicsToMinutes(cond[condnum].requirement, true), G_TicsToSeconds(cond[condnum].requirement), G_TicsToCentiseconds(cond[condnum].requirement)); @@ -5755,12 +5755,12 @@ static void M_DrawChecklist(void) break; case UC_NIGHTSTIME: if (cond[condnum].extrainfo2) - beat = va("Beat %s, mare %d in %d:%d.%d", level, cond[condnum].extrainfo2, + beat = va("Beat %s, mare %d in %d:%02d.%02d", level, cond[condnum].extrainfo2, G_TicsToMinutes(cond[condnum].requirement, true), G_TicsToSeconds(cond[condnum].requirement), G_TicsToCentiseconds(cond[condnum].requirement)); else - beat = va("Beat %s in %d:%d.%d", + beat = va("Beat %s in %d:%02d.%02d", level, G_TicsToMinutes(cond[condnum].requirement, true), G_TicsToSeconds(cond[condnum].requirement), diff --git a/src/p_user.c b/src/p_user.c index f422e9b65..d127e7139 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1725,7 +1725,7 @@ void P_DoPlayerExit(player_t *player) else if (gametype == GT_RACE || gametype == GT_COMPETITION) // If in Race Mode, allow { if (!countdown) // a 60-second wait ala Sonic 2. - countdown = cv_countdowntime.value*TICRATE + 1; // Use cv_countdowntime + countdown = (cv_countdowntime.value - 1)*TICRATE + 1; // Use cv_countdowntime player->exiting = 3*TICRATE; @@ -9538,7 +9538,7 @@ void P_PlayerThink(player_t *player) if (i == MAXPLAYERS && player->exiting == 3*TICRATE) // finished player->exiting = (14*TICRATE)/5 + 1; - // If 10 seconds are left on the timer, + // If 11 seconds are left on the timer, // begin the drown music for countdown! if (countdown == 11*TICRATE - 1) { diff --git a/src/screen.c b/src/screen.c index 28765785b..5120aa581 100644 --- a/src/screen.c +++ b/src/screen.c @@ -455,9 +455,8 @@ void SCR_ClosedCaptions(void) if (music && !gamestopped && (closedcaptions[i].t < flashingtics) && (closedcaptions[i].t & 1)) continue; - flags = V_NOSCALESTART|V_ALLOWLOWERCASE; - y = vid.height-((i + 2)*10*vid.dupy); - dot = ' '; + flags = V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_ALLOWLOWERCASE; + y = BASEVIDHEIGHT-((i + 2)*10); if (closedcaptions[i].b) y -= (closedcaptions[i].b--)*vid.dupy; @@ -469,8 +468,10 @@ void SCR_ClosedCaptions(void) dot = '\x19'; else if (closedcaptions[i].c && closedcaptions[i].c->origin) dot = '\x1E'; + else + dot = ' '; - V_DrawRightAlignedString(vid.width-(20*vid.dupx), y, - flags, va("%c [%s]", dot, (closedcaptions[i].s->caption[0] ? closedcaptions[i].s->caption : closedcaptions[i].s->name))); + V_DrawRightAlignedString(BASEVIDWIDTH - 20, y, flags, + va("%c [%s]", dot, (closedcaptions[i].s->caption[0] ? closedcaptions[i].s->caption : closedcaptions[i].s->name))); } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 168c98724..b9005ab68 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -151,8 +151,6 @@ hudinfo_t hudinfo[NUMHUDITEMS] = { 152, 168, 0}, // HUD_HUNTPICS { 152, 24, V_SNAPTORIGHT}, // HUD_GRAVBOOTSICO - - { 240, 160, V_SNAPTOBOTTOM|V_SNAPTORIGHT}, // HUD_LAP }; // @@ -541,15 +539,46 @@ static void ST_drawScore(void) ST_DrawNumFromHud(HUD_SCORENUM, op_displayflags, V_HUDTRANS); } else - ST_DrawNumFromHud(HUD_SCORENUM, stplyr->score,V_HUDTRANS); + ST_DrawNumFromHud(HUD_SCORENUM, stplyr->score, V_HUDTRANS); +} + +static void ST_drawRaceNum(INT32 time) +{ + INT32 height, bounce; + patch_t *racenum; + + time += TICRATE; + height = ((3*BASEVIDHEIGHT)>>2) - 8; + bounce = TICRATE - (1 + (time % TICRATE)); + + switch (time/TICRATE) + { + case 3: + racenum = race3; + break; + case 2: + racenum = race2; + break; + case 1: + racenum = race1; + break; + default: + racenum = racego; + break; + } + if (bounce < 3) + { + height -= (2 - bounce); + if (!(P_AutoPause() || paused) && !bounce) + S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); + } + V_DrawScaledPatch(((BASEVIDWIDTH - SHORT(racenum->width))/2), height, V_PERPLAYER, racenum); } static void ST_drawTime(void) { INT32 seconds, minutes, tictrn, tics; - - // TIME: - ST_DrawPatchFromHud(HUD_TIME, ((mapheaderinfo[gamemap-1]->countdown && countdowntimer < 11*TICRATE && leveltime/5 & 1) ? sboredtime : sbotime), V_HUDTRANS); + boolean downwards = false; if (objectplacing) { @@ -560,12 +589,61 @@ static void ST_drawTime(void) } else { - tics = (mapheaderinfo[gamemap-1]->countdown ? countdowntimer : stplyr->realtime); - seconds = G_TicsToSeconds(tics); + // Counting down the hidetime? + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (leveltime <= (hidetime*TICRATE))) + { + tics = (hidetime*TICRATE - leveltime); + if (tics < 3*TICRATE) + ST_drawRaceNum(tics); + downwards = true; + } + else + { + // Hidetime finish! + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (leveltime < ((hidetime+1)*TICRATE))) + ST_drawRaceNum(hidetime*TICRATE - leveltime); + + // Time limit? + if (gametype != GT_RACE && gametype != GT_COMPETITION && gametype != GT_COOP && cv_timelimit.value && timelimitintics > 0) + { + if (timelimitintics >= leveltime) + { + tics = (timelimitintics - leveltime); + if (tics < 3*TICRATE) + ST_drawRaceNum(tics); + } + else // Overtime! + tics = 0; + downwards = true; + } + // Post-hidetime normal. + else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + tics = stplyr->realtime - hidetime*TICRATE; + // "Shadow! What are you doing? Hurry and get back here + // right now before the island blows up with you on it!" + // "Blows up??" *awkward silence* "I've got to get outta + // here and find Amy and Tails right away!" + else if (mapheaderinfo[gamemap-1]->countdown) + { + tics = countdowntimer; + downwards = true; + } + // Normal. + else + tics = stplyr->realtime; + } + minutes = G_TicsToMinutes(tics, true); + seconds = G_TicsToSeconds(tics); tictrn = G_TicsToCentiseconds(tics); } + // TIME: + ST_DrawPatchFromHud(HUD_TIME, ((downwards && (tics < 30*TICRATE) && (leveltime/5 & 1)) ? sboredtime : sbotime), V_HUDTRANS); + + if (!tics && downwards && (leveltime/5 & 1)) // overtime! + return; + if (cv_timetic.value == 1) // Tics only -- how simple is this? ST_DrawNumFromHud(HUD_SECONDS, tics, V_HUDTRANS); else @@ -709,7 +787,7 @@ static void ST_drawLivesArea(void) // Spectator else if (stplyr->spectator) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "SPECTATE"); + //V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "SPECTATOR"); v_colmap = V_GRAYMAP; } // Tag @@ -747,10 +825,19 @@ static void ST_drawLivesArea(void) else v_colmap = V_GRAYMAP; } - else + else if (circuitmap) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "PLAYING"); + if (stplyr->exiting) + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "FINISHED"); + //V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f|V_YELLOWMAP, "FINISHED!"); + else + { + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, va("%u/%d", stplyr->laps+1, cv_numlaps.value)); + //V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); + } } + /*else + V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "PLAYING");*/ // name v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); @@ -1647,92 +1734,34 @@ static void ST_drawMatchHUD(void) static inline void ST_drawRaceHUD(void) { - if (leveltime >= TICRATE && leveltime < 5*TICRATE) - { - INT32 height = ((3*BASEVIDHEIGHT)>>2) - 8; - INT32 bounce = (leveltime % TICRATE); - patch_t *racenum; - switch (leveltime/TICRATE) - { - case 1: - racenum = race3; - break; - case 2: - racenum = race2; - break; - case 3: - racenum = race1; - break; - default: - racenum = racego; - break; - } - if (bounce < 3) - { - height -= (2 - bounce); - if (!(P_AutoPause() || paused) && !bounce) - S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7)); - } - V_DrawScaledPatch(((BASEVIDWIDTH - SHORT(racenum->width))/2), height, V_PERPLAYER, racenum); - } - - if (circuitmap) - { - if (stplyr->exiting) - V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f|V_YELLOWMAP, "FINISHED!"); - else - V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); - } + if (leveltime > TICRATE && leveltime <= 5*TICRATE) + ST_drawRaceNum(4*TICRATE - leveltime); } static void ST_drawTagHUD(void) { - char pstime[33] = ""; char pstext[33] = ""; // Figure out what we're going to print. if (leveltime < hidetime * TICRATE) //during the hide time, the seeker and hiders have different messages on their HUD. { - if (hidetime) - sprintf(pstime, "%d", (hidetime - leveltime/TICRATE)); //hide time is in seconds, not tics. - - if (stplyr->pflags & PF_TAGIT && !stplyr->spectator) - sprintf(pstext, "%s", M_GetText("WAITING FOR PLAYERS TO HIDE...")); - else - { - if (!stplyr->spectator) //spectators get a generic HUD message rather than a gametype specific one. - { - if (gametype == GT_HIDEANDSEEK) //hide and seek. - sprintf(pstext, "%s", M_GetText("HIDE BEFORE TIME RUNS OUT!")); - else //default - sprintf(pstext, "%s", M_GetText("FLEE BEFORE YOU ARE HUNTED!")); - } - else - sprintf(pstext, "%s", M_GetText("HIDE TIME REMAINING:")); - } - } - else - { - if (cv_timelimit.value && timelimitintics >= leveltime) - sprintf(pstime, "%d", (timelimitintics-leveltime)/TICRATE); - if (stplyr->pflags & PF_TAGIT) - sprintf(pstext, "%s", M_GetText("YOU'RE IT!")); - else - { - if (cv_timelimit.value) - sprintf(pstext, "%s", M_GetText("TIME REMAINING:")); - else //Since having no hud message in tag is not characteristic: - sprintf(pstext, "%s", M_GetText("NO TIME LIMIT")); - } + sprintf(pstext, "%s", M_GetText("Waiting for players to hide...")); + else if (gametype == GT_HIDEANDSEEK) //hide and seek. + sprintf(pstext, "%s", M_GetText("Hide before time runs out!")); + else //default + sprintf(pstext, "%s", M_GetText("Flee before you are hunted!")); } + else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) + { + sprintf(pstext, "%s", M_GetText("You cannot move while hiding.")); + if (!splitscreen) + V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); + } // Print the stuff. if (pstext[0]) - V_DrawCenteredString(BASEVIDWIDTH/2, 168, V_PERPLAYER|V_SNAPTOBOTTOM, pstext); - - if (pstime[0]) - V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_PERPLAYER|V_SNAPTOBOTTOM, pstime); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER, pstext); } static void ST_drawCTFHUD(void) @@ -2010,8 +2039,24 @@ static void ST_overlayDrawer(void) if (!hu_showscores) // hide the following if TAB is held { // Countdown timer for Race Mode - if (countdown) - V_DrawCenteredString(BASEVIDWIDTH/2, 176, V_PERPLAYER, va("%d", countdown/TICRATE)); + if (countdown > 1) + { + tic_t time = countdown/TICRATE + 1; + if (time < 4) + ST_drawRaceNum(countdown); + else + { + tic_t num = time; + INT32 sz = SHORT(tallnum[0]->width)/2, width = 0; + do + { + width += sz; + num /= 10; + } while (num); + V_DrawTallNum((BASEVIDWIDTH/2) + width, ((3*BASEVIDHEIGHT)>>2) - 7, V_PERPLAYER, time); + //V_DrawCenteredString(BASEVIDWIDTH/2, 176, V_PERPLAYER, va("%d", countdown/TICRATE + 1)); + } + } // If you are in overtime, put a big honkin' flashin' message on the screen. if (G_RingSlingerGametype() && cv_overtime.value @@ -2032,7 +2077,7 @@ static void ST_overlayDrawer(void) if (gametype == GT_RACE || gametype == GT_COMPETITION) ST_drawRaceHUD(); // Tag HUD Stuff - else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) ST_drawTagHUD(); // CTF HUD Stuff else if (gametype == GT_CTF) @@ -2118,20 +2163,13 @@ static void ST_overlayDrawer(void) } else if (!splitscreen && gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); - else if (gametype == GT_HIDEANDSEEK && - (!stplyr->spectator && !(stplyr->pflags & PF_TAGIT)) && (leveltime > hidetime * TICRATE)) - { - V_DrawCenteredString(BASEVIDWIDTH/2, 116, V_PERPLAYER, M_GetText("You cannot move while hiding.")); - if (!splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); - } else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; if (respawntime > 0 && !stplyr->spectator) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, va(M_GetText("Respawn in %d..."), respawntime)); else - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); } else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE) #ifdef HAVE_BLUA @@ -2141,9 +2179,9 @@ static void ST_overlayDrawer(void) { V_DrawCenteredString(BASEVIDWIDTH/2, 60, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You are a spectator.")); if (G_GametypeHasTeams()) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); else if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); else if (gametype == GT_COOP && stplyr->lives <= 0) { if (cv_cooplives.value == 2 @@ -2163,13 +2201,13 @@ static void ST_overlayDrawer(void) } if (i != MAXPLAYERS) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); } } else if (gametype != GT_COOP) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); if (!splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); + V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); V_DrawCenteredString(BASEVIDWIDTH/2, 148, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); } } diff --git a/src/st_stuff.h b/src/st_stuff.h index 50937907f..df1ac6433 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -102,7 +102,6 @@ typedef enum HUD_TIMEUP, HUD_HUNTPICS, HUD_GRAVBOOTSICO, - HUD_LAP, NUMHUDITEMS } hudnum_t; From 0885d271711155e02d389c04f12bf2c234d1a7f1 Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 21 Mar 2018 19:45:37 +0000 Subject: [PATCH 41/66] 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 42/66] 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 43/66] 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 f62cb3a30a7bd36d52a5c6a7853baf9aaf887aa9 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 23 Mar 2018 22:27:29 +0000 Subject: [PATCH 44/66] 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 dc9fd6f02ed4b681ed4982d119672f07cc91e585 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 25 Mar 2018 19:07:21 -0400 Subject: [PATCH 45/66] MT_NIGHTSBUMPER Spawn: Don't reset mthing->options --- src/p_mobj.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 8695d57e4..157092dea 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10060,9 +10060,6 @@ domaceagain: // the bumper in 30 degree increments. mobj->threshold = (mthing->options & 15) % 12; // It loops over, etc P_SetMobjState(mobj, mobj->info->spawnstate+mobj->threshold); - - // you can shut up now, OBJECTFLIP. And all of the other options, for that matter. - mthing->options &= ~0xF; break; case MT_EGGCAPSULE: if (mthing->angle <= 0) From d85f108997bfeca3e0b1731c1aad70617456400b Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 25 Mar 2018 19:42:46 -0400 Subject: [PATCH 46/66] P_SpawnMapThing: Ignore MTF_ flags if MT_NIGHTSBUMPER --- src/p_mobj.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 157092dea..4c0ebb657 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10261,6 +10261,14 @@ domaceagain: } } + // ignore MTF_ flags and return early + if (i == MT_NIGHTSBUMPER) + { + mobj->angle = FixedAngle(mthing->angle*FRACUNIT); + mthing->mobj = mobj; + return; + } + mobj->angle = FixedAngle(mthing->angle*FRACUNIT); if ((mthing->options & MTF_AMBUSH) From 98601dc757cb2c06fe8402bbb76f92475b7bd0c5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 26 Mar 2018 23:53:09 +0100 Subject: [PATCH 47/66] A lot! * cv_powerupdisplay. Never, First-person only (default), Always. * New monitor stuff. * Fixed hitmessages. * Some CTF stuff. * Aaaaugh it's a lot I hate myself I need to work on my coursework. * I'll figure out what I did here in the merge request when that's done. --- src/d_netcmd.c | 6 +- src/dehacked.c | 9 +- src/doomstat.h | 1 + src/hu_stuff.c | 22 +-- src/info.c | 163 +++++++++---------- src/info.h | 7 +- src/m_cheat.c | 2 +- src/m_menu.c | 27 ++-- src/p_inter.c | 5 +- src/p_spec.c | 9 +- src/p_user.c | 12 +- src/screen.c | 14 +- src/sounds.c | 16 +- src/st_stuff.c | 417 +++++++++++++++++++++++++++++++------------------ src/st_stuff.h | 2 +- 15 files changed, 415 insertions(+), 297 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 94eada152..cc641b8b0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -309,9 +309,12 @@ consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Tics"}, {2, "Centiseconds"}, {3, "Mania"}, {0, NULL}}; +static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Centiseconds"}, {2, "Mania"}, {3, "Tics"}, {0, NULL}}; consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display +static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}}; +consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display + consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}}; @@ -670,6 +673,7 @@ void D_RegisterClientCommands(void) // HUD CV_RegisterVar(&cv_timetic); + CV_RegisterVar(&cv_powerupdisplay); CV_RegisterVar(&cv_itemfinder); CV_RegisterVar(&cv_showinputjoy); diff --git a/src/dehacked.c b/src/dehacked.c index 704786879..3726cb381 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4521,6 +4521,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BOXSPARKLE1", "S_BOXSPARKLE2", "S_BOXSPARKLE3", + "S_BOXSPARKLE4", "S_BOX_FLICKER", "S_BOX_POP1", @@ -5511,8 +5512,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Got Flag Sign "S_GOTFLAG", - "S_GOTREDFLAG", - "S_GOTBLUEFLAG", "S_CORK", @@ -5852,6 +5851,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_XPLD_FLICKY", "S_XPLD1", "S_XPLD2", + "S_XPLD3", + "S_XPLD4", + "S_XPLD5", + "S_XPLD6", "S_XPLD_EGGTRAP", // Underwater Explosion @@ -6815,7 +6818,7 @@ static const char *const HUDITEMS_LIST[] = { "TIMELEFTNUM", "TIMEUP", "HUNTPICS", - "GRAVBOOTSICO", + "POWERUPS", "LAP" }; diff --git a/src/doomstat.h b/src/doomstat.h index de260ef06..d4735f6b2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -498,6 +498,7 @@ extern boolean singletics; #include "d_clisrv.h" extern consvar_t cv_timetic; // display high resolution timer +extern consvar_t cv_powerupdisplay; // display powerups extern consvar_t cv_showinputjoy; // display joystick in time attack extern consvar_t cv_forceskin; // force clients to use the server's skin extern consvar_t cv_downloading; // allow clients to downloading WADs. diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 58db7961b..c955a490d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1547,7 +1547,7 @@ static inline void HU_DrawSpectatorTicker(void) templength = length; } - V_DrawString(templength, height + 8, V_TRANSLUCENT, current); + V_DrawString(templength, height + 8, V_TRANSLUCENT|V_ALLOWLOWERCASE, current); } length += (signed)strlen(player_names[i]) * 8 + 16; @@ -1559,7 +1559,6 @@ static inline void HU_DrawSpectatorTicker(void) // static void HU_DrawRankings(void) { - patch_t *p; playersort_t tab[MAXPLAYERS]; INT32 i, j, scorelines; boolean completed[MAXPLAYERS]; @@ -1568,25 +1567,6 @@ static void HU_DrawRankings(void) // draw the current gametype in the lower right HU_drawGametype(); - if (G_GametypeHasTeams()) - { - if (gametype == GT_CTF) - p = bflagico; - else - p = bmatcico; - - V_DrawSmallScaledPatch(128 - SHORT(p->width)/4, 4, 0, p); - V_DrawCenteredString(128, 16, 0, va("%u", bluescore)); - - if (gametype == GT_CTF) - p = rflagico; - else - p = rmatcico; - - V_DrawSmallScaledPatch(192 - SHORT(p->width)/4, 4, 0, p); - V_DrawCenteredString(192, 16, 0, va("%u", redscore)); - } - if (gametype != GT_RACE && gametype != GT_COMPETITION && gametype != GT_COOP) { if (cv_timelimit.value && timelimitintics > 0) diff --git a/src/info.c b/src/info.c index acb12379a..58a2ba8f4 100644 --- a/src/info.c +++ b/src/info.c @@ -680,7 +680,7 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY // 1-Up box sprites (uses player sprite) - {SPR_PLAY, SPR2_LIFE, 2, {NULL}, 0, 16, S_PLAY_BOX2}, // S_PLAY_BOX1 + {SPR_PLAY, SPR2_LIFE, 2, {NULL}, 0, 18, S_PLAY_BOX2}, // S_PLAY_BOX1 {SPR_NULL, 0, 1, {NULL}, 0, 0, S_PLAY_BOX1}, // S_PLAY_BOX2 {SPR_PLAY, SPR2_LIFE, 4, {NULL}, 0, 4, S_PLAY_ICON2}, // S_PLAY_ICON1 {SPR_NULL, 0, 12, {NULL}, 0, 0, S_PLAY_ICON3}, // S_PLAY_ICON2 @@ -1727,9 +1727,10 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 2, {A_SetRandomTics}, TICRATE/2, 3*TICRATE, S_CANNONLAUNCHER1}, // S_CANNONLAUNCHER3 // Monitor Miscellany - {SPR_NSPK, FF_TRANS40, 20, {NULL}, 0, 0, S_BOXSPARKLE2}, // S_BOXSPARKLE1 - {SPR_NSPK, FF_TRANS60, 10, {NULL}, 0, 0, S_BOXSPARKLE3}, // S_BOXSPARKLE2 - {SPR_NSPK, FF_TRANS80, 5, {NULL}, 0, 0, S_NULL}, // S_BOXSPARKLE3 + {SPR_NSPK, 0, 16, {NULL}, 0, 0, S_BOXSPARKLE2}, // S_BOXSPARKLE1 + {SPR_NSPK, 1, 12, {NULL}, 0, 0, S_BOXSPARKLE3}, // S_BOXSPARKLE2 + {SPR_NSPK, 2, 8, {NULL}, 0, 0, S_BOXSPARKLE4}, // S_BOXSPARKLE3 + {SPR_NSPK, 3, 4, {NULL}, 0, 0, S_NULL}, // S_BOXSPARKLE4 {SPR_MSTV, 0, 1, {NULL}, 0, 0, S_SPAWNSTATE}, // S_BOX_FLICKER {SPR_MSTV, 0, 4, {A_MonitorPop}, 0, 0, S_BOX_POP2}, // S_BOX_POP1 @@ -2735,8 +2736,6 @@ state_t states[NUMSTATES] = // CTF Sign {SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG - {SPR_GFLG, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTREDFLAG - {SPR_GFLG, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTBLUEFLAG {SPR_CORK, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORK @@ -3121,11 +3120,15 @@ state_t states[NUMSTATES] = {SPR_SPRK, FF_TRANS90|3, 1, {NULL}, 0, 0, S_NULL}, // S_SPRK16 // Robot Explosion - {SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY - {SPR_BOM1, 0, 1, {A_Scream}, 0, 0, S_XPLD2}, // S_XPLD1 - {SPR_BOM1, FF_ANIMATE|1, 15, {NULL}, 2, 5, S_NULL}, // S_XPLD2 + {SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY + {SPR_BOM1, 0, 2, {A_Scream}, 0, 0, S_XPLD2}, // S_XPLD1 + {SPR_BOM1, 1, 2, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2 + {SPR_BOM1, 2, 3, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3 + {SPR_BOM1, 3, 3, {NULL}, 0, 0, S_XPLD5}, // S_XPLD4 + {SPR_BOM1, 4, 4, {NULL}, 0, 0, S_XPLD6}, // S_XPLD5 + {SPR_BOM1, 5, 4, {NULL}, 0, 0, S_NULL}, // S_XPLD6 - {SPR_BOM1, FF_ANIMATE, 20, {NULL}, 3, 5, S_INVISIBLE}, // S_XPLD_EGGTRAP + {SPR_BOM1, FF_ANIMATE, 21, {NULL}, 5, 4, S_INVISIBLE}, // S_XPLD_EGGTRAP // Underwater Explosion {SPR_BOM4, 0, 3, {A_Scream}, 0, 0, S_WPLD2}, // S_WPLD1 @@ -6386,8 +6389,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_RING_ICON, // damage @@ -6413,8 +6416,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_PITY_ICON, // damage @@ -6440,8 +6443,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_ATTRACT_ICON,// damage @@ -6467,8 +6470,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_FORCE_ICON, // damage @@ -6494,8 +6497,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_ARMAGEDDON_ICON, // damage @@ -6521,8 +6524,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_WHIRLWIND_ICON, // damage @@ -6548,8 +6551,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_ELEMENTAL_ICON, // damage @@ -6575,8 +6578,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_SNEAKERS_ICON, // damage @@ -6602,8 +6605,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_INVULN_ICON, // damage @@ -6629,8 +6632,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_1UP_ICON, // damage @@ -6656,8 +6659,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_EGGMAN_ICON, // damage @@ -6683,8 +6686,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_MIXUP_ICON, // damage @@ -6710,8 +6713,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_UNKNOWN, // damage @@ -6737,8 +6740,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_GRAVITY_ICON, // damage @@ -6764,8 +6767,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_RECYCLER_ICON, // damage @@ -6791,8 +6794,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_SCORE1K_ICON, // damage @@ -6818,8 +6821,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_SCORE10K_ICON, // damage @@ -6845,8 +6848,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_FLAMEAURA_ICON, // damage @@ -6872,8 +6875,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_BUBBLEWRAP_ICON, // damage @@ -6899,8 +6902,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 1, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_THUNDERCOIN_ICON, // damage @@ -6926,8 +6929,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_PITY_ICON, // damage @@ -6953,8 +6956,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_ATTRACT_ICON,// damage @@ -6980,8 +6983,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_FORCE_ICON, // damage @@ -7007,8 +7010,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_ARMAGEDDON_ICON, // damage @@ -7034,8 +7037,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_WHIRLWIND_ICON, // damage @@ -7061,8 +7064,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_ELEMENTAL_ICON, // damage @@ -7088,8 +7091,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_SNEAKERS_ICON, // damage @@ -7115,8 +7118,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_INVULN_ICON, // damage @@ -7142,8 +7145,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_EGGMAN_ICON, // damage @@ -7169,8 +7172,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_GRAVITY_ICON, // damage @@ -7196,8 +7199,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_FLAMEAURA_ICON, // damage @@ -7223,8 +7226,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_BUBBLEWRAP_ICON, // damage @@ -7250,8 +7253,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 36*FRACUNIT, // height + 20*FRACUNIT, // radius + 44*FRACUNIT, // height 0, // display offset 100, // mass MT_THUNDERCOIN_ICON, // damage @@ -7277,8 +7280,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_RING_ICON, // damage @@ -7304,8 +7307,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_pop, // deathsound 0, // speed - 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 18*FRACUNIT, // radius + 40*FRACUNIT, // height 0, // display offset 100, // mass MT_RING_ICON, // damage diff --git a/src/info.h b/src/info.h index 35a3f5f15..f9052b5da 100644 --- a/src/info.h +++ b/src/info.h @@ -1834,6 +1834,7 @@ typedef enum state S_BOXSPARKLE1, S_BOXSPARKLE2, S_BOXSPARKLE3, + S_BOXSPARKLE4, S_BOX_FLICKER, S_BOX_POP1, @@ -2826,8 +2827,6 @@ typedef enum state // Got Flag Sign S_GOTFLAG, - S_GOTREDFLAG, - S_GOTBLUEFLAG, S_CORK, @@ -3167,6 +3166,10 @@ typedef enum state S_XPLD_FLICKY, S_XPLD1, S_XPLD2, + S_XPLD3, + S_XPLD4, + S_XPLD5, + S_XPLD6, S_XPLD_EGGTRAP, // Underwater Explosion diff --git a/src/m_cheat.c b/src/m_cheat.c index a4eaede3a..174e2780d 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1266,7 +1266,7 @@ void Command_ObjectPlace_f(void) if (!COM_CheckParm("-silent")) { - HU_SetCEchoFlags(V_RETURN8|V_MONOSPACE); + HU_SetCEchoFlags(V_RETURN8|V_MONOSPACE|V_AUTOFADEOUT); HU_SetCEchoDuration(10); HU_DoCEcho(va(M_GetText( "\\\\\\\\\\\\\\\\\\\\\\\\\x82" diff --git a/src/m_menu.c b/src/m_menu.c index e53d9012f..4857df104 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1196,24 +1196,25 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Show HUD", &cv_showhud, 61}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "HUD Transparency", &cv_translucenthud, 66}, - {IT_STRING | IT_CVAR, NULL, "Time Display", &cv_timetic, 71}, + {IT_STRING | IT_CVAR, NULL, "Score/Time/Rings", &cv_timetic, 71}, + {IT_STRING | IT_CVAR, NULL, "Show Powerups", &cv_powerupdisplay, 76}, #ifdef SEENAMES - {IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 76}, + {IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 81}, #endif - {IT_HEADER, NULL, "Console", NULL, 85}, - {IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 91}, - {IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 96}, + {IT_HEADER, NULL, "Console", NULL, 90}, + {IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 96}, + {IT_STRING | IT_CVAR, NULL, "Text Size", &cv_constextsize, 101}, - {IT_HEADER, NULL, "Level", NULL, 105}, - {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 111}, - {IT_STRING | IT_CVAR, NULL, "NiGHTS Draw Dist.", &cv_drawdist_nights, 116}, - {IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 121}, - {IT_STRING | IT_CVAR, NULL, "Weather Density", &cv_precipdensity, 126}, + {IT_HEADER, NULL, "Level", NULL, 110}, + {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 116}, + {IT_STRING | IT_CVAR, NULL, "NiGHTS Draw Dist.", &cv_drawdist_nights, 121}, + {IT_STRING | IT_CVAR, NULL, "Weather Draw Dist.", &cv_drawdist_precip, 126}, + {IT_STRING | IT_CVAR, NULL, "Weather Density", &cv_precipdensity, 131}, - {IT_HEADER, NULL, "Diagnostic", NULL, 135}, - {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 141}, - {IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 146}, + {IT_HEADER, NULL, "Diagnostic", NULL, 140}, + {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 146}, + {IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 151}, }; static menuitem_t OP_VideoModeMenu[] = diff --git a/src/p_inter.c b/src/p_inter.c index 4c9e231fe..833a9ba52 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3365,8 +3365,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_KillPlayer(player, source, damage); } - P_HitDeathMessages(player, inflictor, source, damagetype); - P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); } @@ -3381,6 +3379,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da else target->health -= damage; + if (player) + P_HitDeathMessages(player, inflictor, source, damagetype); + if (source && source->player && target) G_GhostAddHit(target); diff --git a/src/p_spec.c b/src/p_spec.c index 0b005baff..595473a5c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -31,6 +31,7 @@ #include "p_polyobj.h" #include "p_slopes.h" #include "hu_stuff.h" +#include "v_video.h" // V_AUTOFADEOUT|V_ALLOWLOWERCASE #include "m_misc.h" #include "m_cond.h" //unlock triggers #include "lua_hook.h" // LUAh_LinedefExecute @@ -3815,9 +3816,9 @@ DoneSection2: if (!P_IsFlagAtBase(MT_REDFLAG)) break; - HU_SetCEchoFlags(0); + HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); HU_SetCEchoDuration(5); - HU_DoCEcho(va(M_GetText("%s\\captured the blue flag.\\\\\\\\"), player_names[player-players])); + HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sBLUE FLAG%s.\\\\\\\\"), "\x85", player_names[player-players], "\x80", "\x84", "\x80")); if (splitscreen || players[consoleplayer].ctfteam == 1) S_StartSound(NULL, sfx_flgcap); @@ -3848,9 +3849,9 @@ DoneSection2: if (!P_IsFlagAtBase(MT_BLUEFLAG)) break; - HU_SetCEchoFlags(0); + HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); HU_SetCEchoDuration(5); - HU_DoCEcho(va(M_GetText("%s\\captured the red flag.\\\\\\\\"), player_names[player-players])); + HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sRED FLAG%s.\\\\\\\\"), "\x84", player_names[player-players], "\x80", "\x85", "\x80")); if (splitscreen || players[consoleplayer].ctfteam == 2) S_StartSound(NULL, sfx_flgcap); diff --git a/src/p_user.c b/src/p_user.c index d127e7139..86eb1bef4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2585,13 +2585,11 @@ static void P_DoPlayerHeadSigns(player_t *player) } else sign->z += P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale); - if (leveltime & 4) - { - if (player->gotflag & GF_REDFLAG) - P_SetMobjStateNF(sign, S_GOTREDFLAG); - } - else if (player->gotflag & GF_BLUEFLAG) - P_SetMobjStateNF(sign, S_GOTBLUEFLAG); + + if (player->gotflag & GF_REDFLAG) + sign->frame = 1|FF_FULLBRIGHT; + else //if (player->gotflag & GF_BLUEFLAG) + sign->frame = 2|FF_FULLBRIGHT; } } } diff --git a/src/screen.c b/src/screen.c index 5120aa581..5b16992c7 100644 --- a/src/screen.c +++ b/src/screen.c @@ -440,6 +440,18 @@ void SCR_ClosedCaptions(void) { UINT8 i; boolean gamestopped = (paused || P_AutoPause()); + INT32 basey = BASEVIDHEIGHT; + + if (gamestate == GS_LEVEL) + { + if (splitscreen) + basey -= 8; + else if (((maptol & TOL_NIGHTS) && (modeattacking == ATTACKING_NIGHTS)) + || (cv_powerupdisplay.value == 2) + || (cv_powerupdisplay.value == 1 && ((stplyr == &players[displayplayer] && !camera.chase) + || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)))) + basey -= 16; + } for (i = 0; i < NUMCAPTIONS; i++) { @@ -456,7 +468,7 @@ void SCR_ClosedCaptions(void) continue; flags = V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_ALLOWLOWERCASE; - y = BASEVIDHEIGHT-((i + 2)*10); + y = basey-((i + 2)*10); if (closedcaptions[i].b) y -= (closedcaptions[i].b--)*vid.dupy; diff --git a/src/sounds.c b/src/sounds.c index 475d65cd1..293ce381d 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -85,14 +85,14 @@ sfxinfo_t S_sfx[NUMSFX] = {"athun1", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Thunder"}, {"athun2", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Thunder"}, - {"amwtr1", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr2", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr3", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr4", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr5", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr6", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr7", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, - {"amwtr8", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"}, + {"amwtr1", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr2", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr3", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr4", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr5", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr6", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr7", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, + {"amwtr8", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stream"}, {"bubbl1", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, {"bubbl2", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, {"bubbl3", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, diff --git a/src/st_stuff.c b/src/st_stuff.c index 93709e453..25a61fa3a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -101,6 +101,7 @@ static patch_t *invincibility; static patch_t *sneakers; static patch_t *gravboots; static patch_t *nonicon; +static patch_t *nonicon2; static patch_t *bluestat; static patch_t *byelstat; static patch_t *orngstat; @@ -150,7 +151,7 @@ hudinfo_t hudinfo[NUMHUDITEMS] = { 130, 93, 0}, // HUD_TIMEUP { 152, 168, 0}, // HUD_HUNTPICS - { 152, 24, V_SNAPTORIGHT}, // HUD_GRAVBOOTSICO + { 288, 176, V_SNAPTORIGHT|V_SNAPTOBOTTOM}, // HUD_POWERUPS }; // @@ -275,18 +276,18 @@ void ST_LoadGraphics(void) scatterring = W_CachePatchName("SCATIND", PU_HUDGFX); grenadering = W_CachePatchName("GRENIND", PU_HUDGFX); railring = W_CachePatchName("RAILIND", PU_HUDGFX); - jumpshield = W_CachePatchName("TVWWC0", PU_HUDGFX); - forceshield = W_CachePatchName("TVFOC0", PU_HUDGFX); - ringshield = W_CachePatchName("TVATC0", PU_HUDGFX); - watershield = W_CachePatchName("TVELC0", PU_HUDGFX); - bombshield = W_CachePatchName("TVARC0", PU_HUDGFX); - pityshield = W_CachePatchName("TVPIC0", PU_HUDGFX); - flameshield = W_CachePatchName("TVFLC0", PU_HUDGFX); - bubbleshield = W_CachePatchName("TVBBC0", PU_HUDGFX); - thundershield = W_CachePatchName("TVZPC0", PU_HUDGFX); - invincibility = W_CachePatchName("TVIVC0", PU_HUDGFX); - sneakers = W_CachePatchName("TVSSC0", PU_HUDGFX); - gravboots = W_CachePatchName("TVGVC0", PU_HUDGFX); + jumpshield = W_CachePatchName("TVWWICON", PU_HUDGFX); + forceshield = W_CachePatchName("TVFOICON", PU_HUDGFX); + ringshield = W_CachePatchName("TVATICON", PU_HUDGFX); + watershield = W_CachePatchName("TVELICON", PU_HUDGFX); + bombshield = W_CachePatchName("TVARICON", PU_HUDGFX); + pityshield = W_CachePatchName("TVPIICON", PU_HUDGFX); + flameshield = W_CachePatchName("TVFLICON", PU_HUDGFX); + bubbleshield = W_CachePatchName("TVBBICON", PU_HUDGFX); + thundershield = W_CachePatchName("TVZPICON", PU_HUDGFX); + invincibility = W_CachePatchName("TVIVICON", PU_HUDGFX); + sneakers = W_CachePatchName("TVSSICON", PU_HUDGFX); + gravboots = W_CachePatchName("TVGVICON", PU_HUDGFX); tagico = W_CachePatchName("TAGICO", PU_HUDGFX); rflagico = W_CachePatchName("RFLAGICO", PU_HUDGFX); @@ -296,6 +297,7 @@ void ST_LoadGraphics(void) gotrflag = W_CachePatchName("GOTRFLAG", PU_HUDGFX); gotbflag = W_CachePatchName("GOTBFLAG", PU_HUDGFX); nonicon = W_CachePatchName("NONICON", PU_HUDGFX); + nonicon2 = W_CachePatchName("NONICON2", PU_HUDGFX); // NiGHTS HUD things bluestat = W_CachePatchName("BLUESTAT", PU_HUDGFX); @@ -644,7 +646,7 @@ static void ST_drawTime(void) if (!tics && downwards && (leveltime/5 & 1)) // overtime! return; - if (cv_timetic.value == 1) // Tics only -- how simple is this? + if (cv_timetic.value == 3) // Tics only -- how simple is this? ST_DrawNumFromHud(HUD_SECONDS, tics, V_HUDTRANS); else { @@ -652,7 +654,7 @@ static void ST_drawTime(void) ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds - if (cv_timetic.value == 2 || cv_timetic.value == 3 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! + if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying! { ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod, V_HUDTRANS); // Period ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2, V_HUDTRANS); // Tics @@ -679,7 +681,7 @@ static inline void ST_drawRings(void) else ringnum = max(stplyr->rings, 0); - if (cv_timetic.value == 3) // Yes, even in modeattacking + if (cv_timetic.value == 2) // Yes, even in modeattacking ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); else ST_DrawNumFromHud(HUD_RINGSNUM, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS)); @@ -1128,93 +1130,160 @@ static void ST_drawLevelTitle(void) V_DrawCenteredString(subttlxpos, lvlttly+48, V_ALLOWLOWERCASE, subttl); } -static void ST_drawFirstPersonHUD(void) +static void ST_drawPowerupHUD(void) { - player_t *player = stplyr; patch_t *p = NULL; UINT16 invulntime = 0; + INT32 offs = hudinfo[HUD_POWERUPS].x; + static INT32 flagoffs = 0, shieldoffs = 0; +#define ICONSEP (16+4) // matches weapon rings HUD - if (player->playerstate != PST_LIVE) + if (stplyr->spectator || stplyr->playerstate != PST_LIVE) return; // Graue 06-18-2004: no V_NOSCALESTART, no SCX, no SCY, snap to right - if ((player->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE) + if (stplyr->powers[pw_shield] & SH_NOSTACK) { - UINT8 i, max = (player->powers[pw_shield] & SH_FORCEHP); - for (i = 0; i <= max; i++) + shieldoffs = ICONSEP; + + if ((stplyr->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE) { - V_DrawScaledPatch(304-(3*i), 24+(3*i), (V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF), forceshield); + UINT8 i, max = (stplyr->powers[pw_shield] & SH_FORCEHP); + for (i = 0; i <= max; i++) + { + V_DrawSmallScaledPatch(offs-(i<<1), hudinfo[HUD_POWERUPS].y-(i<<1), (V_PERPLAYER|hudinfo[HUD_POWERUPS].f)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF), forceshield); + } + } + else + { + switch (stplyr->powers[pw_shield] & SH_NOSTACK) + { + case SH_WHIRLWIND: p = jumpshield; break; + case SH_ELEMENTAL: p = watershield; break; + case SH_ARMAGEDDON: p = bombshield; break; + case SH_ATTRACT: p = ringshield; break; + case SH_PITY: p = pityshield; break; + case SH_FLAMEAURA: p = flameshield; break; + case SH_BUBBLEWRAP: p = bubbleshield; break; + case SH_THUNDERCOIN: p = thundershield; break; + default: break; + } + + if (p) + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); } } - else switch (player->powers[pw_shield] & SH_NOSTACK) + else if (shieldoffs) { - case SH_WHIRLWIND: p = jumpshield; break; - case SH_ELEMENTAL: p = watershield; break; - case SH_ARMAGEDDON: p = bombshield; break; - case SH_ATTRACT: p = ringshield; break; - case SH_PITY: p = pityshield; break; - case SH_FLAMEAURA: p = flameshield; break; - case SH_BUBBLEWRAP: p = bubbleshield; break; - case SH_THUNDERCOIN: p = thundershield; break; - default: break; - } - - if (p) - V_DrawScaledPatch(304, 24, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - - // pw_flashing just sets the icon to flash no matter what. - invulntime = player->powers[pw_flashing] ? 1 : player->powers[pw_invulnerability]; - if (invulntime > 3*TICRATE || (invulntime && leveltime & 1)) - V_DrawScaledPatch(304, 24 + 28, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); - - if (player->powers[pw_sneakers] > 3*TICRATE || (player->powers[pw_sneakers] && leveltime & 1)) - { - V_DrawScaledPatch(304, 24 + 56, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); - } - - p = NULL; - - { - UINT32 airtime; - UINT32 frame = 0; - spriteframe_t *sprframe; - // If both air timers are active, use the air timer with the least time left - if (player->powers[pw_underwater] && player->powers[pw_spacetime]) - airtime = min(player->powers[pw_underwater], player->powers[pw_spacetime]); - else // Use whichever one is active otherwise - airtime = (player->powers[pw_spacetime]) ? player->powers[pw_spacetime] : player->powers[pw_underwater]; - - if (!airtime) - return; // No air timers are active, nothing would be drawn anyway - - airtime--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity - - if (airtime > 11*TICRATE) - return; // Not time to draw any drown numbers yet - // Choose which frame to use based on time left - if (airtime <= 11*TICRATE && airtime >= 10*TICRATE) - frame = 5; - else if (airtime <= 9*TICRATE && airtime >= 8*TICRATE) - frame = 4; - else if (airtime <= 7*TICRATE && airtime >= 6*TICRATE) - frame = 3; - else if (airtime <= 5*TICRATE && airtime >= 4*TICRATE) - frame = 2; - else if (airtime <= 3*TICRATE && airtime >= 2*TICRATE) - frame = 1; - else if (airtime <= 1*TICRATE && airtime > 0) - frame = 0; + if (shieldoffs > 1) + shieldoffs = 2*shieldoffs/3; else - return; // Don't draw anything between numbers - - if (player->charflags & SF_MACHINE) - frame += 6; // Robots use different drown numbers - - // Get the front angle patch for the frame - sprframe = &sprites[SPR_DRWN].spriteframes[frame]; - p = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + shieldoffs = 0; } + offs -= shieldoffs; + + // YOU have a flag. Display a monitor-like icon for it. + if (stplyr->gotflag) + { + flagoffs = ICONSEP; + p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); + } + else if (flagoffs) + { + if (flagoffs > 1) + flagoffs = 2*flagoffs/3; + else + flagoffs = 0; + } + + offs -= flagoffs; + + invulntime = stplyr->powers[pw_flashing] ? stplyr->powers[pw_flashing] : stplyr->powers[pw_invulnerability]; + if (stplyr->powers[pw_invulnerability] > 3*TICRATE || (invulntime && leveltime & 1)) + { + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, invincibility); + V_DrawRightAlignedThinString(offs + 16, hudinfo[HUD_POWERUPS].y + 8, V_PERPLAYER|hudinfo[HUD_POWERUPS].f, va("%d", invulntime/TICRATE)); + } + + if (invulntime > 7) + offs -= ICONSEP; + else + { + UINT8 a = ICONSEP, b = 7-invulntime; + while (b--) + a = 2*a/3; + offs -= a; + } + + if (stplyr->powers[pw_sneakers] > 3*TICRATE || (stplyr->powers[pw_sneakers] && leveltime & 1)) + { + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, sneakers); + V_DrawRightAlignedThinString(offs + 16, hudinfo[HUD_POWERUPS].y + 8, V_PERPLAYER|hudinfo[HUD_POWERUPS].f, va("%d", stplyr->powers[pw_sneakers]/TICRATE)); + } + + if (stplyr->powers[pw_sneakers] > 7) + offs -= ICONSEP; + else + { + UINT8 a = ICONSEP, b = 7-stplyr->powers[pw_sneakers]; + while (b--) + a = 2*a/3; + offs -= a; + } + + if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) + { + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, gravboots); + V_DrawRightAlignedThinString(offs + 16, hudinfo[HUD_POWERUPS].y + 8, V_PERPLAYER|hudinfo[HUD_POWERUPS].f, va("%d", stplyr->powers[pw_gravityboots]/TICRATE)); + } + +#undef ICONSEP +} + +static void ST_drawFirstPersonHUD(void) +{ + patch_t *p = NULL; + UINT32 airtime; + UINT32 frame = 0; + spriteframe_t *sprframe; + // If both air timers are active, use the air timer with the least time left + if (stplyr->powers[pw_underwater] && stplyr->powers[pw_spacetime]) + airtime = min(stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime]); + else // Use whichever one is active otherwise + airtime = (stplyr->powers[pw_spacetime]) ? stplyr->powers[pw_spacetime] : stplyr->powers[pw_underwater]; + + if (!airtime) + return; // No air timers are active, nothing would be drawn anyway + + airtime--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity + + if (airtime > 11*TICRATE) + return; // Not time to draw any drown numbers yet + // Choose which frame to use based on time left + if (airtime <= 11*TICRATE && airtime >= 10*TICRATE) + frame = 5; + else if (airtime <= 9*TICRATE && airtime >= 8*TICRATE) + frame = 4; + else if (airtime <= 7*TICRATE && airtime >= 6*TICRATE) + frame = 3; + else if (airtime <= 5*TICRATE && airtime >= 4*TICRATE) + frame = 2; + else if (airtime <= 3*TICRATE && airtime >= 2*TICRATE) + frame = 1; + else if (airtime <= 1*TICRATE && airtime > 0) + frame = 0; + else + return; // Don't draw anything between numbers + + if (stplyr->charflags & SF_MACHINE) + frame += 6; // Robots use different drown numbers + + // Get the front angle patch for the frame + sprframe = &sprites[SPR_DRWN].spriteframes[frame]; + p = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + // Display the countdown drown numbers! if (p) V_DrawScaledPatch((BASEVIDWIDTH/2) - (SHORT(p->width)/2) + SHORT(p->leftoffset), 60 - SHORT(p->topoffset), @@ -1674,7 +1743,7 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I if (weapon == pw_infinityring || (stplyr->ringweapons & rwflag)) - txtflags |= V_20TRANS; + ; //txtflags |= V_20TRANS; else { txtflags |= V_TRANSLUCENT; @@ -1683,10 +1752,10 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|patflags, pat); - if (stplyr->powers[weapon] > 99) - V_DrawThinString(8 + xoffs + 1, y, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); - else - V_DrawString(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); + //if (stplyr->powers[weapon] > 9) + V_DrawRightAlignedThinString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); + /*else + V_DrawRightAlignedString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon]));*/ if (stplyr->currentweapon == wepflag) V_DrawScaledPatch(6 + xoffs, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); @@ -1756,57 +1825,67 @@ static void ST_drawTagHUD(void) { sprintf(pstext, "%s", M_GetText("You cannot move while hiding.")); if (!splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); + V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); } // Print the stuff. if (pstext[0]) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER, pstext); + V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, pstext); } -static void ST_drawCTFHUD(void) +static void ST_drawTeamHUD(void) { - INT32 i, y = 176; - UINT16 whichflag = 0; + patch_t *p; +#define SEP 20 - // Draw the flags - V_DrawSmallScaledPatch(256, y, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, rflagico); - V_DrawSmallScaledPatch(280, y, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, bflagico); + if (gametype == GT_CTF) + p = bflagico; + else + p = bmatcico; - for (i = 0; i < MAXPLAYERS; i++) + V_DrawSmallScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); + + if (gametype == GT_CTF) + p = rflagico; + else + p = rmatcico; + + V_DrawSmallScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); + + if (gametype != GT_CTF) + goto num; { - if (players[i].gotflag & GF_REDFLAG) // Red flag isn't at base - V_DrawScaledPatch(256, y-4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, nonicon); - else if (players[i].gotflag & GF_BLUEFLAG) // Blue flag isn't at base - V_DrawScaledPatch(280, y-4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, nonicon); + INT32 i; + UINT16 whichflag = 0; - whichflag |= players[i].gotflag; - if ((whichflag & (GF_REDFLAG|GF_BLUEFLAG)) == (GF_REDFLAG|GF_BLUEFLAG)) - break; // both flags were found, let's stop early - } - - // YOU have a flag. Display a monitor-like icon for it. - if (stplyr->gotflag) - { - patch_t *p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; - V_DrawScaledPatch(304, 24 + 84, V_PERPLAYER|V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); - } - - // Display a countdown timer showing how much time left until the flag your team dropped returns to base. - { - char timeleft[33]; - if (redflag && redflag->fuse > 1) + // Show which flags aren't at base. + for (i = 0; i < MAXPLAYERS; i++) { - sprintf(timeleft, "%u", (redflag->fuse / TICRATE)); - V_DrawCenteredString(268, y+8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, timeleft); + if (players[i].gotflag & GF_BLUEFLAG) // Blue flag isn't at base + V_DrawScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(nonicon->width)/2, 0, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, nonicon); + if (players[i].gotflag & GF_REDFLAG) // Red flag isn't at base + V_DrawScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(nonicon2->width)/2, 0, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, nonicon2); + + whichflag |= players[i].gotflag; + if ((whichflag & (GF_REDFLAG|GF_BLUEFLAG)) == (GF_REDFLAG|GF_BLUEFLAG)) + break; // both flags were found, let's stop early } - if (blueflag && blueflag->fuse > 1) + // Display a countdown timer showing how much time left until the flag returns to base. { - sprintf(timeleft, "%u", (blueflag->fuse / TICRATE)); - V_DrawCenteredString(300, y+8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, timeleft); + if (blueflag && blueflag->fuse > 1) + V_DrawCenteredString(BASEVIDWIDTH/2 - SEP, 8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", (blueflag->fuse / TICRATE))); + + if (redflag && redflag->fuse > 1) + V_DrawCenteredString(BASEVIDWIDTH/2 + SEP, 8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", (redflag->fuse / TICRATE))); } } + +num: + V_DrawCenteredString(BASEVIDWIDTH/2 - SEP, 16, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", bluescore)); + V_DrawCenteredString(BASEVIDWIDTH/2 + SEP, 16, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", redscore)); + +#undef SEP } static void ST_drawSpecialStageHUD(void) @@ -1815,7 +1894,7 @@ static void ST_drawSpecialStageHUD(void) { if (hudinfo[HUD_SS_TOTALRINGS].x) ST_DrawNumFromHud(HUD_SS_TOTALRINGS, totalrings, V_HUDTRANS); - else if (cv_timetic.value == 3) + else if (cv_timetic.value == 2) V_DrawTallNum(hudinfo[HUD_RINGSNUMTICS].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUMTICS].f|V_PERPLAYER|V_HUDTRANS, totalrings); else V_DrawTallNum(hudinfo[HUD_RINGSNUM].x, hudinfo[HUD_SS_TOTALRINGS].y, hudinfo[HUD_RINGSNUM].f|V_PERPLAYER|V_HUDTRANS, totalrings); @@ -2035,6 +2114,8 @@ static void ST_overlayDrawer(void) V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, BASEVIDHEIGHT/2 - (SHORT(p->height)/2), V_PERPLAYER|(stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p); } + if (G_GametypeHasTeams()) + ST_drawTeamHUD(); if (!hu_showscores) // hide the following if TAB is held { @@ -2079,9 +2160,6 @@ static void ST_overlayDrawer(void) // Tag HUD Stuff else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) ST_drawTagHUD(); - // CTF HUD Stuff - else if (gametype == GT_CTF) - ST_drawCTFHUD(); // Special Stage HUD if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer]) @@ -2093,9 +2171,6 @@ static void ST_overlayDrawer(void) else ST_doHuntIconsAndSound(); - if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) - V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, hudinfo[HUD_GRAVBOOTSICO].y, hudinfo[HUD_GRAVBOOTSICO].f|V_PERPLAYER, gravboots); - if(!P_IsLocalPlayer(stplyr)) { char name[MAXPLAYERNAME+1]; @@ -2109,10 +2184,14 @@ static void ST_overlayDrawer(void) // This is where we draw all the fun cheese if you have the chasecam off! if ((stplyr == &players[displayplayer] && !camera.chase) - || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)) + || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)) { ST_drawFirstPersonHUD(); + if (cv_powerupdisplay.value) + ST_drawPowerupHUD(); } + else if (cv_powerupdisplay.value == 2) + ST_drawPowerupHUD(); } #ifdef HAVE_BLUA @@ -2149,27 +2228,30 @@ static void ST_overlayDrawer(void) if (cv_playersforexit.value != 4) { total *= cv_playersforexit.value; - if (total % 4) total += 4; // round up + if (total & 3) + total += 4; // round up total /= 4; } if (exiting < total) { total -= exiting; - V_DrawCenteredString(BASEVIDWIDTH/2, 124, V_PERPLAYER, va(M_GetText("%d more player%s required to exit."), total, ((total == 1) ? "" : "s"))); + V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s"))); if (!splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); + { + V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); + } } } else if (!splitscreen && gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, 0, M_GetText("Press F12 to watch another player.")); + V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; if (respawntime > 0 && !stplyr->spectator) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, va(M_GetText("Respawn in %d..."), respawntime)); + V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, va(M_GetText("Respawn in %d..."), respawntime)); else - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); + V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""JUMP:""\x80 Respawn")); } else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE) #ifdef HAVE_BLUA @@ -2177,14 +2259,13 @@ static void ST_overlayDrawer(void) #endif ) { - V_DrawCenteredString(BASEVIDWIDTH/2, 60, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You are a spectator.")); - if (G_GametypeHasTeams()) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); - else if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You cannot play until the stage has ended.")); - else if (gametype == GT_COOP && stplyr->lives <= 0) + INT32 y = 176 - 16; // HUD_LIVES + if (G_IsSpecialStage(gamemap) && useNightsSS) + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("Wait for the stage to end...")); + else if (gametype == GT_COOP) { - if (cv_cooplives.value == 2 + if (stplyr->lives <= 0 + && cv_cooplives.value == 2 && (netgame || multiplayer)) { INT32 i; @@ -2201,14 +2282,26 @@ static void ST_overlayDrawer(void) } if (i != MAXPLAYERS) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("You'll steal a life on respawn.")); + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("You'll steal a life on respawn...")); + else + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Wait to respawn...")); } + else + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Wait to respawn...")); } - else if (gametype != GT_COOP) - V_DrawCenteredString(BASEVIDWIDTH/2, 164, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); + else + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""FIRE:""\x80 Enter game")); + y -= 8; + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""SPIN:""\x80 Sink")); + y -= 8; + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""JUMP:""\x80 Float")); + y -= 8; if (!splitscreen) - V_DrawCenteredString(BASEVIDWIDTH/2, 132, V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); - V_DrawCenteredString(BASEVIDWIDTH/2, 148, V_PERPLAYER|V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); + { + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); + y -= 8; + } + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_GRAYMAP, M_GetText("Spectator mode:")); } } @@ -2252,6 +2345,24 @@ void ST_Drawer(void) #endif if (rendermode != render_none) ST_doPaletteStuff(); + // Blindfold! + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + && (leveltime < hidetime * TICRATE)) + { + if (players[displayplayer].pflags & PF_TAGIT) + { + stplyr = &players[displayplayer]; + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); + V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("You are blindfolded!")); + } + else if (splitscreen && players[secondarydisplayplayer].pflags & PF_TAGIT) + { + stplyr = &players[secondarydisplayplayer]; + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); + V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("You are blindfolded!")); + } + } + if (st_overlay) { // No deadview! diff --git a/src/st_stuff.h b/src/st_stuff.h index df1ac6433..df0adace3 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -101,7 +101,7 @@ typedef enum HUD_TIMELEFTNUM, HUD_TIMEUP, HUD_HUNTPICS, - HUD_GRAVBOOTSICO, + HUD_POWERUPS, NUMHUDITEMS } hudnum_t; From fc3e863fd3a371df6c21fcc222a656780df5bab0 Mon Sep 17 00:00:00 2001 From: Nevur Date: Thu, 29 Mar 2018 20:12:19 +0200 Subject: [PATCH 48/66] asdf Signed-off-by: Nevur --- src/p_slopes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index f480b6e4f..7c84a2db5 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -251,7 +251,7 @@ void P_SpawnSlope_Line(int linenum) UINT8 flags = 0; // Slope flags if (line->flags & ML_NOSONIC) flags |= SL_NOPHYSICS; - if (line->flags & ML_NOTAILS) + if (!(line->flags & ML_NOTAILS)) flags |= SL_NODYNAMIC; if (line->flags & ML_NOKNUX) flags |= SL_ANCHORVERTEX; From 65c893da86e23bc3c75aeb16a4d4ec1cdebdc79d Mon Sep 17 00:00:00 2001 From: Sryder Date: Thu, 29 Mar 2018 23:28:54 +0100 Subject: [PATCH 49/66] 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 de8f1fa407beede452ad5d391f92a288c4b70cc3 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 30 Mar 2018 16:39:59 +0100 Subject: [PATCH 50/66] * Incorporate (almost) all of Mystic's feedback. * Prevent ANY input when blindfolded. * Make CECHOs always perplayer'd. (A little hacky; quads will need work here.) * Make NiGHTS link timer bounces not a mess, and only when the colour changes. --- src/g_game.c | 4 +- src/hu_stuff.c | 8 +- src/p_user.c | 2 +- src/st_stuff.c | 484 ++++++++++++++++++++++++++----------------------- 4 files changed, 264 insertions(+), 234 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 9db9c413b..984b1ec40 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -888,7 +888,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // why build a ticcmd if we're paused? // Or, for that matter, if we're being reborn. - if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN)) + // ...OR if we're blindfolded. No looking into the floor. + if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + && (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT))))) { cmd->angleturn = (INT16)(localangle >> 16); cmd->aiming = G_ClipAimingPitch(&localaiming); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index c955a490d..a13801388 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -947,7 +947,7 @@ static void HU_DrawCEcho(void) INT32 y = (BASEVIDHEIGHT/2)-4; INT32 pnumlines = 0; - UINT32 realflags = cechoflags; + UINT32 realflags = cechoflags|V_PERPLAYER; // requested as part of splitscreen's stuff INT32 realalpha = (INT32)((cechoflags & V_ALPHAMASK) >> V_ALPHASHIFT); char *line; @@ -990,6 +990,12 @@ static void HU_DrawCEcho(void) *line = '\0'; V_DrawCenteredString(BASEVIDWIDTH/2, y, realflags, echoptr); + if (splitscreen) + { + stplyr = ((stplyr == &players[displayplayer]) ? &players[secondarydisplayplayer] : &players[displayplayer]); + V_DrawCenteredString(BASEVIDWIDTH/2, y, realflags, echoptr); + stplyr = ((stplyr == &players[displayplayer]) ? &players[secondarydisplayplayer] : &players[displayplayer]); + } y += ((realflags & V_RETURN8) ? 8 : 12); echoptr = line; diff --git a/src/p_user.c b/src/p_user.c index 86eb1bef4..b8634afa8 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9709,7 +9709,7 @@ void P_PlayerThink(player_t *player) } } - if (player->linktimer && (player->linktimer >= (2*TICRATE - 1) || !player->powers[pw_nights_linkfreeze])) + if (player->linktimer && !player->powers[pw_nights_linkfreeze]) { if (--player->linktimer <= 0) // Link timer player->linkcount = 0; diff --git a/src/st_stuff.c b/src/st_stuff.c index 25a61fa3a..3ae212bc1 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -737,14 +737,19 @@ static void ST_drawLivesArea(void) } // Lives number - if (G_GametypeUsesLives()) + if (G_GametypeUsesLives() || gametype == GT_RACE) { // x V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); // lives number - if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) + if (gametype == GT_RACE) + { + livescount = 0x7f; + notgreyedout = true; + } + else if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) { INT32 i; livescount = 0; @@ -788,58 +793,30 @@ static void ST_drawLivesArea(void) } // Spectator else if (stplyr->spectator) - { - //V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "SPECTATOR"); v_colmap = V_GRAYMAP; - } // Tag else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) { if (stplyr->pflags & PF_TAGIT) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, (gametype == GT_HIDEANDSEEK) ? "SEEKER" : "IT!"); + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "IT!"); v_colmap = V_ORANGEMAP; } - else if (stplyr->pflags & PF_GAMETYPEOVER) - { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANSHALF|hudinfo[HUD_LIVES].f|V_PERPLAYER, "FAILED"); - v_colmap = V_GRAYMAP; - } - else - { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, (gametype == GT_HIDEANDSEEK) ? "HIDER" : "RUNNER"); - v_colmap = V_GREENMAP; - } } // Team name else if (G_GametypeHasTeams()) { if (stplyr->ctfteam == 1) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED"); + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED"); v_colmap = V_REDMAP; } else if (stplyr->ctfteam == 2) { - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE"); + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE"); v_colmap = V_BLUEMAP; } - else - v_colmap = V_GRAYMAP; } - else if (circuitmap) - { - if (stplyr->exiting) - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "FINISHED"); - //V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f|V_YELLOWMAP, "FINISHED!"); - else - { - V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, va("%u/%d", stplyr->laps+1, cv_numlaps.value)); - //V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value)); - } - } - /*else - V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "PLAYING");*/ // name v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); @@ -1074,13 +1051,8 @@ static void ST_drawLevelTitle(void) char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *subttl = mapheaderinfo[gamemap-1]->subttl; INT32 actnum = mapheaderinfo[gamemap-1]->actnum; - INT32 lvlttlxpos; + INT32 lvlttly, zoney, lvlttlxpos, ttlnumxpos, zonexpos; INT32 subttlxpos = BASEVIDWIDTH/2; - INT32 ttlnumxpos; - INT32 zonexpos; - - INT32 lvlttly; - INT32 zoney; if (!(timeinmap > 2 && timeinmap-3 < 110)) return; @@ -1095,10 +1067,41 @@ static void ST_drawLevelTitle(void) ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl); zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("ZONE")); + ttlnumxpos++; if (lvlttlxpos < 0) lvlttlxpos = 0; +#if 0 // toaster's experiment. srb2&toast.exe one day, maybe? Requires stuff below to be converted to fixed point. +#define MIDTTLY 79 +#define MIDZONEY 105 +#define MIDDIFF 4 + + if (timeinmap < 10) + { + fixed_t z = ((timeinmap - 3)<levelflags & LF_NOZONE)) - V_DrawLevelTitle(zonexpos, zoney, 0, M_GetText("ZONE")); + V_DrawLevelTitle(zonexpos, zoney, V_PERPLAYER, M_GetText("ZONE")); if (lvlttly+48 < 200) - V_DrawCenteredString(subttlxpos, lvlttly+48, V_ALLOWLOWERCASE, subttl); + V_DrawCenteredString(subttlxpos, lvlttly+48, V_PERPLAYER|V_ALLOWLOWERCASE, subttl); } static void ST_drawPowerupHUD(void) @@ -1135,7 +1139,8 @@ static void ST_drawPowerupHUD(void) patch_t *p = NULL; UINT16 invulntime = 0; INT32 offs = hudinfo[HUD_POWERUPS].x; - static INT32 flagoffs = 0, shieldoffs = 0; + const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); + static INT32 flagoffs[2] = {0, 0}, shieldoffs[2] = {0, 0}; #define ICONSEP (16+4) // matches weapon rings HUD if (stplyr->spectator || stplyr->playerstate != PST_LIVE) @@ -1144,7 +1149,7 @@ static void ST_drawPowerupHUD(void) // Graue 06-18-2004: no V_NOSCALESTART, no SCX, no SCY, snap to right if (stplyr->powers[pw_shield] & SH_NOSTACK) { - shieldoffs = ICONSEP; + shieldoffs[q] = ICONSEP; if ((stplyr->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE) { @@ -1173,32 +1178,32 @@ static void ST_drawPowerupHUD(void) V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); } } - else if (shieldoffs) + else if (shieldoffs[q]) { - if (shieldoffs > 1) - shieldoffs = 2*shieldoffs/3; + if (shieldoffs[q] > 1) + shieldoffs[q] = 2*shieldoffs[q]/3; else - shieldoffs = 0; + shieldoffs[q] = 0; } - offs -= shieldoffs; + offs -= shieldoffs[q]; // YOU have a flag. Display a monitor-like icon for it. if (stplyr->gotflag) { - flagoffs = ICONSEP; + flagoffs[q] = ICONSEP; p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); } - else if (flagoffs) + else if (flagoffs[q]) { - if (flagoffs > 1) - flagoffs = 2*flagoffs/3; + if (flagoffs[q] > 1) + flagoffs[q] = 2*flagoffs[q]/3; else - flagoffs = 0; + flagoffs[q] = 0; } - offs -= flagoffs; + offs -= flagoffs[q]; invulntime = stplyr->powers[pw_flashing] ? stplyr->powers[pw_flashing] : stplyr->powers[pw_invulnerability]; if (stplyr->powers[pw_invulnerability] > 3*TICRATE || (invulntime && leveltime & 1)) @@ -1394,7 +1399,6 @@ static void ST_drawNiGHTSHUD(void) INT32 origamount; INT32 minlink = 1; INT32 total_ringcount; - boolean nosshack = false; // When debugging, show "0 Link". if (cv_debug & DBG_NIGHTSBASIC) @@ -1411,21 +1415,10 @@ static void ST_drawNiGHTSHUD(void) #endif stplyr->powers[pw_carry] == CR_NIGHTSMODE) { - INT32 locx, locy; + INT32 locx = 16, locy = 180; INT32 dfill; UINT8 fillpatch; - if (splitscreen) - { - locx = 110; - locy = 188; - } - else - { - locx = 16; - locy = 180; - } - // Use which patch? if (stplyr->pflags & PF_DRILLING) fillpatch = (stplyr->drillmeter & 1) + 1; @@ -1446,14 +1439,17 @@ static void ST_drawNiGHTSHUD(void) } } - if (G_IsSpecialStage(gamemap)) + /*if (G_IsSpecialStage(gamemap)) { // Since special stages share score, time, rings, etc. // disable splitscreen mode for its HUD. + // -------------------------------------- + // NOPE! Consistency between different splitscreen stuffs + // now we've got the screen squashing instead. ~toast if (stplyr != &players[displayplayer]) return; nosshack = splitscreen; splitscreen = false; - } + }*/ // Link drawing if ( @@ -1462,42 +1458,39 @@ static void ST_drawNiGHTSHUD(void) #endif stplyr->linkcount > minlink) { + static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0}; + const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); + INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? 1 : 0); skincolors_t colornum; - INT32 aflag = V_PERPLAYER; fixed_t x, y, scale; + if (sel != prevsel[q]) + { + prevsel[q] = sel; + prevtime[q] = 2 + mag; + } + if (stplyr->powers[pw_nights_linkfreeze] && (!(stplyr->powers[pw_nights_linkfreeze] & 2) || (stplyr->powers[pw_nights_linkfreeze] > flashingtics))) colornum = SKINCOLOR_ICY; else - colornum = linkColor[((stplyr->linkcount-1 >= 300) ? 1 : 0)][((stplyr->linkcount-1) / 5) % NUMLINKCOLORS]; + colornum = linkColor[mag][sel]; aflag |= ((stplyr->linktimer < 2*TICRATE/3) ? (9 - 9*stplyr->linktimer/(2*TICRATE/3)) << V_ALPHASHIFT : 0); - y = (nosshack ? 16+11+(BASEVIDHEIGHT/2) : 160+11)<linktimer) - { - case (2*TICRATE): - scale = (36*FRACUNIT)/32; - break; - case (2*TICRATE - 1): - scale = (34*FRACUNIT)/32; - break; - default: - scale = FRACUNIT; - break; - } + scale = FRACUNIT; y -= (11*scale); @@ -1619,7 +1612,7 @@ static void ST_drawNiGHTSHUD(void) && LUA_HudEnabled(hud_nightsscore) #endif ) - ST_DrawNightsOverlayNum(304<marescore, nightsnum, SKINCOLOR_AZURE); + ST_DrawNightsOverlayNum(304<marescore, nightsnum, SKINCOLOR_AZURE); if (!stplyr->exiting #ifdef HAVE_BLUA @@ -1687,7 +1680,7 @@ static void ST_drawNiGHTSHUD(void) else numbersize = 48/2; - ST_DrawNightsOverlayNum((160 + numbersize)<weapondelay, del = 0, p = 16; + while (q) + { + if (q > p) + { + del += p; + q -= p; + q /= 2; + if (p > 1) + p /= 2; + } + else + { + del += q; + break; + } + } + V_DrawScaledPatch(6 + xoffs, y-2 - del/2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); } static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, INT32 xoffs, INT32 y, patch_t *pat) @@ -1751,14 +1763,10 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I } V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|patflags, pat); - - //if (stplyr->powers[weapon] > 9) - V_DrawRightAlignedThinString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); - /*else - V_DrawRightAlignedString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon]));*/ + V_DrawRightAlignedThinString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon])); if (stplyr->currentweapon == wepflag) - V_DrawScaledPatch(6 + xoffs, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); + ST_drawWeaponSelect(xoffs, y); } else if (stplyr->ringweapons & rwflag) V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_TRANSLUCENT, pat); @@ -1778,13 +1786,16 @@ static void ST_drawMatchHUD(void) { if (stplyr->powers[pw_infinityring]) ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring); - else if (stplyr->rings > 0) - V_DrawScaledPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM, normring); else - V_DrawTranslucentPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_80TRANS, normring); + { + if (stplyr->rings > 0) + V_DrawScaledPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM, normring); + else + V_DrawTranslucentPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_80TRANS, normring); - if (!stplyr->currentweapon) - V_DrawScaledPatch(6 + offset, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); + if (!stplyr->currentweapon) + ST_drawWeaponSelect(offset, y); + } offset += 20; ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring); @@ -1801,38 +1812,145 @@ static void ST_drawMatchHUD(void) } } +static void ST_drawTextHUD(void) +{ + INT32 y = 176 - 16; // HUD_LIVES + boolean dof12 = false, dospecheader = false; + +#define textHUDdraw(str) \ +{\ + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, str);\ + y -= 8;\ +} + + if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) + { + if (leveltime < hidetime * TICRATE) + { + if (stplyr->pflags & PF_TAGIT) + { + textHUDdraw(M_GetText("Waiting for players to hide...")) + textHUDdraw(M_GetText("\x82""You are blindfolded!")) + } + else if (gametype == GT_HIDEANDSEEK) + textHUDdraw(M_GetText("Hide before time runs out!")) + else + textHUDdraw(M_GetText("Flee before you are hunted!")) + } + else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) + { + textHUDdraw(M_GetText("You cannot move while hiding.")) + dof12 = true; + } + } + + if (!stplyr->spectator && stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP) + { + INT32 i, total = 0, exiting = 0; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + if (players[i].lives <= 0) + continue; + + total++; + if (players[i].exiting) + exiting++; + } + + if (cv_playersforexit.value != 4) + { + total *= cv_playersforexit.value; + if (total & 3) + total += 4; // round up + total /= 4; + } + + if (exiting < total) + { + total -= exiting; + textHUDdraw(va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s"))) + dof12 = true; + } + } + else if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) + dof12 = true; + else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. + { + INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; + + if (respawntime > 0 && !stplyr->spectator) + textHUDdraw(va(M_GetText("Respawn in %d..."), respawntime)) + else + textHUDdraw(M_GetText("\x82""JUMP:""\x80 Respawn")) + } + else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE)) + { + if (G_IsSpecialStage(gamemap) && useNightsSS) + textHUDdraw(M_GetText("\x82""Wait for the stage to end...")) + else if (gametype == GT_COOP) + { + if (stplyr->lives <= 0 + && cv_cooplives.value == 2 + && (netgame || multiplayer)) + { + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (&players[i] == stplyr) + continue; + + if (players[i].lives > 1) + break; + } + + if (i != MAXPLAYERS) + textHUDdraw(M_GetText("You'll steal a life on respawn...")) + else + textHUDdraw(M_GetText("Wait to respawn...")) + } + else + textHUDdraw(M_GetText("Wait to respawn...")) + } + else + textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game")) + + textHUDdraw(M_GetText("\x82""SPIN:""\x80 Sink")) + textHUDdraw(M_GetText("\x82""JUMP:""\x80 Float")) + + dof12 = true; + dospecheader = true; + } + + if (!splitscreen && dof12) + textHUDdraw(M_GetText("\x82""F12:""\x80 Switch view")) + + if (circuitmap) + { + if (stplyr->exiting) + textHUDdraw(M_GetText("\x82""FINISHED!")) + else + textHUDdraw(va("Lap:""\x82 %u/%d", stplyr->laps+1, cv_numlaps.value)) + } + + if (dospecheader) + textHUDdraw(M_GetText("\x86""Spectator mode:")) + +#undef textHUDdraw + +} + static inline void ST_drawRaceHUD(void) { if (leveltime > TICRATE && leveltime <= 5*TICRATE) ST_drawRaceNum(4*TICRATE - leveltime); } -static void ST_drawTagHUD(void) -{ - char pstext[33] = ""; - - // Figure out what we're going to print. - if (leveltime < hidetime * TICRATE) //during the hide time, the seeker and hiders have different messages on their HUD. - { - if (stplyr->pflags & PF_TAGIT) - sprintf(pstext, "%s", M_GetText("Waiting for players to hide...")); - else if (gametype == GT_HIDEANDSEEK) //hide and seek. - sprintf(pstext, "%s", M_GetText("Hide before time runs out!")); - else //default - sprintf(pstext, "%s", M_GetText("Flee before you are hunted!")); - } - else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) - { - sprintf(pstext, "%s", M_GetText("You cannot move while hiding.")); - if (!splitscreen) - V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); - } - - // Print the stuff. - if (pstext[0]) - V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, pstext); -} - static void ST_drawTeamHUD(void) { patch_t *p; @@ -2157,9 +2275,6 @@ static void ST_overlayDrawer(void) // Race HUD Stuff if (gametype == GT_RACE || gametype == GT_COMPETITION) ST_drawRaceHUD(); - // Tag HUD Stuff - else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) - ST_drawTagHUD(); // Special Stage HUD if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer]) @@ -2207,103 +2322,12 @@ static void ST_overlayDrawer(void) ) ST_drawLevelTitle(); - if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer) - { - if (!stplyr->spectator && stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP) - { - INT32 i, total = 0, exiting = 0; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - if (players[i].lives <= 0) - continue; - - total++; - if (players[i].exiting) - exiting++; - } - - if (cv_playersforexit.value != 4) - { - total *= cv_playersforexit.value; - if (total & 3) - total += 4; // round up - total /= 4; - } - - if (exiting < total) - { - total -= exiting; - V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s"))); - if (!splitscreen) - { - V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); - } - } - } - else if (!splitscreen && gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) - V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); - else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. - { - INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; - if (respawntime > 0 && !stplyr->spectator) - V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, va(M_GetText("Respawn in %d..."), respawntime)); - else - V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""JUMP:""\x80 Respawn")); - } - else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE) + if (!hu_showscores && (netgame || multiplayer) #ifdef HAVE_BLUA && LUA_HudEnabled(hud_textspectator) #endif - ) - { - INT32 y = 176 - 16; // HUD_LIVES - if (G_IsSpecialStage(gamemap) && useNightsSS) - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("Wait for the stage to end...")); - else if (gametype == GT_COOP) - { - if (stplyr->lives <= 0 - && cv_cooplives.value == 2 - && (netgame || multiplayer)) - { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - if (&players[i] == stplyr) - continue; - - if (players[i].lives > 1) - break; - } - - if (i != MAXPLAYERS) - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("You'll steal a life on respawn...")); - else - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Wait to respawn...")); - } - else - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Wait to respawn...")); - } - else - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""FIRE:""\x80 Enter game")); - y -= 8; - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""SPIN:""\x80 Sink")); - y -= 8; - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""JUMP:""\x80 Float")); - y -= 8; - if (!splitscreen) - { - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view")); - y -= 8; - } - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_GRAYMAP, M_GetText("Spectator mode:")); - } - } + ) + ST_drawTextHUD(); if (modeattacking) ST_drawInput(); @@ -2353,13 +2377,11 @@ void ST_Drawer(void) { stplyr = &players[displayplayer]; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); - V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("You are blindfolded!")); } else if (splitscreen && players[secondarydisplayplayer].pflags & PF_TAGIT) { stplyr = &players[secondarydisplayplayer]; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); - V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("You are blindfolded!")); } } From f3aa02e26dad0ce1178925284f65cc8eb7b6e4f3 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 30 Mar 2018 18:13:52 +0100 Subject: [PATCH 51/66] 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 52/66] 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 d9b5155e6ea4110199a440415cf9f41234b7b07c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 30 Mar 2018 21:49:15 +0100 Subject: [PATCH 53/66] * Make Tokens appear in competition. * Tweak thrown ring colours. * Make Armageddon shield loop properly. * Tweak drowning numbers to be consistent between third and first person. --- src/dehacked.c | 32 +++++++++++++++++ src/g_game.c | 4 +-- src/info.c | 96 +++++++++++++++++++++++++++++++++----------------- src/info.h | 32 +++++++++++++++++ src/p_inter.c | 26 +++++++------- src/p_mobj.c | 2 +- src/p_user.c | 27 +++++++------- src/st_stuff.c | 33 ++++++++--------- 8 files changed, 172 insertions(+), 80 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 3726cb381..a7ba72a6c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5015,6 +5015,22 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARMF14", "S_ARMF15", "S_ARMF16", + "S_ARMF17", + "S_ARMF18", + "S_ARMF19", + "S_ARMF20", + "S_ARMF21", + "S_ARMF22", + "S_ARMF23", + "S_ARMF24", + "S_ARMF25", + "S_ARMF26", + "S_ARMF27", + "S_ARMF28", + "S_ARMF29", + "S_ARMF30", + "S_ARMF31", + "S_ARMF32", "S_ARMB1", "S_ARMB2", @@ -5032,6 +5048,22 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ARMB14", "S_ARMB15", "S_ARMB16", + "S_ARMB17", + "S_ARMB18", + "S_ARMB19", + "S_ARMB20", + "S_ARMB21", + "S_ARMB22", + "S_ARMB23", + "S_ARMB24", + "S_ARMB25", + "S_ARMB26", + "S_ARMB27", + "S_ARMB28", + "S_ARMB29", + "S_ARMB30", + "S_ARMB31", + "S_ARMB32", "S_WIND1", "S_WIND2", diff --git a/src/g_game.c b/src/g_game.c index 984b1ec40..509ccf0ab 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -133,8 +133,8 @@ boolean useNightsSS = false; UINT8 skincolor_redteam = SKINCOLOR_RED; UINT8 skincolor_blueteam = SKINCOLOR_BLUE; -UINT8 skincolor_redring = SKINCOLOR_RED; -UINT8 skincolor_bluering = SKINCOLOR_AZURE; +UINT8 skincolor_redring = SKINCOLOR_SALMON; +UINT8 skincolor_bluering = SKINCOLOR_CORNFLOWER; tic_t countdowntimer = 0; boolean countdowntimeup = false; diff --git a/src/info.c b/src/info.c index 58a2ba8f4..5f46744bd 100644 --- a/src/info.c +++ b/src/info.c @@ -2215,39 +2215,71 @@ state_t states[NUMSTATES] = {SPR_ARMA, FF_TRANS40|14, 2, {NULL}, 0, 0, S_ARMA16}, // S_ARMA15 {SPR_ARMA, FF_TRANS40|15, 2, {NULL}, 0, 0, S_ARMA1 }, // S_ARMA16 - {SPR_ARMF, FF_FULLBRIGHT , 3, {NULL}, 0, 0, S_ARMF2 }, // S_ARMF1 - {SPR_ARMF, FF_FULLBRIGHT| 1, 3, {NULL}, 0, 0, S_ARMF3 }, // S_ARMF2 - {SPR_ARMF, FF_FULLBRIGHT| 2, 3, {NULL}, 0, 0, S_ARMF4 }, // S_ARMF3 - {SPR_ARMF, FF_FULLBRIGHT| 3, 3, {NULL}, 0, 0, S_ARMF5 }, // S_ARMF4 - {SPR_ARMF, FF_FULLBRIGHT| 4, 3, {NULL}, 0, 0, S_ARMF6 }, // S_ARMF5 - {SPR_ARMF, FF_FULLBRIGHT| 5, 3, {NULL}, 0, 0, S_ARMF7 }, // S_ARMF6 - {SPR_ARMF, FF_FULLBRIGHT| 6, 3, {NULL}, 0, 0, S_ARMF8 }, // S_ARMF7 - {SPR_ARMF, FF_FULLBRIGHT| 7, 3, {NULL}, 0, 0, S_ARMF9 }, // S_ARMF8 - {SPR_ARMF, FF_FULLBRIGHT| 8, 3, {NULL}, 0, 0, S_ARMF10}, // S_ARMF9 - {SPR_ARMF, FF_FULLBRIGHT| 9, 3, {NULL}, 0, 0, S_ARMF11}, // S_ARMF10 - {SPR_ARMF, FF_FULLBRIGHT|10, 3, {NULL}, 0, 0, S_ARMF12}, // S_ARMF11 - {SPR_ARMF, FF_FULLBRIGHT|11, 3, {NULL}, 0, 0, S_ARMF13}, // S_ARMF12 - {SPR_ARMF, FF_FULLBRIGHT|12, 3, {NULL}, 0, 0, S_ARMF14}, // S_ARMF13 - {SPR_ARMF, FF_FULLBRIGHT|13, 3, {NULL}, 0, 0, S_ARMF15}, // S_ARMF14 - {SPR_ARMF, FF_FULLBRIGHT|14, 3, {NULL}, 0, 0, S_ARMF16}, // S_ARMF15 - {SPR_ARMF, FF_FULLBRIGHT|15, 3, {NULL}, 0, 0, S_ARMF1 }, // S_ARMF16 + {SPR_ARMF, FF_FULLBRIGHT , 2, {NULL}, 0, 0, S_ARMF2 }, // S_ARMF1 + {SPR_ARMF, FF_FULLBRIGHT| 1, 2, {NULL}, 0, 0, S_ARMF3 }, // S_ARMF2 + {SPR_ARMF, FF_FULLBRIGHT| 2, 2, {NULL}, 0, 0, S_ARMF4 }, // S_ARMF3 + {SPR_ARMF, FF_FULLBRIGHT| 3, 2, {NULL}, 0, 0, S_ARMF5 }, // S_ARMF4 + {SPR_ARMF, FF_FULLBRIGHT| 4, 2, {NULL}, 0, 0, S_ARMF6 }, // S_ARMF5 + {SPR_ARMF, FF_FULLBRIGHT| 5, 2, {NULL}, 0, 0, S_ARMF7 }, // S_ARMF6 + {SPR_ARMF, FF_FULLBRIGHT| 6, 2, {NULL}, 0, 0, S_ARMF8 }, // S_ARMF7 + {SPR_ARMF, FF_FULLBRIGHT| 7, 2, {NULL}, 0, 0, S_ARMF9 }, // S_ARMF8 + {SPR_ARMF, FF_FULLBRIGHT| 8, 2, {NULL}, 0, 0, S_ARMF10}, // S_ARMF9 + {SPR_ARMF, FF_FULLBRIGHT| 9, 2, {NULL}, 0, 0, S_ARMF11}, // S_ARMF10 + {SPR_ARMF, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_ARMF12}, // S_ARMF11 + {SPR_ARMF, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_ARMF13}, // S_ARMF12 + {SPR_ARMF, FF_FULLBRIGHT|12, 2, {NULL}, 0, 0, S_ARMF14}, // S_ARMF13 + {SPR_ARMF, FF_FULLBRIGHT|13, 2, {NULL}, 0, 0, S_ARMF15}, // S_ARMF14 + {SPR_ARMF, FF_FULLBRIGHT|14, 2, {NULL}, 0, 0, S_ARMF16}, // S_ARMF15 + {SPR_ARMF, FF_FULLBRIGHT|15, 2, {NULL}, 0, 0, S_ARMF17}, // S_ARMF16 + {SPR_ARMB, FF_FULLBRIGHT , 2, {NULL}, 0, 0, S_ARMF18}, // S_ARMF17 + {SPR_ARMB, FF_FULLBRIGHT| 1, 2, {NULL}, 0, 0, S_ARMF19}, // S_ARMF18 + {SPR_ARMB, FF_FULLBRIGHT| 2, 2, {NULL}, 0, 0, S_ARMF20}, // S_ARMF19 + {SPR_ARMB, FF_FULLBRIGHT| 3, 2, {NULL}, 0, 0, S_ARMF21}, // S_ARMF20 + {SPR_ARMB, FF_FULLBRIGHT| 4, 2, {NULL}, 0, 0, S_ARMF22}, // S_ARMF21 + {SPR_ARMB, FF_FULLBRIGHT| 5, 2, {NULL}, 0, 0, S_ARMF23}, // S_ARMF22 + {SPR_ARMB, FF_FULLBRIGHT| 6, 2, {NULL}, 0, 0, S_ARMF24}, // S_ARMF23 + {SPR_ARMB, FF_FULLBRIGHT| 7, 2, {NULL}, 0, 0, S_ARMF25}, // S_ARMF24 + {SPR_ARMB, FF_FULLBRIGHT| 8, 2, {NULL}, 0, 0, S_ARMF26}, // S_ARMF25 + {SPR_ARMB, FF_FULLBRIGHT| 9, 2, {NULL}, 0, 0, S_ARMF27}, // S_ARMF26 + {SPR_ARMB, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_ARMF28}, // S_ARMF27 + {SPR_ARMB, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_ARMF29}, // S_ARMF28 + {SPR_ARMB, FF_FULLBRIGHT|12, 2, {NULL}, 0, 0, S_ARMF30}, // S_ARMF29 + {SPR_ARMB, FF_FULLBRIGHT|13, 2, {NULL}, 0, 0, S_ARMF31}, // S_ARMF30 + {SPR_ARMB, FF_FULLBRIGHT|14, 2, {NULL}, 0, 0, S_ARMF32}, // S_ARMF31 + {SPR_ARMB, FF_FULLBRIGHT|15, 2, {NULL}, 0, 0, S_ARMF1 }, // S_ARMF32 - {SPR_ARMB, FF_FULLBRIGHT| 0, 3, {NULL}, 1, 0, S_ARMB2 }, // S_ARMB1 - {SPR_ARMB, FF_FULLBRIGHT| 1, 3, {NULL}, 1, 0, S_ARMB3 }, // S_ARMB2 - {SPR_ARMB, FF_FULLBRIGHT| 2, 3, {NULL}, 1, 0, S_ARMB4 }, // S_ARMB3 - {SPR_ARMB, FF_FULLBRIGHT| 3, 3, {NULL}, 1, 0, S_ARMB5 }, // S_ARMB4 - {SPR_ARMB, FF_FULLBRIGHT| 4, 3, {NULL}, 1, 0, S_ARMB6 }, // S_ARMB5 - {SPR_ARMB, FF_FULLBRIGHT| 5, 3, {NULL}, 1, 0, S_ARMB7 }, // S_ARMB6 - {SPR_ARMB, FF_FULLBRIGHT| 6, 3, {NULL}, 1, 0, S_ARMB8 }, // S_ARMB7 - {SPR_ARMB, FF_FULLBRIGHT| 7, 3, {NULL}, 1, 0, S_ARMB9 }, // S_ARMB8 - {SPR_ARMB, FF_FULLBRIGHT| 8, 3, {NULL}, 1, 0, S_ARMB10}, // S_ARMB9 - {SPR_ARMB, FF_FULLBRIGHT| 9, 3, {NULL}, 1, 0, S_ARMB11}, // S_ARMB10 - {SPR_ARMB, FF_FULLBRIGHT|10, 3, {NULL}, 1, 0, S_ARMB12}, // S_ARMB11 - {SPR_ARMB, FF_FULLBRIGHT|11, 3, {NULL}, 1, 0, S_ARMB13}, // S_ARMB12 - {SPR_ARMB, FF_FULLBRIGHT|12, 3, {NULL}, 1, 0, S_ARMB14}, // S_ARMB13 - {SPR_ARMB, FF_FULLBRIGHT|13, 3, {NULL}, 1, 0, S_ARMB15}, // S_ARMB14 - {SPR_ARMB, FF_FULLBRIGHT|14, 3, {NULL}, 1, 0, S_ARMB16}, // S_ARMB15 - {SPR_ARMB, FF_FULLBRIGHT|15, 3, {NULL}, 1, 0, S_ARMB1 }, // S_ARMB16 + {SPR_ARMB, FF_FULLBRIGHT , 2, {NULL}, 1, 0, S_ARMB2 }, // S_ARMB1 + {SPR_ARMB, FF_FULLBRIGHT| 1, 2, {NULL}, 1, 0, S_ARMB3 }, // S_ARMB2 + {SPR_ARMB, FF_FULLBRIGHT| 2, 2, {NULL}, 1, 0, S_ARMB4 }, // S_ARMB3 + {SPR_ARMB, FF_FULLBRIGHT| 3, 2, {NULL}, 1, 0, S_ARMB5 }, // S_ARMB4 + {SPR_ARMB, FF_FULLBRIGHT| 4, 2, {NULL}, 1, 0, S_ARMB6 }, // S_ARMB5 + {SPR_ARMB, FF_FULLBRIGHT| 5, 2, {NULL}, 1, 0, S_ARMB7 }, // S_ARMB6 + {SPR_ARMB, FF_FULLBRIGHT| 6, 2, {NULL}, 1, 0, S_ARMB8 }, // S_ARMB7 + {SPR_ARMB, FF_FULLBRIGHT| 7, 2, {NULL}, 1, 0, S_ARMB9 }, // S_ARMB8 + {SPR_ARMB, FF_FULLBRIGHT| 8, 2, {NULL}, 1, 0, S_ARMB10}, // S_ARMB9 + {SPR_ARMB, FF_FULLBRIGHT| 9, 2, {NULL}, 1, 0, S_ARMB11}, // S_ARMB10 + {SPR_ARMB, FF_FULLBRIGHT|10, 2, {NULL}, 1, 0, S_ARMB12}, // S_ARMB11 + {SPR_ARMB, FF_FULLBRIGHT|11, 2, {NULL}, 1, 0, S_ARMB13}, // S_ARMB12 + {SPR_ARMB, FF_FULLBRIGHT|12, 2, {NULL}, 1, 0, S_ARMB14}, // S_ARMB13 + {SPR_ARMB, FF_FULLBRIGHT|13, 2, {NULL}, 1, 0, S_ARMB15}, // S_ARMB14 + {SPR_ARMB, FF_FULLBRIGHT|14, 2, {NULL}, 1, 0, S_ARMB16}, // S_ARMB15 + {SPR_ARMB, FF_FULLBRIGHT|15, 2, {NULL}, 1, 0, S_ARMB17}, // S_ARMB16 + {SPR_ARMF, FF_FULLBRIGHT , 2, {NULL}, 1, 0, S_ARMB18}, // S_ARMB17 + {SPR_ARMF, FF_FULLBRIGHT| 1, 2, {NULL}, 1, 0, S_ARMB19}, // S_ARMB18 + {SPR_ARMF, FF_FULLBRIGHT| 2, 2, {NULL}, 1, 0, S_ARMB20}, // S_ARMB19 + {SPR_ARMF, FF_FULLBRIGHT| 3, 2, {NULL}, 1, 0, S_ARMB21}, // S_ARMB20 + {SPR_ARMF, FF_FULLBRIGHT| 4, 2, {NULL}, 1, 0, S_ARMB22}, // S_ARMB21 + {SPR_ARMF, FF_FULLBRIGHT| 5, 2, {NULL}, 1, 0, S_ARMB23}, // S_ARMB22 + {SPR_ARMF, FF_FULLBRIGHT| 6, 2, {NULL}, 1, 0, S_ARMB24}, // S_ARMB23 + {SPR_ARMF, FF_FULLBRIGHT| 7, 2, {NULL}, 1, 0, S_ARMB25}, // S_ARMB24 + {SPR_ARMF, FF_FULLBRIGHT| 8, 2, {NULL}, 1, 0, S_ARMB26}, // S_ARMB25 + {SPR_ARMF, FF_FULLBRIGHT| 9, 2, {NULL}, 1, 0, S_ARMB27}, // S_ARMB26 + {SPR_ARMF, FF_FULLBRIGHT|10, 2, {NULL}, 1, 0, S_ARMB28}, // S_ARMB27 + {SPR_ARMF, FF_FULLBRIGHT|11, 2, {NULL}, 1, 0, S_ARMB29}, // S_ARMB28 + {SPR_ARMF, FF_FULLBRIGHT|12, 2, {NULL}, 1, 0, S_ARMB30}, // S_ARMB29 + {SPR_ARMF, FF_FULLBRIGHT|13, 2, {NULL}, 1, 0, S_ARMB31}, // S_ARMB30 + {SPR_ARMF, FF_FULLBRIGHT|14, 2, {NULL}, 1, 0, S_ARMB32}, // S_ARMB31 + {SPR_ARMF, FF_FULLBRIGHT|15, 2, {NULL}, 1, 0, S_ARMB1 }, // S_ARMB32 {SPR_WIND, FF_TRANS70 , 2, {NULL}, 0, 0, S_WIND2}, // S_WIND1 {SPR_WIND, FF_TRANS70|1, 2, {NULL}, 0, 0, S_WIND3}, // S_WIND2 diff --git a/src/info.h b/src/info.h index f9052b5da..d0e75e2e8 100644 --- a/src/info.h +++ b/src/info.h @@ -2330,6 +2330,22 @@ typedef enum state S_ARMF14, S_ARMF15, S_ARMF16, + S_ARMF17, + S_ARMF18, + S_ARMF19, + S_ARMF20, + S_ARMF21, + S_ARMF22, + S_ARMF23, + S_ARMF24, + S_ARMF25, + S_ARMF26, + S_ARMF27, + S_ARMF28, + S_ARMF29, + S_ARMF30, + S_ARMF31, + S_ARMF32, S_ARMB1, S_ARMB2, @@ -2347,6 +2363,22 @@ typedef enum state S_ARMB14, S_ARMB15, S_ARMB16, + S_ARMB17, + S_ARMB18, + S_ARMB19, + S_ARMB20, + S_ARMB21, + S_ARMB22, + S_ARMB23, + S_ARMB24, + S_ARMB25, + S_ARMB26, + S_ARMB27, + S_ARMB28, + S_ARMB29, + S_ARMB30, + S_ARMB31, + S_ARMB32, S_WIND1, S_WIND2, diff --git a/src/p_inter.c b/src/p_inter.c index 833a9ba52..c57d348fc 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -577,25 +577,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_TOKEN: if (player->bot) return; - tokenlist += special->health; P_AddPlayerScore(player, 1000); - if (!modeattacking) // score only there... + if (gametype != GT_COOP || modeattacking) // score only? + break; + + tokenlist += special->health; + + if (ALL7EMERALDS(emeralds)) // Got all 7 { - if (ALL7EMERALDS(emeralds)) // Got all 7 + if (!(netgame || multiplayer)) { - if (!(netgame || multiplayer)) - { - player->continues += 1; - players->gotcontinue = true; - if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_s3kac); - } + player->continues += 1; + players->gotcontinue = true; + if (P_IsLocalPlayer(player)) + S_StartSound(NULL, sfx_s3kac); } - else - token++; } + else + token++; + break; // Emerald Hunt diff --git a/src/p_mobj.c b/src/p_mobj.c index 8695d57e4..64756c55a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9539,7 +9539,7 @@ void P_SpawnMapThing(mapthing_t *mthing) // They're likely facets of the level's design and therefore required to progress. } - if (i == MT_TOKEN && (gametype != GT_COOP || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++))) + if (i == MT_TOKEN && ((gametype != GT_COOP && gametype != GT_COMPETITION) || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++))) return; // you already got this token, or there are too many, or the gametype's not right // Objectplace landing point diff --git a/src/p_user.c b/src/p_user.c index b8634afa8..b3a8bcf4b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2336,12 +2336,17 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) { tic_t timeleft = (player->powers[pw_spacetime]) ? player->powers[pw_spacetime] : player->powers[pw_underwater]; - if ((timeleft == 11*TICRATE + 1) // 5 - || (timeleft == 9*TICRATE + 1) // 4 - || (timeleft == 7*TICRATE + 1) // 3 - || (timeleft == 5*TICRATE + 1) // 2 - || (timeleft == 3*TICRATE + 1) // 1 - || (timeleft == 1*TICRATE + 1) // 0 + if (player->exiting) + player->powers[pw_underwater] = player->powers[pw_spacetime] = 0; + + timeleft--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity + + if ((timeleft == 11*TICRATE) // 5 + || (timeleft == 9*TICRATE) // 4 + || (timeleft == 7*TICRATE) // 3 + || (timeleft == 5*TICRATE) // 2 + || (timeleft == 3*TICRATE) // 1 + || (timeleft == 1*TICRATE) // 0 ) { fixed_t height = (player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->z - FixedMul(8*FRACUNIT + mobjinfo[MT_DROWNNUMBERS].height, FixedMul(player->mo->scale, player->shieldscale)) @@ -2349,7 +2354,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) mobj_t *numbermobj = P_SpawnMobj(player->mo->x, player->mo->y, height, MT_DROWNNUMBERS); - timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be (((timeleft - 1)/TICRATE) - 1)/2, but integer division rounds down for us + timeleft /= (2*TICRATE); // To be strictly accurate it'd need to be ((timeleft/TICRATE) - 1)/2, but integer division rounds down for us if (player->charflags & SF_MACHINE) { @@ -2408,14 +2413,6 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) S_ChangeMusicInternal("_drown", false); } } - - if (player->exiting) - { - if (player->powers[pw_underwater] > 1) - player->powers[pw_underwater] = 0; - - player->powers[pw_spacetime] = 0; - } } // diff --git a/src/st_stuff.c b/src/st_stuff.c index 3ae212bc1..6a909580d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1251,7 +1251,6 @@ static void ST_drawFirstPersonHUD(void) { patch_t *p = NULL; UINT32 airtime; - UINT32 frame = 0; spriteframe_t *sprframe; // If both air timers are active, use the air timer with the least time left if (stplyr->powers[pw_underwater] && stplyr->powers[pw_spacetime]) @@ -1259,34 +1258,32 @@ static void ST_drawFirstPersonHUD(void) else // Use whichever one is active otherwise airtime = (stplyr->powers[pw_spacetime]) ? stplyr->powers[pw_spacetime] : stplyr->powers[pw_underwater]; - if (!airtime) + if (airtime < 1) return; // No air timers are active, nothing would be drawn anyway airtime--; // The original code was all n*TICRATE + 1, so let's remove 1 tic for simplicity if (airtime > 11*TICRATE) return; // Not time to draw any drown numbers yet - // Choose which frame to use based on time left - if (airtime <= 11*TICRATE && airtime >= 10*TICRATE) - frame = 5; - else if (airtime <= 9*TICRATE && airtime >= 8*TICRATE) - frame = 4; - else if (airtime <= 7*TICRATE && airtime >= 6*TICRATE) - frame = 3; - else if (airtime <= 5*TICRATE && airtime >= 4*TICRATE) - frame = 2; - else if (airtime <= 3*TICRATE && airtime >= 2*TICRATE) - frame = 1; - else if (airtime <= 1*TICRATE && airtime > 0) - frame = 0; - else + + if (!((airtime > 10*TICRATE - 5) + || (airtime <= 9*TICRATE && airtime > 8*TICRATE - 5) + || (airtime <= 7*TICRATE && airtime > 6*TICRATE - 5) + || (airtime <= 5*TICRATE && airtime > 4*TICRATE - 5) + || (airtime <= 3*TICRATE && airtime > 2*TICRATE - 5) + || (airtime <= 1*TICRATE))) return; // Don't draw anything between numbers + if (!((airtime % 10) < 5)) + return; // Keep in line with the flashing thing from third person. + + airtime /= (2*TICRATE); // To be strictly accurate it'd need to be ((airtime/TICRATE) - 1)/2, but integer division rounds down for us + if (stplyr->charflags & SF_MACHINE) - frame += 6; // Robots use different drown numbers + airtime += 6; // Robots use different drown numbers // Get the front angle patch for the frame - sprframe = &sprites[SPR_DRWN].spriteframes[frame]; + sprframe = &sprites[SPR_DRWN].spriteframes[airtime]; p = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); // Display the countdown drown numbers! From 0fbebcaa08e5a64e457f84a2e748d065ffc9cdc0 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 30 Mar 2018 22:03:14 +0100 Subject: [PATCH 54/66] Make special stage tallies do the token noise if you cash in a token! --- src/y_inter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 7ac28018b..c86dee758 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -825,7 +825,7 @@ void Y_Ticker(void) { tallydonetic = intertic; endtic = intertic + 3*TICRATE; // 3 second pause after end of tally - S_StartSound(NULL, sfx_chchng); // cha-ching! + S_StartSound(NULL, (gottoken ? sfx_token : sfx_chchng)); // cha-ching! // Update when done with tally if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) @@ -870,7 +870,7 @@ void Y_Ticker(void) if ((intertic - tallydonetic) > (3*TICRATE)/2) { endtic = intertic + 4*TICRATE; // 4 second pause after end of tally - S_StartSound(NULL, sfx_s3kac); // cha-ching! + S_StartSound(NULL, sfx_s3kac); // bingly-bingly-bing! } return; } @@ -890,7 +890,7 @@ void Y_Ticker(void) if (!(data.spec.continues & 0x80)) // don't set endtic yet! endtic = intertic + 4*TICRATE; // 4 second pause after end of tally - S_StartSound(NULL, sfx_chchng); // cha-ching! + S_StartSound(NULL, (gottoken ? sfx_token : sfx_chchng)); // cha-ching! // Update when done with tally if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) From 6f2de824fb015d71940e9c4d12b321b30bcb63b2 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 30 Mar 2018 23:12:44 +0100 Subject: [PATCH 55/66] 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 6d59551afdac6bf20c5add5f6a86c169c9db431f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 1 Apr 2018 20:54:19 +0100 Subject: [PATCH 56/66] Mace optimisation! * Handle all chain objects as a hnext/hprev chain. * When removing mobjs with hnext/hprev, "repair the chain" (make the h links meet). * Fix hidden slings, which I accidentially broke when I revamped maces the first time. * Kill MF2_MACEROTATE. Not needed for anything anymore. * P_MaceRotate now available to Lua to make up for it. * Related: Made modifying hnext/hprev using Lua safer, so it keeps the reference counts in play. --- src/dehacked.c | 1 - src/info.c | 14 +-- src/lua_baselib.c | 14 +++ src/lua_mobjlib.c | 16 ++- src/p_enemy.c | 11 +- src/p_local.h | 2 + src/p_mobj.c | 260 +++++++++++++++++++++++++++++----------------- src/p_mobj.h | 2 - 8 files changed, 209 insertions(+), 111 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c172549e1..ced71f079 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6515,7 +6515,6 @@ static const char *const MOBJFLAG2_LIST[] = { "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH "LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) "SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) - "MACEROTATE", // Thinker calls P_MaceRotate around tracer NULL }; diff --git a/src/info.c b/src/info.c index acb12379a..f11d88af8 100644 --- a/src/info.c +++ b/src/info.c @@ -9011,7 +9011,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 10000, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9038,7 +9038,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 10000, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9065,7 +9065,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 10000, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9092,7 +9092,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 10000, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9119,7 +9119,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9146,7 +9146,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 200, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, @@ -9173,7 +9173,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 200, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_SCENERY, // flags S_NULL // raisestate }, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9d65a5832..4040e271d 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -776,6 +776,19 @@ static int lib_pCanRunOnWater(lua_State *L) return 1; } +static int lib_pMaceRotate(lua_State *L) +{ + mobj_t *center = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + INT32 baserot = luaL_checkinteger(L, 2); + INT32 baseprevrot = luaL_checkinteger(L, 3); + NOHUD + INLEVEL + if (!center) + return LUA_ErrInvalid(L, "mobj_t"); + P_MaceRotate(center, baserot, baseprevrot); + return 0; +} + // P_USER //////////// @@ -2526,6 +2539,7 @@ static luaL_Reg lib[] = { {"P_CheckDeathPitCollide",lib_pCheckDeathPitCollide}, {"P_CheckSolidLava",lib_pCheckSolidLava}, {"P_CanRunOnWater",lib_pCanRunOnWater}, + {"P_MaceRotate",lib_pMaceRotate}, // p_user {"P_GetPlayerHeight",lib_pGetPlayerHeight}, diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index d384b75d1..1583bd3c4 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -530,10 +530,22 @@ static int mobj_set(lua_State *L) case mobj_bprev: return UNIMPLEMENTED; case mobj_hnext: - mo->hnext = luaL_checkudata(L, 3, META_MOBJ); + if (lua_isnil(L, 3)) + P_SetTarget(&mo->hnext, NULL); + else + { + mobj_t *hnext = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->hnext, hnext); + } break; case mobj_hprev: - mo->hprev = luaL_checkudata(L, 3, META_MOBJ); + if (lua_isnil(L, 3)) + P_SetTarget(&mo->hprev, NULL); + else + { + mobj_t *hprev = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->hprev, hprev); + } break; case mobj_type: // yeah sure, we'll let you change the mobj's type. { diff --git a/src/p_enemy.c b/src/p_enemy.c index 9acc8430e..a8ce7869c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4917,6 +4917,7 @@ void A_SlingAppear(mobj_t *actor) boolean firsttime = true; UINT8 mlength = 4; mobj_t *spawnee; + mobj_t *hprev = actor; #ifdef HAVE_BLUA if (LUA_CallAction("A_SlingAppear", actor)) return; @@ -4927,7 +4928,6 @@ void A_SlingAppear(mobj_t *actor) P_SetThingPosition(actor); actor->lastlook = 128; actor->movecount = actor->lastlook; - actor->health = actor->angle>>ANGLETOFINESHIFT; actor->threshold = 0; actor->movefactor = actor->threshold; actor->friction = 128; @@ -4936,10 +4936,13 @@ void A_SlingAppear(mobj_t *actor) { spawnee = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMALLMACECHAIN); - P_SetTarget(&spawnee->target, actor); + P_SetTarget(&spawnee->tracer, actor); + P_SetTarget(&spawnee->hprev, hprev); + P_SetTarget(&hprev->hnext, spawnee); + hprev = spawnee; - spawnee->threshold = 0; - spawnee->reactiontime = mlength; + spawnee->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT; + spawnee->movecount = mlength; if (firsttime) { diff --git a/src/p_local.h b/src/p_local.h index 54ae37ed2..49d3ed614 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -280,6 +280,8 @@ mobj_t *P_GetClosestAxis(mobj_t *source); boolean P_CanRunOnWater(player_t *player, ffloor_t *rover); +void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot); + void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration); #define PAL_WHITE 1 #define PAL_MIXUP 2 diff --git a/src/p_mobj.c b/src/p_mobj.c index 8695d57e4..2e78c098e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6176,98 +6176,149 @@ static void P_NightsItemChase(mobj_t *thing) // // P_MaceRotate -// Spins an object around its target, or, swings it from side to side. +// Spins a hnext-chain of objects around its centerpoint, side to side or periodically. // -static void P_MaceRotate(mobj_t *mobj) +void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) { - TVector v; + TVector unit, baseuo, unitoffset; TVector *res; - fixed_t radius, dist; + fixed_t radius, dist, wah; angle_t fa; - INT32 prevswing; - boolean donetwice = false; + //boolean donetwice = false; + boolean dosound = false; + mobj_t *mobj = center->hnext, *hnext = NULL; // Tracer was removed. - if (!mobj->health) + /*if (!mobj->health) return; else if (!mobj->tracer) { P_KillMobj(mobj, NULL, NULL, 0); return; - } + }*/ - mobj->momx = mobj->momy = mobj->momz = 0; + INT32 rot = (baserot &= FINEMASK); + INT32 prevrot = (baseprevrot &= FINEMASK); - prevswing = mobj->threshold; - mobj->threshold += mobj->tracer->lastlook; - mobj->threshold &= FINEMASK; + INT32 lastthreshold = FINEMASK; // needs to never be equal at start of loop + fixed_t lastfriction = INT32_MIN; // ditto; almost certainly never, but... - dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); + fixed_t movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = 0; - // Radius of the link's rotation. - radius = FixedMul(dist * mobj->movecount, mobj->tracer->scale) + mobj->tracer->extravalue1; + baseuo[3] = 0; -maceretry: - - fa = (FixedAngle(mobj->tracer->movefactor*FRACUNIT) >> ANGLETOFINESHIFT); - radius = FixedMul(FINECOSINE(fa), radius); - v[1] = -FixedMul(FINESINE(fa), radius) - + FixedMul(dist * mobj->movefactor, mobj->tracer->scale); - v[3] = FRACUNIT; - - // Swinging Chain. - if (mobj->tracer->flags2 & MF2_STRONGBOX) + while (mobj) { - fixed_t swingmagnitude = FixedMul(FINECOSINE(mobj->threshold), mobj->tracer->lastlook << FRACBITS); - prevswing = FINECOSINE(prevswing); + mobj->momx = mobj->momy = mobj->momz = 0; - if (!donetwice - && (mobj->flags2 & MF2_BOSSNOTRAP) // at the end of the chain and can play a sound - && ((prevswing > 0) != (swingmagnitude > 0))) // just passed its lowest point + if (mobj->threshold != lastthreshold + || mobj->friction != lastfriction) + { + rot = (baserot + mobj->threshold) & FINEMASK; + prevrot = (baseprevrot + mobj->threshold) & FINEMASK; + + fa = (FixedAngle(center->movefactor*FRACUNIT) >> ANGLETOFINESHIFT); // mpinch + radius = FINECOSINE(fa); + unit[1] = -FixedMul(FINESINE(fa), radius); + unit[3] = center->scale; + + // Swinging Chain. + if (center->flags2 & MF2_STRONGBOX) + { + fixed_t swingmag = FixedMul(FINECOSINE(rot), center->lastlook << FRACBITS); + fixed_t prevswingmag = FINECOSINE(prevrot); + + if ((prevswingmag > 0) != (swingmag > 0)) // just passed its lowest point + dosound = true; + //S_StartSound(mobj, mobj->info->activesound); + + fa = ((FixedAngle(swingmag) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK; + + unit[0] = FixedMul(FINESINE(fa), -radius); + unit[2] = FixedMul(FINECOSINE(fa), -radius); + } + // Rotating Chain. + else + { + angle_t prevfa = (prevrot + mobj->friction) & FINEMASK; + fa = (rot + mobj->friction) & FINEMASK; + + if (!(prevfa > (FINEMASK/2)) && (fa > (FINEMASK/2))) // completed a full swing + dosound = true; + + unit[0] = FixedMul(FINECOSINE(fa), radius); + unit[2] = FixedMul(FINESINE(fa), radius); + } + + // Calculate the angle matrixes for the link. + res = VectorMatrixMultiply(unit, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&unit, res, sizeof(unit)); + res = VectorMatrixMultiply(unit, *RotateZMatrix(center->angle)); + M_Memcpy(&unit, res, sizeof(unit)); + } + + if (dosound && (mobj->flags2 & MF2_BOSSNOTRAP)) + { S_StartSound(mobj, mobj->info->activesound); + dosound = false; + } - fa = ((FixedAngle(swingmagnitude) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK; + dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); - v[0] = FixedMul(FINESINE(fa), -radius); - v[2] = FixedMul(FINECOSINE(fa), -radius); - } - // Rotating Chain. - else - { - prevswing = (prevswing + mobj->friction) & FINEMASK; - fa = (mobj->threshold + mobj->friction) & FINEMASK; + if (dist*mobj->movefactor != movefac) + { + if (!baseuo[3]) + { + baseuo[1] = FRACUNIT; + baseuo[3] = center->scale; + baseuo[0] = baseuo[2] = 0; - if (!donetwice - && (mobj->flags2 & MF2_BOSSNOTRAP) // at the end of the chain and can play a sound - && (!(prevswing > (FINEMASK/2)) && (fa > (FINEMASK/2)))) // completed a full swing - S_StartSound(mobj, mobj->info->activesound); + res = VectorMatrixMultiply(baseuo, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&baseuo, res, sizeof(unit)); + res = VectorMatrixMultiply(baseuo, *RotateZMatrix(center->angle)); + M_Memcpy(&baseuo, res, sizeof(unit)); - v[0] = FixedMul(FINECOSINE(fa), radius); - v[2] = FixedMul(FINESINE(fa), radius); + lastthreshold = mobj->threshold; + lastfriction = mobj->friction; + } + + if (mobj->movefactor) + { + movefac = dist*mobj->movefactor; + unitoffset[0] = FixedMul(movefac, baseuo[0]); + unitoffset[1] = FixedMul(movefac, baseuo[1]); + unitoffset[2] = FixedMul(movefac, baseuo[2]); + } + else + movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = 0; + } + + //maceretry: + + hnext = mobj->hnext; // just in case the mobj is removed + + P_UnsetThingPosition(mobj); + + // Radius of the link's rotation. + wah = (dist * mobj->movecount) + center->extravalue1; + + // Add on the appropriate distances to the center's co-ordinates. + mobj->x = center->x + FixedMul(unit[0], wah) + unitoffset[0]; + mobj->y = center->y + FixedMul(unit[1], wah) + unitoffset[1]; + mobj->z = center->z + FixedMul(unit[2], wah) + unitoffset[2]; + + // Cut the height to align the link with the axis. + if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN) + mobj->z -= P_MobjFlip(mobj)*mobj->height/4; + else + mobj->z -= P_MobjFlip(mobj)*mobj->height/2; + + P_SetThingPosition(mobj); + + mobj = hnext; } - // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(v, *RotateXMatrix(mobj->tracer->threshold << ANGLETOFINESHIFT)); - M_Memcpy(&v, res, sizeof(v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(mobj->tracer->health << ANGLETOFINESHIFT)); - M_Memcpy(&v, res, sizeof(v)); - - // Cut the height to align the link with the axis. - if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN) - v[2] -= P_MobjFlip(mobj)*mobj->height/4; - else - v[2] -= P_MobjFlip(mobj)*mobj->height/2; - - P_UnsetThingPosition(mobj); - - // Add on the appropriate distances to the center's co-ordinates. - mobj->x = mobj->tracer->x + v[0]; - mobj->y = mobj->tracer->y + v[1]; - mobj->z = mobj->tracer->z + v[2]; - - P_SetThingPosition(mobj); - - if (donetwice || P_MobjWasRemoved(mobj)) + /*if (donetwice || P_MobjWasRemoved(mobj)) return; if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) @@ -6293,7 +6344,7 @@ maceretry: radius = FixedMul(radius, dist); donetwice = true; dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); - goto maceretry; + goto maceretry;*/ } static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) @@ -6664,13 +6715,6 @@ void P_MobjThinker(mobj_t *mobj) } } - if (mobj->flags2 & MF2_MACEROTATE) - { - P_MaceRotate(mobj); - if (P_MobjWasRemoved(mobj)) - return; - } - // Special thinker for scenery objects if (mobj->flags & MF_SCENERY) { @@ -6687,6 +6731,29 @@ void P_MobjThinker(mobj_t *mobj) switch (mobj->type) { + case MT_CHAINPOINT: + case MT_CHAINMACEPOINT: + if (leveltime & 1) + { + if (mobj->lastlook > mobj->movecount) + mobj->lastlook--; + /* + if (mobj->threshold > mobj->movefactor) + mobj->threshold -= FRACUNIT; + else if (mobj->threshold < mobj->movefactor) + mobj->threshold += FRACUNIT;*/ + } + /* FALLTHRU */ + case MT_MACEPOINT: + case MT_SPRINGBALLPOINT: + case MT_FIREBARPOINT: + case MT_CUSTOMMACEPOINT: + case MT_HIDDEN_SLING: + // The following was pretty good, but liked breaking whenever mobj->lastlook changed. + //P_MaceRotate(mobj, ((leveltime + 1) * mobj->lastlook), (leveltime * mobj->lastlook)); + P_MaceRotate(mobj, mobj->movedir + mobj->lastlook, mobj->movedir); + mobj->movedir = (mobj->movedir + mobj->lastlook) & FINEMASK; + break; case MT_HOOP: if (mobj->fuse > 1) P_MoveHoop(mobj); @@ -7337,19 +7404,6 @@ void P_MobjThinker(mobj_t *mobj) } } break; - case MT_CHAINPOINT: - case MT_CHAINMACEPOINT: - if (leveltime & 1) - { - if (mobj->lastlook > mobj->movecount) - mobj->lastlook--; -/* - if (mobj->threshold > mobj->movefactor) - mobj->threshold -= FRACUNIT; - else if (mobj->threshold < mobj->movefactor) - mobj->threshold += FRACUNIT;*/ - } - break; case MT_EGGCAPSULE: if (!mobj->reactiontime) { @@ -8615,6 +8669,13 @@ void P_RemoveMobj(mobj_t *mobj) // Remove any references to other mobjs. P_SetTarget(&mobj->target, P_SetTarget(&mobj->tracer, NULL)); + if (mobj->hnext) + P_SetTarget(&mobj->hnext->hprev, mobj->hprev); + if (mobj->hprev) + P_SetTarget(&mobj->hprev->hnext, mobj->hnext); + + P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL)); + // free block // DBG: set everything in mobj_t to 0xFF instead of leaving it. debug memory error. if (mobj->flags & MF_NOTHINK && !mobj->thinker.next) @@ -9301,6 +9362,7 @@ void P_SpawnMapThing(mapthing_t *mthing) mobj_t *mobj; fixed_t x, y, z; subsector_t *ss; + boolean doangle = true; if (!mthing->type) return; // Ignore type-0 things as NOPs @@ -9710,7 +9772,7 @@ void P_SpawnMapThing(mapthing_t *mthing) angle_t mspokeangle; mobjtype_t chainlink, macetype, firsttype, linktype; boolean mdoall = true; - mobj_t *spawnee; + mobj_t *spawnee, *hprev; mobjflag_t mflagsapply; mobjflag2_t mflags2apply; mobjeflag_t meflagsapply; @@ -9748,7 +9810,7 @@ ML_EFFECT4 : Don't clip inside the ground mspeed = abs(lines[line].dy >> (FRACBITS - 4)); mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; if ((mmaxspeed = sides[lines[line].sidenum[0]].rowoffset >> (FRACBITS - 4)) < mspeed) - mmaxspeed = mspeed << 1; + mmaxspeed = mspeed; mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; @@ -9787,10 +9849,12 @@ ML_EFFECT4 : Don't clip inside the ground mobj->lastlook = mspeed; mobj->movecount = mobj->lastlook; - mobj->health = (FixedAngle(myaw*FRACUNIT)>>ANGLETOFINESHIFT); + mobj->angle = FixedAngle(myaw*FRACUNIT); + doangle = false; mobj->threshold = (FixedAngle(mpitch*FRACUNIT)>>ANGLETOFINESHIFT); mobj->friction = mmaxspeed; mobj->movefactor = mpinch; + mobj->movedir = 0; // Mobjtype selection switch(mobj->type) @@ -9857,7 +9921,7 @@ ML_EFFECT4 : Don't clip inside the ground mmin = mnumspokes; // Make the links the same type as the end - repeated below - if ((mobj->type != MT_CHAINPOINT) && ((lines[line].flags & ML_EFFECT2) != (mobj->type == MT_FIREBARPOINT))) // exclusive or + if ((mobj->type != MT_CHAINPOINT) && (((lines[line].flags & ML_EFFECT2) == ML_EFFECT2) != (mobj->type == MT_FIREBARPOINT))) // exclusive or { linktype = macetype; radiusfactor = 2; // Double the radius. @@ -9866,7 +9930,7 @@ ML_EFFECT4 : Don't clip inside the ground radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP|MF_NOCLIPHEIGHT)); - mflags2apply = (MF2_MACEROTATE|((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0)); + mflags2apply = ((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0); meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0); msound = ((firsttype == chainlink) ? 0 : (mwidth & 1)); @@ -9875,6 +9939,8 @@ ML_EFFECT4 : Don't clip inside the ground mphase = (FixedAngle(mphase*FRACUNIT)>>ANGLETOFINESHIFT); mroll = (FixedAngle(mroll*FRACUNIT)>>ANGLETOFINESHIFT); + hprev = mobj; + #define makemace(mobjtype, dist, moreflags2) P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ P_SetTarget(&spawnee->tracer, mobj);\ spawnee->threshold = mphase;\ @@ -9884,7 +9950,10 @@ ML_EFFECT4 : Don't clip inside the ground spawnee->angle = myaw;\ spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ spawnee->flags2 |= (mflags2apply|moreflags2);\ - spawnee->eflags |= meflagsapply + spawnee->eflags |= meflagsapply;\ + P_SetTarget(&hprev->hnext, spawnee);\ + P_SetTarget(&spawnee->hprev, hprev);\ + hprev = spawnee domaceagain: mnumspokesset = mnumspokes; @@ -10264,7 +10333,8 @@ domaceagain: } } - mobj->angle = FixedAngle(mthing->angle*FRACUNIT); + if (doangle) + mobj->angle = FixedAngle(mthing->angle*FRACUNIT); if ((mthing->options & MTF_AMBUSH) && (mthing->options & MTF_OBJECTSPECIAL) diff --git a/src/p_mobj.h b/src/p_mobj.h index c6e1bfbf2..ec25855d8 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -194,8 +194,6 @@ typedef enum MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) MF2_SHIELD = 1<<29, // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) - MF2_MACEROTATE = 1<<30, // Thinker calls P_MaceRotate around tracer - // free: to and including 1<<31 } mobjflag2_t; typedef enum From 97ddb8881d5a5af40097f8f8480200c91262a60e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 1 Apr 2018 22:05:59 +0100 Subject: [PATCH 57/66] * Remove ability to change speed of chains. * Fix ability to turn chains (still disabled by default, just at least want the option...) * Replace max speed setting with a "minimum chainlink distance" setting - if greater than zero, that many chains will not be spawned from the center outwards. Doesn't affect the head of the chain at all, since otherwise what's the point? :V --- src/p_mobj.c | 32 +++++++++----------------------- src/p_user.c | 13 +------------ 2 files changed, 10 insertions(+), 35 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 2e78c098e..17775b0ef 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6731,21 +6731,10 @@ void P_MobjThinker(mobj_t *mobj) switch (mobj->type) { - case MT_CHAINPOINT: - case MT_CHAINMACEPOINT: - if (leveltime & 1) - { - if (mobj->lastlook > mobj->movecount) - mobj->lastlook--; - /* - if (mobj->threshold > mobj->movefactor) - mobj->threshold -= FRACUNIT; - else if (mobj->threshold < mobj->movefactor) - mobj->threshold += FRACUNIT;*/ - } - /* FALLTHRU */ case MT_MACEPOINT: + case MT_CHAINMACEPOINT: case MT_SPRINGBALLPOINT: + case MT_CHAINPOINT: case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: case MT_HIDDEN_SLING: @@ -9768,7 +9757,7 @@ void P_SpawnMapThing(mapthing_t *mthing) case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: { - fixed_t mlength, mlengthset, mspeed, mphase, myaw, mpitch, mmaxspeed, mnumspokes, mnumspokesset, mpinch, mroll, mnumnospokes, mwidth, mmin, msound, radiusfactor; + fixed_t mlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mnumspokesset, mpinch, mroll, mnumnospokes, mwidth, mmin, msound, radiusfactor; angle_t mspokeangle; mobjtype_t chainlink, macetype, firsttype, linktype; boolean mdoall = true; @@ -9809,8 +9798,8 @@ ML_EFFECT4 : Don't clip inside the ground mlength = abs(lines[line].dx >> FRACBITS); mspeed = abs(lines[line].dy >> (FRACBITS - 4)); mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; - if ((mmaxspeed = sides[lines[line].sidenum[0]].rowoffset >> (FRACBITS - 4)) < mspeed) - mmaxspeed = mspeed; + if ((mminlength = sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0) + mminlength = 0; mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; @@ -9829,18 +9818,16 @@ ML_EFFECT4 : Don't clip inside the ground mpinch = mroll = mnumnospokes = mwidth = 0; CONS_Debug(DBG_GAMELOGIC, "Mace/Chain (mapthing #%s):\n" - "Length is %d\n" + "Length is %d (minus %d)\n" "Speed is %d\n" "Phase is %d\n" "Yaw is %d\n" "Pitch is %d\n" - "Max. speed is %d\n" - "No. of spokes is %d\n" + "No. of spokes is %d (%d antispokes)\n" "Pinch is %d\n" "Roll is %d\n" - "No. of antispokes is %d\n" "Width is %d\n", - sizeu1(mthingi), mlength, mspeed, mphase, myaw, mpitch, mmaxspeed, mnumspokes, mpinch, mroll, mnumnospokes, mwidth); + sizeu1(mthingi), mlength, mminlength, mspeed, mphase, myaw, mpitch, mnumspokes, mnumnospokes, mpinch, mroll, mwidth); if (mnumnospokes > 0 && (mnumnospokes < mnumspokes)) mnumnospokes = mnumspokes/mnumnospokes; @@ -9852,7 +9839,6 @@ ML_EFFECT4 : Don't clip inside the ground mobj->angle = FixedAngle(myaw*FRACUNIT); doangle = false; mobj->threshold = (FixedAngle(mpitch*FRACUNIT)>>ANGLETOFINESHIFT); - mobj->friction = mmaxspeed; mobj->movefactor = mpinch; mobj->movedir = 0; @@ -10011,7 +9997,7 @@ domaceagain: continue; // The rest of the links - while (mlengthset > 0) + while (mlengthset > mminlength) { spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); } } diff --git a/src/p_user.c b/src/p_user.c index f422e9b65..c0fd01000 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10421,21 +10421,10 @@ void P_PlayerAfterThink(player_t *player) player->secondjump = 0; player->pflags &= ~PF_THOKKED; - if (cmd->forwardmove > 0) - { - if ((player->mo->tracer->tracer->lastlook += 2) > player->mo->tracer->tracer->friction) - player->mo->tracer->tracer->lastlook = player->mo->tracer->tracer->friction; - } - else if (cmd->forwardmove < 0) - { - if ((player->mo->tracer->tracer->lastlook -= 2) < player->mo->tracer->tracer->movecount) - player->mo->tracer->tracer->lastlook = player->mo->tracer->tracer->movecount; - } - if ((player->mo->tracer->tracer->flags & MF_SLIDEME) // Noclimb on chain parameters gives this && !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode? { - player->mo->tracer->tracer->health += cmd->sidemove; + player->mo->tracer->tracer->angle += cmd->sidemove<mo->angle += cmd->sidemove< ANGLE_MAX if (!demoplayback || P_AnalogMove(player)) From 5ac70bbb7e286c1908ed5056af530940ef1c00d8 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 2 Apr 2018 01:08:31 +0100 Subject: [PATCH 58/66] * Fix multispoke mace/chainbars having problems. * Completely rework how mace/chainbars are spawned to reduce the number of matrix multiplications required EVEN FURTHER! * Reimplement the maceretry solidity stuff (effect 4). * Flip the mminlength stuff so that existing dev maps don't break badly. * Fix hacky chainbar grabbing. * Tweak height of tinychain a smidge. --- src/info.c | 2 +- src/p_inter.c | 4 +- src/p_mobj.c | 197 ++++++++++++++++++++++++++++---------------------- 3 files changed, 112 insertions(+), 91 deletions(-) diff --git a/src/info.c b/src/info.c index f11d88af8..673c18ac6 100644 --- a/src/info.c +++ b/src/info.c @@ -9195,7 +9195,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 24*FRACUNIT, // speed 24*FRACUNIT, // radius - 48*FRACUNIT, // height + 32*FRACUNIT, // height 0, // display offset 100, // mass 1, // damage diff --git a/src/p_inter.c b/src/p_inter.c index 4c9e231fe..82187f533 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1503,10 +1503,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_flashing]) return; - if (special->movefactor && special->tracer && (angle_t)special->tracer->health != ANGLE_90 && (angle_t)special->tracer->health != ANGLE_270) + if (special->movefactor && special->tracer && (angle_t)special->tracer->angle != ANGLE_90 && (angle_t)special->tracer->angle != ANGLE_270) { // I don't expect you to understand this, Mr Bond... angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->threshold; - if ((special->movefactor > 0) == ((angle_t)special->tracer->health > ANGLE_90 && (angle_t)special->tracer->health < ANGLE_270)) + if ((special->movefactor > 0) == ((angle_t)special->tracer->angle > ANGLE_90 && (angle_t)special->tracer->angle < ANGLE_270)) ang += ANGLE_180; if (ang < ANGLE_180) return; // I expect you to die. diff --git a/src/p_mobj.c b/src/p_mobj.c index 17775b0ef..f98943d84 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6182,33 +6182,28 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) { TVector unit, baseuo, unitoffset; TVector *res; - fixed_t radius, dist, wah; + fixed_t radius, dist, mag, zstore; angle_t fa; - //boolean donetwice = false; + boolean donetwice = false; boolean dosound = false; mobj_t *mobj = center->hnext, *hnext = NULL; - // Tracer was removed. - /*if (!mobj->health) - return; - else if (!mobj->tracer) - { - P_KillMobj(mobj, NULL, NULL, 0); - return; - }*/ - INT32 rot = (baserot &= FINEMASK); INT32 prevrot = (baseprevrot &= FINEMASK); INT32 lastthreshold = FINEMASK; // needs to never be equal at start of loop fixed_t lastfriction = INT32_MIN; // ditto; almost certainly never, but... - fixed_t movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = 0; - - baseuo[3] = 0; + fixed_t movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = baseuo[3] = 0; while (mobj) { + if (!mobj->health) + { + mobj = mobj->hnext; + continue; + } + mobj->momx = mobj->momy = mobj->momz = 0; if (mobj->threshold != lastthreshold @@ -6255,6 +6250,9 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) M_Memcpy(&unit, res, sizeof(unit)); res = VectorMatrixMultiply(unit, *RotateZMatrix(center->angle)); M_Memcpy(&unit, res, sizeof(unit)); + + lastthreshold = mobj->threshold; + lastfriction = mobj->friction; } if (dosound && (mobj->flags2 & MF2_BOSSNOTRAP)) @@ -6277,9 +6275,6 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) M_Memcpy(&baseuo, res, sizeof(unit)); res = VectorMatrixMultiply(baseuo, *RotateZMatrix(center->angle)); M_Memcpy(&baseuo, res, sizeof(unit)); - - lastthreshold = mobj->threshold; - lastfriction = mobj->friction; } if (mobj->movefactor) @@ -6293,58 +6288,78 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = 0; } - //maceretry: - hnext = mobj->hnext; // just in case the mobj is removed + // Radius of the link's rotation. + mag = (dist * mobj->movecount) + mobj->extravalue1; + +maceretry: P_UnsetThingPosition(mobj); - // Radius of the link's rotation. - wah = (dist * mobj->movecount) + center->extravalue1; + mobj->x = center->x; + mobj->y = center->y; + mobj->z = center->z; // Add on the appropriate distances to the center's co-ordinates. - mobj->x = center->x + FixedMul(unit[0], wah) + unitoffset[0]; - mobj->y = center->y + FixedMul(unit[1], wah) + unitoffset[1]; - mobj->z = center->z + FixedMul(unit[2], wah) + unitoffset[2]; + if (mag) + { + zstore = FixedMul(unit[2], mag); + mobj->x += FixedMul(unit[0], mag); + mobj->y += FixedMul(unit[1], mag); + } + else + zstore = 0; + zstore += unitoffset[2]; + + mobj->x += unitoffset[0]; + mobj->y += unitoffset[1]; // Cut the height to align the link with the axis. if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN) - mobj->z -= P_MobjFlip(mobj)*mobj->height/4; + zstore -= P_MobjFlip(mobj)*mobj->height/4; else - mobj->z -= P_MobjFlip(mobj)*mobj->height/2; + zstore -= P_MobjFlip(mobj)*mobj->height/2; + + mobj->z += zstore; + +#if 0 // toaster's testing flashie! + if (!mobj->threshold && !mobj->friction && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. + mobj->flags2 ^= MF2_DONTDRAW; +#endif P_SetThingPosition(mobj); + if (!mag || donetwice || P_MobjWasRemoved(mobj)) + goto cont; + + if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) + goto cont; + + if ((fa = ((mobj->tracer->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it + goto cont; + + if (mobj->subsector->sector->ffloors) + P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2); + + // Variable reuse + if (mobj->floorz > mobj->z) + dist = (mobj->floorz - mobj->tracer->z); + else if (mobj->ceilingz < mobj->z) + dist = (mobj->ceilingz - mobj->tracer->z); + else + goto cont; + + if ((dist = FixedDiv(dist, zstore)) > FRACUNIT) + goto cont; + + mag = FixedMul(mag, dist); + donetwice = true; + dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); + goto maceretry; + +cont: mobj = hnext; } - - /*if (donetwice || P_MobjWasRemoved(mobj)) - return; - - if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) - return; - - if ((fa = ((mobj->tracer->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it - return; - - if (mobj->subsector->sector->ffloors) - P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2); - - // Variable reuse - if (mobj->floorz > mobj->z) - dist = (mobj->floorz - mobj->tracer->z); - else if (mobj->ceilingz < mobj->z) - dist = (mobj->ceilingz - mobj->tracer->z); - else - return; - - if ((dist = FixedDiv(dist, v[2])) > FRACUNIT) - return; - - radius = FixedMul(radius, dist); - donetwice = true; - dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); - goto maceretry;*/ } static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) @@ -9757,10 +9772,10 @@ void P_SpawnMapThing(mapthing_t *mthing) case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: { - fixed_t mlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mnumspokesset, mpinch, mroll, mnumnospokes, mwidth, mmin, msound, radiusfactor; + fixed_t mlength, mlengthmax, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor; angle_t mspokeangle; mobjtype_t chainlink, macetype, firsttype, linktype; - boolean mdoall = true; + boolean mdoall = true, mdocenter; mobj_t *spawnee, *hprev; mobjflag_t mflagsapply; mobjflag2_t mflags2apply; @@ -9798,7 +9813,7 @@ ML_EFFECT4 : Don't clip inside the ground mlength = abs(lines[line].dx >> FRACBITS); mspeed = abs(lines[line].dy >> (FRACBITS - 4)); mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; - if ((mminlength = sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0) + if ((mminlength = -sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0) mminlength = 0; mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; @@ -9931,7 +9946,7 @@ ML_EFFECT4 : Don't clip inside the ground P_SetTarget(&spawnee->tracer, mobj);\ spawnee->threshold = mphase;\ spawnee->friction = mroll;\ - spawnee->movefactor = mwidth;\ + spawnee->movefactor = mwidthset;\ spawnee->movecount = dist;\ spawnee->angle = myaw;\ spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ @@ -9941,14 +9956,10 @@ ML_EFFECT4 : Don't clip inside the ground P_SetTarget(&spawnee->hprev, hprev);\ hprev = spawnee -domaceagain: - mnumspokesset = mnumspokes; - - if (mdoall && lines[line].flags & ML_EFFECT3) // Innermost mace/link - { spawnee = makemace(macetype, 0, MF2_AMBUSH); } + mdocenter = (lines[line].flags & ML_EFFECT3); // The actual spawning of spokes - while (mnumspokesset-- > 0) + while (mnumspokes-- > 0) { // Offsets if (lines[line].flags & ML_EFFECT1) // Swinging @@ -9956,13 +9967,13 @@ domaceagain: else // Spinning mphase = (mphase - mspokeangle) & FINEMASK; - if (mnumnospokes && !(mnumspokesset % mnumnospokes)) // Skipping a "missing" spoke + if (mnumnospokes && !(mnumspokes % mnumnospokes)) // Skipping a "missing" spoke { if (mobj->type != MT_CHAINMACEPOINT) continue; firsttype = linktype = chainlink; - mlengthset = 1 + (mlength - 1)*radiusfactor; + mlengthmax = 1 + (mlength - 1)*radiusfactor; radiusfactor = 1; } else @@ -9984,34 +9995,44 @@ domaceagain: firsttype = macetype; } - mlengthset = mlength; + mlengthmax = mlength; } - // Outermost mace/link - spawnee = makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); + mwidthset = mwidth; + mdoall = true; + while (1) + { + mlengthset = mlengthmax; - if (mspeed && (mwidth == msound) && !(mthing->options & MTF_OBJECTSPECIAL) && mnumspokesset <= mmin) // Can it make a sound? - spawnee->flags2 |= MF2_BOSSNOTRAP; + if (mdocenter) // Innermost mace/link + { + spawnee = makemace(macetype, 0, 0); + } - if (!mdoall || !linktype) - continue; + // Outermost mace/link + spawnee = makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); - // The rest of the links - while (mlengthset > mminlength) - { spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); } - } + if (mspeed && (mwidthset == msound) && !(mthing->options & MTF_OBJECTSPECIAL) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; - if (mwidth > 0) - { - mwidth *= -1; - goto domaceagain; - } - else if (mwidth != 0) - { - if ((mwidth = -(mwidth + ((firsttype == chainlink) ? 1 : 2))) < 0) - break; - mdoall = false; - goto domaceagain; + if (mdoall && linktype) + { + // The rest of the links + while (mlengthset > mminlength) + { + spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); + } + } + + if (mwidthset > 0) + mwidthset *= -1; + else if (!mwidthset + || ((mwidthset = -(mwidthset + ((firsttype == chainlink) ? 1 : 2))) < 0)) + break; + else + mdocenter = mdoall = false; + + } } #undef makemace From 0102da824e462a344ef38c8a868bbe51a3eaea78 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 2 Apr 2018 01:20:32 +0100 Subject: [PATCH 59/66] Make the h-chain repairing safer. --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index f98943d84..4e1356d61 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8673,9 +8673,9 @@ void P_RemoveMobj(mobj_t *mobj) // Remove any references to other mobjs. P_SetTarget(&mobj->target, P_SetTarget(&mobj->tracer, NULL)); - if (mobj->hnext) + if (mobj->hnext && !P_MobjWasRemoved(mobj->hnext)) P_SetTarget(&mobj->hnext->hprev, mobj->hprev); - if (mobj->hprev) + if (mobj->hprev && !P_MobjWasRemoved(mobj->hprev)) P_SetTarget(&mobj->hprev->hnext, mobj->hnext); P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL)); From 4051ae8915525d850b754ee12e3e6895ffdfa509 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 2 Apr 2018 21:36:12 +0100 Subject: [PATCH 60/66] * Revamp mace creation again to potentially serve as the foundation for further optimisation (and also not rely on a while (1) loop, which easily went wrong several times whilst I was making changes to it). * Fix minor typoes and other small tweaks in the P_MaceRotate function, which I'm probably about to rewrite again anyways... --- src/p_mobj.c | 123 +++++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 59 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4e1356d61..63d3aa666 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6184,8 +6184,7 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) TVector *res; fixed_t radius, dist, mag, zstore; angle_t fa; - boolean donetwice = false; - boolean dosound = false; + boolean donetwice, dosound = false; mobj_t *mobj = center->hnext, *hnext = NULL; INT32 rot = (baserot &= FINEMASK); @@ -6268,13 +6267,13 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) if (!baseuo[3]) { baseuo[1] = FRACUNIT; - baseuo[3] = center->scale; baseuo[0] = baseuo[2] = 0; + baseuo[3] = center->scale; res = VectorMatrixMultiply(baseuo, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); - M_Memcpy(&baseuo, res, sizeof(unit)); + M_Memcpy(&baseuo, res, sizeof(baseuo)); res = VectorMatrixMultiply(baseuo, *RotateZMatrix(center->angle)); - M_Memcpy(&baseuo, res, sizeof(unit)); + M_Memcpy(&baseuo, res, sizeof(baseuo)); } if (mobj->movefactor) @@ -6293,6 +6292,7 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) // Radius of the link's rotation. mag = (dist * mobj->movecount) + mobj->extravalue1; + donetwice = false; maceretry: P_UnsetThingPosition(mobj); @@ -6303,13 +6303,12 @@ maceretry: // Add on the appropriate distances to the center's co-ordinates. if (mag) { - zstore = FixedMul(unit[2], mag); mobj->x += FixedMul(unit[0], mag); mobj->y += FixedMul(unit[1], mag); + zstore = FixedMul(unit[2], mag) + unitoffset[2]; } else - zstore = 0; - zstore += unitoffset[2]; + zstore = unitoffset[2]; mobj->x += unitoffset[0]; mobj->y += unitoffset[1]; @@ -6323,7 +6322,7 @@ maceretry: mobj->z += zstore; #if 0 // toaster's testing flashie! - if (!mobj->threshold && !mobj->friction && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. + if (!donetwice && mobj->movefactor != -5 && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. mobj->flags2 ^= MF2_DONTDRAW; #endif @@ -9772,11 +9771,11 @@ void P_SpawnMapThing(mapthing_t *mthing) case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: { - fixed_t mlength, mlengthmax, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor; + fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor; angle_t mspokeangle; mobjtype_t chainlink, macetype, firsttype, linktype; - boolean mdoall = true, mdocenter; - mobj_t *spawnee, *hprev; + boolean mdosound, mdocenter; + mobj_t *spawnee = NULL, *hprev = mobj; mobjflag_t mflagsapply; mobjflag2_t mflags2apply; mobjeflag_t meflagsapply; @@ -9815,6 +9814,8 @@ ML_EFFECT4 : Don't clip inside the ground mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; if ((mminlength = -sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0) mminlength = 0; + else if (mminlength > mlength-1) + mminlength = mlength-1; mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; @@ -9940,22 +9941,23 @@ ML_EFFECT4 : Don't clip inside the ground mphase = (FixedAngle(mphase*FRACUNIT)>>ANGLETOFINESHIFT); mroll = (FixedAngle(mroll*FRACUNIT)>>ANGLETOFINESHIFT); - hprev = mobj; - -#define makemace(mobjtype, dist, moreflags2) P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ - P_SetTarget(&spawnee->tracer, mobj);\ - spawnee->threshold = mphase;\ - spawnee->friction = mroll;\ - spawnee->movefactor = mwidthset;\ - spawnee->movecount = dist;\ - spawnee->angle = myaw;\ - spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ - spawnee->flags2 |= (mflags2apply|moreflags2);\ - spawnee->eflags |= meflagsapply;\ - P_SetTarget(&hprev->hnext, spawnee);\ - P_SetTarget(&spawnee->hprev, hprev);\ - hprev = spawnee +#define makemace(mobjtype, dist, moreflags2) {\ + spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ + P_SetTarget(&spawnee->tracer, mobj);\ + spawnee->threshold = mphase;\ + spawnee->friction = mroll;\ + spawnee->movefactor = mwidthset;\ + spawnee->movecount = dist;\ + spawnee->angle = myaw;\ + spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ + spawnee->flags2 |= (mflags2apply|moreflags2);\ + spawnee->eflags |= meflagsapply;\ + P_SetTarget(&hprev->hnext, spawnee);\ + P_SetTarget(&spawnee->hprev, hprev);\ + hprev = spawnee;\ +} + mdosound = (mspeed && !(mthing->options & MTF_OBJECTSPECIAL)); mdocenter = (lines[line].flags & ML_EFFECT3); // The actual spawning of spokes @@ -9973,7 +9975,7 @@ ML_EFFECT4 : Don't clip inside the ground continue; firsttype = linktype = chainlink; - mlengthmax = 1 + (mlength - 1)*radiusfactor; + mmaxlength = 1 + (mlength - 1)*radiusfactor; radiusfactor = 1; } else @@ -9995,43 +9997,46 @@ ML_EFFECT4 : Don't clip inside the ground firsttype = macetype; } - mlengthmax = mlength; + mmaxlength = mlength; } mwidthset = mwidth; - mdoall = true; - while (1) + //fixed_t base = 0; + mlengthset = mminlength; + + if (mdocenter) // Innermost mace/link + makemace(macetype, 0, 0); + + //base = mlengthset*((mobjinfo[macetype].speed) ? mobjinfo[macetype].speed : mobjinfo[MT_SMALLMACECHAIN].speed); + + while ((++mlengthset) < mmaxlength) + makemace(linktype, radiusfactor*mlengthset, 0); + + // Outermost mace/link + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + + if (!mwidth) { - mlengthset = mlengthmax; + if (mdosound && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + else + { + while ((mwidthset -= ((firsttype == chainlink) ? 1 : 2)) > -mwidth) + { + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + + // Outermost mace/link again! + makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); + + while (mlengthset > mminlength) + makemace(linktype, radiusfactor*(mlengthset--), 0); if (mdocenter) // Innermost mace/link - { - spawnee = makemace(macetype, 0, 0); - } - - // Outermost mace/link - spawnee = makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); - - if (mspeed && (mwidthset == msound) && !(mthing->options & MTF_OBJECTSPECIAL) && mnumspokes <= mmin) // Can it make a sound? - spawnee->flags2 |= MF2_BOSSNOTRAP; - - if (mdoall && linktype) - { - // The rest of the links - while (mlengthset > mminlength) - { - spawnee = makemace(linktype, radiusfactor*(mlengthset--), 0); - } - } - - if (mwidthset > 0) - mwidthset *= -1; - else if (!mwidthset - || ((mwidthset = -(mwidthset + ((firsttype == chainlink) ? 1 : 2))) < 0)) - break; - else - mdocenter = mdoall = false; - + makemace(macetype, 0, 0); } } From 156cc031ea22d59296644c7f5d2c836746ad0937 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 3 Apr 2018 01:10:10 +0100 Subject: [PATCH 61/66] * Optimise them even further... AGAIN! Using an offset-based system rather than a multiplication-based one... * Again, tweak the spawning code to take maximum advantage of these gains. * Fix potential crashes with MT_NULL mace/chain types supplied. * #ifdef out the height-clipping code. It needs more TLC than I can give it right now, and the existing behaviour is less obviously broken (sadly enough). * Fix chainmace points, which were apparently broken without anyone realising. --- src/p_mobj.c | 203 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 129 insertions(+), 74 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 63d3aa666..286357964 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6180,11 +6180,11 @@ static void P_NightsItemChase(mobj_t *thing) // void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) { - TVector unit, baseuo, unitoffset; + TVector unit_lengthways, unit_sideways, pos_lengthways, pos_sideways; TVector *res; - fixed_t radius, dist, mag, zstore; + fixed_t radius, dist, zstore; angle_t fa; - boolean donetwice, dosound = false; + boolean dosound = false; mobj_t *mobj = center->hnext, *hnext = NULL; INT32 rot = (baserot &= FINEMASK); @@ -6193,7 +6193,7 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) INT32 lastthreshold = FINEMASK; // needs to never be equal at start of loop fixed_t lastfriction = INT32_MIN; // ditto; almost certainly never, but... - fixed_t movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = baseuo[3] = 0; + dist = pos_sideways[0] = pos_sideways[1] = pos_sideways[2] = pos_sideways[3] = unit_sideways[3] = pos_lengthways[0] = pos_lengthways[1] = pos_lengthways[2] = pos_lengthways[3] = 0; while (mobj) { @@ -6211,10 +6211,15 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) rot = (baserot + mobj->threshold) & FINEMASK; prevrot = (baseprevrot + mobj->threshold) & FINEMASK; - fa = (FixedAngle(center->movefactor*FRACUNIT) >> ANGLETOFINESHIFT); // mpinch - radius = FINECOSINE(fa); - unit[1] = -FixedMul(FINESINE(fa), radius); - unit[3] = center->scale; + pos_lengthways[0] = pos_lengthways[1] = pos_lengthways[2] = pos_lengthways[3] = 0; + + dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); + dist = ((center->scale == FRACUNIT) ? dist : FixedMul(dist, center->scale)); + + fa = (FixedAngle(center->movefactor*FRACUNIT) >> ANGLETOFINESHIFT); + radius = FixedMul(dist, FINECOSINE(fa)); + unit_lengthways[1] = -FixedMul(dist, FINESINE(fa)); + unit_lengthways[3] = FRACUNIT; // Swinging Chain. if (center->flags2 & MF2_STRONGBOX) @@ -6224,12 +6229,11 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) if ((prevswingmag > 0) != (swingmag > 0)) // just passed its lowest point dosound = true; - //S_StartSound(mobj, mobj->info->activesound); fa = ((FixedAngle(swingmag) >> ANGLETOFINESHIFT) + mobj->friction) & FINEMASK; - unit[0] = FixedMul(FINESINE(fa), -radius); - unit[2] = FixedMul(FINECOSINE(fa), -radius); + unit_lengthways[0] = FixedMul(FINESINE(fa), -radius); + unit_lengthways[2] = FixedMul(FINECOSINE(fa), -radius); } // Rotating Chain. else @@ -6240,15 +6244,15 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) if (!(prevfa > (FINEMASK/2)) && (fa > (FINEMASK/2))) // completed a full swing dosound = true; - unit[0] = FixedMul(FINECOSINE(fa), radius); - unit[2] = FixedMul(FINESINE(fa), radius); + unit_lengthways[0] = FixedMul(FINECOSINE(fa), radius); + unit_lengthways[2] = FixedMul(FINESINE(fa), radius); } // Calculate the angle matrixes for the link. - res = VectorMatrixMultiply(unit, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); - M_Memcpy(&unit, res, sizeof(unit)); - res = VectorMatrixMultiply(unit, *RotateZMatrix(center->angle)); - M_Memcpy(&unit, res, sizeof(unit)); + res = VectorMatrixMultiply(unit_lengthways, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&unit_lengthways, res, sizeof(unit_lengthways)); + res = VectorMatrixMultiply(unit_lengthways, *RotateZMatrix(center->angle)); + M_Memcpy(&unit_lengthways, res, sizeof(unit_lengthways)); lastthreshold = mobj->threshold; lastfriction = mobj->friction; @@ -6260,40 +6264,65 @@ void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot) dosound = false; } - dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); - - if (dist*mobj->movefactor != movefac) + if (pos_sideways[3] != mobj->movefactor) { - if (!baseuo[3]) + if (!unit_sideways[3]) { - baseuo[1] = FRACUNIT; - baseuo[0] = baseuo[2] = 0; - baseuo[3] = center->scale; + unit_sideways[1] = dist; + unit_sideways[0] = unit_sideways[2] = 0; + unit_sideways[3] = FRACUNIT; - res = VectorMatrixMultiply(baseuo, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); - M_Memcpy(&baseuo, res, sizeof(baseuo)); - res = VectorMatrixMultiply(baseuo, *RotateZMatrix(center->angle)); - M_Memcpy(&baseuo, res, sizeof(baseuo)); + res = VectorMatrixMultiply(unit_sideways, *RotateXMatrix(center->threshold << ANGLETOFINESHIFT)); + M_Memcpy(&unit_sideways, res, sizeof(unit_sideways)); + res = VectorMatrixMultiply(unit_sideways, *RotateZMatrix(center->angle)); + M_Memcpy(&unit_sideways, res, sizeof(unit_sideways)); } - if (mobj->movefactor) + if (pos_sideways[3] > mobj->movefactor) { - movefac = dist*mobj->movefactor; - unitoffset[0] = FixedMul(movefac, baseuo[0]); - unitoffset[1] = FixedMul(movefac, baseuo[1]); - unitoffset[2] = FixedMul(movefac, baseuo[2]); + do + { + pos_sideways[0] -= unit_sideways[0]; + pos_sideways[1] -= unit_sideways[1]; + pos_sideways[2] -= unit_sideways[2]; + } + while ((--pos_sideways[3]) != mobj->movefactor); } else - movefac = unitoffset[0] = unitoffset[1] = unitoffset[2] = 0; + { + do + { + pos_sideways[0] += unit_sideways[0]; + pos_sideways[1] += unit_sideways[1]; + pos_sideways[2] += unit_sideways[2]; + } + while ((++pos_sideways[3]) != mobj->movefactor); + } } hnext = mobj->hnext; // just in case the mobj is removed - // Radius of the link's rotation. - mag = (dist * mobj->movecount) + mobj->extravalue1; + if (pos_lengthways[3] > mobj->movecount) + { + do + { + pos_lengthways[0] -= unit_lengthways[0]; + pos_lengthways[1] -= unit_lengthways[1]; + pos_lengthways[2] -= unit_lengthways[2]; + } + while ((--pos_lengthways[3]) != mobj->movecount); + } + else if (pos_lengthways[3] < mobj->movecount) + { + do + { + pos_lengthways[0] += unit_lengthways[0]; + pos_lengthways[1] += unit_lengthways[1]; + pos_lengthways[2] += unit_lengthways[2]; + } + while ((++pos_lengthways[3]) != mobj->movecount); + } - donetwice = false; -maceretry: P_UnsetThingPosition(mobj); mobj->x = center->x; @@ -6301,17 +6330,17 @@ maceretry: mobj->z = center->z; // Add on the appropriate distances to the center's co-ordinates. - if (mag) + if (pos_lengthways[3]) { - mobj->x += FixedMul(unit[0], mag); - mobj->y += FixedMul(unit[1], mag); - zstore = FixedMul(unit[2], mag) + unitoffset[2]; + mobj->x += pos_lengthways[0]; + mobj->y += pos_lengthways[1]; + zstore = pos_lengthways[2] + pos_sideways[2]; } else - zstore = unitoffset[2]; + zstore = pos_sideways[2]; - mobj->x += unitoffset[0]; - mobj->y += unitoffset[1]; + mobj->x += pos_sideways[0]; + mobj->y += pos_sideways[1]; // Cut the height to align the link with the axis. if (mobj->type == MT_SMALLMACECHAIN || mobj->type == MT_BIGMACECHAIN) @@ -6322,41 +6351,40 @@ maceretry: mobj->z += zstore; #if 0 // toaster's testing flashie! - if (!donetwice && mobj->movefactor != -5 && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. + if (!(mobj->movecount & 1) && !(leveltime & TICRATE)) // I had a brainfart and the flashing isn't exactly what I expected it to be, but it's actually much more useful. mobj->flags2 ^= MF2_DONTDRAW; #endif P_SetThingPosition(mobj); - if (!mag || donetwice || P_MobjWasRemoved(mobj)) +#if 0 // toaster's height-clipping dealie! + if (!pos_lengthways[3] || P_MobjWasRemoved(mobj) || (mobj->flags & MF_NOCLIPHEIGHT)) goto cont; - if (mobj->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) - goto cont; - - if ((fa = ((mobj->tracer->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it + if ((fa = ((center->threshold & (FINEMASK/2)) << ANGLETOFINESHIFT)) > ANGLE_45 && fa < ANGLE_135) // only move towards center when the motion is towards/away from the ground, rather than alongside it goto cont; if (mobj->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 2); - // Variable reuse if (mobj->floorz > mobj->z) - dist = (mobj->floorz - mobj->tracer->z); + zstore = (mobj->floorz - zstore); else if (mobj->ceilingz < mobj->z) - dist = (mobj->ceilingz - mobj->tracer->z); + zstore = (mobj->ceilingz - mobj->height - zstore); else goto cont; - if ((dist = FixedDiv(dist, zstore)) > FRACUNIT) - goto cont; + zstore = FixedDiv(zstore, dist); // Still needs work... scaling factor is wrong! - mag = FixedMul(mag, dist); - donetwice = true; - dist = ((mobj->info->speed) ? mobj->info->speed : mobjinfo[MT_SMALLMACECHAIN].speed); - goto maceretry; + P_UnsetThingPosition(mobj); + + mobj->x -= FixedMul(unit_lengthways[0], zstore); + mobj->y -= FixedMul(unit_lengthways[1], zstore); + + P_SetThingPosition(mobj); cont: +#endif mobj = hnext; } } @@ -9771,7 +9799,7 @@ void P_SpawnMapThing(mapthing_t *mthing) case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: { - fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor; + fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor, widthfactor; angle_t mspokeangle; mobjtype_t chainlink, macetype, firsttype, linktype; boolean mdosound, mdocenter; @@ -9848,7 +9876,7 @@ ML_EFFECT4 : Don't clip inside the ground if (mnumnospokes > 0 && (mnumnospokes < mnumspokes)) mnumnospokes = mnumspokes/mnumnospokes; else - mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes - 1) : 0); + mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes) : 0); mobj->lastlook = mspeed; mobj->movecount = mobj->lastlook; @@ -9894,7 +9922,7 @@ ML_EFFECT4 : Don't clip inside the ground break; } - if (!macetype) + if (!macetype && !chainlink) break; if (mobj->type != MT_CHAINPOINT) @@ -9958,7 +9986,7 @@ ML_EFFECT4 : Don't clip inside the ground } mdosound = (mspeed && !(mthing->options & MTF_OBJECTSPECIAL)); - mdocenter = (lines[line].flags & ML_EFFECT3); + mdocenter = (macetype && (lines[line].flags & ML_EFFECT3)); // The actual spawning of spokes while (mnumspokes-- > 0) @@ -9999,6 +10027,7 @@ ML_EFFECT4 : Don't clip inside the ground mmaxlength = mlength; } + widthfactor = ((firsttype == chainlink) ? 1 : 2); mwidthset = mwidth; //fixed_t base = 0; @@ -10009,11 +10038,18 @@ ML_EFFECT4 : Don't clip inside the ground //base = mlengthset*((mobjinfo[macetype].speed) ? mobjinfo[macetype].speed : mobjinfo[MT_SMALLMACECHAIN].speed); - while ((++mlengthset) < mmaxlength) - makemace(linktype, radiusfactor*mlengthset, 0); + // Out from the center... + if (linktype) + { + while ((++mlengthset) < mmaxlength) + makemace(linktype, radiusfactor*mlengthset, 0); + } + else + mlengthset = mmaxlength; // Outermost mace/link - makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (firsttype) + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); if (!mwidth) { @@ -10022,18 +10058,37 @@ ML_EFFECT4 : Don't clip inside the ground } else { - while ((mwidthset -= ((firsttype == chainlink) ? 1 : 2)) > -mwidth) + // Across the bar! + if (!firsttype) + mwidthset = -mwidth; + else if (mwidth > 0) { - makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); - if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? - spawnee->flags2 |= MF2_BOSSNOTRAP; + while ((mwidthset -= widthfactor) > -mwidth) + { + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } } + else + { + while ((mwidthset += widthfactor) < -mwidth) + { + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + } + mwidth = -mwidth; // Outermost mace/link again! - makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); + if (firsttype) + makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); - while (mlengthset > mminlength) - makemace(linktype, radiusfactor*(mlengthset--), 0); + // ...and then back into the center! + if (linktype) + while (mlengthset > mminlength) + makemace(linktype, radiusfactor*(mlengthset--), 0); if (mdocenter) // Innermost mace/link makemace(macetype, 0, 0); From 4f3f647f5b31266445307a470a3f771bfe567721 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 3 Apr 2018 01:46:42 +0100 Subject: [PATCH 62/66] A minor assortment of changes. --- src/p_inter.c | 6 +++--- src/p_mobj.c | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 82187f533..88fa7d57b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1503,10 +1503,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->powers[pw_flashing]) return; - if (special->movefactor && special->tracer && (angle_t)special->tracer->angle != ANGLE_90 && (angle_t)special->tracer->angle != ANGLE_270) + if (special->movefactor && special->tracer && special->tracer->angle != ANGLE_90 && special->tracer->angle != ANGLE_270) { // I don't expect you to understand this, Mr Bond... - angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->threshold; - if ((special->movefactor > 0) == ((angle_t)special->tracer->angle > ANGLE_90 && (angle_t)special->tracer->angle < ANGLE_270)) + angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->angle; + if ((special->movefactor > 0) == (special->tracer->angle > ANGLE_90 && special->tracer->angle < ANGLE_270)) ang += ANGLE_180; if (ang < ANGLE_180) return; // I expect you to die. diff --git a/src/p_mobj.c b/src/p_mobj.c index 286357964..3660f1e5e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9959,6 +9959,8 @@ ML_EFFECT4 : Don't clip inside the ground else radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); + widthfactor = ((firsttype == chainlink) ? 1 : 2); + mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP|MF_NOCLIPHEIGHT)); mflags2apply = ((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0); meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0); @@ -10004,7 +10006,7 @@ ML_EFFECT4 : Don't clip inside the ground firsttype = linktype = chainlink; mmaxlength = 1 + (mlength - 1)*radiusfactor; - radiusfactor = 1; + radiusfactor = widthfactor = 1; } else { @@ -10023,21 +10025,18 @@ ML_EFFECT4 : Don't clip inside the ground } firsttype = macetype; + widthfactor = 2; } mmaxlength = mlength; } - widthfactor = ((firsttype == chainlink) ? 1 : 2); mwidthset = mwidth; - //fixed_t base = 0; mlengthset = mminlength; if (mdocenter) // Innermost mace/link makemace(macetype, 0, 0); - //base = mlengthset*((mobjinfo[macetype].speed) ? mobjinfo[macetype].speed : mobjinfo[MT_SMALLMACECHAIN].speed); - // Out from the center... if (linktype) { From 15903c6271e8c215a73ef3baa78015704b2ef3cf Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 6 Apr 2018 14:42:49 +0100 Subject: [PATCH 63/66] * Correct V_PERPLAYER's screen-centered (no snapto flags on a given axis) behaviour. * Fix that one comment Digiku mentioned. ;P * Make extra lives/100 ring rewards consistent between lives being relevant and lives being infinite/not present, which was a problem this branch made evident when Race ended up getting the infinite lives symbol! --- src/p_enemy.c | 9 +---- src/p_user.c | 44 +++++++++++++++++---- src/st_stuff.c | 2 +- src/v_video.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ src/y_inter.c | 11 +++--- 5 files changed, 145 insertions(+), 23 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 9acc8430e..331202cbe 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3243,14 +3243,7 @@ void A_ExtraLife(mobj_t *actor) return; } - // In shooter gametypes, give the player 100 rings instead of an extra life. - if (gametype != GT_COOP && gametype != GT_COMPETITION) - { - P_GivePlayerRings(player, 100); - P_PlayLivesJingle(player); - } - else - P_GiveCoopLives(player, 1, true); + P_GiveCoopLives(player, 1, true); } // Function: A_GiveShield diff --git a/src/p_user.c b/src/p_user.c index b3a8bcf4b..9fb9d4262 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -909,8 +909,12 @@ void P_ResetPlayer(player_t *player) // Gives rings to the player, and does any special things required. // Call this function when you want to increment the player's health. // + void P_GivePlayerRings(player_t *player, INT32 num_rings) { + if (!player) + return; + if (player->bot) player = &players[consoleplayer]; @@ -929,7 +933,7 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) player->rings = 0; // Now extra life bonuses are handled here instead of in P_MovePlayer, since why not? - if (!ultimatemode && !modeattacking && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives()) + if (!ultimatemode && !modeattacking && !G_IsSpecialStage(gamemap) && G_GametypeUsesLives() && player->lives != 0x7f) { INT32 gainlives = 0; @@ -941,7 +945,12 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (gainlives) { - P_GivePlayerLives(player, gainlives); + player->lives += gainlives; + if (player->lives > 99) + player->lives = 99; + else if (player->lives < 1) + player->lives = 1; + P_PlayLivesJingle(player); } } @@ -955,7 +964,30 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) // void P_GivePlayerLives(player_t *player, INT32 numlives) { - if (player->lives == 0x7f) return; + if (!player) + return; + + if (player->bot) + player = &players[consoleplayer]; + + if (gamestate == GS_LEVEL) + { + if (player->lives == 0x7f || (gametype != GT_COOP && gametype != GT_COMPETITION)) + { + P_GivePlayerRings(player, 100*numlives); + return; + } + + if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) + { + UINT8 prevlives = player->lives; + P_GivePlayerRings(player, 100*numlives); + if (player->lives - prevlives >= numlives) + return; + + numlives = (numlives + prevlives - player->lives); + } + } player->lives += numlives; @@ -1159,11 +1191,7 @@ void P_PlayLivesJingle(player_t *player) if (player && !P_IsLocalPlayer(player)) return; - if ((player && player->lives == 0x7f) - || (!player && &players[consoleplayer] && players[consoleplayer].lives == 0x7f) - || (gametype == GT_COOP && (netgame || multiplayer) && cv_cooplives.value == 0)) - S_StartSound(NULL, sfx_lose); - else if (use1upSound) + if (use1upSound) S_StartSound(NULL, sfx_oneup); else if (mariomode) S_StartSound(NULL, sfx_marioa); diff --git a/src/st_stuff.c b/src/st_stuff.c index 6a909580d..ab78595b4 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -776,7 +776,7 @@ static void ST_drawLivesArea(void) } else { - livescount = ((cv_cooplives.value == 0) ? 0x7f : stplyr->lives); + livescount = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0x7f : stplyr->lives); notgreyedout = true; } diff --git a/src/v_video.c b/src/v_video.c index d23e5f4f5..685cd053f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -542,6 +542,8 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t fixed_t pwidth; // patch width fixed_t offx = 0; // x offset + UINT8 perplayershuffle = 0; + if (rendermode == render_none) return; @@ -639,19 +641,37 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t colfrac <<= 1; x >>= 1; if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; scrn &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } else if (stplyr == &players[secondarydisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; } else if (stplyr == &players[thirddisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; y += adjusty; scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; } else //if (stplyr == &players[fourthdisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; y += adjusty; scrn &= ~V_SNAPTOTOP|V_SNAPTOLEFT; @@ -662,9 +682,15 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t // 2 players { if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle = 1; scrn &= ~V_SNAPTOBOTTOM; + } else //if (stplyr == &players[secondarydisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle = 2; y += adjusty; scrn &= ~V_SNAPTOTOP; } @@ -710,6 +736,10 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t x += (vid.width - (BASEVIDWIDTH * dupx)); else if (!(scrn & V_SNAPTOLEFT)) x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + if (perplayershuffle & 4) + x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4; + else if (perplayershuffle & 8) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 4; } if (vid.height != BASEVIDHEIGHT * dupy) { @@ -718,6 +748,10 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + if (perplayershuffle & 1) + y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4; + else if (perplayershuffle & 2) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4; } } @@ -792,6 +826,8 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ UINT8 *desttop, *dest; const UINT8 *source, *deststop; + UINT8 perplayershuffle = 0; + if (rendermode == render_none) return; @@ -852,21 +888,39 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ sx >>= 1; w >>= 1; if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; scrn &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } else if (stplyr == &players[secondarydisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; sx += adjustx; scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; } else if (stplyr == &players[thirddisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; y += adjusty; sy += adjusty; scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; } else //if (stplyr == &players[fourthdisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; sx += adjustx; y += adjusty; @@ -879,9 +933,15 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ // 2 players { if (stplyr == &players[displayplayer]) + { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; scrn &= ~V_SNAPTOBOTTOM; + } else //if (stplyr == &players[secondarydisplayplayer]) { + if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; y += adjusty; sy += adjusty; scrn &= ~V_SNAPTOTOP; @@ -927,6 +987,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ x += (vid.width - (BASEVIDWIDTH * dupx)); else if (!(scrn & V_SNAPTOLEFT)) x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + if (perplayershuffle & 4) + x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4; + else if (perplayershuffle & 8) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 4; } if (vid.height != BASEVIDHEIGHT * dupy) { @@ -935,6 +999,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(scrn & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + if (perplayershuffle & 1) + y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4; + else if (perplayershuffle & 2) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4; } } @@ -1081,6 +1149,8 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) UINT8 *dest; const UINT8 *deststop; + UINT8 perplayershuffle = 0; + if (rendermode == render_none) return; @@ -1104,19 +1174,37 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) w >>= 1; x >>= 1; if (stplyr == &players[displayplayer]) + { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; c &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } else if (stplyr == &players[secondarydisplayplayer]) { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; c &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; } else if (stplyr == &players[thirddisplayplayer]) { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; y += adjusty; c &= ~V_SNAPTOTOP|V_SNAPTORIGHT; } else //if (stplyr == &players[fourthdisplayplayer]) { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(c & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; x += adjustx; y += adjusty; c &= ~V_SNAPTOTOP|V_SNAPTOLEFT; @@ -1127,9 +1215,15 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) // 2 players { if (stplyr == &players[displayplayer]) + { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; c &= ~V_SNAPTOBOTTOM; + } else //if (stplyr == &players[secondarydisplayplayer]) { + if (!(c & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; y += adjusty; c &= ~V_SNAPTOTOP; } @@ -1160,6 +1254,10 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) x += (vid.width - (BASEVIDWIDTH * dupx)); else if (!(c & V_SNAPTOLEFT)) x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + if (perplayershuffle & 4) + x -= (vid.width - (BASEVIDWIDTH * dupx)) / 4; + else if (perplayershuffle & 8) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 4; } if (vid.height != BASEVIDHEIGHT * dupy) { @@ -1168,6 +1266,10 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) y += (vid.height - (BASEVIDHEIGHT * dupy)); else if (!(c & V_SNAPTOTOP)) y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2; + if (perplayershuffle & 1) + y -= (vid.height - (BASEVIDHEIGHT * dupy)) / 4; + else if (perplayershuffle & 2) + y += (vid.height - (BASEVIDHEIGHT * dupy)) / 4; } } diff --git a/src/y_inter.c b/src/y_inter.c index c86dee758..ed9cc4185 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -858,7 +858,7 @@ void Y_Ticker(void) tallydonetic = -1; } - if (intertic < 2*TICRATE) // one second pause before tally begins + if (intertic < 2*TICRATE) // TWO second pause before tally begins, thank you mazmazz return; for (i = 0; i < MAXPLAYERS; i++) @@ -1822,13 +1822,13 @@ static void Y_AwardCoopBonuses(void) players[i].score = MAXSCORE; } - ptlives = (!ultimatemode && !modeattacking) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; + ptlives = (!ultimatemode && !modeattacking && players[i].lives != 0x7f) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; if (ptlives) P_GivePlayerLives(&players[i], ptlives); if (i == consoleplayer) { - data.coop.gotlife = ptlives; + data.coop.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives); M_Memcpy(&data.coop.bonuses, &localbonuses, sizeof(data.coop.bonuses)); } } @@ -1866,16 +1866,15 @@ static void Y_AwardSpecialStageBonus(void) players[i].score = MAXSCORE; // grant extra lives right away since tally is faked - ptlives = (!ultimatemode && !modeattacking) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; + ptlives = (!ultimatemode && !modeattacking && players[i].lives != 0x7f) ? max((players[i].score/50000) - (oldscore/50000), 0) : 0; if (ptlives) P_GivePlayerLives(&players[i], ptlives); if (i == consoleplayer) { + data.spec.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives); M_Memcpy(&data.spec.bonus, &localbonus, sizeof(data.spec.bonus)); - data.spec.gotlife = ptlives; - // Continues related data.spec.continues = min(players[i].continues, 8); if (players[i].gotcontinue) From 3f427d0161a79cfecb447269c873bb66bcd81e76 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 6 Apr 2018 18:40:08 +0100 Subject: [PATCH 64/66] * Improve devmode text. * Make sure showfps never covers anything relevant to the base game. * Tweak spectator text for raising/lowering. * Minor code-smell squishes. --- src/d_netcmd.c | 2 +- src/m_menu.c | 2 +- src/screen.c | 8 +- src/st_stuff.c | 197 ++++++++++++++++++++++++++++++++----------------- 4 files changed, 137 insertions(+), 72 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index cc641b8b0..e01178155 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -313,7 +313,7 @@ static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Centiseconds"} consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE, timetic_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-person only"}, {2, "Always"}, {0, NULL}}; -consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display +consvar_t cv_powerupdisplay = {"powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/m_menu.c b/src/m_menu.c index 4857df104..f10c6b653 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1188,7 +1188,7 @@ static menuitem_t OP_VideoOptionsMenu[] = #endif {IT_HEADER, NULL, "Color Profile", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness (F11)", &cv_globalgamma, 36}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness (F11)", &cv_globalgamma,36}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_globalsaturation, 41}, {IT_SUBMENU|IT_STRING, NULL, "Advanced Settings...", &OP_ColorOptionsDef, 46}, diff --git a/src/screen.c b/src/screen.c index 5b16992c7..cd97b62fa 100644 --- a/src/screen.c +++ b/src/screen.c @@ -414,7 +414,7 @@ void SCR_DisplayTicRate(void) tic_t ontic = I_GetTime(); tic_t totaltics = 0; INT32 ticcntcolor = 0; - INT32 offs = (cv_debug ? 8 : 0); + const INT32 h = vid.height-(8*vid.dupy); for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i) fpsgraph[i % TICRATE] = false; @@ -428,9 +428,9 @@ void SCR_DisplayTicRate(void) if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP; else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP; - V_DrawString(vid.width-((24+(6*offs))*vid.dupx), vid.height-((16-offs)*vid.dupy), - V_YELLOWMAP|V_NOSCALESTART, "FPS"); - V_DrawString(vid.width-(40*vid.dupx), vid.height-(8*vid.dupy), + V_DrawString(vid.width-(72*vid.dupx), h, + V_YELLOWMAP|V_NOSCALESTART, "FPS:"); + V_DrawString(vid.width-(40*vid.dupx), h, ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE)); lasttic = ontic; diff --git a/src/st_stuff.c b/src/st_stuff.c index ab78595b4..3b07d375e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -453,80 +453,145 @@ static void ST_DrawNightsOverlayNum(fixed_t x /* right border */, fixed_t y, fix // Devmode information static void ST_drawDebugInfo(void) { - INT32 height = 192; + INT32 height = 0; if (!(stplyr->mo && cv_debug)) return; - if (cv_ticrate.value) - height -= 12; +#define VFLAGS V_MONOSPACE|V_SNAPTOTOP|V_SNAPTORIGHT -#define dist 4 -#define VFLAGS V_MONOSPACE|V_SNAPTOBOTTOM|V_SNAPTORIGHT - - if (cv_debug & DBG_BASIC) + if (vid.dupx == 1) { - const fixed_t d = AngleFixed(stplyr->mo->angle); - V_DrawRightAlignedString(320, height - 24, VFLAGS, va("X: %6d", stplyr->mo->x>>FRACBITS)); - V_DrawRightAlignedString(320, height - 16, VFLAGS, va("Y: %6d", stplyr->mo->y>>FRACBITS)); - V_DrawRightAlignedString(320, height - 8, VFLAGS, va("Z: %6d", stplyr->mo->z>>FRACBITS)); - V_DrawRightAlignedString(320, height, VFLAGS, va("A: %6d", FixedInt(d))); + if (cv_debug & DBG_BASIC) + { + const fixed_t d = AngleFixed(stplyr->mo->angle); + V_DrawRightAlignedString(320, 0, VFLAGS, va("X: %6d", stplyr->mo->x>>FRACBITS)); + V_DrawRightAlignedString(320, 8, VFLAGS, va("Y: %6d", stplyr->mo->y>>FRACBITS)); + V_DrawRightAlignedString(320, 16, VFLAGS, va("Z: %6d", stplyr->mo->z>>FRACBITS)); + V_DrawRightAlignedString(320, 24, VFLAGS, va("A: %6d", FixedInt(d))); - height -= (32+dist); + height += 4*9; + } + + if (cv_debug & (DBG_MEMORY|DBG_RANDOMIZER|DBG_DETAILED)) + { + V_DrawRightAlignedThinString(320, height, VFLAGS|V_REDMAP, "INFO NOT AVAILABLE"); + V_DrawRightAlignedThinString(320, 8+height, VFLAGS|V_REDMAP, "AT THIS RESOLUTION"); + } + } + else + { +#define h 4 +#define dist 2 +#define V_DrawDebugLine(str) V_DrawRightAlignedSmallString(320, height, VFLAGS, str);\ + height += h + + if (cv_debug & DBG_MEMORY) + { + V_DrawDebugLine(va("Heap: %8sKB", sizeu1(Z_TotalUsage()>>10))); + + height += dist; + } + + if (cv_debug & DBG_RANDOMIZER) // randomizer testing + { + fixed_t peekres = P_RandomPeek(); + peekres *= 10000; // Change from fixed point + peekres >>= FRACBITS; // to displayable decimal + + V_DrawDebugLine(va("Init: %08x", P_GetInitSeed())); + V_DrawDebugLine(va("Seed: %08x", P_GetRandSeed())); + V_DrawDebugLine(va("== : .%04d", peekres)); + + height += dist; + } + + if (cv_debug & DBG_DETAILED) + { +#define V_DrawDebugFlag(f, str) V_DrawRightAlignedSmallString(w, height, VFLAGS|f, str);\ + w -= 9 + const fixed_t d = AngleFixed(stplyr->drawangle); + INT32 w = 320; + + V_DrawDebugLine(va("SHIELD: %5x", stplyr->powers[pw_shield])); + V_DrawDebugLine(va("SCALE: %5d%%", (stplyr->mo->scale*100)>>FRACBITS)); + V_DrawDebugLine(va("CARRY: %5x", stplyr->powers[pw_carry])); + V_DrawDebugLine(va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); + V_DrawDebugLine(va("ABILITY: %3d, %3d", stplyr->charability, stplyr->charability2)); + V_DrawDebugLine(va("ACTIONSPD: %5d", stplyr->actionspd>>FRACBITS)); + V_DrawDebugLine(va("PEEL: %3d", stplyr->dashmode)); + V_DrawDebugLine(va("SCOREADD: %3d", stplyr->scoreadd)); + + // Flags + V_DrawDebugFlag(((stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP), "SH"); + V_DrawDebugFlag(((stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP), "TH"); + V_DrawDebugFlag(((stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP), "ST"); + V_DrawDebugFlag(((stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP), "SP"); + V_DrawDebugFlag(((stplyr->pflags & PF_NOJUMPDAMAGE) ? V_GREENMAP : V_REDMAP), "ND"); + V_DrawDebugFlag(((stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP), "JD"); + V_DrawDebugFlag(((stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP), "SJ"); + V_DrawDebugFlag(0, "PF/SF:"); + height += h; + w = 320; + V_DrawDebugFlag(((stplyr->pflags & PF_INVIS) ? V_GREENMAP : V_REDMAP), "*I"); + V_DrawDebugFlag(((stplyr->pflags & PF_NOCLIP) ? V_GREENMAP : V_REDMAP), "*C"); + V_DrawDebugFlag(((stplyr->pflags & PF_GODMODE) ? V_GREENMAP : V_REDMAP), "*G"); + V_DrawDebugFlag(((stplyr->charflags & SF_SUPER) ? V_GREENMAP : V_REDMAP), "SU"); + V_DrawDebugFlag(((stplyr->pflags & PF_APPLYAUTOBRAKE) ? V_GREENMAP : V_REDMAP), "AA"); + V_DrawDebugFlag(((stplyr->pflags & PF_SLIDING) ? V_GREENMAP : V_REDMAP), "SL"); + V_DrawDebugFlag(((stplyr->pflags & PF_BOUNCING) ? V_GREENMAP : V_REDMAP), "BO"); + V_DrawDebugFlag(((stplyr->pflags & PF_GLIDING) ? V_GREENMAP : V_REDMAP), "GL"); + height += h; + + V_DrawDebugLine(va("CEILINGZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); + V_DrawDebugLine(va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); + + V_DrawDebugLine(va("CMOMX: %6d", stplyr->cmomx>>FRACBITS)); + V_DrawDebugLine(va("CMOMY: %6d", stplyr->cmomy>>FRACBITS)); + V_DrawDebugLine(va("PMOMZ: %6d", stplyr->mo->pmomz>>FRACBITS)); + + w = 320; + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_APPLYPMOMZ) ? V_GREENMAP : V_REDMAP), "AP"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_SPRUNG) ? V_GREENMAP : V_REDMAP), "SP"); + //V_DrawDebugFlag(((stplyr->mo->eflags & MFE_PUSHED) ? V_GREENMAP : V_REDMAP), "PU"); -- not relevant to players + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_GOOWATER) ? V_GREENMAP : V_REDMAP), "GW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_VERTICALFLIP) ? V_GREENMAP : V_REDMAP), "VF"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTSTEPPEDDOWN) ? V_GREENMAP : V_REDMAP), "JS"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_UNDERWATER) ? V_GREENMAP : V_REDMAP), "UW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_TOUCHWATER) ? V_GREENMAP : V_REDMAP), "TW"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_JUSTHITFLOOR) ? V_GREENMAP : V_REDMAP), "JH"); + V_DrawDebugFlag(((stplyr->mo->eflags & MFE_ONGROUND) ? V_GREENMAP : V_REDMAP), "OG"); + V_DrawDebugFlag(0, "MFE:"); + height += h; + + V_DrawDebugLine(va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); + V_DrawDebugLine(va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); + V_DrawDebugLine(va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); + + V_DrawDebugLine(va("SPEED: %6d", stplyr->speed>>FRACBITS)); + + V_DrawDebugLine(va("DRAWANGLE: %6d", FixedInt(d))); + + height += dist; +#undef V_DrawDebugFlag + } + + if (cv_debug & DBG_BASIC) + { + const fixed_t d = AngleFixed(stplyr->mo->angle); + V_DrawDebugLine(va("X: %6d", stplyr->mo->x>>FRACBITS)); + V_DrawDebugLine(va("Y: %6d", stplyr->mo->y>>FRACBITS)); + V_DrawDebugLine(va("Z: %6d", stplyr->mo->z>>FRACBITS)); + V_DrawDebugLine(va("A: %6d", FixedInt(d))); + + //height += dist; + } } - if (cv_debug & DBG_DETAILED) - { - V_DrawRightAlignedString(320, height - 104, VFLAGS, va("SHIELD: %5x", stplyr->powers[pw_shield])); - V_DrawRightAlignedString(320, height - 96, VFLAGS, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT)); - V_DrawRightAlignedString(320, height - 88, VFLAGS, va("CARRY: %5x", stplyr->powers[pw_carry])); - V_DrawRightAlignedString(320, height - 80, VFLAGS, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); - - // Flags - V_DrawRightAlignedString(304-92, height - 72, VFLAGS, "PF:"); - V_DrawString(304-90, height - 72, VFLAGS|((stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP), "SJ"); - V_DrawString(304-72, height - 72, VFLAGS|((stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP), "JD"); - V_DrawString(304-54, height - 72, VFLAGS|((stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP), "SP"); - V_DrawString(304-36, height - 72, VFLAGS|((stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP), "ST"); - V_DrawString(304-18, height - 72, VFLAGS|((stplyr->pflags & PF_THOKKED) ? V_GREENMAP : V_REDMAP), "TH"); - V_DrawString(304, height - 72, VFLAGS|((stplyr->pflags & PF_SHIELDABILITY) ? V_GREENMAP : V_REDMAP), "SH"); - - V_DrawRightAlignedString(320, height - 64, VFLAGS, va("CEILZ: %6d", stplyr->mo->ceilingz>>FRACBITS)); - V_DrawRightAlignedString(320, height - 56, VFLAGS, va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS)); - - V_DrawRightAlignedString(320, height - 48, VFLAGS, va("CNVX: %6d", stplyr->cmomx>>FRACBITS)); - V_DrawRightAlignedString(320, height - 40, VFLAGS, va("CNVY: %6d", stplyr->cmomy>>FRACBITS)); - V_DrawRightAlignedString(320, height - 32, VFLAGS, va("PLTZ: %6d", stplyr->mo->pmomz>>FRACBITS)); - - V_DrawRightAlignedString(320, height - 24, VFLAGS, va("MOMX: %6d", stplyr->rmomx>>FRACBITS)); - V_DrawRightAlignedString(320, height - 16, VFLAGS, va("MOMY: %6d", stplyr->rmomy>>FRACBITS)); - V_DrawRightAlignedString(320, height - 8, VFLAGS, va("MOMZ: %6d", stplyr->mo->momz>>FRACBITS)); - - V_DrawRightAlignedString(320, height, VFLAGS, va("SPEED: %6d", stplyr->speed>>FRACBITS)); - - height -= (112+dist); - } - - if (cv_debug & DBG_RANDOMIZER) // randomizer testing - { - fixed_t peekres = P_RandomPeek(); - peekres *= 10000; // Change from fixed point - peekres >>= FRACBITS; // to displayable decimal - - V_DrawRightAlignedString(320, height - 16, VFLAGS, va("Init: %08x", P_GetInitSeed())); - V_DrawRightAlignedString(320, height - 8, VFLAGS, va("Seed: %08x", P_GetRandSeed())); - V_DrawRightAlignedString(320, height, VFLAGS, va("== : .%04d", peekres)); - - height -= (24+dist); - } - - if (cv_debug & DBG_MEMORY) - { - V_DrawRightAlignedString(320, height, VFLAGS, va("Heap: %7sKB", sizeu1(Z_TotalUsage()>>10))); - } - -#undef VFLAGS +#undef V_DrawDebugLine #undef dist +#undef h +#undef VFLAGS } static void ST_drawScore(void) @@ -1917,8 +1982,8 @@ static void ST_drawTextHUD(void) else textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game")) - textHUDdraw(M_GetText("\x82""SPIN:""\x80 Sink")) - textHUDdraw(M_GetText("\x82""JUMP:""\x80 Float")) + textHUDdraw(M_GetText("\x82""SPIN:""\x80 Lower")) + textHUDdraw(M_GetText("\x82""JUMP:""\x80 Rise")) dof12 = true; dospecheader = true; From 790e334d19692498466ca2ce30fdd1cc8fc817fa Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 7 Apr 2018 23:10:34 +0100 Subject: [PATCH 65/66] comment goof --- src/p_mobj.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_mobj.h b/src/p_mobj.h index ec25855d8..f6ebd3cad 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -194,6 +194,7 @@ typedef enum MF2_AMBUSH = 1<<27, // Alternate behaviour typically set by MTF_AMBUSH MF2_LINKDRAW = 1<<28, // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) MF2_SHIELD = 1<<29, // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) + // free: to and including 1<<31 } mobjflag2_t; typedef enum From 375c3c584e412e52f57b94f5f991d8735f7e87da Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 8 Apr 2018 13:03:40 +0100 Subject: [PATCH 66/66] =?UTF-8?q?[13:01]=20toaster:=20hey=20[13:01]=20toas?= =?UTF-8?q?ter:=20would=20anyone=20object=20if=20i=20pushed=20this=20to=20?= =?UTF-8?q?master=20[13:02]=20toaster:=20so=20my=20changes=20to=20devmode?= =?UTF-8?q?=20don't=20fuck=20with=20gifs,=20for=20example=20https://cdn.di?= =?UTF-8?q?scordapp.com/attachments/428262628893261828/432500920773771264/?= =?UTF-8?q?srb20575.gif=20[13:02]=20NEV3R:=20=C2=AF\=5F(=E3=83=84)=5F/?= =?UTF-8?q?=C2=AF=20[13:02]=20toaster:=20ok=20i'll=20just=20do=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/st_stuff.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 3b07d375e..a513a028c 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -27,6 +27,8 @@ #include "i_system.h" #include "m_menu.h" #include "m_cheat.h" +#include "m_misc.h" // moviemode +#include "m_anigif.h" // cv_gif_downscale #include "p_setup.h" // NiGHTS grading //random index @@ -460,7 +462,7 @@ static void ST_drawDebugInfo(void) #define VFLAGS V_MONOSPACE|V_SNAPTOTOP|V_SNAPTORIGHT - if (vid.dupx == 1) + if ((moviemode == MM_GIF && cv_gif_downscale.value) || vid.dupx == 1) { if (cv_debug & DBG_BASIC) {