diff options
Diffstat (limited to 'firmware/drivers/lcd-2bit-vert.c')
-rw-r--r-- | firmware/drivers/lcd-2bit-vert.c | 176 |
1 files changed, 57 insertions, 119 deletions
diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c index 37abf0496f..751d2a2ad9 100644 --- a/firmware/drivers/lcd-2bit-vert.c +++ b/firmware/drivers/lcd-2bit-vert.c | |||
@@ -30,10 +30,7 @@ | |||
30 | #include "font.h" | 30 | #include "font.h" |
31 | #include "rbunicode.h" | 31 | #include "rbunicode.h" |
32 | #include "bidi.h" | 32 | #include "bidi.h" |
33 | 33 | #include "scroll_engine.h" | |
34 | /*** definitions ***/ | ||
35 | |||
36 | #define SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32) | ||
37 | 34 | ||
38 | /*** globals ***/ | 35 | /*** globals ***/ |
39 | 36 | ||
@@ -58,32 +55,13 @@ static int xmargin = 0; | |||
58 | static int ymargin = 0; | 55 | static int ymargin = 0; |
59 | static int curfont = FONT_SYSFIXED; | 56 | static int curfont = FONT_SYSFIXED; |
60 | 57 | ||
61 | /* scrolling */ | ||
62 | static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ | ||
63 | static void scroll_thread(void); | ||
64 | static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; | ||
65 | static const char scroll_name[] = "scroll"; | ||
66 | static int scroll_ticks = 12; /* # of ticks between updates*/ | ||
67 | static int scroll_delay = HZ/2; /* ticks delay before start */ | ||
68 | static int scroll_step = 6; /* pixels per scroll step */ | ||
69 | static int bidir_limit = 50; /* percent */ | ||
70 | static struct scrollinfo scroll[SCROLLABLE_LINES]; | ||
71 | |||
72 | static const char scroll_tick_table[16] = { | ||
73 | /* Hz values: | ||
74 | 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ | ||
75 | 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 | ||
76 | }; | ||
77 | |||
78 | /* LCD init */ | 58 | /* LCD init */ |
79 | void lcd_init(void) | 59 | void lcd_init(void) |
80 | { | 60 | { |
81 | lcd_clear_display(); | 61 | lcd_clear_display(); |
82 | /* Call device specific init */ | 62 | /* Call device specific init */ |
83 | lcd_init_device(); | 63 | lcd_init_device(); |
84 | create_thread(scroll_thread, scroll_stack, | 64 | scroll_init(); |
85 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) | ||
86 | IF_COP(, CPU, false)); | ||
87 | } | 65 | } |
88 | 66 | ||
89 | /*** parameter handling ***/ | 67 | /*** parameter handling ***/ |
@@ -146,6 +124,11 @@ void lcd_setfont(int newfont) | |||
146 | curfont = newfont; | 124 | curfont = newfont; |
147 | } | 125 | } |
148 | 126 | ||
127 | int lcd_getfont(void) | ||
128 | { | ||
129 | return curfont; | ||
130 | } | ||
131 | |||
149 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) | 132 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) |
150 | { | 133 | { |
151 | return font_getstringsize(str, w, h, curfont); | 134 | return font_getstringsize(str, w, h, curfont); |
@@ -380,7 +363,8 @@ void lcd_clear_display(void) | |||
380 | else | 363 | else |
381 | memset(lcd_framebuffer, bg_pattern, sizeof lcd_framebuffer); | 364 | memset(lcd_framebuffer, bg_pattern, sizeof lcd_framebuffer); |
382 | } | 365 | } |
383 | scrolling_lines = 0; | 366 | |
367 | lcd_scroll_info.lines = 0; | ||
384 | } | 368 | } |
385 | 369 | ||
386 | /* Set a single pixel */ | 370 | /* Set a single pixel */ |
@@ -998,7 +982,7 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, | |||
998 | int lastmode = drawmode; | 982 | int lastmode = drawmode; |
999 | 983 | ||
1000 | /* make sure scrolling is turned off on the line we are updating */ | 984 | /* make sure scrolling is turned off on the line we are updating */ |
1001 | scrolling_lines &= ~(1 << y); | 985 | lcd_scroll_info.lines &= ~(1 << y); |
1002 | 986 | ||
1003 | if(!str || !str[0]) | 987 | if(!str || !str[0]) |
1004 | return; | 988 | return; |
@@ -1017,45 +1001,6 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, | |||
1017 | 1001 | ||
1018 | /*** scrolling ***/ | 1002 | /*** scrolling ***/ |
1019 | 1003 | ||
1020 | /* Reverse the invert setting of the scrolling line (if any) at given char | ||
1021 | position. Setting will go into affect next time line scrolls. */ | ||
1022 | void lcd_invertscroll(int x, int y) | ||
1023 | { | ||
1024 | struct scrollinfo* s; | ||
1025 | |||
1026 | (void)x; | ||
1027 | |||
1028 | if(y>=SCROLLABLE_LINES) return; | ||
1029 | |||
1030 | s = &scroll[y]; | ||
1031 | s->invert = !s->invert; | ||
1032 | } | ||
1033 | |||
1034 | void lcd_stop_scroll(void) | ||
1035 | { | ||
1036 | scrolling_lines=0; | ||
1037 | } | ||
1038 | |||
1039 | void lcd_scroll_speed(int speed) | ||
1040 | { | ||
1041 | scroll_ticks = scroll_tick_table[speed]; | ||
1042 | } | ||
1043 | |||
1044 | void lcd_scroll_step(int step) | ||
1045 | { | ||
1046 | scroll_step = step; | ||
1047 | } | ||
1048 | |||
1049 | void lcd_scroll_delay(int ms) | ||
1050 | { | ||
1051 | scroll_delay = ms / (HZ / 10); | ||
1052 | } | ||
1053 | |||
1054 | void lcd_bidir_scroll(int percent) | ||
1055 | { | ||
1056 | bidir_limit = percent; | ||
1057 | } | ||
1058 | |||
1059 | void lcd_puts_scroll(int x, int y, const unsigned char *string) | 1004 | void lcd_puts_scroll(int x, int y, const unsigned char *string) |
1060 | { | 1005 | { |
1061 | lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); | 1006 | lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); |
@@ -1077,11 +1022,11 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
1077 | struct scrollinfo* s; | 1022 | struct scrollinfo* s; |
1078 | int w, h; | 1023 | int w, h; |
1079 | 1024 | ||
1080 | if(y>=SCROLLABLE_LINES) return; | 1025 | if(y>=LCD_SCROLLABLE_LINES) return; |
1081 | 1026 | ||
1082 | s = &scroll[y]; | 1027 | s = &lcd_scroll_info.scroll[y]; |
1083 | 1028 | ||
1084 | s->start_tick = current_tick + scroll_delay; | 1029 | s->start_tick = current_tick + lcd_scroll_info.delay; |
1085 | s->invert = false; | 1030 | s->invert = false; |
1086 | if (style & STYLE_INVERT) { | 1031 | if (style & STYLE_INVERT) { |
1087 | s->invert = true; | 1032 | s->invert = true; |
@@ -1104,9 +1049,9 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
1104 | 1049 | ||
1105 | /* scroll bidirectional or forward only depending on the string | 1050 | /* scroll bidirectional or forward only depending on the string |
1106 | width */ | 1051 | width */ |
1107 | if ( bidir_limit ) { | 1052 | if ( lcd_scroll_info.bidir_limit ) { |
1108 | s->bidir = s->width < (LCD_WIDTH - xmargin) * | 1053 | s->bidir = s->width < (LCD_WIDTH - xmargin) * |
1109 | (100 + bidir_limit) / 100; | 1054 | (100 + lcd_scroll_info.bidir_limit) / 100; |
1110 | } | 1055 | } |
1111 | else | 1056 | else |
1112 | s->bidir = false; | 1057 | s->bidir = false; |
@@ -1124,14 +1069,14 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
1124 | s->offset = offset; | 1069 | s->offset = offset; |
1125 | s->startx = xmargin + x * s->width / s->len; | 1070 | s->startx = xmargin + x * s->width / s->len; |
1126 | s->backward = false; | 1071 | s->backward = false; |
1127 | scrolling_lines |= (1<<y); | 1072 | lcd_scroll_info.lines |= (1<<y); |
1128 | } | 1073 | } |
1129 | else | 1074 | else |
1130 | /* force a bit switch-off since it doesn't scroll */ | 1075 | /* force a bit switch-off since it doesn't scroll */ |
1131 | scrolling_lines &= ~(1<<y); | 1076 | lcd_scroll_info.lines &= ~(1<<y); |
1132 | } | 1077 | } |
1133 | 1078 | ||
1134 | static void scroll_thread(void) | 1079 | void lcd_scroll_fn(void) |
1135 | { | 1080 | { |
1136 | struct font* pf; | 1081 | struct font* pf; |
1137 | struct scrollinfo* s; | 1082 | struct scrollinfo* s; |
@@ -1139,58 +1084,51 @@ static void scroll_thread(void) | |||
1139 | int xpos, ypos; | 1084 | int xpos, ypos; |
1140 | int lastmode; | 1085 | int lastmode; |
1141 | 1086 | ||
1142 | /* initialize scroll struct array */ | 1087 | for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) { |
1143 | scrolling_lines = 0; | 1088 | /* really scroll? */ |
1144 | 1089 | if ((lcd_scroll_info.lines & (1 << index)) == 0) | |
1145 | while ( 1 ) { | 1090 | continue; |
1146 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | ||
1147 | /* really scroll? */ | ||
1148 | if ( !(scrolling_lines&(1<<index)) ) | ||
1149 | continue; | ||
1150 | 1091 | ||
1151 | s = &scroll[index]; | 1092 | s = &lcd_scroll_info.scroll[index]; |
1152 | 1093 | ||
1153 | /* check pause */ | 1094 | /* check pause */ |
1154 | if (TIME_BEFORE(current_tick, s->start_tick)) | 1095 | if (TIME_BEFORE(current_tick, s->start_tick)) |
1155 | continue; | 1096 | continue; |
1156 | 1097 | ||
1157 | if (s->backward) | 1098 | if (s->backward) |
1158 | s->offset -= scroll_step; | 1099 | s->offset -= lcd_scroll_info.step; |
1159 | else | 1100 | else |
1160 | s->offset += scroll_step; | 1101 | s->offset += lcd_scroll_info.step; |
1161 | 1102 | ||
1162 | pf = font_get(curfont); | 1103 | pf = font_get(curfont); |
1163 | xpos = s->startx; | 1104 | xpos = s->startx; |
1164 | ypos = ymargin + index * pf->height; | 1105 | ypos = ymargin + index * pf->height; |
1165 | 1106 | ||
1166 | if (s->bidir) { /* scroll bidirectional */ | 1107 | if (s->bidir) { /* scroll bidirectional */ |
1167 | if (s->offset <= 0) { | 1108 | if (s->offset <= 0) { |
1168 | /* at beginning of line */ | 1109 | /* at beginning of line */ |
1169 | s->offset = 0; | 1110 | s->offset = 0; |
1170 | s->backward = false; | 1111 | s->backward = false; |
1171 | s->start_tick = current_tick + scroll_delay * 2; | 1112 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; |
1172 | } | ||
1173 | if (s->offset >= s->width - (LCD_WIDTH - xpos)) { | ||
1174 | /* at end of line */ | ||
1175 | s->offset = s->width - (LCD_WIDTH - xpos); | ||
1176 | s->backward = true; | ||
1177 | s->start_tick = current_tick + scroll_delay * 2; | ||
1178 | } | ||
1179 | } | 1113 | } |
1180 | else { | 1114 | if (s->offset >= s->width - (LCD_WIDTH - xpos)) { |
1181 | /* scroll forward the whole time */ | 1115 | /* at end of line */ |
1182 | if (s->offset >= s->width) | 1116 | s->offset = s->width - (LCD_WIDTH - xpos); |
1183 | s->offset %= s->width; | 1117 | s->backward = true; |
1118 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | ||
1184 | } | 1119 | } |
1185 | 1120 | } | |
1186 | lastmode = drawmode; | 1121 | else { |
1187 | drawmode = s->invert ? | 1122 | /* scroll forward the whole time */ |
1188 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 1123 | if (s->offset >= s->width) |
1189 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | 1124 | s->offset %= s->width; |
1190 | drawmode = lastmode; | ||
1191 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
1192 | } | 1125 | } |
1193 | 1126 | ||
1194 | sleep(scroll_ticks); | 1127 | lastmode = drawmode; |
1128 | drawmode = s->invert ? | ||
1129 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | ||
1130 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | ||
1131 | drawmode = lastmode; | ||
1132 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
1195 | } | 1133 | } |
1196 | } | 1134 | } |