better text managment

master
Clyne Sullivan 7 years ago
parent 1a11ab00d8
commit 5df5c67397

@ -27,7 +27,7 @@ STRIP = strip
MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
AFLAGS = $(MCUFLAGS) AFLAGS = $(MCUFLAGS)
CFLAGS = $(MCUFLAGS) -ggdb \ CFLAGS = $(MCUFLAGS) -O2 \
-Iinclude -Iinclude/cmsis \ -Iinclude -Iinclude/cmsis \
-fno-builtin -fsigned-char -ffreestanding \ -fno-builtin -fsigned-char -ffreestanding \
-Wall -Werror -Wextra -pedantic \ -Wall -Werror -Wextra -pedantic \

@ -23,6 +23,9 @@
#include <stdint.h> #include <stdint.h>
#define C_WIDTH 12
#define C_HEIGHT 16
/** /**
* Starts the task for a blinking text cursor. * 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); void dsp_rect(int x, int y, int w, int h, uint16_t color);
/** void dsp_putchar(int c, unsigned int xpos, unsigned int ypos);
* 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);
#endif // DISPLAY_DRAW_H_ #endif // DISPLAY_DRAW_H_

@ -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_

@ -1,10 +1,8 @@
while (1) { while (1) {
rect(0, 0, 480, 300, 0)
ppos(0, 0)
print("Free mem: ") print("Free mem: ")
print(freemem()) print(freemem())
print("\n") print("\n")
choice = filemenu() choice = filemenu()
program(choice) program(choice)
clear()
} }

@ -25,44 +25,22 @@
#include <task.h> #include <task.h>
#include <clock.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; volatile uint8_t lock = 0;
#define LOCK while (lock) { delay(5); } task_hold(1); lock = 1 #define LOCK while (lock) { delay(5); } task_hold(1); lock = 1
#define UNLOCK task_hold(0); lock = 0 #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; 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) void dsp_cursoron(void)
{ {
font = malloc(32 * 256); font = malloc(32 * 256);
flash_read((char *)font, 0, 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; LOCK;
if (c == '\n') { /*if (c == '\n') {
curx = 0; curx = 0;
if (++cury == S_HEIGHT) { if (++cury == S_HEIGHT) {
UNLOCK; UNLOCK;
@ -78,10 +56,10 @@ void dsp_putchar(int c)
dsp_rect(curxo + curx * C_WIDTH, curyo + cury * C_HEIGHT, dsp_rect(curxo + curx * C_WIDTH, curyo + cury * C_HEIGHT,
C_WIDTH, C_HEIGHT, 0); C_WIDTH, C_HEIGHT, 0);
return; return;
} }*/
unsigned int x = curxo + curx * C_WIDTH; unsigned int x = xpos * C_WIDTH;
unsigned int y = curyo + cury * C_HEIGHT; unsigned int y = ypos * C_HEIGHT;
dsp_set_addr(x, y, x + C_WIDTH - 1, y + C_HEIGHT - 1); dsp_set_addr(x, y, x + C_WIDTH - 1, y + C_HEIGHT - 1);
uint32_t base = c * 32; uint32_t base = c * 32;
@ -94,7 +72,7 @@ void dsp_putchar(int c)
} }
} }
if (++curx == S_WIDTH) { /*if (++curx == S_WIDTH) {
curx = 0; curx = 0;
if (++cury == S_HEIGHT) { if (++cury == S_HEIGHT) {
UNLOCK; UNLOCK;
@ -102,37 +80,14 @@ void dsp_putchar(int c)
LOCK; LOCK;
cury = 0; cury = 0;
} }
} }*/
UNLOCK; UNLOCK;
} }
void dsp_puts(const char *s) //
{ // Drawing functions
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;
}
void dsp_rect(int x, int y, int w, int h, uint16_t color) void dsp_rect(int x, int y, int w, int h, uint16_t color)
{ {

@ -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;
}

@ -15,6 +15,8 @@ static uint32_t RootDirCluster;
static uint32_t ClustersLBA; static uint32_t ClustersLBA;
static uint32_t FATStartLBA; static uint32_t FATStartLBA;
static uint8_t *RootDir = 0;
int fat_find(void) int fat_find(void)
{ {
uint8_t *block = malloc(512); 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) file_t *fat_findfile(const char *name)
{ {
uint8_t *block = malloc(512 * SectorsPerCluster); if (RootDir == 0) {
sd_read(block, fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster); 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++) { for (unsigned int i = 0; block[i * 32] != 0; i++) {
if (block[i * 32] == 0xE5 || (block[i * 32 + 11] & 0x0F) == 0x0F) if (block[i * 32] == 0xE5 || (block[i * 32 + 11] & 0x0F) == 0x0F)
continue; continue;
@ -79,34 +84,34 @@ file_t *fat_findfile(const char *name)
file_t *file = malloc(sizeof(file_t)); file_t *file = malloc(sizeof(file_t));
file->size = size; file->size = size;
file->start = start; file->start = start;
free(block);
return file; return file;
} }
} }
free(block);
return 0; return 0;
} }
char *fat_getname(uint32_t index) char *fat_getname(uint32_t index)
{ {
uint8_t *block = malloc(512 * SectorsPerCluster); if (RootDir == 0) {
sd_read(block, fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster); RootDir = sd_read(malloc(512 * SectorsPerCluster),
fat_cluster2lba(RootDirCluster), 512 * SectorsPerCluster);
}
uint32_t idx = 0; uint32_t idx = 0;
uint8_t *block = RootDir;
for (unsigned int i = 0; block[i * 32] != 0; i++) { for (unsigned int i = 0; block[i * 32] != 0; i++) {
if (block[i * 32] == 0xE5 || (block[i * 32 + 11] & 0x0F) == 0x0F) if (block[i * 32] == 0xE5 || (block[i * 32 + 11] & 0x0F) == 0x0F)
continue; continue;
if (idx == index) { if (idx == index) {
char *name = strncpy(malloc(11), (char *)(block + i * 32), 11); char *name = strncpy(malloc(12), (char *)(block + i * 32), 11);
free(block); name[11] = '\0';
return name; return name;
} }
idx++; idx++;
} }
free(block);
return 0; return 0;
} }

@ -21,6 +21,7 @@
#include <clock.h> #include <clock.h>
#include <display.h> #include <display.h>
#include <display_draw.h> #include <display_draw.h>
#include <display_text.h>
#include <fat32.h> #include <fat32.h>
#include <flash.h> #include <flash.h>
#include <gpio.h> #include <gpio.h>
@ -90,9 +91,11 @@ void wakeup(void)
void kmain(void) void kmain(void)
{ {
dsp_init(); dsp_init();
dsp_cursoron();
text_init();
sd_init(); sd_init();
fat_find(); fat_find();
dsp_cursoron();
keypad_start(); keypad_start();
task_start(task_interpreter, 4096); task_start(task_interpreter, 4096);
@ -117,8 +120,8 @@ instance *load_program(const char *name)
// load file // load file
file_t *file = fat_findfile(name); file_t *file = fat_findfile(name);
if (file == 0) { if (file == 0) {
dsp_puts("can't find "); text_puts("can't find ");
dsp_puts(name); text_puts(name);
goto fail; goto fail;
} }
@ -184,6 +187,7 @@ void task_status(void)
void task_interpreter(void) void task_interpreter(void)
{ {
dsp_rect(0, 0, 480, 300, 0);
instance *it = load_program("init"); instance *it = load_program("init");
// run the script // run the script

@ -25,6 +25,7 @@
#include <ctype.h> #include <ctype.h>
#include <display.h> #include <display.h>
#include <display_draw.h> #include <display_draw.h>
#include <display_text.h>
#include <heap.h> #include <heap.h>
#include <initrd.h> #include <initrd.h>
#include <it/string.h> #include <it/string.h>
@ -53,6 +54,7 @@ int script_menu(instance *it);
int script_filemenu(instance *it); int script_filemenu(instance *it);
int script_program(instance *it); int script_program(instance *it);
int script_free(instance *it); int script_free(instance *it);
int script_clear(instance *it);
int math_sin(instance *it); int math_sin(instance *it);
int math_cos(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, "line", script_line);
inew_cfunc(it, "rect", script_rect); inew_cfunc(it, "rect", script_rect);
inew_cfunc(it, "color", script_color); inew_cfunc(it, "color", script_color);
inew_cfunc(it, "clear", script_clear);
inew_cfunc(it, "rand", script_rand); inew_cfunc(it, "rand", script_rand);
inew_cfunc(it, "delay", script_delay); inew_cfunc(it, "delay", script_delay);
@ -118,11 +121,15 @@ int script_menu(instance *it)
int nargs = igetarg_integer(it, 0); int nargs = igetarg_integer(it, 0);
float *resps = (float *)calloc(nargs, sizeof(float)); float *resps = (float *)calloc(nargs, sizeof(float));
strncpy(listbuf, " : \0", 4); strncpy(listbuf, " : \0", 4);
text_switch(1);
text_clear();
for (int i = 0; i < nargs; i++) { for (int i = 0; i < nargs; i++) {
listbuf[0] = i + '0'; listbuf[0] = i + '0';
dsp_puts(listbuf); text_puts(listbuf);
dsp_puts((char *)igetarg(it, 1 + i * 2)->value.p); text_puts((char *)igetarg(it, 1 + i * 2)->value.p);
dsp_puts("\n"); text_puts("\n");
resps[i] = igetarg(it, 2 + i * 2)->value.f; 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); variable *v = make_varf(0, isdigit(c) ? c - '0' : -1.0f);
ipush(it, (uint32_t)v); ipush(it, (uint32_t)v);
text_switch(0);
free(resps); free(resps);
return 0; return 0;
} }
@ -144,13 +152,13 @@ int script_filemenu(instance *it)
char listbuf[4]; char listbuf[4];
char *fname; char *fname;
strncpy(listbuf, " : \0", 4); 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++) { for (unsigned int i = 0; (fname = /*initrd*/fat_getname(i)) != 0; i++) {
listbuf[0] = i + '0'; listbuf[0] = i + '0';
dsp_puts(listbuf); text_puts(listbuf);
dsp_puts(fname); text_puts(fname);
free(fname); free(fname);
dsp_puts("\n"); text_puts("\n");
} }
int c; int c;
@ -170,9 +178,9 @@ int script_puts(instance *it)
char buf[33]; char buf[33];
//snprintf(buf, 33, "%d", (int)v->value.f); // TODO //snprintf(buf, 33, "%d", (int)v->value.f); // TODO
ftostr(buf, v->value.f); ftostr(buf, v->value.f);
dsp_puts(buf); text_puts(buf);
} else if (v->type == STRING) { } else if (v->type == STRING) {
dsp_puts((const char *)v->value.p); text_puts((const char *)v->value.p);
} }
return 0; return 0;
} }
@ -184,7 +192,7 @@ int script_putchar(instance *it)
buf[0] = (int)v->value.f; buf[0] = (int)v->value.f;
buf[1] = '\0'; buf[1] = '\0';
dsp_puts(buf); text_puts(buf);
return 0; return 0;
} }
@ -219,13 +227,13 @@ int script_gets(instance *it)
break; break;
} else if (c[0] == K_LEFT) { } else if (c[0] == K_LEFT) {
if (index > 0) { if (index > 0) {
dsp_spos(-1, 0); text_relpos(-1, 0);
index--; index--;
} }
continue; continue;
} else if (c[0] == K_RIGHT) { } else if (c[0] == K_RIGHT) {
if (index < furthest) { if (index < furthest) {
dsp_spos(1, 0); text_relpos(1, 0);
index++; index++;
} }
continue; continue;
@ -247,17 +255,17 @@ int script_gets(instance *it)
if (c[0] == '\b' || c[0] == 127) { if (c[0] == '\b' || c[0] == 127) {
index--; index--;
if (index > -1) { if (index > -1) {
dsp_puts("\b"); text_puts("\b");
index--; index--;
} }
} else if (keypad_insert != 0) { } else if (keypad_insert != 0) {
dsp_spos(-index, 0); text_relpos(-index, 0);
s[furthest + 1] = '\0'; s[furthest + 1] = '\0';
dsp_puts(s); text_puts(s);
dsp_spos(-(furthest - index), 0); text_relpos(-(furthest - index), 0);
furthest++; furthest++;
} else if (c[0] != '\n'/*'\r'*/) { } else if (c[0] != '\n'/*'\r'*/) {
dsp_puts(c); text_puts(c);
} }
if (++index > furthest) if (++index > furthest)
@ -299,14 +307,13 @@ int script_line(instance *it)
int script_ppos(instance *it) int script_ppos(instance *it)
{ {
dsp_coff(0, 0); text_setpos(igetarg_integer(it, 0), igetarg_integer(it, 1));
dsp_cpos(igetarg_integer(it, 0), igetarg_integer(it, 1));
return 0; return 0;
} }
int script_rpos(instance *it) 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; return 0;
} }
@ -351,10 +358,7 @@ int script_program(instance *it)
int initrdOffset = (int)igetarg(it, 0)->value.f; int initrdOffset = (int)igetarg(it, 0)->value.f;
char *name = fat_getname(initrdOffset); char *name = fat_getname(initrdOffset);
dsp_rect(0, 0, 480, 300, 0); text_clear();
dsp_cpos(0, 0);
dsp_coff(0, 0);
instance *it2 = load_program(name); instance *it2 = load_program(name);
free(name); free(name);
@ -372,3 +376,10 @@ int script_free(instance *it)
ipush(it, (uint32_t)make_varf(0, 98303 - heap_used)); ipush(it, (uint32_t)make_varf(0, 98303 - heap_used));
return 0; return 0;
} }
int script_clear(instance *it)
{
(void)it;
text_clear();
return 0;
}

Loading…
Cancel
Save