summaryrefslogtreecommitdiff
path: root/apps/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/misc.c')
-rw-r--r--apps/misc.c179
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
426void screen_dump(void) 426void 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
595void screen_dump_set_hook(void (*hook)(int fh)) 562void screen_dump_set_hook(void (*hook)(int fh))