diff options
Diffstat (limited to 'firmware/drivers/lcd-16bit.c')
-rw-r--r-- | firmware/drivers/lcd-16bit.c | 213 |
1 files changed, 70 insertions, 143 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index 96711248ff..bd5d09368c 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c | |||
@@ -33,8 +33,7 @@ | |||
33 | #include "font.h" | 33 | #include "font.h" |
34 | #include "rbunicode.h" | 34 | #include "rbunicode.h" |
35 | #include "bidi.h" | 35 | #include "bidi.h" |
36 | 36 | #include "scroll_engine.h" | |
37 | #define SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32) | ||
38 | 37 | ||
39 | enum fill_opt { | 38 | enum fill_opt { |
40 | OPT_NONE = 0, | 39 | OPT_NONE = 0, |
@@ -62,23 +61,6 @@ static int xmargin = 0; | |||
62 | static int ymargin = 0; | 61 | static int ymargin = 0; |
63 | static int curfont = FONT_SYSFIXED; | 62 | static int curfont = FONT_SYSFIXED; |
64 | 63 | ||
65 | /* scrolling */ | ||
66 | static volatile int scrolling_lines = 0; /* Bitpattern of which lines are scrolling */ | ||
67 | static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; | ||
68 | static const char scroll_name[] = "scroll"; | ||
69 | static void scroll_thread(void); | ||
70 | static int scroll_ticks = 12; /* # of ticks between updates*/ | ||
71 | static int scroll_delay = HZ/2; /* ticks delay before start */ | ||
72 | static int scroll_step = 6; /* pixels per scroll step */ | ||
73 | static int bidir_limit = 50; /* percent */ | ||
74 | static struct scrollinfo scroll[SCROLLABLE_LINES]; | ||
75 | |||
76 | static const char scroll_tick_table[16] = { | ||
77 | /* Hz values: | ||
78 | 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ | ||
79 | 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 | ||
80 | }; | ||
81 | |||
82 | /* LCD init */ | 64 | /* LCD init */ |
83 | void lcd_init(void) | 65 | void lcd_init(void) |
84 | { | 66 | { |
@@ -86,12 +68,7 @@ void lcd_init(void) | |||
86 | 68 | ||
87 | /* Call device specific init */ | 69 | /* Call device specific init */ |
88 | lcd_init_device(); | 70 | lcd_init_device(); |
89 | 71 | scroll_init(); | |
90 | |||
91 | create_thread(scroll_thread, scroll_stack, | ||
92 | sizeof(scroll_stack), scroll_name | ||
93 | IF_PRIO(, PRIORITY_USER_INTERFACE) | ||
94 | IF_COP(, CPU, false)); | ||
95 | } | 72 | } |
96 | 73 | ||
97 | /*** parameter handling ***/ | 74 | /*** parameter handling ***/ |
@@ -243,7 +220,8 @@ void lcd_clear_display(void) | |||
243 | else | 220 | else |
244 | memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); | 221 | memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); |
245 | } | 222 | } |
246 | scrolling_lines = 0; | 223 | |
224 | lcd_scroll_info.lines = 0; | ||
247 | } | 225 | } |
248 | 226 | ||
249 | /* Set a single pixel */ | 227 | /* Set a single pixel */ |
@@ -819,7 +797,7 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style, | |||
819 | int oldbgcolor = bg_pattern; | 797 | int oldbgcolor = bg_pattern; |
820 | 798 | ||
821 | /* make sure scrolling is turned off on the line we are updating */ | 799 | /* make sure scrolling is turned off on the line we are updating */ |
822 | scrolling_lines &= ~(1 << y); | 800 | lcd_scroll_info.lines &= ~(1 << y); |
823 | 801 | ||
824 | if(!str || !str[0]) | 802 | if(!str || !str[0]) |
825 | return; | 803 | return; |
@@ -845,46 +823,6 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style, | |||
845 | } | 823 | } |
846 | 824 | ||
847 | /*** scrolling ***/ | 825 | /*** scrolling ***/ |
848 | |||
849 | /* Reverse the invert setting of the scrolling line (if any) at given char | ||
850 | position. Setting will go into affect next time line scrolls. */ | ||
851 | void lcd_invertscroll(int x, int y) | ||
852 | { | ||
853 | struct scrollinfo* s; | ||
854 | |||
855 | (void)x; | ||
856 | |||
857 | if(y>=SCROLLABLE_LINES) return; | ||
858 | |||
859 | s = &scroll[y]; | ||
860 | s->invert = !s->invert; | ||
861 | } | ||
862 | |||
863 | void lcd_stop_scroll(void) | ||
864 | { | ||
865 | scrolling_lines=0; | ||
866 | } | ||
867 | |||
868 | void lcd_scroll_speed(int speed) | ||
869 | { | ||
870 | scroll_ticks = scroll_tick_table[speed]; | ||
871 | } | ||
872 | |||
873 | void lcd_scroll_step(int step) | ||
874 | { | ||
875 | scroll_step = step; | ||
876 | } | ||
877 | |||
878 | void lcd_scroll_delay(int ms) | ||
879 | { | ||
880 | scroll_delay = ms / (HZ / 10); | ||
881 | } | ||
882 | |||
883 | void lcd_bidir_scroll(int percent) | ||
884 | { | ||
885 | bidir_limit = percent; | ||
886 | } | ||
887 | |||
888 | void lcd_puts_scroll(int x, int y, const unsigned char *string) | 826 | void lcd_puts_scroll(int x, int y, const unsigned char *string) |
889 | { | 827 | { |
890 | lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); | 828 | lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); |
@@ -906,11 +844,11 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
906 | struct scrollinfo* s; | 844 | struct scrollinfo* s; |
907 | int w, h; | 845 | int w, h; |
908 | 846 | ||
909 | if(y>=SCROLLABLE_LINES) return; | 847 | if(y>=LCD_SCROLLABLE_LINES) return; |
910 | 848 | ||
911 | s = &scroll[y]; | 849 | s = &lcd_scroll_info.scroll[y]; |
912 | 850 | ||
913 | s->start_tick = current_tick + scroll_delay; | 851 | s->start_tick = current_tick + lcd_scroll_info.delay; |
914 | s->invert = false; | 852 | s->invert = false; |
915 | if (style & STYLE_INVERT) { | 853 | if (style & STYLE_INVERT) { |
916 | s->invert = true; | 854 | s->invert = true; |
@@ -931,9 +869,9 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
931 | 869 | ||
932 | /* scroll bidirectional or forward only depending on the string | 870 | /* scroll bidirectional or forward only depending on the string |
933 | width */ | 871 | width */ |
934 | if ( bidir_limit ) { | 872 | if ( lcd_scroll_info.bidir_limit ) { |
935 | s->bidir = s->width < (LCD_WIDTH - xmargin) * | 873 | s->bidir = s->width < (LCD_WIDTH - xmargin) * |
936 | (100 + bidir_limit) / 100; | 874 | (100 + lcd_scroll_info.bidir_limit) / 100; |
937 | } | 875 | } |
938 | else | 876 | else |
939 | s->bidir = false; | 877 | s->bidir = false; |
@@ -951,95 +889,84 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
951 | s->offset = offset; | 889 | s->offset = offset; |
952 | s->startx = xmargin + x * s->width / s->len; | 890 | s->startx = xmargin + x * s->width / s->len; |
953 | s->backward = false; | 891 | s->backward = false; |
954 | s->line_colour = (style&STYLE_COLORED)? | 892 | s->line_color = (style&STYLE_COLORED)? |
955 | (style&STYLE_COLOR_MASK): -1; | 893 | (style&STYLE_COLOR_MASK): -1; |
956 | scrolling_lines |= (1<<y); | 894 | lcd_scroll_info.lines |= (1<<y); |
957 | } | 895 | } |
958 | else | 896 | else |
959 | /* force a bit switch-off since it doesn't scroll */ | 897 | /* force a bit switch-off since it doesn't scroll */ |
960 | scrolling_lines &= ~(1<<y); | 898 | lcd_scroll_info.lines &= ~(1<<y); |
961 | } | 899 | } |
962 | 900 | ||
963 | static void scroll_thread(void) | 901 | void lcd_scroll_fn(void) |
964 | { | 902 | { |
965 | struct font* pf; | 903 | struct font* pf; |
966 | struct scrollinfo* s; | 904 | struct scrollinfo* s; |
967 | int index; | 905 | int index; |
968 | int xpos, ypos; | 906 | int xpos, ypos; |
969 | int lastmode; | 907 | int lastmode; |
970 | unsigned old_bgcolour, old_fgcolour; | 908 | unsigned old_fgcolor = fg_pattern; |
909 | unsigned old_bgcolor = bg_pattern; | ||
971 | 910 | ||
972 | /* initialize scroll struct array */ | 911 | for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) { |
973 | scrolling_lines = 0; | 912 | /* really scroll? */ |
913 | if ((lcd_scroll_info.lines & (1 << index)) == 0) | ||
914 | continue; | ||
974 | 915 | ||
975 | while ( 1 ) { | 916 | s = &lcd_scroll_info.scroll[index]; |
976 | if(!lcd_enabled()) { | 917 | |
977 | sleep(scroll_ticks); | 918 | /* check pause */ |
919 | if (TIME_BEFORE(current_tick, s->start_tick)) | ||
978 | continue; | 920 | continue; |
979 | } | 921 | |
980 | old_fgcolour = lcd_get_foreground(); | 922 | if (s->line_color >= 0) { |
981 | old_bgcolour = lcd_get_background(); | 923 | if (s->invert) { |
982 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | 924 | fg_pattern = old_fgcolor; |
983 | /* really scroll? */ | 925 | bg_pattern = s->line_color; |
984 | if ( !(scrolling_lines&(1<<index)) ) | ||
985 | continue; | ||
986 | |||
987 | s = &scroll[index]; | ||
988 | /* check pause */ | ||
989 | if (TIME_BEFORE(current_tick, s->start_tick)) | ||
990 | continue; | ||
991 | if (s->line_colour >= 0) | ||
992 | { | ||
993 | if (s->invert) | ||
994 | { | ||
995 | lcd_set_foreground(old_fgcolour); | ||
996 | lcd_set_background(s->line_colour); | ||
997 | } | ||
998 | else | ||
999 | { | ||
1000 | lcd_set_foreground(s->line_colour); | ||
1001 | lcd_set_background(old_bgcolour); | ||
1002 | } | ||
1003 | } | ||
1004 | |||
1005 | if (s->backward) | ||
1006 | s->offset -= scroll_step; | ||
1007 | else | ||
1008 | s->offset += scroll_step; | ||
1009 | |||
1010 | pf = font_get(curfont); | ||
1011 | xpos = s->startx; | ||
1012 | ypos = ymargin + index * pf->height; | ||
1013 | |||
1014 | if (s->bidir) { /* scroll bidirectional */ | ||
1015 | if (s->offset <= 0) { | ||
1016 | /* at beginning of line */ | ||
1017 | s->offset = 0; | ||
1018 | s->backward = false; | ||
1019 | s->start_tick = current_tick + scroll_delay * 2; | ||
1020 | } | ||
1021 | if (s->offset >= s->width - (LCD_WIDTH - xpos)) { | ||
1022 | /* at end of line */ | ||
1023 | s->offset = s->width - (LCD_WIDTH - xpos); | ||
1024 | s->backward = true; | ||
1025 | s->start_tick = current_tick + scroll_delay * 2; | ||
1026 | } | ||
1027 | } | 926 | } |
1028 | else { | 927 | else { |
1029 | /* scroll forward the whole time */ | 928 | fg_pattern = s->line_color; |
1030 | if (s->offset >= s->width) | 929 | bg_pattern = old_bgcolor; |
1031 | s->offset %= s->width; | ||
1032 | } | 930 | } |
931 | } | ||
1033 | 932 | ||
1034 | lastmode = drawmode; | 933 | if (s->backward) |
1035 | drawmode = s->invert ? | 934 | s->offset -= lcd_scroll_info.step; |
1036 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 935 | else |
1037 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | 936 | s->offset += lcd_scroll_info.step; |
1038 | drawmode = lastmode; | 937 | |
1039 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | 938 | pf = font_get(curfont); |
939 | xpos = s->startx; | ||
940 | ypos = ymargin + index * pf->height; | ||
941 | |||
942 | if (s->bidir) { /* scroll bidirectional */ | ||
943 | if (s->offset <= 0) { | ||
944 | /* at beginning of line */ | ||
945 | s->offset = 0; | ||
946 | s->backward = false; | ||
947 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | ||
948 | } | ||
949 | if (s->offset >= s->width - (LCD_WIDTH - xpos)) { | ||
950 | /* at end of line */ | ||
951 | s->offset = s->width - (LCD_WIDTH - xpos); | ||
952 | s->backward = true; | ||
953 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | ||
954 | } | ||
955 | } | ||
956 | else { | ||
957 | /* scroll forward the whole time */ | ||
958 | if (s->offset >= s->width) | ||
959 | s->offset %= s->width; | ||
1040 | } | 960 | } |
1041 | lcd_set_foreground(old_fgcolour); | 961 | |
1042 | lcd_set_background(old_bgcolour); | 962 | lastmode = drawmode; |
1043 | sleep(scroll_ticks); | 963 | drawmode = s->invert ? |
964 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | ||
965 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | ||
966 | drawmode = lastmode; | ||
967 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
1044 | } | 968 | } |
969 | |||
970 | fg_pattern = old_fgcolor; | ||
971 | bg_pattern = old_bgcolor; | ||
1045 | } | 972 | } |