summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/misc.c84
-rw-r--r--apps/misc.h1
-rw-r--r--apps/plugin.c2
-rw-r--r--apps/plugin.h4
-rw-r--r--apps/plugins/lib/gray.h1
-rw-r--r--apps/plugins/lib/gray_core.c238
-rw-r--r--apps/plugins/lib/gray_draw.c38
7 files changed, 203 insertions, 165 deletions
diff --git a/apps/misc.c b/apps/misc.c
index d1b5c2274f..1c19c155d2 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -274,6 +274,8 @@ static const unsigned char bmpheader[] =
274#endif 274#endif
275}; 275};
276 276
277static void (*screen_dump_hook)(int fh) = NULL;
278
277void screen_dump(void) 279void screen_dump(void)
278{ 280{
279 int fh; 281 int fh;
@@ -298,56 +300,70 @@ void screen_dump(void)
298 if (fh < 0) 300 if (fh < 0)
299 return; 301 return;
300 302
301 write(fh, bmpheader, sizeof(bmpheader)); 303 if (screen_dump_hook)
302
303 /* BMP image goes bottom up */
304#if LCD_DEPTH == 1
305 for (by = LCD_HEIGHT/8 - 1; by >= 0; by--)
306 { 304 {
307 memset(&line_block[0][0], 0, sizeof(line_block)); 305 screen_dump_hook(fh);
306 }
307 else
308 {
309 write(fh, bmpheader, sizeof(bmpheader));
308 310
309 for (bx = 0; bx < LCD_WIDTH/8; bx++) 311 /* BMP image goes bottom up */
312#if LCD_DEPTH == 1
313 for (by = LCD_HEIGHT/8 - 1; by >= 0; by--)
310 { 314 {
311 dst_mask = 0x01; 315 memset(&line_block[0][0], 0, sizeof(line_block));
312 for (ix = 7; ix >= 0; ix--) 316
317 for (bx = 0; bx < LCD_WIDTH/8; bx++)
313 { 318 {
314 src_byte = lcd_framebuffer[by][8*bx+ix]; 319 dst_mask = 0x01;
315 src_mask = 0x01; 320 for (ix = 7; ix >= 0; ix--)
316 for (iy = 7; iy >= 0; iy--)
317 { 321 {
318 if (src_byte & src_mask) 322 src_byte = lcd_framebuffer[by][8*bx+ix];
319 line_block[iy][bx] |= dst_mask; 323 src_mask = 0x01;
320 src_mask <<= 1; 324 for (iy = 7; iy >= 0; iy--)
325 {
326 if (src_byte & src_mask)
327 line_block[iy][bx] |= dst_mask;
328 src_mask <<= 1;
329 }
330 dst_mask <<= 1;
321 } 331 }
322 dst_mask <<= 1;
323 } 332 }
333
334 write(fh, &line_block[0][0], sizeof(line_block));
324 } 335 }
325
326 write(fh, &line_block[0][0], sizeof(line_block));
327 }
328#elif LCD_DEPTH == 2 336#elif LCD_DEPTH == 2
329 for (by = LCD_HEIGHT/4 - 1; by >= 0; by--) 337 for (by = LCD_HEIGHT/4 - 1; by >= 0; by--)
330 {
331 memset(&line_block[0][0], 0, sizeof(line_block));
332
333 for (bx = 0; bx < LCD_WIDTH/2; bx++)
334 { 338 {
335 src_byte = lcd_framebuffer[by][2*bx]; 339 memset(&line_block[0][0], 0, sizeof(line_block));
336 src_byte2 = lcd_framebuffer[by][2*bx+1]; 340
337 for (iy = 3; iy >= 0; iy--) 341 for (bx = 0; bx < LCD_WIDTH/2; bx++)
338 { 342 {
339 line_block[iy][bx] = ((src_byte & 3) << 4) | (src_byte2 & 3); 343 src_byte = lcd_framebuffer[by][2*bx];
340 src_byte >>= 2; 344 src_byte2 = lcd_framebuffer[by][2*bx+1];
341 src_byte2 >>= 2; 345 for (iy = 3; iy >= 0; iy--)
346 {
347 line_block[iy][bx] = ((src_byte & 3) << 4) | (src_byte2 & 3);
348 src_byte >>= 2;
349 src_byte2 >>= 2;
350 }
342 } 351 }
343 }
344 352
345 write(fh, &line_block[0][0], sizeof(line_block)); 353 write(fh, &line_block[0][0], sizeof(line_block));
354 }
355#endif /* LCD_DEPTH */
346 } 356 }
347#endif 357
348 close(fh); 358 close(fh);
349} 359}
350#endif 360
361void screen_dump_set_hook(void (*hook)(int fh))
362{
363 screen_dump_hook = hook;
364}
365
366#endif /* HAVE_LCD_BITMAP */
351 367
352/* parse a line from a configuration file. the line format is: 368/* parse a line from a configuration file. the line format is:
353 369
diff --git a/apps/misc.h b/apps/misc.h
index d637501c27..5af2568f7b 100644
--- a/apps/misc.h
+++ b/apps/misc.h
@@ -46,6 +46,7 @@ int read_line(int fd, char* buffer, int buffer_size);
46#ifdef HAVE_LCD_BITMAP 46#ifdef HAVE_LCD_BITMAP
47/* Save a .BMP file containing the current screen contents. */ 47/* Save a .BMP file containing the current screen contents. */
48void screen_dump(void); 48void screen_dump(void);
49void screen_dump_set_hook(void (*hook)(int fh));
49#endif 50#endif
50 51
51bool settings_parseline(char* line, char** name, char** value); 52bool settings_parseline(char* line, char** name, char** value);
diff --git a/apps/plugin.c b/apps/plugin.c
index 6748a19355..35ed62aba8 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -355,6 +355,8 @@ static const struct plugin_api rockbox_api = {
355 menu_draw, 355 menu_draw,
356 menu_insert, 356 menu_insert,
357 menu_set_cursor, 357 menu_set_cursor,
358
359 screen_dump_set_hook,
358}; 360};
359 361
360int plugin_load(const char* plugin, void* parameter) 362int plugin_load(const char* plugin, void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index f133d325a5..8fd57d2b5a 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -90,7 +90,7 @@
90#endif 90#endif
91 91
92/* increase this every time the api struct changes */ 92/* increase this every time the api struct changes */
93#define PLUGIN_API_VERSION 51 93#define PLUGIN_API_VERSION 52
94 94
95/* update this to latest version if a change to the api struct breaks 95/* update this to latest version if a change to the api struct breaks
96 backwards compatibility (and please take the opportunity to sort in any 96 backwards compatibility (and please take the opportunity to sort in any
@@ -443,6 +443,8 @@ struct plugin_api {
443 void (*menu_draw)(int menu); 443 void (*menu_draw)(int menu);
444 void (*menu_insert)(int menu, int position, char *desc, bool (*function) (void)); 444 void (*menu_insert)(int menu, int position, char *desc, bool (*function) (void));
445 void (*menu_set_cursor)(int menu, int position); 445 void (*menu_set_cursor)(int menu, int position);
446
447 void (*screen_dump_set_hook)(void (*hook)(int fh));
446}; 448};
447 449
448int plugin_load(const char* plugin, void* parameter); 450int plugin_load(const char* plugin, void* parameter);
diff --git a/apps/plugins/lib/gray.h b/apps/plugins/lib/gray.h
index f1007984b5..dadac9298f 100644
--- a/apps/plugins/lib/gray.h
+++ b/apps/plugins/lib/gray.h
@@ -42,7 +42,6 @@ void gray_release(void);
42/* Special functions */ 42/* Special functions */
43void gray_show(bool enable); 43void gray_show(bool enable);
44void gray_deferred_lcd_update(void); 44void gray_deferred_lcd_update(void);
45void gray_screendump(void);
46 45
47/* Update functions */ 46/* Update functions */
48void gray_update(void); 47void gray_update(void);
diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c
index ecff53f1c5..02477b5b82 100644
--- a/apps/plugins/lib/gray_core.c
+++ b/apps/plugins/lib/gray_core.c
@@ -36,6 +36,7 @@ short _gray_random_buffer; /* buffer for random number generator */
36 36
37/* Prototypes */ 37/* Prototypes */
38static void _timer_isr(void); 38static void _timer_isr(void);
39static void gray_screendump_hook(int fd);
39 40
40/* Timer interrupt handler: display next bitplane */ 41/* Timer interrupt handler: display next bitplane */
41static void _timer_isr(void) 42static void _timer_isr(void)
@@ -230,11 +231,13 @@ void gray_show(bool enable)
230 { 231 {
231 _gray_info.flags |= _GRAY_RUNNING; 232 _gray_info.flags |= _GRAY_RUNNING;
232 _gray_rb->timer_register(1, NULL, FREQ / 67, 1, _timer_isr); 233 _gray_rb->timer_register(1, NULL, FREQ / 67, 1, _timer_isr);
234 _gray_rb->screen_dump_set_hook(gray_screendump_hook);
233 } 235 }
234 else 236 else
235 { 237 {
236 _gray_rb->timer_unregister(); 238 _gray_rb->timer_unregister();
237 _gray_info.flags &= ~_GRAY_RUNNING; 239 _gray_info.flags &= ~_GRAY_RUNNING;
240 _gray_rb->screen_dump_set_hook(NULL);
238 _gray_rb->lcd_update(); /* restore whatever there was before */ 241 _gray_rb->lcd_update(); /* restore whatever there was before */
239 } 242 }
240#elif defined(CPU_COLDFIRE) && (CONFIG_LCD == LCD_S1D15E06) 243#elif defined(CPU_COLDFIRE) && (CONFIG_LCD == LCD_S1D15E06)
@@ -244,12 +247,14 @@ void gray_show(bool enable)
244 _gray_rb->cpu_boost(true); /* run at 120 MHz to avoid freq changes */ 247 _gray_rb->cpu_boost(true); /* run at 120 MHz to avoid freq changes */
245 _gray_rb->timer_register(1, NULL, *_gray_rb->cpu_frequency / 70, 1, 248 _gray_rb->timer_register(1, NULL, *_gray_rb->cpu_frequency / 70, 1,
246 _timer_isr); 249 _timer_isr);
250 _gray_rb->screen_dump_set_hook(gray_screendump_hook);
247 } 251 }
248 else if (!enable && (_gray_info.flags & _GRAY_RUNNING)) 252 else if (!enable && (_gray_info.flags & _GRAY_RUNNING))
249 { 253 {
250 _gray_rb->timer_unregister(); 254 _gray_rb->timer_unregister();
251 _gray_rb->cpu_boost(false); 255 _gray_rb->cpu_boost(false);
252 _gray_info.flags &= ~_GRAY_RUNNING; 256 _gray_info.flags &= ~_GRAY_RUNNING;
257 _gray_rb->screen_dump_set_hook(NULL);
253 _gray_rb->lcd_update(); /* restore whatever there was before */ 258 _gray_rb->lcd_update(); /* restore whatever there was before */
254 } 259 }
255#endif 260#endif
@@ -315,7 +320,7 @@ void gray_update_rect(int x, int y, int width, int height)
315 if (change != 0) 320 if (change != 0)
316 { 321 {
317 unsigned char *addr, *end; 322 unsigned char *addr, *end;
318 unsigned mask; 323 unsigned mask, trash;
319 324
320 pat_ptr = &pat_stack[8]; 325 pat_ptr = &pat_stack[8];
321 cbuf = _gray_info.cur_buffer + srcofs_row; 326 cbuf = _gray_info.cur_buffer + srcofs_row;
@@ -400,7 +405,7 @@ void gray_update_rect(int x, int y, int width, int height)
400 "mov.l @%[patp]+,r7\n" 405 "mov.l @%[patp]+,r7\n"
401 "mov.l @%[patp]+,r8\n" 406 "mov.l @%[patp]+,r8\n"
402 "mov.l @%[patp]+,r9\n" 407 "mov.l @%[patp]+,r9\n"
403 "mov.l @%[patp]+,r10 \n" 408 "mov.l @%[patp],%[rx] \n"
404 409
405 "tst %[mask],%[mask] \n" /* nothing to keep? */ 410 "tst %[mask],%[mask] \n" /* nothing to keep? */
406 "bt .ur_sloop \n" /* yes: jump to short loop */ 411 "bt .ur_sloop \n" /* yes: jump to short loop */
@@ -420,7 +425,7 @@ void gray_update_rect(int x, int y, int width, int height)
420 "rotcl r0 \n" 425 "rotcl r0 \n"
421 "shlr r9 \n" 426 "shlr r9 \n"
422 "rotcl r0 \n" 427 "rotcl r0 \n"
423 "shlr r10 \n" 428 "shlr %[rx] \n"
424 "mov.b @%[addr],%[patp]\n" /* read old value */ 429 "mov.b @%[addr],%[patp]\n" /* read old value */
425 "rotcl r0 \n" 430 "rotcl r0 \n"
426 "and %[mask],%[patp] \n" /* mask out unneeded bits */ 431 "and %[mask],%[patp] \n" /* mask out unneeded bits */
@@ -448,7 +453,7 @@ void gray_update_rect(int x, int y, int width, int height)
448 "rotcl r0 \n" 453 "rotcl r0 \n"
449 "shlr r9 \n" 454 "shlr r9 \n"
450 "rotcl r0 \n" 455 "rotcl r0 \n"
451 "shlr r10 \n" 456 "shlr %[rx] \n"
452 "rotcl r0 \n" 457 "rotcl r0 \n"
453 "mov.b r0,@%[addr] \n" /* store byte to bitplane */ 458 "mov.b r0,@%[addr] \n" /* store byte to bitplane */
454 "add %[psiz],%[addr] \n" /* advance to next bitplane */ 459 "add %[psiz],%[addr] \n" /* advance to next bitplane */
@@ -457,14 +462,15 @@ void gray_update_rect(int x, int y, int width, int height)
457 462
458 ".ur_end: \n" 463 ".ur_end: \n"
459 : /* outputs */ 464 : /* outputs */
460 [patp]"+r"(pat_ptr),
461 [addr]"+r"(addr), 465 [addr]"+r"(addr),
462 [mask]"+r"(mask) 466 [mask]"+r"(mask),
467 [rx] "=&r"(trash)
463 : /* inputs */ 468 : /* inputs */
469 [psiz]"r"(_gray_info.plane_size),
464 [end] "r"(end), 470 [end] "r"(end),
465 [psiz]"r"(_gray_info.plane_size) 471 [patp]"[rx]"(pat_ptr)
466 : /* clobbers */ 472 : /* clobbers */
467 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" 473 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9"
468 ); 474 );
469 } 475 }
470#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) 476#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2)
@@ -496,7 +502,7 @@ void gray_update_rect(int x, int y, int width, int height)
496 if (change != 0) 502 if (change != 0)
497 { 503 {
498 unsigned char *addr, *end; 504 unsigned char *addr, *end;
499 unsigned mask; 505 unsigned mask, trash;
500 506
501 pat_ptr = &pat_stack[8]; 507 pat_ptr = &pat_stack[8];
502 cbuf = _gray_info.cur_buffer + srcofs_row; 508 cbuf = _gray_info.cur_buffer + srcofs_row;
@@ -567,7 +573,7 @@ void gray_update_rect(int x, int y, int width, int height)
567 /* set the bits for all 8 pixels in all bytes according to the 573 /* set the bits for all 8 pixels in all bytes according to the
568 * precalculated patterns on the pattern stack */ 574 * precalculated patterns on the pattern stack */
569 asm volatile ( 575 asm volatile (
570 "movem.l (%[patp]),%%d2-%%d6/%%a0-%%a2 \n" 576 "movem.l (%[patp]),%%d2-%%d6/%%a0-%%a1/%[ax] \n"
571 /* pop all 8 patterns */ 577 /* pop all 8 patterns */
572 "not.l %[mask] \n" /* set mask -> keep mask */ 578 "not.l %[mask] \n" /* set mask -> keep mask */
573 "and.l #0xFF,%[mask] \n" 579 "and.l #0xFF,%[mask] \n"
@@ -593,10 +599,10 @@ void gray_update_rect(int x, int y, int width, int height)
593 "lsr.l #1,%%d1 \n" 599 "lsr.l #1,%%d1 \n"
594 "addx.l %%d0,%%d0 \n" 600 "addx.l %%d0,%%d0 \n"
595 "move.l %%d1,%%a1 \n" 601 "move.l %%d1,%%a1 \n"
596 "move.l %%a2,%%d1 \n" 602 "move.l %[ax],%%d1 \n"
597 "lsr.l #1,%%d1 \n" 603 "lsr.l #1,%%d1 \n"
598 "addx.l %%d0,%%d0 \n" 604 "addx.l %%d0,%%d0 \n"
599 "move.l %%d1,%%a2 \n" 605 "move.l %%d1,%[ax] \n"
600 606
601 "move.b (%[addr]),%%d1 \n" /* read old value */ 607 "move.b (%[addr]),%%d1 \n" /* read old value */
602 "and.l %[mask],%%d1 \n" /* mask out unneeded bits */ 608 "and.l %[mask],%%d1 \n" /* mask out unneeded bits */
@@ -629,10 +635,10 @@ void gray_update_rect(int x, int y, int width, int height)
629 "lsr.l #1,%%d1 \n" 635 "lsr.l #1,%%d1 \n"
630 "addx.l %%d0,%%d0 \n" 636 "addx.l %%d0,%%d0 \n"
631 "move.l %%d1,%%a1 \n" 637 "move.l %%d1,%%a1 \n"
632 "move.l %%a2,%%d1 \n" 638 "move.l %[ax],%%d1 \n"
633 "lsr.l #1,%%d1 \n" 639 "lsr.l #1,%%d1 \n"
634 "addx.l %%d0,%%d0 \n" 640 "addx.l %%d0,%%d0 \n"
635 "move.l %%d1,%%a2 \n" 641 "move.l %%d1,%[ax] \n"
636 642
637 "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */ 643 "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */
638 "add.l %[psiz],%[addr] \n" /* advance to next bitplane */ 644 "add.l %[psiz],%[addr] \n" /* advance to next bitplane */
@@ -642,13 +648,14 @@ void gray_update_rect(int x, int y, int width, int height)
642 ".ur_end: \n" 648 ".ur_end: \n"
643 : /* outputs */ 649 : /* outputs */
644 [addr]"+a"(addr), 650 [addr]"+a"(addr),
645 [mask]"+d"(mask) 651 [mask]"+d"(mask),
652 [ax] "=&a"(trash)
646 : /* inputs */ 653 : /* inputs */
647 [psiz]"a"(_gray_info.plane_size), 654 [psiz]"a"(_gray_info.plane_size),
648 [end] "a"(end), 655 [end] "a"(end),
649 [patp]"a"(pat_ptr) 656 [patp]"[ax]"(pat_ptr)
650 : /* clobbers */ 657 : /* clobbers */
651 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1", "a2" 658 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1"
652 ); 659 );
653 } 660 }
654#endif 661#endif
@@ -692,12 +699,14 @@ void gray_deferred_lcd_update(void)
692 699
693/*** Screenshot ***/ 700/*** Screenshot ***/
694 701
695#define BMP_NUMCOLORS 33 702#define BMP_FIXEDCOLORS (1 << LCD_DEPTH)
696#define BMP_BPP 8 703#define BMP_VARCOLORS 33
697#define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3) 704#define BMP_NUMCOLORS (BMP_FIXEDCOLORS + BMP_VARCOLORS)
698#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS) 705#define BMP_BPP 8
699#define BMP_DATASIZE (BMP_LINESIZE * LCD_HEIGHT) 706#define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3)
700#define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE) 707#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS)
708#define BMP_DATASIZE (BMP_LINESIZE * LCD_HEIGHT)
709#define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE)
701 710
702#define LE16_CONST(x) (x)&0xff, ((x)>>8)&0xff 711#define LE16_CONST(x) (x)&0xff, ((x)>>8)&0xff
703#define LE32_CONST(x) (x)&0xff, ((x)>>8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff 712#define LE32_CONST(x) (x)&0xff, ((x)>>8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff
@@ -720,6 +729,17 @@ static const unsigned char bmpheader[] =
720 0xc4, 0x0e, 0x00, 0x00, /* Vertical resolution (pixels/meter) */ 729 0xc4, 0x0e, 0x00, 0x00, /* Vertical resolution (pixels/meter) */
721 LE32_CONST(BMP_NUMCOLORS), /* Number of used colours */ 730 LE32_CONST(BMP_NUMCOLORS), /* Number of used colours */
722 LE32_CONST(BMP_NUMCOLORS), /* Number of important colours */ 731 LE32_CONST(BMP_NUMCOLORS), /* Number of important colours */
732
733 /* Fixed colours */
734#if LCD_DEPTH == 1
735 0x90, 0xee, 0x90, 0x00, /* Colour #0 */
736 0x00, 0x00, 0x00, 0x00 /* Colour #1 */
737#elif LCD_DEPTH == 2
738 0xe6, 0xd8, 0xad, 0x00, /* Colour #0 */
739 0x99, 0x90, 0x73, 0x00, /* Colour #1 */
740 0x4c, 0x48, 0x39, 0x00, /* Colour #2 */
741 0x00, 0x00, 0x00, 0x00 /* Colour #3 */
742#endif
723}; 743};
724 744
725#if LCD_DEPTH == 1 745#if LCD_DEPTH == 1
@@ -732,135 +752,131 @@ static const unsigned char bmpheader[] =
732#define BMP_BLUE 0xe6 752#define BMP_BLUE 0xe6
733#endif 753#endif
734 754
735static unsigned char linebuf[BMP_LINESIZE]; 755/* Hook function for core screen_dump() to save the current display
736 756 content (b&w and greyscale overlay) to an 8-bit BMP file. */
737/* Save the current display content (b&w and greyscale overlay) to an 8-bit 757static void gray_screendump_hook(int fd)
738 * BMP file in the root directory. */
739void gray_screendump(void)
740{ 758{
741 int fh, i, bright; 759 int i, idx;
742 int y; 760 int x, y, by;
761 int gx, mask;
743#if LCD_DEPTH == 1 762#if LCD_DEPTH == 1
744 int x, by, mask; 763 int gby;
745 int gx, gby; 764#elif LCD_DEPTH == 2
746 unsigned char *lcdptr, *grayptr, *grayptr2; 765 int shift, gy;
747#endif
748 char filename[MAX_PATH];
749
750#ifdef HAVE_RTC
751 struct tm *tm = _gray_rb->get_time();
752
753 _gray_rb->snprintf(filename, MAX_PATH,
754 "/graydump %04d-%02d-%02d %02d-%02d-%02d.bmp",
755 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
756 tm->tm_hour, tm->tm_min, tm->tm_sec);
757#else
758 {
759 DIR* dir;
760 int max_dump_file = 1; /* default to graydump_0001.bmp */
761 dir = _gray_rb->opendir("/");
762 if (dir) /* found */
763 {
764 /* Search for the highest screendump filename present,
765 increment behind that. So even with "holes"
766 (deleted files), the newest will always have the
767 highest number. */
768 while(true)
769 {
770 struct dirent* entry;
771 int curr_dump_file;
772 /* walk through the directory content */
773 entry = _gray_rb->readdir(dir);
774 if (!entry)
775 {
776 _gray_rb->closedir(dir);
777 break; /* end of dir */
778 }
779 if (_gray_rb->strncasecmp(entry->d_name, "graydump_", 9))
780 continue; /* no screendump file */
781 curr_dump_file = _gray_rb->atoi(&entry->d_name[9]);
782 if (curr_dump_file >= max_dump_file)
783 max_dump_file = curr_dump_file + 1;
784 }
785 }
786 _gray_rb->snprintf(filename, MAX_PATH, "/graydump_%04d.bmp",
787 max_dump_file);
788 }
789#endif 766#endif
767 unsigned char *clut_entry;
768 unsigned char *lcdptr;
769 unsigned char *grayptr, *grayptr2;
770 unsigned char linebuf[MAX(4*BMP_VARCOLORS,BMP_LINESIZE)];
790 771
791 fh = _gray_rb->creat(filename, O_WRONLY); 772 _gray_rb->write(fd, bmpheader, sizeof(bmpheader)); /* write header */
792
793 if (fh < 0)
794 return;
795
796 _gray_rb->write(fh, bmpheader, sizeof(bmpheader)); /* write header */
797 773
798 /* build clut */ 774 /* build clut */
799 linebuf[3] = 0; 775 _gray_rb->memset(linebuf, 0, 4*BMP_VARCOLORS);
776 clut_entry = linebuf;
800 777
801 for (i = 0; i < BMP_NUMCOLORS; i++) 778 for (i = _gray_info.depth; i > 0; i--)
802 { 779 {
803 bright = MIN(i, _gray_info.depth); 780 *clut_entry++ = MULU16(BMP_BLUE, i) / _gray_info.depth;
804 linebuf[0] = MULU16(BMP_BLUE, bright) / _gray_info.depth; 781 *clut_entry++ = MULU16(BMP_GREEN, i) / _gray_info.depth;
805 linebuf[1] = MULU16(BMP_GREEN, bright) / _gray_info.depth; 782 *clut_entry++ = MULU16(BMP_RED, i) / _gray_info.depth;
806 linebuf[2] = MULU16(BMP_RED, bright) / _gray_info.depth; 783 clut_entry++;
807 _gray_rb->write(fh, linebuf, 4);
808 } 784 }
785 _gray_rb->write(fd, linebuf, 4*BMP_VARCOLORS);
809 786
810 /* 8-bit BMP image goes bottom -> top */ 787 /* BMP image goes bottom -> top */
811 for (y = LCD_HEIGHT - 1; y >= 0; y--) 788 for (y = LCD_HEIGHT - 1; y >= 0; y--)
812 { 789 {
813 _gray_rb->memset(linebuf, BMP_NUMCOLORS-1, LCD_WIDTH); 790 _gray_rb->memset(linebuf, 0, BMP_LINESIZE);
814 791
815#if LCD_DEPTH == 1 792#if LCD_DEPTH == 1
816 mask = 1 << (y & 7); 793 mask = 1 << (y & (_PBLOCK-1));
817 by = y >> 3; 794 by = y >> _PBLOCK_EXP;
818 lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by); 795 lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by);
819 gby = by - _gray_info.by; 796 gby = by - _gray_info.by;
820 797
821 if ((_gray_info.flags & _GRAY_RUNNING) 798 if ((unsigned) gby < (unsigned) _gray_info.bheight)
822 && (unsigned) gby < (unsigned) _gray_info.bheight) 799 {
823 {
824 /* line contains greyscale (and maybe b&w) graphics */ 800 /* line contains greyscale (and maybe b&w) graphics */
825 grayptr = _gray_info.plane_data + MULU16(_gray_info.width, gby); 801 grayptr = _gray_info.plane_data + MULU16(_gray_info.width, gby);
826 802
827 for (x = 0; x < LCD_WIDTH; x++) 803 for (x = 0; x < LCD_WIDTH; x++)
828 { 804 {
829 if (*lcdptr++ & mask)
830 linebuf[x] = 0;
831
832 gx = x - _gray_info.x; 805 gx = x - _gray_info.x;
833 806
834 if ((unsigned)gx < (unsigned)_gray_info.width) 807 if ((unsigned)gx < (unsigned)_gray_info.width)
835 { 808 {
836 bright = 0; 809 idx = BMP_FIXEDCOLORS;
837 grayptr2 = grayptr + gx; 810 grayptr2 = grayptr + gx;
838 811
839 for (i = 0; i < _gray_info.depth; i++) 812 for (i = _gray_info.depth; i > 0; i--)
840 { 813 {
841 if (!(*grayptr2 & mask)) 814 if (*grayptr2 & mask)
842 bright++; 815 idx++;
843 grayptr2 += _gray_info.plane_size; 816 grayptr2 += _gray_info.plane_size;
844 } 817 }
845 linebuf[x] = bright; 818 linebuf[x] = idx;
819 }
820 else
821 {
822 linebuf[x] = (*lcdptr & mask) ? 1 : 0;
846 } 823 }
824 lcdptr++;
847 } 825 }
848 } 826 }
849 else 827 else
850 { 828 {
851 /* line contains only b&w graphics */ 829 /* line contains only b&w graphics */
852 for (x = 0; x < LCD_WIDTH; x++) 830 for (x = 0; x < LCD_WIDTH; x++)
853 if (*lcdptr++ & mask) 831 linebuf[x] = (*lcdptr++ & mask) ? 1 : 0;
854 linebuf[x] = 0;
855 } 832 }
856#elif LCD_DEPTH == 2 833#elif LCD_DEPTH == 2
857 /* TODO */ 834 shift = 2 * (y & 3);
835 by = y >> 2;
836 lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by);
837 gy = y - (_gray_info.by << _PBLOCK_EXP);
838
839 if ((unsigned)gy < (unsigned)_gray_info.height)
840 {
841 /* line contains greyscale (and maybe b&w) graphics */
842 mask = 1 << (gy & (_PBLOCK-1));
843 grayptr = _gray_info.plane_data
844 + MULU16(_gray_info.width, gy >> _PBLOCK_EXP);
845
846 for (x = 0; x < LCD_WIDTH; x++)
847 {
848 gx = x - _gray_info.x;
849
850 if ((unsigned)gx < (unsigned)_gray_info.width)
851 {
852 idx = BMP_FIXEDCOLORS;
853 grayptr2 = grayptr + gx;
854
855 for (i = _gray_info.depth; i > 0; i--)
856 {
857 if (*grayptr2 & mask)
858 idx++;
859 grayptr2 += _gray_info.plane_size;
860 }
861 linebuf[x] = idx;
862 }
863 else
864 {
865 linebuf[x] = (*lcdptr >> shift) & 3;
866 }
867 lcdptr++;
868 }
869 }
870 else
871 {
872 /* line contains only b&w graphics */
873 for (x = 0; x < LCD_WIDTH; x++)
874 linebuf[x] = (*lcdptr++ >> shift) & 3;
875 }
858#endif 876#endif
859 877
860 _gray_rb->write(fh, linebuf, sizeof(linebuf)); 878 _gray_rb->write(fd, linebuf, BMP_LINESIZE);
861 } 879 }
862
863 _gray_rb->close(fh);
864} 880}
865 881
866#endif /* HAVE_LCD_BITMAP */ 882#endif /* HAVE_LCD_BITMAP */
diff --git a/apps/plugins/lib/gray_draw.c b/apps/plugins/lib/gray_draw.c
index 4b2237197c..d03f450b5f 100644
--- a/apps/plugins/lib/gray_draw.c
+++ b/apps/plugins/lib/gray_draw.c
@@ -588,7 +588,7 @@ static void _writearray(unsigned char *address, const unsigned char *src,
588 unsigned long *pat_ptr = &pat_stack[8]; 588 unsigned long *pat_ptr = &pat_stack[8];
589 const unsigned char *_src; 589 const unsigned char *_src;
590 unsigned char *addr, *end; 590 unsigned char *addr, *end;
591 unsigned _mask; 591 unsigned _mask, trash;
592 592
593 _mask = mask; 593 _mask = mask;
594 _src = src; 594 _src = src;
@@ -675,7 +675,7 @@ static void _writearray(unsigned char *address, const unsigned char *src,
675 "mov.l @%[patp]+,r7\n" 675 "mov.l @%[patp]+,r7\n"
676 "mov.l @%[patp]+,r8\n" 676 "mov.l @%[patp]+,r8\n"
677 "mov.l @%[patp]+,r9\n" 677 "mov.l @%[patp]+,r9\n"
678 "mov.l @%[patp]+,r10 \n" 678 "mov.l @%[patp],%[rx] \n"
679 679
680 "not %[mask],%[mask] \n" /* "set" mask -> "keep" mask */ 680 "not %[mask],%[mask] \n" /* "set" mask -> "keep" mask */
681 "extu.b %[mask],%[mask] \n" /* mask out high bits */ 681 "extu.b %[mask],%[mask] \n" /* mask out high bits */
@@ -697,7 +697,7 @@ static void _writearray(unsigned char *address, const unsigned char *src,
697 "rotcl r0 \n" 697 "rotcl r0 \n"
698 "shlr r9 \n" 698 "shlr r9 \n"
699 "rotcl r0 \n" 699 "rotcl r0 \n"
700 "shlr r10 \n" 700 "shlr %[rx] \n"
701 "mov.b @%[addr],%[patp]\n" /* read old value */ 701 "mov.b @%[addr],%[patp]\n" /* read old value */
702 "rotcl r0 \n" 702 "rotcl r0 \n"
703 "and %[mask],%[patp] \n" /* mask out unneeded bits */ 703 "and %[mask],%[patp] \n" /* mask out unneeded bits */
@@ -725,7 +725,7 @@ static void _writearray(unsigned char *address, const unsigned char *src,
725 "rotcl r0 \n" 725 "rotcl r0 \n"
726 "shlr r9 \n" 726 "shlr r9 \n"
727 "rotcl r0 \n" 727 "rotcl r0 \n"
728 "shlr r10 \n" 728 "shlr %[rx] \n"
729 "rotcl r0 \n" 729 "rotcl r0 \n"
730 "mov.b r0,@%[addr] \n" /* store byte to bitplane */ 730 "mov.b r0,@%[addr] \n" /* store byte to bitplane */
731 "add %[psiz],%[addr] \n" /* advance to next bitplane */ 731 "add %[psiz],%[addr] \n" /* advance to next bitplane */
@@ -734,21 +734,22 @@ static void _writearray(unsigned char *address, const unsigned char *src,
734 734
735 ".wa_end: \n" 735 ".wa_end: \n"
736 : /* outputs */ 736 : /* outputs */
737 [patp]"+r"(pat_ptr),
738 [addr]"+r"(addr), 737 [addr]"+r"(addr),
739 [mask]"+r"(_mask) 738 [mask]"+r"(_mask),
739 [rx] "=&r"(trash)
740 : /* inputs */ 740 : /* inputs */
741 [psiz]"r"(_gray_info.plane_size),
741 [end] "r"(end), 742 [end] "r"(end),
742 [psiz]"r"(_gray_info.plane_size) 743 [patp]"[rx]"(pat_ptr)
743 : /* clobbers */ 744 : /* clobbers */
744 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" 745 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9"
745 ); 746 );
746#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2) 747#elif defined(CPU_COLDFIRE) && (LCD_DEPTH == 2)
747 unsigned long pat_stack[8]; 748 unsigned long pat_stack[8];
748 unsigned long *pat_ptr = &pat_stack[8]; 749 unsigned long *pat_ptr = &pat_stack[8];
749 const unsigned char *_src; 750 const unsigned char *_src;
750 unsigned char *addr, *end; 751 unsigned char *addr, *end;
751 unsigned _mask; 752 unsigned _mask, trash;
752 753
753 _mask = mask; 754 _mask = mask;
754 _src = src; 755 _src = src;
@@ -819,8 +820,8 @@ static void _writearray(unsigned char *address, const unsigned char *src,
819 /* set the bits for all 8 pixels in all bytes according to the 820 /* set the bits for all 8 pixels in all bytes according to the
820 * precalculated patterns on the pattern stack */ 821 * precalculated patterns on the pattern stack */
821 asm volatile ( 822 asm volatile (
822 "movem.l (%[patp]),%%d2-%%d6/%%a0-%%a2 \n" /* pop all 8 patterns */ 823 "movem.l (%[patp]),%%d2-%%d6/%%a0-%%a1/%[ax] \n"
823 824 /* pop all 8 patterns */
824 "not.l %[mask] \n" /* "set" mask -> "keep" mask */ 825 "not.l %[mask] \n" /* "set" mask -> "keep" mask */
825 "and.l #0xFF,%[mask] \n" 826 "and.l #0xFF,%[mask] \n"
826 "beq.b .wa_sloop \n" /* yes: jump to short loop */ 827 "beq.b .wa_sloop \n" /* yes: jump to short loop */
@@ -845,10 +846,10 @@ static void _writearray(unsigned char *address, const unsigned char *src,
845 "lsr.l #1,%%d1 \n" 846 "lsr.l #1,%%d1 \n"
846 "addx.l %%d0,%%d0 \n" 847 "addx.l %%d0,%%d0 \n"
847 "move.l %%d1,%%a1 \n" 848 "move.l %%d1,%%a1 \n"
848 "move.l %%a2,%%d1 \n" 849 "move.l %[ax],%%d1 \n"
849 "lsr.l #1,%%d1 \n" 850 "lsr.l #1,%%d1 \n"
850 "addx.l %%d0,%%d0 \n" 851 "addx.l %%d0,%%d0 \n"
851 "move.l %%d1,%%a2 \n" 852 "move.l %%d1,%[ax] \n"
852 853
853 "move.b (%[addr]),%%d1 \n" /* read old value */ 854 "move.b (%[addr]),%%d1 \n" /* read old value */
854 "and.l %[mask],%%d1 \n" /* mask out unneeded bits */ 855 "and.l %[mask],%%d1 \n" /* mask out unneeded bits */
@@ -881,10 +882,10 @@ static void _writearray(unsigned char *address, const unsigned char *src,
881 "lsr.l #1,%%d1 \n" 882 "lsr.l #1,%%d1 \n"
882 "addx.l %%d0,%%d0 \n" 883 "addx.l %%d0,%%d0 \n"
883 "move.l %%d1,%%a1 \n" 884 "move.l %%d1,%%a1 \n"
884 "move.l %%a2,%%d1 \n" 885 "move.l %[ax],%%d1 \n"
885 "lsr.l #1,%%d1 \n" 886 "lsr.l #1,%%d1 \n"
886 "addx.l %%d0,%%d0 \n" 887 "addx.l %%d0,%%d0 \n"
887 "move.l %%d1,%%a2 \n" 888 "move.l %%d1,%[ax] \n"
888 889
889 "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */ 890 "move.b %%d0,(%[addr]) \n" /* store byte to bitplane */
890 "add.l %[psiz],%[addr] \n" /* advance to next bitplane */ 891 "add.l %[psiz],%[addr] \n" /* advance to next bitplane */
@@ -894,13 +895,14 @@ static void _writearray(unsigned char *address, const unsigned char *src,
894 ".wa_end: \n" 895 ".wa_end: \n"
895 : /* outputs */ 896 : /* outputs */
896 [addr]"+a"(addr), 897 [addr]"+a"(addr),
897 [mask]"+d"(_mask) 898 [mask]"+d"(_mask),
899 [ax] "=&a"(trash)
898 : /* inputs */ 900 : /* inputs */
899 [psiz]"a"(_gray_info.plane_size), 901 [psiz]"a"(_gray_info.plane_size),
900 [end] "a"(end), 902 [end] "a"(end),
901 [patp]"a"(pat_ptr) 903 [patp]"[ax]"(pat_ptr)
902 : /* clobbers */ 904 : /* clobbers */
903 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1", "a2" 905 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1"
904 ); 906 );
905#endif 907#endif
906} 908}