diff --git a/src/g_input.c b/src/g_input.c
index 4222951fac258c75e3747e68ca1464e6d17e1934..7d963321643eb16bfabe453873007f7502c279d5 100644
--- a/src/g_input.c
+++ b/src/g_input.c
@@ -1475,7 +1475,7 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis
 	}
 }
 
-INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify)
+INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify, UINT8 player)
 {
 	INT32 result = GC_NULL;
 	if (cv_controlperkey.value == 1)
@@ -1483,22 +1483,22 @@ INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify)
 		INT32 i;
 		for (i = 0; i < NUM_GAMECONTROLS; i++)
 		{
-			if (gamecontrol[i][0] == keynum)
+			if (gamecontrol[i][0] == keynum && player != 2)
 			{
 				result = i;
 				if (modify) gamecontrol[i][0] = KEY_NULL;
 			}
-			if (gamecontrol[i][1] == keynum)
+			if (gamecontrol[i][1] == keynum && player != 2)
 			{
 				result = i;
 				if (modify) gamecontrol[i][1] = KEY_NULL;
 			}
-			if (gamecontrolbis[i][0] == keynum)
+			if (gamecontrolbis[i][0] == keynum && player != 1)
 			{
 				result = i;
 				if (modify) gamecontrolbis[i][0] = KEY_NULL;
 			}
-			if (gamecontrolbis[i][1] == keynum)
+			if (gamecontrolbis[i][1] == keynum && player != 1)
 			{
 				result = i;
 				if (modify) gamecontrolbis[i][1] = KEY_NULL;
@@ -1510,7 +1510,7 @@ INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify)
 	return result;
 }
 
-static INT32 G_FilterKeyByVersion(INT32 numctrl, INT32 keyidx, INT32 player, INT32 *keynum1, INT32 *keynum2, boolean *nestedoverride)
+static INT32 G_FilterSpecialKeys(INT32 keyidx, INT32 player, INT32 *keynum1, INT32 *keynum2)
 {
 	// Special case: ignore KEY_PAUSE because it's hardcoded
 	if (keyidx == 0 && *keynum1 == KEY_PAUSE)
@@ -1526,99 +1526,6 @@ static INT32 G_FilterKeyByVersion(INT32 numctrl, INT32 keyidx, INT32 player, INT
 	else if (keyidx == 1 && *keynum2 == KEY_PAUSE)
 		return -1; // skip setting control
 
-	if (GETMAJOREXECVERSION(cv_execversion.value) < 27 && ( // v2.1.22
-		numctrl == GC_WEAPONNEXT || numctrl == GC_WEAPONPREV || numctrl == GC_TOSSFLAG ||
-		numctrl == GC_SPIN || numctrl == GC_CAMRESET || numctrl == GC_JUMP ||
-		numctrl == GC_PAUSE || numctrl == GC_SYSTEMMENU || numctrl == GC_CAMTOGGLE ||
-		numctrl == GC_SCREENSHOT || numctrl == GC_TALKKEY || numctrl == GC_SCORES ||
-		numctrl == GC_CENTERVIEW
-	))
-	{
-		INT32 keynum = 0, existingctrl = 0;
-		INT32 defaultkey;
-		boolean defaultoverride = false;
-
-		// get the default gamecontrol
-		if (player == 0 && numctrl == GC_SYSTEMMENU)
-			defaultkey = gamecontrol[numctrl][0];
-		else
-			defaultkey = (player == 1 ? gamecontrolbis[numctrl][0] : gamecontrol[numctrl][1]);
-
-		// Assign joypad button defaults if there is an open slot.
-		// At this point, gamecontrol/bis should have the default controls
-		// (unless LOADCONFIG is being run)
-		//
-		// If the player runs SETCONTROL in-game, this block should not be reached
-		// because EXECVERSION is locked onto the latest version.
-		if (keyidx == 0 && !*keynum1)
-		{
-			if (*keynum2) // push keynum2 down; this is an edge case
-			{
-				*keynum1 = *keynum2;
-				*keynum2 = 0;
-				keynum = *keynum1;
-			}
-			else
-			{
-				keynum = defaultkey;
-				defaultoverride = true;
-			}
-		}
-		else if (keyidx == 1 && (!*keynum2 || (!*keynum1 && *keynum2))) // last one is the same edge case as above
-		{
-			keynum = defaultkey;
-			defaultoverride = true;
-		}
-		else // default to the specified keynum
-			keynum = (keyidx == 1 ? *keynum2 : *keynum1);
-
-		// Did our last call override keynum2?
-		if (*nestedoverride)
-		{
-			defaultoverride = true;
-			*nestedoverride = false;
-		}
-
-		// Fill keynum2 with the default control
-		if (keyidx == 0 && !*keynum2)
-		{
-			*keynum2 = defaultkey;
-			// Tell the next call that this is an override
-			*nestedoverride = true;
-
-			// if keynum2 already matches keynum1, we probably recursed
-			// so unset it
-			if (*keynum1 == *keynum2)
-			{
-				*keynum2 = 0;
-				*nestedoverride = false;
-		}
-		}
-
-		// check if the key is being used somewhere else before passing it
-		// pass it through if it's the same numctrl. This is an edge case -- when using
-		// LOADCONFIG, gamecontrol is not reset with default.
-		//
-		// Also, only check if we're actually overriding, to preserve behavior where
-		// config'd keys overwrite default keys.
-		if (defaultoverride)
-			existingctrl = G_CheckDoubleUsage(keynum, false);
-
-		if (keynum && (!existingctrl || existingctrl == numctrl))
-			return keynum;
-		else if (keyidx == 0 && *keynum2)
-		{
-			// try it again and push down keynum2
-			*keynum1 = *keynum2;
-			*keynum2 = 0;
-			return G_FilterKeyByVersion(numctrl, keyidx, player, keynum1, keynum2, nestedoverride);
-			// recursion *should* be safe because we only assign keynum2 to a joy default
-			// and then clear it if we find that keynum1 already has the joy default.
-		}
-		else
-			return 0;
-	}
-
 	// All's good, so pass the keynum as-is
 	if (keyidx == 1)
 		return *keynum2;
@@ -1632,7 +1539,6 @@ static void setcontrol(INT32 (*gc)[2])
 	const char *namectrl;
 	INT32 keynum, keynum1, keynum2;
 	INT32 player = ((void*)gc == (void*)&gamecontrolbis ? 1 : 0);
-	boolean nestedoverride = false;
 
 	// Update me for 2.3
 	namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin";
@@ -1647,20 +1553,20 @@ static void setcontrol(INT32 (*gc)[2])
 	}
 	keynum1 = G_KeyNameToNum(COM_Argv(2));
 	keynum2 = G_KeyNameToNum(COM_Argv(3));
-	keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride);
+	keynum = G_FilterSpecialKeys(0, player, &keynum1, &keynum2);
 
 	if (keynum >= 0)
 	{
-		(void)G_CheckDoubleUsage(keynum, true);
+		(void)G_CheckDoubleUsage(keynum, true, player+1);
 
 		// if keynum was rejected, try it again with keynum2
 		if (!keynum && keynum2)
 		{
 			keynum1 = keynum2; // push down keynum2
 			keynum2 = 0;
-			keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride);
+			keynum = G_FilterSpecialKeys(0, player, &keynum1, &keynum2);
 			if (keynum >= 0)
-				(void)G_CheckDoubleUsage(keynum, true);
+				(void)G_CheckDoubleUsage(keynum, true, player+1);
 		}
 	}
 
@@ -1669,7 +1575,7 @@ static void setcontrol(INT32 (*gc)[2])
 
 	if (keynum2)
 	{
-		keynum = G_FilterKeyByVersion(numctrl, 1, player, &keynum1, &keynum2, &nestedoverride);
+		keynum = G_FilterSpecialKeys(1, player, &keynum1, &keynum2);
 		if (keynum >= 0)
 		{
 			if (keynum != gc[numctrl][0])
diff --git a/src/g_input.h b/src/g_input.h
index 9d393fee1fc2112e6dc691aa7142c09377064152..ff42d1489fc6132eb579d96c9cf5e7c083304125 100644
--- a/src/g_input.h
+++ b/src/g_input.h
@@ -355,7 +355,7 @@ void G_DefineDefaultControls(void);
 INT32 G_GetControlScheme(INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen);
 void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen);
 void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis)[2]);
-INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify);
+INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify, UINT8 player);
 
 // sets the members of a mouse_t given position deltas
 void G_SetMouseDeltas(INT32 dx, INT32 dy, UINT8 ssplayer);
diff --git a/src/m_menu.c b/src/m_menu.c
index 7c67cf2da2342464a548c7b37d77a1d896c64403..461a0855237aacbd59f7975cbd4a6b070a1b553a 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -12969,7 +12969,7 @@ static void M_ChangeControlResponse(event_t *ev)
 				setupcontrols[control][1] = KEY_NULL;  //replace key 1,clear key2
 			}
 
-			G_CheckDoubleUsage(ch, true);
+			G_CheckDoubleUsage(ch, true, setupcontrols_secondaryplayer ? 2 : 1);
 			setupcontrols[control][found] = ch;
 		}