diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index bedc108da..c7f6f38c7 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -245,11 +245,11 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p flags |= HWR_GetBlendModeFlag(blendmode); if (alphalevel == 13) - Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency]; + Surf.PolyColor.s.alpha = softwaretranstogl_lo[V_GetHUDTranslucency(option)]; else if (alphalevel == 14) - Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency]; + Surf.PolyColor.s.alpha = softwaretranstogl[V_GetHUDTranslucency(option)]; else if (alphalevel == 15) - Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency]; + Surf.PolyColor.s.alpha = softwaretranstogl_hi[V_GetHUDTranslucency(option)]; else if (alphalevel < 10) Surf.PolyColor.s.alpha = softwaretranstogl[min(max((10 - alphalevel), 0), 10)]; else @@ -370,11 +370,11 @@ void HWR_DrawAffinePatch(patch_t *gpatch, fixed_t x, fixed_t y, const affine_t * flags |= HWR_GetBlendModeFlag(blendmode); if (alphalevel == 13) - Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency]; + Surf.PolyColor.s.alpha = softwaretranstogl_lo[V_GetHUDTranslucency(option)]; else if (alphalevel == 14) - Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency]; + Surf.PolyColor.s.alpha = softwaretranstogl[V_GetHUDTranslucency(option)]; else if (alphalevel == 15) - Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency]; + Surf.PolyColor.s.alpha = softwaretranstogl_hi[V_GetHUDTranslucency(option)]; else if (alphalevel < 10) Surf.PolyColor.s.alpha = softwaretranstogl[min(max((10 - alphalevel), 0), 10)]; else @@ -522,11 +522,11 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, flags |= HWR_GetBlendModeFlag(blendmode); if (alphalevel == 13) - Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency]; + Surf.PolyColor.s.alpha = softwaretranstogl_lo[V_GetHUDTranslucency(option)]; else if (alphalevel == 14) - Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency]; + Surf.PolyColor.s.alpha = softwaretranstogl[V_GetHUDTranslucency(option)]; else if (alphalevel == 15) - Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency]; + Surf.PolyColor.s.alpha = softwaretranstogl_hi[V_GetHUDTranslucency(option)]; else if (alphalevel < 10) Surf.PolyColor.s.alpha = softwaretranstogl[min(max((10 - alphalevel), 0), 10)]; else diff --git a/src/st_stuff.c b/src/st_stuff.c index eda5e70c5..3ebe0e56b 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -134,6 +134,7 @@ void ST_Ticker(boolean run) // 0 is default, any others are special palettes. INT32 st_palette = 0; UINT32 st_translucency = 10; +fixed_t st_fadein = 0; void ST_doPaletteStuff(void) { @@ -984,6 +985,37 @@ void ST_AskToJoinEnvelope(void) } #endif +static fixed_t ST_CalculateFadeIn(player_t *player) +{ + const tic_t length = TICRATE/4; + + tic_t timer = lt_exitticker; + + if (bossinfo.boss == true || G_IsTitleCardAvailable() == false) + { + if (timeinmap <= 16) + timer = 0; + else + timer = timeinmap-16; + } + + if (timer < length) + { + fixed_t f = timer * FRACUNIT; + + // Not interpolated at very beginning + if (timer > 0) + { + f += R_GetTimeFrac(RTF_LEVEL); + } + + return f / length; + } + + // Not interpolated at very end + return FRACUNIT; +} + void ST_Drawer(void) { boolean stagetitle = false; // Decide whether to draw the stage title or not @@ -1005,17 +1037,32 @@ void ST_Drawer(void) #endif if (rendermode != render_none) ST_doPaletteStuff(); - { - const tic_t length = TICRATE/2; + fixed_t localfadein[MAXSPLITSCREENPLAYERS]; - if (lt_exitticker) + // HUD fading for anything not tied to a single player, + // i.e. the minimap. Since individual splitscreen + // players' HUDs may fade away before other's, use the + // the last one remaining. + { + fixed_t maxFade = 0; + UINT8 i; + + for (i = 0; i <= r_splitscreen; i++) { - st_translucency = cv_translucenthud.value; - if (lt_exitticker < length) - st_translucency = (((INT32)(lt_ticker - lt_endtime))*st_translucency)/((INT32)length); + localfadein[i] = ST_CalculateFadeIn(&players[displayplayers[i]]); + + if (localfadein[i] > maxFade) + { + maxFade = localfadein[i]; + } } + + if (maxFade == FRACUNIT) + st_translucency = cv_translucenthud.value; else - st_translucency = 0; + st_translucency = FixedMul(cv_translucenthud.value, maxFade); + + st_translucency = min(max((st_translucency), 0), 10); } // Check for a valid level title @@ -1031,6 +1078,7 @@ void ST_Drawer(void) for (i = 0; i <= r_splitscreen; i++) { stplyr = &players[displayplayers[i]]; + st_fadein = localfadein[i]; stplyrnum = i; R_SetViewContext(VIEWCONTEXT_PLAYER1 + i); R_InterpolateView(R_GetTimeFrac(RTF_CAMERA)); // to assist with object tracking diff --git a/src/st_stuff.h b/src/st_stuff.h index 936b64f6e..67535d7af 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -83,7 +83,8 @@ extern boolean st_overlay; // sb overlay on or off when fullscreen extern INT32 st_palette; // 0 is default, any others are special palettes. extern player_t *stplyr; // for splitscreen correct palette changes and overlay extern UINT8 stplyrnum; -extern UINT32 st_translucency; +extern UINT32 st_translucency; // HUD fading for elements not attached to specific players +extern fixed_t st_fadein; // transitioning value per player, FRACUNIT = fully in view extern lumpnum_t st_borderpatchnum; // patches, also used in intermission diff --git a/src/v_video.c b/src/v_video.c index cc4f93ae2..f8b44ce3b 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -612,45 +612,47 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dup) } } - if (options & V_SLIDEIN) + if ((options & V_SLIDEIN)) { - const tic_t length = TICRATE/4; - tic_t timer = lt_exitticker; - if (bossinfo.boss == true) + if (st_fadein < FRACUNIT) { - if (leveltime <= 3) - timer = 0; - else - timer = leveltime-3; - } - - if (timer < length) - { - boolean slidefromright = false; - - const INT32 offsetAmount = (screenwidth * FRACUNIT/2) / length; - fixed_t offset = (screenwidth * FRACUNIT/2) - (timer * offsetAmount); - - offset += FixedMul(offsetAmount, renderdeltatics); - offset /= FRACUNIT; - - if (r_splitscreen > 1) + if ((options & (V_SNAPTORIGHT|V_SNAPTOLEFT|V_SPLITSCREEN)) != 0) { - if (stplyrnum == 1 || stplyrnum == 3) + boolean slidefromright = false; + + const fixed_t offsetAmount = (screenwidth * FRACUNIT/2); + INT32 offset = (offsetAmount - FixedMul(offsetAmount, st_fadein)) / FRACUNIT; + + if (r_splitscreen > 1) + { + if (player & 1) + slidefromright = true; + } + + if (options & V_SNAPTORIGHT) slidefromright = true; + else if (options & V_SNAPTOLEFT) + slidefromright = false; + + if (slidefromright == true) + { + offset = -offset; + } + + *x -= offset; } - - if (options & V_SNAPTORIGHT) - slidefromright = true; - else if (options & V_SNAPTOLEFT) - slidefromright = false; - - if (slidefromright == true) + else { - offset = -offset; - } + const fixed_t offsetAmount = (screenheight * FRACUNIT/2); + INT32 offset = (offsetAmount - FixedMul(offsetAmount, st_fadein)) / FRACUNIT; - *x -= offset; + if (options & V_SNAPTOBOTTOM) + { + offset = -offset; + } + + *y -= offset; + } } } } @@ -1101,6 +1103,39 @@ void V_DrawRotatedPatch(fixed_t x, fixed_t y, angle_t angle, fixed_t pscale, fix V_DrawAffinePatch(x, y, &t, scrn, patch, colormap); } +UINT32 V_GetHUDTranslucency(INT32 scrn) +{ + if (scrn & V_SLIDEIN) + { + return cv_translucenthud.value; + } + + if (scrn & V_SPLITSCREEN) + { + return FixedMul(cv_translucenthud.value, st_fadein); + } + + return st_translucency; +} + +static UINT32 V_GetAlphaLevel(INT32 scrn) +{ + switch (scrn & V_ALPHAMASK) + { + case V_HUDTRANSHALF: + return hudminusalpha[V_GetHUDTranslucency(scrn)]; + + case V_HUDTRANS: + return 10 - V_GetHUDTranslucency(scrn); + + case V_HUDTRANSDOUBLE: + return hudplusalpha[V_GetHUDTranslucency(scrn)]; + + default: + return (scrn & V_ALPHAMASK) >> V_ALPHASHIFT; + } +} + // Draws a patch scaled to arbitrary size. void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap) { @@ -1134,18 +1169,10 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca if ((blendmode = ((scrn & V_BLENDMASK) >> V_BLENDSHIFT))) blendmode++; // realign to constants - if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT))) - { - if (alphalevel == 13) // V_HUDTRANSHALF - alphalevel = hudminusalpha[st_translucency]; - else if (alphalevel == 14) // V_HUDTRANS - alphalevel = 10 - st_translucency; - else if (alphalevel == 15) // V_HUDTRANSDOUBLE - alphalevel = hudplusalpha[st_translucency]; - if (alphalevel >= 10) // Still inelegible to render? - return; - } + if ((alphalevel = V_GetAlphaLevel(scrn)) >= 10) + return; + if ((v_translevel = R_GetBlendTable(blendmode, alphalevel))) patchdrawtype = TRANSLUCENTDRAW; @@ -1801,18 +1828,9 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) } #endif - if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT))) - { - if (alphalevel == 13) // V_HUDTRANSHALF - alphalevel = hudminusalpha[st_translucency]; - else if (alphalevel == 14) // V_HUDTRANS - alphalevel = 10 - st_translucency; - else if (alphalevel == 15) // V_HUDTRANSDOUBLE - alphalevel = hudplusalpha[st_translucency]; + if ((alphalevel = V_GetAlphaLevel(c)) >= 10) + return; - if (alphalevel >= 10) // Still inelegible to render? - return; - } if (!(c & V_NOSCALESTART)) { diff --git a/src/v_video.h b/src/v_video.h index b4d8cf3a4..54554e33f 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -185,6 +185,8 @@ void V_CubeApply(RGBA_t *input); #define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords #define V_SPLITSCREEN 0x80000000 // Add half of screen width or height automatically depending on player number +UINT32 V_GetHUDTranslucency(INT32 scrn); + void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dup); struct cliprect_t