aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
index f0709c2..648ded2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
}