diff options
| author | gbc dev <gbc@localhost> | 2026-07-04 23:07:50 +0200 |
|---|---|---|
| committer | gbc dev <gbc@localhost> | 2026-07-04 23:07:50 +0200 |
| commit | f4ba890eb4b98e1a65a3d9fc8ba8f62dda66895b (patch) | |
| tree | cb1cccb2dfd0f1b59e59e8e86454849179c88cb2 /src/render.c | |
| parent | input: external control channel via FIFO (diff) | |
| download | sl0pboy-f4ba890eb4b98e1a65a3d9fc8ba8f62dda66895b.tar.gz sl0pboy-f4ba890eb4b98e1a65a3d9fc8ba8f62dda66895b.tar.xz sl0pboy-f4ba890eb4b98e1a65a3d9fc8ba8f62dda66895b.zip | |
speed control: frame skipping to decouple terminal draw from emulation
Emulation always runs at native rate (correct game speed); --frameskip N draws
only 1 of every N+1 frames so a slow terminal no longer bottlenecks the loop.
Adds --fps cap, --uncapped/--turbo, live [ ] and f keys, HUD readout, and an
exit summary of emulated-vs-drawn fps. Replaces the confusing --render-fps.
Diffstat (limited to 'src/render.c')
| -rw-r--r-- | src/render.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/src/render.c b/src/render.c index f659da3..df39c99 100644 --- a/src/render.c +++ b/src/render.c @@ -51,8 +51,19 @@ static char outbuf[SCREEN_W * (SCREEN_H/2) * 40 + 4096]; static u8 prev_fb[SCREEN_H][SCREEN_W][3]; static bool need_full = true; // force a complete repaint static volatile sig_atomic_t resized = 0; // set by SIGWINCH +static int hud_frameskip = 0; +static bool hud_turbo = false; void render_force_full(void) { need_full = true; } + +// Update the on-screen HUD values; forces a status-line repaint on change. +void render_set_hud(int frameskip, bool turbo) { + if (frameskip != hud_frameskip || turbo != hud_turbo) { + hud_frameskip = frameskip; + hud_turbo = turbo; + need_full = true; + } +} static void on_winch(int s) { (void)s; resized = 1; } void render_frame(GB *gb) { @@ -99,8 +110,9 @@ void render_frame(GB *gb) { // status line: static text, only (re)draw on a full repaint if (need_full) { o += sprintf(o, "\x1b[0m\x1b[%d;1H\x1b[38;2;150;150;150m %.*s " - "[wasd/arrows] z:A x:B space:sel enter:start q:quit", - SCREEN_H/2 + 1, 15, gb->cart.title); + "skip:%d%s [f]ast [ ][ ] q:quit\x1b[K", + SCREEN_H/2 + 1, 12, gb->cart.title, + hud_frameskip, hud_turbo ? " TURBO" : ""); } memcpy(prev_fb, p->fb, sizeof(prev_fb)); @@ -119,8 +131,18 @@ void render_frame(GB *gb) { // decay[] : momentary presses (keyboard, or FIFO taps), count down per frame static int decay[8]; // frames remaining for each BTN bit position static u8 held; // explicitly-held buttons (FIFO) +static int turbo_toggles; // pending fast-forward toggles (consumed by main) +static int frameskip_delta;// pending frameskip adjustment (consumed by main) #define HOLD_FRAMES 4 +bool input_take_turbo(void) { + if (turbo_toggles > 0) { turbo_toggles--; return true; } + return false; +} +int input_take_frameskip_delta(void) { + int d = frameskip_delta; frameskip_delta = 0; return d; +} + static int mask_index(int mask) { for (int i = 0; i < 8; i++) if ((1 << i) == mask) return i; return -1; @@ -226,6 +248,9 @@ bool input_poll(GB *gb) { case 'x': case 'k': tap(BTN_B, HOLD_FRAMES); break; case '\r': case '\n': tap(BTN_START, HOLD_FRAMES); break; case ' ': tap(BTN_SELECT, HOLD_FRAMES); break; + case 'f': turbo_toggles++; break; // toggle fast-forward + case '[': frameskip_delta--; break; // fewer skipped frames + case ']': frameskip_delta++; break; // more skipped frames case 'q': case 3: quit = true; break; } } |
