diff --git a/src/doomstat.h b/src/doomstat.h
index 57e37f72dc98dfbcbecdb225292e6bcc10c71db7..7d06f03e24445c868d385f6dc83002fbcb542ab2 100644
--- a/src/doomstat.h
+++ b/src/doomstat.h
@@ -327,7 +327,7 @@ typedef struct
 	// Music stuff.
 	UINT32 musinterfadeout;  ///< Fade out level music on intermission screen in milliseconds
 	char musintername[7];    ///< Intermission screen music.
-	
+
 	char muspostbossname[7];    ///< Post-bossdeath music.
 	UINT16 muspostbosstrack;    ///< Post-bossdeath track.
 	UINT32 muspostbosspos;      ///< Post-bossdeath position
@@ -433,6 +433,7 @@ typedef struct
 	tic_t time;   ///< Time in which the level was finished.
 	UINT32 score; ///< Score when the level was finished.
 	UINT16 rings; ///< Rings when the level was finished.
+	boolean gotperfect; ///< Got perfect bonus?
 } recorddata_t;
 
 /** Setup for one NiGHTS map.
diff --git a/src/g_game.c b/src/g_game.c
index 6c31ce9e32b9716494ea7915da4ff55e755bd8e7..fc5055bab84db454e83588629603fef9e41ea47b 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -3341,6 +3341,7 @@ void G_LoadGameData(void)
 	UINT32 recscore;
 	tic_t  rectime;
 	UINT16 recrings;
+	boolean gotperf;
 
 	UINT8 recmares;
 	INT32 curmare;
@@ -3433,6 +3434,7 @@ void G_LoadGameData(void)
 		recscore = READUINT32(save_p);
 		rectime  = (tic_t)READUINT32(save_p);
 		recrings = READUINT16(save_p);
+		gotperf = (boolean)READUINT8(save_p);
 
 		if (recrings > 10000 || recscore > MAXSCORE)
 			goto datacorrupt;
@@ -3444,6 +3446,9 @@ void G_LoadGameData(void)
 			mainrecords[i]->time = rectime;
 			mainrecords[i]->rings = recrings;
 		}
+
+		if (gotperf)
+			mainrecords[i]->gotperfect = gotperf;
 	}
 
 	// Nights records
@@ -3575,12 +3580,14 @@ void G_SaveGameData(void)
 			WRITEUINT32(save_p, mainrecords[i]->score);
 			WRITEUINT32(save_p, mainrecords[i]->time);
 			WRITEUINT16(save_p, mainrecords[i]->rings);
+			WRITEUINT8(save_p, mainrecords[i]->gotperfect);
 		}
 		else
 		{
 			WRITEUINT32(save_p, 0);
 			WRITEUINT32(save_p, 0);
 			WRITEUINT16(save_p, 0);
+			WRITEUINT8(save_p, 0);
 		}
 	}
 
diff --git a/src/info.h b/src/info.h
index 1e765255754207967e634dd123262e1bf4865d35..38e6276ab8a37d031f7caad92ef993164fb98994 100644
--- a/src/info.h
+++ b/src/info.h
@@ -874,9 +874,8 @@ typedef enum playersprite
 // SPR2_XTRA
 #define XTRA_LIFEPIC    0                 // Life icon patch
 #define XTRA_CHARSEL    1                 // Character select picture
-#define XTRA_NAMETAG    2                 // Character select nametag
-#define XTRA_CONTINUE   3                 // Continue icon
-#define XTRA_ENDING     4                 // Ending finale patches
+#define XTRA_CONTINUE   2                 // Continue icon
+#define XTRA_ENDING     3                 // Ending finale patches
 
 typedef enum state
 {
diff --git a/src/m_cond.c b/src/m_cond.c
index 539c6d1f6d1fc38efacad7d1e56329a323010afb..b7520aba78e1be64ef810e46bfbb58c3d593b155 100644
--- a/src/m_cond.c
+++ b/src/m_cond.c
@@ -528,12 +528,22 @@ skincolors_t M_GetEmblemColor(emblem_t *em)
 	return em->color;
 }
 
-const char *M_GetEmblemPatch(emblem_t *em)
+const char *M_GetEmblemPatch(emblem_t *em, boolean big)
 {
-	static char pnamebuf[7] = "GOTITn";
+	static char pnamebuf[7];
+
+	if (!big)
+		strcpy(pnamebuf, "GOTITn");
+	else
+		strcpy(pnamebuf, "EMBMn0");
 
 	I_Assert(em->sprite >= 'A' && em->sprite <= 'Z');
-	pnamebuf[5] = em->sprite;
+
+	if (!big)
+		pnamebuf[5] = em->sprite;
+	else
+		pnamebuf[4] = em->sprite;
+
 	return pnamebuf;
 }
 
@@ -544,11 +554,21 @@ skincolors_t M_GetExtraEmblemColor(extraemblem_t *em)
 	return em->color;
 }
 
-const char *M_GetExtraEmblemPatch(extraemblem_t *em)
+const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big)
 {
-	static char pnamebuf[7] = "GOTITn";
+	static char pnamebuf[7];
+
+	if (!big)
+		strcpy(pnamebuf, "GOTITn");
+	else
+		strcpy(pnamebuf, "EMBMn0");
 
 	I_Assert(em->sprite >= 'A' && em->sprite <= 'Z');
-	pnamebuf[5] = em->sprite;
+
+	if (!big)
+		pnamebuf[5] = em->sprite;
+	else
+		pnamebuf[4] = em->sprite;
+
 	return pnamebuf;
 }
diff --git a/src/m_cond.h b/src/m_cond.h
index f82e49372ed0120da76cdd2bd8d8c0a7f2a128c5..e9859cf11552125e40fdfffba8b57bb2f5497386 100644
--- a/src/m_cond.h
+++ b/src/m_cond.h
@@ -171,9 +171,9 @@ INT32 M_CountEmblems(void);
 // Emblem shit
 emblem_t *M_GetLevelEmblems(INT32 mapnum);
 skincolors_t M_GetEmblemColor(emblem_t *em);
-const char *M_GetEmblemPatch(emblem_t *em);
+const char *M_GetEmblemPatch(emblem_t *em, boolean big);
 skincolors_t M_GetExtraEmblemColor(extraemblem_t *em);
-const char *M_GetExtraEmblemPatch(extraemblem_t *em);
+const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big);
 
 // If you're looking to compare stats for unlocks or what not, use these
 // They stop checking upon reaching the target number so they
diff --git a/src/m_menu.c b/src/m_menu.c
index fea6629429301eb5f452cfa07df60d296b975ddc..2a028834de90e69e93dec429db3cb5da189f94f8 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -753,8 +753,8 @@ static menuitem_t SP_TimeAttackLevelSelectMenu[] =
 // Single Player Time Attack
 static menuitem_t SP_TimeAttackMenu[] =
 {
-	{IT_STRING|IT_KEYHANDLER,  NULL, "Level Select...", M_HandleTimeAttackLevelSelect,   52},
-	{IT_STRING|IT_CVAR,        NULL, "Character",       &cv_chooseskin,             62},
+	{IT_STRING|IT_KEYHANDLER,  NULL, "Level Select...", M_HandleTimeAttackLevelSelect,   62},
+	{IT_STRING|IT_CVAR,        NULL, "Character",       &cv_chooseskin,             72},
 
 	{IT_DISABLED,              NULL, "Guest Option...", &SP_GuestReplayDef, 100},
 	{IT_DISABLED,              NULL, "Replay...",       &SP_ReplayDef,      110},
@@ -3906,7 +3906,7 @@ static void M_DrawMapEmblems(INT32 mapnum, INT32 x, INT32 y)
 		lasttype = curtype;
 
 		if (emblem->collected)
-			V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE),
+			V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE),
 			                       R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE));
 		else
 			V_DrawSmallScaledPatch(x, y, 0, W_CachePatchName("NEEDIT", PU_CACHE));
@@ -4345,7 +4345,7 @@ static void M_DrawPauseMenu(void)
 				continue;
 
 			if (emblem->collected)
-				V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE),
+				V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE),
 				                       R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE));
 			else
 				V_DrawSmallScaledPatch(40, 44 + (i*8), 0, W_CachePatchName("NEEDIT", PU_CACHE));
@@ -6866,7 +6866,7 @@ static void M_DrawEmblemHints(void)
 		if (emblem->collected)
 		{
 			collected = V_GREENMAP;
-			V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem), PU_CACHE),
+			V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE),
 				R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE));
 		}
 		else
@@ -8487,7 +8487,7 @@ static void M_DrawStatsMaps(int location)
 			exemblem = &extraemblems[i];
 
 			if (exemblem->collected)
-				V_DrawSmallMappedPatch(292, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem), PU_CACHE),
+				V_DrawSmallMappedPatch(292, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem, false), PU_CACHE),
 				                       R_GetTranslationColormap(TC_DEFAULT, M_GetExtraEmblemColor(exemblem), GTC_CACHE));
 			else
 				V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_CACHE));
@@ -8632,9 +8632,10 @@ static void M_HandleLevelStats(INT32 choice)
 // Drawing function for Time Attack
 void M_DrawTimeAttackMenu(void)
 {
-	INT32 i, x, y, cursory = 0;
+	INT32 i, x, y, empatx, empaty, cursory = 0;
 	UINT16 dispstatus;
 	patch_t *PictureOfUrFace;	// my WHAT
+	patch_t *empatch;
 
 	M_SetMenuCurBackground("RECATKBG");
 
@@ -8738,16 +8739,22 @@ void M_DrawTimeAttackMenu(void)
 			PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE);
 
 		y = 32+lsheadingheight;
-		V_DrawSmallScaledPatch(208, y, 0, PictureOfLevel);
+		V_DrawSmallScaledPatch(216, y, 0, PictureOfLevel);
+
 
-		if (itemOn == talevel)
+		if (currentMenu == &SP_TimeAttackDef)
 		{
-			/* Draw arrows !! */
-			y = y + 25 - 4;
-			V_DrawCharacter(208 - 10 - (skullAnimCounter/5), y,
-					'\x1C' | V_YELLOWMAP, false);
-			V_DrawCharacter(208 + 80 + 2 + (skullAnimCounter/5), y,
-					'\x1D' | V_YELLOWMAP, false);
+			if (itemOn == talevel)
+			{
+				/* Draw arrows !! */
+				y = y + 25 - 4;
+				V_DrawCharacter(216 - 10 - (skullAnimCounter/5), y,
+						'\x1C' | V_YELLOWMAP, false);
+				V_DrawCharacter(216 + 80 + 2 + (skullAnimCounter/5), y,
+						'\x1D' | V_YELLOWMAP, false);
+			}
+			// Draw press ESC to exit string on main record attack menu
+			V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit"));
 		}
 
 		em = M_GetLevelEmblems(cv_nextmap.value);
@@ -8757,42 +8764,46 @@ void M_DrawTimeAttackMenu(void)
 			switch (em->type)
 			{
 				case ET_SCORE:
-					yHeight = 48;
-					sprintf(reqscore, "%u", em->var);
+					yHeight = 33;
+					sprintf(reqscore, "(%u)", em->var);
 					break;
 				case ET_TIME:
-					yHeight = 58;
-					sprintf(reqtime, "%i:%02i.%02i", G_TicsToMinutes((tic_t)em->var, true),
+					yHeight = 53;
+					sprintf(reqtime, "(%i:%02i.%02i)", G_TicsToMinutes((tic_t)em->var, true),
 										G_TicsToSeconds((tic_t)em->var),
 										G_TicsToCentiseconds((tic_t)em->var));
 					break;
 				case ET_RINGS:
-					yHeight = 68;
-					sprintf(reqrings, "%u", em->var);
+					yHeight = 73;
+					sprintf(reqrings, "(%u)", em->var);
 					break;
 				default:
 					goto skipThisOne;
 			}
 
+			empatch = W_CachePatchName(M_GetEmblemPatch(em, true), PU_CACHE);
+
+			empatx = SHORT(empatch->leftoffset)/2;
+			empaty = SHORT(empatch->topoffset)/2;
+
 			if (em->collected)
-				V_DrawSmallMappedPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE),
+				V_DrawSmallMappedPatch(104+76+empatx, yHeight+lsheadingheight/2+empaty, 0, empatch,
 				                       R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE));
 			else
-				V_DrawSmallScaledPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE));
+				V_DrawSmallScaledPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDITL", PU_CACHE));
 
 			skipThisOne:
 			em = M_GetLevelEmblems(-1);
 		}
 
-		V_DrawString(104 - 72, 32+lsheadingheight/2, 0, "* LEVEL RECORDS *");
-
 		if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->score)
 			sprintf(beststr, "(none)");
 		else
 			sprintf(beststr, "%u", mainrecords[cv_nextmap.value-1]->score);
 
-		V_DrawString(104-72, 48+lsheadingheight/2, V_YELLOWMAP, "SCORE:");
-		V_DrawRightAlignedString(104+72, 48+lsheadingheight/2, V_ALLOWLOWERCASE, va("%s%s", beststr,reqscore));
+		V_DrawString(104-72, 33+lsheadingheight/2, V_YELLOWMAP, "SCORE:");
+		V_DrawRightAlignedString(104+64, 33+lsheadingheight/2, V_ALLOWLOWERCASE, beststr);
+		V_DrawRightAlignedString(104+72, 43+lsheadingheight/2, V_ALLOWLOWERCASE, reqscore);
 
 		if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->time)
 			sprintf(beststr, "(none)");
@@ -8801,16 +8812,23 @@ void M_DrawTimeAttackMenu(void)
 			                                 G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->time),
 			                                 G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->time));
 
-		V_DrawString(104-72, 58+lsheadingheight/2, V_YELLOWMAP, "TIME:");
-		V_DrawRightAlignedString(104+72, 58+lsheadingheight/2, V_ALLOWLOWERCASE, va("%s%s", beststr,reqtime));
+		V_DrawString(104-72, 53+lsheadingheight/2, V_YELLOWMAP, "TIME:");
+		V_DrawRightAlignedString(104+64, 53+lsheadingheight/2, V_ALLOWLOWERCASE, beststr);
+		V_DrawRightAlignedString(104+72, 63+lsheadingheight/2, V_ALLOWLOWERCASE, reqtime);
 
 		if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->rings)
 			sprintf(beststr, "(none)");
 		else
 			sprintf(beststr, "%hu", mainrecords[cv_nextmap.value-1]->rings);
 
-		V_DrawString(104-72, 68+lsheadingheight/2, V_YELLOWMAP, "RINGS:");
-		V_DrawRightAlignedString(104+72, 68+lsheadingheight/2, V_ALLOWLOWERCASE, va("%s%s", beststr,reqrings));
+		V_DrawString(104-72, 73+lsheadingheight/2, V_YELLOWMAP, "RINGS:");
+
+		if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->gotperfect)
+			V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE, beststr);
+		else
+			V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE|V_YELLOWMAP, beststr);
+
+		V_DrawRightAlignedString(104+72, 83+lsheadingheight/2, V_ALLOWLOWERCASE, reqrings);
 	}
 
 	// ALWAYS DRAW level and skin even when not on this menu!
@@ -8827,10 +8845,6 @@ void M_DrawTimeAttackMenu(void)
 		V_DrawString(x, y + SP_TimeAttackMenu[taplayer].alphaKey, V_TRANSLUCENT, SP_TimeAttackMenu[taplayer].text);
 		V_DrawString(BASEVIDWIDTH - x - V_StringWidth(ncv->string, 0), y + SP_TimeAttackMenu[taplayer].alphaKey, V_YELLOWMAP|V_TRANSLUCENT, ncv->string);
 	}
-
-	// Draw press ESC to exit string on main record attack menu
-	if (currentMenu == &SP_TimeAttackDef)
-		V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit"));
 }
 
 static void M_HandleTimeAttackLevelSelect(INT32 choice)
@@ -8985,8 +8999,6 @@ void M_DrawNightsAttackMenu(void)
 
 		V_DrawSmallScaledPatch(208, 32+lsheadingheight, 0, PictureOfLevel);
 
-		V_DrawString(104 - 72, 32+lsheadingheight/2, 0, "* LEVEL RECORDS *");
-
 		// Super Sonic
 		M_DrawNightsAttackSuperSonic();
 		//if (P_HasGrades(cv_nextmap.value, 0))
@@ -9032,7 +9044,7 @@ void M_DrawNightsAttackMenu(void)
 				}
 
 				if (em->collected)
-					V_DrawSmallMappedPatch(104+38, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em), PU_CACHE),
+					V_DrawSmallMappedPatch(104+38, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em, false), PU_CACHE),
 																 R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE));
 				else
 					V_DrawSmallScaledPatch(104+38, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE));
diff --git a/src/v_video.c b/src/v_video.c
index 8f44ca8cdbe8b0dc603766e3121ec9327ccc2ca7..51c9cf56be00e9f1e5007977787e7fbd0dd07cff 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -1074,7 +1074,7 @@ void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skin
 	if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes >= 4)
 	{
 		spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
-		spriteframe_t *sprframe = &sprdef->spriteframes[3];
+		spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CONTINUE];
 		patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
 		const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
 
diff --git a/src/y_inter.c b/src/y_inter.c
index 0d6a3d03cff6b9e7676838d7a7a9d93e18cbdbcc..9eea4837ed82b31538b60f287a13616154e40103 100644
--- a/src/y_inter.c
+++ b/src/y_inter.c
@@ -1047,6 +1047,9 @@ static void Y_UpdateRecordReplays(void)
 	if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings)
 		mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings);
 
+	if (data.coop.gotperfbonus)
+		mainrecords[gamemap-1]->gotperfect = true;
+
 	// Save demo!
 	bestdemo[255] = '\0';
 	lastdemo[255] = '\0';