diff options
Diffstat (limited to 'apps/misc.c')
-rw-r--r-- | apps/misc.c | 179 |
1 files changed, 73 insertions, 106 deletions
diff --git a/apps/misc.c b/apps/misc.c index 43dfd45e51..0d244563d0 100644 --- a/apps/misc.c +++ b/apps/misc.c | |||
@@ -425,21 +425,23 @@ static void (*screen_dump_hook)(int fh) = NULL; | |||
425 | 425 | ||
426 | void screen_dump(void) | 426 | void screen_dump(void) |
427 | { | 427 | { |
428 | int fh; | 428 | int fd, y; |
429 | char filename[MAX_PATH]; | 429 | char filename[MAX_PATH]; |
430 | int bx, by; | 430 | |
431 | fb_data *src; | ||
431 | #if LCD_DEPTH == 1 | 432 | #if LCD_DEPTH == 1 |
432 | static unsigned char line_block[8][BMP_LINESIZE]; | 433 | unsigned mask; |
433 | #elif LCD_DEPTH == 2 | 434 | unsigned val; |
434 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | 435 | #elif (LCD_DEPTH == 2) && (LCD_PIXELFORMAT != HORIZONTAL_PACKING) |
435 | static unsigned char line_block[BMP_LINESIZE]; | 436 | int shift; |
436 | #elif LCD_PIXELFORMAT == VERTICAL_PACKING | 437 | unsigned val; |
437 | static unsigned char line_block[4][BMP_LINESIZE]; | ||
438 | #elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED | ||
439 | static unsigned char line_block[8][BMP_LINESIZE]; | ||
440 | #endif | 438 | #endif |
441 | #elif LCD_DEPTH == 16 | 439 | #if LCD_DEPTH <= 8 |
442 | static unsigned short line_block[BMP_LINESIZE/2]; | 440 | unsigned char *dst, *dst_end; |
441 | unsigned char linebuf[BMP_LINESIZE]; | ||
442 | #elif LCD_DEPTH <= 16 | ||
443 | unsigned short *dst, *dst_end; | ||
444 | unsigned short linebuf[BMP_LINESIZE/2]; | ||
443 | #endif | 445 | #endif |
444 | 446 | ||
445 | #if CONFIG_RTC | 447 | #if CONFIG_RTC |
@@ -449,132 +451,97 @@ void screen_dump(void) | |||
449 | IF_CNFN_NUM_(, NULL)); | 451 | IF_CNFN_NUM_(, NULL)); |
450 | #endif | 452 | #endif |
451 | 453 | ||
452 | fh = creat(filename); | 454 | fd = creat(filename); |
453 | if (fh < 0) | 455 | if (fd < 0) |
454 | return; | 456 | return; |
455 | 457 | ||
456 | if (screen_dump_hook) | 458 | if (screen_dump_hook) |
457 | { | 459 | { |
458 | screen_dump_hook(fh); | 460 | screen_dump_hook(fd); |
459 | } | 461 | } |
460 | else | 462 | else |
461 | { | 463 | { |
462 | write(fh, bmpheader, sizeof(bmpheader)); | 464 | write(fd, bmpheader, sizeof(bmpheader)); |
463 | 465 | ||
464 | /* BMP image goes bottom up */ | 466 | /* BMP image goes bottom up */ |
465 | #if LCD_DEPTH == 1 | 467 | for (y = LCD_HEIGHT - 1; y >= 0; y--) |
466 | for (by = LCD_FBHEIGHT - 1; by >= 0; by--) | 468 | { |
467 | { | 469 | memset(linebuf, 0, BMP_LINESIZE); |
468 | unsigned char *src = &lcd_framebuffer[by][0]; | ||
469 | unsigned char *dst = &line_block[7][0]; | ||
470 | |||
471 | memset(line_block, 0, sizeof(line_block)); | ||
472 | 470 | ||
473 | #ifdef HAVE_LCD_SPLIT | 471 | #if defined(HAVE_LCD_SPLIT) && (LCD_SPLIT_LINES == 2) |
474 | if (by == (LCD_SPLIT_POS/8 - 1)) | 472 | if (y == LCD_SPLIT_POS - 1) |
475 | write(fh, line_block, LCD_SPLIT_LINES * sizeof(line_block[0])); | ||
476 | #endif | ||
477 | for (bx = LCD_WIDTH/2; bx > 0; bx--) | ||
478 | { | 473 | { |
479 | unsigned char *dst_blk = dst++; | 474 | write(fd, linebuf, BMP_LINESIZE); |
480 | unsigned src_byte0 = *src++ << 4; | 475 | write(fd, linebuf, BMP_LINESIZE); |
481 | unsigned src_byte1 = *src++; | 476 | } |
482 | int iy; | 477 | #endif |
478 | dst = linebuf; | ||
483 | 479 | ||
484 | for (iy = 8; iy > 0; iy--) | 480 | #if LCD_DEPTH == 1 |
485 | { | 481 | dst_end = dst + LCD_WIDTH/2; |
486 | *dst_blk = (src_byte0 & 0x10) | 482 | src = lcd_framebuffer[y >> 3]; |
487 | | (src_byte1 & 0x01) | 483 | mask = 1 << (y & 7); |
484 | |||
485 | do | ||
486 | { | ||
487 | val = (*src++ & mask) ? 0x10 : 0; | ||
488 | val |= (*src++ & mask) ? 0x01 : 0; | ||
488 | #ifdef HAVE_LCD_SPLIT | 489 | #ifdef HAVE_LCD_SPLIT |
489 | | (by < (LCD_SPLIT_POS/8) ? 0x22 : 0) | 490 | if (y < LCD_SPLIT_POS) |
491 | val |= 0x22; | ||
490 | #endif | 492 | #endif |
491 | ; | 493 | *dst++ = val; |
492 | src_byte0 >>= 1; | ||
493 | src_byte1 >>= 1; | ||
494 | dst_blk -= BMP_LINESIZE; | ||
495 | } | ||
496 | } | 494 | } |
495 | while (dst < dst_end); | ||
497 | 496 | ||
498 | write(fh, line_block, sizeof(line_block)); | ||
499 | } | ||
500 | #elif LCD_DEPTH == 2 | 497 | #elif LCD_DEPTH == 2 |
498 | dst_end = dst + LCD_WIDTH/2; | ||
499 | |||
501 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | 500 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING |
502 | for (by = LCD_FBHEIGHT - 1; by >= 0; by--) | 501 | src = lcd_framebuffer[y]; |
503 | { | ||
504 | unsigned char *src = &lcd_framebuffer[by][0]; | ||
505 | unsigned char *dst = line_block; | ||
506 | 502 | ||
507 | memset(line_block, 0, sizeof(line_block)); | 503 | do |
508 | for (bx = LCD_FBWIDTH; bx > 0; bx--) | ||
509 | { | 504 | { |
510 | unsigned src_byte = *src++; | 505 | unsigned data = *src++; |
511 | 506 | ||
512 | *dst++ = ((src_byte >> 2) & 0x30) | ((src_byte >> 4) & 0x03); | 507 | *dst++ = (data >> 2) & 0x30 | (data >> 4) & 0x03; |
513 | *dst++ = ((src_byte << 2) & 0x30) | (src_byte & 0x03); | 508 | *dst++ = (data << 2) & 0x30 | data & 0x03; |
514 | } | 509 | } |
510 | while (dst < dst_end); | ||
515 | 511 | ||
516 | write(fh, line_block, sizeof(line_block)); | ||
517 | } | ||
518 | #elif LCD_PIXELFORMAT == VERTICAL_PACKING | 512 | #elif LCD_PIXELFORMAT == VERTICAL_PACKING |
519 | for (by = LCD_FBHEIGHT - 1; by >= 0; by--) | 513 | src = lcd_framebuffer[y >> 2]; |
520 | { | 514 | shift = 2 * (y & 3); |
521 | unsigned char *src = &lcd_framebuffer[by][0]; | ||
522 | unsigned char *dst = &line_block[3][0]; | ||
523 | 515 | ||
524 | memset(line_block, 0, sizeof(line_block)); | 516 | do |
525 | for (bx = LCD_WIDTH/2; bx > 0; bx--) | ||
526 | { | 517 | { |
527 | unsigned char *dst_blk = dst++; | 518 | val = ((*src++ >> shift) & 3) << 4; |
528 | unsigned src_byte0 = *src++ << 4; | 519 | val |= ((*src++ >> shift) & 3); |
529 | unsigned src_byte1 = *src++; | 520 | *dst++ = val; |
530 | int iy; | ||
531 | |||
532 | for (iy = 4; iy > 0; iy--) | ||
533 | { | ||
534 | *dst_blk = (src_byte0 & 0x30) | (src_byte1 & 0x03); | ||
535 | src_byte0 >>= 2; | ||
536 | src_byte1 >>= 2; | ||
537 | dst_blk -= BMP_LINESIZE; | ||
538 | } | ||
539 | } | 521 | } |
522 | while (dst < dst_end); | ||
540 | 523 | ||
541 | write(fh, line_block, sizeof(line_block)); | ||
542 | } | ||
543 | #elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED | 524 | #elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED |
544 | for (by = LCD_FBHEIGHT - 1; by >= 0; by--) | 525 | src = lcd_framebuffer[y >> 3]; |
545 | { | 526 | shift = y & 7; |
546 | const fb_data *src = &lcd_framebuffer[by][0]; | ||
547 | unsigned char *dst = &line_block[7][0]; | ||
548 | 527 | ||
549 | memset(line_block, 0, sizeof(line_block)); | 528 | do |
550 | for (bx = LCD_WIDTH/2; bx > 0; bx--) | ||
551 | { | 529 | { |
552 | unsigned char *dst_blk = dst++; | 530 | unsigned data = (*src++ >> shift) & 0x0101; |
553 | unsigned src_data0 = *src++ << 4; | ||
554 | unsigned src_data1 = *src++; | ||
555 | int iy; | ||
556 | 531 | ||
557 | for (iy = 8; iy > 0; iy--) | 532 | val = (((data >> 7) | data) & 3) << 4; |
558 | { | 533 | data = (*src++ >> shift) & 0x0101; |
559 | *dst_blk = (src_data0 & 0x10) | (src_data1 & 0x01) | 534 | val |= ((data >> 7) | data) & 3; |
560 | | ((src_data0 & 0x1000) | (src_data1 & 0x0100)) >> 7; | 535 | *dst++ = val; |
561 | src_data0 >>= 1; | ||
562 | src_data1 >>= 1; | ||
563 | dst_blk -= BMP_LINESIZE; | ||
564 | } | ||
565 | } | 536 | } |
537 | while (dst < dst_end); | ||
566 | 538 | ||
567 | write(fh, line_block, sizeof(line_block)); | ||
568 | } | ||
569 | #endif | 539 | #endif |
570 | #elif LCD_DEPTH == 16 | 540 | #elif LCD_DEPTH == 16 |
571 | for (by = LCD_HEIGHT - 1; by >= 0; by--) | 541 | dst_end = dst + LCD_WIDTH; |
572 | { | 542 | src = lcd_framebuffer[y]; |
573 | unsigned short *src = &lcd_framebuffer[by][0]; | 543 | |
574 | unsigned short *dst = line_block; | 544 | do |
575 | |||
576 | memset(line_block, 0, sizeof(line_block)); | ||
577 | for (bx = LCD_WIDTH; bx > 0; bx--) | ||
578 | { | 545 | { |
579 | #if (LCD_PIXELFORMAT == RGB565SWAPPED) | 546 | #if (LCD_PIXELFORMAT == RGB565SWAPPED) |
580 | /* iPod LCD data is big endian although the CPU is not */ | 547 | /* iPod LCD data is big endian although the CPU is not */ |
@@ -583,13 +550,13 @@ void screen_dump(void) | |||
583 | *dst++ = htole16(*src++); | 550 | *dst++ = htole16(*src++); |
584 | #endif | 551 | #endif |
585 | } | 552 | } |
553 | while (dst < dst_end); | ||
586 | 554 | ||
587 | write(fh, line_block, sizeof(line_block)); | ||
588 | } | ||
589 | #endif /* LCD_DEPTH */ | 555 | #endif /* LCD_DEPTH */ |
556 | write(fd, linebuf, BMP_LINESIZE); | ||
557 | } | ||
590 | } | 558 | } |
591 | 559 | close(fd); | |
592 | close(fh); | ||
593 | } | 560 | } |
594 | 561 | ||
595 | void screen_dump_set_hook(void (*hook)(int fh)) | 562 | void screen_dump_set_hook(void (*hook)(int fh)) |