aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
parent1a11ab00d898c4484bc0f518a1d53b1f4cbf5fb4 (diff)
better text managment
Diffstat (limited to 'src')
-rw-r--r--src/display_draw.c65
-rw-r--r--src/display_text.c168
-rw-r--r--src/fat32.c23
-rw-r--r--src/main.c10
-rw-r--r--src/script.c59
5 files changed, 234 insertions, 91 deletions
diff --git a/src/display_draw.c b/src/display_draw.c
index 97ee386..ff58c27 100644
--- a/src/display_draw.c
+++ b/src/display_draw.c
@@ -25,44 +25,22 @@
#include <task.h>
#include <clock.h>
-#define C_WIDTH 12
-#define C_HEIGHT 16
-#define S_WIDTH 40
-#define S_HEIGHT 18
-
volatile uint8_t lock = 0;
#define LOCK while (lock) { delay(5); } task_hold(1); lock = 1
#define UNLOCK task_hold(0); lock = 0
-static unsigned int curx = 0;
-static unsigned int cury = 0;
-static unsigned int curxo = 0;
-static unsigned int curyo = 0;
static unsigned char *font;
-void task_cursor(void)
-{
- while (1) {
- int x = curxo + curx * C_WIDTH;
- int y = curyo + cury * C_HEIGHT;
- dsp_rect(x, y + C_HEIGHT, C_WIDTH, 1, 0xFFFF);
- delay(300);
- dsp_rect(x, y + C_HEIGHT, C_WIDTH, 1, 0);
- delay(300);
- }
-}
-
void dsp_cursoron(void)
{
font = malloc(32 * 256);
flash_read((char *)font, 0, 32 * 256);
- task_start(task_cursor, 512);
}
-void dsp_putchar(int c)
+void dsp_putchar(int c, unsigned int xpos, unsigned int ypos)
{
LOCK;
- if (c == '\n') {
+ /*if (c == '\n') {
curx = 0;
if (++cury == S_HEIGHT) {
UNLOCK;
@@ -78,10 +56,10 @@ void dsp_putchar(int c)
dsp_rect(curxo + curx * C_WIDTH, curyo + cury * C_HEIGHT,
C_WIDTH, C_HEIGHT, 0);
return;
- }
+ }*/
- unsigned int x = curxo + curx * C_WIDTH;
- unsigned int y = curyo + cury * C_HEIGHT;
+ unsigned int x = xpos * C_WIDTH;
+ unsigned int y = ypos * C_HEIGHT;
dsp_set_addr(x, y, x + C_WIDTH - 1, y + C_HEIGHT - 1);
uint32_t base = c * 32;
@@ -94,7 +72,7 @@ void dsp_putchar(int c)
}
}
- if (++curx == S_WIDTH) {
+ /*if (++curx == S_WIDTH) {
curx = 0;
if (++cury == S_HEIGHT) {
UNLOCK;
@@ -102,37 +80,14 @@ void dsp_putchar(int c)
LOCK;
cury = 0;
}
- }
+ }*/
UNLOCK;
}
-void dsp_puts(const char *s)
-{
- unsigned int i = 0;
- while (s[i])
- dsp_putchar(s[i++]);
-}
-
-void dsp_cpos(int x, int y)
-{
- curx = x;
- cury = y;
-}
-
-void dsp_spos(int x, int y)
-{
- if ((int)curx + x >= 0)
- curx += x;
- if ((int)cury + y >= 0)
- cury += y;
-}
-
-void dsp_coff(int x, int y)
-{
- curxo = x;
- curyo = y;
-}
+//
+// Drawing functions
+//
void dsp_rect(int x, int y, int w, int h, uint16_t color)
{
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;
+}
diff --git a/src/fat32.c b/src/fat32.c
index 1154998..3c64f52 100644
--- a/src/fat32.c
+++ b/src/fat32.c
@@ -15,6 +15,8 @@ static uint32_t RootDirCluster;
static uint32_t ClustersLBA;
static uint32_t FATStartLBA;
+static uint8_t *RootDir = 0;
+
int fat_find(void)
{
uint8_t *block = malloc(512);
@@ -65,9 +67,12 @@ int fat_namecmp(const char *fatname, const char *name)
file_t *fat_findfile(const char *name)
{
- uint8_t *block = malloc(512 * SectorsPerCluster);
- sd_read(block, fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster);
+ if (RootDir == 0) {
+ RootDir = sd_read(malloc(512 * SectorsPerCluster),
+ fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster);
+ }
+ uint8_t *block = RootDir;
for (unsigned int i = 0; block[i * 32] != 0; i++) {
if (block[i * 32] == 0xE5 || (block[i * 32 + 11] & 0x0F) == 0x0F)
continue;
@@ -79,34 +84,34 @@ file_t *fat_findfile(const char *name)
file_t *file = malloc(sizeof(file_t));
file->size = size;
file->start = start;
- free(block);
return file;
}
}
- free(block);
return 0;
}
char *fat_getname(uint32_t index)
{
- uint8_t *block = malloc(512 * SectorsPerCluster);
- sd_read(block, fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster);
+ if (RootDir == 0) {
+ RootDir = sd_read(malloc(512 * SectorsPerCluster),
+ fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster);
+ }
uint32_t idx = 0;
+ uint8_t *block = RootDir;
for (unsigned int i = 0; block[i * 32] != 0; i++) {
if (block[i * 32] == 0xE5 || (block[i * 32 + 11] & 0x0F) == 0x0F)
continue;
if (idx == index) {
- char *name = strncpy(malloc(11), (char *)(block + i * 32), 11);
- free(block);
+ char *name = strncpy(malloc(12), (char *)(block + i * 32), 11);
+ name[11] = '\0';
return name;
}
idx++;
}
- free(block);
return 0;
}
diff --git a/src/main.c b/src/main.c
index 4380eae..b60f626 100644
--- a/src/main.c
+++ b/src/main.c
@@ -21,6 +21,7 @@
#include <clock.h>
#include <display.h>
#include <display_draw.h>
+#include <display_text.h>
#include <fat32.h>
#include <flash.h>
#include <gpio.h>
@@ -90,9 +91,11 @@ void wakeup(void)
void kmain(void)
{
dsp_init();
+ dsp_cursoron();
+ text_init();
+
sd_init();
fat_find();
- dsp_cursoron();
keypad_start();
task_start(task_interpreter, 4096);
@@ -117,8 +120,8 @@ instance *load_program(const char *name)
// load file
file_t *file = fat_findfile(name);
if (file == 0) {
- dsp_puts("can't find ");
- dsp_puts(name);
+ text_puts("can't find ");
+ text_puts(name);
goto fail;
}
@@ -184,6 +187,7 @@ void task_status(void)
void task_interpreter(void)
{
+ dsp_rect(0, 0, 480, 300, 0);
instance *it = load_program("init");
// run the script
diff --git a/src/script.c b/src/script.c
index 5ba0c08..65dd5a4 100644
--- a/src/script.c
+++ b/src/script.c
@@ -25,6 +25,7 @@
#include <ctype.h>
#include <display.h>
#include <display_draw.h>
+#include <display_text.h>
#include <heap.h>
#include <initrd.h>
#include <it/string.h>
@@ -53,6 +54,7 @@ int script_menu(instance *it);
int script_filemenu(instance *it);
int script_program(instance *it);
int script_free(instance *it);
+int script_clear(instance *it);
int math_sin(instance *it);
int math_cos(instance *it);
@@ -74,6 +76,7 @@ void script_loadlib(instance *it)
inew_cfunc(it, "line", script_line);
inew_cfunc(it, "rect", script_rect);
inew_cfunc(it, "color", script_color);
+ inew_cfunc(it, "clear", script_clear);
inew_cfunc(it, "rand", script_rand);
inew_cfunc(it, "delay", script_delay);
@@ -118,11 +121,15 @@ int script_menu(instance *it)
int nargs = igetarg_integer(it, 0);
float *resps = (float *)calloc(nargs, sizeof(float));
strncpy(listbuf, " : \0", 4);
+
+ text_switch(1);
+ text_clear();
+
for (int i = 0; i < nargs; i++) {
listbuf[0] = i + '0';
- dsp_puts(listbuf);
- dsp_puts((char *)igetarg(it, 1 + i * 2)->value.p);
- dsp_puts("\n");
+ text_puts(listbuf);
+ text_puts((char *)igetarg(it, 1 + i * 2)->value.p);
+ text_puts("\n");
resps[i] = igetarg(it, 2 + i * 2)->value.f;
}
@@ -133,6 +140,7 @@ int script_menu(instance *it)
variable *v = make_varf(0, isdigit(c) ? c - '0' : -1.0f);
ipush(it, (uint32_t)v);
+ text_switch(0);
free(resps);
return 0;
}
@@ -144,13 +152,13 @@ int script_filemenu(instance *it)
char listbuf[4];
char *fname;
strncpy(listbuf, " : \0", 4);
- dsp_puts("Choose a file: \n");
+ text_puts("Choose a file: \n");
for (unsigned int i = 0; (fname = /*initrd*/fat_getname(i)) != 0; i++) {
listbuf[0] = i + '0';
- dsp_puts(listbuf);
- dsp_puts(fname);
+ text_puts(listbuf);
+ text_puts(fname);
free(fname);
- dsp_puts("\n");
+ text_puts("\n");
}
int c;
@@ -170,9 +178,9 @@ int script_puts(instance *it)
char buf[33];
//snprintf(buf, 33, "%d", (int)v->value.f); // TODO
ftostr(buf, v->value.f);
- dsp_puts(buf);
+ text_puts(buf);
} else if (v->type == STRING) {
- dsp_puts((const char *)v->value.p);
+ text_puts((const char *)v->value.p);
}
return 0;
}
@@ -184,7 +192,7 @@ int script_putchar(instance *it)
buf[0] = (int)v->value.f;
buf[1] = '\0';
- dsp_puts(buf);
+ text_puts(buf);
return 0;
}
@@ -219,13 +227,13 @@ int script_gets(instance *it)
break;
} else if (c[0] == K_LEFT) {
if (index > 0) {
- dsp_spos(-1, 0);
+ text_relpos(-1, 0);
index--;
}
continue;
} else if (c[0] == K_RIGHT) {
if (index < furthest) {
- dsp_spos(1, 0);
+ text_relpos(1, 0);
index++;
}
continue;
@@ -247,17 +255,17 @@ int script_gets(instance *it)
if (c[0] == '\b' || c[0] == 127) {
index--;
if (index > -1) {
- dsp_puts("\b");
+ text_puts("\b");
index--;
}
} else if (keypad_insert != 0) {
- dsp_spos(-index, 0);
+ text_relpos(-index, 0);
s[furthest + 1] = '\0';
- dsp_puts(s);
- dsp_spos(-(furthest - index), 0);
+ text_puts(s);
+ text_relpos(-(furthest - index), 0);
furthest++;
} else if (c[0] != '\n'/*'\r'*/) {
- dsp_puts(c);
+ text_puts(c);
}
if (++index > furthest)
@@ -299,14 +307,13 @@ int script_line(instance *it)
int script_ppos(instance *it)
{
- dsp_coff(0, 0);
- dsp_cpos(igetarg_integer(it, 0), igetarg_integer(it, 1));
+ text_setpos(igetarg_integer(it, 0), igetarg_integer(it, 1));
return 0;
}
int script_rpos(instance *it)
{
- dsp_spos(igetarg_integer(it, 0), igetarg_integer(it, 1));
+ text_relpos(igetarg_integer(it, 0), igetarg_integer(it, 1));
return 0;
}
@@ -351,10 +358,7 @@ int script_program(instance *it)
int initrdOffset = (int)igetarg(it, 0)->value.f;
char *name = fat_getname(initrdOffset);
- dsp_rect(0, 0, 480, 300, 0);
- dsp_cpos(0, 0);
- dsp_coff(0, 0);
-
+ text_clear();
instance *it2 = load_program(name);
free(name);
@@ -372,3 +376,10 @@ int script_free(instance *it)
ipush(it, (uint32_t)make_varf(0, 98303 - heap_used));
return 0;
}
+
+int script_clear(instance *it)
+{
+ (void)it;
+ text_clear();
+ return 0;
+}