From 0d598150b34829ed957962f1c893a03ee00dca81 Mon Sep 17 00:00:00 2001 From: Hanicef Date: Tue, 20 Feb 2024 21:43:45 +0100 Subject: [PATCH] Fix insane TTY input latency --- src/dedicated/i_system.c | 79 +++++++++++++++++++++++----------------- src/sdl/i_system.c | 79 +++++++++++++++++++++++----------------- 2 files changed, 90 insertions(+), 68 deletions(-) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index 4dbaec8df..13d5d1700 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -96,6 +96,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__)) +#include #include #include #define NEWSIGNALHANDLER @@ -855,50 +856,60 @@ static void I_GetConsoleEvents(void) // we use this when sending back commands event_t ev = {0}; char key = 0; - ssize_t d; + struct pollfd pfd = + { + .fd = STDIN_FILENO, + .events = POLLIN, + .revents = 0, + }; if (!consolevent) return; - ev.type = ev_console; - ev.key = 0; - if (read(STDIN_FILENO, &key, 1) == -1 || !key) - return; + for (;;) + { + if (poll(&pfd, 1, 0) < 1 || !(pfd.revents & POLLIN)) + return; - // we have something - // backspace? - // NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere - if ((key == tty_erase) || (key == 127) || (key == 8)) - { - if (tty_con.cursor > 0) + ev.type = ev_console; + ev.key = 0; + if (read(STDIN_FILENO, &key, 1) == -1 || !key) + return; + + // we have something + // backspace? + // NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere + if ((key == tty_erase) || (key == 127) || (key == 8)) { - tty_con.cursor--; - tty_con.buffer[tty_con.cursor] = '\0'; - tty_Back(); + if (tty_con.cursor > 0) + { + tty_con.cursor--; + tty_con.buffer[tty_con.cursor] = '\0'; + tty_Back(); + } + ev.key = KEY_BACKSPACE; } - ev.key = KEY_BACKSPACE; - } - else if (key < ' ') // check if this is a control char - { - if (key == '\n') + else if (key < ' ') // check if this is a control char { - tty_Clear(); - tty_con.cursor = 0; - ev.key = KEY_ENTER; + if (key == '\n') + { + tty_Clear(); + tty_con.cursor = 0; + ev.key = KEY_ENTER; + } + else continue; } - else return; + else if (tty_con.cursor < sizeof(tty_con.buffer)) + { + // push regular character + ev.key = tty_con.buffer[tty_con.cursor] = key; + tty_con.cursor++; + // print the current line (this is differential) + write(STDOUT_FILENO, &key, 1); + } + if (ev.key) D_PostEvent(&ev); + //tty_FlushIn(); } - else if (tty_con.cursor < sizeof(tty_con.buffer)) - { - // push regular character - ev.key = tty_con.buffer[tty_con.cursor] = key; - tty_con.cursor++; - // print the current line (this is differential) - d = write(STDOUT_FILENO, &key, 1); - } - if (ev.key) D_PostEvent(&ev); - //tty_FlushIn(); - (void)d; } #elif defined (_WIN32) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index f03ea6226..5509f8cab 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -109,6 +109,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__)) +#include #include #include #define NEWSIGNALHANDLER @@ -616,50 +617,60 @@ void I_GetConsoleEvents(void) // we use this when sending back commands event_t ev = {0}; char key = 0; - ssize_t d; + struct pollfd pfd = + { + .fd = STDIN_FILENO, + .events = POLLIN, + .revents = 0, + }; if (!consolevent) return; - ev.type = ev_console; - ev.key = 0; - if (read(STDIN_FILENO, &key, 1) == -1 || !key) - return; + for (;;) + { + if (poll(&pfd, 1, 0) < 1 || !(pfd.revents & POLLIN)) + return; - // we have something - // backspace? - // NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere - if ((key == tty_erase) || (key == 127) || (key == 8)) - { - if (tty_con.cursor > 0) + ev.type = ev_console; + ev.key = 0; + if (read(STDIN_FILENO, &key, 1) == -1 || !key) + return; + + // we have something + // backspace? + // NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere + if ((key == tty_erase) || (key == 127) || (key == 8)) { - tty_con.cursor--; - tty_con.buffer[tty_con.cursor] = '\0'; - tty_Back(); + if (tty_con.cursor > 0) + { + tty_con.cursor--; + tty_con.buffer[tty_con.cursor] = '\0'; + tty_Back(); + } + ev.key = KEY_BACKSPACE; } - ev.key = KEY_BACKSPACE; - } - else if (key < ' ') // check if this is a control char - { - if (key == '\n') + else if (key < ' ') // check if this is a control char { - tty_Clear(); - tty_con.cursor = 0; - ev.key = KEY_ENTER; + if (key == '\n') + { + tty_Clear(); + tty_con.cursor = 0; + ev.key = KEY_ENTER; + } + else continue; } - else return; + else if (tty_con.cursor < sizeof (tty_con.buffer)) + { + // push regular character + ev.key = tty_con.buffer[tty_con.cursor] = key; + tty_con.cursor++; + // print the current line (this is differential) + write(STDOUT_FILENO, &key, 1); + } + if (ev.key) D_PostEvent(&ev); + //tty_FlushIn(); } - else if (tty_con.cursor < sizeof (tty_con.buffer)) - { - // push regular character - ev.key = tty_con.buffer[tty_con.cursor] = key; - tty_con.cursor++; - // print the current line (this is differential) - d = write(STDOUT_FILENO, &key, 1); - } - if (ev.key) D_PostEvent(&ev); - //tty_FlushIn(); - (void)d; } #elif defined (_WIN32)