diff options
Diffstat (limited to 'firmware/drivers/lcd-remote-2bit-vi.c')
-rw-r--r-- | firmware/drivers/lcd-remote-2bit-vi.c | 219 |
1 files changed, 56 insertions, 163 deletions
diff --git a/firmware/drivers/lcd-remote-2bit-vi.c b/firmware/drivers/lcd-remote-2bit-vi.c index 65704f0bd3..21e3ee4aa0 100644 --- a/firmware/drivers/lcd-remote-2bit-vi.c +++ b/firmware/drivers/lcd-remote-2bit-vi.c | |||
@@ -34,8 +34,7 @@ | |||
34 | #include "rbunicode.h" | 34 | #include "rbunicode.h" |
35 | #include "bidi.h" | 35 | #include "bidi.h" |
36 | #include "lcd-remote-target.h" | 36 | #include "lcd-remote-target.h" |
37 | 37 | #include "scroll_engine.h" | |
38 | #define SCROLLABLE_LINES (((LCD_REMOTE_HEIGHT+4)/5 < 32) ? (LCD_REMOTE_HEIGHT+4)/5 : 32) | ||
39 | 38 | ||
40 | /*** globals ***/ | 39 | /*** globals ***/ |
41 | 40 | ||
@@ -54,28 +53,6 @@ static int xmargin = 0; | |||
54 | static int ymargin = 0; | 53 | static int ymargin = 0; |
55 | static int curfont = FONT_SYSFIXED; | 54 | static int curfont = FONT_SYSFIXED; |
56 | 55 | ||
57 | /* scrolling */ | ||
58 | static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ | ||
59 | static void scroll_thread(void); | ||
60 | static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; | ||
61 | static const char scroll_name[] = "remote_scroll"; | ||
62 | static int scroll_ticks = 12; /* # of ticks between updates*/ | ||
63 | static int scroll_delay = HZ/2; /* ticks delay before start */ | ||
64 | static int scroll_step = 6; /* pixels per scroll step */ | ||
65 | static int bidir_limit = 50; /* percent */ | ||
66 | static struct scrollinfo scroll[SCROLLABLE_LINES]; | ||
67 | |||
68 | static const char scroll_tick_table[16] = { | ||
69 | /* Hz values: | ||
70 | 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ | ||
71 | 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 | ||
72 | }; | ||
73 | |||
74 | /* remote hotplug */ | ||
75 | #ifndef SIMULATOR | ||
76 | struct event_queue remote_scroll_queue; | ||
77 | #endif | ||
78 | |||
79 | /*** parameter handling ***/ | 56 | /*** parameter handling ***/ |
80 | unsigned lcd_remote_color_to_native(unsigned color) | 57 | unsigned lcd_remote_color_to_native(unsigned color) |
81 | { | 58 | { |
@@ -149,6 +126,11 @@ void lcd_remote_setfont(int newfont) | |||
149 | curfont = newfont; | 126 | curfont = newfont; |
150 | } | 127 | } |
151 | 128 | ||
129 | int lcd_remote_getfont(void) | ||
130 | { | ||
131 | return curfont; | ||
132 | } | ||
133 | |||
152 | int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) | 134 | int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) |
153 | { | 135 | { |
154 | return font_getstringsize(str, w, h, curfont); | 136 | return font_getstringsize(str, w, h, curfont); |
@@ -388,7 +370,8 @@ void lcd_remote_clear_display(void) | |||
388 | memset(lcd_remote_framebuffer, bg_pattern, | 370 | memset(lcd_remote_framebuffer, bg_pattern, |
389 | sizeof lcd_remote_framebuffer); | 371 | sizeof lcd_remote_framebuffer); |
390 | } | 372 | } |
391 | scrolling_lines = 0; | 373 | |
374 | lcd_remote_scroll_info.lines = 0; | ||
392 | } | 375 | } |
393 | 376 | ||
394 | /* Set a single pixel */ | 377 | /* Set a single pixel */ |
@@ -935,7 +918,7 @@ void lcd_remote_bitmap(const fb_remote_data *src, int x, int y, int width, | |||
935 | } | 918 | } |
936 | 919 | ||
937 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | 920 | /* put a string at a given pixel position, skipping first ofs pixel columns */ |
938 | static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) | 921 | void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) |
939 | { | 922 | { |
940 | unsigned short ch; | 923 | unsigned short ch; |
941 | unsigned short *ucs; | 924 | unsigned short *ucs; |
@@ -1000,7 +983,7 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, | |||
1000 | int lastmode = drawmode; | 983 | int lastmode = drawmode; |
1001 | 984 | ||
1002 | /* make sure scrolling is turned off on the line we are updating */ | 985 | /* make sure scrolling is turned off on the line we are updating */ |
1003 | scrolling_lines &= ~(1 << y); | 986 | lcd_remote_scroll_info.lines &= ~(1 << y); |
1004 | 987 | ||
1005 | if(!str || !str[0]) | 988 | if(!str || !str[0]) |
1006 | return; | 989 | return; |
@@ -1018,46 +1001,6 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, | |||
1018 | } | 1001 | } |
1019 | 1002 | ||
1020 | /*** scrolling ***/ | 1003 | /*** scrolling ***/ |
1021 | |||
1022 | /* Reverse the invert setting of the scrolling line (if any) at given char | ||
1023 | position. Setting will go into affect next time line scrolls. */ | ||
1024 | void lcd_remote_invertscroll(int x, int y) | ||
1025 | { | ||
1026 | struct scrollinfo* s; | ||
1027 | |||
1028 | (void)x; | ||
1029 | |||
1030 | if(y>=SCROLLABLE_LINES) return; | ||
1031 | |||
1032 | s = &scroll[y]; | ||
1033 | s->invert = !s->invert; | ||
1034 | } | ||
1035 | |||
1036 | void lcd_remote_stop_scroll(void) | ||
1037 | { | ||
1038 | scrolling_lines=0; | ||
1039 | } | ||
1040 | |||
1041 | void lcd_remote_scroll_speed(int speed) | ||
1042 | { | ||
1043 | scroll_ticks = scroll_tick_table[speed]; | ||
1044 | } | ||
1045 | |||
1046 | void lcd_remote_scroll_step(int step) | ||
1047 | { | ||
1048 | scroll_step = step; | ||
1049 | } | ||
1050 | |||
1051 | void lcd_remote_scroll_delay(int ms) | ||
1052 | { | ||
1053 | scroll_delay = ms / (HZ / 10); | ||
1054 | } | ||
1055 | |||
1056 | void lcd_remote_bidir_scroll(int percent) | ||
1057 | { | ||
1058 | bidir_limit = percent; | ||
1059 | } | ||
1060 | |||
1061 | void lcd_remote_puts_scroll(int x, int y, const unsigned char *string) | 1004 | void lcd_remote_puts_scroll(int x, int y, const unsigned char *string) |
1062 | { | 1005 | { |
1063 | lcd_remote_puts_scroll_style(x, y, string, STYLE_DEFAULT); | 1006 | lcd_remote_puts_scroll_style(x, y, string, STYLE_DEFAULT); |
@@ -1079,11 +1022,11 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
1079 | struct scrollinfo* s; | 1022 | struct scrollinfo* s; |
1080 | int w, h; | 1023 | int w, h; |
1081 | 1024 | ||
1082 | if(y>=SCROLLABLE_LINES) return; | 1025 | if(y>=LCD_REMOTE_SCROLLABLE_LINES) return; |
1083 | 1026 | ||
1084 | s = &scroll[y]; | 1027 | s = &lcd_remote_scroll_info.scroll[y]; |
1085 | 1028 | ||
1086 | s->start_tick = current_tick + scroll_delay; | 1029 | s->start_tick = current_tick + lcd_remote_scroll_info.delay; |
1087 | s->invert = false; | 1030 | s->invert = false; |
1088 | if (style & STYLE_INVERT) { | 1031 | if (style & STYLE_INVERT) { |
1089 | s->invert = true; | 1032 | s->invert = true; |
@@ -1106,9 +1049,9 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
1106 | 1049 | ||
1107 | /* scroll bidirectional or forward only depending on the string | 1050 | /* scroll bidirectional or forward only depending on the string |
1108 | width */ | 1051 | width */ |
1109 | if ( bidir_limit ) { | 1052 | if ( lcd_remote_scroll_info.bidir_limit ) { |
1110 | s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) * | 1053 | s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) * |
1111 | (100 + bidir_limit) / 100; | 1054 | (100 + lcd_remote_scroll_info.bidir_limit) / 100; |
1112 | } | 1055 | } |
1113 | else | 1056 | else |
1114 | s->bidir = false; | 1057 | s->bidir = false; |
@@ -1126,112 +1069,67 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
1126 | s->offset = offset; | 1069 | s->offset = offset; |
1127 | s->startx = xmargin + x * s->width / s->len;; | 1070 | s->startx = xmargin + x * s->width / s->len;; |
1128 | s->backward = false; | 1071 | s->backward = false; |
1129 | scrolling_lines |= (1<<y); | 1072 | lcd_remote_scroll_info.lines |= (1<<y); |
1130 | } | 1073 | } |
1131 | else | 1074 | else |
1132 | /* force a bit switch-off since it doesn't scroll */ | 1075 | /* force a bit switch-off since it doesn't scroll */ |
1133 | scrolling_lines &= ~(1<<y); | 1076 | lcd_remote_scroll_info.lines &= ~(1<<y); |
1134 | } | 1077 | } |
1135 | 1078 | ||
1136 | static void scroll_thread(void) | 1079 | void lcd_remote_scroll_fn(void) |
1137 | { | 1080 | { |
1138 | struct font* pf; | 1081 | struct font* pf; |
1139 | struct scrollinfo* s; | 1082 | struct scrollinfo* s; |
1140 | int index; | 1083 | int index; |
1141 | int xpos, ypos; | 1084 | int xpos, ypos; |
1142 | int lastmode; | 1085 | int lastmode; |
1143 | long delay = 0; | ||
1144 | long next_tick = current_tick; | ||
1145 | #ifndef SIMULATOR | ||
1146 | struct event ev; | ||
1147 | #endif | ||
1148 | |||
1149 | /* initialize scroll struct array */ | ||
1150 | scrolling_lines = 0; | ||
1151 | 1086 | ||
1152 | while ( 1 ) { | 1087 | for ( index = 0; index < LCD_REMOTE_SCROLLABLE_LINES; index++ ) { |
1153 | 1088 | /* really scroll? */ | |
1154 | #ifdef SIMULATOR | 1089 | if ((lcd_remote_scroll_info.lines & (1 << index)) == 0) |
1155 | sleep(delay); | ||
1156 | #else | ||
1157 | if (remote_initialized) | ||
1158 | queue_wait_w_tmo(&remote_scroll_queue, &ev, delay); | ||
1159 | else | ||
1160 | queue_wait(&remote_scroll_queue, &ev); | ||
1161 | |||
1162 | switch (ev.id) | ||
1163 | { | ||
1164 | case REMOTE_INIT_LCD: | ||
1165 | lcd_remote_on(); | ||
1166 | lcd_remote_update(); | ||
1167 | break; | ||
1168 | |||
1169 | case REMOTE_DEINIT_LCD: | ||
1170 | lcd_remote_off(); | ||
1171 | break; | ||
1172 | } | ||
1173 | |||
1174 | delay = next_tick - current_tick - 1; | ||
1175 | if (delay >= 0) | ||
1176 | continue; | 1090 | continue; |
1177 | #endif | ||
1178 | 1091 | ||
1179 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | 1092 | s = &lcd_remote_scroll_info.scroll[index]; |
1180 | /* really scroll? */ | ||
1181 | if ( !(scrolling_lines&(1<<index)) ) | ||
1182 | continue; | ||
1183 | 1093 | ||
1184 | s = &scroll[index]; | 1094 | /* check pause */ |
1185 | 1095 | if (TIME_BEFORE(current_tick, s->start_tick)) | |
1186 | /* check pause */ | 1096 | continue; |
1187 | if (TIME_BEFORE(current_tick, s->start_tick)) | ||
1188 | continue; | ||
1189 | 1097 | ||
1190 | if (s->backward) | 1098 | if (s->backward) |
1191 | s->offset -= scroll_step; | 1099 | s->offset -= lcd_remote_scroll_info.step; |
1192 | else | 1100 | else |
1193 | s->offset += scroll_step; | 1101 | s->offset += lcd_remote_scroll_info.step; |
1194 | 1102 | ||
1195 | pf = font_get(curfont); | 1103 | pf = font_get(curfont); |
1196 | xpos = s->startx; | 1104 | xpos = s->startx; |
1197 | ypos = ymargin + index * pf->height; | 1105 | ypos = ymargin + index * pf->height; |
1198 | 1106 | ||
1199 | if (s->bidir) { /* scroll bidirectional */ | 1107 | if (s->bidir) { /* scroll bidirectional */ |
1200 | if (s->offset <= 0) { | 1108 | if (s->offset <= 0) { |
1201 | /* at beginning of line */ | 1109 | /* at beginning of line */ |
1202 | s->offset = 0; | 1110 | s->offset = 0; |
1203 | s->backward = false; | 1111 | s->backward = false; |
1204 | s->start_tick = current_tick + scroll_delay * 2; | 1112 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; |
1205 | } | ||
1206 | if (s->offset >= s->width - (LCD_REMOTE_WIDTH - xpos)) { | ||
1207 | /* at end of line */ | ||
1208 | s->offset = s->width - (LCD_REMOTE_WIDTH - xpos); | ||
1209 | s->backward = true; | ||
1210 | s->start_tick = current_tick + scroll_delay * 2; | ||
1211 | } | ||
1212 | } | 1113 | } |
1213 | else { | 1114 | if (s->offset >= s->width - (LCD_REMOTE_WIDTH - xpos)) { |
1214 | /* scroll forward the whole time */ | 1115 | /* at end of line */ |
1215 | if (s->offset >= s->width) | 1116 | s->offset = s->width - (LCD_REMOTE_WIDTH - xpos); |
1216 | s->offset %= s->width; | 1117 | s->backward = true; |
1118 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; | ||
1217 | } | 1119 | } |
1218 | |||
1219 | lastmode = drawmode; | ||
1220 | drawmode = s->invert ? | ||
1221 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | ||
1222 | lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); | ||
1223 | drawmode = lastmode; | ||
1224 | lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); | ||
1225 | } | 1120 | } |
1226 | 1121 | else { | |
1227 | 1122 | /* scroll forward the whole time */ | |
1228 | next_tick += scroll_ticks; | 1123 | if (s->offset >= s->width) |
1229 | delay = next_tick - current_tick - 1; | 1124 | s->offset %= s->width; |
1230 | if (delay < 0) | ||
1231 | { | ||
1232 | next_tick = current_tick + 1; | ||
1233 | delay = 0; | ||
1234 | } | 1125 | } |
1126 | |||
1127 | lastmode = drawmode; | ||
1128 | drawmode = s->invert ? | ||
1129 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | ||
1130 | lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); | ||
1131 | drawmode = lastmode; | ||
1132 | lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); | ||
1235 | } | 1133 | } |
1236 | } | 1134 | } |
1237 | 1135 | ||
@@ -1241,10 +1139,5 @@ void lcd_remote_init(void) | |||
1241 | #ifndef SIMULATOR | 1139 | #ifndef SIMULATOR |
1242 | /* Call device specific init */ | 1140 | /* Call device specific init */ |
1243 | lcd_remote_init_device(); | 1141 | lcd_remote_init_device(); |
1244 | /* private queue */ | ||
1245 | queue_init(&remote_scroll_queue, false); | ||
1246 | #endif | 1142 | #endif |
1247 | create_thread(scroll_thread, scroll_stack, | ||
1248 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) | ||
1249 | IF_COP(, CPU, false)); | ||
1250 | } | 1143 | } |