summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-recorder.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-recorder.c')
-rw-r--r--firmware/drivers/lcd-recorder.c146
1 files changed, 75 insertions, 71 deletions
diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c
index fee42d9ef4..a5d8900f5d 100644
--- a/firmware/drivers/lcd-recorder.c
+++ b/firmware/drivers/lcd-recorder.c
@@ -68,21 +68,22 @@
68#define LCD_CNTL_HIGHCOL 0x10 // Upper column address 68#define LCD_CNTL_HIGHCOL 0x10 // Upper column address
69#define LCD_CNTL_LOWCOL 0x00 // Lower column address 69#define LCD_CNTL_LOWCOL 0x00 // Lower column address
70 70
71#define SCROLL_SPACING 3
72
71struct scrollinfo { 73struct scrollinfo {
72 char text[MAX_PATH]; 74 char line[MAX_PATH + LCD_WIDTH/2 + SCROLL_SPACING + 2];
73 char line[32]; 75 int len; /* length of line in chars */
74 int textlen; 76 int width; /* length of line in pixels */
75 int offset; 77 int offset;
76 int startx; 78 int startx;
77 int starty; 79 int starty;
78 int space;
79}; 80};
80 81
81static void scroll_thread(void); 82static void scroll_thread(void);
82static char scroll_stack[DEFAULT_STACK_SIZE]; 83static char scroll_stack[DEFAULT_STACK_SIZE];
83static char scroll_name[] = "scroll"; 84static char scroll_name[] = "scroll";
84static char scroll_speed = 8; /* updates per second */ 85static char scroll_speed = 8; /* updates per second */
85static char scroll_spacing = 3; /* spaces between end and start of text */ 86static char scroll_step = 6; /* pixels per scroll step */
86static struct scrollinfo scroll; /* only one scroll line at the moment */ 87static struct scrollinfo scroll; /* only one scroll line at the moment */
87static int scroll_count = 0; 88static int scroll_count = 0;
88static int xmargin = 0; 89static int xmargin = 0;
@@ -284,36 +285,58 @@ void lcd_puts(int x, int y, unsigned char *str)
284#endif 285#endif
285} 286}
286 287
287/* put a string at a given pixel position */ 288/* put a string at a given pixel position, skipping first ofs pixel columns */
288void lcd_putsxy(int x, int y, unsigned char *str) 289static void lcd_putsxyofs(int x, int y, int ofs, unsigned char *str)
289{ 290{
290 int ch; 291 int ch;
291 struct font* pf = font_get(curfont); 292 struct font* pf = font_get(curfont);
292 293
293 while (((ch = *str++) != '\0')) { 294 while ((ch = *str++) != '\0' && x < LCD_WIDTH)
294 bitmap_t *bits; 295 {
295 int width; 296 int width;
296 297
297 /* check input range*/ 298 /* check input range */
298 if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) 299 if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
299 ch = pf->defaultchar; 300 ch = pf->defaultchar;
300 ch -= pf->firstchar; 301 ch -= pf->firstchar;
301 302
302 /* get proportional width and glyph bits*/ 303 /* no partial-height drawing for now... */
303 width = pf->width ? pf->width[ch] : pf->maxwidth;
304 if (x + width > LCD_WIDTH)
305 break;
306
307 /* no partial-height drawing for now...*/
308 if (y + pf->height > LCD_HEIGHT) 304 if (y + pf->height > LCD_HEIGHT)
309 break; 305 break;
310 bits = pf->bits + (pf->offset ? pf->offset[ch] : (pf->height * ch));
311 306
312 lcd_bitmap((unsigned char *)bits, x, y, width, pf->height, true); 307 /* get proportional width and glyph bits */
313 x += width; 308 width = pf->width ? pf->width[ch] : pf->maxwidth;
309 width = MIN (width, LCD_WIDTH - x);
310
311 if (ofs != 0)
312 {
313 if (ofs > width)
314 {
315 ofs -= width;
316 continue;
317 }
318 width -= ofs;
319 }
320
321 if (width > 0)
322 {
323 int rows = (pf->height + 7) / 8;
324 bitmap_t* bits = pf->bits +
325 (pf->offset ? pf->offset[ch] : (pf->height * ch));
326 lcd_bitmap (((unsigned char*) bits) + ofs*rows, x, y,
327 width, pf->height, true);
328 x += width;
329 }
330 ofs = 0;
314 } 331 }
315} 332}
316 333
334/* put a string at a given pixel position */
335void lcd_putsxy(int x, int y, unsigned char *str)
336{
337 lcd_putsxyofs(x, y, 0, str);
338}
339
317/* 340/*
318 * All bitmaps have this format: 341 * All bitmaps have this format:
319 * Bits within a byte are arranged veritcally, LSB at top. 342 * Bits within a byte are arranged veritcally, LSB at top.
@@ -635,38 +658,29 @@ void lcd_invertpixel(int x, int y)
635void lcd_puts_scroll(int x, int y, unsigned char* string ) 658void lcd_puts_scroll(int x, int y, unsigned char* string )
636{ 659{
637 struct scrollinfo* s = &scroll; 660 struct scrollinfo* s = &scroll;
638 unsigned char ch[2];
639 int w, h; 661 int w, h;
640 int width;
641
642 ch[1] = 0; /* zero terminate */
643 ch[0] = string[0];
644 width = 0;
645 s->space = 0;
646 while ( ch[0] &&
647 (width + lcd_getstringsize(ch, &w, &h) <
648 (LCD_WIDTH - x*8))) {
649 width += w;
650 s->space++;
651 ch[0]=string[s->space];
652 }
653 662
654 lcd_puts(x,y,string); 663 lcd_puts(x,y,string);
655 s->textlen = strlen(string); 664 lcd_getstringsize(string, &w, &h);
656 665
657 s->space += 2; 666 if (LCD_WIDTH - x*8 - xmargin < w)
658 lcd_getstringsize(string,&w,&h); 667 {
659 if ( w > LCD_WIDTH - xmargin ) { 668 /* prepare scroll line */
660 s->offset=s->space; 669 char *end;
661 s->startx=x; 670
662 s->starty=y;
663 strncpy(s->text,string,sizeof s->text);
664 s->text[sizeof s->text - 1] = 0;
665 memset(s->line, 0, sizeof s->line); 671 memset(s->line, 0, sizeof s->line);
666 strncpy(s->line,string, 672 strcpy(s->line, string);
667 s->space > (int)sizeof s->line ? 673 strcat(s->line, " ");
668 (int)sizeof s->line : s->space ); 674 /* get new width incl. spaces */
669 s->line[sizeof s->line - 1] = 0; 675 s->width = lcd_getstringsize(s->line, &w, &h);
676
677 for (end = s->line; *end; end++);
678 strncpy(end, string, LCD_WIDTH/2);
679
680 s->len = strlen(string);
681 s->offset = 0;
682 s->startx = x;
683 s->starty = y;
670 scroll_count = 1; 684 scroll_count = 1;
671 } 685 }
672} 686}
@@ -679,14 +693,14 @@ void lcd_stop_scroll(void)
679 struct scrollinfo* s = &scroll; 693 struct scrollinfo* s = &scroll;
680 scroll_count = 0; 694 scroll_count = 0;
681 695
682 lcd_getstringsize( s->text, &w, &h); 696 lcd_getstringsize(s->line, &w, &h);
683 lcd_clearrect(xmargin + s->startx*w/s->textlen, 697 lcd_clearrect(xmargin + s->startx*w/s->len,
684 ymargin + s->starty*h, 698 ymargin + s->starty*h,
685 LCD_WIDTH - xmargin, 699 LCD_WIDTH - xmargin,
686 h); 700 h);
687 701
688 /* restore scrolled row */ 702 /* restore scrolled row */
689 lcd_puts(s->startx,s->starty,s->text); 703 lcd_puts(s->startx,s->starty,s->line);
690 lcd_update(); 704 lcd_update();
691 } 705 }
692} 706}
@@ -703,7 +717,7 @@ void lcd_scroll_resume(void)
703 717
704void lcd_scroll_speed(int speed) 718void lcd_scroll_speed(int speed)
705{ 719{
706 scroll_speed = speed; 720 scroll_step = speed;
707} 721}
708 722
709static void scroll_thread(void) 723static void scroll_thread(void)
@@ -719,30 +733,20 @@ static void scroll_thread(void)
719 if ( scroll_count < scroll_speed/2 ) 733 if ( scroll_count < scroll_speed/2 )
720 scroll_count++; 734 scroll_count++;
721 else { 735 else {
722 int i;
723 int w, h; 736 int w, h;
724 for ( i=0; i<s->space-1; i++ ) 737 int xpos, ypos;
725 s->line[i] = s->line[i+1];
726 738
727 if ( s->offset < s->textlen ) { 739 s->offset += scroll_step;
728 s->line[(int)s->space - 1] = s->text[(int)s->offset]; 740
729 s->offset++; 741 if (s->offset >= s->width)
730 } 742 s->offset %= s->width;
731 else {
732 s->line[s->space - 1] = ' ';
733 if ( s->offset < s->textlen + scroll_spacing - 1 )
734 s->offset++;
735 else
736 s->offset = 0;
737 }
738 743
739 lcd_getstringsize( s->text, &w, &h); 744 lcd_getstringsize(s->line, &w, &h);
740 lcd_clearrect(xmargin + s->startx*w/s->textlen, 745 xpos = xmargin + s->startx * w / s->len;
741 ymargin + s->starty*h, 746 ypos = ymargin + s->starty * h;
742 LCD_WIDTH - xmargin,
743 h);
744 747
745 lcd_puts(s->startx,s->starty,s->line); 748 lcd_clearrect(xpos, ypos, LCD_WIDTH - xmargin, h);
749 lcd_putsxyofs(xpos, ypos, s->offset, s->line);
746 lcd_update(); 750 lcd_update();
747 } 751 }
748 sleep(HZ/scroll_speed); 752 sleep(HZ/scroll_speed);