diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-07-28 08:12:05 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-07-28 08:12:05 +0000 |
commit | 58fc279d2674b5d56fed6772f82cdf1e431088f1 (patch) | |
tree | 07a174bba7430b0ebc3c0f84d39ecb209eec1fc5 /firmware/drivers | |
parent | 885cdfdeb98d54b2597e65f1b9ae9ab98da8286f (diff) | |
download | rockbox-58fc279d2674b5d56fed6772f82cdf1e431088f1.tar.gz rockbox-58fc279d2674b5d56fed6772f82cdf1e431088f1.zip |
Scroll on main and remote with a single thread. Change the way system messages are defined before running out is an issue (which requires a full update of rockbox on the player).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14035 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/lcd-16bit.c | 213 | ||||
-rw-r--r-- | firmware/drivers/lcd-1bit-vert.c | 177 | ||||
-rw-r--r-- | firmware/drivers/lcd-2bit-horz.c | 176 | ||||
-rw-r--r-- | firmware/drivers/lcd-2bit-vert.c | 176 | ||||
-rw-r--r-- | firmware/drivers/lcd-charcell.c | 184 | ||||
-rw-r--r-- | firmware/drivers/lcd-remote-1bit-v.c | 216 | ||||
-rw-r--r-- | firmware/drivers/lcd-remote-2bit-vi.c | 219 |
7 files changed, 414 insertions, 947 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 | } |
diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c index b54238d085..ac50eff95c 100644 --- a/firmware/drivers/lcd-1bit-vert.c +++ b/firmware/drivers/lcd-1bit-vert.c | |||
@@ -29,10 +29,7 @@ | |||
29 | #include "font.h" | 29 | #include "font.h" |
30 | #include "rbunicode.h" | 30 | #include "rbunicode.h" |
31 | #include "bidi.h" | 31 | #include "bidi.h" |
32 | 32 | #include "scroll_engine.h" | |
33 | /*** definitions ***/ | ||
34 | |||
35 | #define SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32) | ||
36 | 33 | ||
37 | /*** globals ***/ | 34 | /*** globals ***/ |
38 | 35 | ||
@@ -43,32 +40,13 @@ static int xmargin = 0; | |||
43 | static int ymargin = 0; | 40 | static int ymargin = 0; |
44 | static int curfont = FONT_SYSFIXED; | 41 | static int curfont = FONT_SYSFIXED; |
45 | 42 | ||
46 | /* scrolling */ | ||
47 | static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ | ||
48 | static void scroll_thread(void); | ||
49 | static char scroll_stack[DEFAULT_STACK_SIZE]; | ||
50 | static const char scroll_name[] = "scroll"; | ||
51 | static int scroll_ticks = 12; /* # of ticks between updates*/ | ||
52 | static int scroll_delay = HZ/2; /* ticks delay before start */ | ||
53 | static int scroll_step = 6; /* pixels per scroll step */ | ||
54 | static int bidir_limit = 50; /* percent */ | ||
55 | static struct scrollinfo scroll[SCROLLABLE_LINES]; | ||
56 | |||
57 | static const char scroll_tick_table[16] = { | ||
58 | /* Hz values: | ||
59 | 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ | ||
60 | 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 | ||
61 | }; | ||
62 | |||
63 | /* LCD init */ | 43 | /* LCD init */ |
64 | void lcd_init(void) | 44 | void lcd_init(void) |
65 | { | 45 | { |
66 | lcd_clear_display(); | 46 | lcd_clear_display(); |
67 | /* Call device specific init */ | 47 | /* Call device specific init */ |
68 | lcd_init_device(); | 48 | lcd_init_device(); |
69 | create_thread(scroll_thread, scroll_stack, | 49 | scroll_init(); |
70 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) | ||
71 | IF_COP(, CPU, false)); | ||
72 | } | 50 | } |
73 | 51 | ||
74 | /*** parameter handling ***/ | 52 | /*** parameter handling ***/ |
@@ -104,6 +82,11 @@ void lcd_setfont(int newfont) | |||
104 | curfont = newfont; | 82 | curfont = newfont; |
105 | } | 83 | } |
106 | 84 | ||
85 | int lcd_getfont(void) | ||
86 | { | ||
87 | return curfont; | ||
88 | } | ||
89 | |||
107 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) | 90 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) |
108 | { | 91 | { |
109 | return font_getstringsize(str, w, h, curfont); | 92 | return font_getstringsize(str, w, h, curfont); |
@@ -212,7 +195,7 @@ void lcd_clear_display(void) | |||
212 | unsigned bits = (drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; | 195 | unsigned bits = (drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; |
213 | 196 | ||
214 | memset(lcd_framebuffer, bits, sizeof lcd_framebuffer); | 197 | memset(lcd_framebuffer, bits, sizeof lcd_framebuffer); |
215 | scrolling_lines = 0; | 198 | lcd_scroll_info.lines = 0; |
216 | } | 199 | } |
217 | 200 | ||
218 | /* Set a single pixel */ | 201 | /* Set a single pixel */ |
@@ -664,7 +647,7 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, | |||
664 | int lastmode = drawmode; | 647 | int lastmode = drawmode; |
665 | 648 | ||
666 | /* make sure scrolling is turned off on the line we are updating */ | 649 | /* make sure scrolling is turned off on the line we are updating */ |
667 | scrolling_lines &= ~(1 << y); | 650 | lcd_scroll_info.lines &= ~(1 << y); |
668 | 651 | ||
669 | if(!str || !str[0]) | 652 | if(!str || !str[0]) |
670 | return; | 653 | return; |
@@ -682,46 +665,6 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, | |||
682 | } | 665 | } |
683 | 666 | ||
684 | /*** scrolling ***/ | 667 | /*** scrolling ***/ |
685 | |||
686 | /* Reverse the invert setting of the scrolling line (if any) at given char | ||
687 | position. Setting will go into affect next time line scrolls. */ | ||
688 | void lcd_invertscroll(int x, int y) | ||
689 | { | ||
690 | struct scrollinfo* s; | ||
691 | |||
692 | (void)x; | ||
693 | |||
694 | if(y>=SCROLLABLE_LINES) return; | ||
695 | |||
696 | s = &scroll[y]; | ||
697 | s->invert = !s->invert; | ||
698 | } | ||
699 | |||
700 | void lcd_stop_scroll(void) | ||
701 | { | ||
702 | scrolling_lines=0; | ||
703 | } | ||
704 | |||
705 | void lcd_scroll_speed(int speed) | ||
706 | { | ||
707 | scroll_ticks = scroll_tick_table[speed]; | ||
708 | } | ||
709 | |||
710 | void lcd_scroll_step(int step) | ||
711 | { | ||
712 | scroll_step = step; | ||
713 | } | ||
714 | |||
715 | void lcd_scroll_delay(int ms) | ||
716 | { | ||
717 | scroll_delay = ms / (HZ / 10); | ||
718 | } | ||
719 | |||
720 | void lcd_bidir_scroll(int percent) | ||
721 | { | ||
722 | bidir_limit = percent; | ||
723 | } | ||
724 | |||
725 | void lcd_puts_scroll(int x, int y, const unsigned char *string) | 668 | void lcd_puts_scroll(int x, int y, const unsigned char *string) |
726 | { | 669 | { |
727 | lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); | 670 | lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); |
@@ -744,11 +687,11 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
744 | struct scrollinfo* s; | 687 | struct scrollinfo* s; |
745 | int w, h; | 688 | int w, h; |
746 | 689 | ||
747 | if(y>=SCROLLABLE_LINES) return; | 690 | if(y>=LCD_SCROLLABLE_LINES) return; |
748 | 691 | ||
749 | s = &scroll[y]; | 692 | s = &lcd_scroll_info.scroll[y]; |
750 | 693 | ||
751 | s->start_tick = current_tick + scroll_delay; | 694 | s->start_tick = current_tick + lcd_scroll_info.delay; |
752 | s->invert = false; | 695 | s->invert = false; |
753 | if (style & STYLE_INVERT) { | 696 | if (style & STYLE_INVERT) { |
754 | s->invert = true; | 697 | s->invert = true; |
@@ -771,9 +714,9 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
771 | 714 | ||
772 | /* scroll bidirectional or forward only depending on the string | 715 | /* scroll bidirectional or forward only depending on the string |
773 | width */ | 716 | width */ |
774 | if ( bidir_limit ) { | 717 | if ( lcd_scroll_info.bidir_limit ) { |
775 | s->bidir = s->width < (LCD_WIDTH - xmargin) * | 718 | s->bidir = s->width < (LCD_WIDTH - xmargin) * |
776 | (100 + bidir_limit) / 100; | 719 | (100 + lcd_scroll_info.bidir_limit) / 100; |
777 | } | 720 | } |
778 | else | 721 | else |
779 | s->bidir = false; | 722 | s->bidir = false; |
@@ -791,14 +734,14 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
791 | s->offset = offset; | 734 | s->offset = offset; |
792 | s->startx = xmargin + x * s->width / s->len;; | 735 | s->startx = xmargin + x * s->width / s->len;; |
793 | s->backward = false; | 736 | s->backward = false; |
794 | scrolling_lines |= (1<<y); | 737 | lcd_scroll_info.lines |= (1<<y); |
795 | } | 738 | } |
796 | else | 739 | else |
797 | /* force a bit switch-off since it doesn't scroll */ | 740 | /* force a bit switch-off since it doesn't scroll */ |
798 | scrolling_lines &= ~(1<<y); | 741 | lcd_scroll_info.lines &= ~(1<<y); |
799 | } | 742 | } |
800 | 743 | ||
801 | static void scroll_thread(void) | 744 | void lcd_scroll_fn(void) |
802 | { | 745 | { |
803 | struct font* pf; | 746 | struct font* pf; |
804 | struct scrollinfo* s; | 747 | struct scrollinfo* s; |
@@ -806,59 +749,51 @@ static void scroll_thread(void) | |||
806 | int xpos, ypos; | 749 | int xpos, ypos; |
807 | int lastmode; | 750 | int lastmode; |
808 | 751 | ||
809 | /* initialize scroll struct array */ | 752 | for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) { |
810 | scrolling_lines = 0; | 753 | /* really scroll? */ |
811 | 754 | if ((lcd_scroll_info.lines & (1 << index)) == 0) | |
812 | while ( 1 ) { | 755 | continue; |
813 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | ||
814 | /* really scroll? */ | ||
815 | if ( !(scrolling_lines&(1<<index)) ) | ||
816 | continue; | ||
817 | 756 | ||
818 | s = &scroll[index]; | 757 | s = &lcd_scroll_info.scroll[index]; |
819 | 758 | ||
820 | /* check pause */ | 759 | /* check pause */ |
821 | if (TIME_BEFORE(current_tick, s->start_tick)) | 760 | if (TIME_BEFORE(current_tick, s->start_tick)) |
822 | continue; | 761 | continue; |
823 | 762 | ||
824 | if (s->backward) | 763 | if (s->backward) |
825 | s->offset -= scroll_step; | 764 | s->offset -= lcd_scroll_info.step; |
826 | else | 765 | else |
827 | s->offset += scroll_step; | 766 | s->offset += lcd_scroll_info.step; |
828 | 767 | ||
829 | pf = font_get(curfont); | 768 | pf = font_get(curfont); |
830 | xpos = s->startx; | 769 | xpos = s->startx; |
831 | ypos = ymargin + index * pf->height; | 770 | ypos = ymargin + index * pf->height; |
832 | 771 | ||
833 | if (s->bidir) { /* scroll bidirectional */ | 772 | if (s->bidir) { /* scroll bidirectional */ |
834 | if (s->offset <= 0) { | 773 | if (s->offset <= 0) { |
835 | /* at beginning of line */ | 774 | /* at beginning of line */ |
836 | s->offset = 0; | 775 | s->offset = 0; |
837 | s->backward = false; | 776 | s->backward = false; |
838 | s->start_tick = current_tick + scroll_delay * 2; | 777 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; |
839 | } | ||
840 | if (s->offset >= s->width - (LCD_WIDTH - xpos)) { | ||
841 | /* at end of line */ | ||
842 | s->offset = s->width - (LCD_WIDTH - xpos); | ||
843 | s->backward = true; | ||
844 | s->start_tick = current_tick + scroll_delay * 2; | ||
845 | } | ||
846 | } | 778 | } |
847 | else { | 779 | if (s->offset >= s->width - (LCD_WIDTH - xpos)) { |
848 | /* scroll forward the whole time */ | 780 | /* at end of line */ |
849 | if (s->offset >= s->width) | 781 | s->offset = s->width - (LCD_WIDTH - xpos); |
850 | s->offset %= s->width; | 782 | s->backward = true; |
783 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | ||
851 | } | 784 | } |
852 | 785 | } | |
853 | lastmode = drawmode; | 786 | else { |
854 | drawmode = s->invert ? | 787 | /* scroll forward the whole time */ |
855 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 788 | if (s->offset >= s->width) |
856 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | 789 | s->offset %= s->width; |
857 | drawmode = lastmode; | ||
858 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
859 | } | 790 | } |
860 | 791 | ||
861 | sleep(scroll_ticks); | 792 | lastmode = drawmode; |
793 | drawmode = s->invert ? | ||
794 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | ||
795 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | ||
796 | drawmode = lastmode; | ||
797 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
862 | } | 798 | } |
863 | } | 799 | } |
864 | |||
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c index d3d086a9d2..48fd22f703 100644 --- a/firmware/drivers/lcd-2bit-horz.c +++ b/firmware/drivers/lcd-2bit-horz.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 | /*** globals ***/ | 38 | /*** globals ***/ |
40 | 39 | ||
@@ -54,33 +53,13 @@ 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[] = "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 | |||
75 | /* LCD init */ | 56 | /* LCD init */ |
76 | void lcd_init(void) | 57 | void lcd_init(void) |
77 | { | 58 | { |
78 | lcd_clear_display(); | 59 | lcd_clear_display(); |
79 | /* Call device specific init */ | 60 | /* Call device specific init */ |
80 | lcd_init_device(); | 61 | lcd_init_device(); |
81 | create_thread(scroll_thread, scroll_stack, | 62 | scroll_init(); |
82 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) | ||
83 | IF_COP(, CPU, false)); | ||
84 | } | 63 | } |
85 | 64 | ||
86 | /*** parameter handling ***/ | 65 | /*** parameter handling ***/ |
@@ -143,6 +122,11 @@ void lcd_setfont(int newfont) | |||
143 | curfont = newfont; | 122 | curfont = newfont; |
144 | } | 123 | } |
145 | 124 | ||
125 | int lcd_getfont(void) | ||
126 | { | ||
127 | return curfont; | ||
128 | } | ||
129 | |||
146 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) | 130 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) |
147 | { | 131 | { |
148 | return font_getstringsize(str, w, h, curfont); | 132 | return font_getstringsize(str, w, h, curfont); |
@@ -377,7 +361,8 @@ void lcd_clear_display(void) | |||
377 | else | 361 | else |
378 | memset(lcd_framebuffer, bg_pattern, sizeof lcd_framebuffer); | 362 | memset(lcd_framebuffer, bg_pattern, sizeof lcd_framebuffer); |
379 | } | 363 | } |
380 | scrolling_lines = 0; | 364 | |
365 | lcd_scroll_info.lines = 0; | ||
381 | } | 366 | } |
382 | 367 | ||
383 | /* Set a single pixel */ | 368 | /* Set a single pixel */ |
@@ -862,7 +847,7 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, | |||
862 | int lastmode = drawmode; | 847 | int lastmode = drawmode; |
863 | 848 | ||
864 | /* make sure scrolling is turned off on the line we are updating */ | 849 | /* make sure scrolling is turned off on the line we are updating */ |
865 | scrolling_lines &= ~(1 << y); | 850 | lcd_scroll_info.lines &= ~(1 << y); |
866 | 851 | ||
867 | if(!str || !str[0]) | 852 | if(!str || !str[0]) |
868 | return; | 853 | return; |
@@ -880,46 +865,6 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, | |||
880 | } | 865 | } |
881 | 866 | ||
882 | /*** scrolling ***/ | 867 | /*** scrolling ***/ |
883 | |||
884 | /* Reverse the invert setting of the scrolling line (if any) at given char | ||
885 | position. Setting will go into affect next time line scrolls. */ | ||
886 | void lcd_invertscroll(int x, int y) | ||
887 | { | ||
888 | struct scrollinfo* s; | ||
889 | |||
890 | (void)x; | ||
891 | |||
892 | if(y>=SCROLLABLE_LINES) return; | ||
893 | |||
894 | s = &scroll[y]; | ||
895 | s->invert = !s->invert; | ||
896 | } | ||
897 | |||
898 | void lcd_stop_scroll(void) | ||
899 | { | ||
900 | scrolling_lines=0; | ||
901 | } | ||
902 | |||
903 | void lcd_scroll_speed(int speed) | ||
904 | { | ||
905 | scroll_ticks = scroll_tick_table[speed]; | ||
906 | } | ||
907 | |||
908 | void lcd_scroll_step(int step) | ||
909 | { | ||
910 | scroll_step = step; | ||
911 | } | ||
912 | |||
913 | void lcd_scroll_delay(int ms) | ||
914 | { | ||
915 | scroll_delay = ms / (HZ / 10); | ||
916 | } | ||
917 | |||
918 | void lcd_bidir_scroll(int percent) | ||
919 | { | ||
920 | bidir_limit = percent; | ||
921 | } | ||
922 | |||
923 | void lcd_puts_scroll(int x, int y, const unsigned char *string) | 868 | void lcd_puts_scroll(int x, int y, const unsigned char *string) |
924 | { | 869 | { |
925 | lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); | 870 | lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); |
@@ -941,11 +886,11 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
941 | struct scrollinfo* s; | 886 | struct scrollinfo* s; |
942 | int w, h; | 887 | int w, h; |
943 | 888 | ||
944 | if(y>=SCROLLABLE_LINES) return; | 889 | if(y>=LCD_SCROLLABLE_LINES) return; |
945 | 890 | ||
946 | s = &scroll[y]; | 891 | s = &lcd_scroll_info.scroll[y]; |
947 | 892 | ||
948 | s->start_tick = current_tick + scroll_delay; | 893 | s->start_tick = current_tick + lcd_scroll_info.delay; |
949 | s->invert = false; | 894 | s->invert = false; |
950 | if (style & STYLE_INVERT) { | 895 | if (style & STYLE_INVERT) { |
951 | s->invert = true; | 896 | s->invert = true; |
@@ -968,9 +913,9 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
968 | 913 | ||
969 | /* scroll bidirectional or forward only depending on the string | 914 | /* scroll bidirectional or forward only depending on the string |
970 | width */ | 915 | width */ |
971 | if ( bidir_limit ) { | 916 | if ( lcd_scroll_info.bidir_limit ) { |
972 | s->bidir = s->width < (LCD_WIDTH - xmargin) * | 917 | s->bidir = s->width < (LCD_WIDTH - xmargin) * |
973 | (100 + bidir_limit) / 100; | 918 | (100 + lcd_scroll_info.bidir_limit) / 100; |
974 | } | 919 | } |
975 | else | 920 | else |
976 | s->bidir = false; | 921 | s->bidir = false; |
@@ -988,14 +933,14 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
988 | s->offset = offset; | 933 | s->offset = offset; |
989 | s->startx = xmargin + x * s->width / s->len;; | 934 | s->startx = xmargin + x * s->width / s->len;; |
990 | s->backward = false; | 935 | s->backward = false; |
991 | scrolling_lines |= (1<<y); | 936 | lcd_scroll_info.lines |= (1<<y); |
992 | } | 937 | } |
993 | else | 938 | else |
994 | /* force a bit switch-off since it doesn't scroll */ | 939 | /* force a bit switch-off since it doesn't scroll */ |
995 | scrolling_lines &= ~(1<<y); | 940 | lcd_scroll_info.lines &= ~(1<<y); |
996 | } | 941 | } |
997 | 942 | ||
998 | static void scroll_thread(void) | 943 | void lcd_scroll_fn(void) |
999 | { | 944 | { |
1000 | struct font* pf; | 945 | struct font* pf; |
1001 | struct scrollinfo* s; | 946 | struct scrollinfo* s; |
@@ -1003,58 +948,51 @@ static void scroll_thread(void) | |||
1003 | int xpos, ypos; | 948 | int xpos, ypos; |
1004 | int lastmode; | 949 | int lastmode; |
1005 | 950 | ||
1006 | /* initialize scroll struct array */ | 951 | for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) { |
1007 | scrolling_lines = 0; | 952 | /* really scroll? */ |
1008 | 953 | if ((lcd_scroll_info.lines & (1 << index)) == 0) | |
1009 | while ( 1 ) { | 954 | continue; |
1010 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | ||
1011 | /* really scroll? */ | ||
1012 | if ( !(scrolling_lines&(1<<index)) ) | ||
1013 | continue; | ||
1014 | 955 | ||
1015 | s = &scroll[index]; | 956 | s = &lcd_scroll_info.scroll[index]; |
1016 | 957 | ||
1017 | /* check pause */ | 958 | /* check pause */ |
1018 | if (TIME_BEFORE(current_tick, s->start_tick)) | 959 | if (TIME_BEFORE(current_tick, s->start_tick)) |
1019 | continue; | 960 | continue; |
1020 | 961 | ||
1021 | if (s->backward) | 962 | if (s->backward) |
1022 | s->offset -= scroll_step; | 963 | s->offset -= lcd_scroll_info.step; |
1023 | else | 964 | else |
1024 | s->offset += scroll_step; | 965 | s->offset += lcd_scroll_info.step; |
1025 | 966 | ||
1026 | pf = font_get(curfont); | 967 | pf = font_get(curfont); |
1027 | xpos = s->startx; | 968 | xpos = s->startx; |
1028 | ypos = ymargin + index * pf->height; | 969 | ypos = ymargin + index * pf->height; |
1029 | 970 | ||
1030 | if (s->bidir) { /* scroll bidirectional */ | 971 | if (s->bidir) { /* scroll bidirectional */ |
1031 | if (s->offset <= 0) { | 972 | if (s->offset <= 0) { |
1032 | /* at beginning of line */ | 973 | /* at beginning of line */ |
1033 | s->offset = 0; | 974 | s->offset = 0; |
1034 | s->backward = false; | 975 | s->backward = false; |
1035 | s->start_tick = current_tick + scroll_delay * 2; | 976 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; |
1036 | } | ||
1037 | if (s->offset >= s->width - (LCD_WIDTH - xpos)) { | ||
1038 | /* at end of line */ | ||
1039 | s->offset = s->width - (LCD_WIDTH - xpos); | ||
1040 | s->backward = true; | ||
1041 | s->start_tick = current_tick + scroll_delay * 2; | ||
1042 | } | ||
1043 | } | 977 | } |
1044 | else { | 978 | if (s->offset >= s->width - (LCD_WIDTH - xpos)) { |
1045 | /* scroll forward the whole time */ | 979 | /* at end of line */ |
1046 | if (s->offset >= s->width) | 980 | s->offset = s->width - (LCD_WIDTH - xpos); |
1047 | s->offset %= s->width; | 981 | s->backward = true; |
982 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | ||
1048 | } | 983 | } |
1049 | 984 | } | |
1050 | lastmode = drawmode; | 985 | else { |
1051 | drawmode = s->invert ? | 986 | /* scroll forward the whole time */ |
1052 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 987 | if (s->offset >= s->width) |
1053 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | 988 | s->offset %= s->width; |
1054 | drawmode = lastmode; | ||
1055 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
1056 | } | 989 | } |
1057 | 990 | ||
1058 | sleep(scroll_ticks); | 991 | lastmode = drawmode; |
992 | drawmode = s->invert ? | ||
993 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | ||
994 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | ||
995 | drawmode = lastmode; | ||
996 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
1059 | } | 997 | } |
1060 | } | 998 | } |
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 | } |
diff --git a/firmware/drivers/lcd-charcell.c b/firmware/drivers/lcd-charcell.c index efc9aa5b1f..0fd41481c5 100644 --- a/firmware/drivers/lcd-charcell.c +++ b/firmware/drivers/lcd-charcell.c | |||
@@ -29,10 +29,10 @@ | |||
29 | #include "system.h" | 29 | #include "system.h" |
30 | #include "lcd-charcell.h" | 30 | #include "lcd-charcell.h" |
31 | #include "rbunicode.h" | 31 | #include "rbunicode.h" |
32 | #include "scroll_engine.h" | ||
32 | 33 | ||
33 | /** definitions **/ | 34 | /** definitions **/ |
34 | 35 | ||
35 | #define SCROLLABLE_LINES LCD_HEIGHT | ||
36 | #define VARIABLE_XCHARS 16 /* number of software user-definable characters */ | 36 | #define VARIABLE_XCHARS 16 /* number of software user-definable characters */ |
37 | /* There must be mappings for this many characters in the 0xe000 unicode range | 37 | /* There must be mappings for this many characters in the 0xe000 unicode range |
38 | * in lcd-charset-<target>.c */ | 38 | * in lcd-charset-<target>.c */ |
@@ -55,24 +55,6 @@ static int xspace; /* stores xhcar id of ' ' - often needed */ | |||
55 | static int xmargin = 0; | 55 | static int xmargin = 0; |
56 | static int ymargin = 0; | 56 | static int ymargin = 0; |
57 | 57 | ||
58 | /* scrolling */ | ||
59 | static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ | ||
60 | static void scroll_thread(void); | ||
61 | static char scroll_stack[DEFAULT_STACK_SIZE]; | ||
62 | static const char scroll_name[] = "scroll"; | ||
63 | static int scroll_ticks = 12; /* # of ticks between updates */ | ||
64 | static int scroll_delay = HZ/2; /* delay before starting scroll */ | ||
65 | static int bidir_limit = 50; /* percent */ | ||
66 | static int jump_scroll_delay = HZ/4; /* delay between jump scroll jumps */ | ||
67 | static int jump_scroll = 0; /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */ | ||
68 | static struct scrollinfo scroll[SCROLLABLE_LINES]; | ||
69 | |||
70 | static const char scroll_tick_table[16] = { | ||
71 | /* Hz values: | ||
72 | 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ | ||
73 | 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 | ||
74 | }; | ||
75 | |||
76 | /* LCD init */ | 58 | /* LCD init */ |
77 | void lcd_init (void) | 59 | void lcd_init (void) |
78 | { | 60 | { |
@@ -81,11 +63,7 @@ void lcd_init (void) | |||
81 | memset(lcd_patterns, 0, sizeof(lcd_patterns)); | 63 | memset(lcd_patterns, 0, sizeof(lcd_patterns)); |
82 | xspace = find_xchar(' '); | 64 | xspace = find_xchar(' '); |
83 | memset(lcd_charbuffer, xchar_info[xspace].hw_char, sizeof(lcd_charbuffer)); | 65 | memset(lcd_charbuffer, xchar_info[xspace].hw_char, sizeof(lcd_charbuffer)); |
84 | 66 | scroll_init(); | |
85 | create_thread(scroll_thread, scroll_stack, | ||
86 | sizeof(scroll_stack), scroll_name | ||
87 | IF_PRIO(, PRIORITY_USER_INTERFACE) | ||
88 | IF_COP(, CPU, false)); | ||
89 | } | 67 | } |
90 | 68 | ||
91 | /** parameter handling **/ | 69 | /** parameter handling **/ |
@@ -336,7 +314,7 @@ void lcd_put_cursor(int x, int y, unsigned long cursor_ucs) | |||
336 | lcd_cursor.x = x; | 314 | lcd_cursor.x = x; |
337 | lcd_cursor.y = y; | 315 | lcd_cursor.y = y; |
338 | lcd_cursor.downcount = 0; | 316 | lcd_cursor.downcount = 0; |
339 | lcd_cursor.divider = MAX((HZ/2) / scroll_ticks, 1); | 317 | lcd_cursor.divider = MAX((HZ/2) / lcd_scroll_info.ticks, 1); |
340 | } | 318 | } |
341 | 319 | ||
342 | /* Remove the cursor */ | 320 | /* Remove the cursor */ |
@@ -398,7 +376,7 @@ void lcd_puts_offset(int x, int y, const unsigned char *str, int offset) | |||
398 | return; | 376 | return; |
399 | 377 | ||
400 | /* make sure scrolling is turned off on the line we are updating */ | 378 | /* make sure scrolling is turned off on the line we are updating */ |
401 | scrolling_lines &= ~(1 << y); | 379 | lcd_scroll_info.lines &= ~(1 << y); |
402 | 380 | ||
403 | x = lcd_putsxyofs(x, y, offset, str); | 381 | x = lcd_putsxyofs(x, y, offset, str); |
404 | while (x < LCD_WIDTH) | 382 | while (x < LCD_WIDTH) |
@@ -406,37 +384,6 @@ void lcd_puts_offset(int x, int y, const unsigned char *str, int offset) | |||
406 | } | 384 | } |
407 | 385 | ||
408 | /** scrolling **/ | 386 | /** scrolling **/ |
409 | |||
410 | void lcd_stop_scroll(void) | ||
411 | { | ||
412 | scrolling_lines=0; | ||
413 | } | ||
414 | |||
415 | void lcd_scroll_speed(int speed) | ||
416 | { | ||
417 | scroll_ticks = scroll_tick_table[speed]; | ||
418 | } | ||
419 | |||
420 | void lcd_scroll_delay(int ms) | ||
421 | { | ||
422 | scroll_delay = ms / (HZ / 10); | ||
423 | } | ||
424 | |||
425 | void lcd_bidir_scroll(int percent) | ||
426 | { | ||
427 | bidir_limit = percent; | ||
428 | } | ||
429 | |||
430 | void lcd_jump_scroll(int mode) /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */ | ||
431 | { | ||
432 | jump_scroll = mode; | ||
433 | } | ||
434 | |||
435 | void lcd_jump_scroll_delay(int ms) | ||
436 | { | ||
437 | jump_scroll_delay = ms / (HZ / 10); | ||
438 | } | ||
439 | |||
440 | void lcd_puts_scroll(int x, int y, const unsigned char *string) | 387 | void lcd_puts_scroll(int x, int y, const unsigned char *string) |
441 | { | 388 | { |
442 | lcd_puts_scroll_offset(x, y, string, 0); | 389 | lcd_puts_scroll_offset(x, y, string, 0); |
@@ -448,11 +395,11 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, | |||
448 | struct scrollinfo* s; | 395 | struct scrollinfo* s; |
449 | int len; | 396 | int len; |
450 | 397 | ||
451 | if(y>=SCROLLABLE_LINES) return; | 398 | if(y>=LCD_SCROLLABLE_LINES) return; |
452 | 399 | ||
453 | s = &scroll[y]; | 400 | s = &lcd_scroll_info.scroll[y]; |
454 | 401 | ||
455 | s->start_tick = current_tick + scroll_delay; | 402 | s->start_tick = current_tick + lcd_scroll_info.delay; |
456 | 403 | ||
457 | lcd_puts_offset(x, y, string, offset); | 404 | lcd_puts_offset(x, y, string, offset); |
458 | len = utf8length(string); | 405 | len = utf8length(string); |
@@ -469,9 +416,10 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, | |||
469 | s->len = utf8length(s->line); | 416 | s->len = utf8length(s->line); |
470 | 417 | ||
471 | /* scroll bidirectional or forward only depending on the string width */ | 418 | /* scroll bidirectional or forward only depending on the string width */ |
472 | if (bidir_limit) | 419 | if (lcd_scroll_info.bidir_limit) |
473 | { | 420 | { |
474 | s->bidir = s->len < (LCD_WIDTH - xmargin) * (100 + bidir_limit) / 100; | 421 | s->bidir = s->len < (LCD_WIDTH - xmargin) * |
422 | (100 + lcd_scroll_info.bidir_limit) / 100; | ||
475 | } | 423 | } |
476 | else | 424 | else |
477 | s->bidir = false; | 425 | s->bidir = false; |
@@ -489,83 +437,77 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, | |||
489 | s->offset = offset; | 437 | s->offset = offset; |
490 | s->startx = xmargin + x; | 438 | s->startx = xmargin + x; |
491 | s->backward = false; | 439 | s->backward = false; |
492 | scrolling_lines |= (1<<y); | 440 | lcd_scroll_info.lines |= (1<<y); |
493 | } | 441 | } |
494 | else | 442 | else |
495 | /* force a bit switch-off since it doesn't scroll */ | 443 | /* force a bit switch-off since it doesn't scroll */ |
496 | scrolling_lines &= ~(1<<y); | 444 | lcd_scroll_info.lines &= ~(1<<y); |
497 | } | 445 | } |
498 | 446 | ||
499 | static void scroll_thread(void) | 447 | void lcd_scroll_fn(void) |
500 | { | 448 | { |
501 | struct scrollinfo* s; | 449 | struct scrollinfo* s; |
502 | int index; | 450 | int index; |
503 | int xpos, ypos; | 451 | int xpos, ypos; |
504 | bool update; | 452 | bool update; |
505 | 453 | ||
506 | /* initialize scroll struct array */ | 454 | update = false; |
507 | scrolling_lines = 0; | 455 | for (index = 0; index < LCD_SCROLLABLE_LINES; index++) |
508 | |||
509 | while (1) | ||
510 | { | 456 | { |
511 | update = false; | 457 | /* really scroll? */ |
512 | for (index = 0; index < SCROLLABLE_LINES; index++) | 458 | if ((lcd_scroll_info.lines & (1 << index)) == 0) |
459 | continue; | ||
460 | |||
461 | s = &lcd_scroll_info.scroll[index]; | ||
462 | |||
463 | /* check pause */ | ||
464 | if (TIME_BEFORE(current_tick, s->start_tick)) | ||
465 | continue; | ||
466 | |||
467 | if (s->backward) | ||
468 | s->offset--; | ||
469 | else | ||
470 | s->offset++; | ||
471 | |||
472 | xpos = s->startx; | ||
473 | ypos = ymargin + index; | ||
474 | |||
475 | if (s->bidir) /* scroll bidirectional */ | ||
513 | { | 476 | { |
514 | /* really scroll? */ | 477 | if (s->offset <= 0) { |
515 | if (!(scrolling_lines&(1<<index))) | 478 | /* at beginning of line */ |
516 | continue; | 479 | s->offset = 0; |
517 | 480 | s->backward = false; | |
518 | s = &scroll[index]; | 481 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; |
519 | |||
520 | /* check pause */ | ||
521 | if (TIME_BEFORE(current_tick, s->start_tick)) | ||
522 | continue; | ||
523 | |||
524 | if (s->backward) | ||
525 | s->offset--; | ||
526 | else | ||
527 | s->offset++; | ||
528 | |||
529 | xpos = s->startx; | ||
530 | ypos = ymargin + index; | ||
531 | |||
532 | if (s->bidir) /* scroll bidirectional */ | ||
533 | { | ||
534 | if (s->offset <= 0) | ||
535 | { | ||
536 | /* at beginning of line */ | ||
537 | s->offset = 0; | ||
538 | s->backward = false; | ||
539 | s->start_tick = current_tick + scroll_delay * 2; | ||
540 | } | ||
541 | if (s->offset >= s->len - (LCD_WIDTH - xpos)) | ||
542 | { | ||
543 | /* at end of line */ | ||
544 | s->offset = s->len - (LCD_WIDTH - xpos); | ||
545 | s->backward = true; | ||
546 | s->start_tick = current_tick + scroll_delay * 2; | ||
547 | } | ||
548 | } | 482 | } |
549 | else /* scroll forward the whole time */ | 483 | if (s->offset >= s->len - (LCD_WIDTH - xpos)) { |
550 | { | 484 | /* at end of line */ |
551 | if (s->offset >= s->len) | 485 | s->offset = s->len - (LCD_WIDTH - xpos); |
552 | s->offset -= s->len; | 486 | s->backward = true; |
487 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | ||
553 | } | 488 | } |
554 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | ||
555 | update = true; | ||
556 | } | 489 | } |
557 | if (lcd_cursor.enabled) | 490 | else /* scroll forward the whole time */ |
558 | { | 491 | { |
559 | if (--lcd_cursor.downcount <= 0) | 492 | if (s->offset >= s->len) |
560 | { | 493 | s->offset -= s->len; |
561 | lcd_cursor.downcount = lcd_cursor.divider; | ||
562 | lcd_cursor.visible = !lcd_cursor.visible; | ||
563 | update = true; | ||
564 | } | ||
565 | } | 494 | } |
566 | if (update) | ||
567 | lcd_update(); | ||
568 | 495 | ||
569 | sleep(scroll_ticks); | 496 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); |
497 | update = true; | ||
498 | } | ||
499 | |||
500 | if (lcd_cursor.enabled) | ||
501 | { | ||
502 | if (--lcd_cursor.downcount <= 0) | ||
503 | { | ||
504 | lcd_cursor.downcount = lcd_cursor.divider; | ||
505 | lcd_cursor.visible = !lcd_cursor.visible; | ||
506 | update = true; | ||
507 | } | ||
570 | } | 508 | } |
509 | |||
510 | if (update) | ||
511 | lcd_update(); | ||
571 | } | 512 | } |
513 | |||
diff --git a/firmware/drivers/lcd-remote-1bit-v.c b/firmware/drivers/lcd-remote-1bit-v.c index 6b5b1fb42f..1ddd8e5071 100644 --- a/firmware/drivers/lcd-remote-1bit-v.c +++ b/firmware/drivers/lcd-remote-1bit-v.c | |||
@@ -31,8 +31,7 @@ | |||
31 | #include "font.h" | 31 | #include "font.h" |
32 | #include "rbunicode.h" | 32 | #include "rbunicode.h" |
33 | #include "bidi.h" | 33 | #include "bidi.h" |
34 | 34 | #include "scroll_engine.h" | |
35 | #define SCROLLABLE_LINES (((LCD_REMOTE_HEIGHT+4)/5 < 32) ? (LCD_REMOTE_HEIGHT+4)/5 : 32) | ||
36 | 35 | ||
37 | /*** globals ***/ | 36 | /*** globals ***/ |
38 | 37 | ||
@@ -44,28 +43,6 @@ static int xmargin = 0; | |||
44 | static int ymargin = 0; | 43 | static int ymargin = 0; |
45 | static int curfont = FONT_SYSFIXED; | 44 | static int curfont = FONT_SYSFIXED; |
46 | 45 | ||
47 | /* scrolling */ | ||
48 | static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ | ||
49 | static void scroll_thread(void); | ||
50 | static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; | ||
51 | static const char scroll_name[] = "remote_scroll"; | ||
52 | static int scroll_ticks = 12; /* # of ticks between updates*/ | ||
53 | static int scroll_delay = HZ/2; /* ticks delay before start */ | ||
54 | static int scroll_step = 6; /* pixels per scroll step */ | ||
55 | static int bidir_limit = 50; /* percent */ | ||
56 | static struct scrollinfo scroll[SCROLLABLE_LINES]; | ||
57 | |||
58 | static const char scroll_tick_table[16] = { | ||
59 | /* Hz values: | ||
60 | 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ | ||
61 | 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 | ||
62 | }; | ||
63 | |||
64 | /* remote hotplug */ | ||
65 | #ifndef SIMULATOR | ||
66 | struct event_queue remote_scroll_queue; | ||
67 | #endif | ||
68 | |||
69 | /*** parameter handling ***/ | 46 | /*** parameter handling ***/ |
70 | 47 | ||
71 | void lcd_remote_set_drawmode(int mode) | 48 | void lcd_remote_set_drawmode(int mode) |
@@ -94,12 +71,16 @@ int lcd_remote_getymargin(void) | |||
94 | return ymargin; | 71 | return ymargin; |
95 | } | 72 | } |
96 | 73 | ||
97 | |||
98 | void lcd_remote_setfont(int newfont) | 74 | void lcd_remote_setfont(int newfont) |
99 | { | 75 | { |
100 | curfont = newfont; | 76 | curfont = newfont; |
101 | } | 77 | } |
102 | 78 | ||
79 | int lcd_remote_getfont(void) | ||
80 | { | ||
81 | return curfont; | ||
82 | } | ||
83 | |||
103 | int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) | 84 | int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) |
104 | { | 85 | { |
105 | return font_getstringsize(str, w, h, curfont); | 86 | return font_getstringsize(str, w, h, curfont); |
@@ -208,7 +189,7 @@ void lcd_remote_clear_display(void) | |||
208 | unsigned bits = (drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; | 189 | unsigned bits = (drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; |
209 | 190 | ||
210 | memset(lcd_remote_framebuffer, bits, sizeof lcd_remote_framebuffer); | 191 | memset(lcd_remote_framebuffer, bits, sizeof lcd_remote_framebuffer); |
211 | scrolling_lines = 0; | 192 | lcd_remote_scroll_info.lines = 0; |
212 | } | 193 | } |
213 | 194 | ||
214 | /* Set a single pixel */ | 195 | /* Set a single pixel */ |
@@ -599,7 +580,7 @@ void lcd_remote_bitmap(const unsigned char *src, int x, int y, int width, | |||
599 | } | 580 | } |
600 | 581 | ||
601 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | 582 | /* put a string at a given pixel position, skipping first ofs pixel columns */ |
602 | static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) | 583 | void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) |
603 | { | 584 | { |
604 | unsigned short ch; | 585 | unsigned short ch; |
605 | unsigned short *ucs; | 586 | unsigned short *ucs; |
@@ -664,7 +645,7 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, | |||
664 | int lastmode = drawmode; | 645 | int lastmode = drawmode; |
665 | 646 | ||
666 | /* make sure scrolling is turned off on the line we are updating */ | 647 | /* make sure scrolling is turned off on the line we are updating */ |
667 | scrolling_lines &= ~(1 << y); | 648 | lcd_remote_scroll_info.lines &= ~(1 << y); |
668 | 649 | ||
669 | if(!str || !str[0]) | 650 | if(!str || !str[0]) |
670 | return; | 651 | return; |
@@ -683,45 +664,6 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, | |||
683 | 664 | ||
684 | /*** scrolling ***/ | 665 | /*** scrolling ***/ |
685 | 666 | ||
686 | /* Reverse the invert setting of the scrolling line (if any) at given char | ||
687 | position. Setting will go into affect next time line scrolls. */ | ||
688 | void lcd_remote_invertscroll(int x, int y) | ||
689 | { | ||
690 | struct scrollinfo* s; | ||
691 | |||
692 | (void)x; | ||
693 | |||
694 | if(y>=SCROLLABLE_LINES) return; | ||
695 | |||
696 | s = &scroll[y]; | ||
697 | s->invert = !s->invert; | ||
698 | } | ||
699 | |||
700 | void lcd_remote_stop_scroll(void) | ||
701 | { | ||
702 | scrolling_lines=0; | ||
703 | } | ||
704 | |||
705 | void lcd_remote_scroll_speed(int speed) | ||
706 | { | ||
707 | scroll_ticks = scroll_tick_table[speed]; | ||
708 | } | ||
709 | |||
710 | void lcd_remote_scroll_step(int step) | ||
711 | { | ||
712 | scroll_step = step; | ||
713 | } | ||
714 | |||
715 | void lcd_remote_scroll_delay(int ms) | ||
716 | { | ||
717 | scroll_delay = ms / (HZ / 10); | ||
718 | } | ||
719 | |||
720 | void lcd_remote_bidir_scroll(int percent) | ||
721 | { | ||
722 | bidir_limit = percent; | ||
723 | } | ||
724 | |||
725 | void lcd_remote_puts_scroll(int x, int y, const unsigned char *string) | 667 | void lcd_remote_puts_scroll(int x, int y, const unsigned char *string) |
726 | { | 668 | { |
727 | lcd_remote_puts_scroll_style(x, y, string, STYLE_DEFAULT); | 669 | lcd_remote_puts_scroll_style(x, y, string, STYLE_DEFAULT); |
@@ -743,11 +685,11 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
743 | struct scrollinfo* s; | 685 | struct scrollinfo* s; |
744 | int w, h; | 686 | int w, h; |
745 | 687 | ||
746 | if(y>=SCROLLABLE_LINES) return; | 688 | if(y>=LCD_REMOTE_SCROLLABLE_LINES) return; |
747 | 689 | ||
748 | s = &scroll[y]; | 690 | s = &lcd_remote_scroll_info.scroll[y]; |
749 | 691 | ||
750 | s->start_tick = current_tick + scroll_delay; | 692 | s->start_tick = current_tick + lcd_remote_scroll_info.delay; |
751 | s->invert = false; | 693 | s->invert = false; |
752 | if (style & STYLE_INVERT) { | 694 | if (style & STYLE_INVERT) { |
753 | s->invert = true; | 695 | s->invert = true; |
@@ -770,9 +712,9 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
770 | 712 | ||
771 | /* scroll bidirectional or forward only depending on the string | 713 | /* scroll bidirectional or forward only depending on the string |
772 | width */ | 714 | width */ |
773 | if ( bidir_limit ) { | 715 | if ( lcd_remote_scroll_info.bidir_limit ) { |
774 | s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) * | 716 | s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) * |
775 | (100 + bidir_limit) / 100; | 717 | (100 + lcd_remote_scroll_info.bidir_limit) / 100; |
776 | } | 718 | } |
777 | else | 719 | else |
778 | s->bidir = false; | 720 | s->bidir = false; |
@@ -790,110 +732,67 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
790 | s->offset = offset; | 732 | s->offset = offset; |
791 | s->startx = xmargin + x * s->width / s->len;; | 733 | s->startx = xmargin + x * s->width / s->len;; |
792 | s->backward = false; | 734 | s->backward = false; |
793 | scrolling_lines |= (1<<y); | 735 | lcd_remote_scroll_info.lines |= (1<<y); |
794 | } | 736 | } |
795 | else | 737 | else |
796 | /* force a bit switch-off since it doesn't scroll */ | 738 | /* force a bit switch-off since it doesn't scroll */ |
797 | scrolling_lines &= ~(1<<y); | 739 | lcd_remote_scroll_info.lines &= ~(1<<y); |
798 | } | 740 | } |
799 | 741 | ||
800 | static void scroll_thread(void) | 742 | void lcd_remote_scroll_fn(void) |
801 | { | 743 | { |
802 | struct font* pf; | 744 | struct font* pf; |
803 | struct scrollinfo* s; | 745 | struct scrollinfo* s; |
804 | long next_tick = current_tick; | ||
805 | long delay = 0; | ||
806 | int index; | 746 | int index; |
807 | int xpos, ypos; | 747 | int xpos, ypos; |
808 | int lastmode; | 748 | int lastmode; |
809 | #ifndef SIMULATOR | ||
810 | struct event ev; | ||
811 | #endif | ||
812 | |||
813 | /* initialize scroll struct array */ | ||
814 | scrolling_lines = 0; | ||
815 | |||
816 | while ( 1 ) { | ||
817 | |||
818 | #ifdef SIMULATOR | ||
819 | sleep(delay); | ||
820 | #else | ||
821 | if (remote_initialized) | ||
822 | queue_wait_w_tmo(&remote_scroll_queue, &ev, delay); | ||
823 | else | ||
824 | queue_wait(&remote_scroll_queue, &ev); | ||
825 | 749 | ||
826 | switch (ev.id) | 750 | for ( index = 0; index < LCD_REMOTE_SCROLLABLE_LINES; index++ ) { |
827 | { | 751 | /* really scroll? */ |
828 | case REMOTE_INIT_LCD: | 752 | if ((lcd_remote_scroll_info.lines & (1 << index)) == 0) |
829 | lcd_remote_on(); | ||
830 | lcd_remote_update(); | ||
831 | break; | ||
832 | |||
833 | case REMOTE_DEINIT_LCD: | ||
834 | lcd_remote_off(); | ||
835 | break; | ||
836 | } | ||
837 | |||
838 | delay = next_tick - current_tick - 1; | ||
839 | if (delay >= 0) | ||
840 | continue; | 753 | continue; |
841 | #endif | ||
842 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | ||
843 | /* really scroll? */ | ||
844 | if ( !(scrolling_lines&(1<<index)) ) | ||
845 | continue; | ||
846 | 754 | ||
847 | s = &scroll[index]; | 755 | s = &lcd_remote_scroll_info.scroll[index]; |
848 | 756 | ||
849 | /* check pause */ | 757 | /* check pause */ |
850 | if (TIME_BEFORE(current_tick, s->start_tick)) | 758 | if (TIME_BEFORE(current_tick, s->start_tick)) |
851 | continue; | 759 | continue; |
852 | 760 | ||
853 | if (s->backward) | 761 | if (s->backward) |
854 | s->offset -= scroll_step; | 762 | s->offset -= lcd_remote_scroll_info.step; |
855 | else | 763 | else |
856 | s->offset += scroll_step; | 764 | s->offset += lcd_remote_scroll_info.step; |
857 | 765 | ||
858 | pf = font_get(curfont); | 766 | pf = font_get(curfont); |
859 | xpos = s->startx; | 767 | xpos = s->startx; |
860 | ypos = ymargin + index * pf->height; | 768 | ypos = ymargin + index * pf->height; |
861 | 769 | ||
862 | if (s->bidir) { /* scroll bidirectional */ | 770 | if (s->bidir) { /* scroll bidirectional */ |
863 | if (s->offset <= 0) { | 771 | if (s->offset <= 0) { |
864 | /* at beginning of line */ | 772 | /* at beginning of line */ |
865 | s->offset = 0; | 773 | s->offset = 0; |
866 | s->backward = false; | 774 | s->backward = false; |
867 | s->start_tick = current_tick + scroll_delay * 2; | 775 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; |
868 | } | ||
869 | if (s->offset >= s->width - (LCD_REMOTE_WIDTH - xpos)) { | ||
870 | /* at end of line */ | ||
871 | s->offset = s->width - (LCD_REMOTE_WIDTH - xpos); | ||
872 | s->backward = true; | ||
873 | s->start_tick = current_tick + scroll_delay * 2; | ||
874 | } | ||
875 | } | 776 | } |
876 | else { | 777 | if (s->offset >= s->width - (LCD_REMOTE_WIDTH - xpos)) { |
877 | /* scroll forward the whole time */ | 778 | /* at end of line */ |
878 | if (s->offset >= s->width) | 779 | s->offset = s->width - (LCD_REMOTE_WIDTH - xpos); |
879 | s->offset %= s->width; | 780 | s->backward = true; |
781 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; | ||
880 | } | 782 | } |
881 | |||
882 | lastmode = drawmode; | ||
883 | drawmode = s->invert ? | ||
884 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | ||
885 | lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); | ||
886 | drawmode = lastmode; | ||
887 | lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); | ||
888 | } | 783 | } |
889 | 784 | else { | |
890 | next_tick += scroll_ticks; | 785 | /* scroll forward the whole time */ |
891 | delay = next_tick - current_tick - 1; | 786 | if (s->offset >= s->width) |
892 | if (delay < 0) | 787 | s->offset %= s->width; |
893 | { | ||
894 | next_tick = current_tick + 1; | ||
895 | delay = 0; | ||
896 | } | 788 | } |
789 | |||
790 | lastmode = drawmode; | ||
791 | drawmode = s->invert ? | ||
792 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | ||
793 | lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); | ||
794 | drawmode = lastmode; | ||
795 | lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); | ||
897 | } | 796 | } |
898 | } | 797 | } |
899 | 798 | ||
@@ -903,10 +802,5 @@ void lcd_remote_init(void) | |||
903 | #ifndef SIMULATOR | 802 | #ifndef SIMULATOR |
904 | /* Call device specific init */ | 803 | /* Call device specific init */ |
905 | lcd_remote_init_device(); | 804 | lcd_remote_init_device(); |
906 | /* private queue */ | ||
907 | queue_init(&remote_scroll_queue, false); | ||
908 | #endif | 805 | #endif |
909 | create_thread(scroll_thread, scroll_stack, | ||
910 | sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) | ||
911 | IF_COP(, CPU, false)); | ||
912 | } | 806 | } |
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 | } |