diff options
author | Jens Arnold <amiconn@rockbox.org> | 2006-02-16 17:22:27 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2006-02-16 17:22:27 +0000 |
commit | fa41253f04e5a6ca7620dbc30add9872aa5a8988 (patch) | |
tree | 3b19f39fe99e093c28335fbe62436014813abe0c | |
parent | b0f05809d54a22deb0c32e99397e3f055ae61570 (diff) | |
download | rockbox-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.c | 29 |
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 | ||
72 | static const unsigned char pixmask[4] ICONST_ATTR = { | ||
73 | 0x03, 0x0C, 0x30, 0xC0 | ||
74 | }; | ||
75 | |||
72 | static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ | 76 | static unsigned fg_pattern IDATA_ATTR = 0xFF; /* initially black */ |
73 | static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */ | 77 | static unsigned bg_pattern IDATA_ATTR = 0x00; /* initially white */ |
74 | static int drawmode = DRMODE_SOLID; | 78 | static int drawmode = DRMODE_SOLID; |
@@ -366,20 +370,20 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h) | |||
366 | static void setpixel(int x, int y) | 370 | static 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 | ||
373 | static void clearpixel(int x, int y) | 377 | static 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 | ||
380 | static void flippixel(int x, int y) | 384 | static 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 | ||
385 | static void nopixel(int x, int y) | 389 | static 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 | ||
468 | static 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 | } |