AnimByte is a C++ engine for terminal-based frame rendering using pure ASCII characters. Flat buffer model, delta-only writes, ANSI cursor reposition — no external dependencies.
A single heap-allocated char[] of width × height bytes.
Every cell maps to one ASCII character. No structs, no colors, no metadata — just characters.
Set_Char only pushes a cell to the dirty list when its value actually changes.
Frame_Clean resets only those cells — untouched cells cost zero work.
Render_Frame writes \033[H to jump the cursor back to (0,0)
then writes the full frame string in one write() syscall — no flicker, no clear.
Every character is a single byte from the 7-bit ASCII table (0–127). No UTF-8 multibyte sequences, no Unicode, no wide chars — rendering width is always predictable.
// main loop pattern AnimByte engine; engine.Initialise(80, 24); while (running) { engine.Frame_Clean(); // reset only dirty cells // write your frame data engine.Set_Char(row, col, ch); // O(1) per cell engine.Render_Frame(); // one write() syscall usleep(16000); // ~60 fps cap }
| Method | Parameters | Description |
|---|---|---|
|
Initialise
→ int
|
int width, int height
Allocates the flat buffer and fills it with spaces. Must be called before any other method. Returns 0.
|
|
|
Set_Char
→ int
|
int row, int col, char ch
Writes one ASCII character at the given 1-indexed position. Returns -1 if out-of-bounds or value unchanged (no dirty push). Otherwise 0.
|
|
|
Render_Frame
→ int
|
none
Builds the full frame string from the buffer, repositions the cursor with
\033[H, and flushes everything in one write() to stdout. Returns -1 if frame is empty. |
|
|
Frame_Clean
→ int
|
none
Iterates only the dirty list and sets each cell back to
' '. Cost is O(d) where d is the number of changed cells — not O(width × height). |
0 // success -1 // out-of-bounds, no-op (value already set), or empty frame // -1 is not a fatal error — callers may safely ignore it
// sine wave across the terminal AnimByte engine; engine.Initialise(80, 24); double t = 0.0; while (running) { engine.Frame_Clean(); for (int col = 1; col <= 80; col++) { int row = (int)(12 + 10 * sin(col * 0.15 + t)); engine.Set_Char(row, col, '*'); } engine.Render_Frame(); t += 0.1; usleep(16000); }
// bouncing ball with simple physics AnimByte engine; engine.Initialise(80, 24); double x=40, y=12, vx=0.8, vy=0.4; while (running) { engine.Frame_Clean(); x += vx; y += vy; if (x <= 1 || x >= 80) vx = -vx; if (y <= 1 || y >= 24) vy = -vy; engine.Set_Char((int)y, (int)x, 'O'); engine.Render_Frame(); usleep(8000); }
// falling column rain — pure ASCII chars only AnimByte engine; engine.Initialise(80, 40); int heads[80] = {0}; int speeds[80]; for (int i=0; i<80; i++) speeds[i] = rand()%3+1; while (running) { engine.Frame_Clean(); for (int col=0; col<80; col++) { char ch = '!' + rand() % 94; // ASCII 33–126 engine.Set_Char(heads[col] % 40 + 1, col+1, ch); heads[col] += speeds[col]; } engine.Render_Frame(); usleep(40000); }
// ASCII progress bar AnimByte engine; engine.Initialise(60, 5); for (int p=0; p<=50; p++) { engine.Frame_Clean(); engine.Set_Char(2, 1, '['); engine.Set_Char(2, 52, ']'); for (int i=0; i<p; i++) engine.Set_Char(2, i+2, '='); if (p < 50) engine.Set_Char(2, p+2, '>'); engine.Render_Frame(); usleep(40000); }
// draw a box border with ASCII line chars void draw_box(AnimByte& e, int r1, int c1, int r2, int c2) { e.Set_Char(r1, c1, '+'); e.Set_Char(r1, c2, '+'); e.Set_Char(r2, c1, '+'); e.Set_Char(r2, c2, '+'); for (int c=c1+1; c<c2; c++) { e.Set_Char(r1, c, '-'); e.Set_Char(r2, c, '-'); } for (int r=r1+1; r<r2; r++) { e.Set_Char(r, c1, '|'); e.Set_Char(r, c2, '|'); } } AnimByte engine; engine.Initialise(80, 24); draw_box(engine, 2, 2, 22, 78); engine.Render_Frame();
Snake, Tetris, Pong, Breakout — any grid-based game maps directly to the char buffer. Input via raw terminal mode.
CPU per-core bars, memory usage, network I/O — rendered live at high refresh using ASCII bar chars.
FFT bins mapped to column heights. Each frame updates only the bars that changed — delta rendering keeps it fast.
Game of Life, Langton's Ant, rule-based 1D automata — each cell is one char, each generation is one frame.
Map distance field samples to brightness chars: . : ; + * # @. Render 3D scenes entirely in ASCII.
Live packet counts, latency histograms, connection maps — a full TUI dashboard without ncurses.
Spawn, move, and expire particles. Each particle is a char. The dirty list ensures only active particles are cleared.
CI/CD runner with animated progress bars and stage indicators rendered directly to the terminal output.
Plot real-time sensor or stdin data as scrolling waveforms — replace graphing tools for embedded debugging.