diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 17 |
1 files changed, 17 insertions, 0 deletions
@@ -9,6 +9,7 @@ #include <signal.h> #include <fcntl.h> #include <unistd.h> +#include <termios.h> static volatile sig_atomic_t running = 1; static void on_sig(int s) { (void)s; running = 0; } @@ -100,6 +101,21 @@ int main(int argc, char **argv) { if (fl != -1) fcntl(STDIN_FILENO, F_SETFL, fl | O_NONBLOCK); signal(SIGINT, on_sig); signal(SIGTERM, on_sig); + // Interactive: if stdin is a terminal, drop line-buffering + local echo + // so keystrokes reach the guest immediately and only the guest echoes. + // (Piped/redirected stdin is left alone, for scripted input.) + struct termios saved_tio; + bool raw_tty = isatty(STDIN_FILENO) && tcgetattr(STDIN_FILENO, &saved_tio) == 0; + if (raw_tty) { + struct termios t = saved_tio; + t.c_lflag &= ~(ICANON | ECHO); // char-at-a-time, no echo (keep ISIG) + // VMIN=1 (not 0): with O_NONBLOCK, "no data" is EAGAIN, not a 0-byte + // read that we'd otherwise misread as EOF. + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; + tcsetattr(STDIN_FILENO, TCSANOW, &t); + fprintf(stderr, "[gbc: interactive serial console - Ctrl-C to quit]\n"); + } bool uncapped = (target_fps <= 0); double start_t = now_sec(); u64 start_cyc = gb->cycles; @@ -118,6 +134,7 @@ int main(int argc, char **argv) { } } } + if (raw_tty) tcsetattr(STDIN_FILENO, TCSANOW, &saved_tio); cart_free(&gb->cart); free(gb); return 0; } |
