From 95d7a486eeb37d3feef16fd29892c62cf966d01d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= <gustaf@hanicef.me> Date: Sat, 25 Mar 2023 16:26:31 +0100 Subject: [PATCH 1/5] Implement support for native keyboard layout --- src/console.c | 19 ++++++++----------- src/d_event.h | 1 + src/d_main.c | 6 +++--- src/hu_stuff.c | 45 ++++++++++++++++++++++++++++++++------------- src/sdl/i_video.c | 16 ++++++++++++++++ 5 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/console.c b/src/console.c index 33d59046e..2a48ad80b 100644 --- a/src/console.c +++ b/src/console.c @@ -924,7 +924,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_console) + if (ev->type != ev_keydown && ev->type != ev_text && ev->type != ev_console) { if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1]) consdown = false; @@ -951,7 +951,7 @@ boolean CON_Responder(event_t *ev) // check other keys only if console prompt is active if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! { - if (! menuactive && bindtable[key]) + if (!menuactive && bindtable[key]) { COM_BufAddText(bindtable[key]); COM_BufAddText("\n"); @@ -968,6 +968,12 @@ 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 @@ -1304,21 +1310,12 @@ 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 5aa435060..7743d8609 100644 --- a/src/d_event.h +++ b/src/d_event.h @@ -22,6 +22,7 @@ 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 32f16a282..d660b732e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -190,19 +190,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) + if (ev->type == ev_keydown || ev->type == ev_keyup || ev->type == ev_text) { // Mouse buttons if ((UINT32)(ev->key - KEY_MOUSE1) < MOUSEBUTTONS) { - if (ev->type == ev_keydown) + if (ev->type == ev_keydown || ev->type == ev_text) 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) + if (ev->type == ev_keydown || ev->type == ev_text) 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 23c63e98f..04d1642a1 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -77,6 +77,7 @@ 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; @@ -1047,7 +1048,7 @@ boolean HU_Responder(event_t *ev) INT32 c=0; #endif - if (ev->type != ev_keydown) + if (ev->type != ev_keydown && ev->type != ev_text) return false; // only KeyDown events now... @@ -1077,11 +1078,15 @@ 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; @@ -1092,6 +1097,7 @@ 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; @@ -1101,6 +1107,31 @@ 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 @@ -1110,8 +1141,6 @@ 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')) @@ -1194,16 +1223,6 @@ 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/sdl/i_video.c b/src/sdl/i_video.c index d2fbb9006..c25de5fd3 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -686,6 +686,19 @@ 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; @@ -934,6 +947,9 @@ 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); From 6896080f4fdca25a764516c66692d52dd8c9063c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= <gustaf@hanicef.me> Date: Sat, 25 Mar 2023 23:08:13 +0100 Subject: [PATCH 2/5] fixup! Implement support for native keyboard layout --- src/hu_stuff.c | 15 +--------- src/m_menu.c | 76 ++++++++++++++++++++++++++++---------------------- 2 files changed, 44 insertions(+), 47 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 04d1642a1..a5268f821 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1141,21 +1141,8 @@ boolean HU_Responder(event_t *ev) || ev->key == KEY_LALT || ev->key == KEY_RALT) return true; - // 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' || c == 'V') && ctrldown) + if (c == 'v' && ctrldown) { const char *paste; size_t chatlen; diff --git a/src/m_menu.c b/src/m_menu.c index e879e9c14..71e47bc69 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3230,40 +3230,42 @@ boolean M_Responder(event_t *ev) } else if (menuactive) { - if (ev->type == ev_keydown) + if (ev->type == ev_keydown || ev->type == ev_text) { - keydown++; ch = ev->key; - - // added 5-2-98 remap virtual keys (mouse & joystick buttons) - switch (ch) + if (ev->type == ev_keydown) { - 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; + 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; + } } } else if (ev->type == ev_joystick && ev->key == 0 && joywait < I_GetTime()) @@ -3425,8 +3427,11 @@ boolean M_Responder(event_t *ev) // Handle menuitems which need a specific key handling if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER) { - if (shiftdown && ch >= 32 && ch <= 127) - ch = shiftxform[ch]; + // 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; + routine(ch); return true; } @@ -3468,6 +3473,11 @@ 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 From b8f8cc145104d41298585a2c5c84abee7211ade7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= <gustaf@hanicef.me> Date: Wed, 29 Mar 2023 18:58:18 +0200 Subject: [PATCH 3/5] fixup! fixup! Implement support for native keyboard layout --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index 2a48ad80b..5571f6bb9 100644 --- a/src/console.c +++ b/src/console.c @@ -951,7 +951,7 @@ boolean CON_Responder(event_t *ev) // check other keys only if console prompt is active if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! { - if (!menuactive && bindtable[key]) + if (ev->type == ev_keydown && !menuactive && bindtable[key]) { COM_BufAddText(bindtable[key]); COM_BufAddText("\n"); From afe8432c1e5e0fcf40cb5fee9e1e4593352821b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= <gustaf@hanicef.me> Date: Tue, 23 May 2023 17:41:10 +0200 Subject: [PATCH 4/5] fixup! fixup! fixup! Implement support for native keyboard layout --- src/sdl/i_system.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index e328bedc2..65f16f0bd 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -601,6 +601,7 @@ void I_GetConsoleEvents(void) else { // 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) From 5deee87bd293430a201e2ced5748d07791c18a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= <gustaf@hanicef.me> Date: Sat, 4 Nov 2023 19:12:23 +0100 Subject: [PATCH 5/5] Fix keyhandler menus not blocking in-game movement --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 56d82eed2..68974d61a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3376,7 +3376,7 @@ boolean M_Responder(event_t *ev) // 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; + return true; routine(ch); return true;