diff --git a/src/console.c b/src/console.c
index cdb1fc196cc79c2552ca7b23232e01688d36f305..01b90ebc39474a547e5666e8e714fa826b032570 100644
--- a/src/console.c
+++ b/src/console.c
@@ -937,7 +937,7 @@ boolean CON_Responder(event_t *ev)
 		return false;
 
 	// let go keyup events, don't eat them
-	if (ev->type != ev_keydown && ev->type != ev_text && ev->type != ev_console)
+	if (ev->type != ev_keydown && ev->type != ev_console)
 	{
 		if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1])
 			consdown = false;
@@ -964,7 +964,7 @@ boolean CON_Responder(event_t *ev)
 		// check other keys only if console prompt is active
 		if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!!
 		{
-			if (ev->type == ev_keydown && !menuactive && bindtable[key])
+			if (! menuactive && bindtable[key])
 			{
 				COM_BufAddText(bindtable[key]);
 				COM_BufAddText("\n");
@@ -981,12 +981,6 @@ boolean CON_Responder(event_t *ev)
 		}
 	}
 
-	if (ev->type == ev_text)
-	{
-		CON_InputAddChar(key);
-		return true;
-	}
-
 	// Always eat ctrl/shift/alt if console open, so the menu doesn't get ideas
 	if (key == KEY_LSHIFT || key == KEY_RSHIFT
 	 || key == KEY_LCTRL || key == KEY_RCTRL
@@ -1301,12 +1295,21 @@ boolean CON_Responder(event_t *ev)
 	else if (key == KEY_KPADSLASH)
 		key = '/';
 
+	if (key >= 'a' && key <= 'z')
+	{
+		if (capslock ^ shiftdown)
+			key = shiftxform[key];
+	}
+	else if (shiftdown)
+		key = shiftxform[key];
+
 	// enter a char into the command prompt
 	if (key < 32 || key > 127)
 		return true;
 
 	if (input_sel != input_cur)
 		CON_InputDelSelection();
+	CON_InputAddChar(key);
 
 	return true;
 }
diff --git a/src/d_event.h b/src/d_event.h
index 7743d860947c8b5e2546f2df6a80cc3bdb9679a7..5aa4350600b85a2aafc5a59b87081492a134e048 100644
--- a/src/d_event.h
+++ b/src/d_event.h
@@ -22,7 +22,6 @@ typedef enum
 {
 	ev_keydown,
 	ev_keyup,
-	ev_text,
 	ev_console,
 	ev_mouse,
 	ev_joystick,
diff --git a/src/d_main.c b/src/d_main.c
index bc821cf71f19982ba725b9ee6a7b198baf8fcf75..274e4ceb366511fe9b9e9d77a792b51f4f51bbba 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -192,19 +192,19 @@ void D_ProcessEvents(void)
 		ev = &events[eventtail];
 
 		// Set mouse buttons early in case event is eaten later
-		if (ev->type == ev_keydown || ev->type == ev_keyup || ev->type == ev_text)
+		if (ev->type == ev_keydown || ev->type == ev_keyup)
 		{
 			// Mouse buttons
 			if ((UINT32)(ev->key - KEY_MOUSE1) < MOUSEBUTTONS)
 			{
-				if (ev->type == ev_keydown || ev->type == ev_text)
+				if (ev->type == ev_keydown)
 					mouse.buttons |= 1 << (ev->key - KEY_MOUSE1);
 				else
 					mouse.buttons &= ~(1 << (ev->key - KEY_MOUSE1));
 			}
 			else if ((UINT32)(ev->key - KEY_2MOUSE1) < MOUSEBUTTONS)
 			{
-				if (ev->type == ev_keydown || ev->type == ev_text)
+				if (ev->type == ev_keydown)
 					mouse2.buttons |= 1 << (ev->key - KEY_2MOUSE1);
 				else
 					mouse2.buttons &= ~(1 << (ev->key - KEY_2MOUSE1));
diff --git a/src/hu_stuff.c b/src/hu_stuff.c
index 0a2b71aeceed9e20e4f18da5b422dfd943ff1cc5..6178298d2e7220d1070e3e1563a76086dc2dde12 100644
--- a/src/hu_stuff.c
+++ b/src/hu_stuff.c
@@ -79,7 +79,6 @@ patch_t *nto_font[NT_FONTSIZE];
 
 static player_t *plr;
 boolean chat_on; // entering a chat message?
-boolean chat_on_first_event; // blocker for first chat input event
 static char w_chat[HU_MAXMSGLEN + 1];
 static size_t c_input = 0; // let's try to make the chat input less shitty.
 static boolean headsupactive = false;
@@ -1040,7 +1039,7 @@ boolean HU_Responder(event_t *ev)
 {
 	INT32 c=0;
 
-	if (ev->type != ev_keydown && ev->type != ev_text)
+	if (ev->type != ev_keydown)
 		return false;
 
 	// only KeyDown events now...
@@ -1069,15 +1068,11 @@ boolean HU_Responder(event_t *ev)
 
 	if (!chat_on)
 	{
-		if (ev->type == ev_text)
-			return false;
-
 		// enter chat mode
 		if ((ev->key == gamecontrol[GC_TALKKEY][0] || ev->key == gamecontrol[GC_TALKKEY][1])
 			&& netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise.
 		{
 			chat_on = true;
-			chat_on_first_event = false;
 			w_chat[0] = 0;
 			teamtalk = false;
 			chat_scrollmedown = true;
@@ -1088,7 +1083,6 @@ boolean HU_Responder(event_t *ev)
 			&& netgame && !OLD_MUTE)
 		{
 			chat_on = true;
-			chat_on_first_event = false;
 			w_chat[0] = 0;
 			teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams.
 			chat_scrollmedown = true;
@@ -1098,31 +1092,6 @@ boolean HU_Responder(event_t *ev)
 	}
 	else // if chat_on
 	{
-		if (!chat_on_first_event)
-		{
-			// since the text event is sent immediately after the keydown event,
-			// we need to make sure that nothing is displayed once the chat
-			// opens, otherwise a 't' would be outputted.
-			chat_on_first_event = true;
-			return true;
-		}
-
-		if (ev->type == ev_text)
-		{
-			if ((c < HU_FONTSTART || c > HU_FONTEND || !hu_font[c-HU_FONTSTART])
-				&& c != ' ') // Allow spaces, of course
-			{
-				return false;
-			}
-
-			if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN)
-				return true;
-
-			memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1);
-			w_chat[c_input] = c;
-			c_input++;
-			return true;
-		}
 
 		// Ignore modifier keys
 		// Note that we do this here so users can still set
@@ -1132,8 +1101,23 @@ boolean HU_Responder(event_t *ev)
 		 || ev->key == KEY_LALT || ev->key == KEY_RALT)
 			return true;
 
+		c = (INT32)ev->key;
+
+		// I know this looks very messy but this works. If it ain't broke, don't fix it!
+		// shift LETTERS to uppercase if we have capslock or are holding shift
+		if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
+		{
+			if (shiftdown ^ capslock)
+				c = shiftxform[c];
+		}
+		else // if we're holding shift we should still shift non letter symbols
+		{
+			if (shiftdown)
+				c = shiftxform[c];
+		}
+
 		// pasting. pasting is cool. chat is a bit limited, though :(
-		if (c == 'v' && ctrldown)
+		if ((c == 'v' || c == 'V') && ctrldown)
 		{
 			const char *paste;
 			size_t chatlen;
@@ -1201,6 +1185,16 @@ boolean HU_Responder(event_t *ev)
 			else
 				c_input++;
 		}
+		else if ((c >= HU_FONTSTART && c <= HU_FONTEND && hu_font[c-HU_FONTSTART])
+			|| c == ' ') // Allow spaces, of course
+		{
+			if (CHAT_MUTE || strlen(w_chat) >= HU_MAXMSGLEN)
+				return true;
+
+			memmove(&w_chat[c_input + 1], &w_chat[c_input], strlen(w_chat) - c_input + 1);
+			w_chat[c_input] = c;
+			c_input++;
+		}
 		else if (c == KEY_BACKSPACE)
 		{
 			if (CHAT_MUTE || c_input <= 0)
diff --git a/src/m_menu.c b/src/m_menu.c
index 9aae59445382270c6d45445dfb113425fe52eee6..72d4547b08d8aedc6c0f75e65538bf0b4a322968 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -3177,42 +3177,40 @@ boolean M_Responder(event_t *ev)
 	}
 	else if (menuactive)
 	{
-		if (ev->type == ev_keydown || ev->type == ev_text)
+		if (ev->type == ev_keydown)
 		{
+			keydown++;
 			ch = ev->key;
-			if (ev->type == ev_keydown)
+
+			// added 5-2-98 remap virtual keys (mouse & joystick buttons)
+			switch (ch)
 			{
-				keydown++;
-				// added 5-2-98 remap virtual keys (mouse & joystick buttons)
-				switch (ch)
-				{
-					case KEY_MOUSE1:
-					case KEY_JOY1:
-						ch = KEY_ENTER;
-						break;
-					case KEY_JOY1 + 3:
-						ch = 'n';
-						break;
-					case KEY_MOUSE1 + 1:
-					case KEY_JOY1 + 1:
-						ch = KEY_ESCAPE;
-						break;
-					case KEY_JOY1 + 2:
-						ch = KEY_BACKSPACE;
-						break;
-					case KEY_HAT1:
-						ch = KEY_UPARROW;
-						break;
-					case KEY_HAT1 + 1:
-						ch = KEY_DOWNARROW;
-						break;
-					case KEY_HAT1 + 2:
-						ch = KEY_LEFTARROW;
-						break;
-					case KEY_HAT1 + 3:
-						ch = KEY_RIGHTARROW;
-						break;
-				}
+				case KEY_MOUSE1:
+				case KEY_JOY1:
+					ch = KEY_ENTER;
+					break;
+				case KEY_JOY1 + 3:
+					ch = 'n';
+					break;
+				case KEY_MOUSE1 + 1:
+				case KEY_JOY1 + 1:
+					ch = KEY_ESCAPE;
+					break;
+				case KEY_JOY1 + 2:
+					ch = KEY_BACKSPACE;
+					break;
+				case KEY_HAT1:
+					ch = KEY_UPARROW;
+					break;
+				case KEY_HAT1 + 1:
+					ch = KEY_DOWNARROW;
+					break;
+				case KEY_HAT1 + 2:
+					ch = KEY_LEFTARROW;
+					break;
+				case KEY_HAT1 + 3:
+					ch = KEY_RIGHTARROW;
+					break;
 			}
 		}
 		else if (ev->type == ev_joystick  && ev->key == 0 && joywait < I_GetTime())
@@ -3374,11 +3372,8 @@ boolean M_Responder(event_t *ev)
 	// Handle menuitems which need a specific key handling
 	if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER)
 	{
-		// ignore ev_keydown events if the key maps to a character, since
-		// the ev_text event will follow immediately after in that case.
-		if (ev->type == ev_keydown && ch >= 32 && ch <= 127)
-			return true;
-
+		if (shiftdown && ch >= 32 && ch <= 127)
+			ch = shiftxform[ch];
 		routine(ch);
 		return true;
 	}
@@ -3420,11 +3415,6 @@ boolean M_Responder(event_t *ev)
 	{
 		if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
 		{
-			// ignore ev_keydown events if the key maps to a character, since
-			// the ev_text event will follow immediately after in that case.
-			if (ev->type == ev_keydown && ch >= 32 && ch <= 127)
-				return false;
-
 			if (M_ChangeStringCvar(ch))
 				return true;
 			else
diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c
index 847806270f78175624fd2fabcdcf32a0b9e0e29e..986647e72e0abae98508b3635c57b48325252505 100644
--- a/src/sdl/i_system.c
+++ b/src/sdl/i_system.c
@@ -652,7 +652,6 @@ void I_GetConsoleEvents(void)
 	else if (tty_con.cursor < sizeof (tty_con.buffer))
 	{
 		// push regular character
-		ev.type = ev_text;
 		ev.key = tty_con.buffer[tty_con.cursor] = key;
 		tty_con.cursor++;
 		// print the current line (this is differential)
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index d3a602c05803fcd5d6aced670321aad5c723ea74..a70e5a86029c22edb8ce4488ecde31f64ff0181d 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -693,19 +693,6 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type)
 	if (event.key) D_PostEvent(&event);
 }
 
-static void Impl_HandleTextEvent(SDL_TextInputEvent evt)
-{
-	event_t event;
-	event.type = ev_text;
-	if (evt.text[1] != '\0')
-	{
-		// limit ourselves to ASCII for now, we can add UTF-8 support later
-		return;
-	}
-	event.key = evt.text[0];
-	D_PostEvent(&event);
-}
-
 static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
 {
 	static boolean firstmove = true;
@@ -954,9 +941,6 @@ void I_GetEvent(void)
 			case SDL_KEYDOWN:
 				Impl_HandleKeyboardEvent(evt.key, evt.type);
 				break;
-			case SDL_TEXTINPUT:
-				Impl_HandleTextEvent(evt.text);
-				break;
 			case SDL_MOUSEMOTION:
 				//if (!mouseMotionOnce)
 				Impl_HandleMouseMotionEvent(evt.motion);