From f0788598c998bdd2b0e6c358718ff26a0b439c78 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 23:31:48 -0300 Subject: [PATCH] Better fades --- src/d_main.c | 4 + src/f_finale.h | 17 ++++ src/f_wipe.c | 150 +++++++++++++++++++++++++++++-- src/hardware/hw_drv.h | 2 + src/hardware/hw_main.c | 5 ++ src/hardware/hw_main.h | 1 + src/hardware/r_opengl/r_opengl.c | 44 +++++++++ src/m_menu.c | 6 +- src/p_setup.c | 15 +++- src/r_data.c | 73 ++++++++++++++- src/r_data.h | 2 + src/r_state.h | 1 + src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + src/win32/win_dll.c | 2 + 15 files changed, 309 insertions(+), 15 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 9fa506bee..499cde45e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -461,6 +461,10 @@ static void D_Display(void) if (gamestate != GS_TIMEATTACK) CON_Drawer(); + // Running a wipe, but it doesn't freeze the game + if (WipeInAction && (!WipeFreezeGame)) + F_WipeTicker(); + M_Drawer(); // menu is drawn even on top of everything // focus lost moved to M_Drawer diff --git a/src/f_finale.h b/src/f_finale.h index d640abc8a..ccef4a362 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -108,11 +108,28 @@ void F_MenuPresTicker(boolean run); #define FORCEWIPEOFF -2 extern boolean WipeInAction; +extern boolean WipeFreezeGame; extern INT32 lastwipetic; +typedef enum +{ + WIPESTYLE_NORMAL, + WIPESTYLE_LEVEL +} wipestyle_t; +extern wipestyle_t wipestyle; + +typedef enum +{ + WSF_FADEOUT = 1, + WSF_FADEIN = 1<<1, + WSF_TOWHITE = 1<<2, +} wipestyleflags_t; +extern wipestyleflags_t wipestyleflags; + void F_WipeStartScreen(void); void F_WipeEndScreen(void); void F_RunWipe(UINT8 wipetype, boolean drawMenu); +void F_WipeTicker(void); tic_t F_GetWipeLength(UINT8 wipetype); boolean F_WipeExists(UINT8 wipetype); diff --git a/src/f_wipe.c b/src/f_wipe.c index 05229f844..cabcbb1a1 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -27,6 +27,13 @@ #include "d_main.h" #include "m_misc.h" // movie mode +#include "doomstat.h" +#include "st_stuff.h" + +#ifdef HAVE_BLUA +#include "lua_hud.h" // level title +#endif + #ifdef HWRENDER #include "hardware/hw_main.h" #endif @@ -82,14 +89,22 @@ UINT8 wipedefs[NUMWIPEDEFS] = { //-------------------------------------------------------------------------- boolean WipeInAction = false; +boolean WipeFreezeGame = true; INT32 lastwipetic = 0; +wipestyle_t wipestyle = WIPESTYLE_NORMAL; +wipestyleflags_t wipestyleflags = 0; + #ifndef NOWIPE static UINT8 *wipe_scr_start; //screen 3 static UINT8 *wipe_scr_end; //screen 4 static UINT8 *wipe_scr; //screen 0 (main drawing) static fixed_t paldiv = 0; +static UINT8 curwipetype; +static UINT8 curwipeframe; +static UINT8 maxwipeframe; + /** Create fademask_t from lump * * \param lump Lump name to get data from @@ -148,7 +163,10 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) { { // Determine pixel to use from fademask pcolor = &pMasterPalette[*lump++]; - *mask++ = FixedDiv((pcolor->s.red+1)<>FRACBITS; + if (wipestyle == WIPESTYLE_LEVEL) + *mask++ = pcolor->s.red/8; // 0-31 range + else + *mask++ = FixedDiv((pcolor->s.red+1)<>FRACBITS; } fm.xscale = FixedDiv(vid.width<lvlttl != '\0' +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_stagetitle) +#endif + ) + ST_drawLevelTitle(TICRATE); +} + /** Wipe ticker * * \param fademask pixels to change @@ -242,7 +273,7 @@ static void F_DoWipe(fademask_t *fademask) relativepos = (draw_linestart * vid.width) + draw_rowstart; draw_linestogo = draw_lineend - draw_linestart; - if (*mask == 0) + if ((*mask == 0) && (wipestyle == WIPESTYLE_NORMAL)) { // shortcut - memcpy source to work while (draw_linestogo--) @@ -251,7 +282,7 @@ static void F_DoWipe(fademask_t *fademask) relativepos += vid.width; } } - else if (*mask == 10) + else if ((*mask >= maxwipeframe) && (wipestyle == WIPESTYLE_NORMAL)) { // shortcut - memcpy target to work while (draw_linestogo--) @@ -262,8 +293,25 @@ static void F_DoWipe(fademask_t *fademask) } else { - // pointer to transtable that this mask would use - transtbl = transtables + ((9 - *mask)<drawroutine) diff --git a/src/p_setup.c b/src/p_setup.c index 65335be3f..51cb38fe0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2679,6 +2679,7 @@ boolean P_SetupLevel(boolean skipprecip) // Cancel all d_main.c fadeouts (keep fade in though). wipegamestate = FORCEWIPEOFF; + wipestyleflags = 0; // Special stage fade to white // This is handled BEFORE sounds are stopped. @@ -2699,11 +2700,17 @@ boolean P_SetupLevel(boolean skipprecip) S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE) F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); + wipestyleflags |= WSF_FADEOUT|WSF_TOWHITE; F_WipeEndScreen(); F_RunWipe(wipedefs[wipe_speclevel_towhite], false); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); + I_OsPolling(); + I_FinishUpdate(); // page flip or blit buffer + if (moviemode) + M_SaveFrame(); + nowtime = lastwipetic; // Hold on white for extra effect. @@ -2737,7 +2744,8 @@ boolean P_SetupLevel(boolean skipprecip) if (rendermode != render_none && !ranspecialwipe) { F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + wipestyleflags |= WSF_FADEOUT; + //V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); // for titlemap: run a specific wipe if specified @@ -3180,6 +3188,9 @@ boolean P_SetupLevel(boolean skipprecip) } // Stage title! + wipestyleflags |= WSF_FADEIN; + wipestyleflags &= ~WSF_FADEOUT; + WipeFreezeGame = false; if (rendermode != render_none && (!titlemapinaction) && ranspecialwipe != 2 diff --git a/src/r_data.c b/src/r_data.c index 6889bddde..2699cf599 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -112,6 +112,7 @@ INT32 *texturetranslation; sprcache_t *spritecachedinfo; lighttable_t *colormaps; +lighttable_t *fadecolormap = NULL; // for debugging/info purposes static size_t flatmemory, spritememory, texturememory; @@ -1294,18 +1295,82 @@ static void R_InitSpriteLumps(void) Z_Malloc(max_spritelumps*sizeof(*spritecachedinfo), PU_STATIC, &spritecachedinfo); } +// +// R_CreateFadeColormaps +// +static void R_CreateFadeColormaps(size_t len) +{ + UINT8 px, fade; + RGBA_t rgba; + INT32 r, g, b; + size_t i; + + fadecolormap = Z_MallocAlign(len*2, PU_STATIC, NULL, 8); + +#define GETCOLOR \ + px = colormaps[i%256]; \ + fade = (i/256) * 8; \ + rgba = V_GetColor(px); + + // to black + for (i = 0; i < len; i++) + { + // find pixel and fade amount + GETCOLOR; + + // subtractive color blending + r = rgba.s.red - fade*3; + g = rgba.s.green - fade*2; + b = rgba.s.blue - fade; + + // clamp values + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + + // find nearest color in palette + fadecolormap[i] = NearestColor(r,g,b); + } + + // to white + for (i = len; i < len*2; i++) + { + // find pixel and fade amount + GETCOLOR; + + // additive color blending + r = rgba.s.red + fade*3; + g = rgba.s.green + fade*2; + b = rgba.s.blue + fade; + + // clamp values + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + + // find nearest color in palette + fadecolormap[i] = NearestColor(r,g,b); + } +#undef GETCOLOR +} + // // R_InitColormaps // static void R_InitColormaps(void) { + size_t len; lumpnum_t lump; // Load in the light tables lump = W_GetNumForName("COLORMAP"); - colormaps = Z_MallocAlign(W_LumpLength (lump), PU_STATIC, NULL, 8); + len = W_LumpLength(lump); + colormaps = Z_MallocAlign(len, PU_STATIC, NULL, 8); W_ReadLump(lump, colormaps); + // Make colormap for fades + R_CreateFadeColormaps(len); + // Init Boom colormaps. R_ClearColormaps(); #ifdef EXTRACOLORMAPLUMPS @@ -1334,6 +1399,9 @@ void R_ReInitColormaps(UINT16 num) } W_ReadLumpHeader(lump, colormaps, W_LumpLength(basecolormaplump), 0U); + if (fadecolormap) + Z_Free(fadecolormap); + R_CreateFadeColormaps(W_LumpLength(lump)); // Init Boom colormaps. R_ClearColormaps(); @@ -1615,7 +1683,6 @@ extracolormap_t *R_ColormapForName(char *name) // static double deltas[256][3], map[256][3]; -static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); static int RoundUp(double number); lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) @@ -2027,7 +2094,7 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex // Thanks to quake2 source! // utils3/qdata/images.c -static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) { int dr, dg, db; int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i; diff --git a/src/r_data.h b/src/r_data.h index b6b0a16a1..77e615799 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -148,6 +148,8 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap); #define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b)) #define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a)) +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); + extern INT32 numtextures; #endif diff --git a/src/r_state.h b/src/r_state.h index da9425bdf..977384926 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -38,6 +38,7 @@ typedef struct extern sprcache_t *spritecachedinfo; extern lighttable_t *colormaps; +extern lighttable_t *fadecolormap; // Boom colormaps. extern extracolormap_t *extra_colormaps; diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 05ac6450e..a07d9eb03 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -98,6 +98,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(StartScreenWipe); GETFUNC(EndScreenWipe); GETFUNC(DoScreenWipe); + GETFUNC(DoScreenWipeLevel); GETFUNC(DrawIntermissionBG); GETFUNC(MakeScreenTexture); GETFUNC(MakeScreenFinalTexture); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5a4fd7a02..998fae239 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1519,6 +1519,7 @@ void I_StartupGraphics(void) HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + HWD.pfnDoScreenWipeLevel= hwSym("DoScreenWipeLevel",NULL); HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index 71eda0437..b6353f80d 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -121,6 +121,7 @@ static loadfunc_t hwdFuncTable[] = { {"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe}, {"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe}, {"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe}, + {"DoScreenWipeLevel@0", &hwdriver.pfnDoScreenWipeLevel}, {"DrawIntermissionBG@0",&hwdriver.pfnDrawIntermissionBG}, {"MakeScreenTexture@0", &hwdriver.pfnMakeScreenTexture}, {"MakeScreenFinalTexture@0", &hwdriver.pfnMakeScreenFinalTexture}, @@ -152,6 +153,7 @@ static loadfunc_t hwdFuncTable[] = { {"StartScreenWipe", &hwdriver.pfnStartScreenWipe}, {"EndScreenWipe", &hwdriver.pfnEndScreenWipe}, {"DoScreenWipe", &hwdriver.pfnDoScreenWipe}, + {"DoScreenWipeLevel", &hwdriver.pfnDoScreenWipeLevel}, {"DrawIntermissionBG", &hwdriver.pfnDrawIntermissionBG}, {"MakeScreenTexture", &hwdriver.pfnMakeScreenTexture}, {"MakeScreenFinalTexture", &hwdriver.pfnMakeScreenFinalTexture},