diff options
| author | Kirill Petrashin <kirill8201@yandex.ru> | 2026-06-22 18:11:53 +0300 |
|---|---|---|
| committer | Kirill Petrashin <kirill8201@yandex.ru> | 2026-06-22 18:11:53 +0300 |
| commit | 4d871b697295f892c76b2204ca50ad513d508788 (patch) | |
| tree | 6f221561f4ab2c043895bee3d1f93af330572479 /framebuffer.c | |
| parent | 769abee99e0fcf27c7700dc57e48e51ca50ccbc2 (diff) | |
| download | wafflestone-4d871b697295f892c76b2204ca50ad513d508788.tar.xz | |
Optimize fb_print()
Diffstat (limited to 'framebuffer.c')
| -rw-r--r-- | framebuffer.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/framebuffer.c b/framebuffer.c index 36969e0..b4c2f6e 100644 --- a/framebuffer.c +++ b/framebuffer.c @@ -3,8 +3,10 @@ #include <termios.h> #include <unistd.h> #include <sys/ioctl.h> +#include <string.h> #include "framebuffer.h" +#include "uint8toa.h" size_t term_width = 0, term_height = 0; @@ -29,20 +31,29 @@ Framebuffer fb_new(size_t width, size_t height) { } } + fb.print_buf = malloc(42 * width * height); + if (fb.print_buf == NULL) { + /* FIXME: see above */ + fb.fb = NULL; + return fb; + } + fb.width = width; fb.height = height; return fb; } void fb_free(Framebuffer *fb) { - if (fb->fb == NULL) goto ret; - - for (size_t i = 0; i < fb->height; i++) { - free(fb->fb[i]); + if (fb->fb != NULL) { + for (size_t i = 0; i < fb->height; i++) { + free(fb->fb[i]); + } + free(fb->fb); } - free(fb->fb); -ret: + if (fb->print_buf != NULL) + free(fb->print_buf); + fb->width = 0; fb->height = 0; return; @@ -108,24 +119,46 @@ void term_update_size(void) { #endif } +/* Converts pixel to ascii and puts it in buf, used in fb_print(). + * This is faster than sprinf(). + * TODO: maybe less memcpy()s will be better? */ +static inline void pixel_to_ascii(char *buf, Pixel p) { + memcpy(buf, "\x1b[38;2;XXX;XXX;XXXm\x1b[48;2;XXX;XXX;XXXmXXXX", 42); + memcpy(buf + 7, uint8toa[p.fg.r], 3); + memcpy(buf + 11, uint8toa[p.fg.g], 3); + memcpy(buf + 15, uint8toa[p.fg.b], 3); + memcpy(buf + 26, uint8toa[p.bg.r], 3); + memcpy(buf + 30, uint8toa[p.bg.g], 3); + memcpy(buf + 34, uint8toa[p.bg.b], 3); + memcpy(buf + 38, &p.ch, 4); +} + void fb_print(Framebuffer fb) { + /* TODO: move this to buffer, maybe? to avoid an extra write every 'frame' */ write(STDOUT_FILENO, "\x1b[H", 3); /* Move cursor to top-left */ + /* 'cursor' of print_buf, used to build it */ + char *cur = fb.print_buf; + + /* build the buffer */ for (size_t row = 0; row < fb.height; row++) { for (size_t col = 0; col < fb.width; col++) { - set_fg(fb.fb[row][col].fg); - set_bg(fb.fb[row][col].bg); - write(STDOUT_FILENO, &(fb.fb[row][col].ch), sizeof(wchar_t)); + pixel_to_ascii(cur, fb.fb[row][col]); + cur += 42; } } - fflush(stdout); + + /* flush the buffer */ + write(STDOUT_FILENO, fb.print_buf, 42 * fb.width * fb.height); } +__attribute__((unused)) static inline void set_fg(Colour col) { fprintf(stdout, "\x1b[38;2;%u;%u;%um", col.r, col.g, col.g); fflush(stdout); } +__attribute__((unused)) static inline void set_bg(Colour col) { fprintf(stdout, "\x1b[48;2;%u;%u;%um", col.r, col.g, col.g); fflush(stdout); |
