diff options
Diffstat (limited to 'firmware/drivers/lcd-recorder.c')
-rw-r--r-- | firmware/drivers/lcd-recorder.c | 195 |
1 files changed, 154 insertions, 41 deletions
diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c index 1c899307ed..10071dc3d7 100644 --- a/firmware/drivers/lcd-recorder.c +++ b/firmware/drivers/lcd-recorder.c | |||
@@ -70,7 +70,14 @@ | |||
70 | 70 | ||
71 | #define SCROLL_SPACING 3 | 71 | #define SCROLL_SPACING 3 |
72 | 72 | ||
73 | #define SCROLLABLE_LINES 10 | ||
74 | |||
75 | #define SCROLL_MODE_OFF 0 | ||
76 | #define SCROLL_MODE_PAUSE 1 | ||
77 | #define SCROLL_MODE_RUN 2 | ||
78 | |||
73 | struct scrollinfo { | 79 | struct scrollinfo { |
80 | int mode; | ||
74 | char line[MAX_PATH + LCD_WIDTH/2 + SCROLL_SPACING + 2]; | 81 | char line[MAX_PATH + LCD_WIDTH/2 + SCROLL_SPACING + 2]; |
75 | int len; /* length of line in chars */ | 82 | int len; /* length of line in chars */ |
76 | int width; /* length of line in pixels */ | 83 | int width; /* length of line in pixels */ |
@@ -84,8 +91,8 @@ static char scroll_stack[DEFAULT_STACK_SIZE]; | |||
84 | static char scroll_name[] = "scroll"; | 91 | static char scroll_name[] = "scroll"; |
85 | static char scroll_speed = 8; /* updates per second */ | 92 | static char scroll_speed = 8; /* updates per second */ |
86 | static char scroll_step = 6; /* pixels per scroll step */ | 93 | static char scroll_step = 6; /* pixels per scroll step */ |
87 | static struct scrollinfo scroll; /* only one scroll line at the moment */ | 94 | static long scroll_start_tick; |
88 | static int scroll_count = 0; | 95 | static struct scrollinfo scroll[SCROLLABLE_LINES]; |
89 | static int xmargin = 0; | 96 | static int xmargin = 0; |
90 | static int ymargin = 0; | 97 | static int ymargin = 0; |
91 | static int curfont = FONT_SYSFIXED; | 98 | static int curfont = FONT_SYSFIXED; |
@@ -656,16 +663,26 @@ void lcd_invertpixel(int x, int y) | |||
656 | INVERT_PIXEL(x,y); | 663 | INVERT_PIXEL(x,y); |
657 | } | 664 | } |
658 | 665 | ||
659 | void lcd_puts_scroll(int x, int y, unsigned char* string ) | 666 | void lcd_puts_scroll(int x, int y, unsigned char* string) |
660 | { | 667 | { |
661 | struct scrollinfo* s = &scroll; | 668 | struct scrollinfo* s; |
662 | int w, h; | 669 | int w, h; |
670 | int index; | ||
671 | |||
672 | scroll_start_tick = current_tick + HZ/2; | ||
673 | |||
674 | /* search for the next free entry */ | ||
675 | for (index = 0; index < SCROLLABLE_LINES; index++) { | ||
676 | s = &scroll[index]; | ||
677 | if (s->mode == SCROLL_MODE_OFF) { | ||
678 | break; | ||
679 | } | ||
680 | } | ||
663 | 681 | ||
664 | lcd_puts(x,y,string); | 682 | lcd_puts(x,y,string); |
665 | lcd_getstringsize(string, &w, &h); | 683 | lcd_getstringsize(string, &w, &h); |
666 | 684 | ||
667 | if (LCD_WIDTH - x*8 - xmargin < w) | 685 | if (LCD_WIDTH - x * 8 - xmargin < w) { |
668 | { | ||
669 | /* prepare scroll line */ | 686 | /* prepare scroll line */ |
670 | char *end; | 687 | char *end; |
671 | 688 | ||
@@ -678,42 +695,121 @@ void lcd_puts_scroll(int x, int y, unsigned char* string ) | |||
678 | for (end = s->line; *end; end++); | 695 | for (end = s->line; *end; end++); |
679 | strncpy(end, string, LCD_WIDTH/2); | 696 | strncpy(end, string, LCD_WIDTH/2); |
680 | 697 | ||
698 | s->mode = SCROLL_MODE_RUN; | ||
681 | s->len = strlen(string); | 699 | s->len = strlen(string); |
682 | s->offset = 0; | 700 | s->offset = 0; |
683 | s->startx = x; | 701 | s->startx = x; |
684 | s->starty = y; | 702 | s->starty = y; |
685 | scroll_count = 1; | ||
686 | } | 703 | } |
687 | } | 704 | } |
688 | 705 | ||
689 | |||
690 | void lcd_stop_scroll(void) | 706 | void lcd_stop_scroll(void) |
691 | { | 707 | { |
692 | if ( scroll_count ) { | 708 | struct scrollinfo* s; |
693 | int w,h; | 709 | int w,h; |
694 | struct scrollinfo* s = &scroll; | 710 | int index; |
695 | scroll_count = 0; | 711 | |
712 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | ||
713 | s = &scroll[index]; | ||
714 | if ( s->mode == SCROLL_MODE_RUN || | ||
715 | s->mode == SCROLL_MODE_PAUSE ) { | ||
716 | lcd_getstringsize(s->line, &w, &h); | ||
717 | lcd_clearrect(xmargin + s->startx * w / s->len, | ||
718 | ymargin + s->starty * h, | ||
719 | LCD_WIDTH - xmargin, | ||
720 | h); | ||
721 | |||
722 | /* restore scrolled row */ | ||
723 | lcd_puts(s->startx, s->starty, s->line); | ||
724 | s->mode = SCROLL_MODE_OFF; | ||
725 | } | ||
726 | } | ||
696 | 727 | ||
697 | lcd_getstringsize(s->line, &w, &h); | 728 | lcd_update(); |
698 | lcd_clearrect(xmargin + s->startx*w/s->len, | 729 | } |
699 | ymargin + s->starty*h, | ||
700 | LCD_WIDTH - xmargin, | ||
701 | h); | ||
702 | 730 | ||
703 | /* restore scrolled row */ | 731 | void lcd_stop_scroll_line(int line) |
704 | lcd_puts(s->startx,s->starty,s->line); | 732 | { |
705 | lcd_update(); | 733 | struct scrollinfo* s; |
734 | int w,h; | ||
735 | int index; | ||
736 | |||
737 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | ||
738 | s = &scroll[index]; | ||
739 | if ( s->startx == line && | ||
740 | ( s->mode == SCROLL_MODE_RUN || | ||
741 | s->mode == SCROLL_MODE_PAUSE )) { | ||
742 | lcd_getstringsize(s->line, &w, &h); | ||
743 | lcd_clearrect(xmargin + s->startx * w / s->len, | ||
744 | ymargin + s->starty * h, | ||
745 | LCD_WIDTH - xmargin, | ||
746 | h); | ||
747 | |||
748 | /* restore scrolled row */ | ||
749 | lcd_puts(s->startx, s->starty, s->line); | ||
750 | s->mode = SCROLL_MODE_OFF; | ||
751 | } | ||
706 | } | 752 | } |
753 | |||
754 | lcd_update(); | ||
707 | } | 755 | } |
708 | 756 | ||
709 | void lcd_scroll_pause(void) | 757 | void lcd_scroll_pause(void) |
710 | { | 758 | { |
711 | scroll_count = 0; | 759 | struct scrollinfo* s; |
760 | int index; | ||
761 | |||
762 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | ||
763 | s = &scroll[index]; | ||
764 | if ( s->mode == SCROLL_MODE_RUN ) { | ||
765 | s->mode = SCROLL_MODE_PAUSE; | ||
766 | } | ||
767 | } | ||
768 | } | ||
769 | |||
770 | void lcd_scroll_pause_line(int line) | ||
771 | { | ||
772 | struct scrollinfo* s; | ||
773 | int index; | ||
774 | |||
775 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | ||
776 | s = &scroll[index]; | ||
777 | if ( s->startx == line && | ||
778 | s->mode == SCROLL_MODE_RUN ) { | ||
779 | s->mode = SCROLL_MODE_PAUSE; | ||
780 | } | ||
781 | } | ||
712 | } | 782 | } |
713 | 783 | ||
714 | void lcd_scroll_resume(void) | 784 | void lcd_scroll_resume(void) |
715 | { | 785 | { |
716 | scroll_count = 1; | 786 | struct scrollinfo* s; |
787 | int index; | ||
788 | |||
789 | scroll_start_tick = current_tick + HZ/2; | ||
790 | |||
791 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | ||
792 | s = &scroll[index]; | ||
793 | if ( s->mode == SCROLL_MODE_PAUSE ) { | ||
794 | s->mode = SCROLL_MODE_RUN; | ||
795 | } | ||
796 | } | ||
797 | } | ||
798 | |||
799 | void lcd_scroll_resume_line(int line) | ||
800 | { | ||
801 | struct scrollinfo* s; | ||
802 | int index; | ||
803 | |||
804 | scroll_start_tick = current_tick + HZ/2; | ||
805 | |||
806 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { | ||
807 | s = &scroll[index]; | ||
808 | if ( s->startx == line && | ||
809 | s->mode == SCROLL_MODE_PAUSE ) { | ||
810 | s->mode = SCROLL_MODE_RUN; | ||
811 | } | ||
812 | } | ||
717 | } | 813 | } |
718 | 814 | ||
719 | void lcd_scroll_speed(int speed) | 815 | void lcd_scroll_speed(int speed) |
@@ -723,33 +819,50 @@ void lcd_scroll_speed(int speed) | |||
723 | 819 | ||
724 | static void scroll_thread(void) | 820 | static void scroll_thread(void) |
725 | { | 821 | { |
726 | struct scrollinfo* s = &scroll; | 822 | struct scrollinfo* s; |
823 | int index; | ||
824 | int w, h; | ||
825 | int xpos, ypos; | ||
826 | bool update; | ||
827 | |||
828 | /* initialize scroll struct array */ | ||
829 | for (index = 0; index < SCROLLABLE_LINES; index++) { | ||
830 | scroll[index].mode = SCROLL_MODE_OFF; | ||
831 | } | ||
832 | |||
833 | scroll_start_tick = current_tick; | ||
727 | 834 | ||
728 | while ( 1 ) { | 835 | while ( 1 ) { |
729 | if ( !scroll_count ) { | 836 | |
730 | yield(); | 837 | update = false; |
731 | continue; | 838 | |
732 | } | ||
733 | /* wait 0.5s before starting scroll */ | 839 | /* wait 0.5s before starting scroll */ |
734 | if ( scroll_count < scroll_speed/2 ) | 840 | if ( TIME_AFTER(current_tick, scroll_start_tick) ) { |
735 | scroll_count++; | ||
736 | else { | ||
737 | int w, h; | ||
738 | int xpos, ypos; | ||
739 | 841 | ||
740 | s->offset += scroll_step; | 842 | for ( index = 0; index < SCROLLABLE_LINES; index++ ) { |
843 | s = &scroll[index]; | ||
844 | if ( s->mode == SCROLL_MODE_RUN ) { | ||
845 | update = true; | ||
741 | 846 | ||
742 | if (s->offset >= s->width) | 847 | s->offset += scroll_step; |
743 | s->offset %= s->width; | ||
744 | 848 | ||
745 | lcd_getstringsize(s->line, &w, &h); | 849 | if (s->offset >= s->width) |
746 | xpos = xmargin + s->startx * w / s->len; | 850 | s->offset %= s->width; |
747 | ypos = ymargin + s->starty * h; | 851 | |
852 | lcd_getstringsize(s->line, &w, &h); | ||
853 | xpos = xmargin + s->startx * w / s->len; | ||
854 | ypos = ymargin + s->starty * h; | ||
855 | |||
856 | lcd_clearrect(xpos, ypos, LCD_WIDTH - xmargin, h); | ||
857 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | ||
858 | } | ||
859 | } | ||
748 | 860 | ||
749 | lcd_clearrect(xpos, ypos, LCD_WIDTH - xmargin, h); | 861 | if (update) { |
750 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | 862 | lcd_update(); |
751 | lcd_update(); | 863 | } |
752 | } | 864 | } |
865 | |||
753 | sleep(HZ/scroll_speed); | 866 | sleep(HZ/scroll_speed); |
754 | } | 867 | } |
755 | } | 868 | } |