From 9e7d5f6e5e01b7473b84bc3449d7f8e0f78e7045 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 18 Jul 2026 20:41:27 +0200 Subject: term: 7-color terminal (per-glyph fg+bg) + ANSI escapes; colorize irc Fano-plane palette scheme: the 7 colors map onto 7 CGB BG palettes so any color pair shares one palette; a tile's palette is picked from the set of colors its two cells need (tables generated by tools/gencolor.py). Per cell a packed (bg<<4)|fg byte lives alongside the char shadow, and the glyph blitter steers glyph/empty pixels to each cell's fg/bg color slots via plane masks. An ANSI-ish CSI parser (ESC [ .. m) drives it; usr/ansi.c demos it and the irc client now renders hashed nick colors, status dimming and a channel-activity bar. --- usr/ansi.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 usr/ansi.c (limited to 'usr/ansi.c') diff --git a/usr/ansi.c b/usr/ansi.c new file mode 100644 index 0000000..0e73ff8 --- /dev/null +++ b/usr/ansi.c @@ -0,0 +1,67 @@ +#include "gbos.h" +/* ansi - show the terminal's 7-color ANSI support. Also stress-tests per-glyph + * coloring: adjacent characters (which share an 8x8 tile) get different colors. + * + * NB: no initialized statics / pointer arrays here - SDCC would place them in + * the _INITIALIZED area at $A000 (the RAM window), overflowing the 16K image. */ + +static void sgr(unsigned char n) { /* emit ESC [ n m */ + putc(27); + putc('['); + putu(n); + putc('m'); +} + +void main(void) { + unsigned char i, c; + const char *s; + + puts("ANSI 7-color test"); nl(); + + /* each color name printed in its own color (31..37) */ + sgr(31); puts("red "); + sgr(32); puts("green "); + sgr(33); puts("yellow "); + sgr(34); puts("blue "); + sgr(35); puts("magenta "); + sgr(36); puts("cyan "); + sgr(37); puts("white"); + sgr(0); nl(); + + /* per-glyph stress: 40 bars, color changes every single character, so the + * left/right halves of one tile differ - impossible with a per-tile palette */ + c = 31; + for (i = 0; i < 40; i++) { + sgr(c); + putc('#'); + if (++c > 37) c = 31; + } + sgr(0); nl(); + + /* one word, one color per letter */ + c = 31; + s = "RAINBOW!"; + for (i = 0; s[i]; i++) { + sgr(c); + putc(s[i]); + if (++c > 37) c = 31; + } + sgr(0); nl(); + + /* background colors: a block of each (SGR 41..47), default white text */ + puts("backgrounds:"); nl(); + c = 41; + for (i = 0; i < 7; i++) { + putc(27); putc('['); putc('4'); putc((char)('0' + (c - 40))); putc('m'); + puts(" bg "); + if (++c > 47) c = 41; + } + sgr(0); nl(); + + /* foreground-on-background combos (one CSI carries both: ESC[fg;bg m) */ + puts("\033[37;41m wht/red \033[33;44m yel/blu \033[34;43m blu/yel " + "\033[32;45m grn/mag \033[36;41m cyn/red \033[0m"); nl(); + + /* per-glyph fg over a shared bg: adjacent letters differ, bg stays green */ + puts("\033[42m\033[31mR\033[33mA\033[34mI\033[35mN\033[37mBOW\033[0m"); nl(); +} -- cgit v1.3.1-sl0p