diff --git a/testline.ino b/testline.ino index 3984b6d..237de60 100644 --- a/testline.ino +++ b/testline.ino @@ -10,17 +10,191 @@ LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 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; - int len; - int fullLines; - int Nlines; - int lastlinelen; - char *pos1, *pos2, *pos3; + list_node_t *pos1, *pos2, *pos3; list_t *wrap; - list_iterator_t *it; } 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); @@ -37,9 +211,17 @@ void loop() { //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); + //Serial.println(String("len: ") + st.len); #endif #ifdef DEBUG @@ -73,198 +255,14 @@ void loop() { delay(1000); scrollUp(&st); } - +*/ delay(3000); } -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(0)) == 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(strlen(text))) == NULL) { - return NULL; - } - return wrap; -} - -void initInfoState(InfoState* st, char* text) { - st->info = text; - st->len = strlen(text); - st->fullLines = st->len / 15; - st->Nlines = (st->len + 14) / 15; - st->lastlinelen = st->len % 15; - st->pos1 = text; - st->pos2 = text; - st->pos3 = text; - st->wrap = list_new(); - st->wrap = aux_gen_wrap_list(st->wrap, st->info); - st->it = list_iterator_new(st->wrap, LIST_HEAD); -} - -void initInfoScreen(InfoState* st, char* text) { - initInfoState(st, text); - lcd.setCursor(0, 0); - - /* - if (*(st->pos1) == '\n' || *(st->pos1) == '\r') { - lcd_blank_line(); - ++st->pos1; - ++st->pos2; - } else { - st->pos2 += lcd_print_line(st->pos1); - } - lcd.setCursor(0, 1); - if ((*(st->pos2) == '\n' || *(st->pos2) == '\r') && *(st->pos2 - 1) == *(st->pos2)) { - lcd_blank_line(); - } else { - lcd_print_line(st->pos2); - } -#ifdef DEBUG - //Serial.println(String("pos1: ") + st->pos1); - //Serial.println(String("pos2: ") + st->pos2); - Serial.println("init"); - Serial.print(st->pos1-st->info); - Serial.println(String(" ")+(st->pos2-st->info)); -#endif - */ -} - - -void scrollDown(InfoState* st) { - st->pos1 = st->pos2; - lcd.setCursor(0, 0); - if ((*(st->pos1) == '\n' || *(st->pos1) == '\r') && *(st->pos1 - 1) == *(st->pos1)) { - lcd_blank_line(); - ++st->pos1; - ++st->pos2; - } else { - st->pos2 += lcd_print_line(st->pos1); - } - lcd.setCursor(0, 1); - if ((*(st->pos2) == '\n' || *(st->pos2) == '\r') && *(st->pos2 - 1) == *(st->pos2)) { - lcd_blank_line(); - } else { - lcd_print_line(st->pos2); - } -#ifdef DEBUG - //Serial.println(String("pos1: ") + st->pos1); - //Serial.println(String("pos2: ") + st->pos2); - Serial.print(st->pos1-st->info); - Serial.println(String(" ")+(st->pos2-st->info)); -#endif -} - -void scrollUp(InfoState* st) { - if (st->pos1 > st->info) { - st->pos2 = st->pos1; - int i = 1; - int va = 1; - /* - int bound = min(st->pos1, 15); - Serial.println(String("bound: ")+bound); - while (i < bound) { - if (st->info[st->pos1-i] != '\n' && st->info[st->pos1-i] != '\r') { - ++i; - } else - if (i == 1){ ++i; ++bound; } else - { - break; - } - } - */ - - /* - while (i < st->pos1-st->info && va < 15) { - if (st->info[st->pos1-i] != '\n' && st->info[st->pos1-i] != '\r') { - ++i; - ++va; - } else - if (i == 1){ ++i; } else - { - break; - } - } - - st->pos1 -= i; - */ - bool is_blank = false; - while (st->pos1 > st->info && va <= 15) { - if (*(st->pos1) != '\n' && *(st->pos1) != '\r') { - ++i; - ++va; - } else if (*(st->pos1 - 1) == *(st->pos1)) { - is_blank = true; - --st->pos1; - break; - } - --st->pos1; - } - while (st->pos1 > st->info && (*(st->pos1) == '\n' || *(st->pos1) == '\r')) { - --st->pos1; - } - //st->pos1 -= i; - - lcd.setCursor(0, 0); - if (is_blank) { - lcd_blank_line(); - } else { - lcd_print_line(st->pos1); - } - lcd.setCursor(0, 1); - if ((*(st->pos2) == '\n' || *(st->pos2) == '\r') && *(st->pos2 - 1) == *(st->pos2)) { - lcd_blank_line(); - } else { - lcd_print_line(st->pos2); - } - } -#ifdef DEBUG - //Serial.println(String("pos1: ") + st->pos1); - //Serial.println(String("pos2: ") + st->pos2); - Serial.print(st->pos1-st->info); - Serial.println(String(" ")+(st->pos2-st->info)); -#endif -} - +/* int lcd_print_line(char* str) { int i = 0; int va = 0; - /* - int bound = min(strlen(str), 15); - while (i < bound) { - if (str[i] != '\n' && str[i] != '\r') { - lcd.print(str[i++]); - } else - if (i == 0){ ++i; ++bound;} else - { - break; - } - } - */ int slen = strlen(str); while (i < slen && va < 15) { if (str[i] != '\n' && str[i] != '\r') { @@ -287,55 +285,5 @@ int lcd_print_line(char* str) { } return i; } - -/* - Separate a substring that can be printed on one line, and return the - original string position corresponding to the end of the substring. - */ -/* -char* aux_sub_line(char* str, char substr[16]) { - int suf = 0; - char* curr = str; - memset(substr, 0, 16); - - while (*curr != '\0' && suf < 15) { - if (*curr != '\n' && *curr != '\r') { - substr[suf++] = *(curr++); - } else - if (curr == str){ ++curr; } else - { - break; - } - } - -#if !REFRESH - while (suf < 15) { - substr[suf++] = ' '; - } -#endif - return curr; -} - -char* aux_sub_line_rev(char* str, char substr[16]) { - int suf = 0; - char* curr = str; - memset(substr, 0, 16); - - while (*curr != '\0' && suf < 15) { - if (*curr != '\n' && *curr != '\r') { - substr[suf++] = *(curr--); - } else - if (curr == str){ --curr; } else - { - break; - } - } - - -} */ -void lcd_blank_line() { - for (int i = 0; i < 15; ++i) { - lcd.print(' '); - } -} +