diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index e0feb036f1c0a54ce534544509f03027db53b900..476bb1a1ea357b36c56894a36645e474e101ef73 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -2417,7 +2417,7 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
 	// the remaining players.
 	if (G_IsSpecialStage(gamemap))
 	{
-		INT32 i, count, increment, spheres;
+		INT32 i, count, sincrement, spheres, rincrement, rings;
 
 		for (i = 0, count = 0; i < MAXPLAYERS; i++)
 		{
@@ -2427,18 +2427,35 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
 
 		count--;
 		spheres = players[playernum].spheres;
-		increment = spheres/count;
+		rings = players[playernum].rings;
+		sincrement = spheres/count;
+		rincrement = rings/count;
 
 		for (i = 0; i < MAXPLAYERS; i++)
 		{
 			if (playeringame[i] && i != playernum)
 			{
-				if (spheres < increment)
+				if (spheres < 2*sincrement)
+				{
 					P_GivePlayerSpheres(&players[i], spheres);
+					spheres = 0;
+				}
 				else
-					P_GivePlayerSpheres(&players[i], increment);
+				{
+					P_GivePlayerSpheres(&players[i], sincrement);
+					spheres -= sincrement;
+				}
 
-				spheres -= increment;
+				if (rings < 2*rincrement)
+				{
+					P_GivePlayerRings(&players[i], rings);
+					rings = 0;
+				}
+				else
+				{
+					P_GivePlayerRings(&players[i], rincrement);
+					rings -= rincrement;
+				}
 			}
 		}
 	}
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 4e3cdaaacadb51a22371006acfbdd06824ed6e48..6b870091ebbc076d47ff18485b9afbf2a044e07c 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -2717,14 +2717,6 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
 		}
 	}
 
-	// Clear player score and rings if a spectator.
-	if (players[playernum].spectator)
-	{
-		players[playernum].score = players[playernum].rings = 0;
-		if (players[playernum].mo)
-			players[playernum].mo->health = 1;
-	}
-
 	// In tag, check to see if you still have a game.
 	if (G_TagGametype())
 		P_CheckSurvivors();
@@ -3611,7 +3603,7 @@ static void CoopLives_OnChange(void)
 	{
 		case 0:
 			CONS_Printf(M_GetText("Players can now respawn indefinitely.\n"));
-			return;
+			break;
 		case 1:
 			CONS_Printf(M_GetText("Lives are now per-player.\n"));
 			return;
diff --git a/src/f_finale.c b/src/f_finale.c
index e44add4d15f47d4fd83720c7ea2cbd3a1f18baa6..ee22ecb2f6f8b3afe399bc0887c6649821ab4b6b 100644
--- a/src/f_finale.c
+++ b/src/f_finale.c
@@ -2465,6 +2465,11 @@ void F_TitleDemoTicker(void)
 // ==========
 //  CONTINUE
 // ==========
+
+static skin_t *contskins[2];
+static UINT8 cont_spr2[2][6];
+static UINT8 *contcolormaps[2];
+
 void F_StartContinue(void)
 {
 	I_Assert(!netgame && !multiplayer);
@@ -2488,7 +2493,44 @@ void F_StartContinue(void)
 	S_ChangeMusicInternal("_conti", false);
 	S_StopSounds();
 
-	timetonext = TICRATE*11;
+	contskins[0] = &skins[players[consoleplayer].skin];
+	cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT1, NULL);
+	cont_spr2[0][2] = contskins[0]->contangle & 7;
+	contcolormaps[0] = R_GetTranslationColormap(players[consoleplayer].skin, players[consoleplayer].skincolor, GTC_CACHE);
+	cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
+	cont_spr2[0][5] = max(1, contskins[0]->contspeed);
+
+	if (botskin)
+	{
+		INT32 secondplaya;
+
+		if (secondarydisplayplayer != consoleplayer)
+			secondplaya = secondarydisplayplayer;
+		else // HACK
+			secondplaya = 1;
+
+		contskins[1] = &skins[players[secondplaya].skin];
+		cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT4, NULL);
+		cont_spr2[1][2] = (contskins[1]->contangle >> 3) & 7;
+		contcolormaps[1] = R_GetTranslationColormap(players[secondplaya].skin, players[secondplaya].skincolor, GTC_CACHE);
+		cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
+		if (cont_spr2[1][0] == SPR2_CNT4)
+			cont_spr2[1][5] = 4; // sorry, this one is hardcoded
+		else
+			cont_spr2[1][5] = max(1, contskins[1]->contspeed);
+	}
+	else
+	{
+		contskins[1] = NULL;
+		contcolormaps[1] = NULL;
+		cont_spr2[1][0] = cont_spr2[1][2] = cont_spr2[1][4] = cont_spr2[1][5] = 0;
+	}
+
+	cont_spr2[0][1] = cont_spr2[0][3] =\
+	cont_spr2[1][1] = cont_spr2[1][3] = 0;
+
+	timetonext = (11*TICRATE)+11;
+	continuetime = 0;
 }
 
 //
@@ -2497,47 +2539,198 @@ void F_StartContinue(void)
 //
 void F_ContinueDrawer(void)
 {
-	patch_t *contsonic;
-	INT32 i, x = (BASEVIDWIDTH/2) + 4, ncontinues = players[consoleplayer].continues;
-	if (ncontinues > 20)
-		ncontinues = 20;
+	spritedef_t *sprdef;
+	spriteframe_t *sprframe;
+	patch_t *patch;
+	INT32 i, x = (BASEVIDWIDTH>>1), ncontinues = players[consoleplayer].continues;
+	char numbuf[9] = "CONTNUM*";
+	tic_t timeleft = (timetonext/TICRATE);
+	INT32 offsx = 0, offsy = 0, lift[2] = {0, 0};
 
-	if (imcontinuing)
-		contsonic = W_CachePatchName("CONT2", PU_CACHE);
-	else
-		contsonic = W_CachePatchName("CONT1", PU_CACHE);
+	if (continuetime >= 3*TICRATE)
+	{
+		V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
+		return;
+	}
 
 	V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
-	V_DrawCenteredString(BASEVIDWIDTH/2, 100, 0, "CONTINUE?");
 
-	// Draw a Sonic!
-	V_DrawScaledPatch((BASEVIDWIDTH - SHORT(contsonic->width))/2, 32, 0, contsonic);
+	if (timetonext >= (11*TICRATE)+10)
+		return;
+
+	V_DrawLevelTitle(x - (V_LevelNameWidth("CONTINUE")>>1), 16, 0, "CONTINUE");
+
+	// Two stars...
+	patch = W_CachePatchName("CONTSTAR", PU_CACHE);
+	V_DrawScaledPatch(x-32, 160, 0, patch);
+	V_DrawScaledPatch(x+32, 160, 0, patch);
 
-	// Draw the continue markers! Show continues minus one.
-	x -= ncontinues * 6;
-	for (i = 0; i < ncontinues; ++i)
-		V_DrawContinueIcon(x + (i*12), 140, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
+	// Time left!
+	if (timeleft > 9)
+	{
+		numbuf[7] = '1';
+		V_DrawScaledPatch(x - 10, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
+		numbuf[7] = '0';
+		V_DrawScaledPatch(x + 10, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
+	}
+	else
+	{
+		numbuf[7] = '0'+timeleft;
+		V_DrawScaledPatch(x, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
+	}
+
+	// Draw the continue markers! Show continues.
+	if (ncontinues > 10)
+	{
+		if (!(continuetime & 1) || continuetime > 17)
+			V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
+		V_DrawScaledPatch(x+12, 68-2, 0, stlivex);
+		V_DrawRightAlignedString(x+36, 69-5, 0,
+			va("%d",(imcontinuing ? ncontinues-1 : ncontinues)));
+	}
+	else
+	{
+		x += (ncontinues/2) * 30;
+		if (!(ncontinues & 1))
+			x -= 15;
+		for (i = 0; i < ncontinues; ++i)
+		{
+			if (i == (ncontinues/2) && ((continuetime & 1) || continuetime > 17))
+				continue;
+			V_DrawContinueIcon(x - (i*30), 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
+		}
+		x = BASEVIDWIDTH>>1;
+	}
+
+	// Spotlight
+	V_DrawScaledPatch(x, 140, 0, W_CachePatchName("CONTSPOT", PU_CACHE));
+
+	// warping laser
+	if (continuetime)
+	{
+		INT32 w = min(continuetime, 28), brightness = (continuetime>>1) & 7;
+		if (brightness > 3)
+			brightness = 8-brightness;
+		V_DrawFadeFill(x-w, 0, w<<1, 140, 0, 0, (3+brightness));
+	}
 
-	V_DrawCenteredString(BASEVIDWIDTH/2, 168, 0, va("\x82*\x80" " %02d " "\x82*\x80", timetonext/TICRATE));
+	if (contskins[1])
+	{
+		if (continuetime > 15)
+		{
+			angle_t work = FixedAngle((10*(continuetime-15))<<FRACBITS)>>ANGLETOFINESHIFT;
+			offsy = FINESINE(work)<<1;
+			offsx = (27*FINECOSINE(work))>>1;
+		}
+		else
+			offsx = 27<<(FRACBITS-1);
+		lift[1] = continuetime-10;
+		if (lift[1] < 0)
+			lift[1] = 0;
+		else if (lift[1] > TICRATE+5)
+			lift[1] = TICRATE+5;
+	}
+
+	lift[0] = continuetime-5;
+	if (lift[0] < 0)
+		lift[0] = 0;
+	else if (lift[0] > TICRATE+5)
+		lift[0] = TICRATE+5;
+
+#define drawchar(dx, dy, n)	{\
+								sprdef = &contskins[n]->sprites[cont_spr2[n][0]];\
+								sprframe = &sprdef->spriteframes[cont_spr2[n][1]];\
+								patch = W_CachePatchNum(sprframe->lumppat[cont_spr2[n][2]], PU_CACHE);\
+								V_DrawFixedPatch((dx), (dy), FRACUNIT, (sprframe->flip & (1<<cont_spr2[n][2])) ? V_FLIP : 0, patch, contcolormaps[n]);\
+							}
+
+	if (offsy < 0)
+		drawchar((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0);
+	if (contskins[1])
+		drawchar((BASEVIDWIDTH<<(FRACBITS-1))+offsx, ((140-lift[1])<<FRACBITS)+offsy, 1);
+	if (offsy >= 0)
+		drawchar((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0);
+
+#undef drawchar
+
+	if (timetonext > (11*TICRATE))
+		V_DrawFadeScreen(31, timetonext-(11*TICRATE));
+	if (continuetime > ((3*TICRATE) - 10))
+		V_DrawFadeScreen(0, (continuetime - ((3*TICRATE) - 10)));
 }
 
 void F_ContinueTicker(void)
 {
 	if (!imcontinuing)
 	{
-		// note the setup to prevent 2x reloading
-		if (timetonext >= 0)
-			timetonext--;
-		if (timetonext == 0)
-			Command_ExitGame_f();
+		if (timetonext > 0)
+		{
+			if (!(--timetonext))
+			{
+				Command_ExitGame_f();
+				return;
+			}
+		}
 	}
 	else
 	{
-		// note the setup to prevent 2x reloading
-		if (continuetime >= 0)
-			continuetime--;
-		if (continuetime == 0)
+		if (++continuetime == 3*TICRATE)
+		{
 			G_Continue();
+			return;
+		}
+
+		if (continuetime > 5 && ((continuetime & 1) || continuetime > TICRATE) && (++cont_spr2[0][2]) >= 8)
+			cont_spr2[0][2] = 0;
+
+		if (continuetime > 10 && (!(continuetime & 1) || continuetime > TICRATE+5) && (++cont_spr2[1][2]) >= 8)
+			cont_spr2[1][2] = 0;
+
+		if (continuetime == (3*TICRATE)-10)
+			S_StartSound(NULL, sfx_cdfm56); // or 31
+		else if (continuetime == 5)
+		{
+			cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT2, NULL);
+			cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
+			cont_spr2[0][1] = cont_spr2[0][3] = 0;
+			cont_spr2[0][5] = 2;
+		}
+		else if (continuetime == TICRATE)
+		{
+			cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT3, NULL);
+			cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
+			cont_spr2[0][1] = cont_spr2[0][3] = 0;
+		}
+		else if (contskins[1])
+		{
+			if (continuetime == 10)
+			{
+				cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT2, NULL);
+				cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
+				cont_spr2[1][1] = cont_spr2[1][3] = 0;
+				cont_spr2[1][5] = 2;
+			}
+			else if (continuetime == TICRATE+5)
+			{
+				cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT3, NULL);
+				cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
+				cont_spr2[1][1] = cont_spr2[1][3] = 0;
+			}
+		}
+	}
+
+	if ((++cont_spr2[0][3]) >= cont_spr2[0][5])
+	{
+		cont_spr2[0][3] = 0;
+		if (++cont_spr2[0][1] >= cont_spr2[0][4])
+			cont_spr2[0][1] = 0;
+	}
+
+	if (contskins[1] && (++cont_spr2[1][3]) >= cont_spr2[1][5])
+	{
+		cont_spr2[1][3] = 0;
+		if (++cont_spr2[1][1] >= cont_spr2[1][4])
+			cont_spr2[1][1] = 0;
 	}
 }
 
@@ -2568,8 +2761,9 @@ boolean F_ContinueResponder(event_t *event)
 
 	keypressed = true;
 	imcontinuing = true;
-	continuetime = TICRATE;
-	S_StartSound(NULL, sfx_itemup);
+	S_StartSound(NULL, sfx_kc6b);
+	I_FadeSong(0, MUSICRATE, &S_StopMusic);
+
 	return true;
 }
 
diff --git a/src/g_game.c b/src/g_game.c
index 80bd8bc3e38e1d9c7e6f7113c286f34b3eb00a34..7a876e968542b8f47e71198d47665e6e5916976a 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -216,7 +216,7 @@ UINT16 spacetimetics = 11*TICRATE + (TICRATE/2);
 UINT16 extralifetics = 4*TICRATE;
 UINT16 nightslinktics = 2*TICRATE;
 
-INT32 gameovertics = 15*TICRATE;
+INT32 gameovertics = 11*TICRATE;
 
 UINT8 ammoremovaltics = 2*TICRATE;
 
@@ -2148,6 +2148,8 @@ void G_PlayerReborn(INT32 player)
 	boolean outofcoop;
 	INT16 bot;
 	SINT8 pity;
+	INT16 rings;
+	INT16 spheres;
 
 	score = players[player].score;
 	lives = players[player].lives;
@@ -2203,6 +2205,17 @@ void G_PlayerReborn(INT32 player)
 	bot = players[player].bot;
 	pity = players[player].pity;
 
+	if (!G_IsSpecialStage(gamemap))
+	{
+		rings = (ultimatemode ? 0 : mapheaderinfo[gamemap-1]->startrings);
+		spheres = 0;
+	}
+	else
+	{
+		rings = players[player].rings;
+		spheres = players[player].spheres;
+	}
+
 	p = &players[player];
 	memset(p, 0, sizeof (*p));
 
@@ -2257,6 +2270,8 @@ void G_PlayerReborn(INT32 player)
 	if (bot)
 		p->bot = 1; // reset to AI-controlled
 	p->pity = pity;
+	p->rings = rings;
+	p->spheres = spheres;
 
 	// Don't do anything immediately
 	p->pflags |= PF_USEDOWN;
@@ -2264,7 +2279,6 @@ void G_PlayerReborn(INT32 player)
 	p->pflags |= PF_JUMPDOWN;
 
 	p->playerstate = PST_LIVE;
-	p->rings = p->spheres = 0; // 0 rings
 	p->panim = PA_IDLE; // standing animation
 
 	//if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
@@ -2375,8 +2389,6 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
 
 	P_SpawnPlayer(playernum);
 
-	players[playernum].rings = mapheaderinfo[gamemap-1]->startrings;
-
 	if (starpost) //Don't even bother with looking for a place to spawn.
 	{
 		P_MovePlayerToStarpost(playernum);
@@ -2599,7 +2611,7 @@ void G_DoReborn(INT32 playernum)
 
 	if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP))
 		resetlevel = true;
-	else if (gametype == GT_COOP && (netgame || multiplayer))
+	else if (gametype == GT_COOP && (netgame || multiplayer) && !G_IsSpecialStage(gamemap))
 	{
 		boolean notgameover = true;
 
diff --git a/src/info.c b/src/info.c
index 5baf289435addc46a40af9aefb0f4ab2f622aeb0..3bee08529de642fc8eac6bde65371ad7f255c35e 100644
--- a/src/info.c
+++ b/src/info.c
@@ -576,8 +576,14 @@ char spr2names[NUMPLAYERSPRITES][5] =
 	"TALA",
 	"TALB",
 
+	"CNT1",
+	"CNT2",
+	"CNT3",
+	"CNT4",
+
 	"SIGN",
 	"LIFE",
+
 	"XTRA",
 };
 playersprite_t free_spr2 = SPR2_FIRSTFREESLOT;
@@ -673,8 +679,14 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
 	SPR2_TAL9, // SPR2_TALA,
 	SPR2_TAL0, // SPR2_TALB,
 
+	SPR2_WAIT, // SPR2_CNT1,
+	SPR2_FALL, // SPR2_CNT2,
+	SPR2_SPNG, // SPR2_CNT3,
+	SPR2_CNT1, // SPR2_CNT4,
+
 	0, // SPR2_SIGN,
 	0, // SPR2_LIFE,
+
 	0, // SPR2_XTRA (should never be referenced)
 };
 
diff --git a/src/info.h b/src/info.h
index a9d4bdde00c44efd28b97a8fd905d797271cc86f..43015ded73e14e1be0c119b264d53ae06808faa3 100644
--- a/src/info.h
+++ b/src/info.h
@@ -832,9 +832,15 @@ typedef enum playersprite
 	SPR2_TALA,
 	SPR2_TALB,
 
+	SPR2_CNT1, // continue disappointment
+	SPR2_CNT2, // continue lift
+	SPR2_CNT3, // continue spin
+	SPR2_CNT4, // continue "soooooooniiic!" tugging
+
 	SPR2_SIGN, // end sign head
 	SPR2_LIFE, // life monitor icon
-	SPR2_XTRA, // stuff that isn't in-game - keep this last in the list
+
+	SPR2_XTRA, // stuff that isn't in-map - "would this ever need an md2 or variable length animation?"
 
 	SPR2_FIRSTFREESLOT,
 	SPR2_LASTFREESLOT = 0x7f,
diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c
index a28f6a359556da233d71c6b598264101e56bb4e8..7f68905aa1ec748aa700fb7ced2441d0538d78d1 100644
--- a/src/lua_skinlib.c
+++ b/src/lua_skinlib.c
@@ -52,6 +52,8 @@ enum skin {
 	skin_supercolor,
 	skin_prefoppositecolor,
 	skin_highresscale,
+	skin_contspeed,
+	skin_contangle,
 	skin_soundsid,
 	skin_availability
 };
@@ -88,6 +90,8 @@ static const char *const skin_opt[] = {
 	"supercolor",
 	"prefoppositecolor",
 	"highresscale",
+	"contspeed",
+	"contangle",
 	"soundsid",
 	"availability",
 	NULL};
@@ -199,6 +203,12 @@ static int skin_get(lua_State *L)
 	case skin_highresscale:
 		lua_pushinteger(L, skin->highresscale);
 		break;
+	case skin_contspeed:
+		lua_pushinteger(L, skin->contspeed);
+		break;
+	case skin_contangle:
+		lua_pushinteger(L, skin->contangle);
+		break;
 	case skin_soundsid:
 		LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID);
 		break;
diff --git a/src/m_menu.c b/src/m_menu.c
index 9ed6d02c1fbe4a8ae64cd87b6a9c53b890abc25d..d05048a9d44ffccbad62a60e87f344cf19da7db7 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -4520,6 +4520,9 @@ static boolean M_CanShowLevelOnPlatter(INT32 mapnum, INT32 gt)
 			if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU)
 				return false;
 
+			if (G_IsSpecialStage(mapnum+1))
+				return false;
+
 			if (gt == GT_COOP && (mapheaderinfo[mapnum]->typeoflevel & TOL_COOP))
 				return true;
 
@@ -7062,7 +7065,7 @@ static void M_DrawLoadGameData(void)
 			}
 		}
 
-		y -= 13;
+		y -= 4;
 
 		// character heads, lives, and continues
 		{
@@ -7071,7 +7074,7 @@ static void M_DrawLoadGameData(void)
 			patch_t *patch;
 			UINT8 *colormap = NULL;
 
-			INT32 tempx = (x+40)<<FRACBITS, tempy = y<<FRACBITS, flip = 0, calc;
+			INT32 tempx = (x+40)<<FRACBITS, flip = 0;
 
 			// botskin first
 			if (savegameinfo[savetodraw].botskin)
@@ -7086,13 +7089,13 @@ static void M_DrawLoadGameData(void)
 
 				V_DrawFixedPatch(
 					tempx + (18<<FRACBITS),
-					tempy -  (4<<FRACBITS),
+					y<<FRACBITS,
 					charbotskin->highresscale,
 					0, patch, colormap);
 
 				Z_Free(colormap);
 
-				tempx -= (15<<FRACBITS);
+				tempx -= (20<<FRACBITS);
 				flip = V_FLIP;
 			}
 skipbot:
@@ -7105,17 +7108,15 @@ skipbot:
 				goto skipsign;
 			sprframe = &sprdef->spriteframes[0];
 			patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
-			if ((calc = SHORT(patch->topoffset) - 42) > 0)
-				tempy += ((4+calc)<<FRACBITS);
 
 			V_DrawFixedPatch(
 				tempx,
-				tempy,
+				y<<FRACBITS,
 				charskin->highresscale,
 				flip, patch, colormap);
 
 skipsign:
-			y += 25;
+			y += 16;
 
 			tempx = x + 10;
 			if (savegameinfo[savetodraw].lives != INFLIVES
diff --git a/src/p_inter.c b/src/p_inter.c
index 6f5d27a9d1665306160cb64f2adc285be1930e11..79491e245bdee03d04742fe54d422a0a7168ec02 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -2482,8 +2482,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
 				else if (P_IsLocalPlayer(target->player))
 					gameovermus = true;
 
-				if (gameovermus)
-					P_PlayJingle(target->player, JT_GOVER); // Yousa dead now, Okieday? Tails 03-14-2000
+				if (gameovermus) // Yousa dead now, Okieday? Tails 03-14-2000
+					S_ChangeMusicEx("_gover", 0, 0, 0, (2*MUSICRATE) - (MUSICRATE/25), 0); // 1.96 seconds
+					//P_PlayJingle(target->player, JT_GOVER); // can't be used because incompatible with track fadeout
 
 				if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && numgameovers < maxgameovers)
 				{
@@ -3520,7 +3521,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
 			return true;
 		}
 
-		if (G_IsSpecialStage(gamemap))
+		if (G_IsSpecialStage(gamemap) && !(damagetype & DMG_DEATHMASK))
 		{
 			P_SpecialStageDamage(player, inflictor, source);
 			return true;
@@ -3544,10 +3545,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
 
 		// Instant-Death
 		if (damagetype & DMG_DEATHMASK)
-		{
 			P_KillPlayer(player, source, damage);
-			player->rings = player->spheres = 0;
-		}
 		else if (metalrecording)
 		{
 			if (!inflictor)
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 41611fb34d1dac980e38b9dd77531f456d47ad25..44c6b9f6ebb388f518943902744a1327318022c6 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -10420,9 +10420,9 @@ void P_SpawnPlayer(INT32 playernum)
 		p->spectator = p->outofcoop =
 		(((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop
 		&& ((leveltime > 0
-		&& ((G_IsSpecialStage(gamemap) && (maptol & TOL_NIGHTS)) // late join special stage
+		&& ((G_IsSpecialStage(gamemap)) // late join special stage
 		|| (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop
-		|| (((cv_cooplives.value == 1) || !P_GetLives(p)) && p->lives <= 0))); // game over and can't redistribute lives
+		|| (!P_GetLives(p) && p->lives <= 0))); // game over and can't redistribute lives
 	}
 	else
 	{
@@ -10489,7 +10489,6 @@ void P_SpawnPlayer(INT32 playernum)
 	P_SetupStateAnimation(mobj, mobj->state);
 
 	mobj->health = 1;
-	p->rings = p->spheres = 0;
 	p->playerstate = PST_LIVE;
 
 	p->bonustime = false;
diff --git a/src/p_setup.c b/src/p_setup.c
index 793735082f2cfbcc43d0266a789d3aeb5f8b6de4..0753f01d3840c965974115b31534b2643cb9237e 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -2253,7 +2253,7 @@ static void P_LevelInitStuff(void)
 		}
 
 		// obliteration station...
-		players[i].rings = players[i].spheres =\
+		players[i].spheres =\
 		 players[i].xtralife = players[i].deadtimer =\
 		 players[i].numboxes = players[i].totalring =\
 		 players[i].laps = players[i].aiming =\
@@ -2278,6 +2278,7 @@ static void P_LevelInitStuff(void)
 
 		// aha, the first evidence this shouldn't be a memset!
 		players[i].drillmeter = 40*20;
+		players[i].rings = (ultimatemode ? 0 : mapheaderinfo[gamemap-1]->startrings);
 
 		P_ResetPlayer(&players[i]);
 		// hit these too
diff --git a/src/p_user.c b/src/p_user.c
index 1f2fac9944d01e9d0a75d985786e5d1682a6d0c0..43138d2e959c466967938eebe0039bff14ef5016 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -9048,19 +9048,22 @@ boolean P_GetLives(player_t *player)
 	INT32 i, maxlivesplayer = -1, livescheck = 1;
 	if (!(netgame || multiplayer)
 	|| (gametype != GT_COOP)
-	|| (cv_cooplives.value == 1)
 	|| (player->lives == INFLIVES))
 		return true;
 
-	if ((cv_cooplives.value == 2 || cv_cooplives.value == 0) && player->lives > 0)
-		return true;
-
 	if (cv_cooplives.value == 0) // infinite lives
 	{
-		player->lives++;
+		if (player->lives < 1)
+			player->lives = 1;
 		return true;
 	}
 
+	if ((cv_cooplives.value == 2 || cv_cooplives.value == 1) && player->lives > 0)
+		return true;
+
+	if (cv_cooplives.value == 1)
+		return false;
+
 	for (i = 0; i < MAXPLAYERS; i++)
 	{
 		if (!playeringame[i])
@@ -9167,7 +9170,7 @@ static void P_DeathThink(player_t *player)
 	// continue logic
 	if (!(netgame || multiplayer) && player->lives <= 0)
 	{
-		if (player->deadtimer > TICRATE && (cmd->buttons & BT_USE || cmd->buttons & BT_JUMP) && player->continues > 0)
+		if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_USE || cmd->buttons & BT_JUMP) && player->continues > 0)
 			G_UseContinue();
 		else if (player->deadtimer >= gameovertics)
 			G_UseContinue(); // Even if we don't have one this handles ending the game
@@ -9191,12 +9194,12 @@ static void P_DeathThink(player_t *player)
 	// Force respawn if idle for more than 30 seconds in shooter modes.
 	if (player->deadtimer > 30*TICRATE && !G_PlatformGametype())
 		player->playerstate = PST_REBORN;
-	else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages!
+	else if ((player->lives > 0 || j != MAXPLAYERS) && !(!(netgame || multiplayer) && G_IsSpecialStage(gamemap))) // Don't allow "click to respawn" in special stages!
 	{
 		if (gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2)
 		{
 			P_ConsiderAllGone();
-			if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))
+			if ((player->deadtimer > TICRATE<<1) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))
 			{
 				//player->spectator = true;
 				player->outofcoop = true;
@@ -9212,16 +9215,11 @@ static void P_DeathThink(player_t *player)
 					player->playerstate = PST_REBORN;
 				else switch(gametype) {
 					case GT_COOP:
-						if (player->deadtimer > TICRATE)
-							player->playerstate = PST_REBORN;
-						break;
 					case GT_COMPETITION:
+					case GT_RACE:
 						if (player->deadtimer > TICRATE)
 							player->playerstate = PST_REBORN;
 						break;
-					case GT_RACE:
-						player->playerstate = PST_REBORN;
-						break;
 					default:
 						if (player->deadtimer > cv_respawntime.value*TICRATE)
 							player->playerstate = PST_REBORN;
@@ -9230,7 +9228,7 @@ static void P_DeathThink(player_t *player)
 			}
 
 			// Single player auto respawn
-			if (!(netgame || multiplayer) && player->deadtimer > 5*TICRATE)
+			if (!(netgame || multiplayer) && player->deadtimer > TICRATE<<1)
 				player->playerstate = PST_REBORN;
 		}
 	}
@@ -11032,8 +11030,6 @@ void P_PlayerThink(player_t *player)
 	{
 		if (gametype != GT_COOP)
 			player->score = 0;
-		player->mo->health = 1;
-		player->rings = player->spheres = 0;
 	}
 	else if ((netgame || multiplayer) && player->lives <= 0 && gametype != GT_COOP)
 	{
diff --git a/src/r_things.c b/src/r_things.c
index 5940e2189514057c71d65a28d82c886511b41934..392821869fd18c3b0975de7069bd40a5f47aac7a 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -2616,6 +2616,8 @@ static void Sk_SetDefaultValue(skin_t *skin)
 	skin->followitem = 0;
 
 	skin->highresscale = FRACUNIT;
+	skin->contspeed = 17;
+	skin->contangle = 0;
 
 	skin->availability = 0;
 
@@ -2882,6 +2884,8 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski
 	for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
 		R_AddSingleSpriteDef((spritename = spr2names[sprite2]), &skin->sprites[sprite2], wadnum, *lump, *lastlump);
 
+	if (skin->sprites[0].numframes == 0)
+		I_Error("R_LoadSkinSprites: no frames found for sprite SPR2_%s\n", spr2names[0]);
 }
 
 // returns whether found appropriate property
@@ -2920,6 +2924,8 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
 	GETINT(thrustfactor)
 	GETINT(accelstart)
 	GETINT(acceleration)
+	GETINT(contspeed)
+	GETINT(contangle)
 #undef GETINT
 
 #define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value);
diff --git a/src/r_things.h b/src/r_things.h
index 9c3d16ab018b27abdb610e4ee5eefe7a6b5e66b3..0fa9c4b94936d895b5bd01bf5b4482dea7f9dccd 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -122,6 +122,8 @@ typedef struct
 	UINT8 prefoppositecolor; // if 0 use tables instead
 
 	fixed_t highresscale; // scale of highres, default is 0.5
+	UINT8 contspeed; // continue screen animation speed
+	UINT8 contangle; // initial angle on continue screen
 
 	// specific sounds per skin
 	sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
diff --git a/src/sounds.c b/src/sounds.c
index 11ba1e0bcb4cb78c7d2547d0634fcb42a170f6ba..43225a6157a6b6a9d4f5890505c5fbe8a27435dc 100644
--- a/src/sounds.c
+++ b/src/sounds.c
@@ -35,6 +35,23 @@ sfxinfo_t S_sfx[NUMSFX] =
 //  name, singularity, priority, pitch, volume, data, length, skinsound, usefulness, lumpnum, caption
   {"none" ,  false,   0,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "///////////////////////////////"}, // maximum length
 
+  // A HUMBLE REQUEST FROM YOUR FRIENDLY NEIGHBORHOOD toaster!
+  //
+  // If you see a caption that's just "" (shows the lumpname in-game),
+  // and you intend to use the sound associated with it in a mod,
+  // PLEASE give it a caption through SOC or Lua.
+  //
+  // If the first character of the caption is '/', no caption will be
+  // produced; only do  this for "unimportant" sounds that aren't used
+  // to indicate gameplay.
+  //
+  // (to whomstever updates the sounds list wiki page for 2.2, please
+  // either copy this comment across, or make sure its desire is
+  // codified in the initial paragraph of the page.)
+  //
+  // Closed Captioning may be a niche feature, but it's an important one.
+  // Thank you! ^u^
+
   // Skin Sounds
   {"altdi1", false, 192, 16, -1, NULL, 0, SKSPLDET1,  -1, LUMPERROR, "Dying"},
   {"altdi2", false, 192, 16, -1, NULL, 0, SKSPLDET2,  -1, LUMPERROR, "Dying"},
@@ -290,6 +307,139 @@ sfxinfo_t S_sfx[NUMSFX] =
   {"brakrl", false,  64, 64, -1, NULL, 0,        -1,  -1, LUMPERROR, "Rocket launch"},
   {"brakrx", false,  64, 64, -1, NULL, 0,        -1,  -1, LUMPERROR, "Rocket explosion"},
 
+  // Sonic 1 sounds
+  {"s1a0",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1a1",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1a2",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1a3",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1a4",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1a5",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1a6",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1a7",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1a8",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1a9",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1aa",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1ab",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1ac",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1ad",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1ae",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1af",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1b0",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1b1",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1b2",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1b3",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1b4",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1b5",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1b6",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1b7",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1b8",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1b9",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1ba",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1bb",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1bc",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1bd",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1be",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1bf",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1c0",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1c1",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1c2",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1c3",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1c4",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1c5",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1c6",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1c7",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1c8",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1c9",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1ca",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1cb",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1cc",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1cd",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1ce",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s1cf",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+
+  // Sonic 2 sounds
+  {"s220",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s221",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s222",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s223",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s224",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s225",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s226",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s227",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s228",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s229",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s22a",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s22b",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s22c",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s22d",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s22e",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s22f",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s230",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s231",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s232",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s233",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s234",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s235",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s236",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s237",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s238",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s239",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s23a",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s23b",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s23c",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s23d",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s23e",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s23f",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s240",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s241",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s242",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s243",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s244",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s245",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s246",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s247",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s248",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s249",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s24a",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s24b",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s24c",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s24d",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s24e",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s24f",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s250",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s251",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s252",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s253",   false, 255,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s254",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s255",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s256",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s257",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s258",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s259",   false,  96,  8, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s25a",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s25b",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s25c",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s25d",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s25e",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s25f",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s260",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s261",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s262",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s263",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s264",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s265",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s266",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s267",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s268",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s269",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s26a",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s26b",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s26c",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s26d",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s26e",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s26f",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"s270",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+
   // S3&K sounds
   {"s3k33",  false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Sparkle"}, // stereo in original game, identical to latter
   {"s3k34",  false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Sparkle"}, // mono in original game, identical to previous
@@ -492,6 +642,174 @@ sfxinfo_t S_sfx[NUMSFX] =
   {"s3kdbs", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Running on water"},
   {"s3kdbl", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Running on water"}, // ditto
 
+  // 3D Blast sounds (the "missing" ones are direct copies of S3K's, no minor differences what-so-ever)
+  {"3db06",  false,  96,  8, -1, NULL, 0,        -1,  -1, LUMPERROR, "Collection"},
+  {"3db09",  false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Peep"},
+  {"3db14",  false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Chirp"},
+  {"3db16",  false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+
+  // Sonic CD sounds
+  {"cdfm00", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Skid"},
+  {"cdfm01", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm02", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Jump"},
+  {"cdfm03", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Dying"},
+  {"cdfm04", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Ring loss"},
+  {"cdfm05", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Sparkle"},
+  {"cdfm06", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Pop"},
+  {"cdfm07", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Shield"},
+  {"cdfm08", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Spring"},
+  {"cdfm09", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm10", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm11", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm12", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm13", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm14", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm15", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm16", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm17", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm18", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm19", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm20", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm21", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm22", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm23", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm24", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm25", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm26", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm27", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm28", false,  96,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm29", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Bubble gasp"},
+  {"cdfm30", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Starpost"},
+  {"cdfm31", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Warp"},
+  {"cdfm32", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm33", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm34", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm35", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm36", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm37", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm38", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Drowning"},
+  {"cdfm39", false, 128,  8, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm40", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm41", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm42", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm43", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm44", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Extra time"},
+  {"cdfm45", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm46", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm47", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm48", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm49", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Aquaphobia"},
+  {"cdfm50", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm51", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm52", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm53", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm54", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm55", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm56", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Warp"},
+  {"cdfm57", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm58", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm59", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm60", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm61", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm62", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm63", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm64", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm65", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm66", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm67", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm68", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm69", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm70", false,  96,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm71", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm72", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm73", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm74", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm75", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm76", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm77", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm78", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdfm79", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdpcm0", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Future."},
+  {"cdpcm1", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Past."},
+  {"cdpcm2", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "All right!"},
+  {"cdpcm3", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "I'm outta here..."},
+  {"cdpcm4", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Yes!"},
+  {"cdpcm5", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Yeah!"},
+  {"cdpcm6", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Giggles"},
+  {"cdpcm7", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Eep!"},
+  {"cdpcm8", false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"cdpcm9", false,  96,  8, -1, NULL, 0,        -1,  -1, LUMPERROR, "Bumper"},
+
+  // Knuckles Chaotix sounds
+  {"kc2a",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc2b",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc2c",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc2d",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc2e",   false,  96,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc2f",   false,  96,  8, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc30",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc31",   false,  64, 64, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc32",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc33",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc34",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc35",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc36",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc37",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc38",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc39",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc3a",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc3b",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc3c",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc3d",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc3e",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc3f",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc40",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc41",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc42",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Confirm"},
+  {"kc43",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc44",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc45",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc46",   false,  96,  8, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc47",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc48",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Select"},
+  {"kc49",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc4a",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc4b",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc4c",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc4d",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc4e",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc4f",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc50",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc51",   false,  64, 64, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc52",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc53",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc54",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc55",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc56",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc57",   false, 128,  8, -1, NULL, 0,        -1,  -1, LUMPERROR, "Sheer terror"},
+  {"kc58",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc59",   false, 128,  8, -1, NULL, 0,        -1,  -1, LUMPERROR, "Shrink"},
+  {"kc5a",   false, 128,  8, -1, NULL, 0,        -1,  -1, LUMPERROR, "Grow"},
+  {"kc5b",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc5c",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc5d",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc5e",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc5f",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc60",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc61",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc62",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc63",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc64",   false,  96,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Terrifying rumble"},
+  {"kc65",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc66",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc67",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc68",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc69",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc6b",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, "Ascending"},
+  {"kc6c",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc6d",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+  {"kc6e",   false,  64,  0, -1, NULL, 0,        -1,  -1, LUMPERROR, ""},
+
   // skin sounds free slots to add sounds at run time (Boris HACK!!!)
   // initialized to NULL
 };
diff --git a/src/sounds.h b/src/sounds.h
index 20f89d9fbb241be125c057584634d618a3eda58e..674f51d798ff0576ecebda9e78c818497fa76fb4 100644
--- a/src/sounds.h
+++ b/src/sounds.h
@@ -356,6 +356,139 @@ typedef enum
 	sfx_brakrl, // Rocket launcher
 	sfx_brakrx, // Rocket explodes
 
+	// S1 sounds
+	sfx_s1a0,
+	sfx_s1a1,
+	sfx_s1a2,
+	sfx_s1a3,
+	sfx_s1a4,
+	sfx_s1a5,
+	sfx_s1a6,
+	sfx_s1a7,
+	sfx_s1a8,
+	sfx_s1a9,
+	sfx_s1aa,
+	sfx_s1ab,
+	sfx_s1ac,
+	sfx_s1ad,
+	sfx_s1ae,
+	sfx_s1af,
+	sfx_s1b0,
+	sfx_s1b1,
+	sfx_s1b2,
+	sfx_s1b3,
+	sfx_s1b4,
+	sfx_s1b5,
+	sfx_s1b6,
+	sfx_s1b7,
+	sfx_s1b8,
+	sfx_s1b9,
+	sfx_s1ba,
+	sfx_s1bb,
+	sfx_s1bc,
+	sfx_s1bd,
+	sfx_s1be,
+	sfx_s1bf,
+	sfx_s1c0,
+	sfx_s1c1,
+	sfx_s1c2,
+	sfx_s1c3,
+	sfx_s1c4,
+	sfx_s1c5,
+	sfx_s1c6,
+	sfx_s1c7,
+	sfx_s1c8,
+	sfx_s1c9,
+	sfx_s1ca,
+	sfx_s1cb,
+	sfx_s1cc,
+	sfx_s1cd,
+	sfx_s1ce,
+	sfx_s1cf,
+
+	// S2 sounds
+	sfx_s220,
+	sfx_s221,
+	sfx_s222,
+	sfx_s223,
+	sfx_s224,
+	sfx_s225,
+	sfx_s226,
+	sfx_s227,
+	sfx_s228,
+	sfx_s229,
+	sfx_s22a,
+	sfx_s22b,
+	sfx_s22c,
+	sfx_s22d,
+	sfx_s22e,
+	sfx_s22f,
+	sfx_s230,
+	sfx_s231,
+	sfx_s232,
+	sfx_s233,
+	sfx_s234,
+	sfx_s235,
+	sfx_s236,
+	sfx_s237,
+	sfx_s238,
+	sfx_s239,
+	sfx_s23a,
+	sfx_s23b,
+	sfx_s23c,
+	sfx_s23d,
+	sfx_s23e,
+	sfx_s23f,
+	sfx_s240,
+	sfx_s241,
+	sfx_s242,
+	sfx_s243,
+	sfx_s244,
+	sfx_s245,
+	sfx_s246,
+	sfx_s247,
+	sfx_s248,
+	sfx_s249,
+	sfx_s24a,
+	sfx_s24b,
+	sfx_s24c,
+	sfx_s24d,
+	sfx_s24e,
+	sfx_s24f,
+	sfx_s250,
+	sfx_s251,
+	sfx_s252,
+	sfx_s253,
+	sfx_s254,
+	sfx_s255,
+	sfx_s256,
+	sfx_s257,
+	sfx_s258,
+	sfx_s259,
+	sfx_s25a,
+	sfx_s25b,
+	sfx_s25c,
+	sfx_s25d,
+	sfx_s25e,
+	sfx_s25f,
+	sfx_s260,
+	sfx_s261,
+	sfx_s262,
+	sfx_s263,
+	sfx_s264,
+	sfx_s265,
+	sfx_s266,
+	sfx_s267,
+	sfx_s268,
+	sfx_s269,
+	sfx_s26a,
+	sfx_s26b,
+	sfx_s26c,
+	sfx_s26d,
+	sfx_s26e,
+	sfx_s26f,
+	sfx_s270,
+
 	// S3&K sounds
 	sfx_s3k33,
 	sfx_s3k34,
@@ -558,6 +691,174 @@ typedef enum
 	sfx_s3kdbs,
 	sfx_s3kdbl,
 
+	// 3DB sounds
+	sfx_3db06,
+	sfx_3db09,
+	sfx_3db14,
+	sfx_3db16,
+
+	// SCD sounds
+	sfx_cdfm00,
+	sfx_cdfm01,
+	sfx_cdfm02,
+	sfx_cdfm03,
+	sfx_cdfm04,
+	sfx_cdfm05,
+	sfx_cdfm06,
+	sfx_cdfm07,
+	sfx_cdfm08,
+	sfx_cdfm09,
+	sfx_cdfm10,
+	sfx_cdfm11,
+	sfx_cdfm12,
+	sfx_cdfm13,
+	sfx_cdfm14,
+	sfx_cdfm15,
+	sfx_cdfm16,
+	sfx_cdfm17,
+	sfx_cdfm18,
+	sfx_cdfm19,
+	sfx_cdfm20,
+	sfx_cdfm21,
+	sfx_cdfm22,
+	sfx_cdfm23,
+	sfx_cdfm24,
+	sfx_cdfm25,
+	sfx_cdfm26,
+	sfx_cdfm27,
+	sfx_cdfm28,
+	sfx_cdfm29,
+	sfx_cdfm30,
+	sfx_cdfm31,
+	sfx_cdfm32,
+	sfx_cdfm33,
+	sfx_cdfm34,
+	sfx_cdfm35,
+	sfx_cdfm36,
+	sfx_cdfm37,
+	sfx_cdfm38,
+	sfx_cdfm39,
+	sfx_cdfm40,
+	sfx_cdfm41,
+	sfx_cdfm42,
+	sfx_cdfm43,
+	sfx_cdfm44,
+	sfx_cdfm45,
+	sfx_cdfm46,
+	sfx_cdfm47,
+	sfx_cdfm48,
+	sfx_cdfm49,
+	sfx_cdfm50,
+	sfx_cdfm51,
+	sfx_cdfm52,
+	sfx_cdfm53,
+	sfx_cdfm54,
+	sfx_cdfm55,
+	sfx_cdfm56,
+	sfx_cdfm57,
+	sfx_cdfm58,
+	sfx_cdfm59,
+	sfx_cdfm60,
+	sfx_cdfm61,
+	sfx_cdfm62,
+	sfx_cdfm63,
+	sfx_cdfm64,
+	sfx_cdfm65,
+	sfx_cdfm66,
+	sfx_cdfm67,
+	sfx_cdfm68,
+	sfx_cdfm69,
+	sfx_cdfm70,
+	sfx_cdfm71,
+	sfx_cdfm72,
+	sfx_cdfm73,
+	sfx_cdfm74,
+	sfx_cdfm75,
+	sfx_cdfm76,
+	sfx_cdfm77,
+	sfx_cdfm78,
+	sfx_cdfm79,
+	sfx_cdpcm0,
+	sfx_cdpcm1,
+	sfx_cdpcm2,
+	sfx_cdpcm3,
+	sfx_cdpcm4,
+	sfx_cdpcm5,
+	sfx_cdpcm6,
+	sfx_cdpcm7,
+	sfx_cdpcm8,
+	sfx_cdpcm9,
+
+	// KC sounds
+	sfx_kc2a,
+	sfx_kc2b,
+	sfx_kc2c,
+	sfx_kc2d,
+	sfx_kc2e,
+	sfx_kc2f,
+	sfx_kc30,
+	sfx_kc31,
+	sfx_kc32,
+	sfx_kc33,
+	sfx_kc34,
+	sfx_kc35,
+	sfx_kc36,
+	sfx_kc37,
+	sfx_kc38,
+	sfx_kc39,
+	sfx_kc3a,
+	sfx_kc3b,
+	sfx_kc3c,
+	sfx_kc3d,
+	sfx_kc3e,
+	sfx_kc3f,
+	sfx_kc40,
+	sfx_kc41,
+	sfx_kc42,
+	sfx_kc43,
+	sfx_kc44,
+	sfx_kc45,
+	sfx_kc46,
+	sfx_kc47,
+	sfx_kc48,
+	sfx_kc49,
+	sfx_kc4a,
+	sfx_kc4b,
+	sfx_kc4c,
+	sfx_kc4d,
+	sfx_kc4e,
+	sfx_kc4f,
+	sfx_kc50,
+	sfx_kc51,
+	sfx_kc52,
+	sfx_kc53,
+	sfx_kc54,
+	sfx_kc55,
+	sfx_kc56,
+	sfx_kc57,
+	sfx_kc58,
+	sfx_kc59,
+	sfx_kc5a,
+	sfx_kc5b,
+	sfx_kc5c,
+	sfx_kc5d,
+	sfx_kc5e,
+	sfx_kc5f,
+	sfx_kc60,
+	sfx_kc61,
+	sfx_kc62,
+	sfx_kc63,
+	sfx_kc64,
+	sfx_kc65,
+	sfx_kc66,
+	sfx_kc67,
+	sfx_kc68,
+	sfx_kc69,
+	sfx_kc6b,
+	sfx_kc6c,
+	sfx_kc6d,
+	sfx_kc6e,
+
 	// free slots for S_AddSoundFx() at run-time --------------------
 	sfx_freeslot0,
 	//
diff --git a/src/st_stuff.c b/src/st_stuff.c
index a90661ef35fff94338b21b19b93d4404fa17cf42..c4f1327c0058a465e86170d5cf80319499acd6fc 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -64,11 +64,12 @@ patch_t *sbotime; // Time logo
 patch_t *sbocolon; // Colon for time
 patch_t *sboperiod; // Period for time centiseconds
 patch_t *livesback; // Lives icon background
+patch_t *stlivex;
 static patch_t *nrec_timer; // Timer for NiGHTS records
 static patch_t *sborings;
-static patch_t *sboover;
-static patch_t *timeover;
-static patch_t *stlivex;
+static patch_t *slidgame;
+static patch_t *slidtime;
+static patch_t *slidover;
 static patch_t *sboredrings;
 static patch_t *sboredtime;
 static patch_t *getall; // Special Stage HUD
@@ -253,8 +254,10 @@ void ST_LoadGraphics(void)
 	sbocolon = W_CachePatchName("STTCOLON", PU_HUDGFX); // Colon for time
 	sboperiod = W_CachePatchName("STTPERIO", PU_HUDGFX); // Period for time centiseconds
 
-	sboover = W_CachePatchName("SBOOVER", PU_HUDGFX);
-	timeover = W_CachePatchName("TIMEOVER", PU_HUDGFX);
+	slidgame = W_CachePatchName("SLIDGAME", PU_HUDGFX);
+	slidtime = W_CachePatchName("SLIDTIME", PU_HUDGFX);
+	slidover = W_CachePatchName("SLIDOVER", PU_HUDGFX);
+
 	stlivex = W_CachePatchName("STLIVEX", PU_HUDGFX);
 	livesback = W_CachePatchName("STLIVEBK", PU_HUDGFX);
 	nrec_timer = W_CachePatchName("NGRTIMER", PU_HUDGFX); // Timer for NiGHTS
@@ -768,7 +771,12 @@ static inline void ST_drawRings(void)
 
 	ST_DrawPatchFromHud(HUD_RINGS, ((!stplyr->spectator && stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings), ((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS));
 
-	ringnum = ((objectplacing) ? op_currentdoomednum : max(stplyr->rings, 0));
+	if (objectplacing)
+		ringnum = op_currentdoomednum;
+	else if (stplyr->rings < 0 || stplyr->spectator || stplyr->playerstate == PST_REBORN)
+		ringnum = 0;
+	else
+		ringnum = stplyr->rings;
 
 	if (cv_timetic.value == 2) // Yes, even in modeattacking
 		ST_DrawNumFromHud(HUD_RINGSNUMTICS, ringnum, V_PERPLAYER|((stplyr->spectator) ? V_HUDTRANSHALF : V_HUDTRANS));
@@ -877,6 +885,8 @@ static void ST_drawLivesArea(void)
 				'\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false);
 		else
 		{
+			if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1)))
+				livescount++;
 			if (livescount > 99)
 				livescount = 99;
 			V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8,
@@ -2029,42 +2039,7 @@ static void ST_drawTextHUD(void)
 			textHUDdraw(va("Lap:""\x82 %u/%d", stplyr->laps+1, cv_numlaps.value))
 	}
 
-	if (!stplyr->spectator && stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP)
-	{
-		INT32 i, total = 0, exiting = 0;
-
-		for (i = 0; i < MAXPLAYERS; i++)
-		{
-			if (!playeringame[i] || players[i].spectator)
-				continue;
-			if (players[i].lives <= 0)
-				continue;
-
-			total++;
-			if (players[i].exiting)
-				exiting++;
-		}
-
-		if (cv_playersforexit.value != 4)
-		{
-			total *= cv_playersforexit.value;
-			if (total & 3)
-				total += 4; // round up
-			total /= 4;
-		}
-
-		if (exiting < total)
-		{
-			if (!splitscreen && !donef12)
-			{
-				textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view"))
-				donef12 = true;
-			}
-			total -= exiting;
-			textHUDdraw(va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s")))
-		}
-	}
-	else if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)))
+	if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)))
 	{
 		if (!splitscreen && !donef12)
 		{
@@ -2072,7 +2047,7 @@ static void ST_drawTextHUD(void)
 			donef12 = true;
 		}
 	}
-	else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text.
+	else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) // Death overrides spectator text.
 	{
 		INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE;
 
@@ -2092,7 +2067,7 @@ static void ST_drawTextHUD(void)
 		textHUDdraw(M_GetText("\x82""JUMP:""\x80 Rise"))
 		textHUDdraw(M_GetText("\x82""SPIN:""\x80 Lower"))
 
-		if (G_IsSpecialStage(gamemap) && (maptol & TOL_NIGHTS))
+		if (G_IsSpecialStage(gamemap))
 			textHUDdraw(M_GetText("\x82""Wait for the stage to end..."))
 		else if (gametype == GT_COOP)
 		{
@@ -2125,7 +2100,42 @@ static void ST_drawTextHUD(void)
 			textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game"))
 	}
 
-	if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator))
+	if (gametype == GT_COOP && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && stplyr->exiting && cv_playersforexit.value)
+	{
+		INT32 i, total = 0, exiting = 0;
+
+		for (i = 0; i < MAXPLAYERS; i++)
+		{
+			if (!playeringame[i] || players[i].spectator)
+				continue;
+			if (players[i].lives <= 0)
+				continue;
+
+			total++;
+			if (players[i].exiting)
+				exiting++;
+		}
+
+		if (cv_playersforexit.value != 4)
+		{
+			total *= cv_playersforexit.value;
+			if (total & 3)
+				total += 4; // round up
+			total /= 4;
+		}
+
+		if (exiting < total)
+		{
+			if (!splitscreen && !donef12)
+			{
+				textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view"))
+				donef12 = true;
+			}
+			total -= exiting;
+			textHUDdraw(va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s")))
+		}
+	}
+	else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator))
 	{
 		if (leveltime < hidetime * TICRATE)
 		{
@@ -2409,25 +2419,20 @@ static void ST_overlayDrawer(void)
 		}
 	}
 
-	// GAME OVER pic
+	// GAME OVER hud
 	if ((gametype == GT_COOP)
 		&& (netgame || multiplayer)
 		&& (cv_cooplives.value == 0))
 	;
-	else if (G_GametypeUsesLives() && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer)))
+	else if ((G_GametypeUsesLives() || gametype == GT_RACE) && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer)))
 	{
-		patch_t *p;
-
-		if (countdown == 1)
-			p = timeover;
-		else
-			p = sboover;
+		INT32 i = MAXPLAYERS;
+		INT32 deadtimer = stplyr->spectator ? TICRATE : (stplyr->deadtimer-(TICRATE<<1));
 
 		if ((gametype == GT_COOP)
 		&& (netgame || multiplayer)
 		&& (cv_cooplives.value != 1))
 		{
-			INT32 i;
 			for (i = 0; i < MAXPLAYERS; i++)
 			{
 				if (!playeringame[i])
@@ -2437,15 +2442,18 @@ static void ST_overlayDrawer(void)
 					continue;
 
 				if (players[i].lives > 0)
-				{
-					p = NULL;
 					break;
-				}
 			}
 		}
 
-		if (p)
-			V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, BASEVIDHEIGHT/2 - (SHORT(p->height)/2), V_PERPLAYER|(stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS), p);
+		if (i == MAXPLAYERS && deadtimer >= 0)
+		{
+			INT32 lvlttlx = min(6*deadtimer, BASEVIDWIDTH/2);
+			UINT32 flags = V_PERPLAYER|(stplyr->spectator ? V_HUDTRANSHALF : V_HUDTRANS);
+
+			V_DrawScaledPatch(lvlttlx - 8, BASEVIDHEIGHT/2, flags, (countdown == 1 ? slidtime : slidgame));
+			V_DrawScaledPatch(BASEVIDWIDTH + 8 - lvlttlx, BASEVIDHEIGHT/2, flags, slidover);
+		}
 	}
 
 	if (G_GametypeHasTeams())
diff --git a/src/st_stuff.h b/src/st_stuff.h
index 40574f46c1d07249318ee713fec74e1291778a4a..aaf01ca15a2c67ad7bfb84859d4df8efde9505fd 100644
--- a/src/st_stuff.h
+++ b/src/st_stuff.h
@@ -70,6 +70,7 @@ extern patch_t *sboperiod;
 extern patch_t *faceprefix[MAXSKINS]; // face status patches
 extern patch_t *superprefix[MAXSKINS]; // super face status patches
 extern patch_t *livesback;
+extern patch_t *stlivex;
 extern patch_t *ngradeletters[7];
 
 /** HUD location information (don't move this comment)
diff --git a/src/v_video.c b/src/v_video.c
index 1ed5939d335206058213e3f6412bcdd863614295..7473001147bda0d95db5bcda274f42186655a21d 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -1071,17 +1071,17 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
 //
 void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
 {
-	if (skinnum < 0 || skinnum >= numskins || (skins[skinnum].flags & SF_HIRES))
-		V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
-	else
+	if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes >= 4)
 	{
-		spriteframe_t *sprframe = &skins[skinnum].sprites[SPR2_WAIT].spriteframes[0];
-		patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
+		spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
+		spriteframe_t *sprframe = &sprdef->spriteframes[3];
+		patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
 		const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
 
-		// No variant for translucency
-		V_DrawTinyMappedPatch(x, y, flags, patch, colormap);
+		V_DrawMappedPatch(x, y, flags, patch, colormap);
 	}
+	else
+		V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
 }
 
 //
diff --git a/src/y_inter.c b/src/y_inter.c
index 975902ab089b2593f738bb14540cb2e812df1df8..1cb1b9cd80a0bf7263aa9b98e89f13e47f542d1e 100644
--- a/src/y_inter.c
+++ b/src/y_inter.c
@@ -429,7 +429,7 @@ void Y_IntermissionDrawer(void)
 				{
 					if ((data.spec.continues & 0x80) && i == continues-1 && (endtic < 0 || intertic%20 < 10))
 						break;
-					V_DrawContinueIcon(246 + xoffset5 - (i*12), 162+yoffset, 0, *data.spec.playerchar, *data.spec.playercolor);
+					V_DrawContinueIcon(246 + xoffset5 - (i*20), 162+yoffset, 0, *data.spec.playerchar, *data.spec.playercolor);
 				}
 			}
 		}