Fumofumotris/source/fumoengine/terminal/terminal.c

141 lines
2.6 KiB
C
Raw Normal View History

2024-05-07 03:29:10 +00:00
#include "terminal.h"
2024-05-07 22:10:15 +00:00
#include <string.h>
2024-05-07 03:29:10 +00:00
#define RESET_STR_LEN 7
#define MAX_CH4_LEN 11
2024-05-15 22:10:47 +00:00
usize TerminalMaxOut(usize wid, usize hgt)
2024-05-07 03:29:10 +00:00
{
return RESET_STR_LEN
2024-05-15 22:10:47 +00:00
+ MAX_CH4_LEN * wid * hgt
+ hgt
2024-05-07 03:29:10 +00:00
+ 1;
}
bool CreateTerminal(struct Terminal *term, usize wid, usize hgt)
{
struct Char4 *ch4s = calloc(wid * hgt, sizeof(struct Char4));
if (ch4s == nullptr)
return false;
2024-05-15 22:10:47 +00:00
char *str = malloc(TerminalMaxOut(wid, hgt));
if (str == nullptr)
return false;
2024-05-07 03:29:10 +00:00
*term = (struct Terminal) {
2024-05-15 22:10:47 +00:00
.buf = ch4s,
.str = str,
2024-05-07 03:29:10 +00:00
2024-05-15 22:10:47 +00:00
.wid = wid,
.hgt = hgt
2024-05-07 03:29:10 +00:00
};
return true;
}
void FreeTerminal(struct Terminal *term)
{
2024-05-07 22:10:15 +00:00
free(term->buf);
2024-05-07 03:29:10 +00:00
}
2024-05-07 22:10:15 +00:00
usize u8_to_str(char *out, u8f x)
2024-05-07 03:29:10 +00:00
{
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;
2024-05-07 22:10:15 +00:00
out[0] = hnds + 48;
out[1] = tens + 48;
out[2] = ones + 48;
2024-05-07 03:29:10 +00:00
} else {
len = 2;
2024-05-07 22:10:15 +00:00
out[0] = tens + 48;
out[1] = ones + 48;
2024-05-07 03:29:10 +00:00
}
} else {
2024-05-07 22:10:15 +00:00
out[0] = x + 48;
2024-05-07 03:29:10 +00:00
}
return len;
}
u8f ansi_bg(u8f bg)
{
return bg + (bg < 8 ? 40 : 92);
}
u8f ansi_fg(u8f fg)
{
return fg + (fg < 8 ? 30 : 82);
}
2024-05-07 22:10:15 +00:00
usize ch4_dif_to_str(char *out, struct Color4 *dif, struct Char4 *ch4)
2024-05-07 03:29:10 +00:00
{
usize len = 0;
if (dif->bg != ch4->color.bg) {
2024-05-07 22:10:15 +00:00
out[len++] = '\x1b';
out[len++] = '[';
len += u8_to_str(out + len, ansi_bg(ch4->color.bg));
2024-05-07 03:29:10 +00:00
if (dif->fg != ch4->color.fg) {
2024-05-07 22:10:15 +00:00
out[len++] = ';';
len += u8_to_str(out + len, ansi_fg(ch4->color.fg));
2024-05-07 03:29:10 +00:00
}
2024-05-07 22:10:15 +00:00
out[len++] = 'm';
2024-05-07 03:29:10 +00:00
} else if (dif->fg != ch4->color.fg) {
2024-05-07 22:10:15 +00:00
out[len++] = '\x1b';
out[len++] = '[';
len += u8_to_str(out + len, ansi_fg(ch4->color.fg));
out[len++] = 'm';
2024-05-07 03:29:10 +00:00
}
2024-05-07 22:10:15 +00:00
out[len++] = ch4->ch;
2024-05-07 03:29:10 +00:00
*dif = ch4->color;
return len;
}
2024-05-15 22:10:47 +00:00
usize TerminalPrint(struct Terminal *term)
2024-05-07 03:29:10 +00:00
{
2024-05-07 22:10:15 +00:00
struct Color4 dif = { 0, 0 };
2024-05-07 03:29:10 +00:00
usize len = 7;
2024-05-15 22:10:47 +00:00
memcpy(term->str, "\x1b[H\x1b[0m", 7);
2024-05-07 03:29:10 +00:00
2024-05-19 06:56:14 +00:00
struct Char4 *ch4 = term->buf;
2024-05-07 03:29:10 +00:00
for (usize y = 0; y < term->hgt; y++) {
2024-05-19 06:56:14 +00:00
for (usize x = 0; x < term->wid; x++, ch4++) {
2024-05-07 03:29:10 +00:00
// DEBUG
if (ch4->ch == 0)
ch4->ch = '#';
// DEBUG
2024-05-15 22:10:47 +00:00
len += ch4_dif_to_str(term->str + len, &dif, ch4);
2024-05-07 03:29:10 +00:00
}
2024-05-15 22:10:47 +00:00
term->str[len++] = '\n';
2024-05-07 03:29:10 +00:00
}
2024-05-15 22:10:47 +00:00
term->str[len] = 0;
2024-05-07 03:29:10 +00:00
return len;
2024-05-19 06:56:14 +00:00
}
struct Char4 *TerminalGet(struct Terminal *term, usize x, usize y)
{
return term->buf + term->wid * y + x;
2024-05-07 03:29:10 +00:00
}