118 lines
2.1 KiB
C
118 lines
2.1 KiB
C
#include "terminal.h"
|
|
|
|
#define RESET_STR_SIZE 7
|
|
#define COLOR4_MAX_SIZE 10
|
|
|
|
|
|
usize max_out(usize wid, usize hgt)
|
|
{
|
|
return RESET_STR_SIZE
|
|
+ wid * hgt * COLOR4_MAX_SIZE
|
|
+ wid * hgt * UTF8_MAX_SIZE
|
|
+ hgt
|
|
+ 1;
|
|
}
|
|
|
|
void CreateTerminal(Alloc *pool, struct Terminal *term, usize wid, usize hgt)
|
|
{
|
|
term->col4s = pool->alloc(wid * hgt, sizeof(struct Color4));
|
|
term->utf8s = pool->alloc(wid * hgt, UTF8_MAX_SIZE);
|
|
term->out = pool->alloc(wid * hgt, max_out(wid, hgt));
|
|
|
|
if (pool->oom)
|
|
return;
|
|
|
|
term->wid = wid;
|
|
term->hgt = hgt;
|
|
}
|
|
|
|
usize u8_to_str(char *out, u8 x)
|
|
{
|
|
u8 ones = x % 10;
|
|
u8 tens = x / 10;
|
|
u8 hnds = tens / 10;
|
|
tens %= 10;
|
|
|
|
usize len = 0;
|
|
|
|
out[len] = hnds + 48;
|
|
len += (hnds != 0);
|
|
|
|
out[len] = tens + 48;
|
|
len += (hnds | tens) != 0;
|
|
|
|
out[len++] = ones + 48;
|
|
|
|
return len;
|
|
}
|
|
|
|
u8 ansi_bg(u8 bg)
|
|
{
|
|
return bg + (bg < 8 ? 40 : 92);
|
|
}
|
|
|
|
u8 ansi_fg(u8 fg)
|
|
{
|
|
return fg + (fg < 8 ? 30 : 82);
|
|
}
|
|
|
|
usize col4_dif_to_str(char *out, struct Color4 *dif, struct Color4 *col)
|
|
{
|
|
if (*(u8 *)dif == *(u8 *)col)
|
|
return 0;
|
|
|
|
usize len = 0;
|
|
|
|
out[len++] = '\x1b';
|
|
out[len++] = '[';
|
|
|
|
if (dif->bg != col->bg) {
|
|
len += u8_to_str(out + len, ansi_bg(col->bg));
|
|
|
|
if (dif->fg != col->fg) {
|
|
out[len++] += ';';
|
|
len += u8_to_str(out + len, ansi_fg(col->fg));
|
|
}
|
|
} else if (dif->fg != col->fg) {
|
|
len += u8_to_str(out + len, ansi_fg(col->fg));
|
|
}
|
|
|
|
out[len++] = 'm';
|
|
*dif = *col;
|
|
|
|
return len;
|
|
}
|
|
|
|
usize utf8_to_str(char *out, char utf8[4])
|
|
{
|
|
if (utf8[0] == 0)
|
|
utf8[0] = '#';
|
|
|
|
out = utf8;
|
|
return 1 + (utf8[1] != 0) + (utf8[2] != 0) + (utf8[3] != 0);
|
|
}
|
|
|
|
usize TerminalPrint(struct Terminal *term)
|
|
{
|
|
term->out = (char[3]) { '\x1b', '[', 'H' };
|
|
usize len = 3;
|
|
|
|
struct Color4 dif = {0};
|
|
|
|
char (*utf8)[4] = term->utf8s;
|
|
struct Color4 *col4 = term->col4s;
|
|
|
|
for (usize y = 0; y < term->hgt; y++) {
|
|
for (usize x = 0; x < term->wid; x++, utf8++, col4++) {
|
|
len += col4_dif_to_str(term->out + len, &dif, col4);
|
|
len += utf8_to_str(term->out + len, *utf8);
|
|
}
|
|
term->out[len++] = '\n';
|
|
}
|
|
|
|
*(term->out + len) = (char[4]) { '\x1b', '[', '0', 'm' };
|
|
len += 4;
|
|
|
|
term->out[len] = '\0';
|
|
return len;
|
|
} |