aboutsummaryrefslogtreecommitdiffstats
path: root/src/display_text.c
diff options
context:
space:
mode:
authorClyne Sullivan <tullivan99@gmail.com>2018-04-19 13:14:39 -0400
committerClyne Sullivan <tullivan99@gmail.com>2018-04-19 13:14:39 -0400
commit5df5c67397e2800182e5016ab89bbd17e4e67a5b (patch)
tree2df26f9b2de074d716aa5b192abac6f5952fa42d /src/display_text.c
parent1a11ab00d898c4484bc0f518a1d53b1f4cbf5fb4 (diff)
better text managment
Diffstat (limited to 'src/display_text.c')
-rw-r--r--src/display_text.c168
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;
+}