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/lcd-remote-1bit-v.c | |
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/lcd-remote-1bit-v.c')
-rw-r--r-- | firmware/drivers/lcd-remote-1bit-v.c | 216 |
1 files changed, 55 insertions, 161 deletions
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 | } |