]> code.bitgloo.com Git - clyne/calculator.git/commitdiff
better text managment
authorClyne Sullivan <tullivan99@gmail.com>
Thu, 19 Apr 2018 17:14:39 +0000 (13:14 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Thu, 19 Apr 2018 17:14:39 +0000 (13:14 -0400)
Makefile
include/display_draw.h
include/display_text.h [new file with mode: 0644]
initrd/init
src/display_draw.c
src/display_text.c [new file with mode: 0644]
src/fat32.c
src/main.c
src/script.c

index 595694a7111c407ec0371fb2a1194be8f933d1ac..07af411355c55c2dac88e85c5a388b925db233b5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,7 @@ STRIP = strip
 
 MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
 AFLAGS = $(MCUFLAGS) 
-CFLAGS = $(MCUFLAGS) -ggdb \
+CFLAGS = $(MCUFLAGS) -O2 \
        -Iinclude -Iinclude/cmsis \
        -fno-builtin -fsigned-char -ffreestanding \
        -Wall -Werror -Wextra -pedantic \
index 1057a1c58851af29822d8a544e7b846542798895..ece280dbfd33caf880a52922aca3d13c90393f65 100644 (file)
@@ -23,6 +23,9 @@
 
 #include <stdint.h>
 
+#define C_WIDTH  12
+#define C_HEIGHT 16
+
 /**
  * Starts the task for a blinking text cursor.
  */
@@ -56,30 +59,6 @@ void dsp_line(int x, int y, int i, int j, uint16_t color);
  */
 void dsp_rect(int x, int y, int w, int h, uint16_t color);
 
-/**
- * Sets the text cursor's position, in characters NOT pixels.
- * @param x text column to move to
- * @param y text row to move to
- */
-void dsp_cpos(int x, int y);
-
-/*
- * Shifts the cursor the given amount of characters.
- */
-void dsp_spos(int x, int y);
-
-/**
- * Sets the pixel offset of the text cursor.
- * @param x x-pixel offset from (0, 0)
- * @param y y-pixel offset from (0, 0)
- */
-void dsp_coff(int x, int y);
-
-/**
- * Puts a string to the screen. Text position if kept track of internally, so
- * multiple calls will print the strings in one line.
- * @param s the string to print
- */
-void dsp_puts(const char *s);
+void dsp_putchar(int c, unsigned int xpos, unsigned int ypos);
 
 #endif // DISPLAY_DRAW_H_
diff --git a/include/display_text.h b/include/display_text.h
new file mode 100644 (file)
index 0000000..de7ebce
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef DISPLAY_TEXT_H_
+#define DISPLAY_TEXT_H_
+
+void text_init(void);
+void text_switch(unsigned int i);
+void text_puts(const char *s);
+
+void text_clear(void);
+
+void text_setpos(uint8_t x, uint8_t y);
+void text_relpos(int8_t x, int8_t y);
+
+#endif // DISPLAY_TEXT_H_
index 68ef07d2567303b087c6232ef6433149a4d4d872..7592b4a6d7fbd76a74945315733877b97d9c3e41 100644 (file)
@@ -1,10 +1,8 @@
 while (1) {
-       rect(0, 0, 480, 300, 0)
-       ppos(0, 0)
-
        print("Free mem: ")
        print(freemem())
        print("\n")
        choice = filemenu()
        program(choice)
+       clear()
 }
index 97ee386266f81ca39d7afd251de1ae8b908ae42c..ff58c27d6dce163b041520abd816933d6e50bed4 100644 (file)
 #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 (file)
index 0000000..8a41fa5
--- /dev/null
@@ -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;
+}
index 115499811594b9a4a6418abc1f9a3bc7e44ab699..3c64f5215ffad70c9e5b4d59c731cabe19d47f55 100644 (file)
@@ -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;
 }
 
index 4380eaeca20c8afb95b9b93189e86735e85ec585..b60f6263f472956691a72664be2fb56965f8c0eb 100644 (file)
@@ -21,6 +21,7 @@
 #include <clock.h>\r
 #include <display.h>\r
 #include <display_draw.h>\r
+#include <display_text.h>\r
 #include <fat32.h>\r
 #include <flash.h>\r
 #include <gpio.h>\r
@@ -90,9 +91,11 @@ void wakeup(void)
 void kmain(void)\r
 {\r
        dsp_init();\r
+       dsp_cursoron();\r
+       text_init();\r
+\r
        sd_init();\r
        fat_find();\r
-       dsp_cursoron();\r
        keypad_start();\r
 \r
        task_start(task_interpreter, 4096);\r
@@ -117,8 +120,8 @@ instance *load_program(const char *name)
        // load file\r
        file_t *file = fat_findfile(name);\r
        if (file == 0) {\r
-               dsp_puts("can't find ");\r
-               dsp_puts(name);\r
+               text_puts("can't find ");\r
+               text_puts(name);\r
                goto fail;\r
        }\r
 \r
@@ -184,6 +187,7 @@ void task_status(void)
 \r
 void task_interpreter(void)\r
 {\r
+       dsp_rect(0, 0, 480, 300, 0);\r
        instance *it = load_program("init");\r
 \r
        // run the script\r
index 5ba0c0803327b391297cd9051c178c02a7e196f9..65dd5a45de1463a2e5e258edbb482041f6c0e502 100644 (file)
@@ -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;
+}