From 67b9d6683fd3070d248185e660f7717317a6be04 Mon Sep 17 00:00:00 2001 From: WHC Date: Thu, 29 Oct 2026 19:15:01 +0800 Subject: [PATCH] fix: keep stream write-head on tip glyph, not next-line col0 (0.9.29) Appending the scanning caret after trailing newlines parked a lonely block at the left margin. Overlay the tip character instead and let the decode crest sweep through the wake. Co-authored-by: Cursor --- include/cst_version.h | 2 +- src/tui.c | 60 +++++++++++++++++++++---------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/include/cst_version.h b/include/cst_version.h index a52ac89..810239e 100644 --- a/include/cst_version.h +++ b/include/cst_version.h @@ -3,7 +3,7 @@ #define CST_VERSION_MAJOR 0 #define CST_VERSION_MINOR 9 -#define CST_VERSION_PATCH 28 +#define CST_VERSION_PATCH 29 #define CST_VERSION_STR_(x) #x #define CST_VERSION_STR(x) CST_VERSION_STR_(x) diff --git a/src/tui.c b/src/tui.c index da5305d..b887eb1 100644 --- a/src/tui.c +++ b/src/tui.c @@ -1051,8 +1051,8 @@ static char *glitch_stream_frontier(const char *src, int spin) { const int ncaret = g_ascii ? (int)(sizeof(asc_caret) / sizeof(asc_caret[0])) : (int)(sizeof(uni_caret) / sizeof(uni_caret[0])); - /* Traveling decode head — a soft sine along the wake. */ - int wave = spin % (nv + 8); + /* Traveling decode crest — sweeps from older wake toward the tip. */ + int wave = (spin * 2) % (nv + 6); size_t o = 0; size_t cursor = 0; @@ -1065,62 +1065,62 @@ static char *glitch_stream_frontier(const char *src, int spin) { int age = nv - 1 - v; /* 0 = newest (tip) */ unsigned h = glitch_mix((unsigned)spin * 131u + (unsigned)v * 17u + (unsigned)st * 3u); - int on_wave = (age >= wave - 1 && age <= wave + 2); + int on_wave = (age >= wave - 2 && age <= wave + 1); - if (age <= 2) { - /* Plasma tip: bright cyan decode glyphs. */ + if (age == 0) { + /* Write head sits ON the tip glyph (never appended after a newline, + * which would park a lonely block at column 0 of the next row). */ + o = glitch_put(out, o, "\033[1;96m"); + o = glitch_put(out, o, caret[(unsigned)spin % (unsigned)ncaret]); + o = glitch_put(out, o, "\033[22;39m"); + } else if (age <= 3) { + /* Plasma just behind the head. */ const char *g = plasma[(h + (unsigned)spin) % (unsigned)nplasma]; o = glitch_put(out, o, "\033[1;96m"); o = glitch_put(out, o, g); o = glitch_put(out, o, "\033[22;39m"); - } else if (age <= 16) { - /* Wake: mostly ghosting the real glyph; braid with phosphor on the - * wave crest so it reads as a decode sweep, not TV static. */ - int dens = 18 - age; /* 15..2 */ - int hit = on_wave || (int)(h % 18) < dens / 2; - if (hit && (spin + v) % 3 != 0) { + } else if (age <= 18) { + /* Wake: ghost real text; crest braids phosphor as it sweeps. */ + int dens = 20 - age; + int hit = on_wave || (int)(h % 16) < dens / 3; + if (on_wave) { const char *g = wake[h % (unsigned)nwake]; - o = glitch_put(out, o, on_wave ? "\033[96m" : "\033[2;36m"); + o = glitch_put(out, o, "\033[1;96m"); o = glitch_put(out, o, g); o = glitch_put(out, o, "\033[22;39m"); - } else if (age <= 6 && (spin + age) % 4 == 0) { - /* Brief bright reveal of the true char — locking in. */ + } else if (hit && (spin + v) % 4 != 0) { + const char *g = wake[h % (unsigned)nwake]; + o = glitch_put(out, o, "\033[2;36m"); + o = glitch_put(out, o, g); + o = glitch_put(out, o, "\033[22;39m"); + } else if (age <= 8 && (spin + age) % 5 == 0) { o = glitch_put(out, o, "\033[1;97m"); memcpy(out + o, src + st, lens[v]); o += lens[v]; o = glitch_put(out, o, "\033[22;39m"); } else { - /* Dim true glyph — readable under the wake. */ o = glitch_put(out, o, "\033[2m"); memcpy(out + o, src + st, lens[v]); o += lens[v]; o = glitch_put(out, o, "\033[22m"); } - } else if (age <= 20) { - /* Lock flash: settle with a one-beat bright pulse. */ - if ((spin + age) % 5 == 0) { - o = glitch_put(out, o, "\033[1m"); - memcpy(out + o, src + st, lens[v]); - o += lens[v]; - o = glitch_put(out, o, "\033[22m"); - } else { - memcpy(out + o, src + st, lens[v]); - o += lens[v]; - } + } else if (age <= 22 && (spin + age) % 6 == 0) { + o = glitch_put(out, o, "\033[1m"); + memcpy(out + o, src + st, lens[v]); + o += lens[v]; + o = glitch_put(out, o, "\033[22m"); } else { memcpy(out + o, src + st, lens[v]); o += lens[v]; } cursor = st + lens[v]; } + /* Trailing newlines / SGR after the last glyph stay as-is — caret already + * sits on the tip character above, so it tracks the text, not col 0. */ if (cursor < n) { memcpy(out + o, src + cursor, n - cursor); o += n - cursor; } - /* Scanning caret past the tip — the "write head". */ - o = glitch_put(out, o, "\033[1;96m"); - o = glitch_put(out, o, caret[(unsigned)spin % (unsigned)ncaret]); - o = glitch_put(out, o, "\033[22;39m"); out[o] = 0; return out; }