Refactor screen wipes, again

This commit is contained in:
Lactozilla 2023-12-27 03:37:48 -03:00
parent cf03f5d91e
commit 3816115e4e
17 changed files with 605 additions and 602 deletions

View file

@ -292,12 +292,6 @@ void D_ProcessEvents(void)
// RENDERING
//
// wipegamestate can be set to -1 to force a wipe on the next draw
// added comment : there is a wipe eatch change of the gamestate
gamestate_t wipegamestate = GS_LEVEL;
INT16 wipetypepre = DEFAULTWIPE;
INT16 wipetypepost = DEFAULTWIPE;
static void D_Render(void)
{
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction && curbghide && (!hidetitlemap))))
@ -412,8 +406,6 @@ static void D_RenderNonLevel(void)
case GS_INTRO:
F_IntroDrawer();
if (wipegamestate == (gamestate_t)-1)
WipeRunPost = true;
break;
case GS_ENDING:
@ -481,7 +473,7 @@ static void D_Display(void)
if (setrenderneeded || setmodeneeded)
{
SCR_SetMode(); // change video mode
if (WipeInAction)
if (wipe_running)
F_StopWipe();
}
@ -506,16 +498,21 @@ static void D_Display(void)
I_UpdateNoBlit();
// save the current screen if about to wipe
// I'm scared of moving this way down there (before CON_Drawer mayhaps)
// but it's probably not a huge deal to leave it here...
// I'd have to make sure nothing during rendering is changing wipegamestate
if ((gamestate != wipegamestate) && wipetypepre != IGNOREWIPE)
F_WipeStartPre();
else
wipetypepre = DEFAULTWIPE;
wipe_t *wipe = F_GetQueuedWipe();
if (wipe && !wipe_running)
{
if (!(wipe->flags & (WSF_FADEIN | WSF_CROSSFADE)))
{
F_SetupFadeOut(wipe->flags);
F_StartPendingWipe();
}
if (wipe->flags & WSF_CROSSFADE)
F_WipeStartScreen();
}
// do buffered drawing
if (WipeInAction)
if (wipe_running)
{
F_DisplayWipe();
@ -525,10 +522,7 @@ static void D_Display(void)
else
D_RenderNonLevel();
// STUPID race condition...
if (wipegamestate == GS_INTRO && gamestate == GS_TITLESCREEN)
wipegamestate = FORCEWIPEOFF;
else if (!WipeInAction)
if (!wipe_running)
D_Render();
// change gamma if needed
@ -558,7 +552,7 @@ static void D_Display(void)
// vid size change is now finished if it was on...
vid.recalc = 0;
if (!WipeInAction || (WipeInAction && (WipeDrawMenu || G_GetRetryFlag(RETRY_CUR))))
if (!wipe_running || (wipe_running && (wipe_drawmenuontop || G_GetRetryFlag(RETRY_CUR))))
{
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
@ -573,16 +567,24 @@ static void D_Display(void)
//
// wipe update
//
if (WipeRunPost && !WipeInAction && wipetypepost != IGNOREWIPE)
wipe = F_GetQueuedWipe();
if (wipe && !wipe_running && (wipe->flags & (WSF_FADEIN | WSF_CROSSFADE)))
{
F_WipeStartPost();
F_WipeEndScreen();
if (wipe->flags & WSF_FADEIN)
{
F_WipeColorFill(levelfadecol);
F_WipeStartScreen();
}
F_StartPendingWipe();
F_DisplayWipe();
if (titlecard.running)
TitleCard_DrawOverWipe();
}
else
wipetypepost = DEFAULTWIPE;
CON_Drawer();
@ -873,6 +875,8 @@ void D_StartTitle(void)
S_StopMusic();
TitleCard_Stop();
if (netgame)
{
if (gametyperules & GTR_CAMPAIGN)
@ -1451,8 +1455,6 @@ void D_SRB2Main(void)
// set user default mode or mode set at cmdline
SCR_CheckDefaultMode();
wipegamestate = gamestate;
savedata.lives = 0; // flag this as not-used
//------------------------------------------------ COMMAND LINE PARAMS
@ -1602,7 +1604,6 @@ void D_SRB2Main(void)
G_TimeDemo(tmp);
G_SetGamestate(GS_NULL);
wipegamestate = GS_NULL;
return;
}

View file

@ -621,12 +621,6 @@ extern INT32 debugload;
// if true, load all graphics at level load
extern boolean precache;
// wipegamestate can be set to -1
// to force a wipe on the next draw
extern gamestate_t wipegamestate;
extern INT16 wipetypepre;
extern INT16 wipetypepost;
// debug flag to cancel adaptiveness
extern boolean singletics;

View file

@ -339,6 +339,8 @@ void F_StartIntro(void)
S_StopMusic();
S_StopSounds();
F_StopAllWipes();
if (introtoplay)
{
if (!cutscenes[introtoplay - 1])
@ -490,22 +492,12 @@ void F_StartIntro(void)
"\x80\n\xA9\xD2\xD2"
"\"All right, then\xAF... \xD2\xD2\xA7let's go!\"\n#");
/*
"What are we waiting for? The first emerald is ours!" Sonic was about to
run, when he saw a shadow pass over him, he recognized the silhouette
instantly.
"Knuckles!" Sonic said. The echidna stopped his glide and landed
facing Sonic. "What are you doing here?"
He replied, "This crisis affects the Floating Island,
if that explosion I saw is anything to go by."
If you're willing to help then... let's go!"
*/
G_SetGamestate(GS_INTRO);
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
F_NewCutscene(introtext[0]);
TitleCard_Stop();
intro_scenenum = 0;
finalecount = animtimer = skullAnimCounter = stoptimer = 0;
@ -639,7 +631,7 @@ void F_IntroDrawer(void)
V_DrawSmallScaledPatch(bgxoffs, 84, 0, background);
}
if (!WipeInAction) // Draw the patch if not in a wipe
if (!wipe_running) // Draw the patch if not in a wipe
{
background = W_CachePatchName(stjrintro, PU_PATCH_LOWPRIORITY);
V_DrawSmallScaledPatch(bgxoffs, 84, 0, background);
@ -838,61 +830,105 @@ void F_IntroDrawer(void)
V_DrawString(cx, cy, V_ALLOWLOWERCASE, cutscene_disptext);
}
static void F_IntroMidSceneWipe(void)
static void F_IntroDoCrossfade(void)
{
INT32 x = 8;
INT32 y = 128;
patch_t *patch;
if (intro_scenenum == INTRO_RADAR && intro_curtime == 5*TICRATE)
patch = W_CachePatchName("RADAR", PU_PATCH_LOWPRIORITY);
else if (intro_scenenum == INTRO_GRASS2 && intro_curtime == 6*TICRATE)
patch = W_CachePatchName("SGRASS2", PU_PATCH_LOWPRIORITY);
else if (intro_scenenum == INTRO_SONICDO2 && intro_curtime == 7*TICRATE)
{
patch = W_CachePatchName("SONICDO2", PU_PATCH_LOWPRIORITY);
x = 224;
y = 8;
}
else
return;
F_WipeStartScreen();
V_DrawSmallScaledPatch(0, 0, 0, patch);
W_UnlockCachedPatch(patch);
V_DrawString(x, y, V_ALLOWLOWERCASE, cutscene_disptext);
F_WipeEndScreenRestore();
wipestyle = WIPESTYLE_NORMAL;
F_StartWipe(99, true);
timetonext--;
wipe_t wipe = {0};
wipe.flags = WSF_CROSSFADE;
wipe.style = WIPESTYLE_NORMAL;
wipe.type = 99;
wipe.drawmenuontop = false;
F_StartWipeParametrized(&wipe);
}
#define F_IntroSceneCrossfades(scene) ((scene) != INTRO_STJR && (scene) != INTRO_SKYRUNNER && (scene) != INTRO_LAST)
static void F_IntroSpecialWipe(INT32 scene)
static void F_IntroCheckMidSceneWipe(void)
{
wipestyleflags = WSF_FADEOUT;
boolean do_crossfade = false;
if (intro_scenenum == INTRO_STJR && intro_curtime == 2*TICRATE-19)
{
S_ChangeMusicInternal("_stjr", false);
F_QueuePostWipe(99, WSF_FADEIN, NULL);
return;
}
else if (intro_scenenum == INTRO_RADAR && intro_curtime == 5*TICRATE)
do_crossfade = true;
else if (intro_scenenum == INTRO_GRASS2 && intro_curtime == 6*TICRATE)
do_crossfade = true;
else if (intro_scenenum == INTRO_SONICDO2 && intro_curtime == 7*TICRATE)
do_crossfade = true;
if (do_crossfade)
{
F_IntroDoCrossfade();
timetonext--;
}
}
static void F_PlayIntroMusic(void)
{
S_ChangeMusicInternal("_intro", false);
}
static void F_IntroDoSpecialWipe(INT32 scene)
{
wipe_t wipe = {0};
wipe.style = WIPESTYLE_NORMAL;
wipe.type = 99;
wipe.drawmenuontop = true;
boolean do_fade_in = false;
switch (scene)
{
case INTRO_STJR:
wipestyleflags |= WSF_INTROSTART;
// The intro music is timed with the fade out and fade in
wipe.callback = F_PlayIntroMusic;
wipe.style = WIPESTYLE_COLORMAP;
do_fade_in = true;
break;
case INTRO_SKYRUNNER:
wipestyleflags |= WSF_TOWHITE;
wipe.flags = WSF_TOWHITE;
wipe.style = WIPESTYLE_COLORMAP;
wipe.type = 0;
wipe.holdframes = 17;
do_fade_in = true;
break;
case INTRO_LAST:
wipestyleflags |= WSF_INTROEND;
wipe.style = WIPESTYLE_COLORMAP;
wipe.holdframes = NEWTICRATE*2;
wipe.callback = D_StartTitle;
break;
default:
wipe.flags = WSF_CROSSFADE;
break;
}
F_WipeStartScreen();
F_WipeDoTinted();
F_WipeEndScreenRestore();
F_StartWipeParametrized(&wipe);
F_StartWipe(99, true);
WipeRunPost = true;
if (do_fade_in)
{
if (scene == INTRO_SKYRUNNER)
wipe.type = 99;
wipe.flags |= WSF_FADEIN;
wipe.callback = NULL;
wipe.holdframes = 0;
F_StartWipeParametrized(&wipe);
}
}
static boolean F_IntroSceneCrossfades(unsigned scene)
{
switch (scene)
{
case INTRO_STJR:
case INTRO_SKYRUNNER:
case INTRO_LAST:
return false;
default:
return true;
}
}
//
@ -911,23 +947,14 @@ void F_IntroTicker(void)
if (keypressed)
keypressed = false;
wipestyleflags = WSF_CROSSFADE;
INT32 lastscene = intro_scenenum;
boolean next = timetonext <= 0;
if (next)
{
if (rendermode == render_none && intro_scenenum == INTRO_LAST)
{
D_StartTitle();
wipegamestate = GS_INTRO;
return;
}
if (F_IntroSceneCrossfades(intro_scenenum))
{
F_WipeDoCrossfade();
F_IntroDoCrossfade();
next = false;
}
@ -938,17 +965,13 @@ void F_IntroTicker(void)
intro_curtime = introscenetime[intro_scenenum] - timetonext;
if (rendermode != render_none)
if (next)
{
if (next)
{
F_IntroSpecialWipe(lastscene);
return;
}
F_IntroMidSceneWipe();
F_IntroDrawer();
F_IntroDoSpecialWipe(lastscene);
return;
}
F_IntroCheckMidSceneWipe();
}
//
@ -1219,17 +1242,23 @@ static const UINT8 credits_numpics = sizeof(credits_pics)/sizeof(credits_pics[0]
void F_StartCredits(void)
{
G_SetGamestate(GS_CREDITS);
boolean from_ending = gamestate == GS_ENDING;
F_StopAllWipes();
TitleCard_Stop();
// Just in case they're open ... somehow
M_ClearMenus(true);
if (creditscutscene)
if (creditscutscene && cutscenes[creditscutscene - 1])
{
F_StartCustomCutscene(creditscutscene - 1, false, false, false);
return;
}
G_SetGamestate(GS_CREDITS);
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
@ -1241,6 +1270,10 @@ void F_StartCredits(void)
finalecount = 0;
animtimer = 0;
timetonext = 2*TICRATE;
if (!from_ending)
F_QueuePreWipe(wipedefs[wipe_credits_toblack], 0, NULL);
F_QueuePostWipe(wipedefs[wipe_credits_final], WSF_FADEIN, NULL);
}
void F_CreditDrawer(void)
@ -1436,6 +1469,9 @@ void F_StartGameEvaluation(void)
finalecount = -1;
sparklloop = 0;
F_QueuePreWipe(wipedefs[wipe_evaluation_toblack], 0, NULL);
F_QueuePostWipe(wipedefs[wipe_evaluation_final], WSF_FADEIN, NULL);
}
void F_GameEvaluationDrawer(void)
@ -1654,7 +1690,7 @@ void F_GameEvaluationTicker(void)
#define STOPPINGPOINT (14*TICRATE)
#define SPARKLLOOPTIME 15 // must be odd
static void F_CacheEnding(void)
static void F_LoadEndingGraphics(void)
{
endbrdr[1] = W_CachePatchName("ENDBRDR1", PU_PATCH_LOWPRIORITY);
@ -1733,8 +1769,11 @@ static void F_CacheGoodEnding(void)
void F_StartEnding(void)
{
F_StopAllWipes();
TitleCard_Stop();
G_SetGamestate(GS_ENDING);
wipetypepost = IGNOREWIPE;
// Just in case they're open ... somehow
M_ClearMenus(true);
@ -1750,7 +1789,10 @@ void F_StartEnding(void)
memset(sparkloffs, 0, sizeof(INT32)*3*2);
sparklloop = 0;
F_CacheEnding();
F_LoadEndingGraphics();
F_QueuePreWipe(wipedefs[wipe_ending_toblack], 0, NULL);
F_QueuePostWipe(wipedefs[wipe_ending_final], WSF_FADEIN, NULL);
}
void F_EndingTicker(void)
@ -1758,7 +1800,6 @@ void F_EndingTicker(void)
if (++finalecount > STOPPINGPOINT)
{
F_StartCredits();
wipetypepre = IGNOREWIPE;
return;
}
@ -2192,6 +2233,8 @@ void F_StartGameEnd(void)
M_ClearMenus(true);
timetonext = TICRATE;
F_QueuePostWipe(99, 0, NULL);
}
//
@ -2199,7 +2242,7 @@ void F_StartGameEnd(void)
//
void F_GameEndDrawer(void)
{
// this function does nothing
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
}
//
@ -2366,8 +2409,16 @@ static void F_CacheTitleScreen(void)
}
}
void F_InitTitleScreen(void)
{
if (titlemap)
G_DoLoadLevel();
}
void F_StartTitleScreen(void)
{
F_StopAllWipes();
if (menupres[MN_MAIN].musname[0])
S_ChangeMusic(menupres[MN_MAIN].musname, menupres[MN_MAIN].mustrack, menupres[MN_MAIN].muslooping);
else
@ -2388,14 +2439,16 @@ void F_StartTitleScreen(void)
finalecount = -3; // hack so that frames don't advance during the entry wipe
else
finalecount = 0;
wipetypepost = menupres[MN_MAIN].enterwipe;
if (!F_GetQueuedWipe())
F_QueuePreWipe(wipedefs[wipe_titlescreen_toblack], 0, F_InitTitleScreen);
F_QueuePostWipe(menupres[MN_MAIN].enterwipe, WSF_FADEIN, NULL);
}
else
wipegamestate = GS_TITLESCREEN;
G_SetGamestate(GS_TITLESCREEN);
if (titlemap)
{
gamestate_t prevwipegamestate = wipegamestate;
titlemapinaction = TITLEMAP_LOADING;
titlemapcameraref = NULL;
gamemap = titlemap;
@ -2409,8 +2462,6 @@ void F_StartTitleScreen(void)
G_StartLevel(true);
if (!titlemap)
return;
wipegamestate = prevwipegamestate;
}
else
{
@ -2421,10 +2472,6 @@ void F_StartTitleScreen(void)
CON_ClearHUD();
}
G_SetGamestate(GS_TITLESCREEN);
// IWAD dependent stuff.
animtimer = skullAnimCounter = 0;
demoDelayLeft = demoDelayTime;
@ -3476,7 +3523,7 @@ void F_StartContinue(void)
return;
}
wipestyleflags = WSF_FADEOUT;
F_StopAllWipes();
G_SetGamestate(GS_CONTINUING);
gameaction = ga_nothing;
@ -3528,6 +3575,9 @@ void F_StartContinue(void)
timetonext = (11*TICRATE)+11;
continuetime = 0;
F_QueuePreWipe(wipedefs[wipe_continuing_toblack], 0, NULL);
F_QueuePostWipe(wipedefs[wipe_continuing_final], WSF_FADEIN, NULL);
}
//
@ -3775,22 +3825,35 @@ static INT32 textxpos, textypos;
static boolean cutsceneover = false;
static boolean runningprecutscene = false, precutresetplayer = false, precutFLS = false;
static void F_PlayCutsceneMusic(void)
{
if (cutscenes[cutnum]->scene[scenenum].musswitch[0])
S_ChangeMusicEx(cutscenes[cutnum]->scene[scenenum].musswitch,
cutscenes[cutnum]->scene[scenenum].musswitchflags,
cutscenes[cutnum]->scene[scenenum].musicloop,
cutscenes[cutnum]->scene[scenenum].musswitchposition, 0, 0);
}
static void F_AdvanceToNextScene(void)
{
if (rendermode != render_none)
F_StopAllWipes();
// Fade to any palette color you want.
if (cutscenes[cutnum]->scene[scenenum].fadecolor)
{
F_WipeStartScreen();
wipe_t wipe = {0};
wipe.flags = 0;
wipe.style = WIPESTYLE_NORMAL;
wipe.type = cutscenes[cutnum]->scene[scenenum].fadeinid;
wipe.drawmenuontop = true;
wipe.callback = F_PlayCutsceneMusic;
F_StartWipeParametrized(&wipe);
// Fade to any palette color you want.
if (cutscenes[cutnum]->scene[scenenum].fadecolor)
{
V_DrawFill(0,0,BASEVIDWIDTH,BASEVIDHEIGHT,cutscenes[cutnum]->scene[scenenum].fadecolor);
F_WipeEndScreenRestore();
F_StartWipe(cutscenes[cutnum]->scene[scenenum].fadeinid, true);
F_WipeStartScreen();
}
levelfadecol = cutscenes[cutnum]->scene[scenenum].fadecolor;
}
else
{
F_WipeDoCrossfade();
}
// Don't increment until after endcutscene check
@ -3809,12 +3872,6 @@ static void F_AdvanceToNextScene(void)
picxpos = cutscenes[cutnum]->scene[scenenum].xcoord[picnum];
picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum];
if (cutscenes[cutnum]->scene[scenenum].musswitch[0])
S_ChangeMusicEx(cutscenes[cutnum]->scene[scenenum].musswitch,
cutscenes[cutnum]->scene[scenenum].musswitchflags,
cutscenes[cutnum]->scene[scenenum].musicloop,
cutscenes[cutnum]->scene[scenenum].musswitchposition, 0, 0);
// Fade to the next
F_NewCutscene(cutscenes[cutnum]->scene[scenenum].text);
@ -3826,13 +3883,7 @@ static void F_AdvanceToNextScene(void)
animtimer = pictime = cutscenes[cutnum]->scene[scenenum].picduration[picnum];
if (rendermode != render_none)
{
F_CutsceneDrawer();
F_WipeEndScreen();
F_StartWipe(cutscenes[cutnum]->scene[scenenum].fadeoutid, true);
}
F_StartWipe(cutscenes[cutnum]->scene[scenenum].fadeoutid, 0);
}
// See also G_AfterIntermission, the only other place which handles intra-map/ending transitions
@ -3862,10 +3913,9 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
if (!cutscenes[cutscenenum])
return;
G_SetGamestate(GS_CUTSCENE);
boolean from_ending = gamestate == GS_ENDING;
if (wipegamestate == GS_CUTSCENE)
wipegamestate = -1;
G_SetGamestate(GS_CUTSCENE);
gameaction = ga_nothing;
paused = false;
@ -3901,6 +3951,10 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
else
S_StopMusic();
S_StopSounds();
if (!from_ending)
F_QueuePreWipe(wipedefs[wipe_cutscene_toblack], 0, NULL);
F_QueuePostWipe(wipedefs[wipe_cutscene_final], WSF_FADEIN, NULL);
}
//
@ -4616,7 +4670,9 @@ void F_TextPromptTicker(void)
void F_StartWaitingPlayers(void)
{
wipegamestate = GS_TITLESCREEN; // technically wiping from title screen
F_QueuePreWipe(0, 0, NULL);
F_QueuePostWipe(0, WSF_FADEIN, NULL);
finalecount = 0;
}
@ -4628,7 +4684,7 @@ void F_WaitingPlayersTicker(void)
finalecount++;
// dumb hack, only start the music on the 1st tick so if you instantly go into the map you aren't hearing a tic of music
if (finalecount == 2)
if (finalecount == 8)
S_ChangeMusicInternal("_CHSEL", true);
}

View file

@ -75,6 +75,8 @@ void F_StartContinue(void);
void F_ContinueTicker(void);
void F_ContinueDrawer(void);
void F_InitTitleScreen(void);
void F_StartWaitingPlayers(void);
void F_WaitingPlayersTicker(void);
void F_WaitingPlayersDrawer(void);
@ -88,7 +90,6 @@ extern INT32 intro_scenenum;
enum
{
INTRO_STJR = 0,
INTRO_FIRST = 1,
INTRO_ASTEROID = 4,
INTRO_RADAR = 5,
@ -163,16 +164,9 @@ void F_MenuPresTicker(void);
#endif
#define DEFAULTWIPE -1
#define IGNOREWIPE INT16_MAX
// HACK for menu fading while titlemapinaction; skips the level check
#define FORCEWIPE -3
#define FORCEWIPEOFF -2
extern boolean WipeInAction;
extern boolean WipeRunPre;
extern boolean WipeRunPost;
extern boolean WipeDrawMenu;
extern boolean wipe_running;
extern boolean wipe_drawmenuontop;
typedef enum
{
@ -180,22 +174,27 @@ typedef enum
WIPESTYLE_NORMAL,
WIPESTYLE_COLORMAP
} wipestyle_t;
extern wipestyle_t wipestyle;
extern wipestyle_t wipe_style;
typedef enum
{
WSF_FADEOUT = 1,
WSF_FADEIN = 1<<1,
WSF_TOWHITE = 1<<2,
WSF_CROSSFADE = 1<<3,
WSF_LEVELLOADING = 1<<4,
WSF_SPECIALSTAGE = 1<<5,
WSF_INTROSTART = 1<<6,
WSF_INTROEND = 1<<7,
WSF_FADEIN = 1,
WSF_TOWHITE = 1<<1,
WSF_CROSSFADE = 1<<2
} wipeflags_t;
extern wipeflags_t wipe_flags;
WSF_ACTION = (WSF_LEVELLOADING|WSF_SPECIALSTAGE|WSF_INTROSTART|WSF_INTROEND)
} wipestyleflags_t;
extern wipestyleflags_t wipestyleflags;
typedef void (*wipe_callback_t)(void);
typedef struct
{
UINT8 type;
wipestyle_t style;
wipeflags_t flags;
boolean drawmenuontop;
tic_t holdframes;
wipe_callback_t callback;
} wipe_t;
typedef enum
{
@ -205,24 +204,21 @@ typedef enum
} specialwipe_t;
extern specialwipe_t ranspecialwipe;
extern UINT8 wipetype;
extern UINT8 wipeframe;
void F_WipeSetStyle(void);
void F_WipeStartScreen(void);
void F_WipeEndScreen(void);
void F_WipeEndScreenRestore(void);
void F_StartWipe(UINT8 type, boolean drawMenu);
void F_StartWipe(UINT8 type, wipeflags_t flags);
void F_StartWipeParametrized(wipe_t *wipe);
void F_RunWipe(void);
void F_DisplayWipe(void);
void F_StopWipe(void);
void F_WipeStartPre(void);
void F_WipeStartPost(void);
void F_StopAllWipes(void);
void F_SetupFadeOut(wipeflags_t flags);
void F_QueuePreWipe(INT16 wipetypepre, wipeflags_t flags, wipe_callback_t callback);
void F_QueuePostWipe(INT16 wipetypepost, wipeflags_t flags, wipe_callback_t callback);
void F_WipeDoCrossfade(void);
boolean F_WipeDoTinted(void);
void F_StartPendingWipe(void);
wipe_t *F_GetQueuedWipe(void);
#define F_WipeColorFill(c) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, c)
@ -235,7 +231,6 @@ boolean F_WipeDoTinted(void);
tic_t F_GetWipeLength(UINT8 type);
boolean F_WipeExists(UINT8 type);
boolean F_WipeCanTint(void);
enum
{

View file

@ -88,19 +88,22 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
// SCREEN WIPE PACKAGE
//--------------------------------------------------------------------------
boolean WipeInAction = false;
boolean WipeRunPre = false;
boolean WipeRunPost = false;
boolean WipeDrawMenu = false;
#define WIPEQUEUESIZE 8
UINT8 wipetype = 0;
UINT8 wipeframe = 0;
static wipe_t wipe_queue[WIPEQUEUESIZE];
static unsigned wipe_numqueued = 0;
wipestyle_t wipestyle = WIPESTYLE_UNDEFINED;
wipestyleflags_t wipestyleflags = WSF_CROSSFADE;
static UINT8 wipe_type;
static UINT8 wipe_frame;
static boolean wipe_stopped = false;
static tic_t wipe_holdframes = 0;
wipestyle_t wipe_style = WIPESTYLE_UNDEFINED;
wipeflags_t wipe_flags = WSF_CROSSFADE;
specialwipe_t ranspecialwipe = SPECIALWIPE_NONE;
static INT32 wipedefindex = 0;
boolean wipe_running = false;
boolean wipe_drawmenuontop = false;
#ifndef NOWIPE
static UINT8 *wipe_scr_start; //screen 3
@ -166,7 +169,7 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
{
// Determine pixel to use from fademask
pcolor = &pMasterPalette[*lump++];
if (wipestyle == WIPESTYLE_COLORMAP)
if (wipe_style == WIPESTYLE_COLORMAP)
*mask++ = pcolor->s.red / FADECOLORMAPDIV;
else
*mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS;
@ -317,12 +320,10 @@ static void F_DoColormapWipe(fademask_t *fademask, UINT8 *colormap)
{
// wipe screen, start, end
UINT8 *w = wipe_scr;
const UINT8 *s = wipe_scr_start;
const UINT8 *e = wipe_scr_end;
// first pixel for each screen
UINT8 *w_base = w;
const UINT8 *s_base = s;
const UINT8 *e_base = e;
// mask data, end
@ -365,47 +366,25 @@ static void F_DoColormapWipe(fademask_t *fademask, UINT8 *colormap)
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
if (*mask == 0)
int nmask = *mask;
if (wipe_flags & WSF_FADEIN)
nmask = (FADECOLORMAPROWS-1) - nmask;
transtbl = colormap + (nmask * 256);
// DRAWING LOOP
while (draw_linestogo--)
{
// shortcut - memcpy source to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
}
else if (*mask >= FADECOLORMAPROWS)
{
// shortcut - memcpy target to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
}
else
{
int nmask = *mask;
if (wipestyleflags & WSF_FADEIN)
nmask = (FADECOLORMAPROWS-1) - nmask;
transtbl = colormap + (nmask * 256);
// DRAWING LOOP
while (draw_linestogo--)
{
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
while (draw_rowstogo--)
*w++ = transtbl[*e++];
relativepos += vid.width;
}
// END DRAWING LOOP
w = w_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
while (draw_rowstogo--)
*w++ = transtbl[*e++];
relativepos += vid.width;
}
// END DRAWING LOOP
if (++maskx >= fademask->width)
++masky, maskx = 0;
@ -453,112 +432,79 @@ void F_WipeEndScreen(void)
#endif
}
/** Saves the "after" screen of a wipe, and copies the "before" screen into the main screen.
*/
void F_WipeEndScreenRestore(void)
static boolean F_WipeCanTint(wipeflags_t flags)
{
#ifndef NOWIPE
#ifdef HWRENDER
if (rendermode == render_opengl)
{
HWR_EndScreenWipe(true);
return;
}
#endif
if (flags & WSF_CROSSFADE)
return false;
F_WipeEndScreen();
VID_BlitLinearScreen(screens[3], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
#endif
}
/** Verifies every condition for a tinted fade.
*/
boolean F_WipeCanTint(void)
{
if ((wipestyleflags & (WSF_FADEIN|WSF_FADEOUT)) // only if one of those wipestyleflags are actually set
&& !(wipestyleflags & WSF_CROSSFADE)) // and if not crossfading
{
switch (gamestate)
{
case GS_LEVEL:
case GS_TITLESCREEN:
case GS_CONTINUING:
case GS_CREDITS:
case GS_EVALUATION:
case GS_ENDING:
case GS_TIMEATTACK:
return true;
case GS_INTRO:
return (intro_scenenum <= INTRO_FIRST);
default:
return false;
}
}
return false;
return true;
}
/** Decides what wipe style to use.
*/
void F_WipeSetStyle(void)
static wipestyle_t F_WipeGetStyle(wipeflags_t flags)
{
// Set default wipe style
wipestyle = WIPESTYLE_NORMAL;
// Check for colormap wipe style
if (F_WipeCanTint())
wipestyle = WIPESTYLE_COLORMAP;
if (F_WipeCanTint(flags))
return WIPESTYLE_COLORMAP;
else
return WIPESTYLE_NORMAL;
}
/** Attempts to run a tinted fade.
*
* \return if true, a tinted fade can run
*/
boolean F_WipeDoTinted(void)
static void F_RestartWipe(void)
{
#ifndef NOWIPE
UINT8 color = (wipestyleflags & WSF_TOWHITE) ? 0 : 31;
#endif
if (!wipe_numqueued)
return;
if (F_WipeCanTint())
{
#if !defined(NOWIPE) && defined(HWRENDER)
if (rendermode == render_opengl)
F_WipeColorFill(color);
#endif
return true;
}
else
{
#ifndef NOWIPE
F_WipeColorFill(color);
#endif
return false;
}
wipe_t *curwipe = &wipe_queue[0];
wipe_running = true;
wipe_stopped = false;
wipe_type = curwipe->type;
wipe_style = curwipe->style;
wipe_flags = curwipe->flags;
wipe_holdframes = curwipe->holdframes;
wipe_drawmenuontop = curwipe->drawmenuontop;
wipe_frame = 0;
}
void F_StartPendingWipe(void)
{
if (wipe_numqueued)
F_RestartWipe();
}
/** After setting up the screens you want to wipe,
* calling this will do a 'typical' wipe.
*/
void F_StartWipe(UINT8 type, boolean drawMenu)
void F_StartWipe(UINT8 type, wipeflags_t flags)
{
wipe_t wipe = {0};
wipe.style = F_WipeGetStyle(flags);
wipe.flags = flags;
wipe.type = type;
wipe.drawmenuontop = true;
F_StartWipeParametrized(&wipe);
}
void F_StartWipeParametrized(wipe_t *wipe)
{
#ifdef NOWIPE
(void)type;
(void)drawMenu;
(void)wipe;
#else
if (!paldiv)
paldiv = FixedDiv(257<<FRACBITS, 11<<FRACBITS);
// Init the wipe
if (wipestyle == WIPESTYLE_UNDEFINED)
F_WipeSetStyle();
WipeInAction = true;
WipeDrawMenu = drawMenu;
wipetype = type;
wipeframe = 0;
#endif
if (wipe_numqueued >= WIPEQUEUESIZE)
{
// Can't queue it, but its callback has to run.
if (wipe->callback)
wipe->callback();
return;
}
wipe_queue[wipe_numqueued] = *wipe;
wipe_numqueued++;
}
/** Runs the current wipe.
@ -566,14 +512,32 @@ void F_StartWipe(UINT8 type, boolean drawMenu)
void F_RunWipe(void)
{
#ifndef NOWIPE
fademask_t *fmask = F_GetFadeMask(wipetype, wipeframe);
if (!wipe_numqueued)
return;
if (wipe_stopped)
{
wipe_holdframes--;
if (wipe_holdframes <= 0)
F_StopWipe();
return;
}
fademask_t *fmask = F_GetFadeMask(wipe_type, wipe_frame);
if (!fmask)
{
wipe_stopped = true;
if (wipe_holdframes)
{
if (!(wipe_flags & WSF_FADEIN))
wipe_frame--;
return;
}
F_StopWipe();
return;
}
wipeframe++;
wipe_frame++;
#else
F_StopWipe();
#endif
@ -583,82 +547,34 @@ void F_RunWipe(void)
*/
void F_StopWipe(void)
{
// TODO maybe just add callbacks instead
boolean runtitle = (wipestyleflags & WSF_INTROEND);
void (*callback)(void) = NULL;
WipeInAction = false;
WipeDrawMenu = false;
if (wipe_numqueued)
{
callback = wipe_queue[0].callback;
wipe_numqueued--;
if (wipe_numqueued)
memmove(&wipe_queue[0], &wipe_queue[1], wipe_numqueued * sizeof(wipe_t));
}
wipe_stopped = false;
wipe_running = false;
wipe_drawmenuontop = false;
if (titlecard.wipe)
titlecard.wipe = 0;
if (wipestyleflags & WSF_SPECIALSTAGE)
{
// #ifndef NOWIPE
#if 0
tic_t starttime = I_GetTime(), lasttime = starttime;
tic_t endtime = starttime + (3*TICRATE)/2;
tic_t nowtime = starttime;
if (callback)
callback();
}
// Hold on white for extra effect.
// TODO don't do this lol
while (nowtime < endtime)
{
while (!((nowtime = I_GetTime()) - lasttime))
I_Sleep();
lasttime = nowtime;
void F_StopAllWipes(void)
{
wipe_numqueued = 0;
I_OsPolling();
if (moviemode) // make sure we save frames for the white hold too
M_SaveFrame();
}
#endif
wipestyleflags &= ~WSF_SPECIALSTAGE;
}
if (wipestyleflags & WSF_LEVELLOADING)
G_DoLoadLevel();
else if (wipestyleflags & WSF_INTROSTART)
S_ChangeMusicInternal("_intro", false);
wipestyleflags &= ~WSF_ACTION;
wipestyle = WIPESTYLE_UNDEFINED;
if (runtitle)
{
// #ifndef NOWIPE
#if 0
// Stay on black for a bit. =)
// TODO this neither
tic_t nowtime, quittime, lasttime;
nowtime = lasttime = I_GetTime();
quittime = nowtime + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds
while (quittime > nowtime)
{
while (!((nowtime = I_GetTime()) - lasttime))
I_Sleep();
lasttime = nowtime;
I_OsPolling();
I_UpdateNoBlit();
#ifdef HAVE_THREADS
I_lock_mutex(&m_menu_mutex);
#endif
M_Drawer(); // menu is drawn even on top of wipes
#ifdef HAVE_THREADS
I_unlock_mutex(m_menu_mutex);
#endif
I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001
if (moviemode) // make sure we save frames for the white hold too
M_SaveFrame();
}
#endif
D_StartTitle();
wipegamestate = GS_INTRO;
}
F_StopWipe();
}
#ifndef NOWIPE
@ -666,20 +582,20 @@ void F_StopWipe(void)
*/
static void F_RenderWipe(fademask_t *fmask)
{
switch (wipestyle)
switch (wipe_style)
{
case WIPESTYLE_COLORMAP:
#ifdef HWRENDER
if (rendermode == render_opengl)
{
// send in the wipe type and wipe frame because we need to cache the graphic
HWR_DoTintedWipe(wipetype, wipeframe-1);
HWR_DoTintedWipe(wipe_type, wipe_frame-1);
}
else
#endif
{
UINT8 *colormap = fadecolormap;
if (wipestyleflags & WSF_TOWHITE)
if (wipe_flags & WSF_TOWHITE)
colormap += (FADECOLORMAPROWS * 256);
F_DoColormapWipe(fmask, colormap);
}
@ -689,7 +605,7 @@ static void F_RenderWipe(fademask_t *fmask)
if (rendermode == render_opengl)
{
// send in the wipe type and wipe frame because we need to cache the graphic
HWR_DoWipe(wipetype, wipeframe-1);
HWR_DoWipe(wipe_type, wipe_frame-1);
}
else
#endif
@ -706,19 +622,16 @@ static void F_RenderWipe(fademask_t *fmask)
void F_DisplayWipe(void)
{
#ifndef NOWIPE
fademask_t *fmask;
wipe_scr = screens[0];
// get fademask first so we can tell if it exists or not
fmask = F_GetFadeMask(wipetype, wipeframe);
fademask_t *fmask = F_GetFadeMask(wipe_type, wipe_frame);
if (!fmask)
{
// Save screen for post-wipe
//if (WipeRunPre)
if (!(wipestyleflags & WSF_CROSSFADE))
if (!(wipe_flags & WSF_CROSSFADE))
{
fmask = F_GetFadeMask(wipetype, wipeframe-1);
WipeRunPre = false; // Disable post-wipe flag
fmask = F_GetFadeMask(wipe_type, wipe_frame-1);
if (!fmask)
return;
else
@ -734,101 +647,99 @@ void F_DisplayWipe(void)
#endif
}
/** Starts the "pre" type of a wipe.
*/
void F_WipeStartPre(void)
static int F_GetWipedefIndex(void)
{
// set for all later
wipedefindex = gamestate; // wipe_xxx_toblack
int index = gamestate; // wipe_xxx_toblack
if (gamestate == GS_INTERMISSION)
{
if (intertype == int_spec) // Special Stage
wipedefindex = wipe_specinter_toblack;
index = wipe_specinter_toblack;
else if (intertype != int_coop) // Multiplayer
wipedefindex = wipe_multinter_toblack;
index = wipe_multinter_toblack;
}
if (wipetypepre == DEFAULTWIPE || !F_WipeExists(wipetypepre))
wipetypepre = wipedefs[wipedefindex];
return index;
}
if (rendermode != render_none)
wipe_t *F_GetQueuedWipe(void)
{
if (wipe_numqueued)
return &wipe_queue[0];
return NULL;
}
void F_SetupFadeOut(wipeflags_t flags)
{
F_WipeStartScreen();
UINT8 wipecolor = (flags & WSF_TOWHITE) ? 0 : 31;
#ifndef NOWIPE
if (F_WipeCanTint(flags))
{
WipeRunPre = true;
// Fade to black first
if ((wipegamestate == (gamestate_t)FORCEWIPE ||
(wipegamestate != (gamestate_t)FORCEWIPEOFF
&& !(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)))
) // fades to black on its own timing, always
&& wipetypepre != UINT8_MAX)
{
F_WipeStartScreen();
// Do a tinted wipe.
wipestyleflags = WSF_FADEOUT;
if (wipegamestate == (gamestate_t)FORCEWIPE)
F_WipeColorFill(31);
else if (F_WipeDoTinted())
wipetypepost = DEFAULTWIPE;
F_WipeEndScreen();
F_StartWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
WipeRunPost = true;
}
#ifdef HWRENDER
if (rendermode == render_opengl)
F_WipeColorFill(wipecolor);
#endif
}
else
#endif
{
F_WipeColorFill(wipecolor);
}
wipetypepre = DEFAULTWIPE;
wipegamestate = gamestate;
F_WipeEndScreen();
}
/** Starts the "pre" type of a wipe.
*/
void F_QueuePreWipe(INT16 wipetypepre, wipeflags_t flags, wipe_callback_t callback)
{
if (wipetypepre == DEFAULTWIPE || !F_WipeExists(wipetypepre))
wipetypepre = wipedefs[F_GetWipedefIndex()];
// Fade to black first
if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) // fades to black on its own timing, always
&& wipetypepre != UINT8_MAX)
{
wipe_t wipe = {0};
wipe.flags = flags;
wipe.style = F_WipeGetStyle(wipe.flags);
wipe.type = wipetypepre;
wipe.drawmenuontop = gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN;
wipe.callback = callback;
F_StartWipeParametrized(&wipe);
}
}
/** Starts the "post" type of a wipe.
*/
void F_WipeStartPost(void)
void F_QueuePostWipe(INT16 wipetypepost, wipeflags_t flags, wipe_callback_t callback)
{
wipedefindex += WIPEFINALSHIFT;
if (wipetypepost == DEFAULTWIPE || !F_WipeExists(wipetypepost))
wipetypepost = wipedefs[wipedefindex];
wipetypepost = wipedefs[F_GetWipedefIndex() + WIPEFINALSHIFT];
if (rendermode != render_none)
{
F_WipeEndScreen();
// Do a tinted wipe.
if (F_WipeCanTint())
{
wipestyleflags |= WSF_FADEIN;
wipestyleflags &= ~(WSF_FADEOUT|WSF_ACTION);
}
F_StartWipe(wipetypepost, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
}
// reset counters so timedemo doesn't count the wipe duration
if (timingdemo)
{
framecount = 0;
demostarttime = I_GetTime();
}
wipetypepost = DEFAULTWIPE;
WipeRunPost = false;
wipe_t wipe = {0};
wipe.flags = flags;
wipe.style = F_WipeGetStyle(wipe.flags);
wipe.type = wipetypepost;
wipe.drawmenuontop = gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN;
wipe.callback = callback;
F_StartWipeParametrized(&wipe);
}
/** Does a crossfade.
*/
void F_WipeDoCrossfade(void)
{
// Set the wipe parameters
wipetypepost = wipedefs[gamestate + wipedefindex];
wipestyle = WIPESTYLE_NORMAL;
wipestyleflags = WSF_CROSSFADE;
// Capture the current screen. Last, if done during gamelogic.
F_WipeStartScreen();
WipeRunPost = true;
WipeInAction = false;
wipe_t wipe = {0};
wipe.flags = WSF_CROSSFADE | WSF_FADEIN;
wipe.style = WIPESTYLE_NORMAL;
wipe.type = wipedefs[F_GetWipedefIndex()];
wipe.drawmenuontop = false;
F_StartWipeParametrized(&wipe);
}
/** Returns tic length of wipe

View file

@ -2879,7 +2879,6 @@ void G_StopDemo(void)
Y_EndIntermission(); // cleanup
G_SetGamestate(GS_NULL);
wipegamestate = GS_NULL;
SV_StopServer();
SV_ResetServer();
}

View file

@ -1181,7 +1181,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
// Or, if the level is starting.
// Or, for that matter, if we're being reborn.
// ...OR if we're blindfolded. No looking into the floor.
if (ignoregameinputs || paused || P_AutoPause() || (levelstarting || WipeInAction) || titlecard.prelevel
if (ignoregameinputs || paused || P_AutoPause() || (levelstarting || wipe_running) || titlecard.prelevel
|| (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametyperules & GTR_TAG)
&& (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT)))))
{//@TODO splitscreen player
@ -1855,14 +1855,10 @@ void G_StartLevel(boolean resetplayer)
levelstarttic = gametic; // for time calculation
levelresetplayer = resetplayer;
if (wipegamestate == GS_LEVEL)
wipegamestate = -1; // force a wipe
if (gamestate == GS_INTERMISSION)
Y_EndIntermission();
G_InitLevelGametype();
ranspecialwipe = SPECIALWIPE_NONE;
if (mapheaderinfo[gamemap-1]->runsoc[0] != '#')
P_RunSOC(mapheaderinfo[gamemap-1]->runsoc);
@ -1880,8 +1876,11 @@ void G_StartLevel(boolean resetplayer)
G_SetMouseDeltas(0, 0, 1);
G_SetMouseDeltas(0, 0, 2);
if (titlemapinaction)
return;
#ifndef NOWIPE
if (!G_GetRetryRA() && rendermode != render_none)
if (!G_GetRetryRA())
G_StartLevelWipe();
else
#endif
@ -2036,7 +2035,11 @@ void G_DoLoadLevel(void)
if (demoplayback && !timingdemo)
precache = true;
if (timingdemo)
{
framecount = 0;
demostarttime = I_GetTime();
G_DoneLevelLoad();
}
if (metalrecording)
G_BeginMetal();
@ -2050,26 +2053,22 @@ void G_DoLoadLevel(void)
//
void G_StartLevelWipe(void)
{
// Cancel all d_main.c fades
WipeRunPost = false;
wipegamestate = FORCEWIPEOFF;
wipestyle = WIPESTYLE_COLORMAP;
wipestyleflags = (WSF_FADEOUT|WSF_LEVELLOADING);
F_StopAllWipes();
ranspecialwipe = SPECIALWIPE_NONE;
// Special stage fade to white
// This is handled BEFORE sounds are stopped.
if (rendermode != render_none && G_IsSpecialStage(gamemap))
if (G_IsSpecialStage(gamemap))
{
// TODO call this after rendering the frame (because of F_WipeStartScreen calls)
P_RunSpecialStageWipe();
ranspecialwipe = SPECIALWIPE_SSTAGE;
}
// Let's fade to black here
// But only if we didn't do the special stage wipe
if (rendermode != render_none && ranspecialwipe == SPECIALWIPE_NONE)
if (ranspecialwipe == SPECIALWIPE_NONE)
{
// TODO same thing as the last one
P_RunLevelWipe();
// Fade out music here. Deduct 2 tics so the fade volume actually reaches 0.
@ -2082,23 +2081,38 @@ void G_StartLevelWipe(void)
}
}
static void G_DoLevelFadeIn(void)
{
wipeflags_t flags = WSF_FADEIN;
if (ranspecialwipe == SPECIALWIPE_SSTAGE)
flags |= WSF_TOWHITE;
wipe_t wipe = {0};
wipe.style = WIPESTYLE_COLORMAP;
wipe.flags = flags;
wipe.type = wipedefs[wipe_level_final];
wipe.drawmenuontop = true;
F_StartWipeParametrized(&wipe);
}
//
// Start the title card.
//
void TitleCard_Start(void)
{
// The title card has been disabled for this map
if (!TitleCard_Available())
if (!TitleCard_IsAvailable())
{
G_DoLevelFadeIn();
ranspecialwipe = SPECIALWIPE_NONE;
st_translucency = cv_translucenthud.value; // Reset the HUD translucency!
WipeRunPost = true; // Start the post wipe.
return;
}
CON_ClearHUD();
TitleCard_LoadGraphics();
// Actually start it
titlecard.running = true;
titlecard.prelevel = true;
@ -2114,8 +2128,6 @@ void TitleCard_Start(void)
patch_t *patch = (patch_t *)titlecard.patches[1];
titlecard.zigzag = -(SHORT(patch->width) * FRACUNIT);
}
wipetypepost = IGNOREWIPE;
}
//
@ -2153,7 +2165,7 @@ void TitleCard_LoadGraphics(void)
//
void TitleCard_Run(void)
{
if (!TitleCard_Available())
if (!TitleCard_IsAvailable())
return;
if (titlecard.wipe)
@ -2166,13 +2178,16 @@ void TitleCard_Run(void)
}
else if (titlecard.ticker >= PRELEVELTIME && titlecard.prelevel)
{
// Force a wipe
wipegamestate = -1;
WipeRunPost = true;
// TODO should be done after rendering
if (!cv_showhud.value)
{
F_WipeDoCrossfade();
}
else
{
G_DoLevelFadeIn();
}
ranspecialwipe = SPECIALWIPE_NONE;
// Disable prelevel flag
titlecard.prelevel = false;
@ -2215,12 +2230,19 @@ void TitleCard_Run(void)
}
}
void TitleCard_Stop(void)
{
titlecard.running = false;
titlecard.prelevel = false;
titlecard.wipe = 0;
}
static boolean titlecardforreload = false;
//
// Returns true if the current level has a title card.
//
boolean TitleCard_Available(void)
boolean TitleCard_IsAvailable(void)
{
// The current level header explicitly disabled the title card.
UINT16 titleflag = LF_NOTITLECARDFIRST;
@ -2527,7 +2549,7 @@ static void G_MarathonTicker(void)
// IGT doesn't increase during loads, unless the game's paused
if (!(paused || P_AutoPause()))
{
if (titlecard.prelevel || WipeInAction)
if (titlecard.prelevel || wipe_running)
return;
}
@ -2538,7 +2560,7 @@ static void G_MarathonTicker(void)
// G_Ticker
// Make ticcmd_ts for the players.
//
void G_Ticker(boolean run, tic_t tics)
void G_Ticker(boolean run)
{
UINT32 i;
INT32 buf;
@ -2561,11 +2583,11 @@ void G_Ticker(boolean run, tic_t tics)
}
// Run the current wipe
if (WipeInAction)
if (wipe_running)
{
if (run)
{
boolean loading = (wipestyleflags & WSF_LEVELLOADING);
boolean loading = levelloading;
switch (gamestate)
{
@ -2579,7 +2601,7 @@ void G_Ticker(boolean run, tic_t tics)
}
// Run the title card
if (titlecard.running && (wipestyleflags & WSF_FADEIN))
if (titlecard.running && (wipe_flags & WSF_FADEIN))
TitleCard_Run();
// Run Marathon Mode in-game timer
@ -2663,7 +2685,7 @@ void G_Ticker(boolean run, tic_t tics)
case GS_LEVEL:
if (titlecard.running)
{
if (run && tics <= 1)
if (run)
TitleCard_Run();
if (titlecard.prelevel)
{
@ -2782,16 +2804,13 @@ static void G_CheckPlayerReborn(void)
P_MapStart();
if (gamestate == GS_LEVEL)
if (gamestate == GS_LEVEL && !levelstarting)
{
// Or, alternatively, retry.
if (!(netgame || multiplayer) && G_GetRetrySP())
{
G_ClearRetrySP();
if (WipeInAction)
F_StopWipe();
if (modeattacking)
{
pausedelay = INT32_MIN;
@ -4341,13 +4360,14 @@ static void G_DoCompleted(void)
gameaction = ga_nothing;
TitleCard_Stop();
if (metalplayback)
G_StopMetalDemo();
if (metalrecording)
G_StopMetalRecording(false);
G_SetGamestate(GS_NULL);
wipegamestate = GS_NULL;
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
@ -4579,6 +4599,8 @@ static void G_DoStartContinue(void)
{
I_Assert(!netgame && !multiplayer);
TitleCard_Stop();
G_PlayerFinishLevel(consoleplayer); // take away cards and stuff
F_StartContinue();
@ -5798,27 +5820,18 @@ boolean G_GetExitGameFlag(void)
// Retrying flags
//
#define CheckRetryFlag(type) \
{ \
if (type < 0 || type >= RETRY_MAX) \
I_Error("G_SetRetryFlag: out of bounds retry flag type (%d)", type); \
}
void G_SetRetryFlag(INT32 type)
{
CheckRetryFlag(type);
retrying[type] = true;
}
void G_ClearRetryFlag(INT32 type)
{
CheckRetryFlag(type);
retrying[type] = false;
}
boolean G_GetRetryFlag(INT32 type)
{
CheckRetryFlag(type);
return retrying[type];
}

View file

@ -189,8 +189,11 @@ void G_DoLoadLevel(void);
// Title card
void TitleCard_Start(void);
void TitleCard_Run(void);
void TitleCard_Stop(void);
void TitleCard_LoadGraphics(void);
boolean TitleCard_Available(void);
boolean TitleCard_IsAvailable(void);
typedef struct
{
@ -249,7 +252,7 @@ void G_UseContinue(void);
void G_AfterIntermission(void);
void G_EndGame(void); // moved from y_inter.c/h and renamed
void G_Ticker(boolean run, tic_t tics);
void G_Ticker(boolean run);
boolean G_Responder(event_t *ev);
boolean G_LuaResponder(event_t *ev);

View file

@ -2952,7 +2952,6 @@ static void M_HandleMenuPresState(menu_t *newMenu)
}
}
// Set the wipes for next frame
if (
(exitwipe >= 0 && enterlevel <= exitlevel) ||
@ -2960,23 +2959,27 @@ static void M_HandleMenuPresState(menu_t *newMenu)
(anceslevel < 0 && newMenu != &MainDef && currentMenu != &MainDef)
)
{
INT16 wipetypepre = DEFAULTWIPE;
INT16 wipetypepost = DEFAULTWIPE;
if (gamestate == GS_TIMEATTACK)
wipetypepre = ((exitwipe && enterlevel <= exitlevel) || anceslevel < 0) ? exitwipe : DEFAULTWIPE; // force default
else
// HACK: INT16_MAX signals to not wipe
// because 0 is a valid index and -1 means default
wipetypepre = ((exitwipe && enterlevel <= exitlevel) || anceslevel < 0) ? exitwipe : IGNOREWIPE;
wipetypepost = ((enterwipe && enterlevel >= exitlevel) || anceslevel < 0) ? enterwipe : IGNOREWIPE;
wipegamestate = FORCEWIPE;
wipetypepre = ((exitwipe && enterlevel <= exitlevel) || anceslevel < 0) ? exitwipe : INT16_MAX;
wipetypepost = ((enterwipe && enterlevel >= exitlevel) || anceslevel < 0) ? enterwipe : INT16_MAX;
// If just one of the above is a force not-wipe,
// mirror the other wipe.
if (wipetypepre != IGNOREWIPE && wipetypepost == IGNOREWIPE)
if (wipetypepre != INT16_MAX && wipetypepost == INT16_MAX)
wipetypepost = wipetypepre;
else if (wipetypepost != IGNOREWIPE && wipetypepre == IGNOREWIPE)
else if (wipetypepost != INT16_MAX && wipetypepre == INT16_MAX)
wipetypepre = wipetypepost;
// D_Display runs the next step of processing
F_StopAllWipes();
F_QueuePreWipe(wipetypepre, 0, NULL);
F_QueuePostWipe(wipetypepost, 0, NULL);
}
}
@ -3000,7 +3003,6 @@ static void M_GoBack(INT32 choice)
if ((currentMenu->prevMenu == &MainDef) && (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef || currentMenu == &SP_MarathonDef))
{
// D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate.
if (levelselect.rows)
{
Z_Free(levelselect.rows);
@ -3008,7 +3010,7 @@ static void M_GoBack(INT32 choice)
}
menuactive = false;
wipetypepre = menupres[M_GetYoungestChildMenu()].exitwipe;
F_QueuePreWipe(menupres[M_GetYoungestChildMenu()].exitwipe, 0, F_InitTitleScreen);
I_UpdateMouseGrab();
D_StartTitle();
}
@ -3166,7 +3168,7 @@ boolean M_Responder(event_t *ev)
if (gamestate == GS_TITLESCREEN && finalecount < (cv_tutorialprompt.value ? TICRATE : 0))
return false;
if (gamestate == GS_TIMEATTACK && WipeInAction)
if (gamestate == GS_TIMEATTACK && wipe_running)
return false;
if (CON_Ready())
@ -10140,6 +10142,8 @@ static void M_TimeAttack(INT32 choice)
M_PatchSkinNameTable();
F_StopAllWipes();
G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching
titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please
M_SetupNextMenu(&SP_TimeAttackDef);
@ -10148,6 +10152,12 @@ static void M_TimeAttack(INT32 choice)
else
Nextmap_OnChange();
if (!F_GetQueuedWipe())
{
F_QueuePreWipe(wipedefs[wipe_level_toblack], 0, NULL);
F_QueuePostWipe(menupres[MN_SP_TIMEATTACK].enterwipe, WSF_FADEIN, NULL);
}
itemOn = tastart; // "Start" is selected.
}
@ -10348,6 +10358,8 @@ static void M_NightsAttack(INT32 choice)
// This is really just to make sure Sonic is the played character, just in case
M_PatchSkinNameTable();
F_StopAllWipes();
ntssupersonic[0] = W_CachePatchName("NTSSONC1", PU_PATCH);
ntssupersonic[1] = W_CachePatchName("NTSSONC2", PU_PATCH);
@ -10359,6 +10371,12 @@ static void M_NightsAttack(INT32 choice)
else
Nextmap_OnChange();
if (!F_GetQueuedWipe())
{
F_QueuePreWipe(wipedefs[wipe_level_toblack], 0, NULL);
F_QueuePostWipe(menupres[MN_SP_NIGHTSATTACK].enterwipe, WSF_FADEIN, NULL);
}
itemOn = nastart; // "Start" is selected.
}
@ -10666,23 +10684,31 @@ static void M_ModeAttackEndGame(INT32 choice)
Command_ExitGame_f();
M_StartControlPanel();
INT16 wipetype;
switch(modeattacking)
{
default:
case ATTACKING_RECORD:
currentMenu = &SP_TimeAttackDef;
wipetypepost = menupres[MN_SP_TIMEATTACK].enterwipe;
wipetype = menupres[MN_SP_TIMEATTACK].enterwipe;
break;
case ATTACKING_NIGHTS:
currentMenu = &SP_NightsAttackDef;
wipetypepost = menupres[MN_SP_NIGHTSATTACK].enterwipe;
wipetype = menupres[MN_SP_NIGHTSATTACK].enterwipe;
break;
}
itemOn = currentMenu->lastOn;
G_SetGamestate(GS_TIMEATTACK);
modeattacking = ATTACKING_NONE;
M_ChangeMenuMusic("_title", true);
Nextmap_OnChange();
F_StopAllWipes();
F_QueuePreWipe(wipedefs[wipe_level_toblack], 0, NULL);
F_QueuePostWipe(wipetype, WSF_FADEIN, NULL);
}
static void M_MarathonLiveEventBackup(INT32 choice)
@ -10755,6 +10781,8 @@ static void M_Marathon(INT32 choice)
M_ChangeMenuMusic("spec8", true);
F_StopAllWipes();
SP_MarathonDef.prevMenu = &MainDef;
G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching
titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please
@ -10762,6 +10790,12 @@ static void M_Marathon(INT32 choice)
itemOn = marathonstart; // "Start" is selected.
recatkdrawtimer = (50-8) * FRACUNIT;
char_scroll = 0;
if (!F_GetQueuedWipe())
{
F_QueuePreWipe(wipedefs[wipe_level_toblack], 0, NULL);
F_QueuePostWipe(menupres[MN_SP_MARATHON].enterwipe, WSF_FADEIN, NULL);
}
}
static void M_HandleMarathonChoosePlayer(INT32 choice)

View file

@ -994,7 +994,6 @@ void CL_ConnectToServer(void)
DEBFILE(va("waiting %d nodes\n", doomcom->numnodes));
G_SetGamestate(GS_WAITINGPLAYERS);
wipegamestate = GS_WAITINGPLAYERS;
ClearAdminPlayers();
pnumnodes = 1;

View file

@ -820,7 +820,7 @@ void SV_StopServer(void)
{
if (gamestate == GS_INTERMISSION)
Y_EndIntermission();
gamestate = wipegamestate = GS_NULL;
gamestate = GS_NULL;
localtextcmd[0] = 0;
localtextcmd2[0] = 0;
@ -1239,7 +1239,7 @@ boolean TryRunTics(tic_t realtics)
if (update_stats)
PS_START_TIMING(ps_tictime);
G_Ticker((gametic % NEWTICRATERATIO) == 0, (neededtic - gametic));
G_Ticker((gametic % NEWTICRATERATIO) == 0);
ExtraDataTicker();
gametic++;
consistancy[gametic%BACKUPTICS] = Consistancy();

View file

@ -4540,11 +4540,6 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
}
G_StartLevelWipe();
wipestyleflags &= ~WSF_ACTION;
F_StopWipe();
WipeRunPost = false;
wipetypepre = wipetypepost = IGNOREWIPE;
titlecard.prelevel = false;

View file

@ -7543,39 +7543,31 @@ void P_RunSpecialStageWipe(void)
(mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap - 1]->musname : mapmusname, 7))
S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)
F_WipeStartScreen();
wipestyleflags |= WSF_TOWHITE|WSF_SPECIALSTAGE;
if (titlemapinaction || F_GetQueuedWipe())
return;
#ifdef HWRENDER
// uh..........
if (rendermode == render_opengl)
F_WipeColorFill(0);
#endif
F_WipeEndScreen();
F_StartWipe(wipedefs[wipe_speclevel_towhite], false);
wipe_t wipe = {0};
wipe.style = WIPESTYLE_COLORMAP;
wipe.flags = WSF_TOWHITE;
wipe.callback = G_DoLoadLevel;
wipe.type = wipedefs[wipe_speclevel_towhite];
wipe.drawmenuontop = false;
wipe.holdframes = (3*TICRATE)/2;
F_StartWipeParametrized(&wipe);
}
void P_RunLevelWipe(void)
{
F_WipeStartScreen();
if (titlemapinaction || F_GetQueuedWipe())
return;
#ifdef HWRENDER
// uh..........
if (rendermode == render_opengl)
F_WipeColorFill(31);
#endif
F_WipeEndScreen();
// for titlemap: run a specific wipe if specified
// needed for exiting time attack
if (wipetypepre != IGNOREWIPE)
F_StartWipe(
(wipetypepre != DEFAULTWIPE && F_WipeExists(wipetypepre)) ? wipetypepre : wipedefs[wipe_level_toblack],
true);
wipetypepre = DEFAULTWIPE;
wipe_t wipe = {0};
wipe.style = WIPESTYLE_COLORMAP;
wipe.flags = 0;
wipe.callback = G_DoLoadLevel;
wipe.type = wipedefs[wipe_level_toblack];
wipe.drawmenuontop = false;
F_StartWipeParametrized(&wipe);
}
static void P_InitPlayers(void)
@ -7772,7 +7764,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
}
}
levelfadecol = (ranspecialwipe) ? 0 : 31;
levelfadecol = ranspecialwipe ? 0 : 31;
// Close text prompt before freeing the old level
F_EndTextPrompt(false, true);
@ -7944,19 +7936,25 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
R_ResetViewInterpolation(0);
R_UpdateMobjInterpolators();
titlecard.running = false;
titlecard.prelevel = false;
titlecard.wipe = 0;
TitleCard_Stop();
// Don't run wipes for the titlemap
if (titlemapinaction)
return true;
if (ranspecialwipe == SPECIALWIPE_RETRY)
{
// Force a wipe
wipegamestate = -1;
wipestyleflags = (WSF_TOWHITE|WSF_FADEIN);
WipeRunPost = true;
wipe_t wipe = {0};
wipe.style = WIPESTYLE_COLORMAP;
wipe.flags = WSF_TOWHITE | WSF_FADEIN;
wipe.type = wipedefs[wipe_level_final];
wipe.drawmenuontop = true;
F_StartWipeParametrized(&wipe);
// Reset the HUD translucency!
st_translucency = cv_translucenthud.value;
ranspecialwipe = SPECIALWIPE_NONE;
}
else
{
@ -7964,7 +7962,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
TitleCard_Start();
}
ranspecialwipe = SPECIALWIPE_NONE;
return true;
}

View file

@ -2327,15 +2327,10 @@ void S_StopMusic(void)
{
if (closedcaptions[0].s-S_sfx == sfx_None)
{
if (gamestate != wipegamestate)
{
closedcaptions[0].c = NULL;
closedcaptions[0].s = NULL;
closedcaptions[0].t = 0;
closedcaptions[0].b = 0;
}
else
closedcaptions[0].t = CAPTIONFADETICS;
closedcaptions[0].c = NULL;
closedcaptions[0].s = NULL;
closedcaptions[0].t = 0;
closedcaptions[0].b = 0;
}
}
}

View file

@ -182,10 +182,9 @@ void SCR_SetMode(void)
if (dedicated)
return;
if (!(setmodeneeded || setrenderneeded) || WipeInAction)
return; // should never happen and don't change it during a wipe, BAD!
if (!(setmodeneeded || setrenderneeded))
return;
// Lactozilla: Renderer switching
if (setrenderneeded)
{
// stop recording movies (APNG only)
@ -504,9 +503,6 @@ void SCR_ClosedCaptions(void)
boolean gamestopped = (paused || P_AutoPause());
INT32 basey = BASEVIDHEIGHT - 20;
if (gamestate != wipegamestate)
return;
if (gamestate == GS_LEVEL)
{
if (promptactive)

View file

@ -1250,7 +1250,7 @@ static void ST_drawInput(void)
//
void TitleCard_PreDraw(void)
{
if (!TitleCard_Available() || !titlecard.running)
if (!TitleCard_IsAvailable() || !titlecard.running)
return;
if (titlecard.ticker >= (titlecard.endtime + TICRATE))
@ -1277,7 +1277,7 @@ void TitleCard_Draw(void)
UINT8 colornum;
const UINT8 *colormap;
if (!TitleCard_Available())
if (!TitleCard_IsAvailable())
return;
if (!titlecard.running)
@ -2555,7 +2555,7 @@ static void ST_overlayDrawer(void)
// Check for a valid level title
// If the HUD is enabled
// And, if Lua is running, if the HUD library has the stage title enabled
if (TitleCard_Available() && !(hu_showscores && (netgame || multiplayer)))
if (TitleCard_IsAvailable() && !(hu_showscores && (netgame || multiplayer)))
{
stagetitle = true;
TitleCard_PreDraw();
@ -2700,7 +2700,7 @@ static void ST_overlayDrawer(void)
}
// draw level title Tails
if (stagetitle && !WipeInAction && !titlecard.wipe)
if (stagetitle && !wipe_running && !titlecard.wipe)
TitleCard_Draw();
if (!hu_showscores && (netgame || multiplayer) && LUA_HudEnabled(hud_textspectator))

View file

@ -1328,9 +1328,7 @@ void Y_StartIntermission(void)
}
}
// We couldn't display the intermission even if we wanted to.
// But we still need to give the players their score bonuses, dummy.
//if (dedicated) return;
F_StopAllWipes();
// This should always exist, but just in case...
if(!mapheaderinfo[prevmap])
@ -1365,6 +1363,8 @@ void Y_StartIntermission(void)
}
usetile = false;
F_WipeDoCrossfade();
// set up the "got through act" message according to skin name
if (stagefailed)
{
@ -1440,6 +1440,9 @@ void Y_StartIntermission(void)
// tile if using the default background
usetile = !useinterpic;
F_QueuePreWipe(DEFAULTWIPE, 0, NULL);
F_QueuePostWipe(DEFAULTWIPE, WSF_FADEIN, NULL);
// get special stage specific patches
/* if (!stagefailed && ALL7EMERALDS(emeralds))
{
@ -1528,6 +1531,9 @@ void Y_StartIntermission(void)
usetile = true;
useinterpic = false;
F_QueuePreWipe(DEFAULTWIPE, 0, NULL);
F_QueuePostWipe(DEFAULTWIPE, WSF_FADEIN, NULL);
break;
}
@ -1552,6 +1558,9 @@ void Y_StartIntermission(void)
usetile = true;
useinterpic = false;
F_QueuePreWipe(DEFAULTWIPE, 0, NULL);
F_QueuePostWipe(DEFAULTWIPE, WSF_FADEIN, NULL);
break;
}
@ -1577,6 +1586,9 @@ void Y_StartIntermission(void)
usetile = true;
useinterpic = false;
F_QueuePreWipe(DEFAULTWIPE, 0, NULL);
F_QueuePostWipe(DEFAULTWIPE, WSF_FADEIN, NULL);
break;
}
@ -1601,6 +1613,9 @@ void Y_StartIntermission(void)
usetile = true;
useinterpic = false;
F_QueuePreWipe(-1, 0, NULL);
F_QueuePostWipe(-1, WSF_FADEIN, NULL);
break;
}