summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-recorder.c
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2004-05-14 22:55:05 +0000
committerJens Arnold <amiconn@rockbox.org>2004-05-14 22:55:05 +0000
commit2d446fef067a8fbf86343160df3799870d65aa6a (patch)
tree15edae3baf50a3f66f4e4b2407e61f4845d640fb /firmware/drivers/lcd-recorder.c
parentc431e227367d18b6b487b7f72aab2653c529450f (diff)
downloadrockbox-2d446fef067a8fbf86343160df3799870d65aa6a.tar.gz
rockbox-2d446fef067a8fbf86343160df3799870d65aa6a.zip
Fixed lcd_bitmap() to use the bitmap format generated by bmp2rb correctly. Now it works for height > 8. Adapted font transposing & changed some other places to take advantage of that. bounce.c was (apart from fonts) the only routine that used the old format correctly.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4620 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-recorder.c')
-rw-r--r--firmware/drivers/lcd-recorder.c90
1 files changed, 51 insertions, 39 deletions
diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c
index 8cf5f12b8b..c174430c83 100644
--- a/firmware/drivers/lcd-recorder.c
+++ b/firmware/drivers/lcd-recorder.c
@@ -436,15 +436,16 @@ void lcd_putsxy(int x, int y, unsigned char *str)
436} 436}
437 437
438/* 438/*
439 * All bitmaps have this format: 439 * About Rockbox' internal bitmap format:
440 * Bits within a byte are arranged veritcally, LSB at top.
441 * Bytes are stored in column-major format, with byte 0 at top left,
442 * byte 1 is 2nd from top, etc. Bytes following left-most column
443 * starts 2nd left column, etc.
444 * 440 *
445 * Note: The HW takes bitmap bytes in row-major order. 441 * A bitmap contains one bit for every pixel that defines if that pixel is
442 * black (1) or white (0). Bits within a byte are arranged vertically, LSB
443 * at top.
444 * The bytes are stored in row-major order, with byte 0 being top left,
445 * byte 1 2nd from left etc. The first row of bytes defines pixel rows
446 * 0..7, the second row defines pixel row 8..15 etc.
446 * 447 *
447 * Memory copy of display bitmap 448 * This is the same as the internal lcd hw format.
448 */ 449 */
449 450
450/* 451/*
@@ -456,77 +457,88 @@ void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny,
456void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny, 457void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny,
457 bool clear) 458 bool clear)
458{ 459{
459 unsigned char *dst; 460 unsigned char *src_col, *dst, *dst_col;
460 unsigned char *dst2; 461 unsigned int data, mask1, mask2, mask3, mask4;
461 unsigned int data, mask, mask2, mask3, mask4; 462 int stride, shift;
462 int shift;
463 463
464 if (((unsigned)x >= LCD_WIDTH) || ((unsigned)y >= LCD_HEIGHT)) 464 if (((unsigned) x >= LCD_WIDTH) || ((unsigned) y >= LCD_HEIGHT))
465 return; 465 return;
466 if (((unsigned)(x + nx)) >= LCD_WIDTH)
467 nx = LCD_WIDTH - x;
468 if (((unsigned)(y + ny)) >= LCD_HEIGHT)
469 ny = LCD_HEIGHT - y;
470 466
471 shift = y & 7; 467 stride = nx; /* otherwise right-clipping will destroy the image */
472 dst2 = &lcd_framebuffer[y/8][x];
473 468
474 /* short cut for byte aligned match (e.g. standard text) */ 469 if (((unsigned) (x + nx)) >= LCD_WIDTH)
475 if (!shift && clear && ny==8) 470 nx = LCD_WIDTH - x;
471 if (((unsigned) (y + ny)) >= LCD_HEIGHT)
472 ny = LCD_HEIGHT - y;
473
474 dst = &lcd_framebuffer[y >> 3][x];
475 shift = y & 7;
476
477 if (!shift && clear) /* shortcut for byte aligned match with clear */
476 { 478 {
477 memcpy(dst2, src, nx); 479 while (ny >= 8) /* all full rows */
478 return; 480 {
481 memcpy(dst, src, nx);
482 src += stride;
483 dst += LCD_WIDTH;
484 ny -= 8;
485 }
486 if (ny == 0) /* nothing left to do? */
487 return;
488 /* last partial row to do by default routine */
479 } 489 }
480 490
481 ny += shift; 491 ny += shift;
482 492
483 /* Calculate bit masks */ 493 /* Calculate bit masks */
484 mask4 = ~(0xfe << ((ny-1) & 7)); 494 mask4 = ~(0xfe << ((ny-1) & 7)); /* data mask for last partial row */
485 if (clear) 495 if (clear)
486 { 496 {
487 mask = ~(0xff << shift); 497 mask1 = ~(0xff << shift); /* clearing of first partial row */
488 mask2 = 0; 498 mask2 = 0; /* clearing of intermediate (full) rows */
489 mask3 = ~mask4; 499 mask3 = ~mask4; /* clearing of last partial row */
490 if (ny <= 8) 500 if (ny <= 8)
491 mask3 |= mask; 501 mask3 |= mask1;
492 } 502 }
493 else 503 else
494 mask = mask2 = mask3 = 0xff; 504 mask1 = mask2 = mask3 = 0xff;
495 505
496 /* Loop for each column */ 506 /* Loop for each column */
497 for (x = 0; x < nx; x++) 507 for (x = 0; x < nx; x++)
498 { 508 {
499 dst = dst2; 509 src_col = src++;
500 dst2++; 510 dst_col = dst++;
501 data = 0; 511 data = 0;
502 y = 0; 512 y = 0;
503 513
504 if (ny > 8) 514 if (ny > 8)
505 { 515 {
506 /* First partial row */ 516 /* First partial row */
507 data = *src++ << shift; 517 data = *src_col << shift;
508 *dst = (*dst & mask) | data; 518 *dst_col = (*dst_col & mask1) | data;
519 src_col += stride;
520 dst_col += LCD_WIDTH;
509 data >>= 8; 521 data >>= 8;
510 dst += LCD_WIDTH;
511 522
512 /* Intermediate rows */ 523 /* Intermediate rows */
513 for (y = 8; y < ny-8; y += 8) 524 for (y = 8; y < ny-8; y += 8)
514 { 525 {
515 data |= *src++ << shift; 526 data |= *src_col << shift;
516 *dst = (*dst & mask2) | data; 527 *dst_col = (*dst_col & mask2) | data;
528 src_col += stride;
529 dst_col += LCD_WIDTH;
517 data >>= 8; 530 data >>= 8;
518 dst += LCD_WIDTH;
519 } 531 }
520 } 532 }
521 533
522 /* Last partial row */ 534 /* Last partial row */
523 if (y + shift < ny) 535 if (y + shift < ny)
524 data |= *src++ << shift; 536 data |= *src_col << shift;
525 *dst = (*dst & mask3) | (data & mask4); 537 *dst_col = (*dst_col & mask3) | (data & mask4);
526 } 538 }
527} 539}
528 540
529/* 541/*
530 * Draw a rectangle with upper left corner at (x, y) 542 * Draw a rectangle with upper left corner at (x, y)
531 * and size (nx, ny) 543 * and size (nx, ny)
532 */ 544 */