summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c132
1 files changed, 85 insertions, 47 deletions
diff --git a/main.c b/main.c
index fa0821d..c3de4f8 100644
--- a/main.c
+++ b/main.c
@@ -15,7 +15,6 @@
/* TODO
*
- * - one fwrite() per blit
* - utf-8 input
* - arrow keys
* - KEY_RESIZE or draw callback
@@ -225,39 +224,78 @@ static inline int bchr_equiv(VuiBuffer *back, VuiBuffer *front, int x, int y) {
/* || BCHR(back,x,y) == ' ' */);
}
+static char vui_out[65536];
+static unsigned short vui_outn = 0;
+
+void vui_outf(const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ int n = vsnprintf(NULL, 0, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ vsprintf(&vui_out[vui_outn], fmt, ap);
+ vui_outn += n;
+ va_end(ap);
+}
+
+static inline void vui_outc(char c) {
+ vui_out[vui_outn++] = c;
+}
+
+static inline void vui_outsn(const char *s, unsigned n) {
+ memcpy(&vui_out[vui_outn], s, n);
+ vui_outn += n;
+}
+
+static inline void vui_outs(const char *s) {
+ vui_outsn(s, strlen(s));
+}
+
+static inline void vui_out_flush(void) {
+ fwrite(vui_out, 1, vui_outn, stdout);
+ fflush(stdout);
+#if 1
+ static unsigned out_frame = 0;
+ FILE *f = fopen("out_log.txt", "a");
+ assert(f);
+ fprintf(f, "\n\n:: OUTPUT FRAME %u ::\n", ++out_frame);
+ fwrite(vui_out, 1, vui_outn, f);
+ fclose(f);
+#endif
+ vui_outn = 0;
+}
+
static inline void curs_move(int src_x, int src_y, int dst_x, int dst_y) {
if (src_x != dst_x && src_y != dst_y) {
if (dst_x > 0) {
- printf("\x1b[%d;%dH", dst_y + 1, dst_x + 1);
+ vui_outf("\x1b[%d;%dH", dst_y + 1, dst_x + 1);
} else {
- printf("\x1b[%dH", dst_y + 1);
+ vui_outf("\x1b[%dH", dst_y + 1);
}
} else if (src_x != dst_x) {
- printf("\x1b[%dG", dst_x + 1);
+ vui_outf("\x1b[%dG", dst_x + 1);
} else if (src_y != dst_y) {
- printf("\x1b[%dd", dst_y + 1);
+ vui_outf("\x1b[%dd", dst_y + 1);
}
}
static void attr_chg(VuiAttr *ptr, VuiAttr to) {
VuiAttr from = *ptr;
if (from == to) return;
- char buf[64] = { 0 };
- char *s = buf;
int chg_attr = (ATTR_A(from) != ATTR_A(to));
chg_attr = 0;
+ /* popcnt(f_attr ^ t_attr) to detect nr. of changes */
+
if (chg_attr) {
- *s++ = '\x1b';
- *s++ = '[';
- *s++ = '0';
- if (to & A_BOLD) *s++ = ';', *s++ = '1';
- if (to & A_DIM) *s++ = ';', *s++ = '1';
- if (to & A_ITALIC) *s++ = ';', *s++ = '3';
- if (to & A_UNDERSCORE) *s++ = ';', *s++ = '4';
- if (to & A_BLINK) *s++ = ';', *s++ = '5';
- if (to & A_REVERSE) *s++ = ';', *s++ = '7';
+ vui_outs("\x1b[0");
+ if (to & A_BOLD) vui_outs(";1");
+ if (to & A_DIM) vui_outs(";2");
+ if (to & A_ITALIC) vui_outs(";3");
+ if (to & A_UNDERSCORE) vui_outs(";4");
+ if (to & A_BLINK) vui_outs(";5");
+ if (to & A_REVERSE) vui_outs(";7");
from = ATTR_DEFAULT;
assert(ATTR_FG(from) == FG_WHITE);
assert(ATTR_BG(from) == BG_BLACK);
@@ -271,35 +309,30 @@ static void attr_chg(VuiAttr *ptr, VuiAttr to) {
int chg_fg = (t_fg != f_fg);
int chg_bg = (t_bg != f_bg);
if (chg_fg || chg_bg) {
- if (chg_attr) *s++ = ';';
- else *s++ = '\x1b', *s++ = '[';
+ if (chg_attr) vui_outc(';');
+ else vui_outs("\x1b[");
if (chg_fg) {
- *s++ = (t_fg > 7 ? '9' : '3');
- *s++ = (t_fg & 7) + '0';
+ vui_outc(t_fg > 7 ? '9' : '3');
+ vui_outc((t_fg & 7) + '0');
}
if (chg_bg) {
- if (chg_fg) *s++ = ';';
+ if (chg_fg) vui_outc(';');
if (t_bg > 7) {
- *s++ = '1';
- *s++ = '0';
+ vui_outs("10");
} else {
- *s++ = '4';
+ vui_outc('4');
}
- *s++ = (t_bg & 7) + '0';
+ vui_outc((t_bg & 7) + '0');
}
}
- if (chg_fg || chg_bg || chg_attr) {
- *s++ = 'm';
- fwrite(buf, 1, s - buf, stdout);
- }
-
+ if (chg_fg || chg_bg || chg_attr) vui_outc('m');
*ptr = to;
}
unsigned vui_changes = 0;
unsigned vui_max_change = 0;
-unsigned vui_repainted = 0;
+unsigned vui_out_chars = 0;
void vui_scroll_buf(VuiBuffer *b, int dx, int dy);
@@ -307,7 +340,7 @@ void vui_blit(void) {
VuiBuffer *front = vui_win.front;
VuiBuffer *back = vui_win.back;
- printf("\x1b[H\x1b[0m");
+ vui_outf("\x1b[H\x1b[0m");
VuiAttr attr_last = ATTR_DEFAULT;
if (vui_win.redraw_all) {
@@ -315,20 +348,17 @@ void vui_blit(void) {
for (unsigned y = 0; y < vui_win.height; y++) {
for (unsigned x = 0; x < vui_win.width; x++) {
attr_chg(&attr_last, ATTR(x, y));
- putchar(CHR(x, y));
+ vui_outc(CHR(x, y));
}
}
- vui_repainted = vui_win.width * vui_win.height;
vui_win.redraw_all = 0;
goto copy_buf;
}
vui_changes = 0;
vui_max_change = 0;
- vui_repainted = 0;
unsigned cur_x = 0, cur_y = 0;
-
/* TODO:
*
* Scroll without repainting whole screen:
@@ -341,28 +371,35 @@ void vui_blit(void) {
*/
if (vui_win.scroll_x || vui_win.scroll_y) {
+ if (abs(vui_win.scroll_x) >= vui_win.width || abs(vui_win.scroll_y) > vui_win.height) {
+ vui_outs("\x1b[2J");
+ goto scrolled;
+ }
+
if (vui_win.scroll_x < 0) {
for (unsigned y = 0; y < vui_win.height; y++) {
curs_move(cur_x, cur_y, 0, y);
- printf("\x1b[%dP", -vui_win.scroll_x);
+ vui_outf("\x1b[%dP", -vui_win.scroll_x);
cur_y = y;
}
} else if (vui_win.scroll_x > 0) {
for (unsigned y = 0; y < vui_win.height; y++) {
curs_move(cur_x, cur_y, 0, y);
- printf("\x1b[%d@", vui_win.scroll_x);
+ vui_outf("\x1b[%d@", vui_win.scroll_x);
cur_y = y;
}
}
if (vui_win.scroll_y < 0) {
curs_move(cur_x, cur_y, 0, 0);
cur_x = (cur_y = 0);
- printf("\x1b[%dM", -vui_win.scroll_y);
+ vui_outf("\x1b[%dM", -vui_win.scroll_y);
} else if (vui_win.scroll_y > 0) {
curs_move(cur_x, cur_y, 0, 0);
cur_x = (cur_y = 0);
- printf("\x1b[%dL", vui_win.scroll_y);
+ vui_outf("\x1b[%dL", vui_win.scroll_y);
}
+
+scrolled:
vui_scroll_buf(back, vui_win.scroll_x, vui_win.scroll_y);
vui_win.scroll_x = 0;
vui_win.scroll_y = 0;
@@ -380,18 +417,17 @@ void vui_blit(void) {
vui_changes++;
curs_move(cur_x, cur_y, x0, y);
attr_chg(&attr_last, a);
- fwrite(&CHR(x0, y), 1, x - x0, stdout);
- //printf("%.*s", x - x0, );
+ vui_outsn(&CHR(x0, y), x - x0);
cur_x = x;
cur_y = y;
- vui_repainted += x - x0;
if (x - x0 > vui_max_change) vui_max_change = x - x0;
}
}
}
copy_buf:
- fflush(stdout);
+ vui_out_chars = vui_outn;
+ vui_out_flush();
memcpy(back->chr, front->chr, sizeof(*back->chr) * (back->width * back->height));
memcpy(back->attr, front->attr, sizeof(*back->attr) * (back->width * back->height));
vui_win.front = back;
@@ -509,15 +545,17 @@ int half_y = 1;
void draw(void *ctx) {
(void)ctx;
+ /*
vui_chra(x, y, C, ((x + y) & 0xf) | BG_BBLUE);
vui_chra(x-1, y, C, ((x + y) & 0xf) | BG_BLUE | A_UNDERSCORE);
vui_chra(x+1, y, C, ((x + y) & 0xf) | BG_BLUE | A_UNDERSCORE);
vui_chra(x, y-1, C, ((x + y) & 0xf) | BG_BLUE | A_UNDERSCORE);
vui_chra(x, y+1, C, ((x + y) & 0xf) | BG_BLUE | A_UNDERSCORE);
+ */
vui_printf(-1, -1, "(%u, %u)", vui_win.width, vui_win.height);
- vui_printf(0, -1, "front buffer = %p", (void*)vui_win.front);
- vui_printf(-1, 0, "longest change = %3u, changes = %5u, repainted%% = %02u%%, chars = %5u", vui_max_change, vui_changes, vui_repainted * 100 / (vui_win.width * vui_win.height), vui_win.width * vui_win.height);
+ //vui_printf(0, -1, "front buffer = %p", (void*)vui_win.front);
+ vui_printf(-1, 0, "longest change = %3u, changes = %5u, output = %5u, chars = %5u", vui_max_change, vui_changes, vui_out_chars, vui_win.width * vui_win.height);
vui_blit();
}
@@ -560,7 +598,7 @@ int main(int argc, const char **argv) {
static int paused = 0;
vui_win.redraw_fn = draw;
-#if 0
+#if 1
/* weird cellular automata */
if (!paused) {
// int dx = 0, dy = 0; /* shadow on purpose */