/* Scroll right */ void grey_scroll_right(int count) { struct viewport *vp = &_grey_default_vp; unsigned char *data, *data_end; int length, blank; if ((unsigned)count >= (unsigned)_grey_info.width) { grey_clear_display(); return; } data = _grey_info.buffer; data_end = data + _GREY_MULUQ(_grey_info.width, _grey_info.height); length = _grey_info.width - count; blank = (vp->drawmode & DRMODE_INVERSEVID) ? vp->fg_pattern : vp->bg_pattern; do { rb->memmove(data + count, data, length); rb->memset(data, blank, count); data += _grey_info.width; } while (data < data_end); }
/* Scroll up */ void grey_scroll_up(int count) { struct viewport *vp = &_grey_default_vp; long shift, length; int blank; if ((unsigned)count >= (unsigned)_grey_info.height) { grey_clear_display(); return; } shift = _GREY_MULUQ(_grey_info.width, count); length = _GREY_MULUQ(_grey_info.width, _grey_info.height - count); blank = (vp->drawmode & DRMODE_INVERSEVID) ? vp->fg_pattern : vp->bg_pattern; rb->memmove(_grey_info.buffer, _grey_info.buffer + shift, length); rb->memset(_grey_info.buffer + length, blank, shift); }
/* Initializes the playback engine */ int stream_init(void) { void *mem; size_t memsize; stream_mgr.status = STREAM_STOPPED; stream_mgr_init_state(); /* Initialize our window to the outside world first */ rb->mutex_init(&stream_mgr.str_mtx); rb->mutex_init(&stream_mgr.actl_mtx); stream_mgr.q = &stream_mgr_queue; rb->queue_init(stream_mgr.q, false); /* sets audiosize and returns buffer pointer */ mem = rb->plugin_get_audio_buffer(&memsize); /* Initialize non-allocator blocks first */ #ifndef HAVE_LCD_COLOR long greysize; /* Greylib init handles all necessary cache alignment */ if (!grey_init(mem, memsize, GREY_BUFFERED|GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, &greysize)) { rb->splash(HZ, "greylib init failed!"); return STREAM_ERROR; } mem += greysize; memsize -= greysize; grey_clear_display(); #endif /* !HAVE_LCD_COLOR */ stream_mgr.thread = rb->create_thread(stream_mgr_thread, stream_mgr_thread_stack, sizeof(stream_mgr_thread_stack), 0, "mpgstream_mgr" IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU)); rb->queue_enable_queue_send(stream_mgr.q, &stream_mgr_queue_send, stream_mgr.thread); if (stream_mgr.thread == 0) { rb->splash(HZ, "Could not create stream manager thread!"); return STREAM_ERROR; } /* Wait for thread to initialize */ stream_mgr_send_msg(STREAM_NULL, 0); /* Initialise our malloc buffer */ if (!mpeg_alloc_init(mem, memsize)) { rb->splash(HZ, "Out of memory in stream_init"); } /* These inits use the allocator */ else if (!pcm_output_init()) { rb->splash(HZ, "Could not initialize PCM!"); } else if (!audio_thread_init()) { rb->splash(HZ, "Cannot create audio thread!"); } else if (!video_thread_init()) { rb->splash(HZ, "Cannot create video thread!"); } /* Disk buffer takes max allotment of what's left so it must be last */ else if (!disk_buf_init()) { rb->splash(HZ, "Cannot create buffering thread!"); } else if (!parser_init()) { rb->splash(HZ, "Parser init failed!"); } else { return STREAM_OK; } return STREAM_ERROR; }
/* this is only a demo of what the framework can do */ int main(void) { int time; int x, y, i; int button, scroll_amount; bool black_border = false; static const unsigned char rockbox[] = { /* ........................................... * .####...###...###..#...#.####...###..#...#. * .#...#.#...#.#...#.#..#..#...#.#...#..#.#.. * .####..#...#.#.....###...####..#...#...#... * .#..#..#...#.#...#.#..#..#...#.#...#..#.#.. * .#...#..###...###..#...#.####...###..#...#. * ........................................... * 43 x 7 pixel, 1 bpp */ 0x00, 0x3E, 0x0A, 0x0A, 0x1A, 0x24, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x14, 0x00, 0x3E, 0x08, 0x08, 0x14, 0x22, 0x00, 0x3E, 0x2A, 0x2A, 0x2A, 0x14, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00 }; static const unsigned char showing[] = { /* ....................................... * ..####.#...#..###..#...#.#.#...#..####. * .#.....#...#.#...#.#...#.#.##..#.#..... * ..###..#####.#...#.#.#.#.#.#.#.#.#..##. * .....#.#...#.#...#.#.#.#.#.#..##.#...#. * .####..#...#..###...#.#..#.#...#..####. * ....................................... * 39 x 7 pixel, 1 bpp */ 0x00, 0x24, 0x2A, 0x2A, 0x2A, 0x12, 0x00, 0x3E, 0x08, 0x08, 0x08, 0x3E, 0x00, 0x1C, 0x22, 0x22, 0x22, 0x1C, 0x00, 0x1E, 0x20, 0x18, 0x20, 0x1E, 0x00, 0x3E, 0x00, 0x3E, 0x04, 0x08, 0x10, 0x3E, 0x00, 0x1C, 0x22, 0x22, 0x2A, 0x3A, 0x00 }; static const unsigned char grayscale_grey[] = { /* ....................................................... * ..####.####...###..#...#..####..###...###..#.....#####. * .#.....#...#.#...#.#...#.#.....#...#.#...#.#.....#..... * .#..##.####..#####..#.#...###..#.....#####.#.....####.. * .#...#.#..#..#...#...#.......#.#...#.#...#.#.....#..... * ..####.#...#.#...#...#...####...###..#...#.#####.#####. * ....................................................... * 55 x 7 pixel, 8 bpp */ 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, 110,110,110,110,110,110,110, 120,120, 20, 20, 20, 20,120,222,222,222,222,120,120,120, 24, 24, 24,120,120,226,120,120,120,226,120,120, 28, 28, 28, 28,120,120, 230,230,230,120,120,120, 32, 32, 32,120,120,234,120,120,120,120, 120, 36, 36, 36, 36, 36,120, 130, 20,130,130,130,130,130,222,130,130,130,222,130, 24,130,130, 130, 24,130,226,130,130,130,226,130, 28,130,130,130,130,130,230, 130,130,130,230,130, 32,130,130,130, 32,130,234,130,130,130,130, 130, 36,130,130,130,130,130, 140, 20,140,140, 20, 20,140,222,222,222,222,140,140, 24, 24, 24, 24, 24,140,140,226,140,226,140,140,140, 28, 28, 28,140,140,230, 140,140,140,140,140, 32, 32, 32, 32, 32,140,234,140,140,140,140, 140, 36, 36, 36, 36,140,140, 130, 20,130,130,130, 20,130,222,130,130,222,130,130, 24,130,130, 130, 24,130,130,130,226,130,130,130,130,130,130,130, 28,130,230, 130,130,130,230,130, 32,130,130,130, 32,130,234,130,130,130,130, 130, 36,130,130,130,130,130, 120,120, 20, 20, 20, 20,120,222,120,120,120,222,120, 24,120,120, 120, 24,120,120,120,226,120,120,120, 28, 28, 28, 28,120,120,120, 230,230,230,120,120, 32,120,120,120, 32,120,234,234,234,234,234, 120, 36, 36, 36, 36, 36,120, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, 110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, 110,110,110,110,110,110,110 }; /* Turn off backlight timeout */ backlight_ignore_timeout(); rb->lcd_setfont(FONT_SYSFIXED); /* select default font */ /* get the remainder of the plugin buffer */ gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size); /* initialize the greyscale buffer: Archos: 112 pixels wide, 7 rows (56 pixels) high. H1x0: 160 pixels wide, 30 rows (120 pixels) high. */ if (!grey_init(gbuf, gbuf_size, GREY_BUFFERED|GREY_ON_COP, LCD_WIDTH, GFX_HEIGHT, NULL)) { rb->splash(HZ, "Not enough memory."); return PLUGIN_ERROR; } /* place greyscale overlay 1 row down */ grey_set_position(0, 8); rb->lcd_puts(0, 0, "Shades: 129"); rb->lcd_update(); #ifdef HAVE_ADJUSTABLE_CPU_FREQ rb->cpu_boost(true); #endif grey_show(true); /* switch on greyscale overlay */ time = *rb->current_tick; /* start time measurement */ grey_set_background(150); grey_clear_display(); /* fill everything with grey 150 */ /* draw a dark grey line star background */ grey_set_foreground(80); for (y = 0; y < GFX_HEIGHT; y += 8) /* horizontal part */ { grey_drawline(0, y, (LCD_WIDTH-1), (GFX_HEIGHT-1) - y); /*grey lines */ } for (x = 10; x <= LCD_WIDTH; x += 10) /* vertical part */ { grey_drawline(x, 0, (LCD_WIDTH-1) - x, (GFX_HEIGHT-1)); /*grey lines */ } grey_set_foreground(0); grey_drawrect(0, 0, LCD_WIDTH, GFX_HEIGHT); /* black border */ /* draw grey tones */ for (i = 0; i < GFX_GREYTONE_WIDTH; i++) { x = ((LCD_WIDTH-GFX_GREYTONE_WIDTH)/2) + i; grey_set_foreground(GFX_GREYTONE_STEP * i); /* vertical lines */ grey_vline(x, (GFX_HEIGHT/8), (GFX_HEIGHT-GFX_HEIGHT/8-1)); } grey_set_drawmode(DRMODE_COMPLEMENT); /* invert rectangle (lower half) */ grey_fillrect((LCD_WIDTH-GFX_GREYTONE_WIDTH)/2, (GFX_HEIGHT/2+1), GFX_GREYTONE_WIDTH, (GFX_HEIGHT/2-GFX_HEIGHT/8-1)); /* invert a line */ grey_hline((LCD_WIDTH-GFX_GREYTONE_WIDTH)/2, (LCD_WIDTH+GFX_GREYTONE_WIDTH)/2, (GFX_HEIGHT/2-1)); /* show bitmaps (1 bit and 8 bit) */ /* opaque */ grey_set_drawinfo(DRMODE_SOLID, 255, 100); grey_mono_bitmap(rockbox, MAX((LCD_WIDTH/2-47), ((LCD_WIDTH-GFX_GREYTONE_WIDTH)/2)), (5*GFX_HEIGHT/16-4), 43, 7); /* transparent */ grey_set_drawinfo(DRMODE_FG, 0, 100); grey_mono_bitmap(showing, (LCD_WIDTH/2+4) , (5*GFX_HEIGHT/16-4), 39, 7); /* greyscale */ grey_gray_bitmap(grayscale_grey, ((LCD_WIDTH-55)/2), (11*GFX_HEIGHT/16-4), 55, 7); grey_update(); time = *rb->current_tick - time; /* end time measurement */ rb->lcd_putsf(0, 0, "Shades: 129, %d.%02ds", time / 100, time % 100); grey_deferred_lcd_update(); /* schedule an lcd_update() */ #ifdef HAVE_ADJUSTABLE_CPU_FREQ rb->cpu_boost(false); #endif /* drawing is now finished, play around with scrolling * until you press OFF or connect USB */ grey_set_background(255); while (true) { scroll_amount = 1; button = rb->button_get(true); exit_on_usb(button); if (button & GREYSCALE_SHIFT) { if (!black_border) { grey_set_background(0); black_border = true; } } else { if (black_border) { grey_set_background(255); black_border = false; } } if (button & BUTTON_REPEAT) scroll_amount = 4; switch (button & ~(GREYSCALE_SHIFT | BUTTON_REPEAT)) { case GREYSCALE_LEFT: grey_scroll_left(scroll_amount); /* scroll left */ grey_update(); break; case GREYSCALE_RIGHT: grey_scroll_right(scroll_amount); /* scroll right */ grey_update(); break; case GREYSCALE_UP: grey_scroll_up(scroll_amount); /* scroll up */ grey_update(); break; case GREYSCALE_DOWN: grey_scroll_down(scroll_amount); /* scroll down */ grey_update(); break; #ifdef GREYSCALE_RC_OFF case GREYSCALE_RC_OFF: #endif case GREYSCALE_OFF: return PLUGIN_OK; } } }