diff --git a/src/d_main.c b/src/d_main.c
index 9fa506bee472054d13148d3a9ce6a961f83d4b47..499cde45ee7babb0c0506491096e06ac927026ff 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 d640abc8a4896590a406d79a5505050cd20cd29f..ccef4a3622811de1a206f003c4fb3afa69a1f779 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 05229f844dfd6f11bc59311f351cff335d50b30f..cabcbb1a16aa359c230294168666924290b602e8 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, paldiv)>>FRACBITS;
+		if (wipestyle == WIPESTYLE_LEVEL)
+			*mask++ = pcolor->s.red/8;		// 0-31 range
+		else
+			*mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS;
 	}
 
 	fm.xscale = FixedDiv(vid.width<<FRACBITS, fm.width<<FRACBITS);
@@ -169,6 +187,19 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
 	return NULL;
 }
 
+static void F_WipeTitleCard(void)
+{
+	if (wipestyle == WIPESTYLE_LEVEL
+		&& (!titlemapinaction)
+		&& (wipestyleflags & WSF_FADEIN)
+		&& *mapheaderinfo[gamemap-1]->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)<<FF_TRANSSHIFT);
+				if (wipestyle == WIPESTYLE_LEVEL)
+				{
+					int nmask;
+					UINT8 *fade = fadecolormap;
+
+					if (wipestyleflags & WSF_TOWHITE)
+						fade = fadecolormap + (32 * 256);
+
+					nmask = *mask;
+					if (wipestyleflags & WSF_FADEIN)
+						nmask = 31 - nmask;
+
+					transtbl = fade + (nmask * 256);
+				}
+				else
+				{
+					// pointer to transtable that this mask would use
+					transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
+				}
 
 				// DRAWING LOOP
 				while (draw_linestogo--)
@@ -273,8 +321,16 @@ static void F_DoWipe(fademask_t *fademask)
 					e = e_base + relativepos;
 					draw_rowstogo = draw_rowend - draw_rowstart;
 
-					while (draw_rowstogo--)
-						*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
+					if (wipestyle == WIPESTYLE_LEVEL)
+					{
+						while (draw_rowstogo--)
+							*w++ = transtbl[*e++];
+					}
+					else
+					{
+						while (draw_rowstogo--)
+							*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
+					}
 
 					relativepos += vid.width;
 				}
@@ -288,6 +344,7 @@ static void F_DoWipe(fademask_t *fademask)
 		free(scrxpos);
 		free(scrypos);
 	}
+	F_WipeTitleCard();
 }
 #endif
 
@@ -346,6 +403,24 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
 	WipeInAction = true;
 	wipe_scr = screens[0];
 
+	// don't know where else to put this.
+	// this any good?
+	if (gamestate == GS_LEVEL || gamestate == GS_TITLESCREEN)
+	{
+		wipestyle = WIPESTYLE_LEVEL;
+		maxwipeframe = 31;
+	}
+	else
+	{
+		wipestyle = WIPESTYLE_NORMAL;
+		maxwipeframe = 10;
+	}
+
+	curwipetype = wipetype;
+	curwipeframe = 0;
+	if (!WipeFreezeGame)
+		return;
+
 	// lastwipetic should either be 0 or the tic we last wiped
 	// on for fade-to-black
 	for (;;)
@@ -362,10 +437,23 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
 
 #ifdef HWRENDER
 		if (rendermode == render_opengl)
-			HWR_DoWipe(wipetype, wipeframe-1); // send in the wipe type and wipeframe because we need to cache the graphic
+		{
+			float frame = wipeframe-1;
+			if (wipestyle == WIPESTYLE_LEVEL)
+			{
+				float length = F_GetWipeLength(wipetype);
+				float strength = (frame / length) * 32.0f;
+				if (wipestyleflags & WSF_FADEIN)
+					strength = 31.0f - strength;
+				HWR_DoWipeLevel();
+				HWR_FadeScreenMenuBack(0xFF00|31, strength);
+			}
+			else
+				HWR_DoWipe(wipetype, frame-1); // send in the wipe type and wipeframe because we need to cache the graphic
+		}
 		else
 #endif
-		F_DoWipe(fmask);
+			F_DoWipe(fmask);
 		I_OsPolling();
 		I_UpdateNoBlit();
 
@@ -378,7 +466,51 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
 			M_SaveFrame();
 	}
 	WipeInAction = false;
+	WipeFreezeGame = true;
+#endif
+}
+
+// Works On My Machine seal of approval
+void F_WipeTicker(void)
+{
+	fademask_t *fmask;
+
+	// Wait, what?
+	if (!WipeInAction)
+		return;
+
+	if (rendermode == render_soft)
+		wipe_scr_start = wipe_scr_end = screens[0];
+
+	// get fademask first so we can tell if it exists or not
+	fmask = F_GetFadeMask(curwipetype, curwipeframe++);
+	if (!fmask)
+	{
+		// stop
+		WipeInAction = false;
+		WipeFreezeGame = true;
+		return;
+	}
+
+#ifdef HWRENDER
+	if (rendermode == render_opengl)
+	{
+		float frame = curwipeframe-1;
+		if (wipestyle == WIPESTYLE_LEVEL)
+		{
+			float length = F_GetWipeLength(curwipetype);
+			float strength = (frame / length) * 32.0f;
+			if (wipestyleflags & WSF_FADEIN)
+				strength = 31.0f - strength;
+			HWR_FadeScreenMenuBack(0xFF00|31, strength);
+			F_WipeTitleCard();
+		}
+		else
+			HWR_DoWipe(curwipetype, frame-1); // send in the wipe type and wipeframe because we need to cache the graphic
+	}
+	else
 #endif
+		F_DoWipe(fmask);
 }
 
 /** Returns tic length of wipe
diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h
index e2fa90eb035de94d0b5ad7d81de624ed0fbe4341..a4ba9cf8f95fdb9710c07fa74e045bbc013e352a 100644
--- a/src/hardware/hw_drv.h
+++ b/src/hardware/hw_drv.h
@@ -72,6 +72,7 @@ EXPORT void HWRAPI(FlushScreenTextures) (void);
 EXPORT void HWRAPI(StartScreenWipe) (void);
 EXPORT void HWRAPI(EndScreenWipe) (void);
 EXPORT void HWRAPI(DoScreenWipe) (float alpha);
+EXPORT void HWRAPI(DoScreenWipeLevel) (void);
 EXPORT void HWRAPI(DrawIntermissionBG) (void);
 EXPORT void HWRAPI(MakeScreenTexture) (void);
 EXPORT void HWRAPI(MakeScreenFinalTexture) (void);
@@ -114,6 +115,7 @@ struct hwdriver_s
 	StartScreenWipe     pfnStartScreenWipe;
 	EndScreenWipe       pfnEndScreenWipe;
 	DoScreenWipe        pfnDoScreenWipe;
+	DoScreenWipeLevel   pfnDoScreenWipeLevel;
 	DrawIntermissionBG  pfnDrawIntermissionBG;
 	MakeScreenTexture   pfnMakeScreenTexture;
 	MakeScreenFinalTexture  pfnMakeScreenFinalTexture;
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index c6a8b16e568b24371af0dbd1da4e275c128444ad..7f6f13b6fd2da1cbf2bdcbf637480dc0d1620f40 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -6913,6 +6913,11 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
 		HWRWipeCounter = 1.0f;
 }
 
+void HWR_DoWipeLevel(void)
+{
+	HWD.pfnDoScreenWipeLevel(); // Still send in wipecounter since old stuff might not support multitexturing
+}
+
 void HWR_MakeScreenFinalTexture(void)
 {
     HWD.pfnMakeScreenFinalTexture();
diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h
index f8524990f9d6f3096150ae76e505400c5708cb8e..fb2cd5d268f8d360b497301b0e3369ee029a73d1 100644
--- a/src/hardware/hw_main.h
+++ b/src/hardware/hw_main.h
@@ -67,6 +67,7 @@ void HWR_StartScreenWipe(void);
 void HWR_EndScreenWipe(void);
 void HWR_DrawIntermissionBG(void);
 void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
+void HWR_DoWipeLevel(void);
 void HWR_MakeScreenFinalTexture(void);
 void HWR_DrawScreenFinalTexture(int width, int height);
 
diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c
index dfee19857cca3881adbd9dc123fd56b48aef7416..f1b9f99eb98ab142e2c338a6c9529de8ffbafcc0 100644
--- a/src/hardware/r_opengl/r_opengl.c
+++ b/src/hardware/r_opengl/r_opengl.c
@@ -2084,6 +2084,50 @@ EXPORT void HWRAPI(DoScreenWipe)(float alpha)
 	}
 }
 
+EXPORT void HWRAPI(DoScreenWipeLevel)(void)
+{
+	INT32 texsize = 2048;
+	float xfix, yfix;
+
+	// Use a power of two texture, dammit
+	if(screen_width <= 1024)
+		texsize = 1024;
+	if(screen_width <= 512)
+		texsize = 512;
+
+	xfix = 1/((float)(texsize)/((float)((screen_width))));
+	yfix = 1/((float)(texsize)/((float)((screen_height))));
+
+	pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+	SetBlend(PF_Modulated|PF_NoDepthTest|PF_Clip|PF_NoZClip);
+
+	// Draw the original screen
+	pglBindTexture(GL_TEXTURE_2D, startScreenWipe);
+	pglBegin(GL_QUADS);
+		pglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+		// Bottom left
+		pglTexCoord2f(0.0f, 0.0f);
+		pglVertex3f(-1.0f, -1.0f, 1.0f);
+
+		// Top left
+		pglTexCoord2f(0.0f, yfix);
+		pglVertex3f(-1.0f, 1.0f, 1.0f);
+
+		// Top right
+		pglTexCoord2f(xfix, yfix);
+		pglVertex3f(1.0f, 1.0f, 1.0f);
+
+		// Bottom right
+		pglTexCoord2f(xfix, 0.0f);
+		pglVertex3f(1.0f, -1.0f, 1.0f);
+
+	pglEnd();
+
+	SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest|PF_Clip|PF_NoZClip);
+}
+
 
 // Create a texture from the screen.
 EXPORT void HWRAPI(MakeScreenTexture) (void)
diff --git a/src/m_menu.c b/src/m_menu.c
index 0c7628ecaac1b686d8281382951c8145a796d8b8..e16f58b6963d1cd71f16f3b22fc2efc42800367b 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -3222,13 +3222,17 @@ boolean M_Responder(event_t *ev)
 //
 void M_Drawer(void)
 {
+	boolean wipe = WipeInAction;
+	if (!WipeFreezeGame)
+		wipe = false;
+
 	if (currentMenu == &MessageDef)
 		menuactive = true;
 
 	if (menuactive)
 	{
 		// now that's more readable with a faded background (yeah like Quake...)
-		if (!WipeInAction && (curfadevalue || (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK)))
+		if (!wipe && (curfadevalue || (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK)))
 			V_DrawFadeScreen(0xFF00, (gamestate != GS_TITLESCREEN && gamestate != GS_TIMEATTACK) ? 16 : curfadevalue);
 
 		if (currentMenu->drawroutine)
diff --git a/src/p_setup.c b/src/p_setup.c
index 65335be3f5239acbf45f1431c4f06522ef0343db..51cb38fe06c00eb6fc292268a43e61229ae687b5 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 6889bdddebf587ce22b3526066fca43aec364ceb..2699cf5999d3e7509c46715e87fc70b13fac73a6 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 b6b0a16a15fad21fb90aa0325721d177a1c6eccc..77e61579939f6b2b64c4fa9550a0f5b47e3a4780 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 da9425bdf0405160810e7102a4d53ce1241eb881..9773849265ef77a17f4fd6712078388c2180aa46 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 05ac6450e2267c0c08182775cece05eeaefabeab..a07d9eb03c8df6f4d74922f58095013fe497d6b2 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 5a4fd7a02247c0ef985868c8e0fa3ee5619b0c39..998fae239128248438496b77fb1f39d02f2ea54a 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 71eda04371d4223dedcd5e193d8c27ed8cf0f70d..b6353f80d65c111407d44e1eb325288fd466ebda 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},