testline/testline.ino
2024-01-14 16:45:15 +08:00

289 lines
6 KiB
C++

#include <stdint.h>
#include <LiquidCrystal.h>
#include "src/list/src/list.h"
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//#define REFRESH 1
#define DEBUG
uint8_t up_arrow[8] = {0x04,0x0E,0x1F,0x1F,0x00,0x00,0x00,0x00};
uint8_t down_arrow[8] = {0x00,0x00,0x00,0x1F,0x1F,0x0E,0x04,0x04};
typedef enum InfoRet {
IR_UNKNOWN = -1,
IR_NORMAL = 0,
IR_UNSUCCESS
} InfoRet;
typedef struct InfoState {
char* info;
list_node_t *pos1, *pos2, *pos3;
list_t *wrap;
} InfoState;
void lcd_blank_line() {
for (int i = 0; i < 15; ++i) {
lcd.print(' ');
//putchar(' ');
}
}
int lcd_print_between(char* str, int pos1, int pos2) {
//int i = 0;
int va = 0;
char* p = str+pos1;
//int slen = strlen(str);
while (p < str+pos2) {
if (*p != '\n' && *p != '\r') {
lcd.print(*p);
//putchar(*p);
++va;
} //else
//if (i == 0){ ++i; } else
//{
// break;
//}
++p;
}
if (va < 15) {
for (int j = 15 - va; j > 0; --j) {
lcd.print(' ');
//putchar(' ');
}
}
//putchar('!');
return va;
}
list_t* aux_gen_wrap_list(list_t* wrap, char* text) {
if (wrap == NULL) {
wrap = list_new();
}
char* curr = text;
int suf = 0;
list_node_t *node;
if (list_rpush(wrap, list_node_new(-1)) == NULL) {
return NULL;
}
while (*curr != '\0') {
//printf("suf: %d\tpos: %d\n", suf, (unsigned int)(curr-text));
if (suf < 15) {
if (*curr != '\n' && *curr != '\r') {
++suf;
} else {
if (list_rpush(wrap, list_node_new((unsigned int)(curr-text))) == NULL) {
return NULL;
}
suf = 0;
}
} else {
if (list_rpush(wrap, list_node_new((unsigned int)(curr-text))) == NULL) {
return NULL;
}
suf = (*curr != '\n' && *curr != '\r') ? 1 : 0;
}
++curr;
}
if (list_rpush(wrap, list_node_new((int)(curr-text))) == NULL) {
return NULL;
}
return wrap;
}
void initInfoState(InfoState* st, char* text) {
st->info = text;
st->wrap = list_new();
st->wrap = aux_gen_wrap_list(st->wrap, st->info);
st->pos1 = list_at(st->wrap, 0);
st->pos2 = st->pos3 = NULL;
}
InfoRet initInfoScreen(InfoState* st, char* text) {
initInfoState(st, text);
//printf("%d\n", st->wrap->len);
if (st->pos1 == NULL) {
return IR_UNKNOWN;
}
lcd.setCursor(0, 0);
if ((st->pos2 = st->pos1->next)) {
//printf("hello\n");
//printf("%d\n", st->pos2->val);
int tmp = lcd_print_between(st->info, 0, (int)st->pos2->val);
//printf("%d\n", tmp);
//printf("%d\n", st->wrap->len);
if ((st->pos3 = st->pos2->next)) {
//printf("\n");
lcd.setCursor(0, 1);
//printf("%d\n", st->pos2->val);
//printf("%d\n", st->pos3->val);
int tmp = lcd_print_between(st->info, (int)st->pos2->val, (int)st->pos3->val);
//printf("%d\n", tmp);
//printf("%d\n", st->wrap->len);
} else {
//printf("\n");
lcd.setCursor(0, 1);
lcd_blank_line();
}
} else {
return IR_UNKNOWN;
}
return IR_NORMAL;
}
InfoRet scrollDown(InfoState* st) {
if (st->pos2) {
st->pos1 = st->pos2;
} else {
return IR_UNKNOWN;
}
if (st->pos3) {
st->pos2 = st->pos3;
} else {
return IR_UNSUCCESS;
}
lcd.setCursor(0, 0);
int tmp = lcd_print_between(st->info, (int)st->pos1->val, (int)st->pos2->val);
if ((st->pos3 = st->pos3->next)) {
//printf("\n");
lcd.setCursor(0, 1);
int tmp = lcd_print_between(st->info, (int)st->pos2->val, (int)st->pos3->val);
} else {
//printf("\n");
lcd.setCursor(0, 1);
lcd_blank_line();
}
return IR_NORMAL;
}
InfoRet scrollUp(InfoState* st) {
if (st->pos2) {
st->pos3 = st->pos2;
} else {
return IR_UNKNOWN;
}
if (st->pos1 == NULL) {
return IR_UNKNOWN;
} else if ((int)st->pos1->val == -1) {
return IR_UNSUCCESS;
} else {
st->pos2 = st->pos1;
}
if ((st->pos1 = st->pos1->prev)) {
lcd.setCursor(0, 0);
if (st->pos1->val == -1) {
int tmp = lcd_print_between(st->info, 0, (int)st->pos2->val);
} else {
int tmp = lcd_print_between(st->info, (int)st->pos1->val, (int)st->pos2->val);
}
} else {
return IR_UNKNOWN;
}
//printf("\n");
lcd.setCursor(0, 1);
int tmp = lcd_print_between(st->info, (int)st->pos2->val, (int)st->pos3->val);
return IR_NORMAL;
}
void destoryInfoState(InfoState* st) {
st->pos1 = st->pos2 = st->pos3 = NULL;
list_destroy(st->wrap);
st->info = NULL;
}
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.createChar(0, up_arrow);
lcd.createChar(1, down_arrow);
lcd.setCursor(0, 0);
lcd.print("...............");
lcd.setCursor(0, 1);
lcd.print("...............");
}
void loop() {
char* cinfo = "Far far away, a\n\nbehind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts.";
//String info = "hello,`world!wwwwwwwwwwwwwwww";
InfoState st;
initInfoScreen(&st, cinfo);
for (int i = 0; i < 10; ++i) {
delay(1000);
scrollDown(&st);
}
for (int i = 0; i < 10; ++i) {
delay(1000);
scrollUp(&st);
}
/*
#ifdef DEBUG
//Serial.println(String("len: ") + st.len);
#endif
#ifdef DEBUG
Serial.println("down");
#endif
for (int i = 0; i < 3; ++i) {
delay(1000);
scrollDown(&st);
}
#ifdef DEBUG
Serial.println("up");
#endif
for (int i = 0; i < 5; ++i) {
delay(1000);
scrollUp(&st);
}
#ifdef DEBUG
Serial.println("down2");
#endif
for (int i = 0; i < 3; ++i) {
delay(1000);
scrollDown(&st);
}
#ifdef DEBUG
Serial.println("up2");
#endif
for (int i = 0; i < 5; ++i) {
delay(1000);
scrollUp(&st);
}
*/
delay(3000);
}
/*
int lcd_print_line(char* str) {
int i = 0;
int va = 0;
int slen = strlen(str);
while (i < slen && va < 15) {
if (str[i] != '\n' && str[i] != '\r') {
lcd.print(str[i++]);
++va;
} else
if (i == 0){ ++i; } else
{
break;
}
}
if (va < 15) {
#if !REFRESH
for (int j = 15 - va; j > 0; --j) {
lcd.print(' ');
}
#endif
++i;
}
return i;
}
*/