summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-11-16 01:41:46 +0000
committerJens Arnold <amiconn@rockbox.org>2005-11-16 01:41:46 +0000
commit5d8c1529a735254d2cc17e47d294b8835ba575b0 (patch)
treeac587a676b0c75eacd6ed4a9bcc2b68f98f4d760
parenta7db52ca894f9d80845267f743ae56663b37f605 (diff)
downloadrockbox-5d8c1529a735254d2cc17e47d294b8835ba575b0.tar.gz
rockbox-5d8c1529a735254d2cc17e47d294b8835ba575b0.zip
16bit LCD driver: * The colour get/set functions now use the native ranges for red/green/blue as intended. * Fixed lcd_fillrect(). * Properly working lcd_mono_bitmap_part(). * Implemented lcd_bitmap_part(). * Some optimisations.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7900 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/lcd-16bit.c180
1 files changed, 99 insertions, 81 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 9f698bbacd..185f572182 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -34,7 +34,7 @@
34 34
35#define SCROLLABLE_LINES 26 35#define SCROLLABLE_LINES 26
36 36
37#define RGB_PACK(r,g,b) (htobe16(((r>>3)<<11)|((g>>2)<<5)|(b>>3))) 37#define RGB_PACK(r,g,b) (htobe16(((r)<<11)|((g)<<5)|(b)))
38 38
39/*** globals ***/ 39/*** globals ***/
40fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH] __attribute__ ((aligned (4))); 40fb_data lcd_framebuffer[LCD_HEIGHT][LCD_WIDTH] __attribute__ ((aligned (4)));
@@ -73,7 +73,7 @@ int lcd_default_contrast(void)
73void lcd_init(void) 73void lcd_init(void)
74{ 74{
75 fg_pattern = 0x0000; /* Black */ 75 fg_pattern = 0x0000; /* Black */
76 bg_pattern = RGB_PACK(0xb6, 0xc6, 0xe5); /* "Rockbox blue" */ 76 bg_pattern = RGB_PACK(0x17, 0x31, 0x1d); /* "Rockbox blue" */
77 77
78 lcd_clear_display(); 78 lcd_clear_display();
79 /* Call device specific init */ 79 /* Call device specific init */
@@ -96,23 +96,22 @@ int lcd_get_drawmode(void)
96 96
97void lcd_set_foreground(struct rgb color) 97void lcd_set_foreground(struct rgb color)
98{ 98{
99 fg_pattern=RGB_PACK(color.red,color.green,color.blue); 99 fg_pattern = RGB_PACK(color.red, color.green, color.blue);
100} 100}
101 101
102struct rgb lcd_get_foreground(void) 102struct rgb lcd_get_foreground(void)
103{ 103{
104 struct rgb colour; 104 struct rgb colour;
105 105
106 colour.red=((fg_pattern&0xf800)>>11)<<3; 106 colour.red = (fg_pattern >> 11) & 0x1f;
107 colour.green=((fg_pattern&0x03e0)>>5)<<2; 107 colour.green = (fg_pattern >> 5) & 0x3f;
108 colour.blue=(fg_pattern&0x1f)<<3; 108 colour.blue = fg_pattern & 0x1f;
109
110 return colour; 109 return colour;
111} 110}
112 111
113void lcd_set_background(struct rgb color) 112void lcd_set_background(struct rgb color)
114{ 113{
115 bg_pattern=RGB_PACK(color.red,color.green,color.blue); 114 bg_pattern = RGB_PACK(color.red, color.green, color. blue);
116} 115}
117 116
118 117
@@ -120,9 +119,9 @@ struct rgb lcd_get_background(void)
120{ 119{
121 struct rgb colour; 120 struct rgb colour;
122 121
123 colour.red=((bg_pattern&0xf800)>>11)<<3; 122 colour.red = (bg_pattern >> 11) & 0x1f;
124 colour.green=((bg_pattern&0x03e0)>>5)<<2; 123 colour.green = (bg_pattern >> 5) & 0x3f;
125 colour.blue=(bg_pattern&0x1f)<<3; 124 colour.blue = bg_pattern & 0x1f;
126 return colour; 125 return colour;
127} 126}
128 127
@@ -174,14 +173,11 @@ static void clearpixel(int x, int y)
174 173
175static void flippixel(int x, int y) 174static void flippixel(int x, int y)
176{ 175{
177 /* What should this do on a color display? */ 176 lcd_framebuffer[y][x] = ~lcd_framebuffer[y][x];
178 (void)x;
179 (void)y;
180} 177}
181 178
182static void nopixel(int x, int y) 179static void nopixel(int x, int y)
183{ 180{
184 /* What should this do on a color display? */
185 (void)x; 181 (void)x;
186 (void)y; 182 (void)y;
187} 183}
@@ -196,13 +192,13 @@ lcd_pixelfunc_type* const lcd_pixelfuncs[8] = {
196/* Clear the whole display */ 192/* Clear the whole display */
197void lcd_clear_display(void) 193void lcd_clear_display(void)
198{ 194{
199 int i; 195 fb_data bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern;
200 unsigned short bits = (drawmode & DRMODE_INVERSEVID) ? fg_pattern : bg_pattern; 196 fb_data *dst = &lcd_framebuffer[0][0];
201 unsigned short* addr = (unsigned short *)lcd_framebuffer; 197 fb_data *dst_end = dst + LCD_HEIGHT*LCD_WIDTH;
202 198
203 for (i=0;i<LCD_HEIGHT*LCD_WIDTH;i++) { 199 do
204 *(addr++)=bits; 200 *dst++ = bits;
205 } 201 while (dst < dst_end);
206 scrolling_lines = 0; 202 scrolling_lines = 0;
207} 203}
208 204
@@ -361,7 +357,7 @@ void lcd_drawrect(int x, int y, int width, int height)
361/* Fill a rectangular area */ 357/* Fill a rectangular area */
362void lcd_fillrect(int x, int y, int width, int height) 358void lcd_fillrect(int x, int y, int width, int height)
363{ 359{
364 int nx, ny; 360 int xe, ye, xc;
365 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode]; 361 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode];
366 362
367 /* nothing to draw? */ 363 /* nothing to draw? */
@@ -385,13 +381,12 @@ void lcd_fillrect(int x, int y, int width, int height)
385 if (y + height > LCD_HEIGHT) 381 if (y + height > LCD_HEIGHT)
386 height = LCD_HEIGHT - y; 382 height = LCD_HEIGHT - y;
387 383
388 ny = y + height; 384 ye = y + height;
389 for(;y < ny;y++) 385 xe = x + width;
386 for(; y < ye; y++)
390 { 387 {
391 int xc; 388 for(xc = x; xc < xe; xc++)
392 nx = x + width; 389 pfunc(xc, y);
393 for(xc = x;xc < nx;xc++)
394 pfunc(x, y);
395 } 390 }
396} 391}
397 392
@@ -404,9 +399,8 @@ void lcd_fillrect(int x, int y, int width, int height)
404 * byte 1 2nd from left etc. The first row of bytes defines pixel rows 399 * byte 1 2nd from left etc. The first row of bytes defines pixel rows
405 * 0..7, the second row defines pixel row 8..15 etc. 400 * 0..7, the second row defines pixel row 8..15 etc.
406 * 401 *
407 * This is similar to the internal lcd hw format. */ 402 * This is the mono bitmap format used on all other targets so far; the
408 403 * pixel packing doesn't really matter on a 8bit+ target. */
409static unsigned char masks[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
410 404
411/* Draw a partial monochrome bitmap */ 405/* Draw a partial monochrome bitmap */
412void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, 406void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
@@ -415,13 +409,10 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
415void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, 409void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
416 int stride, int x, int y, int width, int height) 410 int stride, int x, int y, int width, int height)
417{ 411{
418 int in_x,in_y; 412 int xe, ye, yc;
419 int out_x; 413 lcd_pixelfunc_type *fgfunc;
420 int out_y; 414 lcd_pixelfunc_type *bgfunc;
421 unsigned char pixel;
422 fb_data * addr;
423 415
424 (void)stride;
425 /* nothing to draw? */ 416 /* nothing to draw? */
426 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 417 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
427 || (x + width <= 0) || (y + height <= 0)) 418 || (x + width <= 0) || (y + height <= 0))
@@ -445,24 +436,35 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
445 if (y + height > LCD_HEIGHT) 436 if (y + height > LCD_HEIGHT)
446 height = LCD_HEIGHT - y; 437 height = LCD_HEIGHT - y;
447 438
448// src += stride * (src_y >> 3) + src_x; /* move starting point */ 439 src += stride * (src_y >> 3) + src_x; /* move starting point */
449 440 src_y &= 7;
450 /* Copying from src_x,src_y to (x,y). Size is width,height */ 441
451 in_x=src_x; 442 xe = x + width;
452 for (out_x=x;out_x<(x+width);out_x++) { 443 ye = y + height;
453 in_y=src_y; 444 fgfunc = lcd_pixelfuncs[drawmode];
454 for (out_y=y;out_y<(y+height);out_y++) { 445 bgfunc = lcd_pixelfuncs[drawmode ^ DRMODE_INVERSEVID];
455 pixel=(*src)&masks[in_y]; 446
456 addr=&lcd_framebuffer[out_y][out_x]; 447 for (; x < xe; x++)
457 if (pixel > 0) { 448 {
458 *addr=fg_pattern; 449 const unsigned char *src_col = src++;
459 } else { 450 unsigned char data = *src_col >> src_y;
460 *addr=bg_pattern; 451 int numbits = 8 - src_y;
461 } 452
462 in_y++; 453 for (yc = y; yc < ye; yc++)
463 } 454 {
464 in_x++; 455 if (data & 0x01)
465 src++; 456 fgfunc(x, yc);
457 else
458 bgfunc(x, yc);
459
460 data >>= 1;
461 if (--numbits == 0)
462 {
463 src_col += stride;
464 data = *src_col;
465 numbits = 8;
466 }
467 }
466 } 468 }
467} 469}
468 470
@@ -479,33 +481,52 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
479void lcd_bitmap_part(const fb_data *src, int src_x, int src_y, 481void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
480 int stride, int x, int y, int width, int height) 482 int stride, int x, int y, int width, int height)
481{ 483{
482 (void)src; 484 int ye;
483 (void)src_x; 485
484 (void)src_y; 486 /* nothing to draw? */
485 (void)stride; 487 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
486 (void)x; 488 || (x + width <= 0) || (y + height <= 0))
487 (void)y; 489 return;
488 (void)width; 490
489 (void)height; 491 /* clipping */
492 if (x < 0)
493 {
494 width += x;
495 src_x -= x;
496 x = 0;
497 }
498 if (y < 0)
499 {
500 height += y;
501 src_y -= y;
502 y = 0;
503 }
504 if (x + width > LCD_WIDTH)
505 width = LCD_WIDTH - x;
506 if (y + height > LCD_HEIGHT)
507 height = LCD_HEIGHT - y;
508
509 src += stride * src_y + src_x; /* move starting point */
510 ye = y + height;
511
512 for (; y < ye; y++)
513 {
514 const fb_data *src_row = src;
515 fb_data *dst = &lcd_framebuffer[y][x];
516 fb_data *dst_end = dst + width;
517
518 do
519 *dst++ = *src_row++;
520 while (dst < dst_end);
521
522 src += stride;
523 }
490} 524}
491 525
492/* Draw a full native bitmap */ 526/* Draw a full native bitmap */
493void lcd_bitmap(const fb_data *src, int x, int y, int width, int height) 527void lcd_bitmap(const fb_data *src, int x, int y, int width, int height)
494{ 528{
495 fb_data* s=(fb_data *)src; 529 lcd_bitmap_part(src, 0, 0, width, x, y, width, height);
496 fb_data* d=&lcd_framebuffer[y][x];
497 int k=LCD_WIDTH-width;
498 int i,j;
499
500 for (i=0;i<height;i++) {
501 for (j=0;j<width;j++) {
502 *(d++)=*(s++);
503 }
504 d+=k;
505 }
506
507//OLD Implementation: lcd_bitmap_part(src, 0, 0, width, x, y, width, height);
508
509} 530}
510 531
511/* put a string at a given pixel position, skipping first ofs pixel columns */ 532/* put a string at a given pixel position, skipping first ofs pixel columns */
@@ -571,15 +592,12 @@ void lcd_puts_style(int x, int y, const unsigned char *str, int style)
571 lcd_putsxy(xpos, ypos, str); 592 lcd_putsxy(xpos, ypos, str);
572 drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); 593 drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID);
573 (void)style; 594 (void)style;
574#if 0
575 /* TODO: Implement lcd_fillrect */
576 lcd_fillrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h); 595 lcd_fillrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h);
577 if (style & STYLE_INVERT) 596 if (style & STYLE_INVERT)
578 { 597 {
579 drawmode = DRMODE_COMPLEMENT; 598 drawmode = DRMODE_COMPLEMENT;
580 lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h); 599 lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h);
581 } 600 }
582#endif
583 drawmode = lastmode; 601 drawmode = lastmode;
584} 602}
585 603