diff --git a/src/console.c b/src/console.c
index a51ff61f7c6033af6d5f3ab2773eb4deebb2cce4..d3e637b82b77797b797bcf5c4353f61ac29f302e 100644
--- a/src/console.c
+++ b/src/console.c
@@ -173,6 +173,14 @@ static void CONS_Clear_f(void)
 	con_scrollup = 0;
 }
 
+// Choose english keymap
+//
+/*static void CONS_English_f(void)
+{
+	shiftxform = english_shiftxform;
+	CONS_Printf(M_GetText("%s keymap.\n"), M_GetText("English"));
+}*/
+
 static char *bindtable[NUMINPUTS];
 
 static void CONS_Bind_f(void)
@@ -1070,6 +1078,30 @@ boolean CON_Responder(event_t *ev)
 		return true;
 	}
 
+	// allow people to use keypad in console (good for typing IP addresses) - Calum
+	if (!cv_textinput.value)
+	{
+		if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL)
+		{
+			char keypad_translation[] = {'7','8','9','-',
+										 '4','5','6','+',
+										 '1','2','3',
+										 '0','.'};
+
+			key = keypad_translation[key - KEY_KEYPAD7];
+		}
+		else if (key == KEY_KPADSLASH)
+			key = '/';
+
+		if (key >= 'a' && key <= 'z')
+		{
+			if (capslock ^ shiftdown)
+				key = shiftxform[key];
+		}
+		else if (shiftdown)
+			key = shiftxform[key];
+	}
+
 	// Lactozilla: Ignore caps lock key
 	// or else it turns into a printable character
 	if (ev->type != ev_textinput && key == KEY_CAPSLOCK)
@@ -1079,6 +1111,11 @@ boolean CON_Responder(event_t *ev)
 	if (key < 32 || key > 0xFF)
 		return true;
 
+	// add key to cmd line here
+	if (!cv_textinput.value)
+		if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers
+			key = key + 'a' - 'A';
+
 	if (input_sel != input_cur)
 		CON_InputDelSelection();
 	CON_InputAddChar(key);
diff --git a/src/hu_stuff.c b/src/hu_stuff.c
index 73872716bf77634c41c962f5c9dfc96285200e3b..e65ebe0773bef4eb07f2d3f7a3772a4dd9ee23ef 100644
--- a/src/hu_stuff.c
+++ b/src/hu_stuff.c
@@ -115,6 +115,53 @@ static void HU_DrawRankings(void);
 static void HU_DrawCoopOverlay(void);
 static void HU_DrawNetplayCoopOverlay(void);
 
+//======================================================================
+//                 KEYBOARD LAYOUTS FOR ENTERING TEXT
+//======================================================================
+
+char *shiftxform;
+
+char english_shiftxform[] =
+{
+	0,
+	1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+	11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+	21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+	31,
+	' ', '!', '"', '#', '$', '%', '&',
+	'"', // shift-'
+	'(', ')', '*', '+',
+	'<', // shift-,
+	'_', // shift--
+	'>', // shift-.
+	'?', // shift-/
+	')', // shift-0
+	'!', // shift-1
+	'@', // shift-2
+	'#', // shift-3
+	'$', // shift-4
+	'%', // shift-5
+	'^', // shift-6
+	'&', // shift-7
+	'*', // shift-8
+	'(', // shift-9
+	':',
+	':', // shift-;
+	'<',
+	'+', // shift-=
+	'>', '?', '@',
+	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+	'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+	'{', // shift-[
+	'|', // shift-backslash - OH MY GOD DOES WATCOM SUCK
+	'}', // shift-]
+	'"', '_',
+	'~', // shift-`
+	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+	'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+	'{', '|', '}', '~', 127
+};
+
 static char cechotext[1024];
 static tic_t cechotimer = 0;
 static tic_t cechoduration = 5*TICRATE;
@@ -286,6 +333,9 @@ void HU_Init(void)
 	RegisterNetXCmd(XD_SAY, Got_Saycmd);
 #endif
 
+	// set shift translation table
+	shiftxform = english_shiftxform;
+
 	HU_LoadGraphics();
 }
 
diff --git a/src/hu_stuff.h b/src/hu_stuff.h
index e8b7280bd90da73d614608dd7bb8955358e48a0f..cfb64e912c58bbb87ca55daafdcbb10552b4c0e8 100644
--- a/src/hu_stuff.h
+++ b/src/hu_stuff.h
@@ -48,6 +48,9 @@
 
 #define HU_CROSSHAIRS 3 // maximum of 9 - see HU_Init();
 
+extern char *shiftxform; // english translation shift table
+extern char english_shiftxform[];
+
 //------------------------------------
 //        sorted player lines
 //------------------------------------
diff --git a/src/m_menu.c b/src/m_menu.c
index e4eeff3aa5c16d8dd24ba636bff6478069eeef20..f8e2069d65dcc590e861ded0aa77b5ab4ced8506 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -2879,6 +2879,10 @@ static boolean M_ChangeStringCvar(INT32 choice)
 	char buf[MAXSTRINGLENGTH];
 	size_t len;
 
+	if (!cv_textinput.value)
+		if (shiftdown && choice >= 32 && choice <= 127)
+			choice = shiftxform[choice];
+
 	switch (choice)
 	{
 		case KEY_BACKSPACE:
@@ -6215,6 +6219,9 @@ static void M_AddonExec(INT32 ch)
 #define len menusearch[0]
 static boolean M_ChangeStringAddons(INT32 choice)
 {
+	if (!cv_textinput.value)
+		choice = shiftxform[choice];
+
 	switch (choice)
 	{
 		case KEY_DEL: