diff --git a/src/d_main.cpp b/src/d_main.cpp index 8833749dd..4ccafff55 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -649,6 +649,13 @@ static bool D_Display(void) V_DrawCustomFadeScreen("FADEMAP0", val); } } + else if (demo.attract == DEMO_ATTRACT_TITLE) + { + if (INT32 fade = F_AttractDemoExitFade()) + { + V_DrawCustomFadeScreen("FADEMAP0", fade); + } + } VID_DisplaySoftwareScreen(); } diff --git a/src/f_finale.c b/src/f_finale.c index 534ebd62e..761e2f812 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -67,6 +67,7 @@ static boolean keypressed = false; static tic_t attractcountdown; // Countdown until attract demo ends static boolean attractcredit; // Show music credit once attract demo begins +boolean g_attractnowipe; // Do not wipe on return to title screen static INT32 menuanimtimer; // Title screen: background animation timing altview_t titlemapcam = {0}; @@ -1837,10 +1838,22 @@ void F_AttractDemoTicker(void) } if (attractcountdown > 0 && !--attractcountdown) + { + // Fade will be handled without a wipe (see F_AttractDemoExitFade) + g_attractnowipe = true; G_CheckDemoStatus(); + } } } +INT32 F_AttractDemoExitFade(void) +{ + if (attractcountdown > 15) + return 0; + + return 31 - (attractcountdown * 2); +} + // ================ // WAITINGPLAYERS // ================ diff --git a/src/f_finale.h b/src/f_finale.h index 5b72790b7..6caf0bd4b 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -64,6 +64,8 @@ void F_EndTextPrompt(boolean forceexec, boolean noexec); boolean F_GetPromptHideHudAll(void); boolean F_GetPromptHideHud(fixed_t y); +INT32 F_AttractDemoExitFade(void); + void F_StartGameEnd(void); void F_StartIntro(void); void F_StartTitleScreen(void); @@ -128,6 +130,8 @@ extern boolean WipeStageTitle; extern INT32 lastwipetic; +extern boolean g_attractnowipe; + // Don't know where else to place this constant // But this file seems appropriate #define PRELEVELTIME TICRATE // frames in tics diff --git a/src/i_time.c b/src/i_time.c index 431d2a9a6..6df6d5581 100644 --- a/src/i_time.c +++ b/src/i_time.c @@ -18,6 +18,8 @@ #include "command.h" #include "doomtype.h" #include "d_netcmd.h" +#include "f_finale.h" +#include "g_demo.h" #include "m_fixed.h" #include "i_system.h" @@ -59,6 +61,12 @@ void I_InitializeTime(void) fixed_t I_GetTimeScale(void) { + if (demo.playback && demo.attract == DEMO_ATTRACT_TITLE && F_AttractDemoExitFade()) + { + // Slow down at the end of attract demos + return FRACUNIT/2; + } + return cv_timescale.value; } diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 0be59c7be..9cf7463bb 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -52,6 +52,7 @@ #include "k_hitlag.h" #include "g_input.h" #include "k_dialogue.h" +#include "f_finale.h" //{ Patch Definitions static patch_t *kp_nodraw; @@ -6097,6 +6098,33 @@ void K_drawKartHUD(void) { INT32 x = BASEVIDWIDTH - 8, y = BASEVIDHEIGHT-8, snapflags = V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SLIDEIN; patch_t *pat = static_cast(W_CachePatchName((M_UseAlternateTitleScreen() ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE)); + const UINT8 *colormap = nullptr; + + if (INT32 fade = F_AttractDemoExitFade()) + { + // TODO: Twodee cannot handle + // V_DrawCustomFadeScreen. + // However, since the screen fade just + // uses a colormap, the same colormap can + // be applied on a per-patch basis. + // I'm only bothering to apply this + // colormap to the attract mode sticker, + // since it's the lone HUD element. + if (lighttable_t *clm = V_LoadCustomFadeMap("FADEMAP0")) + { + // This must be statically allocated for Twodee + static UINT8 *colormap_storage; + const UINT8 *fadetable = V_OffsetIntoFadeMap(clm, fade); + + if (!colormap_storage) + Z_MallocAlign(256, PU_STATIC, &colormap_storage, 8); + + memcpy(colormap_storage, fadetable, 256); + colormap = colormap_storage; + + Z_Free(clm); + } + } if (r_splitscreen == 3) { @@ -6105,7 +6133,7 @@ void K_drawKartHUD(void) snapflags = 0; } - V_DrawScaledPatch(x-(SHORT(pat->width)), y-(SHORT(pat->height)), snapflags, pat); + V_DrawMappedPatch(x-(SHORT(pat->width)), y-(SHORT(pat->height)), snapflags, pat, colormap); } } else diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 1a64b20da..1cc4c9cd3 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -8532,15 +8532,24 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) wipetype = wipe_encore_towhite; } - if (rendermode != render_none) + if (g_attractnowipe) { - F_WipeStartScreen(); - - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); - F_WipeEndScreen(); + // Attract demos do a custom fade on exit, so + // don't run a wipe here. + g_attractnowipe = false; } + else + { + if (rendermode != render_none) + { + F_WipeStartScreen(); - F_RunWipe(wipetype, wipedefs[wipetype], false, ((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), false, false); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); + F_WipeEndScreen(); + } + + F_RunWipe(wipetype, wipedefs[wipetype], false, ((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), false, false); + } } /*