nshell/src/term.c

182 lines
4.3 KiB
C
Raw Permalink Normal View History

2021-08-31 15:52:53 +02:00
#include "term.h"
#include <gint/display.h>
2021-09-10 23:12:01 +02:00
#include <gint/rtc.h>
#include <ctype.h>
2021-09-12 20:34:21 +02:00
#include <printf.h>
2021-09-08 23:36:18 +02:00
#include <stdarg.h>
2021-09-01 13:33:21 +02:00
#include <string.h>
2021-08-31 15:52:53 +02:00
#include "utf8.h"
2021-08-31 15:52:53 +02:00
extern font_t uf5x7;
struct tcell {
char chr[4];
int fg;
int bg;
};
static struct tcell tgrid[UNS_TERM_ROWS][UNS_TERM_COLS];
static void tgrid_set(int row, int col, int fg, int bg, char c[4]) {
tgrid[row][col].chr[0] = c[0];
tgrid[row][col].chr[1] = c[1];
tgrid[row][col].chr[2] = c[2];
tgrid[row][col].chr[3] = c[3];
tgrid[row][col].fg = fg;
tgrid[row][col].bg = bg;
}
static int tgrid_sets(int *row, int *col, int fg, int bg, const char *s) {
int i = 0;
while (s[i] != '\0') {
2021-08-31 15:52:53 +02:00
// boundary check
if (*row >= UNS_TERM_ROWS)
return i;
if (*col >= UNS_TERM_COLS)
return i;
2021-08-31 15:52:53 +02:00
int charlen = charlen_utf8(s[i]);
2021-08-31 15:52:53 +02:00
char unichar[4];
int j;
for (j = 0; j < charlen; j++)
2021-08-31 15:52:53 +02:00
unichar[j] = s[i + j];
for (; j < 4; j++)
unichar[j] = '\0';
2021-08-31 15:52:53 +02:00
i += charlen;
2021-09-01 13:33:21 +02:00
const int char_is_newline = (strncmp(unichar, "\n", 4) == 0);
2021-09-01 13:33:21 +02:00
if (char_is_newline) {
// clear line end
for (; *col < UNS_TERM_COLS; *col = *col + 1)
tgrid_set(*row, *col, C_WHITE, C_BLACK, " \0\0");
2021-09-01 13:33:21 +02:00
} else {
tgrid_set(*row, *col, fg, bg, unichar);
*col = *col + 1;
2021-09-01 13:33:21 +02:00
}
2021-08-31 15:52:53 +02:00
}
return i;
2021-08-31 15:52:53 +02:00
}
int term_writeat(int row, int col, int fg, int bg, const char *s) { return tgrid_sets(&row, &col, fg, bg, s); }
2021-08-31 15:52:53 +02:00
void tgrid_display(void) {
dfont(&uf5x7);
int y = 3;
for (int row = 0; row < UNS_TERM_ROWS; row++) {
int x = 2;
for (int col = 0; col < UNS_TERM_COLS; col++) {
2021-08-31 16:21:50 +02:00
const struct tcell cell = tgrid[row][col];
2021-08-31 15:52:53 +02:00
2021-08-31 16:23:09 +02:00
// unpack unicode
2021-08-31 15:52:53 +02:00
char buf[5];
buf[0] = cell.chr[0];
buf[1] = cell.chr[1];
buf[2] = cell.chr[2];
buf[3] = cell.chr[3];
2021-08-31 16:23:09 +02:00
buf[4] = '\0';
2021-08-31 15:52:53 +02:00
drect(x - 1, y - 1, x + 6, y + 8, cell.bg);
dtext_opt(x, y, cell.fg, C_NONE, DTEXT_LEFT, DTEXT_TOP, (char *)&buf, -1);
x += 1 + 5;
}
y += 1 + 7 + 2;
}
2021-09-01 14:24:10 +02:00
}
void term_scroll_down(void) {
// clear last line
for (int i = 0; i < UNS_TERM_COLS; i++) {
tgrid[UNS_TERM_ROWS - 1][i].chr[0] = ' ';
tgrid[UNS_TERM_ROWS - 1][i].chr[1] = '\0';
tgrid[UNS_TERM_ROWS - 1][i].chr[2] = '\0';
tgrid[UNS_TERM_ROWS - 1][i].chr[3] = '\0';
tgrid[UNS_TERM_ROWS - 1][i].fg = C_WHITE;
tgrid[UNS_TERM_ROWS - 1][i].bg = C_BLACK;
}
for (int i = 1; i < UNS_TERM_ROWS - 1; i++) {
2021-09-01 14:24:10 +02:00
memcpy(tgrid[i], tgrid[i + 1], UNS_TERM_COLS * sizeof(struct tcell));
}
}
2021-09-10 21:43:19 +02:00
static int term_print_opt(const char *str, int fg, int bg) {
static int row = 1;
static int col = 0;
int i = 0;
while (str[i] != '\0') {
// handle cursor overflow (column)
if (col >= UNS_TERM_COLS) {
col = 0;
row++;
}
// handle cursor overflow (row)
if (row >= UNS_TERM_ROWS - 1) {
term_scroll_down();
row = UNS_TERM_ROWS - 2;
}
2021-09-09 23:43:50 +02:00
i += tgrid_sets(&row, &col, fg, bg, str + i);
}
2021-09-09 22:09:33 +02:00
return i;
}
2021-09-09 23:43:50 +02:00
int term_print(const char *str) { return term_print_opt(str, C_WHITE, C_BLACK); }
2021-09-08 22:15:46 +02:00
int term_printf(const char *restrict format, ...) {
va_list argp;
2021-09-08 23:36:18 +02:00
va_start(argp, format);
2021-09-12 21:47:50 +02:00
char buf[256];
2021-09-12 20:34:21 +02:00
const int n = vsnprintf(buf, sizeof(buf), format, argp);
2021-09-09 22:09:33 +02:00
term_print(buf);
2021-09-08 23:36:18 +02:00
2021-09-09 23:43:50 +02:00
va_end(argp);
return n;
}
2021-09-10 23:12:01 +02:00
int term_eprint(const char *str) { return term_print_opt(str, C_RED, C_BLACK); }
2021-09-09 23:43:50 +02:00
int term_eprintf(const char *restrict format, ...) {
va_list argp;
va_start(argp, format);
2021-09-12 21:47:50 +02:00
char buf[256];
2021-09-12 20:34:21 +02:00
const int n = vsnprintf(buf, sizeof(buf), format, argp);
2021-09-09 23:43:50 +02:00
term_eprint(buf);
2021-09-10 23:12:01 +02:00
va_end(argp);
return n;
}
int term_kprint(const char *str) {
int t = rtc_ticks();
2021-09-12 23:14:21 +02:00
char kstr[256];
2021-09-12 21:47:50 +02:00
sprintf(kstr, "[%5d.%03d] %s\n", t / 128, (t % 128) * 100 / 128, str);
2021-09-10 23:12:01 +02:00
const int ret = term_print_opt(kstr, C_RED | C_GREEN, C_BLACK);
return ret;
}
int term_kprintf(const char *restrict format, ...) {
va_list argp;
va_start(argp, format);
2021-09-12 21:47:50 +02:00
char buf[256];
2021-09-12 20:34:21 +02:00
const int n = vsnprintf(buf, sizeof(buf), format, argp);
2021-09-10 23:12:01 +02:00
term_kprint(buf);
2021-09-08 23:36:18 +02:00
va_end(argp);
2021-09-08 22:15:46 +02:00
return n;
2021-08-31 15:52:53 +02:00
}