Fumofumotris/source/fumoengine/terminal/terminal.c

133 lines
2.4 KiB
C
Raw Normal View History

2024-05-07 03:29:10 +00:00
#include "terminal.h"
#define RESET_STR_LEN 7
#define MAX_CH4_LEN 11
usize TerminalStringSize(usize wid, usize hgt)
{
return RESET_STR_LEN
+ MAX_CH4_LEN * wid * hgt
+ hgt
+ 1;
}
bool CreateTerminal(struct Terminal *term, usize wid, usize hgt)
{
struct Char4 *ch4s = calloc(wid * hgt, sizeof(struct Char4));
if (ch4s == nullptr)
return false;
*term = (struct Terminal) {
.wid = wid,
.hgt = hgt,
.ch4s = ch4s
};
return true;
}
void FreeTerminal(struct Terminal *term)
{
free(term->ch4s);
}
usize u8_to_buf(char *buf, u8f x)
{
usize len = 1;
if (x > 9) {
u8f ones, tens;
ones = x % 10;
tens = x / 10;
if (x > 99) {
u8f hnds;
tens %= 10;
hnds = tens / 10;
len = 3;
buf[0] = hnds + 48;
buf[1] = tens + 48;
buf[2] = ones + 48;
} else {
len = 2;
buf[0] = tens + 48;
buf[1] = ones + 48;
}
} else {
buf[0] = x + 48;
}
return len;
}
u8f ansi_bg(u8f bg)
{
return bg + (bg < 8 ? 40 : 92);
}
u8f ansi_fg(u8f fg)
{
return fg + (fg < 8 ? 30 : 82);
}
usize ch4_dif_to_buf(char *buf, struct Color4 *dif, struct Char4 *ch4)
{
usize len = 0;
if (dif->bg != ch4->color.bg) {
buf[len++] = '\x1b';
buf[len++] = '[';
len += u8_to_buf(buf + len, ansi_bg(ch4->color.bg));
if (dif->fg != ch4->color.fg) {
buf[len++] = ';';
len += u8_to_buf(buf + len, ansi_fg(ch4->color.fg));
}
buf[len++] = 'm';
} else if (dif->fg != ch4->color.fg) {
buf[len++] = '\x1b';
buf[len++] = '[';
len += u8_to_buf(buf + len, ansi_fg(ch4->color.fg));
buf[len++] = 'm';
}
buf[len++] = ch4->ch;
*dif = ch4->color;
return len;
}
usize TerminalPrint(char *buf, usize n, struct Terminal *term)
{
struct Char4 dif;
usize len = 7;
memcpy(buf, "\x1b[H\x1b[0m", 7);
for (usize y = 0; y < term->hgt; y++) {
for (usize x = 0; x < term->wid; x++) {
usize i = y * term->wid + x;
struct Char4 *ch4 = &term->ch4s[i];
// DEBUG
if (ch4->ch == 0)
ch4->ch = '#';
// DEBUG
len += ch4_dif_to_buf(buf + len, &dif, ch4);
}
buf[len++] = '\n';
}
buf[len] = 0;
return len;
}