summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2006-02-16 17:22:27 +0000
committerJens Arnold <amiconn@rockbox.org>2006-02-16 17:22:27 +0000
commitfa41253f04e5a6ca7620dbc30add9872aa5a8988 (patch)
tree3b19f39fe99e093c28335fbe62436014813abe0c
parentb0f05809d54a22deb0c32e99397e3f055ae61570 (diff)
downloadrockbox-fa41253f04e5a6ca7620dbc30add9872aa5a8988.tar.gz
rockbox-fa41253f04e5a6ca7620dbc30add9872aa5a8988.zip
Important bugfix for lcd_bitmap_part(). * Some slight optimisations.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8703 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/lcd-h100.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/firmware/drivers/lcd-h100.c b/firmware/drivers/lcd-h100.c
index ef32078afb..3af6ffef6a 100644
--- a/firmware/drivers/lcd-h100.c
+++ b/firmware/drivers/lcd-h100.c
@@ -69,6 +69,10 @@ static const unsigned char dibits[16] ICONST_ATTR = {
69 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF 69 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF
70}; 70};
71 71
72static const unsigned char pixmask[4] ICONST_ATTR = {
73 0x03, 0x0C, 0x30, 0xC0
74};
75
72static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ 76static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */
73static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */ 77static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */
74static int drawmode = DRMODE_SOLID; 78static int drawmode = DRMODE_SOLID;
@@ -366,20 +370,20 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h)
366static void setpixel(int x, int y) 370static void setpixel(int x, int y)
367{ 371{
368 unsigned char *data = &lcd_framebuffer[y>>2][x]; 372 unsigned char *data = &lcd_framebuffer[y>>2][x];
369 unsigned mask = 3 << (2 * (y & 3)); 373 unsigned mask = pixmask[y & 3];
370 *data = (*data & ~mask) | (fg_pattern & mask); 374 *data = (*data & ~mask) | (fg_pattern & mask);
371} 375}
372 376
373static void clearpixel(int x, int y) 377static void clearpixel(int x, int y)
374{ 378{
375 unsigned char *data = &lcd_framebuffer[y>>2][x]; 379 unsigned char *data = &lcd_framebuffer[y>>2][x];
376 unsigned mask = 3 << (2 * (y & 3)); 380 unsigned mask = pixmask[y & 3];
377 *data = (*data & ~mask) | (bg_pattern & mask); 381 *data = (*data & ~mask) | (bg_pattern & mask);
378} 382}
379 383
380static void flippixel(int x, int y) 384static void flippixel(int x, int y)
381{ 385{
382 lcd_framebuffer[y>>2][x] ^= 3 << (2 * (y & 3)); 386 lcd_framebuffer[y>>2][x] ^= pixmask[y & 3];
383} 387}
384 388
385static void nopixel(int x, int y) 389static void nopixel(int x, int y)
@@ -461,6 +465,11 @@ lcd_blockfunc_type* const lcd_blockfuncs[8] = {
461 flipinvblock, bginvblock, fginvblock, solidinvblock 465 flipinvblock, bginvblock, fginvblock, solidinvblock
462}; 466};
463 467
468static inline void setblock(unsigned char *address, unsigned mask, unsigned bits)
469{
470 *address = (*address & ~mask) | (bits & mask);
471}
472
464/*** drawing functions ***/ 473/*** drawing functions ***/
465 474
466/* Clear the whole display */ 475/* Clear the whole display */
@@ -578,7 +587,7 @@ void lcd_hline(int x1, int x2, int y)
578 587
579 bfunc = lcd_blockfuncs[drawmode]; 588 bfunc = lcd_blockfuncs[drawmode];
580 dst = &lcd_framebuffer[y>>2][x1]; 589 dst = &lcd_framebuffer[y>>2][x1];
581 mask = 3 << (2 * (y & 3)); 590 mask = pixmask[y & 3];
582 591
583 dst_end = dst + x2 - x1; 592 dst_end = dst + x2 - x1;
584 do 593 do
@@ -674,7 +683,7 @@ void lcd_fillrect(int x, int y, int width, int height)
674 if (y + height > LCD_HEIGHT) 683 if (y + height > LCD_HEIGHT)
675 height = LCD_HEIGHT - y; 684 height = LCD_HEIGHT - y;
676 685
677 fillopt = (drawmode & DRMODE_INVERSEVID) ? 686 fillopt = (drawmode & DRMODE_INVERSEVID) ?
678 (drawmode & DRMODE_BG) : (drawmode & DRMODE_FG); 687 (drawmode & DRMODE_BG) : (drawmode & DRMODE_FG);
679 if (fillopt &&(drawmode & DRMODE_INVERSEVID)) 688 if (fillopt &&(drawmode & DRMODE_INVERSEVID))
680 bits = bg_pattern; 689 bits = bg_pattern;
@@ -903,7 +912,6 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
903 int shift, ny; 912 int shift, ny;
904 unsigned char *dst, *dst_end; 913 unsigned char *dst, *dst_end;
905 unsigned mask, mask_bottom; 914 unsigned mask, mask_bottom;
906 lcd_blockfunc_type *bfunc;
907 915
908 /* nothing to draw? */ 916 /* nothing to draw? */
909 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 917 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
@@ -935,7 +943,6 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
935 shift = y & 3; 943 shift = y & 3;
936 ny = height - 1 + shift + src_y; 944 ny = height - 1 + shift + src_y;
937 945
938 bfunc = lcd_blockfuncs[drawmode];
939 mask = 0xFFu << (2 * (shift + src_y)); 946 mask = 0xFFu << (2 * (shift + src_y));
940 mask_bottom = 0xFFu >> (2 * (~ny & 3)); 947 mask_bottom = 0xFFu >> (2 * (~ny & 3));
941 948
@@ -952,7 +959,7 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
952 959
953 dst_end = dst_row + width; 960 dst_end = dst_row + width;
954 do 961 do
955 bfunc(dst_row++, mask, *src_row++); 962 setblock(dst_row++, mask, *src_row++);
956 while (dst_row < dst_end); 963 while (dst_row < dst_end);
957 } 964 }
958 965
@@ -968,7 +975,7 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
968 { 975 {
969 dst_end = dst + width; 976 dst_end = dst + width;
970 do 977 do
971 bfunc(dst++, mask, *src++); 978 setblock(dst++, mask, *src++);
972 while (dst < dst_end); 979 while (dst < dst_end);
973 } 980 }
974 } 981 }
@@ -989,7 +996,7 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
989 996
990 if (mask_col & 0xFFu) 997 if (mask_col & 0xFFu)
991 { 998 {
992 bfunc(dst_col, mask_col, data); 999 setblock(dst_col, mask_col, data);
993 mask_col = 0xFFu; 1000 mask_col = 0xFFu;
994 } 1001 }
995 else 1002 else
@@ -1000,7 +1007,7 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y,
1000 data >>= 8; 1007 data >>= 8;
1001 } 1008 }
1002 data |= *src_col << shift; 1009 data |= *src_col << shift;
1003 bfunc(dst_col, mask_col & mask_bottom, data); 1010 setblock(dst_col, mask_col & mask_bottom, data);
1004 } 1011 }
1005 while (dst < dst_end); 1012 while (dst < dst_end);
1006 } 1013 }