diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-09-24 22:44:59 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-09-24 22:44:59 +0000 |
commit | d34fbd0250e81d86eb28684e92f19d2d910b3ef1 (patch) | |
tree | bc719c79c743ca5637ff717efff5f69d986b99e5 /firmware/drivers/lcd-recorder.c | |
parent | 8fb7312650d549e200cf725a8f3863157bb5f839 (diff) | |
download | rockbox-d34fbd0250e81d86eb28684e92f19d2d910b3ef1.tar.gz rockbox-d34fbd0250e81d86eb28684e92f19d2d910b3ef1.zip |
New scroll code by Björn Fischer.
Fixed >8 pixel font support for it.
Changed speed setting to step setting, do we need both?
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2407 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-recorder.c')
-rw-r--r-- | firmware/drivers/lcd-recorder.c | 146 |
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 | |||
71 | struct scrollinfo { | 73 | struct 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 | ||
81 | static void scroll_thread(void); | 82 | static void scroll_thread(void); |
82 | static char scroll_stack[DEFAULT_STACK_SIZE]; | 83 | static char scroll_stack[DEFAULT_STACK_SIZE]; |
83 | static char scroll_name[] = "scroll"; | 84 | static char scroll_name[] = "scroll"; |
84 | static char scroll_speed = 8; /* updates per second */ | 85 | static char scroll_speed = 8; /* updates per second */ |
85 | static char scroll_spacing = 3; /* spaces between end and start of text */ | 86 | static char scroll_step = 6; /* pixels per scroll step */ |
86 | static struct scrollinfo scroll; /* only one scroll line at the moment */ | 87 | static struct scrollinfo scroll; /* only one scroll line at the moment */ |
87 | static int scroll_count = 0; | 88 | static int scroll_count = 0; |
88 | static int xmargin = 0; | 89 | static 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 */ |
288 | void lcd_putsxy(int x, int y, unsigned char *str) | 289 | static 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 */ | ||
335 | void 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) | |||
635 | void lcd_puts_scroll(int x, int y, unsigned char* string ) | 658 | void 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 | ||
704 | void lcd_scroll_speed(int speed) | 718 | void lcd_scroll_speed(int speed) |
705 | { | 719 | { |
706 | scroll_speed = speed; | 720 | scroll_step = speed; |
707 | } | 721 | } |
708 | 722 | ||
709 | static void scroll_thread(void) | 723 | static 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); |