summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-remote-1bit-v.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-remote-1bit-v.c')
-rw-r--r--firmware/drivers/lcd-remote-1bit-v.c216
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;
44static int ymargin = 0; 43static int ymargin = 0;
45static int curfont = FONT_SYSFIXED; 44static int curfont = FONT_SYSFIXED;
46 45
47/* scrolling */
48static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */
49static void scroll_thread(void);
50static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)];
51static const char scroll_name[] = "remote_scroll";
52static int scroll_ticks = 12; /* # of ticks between updates*/
53static int scroll_delay = HZ/2; /* ticks delay before start */
54static int scroll_step = 6; /* pixels per scroll step */
55static int bidir_limit = 50; /* percent */
56static struct scrollinfo scroll[SCROLLABLE_LINES];
57
58static 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
66struct event_queue remote_scroll_queue;
67#endif
68
69/*** parameter handling ***/ 46/*** parameter handling ***/
70 47
71void lcd_remote_set_drawmode(int mode) 48void 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
98void lcd_remote_setfont(int newfont) 74void lcd_remote_setfont(int newfont)
99{ 75{
100 curfont = newfont; 76 curfont = newfont;
101} 77}
102 78
79int lcd_remote_getfont(void)
80{
81 return curfont;
82}
83
103int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) 84int 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 */
602static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) 583void 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. */
688void 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
700void lcd_remote_stop_scroll(void)
701{
702 scrolling_lines=0;
703}
704
705void lcd_remote_scroll_speed(int speed)
706{
707 scroll_ticks = scroll_tick_table[speed];
708}
709
710void lcd_remote_scroll_step(int step)
711{
712 scroll_step = step;
713}
714
715void lcd_remote_scroll_delay(int ms)
716{
717 scroll_delay = ms / (HZ / 10);
718}
719
720void lcd_remote_bidir_scroll(int percent)
721{
722 bidir_limit = percent;
723}
724
725void lcd_remote_puts_scroll(int x, int y, const unsigned char *string) 667void 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
800static void scroll_thread(void) 742void 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}