diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2018-04-19 13:14:39 -0400 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2018-04-19 13:14:39 -0400 |
commit | 5df5c67397e2800182e5016ab89bbd17e4e67a5b (patch) | |
tree | 2df26f9b2de074d716aa5b192abac6f5952fa42d /src/display_text.c | |
parent | 1a11ab00d898c4484bc0f518a1d53b1f4cbf5fb4 (diff) |
better text managment
Diffstat (limited to 'src/display_text.c')
-rw-r--r-- | src/display_text.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/display_text.c b/src/display_text.c new file mode 100644 index 0000000..8a41fa5 --- /dev/null +++ b/src/display_text.c @@ -0,0 +1,168 @@ + +#include <clock.h> +#include <task.h> +#include <display_draw.h> +#include <heap.h> +#include <string.h> + +#define WIDTH 40 +#define HEIGHT 18 + +#define TTY_COUNT 2 + +typedef struct { + char *buf; + uint8_t x; + uint8_t y; +} tty_t; + +static tty_t text_tty[TTY_COUNT]; +static tty_t *text_current; +static uint8_t text_cursor; + +void task_cursor(void) +{ + while (1) { + delay(300); + if (text_cursor == 0) + continue; + + int x = text_current->x * C_WIDTH; + int y = text_current->y * C_HEIGHT; + dsp_rect(x, y + C_HEIGHT - 1, C_WIDTH, 1, 0xFFFF); + delay(300); + dsp_rect(x, y + C_HEIGHT - 1, C_WIDTH, 1, 0); + } +} + +void text_init(void) +{ + for (int i = 0; i < TTY_COUNT; i++) { + text_tty[i].buf = calloc(WIDTH * HEIGHT, sizeof(char)); + text_tty[i].x = 0; + text_tty[i].y = 0; + } + + text_current = &text_tty[0]; + + text_cursor = 1; + task_start(task_cursor, 512); +} + +void text_redraw(void) +{ + for (unsigned int i = 0; i < WIDTH; i++) { + //unsigned int zc = 0; + for (unsigned int j = 0; j < HEIGHT; j++) { + int c = text_current->buf[i + j * WIDTH]; + /*if (c == '\0') { + if (++zc == 3) + break; + } else if (zc > 0) { + zc = 0; + }*/ + + dsp_putchar(c, i, j); + } + } +} + +void text_switch(unsigned int i) +{ + if (i >= TTY_COUNT) + return; + + text_current = &text_tty[i]; + text_redraw(); +} + +void text_clear(void) +{ + for (unsigned int i = 0; i < WIDTH; i++) { + for (unsigned int j = 0; j < HEIGHT; j++) { + text_current->buf[i + j * WIDTH] = 0; + dsp_putchar(' ', i, j); + } + } + text_current->x = 0; + text_current->y = 0; +} + +void text_putchar(int c) +{ + uint8_t x = text_current->x; + uint8_t y = text_current->y; + + switch (c) { + case '\n': + y++; + // fall_through + case '\r': + x = 0; + break; + case '\t': + for (unsigned int i = 0; i < 4; i++) + dsp_putchar(' ', x++, y); + break; + case '\b': + x--; + dsp_putchar(' ', x, y); + break; + default: + dsp_putchar(c, x, y); + text_current->buf[x + y * WIDTH] = c; + x++; + break; + } + + if (x >= WIDTH) { + x = 0; + y++; + } + + if (y >= HEIGHT) { + // clear + for (int i = 1; i < HEIGHT; i++) { + memcpy(text_current->buf + (i - 1) * WIDTH, + text_current->buf + i * WIDTH, WIDTH); + } + x = 0; + y = HEIGHT - 1; + for (int i = 0; i < WIDTH; i++) + text_current->buf[i + y * WIDTH] = 0; + + text_redraw(); + } + + text_current->x = x; + text_current->y = y; +} + +void text_puts(const char *s) +{ + unsigned int i = 0; + while (s[i]) + text_putchar(s[i++]); +} + +void text_setpos(uint8_t x, uint8_t y) +{ + if (x >= WIDTH) + x = WIDTH - 1; + if (y >= HEIGHT) + y = HEIGHT - 1; + text_current->x = x; + text_current->y = y; +} + +void text_relpos(int8_t x, int8_t y) +{ + if ((int)(text_current->x + x) < 0) + text_current->x = 0; + else + text_current->x += x; + if ((int)(text_current->y + y) < 0) + text_current->y = 0; + else + text_current->y += y; +} |